Vanara/PInvoke/Kernel32/ProcessThreadsApi.cs

7949 lines
431 KiB
C#
Raw Normal View History

2018-05-13 23:41:49 -04:00
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
2018-05-13 23:41:49 -04:00
using System.Runtime.InteropServices;
using System.Text;
2018-10-26 14:24:07 -04:00
using Vanara.Extensions;
2018-05-13 23:41:49 -04:00
using Vanara.InteropServices;
using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME;
namespace Vanara.PInvoke;
public static partial class Kernel32
2018-05-13 23:41:49 -04:00
{
/// <summary>Value indicating that there are no thread local storage indexes to allocate.</summary>
public const uint TLS_OUT_OF_INDEXES = 0xFFFFFFFF;
/// <summary>The maximum processors.</summary>
public static readonly uint MAXIMUM_PROCESSORS = Is64bitOS() ? 64U : 32U;
/// <summary>
/// An application-defined completion routine. Specify this address when calling the QueueUserAPC function. The PAPCFUNC type defines a
/// pointer to this callback function.
/// </summary>
/// <param name="dwParam">The data passed to the function using the dwData parameter of the QueueUserAPC function.</param>
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void PAPCFUNC(IntPtr dwParam);
/// <summary>Represents the type of information in the <c>SYSTEM_CPU_SET_INFORMATION</c> structure.</summary>
// typedef enum _CPU_SET_INFORMATION_TYPE { CpuSetInformation} CPU_SET_INFORMATION_TYPE, *PCPU_SET_INFORMATION_TYPE; https://msdn.microsoft.com/en-us/library/windows/desktop/mt186423(v=vs.85).aspx
[PInvokeData("Processthreadapi.h", MSDNShortId = "mt186423")]
public enum CPU_SET_INFORMATION_TYPE
2018-05-13 23:41:49 -04:00
{
/// <summary>The structure contains CPU Set information.</summary>
CpuSetInformation
}
2018-05-13 23:41:49 -04:00
/// <summary>
/// The following process creation flags are used by the <c>CreateProcess</c>, <c>CreateProcessAsUser</c>,
/// <c>CreateProcessWithLogonW</c>, and <c>CreateProcessWithTokenW</c> functions. They can be specified in any combination, except as noted.
/// </summary>
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684863(v=vs.85).aspx
[PInvokeData("WinBase.h", MSDNShortId = "ms684863")]
[Flags]
public enum CREATE_PROCESS : uint
{
2018-05-13 23:41:49 -04:00
/// <summary>
/// The child processes of a process associated with a job are not associated with the job. If the calling process is not associated
/// with a job, this constant has no effect. If the calling process is associated with a job, the job must set the
/// JOB_OBJECT_LIMIT_BREAKAWAY_OK limit.
2018-05-13 23:41:49 -04:00
/// </summary>
CREATE_BREAKAWAY_FROM_JOB = 0x01000000,
2018-05-13 23:41:49 -04:00
/// <summary>
/// The new process does not inherit the error mode of the calling process. Instead, the new process gets the default error mode.
/// This feature is particularly useful for multithreaded shell applications that run with hard errors disabled.The default behavior
/// is for the new process to inherit the error mode of the caller. Setting this flag changes that default behavior.
/// </summary>
CREATE_DEFAULT_ERROR_MODE = 0x04000000,
2018-05-13 23:41:49 -04:00
/// <summary>
/// The new process has a new console, instead of inheriting its parent's console (the default). For more information, see Creation
/// of a Console. This flag cannot be used with DETACHED_PROCESS.
2018-05-13 23:41:49 -04:00
/// </summary>
CREATE_NEW_CONSOLE = 0x00000010,
2018-10-26 14:24:07 -04:00
/// <summary>
/// The new process is the root process of a new process group. The process group includes all processes that are descendants of this
/// root process. The process identifier of the new process group is the same as the process identifier, which is returned in the
/// lpProcessInformation parameter. Process groups are used by the GenerateConsoleCtrlEvent function to enable sending a CTRL+BREAK
/// signal to a group of console processes.If this flag is specified, CTRL+C signals will be disabled for all processes within the
/// new process group.This flag is ignored if specified with CREATE_NEW_CONSOLE.
/// </summary>
CREATE_NEW_PROCESS_GROUP = 0x00000200,
2018-10-26 14:24:07 -04:00
/// <summary>
/// The process is a console application that is being run without a console window. Therefore, the console handle for the
/// application is not set.This flag is ignored if the application is not a console application, or if it is used with either
/// CREATE_NEW_CONSOLE or DETACHED_PROCESS.
/// </summary>
CREATE_NO_WINDOW = 0x08000000,
2018-10-26 14:24:07 -04:00
/// <summary>
/// The process is to be run as a protected process. The system restricts access to protected processes and the threads of protected
/// processes. For more information on how processes can interact with protected processes, see Process Security and Access Rights.To
/// activate a protected process, the binary must have a special signature. This signature is provided by Microsoft but not currently
/// available for non-Microsoft binaries. There are currently four protected processes: media foundation, audio engine, Windows error
/// reporting, and system. Components that load into these binaries must also be signed. Multimedia companies can leverage the first
/// two protected processes. For more information, see Overview of the Protected Media Path.Windows Server 2003 and Windows XP: This
/// value is not supported.
/// </summary>
CREATE_PROTECTED_PROCESS = 0x00040000,
2018-10-26 14:24:07 -04:00
/// <summary>
/// Allows the caller to execute a child process that bypasses the process restrictions that would normally be applied automatically
/// to the process.
/// </summary>
CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000,
2018-10-26 14:24:07 -04:00
/// <summary>This flag allows secure processes, that run in the Virtualization-Based Security environment, to launch.</summary>
CREATE_SECURE_PROCESS = 0x00400000,
2018-10-26 14:24:07 -04:00
/// <summary>
/// This flag is valid only when starting a 16-bit Windows-based application. If set, the new process runs in a private Virtual DOS
/// Machine (VDM). By default, all 16-bit Windows-based applications run as threads in a single, shared VDM. The advantage of running
/// separately is that a crash only terminates the single VDM; any other programs running in distinct VDMs continue to function
/// normally. Also, 16-bit Windows-based applications that are run in separate VDMs have separate input queues. That means that if
/// one application stops responding momentarily, applications in separate VDMs continue to receive input. The disadvantage of
/// running separately is that it takes significantly more memory to do so. You should use this flag only if the user requests that
/// 16-bit applications should run in their own VDM.
/// </summary>
CREATE_SEPARATE_WOW_VDM = 0x00000800,
2018-10-26 14:24:07 -04:00
/// <summary>
/// The flag is valid only when starting a 16-bit Windows-based application. If the DefaultSeparateVDM switch in the Windows section
/// of WIN.INI is TRUE, this flag overrides the switch. The new process is run in the shared Virtual DOS Machine.
/// </summary>
CREATE_SHARED_WOW_VDM = 0x00001000,
2018-10-26 14:24:07 -04:00
/// <summary>
/// The primary thread of the new process is created in a suspended state, and does not run until the ResumeThread function is called.
/// </summary>
CREATE_SUSPENDED = 0x00000004,
2018-10-26 14:24:07 -04:00
/// <summary>
/// If this flag is set, the environment block pointed to by lpEnvironment uses Unicode characters. Otherwise, the environment block
/// uses ANSI characters.
/// </summary>
CREATE_UNICODE_ENVIRONMENT = 0x00000400,
2018-10-26 14:24:07 -04:00
/// <summary>
/// The calling thread starts and debugs the new process. It can receive all related debug events using the WaitForDebugEvent function.
/// </summary>
DEBUG_ONLY_THIS_PROCESS = 0x00000002,
2018-10-26 14:24:07 -04:00
/// <summary>
/// The calling thread starts and debugs the new process and all child processes created by the new process. It can receive all
/// related debug events using the WaitForDebugEvent function. A process that uses DEBUG_PROCESS becomes the root of a debugging
/// chain. This continues until another process in the chain is created with DEBUG_PROCESS.If this flag is combined with
/// DEBUG_ONLY_THIS_PROCESS, the caller debugs only the new process, not any child processes.
/// </summary>
DEBUG_PROCESS = 0x00000001,
2018-10-26 14:24:07 -04:00
/// <summary>
/// For console processes, the new process does not inherit its parent's console (the default). The new process can call the
/// AllocConsole function at a later time to create a console. For more information, see Creation of a Console. This value cannot be
/// used with CREATE_NEW_CONSOLE.
/// </summary>
DETACHED_PROCESS = 0x00000008,
2018-10-26 14:24:07 -04:00
/// <summary>
/// The process is created with extended startup information; the lpStartupInfo parameter specifies a STARTUPINFOEX structure.Windows
/// Server 2003 and Windows XP: This value is not supported.
/// </summary>
EXTENDED_STARTUPINFO_PRESENT = 0x00080000,
2018-10-26 14:24:07 -04:00
/// <summary>
/// The process inherits its parent's affinity. If the parent process has threads in more than one processor group, the new process
/// inherits the group-relative affinity of an arbitrary group in use by the parent.Windows Server 2008, Windows Vista, Windows
/// Server 2003 and Windows XP: This value is not supported.
/// </summary>
INHERIT_PARENT_AFFINITY = 0x00010000,
2018-10-26 14:24:07 -04:00
/// <summary>Process with no special scheduling needs.</summary>
NORMAL_PRIORITY_CLASS = 0x00000020,
2018-10-26 14:24:07 -04:00
/// <summary>
/// Process whose threads run only when the system is idle and are preempted by the threads of any process running in a higher
/// priority class. An example is a screen saver. The idle priority class is inherited by child processes.
/// </summary>
IDLE_PRIORITY_CLASS = 0x00000040,
2018-10-26 14:24:07 -04:00
/// <summary>
/// Process that performs time-critical tasks that must be executed immediately for it to run correctly. The threads of a
/// high-priority class process preempt the threads of normal or idle priority class processes. An example is the Task List, which
/// must respond quickly when called by the user, regardless of the load on the operating system. Use extreme care when using the
/// high-priority class, because a high-priority class CPU-bound application can use nearly all available cycles.
/// </summary>
HIGH_PRIORITY_CLASS = 0x00000080,
2018-10-26 14:24:07 -04:00
/// <summary>
/// Process that has the highest possible priority. The threads of a real-time priority class process preempt the threads of all
/// other processes, including operating system processes performing important tasks. For example, a real-time process that executes
/// for more than a very brief interval can cause disk caches not to flush or cause the mouse to be unresponsive.
/// </summary>
REALTIME_PRIORITY_CLASS = 0x00000100,
2018-10-26 14:24:07 -04:00
/// <summary>Process that has priority above IDLE_PRIORITY_CLASS but below NORMAL_PRIORITY_CLASS.</summary>
BELOW_NORMAL_PRIORITY_CLASS = 0x00004000,
2018-10-26 14:24:07 -04:00
/// <summary>Process that has priority above NORMAL_PRIORITY_CLASS but below HIGH_PRIORITY_CLASS.</summary>
ABOVE_NORMAL_PRIORITY_CLASS = 0x00008000,
2018-10-26 14:24:07 -04:00
/// <summary>Undocumented.</summary>
CREATE_FORCEDOS = 0x00002000,
2018-10-26 14:24:07 -04:00
/// <summary>Creates profiles for the user mode modeuls of the process.</summary>
PROFILE_USER = 0x10000000,
2018-10-26 14:24:07 -04:00
/// <summary>Undocumented.</summary>
PROFILE_KERNEL = 0x20000000,
2018-10-26 14:24:07 -04:00
/// <summary>Undocumented.</summary>
PROFILE_SERVER = 0x40000000,
2018-10-26 14:24:07 -04:00
/// <summary>Undocumented.</summary>
CREATE_IGNORE_SYSTEM_DEFAULT = 0x80000000,
2018-10-26 14:24:07 -04:00
/// <summary>Undocumented.</summary>
INHERIT_CALLER_PRIORITY = 0x00020000,
2018-10-26 14:24:07 -04:00
/// <summary>
/// Begin background processing mode. The system lowers the resource scheduling priorities of the process (and its threads) so that
/// it can perform background work without significantly affecting activity in the foreground.
/// <para>
/// This value can be specified only if hProcess is a handle to the current process. The function fails if the process is already in
/// background processing mode.
/// </para>
/// <para>Windows Server 2003 and Windows XP: This value is not supported.</para>
/// </summary>
PROCESS_MODE_BACKGROUND_BEGIN = 0x00100000,
2018-10-26 14:24:07 -04:00
/// <summary>
/// End background processing mode. The system restores the resource scheduling priorities of the process (and its threads) as they
/// were before the process entered background processing mode.
/// <para>
/// This value can be specified only if hProcess is a handle to the current process. The function fails if the process is not in
/// background processing mode.
/// </para>
/// <para>Windows Server 2003 and Windows XP: This value is not supported.</para>
/// </summary>
PROCESS_MODE_BACKGROUND_END = 0x00200000,
}
2018-10-26 14:24:07 -04:00
/// <summary>
/// Flags used by <see cref="CreateRemoteThread(HPROCESS, SECURITY_ATTRIBUTES, SizeT, IntPtr, IntPtr, CREATE_THREAD_FLAGS, out uint)"/>.
/// </summary>
[Flags]
public enum CREATE_THREAD_FLAGS
{
/// <term>The thread runs immediately after creation.</term>
RUN_IMMEDIATELY = 0,
2018-10-26 14:24:07 -04:00
/// <term>The thread is created in a suspended state, and does not run until the ResumeThread function is called.</term>
CREATE_SUSPENDED = 4,
2018-05-13 23:41:49 -04:00
/// The dwStackSize parameter specifies the initial reserve size of the stack. If this flag is not specified, dwStackSize specifies
/// the commit size.
STACK_SIZE_PARAM_IS_A_RESERVATION = 0x00010000,
}
2018-10-26 14:24:07 -04:00
/// <summary>Flags that apply to the dynamic exception handling continuation target in TargetAddress in <see cref="PROCESS_DYNAMIC_EH_CONTINUATION_TARGET"/>.</summary>
[PInvokeData("winnt.h", MSDNShortId = "NS:winnt._PROCESS_DYNAMIC_EH_CONTINUATION_TARGET")]
[Flags]
public enum DYNAMIC_EH_CONTINUATION_TARGET
{
/// <summary>
/// Dynamic exception handling continuation target should be added. If this flag is not set, the target is removed. This is an input flag.
/// </summary>
DYNAMIC_EH_CONTINUATION_TARGET_ADD = 0x00000001,
2018-10-26 14:24:07 -04:00
/// <summary>
/// Dynamic exception handling continuation target has been successfully processed (either added or removed). This is an output flag
/// used to report which targets were successfully processed when processing an array of multiple targets.
/// </summary>
DYNAMIC_EH_CONTINUATION_TARGET_PROCESSED = 0x00000002
}
2018-05-13 23:41:49 -04:00
/// <summary>Specifies the ways in which an architecture of code can run on a host operating system. More than one bit may be set.</summary>
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/ne-processthreadsapi-machine_attributes typedef enum
// _MACHINE_ATTRIBUTES { UserEnabled, KernelEnabled, Wow64Container } MACHINE_ATTRIBUTES;
[PInvokeData("processthreadsapi.h", MSDNShortId = "NE:processthreadsapi._MACHINE_ATTRIBUTES")]
public enum MACHINE_ATTRIBUTES
{
/// <summary>The specified architecture of code can run in user mode.</summary>
UserEnabled,
/// <summary>The specified architecture of code can run in kernel mode.</summary>
KernelEnabled,
/// <summary>
/// The specified architecture of code runs by relying on WOW64's namespace <c>File System Redirector</c> and <c>Registry
/// Redirector</c>. This bit will be set, for example, on x86 code running on a host operating system that is x64 or ARM64. When the
/// compatibility layer does not use WOW64 style filesystem and registry namespaces, like x64 on ARM64 which runs on the root
/// namespace of the OS, this bit will be reset.
/// </summary>
Wow64Container,
}
/// <summary>The memory priority for the thread or process.</summary>
public enum MEMORY_PRIORITY
{
/// <summary>Lowest memory priority.</summary>
MEMORY_PRIORITY_LOWEST = 0,
/// <summary>Very low memory priority.</summary>
MEMORY_PRIORITY_VERY_LOW = 1,
/// <summary>Low memory priority.</summary>
MEMORY_PRIORITY_LOW = 2,
2018-10-26 14:24:07 -04:00
/// <summary>Medium memory priority.</summary>
MEMORY_PRIORITY_MEDIUM = 3,
2018-10-26 14:24:07 -04:00
/// <summary>Below normal memory priority.</summary>
MEMORY_PRIORITY_BELOW_NORMAL = 4,
2018-10-26 14:24:07 -04:00
/// <summary>Normal memory priority. This is the default priority for all threads and processes on the system.</summary>
MEMORY_PRIORITY_NORMAL = 5,
}
2018-10-26 14:24:07 -04:00
/// <summary>The affinity update mode.</summary>
public enum PROCESS_AFFINITY_MODE
{
/// <summary>Dynamic update of the process affinity by the system is disabled.</summary>
PROCESS_AFFINITY_DISABLE_AUTO_UPDATE,
2018-10-26 14:24:07 -04:00
/// <summary>Dynamic update of the process affinity by the system is enabled.</summary>
PROCESS_AFFINITY_ENABLE_AUTO_UPDATE
}
2018-05-13 23:41:49 -04:00
/// <summary>
/// Indicates a specific class of process information. Values from this enumeration are passed into the GetProcessInformation and
/// SetProcessInformation functions to specify the type of process information passed in the void pointer argument of the function call.
/// </summary>
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/ne-processthreadsapi-process_information_class typedef enum
// _PROCESS_INFORMATION_CLASS { ProcessMemoryPriority, ProcessMemoryExhaustionInfo, ProcessAppMemoryInfo, ProcessInPrivateInfo,
// ProcessPowerThrottling, ProcessReservedValue1, ProcessTelemetryCoverageInfo, ProcessProtectionLevelInfo, ProcessLeapSecondInfo,
// ProcessMachineTypeInfo, ProcessInformationClassMax } PROCESS_INFORMATION_CLASS;
[PInvokeData("processthreadsapi.h", MSDNShortId = "NE:processthreadsapi._PROCESS_INFORMATION_CLASS")]
public enum PROCESS_INFORMATION_CLASS
{
/// <summary>
/// The process information is represented by a MEMORY_PRIORITY_INFORMATION structure. Allows applications to lower the default
/// memory priority of threads that perform background operations or access files and data that are not expected to be accessed again soon.
/// </summary>
[CorrespondingType(typeof(MEMORY_PRIORITY_INFORMATION), CorrespondingAction.GetSet)]
ProcessMemoryPriority,
2018-10-26 14:24:07 -04:00
/// <summary>
/// The process information is represented by a PROCESS_MEMORY_EXHAUSTION_INFO structure. Allows applications to configure a process
/// to terminate if an allocation fails to commit memory.
/// </summary>
[CorrespondingType(typeof(PROCESS_MEMORY_EXHAUSTION_INFO), CorrespondingAction.Set)]
ProcessMemoryExhaustionInfo,
2018-05-13 23:41:49 -04:00
/// <summary>
/// The process information is represented by a APP_MEMORY_INFORMATION structure. Allows applications to query the commit usage and
/// the additional commit available to this process. Does not allow the caller to actually get a commit limit.
/// </summary>
[CorrespondingType(typeof(APP_MEMORY_INFORMATION), CorrespondingAction.Get)]
ProcessAppMemoryInfo,
2018-10-26 14:24:07 -04:00
/// <summary>
/// If a process is set to <c>ProcessInPrivate</c> mode, and a trace session has set the EVENT_ENABLE_PROPERTY_EXCLUDE_INPRIVATE
/// flag, then the trace session will drop all events from that process.
/// </summary>
ProcessInPrivateInfo,
2018-10-26 14:24:07 -04:00
/// <summary>
/// The process information is represented by a PROCESS_POWER_THROTTLING_STATE structure. Allows applications to configure how the
/// system should throttle the target processs activity when managing power.
/// </summary>
[CorrespondingType(typeof(PROCESS_POWER_THROTTLING_STATE), CorrespondingAction.GetSet)]
ProcessPowerThrottling,
2018-10-26 14:24:07 -04:00
/// <summary>Reserved.</summary>
ProcessReservedValue1,
2018-10-26 14:24:07 -04:00
/// <summary>Reserved.</summary>
ProcessTelemetryCoverageInfo,
2018-10-26 14:24:07 -04:00
/// <summary>The process information is represented by a PROCESS_PROTECTION_LEVEL_INFORMATION structure.</summary>
[CorrespondingType(typeof(PROCESS_PROTECTION_LEVEL_INFORMATION), CorrespondingAction.Get)]
ProcessProtectionLevelInfo,
2018-10-26 14:24:07 -04:00
/// <summary>The process information is represented by a PROCESS_LEAP_SECOND_INFO structure.</summary>
[CorrespondingType(typeof(PROCESS_LEAP_SECOND_INFO), CorrespondingAction.GetSet)]
ProcessLeapSecondInfo,
2018-10-26 14:24:07 -04:00
/// <summary>The process is represented by a PROCESS_MACHINE_INFORMATION structure.</summary>
[CorrespondingType(typeof(PROCESS_MACHINE_INFORMATION), CorrespondingAction.Get)]
ProcessMachineTypeInfo,
}
/// <summary>Flags for <see cref="PROCESS_LEAP_SECOND_INFO.Flags"/>.</summary>
[PInvokeData("processthreadsapi.h")]
[Flags]
public enum PROCESS_LEAP_SECOND_INFO_FLAGS
{
/// <summary>
/// This value changes the way positive leap seconds are handled by system. Specifically, it changes how the seconds field during a
/// positive leap second is handled by the system. If this value is used, then the positive leap second will be shown (For example:
/// 23:59:59 -&gt; 23:59:60 -&gt; 00:00:00. If this value is not used, then "sixty seconds" is disabled, and the 59th second
/// preceding a positive leap second will be shown for 2 seconds with the milliseconds value ticking twice as slow. So 23:59:59 -&gt;
/// 23:59:59.500 -&gt; 00:00:00, which takes 2 seconds in wall clock time. Disabling "sixty second" can help with legacy apps that do
/// not support seeing the seconds value as 60 during the positive leap second. Such apps may crash or misbehave. Therefore, in these
/// cases, we display the 59th second for twice as long during the positive leap second. Note that this setting is per-process, and
/// does not persist if the process is restarted. Developers should test their app for compatibility with seeing the system return
/// "60", and add a call to their app startup routines to either enable or disable "sixty seconds". "Sixty seconds" is disabled by
/// default for each process. Obviously, this setting has no effect if leap seconds are disabled system-wide, because then the system
/// will never even encounter a leap second.
/// </summary>
PROCESS_LEAP_SECOND_INFO_FLAG = 1
}
/// <summary>Represents the different memory exhaustion types.</summary>
// typedef enum _PROCESS_MEMORY_EXHAUSTION_TYPE { PMETypeFailFastOnCommitFailure, PMETypeMax} PROCESS_MEMORY_EXHAUSTION_TYPE,
// *PPROCESS_MEMORY_EXHAUSTION_TYPE;// https://msdn.microsoft.com/en-us/library/windows/desktop/mt767998(v=vs.85).aspx
[PInvokeData("WinBase.h", MSDNShortId = "mt767998")]
public enum PROCESS_MEMORY_EXHAUSTION_TYPE
{
/// <summary>
/// Anytime memory management fails an allocation due to an inability to commit memory, it will cause the process to trigger a
/// Windows Error Reporting report and then terminate immediately with <c>STATUS_COMMITMENT_LIMIT</c>. The failure cannot be caught
/// and handled by the app.
/// </summary>
PMETypeFailFastOnCommitFailure,
/// <summary>The maximum value for this enumeration. This value may change in a future version.</summary>
PMETypeMax
}
2018-05-13 23:41:49 -04:00
/// <summary>Flags used by PROCESS_MITIGATION_ASLR_POLICY</summary>
[Flags]
public enum PROCESS_MITIGATION_ASLR_POLICY_FLAGS : uint
{
/// <summary>
/// Thread stacks and other bottom-up allocations are subject to randomization by ASLR if this flag is set. This flag is read-only
/// and cannot be modified after a process has been created.
/// </summary>
EnableBottomUpRandomization = 1 << 0,
2018-10-26 14:24:07 -04:00
/// <summary>Images that have not been built with /DYNAMICBASE are forcibly relocated on load if this flag is set.</summary>
EnableForceRelocateImages = 1 << 1,
2018-05-13 23:41:49 -04:00
/// <summary>
/// Bottom-up allocations are subject to higher degrees of entropy when randomized by ASLR if this flag is set. This flag only
/// applies to 64-bit processes and is read-only.
/// </summary>
EnableHighEntropy = 1 << 2,
2018-10-26 14:24:07 -04:00
/// <summary>
/// Images that have not been built with /DYNAMICBASE and do not have relocation information will fail to load if this flag and
/// <c>EnableForceRelocateImages</c> are set.
/// </summary>
DisallowStrippedImages = 1 << 3,
}
2018-10-26 14:24:07 -04:00
/// <summary>Flags used by PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY.</summary>
[Flags]
public enum PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY_FLAGS : uint
{
/// <summary>Set (0x1) to prevent the process from loading images that are not signed by Microsoft; otherwise leave unset (0x0).</summary>
MicrosoftSignedOnly = 1 << 0,
2018-10-26 14:24:07 -04:00
/// <summary>
/// Set (0x1) to prevent the process from loading images that are not signed by the Windows Store; otherwise leave unset (0x0).
/// </summary>
StoreSignedOnly = 1 << 1,
2018-05-13 23:41:49 -04:00
/// <summary>
/// Set (0x1) to prevent the process from loading images that are not signed by Microsoft, the Windows Store and the Windows Hardware
/// Quality Labs (WHQL); otherwise leave unset (0x0).
/// </summary>
MitigationOptIn = 1 << 2,
2018-10-26 14:24:07 -04:00
/// <summary>Undocumented</summary>
AuditMicrosoftSignedOnly = 1 << 3,
2018-10-26 14:24:07 -04:00
/// <summary>Undocumented</summary>
AuditStoreSignedOnly = 1 << 4,
}
2018-10-26 14:24:07 -04:00
/// <summary>Flags used by PROCESS_MITIGATION_CHILD_PROCESS_POLICY.</summary>
[Flags]
public enum PROCESS_MITIGATION_CHILD_PROCESS_POLICY_FLAGS : uint
{
/// <summary>If set, the process cannot create child processes.</summary>
NoChildProcessCreation = 1 << 0,
2018-10-26 14:24:07 -04:00
/// <summary>
/// If set, causes audit events to be generated when child processes are created by the process. If both NoChildProcessCreation and
/// AuditNoChildProcessCreation are set, NoChildProcessCreation takes precedence over audit setting.
/// </summary>
AuditNoChildProcessCreation = 1 << 1,
2018-05-13 23:41:49 -04:00
/// <summary>
/// Denies creation of child processes unless the child process is a secure process and if creation was previously blocked. It allows
/// a process to spawn a child process on behalf of another process that cannot itself create child processes. See
/// PROCESS_CREATION_CHILD_PROCESS_OVERRIDE in UpdateProcThreadAttribute.
/// </summary>
AllowSecureProcessCreation = 1 << 2,
}
2018-10-26 14:24:07 -04:00
/// <summary>Flags used by PROCESS_MITIGATION_CONTROL_FLOW_GUARD_POLICY</summary>
[Flags]
public enum PROCESS_MITIGATION_CONTROL_FLOW_GUARD_POLICY_FLAGS : uint
{
/// <summary>CFG is enabled for the process if this flag is set. This field cannot be changed via SetProcessMitigationPolicy.</summary>
EnableControlFlowGuard = 1 << 0,
2018-10-26 14:24:07 -04:00
/// <summary>
/// If TRUE, exported functions will be treated as invalid indirect call targets by default. Exported functions only become valid
/// indirect call targets if they are dynamically resolved via GetProcAddress. This field cannot be changed via <c>SetProcessMitigationPolicy</c>.
/// </summary>
EnableExportSuppression = 1 << 1,
2018-05-13 23:41:49 -04:00
/// <summary>
/// If TRUE, all DLLs that are loaded must enable CFG. If a DLL does not enable CFG then the image will fail to load. This policy can
/// be enabled after a process has started by calling <c>SetProcessMitigationPolicy</c>. It cannot be disabled once enabled.
/// </summary>
StrictMode = 1 << 2,
}
2018-10-26 14:24:07 -04:00
/// <summary>Flags used by PROCESS_MITIGATION_DEP_POLICY</summary>
[Flags]
public enum PROCESS_MITIGATION_DEP_POLICY_FLAGS : uint
{
/// <summary>DEP is enabled for the process if this flag is set.</summary>
Enable = 1 << 0,
2018-10-26 14:24:07 -04:00
/// <summary>ATL thunk emulation is disabled for the process if this flag is set.</summary>
DisableAtlThunkEmulation = 1 << 1,
}
2018-05-13 23:41:49 -04:00
/// <summary>Flags used by PROCESS_MITIGATION_DYNAMIC_CODE_POLICY</summary>
[Flags]
public enum PROCESS_MITIGATION_DYNAMIC_CODE_POLICY_FLAGS : uint
{
/// <summary>
/// Set (0x1) to prevent the process from generating dynamic code or modifying existing executable code; otherwise leave unset (0x0).
/// </summary>
ProhibitDynamicCode = 1 << 0,
2018-10-26 14:24:07 -04:00
/// <summary>
/// Set (0x1) to allow threads to opt out of the restrictions on dynamic code generation by calling the <c>SetThreadInformation</c>
/// function with the ThreadInformation parameter set to <c>ThreadDynamicCodePolicy</c>; otherwise leave unset (0x0). You should not
/// use the <c>AllowThreadOptOut</c> and <c>ThreadDynamicCodePolicy</c> settings together to provide strong security. These settings
/// are only intended to enable applications to adapt their code more easily for full dynamic code restrictions.
/// </summary>
AllowThreadOptOut = 1 << 1,
2018-05-13 23:41:49 -04:00
/// <summary>
/// Set (0x1) to allow non-AppContainer processes to modify all of the dynamic code settings for the calling process, including
/// relaxing dynamic code restrictions after they have been set.
/// </summary>
AllowRemoteDowngrade = 1 << 2,
2018-10-26 14:24:07 -04:00
/// <summary>Undocumented</summary>
AuditProhibitDynamicCode = 1 << 3,
}
2018-10-26 14:24:07 -04:00
/// <summary>Flags used by PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY</summary>
[Flags]
public enum PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY_FLAGS : uint
{
/// <summary>Prevents legacy extension point DLLs from being loaded into the process.</summary>
DisableExtensionPoints = 1 << 0,
}
2018-05-13 23:41:49 -04:00
/// <summary>Flags used by PROCESS_MITIGATION_FONT_DISABLE_POLICY.</summary>
[Flags]
public enum PROCESS_MITIGATION_FONT_DISABLE_POLICY_FLAGS : uint
{
/// <summary>Set (0x1) to prevent the process from loading non-system fonts; otherwise leave unset (0x0).</summary>
DisableNonSystemFonts = 1 << 0,
2018-05-13 23:41:49 -04:00
/// <summary>
/// Set (0x1) to indicate that an Event Tracing for Windows (ETW) event should be logged when the process attempts to load a
/// non-system font; leave unset (0x0) to indicate that an ETW event should not be logged.
/// </summary>
AuditNonSystemFontLoading = 1 << 1,
}
2018-10-26 14:24:07 -04:00
/// <summary>Flags used by PROCESS_MITIGATION_IMAGE_LOAD_POLICY.</summary>
[Flags]
public enum PROCESS_MITIGATION_IMAGE_LOAD_POLICY_FLAGS : uint
{
/// <summary>
/// Set (0x1) to prevent the process from loading images from a remote device, such as a UNC share; otherwise leave unset (0x0).
/// </summary>
NoRemoteImages = 1 << 0,
2018-05-13 23:41:49 -04:00
/// <summary>
/// Set (0x1) to prevent the process from loading images that have a Low mandatory label, as written by low IL; otherwise leave unset (0x0).
/// </summary>
NoLowMandatoryLabelImages = 1 << 1,
2018-10-26 14:24:07 -04:00
/// <summary>
/// Set (0x1) to search for images to load in the System32 subfolder of the folder in which Windows is installed first, then in the
/// application directory in the standard DLL search order; otherwise leave unset (0x0).
/// </summary>
PreferSystem32Images = 1 << 2,
2018-10-26 14:24:07 -04:00
/// <summary>Undocumented.</summary>
AuditNoRemoteImages = 1 << 3,
2018-10-26 14:24:07 -04:00
/// <summary>Undocumented.</summary>
AuditNoLowMandatoryLabelImages = 1 << 4,
}
2018-10-26 14:24:07 -04:00
/// <summary>Flags used by PROCESS_MITIGATION_PAYLOAD_RESTRICTION_POLICY.</summary>
[Flags]
public enum PROCESS_MITIGATION_PAYLOAD_RESTRICTION_POLICY_FLAGS : uint
{
/// <summary>If set this enables the Export Address Filter mitigation in enforcement mode for the process.</summary>
EnableExportAddressFilter = 1 << 0,
2018-05-13 23:41:49 -04:00
/// <summary>If set this enables the Export Address Filter mitigation in audit mode for the process.</summary>
AuditExportAddressFilter = 1 << 1,
2018-10-26 14:24:07 -04:00
/// <summary>If set this enables the Export Address Filter Plus mitigation in enforcement mode for the process.</summary>
EnableExportAddressFilterPlus = 1 << 2,
2018-10-26 14:24:07 -04:00
/// <summary>If set this enables the Export Address Filter mitigation in audit mode for the process.</summary>
AuditExportAddressFilterPlus = 1 << 3,
2018-10-26 14:24:07 -04:00
/// <summary>If set this enables the Import Address Filter mitigation in enforcement mode for the process.</summary>
EnableImportAddressFilter = 1 << 4,
2018-10-26 14:24:07 -04:00
/// <summary>If set this enables the Import Address Filter mitigation in enforcement mode for the process.</summary>
AuditImportAddressFilter = 1 << 5,
2018-10-26 14:24:07 -04:00
/// <summary>
/// If set this enables the stack pivot anti-ROP (Return-oriented-programming) mitigation in enforcement mode for the process.
/// </summary>
EnableRopStackPivot = 1 << 6,
2018-10-26 14:24:07 -04:00
/// <summary>If set this enables the stack pivot anti-ROP (Return-oriented-programming) mitigation in audit mode for the process.</summary>
AuditRopStackPivot = 1 << 7,
2018-10-26 14:24:07 -04:00
/// <summary>
/// If set this enables the caller check anti-ROP (Return-oriented-programming) mitigation in enforcement mode for the process.
/// Applies to 32-bit processes only.
/// </summary>
EnableRopCallerCheck = 1 << 8,
2018-10-26 14:24:07 -04:00
/// <summary>
/// If set this enables the caller check anti-ROP (Return-oriented-programming) mitigation in audit mode for the process. Applies to
/// 32-bit processes only.
/// </summary>
AuditRopCallerCheck = 1 << 9,
2018-10-26 14:24:07 -04:00
/// <summary>
/// If set this enables the simulated execution anti-ROP (Return-oriented-programming) mitigation in enforcement mode for the
/// process. Applies to 32-bit processes only.
/// </summary>
EnableRopSimExec = 1 << 10,
2018-10-26 14:24:07 -04:00
/// <summary>
/// If set this enables the simulated execution anti-ROP (Return-oriented-programming) mitigation in audit mode for the process.
/// Applies to 32-bit processes only.
/// </summary>
AuditRopSimExec = 1 << 11,
}
2018-10-26 14:24:07 -04:00
/// <summary>Represents the different process mitigation policies.</summary>
[PInvokeData("winnt.h")]
public enum PROCESS_MITIGATION_POLICY
{
/// <summary>The data execution prevention (DEP) policy of the process.</summary>
[CorrespondingType(typeof(PROCESS_MITIGATION_DEP_POLICY))]
ProcessDEPPolicy,
2018-05-13 23:41:49 -04:00
/// <summary>The Address Space Layout Randomization (ASLR) policy of the process.</summary>
[CorrespondingType(typeof(PROCESS_MITIGATION_ASLR_POLICY))]
ProcessASLRPolicy,
2018-10-26 14:24:07 -04:00
/// <summary>The policy that turns off the ability of the process to generate dynamic code or modify existing executable code.</summary>
[CorrespondingType(typeof(PROCESS_MITIGATION_DYNAMIC_CODE_POLICY))]
ProcessDynamicCodePolicy,
2018-10-26 14:24:07 -04:00
/// <summary>
/// The process will receive a fatal error if it manipulates an invalid handle. Useful for preventing downstream problems in a
/// process due to handle misuse.
/// </summary>
[CorrespondingType(typeof(PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY))]
ProcessStrictHandleCheckPolicy,
2018-10-26 14:24:07 -04:00
/// <summary>Disables the ability to use NTUser/GDI functions at the lowest layer.</summary>
[CorrespondingType(typeof(PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY))]
ProcessSystemCallDisablePolicy,
2018-10-26 14:24:07 -04:00
/// <summary>
/// Returns the mask of valid bits for all the mitigation options on the system. An application can set many mitigation options
/// without querying the operating system for mitigation options by combining bitwise with the mask to exclude all non-supported bits
/// at once.
/// </summary>
[CorrespondingType(typeof(ulong[]))]
ProcessMitigationOptionsMask,
2018-10-26 14:24:07 -04:00
/// <summary>
/// The policy that prevents some built-in third party extension points from being turned on, which prevents legacy extension point
/// DLLs from being loaded into the process.
/// </summary>
[CorrespondingType(typeof(PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY))]
ProcessExtensionPointDisablePolicy,
2018-10-26 14:24:07 -04:00
/// <summary>The Control Flow Guard (CFG) policy of the process.</summary>
[CorrespondingType(typeof(PROCESS_MITIGATION_CONTROL_FLOW_GUARD_POLICY))]
ProcessControlFlowGuardPolicy,
2018-10-26 14:24:07 -04:00
/// <summary>
/// The policy of a process that can restrict image loading to those images that are either signed by Microsoft, by the Windows
/// Store, or by Microsoft, the Windows Store and the Windows Hardware Quality Labs (WHQL).
/// </summary>
[CorrespondingType(typeof(PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY))]
ProcessSignaturePolicy,
2018-10-26 14:24:07 -04:00
/// <summary>The policy that turns off the ability of the process to load non-system fonts.</summary>
[CorrespondingType(typeof(PROCESS_MITIGATION_FONT_DISABLE_POLICY))]
ProcessFontDisablePolicy,
2018-10-26 14:24:07 -04:00
/// <summary>
/// The policy that turns off the ability of the process to load images from some locations, such a remote devices or files that have
/// the low mandatory label.
/// </summary>
[CorrespondingType(typeof(PROCESS_MITIGATION_IMAGE_LOAD_POLICY))]
ProcessImageLoadPolicy,
}
2018-10-26 14:24:07 -04:00
/// <summary>Flags used by PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY</summary>
[Flags]
public enum PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY_FLAGS : uint
{
/// <summary>
/// When set to 1, an exception is raised if an invalid handle to a kernel object is used. Except as noted in the Remarks section,
/// once exceptions for invalid handles are enabled for a process, they cannot be disabled.
/// </summary>
RaiseExceptionOnInvalidHandleReference = 1 << 0,
2018-05-13 23:41:49 -04:00
/// <summary>When set to 1, exceptions for invalid kernel handles are permanently enabled.</summary>
HandleExceptionsPermanentlyEnabled = 1 << 1,
}
2018-10-26 14:24:07 -04:00
/// <summary>Flags used by PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY</summary>
[Flags]
public enum PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY_FLAGS : uint
{
/// <summary>When set to 1, the process is not permitted to perform GUI system calls.</summary>
DisallowWin32kSystemCalls = 1 << 0,
2018-05-13 23:41:49 -04:00
/// <summary>Undocumented.</summary>
AuditDisallowWin32kSystemCalls = 1 << 1,
}
2018-10-26 14:24:07 -04:00
/// <summary>Enables the caller to take control of the power throttling mechanism.</summary>
[PInvokeData("processthreadsapi.h", MSDNShortId = "394B6509-849C-4B4C-9A46-AF5011A03585")]
[Flags]
public enum PROCESS_POWER_THROTTLING_MASK
{
/// <summary>Manages the execution speed of the process.</summary>
PROCESS_POWER_THROTTLING_EXECUTION_SPEED = 1
}
2018-05-13 23:41:49 -04:00
/// <summary>
/// <para>
/// The Microsoft Windows security model enables you to control access to process objects. For more information about security, see
/// Access-Control Model.
/// </para>
/// <para>
/// When a user logs in, the system collects a set of data that uniquely identifies the user during the authentication process, and
/// stores it in an access token. This access token describes the security context of all processes associated with the user. The
/// security context of a process is the set of credentials given to the process or the user account that created the process.
/// </para>
/// <para>
/// You can use a token to specify the current security context for a process using the <c>CreateProcessWithTokenW</c> function. You can
/// specify a security descriptor for a process when you call the <c>CreateProcess</c>, <c>CreateProcessAsUser</c>, or
/// <c>CreateProcessWithLogonW</c> function. If you specify <c>NULL</c>, the process gets a default security descriptor. The ACLs in the
/// default security descriptor for a process come from the primary or impersonation token of the creator.
/// </para>
/// <para>
/// To retrieve a process's security descriptor, call the <c>GetSecurityInfo</c> function. To change a process's security descriptor,
/// call the <c>SetSecurityInfo</c> function.
/// </para>
/// <para>
/// The valid access rights for process objects include the standard access rights and some process-specific access rights. The following
/// table lists the standard access rights used by all objects.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>DELETE (0x00010000L)</term>
/// <term>Required to delete the object.</term>
/// </item>
/// <item>
/// <term>READ_CONTROL (0x00020000L)</term>
/// <term>
/// Required to read information in the security descriptor for the object, not including the information in the SACL. To read or write
/// the SACL, you must request the ACCESS_SYSTEM_SECURITY access right. For more information, see SACL Access Right.
/// </term>
/// </item>
/// <item>
/// <term>SYNCHRONIZE (0x00100000L)</term>
/// <term>The right to use the object for synchronization. This enables a thread to wait until the object is in the signaled state.</term>
/// </item>
/// <item>
/// <term>WRITE_DAC (0x00040000L)</term>
/// <term>Required to modify the DACL in the security descriptor for the object.</term>
/// </item>
/// <item>
/// <term>WRITE_OWNER (0x00080000L)</term>
/// <term>Required to change the owner in the security descriptor for the object.</term>
/// </item>
/// </list>
/// <para>The following table lists the process-specific access rights.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PROCESS_ALL_ACCESS</term>
/// <term>
/// All possible access rights for a process object.Windows Server 2003 and Windows XP: The size of the PROCESS_ALL_ACCESS flag increased
/// on Windows Server 2008 and Windows Vista. If an application compiled for Windows Server 2008 and Windows Vista is run on Windows
/// Server 2003 or Windows XP, the PROCESS_ALL_ACCESS flag is too large and the function specifying this flag fails with
/// ERROR_ACCESS_DENIED. To avoid this problem, specify the minimum set of access rights required for the operation. If
/// PROCESS_ALL_ACCESS must be used, set _WIN32_WINNT to the minimum operating system targeted by your application (for example, ). For
/// more information, see Using the Windows Headers.
/// </term>
/// </item>
/// <item>
/// <term>PROCESS_CREATE_PROCESS (0x0080)</term>
/// <term>Required to create a process.</term>
/// </item>
/// <item>
/// <term>PROCESS_CREATE_THREAD (0x0002)</term>
/// <term>Required to create a thread.</term>
/// </item>
/// <item>
/// <term>PROCESS_DUP_HANDLE (0x0040)</term>
/// <term>Required to duplicate a handle using DuplicateHandle.</term>
/// </item>
/// <item>
/// <term>PROCESS_QUERY_INFORMATION (0x0400)</term>
/// <term>Required to retrieve certain information about a process, such as its token, exit code, and priority class (see OpenProcessToken).</term>
/// </item>
/// <item>
/// <term>PROCESS_QUERY_LIMITED_INFORMATION (0x1000)</term>
/// <term>
/// Required to retrieve certain information about a process (see GetExitCodeProcess, GetPriorityClass, IsProcessInJob,
/// QueryFullProcessImageName). A handle that has the PROCESS_QUERY_INFORMATION access right is automatically granted
/// PROCESS_QUERY_LIMITED_INFORMATION.Windows Server 2003 and Windows XP: This access right is not supported.
/// </term>
/// </item>
/// <item>
/// <term>PROCESS_SET_INFORMATION (0x0200)</term>
/// <term>Required to set certain information about a process, such as its priority class (see SetPriorityClass).</term>
/// </item>
/// <item>
/// <term>PROCESS_SET_QUOTA (0x0100)</term>
/// <term>Required to set memory limits using SetProcessWorkingSetSize.</term>
/// </item>
/// <item>
/// <term>PROCESS_SUSPEND_RESUME (0x0800)</term>
/// <term>Required to suspend or resume a process.</term>
/// </item>
/// <item>
/// <term>PROCESS_TERMINATE (0x0001)</term>
/// <term>Required to terminate a process using TerminateProcess.</term>
/// </item>
/// <item>
/// <term>PROCESS_VM_OPERATION (0x0008)</term>
/// <term>Required to perform an operation on the address space of a process (see VirtualProtectEx and WriteProcessMemory).</term>
/// </item>
/// <item>
/// <term>PROCESS_VM_READ (0x0010)</term>
/// <term>Required to read memory in a process using ReadProcessMemory.</term>
/// </item>
/// <item>
/// <term>PROCESS_VM_WRITE (0x0020)</term>
/// <term>Required to write to memory in a process using WriteProcessMemory.</term>
/// </item>
/// <item>
/// <term>SYNCHRONIZE (0x00100000L)</term>
/// <term>Required to wait for the process to terminate using the wait functions.</term>
/// </item>
/// </list>
/// <para>
/// To open a handle to another process and obtain full access rights, you must enable the <c>SeDebugPrivilege</c> privilege. For more
/// information, see Changing Privileges in a Token.
/// </para>
/// <para>
/// The handle returned by the <c>CreateProcess</c> function has <c>PROCESS_ALL_ACCESS</c> access to the process object. When you call
/// the <c>OpenProcess</c> function, the system checks the requested access rights against the DACL in the process's security descriptor.
/// When you call the <c>GetCurrentProcess</c> function, the system returns a pseudohandle with the maximum access that the DACL allows
/// to the caller.
/// </para>
/// <para>
/// You can request the <c>ACCESS_SYSTEM_SECURITY</c> access right to a process object if you want to read or write the object's SACL.
/// For more information, see Access-Control Lists (ACLs) and SACL Access Right.
/// </para>
/// </summary>
// https://docs.microsoft.com/en-us/windows/win32/procthread/process-security-and-access-rights
[PInvokeData("ntpsapi.h", MSDNShortId = "508a17c4-88cd-431a-a102-00180a7f7ab5")]
[Flags]
public enum ProcessAccess : uint
{
/// <summary>Required to terminate a process using TerminateProcess.</summary>
PROCESS_TERMINATE = 0x0001,
/// <summary>Required to create a thread.</summary>
PROCESS_CREATE_THREAD = 0x0002,
2018-10-26 14:24:07 -04:00
/// <summary/>
PROCESS_SET_SESSIONID = 0x0004,
2018-10-26 14:24:07 -04:00
/// <summary>Required to perform an operation on the address space of a process (see VirtualProtectEx and WriteProcessMemory).</summary>
PROCESS_VM_OPERATION = 0x0008,
2018-10-26 14:24:07 -04:00
/// <summary>Required to read memory in a process using ReadProcessMemory.</summary>
PROCESS_VM_READ = 0x0010,
2018-10-26 14:24:07 -04:00
/// <summary>Required to write to memory in a process using WriteProcessMemory.</summary>
PROCESS_VM_WRITE = 0x0020,
2018-10-26 14:24:07 -04:00
/// <summary>Required to duplicate a handle using DuplicateHandle.</summary>
PROCESS_DUP_HANDLE = 0x0040,
2018-10-26 14:24:07 -04:00
/// <summary>Required to create a process.</summary>
PROCESS_CREATE_PROCESS = 0x0080,
2018-10-26 14:24:07 -04:00
/// <summary>Required to set memory limits using SetProcessWorkingSetSize.</summary>
PROCESS_SET_QUOTA = 0x0100,
2018-10-26 14:24:07 -04:00
/// <summary>Required to set certain information about a process, such as its priority class (see SetPriorityClass).</summary>
PROCESS_SET_INFORMATION = 0x0200,
2018-10-26 14:24:07 -04:00
/// <summary>Required to retrieve certain information about a process, such as its token, exit code, and priority class (see OpenProcessToken).</summary>
PROCESS_QUERY_INFORMATION = 0x0400,
2018-10-26 14:24:07 -04:00
/// <summary>Required to suspend or resume a process.</summary>
PROCESS_SUSPEND_RESUME = 0x0800,
2018-10-26 14:24:07 -04:00
/// <summary>
/// Required to retrieve certain information about a process (see GetExitCodeProcess, GetPriorityClass, IsProcessInJob,
/// QueryFullProcessImageName). A handle that has the PROCESS_QUERY_INFORMATION access right is automatically granted
/// PROCESS_QUERY_LIMITED_INFORMATION.Windows Server 2003 and Windows XP: This access right is not supported.
/// </summary>
PROCESS_QUERY_LIMITED_INFORMATION = 0x1000,
2018-10-26 14:24:07 -04:00
/// <summary/>
PROCESS_SET_LIMITED_INFORMATION = 0x2000,
2018-10-26 14:24:07 -04:00
/// <summary>
/// All possible access rights for a process object.Windows Server 2003 and Windows XP: The size of the PROCESS_ALL_ACCESS flag
/// increased on Windows Server 2008 and Windows Vista. If an application compiled for Windows Server 2008 and Windows Vista is run
/// on Windows Server 2003 or Windows XP, the PROCESS_ALL_ACCESS flag is too large and the function specifying this flag fails with
/// ERROR_ACCESS_DENIED. To avoid this problem, specify the minimum set of access rights required for the operation. If
/// PROCESS_ALL_ACCESS must be used, set _WIN32_WINNT to the minimum operating system targeted by your application (for example, ).
/// For more information, see Using the Windows Headers.
/// </summary>
PROCESS_ALL_ACCESS = ACCESS_MASK.STANDARD_RIGHTS_REQUIRED | ACCESS_MASK.SYNCHRONIZE | 0xFFFF,
}
2018-10-26 14:24:07 -04:00
/// <summary>The processor feature to be tested.</summary>
[PInvokeData("winnt.h", MSDNShortId = "ms724482")]
public enum PROCESSOR_FEATURE
{
/// <summary>The alpha byte instructions are available.</summary>
PF_ALPHA_BYTE_INSTRUCTIONS = 5,
2018-10-26 14:24:07 -04:00
/// <summary>The 64-bit load/store atomic instructions are available.</summary>
PF_ARM_64BIT_LOADSTORE_ATOMIC = 25,
2018-10-26 14:24:07 -04:00
/// <summary>The divide instructions are available.</summary>
PF_ARM_DIVIDE_INSTRUCTION_AVAILABLE = 24,
2018-10-26 14:24:07 -04:00
/// <summary>The external cache is available.</summary>
PF_ARM_EXTERNAL_CACHE_AVAILABLE = 26,
2018-10-26 14:24:07 -04:00
/// <summary>The floating-point multiply-accumulate instruction is available.</summary>
PF_ARM_FMAC_INSTRUCTIONS_AVAILABLE = 27,
2018-10-26 14:24:07 -04:00
/// <summary>The neon instructions are available.</summary>
PF_ARM_NEON_INSTRUCTIONS_AVAILABLE = 19,
2018-10-26 14:24:07 -04:00
/// <summary>The v8 CRC32 instructions are available.</summary>
PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE = 31,
2018-10-26 14:24:07 -04:00
/// <summary>The v8 Crypto instructions are available.</summary>
PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE = 30,
2018-10-26 14:24:07 -04:00
/// <summary>The v8 instructions are available.</summary>
PF_ARM_V8_INSTRUCTIONS_AVAILABLE = 29,
2018-10-26 14:24:07 -04:00
/// <summary>The VFP/Neon: 32 x 64bit register bank is present. This flag has the same meaning as PF_ARM_VFP_EXTENDED_REGISTERS.</summary>
PF_ARM_VFP_32_REGISTERS_AVAILABLE = 18,
2018-10-26 14:24:07 -04:00
/// <summary>The 3D-Now instruction set is available.</summary>
PF_3DNOW_INSTRUCTIONS_AVAILABLE = 7,
2018-10-26 14:24:07 -04:00
/// <summary>The processor channels are enabled.</summary>
PF_CHANNELS_ENABLED = 16,
2018-10-26 14:24:07 -04:00
/// <summary>The atomic compare and exchange operation (cmpxchg) is available.</summary>
PF_COMPARE_EXCHANGE_DOUBLE = 2,
2018-10-26 14:24:07 -04:00
/// <summary>
/// The atomic compare and exchange 128-bit operation (cmpxchg16b) is available.
/// <para>Windows Server 2003 and Windows XP/2000: This feature is not supported.</para>
/// </summary>
PF_COMPARE_EXCHANGE128 = 14,
2018-10-26 14:24:07 -04:00
/// <summary>
/// The atomic compare 64 and exchange 128-bit operation (cmp8xchg16) is available.
/// <para>Windows Server 2003 and Windows XP/2000: This feature is not supported.</para>
/// </summary>
PF_COMPARE64_EXCHANGE128 = 15,
2018-10-26 14:24:07 -04:00
/// <summary>_fastfail() is available.</summary>
PF_FASTFAIL_AVAILABLE = 23,
2018-10-26 14:24:07 -04:00
/// <summary>
/// Floating-point operations are emulated using a software emulator.
/// <para>This function returns a nonzero value if floating-point operations are emulated; otherwise, it returns zero.</para>
/// </summary>
PF_FLOATING_POINT_EMULATED = 1,
2018-10-26 14:24:07 -04:00
/// <summary>On a Pentium, a floating-point precision error can occur in rare circumstances.</summary>
PF_FLOATING_POINT_PRECISION_ERRATA = 0,
2018-10-26 14:24:07 -04:00
/// <summary>The MMX instruction set is available.</summary>
PF_MMX_INSTRUCTIONS_AVAILABLE = 3,
2018-10-26 14:24:07 -04:00
/// <summary>
/// Data execution prevention is enabled.
/// <para>Windows XP/2000: This feature is not supported until Windows XP with SP2 and Windows Server 2003 with SP1.</para>
/// </summary>
PF_NX_ENABLED = 12,
2018-05-13 23:41:49 -04:00
/// <summary>
/// The processor is PAE-enabled. For more information, see Physical Address Extension.
/// <para>All x64 processors always return a nonzero value for this feature.</para>
/// </summary>
PF_PAE_ENABLED = 9,
2018-10-26 14:24:07 -04:00
/// <summary>The PPC movemem 64 bit is ok.</summary>
PF_PPC_MOVEMEM_64BIT_OK = 4,
2018-10-26 14:24:07 -04:00
/// <summary>The pf rdrand instruction available</summary>
PF_RDRAND_INSTRUCTION_AVAILABLE = 28,
2018-10-26 14:24:07 -04:00
/// <summary>The RDTSC instruction is available.</summary>
PF_RDTSC_INSTRUCTION_AVAILABLE = 8,
2018-10-26 14:24:07 -04:00
/// <summary>The pf RDTSCP instruction available</summary>
PF_RDTSCP_INSTRUCTION_AVAILABLE = 32,
2018-10-26 14:24:07 -04:00
/// <summary>RDFSBASE, RDGSBASE, WRFSBASE, and WRGSBASE instructions are available.</summary>
PF_RDWRFSGSBASE_AVAILABLE = 22,
2018-10-26 14:24:07 -04:00
/// <summary>Second Level Address Translation is supported by the hardware.</summary>
PF_SECOND_LEVEL_ADDRESS_TRANSLATION = 20,
2018-10-26 14:24:07 -04:00
/// <summary>The pf sse daz mode available</summary>
PF_SSE_DAZ_MODE_AVAILABLE = 11,
2018-10-26 14:24:07 -04:00
/// <summary>
/// The SSE3 instruction set is available.
/// <para>Windows Server 2003 and Windows XP/2000: This feature is not supported.</para>
/// </summary>
PF_SSE3_INSTRUCTIONS_AVAILABLE = 13,
2018-10-26 14:24:07 -04:00
/// <summary>Virtualization is enabled in the firmware.</summary>
PF_VIRT_FIRMWARE_ENABLED = 21,
2018-10-26 14:24:07 -04:00
/// <summary>The SSE instruction set is available.</summary>
PF_XMMI_INSTRUCTIONS_AVAILABLE = 6,
2018-05-13 23:41:49 -04:00
/// <summary>
/// The SSE2 instruction set is available.
/// <para>Windows 2000: This feature is not supported.</para>
/// </summary>
PF_XMMI64_INSTRUCTIONS_AVAILABLE = 10,
2018-05-13 23:41:49 -04:00
/// <summary>
/// The processor implements the XSAVE and XRSTOR instructions.
/// <para>
/// Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP/2000: This feature is not supported until Windows 7 and
/// Windows Server 2008 R2.
/// </para>
/// </summary>
PF_XSAVE_ENABLED = 17,
}
2018-10-26 14:24:07 -04:00
/// <summary>Process protection level.</summary>
public enum PROTECTION_LEVEL : uint
{
/// <summary>For internal use only.</summary>
PROTECTION_LEVEL_WINTCB_LIGHT = 0x00000000,
2018-10-26 14:24:07 -04:00
/// <summary>For internal use only.</summary>
PROTECTION_LEVEL_WINDOWS = 0x00000001,
2018-10-26 14:24:07 -04:00
/// <summary>For internal use only.</summary>
PROTECTION_LEVEL_WINDOWS_LIGHT = 0x00000002,
2018-10-26 14:24:07 -04:00
/// <summary>For internal use only.</summary>
PROTECTION_LEVEL_ANTIMALWARE_LIGHT = 0x00000003,
2018-10-26 14:24:07 -04:00
/// <summary>For internal use only.</summary>
PROTECTION_LEVEL_LSA_LIGHT = 0x00000004,
2018-10-26 14:24:07 -04:00
/// <summary>Not implemented.</summary>
PROTECTION_LEVEL_WINTCB = 0x00000005,
2018-10-26 14:24:07 -04:00
/// <summary>Not implemented.</summary>
PROTECTION_LEVEL_CODEGEN_LIGHT = 0x00000006,
2018-10-26 14:24:07 -04:00
/// <summary>Not implemented.</summary>
PROTECTION_LEVEL_AUTHENTICODE = 0x00000007,
2018-10-26 14:24:07 -04:00
/// <summary>The process is a third party app that is using process protection.</summary>
PROTECTION_LEVEL_PPL_APP = 0x00000008,
2018-10-26 14:24:07 -04:00
/// <summary>The protection level same</summary>
PROTECTION_LEVEL_SAME = 0xFFFFFFFF,
2018-10-26 14:24:07 -04:00
/// <summary>The process is not protected.</summary>
PROTECTION_LEVEL_NONE = 0xFFFFFFFE,
}
2018-10-26 14:24:07 -04:00
/// <summary>Value retrieved by the <see cref="GetProcessShutdownParameters"/> function.</summary>
public enum SHUTDOWN
{
/// <summary>
/// If this process takes longer than the specified timeout to shut down, do not display a retry dialog box for the user. Instead,
/// just cause the process to directly exit.
/// </summary>
SHUTDOWN_NORETRY = 1
}
2018-10-26 14:24:07 -04:00
/// <summary>Flags used in the <see cref="STARTUPINFO.dwFlags"/> field.</summary>
[PInvokeData("WinBase.h")]
[Flags]
public enum STARTF
{
/// <summary>
/// Indicates that the cursor is in feedback mode for two seconds after CreateProcess is called. The Working in Background cursor is
/// displayed (see the Pointers tab in the Mouse control panel utility). If during those two seconds the process makes the first GUI
/// call, the system gives five more seconds to the process. If during those five seconds the process shows a window, the system
/// gives five more seconds to the process to finish drawing the window.The system turns the feedback cursor off after the first call
/// to GetMessage, regardless of whether the process is drawing.
/// </summary>
STARTF_FORCEONFEEDBACK = 0x00000040,
2018-05-13 23:41:49 -04:00
/// <summary>Indicates that the feedback cursor is forced off while the process is starting. The Normal Select cursor is displayed.</summary>
STARTF_FORCEOFFFEEDBACK = 0x00000080,
2018-10-26 14:24:07 -04:00
/// <summary>
/// Indicates that any windows created by the process cannot be pinned on the taskbar.This flag must be combined with STARTF_TITLEISAPPID.
/// </summary>
STARTF_PREVENTPINNING = 0x00002000,
2018-10-26 14:24:07 -04:00
/// <summary>
/// Indicates that the process should be run in full-screen mode, rather than in windowed mode. This flag is only valid for console
/// applications running on an x86 computer.
/// </summary>
STARTF_RUNFULLSCREEN = 0x00000020,
2018-10-26 14:24:07 -04:00
/// <summary>
/// The lpTitle member contains an AppUserModelID. This identifier controls how the taskbar and Start menu present the application,
/// and enables it to be associated with the correct shortcuts and Jump Lists. Generally, applications will use the
/// SetCurrentProcessExplicitAppUserModelID and GetCurrentProcessExplicitAppUserModelID functions instead of setting this flag. For
/// more information, see Application User Model IDs.If STARTF_PREVENTPINNING is used, application windows cannot be pinned on the
/// taskbar. The use of any AppUserModelID-related window properties by the application overrides this setting for that window
/// only.This flag cannot be used with STARTF_TITLEISLINKNAME.
/// </summary>
STARTF_TITLEISAPPID = 0x00001000,
2018-05-13 23:41:49 -04:00
/// <summary>
/// The lpTitle member contains the path of the shortcut file (.lnk) that the user invoked to start this process. This is typically
/// set by the shell when a .lnk file pointing to the launched application is invoked. Most applications will not need to set this
/// value.This flag cannot be used with STARTF_TITLEISAPPID.
/// </summary>
STARTF_TITLEISLINKNAME = 0x00000800,
2018-10-26 14:24:07 -04:00
/// <summary>The command line came from an untrusted source. For more information, see Remarks.</summary>
STARTF_UNTRUSTEDSOURCE = 0x00008000,
2018-10-26 14:24:07 -04:00
/// <summary>The dwXCountChars and dwYCountChars members contain additional information.</summary>
STARTF_USECOUNTCHARS = 0x00000008,
2018-10-26 14:24:07 -04:00
/// <summary>The dwFillAttribute member contains additional information.</summary>
STARTF_USEFILLATTRIBUTE = 0x00000010,
2018-05-13 23:41:49 -04:00
/// <summary>The hStdInput member contains additional information. This flag cannot be used with STARTF_USESTDHANDLES.</summary>
STARTF_USEHOTKEY = 0x00000200,
2018-10-26 14:24:07 -04:00
/// <summary>The dwX and dwY members contain additional information.</summary>
STARTF_USEPOSITION = 0x00000004,
2018-10-26 14:24:07 -04:00
/// <summary>The wShowWindow member contains additional information.</summary>
STARTF_USESHOWWINDOW = 0x00000001,
2018-10-26 14:24:07 -04:00
/// <summary>The dwXSize and dwYSize members contain additional information.</summary>
STARTF_USESIZE = 0x00000002,
2018-10-26 14:24:07 -04:00
/// <summary>
/// The hStdInput, hStdOutput, and hStdError members contain additional information. If this flag is specified when calling one of
/// the process creation functions, the handles must be inheritable and the function's bInheritHandles parameter must be set to TRUE.
/// For more information, see Handle Inheritance.If this flag is specified when calling the GetStartupInfo function, these members
/// are either the handle value specified during process creation or INVALID_HANDLE_VALUE.Handles must be closed with CloseHandle
/// when they are no longer needed.This flag cannot be used with STARTF_USEHOTKEY.
/// </summary>
STARTF_USESTDHANDLES = 0x00000100,
}
2018-10-26 14:24:07 -04:00
/// <summary>Used by the <see cref="SYSTEM_CPU_SET_INFORMATION"/> structure.</summary>
[Flags]
public enum SYSTEM_CPU_SET_FLAGS : byte
{
/// <summary>
/// If set, the home processor of this CPU Set is parked. If the CPU Set is on a parked processor, threads assigned to that set may
/// be reassigned to other processors that are selected by the Process Default sets or the Thread Selected sets. If all such
/// processors are parked, the threads are reassigned to other available processors on the system.
/// </summary>
SYSTEM_CPU_SET_INFORMATION_PARKED = 0x1,
2018-10-26 14:24:07 -04:00
/// <summary>
/// If set, the specified CPU Set is not available for general system use, but instead is allocated for exclusive use of some
/// processes. If a non-NULL Process argument is specified in a call to GetSystemCpuSetInformation, it is possible to determine if
/// the processor is allocated for use with that process.
/// </summary>
SYSTEM_CPU_SET_INFORMATION_ALLOCATED = 0x2,
2018-10-26 14:24:07 -04:00
/// <summary>
/// This is set if the CPU Set is allocated for the exclusive use of some subset of the system processes and if it is allocated for
/// the use of the process passed into GetSystemCpuSetInformation.
/// </summary>
SYSTEM_CPU_SET_INFORMATION_ALLOCATED_TO_TARGET_PROCESS = 0x4,
/// <summary>
/// This is set of the CPU Set is on a processor that is suitable for low-latency realtime processing. The system takes steps to
/// ensure that RealTime CPU Sets are unlikely to be running non-preemptible code, by moving other work like Interrupts and other
/// application threads off of those processors.
/// </summary>
SYSTEM_CPU_SET_INFORMATION_REALTIME = 0x8,
}
2018-10-26 14:24:07 -04:00
/// <summary></summary>
public enum THREAD_INFORMATION_CLASS
{
/// <summary>The thread memory priority</summary>
[CorrespondingType(typeof(MEMORY_PRIORITY_INFORMATION), CorrespondingAction.GetSet)]
ThreadMemoryPriority,
2018-10-26 14:24:07 -04:00
/// <summary>The thread absolute cpu priority</summary>
ThreadAbsoluteCpuPriority,
/// <summary>The thread dynamic code policy</summary>
ThreadDynamicCodePolicy,
/// <summary>The thread power throttling</summary>
[CorrespondingType(typeof(THREAD_POWER_THROTTLING_STATE), CorrespondingAction.Set)] // TODO: Figure out why Get doesn't work
ThreadPowerThrottling,
}
/// <summary>The thread's priority level.</summary>
public enum THREAD_PRIORITY
{
/// <summary>Priority 2 points below the priority class.</summary>
THREAD_PRIORITY_LOWEST = -2,
/// <summary>Priority 1 point below the priority class.</summary>
THREAD_PRIORITY_BELOW_NORMAL = THREAD_PRIORITY_LOWEST + 1,
/// <summary>Normal priority for the priority class.</summary>
THREAD_PRIORITY_NORMAL = 0,
/// <summary>Priority 2 points above the priority class.</summary>
THREAD_PRIORITY_HIGHEST = 2,
/// <summary>Priority 1 point above the priority class.</summary>
THREAD_PRIORITY_ABOVE_NORMAL = THREAD_PRIORITY_HIGHEST - 1,
/// <summary>The thread priority error return</summary>
THREAD_PRIORITY_ERROR_RETURN = 0x7fffffff,
2018-05-13 23:41:49 -04:00
2020-03-01 20:59:39 -05:00
/// <summary>
/// Base-priority level of 15 for IDLE_PRIORITY_CLASS, BELOW_NORMAL_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS,
/// ABOVE_NORMAL_PRIORITY_CLASS, or HIGH_PRIORITY_CLASS processes, and a base-priority level of 31 for REALTIME_PRIORITY_CLASS processes.
/// </summary>
THREAD_PRIORITY_TIME_CRITICAL = 15,
/// <summary>
/// Base priority of 1 for IDLE_PRIORITY_CLASS, BELOW_NORMAL_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS, ABOVE_NORMAL_PRIORITY_CLASS, or
/// HIGH_PRIORITY_CLASS processes, and a base priority of 16 for REALTIME_PRIORITY_CLASS processes.
/// </summary>
THREAD_PRIORITY_IDLE = -15,
/// <summary>The thread mode background begin</summary>
THREAD_MODE_BACKGROUND_BEGIN = 0x00010000,
/// <summary>The thread mode background end</summary>
THREAD_MODE_BACKGROUND_END = 0x00020000,
}
/// <summary>
/// <para>
/// Microsoft Windows enables you to control access to thread objects. For more information about security, see Access-Control Model.
/// </para>
/// <para>
/// You can specify a security descriptor for a thread when you call the <c>CreateProcess</c>, <c>CreateProcessAsUser</c>,
/// <c>CreateProcessWithLogonW</c>, <c>CreateThread</c>, or <c>CreateRemoteThread</c> function. If you specify <c>NULL</c>, the thread
/// gets a default security descriptor. The ACLs in the default security descriptor for a thread come from the primary or impersonation
/// token of the creator.
/// </para>
/// <para>
/// To retrieve a thread's security descriptor, call the <c>GetSecurityInfo</c> function. To change a thread's security descriptor, call
/// the <c>SetSecurityInfo</c> function.
/// </para>
/// <para>
/// The handle returned by the <c>CreateThread</c> function has <c>THREAD_ALL_ACCESS</c> access to the thread object. When you call the
/// <c>GetCurrentThread</c> function, the system returns a pseudohandle with the maximum access that the thread's security descriptor
/// allows the caller.
/// </para>
/// <para>
/// The valid access rights for thread objects include the standard access rights and some thread-specific access rights. The following
/// table lists the standard access rights used by all objects.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>DELETE (0x00010000L)</term>
/// <term>Required to delete the object.</term>
/// </item>
/// <item>
/// <term>READ_CONTROL (0x00020000L)</term>
/// <term>
/// Required to read information in the security descriptor for the object, not including the information in the SACL. To read or write
/// the SACL, you must request the ACCESS_SYSTEM_SECURITY access right. For more information, see SACL Access Right.
/// </term>
/// </item>
/// <item>
/// <term>SYNCHRONIZE (0x00100000L)</term>
/// <term>The right to use the object for synchronization. This enables a thread to wait until the object is in the signaled state.</term>
/// </item>
/// <item>
/// <term>WRITE_DAC (0x00040000L)</term>
/// <term>Required to modify the DACL in the security descriptor for the object.</term>
/// </item>
/// <item>
/// <term>WRITE_OWNER (0x00080000L)</term>
/// <term>Required to change the owner in the security descriptor for the object.</term>
/// </item>
/// </list>
/// <para>The following table lists the thread-specific access rights.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>SYNCHRONIZE (0x00100000L)</term>
/// <term>Enables the use of the thread handle in any of the wait functions.</term>
/// </item>
/// <item>
/// <term>THREAD_ALL_ACCESS</term>
/// <term>
/// All possible access rights for a thread object.Windows Server 2003 and Windows XP: The value of the THREAD_ALL_ACCESS flag increased
/// on Windows Server 2008 and Windows Vista. If an application compiled for Windows Server 2008 and Windows Vista is run on Windows
/// Server 2003 or Windows XP, the THREAD_ALL_ACCESS flag contains access bits that are not supported and the function specifying this
/// flag fails with ERROR_ACCESS_DENIED. To avoid this problem, specify the minimum set of access rights required for the operation. If
/// THREAD_ALL_ACCESS must be used, set _WIN32_WINNT to the minimum operating system targeted by your application (for example, ). For
/// more information, see Using the Windows Headers.
/// </term>
/// </item>
/// <item>
/// <term>THREAD_DIRECT_IMPERSONATION (0x0200)</term>
/// <term>Required for a server thread that impersonates a client.</term>
/// </item>
/// <item>
/// <term>THREAD_GET_CONTEXT (0x0008)</term>
/// <term>Required to read the context of a thread using GetThreadContext.</term>
/// </item>
/// <item>
/// <term>THREAD_IMPERSONATE (0x0100)</term>
/// <term>
/// Required to use a thread's security information directly without calling it by using a communication mechanism that provides
/// impersonation services.
/// </term>
/// </item>
/// <item>
/// <term>THREAD_QUERY_INFORMATION (0x0040)</term>
/// <term>Required to read certain information from the thread object, such as the exit code (see GetExitCodeThread).</term>
/// </item>
/// <item>
/// <term>THREAD_QUERY_LIMITED_INFORMATION (0x0800)</term>
/// <term>
/// Required to read certain information from the thread objects (see GetProcessIdOfThread). A handle that has the
/// THREAD_QUERY_INFORMATION access right is automatically granted THREAD_QUERY_LIMITED_INFORMATION.Windows Server 2003 and Windows XP:
/// This access right is not supported.
/// </term>
/// </item>
/// <item>
/// <term>THREAD_SET_CONTEXT (0x0010)</term>
/// <term>Required to write the context of a thread using SetThreadContext.</term>
/// </item>
/// <item>
/// <term>THREAD_SET_INFORMATION (0x0020)</term>
/// <term>Required to set certain information in the thread object.</term>
/// </item>
/// <item>
/// <term>THREAD_SET_LIMITED_INFORMATION (0x0400)</term>
/// <term>
/// Required to set certain information in the thread object. A handle that has the THREAD_SET_INFORMATION access right is automatically
/// granted THREAD_SET_LIMITED_INFORMATION.Windows Server 2003 and Windows XP: This access right is not supported.
/// </term>
/// </item>
/// <item>
/// <term>THREAD_SET_THREAD_TOKEN (0x0080)</term>
/// <term>Required to set the impersonation token for a thread using SetThreadToken.</term>
/// </item>
/// <item>
/// <term>THREAD_SUSPEND_RESUME (0x0002)</term>
/// <term>Required to suspend or resume a thread (see SuspendThread and ResumeThread).</term>
/// </item>
/// <item>
/// <term>THREAD_TERMINATE (0x0001)</term>
/// <term>Required to terminate a thread using TerminateThread.</term>
/// </item>
/// </list>
/// <para>
/// You can request the <c>ACCESS_SYSTEM_SECURITY</c> access right to a thread object if you want to read or write the object's SACL. For
/// more information, see Access-Control Lists (ACLs) and SACL Access Right.
/// </para>
/// </summary>
// https://docs.microsoft.com/en-us/windows/win32/procthread/thread-security-and-access-rights
[PInvokeData("", MSDNShortId = "72709446-5c59-4fac-8dc8-7912906ecc85")]
[Flags]
public enum ThreadAccess : uint
{
/// <term>Required to terminate a thread using TerminateThread.</term>
THREAD_TERMINATE = 0x0001,
/// <term>Required to suspend or resume a thread (see SuspendThread and ResumeThread).</term>
THREAD_SUSPEND_RESUME = 0x0002,
2020-03-01 20:59:39 -05:00
/// <term>Required to read the context of a thread using GetThreadContext.</term>
THREAD_GET_CONTEXT = 0x0008,
2020-03-01 20:59:39 -05:00
/// <term>Required to write the context of a thread using SetThreadContext.</term>
THREAD_SET_CONTEXT = 0x0010,
/// <term>Required to read certain information from the thread object, such as the exit code (see GetExitCodeThread).</term>
THREAD_QUERY_INFORMATION = 0x0040,
2020-03-01 20:59:39 -05:00
/// <term>Required to set certain information in the thread object.</term>
THREAD_SET_INFORMATION = 0x0020,
2020-03-01 20:59:39 -05:00
/// <term>Required to set the impersonation token for a thread using SetThreadToken.</term>
THREAD_SET_THREAD_TOKEN = 0x0080,
2018-10-26 14:24:07 -04:00
/// <term>
/// Required to use a thread's security information directly without calling it by using a communication mechanism that provides
/// impersonation services.
/// </term>
THREAD_IMPERSONATE = 0x0100,
/// <term>Required for a server thread that impersonates a client.</term>
THREAD_DIRECT_IMPERSONATION = 0x0200,
/// <term>
/// Required to set certain information in the thread object. A handle that has the THREAD_SET_INFORMATION access right is
/// automatically granted THREAD_SET_LIMITED_INFORMATION.Windows Server 2003 and Windows XP: This access right is not supported.
/// </term>
THREAD_SET_LIMITED_INFORMATION = 0x0400,
/// <term>
/// Required to read certain information from the thread objects (see GetProcessIdOfThread). A handle that has the
/// THREAD_QUERY_INFORMATION access right is automatically granted THREAD_QUERY_LIMITED_INFORMATION.Windows Server 2003 and Windows
/// XP: This access right is not supported.
/// </term>
THREAD_QUERY_LIMITED_INFORMATION = 0x0800,
/// <term>Required to resume a thread (see ResumeThread).</term>
THREAD_RESUME = 0x1000,
/// <term>
/// All possible access rights for a thread object.Windows Server 2003 and Windows XP: The value of the THREAD_ALL_ACCESS flag
/// increased on Windows Server 2008 and Windows Vista. If an application compiled for Windows Server 2008 and Windows Vista is run
/// on Windows Server 2003 or Windows XP, the THREAD_ALL_ACCESS flag contains access bits that are not supported and the function
/// specifying this flag fails with ERROR_ACCESS_DENIED. To avoid this problem, specify the minimum set of access rights required for
/// the operation. If THREAD_ALL_ACCESS must be used, set _WIN32_WINNT to the minimum operating system targeted by your application
/// (for example, ). For more information, see Using the Windows Headers.
/// </term>
THREAD_ALL_ACCESS = ACCESS_MASK.STANDARD_RIGHTS_REQUIRED | ACCESS_MASK.SYNCHRONIZE | 0xFFFF
}
/// <summary>
/// <para>Creates a new process and its primary thread. The new process runs in the security context of the calling process.</para>
/// <para>
/// If the calling process is impersonating another user, the new process uses the token for the calling process, not the impersonation
/// token. To run the new process in the security context of the user represented by the impersonation token, use the
/// <c>CreateProcessAsUser</c> or <c>CreateProcessWithLogonW</c> function.
/// </para>
/// </summary>
/// <param name="lpApplicationName">
/// <para>
/// The name of the module to be executed. This module can be a Windows-based application. It can be some other type of module (for
/// example, MS-DOS or OS/2) if the appropriate subsystem is available on the local computer.
/// </para>
/// <para>
/// The string can specify the full path and file name of the module to execute or it can specify a partial name. In the case of a
/// partial name, the function uses the current drive and current directory to complete the specification. The function will not use the
/// search path. This parameter must include the file name extension; no default extension is assumed.
/// </para>
/// <para>
/// The lpApplicationName parameter can be <c>NULL</c>. In that case, the module name must be the first white spacedelimited token in
/// the lpCommandLine string. If you are using a long file name that contains a space, use quoted strings to indicate where the file name
/// ends and the arguments begin; otherwise, the file name is ambiguous. For example, consider the string "c:\program files\sub
/// dir\program name". This string can be interpreted in a number of ways. The system tries to interpret the possibilities in the
/// following order:
/// </para>
/// <para>
/// If the executable module is a 16-bit application, lpApplicationName should be <c>NULL</c>, and the string pointed to by lpCommandLine
/// should specify the executable module as well as its arguments.
/// </para>
/// <para>
/// To run a batch file, you must start the command interpreter; set lpApplicationName to cmd.exe and set lpCommandLine to the following
/// arguments: /c plus the name of the batch file.
/// </para>
/// </param>
/// <param name="lpCommandLine">
/// <para>
/// The command line to be executed. The maximum length of this string is 32,768 characters, including the Unicode terminating null
/// character. If lpApplicationName is <c>NULL</c>, the module name portion of lpCommandLine is limited to <c>MAX_PATH</c> characters.
/// </para>
/// <para>
/// The Unicode version of this function, <c>CreateProcessW</c>, can modify the contents of this string. Therefore, this parameter cannot
/// be a pointer to read-only memory (such as a <c>const</c> variable or a literal string). If this parameter is a constant string, the
/// function may cause an access violation.
/// </para>
/// <para>
/// The lpCommandLine parameter can be NULL. In that case, the function uses the string pointed to by lpApplicationName as the command line.
/// </para>
/// <para>
/// If both lpApplicationName and lpCommandLine are non- <c>NULL</c>, the null-terminated string pointed to by lpApplicationName
/// specifies the module to execute, and the null-terminated string pointed to by lpCommandLine specifies the command line. The new
/// process can use <c>GetCommandLine</c> to retrieve the entire command line. Console processes written in C can use the argc and argv
/// arguments to parse the command line. Because argv[0] is the module name, C programmers generally repeat the module name as the first
/// token in the command line.
/// </para>
/// <para>
/// If lpApplicationName is NULL, the first white spacedelimited token of the command line specifies the module name. If you are using a
/// long file name that contains a space, use quoted strings to indicate where the file name ends and the arguments begin (see the
/// explanation for the lpApplicationName parameter). If the file name does not contain an extension, .exe is appended. Therefore, if the
/// file name extension is .com, this parameter must include the .com extension. If the file name ends in a period (.) with no extension,
/// or if the file name contains a path, .exe is not appended. If the file name does not contain a directory path, the system searches
/// for the executable file in the following sequence:
/// </para>
/// <para>
/// The system adds a terminating null character to the command-line string to separate the file name from the arguments. This divides
/// the original string into two strings for internal processing.
/// </para>
/// </param>
/// <param name="lpProcessAttributes">
/// <para>
/// A pointer to a <c>SECURITY_ATTRIBUTES</c> structure that determines whether the returned handle to the new process object can be
/// inherited by child processes. If lpProcessAttributes is <c>NULL</c>, the handle cannot be inherited.
/// </para>
/// <para>
/// The <c>lpSecurityDescriptor</c> member of the structure specifies a security descriptor for the new process. If lpProcessAttributes
/// is NULL or <c>lpSecurityDescriptor</c> is <c>NULL</c>, the process gets a default security descriptor. The ACLs in the default
/// security descriptor for a process come from the primary token of the creator.
/// </para>
/// <para>
/// <c>Windows XP:</c> The ACLs in the default security descriptor for a process come from the primary or impersonation token of the
/// creator. This behavior changed with Windows XP with SP2 and Windows Server 2003.
/// </para>
/// </param>
/// <param name="lpThreadAttributes">
/// <para>
/// A pointer to a <c>SECURITY_ATTRIBUTES</c> structure that determines whether the returned handle to the new thread object can be
/// inherited by child processes. If lpThreadAttributes is NULL, the handle cannot be inherited.
/// </para>
/// <para>
/// The <c>lpSecurityDescriptor</c> member of the structure specifies a security descriptor for the main thread. If lpThreadAttributes is
/// NULL or <c>lpSecurityDescriptor</c> is NULL, the thread gets a default security descriptor. The ACLs in the default security
/// descriptor for a thread come from the process token.
/// </para>
/// <para>
/// <c>Windows XP:</c> The ACLs in the default security descriptor for a thread come from the primary or impersonation token of the
/// creator. This behavior changed with Windows XP with SP2 and Windows Server 2003.
/// </para>
/// </param>
/// <param name="bInheritHandles">
/// <para>
/// If this parameter is TRUE, each inheritable handle in the calling process is inherited by the new process. If the parameter is FALSE,
/// the handles are not inherited. Note that inherited handles have the same value and access rights as the original handles.
/// </para>
/// <para>
/// <c>Terminal Services:</c> You cannot inherit handles across sessions. Additionally, if this parameter is TRUE, you must create the
/// process in the same session as the caller.
/// </para>
/// <para>
/// <c>Protected Process Light (PPL) processes:</c> The generic handle inheritance is blocked when a PPL process creates a non-PPL
/// process since PROCESS_DUP_HANDLE is not allowed from a non-PPL process to a PPL process. See Process Security and Access Rights
/// </para>
/// </param>
/// <param name="dwCreationFlags">
/// <para>The flags that control the priority class and the creation of the process. For a list of values, see Process Creation Flags.</para>
/// <para>
/// This parameter also controls the new process's priority class, which is used to determine the scheduling priorities of the process's
/// threads. For a list of values, see <c>GetPriorityClass</c>. If none of the priority class flags is specified, the priority class
/// defaults to <c>NORMAL_PRIORITY_CLASS</c> unless the priority class of the creating process is <c>IDLE_PRIORITY_CLASS</c> or
/// <c>BELOW_NORMAL_PRIORITY_CLASS</c>. In this case, the child process receives the default priority class of the calling process.
/// </para>
/// </param>
/// <param name="lpEnvironment">
/// <para>
/// An array of the environment items for the new process. If this parameter is <c>NULL</c>, the new process uses the environment of the
/// calling process.
/// </para>
/// <para>An environment item is in the following form:</para>
/// <para>name=value\0</para>
/// <para>Because the equal sign is used as a separator, it must not be used in the name of an environment variable.</para>
/// <para>
/// An environment block can contain either Unicode or ANSI characters. If the environment block pointed to by lpEnvironment contains
/// Unicode characters, be sure that dwCreationFlags includes <c>CREATE_UNICODE_ENVIRONMENT</c>. If this parameter is <c>NULL</c> and the
/// environment block of the parent process contains Unicode characters, you must also ensure that dwCreationFlags includes <c>CREATE_UNICODE_ENVIRONMENT</c>.
/// </para>
/// <para>
/// The ANSI version of this function, <c>CreateProcessA</c> fails if the total size of the environment block for the process exceeds
/// 32,767 characters.
/// </para>
/// </param>
/// <param name="lpCurrentDirectory">
/// <para>The full path to the current directory for the process. The string can also specify a UNC path.</para>
/// <para>
/// If this parameter is <c>NULL</c>, the new process will have the same current drive and directory as the calling process. (This
/// feature is provided primarily for shells that need to start an application and specify its initial drive and working directory.)
/// </para>
/// </param>
/// <param name="lpStartupInfo">
/// <para>A pointer to a <c>STARTUPINFO</c> or <c>STARTUPINFOEX</c> structure.</para>
/// <para>
/// To set extended attributes, use a <c>STARTUPINFOEX</c> structure and specify EXTENDED_STARTUPINFO_PRESENT in the dwCreationFlags parameter.
/// </para>
/// <para>Handles in <c>STARTUPINFO</c> or <c>STARTUPINFOEX</c> must be closed with <c>CloseHandle</c> when they are no longer needed.</para>
/// </param>
/// <param name="lpProcessInformation">
/// <para>A pointer to a <c>PROCESS_INFORMATION</c> structure that receives identification information about the new process.</para>
/// <para>Handles in <c>PROCESS_INFORMATION</c> must be closed with <c>CloseHandle</c> when they are no longer needed.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// <para>
/// Note that the function returns before the process has finished initialization. If a required DLL cannot be located or fails to
/// initialize, the process is terminated. To get the termination status of a process, call <c>GetExitCodeProcess</c>.
/// </para>
/// </returns>
// BOOL WINAPI CreateProcess( _In_opt_ LPCTSTR lpApplicationName, _Inout_opt_ LPTSTR lpCommandLine, _In_opt_ LPSECURITY_ATTRIBUTES
// lpProcessAttributes, _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ BOOL bInheritHandles, _In_ DWORD dwCreationFlags,
// _In_opt_ LPVOID lpEnvironment, _In_opt_ LPCTSTR lpCurrentDirectory, _In_ LPSTARTUPINFO lpStartupInfo, _Out_ LPPROCESS_INFORMATION
// lpProcessInformation); https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx
[PInvokeData("WinBase.h", MSDNShortId = "ms682425")]
public static bool CreateProcess([Optional] string lpApplicationName, [Optional] StringBuilder lpCommandLine, [In, Optional] SECURITY_ATTRIBUTES lpProcessAttributes,
[In, Optional] SECURITY_ATTRIBUTES lpThreadAttributes, [Optional] bool bInheritHandles, [Optional] CREATE_PROCESS dwCreationFlags, [In, Optional] string[] lpEnvironment,
[Optional] string lpCurrentDirectory, in STARTUPINFO lpStartupInfo, out SafePROCESS_INFORMATION lpProcessInformation)
{
if (lpEnvironment != null && StringHelper.GetCharSize() == 2)
dwCreationFlags |= CREATE_PROCESS.CREATE_UNICODE_ENVIRONMENT;
bool ret = CreateProcess(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
lpCurrentDirectory, lpStartupInfo, out PROCESS_INFORMATION pi);
lpProcessInformation = ret ? new SafePROCESS_INFORMATION(pi) : null;
return ret;
}
/// <summary>
/// <para>Creates a new process and its primary thread. The new process runs in the security context of the calling process.</para>
/// <para>
/// If the calling process is impersonating another user, the new process uses the token for the calling process, not the impersonation
/// token. To run the new process in the security context of the user represented by the impersonation token, use the
/// <c>CreateProcessAsUser</c> or <c>CreateProcessWithLogonW</c> function.
/// </para>
/// </summary>
/// <param name="lpCommandLine">
/// <para>
/// The command line to be executed. The maximum length of this string is 32,768 characters, including the Unicode terminating null
/// character. The module name portion of lpCommandLine is limited to <c>MAX_PATH</c> characters.
/// </para>
/// <para>
/// The first white spacedelimited token of the command line specifies the module name. If you are using a long file name that contains
/// a space, use quoted strings to indicate where the file name ends and the arguments begin (see the explanation for the
/// lpApplicationName parameter). If the file name does not contain an extension, .exe is appended. Therefore, if the file name extension
/// is .com, this parameter must include the .com extension. If the file name ends in a period (.) with no extension, or if the file name
/// contains a path, .exe is not appended. If the file name does not contain a directory path, the system searches for the executable
/// file in the following sequence:
/// </para>
/// </param>
/// <returns>A handle to the created process.</returns>
[PInvokeData("WinBase.h", MSDNShortId = "ms682425")]
public static SafeHPROCESS CreateProcess(string lpCommandLine)
{
if (CreateProcess(null, new StringBuilder(lpCommandLine ?? throw new ArgumentNullException(nameof(lpCommandLine))), null, null, false, 0, null, null, STARTUPINFO.Default, out PROCESS_INFORMATION pi))
2018-10-26 14:24:07 -04:00
{
CloseHandle((IntPtr)pi.hThread);
return new SafeHPROCESS(pi.hProcess);
}
return SafeHPROCESS.Null;
}
/// <summary>
/// <para>Creates a new process and its primary thread. The new process runs in the security context of the calling process.</para>
/// <para>
/// If the calling process is impersonating another user, the new process uses the token for the calling process, not the impersonation
/// token. To run the new process in the security context of the user represented by the impersonation token, use the
/// <c>CreateProcessAsUser</c> or <c>CreateProcessWithLogonW</c> function.
/// </para>
/// </summary>
/// <param name="lpApplicationName">
/// <para>
/// The name of the module to be executed. This module can be a Windows-based application. It can be some other type of module (for
/// example, MS-DOS or OS/2) if the appropriate subsystem is available on the local computer.
/// </para>
/// <para>
/// The string can specify the full path and file name of the module to execute or it can specify a partial name. In the case of a
/// partial name, the function uses the current drive and current directory to complete the specification. The function will not use the
/// search path. This parameter must include the file name extension; no default extension is assumed.
/// </para>
/// <para>
/// The lpApplicationName parameter can be <c>NULL</c>. In that case, the module name must be the first white spacedelimited token in
/// the lpCommandLine string. If you are using a long file name that contains a space, use quoted strings to indicate where the file name
/// ends and the arguments begin; otherwise, the file name is ambiguous. For example, consider the string "c:\program files\sub
/// dir\program name". This string can be interpreted in a number of ways. The system tries to interpret the possibilities in the
/// following order:
/// </para>
/// <para>
/// If the executable module is a 16-bit application, lpApplicationName should be <c>NULL</c>, and the string pointed to by lpCommandLine
/// should specify the executable module as well as its arguments.
/// </para>
/// <para>
/// To run a batch file, you must start the command interpreter; set lpApplicationName to cmd.exe and set lpCommandLine to the following
/// arguments: /c plus the name of the batch file.
/// </para>
/// </param>
/// <param name="lpCommandLine">
/// <para>
/// The command line to be executed. The maximum length of this string is 32,768 characters, including the Unicode terminating null
/// character. If lpApplicationName is <c>NULL</c>, the module name portion of lpCommandLine is limited to <c>MAX_PATH</c> characters.
/// </para>
/// <para>
/// The Unicode version of this function, <c>CreateProcessW</c>, can modify the contents of this string. Therefore, this parameter cannot
/// be a pointer to read-only memory (such as a <c>const</c> variable or a literal string). If this parameter is a constant string, the
/// function may cause an access violation.
/// </para>
/// <para>
/// The lpCommandLine parameter can be NULL. In that case, the function uses the string pointed to by lpApplicationName as the command line.
/// </para>
/// <para>
/// If both lpApplicationName and lpCommandLine are non- <c>NULL</c>, the null-terminated string pointed to by lpApplicationName
/// specifies the module to execute, and the null-terminated string pointed to by lpCommandLine specifies the command line. The new
/// process can use <c>GetCommandLine</c> to retrieve the entire command line. Console processes written in C can use the argc and argv
/// arguments to parse the command line. Because argv[0] is the module name, C programmers generally repeat the module name as the first
/// token in the command line.
/// </para>
/// <para>
/// If lpApplicationName is NULL, the first white spacedelimited token of the command line specifies the module name. If you are using a
/// long file name that contains a space, use quoted strings to indicate where the file name ends and the arguments begin (see the
/// explanation for the lpApplicationName parameter). If the file name does not contain an extension, .exe is appended. Therefore, if the
/// file name extension is .com, this parameter must include the .com extension. If the file name ends in a period (.) with no extension,
/// or if the file name contains a path, .exe is not appended. If the file name does not contain a directory path, the system searches
/// for the executable file in the following sequence:
/// </para>
/// <para>
/// The system adds a terminating null character to the command-line string to separate the file name from the arguments. This divides
/// the original string into two strings for internal processing.
/// </para>
/// </param>
/// <param name="lpProcessAttributes">
/// <para>
/// A pointer to a <c>SECURITY_ATTRIBUTES</c> structure that determines whether the returned handle to the new process object can be
/// inherited by child processes. If lpProcessAttributes is <c>NULL</c>, the handle cannot be inherited.
/// </para>
/// <para>
/// The <c>lpSecurityDescriptor</c> member of the structure specifies a security descriptor for the new process. If lpProcessAttributes
/// is NULL or <c>lpSecurityDescriptor</c> is <c>NULL</c>, the process gets a default security descriptor. The ACLs in the default
/// security descriptor for a process come from the primary token of the creator.
/// </para>
/// <para>
/// <c>Windows XP:</c> The ACLs in the default security descriptor for a process come from the primary or impersonation token of the
/// creator. This behavior changed with Windows XP with SP2 and Windows Server 2003.
/// </para>
/// </param>
/// <param name="lpThreadAttributes">
/// <para>
/// A pointer to a <c>SECURITY_ATTRIBUTES</c> structure that determines whether the returned handle to the new thread object can be
/// inherited by child processes. If lpThreadAttributes is NULL, the handle cannot be inherited.
/// </para>
/// <para>
/// The <c>lpSecurityDescriptor</c> member of the structure specifies a security descriptor for the main thread. If lpThreadAttributes is
/// NULL or <c>lpSecurityDescriptor</c> is NULL, the thread gets a default security descriptor. The ACLs in the default security
/// descriptor for a thread come from the process token.
/// </para>
/// <para>
/// <c>Windows XP:</c> The ACLs in the default security descriptor for a thread come from the primary or impersonation token of the
/// creator. This behavior changed with Windows XP with SP2 and Windows Server 2003.
/// </para>
/// </param>
/// <param name="bInheritHandles">
/// <para>
/// If this parameter is TRUE, each inheritable handle in the calling process is inherited by the new process. If the parameter is FALSE,
/// the handles are not inherited. Note that inherited handles have the same value and access rights as the original handles.
/// </para>
/// <para>
/// <c>Terminal Services:</c> You cannot inherit handles across sessions. Additionally, if this parameter is TRUE, you must create the
/// process in the same session as the caller.
/// </para>
/// <para>
/// <c>Protected Process Light (PPL) processes:</c> The generic handle inheritance is blocked when a PPL process creates a non-PPL
/// process since PROCESS_DUP_HANDLE is not allowed from a non-PPL process to a PPL process. See Process Security and Access Rights
/// </para>
/// </param>
/// <param name="dwCreationFlags">
/// <para>The flags that control the priority class and the creation of the process. For a list of values, see Process Creation Flags.</para>
/// <para>
/// This parameter also controls the new process's priority class, which is used to determine the scheduling priorities of the process's
/// threads. For a list of values, see <c>GetPriorityClass</c>. If none of the priority class flags is specified, the priority class
/// defaults to <c>NORMAL_PRIORITY_CLASS</c> unless the priority class of the creating process is <c>IDLE_PRIORITY_CLASS</c> or
/// <c>BELOW_NORMAL_PRIORITY_CLASS</c>. In this case, the child process receives the default priority class of the calling process.
/// </para>
/// </param>
/// <param name="lpEnvironment">
/// <para>
/// An array of the environment items for the new process. If this parameter is <c>NULL</c>, the new process uses the environment of the
/// calling process.
/// </para>
/// <para>An environment item is in the following form:</para>
/// <para>name=value\0</para>
/// <para>Because the equal sign is used as a separator, it must not be used in the name of an environment variable.</para>
/// <para>
/// An environment block can contain either Unicode or ANSI characters. If the environment block pointed to by lpEnvironment contains
/// Unicode characters, be sure that dwCreationFlags includes <c>CREATE_UNICODE_ENVIRONMENT</c>. If this parameter is <c>NULL</c> and the
/// environment block of the parent process contains Unicode characters, you must also ensure that dwCreationFlags includes <c>CREATE_UNICODE_ENVIRONMENT</c>.
/// </para>
/// <para>
/// The ANSI version of this function, <c>CreateProcessA</c> fails if the total size of the environment block for the process exceeds
/// 32,767 characters.
/// </para>
/// </param>
/// <param name="lpCurrentDirectory">
/// <para>The full path to the current directory for the process. The string can also specify a UNC path.</para>
/// <para>
/// If this parameter is <c>NULL</c>, the new process will have the same current drive and directory as the calling process. (This
/// feature is provided primarily for shells that need to start an application and specify its initial drive and working directory.)
/// </para>
/// </param>
/// <param name="lpStartupInfo">
/// <para>A pointer to a <c>STARTUPINFO</c> or <c>STARTUPINFOEX</c> structure.</para>
/// <para>
/// To set extended attributes, use a <c>STARTUPINFOEX</c> structure and specify EXTENDED_STARTUPINFO_PRESENT in the dwCreationFlags parameter.
/// </para>
/// <para>Handles in <c>STARTUPINFO</c> or <c>STARTUPINFOEX</c> must be closed with <c>CloseHandle</c> when they are no longer needed.</para>
/// </param>
/// <param name="lpProcessInformation">
/// <para>A pointer to a <c>PROCESS_INFORMATION</c> structure that receives identification information about the new process.</para>
/// <para>Handles in <c>PROCESS_INFORMATION</c> must be closed with <c>CloseHandle</c> when they are no longer needed.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// <para>
/// Note that the function returns before the process has finished initialization. If a required DLL cannot be located or fails to
/// initialize, the process is terminated. To get the termination status of a process, call <c>GetExitCodeProcess</c>.
/// </para>
/// </returns>
// BOOL WINAPI CreateProcess( _In_opt_ LPCTSTR lpApplicationName, _Inout_opt_ LPTSTR lpCommandLine, _In_opt_ LPSECURITY_ATTRIBUTES
// lpProcessAttributes, _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ BOOL bInheritHandles, _In_ DWORD dwCreationFlags,
// _In_opt_ LPVOID lpEnvironment, _In_opt_ LPCTSTR lpCurrentDirectory, _In_ LPSTARTUPINFO lpStartupInfo, _Out_ LPPROCESS_INFORMATION
// lpProcessInformation); https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx
[PInvokeData("WinBase.h", MSDNShortId = "ms682425")]
public static bool CreateProcess([Optional] string lpApplicationName, [Optional] StringBuilder lpCommandLine, [In, Optional] SECURITY_ATTRIBUTES lpProcessAttributes,
[In, Optional] SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandles, [Optional] CREATE_PROCESS dwCreationFlags, [In, Optional] string[] lpEnvironment,
[Optional] string lpCurrentDirectory, in STARTUPINFOEX lpStartupInfo, out SafePROCESS_INFORMATION lpProcessInformation)
{
if (lpEnvironment != null && StringHelper.GetCharSize() == 2)
dwCreationFlags |= CREATE_PROCESS.CREATE_UNICODE_ENVIRONMENT;
bool ret = CreateProcess(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment,
lpCurrentDirectory, lpStartupInfo, out PROCESS_INFORMATION pi);
lpProcessInformation = ret ? new SafePROCESS_INFORMATION(pi) : null;
return ret;
}
/// <summary>
/// <para>Creates a thread that runs in the virtual address space of another process.</para>
/// <para>
/// Use the <c>CreateRemoteThreadEx</c> function to create a thread that runs in the virtual address space of another process and
/// optionally specify extended attributes.
/// </para>
/// </summary>
/// <param name="hProcess">
/// A handle to the process in which the thread is to be created. The handle must have the <c>PROCESS_CREATE_THREAD</c>,
/// <c>PROCESS_QUERY_INFORMATION</c>, <c>PROCESS_VM_OPERATION</c>, <c>PROCESS_VM_WRITE</c>, and <c>PROCESS_VM_READ</c> access rights, and
/// may fail without these rights on certain platforms. For more information, see Process Security and Access Rights.
/// </param>
/// <param name="lpThreadAttributes">
/// <para>
/// A pointer to a <c>SECURITY_ATTRIBUTES</c> structure that specifies a security descriptor for the new thread and determines whether
/// child processes can inherit the returned handle. If lpThreadAttributes is NULL, the thread gets a default security descriptor and the
/// handle cannot be inherited. The access control lists (ACL) in the default security descriptor for a thread come from the primary
/// token of the creator.
/// </para>
/// <para>
/// <c>Windows XP:</c> The ACLs in the default security descriptor for a thread come from the primary or impersonation token of the
/// creator. This behavior changed with Windows XP with SP2 and Windows Server 2003.
/// </para>
/// </param>
/// <param name="dwStackSize">
/// The initial size of the stack, in bytes. The system rounds this value to the nearest page. If this parameter is 0 (zero), the new
/// thread uses the default size for the executable. For more information, see Thread Stack Size.
/// </param>
/// <param name="lpStartAddress">
/// A pointer to the application-defined function of type <c>LPTHREAD_START_ROUTINE</c> to be executed by the thread and represents the
/// starting address of the thread in the remote process. The function must exist in the remote process. For more information, see <c>ThreadProc</c>.
/// </param>
/// <param name="lpParameter">A pointer to a variable to be passed to the thread function.</param>
/// <param name="dwCreationFlags">
/// <para>The flags that control the creation of the thread.</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>0</term>
/// <term>The thread runs immediately after creation.</term>
/// </item>
/// <item>
/// <term>CREATE_SUSPENDED0x00000004</term>
/// <term>The thread is created in a suspended state, and does not run until the ResumeThread function is called.</term>
/// </item>
/// <item>
/// <term>STACK_SIZE_PARAM_IS_A_RESERVATION0x00010000</term>
/// <term>
/// The dwStackSize parameter specifies the initial reserve size of the stack. If this flag is not specified, dwStackSize specifies the
/// commit size.
/// </term>
/// </item>
/// </list>
/// </para>
/// </param>
/// <param name="lpThreadId">
/// <para>A pointer to a variable that receives the thread identifier.</para>
/// <para>If this parameter is <c>NULL</c>, the thread identifier is not returned.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is a handle to the new thread.</para>
/// <para>If the function fails, the return value is <c>NULL</c>. To get extended error information, call <c>GetLastError</c>.</para>
/// <para>
/// Note that <c>CreateRemoteThread</c> may succeed even if lpStartAddress points to data, code, or is not accessible. If the start
/// address is invalid when the thread runs, an exception occurs, and the thread terminates. Thread termination due to a invalid start
/// address is handled as an error exit for the thread's process. This behavior is similar to the asynchronous nature of
/// <c>CreateProcess</c>, where the process is created even if it refers to invalid or missing dynamic-link libraries (DLL).
/// </para>
/// </returns>
// HANDLE WINAPI CreateRemoteThread( _In_ HANDLE hProcess, _In_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ SIZE_T dwStackSize, _In_
// LPTHREAD_START_ROUTINE lpStartAddress, _In_ LPVOID lpParameter, _In_ DWORD dwCreationFlags, _Out_ LPDWORD lpThreadId); https://msdn.microsoft.com/en-us/library/windows/desktop/ms682437(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms682437")]
public static extern SafeHTHREAD CreateRemoteThread([In] HPROCESS hProcess, [In, Optional] SECURITY_ATTRIBUTES lpThreadAttributes, [Optional] SizeT dwStackSize,
ThreadProc lpStartAddress, [In, Optional] IntPtr lpParameter, [Optional] CREATE_THREAD_FLAGS dwCreationFlags, out uint lpThreadId);
/// <summary>
/// <para>Creates a thread that runs in the virtual address space of another process.</para>
/// <para>
/// Use the <c>CreateRemoteThreadEx</c> function to create a thread that runs in the virtual address space of another process and
/// optionally specify extended attributes.
/// </para>
/// </summary>
/// <param name="hProcess">
/// A handle to the process in which the thread is to be created. The handle must have the <c>PROCESS_CREATE_THREAD</c>,
/// <c>PROCESS_QUERY_INFORMATION</c>, <c>PROCESS_VM_OPERATION</c>, <c>PROCESS_VM_WRITE</c>, and <c>PROCESS_VM_READ</c> access rights, and
/// may fail without these rights on certain platforms. For more information, see Process Security and Access Rights.
/// </param>
/// <param name="lpThreadAttributes">
/// <para>
/// A pointer to a <c>SECURITY_ATTRIBUTES</c> structure that specifies a security descriptor for the new thread and determines whether
/// child processes can inherit the returned handle. If lpThreadAttributes is NULL, the thread gets a default security descriptor and the
/// handle cannot be inherited. The access control lists (ACL) in the default security descriptor for a thread come from the primary
/// token of the creator.
/// </para>
/// <para>
/// <c>Windows XP:</c> The ACLs in the default security descriptor for a thread come from the primary or impersonation token of the
/// creator. This behavior changed with Windows XP with SP2 and Windows Server 2003.
/// </para>
/// </param>
/// <param name="dwStackSize">
/// The initial size of the stack, in bytes. The system rounds this value to the nearest page. If this parameter is 0 (zero), the new
/// thread uses the default size for the executable. For more information, see Thread Stack Size.
/// </param>
/// <param name="lpStartAddress">
/// A pointer to the application-defined function of type <c>LPTHREAD_START_ROUTINE</c> to be executed by the thread and represents the
/// starting address of the thread in the remote process. The function must exist in the remote process. For more information, see <c>ThreadProc</c>.
/// </param>
/// <param name="lpParameter">A pointer to a variable to be passed to the thread function.</param>
/// <param name="dwCreationFlags">
/// <para>The flags that control the creation of the thread.</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>0</term>
/// <term>The thread runs immediately after creation.</term>
/// </item>
/// <item>
/// <term>CREATE_SUSPENDED0x00000004</term>
/// <term>The thread is created in a suspended state, and does not run until the ResumeThread function is called.</term>
/// </item>
/// <item>
/// <term>STACK_SIZE_PARAM_IS_A_RESERVATION0x00010000</term>
/// <term>
/// The dwStackSize parameter specifies the initial reserve size of the stack. If this flag is not specified, dwStackSize specifies the
/// commit size.
/// </term>
/// </item>
/// </list>
/// </para>
/// </param>
/// <param name="lpThreadId">
/// <para>A pointer to a variable that receives the thread identifier.</para>
/// <para>If this parameter is <c>NULL</c>, the thread identifier is not returned.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is a handle to the new thread.</para>
/// <para>If the function fails, the return value is <c>NULL</c>. To get extended error information, call <c>GetLastError</c>.</para>
/// <para>
/// Note that <c>CreateRemoteThread</c> may succeed even if lpStartAddress points to data, code, or is not accessible. If the start
/// address is invalid when the thread runs, an exception occurs, and the thread terminates. Thread termination due to a invalid start
/// address is handled as an error exit for the thread's process. This behavior is similar to the asynchronous nature of
/// <c>CreateProcess</c>, where the process is created even if it refers to invalid or missing dynamic-link libraries (DLL).
/// </para>
/// </returns>
// HANDLE WINAPI CreateRemoteThread( _In_ HANDLE hProcess, _In_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ SIZE_T dwStackSize, _In_
// LPTHREAD_START_ROUTINE lpStartAddress, _In_ LPVOID lpParameter, _In_ DWORD dwCreationFlags, _Out_ LPDWORD lpThreadId); https://msdn.microsoft.com/en-us/library/windows/desktop/ms682437(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms682437")]
public static extern SafeHTHREAD CreateRemoteThread([In] HPROCESS hProcess, [In, Optional] SECURITY_ATTRIBUTES lpThreadAttributes, [Optional] SizeT dwStackSize,
IntPtr lpStartAddress, [In, Optional] IntPtr lpParameter, [Optional] CREATE_THREAD_FLAGS dwCreationFlags, out uint lpThreadId);
/// <summary>
/// Creates a thread that runs in the virtual address space of another process and optionally specifies extended attributes such as
/// processor group affinity.
/// </summary>
/// <param name="hProcess">
/// A handle to the process in which the thread is to be created. The handle must have the PROCESS_CREATE_THREAD,
/// PROCESS_QUERY_INFORMATION, PROCESS_VM_OPERATION, PROCESS_VM_WRITE, and PROCESS_VM_READ access rights. In Windows 10, version 1607,
/// your code must obtain these access rights for the new handle. However, starting in Windows 10, version 1703, if the new handle is
/// entitled to these access rights, the system obtains them for you. For more information, see Process Security and Access Rights.
/// </param>
/// <param name="lpThreadAttributes">
/// A pointer to a <c>SECURITY_ATTRIBUTES</c> structure that specifies a security descriptor for the new thread and determines whether
/// child processes can inherit the returned handle. If lpThreadAttributes is NULL, the thread gets a default security descriptor and the
/// handle cannot be inherited. The access control lists (ACL) in the default security descriptor for a thread come from the primary
/// token of the creator.
/// </param>
/// <param name="dwStackSize">
/// The initial size of the stack, in bytes. The system rounds this value to the nearest page. If this parameter is 0 (zero), the new
/// thread uses the default size for the executable. For more information, see Thread Stack Size.
/// </param>
/// <param name="lpStartAddress">
/// A pointer to the application-defined function of type <c>LPTHREAD_START_ROUTINE</c> to be executed by the thread and represents the
/// starting address of the thread in the remote process. The function must exist in the remote process. For more information, see <c>ThreadProc</c>.
/// </param>
/// <param name="lpParameter">
/// A pointer to a variable to be passed to the thread function pointed to by lpStartAddress. This parameter can be NULL.
/// </param>
/// <param name="dwCreationFlags">
/// <para>The flags that control the creation of the thread.</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>0</term>
/// <term>The thread runs immediately after creation.</term>
/// </item>
/// <item>
/// <term>CREATE_SUSPENDED0x00000004</term>
/// <term>The thread is created in a suspended state and does not run until the ResumeThread function is called.</term>
/// </item>
/// <item>
/// <term>STACK_SIZE_PARAM_IS_A_RESERVATION0x00010000</term>
/// <term>
/// The dwStackSize parameter specifies the initial reserve size of the stack. If this flag is not specified, dwStackSize specifies the
/// commit size.
/// </term>
/// </item>
/// </list>
/// </para>
/// </param>
/// <param name="lpAttributeList">
/// An attribute list that contains additional parameters for the new thread. This list is created by the
/// <c>InitializeProcThreadAttributeList</c> function.
/// </param>
/// <param name="lpThreadId">
/// <para>A pointer to a variable that receives the thread identifier.</para>
/// <para>If this parameter is NULL, the thread identifier is not returned.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is a handle to the new thread.</para>
/// <para>If the function fails, the return value is NULL. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// HANDLE CreateRemoteThreadEx( _In_ HANDLE hProcess, _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ SIZE_T dwStackSize, _In_
// LPTHREAD_START_ROUTINE lpStartAddress, _In_opt_ LPVOID lpParameter, _In_ DWORD dwCreationFlags, _In_opt_ LPPROC_THREAD_ATTRIBUTE_LIST
// lpAttributeList, _Out_opt_ LPDWORD lpThreadId); https://msdn.microsoft.com/en-us/library/windows/desktop/dd405484(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "dd405484")]
public static extern SafeHTHREAD CreateRemoteThreadEx([In] HPROCESS hProcess, [In, Optional] SECURITY_ATTRIBUTES lpThreadAttributes, [Optional] SizeT dwStackSize,
ThreadProc lpStartAddress, [In, Optional] IntPtr lpParameter, [Optional] CREATE_THREAD_FLAGS dwCreationFlags, SafeProcThreadAttributeList lpAttributeList,
out uint lpThreadId);
/// <summary>
/// Creates a thread that runs in the virtual address space of another process and optionally specifies extended attributes such as
/// processor group affinity.
/// </summary>
/// <param name="hProcess">
/// A handle to the process in which the thread is to be created. The handle must have the PROCESS_CREATE_THREAD,
/// PROCESS_QUERY_INFORMATION, PROCESS_VM_OPERATION, PROCESS_VM_WRITE, and PROCESS_VM_READ access rights. In Windows 10, version 1607,
/// your code must obtain these access rights for the new handle. However, starting in Windows 10, version 1703, if the new handle is
/// entitled to these access rights, the system obtains them for you. For more information, see Process Security and Access Rights.
/// </param>
/// <param name="lpThreadAttributes">
/// A pointer to a <c>SECURITY_ATTRIBUTES</c> structure that specifies a security descriptor for the new thread and determines whether
/// child processes can inherit the returned handle. If lpThreadAttributes is NULL, the thread gets a default security descriptor and the
/// handle cannot be inherited. The access control lists (ACL) in the default security descriptor for a thread come from the primary
/// token of the creator.
/// </param>
/// <param name="dwStackSize">
/// The initial size of the stack, in bytes. The system rounds this value to the nearest page. If this parameter is 0 (zero), the new
/// thread uses the default size for the executable. For more information, see Thread Stack Size.
/// </param>
/// <param name="lpStartAddress">
/// A pointer to the application-defined function of type <c>LPTHREAD_START_ROUTINE</c> to be executed by the thread and represents the
/// starting address of the thread in the remote process. The function must exist in the remote process. For more information, see <c>ThreadProc</c>.
/// </param>
/// <param name="lpParameter">
/// A pointer to a variable to be passed to the thread function pointed to by lpStartAddress. This parameter can be NULL.
/// </param>
/// <param name="dwCreationFlags">
/// <para>The flags that control the creation of the thread.</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>0</term>
/// <term>The thread runs immediately after creation.</term>
/// </item>
/// <item>
/// <term>CREATE_SUSPENDED0x00000004</term>
/// <term>The thread is created in a suspended state and does not run until the ResumeThread function is called.</term>
/// </item>
/// <item>
/// <term>STACK_SIZE_PARAM_IS_A_RESERVATION0x00010000</term>
/// <term>
/// The dwStackSize parameter specifies the initial reserve size of the stack. If this flag is not specified, dwStackSize specifies the
/// commit size.
/// </term>
/// </item>
/// </list>
/// </para>
/// </param>
/// <param name="lpAttributeList">
/// An attribute list that contains additional parameters for the new thread. This list is created by the
/// <c>InitializeProcThreadAttributeList</c> function.
/// </param>
/// <param name="lpThreadId">
/// <para>A pointer to a variable that receives the thread identifier.</para>
/// <para>If this parameter is NULL, the thread identifier is not returned.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is a handle to the new thread.</para>
/// <para>If the function fails, the return value is NULL. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// HANDLE CreateRemoteThreadEx( _In_ HANDLE hProcess, _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ SIZE_T dwStackSize, _In_
// LPTHREAD_START_ROUTINE lpStartAddress, _In_opt_ LPVOID lpParameter, _In_ DWORD dwCreationFlags, _In_opt_ LPPROC_THREAD_ATTRIBUTE_LIST
// lpAttributeList, _Out_opt_ LPDWORD lpThreadId); https://msdn.microsoft.com/en-us/library/windows/desktop/dd405484(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "dd405484")]
public static extern SafeHTHREAD CreateRemoteThreadEx([In] HPROCESS hProcess, [In, Optional] SECURITY_ATTRIBUTES lpThreadAttributes, [Optional] SizeT dwStackSize,
ThreadProc lpStartAddress, [In, Optional] IntPtr lpParameter, [Optional] CREATE_THREAD_FLAGS dwCreationFlags, [Optional] IntPtr lpAttributeList,
out uint lpThreadId);
/// <summary>
/// Creates a thread that runs in the virtual address space of another process and optionally specifies extended attributes such as
/// processor group affinity.
/// </summary>
/// <param name="hProcess">
/// A handle to the process in which the thread is to be created. The handle must have the PROCESS_CREATE_THREAD,
/// PROCESS_QUERY_INFORMATION, PROCESS_VM_OPERATION, PROCESS_VM_WRITE, and PROCESS_VM_READ access rights. In Windows 10, version 1607,
/// your code must obtain these access rights for the new handle. However, starting in Windows 10, version 1703, if the new handle is
/// entitled to these access rights, the system obtains them for you. For more information, see Process Security and Access Rights.
/// </param>
/// <param name="lpThreadAttributes">
/// A pointer to a <c>SECURITY_ATTRIBUTES</c> structure that specifies a security descriptor for the new thread and determines whether
/// child processes can inherit the returned handle. If lpThreadAttributes is NULL, the thread gets a default security descriptor and the
/// handle cannot be inherited. The access control lists (ACL) in the default security descriptor for a thread come from the primary
/// token of the creator.
/// </param>
/// <param name="dwStackSize">
/// The initial size of the stack, in bytes. The system rounds this value to the nearest page. If this parameter is 0 (zero), the new
/// thread uses the default size for the executable. For more information, see Thread Stack Size.
/// </param>
/// <param name="lpStartAddress">
/// A pointer to the application-defined function of type <c>LPTHREAD_START_ROUTINE</c> to be executed by the thread and represents the
/// starting address of the thread in the remote process. The function must exist in the remote process. For more information, see <c>ThreadProc</c>.
/// </param>
/// <param name="lpParameter">
/// A pointer to a variable to be passed to the thread function pointed to by lpStartAddress. This parameter can be NULL.
/// </param>
/// <param name="dwCreationFlags">
/// <para>The flags that control the creation of the thread.</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>0</term>
/// <term>The thread runs immediately after creation.</term>
/// </item>
/// <item>
/// <term>CREATE_SUSPENDED0x00000004</term>
/// <term>The thread is created in a suspended state and does not run until the ResumeThread function is called.</term>
/// </item>
/// <item>
/// <term>STACK_SIZE_PARAM_IS_A_RESERVATION0x00010000</term>
/// <term>
/// The dwStackSize parameter specifies the initial reserve size of the stack. If this flag is not specified, dwStackSize specifies the
/// commit size.
/// </term>
/// </item>
/// </list>
/// </para>
/// </param>
/// <param name="lpAttributeList">
/// An attribute list that contains additional parameters for the new thread. This list is created by the
/// <c>InitializeProcThreadAttributeList</c> function.
/// </param>
/// <param name="lpThreadId">
/// <para>A pointer to a variable that receives the thread identifier.</para>
/// <para>If this parameter is NULL, the thread identifier is not returned.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is a handle to the new thread.</para>
/// <para>If the function fails, the return value is NULL. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// HANDLE CreateRemoteThreadEx( _In_ HANDLE hProcess, _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ SIZE_T dwStackSize, _In_
// LPTHREAD_START_ROUTINE lpStartAddress, _In_opt_ LPVOID lpParameter, _In_ DWORD dwCreationFlags, _In_opt_ LPPROC_THREAD_ATTRIBUTE_LIST
// lpAttributeList, _Out_opt_ LPDWORD lpThreadId); https://msdn.microsoft.com/en-us/library/windows/desktop/dd405484(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "dd405484")]
public static extern SafeHTHREAD CreateRemoteThreadEx([In] HPROCESS hProcess, [In, Optional] SECURITY_ATTRIBUTES lpThreadAttributes, [Optional] SizeT dwStackSize,
IntPtr lpStartAddress, [In, Optional] IntPtr lpParameter, [Optional] CREATE_THREAD_FLAGS dwCreationFlags, SafeProcThreadAttributeList lpAttributeList,
out uint lpThreadId);
/// <summary>
/// Creates a thread that runs in the virtual address space of another process and optionally specifies extended attributes such as
/// processor group affinity.
/// </summary>
/// <param name="hProcess">
/// A handle to the process in which the thread is to be created. The handle must have the PROCESS_CREATE_THREAD,
/// PROCESS_QUERY_INFORMATION, PROCESS_VM_OPERATION, PROCESS_VM_WRITE, and PROCESS_VM_READ access rights. In Windows 10, version 1607,
/// your code must obtain these access rights for the new handle. However, starting in Windows 10, version 1703, if the new handle is
/// entitled to these access rights, the system obtains them for you. For more information, see Process Security and Access Rights.
/// </param>
/// <param name="lpThreadAttributes">
/// A pointer to a <c>SECURITY_ATTRIBUTES</c> structure that specifies a security descriptor for the new thread and determines whether
/// child processes can inherit the returned handle. If lpThreadAttributes is NULL, the thread gets a default security descriptor and the
/// handle cannot be inherited. The access control lists (ACL) in the default security descriptor for a thread come from the primary
/// token of the creator.
/// </param>
/// <param name="dwStackSize">
/// The initial size of the stack, in bytes. The system rounds this value to the nearest page. If this parameter is 0 (zero), the new
/// thread uses the default size for the executable. For more information, see Thread Stack Size.
/// </param>
/// <param name="lpStartAddress">
/// A pointer to the application-defined function of type <c>LPTHREAD_START_ROUTINE</c> to be executed by the thread and represents the
/// starting address of the thread in the remote process. The function must exist in the remote process. For more information, see <c>ThreadProc</c>.
/// </param>
/// <param name="lpParameter">
/// A pointer to a variable to be passed to the thread function pointed to by lpStartAddress. This parameter can be NULL.
/// </param>
/// <param name="dwCreationFlags">
/// <para>The flags that control the creation of the thread.</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>0</term>
/// <term>The thread runs immediately after creation.</term>
/// </item>
/// <item>
/// <term>CREATE_SUSPENDED0x00000004</term>
/// <term>The thread is created in a suspended state and does not run until the ResumeThread function is called.</term>
/// </item>
/// <item>
/// <term>STACK_SIZE_PARAM_IS_A_RESERVATION0x00010000</term>
/// <term>
/// The dwStackSize parameter specifies the initial reserve size of the stack. If this flag is not specified, dwStackSize specifies the
/// commit size.
/// </term>
/// </item>
/// </list>
/// </para>
/// </param>
/// <param name="lpAttributeList">
/// An attribute list that contains additional parameters for the new thread. This list is created by the
/// <c>InitializeProcThreadAttributeList</c> function.
/// </param>
/// <param name="lpThreadId">
/// <para>A pointer to a variable that receives the thread identifier.</para>
/// <para>If this parameter is NULL, the thread identifier is not returned.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is a handle to the new thread.</para>
/// <para>If the function fails, the return value is NULL. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// HANDLE CreateRemoteThreadEx( _In_ HANDLE hProcess, _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ SIZE_T dwStackSize, _In_
// LPTHREAD_START_ROUTINE lpStartAddress, _In_opt_ LPVOID lpParameter, _In_ DWORD dwCreationFlags, _In_opt_ LPPROC_THREAD_ATTRIBUTE_LIST
// lpAttributeList, _Out_opt_ LPDWORD lpThreadId); https://msdn.microsoft.com/en-us/library/windows/desktop/dd405484(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "dd405484")]
public static extern SafeHTHREAD CreateRemoteThreadEx([In] HPROCESS hProcess, [In, Optional] SECURITY_ATTRIBUTES lpThreadAttributes, [Optional] SizeT dwStackSize,
IntPtr lpStartAddress, [In, Optional] IntPtr lpParameter, [Optional] CREATE_THREAD_FLAGS dwCreationFlags, [Optional] IntPtr lpAttributeList,
out uint lpThreadId);
/// <summary>
/// <para>Creates a thread to execute within the virtual address space of the calling process.</para>
/// <para>To create a thread that runs in the virtual address space of another process, use the <c>CreateRemoteThread</c> function.</para>
/// </summary>
/// <param name="lpThreadAttributes">
/// <para>
/// A pointer to a <c>SECURITY_ATTRIBUTES</c> structure that determines whether the returned handle can be inherited by child processes.
/// If lpThreadAttributes is NULL, the handle cannot be inherited.
/// </para>
/// <para>
/// The <c>lpSecurityDescriptor</c> member of the structure specifies a security descriptor for the new thread. If lpThreadAttributes is
/// NULL, the thread gets a default security descriptor. The ACLs in the default security descriptor for a thread come from the primary
/// token of the creator.
/// </para>
/// </param>
/// <param name="dwStackSize">
/// The initial size of the stack, in bytes. The system rounds this value to the nearest page. If this parameter is zero, the new thread
/// uses the default size for the executable. For more information, see Thread Stack Size.
/// </param>
/// <param name="lpStartAddress">
/// A pointer to the application-defined function to be executed by the thread. This pointer represents the starting address of the
/// thread. For more information on the thread function, see <c>ThreadProc</c>.
/// </param>
/// <param name="lpParameter">A pointer to a variable to be passed to the thread.</param>
/// <param name="dwCreationFlags">
/// <para>The flags that control the creation of the thread.</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>0</term>
/// <term>The thread runs immediately after creation.</term>
/// </item>
/// <item>
/// <term>CREATE_SUSPENDED0x00000004</term>
/// <term>The thread is created in a suspended state, and does not run until the ResumeThread function is called.</term>
/// </item>
/// <item>
/// <term>STACK_SIZE_PARAM_IS_A_RESERVATION0x00010000</term>
/// <term>
/// The dwStackSize parameter specifies the initial reserve size of the stack. If this flag is not specified, dwStackSize specifies the
/// commit size.
/// </term>
/// </item>
/// </list>
/// </para>
/// </param>
/// <param name="lpThreadId">
/// A pointer to a variable that receives the thread identifier. If this parameter is <c>NULL</c>, the thread identifier is not returned.
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is a handle to the new thread.</para>
/// <para>If the function fails, the return value is <c>NULL</c>. To get extended error information, call <c>GetLastError</c>.</para>
/// <para>
/// Note that <c>CreateThread</c> may succeed even if lpStartAddress points to data, code, or is not accessible. If the start address is
/// invalid when the thread runs, an exception occurs, and the thread terminates. Thread termination due to a invalid start address is
/// handled as an error exit for the thread's process. This behavior is similar to the asynchronous nature of <c>CreateProcess</c>, where
/// the process is created even if it refers to invalid or missing dynamic-link libraries (DLLs).
/// </para>
/// </returns>
// HANDLE WINAPI CreateThread( _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ SIZE_T dwStackSize, _In_ LPTHREAD_START_ROUTINE
// lpStartAddress, _In_opt_ LPVOID lpParameter, _In_ DWORD dwCreationFlags, _Out_opt_ LPDWORD lpThreadId); https://msdn.microsoft.com/en-us/library/windows/desktop/ms682453(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms682453")]
public static extern SafeHTHREAD CreateThread([In, Optional] SECURITY_ATTRIBUTES lpThreadAttributes, [Optional] SizeT dwStackSize, ThreadProc lpStartAddress,
[In, Optional] IntPtr lpParameter, [Optional] CREATE_THREAD_FLAGS dwCreationFlags, out uint lpThreadId);
/// <summary>
/// <para>Creates a thread to execute within the virtual address space of the calling process.</para>
/// <para>To create a thread that runs in the virtual address space of another process, use the <c>CreateRemoteThread</c> function.</para>
/// </summary>
/// <param name="lpThreadAttributes">
/// <para>
/// A pointer to a <c>SECURITY_ATTRIBUTES</c> structure that determines whether the returned handle can be inherited by child processes.
/// If lpThreadAttributes is NULL, the handle cannot be inherited.
/// </para>
/// <para>
/// The <c>lpSecurityDescriptor</c> member of the structure specifies a security descriptor for the new thread. If lpThreadAttributes is
/// NULL, the thread gets a default security descriptor. The ACLs in the default security descriptor for a thread come from the primary
/// token of the creator.
/// </para>
/// </param>
/// <param name="dwStackSize">
/// The initial size of the stack, in bytes. The system rounds this value to the nearest page. If this parameter is zero, the new thread
/// uses the default size for the executable. For more information, see Thread Stack Size.
/// </param>
/// <param name="lpStartAddress">
/// A pointer to the application-defined function to be executed by the thread. This pointer represents the starting address of the
/// thread. For more information on the thread function, see <c>ThreadProc</c>.
/// </param>
/// <param name="lpParameter">A pointer to a variable to be passed to the thread.</param>
/// <param name="dwCreationFlags">
/// <para>The flags that control the creation of the thread.</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>0</term>
/// <term>The thread runs immediately after creation.</term>
/// </item>
/// <item>
/// <term>CREATE_SUSPENDED0x00000004</term>
/// <term>The thread is created in a suspended state, and does not run until the ResumeThread function is called.</term>
/// </item>
/// <item>
/// <term>STACK_SIZE_PARAM_IS_A_RESERVATION0x00010000</term>
/// <term>
/// The dwStackSize parameter specifies the initial reserve size of the stack. If this flag is not specified, dwStackSize specifies the
/// commit size.
/// </term>
/// </item>
/// </list>
/// </para>
/// </param>
/// <param name="lpThreadId">
/// A pointer to a variable that receives the thread identifier. If this parameter is <c>NULL</c>, the thread identifier is not returned.
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is a handle to the new thread.</para>
/// <para>If the function fails, the return value is <c>NULL</c>. To get extended error information, call <c>GetLastError</c>.</para>
/// <para>
/// Note that <c>CreateThread</c> may succeed even if lpStartAddress points to data, code, or is not accessible. If the start address is
/// invalid when the thread runs, an exception occurs, and the thread terminates. Thread termination due to a invalid start address is
/// handled as an error exit for the thread's process. This behavior is similar to the asynchronous nature of <c>CreateProcess</c>, where
/// the process is created even if it refers to invalid or missing dynamic-link libraries (DLLs).
/// </para>
/// </returns>
// HANDLE WINAPI CreateThread( _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ SIZE_T dwStackSize, _In_ LPTHREAD_START_ROUTINE
// lpStartAddress, _In_opt_ LPVOID lpParameter, _In_ DWORD dwCreationFlags, _Out_opt_ LPDWORD lpThreadId); https://msdn.microsoft.com/en-us/library/windows/desktop/ms682453(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms682453")]
public static extern unsafe SafeHTHREAD CreateThread([In, Optional] SECURITY_ATTRIBUTES lpThreadAttributes, [Optional] SizeT dwStackSize, ThreadProcUnsafe lpStartAddress,
[In, Optional] void* lpParameter, [Optional] CREATE_THREAD_FLAGS dwCreationFlags, out uint lpThreadId);
/// <summary>Deletes the specified list of attributes for process and thread creation.</summary>
/// <param name="lpAttributeList">The attribute list. This list is created by the <see cref="InitializeProcThreadAttributeList"/>.</param>
/// <returns>This function does not return a value.</returns>
// VOID WINAPI DeleteProcThreadAttributeList( _Inout_ LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList); https://msdn.microsoft.com/en-us/library/windows/desktop/ms682559(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms682559")]
public static extern void DeleteProcThreadAttributeList(IntPtr lpAttributeList);
/// <summary>Ends the calling process and all its threads.</summary>
/// <param name="uExitCode">The exit code for the process and all threads.</param>
/// <returns>This function does not return a value.</returns>
// VOID WINAPI ExitProcess( _In_ UINT uExitCode); https://msdn.microsoft.com/en-us/library/windows/desktop/ms682658(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms682658")]
public static extern void ExitProcess(uint uExitCode);
/// <summary>Ends the calling thread.</summary>
/// <param name="dwExitCode">The exit code for the thread.</param>
/// <returns>This function does not return a value.</returns>
// VOID WINAPI ExitThread( _In_ DWORD dwExitCode); https://msdn.microsoft.com/en-us/library/windows/desktop/ms682659(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms682659")]
public static extern void ExitThread(uint dwExitCode);
/// <summary>Flushes the instruction cache for the specified process.</summary>
/// <param name="hProcess">A handle to a process whose instruction cache is to be flushed.</param>
/// <param name="lpBaseAddress">A pointer to the base of the region to be flushed. This parameter can be <c>NULL</c>.</param>
/// <param name="dwSize">The size of the region to be flushed if the lpBaseAddress parameter is not <c>NULL</c>, in bytes.</param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL WINAPI FlushInstructionCache( _In_ HANDLE hProcess, _In_ LPCVOID lpBaseAddress, _In_ SIZE_T dwSize); https://msdn.microsoft.com/en-us/library/windows/desktop/ms679350(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms679350")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool FlushInstructionCache([In] HPROCESS hProcess, [In, Optional] IntPtr lpBaseAddress, [Optional] SizeT dwSize);
/// <summary>Flushes the write queue of each processor that is running a thread of the current process.</summary>
/// <returns>This function does not return a value.</returns>
// VOID WINAPI FlushProcessWriteBuffers(void); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683148(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms683148")]
public static extern void FlushProcessWriteBuffers();
/// <summary>Retrieves the process identifier of the calling process.</summary>
/// <returns>The return value is the process identifier of the calling process.</returns>
// DWORD WINAPI GetCurrentProcessId(void); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683180(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms683180")]
public static extern uint GetCurrentProcessId();
/// <summary>
/// <para>Retrieves the number of the processor the current thread was running on during the call to this function.</para>
/// </summary>
/// <returns>
/// <para>The function returns the current processor number.</para>
/// </returns>
/// <remarks>
/// <para>This function is used to provide information for estimating process performance.</para>
/// <para>
/// On systems with more than 64 logical processors, the <c>GetCurrentProcessorNumber</c> function returns the processor number within
/// the processor group to which the logical processor is assigned. Use the GetCurrentProcessorNumberEx function to retrieve the
/// processor group and number of the current processor.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-getcurrentprocessornumber DWORD
// GetCurrentProcessorNumber( );
[DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("processthreadsapi.h", MSDNShortId = "1f2bebc7-a548-409a-ab74-78a4b55c8fa7")]
public static extern uint GetCurrentProcessorNumber();
/// <summary>Retrieves the processor group and number of the logical processor in which the calling thread is running.</summary>
/// <param name="ProcNumber">
/// A pointer to a <c>PROCESSOR_NUMBER</c> structure that receives the processor group to which the logical processor is assigned and the
/// number of the logical processor within its group.
/// </param>
/// <returns>
/// If the function succeeds, the ProcNumber parameter contains the group and processor number of the processor on which the calling
/// thread is running.
/// </returns>
// VOID GetCurrentProcessorNumberEx( _Out_ PPROCESSOR_NUMBER ProcNumber); https://msdn.microsoft.com/en-us/library/windows/desktop/dd405487(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "dd405487")]
public static extern void GetCurrentProcessorNumberEx(out PROCESSOR_NUMBER ProcNumber);
/// <summary>Retrieves a pseudo-handle that you can use as a shorthand way to refer to the access token associated with a process.</summary>
/// <returns>A pseudo-handle that you can use as a shorthand way to refer to the access token associated with a process.</returns>
[PInvokeData("Processthreadsapi.h", MSDNShortId = "mt643211")]
public static HTOKEN GetCurrentProcessToken() => new IntPtr(-4);
/// <summary>Retrieves a pseudo handle for the calling thread.</summary>
/// <returns>The return value is a pseudo handle for the current thread.</returns>
/// <remarks>
/// A pseudo handle is a special constant that is interpreted as the current thread handle. The calling thread can use this handle to
/// specify itself whenever a thread handle is required. Pseudo handles are not inherited by child processes.
/// <para>
/// This handle has the THREAD_ALL_ACCESS access right to the thread object. For more information, see Thread Security and Access Rights.
/// </para>
/// <para>
/// Windows Server 2003 and Windows XP: This handle has the maximum access allowed by the security descriptor of the thread to the
/// primary token of the process.
/// </para>
/// <para>
/// The function cannot be used by one thread to create a handle that can be used by other threads to refer to the first thread. The
/// handle is always interpreted as referring to the thread that is using it. A thread can create a "real" handle to itself that can be
/// used by other threads, or inherited by other processes, by specifying the pseudo handle as the source handle in a call to the
/// DuplicateHandle function.
/// </para>
/// <para>
/// The pseudo handle need not be closed when it is no longer needed. Calling the CloseHandle function with this handle has no effect. If
/// the pseudo handle is duplicated by DuplicateHandle, the duplicate handle must be closed.
/// </para>
/// <para>
/// Do not create a thread while impersonating a security context. The call will succeed, however the newly created thread will have
/// reduced access rights to itself when calling GetCurrentThread. The access rights granted this thread will be derived from the access
/// rights the impersonated user has to the process. Some access rights including THREAD_SET_THREAD_TOKEN and THREAD_GET_CONTEXT may not
/// be present, leading to unexpected failures.
/// </para>
/// </remarks>
[DllImport(Lib.Kernel32, ExactSpelling = true, SetLastError = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms683182")]
public static extern HTHREAD GetCurrentThread();
/// <summary>
/// Retrieves a pseudo-handle that you can use as a shorthand way to refer to the token that is currently in effect for the thread, which
/// is the thread token if one exists and the process token otherwise.
/// </summary>
/// <returns>A pseudo-handle that you can use as a shorthand way to refer to the token that is currently in effect for the thread.</returns>
// FORCEINLINE HANDLE GetCurrentThreadEffectiveToken(void); https://msdn.microsoft.com/en-us/library/windows/desktop/mt643212(v=vs.85).aspx
[PInvokeData("Processthreadsapi.h", MSDNShortId = "mt643212")]
public static HTOKEN GetCurrentThreadEffectiveToken() => new IntPtr(-6);
/// <summary>Retrieves the thread identifier of the calling thread.</summary>
/// <returns>The return value is the thread identifier of the calling thread.</returns>
// DWORD WINAPI GetCurrentThreadId(void); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683183(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms683183")]
public static extern uint GetCurrentThreadId();
/// <summary>Retrieves the boundaries of the stack that was allocated by the system for the current thread.</summary>
/// <param name="LowLimit">A pointer variable that receives the lower boundary of the current thread stack.</param>
/// <param name="HighLimit">A pointer variable that receives the upper boundary of the current thread stack.</param>
/// <returns>This function does not return a value.</returns>
// VOID WINAPI GetCurrentThreadStackLimits( _Out_ PULONG_PTR LowLimit, _Out_ PULONG_PTR HighLimit); https://msdn.microsoft.com/en-us/library/windows/desktop/hh706789(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("Processthreadsapi.h", MSDNShortId = "hh706789")]
public static extern void GetCurrentThreadStackLimits(out UIntPtr LowLimit, out UIntPtr HighLimit);
/// <summary>
/// Retrieves a pseudo-handle that you can use as a shorthand way to refer to the impersonation token that was assigned to the current thread.
/// </summary>
/// <returns>
/// A pseudo-handle that you can use as a shorthand way to refer to the impersonation token that was assigned to the current thread.
/// </returns>
// FORCEINLINE HANDLE GetCurrentThreadEffectiveToken(void); https://msdn.microsoft.com/en-us/library/windows/desktop/mt643213(v=vs.85).aspx
[PInvokeData("Processthreadsapi.h", MSDNShortId = "mt643213")]
public static HTOKEN GetCurrentThreadToken() => new IntPtr(-5);
/// <summary>Retrieves the termination status of the specified process.</summary>
/// <param name="hProcess">
/// <para>A handle to the process.</para>
/// <para>
/// The handle must have the <c>PROCESS_QUERY_INFORMATION</c> or <c>PROCESS_QUERY_LIMITED_INFORMATION</c> access right. For more
/// information, see Process Security and Access Rights.
/// </para>
/// <para><c>Windows Server 2003 and Windows XP:</c> The handle must have the <c>PROCESS_QUERY_INFORMATION</c> access right.</para>
/// </param>
/// <param name="lpExitCode">A pointer to a variable to receive the process termination status. For more information, see Remarks.</param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL WINAPI GetExitCodeProcess( _In_ HANDLE hProcess, _Out_ LPDWORD lpExitCode); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683189(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms683189")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetExitCodeProcess([In] HPROCESS hProcess, out uint lpExitCode);
/// <summary>Retrieves the termination status of the specified thread.</summary>
/// <param name="hThread">
/// <para>A handle to the thread.</para>
/// <para>
/// The handle must have the <c>THREAD_QUERY_INFORMATION</c> or <c>THREAD_QUERY_LIMITED_INFORMATION</c> access right. For more
/// information, see Thread Security and Access Rights.
/// </para>
/// <para><c>Windows Server 2003 and Windows XP:</c> The handle must have the <c>THREAD_QUERY_INFORMATION</c> access right.</para>
/// </param>
/// <param name="lpExitCode">A pointer to a variable to receive the thread termination status. For more information, see Remarks.</param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL WINAPI GetExitCodeThread( _In_ HANDLE hThread, _Out_ LPDWORD lpExitCode); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683190(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms683190")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetExitCodeThread([In] HTHREAD hThread, out uint lpExitCode);
/// <summary>
/// Queries if the specified architecture is supported on the current system, either natively or by any form of compatibility or
/// emulation layer.
/// </summary>
/// <param name="Machine">
/// An IMAGE_FILE_MACHINE_* value corresponding to the architecture of code to be tested for supportability. See the list of architecture
/// values in Image File Machine Constants.
/// </param>
/// <param name="MachineTypeAttributes">
/// Output parameter receives a pointer to a value from the MACHINE_ATTRIBUTES enumeration indicating if the specified code architecture
/// can run in user mode, kernel mode, and/or under WOW64 on the host operating system.
/// </param>
/// <returns>If the function fails, the return value is a nonzero HRESULT value. If the function succeeds, the return value is zero.</returns>
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getmachinetypeattributes HRESULT
// GetMachineTypeAttributes( USHORT Machine, MACHINE_ATTRIBUTES *MachineTypeAttributes );
[DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("processthreadsapi.h", MSDNShortId = "NF:processthreadsapi.GetMachineTypeAttributes")]
public static extern HRESULT GetMachineTypeAttributes(IMAGE_FILE_MACHINE Machine, out MACHINE_ATTRIBUTES MachineTypeAttributes);
/// <summary>
/// Retrieves the priority class for the specified process. This value, together with the priority value of each thread of the process,
/// determines each thread's base priority level.
/// </summary>
/// <param name="hProcess">
/// <para>A handle to the process.</para>
/// <para>
/// The handle must have the <c>PROCESS_QUERY_INFORMATION</c> or <c>PROCESS_QUERY_LIMITED_INFORMATION</c> access right. For more
/// information, see Process Security and Access Rights.
/// </para>
/// <para><c>Windows Server 2003 and Windows XP:</c> The handle must have the <c>PROCESS_QUERY_INFORMATION</c> access right.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is the priority class of the specified process.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// <para>The process's priority class is one of the following values.</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Return code/value</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ABOVE_NORMAL_PRIORITY_CLASS0x00008000</term>
/// <term>Process that has priority above NORMAL_PRIORITY_CLASS but below HIGH_PRIORITY_CLASS.</term>
/// </item>
/// <item>
/// <term>BELOW_NORMAL_PRIORITY_CLASS0x00004000</term>
/// <term>Process that has priority above IDLE_PRIORITY_CLASS but below NORMAL_PRIORITY_CLASS.</term>
/// </item>
/// <item>
/// <term>HIGH_PRIORITY_CLASS0x00000080</term>
/// <term>
/// Process that performs time-critical tasks that must be executed immediately for it to run correctly. The threads of a high-priority
/// class process preempt the threads of normal or idle priority class processes. An example is the Task List, which must respond quickly
/// when called by the user, regardless of the load on the operating system. Use extreme care when using the high-priority class, because
/// a high-priority class CPU-bound application can use nearly all available cycles.
/// </term>
/// </item>
/// <item>
/// <term>IDLE_PRIORITY_CLASS0x00000040</term>
/// <term>
/// Process whose threads run only when the system is idle and are preempted by the threads of any process running in a higher priority
/// class. An example is a screen saver. The idle priority class is inherited by child processes.
/// </term>
/// </item>
/// <item>
/// <term>NORMAL_PRIORITY_CLASS0x00000020</term>
/// <term>Process with no special scheduling needs.</term>
/// </item>
/// <item>
/// <term>REALTIME_PRIORITY_CLASS0x00000100</term>
/// <term>
/// Process that has the highest possible priority. The threads of a real-time priority class process preempt the threads of all other
/// processes, including operating system processes performing important tasks. For example, a real-time process that executes for more
/// than a very brief interval can cause disk caches not to flush or cause the mouse to be unresponsive.
/// </term>
/// </item>
/// </list>
/// </para>
/// </returns>
// DWORD WINAPI GetPriorityClass( _In_ HANDLE hProcess); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683211(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms683211")]
public static extern CREATE_PROCESS GetPriorityClass([In] HPROCESS hProcess);
/// <summary>Retrieves the list of CPU Sets in the process default set that was set by SetProcessDefaultCpuSetMasks or SetProcessDefaultCpuSets.</summary>
/// <param name="Process">
/// Specifies a process handle for the process to query. This handle must have the PROCESS_QUERY_LIMITED_INFORMATION access right. The
/// value returned by GetCurrentProcess can also be specified here.
/// </param>
/// <param name="CpuSetMasks">
/// Specifies an optional buffer to retrieve a list of GROUP_AFFINITY structures representing the process default CPU Sets.
/// </param>
/// <param name="CpuSetMaskCount">Specifies the size of the CpuSetMasks array, in elements.</param>
/// <param name="RequiredMaskCount">
/// On successful return, specifies the number of affinity structures written to the array. If the CpuSetMasks array is too small, the
/// function fails with <c>ERROR_INSUFFICIENT_BUFFER</c> and sets the RequiredMaskCount parameter to the number of elements required. The
/// number of required elements is always less than or equal to the maximum group count returned by GetMaximumProcessorGroupCount.
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero and extended error information can be retrieved by calling GetLastError.</para>
/// <para>
/// If the array supplied is too small, the error value is <c>ERROR_INSUFFICIENT_BUFFER</c> and the RequiredMaskCount is set to the
/// number of elements required.
/// </para>
/// </returns>
/// <remarks>
/// <para>If no default CPU Sets are set for a given process, then the RequiredMaskCount parameter is set to 0 and the function succeeds.</para>
/// <para>
/// This function is analogous to GetProcessDefaultCpuSets, except that it uses group affinities as opposed to CPU Set IDs to represent a
/// list of CPU sets. This means that the process default CPU Sets are mapped to their home processors, and those processors are
/// retrieved in the resulting list of group affinities.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getprocessdefaultcpusetmasks BOOL
// GetProcessDefaultCpuSetMasks( HANDLE Process, PGROUP_AFFINITY CpuSetMasks, USHORT CpuSetMaskCount, PUSHORT RequiredMaskCount );
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("processthreadsapi.h", MSDNShortId = "NF:processthreadsapi.GetProcessDefaultCpuSetMasks")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetProcessDefaultCpuSetMasks([In] HPROCESS Process,
[Out, Optional, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] GROUP_AFFINITY[] CpuSetMasks,
ushort CpuSetMaskCount, out ushort RequiredMaskCount);
/// <summary>
/// Retrieves the list of CPU Sets in the process default set that was set by <c>SetProcessDefaultCpuSets</c>. If no default CPU Sets are
/// set for a given process, then the <c>RequiredIdCount</c> is set to 0 and the function succeeds.
/// </summary>
/// <param name="Process">
/// Specifies a process handle for the process to query. This handle must have the PROCESS_QUERY_LIMITED_INFORMATION access right. The
/// value returned by <c>GetCurrentProcess</c> can also be specified here.
/// </param>
/// <param name="CpuSetIds">Specifies an optional buffer to retrieve the list of CPU Set identifiers.</param>
/// <param name="CpuSetIdCount">
/// Specifies the capacity of the buffer specified in <c>CpuSetIds</c>. If the buffer is NULL, this must be 0.
/// </param>
/// <param name="RequiredIdCount">
/// Specifies the required capacity of the buffer to hold the entire list of process default CPU Sets. On successful return, this
/// specifies the number of IDs filled into the buffer.
/// </param>
/// <returns>
/// This API returns TRUE on success. If the buffer is not large enough the API returns FALSE, and the <c>GetLastError</c> value is
/// ERROR_INSUFFICIENT_BUFFER. This API cannot fail when passed valid parameters and the return buffer is large enough.
/// </returns>
// BOOL WINAPI GetProcessDefaultCpuSets( _In_ HANDLE Process, _Out_opt_ PULONG CpuSetIds, _In_ ULONG CpuSetIdCount, _Out_ PULONG
// RequiredIdCount); https://msdn.microsoft.com/en-us/library/windows/desktop/mt186424(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("Processthreadapi.h", MSDNShortId = "mt186424")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetProcessDefaultCpuSets(HPROCESS Process, IntPtr CpuSetIds, uint CpuSetIdCount, out uint RequiredIdCount);
/// <summary>
/// Retrieves the list of CPU Sets in the process default set that was set by <c>SetProcessDefaultCpuSets</c>. If no default CPU Sets are
/// set for a given process, then an empty array is returned.
/// </summary>
/// <param name="Process">
/// Specifies a process handle for the process to query. This handle must have the PROCESS_QUERY_LIMITED_INFORMATION access right. The
/// value returned by <c>GetCurrentProcess</c> can also be specified here.
/// </param>
/// <returns>The list of CPU Set identifiers.</returns>
public static uint[] GetProcessDefaultCpuSets(HPROCESS Process)
{
uint cnt = (uint)Environment.ProcessorCount;
if (cnt == 0) return new uint[0];
SafeCoTaskMemHandle iptr = new((int)cnt * Marshal.SizeOf(typeof(uint)));
if (!GetProcessDefaultCpuSets(Process, (IntPtr)iptr, cnt, out cnt)) Win32Error.ThrowLastError();
return iptr.ToArray<uint>((int)cnt);
}
/// <summary>Retrieves the number of open handles that belong to the specified process.</summary>
/// <param name="hProcess">
/// <para>
/// A handle to the process whose handle count is being requested. The handle must have the PROCESS_QUERY_INFORMATION or
/// PROCESS_QUERY_LIMITED_INFORMATION access right. For more information, see Process Security and Access Rights.
/// </para>
/// <para><c>Windows Server 2003 and Windows XP:</c> The handle must have the PROCESS_QUERY_INFORMATION access right.</para>
/// </param>
/// <param name="pdwHandleCount">A pointer to a variable that receives the number of open handles that belong to the specified process.</param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL WINAPI GetProcessHandleCount( _In_ HANDLE hProcess, _Inout_ PDWORD pdwHandleCount); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683214(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms683214")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetProcessHandleCount([In] HPROCESS hProcess, out uint pdwHandleCount);
/// <summary>Retrieves the process identifier of the specified process.</summary>
/// <param name="Process">
/// <para>
/// A handle to the process. The handle must have the PROCESS_QUERY_INFORMATION or PROCESS_QUERY_LIMITED_INFORMATION access right. For
/// more information, see Process Security and Access Rights.
/// </para>
/// <para><c>Windows Server 2003 and Windows XP:</c> The handle must have the PROCESS_QUERY_INFORMATION access right.</para>
/// </param>
/// <returns></returns>
// DWORD WINAPI GetProcessId( _In_ HANDLE Process); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683215(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms683215")]
public static extern uint GetProcessId([In] HPROCESS Process);
/// <summary>Retrieves the process identifier of the process associated with the specified thread.</summary>
/// <param name="Thread">
/// <para>
/// A handle to the thread. The handle must have the THREAD_QUERY_INFORMATION or THREAD_QUERY_LIMITED_INFORMATION access right. For more
/// information, see Thread Security and Access Rights.
/// </para>
/// <para><c>Windows Server 2003:</c> The handle must have the THREAD_QUERY_INFORMATION access right.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is the process identifier of the process associated with the specified thread.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// DWORD WINAPI GetProcessIdOfThread( _In_ HANDLE Thread); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683216(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms683216")]
public static extern uint GetProcessIdOfThread(HTHREAD Thread);
/// <summary>Retrieves information about the specified process.</summary>
/// <param name="hProcess">
/// A handle to the process. This handle must have the <c>PROCESS_SET_INFORMATION</c> access right. For more information, see Process
/// Security and Access Rights.
/// </param>
/// <param name="ProcessInformationClass">
/// A member of the PROCESS_INFORMATION_CLASS enumeration specifying the kind of information to retrieve.
/// </param>
/// <param name="ProcessInformation">
/// <para>Pointer to an object to receive the type of information specified by the ProcessInformationClass parameter.</para>
/// <para>
/// If the ProcessInformationClass parameter is <c>ProcessMemoryPriority</c>, this parameter must point to a MEMORY_PRIORITY_INFORMATION structure.
/// </para>
/// <para>
/// If the ProcessInformationClass parameter is <c>ProcessPowerThrottling</c>, this parameter must point to a
/// PROCESS_POWER_THROTTLING_STATE structure.
/// </para>
/// <para>
/// If the ProcessInformationClass parameter is <c>ProcessProtectionLevelInfo</c>, this parameter must point to a
/// PROCESS_PROTECTION_LEVEL_INFORMATION structure.
/// </para>
/// <para>
/// If the ProcessInformationClass parameter is <c>ProcessLeapSecondInfo</c>, this parameter must point to a PROCESS_LEAP_SECOND_INFO structure.
/// </para>
/// <para>
/// If the ProcessInformationClass parameter is <c>ProcessAppMemoryInfo</c>, this parameter must point to a APP_MEMORY_INFORMATION structure.
/// </para>
/// </param>
/// <param name="ProcessInformationSize">
/// <para>The size in bytes of the structure specified by the ProcessInformation parameter.</para>
/// <para>If the ProcessInformationClass parameter is <c>ProcessMemoryPriority</c>, this parameter must be
/// <code>sizeof(MEMORY_PRIORITY_INFORMATION)</code>
/// .
/// </para>
/// <para>If the ProcessInformationClass parameter is <c>ProcessPowerThrottling</c>, this parameter must be
/// <code>sizeof(PROCESS_POWER_THROTTLING_STATE)</code>
/// .
/// </para>
/// <para>If the ProcessInformationClass parameter is <c>ProcessProtectionLevelInfo</c>, this parameter must be
/// <code>sizeof(PROCESS_PROTECTION_LEVEL_INFORMATION)</code>
/// .
/// </para>
/// <para>If the ProcessInformationClass parameter is <c>ProcessLeapSecondInfo</c>, this parameter must be
/// <code>sizeof(PROCESS_LEAP_SECOND_INFO)</code>
/// .
/// </para>
/// <para>If the ProcessInformationClass parameter is <c>ProcessAppMemoryInfo</c>, this parameter must be
/// <code>sizeof(APP_MEMORY_INFORMATION)</code>
/// .
/// </para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getprocessinformation BOOL
// GetProcessInformation( HANDLE hProcess, PROCESS_INFORMATION_CLASS ProcessInformationClass, LPVOID ProcessInformation, DWORD
// ProcessInformationSize );
[PInvokeData("processthreadsapi.h", MSDNShortId = "NF:processthreadsapi.GetProcessInformation")]
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetProcessInformation(HPROCESS hProcess, PROCESS_INFORMATION_CLASS ProcessInformationClass,
IntPtr ProcessInformation, uint ProcessInformationSize);
/// <summary>Retrieves information about the specified process.</summary>
/// <typeparam name="T">The type to retrive.</typeparam>
/// <param name="hProcess">
/// A handle to the process. This handle must have the <c>PROCESS_SET_INFORMATION</c> access right. For more information, see Process
/// Security and Access Rights.
/// </param>
/// <param name="ProcessInformationClass">
/// A member of the PROCESS_INFORMATION_CLASS enumeration specifying the kind of information to retrieve.
/// </param>
/// <returns>
/// <para>Pointer to an object to receive the type of information specified by the ProcessInformationClass parameter.</para>
/// <para>
/// If the ProcessInformationClass parameter is <c>ProcessMemoryPriority</c>, this parameter must point to a MEMORY_PRIORITY_INFORMATION structure.
/// </para>
/// <para>
/// If the ProcessInformationClass parameter is <c>ProcessPowerThrottling</c>, this parameter must point to a
/// PROCESS_POWER_THROTTLING_STATE structure.
/// </para>
/// <para>
/// If the ProcessInformationClass parameter is <c>ProcessProtectionLevelInfo</c>, this parameter must point to a
/// PROCESS_PROTECTION_LEVEL_INFORMATION structure.
/// </para>
/// <para>
/// If the ProcessInformationClass parameter is <c>ProcessLeapSecondInfo</c>, this parameter must point to a PROCESS_LEAP_SECOND_INFO structure.
/// </para>
/// <para>
/// If the ProcessInformationClass parameter is <c>ProcessAppMemoryInfo</c>, this parameter must point to a APP_MEMORY_INFORMATION structure.
/// </para>
/// </returns>
public static T GetProcessInformation<T>(HPROCESS hProcess, PROCESS_INFORMATION_CLASS ProcessInformationClass = (PROCESS_INFORMATION_CLASS)(-1)) where T : struct
{
if (!ProcessInformationClass.IsValid() && !CorrespondingTypeAttribute.CanGet<T, PROCESS_INFORMATION_CLASS>(out ProcessInformationClass))
throw new ArgumentException("The type specified by the type parameter cannot be retrieved for a process.", nameof(T));
else if (!CorrespondingTypeAttribute.CanGet(ProcessInformationClass, typeof(T)))
throw new ArgumentException("Type mismatch.");
using SafeCoTaskMemStruct<T> mem = new();
if (!GetProcessInformation(hProcess, ProcessInformationClass, mem, mem.Size))
Win32Error.ThrowLastError();
return mem.Value;
}
/// <summary>Retrieves mitigation policy settings for the calling process.</summary>
/// <param name="hProcess">
/// A handle to the process. This handle must have the PROCESS_QUERY_INFORMATION access right. For more information, see Process Security
/// and Access Rights.
/// </param>
/// <param name="MitigationPolicy">
/// <para>The mitigation policy to retrieve. This parameter can be one of the following values.</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>ProcessDEPPolicy</term>
/// <term>
/// The data execution prevention (DEP) policy of the process.The lpBuffer parameter points to a PROCESS_MITIGATION_DEP_POLICY structure
/// that specifies the DEP policy flags.
/// </term>
/// </item>
/// <item>
/// <term>ProcessASLRPolicy</term>
/// <term>
/// The Address Space Layout Randomization (ASLR) policy of the process.The lpBuffer parameter points to a PROCESS_MITIGATION_ASLR_POLICY
/// structure that specifies the ASLR policy flags.
/// </term>
/// </item>
/// <item>
/// <term>ProcessDynamicCodePolicy</term>
/// <term>
/// The dynamic code policy of the process. When turned on, the process cannot generate dynamic code or modify existing executable
/// code.The lpBuffer parameter points to a PROCESS_MITIGATION_DYNAMIC_CODE_POLICY structure that specifies the dynamic code policy flags.
/// </term>
/// </item>
/// <item>
/// <term>ProcessStrictHandleCheckPolicy</term>
/// <term>
/// The process will receive a fatal error if it manipulates a handle that is not valid.The lpBuffer parameter points to a
/// PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY structure that specifies the handle check policy flags.
/// </term>
/// </item>
/// <item>
/// <term>ProcessSystemCallDisablePolicy</term>
/// <term>
/// Disables the ability to use NTUser/GDI functions at the lowest layer.The lpBuffer parameter points to a
/// PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY structure that specifies the system call disable policy flags.
/// </term>
/// </item>
/// <item>
/// <term>ProcessMitigationOptionsMask</term>
/// <term>
/// Returns the mask of valid bits for all the mitigation options on the system. An application can set many mitigation options without
/// querying the operating system for mitigation options by combining bitwise with the mask to exclude all non-supported bits at once.The
/// lpBuffer parameter points to a ULONG64 bit vector for the mask, or a two-element array of ULONG64 bit vectors.
/// </term>
/// </item>
/// <item>
/// <term>ProcessExtensionPointDisablePolicy</term>
/// <term>
/// Prevents certain built-in third party extension points from being enabled, preventing legacy extension point DLLs from being loaded
/// into the process.The lpBuffer parameter points to a PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY structure that specifies the
/// extension point disable policy flags.
/// </term>
/// </item>
/// <item>
/// <term>ProcessControlFlowGuardPolicy</term>
/// <term>
/// The Control Flow Guard (CFG) policy of the process.The lpBuffer parameter points to a PROCESS_MITIGATION_CONTROL_FLOW_GUARD_POLICY
/// structure that specifies the CFG policy flags.
/// </term>
/// </item>
/// <item>
/// <term>ProcessSignaturePolicy</term>
/// <term>
/// The policy of a process that can restrict image loading to those images that are either signed by Microsoft, by the Windows Store, or
/// by Microsoft, the Windows Store and the Windows Hardware Quality Labs (WHQL).he lpBuffer parameter points to a
/// PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY structure that specifies the signature policy flags.
/// </term>
/// </item>
/// <item>
/// <term>ProcessFontDisablePolicy</term>
/// <term>
/// The policy regarding font loading for the process. When turned on, the process cannot load non-system fonts.The lpBuffer parameter
/// points to a PROCESS_MITIGATION_FONT_DISABLE_POLICY structure that specifies the policy flags for font loading.
/// </term>
/// </item>
/// <item>
/// <term>ProcessImageLoadPolicy</term>
/// <term>
/// The policy regarding image loading for the process, which determines the types of executable images that are allowed to be mapped
/// into the process. When turned on, images cannot be loaded from some locations, such a remote devices or files that have the low
/// mandatory label.The lpBuffer parameter points to a PROCESS_MITIGATION_IMAGE_LOAD_POLICY structure that specifies the policy flags for
/// image loading.
/// </term>
/// </item>
/// </list>
/// </para>
/// </param>
/// <param name="lpBuffer">
/// <para>
/// If the MitigationPolicy parameter is <c>ProcessDEPPolicy</c>, this parameter points to a <c>PROCESS_MITIGATION_DEP_POLICY</c>
/// structure that receives the DEP policy flags.
/// </para>
/// <para>
/// If the MitigationPolicy parameter is <c>ProcessASLRPolicy</c>, this parameter points to a <c>PROCESS_MITIGATION_ASLR_POLICY</c>
/// structure that receives the ASLR policy flags.
/// </para>
/// <para>
/// If the MitigationPolicy parameter is <c>ProcessDynamicCodePolicy</c>, this parameter points to a
/// <c>PROCESS_MITIGATION_DYNAMIC_CODE_POLICY</c> structure that receives the dynamic code policy flags.
/// </para>
/// <para>
/// If the MitigationPolicy parameter is <c>ProcessStrictHandleCheckPolicy</c>, this parameter points to a
/// <c>PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY</c> structure that specifies the handle check policy flags.
/// </para>
/// <para>
/// If the MitigationPolicy parameter is <c>ProcessSystemCallDisablePolicy</c>, this parameter points to a
/// <c>PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY</c> structure that specifies the system call disable policy flags.
/// </para>
/// <para>
/// If the MitigationPolicy parameter is <c>ProcessMitigationOptionsMask</c>, this parameter points to a <c>ULONG64</c> bit vector for
/// the mask or a two-element array of <c>ULONG64</c> bit vectors.
/// </para>
/// <para>
/// If the MitigationPolicy parameter is <c>ProcessExtensionPointDisablePolicy</c>, this parameter points to a
/// <c>PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY</c> structure that specifies the extension point disable policy flags.
/// </para>
/// <para>
/// If the MitigationPolicy parameter is <c>ProcessControlFlowGuardPolicy</c>, this parameter points to a
/// <c>PROCESS_MITIGATION_CONTROL_FLOW_GUARD_POLICY</c> structure that specifies the CFG policy flags.
/// </para>
/// <para>
/// If the MitigationPolicy parameter is <c>ProcessSignaturePolicy</c>, this parameter points to a
/// <c>PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY</c> structure that receives the signature policy flags.
/// </para>
/// <para>
/// If the MitigationPolicy parameter is <c>ProcessFontDisablePolicy</c>, this parameter points to a
/// <c>PROCESS_MITIGATION_FONT_DISABLE_POLICY</c> structure that receives the policy flags for font loading.
/// </para>
/// <para>
/// If the MitigationPolicy parameter is <c>ProcessImageLoadPolicy</c>, this parameter points to a
/// <c>PROCESS_MITIGATION_IMAGE_LOAD_POLICY</c> structure that receives the policy flags for image loading.
/// </para>
/// </param>
/// <param name="dwLength">The size of lpBuffer, in bytes.</param>
/// <returns>
/// If the function succeeds, it returns <c>TRUE</c>. If the function fails, it returns <c>FALSE</c>. To retrieve error values defined
/// for this function, call <c>GetLastError</c>.
/// </returns>
// BOOL WINAPI GetProcessMitigationPolicy( _In_ HANDLE hProcess, _In_ PROCESS_MITIGATION_POLICY MitigationPolicy, _Out_ PVOID lpBuffer,
// _In_ SIZE_T dwLength); https://msdn.microsoft.com/en-us/library/windows/desktop/hh769085(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("Processthreadsapi.h", MSDNShortId = "hh769085")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetProcessMitigationPolicy(HPROCESS hProcess, PROCESS_MITIGATION_POLICY MitigationPolicy, IntPtr lpBuffer, SizeT dwLength);
/// <summary>Retrieves mitigation policy settings for the calling process.</summary>
/// <typeparam name="T">The type of the value to retrieve.</typeparam>
/// <param name="hProcess">
/// A handle to the process. This handle must have the PROCESS_QUERY_INFORMATION access right. For more information, see Process Security
/// and Access Rights.
/// </param>
/// <param name="MitigationPolicy">
/// <para>The mitigation policy to retrieve. This parameter can be one of the following values.</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>ProcessDEPPolicy</term>
/// <term>
/// The data execution prevention (DEP) policy of the process.The lpBuffer parameter points to a PROCESS_MITIGATION_DEP_POLICY structure
/// that specifies the DEP policy flags.
/// </term>
/// </item>
/// <item>
/// <term>ProcessASLRPolicy</term>
/// <term>
/// The Address Space Layout Randomization (ASLR) policy of the process.The lpBuffer parameter points to a PROCESS_MITIGATION_ASLR_POLICY
/// structure that specifies the ASLR policy flags.
/// </term>
/// </item>
/// <item>
/// <term>ProcessDynamicCodePolicy</term>
/// <term>
/// The dynamic code policy of the process. When turned on, the process cannot generate dynamic code or modify existing executable
/// code.The lpBuffer parameter points to a PROCESS_MITIGATION_DYNAMIC_CODE_POLICY structure that specifies the dynamic code policy flags.
/// </term>
/// </item>
/// <item>
/// <term>ProcessStrictHandleCheckPolicy</term>
/// <term>
/// The process will receive a fatal error if it manipulates a handle that is not valid.The lpBuffer parameter points to a
/// PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY structure that specifies the handle check policy flags.
/// </term>
/// </item>
/// <item>
/// <term>ProcessSystemCallDisablePolicy</term>
/// <term>
/// Disables the ability to use NTUser/GDI functions at the lowest layer.The lpBuffer parameter points to a
/// PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY structure that specifies the system call disable policy flags.
/// </term>
/// </item>
/// <item>
/// <term>ProcessMitigationOptionsMask</term>
/// <term>
/// Returns the mask of valid bits for all the mitigation options on the system. An application can set many mitigation options without
/// querying the operating system for mitigation options by combining bitwise with the mask to exclude all non-supported bits at once.The
/// lpBuffer parameter points to a ULONG64 bit vector for the mask, or a two-element array of ULONG64 bit vectors.
/// </term>
/// </item>
/// <item>
/// <term>ProcessExtensionPointDisablePolicy</term>
/// <term>
/// Prevents certain built-in third party extension points from being enabled, preventing legacy extension point DLLs from being loaded
/// into the process.The lpBuffer parameter points to a PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY structure that specifies the
/// extension point disable policy flags.
/// </term>
/// </item>
/// <item>
/// <term>ProcessControlFlowGuardPolicy</term>
/// <term>
/// The Control Flow Guard (CFG) policy of the process.The lpBuffer parameter points to a PROCESS_MITIGATION_CONTROL_FLOW_GUARD_POLICY
/// structure that specifies the CFG policy flags.
/// </term>
/// </item>
/// <item>
/// <term>ProcessSignaturePolicy</term>
/// <term>
/// The policy of a process that can restrict image loading to those images that are either signed by Microsoft, by the Windows Store, or
/// by Microsoft, the Windows Store and the Windows Hardware Quality Labs (WHQL).he lpBuffer parameter points to a
/// PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY structure that specifies the signature policy flags.
/// </term>
/// </item>
/// <item>
/// <term>ProcessFontDisablePolicy</term>
/// <term>
/// The policy regarding font loading for the process. When turned on, the process cannot load non-system fonts.The lpBuffer parameter
/// points to a PROCESS_MITIGATION_FONT_DISABLE_POLICY structure that specifies the policy flags for font loading.
/// </term>
/// </item>
/// <item>
/// <term>ProcessImageLoadPolicy</term>
/// <term>
/// The policy regarding image loading for the process, which determines the types of executable images that are allowed to be mapped
/// into the process. When turned on, images cannot be loaded from some locations, such a remote devices or files that have the low
/// mandatory label.The lpBuffer parameter points to a PROCESS_MITIGATION_IMAGE_LOAD_POLICY structure that specifies the policy flags for
/// image loading.
/// </term>
/// </item>
/// </list>
/// </para>
/// </param>
/// <param name="value">The value.</param>
/// <returns>
/// If the function succeeds, it returns <c>TRUE</c>. If the function fails, it returns <c>FALSE</c>. To retrieve error values defined
/// for this function, call <c>GetLastError</c>.
/// </returns>
/// <exception cref="ArgumentException"></exception>
public static bool GetProcessMitigationPolicy<T>(HPROCESS hProcess, PROCESS_MITIGATION_POLICY MitigationPolicy, out T value)
{
bool isMask = MitigationPolicy == PROCESS_MITIGATION_POLICY.ProcessMitigationOptionsMask;
if (!isMask && !CorrespondingTypeAttribute.CanGet(MitigationPolicy, typeof(T))) throw new ArgumentException($"{MitigationPolicy} cannot be used to get values of type {typeof(T)}.");
int sz = isMask ? 16 : Marshal.SizeOf(typeof(T));
using (SafeCoTaskMemHandle ptr = new(sz))
{
if (!isMask)
{
if (GetProcessMitigationPolicy(hProcess, MitigationPolicy, (IntPtr)ptr, (uint)ptr.Size))
{
value = ptr.ToStructure<T>();
return true;
}
}
else
{
if (GetProcessMitigationPolicy(hProcess, MitigationPolicy, (IntPtr)ptr, (uint)ptr.Size))
{
value = (T)(object)ptr.ToArray<ulong>(2);
return true;
}
else if (GetProcessMitigationPolicy(hProcess, MitigationPolicy, (IntPtr)ptr, 8))
{
value = (T)(object)ptr.ToArray<ulong>(1);
return true;
}
}
2018-10-26 14:24:07 -04:00
}
value = default;
return false;
}
2018-05-13 23:41:49 -04:00
/// <summary>Retrieves the priority boost control state of the specified process.</summary>
/// <param name="hProcess">
/// <para>
/// A handle to the process. This handle must have the <c>PROCESS_QUERY_INFORMATION</c> or <c>PROCESS_QUERY_LIMITED_INFORMATION</c>
/// access right. For more information, see Process Security and Access Rights.
/// </para>
/// <para><c>Windows Server 2003 and Windows XP:</c> The handle must have the <c>PROCESS_QUERY_INFORMATION</c> access right.</para>
/// </param>
/// <param name="pDisablePriorityBoost">
/// A pointer to a variable that receives the priority boost control state. A value of TRUE indicates that dynamic boosting is disabled.
/// A value of FALSE indicates normal behavior.
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, the return value is nonzero. In that case, the variable pointed to by the pDisablePriorityBoost parameter
/// receives the priority boost control state.
/// </para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL WINAPI GetProcessPriorityBoost( _In_ HANDLE hProcess, _Out_ PBOOL pDisablePriorityBoost); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683220(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms683220")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetProcessPriorityBoost([In] HPROCESS hProcess, [MarshalAs(UnmanagedType.Bool)] out bool pDisablePriorityBoost);
/// <summary>Retrieves the shutdown parameters for the currently calling process.</summary>
/// <param name="lpdwLevel">
/// <para>
/// A pointer to a variable that receives the shutdown priority level. Higher levels shut down first. System level shutdown orders are
/// reserved for system components. Higher numbers shut down first. Following are the level conventions.
/// </para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>000-0FF</term>
/// <term>System reserved last shutdown range.</term>
/// </item>
/// <item>
/// <term>100-1FF</term>
/// <term>Application reserved last shutdown range.</term>
/// </item>
/// <item>
/// <term>200-2FF</term>
/// <term>Application reserved &amp;quot;in between&amp;quot; shutdown range.</term>
/// </item>
/// <item>
/// <term>300-3FF</term>
/// <term>Application reserved first shutdown range.</term>
/// </item>
/// <item>
/// <term>400-4FF</term>
/// <term>System reserved first shutdown range.</term>
/// </item>
/// </list>
/// </para>
/// <para>All processes start at shutdown level 0x280.</para>
/// </param>
/// <param name="lpdwFlags">
/// <para>A pointer to a variable that receives the shutdown flags. This parameter can be the following value.</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>SHUTDOWN_NORETRY0x00000001</term>
/// <term>
/// If this process takes longer than the specified timeout to shut down, do not display a retry dialog box for the user. Instead, just
/// cause the process to directly exit.
/// </term>
/// </item>
/// </list>
/// </para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL WINAPI GetProcessShutdownParameters( _Out_ LPDWORD lpdwLevel, _Out_ LPDWORD lpdwFlags); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683221(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms683221")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetProcessShutdownParameters(out uint lpdwLevel, out SHUTDOWN lpdwFlags);
/// <summary>Retrieves timing information for the specified process.</summary>
/// <param name="hProcess">
/// <para>
/// A handle to the process whose timing information is sought. The handle must have the <c>PROCESS_QUERY_INFORMATION</c> or
/// <c>PROCESS_QUERY_LIMITED_INFORMATION</c> access right. For more information, see Process Security and Access Rights.
/// </para>
/// <para><c>Windows Server 2003 and Windows XP:</c> The handle must have the <c>PROCESS_QUERY_INFORMATION</c> access right.</para>
/// </param>
/// <param name="lpCreationTime">A pointer to a <c>FILETIME</c> structure that receives the creation time of the process.</param>
/// <param name="lpExitTime">
/// A pointer to a <c>FILETIME</c> structure that receives the exit time of the process. If the process has not exited, the content of
/// this structure is undefined.
/// </param>
/// <param name="lpKernelTime">
/// A pointer to a <c>FILETIME</c> structure that receives 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.
/// </param>
/// <param name="lpUserTime">
/// A pointer to a <c>FILETIME</c> structure that receives 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.
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL WINAPI GetProcessTimes( _In_ HANDLE hProcess, _Out_ LPFILETIME lpCreationTime, _Out_ LPFILETIME lpExitTime, _Out_ LPFILETIME
// lpKernelTime, _Out_ LPFILETIME lpUserTime); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683223(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms683223")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetProcessTimes([In] HPROCESS hProcess, out FILETIME lpCreationTime, out FILETIME lpExitTime, out FILETIME lpKernelTime,
out FILETIME lpUserTime);
/// <summary>Retrieves the major and minor version numbers of the system on which the specified process expects to run.</summary>
/// <param name="ProcessId">The process identifier of the process of interest. A value of zero specifies the calling process.</param>
/// <returns>
/// <para>
/// If the function succeeds, the return value is the version of the system on which the process expects to run. The high word of the
/// return value contains the major version number. The low word of the return value contains the minor version number.
/// </para>
/// <para>
/// If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>. The function fails if
/// ProcessId is an invalid value.
/// </para>
/// </returns>
// DWORD WINAPI GetProcessVersion( _In_ DWORD ProcessId); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683224(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms683224")]
public static extern uint GetProcessVersion(uint ProcessId = 0);
/// <summary>Retrieves the contents of the <c>STARTUPINFO</c> structure that was specified when the calling process was created.</summary>
/// <param name="lpStartupInfo">A pointer to a <c>STARTUPINFO</c> structure that receives the startup information.</param>
/// <returns>
/// <para>This function does not return a value.</para>
/// <para>
/// If an error occurs, the ANSI version of this function ( <c>GetStartupInfoA</c>) can raise an exception. The Unicode version (
/// <c>GetStartupInfoW</c>) does not fail.
/// </para>
/// </returns>
// VOID WINAPI GetStartupInfo( _Out_ LPSTARTUPINFO lpStartupInfo); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683230(v=vs.85).aspx
[PInvokeData("WinBase.h", MSDNShortId = "ms683230")]
public static void GetStartupInfo(out STARTUPINFO lpStartupInfo)
{ GetStartupInfo(out STARTUPINFO_OUT sio); lpStartupInfo = sio; }
/// <summary>Allows an application to query the available CPU Sets on the system, and their current state.</summary>
/// <param name="Information">
/// A pointer to a <c>SYSTEM_CPU_SET_INFORMATION</c> structure that receives the CPU Set data. Pass NULL with a buffer length of 0 to
/// determine the required buffer size.
/// </param>
/// <param name="BufferLength">The length, in bytes, of the output buffer passed as the Information argument.</param>
/// <param name="ReturnedLength">
/// The length, in bytes, of the valid data in the output buffer if the buffer is large enough, or the required size of the output
/// buffer. If no CPU Sets exist, this value will be 0.
/// </param>
/// <param name="Process">
/// An optional handle to a process. This process is used to determine the value of the <c>AllocatedToTargetProcess</c> flag in the
/// SYSTEM_CPU_SET_INFORMATION structure. If a CPU Set is allocated to the specified process, the flag is set. Otherwise, it is clear.
/// This handle must have the PROCESS_QUERY_LIMITED_INFORMATION access right. The value returned by <c>GetCurrentProcess</c> may also be
/// specified here.
/// </param>
/// <param name="Flags">Reserved, must be 0.</param>
/// <returns>
/// If the API succeeds it returns TRUE. If it fails, the error reason is available through <c>GetLastError</c>. If the Information
/// buffer was NULL or not large enough, the error code ERROR_INSUFFICIENT_BUFFER is returned. This API cannot fail when passed valid
/// parameters and a buffer that is large enough to hold all of the return data.
/// </returns>
// BOOL WINAPI GetSystemCpuSetInformation( _Out_opt_ PSYSTEM_CPU_SET_INFORMATION Information, _In_ ULONG BufferLength, _Out_ PULONG
// ReturnedLength, _In_opt_ HANDLE Process, _Reserved_ ULONG Flags); https://msdn.microsoft.com/en-us/library/windows/desktop/mt186425(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("Processthreadapi.h", MSDNShortId = "mt186425")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetSystemCpuSetInformation(IntPtr Information, uint BufferLength, out uint ReturnedLength, [Optional] HPROCESS Process, [Optional] uint Flags);
/// <summary>Allows an application to query the available CPU Sets on the system, and their current state.</summary>
/// <param name="Process">
/// An optional handle to a process. This process is used to determine the value of the <c>AllocatedToTargetProcess</c> flag in the
/// SYSTEM_CPU_SET_INFORMATION structure. If a CPU Set is allocated to the specified process, the flag is set. Otherwise, it is clear.
/// This handle must have the PROCESS_QUERY_LIMITED_INFORMATION access right. The value returned by <c>GetCurrentProcess</c> may also be
/// specified here.
/// </param>
/// <returns>A list of <c>SYSTEM_CPU_SET_INFORMATION</c> structures with CPU Set data.</returns>
public static IEnumerable<SYSTEM_CPU_SET_INFORMATION> GetSystemCpuSetInformation([Optional] HPROCESS Process)
{
if (!GetSystemCpuSetInformation(IntPtr.Zero, 0, out uint sz, Process) || sz == 0)
{
Win32Error err = Win32Error.GetLastError();
if (err != Win32Error.ERROR_INSUFFICIENT_BUFFER) throw err.GetException();
}
using SafeCoTaskMemHandle ptr = new((int)sz);
if (!GetSystemCpuSetInformation((IntPtr)ptr, sz, out sz, Process))
Win32Error.ThrowLastError();
int offset = 0;
while (offset < sz)
2018-05-13 23:41:49 -04:00
{
IntPtr sptr = ptr.DangerousGetHandle().Offset(offset);
int structSize = Marshal.ReadInt32(sptr);
yield return sptr.ToStructure<SYSTEM_CPU_SET_INFORMATION>(sz - offset);
offset += structSize;
2018-05-13 23:41:49 -04:00
}
}
2018-05-13 23:41:49 -04:00
/// <summary>
/// Retrieves system timing information. On a multiprocessor system, the values returned are the sum of the designated times across all processors.
/// </summary>
/// <param name="lpIdleTime">A pointer to a <c>FILETIME</c> structure that receives the amount of time that the system has been idle.</param>
/// <param name="lpKernelTime">
/// A pointer to a <c>FILETIME</c> structure that receives the amount of time that the system has spent executing in Kernel mode
/// (including all threads in all processes, on all processors). This time value also includes the amount of time the system has been idle.
/// </param>
/// <param name="lpUserTime">
/// A pointer to a <c>FILETIME</c> structure that receives the amount of time that the system has spent executing in User mode (including
/// all threads in all processes, on all processors).
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL WINAPI GetSystemTimes( _Out_opt_ LPFILETIME lpIdleTime, _Out_opt_ LPFILETIME lpKernelTime, _Out_opt_ LPFILETIME lpUserTime); https://msdn.microsoft.com/en-us/library/windows/desktop/ms724400(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("Winbase.h", MSDNShortId = "ms724400")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetSystemTimes(out FILETIME lpIdleTime, out FILETIME lpKernelTime, out FILETIME lpUserTime);
/// <summary>
/// <para>Retrieves the context of the specified thread.</para>
/// <para>A 64-bit application can retrieve the context of a WOW64 thread using the <c>Wow64GetThreadContext</c> function.</para>
/// </summary>
/// <param name="hThread">
/// <para>
/// A handle to the thread whose context is to be retrieved. The handle must have <c>THREAD_GET_CONTEXT</c> access to the thread. For
/// more information, see Thread Security and Access Rights.
/// </para>
/// <para><c>WOW64:</c> The handle must also have <c>THREAD_QUERY_INFORMATION</c> access.</para>
/// </param>
/// <param name="lpContext">
/// A pointer to a <c>CONTEXT</c> structure that receives the appropriate context of the specified thread. The value of the
/// <c>ContextFlags</c> member of this structure specifies which portions of a thread's context are retrieved. The <c>CONTEXT</c>
/// structure is highly processor specific. Refer to the WinNT.h header file for processor-specific definitions of this structures and
/// any alignment requirements.
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL WINAPI GetThreadContext( _In_ HANDLE hThread, _Inout_ LPCONTEXT lpContext); https://msdn.microsoft.com/en-us/library/windows/desktop/ms679362(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms679362")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetThreadContext([In] HTHREAD hThread, ref CONTEXT lpContext);
/// <summary>Retrieves the description that was assigned to a thread by calling SetThreadDescription.</summary>
/// <param name="hThread">
/// A handle to the thread for which to retrieve the description. The handle must have THREAD_QUERY_LIMITED_INFORMATION access.
/// </param>
/// <param name="ppszThreadDescription">A Unicode string that contains the description of the thread.</param>
/// <returns>
/// If the function succeeds, the return value is the <c>HRESULT</c> that denotes a successful operation. If the function fails, the
/// return value is an <c>HRESULT</c> that denotes the error.
/// </returns>
/// <remarks>
/// <para>
/// The description for a thread can change at any time. For example, a different thread can change the description of a thread of
/// interest while you try to retrieve that description.
/// </para>
/// <para>Thread descriptions do not need to be unique.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getthreaddescription HRESULT
// GetThreadDescription( HANDLE hThread, PWSTR *ppszThreadDescription );
[DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("processthreadsapi.h", MSDNShortId = "9CFF0A2D-2196-4AE0-8F77-229A8AB7A3E8")]
public static extern HRESULT GetThreadDescription(HTHREAD hThread, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LocalStringMarshaler))] out string ppszThreadDescription);
/// <summary>Retrieves the thread identifier of the specified thread.</summary>
/// <param name="Thread">
/// <para>
/// A handle to the thread. The handle must have the THREAD_QUERY_INFORMATION or THREAD_QUERY_LIMITED_INFORMATION access right. For more
/// information about access rights, see Thread Security and Access Rights.
/// </para>
/// <para><c>Windows Server 2003:</c> The handle must have the THREAD_QUERY_INFORMATION access right.</para>
/// </param>
/// <returns>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</returns>
// DWORD WINAPI GetThreadId( _In_ HANDLE Thread); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683233(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms683233")]
public static extern uint GetThreadId(HTHREAD Thread);
/// <summary>Retrieves the processor number of the ideal processor for the specified thread.</summary>
/// <param name="hThread">
/// A handle to the thread for which to retrieve the ideal processor. This handle must have been created with the
/// THREAD_QUERY_LIMITED_INFORMATION access right. For more information, see Thread Security and Access Rights.
/// </param>
/// <param name="lpIdealProcessor">Points to <c>PROCESSOR_NUMBER</c> structure to receive the number of the ideal processor.</param>
/// <returns>
/// <para>If the function succeeds, it returns a nonzero value.</para>
/// <para>If the function fails, it returns zero. To get extended error information, use <c>GetLastError</c>.</para>
/// </returns>
// BOOL GetThreadIdealProcessorEx( _In_ HANDLE hThread, _Out_ PPROCESSOR_NUMBER lpIdealProcessor); https://msdn.microsoft.com/en-us/library/windows/desktop/dd405499(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "dd405499")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetThreadIdealProcessorEx(HTHREAD hThread, out PROCESSOR_NUMBER lpIdealProcessor);
/// <summary>Retrieves information about the specified thread.</summary>
/// <param name="hThread">
/// A handle to the thread. The handle must have THREAD_QUERY_INFORMATION access rights. For more information, see Thread Security and
/// Access Rights.
/// </param>
/// <param name="ThreadInformationClass">
/// The class of information to retrieve. The only supported values are <c>ThreadMemoryPriority</c> and <c>ThreadPowerThrottling</c>.
/// </param>
/// <param name="ThreadInformation">
/// <para>Pointer to a structure to receive the type of information specified by the ThreadInformationClass parameter.</para>
/// <para>
/// If the ThreadInformationClass parameter is <c>ThreadMemoryPriority</c>, this parameter must point to a
/// <c>MEMORY_PRIORITY_INFORMATION</c> structure.
/// </para>
/// <para>
/// If the ThreadInformationClass parameter is <c>ThreadPowerThrottling</c>, this parameter must point to a
/// <c>THREAD_POWER_THROTTLING_STATE</c> structure.
/// </para>
/// </param>
/// <param name="ThreadInformationSize">
/// <para>The size in bytes of the structure specified by the ThreadInformation parameter.</para>
/// <para>If the ThreadInformationClass parameter is <c>ThreadMemoryPriority</c>, this parameter must be .</para>
/// <para>If the ThreadInformationClass parameter is <c>ThreadPowerThrottling</c>, this parameter must be .</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL GetThreadInformation( _In_ HANDLE hThread, _In_ THREAD_INFORMATION_CLASS ThreadInformationClass, _Out_writes_bytes_
// ThreadInformation, _In_ DWORD ThreadInformationSize);// https://msdn.microsoft.com/en-us/library/windows/desktop/hh448382(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "hh448382")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetThreadInformation(HTHREAD hThread, THREAD_INFORMATION_CLASS ThreadInformationClass, IntPtr ThreadInformation, uint ThreadInformationSize);
/// <summary>Retrieves information about the specified thread.</summary>
/// <param name="hThread">
/// A handle to the thread. The handle must have THREAD_QUERY_INFORMATION access rights. For more information, see Thread Security and
/// Access Rights.
/// </param>
/// <param name="ThreadInformationClass">
/// The class of information to retrieve. The only supported values are <c>ThreadMemoryPriority</c> and <c>ThreadPowerThrottling</c>.
/// </param>
/// <returns>
/// <para>A structure that receives the type of information specified by the ThreadInformationClass parameter.</para>
/// <para>
/// If the ThreadInformationClass parameter is <c>ThreadMemoryPriority</c>, this parameter must point to a
/// <c>MEMORY_PRIORITY_INFORMATION</c> structure.
/// </para>
/// <para>
/// If the ThreadInformationClass parameter is <c>ThreadPowerThrottling</c>, this parameter must point to a
/// <c>THREAD_POWER_THROTTLING_STATE</c> structure.
/// </para>
/// </returns>
[PInvokeData("WinBase.h", MSDNShortId = "hh448382")]
public static T GetThreadInformation<T>(HTHREAD hThread, THREAD_INFORMATION_CLASS ThreadInformationClass) where T : struct
{
if (!CorrespondingTypeAttribute.CanGet(ThreadInformationClass, typeof(T))) throw new ArgumentException($"{ThreadInformationClass} cannot be used to get values of type {typeof(T)}.");
using SafeHGlobalHandle mem = SafeHGlobalHandle.CreateFromStructure(ReflectionExtensions.CreateOrDefault<T>());
if (!GetThreadInformation(hThread, ThreadInformationClass, (IntPtr)mem, (uint)mem.Size))
Win32Error.ThrowLastError();
return mem.ToStructure<T>();
}
/// <summary>Determines whether a specified thread has any I/O requests pending.</summary>
/// <param name="hThread">
/// A handle to the thread in question. This handle must have been created with the THREAD_QUERY_INFORMATION access right. For more
/// information, see Thread Security and Access Rights.
/// </param>
/// <param name="lpIOIsPending">
/// A pointer to a variable which the function sets to TRUE if the specified thread has one or more I/O requests pending, or to FALSE otherwise.
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL WINAPI GetThreadIOPendingFlag( _In_ HANDLE hThread, _Inout_ PBOOL lpIOIsPending); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683234(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms683234")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetThreadIOPendingFlag([In] HTHREAD hThread, [MarshalAs(UnmanagedType.Bool)] out bool lpIOIsPending);
/// <summary>
/// Retrieves the priority value for the specified thread. This value, together with the priority class of the thread's process,
/// determines the thread's base-priority level.
/// </summary>
/// <param name="hThread">
/// <para>A handle to the thread.</para>
/// <para>
/// The handle must have the <c>THREAD_QUERY_INFORMATION</c> or <c>THREAD_QUERY_LIMITED_INFORMATION</c> access right. For more
/// information, see Thread Security and Access Rights.
/// </para>
/// <para><c>Windows Server 2003:</c> The handle must have the <c>THREAD_QUERY_INFORMATION</c> access right.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is the thread's priority level.</para>
/// <para>If the function fails, the return value is <c>THREAD_PRIORITY_ERROR_RETURN</c>. To get extended error information, call <c>GetLastError</c>.</para>
/// <para><c>Windows Phone 8.1:</c> This function will always return <c>THREAD_PRIORITY_NORMAL</c>.</para>
/// <para>The thread's priority level is one of the following values.</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Return code/value</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>THREAD_PRIORITY_ABOVE_NORMAL1</term>
/// <term>Priority 1 point above the priority class.</term>
/// </item>
/// <item>
/// <term>THREAD_PRIORITY_BELOW_NORMAL-1</term>
/// <term>Priority 1 point below the priority class.</term>
/// </item>
/// <item>
/// <term>THREAD_PRIORITY_HIGHEST2</term>
/// <term>Priority 2 points above the priority class.</term>
/// </item>
/// <item>
/// <term>THREAD_PRIORITY_IDLE-15</term>
/// <term>
/// Base priority of 1 for IDLE_PRIORITY_CLASS, BELOW_NORMAL_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS, ABOVE_NORMAL_PRIORITY_CLASS, or
/// HIGH_PRIORITY_CLASS processes, and a base priority of 16 for REALTIME_PRIORITY_CLASS processes.
/// </term>
/// </item>
/// <item>
/// <term>THREAD_PRIORITY_LOWEST-2</term>
/// <term>Priority 2 points below the priority class.</term>
/// </item>
/// <item>
/// <term>THREAD_PRIORITY_NORMAL0</term>
/// <term>Normal priority for the priority class.</term>
/// </item>
/// <item>
/// <term>THREAD_PRIORITY_TIME_CRITICAL15</term>
/// <term>
/// Base-priority level of 15 for IDLE_PRIORITY_CLASS, BELOW_NORMAL_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS, ABOVE_NORMAL_PRIORITY_CLASS,
/// or HIGH_PRIORITY_CLASS processes, and a base-priority level of 31 for REALTIME_PRIORITY_CLASS processes.
/// </term>
/// </item>
/// </list>
/// </para>
/// <para>
/// If the thread has the <c>REALTIME_PRIORITY_CLASS</c> base class, this function can also return one of the following values: -7,
/// -6, -5, -4, -3, 3, 4, 5, or 6. For more information, see Scheduling Priorities.
/// </para>
/// </returns>
// int WINAPI GetThreadPriority( _In_ HANDLE hThread);// https://msdn.microsoft.com/en-us/library/windows/desktop/ms683235(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms683235")]
public static extern int GetThreadPriority([In] HTHREAD hThread);
/// <summary>Retrieves the priority boost control state of the specified thread.</summary>
/// <param name="hThread">
/// <para>
/// A handle to the thread. The handle must have the <c>THREAD_QUERY_INFORMATION</c> or <c>THREAD_QUERY_LIMITED_INFORMATION</c> access
/// right. For more information, see Thread Security and Access Rights.
/// </para>
/// <para><c>Windows Server 2003 and Windows XP:</c> The handle must have the <c>THREAD_QUERY_INFORMATION</c> access right.</para>
/// </param>
/// <param name="pDisablePriorityBoost">
/// A pointer to a variable that receives the priority boost control state. A value of TRUE indicates that dynamic boosting is disabled.
/// A value of FALSE indicates normal behavior.
/// </param>
/// <returns>
/// <para>
/// If the function succeeds, the return value is nonzero. In that case, the variable pointed to by the pDisablePriorityBoost parameter
/// receives the priority boost control state.
/// </para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL WINAPI GetThreadPriorityBoost( _In_ HANDLE hThread, _Out_ PBOOL pDisablePriorityBoost); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683236(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms683236")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetThreadPriorityBoost([In] HTHREAD hThread, [MarshalAs(UnmanagedType.Bool)] out bool pDisablePriorityBoost);
/// <summary>
/// Returns the explicit CPU Set assignment of the specified thread, if any assignment was set using the <c>SetThreadSelectedCpuSets</c>
/// API. If no explicit assignment is set, <c>RequiredIdCount</c> is set to 0 and the function returns TRUE.
/// </summary>
/// <param name="Thread">
/// Specifies the thread for which to query the selected CPU Sets. This handle must have the THREAD_QUERY_LIMITED_INFORMATION access
/// right. The value returned by <c>GetCurrentThread</c> can also be specified here.
/// </param>
/// <param name="CpuSetIds">Specifies an optional buffer to retrieve the list of CPU Set identifiers.</param>
/// <param name="CpuSetIdCount">
/// Specifies the capacity of the buffer specified in <c>CpuSetIds</c>. If the buffer is NULL, this must be 0.
/// </param>
/// <param name="RequiredIdCount">
/// Specifies the required capacity of the buffer to hold the entire list of thread selected CPU Sets. On successful return, this
/// specifies the number of IDs filled into the buffer.
/// </param>
/// <returns>
/// This API returns TRUE on success. If the buffer is not large enough, the <c>GetLastError</c> value is ERROR_INSUFFICIENT_BUFFER. This
/// API cannot fail when passed valid parameters and the return buffer is large enough.
/// </returns>
// BOOL WINAPI GetThreadSelectedCpuSets( _In_ HANDLE Thread, _Out_opt_ PULONG CpuSetIds, _In_ ULONG CpuSetIdCount, _Out_ PULONG
// RequiredIdCount); https://msdn.microsoft.com/en-us/library/windows/desktop/mt186426(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("Processthreadapi.h", MSDNShortId = "mt186426")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetThreadSelectedCpuSets(HTHREAD Thread, IntPtr CpuSetIds, uint CpuSetIdCount, out uint RequiredIdCount);
/// <summary>
/// Returns the explicit CPU Set assignment of the specified thread, if any assignment was set using the <c>SetThreadSelectedCpuSets</c>
/// API. If no explicit assignment is set, <c>RequiredIdCount</c> is set to 0 and the function returns TRUE.
/// </summary>
/// <param name="Thread">
/// Specifies the thread for which to query the selected CPU Sets. This handle must have the THREAD_QUERY_LIMITED_INFORMATION access
/// right. The value returned by <c>GetCurrentThread</c> can also be specified here.
/// </param>
/// <returns>The list of CPU Set identifiers.</returns>
[PInvokeData("Processthreadapi.h", MSDNShortId = "mt186426")]
public static uint[] GetThreadSelectedCpuSets(HTHREAD Thread)
{
uint cnt = (uint)Environment.ProcessorCount;
if (cnt == 0) return new uint[0];
SafeCoTaskMemHandle iptr = new((int)cnt * Marshal.SizeOf(typeof(uint)));
if (!GetThreadSelectedCpuSets(Thread, (IntPtr)iptr, cnt, out cnt)) Win32Error.ThrowLastError();
return iptr.ToArray<uint>((int)cnt);
}
/// <summary>Retrieves timing information for the specified thread.</summary>
/// <param name="hThread">
/// <para>
/// A handle to the thread whose timing information is sought. The handle must have the <c>THREAD_QUERY_INFORMATION</c> or
/// <c>THREAD_QUERY_LIMITED_INFORMATION</c> access right. For more information, see Thread Security and Access Rights.
/// </para>
/// <para><c>Windows Server 2003 and Windows XP:</c> The handle must have the <c>THREAD_QUERY_INFORMATION</c> access right.</para>
/// </param>
/// <param name="lpCreationTime">A pointer to a <c>FILETIME</c> structure that receives the creation time of the thread.</param>
/// <param name="lpExitTime">
/// A pointer to a <c>FILETIME</c> structure that receives the exit time of the thread. If the thread has not exited, the content of this
/// structure is undefined.
/// </param>
/// <param name="lpKernelTime">
/// A pointer to a <c>FILETIME</c> structure that receives the amount of time that the thread has executed in kernel mode.
/// </param>
/// <param name="lpUserTime">
/// A pointer to a <c>FILETIME</c> structure that receives the amount of time that the thread has executed in user mode.
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL WINAPI GetThreadTimes( _In_ HANDLE hThread, _Out_ LPFILETIME lpCreationTime, _Out_ LPFILETIME lpExitTime, _Out_ LPFILETIME
// lpKernelTime, _Out_ LPFILETIME lpUserTime);// https://msdn.microsoft.com/en-us/library/windows/desktop/ms683237(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms683237")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetThreadTimes([In] HTHREAD hThread, out FILETIME lpCreationTime, out FILETIME lpExitTime, out FILETIME lpKernelTime,
out FILETIME lpUserTime);
/// <summary>Initializes the specified list of attributes for process and thread creation.</summary>
/// <param name="lpAttributeList">
/// The attribute list. This parameter can be NULL to determine the buffer size required to support the specified number of attributes.
/// </param>
/// <param name="dwAttributeCount">The count of attributes to be added to the list.</param>
/// <param name="dwFlags">This parameter is reserved and must be zero.</param>
/// <param name="lpSize">
/// <para>
/// If lpAttributeList is not NULL, this parameter specifies the size in bytes of the lpAttributeList buffer on input. On output, this
/// parameter receives the size in bytes of the initialized attribute list.
/// </para>
/// <para>If lpAttributeList is NULL, this parameter receives the required buffer size in bytes.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL WINAPI InitializeProcThreadAttributeList( _Out_opt_ LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList, _In_ DWORD dwAttributeCount,
// _Reserved_ DWORD dwFlags, _Inout_ PSIZE_T lpSize); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683481(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms683481")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool InitializeProcThreadAttributeList(IntPtr lpAttributeList, uint dwAttributeCount, [Optional] uint dwFlags, ref SizeT lpSize);
/// <summary>Determines whether the specified process is considered critical.</summary>
/// <param name="hProcess">
/// A handle to the process to query. The process must have been opened with <c>PROCESS_QUERY_LIMITED_INFORMATION</c> access.
/// </param>
/// <param name="Critical">A pointer to the <c>BOOL</c> value this function will use to indicate whether the process is considered critical.</param>
/// <returns>
/// This routine returns FALSE on failure. Any other value indicates success. Call <c>GetLastError</c> to query for the specific error
/// reason on failure.
/// </returns>
// BOOL WINAPI IsProcessCritical( _In_ HANDLE hProcess, _Out_ PBOOL Critical); https://msdn.microsoft.com/en-us/library/windows/desktop/dn386160(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("Processthreadsapi.h", MSDNShortId = "dn386160")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsProcessCritical([In] HPROCESS hProcess, [MarshalAs(UnmanagedType.Bool)] out bool Critical);
/// <summary>Determines whether the specified processor feature is supported by the current computer.</summary>
/// <param name="ProcessorFeature">
/// <para>The processor feature to be tested. This parameter can be one of the following values.</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PF_ARM_64BIT_LOADSTORE_ATOMIC25</term>
/// <term>The 64-bit load/store atomic instructions are available.</term>
/// </item>
/// <item>
/// <term>PF_ARM_DIVIDE_INSTRUCTION_AVAILABLE24</term>
/// <term>The divide instructions are available.</term>
/// </item>
/// <item>
/// <term>PF_ARM_EXTERNAL_CACHE_AVAILABLE26</term>
/// <term>The external cache is available.</term>
/// </item>
/// <item>
/// <term>PF_ARM_FMAC_INSTRUCTIONS_AVAILABLE27</term>
/// <term>The floating-point multiply-accumulate instruction is available.</term>
/// </item>
/// <item>
/// <term>PF_ARM_VFP_32_REGISTERS_AVAILABLE18</term>
/// <term>The VFP/Neon: 32 x 64bit register bank is present. This flag has the same meaning as PF_ARM_VFP_EXTENDED_REGISTERS.</term>
/// </item>
/// <item>
/// <term>PF_3DNOW_INSTRUCTIONS_AVAILABLE7</term>
/// <term>The 3D-Now instruction set is available.</term>
/// </item>
/// <item>
/// <term>PF_CHANNELS_ENABLED16</term>
/// <term>The processor channels are enabled.</term>
/// </item>
/// <item>
/// <term>PF_COMPARE_EXCHANGE_DOUBLE2</term>
/// <term>The atomic compare and exchange operation (cmpxchg) is available.</term>
/// </item>
/// <item>
/// <term>PF_COMPARE_EXCHANGE12814</term>
/// <term>
/// The atomic compare and exchange 128-bit operation (cmpxchg16b) is available.Windows Server 2003 and Windows XP/2000: This feature is
/// not supported.
/// </term>
/// </item>
/// <item>
/// <term>PF_COMPARE64_EXCHANGE12815</term>
/// <term>
/// The atomic compare 64 and exchange 128-bit operation (cmp8xchg16) is available.Windows Server 2003 and Windows XP/2000: This feature
/// is not supported.
/// </term>
/// </item>
/// <item>
/// <term>PF_FASTFAIL_AVAILABLE23</term>
/// <term>_fastfail() is available.</term>
/// </item>
/// <item>
/// <term>PF_FLOATING_POINT_EMULATED1</term>
/// <term>
/// Floating-point operations are emulated using a software emulator.This function returns a nonzero value if floating-point operations
/// are emulated; otherwise, it returns zero.
/// </term>
/// </item>
/// <item>
/// <term>PF_FLOATING_POINT_PRECISION_ERRATA0</term>
/// <term>On a Pentium, a floating-point precision error can occur in rare circumstances.</term>
/// </item>
/// <item>
/// <term>PF_MMX_INSTRUCTIONS_AVAILABLE3</term>
/// <term>The MMX instruction set is available.</term>
/// </item>
/// <item>
/// <term>PF_NX_ENABLED12</term>
/// <term>
/// Data execution prevention is enabled.Windows XP/2000: This feature is not supported until Windows XP with SP2 and Windows Server 2003
/// with SP1.
/// </term>
/// </item>
/// <item>
/// <term>PF_PAE_ENABLED9</term>
/// <term>
/// The processor is PAE-enabled. For more information, see Physical Address Extension.All x64 processors always return a nonzero value
/// for this feature.
/// </term>
/// </item>
/// <item>
/// <term>PF_RDTSC_INSTRUCTION_AVAILABLE8</term>
/// <term>The RDTSC instruction is available.</term>
/// </item>
/// <item>
/// <term>PF_RDWRFSGSBASE_AVAILABLE22</term>
/// <term>RDFSBASE, RDGSBASE, WRFSBASE, and WRGSBASE instructions are available.</term>
/// </item>
/// <item>
/// <term>PF_SECOND_LEVEL_ADDRESS_TRANSLATION20</term>
/// <term>Second Level Address Translation is supported by the hardware.</term>
/// </item>
/// <item>
/// <term>PF_SSE3_INSTRUCTIONS_AVAILABLE13</term>
/// <term>The SSE3 instruction set is available.Windows Server 2003 and Windows XP/2000: This feature is not supported.</term>
/// </item>
/// <item>
/// <term>PF_VIRT_FIRMWARE_ENABLED21</term>
/// <term>Virtualization is enabled in the firmware.</term>
/// </item>
/// <item>
/// <term>PF_XMMI_INSTRUCTIONS_AVAILABLE6</term>
/// <term>The SSE instruction set is available.</term>
/// </item>
/// <item>
/// <term>PF_XMMI64_INSTRUCTIONS_AVAILABLE10</term>
/// <term>The SSE2 instruction set is available.Windows 2000: This feature is not supported.</term>
/// </item>
/// <item>
/// <term>PF_XSAVE_ENABLED17</term>
/// <term>
/// The processor implements the XSAVE and XRSTOR instructions.Windows Server 2008, Windows Vista, Windows Server 2003 and Windows
/// XP/2000: This feature is not supported until Windows 7 and Windows Server 2008 R2.
/// </term>
/// </item>
/// </list>
/// </para>
/// </param>
/// <returns>
/// <para>If the feature is supported, the return value is a nonzero value.</para>
/// <para>If the feature is not supported, the return value is zero.</para>
/// <para>
/// If the HAL does not support detection of the feature, whether or not the hardware supports the feature, the return value is also zero.
/// </para>
/// </returns>
// BOOL WINAPI IsProcessorFeaturePresent( _In_ DWORD ProcessorFeature); https://msdn.microsoft.com/en-us/library/windows/desktop/ms724482(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("Winbase.h", MSDNShortId = "ms724482")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsProcessorFeaturePresent(PROCESSOR_FEATURE ProcessorFeature);
/// <summary>Opens an existing local process object.</summary>
/// <param name="dwDesiredAccess">
/// <para>
/// The access to the process object. This access right is checked against the security descriptor for the process. This parameter can be
/// one or more of the process access rights.
/// </para>
/// <para>
/// If the caller has enabled the SeDebugPrivilege privilege, the requested access is granted regardless of the contents of the security descriptor.
/// </para>
/// </param>
/// <param name="bInheritHandle">
/// If this value is TRUE, processes created by this process will inherit the handle. Otherwise, the processes do not inherit this handle.
/// </param>
/// <param name="dwProcessId">
/// <para>The identifier of the local process to be opened.</para>
/// <para>
/// If the specified process is the System Process (0x00000000), the function fails and the last error code is ERROR_INVALID_PARAMETER.
/// If the specified process is the Idle process or one of the CSRSS processes, this function fails and the last error code is
/// ERROR_ACCESS_DENIED because their access restrictions prevent user-level code from opening them.
/// </para>
/// <para>
/// If you are using <c>GetCurrentProcessId</c> as an argument to this function, consider using <c>GetCurrentProcess</c> instead of
/// OpenProcess, for improved performance.
/// </para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is an open handle to the specified process.</para>
/// <para>If the function fails, the return value is NULL. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// HANDLE WINAPI OpenProcess( _In_ DWORD dwDesiredAccess, _In_ BOOL bInheritHandle, _In_ DWORD dwProcessId); https://msdn.microsoft.com/en-us/library/windows/desktop/ms684320(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms684320")]
public static extern SafeHPROCESS OpenProcess(ACCESS_MASK dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwProcessId);
/// <summary>Opens an existing thread object.</summary>
/// <param name="dwDesiredAccess">
/// <para>
/// The access to the thread object. This access right is checked against the security descriptor for the thread. This parameter can be
/// one or more of the thread access rights.
/// </para>
/// <para>
/// If the caller has enabled the SeDebugPrivilege privilege, the requested access is granted regardless of the contents of the security descriptor.
/// </para>
/// </param>
/// <param name="bInheritHandle">
/// If this value is TRUE, processes created by this process will inherit the handle. Otherwise, the processes do not inherit this handle.
/// </param>
/// <param name="dwThreadId">The identifier of the thread to be opened.</param>
/// <returns>
/// <para>If the function succeeds, the return value is an open handle to the specified thread.</para>
/// <para>If the function fails, the return value is NULL. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// HANDLE WINAPI OpenThread( _In_ DWORD dwDesiredAccess, _In_ BOOL bInheritHandle, _In_ DWORD dwThreadId); https://msdn.microsoft.com/en-us/library/windows/desktop/ms684335(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms684335")]
public static extern SafeHTHREAD OpenThread(ACCESS_MASK dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwThreadId);
/// <summary>Retrieves the Remote Desktop Services session associated with a specified process.</summary>
/// <param name="dwProcessId">
/// Specifies a process identifier. Use the <c>GetCurrentProcessId</c> function to retrieve the process identifier for the current process.
/// </param>
/// <param name="pSessionId">
/// Pointer to a variable that receives the identifier of the Remote Desktop Services session under which the specified process is
/// running. To retrieve the identifier of the session currently attached to the console, use the <c>WTSGetActiveConsoleSessionId</c> function.
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is a nonzero value.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL ProcessIdToSessionId( _In_ DWORD dwProcessId, _Out_ DWORD *pSessionId ); https://msdn.microsoft.com/en-us/library/aa382990(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("Winbase.h", MSDNShortId = "aa382990")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ProcessIdToSessionId(uint dwProcessId, out uint pSessionId);
/// <summary>Retrieves the affinity update mode of the specified process.</summary>
/// <param name="ProcessHandle">
/// A handle to the process. The handle must have the PROCESS_QUERY_INFORMATION or PROCESS_QUERY_LIMITED_INFORMATION access right. For
/// more information, see Process Security and Access Rights.
/// </param>
/// <param name="lpdwFlags">
/// <para>The affinity update mode. This parameter can be one of the following values.</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>0</term>
/// <term>Dynamic update of the process affinity by the system is disabled.</term>
/// </item>
/// <item>
/// <term>PROCESS_AFFINITY_ENABLE_AUTO_UPDATE0x00000001UL</term>
/// <term>Dynamic update of the process affinity by the system is enabled.</term>
/// </item>
/// </list>
/// </para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL WINAPI QueryProcessAffinityUpdateMode( _In_ HANDLE ProcessHandle, _Out_opt_ DWORD lpdwFlags); https://msdn.microsoft.com/en-us/library/windows/desktop/bb309062(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "bb309062")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool QueryProcessAffinityUpdateMode(HPROCESS ProcessHandle, out PROCESS_AFFINITY_MODE lpdwFlags);
/// <summary>Queries the value associated with a protected policy.</summary>
/// <param name="PolicyGuid">The globally-unique identifier of the policy to query.</param>
/// <param name="PolicyValue">Receives the value that the supplied policy is set to.</param>
/// <returns>True if the function succeeds; otherwise, false.</returns>
// BOOL WINAPI QueryProtectedPolicy( _In_ LPCGUID PolicyGuid, _Out_ PULONG_PTR PolicyValue); https://msdn.microsoft.com/en-us/library/windows/desktop/dn893591(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("Winbase.h", MSDNShortId = "dn893591")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool QueryProtectedPolicy(in Guid PolicyGuid, out IntPtr PolicyValue);
/// <summary>Adds a user-mode asynchronous procedure call (APC) object to the APC queue of the specified thread.</summary>
/// <param name="pfnAPC">
/// A pointer to the application-supplied APC function to be called when the specified thread performs an alertable wait operation. For
/// more information, see APCProc.
/// </param>
/// <param name="hThread">
/// A handle to the thread. The handle must have the <c>THREAD_SET_CONTEXT</c> access right. For more information, see Synchronization
/// Object Security and Access Rights.
/// </param>
/// <param name="dwData">A single value that is passed to the APC function pointed to by the pfnAPC parameter.</param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>
/// If the function fails, the return value is zero. To get extended error information, call GetLastError. <c>Windows Server 2003 and
/// Windows XP:</c> There are no error values defined for this function that can be retrieved by calling GetLastError.
/// </para>
/// </returns>
/// <remarks>
/// <para>
/// The APC support provided in the operating system allows an application to queue an APC object to a thread. To ensure successful
/// execution of functions used by the APC, APCs should be queued only to threads in the caller's process.
/// </para>
/// <para>
/// <c>Note</c> Queuing APCs to threads outside the caller's process is not recommended for a number of reasons. DLL rebasing can cause
/// the addresses of functions used by the APC to be incorrect when the functions are executed outside the caller's process. Similarly,
/// if a 64-bit process queues an APC to a 32-bit process or vice versa, addresses will be incorrect and the application will crash.
/// Other factors can prevent successful function execution, even if the address is known.
/// </para>
/// <para>
/// Each thread has its own APC queue. The queuing of an APC is a request for the thread to call the APC function. The operating system
/// issues a software interrupt to direct the thread to call the APC function.
/// </para>
/// <para>
/// When a user-mode APC is queued, the thread is not directed to call the APC function unless it is in an alertable state. After the
/// thread is in an alertable state, the thread handles all pending APCs in first in, first out (FIFO) order, and the wait operation
/// returns <c>WAIT_IO_COMPLETION</c>. A thread enters an alertable state by using SleepEx, SignalObjectAndWait, WaitForSingleObjectEx,
/// WaitForMultipleObjectsEx, or MsgWaitForMultipleObjectsEx to perform an alertable wait operation.
/// </para>
/// <para>
/// If an application queues an APC before the thread begins running, the thread begins by calling the APC function. After the thread
/// calls an APC function, it calls the APC functions for all APCs in its APC queue.
/// </para>
/// <para>
/// It is possible to sleep or wait for an object within the APC. If you perform an alertable wait inside an APC, it will recursively
/// dispatch the APCs. This can cause a stack overflow.
/// </para>
/// <para>
/// When the thread is terminated using the ExitThread or TerminateThread function, the APCs in its APC queue are lost. The APC functions
/// are not called.
/// </para>
/// <para>
/// When the thread is in the process of being terminated, calling QueueUserAPC to add to the thread's APC queue will fail with <c>(31) ERROR_GEN_FAILURE</c>.
/// </para>
/// <para>
/// Note that the ReadFileEx, SetWaitableTimer, and WriteFileEx functions are implemented using an APC as the completion notification
/// callback mechanism.
/// </para>
/// <para>
/// To compile an application that uses this function, define <c>_WIN32_WINNT</c> as 0x0400 or later. For more information, see Using the
/// Windows Headers.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-queueuserapc DWORD QueueUserAPC( PAPCFUNC
// pfnAPC, HANDLE hThread, ULONG_PTR dwData );
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("processthreadsapi.h", MSDNShortId = "5b141372-7c95-4eb2-987b-64fdf7d0783d")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool QueueUserAPC(PAPCFUNC pfnAPC, [In] HTHREAD hThread, IntPtr dwData);
/// <summary>Decrements a thread's suspend count. When the suspend count is decremented to zero, the execution of the thread is resumed.</summary>
/// <param name="hThread">
/// <para>A handle to the thread to be restarted.</para>
/// <para>This handle must have the THREAD_SUSPEND_RESUME access right. For more information, see Thread Security and Access Rights.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is the thread's previous suspend count.</para>
/// <para>If the function fails, the return value is (DWORD) -1. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// DWORD WINAPI ResumeThread( _In_ HANDLE hThread); https://msdn.microsoft.com/en-us/library/windows/desktop/ms685086(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms685086")]
public static extern uint ResumeThread([In] HTHREAD hThread);
/// <summary>
/// Sets the priority class for the specified process. This value together with the priority value of each thread of the process
/// determines each thread's base priority level.
/// </summary>
/// <param name="hProcess">
/// <para>A handle to the process.</para>
/// <para>
/// The handle must have the <c>PROCESS_SET_INFORMATION</c> access right. For more information, see Process Security and Access Rights.
/// </para>
/// </param>
/// <param name="dwPriorityClass">
/// <para>The priority class for the process. This parameter can be one of the following values.</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Priority</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>ABOVE_NORMAL_PRIORITY_CLASS0x00008000</term>
/// <term>Process that has priority above NORMAL_PRIORITY_CLASS but below HIGH_PRIORITY_CLASS.</term>
/// </item>
/// <item>
/// <term>BELOW_NORMAL_PRIORITY_CLASS0x00004000</term>
/// <term>Process that has priority above IDLE_PRIORITY_CLASS but below NORMAL_PRIORITY_CLASS.</term>
/// </item>
/// <item>
/// <term>HIGH_PRIORITY_CLASS0x00000080</term>
/// <term>
/// Process that performs time-critical tasks that must be executed immediately. The threads of the process preempt the threads of normal
/// or idle priority class processes. An example is the Task List, which must respond quickly when called by the user, regardless of the
/// load on the operating system. Use extreme care when using the high-priority class, because a high-priority class application can use
/// nearly all available CPU time.
/// </term>
/// </item>
/// <item>
/// <term>IDLE_PRIORITY_CLASS0x00000040</term>
/// <term>
/// Process whose threads run only when the system is idle. The threads of the process are preempted by the threads of any process
/// running in a higher priority class. An example is a screen saver. The idle-priority class is inherited by child processes.
/// </term>
/// </item>
/// <item>
/// <term>NORMAL_PRIORITY_CLASS0x00000020</term>
/// <term>Process with no special scheduling needs.</term>
/// </item>
/// <item>
/// <term>PROCESS_MODE_BACKGROUND_BEGIN0x00100000</term>
/// <term>
/// Begin background processing mode. The system lowers the resource scheduling priorities of the process (and its threads) so that it
/// can perform background work without significantly affecting activity in the foreground.This value can be specified only if hProcess
/// is a handle to the current process. The function fails if the process is already in background processing mode.Windows Server 2003
/// and Windows XP: This value is not supported.
/// </term>
/// </item>
/// <item>
/// <term>PROCESS_MODE_BACKGROUND_END0x00200000</term>
/// <term>
/// End background processing mode. The system restores the resource scheduling priorities of the process (and its threads) as they were
/// before the process entered background processing mode.This value can be specified only if hProcess is a handle to the current
/// process. The function fails if the process is not in background processing mode.Windows Server 2003 and Windows XP: This value is not supported.
/// </term>
/// </item>
/// <item>
/// <term>REALTIME_PRIORITY_CLASS0x00000100</term>
/// <term>
/// Process that has the highest possible priority. The threads of the process preempt the threads of all other processes, including
/// operating system processes performing important tasks. For example, a real-time process that executes for more than a very brief
/// interval can cause disk caches not to flush or cause the mouse to be unresponsive.
/// </term>
/// </item>
/// </list>
/// </para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL WINAPI SetPriorityClass( _In_ HANDLE hProcess, _In_ DWORD dwPriorityClass); https://msdn.microsoft.com/en-us/library/windows/desktop/ms686219(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms686219")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetPriorityClass([In] HPROCESS hProcess, CREATE_PROCESS dwPriorityClass);
/// <summary>Sets the affinity update mode of the specified process.</summary>
/// <param name="ProcessHandle">A handle to the process. This handle must be returned by the <c>GetCurrentProcess</c> function.</param>
/// <param name="dwFlags">
/// <para>The affinity update mode. This parameter can be one of the following values.</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>0</term>
/// <term>Disables dynamic update of the process affinity by the system.</term>
/// </item>
/// <item>
/// <term>PROCESS_AFFINITY_ENABLE_AUTO_UPDATE0x00000001UL</term>
/// <term>Enables dynamic update of the process affinity by the system.</term>
/// </item>
/// </list>
/// </para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL WINAPI SetProcessAffinityUpdateMode( _In_ HANDLE ProcessHandle, _In_ DWORD dwFlags); https://msdn.microsoft.com/en-us/library/windows/desktop/bb309063(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "bb309063")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetProcessAffinityUpdateMode([In] HPROCESS ProcessHandle, PROCESS_AFFINITY_MODE dwFlags);
/// <summary>Sets the default CPU Sets assignment for threads in the specified process.</summary>
/// <param name="Process">
/// Specifies the process for which to set the default CPU Sets. This handle must have the PROCESS_SET_LIMITED_INFORMATION access right.
/// The value returned by GetCurrentProcess can also be specified here.
/// </param>
/// <param name="CpuSetMasks">
/// Specifies an optional buffer of GROUP_AFFINITY structures representing the CPU Sets to set as the process default CPU set. If this is
/// NULL, the <c>SetProcessDefaultCpuSetMasks</c> function clears out any assignment.
/// </param>
/// <param name="CpuSetMaskCount">
/// Specifies the size of the CpuSetMasks array, in elements. If the buffer is NULL, this value must be zero.
/// </param>
/// <returns>This function cannot fail when passed valid parameters.</returns>
/// <remarks>
/// <para>
/// Threads belonging to this process which dont have CPU Sets explicitly set using SetThreadSelectedCpuSetMasks or
/// SetThreadSelectedCpuSets, will inherit the sets specified by <c>SetProcessDefaultCpuSetMasks</c> automatically.
/// </para>
/// <para>
/// This function is analogous to SetProcessDefaultCpuSets, except that it uses group affinities as opposed to CPU Set IDs to represent a
/// list of CPU sets. This means that the resulting process default CPU Set assignment is the set of all CPU sets with a home processor
/// in the provided list of group affinities.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setprocessdefaultcpusetmasks BOOL
// SetProcessDefaultCpuSetMasks( HANDLE Process, PGROUP_AFFINITY CpuSetMasks, USHORT CpuSetMaskCount );
[DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("processthreadsapi.h", MSDNShortId = "NF:processthreadsapi.SetProcessDefaultCpuSetMasks")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetProcessDefaultCpuSetMasks([In] HPROCESS Process,
[In, Optional, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] GROUP_AFFINITY[] CpuSetMasks, [Optional] ushort CpuSetMaskCount);
/// <summary>
/// Sets the default CPU Sets assignment for threads in the specified process. Threads that are created, which dont have CPU Sets
/// explicitly set using <c>SetThreadSelectedCpuSets</c>, will inherit the sets specified by <c>SetProcessDefaultCpuSets</c> automatically.
/// </summary>
/// <param name="Process">
/// Specifies the process for which to set the default CPU Sets. This handle must have the PROCESS_SET_LIMITED_INFORMATION access right.
/// The value returned by <c>GetCurrentProcess</c> can also be specified here.
/// </param>
/// <param name="CpuSetIds">
/// Specifies the list of CPU Set IDs to set as the process default CPU set. If this is NULL, the <c>SetProcessDefaultCpuSets</c> clears
/// out any assignment.
/// </param>
/// <param name="CpuSetIdCound">
/// Specifies the number of IDs in the list passed in the <c>CpuSetIds</c> argument. If that value is NULL, this should be 0.
/// </param>
/// <returns>This function cannot fail when passed valid parameters.</returns>
// BOOL WINAPI SetProcessDefaultCpuSets( _In_ HANDLE Process, _In_opt_ ULONG CpuSetIds, _In_ ULONG CpuSetIdCound); https://msdn.microsoft.com/en-us/library/windows/desktop/mt186427(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("Processthreadapi.h", MSDNShortId = "mt186427")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetProcessDefaultCpuSets([In] HPROCESS Process, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] CpuSetIds, uint CpuSetIdCound);
/// <summary>Sets dynamic exception handling continuation targets for the specified process.</summary>
/// <param name="Process">
/// A handle to the process. This handle must have the <c>PROCESS_SET_INFORMATION</c> access right. For more information, see Process
/// Security and Access Rights.
/// </param>
/// <param name="NumberOfTargets">Supplies the number of dynamic exception handling continuation targets to set.</param>
/// <param name="Targets">
/// A pointer to an array of dynamic exception handling continuation targets. For more information on this structure, see PROCESS_DYNAMIC_EH_CONTINUATION_TARGET.
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>
/// If the function fails, the return value is zero. To get extended error information, call GetLastError. Note that even if the function
/// fails, a portion of the supplied continuation targets may have been successfully processed. The caller needs to check the flags in
/// each individual continuation target specified via Targets to determine if it was successfully processed.
/// </para>
/// </returns>
/// <remarks>
/// If user-mode Hardware-enforced Stack Protection is enabled for a process, when calling APIs that modify the execution context of a
/// thread such as RtlRestoreContext and SetThreadContext, validation is performed on the Instruction Pointer specified in the new
/// execution context. RtlRestoreContext is used during Structured Exception Handling (SEH) exception unwinding to unwind to the target
/// frame that contains the <c>__except</c> block and to start executing code at the continuation target. Therefore, the operating system
/// needs to know the instruction addresses of all the valid continuation targets in order to allow the unwind operation via
/// RtlRestoreContext. For compiled binaries, the list of continuation targets is generated by the linker and stored in the binary image.
/// For dynamic code, the continuation targets need to be specified using SetProcessDynamicEHContinuationTargets.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setprocessdynamicehcontinuationtargets BOOL
// SetProcessDynamicEHContinuationTargets( HANDLE Process, USHORT NumberOfTargets, PPROCESS_DYNAMIC_EH_CONTINUATION_TARGET Targets );
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("processthreadsapi.h", MSDNShortId = "NF:processthreadsapi.SetProcessDynamicEHContinuationTargets")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetProcessDynamicEHContinuationTargets([In] HPROCESS Process, ushort NumberOfTargets, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] PROCESS_DYNAMIC_EH_CONTINUATION_TARGET[] Targets);
/// <summary>Sets information for the specified process.</summary>
/// <param name="hProcess">
/// A handle to the process. This handle must have the <c>PROCESS_SET_INFORMATION</c> access right. For more information, see Process
/// Security and Access Rights.
/// </param>
/// <param name="ProcessInformationClass">
/// The class of information to set. The only supported values are <c>ProcessMemoryPriority</c> and <c>ProcessPowerThrottling</c>.
/// </param>
/// <param name="ProcessInformation">
/// <para>Pointer to an object that contains the type of information specified by the ProcessInformationClass parameter.</para>
/// <para>
/// If the ProcessInformationClass parameter is <c>ProcessMemoryPriority</c>, this parameter must point to a
/// <c>MEMORY_PRIORITY_INFORMATION</c> structure.
/// </para>
/// <para>
/// If the ProcessInformationClass parameter is <c>ProcessPowerThrottling</c>, this parameter must point to a
/// <c>PROCESS_POWER_THROTTLING_STATE</c> structure.
/// </para>
/// </param>
/// <param name="ProcessInformationSize">
/// <para>The size in bytes of the structure specified by the ProcessInformation parameter.</para>
/// <para>If the ProcessInformationClass parameter is <c>ProcessMemoryPriority</c>, this parameter must be .</para>
/// <para>If the ProcessInformationClass parameter is <c>ProcessPowerThrottling</c>, this parameter must be .</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL WINAPI SetProcessInformation( _In_ HANDLE hProcess, _In_ PROCESS_INFORMATION_CLASS ProcessInformationClass,
// _In_reads_bytes_(ProcessInformationSize) ProcessInformation, _In_ DWORD ProcessInformationSize); https://msdn.microsoft.com/en-us/library/windows/desktop/hh448389(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "hh448389")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetProcessInformation([In] HPROCESS hProcess, PROCESS_INFORMATION_CLASS ProcessInformationClass, IntPtr ProcessInformation, uint ProcessInformationSize);
/// <summary>Sets information for the specified process.</summary>
/// <param name="hProcess">
/// A handle to the process. This handle must have the <c>PROCESS_SET_INFORMATION</c> access right. For more information, see Process
/// Security and Access Rights.
/// </param>
/// <param name="ProcessInformationClass">
/// The class of information to set. The only supported values are <c>ProcessMemoryPriority</c> and <c>ProcessPowerThrottling</c>.
/// </param>
/// <param name="ProcessInformation">
/// <para>Pointer to an object that contains the type of information specified by the ProcessInformationClass parameter.</para>
/// <para>
/// If the ProcessInformationClass parameter is <c>ProcessMemoryPriority</c>, this parameter must point to a
/// <c>MEMORY_PRIORITY_INFORMATION</c> structure.
/// </para>
/// <para>
/// If the ProcessInformationClass parameter is <c>ProcessPowerThrottling</c>, this parameter must point to a
/// <c>PROCESS_POWER_THROTTLING_STATE</c> structure.
/// </para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
[PInvokeData("WinBase.h", MSDNShortId = "hh448389")]
public static bool SetProcessInformation<T>([In] HPROCESS hProcess, PROCESS_INFORMATION_CLASS ProcessInformationClass, in T ProcessInformation) where T : struct
{
if (!CorrespondingTypeAttribute.CanSet(ProcessInformationClass, typeof(T))) throw new ArgumentException($"{ProcessInformationClass} cannot be used to set values of type {typeof(T)}.");
using SafeHGlobalHandle mem = SafeHGlobalHandle.CreateFromStructure(ProcessInformation);
return SetProcessInformation(hProcess, ProcessInformationClass, (IntPtr)mem, (uint)mem.Size);
}
/// <summary>
/// Sets a mitigation policy for the calling process. Mitigation policies enable a process to harden itself against various types of attacks.
/// </summary>
/// <param name="MitigationPolicy">
/// <para>The mitigation policy to apply. This parameter can be one of the following values.</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>ProcessDEPPolicy</term>
/// <term>
/// The data execution prevention (DEP) policy of the process.The lpBuffer parameter points to a PROCESS_MITIGATION_DEP_POLICY structure
/// that specifies the DEP policy flags.
/// </term>
/// </item>
/// <item>
/// <term>ProcessASLRPolicy</term>
/// <term>
/// The Address Space Layout Randomization (ASLR) policy of the process.The lpBuffer parameter points to a PROCESS_MITIGATION_ASLR_POLICY
/// structure that specifies the ASLR policy flags.
/// </term>
/// </item>
/// <item>
/// <term>ProcessDynamicCodePolicy</term>
/// <term>
/// The dynamic code policy of the process. When turned on, the process cannot generate dynamic code or modify existing executable
/// code.The lpBuffer parameter points to a PROCESS_MITIGATION_DYNAMIC_CODE_POLICY structure that specifies the dynamic code policy flags.
/// </term>
/// </item>
/// <item>
/// <term>ProcessStrictHandleCheckPolicy</term>
/// <term>
/// The process will receive a fatal error if it manipulates a handle that is not valid.The lpBuffer parameter points to a
/// PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY structure that specifies the handle check policy flags.
/// </term>
/// </item>
/// <item>
/// <term>ProcessSystemCallDisablePolicy</term>
/// <term>
/// Disables the ability to use NTUser/GDI functions at the lowest layer.The lpBuffer parameter points to a
/// PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY structure that specifies the system call disable policy flags.
/// </term>
/// </item>
/// <item>
/// <term>ProcessMitigationOptionsMask</term>
/// <term>
/// Returns the mask of valid bits for all the mitigation options on the system. An application can set many mitigation options without
/// querying the operating system for mitigation options by combining bitwise with the mask to exclude all non-supported bits at once.The
/// lpBuffer parameter points to a ULONG64 bit vector for the mask, or to accommodate more than 64 bits, a two-element array of ULONG64
/// bit vectors.
/// </term>
/// </item>
/// <item>
/// <term>ProcessExtensionPointDisablePolicy</term>
/// <term>
/// The lpBuffer parameter points to a PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY structure that specifies the extension point
/// disable policy flags.
/// </term>
/// </item>
/// <item>
/// <term>ProcessControlFlowGuardPolicy</term>
/// <term>
/// The Control Flow Guard (CFG) policy of the process.The lpBuffer parameter points to a PROCESS_MITIGATION_CONTROL_FLOW_GUARD_POLICY
/// structure that specifies the CFG policy flags.
/// </term>
/// </item>
/// <item>
/// <term>ProcessSignaturePolicy</term>
/// <term>
/// The policy of a process that can restrict image loading to those images that are either signed by Microsoft, by the Windows Store, or
/// by Microsoft, the Windows Store and the Windows Hardware Quality Labs (WHQL).he lpBuffer parameter points to a
/// PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY structure that specifies the signature policy flags.
/// </term>
/// </item>
/// <item>
/// <term>ProcessFontDisablePolicy</term>
/// <term>
/// The policy regarding font loading for the process. When turned on, the process cannot load non-system fonts.The lpBuffer parameter
/// points to a PROCESS_MITIGATION_FONT_DISABLE_POLICY structure that specifies the policy flags for font loading.
/// </term>
/// </item>
/// <item>
/// <term>ProcessImageLoadPolicy</term>
/// <term>
/// The policy regarding image loading for the process, which determines the types of executable images that are allowed to be mapped
/// into the process. When turned on, images cannot be loaded from some locations, such a remote devices or files that have the low
/// mandatory label.The lpBuffer parameter points to a PROCESS_MITIGATION_IMAGE_LOAD_POLICY structure that specifies the policy flags for
/// image loading.
/// </term>
/// </item>
/// </list>
/// </para>
/// </param>
/// <param name="lpBuffer">
/// <para>
/// If the MitigationPolicy parameter is <c>ProcessDEPPolicy</c>, this parameter points to a <c>PROCESS_MITIGATION_DEP_POLICY</c>
/// structure that specifies the DEP policy flags.
/// </para>
/// <para>
/// If the MitigationPolicy parameter is <c>ProcessASLRPolicy</c>, this parameter points to a <c>PROCESS_MITIGATION_ASLR_POLICY</c>
/// structure that specifies the ASLR policy flags.
/// </para>
/// <para>
/// If the MitigationPolicy parameter is <c>ProcessImageLoadPolicy</c>, this parameter points to a
/// <c>PROCESS_MITIGATION_IMAGE_LOAD_POLICY</c> structure that receives the policy flags for image loading.
/// </para>
/// <para>
/// If the MitigationPolicy parameter is <c>ProcessStrictHandleCheckPolicy</c>, this parameter points to a
/// <c>PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY</c> structure that specifies the handle check policy flags.
/// </para>
/// <para>
/// If the MitigationPolicy parameter is <c>ProcessSystemCallDisablePolicy</c>, this parameter points to a
/// <c>PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY</c> structure that specifies the system call disable policy flags.
/// </para>
/// <para>
/// If the MitigationPolicy parameter is <c>ProcessMitigationOptionsMask</c>, this parameter points to a <c>ULONG64</c> bit vector for
/// the mask, or to accommodate more than 64 bits, a two-element array of <c>ULONG64</c> bit vectors.
/// </para>
/// <para>
/// If the MitigationPolicy parameter is <c>ProcessExtensionPointDisablePolicy</c>, this parameter points to a
/// <c>PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY</c> structure that specifies the extension point disable policy flags.
/// </para>
/// <para>
/// If the MitigationPolicy parameter is <c>ProcessControlFlowGuardPolicy</c>, this parameter points to a
/// <c>PROCESS_MITIGATION_CONTROL_FLOW_GUARD_POLICY</c> structure that specifies the CFG policy flags.
/// </para>
/// <para>
/// If the MitigationPolicy parameter is <c>ProcessSignaturePolicy</c>, this parameter points to a
/// <c>PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY</c> structure that specifies the signature policy flags.
/// </para>
/// <para>
/// If the MitigationPolicy parameter is <c>ProcessFontDisablePolicy</c>, this parameter points to a
/// <c>PROCESS_MITIGATION_FONT_DISABLE_POLICY</c> structure that specifies the policy flags for font loading.
/// </para>
/// <para>
/// If the MitigationPolicy parameter is <c>ProcessImageLoadPolicy</c>, this parameter points to a
/// <c>PROCESS_MITIGATION_IMAGE_LOAD_POLICY</c> structure that specifies the policy flags for image loading.
/// </para>
/// </param>
/// <param name="dwLength">The size of lpBuffer, in bytes.</param>
/// <returns>
/// If the function succeeds, it returns <c>TRUE</c>. If the function fails, it returns <c>FALSE</c>. To retrieve error values defined
/// for this function, call <c>GetLastError</c>.
/// </returns>
// BOOL WINAPI SetProcessMitigationPolicy( _In_ PROCESS_MITIGATION_POLICY MitigationPolicy, _In_ PVOID lpBuffer, _In_ SIZE_T dwLength); https://msdn.microsoft.com/en-us/library/windows/desktop/hh769088(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("Processthreadsapi.h", MSDNShortId = "hh769088")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetProcessMitigationPolicy(PROCESS_MITIGATION_POLICY MitigationPolicy, IntPtr lpBuffer, SizeT dwLength);
/// <summary>
/// Sets a mitigation policy for the calling process. Mitigation policies enable a process to harden itself against various types of attacks.
/// </summary>
/// <typeparam name="T">The type of the value being set.</typeparam>
/// <param name="MitigationPolicy">
/// <para>The mitigation policy to apply. This parameter can be one of the following values.</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>ProcessDEPPolicy</term>
/// <term>
/// The data execution prevention (DEP) policy of the process.The lpBuffer parameter points to a PROCESS_MITIGATION_DEP_POLICY structure
/// that specifies the DEP policy flags.
/// </term>
/// </item>
/// <item>
/// <term>ProcessASLRPolicy</term>
/// <term>
/// The Address Space Layout Randomization (ASLR) policy of the process.The lpBuffer parameter points to a PROCESS_MITIGATION_ASLR_POLICY
/// structure that specifies the ASLR policy flags.
/// </term>
/// </item>
/// <item>
/// <term>ProcessDynamicCodePolicy</term>
/// <term>
/// The dynamic code policy of the process. When turned on, the process cannot generate dynamic code or modify existing executable
/// code.The lpBuffer parameter points to a PROCESS_MITIGATION_DYNAMIC_CODE_POLICY structure that specifies the dynamic code policy flags.
/// </term>
/// </item>
/// <item>
/// <term>ProcessStrictHandleCheckPolicy</term>
/// <term>
/// The process will receive a fatal error if it manipulates a handle that is not valid.The lpBuffer parameter points to a
/// PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY structure that specifies the handle check policy flags.
/// </term>
/// </item>
/// <item>
/// <term>ProcessSystemCallDisablePolicy</term>
/// <term>
/// Disables the ability to use NTUser/GDI functions at the lowest layer.The lpBuffer parameter points to a
/// PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY structure that specifies the system call disable policy flags.
/// </term>
/// </item>
/// <item>
/// <term>ProcessMitigationOptionsMask</term>
/// <term>
/// Returns the mask of valid bits for all the mitigation options on the system. An application can set many mitigation options without
/// querying the operating system for mitigation options by combining bitwise with the mask to exclude all non-supported bits at once.The
/// lpBuffer parameter points to a ULONG64 bit vector for the mask, or to accommodate more than 64 bits, a two-element array of ULONG64
/// bit vectors.
/// </term>
/// </item>
/// <item>
/// <term>ProcessExtensionPointDisablePolicy</term>
/// <term>
/// The lpBuffer parameter points to a PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY structure that specifies the extension point
/// disable policy flags.
/// </term>
/// </item>
/// <item>
/// <term>ProcessControlFlowGuardPolicy</term>
/// <term>
/// The Control Flow Guard (CFG) policy of the process.The lpBuffer parameter points to a PROCESS_MITIGATION_CONTROL_FLOW_GUARD_POLICY
/// structure that specifies the CFG policy flags.
/// </term>
/// </item>
/// <item>
/// <term>ProcessSignaturePolicy</term>
/// <term>
/// The policy of a process that can restrict image loading to those images that are either signed by Microsoft, by the Windows Store, or
/// by Microsoft, the Windows Store and the Windows Hardware Quality Labs (WHQL).he lpBuffer parameter points to a
/// PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY structure that specifies the signature policy flags.
/// </term>
/// </item>
/// <item>
/// <term>ProcessFontDisablePolicy</term>
/// <term>
/// The policy regarding font loading for the process. When turned on, the process cannot load non-system fonts.The lpBuffer parameter
/// points to a PROCESS_MITIGATION_FONT_DISABLE_POLICY structure that specifies the policy flags for font loading.
/// </term>
/// </item>
/// <item>
/// <term>ProcessImageLoadPolicy</term>
/// <term>
/// The policy regarding image loading for the process, which determines the types of executable images that are allowed to be mapped
/// into the process. When turned on, images cannot be loaded from some locations, such a remote devices or files that have the low
/// mandatory label.The lpBuffer parameter points to a PROCESS_MITIGATION_IMAGE_LOAD_POLICY structure that specifies the policy flags for
/// image loading.
/// </term>
/// </item>
/// </list>
/// </para>
/// </param>
/// <param name="value">The value. This must correspond to the <paramref name="MitigationPolicy"/> value.</param>
/// <returns>
/// If the function succeeds, it returns <c>TRUE</c>. If the function fails, it returns <c>FALSE</c>. To retrieve error values defined
/// for this function, call <c>GetLastError</c>.
/// </returns>
public static bool SetProcessMitigationPolicy<T>(PROCESS_MITIGATION_POLICY MitigationPolicy, in T value)
{
if (MitigationPolicy == PROCESS_MITIGATION_POLICY.ProcessMitigationOptionsMask)
{
if (!(value is ulong || value is ulong[])) throw new ArgumentException($"{MitigationPolicy} cannot be used to set values of type {typeof(T)}.");
using PinnedObject ptr = new(value);
return SetProcessMitigationPolicy(MitigationPolicy, ptr, value is ulong ? 8U : 16U);
}
if (!CorrespondingTypeAttribute.CanSet(MitigationPolicy, typeof(T))) throw new ArgumentException($"{MitigationPolicy} cannot be used to set values of type {typeof(T)}.");
using (SafeCoTaskMemHandle ptr = SafeCoTaskMemHandle.CreateFromStructure(value))
return SetProcessMitigationPolicy(MitigationPolicy, (IntPtr)ptr, (uint)ptr.Size);
}
/// <summary>Disables or enables the ability of the system to temporarily boost the priority of the threads of the specified process.</summary>
/// <param name="hProcess">
/// A handle to the process. This handle must have the PROCESS_SET_INFORMATION access right. For more information, see Process Security
/// and Access Rights.
/// </param>
/// <param name="DisablePriorityBoost">
/// If this parameter is TRUE, dynamic boosting is disabled. If the parameter is FALSE, dynamic boosting is enabled.
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL WINAPI SetProcessPriorityBoost( _In_ HANDLE hProcess, _In_ BOOL DisablePriorityBoost); https://msdn.microsoft.com/en-us/library/windows/desktop/ms686225(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms686225")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetProcessPriorityBoost([In] HPROCESS hProcess, [MarshalAs(UnmanagedType.Bool)] bool DisablePriorityBoost);
/// <summary>
/// Sets shutdown parameters for the currently calling process. This function sets a shutdown order for a process relative to the other
/// processes in the system.
/// </summary>
/// <param name="dwLevel">
/// <para>
/// The shutdown priority for a process relative to other processes in the system. The system shuts down processes from high dwLevel
/// values to low. The highest and lowest shutdown priorities are reserved for system components. This parameter must be in the following
/// range of values.
/// </para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>000-0FF</term>
/// <term>System reserved last shutdown range.</term>
/// </item>
/// <item>
/// <term>100-1FF</term>
/// <term>Application reserved last shutdown range.</term>
/// </item>
/// <item>
/// <term>200-2FF</term>
/// <term>Application reserved &amp;quot;in between&amp;quot; shutdown range.</term>
/// </item>
/// <item>
/// <term>300-3FF</term>
/// <term>Application reserved first shutdown range.</term>
/// </item>
/// <item>
/// <term>400-4FF</term>
/// <term>System reserved first shutdown range.</term>
/// </item>
/// </list>
/// </para>
/// <para>All processes start at shutdown level 0x280.</para>
/// </param>
/// <param name="dwFlags">
/// <para>This parameter can be the following value.</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>SHUTDOWN_NORETRY0x00000001</term>
/// <term>The system terminates the process without displaying a retry dialog box for the user.</term>
/// </item>
/// </list>
/// </para>
/// </param>
/// <returns>
/// <para>If the function is succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL WINAPI SetProcessShutdownParameters( _In_ DWORD dwLevel, _In_ DWORD dwFlags); https://msdn.microsoft.com/en-us/library/windows/desktop/ms686227(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms686227")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetProcessShutdownParameters(uint dwLevel, SHUTDOWN dwFlags);
/// <summary>Sets a protected policy. This function is for use primarily by Windows, and not designed for external use.</summary>
/// <param name="PolicyGuid">The globally-unique identifier of the policy to set.</param>
/// <param name="PolicyValue">The value to set the policy to.</param>
/// <param name="OldPolicyValue">Optionally receives the original value that was associated with the supplied policy.</param>
/// <returns>True if the function succeeds; otherwise, false. To retrieve error values for this function, call <c>GetLastError</c>.</returns>
// BOOL WINAPI SetProtectedPolicy( _In_ LPCGUID PolicyGuid, _In_ ULONG_PTR PolicyValue, _Out_ PULONG_PTR OldPolicyValue); https://msdn.microsoft.com/en-us/library/windows/desktop/dn893592(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("Winbase.h", MSDNShortId = "dn893592")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetProtectedPolicy(in Guid PolicyGuid, IntPtr PolicyValue, out IntPtr OldPolicyValue);
/// <summary>
/// <para>Sets the context for the specified thread.</para>
/// <para>A 64-bit application can set the context of a WOW64 thread using the <c>Wow64SetThreadContext</c> function.</para>
/// </summary>
/// <param name="hThread">
/// A handle to the thread whose context is to be set. The handle must have the <c>THREAD_SET_CONTEXT</c> access right to the thread. For
/// more information, see Thread Security and Access Rights.
/// </param>
/// <param name="lpContext">
/// A pointer to a <c>CONTEXT</c> structure that contains the context to be set in the specified thread. The value of the
/// <c>ContextFlags</c> member of this structure specifies which portions of a thread's context to set. Some values in the <c>CONTEXT</c>
/// structure that cannot be specified are silently set to the correct value. This includes bits in the CPU status register that specify
/// the privileged processor mode, global enabling bits in the debugging register, and other states that must be controlled by the
/// operating system.
/// </param>
/// <returns>
/// <para>If the context was set, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL WINAPI SetThreadContext( _In_ HANDLE hThread, _In_ const CONTEXT *lpContext); https://msdn.microsoft.com/en-us/library/windows/desktop/ms680632(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms680632")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetThreadContext([In] HTHREAD hThread, in CONTEXT lpContext);
/// <summary>Assigns a description to a thread.</summary>
/// <param name="hThread">
/// A handle for the thread for which you want to set the description. The handle must have THREAD_SET_LIMITED_INFORMATION access.
/// </param>
/// <param name="lpThreadDescription">A Unicode string that specifies the description of the thread.</param>
/// <returns>
/// If the function succeeds, the return value is the <c>HRESULT</c> that denotes a successful operation.If the function fails, the
/// return value is an <c>HRESULT</c> that denotes the error.
/// </returns>
// HRESULT WINAPI SetThreadDescription( _In_ HANDLE hThread, _In_ PCWSTR lpThreadDescription); https://msdn.microsoft.com/en-us/library/windows/desktop/mt774976(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("ProcessThreadsApi.h", MSDNShortId = "mt774976")]
public static extern HRESULT SetThreadDescription(HTHREAD hThread, [MarshalAs(UnmanagedType.LPWStr)] string lpThreadDescription);
/// <summary>
/// <para>Sets a preferred processor for a thread. The system schedules threads on their preferred processors whenever possible.</para>
/// <para>
/// On a system with more than 64 processors, this function sets the preferred processor to a logical processor in the processor group to
/// which the calling thread is assigned. Use the <c>SetThreadIdealProcessorEx</c> function to specify a processor group and preferred processor.
/// </para>
/// </summary>
/// <param name="hThread">
/// A handle to the thread whose preferred processor is to be set. The handle must have the THREAD_SET_INFORMATION access right. For more
/// information, see Thread Security and Access Rights.
/// </param>
/// <param name="dwIdealProcessor">
/// The number of the preferred processor for the thread. This value is zero-based. If this parameter is MAXIMUM_PROCESSORS, the function
/// returns the current ideal processor without changing it.
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is the previous preferred processor.</para>
/// <para>If the function fails, the return value is (DWORD) 1. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// DWORD WINAPI SetThreadIdealProcessor( _In_ HANDLE hThread, _In_ DWORD dwIdealProcessor); https://msdn.microsoft.com/en-us/library/windows/desktop/ms686253(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms686253")]
public static extern uint SetThreadIdealProcessor([In] HTHREAD hThread, uint dwIdealProcessor);
/// <summary>Sets the ideal processor for the specified thread and optionally retrieves the previous ideal processor.</summary>
/// <param name="hThread">
/// A handle to the thread for which to set the ideal processor. This handle must have been created with the THREAD_SET_INFORMATION
/// access right. For more information, see Thread Security and Access Rights.
/// </param>
/// <param name="lpIdealProcessor">
/// A pointer to a PROCESSOR_NUMBER structure that specifies the processor number of the desired ideal processor.
/// </param>
/// <param name="lpPreviousIdealProcessor">
/// A pointer to a PROCESSOR_NUMBER structure to receive the previous ideal processor. This parameter can point to the same memory
/// location as the lpIdealProcessor parameter. This parameter can be NULL if the previous ideal processor is not required.
/// </param>
/// <returns>
/// If the function succeeds, it returns a nonzero value. If the function fails, it returns zero.To get extended error information, use GetLastError.
/// </returns>
// https://msdn.microsoft.com/en-us/library/windows/desktop/dd405517(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "dd405517")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetThreadIdealProcessorEx([In] HTHREAD hThread, in PROCESSOR_NUMBER lpIdealProcessor, out PROCESSOR_NUMBER lpPreviousIdealProcessor);
/// <summary>Sets information for the specified thread.</summary>
/// <param name="hThread">
/// A handle to the thread. The handle must have THREAD_QUERY_INFORMATION access right. For more information, see Thread Security and
/// Access Rights.
/// </param>
/// <param name="ThreadInformationClass">
/// The class of information to set. The only supported values are <c>ThreadMemoryPriority</c> and <c>ThreadPowerThrottling</c>.
/// </param>
/// <param name="ThreadInformation">
/// <para>Pointer to a structure that contains the type of information specified by the ThreadInformationClass parameter.</para>
/// <para>
/// If the ThreadInformationClass parameter is <c>ThreadMemoryPriority</c>, this parameter must point to a
/// <c>MEMORY_PRIORITY_INFORMATION</c> structure.
/// </para>
/// <para>
/// If the ThreadInformationClass parameter is <c>ThreadPowerThrottling</c>, this parameter must point to a
/// <c>THREAD_POWER_THROTTLING_STATE</c> structure.
/// </para>
/// </param>
/// <param name="ThreadInformationSize">
/// <para>The size in bytes of the structure specified by the ThreadInformation parameter.</para>
/// <para>If the ThreadInformationClass parameter is <c>ThreadMemoryPriority</c>, this parameter must be .</para>
/// <para>If the ThreadInformationClass parameter is <c>ThreadPowerThrottling</c>, this parameter must be .</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
/// </returns>
/// <remarks>
/// <para>
/// To help improve system performance, applications should use the <c>SetThreadInformation</c> function with <c>ThreadMemoryPriority</c>
/// to lower the memory priority of threads that perform background operations or access files and data that are not expected to be
/// accessed again soon. For example, an anti-malware application might lower the priority of threads involved in scanning files.
/// </para>
/// <para>
/// Memory priority helps to determine how long pages remain in the working set of a process before they are trimmed. A thread's memory
/// priority determines the minimum priority of the physical pages that are added to the process working set by that thread. When the
/// memory manager trims the working set, it trims lower priority pages before higher priority pages. This improves overall system
/// performance because higher priority pages are less likely to be trimmed from the working set and then trigger a page fault when they
/// are accessed again.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following example shows how to call <c>SetThreadInformation</c> with <c>ThreadMemoryPriority</c> to set low memory priority on
/// the current thread.
/// </para>
/// <para>
/// The following example shows how to call <c>SetThreadInformation</c> with <c>ThreadPowerThrottling</c> to enable throttling policies
/// on a thread.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreadinformation BOOL
// SetThreadInformation( HANDLE hThread, THREAD_INFORMATION_CLASS ThreadInformationClass, LPVOID ThreadInformation, DWORD
// ThreadInformationSize );
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("processthreadsapi.h", MSDNShortId = "c0159bea-870a-46b7-a350-91fe52efae49")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetThreadInformation(HTHREAD hThread, THREAD_INFORMATION_CLASS ThreadInformationClass, IntPtr ThreadInformation, uint ThreadInformationSize);
/// <summary>Sets information for the specified thread.</summary>
/// <typeparam name="T">
/// The type of the structure that contains the type of information specified by the ThreadInformationClass parameter.
/// </typeparam>
/// <param name="hThread">
/// A handle to the thread. The handle must have THREAD_QUERY_INFORMATION access right. For more information, see Thread Security and
/// Access Rights.
/// </param>
/// <param name="ThreadInformationClass">
/// The class of information to set. The only supported values are <c>ThreadMemoryPriority</c> and <c>ThreadPowerThrottling</c>.
/// </param>
/// <param name="ThreadInformation">
/// <para>The structure that contains the type of information specified by the ThreadInformationClass parameter.</para>
/// <para>
/// If the ThreadInformationClass parameter is <c>ThreadMemoryPriority</c>, this parameter must point to a
/// <c>MEMORY_PRIORITY_INFORMATION</c> structure.
/// </para>
/// <para>
/// If the ThreadInformationClass parameter is <c>ThreadPowerThrottling</c>, this parameter must point to a
/// <c>THREAD_POWER_THROTTLING_STATE</c> structure.
/// </para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
/// </returns>
/// <exception cref="ArgumentException"></exception>
/// <remarks>
/// <para>
/// To help improve system performance, applications should use the <c>SetThreadInformation</c> function with <c>ThreadMemoryPriority</c>
/// to lower the memory priority of threads that perform background operations or access files and data that are not expected to be
/// accessed again soon. For example, an anti-malware application might lower the priority of threads involved in scanning files.
/// </para>
/// <para>
/// Memory priority helps to determine how long pages remain in the working set of a process before they are trimmed. A thread's memory
/// priority determines the minimum priority of the physical pages that are added to the process working set by that thread. When the
/// memory manager trims the working set, it trims lower priority pages before higher priority pages. This improves overall system
/// performance because higher priority pages are less likely to be trimmed from the working set and then trigger a page fault when they
/// are accessed again.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following example shows how to call <c>SetThreadInformation</c> with <c>ThreadMemoryPriority</c> to set low memory priority on
/// the current thread.
/// </para>
/// <para>
/// The following example shows how to call <c>SetThreadInformation</c> with <c>ThreadPowerThrottling</c> to enable throttling policies
/// on a thread.
/// </para>
/// </remarks>
[PInvokeData("processthreadsapi.h", MSDNShortId = "c0159bea-870a-46b7-a350-91fe52efae49")]
public static bool SetThreadInformation<T>(HTHREAD hThread, THREAD_INFORMATION_CLASS ThreadInformationClass, in T ThreadInformation)
{
if (!CorrespondingTypeAttribute.CanSet(ThreadInformationClass, typeof(T))) throw new ArgumentException($"{ThreadInformationClass} cannot be used to set values of type {typeof(T)}.");
using SafeHGlobalHandle mem = SafeHGlobalHandle.CreateFromStructure(ThreadInformation);
return SetThreadInformation(hThread, ThreadInformationClass, (IntPtr)mem, (uint)mem.Size);
}
/// <summary>
/// Sets the priority value for the specified thread. This value, together with the priority class of the thread's process, determines
/// the thread's base priority level.
/// </summary>
/// <param name="hThread">
/// <para>A handle to the thread whose priority value is to be set.</para>
/// <para>
/// The handle must have the <c>THREAD_SET_INFORMATION</c> or <c>THREAD_SET_LIMITED_INFORMATION</c> access right. For more information,
/// see Thread Security and Access Rights.
/// </para>
/// <para><c>Windows Server 2003:</c> The handle must have the <c>THREAD_SET_INFORMATION</c> access right.</para>
/// </param>
/// <param name="nPriority">
/// <para>The priority value for the thread. This parameter can be one of the following values.</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Priority</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>THREAD_MODE_BACKGROUND_BEGIN0x00010000</term>
/// <term>
/// Begin background processing mode. The system lowers the resource scheduling priorities of the thread so that it can perform
/// background work without significantly affecting activity in the foreground.This value can be specified only if hThread is a handle to
/// the current thread. The function fails if the thread is already in background processing mode.Windows Server 2003: This value is not supported.
/// </term>
/// </item>
/// <item>
/// <term>THREAD_MODE_BACKGROUND_END0x00020000</term>
/// <term>
/// End background processing mode. The system restores the resource scheduling priorities of the thread as they were before the thread
/// entered background processing mode.This value can be specified only if hThread is a handle to the current thread. The function fails
/// if the thread is not in background processing mode.Windows Server 2003: This value is not supported.
/// </term>
/// </item>
/// <item>
/// <term>THREAD_PRIORITY_ABOVE_NORMAL1</term>
/// <term>Priority 1 point above the priority class.</term>
/// </item>
/// <item>
/// <term>THREAD_PRIORITY_BELOW_NORMAL-1</term>
/// <term>Priority 1 point below the priority class.</term>
/// </item>
/// <item>
/// <term>THREAD_PRIORITY_HIGHEST2</term>
/// <term>Priority 2 points above the priority class.</term>
/// </item>
/// <item>
/// <term>THREAD_PRIORITY_IDLE-15</term>
/// <term>
/// Base priority of 1 for IDLE_PRIORITY_CLASS, BELOW_NORMAL_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS, ABOVE_NORMAL_PRIORITY_CLASS, or
/// HIGH_PRIORITY_CLASS processes, and a base priority of 16 for REALTIME_PRIORITY_CLASS processes.
/// </term>
/// </item>
/// <item>
/// <term>THREAD_PRIORITY_LOWEST-2</term>
/// <term>Priority 2 points below the priority class.</term>
/// </item>
/// <item>
/// <term>THREAD_PRIORITY_NORMAL0</term>
/// <term>Normal priority for the priority class.</term>
/// </item>
/// <item>
/// <term>THREAD_PRIORITY_TIME_CRITICAL15</term>
/// <term>
/// Base priority of 15 for IDLE_PRIORITY_CLASS, BELOW_NORMAL_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS, ABOVE_NORMAL_PRIORITY_CLASS, or
/// HIGH_PRIORITY_CLASS processes, and a base priority of 31 for REALTIME_PRIORITY_CLASS processes.
/// </term>
/// </item>
/// </list>
/// </para>
/// <para>
/// If the thread has the <c>REALTIME_PRIORITY_CLASS</c> base class, this parameter can also be -7, -6, -5, -4, -3, 3, 4, 5, or 6. For
/// more information, see Scheduling Priorities.
/// </para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// <para>
/// <c>Windows Phone 8.1:</c> Windows Phone Store apps may call this function but it has no effect. The function will return a nonzero
/// value indicating success.
/// </para>
/// </returns>
// BOOL WINAPI SetThreadPriority( _In_ HANDLE hThread, _In_ int nPriority); https://msdn.microsoft.com/en-us/library/windows/desktop/ms686277(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms686277")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetThreadPriority([In] HTHREAD hThread, int nPriority);
/// <summary>Disables or enables the ability of the system to temporarily boost the priority of a thread.</summary>
/// <param name="hThread">
/// <para>
/// A handle to the thread whose priority is to be boosted. The handle must have the <c>THREAD_SET_INFORMATION</c> or
/// <c>THREAD_SET_LIMITED_INFORMATION</c> access right. For more information, see Thread Security and Access Rights.
/// </para>
/// <para><c>Windows Server 2003 and Windows XP:</c> The handle must have the <c>THREAD_SET_INFORMATION</c> access right.</para>
/// </param>
/// <param name="DisablePriorityBoost">
/// If this parameter is <c>TRUE</c>, dynamic boosting is disabled. If the parameter is <c>FALSE</c>, dynamic boosting is enabled.
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL WINAPI SetThreadPriorityBoost( _In_ HANDLE hThread, _In_ BOOL DisablePriorityBoost); https://msdn.microsoft.com/en-us/library/windows/desktop/ms686280(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms686280")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetThreadPriorityBoost([In] HTHREAD hThread, [MarshalAs(UnmanagedType.Bool)] bool DisablePriorityBoost);
/// <summary>
/// Sets the selected CPU Sets assignment for the specified thread. This assignment overrides the process default assignment, if one is set.
/// </summary>
/// <param name="Thread">
/// Specifies the thread on which to set the CPU Set assignment. PROCESS_SET_LIMITED_INFORMATION access right. The value returned by
/// GetCurrentProcess can also be specified here.
/// </param>
/// <param name="CpuSetMasks">
/// Specifies an optional buffer of GROUP_AFFINITY structures representing the CPU Sets to set as the thread selected CPU set. If this is
/// NULL, the <c>SetThreadSelectedCpuSetMasks</c> function clears out any assignment, reverting to process default assignment if one is set.
/// </param>
/// <param name="CpuSetMaskCount">
/// Specifies the number of <c>GROUP_AFFINITY</c> structures in the list passed in the GroupCpuSets argument. If the buffer is NULL, this
/// value must be zero.
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero and extended error information can be retrieved by calling GetLastError.</para>
/// </returns>
/// <remarks>
/// This function is analogous to SetThreadSelectedCpuSets, except that it uses group affinities as opposed to CPU Set IDs to represent a
/// list of CPU sets. This means that the resulting thread selected CPU Set assignment is the set of all CPU sets with a home processor
/// in the provided list of group affinities.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreadselectedcpusetmasks BOOL
// SetThreadSelectedCpuSetMasks( HANDLE Thread, PGROUP_AFFINITY CpuSetMasks, USHORT CpuSetMaskCount );
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("processthreadsapi.h", MSDNShortId = "NF:processthreadsapi.SetThreadSelectedCpuSetMasks")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetThreadSelectedCpuSetMasks([In] HTHREAD Thread,
[In, Optional, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] GROUP_AFFINITY[] CpuSetMasks, [Optional] ushort CpuSetMaskCount);
/// <summary>
/// Sets the selected CPU Sets assignment for the specified thread. This assignment overrides the process default assignment, if one is set.
/// </summary>
/// <param name="Thread">
/// Specifies the thread on which to set the CPU Set assignment. This handle must have the THREAD_SET_LIMITED_INFORMATION access right.
/// The value returned by <c>GetCurrentThread</c> can also be used.
/// </param>
/// <param name="CpuSetIds">
/// Specifies the list of CPU Set IDs to set as the thread selected CPU set. If this is NULL, the API clears out any assignment,
/// reverting to process default assignment if one is set.
/// </param>
/// <param name="CpuSetIdCount">
/// Specifies the number of IDs in the list passed in the <c>CpuSetIds</c> argument. If that value is NULL, this should be 0.
/// </param>
/// <returns>This function cannot fail when passed valid parameters.</returns>
// BOOL WINAPI SetThreadSelectedCpuSets( _In_ HANDLE Thread, _In_ const ULONG *CpuSetIds, _In_ ULONG CpuSetIdCount); https://msdn.microsoft.com/en-us/library/windows/desktop/mt186428(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("Processthreadapi.h", MSDNShortId = "mt186428")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetThreadSelectedCpuSets([In] HTHREAD Thread, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] uint[] CpuSetIds, uint CpuSetIdCount);
/// <summary>
/// Sets the minimum size of the stack associated with the calling thread or fiber that will be available during any stack overflow
/// exceptions. This is useful for handling stack overflow exceptions; the application can safely use the specified number of bytes
/// during exception handling.
/// </summary>
/// <param name="StackSizeInBytes">
/// <para>The size of the stack, in bytes. On return, this value is set to the size of the previous stack, in bytes.</para>
/// <para>If this parameter is 0 (zero), the function succeeds and the parameter contains the size of the current stack.</para>
/// <para>
/// If the specified size is less than the current size, the function succeeds but ignores this request. Therefore, you cannot use this
/// function to reduce the size of the stack.
/// </para>
/// <para>This value cannot be larger than the reserved stack size.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is 0 (zero). To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL WINAPI SetThreadStackGuarantee( _Inout_ PULONG StackSizeInBytes); https://msdn.microsoft.com/en-us/library/windows/desktop/ms686283(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms686283")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetThreadStackGuarantee(ref uint StackSizeInBytes);
/// <summary>
/// <para>Suspends the specified thread.</para>
/// <para>A 64-bit application can suspend a WOW64 thread using the <c>Wow64SuspendThread</c> function.</para>
/// </summary>
/// <param name="hThread">
/// <para>A handle to the thread that is to be suspended.</para>
/// <para>The handle must have the <c>THREAD_SUSPEND_RESUME</c> access right. For more information, see Thread Security and Access Rights.</para>
/// </param>
/// <returns>
/// If the function succeeds, the return value is the thread's previous suspend count; otherwise, it is . To get extended error
/// information, use the <c>GetLastError</c> function.
/// </returns>
// DWORD WINAPI SuspendThread( _In_ HANDLE hThread); https://msdn.microsoft.com/en-us/library/windows/desktop/ms686345(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms686345")]
public static extern uint SuspendThread(HTHREAD hThread);
/// <summary>
/// Causes the calling thread to yield execution to another thread that is ready to run on the current processor. The operating system
/// selects the next thread to be executed.
/// </summary>
/// <returns>
/// <para>
/// If calling the <c>SwitchToThread</c> function causes the operating system to switch execution to another thread, the return value is nonzero.
/// </para>
/// <para>
/// If there are no other threads ready to execute, the operating system does not switch execution to another thread, and the return
/// value is zero.
/// </para>
/// </returns>
// BOOL WINAPI SwitchToThread(void); https://msdn.microsoft.com/en-us/library/windows/desktop/ms686352(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms686352")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SwitchToThread();
/// <summary>Terminates the specified process and all of its threads.</summary>
/// <param name="hProcess">
/// <para>A handle to the process to be terminated.</para>
/// <para>The handle must have the <c>PROCESS_TERMINATE</c> access right. For more information, see Process Security and Access Rights.</para>
/// </param>
/// <param name="uExitCode">
/// The exit code to be used by the process and threads terminated as a result of this call. Use the <c>GetExitCodeProcess</c> function
/// to retrieve a process's exit value. Use the <c>GetExitCodeThread</c> function to retrieve a thread's exit value.
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL WINAPI TerminateProcess( _In_ HANDLE hProcess, _In_ UINT uExitCode); https://msdn.microsoft.com/en-us/library/windows/desktop/ms686714(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms686714")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool TerminateProcess([In] HPROCESS hProcess, uint uExitCode);
/// <summary>Terminates a thread.</summary>
/// <param name="hThread">
/// <para>A handle to the thread to be terminated.</para>
/// <para>The handle must have the <c>THREAD_TERMINATE</c> access right. For more information, see Thread Security and Access Rights.</para>
/// </param>
/// <param name="dwExitCode">The exit code for the thread. Use the <c>GetExitCodeThread</c> function to retrieve a thread's exit value.</param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL WINAPI TerminateThread( _Inout_ HANDLE hThread, _In_ DWORD dwExitCode); https://msdn.microsoft.com/en-us/library/windows/desktop/ms686717(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms686717")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool TerminateThread([In] HTHREAD hThread, uint dwExitCode);
/// <summary>
/// Allocates a thread local storage (TLS) index. Any thread of the process can subsequently use this index to store and retrieve values
/// that are local to the thread, because each thread receives its own slot for the index.
/// </summary>
/// <returns>
/// <para>If the function succeeds, the return value is a TLS index. The slots for the index are initialized to zero.</para>
/// <para>If the function fails, the return value is <c>TLS_OUT_OF_INDEXES</c>. To get extended error information, call GetLastError.</para>
/// </returns>
/// <remarks>
/// <para>
/// <c>Windows Phone 8.1:</c> This function is supported for Windows Phone Store apps on Windows Phone 8.1 and later. When a Windows
/// Phone Store app calls this function, it is replaced with an inline call to <c>FlsAlloc</c>. Refer to FlsAlloc for function documentation.
/// </para>
/// <para>
/// <c>Windows 8.1</c>, <c>Windows Server 2012 R2</c>, and <c>Windows 10, version 1507</c>: This function is supported for Windows Store
/// apps on Windows 8.1, Windows Server 2012 R2, and Windows 10, version 1507. When a Windows Store app calls this function, it is
/// replaced with an inline call to <c>FlsAlloc</c>. Refer to FlsAlloc for function documentation.
/// </para>
/// <para>
/// <c>Windows 10, version 1511</c> and <c>Windows 10, version 1607</c>: This function is fully supported for Universal Windows Platform
/// (UWP) apps, and is no longer replaced with an inline call to <c>FlsAlloc</c>.
/// </para>
/// <para>
/// The threads of the process can use the TLS index in subsequent calls to the TlsFree, TlsSetValue, or TlsGetValue functions. The value
/// of the TLS index should be treated as an opaque value; do not assume that it is an index into a zero-based array.
/// </para>
/// <para>
/// TLS indexes are typically allocated during process or dynamic-link library (DLL) initialization. When a TLS index is allocated, its
/// storage slots are initialized to <c>NULL</c>. After a TLS index has been allocated, each thread of the process can use it to access
/// its own TLS storage slot. To store a value in its TLS slot, a thread specifies the index in a call to TlsSetValue. The thread
/// specifies the same index in a subsequent call to TlsGetValue, to retrieve the stored value.
/// </para>
/// <para>
/// TLS indexes are not valid across process boundaries. A DLL cannot assume that an index assigned in one process is valid in another process.
/// </para>
/// <para>Examples</para>
/// <para>For an example, see Using Thread Local Storage or Using Thread Local Storage in a Dynamic-Link Library.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-tlsalloc DWORD TlsAlloc( );
[DllImport(Lib.KernelBase, SetLastError = true, ExactSpelling = true)]
[PInvokeData("processthreadsapi.h", MSDNShortId = "cbb3d832-cd92-4875-8366-6b69be7a536f")]
public static extern uint TlsAlloc();
/// <summary>Releases a thread local storage (TLS) index, making it available for reuse.</summary>
/// <param name="dwTlsIndex">The TLS index that was allocated by the TlsAlloc function.</param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
/// </returns>
/// <remarks>
/// <para>
/// <c>Windows Phone 8.1:</c> This function is supported for Windows Phone Store apps on Windows Phone 8.1 and later. When a Windows
/// Phone Store app calls this function, it is replaced with an inline call to <c>FlsFree</c>. Refer to FlsFree for function documentation.
/// </para>
/// <para>
/// <c>Windows 8.1</c>, <c>Windows Server 2012 R2</c>, and <c>Windows 10, version 1507</c>: This function is supported for Windows Store
/// apps on Windows 8.1, Windows Server 2012 R2, and Windows 10, version 1507. When a Windows Store app calls this function, it is
/// replaced with an inline call to <c>FlsFree</c>. Refer to FlsFree for function documentation.
/// </para>
/// <para>
/// <c>Windows 10, version 1511</c> and <c>Windows 10, version 1607</c>: This function is fully supported for Universal Windows Platform
/// (UWP) apps, and is no longer replaced with an inline call to <c>FlsFree</c>.
/// </para>
/// <para>
/// If the threads of the process have allocated memory and stored a pointer to the memory in a TLS slot, they should free the memory
/// before calling <c>TlsFree</c>. The <c>TlsFree</c> function does not free memory blocks whose addresses have been stored in the TLS
/// slots associated with the TLS index. It is expected that DLLs call this function (if at all) only during <c>DLL_PROCESS_DETACH</c>.
/// </para>
/// <para>For more information, see Thread Local Storage.</para>
/// <para>Examples</para>
/// <para>For an example, see Using Thread Local Storage or Using Thread Local Storage in a Dynamic-Link Library.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-tlsfree BOOL TlsFree( DWORD dwTlsIndex );
[DllImport(Lib.KernelBase, SetLastError = true, ExactSpelling = true)]
[PInvokeData("processthreadsapi.h", MSDNShortId = "f5b1e8fc-02eb-4a06-b606-2b647944029b")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool TlsFree(uint dwTlsIndex);
/// <summary>
/// Retrieves the value in the calling thread's thread local storage (TLS) slot for the specified TLS index. Each thread of a process has
/// its own slot for each TLS index.
/// </summary>
/// <param name="dwTlsIndex">The TLS index that was allocated by the TlsAlloc function.</param>
/// <returns>
/// <para>
/// If the function succeeds, the return value is the value stored in the calling thread's TLS slot associated with the specified index.
/// If dwTlsIndex is a valid index allocated by a successful call to TlsAlloc, this function always succeeds.
/// </para>
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
/// <para>
/// The data stored in a TLS slot can have a value of 0 because it still has its initial value or because the thread called the
/// TlsSetValue function with 0. Therefore, if the return value is 0, you must check whether GetLastError returns <c>ERROR_SUCCESS</c>
/// before determining that the function has failed. If <c>GetLastError</c> returns <c>ERROR_SUCCESS</c>, then the function has succeeded
/// and the data stored in the TLS slot is 0. Otherwise, the function has failed.
/// </para>
/// <para>
/// Functions that return indications of failure call SetLastErrorwhen they fail. They generally do not call <c>SetLastError</c> when
/// they succeed. The <c>TlsGetValue</c> function is an exception to this general rule. The <c>TlsGetValue</c> function calls
/// <c>SetLastError</c> to clear a thread's last error when it succeeds. That allows checking for the error-free retrieval of zero values.
/// </para>
/// </returns>
/// <remarks>
/// <para>
/// <c>Windows Phone 8.1:</c> This function is supported for Windows Phone Store apps on Windows Phone 8.1 and later. When a Windows
/// Phone Store app calls this function, it is replaced with an inline call to <c>FlsGetValue</c>. Refer to FlsGetValue for function documentation.
/// </para>
/// <para>
/// <c>Windows 8.1</c>, <c>Windows Server 2012 R2</c>, and <c>Windows 10, version 1507</c>: This function is supported for Windows Store
/// apps on Windows 8.1, Windows Server 2012 R2, and Windows 10, version 1507. When a Windows Store app calls this function, it is
/// replaced with an inline call to <c>FlsGetValue</c>. Refer to FlsGetValue for function documentation.
/// </para>
/// <para>
/// <c>Windows 10, version 1511</c> and <c>Windows 10, version 1607</c>: This function is fully supported for Universal Windows Platform
/// (UWP) apps, and is no longer replaced with an inline call to <c>FlsGetValue</c>.
/// </para>
/// <para>
/// TLS indexes are typically allocated by the TlsAlloc function during process or DLL initialization. After a TLS index is allocated,
/// each thread of the process can use it to access its own TLS slot for that index. A thread specifies a TLS index in a call to
/// TlsSetValue to store a value in its slot. The thread specifies the same index in a subsequent call to <c>TlsGetValue</c> to retrieve
/// the stored value.
/// </para>
/// <para>
/// <c>TlsGetValue</c> was implemented with speed as the primary goal. The function performs minimal parameter validation and error
/// checking. In particular, it succeeds if dwTlsIndex is in the range 0 through ( <c>TLS_MINIMUM_AVAILABLE</c> 1). It is up to the
/// programmer to ensure that the index is valid and that the thread calls TlsSetValue before calling <c>TlsGetValue</c>.
/// </para>
/// <para>Examples</para>
/// <para>For an example, see Using Thread Local Storage or Using Thread Local Storage in a Dynamic-Link Library.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-tlsgetvalue LPVOID TlsGetValue( DWORD
// dwTlsIndex );
[DllImport(Lib.KernelBase, SetLastError = true, ExactSpelling = true)]
[PInvokeData("processthreadsapi.h", MSDNShortId = "82bd5ff6-ff0b-42b7-9ece-e9e8531eb5fb")]
public static extern IntPtr TlsGetValue(uint dwTlsIndex);
/// <summary>
/// Stores a value in the calling thread's thread local storage (TLS) slot for the specified TLS index. Each thread of a process has its
/// own slot for each TLS index.
/// </summary>
/// <param name="dwTlsIndex">The TLS index that was allocated by the TlsAlloc function.</param>
/// <param name="lpTlsValue">The value to be stored in the calling thread's TLS slot for the index.</param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
/// </returns>
/// <remarks>
/// <para>
/// <c>Windows Phone 8.1:</c> This function is supported for Windows Phone Store apps on Windows Phone 8.1 and later. When a Windows
/// Phone Store app calls this function, it is replaced with an inline call to <c>FlsSetValue</c>. Refer to FlsSetValue for function documentation.
/// </para>
/// <para>
/// <c>Windows 8.1</c>, <c>Windows Server 2012 R2</c>, and <c>Windows 10, version 1507</c>: This function is supported for Windows Store
/// apps on Windows 8.1, Windows Server 2012 R2, and Windows 10, version 1507. When a Windows Store app calls this function, it is
/// replaced with an inline call to <c>FlsSetValue</c>. Refer to FlsSetValue for function documentation.
/// </para>
/// <para>
/// <c>Windows 10, version 1511</c> and <c>Windows 10, version 1607</c>: This function is fully supported for Universal Windows Platform
/// (UWP) apps, and is no longer replaced with an inline call to <c>FlsSetValue</c>.
/// </para>
/// <para>
/// TLS indexes are typically allocated by the TlsAlloc function during process or DLL initialization. When a TLS index is allocated, its
/// storage slots are initialized to NULL. After a TLS index is allocated, each thread of the process can use it to access its own TLS
/// slot for that index. A thread specifies a TLS index in a call to <c>TlsSetValue</c>, to store a value in its slot. The thread
/// specifies the same index in a subsequent call to TlsGetValue, to retrieve the stored value.
/// </para>
/// <para>
/// <c>TlsSetValue</c> was implemented with speed as the primary goal. The function performs minimal parameter validation and error
/// checking. In particular, it succeeds if dwTlsIndex is in the range 0 through ( <c>TLS_MINIMUM_AVAILABLE</c> 1). It is up to the
/// programmer to ensure that the index is valid before calling TlsGetValue.
/// </para>
/// <para>Examples</para>
/// <para>For an example, see Using Thread Local Storage or Using Thread Local Storage in a Dynamic-Link Library.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-tlssetvalue BOOL TlsSetValue( DWORD
// dwTlsIndex, LPVOID lpTlsValue );
[DllImport(Lib.KernelBase, SetLastError = true, ExactSpelling = true)]
[PInvokeData("processthreadsapi.h", MSDNShortId = "531b4a4a-a251-4ab4-b00a-754783a51283")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool TlsSetValue(uint dwTlsIndex, [In] IntPtr lpTlsValue);
/// <summary>Updates the specified attribute in a list of attributes for process and thread creation.</summary>
/// <param name="lpAttributeList">A pointer to an attribute list created by the <c>InitializeProcThreadAttributeList</c> function.</param>
/// <param name="dwFlags">This parameter is reserved and must be zero.</param>
/// <param name="Attribute">
/// <para>The attribute key to update in the attribute list. This parameter can be one of the following values.</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PROC_THREAD_ATTRIBUTE_GROUP_AFFINITY</term>
/// <term>
/// The lpValue parameter is a pointer to a GROUP_AFFINITY structure that specifies the processor group affinity for the new
/// thread.Windows Server 2008 and Windows Vista: This value is not supported until Windows 7 and Windows Server 2008 R2.
/// </term>
/// </item>
/// <item>
/// <term>PROC_THREAD_ATTRIBUTE_HANDLE_LIST</term>
/// <term>
/// The lpValue parameter is a pointer to a list of handles to be inherited by the child process.These handles must be created as
/// inheritable handles and must not include pseudo handles such as those returned by the GetCurrentProcess or GetCurrentThread function.
/// </term>
/// </item>
/// <item>
/// <term>PROC_THREAD_ATTRIBUTE_IDEAL_PROCESSOR</term>
/// <term>
/// The lpValue parameter is a pointer to a PROCESSOR_NUMBER structure that specifies the ideal processor for the new thread.Windows
/// Server 2008 and Windows Vista: This value is not supported until Windows 7 and Windows Server 2008 R2.
/// </term>
/// </item>
/// <item>
/// <term>PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY</term>
/// <term>
/// The lpValue parameter is a pointer to a DWORD or DWORD64 that specifies the exploit mitigation policy for the child process. Starting
/// in Windows 10, version 1703, this parameter can also be a pointer to a two-element DWORD64 array.The specified policy overrides the
/// policies set for the application and the system and cannot be changed after the child process starts running. Windows Server 2008 and
/// Windows Vista: This value is not supported until Windows 7 and Windows Server 2008 R2.The DWORD or DWORD64 pointed to by lpValue can
/// be one or more of the values listed in the remarks.
/// </term>
/// </item>
/// <item>
/// <term>PROC_THREAD_ATTRIBUTE_PARENT_PROCESS</term>
/// <term>
/// The lpValue parameter is a pointer to a handle to a process to use instead of the calling process as the parent for the process being
/// created. The process to use must have the PROCESS_CREATE_PROCESS access right.Attributes inherited from the specified process include
/// handles, the device map, processor affinity, priority, quotas, the process token, and job object. (Note that some attributes such as
/// the debug port will come from the creating process, not the process specified by this handle.)
/// </term>
/// </item>
/// <item>
/// <term>PROC_THREAD_ATTRIBUTE_PREFERRED_NODE</term>
/// <term>
/// The lpValue parameter is a pointer to the node number of the preferred NUMA node for the new process.Windows Server 2008 and Windows
/// Vista: This value is not supported until Windows 7 and Windows Server 2008 R2.
/// </term>
/// </item>
/// <item>
/// <term>PROC_THREAD_ATTRIBUTE_UMS_THREAD</term>
/// <term>
/// The lpValue parameter is a pointer to a UMS_CREATE_THREAD_ATTRIBUTES structure that specifies a user-mode scheduling (UMS) thread
/// context and a UMS completion list to associate with the thread. After the UMS thread is created, the system queues it to the
/// specified completion list. The UMS thread runs only when an application's UMS scheduler retrieves the UMS thread from the completion
/// list and selects it to run. For more information, see User-Mode Scheduling.Windows Server 2008 and Windows Vista: This value is not
/// supported until Windows 7 and Windows Server 2008 R2.
/// </term>
/// </item>
/// <item>
/// <term>PROC_THREAD_ATTRIBUTE_SECURITY_CAPABILITIES</term>
/// <term>
/// The lpValue parameter is a pointer to a SECURITY_CAPABILITIES structure that defines the security capabilities of an app container.
/// If this attribute is set the new process will be created as an AppContainer process.Windows 7, Windows Server 2008 R2, Windows Server
/// 2008 and Windows Vista: This value is not supported until Windows 8 and Windows Server 2012.
/// </term>
/// </item>
/// <item>
/// <term>PROC_THREAD_ATTRIBUTE_PROTECTION_LEVEL</term>
/// <term>
/// The lpValue parameter is a pointer to a DWORD value of PROTECTION_LEVEL_SAME. This specifies the protection level of the child
/// process to be the same as the protection level of its parent process.
/// </term>
/// </item>
/// <item>
/// <term>PROC_THREAD_ATTRIBUTE_CHILD_PROCESS_POLICY</term>
/// <term>
/// The lpValue parameter is a pointer to a DWORD or DWORD64 value that specifies the child process policy. THe policy specifies whether
/// to allow a child process to be created.For information on the possible values for the DWORD or DWORD64 to which lpValue points, see Remarks.
/// </term>
/// </item>
/// <item>
/// <term>PROC_THREAD_ATTRIBUTE_DESKTOP_APP_POLICY</term>
/// <term>
/// This attribute is relevant only to win32 applications that have been converted to UWP packages by using the Desktop Bridge. The
/// lpValue parameter is a pointer to a DWORD value that specifies the desktop app policy. The policy specifies whether descendant
/// processes should continue to run in the desktop environment.For information about the possible values for the DWORD to which lpValue
/// points, see Remarks.
/// </term>
/// </item>
/// </list>
/// </para>
/// </param>
/// <param name="lpValue">
/// A pointer to the attribute value. This value should persist until the attribute is destroyed using the
/// <c>DeleteProcThreadAttributeList</c> function.
/// </param>
/// <param name="cbSize">The size of the attribute value specified by the lpValue parameter.</param>
/// <param name="lpPreviousValue">This parameter is reserved and must be NULL.</param>
/// <param name="lpReturnSize">This parameter is reserved and must be NULL.</param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// </returns>
// BOOL WINAPI UpdateProcThreadAttribute( _Inout_ LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList, _In_ DWORD dwFlags, _In_ DWORD_PTR
// Attribute, _In_ PVOID lpValue, _In_ SIZE_T cbSize, _Out_opt_ PVOID lpPreviousValue, _In_opt_ PSIZE_T lpReturnSize); https://msdn.microsoft.com/en-us/library/windows/desktop/ms686880(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
[PInvokeData("WinBase.h", MSDNShortId = "ms686880")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool UpdateProcThreadAttribute(IntPtr lpAttributeList, [Optional] uint dwFlags, PROC_THREAD_ATTRIBUTE Attribute, IntPtr lpValue, SizeT cbSize, [Optional] IntPtr lpPreviousValue, [Optional] IntPtr lpReturnSize);
/// <summary>
/// <para>Creates a new process and its primary thread. The new process runs in the security context of the calling process.</para>
/// <para>
/// If the calling process is impersonating another user, the new process uses the token for the calling process, not the impersonation
/// token. To run the new process in the security context of the user represented by the impersonation token, use the
/// <c>CreateProcessAsUser</c> or <c>CreateProcessWithLogonW</c> function.
/// </para>
/// </summary>
/// <param name="lpApplicationName">
/// <para>
/// The name of the module to be executed. This module can be a Windows-based application. It can be some other type of module (for
/// example, MS-DOS or OS/2) if the appropriate subsystem is available on the local computer.
/// </para>
/// <para>
/// The string can specify the full path and file name of the module to execute or it can specify a partial name. In the case of a
/// partial name, the function uses the current drive and current directory to complete the specification. The function will not use the
/// search path. This parameter must include the file name extension; no default extension is assumed.
/// </para>
/// <para>
/// The lpApplicationName parameter can be <c>NULL</c>. In that case, the module name must be the first white spacedelimited token in
/// the lpCommandLine string. If you are using a long file name that contains a space, use quoted strings to indicate where the file name
/// ends and the arguments begin; otherwise, the file name is ambiguous. For example, consider the string "c:\program files\sub
/// dir\program name". This string can be interpreted in a number of ways. The system tries to interpret the possibilities in the
/// following order:
/// </para>
/// <para>
/// If the executable module is a 16-bit application, lpApplicationName should be <c>NULL</c>, and the string pointed to by lpCommandLine
/// should specify the executable module as well as its arguments.
/// </para>
/// <para>
/// To run a batch file, you must start the command interpreter; set lpApplicationName to cmd.exe and set lpCommandLine to the following
/// arguments: /c plus the name of the batch file.
/// </para>
/// </param>
/// <param name="lpCommandLine">
/// <para>
/// The command line to be executed. The maximum length of this string is 32,768 characters, including the Unicode terminating null
/// character. If lpApplicationName is <c>NULL</c>, the module name portion of lpCommandLine is limited to <c>MAX_PATH</c> characters.
/// </para>
/// <para>
/// The Unicode version of this function, <c>CreateProcessW</c>, can modify the contents of this string. Therefore, this parameter cannot
/// be a pointer to read-only memory (such as a <c>const</c> variable or a literal string). If this parameter is a constant string, the
/// function may cause an access violation.
/// </para>
/// <para>
/// The lpCommandLine parameter can be NULL. In that case, the function uses the string pointed to by lpApplicationName as the command line.
/// </para>
/// <para>
/// If both lpApplicationName and lpCommandLine are non- <c>NULL</c>, the null-terminated string pointed to by lpApplicationName
/// specifies the module to execute, and the null-terminated string pointed to by lpCommandLine specifies the command line. The new
/// process can use <c>GetCommandLine</c> to retrieve the entire command line. Console processes written in C can use the argc and argv
/// arguments to parse the command line. Because argv[0] is the module name, C programmers generally repeat the module name as the first
/// token in the command line.
/// </para>
/// <para>
/// If lpApplicationName is NULL, the first white spacedelimited token of the command line specifies the module name. If you are using a
/// long file name that contains a space, use quoted strings to indicate where the file name ends and the arguments begin (see the
/// explanation for the lpApplicationName parameter). If the file name does not contain an extension, .exe is appended. Therefore, if the
/// file name extension is .com, this parameter must include the .com extension. If the file name ends in a period (.) with no extension,
/// or if the file name contains a path, .exe is not appended. If the file name does not contain a directory path, the system searches
/// for the executable file in the following sequence:
/// </para>
/// <para>
/// The system adds a terminating null character to the command-line string to separate the file name from the arguments. This divides
/// the original string into two strings for internal processing.
/// </para>
/// </param>
/// <param name="lpProcessAttributes">
/// <para>
/// A pointer to a <c>SECURITY_ATTRIBUTES</c> structure that determines whether the returned handle to the new process object can be
/// inherited by child processes. If lpProcessAttributes is <c>NULL</c>, the handle cannot be inherited.
/// </para>
/// <para>
/// The <c>lpSecurityDescriptor</c> member of the structure specifies a security descriptor for the new process. If lpProcessAttributes
/// is NULL or <c>lpSecurityDescriptor</c> is <c>NULL</c>, the process gets a default security descriptor. The ACLs in the default
/// security descriptor for a process come from the primary token of the creator.
/// </para>
/// <para>
/// <c>Windows XP:</c> The ACLs in the default security descriptor for a process come from the primary or impersonation token of the
/// creator. This behavior changed with Windows XP with SP2 and Windows Server 2003.
/// </para>
/// </param>
/// <param name="lpThreadAttributes">
/// <para>
/// A pointer to a <c>SECURITY_ATTRIBUTES</c> structure that determines whether the returned handle to the new thread object can be
/// inherited by child processes. If lpThreadAttributes is NULL, the handle cannot be inherited.
/// </para>
/// <para>
/// The <c>lpSecurityDescriptor</c> member of the structure specifies a security descriptor for the main thread. If lpThreadAttributes is
/// NULL or <c>lpSecurityDescriptor</c> is NULL, the thread gets a default security descriptor. The ACLs in the default security
/// descriptor for a thread come from the process token.
/// </para>
/// <para>
/// <c>Windows XP:</c> The ACLs in the default security descriptor for a thread come from the primary or impersonation token of the
/// creator. This behavior changed with Windows XP with SP2 and Windows Server 2003.
/// </para>
/// </param>
/// <param name="bInheritHandles">
/// <para>
/// If this parameter is TRUE, each inheritable handle in the calling process is inherited by the new process. If the parameter is FALSE,
/// the handles are not inherited. Note that inherited handles have the same value and access rights as the original handles.
/// </para>
/// <para>
/// <c>Terminal Services:</c> You cannot inherit handles across sessions. Additionally, if this parameter is TRUE, you must create the
/// process in the same session as the caller.
/// </para>
/// <para>
/// <c>Protected Process Light (PPL) processes:</c> The generic handle inheritance is blocked when a PPL process creates a non-PPL
/// process since PROCESS_DUP_HANDLE is not allowed from a non-PPL process to a PPL process. See Process Security and Access Rights
/// </para>
/// </param>
/// <param name="dwCreationFlags">
/// <para>The flags that control the priority class and the creation of the process. For a list of values, see Process Creation Flags.</para>
/// <para>
/// This parameter also controls the new process's priority class, which is used to determine the scheduling priorities of the process's
/// threads. For a list of values, see <c>GetPriorityClass</c>. If none of the priority class flags is specified, the priority class
/// defaults to <c>NORMAL_PRIORITY_CLASS</c> unless the priority class of the creating process is <c>IDLE_PRIORITY_CLASS</c> or
/// <c>BELOW_NORMAL_PRIORITY_CLASS</c>. In this case, the child process receives the default priority class of the calling process.
/// </para>
/// </param>
/// <param name="lpEnvironment">
/// <para>
/// A pointer to the environment block for the new process. If this parameter is <c>NULL</c>, the new process uses the environment of the
/// calling process.
/// </para>
/// <para>An environment block consists of a null-terminated block of null-terminated strings. Each string is in the following form:</para>
/// <para>name=value\0</para>
/// <para>Because the equal sign is used as a separator, it must not be used in the name of an environment variable.</para>
/// <para>
/// An environment block can contain either Unicode or ANSI characters. If the environment block pointed to by lpEnvironment contains
/// Unicode characters, be sure that dwCreationFlags includes <c>CREATE_UNICODE_ENVIRONMENT</c>. If this parameter is <c>NULL</c> and the
/// environment block of the parent process contains Unicode characters, you must also ensure that dwCreationFlags includes <c>CREATE_UNICODE_ENVIRONMENT</c>.
/// </para>
/// <para>
/// The ANSI version of this function, <c>CreateProcessA</c> fails if the total size of the environment block for the process exceeds
/// 32,767 characters.
/// </para>
/// <para>
/// Note that an ANSI environment block is terminated by two zero bytes: one for the last string, one more to terminate the block. A
/// Unicode environment block is terminated by four zero bytes: two for the last string, two more to terminate the block.
/// </para>
/// </param>
/// <param name="lpCurrentDirectory">
/// <para>The full path to the current directory for the process. The string can also specify a UNC path.</para>
/// <para>
/// If this parameter is <c>NULL</c>, the new process will have the same current drive and directory as the calling process. (This
/// feature is provided primarily for shells that need to start an application and specify its initial drive and working directory.)
/// </para>
/// </param>
/// <param name="lpStartupInfo">
/// <para>A pointer to a <c>STARTUPINFO</c> or <c>STARTUPINFOEX</c> structure.</para>
/// <para>
/// To set extended attributes, use a <c>STARTUPINFOEX</c> structure and specify EXTENDED_STARTUPINFO_PRESENT in the dwCreationFlags parameter.
/// </para>
/// <para>Handles in <c>STARTUPINFO</c> or <c>STARTUPINFOEX</c> must be closed with <c>CloseHandle</c> when they are no longer needed.</para>
/// </param>
/// <param name="lpProcessInformation">
/// <para>A pointer to a <c>PROCESS_INFORMATION</c> structure that receives identification information about the new process.</para>
/// <para>Handles in <c>PROCESS_INFORMATION</c> must be closed with <c>CloseHandle</c> when they are no longer needed.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// <para>
/// Note that the function returns before the process has finished initialization. If a required DLL cannot be located or fails to
/// initialize, the process is terminated. To get the termination status of a process, call <c>GetExitCodeProcess</c>.
/// </para>
/// </returns>
// BOOL WINAPI CreateProcess( _In_opt_ LPCTSTR lpApplicationName, _Inout_opt_ LPTSTR lpCommandLine, _In_opt_ LPSECURITY_ATTRIBUTES
// lpProcessAttributes, _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ BOOL bInheritHandles, _In_ DWORD dwCreationFlags,
// _In_opt_ LPVOID lpEnvironment, _In_opt_ LPCTSTR lpCurrentDirectory, _In_ LPSTARTUPINFO lpStartupInfo, _Out_ LPPROCESS_INFORMATION
// lpProcessInformation); https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("WinBase.h", MSDNShortId = "ms682425")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CreateProcess(string lpApplicationName, StringBuilder lpCommandLine, [In] SECURITY_ATTRIBUTES lpProcessAttributes,
[In] SECURITY_ATTRIBUTES lpThreadAttributes, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandles, CREATE_PROCESS dwCreationFlags,
[In, Optional, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(NullTermStringArrayMarshaler), MarshalCookie = "Auto")] string[] lpEnvironment,
string lpCurrentDirectory, in STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
/// <summary>
/// <para>Creates a new process and its primary thread. The new process runs in the security context of the calling process.</para>
/// <para>
/// If the calling process is impersonating another user, the new process uses the token for the calling process, not the impersonation
/// token. To run the new process in the security context of the user represented by the impersonation token, use the
/// <c>CreateProcessAsUser</c> or <c>CreateProcessWithLogonW</c> function.
/// </para>
/// </summary>
/// <param name="lpApplicationName">
/// <para>
/// The name of the module to be executed. This module can be a Windows-based application. It can be some other type of module (for
/// example, MS-DOS or OS/2) if the appropriate subsystem is available on the local computer.
/// </para>
/// <para>
/// The string can specify the full path and file name of the module to execute or it can specify a partial name. In the case of a
/// partial name, the function uses the current drive and current directory to complete the specification. The function will not use the
/// search path. This parameter must include the file name extension; no default extension is assumed.
/// </para>
/// <para>
/// The lpApplicationName parameter can be <c>NULL</c>. In that case, the module name must be the first white spacedelimited token in
/// the lpCommandLine string. If you are using a long file name that contains a space, use quoted strings to indicate where the file name
/// ends and the arguments begin; otherwise, the file name is ambiguous. For example, consider the string "c:\program files\sub
/// dir\program name". This string can be interpreted in a number of ways. The system tries to interpret the possibilities in the
/// following order:
/// </para>
/// <para>
/// If the executable module is a 16-bit application, lpApplicationName should be <c>NULL</c>, and the string pointed to by lpCommandLine
/// should specify the executable module as well as its arguments.
/// </para>
/// <para>
/// To run a batch file, you must start the command interpreter; set lpApplicationName to cmd.exe and set lpCommandLine to the following
/// arguments: /c plus the name of the batch file.
/// </para>
/// </param>
/// <param name="lpCommandLine">
/// <para>
/// The command line to be executed. The maximum length of this string is 32,768 characters, including the Unicode terminating null
/// character. If lpApplicationName is <c>NULL</c>, the module name portion of lpCommandLine is limited to <c>MAX_PATH</c> characters.
/// </para>
/// <para>
/// The Unicode version of this function, <c>CreateProcessW</c>, can modify the contents of this string. Therefore, this parameter cannot
/// be a pointer to read-only memory (such as a <c>const</c> variable or a literal string). If this parameter is a constant string, the
/// function may cause an access violation.
/// </para>
/// <para>
/// The lpCommandLine parameter can be NULL. In that case, the function uses the string pointed to by lpApplicationName as the command line.
/// </para>
/// <para>
/// If both lpApplicationName and lpCommandLine are non- <c>NULL</c>, the null-terminated string pointed to by lpApplicationName
/// specifies the module to execute, and the null-terminated string pointed to by lpCommandLine specifies the command line. The new
/// process can use <c>GetCommandLine</c> to retrieve the entire command line. Console processes written in C can use the argc and argv
/// arguments to parse the command line. Because argv[0] is the module name, C programmers generally repeat the module name as the first
/// token in the command line.
/// </para>
/// <para>
/// If lpApplicationName is NULL, the first white spacedelimited token of the command line specifies the module name. If you are using a
/// long file name that contains a space, use quoted strings to indicate where the file name ends and the arguments begin (see the
/// explanation for the lpApplicationName parameter). If the file name does not contain an extension, .exe is appended. Therefore, if the
/// file name extension is .com, this parameter must include the .com extension. If the file name ends in a period (.) with no extension,
/// or if the file name contains a path, .exe is not appended. If the file name does not contain a directory path, the system searches
/// for the executable file in the following sequence:
/// </para>
/// <para>
/// The system adds a terminating null character to the command-line string to separate the file name from the arguments. This divides
/// the original string into two strings for internal processing.
/// </para>
/// </param>
/// <param name="lpProcessAttributes">
/// <para>
/// A pointer to a <c>SECURITY_ATTRIBUTES</c> structure that determines whether the returned handle to the new process object can be
/// inherited by child processes. If lpProcessAttributes is <c>NULL</c>, the handle cannot be inherited.
/// </para>
/// <para>
/// The <c>lpSecurityDescriptor</c> member of the structure specifies a security descriptor for the new process. If lpProcessAttributes
/// is NULL or <c>lpSecurityDescriptor</c> is <c>NULL</c>, the process gets a default security descriptor. The ACLs in the default
/// security descriptor for a process come from the primary token of the creator.
/// </para>
/// <para>
/// <c>Windows XP:</c> The ACLs in the default security descriptor for a process come from the primary or impersonation token of the
/// creator. This behavior changed with Windows XP with SP2 and Windows Server 2003.
/// </para>
/// </param>
/// <param name="lpThreadAttributes">
/// <para>
/// A pointer to a <c>SECURITY_ATTRIBUTES</c> structure that determines whether the returned handle to the new thread object can be
/// inherited by child processes. If lpThreadAttributes is NULL, the handle cannot be inherited.
/// </para>
/// <para>
/// The <c>lpSecurityDescriptor</c> member of the structure specifies a security descriptor for the main thread. If lpThreadAttributes is
/// NULL or <c>lpSecurityDescriptor</c> is NULL, the thread gets a default security descriptor. The ACLs in the default security
/// descriptor for a thread come from the process token.
/// </para>
/// <para>
/// <c>Windows XP:</c> The ACLs in the default security descriptor for a thread come from the primary or impersonation token of the
/// creator. This behavior changed with Windows XP with SP2 and Windows Server 2003.
/// </para>
/// </param>
/// <param name="bInheritHandles">
/// <para>
/// If this parameter is TRUE, each inheritable handle in the calling process is inherited by the new process. If the parameter is FALSE,
/// the handles are not inherited. Note that inherited handles have the same value and access rights as the original handles.
/// </para>
/// <para>
/// <c>Terminal Services:</c> You cannot inherit handles across sessions. Additionally, if this parameter is TRUE, you must create the
/// process in the same session as the caller.
/// </para>
/// <para>
/// <c>Protected Process Light (PPL) processes:</c> The generic handle inheritance is blocked when a PPL process creates a non-PPL
/// process since PROCESS_DUP_HANDLE is not allowed from a non-PPL process to a PPL process. See Process Security and Access Rights
/// </para>
/// </param>
/// <param name="dwCreationFlags">
/// <para>The flags that control the priority class and the creation of the process. For a list of values, see Process Creation Flags.</para>
/// <para>
/// This parameter also controls the new process's priority class, which is used to determine the scheduling priorities of the process's
/// threads. For a list of values, see <c>GetPriorityClass</c>. If none of the priority class flags is specified, the priority class
/// defaults to <c>NORMAL_PRIORITY_CLASS</c> unless the priority class of the creating process is <c>IDLE_PRIORITY_CLASS</c> or
/// <c>BELOW_NORMAL_PRIORITY_CLASS</c>. In this case, the child process receives the default priority class of the calling process.
/// </para>
/// </param>
/// <param name="lpEnvironment">
/// <para>
/// A pointer to the environment block for the new process. If this parameter is <c>NULL</c>, the new process uses the environment of the
/// calling process.
/// </para>
/// <para>An environment block consists of a null-terminated block of null-terminated strings. Each string is in the following form:</para>
/// <para>name=value\0</para>
/// <para>Because the equal sign is used as a separator, it must not be used in the name of an environment variable.</para>
/// <para>
/// An environment block can contain either Unicode or ANSI characters. If the environment block pointed to by lpEnvironment contains
/// Unicode characters, be sure that dwCreationFlags includes <c>CREATE_UNICODE_ENVIRONMENT</c>. If this parameter is <c>NULL</c> and the
/// environment block of the parent process contains Unicode characters, you must also ensure that dwCreationFlags includes <c>CREATE_UNICODE_ENVIRONMENT</c>.
/// </para>
/// <para>
/// The ANSI version of this function, <c>CreateProcessA</c> fails if the total size of the environment block for the process exceeds
/// 32,767 characters.
/// </para>
/// <para>
/// Note that an ANSI environment block is terminated by two zero bytes: one for the last string, one more to terminate the block. A
/// Unicode environment block is terminated by four zero bytes: two for the last string, two more to terminate the block.
/// </para>
/// </param>
/// <param name="lpCurrentDirectory">
/// <para>The full path to the current directory for the process. The string can also specify a UNC path.</para>
/// <para>
/// If this parameter is <c>NULL</c>, the new process will have the same current drive and directory as the calling process. (This
/// feature is provided primarily for shells that need to start an application and specify its initial drive and working directory.)
/// </para>
/// </param>
/// <param name="lpStartupInfo">
/// <para>A pointer to a <c>STARTUPINFO</c> or <c>STARTUPINFOEX</c> structure.</para>
/// <para>
/// To set extended attributes, use a <c>STARTUPINFOEX</c> structure and specify EXTENDED_STARTUPINFO_PRESENT in the dwCreationFlags parameter.
/// </para>
/// <para>Handles in <c>STARTUPINFO</c> or <c>STARTUPINFOEX</c> must be closed with <c>CloseHandle</c> when they are no longer needed.</para>
/// </param>
/// <param name="lpProcessInformation">
/// <para>A pointer to a <c>PROCESS_INFORMATION</c> structure that receives identification information about the new process.</para>
/// <para>Handles in <c>PROCESS_INFORMATION</c> must be closed with <c>CloseHandle</c> when they are no longer needed.</para>
/// </param>
/// <returns>
/// <para>If the function succeeds, the return value is nonzero.</para>
/// <para>If the function fails, the return value is zero. To get extended error information, call <c>GetLastError</c>.</para>
/// <para>
/// Note that the function returns before the process has finished initialization. If a required DLL cannot be located or fails to
/// initialize, the process is terminated. To get the termination status of a process, call <c>GetExitCodeProcess</c>.
/// </para>
/// </returns>
// BOOL WINAPI CreateProcess( _In_opt_ LPCTSTR lpApplicationName, _Inout_opt_ LPTSTR lpCommandLine, _In_opt_ LPSECURITY_ATTRIBUTES
// lpProcessAttributes, _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ BOOL bInheritHandles, _In_ DWORD dwCreationFlags,
// _In_opt_ LPVOID lpEnvironment, _In_opt_ LPCTSTR lpCurrentDirectory, _In_ LPSTARTUPINFO lpStartupInfo, _Out_ LPPROCESS_INFORMATION
// lpProcessInformation); https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("WinBase.h", MSDNShortId = "ms682425")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CreateProcess(string lpApplicationName, StringBuilder lpCommandLine, [In] SECURITY_ATTRIBUTES lpProcessAttributes,
[In] SECURITY_ATTRIBUTES lpThreadAttributes, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandles, CREATE_PROCESS dwCreationFlags,
[In, Optional, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(NullTermStringArrayMarshaler), MarshalCookie = "Auto")] string[] lpEnvironment,
string lpCurrentDirectory, in STARTUPINFOEX lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
/// <summary>Retrieves the contents of the <c>STARTUPINFO</c> structure that was specified when the calling process was created.</summary>
/// <param name="lpStartupInfo">A pointer to a <c>STARTUPINFO</c> structure that receives the startup information.</param>
/// <returns>
/// <para>This function does not return a value.</para>
/// <para>
/// If an error occurs, the ANSI version of this function ( <c>GetStartupInfoA</c>) can raise an exception. The Unicode version (
/// <c>GetStartupInfoW</c>) does not fail.
/// </para>
/// </returns>
// VOID WINAPI GetStartupInfo( _Out_ LPSTARTUPINFO lpStartupInfo); https://msdn.microsoft.com/en-us/library/windows/desktop/ms683230(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("WinBase.h", MSDNShortId = "ms683230")]
private static extern void GetStartupInfo(out STARTUPINFO_OUT lpStartupInfo);
private static bool Is64bitOS() => !(0 == GetSystemWow64Directory(null, 0) && Win32Error.GetLastError() == Win32Error.ERROR_CALL_NOT_IMPLEMENTED);
/// <summary>
/// Represents app memory usage at a single point in time. This structure is used by the <c>PROCESS_INFORMATION_CLASS</c> class.
/// </summary>
// typedef struct _APP_MEMORY_INFORMATION { ULONG64 AvailableCommit; ULONG64 PrivateCommitUsage; ULONG64 PeakPrivateCommitUsage; ULONG64
// TotalCommitUsage;} APP_MEMORY_INFORMATION, *PAPP_MEMORY_INFORMATION; https://msdn.microsoft.com/en-us/library/windows/desktop/mt767995(v=vs.85).aspx
[PInvokeData("WinBase.h", MSDNShortId = "mt767995")]
[StructLayout(LayoutKind.Sequential)]
public struct APP_MEMORY_INFORMATION
{
/// <summary>Total commit available to the app.</summary>
public ulong AvailableCommit;
/// <summary>The app's usage of private commit.</summary>
public ulong PrivateCommitUsage;
/// <summary>The app's peak usage of private commit.</summary>
public ulong PeakPrivateCommitUsage;
/// <summary>The app's total usage of private plus shared commit.</summary>
public ulong TotalCommitUsage;
}
/// <summary>
/// Specifies the memory priority for a thread or process. This structure is used by the <c>GetProcessInformation</c>,
/// <c>SetProcessInformation</c>, <c>GetThreadInformation</c>, and <c>SetThreadInformation</c> functions.
/// </summary>
// typedef struct _MEMORY_PRIORITY_INFORMATION { ULONG MemoryPriority;} MEMORY_PRIORITY_INFORMATION, *PMEMORY_PRIORITY_INFORMATION; https://msdn.microsoft.com/en-us/library/windows/desktop/hh448387(v=vs.85).aspx
[PInvokeData("WinBase.h", MSDNShortId = "hh448387")]
[StructLayout(LayoutKind.Sequential)]
public struct MEMORY_PRIORITY_INFORMATION
{
2018-05-13 23:41:49 -04:00
/// <summary>
/// <para>The memory priority for the thread or process. This member can be one of the following values.</para>
2018-05-13 23:41:49 -04:00
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
2018-05-13 23:41:49 -04:00
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>MEMORY_PRIORITY_VERY_LOW1</term>
/// <term>Very low memory priority.</term>
2018-05-13 23:41:49 -04:00
/// </item>
/// <item>
/// <term>MEMORY_PRIORITY_LOW2</term>
/// <term>Low memory priority.</term>
2018-05-13 23:41:49 -04:00
/// </item>
/// <item>
/// <term>MEMORY_PRIORITY_MEDIUM3</term>
/// <term>Medium memory priority.</term>
2018-05-13 23:41:49 -04:00
/// </item>
/// <item>
/// <term>MEMORY_PRIORITY_BELOW_NORMAL4</term>
/// <term>Below normal memory priority.</term>
2018-05-13 23:41:49 -04:00
/// </item>
/// <item>
/// <term>MEMORY_PRIORITY_NORMAL5</term>
/// <term>Normal memory priority. This is the default priority for all threads and processes on the system.</term>
2018-05-13 23:41:49 -04:00
/// </item>
/// </list>
/// </para>
/// </summary>
public MEMORY_PRIORITY MemoryPriority;
/// <summary>Initializes a new instance of the <see cref="MEMORY_PRIORITY_INFORMATION"/> struct.</summary>
/// <param name="memoryPriority">The memory priority for the thread or process.</param>
public MEMORY_PRIORITY_INFORMATION(MEMORY_PRIORITY memoryPriority) => MemoryPriority = memoryPriority;
}
/// <summary>Represents a process or thread attribute identifier.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct PROC_THREAD_ATTRIBUTE : IEquatable<PROC_THREAD_ATTRIBUTE>, IEquatable<UIntPtr>
{
private readonly UIntPtr value;
private const uint PROC_THREAD_ATTRIBUTE_NUMBER = 0x0000FFFF;
private const uint PROC_THREAD_ATTRIBUTE_THREAD = 0x00010000;
private const uint PROC_THREAD_ATTRIBUTE_INPUT = 0x00020000;
private const uint PROC_THREAD_ATTRIBUTE_ADDITIVE = 0x00040000;
private static readonly Dictionary<uint, Type> typeLookup = new();
static PROC_THREAD_ATTRIBUTE()
{
typeLookup.Add(PROC_THREAD_ATTRIBUTE_ALL_APPLICATION_PACKAGES_POLICY, null);
typeLookup.Add(PROC_THREAD_ATTRIBUTE_CHILD_PROCESS_POLICY, typeof(ulong));
typeLookup.Add(PROC_THREAD_ATTRIBUTE_DESKTOP_APP_POLICY, typeof(uint));
typeLookup.Add(PROC_THREAD_ATTRIBUTE_GROUP_AFFINITY, typeof(GROUP_AFFINITY));
typeLookup.Add(PROC_THREAD_ATTRIBUTE_HANDLE_LIST, typeof(HANDLE[]));
typeLookup.Add(PROC_THREAD_ATTRIBUTE_IDEAL_PROCESSOR, typeof(PROCESSOR_NUMBER));
typeLookup.Add(PROC_THREAD_ATTRIBUTE_JOB_LIST, null);
typeLookup.Add(PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY, typeof(ulong));
typeLookup.Add(PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, typeof(HPROCESS));
typeLookup.Add(PROC_THREAD_ATTRIBUTE_PREFERRED_NODE, typeof(uint));
typeLookup.Add(PROC_THREAD_ATTRIBUTE_PROTECTION_LEVEL, typeof(uint));
typeLookup.Add(PROC_THREAD_ATTRIBUTE_SECURITY_CAPABILITIES, typeof(SECURITY_CAPABILITIES));
typeLookup.Add(PROC_THREAD_ATTRIBUTE_UMS_THREAD, typeof(UMS_CREATE_THREAD_ATTRIBUTES));
typeLookup.Add(PROC_THREAD_ATTRIBUTE_WIN32K_FILTER, null);
}
/// <summary>Determines equality.</summary>
/// <param name="attr">The attribute to compare.</param>
/// <returns><see langword="true"/> if the value is equal to this instance.</returns>
public bool Equals(PROC_THREAD_ATTRIBUTE attr) => value.Equals(attr.value);
/// <summary>Determines equality.</summary>
/// <param name="puint">The <see cref="UIntPtr"/> value.</param>
/// <returns><see langword="true"/> if the value is equal to this instance.</returns>
public bool Equals(UIntPtr puint) => value.Equals(puint);
/// <summary>Determines whether the specified <see cref="object"/>, is equal to this instance.</summary>
/// <param name="obj">The <see cref="object"/> to compare with this instance.</param>
/// <returns><c>true</c> if the specified <see cref="object"/> is equal to this instance; otherwise, <c>false</c>.</returns>
public override bool Equals(object obj) => obj switch
{
PROC_THREAD_ATTRIBUTE pta => Equals(pta),
UIntPtr up => Equals(up),
uint ui => ui.Equals(this),
_ => base.Equals(obj),
};
/// <summary>Returns a hash code for this instance.</summary>
/// <returns>A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.</returns>
public override int GetHashCode() => unchecked((int)value.ToUInt32());
/// <summary>Performs an implicit conversion from <see cref="PROC_THREAD_ATTRIBUTE"/> to <see cref="uint"/>.</summary>
/// <param name="pta">The PROC_THREAD_ATTRIBUTE.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator uint(PROC_THREAD_ATTRIBUTE pta) => pta.value.ToUInt32();
/// <summary>A type specifier for an attribute.</summary>
public enum AttrType : uint
{
/// <summary>
/// The lpValue parameter is a pointer to a handle to a process to use instead of the calling process as the parent for the
/// process being created. The process to use must have the PROCESS_CREATE_PROCESS access right.
/// <para>
/// Attributes inherited from the specified process include handles, the device map, processor affinity, priority, quotas, the
/// process token, and job object. (Note that some attributes such as the debug port will come from the creating process, not the
/// process specified by this handle.)
/// </para>
/// </summary>
[CorrespondingType(typeof(HPROCESS))]
ProcThreadAttributeParentProcess = 0,
/// <summary>
/// The lpValue parameter is a pointer to a list of handles to be inherited by the child process.
/// <para>
/// These handles must be created as inheritable handles and must not include pseudo handles such as those returned by the
/// GetCurrentProcess or GetCurrentThread function.
/// </para>
/// <para>Note if you use this attribute, pass in a value of TRUE for the bInheritHandles parameter of the CreateProcess function.</para>
/// </summary>
[CorrespondingType(typeof(HANDLE[]))]
ProcThreadAttributeHandleList = 2,
/// <summary>
/// The lpValue parameter is a pointer to a GROUP_AFFINITY structure that specifies the processor group affinity for the new thread.
/// <para>Windows Server 2008 and Windows Vista: This value is not supported until Windows 7 and Windows Server 2008 R2.</para>
/// </summary>
[CorrespondingType(typeof(GROUP_AFFINITY))]
ProcThreadAttributeGroupAffinity = 3,
/// <summary>
/// The lpValue parameter is a pointer to the node number of the preferred NUMA node for the new process.
/// <para>Windows Server 2008 and Windows Vista: This value is not supported until Windows 7 and Windows Server 2008 R2.</para>
/// </summary>
[CorrespondingType(typeof(uint))]
ProcThreadAttributePreferredNode = 4,
/// <summary>
/// The lpValue parameter is a pointer to a PROCESSOR_NUMBER structure that specifies the ideal processor for the new thread.
/// <para>Windows Server 2008 and Windows Vista: This value is not supported until Windows 7 and Windows Server 2008 R2.</para>
/// </summary>
[CorrespondingType(typeof(PROCESSOR_NUMBER))]
ProcThreadAttributeIdealProcessor = 5,
/// <summary>
/// The lpValue parameter is a pointer to a UMS_CREATE_THREAD_ATTRIBUTES structure that specifies a user-mode scheduling (UMS)
/// thread context and a UMS completion list to associate with the thread.
/// <para>
/// After the UMS thread is created, the system queues it to the specified completion list. The UMS thread runs only when an
/// application's UMS scheduler retrieves the UMS thread from the completion list and selects it to run. For more information,
/// see User-Mode Scheduling.
/// </para>
/// <para>Windows Server 2008 and Windows Vista: This value is not supported until Windows 7 and Windows Server 2008 R2.</para>
/// </summary>
[CorrespondingType(typeof(UMS_CREATE_THREAD_ATTRIBUTES))]
ProcThreadAttributeUmsThread = 6,
/// <summary>
/// The lpValue parameter is a pointer to a DWORD or DWORD64 that specifies the exploit mitigation policy for the child process.
/// Starting in Windows 10, version 1703, this parameter can also be a pointer to a two-element DWORD64 array.
/// <para>
/// The specified policy overrides the policies set for the application and the system and cannot be changed after the child
/// process starts running.
/// </para>
/// <para>Windows Server 2008 and Windows Vista: This value is not supported until Windows 7 and Windows Server 2008 R2.</para>
/// <para>The DWORD or DWORD64 pointed to by lpValue can be one or more of the values listed in the remarks.</para>
/// </summary>
[CorrespondingType(typeof(uint))]
[CorrespondingType(typeof(uint[]))]
[CorrespondingType(typeof(ulong))]
ProcThreadAttributeMitigationPolicy = 7,
/// <summary>
/// The lpValue parameter is a pointer to a SECURITY_CAPABILITIES structure that defines the security capabilities of an app
/// container. If this attribute is set the new process will be created as an AppContainer process.
/// <para>
/// Windows 7, Windows Server 2008 R2, Windows Server 2008 and Windows Vista: This value is not supported until Windows 8 and
/// Windows Server 2012.
/// </para>
/// </summary>
[CorrespondingType(typeof(SECURITY_CAPABILITIES))]
ProcThreadAttributeSecurityCapabilities = 9,
/// <summary>
/// The lpValue parameter is a pointer to a DWORD value of PROTECTION_LEVEL_SAME. This specifies the protection level of the
/// child process to be the same as the protection level of its parent process.
/// </summary>
[CorrespondingType(typeof(uint))]
ProcThreadAttributeProtectionLevel = 11,
/// <summary/>
ProcThreadAttributeJobList = 13,
/// <summary>
/// The lpValue parameter is a pointer to a DWORD or DWORD64 value that specifies the child process policy. THe policy specifies
/// whether to allow a child process to be created.
/// <para>For information on the possible values for the DWORD or DWORD64 to which lpValue points, see Remarks.</para>
/// </summary>
[CorrespondingType(typeof(uint))]
[CorrespondingType(typeof(ulong))]
ProcThreadAttributeChildProcessPolicy = 14,
/// <summary/>
ProcThreadAttributeAllApplicationPackagesPolicy = 15,
/// <summary/>
ProcThreadAttributeWin32kFilter = 16,
/// <summary/>
ProcThreadAttributeSafeOpenPromptOriginClaim = 17,
/// <summary>
/// This attribute is relevant only to win32 applications that have been converted to UWP packages by using the Desktop Bridge.
/// <para>
/// The lpValue parameter is a pointer to a DWORD value that specifies the desktop app policy. The policy specifies whether
/// descendant processes should continue to run in the desktop environment.
/// </para>
/// <para>For information about the possible values for the DWORD to which lpValue points, see Remarks.</para>
/// </summary>
[CorrespondingType(typeof(uint))]
ProcThreadAttributeDesktopAppPolicy = 18,
}
/// <summary>Initializes a new instance of the <see cref="PROC_THREAD_ATTRIBUTE"/> struct.</summary>
/// <param name="type">The attribute type.</param>
/// <param name="Thread">if set to <c>true</c> this is thread specific.</param>
/// <param name="Input">if set to <c>true</c> this is an input attribute.</param>
/// <param name="Additive">if set to <c>true</c> this is additive.</param>
public PROC_THREAD_ATTRIBUTE(AttrType type, bool Thread, bool Input, bool Additive) =>
value = (UIntPtr)(((uint)type & PROC_THREAD_ATTRIBUTE_NUMBER) | (Thread ? PROC_THREAD_ATTRIBUTE_THREAD : 0) |
(Input ? PROC_THREAD_ATTRIBUTE_INPUT : 0) | (Additive ? PROC_THREAD_ATTRIBUTE_ADDITIVE : 0));
/// <summary>Gets the type associated with this attribute.</summary>
public Type ValidType => LookupType(this);
/// <summary>Performs an implicit conversion from <see cref="PROC_THREAD_ATTRIBUTE"/> to <see cref="UIntPtr"/>.</summary>
/// <param name="attr">The attribute.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator UIntPtr(PROC_THREAD_ATTRIBUTE attr) => attr.value;
/// <summary>Lookups the type associated with an attribute.</summary>
/// <param name="attr">The attribute.</param>
/// <returns>The associated type, or <see langword="null"/> if not found.</returns>
public static Type LookupType(PROC_THREAD_ATTRIBUTE attr) => typeLookup.TryGetValue(attr, out Type type) ? type : null;
/// <summary>Undocumented.</summary>
public static readonly PROC_THREAD_ATTRIBUTE PROC_THREAD_ATTRIBUTE_ALL_APPLICATION_PACKAGES_POLICY = new(AttrType.ProcThreadAttributeAllApplicationPackagesPolicy, false, true, false);
2018-05-13 23:41:49 -04:00
/// <summary>
/// The lpValue parameter is a pointer to a DWORD or DWORD64 value that specifies the child process policy. THe policy specifies
/// whether to allow a child process to be created.For information on the possible values for the DWORD or DWORD64 to which lpValue
/// points, see Remarks.
/// </summary>
public static readonly PROC_THREAD_ATTRIBUTE PROC_THREAD_ATTRIBUTE_CHILD_PROCESS_POLICY = new(AttrType.ProcThreadAttributeChildProcessPolicy, false, true, false);
2018-05-13 23:41:49 -04:00
/// <summary>
/// This attribute is relevant only to win32 applications that have been converted to UWP packages by using the Desktop Bridge. The
/// lpValue parameter is a pointer to a DWORD value that specifies the desktop app policy. The policy specifies whether descendant
/// processes should continue to run in the desktop environment.For information about the possible values for the DWORD to which
/// lpValue points, see Remarks.
2018-05-13 23:41:49 -04:00
/// </summary>
public static readonly PROC_THREAD_ATTRIBUTE PROC_THREAD_ATTRIBUTE_DESKTOP_APP_POLICY = new(AttrType.ProcThreadAttributeDesktopAppPolicy, false, true, false);
/// <summary>
2018-10-26 14:24:07 -04:00
/// The lpValue parameter is a pointer to a GROUP_AFFINITY structure that specifies the processor group affinity for the new
/// thread.Windows Server 2008 and Windows Vista: This value is not supported until Windows 7 and Windows Server 2008 R2.
/// </summary>
public static readonly PROC_THREAD_ATTRIBUTE PROC_THREAD_ATTRIBUTE_GROUP_AFFINITY = new(AttrType.ProcThreadAttributeGroupAffinity, true, true, false);
/// <summary>
2018-10-26 14:24:07 -04:00
/// The lpValue parameter is a pointer to a list of handles to be inherited by the child process.These handles must be created as
/// inheritable handles and must not include pseudo handles such as those returned by the GetCurrentProcess or GetCurrentThread function.
/// </summary>
public static readonly PROC_THREAD_ATTRIBUTE PROC_THREAD_ATTRIBUTE_HANDLE_LIST = new(AttrType.ProcThreadAttributeHandleList, false, true, false);
/// <summary>
2018-10-26 14:24:07 -04:00
/// The lpValue parameter is a pointer to a PROCESSOR_NUMBER structure that specifies the ideal processor for the new thread.Windows
/// Server 2008 and Windows Vista: This value is not supported until Windows 7 and Windows Server 2008 R2.
/// </summary>
public static readonly PROC_THREAD_ATTRIBUTE PROC_THREAD_ATTRIBUTE_IDEAL_PROCESSOR = new(AttrType.ProcThreadAttributeIdealProcessor, true, true, false);
/// <summary>Undocumented.</summary>
public static readonly PROC_THREAD_ATTRIBUTE PROC_THREAD_ATTRIBUTE_JOB_LIST = new(AttrType.ProcThreadAttributeJobList, false, true, false);
/// <summary>
2018-10-26 14:24:07 -04:00
/// The lpValue parameter is a pointer to a DWORD or DWORD64 that specifies the exploit mitigation policy for the child process.
/// Starting in Windows 10, version 1703, this parameter can also be a pointer to a two-element DWORD64 array.The specified policy
/// overrides the policies set for the application and the system and cannot be changed after the child process starts running.
/// Windows Server 2008 and Windows Vista: This value is not supported until Windows 7 and Windows Server 2008 R2.The DWORD or
/// DWORD64 pointed to by lpValue can be one or more of the values listed in the remarks.
/// </summary>
public static readonly PROC_THREAD_ATTRIBUTE PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY = new(AttrType.ProcThreadAttributeMitigationPolicy, false, true, false);
/// <summary>
2018-10-26 14:24:07 -04:00
/// The lpValue parameter is a pointer to a handle to a process to use instead of the calling process as the parent for the process
/// being created. The process to use must have the PROCESS_CREATE_PROCESS access right.Attributes inherited from the specified
/// process include handles, the device map, processor affinity, priority, quotas, the process token, and job object. (Note that some
/// attributes such as the debug port will come from the creating process, not the process specified by this handle.)
/// </summary>
public static readonly PROC_THREAD_ATTRIBUTE PROC_THREAD_ATTRIBUTE_PARENT_PROCESS = new(AttrType.ProcThreadAttributeParentProcess, false, true, false);
/// <summary>
2018-10-26 14:24:07 -04:00
/// The lpValue parameter is a pointer to the node number of the preferred NUMA node for the new process.Windows Server 2008 and
/// Windows Vista: This value is not supported until Windows 7 and Windows Server 2008 R2.
/// </summary>
public static readonly PROC_THREAD_ATTRIBUTE PROC_THREAD_ATTRIBUTE_PREFERRED_NODE = new(AttrType.ProcThreadAttributePreferredNode, false, true, false);
/// <summary>
/// The lpValue parameter is a pointer to a DWORD value of PROTECTION_LEVEL_SAME. This specifies the protection level of the child
/// process to be the same as the protection level of its parent process.
/// </summary>
public static readonly PROC_THREAD_ATTRIBUTE PROC_THREAD_ATTRIBUTE_PROTECTION_LEVEL = new(AttrType.ProcThreadAttributeProtectionLevel, false, true, false);
/// <summary>
2018-10-26 14:24:07 -04:00
/// The lpValue parameter is a pointer to a SECURITY_CAPABILITIES structure that defines the security capabilities of an app
/// container. If this attribute is set the new process will be created as an AppContainer process.Windows 7, Windows Server 2008 R2,
/// Windows Server 2008 and Windows Vista: This value is not supported until Windows 8 and Windows Server 2012.
/// </summary>
public static readonly PROC_THREAD_ATTRIBUTE PROC_THREAD_ATTRIBUTE_SECURITY_CAPABILITIES = new(AttrType.ProcThreadAttributeSecurityCapabilities, false, true, false);
/// <summary>
/// The lpValue parameter is a pointer to a UMS_CREATE_THREAD_ATTRIBUTES structure that specifies a user-mode scheduling (UMS) thread
/// context and a UMS completion list to associate with the thread. After the UMS thread is created, the system queues it to the
/// specified completion list. The UMS thread runs only when an application's UMS scheduler retrieves the UMS thread from the
/// completion list and selects it to run. For more information, see User-Mode Scheduling.Windows Server 2008 and Windows
/// Vista: This value is not supported until Windows 7 and Windows Server 2008 R2.
/// </summary>
public static readonly PROC_THREAD_ATTRIBUTE PROC_THREAD_ATTRIBUTE_UMS_THREAD = new(AttrType.ProcThreadAttributeUmsThread, true, true, false);
/// <summary>Undocumented.</summary>
public static readonly PROC_THREAD_ATTRIBUTE PROC_THREAD_ATTRIBUTE_WIN32K_FILTER = new(AttrType.ProcThreadAttributeWin32kFilter, false, true, false);
/// <summary>Implements the operator ==.</summary>
/// <param name="left">The left.</param>
/// <param name="right">The right.</param>
/// <returns>The result of the operator.</returns>
public static bool operator ==(PROC_THREAD_ATTRIBUTE left, PROC_THREAD_ATTRIBUTE right) => left.Equals(right);
/// <summary>Implements the operator !=.</summary>
/// <param name="left">The left.</param>
/// <param name="right">The right.</param>
/// <returns>The result of the operator.</returns>
public static bool operator !=(PROC_THREAD_ATTRIBUTE left, PROC_THREAD_ATTRIBUTE right) => !left.Equals(right);
}
/// <summary>
/// Contains dynamic exception handling continuation targets. The SetProcessDynamicEHContinuationTargets function uses this structure.
/// </summary>
// https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-process_dynamic_eh_continuation_target typedef struct
// _PROCESS_DYNAMIC_EH_CONTINUATION_TARGET { ULONG_PTR TargetAddress; ULONG_PTR Flags; } PROCESS_DYNAMIC_EH_CONTINUATION_TARGET, *PPROCESS_DYNAMIC_EH_CONTINUATION_TARGET;
[PInvokeData("winnt.h", MSDNShortId = "NS:winnt._PROCESS_DYNAMIC_EH_CONTINUATION_TARGET")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct PROCESS_DYNAMIC_EH_CONTINUATION_TARGET
{
/// <summary>The address of a dynamic exception handling continuation target.</summary>
public IntPtr TargetAddress;
private IntPtr _Flags;
/// <summary>
/// <para>Flags that apply to the dynamic exception handling continuation target in TargetAddress.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
2018-05-13 23:41:49 -04:00
/// <item>
/// <term>DYNAMIC_EH_CONTINUATION_TARGET_ADD 0x00000001UL</term>
2018-05-13 23:41:49 -04:00
/// <term>
/// Dynamic exception handling continuation target should be added. If this flag is not set, the target is removed. This is an input flag.
2018-05-13 23:41:49 -04:00
/// </term>
/// </item>
/// <item>
/// <term>DYNAMIC_EH_CONTINUATION_TARGET_PROCESSED 0x00000002UL</term>
2018-05-13 23:41:49 -04:00
/// <term>
/// Dynamic exception handling continuation target has been successfully processed (either added or removed). This is an output flag
/// used to report which targets were successfully processed when processing an array of multiple targets.
2018-05-13 23:41:49 -04:00
/// </term>
/// </item>
/// </list>
/// </summary>
public DYNAMIC_EH_CONTINUATION_TARGET Flags { get => (DYNAMIC_EH_CONTINUATION_TARGET)_Flags.ToInt32(); set => _Flags = new IntPtr((int)value); }
}
/// <summary>
/// Contains information about a newly created process and its primary thread. It is used with the <c>CreateProcess</c>,
/// <c>CreateProcessAsUser</c>, <c>CreateProcessWithLogonW</c>, or <c>CreateProcessWithTokenW</c> function.
/// </summary>
// typedef struct _PROCESS_INFORMATION { HANDLE hProcess; HANDLE hThread; DWORD dwProcessId; DWORD dwThreadId;} PROCESS_INFORMATION,
// *LPPROCESS_INFORMATION; https://msdn.microsoft.com/en-us/library/windows/desktop/ms684873(v=vs.85).aspx
[PInvokeData("WinBase.h", MSDNShortId = "ms684873")]
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_INFORMATION
{
/// <summary>
/// A handle to the newly created process. The handle is used to specify the process in all functions that perform operations on the
/// process object.
2018-10-26 14:24:07 -04:00
/// </summary>
public HPROCESS hProcess;
/// <summary>
/// A handle to the primary thread of the newly created process. The handle is used to specify the thread in all functions that
/// perform operations on the thread object.
/// </summary>
public HTHREAD hThread;
/// <summary>
/// A value that can be used to identify a process. The value is valid from the time the process is created until all handles to the
/// process are closed and the process object is freed; at this point, the identifier may be reused.
/// </summary>
public uint dwProcessId;
/// <summary>
/// A value that can be used to identify a thread. The value is valid from the time the thread is created until all handles to the
/// thread are closed and the thread object is freed; at this point, the identifier may be reused.
/// </summary>
public uint dwThreadId;
}
/// <summary>Specifies how the system handles positive leap seconds.</summary>
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/ns-processthreadsapi-process_leap_second_info typedef struct
// _PROCESS_LEAP_SECOND_INFO { ULONG Flags; ULONG Reserved; } PROCESS_LEAP_SECOND_INFO, *PPROCESS_LEAP_SECOND_INFO;
[PInvokeData("processthreadsapi.h", MSDNShortId = "NS:processthreadsapi._PROCESS_LEAP_SECOND_INFO")]
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_LEAP_SECOND_INFO
{
/// <summary>
/// <para>Currently, the only valid flag is <c>PROCESS_LEAP_SECOND_INFO_FLAG_ENABLE_SIXTY_SECOND</c>. That flag is described below.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <description>PROCESS_LEAP_SECOND_INFO_FLAG_ENABLE_SIXTY_SECOND</description>
/// <description>
/// This value changes the way positive leap seconds are handled by system. Specifically, it changes how the seconds field during a
/// positive leap second is handled by the system. If this value is used, then the positive leap second will be shown (For example:
/// 23:59:59 -&gt; 23:59:60 -&gt; 00:00:00. If this value is not used, then "sixty seconds" is disabled, and the 59th second
/// preceding a positive leap second will be shown for 2 seconds with the milliseconds value ticking twice as slow. So 23:59:59 -&gt;
/// 23:59:59.500 -&gt; 00:00:00, which takes 2 seconds in wall clock time. Disabling "sixty second" can help with legacy apps that do
/// not support seeing the seconds value as 60 during the positive leap second. Such apps may crash or misbehave. Therefore, in these
/// cases, we display the 59th second for twice as long during the positive leap second. Note that this setting is per-process, and
/// does not persist if the process is restarted. Developers should test their app for compatibility with seeing the system return
/// "60", and add a call to their app startup routines to either enable or disable "sixty seconds". "Sixty seconds" is disabled by
/// default for each process. Obviously, this setting has no effect if leap seconds are disabled system-wide, because then the system
/// will never even encounter a leap second.
/// </description>
/// </item>
/// </list>
/// </summary>
public PROCESS_LEAP_SECOND_INFO_FLAGS Flags;
/// <summary>Reserved for future use</summary>
public uint Reserved;
}
/// <summary>
/// Specifies the architecture of a process and if that architecture of code can run in user mode, kernel mode, and/or under WoW64 on the
/// host operating system.
/// </summary>
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/ns-processthreadsapi-process_machine_information typedef struct
// _PROCESS_MACHINE_INFORMATION { USHORT ProcessMachine; USHORT Res0; MACHINE_ATTRIBUTES MachineAttributes; } PROCESS_MACHINE_INFORMATION;
[PInvokeData("processthreadsapi.h", MSDNShortId = "NS:processthreadsapi._PROCESS_MACHINE_INFORMATION")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct PROCESS_MACHINE_INFORMATION
{
/// <summary>
/// An IMAGE_FILE_MACHINE_* value indicating the architecture of the associated process. See the list of architecture values in Image
/// File Machine Constants.
/// </summary>
public IMAGE_FILE_MACHINE ProcessMachine;
/// <summary>Reserved.</summary>
public ushort Res0;
/// <summary>
/// A value from the MACHINE_ATTRIBUTES enumeration indicating if the processs architecture can run in user mode, kernel mode,
/// and/or under WOW64 on the host operating system.
/// </summary>
public MACHINE_ATTRIBUTES MachineAttributes;
}
/// <summary>
/// Allows applications to configure a process to terminate if an allocation fails to commit memory. This structure is used by the
/// <c>PROCESS_INFORMATION_CLASS</c> class.
/// </summary>
// typedef struct _PROCESS_MEMORY_EXHAUSTION_INFO { USHORT Version; USHORT Reserved; PROCESS_MEMORY_EXHAUSTION_TYPE Type; ULONG_PTR
// Value;} PROCESS_MEMORY_EXHAUSTION_INFO, *PPROCESS_MEMORY_EXHAUSTION_INFO;// https://msdn.microsoft.com/en-us/library/windows/desktop/mt767997(v=vs.85).aspx
[PInvokeData("WinBase.h", MSDNShortId = "mt767997")]
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_MEMORY_EXHAUSTION_INFO
{
/// <summary>Version should be set to <c>PME_CURRENT_VERSION</c>.</summary>
public ushort Version;
/// <summary>Reserved.</summary>
public ushort Reserved;
/// <summary>
/// <para>Type of failure.</para>
/// <para>Type should be set to <c>PMETypeFailFastOnCommitFailure</c> (this is the only type available).</para>
/// </summary>
public PROCESS_MEMORY_EXHAUSTION_TYPE Type;
/// <summary>
/// <para>Used to turn the feature on or off.</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Function</term>
/// <term>Setting</term>
/// </listheader>
/// <item>
/// <term>Enable</term>
/// <term>PME_FAILFAST_ON_COMMIT_FAIL_ENABLE</term>
/// </item>
/// <item>
/// <term>Disable</term>
/// <term>PME_FAILFAST_ON_COMMIT_FAIL_DISABLE</term>
/// </item>
/// </list>
/// </para>
/// </summary>
public UIntPtr Value;
}
/// <summary>
/// Contains process mitigation policy settings for Address Space Randomization Layout (ASLR). The <c>GetProcessMitigationPolicy</c> and
/// <c>SetProcessMitigationPolicy</c> functions use this structure.
/// </summary>
// typedef struct _PROCESS_MITIGATION_ASLR_POLICY { union { DWORD Flags; struct { DWORD EnableBottomUpRandomization : 1; DWORD
// EnableForceRelocateImages : 1; DWORD EnableHighEntropy : 1; DWORD DisallowStrippedImages : 1; DWORD ReservedFlags : 28; }; };} PROCESS_MITIGATION_ASLR_POLICY,
// *PPROCESS_MITIGATION_ASLR_POLICY; https://msdn.microsoft.com/en-us/library/windows/desktop/hh769086(v=vs.85).aspx
[PInvokeData("WinNT.h", MSDNShortId = "hh769086")]
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_MITIGATION_ASLR_POLICY
{
/// <summary>The flags</summary>
public PROCESS_MITIGATION_ASLR_POLICY_FLAGS Flags;
}
/// <summary>Contains process mitigation policy settings for the loading of images depending on the signatures for the image.</summary>
// typedef struct _PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY { union { DWORD Flags; struct { DWORD MicrosoftSignedOnly :1; DWORD
// StoreSignedOnly :1; DWORD MitigationOptIn :1; DWORD ReservedFlags :29; }; };} PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY,
// *PPROCESS_MITIGATION_BINARY_SIGNATURE_POLICY; https://msdn.microsoft.com/en-us/library/windows/desktop/mt706242(v=vs.85).aspx
[PInvokeData("WinNT.h", MSDNShortId = "mt706242")]
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY
{
/// <summary>The flags</summary>
public PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY_FLAGS Flags;
}
/// <summary>Stores policy information about creating child processes.</summary>
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/ntddk/ns-ntddk-_process_mitigation_child_process_policy
[PInvokeData("WinNT.h", MSDNShortId = "")]
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_MITIGATION_CHILD_PROCESS_POLICY
{
/// <summary>The flags</summary>
public PROCESS_MITIGATION_CHILD_PROCESS_POLICY_FLAGS Flags;
}
/// <summary>
/// Contains process mitigation policy settings for Control Flow Guard (CFG). The <c>GetProcessMitigationPolicy</c> and
/// <c>SetProcessMitigationPolicy</c> functions use this structure.
/// </summary>
// typedef struct _PROCESS_MITIGATION_CONTROL_FLOW_GUARD_POLICY { union { DWORD Flags; struct { DWORD EnableControlFlowGuard :1; DWORD
// EnableExportSuppression :1; DWORD StrictMode :1; DWORD ReservedFlags :29; }; };} PROCESS_MITIGATION_CONTROL_FLOW_GUARD_POLICY,
// *PPROCESS_MITIGATION_CONTROL_FLOW_GUARD_POLICY; https://msdn.microsoft.com/en-us/library/windows/desktop/mt654121(v=vs.85).aspx
[PInvokeData("WinNT.h", MSDNShortId = "mt654121")]
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_MITIGATION_CONTROL_FLOW_GUARD_POLICY
{
/// <summary>The flags</summary>
public PROCESS_MITIGATION_CONTROL_FLOW_GUARD_POLICY_FLAGS Flags;
}
/// <summary>
/// Contains process mitigation policy settings for data execution prevention (DEP). The <c>GetProcessMitigationPolicy</c> and
/// <c>SetProcessMitigationPolicy</c> functions use this structure.
/// </summary>
// typedef struct _PROCESS_MITIGATION_DEP_POLICY { union { DWORD Flags; struct { DWORD Enable : 1; DWORD DisableAtlThunkEmulation : 1;
// DWORD ReservedFlags : 30; }; }; BOOLEAN Permanent;} PROCESS_MITIGATION_DEP_POLICY, *PPROCESS_MITIGATION_DEP_POLICY; https://msdn.microsoft.com/en-us/library/windows/desktop/hh769087(v=vs.85).aspx
[PInvokeData("WinNT.h", MSDNShortId = "hh769087")]
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct PROCESS_MITIGATION_DEP_POLICY
{
/// <summary>The flags</summary>
public PROCESS_MITIGATION_DEP_POLICY_FLAGS Flags;
/// <summary>DEP is permanently enabled and cannot be disabled if this field is set to TRUE.</summary>
[MarshalAs(UnmanagedType.U1)]
public bool Permanent;
}
/// <summary>Contains process mitigation policy settings for restricting dynamic code generation and modification.</summary>
// typedef struct _PROCESS_MITIGATION_DYNAMIC_CODE_POLICY { union { DWORD Flags; struct { DWORD ProhibitDynamicCode :1; DWORD
// AllowThreadOptOut :1; DWORD AllowRemoteDowngrade :1; DWORD ReservedFlags :30; }; };} PROCESS_MITIGATION_DYNAMIC_CODE_POLICY,
// *PPROCESS_MITIGATION_DYNAMIC_CODE_POLICY; https://msdn.microsoft.com/en-us/library/windows/desktop/mt706243(v=vs.85).aspx
[PInvokeData("WinNT.h", MSDNShortId = "mt706243")]
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_MITIGATION_DYNAMIC_CODE_POLICY
{
/// <summary>The flags</summary>
public PROCESS_MITIGATION_DYNAMIC_CODE_POLICY_FLAGS Flags;
}
/// <summary>
/// Contains process mitigation policy settings for legacy extension point DLLs. The <c>GetProcessMitigationPolicy</c> and
/// <c>SetProcessMitigationPolicy</c> functions use this structure.
/// </summary>
// typedef struct _PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY { union { DWORD Flags; struct { DWORD DisableExtensionPoints : 1;
// DWORD ReservedFlags : 31; }; };} PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY,
// *PPROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY; https://msdn.microsoft.com/en-us/library/windows/desktop/jj200586(v=vs.85).aspx
[PInvokeData("Winnt.h", MSDNShortId = "jj200586")]
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY
{
/// <summary>The flags</summary>
public PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY_FLAGS Flags;
}
/// <summary>Contains process mitigation policy settings for the loading of non-system fonts.</summary>
// typedef struct _PROCESS_MITIGATION_FONT_DISABLE_POLICY { union { DWORD Flags; struct { DWORD DisableNonSystemFonts :1; DWORD
// AuditNonSystemFontLoading :1; DWORD ReservedFlags :30; }; };} PROCESS_MITIGATION_FONT_DISABLE_POLICY,
// *PPROCESS_MITIGATION_FONT_DISABLE_POLICY; https://msdn.microsoft.com/en-us/library/windows/desktop/mt706244(v=vs.85).aspx
[PInvokeData("WinNT.h", MSDNShortId = "mt706244")]
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_MITIGATION_FONT_DISABLE_POLICY
{
/// <summary>The flags</summary>
public PROCESS_MITIGATION_FONT_DISABLE_POLICY_FLAGS Flags;
}
/// <summary>Contains process mitigation policy settings for the loading of images from a remote device.</summary>
// typedef struct _PROCESS_MITIGATION_IMAGE_LOAD_POLICY { union { DWORD Flags; struct { DWORD NoRemoteImages :1; DWORD
// NoLowMandatoryLabelImages :1; DWORD PreferSystem32Images :1; DWORD ReservedFlags :29; }; };} PROCESS_MITIGATION_IMAGE_LOAD_POLICY,
// *PPROCESS_MITIGATION_IMAGE_LOAD_POLICY; https://msdn.microsoft.com/en-us/library/windows/desktop/mt706245(v=vs.85).aspx
[PInvokeData("WinNT.h", MSDNShortId = "mt706245")]
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_MITIGATION_IMAGE_LOAD_POLICY
{
/// <summary>The flags</summary>
public PROCESS_MITIGATION_IMAGE_LOAD_POLICY_FLAGS Flags;
}
/// <summary>Stores information about process mitigation policy.</summary>
// https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/ntddk/ns-ntddk-_process_mitigation_payload_restriction_policy
[PInvokeData("WinNT.h", MSDNShortId = "")]
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_MITIGATION_PAYLOAD_RESTRICTION_POLICY
{
/// <summary>The flags</summary>
public PROCESS_MITIGATION_PAYLOAD_RESTRICTION_POLICY_FLAGS Flags;
}
/// <summary>Used to impose new behavior on handle references that are not valid.</summary>
// typedef struct _PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY { union { DWORD Flags; struct { DWORD
// RaiseExceptionOnInvalidHandleReference : 1; DWORD HandleExceptionsPermanentlyEnabled : 1; DWORD ReservedFlags : 30; }; };} PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY,
// *PPROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY; https://msdn.microsoft.com/en-us/library/windows/desktop/hh871471(v=vs.85).aspx
[PInvokeData("WinNT.h", MSDNShortId = "hh871471")]
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY
{
/// <summary>The flags</summary>
public PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY_FLAGS Flags;
}
/// <summary>Used to impose restrictions on what system calls can be invoked by a process.</summary>
// typedef struct _PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY { union { DWORD Flags; struct { DWORD DisallowWin32kSystemCalls : 1;
// DWORD ReservedFlags : 31; }; };} PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY, *PPROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY; https://msdn.microsoft.com/en-us/library/windows/desktop/hh871472(v=vs.85).aspx
[PInvokeData("WinNT.h", MSDNShortId = "hh871472")]
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY
{
/// <summary>The flags</summary>
public PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY_FLAGS Flags;
}
/// <summary>This structure is not supported.</summary>
// https://msdn.microsoft.com/en-us/library/windows/hardware/mt843942(v=vs.85).aspx
[PInvokeData("WinNT.h", MSDNShortId = "mt843942")]
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_MITIGATION_SYSTEM_CALL_FILTER_POLICY
{
/// <summary>Undocumented.</summary>
public uint FilterId; // Only lowest 4 bits
}
/// <summary>Specifies the throttling policies and how to apply them to a target process when that process is subject to power management.</summary>
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/ns-processthreadsapi-process_power_throttling_state typedef
// struct _PROCESS_POWER_THROTTLING_STATE { ULONG Version; ULONG ControlMask; ULONG StateMask; } PROCESS_POWER_THROTTLING_STATE, *PPROCESS_POWER_THROTTLING_STATE;
[PInvokeData("processthreadsapi.h", MSDNShortId = "394B6509-849C-4B4C-9A46-AF5011A03585")]
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_POWER_THROTTLING_STATE
{
/// <summary/>
public const uint PROCESS_POWER_THROTTLING_CURRENT_VERSION = 1;
/// <summary>
/// <para>The version of the <c>PROCESS_POWER_THROTTLING_STATE</c> structure.</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PROCESS_POWER_THROTTLING_CURRENT_VERSION</term>
/// <term>The current version.</term>
/// </item>
/// </list>
/// </para>
/// </summary>
public uint Version;
/// <summary>
/// <para>This field enables the caller to take control of the power throttling mechanism.</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PROCESS_POWER_THROTTLING_EXECUTION_SPEED</term>
/// <term>Manages the execution speed of the process.</term>
/// </item>
/// </list>
/// </para>
/// </summary>
public PROCESS_POWER_THROTTLING_MASK ControlMask;
/// <summary>
/// <para>Manages the power throttling mechanism on/off state.</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PROCESS_POWER_THROTTLING_EXECUTION_SPEED</term>
/// <term>Manages the execution speed of the process.</term>
/// </item>
/// </list>
/// </para>
/// </summary>
public PROCESS_POWER_THROTTLING_MASK StateMask;
/// <summary>Initializes a new instance of the <see cref="PROCESS_POWER_THROTTLING_STATE"/> struct.</summary>
/// <param name="controlMask">The control mask.</param>
/// <param name="stateMask">The state mask.</param>
public PROCESS_POWER_THROTTLING_STATE(PROCESS_POWER_THROTTLING_MASK controlMask, PROCESS_POWER_THROTTLING_MASK stateMask)
{
Version = PROCESS_POWER_THROTTLING_CURRENT_VERSION;
ControlMask = controlMask;
StateMask = stateMask;
}
}
/// <summary>Specifies whether Protected Process Light (PPL) is enabled.</summary>
// typedef struct _PROCESS_PROTECTION_LEVEL_INFORMATION { DWORD ProtectionLevel;} PROCESS_PROTECTION_LEVEL_INFORMATION,
// *PPROCESS_PROTECTION_LEVEL_INFORMATION;// https://msdn.microsoft.com/en-us/library/windows/desktop/mt823702(v=vs.85).aspx
[PInvokeData("Processthreadsapi.h", MSDNShortId = "mt823702")]
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_PROTECTION_LEVEL_INFORMATION
{
/// <summary>
/// <para>The one of the following values.</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>PROTECTION_LEVEL_WINTCB_LIGHT</term>
/// <term>For internal use only.</term>
/// </item>
/// <item>
/// <term>PROTECTION_LEVEL_WINDOWS</term>
/// <term>For internal use only.</term>
/// </item>
/// <item>
/// <term>PROTECTION_LEVEL_WINDOWS_LIGHT</term>
/// <term>For internal use only.</term>
/// </item>
/// <item>
/// <term>PROTECTION_LEVEL_ANTIMALWARE_LIGHT</term>
/// <term>For internal use only.</term>
/// </item>
/// <item>
/// <term>PROTECTION_LEVEL_LSA_LIGHT</term>
/// <term>For internal use only.</term>
/// </item>
/// <item>
/// <term>PROTECTION_LEVEL_WINTCB</term>
/// <term>Not implemented.</term>
/// </item>
/// <item>
/// <term>PROTECTION_LEVEL_CODEGEN_LIGHT</term>
/// <term>Not implemented.</term>
/// </item>
/// <item>
/// <term>PROTECTION_LEVEL_AUTHENTICODE</term>
/// <term>Not implemented.</term>
/// </item>
/// <item>
/// <term>PROTECTION_LEVEL_PPL_APP</term>
/// <term>The process is a third party app that is using process protection.</term>
/// </item>
/// <item>
/// <term>PROTECTION_LEVEL_NONE</term>
/// <term>The process is not protected.</term>
/// </item>
/// </list>
/// </para>
/// </summary>
public PROTECTION_LEVEL ProtectionLevel;
}
/// <summary>Represents a logical processor in a processor group.</summary>
[PInvokeData("WinNT.h", MSDNShortId = "dd405505")]
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct PROCESSOR_NUMBER
{
/// <summary>The processor group to which the logical processor is assigned.</summary>
public ushort Group;
/// <summary>The number of the logical processor relative to the group.</summary>
public byte Number;
/// <summary>This parameter is reserved.</summary>
public byte Reserved;
/// <summary>Initializes a new instance of the <see cref="PROCESSOR_NUMBER"/> struct.</summary>
/// <param name="processorGroup">The processor group to which the logical processor is assigned.</param>
/// <param name="logicalProcessor">The number of the logical processor relative to the group.</param>
public PROCESSOR_NUMBER(ushort processorGroup, byte logicalProcessor)
{
Group = processorGroup;
Number = logicalProcessor;
Reserved = 0;
}
}
/// <summary>
/// Specifies the window station, desktop, standard handles, and appearance of the main window for a process at creation time.
/// </summary>
/// <remarks>
/// <para>
/// For graphical user interface (GUI) processes, this information affects the first window created by the CreateWindow function and
/// shown by the ShowWindow function. For console processes, this information affects the console window if a new console is created for
/// the process. A process can use the GetStartupInfo function to retrieve the <c>STARTUPINFO</c> structure specified when the process
/// was created.
/// </para>
/// <para>
/// If a GUI process is being started and neither STARTF_FORCEONFEEDBACK or STARTF_FORCEOFFFEEDBACK is specified, the process feedback
/// cursor is used. A GUI process is one whose subsystem is specified as "windows."
/// </para>
/// <para>
/// If a process is launched from the taskbar or jump list, the system sets <c>hStdOutput</c> to a handle to the monitor that contains
/// the taskbar or jump list used to launch the process. To retrieve this handle, use GetStartupInfo to retrieve the <c>STARTUPINFO</c>
/// structure and check that <c>hStdOutput</c> is set. If so, use GetMonitorInfo to check whether <c>hStdOutput</c> is a valid monitor
/// handle (HMONITOR). The process can then use the handle to position its windows.
/// </para>
/// <para>
/// If the <c>STARTF_UNTRUSTEDSOURCE</c> flag is set in the in the <c>STARTUPINFO</c> structure returned by the GetStartupInfo function,
/// then applications should be aware that the command line is untrusted. If this flag is set, applications should disable potentially
/// dangerous features such as macros, downloaded content, and automatic printing. This flag is optional. Applications that call
/// CreateProcess are encouraged to set this flag when launching a program with a untrusted command line so that the created process can
/// apply appropriate policy.
/// </para>
/// <para>
/// The <c>STARTF_UNTRUSTEDSOURCE</c> flag is supported starting in Windows Vista, but it is not defined in the SDK header files prior to
/// the Windows 10 SDK. To use the flag in versions prior to Windows 10, you can define it manually in your program.
/// </para>
/// <para>Examples</para>
/// <para>For an example, see Creating Processes.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/ns-processthreadsapi-_startupinfoa typedef struct _STARTUPINFOA {
// DWORD cb; LPSTR lpReserved; LPSTR lpDesktop; LPSTR lpTitle; DWORD dwX; DWORD dwY; DWORD dwXSize; DWORD dwYSize; DWORD dwXCountChars;
// DWORD dwYCountChars; DWORD dwFillAttribute; DWORD dwFlags; WORD wShowWindow; WORD cbReserved2; LPBYTE lpReserved2; HANDLE hStdInput;
// HANDLE hStdOutput; HANDLE hStdError; } STARTUPINFOA, *LPSTARTUPINFOA;
[PInvokeData("processthreadsapi.h", MSDNShortId = "cf4b795c-52c1-4573-8328-99ee13f68bb3")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct STARTUPINFO
{
/// <summary>The size of the structure, in bytes.</summary>
public uint cb;
/// <summary>Reserved; must be NULL.</summary>
public IntPtr lpReserved;
/// <summary>
/// The name of the desktop, or the name of both the desktop and window station for this process. A backslash in the string indicates
/// that the string includes both the desktop and window station names.
/// <para>
/// For more information, see <a href="https://msdn.microsoft.com/45016619-ed11-4b0c-84e3-f8662553c64d">Thread Connection to a Desktop</a>.
/// </para>
/// </summary>
[MarshalAs(UnmanagedType.LPTStr)]
public string lpDesktop;
/// <summary>
/// For console processes, this is the title displayed in the title bar if a new console window is created. If NULL, the name of the
/// executable file is used as the window title instead. This parameter must be NULL for GUI or console processes that do not create
/// a new console window.
/// </summary>
[MarshalAs(UnmanagedType.LPTStr)]
public string lpTitle;
/// <summary>
/// <para>
/// If <c>dwFlags</c> specifies STARTF_USEPOSITION, this member is the x offset of the upper left corner of a window if a new window
/// is created, in pixels. Otherwise, this member is ignored.
/// </para>
/// <para>
/// The offset is from the upper left corner of the screen. For GUI processes, the specified position is used the first time the new
/// process calls CreateWindow to create an overlapped window if the x parameter of <c>CreateWindow</c> is CW_USEDEFAULT.
/// </para>
/// </summary>
public uint dwX;
/// <summary>
/// <para>
/// If <c>dwFlags</c> specifies STARTF_USEPOSITION, this member is the y offset of the upper left corner of a window if a new window
/// is created, in pixels. Otherwise, this member is ignored.
/// </para>
/// <para>
/// The offset is from the upper left corner of the screen. For GUI processes, the specified position is used the first time the new
/// process calls CreateWindow to create an overlapped window if the y parameter of <c>CreateWindow</c> is CW_USEDEFAULT.
/// </para>
/// </summary>
public uint dwY;
/// <summary>
/// <para>
/// If <c>dwFlags</c> specifies STARTF_USESIZE, this member is the width of the window if a new window is created, in pixels.
/// Otherwise, this member is ignored.
/// </para>
/// <para>
/// For GUI processes, this is used only the first time the new process calls CreateWindow to create an overlapped window if the
/// nWidth parameter of <c>CreateWindow</c> is CW_USEDEFAULT.
/// </para>
/// </summary>
public uint dwXSize;
/// <summary>
/// <para>
/// If <c>dwFlags</c> specifies STARTF_USESIZE, this member is the height of the window if a new window is created, in pixels.
/// Otherwise, this member is ignored.
/// </para>
/// <para>
/// For GUI processes, this is used only the first time the new process calls CreateWindow to create an overlapped window if the
/// nHeight parameter of <c>CreateWindow</c> is CW_USEDEFAULT.
/// </para>
/// </summary>
public uint dwYSize;
/// <summary>
/// If <c>dwFlags</c> specifies STARTF_USECOUNTCHARS, if a new console window is created in a console process, this member specifies
/// the screen buffer width, in character columns. Otherwise, this member is ignored.
/// </summary>
public uint dwXCountChars;
/// <summary>
/// If <c>dwFlags</c> specifies STARTF_USECOUNTCHARS, if a new console window is created in a console process, this member specifies
/// the screen buffer height, in character rows. Otherwise, this member is ignored.
/// </summary>
public uint dwYCountChars;
/// <summary>
/// <para>
/// If <c>dwFlags</c> specifies STARTF_USEFILLATTRIBUTE, this member is the initial text and background colors if a new console
/// window is created in a console application. Otherwise, this member is ignored.
/// </para>
/// <para>
/// This value can be any combination of the following values: FOREGROUND_BLUE, FOREGROUND_GREEN, FOREGROUND_RED,
/// FOREGROUND_INTENSITY, BACKGROUND_BLUE, BACKGROUND_GREEN, BACKGROUND_RED, and BACKGROUND_INTENSITY. For example, the following
/// combination of values produces red text on a white background:
/// </para>
/// <para><c>FOREGROUND_RED | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE</c></para>
/// </summary>
public uint dwFillAttribute; // CHARACTER_ATTRIBUTE
/// <summary>
/// <para>
/// A bitfield that determines whether certain <c>STARTUPINFO</c> members are used when the process creates a window. This member can
/// be one or more of the following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>STARTF_FORCEONFEEDBACK 0x00000040</term>
/// <term>
/// Indicates that the cursor is in feedback mode for two seconds after CreateProcess is called. The Working in Background cursor is
/// displayed (see the Pointers tab in the Mouse control panel utility). If during those two seconds the process makes the first GUI
/// call, the system gives five more seconds to the process. If during those five seconds the process shows a window, the system
/// gives five more seconds to the process to finish drawing the window. The system turns the feedback cursor off after the first
/// call to GetMessage, regardless of whether the process is drawing.
/// </term>
/// </item>
/// <item>
/// <term>STARTF_FORCEOFFFEEDBACK 0x00000080</term>
/// <term>Indicates that the feedback cursor is forced off while the process is starting. The Normal Select cursor is displayed.</term>
/// </item>
/// <item>
/// <term>STARTF_PREVENTPINNING 0x00002000</term>
/// <term>Indicates that any windows created by the process cannot be pinned on the taskbar. This flag must be combined with STARTF_TITLEISAPPID.</term>
/// </item>
/// <item>
/// <term>STARTF_RUNFULLSCREEN 0x00000020</term>
/// <term>
/// Indicates that the process should be run in full-screen mode, rather than in windowed mode. This flag is only valid for console
/// applications running on an x86 computer.
/// </term>
/// </item>
/// <item>
/// <term>STARTF_TITLEISAPPID 0x00001000</term>
/// <term>
/// The lpTitle member contains an AppUserModelID. This identifier controls how the taskbar and Start menu present the application,
/// and enables it to be associated with the correct shortcuts and Jump Lists. Generally, applications will use the
/// SetCurrentProcessExplicitAppUserModelID and GetCurrentProcessExplicitAppUserModelID functions instead of setting this flag. For
/// more information, see Application User Model IDs. If STARTF_PREVENTPINNING is used, application windows cannot be pinned on the
/// taskbar. The use of any AppUserModelID-related window properties by the application overrides this setting for that window only.
/// This flag cannot be used with STARTF_TITLEISLINKNAME.
/// </term>
/// </item>
/// <item>
/// <term>STARTF_TITLEISLINKNAME 0x00000800</term>
/// <term>
/// The lpTitle member contains the path of the shortcut file (.lnk) that the user invoked to start this process. This is typically
/// set by the shell when a .lnk file pointing to the launched application is invoked. Most applications will not need to set this
/// value. This flag cannot be used with STARTF_TITLEISAPPID.
/// </term>
/// </item>
/// <item>
/// <term>STARTF_UNTRUSTEDSOURCE 0x00008000</term>
/// <term>The command line came from an untrusted source. For more information, see Remarks.</term>
/// </item>
/// <item>
/// <term/>
/// <term/>
/// </item>
/// <item>
/// <term>STARTF_USECOUNTCHARS 0x00000008</term>
/// <term>The dwXCountChars and dwYCountChars members contain additional information.</term>
/// </item>
/// <item>
/// <term>STARTF_USEFILLATTRIBUTE 0x00000010</term>
/// <term>The dwFillAttribute member contains additional information.</term>
/// </item>
/// <item>
/// <term>STARTF_USEHOTKEY 0x00000200</term>
/// <term>The hStdInput member contains additional information. This flag cannot be used with STARTF_USESTDHANDLES.</term>
/// </item>
/// <item>
/// <term>STARTF_USEPOSITION 0x00000004</term>
/// <term>The dwX and dwY members contain additional information.</term>
/// </item>
/// <item>
/// <term>STARTF_USESHOWWINDOW 0x00000001</term>
/// <term>The wShowWindow member contains additional information.</term>
/// </item>
/// <item>
/// <term>STARTF_USESIZE 0x00000002</term>
/// <term>The dwXSize and dwYSize members contain additional information.</term>
/// </item>
/// <item>
/// <term>STARTF_USESTDHANDLES 0x00000100</term>
/// <term>
/// The hStdInput, hStdOutput, and hStdError members contain additional information. If this flag is specified when calling one of
/// the process creation functions, the handles must be inheritable and the function's bInheritHandles parameter must be set to TRUE.
/// For more information, see Handle Inheritance. If this flag is specified when calling the GetStartupInfo function, these members
/// are either the handle value specified during process creation or INVALID_HANDLE_VALUE. Handles must be closed with CloseHandle
/// when they are no longer needed. This flag cannot be used with STARTF_USEHOTKEY.
/// </term>
/// </item>
/// </list>
/// </summary>
public STARTF dwFlags;
/// <summary>
/// <para>
/// If <c>dwFlags</c> specifies STARTF_USESHOWWINDOW, this member can be any of the values that can be specified in the nCmdShow
/// parameter for the ShowWindow function, except for SW_SHOWDEFAULT. Otherwise, this member is ignored.
/// </para>
/// <para>
/// For GUI processes, the first time ShowWindow is called, its nCmdShow parameter is ignored <c>wShowWindow</c> specifies the
/// default value. In subsequent calls to ShowWindow, the <c>wShowWindow</c> member is used if the nCmdShow parameter of
/// <c>ShowWindow</c> is set to SW_SHOWDEFAULT.
/// </para>
/// </summary>
public ushort wShowWindow;
/// <summary>Reserved for use by the C Run-time; must be zero.</summary>
public ushort cbReserved2;
/// <summary>Reserved for use by the C Run-time; must be NULL.</summary>
public IntPtr lpReserved2;
/// <summary>
/// <para>
/// If <c>dwFlags</c> specifies STARTF_USESTDHANDLES, this member is the standard input handle for the process. If
/// STARTF_USESTDHANDLES is not specified, the default for standard input is the keyboard buffer.
/// </para>
/// <para>
/// If <c>dwFlags</c> specifies STARTF_USEHOTKEY, this member specifies a hotkey value that is sent as the wParam parameter of a
/// WM_SETHOTKEY message to the first eligible top-level window created by the application that owns the process. If the window is
/// created with the WS_POPUP window style, it is not eligible unless the WS_EX_APPWINDOW extended window style is also set. For more
/// information, see CreateWindowEx.
/// </para>
/// <para>Otherwise, this member is ignored.</para>
/// </summary>
public HANDLE hStdInput;
/// <summary>
/// <para>
/// If <c>dwFlags</c> specifies STARTF_USESTDHANDLES, this member is the standard output handle for the process. Otherwise, this
/// member is ignored and the default for standard output is the console window's buffer.
/// </para>
/// <para>
/// If a process is launched from the taskbar or jump list, the system sets <c>hStdOutput</c> to a handle to the monitor that
/// contains the taskbar or jump list used to launch the process. For more information, see Remarks. <c>Windows 7, Windows Server
/// 2008 R2, Windows Vista, Windows Server 2008, Windows XP and Windows Server 2003:</c> This behavior was introduced in Windows 8
/// and Windows Server 2012.
/// </para>
/// </summary>
public HANDLE hStdOutput;
/// <summary>
/// If <c>dwFlags</c> specifies STARTF_USESTDHANDLES, this member is the standard error handle for the process. Otherwise, this
/// member is ignored and the default for standard error is the console window's buffer.
/// </summary>
public HANDLE hStdError;
/// <summary>
/// <para>
/// If <c>dwFlags</c> specifies STARTF_USEFILLATTRIBUTE, this member is the initial text and background colors if a new console
/// window is created in a console application. Otherwise, this member is ignored.
/// </para>
/// <para>
/// This value can be any combination of the following values: FOREGROUND_BLUE, FOREGROUND_GREEN, FOREGROUND_RED,
/// FOREGROUND_INTENSITY, BACKGROUND_BLUE, BACKGROUND_GREEN, BACKGROUND_RED, and BACKGROUND_INTENSITY. For example, the following
/// combination of values produces red text on a white background:
/// </para>
/// <para><c>FOREGROUND_RED | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE</c></para>
/// </summary>
public CHARACTER_ATTRIBUTE FillAttribute { get => (CHARACTER_ATTRIBUTE)dwFillAttribute; set { dwFillAttribute = (uint)value; dwFlags = dwFlags.SetFlags(STARTF.STARTF_USEFILLATTRIBUTE, value != 0); } }
/// <summary>
/// <para>
/// This member can be any of the values that can be specified in the nCmdShow parameter for the <c>ShowWindow</c> function, except
/// for SW_SHOWDEFAULT.
/// </para>
/// <para>
/// For GUI processes, the first time <c>ShowWindow</c> is called, its nCmdShow parameter is ignored <c>wShowWindow</c> specifies the
/// default value. In subsequent calls to <c>ShowWindow</c>, the <c>wShowWindow</c> member is used if the nCmdShow parameter of
/// <c>ShowWindow</c> is set to SW_SHOWDEFAULT.
/// </para>
/// </summary>
public ShowWindowCommand ShowWindowCommand { get => (ShowWindowCommand)wShowWindow; set { wShowWindow = (ushort)value; dwFlags = dwFlags.SetFlags(STARTF.STARTF_USESHOWWINDOW, value != 0); } }
/// <summary>
/// <para>The x and y offset of the upper left corner of a window if a new window is created, in pixels.</para>
/// <para>
/// The offset is from the upper left corner of the screen. For GUI processes, the specified position is used the first time the new
/// process calls <c>CreateWindow</c> to create an overlapped window if the x or y parameter of <c>CreateWindow</c> is CW_USEDEFAULT.
/// </para>
/// </summary>
public POINT WindowPosition { get => new((int)dwX, (int)dwY); set { dwX = (uint)value.X; dwY = (uint)value.Y; dwFlags = dwFlags.SetFlags(STARTF.STARTF_USEPOSITION, value != POINT.Empty); } }
2018-10-26 14:24:07 -04:00
/// <summary>
/// <para>The height of the window if a new window is created, in pixels.</para>
/// <para>
/// For GUI processes, this is used only the first time the new process calls <c>CreateWindow</c> to create an overlapped window if
/// the nHeight or nWidth parameter of <c>CreateWindow</c> is CW_USEDEFAULT.
/// </para>
/// </summary>
public SIZE WindowSize { get => new((int)dwXSize, (int)dwYSize); set { dwXSize = (uint)value.cx; dwYSize = (uint)value.cy; dwFlags = dwFlags.SetFlags(STARTF.STARTF_USESIZE, value != SIZE.Empty); } }
/// <summary>Gets the default value for this structure with the <c>cb</c> field set to the size of the structure.</summary>
public static STARTUPINFO Default => new() { cb = (uint)Marshal.SizeOf(typeof(STARTUPINFO)) };
}
2018-10-26 14:24:07 -04:00
/// <summary>
/// <para>
/// Specifies the window station, desktop, standard handles, and attributes for a new process. It is used with the CreateProcess and
/// CreateProcessAsUser functions.
/// </para>
/// </summary>
/// <remarks>
/// <para>Be sure to set the <c>cb</c> member of the STARTUPINFO structure to .</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/winbase/ns-winbase-_startupinfoexa typedef struct _STARTUPINFOEXA { STARTUPINFOA
// StartupInfo; LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList; } STARTUPINFOEXA, *LPSTARTUPINFOEXA;
[PInvokeData("winbase.h", MSDNShortId = "61203f57-292d-4ea1-88f4-a3b05012d7a3")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct STARTUPINFOEX
{
/// <summary>
/// <para>A STARTUPINFO structure.</para>
/// </summary>
public STARTUPINFO StartupInfo;
2018-10-26 14:24:07 -04:00
/// <summary>
/// <para>An attribute list. This list is created by the InitializeProcThreadAttributeList function.</para>
2018-10-26 14:24:07 -04:00
/// </summary>
public IntPtr lpAttributeList;
2018-10-26 14:24:07 -04:00
/// <summary>Gets the default value for this structure with the <c>cb</c> field set to the size of the structure.</summary>
public static STARTUPINFOEX Default => new() { StartupInfo = new STARTUPINFO { cb = (uint)Marshal.SizeOf(typeof(STARTUPINFOEX)) } };
}
2018-10-26 14:24:07 -04:00
/// <summary>
/// <para>
/// This structure is returned by <c>GetSystemCpuSetInformation</c>. It is used to enumerate the CPU Sets on the system and determine
/// their current state.
/// </para>
/// <para>
/// This is a variable-sized structure designed for future expansion. When iterating over this structure, use the size field to determine
/// the offset to the next structure.
/// </para>
/// </summary>
// typedef struct _SYSTEM_CPU_SET_INFORMATION { DWORD Size; CPU_SET_INFORMATION_TYPE Type; union { struct { DWORD Id; WORD Group; BYTE
// LogicalProcessorIndex; BYTE CoreIndex; BYTE LastLevelCacheIndex; BYTE NumaNodeIndex; BYTE EfficiencyClass; struct { BOOLEAN Parked :
// 1; BOOLEAN Allocated : 1; BOOLEAN AllocatedToTargetProcess : 1; BOOLEAN RealTime : 1; BYTE ReservedFlags : 4; }; DWORD Reserved;
// DWORD64 AllocationTag; } CpuSet; };} SYSTEM_CPU_SET_INFORMATION, *PSYSTEM_CPU_SET_INFORMATION;// https://msdn.microsoft.com/en-us/library/windows/desktop/mt186429(v=vs.85).aspx
[PInvokeData("Winnt.h", MSDNShortId = "mt186429")]
[StructLayout(LayoutKind.Explicit)]
public struct SYSTEM_CPU_SET_INFORMATION
{
/// <summary>This is the size, in bytes, of this information structure.</summary>
[FieldOffset(0)]
public uint Size;
2018-10-26 14:24:07 -04:00
/// <summary>This is the type of information in the structure. Applications should skip any structures with unrecognized types.</summary>
[FieldOffset(4)]
public CPU_SET_INFORMATION_TYPE Type;
/// <summary>Value used when Type is CpuSetInformation.</summary>
[FieldOffset(8)]
public CPU_SET CpuSet;
/// <summary>Defines values used when Type is CpuSetInformation.</summary>
[StructLayout(LayoutKind.Sequential)]
public struct CPU_SET
2018-05-13 23:41:49 -04:00
{
/// <summary>
/// The ID of the specified CPU Set. This identifier can be used with SetProcessDefaultCpuSets or SetThreadSelectedCpuSets when
/// specifying a list of CPU Sets to affinitize to.
/// </summary>
public uint Id;
2018-05-13 23:41:49 -04:00
/// <summary>
/// Specifies the Processor Group of the CPU Set. All other values in the CpuSet structure are relative to the processor group.
/// </summary>
public ushort Group;
2018-10-26 14:24:07 -04:00
/// <summary>
/// Specifies the group-relative index of the home processor of the CPU Set. Unless the CPU Set is parked for thermal or power
/// management reasons or assigned for exclusive use to another application, threads will run on the home processor of one of
/// their CPU Sets. The Group and LogicalProcessorIndex fields are the same as the ones found in the PROCESSOR_NUMBER structure
/// and they correspond to the Group field and Mask field of the GROUP_AFFINITY structure.
/// </summary>
public byte LogicalProcessorIndex;
2018-05-13 23:41:49 -04:00
/// <summary>
/// A group-relative value indicating which "Core" has the home processor of the CPU Set. This number is the same for all CPU
/// Sets in the same group that share significant execution resources with each other, such as different hardware threads on a
/// single core that supports simultaneous multi-threading.
/// </summary>
public byte CoreIndex;
2018-05-13 23:41:49 -04:00
/// <summary>
/// A group-relative value indicating which CPU Sets share at least one level of cache with each other. This value is the same
/// for all CPU Sets in a group that are on processors that share cache with each other.
/// </summary>
public byte LastLevelCacheIndex;
2018-05-13 23:41:49 -04:00
/// <summary>
/// A group-relative value indicating which NUMA node a CPU Set is on. All CPU Sets in a given group that are on the same NUMA
/// node will have the same value for this field.
/// </summary>
public byte NumaNodeIndex;
2018-05-13 23:41:49 -04:00
/// <summary>
/// A value indicating the intrinsic energy efficiency of a processor for systems that support heterogeneous processors (such as
/// ARM big.LITTLE systems). CPU Sets with higher numerical values of this field have home processors that are faster but less
/// power-efficient than ones with lower values.
/// </summary>
public byte EfficiencyClass;
2018-05-13 23:41:49 -04:00
/// <summary>All flags</summary>
public SYSTEM_CPU_SET_FLAGS AllFlags;
2018-05-13 23:41:49 -04:00
/// <summary>Reserved</summary>
private readonly uint Reserved;
2018-05-13 23:41:49 -04:00
/// <summary>
/// Specifies a tag used by Core Allocation to communicate a given allocated CPU Set between threads in different components.
2018-05-13 23:41:49 -04:00
/// </summary>
public ulong AllocationTag;
}
}
2018-05-13 23:41:49 -04:00
/// <summary>Specifies the throttling policies and how to apply them to a target thread when that thread is subject to power management.</summary>
// typedef struct _THREAD_POWER_THROTTLING_STATE { ULONG Version; ULONG ControlMask; ULONG StateMask;} THREAD_POWER_THROTTLING_STATE,
// *PTHREAD_POWER_THROTTLING_STATE; https://msdn.microsoft.com/en-us/library/windows/desktop/mt804325(v=vs.85).aspx
[PInvokeData("Processthreadsapi.h", MSDNShortId = "mt804325")]
[StructLayout(LayoutKind.Sequential)]
public struct THREAD_POWER_THROTTLING_STATE
{
/// <summary/>
public const uint THREAD_POWER_THROTTLING_CURRENT_VERSION = 1;
/// <summary/>
public const uint THREAD_POWER_THROTTLING_EXECUTION_SPEED = 0x1;
/// <summary>
/// <para>The version of the <c>THREAD_POWER_THROTTLING_STATE</c> structure.</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>THREAD_POWER_THROTTLING_CURRENT_VERSION</term>
/// <term>The current version.</term>
/// </item>
/// </list>
/// </para>
/// </summary>
public uint Version;
/// <summary>
/// <para>This field enables the caller to take control of the power throttling mechanism.</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>THREAD_POWER_THROTTLING_EXECUTION_SPEED</term>
/// <term>Manages the execution speed of the thread.</term>
/// </item>
/// </list>
/// </para>
/// </summary>
public uint ControlMask;
/// <summary>
/// <para>Manages the power throttling mechanism on/off state.</para>
/// <para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>THREAD_POWER_THROTTLING_EXECUTION_SPEED</term>
/// <term>Manages the execution speed of the thread.</term>
/// </item>
/// </list>
/// </para>
/// </summary>
public uint StateMask;
/// <summary>Creates an initialized instance of THREAD_POWER_THROTTLING_STATE.</summary>
public static THREAD_POWER_THROTTLING_STATE Create() => new() { Version = THREAD_POWER_THROTTLING_CURRENT_VERSION, ControlMask = THREAD_POWER_THROTTLING_EXECUTION_SPEED };
}
2018-10-26 14:24:07 -04:00
/// <summary>
/// Specifies the window station, desktop, standard handles, and appearance of the main window for a process at creation time.
/// </summary>
/// <remarks>
/// <para>
/// For graphical user interface (GUI) processes, this information affects the first window created by the CreateWindow function and
/// shown by the ShowWindow function. For console processes, this information affects the console window if a new console is created for
/// the process. A process can use the GetStartupInfo function to retrieve the <c>STARTUPINFO</c> structure specified when the process
/// was created.
/// </para>
/// <para>
/// If a GUI process is being started and neither STARTF_FORCEONFEEDBACK or STARTF_FORCEOFFFEEDBACK is specified, the process feedback
/// cursor is used. A GUI process is one whose subsystem is specified as "windows."
/// </para>
/// <para>
/// If a process is launched from the taskbar or jump list, the system sets <c>hStdOutput</c> to a handle to the monitor that contains
/// the taskbar or jump list used to launch the process. To retrieve this handle, use GetStartupInfo to retrieve the <c>STARTUPINFO</c>
/// structure and check that <c>hStdOutput</c> is set. If so, use GetMonitorInfo to check whether <c>hStdOutput</c> is a valid monitor
/// handle (HMONITOR). The process can then use the handle to position its windows.
/// </para>
/// <para>
/// If the <c>STARTF_UNTRUSTEDSOURCE</c> flag is set in the in the <c>STARTUPINFO</c> structure returned by the GetStartupInfo function,
/// then applications should be aware that the command line is untrusted. If this flag is set, applications should disable potentially
/// dangerous features such as macros, downloaded content, and automatic printing. This flag is optional. Applications that call
/// CreateProcess are encouraged to set this flag when launching a program with a untrusted command line so that the created process can
/// apply appropriate policy.
/// </para>
/// <para>
/// The <c>STARTF_UNTRUSTEDSOURCE</c> flag is supported starting in Windows Vista, but it is not defined in the SDK header files prior to
/// the Windows 10 SDK. To use the flag in versions prior to Windows 10, you can define it manually in your program.
/// </para>
/// <para>Examples</para>
/// <para>For an example, see Creating Processes.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/ns-processthreadsapi-_startupinfoa typedef struct _STARTUPINFOA {
// DWORD cb; LPSTR lpReserved; LPSTR lpDesktop; LPSTR lpTitle; DWORD dwX; DWORD dwY; DWORD dwXSize; DWORD dwYSize; DWORD dwXCountChars;
// DWORD dwYCountChars; DWORD dwFillAttribute; DWORD dwFlags; WORD wShowWindow; WORD cbReserved2; LPBYTE lpReserved2; HANDLE hStdInput;
// HANDLE hStdOutput; HANDLE hStdError; } STARTUPINFOA, *LPSTARTUPINFOA;
[PInvokeData("processthreadsapi.h", MSDNShortId = "cf4b795c-52c1-4573-8328-99ee13f68bb3")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
private struct STARTUPINFO_OUT
{
/// <summary>The size of the structure, in bytes.</summary>
public uint cb;
2018-10-26 14:24:07 -04:00
/// <summary>Reserved; must be NULL.</summary>
public IntPtr lpReserved;
2018-05-13 23:41:49 -04:00
/// <summary>
/// The name of the desktop, or the name of both the desktop and window station for this process. A backslash in the string indicates
/// that the string includes both the desktop and window station names.
/// <para>
/// For more information, see <a href="https://msdn.microsoft.com/45016619-ed11-4b0c-84e3-f8662553c64d">Thread Connection to a Desktop</a>.
/// </para>
/// </summary>
//[MarshalAs(UnmanagedType.LPTStr)]
//public string lpDesktop;
public StrPtrAuto lpDesktop;
2018-10-26 14:24:07 -04:00
/// <summary>
/// For console processes, this is the title displayed in the title bar if a new console window is created. If NULL, the name of the
/// executable file is used as the window title instead. This parameter must be NULL for GUI or console processes that do not create
/// a new console window.
/// </summary>
//[MarshalAs(UnmanagedType.LPTStr)]
//public string lpTitle;
public StrPtrAuto lpTitle;
2018-05-13 23:41:49 -04:00
/// <summary>
/// <para>
/// If <c>dwFlags</c> specifies STARTF_USEPOSITION, this member is the x offset of the upper left corner of a window if a new window
/// is created, in pixels. Otherwise, this member is ignored.
/// </para>
/// <para>
/// The offset is from the upper left corner of the screen. For GUI processes, the specified position is used the first time the new
/// process calls CreateWindow to create an overlapped window if the x parameter of <c>CreateWindow</c> is CW_USEDEFAULT.
/// </para>
/// </summary>
public uint dwX;
2018-05-13 23:41:49 -04:00
/// <summary>
/// <para>
/// If <c>dwFlags</c> specifies STARTF_USEPOSITION, this member is the y offset of the upper left corner of a window if a new window
/// is created, in pixels. Otherwise, this member is ignored.
/// </para>
/// <para>
/// The offset is from the upper left corner of the screen. For GUI processes, the specified position is used the first time the new
/// process calls CreateWindow to create an overlapped window if the y parameter of <c>CreateWindow</c> is CW_USEDEFAULT.
/// </para>
2018-05-13 23:41:49 -04:00
/// </summary>
public uint dwY;
2018-05-13 23:41:49 -04:00
/// <summary>
/// <para>
/// If <c>dwFlags</c> specifies STARTF_USESIZE, this member is the width of the window if a new window is created, in pixels.
/// Otherwise, this member is ignored.
/// </para>
/// <para>
/// For GUI processes, this is used only the first time the new process calls CreateWindow to create an overlapped window if the
/// nWidth parameter of <c>CreateWindow</c> is CW_USEDEFAULT.
/// </para>
/// </summary>
public uint dwXSize;
2018-05-13 23:41:49 -04:00
2018-10-26 14:24:07 -04:00
/// <summary>
/// <para>
/// If <c>dwFlags</c> specifies STARTF_USESIZE, this member is the height of the window if a new window is created, in pixels.
/// Otherwise, this member is ignored.
/// </para>
/// <para>
/// For GUI processes, this is used only the first time the new process calls CreateWindow to create an overlapped window if the
/// nHeight parameter of <c>CreateWindow</c> is CW_USEDEFAULT.
/// </para>
2018-10-26 14:24:07 -04:00
/// </summary>
public uint dwYSize;
2018-10-26 14:24:07 -04:00
/// <summary>
/// If <c>dwFlags</c> specifies STARTF_USECOUNTCHARS, if a new console window is created in a console process, this member specifies
/// the screen buffer width, in character columns. Otherwise, this member is ignored.
/// </summary>
public uint dwXCountChars;
2018-05-13 23:41:49 -04:00
2018-10-26 14:24:07 -04:00
/// <summary>
/// If <c>dwFlags</c> specifies STARTF_USECOUNTCHARS, if a new console window is created in a console process, this member specifies
/// the screen buffer height, in character rows. Otherwise, this member is ignored.
2018-10-26 14:24:07 -04:00
/// </summary>
public uint dwYCountChars;
/// <summary>
/// <para>
/// If <c>dwFlags</c> specifies STARTF_USEFILLATTRIBUTE, this member is the initial text and background colors if a new console
/// window is created in a console application. Otherwise, this member is ignored.
/// </para>
/// <para>
/// This value can be any combination of the following values: FOREGROUND_BLUE, FOREGROUND_GREEN, FOREGROUND_RED,
/// FOREGROUND_INTENSITY, BACKGROUND_BLUE, BACKGROUND_GREEN, BACKGROUND_RED, and BACKGROUND_INTENSITY. For example, the following
/// combination of values produces red text on a white background:
/// </para>
/// <para><c>FOREGROUND_RED | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE</c></para>
/// </summary>
public uint dwFillAttribute; // CHARACTER_ATTRIBUTE
/// <summary>
/// <para>
/// A bitfield that determines whether certain <c>STARTUPINFO</c> members are used when the process creates a window. This member can
/// be one or more of the following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>STARTF_FORCEONFEEDBACK 0x00000040</term>
/// <term>
/// Indicates that the cursor is in feedback mode for two seconds after CreateProcess is called. The Working in Background cursor is
/// displayed (see the Pointers tab in the Mouse control panel utility). If during those two seconds the process makes the first GUI
/// call, the system gives five more seconds to the process. If during those five seconds the process shows a window, the system
/// gives five more seconds to the process to finish drawing the window. The system turns the feedback cursor off after the first
/// call to GetMessage, regardless of whether the process is drawing.
/// </term>
/// </item>
/// <item>
/// <term>STARTF_FORCEOFFFEEDBACK 0x00000080</term>
/// <term>Indicates that the feedback cursor is forced off while the process is starting. The Normal Select cursor is displayed.</term>
/// </item>
/// <item>
/// <term>STARTF_PREVENTPINNING 0x00002000</term>
/// <term>Indicates that any windows created by the process cannot be pinned on the taskbar. This flag must be combined with STARTF_TITLEISAPPID.</term>
/// </item>
/// <item>
/// <term>STARTF_RUNFULLSCREEN 0x00000020</term>
/// <term>
/// Indicates that the process should be run in full-screen mode, rather than in windowed mode. This flag is only valid for console
/// applications running on an x86 computer.
/// </term>
/// </item>
/// <item>
/// <term>STARTF_TITLEISAPPID 0x00001000</term>
/// <term>
/// The lpTitle member contains an AppUserModelID. This identifier controls how the taskbar and Start menu present the application,
/// and enables it to be associated with the correct shortcuts and Jump Lists. Generally, applications will use the
/// SetCurrentProcessExplicitAppUserModelID and GetCurrentProcessExplicitAppUserModelID functions instead of setting this flag. For
/// more information, see Application User Model IDs. If STARTF_PREVENTPINNING is used, application windows cannot be pinned on the
/// taskbar. The use of any AppUserModelID-related window properties by the application overrides this setting for that window only.
/// This flag cannot be used with STARTF_TITLEISLINKNAME.
/// </term>
/// </item>
/// <item>
/// <term>STARTF_TITLEISLINKNAME 0x00000800</term>
/// <term>
/// The lpTitle member contains the path of the shortcut file (.lnk) that the user invoked to start this process. This is typically
/// set by the shell when a .lnk file pointing to the launched application is invoked. Most applications will not need to set this
/// value. This flag cannot be used with STARTF_TITLEISAPPID.
/// </term>
/// </item>
/// <item>
/// <term>STARTF_UNTRUSTEDSOURCE 0x00008000</term>
/// <term>The command line came from an untrusted source. For more information, see Remarks.</term>
/// </item>
/// <item>
/// <term/>
/// <term/>
/// </item>
/// <item>
/// <term>STARTF_USECOUNTCHARS 0x00000008</term>
/// <term>The dwXCountChars and dwYCountChars members contain additional information.</term>
/// </item>
/// <item>
/// <term>STARTF_USEFILLATTRIBUTE 0x00000010</term>
/// <term>The dwFillAttribute member contains additional information.</term>
/// </item>
/// <item>
/// <term>STARTF_USEHOTKEY 0x00000200</term>
/// <term>The hStdInput member contains additional information. This flag cannot be used with STARTF_USESTDHANDLES.</term>
/// </item>
/// <item>
/// <term>STARTF_USEPOSITION 0x00000004</term>
/// <term>The dwX and dwY members contain additional information.</term>
/// </item>
/// <item>
/// <term>STARTF_USESHOWWINDOW 0x00000001</term>
/// <term>The wShowWindow member contains additional information.</term>
/// </item>
/// <item>
/// <term>STARTF_USESIZE 0x00000002</term>
/// <term>The dwXSize and dwYSize members contain additional information.</term>
/// </item>
/// <item>
/// <term>STARTF_USESTDHANDLES 0x00000100</term>
/// <term>
/// The hStdInput, hStdOutput, and hStdError members contain additional information. If this flag is specified when calling one of
/// the process creation functions, the handles must be inheritable and the function's bInheritHandles parameter must be set to TRUE.
/// For more information, see Handle Inheritance. If this flag is specified when calling the GetStartupInfo function, these members
/// are either the handle value specified during process creation or INVALID_HANDLE_VALUE. Handles must be closed with CloseHandle
/// when they are no longer needed. This flag cannot be used with STARTF_USEHOTKEY.
/// </term>
/// </item>
/// </list>
/// </summary>
public STARTF dwFlags;
/// <summary>
/// <para>
/// If <c>dwFlags</c> specifies STARTF_USESHOWWINDOW, this member can be any of the values that can be specified in the nCmdShow
/// parameter for the ShowWindow function, except for SW_SHOWDEFAULT. Otherwise, this member is ignored.
/// </para>
/// <para>
/// For GUI processes, the first time ShowWindow is called, its nCmdShow parameter is ignored <c>wShowWindow</c> specifies the
/// default value. In subsequent calls to ShowWindow, the <c>wShowWindow</c> member is used if the nCmdShow parameter of
/// <c>ShowWindow</c> is set to SW_SHOWDEFAULT.
/// </para>
/// </summary>
public ushort wShowWindow;
2018-10-26 14:24:07 -04:00
/// <summary>Reserved for use by the C Run-time; must be zero.</summary>
public ushort cbReserved2;
2018-10-26 14:24:07 -04:00
/// <summary>Reserved for use by the C Run-time; must be NULL.</summary>
public IntPtr lpReserved2;
2018-10-26 14:24:07 -04:00
/// <summary>
/// <para>
/// If <c>dwFlags</c> specifies STARTF_USESTDHANDLES, this member is the standard input handle for the process. If
/// STARTF_USESTDHANDLES is not specified, the default for standard input is the keyboard buffer.
/// </para>
/// <para>
/// If <c>dwFlags</c> specifies STARTF_USEHOTKEY, this member specifies a hotkey value that is sent as the wParam parameter of a
/// WM_SETHOTKEY message to the first eligible top-level window created by the application that owns the process. If the window is
/// created with the WS_POPUP window style, it is not eligible unless the WS_EX_APPWINDOW extended window style is also set. For more
/// information, see CreateWindowEx.
/// </para>
/// <para>Otherwise, this member is ignored.</para>
/// </summary>
public HANDLE hStdInput;
2018-10-26 14:24:07 -04:00
/// <summary>
/// <para>
/// If <c>dwFlags</c> specifies STARTF_USESTDHANDLES, this member is the standard output handle for the process. Otherwise, this
/// member is ignored and the default for standard output is the console window's buffer.
/// </para>
/// <para>
/// If a process is launched from the taskbar or jump list, the system sets <c>hStdOutput</c> to a handle to the monitor that
/// contains the taskbar or jump list used to launch the process. For more information, see Remarks. <c>Windows 7, Windows Server
/// 2008 R2, Windows Vista, Windows Server 2008, Windows XP and Windows Server 2003:</c> This behavior was introduced in Windows 8
/// and Windows Server 2012.
/// </para>
/// </summary>
public HANDLE hStdOutput;
2018-10-26 14:24:07 -04:00
/// <summary>
/// If <c>dwFlags</c> specifies STARTF_USESTDHANDLES, this member is the standard error handle for the process. Otherwise, this
/// member is ignored and the default for standard error is the console window's buffer.
/// </summary>
public HANDLE hStdError;
2018-10-26 14:24:07 -04:00
/// <summary>Performs an implicit conversion from <see cref="STARTUPINFO_OUT"/> to <see cref="STARTUPINFO"/>.</summary>
/// <param name="sio">The STARTUPINFO_OUT instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator STARTUPINFO(STARTUPINFO_OUT sio) => new()
{
cb = sio.cb,
lpReserved = sio.lpReserved,
lpDesktop = sio.lpDesktop,
lpTitle = sio.lpTitle,
dwX = sio.dwX,
dwY = sio.dwY,
dwXSize = sio.dwXSize,
dwYSize = sio.dwYSize,
dwXCountChars = sio.dwXCountChars,
dwYCountChars = sio.dwYCountChars,
dwFillAttribute = sio.dwFillAttribute,
dwFlags = sio.dwFlags,
wShowWindow = sio.wShowWindow,
cbReserved2 = sio.cbReserved2,
lpReserved2 = sio.lpReserved2,
hStdInput = sio.hStdInput,
hStdOutput = sio.hStdOutput,
hStdError = sio.hStdError,
};
}
2018-10-26 14:24:07 -04:00
/// <summary>Provides a <see cref="SafeHandle"/> to a process that releases a created HPROCESS instance at disposal using CloseHandle.</summary>
public class SafeHPROCESS : SafeSyncHandle
{
/// <summary>Initializes a new instance of the <see cref="HPROCESS"/> 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 SafeHPROCESS(HPROCESS preexistingHandle, bool ownsHandle = true) : base((IntPtr)preexistingHandle, ownsHandle) { }
2018-10-26 14:24:07 -04:00
private SafeHPROCESS() : base()
{
}
2018-10-26 14:24:07 -04:00
/// <summary>Gets a handle to the current process that can be used across processes.</summary>
/// <value>The current process handle.</value>
public static SafeHPROCESS Current => new(GetCurrentProcess().Duplicate());
2018-10-26 14:24:07 -04:00
/// <summary>Represents a <see langword="null"/> or invalid process.</summary>
public static SafeHPROCESS Null => new();
2018-10-26 14:24:07 -04:00
/// <summary>Performs an implicit conversion from <see cref="SafeHPROCESS"/> to <see cref="HPROCESS"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HPROCESS(SafeHPROCESS h) => h.handle;
}
2018-10-26 14:24:07 -04:00
/// <summary>Provides a <see cref="SafeHandle"/> to a thread that releases a created HTHREAD instance at disposal using CloseHandle.</summary>
public class SafeHTHREAD : SafeSyncHandle
{
/// <summary>Initializes a new instance of the <see cref="HTHREAD"/> 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 SafeHTHREAD(HTHREAD preexistingHandle, bool ownsHandle = true) : base((IntPtr)preexistingHandle, ownsHandle) { }
2018-05-13 23:41:49 -04:00
private SafeHTHREAD() : base()
2018-10-26 14:24:07 -04:00
{
}
/// <summary>Gets a handle to the current thread that can be used across processes.</summary>
/// <value>The current thread handle.</value>
public static SafeHTHREAD Current => new(GetCurrentThread().Duplicate());
/// <summary>Performs an implicit conversion from <see cref="SafeHTHREAD"/> to <see cref="HTHREAD"/>.</summary>
/// <param name="h">The safe handle instance.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator HTHREAD(SafeHTHREAD h) => h.handle;
}
/// <summary>
/// Contains information about a newly created process and its primary thread. It is used with the <c>CreateProcess</c>,
/// <c>CreateProcessAsUser</c>, <c>CreateProcessWithLogonW</c>, or <c>CreateProcessWithTokenW</c> function. This class will close the
/// process and thread handles at disposal.
/// </summary>
// typedef struct _PROCESS_INFORMATION { HANDLE hProcess; HANDLE hThread; DWORD dwProcessId; DWORD dwThreadId;} PROCESS_INFORMATION,
// *LPPROCESS_INFORMATION; https://msdn.microsoft.com/en-us/library/windows/desktop/ms684873(v=vs.85).aspx
[PInvokeData("WinBase.h", MSDNShortId = "ms684873")]
public sealed class SafePROCESS_INFORMATION : IDisposable
{
/// <summary>Initializes a new instance of the <see cref="SafePROCESS_INFORMATION"/> class.</summary>
/// <param name="pi">The pi.</param>
public SafePROCESS_INFORMATION(in PROCESS_INFORMATION pi)
{
hProcess = new SafeHPROCESS(pi.hProcess);
hThread = new SafeHTHREAD(pi.hThread);
dwProcessId = pi.dwProcessId;
dwThreadId = pi.dwThreadId;
}
/// <summary>Initializes an empty instance of the <see cref="SafePROCESS_INFORMATION"/> class.</summary>
public SafePROCESS_INFORMATION()
{
hProcess = new SafeHPROCESS(IntPtr.Zero);
hThread = new SafeHTHREAD(IntPtr.Zero);
}
/// <summary>
/// A value that can be used to identify a process. The value is valid from the time the process is created until all handles to the
/// process are closed and the process object is freed; at this point, the identifier may be reused.
/// </summary>
public uint dwProcessId { get; }
/// <summary>
/// A value that can be used to identify a thread. The value is valid from the time the thread is created until all handles to the
/// thread are closed and the thread object is freed; at this point, the identifier may be reused.
/// </summary>
public uint dwThreadId { get; }
2018-10-26 14:24:07 -04:00
/// <summary>
/// A handle to the newly created process. The handle is used to specify the process in all functions that perform operations on the
/// process object.
2018-10-26 14:24:07 -04:00
/// </summary>
public SafeHPROCESS hProcess { get; private set; }
/// <summary>
/// A handle to the primary thread of the newly created process. The handle is used to specify the thread in all functions that
/// perform operations on the thread object.
/// </summary>
public SafeHTHREAD hThread { get; private set; }
2018-10-26 14:24:07 -04:00
/// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
void IDisposable.Dispose()
{
hProcess.Dispose();
hThread.Dispose();
}
}
2018-10-26 14:24:07 -04:00
/// <summary>
/// Provides a <see cref="SafeHandle"/> for a list of <see cref="PROC_THREAD_ATTRIBUTE"/> structures that is disposed using <see cref="DeleteProcThreadAttributeList"/>.
/// </summary>
public class SafeProcThreadAttributeList : SafeHANDLE
{
private readonly List<(PROC_THREAD_ATTRIBUTE attr, object obj, PinnedObject ptr)> values = new();
2018-10-26 14:24:07 -04:00
/// <summary>Initializes a new instance of the <see cref="SafeProcThreadAttributeList"/> 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 SafeProcThreadAttributeList(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
2018-10-26 14:24:07 -04:00
/// <summary>Initializes a new instance of the <see cref="SafeProcThreadAttributeList"/> class.</summary>
private SafeProcThreadAttributeList() : base() { }
2018-10-26 14:24:07 -04:00
/// <summary>Creates an instance of a SafeProcThreadAttributeList with a single attribute and value added.</summary>
/// <param name="attribute">The attribute.</param>
/// <param name="value">The value.</param>
/// <returns>A <see cref="SafeProcThreadAttributeList"/> instance with the attribute/value pair added.</returns>
public static SafeProcThreadAttributeList Create(PROC_THREAD_ATTRIBUTE attribute, object value) =>
Create(new Dictionary<PROC_THREAD_ATTRIBUTE, object> { { attribute, value } });
/// <summary>Creates an instance of a SafeProcThreadAttributeList with a list of attributes/value pairs added.</summary>
/// <param name="attributes">A dictionary of attribute/value pairs to add.</param>
/// <returns>A <see cref="SafeProcThreadAttributeList"/> instance with the supplied attribute/value pairs added.</returns>
public static SafeProcThreadAttributeList Create(IDictionary<PROC_THREAD_ATTRIBUTE, object> attributes)
{
if (attributes is null) throw new ArgumentNullException(nameof(attributes));
foreach (KeyValuePair<PROC_THREAD_ATTRIBUTE, object> kv in attributes)
if (!IsValid(kv.Key, kv.Value)) throw new ArgumentException($"The attribute {kv.Key} does not support a value of type {kv.Value.GetType().Name}.");
SizeT sz = 0;
InitializeProcThreadAttributeList(IntPtr.Zero, (uint)attributes.Count, 0, ref sz);
if (sz == 0) Win32Error.ThrowLastError();
RuntimeHelpers.PrepareConstrainedRegions();
IntPtr ptr = Marshal.AllocHGlobal(sz);
if (!InitializeProcThreadAttributeList(ptr, (uint)attributes.Count, 0, ref sz))
2018-10-26 14:24:07 -04:00
{
Marshal.FreeHGlobal(ptr);
Win32Error.ThrowLastError();
2018-10-26 14:24:07 -04:00
}
SafeProcThreadAttributeList hAttr = new(ptr);
foreach (KeyValuePair<PROC_THREAD_ATTRIBUTE, object> kv in attributes)
hAttr.Add(kv.Key, kv.Value);
return hAttr;
2018-10-26 14:24:07 -04:00
}
/// <summary>Clones this instance.</summary>
/// <returns>A new instance of the list with all attributes and objects duplicated.</returns>
public SafeProcThreadAttributeList Clone()
{
Dictionary<PROC_THREAD_ATTRIBUTE, object> d = new();
foreach ((PROC_THREAD_ATTRIBUTE attr, object obj, _) in values) d.Add(attr, obj);
return Create(d);
}
/// <inheritdoc/>
protected override bool InternalReleaseHandle()
{
foreach ((PROC_THREAD_ATTRIBUTE _, object _, PinnedObject ptr) in values)
ptr.Dispose();
values.Clear();
DeleteProcThreadAttributeList(handle);
Marshal.FreeHGlobal(handle);
return true;
}
private static bool IsValid(PROC_THREAD_ATTRIBUTE attr, object value) => value is not null && value.GetType().Equals(attr.ValidType);
private void Add(PROC_THREAD_ATTRIBUTE attr, object value)
{
PinnedObject pVal = new(value);
values.Add((attr, value, pVal));
if (!UpdateProcThreadAttribute(handle, 0, attr, pVal, InteropExtensions.SizeOf(value)))
Win32Error.ThrowLastError();
}
2018-05-13 23:41:49 -04:00
}
}