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