diff --git a/PInvoke/DbgHelp/DbgHelp.Structs.cs b/PInvoke/DbgHelp/DbgHelp.Structs.cs
index a9151f05..e30795d4 100644
--- a/PInvoke/DbgHelp/DbgHelp.Structs.cs
+++ b/PInvoke/DbgHelp/DbgHelp.Structs.cs
@@ -604,7 +604,7 @@ namespace Vanara.PInvoke
{
///
/// The size of the structure, in bytes. The caller must set this member to
- /// sizeof(IMAGEHLP_DEFERRED_SYMBOL_LOAD64)
+ /// sizeof(IMAGEHLP_DEFERRED_SYMBOL_LOAD64)
/// .
///
public uint SizeOfStruct;
@@ -655,7 +655,7 @@ namespace Vanara.PInvoke
{
///
/// The size of the structure, in bytes. The caller must set this member to
- /// sizeof(IMAGEHLP_DEFERRED_SYMBOL_LOAD64)
+ /// sizeof(IMAGEHLP_DEFERRED_SYMBOL_LOAD64)
/// .
///
public uint SizeOfStruct;
@@ -713,7 +713,7 @@ namespace Vanara.PInvoke
{
///
/// The size of the structure, in bytes. The caller must set this member to
- /// sizeof(IMAGEHLP_DEFERRED_SYMBOL_LOAD64)
+ /// sizeof(IMAGEHLP_DEFERRED_SYMBOL_LOAD64)
/// .
///
public uint SizeOfStruct;
@@ -771,7 +771,7 @@ namespace Vanara.PInvoke
{
///
/// The size of the structure, in bytes. The caller must set this member to
- /// sizeof(IMAGEHLP_DUPLICATE_SYMBOL64)
+ /// sizeof(IMAGEHLP_DUPLICATE_SYMBOL64)
/// .
///
public uint SizeOfStruct;
@@ -908,7 +908,7 @@ namespace Vanara.PInvoke
{
///
/// The size of the structure, in bytes. The caller must set this member to
- /// sizeof(IMAGEHLP_LINE64)
+ /// sizeof(IMAGEHLP_LINE64)
/// .
///
public uint SizeOfStruct;
@@ -944,7 +944,7 @@ namespace Vanara.PInvoke
{
///
/// The size of the structure, in bytes. The caller must set this member to
- /// sizeof(IMAGEHLP_LINE64)
+ /// sizeof(IMAGEHLP_LINE64)
/// .
///
public uint SizeOfStruct;
@@ -981,7 +981,7 @@ namespace Vanara.PInvoke
{
///
/// The size of the structure, in bytes. The caller must set this member to
- /// sizeof(IMAGEHLP_MODULE64)
+ /// sizeof(IMAGEHLP_MODULE64)
/// .
///
public uint SizeOfStruct;
@@ -1089,7 +1089,7 @@ namespace Vanara.PInvoke
{
///
/// The size of the structure, in bytes. The caller must set this member to
- /// sizeof(IMAGEHLP_MODULE64)
+ /// sizeof(IMAGEHLP_MODULE64)
/// .
///
public uint SizeOfStruct;
@@ -1403,7 +1403,6 @@ namespace Vanara.PInvoke
}
}
-
/// Contains symbol information.
///
///
@@ -2089,7 +2088,7 @@ namespace Vanara.PInvoke
///
/// Set to
- /// sizeof(STACKFRAME_EX)
+ /// sizeof(STACKFRAME_EX)
/// .
///
public uint StackFrameSize;
@@ -2177,15 +2176,14 @@ 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
{
///
- /// 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.
+ /// 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;
@@ -2310,11 +2308,8 @@ namespace Vanara.PInvoke
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.)
+ /// may not be available in some languages and countries.)
///
public uint Scope;
@@ -2343,11 +2338,8 @@ namespace Vanara.PInvoke
public struct SYMSRV_INDEX_INFO
{
///
- /// The size of the structure, in bytes. This member must be set to
- /// sizeof(SYMSRV_INDEX_INFO)
- /// or
- /// sizeof(SYMSRV_INDEX_INFOW)
- /// .
+ /// The size of the structure, in bytes. This member must be set to sizeof(SYMSRV_INDEX_INFO) or
+ /// sizeof(SYMSRV_INDEX_INFOW) .
///
public uint sizeofstruct;
diff --git a/PInvoke/DbgHelp/DbgHelp.Sym.cs b/PInvoke/DbgHelp/DbgHelp.Sym.cs
index b2fdea30..4ea49f2f 100644
--- a/PInvoke/DbgHelp/DbgHelp.Sym.cs
+++ b/PInvoke/DbgHelp/DbgHelp.Sym.cs
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
+using Vanara.Extensions;
using Vanara.InteropServices;
namespace Vanara.PInvoke
@@ -88,7 +89,7 @@ namespace Vanara.PInvoke
// SymbolSize, PVOID UserContext ) {...}
[UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Auto)]
[PInvokeData("dbghelp.h", MSDNShortId = "NC:dbghelp.PSYM_ENUMERATESYMBOLS_CALLBACK")]
- public delegate bool PSYM_ENUMERATESYMBOLS_CALLBACK(in SYMBOL_INFO pSymInfo, uint SymbolSize, [In, Optional] IntPtr UserContext);
+ public delegate bool PSYM_ENUMERATESYMBOLS_CALLBACK([In] IntPtr pSymInfo, uint SymbolSize, [In, Optional] IntPtr UserContext);
///
/// An application-defined callback function used with the SymEnumLines and SymEnumSourceLines functions.
@@ -1826,9 +1827,105 @@ namespace Vanara.PInvoke
[DllImport(Lib_DbgHelp, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("dbghelp.h", MSDNShortId = "NF:dbghelp.SymEnumSymbols")]
[return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool SymEnumSymbols(HPROCESS hProcess, ulong BaseOfDll, [Optional, MarshalAs(UnmanagedType.LPTStr)] string Mask,
+ public static extern bool SymEnumSymbols(HPROCESS hProcess, [Optional] ulong BaseOfDll, [Optional, MarshalAs(UnmanagedType.LPTStr)] string Mask,
PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, [In, Optional] IntPtr UserContext);
+ /// Enumerates all symbols in a process.
+ /// A handle to a process. This handle must have been previously passed to the SymInitialize function.
+ ///
+ /// The base address of the module. If this value is zero and Mask contains an exclamation point (!), the function looks across
+ /// modules. If this value is zero and Mask does not contain an exclamation point, the function uses the scope established by the
+ /// SymSetContext function.
+ ///
+ ///
+ ///
+ /// A wildcard string that indicates the names of the symbols to be enumerated. The text can optionally contain the wildcards, "*"
+ /// and "?".
+ ///
+ ///
+ /// To specify a specific module or set of modules, begin the text with a wildcard string specifying the module, followed by an
+ /// exclamation point. When specifying a module, BaseOfDll is ignored.
+ ///
+ ///
+ ///
+ /// Value
+ /// Meaning
+ ///
+ /// -
+ /// foo
+ ///
+ /// If BaseOfDll is not zero, then SymEnumSymbols will look for a global symbol named "foo". If BaseOfDll is zero, then
+ /// SymEnumSymbols will look for a local symbol named "foo" within the scope established by the most recent call to the SymSetContext function.
+ ///
+ ///
+ /// -
+ /// foo?
+ ///
+ /// If BaseOfDll is not zero, then SymEnumSymbols will look for a global symbol that starts with "foo" and contains one extra
+ /// character afterwards, such as "fool" and "foot". If BaseOfDll is zero, then SymEnumSymbols will look for a symbol that starts
+ /// with "foo" and contains one extra character afterwards, such as "fool" and "foot". The search would be within the scope
+ /// established by the most recent call to the SymSetContext function.
+ ///
+ ///
+ /// -
+ /// foo*!bar
+ ///
+ /// SymEnumSymbols will look in every loaded module that starts with the text "foo" for a symbol called "bar". It could find matches
+ /// such as these, "foot!bar", "footlocker!bar", and "fool!bar".
+ ///
+ ///
+ /// -
+ /// *!*
+ /// SymEnumSymbols will enumerate every symbol in every loaded module.
+ ///
+ ///
+ ///
+ ///
+ /// Indicates possible options.
+ ///
+ ///
+ /// Value
+ /// Meaning
+ ///
+ /// -
+ /// SYMENUM_OPTIONS_DEFAULT 1
+ /// Use the default options.
+ ///
+ /// -
+ /// SYMENUM_OPTIONS_INLINE 2
+ /// Enumerate inline symbols.
+ ///
+ ///
+ ///
+ ///
+ /// A user-defined value that is passed to the callback function, or NULL. This parameter is typically used by an application
+ /// to pass a pointer to a data structure that provides context for the callback function.
+ ///
+ /// A list of structures.
+ ///
+ ///
+ /// All DbgHelp functions, such as this one, are single threaded. Therefore, calls from more than one thread to this function will
+ /// likely result in unexpected behavior or memory corruption. To avoid this, you must synchronize all concurrent calls from more
+ /// than one thread to this function.
+ ///
+ /// Examples
+ /// For an example, see Enumerating Symbols.
+ ///
+ public static IList SymEnumSymbolsEx(HPROCESS hProcess, [Optional] ulong BaseOfDll, [Optional, MarshalAs(UnmanagedType.LPTStr)] string Mask,
+ SYMENUM Options = SYMENUM.SYMENUM_OPTIONS_DEFAULT, [In] IntPtr UserContext = default)
+ {
+ List list = new();
+ Win32Error.ThrowLastErrorIfFalse(SymEnumSymbolsEx(hProcess, BaseOfDll, Mask, EnumProc, UserContext, Options));
+ return list;
+
+ bool EnumProc(IntPtr pSymInfo, uint SymbolSize, IntPtr UserContext)
+ {
+ try { list.Add(pSymInfo.ToStructure(SymbolSize)); return true; }
+ catch { }
+ return false;
+ }
+ }
+
/// Enumerates all symbols in a process.
/// A handle to a process. This handle must have been previously passed to the SymInitialize function.
///
@@ -1911,7 +2008,7 @@ namespace Vanara.PInvoke
[DllImport(Lib_DbgHelp, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("dbghelp.h", MSDNShortId = "NF:dbghelp.SymEnumSymbolsEx")]
[return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool SymEnumSymbolsEx(HPROCESS hProcess, ulong BaseOfDll, [Optional, MarshalAs(UnmanagedType.LPTStr)] string Mask,
+ public static extern bool SymEnumSymbolsEx(HPROCESS hProcess, [Optional] ulong BaseOfDll, [Optional, MarshalAs(UnmanagedType.LPTStr)] string Mask,
PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, [In, Optional] IntPtr UserContext, SYMENUM Options);
/// Enumerates the symbols for the specified address.
@@ -4480,7 +4577,7 @@ namespace Vanara.PInvoke
[DllImport(Lib_DbgHelp, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("dbghelp.h", MSDNShortId = "NF:dbghelp.SymLoadModuleEx")]
public static extern ulong SymLoadModuleEx(HPROCESS hProcess, [Optional] HFILE hFile, [Optional, MarshalAs(UnmanagedType.LPTStr)] string ImageName,
- [Optional, MarshalAs(UnmanagedType.LPTStr)] string ModuleName, ulong BaseOfDll, uint DllSize, in MODLOAD_DATA Data, SLMFLAG Flags);
+ [Optional, MarshalAs(UnmanagedType.LPTStr)] string ModuleName, ulong BaseOfDll, uint DllSize, in MODLOAD_DATA Data, [Optional] SLMFLAG Flags);
/// Loads the symbol table for the specified module.
/// A handle to the process that was originally passed to the SymInitialize function.
@@ -4566,7 +4663,8 @@ namespace Vanara.PInvoke
[DllImport(Lib_DbgHelp, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("dbghelp.h", MSDNShortId = "NF:dbghelp.SymLoadModuleEx")]
public static extern ulong SymLoadModuleEx(HPROCESS hProcess, [Optional] HFILE hFile, [Optional, MarshalAs(UnmanagedType.LPTStr)] string ImageName,
- [Optional, MarshalAs(UnmanagedType.LPTStr)] string ModuleName, ulong BaseOfDll, uint DllSize, [In, Optional] IntPtr Data, SLMFLAG Flags);
+ [Optional, MarshalAs(UnmanagedType.LPTStr)] string ModuleName, [Optional] ulong BaseOfDll, [Optional] uint DllSize, [In, Optional] IntPtr Data,
+ [Optional] SLMFLAG Flags);
/// Compares a string to a file name and path.
/// The file name to be compared to the Match parameter.
diff --git a/UnitTests/PInvoke/DbgHelp/DbgHelpTests.cs b/UnitTests/PInvoke/DbgHelp/DbgHelpTests.cs
index 0ec1cb27..aa629050 100644
--- a/UnitTests/PInvoke/DbgHelp/DbgHelpTests.cs
+++ b/UnitTests/PInvoke/DbgHelp/DbgHelpTests.cs
@@ -122,6 +122,17 @@ namespace Vanara.PInvoke.Tests
Assert.That(SymEnumProcesses(), Is.Not.Empty);
}
+ [Test]
+ public void SymEnumSymbolsExTest()
+ {
+ using var fakeProc = new ProcessSymbolHandler(new IntPtr(1), null, false);
+ var pdbBase = SymLoadModuleEx(fakeProc, default, @"C:\Windows\System32\ntdll.dll");
+ var list = SymEnumSymbolsEx(fakeProc, pdbBase);
+ Assert.That(list, Is.Not.Empty);
+ foreach (var i in list)
+ TestContext.WriteLine(i.Name);
+ }
+
[Test]
public unsafe void SymGetOmapsTest()
{