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(); } } } }