Vanara/PInvoke/Kernel32/ProcessSnapshot.cs

2058 lines
86 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Vanara.InteropServices;
using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME;
namespace Vanara.PInvoke
{
public static partial class Kernel32
{
/// <summary>The resolution in microseconds of the performance counters in PSS_PERFORMANCE_COUNTERS.</summary>
[PInvokeData("processsnapshot.h")]
public const uint PSS_PERF_RESOLUTION = 1000000;
/// <summary>
/// <para>Flags that specify what PssCaptureSnapshot captures.</para>
/// </summary>
/// <remarks>
/// <para>
/// If both <c>PSS_CREATE_FORCE_BREAKAWAY</c> and <c>PSS_CREATE_BREAKAWAY</c> are specified, then <c>PSS_CREATE_FORCE_BREAKAWAY</c>
/// takes precedence.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/api/processsnapshot/ne-processsnapshot-pss_capture_flags
// typedef enum PSS_CAPTURE_FLAGS { PSS_CAPTURE_NONE , PSS_CAPTURE_VA_CLONE , PSS_CAPTURE_RESERVED_00000002 , PSS_CAPTURE_HANDLES ,
// PSS_CAPTURE_HANDLE_NAME_INFORMATION , PSS_CAPTURE_HANDLE_BASIC_INFORMATION , PSS_CAPTURE_HANDLE_TYPE_SPECIFIC_INFORMATION ,
// PSS_CAPTURE_HANDLE_TRACE , PSS_CAPTURE_THREADS , PSS_CAPTURE_THREAD_CONTEXT , PSS_CAPTURE_THREAD_CONTEXT_EXTENDED ,
// PSS_CAPTURE_RESERVED_00000400 , PSS_CAPTURE_VA_SPACE , PSS_CAPTURE_VA_SPACE_SECTION_INFORMATION , PSS_CAPTURE_IPT_TRACE ,
// PSS_CREATE_BREAKAWAY_OPTIONAL , PSS_CREATE_BREAKAWAY , PSS_CREATE_FORCE_BREAKAWAY , PSS_CREATE_USE_VM_ALLOCATIONS ,
// PSS_CREATE_MEASURE_PERFORMANCE , PSS_CREATE_RELEASE_SECTION } ;
[PInvokeData("processsnapshot.h", MSDNShortId = "6146DDA2-2475-45F8-86F3-65791B10743D")]
[Flags]
public enum PSS_CAPTURE_FLAGS : uint
{
/// <summary>Capture nothing.</summary>
PSS_CAPTURE_NONE = 0x00000000,
/// <summary>
/// Capture a snapshot of all cloneable pages in the process. The clone includes all MEM_PRIVATE regions, as well as all sections
/// (MEM_MAPPED and MEM_IMAGE) that are shareable. All Win32 sections created via CreateFileMapping are shareable.
/// </summary>
PSS_CAPTURE_VA_CLONE = 0x00000001,
/// <summary>(Do not use.)</summary>
PSS_CAPTURE_RESERVED_00000002 = 0x00000002,
/// <summary>Capture the handle table (handle values only).</summary>
PSS_CAPTURE_HANDLES = 0x00000004,
/// <summary>Capture name information for each handle.</summary>
PSS_CAPTURE_HANDLE_NAME_INFORMATION = 0x00000008,
/// <summary>Capture basic handle information such as HandleCount, PointerCount, GrantedAccess, etc.</summary>
PSS_CAPTURE_HANDLE_BASIC_INFORMATION = 0x00000010,
/// <summary>Capture type-specific information for supported object types: Process, Thread, Event, Mutant, Section.</summary>
PSS_CAPTURE_HANDLE_TYPE_SPECIFIC_INFORMATION = 0x00000020,
/// <summary>Capture the handle tracing table.</summary>
PSS_CAPTURE_HANDLE_TRACE = 0x00000040,
/// <summary>Capture thread information (IDs only).</summary>
PSS_CAPTURE_THREADS = 0x00000080,
/// <summary>Capture the context for each thread.</summary>
PSS_CAPTURE_THREAD_CONTEXT = 0x00000100,
/// <summary>Capture extended context for each thread (e.g. CONTEXT_XSTATE).</summary>
PSS_CAPTURE_THREAD_CONTEXT_EXTENDED = 0x00000200,
/// <summary>(Do not use.)</summary>
PSS_CAPTURE_RESERVED_00000400 = 0x00000400,
/// <summary>
/// Capture a snapshot of the virtual address space. The VA space is captured as an array of MEMORY_BASIC_INFORMATION structures.
/// This flag does not capture the contents of the pages.
/// </summary>
PSS_CAPTURE_VA_SPACE = 0x00000800,
/// <summary>
/// For MEM_IMAGE and MEM_MAPPED regions, dumps the path to the file backing the sections (identical to what GetMappedFileName
/// returns). For MEM_IMAGE regions, also dumps: The PROCESS_VM_READ access right is required on the process handle.
/// </summary>
PSS_CAPTURE_VA_SPACE_SECTION_INFORMATION = 0x00001000,
/// <summary/>
PSS_CAPTURE_IPT_TRACE = 0x00002000,
/// <summary>
/// The breakaway is optional. If the clone process fails to create as a breakaway, then it is created still inside the job. This
/// flag must be specified in combination with either PSS_CREATE_FORCE_BREAKAWAY and/or PSS_CREATE_BREAKAWAY.
/// </summary>
PSS_CREATE_BREAKAWAY_OPTIONAL = 0x04000000,
/// <summary>The clone is broken away from the parent process' job. This is equivalent to CreateProcess flag CREATE_BREAKAWAY_FROM_JOB.</summary>
PSS_CREATE_BREAKAWAY = 0x08000000,
/// <summary>The clone is forcefully broken away the parent process's job. This is only allowed for Tcb-privileged callers.</summary>
PSS_CREATE_FORCE_BREAKAWAY = 0x10000000,
/// <summary>
/// The facility should not use the process heap for any persistent or transient allocations. The use of the heap may be
/// undesirable in certain contexts such as creation of snapshots in the exception reporting path (where the heap may be corrupted).
/// </summary>
PSS_CREATE_USE_VM_ALLOCATIONS = 0x20000000,
/// <summary>
/// Measure performance of the facility. Performance counters can be retrieved via PssQuerySnapshot with the
/// PSS_QUERY_PERFORMANCE_COUNTERS information class of PSS_QUERY_INFORMATION_CLASS.
/// </summary>
PSS_CREATE_MEASURE_PERFORMANCE = 0x40000000,
/// <summary>
/// The virtual address (VA) clone process does not hold a reference to the underlying image. This will cause functions such as
/// QueryFullProcessImageName to fail on the VA clone process.
/// </summary>
PSS_CREATE_RELEASE_SECTION = 0x80000000
}
/// <summary>
/// <para>Duplication flags for use by PssDuplicateSnapshot.</para>
/// </summary>
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/api/processsnapshot/ne-processsnapshot-pss_duplicate_flags
// typedef enum PSS_DUPLICATE_FLAGS { PSS_DUPLICATE_NONE , PSS_DUPLICATE_CLOSE_SOURCE } ;
[PInvokeData("processsnapshot.h", MSDNShortId = "CAD06441-750F-42FC-A95A-7CAA79F31348")]
[Flags]
public enum PSS_DUPLICATE_FLAGS
{
/// <summary>No flag.</summary>
PSS_DUPLICATE_NONE = 0x00,
/// <summary>
/// Free the source handle. This will only succeed if you set the PSS_CREATE_USE_VM_ALLOCATIONS flag when you called
/// PssCaptureSnapshot to create the snapshot and handle. The handle will be freed even if duplication fails. The close operation
/// does not protect against concurrent access to the same descriptor.
/// </summary>
PSS_DUPLICATE_CLOSE_SOURCE = 0x01
}
/// <summary>
/// <para>Flags to specify what parts of a PSS_HANDLE_ENTRY structure are valid.</para>
/// </summary>
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/api/processsnapshot/ne-processsnapshot-pss_handle_flags typedef
// enum PSS_HANDLE_FLAGS { PSS_HANDLE_NONE , PSS_HANDLE_HAVE_TYPE , PSS_HANDLE_HAVE_NAME , PSS_HANDLE_HAVE_BASIC_INFORMATION ,
// PSS_HANDLE_HAVE_TYPE_SPECIFIC_INFORMATION } ;
[PInvokeData("processsnapshot.h", MSDNShortId = "A4A604A9-0210-413C-BCAC-F8458B371D42")]
[Flags]
public enum PSS_HANDLE_FLAGS
{
/// <summary>No parts specified.</summary>
PSS_HANDLE_NONE = 0x00,
/// <summary>The ObjectType member is valid.</summary>
PSS_HANDLE_HAVE_TYPE = 0x01,
/// <summary>The ObjectName member is valid.</summary>
PSS_HANDLE_HAVE_NAME = 0x02,
/// <summary>
/// The Attributes, GrantedAccess, HandleCount, PointerCount, PagedPoolCharge, and NonPagedPoolCharge members are valid.
/// </summary>
PSS_HANDLE_HAVE_BASIC_INFORMATION = 0x04,
/// <summary>The TypeSpecificInformation member is valid (either Process, Thread, Mutant, Event or Section).</summary>
PSS_HANDLE_HAVE_TYPE_SPECIFIC_INFORMATION = 0x08
}
/// <summary>
/// <para>Specifies the object type in a PSS_HANDLE_ENTRY structure.</para>
/// </summary>
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/api/processsnapshot/ne-processsnapshot-pss_object_type typedef
// enum PSS_OBJECT_TYPE { PSS_OBJECT_TYPE_UNKNOWN , PSS_OBJECT_TYPE_PROCESS , PSS_OBJECT_TYPE_THREAD , PSS_OBJECT_TYPE_MUTANT ,
// PSS_OBJECT_TYPE_EVENT , PSS_OBJECT_TYPE_SECTION , PSS_OBJECT_TYPE_SEMAPHORE } ;
[PInvokeData("processsnapshot.h", MSDNShortId = "3AF2AE47-6E1A-4B20-B6A3-36C1DDB80674")]
public enum PSS_OBJECT_TYPE
{
/// <summary>The object type is either unknown or unsupported.</summary>
PSS_OBJECT_TYPE_UNKNOWN,
/// <summary>The object is a process.</summary>
PSS_OBJECT_TYPE_PROCESS,
/// <summary>The object is a thread.</summary>
PSS_OBJECT_TYPE_THREAD,
/// <summary>The object is a mutant/mutex.</summary>
PSS_OBJECT_TYPE_MUTANT,
/// <summary>The object is an event.</summary>
PSS_OBJECT_TYPE_EVENT,
/// <summary>The object is a file-mapping object.</summary>
PSS_OBJECT_TYPE_SECTION,
/// <summary/>
PSS_OBJECT_TYPE_SEMAPHORE,
}
/// <summary>
/// <para>Flags that describe a process.</para>
/// </summary>
/// <remarks>
/// <para>There are <c>PSS_PROCESS_FLAGS</c> members in the PSS_PROCESS_INFORMATION and PSS_HANDLE_ENTRY structures.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/api/processsnapshot/ne-processsnapshot-pss_process_flags
// typedef enum PSS_PROCESS_FLAGS { PSS_PROCESS_FLAGS_NONE , PSS_PROCESS_FLAGS_PROTECTED , PSS_PROCESS_FLAGS_WOW64 ,
// PSS_PROCESS_FLAGS_RESERVED_03 , PSS_PROCESS_FLAGS_RESERVED_04 , PSS_PROCESS_FLAGS_FROZEN } ;
[PInvokeData("processsnapshot.h", MSDNShortId = "A1C793DD-EE93-47B6-8EA8-3A45DAD55F2D")]
[Flags]
public enum PSS_PROCESS_FLAGS
{
/// <summary>No flag.</summary>
PSS_PROCESS_FLAGS_NONE = 0x00000000,
/// <summary>The process is protected.</summary>
PSS_PROCESS_FLAGS_PROTECTED = 0x00000001,
/// <summary>The process is a 32-bit process running on a 64-bit native OS.</summary>
PSS_PROCESS_FLAGS_WOW64 = 0x00000002,
/// <summary>Undefined.</summary>
PSS_PROCESS_FLAGS_RESERVED_03 = 0x00000004,
/// <summary>Undefined.</summary>
PSS_PROCESS_FLAGS_RESERVED_04 = 0x00000008,
/// <summary>
/// The process is frozen; for example, a debugger is attached and broken into the process or a Store process is suspended by a
/// lifetime management service.
/// </summary>
PSS_PROCESS_FLAGS_FROZEN = 0x00000010
}
/// <summary>
/// <para>Specifies what information PssQuerySnapshot function returns.</para>
/// </summary>
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/api/processsnapshot/ne-processsnapshot-pss_query_information_class
// typedef enum PSS_QUERY_INFORMATION_CLASS { PSS_QUERY_PROCESS_INFORMATION , PSS_QUERY_VA_CLONE_INFORMATION ,
// PSS_QUERY_AUXILIARY_PAGES_INFORMATION , PSS_QUERY_VA_SPACE_INFORMATION , PSS_QUERY_HANDLE_INFORMATION ,
// PSS_QUERY_THREAD_INFORMATION , PSS_QUERY_HANDLE_TRACE_INFORMATION , PSS_QUERY_PERFORMANCE_COUNTERS } ;
[PInvokeData("processsnapshot.h", MSDNShortId = "1C3E5BF4-5AC9-4012-B29D-49C35C0AF90B")]
public enum PSS_QUERY_INFORMATION_CLASS
{
/// <summary>Returns a PSS_PROCESS_INFORMATION structure, with information about the original process.</summary>
[CorrespondingType(typeof(PSS_PROCESS_INFORMATION), CorrespondingAction.Get)]
PSS_QUERY_PROCESS_INFORMATION,
/// <summary>Returns a PSS_VA_CLONE_INFORMATION structure, with a handle to the VA clone.</summary>
[CorrespondingType(typeof(PSS_VA_CLONE_INFORMATION), CorrespondingAction.Get)]
PSS_QUERY_VA_CLONE_INFORMATION,
/// <summary>Returns a PSS_AUXILIARY_PAGES_INFORMATION structure, which contains the count of auxiliary pages captured.</summary>
[CorrespondingType(typeof(PSS_AUXILIARY_PAGES_INFORMATION), CorrespondingAction.Get)]
PSS_QUERY_AUXILIARY_PAGES_INFORMATION,
/// <summary>Returns a PSS_VA_SPACE_INFORMATION structure, which contains the count of regions captured.</summary>
[CorrespondingType(typeof(PSS_VA_SPACE_INFORMATION), CorrespondingAction.Get)]
PSS_QUERY_VA_SPACE_INFORMATION,
/// <summary>Returns a PSS_HANDLE_INFORMATION structure, which contains the count of handles captured.</summary>
[CorrespondingType(typeof(PSS_HANDLE_INFORMATION), CorrespondingAction.Get)]
PSS_QUERY_HANDLE_INFORMATION,
/// <summary>Returns a PSS_THREAD_INFORMATION structure, which contains the count of threads captured.</summary>
[CorrespondingType(typeof(PSS_THREAD_INFORMATION), CorrespondingAction.Get)]
PSS_QUERY_THREAD_INFORMATION,
/// <summary>
/// Returns a PSS_HANDLE_TRACE_INFORMATION structure, which contains a handle to the handle trace section, and its size.
/// </summary>
[CorrespondingType(typeof(PSS_HANDLE_TRACE_INFORMATION), CorrespondingAction.Get)]
PSS_QUERY_HANDLE_TRACE_INFORMATION,
/// <summary>Returns a PSS_PERFORMANCE_COUNTERS structure, which contains various performance counters.</summary>
[CorrespondingType(typeof(PSS_PERFORMANCE_COUNTERS), CorrespondingAction.Get)]
PSS_QUERY_PERFORMANCE_COUNTERS,
}
/// <summary>
/// <para>Flags that describe a thread.</para>
/// </summary>
/// <remarks>
/// <para>There is a <c>PSS_THREAD_FLAGS</c> member in the PSS_THREAD_ENTRY structure that PssWalkSnapshot returns.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/api/processsnapshot/ne-processsnapshot-pss_thread_flags typedef
// enum PSS_THREAD_FLAGS { PSS_THREAD_FLAGS_NONE , PSS_THREAD_FLAGS_TERMINATED } ;
[PInvokeData("processsnapshot.h", MSDNShortId = "8E90F0EA-D50A-431D-9507-B882EB673629")]
[Flags]
public enum PSS_THREAD_FLAGS
{
/// <summary>No flag.</summary>
PSS_THREAD_FLAGS_NONE = 0x0000,
/// <summary>The thread terminated.</summary>
PSS_THREAD_FLAGS_TERMINATED = 0x0001
}
/// <summary>
/// <para>Specifies what information the PssWalkSnapshot function returns.</para>
/// </summary>
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/api/processsnapshot/ne-processsnapshot-pss_walk_information_class
// typedef enum PSS_WALK_INFORMATION_CLASS { PSS_WALK_AUXILIARY_PAGES , PSS_WALK_VA_SPACE , PSS_WALK_HANDLES , PSS_WALK_THREADS } ;
[PInvokeData("processsnapshot.h", MSDNShortId = "93A79F7F-2164-4F7A-ADE7-C1655EEFC9BF")]
public enum PSS_WALK_INFORMATION_CLASS
{
/// <summary>
/// Returns a PSS_AUXILIARY_PAGE_ENTRY structure, which contains the address, page attributes and contents of an auxiliary copied page.
/// </summary>
[CorrespondingType(typeof(PSS_AUXILIARY_PAGE_ENTRY), CorrespondingAction.Get)]
PSS_WALK_AUXILIARY_PAGES,
/// <summary>
/// Returns a PSS_VA_SPACE_ENTRY structure, which contains the MEMORY_BASIC_INFORMATION structure for every distinct VA region.
/// </summary>
[CorrespondingType(typeof(PSS_VA_SPACE_ENTRY), CorrespondingAction.Get)]
PSS_WALK_VA_SPACE,
/// <summary>
/// Returns a PSS_HANDLE_ENTRY structure, with information specifying the handle value, its type name, object name (if captured),
/// basic information (if captured), and type-specific information (if captured).
/// </summary>
[CorrespondingType(typeof(PSS_HANDLE_ENTRY), CorrespondingAction.Get)]
PSS_WALK_HANDLES,
/// <summary>
/// Returns a PSS_THREAD_ENTRY structure, with basic information about the thread, as well as its termination state, suspend
/// count and Win32 start address.
/// </summary>
[CorrespondingType(typeof(PSS_THREAD_ENTRY), CorrespondingAction.Get)]
PSS_WALK_THREADS,
}
/// <summary>
/// <para>Captures a snapshot of a target process.</para>
/// </summary>
/// <param name="ProcessHandle">
/// <para>A handle to the target process.</para>
/// </param>
/// <param name="CaptureFlags">
/// <para>Flags that specify what to capture. For more information, see PSS_CAPTURE_FLAGS.</para>
/// </param>
/// <param name="ThreadContextFlags">
/// <para>The <c>CONTEXT</c> record flags to capture if CaptureFlags specifies thread contexts.</para>
/// </param>
/// <param name="SnapshotHandle">
/// <para>A handle to the snapshot that this function captures.</para>
/// </param>
/// <returns>
/// <para>This function returns <c>ERROR_SUCCESS</c> on success.</para>
/// <para>
/// All error codes are defined in winerror.h. Use FormatMessage with the <c>FORMAT_MESSAGE_FROM_SYSTEM</c> flag to get a message for
/// an error code.
/// </para>
/// </returns>
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/api/processsnapshot/nf-processsnapshot-psscapturesnapshot DWORD
// PssCaptureSnapshot( HANDLE ProcessHandle, PSS_CAPTURE_FLAGS CaptureFlags, DWORD ThreadContextFlags, HPSS *SnapshotHandle );
[PInvokeData("processsnapshot.h", MSDNShortId = "44F2CB48-A9F6-4131-B21C-9F27A27CECD5")]
public static Win32Error PssCaptureSnapshot(HPROCESS ProcessHandle, PSS_CAPTURE_FLAGS CaptureFlags, uint ThreadContextFlags, out SafeHPSS SnapshotHandle)
{
var err = PssCaptureSnapshotInternal(ProcessHandle, CaptureFlags, ThreadContextFlags, out SnapshotHandle);
SnapshotHandle.ProcessHandle = ProcessHandle;
return err;
}
/// <summary>
/// <para>Duplicates a snapshot handle from one process to another.</para>
/// </summary>
/// <param name="SourceProcessHandle">
/// <para>
/// A handle to the source process from which the original snapshot was captured. The handle must have <c>PROCESS_VM_READ</c> and
/// <c>PROCESS_DUP_HANDLE</c> rights.
/// </para>
/// </param>
/// <param name="SnapshotHandle">
/// <para>A handle to the snapshot to duplicate. This handle must be in the context of the source process.</para>
/// </param>
/// <param name="TargetProcessHandle">
/// <para>
/// A handle to the target process that receives the duplicate snapshot. The handle must have <c>PROCESS_VM_OPERATION</c>,
/// <c>PROCESS_VM_WRITE</c>, and <c>PROCESS_DUP_HANDLE</c> rights.
/// </para>
/// </param>
/// <param name="TargetSnapshotHandle">
/// <para>A handle to the duplicate snapshot that this function creates, in the context of the target process.</para>
/// </param>
/// <param name="Flags">
/// <para>The duplication flags. For more information, see PSS_DUPLICATE_FLAGS.</para>
/// </param>
/// <returns>
/// <para>This function returns <c>ERROR_SUCCESS</c> on success or the following error code.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_INVALID_HANDLE</term>
/// <term>The specified handle is invalid.</term>
/// </item>
/// </list>
/// <para>
/// All error codes are defined in winerror.h. Use FormatMessage with the <c>FORMAT_MESSAGE_FROM_SYSTEM</c> flag to get a message for
/// an error code.
/// </para>
/// </returns>
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/api/processsnapshot/nf-processsnapshot-pssduplicatesnapshot
// DWORD PssDuplicateSnapshot( HANDLE SourceProcessHandle, HPSS SnapshotHandle, HANDLE TargetProcessHandle, HPSS
// *TargetSnapshotHandle, PSS_DUPLICATE_FLAGS Flags );
[PInvokeData("processsnapshot.h", MSDNShortId = "5D2751F3-E7E1-4917-8060-E2BC8A7A3DEA")]
public static Win32Error PssDuplicateSnapshot(HPROCESS SourceProcessHandle, HPSS SnapshotHandle, HPROCESS TargetProcessHandle, out SafeHPSS TargetSnapshotHandle, PSS_DUPLICATE_FLAGS Flags)
{
var err = PssDuplicateSnapshot(SourceProcessHandle, SnapshotHandle, TargetProcessHandle, out TargetSnapshotHandle, Flags);
TargetSnapshotHandle.ProcessHandle = TargetProcessHandle;
return err;
}
/// <summary>
/// <para>Frees a snapshot.</para>
/// </summary>
/// <param name="ProcessHandle">
/// <para>
/// A handle to the process that contains the snapshot. The handle must have <c>PROCESS_VM_READ</c>, <c>PROCESS_VM_OPERATION</c>, and
/// <c>PROCESS_DUP_HANDLE</c> rights. If the snapshot was captured from the current process, or duplicated into the current process,
/// then pass in the result of GetCurrentProcess.
/// </para>
/// </param>
/// <param name="SnapshotHandle">
/// <para>A handle to the snapshot to free.</para>
/// </param>
/// <returns>
/// <para>This function returns <c>ERROR_SUCCESS</c> on success or one of the following error codes.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_INVALID_HANDLE</term>
/// <term>The specified handle is invalid.</term>
/// </item>
/// <item>
/// <term>ERROR_NOT_SUPPORTED</term>
/// <term>The remote snapshot was not created with PSS_CREATE_USE_VM_ALLOCATIONS.</term>
/// </item>
/// </list>
/// <para>
/// All error codes are defined in winerror.h. Use FormatMessage with the <c>FORMAT_MESSAGE_FROM_SYSTEM</c> flag to get a message for
/// an error code.
/// </para>
/// </returns>
/// <remarks>
/// <para>
/// This API can free snapshot handles in the context of either the local or remote processes. If the snapshot was captured in the
/// local process with PssCaptureSnapshot, or duplicated into the local process with PssDuplicateSnapshot, then specify the result of
/// GetCurrentProcess as the process handle. If the snapshot is in the context of a remote process (for example, duplicated into the
/// remote process), then specify the handle to that process.
/// </para>
/// <para>The operation does not protect against concurrent access to the same descriptor.</para>
/// <para>
/// For remote process frees, only snapshot handles that were created with <c>PSS_CREATE_USE_VM_ALLOCATIONS</c> or duplicated
/// remotely can be freed by this API.
/// </para>
/// <para>The behavior of this routine on a descriptor that has already been freed is undefined.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/api/processsnapshot/nf-processsnapshot-pssfreesnapshot DWORD
// PssFreeSnapshot( HANDLE ProcessHandle, HPSS SnapshotHandle );
[DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("processsnapshot.h", MSDNShortId = "5D062AE6-2F7C-4121-AB6E-9BFA06AB36C6")]
public static extern Win32Error PssFreeSnapshot(HPROCESS ProcessHandle, HPSS SnapshotHandle);
/// <summary>Queries the snapshot.</summary>
/// <param name="SnapshotHandle">A handle to the snapshot to query.</param>
/// <param name="InformationClass">An enumerator member that selects what information to query. For more information, see PSS_QUERY_INFORMATION_CLASS.</param>
/// <param name="Buffer">The information that this function provides.</param>
/// <param name="BufferLength">The size of Buffer, in bytes.</param>
/// <returns>
/// <para>This function returns <c>ERROR_SUCCESS</c> on success or one of the following error codes.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_BAD_LENGTH</term>
/// <term>The specified buffer length is invalid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_HANDLE</term>
/// <term>The specified handle is invalid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>The specified information class is invalid.</term>
/// </item>
/// <item>
/// <term>ERROR_NOT_FOUND</term>
/// <term>The requested information is not in the snapshot.</term>
/// </item>
/// </list>
/// <para>
/// All error codes are defined in winerror.h. Use FormatMessage with the <c>FORMAT_MESSAGE_FROM_SYSTEM</c> flag to get a message for
/// an error code.
/// </para>
/// </returns>
// https://docs.microsoft.com/en-us/windows/desktop/api/processsnapshot/nf-processsnapshot-pssquerysnapshot DWORD PssQuerySnapshot(
// HPSS SnapshotHandle, PSS_QUERY_INFORMATION_CLASS InformationClass, void *Buffer, DWORD BufferLength );
[DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("processsnapshot.h", MSDNShortId = "D9580147-28ED-4FF5-B7DB-844ACB19769F")]
public static extern Win32Error PssQuerySnapshot(HPSS SnapshotHandle, PSS_QUERY_INFORMATION_CLASS InformationClass, IntPtr Buffer, uint BufferLength);
/// <summary>Queries the snapshot.</summary>
/// <typeparam name="T">The type of the information to retrieve specified by <paramref name="InformationClass"/>.</typeparam>
/// <param name="SnapshotHandle">A handle to the snapshot to query.</param>
/// <param name="InformationClass">An enumerator member that selects what information to query. For more information, see PSS_QUERY_INFORMATION_CLASS.</param>
/// <returns>The information that this function provides.</returns>
/// <exception cref="ArgumentOutOfRangeException">InformationClass</exception>
public static T PssQuerySnapshot<T>(HPSS SnapshotHandle, PSS_QUERY_INFORMATION_CLASS InformationClass) where T : struct
{
if (!CorrespondingTypeAttribute.CanGet(InformationClass, typeof(T))) throw new ArgumentOutOfRangeException(nameof(InformationClass));
using (var mem = SafeCoTaskMemHandle.CreateFromStructure<T>())
{
PssQuerySnapshot(SnapshotHandle, InformationClass, (IntPtr)mem, (uint)mem.Size).ThrowIfFailed();
return mem.ToStructure<T>();
}
}
/// <summary>
/// <para>Creates a walk marker.</para>
/// </summary>
/// <param name="Allocator">
/// <para>
/// A structure that provides functions to allocate and free memory. If you provide the structure, <c>PssWalkMarkerCreate</c> uses
/// the functions to allocate the internal walk marker structures. Otherwise it uses the default process heap. For more information,
/// see PSS_ALLOCATOR.
/// </para>
/// </param>
/// <param name="WalkMarkerHandle">
/// <para>A handle to the walk marker that this function creates.</para>
/// </param>
/// <returns>
/// <para>This function returns <c>ERROR_SUCCESS</c> on success or the following error code.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_NOT_ENOUGH_MEMORY</term>
/// <term>Could not allocate memory for the walk marker.</term>
/// </item>
/// </list>
/// <para>
/// All error codes are defined in winerror.h. Use FormatMessage with the <c>FORMAT_MESSAGE_FROM_SYSTEM</c> flag to get a message for
/// an error code.
/// </para>
/// </returns>
/// <remarks>
/// <para>The walk marker maintains the state of a walk, and can be used to reposition or rewind the walk.</para>
/// <para>
/// The Allocator structure that provides the custom functions should remain valid for the lifetime of the walk marker. The custom
/// functions are called from <c>PssWalkMarkerCreate</c>, PssWalkMarkerFree and PssWalkSnapshot using the same thread that calls
/// <c>PssWalkMarkerCreate</c>, <c>PssWalkMarkerFree</c> and <c>PssWalkSnapshot</c>. Therefore the custom functions need not be multi-threaded.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/api/processsnapshot/nf-processsnapshot-psswalkmarkercreate
// DWORD PssWalkMarkerCreate( PSS_ALLOCATOR const *Allocator, HPSSWALK *WalkMarkerHandle );
[DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("processsnapshot.h", MSDNShortId = "58E2FBAF-661C-45BE-A25A-A096AF52ED3E")]
public static extern Win32Error PssWalkMarkerCreate(in PSS_ALLOCATOR Allocator, out SafeHPSSWALK WalkMarkerHandle);
/// <summary>
/// <para>Creates a walk marker.</para>
/// </summary>
/// <param name="Allocator">
/// <para>
/// A structure that provides functions to allocate and free memory. If you provide the structure, <c>PssWalkMarkerCreate</c> uses
/// the functions to allocate the internal walk marker structures. Otherwise it uses the default process heap. For more information,
/// see PSS_ALLOCATOR.
/// </para>
/// </param>
/// <param name="WalkMarkerHandle">
/// <para>A handle to the walk marker that this function creates.</para>
/// </param>
/// <returns>
/// <para>This function returns <c>ERROR_SUCCESS</c> on success or the following error code.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_NOT_ENOUGH_MEMORY</term>
/// <term>Could not allocate memory for the walk marker.</term>
/// </item>
/// </list>
/// <para>
/// All error codes are defined in winerror.h. Use FormatMessage with the <c>FORMAT_MESSAGE_FROM_SYSTEM</c> flag to get a message for
/// an error code.
/// </para>
/// </returns>
/// <remarks>
/// <para>The walk marker maintains the state of a walk, and can be used to reposition or rewind the walk.</para>
/// <para>
/// The Allocator structure that provides the custom functions should remain valid for the lifetime of the walk marker. The custom
/// functions are called from <c>PssWalkMarkerCreate</c>, PssWalkMarkerFree and PssWalkSnapshot using the same thread that calls
/// <c>PssWalkMarkerCreate</c>, <c>PssWalkMarkerFree</c> and <c>PssWalkSnapshot</c>. Therefore the custom functions need not be multi-threaded.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/api/processsnapshot/nf-processsnapshot-psswalkmarkercreate
// DWORD PssWalkMarkerCreate( PSS_ALLOCATOR const *Allocator, HPSSWALK *WalkMarkerHandle );
[DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("processsnapshot.h", MSDNShortId = "58E2FBAF-661C-45BE-A25A-A096AF52ED3E")]
public static extern Win32Error PssWalkMarkerCreate([Optional] IntPtr Allocator, out SafeHPSSWALK WalkMarkerHandle);
/// <summary>
/// <para>Frees a walk marker created by PssWalkMarkerCreate.</para>
/// </summary>
/// <param name="WalkMarkerHandle">
/// <para>A handle to the walk marker.</para>
/// </param>
/// <returns>
/// <para>This function returns <c>ERROR_SUCCESS</c> on success.</para>
/// <para>
/// All error codes are defined in winerror.h. Use FormatMessage with the <c>FORMAT_MESSAGE_FROM_SYSTEM</c> flag to get a message for
/// an error code.
/// </para>
/// </returns>
/// <remarks>
/// <para>
/// If PssWalkMarkerCreate used <c>AllocRoutine</c> of a custom allocator to create the walk marker, <c>PssWalkMarkerFree</c> uses
/// the <c>FreeRoutine</c> of the allocator.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/api/processsnapshot/nf-processsnapshot-psswalkmarkerfree DWORD
// PssWalkMarkerFree( HPSSWALK WalkMarkerHandle );
[DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("processsnapshot.h", MSDNShortId = "74158846-6A5F-4F81-B4D7-46DED1EE017C")]
public static extern Win32Error PssWalkMarkerFree(HPSSWALK WalkMarkerHandle);
/// <summary>
/// <para>Returns the current position of a walk marker.</para>
/// </summary>
/// <param name="WalkMarkerHandle">
/// <para>A handle to the walk marker.</para>
/// </param>
/// <param name="Position">
/// <para>The walk marker position that this function returns.</para>
/// </param>
/// <returns>
/// <para>This function returns <c>ERROR_SUCCESS</c> on success.</para>
/// <para>
/// All error codes are defined in winerror.h. Use FormatMessage with the <c>FORMAT_MESSAGE_FROM_SYSTEM</c> flag to get a message for
/// an error code.
/// </para>
/// </returns>
/// <remarks>
/// <para>
/// The position value compared to the values of other positions is not of any significance. The only valid use of the position is to
/// set the current position using the PssWalkMarkerSetPosition function.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/api/processsnapshot/nf-processsnapshot-psswalkmarkergetposition
// DWORD PssWalkMarkerGetPosition( HPSSWALK WalkMarkerHandle, ULONG_PTR *Position );
[DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("processsnapshot.h", MSDNShortId = "A2058E81-2B01-4436-ACC6-2A3E58BC4E27")]
public static extern Win32Error PssWalkMarkerGetPosition(HPSSWALK WalkMarkerHandle, out UIntPtr Position);
/// <summary>
/// <para>Rewinds a walk marker back to the beginning.</para>
/// </summary>
/// <param name="WalkMarkerHandle">
/// <para>A handle to the walk marker.</para>
/// </param>
/// <returns>
/// <para>This function returns <c>ERROR_SUCCESS</c> on success.</para>
/// <para>
/// All error codes are defined in winerror.h. Use FormatMessage with the <c>FORMAT_MESSAGE_FROM_SYSTEM</c> flag to get a message for
/// an error code.
/// </para>
/// </returns>
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/api/processsnapshot/nf-processsnapshot-psswalkmarkerseektobeginning
// DWORD PssWalkMarkerSeekToBeginning( HPSSWALK WalkMarkerHandle );
[DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("processsnapshot.h", MSDNShortId = "BE0FA122-3966-4827-9DA3-A98A162EF270")]
public static extern Win32Error PssWalkMarkerSeekToBeginning(HPSSWALK WalkMarkerHandle);
/// <summary>
/// <para>Sets the position of a walk marker.</para>
/// </summary>
/// <param name="WalkMarkerHandle">
/// <para>A handle to the walk marker.</para>
/// </param>
/// <param name="Position">
/// <para>The position to set. This is a position that the PssWalkMarkerGetPosition function provided.</para>
/// </param>
/// <returns>
/// <para>This function returns <c>ERROR_SUCCESS</c> on success or one of the following error codes.</para>
/// <para>
/// All error codes are defined in winerror.h. Use FormatMessage with the <c>FORMAT_MESSAGE_FROM_SYSTEM</c> flag to get a message for
/// an error code.
/// </para>
/// </returns>
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/api/processsnapshot/nf-processsnapshot-psswalkmarkersetposition
// DWORD PssWalkMarkerSetPosition( HPSSWALK WalkMarkerHandle, ULONG_PTR Position );
[DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("processsnapshot.h", MSDNShortId = "D89EA4DB-D8C6-43D1-B292-D24F1EAB2E43")]
public static extern Win32Error PssWalkMarkerSetPosition(HPSSWALK WalkMarkerHandle, UIntPtr Position);
/// <summary>
/// <para>Returns information from the current walk position and advanced the walk marker to the next position.</para>
/// </summary>
/// <param name="SnapshotHandle">
/// <para>A handle to the snapshot.</para>
/// </param>
/// <param name="InformationClass">
/// <para>The type of information to return. For more information, see PSS_WALK_INFORMATION_CLASS.</para>
/// </param>
/// <param name="WalkMarkerHandle">
/// <para>
/// A handle to a walk marker. The walk marker indicates the walk position from which data is to be returned. <c>PssWalkSnapshot</c>
/// advances the walk marker to the next walk position in time order before returning to the caller.
/// </para>
/// </param>
/// <param name="Buffer">
/// <para>The snapshot information that this function returns.</para>
/// </param>
/// <param name="BufferLength">
/// <para>The size of Buffer, in bytes.</para>
/// </param>
/// <returns>
/// <para>This function returns <c>ERROR_SUCCESS</c> on success or one of the following error codes.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_BAD_LENGTH</term>
/// <term>The specified buffer length is invalid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_HANDLE</term>
/// <term>The specified handle is invalid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>The specified information class is invalid.</term>
/// </item>
/// <item>
/// <term>ERROR_MORE_DATA</term>
/// <term>Buffer is NULL, and there is data at the current position to return.</term>
/// </item>
/// <item>
/// <term>ERROR_NO_MORE_ITEMS</term>
/// <term>The walk has completed and there are no more items to return.</term>
/// </item>
/// <item>
/// <term>ERROR_NOT_FOUND</term>
/// <term>The requested information is not in the snapshot.</term>
/// </item>
/// </list>
/// <para>
/// All error codes are defined in winerror.h. Use FormatMessage with the <c>FORMAT_MESSAGE_FROM_SYSTEM</c> flag to get a message for
/// an error code.
/// </para>
/// </returns>
/// <remarks>
/// <para>
/// For snapshot data types that have a variable number of instances within a snapshot, you use the <c>PssWalkSnapshot</c> function
/// to obtain the instances one after another. You set the InformationClass parameter to specify the type of data.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/api/processsnapshot/nf-processsnapshot-psswalksnapshot DWORD
// PssWalkSnapshot( HPSS SnapshotHandle, PSS_WALK_INFORMATION_CLASS InformationClass, HPSSWALK WalkMarkerHandle, void *Buffer, DWORD
// BufferLength );
[DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("processsnapshot.h", MSDNShortId = "C6AC38B5-0A1C-44D7-A1F6-8196AE9B8FB0")]
public static extern Win32Error PssWalkSnapshot(HPSS SnapshotHandle, PSS_WALK_INFORMATION_CLASS InformationClass, HPSSWALK WalkMarkerHandle, IntPtr Buffer, uint BufferLength);
/// <summary>Returns information from the current walk position and advanced the walk marker to the next position.</summary>
/// <param name="SnapshotHandle">A handle to the snapshot.</param>
/// <param name="InformationClass">The type of information to return. For more information, see PSS_WALK_INFORMATION_CLASS.</param>
/// <param name="WalkMarkerHandle">
/// An optional handle to a walk marker. The walk marker indicates the walk position from which data is to be returned. <c>PssWalkSnapshot</c>
/// advances the walk marker to the next walk position in time order before returning to the caller.
/// <para>If this value is <c>NULL</c>, then a new walk marker will be temporarily created.</para>
/// </param>
/// <returns>The list of snapshot information that this function returns.</returns>
[PInvokeData("processsnapshot.h", MSDNShortId = "C6AC38B5-0A1C-44D7-A1F6-8196AE9B8FB0")]
public static IEnumerable<T> PssWalkSnapshot<T>(HPSS SnapshotHandle, PSS_WALK_INFORMATION_CLASS InformationClass, HPSSWALK WalkMarkerHandle = default) where T : struct
{
if (!CorrespondingTypeAttribute.CanGet(InformationClass, typeof(T))) throw new ArgumentOutOfRangeException(nameof(InformationClass));
if (SnapshotHandle.IsNull) throw new ArgumentNullException(nameof(SnapshotHandle));
SafeHPSSWALK hWalk;
if (WalkMarkerHandle.IsNull)
PssWalkMarkerCreate(IntPtr.Zero, out hWalk).ThrowIfFailed();
else
hWalk = new SafeHPSSWALK(WalkMarkerHandle.DangerousGetHandle(), false);
using (hWalk)
using (var mem = SafeCoTaskMemHandle.CreateFromStructure<T>())
{
do
{
var err = PssWalkSnapshot(SnapshotHandle, InformationClass, hWalk, (IntPtr)mem, (uint)mem.Size);
if (err == Win32Error.ERROR_NO_MORE_ITEMS)
break;
else
err.ThrowIfFailed();
yield return mem.ToStructure<T>();
} while (true);
}
}
[DllImport(Lib.Kernel32, SetLastError = false, EntryPoint = "PssCaptureSnapshot", ExactSpelling = true)]
private static extern Win32Error PssCaptureSnapshotInternal(HPROCESS ProcessHandle, PSS_CAPTURE_FLAGS CaptureFlags, uint ThreadContextFlags, out SafeHPSS SnapshotHandle);
[DllImport(Lib.Kernel32, SetLastError = false, EntryPoint = "PssDuplicateSnapshot", ExactSpelling = true)]
private static extern Win32Error PssDuplicateSnapshotInternal(HPROCESS SourceProcessHandle, HPSS SnapshotHandle, HPROCESS TargetProcessHandle, out SafeHPSS TargetSnapshotHandle, PSS_DUPLICATE_FLAGS Flags);
/// <summary>Provides a handle to a target snapshot.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct HPSS : IHandle
{
private IntPtr handle;
/// <summary>Initializes a new instance of the <see cref="HPSS"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
public HPSS(IntPtr preexistingHandle) => handle = preexistingHandle;
/// <summary>Returns an invalid handle by instantiating a <see cref="HPSS"/> object with <see cref="IntPtr.Zero"/>.</summary>
public static HPSS NULL => new HPSS(IntPtr.Zero);
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
/// <summary>Performs an explicit conversion from <see cref="HPSS"/> to <see cref="IntPtr"/>.</summary>
/// <param name="h">The handle.</param>
/// <returns>The result of the conversion.</returns>
public static explicit operator IntPtr(HPSS h) => h.handle;
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="HPSS"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HPSS(IntPtr h) => new HPSS(h);
/// <summary>Implements the operator !=.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator !=(HPSS h1, HPSS h2) => !(h1 == h2);
/// <summary>Implements the operator ==.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator ==(HPSS h1, HPSS h2) => h1.Equals(h2);
/// <inheritdoc/>
public override bool Equals(object obj) => obj is HPSS h ? handle == h.handle : false;
/// <inheritdoc/>
public override int GetHashCode() => handle.GetHashCode();
/// <inheritdoc/>
public IntPtr DangerousGetHandle() => handle;
}
/// <summary>Provides a handle to a wall marker.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct HPSSWALK : IHandle
{
private IntPtr handle;
/// <summary>Initializes a new instance of the <see cref="HPSSWALK"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
public HPSSWALK(IntPtr preexistingHandle) => handle = preexistingHandle;
/// <summary>Returns an invalid handle by instantiating a <see cref="HPSSWALK"/> object with <see cref="IntPtr.Zero"/>.</summary>
public static HPSSWALK NULL => new HPSSWALK(IntPtr.Zero);
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
/// <summary>Performs an explicit conversion from <see cref="HPSSWALK"/> to <see cref="IntPtr"/>.</summary>
/// <param name="h">The handle.</param>
/// <returns>The result of the conversion.</returns>
public static explicit operator IntPtr(HPSSWALK h) => h.handle;
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="HPSSWALK"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HPSSWALK(IntPtr h) => new HPSSWALK(h);
/// <summary>Implements the operator !=.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator !=(HPSSWALK h1, HPSSWALK h2) => !(h1 == h2);
/// <summary>Implements the operator ==.</summary>
/// <param name="h1">The first handle.</param>
/// <param name="h2">The second handle.</param>
/// <returns>The result of the operator.</returns>
public static bool operator ==(HPSSWALK h1, HPSSWALK h2) => h1.Equals(h2);
/// <inheritdoc/>
public override bool Equals(object obj) => obj is HPSSWALK h ? handle == h.handle : false;
/// <inheritdoc/>
public override int GetHashCode() => handle.GetHashCode();
/// <inheritdoc/>
public IntPtr DangerousGetHandle() => handle;
}
/// <summary>
/// <para>
/// Contains information about a range of pages in the virtual address space of a process. The VirtualQuery and VirtualQueryEx
/// functions use this structure.
/// </para>
/// </summary>
/// <remarks>
/// <para>
/// To enable a debugger to debug a target that is running on a different architecture (32-bit versus 64-bit), use one of the
/// explicit forms of this structure.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_memory_basic_information typedef struct
// _MEMORY_BASIC_INFORMATION { PVOID BaseAddress; PVOID AllocationBase; DWORD AllocationProtect; SIZE_T RegionSize; DWORD State;
// DWORD Protect; DWORD Type; } MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION;
[PInvokeData("winnt.h", MSDNShortId = "dc3fa48e-0986-49cc-88a9-ff8179fbe5f0")]
[StructLayout(LayoutKind.Sequential)]
public struct MEMORY_BASIC_INFORMATION
{
/// <summary>
/// <para>A pointer to the base address of the region of pages.</para>
/// </summary>
public IntPtr BaseAddress;
/// <summary>
/// <para>
/// A pointer to the base address of a range of pages allocated by the VirtualAlloc function. The page pointed to by the
/// <c>BaseAddress</c> member is contained within this allocation range.
/// </para>
/// </summary>
public IntPtr AllocationBase;
/// <summary>
/// <para>
/// The memory protection option when the region was initially allocated. This member can be one of the memory protection
/// constants or 0 if the caller does not have access.
/// </para>
/// </summary>
public uint AllocationProtect;
/// <summary>
/// <para>The size of the region beginning at the base address in which all pages have identical attributes, in bytes.</para>
/// </summary>
public SizeT RegionSize;
/// <summary>
/// <para>The state of the pages in the region. This member can be one of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>State</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>MEM_COMMIT 0x1000</term>
/// <term>
/// Indicates committed pages for which physical storage has been allocated, either in memory or in the paging file on disk.
/// </term>
/// </item>
/// <item>
/// <term>MEM_FREE 0x10000</term>
/// <term>
/// Indicates free pages not accessible to the calling process and available to be allocated. For free pages, the information in
/// the AllocationBase, AllocationProtect, Protect, and Type members is undefined.
/// </term>
/// </item>
/// <item>
/// <term>MEM_RESERVE 0x2000</term>
/// <term>
/// Indicates reserved pages where a range of the process's virtual address space is reserved without any physical storage being
/// allocated. For reserved pages, the information in the Protect member is undefined.
/// </term>
/// </item>
/// </list>
/// </summary>
public uint State;
/// <summary>
/// <para>
/// The access protection of the pages in the region. This member is one of the values listed for the <c>AllocationProtect</c> member.
/// </para>
/// </summary>
public uint Protect;
/// <summary>
/// <para>The type of pages in the region. The following types are defined.</para>
/// <list type="table">
/// <listheader>
/// <term>Type</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>MEM_IMAGE 0x1000000</term>
/// <term>Indicates that the memory pages within the region are mapped into the view of an image section.</term>
/// </item>
/// <item>
/// <term>MEM_MAPPED 0x40000</term>
/// <term>Indicates that the memory pages within the region are mapped into the view of a section.</term>
/// </item>
/// <item>
/// <term>MEM_PRIVATE 0x20000</term>
/// <term>Indicates that the memory pages within the region are private (that is, not shared by other processes).</term>
/// </item>
/// </list>
/// </summary>
public uint Type;
}
/// <summary>
/// <para>
/// Specifies custom functions which the Process Snapshotting functions use to allocate and free the internal walk marker structures.
/// </para>
/// </summary>
/// <remarks>
/// <para>
/// To use custom memory allocation functions, pass this structure to PssWalkMarkerCreate. Otherwise, the Process Snapshotting
/// functions use the default process heap.
/// </para>
/// <para>
/// The <c>PSS_ALLOCATOR</c> structure that provides the custom functions should remain valid for the lifetime of the walk marker
/// that PssWalkMarkerCreate creates.
/// </para>
/// <para><c>FreeRoutine</c> must accept <c>NULL</c> address parameters without failing.</para>
/// <para>
/// The custom functions are called from PssWalkMarkerCreate, PssWalkMarkerFree and PssWalkSnapshot using the same thread that calls
/// <c>PssWalkMarkerCreate</c>, <c>PssWalkMarkerFree</c> and <c>PssWalkSnapshot</c>. Therefore the custom functions need not be multi-threaded.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/api/processsnapshot/ns-processsnapshot-pss_allocator typedef
// struct PSS_ALLOCATOR { void *Context; void )(void *Context,DWORD Size) *(*AllocRoutine; void((void *Context, void *Address) *
// )FreeRoutine; };
[PInvokeData("processsnapshot.h", MSDNShortId = "54225F76-9A2E-4CB3-A3B5-9F9DB5551D53")]
[StructLayout(LayoutKind.Sequential)]
public struct PSS_ALLOCATOR
{
/// <summary>
/// <para>An arbitrary pointer-sized value that the Process Snapshotting functions pass to <c>AllocRoutine</c> and <c>FreeRoutine</c>.</para>
/// </summary>
public IntPtr Context;
/// <summary>
/// <para>
/// A pointer to a WINAPI-calling convention function that takes two parameters. It returns a pointer to the block of memory that
/// it allocates, or <c>NULL</c> if allocation fails.
/// </para>
/// <para>Context</para>
/// <para>The context value, as passed in <c>PSS_ALLOCATOR</c>.</para>
/// <para>Size</para>
/// <para>Number of bytes to allocate.</para>
/// </summary>
[MarshalAs(UnmanagedType.FunctionPtr)]
public AllocRoutine Alloc;
/// <summary>
/// <para>
/// A pointer to a WINAPI-calling convention function taking two parameters. It deallocates a block of memory that
/// <c>AllocRoutine</c> allocated.
/// </para>
/// <para>Context</para>
/// <para>The context value, as passed in <c>PSS_ALLOCATOR</c>.</para>
/// <para>Address</para>
/// <para>The address of a block of memory that <c>AllocRoutine</c> allocated.</para>
/// </summary>
[MarshalAs(UnmanagedType.FunctionPtr)]
public FreeRoutine Free;
/// <summary>A WINAPI-calling convention function that takes two parameters.</summary>
/// <param name="Context">The context.</param>
/// <param name="Size">The size.</param>
/// <returns>A pointer to the block of memory that it allocates, or NULL if allocation fails.</returns>
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate IntPtr AllocRoutine(IntPtr Context, uint Size);
/// <summary>A WINAPI-calling convention function taking two parameters.</summary>
/// <param name="Context">The context.</param>
/// <param name="Address">The address.</param>
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate void FreeRoutine(IntPtr Context, IntPtr Address);
}
/// <summary>
/// <para>Holds auxiliary page entry information returned by PssWalkSnapshot.</para>
/// </summary>
/// <remarks>
/// <para>
/// PssWalkSnapshot returns a <c>PSS_AUXILIARY_PAGE_ENTRY</c> structure when the PSS_WALK_INFORMATION_CLASS member that the caller
/// provides it is <c>PSS_WALK_AUXILIARY_PAGES</c>.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/api/processsnapshot/ns-processsnapshot-pss_auxiliary_page_entry
// typedef struct PSS_AUXILIARY_PAGE_ENTRY { void *Address; MEMORY_BASIC_INFORMATION BasicInformation; FILETIME CaptureTime; void
// *PageContents; DWORD PageSize; };
[PInvokeData("processsnapshot.h", MSDNShortId = "A3D948E6-6FFE-4732-A8C7-A292FDA07D7C")]
[StructLayout(LayoutKind.Sequential)]
public struct PSS_AUXILIARY_PAGE_ENTRY
{
/// <summary>
/// <para>The address of the captured auxiliary page, in the context of the captured process.</para>
/// </summary>
public IntPtr Address;
/// <summary>
/// <para>Basic information about the captured page. See MEMORY_BASIC_INFORMATION for more information.</para>
/// </summary>
public MEMORY_BASIC_INFORMATION BasicInformation;
/// <summary>
/// <para>The capture time of the page. For more information, see FILETIME.</para>
/// </summary>
public FILETIME CaptureTime;
/// <summary>
/// <para>
/// A pointer to the contents of the captured page, in the context of the current process. This member may be <c>NULL</c> if page
/// contents were not captured. The pointer is valid for the lifetime of the walk marker passed to PssWalkSnapshot.
/// </para>
/// </summary>
public IntPtr PageContents;
/// <summary>
/// <para>The size of the page contents that <c>PageContents</c> points to, in bytes.</para>
/// </summary>
public uint PageSize;
}
/// <summary>Holds auxiliary pages information returned by PssQuerySnapshot.</summary>
/// <remarks>
/// PssQuerySnapshot returns a <c>PSS_AUXILIARY_PAGES_INFORMATION</c> structure when the PSS_QUERY_INFORMATION_CLASS member that the
/// caller provides it is <c>PSS_QUERY_AUXILIARY_PAGES_INFORMATION</c>.
/// </remarks>
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/api/processsnapshot/ns-processsnapshot-pss_auxiliary_pages_information
// typedef struct PSS_AUXILIARY_PAGES_INFORMATION { DWORD AuxPagesCaptured; };
[PInvokeData("processsnapshot.h", MSDNShortId = "122DD3DF-002A-4250-9E37-BA239638A684")]
[StructLayout(LayoutKind.Sequential)]
public struct PSS_AUXILIARY_PAGES_INFORMATION
{
/// <summary>
/// <para>The count of auxiliary pages captured.</para>
/// </summary>
public uint AuxPagesCaptured;
}
/// <summary>
/// <para>Holds information about a handle returned by PssWalkSnapshot.</para>
/// </summary>
/// <remarks>
/// <para>
/// PssWalkSnapshot returns a <c>PSS_HANDLE_ENTRY</c> structure when the PSS_WALK_INFORMATION_CLASS member that the caller provides
/// it is <c>PSS_WALK_HANDLES</c>.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/api/processsnapshot/ns-processsnapshot-pss_handle_entry typedef
// struct PSS_HANDLE_ENTRY { HANDLE Handle; PSS_HANDLE_FLAGS Flags; PSS_OBJECT_TYPE ObjectType; FILETIME CaptureTime; DWORD
// Attributes; DWORD GrantedAccess; DWORD HandleCount; DWORD PointerCount; DWORD PagedPoolCharge; DWORD NonPagedPoolCharge; FILETIME
// CreationTime; WORD TypeNameLength; wchar_t const *TypeName; WORD ObjectNameLength; wchar_t const *ObjectName; union { struct {
// DWORD ExitStatus; void *PebBaseAddress; ULONG_PTR AffinityMask; LONG BasePriority; DWORD ProcessId; DWORD ParentProcessId; DWORD
// Flags; } Process; struct { DWORD ExitStatus; void *TebBaseAddress; DWORD ProcessId; DWORD ThreadId; ULONG_PTR AffinityMask; int
// Priority; int BasePriority; void *Win32StartAddress; } Thread; struct { LONG CurrentCount; BOOL Abandoned; DWORD OwnerProcessId;
// DWORD OwnerThreadId; } Mutant; struct { BOOL ManualReset; BOOL Signaled; } Event; struct { void *BaseAddress; DWORD
// AllocationAttributes; LARGE_INTEGER MaximumSize; } Section; struct { LONG CurrentCount; LONG MaximumCount; } Semaphore; }
// TypeSpecificInformation; };
[PInvokeData("processsnapshot.h", MSDNShortId = "F56E8C35-949A-4DEE-973F-CF24F6596036")]
[StructLayout(LayoutKind.Sequential)]
public struct PSS_HANDLE_ENTRY
{
/// <summary>
/// <para>The handle value.</para>
/// </summary>
public IntPtr Handle;
/// <summary>
/// <para>Flags that indicate what parts of this structure are valid. For more information, see PSS_HANDLE_FLAGS.</para>
/// </summary>
public PSS_HANDLE_FLAGS Flags;
/// <summary>
/// <para>The type of the object that the handle references. For more information, see PSS_OBJECT_TYPE.</para>
/// </summary>
public PSS_OBJECT_TYPE ObjectType;
/// <summary>
/// <para>The capture time of this information. For more information, see FILETIME.</para>
/// </summary>
public FILETIME CaptureTime;
/// <summary>
/// <para>Attributes.</para>
/// </summary>
public uint Attributes;
/// <summary>
/// <para>Reserved for use by the operating system.</para>
/// </summary>
public uint GrantedAccess;
/// <summary>
/// <para>Reserved for use by the operating system.</para>
/// </summary>
public uint HandleCount;
/// <summary>
/// <para>Reserved for use by the operating system.</para>
/// </summary>
public uint PointerCount;
/// <summary>
/// <para>Reserved for use by the operating system.</para>
/// </summary>
public uint PagedPoolCharge;
/// <summary>
/// <para>Reserved for use by the operating system.</para>
/// </summary>
public uint NonPagedPoolCharge;
/// <summary>
/// <para>Reserved for use by the operating system.</para>
/// </summary>
public FILETIME CreationTime;
/// <summary>
/// <para>The length of <c>TypeName</c>, in bytes.</para>
/// </summary>
public ushort TypeNameLength;
/// <summary>
/// <para>
/// The type name of the object referenced by this handle. The buffer may not terminated by a <c>NULL</c> character. The pointer
/// is valid for the lifetime of the walk marker passed to PssWalkSnapshot.
/// </para>
/// </summary>
public IntPtr TypeName;
/// <summary>
/// <para>The length of <c>ObjectName</c>, in bytes.</para>
/// </summary>
public ushort ObjectNameLength;
/// <summary>
/// <para>
/// Specifies the name of the object referenced by this handle. The buffer may not terminated by a <c>NULL</c> character. The
/// pointer is valid for the lifetime of the walk marker passed to PssWalkSnapshot.
/// </para>
/// </summary>
public IntPtr ObjectName;
/// <summary>
/// <para>Type-specific information.</para>
/// </summary>
public UNION TypeSpecificInformation;
/// <summary>
/// <para>Type-specific information.</para>
/// </summary>
[StructLayout(LayoutKind.Explicit)]
public struct UNION
{
/// <summary>Process</summary>
[FieldOffset(0)]
public Process Process;
/// <summary>Thread</summary>
[FieldOffset(0)]
public Thread Thread;
/// <summary>Mutant</summary>
[FieldOffset(0)]
public Mutant Mutant;
/// <summary>Event</summary>
[FieldOffset(0)]
public Event Event;
/// <summary>Section</summary>
[FieldOffset(0)]
public Section Section;
/// <summary>Semaphore</summary>
[FieldOffset(0)]
public Semaphore Semaphore;
}
/// <summary>Undocumented.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct Process
{
/// <summary>
/// <para>The exit code of the process. If the process has not exited, this is set to <c>STILL_ACTIVE</c> (259).</para>
/// </summary>
public uint ExitStatus;
/// <summary>
/// <para>The address of the process environment block (PEB). Reserved for use by the operating system.</para>
/// </summary>
public IntPtr PebBaseAddress;
/// <summary>
/// <para>The affinity mask of the process.</para>
/// </summary>
public UIntPtr AffinityMask;
/// <summary>
/// <para>The base priority level of the process.</para>
/// </summary>
public int BasePriority;
/// <summary>
/// <para>The process ID.</para>
/// </summary>
public uint ProcessId;
/// <summary>
/// <para>The parent process ID.</para>
/// </summary>
public uint ParentProcessId;
/// <summary>
/// <para>Flags about the process. For more information, see PSS_PROCESS_FLAGS.</para>
/// </summary>
public uint Flags;
}
/// <summary>Undocumented.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct Thread
{
/// <summary>
/// <para>The exit code of the process. If the process has not exited, this is set to <c>STILL_ACTIVE</c> (259).</para>
/// </summary>
public uint ExitStatus;
/// <summary>
/// <para>The address of the thread environment block (TEB). Reserved for use by the operating system.</para>
/// </summary>
public IntPtr TebBaseAddress;
/// <summary>
/// <para>The process ID.</para>
/// </summary>
public uint ProcessId;
/// <summary>
/// <para>The thread ID.</para>
/// </summary>
public uint ThreadId;
/// <summary>
/// <para>The affinity mask of the process.</para>
/// </summary>
public UIntPtr AffinityMask;
/// <summary>
/// <para>The threads dynamic priority level.</para>
/// </summary>
public int Priority;
/// <summary>
/// <para>The threads base priority level.</para>
/// </summary>
public int BasePriority;
/// <summary>
/// <para>A pointer to the thread procedure for the thread.</para>
/// </summary>
public IntPtr Win32StartAddress;
}
/// <summary>Undocumented.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct Mutant
{
/// <summary>
/// <para>Reserved for use by the operating system.</para>
/// </summary>
public int CurrentCount;
/// <summary>
/// <para>
/// <c>TRUE</c> if the mutant has been abandoned (the owning thread exited without releasing the mutex), <c>FALSE</c> if not.
/// </para>
/// </summary>
[MarshalAs(UnmanagedType.Bool)] public bool Abandoned;
/// <summary>
/// <para>The process ID of the owning thread, at the time of snapshot creation and handle capture.</para>
/// </summary>
public uint OwnerProcessId;
/// <summary>
/// <para>The process ID of the owning thread, at the time of snapshot creation and handle capture.</para>
/// </summary>
public uint OwnerThreadId;
}
/// <summary>Undocumented.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct Event
{
/// <summary>
/// <para><c>TRUE</c> if the event is manual reset, <c>FALSE</c> if not.</para>
/// </summary>
[MarshalAs(UnmanagedType.Bool)] public bool ManualReset;
/// <summary>
/// <para><c>TRUE</c> if the event was signaled at the time of snapshot creation and handle capture, <c>FALSE</c> if not.</para>
/// </summary>
[MarshalAs(UnmanagedType.Bool)] public bool Signaled;
}
/// <summary>Undocumented.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct Section
{
/// <summary>
/// <para>Reserved for use by the operating system.</para>
/// </summary>
public IntPtr BaseAddress;
/// <summary>
/// <para>Reserved for use by the operating system.</para>
/// </summary>
public uint AllocationAttributes;
/// <summary>
/// <para>Reserved for use by the operating system.</para>
/// </summary>
public long MaximumSize;
}
/// <summary>Undocumented.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct Semaphore
{
/// <summary>Undocumented.</summary>
public int CurrentCount;
/// <summary>Undocumented.</summary>
public int MaximumCount;
}
}
/// <summary>
/// <para>Holds handle information returned by PssQuerySnapshot.</para>
/// </summary>
/// <remarks>
/// <para>
/// PssQuerySnapshot returns a <c>PSS_HANDLE_INFORMATION</c> structure when the PSS_QUERY_INFORMATION_CLASS member that the caller
/// provides it is <c>PSS_QUERY_HANDLE_INFORMATION</c>.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/api/processsnapshot/ns-processsnapshot-pss_handle_information
// typedef struct PSS_HANDLE_INFORMATION { DWORD HandlesCaptured; };
[PInvokeData("processsnapshot.h", MSDNShortId = "77192849-D919-4947-9BFF-343C166C5A51")]
[StructLayout(LayoutKind.Sequential)]
public struct PSS_HANDLE_INFORMATION
{
/// <summary>
/// <para>The count of handles captured.</para>
/// </summary>
public uint HandlesCaptured;
}
/// <summary>Holds handle trace information returned by PssQuerySnapshot.</summary>
/// <remarks>
/// PssQuerySnapshot returns a <c>PSS_HANDLE_TRACE_INFORMATION</c> structure when the PSS_QUERY_INFORMATION_CLASS member that the
/// caller provides it is <c>PSS_QUERY_HANDLE_TRACE_INFORMATION</c>.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/processsnapshot/ns-processsnapshot-pss_handle_trace_information typedef
// struct { HANDLE SectionHandle; DWORD Size; } PSS_HANDLE_TRACE_INFORMATION;
[PInvokeData("processsnapshot.h", MSDNShortId = "0877DF1F-044C-48F2-9BCC-938EBD6D46EE")]
[StructLayout(LayoutKind.Sequential)]
public struct PSS_HANDLE_TRACE_INFORMATION
{
/// <summary>A handle to a section containing the handle trace information.</summary>
public HANDLE SectionHandle;
/// <summary>The size of the handle trace section, in bytes.</summary>
public uint Size;
}
/// <summary>
/// <para>Holds performance counters returned by PssQuerySnapshot.</para>
/// </summary>
/// <remarks>
/// <para>
/// PssQuerySnapshot returns a <c>PSS_PERFORMANCE_COUNTERS</c> structure when the PSS_QUERY_INFORMATION_CLASS member that the caller
/// provides it is <c>PSS_QUERY_PERFORMANCE_COUNTERS</c>.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/api/processsnapshot/ns-processsnapshot-pss_performance_counters
// typedef struct PSS_PERFORMANCE_COUNTERS { UINT64 TotalCycleCount; UINT64 TotalWallClockPeriod; UINT64 VaCloneCycleCount; UINT64
// VaCloneWallClockPeriod; UINT64 VaSpaceCycleCount; UINT64 VaSpaceWallClockPeriod; UINT64 AuxPagesCycleCount; UINT64
// AuxPagesWallClockPeriod; UINT64 HandlesCycleCount; UINT64 HandlesWallClockPeriod; UINT64 ThreadsCycleCount; UINT64
// ThreadsWallClockPeriod; };
[PInvokeData("processsnapshot.h", MSDNShortId = "298C1FC8-D19D-4DB3-84AA-3870D06B16A1")]
[StructLayout(LayoutKind.Sequential)]
public struct PSS_PERFORMANCE_COUNTERS
{
/// <summary>
/// <para>The count of clock cycles spent for capture.</para>
/// </summary>
public ulong TotalCycleCount;
/// <summary>
/// <para>The count of FILETIME units spent for capture.</para>
/// </summary>
public ulong TotalWallClockPeriod;
/// <summary>
/// <para>The count of clock cycles spent for the capture of the VA clone.</para>
/// </summary>
public ulong VaCloneCycleCount;
/// <summary>
/// <para>The count of FILETIME units spent for the capture of the VA clone.</para>
/// </summary>
public ulong VaCloneWallClockPeriod;
/// <summary>
/// <para>The count of clock cycles spent for the capture of VA space information.</para>
/// </summary>
public ulong VaSpaceCycleCount;
/// <summary>
/// <para>The count of FILETIME units spent for the capture VA space information.</para>
/// </summary>
public ulong VaSpaceWallClockPeriod;
/// <summary>
/// <para>The count of clock cycles spent for the capture of auxiliary page information.</para>
/// </summary>
public ulong AuxPagesCycleCount;
/// <summary>
/// <para>The count of FILETIME units spent for the capture of auxiliary page information.</para>
/// </summary>
public ulong AuxPagesWallClockPeriod;
/// <summary>
/// <para>The count of clock cycles spent for the capture of handle information.</para>
/// </summary>
public ulong HandlesCycleCount;
/// <summary>
/// <para>The count of FILETIME units spent for the capture of handle information.</para>
/// </summary>
public ulong HandlesWallClockPeriod;
/// <summary>
/// <para>The count of clock cycles spent for the capture of thread information.</para>
/// </summary>
public ulong ThreadsCycleCount;
/// <summary>
/// <para>The count of FILETIME units spent for the capture of thread information.</para>
/// </summary>
public ulong ThreadsWallClockPeriod;
}
/// <summary>
/// <para>Holds process information returned by PssQuerySnapshot.</para>
/// </summary>
/// <remarks>
/// <para>
/// PssQuerySnapshot returns a <c>PSS_PROCESS_INFORMATION</c> structure when the PSS_QUERY_INFORMATION_CLASS member that the caller
/// provides it is <c>PSS_QUERY_PROCESS_INFORMATION</c>.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/api/processsnapshot/ns-processsnapshot-pss_process_information
// typedef struct PSS_PROCESS_INFORMATION { DWORD ExitStatus; void *PebBaseAddress; ULONG_PTR AffinityMask; LONG BasePriority; DWORD
// ProcessId; DWORD ParentProcessId; PSS_PROCESS_FLAGS Flags; FILETIME CreateTime; FILETIME ExitTime; FILETIME KernelTime; FILETIME
// UserTime; DWORD PriorityClass; ULONG_PTR PeakVirtualSize; ULONG_PTR VirtualSize; DWORD PageFaultCount; ULONG_PTR
// PeakWorkingSetSize; ULONG_PTR WorkingSetSize; ULONG_PTR QuotaPeakPagedPoolUsage; ULONG_PTR QuotaPagedPoolUsage; ULONG_PTR
// QuotaPeakNonPagedPoolUsage; ULONG_PTR QuotaNonPagedPoolUsage; ULONG_PTR PagefileUsage; ULONG_PTR PeakPagefileUsage; ULONG_PTR
// PrivateUsage; DWORD ExecuteFlags; wchar_t ImageFileName[MAX_PATH]; };
[PInvokeData("processsnapshot.h", MSDNShortId = "D629FA42-B501-4A0E-9B53-6D70E580B687")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct PSS_PROCESS_INFORMATION
{
/// <summary>
/// <para>The exit code of the process. If the process has not exited, this is set to <c>STILL_ACTIVE</c> (259).</para>
/// </summary>
public uint ExitStatus;
/// <summary>
/// <para>The address to the process environment block (PEB). Reserved for use by the operating system.</para>
/// </summary>
public IntPtr PebBaseAddress;
/// <summary>
/// <para>The affinity mask of the process.</para>
/// </summary>
public UIntPtr AffinityMask;
/// <summary>
/// <para>The base priority level of the process.</para>
/// </summary>
public int BasePriority;
/// <summary>
/// <para>The process ID.</para>
/// </summary>
public uint ProcessId;
/// <summary>
/// <para>The parent process ID.</para>
/// </summary>
public uint ParentProcessId;
/// <summary>
/// <para>Flags about the process. For more information, see PSS_PROCESS_FLAGS.</para>
/// </summary>
public PSS_PROCESS_FLAGS Flags;
/// <summary>
/// <para>The time the process was created. For more information, see FILETIME.</para>
/// </summary>
public FILETIME CreateTime;
/// <summary>
/// <para>If the process exited, the time of the exit. For more information, see FILETIME.</para>
/// </summary>
public FILETIME ExitTime;
/// <summary>
/// <para>The amount of time the process spent executing in kernel-mode. For more information, see FILETIME.</para>
/// </summary>
public FILETIME KernelTime;
/// <summary>
/// <para>The amount of time the process spent executing in user-mode. For more information, see FILETIME.</para>
/// </summary>
public FILETIME UserTime;
/// <summary>
/// <para>The priority class.</para>
/// </summary>
public uint PriorityClass;
/// <summary>
/// <para>A memory usage counter. See the GetProcessMemoryInfo function for more information.</para>
/// </summary>
public UIntPtr PeakVirtualSize;
/// <summary>
/// <para>A memory usage counter. See the GetProcessMemoryInfo function for more information.</para>
/// </summary>
public UIntPtr VirtualSize;
/// <summary>
/// <para>A memory usage counter. See the GetProcessMemoryInfo function for more information.</para>
/// </summary>
public uint PageFaultCount;
/// <summary>
/// <para>A memory usage counter. See the GetProcessMemoryInfo function for more information.</para>
/// </summary>
public UIntPtr PeakWorkingSetSize;
/// <summary>
/// <para>A memory usage counter. See the GetProcessMemoryInfo function for more information.</para>
/// </summary>
public UIntPtr WorkingSetSize;
/// <summary>
/// <para>A memory usage counter. See the GetProcessMemoryInfo function for more information.</para>
/// </summary>
public UIntPtr QuotaPeakPagedPoolUsage;
/// <summary>
/// <para>A memory usage counter. See the GetProcessMemoryInfo function for more information.</para>
/// </summary>
public UIntPtr QuotaPagedPoolUsage;
/// <summary>
/// <para>A memory usage counter. See the GetProcessMemoryInfo function for more information.</para>
/// </summary>
public UIntPtr QuotaPeakNonPagedPoolUsage;
/// <summary>
/// <para>A memory usage counter. See the GetProcessMemoryInfo function for more information.</para>
/// </summary>
public UIntPtr QuotaNonPagedPoolUsage;
/// <summary>
/// <para>A memory usage counter. See the GetProcessMemoryInfo function for more information.</para>
/// </summary>
public UIntPtr PagefileUsage;
/// <summary>
/// <para>A memory usage counter. See the GetProcessMemoryInfo function for more information.</para>
/// </summary>
public UIntPtr PeakPagefileUsage;
/// <summary>
/// <para>A memory usage counter. See the GetProcessMemoryInfo function for more information.</para>
/// </summary>
public UIntPtr PrivateUsage;
/// <summary>
/// <para>Reserved for use by the operating system.</para>
/// </summary>
public uint ExecuteFlags;
/// <summary>
/// <para>The full path to the process executable. If the path exceeds the allocated buffer size, it is truncated.</para>
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)]
public string ImageFileName;
}
/// <summary>
/// <para>Holds thread information returned by PssWalkSnapshot <c>PssWalkSnapshot</c>.</para>
/// </summary>
/// <remarks>
/// <para>
/// PssWalkSnapshot returns a <c>PSS_THREAD_ENTRY</c> structure when the PSS_WALK_INFORMATION_CLASS member that the caller provides
/// it is <c>PSS_WALK_THREADS</c>.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/api/processsnapshot/ns-processsnapshot-pss_thread_entry typedef
// struct PSS_THREAD_ENTRY { DWORD ExitStatus; void *TebBaseAddress; DWORD ProcessId; DWORD ThreadId; ULONG_PTR AffinityMask; int
// Priority; int BasePriority; void *LastSyscallFirstArgument; WORD LastSyscallNumber; FILETIME CreateTime; FILETIME ExitTime;
// FILETIME KernelTime; FILETIME UserTime; void *Win32StartAddress; FILETIME CaptureTime; PSS_THREAD_FLAGS Flags; WORD SuspendCount;
// WORD SizeOfContextRecord; PCONTEXT ContextRecord; };
[PInvokeData("processsnapshot.h", MSDNShortId = "99C89DBB-8C12-482E-B33D-AE59C37662CF")]
[StructLayout(LayoutKind.Sequential)]
public struct PSS_THREAD_ENTRY
{
/// <summary>
/// <para>The exit code of the process. If the process has not exited, this is set to <c>STILL_ACTIVE</c> (259).</para>
/// </summary>
public uint ExitStatus;
/// <summary>
/// <para>The address of the thread environment block (TEB). Reserved for use by the operating system.</para>
/// </summary>
public IntPtr TebBaseAddress;
/// <summary>
/// <para>The process ID.</para>
/// </summary>
public uint ProcessId;
/// <summary>
/// <para>The thread ID.</para>
/// </summary>
public uint ThreadId;
/// <summary>
/// <para>The affinity mask of the process.</para>
/// </summary>
public UIntPtr AffinityMask;
/// <summary>
/// <para>The threads dynamic priority level.</para>
/// </summary>
public int Priority;
/// <summary>
/// <para>The base priority level of the process.</para>
/// </summary>
public int BasePriority;
/// <summary>
/// <para>Reserved for use by the operating system.</para>
/// </summary>
public IntPtr LastSyscallFirstArgument;
/// <summary>
/// <para>Reserved for use by the operating system.</para>
/// </summary>
public ushort LastSyscallNumber;
/// <summary>
/// <para>The time the thread was created. For more information, see FILETIME.</para>
/// </summary>
public FILETIME CreateTime;
/// <summary>
/// <para>If the thread exited, the time of the exit. For more information, see FILETIME.</para>
/// </summary>
public FILETIME ExitTime;
/// <summary>
/// <para>The amount of time the thread spent executing in kernel mode. For more information, see FILETIME.</para>
/// </summary>
public FILETIME KernelTime;
/// <summary>
/// <para>The amount of time the thread spent executing in user mode. For more information, see FILETIME.</para>
/// </summary>
public FILETIME UserTime;
/// <summary>
/// <para>A pointer to the thread procedure for thread.</para>
/// </summary>
public IntPtr Win32StartAddress;
/// <summary>
/// <para>The capture time of this thread. For more information, see FILETIME.</para>
/// </summary>
public FILETIME CaptureTime;
/// <summary>
/// <para>Flags about the thread. For more information, see PSS_THREAD_FLAGS.</para>
/// </summary>
public PSS_THREAD_FLAGS Flags;
/// <summary>
/// <para>The count of times the thread suspended.</para>
/// </summary>
public ushort SuspendCount;
/// <summary>
/// <para>The size of ContextRecord, in bytes.</para>
/// </summary>
public ushort SizeOfContextRecord;
/// <summary>
/// <para>
/// A pointer to the context record if thread context information was captured. The pointer is valid for the lifetime of the walk
/// marker passed to PssWalkSnapshot.
/// </para>
/// </summary>
public IntPtr ContextRecord; // valid for life time of walk marker
}
/// <summary>
/// <para>Holds thread information returned by PssQuerySnapshot.</para>
/// </summary>
/// <remarks>
/// <para>
/// PssQuerySnapshot returns a <c>PSS_THREAD_INFORMATION</c> structure when the PSS_QUERY_INFORMATION_CLASS member that the caller
/// provides it is <c>PSS_QUERY_THREAD_INFORMATION</c>.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/api/processsnapshot/ns-processsnapshot-pss_thread_information
// typedef struct PSS_THREAD_INFORMATION { DWORD ThreadsCaptured; DWORD ContextLength; };
[PInvokeData("processsnapshot.h", MSDNShortId = "68BC42FD-9A30-462F-AFB1-DF9587C50F45")]
[StructLayout(LayoutKind.Sequential)]
public struct PSS_THREAD_INFORMATION
{
/// <summary>
/// <para>The count of threads in the snapshot.</para>
/// </summary>
public uint ThreadsCaptured;
/// <summary>
/// <para>The length of the <c>CONTEXT</c> record captured, in bytes.</para>
/// </summary>
public uint ContextLength;
}
/// <summary>
/// <para>Holds virtual address (VA) clone information returned by PssQuerySnapshot.</para>
/// </summary>
/// <remarks>
/// <para>
/// PssQuerySnapshot returns a <c>PSS_VA_CLONE_INFORMATION</c> structure when the PSS_QUERY_INFORMATION_CLASS member that the caller
/// provides it is <c>PSS_QUERY_VA_CLONE_INFORMATION</c>.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/api/processsnapshot/ns-processsnapshot-pss_va_clone_information
// typedef struct PSS_VA_CLONE_INFORMATION { HANDLE VaCloneHandle; };
[PInvokeData("processsnapshot.h", MSDNShortId = "F93D61B0-EDB2-4560-A69F-CF839EC98B53")]
[StructLayout(LayoutKind.Sequential)]
public struct PSS_VA_CLONE_INFORMATION
{
/// <summary>
/// <para>A handle to the VA clone process.</para>
/// </summary>
public IntPtr VaCloneHandle;
}
/// <summary>
/// <para>Holds the MEMORY_BASIC_INFORMATION returned by PssWalkSnapshot for a virtual address (VA) region.</para>
/// </summary>
/// <remarks>
/// <para>
/// PssWalkSnapshot returns a <c>PSS_VA_SPACE_ENTRY</c> structure when the PSS_WALK_INFORMATION_CLASS member that the caller provides
/// it is <c>PSS_WALK_VA_SPACE</c>.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/api/processsnapshot/ns-processsnapshot-pss_va_space_entry
// typedef struct PSS_VA_SPACE_ENTRY { void *BaseAddress; void *AllocationBase; DWORD AllocationProtect; ULONG_PTR RegionSize; DWORD
// State; DWORD Protect; DWORD Type; DWORD TimeDateStamp; DWORD SizeOfImage; void *ImageBase; DWORD CheckSum; WORD
// MappedFileNameLength; wchar_t const *MappedFileName; };
[PInvokeData("processsnapshot.h", MSDNShortId = "69B8F6A3-76DF-421B-B89B-73BA3254F897")]
[StructLayout(LayoutKind.Sequential)]
public struct PSS_VA_SPACE_ENTRY
{
/// <summary>
/// <para>Information about the VA region. For more information, see MEMORY_BASIC_INFORMATION.</para>
/// </summary>
public IntPtr BaseAddress;
/// <summary>
/// <para>Information about the VA region. For more information, see MEMORY_BASIC_INFORMATION.</para>
/// </summary>
public IntPtr AllocationBase;
/// <summary>
/// <para>Information about the VA region. For more information, see MEMORY_BASIC_INFORMATION.</para>
/// </summary>
public uint AllocationProtect;
/// <summary>
/// <para>Information about the VA region. For more information, see MEMORY_BASIC_INFORMATION.</para>
/// </summary>
public UIntPtr RegionSize;
/// <summary>
/// <para>Information about the VA region. For more information, see MEMORY_BASIC_INFORMATION.</para>
/// </summary>
public uint State;
/// <summary>
/// <para>Information about the VA region. For more information, see MEMORY_BASIC_INFORMATION.</para>
/// </summary>
public uint Protect;
/// <summary>
/// <para>Information about the VA region. For more information, see MEMORY_BASIC_INFORMATION.</para>
/// </summary>
public uint Type;
/// <summary>
/// <para>
/// If section information was captured and the region is an executable image ( <c>MEM_IMAGE</c>), this is the
/// <c>TimeDateStamp</c> value from the Portable Executable (PE) header which describes the image. It is the low 32 bits of the
/// number of seconds since 00:00 January 1, 1970 (a C run-time time_t value), that indicates when the file was created.
/// </para>
/// </summary>
public uint TimeDateStamp;
/// <summary>
/// <para>
/// If section information was captured and the region is an executable image ( <c>MEM_IMAGE</c>), this is the <c>SizeOfImage</c>
/// value from the Portable Executable (PE) header which describes the image. It is the size (in bytes) of the image, including
/// all headers, as the image is loaded in memory.
/// </para>
/// </summary>
public uint SizeOfImage;
/// <summary>
/// <para>
/// If section information was captured and the region is an executable image ( <c>MEM_IMAGE</c>), this is the <c>ImageBase</c>
/// value from the Portable Executable (PE) header which describes the image. It is the preferred address of the first byte of
/// the image when loaded into memory.
/// </para>
/// </summary>
public IntPtr ImageBase;
/// <summary>
/// <para>
/// If section information was captured and the region is an executable image ( <c>MEM_IMAGE</c>), this is the <c>CheckSum</c>
/// value from the Portable Executable (PE) header which describes the image. It is the image file checksum.
/// </para>
/// </summary>
public uint CheckSum;
/// <summary>
/// <para>The length of the mapped file name buffer, in bytes.</para>
/// </summary>
public ushort MappedFileNameLength;
/// <summary>
/// <para>
/// If section information was captured, this is the file path backing the section (if any). The path may be in NT namespace. The
/// string may not be terminated by a <c>NULL</c> character. The pointer is valid for the lifetime of the walk marker passed to PssWalkSnapshot.
/// </para>
/// </summary>
public IntPtr MappedFileName;
}
/// <summary>
/// <para>Holds virtual address (VA) space information returned by PssQuerySnapshot.</para>
/// </summary>
/// <remarks>
/// <para>
/// PssQuerySnapshot returns a <c>PSS_VA_SPACE_INFORMATION</c> structure when the PSS_QUERY_INFORMATION_CLASS member that the caller
/// provides it is <c>PSS_QUERY_VA_SPACE_INFORMATION</c>.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/api/processsnapshot/ns-processsnapshot-pss_va_space_information
// typedef struct PSS_VA_SPACE_INFORMATION { DWORD RegionCount; };
[PInvokeData("processsnapshot.h", MSDNShortId = "F38FF7EB-DDC5-4692-8F57-8D633193D891")]
[StructLayout(LayoutKind.Sequential)]
public struct PSS_VA_SPACE_INFORMATION
{
/// <summary>
/// <para>The count of VA regions captured.</para>
/// </summary>
public uint RegionCount;
}
/// <summary>Provides a <see cref="SafeHandle"/> for <see cref="HPSS"/> that is disposed using <see cref="PssFreeSnapshot"/>.</summary>
public class SafeHPSS : SafeHANDLE
{
internal HPROCESS ProcessHandle;
/// <summary>Initializes a new instance of the <see cref="SafeHPSS"/> class and assigns an existing handle.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
/// <param name="ownsHandle">
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
/// </param>
public SafeHPSS(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// <summary>Initializes a new instance of the <see cref="SafeHPSS"/> class.</summary>
private SafeHPSS() : base() { }
/// <summary>Performs an implicit conversion from <see cref="SafeHPSS"/> to <see cref="HPSS"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HPSS(SafeHPSS h) => h.handle;
/// <inheritdoc/>
protected override bool InternalReleaseHandle() => PssFreeSnapshot(ProcessHandle, handle).Succeeded;
}
/// <summary>Provides a <see cref="SafeHandle"/> for <see cref="HPSSWALK"/> that is disposed using <see cref="PssWalkMarkerFree"/>.</summary>
public class SafeHPSSWALK : SafeHANDLE
{
/// <summary>Initializes a new instance of the <see cref="SafeHPSSWALK"/> class and assigns an existing handle.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
/// <param name="ownsHandle">
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
/// </param>
public SafeHPSSWALK(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// <summary>Initializes a new instance of the <see cref="SafeHPSSWALK"/> class.</summary>
private SafeHPSSWALK() : base() { }
/// <summary>Performs an implicit conversion from <see cref="SafeHPSSWALK"/> to <see cref="HPSSWALK"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HPSSWALK(SafeHPSSWALK h) => h.handle;
/// <inheritdoc/>
protected override bool InternalReleaseHandle() => PssWalkMarkerFree(handle).Succeeded;
}
}
}