using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Vanara.InteropServices;
namespace Vanara.PInvoke
{
public static partial class Kernel32
{
/// Used by HEAPENTRY32
[PInvokeData("tlhelp32.h", MSDNShortId = "c5f1dc66-d44f-4491-b0b7-961b163d0f1f")]
[Flags]
public enum HEAPENTRY32_FLAGS
{
/// The memory block has a fixed (unmovable) location.
LF32_FIXED = 0x00000001,
/// The memory block is not used.
LF32_FREE = 0x00000002,
/// The memory block location can be moved.
LF32_MOVEABLE = 0x00000004,
}
/// Used by HEAPLIST32
[PInvokeData("tlhelp32.h", MSDNShortId = "61e01d23-9f15-44c5-9f6d-45df4809ccad")]
[Flags]
public enum HEAPLIST32_FLAGS
{
/// Process's default heap
HF32_DEFAULT = 1,
/// Process's shared heap
HF32_SHARED = 2
}
/// Flags used by .
[PInvokeData("tlhelp32.h", MSDNShortId = "df643c25-7558-424c-b187-b3f86ba51358")]
public enum TH32CS : uint
{
/// Indicates that the snapshot handle is to be inheritable.
TH32CS_INHERIT = 0x80000000,
/// Includes all heaps of the process specified in th32ProcessID in the snapshot. To enumerate the heaps, see Heap32ListFirst.
[CorrespondingType(typeof(HEAPLIST32))]
TH32CS_SNAPHEAPLIST = 0x00000001,
///
/// Includes all modules of the process specified in th32ProcessID in the snapshot. To enumerate the modules, see Module32First.
/// If the function fails with ERROR_BAD_LENGTH, retry the function until it succeeds.
///
/// 64-bit Windows: Using this flag in a 32-bit process includes the 32-bit modules of the process specified in th32ProcessID,
/// while using it in a 64-bit process includes the 64-bit modules. To include the 32-bit modules of the process specified in
/// th32ProcessID from a 64-bit process, use the TH32CS_SNAPMODULE32 flag.
///
///
[CorrespondingType(typeof(MODULEENTRY32))]
TH32CS_SNAPMODULE = 0x00000008,
///
/// Includes all 32-bit modules of the process specified in th32ProcessID in the snapshot when called from a 64-bit process. This
/// flag can be combined with TH32CS_SNAPMODULE or TH32CS_SNAPALL. If the function fails with ERROR_BAD_LENGTH, retry the
/// function until it succeeds.
///
[CorrespondingType(typeof(MODULEENTRY32))]
TH32CS_SNAPMODULE32 = 0x00000010,
/// Includes all processes in the system in the snapshot. To enumerate the processes, see Process32First.
[CorrespondingType(typeof(PROCESSENTRY32))]
TH32CS_SNAPPROCESS = 0x00000002,
///
/// Includes all threads in the system in the snapshot. To enumerate the threads, see Thread32First.
///
/// To identify the threads that belong to a specific process, compare its process identifier to the th32OwnerProcessID member of
/// the THREADENTRY32 structure when enumerating the threads.
///
///
[CorrespondingType(typeof(THREADENTRY32))]
TH32CS_SNAPTHREAD = 0x00000004,
///
/// Includes all processes and threads in the system, plus the heaps and modules of the process specified in th32ProcessID.
/// Equivalent to specifying the TH32CS_SNAPHEAPLIST, TH32CS_SNAPMODULE, TH32CS_SNAPPROCESS, and TH32CS_SNAPTHREAD values
/// combined using an OR operation ('|').
///
TH32CS_SNAPALL = TH32CS_SNAPHEAPLIST | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD | TH32CS_SNAPMODULE,
}
///
/// Takes a snapshot of the specified processes, as well as the heaps, modules, and threads used by these processes.
///
///
/// The portions of the system to be included in the snapshot. This parameter can be one or more of the following values.
///
///
/// Value
/// Meaning
///
/// -
/// TH32CS_INHERIT 0x80000000
/// Indicates that the snapshot handle is to be inheritable.
///
/// -
/// TH32CS_SNAPALL
///
/// Includes all processes and threads in the system, plus the heaps and modules of the process specified in . Equivalent to
/// specifying the TH32CS_SNAPHEAPLIST, TH32CS_SNAPMODULE, TH32CS_SNAPPROCESS, and TH32CS_SNAPTHREAD values combined using an OR
/// operation ('|').
///
///
/// -
/// TH32CS_SNAPHEAPLIST 0x00000001
/// Includes all heaps of the process specified in in the snapshot. To enumerate the heaps, see Heap32ListFirst.
///
/// -
/// TH32CS_SNAPMODULE 0x00000008
///
/// Includes all modules of the process specified in in the snapshot. To enumerate the modules, see Module32First. If the function
/// fails with ERROR_BAD_LENGTH, retry the function until it succeeds. 64-bit Windows: Using this flag in a 32-bit process includes
/// the 32-bit modules of the process specified in , while using it in a 64-bit process includes the 64-bit modules. To include the
/// 32-bit modules of the process specified in from a 64-bit process, use the TH32CS_SNAPMODULE32 flag.
///
///
/// -
/// TH32CS_SNAPMODULE32 0x00000010
///
/// Includes all 32-bit modules of the process specified in in the snapshot when called from a 64-bit process. This flag can be
/// combined with TH32CS_SNAPMODULE or TH32CS_SNAPALL. If the function fails with ERROR_BAD_LENGTH, retry the function until it succeeds.
///
///
/// -
/// TH32CS_SNAPPROCESS 0x00000002
/// Includes all processes in the system in the snapshot. To enumerate the processes, see Process32First.
///
/// -
/// TH32CS_SNAPTHREAD 0x00000004
///
/// Includes all threads in the system in the snapshot. To enumerate the threads, see Thread32First. To identify the threads that
/// belong to a specific process, compare its process identifier to the th32OwnerProcessID member of the THREADENTRY32 structure when
/// enumerating the threads.
///
///
///
///
///
///
/// The process identifier of the process to be included in the snapshot. This parameter can be zero to indicate the current process.
/// This parameter is used when the TH32CS_SNAPHEAPLIST, TH32CS_SNAPMODULE, TH32CS_SNAPMODULE32, or
/// TH32CS_SNAPALL value is specified. Otherwise, it is ignored and all processes are included in the snapshot.
///
///
/// If the specified process is the Idle process or one of the CSRSS processes, this function fails and the last error code is
/// ERROR_ACCESS_DENIED because their access restrictions prevent user-level code from opening them.
///
///
/// If the specified process is a 64-bit process and the caller is a 32-bit process, this function fails and the last error code is
/// ERROR_PARTIAL_COPY (299).
///
///
///
/// If the function succeeds, it returns an open handle to the specified snapshot.
///
/// If the function fails, it returns INVALID_HANDLE_VALUE. To get extended error information, call GetLastError. Possible
/// error codes include ERROR_BAD_LENGTH.
///
///
///
///
/// The snapshot taken by this function is examined by the other tool help functions to provide their results. Access to the snapshot
/// is read only. The snapshot handle acts as an object handle and is subject to the same rules regarding which processes and threads
/// it is valid in.
///
///
/// To enumerate the heap or module states for all processes, specify TH32CS_SNAPALL and set to zero. Then, for each
/// additional process in the snapshot, call CreateToolhelp32Snapshot again, specifying its process identifier and the
/// TH32CS_SNAPHEAPLIST or TH32_SNAPMODULE value.
///
///
/// When taking snapshots that include heaps and modules for a process other than the current process, the
/// CreateToolhelp32Snapshot function can fail or return incorrect information for a variety of reasons. For example, if the
/// loader data table in the target process is corrupted or not initialized, or if the module list changes during the function call
/// as a result of DLLs being loaded or unloaded, the function might fail with ERROR_BAD_LENGTH or other error code. Ensure
/// that the target process was not started in a suspended state, and try calling the function again. If the function fails with
/// ERROR_BAD_LENGTH when called with TH32CS_SNAPMODULE or TH32CS_SNAPMODULE32, call the function again until it succeeds.
///
///
/// The TH32CS_SNAPMODULE and TH32CS_SNAPMODULE32 flags do not retrieve handles for modules that were loaded with the
/// LOAD_LIBRARY_AS_DATAFILE or similar flags. For more information, see LoadLibraryEx.
///
/// To destroy the snapshot, use the CloseHandle function.
///
/// Note that you can use the QueryFullProcessImageName function to retrieve the full name of an executable image for both 32- and
/// 64-bit processes from a 32-bit process.
///
/// Examples
/// For an example, see Taking a Snapshot and Viewing Processes.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/tlhelp32/nf-tlhelp32-createtoolhelp32snapshot HANDLE
// CreateToolhelp32Snapshot( DWORD dwFlags, DWORD th32ProcessID );
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("tlhelp32.h", MSDNShortId = "df643c25-7558-424c-b187-b3f86ba51358")]
public static extern SafeHSNAPSHOT CreateToolhelp32Snapshot(TH32CS dwFlags, [Optional] uint th32ProcessID);
///
/// Retrieves information about the first block of a heap that has been allocated by a process.
///
///
/// A pointer to a HEAPENTRY32 structure.
///
///
/// The identifier of the process context that owns the heap.
///
///
/// The identifier of the heap to be enumerated.
///
///
///
/// Returns TRUE if information for the first heap block has been copied to the buffer or FALSE otherwise. The
/// ERROR_NO_MORE_FILES error value is returned by the GetLastError function if the heap is invalid or empty.
///
///
///
///
/// The calling application must set the dwSize member of HEAPENTRY32 to the size, in bytes, of the structure.
/// Heap32First changes dwSize to the number of bytes written to the structure. This will never be greater than the
/// initial value of dwSize, but it may be smaller. If the value is smaller, do not rely on the values of any members whose
/// offsets are greater than this value.
///
/// To access subsequent blocks of the same heap, use the Heap32Next function.
/// Examples
/// For an example, see Traversing the Heap List.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/tlhelp32/nf-tlhelp32-heap32first BOOL Heap32First( LPHEAPENTRY32 lphe, DWORD
// th32ProcessID, ULONG_PTR th32HeapID );
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("tlhelp32.h", MSDNShortId = "79d01e3a-b11b-46b5-99d0-b445000288a7")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool Heap32First(ref HEAPENTRY32 lphe, uint th32ProcessID, UIntPtr th32HeapID);
///
/// Retrieves information about the first heap that has been allocated by a specified process.
///
///
/// A handle to the snapshot returned from a previous call to the CreateToolhelp32Snapshot function.
///
///
/// A pointer to a HEAPLIST32 structure.
///
///
///
/// Returns TRUE if the first entry of the heap list has been copied to the buffer or FALSE otherwise. The
/// ERROR_NO_MORE_FILES error value is returned by the GetLastError function when no heap list exists or the snapshot does not
/// contain heap list information.
///
///
///
///
/// The calling application must set the dwSize member of HEAPLIST32 to the size, in bytes, of the structure.
/// Heap32ListFirst changes dwSize to the number of bytes written to the structure. This will never be greater than the
/// initial value of dwSize, but it may be smaller. If the value is smaller, do not rely on the values of any members whose
/// offsets are greater than this value.
///
/// To retrieve information about other heaps in the heap list, use the Heap32ListNext function.
/// Examples
/// For an example, see Traversing the Heap List.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/tlhelp32/nf-tlhelp32-heap32listfirst BOOL Heap32ListFirst( HANDLE hSnapshot,
// LPHEAPLIST32 lphl );
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("tlhelp32.h", MSDNShortId = "b9a2992b-0dc1-41c3-aa23-796def674831")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool Heap32ListFirst(HSNAPSHOT hSnapshot, ref HEAPLIST32 lphl);
///
/// Retrieves information about the next heap that has been allocated by a process.
///
///
/// A handle to the snapshot returned from a previous call to the CreateToolhelp32Snapshot function.
///
///
/// A pointer to a HEAPLIST32 structure.
///
///
///
/// Returns TRUE if the next entry of the heap list has been copied to the buffer or FALSE otherwise. The
/// ERROR_NO_MORE_FILES error value is returned by the GetLastError function when no more entries in the heap list exist.
///
///
///
/// To retrieve information about the first heap in a heap list, use the Heap32ListFirst function.
/// Examples
/// For an example, see Traversing the Heap List.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/tlhelp32/nf-tlhelp32-heap32listnext BOOL Heap32ListNext( HANDLE hSnapshot,
// LPHEAPLIST32 lphl );
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("tlhelp32.h", MSDNShortId = "bb4d573c-a82f-48ac-be22-440d6a1d0c9c")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool Heap32ListNext(HSNAPSHOT hSnapshot, ref HEAPLIST32 lphl);
///
/// Retrieves information about the next block of a heap that has been allocated by a process.
///
///
/// A pointer to a HEAPENTRY32 structure.
///
///
///
/// Returns TRUE if information about the next block in the heap has been copied to the buffer or FALSE otherwise. The
/// GetLastError function returns ERROR_NO_MORE_FILES when no more objects in the heap exist and ERROR_INVALID_DATA if
/// the heap appears to be corrupt or is modified during the walk in such a way that Heap32Next cannot continue.
///
///
///
/// To retrieve information for the first block of a heap, use the Heap32First function.
///
/// The Heap32Next function does not maintain a reference to the target process. If the target process dies, the system may
/// create a new process using the same process identifier. Therefore, the caller should maintain a reference to the target process
/// as long as it is using Heap32Next.
///
/// Examples
/// For an example, see Traversing the Heap List.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/tlhelp32/nf-tlhelp32-heap32next BOOL Heap32Next( LPHEAPENTRY32 lphe );
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("tlhelp32.h", MSDNShortId = "cc3becd0-edba-47cf-ac2d-26a5d98390e7")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool Heap32Next(ref HEAPENTRY32 lphe);
///
/// Retrieves information about the first module associated with a process.
///
///
/// A handle to the snapshot returned from a previous call to the CreateToolhelp32Snapshot function.
///
///
/// A pointer to a MODULEENTRY32 structure.
///
///
///
/// Returns TRUE if the first entry of the module list has been copied to the buffer or FALSE otherwise. The
/// ERROR_NO_MORE_FILES error value is returned by the GetLastError function if no modules exist or the snapshot does not
/// contain module information.
///
///
///
/// The calling application must set the dwSize member of MODULEENTRY32 to the size, in bytes, of the structure.
/// To retrieve information about other modules associated with the specified process, use the Module32Next function.
/// Examples
/// For an example, see Traversing the Module List.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/tlhelp32/nf-tlhelp32-module32first BOOL Module32First( HANDLE hSnapshot,
// LPMODULEENTRY32 lpme );
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("tlhelp32.h", MSDNShortId = "bb41cab9-13a1-469d-bf76-68c172e982f6")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool Module32First(HSNAPSHOT hSnapshot, ref MODULEENTRY32 lpme);
///
/// Retrieves information about the next module associated with a process or thread.
///
///
/// A handle to the snapshot returned from a previous call to the CreateToolhelp32Snapshot function.
///
///
/// A pointer to a MODULEENTRY32 structure.
///
///
///
/// Returns TRUE if the next entry of the module list has been copied to the buffer or FALSE otherwise. The
/// ERROR_NO_MORE_FILES error value is returned by the GetLastError function if no more modules exist.
///
///
///
/// To retrieve information about first module associated with a process, use the Module32First function.
/// Examples
/// For an example, see Traversing the Module List.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/tlhelp32/nf-tlhelp32-module32next BOOL Module32Next( HANDLE hSnapshot,
// LPMODULEENTRY32 lpme );
[DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("tlhelp32.h", MSDNShortId = "88ec1af4-bae7-4cd7-b830-97a98fb337f4")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool Module32Next(HSNAPSHOT hSnapshot, ref MODULEENTRY32 lpme);
///
/// Retrieves information about the first process encountered in a system snapshot.
///
///
/// A handle to the snapshot returned from a previous call to the CreateToolhelp32Snapshot function.
///
///
///
/// A pointer to a PROCESSENTRY32 structure. It contains process information such as the name of the executable file, the process
/// identifier, and the process identifier of the parent process.
///
///
///
///
/// Returns TRUE if the first entry of the process list has been copied to the buffer or FALSE otherwise. The
/// ERROR_NO_MORE_FILES error value is returned by the GetLastError function if no processes exist or the snapshot does not
/// contain process information.
///
///
///
/// The calling application must set the dwSize member of PROCESSENTRY32 to the size, in bytes, of the structure.
/// To retrieve information about other processes recorded in the same snapshot, use the Process32Next function.
/// Examples
/// For an example, see Taking a Snapshot and Viewing Processes.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/tlhelp32/nf-tlhelp32-process32first BOOL Process32First( HANDLE hSnapshot,
// LPPROCESSENTRY32 lppe );
[DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("tlhelp32.h", MSDNShortId = "097790e8-30c2-4b00-9256-fa26e2ceb893")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool Process32First(HSNAPSHOT hSnapshot, ref PROCESSENTRY32 lppe);
///
/// Retrieves information about the next process recorded in a system snapshot.
///
///
/// A handle to the snapshot returned from a previous call to the CreateToolhelp32Snapshot function.
///
///
/// A pointer to a PROCESSENTRY32 structure.
///
///
///
/// Returns TRUE if the next entry of the process list has been copied to the buffer or FALSE otherwise. The
/// ERROR_NO_MORE_FILES error value is returned by the GetLastError function if no processes exist or the snapshot does not
/// contain process information.
///
///
///
/// To retrieve information about the first process recorded in a snapshot, use the Process32First function.
/// Examples
/// For an example, see Taking a Snapshot and Viewing Processes.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/tlhelp32/nf-tlhelp32-process32next BOOL Process32Next( HANDLE hSnapshot,
// LPPROCESSENTRY32 lppe );
[DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("tlhelp32.h", MSDNShortId = "843a95fd-27ae-4215-83d0-82fc402b82b6")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool Process32Next(HSNAPSHOT hSnapshot, ref PROCESSENTRY32 lppe);
///
/// Retrieves information about the first thread of any process encountered in a system snapshot.
///
///
/// A handle to the snapshot returned from a previous call to the CreateToolhelp32Snapshot function.
///
///
/// A pointer to a THREADENTRY32 structure.
///
///
///
/// Returns TRUE if the first entry of the thread list has been copied to the buffer or FALSE otherwise. The
/// ERROR_NO_MORE_FILES error value is returned by the GetLastError function if no threads exist or the snapshot does not
/// contain thread information.
///
///
///
///
/// The calling application must set the dwSize member of THREADENTRY32 to the size, in bytes, of the structure.
/// Thread32First changes dwSize to the number of bytes written to the structure. This will never be greater than the
/// initial value of dwSize, but it may be smaller. If the value is smaller, do not rely on the values of any members whose
/// offsets are greater than this value.
///
/// To retrieve information about other threads recorded in the same snapshot, use the Thread32Next function.
/// Examples
/// For an example, see Traversing the Thread List.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/tlhelp32/nf-tlhelp32-thread32first BOOL Thread32First( HANDLE hSnapshot,
// LPTHREADENTRY32 lpte );
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("tlhelp32.h", MSDNShortId = "d4cb7a19-850e-43b5-bda5-91be48382d2a")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool Thread32First(HSNAPSHOT hSnapshot, ref THREADENTRY32 lpte);
///
/// Retrieves information about the next thread of any process encountered in the system memory snapshot.
///
///
/// A handle to the snapshot returned from a previous call to the CreateToolhelp32Snapshot function.
///
///
/// A pointer to a THREADENTRY32 structure.
///
///
///
/// Returns TRUE if the next entry of the thread list has been copied to the buffer or FALSE otherwise. The
/// ERROR_NO_MORE_FILES error value is returned by the GetLastError function if no threads exist or the snapshot does not
/// contain thread information.
///
///
///
/// To retrieve information about the first thread recorded in a snapshot, use the Thread32First function.
/// Examples
/// For an example, see Traversing the Thread List.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/tlhelp32/nf-tlhelp32-thread32next BOOL Thread32Next( HANDLE hSnapshot,
// LPTHREADENTRY32 lpte );
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("tlhelp32.h", MSDNShortId = "5efe514e-626c-4138-97a0-bdad217c424f")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool Thread32Next(HSNAPSHOT hSnapshot, ref THREADENTRY32 lpte);
///
/// Copies memory allocated to another process into an application-supplied buffer.
///
///
///
/// The identifier of the process whose memory is being copied. This parameter can be zero to copy the memory of the current process.
///
///
///
///
/// The base address in the specified process to read. Before transferring any data, the system verifies that all data in the base
/// address and memory of the specified size is accessible for read access. If this is the case, the function proceeds. Otherwise,
/// the function fails.
///
///
///
/// A pointer to a buffer that receives the contents of the address space of the specified process.
///
///
/// The number of bytes to read from the specified process.
///
///
/// The number of bytes copied to the specified buffer. If this parameter is NULL, it is ignored.
///
///
/// Returns TRUE if successful.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/tlhelp32/nf-tlhelp32-toolhelp32readprocessmemory BOOL
// Toolhelp32ReadProcessMemory( DWORD th32ProcessID, LPCVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T cbRead, SIZE_T
// *lpNumberOfBytesRead );
[DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("tlhelp32.h", MSDNShortId = "e579b813-32ef-481d-8dc6-f959ec9b6bad")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool Toolhelp32ReadProcessMemory(uint th32ProcessID, IntPtr lpBaseAddress, IntPtr lpBuffer, SizeT cbRead, out SizeT lpNumberOfBytesRead);
///
/// Describes one entry (block) of a heap that is being examined.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/tlhelp32/ns-tlhelp32-tagheapentry32 typedef struct tagHEAPENTRY32 { SIZE_T
// dwSize; HANDLE hHandle; ULONG_PTR dwAddress; SIZE_T dwBlockSize; DWORD dwFlags; DWORD dwLockCount; DWORD dwResvd; DWORD
// th32ProcessID; ULONG_PTR th32HeapID; } HEAPENTRY32;
[PInvokeData("tlhelp32.h", MSDNShortId = "c5f1dc66-d44f-4491-b0b7-961b163d0f1f")]
[StructLayout(LayoutKind.Sequential)]
public struct HEAPENTRY32
{
///
///
/// The size of the structure, in bytes. Before calling the Heap32First function, set this member to . If you do not initialize
/// dwSize, Heap32First fails.
///
///
public SizeT dwSize;
///
/// A handle to the heap block.
///
public IntPtr hHandle;
///
/// The linear address of the start of the block.
///
public UIntPtr dwAddress;
///
/// The size of the heap block, in bytes.
///
public SizeT dwBlockSize;
///
/// This member can be one of the following values.
///
///
/// Value
/// Meaning
///
/// -
/// LF32_FIXED
/// The memory block has a fixed (unmovable) location.
///
/// -
/// LF32_FREE
/// The memory block is not used.
///
/// -
/// LF32_MOVEABLE
/// The memory block location can be moved.
///
///
///
public uint dwFlags;
///
/// This member is no longer used and is always set to zero.
///
public uint dwLockCount;
///
/// Reserved; do not use or alter.
///
public uint dwResvd;
///
/// The identifier of the process that uses the heap.
///
public uint th32ProcessID;
///
/// The heap identifier. This is not a handle, and has meaning only to the tool help functions.
///
public UIntPtr th32HeapID;
/// Gets an empty instance with the size value set.
public static readonly HEAPENTRY32 Default = new HEAPENTRY32 { dwSize = (uint)Marshal.SizeOf(typeof(HEAPENTRY32)) };
}
///
/// Describes an entry from a list that enumerates the heaps used by a specified process.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/tlhelp32/ns-tlhelp32-tagheaplist32 typedef struct tagHEAPLIST32 { SIZE_T
// dwSize; DWORD th32ProcessID; ULONG_PTR th32HeapID; DWORD dwFlags; } HEAPLIST32;
[PInvokeData("tlhelp32.h", MSDNShortId = "61e01d23-9f15-44c5-9f6d-45df4809ccad")]
[StructLayout(LayoutKind.Sequential)]
public struct HEAPLIST32
{
///
///
/// The size of the structure, in bytes. Before calling the Heap32ListFirst function, set this member to . If you do not
/// initialize dwSize, Heap32ListFirst will fail.
///
///
public SizeT dwSize;
///
/// The identifier of the process to be examined.
///
public uint th32ProcessID;
///
/// The heap identifier. This is not a handle, and has meaning only to the tool help functions.
///
public UIntPtr th32HeapID;
///
/// This member can be one of the following values.
///
///
/// Value
/// Meaning
///
/// -
/// HF32_DEFAULT
/// Process's default heap
///
///
///
public HEAPLIST32_FLAGS dwFlags;
/// Gets an empty instance with the size value set.
public static readonly HEAPLIST32 Default = new HEAPLIST32 { dwSize = (uint)Marshal.SizeOf(typeof(HEAPLIST32)) };
/// Retrieves information about the blocks of a heap that have been allocated by a process.
/// A enumeration of structures.
public IEnumerable EnumHeapEntries()
{
var pe = HEAPENTRY32.Default;
if (!Heap32First(ref pe, th32ProcessID, th32HeapID))
throw Win32Error.GetLastError().GetException();
do { yield return pe; } while (Heap32Next(ref pe));
var err = Win32Error.GetLastError();
if (err != Win32Error.ERROR_NO_MORE_FILES)
throw err.GetException();
}
}
/// Provides a handle to a snapshot.
[StructLayout(LayoutKind.Sequential)]
public struct HSNAPSHOT : IKernelHandle
{
private IntPtr handle;
/// Initializes a new instance of the struct.
/// An object that represents the pre-existing handle to use.
public HSNAPSHOT(IntPtr preexistingHandle) => handle = preexistingHandle;
/// Returns an invalid handle by instantiating a object with .
public static HSNAPSHOT NULL => new HSNAPSHOT(IntPtr.Zero);
/// Gets a value indicating whether this instance is a null handle.
public bool IsNull => handle == IntPtr.Zero;
/// Performs an explicit conversion from to .
/// The handle.
/// The result of the conversion.
public static explicit operator IntPtr(HSNAPSHOT h) => h.handle;
/// Performs an implicit conversion from to .
/// The pointer to a handle.
/// The result of the conversion.
public static implicit operator HSNAPSHOT(IntPtr h) => new HSNAPSHOT(h);
/// Implements the operator !=.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator !=(HSNAPSHOT h1, HSNAPSHOT h2) => !(h1 == h2);
/// Implements the operator ==.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator ==(HSNAPSHOT h1, HSNAPSHOT h2) => h1.Equals(h2);
///
public override bool Equals(object obj) => obj is HSNAPSHOT h ? handle == h.handle : false;
///
public override int GetHashCode() => handle.GetHashCode();
///
public IntPtr DangerousGetHandle() => handle;
}
///
/// Describes an entry from a list of the modules belonging to the specified process.
///
///
/// The modBaseAddr and hModule members are valid only in the context of the process specified by th32ProcessID.
/// Examples
/// For an example that uses MODULEENTRY32, see Traversing the Module List.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/tlhelp32/ns-tlhelp32-tagmoduleentry32 typedef struct tagMODULEENTRY32 { DWORD
// dwSize; DWORD th32ModuleID; DWORD th32ProcessID; DWORD GlblcntUsage; DWORD ProccntUsage; BYTE *modBaseAddr; DWORD modBaseSize;
// HMODULE hModule; char szModule[MAX_MODULE_NAME32 + 1]; char szExePath[MAX_PATH]; } MODULEENTRY32;
[PInvokeData("tlhelp32.h", MSDNShortId = "305fab35-625c-42e3-a434-e2513e4c8870")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct MODULEENTRY32
{
private const int MAX_MODULE_NAME32 = 255;
///
///
/// The size of the structure, in bytes. Before calling the Module32First function, set this member to . If you do not initialize
/// dwSize, Module32First fails.
///
///
public uint dwSize;
///
/// This member is no longer used, and is always set to one.
///
public uint th32ModuleID;
///
/// The identifier of the process whose modules are to be examined.
///
public uint th32ProcessID;
///
/// The load count of the module, which is not generally meaningful, and usually equal to 0xFFFF.
///
public uint GlblcntUsage;
///
/// The load count of the module (same as GlblcntUsage), which is not generally meaningful, and usually equal to 0xFFFF.
///
public uint ProccntUsage;
///
/// The base address of the module in the context of the owning process.
///
public IntPtr modBaseAddr;
///
/// The size of the module, in bytes.
///
public uint modBaseSize;
///
/// A handle to the module in the context of the owning process.
///
public HINSTANCE hModule;
///
/// The module name.
///
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_MODULE_NAME32 + 1)]
public string szModule;
///
/// The module path.
///
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)]
public string szExePath;
/// Gets an empty instance with the size value set.
public static readonly MODULEENTRY32 Default = new MODULEENTRY32 { dwSize = (uint)Marshal.SizeOf(typeof(MODULEENTRY32)) };
}
///
/// Describes an entry from a list of the processes residing in the system address space when a snapshot was taken.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/tlhelp32/ns-tlhelp32-tagprocessentry32 typedef struct tagPROCESSENTRY32 {
// DWORD dwSize; DWORD cntUsage; DWORD th32ProcessID; ULONG_PTR th32DefaultHeapID; DWORD th32ModuleID; DWORD cntThreads; DWORD
// th32ParentProcessID; LONG pcPriClassBase; DWORD dwFlags; CHAR szExeFile[MAX_PATH]; } PROCESSENTRY32;
[PInvokeData("tlhelp32.h", MSDNShortId = "9e2f7345-52bf-4bfc-9761-90b0b374c727")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct PROCESSENTRY32
{
///
///
/// The size of the structure, in bytes. Before calling the Process32First function, set this member to . If you do not
/// initialize dwSize, Process32First fails.
///
///
public uint dwSize;
///
/// This member is no longer used and is always set to zero.
///
public uint cntUsage;
///
/// The process identifier.
///
public uint th32ProcessID;
///
/// This member is no longer used and is always set to zero.
///
public UIntPtr th32DefaultHeapID;
///
/// This member is no longer used and is always set to zero.
///
public uint th32ModuleID;
///
/// The number of execution threads started by the process.
///
public uint cntThreads;
///
/// The identifier of the process that created this process (its parent process).
///
public uint th32ParentProcessID;
///
/// The base priority of any threads created by this process.
///
public int pcPriClassBase;
///
/// This member is no longer used, and is always set to zero.
///
public uint dwFlags;
///
///
/// The name of the executable file for the process. To retrieve the full path to the executable file, call the Module32First
/// function and check the szExePath member of the MODULEENTRY32 structure that is returned. However, if the calling
/// process is a 32-bit process, you must call the QueryFullProcessImageName function to retrieve the full path of the executable
/// file for a 64-bit process.
///
///
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)]
public string szExeFile;
/// Gets an empty instance with the size value set.
public static readonly PROCESSENTRY32 Default = new PROCESSENTRY32 { dwSize = (uint)Marshal.SizeOf(typeof(PROCESSENTRY32)) };
}
///
/// Describes an entry from a list of the threads executing in the system when a snapshot was taken.
///
// https://docs.microsoft.com/en-us/windows/desktop/api/tlhelp32/ns-tlhelp32-tagthreadentry32 typedef struct tagTHREADENTRY32 { DWORD
// dwSize; DWORD cntUsage; DWORD th32ThreadID; DWORD th32OwnerProcessID; LONG tpBasePri; LONG tpDeltaPri; DWORD dwFlags; } THREADENTRY32;
[PInvokeData("tlhelp32.h", MSDNShortId = "923feca1-8807-4752-8a5a-79075688aabd")]
[StructLayout(LayoutKind.Sequential)]
public struct THREADENTRY32
{
///
///
/// The size of the structure, in bytes. Before calling the Thread32First function, set this member to . If you do not initialize
/// dwSize, Thread32First fails.
///
///
public uint dwSize;
///
/// This member is no longer used and is always set to zero.
///
public uint cntUsage;
///
/// The thread identifier, compatible with the thread identifier returned by the CreateProcess function.
///
public uint th32ThreadID;
///
/// The identifier of the process that created the thread.
///
public uint th32OwnerProcessID;
///
///
/// The kernel base priority level assigned to the thread. The priority is a number from 0 to 31, with 0 representing the lowest
/// possible thread priority. For more information, see KeQueryPriorityThread.
///
///
public int tpBasePri;
///
/// This member is no longer used and is always set to zero.
///
public int tpDeltaPri;
///
/// This member is no longer used and is always set to zero.
///
public uint dwFlags;
/// Gets an empty instance with the size value set.
public static readonly THREADENTRY32 Default = new THREADENTRY32 { dwSize = (uint)Marshal.SizeOf(typeof(THREADENTRY32)) };
}
/// Provides a to a snapshot that releases a created HSNAPSHOT instance at disposal using CloseHandle.
public class SafeHSNAPSHOT : SafeKernelHandle
{
/// Initializes a new instance of the class and assigns an existing handle.
/// An object that represents the pre-existing handle to use.
///
/// to reliably release the handle during the finalization phase; otherwise, (not recommended).
///
public SafeHSNAPSHOT(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
private SafeHSNAPSHOT() : base()
{
}
private delegate bool FirstNext(HSNAPSHOT h, ref TStruct str) where TStruct : struct;
/// Performs an implicit conversion from to .
/// The safe handle instance.
/// The result of the conversion.
public static implicit operator HSNAPSHOT(SafeHSNAPSHOT h) => h.handle;
/// Retrieves information about the heaps that have been allocated by a specified process.
/// A enumeration of structures.
public IEnumerable EnumHeap32List() => EnumSnap(Heap32ListFirst, Heap32ListNext);
/// Retrieves information about the modules that are associated with a process.
/// A enumeration of structures.
public IEnumerable EnumModule32() => EnumSnap(Module32First, Module32Next);
/// Retrieves information about the processes encountered in a system snapshot.
/// A enumeration of structures.
public IEnumerable EnumProcess32() => EnumSnap(Process32First, Process32Next);
/// Retrieves information about the threads of any process encountered in a system snapshot.
/// A enumeration of structures.
public IEnumerable EnumThread32() => EnumSnap(Thread32First, Thread32Next);
private IEnumerable EnumSnap(FirstNext first, FirstNext next) where TStruct : struct
{
var pe = Vanara.Extensions.ReflectionExtensions.GetStaticFieldValue("Default");
if (!first(handle, ref pe))
throw Win32Error.GetLastError().GetException();
do { yield return pe; } while (next(handle, ref pe));
var err = Win32Error.GetLastError();
if (err != Win32Error.ERROR_NO_MORE_FILES)
throw err.GetException();
}
}
}
}