using System;
using System.Linq;
using System.Runtime.InteropServices;
using Vanara.InteropServices;
using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME;
namespace Vanara.PInvoke
{
/// Platform invokable enumerated types, constants and functions from ntdll.h
public static partial class NtDll
{
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
/// The type of process information to be retrieved.
[PInvokeData("winternl.h", MSDNShortId = "0eae7899-c40b-4a5f-9e9c-adae021885e7")]
// Undocumented values pulled from ProcessHacker source.
public enum PROCESSINFOCLASS
{
///
/// Retrieves a pointer to a PEB structure that can be used to determine whether the specified process is being debugged, and a
/// unique value used by the system to identify the specified process.
/// Use the CheckRemoteDebuggerPresent and GetProcessId functions to obtain this information.
///
[CorrespondingType(typeof(PROCESS_BASIC_INFORMATION), CorrespondingAction.Get)]
[CorrespondingType(typeof(PROCESS_BASIC_INFORMATION_WOW64), CorrespondingAction.Get)]
ProcessBasicInformation = 0,
ProcessQuotaLimits, // qs: QUOTA_LIMITS, QUOTA_LIMITS_EX
ProcessIoCounters, // q: IO_COUNTERS
ProcessVmCounters, // q: VM_COUNTERS, VM_COUNTERS_EX, VM_COUNTERS_EX2
[CorrespondingType(typeof(KERNEL_USER_TIMES), CorrespondingAction.Get)]
ProcessTimes, // q: KERNEL_USER_TIMES
ProcessBasePriority, // s: KPRIORITY
ProcessRaisePriority, // s: ULONG
///
/// Retrieves a DWORD_PTR value that is the port number of the debugger for the process. A nonzero value indicates that the
/// process is being run under the control of a ring 3 debugger.
/// Use the CheckRemoteDebuggerPresent or IsDebuggerPresent function.
///
[CorrespondingType(typeof(IntPtr), CorrespondingAction.Get)]
ProcessDebugPort = 7,
ProcessExceptionPort, // s: PROCESS_EXCEPTION_PORT
ProcessAccessToken, // s: PROCESS_ACCESS_TOKEN
ProcessLdtInformation, // qs: PROCESS_LDT_INFORMATION // 10
ProcessLdtSize, // s: PROCESS_LDT_SIZE
ProcessDefaultHardErrorMode, // qs: ULONG
ProcessIoPortHandlers, // (kernel-mode only) // PROCESS_IO_PORT_HANDLER_INFORMATION
ProcessPooledUsageAndLimits, // q: POOLED_USAGE_AND_LIMITS
ProcessWorkingSetWatch, // q: PROCESS_WS_WATCH_INFORMATION[]; s: void
ProcessUserModeIOPL, // qs: ULONG (requires SeTcbPrivilege)
ProcessEnableAlignmentFaultFixup, // s: BOOLEAN
ProcessPriorityClass, // qs: PROCESS_PRIORITY_CLASS
ProcessWx86Information, // qs: ULONG (requires SeTcbPrivilege) (VdmAllowed)
ProcessHandleCount, // q: ULONG, PROCESS_HANDLE_INFORMATION // 20
ProcessAffinityMask, // s: KAFFINITY
ProcessPriorityBoost, // qs: ULONG
ProcessDeviceMap, // qs: PROCESS_DEVICEMAP_INFORMATION, PROCESS_DEVICEMAP_INFORMATION_EX
ProcessSessionInformation, // q: PROCESS_SESSION_INFORMATION
ProcessForegroundInformation, // s: PROCESS_FOREGROUND_BACKGROUND
///
/// Determines whether the process is running in the WOW64 environment (WOW64 is the x86 emulator that allows Win32-based
/// applications to run on 64-bit Windows).
/// Use the IsWow64Process2 function to obtain this information.
///
[CorrespondingType(typeof(BOOL), CorrespondingAction.Get)]
ProcessWow64Information = 26,
///
/// Retrieves a UNICODE_STRING value containing the name of the image file for the process.
/// Use the QueryFullProcessImageName or GetProcessImageFileName function to obtain this information.
///
[CorrespondingType(typeof(UNICODE_STRING), CorrespondingAction.Get)]
[CorrespondingType(typeof(UNICODE_STRING_WOW64), CorrespondingAction.Get)]
ProcessImageFileName = 27,
ProcessLUIDDeviceMapsEnabled, // q: ULONG
///
/// Retrieves a ULONG value indicating whether the process is considered critical.
///
/// Note This value can be used starting in Windows XP with SP3. Starting in Windows 8.1, IsProcessCritical should be used instead.
///
///
[CorrespondingType(typeof(BOOL), CorrespondingAction.GetSet)]
ProcessBreakOnTermination = 29,
ProcessDebugObjectHandle, // q: HANDLE // 30
ProcessDebugFlags, // qs: ULONG
ProcessHandleTracing, // q: PROCESS_HANDLE_TRACING_QUERY; s: size 0 disables, otherwise enables
ProcessIoPriority, // qs: IO_PRIORITY_HINT
ProcessExecuteFlags, // qs: ULONG
ProcessResourceManagement, // ProcessTlsInformation // PROCESS_TLS_INFORMATION
ProcessCookie, // q: ULONG
ProcessImageInformation, // q: SECTION_IMAGE_INFORMATION
ProcessCycleTime, // q: PROCESS_CYCLE_TIME_INFORMATION // since VISTA
ProcessPagePriority, // q: PAGE_PRIORITY_INFORMATION
ProcessInstrumentationCallback, // qs: PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION // 40
ProcessThreadStackAllocation, // s: PROCESS_STACK_ALLOCATION_INFORMATION, PROCESS_STACK_ALLOCATION_INFORMATION_EX
ProcessWorkingSetWatchEx, // q: PROCESS_WS_WATCH_INFORMATION_EX[]
ProcessImageFileNameWin32, // q: UNICODE_STRING
ProcessImageFileMapping, // q: HANDLE (input)
ProcessAffinityUpdateMode, // qs: PROCESS_AFFINITY_UPDATE_MODE
ProcessMemoryAllocationMode, // qs: PROCESS_MEMORY_ALLOCATION_MODE
ProcessGroupInformation, // q: USHORT[]
ProcessTokenVirtualizationEnabled, // s: ULONG
ProcessConsoleHostProcess, // q: ULONG_PTR // ProcessOwnerInformation
ProcessWindowInformation, // q: PROCESS_WINDOW_INFORMATION // 50
ProcessHandleInformation, // q: PROCESS_HANDLE_SNAPSHOT_INFORMATION // since WIN8
ProcessMitigationPolicy, // s: PROCESS_MITIGATION_POLICY_INFORMATION
ProcessDynamicFunctionTableInformation,
ProcessHandleCheckingMode, // qs: ULONG; s: 0 disables, otherwise enables
ProcessKeepAliveCount, // q: PROCESS_KEEPALIVE_COUNT_INFORMATION
ProcessRevokeFileHandles, // s: PROCESS_REVOKE_FILE_HANDLES_INFORMATION
ProcessWorkingSetControl, // s: PROCESS_WORKING_SET_CONTROL
ProcessHandleTable, // q: ULONG[] // since WINBLUE
ProcessCheckStackExtentsMode,
ProcessCommandLineInformation, // q: UNICODE_STRING // 60
ProcessProtectionInformation, // q: PS_PROTECTION
ProcessMemoryExhaustion, // PROCESS_MEMORY_EXHAUSTION_INFO // since THRESHOLD
ProcessFaultInformation, // PROCESS_FAULT_INFORMATION
ProcessTelemetryIdInformation, // PROCESS_TELEMETRY_ID_INFORMATION
ProcessCommitReleaseInformation, // PROCESS_COMMIT_RELEASE_INFORMATION
ProcessDefaultCpuSetsInformation,
ProcessAllowedCpuSetsInformation,
ProcessSubsystemProcess,
ProcessJobMemoryInformation, // PROCESS_JOB_MEMORY_INFO
ProcessInPrivate, // since THRESHOLD2 // 70
ProcessRaiseUMExceptionOnInvalidHandleClose, // qs: ULONG; s: 0 disables, otherwise enables
ProcessIumChallengeResponse,
ProcessChildProcessInformation, // PROCESS_CHILD_PROCESS_INFORMATION
ProcessHighGraphicsPriorityInformation,
///
/// Retrieves a SUBSYSTEM_INFORMATION_TYPE value indicating the subsystem type of the process. The buffer pointed to by the
/// ProcessInformation parameter should be large enough to hold a single SUBSYSTEM_INFORMATION_TYPE enumeration.
///
[CorrespondingType(typeof(SUBSYSTEM_INFORMATION_TYPE), CorrespondingAction.Get)]
ProcessSubsystemInformation = 75,
ProcessEnergyValues, // PROCESS_ENERGY_VALUES, PROCESS_EXTENDED_ENERGY_VALUES
ProcessActivityThrottleState, // PROCESS_ACTIVITY_THROTTLE_STATE
ProcessActivityThrottlePolicy, // PROCESS_ACTIVITY_THROTTLE_POLICY
ProcessWin32kSyscallFilterInformation,
ProcessDisableSystemAllowedCpuSets, // 80
ProcessWakeInformation, // PROCESS_WAKE_INFORMATION
ProcessEnergyTrackingState, // PROCESS_ENERGY_TRACKING_STATE
ProcessManageWritesToExecutableMemory, // MANAGE_WRITES_TO_EXECUTABLE_MEMORY // since REDSTONE3
ProcessCaptureTrustletLiveDump,
ProcessTelemetryCoverage,
ProcessEnclaveInformation,
ProcessEnableReadWriteVmLogging, // PROCESS_READWRITEVM_LOGGING_INFORMATION
ProcessUptimeInformation, // PROCESS_UPTIME_INFORMATION
ProcessImageSection, // q: HANDLE
ProcessDebugAuthInformation, // since REDSTONE4 // 90
ProcessSystemResourceManagement, // PROCESS_SYSTEM_RESOURCE_MANAGEMENT
ProcessSequenceNumber, // q: ULONGLONG
ProcessLoaderDetour, // since REDSTONE5
ProcessSecurityDomainInformation, // PROCESS_SECURITY_DOMAIN_INFORMATION
ProcessCombineSecurityDomainsInformation, // PROCESS_COMBINE_SECURITY_DOMAINS_INFORMATION
ProcessEnableLogging, // PROCESS_LOGGING_INFORMATION
ProcessLeapSecondInformation, // PROCESS_LEAP_SECOND_INFORMATION
ProcessFiberShadowStackAllocation, // PROCESS_FIBER_SHADOW_STACK_ALLOCATION_INFORMATION // since 19H1
ProcessFreeFiberShadowStackAllocation, // PROCESS_FREE_FIBER_SHADOW_STACK_ALLOCATION_INFORMATION
ProcessAltSystemCallInformation, // qs: BOOLEAN (kernel-mode only) // since 20H1 // 100
ProcessDynamicEHContinuationTargets, // PROCESS_DYNAMIC_EH_CONTINUATION_TARGETS_INFORMATION
}
#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
///
/// Indicates the type of subsystem for a process or thread. This enumeration is used in NtQueryInformationProcess and
/// NtQueryInformationThread calls.
///
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/ne-ntddk-_subsystem_information_type typedef enum
// _SUBSYSTEM_INFORMATION_TYPE { SubsystemInformationTypeWin32, SubsystemInformationTypeWSL, MaxSubsystemInformationType }
// SUBSYSTEM_INFORMATION_TYPE, *PSUBSYSTEM_INFORMATION_TYPE;
[PInvokeData("ntddk.h", MSDNShortId = "B1E334BF-AAB3-410D-8D10-A750E8459E42")]
public enum SUBSYSTEM_INFORMATION_TYPE
{
/// The subsystem type for the process or thread is Win32.
SubsystemInformationTypeWin32,
///
/// The subsystem type for the process or thread is Windows Subsystem for Linux (WSL). For this process, these members of the
/// PS_CREATE_NOTIFY_INFO structure are set as follows: The preceding member values may be NULL.
///
SubsystemInformationTypeWSL,
/// Reserved.
MaxSubsystemInformationType,
}
///
[Flags]
public enum PROCESS_CREATE_FLAGS : uint
{
///
PROCESS_CREATE_FLAGS_BREAKAWAY = 0x00000001,
///
PROCESS_CREATE_FLAGS_NO_DEBUG_INHERIT = 0x00000002,
///
PROCESS_CREATE_FLAGS_INHERIT_HANDLES = 0x00000004,
///
PROCESS_CREATE_FLAGS_OVERRIDE_ADDRESS_SPACE = 0x00000008,
///
PROCESS_CREATE_FLAGS_LARGE_PAGES = 0x00000010,
}
/// Creates a process. This function is UNDOCUMENTED.
/// The process handle.
/// The desired access.
/// The object attributes.
/// The parent process.
/// if set to , inherits the object table.
/// The section handle.
/// The debug port.
/// The exception port.
///
/// The function returns an NTSTATUS success or error code.
///
/// The forms and significance of NTSTATUS error codes are listed in the Ntstatus.h header file available in the DDK, and are
/// described in the DDK documentation under Kernel-Mode Driver Architecture / Design Guide / Driver Programming Techniques /
/// Logging Errors.
///
///
[DllImport(Lib.NtDll, SetLastError = false, ExactSpelling = true)]
public static extern NTStatus NtCreateProcess(out HPROCESS ProcessHandle, [In] ACCESS_MASK DesiredAccess, in OBJECT_ATTRIBUTES ObjectAttributes,
[In] HPROCESS ParentProcess, [In, MarshalAs(UnmanagedType.U1)] bool InheritObjectTable, [In, Optional] IntPtr SectionHandle,
[In, Optional] IntPtr DebugPort, [In, Optional] IntPtr ExceptionPort);
/// Creates a process. This function is UNDOCUMENTED.
/// The process handle.
/// The desired access.
/// The object attributes.
/// The parent process.
/// if set to , inherits the object table.
/// The section handle.
/// The debug port.
/// The exception port.
///
/// The function returns an NTSTATUS success or error code.
///
/// The forms and significance of NTSTATUS error codes are listed in the Ntstatus.h header file available in the DDK, and are
/// described in the DDK documentation under Kernel-Mode Driver Architecture / Design Guide / Driver Programming Techniques /
/// Logging Errors.
///
///
[DllImport(Lib.NtDll, SetLastError = false, ExactSpelling = true)]
public static extern NTStatus NtCreateProcess(out HPROCESS ProcessHandle, [In] ACCESS_MASK DesiredAccess, [In, Optional] IntPtr ObjectAttributes,
[In] HPROCESS ParentProcess, [In, MarshalAs(UnmanagedType.U1)] bool InheritObjectTable, [In, Optional] IntPtr SectionHandle,
[In, Optional] IntPtr DebugPort, [In, Optional] IntPtr ExceptionPort);
/// Creates a process. This function is UNDOCUMENTED.
/// The process handle.
/// The desired access.
/// The object attributes.
/// The parent process.
/// The flags.
/// The section handle.
/// The debug port.
/// The exception port.
/// The job member level.
///
/// The function returns an NTSTATUS success or error code.
///
/// The forms and significance of NTSTATUS error codes are listed in the Ntstatus.h header file available in the DDK, and are
/// described in the DDK documentation under Kernel-Mode Driver Architecture / Design Guide / Driver Programming Techniques /
/// Logging Errors.
///
///
[DllImport(Lib.NtDll, SetLastError = false, ExactSpelling = true)]
public static extern NTStatus NtCreateProcessEx(out HPROCESS ProcessHandle, [In] ACCESS_MASK DesiredAccess, in OBJECT_ATTRIBUTES ObjectAttributes,
[In] HPROCESS ParentProcess, [In] PROCESS_CREATE_FLAGS Flags, [In, Optional] IntPtr SectionHandle,
[In, Optional] IntPtr DebugPort, [In, Optional] IntPtr ExceptionPort, uint JobMemberLevel);
/// Creates a process. This function is UNDOCUMENTED.
/// The process handle.
/// The desired access.
/// The object attributes.
/// The parent process.
/// The flags.
/// The section handle.
/// The debug port.
/// The exception port.
/// The job member level.
///
/// The function returns an NTSTATUS success or error code.
///
/// The forms and significance of NTSTATUS error codes are listed in the Ntstatus.h header file available in the DDK, and are
/// described in the DDK documentation under Kernel-Mode Driver Architecture / Design Guide / Driver Programming Techniques /
/// Logging Errors.
///
///
[DllImport(Lib.NtDll, SetLastError = false, ExactSpelling = true)]
public static extern NTStatus NtCreateProcessEx(out HPROCESS ProcessHandle, [In] ACCESS_MASK DesiredAccess, [In, Optional] IntPtr ObjectAttributes,
[In] HPROCESS ParentProcess, [In] PROCESS_CREATE_FLAGS Flags, [In, Optional] IntPtr SectionHandle,
[In, Optional] IntPtr DebugPort, [In, Optional] IntPtr ExceptionPort, uint JobMemberLevel);
///
///
/// [ NtQueryInformationProcess may be altered or unavailable in future versions of Windows. Applications should use the
/// alternate functions listed in this topic.]
///
/// Retrieves information about the specified process.
///
/// A handle to the process for which information is to be retrieved.
///
///
/// The type of process information to be retrieved. This parameter can be one of the following values from the
/// PROCESSINFOCLASS enumeration.
///
///
///
/// Value
/// Meaning
///
/// -
/// ProcessBasicInformation
0
///
/// Retrieves a pointer to a PEB structure that can be used to determine whether the specified process is being debugged, and a
/// unique value used by the system to identify the specified process. Use the CheckRemoteDebuggerPresent and GetProcessId functions
/// to obtain this information.
///
///
/// -
/// ProcessDebugPort
7
///
/// Retrieves a DWORD_PTR value that is the port number of the debugger for the process. A nonzero value indicates that the process
/// is being run under the control of a ring 3 debugger. Use the CheckRemoteDebuggerPresent or IsDebuggerPresent function.
///
///
/// -
/// ProcessWow64Information
26
///
/// Determines whether the process is running in the WOW64 environment (WOW64 is the x86 emulator that allows Win32-based
/// applications to run on 64-bit Windows). Use the IsWow64Process2 function to obtain this information.
///
///
/// -
/// ProcessImageFileName
27
///
/// Retrieves a UNICODE_STRING value containing the name of the image file for the process. Use the QueryFullProcessImageName or
/// GetProcessImageFileName function to obtain this information.
///
///
/// -
/// ProcessBreakOnTermination
29
/// Retrieves a ULONG value indicating whether the process is considered critical.
///
/// -
/// ProcessSubsystemInformation
75
///
/// Retrieves a SUBSYSTEM_INFORMATION_TYPE value indicating the subsystem type of the process. The buffer pointed to by the
/// ProcessInformation parameter should be large enough to hold a single SUBSYSTEM_INFORMATION_TYPE enumeration.
///
///
///
///
///
///
/// A pointer to a buffer supplied by the calling application into which the function writes the requested information. The size of
/// the information written varies depending on the data type of the ProcessInformationClass parameter:
///
/// PROCESS_BASIC_INFORMATION
///
/// When the ProcessInformationClass parameter is ProcessBasicInformation, the buffer pointed to by the ProcessInformation
/// parameter should be large enough to hold a single PROCESS_BASIC_INFORMATION structure having the following layout:
///
///
///
/// The UniqueProcessId member points to the system's unique identifier for this process. Use the GetProcessId function to
/// retrieve this information.
///
/// The PebBaseAddress member points to a PEB structure.
/// The other members of this structure are reserved for internal use by the operating system.
/// ULONG_PTR
///
/// When the ProcessInformationClass parameter is ProcessWow64Information, the buffer pointed to by the ProcessInformation
/// parameter should be large enough to hold a ULONG_PTR. If this value is nonzero, the process is running in a WOW64
/// environment; otherwise, if the value is equal to zero, the process is not running in a WOW64 environment.
///
/// Use the IsWow64Process2 function to determine whether a process is running in the WOW64 environment.
/// UNICODE_STRING
///
/// When the ProcessInformationClass parameter is ProcessImageFileName, the buffer pointed to by the ProcessInformation
/// parameter should be large enough to hold a UNICODE_STRING structure as well as the string itself. The string stored in
/// the Buffer member is the name of the image file.
///
///
/// If the buffer is too small, the function fails with the STATUS_INFO_LENGTH_MISMATCH error code and the ReturnLength parameter is
/// set to the required buffer size.
///
///
/// The size of the buffer pointed to by the ProcessInformation parameter, in bytes.
///
/// A pointer to a variable in which the function returns the size of the requested information. If the function was successful,
/// this is the size of the information written to the buffer pointed to by the ProcessInformation parameter, but if the buffer was
/// too small, this is the minimum size of buffer needed to receive the information successfully.
///
///
/// The function returns an NTSTATUS success or error code.
///
/// The forms and significance of NTSTATUS error codes are listed in the Ntstatus.h header file available in the DDK, and are
/// described in the DDK documentation under Kernel-Mode Driver Architecture / Design Guide / Driver Programming Techniques /
/// Logging Errors.
///
///
///
///
/// The NtQueryInformationProcess function and the structures that it returns are internal to the operating system and
/// subject to change from one release of Windows to another. To maintain the compatibility of your application, it is better to use
/// public functions mentioned in the description of the ProcessInformationClass parameter instead.
///
///
/// If you do use NtQueryInformationProcess, access the function through run-time dynamic linking. This gives your code an
/// opportunity to respond gracefully if the function has been changed or removed from the operating system. Signature changes,
/// however, may not be detectable.
///
///
/// This function has no associated import library. You must use the LoadLibrary and GetProcAddress functions to dynamically link to Ntdll.dll.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntqueryinformationprocess __kernel_entry NTSTATUS
// NtQueryInformationProcess( IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, OUT PVOID ProcessInformation, IN
// ULONG ProcessInformationLength, OUT PULONG ReturnLength );
[DllImport(Lib.NtDll, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winternl.h", MSDNShortId = "0eae7899-c40b-4a5f-9e9c-adae021885e7")]
public static extern NTStatus NtQueryInformationProcess([In] HPROCESS ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, [Out] IntPtr ProcessInformation, uint ProcessInformationLength, out uint ReturnLength);
///
///
/// [ NtQueryInformationProcess may be altered or unavailable in future versions of Windows. Applications should use the
/// alternate functions listed in this topic.]
///
/// Retrieves information about the specified process.
///
/// A handle to the process for which information is to be retrieved.
///
///
/// The type of process information to be retrieved. This parameter can be one of the following values from the
/// PROCESSINFOCLASS enumeration.
///
///
///
/// Value
/// Meaning
///
/// -
/// ProcessBasicInformation
0
///
/// Retrieves a pointer to a PEB structure that can be used to determine whether the specified process is being debugged, and a
/// unique value used by the system to identify the specified process. Use the CheckRemoteDebuggerPresent and GetProcessId functions
/// to obtain this information.
///
///
/// -
/// ProcessDebugPort
7
///
/// Retrieves a DWORD_PTR value that is the port number of the debugger for the process. A nonzero value indicates that the process
/// is being run under the control of a ring 3 debugger. Use the CheckRemoteDebuggerPresent or IsDebuggerPresent function.
///
///
/// -
/// ProcessWow64Information
26
///
/// Determines whether the process is running in the WOW64 environment (WOW64 is the x86 emulator that allows Win32-based
/// applications to run on 64-bit Windows). Use the IsWow64Process2 function to obtain this information.
///
///
/// -
/// ProcessImageFileName
27
///
/// Retrieves a UNICODE_STRING value containing the name of the image file for the process. Use the QueryFullProcessImageName or
/// GetProcessImageFileName function to obtain this information.
///
///
/// -
/// ProcessBreakOnTermination
29
/// Retrieves a ULONG value indicating whether the process is considered critical.
///
/// -
/// ProcessSubsystemInformation
75
///
/// Retrieves a SUBSYSTEM_INFORMATION_TYPE value indicating the subsystem type of the process. The buffer pointed to by the
/// ProcessInformation parameter should be large enough to hold a single SUBSYSTEM_INFORMATION_TYPE enumeration.
///
///
///
///
///
///
/// A pointer to a buffer supplied by the calling application into which the function writes the requested information. The size of
/// the information written varies depending on the data type of the ProcessInformationClass parameter:
///
/// PROCESS_BASIC_INFORMATION
///
/// When the ProcessInformationClass parameter is ProcessBasicInformation, the buffer pointed to by the ProcessInformation
/// parameter should be large enough to hold a single PROCESS_BASIC_INFORMATION structure having the following layout:
///
///
///
/// The UniqueProcessId member points to the system's unique identifier for this process. Use the GetProcessId function to
/// retrieve this information.
///
/// The PebBaseAddress member points to a PEB structure.
/// The other members of this structure are reserved for internal use by the operating system.
/// ULONG_PTR
///
/// When the ProcessInformationClass parameter is ProcessWow64Information, the buffer pointed to by the ProcessInformation
/// parameter should be large enough to hold a ULONG_PTR. If this value is nonzero, the process is running in a WOW64
/// environment; otherwise, if the value is equal to zero, the process is not running in a WOW64 environment.
///
/// Use the IsWow64Process2 function to determine whether a process is running in the WOW64 environment.
/// UNICODE_STRING
///
/// When the ProcessInformationClass parameter is ProcessImageFileName, the buffer pointed to by the ProcessInformation
/// parameter should be large enough to hold a UNICODE_STRING structure as well as the string itself. The string stored in
/// the Buffer member is the name of the image file.
///
///
/// If the buffer is too small, the function fails with the STATUS_INFO_LENGTH_MISMATCH error code and the ReturnLength parameter is
/// set to the required buffer size.
///
///
/// The size of the buffer pointed to by the ProcessInformation parameter, in bytes.
///
/// A pointer to a variable in which the function returns the size of the requested information. If the function was successful,
/// this is the size of the information written to the buffer pointed to by the ProcessInformation parameter, but if the buffer was
/// too small, this is the minimum size of buffer needed to receive the information successfully.
///
///
/// The function returns an NTSTATUS success or error code.
///
/// The forms and significance of NTSTATUS error codes are listed in the Ntstatus.h header file available in the DDK, and are
/// described in the DDK documentation under Kernel-Mode Driver Architecture / Design Guide / Driver Programming Techniques /
/// Logging Errors.
///
///
///
///
/// The NtQueryInformationProcess function and the structures that it returns are internal to the operating system and
/// subject to change from one release of Windows to another. To maintain the compatibility of your application, it is better to use
/// public functions mentioned in the description of the ProcessInformationClass parameter instead.
///
///
/// If you do use NtQueryInformationProcess, access the function through run-time dynamic linking. This gives your code an
/// opportunity to respond gracefully if the function has been changed or removed from the operating system. Signature changes,
/// however, may not be detectable.
///
///
/// This function has no associated import library. You must use the LoadLibrary and GetProcAddress functions to dynamically link to Ntdll.dll.
///
///
[DllImport(Lib.NtDll, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winternl.h")]
public static extern NTStatus NtWow64QueryInformationProcess64([In] HPROCESS ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, [Out] int ProcessInformation, [In] ulong ProcessInformationLength, out ulong ReturnLength);
///
/// Retrieves information about the specified process.
///
/// The type of the structure to retrieve.
/// A handle to the process for which information is to be retrieved.
///
///
/// The type of process information to be retrieved. This parameter can be one of the following values from the
/// PROCESSINFOCLASS enumeration.
///
///
///
/// Value
/// Meaning
///
/// -
/// ProcessBasicInformation
0
///
/// Retrieves a pointer to a PEB structure that can be used to determine whether the specified process is being debugged, and a
/// unique value used by the system to identify the specified process. Use the CheckRemoteDebuggerPresent and GetProcessId functions
/// to obtain this information.
///
///
/// -
/// ProcessDebugPort
7
///
/// Retrieves a DWORD_PTR value that is the port number of the debugger for the process. A nonzero value indicates that the process
/// is being run under the control of a ring 3 debugger. Use the CheckRemoteDebuggerPresent or IsDebuggerPresent function.
///
///
/// -
/// ProcessWow64Information
26
///
/// Determines whether the process is running in the WOW64 environment (WOW64 is the x86 emulator that allows Win32-based
/// applications to run on 64-bit Windows). Use the IsWow64Process2 function to obtain this information.
///
///
/// -
/// ProcessImageFileName
27
///
/// Retrieves a UNICODE_STRING value containing the name of the image file for the process. Use the QueryFullProcessImageName or
/// GetProcessImageFileName function to obtain this information.
///
///
/// -
/// ProcessBreakOnTermination
29
/// Retrieves a ULONG value indicating whether the process is considered critical.
///
/// -
/// ProcessSubsystemInformation
75
///
/// Retrieves a SUBSYSTEM_INFORMATION_TYPE value indicating the subsystem type of the process. The buffer pointed to by the
/// ProcessInformation parameter should be large enough to hold a single SUBSYSTEM_INFORMATION_TYPE enumeration.
///
///
///
///
/// The structure and associated memory for any allocated sub-types.
/// Mismatch between requested type and class.
public static NtQueryResult NtQueryInformationProcess([In] HPROCESS ProcessHandle, PROCESSINFOCLASS ProcessInformationClass) where T : struct
{
var validTypes = CorrespondingTypeAttribute.GetCorrespondingTypes(ProcessInformationClass, CorrespondingAction.Get).ToArray();
if (validTypes.Length > 0 && Array.IndexOf(validTypes, typeof(T)) == -1)
throw new ArgumentException("Mismatch between requested type and class.");
#if x64
// Check if the target is a 32 bit process running in WoW64 mode.
if (IsWow64(ProcessHandle))
{
// We are 64 bit. Target process is 32 bit running in WoW64 mode.
throw new PlatformNotSupportedException("Unable to query a 32-bit process from a 64-bit process.");
}
#else
if (NtQueryInformationProcessRequiresWow64Structs(ProcessHandle))
{
if (validTypes.Length > 1 && !TypeIsWow()) throw new ArgumentException("Type name must end in WOW64 to indicate it was configured exclusively for 64-bit use.");
var mem = new NtQueryResult();
var status = NtWow64QueryInformationProcess64(ProcessHandle, ProcessInformationClass, ((IntPtr)mem).ToInt32(), mem.Size, out var sz);
if (status.Succeeded) return mem;
if (status != NTStatus.STATUS_INFO_LENGTH_MISMATCH || sz == 0) throw status.GetException();
mem.Size = sz;
NtWow64QueryInformationProcess64(ProcessHandle, ProcessInformationClass, ((IntPtr)mem).ToInt32(), mem.Size, out _).ThrowIfFailed();
return mem;
}
#endif
// Target process is of the same bitness as us.
else
{
if (validTypes.Length > 1 && TypeIsWow()) throw new ArgumentException("Type name must not end in WOW64 should be configured for 32 or 64-bit use.");
var mem = new NtQueryResult();
var status = NtQueryInformationProcess(ProcessHandle, ProcessInformationClass, mem, mem.Size, out var sz);
if (status.Succeeded) return mem;
if (status != NTStatus.STATUS_INFO_LENGTH_MISMATCH || sz == 0) throw status.GetException();
mem.Size = sz;
NtQueryInformationProcess(ProcessHandle, ProcessInformationClass, mem, mem.Size, out _).ThrowIfFailed();
return mem;
}
bool TypeIsWow() => typeof(T).Name.EndsWith("WOW64");
}
/// A call to NtQueryInformationProcess for the supplied process requires WOW64 structs.
/// The process handle.
/// if structures returned from NtQueryInformationProcess must be configured exclusively for 64-bit use.
public static bool NtQueryInformationProcessRequiresWow64Structs(HPROCESS ProcessHandle) => IsWow64(Kernel32.GetCurrentProcess()) && !IsWow64(ProcessHandle);
internal static bool IsWow64(HPROCESS hProc) => (Environment.OSVersion.Version.Major >= 6 || (Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor >= 1)) && Kernel32.IsWow64Process(hProc, out var b) && b;
/// Timing information for a process.
[StructLayout(LayoutKind.Sequential)]
public struct KERNEL_USER_TIMES
{
/// The creation time of the process.
public FILETIME CreateTime;
/// The exit time of the process.
public FILETIME ExitTime;
///
/// The amount of time that the process has executed in kernel mode. The time that each of the threads of the process has
/// executed in kernel mode is determined, and then all of those times are summed together to obtain this value.
///
public FILETIME KernelTime;
///
/// The amount of time that the process has executed in user mode. The time that each of the threads of the process has executed
/// in user mode is determined, and then all of those times are summed together to obtain this value. Note that this value can
/// exceed the amount of real time elapsed (between lpCreationTime and lpExitTime) if the process executes across multiple CPU cores.
///
public FILETIME UserTime;
}
///
/// [This structure may be altered in future versions of Windows.]
/// Contains process information.
///
/// The syntax for this structure on 64-bit Windows is as follows:
// https://docs.microsoft.com/en-us/windows/win32/api/winternl/ns-winternl-peb typedef struct _PEB { BYTE Reserved1[2]; BYTE
// BeingDebugged; BYTE Reserved2[1]; PVOID Reserved3[2]; PPEB_LDR_DATA Ldr; PRTL_USER_PROCESS_PARAMETERS ProcessParameters; PVOID
// Reserved4[3]; PVOID AtlThunkSListPtr; PVOID Reserved5; ULONG Reserved6; PVOID Reserved7; ULONG Reserved8; ULONG
// AtlThunkSListPtr32; PVOID Reserved9[45]; BYTE Reserved10[96]; PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine; BYTE
// Reserved11[128]; PVOID Reserved12[1]; ULONG SessionId; } PEB, *PPEB;
[PInvokeData("winternl.h", MSDNShortId = "836a6b82-d3e8-4de6-808d-5476dfb51356")]
[StructLayout(LayoutKind.Sequential)]
public struct PEB
{
/// Reserved for internal use by the operating system.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
private readonly byte[] Reserved_1;
/// Indicates whether the specified process is currently being debugged.
public byte BeingDebugged;
/// Reserved for internal use by the operating system.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
private readonly byte[] Reserved2;
/// Reserved for internal use by the operating system.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
private readonly IntPtr[] Reserved3;
/// A pointer to a PEB_LDR_DATA structure that contains information about the loaded modules for the process.
public IntPtr Ldr;
///
/// A pointer to an RTL_USER_PROCESS_PARAMETERS structure that contains process parameter information such as the command line.
///
public IntPtr ProcessParameters;
/// Reserved for internal use by the operating system.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
private readonly IntPtr[] Reserved4;
private readonly IntPtr AtlThunkSListPtr;
/// Reserved for internal use by the operating system.
private readonly IntPtr Reserved5;
/// Reserved for internal use by the operating system.
private readonly uint Reserved6;
/// Reserved for internal use by the operating system.
private readonly IntPtr Reserved7;
/// Reserved for internal use by the operating system.
private readonly uint Reserved8;
///
private readonly uint AtlThunkSListPtr32;
/// Reserved for internal use by the operating system.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 45)]
private readonly IntPtr[] Reserved9;
/// Reserved for internal use by the operating system.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 96)]
private readonly byte[] Reserved10;
///
private readonly IntPtr PostProcessInitRoutine;
/// Reserved for internal use by the operating system.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
private readonly byte[] Reserved11;
/// Reserved for internal use by the operating system.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
private readonly IntPtr[] Reserved12;
/// The Terminal Services session identifier associated with the current process.
public uint SessionId;
}
///
/// [This structure may be altered in future versions of Windows.]
/// Contains process information.
///
/// The syntax for this structure on 64-bit Windows is as follows:
// https://docs.microsoft.com/en-us/windows/win32/api/winternl/ns-winternl-peb typedef struct _PEB { BYTE Reserved1[2]; BYTE
// BeingDebugged; BYTE Reserved2[1]; PVOID Reserved3[2]; PPEB_LDR_DATA Ldr; PRTL_USER_PROCESS_PARAMETERS ProcessParameters; PVOID
// Reserved4[3]; PVOID AtlThunkSListPtr; PVOID Reserved5; ULONG Reserved6; PVOID Reserved7; ULONG Reserved8; ULONG
// AtlThunkSListPtr32; PVOID Reserved9[45]; BYTE Reserved10[96]; PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine; BYTE
// Reserved11[128]; PVOID Reserved12[1]; ULONG SessionId; } PEB, *PPEB;
[PInvokeData("winternl.h", MSDNShortId = "836a6b82-d3e8-4de6-808d-5476dfb51356")]
[StructLayout(LayoutKind.Sequential)]
public struct PEB_WOW64
{
/// Reserved for internal use by the operating system.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
private readonly byte[] Reserved_1;
/// Indicates whether the specified process is currently being debugged.
public byte BeingDebugged;
/// Reserved for internal use by the operating system.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
private readonly byte[] Reserved2;
/// Reserved for internal use by the operating system.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
private readonly long[] Reserved3;
/// A pointer to a PEB_LDR_DATA structure that contains information about the loaded modules for the process.
public long Ldr;
///
/// A pointer to an RTL_USER_PROCESS_PARAMETERS structure that contains process parameter information such as the command line.
///
public long ProcessParameters;
/// Reserved for internal use by the operating system.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
private readonly long[] Reserved4;
private readonly long AtlThunkSListPtr;
/// Reserved for internal use by the operating system.
private readonly long Reserved5;
/// Reserved for internal use by the operating system.
private readonly uint Reserved6;
/// Reserved for internal use by the operating system.
private readonly long Reserved7;
/// Reserved for internal use by the operating system.
private readonly uint Reserved8;
///
private readonly uint AtlThunkSListPtr32;
/// Reserved for internal use by the operating system.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 45)]
private readonly long[] Reserved9;
/// Reserved for internal use by the operating system.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 96)]
private readonly byte[] Reserved10;
///
private readonly long PostProcessInitRoutine;
/// Reserved for internal use by the operating system.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
private readonly byte[] Reserved11;
/// Reserved for internal use by the operating system.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
private readonly long[] Reserved12;
/// The Terminal Services session identifier associated with the current process.
public uint SessionId;
}
/// Contains information for basic process information.
/// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684280(v=vs.85).aspx
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_BASIC_INFORMATION
{
/// Reserved for internal use by the operating system.
private readonly IntPtr Reserved1;
/// Pointer to a PEB structure.
public IntPtr PebBaseAddress;
/// Reserved for internal use by the operating system.
private readonly IntPtr Reserved2_1;
/// Reserved for internal use by the operating system.
private readonly IntPtr Reserved2_2;
/// System's unique identifier for this process.
public IntPtr UniqueProcessId;
/// Reserved for internal use by the operating system.
private readonly IntPtr Reserved3;
}
/// Contains information for basic process information.
/// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684280(v=vs.85).aspx
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_BASIC_INFORMATION_WOW64
{
/// Reserved for internal use by the operating system.
private readonly long Reserved1;
/// Pointer to a PEB structure.
public long PebBaseAddress;
/// Reserved for internal use by the operating system.
private readonly long Reserved2_1;
/// Reserved for internal use by the operating system.
private readonly long Reserved2_2;
/// System's unique identifier for this process.
public long UniqueProcessId;
/// Reserved for internal use by the operating system.
private readonly long Reserved3;
}
///
/// [This structure may be altered in future versions of Windows.]
/// Contains process parameter information.
///
// https://docs.microsoft.com/en-us/windows/win32/api/winternl/ns-winternl-rtl_user_process_parameters typedef struct
// _RTL_USER_PROCESS_PARAMETERS { BYTE Reserved1[16]; PVOID Reserved2[10]; UNICODE_STRING ImagePathName; UNICODE_STRING CommandLine;
// } RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
[PInvokeData("winternl.h", MSDNShortId = "e736aefa-9945-4526-84d8-adb6e82b9991")]
[StructLayout(LayoutKind.Sequential)]
public struct RTL_USER_PROCESS_PARAMETERS
{
/// Reserved for internal use by the operating system.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
private readonly byte[] Reserved1;
/// Reserved for internal use by the operating system.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
private readonly IntPtr[] Reserved2;
/// The path of the image file for the process.
public UNICODE_STRING ImagePathName;
/// The command-line string passed to the process.
public UNICODE_STRING CommandLine;
}
///
/// [This structure may be altered in future versions of Windows.]
/// Contains process parameter information.
///
// https://docs.microsoft.com/en-us/windows/win32/api/winternl/ns-winternl-rtl_user_process_parameters typedef struct
// _RTL_USER_PROCESS_PARAMETERS { BYTE Reserved1[16]; PVOID Reserved2[10]; UNICODE_STRING ImagePathName; UNICODE_STRING CommandLine;
// } RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
[PInvokeData("winternl.h", MSDNShortId = "e736aefa-9945-4526-84d8-adb6e82b9991")]
[StructLayout(LayoutKind.Sequential)]
public struct RTL_USER_PROCESS_PARAMETERS_WOW64
{
/// Reserved for internal use by the operating system.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
private readonly byte[] Reserved1;
/// Reserved for internal use by the operating system.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
private readonly long[] Reserved2;
/// The path of the image file for the process.
public UNICODE_STRING_WOW64 ImagePathName;
/// The command-line string passed to the process.
public UNICODE_STRING_WOW64 CommandLine;
}
///
/// Represents the structure and associated memory returned by NtQueryXX functions. The memory associate with this structure
/// will be disposed when this variable goes out of scope or is disposed.
///
/// The type of the retrieved structure.
public class NtQueryResult : SafeMemStruct where T : struct
{
internal NtQueryResult(uint sz = 0) : base(sz)
{
}
}
}
}