Vanara/PInvoke/Kernel32/ProcessSnapshot.cs

2058 lines
86 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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