diff --git a/PInvoke/DbgHelp/DbgHelp.Structs.cs b/PInvoke/DbgHelp/DbgHelp.Structs.cs index e30795d4..9197e465 100644 --- a/PInvoke/DbgHelp/DbgHelp.Structs.cs +++ b/PInvoke/DbgHelp/DbgHelp.Structs.cs @@ -2,6 +2,7 @@ using System; using System.Linq; using System.Runtime.InteropServices; using Vanara.Extensions; +using Vanara.Extensions.Reflection; using Vanara.InteropServices; namespace Vanara.PInvoke @@ -9,6 +10,9 @@ namespace Vanara.PInvoke /// Items from the DbgHelp.dll public static partial class DbgHelp { + /// The maximum length of a symbol name. + public const int MAX_SYM_NAME = 2000; + /// Flags for . [PInvokeData("dbghelp.h", MSDNShortId = "NS:dbghelp._IMAGEHLP_DEFERRED_SYMBOL_LOAD64")] [Flags] @@ -2176,7 +2180,6 @@ namespace Vanara.PInvoke // SizeOfStruct; ULONG TypeIndex; ULONG64 Reserved[2]; ULONG Index; ULONG Size; ULONG64 ModBase; ULONG Flags; ULONG64 Value; ULONG64 // Address; ULONG Register; ULONG Scope; ULONG Tag; ULONG NameLen; ULONG MaxNameLen; CHAR Name[1]; } SYMBOL_INFO, *PSYMBOL_INFO; [PInvokeData("dbghelp.h", MSDNShortId = "NS:dbghelp._SYMBOL_INFO")] - [VanaraMarshaler(typeof(SafeAnysizeStringMarshaler), "Auto")] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct SYMBOL_INFO { @@ -2322,11 +2325,196 @@ namespace Vanara.PInvoke /// The size of the Name buffer, in characters. If this member is 0, the Name member is not used. public uint MaxNameLen; + /// + /// The name of the symbol. The name can be undecorated if the SYMOPT_UNDNAME option is used with the SymSetOptions function. + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_SYM_NAME)] + public string Name; + + /// The default initial value for SYMBOL_INFO with size parameters set. + public static SYMBOL_INFO Default = new() { SizeOfStruct = (uint)Marshal.SizeOf(typeof(SYMBOL_INFO)), MaxNameLen = MAX_SYM_NAME }; + } + + /// + /// Contains symbol information. Use this structure when extracting from a pointer, like in the enumeration callbacks. + /// + /// + /// This is a sample of how to use this structure in a callback. + /// List<SYMBOL_INFO> list = new(); + /// Win32Error.ThrowLastErrorIfFalse(SymEnumSymbolsEx(hProcess, baseOfDll, mask, EnumProc, userContext, options)); + /// + /// bool EnumProc(IntPtr pSymInfo, uint SymbolSize, IntPtr UserContext) + /// { + /// try { list.Add((SYMBOL_INFO)pSymInfo.ToStructure<SYMBOL_INFO_V>(SymbolSize)); return true; } + /// catch { return false; } + /// } + /// + // https://docs.microsoft.com/en-us/windows/win32/api/dbghelp/ns-dbghelp-symbol_info typedef struct _SYMBOL_INFO { ULONG + // SizeOfStruct; ULONG TypeIndex; ULONG64 Reserved[2]; ULONG Index; ULONG Size; ULONG64 ModBase; ULONG Flags; ULONG64 Value; ULONG64 + // Address; ULONG Register; ULONG Scope; ULONG Tag; ULONG NameLen; ULONG MaxNameLen; CHAR Name[1]; } SYMBOL_INFO, *PSYMBOL_INFO; + [PInvokeData("dbghelp.h", MSDNShortId = "NS:dbghelp._SYMBOL_INFO")] + [VanaraMarshaler(typeof(SafeAnysizeStringMarshaler), "Auto")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct SYMBOL_INFO_V + { + /// + /// The size of the structure, in bytes. This member must be set to sizeof(SYMBOL_INFO) . Note that the total size of the + /// data is the SizeOfStruct + (MaxNameLen - 1) * sizeof(TCHAR) . The reason to subtract one is that the first character + /// in the name is accounted for in the size of the structure. + /// + public uint SizeOfStruct; + + /// + /// A unique value that identifies the type data that describes the symbol. This value does not persist between sessions. + /// + public uint TypeIndex; + + /// This member is reserved for system use. + public ulong Reserved0; + + private ulong Reserved1; + + /// + /// + /// The unique value for the symbol. The value associated with a symbol is not guaranteed to be the same each time you run the process. + /// + /// + /// For PDB symbols, the index value for a symbol is not generated until the symbol is enumerated or retrieved through a search + /// by name or address. The index values for all CodeView and COFF symbols are generated when the symbols are loaded. + /// + /// + public uint Index; + + /// + /// The symbol size, in bytes. This value is meaningful only if the module symbols are from a pdb file; otherwise, this value is + /// typically zero and should be ignored. + /// + public uint Size; + + /// The base address of the module that contains the symbol. + public ulong ModBase; + + /// + /// This member can be one or more of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// SYMFLAG_CLR_TOKEN 0x00040000 + /// The symbol is a CLR token. + /// + /// + /// SYMFLAG_CONSTANT 0x00000100 + /// The symbol is a constant. + /// + /// + /// SYMFLAG_EXPORT 0x00000200 + /// The symbol is from the export table. + /// + /// + /// SYMFLAG_FORWARDER 0x00000400 + /// The symbol is a forwarder. + /// + /// + /// SYMFLAG_FRAMEREL 0x00000020 + /// Offsets are frame relative. + /// + /// + /// SYMFLAG_FUNCTION 0x00000800 + /// The symbol is a known function. + /// + /// + /// SYMFLAG_ILREL 0x00010000 + /// + /// The symbol address is an offset relative to the beginning of the intermediate language block. This applies to managed code only. + /// + /// + /// + /// SYMFLAG_LOCAL 0x00000080 + /// The symbol is a local variable. + /// + /// + /// SYMFLAG_METADATA 0x00020000 + /// The symbol is managed metadata. + /// + /// + /// SYMFLAG_PARAMETER 0x00000040 + /// The symbol is a parameter. + /// + /// + /// SYMFLAG_REGISTER 0x00000008 + /// The symbol is a register. The Register member is used. + /// + /// + /// SYMFLAG_REGREL 0x00000010 + /// Offsets are register relative. + /// + /// + /// SYMFLAG_SLOT 0x00008000 + /// The symbol is a managed code slot. + /// + /// + /// SYMFLAG_THUNK 0x00002000 + /// The symbol is a thunk. + /// + /// + /// SYMFLAG_TLSREL 0x00004000 + /// The symbol is an offset into the TLS data area. + /// + /// + /// SYMFLAG_VALUEPRESENT 0x00000001 + /// The Value member is used. + /// + /// + /// SYMFLAG_VIRTUAL 0x00001000 + /// The symbol is a virtual symbol created by the SymAddSymbol function. + /// + /// + /// + public SYMFLAG Flags; + + /// The value of a constant. + public ulong Value; + + /// The virtual address of the start of the symbol. + public ulong Address; + + /// The register. + public uint Register; + + /// + /// The DIA scope. For more information, see the Debug Interface Access SDK in the Visual Studio documentation. (This resource + /// may not be available in some languages and countries.) + /// + public uint Scope; + + /// The PDB classification. These values are defined in Dbghelp.h in the SymTagEnum enumeration type. + public uint Tag; + + /// The length of the name, in characters, not including the null-terminating character. + public uint NameLen; + + /// The size of the Name buffer, in characters. If this member is 0, the Name member is not used. + public uint MaxNameLen; + /// /// The name of the symbol. The name can be undecorated if the SYMOPT_UNDNAME option is used with the SymSetOptions function. /// [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1)] public string Name; + + /// Performs an implicit conversion from to . + /// The r. + /// The result of the conversion. + public static implicit operator SYMBOL_INFO(SYMBOL_INFO_V r) + { + var ret = default(SYMBOL_INFO); + foreach (var fi in typeof(SYMBOL_INFO_V).GetFields()) + ret.SetFieldValue(fi.Name, fi.GetValue(r)); + return ret; + } } /// Contains symbol server index information. diff --git a/PInvoke/DbgHelp/DbgHelp.Sym.cs b/PInvoke/DbgHelp/DbgHelp.Sym.cs index 4ea49f2f..017e3e2a 100644 --- a/PInvoke/DbgHelp/DbgHelp.Sym.cs +++ b/PInvoke/DbgHelp/DbgHelp.Sym.cs @@ -1911,7 +1911,7 @@ namespace Vanara.PInvoke /// Examples /// For an example, see Enumerating Symbols. /// - public static IList SymEnumSymbolsEx(HPROCESS hProcess, [Optional] ulong BaseOfDll, [Optional, MarshalAs(UnmanagedType.LPTStr)] string Mask, + public static IList SymEnumSymbolsEx(HPROCESS hProcess, [Optional] ulong BaseOfDll, [Optional] string Mask, SYMENUM Options = SYMENUM.SYMENUM_OPTIONS_DEFAULT, [In] IntPtr UserContext = default) { List list = new(); @@ -1920,7 +1920,7 @@ namespace Vanara.PInvoke bool EnumProc(IntPtr pSymInfo, uint SymbolSize, IntPtr UserContext) { - try { list.Add(pSymInfo.ToStructure(SymbolSize)); return true; } + try { list.Add(pSymInfo.ToStructure(SymbolSize)); return true; } catch { } return false; }