using System; using System.Runtime.InteropServices; using static Vanara.Extensions.BitHelper; // ReSharper disable InconsistentNaming namespace Vanara.PInvoke { public static partial class Kernel32 { /// /// /// An application-defined function previously registered with the AddSecureMemoryCacheCallback function that is called when a /// secured memory range is freed or its protections are changed. /// /// /// The PSECURE_MEMORY_CACHE_CALLBACK type defines a pointer to this callback function. is a placeholder for the /// application-defined function name. /// /// /// /// The starting address of the memory range. /// /// /// The size of the memory range, in bytes. /// /// /// The return value indicates the success or failure of this function. /// If the caller has secured the specified memory range, this function should unsecure the memory and return TRUE. /// If the caller has not secured the specified memory range, this function should return FALSE. /// /// /// /// After the callback function is registered, it is called after any attempt to free the specified memory range or change its /// protections. If the application has secured any part of the specified memory range, the callback function must invalidate all of /// the application's cached memory mappings for the secured memory range, unsecure the secured parts of the memory range, and return /// TRUE. Otherwise it must return FALSE. /// /// /// The application secures and unsecures a memory range by sending requests to a device driver, which uses the MmSecureVirtualMemory /// and MmUnsecureVirtualMemory functions to actually secure and unsecure the range. Operations on other types of secured or locked /// memory do not trigger this callback. /// /// /// Examples of function calls that trigger the callback function include calls to the VirtualFree, VirtualFreeEx, VirtualProtect, /// VirtualProtectEx, and UnmapViewOfFile functions. /// /// /// The callback function can also be triggered by a heap operation. In this case, the function must not perform any further /// operations on the heap that triggered the callback. This includes calling heap functions on a private heap or the process's /// default heap, or calling standard library functions such as malloc and free, which implicitly use the process's /// default heap. /// /// To unregister the callback function, use the RemoveSecureMemoryCacheCallback function. /// // https://docs.microsoft.com/en-us/windows/desktop/api/winnt/nc-winnt-psecure_memory_cache_callback // BOOLEAN PsecureMemoryCacheCallback( PVOID Addr, SIZE_T Range ) {...} [UnmanagedFunctionPointer(CallingConvention.Winapi)] [PInvokeData("winnt.h", MSDNShortId = "abde4b6f-7cd8-4a4b-9b00-f035b2c29054")] [return: MarshalAs(UnmanagedType.U1)] public delegate bool PsecureMemoryCacheCallback(IntPtr Addr, SizeT Range); /// /// The application-defined user-mode scheduling (UMS) scheduler entry point function associated with a UMS completion list. /// /// The PUMS_SCHEDULER_ENTRY_POINT type defines a pointer to this function. UmsSchedulerProc is a placeholder for the /// application-defined function name. /// /// /// /// The reason the scheduler entry point is being called. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// UmsSchedulerStartup 0 /// /// A UMS scheduler thread was created. The entry point is called with this reason once each time EnterUmsSchedulingMode is called. /// /// /// /// UmsSchedulerThreadBlocked 1 /// A UMS worker thread blocked. /// /// /// UmsSchedulerThreadYield 2 /// An executing UMS worker thread yielded control by calling the UmsThreadYield function. /// /// /// /// /// If the Reason parameter is UmsSchedulerStartup, this parameter is NULL. /// /// If the Reason parameter is UmsSchedulerThreadBlocked, bit 0 of this parameter indicates the type of activity that was /// being serviced when the UMS worker thread blocked. /// /// /// /// Value /// Meaning /// /// /// 0 /// /// The thread blocked on a trap (for example, a hard page fault) or an interrupt (for example, an asynchronous procedure call). /// /// /// /// 1 /// The thread blocked on a system call. /// /// /// /// If the Reason parameter is UmsSchedulerThreadYield, this parameter is a pointer to the UMS thread context of the UMS /// worker thread that yielded. /// /// /// /// /// If the Reason parameter is UmsSchedulerStartup, this parameter is the SchedulerParam member of the /// UMS_SCHEDULER_STARTUP_INFO structure passed to the EnterUmsSchedulingMode function that triggered the entry point call. /// /// /// If the Reason parameter is UmsSchedulerThreadYield this parameter is the SchedulerParam parameter passed to the /// UmsThreadYield function that triggered the entry point call. /// /// If the Reason parameter is UmsSchedulerThreadBlocked, this parameter is NULL. /// /// /// This function does not return a value. /// /// /// /// The UmsSchedulerProc function pointer type is defined as PUMS_SCHEDULER_ENTRY_POINT in WinBase.h. The underlying function /// type is defined as RTL_UMS_SCHEDULER_ENTRY_POINT in WinNT.h /// /// /// Each UMS scheduler thread has an associated UmsSchedulerProc entry point function that is specified when the thread calls the /// EnterUmsSchedulingMode function. The system calls the scheduler entry point function with a reason of UmsSchedulerStartup /// when the scheduler thread is converted for UMS. /// /// /// Subsequently, when a UMS worker thread that is running on the scheduler thread yields or blocks, the system calls the scheduler /// thread's entry point function with a pointer to the UMS thread context of the worker thread. /// /// /// The application's scheduler is responsible for selecting the next UMS worker thread to run. The scheduler implements all policies /// that influence execution of its UMS threads, including processor affinity and thread priority. For example, a scheduler might /// give priority to I/O-intensive threads, or it might run threads on a first-come, first-served basis. This logic can be /// implemented in the scheduler entry point function or elsewhere in the application. /// /// /// When a blocked UMS worker thread becomes unblocked, the system queues the unblocked thread to the associated completion list and /// signals the completion list event. To retrieve UMS worker threads from the completion list, use the DequeueUmsCompletionListItems function. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winnt/nc-winnt-rtl_ums_scheduler_entry_point RTL_UMS_SCHEDULER_ENTRY_POINT // RtlUmsSchedulerEntryPoint; void RtlUmsSchedulerEntryPoint( RTL_UMS_SCHEDULER_REASON Reason, ULONG_PTR ActivationPayload, PVOID // SchedulerParam ) {...} [PInvokeData("winnt.h", MSDNShortId = "10de1c48-255d-45c3-acf0-25f8a564b585")] [UnmanagedFunctionPointer(CallingConvention.Winapi)] public delegate void RtlUmsSchedulerEntryPoint(RTL_UMS_SCHEDULER_REASON Reason, UIntPtr ActivationPayload, IntPtr SchedulerParam); /// Used by thread context functions. [PInvokeData("winnt.h")] [Flags] public enum CONTEXT_FLAG : uint { /// Undocumented. CONTEXT_AMD64 = 0x00100000, /// Undocumented. CONTEXT_CONTROL = (CONTEXT_AMD64 | 0x00000001), /// Undocumented. CONTEXT_INTEGER = (CONTEXT_AMD64 | 0x00000002), /// Undocumented. CONTEXT_SEGMENTS = (CONTEXT_AMD64 | 0x00000004), /// Undocumented. CONTEXT_FLOATING_POINT = (CONTEXT_AMD64 | 0x00000008), /// Undocumented. CONTEXT_DEBUG_REGISTERS = (CONTEXT_AMD64 | 0x00000010), /// Undocumented. CONTEXT_FULL = (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT), /// Undocumented. CONTEXT_ALL = (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS), /// Undocumented. CONTEXT_XSTATE = (CONTEXT_AMD64 | 0x00000040), /// Undocumented. CONTEXT_KERNEL_DEBUGGER = 0x04000000, /// Undocumented. CONTEXT_EXCEPTION_ACTIVE = 0x08000000, /// Undocumented. CONTEXT_SERVICE_ACTIVE = 0x10000000, /// Undocumented. CONTEXT_EXCEPTION_REQUEST = 0x40000000, /// Undocumented. CONTEXT_EXCEPTION_REPORTING = 0x80000000 } /// The flags that control the enforcement of the minimum and maximum working set sizes. [PInvokeData("winnt.h")] [Flags] public enum QUOTA_LIMITS_HARDWS { /// The working set will not fall below the minimum working set limit. QUOTA_LIMITS_HARDWS_MIN_ENABLE = 0x00000001, /// The working set may fall below the minimum working set limit if memory demands are high. QUOTA_LIMITS_HARDWS_MIN_DISABLE = 0x00000002, /// The working set will not exceed the maximum working set limit. QUOTA_LIMITS_HARDWS_MAX_ENABLE = 0x00000004, /// The working set may exceed the maximum working set limit if there is abundant memory. QUOTA_LIMITS_HARDWS_MAX_DISABLE = 0x00000008, /// The quota limits use default limits QUOTA_LIMITS_USE_DEFAULT_LIMITS = 0x00000010, } /// Used by . [PInvokeData("winnt.h", MSDNShortId = "10de1c48-255d-45c3-acf0-25f8a564b585")] public enum RTL_UMS_SCHEDULER_REASON { /// /// A UMS scheduler thread was created. The entry point is called with this reason once each time EnterUmsSchedulingMode is called. /// UmsSchedulerStartup = 0, /// A UMS worker thread blocked. UmsSchedulerThreadBlocked = 1, /// An executing UMS worker thread yielded control by calling the UmsThreadYield function. UmsSchedulerThreadYield = 2, } /// /// Represents classes of information about user-mode scheduling (UMS) threads. /// This enumeration is used by the QueryUmsThreadInformation and SetUmsThreadInformation functions. /// // https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ne-winnt-_rtl_ums_thread_info_class typedef enum // _RTL_UMS_THREAD_INFO_CLASS { UmsThreadInvalidInfoClass , UmsThreadUserContext , UmsThreadPriority , UmsThreadAffinity , // UmsThreadTeb , UmsThreadIsSuspended , UmsThreadIsTerminated , UmsThreadMaxInfoClass } RTL_UMS_THREAD_INFO_CLASS, *PRTL_UMS_THREAD_INFO_CLASS; [PInvokeData("winnt.h", MSDNShortId = "2d6730b2-4d01-45f5-9514-0d91806f50d5")] public enum RTL_UMS_THREAD_INFO_CLASS { /// Reserved. UmsThreadInvalidInfoClass, /// Application-defined information stored in a UMS thread context. UmsThreadUserContext, /// Reserved. UmsThreadPriority, /// Reserved. UmsThreadAffinity, /// /// The thread execution block (TEB) for a UMS thread. This information class can only be queried; it cannot be set. /// UmsThreadTeb, /// The suspension status of the thread. This information can only be queried; it cannot be set. UmsThreadIsSuspended, /// The termination status of the thread. This information can only be queried; it cannot be set. UmsThreadIsTerminated, /// Reserved. UmsThreadMaxInfoClass, } [PInvokeData("winnt.h")] [Flags] public enum SECTION_MAP : uint { SECTION_QUERY = 0x0001, SECTION_MAP_WRITE = 0x0002, SECTION_MAP_READ = 0x0004, SECTION_MAP_EXECUTE = 0x0008, SECTION_EXTEND_SIZE = 0x0010, SECTION_MAP_EXECUTE_EXPLICIT = 0x0020, SECTION_ALL_ACCESS = ACCESS_MASK.STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_WRITE | SECTION_MAP_READ | SECTION_MAP_EXECUTE | SECTION_EXTEND_SIZE, } /// /// The operator to be used for the comparison. The VerifyVersionInfo function uses this operator to compare a specified attribute /// value to the corresponding value for the currently running system. /// public enum VERSION_CONDITION : byte { /// The current value must be equal to the specified value. VER_EQUAL = 1, /// The current value must be greater than the specified value. VER_GREATER, /// The current value must be greater than or equal to the specified value. VER_GREATER_EQUAL, /// The current value must be less than the specified value. VER_LESS, /// The current value must be less than or equal to the specified value. VER_LESS_EQUAL, /// All product suites specified in the wSuiteMask member must be present in the current system. VER_AND, /// At least one of the specified product suites must be present in the current system. VER_OR, } /// /// A mask that indicates the member of the OSVERSIONINFOEX structure whose comparison operator is being set. This value corresponds /// to one of the bits specified in the dwTypeMask parameter for the VerifyVersionInfo function. /// [Flags] public enum VERSION_MASK : uint { /// dwMinorVersion VER_MINORVERSION = 0x0000001, /// dwMajorVersion VER_MAJORVERSION = 0x0000002, /// dwBuildNumber VER_BUILDNUMBER = 0x0000004, /// dwPlatformId VER_PLATFORMID = 0x0000008, /// wServicePackMinor VER_SERVICEPACKMINOR = 0x0000010, /// wServicePackMajor VER_SERVICEPACKMAJOR = 0x0000020, /// wSuiteMask VER_SUITENAME = 0x0000040, /// wProductType VER_PRODUCT_TYPE = 0x0000080, } /// Contains the hardware counter value. // typedef struct _HARDWARE_COUNTER_DATA { HARDWARE_COUNTER_TYPE Type; DWORD Reserved; DWORD64 Value;} HARDWARE_COUNTER_DATA, // *PHARDWARE_COUNTER_DATA; https://msdn.microsoft.com/en-us/library/windows/desktop/dd796394(v=vs.85).aspx [PInvokeData("Winnt.h", MSDNShortId = "dd796394")] [StructLayout(LayoutKind.Sequential)] public struct HARDWARE_COUNTER_DATA { /// The type of hardware counter data collected. For possible values, see the HARDWARE_COUNTER_TYPE enumeration. public HARDWARE_COUNTER_TYPE Type; /// Reserved. Initialize to zero. public uint Reserved; /// /// The counter index. Each hardware counter in a processor's performance monitoring unit (PMU) is identified by an index. /// public ulong Value; } /// Contains the thread profiling and hardware counter data that you requested. // typedef struct _PERFORMANCE_DATA { WORD Size; BYTE Version; BYTE HwCountersCount; DWORD ContextSwitchCount; DWORD64 // WaitReasonBitMap; DWORD64 CycleTime; DWORD RetryCount; DWORD Reserved; HARDWARE_COUNTER_DATA HwCounters[MAX_HW_COUNTERS];} // PERFORMANCE_DATA, *PPERFORMANCE_DATA; https://msdn.microsoft.com/en-us/library/windows/desktop/dd796401(v=vs.85).aspx [PInvokeData("Winnt.h", MSDNShortId = "dd796401")] [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct PERFORMANCE_DATA { private const int MAX_HW_COUNTERS = 16; /// The size of this structure. public ushort Size; /// The version of this structure. Must be set to PERFORMANCE_DATA_VERSION. public byte Version; /// /// The number of array elements in the HwCounters array that contain hardware counter data. A value of 3 means that the /// array contains data for three hardware counters, not that elements 0 through 2 contain counter data. /// public byte HwCountersCount; /// The number of context switches that occurred from the time profiling was enabled. public uint ContextSwitchCount; /// /// A bitmask that identifies the reasons for the context switches that occurred since the last time the data was read. For /// possible values, see the KWAIT_REASON enumeration (the enumeration is included in the Wdm.h file in the WDK). /// public ulong WaitReasonBitMap; /// The cycle time of the thread (excludes the time spent interrupted) from the time profiling was enabled. public ulong CycleTime; /// The number of times that the read operation read the data to ensure a consistent snapshot of the data. public uint RetryCount; /// Reserved. Set to zero. public uint Reserved; /// /// An array of HARDWARE_COUNTER_DATA structures that contain the counter values. The elements of the array that contain /// counter data relate directly to the bits set in the HardwareCounters bitmask that you specified when you called the /// EnableThreadProfiling function. For example, if you set bit 3 in the HardwareCounters bitmask, HwCounters[3] will /// contain the counter data for that counter. /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_HW_COUNTERS)] public HARDWARE_COUNTER_DATA[] HwCounters; } /// /// Represents a context frame on WOW64. Refer to the header file WinNT.h for the definition of this structure. /// /// /// /// In the following versions of Windows, Slot 1 of Thread Local Storage (TLS) holds a pointer to a structure that contains a /// WOW64_CONTEXT structure starting at offset 4. This might change in later versions of Windows. /// /// /// /// Windows Vista /// Windows Server 2008 /// /// /// Windows 7 /// Windows Server 2008 R2 /// /// /// Windows 8 /// Windows Server 2012 /// /// /// Windows 8.1 /// Windows Server 2012 R2 /// /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_wow64_context [PInvokeData("winnt.h", MSDNShortId = "b27205a2-2c33-4f45-8948-9919bcd2355a")] [StructLayout(LayoutKind.Sequential)] public struct WOW64_CONTEXT { /// public WOW64_CONTEXT_FLAGS ContextFlags; /// public uint Dr0; /// public uint Dr1; /// public uint Dr2; /// public uint Dr3; /// public uint Dr6; /// public uint Dr7; /// public WOW64_FLOATING_SAVE_AREA FloatSave; /// public uint SegGs; /// public uint SegFs; /// public uint SegEs; /// public uint SegDs; /// public uint Edi; /// public uint Esi; /// public uint Ebx; /// public uint Edx; /// public uint Ecx; /// public uint Eax; /// public uint Ebp; /// public uint Eip; /// public uint SegCs; /// public uint EFlags; /// public uint Esp; /// public uint SegSs; /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)] public byte[] ExtendedRegisters; } /// /// Represents the 80387 save area on WOW64. Refer to the header file WinNT.h for the definition of this structure. /// // https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_wow64_floating_save_area [PInvokeData("winnt.h", MSDNShortId = "56fba1c1-432b-40a8-b882-e4c637c03d5d")] [StructLayout(LayoutKind.Sequential)] public struct WOW64_FLOATING_SAVE_AREA { /// public uint ControlWord; /// public uint StatusWord; /// public uint TagWord; /// public uint ErrorOffset; /// public uint ErrorSelector; /// public uint DataOffset; /// public uint DataSelector; /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 80)] public byte[] RegisterArea; /// public uint Cr0NpxState; } /// /// /// Describes an entry in the descriptor table for a 32-bit thread on a 64-bit system. This structure is valid only on 64-bit systems. /// /// /// /// /// The Wow64GetThreadSelectorEntry function fills this structure with information from an entry in the descriptor table. You can use /// this information to convert a segment-relative address to a linear virtual address. /// /// /// The base address of a segment is the address of offset 0 in the segment. To calculate this value, combine the BaseLow, /// BaseMid, and BaseHi members. /// /// /// The limit of a segment is the address of the last byte that can be addressed in the segment. To calculate this value, combine the /// LimitLow and LimitHi members. /// /// /// The WOW64_LDT_ENTRY structure has the same layout for a 64-bit process as the LDT_ENTRY structure has for a 32-bit process. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_wow64_ldt_entry typedef struct _WOW64_LDT_ENTRY { WORD // LimitLow; WORD BaseLow; union { struct { BYTE BaseMid; BYTE Flags1; BYTE Flags2; BYTE BaseHi; } Bytes; struct { DWORD BaseMid : 8; // DWORD Type : 5; DWORD Dpl : 2; DWORD Pres : 1; DWORD LimitHi : 4; DWORD Sys : 1; DWORD Reserved_0 : 1; DWORD Default_Big : 1; // DWORD Granularity : 1; DWORD BaseHi : 8; } Bits; } HighWord; } WOW64_LDT_ENTRY, *PWOW64_LDT_ENTRY; [PInvokeData("winnt.h", MSDNShortId = "a571cd2f-0873-4ad5-bcb8-c0da2d47a820")] [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct WOW64_LDT_ENTRY { /// /// The low-order part of the address of the last byte in the segment. /// public ushort LimitLow; /// /// The low-order part of the base address of the segment. /// public ushort BaseLow; /// /// Middle bits (16-23) of the base address of the segment. /// public byte BaseMid; private ushort Flags; /// /// The high bits (24-31) of the base address of the segment. /// public byte BaseHi; /// /// The type of segment. This member can be one of the following values: /// public byte Type { get => (byte)GetBits(Flags, 0, 5); set => SetBits(ref Flags, 0, 5, value); } /// /// /// The privilege level of the descriptor. This member is an integer value in the range 0 (most privileged) through 3 (least privileged). /// /// public byte Dpl { get => (byte)GetBits(Flags, 5, 2); set => SetBits(ref Flags, 5, 2, value); } /// /// The present flag. This member is 1 if the segment is present in physical memory or 0 if it is not. /// public bool Pres { get => GetBit(Flags, 7); set => SetBit(ref Flags, 7, value); } /// /// The high bits (16–19) of the address of the last byte in the segment. /// public byte LimitHi { get => (byte)GetBits(Flags, 8, 4); set => SetBits(ref Flags, 8, 4, value); } /// /// /// The space that is available to system programmers. This member might be used for marking segments in some system-specific way. /// /// public bool Sys { get => GetBit(Flags, 12); set => SetBit(ref Flags, 12, value); } /// /// Reserved. /// public bool Reserved_0 { get => GetBit(Flags, 13); set => SetBit(ref Flags, 13, value); } /// /// /// The size of segment. If the segment is a data segment, this member contains 1 if the segment is larger than 64 kilobytes (KB) /// or 0 if the segment is smaller than or equal to 64 KB. /// /// /// If the segment is a code segment, this member contains 1. The segment runs with the default (native mode) instruction set. /// /// public bool Default_Big { get => GetBit(Flags, 14); set => SetBit(ref Flags, 14, value); } /// /// The granularity. This member contains 0 if the segment is byte granular, 1 if the segment is page granular. /// public bool Granularity { get => GetBit(Flags, 15); set => SetBit(ref Flags, 15, value); } } } }