using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using Vanara.Extensions; using Vanara.Extensions.Reflection; using Vanara.InteropServices; namespace Vanara.PInvoke { /// Platform invokable enumerated types, constants and functions from ntdll.h public static partial class NtDll { /// /// [This function may be changed or removed from Windows without further notice.] /// /// A notification callback function specified with the LdrRegisterDllNotification function. The loader calls this function /// when a DLL is first loaded. /// /// Warning: It is unsafe for the notification callback function to call functions in any DLL. /// /// /// This callback function does not return a value. /// /// /// The notification callback function is called before dynamic linking takes place. /// // https://docs.microsoft.com/en-us/windows/desktop/DevNotes/ldrdllnotification VOID CALLBACK LdrDllNotification( _In_ ULONG // NotificationReason, _In_ PCLDR_DLL_NOTIFICATION_DATA NotificationData, _In_opt_ PVOID Context ); [UnmanagedFunctionPointer(CallingConvention.Winapi)] [PInvokeData("ntldr.h", MSDNShortId = "12202797-c80c-4fa3-9cc4-dcb1a9f01551")] public delegate void LdrDllNotification(uint NotificationReason, ref LDR_DLL_NOTIFICATION_DATA NotificationData, [In, Optional] IntPtr Context); /// Lists the different types of notifications that can be received by an enlistment. [PInvokeData("ktmtypes.h", MSDNShortId = "32c2be6a-c75a-9391-274d-a53a6e2b74c8")] public enum NOTIFICATION_MASK { /// A mask that indicates all valid bits for a transaction notification. TRANSACTION_NOTIFY_MASK = 0x3FFFFFFF, /// /// This notification is called after a client calls CommitTransaction and either no resource manager (RM) supports single-phase /// commit or a superior transaction manager (TM) calls PrePrepareEnlistment. This notification is received by the RMs /// indicating that they should complete any work that could cause other RMs to need to enlist in a transaction, such as /// flushing its cache. After completing these operations the RM must call PrePrepareComplete. To receive this notification the /// RM must also support TRANSACTION_NOTIFY_PREPARE and TRANSACTION_NOTIFY_COMMIT. /// TRANSACTION_NOTIFY_PREPREPARE = 0x00000001, /// /// This notification is called after the TRANSACTION_NOTIFY_PREPREPARE processing is complete. It signals the RM to complete /// all the work that is associated with this enlistment so that it can guarantee that a commit operation could succeed and an /// abort operation could also succeed. Typically, the bulk of the work for a transaction is done during the prepare phase. For /// durable RMs, they must log their state prior to calling the PrepareComplete function. This is the last chance for the RM to /// request that the transaction be rolled back. /// TRANSACTION_NOTIFY_PREPARE = 0x00000002, /// /// This notification signals the RM to complete all the work that is associated with this enlistment. Typically, the RM /// releases any locks, releases any information necessary to roll back the transaction. The RM must respond by calling the /// CommitComplete function when it has finished these operations. /// TRANSACTION_NOTIFY_COMMIT = 0x00000004, /// This notification signals the RM to undo all the work it has done that is associated with the transaction. TRANSACTION_NOTIFY_ROLLBACK = 0x00000008, /// This notification signals to the superior TM that a pre-prepare operation was completed successfully. TRANSACTION_NOTIFY_PREPREPARE_COMPLETE = 0x00000010, /// This notification signals to the superior TM that a prepare operation was completed successfully. TRANSACTION_NOTIFY_PREPARE_COMPLETE = 0x00000020, /// This notification signals to the superior TM that a commit operation was completed successfully. TRANSACTION_NOTIFY_COMMIT_COMPLETE = 0x00000040, /// This notification signals to the superior TM that a rollback operation was completed successfully. TRANSACTION_NOTIFY_ROLLBACK_COMPLETE = 0x00000080, /// /// This notification signals to RMs that they should recover their state because a transaction outcome must be redelivered. For /// example, when an RM is recovered, and when there are transactions left in-doubt. This notification is delivered once the /// in-doubt state is resolved. /// TRANSACTION_NOTIFY_RECOVER = 0x00000100, /// /// This notification signals the RM to complete and commit the transaction without using a two-phase commit protocol. If the RM /// wants to use a two-phase operation, it must respond by calling the SinglePhaseReject function. /// TRANSACTION_NOTIFY_SINGLE_PHASE_COMMIT = 0x00000200, /// KTM is signaling to the superior TM to perform a commit operation. TRANSACTION_NOTIFY_DELEGATE_COMMIT = 0x00000400, /// KTM is signaling to the superior TM to query the status of an in-doubt transaction. TRANSACTION_NOTIFY_RECOVER_QUERY = 0x00000800, /// /// This notification signals to the superior TM that pre-prepare notifications must be delivered on the specified enlistment. /// TRANSACTION_NOTIFY_ENLIST_PREPREPARE = 0x00001000, /// This notification indicates that the recovery operation is complete for this RM. TRANSACTION_NOTIFY_LAST_RECOVER = 0x00002000, /// /// The specified transaction is in an in-doubt state. The RM receives this notification during recovery operations when a /// transaction has been prepared, but there is no superior transaction manager (TM) available. For example, when a transaction /// involves a remote TM and that node is unavailable, its node is unavailable, or the local Distributed Transaction Coordinator /// service is unavailable, the transaction state is in-doubt. /// TRANSACTION_NOTIFY_INDOUBT = 0x00004000, /// Undocumented or not supported. TRANSACTION_NOTIFY_PROPAGATE_PULL = 0x00008000, /// Undocumented or not supported. TRANSACTION_NOTIFY_PROPAGATE_PUSH = 0x00010000, /// Undocumented or not supported. TRANSACTION_NOTIFY_MARSHAL = 0x00020000, /// Undocumented or not supported. TRANSACTION_NOTIFY_ENLIST_MASK = 0x00040000, /// Undocumented or not supported. TRANSACTION_NOTIFY_RM_DISCONNECTED = 0x01000000, /// Undocumented or not supported. TRANSACTION_NOTIFY_TM_ONLINE = 0x02000000, /// Undocumented or not supported. TRANSACTION_NOTIFY_COMMIT_REQUEST = 0x04000000, /// Undocumented or not supported. TRANSACTION_NOTIFY_PROMOTE = 0x08000000, /// Undocumented or not supported. TRANSACTION_NOTIFY_PROMOTE_NEW = 0x10000000, /// /// Signals to RMs that there is outcome information available, and that a request for that information should be made. /// TRANSACTION_NOTIFY_REQUEST_OUTCOME = 0x20000000, /// Reserved. TRANSACTION_NOTIFY_COMMIT_FINALIZE = 0x40000000, } /// Indicates the kind of system information to be retrieved by . [PInvokeData("winternl.h", MSDNShortId = "553ec7b9-c5eb-4955-8dc0-f1c06f59fe31")] public enum SYSTEM_INFORMATION_CLASS { /// /// Returns the number of processors in the system in a SYSTEM_BASIC_INFORMATION structure. Use the GetSystemInfo function instead. /// [Obsolete("Use the GetSystemInfo function instead.")] [CorrespondingType(typeof(SYSTEM_BASIC_INFORMATION))] SystemBasicInformation = 0, /// /// Returns an opaque SYSTEM_PERFORMANCE_INFORMATION structure that can be used to generate an unpredictable seed for a random /// number generator. Use the CryptGenRandomfunction instead. /// [Obsolete("Use the CryptGenRandomfunction function instead.")] SystemPerformanceInformation = 2, /// /// Returns an opaque SYSTEM_TIMEOFDAY_INFORMATION structure that can be used to generate an unpredictable seed for a random /// number generator. Use the CryptGenRandom function instead. /// [Obsolete("Use the CryptGenRandom function instead.")] SystemTimeOfDayInformation = 3, /// /// Returns an array of SYSTEM_PROCESS_INFORMATION structures, one for each process running in the system. /// /// These structures contain information about the resource usage of each process, including the number of threads and handles /// used by the process, the peak page-file usage, and the number of memory pages that the process has allocated. /// /// [CorrespondingType(typeof(SYSTEM_PROCESS_INFORMATION[]))] SystemProcessInformation = 5, /// /// Returns an array of SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION structures, one for each processor installed in the system. /// [CorrespondingType(typeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION[]))] SystemProcessorPerformanceInformation = 8, /// /// Returns an opaque SYSTEM_INTERRUPT_INFORMATION structure that can be used to generate an unpredictable seed for a random /// number generator. Use the CryptGenRandom function instead. /// [Obsolete("Use the CryptGenRandom function instead.")] SystemInterruptInformation = 23, /// /// Returns an opaque SYSTEM_EXCEPTION_INFORMATION structure that can be used to generate an unpredictable seed for a random /// number generator. Use the CryptGenRandom function instead. /// [Obsolete("Use the CryptGenRandom function instead.")] SystemExceptionInformation = 33, /// Returns a SYSTEM_REGISTRY_QUOTA_INFORMATION structure. [CorrespondingType(typeof(SYSTEM_REGISTRY_QUOTA_INFORMATION))] SystemRegistryQuotaInformation = 37, /// /// Returns an opaque SYSTEM_LOOKASIDE_INFORMATION structure that can be used to generate an unpredictable seed for a random /// number generator. Use the CryptGenRandom function instead. /// [Obsolete("Use the CryptGenRandom function instead.")] SystemLookasideInformation = 45, /// /// Returns policy information in a SYSTEM_POLICY_INFORMATION structure. Use the SLGetWindowsInformation function instead to /// obtain policy information. /// [Obsolete("Use the SLGetWindowsInformation function instead.")] SystemPolicyInformation = 134, } /// /// /// The DbgPrompt routine displays a caller-specified user prompt string on the kernel debugger's display device and obtains /// a user response string. /// /// /// /// /// A pointer to a NULL-terminated constant character string that the debugger will display as a user prompt. The maximum size of /// this string is 512 characters. /// /// /// /// /// A pointer to a character array buffer that receives the user's response, including a terminating newline character. The maximum /// size of this buffer is 512 characters. /// /// /// /// TBD /// /// /// /// DbgPrompt returns the number of characters that the Response buffer received, including the terminating newline /// character. DbgPrompt returns zero if it receives no characters. /// /// /// /// /// The DbgPrompt routine displays the specified prompt string on the kernel debugger's display device and then reads a line /// of user input text. /// /// /// After DbgPrompt returns, the Response buffer contains the user's response, including the terminating newline character. /// The user response string is not NULL-terminated. /// /// /// The following code example asks if the user wants to continue and accepts the letter "y" for yes and the letter "n" for no. /// /// // https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/ntddk/nf-ntddk-dbgprompt NTSYSAPI ULONG DbgPrompt( PCCH // Prompt, PCH Response, ULONG Length ); [DllImport(Lib.NtDll, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Ansi)] [PInvokeData("ntddk.h", MSDNShortId = "4bb44aab-7032-4cc7-89e3-6ac3bee233d3")] public static extern uint DbgPrompt(string Prompt, StringBuilder Response, uint Length); /// /// /// [Some information relates to pre-released product which may be substantially modified before it's commercially released. /// Microsoft makes no warranties, express or implied, with respect to the information provided here.] /// /// /// This function forcefully terminates the calling program if it is invoked inside a loader callout. Otherwise, it has no effect. /// /// /// /// This function does not return a value. /// /// /// /// This routine does not catch all potential deadlock cases; it is possible for a thread inside a loader callout to acquire a lock /// while some thread outside a loader callout holds the same lock and makes a call into the loader. In other words, there can be a /// lock order inversion between the loader lock and a client lock. /// /// // https://docs.microsoft.com/en-us/windows/desktop/DevNotes/ldrfastfailinloadercallout VOID NTAPI LdrFastFailInLoaderCallout(void); [DllImport(Lib.NtDll, SetLastError = false, ExactSpelling = true)] [PInvokeData("ntldr.h", MSDNShortId = "5C10BF04-B7C7-4481-A184-FDD418FE5F52")] public static extern void LdrFastFailInLoaderCallout(); /// /// [This function may be changed or removed from Windows without further notice.] /// Registers for notification when a DLL is first loaded. This notification occurs before dynamic linking takes place. /// /// This parameter must be zero. /// /// A pointer to an LdrDllNotification notification callback function to call when the DLL is loaded. /// /// A pointer to context data for the callback function. /// /// A pointer to a variable to receive an identifier for the callback function. This identifier is used to unregister the /// notification callback function. /// /// /// If the function succeeds, it returns STATUS_SUCCESS. /// /// The forms and significance of NTSTATUS error codes are listed in the Ntstatus.h header file available in the WDK, and are /// described in the WDK documentation. /// /// /// /// This function has no associated header file. The associated import library, Ntdll.lib, is available in the WDK. You can also use /// the LoadLibrary and GetProcAddress functions to dynamically link to Ntdll.dll. /// // https://docs.microsoft.com/en-us/windows/desktop/devnotes/ldrregisterdllnotification NTSTATUS NTAPI LdrRegisterDllNotification( // _In_ ULONG Flags, _In_ PLDR_DLL_NOTIFICATION_FUNCTION NotificationFunction, _In_opt_ PVOID Context, _Out_ PVOID *Cookie ); [DllImport(Lib.NtDll, SetLastError = false, ExactSpelling = true)] [PInvokeData("", MSDNShortId = "c2757aa0-76fa-427a-a4f6-cb26e7f7d0d1")] public static extern NTStatus LdrRegisterDllNotification([Optional] uint Flags, LdrDllNotification NotificationFunction, [Optional] IntPtr Context, out IntPtr Cookie); /// /// [This function may be changed or removed from Windows without further notice.] /// Cancels DLL load notification previously registered by calling the LdrRegisterDllNotification function. /// /// /// Returns an NTSTATUS or error code. /// If the function succeeds, it returns STATUS_SUCCESS. /// If the callback function is not found, the function returns STATUS_DLL_NOT_FOUND. /// /// The forms and significance of NTSTATUS error codes are listed in the Ntstatus.h header file available in the WDK, and are /// described in the WDK documentation. /// /// /// /// /// This function has no associated header file. The associated import library, Ntdll.lib, is available in the WDK. You can also use /// the LoadLibrary and GetProcAddress functions to dynamically link to Ntdll.dll. /// /// // https://docs.microsoft.com/en-us/windows/desktop/DevNotes/ldrunregisterdllnotification NTSTATUS NTAPI // LdrUnregisterDllNotification( _In_ PVOID Cookie ); [DllImport(Lib.NtDll, SetLastError = false, ExactSpelling = true)] [PInvokeData("ntldr.h", MSDNShortId = "18c3a027-e3cb-4083-afdc-00f416a70d8c")] public static extern NTStatus LdrUnregisterDllNotification([In] IntPtr Cookie); /// /// Deprecated. Closes the specified handle. NtClose is superseded by CloseHandle. /// /// /// The handle being closed. /// /// /// The various NTSTATUS values are defined in NTSTATUS.H, which is distributed with the Windows DDK. /// /// /// Return code /// Description /// /// /// STATUS_SUCCESS /// The handle was closed. /// /// /// /// /// The NtClose function closes handles to the following objects. /// /// /// Access token /// /// /// Communications device /// /// /// Console input /// /// /// Console screen buffer /// /// /// Event /// /// /// File /// /// /// File mapping /// /// /// Job /// /// /// Mailslot /// /// /// Mutex /// /// /// Named pipe /// /// /// Process /// /// /// Semaphore /// /// /// Socket /// /// /// Thread /// /// /// Because there is no import library for this function, you must use GetProcAddress. /// // https://docs.microsoft.com/en-us/windows/desktop/api/winternl/nf-winternl-ntclose __kernel_entry NTSTATUS NtClose( IN HANDLE // Handle ); [DllImport(Lib.NtDll, SetLastError = false, ExactSpelling = true)] [PInvokeData("winternl.h")] [Obsolete] public static extern NTStatus NtClose(IntPtr Handle); /// /// /// The NtCompareTokens function compares two access tokens and determines whether they are equivalent with respect to a call /// to the AccessCheck function. /// /// /// /// If the function succeeds, the function returns STATUS_SUCCESS. /// If the function fails, it returns an NTSTATUS error code. /// /// /// Two access control tokens are considered to be equivalent if all of the following conditions are true: /// /// /// Every security identifier (SID) that is present in either token is also present in the other token. /// /// /// Neither or both of the tokens are restricted. /// /// /// If both tokens are restricted, every SID that is restricted in one token is also restricted in the other token. /// /// /// Every privilege present in either token is also present in the other token. /// /// /// /// This function has no associated import library or header file; you must call it using the LoadLibrary and /// GetProcAddress functions. /// /// // https://docs.microsoft.com/en-us/windows/desktop/SecAuthZ/ntcomparetokens NTSTATUS NTAPI NtCompareTokens( _In_ HANDLE // FirstTokenHandle, _In_ HANDLE SecondTokenHandle, _Out_ PBOOLEAN Equal ); [DllImport(Lib.NtDll, SetLastError = false, ExactSpelling = true)] [PInvokeData("Ntseapi.h", MSDNShortId = "3a07ddc6-9748-4f96-a597-2af6b4282e56")] public static extern NTStatus NtCompareTokens([In] IntPtr FirstTokenHandle, [In] IntPtr SecondTokenHandle, [MarshalAs(UnmanagedType.U1)] out bool Equal); /// /// /// [ NtQuerySystemInformation may be altered or unavailable in future versions of Windows. Applications should use the /// alternate functions listed in this topic.] /// /// Retrieves the specified system information. /// /// /// /// One of the values enumerated in SYSTEM_INFORMATION_CLASS, which indicate the kind of system information to be retrieved. These /// include the following values. /// /// SystemBasicInformation /// /// Returns the number of processors in the system in a SYSTEM_BASIC_INFORMATION structure. Use the GetSystemInfo function instead. /// /// SystemCodeIntegrityInformation /// /// Returns a SYSTEM_CODEINTEGRITY_INFORMATION structure that can be used to determine the options being enforced by Code /// Integrity on the system. /// /// SystemExceptionInformation /// /// Returns an opaque SYSTEM_EXCEPTION_INFORMATION structure that can be used to generate an unpredictable seed for a random /// number generator. Use the CryptGenRandom function instead. /// /// SystemInterruptInformation /// /// Returns an opaque SYSTEM_INTERRUPT_INFORMATION structure that can be used to generate an unpredictable seed for a random /// number generator. Use the CryptGenRandom function instead. /// /// SystemKernelVaShadowInformation /// /// Returns a SYSTEM_KERNEL_VA_SHADOW_INFORMATION structure that can be used to determine the speculation control settings /// for attacks involving rogue data cache loads (such as CVE-2017-5754). /// /// SystemLeapSecondInformation /// /// Returns an opaque SYSTEM_LEAP_SECOND_INFORMATION structure that can be used to enable or disable leap seconds /// system-wide. This setting will persist even after a reboot of the system. /// /// SystemLookasideInformation /// /// Returns an opaque SYSTEM_LOOKASIDE_INFORMATION structure that can be used to generate an unpredictable seed for a random /// number generator. Use the CryptGenRandom function instead. /// /// SystemPerformanceInformation /// /// Returns an opaque SYSTEM_PERFORMANCE_INFORMATION structure that can be used to generate an unpredictable seed for a /// random number generator. Use the CryptGenRandomfunction instead. /// /// SystemPolicyInformation /// /// Returns policy information in a SYSTEM_POLICY_INFORMATION structure. Use the SLGetWindowsInformation function instead to /// obtain policy information. /// /// SystemProcessInformation /// Returns an array of SYSTEM_PROCESS_INFORMATION structures, one for each process running in the system. /// /// These structures contain information about the resource usage of each process, including the number of threads and handles used /// by the process, the peak page-file usage, and the number of memory pages that the process has allocated. /// /// SystemProcessorPerformanceInformation /// /// Returns an array of SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION structures, one for each processor installed in the system. /// /// SystemQueryPerformanceCounterInformation /// /// Returns a SYSTEM_QUERY_PERFORMANCE_COUNTER_INFORMATION structure that can be used to determine whether the system /// requires a kernel transition to retrieve the high-resolution performance counter information through a QueryPerformanceCounter /// function call. /// /// SystemRegistryQuotaInformation /// Returns a SYSTEM_REGISTRY_QUOTA_INFORMATION structure. /// SystemSpeculationControlInformation /// /// Returns a SYSTEM_SPECULATION_CONTROL_INFORMATION structure that can be used to determine the speculation control settings /// for attacks involving branch target injection (such as CVE-2017-5715). /// /// SystemTimeOfDayInformation /// /// Returns an opaque SYSTEM_TIMEOFDAY_INFORMATION structure that can be used to generate an unpredictable seed for a random /// number generator. Use the CryptGenRandom function instead. /// /// /// /// /// A pointer to a buffer that receives the requested information. The size and structure of this information varies depending on /// the value of the SystemInformationClass parameter: /// /// SYSTEM_BASIC_INFORMATION /// /// When the SystemInformationClass parameter is SystemBasicInformation, the buffer pointed to by the SystemInformation /// parameter should be large enough to hold a single SYSTEM_BASIC_INFORMATION structure having the following layout: /// /// ///typedef struct _SYSTEM_BASIC_INFORMATION { ///BYTE Reserved1[24]; ///PVOID Reserved2[4]; ///CCHAR NumberOfProcessors; ///} SYSTEM_BASIC_INFORMATION;" /// /// /// The NumberOfProcessors member contains the number of processors present in the system. Use GetSystemInfo instead to /// retrieve this information. /// /// The other members of the structure are reserved for internal use by the operating system. /// SYSTEM_CODEINTEGRITY_INFORMATION /// /// When the SystemInformationClass parameter is SystemCodeIntegrityInformation, the buffer pointed to by the /// SystemInformation parameter should be large enough to hold a single SYSTEM_CODEINTEGRITY_INFORMATION structure having the /// following layout: /// /// ///typedef struct _SYSTEM_CODEINTEGRITY_INFORMATION { ///ULONG Length; ///ULONG CodeIntegrityOptions; ///} SYSTEM_CODEINTEGRITY_INFORMATION, *PSYSTEM_CODEINTEGRITY_INFORMATION;" /// /// The Length member contains the size of the structure in bytes. This must be set by the caller. /// The CodeIntegrityOptions member contains a bitmask to identify code integrity options. /// /// /// Value /// /// Meaning /// /// /// 0x01 /// CODEINTEGRITY_OPTION_ENABLED /// Enforcement of kernel mode Code Integrity is enabled. /// /// /// 0x02 /// CODEINTEGRITY_OPTION_TESTSIGN /// Test signed content is allowed by Code Integrity. /// /// /// 0x04 /// CODEINTEGRITY_OPTION_UMCI_ENABLED /// Enforcement of user mode Code Integrity is enabled. /// /// /// 0x08 /// CODEINTEGRITY_OPTION_UMCI_AUDITMODE_ENABLED /// /// Enforcement of user mode Code Integrity is enabled in audit mode. Executables will be allowed to run/load; however, audit events /// will be recorded. /// /// /// /// 0x10 /// CODEINTEGRITY_OPTION_UMCI_EXCLUSIONPATHS_ENABLED /// /// User mode binaries being run from certain paths are allowed to run even if they fail code integrity checks. Exclusion paths are /// listed in the following registry key in REG_MULTI_SZ format: Paths added to this key should be in one of two formats: The /// following paths are restricted and cannot be added as an exclusion: Built-in Path Exclusions: The following paths are excluded /// by default. You don't need to specifically add these to path exclusions. This only applies on ARM (Windows Runtime). /// /// /// /// 0x20 /// CODEINTEGRITY_OPTION_TEST_BUILD /// The build of Code Integrity is from a test build. /// /// /// 0x40 /// CODEINTEGRITY_OPTION_PREPRODUCTION_BUILD /// The build of Code Integrity is from a pre-production build. /// /// /// 0x80 /// CODEINTEGRITY_OPTION_DEBUGMODE_ENABLED /// The kernel debugger is attached and Code Integrity may allow unsigned code to load. /// /// /// 0x100 /// CODEINTEGRITY_OPTION_FLIGHT_BUILD /// The build of Code Integrity is from a flight build. /// /// /// 0x200 /// CODEINTEGRITY_OPTION_FLIGHTING_ENABLED /// /// Flight signed content is allowed by Code Integrity. Flight signed content is content signed by the Microsoft Development Root /// Certificate Authority 2014. /// /// /// /// 0x400 /// CODEINTEGRITY_OPTION_HVCI_KMCI_ENABLED /// Hypervisor enforced Code Integrity is enabled for kernel mode components. /// /// /// 0x800 /// CODEINTEGRITY_OPTION_HVCI_KMCI_AUDITMODE_ENABLED /// /// Hypervisor enforced Code Integrity is enabled in audit mode. Audit events will be recorded for kernel mode components that are /// not compatible with HVCI. This bit can be set whether CODEINTEGRITY_OPTION_HVCI_KMCI_ENABLED is set or not. /// /// /// /// 0x1000 /// CODEINTEGRITY_OPTION_HVCI_KMCI_STRICTMODE_ENABLED /// Hypervisor enforced Code Integrity is enabled for kernel mode components, but in strict mode. /// /// /// 0x2000 /// CODEINTEGRITY_OPTION_HVCI_IUM_ENABLED /// Hypervisor enforced Code Integrity is enabled with enforcement of Isolated User Mode component signing. /// /// /// SYSTEM_EXCEPTION_INFORMATION /// /// When the SystemInformationClass parameter is SystemExceptionInformation, the buffer pointed to by the SystemInformation /// parameter should be large enough to hold an opaque SYSTEM_EXCEPTION_INFORMATION structure for use in generating an /// unpredictable seed for a random number generator. For this purpose, the structure has the following layout: /// /// ///typedef struct _SYSTEM_EXCEPTION_INFORMATION { ///BYTE Reserved1[16]; ///} SYSTEM_EXCEPTION_INFORMATION; /// /// Individual members of the structure are reserved for internal use by the operating system. /// Use the CryptGenRandom function instead to generate cryptographically random data. /// SYSTEM_INTERRUPT_INFORMATION /// /// When the SystemInformationClass parameter is SystemInterruptInformation, the buffer pointed to by the SystemInformation /// parameter should be large enough to hold an array that contains as many opaque SYSTEM_INTERRUPT_INFORMATION structures as /// there are processors (CPUs) installed on the system. Each structure, or the array as a whole, can be used to generate an /// unpredictable seed for a random number generator. For this purpose, the structure has the following layout: /// /// ///typedef struct _SYSTEM_INTERRUPT_INFORMATION { ///BYTE Reserved1[24]; ///} SYSTEM_INTERRUPT_INFORMATION; /// /// Individual members of the structure are reserved for internal use by the operating system. /// Use the CryptGenRandom function instead to generate cryptographically random data. /// SYSTEM_KERNEL_VA_SHADOW_INFORMATION /// /// When the SystemInformationClass parameter is SystemKernelVaShadowInformation, the buffer pointed to by the /// SystemInformation parameter should be large enough to hold a single SYSTEM_KERNEL_VA_SHADOW_INFORMATION structure having /// the following layout: /// /// ///typedef struct _SYSTEM_KERNEL_VA_SHADOW_INFORMATION { ///struct { ///ULONG KvaShadowEnabled:1; ///ULONG KvaShadowUserGlobal:1; ///ULONG KvaShadowPcid:1; ///ULONG KvaShadowInvpcid:1; ///ULONG Reserved:28; ///} KvaShadowFlags; ///} SYSTEM_KERNEL_VA_SHADOW_INFORMATION, * PSYSTEM_KERNEL_VA_SHADOW_INFORMATION; /// /// The KvaShadowEnabled indicates whether shadowing is enabled. /// The KvaShadowUserGlobal indicates that user/global is enabled. /// The KvaShadowPcid indicates whether PCID is enabled. /// The KvaShadowInvpcid indicates whether PCID is enabled and whether INVPCID is in use. /// The Reserved member of the structure is reserved for internal use by the operating system. /// SYSTEM_LEAP_SECOND_INFORMATION /// /// When the SystemInformationClass parameter is SystemLeapSecondInformation, the buffer pointed to by the SystemInformation /// parameter should be large enough to hold an opaque SYSTEM_LEAP_SECOND_INFORMATION structure for use in enabling or /// disabling leap seconds system-wide. This setting will persist even after a reboot of the system. For this purpose, the structure /// has the following layout: /// /// ///typedef struct _SYSTEM_LEAP_SECOND_INFORMATION { ///BOOLEAN Enabled; ///ULONG Flags; ///} SYSTEM_LEAP_SECOND_INFORMATION /// /// The Flags field is reserved for future use. /// SYSTEM_LOOKASIDE_INFORMATION /// /// When the SystemInformationClass parameter is SystemLookasideInformation, the buffer pointed to by the SystemInformation /// parameter should be large enough to hold an opaque SYSTEM_LOOKASIDE_INFORMATION structure for use in generating an /// unpredictable seed for a random number generator. For this purpose, the structure has the following layout: /// /// ///typedef struct _SYSTEM_LOOKASIDE_INFORMATION { ///BYTE Reserved1[32]; ///} SYSTEM_LOOKASIDE_INFORMATION; /// /// Individual members of the structure are reserved for internal use by the operating system. /// Use the CryptGenRandom function instead to generate cryptographically random data. /// SYSTEM_PERFORMANCE_INFORMATION /// /// When the SystemInformationClass parameter is SystemPerformanceInformation, the buffer pointed to by the SystemInformation /// parameter should be large enough to hold an opaque SYSTEM_PERFORMANCE_INFORMATION structure for use in generating an /// unpredictable seed for a random number generator. For this purpose, the structure has the following layout: /// /// ///typedef struct _SYSTEM_PERFORMANCE_INFORMATION { ///BYTE Reserved1[312]; ///} SYSTEM_PERFORMANCE_INFORMATION; /// /// Individual members of the structure are reserved for internal use by the operating system. /// Use the CryptGenRandom function instead to generate cryptographically random data. /// SYSTEM_POLICY_INFORMATION /// /// When the SystemInformationClass parameter is SystemPolicyInformation, the buffer pointed to by the SystemInformation /// parameter should be large enough to hold a single SYSTEM_POLICY_INFORMATION structure having the following layout: /// /// ///typedef struct _SYSTEM_POLICY_INFORMATION { ///PVOID Reserved1[2]; ///ULONG Reserved2[3]; ///} SYSTEM_POLICY_INFORMATION; /// /// Individual members of the structure are reserved for internal use by the operating system. /// Use the SLGetWindowsInformation function instead to obtain policy information. /// SYSTEM_PROCESS_INFORMATION /// /// When the SystemInformationClass parameter is SystemProcessInformation, the buffer pointed to by the SystemInformation /// parameter contains a SYSTEM_PROCESS_INFORMATION structure for each process. Each of these structures is immediately /// followed in memory by one or more SYSTEM_THREAD_INFORMATION structures that provide info for each thread in the preceding /// process. For more information about SYSTEM_THREAD_INFORMATION, see the section about this structure in this article. /// /// /// The buffer pointed to by the SystemInformation parameter should be large enough to hold an array that contains as many /// SYSTEM_PROCESS_INFORMATION and SYSTEM_THREAD_INFORMATION structures as there are processes and threads running in /// the system. This size is specified by the ReturnLength parameter. /// /// Each SYSTEM_PROCESS_INFORMATION structure has the following layout: /// ///typedef struct _SYSTEM_PROCESS_INFORMATION { ///ULONG NextEntryOffset; ///ULONG NumberOfThreads; ///BYTE Reserved1[48]; ///UNICODE_STRING ImageName; ///KPRIORITY BasePriority; ///HANDLE UniqueProcessId; ///PVOID Reserved2; ///ULONG HandleCount; ///ULONG SessionId; ///PVOID Reserved3; ///SIZE_T PeakVirtualSize; ///SIZE_T VirtualSize; ///ULONG Reserved4; ///SIZE_T PeakWorkingSetSize; ///SIZE_T WorkingSetSize; ///PVOID Reserved5; ///SIZE_T QuotaPagedPoolUsage; ///PVOID Reserved6; ///SIZE_T QuotaNonPagedPoolUsage; ///SIZE_T PagefileUsage; ///SIZE_T PeakPagefileUsage; ///SIZE_T PrivatePageCount; ///LARGE_INTEGER Reserved7[6]; ///} SYSTEM_PROCESS_INFORMATION; /// /// /// The start of the next item in the array is the address of the previous item plus the value in the NextEntryOffset member. /// For the last item in the array, NextEntryOffset is 0. /// /// The NumberOfThreads member contains the number of threads in the process. /// The ImageName member contains the process's image name. /// /// The BasePriority member contains the base priority of the process, which is the starting priority for threads created /// within the associated process. /// /// The UniqueProcessId member contains the process's unique process ID. /// /// The HandleCount member contains the total number of handles being used by the process in question; use /// GetProcessHandleCount to retrieve this information instead. /// /// The SessionId member contains the session identifier of the process session. /// The PeakVirtualSize member contains the peak size, in bytes, of the virtual memory used by the process. /// The VirtualSize member contains the current size, in bytes, of virtual memory used by the process. /// The PeakWorkingSetSize member contains the peak size, in kilobytes, of the working set of the process. /// The QuotaPagedPoolUsage member contains the current quota charged to the process for paged pool usage. /// The QuotaNonPagedPoolUsage member contains the current quota charged to the process for nonpaged pool usage. /// The PagefileUsage member contains the number of bytes of page file storage in use by the process. /// The PeakPagefileUsage member contains the maximum number of bytes of page-file storage used by the process. /// The PrivatePageCount member contains the number of memory pages allocated for the use of this process. /// /// You can also retrieve the PeakWorkingSetSize, QuotaPagedPoolUsage, QuotaNonPagedPoolUsage, /// PagefileUsage, PeakPagefileUsage, and PrivatePageCount information using either the GetProcessMemoryInfo /// function or the Win32_Process class. /// /// The other members of the structure are reserved for internal use by the operating system. /// SYSTEM_THREAD_INFORMATION /// /// When the SystemInformationClass parameter is SystemProcessInformation, the buffer pointed to by the SystemInformation /// parameter contains a SYSTEM_PROCESS_INFORMATION structure for each process. Each of these structures is immediately /// followed in memory by one or more SYSTEM_THREAD_INFORMATION structures that provide info for each thread in the preceding /// process. For more information about SYSTEM_PROCESS_INFORMATION, see the section about this structure in this article. /// Each SYSTEM_THREAD_INFORMATION structure has the following layout: /// /// ///typedef struct _SYSTEM_THREAD_INFORMATION { ///LARGE_INTEGER Reserved1[3]; ///ULONG Reserved2; ///PVOID StartAddress; ///CLIENT_ID ClientId; ///KPRIORITY Priority; ///LONG BasePriority; ///ULONG Reserved3; ///ULONG ThreadState; ///ULONG WaitReason; ///} SYSTEM_THREAD_INFORMATION; /// /// The StartAddress member contains the start address of the thread. /// The ClientId member contains the ID of the thread and the process owning the thread. /// The Priority member contains the dynamic thread priority. /// The BasePriority member contains the base thread priority. /// The ThreadState member contains the current thread state. /// The WaitReason member contains the reason the thread is waiting. /// The other members of the structure are reserved for internal use by the operating system. /// SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION /// /// When the SystemInformationClass parameter is SystemProcessorPerformanceInformation, the buffer pointed to by the /// SystemInformation parameter should be large enough to hold an array that contains as many /// SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION structures as there are processors (CPUs) installed in the system. Each /// structure has the following layout: /// /// ///typedef struct ///_SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION { ///LARGE_INTEGER IdleTime; ///LARGE_INTEGER KernelTime; ///LARGE_INTEGER UserTime; ///LARGE_INTEGER Reserved1[2]; ///ULONG Reserved2; ///} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION; /// /// The IdleTime member contains the amount of time that the system has been idle, in 100-nanosecond intervals. /// /// The KernelTime member contains the amount of time that the system has spent executing in Kernel mode (including all /// threads in all processes, on all processors), in 100-nanosecond intervals. /// /// /// The UserTime member contains the amount of time that the system has spent executing in User mode (including all threads /// in all processes, on all processors), in 100-nanosecond intervals. /// /// Use GetSystemTimesinstead to retrieve this information. /// SYSTEM_QUERY_PERFORMANCE_COUNTER_INFORMATION /// /// When the SystemInformationClass parameter is SystemQueryPerformanceCounterInformation, the buffer pointed to by the /// SystemInformation parameter should be large enough to hold a single SYSTEM_QUERY_PERFORMANCE_COUNTER_INFORMATION /// structure having the following layout: /// /// ///typedef struct _SYSTEM_QUERY_PERFORMANCE_COUNTER_INFORMATION { ///ULONG Version; ///QUERY_PERFORMANCE_COUNTER_FLAGS Flags; ///QUERY_PERFORMANCE_COUNTER_FLAGS ValidFlags; ///} SYSTEM_QUERY_PERFORMANCE_COUNTER_INFORMATION; /// /// /// The Flags and ValidFlags members are QUERY_PERFORMANCE_COUNTER_FLAGS structures having the following layout: /// /// ///typedef struct _QUERY_PERFORMANCE_COUNTER_FLAGS { ///union { ///struct { ///ULONG KernelTransition:1; ///ULONG Reserved:31; ///}; ///ULONG ul; ///}; ///} QUERY_PERFORMANCE_COUNTER_FLAGS; /// /// /// The ValidFlags member of the SYSTEM_QUERY_PERFORMANCE_COUNTER_INFORMATION structure indicates which bits of the /// Flags member contain valid information. If a kernel transition is required, the KernelTransition bit is set in /// both ValidFlags and Flags. If a kernel transition is not required, the KernelTransition bit is set in /// ValidFlags and clear in Flags. /// /// SYSTEM_REGISTRY_QUOTA_INFORMATION /// /// When the SystemInformationClass parameter is SystemRegistryQuotaInformation, the buffer pointed to by the /// SystemInformation parameter should be large enough to hold a single SYSTEM_REGISTRY_QUOTA_INFORMATION structure having /// the following layout: /// /// ///typedef struct _SYSTEM_REGISTRY_QUOTA_INFORMATION { ///ULONG RegistryQuotaAllowed; ///ULONG RegistryQuotaUsed; ///PVOID Reserved1; ///} SYSTEM_REGISTRY_QUOTA_INFORMATION; /// /// The RegistryQuotaAllowed member contains the maximum size, in bytes, that the Registry can attain on this system. /// The RegistryQuotaUsed member contains the current size of the Registry, in bytes. /// Use GetSystemRegistryQuota instead to retrieve this information. /// The other member of the structure is reserved for internal use by the operating system. /// SYSTEM_SPECULATION_CONTROL_INFORMATION /// /// When the SystemInformationClass parameter is SystemSpeculationControlInformation, the buffer pointed to by the /// SystemInformation parameter should be large enough to hold a single SYSTEM_SPECULATION_CONTROL_INFORMATION structure /// having the following layout: /// /// ///typedef struct _SYSTEM_SPECULATION_CONTROL_INFORMATION { ///struct { ///ULONG BpbEnabled:1; ///ULONG BpbDisabledSystemPolicy:1; ///ULONG BpbDisabledNoHardwareSupport:1; ///ULONG SpecCtrlEnumerated:1; ///ULONG SpecCmdEnumerated:1; ///ULONG IbrsPresent:1; ///ULONG StibpPresent:1; ///ULONG SmepPresent:1; ///ULONG Reserved:24; ///} SpeculationControlFlags; /// ///} SYSTEM_SPECULATION_CONTROL_INFORMATION, * PSYSTEM_SPECULATION_CONTROL_INFORMATION; /// /// The BpbEnabled indicates whether speculation control features are supported and enabled. /// The BpbDisabledSystemPolicy indicates whether speculation control features are disabled due to system policy. /// /// The BpbDisabledNoHardwareSupport whether speculation control features are disabled due to the absence of hardware support. /// /// The SpecCtrlEnumerated whether the IA32_SPEC_CTRL MSR is enumerated by hardware. /// The SpecCmdEnumerated indicates whether the IA32_SPEC_CMD MSR is enumerated by hardware. /// The IbrsPresent indicates whether the IBRS MSR is treated as being present. /// The StibpPresent indicates whether the STIBP MSR is present. /// The SmepPresent indicates whether the SMEP feature is present and enabled. /// The Reserved member of the structure is reserved for internal use by the operating system. /// SYSTEM_TIMEOFDAY_INFORMATION /// /// When the SystemInformationClass parameter is SystemTimeOfDayInformation, the buffer pointed to by the SystemInformation /// parameter should be large enough to hold an opaque SYSTEM_TIMEOFDAY_INFORMATION structure for use in generating an /// unpredictable seed for a random number generator. For this purpose, the structure has the following layout: /// /// ///typedef struct _SYSTEM_TIMEOFDAY_INFORMATION { ///BYTE Reserved1[48]; ///} SYSTEM_TIMEOFDAY_INFORMATION; /// /// Individual members of the structure are reserved for internal use by the operating system. /// Use the CryptGenRandom function instead to generate cryptographically random data. /// /// /// The size of the buffer pointed to by the SystemInformationparameter, in bytes. /// /// /// /// Returns an NTSTATUS success or error code. /// /// The forms and significance of NTSTATUS error codes are listed in the Ntstatus.h header file available in the DDK, and are /// described in the DDK documentation. /// /// /// /// /// The NtQuerySystemInformation function and the structures that it returns are internal to the operating system and subject /// to change from one release of Windows to another. To maintain the compatibility of your application, it is better to use the /// alternate functions previously mentioned instead. /// /// /// If you do use NtQuerySystemInformation, access the function through run-time dynamic linking. This gives your code an /// opportunity to respond gracefully if the function has been changed or removed from the operating system. Signature changes, /// however, may not be detectable. /// /// /// This function has no associated import library. You must use the LoadLibrary and GetProcAddress functions to dynamically link to Ntdll.dll. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winternl/nf-winternl-ntquerysysteminformation __kernel_entry NTSTATUS // NtQuerySystemInformation( IN SYSTEM_INFORMATION_CLASS SystemInformationClass, OUT PVOID SystemInformation, IN ULONG // SystemInformationLength, OUT PULONG ReturnLength OPTIONAL ); [DllImport(Lib.NtDll, SetLastError = false, ExactSpelling = true)] [PInvokeData("winternl.h", MSDNShortId = "553ec7b9-c5eb-4955-8dc0-f1c06f59fe31")] public static extern NTStatus NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, SafeHGlobalHandle SystemInformation, uint SystemInformationLength, out uint ReturnLength); /// /// /// [ NtQuerySystemInformation may be altered or unavailable in future versions of Windows. Applications should use the /// alternate functions listed in this topic.] /// /// Retrieves the specified system information. /// /// The type of the return value. /// /// /// One of the values enumerated in SYSTEM_INFORMATION_CLASS, which indicate the kind of system information to be retrieved. These /// include the following values. /// /// SystemBasicInformation /// /// Returns the number of processors in the system in a SYSTEM_BASIC_INFORMATION structure. Use the GetSystemInfo function instead. /// /// SystemCodeIntegrityInformation /// /// Returns a SYSTEM_CODEINTEGRITY_INFORMATION structure that can be used to determine the options being enforced by Code /// Integrity on the system. /// /// SystemExceptionInformation /// /// Returns an opaque SYSTEM_EXCEPTION_INFORMATION structure that can be used to generate an unpredictable seed for a random /// number generator. Use the CryptGenRandom function instead. /// /// SystemInterruptInformation /// /// Returns an opaque SYSTEM_INTERRUPT_INFORMATION structure that can be used to generate an unpredictable seed for a random /// number generator. Use the CryptGenRandom function instead. /// /// SystemKernelVaShadowInformation /// /// Returns a SYSTEM_KERNEL_VA_SHADOW_INFORMATION structure that can be used to determine the speculation control settings /// for attacks involving rogue data cache loads (such as CVE-2017-5754). /// /// SystemLeapSecondInformation /// /// Returns an opaque SYSTEM_LEAP_SECOND_INFORMATION structure that can be used to enable or disable leap seconds /// system-wide. This setting will persist even after a reboot of the system. /// /// SystemLookasideInformation /// /// Returns an opaque SYSTEM_LOOKASIDE_INFORMATION structure that can be used to generate an unpredictable seed for a random /// number generator. Use the CryptGenRandom function instead. /// /// SystemPerformanceInformation /// /// Returns an opaque SYSTEM_PERFORMANCE_INFORMATION structure that can be used to generate an unpredictable seed for a /// random number generator. Use the CryptGenRandomfunction instead. /// /// SystemPolicyInformation /// /// Returns policy information in a SYSTEM_POLICY_INFORMATION structure. Use the SLGetWindowsInformation function instead to /// obtain policy information. /// /// SystemProcessInformation /// Returns an array of SYSTEM_PROCESS_INFORMATION structures, one for each process running in the system. /// /// These structures contain information about the resource usage of each process, including the number of threads and handles used /// by the process, the peak page-file usage, and the number of memory pages that the process has allocated. /// /// SystemProcessorPerformanceInformation /// /// Returns an array of SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION structures, one for each processor installed in the system. /// /// SystemQueryPerformanceCounterInformation /// /// Returns a SYSTEM_QUERY_PERFORMANCE_COUNTER_INFORMATION structure that can be used to determine whether the system /// requires a kernel transition to retrieve the high-resolution performance counter information through a QueryPerformanceCounter /// function call. /// /// SystemRegistryQuotaInformation /// Returns a SYSTEM_REGISTRY_QUOTA_INFORMATION structure. /// SystemSpeculationControlInformation /// /// Returns a SYSTEM_SPECULATION_CONTROL_INFORMATION structure that can be used to determine the speculation control settings /// for attacks involving branch target injection (such as CVE-2017-5715). /// /// SystemTimeOfDayInformation /// /// Returns an opaque SYSTEM_TIMEOFDAY_INFORMATION structure that can be used to generate an unpredictable seed for a random /// number generator. Use the CryptGenRandom function instead. /// /// /// /// /// A pointer to a buffer that receives the requested information. The size and structure of this information varies depending on /// the value of the SystemInformationClass parameter: /// /// SYSTEM_BASIC_INFORMATION /// /// When the SystemInformationClass parameter is SystemBasicInformation, the buffer pointed to by the SystemInformation /// parameter should be large enough to hold a single SYSTEM_BASIC_INFORMATION structure having the following layout: /// /// ///typedef struct _SYSTEM_BASIC_INFORMATION { ///BYTE Reserved1[24]; ///PVOID Reserved2[4]; ///CCHAR NumberOfProcessors; ///} SYSTEM_BASIC_INFORMATION;" /// /// /// The NumberOfProcessors member contains the number of processors present in the system. Use GetSystemInfo instead to /// retrieve this information. /// /// The other members of the structure are reserved for internal use by the operating system. /// SYSTEM_CODEINTEGRITY_INFORMATION /// /// When the SystemInformationClass parameter is SystemCodeIntegrityInformation, the buffer pointed to by the /// SystemInformation parameter should be large enough to hold a single SYSTEM_CODEINTEGRITY_INFORMATION structure having the /// following layout: /// /// ///typedef struct _SYSTEM_CODEINTEGRITY_INFORMATION { ///ULONG Length; ///ULONG CodeIntegrityOptions; ///} SYSTEM_CODEINTEGRITY_INFORMATION, *PSYSTEM_CODEINTEGRITY_INFORMATION;" /// /// The Length member contains the size of the structure in bytes. This must be set by the caller. /// The CodeIntegrityOptions member contains a bitmask to identify code integrity options. /// /// /// Value /// /// Meaning /// /// /// 0x01 /// CODEINTEGRITY_OPTION_ENABLED /// Enforcement of kernel mode Code Integrity is enabled. /// /// /// 0x02 /// CODEINTEGRITY_OPTION_TESTSIGN /// Test signed content is allowed by Code Integrity. /// /// /// 0x04 /// CODEINTEGRITY_OPTION_UMCI_ENABLED /// Enforcement of user mode Code Integrity is enabled. /// /// /// 0x08 /// CODEINTEGRITY_OPTION_UMCI_AUDITMODE_ENABLED /// /// Enforcement of user mode Code Integrity is enabled in audit mode. Executables will be allowed to run/load; however, audit events /// will be recorded. /// /// /// /// 0x10 /// CODEINTEGRITY_OPTION_UMCI_EXCLUSIONPATHS_ENABLED /// /// User mode binaries being run from certain paths are allowed to run even if they fail code integrity checks. Exclusion paths are /// listed in the following registry key in REG_MULTI_SZ format: Paths added to this key should be in one of two formats: The /// following paths are restricted and cannot be added as an exclusion: Built-in Path Exclusions: The following paths are excluded /// by default. You don't need to specifically add these to path exclusions. This only applies on ARM (Windows Runtime). /// /// /// /// 0x20 /// CODEINTEGRITY_OPTION_TEST_BUILD /// The build of Code Integrity is from a test build. /// /// /// 0x40 /// CODEINTEGRITY_OPTION_PREPRODUCTION_BUILD /// The build of Code Integrity is from a pre-production build. /// /// /// 0x80 /// CODEINTEGRITY_OPTION_DEBUGMODE_ENABLED /// The kernel debugger is attached and Code Integrity may allow unsigned code to load. /// /// /// 0x100 /// CODEINTEGRITY_OPTION_FLIGHT_BUILD /// The build of Code Integrity is from a flight build. /// /// /// 0x200 /// CODEINTEGRITY_OPTION_FLIGHTING_ENABLED /// /// Flight signed content is allowed by Code Integrity. Flight signed content is content signed by the Microsoft Development Root /// Certificate Authority 2014. /// /// /// /// 0x400 /// CODEINTEGRITY_OPTION_HVCI_KMCI_ENABLED /// Hypervisor enforced Code Integrity is enabled for kernel mode components. /// /// /// 0x800 /// CODEINTEGRITY_OPTION_HVCI_KMCI_AUDITMODE_ENABLED /// /// Hypervisor enforced Code Integrity is enabled in audit mode. Audit events will be recorded for kernel mode components that are /// not compatible with HVCI. This bit can be set whether CODEINTEGRITY_OPTION_HVCI_KMCI_ENABLED is set or not. /// /// /// /// 0x1000 /// CODEINTEGRITY_OPTION_HVCI_KMCI_STRICTMODE_ENABLED /// Hypervisor enforced Code Integrity is enabled for kernel mode components, but in strict mode. /// /// /// 0x2000 /// CODEINTEGRITY_OPTION_HVCI_IUM_ENABLED /// Hypervisor enforced Code Integrity is enabled with enforcement of Isolated User Mode component signing. /// /// /// SYSTEM_EXCEPTION_INFORMATION /// /// When the SystemInformationClass parameter is SystemExceptionInformation, the buffer pointed to by the SystemInformation /// parameter should be large enough to hold an opaque SYSTEM_EXCEPTION_INFORMATION structure for use in generating an /// unpredictable seed for a random number generator. For this purpose, the structure has the following layout: /// /// ///typedef struct _SYSTEM_EXCEPTION_INFORMATION { ///BYTE Reserved1[16]; ///} SYSTEM_EXCEPTION_INFORMATION; /// /// Individual members of the structure are reserved for internal use by the operating system. /// Use the CryptGenRandom function instead to generate cryptographically random data. /// SYSTEM_INTERRUPT_INFORMATION /// /// When the SystemInformationClass parameter is SystemInterruptInformation, the buffer pointed to by the SystemInformation /// parameter should be large enough to hold an array that contains as many opaque SYSTEM_INTERRUPT_INFORMATION structures as /// there are processors (CPUs) installed on the system. Each structure, or the array as a whole, can be used to generate an /// unpredictable seed for a random number generator. For this purpose, the structure has the following layout: /// /// ///typedef struct _SYSTEM_INTERRUPT_INFORMATION { ///BYTE Reserved1[24]; ///} SYSTEM_INTERRUPT_INFORMATION; /// /// Individual members of the structure are reserved for internal use by the operating system. /// Use the CryptGenRandom function instead to generate cryptographically random data. /// SYSTEM_KERNEL_VA_SHADOW_INFORMATION /// /// When the SystemInformationClass parameter is SystemKernelVaShadowInformation, the buffer pointed to by the /// SystemInformation parameter should be large enough to hold a single SYSTEM_KERNEL_VA_SHADOW_INFORMATION structure having /// the following layout: /// /// ///typedef struct _SYSTEM_KERNEL_VA_SHADOW_INFORMATION { ///struct { ///ULONG KvaShadowEnabled:1; ///ULONG KvaShadowUserGlobal:1; ///ULONG KvaShadowPcid:1; ///ULONG KvaShadowInvpcid:1; ///ULONG Reserved:28; ///} KvaShadowFlags; ///} SYSTEM_KERNEL_VA_SHADOW_INFORMATION, * PSYSTEM_KERNEL_VA_SHADOW_INFORMATION; /// /// The KvaShadowEnabled indicates whether shadowing is enabled. /// The KvaShadowUserGlobal indicates that user/global is enabled. /// The KvaShadowPcid indicates whether PCID is enabled. /// The KvaShadowInvpcid indicates whether PCID is enabled and whether INVPCID is in use. /// The Reserved member of the structure is reserved for internal use by the operating system. /// SYSTEM_LEAP_SECOND_INFORMATION /// /// When the SystemInformationClass parameter is SystemLeapSecondInformation, the buffer pointed to by the SystemInformation /// parameter should be large enough to hold an opaque SYSTEM_LEAP_SECOND_INFORMATION structure for use in enabling or /// disabling leap seconds system-wide. This setting will persist even after a reboot of the system. For this purpose, the structure /// has the following layout: /// /// ///typedef struct _SYSTEM_LEAP_SECOND_INFORMATION { ///BOOLEAN Enabled; ///ULONG Flags; ///} SYSTEM_LEAP_SECOND_INFORMATION /// /// The Flags field is reserved for future use. /// SYSTEM_LOOKASIDE_INFORMATION /// /// When the SystemInformationClass parameter is SystemLookasideInformation, the buffer pointed to by the SystemInformation /// parameter should be large enough to hold an opaque SYSTEM_LOOKASIDE_INFORMATION structure for use in generating an /// unpredictable seed for a random number generator. For this purpose, the structure has the following layout: /// /// ///typedef struct _SYSTEM_LOOKASIDE_INFORMATION { ///BYTE Reserved1[32]; ///} SYSTEM_LOOKASIDE_INFORMATION; /// /// Individual members of the structure are reserved for internal use by the operating system. /// Use the CryptGenRandom function instead to generate cryptographically random data. /// SYSTEM_PERFORMANCE_INFORMATION /// /// When the SystemInformationClass parameter is SystemPerformanceInformation, the buffer pointed to by the SystemInformation /// parameter should be large enough to hold an opaque SYSTEM_PERFORMANCE_INFORMATION structure for use in generating an /// unpredictable seed for a random number generator. For this purpose, the structure has the following layout: /// /// ///typedef struct _SYSTEM_PERFORMANCE_INFORMATION { ///BYTE Reserved1[312]; ///} SYSTEM_PERFORMANCE_INFORMATION; /// /// Individual members of the structure are reserved for internal use by the operating system. /// Use the CryptGenRandom function instead to generate cryptographically random data. /// SYSTEM_POLICY_INFORMATION /// /// When the SystemInformationClass parameter is SystemPolicyInformation, the buffer pointed to by the SystemInformation /// parameter should be large enough to hold a single SYSTEM_POLICY_INFORMATION structure having the following layout: /// /// ///typedef struct _SYSTEM_POLICY_INFORMATION { ///PVOID Reserved1[2]; ///ULONG Reserved2[3]; ///} SYSTEM_POLICY_INFORMATION; /// /// Individual members of the structure are reserved for internal use by the operating system. /// Use the SLGetWindowsInformation function instead to obtain policy information. /// SYSTEM_PROCESS_INFORMATION /// /// When the SystemInformationClass parameter is SystemProcessInformation, the buffer pointed to by the SystemInformation /// parameter contains a SYSTEM_PROCESS_INFORMATION structure for each process. Each of these structures is immediately /// followed in memory by one or more SYSTEM_THREAD_INFORMATION structures that provide info for each thread in the preceding /// process. For more information about SYSTEM_THREAD_INFORMATION, see the section about this structure in this article. /// /// /// The buffer pointed to by the SystemInformation parameter should be large enough to hold an array that contains as many /// SYSTEM_PROCESS_INFORMATION and SYSTEM_THREAD_INFORMATION structures as there are processes and threads running in /// the system. This size is specified by the ReturnLength parameter. /// /// Each SYSTEM_PROCESS_INFORMATION structure has the following layout: /// ///typedef struct _SYSTEM_PROCESS_INFORMATION { ///ULONG NextEntryOffset; ///ULONG NumberOfThreads; ///BYTE Reserved1[48]; ///UNICODE_STRING ImageName; ///KPRIORITY BasePriority; ///HANDLE UniqueProcessId; ///PVOID Reserved2; ///ULONG HandleCount; ///ULONG SessionId; ///PVOID Reserved3; ///SIZE_T PeakVirtualSize; ///SIZE_T VirtualSize; ///ULONG Reserved4; ///SIZE_T PeakWorkingSetSize; ///SIZE_T WorkingSetSize; ///PVOID Reserved5; ///SIZE_T QuotaPagedPoolUsage; ///PVOID Reserved6; ///SIZE_T QuotaNonPagedPoolUsage; ///SIZE_T PagefileUsage; ///SIZE_T PeakPagefileUsage; ///SIZE_T PrivatePageCount; ///LARGE_INTEGER Reserved7[6]; ///} SYSTEM_PROCESS_INFORMATION; /// /// /// The start of the next item in the array is the address of the previous item plus the value in the NextEntryOffset member. /// For the last item in the array, NextEntryOffset is 0. /// /// The NumberOfThreads member contains the number of threads in the process. /// The ImageName member contains the process's image name. /// /// The BasePriority member contains the base priority of the process, which is the starting priority for threads created /// within the associated process. /// /// The UniqueProcessId member contains the process's unique process ID. /// /// The HandleCount member contains the total number of handles being used by the process in question; use /// GetProcessHandleCount to retrieve this information instead. /// /// The SessionId member contains the session identifier of the process session. /// The PeakVirtualSize member contains the peak size, in bytes, of the virtual memory used by the process. /// The VirtualSize member contains the current size, in bytes, of virtual memory used by the process. /// The PeakWorkingSetSize member contains the peak size, in kilobytes, of the working set of the process. /// The QuotaPagedPoolUsage member contains the current quota charged to the process for paged pool usage. /// The QuotaNonPagedPoolUsage member contains the current quota charged to the process for nonpaged pool usage. /// The PagefileUsage member contains the number of bytes of page file storage in use by the process. /// The PeakPagefileUsage member contains the maximum number of bytes of page-file storage used by the process. /// The PrivatePageCount member contains the number of memory pages allocated for the use of this process. /// /// You can also retrieve the PeakWorkingSetSize, QuotaPagedPoolUsage, QuotaNonPagedPoolUsage, /// PagefileUsage, PeakPagefileUsage, and PrivatePageCount information using either the GetProcessMemoryInfo /// function or the Win32_Process class. /// /// The other members of the structure are reserved for internal use by the operating system. /// SYSTEM_THREAD_INFORMATION /// /// When the SystemInformationClass parameter is SystemProcessInformation, the buffer pointed to by the SystemInformation /// parameter contains a SYSTEM_PROCESS_INFORMATION structure for each process. Each of these structures is immediately /// followed in memory by one or more SYSTEM_THREAD_INFORMATION structures that provide info for each thread in the preceding /// process. For more information about SYSTEM_PROCESS_INFORMATION, see the section about this structure in this article. /// Each SYSTEM_THREAD_INFORMATION structure has the following layout: /// /// ///typedef struct _SYSTEM_THREAD_INFORMATION { ///LARGE_INTEGER Reserved1[3]; ///ULONG Reserved2; ///PVOID StartAddress; ///CLIENT_ID ClientId; ///KPRIORITY Priority; ///LONG BasePriority; ///ULONG Reserved3; ///ULONG ThreadState; ///ULONG WaitReason; ///} SYSTEM_THREAD_INFORMATION; /// /// The StartAddress member contains the start address of the thread. /// The ClientId member contains the ID of the thread and the process owning the thread. /// The Priority member contains the dynamic thread priority. /// The BasePriority member contains the base thread priority. /// The ThreadState member contains the current thread state. /// The WaitReason member contains the reason the thread is waiting. /// The other members of the structure are reserved for internal use by the operating system. /// SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION /// /// When the SystemInformationClass parameter is SystemProcessorPerformanceInformation, the buffer pointed to by the /// SystemInformation parameter should be large enough to hold an array that contains as many /// SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION structures as there are processors (CPUs) installed in the system. Each /// structure has the following layout: /// /// ///typedef struct ///_SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION { ///LARGE_INTEGER IdleTime; ///LARGE_INTEGER KernelTime; ///LARGE_INTEGER UserTime; ///LARGE_INTEGER Reserved1[2]; ///ULONG Reserved2; ///} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION; /// /// The IdleTime member contains the amount of time that the system has been idle, in 100-nanosecond intervals. /// /// The KernelTime member contains the amount of time that the system has spent executing in Kernel mode (including all /// threads in all processes, on all processors), in 100-nanosecond intervals. /// /// /// The UserTime member contains the amount of time that the system has spent executing in User mode (including all threads /// in all processes, on all processors), in 100-nanosecond intervals. /// /// Use GetSystemTimesinstead to retrieve this information. /// SYSTEM_QUERY_PERFORMANCE_COUNTER_INFORMATION /// /// When the SystemInformationClass parameter is SystemQueryPerformanceCounterInformation, the buffer pointed to by the /// SystemInformation parameter should be large enough to hold a single SYSTEM_QUERY_PERFORMANCE_COUNTER_INFORMATION /// structure having the following layout: /// /// ///typedef struct _SYSTEM_QUERY_PERFORMANCE_COUNTER_INFORMATION { ///ULONG Version; ///QUERY_PERFORMANCE_COUNTER_FLAGS Flags; ///QUERY_PERFORMANCE_COUNTER_FLAGS ValidFlags; ///} SYSTEM_QUERY_PERFORMANCE_COUNTER_INFORMATION; /// /// /// The Flags and ValidFlags members are QUERY_PERFORMANCE_COUNTER_FLAGS structures having the following layout: /// /// ///typedef struct _QUERY_PERFORMANCE_COUNTER_FLAGS { ///union { ///struct { ///ULONG KernelTransition:1; ///ULONG Reserved:31; ///}; ///ULONG ul; ///}; ///} QUERY_PERFORMANCE_COUNTER_FLAGS; /// /// /// The ValidFlags member of the SYSTEM_QUERY_PERFORMANCE_COUNTER_INFORMATION structure indicates which bits of the /// Flags member contain valid information. If a kernel transition is required, the KernelTransition bit is set in /// both ValidFlags and Flags. If a kernel transition is not required, the KernelTransition bit is set in /// ValidFlags and clear in Flags. /// /// SYSTEM_REGISTRY_QUOTA_INFORMATION /// /// When the SystemInformationClass parameter is SystemRegistryQuotaInformation, the buffer pointed to by the /// SystemInformation parameter should be large enough to hold a single SYSTEM_REGISTRY_QUOTA_INFORMATION structure having /// the following layout: /// /// ///typedef struct _SYSTEM_REGISTRY_QUOTA_INFORMATION { ///ULONG RegistryQuotaAllowed; ///ULONG RegistryQuotaUsed; ///PVOID Reserved1; ///} SYSTEM_REGISTRY_QUOTA_INFORMATION; /// /// The RegistryQuotaAllowed member contains the maximum size, in bytes, that the Registry can attain on this system. /// The RegistryQuotaUsed member contains the current size of the Registry, in bytes. /// Use GetSystemRegistryQuota instead to retrieve this information. /// The other member of the structure is reserved for internal use by the operating system. /// SYSTEM_SPECULATION_CONTROL_INFORMATION /// /// When the SystemInformationClass parameter is SystemSpeculationControlInformation, the buffer pointed to by the /// SystemInformation parameter should be large enough to hold a single SYSTEM_SPECULATION_CONTROL_INFORMATION structure /// having the following layout: /// /// ///typedef struct _SYSTEM_SPECULATION_CONTROL_INFORMATION { ///struct { ///ULONG BpbEnabled:1; ///ULONG BpbDisabledSystemPolicy:1; ///ULONG BpbDisabledNoHardwareSupport:1; ///ULONG SpecCtrlEnumerated:1; ///ULONG SpecCmdEnumerated:1; ///ULONG IbrsPresent:1; ///ULONG StibpPresent:1; ///ULONG SmepPresent:1; ///ULONG Reserved:24; ///} SpeculationControlFlags; ///} SYSTEM_SPECULATION_CONTROL_INFORMATION, * PSYSTEM_SPECULATION_CONTROL_INFORMATION; /// /// The BpbEnabled indicates whether speculation control features are supported and enabled. /// The BpbDisabledSystemPolicy indicates whether speculation control features are disabled due to system policy. /// /// The BpbDisabledNoHardwareSupport whether speculation control features are disabled due to the absence of hardware support. /// /// The SpecCtrlEnumerated whether the IA32_SPEC_CTRL MSR is enumerated by hardware. /// The SpecCmdEnumerated indicates whether the IA32_SPEC_CMD MSR is enumerated by hardware. /// The IbrsPresent indicates whether the IBRS MSR is treated as being present. /// The StibpPresent indicates whether the STIBP MSR is present. /// The SmepPresent indicates whether the SMEP feature is present and enabled. /// The Reserved member of the structure is reserved for internal use by the operating system. /// SYSTEM_TIMEOFDAY_INFORMATION /// /// When the SystemInformationClass parameter is SystemTimeOfDayInformation, the buffer pointed to by the SystemInformation /// parameter should be large enough to hold an opaque SYSTEM_TIMEOFDAY_INFORMATION structure for use in generating an /// unpredictable seed for a random number generator. For this purpose, the structure has the following layout: /// /// ///typedef struct _SYSTEM_TIMEOFDAY_INFORMATION { ///BYTE Reserved1[48]; ///} SYSTEM_TIMEOFDAY_INFORMATION; /// /// Individual members of the structure are reserved for internal use by the operating system. /// Use the CryptGenRandom function instead to generate cryptographically random data. /// /// /// The requested SystemInformationClass does not match the return type requested. or Reported size of object does not match query. /// public static T NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass) { var tType = typeof(T); if (CorrespondingTypeAttribute.GetCorrespondingTypes(SystemInformationClass).Any() && !CorrespondingTypeAttribute.CanGet(SystemInformationClass, tType)) throw new InvalidCastException("The requested SystemInformationClass does not match the return type requested."); var status = NtQuerySystemInformation(SystemInformationClass, SafeHGlobalHandle.Null, 0, out var len); if (status != NTStatus.STATUS_INFO_LENGTH_MISMATCH && status != NTStatus.STATUS_BUFFER_OVERFLOW && status != NTStatus.STATUS_BUFFER_TOO_SMALL) throw status.GetException(); var mem = new SafeHGlobalHandle(SystemInformationClass == SYSTEM_INFORMATION_CLASS.SystemProcessInformation ? (int)len * 2 : (int)len); NtQuerySystemInformation(SystemInformationClass, mem, (uint)mem.Size, out len).ThrowIfFailed(); if (tType.IsArray) { var aType = tType.GetElementType(); if (aType == typeof(SYSTEM_PROCESS_INFORMATION) && SystemInformationClass == SYSTEM_INFORMATION_CLASS.SystemProcessInformation) { var retList = new List(); var pi = new SYSTEM_PROCESS_INFORMATION(); var ptr = mem.DangerousGetHandle(); do { pi = ptr.ToStructure(); retList.Add(pi); ptr = ptr.Offset(pi.NextEntryOffset); } while (pi.NextEntryOffset > 0); return (T)(object)retList.ToArray(); } var cnt = Math.DivRem(len, Marshal.SizeOf(aType), out var res); if (res != 0) throw new InvalidCastException("Reported size of object does not match query."); return (T)mem.InvokeGenericMethod("ToArray", new[] { aType }, new[] { typeof(int), typeof(int) }, new object[] { (int)cnt, 0 }); } return mem.ToStructure(); } /// /// /// [ NtQuerySystemInformation may be altered or unavailable in future versions of Windows. Applications should use the /// alternate functions listed in this topic.] /// /// Retrieves the specified system information. /// /// The list of results from calling NtQuerySystemInformation with SystemProcessInformation. public static IList> NtQuerySystemInformation_Process() { var status = NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS.SystemProcessInformation, SafeHGlobalHandle.Null, 0, out var len); if (status != NTStatus.STATUS_INFO_LENGTH_MISMATCH && status != NTStatus.STATUS_BUFFER_OVERFLOW && status != NTStatus.STATUS_BUFFER_TOO_SMALL) throw status.GetException(); var mem = new SafeHGlobalHandle((int)len * 2); NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS.SystemProcessInformation, mem, (uint)mem.Size, out len).ThrowIfFailed(); var retList = new List>(); var pi = new SYSTEM_PROCESS_INFORMATION(); var ptr = mem.DangerousGetHandle(); var pSz = Marshal.SizeOf(pi); do { pi = ptr.ToStructure(); retList.Add(new Tuple(pi, ptr.Offset(pSz).ToArray((int)pi.NumberOfThreads))); ptr = ptr.Offset(pi.NextEntryOffset); } while (pi.NextEntryOffset > 0); return retList; } /// /// Reads data from an area of memory in a specified process. The entire area to be read must be accessible or the operation fails. /// /// /// A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process. /// /// /// A pointer to the base address in the specified process from which to read. Before any data transfer occurs, the system verifies /// that all data in the base address and memory of the specified size is accessible for read access, and if it is not accessible /// the function fails. /// /// A pointer to a buffer that receives the contents from the address space of the specified process. /// The number of bytes to be read from the specified process. /// /// A pointer to a variable that receives the number of bytes transferred into the specified buffer. If lpNumberOfBytesRead is /// NULL, the parameter is ignored. /// /// /// Returns an NTSTATUS success or error code. /// /// The forms and significance of NTSTATUS error codes are listed in the Ntstatus.h header file available in the DDK, and are /// described in the DDK documentation. /// /// [DllImport(Lib.NtDll, SetLastError = false, ExactSpelling = true)] [PInvokeData("winternl.h")] public static extern NTStatus NtWow64ReadVirtualMemory64([In] HPROCESS hProcess, [In] long lpBaseAddress, [Out] int lpBuffer, [In] long nSize, out long lpNumberOfBytesRead); /// The CLIENT_ID structure contains identifiers of a process and a thread. [StructLayout(LayoutKind.Sequential, Pack = 4)] public struct CLIENT_ID { /// The unique process identifier. public IntPtr UniqueProcess; /// The unique thread identifier. public IntPtr UniqueThread; } /// /// The KEY_NAME_INFORMATION structure holds the name and name length of the key. /// /// /// /// The ZwQueryKey routine uses the KEY_NAME_INFORMATION structure to contain the registry key name. When the /// KeyInformationClass parameter of this routine is KeyNameInformation, the KeyInformation buffer is treated as a /// KEY_NAME_INFORMATION structure. For more information about the KeyNameInformation enumeration value, see KEY_INFORMATION_CLASS. /// /// // https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/ntddk/ns-ntddk-_key_name_information typedef struct // _KEY_NAME_INFORMATION { ULONG NameLength; WCHAR Name[1]; } KEY_NAME_INFORMATION, *PKEY_NAME_INFORMATION; [PInvokeData("ntddk.h", MSDNShortId = "5b46e7d9-fbb0-4e55-b1f5-d9d0f1dd1f2c")] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct KEY_NAME_INFORMATION { /// /// The size, in bytes, of the key name string in the Name array. /// public uint NameLength; /// /// /// An array of wide characters that contains the name of the registry key. This character string is null-terminated. Only the /// first element in this array is included in the KEY_NAME_INFORMATION structure definition. The storage for the /// remaining elements in the array immediately follows this element. /// /// public StrPtrUni Name; } /// Used by . [PInvokeData("ntldr.h", MSDNShortId = "12202797-c80c-4fa3-9cc4-dcb1a9f01551")] [StructLayout(LayoutKind.Sequential)] public struct LDR_DLL_NOTIFICATION_DATA { /// Reserved. public uint Flags; /// The full path name of the DLL module. public IntPtr FullDllName; /// The base file name of the DLL module. public IntPtr BaseDllName; /// A pointer to the base address for the DLL in memory. public IntPtr DllBase; /// The size of the DLL image, in bytes. public uint SizeOfImage; } /// /// /// The OBJECT_ATTRIBUTES structure specifies attributes that can be applied to objects or object handles by routines that /// create objects and/or return handles to objects. /// /// /// /// /// Use the InitializeObjectAttributes macro to initialize the members of the OBJECT_ATTRIBUTES structure. Note that /// InitializeObjectAttributes initializes the SecurityQualityOfService member to NULL. If you must specify a /// non- NULL value, set the SecurityQualityOfService member after initialization. /// /// /// To apply the attributes contained in this structure to an object or object handle, pass a pointer to this structure to a routine /// that accesses objects or returns object handles, such as ZwCreateFile or ZwCreateDirectoryObject. /// /// /// All members of this structure are read-only. If a member of this structure is a pointer, the object that this member points to /// is read-only as well. Read-only members and objects can be used to acquire relevant information but must not be modified. To set /// the members of this structure, use the InitializeObjectAttributes macro. /// /// /// Driver routines that run in a process context other than that of the system process must set the OBJ_KERNEL_HANDLE flag for the /// Attributes member (by using the InitializeObjectAttributes macro). This restricts the use of a handle opened for /// that object to processes running only in kernel mode. Otherwise, the handle can be accessed by the process in whose context the /// driver is running. /// /// // https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/wudfwdm/ns-wudfwdm-_object_attributes typedef struct // _OBJECT_ATTRIBUTES { ULONG Length; HANDLE RootDirectory; PUNICODE_STRING ObjectName; ULONG Attributes; PVOID SecurityDescriptor; // PVOID SecurityQualityOfService; } OBJECT_ATTRIBUTES; [PInvokeData("wudfwdm.h", MSDNShortId = "08f5a141-abce-4890-867c-5fe8c4239905")] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct OBJECT_ATTRIBUTES { /// /// /// The number of bytes of data contained in this structure. The InitializeObjectAttributes macro sets this member to /// sizeof( OBJECT_ATTRIBUTES). /// /// public uint length; /// /// /// Optional handle to the root object directory for the path name specified by the ObjectName member. If /// RootDirectory is NULL, ObjectName must point to a fully qualified object name that includes the full /// path to the target object. If RootDirectory is non- NULL, ObjectName specifies an object name relative /// to the RootDirectory directory. The RootDirectory handle can refer to a file system directory or an object /// directory in the object manager namespace. /// /// public IntPtr rootDirectory; /// /// /// Pointer to a Unicode string that contains the name of the object for which a handle is to be opened. This must either be a /// fully qualified object name, or a relative path name to the directory specified by the RootDirectory member. /// /// public IntPtr objectName; /// /// /// Bitmask of flags that specify object handle attributes. This member can contain one or more of the flags in the following table. /// /// /// /// Flag /// Meaning /// /// /// OBJ_INHERIT /// This handle can be inherited by child processes of the current process. /// /// /// OBJ_PERMANENT /// /// This flag only applies to objects that are named within the object manager. By default, such objects are deleted when all /// open handles to them are closed. If this flag is specified, the object is not deleted when all open handles are closed. /// Drivers can use the ZwMakeTemporaryObject routine to make a permanent object non-permanent. /// /// /// /// OBJ_EXCLUSIVE /// /// If this flag is set and the OBJECT_ATTRIBUTES structure is passed to a routine that creates an object, the object can be /// accessed exclusively. That is, once a process opens such a handle to the object, no other processes can open handles to this /// object. If this flag is set and the OBJECT_ATTRIBUTES structure is passed to a routine that creates an object handle, the /// caller is requesting exclusive access to the object for the process context that the handle was created in. This request can /// be granted only if the OBJ_EXCLUSIVE flag was set when the object was created. /// /// /// /// OBJ_CASE_INSENSITIVE /// /// If this flag is specified, a case-insensitive comparison is used when matching the name pointed to by the ObjectName member /// against the names of existing objects. Otherwise, object names are compared using the default system settings. /// /// /// /// OBJ_OPENIF /// /// If this flag is specified, by using the object handle, to a routine that creates objects and if that object already exists, /// the routine should open that object. Otherwise, the routine creating the object returns an NTSTATUS code of STATUS_OBJECT_NAME_COLLISION. /// /// /// /// OBJ_OPENLINK /// /// If an object handle, with this flag set, is passed to a routine that opens objects and if the object is a symbolic link /// object, the routine should open the symbolic link object itself, rather than the object that the symbolic link refers to /// (which is the default behavior). /// /// /// /// OBJ_KERNEL_HANDLE /// The handle is created in system process context and can only be accessed from kernel mode. /// /// /// OBJ_FORCE_ACCESS_CHECK /// /// The routine that opens the handle should enforce all access checks for the object, even if the handle is being opened in /// kernel mode. /// /// /// /// OBJ_VALID_ATTRIBUTES /// Reserved. /// /// /// public uint attributes; /// /// /// Specifies a security descriptor (SECURITY_DESCRIPTOR) for the object when the object is created. If this member is /// NULL, the object will receive default security settings. /// /// public IntPtr securityDescriptor; /// /// /// Optional quality of service to be applied to the object when it is created. Used to indicate the security impersonation /// level and context tracking mode (dynamic or static). Currently, the InitializeObjectAttributes macro sets this member to NULL. /// /// public IntPtr securityQualityOfService; } /// Provides a to an enlistment that releases its handle at disposal using NTClose. public class SafeEnlistmentHandle : SafeNtHandle { /// Initializes a new instance of the class and assigns an existing handle. /// An object that represents the pre-existing handle to use. /// /// to reliably release the handle during the finalization phase; otherwise, (not recommended). /// public SafeEnlistmentHandle(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { } /// Initializes a new instance of the class. private SafeEnlistmentHandle() : base() { } } /// Provides a to an object that releases a created handle at disposal using NtClose. public abstract class SafeNtHandle : SafeHANDLE { /// Initializes a new instance of the class and assigns an existing handle. /// An object that represents the pre-existing handle to use. /// /// to reliably release the handle during the finalization phase; otherwise, (not recommended). /// public SafeNtHandle(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { } /// Initializes a new instance of the class. protected SafeNtHandle() : base() { } #pragma warning disable CS0612 // Type or member is obsolete /// protected override bool InternalReleaseHandle() => NtClose(handle).Succeeded; #pragma warning restore CS0612 // Type or member is obsolete } /// Provides a to a resource manager that releases its handle at disposal using NTClose. public class SafeResourceManagerHandle : SafeNtHandle { /// Initializes a new instance of the class and assigns an existing handle. /// An object that represents the pre-existing handle to use. /// /// to reliably release the handle during the finalization phase; otherwise, (not recommended). /// public SafeResourceManagerHandle(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { } /// Initializes a new instance of the class. private SafeResourceManagerHandle() : base() { } } /// Provides a to a section that releases its handle at disposal using NTClose. public class SafeSectionHandle : SafeNtHandle { /// Initializes a new instance of the class and assigns an existing handle. /// An object that represents the pre-existing handle to use. /// /// to reliably release the handle during the finalization phase; otherwise, (not recommended). /// public SafeSectionHandle(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { } /// Initializes a new instance of the class. private SafeSectionHandle() : base() { } } /// Provides a to a transaction that releases its handle at disposal using NTClose. public class SafeTransactionHandle : SafeNtHandle { /// Initializes a new instance of the class and assigns an existing handle. /// An object that represents the pre-existing handle to use. /// /// to reliably release the handle during the finalization phase; otherwise, (not recommended). /// public SafeTransactionHandle(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { } /// Initializes a new instance of the class. private SafeTransactionHandle() : base() { } } /// Provides a to a transaction manager that releases its handle at disposal using NTClose. public class SafeTransactionManagerHandle : SafeNtHandle { /// Initializes a new instance of the class and assigns an existing handle. /// An object that represents the pre-existing handle to use. /// /// to reliably release the handle during the finalization phase; otherwise, (not recommended). /// public SafeTransactionManagerHandle(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { } /// Initializes a new instance of the class. private SafeTransactionManagerHandle() : base() { } } /* NtDeviceIoControlFile NtDuplicateToken NtEnumerateTransactionObject NtFlushBuffersFileEx NtFreeVirtualMemory NtFsControlFile NtGetCurrentProcessorNumber NtGetNotificationResourceManager NtLockFile NtNotifyChangeMultipleKeys NtOpenDirectoryObject NtOpenEnlistment NtOpenFile NtOpenProcess NtOpenProcessTokenEx NtOpenResourceManager NtOpenSymbolicLinkObject NtOpenThread NtOpenThreadTokenEx NtOpenTransaction NtOpenTransactionManager NtPowerInformation NtPrepareComplete NtPrepareEnlistment NtPrePrepareComplete NtPrePrepareEnlistment NtProtectVirtualMemory NtQueryAttributesFile NtQueryDirectoryFile NtQueryInformationEnlistment NtQueryInformationFile NtQueryInformationProcess NtQueryInformationResourceManager NtQueryInformationThread NtQueryInformationToken NtQueryInformationTransaction NtQueryInformationTransactionManager NtQueryMultipleValueKey NtQueryObject NtQueryPerformanceCounter NtQueryQuotaInformationFile NtQuerySecurityObject NtQuerySymbolicLinkObject NtQuerySystemTime NtQueryVirtualMemory NtQueryVolumeInformationFile NtReadFile NtReadOnlyEnlistment NtRecoverEnlistment NtRecoverResourceManager NtRecoverTransactionManager NtRenameKey NtRenameTransactionManager NtRollbackComplete NtRollbackEnlistment NtRollbackTransaction NtRollforwardTransactionManager NtSetInformationEnlistment NtSetInformationFile NtSetInformationKey NtSetInformationResourceManager NtSetInformationThread NtSetInformationToken NtSetInformationTransaction NtSetInformationTransactionManager NtSetQuotaInformationFile NtSetSecurityObject NtSinglePhaseReject NtUnlockFile NtUnmapViewOfSection NtWaitForSingleObject NtWriteFile RtlAbsoluteToSelfRelativeSD RtlAddAccessAllowedAce RtlAddAccessAllowedAceEx RtlAddAce RtlAddFunctionTable RtlAddGrowableFunctionTable RtlAllocateAndInitializeSid RtlAllocateHeap RtlAppendStringToString RtlAppendUnicodeToString RtlAreBitsClear RtlAreBitsSet RtlCaptureContext RtlCaptureStackBackTrace RtlCharToInteger RtlCheckRegistryKey RtlClearBits RtlCmEncodeMemIoResource RtlCompareMemory RtlCompareMemoryUlong RtlCompareString RtlCompressBuffer RtlCopyLuid RtlCopyMemoryNonTemporal RtlCopySid RtlCopyString RtlCreateAcl RtlCreateHeap RtlCreateRegistryKey RtlCreateSecurityDescriptor RtlCreateSystemVolumeInformationFolder RtlCustomCPToUnicodeN RtlDecompressBuffer RtlDecompressBufferEx RtlDecompressFragment RtlDelete RtlDeleteAce RtlDeleteElementGenericTable RtlDeleteElementGenericTableAvl RtlDeleteFunctionTable RtlDeleteGrowableFunctionTable RtlDeleteNoSplay RtlDeleteRegistryValue RtlDestroyHeap RtlDrainNonVolatileFlush RtlEnumerateGenericTable RtlEnumerateGenericTableAvl RtlEnumerateGenericTableLikeADirectory RtlEnumerateGenericTableWithoutSplaying RtlEnumerateGenericTableWithoutSplayingAvl RtlEqualPrefixSid RtlEqualSid RtlEthernetAddressToStringA RtlEthernetAddressToStringW RtlEthernetStringToAddressA RtlEthernetStringToAddressW RtlFindClearBits RtlFindClearBitsAndSet RtlFindClearRuns RtlFindLastBackwardRunClear RtlFindLeastSignificantBit RtlFindLongestRunClear RtlFindMostSignificantBit RtlFindNextForwardRunClear RtlFindSetBits RtlFindSetBitsAndClear RtlFirstEntrySList RtlFlushNonVolatileMemory RtlFlushNonVolatileMemoryRanges RtlFreeAnsiString RtlFreeHeap RtlFreeNonVolatileToken RtlFreeOemString RtlGenerate8dot3Name RtlGetAce RtlGetCompressionWorkSpaceSize RtlGetDaclSecurityDescriptor RtlGetElementGenericTable RtlGetElementGenericTableAvl RtlGetEnabledExtendedFeatures RtlGetFunctionTableListHead RtlGetGroupSecurityDescriptor RtlGetNonVolatileToken RtlGetOwnerSecurityDescriptor RtlGetSaclSecurityDescriptor RtlGetUnloadEventTrace RtlGetUnloadEventTraceEx RtlGetVersion RtlGrowFunctionTable RtlGUIDFromString RtlInitAnsiString RtlInitCodePageTable RtlInitializeBitMap RtlInitializeGenericTable RtlInitializeGenericTableAvl RtlInitializeSid RtlInitializeSidEx RtlInitializeSListHead RtlInitString RtlInitStringEx RtlInsertElementGenericTable RtlInsertElementGenericTableAvl RtlInsertElementGenericTableFullAvl RtlInstallFunctionTableCallback RtlInterlockedFlushSList RtlInterlockedPushEntrySList RtlIoDecodeMemIoResource RtlIoEncodeMemIoResource RtlIpv4AddressToStringA RtlIpv4AddressToStringExW RtlIpv4StringToAddressA RtlIpv4StringToAddressExA RtlIpv4StringToAddressExW RtlIpv4StringToAddressW RtlIpv6AddressToStringA RtlIpv6AddressToStringExW RtlIpv6AddressToStringW RtlIpv6StringToAddressA RtlIpv6StringToAddressExW RtlIpv6StringToAddressW RtlIsGenericTableEmpty RtlIsGenericTableEmptyAvl RtlIsNameInExpression RtlIsNameLegalDOS8Dot3 RtlIsValidLocaleName RtlLengthSecurityDescriptor RtlLengthSid RtlLocalTimeToSystemTime RtlLookupElementGenericTable RtlLookupElementGenericTableAvl RtlLookupElementGenericTableFullAvl RtlLookupFirstMatchingElementGenericTableAvl RtlLookupFunctionEntry RtlMapGenericMask RtlMoveMemory RtlMultiByteToUnicodeN RtlMultiByteToUnicodeSize RtlNtStatusToDosError RtlNumberGenericTableElements RtlNumberGenericTableElementsAvl RtlNumberOfClearBits RtlNumberOfSetBits RtlNumberOfSetBitsUlongPtr RtlOemToUnicodeN RtlPcToFileHeader RtlQueryDepthSList RtlQueryRegistryValues RtlRaiseException RtlRandom RtlRandomEx RtlRealPredecessor RtlRealSuccessor RtlRestoreContext RtlRunOnceBeginInitialize RtlRunOnceComplete RtlRunOnceExecuteOnce RtlRunOnceInitialize RtlSecondsSince1970ToTime RtlSecondsSince1980ToTime RtlSelfRelativeToAbsoluteSD RtlSetAllBits RtlSetBits RtlSetDaclSecurityDescriptor RtlSetGroupSecurityDescriptor RtlSetOwnerSecurityDescriptor RtlSplay RtlStringFromGUID RtlSubAuthorityCountSid RtlSubAuthoritySid RtlSubtreePredecessor RtlSubtreeSuccessor RtlTimeFieldsToTime RtlTimeToSecondsSince1970 RtlTimeToSecondsSince1980 RtlTimeToTimeFields RtlUnicodeToCustomCPN RtlUnicodeToMultiByteN RtlUnicodeToMultiByteSize RtlUnicodeToOemN RtlUnicodeToUTF8N RtlUniform RtlUnwind RtlUpcaseUnicodeChar RtlUpcaseUnicodeToCustomCPN RtlUpcaseUnicodeToMultiByteN RtlUpcaseUnicodeToOemN RtlUpperChar RtlUpperString RtlUTF8ToUnicodeN RtlValidRelativeSecurityDescriptor RtlVerifyVersionInfo RtlVirtualUnwind RtlWriteNonVolatileMemory RtlWriteRegistryValue vDbgPrintEx vDbgPrintExWithPrefix VerSetConditionMask ZwAllocateLocallyUniqueId ZwAllocateVirtualMemory ZwClose ZwCommitComplete ZwCommitEnlistment ZwCommitTransaction ZwCreateDirectoryObject ZwCreateEnlistment ZwCreateEvent ZwCreateFile ZwCreateKey ZwCreateKeyTransacted ZwCreateResourceManager ZwCreateSection ZwCreateTransaction ZwCreateTransactionManager ZwDeleteFile ZwDeleteKey ZwDeleteValueKey ZwDeviceIoControlFile ZwDuplicateObject ZwDuplicateToken ZwEnumerateKey ZwEnumerateTransactionObject ZwEnumerateValueKey ZwFlushBuffersFileEx ZwFlushKey ZwFlushVirtualMemory ZwFreeVirtualMemory ZwFsControlFile ZwGetNotificationResourceManager ZwLoadDriver ZwLockFile ZwMakeTemporaryObject ZwMapViewOfSection ZwNotifyChangeKey ZwOpenDirectoryObject ZwOpenEnlistment ZwOpenEvent ZwOpenFile ZwOpenKey ZwOpenKeyEx ZwOpenKeyTransacted ZwOpenKeyTransactedEx ZwOpenProcess ZwOpenProcessTokenEx ZwOpenResourceManager ZwOpenSection ZwOpenSymbolicLinkObject ZwOpenThreadTokenEx ZwOpenTransaction ZwOpenTransactionManager ZwPowerInformation ZwPrepareComplete ZwPrepareEnlistment ZwPrePrepareComplete ZwPrePrepareEnlistment ZwQueryDirectoryFile ZwQueryEaFile ZwQueryFullAttributesFile ZwQueryInformationEnlistment ZwQueryInformationFile ZwQueryInformationProcess ZwQueryInformationResourceManager ZwQueryInformationToken ZwQueryInformationTransaction ZwQueryInformationTransactionManager ZwQueryKey ZwQueryObject ZwQueryQuotaInformationFile ZwQuerySecurityObject ZwQuerySymbolicLinkObject ZwQuerySystemInformation ZwQuerySystemInformationEx ZwQueryValueKey ZwQueryVirtualMemory ZwQueryVolumeInformationFile ZwReadFile ZwReadOnlyEnlistment ZwRecoverEnlistment ZwRecoverResourceManager ZwRecoverTransactionManager ZwRollbackComplete ZwRollbackEnlistment ZwRollbackTransaction ZwRollforwardTransactionManager ZwSetEaFile ZwSetEvent ZwSetInformationEnlistment ZwSetInformationFile ZwSetInformationResourceManager ZwSetInformationThread ZwSetInformationToken ZwSetInformationTransaction ZwSetInformationVirtualMemory ZwSetQuotaInformationFile ZwSetSecurityObject ZwSetValueKey ZwSetVolumeInformationFile ZwSinglePhaseReject ZwSuspendProcess ZwTerminateProcess ZwUnloadDriver ZwUnlockFile ZwUnmapViewOfSection ZwUnmapViewOfSectionEx ZwWaitForSingleObject ZwWriteFile */ } }