diff --git a/00-Common Headers/KexAssert.h b/00-Common Headers/KexAssert.h new file mode 100644 index 0000000..3110d8b --- /dev/null +++ b/00-Common Headers/KexAssert.h @@ -0,0 +1,86 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// KexAssert.h +// +// Abstract: +// +// ASSERT and ASSUME macros. +// +// Author: +// +// vxiiduu (26-Sep-2022) +// +// Environment: +// +// ASSERT displays an error box when compiling for an EXE target. +// Otherwise, it will simply cause a breakpoint in the current process. +// +// ASSUME can be used anywhere. +// +// Revision History: +// +// vxiiduu 26-Sep-2022 Initial creation. +// vxiiduu 22-Feb-2022 Remove obsolete CHECKED macro. +// +/////////////////////////////////////////////////////////////////////////////// + +#pragma once + +// +// Uncomment the macro definition to keep asserts enabled in release builds. +// +//#define RELEASE_ASSERTS_ENABLED + +// +// == Guidelines for ASSERT Macro Usage in the VxKex Codebase == +// +// 1. Use a space between ASSERT and (. +// Bad: ASSERT(Pointer != NULL); +// Good: ASSERT (Pointer != NULL); +// +// 2. Do not omit the conditional operator. +// Bad: ASSERT (Pointer); +// Good: ASSERT (Pointer != NULL); +// +// 3. Use only one condition in an ASSERT macro. +// Bad: ASSERT (Pointer != NULL && Size != 0); +// +// Good: ASSERT (Pointer != NULL); +// ASSERT (Size != 0); +// +// 4. When asserting that a particular code-path will not be executed, use +// the comma operator to give the user/developer an explanation for what +// happened. Remember, no other context is given besides the condition +// inside the ASSERT macro. +// Bad: ASSERT (FALSE); +// Good: ASSERT (("The event ID is not valid", FALSE)); +// +#if defined(_DEBUG) || defined(RELEASE_ASSERTS_ENABLED) +# define ASSERTS_ENABLED +# if defined(KEX_TARGET_TYPE_EXE) && !defined(KEX_DISABLE_GRAPHICAL_ASSERTS) +# define ASSERT(Condition) if (!(Condition)) { \ + BOOLEAN ShouldRaiseException = ReportAssertionFailure( \ + __FILEW__, __LINE__, __FUNCTIONW__, L#Condition); \ + if (ShouldRaiseException) __int2c(); \ + } +# define SOFT_ASSERT ASSERT +# else +# define ASSERT(Condition) do { if (!(Condition)) { DbgPrint("Assertion failure: %s (%s:%d in %s)\r\n", #Condition, __FILE__, __LINE__, __FUNCTION__); __int2c(); } } while(0) +# define SOFT_ASSERT (Condition) do { if (!(Condition)) { DbgPrint("Soft assertion failure: %s (%S:%d in %s)\r\n", #Condition, __FILE__, __LINE__, __FUNCTION); } while (0) +# endif +#else +# define ASSERT(Condition) +#endif + +#ifndef _DEBUG +# define ASSUME __assume +# define NOT_REACHED ASSUME(FALSE) +#else +# define ASSUME ASSERT +# define NOT_REACHED ASSUME(("Execution should not have reached this point", FALSE)) +#endif + + +#define NOTHING \ No newline at end of file diff --git a/00-Common Headers/KexComm.h b/00-Common Headers/KexComm.h new file mode 100644 index 0000000..25dcd50 --- /dev/null +++ b/00-Common Headers/KexComm.h @@ -0,0 +1,276 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// KexComm.h +// +// Abstract: +// +// VxKex common header file. Every project which is a part of VxKex must +// include this file unless there is a very good reason not to. +// +// Author: +// +// vxiiduu (30-Sep-2022) +// +// Environment: +// +// Refer to included header files for information about their contents. +// +// Revision History: +// +// vxiiduu 30-Sep-2022 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#if !defined(KEX_ARCH_X64) && !defined(KEX_ARCH_X86) +# if defined(_M_X64) +# define KEX_ARCH_X64 +# elif defined(_M_IX86) +# define KEX_ARCH_X86 +# else +# error Invalid CPU architecture for VxKex. Only x86 and x64 are supported. +# endif +#endif + +#ifndef KEX_ENV_NATIVE +# define KEX_ENV_WIN32 +#endif + +#if defined(KEX_ENV_NATIVE) && defined(KEX_ENV_WIN32) +# error Only one of the KEX_ENV_ macros may be defined. +#endif + +// Define Unicode macros. +// __FILEW__ and __FUNCTIONW__ are already defined somewhere inside the windows +// headers. +#define CONCAT(a,b) a##b +#define _L(str) CONCAT(L,str) +#define __DATEW__ _L(__DATE__) +#define __TIMEW__ _L(__TIME__) +#define __TIMESTAMPW__ _L(__TIMESTAMP__) +#define __FUNCDNAMEW__ _L(__FUNCDNAME__) +#define __FUNCSIGW__ _L(__FUNCSIG__) + +// +// Define convenience macros so we don't need #ifdef in the middle of code. +// +#ifdef _DEBUG +# define KexIsDebugBuild TRUE +# define KexIsReleaseBuild FALSE +#else +# define KexIsDebugBuild FALSE +# define KexIsReleaseBuild TRUE +#endif + +#ifdef KEX_ARCH_X64 +# define KexIs32BitBuild FALSE +# define KexIs64BitBuild TRUE +#else +# define KexIs32BitBuild TRUE +# define KexIs64BitBuild FALSE +#endif + +#pragma region Header Includes +// these two must be included before other headers (esp. KexStrSafe.h), or +// undefined symbol errors can occur +# include +# include + +# ifdef KEX_ENV_NATIVE + // + // We can't use any of this stuff in a native environment, + // so we disable it to avoid mistakes/accidentally calling + // unusable APIs. + // +# define NOGDICAPMASKS +# define NOVIRTUALKEYCODES +# define NOWINMESSAGES +# define NOWINSTYLES +# define NOSYSMETRICS +# define NOMENUS +# define NOICONS +# define NOKEYSTATES +# define NOSYSCOMMANDS +# define NORASTEROPS +# define NOSHOWWINDOW +# define NOATOM +# define NOCLIPBOARD +# define NOCOLOR +# define NOCTLMGR +# define NODRAWTEXT +# define NOGDI +# define NOKERNEL +# define NOUSER +# define NONLS +# define NOMB +# define NOMEMMGR +# define NOMSG +# define NOOPENFILE +# define NOSCROLL +# define NOTEXTMETRIC +# define NOWH +# define NOWINOFFSETS +# define NOCOMM +# define NOKANJI +# define NOHELP +# define NOPROFILER +# define NODEFERWINDOWPOS +# define NOMCX +# define NOCRYPT +# define NOMETAFILE +# define NOSERVICE +# define NOSOUND +# endif + +# define COBJMACROS +# define CINTERFACE + +# define STRICT +# define WIN32_NO_STATUS + +# ifdef __INTELLISENSE__ +# undef __cplusplus +# endif + +// attempt to make vxkex build with newer sdk's as well. +// no guarantees. if you install the win10 sdk and it doesn't build, tough luck. +// don't ask me to make shit build on your windows 11 with newest SDK. +# define _WIN32_WINNT 0x0601 + +# include +# include +# include + +# ifdef KEX_TARGET_TYPE_SYS +# include +# endif + +# ifdef __INTELLISENSE__ +# undef NULL +# define NULL 0 +# endif + +# if defined(KEX_ENV_WIN32) && !defined(NOUSER) + // Generally speaking we import from SHLWAPI only for the Path* + // functions. In the future we will dogfood our own PathCch* functions + // and avoid importing from SHLWAPI altogether. + + // SHLWAPI string functions are EXTREMELY slow. Do not use them, ever. +# define NO_SHLWAPI_STRFCNS + + // Ok, we'll make an exception for StrFormatByteSizeW -_- +# define StrFormatByteSize StrFormatByteSizeW + PWSTR StrFormatByteSizeW(LONGLONG qdw, PWSTR pszBuf, UINT cchBuf); + +# define NO_SHLWAPI_ISOS +# define NO_SHLWAPI_STREAM +# define NO_SHLWAPI_HTTP +# define NO_SHLWAPI_GDI +# define NO_SHLWAPI_STOPWATCH +# pragma comment(lib, "shlwapi.lib") +# include +# endif + +// Some bullshit warning about a "deprecated" function in intrin.h +// get rid of the stupid warning +# pragma warning(push) +# pragma warning(disable:4995) +# include +# pragma warning(pop) + +# include +# include + +# if defined(KEX_ENV_WIN32) && !defined(KEX_TARGET_TYPE_LIB) +# include +# include +# include +# endif + +# include + +# ifdef KEX_TARGET_TYPE_SYS +# include +# else +# include +# include +# include +# endif +#pragma endregion + +#pragma region Extended Language Constructs +# define try __try +# define except __except +# define finally __finally +# define leave __leave +# define throw(Status) RtlRaiseStatus(Status) +# define asm __asm + +# ifndef until +# define until(Condition) while (!(Condition)) +# endif + +# define unless(Condition) if (!(Condition)) +# define ReturnAddress _ReturnAddress + +# define PopulationCount16 __popcnt16 +# define PopulationCount __popcnt +# define PopulationCount64 __popcnt64 +#pragma endregion + +#pragma region Convenience Macros +// +// Convert a HRESULT code to a Win32 error code. +// Note that not all HRESULT codes can be mapped to a valid Win32 error code. +// +# define WIN32_FROM_HRESULT(x) (HRESULT_CODE(x)) + +# define LODWORD(ull) ((ULONG) (ull)) +# define HIDWORD(ull) ((ULONG) ((ULONGLONG) (ull) >> 32)) + +// +// Convert a relative virtual address (e.g. as found in PE image files) to a +// real virtual address which can be read, written, dereferenced etc. +// VA_TO_RVA does the opposite. +// +# define RVA_TO_VA(base, rva) ((PVOID) (((PBYTE) (base)) + (rva))) +# define VA_TO_RVA(base, va) ((ULONG_PTR) (((PBYTE) (va)) - ((PBYTE) (base)))) + +// +// Convert a boolean to a string which can be displayed to the user. +// +# define BOOLEAN_AS_STRING(b) ((b) ? L"TRUE" : L"FALSE") + +// +// Lookup an entry in a static entry table with bounds clamping. +// +# define ARRAY_LOOKUP_BOUNDS_CHECKED(Array, Index) Array[max(0, min((Index), ARRAYSIZE(Array) - 1))] + +// +// Convert a byte count to a character count (assuming a character is +// 2 bytes long, as it always is when dealing with windows unicode strings) +// and vice versa. +// +# define CB_TO_CCH(Cb) ((Cb) >> 1) +# define CCH_TO_CB(Cch) ((Cch) << 1) + +// +// Check that a kernel handle is not NULL or INVALID_HANDLE_VALUE. +// Keep in mind that NtCurrentProcess() will not be valid if checked with +// this macro, so you will have to special-case it in any code that uses +// process handles. +// +# define VALID_HANDLE(Handle) \ + (((Handle) != NULL) && \ + ((Handle) != INVALID_HANDLE_VALUE) && \ + !(((ULONG_PTR) (Handle)) & 3) && \ + (((ULONG_PTR) (Handle)) <= ULONG_MAX)) + +# define KexDebugCheckpoint() if (KexIsDebugBuild && NtCurrentPeb()->BeingDebugged) __debugbreak() + +# define InterlockedIncrement16 _InterlockedIncrement16 +# define InterlockedDecrement16 _InterlockedDecrement16 +#pragma endregion \ No newline at end of file diff --git a/00-Common Headers/KexComp.h b/00-Common Headers/KexComp.h new file mode 100644 index 0000000..29dcaae --- /dev/null +++ b/00-Common Headers/KexComp.h @@ -0,0 +1,49 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// KexComp.h +// +// Abstract: +// +// Defines compiler settings for VxKex projects. +// +// Author: +// +// vxiiduu (30-Sep-2022) +// +// Revision History: +// +// vxiiduu 30-Sep-2022 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#ifdef _DEBUG +# pragma optimize("", off) +#else +# pragma optimize("y", off) +# pragma optimize("gs", on) +#endif + +// +// We can use stack checking in VxKex because NTDLL exports the __chkstk +// symbol in both x86 and x64. +// +#ifdef _DEBUG +# pragma check_stack(on) +#else +# pragma check_stack(off) +#endif + +// +// Disable runtime checking. These features require the CRT, +// which we do not use. +// +#pragma runtime_checks("", off) + +// +// Note: You still need to disable /GS (buffer security check) in the project +// configuration, because unfortunately, there is no pragma which can do this. +// \ No newline at end of file diff --git a/00-Common Headers/KexCpu.h b/00-Common Headers/KexCpu.h new file mode 100644 index 0000000..36ac55c --- /dev/null +++ b/00-Common Headers/KexCpu.h @@ -0,0 +1,86 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// KexCpu.h +// +// Abstract: +// +// Contains structure definitions for CPU-related bit flags and +// registers. +// +// Author: +// +// vxiiduu (30-Sep-2022) +// +// Environment: +// +// Any environment. +// +// Revision History: +// +// vxiiduu 30-Sep-2022 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#pragma once +#include + +// Debug Status register +typedef struct _DR6 { + union { + ULONG_PTR Entire; + + struct { + UCHAR B0 : 1; + UCHAR B1 : 1; + UCHAR B2 : 1; + UCHAR B3 : 1; + USHORT Reserved1 : 9; + UCHAR BD : 1; + UCHAR BS : 1; + UCHAR BT : 1; + UCHAR RTM : 1; + USHORT Reserved2 : 15; +#ifdef _M_X64 + ULONG Reserved3 : 32; +#endif + }; + }; +} DR6; + +// Debug Control register +typedef struct _DR7 { + union { + ULONG_PTR Entire; + + struct { + UCHAR L0 : 1; + UCHAR G0 : 1; + UCHAR L1 : 1; + UCHAR G1 : 1; + UCHAR L2 : 1; + UCHAR G2 : 1; + UCHAR L3 : 1; + UCHAR G3 : 1; + UCHAR LE : 1; + UCHAR GE : 1; + UCHAR Reserved1 : 1; // set to 1 + UCHAR RTM : 1; + UCHAR Reserved2 : 1; // set to 0 + UCHAR GD : 1; + UCHAR Reserved3 : 2; // both set to 0 + UCHAR RW0 : 2; + UCHAR LEN0 : 2; + UCHAR RW1 : 2; + UCHAR LEN1 : 2; + UCHAR RW2 : 2; + UCHAR LEN2 : 2; + UCHAR RW3 : 2; + UCHAR LEN3 : 2; +#ifdef _M_X64 + ULONG Reserved4 : 32; +#endif + }; + }; +} DR7; \ No newline at end of file diff --git a/00-Common Headers/KexDll.h b/00-Common Headers/KexDll.h new file mode 100644 index 0000000..3f3b063 --- /dev/null +++ b/00-Common Headers/KexDll.h @@ -0,0 +1,898 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// KexDll.h +// +// Abstract: +// +// VxKex base API +// +// Author: +// +// vxiiduu (11-Oct-2022) +// +// Revision History: +// +// vxiiduu 11-Oct-2022 Initial creation. +// vxiiduu 06-Nov-2022 Refactor and create KexLdr* section +// +/////////////////////////////////////////////////////////////////////////////// + +#pragma once +#include + +#ifndef KEXAPI +# pragma comment(lib, "KexDll.lib") +# define KEXAPI DECLSPEC_IMPORT +#endif + +#ifndef KEX_COMPONENT +# error You must define a Unicode component name as the KEX_COMPONENT macro. +#endif + +#pragma region Macros and Structure Definitions + +// +// Uncomment the macro definition to keep debug logging enabled in release +// builds. +// +// Note that this only affects debug logs made through the KexLogDebugEvent +// macro. +// +//#define RELEASE_DEBUGLOGS_ENABLED + +#define REG_RESTRICT_NONE (1 << REG_NONE) +#define REG_RESTRICT_SZ (1 << REG_SZ) +#define REG_RESTRICT_EXPAND_SZ (1 << REG_EXPAND_SZ) +#define REG_RESTRICT_BINARY (1 << REG_BINARY) +#define REG_RESTRICT_DWORD (1 << REG_DWORD) +#define REG_RESTRICT_DWORD_BE (1 << REG_DWORD_BIG_ENDIAN) +#define REG_RESTRICT_LINK (1 << REG_LINK) +#define REG_RESTRICT_MULTI_SZ (1 << REG_MULTI_SZ) +#define REG_RESTRICT_RESOURCE_LIST (1 << REG_RESOURCE_LIST) +#define REG_RESTRICT_FULL_RESOURCE_DESCRIPTOR (1 << REG_FULL_RESOURCE_DESCRIPTOR) +#define REG_RESTRICT_RESOURCE_REQUIREMENTS_LIST (1 << REG_RESOURCE_REQUIREMENTS_LIST) +#define REG_RESTRICT_QWORD (1 << REG_QWORD) + +#define LEGAL_REG_RESTRICT_MASK \ + (REG_RESTRICT_NONE | \ + REG_RESTRICT_SZ | \ + REG_RESTRICT_EXPAND_SZ | \ + REG_RESTRICT_BINARY | \ + REG_RESTRICT_DWORD | \ + REG_RESTRICT_DWORD_BE | \ + REG_RESTRICT_LINK | \ + REG_RESTRICT_MULTI_SZ | \ + REG_RESTRICT_RESOURCE_LIST | \ + REG_RESTRICT_FULL_RESOURCE_DESCRIPTOR | \ + REG_RESTRICT_RESOURCE_REQUIREMENTS_LIST | \ + REG_RESTRICT_QWORD) + +#define REG_RESTRICT_ANY LEGAL_REG_RESTRICT_MASK + +#define QUERY_KEY_MULTIPLE_VALUE_FAIL_FAST 1 + +#define QUERY_KEY_MULTIPLE_VALUE_VALID_MASK \ + (QUERY_KEY_MULTIPLE_VALUE_FAIL_FAST) + +#define KEX_RTL_STRING_MAPPER_CASE_INSENSITIVE_KEYS 1 +#define KEX_RTL_STRING_MAPPER_FLAGS_VALID_MASK (KEX_RTL_STRING_MAPPER_CASE_INSENSITIVE_KEYS) + +// +// When you define new custom NTSTATUS values, make sure to update the code +// in status.c to convert it into a string. +// + +#define NTSTATUS_SUCCESS (0x00000000L) +#define NTSTATUS_INFORMATIONAL (0x40000000L) +#define NTSTATUS_WARNING (0x80000000L) +#define NTSTATUS_ERROR (0xC0000000L) +#define NTSTATUS_CUSTOMER (0x20000000L) +#define DEFINE_KEX_NTSTATUS(Severity, Number) ((NTSTATUS) (NTSTATUS_CUSTOMER | Severity | Number)) + +// Remember to add entries to KexDll\status.c if you add more values. + +#define STATUS_USER_DISABLED DEFINE_KEX_NTSTATUS(NTSTATUS_INFORMATIONAL, 0) +#define STATUS_ALREADY_INITIALIZED DEFINE_KEX_NTSTATUS(NTSTATUS_INFORMATIONAL, 1) +#define STATUS_ALREADY_CONNECTED DEFINE_KEX_NTSTATUS(NTSTATUS_INFORMATIONAL, 2) + +#define STATUS_IMAGE_NO_IMPORT_DIRECTORY DEFINE_KEX_NTSTATUS(NTSTATUS_ERROR, 0) +#define STATUS_STRING_MAPPER_ENTRY_NOT_FOUND DEFINE_KEX_NTSTATUS(NTSTATUS_ERROR, 1) +#define STATUS_REG_DATA_TYPE_MISMATCH DEFINE_KEX_NTSTATUS(NTSTATUS_ERROR, 2) +#define STATUS_KEXDLL_INITIALIZATION_FAILURE DEFINE_KEX_NTSTATUS(NTSTATUS_ERROR, 3) +#define STATUS_VERSION_MISMATCH DEFINE_KEX_NTSTATUS(NTSTATUS_ERROR, 4) +#define STATUS_SOURCE_APPLICATION_MISMATCH DEFINE_KEX_NTSTATUS(NTSTATUS_ERROR, 5) +#define STATUS_TOO_MANY_INDICES DEFINE_KEX_NTSTATUS(NTSTATUS_ERROR, 6) +#define STATUS_INVALID_OPEN_MODE DEFINE_KEX_NTSTATUS(NTSTATUS_ERROR, 7) +#define STATUS_KEXDATA_NOT_INITIALIZED DEFINE_KEX_NTSTATUS(NTSTATUS_ERROR, 8) +#define STATUS_KEXSETUP_FAILURE DEFINE_KEX_NTSTATUS(NTSTATUS_ERROR, 9) +#define STATUS_IMAGE_SECTION_NOT_FOUND DEFINE_KEX_NTSTATUS(NTSTATUS_ERROR, 10) +#define STATUS_DLL_NOT_IN_SYSTEM_ROOT DEFINE_KEX_NTSTATUS(NTSTATUS_ERROR, 11) + +#define KEXDATA_FLAG_PROPAGATED 1 // Indicates that this process was spawned from a VxKex-enabled parent +#define KEXDATA_FLAG_IFEO_OPTIONS_PRESENT 2 // Indicates that this process has VxKex options set in IFEO +#define KEXDATA_FLAG_MSIEXEC 4 // Indicates that this process is %SystemRoot%\system32\msiexec.exe +#define KEXDATA_FLAG_ENABLED_FOR_MSI 8 // Indicates that this MSI has VxKex enabled. +#define KEXDATA_FLAG_DISABLE_LOGGING 16 // Log files are not to be created. +#define KEXDATA_FLAG_CHROMIUM 32 // This is a Chromium-based application (Chrome, Edge, Electron, QtWebEngine, etc.) +#define KEXDATA_FLAG_KB2533623_PRESENT 64 // Indicates the DllDirectory APIs are available + +#define KEX_STRONGSPOOF_SHAREDUSERDATA 1 +#define KEX_STRONGSPOOF_REGISTRY 2 +#define KEX_STRONGSPOOF_VALID_MASK (KEX_STRONGSPOOF_SHAREDUSERDATA | KEX_STRONGSPOOF_REGISTRY) + +typedef struct _KEX_RTL_QUERY_KEY_MULTIPLE_VARIABLE_TABLE_ENTRY { + IN CONST UNICODE_STRING ValueName; + OUT NTSTATUS Status; + IN OUT ULONG ValueDataCb; + + // + // If you don't want to store data outside the structure, and if + // you are querying value data that you know should be 8 bytes or + // less, then you can set ValueData to point to ValueDataRawBytes. + // Make sure you set ValueDataCb and ValueDataTypeRestrict as + // appropriate. + // + union { + OUT PVOID ValueData; + OUT ULONG ValueDataAsDword; + OUT ULONGLONG ValueDataAsQword; + OUT BYTE ValueDataRawBytes[8]; + }; + + IN ULONG ValueDataTypeRestrict; + OUT ULONG ValueDataType; +} TYPEDEF_TYPE_NAME(KEX_RTL_QUERY_KEY_MULTIPLE_VARIABLE_TABLE_ENTRY); + +typedef struct _KEX_RTL_STRING_MAPPER { + RTL_DYNAMIC_HASH_TABLE HashTable; + ULONG Flags; +} TYPEDEF_TYPE_NAME(KEX_RTL_STRING_MAPPER); + +typedef struct _KEX_RTL_STRING_MAPPER_ENTRY { + UNICODE_STRING Key; + UNICODE_STRING Value; +} TYPEDEF_TYPE_NAME(KEX_RTL_STRING_MAPPER_ENTRY); + +typedef struct _KEX_RTL_STRING_MAPPER_HASH_TABLE_ENTRY { + RTL_DYNAMIC_HASH_TABLE_ENTRY HashTableEntry; + UNICODE_STRING Key; + UNICODE_STRING Value; +} TYPEDEF_TYPE_NAME(KEX_RTL_STRING_MAPPER_HASH_TABLE_ENTRY); + +#define VXLL_VERSION 1 + +typedef enum _VXLLOGINFOCLASS { + LogLibraryVersion, + LogNumberOfCriticalEvents, + LogNumberOfErrorEvents, + LogNumberOfWarningEvents, + LogNumberOfInformationEvents, + LogNumberOfDetailEvents, + LogNumberOfDebugEvents, + LogTotalNumberOfEvents, + LogSourceApplication, + MaxLogInfoClass +} VXLLOGINFOCLASS; + +typedef enum _VXLSEVERITY { + LogSeverityInvalidValue = -1, + LogSeverityCritical, + LogSeverityError, + LogSeverityWarning, + LogSeverityInformation, + LogSeverityDetail, + LogSeverityDebug, + LogSeverityMaximumValue +} VXLSEVERITY; + +// All UNICODE_STRINGs in VXLLOGENTRY are guaranteed to be null terminated. +// So you can pass the buffers directly to Win32 functions. +typedef struct _VXLLOGENTRY { + UNICODE_STRING TextHeader; + UNICODE_STRING Text; + UCHAR SourceComponentIndex; + UCHAR SourceFileIndex; + UCHAR SourceFunctionIndex; + ULONG SourceLine; + CLIENT_ID ClientId; + VXLSEVERITY Severity; + SYSTEMTIME Time; +} TYPEDEF_TYPE_NAME(VXLLOGENTRY); + +typedef struct _VXLLOGFILEHEADER { + CHAR Magic[4]; + ULONG Version; + ULONG EventSeverityTypeCount[LogSeverityMaximumValue]; + WCHAR SourceApplication[32]; + WCHAR SourceComponents[64][16]; + WCHAR SourceFiles[128][16]; + WCHAR SourceFunctions[256][64]; + BOOLEAN Dirty; +} TYPEDEF_TYPE_NAME(VXLLOGFILEHEADER); + +typedef struct _VXLLOGFILEENTRY { + union { + FILETIME Time; + LONGLONG Time64; + }; + + // Do not directly use CLIENT_ID here since its size varies with + // bitness. (contains HANDLE members) + ULONG ProcessId; + ULONG ThreadId; + + VXLSEVERITY Severity; + ULONG SourceLine; + UCHAR SourceComponentIndex; + UCHAR SourceFileIndex; + UCHAR SourceFunctionIndex; + + USHORT TextHeaderCch; + USHORT TextCch; + + WCHAR Text[]; +} TYPEDEF_TYPE_NAME(VXLLOGFILEENTRY); + +// index cache (EntryIndexToFileOffset) makes reading and sorting the +// log file faster. Without it, writing the log file is very fast but +// read and export performance is unacceptably bad. +typedef struct _VXLCONTEXT { + RTL_SRWLOCK Lock; + HANDLE FileHandle; + PULONG EntryIndexToFileOffset; // only populated when file is opened for READ ONLY, otherwise NULL + + union { + PVXLLOGFILEHEADER Header; + PBYTE MappedFile; // only populated in READ ONLY mode, otherwise NULL + PVOID MappedSection; // ^ + }; + + ULONG OpenMode; // GENERIC_READ or GENERIC_WRITE +} TYPEDEF_TYPE_NAME(VXLCONTEXT); + +typedef PVXLCONTEXT TYPEDEF_TYPE_NAME(VXLHANDLE); + +typedef enum _KEX_WIN_VER_SPOOF { + WinVerSpoofNone, // do not spoof + WinVerSpoofWin7, // Win7 SP1 + WinVerSpoofWin8, + WinVerSpoofWin8Point1, + WinVerSpoofWin10, + WinVerSpoofWin11, + WinVerSpoofMax // should always be the last value +} TYPEDEF_TYPE_NAME(KEX_WIN_VER_SPOOF); + +// +// These variable names are present under the IFEO key for each executable +// with a KEX_ prefix. For example: +// +// HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ +// Image File Execution Options\application.exe\{id}\KEX_WinVerSpoof +// +// The KEX_IFEO_PARAMETERS structure may never contain members whose size +// varies by processor architecture, because it may be copied verbatim between +// processes during propagation. (See propagte.c.) +// + +typedef struct _KEX_IFEO_PARAMETERS { + ULONG DisableForChild; + ULONG DisableAppSpecific; + KEX_WIN_VER_SPOOF WinVerSpoof; + ULONG StrongVersionSpoof; // KEX_STRONGSPOOF_* +} TYPEDEF_TYPE_NAME(KEX_IFEO_PARAMETERS); + +// +// A KEX_PROCESS_DATA structure for the current process can be obtained +// outside of KexDll by calling the exported function KexDataInitialize. +// + +typedef struct _KEX_PROCESS_DATA { + ULONG Flags; // KEXDATA_FLAG_* + KEX_IFEO_PARAMETERS IfeoParameters; + UNICODE_STRING WinDir; // e.g. "C:\Windows" + UNICODE_STRING KexDir; // e.g. "C:\Program Files\VxKex" + UNICODE_STRING LogDir; + UNICODE_STRING Kex3264DirPath; // e.g. "C:\Program Files\VxKex\Kex64;" + UNICODE_STRING ImageBaseName; // e.g. program.exe + VXLHANDLE LogHandle; + PVOID KexDllBase; + PVOID SystemDllBase; // NTDLL base address + PVOID NativeSystemDllBase; + PVOID BaseDllBase; // Kernel32 base address + HANDLE BaseNamedObjects; // object directory handle + HANDLE UntrustedNamedObjects; +} TYPEDEF_TYPE_NAME(KEX_PROCESS_DATA); + +#pragma endregion + +#pragma region Kex* functions + +KEXAPI NTSTATUS NTAPI KexInitializePropagation( + VOID); + +KEXAPI NTSTATUS NTAPI KexDataInitialize( + OUT PPKEX_PROCESS_DATA KexDataOut OPTIONAL); + +#pragma endregion + +#pragma region KexRtl* functions + +KEXAPI NTSTATUS NTAPI KexRtlPathFindFileName( + IN PCUNICODE_STRING Path, + OUT PUNICODE_STRING FileName); + +KEXAPI NTSTATUS NTAPI KexRtlPathRemoveExtension( + IN PCUNICODE_STRING Path, + OUT PUNICODE_STRING PathWithoutExtension); + +KEXAPI BOOLEAN NTAPI KexRtlPathReplaceIllegalCharacters( + IN OUT PUNICODE_STRING Path, + IN WCHAR ReplacementCharacter OPTIONAL, + IN BOOLEAN AllowPathSeparators); + +KEXAPI NTSTATUS NTAPI KexRtlGetProcessImageBaseName( + OUT PUNICODE_STRING FileName); + +KEXAPI NTSTATUS NTAPI KexRtlQueryKeyValueData( + IN HANDLE KeyHandle, + IN PCUNICODE_STRING ValueName, + IN OUT PULONG ValueDataCb, + OUT PVOID ValueData OPTIONAL, + IN ULONG ValueDataTypeRestrict, + OUT PULONG ValueDataType OPTIONAL); + +KEXAPI NTSTATUS NTAPI KexRtlQueryKeyMultipleValueData( + IN HANDLE KeyHandle, + IN PKEX_RTL_QUERY_KEY_MULTIPLE_VARIABLE_TABLE_ENTRY QueryTable, + IN OUT PULONG NumberOfQueryTableElements, + IN ULONG Flags); + +KEXAPI BOOLEAN NTAPI KexRtlUnicodeStringEndsWith( + IN PCUNICODE_STRING String, + IN PCUNICODE_STRING EndsWith, + IN BOOLEAN CaseInsensitive); + +KEXAPI PWCHAR NTAPI KexRtlFindUnicodeSubstring( + PCUNICODE_STRING Haystack, + PCUNICODE_STRING Needle, + BOOLEAN CaseInsensitive); + +KEXAPI VOID NTAPI KexRtlAdvanceUnicodeString( + OUT PUNICODE_STRING String, + IN USHORT AdvanceCb); + +KEXAPI VOID NTAPI KexRtlRetreatUnicodeString( + OUT PUNICODE_STRING String, + IN USHORT RetreatCb); + +KEXAPI NTSTATUS NTAPI KexRtlShiftUnicodeString( + IN OUT PUNICODE_STRING String, + IN USHORT ShiftCch, + IN WCHAR LeftFillCharacter OPTIONAL); + +KEXAPI ULONG NTAPI KexRtlRemoteProcessBitness( + IN HANDLE ProcessHandle); + +KEXAPI NTSTATUS NTAPI KexRtlWriteProcessMemory( + IN HANDLE ProcessHandle, + IN ULONG_PTR Destination, + IN PVOID Source, + IN SIZE_T Cb); + +KEXAPI NTSTATUS NTAPI KexRtlCreateDirectoryRecursive( + OUT PHANDLE DirectoryHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN ULONG ShareAccess); + +KEXAPI PCWSTR NTAPI KexRtlNtStatusToString( + IN NTSTATUS Status); + +KEXAPI NTSTATUS NTAPI KexRtlCreateStringMapper( + OUT PPKEX_RTL_STRING_MAPPER StringMapper, + IN ULONG Flags OPTIONAL); + +KEXAPI NTSTATUS NTAPI KexRtlDeleteStringMapper( + IN PPKEX_RTL_STRING_MAPPER StringMapper); + +KEXAPI NTSTATUS NTAPI KexRtlInsertEntryStringMapper( + IN PKEX_RTL_STRING_MAPPER StringMapper, + IN PCUNICODE_STRING Key, + IN PCUNICODE_STRING Value); + +KEXAPI NTSTATUS NTAPI KexRtlLookupEntryStringMapper( + IN PKEX_RTL_STRING_MAPPER StringMapper, + IN PCUNICODE_STRING Key, + OUT PUNICODE_STRING Value OPTIONAL); + +KEXAPI NTSTATUS NTAPI KexRtlRemoveEntryStringMapper( + IN PKEX_RTL_STRING_MAPPER StringMapper, + IN PCUNICODE_STRING Key); + +KEXAPI NTSTATUS NTAPI KexRtlApplyStringMapper( + IN PKEX_RTL_STRING_MAPPER StringMapper, + IN OUT PUNICODE_STRING KeyToValue); + +KEXAPI NTSTATUS NTAPI KexRtlInsertMultipleEntriesStringMapper( + IN PKEX_RTL_STRING_MAPPER StringMapper, + IN CONST KEX_RTL_STRING_MAPPER_ENTRY Entries[], + IN ULONG EntryCount); + +KEXAPI NTSTATUS NTAPI KexRtlLookupMultipleEntriesStringMapper( + IN PKEX_RTL_STRING_MAPPER StringMapper, + IN OUT KEX_RTL_STRING_MAPPER_ENTRY Entries[], + IN ULONG EntryCount); + +KEXAPI NTSTATUS NTAPI KexRtlBatchApplyStringMapper( + IN PKEX_RTL_STRING_MAPPER StringMapper, + IN OUT UNICODE_STRING KeyToValue[], + IN ULONG KeyToValueCount); + +KEXAPI PIMAGE_SECTION_HEADER NTAPI KexRtlSectionTableFromRva( + IN PIMAGE_NT_HEADERS NtHeaders, + IN ULONG ImageRva); + +KEXAPI NTSTATUS NTAPI KexRtlNullTerminateUnicodeString( + IN PUNICODE_STRING String); + +KEXAPI NTSTATUS NTAPI KexRtlWaitOnAddress( + IN volatile VOID *Address, + IN PVOID CompareAddress, + IN SIZE_T AddressSize, + IN PLARGE_INTEGER Timeout OPTIONAL); + +KEXAPI VOID NTAPI KexRtlWakeByAddressSingle( + IN PVOID Address); + +KEXAPI VOID NTAPI KexRtlWakeByAddressAll( + IN PVOID Address); + +KEXAPI NTSTATUS NTAPI KexRtlWow64GetProcessMachines( + IN HANDLE ProcessHandle, + OUT PUSHORT ProcessMachine, + OUT PUSHORT NativeMachine OPTIONAL); + +KEXAPI VOID NTAPI KexRtlSetBit( + IN PRTL_BITMAP BitmapHeader, + IN ULONG BitNumber); + +KEXAPI VOID NTAPI KexRtlClearBit( + IN PRTL_BITMAP BitmapHeader, + IN ULONG BitNumber); + +KEXAPI NTSTATUS NTAPI KexRtlCreateUntrustedDirectoryObject( + OUT PHANDLE DirectoryHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes); + +#ifdef KEX_ARCH_X64 +# define KexRtlCurrentProcessBitness() (64) +#else +# define KexRtlCurrentProcessBitness() (32) +#endif + +#ifdef KEX_ARCH_X64 +# define KexRtlOperatingSystemBitness() (64) +#else +# define KexRtlOperatingSystemBitness() (SharedUserData->SystemCall != 0 ? 32 : 64) +#endif + +#define KexRtlUpdateNullTerminatedUnicodeStringLength(UnicodeString) ((UnicodeString)->Length = (USHORT) (wcslen((UnicodeString)->Buffer) << 1)) +#define KexRtlUpdateNullTerminatedAnsiStringLength(AnsiString) ((AnsiString)->Length = (USHORT) wcslen((AnsiString)->Buffer)) +#define KexRtlUnicodeStringCch(UnicodeString) ((UnicodeString)->Length / sizeof(WCHAR)) +#define KexRtlUnicodeStringBufferCch(UnicodeString) ((UnicodeString)->MaximumLength / sizeof(WCHAR)) +#define KexRtlAnsiStringCch(AnsiString) ((AnsiString)->Length) +#define KexRtlAnsiStringBufferCch(AnsiString) ((AnsiString)->MaximumLength) +#define KexRtlEndOfUnicodeString(UnicodeString) ((UnicodeString)->Buffer + KexRtlUnicodeStringCch(UnicodeString)) +#define KexRtlCopyMemory(Destination, Source, Cb) __movsb((PUCHAR) (Destination), (PUCHAR) (Source), (Cb)) + +#define ForEachArrayItem(Array, Index) for (Index = 0; Index < ARRAYSIZE(Array); ++Index) + +#pragma endregion + +#pragma region KexLdr* functions + +KEXAPI PVOID NTAPI KexLdrGetSystemDllBase( + VOID); + +KEXAPI PVOID NTAPI KexLdrGetRemoteSystemDllBase( + IN HANDLE ProcessHandle); + +KEXAPI PVOID NTAPI KexLdrGetNativeSystemDllBase( + VOID); + +KEXAPI NTSTATUS NTAPI KexLdrMiniGetProcedureAddress( + IN PVOID DllBase, + IN PCSTR ProcedureName, + OUT PPVOID ProcedureAddress); + +KEXAPI NTSTATUS NTAPI KexLdrFindDllInitRoutine( + IN PVOID DllBase, + OUT PPVOID InitRoutine); + +NTSTATUS NTAPI KexLdrGetDllFullName( + IN PVOID DllBase OPTIONAL, + OUT PUNICODE_STRING DllFullPath); + +KEXAPI NTSTATUS NTAPI KexLdrGetDllFullNameFromAddress( + IN PVOID Address, + OUT PUNICODE_STRING DllFullPath); + +KEXAPI NTSTATUS NTAPI KexLdrProtectImageImportSection( + IN PVOID ImageBase, + IN ULONG PageProtection, + OUT PULONG OldProtection); + +#pragma endregion + +#pragma region KexHk* functions + +#ifdef KEX_ARCH_X64 +# define BASIC_HOOK_LENGTH 14 +# define BASIC_HOOK_DESTINATION_OFFSET 6 +#else +# define BASIC_HOOK_LENGTH 6 +# define BASIC_HOOK_DESTINATION_OFFSET 1 +#endif + +typedef struct _KEX_BASIC_HOOK_CONTEXT { + PVOID OriginalApiAddress; + BYTE OriginalInstructions[BASIC_HOOK_LENGTH]; +} TYPEDEF_TYPE_NAME(KEX_BASIC_HOOK_CONTEXT); + +KEXAPI NTSTATUS NTAPI KexHkInstallBasicHook( + IN PVOID ApiAddress, + IN PVOID RedirectedAddress, + OUT PKEX_BASIC_HOOK_CONTEXT HookContext OPTIONAL); + +KEXAPI NTSTATUS NTAPI KexHkRemoveBasicHook( + IN PKEX_BASIC_HOOK_CONTEXT HookContext); + +#pragma endregion + +#pragma region Ash* functions + +KEXAPI BOOLEAN NTAPI AshExeBaseNameIs( + IN PCWSTR ExeName); + +KEXAPI BOOLEAN NTAPI AshModuleBaseNameIs( + IN PVOID AddressInsideModule, + IN PCWSTR ModuleName); + +KEXAPI BOOLEAN NTAPI AshModuleIsWindowsModule( + IN PVOID AddressInsideModule); + +#pragma endregion + +#pragma region Vxl* functions + +// +// vxlopcl.c +// + +KEXAPI NTSTATUS NTAPI VxlOpenLog( + OUT PVXLHANDLE LogHandle, + IN PUNICODE_STRING SourceApplication OPTIONAL, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN ACCESS_MASK DesiredAccess, + IN ULONG CreateDisposition); + +KEXAPI NTSTATUS NTAPI VxlCloseLog( + IN OUT PVXLHANDLE LogHandle); + +// +// vxlquery.c +// + +KEXAPI NTSTATUS NTAPI VxlQueryInformationLog( + IN VXLHANDLE LogHandle, + IN VXLLOGINFOCLASS LogInformationClass, + OUT PVOID Buffer OPTIONAL, + IN OUT PULONG BufferSize); + +// +// vxlwrite.c +// + +#define VxlWriteLog(LogHandle, SourceComponent, Severity, ...) \ + VxlWriteLogEx( \ + LogHandle, \ + SourceComponent, \ + __FILEW__, \ + __LINE__, \ + __FUNCTIONW__, \ + Severity, \ + __VA_ARGS__) + +#define KexLogEvent(Severity, ...) \ + VxlWriteLog(KexData->LogHandle, KEX_COMPONENT, Severity, __VA_ARGS__) + +#define KexLogCriticalEvent(...) KexLogEvent(LogSeverityCritical, __VA_ARGS__) +#define KexLogErrorEvent(...) KexLogEvent(LogSeverityError, __VA_ARGS__) +#define KexLogWarningEvent(...) KexLogEvent(LogSeverityWarning, __VA_ARGS__) +#define KexLogInformationEvent(...) KexLogEvent(LogSeverityInformation, __VA_ARGS__) +#define KexLogDetailEvent(...) KexLogEvent(LogSeverityDetail, __VA_ARGS__) + +#if defined(_DEBUG) || defined(RELEASE_DEBUGLOGS_ENABLED) +# define KexLogDebugEvent(...) KexLogEvent(LogSeverityDebug, __VA_ARGS__) +#else +# define KexLogDebugEvent(...) +#endif + +KEXAPI NTSTATUS CDECL VxlWriteLogEx( + IN VXLHANDLE LogHandle OPTIONAL, + IN PCWSTR SourceComponent OPTIONAL, + IN PCWSTR SourceFile OPTIONAL, + IN ULONG SourceLine, + IN PCWSTR SourceFunction OPTIONAL, + IN VXLSEVERITY Severity, + IN PCWSTR Format, + IN ...); + +// +// vxlread.c +// + +KEXAPI NTSTATUS NTAPI VxlReadLog( + IN VXLHANDLE LogHandle, + IN ULONG LogEntryIndex, + OUT PVXLLOGENTRY Entry); + +KEXAPI NTSTATUS NTAPI VxlReadMultipleEntriesLog( + IN VXLHANDLE LogHandle, + IN ULONG LogEntryIndexStart, + IN ULONG LogEntryIndexEnd, + OUT PVXLLOGENTRY Entry[]); + +// +// vxlsever.c +// + +KEXAPI PCWSTR NTAPI VxlSeverityToText( + IN VXLSEVERITY Severity, + IN BOOLEAN LongDescription); + +// +// dllrewrt.c +// + +KEXAPI NTSTATUS NTAPI KexRewriteDllPath( + IN PCUNICODE_STRING DllPath, + OUT PUNICODE_STRING RewrittenDllName); + +// +// kexhe.c +// + +VOID KexMessageBox( + IN ULONG Flags, + IN PCWSTR Caption OPTIONAL, + IN PCWSTR Message OPTIONAL); + +VOID KexMessageBoxF( + IN ULONG Flags, + IN PCWSTR Caption OPTIONAL, + IN PCWSTR Message OPTIONAL, + IN ...); + +// +// cpiwbypa.c +// + +KEXAPI NTSTATUS NTAPI KexPatchCpiwSubsystemVersionCheck( + VOID); + +// +// System Service Extensions/Hooks +// + +NTSTATUS NTAPI Ext_NtQueryInformationThread( + IN HANDLE ThreadHandle, + IN THREADINFOCLASS ThreadInformationClass, + OUT PVOID ThreadInformation, + IN ULONG ThreadInformationLength, + OUT PULONG ReturnLength OPTIONAL); + +NTSTATUS NTAPI Ext_NtSetInformationThread( + IN HANDLE ThreadHandle, + IN THREADINFOCLASS ThreadInformationClass, + IN PVOID ThreadInformation, + IN ULONG ThreadInformationLength); + +NTSTATUS NTAPI Ext_NtNotifyChangeKey( + IN HANDLE KeyHandle, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN ULONG CompletionFilter, + IN BOOLEAN WatchTree, + OUT PVOID Buffer OPTIONAL, + IN ULONG BufferSize, + IN BOOLEAN Asynchronous); + +NTSTATUS NTAPI Ext_NtNotifyChangeMultipleKeys( + IN HANDLE MasterKeyHandle, + IN ULONG Count OPTIONAL, + IN OBJECT_ATTRIBUTES SlaveObjects[] OPTIONAL, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN ULONG CompletionFilter, + IN BOOLEAN WatchTree, + OUT PVOID Buffer OPTIONAL, + IN ULONG BufferSize, + IN BOOLEAN Asynchronous); + +NTSTATUS NTAPI Ext_NtCreateSection( + OUT PHANDLE SectionHandle, + IN ULONG DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, + IN PLONGLONG MaximumSize OPTIONAL, + IN ULONG PageAttributes, + IN ULONG SectionAttributes, + IN HANDLE FileHandle OPTIONAL); + +NTSTATUS NTAPI Ext_NtQueryInformationProcess( + IN HANDLE ProcessHandle, + IN PROCESSINFOCLASS ProcessInformationClass, + OUT PVOID ProcessInformation, + IN ULONG ProcessInformationLength, + OUT PULONG ReturnLength OPTIONAL); + +KEXAPI NTSTATUS NTAPI Ext_NtAssignProcessToJobObject( + IN HANDLE JobHandle, + IN HANDLE ProcessHandle); + +#pragma endregion + +#pragma region KexNt* functions + +KEXAPI NTSTATUS NTAPI KexNtQuerySystemTime( + OUT PLONGLONG CurrentTime); + +KEXAPI NTSTATUS NTAPI KexNtCreateUserProcess( + OUT PHANDLE ProcessHandle, + OUT PHANDLE ThreadHandle, + IN ACCESS_MASK ProcessDesiredAccess, + IN ACCESS_MASK ThreadDesiredAccess, + IN POBJECT_ATTRIBUTES ProcessObjectAttributes OPTIONAL, + IN POBJECT_ATTRIBUTES ThreadObjectAttributes OPTIONAL, + IN ULONG ProcessFlags, + IN ULONG ThreadFlags, + IN PRTL_USER_PROCESS_PARAMETERS ProcessParameters, + IN OUT PPS_CREATE_INFO CreateInfo, + IN PPS_ATTRIBUTE_LIST AttributeList OPTIONAL); + +KEXAPI NTSTATUS NTAPI KexNtProtectVirtualMemory( + IN HANDLE ProcessHandle, + IN OUT PPVOID BaseAddress, + IN OUT PSIZE_T RegionSize, + IN ULONG NewProtect, + OUT PULONG OldProtect); + +KEXAPI NTSTATUS NTAPI KexNtAllocateVirtualMemory( + IN HANDLE ProcessHandle, + IN OUT PVOID *BaseAddress, + IN ULONG_PTR ZeroBits, + IN OUT PSIZE_T RegionSize, + IN ULONG AllocationType, + IN ULONG Protect); + +KEXAPI NTSTATUS NTAPI KexNtQueryVirtualMemory( + IN HANDLE ProcessHandle, + IN PVOID BaseAddress OPTIONAL, + IN MEMINFOCLASS MemoryInformationClass, + OUT PVOID MemoryInformation, + IN SIZE_T MemoryInformationLength, + OUT PSIZE_T ReturnLength OPTIONAL); + +KEXAPI NTSTATUS NTAPI KexNtFreeVirtualMemory( + IN HANDLE ProcessHandle, + IN OUT PVOID *BaseAddress, + IN OUT PSIZE_T RegionSize, + IN ULONG FreeType); + +KEXAPI NTSTATUS NTAPI KexNtOpenKeyEx( + OUT PHANDLE KeyHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN ULONG OpenOptions); + +KEXAPI NTSTATUS NTAPI KexNtQueryObject( + IN HANDLE ObjectHandle, + IN OBJECT_INFORMATION_CLASS ObjectInformationClass, + OUT PVOID ObjectInformation, + IN ULONG Length, + OUT PULONG ReturnLength OPTIONAL); + +KEXAPI NTSTATUS NTAPI KexNtOpenFile( + OUT PHANDLE FileHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN ULONG ShareAccess, + IN ULONG OpenOptions); + +KEXAPI NTSTATUS NTAPI KexNtWriteFile( + IN HANDLE FileHandle, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN PVOID Buffer, + IN ULONG Length, + IN PLONGLONG ByteOffset OPTIONAL, + IN PULONG Key OPTIONAL); + +KEXAPI NTSTATUS NTAPI KexNtRaiseHardError( + IN NTSTATUS ErrorStatus, + IN ULONG NumberOfParameters, + IN ULONG UnicodeStringParameterMask, + IN PULONG_PTR Parameters, + IN ULONG ValidResponseOptions, + OUT PULONG Response); + +KEXAPI NTSTATUS NTAPI KexNtQueryInformationThread( + IN HANDLE ThreadHandle, + IN THREADINFOCLASS ThreadInformationClass, + OUT PVOID ThreadInformation, + IN ULONG ThreadInformationLength, + OUT PULONG ReturnLength OPTIONAL); + +KEXAPI NTSTATUS NTAPI KexNtSetInformationThread( + IN HANDLE ThreadHandle, + IN THREADINFOCLASS ThreadInformationClass, + IN PVOID ThreadInformation, + IN ULONG ThreadInformationLength); + +KEXAPI NTSTATUS NTAPI KexNtNotifyChangeKey( + IN HANDLE KeyHandle, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN ULONG CompletionFilter, + IN BOOLEAN WatchTree, + OUT PVOID Buffer OPTIONAL, + IN ULONG BufferSize, + IN BOOLEAN Asynchronous); + +KEXAPI NTSTATUS NTAPI KexNtNotifyChangeMultipleKeys( + IN HANDLE MasterKeyHandle, + IN ULONG Count OPTIONAL, + IN OBJECT_ATTRIBUTES SlaveObjects[] OPTIONAL, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN ULONG CompletionFilter, + IN BOOLEAN WatchTree, + OUT PVOID Buffer OPTIONAL, + IN ULONG BufferSize, + IN BOOLEAN Asynchronous); + +KEXAPI NTSTATUS NTAPI KexNtCreateSection( + OUT PHANDLE SectionHandle, + IN ULONG DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, + IN PLONGLONG MaximumSize OPTIONAL, + IN ULONG PageAttributes, + IN ULONG SectionAttributes, + IN HANDLE FileHandle OPTIONAL); + +KEXAPI NTSTATUS NTAPI KexNtQueryInformationProcess( + IN HANDLE ProcessHandle, + IN PROCESSINFOCLASS ProcessInformationClass, + OUT PVOID ProcessInformation, + IN ULONG ProcessInformationLength, + OUT PULONG ReturnLength OPTIONAL); + +KEXAPI NTSTATUS NTAPI KexNtAssignProcessToJobObject( + IN HANDLE JobHandle, + IN HANDLE ProcessHandle); + +#pragma endregion \ No newline at end of file diff --git a/00-Common Headers/KexGui.h b/00-Common Headers/KexGui.h new file mode 100644 index 0000000..d00fba5 --- /dev/null +++ b/00-Common Headers/KexGui.h @@ -0,0 +1,232 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// KexGui.h +// +// Abstract: +// +// Convenience functions and macros for GUI applications. +// +// Author: +// +// vxiiduu (01-Oct-2022) +// +// Environment: +// +// This header is automatically included in all EXE targets. +// You may include the header in DLL projects manually if required; however, +// do not use it in any DLLs to be loaded in a kex process. +// +// Revision History: +// +// vxiiduu 01-Oct-2022 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#ifdef KEX_ENV_NATIVE +# error This header file cannot be used in a native mode project. +#endif + +// +// Enable visual styles. +// +#pragma comment(linker, "\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' \ + version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' \ + language='*'\"") + +#pragma comment(lib, "comctl32.lib") +#pragma comment(lib, "comdlg32.lib") +#pragma comment(lib, "gdi32.lib") +#pragma comment(lib, "user32.lib") +#pragma comment(lib, "shell32.lib") + +#include +#include +#include +#include + +#ifndef KEXGDECLSPEC +# define KEXGDECLSPEC +# pragma comment(lib, "KexGui.lib") +#endif + +#define KEXGAPI CDECL + +#define StatusBar_SetParts(StatusBarWindow, NumberOfParts, SizeArray) (SendMessage((StatusBarWindow), SB_SETPARTS, (NumberOfParts), (LPARAM) (SizeArray))) +#define StatusBar_SetText(StatusBarWindow, Index, Text) (SendMessage((StatusBarWindow), SB_SETTEXT, (Index), (LPARAM) (Text))) + +#define ListView_GetItemTextEx(hwndLV, i, iSubItem_, pszText_, cchTextMax_, pcchText_) \ +{ LV_ITEM _macro_lvi;\ + _macro_lvi.iSubItem = (iSubItem_);\ + _macro_lvi.cchTextMax = (cchTextMax_);\ + _macro_lvi.pszText = (pszText_);\ + *(pcchText_) = (ULONG) SNDMSG((hwndLV), LVM_GETITEMTEXT, (WPARAM)(i), (LPARAM)(LV_ITEM *)&_macro_lvi);\ +} + +// undocumented window message +#define WM_COPYGLOBALDATA 0x0049 + +// special taskdialog flag not defined in sdk headers +#define TDIF_SIZE_TO_CONTENT 0x1000000 + +// +// ctlsx.c +// + +KEXGDECLSPEC EXTERN_C VOID KEXGAPI StatusBar_SetTextF( + IN HWND Window, + IN INT Index, + IN PCWSTR Format, + IN ...); + +KEXGDECLSPEC EXTERN_C VOID KEXGAPI ListView_SetCheckedStateAll( + IN HWND Window, + IN BOOLEAN Checked); + +KEXGDECLSPEC EXTERN_C VOID KEXGAPI Button_SetShield( + IN HWND Window, + IN BOOLEAN HasShield); + +// +// fldrpkr.c +// + +KEXGDECLSPEC EXTERN_C BOOLEAN KEXGAPI PickFolder( + IN HWND OwnerWindow OPTIONAL, + IN PCWSTR DefaultValue OPTIONAL, + IN ULONG AdditionalFlags OPTIONAL, // FOS_* + OUT PWSTR DirectoryPath, + IN ULONG DirectoryPathCch); + +// +// kexgui.c +// + +// This name is displayed in the captions of message boxes. +KEXGDECLSPEC extern PCWSTR KexgApplicationFriendlyName; + +// This can be NULL if the application has no main window. +KEXGDECLSPEC extern HWND KexgApplicationMainWindow; + +// +// msgbox.c +// + +KEXGDECLSPEC EXTERN_C INT KEXGAPI MessageBoxV( + IN ULONG Buttons OPTIONAL, + IN PCWSTR Icon OPTIONAL, + IN PCWSTR WindowTitle OPTIONAL, + IN PCWSTR MessageTitle OPTIONAL, + IN PCWSTR Format, + IN va_list ArgList); + +KEXGDECLSPEC EXTERN_C INT KEXGAPI MessageBoxF( + IN ULONG Buttons OPTIONAL, + IN PCWSTR Icon OPTIONAL, + IN PCWSTR WindowTitle OPTIONAL, + IN PCWSTR MessageTitle OPTIONAL, + IN PCWSTR Format, + IN ...); + +KEXGDECLSPEC EXTERN_C NORETURN VOID KEXGAPI CriticalErrorBoxF( + IN PCWSTR Format, + IN ...); + +KEXGDECLSPEC EXTERN_C VOID KEXGAPI ErrorBoxF( + IN PCWSTR Format, + IN ...); + +KEXGDECLSPEC EXTERN_C VOID KEXGAPI WarningBoxF( + IN PCWSTR Format, + IN ...); + +KEXGDECLSPEC EXTERN_C VOID KEXGAPI InfoBoxF( + IN PCWSTR Format, + IN ...); + +KEXGDECLSPEC EXTERN_C BOOLEAN KEXGAPI ReportAssertionFailure( + IN PCWSTR SourceFile, + IN ULONG SourceLine, + IN PCWSTR SourceFunction, + IN PCWSTR AssertCondition); + +// +// window.c +// + +KEXGDECLSPEC EXTERN_C BOOLEAN KEXGAPI SetWindowTextF( + IN HWND Window, + IN PCWSTR Format, + IN ...); + +KEXGDECLSPEC EXTERN_C BOOLEAN KEXGAPI SetDlgItemTextF( + IN HWND Window, + IN USHORT ItemId, + IN PCWSTR Format, + IN ...); + +KEXGDECLSPEC EXTERN_C VOID KEXGAPI SetWindowIcon( + IN HWND Window, + IN USHORT IconId); + +KEXGDECLSPEC EXTERN_C VOID KEXGAPI CenterWindow( + IN HWND Window, + IN HWND ParentWindow OPTIONAL); + +KEXGDECLSPEC EXTERN_C VOID KEXGAPI BanishWindow( + IN HWND Window); + +KEXGDECLSPEC EXTERN_C VOID KEXGAPI SummonWindow( + IN HWND Window); + +// +// wndx.c +// +KEXGDECLSPEC EXTERN_C ULONG KEXGAPI ContextMenu( + IN HWND Window, + IN USHORT MenuId, + IN PPOINT ClickPoint); + +KEXGDECLSPEC EXTERN_C ULONG KEXGAPI ContextMenuEx( + IN HWND Window, + IN USHORT MenuId, + IN PPOINT ClickPoint, + IN INT DefaultMenuItem); + +KEXGDECLSPEC EXTERN_C HWND KEXGAPI ToolTip( + IN HWND DialogWindow, + IN INT ToolId, + IN PWSTR Format, + IN ...); + +// +// shprops.c +// + +KEXGDECLSPEC BOOLEAN KEXGAPI ShowPropertiesDialog( + IN PCWSTR FilePath, + IN INT ShowControl); + +KEXGDECLSPEC HRESULT KEXGAPI OpenFileLocation( + IN PCWSTR FilePath, + IN ULONG Flags); + +// +// dpi.c +// + +KEXGDECLSPEC INT KEXGAPI DpiScaleX( + IN INT PixelsX); + +KEXGDECLSPEC INT KEXGAPI DpiScaleY( + IN INT PixelsY); + +// +// locale.c +// + +KEXGDECLSPEC LANGID KEXGAPI GetVxKexUserInterfaceLanguage( + VOID); \ No newline at end of file diff --git a/00-Common Headers/KexLnk.h b/00-Common Headers/KexLnk.h new file mode 100644 index 0000000..81680df --- /dev/null +++ b/00-Common Headers/KexLnk.h @@ -0,0 +1,79 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// NtDll.h +// +// Abstract: +// +// Defines linker settings for VxKex projects. +// +// Author: +// +// vxiiduu (30-Sep-2022) +// +// Revision History: +// +// vxiiduu 30-Sep-2022 Initial creation. +// vxiiduu 31-Oct-2022 Fix 32-bit SEH. +// +/////////////////////////////////////////////////////////////////////////////// + +#pragma once + +// +// Disable CRT across the board. It is not used in VxKex. +// +#pragma comment(linker, "/NODEFAULTLIB:LIBCMT.LIB") +#pragma comment(linker, "/NODEFAULTLIB:LIBCMTD.LIB") +#pragma comment(linker, "/NODEFAULTLIB:MSVCRT.LIB") +#pragma comment(linker, "/NODEFAULTLIB:MSVCRTD.LIB") + +#ifdef KEX_ENV_WIN32 +# pragma comment(linker, "/SUBSYSTEM:WINDOWS") +#else +# pragma comment(linker, "/SUBSYSTEM:NATIVE") +#endif + +// +// Set appropriate entry point. +// +#if defined(KEX_TARGET_TYPE_EXE) +# pragma comment(linker, "/ENTRY:EntryPoint") +#elif defined(KEX_TARGET_TYPE_DLL) +# pragma comment(linker, "/ENTRY:DllMain") +#elif defined(KEX_TARGET_TYPE_SYS) +# pragma comment(linker, "/ENTRY:DriverEntry") +#elif !defined(KEX_TARGET_TYPE_LIB) +// Did you forget to include buildcfg.h? +# error You must specify a target file type (EXE, DLL or LIB) for this project by defining a KEX_TARGET_TYPE_* macro before including KexLnk.h or KexComm.h. +#endif + +#pragma region Library Inputs +#if defined(KEX_TARGET_TYPE_EXE) || defined(KEX_TARGET_TYPE_DLL) +# ifdef KEX_ENV_WIN32 +# if defined(KEX_TARGET_TYPE_EXE) || defined(KEX_TARGET_TYPE_DLL) +# ifdef _M_X64 +# pragma comment(lib, "kernel32_x64.lib") +# pragma comment(lib, "kernelbase_x64.lib") +# else +# pragma comment(lib, "kernel32_x86.lib") +# pragma comment(lib, "kernelbase_x86.lib") +# endif +# pragma comment(lib, "ole32.lib") +# endif +# endif +#elif defined(KEX_TARGET_TYPE_SYS) +# ifdef _M_X64 +# pragma comment(lib, "ntoskrnl_x64.lib") +# pragma comment(lib, "ntstrsafe_x64.lib") +# else +# pragma comment(lib, "ntoskrnl_x86.lib") +# pragma comment(lib, "ntstrsafe_x86.lib") +# endif +#endif + +#ifdef KEX_ARCH_X86 +# pragma comment(lib, "seh32.lib") +#endif +#pragma endregion \ No newline at end of file diff --git a/00-Common Headers/KexPathCch.h b/00-Common Headers/KexPathCch.h new file mode 100644 index 0000000..ddfcf2b --- /dev/null +++ b/00-Common Headers/KexPathCch.h @@ -0,0 +1,141 @@ +#pragma once + +#include + +#ifndef WINPATHCCHAPI +# define WINPATHCCHAPI +# pragma comment(lib, "KexPathCch.lib") +#endif + +// Values for various "dwFlags" parameters +#define PATHCCH_MAX_CCH ((SIZE_T) 32768) +#define PATHCCH_NONE 0x00000000 +#define PATHCCH_ALLOW_LONG_PATHS 0x00000001 +#define PATHCCH_FORCE_ENABLE_LONG_NAME_PROCESS 0x00000002 +#define PATHCCH_FORCE_DISABLE_LONG_NAME_PROCESS 0x00000004 +#define PATHCCH_DO_NOT_NORMALIZE_SEGMENTS 0x00000008 +#define PATHCCH_ENSURE_IS_EXTENDED_LENGTH_PATH 0x00000010 +#define PATHCCH_ENSURE_TRAILING_SLASH 0x00000020 + +#define PATHCCH_E_FILENAME_TOO_LONG ((HRESULT) 0x800700CE) + +WINPATHCCHAPI HRESULT WINAPI PathAllocCanonicalize( + IN LPCWSTR lpszPathIn, + IN DWORD dwFlags, + OUT LPWSTR *ppszPathOut); + +WINPATHCCHAPI HRESULT WINAPI PathAllocCombine( + IN LPCWSTR lpszPathIn, + IN LPCWSTR lpszMore, + IN DWORD dwFlags, + OUT LPWSTR *ppszPathOut); + +WINPATHCCHAPI HRESULT WINAPI PathCchAddBackslash( + IN OUT LPWSTR lpszPath, + IN SIZE_T cchPath); + +WINPATHCCHAPI HRESULT WINAPI PathCchAddBackslashEx( + IN OUT LPWSTR lpszPath, + IN SIZE_T cchPath, + OUT LPWSTR *ppszEnd OPTIONAL, + OUT PSIZE_T pcchRemaining OPTIONAL); + +WINPATHCCHAPI HRESULT WINAPI PathCchAddExtension( + IN OUT LPWSTR lpszPath, + IN SIZE_T cchPath, + IN LPCWSTR lpszExt); + +WINPATHCCHAPI HRESULT WINAPI PathCchAppend( + IN OUT LPWSTR lpszPath, + IN SIZE_T cchPath, + IN LPCWSTR lpszMore); + +WINPATHCCHAPI HRESULT WINAPI PathCchAppendEx( + IN OUT LPWSTR lpszPath, + IN SIZE_T cchPath, + IN LPCWSTR lpszMore OPTIONAL, + IN DWORD dwFlags); + +WINPATHCCHAPI HRESULT WINAPI PathCchCanonicalize( + OUT LPWSTR lpszPathOut, + IN SIZE_T cchPathOut, + IN LPCWSTR lpszPathIn); + +WINPATHCCHAPI HRESULT WINAPI PathCchCanonicalizeEx( + OUT LPWSTR lpszPathOut, + IN SIZE_T cchPathOut, + IN LPCWSTR lpszPathIn, + IN DWORD dwFlags); + +WINPATHCCHAPI HRESULT WINAPI PathCchCombine( + OUT LPWSTR lpszPathOut, + IN SIZE_T cchPathOut, + IN LPCWSTR lpszPathIn OPTIONAL, + IN LPCWSTR lpszMore OPTIONAL); + +WINPATHCCHAPI HRESULT WINAPI PathCchCombineEx( + OUT LPWSTR lpszPathOut, + IN SIZE_T cchPathOut, + IN LPCWSTR lpszPathIn OPTIONAL, + IN LPCWSTR lpszMore OPTIONAL, + IN DWORD dwFlags); + +WINPATHCCHAPI HRESULT WINAPI PathCchFindExtension( + IN LPCWSTR lpszPath, + IN SIZE_T cchPath, + OUT LPCWSTR *ppszExt); + +WINPATHCCHAPI BOOL WINAPI PathCchIsRoot( + IN LPCWSTR lpszPath); + +WINPATHCCHAPI HRESULT WINAPI PathCchRemoveBackslash( + IN OUT LPWSTR lpszPath, + IN SIZE_T cchPath); + +WINPATHCCHAPI HRESULT WINAPI PathCchRemoveBackslashEx( + IN OUT LPWSTR lpszPath, + IN SIZE_T cchPath, + OUT LPWSTR *ppszEnd OPTIONAL, + OUT PSIZE_T pcchRemaining OPTIONAL); + +WINPATHCCHAPI HRESULT WINAPI PathCchRemoveExtension( + IN OUT LPWSTR lpszPath, + IN SIZE_T cchPath); + +WINPATHCCHAPI HRESULT WINAPI PathCchRemoveFileSpec( + IN OUT LPWSTR lpszPath, + IN SIZE_T cchPath); + +WINPATHCCHAPI HRESULT WINAPI PathCchRenameExtension( + IN OUT LPWSTR lpszPath, + IN SIZE_T cchPath, + IN LPCWSTR lpszExt); + +WINPATHCCHAPI HRESULT WINAPI PathCchSkipRoot( + IN LPCWSTR lpszPath, + OUT LPCWSTR *ppszRootEnd); + +WINPATHCCHAPI HRESULT WINAPI PathCchStripPrefix( + IN OUT LPWSTR lpszPath, + IN SIZE_T cchPath); + +WINPATHCCHAPI HRESULT WINAPI PathCchStripToRoot( + IN OUT LPWSTR lpszPath, + IN SIZE_T cchPath); + +WINPATHCCHAPI BOOL WINAPI PathIsUNCEx( + IN LPCWSTR lpszPath, + OUT LPCWSTR *ppszServer OPTIONAL); + +#pragma deprecated(PathAddBackslash) +#pragma deprecated(PathAddExtension) +#pragma deprecated(PathAppend) +#pragma deprecated(PathCanonicalize) +#pragma deprecated(PathCombine) +#pragma deprecated(PathIsRoot) +#pragma deprecated(PathRemoveBackslash) +#pragma deprecated(PathRemoveFileSpec) +#pragma deprecated(PathRenameExtension) +#pragma deprecated(PathSkipRoot) +#pragma deprecated(PathStripPrefix) +#pragma deprecated(PathStripToRoot) \ No newline at end of file diff --git a/00-Common Headers/KexStrSafe.h b/00-Common Headers/KexStrSafe.h new file mode 100644 index 0000000..80bfbc3 --- /dev/null +++ b/00-Common Headers/KexStrSafe.h @@ -0,0 +1,789 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// KexStrSafe.h +// +// Abstract: +// +// Safe string handling functions (extended). +// These functions are much faster than importing from shlwapi.dll +// or ntdll.dll. The shlwapi functions especially are incredibly slow, +// about 20-100x slower than these. +// +// These functions are inlined in the header because their performance +// is often important (unlike, say, ContextMenu or CriticalErrorBoxF), +// and their code size is generally small. +// +// Author: +// +// vxiiduu (01-Oct-2022) +// +// Environment: +// +// StringAllocPrintf family can be called only when the process heap is +// available. +// Other functions can be called anywhere. +// +// Revision History: +// +// vxiiduu 01-Oct-2022 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include + +#ifndef until +# define until(x) while(!(x)) +#endif + +// +// The StringCchPrintfBufferLength family of functions returns the required +// number of characters, including space for the null terminator, you need +// to allocate in a buffer to hold a formatted string. +// + +INLINE HRESULT StringCchVPrintfBufferLengthA( + OUT PSIZE_T BufferCch, + IN PCSTR Format, + IN ARGLIST ArgList) +{ + INT StringCch; + + ASSERT (Format != NULL); + ASSERT (BufferCch != NULL); + + if (BufferCch) { + *BufferCch = 0; + } + + if (!Format || !BufferCch) { + return STRSAFE_E_INVALID_PARAMETER; + } + + StringCch = _vscprintf(Format, ArgList); + + if (StringCch == -1) { + ASSERT (("Invalid parameters passed to _vscprintf", FALSE)); + return STRSAFE_E_INVALID_PARAMETER; + } + + *BufferCch = StringCch + 1; + return S_OK; +} + +INLINE HRESULT StringCchVPrintfBufferLengthW( + OUT PSIZE_T BufferCch, + IN PCWSTR Format, + IN ARGLIST ArgList) +{ + INT StringCch; + + ASSERT (Format != NULL); + ASSERT (BufferCch != NULL); + + if (BufferCch) { + *BufferCch = 0; + } + + if (!Format || !BufferCch) { + return STRSAFE_E_INVALID_PARAMETER; + } + + StringCch = _vscwprintf(Format, ArgList); + + if (StringCch == -1) { + ASSERT (("Invalid parameters passed to _vscprintf", FALSE)); + return STRSAFE_E_INVALID_PARAMETER; + } + + *BufferCch = StringCch + 1; + return S_OK; +} + +INLINE HRESULT StringCchPrintfBufferLengthA( + OUT PSIZE_T BufferCch, + IN PCSTR Format, + IN ...) +{ + ARGLIST ArgList; + HRESULT Result; + + va_start(ArgList, Format); + Result = StringCchVPrintfBufferLengthA(BufferCch, Format, ArgList); + return Result; +} + +INLINE HRESULT StringCchPrintfBufferLengthW( + OUT PSIZE_T BufferCch, + IN PCWSTR Format, + IN ...) +{ + ARGLIST ArgList; + HRESULT Result; + + va_start(ArgList, Format); + Result = StringCchVPrintfBufferLengthW(BufferCch, Format, ArgList); + return Result; +} + +// +// The StringAllocPrintf family of functions allocates a buffer on the process +// heap to hold a formatted string. +// +// You need to pass the returned Buffer to SafeFree if the function succeeds. +// + +INLINE HRESULT StringAllocPrintfA( + OUT PPSTR Buffer, + OUT PSIZE_T BufferCch OPTIONAL, + IN PCSTR Format, + IN ...) +{ + HRESULT Result; + SIZE_T BufferCchInternal; + PSTR BufferInternal = NULL; + ARGLIST ArgList; + + ASSERT (Buffer != NULL); + + if (!Buffer) { + return STRSAFE_E_INVALID_PARAMETER; + } + + *Buffer = NULL; + + if (BufferCch) { + *BufferCch = 0; + } + + va_start(ArgList, Format); + + // + // Find length of the buffer we need to allocate. + // + + Result = StringCchVPrintfBufferLengthA(&BufferCchInternal, Format, ArgList); + + if (FAILED(Result)) { + goto Exit; + } + + // + // Allocate the buffer. + // + + BufferInternal = SafeAlloc(CHAR, BufferCchInternal); + if (!BufferInternal) { + Result = E_OUTOFMEMORY; + goto Exit; + } + + // + // Format the caller-supplied string into the buffer. + // + + Result = StringCchVPrintfA(BufferInternal, BufferCchInternal, Format, ArgList); + ASSERT (SUCCEEDED(Result)); + + if (FAILED(Result)) { + goto Exit; + } + + // + // Return results to caller. + // + + if (BufferCch) { + *BufferCch = BufferCchInternal; + } + + *Buffer = BufferInternal; + Result = S_OK; + +Exit: + if (FAILED(Result)) { + SafeFree(BufferInternal); + } + + return Result; +} + +INLINE HRESULT StringAllocPrintfW( + OUT PPWSTR Buffer, + OUT PSIZE_T BufferCch OPTIONAL, + IN PCWSTR Format, + IN ...) +{ + HRESULT Result; + SIZE_T BufferCchInternal; + PWSTR BufferInternal = NULL; + ARGLIST ArgList; + + ASSERT (Buffer != NULL); + + if (!Buffer) { + return STRSAFE_E_INVALID_PARAMETER; + } + + *Buffer = NULL; + + if (BufferCch) { + *BufferCch = 0; + } + + va_start(ArgList, Format); + + // + // Find length of the buffer we need to allocate. + // + + Result = StringCchVPrintfBufferLengthW(&BufferCchInternal, Format, ArgList); + + if (FAILED(Result)) { + goto Exit; + } + + // + // Allocate the buffer. + // + + BufferInternal = SafeAlloc(WCHAR, BufferCchInternal); + if (!BufferInternal) { + Result = E_OUTOFMEMORY; + goto Exit; + } + + // + // Format the caller-supplied string into the buffer. + // + + Result = StringCchVPrintfW(BufferInternal, BufferCchInternal, Format, ArgList); + ASSERT (SUCCEEDED(Result)); + + if (FAILED(Result)) { + goto Exit; + } + + // + // Return results to caller. + // + + Result = S_OK; + +Exit: + if (FAILED(Result)) { + SafeFree(BufferInternal); + } else { + if (BufferCch) { + *BufferCch = BufferCchInternal; + } + + *Buffer = BufferInternal; + } + + return Result; +} + +// These macros are generic and can operate on both ANSI and Unicode. +#define ToUpper(c) (((c) >= 'a' && (c) <= 'z') ? ((c) - 32) : (c)) +#define ToLower(c) (((c) >= 'A' && (c) <= 'Z') ? ((c) + 32) : (c)) + +// The StringEqual family of functions returns 0 if the strings are +// different and 1 if the strings are equal. +// The StringEqualI family does the same things except it is case +// insensitive. + +INLINE BOOLEAN StringEqualA( + IN PCSTR String1, + IN PCSTR String2) +{ + ASSERT (String1 != NULL); + ASSERT (String2 != NULL); + + while (*String1 && *String2 && *String1 == *String2) { + ++String1; + ++String2; + } + + return (*String1 == *String2); +} + +INLINE BOOLEAN StringEqualIA( + IN PCSTR String1, + IN PCSTR String2) +{ + ASSERT (String1 != NULL); + ASSERT (String2 != NULL); + + while (*String1 && *String2 && ToUpper(*String1) == ToUpper(*String2)) { + ++String1; + ++String2; + } + + return (*String1 == *String2); +} + +INLINE BOOLEAN StringEqualW( + IN PCWSTR String1, + IN PCWSTR String2) +{ + ASSERT (String1 != NULL); + ASSERT (String2 != NULL); + + while (*String1 && *String2 && *String1 == *String2) { + ++String1; + ++String2; + } + + return (*String1 == *String2); +} + +INLINE BOOLEAN StringEqualIW( + IN PCWSTR String1, + IN PCWSTR String2) +{ + ASSERT (String1 != NULL); + ASSERT (String2 != NULL); + + while (*String1 && *String2 && ToUpper(*String1) == ToUpper(*String2)) { + ++String1; + ++String2; + } + + return (*String1 == *String2); +} + +// +// The StringSearch family of functions returns TRUE if Needle was found as +// a substring of Haystack. +// The StringSearchI family of functions is case insensitive. +// +// If you need the starting address of the first match of the substring, +// then these functions are not suitable. Use StrStr(I)(A/W) from shlwapi.dll +// instead. +// + +INLINE BOOLEAN StringSearchA( + IN PCSTR Haystack, + IN PCSTR Needle) +{ + ASSERT (Haystack != NULL); + ASSERT (Needle != NULL); + + while (TRUE) { + PCSTR Needle2 = Needle; + + // find first char of needle in haystack + while (*Haystack != *Needle) { + if (!*++Haystack) { + // at end of haystack - needle not found + return FALSE; + } + } + + while (*Haystack && *Needle2 && *Haystack == *Needle2) { + if (!*++Needle2) { + // end of needle - this means the needle is entirely in the haystack + return TRUE; + } + + if (!*++Haystack) { + // end of haystack - this means not the entire needle in haystack + return FALSE; + } + } + } +} + +INLINE BOOLEAN StringSearchIA( + IN PCSTR Haystack, + IN PCSTR Needle) +{ + CHAR NeedleFirst; + + ASSERT (Haystack != NULL); + ASSERT (Needle != NULL); + + // cache the first char of the needle for faster search + NeedleFirst = ToUpper(*Needle); + + while (TRUE) { + PCSTR Needle2 = Needle; + + while (ToUpper(*Haystack) != NeedleFirst) { + if (!*++Haystack) { + return FALSE; + } + } + + while (*Haystack && *Needle2 && ToUpper(*Haystack) == ToUpper(*Needle2)) { + if (!*++Needle2) { + return TRUE; + } + + if (!*++Haystack) { + return FALSE; + } + } + } +} + +INLINE BOOLEAN StringSearchW( + IN PCWSTR Haystack, + IN PCWSTR Needle) +{ + ASSERT (Haystack != NULL); + ASSERT (Needle != NULL); + + while (TRUE) { + PCWSTR Needle2 = Needle; + + // find first char of needle in haystack + while (*Haystack != *Needle) { + if (!*++Haystack) { + // at end of haystack - needle not found + return FALSE; + } + } + + while (*Haystack && *Needle2 && *Haystack == *Needle2) { + if (!*++Needle2) { + // end of needle - this means the needle is entirely in the haystack + return TRUE; + } + + if (!*++Haystack) { + // end of haystack - this means not the entire needle in haystack + return FALSE; + } + } + } +} + +INLINE BOOLEAN StringSearchIW( + IN PCWSTR Haystack, + IN PCWSTR Needle) +{ + WCHAR NeedleFirst; + + ASSERT (Haystack != NULL); + ASSERT (Needle != NULL); + + // cache the first char of the needle for faster search + NeedleFirst = ToUpper(*Needle); + + while (TRUE) { + PCWSTR Needle2 = Needle; + + while (ToUpper(*Haystack) != NeedleFirst) { + if (!*++Haystack) { + return FALSE; + } + } + + while (*Haystack && *Needle2 && ToUpper(*Haystack) == ToUpper(*Needle2)) { + if (!*++Needle2) { + return TRUE; + } + + if (!*++Haystack) { + return FALSE; + } + } + } +} + +INLINE BOOLEAN StringBeginsWithW( + IN PCWSTR String, + IN PCWSTR Prefix) +{ + ULONG Index; + + ASSERT (String != NULL); + ASSERT (Prefix != NULL); + + if (String[0] == '\0') { + return FALSE; + } + + if (Prefix[0] == '\0') { + return TRUE; + } + + Index = 0; + + while (String[Index] == Prefix[Index] && Prefix[Index] != '\0') { + ++Index; + } + + if (Prefix[Index] == '\0') { + return TRUE; + } else { + return FALSE; + } +} + +INLINE BOOLEAN StringBeginsWithA( + IN PCSTR String, + IN PCSTR Prefix) +{ + ULONG Index; + + ASSERT (String != NULL); + ASSERT (Prefix != NULL); + + if (String[0] == '\0') { + return FALSE; + } + + if (Prefix[0] == '\0') { + return TRUE; + } + + Index = 0; + + while (String[Index] == Prefix[Index] && Prefix[Index] != '\0') { + ++Index; + } + + if (Prefix[Index] == '\0') { + return TRUE; + } else { + return FALSE; + } +} + +INLINE BOOLEAN StringBeginsWithIW( + IN PCWSTR String, + IN PCWSTR Prefix) +{ + ULONG Index; + + ASSERT (String != NULL); + ASSERT (Prefix != NULL); + + if (String[0] == '\0') { + return FALSE; + } + + if (Prefix[0] == '\0') { + return TRUE; + } + + Index = 0; + + while (towupper(String[Index]) == towupper(Prefix[Index]) && Prefix[Index] != '\0') { + ++Index; + } + + if (Prefix[Index] == '\0') { + return TRUE; + } else { + return FALSE; + } +} + +INLINE BOOLEAN StringBeginsWithIA( + IN PCSTR String, + IN PCSTR Prefix) +{ + ULONG Index; + + ASSERT (String != NULL); + ASSERT (Prefix != NULL); + + if (String[0] == '\0') { + return FALSE; + } + + if (Prefix[0] == '\0') { + return TRUE; + } + + Index = 0; + + while (toupper(String[Index]) == toupper(Prefix[Index]) && Prefix[Index] != '\0') { + ++Index; + } + + if (Prefix[Index] == '\0') { + return TRUE; + } else { + return FALSE; + } +} + +INLINE PCSTR StringFindA( + IN PCSTR Haystack, + IN PCSTR Needle) +{ + CHAR NeedleFirst; + ULONG Index; + + ASSERT (Haystack != NULL); + ASSERT (Needle != NULL); + + if (Haystack[0] == '\0' || Needle[0] == '\0') { + return NULL; + } + + NeedleFirst = Needle[0]; + Index = 0; + + while (TRUE) { + until (Haystack[Index] == NeedleFirst || Haystack[Index] == '\0') { + ++Index; + } + + if (Haystack[Index] == '\0') { + return NULL; + } + + if (StringBeginsWithA(&Haystack[Index], Needle)) { + return &Haystack[Index]; + } + + ++Index; + } +} + +INLINE PCSTR StringFindIA( + IN PCSTR Haystack, + IN PCSTR Needle) +{ + CHAR NeedleFirst; + ULONG Index; + + ASSERT (Haystack != NULL); + ASSERT (Needle != NULL); + + if (Haystack[0] == '\0' || Needle[0] == '\0') { + return NULL; + } + + NeedleFirst = ToUpper(Needle[0]); + Index = 0; + + while (TRUE) { + until (ToUpper(Haystack[Index]) == NeedleFirst || Haystack[Index] == '\0') { + ++Index; + } + + if (Haystack[Index] == '\0') { + return NULL; + } + + if (StringBeginsWithIA(&Haystack[Index], Needle)) { + return &Haystack[Index]; + } + + ++Index; + } +} + +INLINE PCWSTR StringFindW( + IN PCWSTR Haystack, + IN PCWSTR Needle) +{ + WCHAR NeedleFirst; + ULONG Index; + + ASSERT (Haystack != NULL); + ASSERT (Needle != NULL); + + if (Haystack[0] == '\0' || Needle[0] == '\0') { + return NULL; + } + + NeedleFirst = Needle[0]; + Index = 0; + + while (TRUE) { + until (Haystack[Index] == NeedleFirst || Haystack[Index] == '\0') { + ++Index; + } + + if (Haystack[Index] == '\0') { + return NULL; + } + + if (StringBeginsWithW(&Haystack[Index], Needle)) { + return &Haystack[Index]; + } + + ++Index; + } +} + +INLINE PCWSTR StringFindIW( + IN PCWSTR Haystack, + IN PCWSTR Needle) +{ + WCHAR NeedleFirst; + ULONG Index; + + ASSERT (Haystack != NULL); + ASSERT (Needle != NULL); + + if (Haystack[0] == '\0' || Needle[0] == '\0') { + return NULL; + } + + NeedleFirst = ToUpper(Needle[0]); + Index = 0; + + while (TRUE) { + until (ToUpper(Haystack[Index]) == NeedleFirst || Haystack[Index] == '\0') { + ++Index; + } + + if (Haystack[Index] == '\0') { + return NULL; + } + + if (StringBeginsWithIW(&Haystack[Index], Needle)) { + return &Haystack[Index]; + } + + ++Index; + } +} + +#ifdef _UNICODE +# define StringCchVPrintfBufferLength StringCchVPrintfBufferLengthW +# define StringCchPrintfBufferLength StringCchPrintfBufferLengthW +# define StringAllocPrintf StringAllocPrintfW +# define StringEqual StringEqualW +# define StringEqualI StringEqualIW +# define StringSearch StringSearchW +# define StringSearchI StringSearchIW +# define StringBeginsWith StringBeginsWithW +# define StringBeginsWithI StringBeginsWithIW +# define StringFind StringFindW +# define StringFindI StringFindIW +#else +# define StringCchVPrintfBufferLength StringCchVPrintfBufferLengthA +# define StringCchPrintfBufferLength StringCchPrintfBufferLengthA +# define StringAllocPrintf StringAllocPrintfA +# define StringEqual StringEqualA +# define StringEqualI StringEqualIA +# define StringSearch StringSearchA +# define StringSearchI StringSearchIA +# define StringBeginsWith StringBeginsWithA +# define StringBeginsWithI StringBeginsWithIA +# define StringFind StringFindA +# define StringFindI StringFindIA +#endif + +#define StringLiteralLength(StringLiteral) (ARRAYSIZE(StringLiteral) - 1) + +#pragma deprecated(wcscmp) +#pragma deprecated(_wcsicmp) +#pragma deprecated(_vscprintf) +#pragma deprecated(_vscwprintf) +#pragma deprecated(wcsstr) +#pragma deprecated(strstr) \ No newline at end of file diff --git a/00-Common Headers/KexTypes.h b/00-Common Headers/KexTypes.h new file mode 100644 index 0000000..0dc6ca3 --- /dev/null +++ b/00-Common Headers/KexTypes.h @@ -0,0 +1,66 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// KexTypes.h +// +// Abstract: +// +// Type definitions and associated macros. +// +// Author: +// +// vxiiduu (26-Sep-2022) +// +// Environment: +// +// Any environment. +// +// Revision History: +// +// vxiiduu 26-Sep-2022 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include + +#undef CDECL +#define CDECL __cdecl +#define NORETURN __declspec(noreturn) +#define DECLSPEC_EXPORT __declspec(dllexport) +#define INLINE __inline +#define NOINLINE __declspec(noinline) +#define STATIC static +#define VOLATILE volatile +#define EXTERN extern + +typedef PSTR *PPSTR; +typedef PCSTR *PPCSTR; +typedef PWSTR *PPWSTR; +typedef PCWSTR *PPCWSTR; +typedef va_list ARGLIST; +typedef ULONGLONG QWORD; +typedef LONG NTSTATUS; + +#define GEN_STD_TYPEDEFS(Type) \ + typedef Type *P##Type; \ + typedef Type **PP##Type; \ + typedef CONST Type *PC##Type; \ + typedef CONST Type **PPC##Type + +#define TYPEDEF_TYPE_NAME(Type) Type; GEN_STD_TYPEDEFS(Type) + +// PCVOID, PPVOID, PPCVOID etc +GEN_STD_TYPEDEFS(VOID); +GEN_STD_TYPEDEFS(NTSTATUS); +GEN_STD_TYPEDEFS(BYTE); +GEN_STD_TYPEDEFS(WORD); +GEN_STD_TYPEDEFS(DWORD); +GEN_STD_TYPEDEFS(QWORD); +GEN_STD_TYPEDEFS(ULONGLONG); +GEN_STD_TYPEDEFS(ULONG); +GEN_STD_TYPEDEFS(USHORT); +GEN_STD_TYPEDEFS(UCHAR); +GEN_STD_TYPEDEFS(HMODULE); \ No newline at end of file diff --git a/00-Common Headers/KexVer.h b/00-Common Headers/KexVer.h new file mode 100644 index 0000000..f1592b0 --- /dev/null +++ b/00-Common Headers/KexVer.h @@ -0,0 +1,51 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// KexVer.h +// +// Abstract: +// +// Contains version information and other strings/constants for file +// metadata across many VxKex components. +// +// Author: +// +// vxiiduu (26-Sep-2022) +// +// Environment: +// +// N/A +// +// Revision History: +// +// vxiiduu 26-Sep-2022 Initial creation +// vxiiduu 04-Feb-2024 Implement autoincrement build number +// +/////////////////////////////////////////////////////////////////////////////// + +#pragma once + +// vautogen is a utility in 01-Development Utilities\vautogen. +// The INI-file controls the major, minor and patch numbers. +// vautogen automatically increments the version number each time it is +// called, and creates a header file containing the definitions: +// KEX_VERSION_DW (written to registry as InstalledVersion) +// KEX_VERSION_FV (placed in version resources, see .rc files) +// KEX_VERSION_STR (displayed to users) +// +// Since KexVer.h is included in basically every VxKex project (and the build +// number auto-increments), allowing vautogen.h to be included all the time +// would cause builds to be longer and more annoying. Therefore it is only +// included in resource files (where version resources are defined) and in +// specific .c files that need it (define NEED_VERSION_DEFS before the inclusion +// of any headers). + +#if defined(RC_INVOKED) || defined(NEED_VERSION_DEFS) +# include +#endif + +#define KEX_WEB_STR "https://github.com/vxiiduu/VxKex" +#define KEX_BUGREPORT_STR "https://github.com/vxiiduu/VxKex/issues/new/choose" + +// You must keep the following line blank or RC will screech. diff --git a/00-Common Headers/KexW32ML.h b/00-Common Headers/KexW32ML.h new file mode 100644 index 0000000..f14938b --- /dev/null +++ b/00-Common Headers/KexW32ML.h @@ -0,0 +1,97 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// KexW32ML.h +// +// Abstract: +// +// VxKex Win32-mode General Library Header file +// +// Author: +// +// vxiiduu (02-Oct-2022) +// +// Environment: +// +// This header is automatically included in EXE targets. +// It may be used in DLLs which are to be loaded in kex processes. +// Do not use in native DLLs. +// +// Revision History: +// +// vxiiduu 02-Oct-2022 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#ifdef KEX_ENV_NATIVE +# error This header file cannot be used in a native mode project. +#endif + +#ifndef KW32MLDECLSPEC +# define KW32MLDECLSPEC +# pragma comment(lib, "KexW32ML.lib") +#endif + +#define KW32MLAPI WINAPI + +#define GetLastErrorAsString() Win32ErrorAsString(GetLastError()) +#define NtStatusAsString(Status) Win32ErrorAsString(RtlNtStatusToDosErrorNoTeb(Status)) + +// Use CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE) instead +#pragma deprecated(CoInitialize) + +KW32MLDECLSPEC LONGLONG KW32MLAPI CompareFileTimes( + IN FILETIME FileTime1, + IN FILETIME FileTime2); + +KW32MLDECLSPEC PWSTR KW32MLAPI GetCommandLineWithoutImageName( + VOID); + +KW32MLDECLSPEC BOOLEAN KW32MLAPI PathReplaceIllegalCharacters( + IN PWSTR Path, + IN WCHAR ReplacementCharacter, + IN BOOLEAN AllowPathSeparators); + +KW32MLDECLSPEC PCWSTR KW32MLAPI Win32ErrorAsString( + IN ULONG Win32ErrorCode); + +KW32MLDECLSPEC ULONG KW32MLAPI RegReadI32( + IN HKEY Key, + IN PCWSTR SubKey OPTIONAL, + IN PCWSTR ValueName OPTIONAL, + OUT PULONG Data); + +KW32MLDECLSPEC ULONG KW32MLAPI RegWriteI32( + IN HKEY Key, + IN PCWSTR SubKey OPTIONAL, + IN PCWSTR ValueName OPTIONAL, + IN ULONG Data); + +KW32MLDECLSPEC ULONG KW32MLAPI RegReadString( + IN HKEY Key, + IN PCWSTR SubKey OPTIONAL, + IN PCWSTR ValueName OPTIONAL, + OUT PWSTR Buffer, + IN ULONG BufferCch); + +KW32MLDECLSPEC ULONG KW32MLAPI RegWriteString( + IN HKEY Key, + IN PCWSTR SubKey OPTIONAL, + IN PCWSTR ValueName OPTIONAL, + IN PCWSTR Data); + +KW32MLDECLSPEC BOOLEAN KW32MLAPI RegReOpenKey( + IN OUT PHKEY KeyHandle, + IN ACCESS_MASK NewAccessMask, + IN HANDLE TransactionHandle OPTIONAL); + +KW32MLDECLSPEC EXTERN_C BOOLEAN KW32MLAPI SupersedeFile( + IN PCWSTR SourceFile, + IN PCWSTR TargetFile, + IN HANDLE TransactionHandle OPTIONAL); + +KW32MLDECLSPEC HANDLE KW32MLAPI CreateSimpleTransaction( + IN PCWSTR Description); \ No newline at end of file diff --git a/00-Common Headers/KseGuid.h b/00-Common Headers/KseGuid.h new file mode 100644 index 0000000..0ebb499 --- /dev/null +++ b/00-Common Headers/KseGuid.h @@ -0,0 +1,4 @@ +#pragma once + +#define CLSID_STRING_KEXSHLEX L"{9AACA888-A5F5-4C01-852E-8A2005C1D45F}" +#define CLSID_STRING_CPIWBYPA L"{7EF224FC-1840-433C-9BCB-2951DE71DDBD}" \ No newline at end of file diff --git a/00-Common Headers/KxBase.h b/00-Common Headers/KxBase.h new file mode 100644 index 0000000..ca755fb --- /dev/null +++ b/00-Common Headers/KxBase.h @@ -0,0 +1,804 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// BaseDll.h +// +// Abstract: +// +// Win32 base API (i.e. kernel32 and kernelbase) +// +// Author: +// +// vxiiduu (07-Nov-2022) +// +// Revision History: +// +// vxiiduu 07-Nov-2022 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include +#include + +#pragma region Macro Definitions + +#if !defined(KXBASEAPI) && defined(KEX_ENV_WIN32) +# define KXBASEAPI +# pragma comment(lib, "KxBase.lib") +#endif + +#define PROCESS_CREATION_MITIGATION_POLICY_VALID_MASK \ + (PROCESS_CREATION_MITIGATION_POLICY_DEP_ENABLE | \ + PROCESS_CREATION_MITIGATION_POLICY_DEP_ATL_THUNK_ENABLE | \ + PROCESS_CREATION_MITIGATION_POLICY_SEHOP_ENABLE) + +// undocumented STARTUPINFO flag +#define STARTF_HASSHELLDATA 0x400 + +#define LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR 0x00000100 +#define LOAD_LIBRARY_SEARCH_APPLICATION_DIR 0x00000200 +#define LOAD_LIBRARY_SEARCH_USER_DIRS 0x00000400 +#define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800 +#define LOAD_LIBRARY_SEARCH_DEFAULT_DIRS 0x00001000 +#define LOAD_LIBRARY_SAFE_CURRENT_DIRS 0x00002000 + +#define LOAD_LIBRARY_ALL_DLLDIR_FLAGS (LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | \ + LOAD_LIBRARY_SEARCH_APPLICATION_DIR | \ + LOAD_LIBRARY_SEARCH_USER_DIRS | \ + LOAD_LIBRARY_SEARCH_SYSTEM32 | \ + LOAD_LIBRARY_SEARCH_DEFAULT_DIRS) + +#define APPMODEL_ERROR_NO_PACKAGE 15700L +#define APPMODEL_ERROR_NO_APPLICATION 15703L + +#pragma endregion + +#pragma region Structures and Typedefs + +// +// With the exception of the type of BaseDllDirectoryLock being different, the +// location and position of all of these members is consistent across every known +// build of Windows 7. +// + +typedef struct _KERNELBASE_GLOBAL_DATA { + // + // Example of what could be in here: "C:\Windows\system32;C:\Windows\system;C:\Windows;" + // The buffer of this string is allocated from the RtlProcessHeap(). + // The trailing semicolon is important. + // + + PUNICODE_STRING BaseDefaultPath; + PRTL_SRWLOCK BaseDefaultPathLock; + + // + // This is what gets accessed when you call SetDllDirectory and GetDllDirectory. + // Note: BaseDllDirectoryLock points to an RTL_CRITICAL_SECTION in early (RTM & SP1) + // builds of Windows 7, but to an RTL_SRWLOCK in later builds. + // + + PUNICODE_STRING BaseDllDirectory; + PVOID BaseDllDirectoryLock; + + // + // This is what gets set when you call SetSearchPathMode. + // The names of the valid flags start with BASE_SEARCH_PATH_*. + // + + PULONG BaseSearchPathMode; + PRTL_SRWLOCK BaseSearchPathModeLock; + + // + // These are all function pointers to functions either in NTDLL or in + // Kernelbase. For the most part, they are not useful, or it is easier + // to get them through other means. + // + + PVOID RtlAnsiStringToUnicodeString; + PVOID RtlUnicodeStringToAnsiString; + PVOID BasepAnsiStringToUnicodeSize; + PVOID BasepUnicodeStringToAnsiSize; + PVOID BasepConvertWin32AttributeList; // used during CreateProcess + + // + // This is passed to most calls to RtlAllocateHeap. + // It originates from a call to RtlCreateTagHeap. + // + + ULONG BaseDllTag; + + // + // Presumably this is only set to TRUE when this is the CSRSS.EXE process. + // The only time other than initialization when this variable is accessed + // is inside CreateRemoteThreadEx. + // + + BOOLEAN BaseRunningInServerProcess; + + // + // These strings are what gets queried when you call GetSystemDirectory or + // GetWindowsDirectory. + // + + UNICODE_STRING BaseWindowsDirectory; + UNICODE_STRING BaseWindowsSystemDirectory; +} TYPEDEF_TYPE_NAME(KERNELBASE_GLOBAL_DATA); + +typedef struct _BASE_STATIC_SERVER_DATA { + // e.g. "C:\Windows" + UNICODE_STRING WindowsDirectory; + + // e.g. "C:\Windows\system32" + UNICODE_STRING WindowsSystemDirectory; + + // e.g. "\Sessions\1\BaseNamedObjects" + UNICODE_STRING NamedObjectDirectory; + + // + // More members follow, but I don't consider them so interesting so + // I didn't bother to include them. + // +} TYPEDEF_TYPE_NAME(BASE_STATIC_SERVER_DATA); + +// Applicable for 32-bit program on 64-bit OS only. +typedef struct _BASE_STATIC_SERVER_DATA_WOW64 { + struct { + USHORT Length; + USHORT MaximumLength; + ULONG Padding; + PWCHAR Buffer; + ULONG Zero; + } WindowsDirectory; + + struct { + USHORT Length; + USHORT MaximumLength; + ULONG Padding; + PWCHAR Buffer; + ULONG Zero; + } WindowsSystemDirectory; + + struct { + USHORT Length; + USHORT MaximumLength; + ULONG Padding; + PWCHAR Buffer; + ULONG Zero; + } NamedObjectDirectory; +} TYPEDEF_TYPE_NAME(BASE_STATIC_SERVER_DATA_WOW64); + +typedef enum _OFFER_PRIORITY { + VMOfferPriorityVeryLow = 1, + VMOfferPriorityLow, + VMOfferPriorityBelowNormal, + VMOfferPriorityNormal, + VMOfferPriorityMaximum +} TYPEDEF_TYPE_NAME(OFFER_PRIORITY); + +typedef MEMORY_RANGE_ENTRY TYPEDEF_TYPE_NAME(WIN32_MEMORY_RANGE_ENTRY); + +typedef struct _CREATEFILE2_EXTENDED_PARAMETERS { + DWORD dwSize; + DWORD dwFileAttributes; + DWORD dwFileFlags; + DWORD dwSecurityQosFlags; + LPSECURITY_ATTRIBUTES lpSecurityAttributes; + HANDLE hTemplateFile; +} TYPEDEF_TYPE_NAME(CREATEFILE2_EXTENDED_PARAMETERS); + +typedef enum _COPYFILE2_MESSAGE_ACTION { + COPYFILE2_PROGRESS_CONTINUE, + COPYFILE2_PROGRESS_CANCEL, + COPYFILE2_PROGRESS_STOP, + COPYFILE2_PROGRESS_QUIET, + COPYFILE2_PROGRESS_PAUSE +} TYPEDEF_TYPE_NAME(COPYFILE2_MESSAGE_ACTION); + +typedef enum _COPYFILE2_COPY_PHASE { + COPYFILE2_PHASE_NONE = 0, + COPYFILE2_PHASE_PREPARE_SOURCE, + COPYFILE2_PHASE_PREPARE_DEST, + COPYFILE2_PHASE_READ_SOURCE, + COPYFILE2_PHASE_WRITE_DESTINATION, + COPYFILE2_PHASE_SERVER_COPY, + COPYFILE2_PHASE_NAMEGRAFT_COPY, + COPYFILE2_PHASE_MAX +} TYPEDEF_TYPE_NAME(COPYFILE2_COPY_PHASE); + +typedef enum _COPYFILE2_MESSAGE_TYPE { + COPYFILE2_CALLBACK_NONE = 0, + COPYFILE2_CALLBACK_CHUNK_STARTED, + COPYFILE2_CALLBACK_CHUNK_FINISHED, + COPYFILE2_CALLBACK_STREAM_STARTED, + COPYFILE2_CALLBACK_STREAM_FINISHED, + COPYFILE2_CALLBACK_POLL_CONTINUE, + COPYFILE2_CALLBACK_ERROR, + COPYFILE2_CALLBACK_MAX +} TYPEDEF_TYPE_NAME(COPYFILE2_MESSAGE_TYPE); + +typedef struct _COPYFILE2_MESSAGE { + COPYFILE2_MESSAGE_TYPE Type; + DWORD dwPadding; + + union { + struct { + DWORD dwStreamNumber; + DWORD dwReserved; + HANDLE hSourceFile; + HANDLE hDestinationFile; + ULARGE_INTEGER uliChunkNumber; + ULARGE_INTEGER uliChunkSize; + ULARGE_INTEGER uliStreamSize; + ULARGE_INTEGER uliTotalFileSize; + } ChunkStarted; + + struct { + DWORD dwStreamNumber; + DWORD dwFlags; + HANDLE hSourceFile; + HANDLE hDestinationFile; + ULARGE_INTEGER uliChunkNumber; + ULARGE_INTEGER uliChunkSize; + ULARGE_INTEGER uliStreamSize; + ULARGE_INTEGER uliStreamBytesTransferred; + ULARGE_INTEGER uliTotalFileSize; + ULARGE_INTEGER uliTotalBytesTransferred; + } ChunkFinished; + + struct { + DWORD dwStreamNumber; + DWORD dwReserved; + HANDLE hSourceFile; + HANDLE hDestinationFile; + ULARGE_INTEGER uliStreamSize; + ULARGE_INTEGER uliTotalFileSize; + } StreamStarted; + + struct { + DWORD dwStreamNumber; + DWORD dwReserved; + HANDLE hSourceFile; + HANDLE hDestinationFile; + ULARGE_INTEGER uliStreamSize; + ULARGE_INTEGER uliStreamBytesTransferred; + ULARGE_INTEGER uliTotalFileSize; + ULARGE_INTEGER uliTotalBytesTransferred; + } StreamFinished; + + struct { + DWORD dwReserved; + } PollContinue; + + struct { + COPYFILE2_COPY_PHASE CopyPhase; + DWORD dwStreamNumber; + HRESULT hrFailure; + DWORD dwReserved; + ULARGE_INTEGER uliChunkNumber; + ULARGE_INTEGER uliStreamSize; + ULARGE_INTEGER uliStreamBytesTransferred; + ULARGE_INTEGER uliTotalFileSize; + ULARGE_INTEGER uliTotalBytesTransferred; + } Error; + } Info; +} TYPEDEF_TYPE_NAME(COPYFILE2_MESSAGE); + +typedef COPYFILE2_MESSAGE_ACTION (CALLBACK *PCOPYFILE2_PROGRESS_ROUTINE) ( + IN PCCOPYFILE2_MESSAGE Message, + IN PVOID Context OPTIONAL); + +#define COPY_FILE_DIRECTORY 0x00000080 // Win10 +#define COPY_FILE_REQUEST_SECURITY_PRIVILEGES 0x00002000 // Win8 +#define COPY_FILE_RESUME_FROM_PAUSE 0x00004000 // Win8 +#define COPY_FILE_SKIP_ALTERNATE_STREAMS 0x00008000 // Win10 +#define COPY_FILE_NO_OFFLOAD 0x00040000 // Win8 +#define COPY_FILE_OPEN_AND_COPY_REPARSE_POINT 0x00200000 // Win10 +#define COPY_FILE_IGNORE_EDP_BLOCK 0x00400000 // Win10 +#define COPY_FILE_IGNORE_SOURCE_ENCRYPTION 0x00800000 // Win10 +#define COPY_FILE_DONT_REQUEST_DEST_WRITE_DAC 0x02000000 // Win10 +#define COPY_FILE_DISABLE_PRE_ALLOCATION 0x04000000 // Win10 +#define COPY_FILE_ENABLE_LOW_FREE_SPACE_MODE 0x08000000 // Win10 +#define COPY_FILE_REQUEST_COMPRESSED_TRAFFIC 0x10000000 // Win10 +#define COPY_FILE_ENABLE_SPARSE_COPY 0x20000000 // Win11 + +#define COPY_FILE_WIN7_VALID_FLAGS (COPY_FILE_FAIL_IF_EXISTS | COPY_FILE_RESTARTABLE | \ + COPY_FILE_OPEN_SOURCE_FOR_WRITE | COPY_FILE_ALLOW_DECRYPTED_DESTINATION | \ + COPY_FILE_COPY_SYMLINK | COPY_FILE_NO_BUFFERING) + +#define COPY_FILE_WIN8_VALID_FLAGS (COPY_FILE_WIN7_VALID_FLAGS | COPY_FILE_REQUEST_SECURITY_PRIVILEGES | \ + COPY_FILE_RESUME_FROM_PAUSE | COPY_FILE_NO_OFFLOAD) + +#define COPY_FILE_WIN10_VALID_FLAGS (COPY_FILE_WIN8_VALID_FLAGS | COPY_FILE_DIRECTORY | COPY_FILE_SKIP_ALTERNATE_STREAMS | \ + COPY_FILE_OPEN_AND_COPY_REPARSE_POINT | COPY_FILE_IGNORE_EDP_BLOCK | \ + COPY_FILE_IGNORE_SOURCE_ENCRYPTION | COPY_FILE_DONT_REQUEST_DEST_WRITE_DAC | \ + COPY_FILE_DISABLE_PRE_ALLOCATION | COPY_FILE_ENABLE_LOW_FREE_SPACE_MODE | \ + COPY_FILE_REQUEST_COMPRESSED_TRAFFIC) + +#define COPY_FILE_WIN11_VALID_FLAGS (COPY_FILE_WIN10_VALID_FLAGS | COPY_FILE_ENABLE_SPARSE_COPY) + +#define COPY_FILE_ALL_VALID_FLAGS (COPY_FILE_WIN11_VALID_FLAGS) + +typedef struct _COPYFILE2_EXTENDED_PARAMETERS { + DWORD dwSize; + DWORD dwCopyFlags; // COPY_FILE_* + PBOOL pfCancel; + PCOPYFILE2_PROGRESS_ROUTINE pProgressRoutine; + PVOID pvCallbackContext; +} TYPEDEF_TYPE_NAME(COPYFILE2_EXTENDED_PARAMETERS); + +typedef PVOID TYPEDEF_TYPE_NAME(DLL_DIRECTORY_COOKIE); + +// Don't confuse this with THREADINFOCLASS from NtDll.h. +// They are two completely separate things, and yes, this is the official +// naming and not just something I made up. +typedef enum _THREAD_INFORMATION_CLASS { + ThreadMemoryPriority, + ThreadAbsoluteCpuPriority, + ThreadDynamicCodePolicy, + ThreadPowerThrottling, + ThreadInformationClassMax +} TYPEDEF_TYPE_NAME(THREAD_INFORMATION_CLASS); + +typedef enum _PROCESS_INFORMATION_CLASS { + ProcessMemoryPriority, + ProcessMemoryExhaustionInfo, + ProcessAppMemoryInfo, + ProcessInPrivateInfo, + ProcessPowerThrottling, + ProcessReservedValue1, + ProcessTelemetryCoverageInfo, + ProcessProtectionLevelInfo, + ProcessLeapSecondInfo, + ProcessMachineTypeInfo, + ProcessOverrideSubsequentPrefetchParameter, + ProcessMaxOverridePrefetchParameter, + ProcessInformationClassMax +} TYPEDEF_TYPE_NAME(PROCESS_INFORMATION_CLASS); + +typedef struct _THREAD_POWER_THROTTLING_STATE { + ULONG Version; + ULONG ControlMask; + ULONG StateMask; +} TYPEDEF_TYPE_NAME(THREAD_POWER_THROTTLING_STATE); + +typedef enum _PROCESS_MITIGATION_POLICY { + ProcessDEPPolicy, + ProcessASLRPolicy, + ProcessDynamicCodePolicy, + ProcessStrictHandleCheckPolicy, + ProcessSystemCallDisablePolicy, + ProcessMitigationOptionsMask, + ProcessExtensionPointDisablePolicy, + ProcessControlFlowGuardPolicy, + ProcessSignaturePolicy, + ProcessFontDisablePolicy, + ProcessImageLoadPolicy, + ProcessSystemCallFilterPolicy, + ProcessPayloadRestrictionPolicy, + ProcessChildProcessPolicy, + ProcessSideChannelIsolationPolicy, + ProcessUserShadowStackPolicy, + ProcessRedirectionTrustPolicy, + MaxProcessMitigationPolicy +} TYPEDEF_TYPE_NAME(PROCESS_MITIGATION_POLICY); + +typedef struct _PROCESS_MITIGATION_DEP_POLICY { + union { + ULONG AsUlong; + + struct { + ULONG Enable : 1; + ULONG DisableAtlThunkEmulation : 1; + ULONG ReservedFlags : 30; + }; + } Flags; + + BOOLEAN Permanent; +} TYPEDEF_TYPE_NAME(PROCESS_MITIGATION_DEP_POLICY); + +DECLARE_HANDLE(HPSS); +DECLARE_HANDLE(HPSSWALK); +GEN_STD_TYPEDEFS(HPSS); +GEN_STD_TYPEDEFS(HPSSWALK); + +typedef enum _PSS_CAPTURE_FLAGS { + PSS_CAPTURE_NONE = 0x00000000, + PSS_CAPTURE_VA_CLONE = 0x00000001, + PSS_CAPTURE_RESERVED_00000002 = 0x00000002, + PSS_CAPTURE_HANDLES = 0x00000004, + PSS_CAPTURE_HANDLE_NAME_INFORMATION = 0x00000008, + PSS_CAPTURE_HANDLE_BASIC_INFORMATION = 0x00000010, + PSS_CAPTURE_HANDLE_TYPE_SPECIFIC_INFORMATION = 0x00000020, + PSS_CAPTURE_HANDLE_TRACE = 0x00000040, + PSS_CAPTURE_THREADS = 0x00000080, + PSS_CAPTURE_THREAD_CONTEXT = 0x00000100, + PSS_CAPTURE_THREAD_CONTEXT_EXTENDED = 0x00000200, + PSS_CAPTURE_RESERVED_00000400 = 0x00000400, + PSS_CAPTURE_VA_SPACE = 0x00000800, + PSS_CAPTURE_VA_SPACE_SECTION_INFORMATION = 0x00001000, + PSS_CAPTURE_IPT_TRACE = 0x00002000, + PSS_CAPTURE_RESERVED_00004000 = 0x00004000, + + PSS_CREATE_BREAKAWAY_OPTIONAL = 0x04000000, + PSS_CREATE_BREAKAWAY = 0x08000000, + PSS_CREATE_FORCE_BREAKAWAY = 0x10000000, + PSS_CREATE_USE_VM_ALLOCATIONS = 0x20000000, + PSS_CREATE_MEASURE_PERFORMANCE = 0x40000000, + PSS_CREATE_RELEASE_SECTION = 0x80000000 +} TYPEDEF_TYPE_NAME(PSS_CAPTURE_FLAGS); + +typedef enum _PSS_QUERY_INFORMATION_CLASS { + PSS_QUERY_PROCESS_INFORMATION = 0, + PSS_QUERY_VA_CLONE_INFORMATION = 1, + PSS_QUERY_AUXILIARY_PAGES_INFORMATION = 2, + PSS_QUERY_VA_SPACE_INFORMATION = 3, + PSS_QUERY_HANDLE_INFORMATION = 4, + PSS_QUERY_THREAD_INFORMATION = 5, + PSS_QUERY_HANDLE_TRACE_INFORMATION = 6, + PSS_QUERY_PERFORMANCE_COUNTERS = 7 +} TYPEDEF_TYPE_NAME(PSS_QUERY_INFORMATION_CLASS); + +typedef PVOID (WINAPI *PPSS_ALLOCATOR_ALLOC_ROUTINE) ( + IN PVOID Context, + IN ULONG Size); + +typedef VOID (WINAPI *PPSS_ALLOCATOR_FREE_ROUTINE) ( + IN PVOID Context, + IN PVOID Address); + +typedef struct _PSS_ALLOCATOR { + PVOID Context; + PPSS_ALLOCATOR_ALLOC_ROUTINE AllocRoutine; + PPSS_ALLOCATOR_FREE_ROUTINE FreeRoutine; +} TYPEDEF_TYPE_NAME(PSS_ALLOCATOR); + +typedef enum _CM_NOTIFY_FILTER_TYPE { + CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE, + CM_NOTIFY_FILTER_TYPE_DEVICEHANDLE, + CM_NOTIFY_FILTER_TYPE_DEVICEINSTANCE, + CM_NOTIFY_FILTER_TYPE_MAX +} CM_NOTIFY_FILTER_TYPE, *PCM_NOTIFY_FILTER_TYPE; + +DECLARE_HANDLE(HCMNOTIFICATION); +GEN_STD_TYPEDEFS(HCMNOTIFICATION); + + +typedef enum _CM_NOTIFY_ACTION { + // Filter type: CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE + CM_NOTIFY_ACTION_DEVICEINTERFACEARRIVAL, + CM_NOTIFY_ACTION_DEVICEINTERFACEREMOVAL, + + // Filter type: CM_NOTIFY_FILTER_TYPE_DEVICEHANDLE + CM_NOTIFY_ACTION_DEVICEQUERYREMOVE, + CM_NOTIFY_ACTION_DEVICEQUERYREMOVEFAILED, + CM_NOTIFY_ACTION_DEVICEREMOVEPENDING, + CM_NOTIFY_ACTION_DEVICEREMOVECOMPLETE, + CM_NOTIFY_ACTION_DEVICECUSTOMEVENT, + + // Filter type: CM_NOTIFY_FILTER_TYPE_DEVICEINSTANCE + CM_NOTIFY_ACTION_DEVICEINSTANCEENUMERATED, + CM_NOTIFY_ACTION_DEVICEINSTANCESTARTED, + CM_NOTIFY_ACTION_DEVICEINSTANCEREMOVED, + + CM_NOTIFY_ACTION_MAX +} TYPEDEF_TYPE_NAME(CM_NOTIFY_ACTION); + +typedef struct _CM_NOTIFY_EVENT_DATA { + CM_NOTIFY_FILTER_TYPE FilterType; + DWORD Reserved; + + union { + struct { + GUID ClassGuid; + WCHAR SymbolicLink[ANYSIZE_ARRAY]; + } DeviceInterface; + + struct { + GUID EventGuid; + LONG NameOffset; + DWORD DataSize; + BYTE Data[ANYSIZE_ARRAY]; + } DeviceHandle; + + struct { + WCHAR InstanceId[ANYSIZE_ARRAY]; + } DeviceInstance; + }; +} TYPEDEF_TYPE_NAME(CM_NOTIFY_EVENT_DATA); + +typedef DWORD (CALLBACK *PCM_NOTIFY_CALLBACK) ( + IN HCMNOTIFICATION hNotify, + IN PVOID Context OPTIONAL, + IN CM_NOTIFY_ACTION Action, + IN PCM_NOTIFY_EVENT_DATA EventData, + IN DWORD EventDataSize); + +typedef struct _CM_NOTIFY_FILTER { + DWORD cbSize; + DWORD Flags; + CM_NOTIFY_FILTER_TYPE FilterType; + DWORD Reserved; + + union { + struct { + GUID ClassGuid; + } DeviceInterface; + struct { + HANDLE hTarget; + } DeviceHandle; + struct { + WCHAR InstanceId[MAX_DEVICE_ID_LEN]; + } DeviceInstance; + }; +} TYPEDEF_TYPE_NAME(CM_NOTIFY_FILTER); + +typedef enum _FIRMWARE_TYPE { + FirmwareTypeUnknown, + FirmwareTypeBios, + FirmwareTypeUefi, + FirmwareTypeMax +} TYPEDEF_TYPE_NAME(FIRMWARE_TYPE); + +typedef enum _APP_POLICY_WINDOWING_MODEL { + AppPolicyWindowingModel_None, + AppPolicyWindowingModel_Universal, + AppPolicyWindowingModel_ClassicDesktop, + AppPolicyWindowingModel_ClassicPhone +} TYPEDEF_TYPE_NAME(APP_POLICY_WINDOWING_MODEL); + +typedef enum _APP_POLICY_THREAD_INITIALIZATION_TYPE { + AppPolicyThreadInitializationType_None, + AppPolicyThreadInitializationType_InitializeWinRT +} TYPEDEF_TYPE_NAME(APP_POLICY_THREAD_INITIALIZATION_TYPE); + +#pragma endregion + +#if defined(KEX_ENV_WIN32) + +WINBASEAPI PKERNELBASE_GLOBAL_DATA WINAPI KernelBaseGetGlobalData( + VOID); + +WINBASEAPI ULONG WINAPI BaseSetLastNTError( + IN NTSTATUS Status); + +// +// thread.c +// + +KXBASEAPI HRESULT WINAPI GetThreadDescription( + IN HANDLE ThreadHandle, + OUT PPWSTR ThreadDescription); + +KXBASEAPI HRESULT WINAPI SetThreadDescription( + IN HANDLE ThreadHandle, + IN PCWSTR ThreadDescription); + +KXBASEAPI VOID WINAPI GetCurrentThreadStackLimits( + OUT PULONG_PTR LowLimit, + OUT PULONG_PTR HighLimit); + +KXBASEAPI BOOL WINAPI SetThreadInformation( + IN HANDLE ThreadHandle, + IN THREAD_INFORMATION_CLASS ThreadInformationClass, + IN PVOID ThreadInformation, + IN ULONG ThreadInformationSize); + +KXBASEAPI BOOL WINAPI GetThreadInformation( + IN HANDLE ThreadHandle, + IN THREAD_INFORMATION_CLASS ThreadInformationClass, + OUT PVOID ThreadInformation, + IN ULONG ThreadInformationSize); + +KXBASEAPI BOOL WINAPI SetThreadSelectedCpuSets( + IN HANDLE ThreadHandle, + IN PULONG CpuSetIds, + IN ULONG NumberOfCpuSetIds); + +KXBASEAPI BOOL WINAPI SetThreadSelectedCpuSetMasks( + IN HANDLE ThreadHandle, + IN PGROUP_AFFINITY CpuSetMasks, + IN ULONG NumberOfCpuSetMasks); + +KXBASEAPI BOOL WINAPI GetThreadSelectedCpuSets( + IN HANDLE ThreadHandle, + OUT PULONG CpuSetIds, + IN ULONG CpuSetIdArraySize, + OUT PULONG ReturnCount); + +KXBASEAPI BOOL WINAPI GetThreadSelectedCpuSetMasks( + IN HANDLE ThreadHandle, + OUT PGROUP_AFFINITY CpuSetMasks, + IN ULONG CpuSetMaskArraySize, + OUT PULONG ReturnCount); + +// +// process.c +// + +KXBASEAPI BOOL WINAPI GetProcessInformation( + IN HANDLE ProcessHandle, + IN PROCESS_INFORMATION_CLASS ProcessInformationClass, + OUT PVOID ProcessInformation, + IN ULONG ProcessInformationSize); + +KXBASEAPI BOOL WINAPI SetProcessInformation( + IN HANDLE ProcessHandle, + IN PROCESS_INFORMATION_CLASS ProcessInformationClass, + IN PVOID ProcessInformation, + IN ULONG ProcessInformationSize); + +KXBASEAPI BOOL WINAPI SetProcessDefaultCpuSets( + IN HANDLE ProcessHandle, + IN PULONG CpuSetIds, + IN ULONG NumberOfCpuSetIds); + +KXBASEAPI BOOL WINAPI SetProcessDefaultCpuSetMasks( + IN HANDLE ProcessHandle, + IN PGROUP_AFFINITY CpuSetMasks, + IN ULONG NumberOfCpuSetMasks); + +KXBASEAPI BOOL WINAPI GetProcessDefaultCpuSets( + IN HANDLE ProcessHandle, + OUT PULONG CpuSetIds, + IN ULONG CpuSetIdArraySize, + OUT PULONG ReturnCount); + +KXBASEAPI BOOL WINAPI GetProcessDefaultCpuSetMasks( + IN HANDLE ProcessHandle, + OUT PGROUP_AFFINITY CpuSetMasks, + IN ULONG CpuSetMaskArraySize, + OUT PULONG ReturnCount); + +KXBASEAPI BOOL WINAPI SetProcessMitigationPolicy( + IN PROCESS_MITIGATION_POLICY MitigationPolicy, + IN PVOID Buffer, + IN SIZE_T BufferCb); + +KXBASEAPI BOOL WINAPI GetProcessMitigationPolicy( + IN HANDLE ProcessHandle, + IN PROCESS_MITIGATION_POLICY MitigationPolicy, + OUT PVOID Buffer, + IN SIZE_T BufferCb); + +// +// file.c +// + +KXBASEAPI HANDLE WINAPI CreateFile2( + IN PCWSTR FileName, + IN ULONG DesiredAccess, + IN ULONG ShareMode, + IN ULONG CreationDisposition, + IN PCREATEFILE2_EXTENDED_PARAMETERS ExtendedParameters OPTIONAL); + +KXBASEAPI ULONG WINAPI GetTempPath2A( + IN ULONG BufferCch, + OUT PSTR Buffer); + +KXBASEAPI ULONG WINAPI GetTempPath2W( + IN ULONG BufferCch, + OUT PWSTR Buffer); + +KXBASEAPI HRESULT WINAPI CopyFile2( + IN PCWSTR ExistingFileName, + IN PCWSTR NewFileName, + IN PCOPYFILE2_EXTENDED_PARAMETERS ExtendedParameters OPTIONAL); + +// +// time.c +// + +KXBASEAPI VOID WINAPI GetSystemTimePreciseAsFileTime( + OUT PFILETIME SystemTimeAsFileTime); + +// +// synch.c +// + +KXBASEAPI BOOL WINAPI WaitOnAddress( + IN VOLATILE VOID *Address, + IN PVOID CompareAddress, + IN SIZE_T AddressSize, + IN DWORD Milliseconds OPTIONAL); + +KXBASEAPI VOID WINAPI WakeByAddressSingle( + IN PVOID Address); + +KXBASEAPI VOID WINAPI WakeByAddressAll( + IN PVOID Address); + +// +// wow64.c +// + +KXBASEAPI BOOL WINAPI IsWow64Process2( + IN HANDLE ProcessHandle, + OUT PUSHORT ProcessMachine, + OUT PUSHORT NativeMachine); + +// +// appmodel.c +// + +KXBASEAPI LONG WINAPI GetCurrentPackageFullName( + IN OUT PULONG PackageFullNameLength, + OUT PWSTR PackageFullName OPTIONAL); + +KXBASEAPI LONG WINAPI GetCurrentPackageId( + IN OUT PULONG BufferLength, + OUT PBYTE Buffer OPTIONAL); + +KXBASEAPI LONG WINAPI AppPolicyGetProcessTerminationMethod( + IN HANDLE ProcessToken, + OUT PULONG Policy); + +KXBASEAPI HRESULT WINAPI CreateAppContainerProfile( + IN PCWSTR AppContainerName, + IN PCWSTR DisplayName, + IN PCWSTR Description, + IN PSID_AND_ATTRIBUTES Capabilities, + IN ULONG NumberOfCapabilities, + OUT PSID *AppContainerSid); + +KXBASEAPI HRESULT WINAPI DeleteAppContainerProfile( + IN PCWSTR AppContainerName); + +KXBASEAPI HRESULT WINAPI GetAppContainerFolderPath( + IN PCWSTR AppContainerName, + OUT PPWSTR FolderPath); + +KXBASEAPI HRESULT WINAPI GetAppContainerRegistryLocation( + IN REGSAM DesiredAccess, + OUT PHKEY AppContainerKey); + +// +// vmem.c +// + +KXBASEAPI ULONG WINAPI OfferVirtualMemory( + IN PVOID VirtualAddress, + IN SIZE_T Size, + IN OFFER_PRIORITY Priority); + +KXBASEAPI ULONG WINAPI DiscardVirtualMemory( + IN PVOID VirtualAddress, + IN SIZE_T Size); + +KXBASEAPI ULONG WINAPI ReclaimVirtualMemory( + IN PCVOID VirtualAddress, + IN SIZE_T Size); + +KXBASEAPI BOOL WINAPI PrefetchVirtualMemory( + IN HANDLE ProcessHandle, + IN ULONG_PTR NumberOfEntries, + IN PWIN32_MEMORY_RANGE_ENTRY VirtualAddresses, + IN ULONG Flags); + +// +// misc.c +// + +KXBASEAPI BOOL WINAPI GetOsSafeBootMode( + OUT PBOOL IsSafeBootMode); + +KXBASEAPI BOOL WINAPI GetFirmwareType( + OUT PFIRMWARE_TYPE FirmwareType); + +// +// module.c +// + +KXBASEAPI DLL_DIRECTORY_COOKIE WINAPI Ext_AddDllDirectory( + IN PCWSTR NewDirectory); + +KXBASEAPI BOOL WINAPI Ext_RemoveDllDirectory( + IN DLL_DIRECTORY_COOKIE Cookie); + +KXBASEAPI BOOL WINAPI Ext_SetDefaultDllDirectories( + IN ULONG DirectoryFlags); + +#endif // if defined(KEX_ENV_WIN32) \ No newline at end of file diff --git a/00-Common Headers/KxCfgHlp.h b/00-Common Headers/KxCfgHlp.h new file mode 100644 index 0000000..70e40af --- /dev/null +++ b/00-Common Headers/KxCfgHlp.h @@ -0,0 +1,201 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// KxCfgHlp.h +// +// Abstract: +// +// Main header file for the VxKex Configuration Helper library. +// +// Author: +// +// vxiiduu (02-Feb-2024) +// +// Environment: +// +// Win32 mode. +// +// Revision History: +// +// vxiiduu 02-Feb-2024 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#pragma once +#include +#include +#include + +#ifdef KEX_ENV_NATIVE +# error This header file cannot be used in a native mode project. +#endif + +#ifndef KXCFGDECLSPEC +# define KXCFGDECLSPEC +# pragma comment(lib, "KxCfgHlp.lib") +#endif + +#define KXCFGAPI WINAPI + +#define KXCFG_ELEVATION_SCHTASK_NAME L"VxKex Configuration Elevation Task" + +// +// Type definitions +// + +typedef struct { + BOOLEAN Enabled; + BOOLEAN DisableForChild; + BOOLEAN DisableAppSpecificHacks; + KEX_WIN_VER_SPOOF WinVerSpoof; + ULONG StrongSpoofOptions; +} TYPEDEF_TYPE_NAME(KXCFG_PROGRAM_CONFIGURATION); + +// +// ExeFullPathOrBaseName can be either a full path (C:\folder\program.exe) +// or a basename (program.exe). The callee can determine this easily by +// checking IsLegacyConfiguration (TRUE means it's a base name only). +// +// This function should return TRUE to continue enumeration or FALSE to stop +// enumerating. +// +typedef BOOLEAN (CALLBACK *PKXCFG_ENUMERATE_CONFIGURATION_CALLBACK) ( + IN PCWSTR ExeFullPathOrBaseName, + IN BOOLEAN IsLegacyConfiguration, + IN PVOID ExtraParameter); + +// +// Public functions +// + +KXCFGDECLSPEC HKEY KXCFGAPI KxCfgOpenVxKexRegistryKey( + IN BOOLEAN PerUserKey, + IN ACCESS_MASK DesiredAccess, + IN HANDLE TransactionHandle OPTIONAL); + +KXCFGDECLSPEC HKEY KXCFGAPI KxCfgOpenLegacyVxKexRegistryKey( + IN BOOLEAN PerUserKey, + IN ACCESS_MASK DesiredAccess, + IN HANDLE TransactionHandle OPTIONAL); + +KXCFGDECLSPEC BOOLEAN KXCFGAPI KxCfgGetConfiguration( + IN PCWSTR ExeFullPath, + OUT PKXCFG_PROGRAM_CONFIGURATION Configuration); + +KXCFGDECLSPEC BOOLEAN KXCFGAPI KxCfgEnumerateConfiguration( + IN PKXCFG_ENUMERATE_CONFIGURATION_CALLBACK ConfigurationCallback, + IN PVOID CallbackExtraParameter); + +KXCFGDECLSPEC BOOLEAN KxCfgSetConfiguration( + IN PCWSTR ExeFullPath, + IN PKXCFG_PROGRAM_CONFIGURATION Configuration, + IN HANDLE TransactionHandle OPTIONAL); + +KXCFGDECLSPEC BOOLEAN KxCfgDeleteConfiguration( + IN PCWSTR ExeFullPath, + IN HANDLE TransactionHandle OPTIONAL); + +KXCFGDECLSPEC BOOLEAN KXCFGAPI KxCfgDeleteLegacyConfiguration( + IN PCWSTR ExeFullPath, + IN HANDLE TransactionHandle OPTIONAL); + +KXCFGDECLSPEC BOOLEAN KXCFGAPI KxCfgGetKexDir( + OUT PWSTR Buffer, + IN ULONG BufferCch); + +KXCFGDECLSPEC BOOLEAN WINAPI KxCfgEnableVxKexForMsiexec( + IN BOOLEAN Enable, + IN HANDLE TransactionHandle OPTIONAL); + +KXCFGDECLSPEC BOOLEAN WINAPI KxCfgQueryVxKexEnabledForMsiexec( + VOID); + +KXCFGDECLSPEC BOOLEAN KXCFGAPI KxCfgEnableExplorerCpiwBypass( + IN BOOLEAN Enable, + IN HANDLE TransactionHandle OPTIONAL); + +KXCFGDECLSPEC BOOLEAN KXCFGAPI KxCfgQueryExplorerCpiwBypass( + VOID); + +KXCFGDECLSPEC BOOLEAN KXCFGAPI KxCfgQueryShellContextMenuEntries( + OUT PBOOLEAN ExtendedMenu OPTIONAL); + +KXCFGDECLSPEC BOOLEAN KXCFGAPI KxCfgConfigureShellContextMenuEntries( + IN BOOLEAN Enable, + IN BOOLEAN ExtendedMenu, + IN HANDLE TransactionHandle OPTIONAL); + +KXCFGDECLSPEC BOOLEAN KXCFGAPI KxCfgQueryLoggingSettings( + OUT PBOOLEAN IsEnabled OPTIONAL, + OUT PWSTR LogDir OPTIONAL, + IN ULONG LogDirCch); + +KXCFGDECLSPEC BOOLEAN KXCFGAPI KxCfgConfigureLoggingSettings( + IN BOOLEAN Enabled, + IN PCWSTR LogDir OPTIONAL, + IN HANDLE TransactionHandle OPTIONAL); + +KXCFGDECLSPEC BOOLEAN KXCFGAPI KxCfgInstallDiskCleanupHandler( + IN PCWSTR KexDir OPTIONAL, + IN PCWSTR LogDir OPTIONAL, + IN HANDLE TransactionHandle OPTIONAL); + +KXCFGDECLSPEC BOOLEAN KXCFGAPI KxCfgRemoveDiskCleanupHandler( + IN HANDLE TransactionHandle OPTIONAL); + +#ifdef KXCFGDECLSPEC +// +// Private functions +// + +BOOLEAN KxCfgpRemoveKexDllFromVerifierDlls( + IN PWSTR VerifierDlls); + +BOOLEAN KxCfgpCreateIfeoKeyForProgram( + IN PCWSTR ExeFullPath, + OUT PHKEY KeyHandle, + IN HANDLE TransactionHandle OPTIONAL); + +BOOLEAN KxCfgpElevationRequired( + VOID); + +BOOLEAN KxCfgpElevatedSetConfiguration( + IN PCWSTR ExeFullPath, + IN PKXCFG_PROGRAM_CONFIGURATION Configuration); + +BOOLEAN KxCfgpElevatedDeleteConfiguration( + IN PCWSTR ExeFullPath); + +BOOLEAN KxCfgpElevatedSetConfigurationTaskScheduler( + IN PCWSTR ExeFullPath, + IN PKXCFG_PROGRAM_CONFIGURATION Configuration); + +BOOLEAN KxCfgpElevatedSetConfigurationShellExecute( + IN PCWSTR ExeFullPath, + IN PKXCFG_PROGRAM_CONFIGURATION Configuration); + +BOOLEAN KxCfgpAssembleKexCfgCommandLine( + OUT PWSTR Buffer, + IN ULONG BufferCch, + IN PCWSTR ExeFullPath, + IN PKXCFG_PROGRAM_CONFIGURATION Configuration); + +HKEY KxCfgpCreateKey( + IN HKEY RootDirectory, + IN PCWSTR KeyPath, + IN ACCESS_MASK DesiredAccess, + IN HANDLE TransactionHandle OPTIONAL); + +HKEY KxCfgpOpenKey( + IN HKEY RootDirectory, + IN PCWSTR KeyPath, + IN ACCESS_MASK DesiredAccess, + IN HANDLE TransactionHandle OPTIONAL); + +ULONG KxCfgpDeleteKey( + IN HKEY KeyHandle, + IN PCWSTR KeyPath OPTIONAL, + IN HANDLE TransactionHandle OPTIONAL); + +#endif \ No newline at end of file diff --git a/00-Common Headers/KxCom.h b/00-Common Headers/KxCom.h new file mode 100644 index 0000000..f23d416 --- /dev/null +++ b/00-Common Headers/KxCom.h @@ -0,0 +1,623 @@ +#pragma once + +#include +#include + +#ifndef KXCOMAPI +# define KXCOMAPI +#else +# ifdef KXCOM_WANT_INITGUID +# include +# endif +#endif + +#define E_STRING_NOT_NULL_TERMINATED ((HRESULT) 0x80000017L) +#define E_BOUNDS ((HRESULT) 0x8000000BL) +#define HRESULT_ARITHMETIC_OVERFLOW ((HRESULT) 0x80070216L) + +#define WRHF_STRING_BUFFER_MAGIC 0xF8B1A8BE + +#define WRHF_NONE 0x0 +#define WRHF_STRING_REFERENCE 0x1 +#define WRHF_VALID_UNICODE_FORMAT_INFO 0x2 +#define WRHF_WELL_FORMED_UNICODE 0x4 +#define WRHF_HAS_EMBEDDED_NULLS 0x8 +#define WRHF_EMBEDDED_NULLS_COMPUTED 0x10 +#define WRHF_RESERVED_FOR_PREALLOCATED_STRING_BUFFER 0x80000000 + +typedef struct _HSTRING_HEADER { + ULONG Flags; // WRHF_* + ULONG Length; // Does not include null terminator + ULONG Padding1; + ULONG Padding2; + PCWSTR StringRef; +} HSTRING_HEADER, *HSTRING; + +typedef struct _HSTRING_ALLOCATED { + HSTRING_HEADER Header; + VOLATILE LONG RefCount; + WCHAR Data[1]; +} HSTRING_ALLOCATED; + +typedef enum _RO_INIT_TYPE { + RO_INIT_SINGLETHREADED, + RO_INIT_MULTITHREADED +} TYPEDEF_TYPE_NAME(RO_INIT_TYPE); + +typedef HSTRING_ALLOCATED *HSTRING_BUFFER, **PHSTRING_BUFFER; + +typedef HANDLE TYPEDEF_TYPE_NAME(CO_MTA_USAGE_COOKIE); + +typedef enum _TrustLevel { + BaseTrust, + PartialTrust, + FullTrust +} TrustLevel; + +typedef enum _DayOfWeek { + DayOfWeek_Sunday = 0, + DayOfWeek_Monday = 1, + DayOfWeek_Tuesday = 2, + DayOfWeek_Wednesday = 3, + DayOfWeek_Thursday = 4, + DayOfWeek_Friday = 5, + DayOfWeek_Saturday = 6, +} DayOfWeek; + +// {82BA7092-4C88-427D-A7BC-16DD93FEB67E} +DEFINE_GUID(IID_IRestrictedErrorInfo, 0x82BA7092, 0x4C88, 0x427D, 0xA7, 0xBC, 0x16, 0xDD, 0x93, 0xFE, 0xB6, 0x7E); + +// {66818B96-DC17-4C12-8CA1-8E1FBAA5BF80} +DEFINE_GUID(IID_IInternalErrorInfo, 0x66818B96, 0xDC17, 0x4C12, 0x8C, 0xA1, 0x8E, 0x1F, 0xBA, 0xA5, 0xBF, 0x80); + +// {94EA2B94-E9CC-49E0-C0FF-EE64CA8F5B90} +DEFINE_GUID(IID_IAgileObject, 0x94EA2B94, 0xE9CC, 0x49E0, 0xC0, 0xFF, 0xEE, 0x64, 0xCA, 0x8F, 0x5B, 0x90); + +// {00000035-0000-0000-C000-000000000046} +DEFINE_GUID(IID_IActivationFactory, 0x00000035, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46); + +// {AF86E2E0-B12D-4C6A-9C5A-D7AA65101E90} +DEFINE_GUID(IID_IInspectable, 0xAF86E2E0, 0xB12D, 0x4C6A, 0x9C, 0x5A, 0xD7, 0xAA, 0x65, 0x10, 0x1E, 0x90); + +// {BBE1FA4C-B0E3-4583-BAEF-1F1B2E483E56} +DEFINE_GUID(IID_IVectorView, 0xBBE1FA4C, 0xB0E3, 0x4583, 0xBA, 0xEF, 0x1F, 0x1B, 0x2E, 0x48, 0x3E, 0x56); + +// {01BF4326-ED37-4E96-B0E9-C1340D1EA158} +DEFINE_GUID(IID_IGlobalizationPreferencesStatics, 0x01BF4326, 0xED37, 0x4E96, 0xB0, 0xE9, 0xC1, 0x34, 0x0D, 0x1E, 0xA1, 0x58); + +// {3694DBF9-8F68-44BE-8FF5-195C98EDE8A6} +DEFINE_GUID(IID_IUIViewSettingsInterop, 0x3694DBF9, 0x8F68, 0x44BE, 0x8F, 0xF5, 0x19, 0x5C, 0x98, 0xED, 0xE8, 0xA6); + +// {C63657F6-8850-470D-88F8-455E16EA2C26} +DEFINE_GUID(IID_IUIViewSettings, 0xC63657F6, 0x8850, 0x470D, 0x88, 0xF8, 0x45, 0x5E, 0x16, 0xEA, 0x2C, 0x26); + +// {85361600-1C63-4627-BCB1-3A89E0BC9C55} +DEFINE_GUID(IID_IUISettings, 0x85361600, 0x1C63, 0x4627, 0xBC, 0xB1, 0x3A, 0x89, 0xE0, 0xBC, 0x9C, 0x55); + +// {03021BE4-5254-4781-8194-5168F7D06D7B} +DEFINE_GUID(IID_IUISettings3, 0x03021BE4, 0x5254, 0x4781, 0x81, 0x94, 0x51, 0x68, 0xF7, 0xD0, 0x6D, 0x7B); + +// {44A9796F-723E-4FDF-A218-033E75B0C084} +DEFINE_GUID(IID_IUriRuntimeClassFactory, 0x44A9796F, 0x723E, 0x4FDF, 0xA2, 0x18, 0x03, 0x3E, 0x75, 0xB0, 0xC0, 0x84); + +// {9E365E57-48B2-4160-956F-C7385120BBFC} +DEFINE_GUID(IID_IUriRuntimeClass, 0x9E365E57, 0x48B2, 0x4160, 0x95, 0x6F, 0xC7, 0x38, 0x51, 0x20, 0xBB, 0xFC); + +// {277151C3-9E3E-42F6-91A4-5DFDEB232451} +DEFINE_GUID(IID_ILauncherStatics, 0x277151C3, 0x9E3E, 0x42F6, 0x91, 0xA4, 0x5D, 0xFD, 0xEB, 0x23, 0x24, 0x51); + +typedef struct _IInspectable IInspectable; + +typedef struct _IInspectableVtbl { + // IUnknown + HRESULT (STDMETHODCALLTYPE *QueryInterface)(IInspectable *, REFIID, PPVOID); + ULONG (STDMETHODCALLTYPE *AddRef)(IInspectable *); + ULONG (STDMETHODCALLTYPE *Release)(IInspectable *); + + // IInspectable + HRESULT (STDMETHODCALLTYPE *GetIids)(IInspectable *, PULONG, IID **); + HRESULT (STDMETHODCALLTYPE *GetRuntimeClassName)(IInspectable *, HSTRING *); + HRESULT (STDMETHODCALLTYPE *GetTrustLevel)(IInspectable *, TrustLevel *); +} IInspectableVtbl; + +typedef struct _IInspectable { + IInspectableVtbl *lpVtbl; +} IInspectable; + +typedef struct _IActivationFactory IActivationFactory; + +typedef struct _IActivationFactoryVtbl { + // IUnknown + HRESULT (STDMETHODCALLTYPE *QueryInterface)(IActivationFactory *, REFIID, PPVOID); + ULONG (STDMETHODCALLTYPE *AddRef)(IActivationFactory *); + ULONG (STDMETHODCALLTYPE *Release)(IActivationFactory *); + + // IInspectable + HRESULT (STDMETHODCALLTYPE *GetIids)(IActivationFactory *, PULONG, IID **); + HRESULT (STDMETHODCALLTYPE *GetRuntimeClassName)(IActivationFactory *, HSTRING *); + HRESULT (STDMETHODCALLTYPE *GetTrustLevel)(IActivationFactory *, TrustLevel *); + + // IActivationFactory + HRESULT (STDMETHODCALLTYPE *ActivateInstance)(IActivationFactory *, IInspectable **); +} IActivationFactoryVtbl; + +typedef struct _IActivationFactory { + IActivationFactoryVtbl *lpVtbl; +} IActivationFactory; + +extern IActivationFactory CActivationFactory; + +typedef struct _IVectorView_HSTRING IVectorView_HSTRING; + +typedef struct _IVectorView_HSTRINGVtbl { + // IUnknown + HRESULT (STDMETHODCALLTYPE *QueryInterface)(IVectorView_HSTRING *, REFIID, PPVOID); + ULONG (STDMETHODCALLTYPE *AddRef)(IVectorView_HSTRING *); + ULONG (STDMETHODCALLTYPE *Release)(IVectorView_HSTRING *); + + // IInspectable + HRESULT (STDMETHODCALLTYPE *GetIids)(IVectorView_HSTRING *, PULONG, IID **); + HRESULT (STDMETHODCALLTYPE *GetRuntimeClassName)(IVectorView_HSTRING *, HSTRING *); + HRESULT (STDMETHODCALLTYPE *GetTrustLevel)(IVectorView_HSTRING *, TrustLevel *); + + // IVectorView_HSTRING + HRESULT (STDMETHODCALLTYPE *GetAt)(IVectorView_HSTRING *, ULONG, HSTRING *); + HRESULT (STDMETHODCALLTYPE *get_Size)(IVectorView_HSTRING *, PULONG); + HRESULT (STDMETHODCALLTYPE *IndexOf)(IVectorView_HSTRING *, HSTRING, PULONG, PBOOLEAN); + HRESULT (STDMETHODCALLTYPE *GetMany)(IVectorView_HSTRING *, ULONG, ULONG, HSTRING *, PULONG); +} IVectorView_HSTRINGVtbl; + +typedef struct _IVectorView_HSTRING { + IVectorView_HSTRINGVtbl *lpVtbl; + LONG RefCount; + ULONG NumberOfHstrings; + HSTRING *HstringArray; +} IVectorView_HSTRING; + +// +// WINRT: Windows.System.UserProfile.GlobalizationPreferences +// + +typedef struct _IGlobalizationPreferencesStatics IGlobalizationPreferencesStatics; + +typedef struct _IGlobalizationPreferencesStaticsVtbl { + // IUnknown + HRESULT (STDMETHODCALLTYPE *QueryInterface)(IGlobalizationPreferencesStatics *, REFIID, PPVOID); + ULONG (STDMETHODCALLTYPE *AddRef)(IGlobalizationPreferencesStatics *); + ULONG (STDMETHODCALLTYPE *Release)(IGlobalizationPreferencesStatics *); + + // IInspectable + HRESULT (STDMETHODCALLTYPE *GetIids)(IGlobalizationPreferencesStatics *, PULONG, IID **); + HRESULT (STDMETHODCALLTYPE *GetRuntimeClassName)(IGlobalizationPreferencesStatics *, HSTRING *); + HRESULT (STDMETHODCALLTYPE *GetTrustLevel)(IGlobalizationPreferencesStatics *, TrustLevel *); + + // IGlobalizationPreferencesStatics + HRESULT (STDMETHODCALLTYPE *get_Calendars)(IGlobalizationPreferencesStatics *, IVectorView_HSTRING **); + HRESULT (STDMETHODCALLTYPE *get_Clocks)(IGlobalizationPreferencesStatics *, IVectorView_HSTRING **); + HRESULT (STDMETHODCALLTYPE *get_Currencies)(IGlobalizationPreferencesStatics *, IVectorView_HSTRING **); + HRESULT (STDMETHODCALLTYPE *get_Languages)(IGlobalizationPreferencesStatics *, IVectorView_HSTRING **); + HRESULT (STDMETHODCALLTYPE *get_HomeGeographicRegion)(IGlobalizationPreferencesStatics *, HSTRING *); + HRESULT (STDMETHODCALLTYPE *get_WeekStartsOn)(IGlobalizationPreferencesStatics *, DayOfWeek *); +} IGlobalizationPreferencesStaticsVtbl; + +typedef struct _IGlobalizationPreferencesStatics { + IGlobalizationPreferencesStaticsVtbl *lpVtbl; +} IGlobalizationPreferencesStatics; + +extern IGlobalizationPreferencesStatics CGlobalizationPreferencesStatics; + +// +// WINRT: Windows.UI.ViewManagement.UIViewSettings +// + +typedef struct _IUIViewSettingsInterop IUIViewSettingsInterop; + +typedef struct _IUIViewSettingsInteropVtbl { + // IUnknown + HRESULT (STDMETHODCALLTYPE *QueryInterface) (IUIViewSettingsInterop *, REFIID, PPVOID); + ULONG (STDMETHODCALLTYPE *AddRef) (IUIViewSettingsInterop *); + ULONG (STDMETHODCALLTYPE *Release) (IUIViewSettingsInterop *); + + // IInspectable + HRESULT (STDMETHODCALLTYPE *GetIids) (IUIViewSettingsInterop *, PULONG, IID **); + HRESULT (STDMETHODCALLTYPE *GetRuntimeClassName) (IUIViewSettingsInterop *, HSTRING *); + HRESULT (STDMETHODCALLTYPE *GetTrustLevel) (IUIViewSettingsInterop *, TrustLevel *); + + // IUIViewSettingsInterop + HRESULT (STDMETHODCALLTYPE *GetForWindow) (IUIViewSettingsInterop *, HWND, REFIID, PPVOID); +} IUIViewSettingsInteropVtbl; + +typedef struct _IUIViewSettingsInterop { + IUIViewSettingsInteropVtbl *lpVtbl; +} IUIViewSettingsInterop; + +typedef enum _UserInteractionMode { + UserInteractionMode_Mouse, + UserInteractionMode_Touch +} UserInteractionMode; + +typedef struct _IUIViewSettings IUIViewSettings; + +typedef struct _IUIViewSettingsVtbl { + // IUnknown + HRESULT (STDMETHODCALLTYPE *QueryInterface) (IUIViewSettings *, REFIID, PPVOID); + ULONG (STDMETHODCALLTYPE *AddRef) (IUIViewSettings *); + ULONG (STDMETHODCALLTYPE *Release) (IUIViewSettings *); + + // IInspectable + HRESULT (STDMETHODCALLTYPE *GetIids) (IUIViewSettings *, PULONG, IID **); + HRESULT (STDMETHODCALLTYPE *GetRuntimeClassName) (IUIViewSettings *, HSTRING *); + HRESULT (STDMETHODCALLTYPE *GetTrustLevel) (IUIViewSettings *, TrustLevel *); + + // IUIViewSettings + HRESULT (STDMETHODCALLTYPE *get_UserInteractionMode) (IUIViewSettings *, UserInteractionMode *); +} IUIViewSettingsVtbl; + +typedef struct _IUIViewSettings { + IUIViewSettingsVtbl *lpVtbl; +} IUIViewSettings; + +extern IUIViewSettingsInterop CUIViewSettingsInterop; +extern IUIViewSettings CUIViewSettings; + +// +// WINRT: Windows.UI.ViewManagement.UISettings +// + +typedef enum _UIElementType { + UIElementType_ActiveCaption = 0, + UIElementType_Background = 1, + UIElementType_ButtonFace = 2, + UIElementType_ButtonText = 3, + UIElementType_CaptionText = 4, + UIElementType_GrayText = 5, + UIElementType_Highlight = 6, + UIElementType_HighlightText = 7, + UIElementType_Hotlight = 8, + UIElementType_InactiveCaption = 9, + UIElementType_InactiveCaptionText = 10, + UIElementType_Window = 11, + UIElementType_WindowText = 12, + UIElementType_AccentColor = 1000, + UIElementType_TextHigh = 1001, + UIElementType_TextMedium = 1002, + UIElementType_TextLow = 1003, + UIElementType_TextContrastWithHigh = 1004, + UIElementType_NonTextHigh = 1005, + UIElementType_NonTextMediumHigh = 1006, + UIElementType_NonTextMedium = 1007, + UIElementType_NonTextMediumLow = 1008, + UIElementType_NonTextLow = 1009, + UIElementType_PageBackground = 1010, + UIElementType_PopupBackground = 1011, + UIElementType_OverlayOutsidePopup = 1012, +} UIElementType; + +typedef enum _UIHandPreference { + HandPreference_LeftHanded, + HandPreference_RightHanded +} UIHandPreference; + +typedef struct _UISettingsSize { + FLOAT Width; + FLOAT Height; +} UISettingsSize; + +typedef struct _UIColor { + BYTE A; + BYTE R; + BYTE G; + BYTE B; +} UIColor; + +typedef struct _IUISettings IUISettings; + +typedef struct _IUISettingsVtbl { + // IUnknown + HRESULT (STDMETHODCALLTYPE *QueryInterface) (IUISettings *, REFIID, PPVOID); + ULONG (STDMETHODCALLTYPE *AddRef) (IUISettings *); + ULONG (STDMETHODCALLTYPE *Release) (IUISettings *); + + // IInspectable + HRESULT (STDMETHODCALLTYPE *GetIids) (IUISettings *, PULONG, IID **); + HRESULT (STDMETHODCALLTYPE *GetRuntimeClassName) (IUISettings *, HSTRING *); + HRESULT (STDMETHODCALLTYPE *GetTrustLevel) (IUISettings *, TrustLevel *); + + // IUISettings + HRESULT (STDMETHODCALLTYPE *get_HandPreference) (IUISettings *, UIHandPreference *); + HRESULT (STDMETHODCALLTYPE *get_CursorSize) (IUISettings *, UISettingsSize *); + HRESULT (STDMETHODCALLTYPE *get_ScrollBarSize) (IUISettings *, UISettingsSize *); + HRESULT (STDMETHODCALLTYPE *get_ScrollBarArrowSize) (IUISettings *, UISettingsSize *); + HRESULT (STDMETHODCALLTYPE *get_ScrollBarThumbBoxSize) (IUISettings *, UISettingsSize *); + HRESULT (STDMETHODCALLTYPE *get_MessageDuration) (IUISettings *, PULONG); + HRESULT (STDMETHODCALLTYPE *get_AnimationsEnabled) (IUISettings *, PBOOLEAN); + HRESULT (STDMETHODCALLTYPE *get_CaretBrowsingEnabled) (IUISettings *, PBOOLEAN); + HRESULT (STDMETHODCALLTYPE *get_CaretBlinkRate) (IUISettings *, PULONG); + HRESULT (STDMETHODCALLTYPE *get_CaretWidth) (IUISettings *, PULONG); + HRESULT (STDMETHODCALLTYPE *get_DoubleClickTime) (IUISettings *, PULONG); + HRESULT (STDMETHODCALLTYPE *get_MouseHoverTime) (IUISettings *, PULONG); + HRESULT (STDMETHODCALLTYPE *UIElementColor) (IUISettings *, UIElementType, UIColor *); +} IUISettingsVtbl; + +typedef struct _IUISettings { + IUISettingsVtbl *lpVtbl; +} IUISettings; + +extern IUISettings CUISettings; + +typedef enum _UIColorType { + UIColorType_Background = 0, + UIColorType_Foreground = 1, + UIColorType_AccentDark3 = 2, + UIColorType_AccentDark2 = 3, + UIColorType_AccentDark1 = 4, + UIColorType_Accent = 5, + UIColorType_AccentLight1 = 6, + UIColorType_AccentLight2 = 7, + UIColorType_AccentLight3 = 8, + UIColorType_Complement = 9, +} UIColorType; + +typedef struct _IUISettings3 IUISettings3; + +typedef struct _IUISettings3Vtbl { + // IUnknown + HRESULT (STDMETHODCALLTYPE *QueryInterface) (IUISettings3 *, REFIID, PPVOID); + ULONG (STDMETHODCALLTYPE *AddRef) (IUISettings3 *); + ULONG (STDMETHODCALLTYPE *Release) (IUISettings3 *); + + // IInspectable + HRESULT (STDMETHODCALLTYPE *GetIids) (IUISettings3 *, PULONG, IID **); + HRESULT (STDMETHODCALLTYPE *GetRuntimeClassName) (IUISettings3 *, HSTRING *); + HRESULT (STDMETHODCALLTYPE *GetTrustLevel) (IUISettings3 *, TrustLevel *); + + // IUISettings3 + HRESULT (STDMETHODCALLTYPE *GetColorValue) (IUISettings3 *, UIColorType, UIColor *); + HRESULT (STDMETHODCALLTYPE *add_ColorValuesChanged) (IUISettings3 *, PVOID, PPVOID); + HRESULT (STDMETHODCALLTYPE *remove_ColorValuesChanged) (IUISettings3 *, PVOID); +} IUISettings3Vtbl; + +typedef struct _IUISettings3 { + IUISettings3Vtbl *lpVtbl; +} IUISettings3; + +extern IUISettings3 CUISettings3; + +typedef struct _IRestrictedErrorInfo IRestrictedErrorInfo; + +typedef struct _IRestrictedErrorInfoVtbl { + // IUnknown + HRESULT (STDMETHODCALLTYPE *QueryInterface)(IRestrictedErrorInfo *, REFIID, PPVOID); + ULONG (STDMETHODCALLTYPE *AddRef)(IRestrictedErrorInfo *); + ULONG (STDMETHODCALLTYPE *Release)(IRestrictedErrorInfo *); + + // IRestrictedErrorInfo + HRESULT (STDMETHODCALLTYPE *GetErrorDetails)(IRestrictedErrorInfo *, BSTR *, HRESULT *, BSTR *, BSTR *); + HRESULT (STDMETHODCALLTYPE *GetReference)(IRestrictedErrorInfo *, BSTR *); +} IRestrictedErrorInfoVtbl; + +typedef struct _IRestrictedErrorInfo { + IRestrictedErrorInfoVtbl *lpVtbl; +} IRestrictedErrorInfo; + +typedef struct _IUriRuntimeClass IUriRuntimeClass; + +typedef struct _IUriRuntimeClassVtbl { + // IUnknown + HRESULT (STDMETHODCALLTYPE *QueryInterface) (IUriRuntimeClass *, REFIID, PPVOID); + ULONG (STDMETHODCALLTYPE *AddRef) (IUriRuntimeClass *); + ULONG (STDMETHODCALLTYPE *Release) (IUriRuntimeClass *); + + // IInspectable + HRESULT (STDMETHODCALLTYPE *GetIids) (IUriRuntimeClass *, PULONG, IID **); + HRESULT (STDMETHODCALLTYPE *GetRuntimeClassName) (IUriRuntimeClass *, HSTRING *); + HRESULT (STDMETHODCALLTYPE *GetTrustLevel) (IUriRuntimeClass *, TrustLevel *); + + // IUriRuntimeClass + HRESULT (STDMETHODCALLTYPE *get_AbsoluteUri) (IUriRuntimeClass *, HSTRING *); + HRESULT (STDMETHODCALLTYPE *get_DisplayUri) (IUriRuntimeClass *, HSTRING *); + HRESULT (STDMETHODCALLTYPE *get_Domain) (IUriRuntimeClass *, HSTRING *); + HRESULT (STDMETHODCALLTYPE *get_Extension) (IUriRuntimeClass *, HSTRING *); + HRESULT (STDMETHODCALLTYPE *get_Fragment) (IUriRuntimeClass *, HSTRING *); + HRESULT (STDMETHODCALLTYPE *get_Host) (IUriRuntimeClass *, HSTRING *); + HRESULT (STDMETHODCALLTYPE *get_Password) (IUriRuntimeClass *, HSTRING *); + HRESULT (STDMETHODCALLTYPE *get_Path) (IUriRuntimeClass *, HSTRING *); + HRESULT (STDMETHODCALLTYPE *get_Query) (IUriRuntimeClass *, HSTRING *); + HRESULT (STDMETHODCALLTYPE *get_QueryParsed) (IUriRuntimeClass *, IUnknown **); // actually IWwwFormUrlDecoderRuntimeClass ** + HRESULT (STDMETHODCALLTYPE *get_RawUri) (IUriRuntimeClass *, HSTRING *); + HRESULT (STDMETHODCALLTYPE *get_SchemeName) (IUriRuntimeClass *, HSTRING *); + HRESULT (STDMETHODCALLTYPE *get_UserName) (IUriRuntimeClass *, HSTRING *); + HRESULT (STDMETHODCALLTYPE *get_Port) (IUriRuntimeClass *, PULONG); + HRESULT (STDMETHODCALLTYPE *get_Suspicious) (IUriRuntimeClass *, PBOOLEAN); + HRESULT (STDMETHODCALLTYPE *Equals) (IUriRuntimeClass *, IUriRuntimeClass *, PBOOLEAN); + HRESULT (STDMETHODCALLTYPE *CombineUri) (IUriRuntimeClass *, HSTRING, IUriRuntimeClass **); +} IUriRuntimeClassVtbl; + +typedef struct _IUriRuntimeClass { + IUriRuntimeClassVtbl *lpVtbl; + LONG RefCount; + IUri *Uri; +} IUriRuntimeClass; + +typedef struct _IUriRuntimeClassFactory IUriRuntimeClassFactory; + +typedef struct _IUriRuntimeClassFactoryVtbl { + // IUnknown + HRESULT (STDMETHODCALLTYPE *QueryInterface) (IUriRuntimeClassFactory *, REFIID, PPVOID); + ULONG (STDMETHODCALLTYPE *AddRef) (IUriRuntimeClassFactory *); + ULONG (STDMETHODCALLTYPE *Release) (IUriRuntimeClassFactory *); + + // IInspectable + HRESULT (STDMETHODCALLTYPE *GetIids) (IUriRuntimeClassFactory *, PULONG, IID **); + HRESULT (STDMETHODCALLTYPE *GetRuntimeClassName) (IUriRuntimeClassFactory *, HSTRING *); + HRESULT (STDMETHODCALLTYPE *GetTrustLevel) (IUriRuntimeClassFactory *, TrustLevel *); + + // IUriRuntimeClassFactory + HRESULT (STDMETHODCALLTYPE *CreateUri) (IUriRuntimeClassFactory *, HSTRING, IUriRuntimeClass **); + HRESULT (STDMETHODCALLTYPE *CreateWithRelativeUri) (IUriRuntimeClassFactory *, HSTRING, HSTRING, IUriRuntimeClass **); +} IUriRuntimeClassFactoryVtbl; + +typedef struct _IUriRuntimeClassFactory { + IUriRuntimeClassFactoryVtbl *lpVtbl; +} IUriRuntimeClassFactory; + +extern IUriRuntimeClassFactory CUriRuntimeClassFactory; + +typedef struct _ILauncherStatics ILauncherStatics; + +typedef struct _ILauncherStaticsVtbl { + // IUnknown + HRESULT (STDMETHODCALLTYPE *QueryInterface) (ILauncherStatics *, REFIID, PPVOID); + ULONG (STDMETHODCALLTYPE *AddRef) (ILauncherStatics *); + ULONG (STDMETHODCALLTYPE *Release) (ILauncherStatics *); + + // IInspectable + HRESULT (STDMETHODCALLTYPE *GetIids) (ILauncherStatics *, PULONG, IID **); + HRESULT (STDMETHODCALLTYPE *GetRuntimeClassName) (ILauncherStatics *, HSTRING *); + HRESULT (STDMETHODCALLTYPE *GetTrustLevel) (ILauncherStatics *, TrustLevel *); + + // ILauncherStatics + HRESULT (STDMETHODCALLTYPE *LaunchFileAsync) (ILauncherStatics *, IUnknown *, IAsyncOperation **); + HRESULT (STDMETHODCALLTYPE *LaunchFileWithOptionsAsync) (ILauncherStatics *, IUnknown *, IUnknown *, IAsyncOperation **); + HRESULT (STDMETHODCALLTYPE *LaunchUriAsync) (ILauncherStatics *, IUriRuntimeClass *, IAsyncOperation **); + HRESULT (STDMETHODCALLTYPE *LaunchUriWithOptionsAsync) (ILauncherStatics *, IUriRuntimeClass *, IUnknown *, IAsyncOperation **); +} ILauncherStaticsVtbl; + +typedef struct _ILauncherStatics { + ILauncherStaticsVtbl *lpVtbl; +} ILauncherStatics; + +extern ILauncherStatics CLauncherStatics; + +// +// roinit.c +// + +KXCOMAPI HRESULT WINAPI RoInitialize( + IN RO_INIT_TYPE InitType); + +KXCOMAPI VOID WINAPI RoUninitialize( + VOID); + +// +// rofactry.c +// + +HRESULT WINAPI RoGetActivationFactory( + IN HSTRING ActivatableClassId, + IN REFIID RefIID, + OUT PPVOID Factory); + +HRESULT WINAPI RoActivateInstance( + IN HSTRING ActivatableClassId, + OUT IInspectable **Instance); + +// +// roerror.c +// + +BOOL WINAPI RoOriginateError( + IN HRESULT Result, + IN HSTRING Message); + +BOOL WINAPI RoOriginateErrorW( + IN HRESULT Result, + IN ULONG Length, + IN PCWSTR Message); + +KXCOMAPI BOOL WINAPI RoOriginateLanguageException( + IN HRESULT Result, + IN HSTRING Message OPTIONAL, + IN IUnknown *LanguageException); + +HRESULT WINAPI GetRestrictedErrorInfo( + OUT IUnknown **RestrictedErrorInfo); + +// +// roapi.c +// + +KXCOMAPI HRESULT WINAPI RoGetAgileReference( + IN ULONG Options, + IN REFIID RefIID, + IN IUnknown *pUnknown, + OUT IUnknown **AgileReference); + +// +// mta.c +// + +KXCOMAPI HRESULT WINAPI CoIncrementMTAUsage( + OUT PCO_MTA_USAGE_COOKIE Cookie); + +KXCOMAPI HRESULT WINAPI CoDecrementMTAUsage( + IN CO_MTA_USAGE_COOKIE Cookie); + +// +// winrt.c +// + +KXCOMAPI ULONG WINAPI WindowsGetStringLen( + IN HSTRING String); + +KXCOMAPI PCWSTR WINAPI WindowsGetStringRawBuffer( + IN HSTRING String, + OUT PULONG Length OPTIONAL); + +KXCOMAPI HRESULT WINAPI WindowsCreateString( + IN PCNZWCH SourceString, + IN ULONG SourceStringCch, + OUT HSTRING *String); + +KXCOMAPI HRESULT WINAPI WindowsCreateStringReference( + IN PCWSTR SourceString, + IN ULONG SourceStringCch, + OUT HSTRING_HEADER *StringHeader, + OUT HSTRING *String); + +KXCOMAPI HRESULT WINAPI WindowsDuplicateString( + IN HSTRING OriginalString, + OUT HSTRING *DuplicatedString); + +KXCOMAPI HRESULT WINAPI WindowsDeleteString( + IN HSTRING String); + +KXCOMAPI BOOL WINAPI WindowsIsStringEmpty( + IN HSTRING String); + +KXCOMAPI HRESULT WINAPI WindowsStringHasEmbeddedNull( + IN HSTRING String, + OUT PBOOL HasEmbeddedNull); + +KXCOMAPI HRESULT WINAPI WindowsCompareStringOrdinal( + IN HSTRING String1, + IN HSTRING String2, + OUT PINT ComparisonResult); + +KXCOMAPI HRESULT WINAPI WindowsSubstring( + IN HSTRING String, + IN ULONG StartIndex, + OUT HSTRING *NewString); + +KXCOMAPI HRESULT WINAPI WindowsSubstringWithSpecifiedLength( + IN HSTRING OriginalString, + IN ULONG StartIndex, + IN ULONG SubstringLength, + OUT HSTRING *NewString); + +KXCOMAPI HRESULT WINAPI WindowsConcatString( + IN HSTRING String1, + IN HSTRING String2, + OUT HSTRING *NewString); + +KXCOMAPI HRESULT WINAPI WindowsPreallocateStringBuffer( + IN ULONG Length, + OUT PPWSTR CharacterBuffer, + OUT PHSTRING_BUFFER BufferHandle); + +KXCOMAPI HRESULT WINAPI WindowsDeleteStringBuffer( + IN HSTRING_BUFFER BufferHandle); + +KXCOMAPI HRESULT WINAPI WindowsPromoteStringBuffer( + IN HSTRING_BUFFER BufferHandle, + OUT HSTRING *NewString); \ No newline at end of file diff --git a/00-Common Headers/KxDx.h b/00-Common Headers/KxDx.h new file mode 100644 index 0000000..4932ec0 --- /dev/null +++ b/00-Common Headers/KxDx.h @@ -0,0 +1,522 @@ +#pragma once +#include +#include +#include +#include + +// +// Structure & enum +// + +typedef enum _DXGI_SCALING { + DXGI_SCALING_STRETCH = 0, + DXGI_SCALING_NONE = 1, + DXGI_SCALING_ASPECT_RATIO_STRETCH = 2 +} TYPEDEF_TYPE_NAME(DXGI_SCALING); + +typedef enum _DXGI_ALPHA_MODE { + DXGI_ALPHA_MODE_UNSPECIFIED = 0, + DXGI_ALPHA_MODE_PREMULTIPLIED = 1, + DXGI_ALPHA_MODE_STRAIGHT = 2, + DXGI_ALPHA_MODE_IGNORE = 3, + DXGI_ALPHA_MODE_FORCE_DWORD = 0xffffffff +} TYPEDEF_TYPE_NAME(DXGI_ALPHA_MODE); + +typedef struct _DXGI_SWAP_CHAIN_DESC1 { + UINT Width; + UINT Height; + DXGI_FORMAT Format; + BOOL Stereo; + DXGI_SAMPLE_DESC SampleDesc; + DXGI_USAGE BufferUsage; + UINT BufferCount; + DXGI_SCALING Scaling; + DXGI_SWAP_EFFECT SwapEffect; + DXGI_ALPHA_MODE AlphaMode; + UINT Flags; +} TYPEDEF_TYPE_NAME(DXGI_SWAP_CHAIN_DESC1); + +typedef struct _DXGI_SWAP_CHAIN_FULLSCREEN_DESC { + DXGI_RATIONAL RefreshRate; + DXGI_MODE_SCANLINE_ORDER ScanlineOrdering; + DXGI_MODE_SCALING Scaling; + BOOL Windowed; +} TYPEDEF_TYPE_NAME(DXGI_SWAP_CHAIN_FULLSCREEN_DESC); + +typedef struct _DXGI_PRESENT_PARAMETERS { + UINT DirtyRectsCount; + RECT *pDirtyRects; + RECT *pScrollRect; + POINT *pScrollOffset; +} TYPEDEF_TYPE_NAME(DXGI_PRESENT_PARAMETERS); + +typedef D3DCOLORVALUE DXGI_RGBA; + +// +// IDXGISwapChain1 +// + +typedef interface IDXGISwapChain1 IDXGISwapChain1; + +typedef struct IDXGISwapChain1Vtbl +{ + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDXGISwapChain1 * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _Out_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDXGISwapChain1 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDXGISwapChain1 * This); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + IDXGISwapChain1 * This, + /* [annotation][in] */ + _In_ REFGUID Name, + /* [in] */ UINT DataSize, + /* [annotation][in] */ + _In_ const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + IDXGISwapChain1 * This, + /* [annotation][in] */ + _In_ REFGUID Name, + /* [annotation][in] */ + _In_opt_ const IUnknown *pUnknown); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + IDXGISwapChain1 * This, + /* [annotation][in] */ + _In_ REFGUID Name, + /* [annotation][out][in] */ + _Inout_ UINT *pDataSize, + /* [annotation][out] */ + _Out_ void *pData); + + HRESULT ( STDMETHODCALLTYPE *GetParent )( + IDXGISwapChain1 * This, + /* [annotation][in] */ + _In_ REFIID riid, + /* [annotation][retval][out] */ + _Out_ void **ppParent); + + HRESULT ( STDMETHODCALLTYPE *GetDevice )( + IDXGISwapChain1 * This, + /* [annotation][in] */ + _In_ REFIID riid, + /* [annotation][retval][out] */ + _Out_ void **ppDevice); + + HRESULT ( STDMETHODCALLTYPE *Present )( + IDXGISwapChain1 * This, + /* [in] */ UINT SyncInterval, + /* [in] */ UINT Flags); + + HRESULT ( STDMETHODCALLTYPE *GetBuffer )( + IDXGISwapChain1 * This, + /* [in] */ UINT Buffer, + /* [annotation][in] */ + _In_ REFIID riid, + /* [annotation][out][in] */ + _Out_ void **ppSurface); + + HRESULT ( STDMETHODCALLTYPE *SetFullscreenState )( + IDXGISwapChain1 * This, + /* [in] */ BOOL Fullscreen, + /* [annotation][in] */ + _In_opt_ IDXGIOutput *pTarget); + + HRESULT ( STDMETHODCALLTYPE *GetFullscreenState )( + IDXGISwapChain1 * This, + /* [annotation][out] */ + _Out_opt_ BOOL *pFullscreen, + /* [annotation][out] */ + _Out_opt_ IDXGIOutput **ppTarget); + + HRESULT ( STDMETHODCALLTYPE *GetDesc )( + IDXGISwapChain1 * This, + /* [annotation][out] */ + _Out_ DXGI_SWAP_CHAIN_DESC *pDesc); + + HRESULT ( STDMETHODCALLTYPE *ResizeBuffers )( + IDXGISwapChain1 * This, + /* [in] */ UINT BufferCount, + /* [in] */ UINT Width, + /* [in] */ UINT Height, + /* [in] */ DXGI_FORMAT NewFormat, + /* [in] */ UINT SwapChainFlags); + + HRESULT ( STDMETHODCALLTYPE *ResizeTarget )( + IDXGISwapChain1 * This, + /* [annotation][in] */ + _In_ const DXGI_MODE_DESC *pNewTargetParameters); + + HRESULT ( STDMETHODCALLTYPE *GetContainingOutput )( + IDXGISwapChain1 * This, + /* [annotation][out] */ + _Out_ IDXGIOutput **ppOutput); + + HRESULT ( STDMETHODCALLTYPE *GetFrameStatistics )( + IDXGISwapChain1 * This, + /* [annotation][out] */ + _Out_ DXGI_FRAME_STATISTICS *pStats); + + HRESULT ( STDMETHODCALLTYPE *GetLastPresentCount )( + IDXGISwapChain1 * This, + /* [annotation][out] */ + _Out_ UINT *pLastPresentCount); + + HRESULT ( STDMETHODCALLTYPE *GetDesc1 )( + IDXGISwapChain1 * This, + /* [annotation][out] */ + _Out_ DXGI_SWAP_CHAIN_DESC1 *pDesc); + + HRESULT ( STDMETHODCALLTYPE *GetFullscreenDesc )( + IDXGISwapChain1 * This, + /* [annotation][out] */ + _Out_ DXGI_SWAP_CHAIN_FULLSCREEN_DESC *pDesc); + + HRESULT ( STDMETHODCALLTYPE *GetHwnd )( + IDXGISwapChain1 * This, + /* [annotation][out] */ + _Out_ HWND *pHwnd); + + HRESULT ( STDMETHODCALLTYPE *GetCoreWindow )( + IDXGISwapChain1 * This, + /* [annotation][in] */ + _In_ REFIID refiid, + /* [annotation][out] */ + _Out_ void **ppUnk); + + HRESULT ( STDMETHODCALLTYPE *Present1 )( + IDXGISwapChain1 * This, + /* [in] */ UINT SyncInterval, + /* [in] */ UINT PresentFlags, + /* [annotation][in] */ + _In_ const DXGI_PRESENT_PARAMETERS *pPresentParameters); + + BOOL ( STDMETHODCALLTYPE *IsTemporaryMonoSupported )( + IDXGISwapChain1 * This); + + HRESULT ( STDMETHODCALLTYPE *GetRestrictToOutput )( + IDXGISwapChain1 * This, + /* [annotation][out] */ + _Out_ IDXGIOutput **ppRestrictToOutput); + + HRESULT ( STDMETHODCALLTYPE *SetBackgroundColor )( + IDXGISwapChain1 * This, + /* [annotation][in] */ + _In_ const DXGI_RGBA *pColor); + + HRESULT ( STDMETHODCALLTYPE *GetBackgroundColor )( + IDXGISwapChain1 * This, + /* [annotation][out] */ + _Out_ DXGI_RGBA *pColor); + + HRESULT ( STDMETHODCALLTYPE *SetRotation )( + IDXGISwapChain1 * This, + /* [annotation][in] */ + _In_ DXGI_MODE_ROTATION Rotation); + + HRESULT ( STDMETHODCALLTYPE *GetRotation )( + IDXGISwapChain1 * This, + /* [annotation][out] */ + _Out_ DXGI_MODE_ROTATION *pRotation); + + END_INTERFACE +} IDXGISwapChain1Vtbl; + +interface IDXGISwapChain1 +{ + CONST_VTBL struct IDXGISwapChain1Vtbl *lpVtbl; +}; + +// +// IDXGIFactory2 +// + +typedef interface IDXGIFactory2 IDXGIFactory2; + +typedef struct IDXGIFactory2Vtbl +{ + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + IDXGIFactory2 * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _Out_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + IDXGIFactory2 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + IDXGIFactory2 * This); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateData )( + IDXGIFactory2 * This, + /* [annotation][in] */ + _In_ REFGUID Name, + /* [in] */ UINT DataSize, + /* [annotation][in] */ + _In_ const void *pData); + + HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )( + IDXGIFactory2 * This, + /* [annotation][in] */ + _In_ REFGUID Name, + /* [annotation][in] */ + _In_opt_ const IUnknown *pUnknown); + + HRESULT ( STDMETHODCALLTYPE *GetPrivateData )( + IDXGIFactory2 * This, + /* [annotation][in] */ + _In_ REFGUID Name, + /* [annotation][out][in] */ + _Inout_ UINT *pDataSize, + /* [annotation][out] */ + _Out_ void *pData); + + HRESULT ( STDMETHODCALLTYPE *GetParent )( + IDXGIFactory2 * This, + /* [annotation][in] */ + _In_ REFIID riid, + /* [annotation][retval][out] */ + _Out_ void **ppParent); + + HRESULT ( STDMETHODCALLTYPE *EnumAdapters )( + IDXGIFactory2 * This, + /* [in] */ UINT Adapter, + /* [annotation][out] */ + _Out_ IDXGIAdapter **ppAdapter); + + HRESULT ( STDMETHODCALLTYPE *MakeWindowAssociation )( + IDXGIFactory2 * This, + HWND WindowHandle, + UINT Flags); + + HRESULT ( STDMETHODCALLTYPE *GetWindowAssociation )( + IDXGIFactory2 * This, + /* [annotation][out] */ + _Out_ HWND *pWindowHandle); + + HRESULT ( STDMETHODCALLTYPE *CreateSwapChain )( + IDXGIFactory2 * This, + /* [annotation][in] */ + _In_ IUnknown *pDevice, + /* [annotation][in] */ + _In_ DXGI_SWAP_CHAIN_DESC *pDesc, + /* [annotation][out] */ + _Out_ IDXGISwapChain **ppSwapChain); + + HRESULT ( STDMETHODCALLTYPE *CreateSoftwareAdapter )( + IDXGIFactory2 * This, + /* [in] */ HMODULE Module, + /* [annotation][out] */ + _Out_ IDXGIAdapter **ppAdapter); + + HRESULT ( STDMETHODCALLTYPE *EnumAdapters1 )( + IDXGIFactory2 * This, + /* [in] */ UINT Adapter, + /* [annotation][out] */ + _Out_ IDXGIAdapter1 **ppAdapter); + + BOOL ( STDMETHODCALLTYPE *IsCurrent )( + IDXGIFactory2 * This); + + BOOL ( STDMETHODCALLTYPE *IsWindowedStereoEnabled )( + IDXGIFactory2 * This); + + HRESULT ( STDMETHODCALLTYPE *CreateSwapChainForHwnd )( + IDXGIFactory2 * This, + /* [annotation][in] */ + _In_ IUnknown *pDevice, + /* [annotation][in] */ + _In_ HWND hWnd, + /* [annotation][in] */ + _In_ const DXGI_SWAP_CHAIN_DESC1 *pDesc, + /* [annotation][in] */ + _In_opt_ const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *pFullscreenDesc, + /* [annotation][in] */ + _In_opt_ IDXGIOutput *pRestrictToOutput, + /* [annotation][out] */ + _Out_ IDXGISwapChain1 **ppSwapChain); + + HRESULT ( STDMETHODCALLTYPE *CreateSwapChainForCoreWindow )( + IDXGIFactory2 * This, + /* [annotation][in] */ + _In_ IUnknown *pDevice, + /* [annotation][in] */ + _In_ IUnknown *pWindow, + /* [annotation][in] */ + _In_ const DXGI_SWAP_CHAIN_DESC1 *pDesc, + /* [annotation][in] */ + _In_opt_ IDXGIOutput *pRestrictToOutput, + /* [annotation][out] */ + _Out_ IDXGISwapChain1 **ppSwapChain); + + HRESULT ( STDMETHODCALLTYPE *GetSharedResourceAdapterLuid )( + IDXGIFactory2 * This, + /* [annotation] */ + _In_ HANDLE hResource, + /* [annotation] */ + _Out_ LUID *pLuid); + + HRESULT ( STDMETHODCALLTYPE *RegisterStereoStatusWindow )( + IDXGIFactory2 * This, + /* [annotation][in] */ + _In_ HWND WindowHandle, + /* [annotation][in] */ + _In_ UINT wMsg, + /* [annotation][out] */ + _Out_ DWORD *pdwCookie); + + HRESULT ( STDMETHODCALLTYPE *RegisterStereoStatusEvent )( + IDXGIFactory2 * This, + /* [annotation][in] */ + _In_ HANDLE hEvent, + /* [annotation][out] */ + _Out_ DWORD *pdwCookie); + + void ( STDMETHODCALLTYPE *UnregisterStereoStatus )( + IDXGIFactory2 * This, + /* [annotation][in] */ + _In_ DWORD dwCookie); + + HRESULT ( STDMETHODCALLTYPE *RegisterOcclusionStatusWindow )( + IDXGIFactory2 * This, + /* [annotation][in] */ + _In_ HWND WindowHandle, + /* [annotation][in] */ + _In_ UINT wMsg, + /* [annotation][out] */ + _Out_ DWORD *pdwCookie); + + HRESULT ( STDMETHODCALLTYPE *RegisterOcclusionStatusEvent )( + IDXGIFactory2 * This, + /* [annotation][in] */ + _In_ HANDLE hEvent, + /* [annotation][out] */ + _Out_ DWORD *pdwCookie); + + void ( STDMETHODCALLTYPE *UnregisterOcclusionStatus )( + IDXGIFactory2 * This, + /* [annotation][in] */ + _In_ DWORD dwCookie); + + HRESULT ( STDMETHODCALLTYPE *CreateSwapChainForComposition )( + IDXGIFactory2 * This, + /* [annotation][in] */ + _In_ IUnknown *pDevice, + /* [annotation][in] */ + _In_ const DXGI_SWAP_CHAIN_DESC1 *pDesc, + /* [annotation][in] */ + _In_opt_ IDXGIOutput *pRestrictToOutput, + /* [annotation][out] */ + _Out_ IDXGISwapChain1 **ppSwapChain); + + END_INTERFACE +} IDXGIFactory2Vtbl; + +interface IDXGIFactory2 +{ + CONST_VTBL struct IDXGIFactory2Vtbl *lpVtbl; +}; + +#define IDXGIFactory2_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define IDXGIFactory2_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define IDXGIFactory2_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define IDXGIFactory2_SetPrivateData(This,Name,DataSize,pData) \ + ( (This)->lpVtbl -> SetPrivateData(This,Name,DataSize,pData) ) + +#define IDXGIFactory2_SetPrivateDataInterface(This,Name,pUnknown) \ + ( (This)->lpVtbl -> SetPrivateDataInterface(This,Name,pUnknown) ) + +#define IDXGIFactory2_GetPrivateData(This,Name,pDataSize,pData) \ + ( (This)->lpVtbl -> GetPrivateData(This,Name,pDataSize,pData) ) + +#define IDXGIFactory2_GetParent(This,riid,ppParent) \ + ( (This)->lpVtbl -> GetParent(This,riid,ppParent) ) + + +#define IDXGIFactory2_EnumAdapters(This,Adapter,ppAdapter) \ + ( (This)->lpVtbl -> EnumAdapters(This,Adapter,ppAdapter) ) + +#define IDXGIFactory2_MakeWindowAssociation(This,WindowHandle,Flags) \ + ( (This)->lpVtbl -> MakeWindowAssociation(This,WindowHandle,Flags) ) + +#define IDXGIFactory2_GetWindowAssociation(This,pWindowHandle) \ + ( (This)->lpVtbl -> GetWindowAssociation(This,pWindowHandle) ) + +#define IDXGIFactory2_CreateSwapChain(This,pDevice,pDesc,ppSwapChain) \ + ( (This)->lpVtbl -> CreateSwapChain(This,pDevice,pDesc,ppSwapChain) ) + +#define IDXGIFactory2_CreateSoftwareAdapter(This,Module,ppAdapter) \ + ( (This)->lpVtbl -> CreateSoftwareAdapter(This,Module,ppAdapter) ) + + +#define IDXGIFactory2_EnumAdapters1(This,Adapter,ppAdapter) \ + ( (This)->lpVtbl -> EnumAdapters1(This,Adapter,ppAdapter) ) + +#define IDXGIFactory2_IsCurrent(This) \ + ( (This)->lpVtbl -> IsCurrent(This) ) + + +#define IDXGIFactory2_IsWindowedStereoEnabled(This) \ + ( (This)->lpVtbl -> IsWindowedStereoEnabled(This) ) + +#define IDXGIFactory2_CreateSwapChainForHwnd(This,pDevice,hWnd,pDesc,pFullscreenDesc,pRestrictToOutput,ppSwapChain) \ + ( (This)->lpVtbl -> CreateSwapChainForHwnd(This,pDevice,hWnd,pDesc,pFullscreenDesc,pRestrictToOutput,ppSwapChain) ) + +#define IDXGIFactory2_CreateSwapChainForCoreWindow(This,pDevice,pWindow,pDesc,pRestrictToOutput,ppSwapChain) \ + ( (This)->lpVtbl -> CreateSwapChainForCoreWindow(This,pDevice,pWindow,pDesc,pRestrictToOutput,ppSwapChain) ) + +#define IDXGIFactory2_GetSharedResourceAdapterLuid(This,hResource,pLuid) \ + ( (This)->lpVtbl -> GetSharedResourceAdapterLuid(This,hResource,pLuid) ) + +#define IDXGIFactory2_RegisterStereoStatusWindow(This,WindowHandle,wMsg,pdwCookie) \ + ( (This)->lpVtbl -> RegisterStereoStatusWindow(This,WindowHandle,wMsg,pdwCookie) ) + +#define IDXGIFactory2_RegisterStereoStatusEvent(This,hEvent,pdwCookie) \ + ( (This)->lpVtbl -> RegisterStereoStatusEvent(This,hEvent,pdwCookie) ) + +#define IDXGIFactory2_UnregisterStereoStatus(This,dwCookie) \ + ( (This)->lpVtbl -> UnregisterStereoStatus(This,dwCookie) ) + +#define IDXGIFactory2_RegisterOcclusionStatusWindow(This,WindowHandle,wMsg,pdwCookie) \ + ( (This)->lpVtbl -> RegisterOcclusionStatusWindow(This,WindowHandle,wMsg,pdwCookie) ) + +#define IDXGIFactory2_RegisterOcclusionStatusEvent(This,hEvent,pdwCookie) \ + ( (This)->lpVtbl -> RegisterOcclusionStatusEvent(This,hEvent,pdwCookie) ) + +#define IDXGIFactory2_UnregisterOcclusionStatus(This,dwCookie) \ + ( (This)->lpVtbl -> UnregisterOcclusionStatus(This,dwCookie) ) + +#define IDXGIFactory2_CreateSwapChainForComposition(This,pDevice,pDesc,pRestrictToOutput,ppSwapChain) \ + ( (This)->lpVtbl -> CreateSwapChainForComposition(This,pDevice,pDesc,pRestrictToOutput,ppSwapChain) ) + +// +// GUIDs +// + +DEFINE_GUID(IID_IDXGIDisplayControl,0xea9dbf1a,0xc88e,0x4486,0x85,0x4a,0x98,0xaa,0x01,0x38,0xf3,0x0c); +DEFINE_GUID(IID_IDXGIOutputDuplication,0x191cfac3,0xa341,0x470d,0xb2,0x6e,0xa8,0x64,0xf4,0x28,0x31,0x9c); +DEFINE_GUID(IID_IDXGISurface2,0xaba496dd,0xb617,0x4cb8,0xa8,0x66,0xbc,0x44,0xd7,0xeb,0x1f,0xa2); +DEFINE_GUID(IID_IDXGIResource1,0x30961379,0x4609,0x4a41,0x99,0x8e,0x54,0xfe,0x56,0x7e,0xe0,0xc1); +DEFINE_GUID(IID_IDXGIDevice2,0x05008617,0xfbfd,0x4051,0xa7,0x90,0x14,0x48,0x84,0xb4,0xf6,0xa9); +DEFINE_GUID(IID_IDXGISwapChain1,0x790a45f7,0x0d42,0x4876,0x98,0x3a,0x0a,0x55,0xcf,0xe6,0xf4,0xaa); +DEFINE_GUID(IID_IDXGIFactory2,0x50c83a1c,0xe072,0x4c48,0x87,0xb0,0x36,0x30,0xfa,0x36,0xa6,0xd0); +DEFINE_GUID(IID_IDXGIAdapter2,0x0AA1AE0A,0xFA0E,0x4B84,0x86,0x44,0xE0,0x5F,0xF8,0xE5,0xAC,0xB5); +DEFINE_GUID(IID_IDXGIOutput1,0x00cddea8,0x939b,0x4b83,0xa3,0x40,0xa6,0x85,0x22,0x66,0x66,0xcc); \ No newline at end of file diff --git a/00-Common Headers/KxMi.h b/00-Common Headers/KxMi.h new file mode 100644 index 0000000..8922794 --- /dev/null +++ b/00-Common Headers/KxMi.h @@ -0,0 +1,34 @@ +#pragma once + +#include +#include + +#if !defined(KXMIAPI) && defined(KEX_ENV_WIN32) +# define KXMIAPI +# pragma comment(lib, "KxMi.lib") +#endif + +typedef ULONG (CALLBACK *PDEVICE_NOTIFY_CALLBACK_ROUTINE) ( + IN PVOID Context OPTIONAL, + IN ULONG Type, + IN PVOID Setting); + +typedef struct _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS { + PDEVICE_NOTIFY_CALLBACK_ROUTINE Callback; + PVOID Context; +} TYPEDEF_TYPE_NAME(DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS); + +// +// powrprof.c +// + +KXMIAPI POWER_PLATFORM_ROLE WINAPI PowerDeterminePlatformRoleEx( + IN ULONG Version); + +KXMIAPI ULONG WINAPI PowerRegisterSuspendResumeNotification( + IN ULONG Flags, + IN HANDLE Recipient, + OUT PHPOWERNOTIFY RegistrationHandle); + +KXMIAPI ULONG WINAPI PowerUnregisterSuspendResumeNotification( + IN OUT HPOWERNOTIFY RegistrationHandle); \ No newline at end of file diff --git a/00-Common Headers/KxUser.h b/00-Common Headers/KxUser.h new file mode 100644 index 0000000..3dfed5d --- /dev/null +++ b/00-Common Headers/KxUser.h @@ -0,0 +1,358 @@ +#pragma once +#include +#include + +typedef enum _DEVICE_SCALE_FACTOR { + DEVICE_SCALE_FACTOR_INVALID = 0, + SCALE_100_PERCENT = 100, + SCALE_120_PERCENT = 120, + SCALE_125_PERCENT = 125, + SCALE_140_PERCENT = 140, + SCALE_150_PERCENT = 150, + SCALE_160_PERCENT = 160, + SCALE_175_PERCENT = 175, + SCALE_180_PERCENT = 180, + SCALE_200_PERCENT = 200, + SCALE_225_PERCENT = 225, + SCALE_250_PERCENT = 250, + SCALE_300_PERCENT = 300, + SCALE_350_PERCENT = 350, + SCALE_400_PERCENT = 400, + SCALE_450_PERCENT = 450, + SCALE_500_PERCENT = 500 +} TYPEDEF_TYPE_NAME(DEVICE_SCALE_FACTOR); + +typedef enum MONITOR_DPI_TYPE { + MDT_EFFECTIVE_DPI = 0, + MDT_ANGULAR_DPI = 1, + MDT_RAW_DPI = 2, + MDT_MAXIMUM_DPI = 3, + MDT_DEFAULT = MDT_EFFECTIVE_DPI +} TYPEDEF_TYPE_NAME(MONITOR_DPI_TYPE); + +typedef enum _DPI_AWARENESS { + DPI_AWARENESS_INVALID = -1, + DPI_AWARENESS_UNAWARE = 0, + DPI_AWARENESS_SYSTEM_AWARE = 1, + DPI_AWARENESS_PER_MONITOR_AWARE = 2, + DPI_AWARENESS_MAX_VALUE = 3 +} TYPEDEF_TYPE_NAME(DPI_AWARENESS); + +typedef enum _PROCESS_DPI_AWARENESS { + PROCESS_DPI_UNAWARE = 0, + PROCESS_SYSTEM_DPI_AWARE = 1, + PROCESS_PER_MONITOR_DPI_AWARE = 2, + PROCESS_MAX_DPI_AWARENESS = 3 // always last value +} TYPEDEF_TYPE_NAME(PROCESS_DPI_AWARENESS); + +typedef ULONG_PTR DPI_AWARENESS_CONTEXT; + +#define DPI_AWARENESS_CONTEXT_UNAWARE ((DPI_AWARENESS_CONTEXT) -1) +#define DPI_AWARENESS_CONTEXT_SYSTEM_AWARE ((DPI_AWARENESS_CONTEXT) -2) +#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE ((DPI_AWARENESS_CONTEXT) -3) +#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((DPI_AWARENESS_CONTEXT) -4) +#define DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED ((DPI_AWARENESS_CONTEXT) -5) + +typedef enum _POINTER_INPUT_TYPE { + PT_POINTER, + PT_TOUCH, + PT_PEN, + PT_MOUSE, + PT_TOUCHPAD +} POINTER_INPUT_TYPE; + +typedef enum _POINTER_BUTTON_CHANGE_TYPE { + POINTER_CHANGE_NONE, + POINTER_CHANGE_FIRSTBUTTON_DOWN, + POINTER_CHANGE_FIRSTBUTTON_UP, + POINTER_CHANGE_SECONDBUTTON_DOWN, + POINTER_CHANGE_SECONDBUTTON_UP, + POINTER_CHANGE_THIRDBUTTON_DOWN, + POINTER_CHANGE_THIRDBUTTON_UP, + POINTER_CHANGE_FOURTHBUTTON_DOWN, + POINTER_CHANGE_FOURTHBUTTON_UP, + POINTER_CHANGE_FIFTHBUTTON_DOWN, + POINTER_CHANGE_FIFTHBUTTON_UP +} POINTER_BUTTON_CHANGE_TYPE; + +typedef UINT32 POINTER_FLAGS; +#define POINTER_FLAG_NONE 0x00000000 // Default +#define POINTER_FLAG_NEW 0x00000001 // New pointer +#define POINTER_FLAG_INRANGE 0x00000002 // Pointer has not departed +#define POINTER_FLAG_INCONTACT 0x00000004 // Pointer is in contact +#define POINTER_FLAG_FIRSTBUTTON 0x00000010 // Primary action +#define POINTER_FLAG_SECONDBUTTON 0x00000020 // Secondary action +#define POINTER_FLAG_THIRDBUTTON 0x00000040 // Third button +#define POINTER_FLAG_FOURTHBUTTON 0x00000080 // Fourth button +#define POINTER_FLAG_FIFTHBUTTON 0x00000100 // Fifth button +#define POINTER_FLAG_PRIMARY 0x00002000 // Pointer is primary for system +#define POINTER_FLAG_CONFIDENCE 0x00004000 // Pointer is considered unlikely to be accidental +#define POINTER_FLAG_CANCELED 0x00008000 // Pointer is departing in an abnormal manner +#define POINTER_FLAG_DOWN 0x00010000 // Pointer transitioned to down state (made contact) +#define POINTER_FLAG_UPDATE 0x00020000 // Pointer update +#define POINTER_FLAG_UP 0x00040000 // Pointer transitioned from down state (broke contact) +#define POINTER_FLAG_WHEEL 0x00080000 // Vertical wheel +#define POINTER_FLAG_HWHEEL 0x00100000 // Horizontal wheel +#define POINTER_FLAG_CAPTURECHANGED 0x00200000 // Lost capture +#define POINTER_FLAG_HASTRANSFORM 0x00400000 // Input has a transform associated with it + +typedef struct _POINTER_INFO { + POINTER_INPUT_TYPE pointerType; + UINT32 pointerId; + UINT32 frameId; + POINTER_FLAGS pointerFlags; + HANDLE sourceDevice; + HWND hwndTarget; + POINT ptPixelLocation; + POINT ptHimetricLocation; + POINT ptPixelLocationRaw; + POINT ptHimetricLocationRaw; + DWORD dwTime; + UINT32 historyCount; + INT32 InputData; + DWORD dwKeyStates; + UINT64 PerformanceCount; + POINTER_BUTTON_CHANGE_TYPE ButtonChangeType; +} POINTER_INFO; + +#define POINTER_DEVICE_PRODUCT_STRING_MAX 520 + +typedef enum _POINTER_DEVICE_TYPE { + POINTER_DEVICE_TYPE_INTEGRATED_PEN = 0x00000001, + POINTER_DEVICE_TYPE_EXTERNAL_PEN = 0x00000002, + POINTER_DEVICE_TYPE_TOUCH = 0x00000003, + POINTER_DEVICE_TYPE_TOUCH_PAD = 0x00000004, + POINTER_DEVICE_TYPE_MAX = 0xFFFFFFFF +} POINTER_DEVICE_TYPE; + +typedef struct _POINTER_DEVICE_INFO { + DWORD displayOrientation; + HANDLE device; + POINTER_DEVICE_TYPE pointerDeviceType; + HMONITOR monitor; + ULONG startingCursorId; + USHORT maxActiveContacts; + WCHAR productString[POINTER_DEVICE_PRODUCT_STRING_MAX]; +} POINTER_DEVICE_INFO; + +typedef enum _SHELL_UI_COMPONENT { + SHELL_UI_COMPONENT_TASKBARS, + SHELL_UI_COMPONENT_NOTIFICATIONAREA, + SHELL_UI_COMPONENT_DESKBAND +} TYPEDEF_TYPE_NAME(SHELL_UI_COMPONENT); + +typedef enum _ORIENTATION_PREFERENCE { + ORIENTATION_PREFERENCE_NONE, + ORIENTATION_PREFERENCE_LANDSCAPE, + ORIENTATION_PREFERENCE_PORTRAIT, + ORIENTATION_PREFERENCE_LANDSCAPE_FLIPPED, + ORIENTATION_PREFERENCE_PORTRAIT_FLIPPED +} TYPEDEF_TYPE_NAME(ORIENTATION_PREFERENCE); + +typedef enum _PROCESS_UICONTEXT { + PROCESS_UICONTEXT_DESKTOP, + PROCESS_UICONTEXT_IMMERSIVE, + PROCESS_UICONTEXT_IMMERSIVE_BROKER, + PROCESS_UICONTEXT_IMMERSIVE_BROWSER +} TYPEDEF_TYPE_NAME(PROCESS_UICONTEXT); + +#define PROCESS_UIF_NONE 0 +#define PROCESS_UIF_AUTHORING_MODE 1 +#define PROCESS_UIF_RESTRICTIONS_DISABLED 2 + +typedef struct _PROCESS_UICONTEXT_INFORMATION { + PROCESS_UICONTEXT UIContext; + ULONG Flags; // PROCESS_UIF_* +} TYPEDEF_TYPE_NAME(PROCESS_UICONTEXT_INFORMATION); + +typedef enum _ZBID { + ZBID_DEFAULT, + ZBID_DESKTOP, + ZBID_UIACCESS, + ZBID_IMMERSIVE_IHM, + ZBID_IMMERSIVE_NOTIFICATION, + ZBID_IMMERSIVE_APPCHROME, + ZBID_IMMERSIVE_MOGO, + ZBID_IMMERSIVE_EDGY, + ZBID_IMMERSIVE_INACTIVEMOBODY, + ZBID_IMMERSIVE_INACTIVEDOCK, + ZBID_IMMERSIVE_ACTIVEMOBODY, + ZBID_IMMERSIVE_ACTIVEDOCK, + ZBID_IMMERSIVE_BACKGROUND, + ZBID_IMMERSIVE_SEARCH, + ZBID_GENUINE_WINDOWS +} TYPEDEF_TYPE_NAME(ZBID); + +typedef enum tagINPUT_MESSAGE_DEVICE_TYPE { + IMDT_UNAVAILABLE = 0x00000000, + IMDT_KEYBOARD = 0x00000001, + IMDT_MOUSE = 0x00000002, + IMDT_TOUCH = 0x00000004, + IMDT_PEN = 0x00000008, + IMDT_TOUCHPAD = 0x00000010 +} INPUT_MESSAGE_DEVICE_TYPE; + +typedef enum tagINPUT_MESSAGE_ORIGIN_ID { + IMO_UNAVAILABLE = 0x00000000, + IMO_HARDWARE = 0x00000001, + IMO_INJECTED = 0x00000002, + IMO_SYSTEM = 0x00000004 +} INPUT_MESSAGE_ORIGIN_ID; + +typedef struct _INPUT_MESSAGE_SOURCE { + INPUT_MESSAGE_DEVICE_TYPE DeviceType; + INPUT_MESSAGE_ORIGIN_ID OriginId; +} TYPEDEF_TYPE_NAME(INPUT_MESSAGE_SOURCE); + +// +// pointer.c +// + +BOOL WINAPI GetPointerDevices( + IN OUT UINT32 *DeviceCount, + OUT POINTER_DEVICE_INFO *PointerDevices); + +BOOL WINAPI GetPointerType( + IN DWORD PointerId, + OUT POINTER_INPUT_TYPE *PointerType); + +BOOL WINAPI GetPointerInfo( + IN DWORD PointerId, + OUT POINTER_INFO *PointerInfo); + +BOOL WINAPI GetPointerTouchInfo( + IN DWORD PointerId, + OUT LPVOID TouchInfo); + +BOOL WINAPI GetPointerFrameTouchInfo( + IN DWORD PointerId, + IN OUT LPDWORD PointerCount, + OUT LPVOID TouchInfo); + +BOOL WINAPI GetPointerFrameTouchInfoHistory( + IN DWORD PointerId, + IN OUT DWORD EntriesCount, + IN OUT LPDWORD PointerCount, + OUT LPVOID TouchInfo); + +BOOL WINAPI GetPointerPenInfo( + IN DWORD PointerId, + OUT LPVOID PenInfo); + +BOOL WINAPI GetPointerPenInfoHistory( + IN DWORD PointerId, + IN OUT LPDWORD EntriesCount, + OUT LPVOID PenInfo); + +BOOL WINAPI SkipPointerFrameMessages( + IN DWORD PointerId); + +BOOL WINAPI GetPointerDeviceRects( + IN HANDLE Device, + OUT LPRECT PointerDeviceRect, + OUT LPRECT DisplayRect); + +BOOL WINAPI EnableMouseInPointer( + IN BOOL Enable); + +// +// scaling.c +// + +KXUSERAPI DPI_AWARENESS GetAwarenessFromDpiAwarenessContext( + IN DPI_AWARENESS_CONTEXT Value); + +KXUSERAPI BOOL WINAPI IsValidDpiAwarenessContext( + IN DPI_AWARENESS_CONTEXT Value); + +KXUSERAPI DPI_AWARENESS_CONTEXT WINAPI GetThreadDpiAwarenessContext( + VOID); + +KXUSERAPI DPI_AWARENESS_CONTEXT WINAPI SetThreadDpiAwarenessContext( + IN DPI_AWARENESS_CONTEXT DpiContext); + +KXUSERAPI BOOL WINAPI SetProcessDpiAwarenessContext( + IN DPI_AWARENESS_CONTEXT DpiContext); + +KXUSERAPI DPI_AWARENESS_CONTEXT WINAPI GetWindowDpiAwarenessContext( + IN HWND Window); + +KXUSERAPI HRESULT WINAPI GetProcessDpiAwareness( + IN HANDLE ProcessHandle, + OUT PROCESS_DPI_AWARENESS *DpiAwareness); + +KXUSERAPI HRESULT WINAPI SetProcessDpiAwareness( + IN PROCESS_DPI_AWARENESS DpiAwareness); + +KXUSERAPI BOOL WINAPI SetProcessDpiAwarenessInternal( + IN PROCESS_DPI_AWARENESS DpiAwareness); + +KXUSERAPI HRESULT WINAPI GetDpiForMonitor( + IN HMONITOR Monitor, + IN MONITOR_DPI_TYPE DpiType, + OUT PULONG DpiX, + OUT PULONG DpiY); + +KXUSERAPI HRESULT WINAPI GetScaleFactorForMonitor( + IN HMONITOR Monitor, + OUT PDEVICE_SCALE_FACTOR ScaleFactor); + +KXUSERAPI UINT WINAPI GetDpiForSystem( + VOID); + +KXUSERAPI UINT WINAPI GetDpiForWindow( + IN HWND Window); + +KXUSERAPI BOOL WINAPI AdjustWindowRectExForDpi( + IN OUT LPRECT Rect, + IN ULONG WindowStyle, + IN BOOL HasMenu, + IN ULONG WindowExStyle, + IN ULONG Dpi); + +KXUSERAPI UINT WINAPI GetDpiForShellUIComponent( + IN SHELL_UI_COMPONENT component); + +KXUSERAPI BOOL WINAPI LogicalToPhysicalPointForPerMonitorDPI( + IN HWND Window, + IN OUT LPPOINT Point); + +KXUSERAPI BOOL WINAPI PhysicalToLogicalPointForPerMonitorDPI( + IN HWND Window, + IN OUT LPPOINT Point); + +KXUSERAPI BOOL WINAPI EnableNonClientDpiScaling( + IN HWND Window); + +// +// sysmetrc.c +// + +INT WINAPI GetSystemMetricsForDpi( + IN INT Index, + IN UINT Dpi); + +BOOL WINAPI SystemParametersInfoForDpi( + IN UINT Action, + IN UINT Parameter, + IN OUT PVOID Data, + IN UINT WinIni, + IN UINT Dpi); + +// +// pwrnotfy.c +// + +KXUSERAPI BOOL WINAPI RegisterSuspendResumeNotification( + IN HANDLE Recipient, + IN ULONG Flags); + +KXUSERAPI BOOL WINAPI UnregisterSuspendResumeNotification( + IN OUT HPOWERNOTIFY Handle); + +// +// misc.c +// + +KXUSERAPI BOOL WINAPI IsImmersiveProcess( + IN HANDLE ProcessHandle); \ No newline at end of file diff --git a/00-Common Headers/NtDll.h b/00-Common Headers/NtDll.h new file mode 100644 index 0000000..01561ca --- /dev/null +++ b/00-Common Headers/NtDll.h @@ -0,0 +1,4684 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// NtDll.h +// +// Abstract: +// +// Windows NT Native API +// +// PSA: If you try and use this header file outside of VxKex, keep in mind +// that many of the structures in here are defined for Windows 7 only. No +// attempt is made to make anything compatible with anything other than +// Windows 7. +// +// Author: +// +// vxiiduu (26-Mar-2022) +// +// Environment: +// +// Any environment. +// +// Revision History: +// +// vxiiduu 26-Mar-2022 Initial creation. +// vxiiduu 26-Sep-2022 Add header. +// +/////////////////////////////////////////////////////////////////////////////// + +#pragma once +#include +#include +#include +#undef WIN32_NO_STATUS +#include +#define WIN32_NO_STATUS + +#if defined(KEX_TARGET_TYPE_EXE) || defined(KEX_TARGET_TYPE_DLL) +# if defined(KEX_ARCH_X64) +# pragma comment(lib, "ntdll_x64.lib") +# elif defined(KEX_ARCH_X86) +# pragma comment(lib, "ntdll_x86.lib") +# endif +#endif + +#pragma region Macro Definitions + +#define NT_SUCCESS(st) (((NTSTATUS) (st)) >= 0) + +#define HARDERROR_OVERRIDE_ERRORMODE 0x10000000L + +#define PAGE_SIZE 0x1000 + +#define RTL_MAX_DRIVE_LETTERS 32 +#define PROCESSOR_FEATURE_MAX 64 +#define GDI_HANDLE_BUFFER_SIZE32 34 +#define GDI_HANDLE_BUFFER_SIZE64 60 + +#define PF_FLOATING_POINT_PRECISION_ERRATA 0 +#define PF_FLOATING_POINT_EMULATED 1 +#define PF_COMPARE_EXCHANGE_DOUBLE 2 +#define PF_MMX_INSTRUCTIONS_AVAILABLE 3 +#define PF_PPC_MOVEMEM_64BIT_OK 4 +#define PF_ALPHA_BYTE_INSTRUCTIONS 5 +#define PF_XMMI_INSTRUCTIONS_AVAILABLE 6 +#define PF_3DNOW_INSTRUCTIONS_AVAILABLE 7 +#define PF_RDTSC_INSTRUCTION_AVAILABLE 8 +#define PF_PAE_ENABLED 9 +#define PF_XMMI64_INSTRUCTIONS_AVAILABLE 10 +#define PF_SSE_DAZ_MODE_AVAILABLE 11 +#define PF_NX_ENABLED 12 +#define PF_SSE3_INSTRUCTIONS_AVAILABLE 13 +#define PF_COMPARE_EXCHANGE128 14 +#define PF_COMPARE64_EXCHANGE128 15 +#define PF_CHANNELS_ENABLED 16 +#define PF_XSAVE_ENABLED 17 + +#define OBJ_INHERIT 0x00000002L +#define OBJ_PERMANENT 0x00000010L +#define OBJ_EXCLUSIVE 0x00000020L +#define OBJ_CASE_INSENSITIVE 0x00000040L +#define OBJ_OPENIF 0x00000080L +#define OBJ_OPENLINK 0x00000100L +#define OBJ_KERNEL_HANDLE 0x00000200L +#define OBJ_FORCE_ACCESS_CHECK 0x00000400L +#define OBJ_VALID_ATTRIBUTES 0x000007F2L + +#define FILE_DIRECTORY_FILE 0x00000001 +#define FILE_WRITE_THROUGH 0x00000002 +#define FILE_SEQUENTIAL_ONLY 0x00000004 +#define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008 + +#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010 +#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020 +#define FILE_NON_DIRECTORY_FILE 0x00000040 +#define FILE_CREATE_TREE_CONNECTION 0x00000080 + +#define FILE_COMPLETE_IF_OPLOCKED 0x00000100 +#define FILE_NO_EA_KNOWLEDGE 0x00000200 +#define FILE_OPEN_FOR_RECOVERY 0x00000400 +#define FILE_RANDOM_ACCESS 0x00000800 + +#define FILE_DELETE_ON_CLOSE 0x00001000 +#define FILE_OPEN_BY_FILE_ID 0x00002000 +#define FILE_OPEN_FOR_BACKUP_INTENT 0x00004000 +#define FILE_NO_COMPRESSION 0x00008000 + +#define FILE_RESERVE_OPFILTER 0x00100000 +#define FILE_OPEN_REPARSE_POINT 0x00200000 +#define FILE_OPEN_NO_RECALL 0x00400000 +#define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000 + + +#define FILE_COPY_STRUCTURED_STORAGE 0x00000041 +#define FILE_STRUCTURED_STORAGE 0x00000441 + + +#define FILE_VALID_OPTION_FLAGS 0x00ffffff +#define FILE_VALID_PIPE_OPTION_FLAGS 0x00000032 +#define FILE_VALID_MAILSLOT_OPTION_FLAGS 0x00000032 +#define FILE_VALID_SET_FLAGS 0x00000036 + +#define FILE_SUPERSEDE 0x00000000 +#define FILE_OPEN 0x00000001 +#define FILE_CREATE 0x00000002 +#define FILE_OPEN_IF 0x00000003 +#define FILE_OVERWRITE 0x00000004 +#define FILE_OVERWRITE_IF 0x00000005 +#define FILE_MAXIMUM_DISPOSITION 0x00000005 + +#define FILE_SUPERSEDED 0x00000000 +#define FILE_OPENED 0x00000001 +#define FILE_CREATED 0x00000002 +#define FILE_OVERWRITTEN 0x00000003 +#define FILE_EXISTS 0x00000004 +#define FILE_DOES_NOT_EXIST 0x00000005 + +#define FILE_PIPE_BYTE_STREAM_TYPE 0x00000000 +#define FILE_PIPE_MESSAGE_TYPE 0x00000001 + +#define FILE_PIPE_QUEUE_OPERATION 0x00000000 +#define FILE_PIPE_COMPLETE_OPERATION 0x00000001 + +#define FILE_PIPE_BYTE_STREAM_MODE 0x00000000 +#define FILE_PIPE_MESSAGE_MODE 0x00000001 + +#define FILE_PIPE_INBOUND 0x00000000 +#define FILE_PIPE_OUTBOUND 0x00000001 +#define FILE_PIPE_FULL_DUPLEX 0x00000002 + +#define FILE_PIPE_DISCONNECTED_STATE 0x00000001 +#define FILE_PIPE_LISTENING_STATE 0x00000002 +#define FILE_PIPE_CONNECTED_STATE 0x00000003 +#define FILE_PIPE_CLOSING_STATE 0x00000004 + +#define FILE_PIPE_CLIENT_END 0x00000000 +#define FILE_PIPE_SERVER_END 0x00000001 + +#define FILE_WRITE_TO_END_OF_FILE 0xffffffff +#define FILE_USE_FILE_POINTER_POSITION 0xfffffffe + +#define FSCTL_PIPE_ASSIGN_EVENT CTL_CODE(FILE_DEVICE_NAMED_PIPE, 0, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define FSCTL_PIPE_DISCONNECT CTL_CODE(FILE_DEVICE_NAMED_PIPE, 1, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define FSCTL_PIPE_LISTEN CTL_CODE(FILE_DEVICE_NAMED_PIPE, 2, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define FSCTL_PIPE_PEEK CTL_CODE(FILE_DEVICE_NAMED_PIPE, 3, METHOD_BUFFERED, FILE_READ_DATA) +#define FSCTL_PIPE_QUERY_EVENT CTL_CODE(FILE_DEVICE_NAMED_PIPE, 4, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define FSCTL_PIPE_TRANSCEIVE CTL_CODE(FILE_DEVICE_NAMED_PIPE, 5, METHOD_NEITHER, FILE_READ_DATA | FILE_WRITE_DATA) +#define FSCTL_PIPE_WAIT CTL_CODE(FILE_DEVICE_NAMED_PIPE, 6, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define FSCTL_PIPE_IMPERSONATE CTL_CODE(FILE_DEVICE_NAMED_PIPE, 7, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define FSCTL_PIPE_SET_CLIENT_PROCESS CTL_CODE(FILE_DEVICE_NAMED_PIPE, 8, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define FSCTL_PIPE_QUERY_CLIENT_PROCESS CTL_CODE(FILE_DEVICE_NAMED_PIPE, 9, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define FSCTL_PIPE_GET_CONNECTION_ATTRIBUTE CTL_CODE(FILE_DEVICE_NAMED_PIPE, 12, METHOD_BUFFERED, FILE_ANY_ACCESS) + +// RTL_USER_PROCESS_PARAMETERS->Flags +#define RTL_USER_PROCESS_PARAMETERS_NORMALIZED 0x01 +#define RTL_USER_PROCESS_PARAMETERS_PROFILE_USER 0x02 +#define RTL_USER_PROCESS_PARAMETERS_PROFILE_KERNEL 0x04 +#define RTL_USER_PROCESS_PARAMETERS_PROFILE_SERVER 0x08 +#define RTL_USER_PROCESS_PARAMETERS_UNKNOWN 0x10 +#define RTL_USER_PROCESS_PARAMETERS_RESERVE_1MB 0x20 +#define RTL_USER_PROCESS_PARAMETERS_RESERVE_16MB 0x40 +#define RTL_USER_PROCESS_PARAMETERS_CASE_SENSITIVE 0x80 +#define RTL_USER_PROCESS_PARAMETERS_DISABLE_HEAP_CHECKS 0x100 +#define RTL_USER_PROCESS_PARAMETERS_PROCESS_OR_1 0x200 +#define RTL_USER_PROCESS_PARAMETERS_PROCESS_OR_2 0x400 +#define RTL_USER_PROCESS_PARAMETERS_PRIVATE_DLL_PATH 0x1000 +#define RTL_USER_PROCESS_PARAMETERS_LOCAL_DLL_PATH 0x2000 +#define RTL_USER_PROCESS_PARAMETERS_IMAGE_KEY_MISSING 0x4000 +#define RTL_USER_PROCESS_PARAMETERS_NX 0x20000 +#define RTL_USER_PROCESS_PARAMETERS_USER_CALLBACK_FILTER 0x80000 // see LdrpIsSystemwideUserCallbackExceptionFilterDisabled + +#define PROCESS_CREATE_FLAGS_BREAKAWAY 0x00000001 // NtCreateProcessEx & NtCreateUserProcess +#define PROCESS_CREATE_FLAGS_NO_DEBUG_INHERIT 0x00000002 // NtCreateProcessEx & NtCreateUserProcess +#define PROCESS_CREATE_FLAGS_INHERIT_HANDLES 0x00000004 // NtCreateProcessEx & NtCreateUserProcess +#define PROCESS_CREATE_FLAGS_OVERRIDE_ADDRESS_SPACE 0x00000008 // NtCreateProcessEx only +#define PROCESS_CREATE_FLAGS_LARGE_PAGES 0x00000010 // NtCreateProcessEx only, requires SeLockMemory (last in 5.2) + +#define PROCESS_CREATE_FLAGS_LARGE_PAGE_SYSTEM_DLL 0x00000020 // NtCreateProcessEx only, requires SeLockMemory (6.0+) +#define PROCESS_CREATE_FLAGS_PROTECTED_PROCESS 0x00000040 // NtCreateUserProcess only +#define PROCESS_CREATE_FLAGS_CREATE_SESSION 0x00000080 // NtCreateProcessEx & NtCreateUserProcess, requires SeLoadDriver +#define PROCESS_CREATE_FLAGS_INHERIT_FROM_PARENT 0x00000100 // NtCreateProcessEx & NtCreateUserProcess +#define PROCESS_CREATE_FLAGS_SUSPENDED 0x00000200 // NtCreateProcessEx & NtCreateUserProcess +#define PROCESS_CREATE_FLAGS_FORCE_BREAKAWAY 0x00000400 // NtCreateProcessEx & NtCreateUserProcess, requires SeTcb +#define PROCESS_CREATE_FLAGS_MINIMAL_PROCESS 0x00000800 // NtCreateProcessEx only +#define PROCESS_CREATE_FLAGS_RELEASE_SECTION 0x00001000 // NtCreateProcessEx & NtCreateUserProcess +#define PROCESS_CREATE_FLAGS_CLONE_MINIMAL 0x00002000 // NtCreateProcessEx only +#define PROCESS_CREATE_FLAGS_CLONE_MINIMAL_REDUCED_COMMIT 0x00004000 // +#define PROCESS_CREATE_FLAGS_AUXILIARY_PROCESS 0x00008000 // NtCreateProcessEx & NtCreateUserProcess, requires SeTcb +#define PROCESS_CREATE_FLAGS_CREATE_STORE 0x00020000 // NtCreateProcessEx only +#define PROCESS_CREATE_FLAGS_USE_PROTECTED_ENVIRONMENT 0x00040000 // NtCreateProcessEx & NtCreateUserProcess + +#define THREAD_CREATE_FLAGS_CREATE_SUSPENDED 0x00000001 // NtCreateUserProcess & NtCreateThreadEx +#define THREAD_CREATE_FLAGS_SKIP_THREAD_ATTACH 0x00000002 // NtCreateThreadEx only +#define THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER 0x00000004 // NtCreateThreadEx only +#define THREAD_CREATE_FLAGS_LOADER_WORKER 0x00000010 // NtCreateThreadEx only +#define THREAD_CREATE_FLAGS_SKIP_LOADER_INIT 0x00000020 // NtCreateThreadEx only +#define THREAD_CREATE_FLAGS_BYPASS_PROCESS_FREEZE 0x00000040 // NtCreateThreadEx only +#define THREAD_CREATE_FLAGS_INITIAL_THREAD 0x00000080 // ? + +#define PS_ATTRIBUTE_NUMBER_MASK 0x0000ffff +#define PS_ATTRIBUTE_THREAD 0x00010000 // may be used with thread creation +#define PS_ATTRIBUTE_INPUT 0x00020000 // input only +#define PS_ATTRIBUTE_ADDITIVE 0x00040000 // "accumulated" e.g. bitmasks, counters, etc. + +#define PsAttributeValue(Number, Thread, Input, Additive) \ + (((Number) & PS_ATTRIBUTE_NUMBER_MASK) | \ + ((Thread) ? PS_ATTRIBUTE_THREAD : 0) | \ + ((Input) ? PS_ATTRIBUTE_INPUT : 0) | \ + ((Additive) ? PS_ATTRIBUTE_ADDITIVE : 0)) + +#define PS_ATTRIBUTE_PARENT_PROCESS PsAttributeValue(PsAttributeParentProcess, FALSE, TRUE, TRUE) +#define PS_ATTRIBUTE_DEBUG_PORT PsAttributeValue(PsAttributeDebugPort, FALSE, TRUE, TRUE) +#define PS_ATTRIBUTE_TOKEN PsAttributeValue(PsAttributeToken, FALSE, TRUE, TRUE) +#define PS_ATTRIBUTE_CLIENT_ID PsAttributeValue(PsAttributeClientId, TRUE, FALSE, FALSE) +#define PS_ATTRIBUTE_TEB_ADDRESS PsAttributeValue(PsAttributeTebAddress, TRUE, FALSE, FALSE) +#define PS_ATTRIBUTE_IMAGE_NAME PsAttributeValue(PsAttributeImageName, FALSE, TRUE, FALSE) +#define PS_ATTRIBUTE_IMAGE_INFO PsAttributeValue(PsAttributeImageInfo, FALSE, FALSE, FALSE) +#define PS_ATTRIBUTE_MEMORY_RESERVE PsAttributeValue(PsAttributeMemoryReserve, FALSE, TRUE, FALSE) +#define PS_ATTRIBUTE_PRIORITY_CLASS PsAttributeValue(PsAttributePriorityClass, FALSE, TRUE, FALSE) +#define PS_ATTRIBUTE_ERROR_MODE PsAttributeValue(PsAttributeErrorMode, FALSE, TRUE, FALSE) +#define PS_ATTRIBUTE_STD_HANDLE_INFO PsAttributeValue(PsAttributeStdHandleInfo, FALSE, TRUE, FALSE) +#define PS_ATTRIBUTE_HANDLE_LIST PsAttributeValue(PsAttributeHandleList, FALSE, TRUE, FALSE) +#define PS_ATTRIBUTE_GROUP_AFFINITY PsAttributeValue(PsAttributeGroupAffinity, TRUE, TRUE, FALSE) +#define PS_ATTRIBUTE_PREFERRED_NODE PsAttributeValue(PsAttributePreferredNode, FALSE, TRUE, FALSE) +#define PS_ATTRIBUTE_IDEAL_PROCESSOR PsAttributeValue(PsAttributeIdealProcessor, TRUE, TRUE, FALSE) +#define PS_ATTRIBUTE_UMS_THREAD PsAttributeValue(PsAttributeUmsThread, TRUE, TRUE, FALSE) +#define PS_ATTRIBUTE_MITIGATION_OPTIONS PsAttributeValue(PsAttributeMitigationOptions, FALSE, TRUE, FALSE) +#define PS_ATTRIBUTE_PROTECTION_LEVEL PsAttributeValue(PsAttributeProtectionLevel, FALSE, TRUE, TRUE) +#define PS_ATTRIBUTE_SECURE_PROCESS PsAttributeValue(PsAttributeSecureProcess, FALSE, TRUE, FALSE) +#define PS_ATTRIBUTE_JOB_LIST PsAttributeValue(PsAttributeJobList, FALSE, TRUE, FALSE) +#define PS_ATTRIBUTE_CHILD_PROCESS_POLICY PsAttributeValue(PsAttributeChildProcessPolicy, FALSE, TRUE, FALSE) +#define PS_ATTRIBUTE_ALL_APPLICATION_PACKAGES_POLICY PsAttributeValue(PsAttributeAllApplicationPackagesPolicy, FALSE, TRUE, FALSE) +#define PS_ATTRIBUTE_WIN32K_FILTER PsAttributeValue(PsAttributeWin32kFilter, FALSE, TRUE, FALSE) +#define PS_ATTRIBUTE_SAFE_OPEN_PROMPT_ORIGIN_CLAIM PsAttributeValue(PsAttributeSafeOpenPromptOriginClaim, FALSE, TRUE, FALSE) +#define PS_ATTRIBUTE_BNO_ISOLATION PsAttributeValue(PsAttributeBnoIsolation, FALSE, TRUE, FALSE) +#define PS_ATTRIBUTE_DESKTOP_APP_POLICY PsAttributeValue(PsAttributeDesktopAppPolicy, FALSE, TRUE, FALSE) +#define PS_ATTRIBUTE_CHPE PsAttributeValue(PsAttributeChpe, FALSE, TRUE, TRUE) +#define PS_ATTRIBUTE_MITIGATION_AUDIT_OPTIONS PsAttributeValue(PsAttributeMitigationAuditOptions, FALSE, TRUE, FALSE) +#define PS_ATTRIBUTE_MACHINE_TYPE PsAttributeValue(PsAttributeMachineType, FALSE, TRUE, TRUE) + +#define NX_SUPPORT_POLICY_ALWAYSOFF 0 +#define NX_SUPPORT_POLICY_ALWAYSON 1 +#define NX_SUPPORT_POLICY_OPTIN 2 +#define NX_SUPPORT_POLICY_OPTOUT 3 + +#define LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS (0x00000001) +#define LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY (0x00000002) // Required to pass Disposition ptr with this flag + +#define LDR_LOCK_LOADER_LOCK_DISPOSITION_INVALID (0) +#define LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_ACQUIRED (1) +#define LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_NOT_ACQUIRED (2) + +// The maximum one in Windows XP is KACF_OLE32ENABLEASYNCDOCFILE. +// This list is from Windows 10 and I don't know how many apply to Win7. +// See nt5src for the descriptions. They are not very relevant to VxKex so +// it doesn't really matter that we don't know what the rest of them do. +// +// The naming for these is complete garbage btw. +#define KACF_OLDGETSHORTPATHNAME 0x00000001 +#define KACF_VERSIONLIE 0x00000002 +#define KACF_GETDISKFREESPACE 0x00000008 +#define KACF_FTMFROMCURRENTAPT 0x00000020 +#define KACF_DISALLOWORBINDINGCHANGES 0x00000040 +#define KACF_OLE32VALIDATEPTRS 0x00000080 +#define KACF_DISABLECICERO 0x00000100 +#define KACF_OLE32ENABLEASYNCDOCFILE 0x00000200 +#define KACF_OLE32ENABLELEGACYEXCEPTIONHANDLING 0x00000400 +#define KACF_RPCDISABLENDRCLIENTHARDENING 0x00000800 +#define KACF_RPCDISABLENDRMAYBENULL_SIZEIS 0x00001000 +#define KACF_DISABLEALLDDEHACK_NOT_USED 0x00002000 +#define KACF_RPCDISABLENDR61_RANGE 0x00004000 +#define KACF_RPC32ENABLELEGACYEXCEPTIONHANDLING 0x00008000 +#define KACF_OLE32DOCFILEUSELEGACYNTFSFLAGS 0x00010000 +#define KACF_RPCDISABLENDRCONSTIIDCHECK 0x00020000 +#define KACF_USERDISABLEFORWARDERPATCH 0x00040000 +#define KACF_OLE32DISABLENEW_WMPAINT_DISPATCH 0x00100000 +#define KACF_ADDRESTRICTEDSIDINCOINITIALIZESECURITY 0x00200000 +#define KACF_ALLOCDEBUGINFOFORCRITSECTIONS 0x00400000 +#define KACF_OLEAUT32ENABLEUNSAFELOADTYPELIBRELATIVE 0x00800000 +#define KACF_ALLOWMAXIMIZEDWINDOWGAMMA 0x01000000 +#define KACF_DONOTADDTOCACHE 0x80000000 + +#define FLG_STOP_ON_EXCEPTION 0x00000001 // user and kernel mode +#define FLG_SHOW_LDR_SNAPS 0x00000002 // user and kernel mode +#define FLG_DEBUG_INITIAL_COMMAND 0x00000004 // kernel mode only up until WINLOGON started +#define FLG_STOP_ON_HUNG_GUI 0x00000008 // kernel mode only while running + +#define FLG_HEAP_ENABLE_TAIL_CHECK 0x00000010 // user mode only +#define FLG_HEAP_ENABLE_FREE_CHECK 0x00000020 // user mode only +#define FLG_HEAP_VALIDATE_PARAMETERS 0x00000040 // user mode only +#define FLG_HEAP_VALIDATE_ALL 0x00000080 // user mode only + +#define FLG_APPLICATION_VERIFIER 0x00000100 // user mode only +#define FLG_POOL_ENABLE_TAGGING 0x00000400 // kernel mode only +#define FLG_HEAP_ENABLE_TAGGING 0x00000800 // user mode only + +#define FLG_USER_STACK_TRACE_DB 0x00001000 // x86 user mode only +#define FLG_KERNEL_STACK_TRACE_DB 0x00002000 // x86 kernel mode only at boot time +#define FLG_MAINTAIN_OBJECT_TYPELIST 0x00004000 // kernel mode only at boot time +#define FLG_HEAP_ENABLE_TAG_BY_DLL 0x00008000 // user mode only + +#define FLG_DISABLE_STACK_EXTENSION 0x00010000 // user mode only +#define FLG_ENABLE_CSRDEBUG 0x00020000 // kernel mode only at boot time +#define FLG_ENABLE_KDEBUG_SYMBOL_LOAD 0x00040000 // kernel mode only +#define FLG_DISABLE_PAGE_KERNEL_STACKS 0x00080000 // kernel mode only at boot time + +#define FLG_ENABLE_SYSTEM_CRIT_BREAKS 0x00100000 // user mode only +#define FLG_HEAP_DISABLE_COALESCING 0x00200000 // user mode only +#define FLG_ENABLE_CLOSE_EXCEPTIONS 0x00400000 // kernel mode only +#define FLG_ENABLE_EXCEPTION_LOGGING 0x00800000 // kernel mode only + +#define FLG_ENABLE_HANDLE_TYPE_TAGGING 0x01000000 // kernel mode only +#define FLG_HEAP_PAGE_ALLOCS 0x02000000 // user mode only +#define FLG_DEBUG_INITIAL_COMMAND_EX 0x04000000 // kernel mode only up until WINLOGON started +#define FLG_DISABLE_DBGPRINT 0x08000000 // kernel mode only + +#define FLG_CRITSEC_EVENT_CREATION 0x10000000 // user mode only, Force early creation of resource events +#define FLG_LDR_TOP_DOWN 0x20000000 // user mode only, win64 only +#define FLG_ENABLE_HANDLE_EXCEPTIONS 0x40000000 // kernel mode only +#define FLG_DISABLE_PROTDLLS 0x80000000 // user mode only (smss/winlogon) + +// IFEO VerifierDebug +#define AVRF_DBG_SHOW_SNAPS 0x0001 +#define AVRF_DBG_SHOW_VERIFIED_EXPORTS 0x0002 +#define AVRF_DBG_SHOW_DLLS_WITH_EXPORTS 0x0004 +#define AVRF_DBG_SHOW_PROVIDER_LOADS 0x0008 +#define AVRF_DBG_SHOW_CHAIN_ACTIVITY 0x0010 +#define AVRF_DBG_SHOW_CHAIN_DETAILS 0x0020 +#define AVRF_DBG_SHOW_PAGE_HEAP_DETAILS 0x0040 + +// IFEO VerifierFlags +#define RTL_VRF_FLG_FULL_PAGE_HEAP 0x00000001 +#define RTL_VRF_FLG_RESERVED_DONOTUSE 0x00000002 +#define RTL_VRF_FLG_HANDLE_CHECKS 0x00000004 +#define RTL_VRF_FLG_STACK_CHECKS 0x00000008 +#define RTL_VRF_FLG_APPCOMPAT_CHECKS 0x00000010 +#define RTL_VRF_FLG_TLS_CHECKS 0x00000020 +#define RTL_VRF_FLG_DIRTY_STACKS 0x00000040 +#define RTL_VRF_FLG_RPC_CHECKS 0x00000080 +#define RTL_VRF_FLG_COM_CHECKS 0x00000100 +#define RTL_VRF_FLG_DANGEROUS_APIS 0x00000200 +#define RTL_VRF_FLG_RACE_CHECKS 0x00000400 +#define RTL_VRF_FLG_DEADLOCK_CHECKS 0x00000800 +#define RTL_VRF_FLG_FIRST_CHANCE_EXCEPTION_CHECKS 0x00001000 +#define RTL_VRF_FLG_VIRTUAL_MEM_CHECKS 0x00002000 +#define RTL_VRF_FLG_ENABLE_LOGGING 0x00004000 +#define RTL_VRF_FLG_FAST_FILL_HEAP 0x00008000 +#define RTL_VRF_FLG_VIRTUAL_SPACE_TRACKING 0x00010000 +#define RTL_VRF_FLG_ENABLED_SYSTEM_WIDE 0x00020000 +#define RTL_VRF_FLG_MISCELLANEOUS_CHECKS 0x00020000 +#define RTL_VRF_FLG_LOCK_CHECKS 0x00040000 + +#define INSPECT_LEAKS 1 +#define BREAK_ON_LEAKS 2 + +#define DLL_PROCESS_VERIFIER 4 + +#ifdef _M_X64 +# define GDI_HANDLE_BUFFER_SIZE GDI_HANDLE_BUFFER_SIZE64 +#else +# define GDI_HANDLE_BUFFER_SIZE GDI_HANDLE_BUFFER_SIZE32 +#endif + +#define EVENT_QUERY_STATE 0x0001 +#define EVENT_MODIFY_STATE 0x0002 + +// Key creation disposition +#define REG_CREATED_NEW_KEY (0x00000001L) +#define REG_OPENED_EXISTING_KEY (0x00000002L) + +// Key save flags +#define REG_STANDARD_FORMAT 1 +#define REG_LATEST_FORMAT 2 +#define REG_NO_COMPRESSION 4 + +// Key restore flags +#define REG_WHOLE_HIVE_VOLATILE (0x00000001L) // Restore whole hive volatile +#define REG_REFRESH_HIVE (0x00000002L) // Unwind changes to last flush +#define REG_NO_LAZY_FLUSH (0x00000004L) // Never lazy flush this hive +#define REG_FORCE_RESTORE (0x00000008L) // Force the restore process even when we have open handles on subkeys + +// Unload flags +#define REG_FORCE_UNLOAD 1 + +// Notify filter flags +#define REG_NOTIFY_CHANGE_NAME (0x00000001L) // Create or delete (child) +#define REG_NOTIFY_CHANGE_ATTRIBUTES (0x00000002L) +#define REG_NOTIFY_CHANGE_LAST_SET (0x00000004L) // time stamp +#define REG_NOTIFY_CHANGE_SECURITY (0x00000008L) + +#define RTL_IMAGE_NT_HEADER_EX_FLAG_NO_RANGE_CHECK (0x00000001) + +#define RTL_HASH_ALLOCATED_HEADER 1 +#define RTL_HASH_RESERVED_SIGNATURE 0 + +#define HASH_STRING_ALGORITHM_DEFAULT (0) +#define HASH_STRING_ALGORITHM_X65599 (1) +#define HASH_STRING_ALGORITHM_INVALID (0xffffffff) + +// for LDR_DATA_TABLE_ENTRY +#define LDRP_STATIC_LINK 0x00000002 +#define LDRP_IMAGE_DLL 0x00000004 +#define LDRP_SHIMENG_ENTRY_PROCESSED 0x00000008 +#define LDRP_TELEMETRY_ENTRY_PROCESSED 0x00000010 +#define LDRP_IMAGE_INTEGRITY_FORCED 0x00000020 +#define LDRP_LOAD_IN_PROGRESS 0x00001000 +#define LDRP_UNLOAD_IN_PROGRESS 0x00002000 +#define LDRP_ENTRY_PROCESSED 0x00004000 +#define LDRP_ENTRY_INSERTED 0x00008000 +#define LDRP_CURRENT_LOAD 0x00010000 +#define LDRP_FAILED_BUILTIN_LOAD 0x00020000 +#define LDRP_DONT_CALL_FOR_THREADS 0x00040000 +#define LDRP_PROCESS_ATTACH_CALLED 0x00080000 +#define LDRP_DEBUG_SYMBOLS_LOADED 0x00100000 +#define LDRP_IMAGE_NOT_AT_BASE 0x00200000 +#define LDRP_COR_IMAGE 0x00400000 +#define LDRP_COR_OWNS_UNMAP 0x00800000 +#define LDRP_SYSTEM_MAPPED 0x01000000 +#define LDRP_IMAGE_VERIFYING 0x02000000 +#define LDRP_DRIVER_DEPENDENT_DLL 0x04000000 +#define LDRP_ENTRY_NATIVE 0x08000000 +#define LDRP_REDIRECTED 0x10000000 +#define LDRP_NON_PAGED_DEBUG_INFO 0x20000000 +#define LDRP_MM_LOADED 0x40000000 +#define LDRP_COMPAT_DATABASE_PROCESSED 0x80000000 + +#define RTL_FIND_CHAR_IN_UNICODE_STRING_START_AT_END (0x00000001) +#define RTL_FIND_CHAR_IN_UNICODE_STRING_COMPLEMENT_CHAR_SET (0x00000002) +#define RTL_FIND_CHAR_IN_UNICODE_STRING_CASE_INSENSITIVE (0x00000004) + +#define HEAP_SIGNATURE (ULONG) 0xEEFFEEFF +#define HEAP_LOCK_USER_ALLOCATED (ULONG) 0x80000000 +#define HEAP_VALIDATE_PARAMETERS_ENABLED (ULONG) 0x40000000 +#define HEAP_VALIDATE_ALL_ENABLED (ULONG) 0x20000000 +#define HEAP_SKIP_VALIDATION_CHECKS (ULONG) 0x10000000 +#define HEAP_CAPTURE_STACK_BACKTRACES (ULONG) 0x08000000 +#define HEAP_FLAG_PAGE_ALLOCS (ULONG) 0x01000000 + +#define HEAP_DEBUG_FLAGS (HEAP_VALIDATE_PARAMETERS_ENABLED | \ + HEAP_VALIDATE_ALL_ENABLED | \ + HEAP_CAPTURE_STACK_BACKTRACES | \ + HEAP_CREATE_ENABLE_TRACING | \ + HEAP_FLAG_PAGE_ALLOCS) + +#define HEAP_CLASS_0 0x00000000 // process heap +#define HEAP_CLASS_1 0x00001000 // private heap +#define HEAP_CLASS_2 0x00002000 // Kernel Heap +#define HEAP_CLASS_3 0x00003000 // GDI heap +#define HEAP_CLASS_4 0x00004000 // User heap +#define HEAP_CLASS_5 0x00005000 // Console heap +#define HEAP_CLASS_6 0x00006000 // User Desktop heap +#define HEAP_CLASS_7 0x00007000 // Csrss Shared heap +#define HEAP_CLASS_8 0x00008000 // Csr Port heap +#define HEAP_CLASS_MASK 0x0000F000 + +// win8+ only - use with NtUnmapViewOfSectionEx +#define MEM_UNMAP_WITH_TRANSIENT_BOOST 1 +#define MEM_PRESERVE_PLACEHOLDER 2 +#define MEM_UNMAP_VALID_FLAGS (MEM_UNMAP_WITH_TRANSIENT_BOOST | MEM_PRESERVE_PLACEHOLDER) + +// win10+ only - NtMapViewOfSectionEx +#define MEM_EXTENDED_PARAMETER_GRAPHICS 0x00000001 +#define MEM_EXTENDED_PARAMETER_NONPAGED 0x00000002 +#define MEM_EXTENDED_PARAMETER_ZERO_PAGES_OPTIONAL 0x00000004 +#define MEM_EXTENDED_PARAMETER_NONPAGED_LARGE 0x00000008 +#define MEM_EXTENDED_PARAMETER_NONPAGED_HUGE 0x00000010 +#define MEM_EXTENDED_PARAMETER_SOFT_FAULT_PAGES 0x00000020 +#define MEM_EXTENDED_PARAMETER_NUMA_NODE_MANDATORY MINLONG64 + +#define MEM_REPLACE_PLACEHOLDER 0x4000 + +// win10+ only - NtMapViewOfSectionEx +typedef enum _MEM_EXTENDED_PARAMETER_TYPE { + MemExtendedParameterInvalidType = 0, + MemExtendedParameterAddressRequirements, + MemExtendedParameterNumaNode, + MemExtendedParameterPartitionHandle, + MemExtendedParameterUserPhysicalHandle, + MemExtendedParameterAttributeFlags, + MemExtendedParameterMax +} TYPEDEF_TYPE_NAME(MEM_EXTENDED_PARAMETER_TYPE); + +// win10+ only - NtMapViewOfSectionEx +#define MEM_EXTENDED_PARAMETER_TYPE_BITS 8 + +typedef struct DECLSPEC_ALIGN(8) _MEM_EXTENDED_PARAMETER { + struct { + DWORD64 Type : MEM_EXTENDED_PARAMETER_TYPE_BITS; + DWORD64 Reserved : 64 - MEM_EXTENDED_PARAMETER_TYPE_BITS; + }; + + union { + DWORD64 ULong64; + PVOID Pointer; + SIZE_T Size; + HANDLE Handle; + DWORD ULong; + }; +} TYPEDEF_TYPE_NAME(MEM_EXTENDED_PARAMETER); + +typedef struct _MEM_ADDRESS_REQUIREMENTS { + PVOID LowestStartingAddress; + PVOID HighestStartingAddress; + SIZE_T Alignment; +} TYPEDEF_TYPE_NAME(MEM_ADDRESS_REQUIREMENTS); + +#define MEM_EXECUTE_OPTION_DISABLE 0x1 +#define MEM_EXECUTE_OPTION_ENABLE 0x2 +#define MEM_EXECUTE_OPTION_DISABLE_THUNK_EMULATION 0x4 +#define MEM_EXECUTE_OPTION_PERMANENT 0x8 +#define MEM_EXECUTE_OPTION_EXECUTE_DISPATCH_ENABLE 0x10 +#define MEM_EXECUTE_OPTION_IMAGE_DISPATCH_ENABLE 0x20 +#define MEM_EXECUTE_OPTION_SEHOP 0x40 +#define MEM_EXECUTE_OPTION_VALID_FLAGS 0x7F + +#define PROCESS_PRIORITY_CLASS_UNKNOWN 0 +#define PROCESS_PRIORITY_CLASS_IDLE 1 +#define PROCESS_PRIORITY_CLASS_NORMAL 2 +#define PROCESS_PRIORITY_CLASS_HIGH 3 +#define PROCESS_PRIORITY_CLASS_REALTIME 4 +#define PROCESS_PRIORITY_CLASS_BELOW_NORMAL 5 +#define PROCESS_PRIORITY_CLASS_ABOVE_NORMAL 6 + +#define RTL_HASH_RESERVED_SIGNATURE 0 +#define RTL_BASE_DYNAMIC_HASH_TABLE_SIZE 0x80 +#define RTL_MAX_DYNAMIC_HASH_TABLE_SIZE 0xFFFF +#define RTL_HT_FIRST_LEVEL_DIR_SIZE 0x1FF + +#define RTL_HT_FLAG_HEAP_ALLOCATED 1 + +// +// Object Manager Directory Specific Access Rights. +// + +#define DIRECTORY_QUERY (0x0001) +#define DIRECTORY_TRAVERSE (0x0002) +#define DIRECTORY_CREATE_OBJECT (0x0004) +#define DIRECTORY_CREATE_SUBDIRECTORY (0x0008) + +#define DIRECTORY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0xF) + +#define DLL_CHARACTERISTIC_LOAD_AS_DATA 0x000002 +#define DLL_CHARACTERISTIC_IGNORE_CODE_AUTHZ_LEVEL 0x001000 +#define DLL_CHARACTERISTIC_REQUIRE_SIGNATURE 0x800000 + +// LDR_GET_DLL_HANDLE_EX_UNCHANGED_REFCOUNT cannot be used together with +// LDR_GET_DLL_HANDLE_EX_PIN. +#define LDR_GET_DLL_HANDLE_EX_UNCHANGED_REFCOUNT 0x0001 // The DLL's reference count will not be incremented. +#define LDR_GET_DLL_HANDLE_EX_PIN 0x0002 // The DLL will remain loaded until the process exits. +#define LDR_GET_DLL_HANDLE_EX_UNKNOWN 0x0004 // Is valid, but appears to do nothing. + +#pragma endregion + +#pragma region Data Type Definitions + +typedef LONG NTSTATUS; +typedef LONG KPRIORITY; +typedef SHORT CSHORT; + +typedef ULONG GDI_HANDLE_BUFFER32[GDI_HANDLE_BUFFER_SIZE32]; +typedef ULONG GDI_HANDLE_BUFFER64[GDI_HANDLE_BUFFER_SIZE64]; +typedef ULONG GDI_HANDLE_BUFFER[GDI_HANDLE_BUFFER_SIZE]; +typedef VOID (*PPS_POST_PROCESS_INIT_ROUTINE) (VOID); + +typedef struct _PEB *PPEB; +typedef struct _PEB *__ptr64 PPEB64; +typedef struct _TEB *PTEB; +typedef struct _TEB *__ptr64 PTEB64; + +typedef struct _CLIENT_ID { + HANDLE UniqueProcess; + HANDLE UniqueThread; +} TYPEDEF_TYPE_NAME(CLIENT_ID); + +typedef struct _PROCESS_BASIC_INFORMATION { + NTSTATUS ExitStatus; + PPEB PebBaseAddress; + ULONG_PTR AffinityMask; + KPRIORITY BasePriority; + ULONG_PTR UniqueProcessId; + ULONG_PTR InheritedFromUniqueProcessId; +} TYPEDEF_TYPE_NAME(PROCESS_BASIC_INFORMATION); + +// Use with NtWow64QueryInformationProcess64. +typedef struct _PROCESS_BASIC_INFORMATION64 { + NTSTATUS ExitStatus; + PPEB64 PebBaseAddress; + ULONGLONG AffinityMask; + KPRIORITY BasePriority; + ULONGLONG UniqueProcessId; + ULONGLONG InheritedFromUniqueProcessId; +} TYPEDEF_TYPE_NAME(PROCESS_BASIC_INFORMATION64); + +typedef struct _THREAD_BASIC_INFORMATION { + NTSTATUS ExitStatus; + PTEB TebBaseAddress; + CLIENT_ID ClientId; + ULONG_PTR AffinityMask; + KPRIORITY Priority; + LONG BasePriority; +} TYPEDEF_TYPE_NAME(THREAD_BASIC_INFORMATION); + +typedef struct _THREAD_TEB_INFORMATION { + PVOID TebInformation; + ULONG TebOffset; + ULONG BytesToRead; +} TYPEDEF_TYPE_NAME(THREAD_TEB_INFORMATION); + +typedef struct _THREAD_LAST_SYSCALL_INFORMATION { + PVOID FirstArgument; + USHORT SystemCallNumber; +} TYPEDEF_TYPE_NAME(THREAD_LAST_SYSCALL_INFORMATION); + +typedef struct _PAGE_PRIORITY_INFORMATION { + ULONG PagePriority; +} TYPEDEF_TYPE_NAME(PAGE_PRIORITY_INFORMATION); + +#pragma pack(push, 1) +typedef struct _PROCESS_DEVICEMAP_INFORMATION { + union { + struct { + HANDLE DirectoryHandle; + } Set; + + struct { + ULONG DriveMap; + UCHAR DriveType[32]; + } Query; + }; +} TYPEDEF_TYPE_NAME(PROCESS_DEVICEMAP_INFORMATION); +#pragma pack(pop) + +typedef enum _HARDERROR_RESPONSE_OPTION { + OptionAbortRetryIgnore, + OptionOk, + OptionOkCancel, + OptionRetryCancel, + OptionYesNo, + OptionYesNoCancel, + OptionShutdownSystem, + OptionOkNoWait, + OptionCancelTryContinue +} TYPEDEF_TYPE_NAME(HARDERROR_RESPONSE_OPTION); + +typedef enum _HARDERROR_RESPONSE +{ + ResponseReturnToCaller, + ResponseNotHandled, + ResponseAbort, + ResponseCancel, + ResponseIgnore, + ResponseNo, + ResponseOk, + ResponseRetry, + ResponseYes, + ResponseTryAgain, + ResponseContinue +} TYPEDEF_TYPE_NAME(HARDERROR_RESPONSE); + +typedef enum _PROCESSINFOCLASS { + ProcessBasicInformation, // PROCESS_BASIC_INFORMATION + ProcessQuotaLimits, // QUOTA_LIMITS + ProcessIoCounters, // IO_COUNTERS + ProcessVmCounters, // VM_COUNTERS or VM_COUNTERS_EX + ProcessTimes, // KERNEL_USER_TIMES + ProcessBasePriority, // KPRIORITY + ProcessRaisePriority, // ULONG + ProcessDebugPort, // HANDLE + ProcessExceptionPort, // HANDLE + ProcessAccessToken, // PROCESS_ACCESS_TOKEN + ProcessLdtInformation, // PROCESS_LDT_INFORMATION + ProcessLdtSize, // ULONG + ProcessDefaultHardErrorMode, // ULONG + ProcessIoPortHandlers, // (Kernel mode only) + ProcessPooledUsageAndLimits, // POOLED_USAGE_AND_LIMITS + ProcessWorkingSetWatch, // PROCESS_WS_WATCH_INFORMATION + ProcessUserModeIOPL, // ULONG + ProcessEnableAlignmentFaultFixup, // BOOLEAN + ProcessPriorityClass, // PROCESS_PRIORITY_CLASS + ProcessWx86Information, // ULONG + ProcessHandleCount, // ULONG or PROCESS_HANDLE_INFORMATION + ProcessAffinityMask, // KAFFINITY or GROUP_AFFINITY + ProcessPriorityBoost, // ULONG + ProcessDeviceMap, // PROCESS_DEVICEMAP_INFORMATION or PROCESS_DEVICEMAP_INFORMATION_EX + ProcessSessionInformation, + ProcessForegroundInformation, + ProcessWow64Information, // ULONG_PTR (returns address of 32-bit PEB, or 0 if not wow64) + ProcessImageFileName, // UNICODE_STRING + ProcessLUIDDeviceMapsEnabled, + ProcessBreakOnTermination, // ULONG + ProcessDebugObjectHandle, // HANDLE + ProcessDebugFlags, // ULONG + ProcessHandleTracing, + ProcessIoPriority, // IO_PRIORITY_HINT + ProcessExecuteFlags, // ULONG + ProcessTlsInformation, + ProcessCookie, + ProcessImageInformation, // SECTION_IMAGE_INFORMATION + ProcessCycleTime, + ProcessPagePriority, // PAGE_PRIORITY_INFORMATION + ProcessInstrumentationCallback, // PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION + ProcessThreadStackAllocation, + ProcessWorkingSetWatchEx, + ProcessImageFileNameWin32, // UNICODE_STRING + ProcessImageFileMapping, + ProcessAffinityUpdateMode, + ProcessMemoryAllocationMode, + ProcessGroupInformation, // USHORT[] + ProcessTokenVirtualizationEnabled, + ProcessConsoleHostProcess, // HANDLE + ProcessWindowInformation, + MaxProcessInfoClass +} PROCESSINFOCLASS; + +typedef enum _THREADINFOCLASS { + ThreadBasicInformation, // THREAD_BASIC_INFORMATION, get + ThreadTimes, // KERNEL_USER_TIMES, get + ThreadPriority, // KPRIORITY, set + ThreadBasePriority, // LONG, set + ThreadAffinityMask, // KAFFINITY, set + ThreadImpersonationToken, // HANDLE, set + ThreadDescriptorTableEntry, // DESCRIPTOR_TABLE_ENTRY, get (Not implemented on x64) + ThreadEnableAlignmentFaultFixup, // BOOLEAN, set + ThreadEventPair, // unused + ThreadQuerySetWin32StartAddress, // PVOID, get/set + ThreadZeroTlsCell, // ULONG, set + ThreadPerformanceCount, // ULONGLONG, get (Always return 0 on normal OS) + ThreadAmILastThread, // BOOL, get + ThreadIdealProcessor, // ULONG, set + ThreadPriorityBoost, // BOOL, get/set + ThreadSetTlsArrayAddresses, // PVOID, set + ThreadIsIoPending, // BOOL, get + ThreadHideFromDebugger, // VOID, set + ThreadBreakOnTermination, // BOOL, get/set + ThreadSwitchLegacyState, // , set + ThreadIsTerminated, // BOOL, get, last member for Windows Research Kernel + ThreadLastSystemCall, // THREAD_LAST_SYSCALL_INFORMATION, get + ThreadIoPriority, + ThreadCycleTime, // THREAD_CYCLE_TIME_INFORMATION, get + ThreadPagePriority, // PAGE_PRIORITY_INFORMATION, get + ThreadActualBasePriority, + ThreadTebInformation, // THREAD_TEB_INFORMATION, get (reads bytes out of specified thread's TEB) + ThreadCSwitchMon, + ThreadCSwitchPmu, + ThreadWow64Context, // WOW64_CONTEXT, get + ThreadGroupInformation, + ThreadUmsInformation, + ThreadCounterProfiling, + ThreadIdealProcessorEx, // PROCESSOR_NUMBER, get, last member for Windows 7 + ThreadCpuAccountingInformation, // Last member for Windows 8 + ThreadSuspendCount, // Last member for Windows 8.1 + ThreadHeterogeneousCpuPolicy, + ThreadContainerId, + ThreadNameInformation, // UNICODE_STRING, get/set + ThreadSelectedCpuSets, + ThreadSystemThreadInformation, + ThreadActualGroupAffinity, + ThreadDynamicCodePolicyInfo, + ThreadExplicitCaseSensitivity, + ThreadWorkOnBehalfTicket, + ThreadSubsystemInformation, + ThreadDbgkWerReportActive, + ThreadAttachContainer, + ThreadManageWritesToExecutableMemory, + ThreadPowerThrottlingState, + ThreadWorkloadClass, // Last member for Windows 10 + ThreadCreateStateChange, // Windows 11+ + ThreadApplyStateChange, + ThreadStrongerBadHandleChecks, + ThreadEffectiveIoPriority, + ThreadEffectivePagePriority, + MaxThreadInfoClass +} THREADINFOCLASS; + +typedef enum _SYSINFOCLASS { + SystemBasicInformation, // SYSTEM_BASIC_INFORMATION + SystemProcessorInformation, // SYSTEM_PROCESSOR_INFORMATION + SystemPerformanceInformation, // SYSTEM_PERFORMANCE_INFORMATION + SystemTimeOfDayInformation, // SYSTEM_TIMEOFDAY_INFORMATION + SystemPathInformation, // always returns STATUS_NOT_IMPLEMENTED + SystemProcessInformation, + SystemCallCountInformation, + SystemDeviceInformation, + SystemProcessorPerformanceInformation, + SystemFlagsInformation, + SystemCallTimeInformation, + SystemModuleInformation, + SystemLocksInformation, + SystemStackTraceInformation, + SystemPagedPoolInformation, + SystemNonPagedPoolInformation, + SystemHandleInformation, + SystemObjectInformation, + SystemPageFileInformation, + SystemVdmInstemulInformation, + SystemVdmBopInformation, + SystemFileCacheInformation, + SystemPoolTagInformation, + SystemInterruptInformation, + SystemDpcBehaviorInformation, + SystemFullMemoryInformation, + SystemLoadGdiDriverInformation, + SystemUnloadGdiDriverInformation, + SystemTimeAdjustmentInformation, + SystemSummaryMemoryInformation, + SystemMirrorMemoryInformation, + SystemPerformanceTraceInformation, + SystemObsolete0, + SystemExceptionInformation, + SystemCrashDumpStateInformation, + SystemKernelDebuggerInformation, + SystemContextSwitchInformation, + SystemRegistryQuotaInformation, + SystemExtendServiceTableInformation, + SystemPrioritySeperation, + SystemVerifierAddDriverInformation, + SystemVerifierRemoveDriverInformation, + SystemProcessorIdleInformation, + SystemLegacyDriverInformation, + SystemCurrentTimeZoneInformation, + SystemLookasideInformation, + SystemTimeSlipNotification, + SystemSessionCreate, + SystemSessionDetach, + SystemSessionInformation, + SystemRangeStartInformation, + SystemVerifierInformation, + SystemVerifierThunkExtend, + SystemSessionProcessInformation, // SYSTEM_SESSION_PROCESS_INFORMATION + SystemLoadGdiDriverInSystemSpace, + SystemNumaProcessorMap, + SystemPrefetcherInformation, + SystemExtendedProcessInformation, + SystemRecommendedSharedDataAlignment, + SystemComPlusPackage, + SystemNumaAvailableMemory, + SystemProcessorPowerInformation, + SystemEmulationBasicInformation, + SystemEmulationProcessorInformation, // SYSTEM_PROCESSOR_INFORMATION + SystemExtendedHandleInformation, + SystemLostDelayedWriteInformation, + SystemBigPoolInformation, + SystemSessionPoolTagInformation, + SystemSessionMappedViewInformation, + SystemHotpatchInformation, + SystemObjectSecurityMode, + SystemWatchdogTimerHandler, + SystemWatchdogTimerInformation, + SystemLogicalProcessorInformation, + SystemWow64SharedInformation, + SystemRegisterFirmwareTableInformationHandler, + SystemFirmwareTableInformation, + SystemModuleInformationEx, + SystemVerifierTriageInformation, + SystemSuperfetchInformation, + SystemMemoryListInformation, + SystemFileCacheInformationEx, // last member in WRK + SystemThreadPriorityClientIdInformation, + SystemProcessorIdleCycleTimeInformation, + SystemVerifierCancellationInformation, + SystemProcessorPowerInformationEx, + SystemRefTraceInformation, + SystemSpecialPoolInformation, + SystemProcessIdInformation, + SystemErrorPortInformation, + SystemBootEnvironmentInformation, + SystemHypervisorInformation, + SystemVerifierInformationEx, // SYSTEM_VERIFIER_INFORMATION_EX + SystemTimeZoneInformation, + SystemImageFileExecutionOptionsInformation, // SYSTEM_IMAGE_FILE_EXECUTION_OPTIONS_INFORMATION + SystemCoverageInformation, + SystemPrefetchPatchInformation, + SystemVerifierFaultsInformation, + SystemSystemPartitionInformation, + SystemSystemDiskInformation, + SystemProcessorPerformanceDistribution, + SystemNumaProximityNodeInformation, + SystemDynamicTimeZoneInformation, + SystemCodeIntegrityInformation, + SystemProcessorMicrocodeUpdateInformation, + SystemProcessorBrandString, + SystemVirtualAddressInformation, + SystemLogicalProcessorAndGroupInformation, + SystemProcessorCycleTimeInformation, + SystemStoreInformation, + SystemRegistryAppendString, + SystemAitSamplingValue, + SystemVhdBootInformation, + SystemCpuQuotaInformation, + SystemNativeBasicInformation, + SystemErrorPortTimeouts, + SystemLowPriorityIoInformation, + SystemBootEntropyInformation, + SystemVerifierCountersInformation, + SystemPagedPoolInformationEx, + SystemSystemPtesInformationEx, + SystemNodeDistanceInformation, + SystemAcpiAuditInformation, + SystemBasicPerformanceInformation, // SYSTEM_BASIC_PERFORMANCE_INFORMATION, last member in Win7 + SystemQueryPerformanceCounterInformation, // Win7 SP1+ only + SystemSessionBigPoolInformation, + SystemBootGraphicsInformation, + SystemScrubPhysicalMemoryInformation, + SystemBadPageInformation, + SystemProcessorProfileControlArea, + SystemCombinePhysicalMemoryInformation, + SystemEntropyInterruptTimingInformation, + SystemConsoleInformation, + SystemPlatformBinaryInformation, + SystemPolicyInformation, + SystemHypervisorProcessorCountInformation, + SystemDeviceDataInformation, + SystemDeviceDataEnumerationInformation, + SystemMemoryTopologyInformation, + SystemMemoryChannelInformation, + SystemBootLogoInformation, + SystemProcessorPerformanceInformationEx, + SystemCriticalProcessErrorLogInformation, + SystemSecureBootPolicyInformation, + SystemPageFileInformationEx, + SystemSecureBootInformation, + SystemEntropyInterruptTimingRawInformation, + SystemPortableWorkspaceEfiLauncherInformation, + SystemFullProcessInformation, // last member in Windows 8 + SystemKernelDebuggerInformationEx, + SystemBootMetadataInformation, + SystemSoftRebootInformation, + SystemElamCertificateInformation, + SystemOfflineDumpConfigInformation, + SystemProcessorFeaturesInformation, + SystemRegistryReconciliationInformation, + SystemEdidInformation, // last member in Windows 8.1 + SystemManufacturingInformation, + SystemEnergyEstimationConfigInformation, + SystemHypervisorDetailInformation, + SystemProcessorCycleStatsInformation, + SystemVmGenerationCountInformation, + SystemTrustedPlatformModuleInformation, + SystemKernelDebuggerFlags, + SystemCodeIntegrityPolicyInformation, + SystemIsolatedUserModeInformation, + SystemHardwareSecurityTestInterfaceResultsInformation, + SystemSingleModuleInformation, + SystemAllowedCpuSetsInformation, + SystemDmaProtectionInformation, + SystemInterruptCpuSetsInformation, + SystemSecureBootPolicyFullInformation, + SystemCodeIntegrityPolicyFullInformation, + SystemAffinitizedInterruptProcessorInformation, + SystemRootSiloInformation, + SystemCpuSetInformation, + SystemCpuSetTagInformation, + SystemWin32WerStartCallout, + SystemSecureKernelProfileInformation, + SystemCodeIntegrityPlatformManifestInformation, + SystemInterruptSteeringInformation, + SystemSuppportedProcessorArchitectures, + SystemMemoryUsageInformation, + SystemCodeIntegrityCertificateInformation, + SystemPhysicalMemoryInformation, + SystemControlFlowTransition, + SystemKernelDebuggingAllowed, + SystemActivityModerationExeState, + SystemActivityModerationUserSettings, + SystemCodeIntegrityPoliciesFullInformation, + SystemCodeIntegrityUnlockInformation, + SystemIntegrityQuotaInformation, + SystemFlushInformation, + SystemProcessorIdleMaskInformation, + SystemSecureDumpEncryptionInformation, + SystemWriteConstraintInformation, + SystemKernelVaShadowInformation, + SystemHypervisorSharedPageInformation, + SystemFirmwareBootPerformanceInformation, + SystemCodeIntegrityVerificationInformation, + SystemFirmwarePartitionInformation, + SystemSpeculationControlInformation, + SystemDmaGuardPolicyInformation, + SystemEnclaveLaunchControlInformation, + SystemWorkloadAllowedCpuSetsInformation, + SystemCodeIntegrityUnlockModeInformation, + SystemLeapSecondInformation, + SystemFlags2Information, + SystemSecurityModelInformation, + SystemCodeIntegritySyntheticCacheInformation, + SystemFeatureConfigurationInformation, + SystemFeatureConfigurationSectionInformation, + SystemFeatureUsageSubscriptionInformation, + SystemSecureSpeculationControlInformation, + MaxSystemInfoClass +} SYSINFOCLASS; + +typedef struct _SYSTEM_BASIC_PERFORMANCE_INFORMATION { + ULONG_PTR AvailablePages; + ULONG_PTR CommittedPages; + ULONG_PTR CommitLimit; + ULONG_PTR PeakCommitment; +} TYPEDEF_TYPE_NAME(SYSTEM_BASIC_PERFORMANCE_INFORMATION); + +#define LDRP_STATIC_LINK 0x00000002 +#define LDRP_IMAGE_DLL 0x00000004 +#define LDRP_LOAD_IN_PROGRESS 0x00001000 +#define LDRP_UNLOAD_IN_PROGRESS 0x00002000 +#define LDRP_ENTRY_PROCESSED 0x00004000 +#define LDRP_ENTRY_INSERTED 0x00008000 +#define LDRP_CURRENT_LOAD 0x00010000 +#define LDRP_FAILED_BUILTIN_LOAD 0x00020000 +#define LDRP_DONT_CALL_FOR_THREADS 0x00040000 +#define LDRP_PROCESS_ATTACH_CALLED 0x00080000 +#define LDRP_DEBUG_SYMBOLS_LOADED 0x00100000 +#define LDRP_IMAGE_NOT_AT_BASE 0x00200000 +#define LDRP_COR_IMAGE 0x00400000 +#define LDRP_COR_OWNS_UNMAP 0x00800000 +#define LDRP_SYSTEM_MAPPED 0x01000000 +#define LDRP_IMAGE_VERIFYING 0x02000000 +#define LDRP_DRIVER_DEPENDENT_DLL 0x04000000 +#define LDRP_ENTRY_NATIVE 0x08000000 +#define LDRP_REDIRECTED 0x10000000 +#define LDRP_NON_PAGED_DEBUG_INFO 0x20000000 +#define LDRP_MM_LOADED 0x40000000 +#define LDRP_COMPAT_DATABASE_PROCESSED 0x80000000 + +// https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/api/ntldr/rtl_process_module_information.htm +typedef struct _RTL_PROCESS_MODULE_INFORMATION { + PVOID Section; + PVOID MappedBase; + PVOID ImageBase; + ULONG ImageSize; + ULONG Flags; // LDRP_* flags defined above + USHORT LoadOrderIndex; + USHORT InitOrderIndex; + USHORT LoadCount; + USHORT OffsetToFileName; // &FullPathName[OffsetToFileName] is the base name. + CHAR FullPathName[0x100]; +} TYPEDEF_TYPE_NAME(RTL_PROCESS_MODULE_INFORMATION); + +// definition from this structure can be found in 8175 leaked symbols and probably other symbols too +// usage example: +// https://raw.githubusercontent.com/gtworek/PSBits/master/DFIR/SystemModuleInformationEx.c +typedef struct _RTL_PROCESS_MODULE_INFORMATION_EX { + USHORT NextOffset; + RTL_PROCESS_MODULE_INFORMATION BaseInfo; + ULONG ImageChecksum; // I'm guessing these are the fields straight out of the PE headers + ULONG TimeDateStamp; + PVOID DefaultBase; +} TYPEDEF_TYPE_NAME(RTL_PROCESS_MODULE_INFORMATION_EX); + +// https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/api/ntldr/rtl_process_modules.htm +typedef struct _RTL_PROCESS_MODULES { + ULONG NumberOfModules; + RTL_PROCESS_MODULE_INFORMATION Modules[]; +} TYPEDEF_TYPE_NAME(RTL_PROCESS_MODULES); + +typedef enum _MEMINFOCLASS { + MemoryBasicInformation, // MEMORY_BASIC_INFORMATION + MemoryWorkingSetInformation, // ULONG_PTR + MemoryMappedFilenameInformation, // UNICODE_STRING followed by a buffer to store the filename + MemoryRegionInformation, // MEMORY_REGION_INFORMATION + MemoryWorkingSetExInformation // MEMORY_WORKING_SET_EX_INFORMATION +} MEMINFOCLASS; + +typedef struct _MEMORY_REGION_INFORMATION { + PVOID AllocationBase; + PVOID AllocationProtect; + + union { + ULONG RegionType; + + struct { + UCHAR Private:1; + UCHAR MappedDataFile:1; + UCHAR MappedImage:1; + UCHAR MappedPageFile:1; + UCHAR MappedPhysical:1; + UCHAR DirectMapped:1; + ULONG Reserved:26; + }; + }; + + SIZE_T RegionSize; +} TYPEDEF_TYPE_NAME(MEMORY_REGION_INFORMATION); + +typedef struct _MEMORY_RANGE_ENTRY { + PVOID VirtualAddress; + SIZE_T NumberOfBytes; +} TYPEDEF_TYPE_NAME(MEMORY_RANGE_ENTRY); + +typedef struct _MEMORY_WORKING_SET_EX_INFORMATION { + PVOID VirtualAddress; + + union { + struct { + ULONG_PTR Valid : 1; + ULONG_PTR ShareCount : 3; + ULONG_PTR Win32Protection : 11; + ULONG_PTR Shared : 1; + ULONG_PTR Node : 6; + ULONG_PTR Locked : 1; + ULONG_PTR LargePage : 1; + ULONG_PTR Priority : 3; + }; + + ULONG_PTR AsUlongPtr; + } Flags; +} TYPEDEF_TYPE_NAME(MEMORY_WORKING_SET_EX_INFORMATION); + +typedef enum _NT_PRODUCT_TYPE { + NtProductWinNt = 1, + NtProductLanManNt, + NtProductServer +} TYPEDEF_TYPE_NAME(NT_PRODUCT_TYPE); + +typedef enum _ALTERNATIVE_ARCHITECTURE_TYPE { + StandardDesign, + NEC98x86 +} ALTERNATIVE_ARCHITECTURE_TYPE; + +typedef struct _STRING { + USHORT Length; + USHORT MaximumLength; + PCHAR Buffer; +} STRING, ANSI_STRING; + +GEN_STD_TYPEDEFS(STRING); +GEN_STD_TYPEDEFS(ANSI_STRING); + +typedef struct _UNICODE_STRING { + USHORT Length; + USHORT MaximumLength; + PWCHAR Buffer; +} TYPEDEF_TYPE_NAME(UNICODE_STRING); + +typedef struct _UNICODE_STRING32 { + USHORT Length; + USHORT MaximumLength; + DWORD Buffer; +} TYPEDEF_TYPE_NAME(UNICODE_STRING32); + +typedef struct _PEB_LDR_DATA { + ULONG Length; + BOOLEAN Initialized; + PVOID SsHandle; + LIST_ENTRY InLoadOrderModuleList; + LIST_ENTRY InMemoryOrderModuleList; + LIST_ENTRY InInitializationOrderModuleList; + PVOID EntryInProgress; + BOOLEAN ShutdownInProgress; + HANDLE ShutdownThreadId; +} TYPEDEF_TYPE_NAME(PEB_LDR_DATA); + +typedef struct _LDR_DATA_TABLE_ENTRY { + LIST_ENTRY InLoadOrderLinks; + LIST_ENTRY InMemoryOrderLinks; + LIST_ENTRY InInitializationOrderLinks; + + PVOID DllBase; + PVOID EntryPoint; + ULONG SizeOfImage; + + UNICODE_STRING FullDllName; + UNICODE_STRING BaseDllName; + + ULONG Flags; // LDRP_ + USHORT LoadCount; + USHORT TlsIndex; + + union { + LIST_ENTRY HashLinks; + + struct { + PVOID SectionPointer; + ULONG CheckSum; + }; + }; + + union { + ULONG TimeDateStamp; + PVOID LoadedImports; + }; + + PVOID EntryPointActivationContext; + PVOID PatchInformation; + + LIST_ENTRY ForwarderLinks; + LIST_ENTRY ServiceTagLinks; + LIST_ENTRY StaticLinks; + + PVOID ContextInformation; + ULONG_PTR OriginalBase; + LARGE_INTEGER LoadTime; +} TYPEDEF_TYPE_NAME(LDR_DATA_TABLE_ENTRY); + +typedef struct _CURDIR { + UNICODE_STRING DosPath; + HANDLE Handle; +} TYPEDEF_TYPE_NAME(CURDIR); + +typedef struct _RTL_DRIVE_LETTER_CURDIR { + USHORT Flags; + USHORT Length; + ULONG TimeStamp; + STRING DosPath; +} TYPEDEF_TYPE_NAME(RTL_DRIVE_LETTER_CURDIR); + +typedef struct _RTL_RELATIVE_NAME_U { + UNICODE_STRING RelativeName; + HANDLE ContainingDirectory; + PVOID CurDirRef; +} TYPEDEF_TYPE_NAME(RTL_RELATIVE_NAME_U); + +typedef struct _PEB_FREE_BLOCK { + struct _PEB_FREE_BLOCK *Next; + ULONG Size; +} TYPEDEF_TYPE_NAME(PEB_FREE_BLOCK); + +typedef struct _RTL_USER_PROCESS_PARAMETERS { + ULONG MaximumLength; + ULONG Length; + + ULONG Flags; // RTL_USER_PROCESS_PARAMETERS_* + ULONG DebugFlags; + + HANDLE ConsoleHandle; + ULONG ConsoleFlags; + HANDLE StandardInput; + HANDLE StandardOutput; + HANDLE StandardError; + + CURDIR CurrentDirectory; + UNICODE_STRING DllPath; + UNICODE_STRING ImagePathName; + UNICODE_STRING CommandLine; + PVOID Environment; + + ULONG StartingX; + ULONG StartingY; + ULONG CountX; + ULONG CountY; + ULONG CountCharsX; + ULONG CountCharsY; + ULONG FillAttribute; + + ULONG WindowFlags; + ULONG ShowWindowFlags; + UNICODE_STRING WindowTitle; + UNICODE_STRING DesktopInfo; + UNICODE_STRING ShellInfo; + UNICODE_STRING RuntimeData; + RTL_DRIVE_LETTER_CURDIR CurrentDirectories[RTL_MAX_DRIVE_LETTERS]; + + ULONG_PTR VOLATILE EnvironmentSize; + ULONG_PTR VOLATILE EnvironmentVersion; +} TYPEDEF_TYPE_NAME(RTL_USER_PROCESS_PARAMETERS); + +// for more info on this "API set" crap - https://lucasg.github.io/2017/10/15/Api-set-resolution +typedef struct _API_SET_NAMESPACE { + ULONG Version; + ULONG Size; + ULONG Flags; + ULONG Count; + ULONG EntryOffset; + ULONG HashOffset; + ULONG HashFactor; +} TYPEDEF_TYPE_NAME(API_SET_NAMESPACE); + +typedef struct _API_SET_HASH_ENTRY { + ULONG Hash; + ULONG Index; +} TYPEDEF_TYPE_NAME(API_SET_HASH_ENTRY); + +typedef struct _API_SET_NAMESPACE_ENTRY { + ULONG Flags; + ULONG NameOffset; + ULONG NameLength; + ULONG HashedLength; + ULONG ValueOffset; + ULONG ValueCount; +} TYPEDEF_TYPE_NAME(API_SET_NAMESPACE_ENTRY); + +typedef struct _API_SET_VALUE_ENTRY { + ULONG Flags; + ULONG NameOffset; + ULONG NameLength; + ULONG ValueOffset; + ULONG ValueLength; +} TYPEDEF_TYPE_NAME(API_SET_VALUE_ENTRY); + +typedef struct _PEB { + BOOLEAN InheritedAddressSpace; + BOOLEAN ReadImageFileExecOptions; + BOOLEAN BeingDebugged; + + union { + UCHAR BitField; + struct { + UCHAR ImageUsedLargePages : 1; + UCHAR IsProtectedProcess : 1; + UCHAR IsLegacyProcess : 1; + UCHAR IsImageDynamicallyRelocated : 1; + UCHAR SkipPatchingUser32Forwarders : 1; + UCHAR SpareBits0 : 2; + + // windows 10 only but we might use it for vxkex in the future + UCHAR IsLongPathAwareProcess : 1; + }; + }; + + HANDLE Mutant; + + PVOID ImageBaseAddress; + PPEB_LDR_DATA Ldr; + PRTL_USER_PROCESS_PARAMETERS ProcessParameters; + PVOID SubSystemData; + HANDLE ProcessHeap; + PRTL_CRITICAL_SECTION FastPebLock; + + PVOID AtlThunkSListPtr; + PVOID IFEOKey; + + union { + ULONG CrossProcessFlags; + struct { + ULONG ProcessInJob : 1; + ULONG ProcessInitializing : 1; + ULONG ProcessUsingVEH : 1; + ULONG ProcessUsingVCH : 1; + ULONG ProcessUsingFTH : 1; + ULONG ReservedBits0 : 27; + }; + }; + + union { + // array of function pointers for KiUserCallbackDispatcher + PVOID KernelCallbackTable; + + // UserSharedInfoPtr is only relevant when starting "protected processes". + PVOID UserSharedInfoPtr; + }; + + ULONG SystemReserved[1]; + ULONG AtlThunkSListPtr32; + + PAPI_SET_NAMESPACE ApiSetMap; + + ULONG TlsExpansionCounter; + PVOID TlsBitmap; + ULONG TlsBitmapBits[2]; + PVOID ReadOnlySharedMemoryBase; + + PVOID HotpatchInformation; + + PPVOID ReadOnlyStaticServerData; + PVOID AnsiCodePageData; + PVOID OemCodePageData; + PVOID UnicodeCaseTableData; + + ULONG NumberOfProcessors; + ULONG NtGlobalFlag; + + // I believe this block of entries is derived from the registry values located + // inside HKLM\SYSTEM\CurrentControlSet\Control\Session Manager + LARGE_INTEGER CriticalSectionTimeout; + SIZE_T HeapSegmentReserve; + SIZE_T HeapSegmentCommit; + SIZE_T HeapDeCommitTotalFreeThreshold; + SIZE_T HeapDeCommitFreeBlockThreshold; + + // Where heap manager keeps track of all heaps created for a process + // Fields initialized by MmCreatePeb. ProcessHeaps is initialized + // to point to the first free byte after the PEB and MaximumNumberOfHeaps + // is computed from the page size used to hold the PEB, less the fixed + // size of this data structure. + ULONG NumberOfHeaps; + ULONG MaximumNumberOfHeaps; + PPVOID ProcessHeaps; + + PVOID GdiSharedHandleTable; + PVOID ProcessStarterHelper; + ULONG GdiDCAttributeList; + PRTL_CRITICAL_SECTION LoaderLock; + + ULONG OSMajorVersion; + ULONG OSMinorVersion; + USHORT OSBuildNumber; + USHORT OSCSDVersion; + ULONG OSPlatformId; + ULONG ImageSubsystem; + ULONG ImageSubsystemMajorVersion; + ULONG ImageSubsystemMinorVersion; + ULONG_PTR ImageProcessAffinityMask; + GDI_HANDLE_BUFFER GdiHandleBuffer; + + // PostProcessInitRoutine is called by NTDLL after all DLL entry points are called. + // However, it is still useless, because user32.dll will overwrite it with NULL when + // its DLL entry point is called. This makes its usage very unreliable. + PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine; + + PVOID TlsExpansionBitmap; + ULONG TlsExpansionBitmapBits[32]; + ULONG SessionId; + + // See KACF_* + ULONGLONG AppCompatFlags; + ULONGLONG AppCompatFlagsUser; + + PVOID pShimData; + PVOID AppCompatInfo; + + UNICODE_STRING CSDVersion; + + PVOID ActivationContextData; + PVOID ProcessAssemblyStorageMap; + PVOID SystemDefaultActivationContextData; + PVOID SystemAssemblyStorageMap; + + SIZE_T MinimumStackCommit; + + PPVOID FlsCallback; + PVOID SparePointers[4]; + LIST_ENTRY FlsListHead; + PVOID FlsBitmap; + ULONG FlsBitmapBits[4]; + ULONG FlsHighIndex; + + PVOID WerRegistrationData; + PVOID WerShipAssetPtr; + + PVOID pContextData; + PVOID pImageHeaderHash; + + union { + ULONG TracingFlags; + struct { + ULONG HeapTracingEnabled : 1; + ULONG CritSecTracingEnabled : 1; + ULONG SpareTracingBits : 30; + }; + }; + + // + // Extending this structure to store our own data is not allowed. + // See the comment for "NumberOfHeaps" to find out why. + // +} TYPEDEF_TYPE_NAME(PEB); + +#define GDI_BATCH_BUFFER_SIZE 310 + +typedef struct _GDI_TEB_BATCH { + ULONG Offset; + ULONG_PTR HDC; + ULONG Buffer[GDI_BATCH_BUFFER_SIZE]; +} TYPEDEF_TYPE_NAME(GDI_TEB_BATCH); + +typedef struct _TEB_ACTIVE_FRAME_CONTEXT { + ULONG Flags; + PCSTR FrameName; +} TYPEDEF_TYPE_NAME(TEB_ACTIVE_FRAME_CONTEXT); + +typedef struct _TEB_ACTIVE_FRAME { + ULONG Flags; + struct _TEB_ACTIVE_FRAME *Previous; + PCTEB_ACTIVE_FRAME_CONTEXT Context; +} TYPEDEF_TYPE_NAME(TEB_ACTIVE_FRAME); + +typedef struct _TEB { + NT_TIB NtTib; + + union { + struct { + // + // KexLdrShouldRewriteDll is set if the current call stack + // includes one of the following functions: + // + // Ext_GetModuleHandleA + // Ext_GetModuleHandleW + // Ext_GetModuleHandleExA + // Ext_GetModuleHandleExW + // Ext_LoadLibraryA + // Ext_LoadLibraryW + // Ext_LoadLibraryExA + // Ext_LoadLibraryExW + // + + BOOLEAN KexLdrShouldRewriteDll : 1; + }; + + ULONG_PTR KexPerThreadData; + PVOID EnvironmentPointer; // unused + }; + + CLIENT_ID ClientId; // GetCurrentProcessId & GetCurrentThreadId + PVOID ActiveRpcHandle; // unused + PVOID ThreadLocalStoragePointer; + PPEB ProcessEnvironmentBlock; + ULONG LastErrorValue; // GetLastError & SetLastError + ULONG CountOfOwnedCriticalSections; // used by app verifier + + PVOID CsrClientThread; + PVOID Win32ThreadInfo; + ULONG User32Reserved[0x1A]; + ULONG UserReserved[5]; + PVOID WOW32Reserved; + + ULONG CurrentLocale; // GetThreadLocale & SetThreadLocale + ULONG FpSoftwareStatusRegister; // unused + + PVOID SystemReserved1[0x36]; + LONG ExceptionCode; + + // The original type of this entry is PACTIVATION_CONTEXT_STACK but it's irrelevant + // to me and there were shitloads of structures to copy so I gave up. + PVOID ActivationContextStackPointer; + + UCHAR SpareBytes[0x24]; + ULONG TxFsContext; + + GDI_TEB_BATCH GdiTebBatch; + CLIENT_ID RealClientId; + PVOID GdiCachedProcessHandle; + ULONG GdiClientPID; + ULONG GdiClientTID; + PVOID GdiThreadLocalInfo; + ULONG_PTR Win32ClientInfo[0x3E]; + + PVOID glDispatchTable[0xE9]; + ULONG_PTR glReserved1[0x1D]; + PVOID glReserved2; + PVOID glSectionInfo; + PVOID glSection; + PVOID glTable; + PVOID glCurrentRC; + PVOID glContext; + + ULONG LastStatusValue; // set by RtlNtStatusToDosError + UNICODE_STRING StaticUnicodeString; // temporary scratch buffer + WCHAR StaticUnicodeBuffer[MAX_PATH + 1]; + PVOID DeallocationStack; + PVOID TlsSlots[0x40]; + LIST_ENTRY TlsLinks; + PVOID Vdm; + PVOID ReservedForNtRpc; // rpcrt4.dll + HANDLE DbgSsReserved[2]; + + ULONG HardErrorMode; + +#ifdef _M_X64 + PVOID Instrumentation[0x0B]; +#else + PVOID Instrumentation[0x09]; +#endif + + GUID ActivityId; + PVOID SubProcessTag; + PVOID EtwLocalData; + PVOID EtwTraceData; + + PVOID WinSockData; + ULONG GdiBatchCount; + + union { + PROCESSOR_NUMBER CurrentIdealProcessor; + ULONG IdealProcessorValue; + + struct { + UCHAR ReservedPad0; + UCHAR ReservedPad1; + UCHAR ReservedPad2; + UCHAR IdealProcessor; + }; + }; + + ULONG GuaranteedStackBytes; + PVOID ReservedForPerf; + PVOID ReservedForOle; + ULONG WaitingOnLoaderLock; + + PVOID SavedPriorityState; + ULONG_PTR SoftPatchPtr1; + PVOID ThreadPoolData; + + PVOID *TlsExpansionSlots; + PVOID DeallocationBStore; + PVOID BStoreLimit; + ULONG MuiGeneration; + ULONG IsImpersonating; + PVOID NlsCache; + + PVOID pShimData; + ULONG HeapVirtualAffinity; + PVOID CurrentTransactionHandle; + PTEB_ACTIVE_FRAME ActiveFrame; + PVOID FlsData; + + PVOID PreferredLanguages; + PVOID UserPrefLanguages; + PVOID MergedPrefLanguages; + ULONG MuiImpersonation; + + union { + USHORT VOLATILE CrossTebFlags; + + struct { + USHORT SpareCrossTebBits : 16; + }; + }; + + union { + USHORT SameTebFlags; + + struct { + USHORT SafeThunkCall : 1; + USHORT InDbgPrint : 1; + USHORT HasFiberData : 1; + USHORT SkipThreadAttach : 1; + USHORT WerInShipAssertCode : 1; + USHORT RanProcessInit : 1; + USHORT ClonedThread : 1; + USHORT SuppressDbgMsg : 1; + USHORT DisableUserStackWalk : 1; + USHORT RtlExceptionAttached : 1; + USHORT InitialThread : 1; + USHORT SpareSameTebBits : 5; + }; + }; + + PVOID TxnScopeEnterCallback; + PVOID TxnScopeExitCallback; + PVOID TxnScopeContext; + ULONG LockCount; + ULONG SpareUlong0; + PVOID ResourceRetValue; +} TYPEDEF_TYPE_NAME(TEB); + +typedef struct _KSYSTEM_TIME { + ULONG LowPart; + LONG High1Time; + LONG High2Time; +} TYPEDEF_TYPE_NAME(KSYSTEM_TIME); + +// KUSER_SHARED_DATA has been checked and is 100% accurate for Windows 7, +// with SP1 and all security updates as of 30-Sep-2022. It is very likely +// to be accurate for Win7 RTM and plain SP1 as well. +// +// Also see: +// https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/api/ntexapi_x/kuser_shared_data/index.htm +typedef struct _KUSER_SHARED_DATA { + ULONG VOLATILE TickCountLowDeprecated; + ULONG TickCountMultiplier; + KSYSTEM_TIME VOLATILE InterruptTime; + KSYSTEM_TIME VOLATILE SystemTime; + KSYSTEM_TIME VOLATILE TimeZoneBias; + + USHORT ImageNumberLow; + USHORT ImageNumberHigh; + + // Contains the path of the Windows directory, e.g. L"C:\\Windows" + WCHAR NtSystemRoot[MAX_PATH]; + + // These values seem to be unused and all set to 0. + ULONG MaxStackTraceDepth; + ULONG CryptoExponent; + ULONG TimeZoneId; + ULONG LargePageMinimum; + ULONG Reserved2[6]; // actually Reserved2[7] + ULONG NtBuildNumber; // win10 only but used for vxkex + + NT_PRODUCT_TYPE NtProductType; + BOOLEAN ProductTypeIsValid; + + // Checked by CreateProcessInternalW. + ULONG NtMajorVersion; + ULONG NtMinorVersion; + + // Search for PF_* in this file + BOOLEAN ProcessorFeatures[PROCESSOR_FEATURE_MAX]; + + // these two NOT VALID FOR 64BIT since they are ULONGs. + // They are however valid for wow64 apps. + ULONG MmHighestUserAddress; + ULONG MmSystemRangeStart; + + ULONG VOLATILE TimeSlip; + ALTERNATIVE_ARCHITECTURE_TYPE AlternativeArchitecture; + ULONG AltArchitecturePad[1]; + LARGE_INTEGER SystemExpirationDate; + ULONG SuiteMask; + BOOLEAN KdDebuggerEnabled; + + // NX_SUPPORT_POLICY_* + UCHAR NXSupportPolicy; + + ULONG VOLATILE ActiveConsoleId; + ULONG VOLATILE DismountCount; + + // ComPlusPackage is the cached value initialized from the registry value + // HKLM\Software\Microsoft\.NETFramework\Enable64Bit (as DWORD). + ULONG ComPlusPackage; + + // Time in tick count for system-wide last user input across all terminal + // sessions. For MP performance, it is not updated all the time (e.g. once + // a minute per session). It is used for idle detection. + ULONG LastSystemRITEventTickCount; + + // Multiply by page size to get amount of physical memory in the computer + ULONG NumberOfPhysicalPages; + + // TRUE if system booted in safe mode + BOOLEAN SafeBootMode; + + union { + UCHAR TscQpcData; + + struct { + UCHAR TscQpcEnabled : 1; + UCHAR TscQpcSpareFlag : 1; + UCHAR TscQpcShift : 6; + }; + }; + + UCHAR TscQpcPad[2]; + + union { + ULONG SharedDataFlags; + + struct { + ULONG DbgErrorPortPresent : 1; + ULONG DbgElevationEnabled : 1; + ULONG DbgVirtEnabled : 1; + ULONG DbgInstallerDetectEnabled : 1; + ULONG DbgSystemDllRelocated : 1; + ULONG DbgDynProcessorEnabled : 1; + ULONG DbgSEHValidationEnabled : 1; + ULONG SpareBits : 25; + }; + }; + + ULONG DataFlagsPad[1]; + + ULONGLONG TestRetInstruction; + ULONG SystemCall; + ULONG SystemCallReturn; + ULONGLONG SystemCallPad[3]; + + union { + KSYSTEM_TIME VOLATILE TickCount; + ULONGLONG VOLATILE TickCountQuad; + }; + + // Cookie is used by EncodeSystemPointer and DecodeSystemPointer APIs. + // It is most likely to be a random value chosen at system boot. + ULONG Cookie; + ULONG CookiePad[1]; + + LONGLONG ConsoleSessionForegroundProcessId; + ULONG Wow64SharedInformation[0x10]; + USHORT UserModeGlobalLogger[16]; + ULONG LangGenerationCount; + ULONGLONG Reserved5; + ULONGLONG VOLATILE InterruptTimeBias; + ULONGLONG VOLATILE TscQpcBias; + ULONG VOLATILE ActiveProcessorCount; + USHORT VOLATILE ActiveGroupCount; + USHORT Reserved4; + ULONG VOLATILE AitSamplingValue; + ULONG VOLATILE AppCompatFlag; + + // The following two members are often set to zero with certain Win7 + // security updates installed, because they decrease the effectiveness + // of ASLR. Do not use these to obtain the address of NTDLL - they are + // not reliable. + ULONGLONG SystemDllNativeRelocation; + ULONG SystemDllWowRelocation; + + ULONG XStatePad[1]; + XSTATE_CONFIGURATION XState; +} TYPEDEF_TYPE_NAME(KUSER_SHARED_DATA); + +typedef struct _OBJECT_ATTRIBUTES { + ULONG Length; + HANDLE RootDirectory; + PUNICODE_STRING ObjectName; + ULONG Attributes; + PSECURITY_DESCRIPTOR SecurityDescriptor; + PSECURITY_QUALITY_OF_SERVICE SecurityQualityOfService; +} TYPEDEF_TYPE_NAME(OBJECT_ATTRIBUTES); + +#define LDR_DLL_LOADED_FLAG_RELOCATED (0x00000001) + +typedef struct _LDR_DLL_NOTIFICATION_DATA { + ULONG Flags; // always zero on win7 + PCUNICODE_STRING FullDllName; + PCUNICODE_STRING BaseDllName; + PVOID DllBase; + ULONG SizeOfImage; +} TYPEDEF_TYPE_NAME(LDR_DLL_NOTIFICATION_DATA); + +typedef struct _IO_STATUS_BLOCK { + union { + NTSTATUS Status; + PVOID Pointer; + }; + + ULONG_PTR Information; +} TYPEDEF_TYPE_NAME(IO_STATUS_BLOCK); + +typedef struct _ALPC_PORT_ATTRIBUTES +{ + ULONG Flags; + SECURITY_QUALITY_OF_SERVICE SecurityQos; + SIZE_T MaxMessageLength; + SIZE_T MemoryBandwidth; + SIZE_T MaxPoolUsage; + SIZE_T MaxSectionSize; + SIZE_T MaxViewSize; + SIZE_T MaxTotalSectionSize; + ULONG DupObjectTypes; +#ifdef _M_X64 + ULONG Reserved; +#endif +} TYPEDEF_TYPE_NAME(ALPC_PORT_ATTRIBUTES); + +typedef struct _PORT_MESSAGE +{ + union + { + struct + { + CSHORT DataLength; + CSHORT TotalLength; + } s1; + ULONG Length; + } u1; + union + { + struct + { + CSHORT Type; + CSHORT DataInfoOffset; + } s2; + ULONG ZeroInit; + } u2; + union + { + CLIENT_ID ClientId; + double DoNotUseThisField; + }; + ULONG MessageId; + union + { + SIZE_T ClientViewSize; // only valid for LPC_CONNECTION_REQUEST messages + ULONG CallbackId; // only valid for LPC_REQUEST messages + }; +} TYPEDEF_TYPE_NAME(PORT_MESSAGE); + +#if defined(USE_LPC6432) +# define LPC_CLIENT_ID CLIENT_ID64 +# define LPC_SIZE_T ULONGLONG +# define LPC_PVOID ULONGLONG +# define LPC_HANDLE ULONGLONG +#else +# define LPC_CLIENT_ID CLIENT_ID +# define LPC_SIZE_T SIZE_T +# define LPC_PVOID PVOID +# define LPC_HANDLE HANDLE +#endif + +typedef struct _PORT_VIEW { + ULONG Length; + LPC_HANDLE SectionHandle; + ULONG SectionOffset; + LPC_SIZE_T ViewSize; + LPC_PVOID ViewBase; + LPC_PVOID ViewRemoteBase; +} TYPEDEF_TYPE_NAME(PORT_VIEW); + +typedef struct _REMOTE_PORT_VIEW { + ULONG Length; + LPC_SIZE_T ViewSize; + LPC_PVOID ViewBase; +} TYPEDEF_TYPE_NAME(REMOTE_PORT_VIEW); + +typedef struct _ALPC_MESSAGE_ATTRIBUTES +{ + ULONG AllocatedAttributes; + ULONG ValidAttributes; +} TYPEDEF_TYPE_NAME(ALPC_MESSAGE_ATTRIBUTES); + +typedef enum _PS_ATTRIBUTE_NUM { + PsAttributeParentProcess, // in HANDLE + PsAttributeDebugPort, // in HANDLE + PsAttributeToken, // in HANDLE + PsAttributeClientId, // out PCLIENT_ID + PsAttributeTebAddress, // out PTEB + PsAttributeImageName, // in PWSTR + PsAttributeImageInfo, // out PSECTION_IMAGE_INFORMATION + PsAttributeMemoryReserve, // in PPS_MEMORY_RESERVE + PsAttributePriorityClass, // in UCHAR + PsAttributeErrorMode, // in ULONG + PsAttributeStdHandleInfo, // 10, in PPS_STD_HANDLE_INFO + PsAttributeHandleList, // in PHANDLE + PsAttributeGroupAffinity, // in PGROUP_AFFINITY + PsAttributePreferredNode, // in PUSHORT + PsAttributeIdealProcessor, // in PPROCESSOR_NUMBER + PsAttributeUmsThread, // see UpdateProcThreadAttributeList in msdn (CreateProcessA/W...) in PUMS_CREATE_THREAD_ATTRIBUTES + PsAttributeMitigationOptions, // in UCHAR + PsAttributeProtectionLevel, + PsAttributeSecureProcess, // since THRESHOLD (Virtual Secure Mode, Device Guard) + PsAttributeJobList, + PsAttributeMax +} PS_ATTRIBUTE_NUM; + +typedef enum _PS_CREATE_STATE { + PsCreateInitialState = 0, + PsCreateFailOnFileOpen = 1, + PsCreateFailOnSectionCreate = 2, + PsCreateFailExeFormat = 3, + PsCreateFailMachineMismatch = 4, + PsCreateFailExeName = 5, + PsCreateSuccess = 6, + PsCreateMaximumStates = 7 +} PS_CREATE_STATE; + +typedef struct _PS_CREATE_INFO { + ULONG_PTR Size; + PS_CREATE_STATE State; + + union { + struct { + union { + ULONG InitFlags; + + struct { + UCHAR WriteOutputOnExit : 1; + UCHAR DetectManifest : 1; + UCHAR SpareBits1 : 6; + UCHAR Unknown : 2; + UCHAR SpareBits2 : 6; + USHORT ProhibitedImageCharacteristics : 16; + }; + }; + + ACCESS_MASK AdditionalFileAccess; + } InitState; + + struct { + HANDLE FileHandle; + } FailSection; + + struct { + USHORT DllCharacteristics; + } ExeFormat; + + struct { + HANDLE IFEOKey; + } ExeName; + + struct { + union { + ULONG OutputFlags; + + struct { + UCHAR ProtectedProcess : 1; + UCHAR AddressSpaceOverride : 1; + UCHAR DevOverrideEnabled : 1; + UCHAR ManifestDetected : 1; + ULONG SpareBits : 28; + }; + }; + + HANDLE FileHandle; + HANDLE SectionHandle; + ULONGLONG UserProcessParametersNative; + ULONG UserProcessParametersWow64; + ULONG CurrentParameterFlags; + ULONGLONG PebAddressNative; + ULONG PebAddressWow64; + ULONGLONG ManifestAddress; + ULONG ManifestSize; + } SuccessState; + }; +} TYPEDEF_TYPE_NAME(PS_CREATE_INFO); + +typedef struct _PS_ATTRIBUTE { + ULONG Attribute; + SIZE_T Size; + ULONG_PTR Value; + PSIZE_T ReturnLength; +} TYPEDEF_TYPE_NAME(PS_ATTRIBUTE); + +typedef struct _PS_ATTRIBUTE_LIST { + SIZE_T TotalLength; + PS_ATTRIBUTE Attributes[]; +} TYPEDEF_TYPE_NAME(PS_ATTRIBUTE_LIST); + +typedef struct _SECTION_IMAGE_INFORMATION { + PVOID TransferAddress; + ULONG ZeroBits; + SIZE_T MaximumStackSize; + SIZE_T CommittedStackSize; + ULONG SubSystemType; + + union { + struct { + USHORT SubSystemMinorVersion; + USHORT SubSystemMajorVersion; + }; + + ULONG SubSystemVersion; + }; + + ULONG GpValue; + USHORT ImageCharacteristics; + USHORT DllCharacteristics; + USHORT Machine; + BOOLEAN ImageContainsCode; + + union { + UCHAR ImageFlags; + + struct { + UCHAR ComPlusNativeReady : 1; + UCHAR ComPlusILOnly : 1; + UCHAR ImageDynamicallyRelocated : 1; + UCHAR ImageMappedFlat : 1; + UCHAR Reserved : 4; + }; + }; + + ULONG LoaderFlags; + ULONG ImageFileSize; + ULONG CheckSum; +} TYPEDEF_TYPE_NAME(SECTION_IMAGE_INFORMATION); + +typedef struct _RTL_USER_PROCESS_INFORMATION { + ULONG Length; + HANDLE Process; + HANDLE Thread; + CLIENT_ID ClientId; + SECTION_IMAGE_INFORMATION ImageInformation; +} TYPEDEF_TYPE_NAME(RTL_USER_PROCESS_INFORMATION); + +typedef enum _LDR_DLL_NOTIFICATION_REASON { + LDR_DLL_NOTIFICATION_REASON_LOADED = 1, + LDR_DLL_NOTIFICATION_REASON_UNLOADED = 2 +} LDR_DLL_NOTIFICATION_REASON; + +typedef VOID (NTAPI *PLDR_DLL_NOTIFICATION_FUNCTION)( + IN LDR_DLL_NOTIFICATION_REASON NotificationReason, + IN PCLDR_DLL_NOTIFICATION_DATA NotificationData, + IN PVOID Context); + +typedef enum _EVENT_TYPE { + NotificationEvent, + SynchronizationEvent +} EVENT_TYPE; + +typedef enum _OBJECT_WAIT_TYPE { + WaitAllObject, + WaitAnyObject +} TYPEDEF_TYPE_NAME(OBJECT_WAIT_TYPE); + +typedef enum _SEMAPHORE_INFORMATION_CLASS { + SemaphoreBasicInformation +} TYPEDEF_TYPE_NAME(SEMAPHORE_INFORMATION_CLASS); + +typedef enum _FILE_INFORMATION_CLASS { + FileDirectoryInformation = 1, + FileFullDirectoryInformation, // 2 + FileBothDirectoryInformation, // 3 + FileBasicInformation, // 4 + FileStandardInformation, // 5 + FileInternalInformation, // 6 + FileEaInformation, // 7 + FileAccessInformation, // 8 + FileNameInformation, // 9 + FileRenameInformation, // 10 + FileLinkInformation, // 11 + FileNamesInformation, // 12 + FileDispositionInformation, // 13 + FilePositionInformation, // 14 + FileFullEaInformation, // 15 + FileModeInformation, // 16 + FileAlignmentInformation, // 17 + FileAllInformation, // 18 + FileAllocationInformation, // 19 + FileEndOfFileInformation, // 20 + FileAlternateNameInformation, // 21 + FileStreamInformation, // 22 + FilePipeInformation, // 23 + FilePipeLocalInformation, // 24 + FilePipeRemoteInformation, // 25 + FileMailslotQueryInformation, // 26 + FileMailslotSetInformation, // 27 + FileCompressionInformation, // 28 + FileObjectIdInformation, // 29 + FileCompletionInformation, // 30 + FileMoveClusterInformation, // 31 + FileQuotaInformation, // 32 + FileReparsePointInformation, // 33 + FileNetworkOpenInformation, // 34 + FileAttributeTagInformation, // 35 + FileTrackingInformation, // 36 + FileIdBothDirectoryInformation, // 37 + FileIdFullDirectoryInformation, // 38 + FileValidDataLengthInformation, // 39 + FileShortNameInformation, // 40 + FileIoCompletionNotificationInformation, // 41 + FileIoStatusBlockRangeInformation, // 42 + FileIoPriorityHintInformation, // 43 + FileSfioReserveInformation, // 44 + FileSfioVolumeInformation, // 45 + FileHardLinkInformation, // 46 + FileProcessIdsUsingFileInformation, // 47 + FileNormalizedNameInformation, // 48 + FileNetworkPhysicalNameInformation, // 49 + FileIdGlobalTxDirectoryInformation, // 50 + FileIsRemoteDeviceInformation, // 51 + FileUnusedInformation, // 52 + FileNumaNodeInformation, // 53 + FileStandardLinkInformation, // 54 + FileRemoteProtocolInformation, // 55 + FileMaximumInformation +} TYPEDEF_TYPE_NAME(FILE_INFORMATION_CLASS); + +// +// Using this structure (returned by NtQueryInformationFile with the file +// information class of FileProcessIdsUsingFileInformation) we can figure +// out which processes have a file open. +// This is useful for the installer. (Although there is a better, documented +// api for that, the Rm* functions in RstrtMgr.dll) and also it can tell you +// which processes have loaded a particular DLL. +// +typedef struct _FILE_PROCESS_IDS_USING_FILE_INFORMATION { + ULONG NumberOfProcessIdsInList; + ULONG_PTR ProcessIdList[]; +} TYPEDEF_TYPE_NAME(FILE_PROCESS_IDS_USING_FILE_INFORMATION); + +typedef struct _FILE_NAMES_INFORMATION { + ULONG NextEntryOffset; + ULONG FileIndex; + ULONG FileNameLength; + WCHAR FileName[]; +} TYPEDEF_TYPE_NAME(FILE_NAMES_INFORMATION); + +typedef struct _FILE_BASIC_INFORMATION { + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + ULONG FileAttributes; +} TYPEDEF_TYPE_NAME(FILE_BASIC_INFORMATION); + +typedef struct _FILE_STANDARD_INFORMATION { + LARGE_INTEGER AllocationSize; + LARGE_INTEGER EndOfFile; + ULONG NumberOfLinks; + BOOLEAN DeletePending; + BOOLEAN Directory; +} TYPEDEF_TYPE_NAME(FILE_STANDARD_INFORMATION); + +typedef struct _FILE_POSITION_INFORMATION { + LARGE_INTEGER CurrentByteOffset; +} TYPEDEF_TYPE_NAME(FILE_POSITION_INFORMATION); + +typedef struct _FILE_NETWORK_OPEN_INFORMATION { + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER AllocationSize; + LARGE_INTEGER EndOfFile; + ULONG FileAttributes; +} TYPEDEF_TYPE_NAME(FILE_NETWORK_OPEN_INFORMATION); + +typedef struct _FILE_FULL_EA_INFORMATION { + ULONG NextEntryOffset; + UCHAR Flags; + UCHAR EaNameLength; + USHORT EaValueLength; + CHAR EaName[1]; +} TYPEDEF_TYPE_NAME(FILE_FULL_EA_INFORMATION); + +typedef struct _SYSTEM_PROCESS_INFORMATION { + ULONG NextEntryOffset; + ULONG NumberOfThreads; + LARGE_INTEGER SpareLi1; + LARGE_INTEGER SpareLi2; + LARGE_INTEGER SpareLi3; + LARGE_INTEGER CreateTime; + LARGE_INTEGER UserTime; + LARGE_INTEGER KernelTime; + UNICODE_STRING ImageName; + KPRIORITY BasePriority; + HANDLE UniqueProcessId; + HANDLE InheritedFromUniqueProcessId; + ULONG HandleCount; + ULONG SessionId; + ULONG_PTR PageDirectoryBase; + SIZE_T PeakVirtualSize; + SIZE_T VirtualSize; + ULONG PageFaultCount; + SIZE_T PeakWorkingSetSize; + SIZE_T WorkingSetSize; + SIZE_T QuotaPeakPagedPoolUsage; + SIZE_T QuotaPagedPoolUsage; + SIZE_T QuotaPeakNonPagedPoolUsage; + SIZE_T QuotaNonPagedPoolUsage; + SIZE_T PagefileUsage; + SIZE_T PeakPagefileUsage; + SIZE_T PrivatePageCount; + LARGE_INTEGER ReadOperationCount; + LARGE_INTEGER WriteOperationCount; + LARGE_INTEGER OtherOperationCount; + LARGE_INTEGER ReadTransferCount; + LARGE_INTEGER WriteTransferCount; + LARGE_INTEGER OtherTransferCount; +} TYPEDEF_TYPE_NAME(SYSTEM_PROCESS_INFORMATION); + +typedef struct _SYSTEM_THREAD_INFORMATION { + LARGE_INTEGER KernelTime; + LARGE_INTEGER UserTime; + LARGE_INTEGER CreateTime; + ULONG WaitTime; + PVOID StartAddress; + CLIENT_ID ClientId; + KPRIORITY Priority; + LONG BasePriority; + ULONG ContextSwitches; + ULONG ThreadState; + ULONG WaitReason; +} TYPEDEF_TYPE_NAME(SYSTEM_THREAD_INFORMATION); + +typedef VOID (NTAPI *RTL_VERIFIER_DLL_LOAD_CALLBACK) ( + PWSTR DllName, + PVOID DllBase, + SIZE_T DllSize, + PVOID Reserved +); + +typedef VOID (NTAPI *RTL_VERIFIER_DLL_UNLOAD_CALLBACK) ( + PWSTR DllName, + PVOID DllBase, + SIZE_T DllSize, + PVOID Reserved +); + +typedef VOID (NTAPI *RTL_VERIFIER_NTDLLHEAPFREE_CALLBACK) ( + PVOID AllocationBase, + SIZE_T AllocationSize +); + +typedef struct _RTL_VERIFIER_THUNK_DESCRIPTOR { + PCHAR ThunkName; + PVOID ThunkOldAddress; + PVOID ThunkNewAddress; +} TYPEDEF_TYPE_NAME(RTL_VERIFIER_THUNK_DESCRIPTOR); + +typedef struct _RTL_VERIFIER_DLL_DESCRIPTOR { + PWCHAR DllName; + DWORD DllFlags; + PVOID DllAddress; + PRTL_VERIFIER_THUNK_DESCRIPTOR DllThunks; +} TYPEDEF_TYPE_NAME(RTL_VERIFIER_DLL_DESCRIPTOR); + +typedef struct _RTL_VERIFIER_PROVIDER_DESCRIPTOR { + // Filled by verifier provider DLL + DWORD Length; + PRTL_VERIFIER_DLL_DESCRIPTOR ProviderDlls; + RTL_VERIFIER_DLL_LOAD_CALLBACK ProviderDllLoadCallback; + RTL_VERIFIER_DLL_UNLOAD_CALLBACK ProviderDllUnloadCallback; + + // Filled by verifier engine + PWSTR VerifierImage; + DWORD VerifierFlags; + DWORD VerifierDebug; + + PVOID RtlpGetStackTraceAddress; + PVOID RtlpDebugPageHeapCreate; + PVOID RtlpDebugPageHeapDestroy; + + // Filled by verifier provider DLL + RTL_VERIFIER_NTDLLHEAPFREE_CALLBACK ProviderNtdllHeapFreeCallback; +} TYPEDEF_TYPE_NAME(RTL_VERIFIER_PROVIDER_DESCRIPTOR); + +typedef enum _KEY_INFORMATION_CLASS { + KeyBasicInformation, + KeyNodeInformation, + KeyFullInformation, + KeyNameInformation, + KeyCachedInformation, + KeyFlagsInformation, + KeyVirtualizationInformation, + KeyHandleTagsInformation, // ULONG + MaxKeyInfoClass +} KEY_INFORMATION_CLASS; + +typedef enum _KEY_VALUE_INFORMATION_CLASS { + KeyValueBasicInformation, + KeyValueFullInformation, + KeyValuePartialInformation, + KeyValueFullInformationAlign64, + KeyValuePartialInformationAlign64, + KeyValueLayerInformation, + MaxKeyValueInfoClass +} KEY_VALUE_INFORMATION_CLASS; + +typedef enum _KEY_SET_INFORMATION_CLASS { + KeyWriteTimeInformation, + KeyWow64FlagsInformation, + KeyControlFlagsInformation, + KeySetVirtualizationInformation, + KeySetDebugInformation, + KeySetHandleTagsInformation, + KeySetLayerInformation, + MaxKeySetInfoClass +} KEY_SET_INFORMATION_CLASS; + +// for KeyControlFlagsInformation +#define REG_KEY_DONT_VIRTUALIZE 2 +#define REG_KEY_DONT_SILENT_FAIL 4 +#define REG_KEY_RECURSE_FLAG 8 + +typedef struct _KEY_BASIC_INFORMATION { + LARGE_INTEGER LastWriteTime; + ULONG TitleIndex; + ULONG NameLength; + WCHAR Name[1]; +} TYPEDEF_TYPE_NAME(KEY_BASIC_INFORMATION); + +typedef struct _KEY_NODE_INFORMATION { + LARGE_INTEGER LastWriteTime; + ULONG TitleIndex; + ULONG ClassOffset; + ULONG ClassLength; + ULONG NameLength; + WCHAR Name[1]; +} TYPEDEF_TYPE_NAME(KEY_NODE_INFORMATION); + +typedef struct _KEY_FULL_INFORMATION { + LARGE_INTEGER LastWriteTime; + ULONG TitleIndex; + ULONG ClassOffset; + ULONG ClassLength; + ULONG SubKeys; + ULONG MaxNameLen; + ULONG MaxClassLen; + ULONG Values; + ULONG MaxValueNameLen; + ULONG MaxValueDataLen; + WCHAR Class[]; +} TYPEDEF_TYPE_NAME(KEY_FULL_INFORMATION); + +typedef struct _KEY_NAME_INFORMATION { + ULONG NameLength; + WCHAR Name[]; +} TYPEDEF_TYPE_NAME(KEY_NAME_INFORMATION); + +typedef struct _KEY_CACHED_INFORMATION { + LARGE_INTEGER LastWriteTime; + ULONG TitleIndex; + ULONG SubKeys; + ULONG MaxNameLen; + ULONG Values; + ULONG MaxValueNameLen; + ULONG MaxValueDataLen; + ULONG NameLength; +} TYPEDEF_TYPE_NAME(KEY_CACHED_INFORMATION); + +typedef struct _KEY_VALUE_BASIC_INFORMATION { + ULONG TitleIndex; + ULONG Type; + ULONG NameLength; + WCHAR Name[]; +} TYPEDEF_TYPE_NAME(KEY_VALUE_BASIC_INFORMATION); + +typedef struct _KEY_VALUE_FULL_INFORMATION { + ULONG TitleIndex; + ULONG Type; + ULONG DataOffset; + ULONG DataLength; + ULONG NameLength; + WCHAR NameAndData[]; +} TYPEDEF_TYPE_NAME(KEY_VALUE_FULL_INFORMATION); + +typedef struct _KEY_VALUE_PARTIAL_INFORMATION { + ULONG TitleIndex; + ULONG Type; + ULONG DataLength; + UCHAR Data[]; +} TYPEDEF_TYPE_NAME(KEY_VALUE_PARTIAL_INFORMATION); + +typedef struct _KEY_VALUE_ENTRY { + PUNICODE_STRING ValueName; + ULONG DataLength; + ULONG DataOffset; + ULONG Type; +} TYPEDEF_TYPE_NAME(KEY_VALUE_ENTRY); + +typedef enum _RTL_QUERY_REGISTRY_RELATIVE_TO { + RTL_REGISTRY_ABSOLUTE, // Path is a full path + RTL_REGISTRY_SERVICES, // \Registry\Machine\System\CurrentControlSet\Services + RTL_REGISTRY_CONTROL, // \Registry\Machine\System\CurrentControlSet\Control + RTL_REGISTRY_WINDOWS_NT, // \Registry\Machine\Software\Microsoft\Windows NT\CurrentVersion + RTL_REGISTRY_DEVICEMAP, // \Registry\Machine\Hardware\DeviceMap + RTL_REGISTRY_USER, // \Registry\User\CurrentUser + RTL_REGISTRY_MAXIMUM, + + RTL_REGISTRY_HANDLE = 0x40000000, // Low order bits are registry handle + RTL_REGISTRY_OPTIONAL = 0x80000000 // Indicates the key node is optional +} RTL_QUERY_REGISTRY_RELATIVE_TO; + +typedef NTSTATUS (NTAPI *PRTL_QUERY_REGISTRY_ROUTINE)( + IN PWSTR ValueName, + IN ULONG ValueType, + IN PVOID ValueData, + IN ULONG ValueLength, + IN PVOID Context, + IN PVOID EntryContext); + +typedef struct _RTL_QUERY_REGISTRY_TABLE { + PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine; + ULONG Flags; + PWSTR Name; + PVOID EntryContext; + ULONG DefaultType; + PVOID DefaultData; + ULONG DefaultLength; +} TYPEDEF_TYPE_NAME(RTL_QUERY_REGISTRY_TABLE); + +typedef enum _RTL_PATH_TYPE { + RtlPathTypeUnknown, + RtlPathTypeUncAbsolute, + RtlPathTypeDriveAbsolute, + RtlPathTypeDriveRelative, + RtlPathTypeRooted, + RtlPathTypeRelative, + RtlPathTypeLocalDevice, + RtlPathTypeRootLocalDevice +} RTL_PATH_TYPE; + +typedef struct _RTL_DYNAMIC_HASH_TABLE_ENTRY { + LIST_ENTRY Linkage; + ULONG_PTR Signature; +} TYPEDEF_TYPE_NAME(RTL_DYNAMIC_HASH_TABLE_ENTRY); + +typedef struct _RTL_DYNAMIC_HASH_TABLE_CONTEXT { + PLIST_ENTRY ChainHead; + PLIST_ENTRY PrevLinkage; + ULONG_PTR Signature; +} TYPEDEF_TYPE_NAME(RTL_DYNAMIC_HASH_TABLE_CONTEXT); + +typedef struct _RTL_DYNAMIC_HASH_TABLE_ENUMERATOR { + RTL_DYNAMIC_HASH_TABLE_ENTRY HashEntry; + PLIST_ENTRY ChainHead; + ULONG BucketIndex; +} TYPEDEF_TYPE_NAME(RTL_DYNAMIC_HASH_TABLE_ENUMERATOR); + +typedef struct _RTL_DYNAMIC_HASH_TABLE { + ULONG Flags; + ULONG Shift; + + ULONG TableSize; + ULONG Pivot; + ULONG DivisorMask; + + ULONG NumEntries; + ULONG NonEmptyBuckets; + ULONG NumEnumerators; + + PVOID Directory; +} TYPEDEF_TYPE_NAME(RTL_DYNAMIC_HASH_TABLE); + +typedef enum _SECTION_INHERIT { + ViewShare = 1, + ViewUnmap = 2 +} SECTION_INHERIT; + +typedef enum _SECTION_INFORMATION_CLASS { + SectionBasicInformation, + SectionImageInformation, + SectionRelocationInformation, + MaxSectionInfoClass +} SECTION_INFORMATION_CLASS; + +typedef VOID (*PKNORMAL_ROUTINE) ( + IN PVOID NormalContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2); + +typedef enum _OBJECT_INFORMATION_CLASS { + ObjectBasicInformation, // OBJECT_BASIC_INFORMATION + ObjectNameInformation, // UNICODE_STRING + ObjectTypeInformation, // OBJECT_TYPE_INFORMATION + ObjectTypesInformation, // ULONG (NumberOfTypes) + ObjectHandleFlagInformation, // OBJECT_HANDLE_FLAG_INFORMATION + ObjectSessionInformation, // none, set only, and requires SeTcbPrivilege + MaxObjectInfoClass +} OBJECT_INFORMATION_CLASS; + +typedef struct _OBJECT_BASIC_INFORMATION { + ULONG Attributes; + ACCESS_MASK GrantedAccess; + ULONG HandleCount; + ULONG PointerCount; + ULONG PagedPoolCharge; + ULONG NonPagedPoolCharge; + ULONG Reserved[3]; + ULONG NameInfoSize; + ULONG TypeInfoSize; + ULONG SecurityDescriptorSize; + LARGE_INTEGER CreationTime; +} TYPEDEF_TYPE_NAME(OBJECT_BASIC_INFORMATION); + +typedef struct _OBJECT_TYPE_INFORMATION { + UNICODE_STRING TypeName; + ULONG TotalNumberOfObjects; + ULONG TotalNumberOfHandles; + ULONG TotalPagedPoolUsage; + ULONG TotalNonPagedPoolUsage; + ULONG TotalNamePoolUsage; + ULONG TotalHandleTableUsage; + ULONG HighWaterNumberOfObjects; + ULONG HighWaterNumberOfHandles; + ULONG HighWaterPagedPoolUsage; + ULONG HighWaterNonPagedPoolUsage; + ULONG HighWaterNamePoolUsage; + ULONG HighWaterHandleTableUsage; + ULONG InvalidAttributes; + GENERIC_MAPPING GenericMapping; + ULONG ValidAccessMask; + BOOLEAN SecurityRequired; + BOOLEAN MaintainHandleCount; + ULONG PoolType; + ULONG DefaultPagedPoolCharge; + ULONG DefaultNonPagedPoolCharge; +} TYPEDEF_TYPE_NAME(OBJECT_TYPE_INFORMATION); + +typedef struct _OBJECT_HANDLE_FLAG_INFORMATION { + BOOLEAN Inherit; + BOOLEAN ProtectFromClose; +} TYPEDEF_TYPE_NAME(OBJECT_HANDLE_FLAG_INFORMATION); + +// Not the real structure, but same size +typedef struct _HEAP_ENTRY { + PVOID Data1; + PVOID Data2; +} TYPEDEF_TYPE_NAME(HEAP_ENTRY); + +typedef struct _HEAP *PHEAP; + +// This structure is not complete. +typedef struct _HEAP { + HEAP_ENTRY Entry; + ULONG SegmentSignature; + ULONG SegmentFlags; + LIST_ENTRY SegmentListEntry; + PHEAP Heap; + PVOID BaseAddress; + ULONG NumberOfPages; + PHEAP_ENTRY FirstEntry; + PHEAP_ENTRY LastValidEntry; + ULONG NumberOfUnCommittedPages; + ULONG NumberOfUnCommittedRanges; + USHORT SegmentAllocatorBackTraceIndex; + USHORT Reserved; + LIST_ENTRY UCRSegmentList; + ULONG Flags; + ULONG ForceFlags; + ULONG CompatibilityFlags; +} TYPEDEF_TYPE_NAME(HEAP); + +typedef BOOLEAN (NTAPI *PDLL_INIT_ROUTINE) ( + IN PVOID DllHandle, + IN ULONG Reason, + IN PVOID Context OPTIONAL); + +typedef VOID (NTAPI *PLDR_LOADED_MODULE_ENUMERATION_CALLBACK_FUNCTION) ( + IN PCLDR_DATA_TABLE_ENTRY DataTableEntry, + IN PVOID Context, + IN OUT PBOOLEAN StopEnumeration); + +typedef NTSTATUS (NTAPI *PUSER_THREAD_START_ROUTINE)( + IN PVOID ThreadParameter); + +typedef struct _TIME_FIELDS { + SHORT Year; // range [1601...] + SHORT Month; // range [1..12] + SHORT Day; // range [1..31] + SHORT Hour; // range [0..23] + SHORT Minute; // range [0..59] + SHORT Second; // range [0..59] + SHORT Milliseconds; // range [0..999] + SHORT Weekday; // range [0..6] == [Sunday..Saturday] +} TYPEDEF_TYPE_NAME(TIME_FIELDS); + +typedef struct _KERNEL_USER_TIMES { + LONGLONG CreateTime; + LONGLONG ExitTime; + LONGLONG KernelTime; + LONGLONG UserTime; +} TYPEDEF_TYPE_NAME(KERNEL_USER_TIMES); + +typedef struct _POOLED_USAGE_AND_LIMITS { + SIZE_T PeakPagedPoolUsage; + SIZE_T PagedPoolUsage; + SIZE_T PagedPoolLimit; + SIZE_T PeakNonPagedPoolUsage; + SIZE_T NonPagedPoolUsage; + SIZE_T NonPagedPoolLimit; + SIZE_T PeakPagefileUsage; + SIZE_T PagefileUsage; + SIZE_T PagefileLimit; +} TYPEDEF_TYPE_NAME(POOLED_USAGE_AND_LIMITS); + +typedef enum _IO_PRIORITY_HINT { + IoPriorityVeryLow, + IoPriorityLow, + IoPriorityNormal, + IoPriorityHigh, + IoPriorityCritical, + MaxIoPriorityTypes +} IO_PRIORITY_HINT; + +typedef struct _VM_COUNTERS { + SIZE_T PeakVirtualSize; + SIZE_T VirtualSize; + ULONG PageFaultCount; + SIZE_T PeakWorkingSetSize; + SIZE_T WorkingSetSize; + SIZE_T QuotaPeakPagedPoolUsage; + SIZE_T QuotaPagedPoolUsage; + SIZE_T QuotaPeakNonPagedPoolUsage; + SIZE_T QuotaNonPagedPoolUsage; + SIZE_T PagefileUsage; + SIZE_T PeakPagefileUsage; +} TYPEDEF_TYPE_NAME(VM_COUNTERS); + +typedef struct _VM_COUNTERS_EX { + SIZE_T PeakVirtualSize; + SIZE_T VirtualSize; + ULONG PageFaultCount; + SIZE_T PeakWorkingSetSize; + SIZE_T WorkingSetSize; + SIZE_T QuotaPeakPagedPoolUsage; + SIZE_T QuotaPagedPoolUsage; + SIZE_T QuotaPeakNonPagedPoolUsage; + SIZE_T QuotaNonPagedPoolUsage; + SIZE_T PagefileUsage; + SIZE_T PeakPagefileUsage; + SIZE_T PrivateUsage; +} TYPEDEF_TYPE_NAME(VM_COUNTERS_EX); + +typedef struct _PROCESS_ACCESS_TOKEN { + HANDLE Token; + HANDLE Thread; +} TYPEDEF_TYPE_NAME(PROCESS_ACCESS_TOKEN); + +typedef struct _PROCESS_LDT_INFORMATION { + ULONG Start; + ULONG Length; + LDT_ENTRY LdtEntries[1]; +} TYPEDEF_TYPE_NAME(PROCESS_LDT_INFORMATION); + +typedef struct _PROCESS_PRIORITY_CLASS { + BOOLEAN Foreground; + UCHAR PriorityClass; // PROCESS_PRIORITY_CLASS_* +} TYPEDEF_TYPE_NAME(PROCESS_PRIORITY_CLASS); + +typedef struct _PROCESS_HANDLE_INFORMATION { + ULONG HandleCount; + ULONG HighWaterHandleCount; +} TYPEDEF_TYPE_NAME(PROCESS_HANDLE_INFORMATION); + +typedef struct _PROCESS_DEVICEMAP_INFORMATION_EX { + union { + struct { + HANDLE DirectoryHandle; + } Set; + + struct { + ULONG DriveMap; + UCHAR DriveType[32]; + } Query; + }; + + ULONG Flags; +} TYPEDEF_TYPE_NAME(PROCESS_DEVICEMAP_INFORMATION_EX); + +typedef struct _PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION { + ULONG Version; + ULONG Reserved; + PVOID Callback; +} TYPEDEF_TYPE_NAME(PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION); + +typedef struct _RTL_MEMORY_ZONE_SEGMENT { + struct _RTL_MEMORY_ZONE_SEGMENT *NextSegment; + SIZE_T Size; + PVOID Next; + PVOID Limit; +} TYPEDEF_TYPE_NAME(RTL_MEMORY_ZONE_SEGMENT); + +typedef struct _RTL_MEMORY_ZONE { + RTL_MEMORY_ZONE_SEGMENT Segment; + RTL_SRWLOCK Lock; + ULONG LockCount; + PRTL_MEMORY_ZONE_SEGMENT FirstSegment; +} TYPEDEF_TYPE_NAME(RTL_MEMORY_ZONE); + +typedef struct _IMAGE_DELAYLOAD_DESCRIPTOR { + union { + DWORD AllAttributes; + + struct { + ULONG RvaBased : 1; // Delay load version 2 + ULONG ReservedAttributes : 31; + }; + } Attributes; + + ULONG DllNameRVA; // RVA to the name of the target library (NULL-terminate ASCII string) + ULONG ModuleHandleRVA; // RVA to the HMODULE caching location (PHMODULE) + ULONG ImportAddressTableRVA; // RVA to the start of the IAT (PIMAGE_THUNK_DATA) + ULONG ImportNameTableRVA; // RVA to the start of the name table (PIMAGE_THUNK_DATA::AddressOfData) + ULONG BoundImportAddressTableRVA; // RVA to an optional bound IAT + ULONG UnloadInformationTableRVA; // RVA to an optional unload info table + ULONG TimeDateStamp; // 0 if not bound, + // Otherwise, date/time of the target DLL + +} TYPEDEF_TYPE_NAME(IMAGE_DELAYLOAD_DESCRIPTOR); + +typedef struct _DELAYLOAD_PROC_DESCRIPTOR { + ULONG ImportDescribedByName; + + union { + PCSTR Name; + ULONG Ordinal; + } Description; +} TYPEDEF_TYPE_NAME(DELAYLOAD_PROC_DESCRIPTOR); + +typedef struct _DELAYLOAD_INFO { + ULONG Size; + PCIMAGE_DELAYLOAD_DESCRIPTOR DelayloadDescriptor; + PIMAGE_THUNK_DATA ThunkAddress; + PCSTR TargetDllName; + DELAYLOAD_PROC_DESCRIPTOR TargetApiDescriptor; + PVOID TargetModuleBase; + PVOID Unused; + ULONG LastError; +} TYPEDEF_TYPE_NAME(DELAYLOAD_INFO); + +#define DELAYLOAD_GPA_FAILURE 4 + +typedef PVOID (NTAPI *PDELAYLOAD_FAILURE_DLL_CALLBACK) ( + IN ULONG NotificationReason, // only value is DELAYLOAD_GPA_FAILURE - + IN PDELAYLOAD_INFO DelayloadInfo); // see delayimp.h for origin reason + +typedef PVOID (NTAPI *PDELAYLOAD_FAILURE_SYSTEM_ROUTINE) ( + IN PCSTR DllName, + IN PCSTR ProcedureName); + +typedef enum _VIRTUAL_MEMORY_INFORMATION_CLASS { + VmPrefetchInformation, + VmPagePriorityInformation, + VmCfgCallTargetInformation, + VmMaxInformationClass +} TYPEDEF_TYPE_NAME(VIRTUAL_MEMORY_INFORMATION_CLASS); + +typedef struct _RTL_BITMAP { + ULONG SizeOfBitMap; + PULONG Buffer; +} TYPEDEF_TYPE_NAME(RTL_BITMAP); + +#pragma endregion + +STATIC PKUSER_SHARED_DATA SharedUserData = (PKUSER_SHARED_DATA) 0x7FFE0000; + +#pragma region Nt* function declarations + +NTSYSCALLAPI NTSTATUS NTAPI NtQueryObject( + IN HANDLE ObjectHandle, + IN OBJECT_INFORMATION_CLASS ObjectInformationClass, + OUT PVOID ObjectInformation, + IN ULONG Length, + OUT PULONG ReturnLength OPTIONAL); + +NTSYSCALLAPI NTSTATUS NTAPI NtFlushInstructionCache( + IN HANDLE ProcessHandle, + IN PVOID BaseAddress OPTIONAL, + IN SIZE_T Length); + +NTSYSCALLAPI NTSTATUS NTAPI NtQuerySystemInformation( + IN SYSINFOCLASS SystemInformationClass, + OUT PVOID SystemInformation, + IN ULONG SystemInformationLength, + OUT PULONG ReturnLength OPTIONAL); + +NTSYSCALLAPI NTSTATUS NTAPI NtQuerySystemInformationEx( + IN SYSINFOCLASS SystemInformationClass, + IN PVOID InputBuffer, + IN ULONG InputBufferLength, + OUT PVOID SystemInformation, + IN ULONG SystemInformationLength, + OUT PULONG ReturnLength); + +NTSYSCALLAPI NTSTATUS NTAPI NtSetInformationFile( + IN HANDLE FileHandle, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN PVOID FileInformation, + IN ULONG FileInformationLength, + IN FILE_INFORMATION_CLASS FileInformationClass); + +// Handle must be opened with at least FILE_READ_ATTRIBUTES access +NTSYSCALLAPI NTSTATUS NTAPI NtQueryInformationFile( + IN HANDLE FileHandle, + OUT PIO_STATUS_BLOCK IoStatusBlock, + OUT PVOID FileInformation, + IN ULONG FileInformationLength, + IN FILE_INFORMATION_CLASS FileInformationClass); + +NTSYSCALLAPI NTSTATUS NTAPI NtQueryInformationProcess( + IN HANDLE ProcessHandle, + IN PROCESSINFOCLASS ProcessInformationClass, + OUT PVOID ProcessInformation, + IN ULONG ProcessInformationLength, + OUT PULONG ReturnLength OPTIONAL); + +NTSYSCALLAPI NTSTATUS NTAPI NtSetInformationProcess( + IN HANDLE ProcessHandle, + IN PROCESSINFOCLASS ProcessInformationClass, + IN PVOID ProcessInformation, + IN ULONG ProcessInformationLength); + +NTSYSCALLAPI NTSTATUS NTAPI NtQueryInformationThread( + IN HANDLE ThreadHandle, + IN THREADINFOCLASS ThreadInformationClass, + OUT PVOID ThreadInformation, + IN ULONG ThreadInformationLength, + OUT PULONG ReturnLength OPTIONAL); + +NTSYSCALLAPI NTSTATUS NTAPI NtSetInformationThread( + IN HANDLE ThreadHandle, + IN THREADINFOCLASS ThreadInformationClass, + IN PVOID ThreadInformation, + IN ULONG ThreadInformationLength); + +// NtGetNextProcess and NtGetNextThread do not accept any Flags. +// Flags parameters must be set to 0. +NTSYSCALLAPI NTSTATUS NTAPI NtGetNextProcess( + IN HANDLE ProcessHandle, + IN ACCESS_MASK DesiredAccess, + IN ULONG HandleAttributes, + IN ULONG Flags OPTIONAL, + OUT PHANDLE NextProcessHandle); + +NTSYSCALLAPI NTSTATUS NTAPI NtGetNextThread( + IN HANDLE ProcessHandle, + IN HANDLE ThreadHandle, + IN ACCESS_MASK DesiredAccess, + IN ULONG HandleAttributes, + IN ULONG Flags, + OUT PHANDLE NextThreadHandle); + +NTSYSCALLAPI NTSTATUS NTAPI NtSuspendProcess( + IN HANDLE ProcessHandle); + +NTSYSCALLAPI NTSTATUS NTAPI NtResumeProcess( + IN HANDLE ProcessHandle); + +NTSYSCALLAPI NTSTATUS NTAPI NtSuspendThread( + IN HANDLE ThreadHandle, + OUT PULONG PreviousSuspendCount OPTIONAL); + +NTSYSCALLAPI NTSTATUS NTAPI NtResumeThread( + IN HANDLE ThreadHandle, + IN PULONG PreviousSuspendCount OPTIONAL); + +NTSYSCALLAPI NTSTATUS NTAPI NtOpenProcess( + OUT PHANDLE ProcessHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN PCLIENT_ID ClientId OPTIONAL); + +NTSYSCALLAPI NTSTATUS NTAPI NtTerminateProcess( + IN HANDLE ProcessHandle OPTIONAL, + IN NTSTATUS ExitStatus); + +NTSYSCALLAPI NTSTATUS NTAPI NtWaitForSingleObject( + IN HANDLE Handle, + IN BOOLEAN Alertable, + IN PLARGE_INTEGER Timeout); + +NTSYSCALLAPI NTSTATUS NTAPI NtWaitForMultipleObjects( + IN ULONG ObjectCount, + IN PHANDLE ObjectArray, + IN OBJECT_WAIT_TYPE WaitType, + IN BOOLEAN Alertable, + IN PLONGLONG Timeout OPTIONAL); + +NTSYSCALLAPI NTSTATUS NTAPI NtSignalAndWaitForSingleObject( + IN HANDLE SignalHandle, + IN HANDLE WaitHandle, + IN BOOLEAN Alertable, + IN PLARGE_INTEGER Timeout); + +NTSYSCALLAPI NTSTATUS NTAPI NtClose( + IN HANDLE Handle); + +NTSYSCALLAPI NTSTATUS NTAPI NtRaiseHardError( + IN NTSTATUS ErrorStatus, + IN ULONG NumberOfParameters, + IN ULONG UnicodeStringParameterMask, + IN PULONG_PTR Parameters, + IN ULONG ValidResponseOptions, + OUT PULONG Response); + +NTSYSCALLAPI NTSTATUS NTAPI NtAllocateVirtualMemory( + IN HANDLE ProcessHandle, + IN OUT PVOID *BaseAddress, + IN ULONG_PTR ZeroBits, + IN OUT PSIZE_T RegionSize, + IN ULONG AllocationType, + IN ULONG Protect); + +NTSYSCALLAPI NTSTATUS NTAPI NtFreeVirtualMemory( + IN HANDLE ProcessHandle, + IN OUT PVOID *BaseAddress, + IN OUT PSIZE_T RegionSize, + IN ULONG FreeType); + +NTSYSCALLAPI NTSTATUS NTAPI NtUnmapViewOfSection( + IN HANDLE ProcessHandle, + IN PVOID BaseAddress OPTIONAL); + +NTSYSCALLAPI NTSTATUS NTAPI NtQueryVirtualMemory( + IN HANDLE ProcessHandle, + IN PVOID BaseAddress OPTIONAL, + IN MEMINFOCLASS MemoryInformationClass, + OUT PVOID MemoryInformation, + IN SIZE_T MemoryInformationLength, + OUT PSIZE_T ReturnLength OPTIONAL); + +NTSYSCALLAPI NTSTATUS NTAPI NtProtectVirtualMemory( + IN HANDLE ProcessHandle, + IN OUT PPVOID BaseAddress, + IN OUT PSIZE_T RegionSize, + IN ULONG NewProtect, + OUT PULONG OldProtect); + +NTSYSCALLAPI NTSTATUS NTAPI NtReadVirtualMemory( + IN HANDLE ProcessHandle, + IN PVOID BaseAddress, + OUT PVOID Buffer, + IN SIZE_T BufferSize, + OUT PSIZE_T NumberOfBytesRead OPTIONAL); + +NTSYSCALLAPI NTSTATUS NTAPI NtWriteVirtualMemory( + IN HANDLE ProcessHandle, + IN PVOID BaseAddress, + IN PCVOID Buffer, + IN SIZE_T BufferSize, + OUT PSIZE_T NumberOfBytesWritten OPTIONAL); + +NTSYSCALLAPI NTSTATUS NTAPI NtFlushVirtualMemory( + IN HANDLE ProcessHandle, + IN OUT PPVOID BaseAddress, + IN OUT PSIZE_T RegionSize, + OUT PIO_STATUS_BLOCK IoStatusBlock); + +// Please note: The DefaultTimeout parameter is marked as optional +// in some NT5 source code, but it appears to be REQUIRED in most +// cases. If you are getting STATUS_INVALID_PARAMETER from this +// system call, pass DefaultTimeout and it will usually fix the +// problem. +NTSYSCALLAPI NTSTATUS NTAPI NtCreateNamedPipeFile( + OUT PHANDLE FileHandle, + IN ULONG DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN ULONG ShareAccess, + IN ULONG CreateDisposition, + IN ULONG CreateOptions, + IN ULONG NamedPipeType, + IN ULONG ReadMode, + IN ULONG CompletionMode, + IN ULONG MaximumInstances, + IN ULONG InboundQuota, + IN ULONG OutboundQuota, + IN PLONGLONG DefaultTimeout OPTIONAL); + +NTSYSCALLAPI NTSTATUS NTAPI NtCreateEvent( + OUT PHANDLE EventHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, + IN EVENT_TYPE EventType, + IN BOOLEAN InitialState); + +NTSYSCALLAPI NTSTATUS NTAPI NtSetEvent( + IN HANDLE EventHandle, + OUT PLONG PreviousState OPTIONAL); + +NTSYSCALLAPI NTSTATUS NTAPI NtCreateSemaphore( + OUT PHANDLE SemaphoreHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, + IN LONG InitialCount, + IN LONG MaximumCount); + +NTSYSCALLAPI NTSTATUS NTAPI NtOpenSemaphore( + OUT PHANDLE SemaphoreHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes); + +NTSYSCALLAPI NTSTATUS NTAPI NtQuerySemaphore( + IN HANDLE SemaphoreHandle, + IN SEMAPHORE_INFORMATION_CLASS SemaphoreInformationClass, + OUT PVOID SemaphoreInformation, + IN ULONG SemaphoreInformationLength, + OUT PULONG ReturnLength OPTIONAL); + +NTSYSCALLAPI NTSTATUS NTAPI NtReleaseSemaphore( + IN HANDLE SemaphoreHandle, + IN LONG ReleaseCount, + OUT PLONG PreviousCount OPTIONAL); + +typedef VOID (NTAPI *PIO_APC_ROUTINE) ( + IN PVOID ApcContext, + IN PIO_STATUS_BLOCK IoStatusBlock, + IN ULONG Reserved); + +NTSYSCALLAPI NTSTATUS NTAPI NtOpenFile( + OUT PHANDLE FileHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN ULONG ShareAccess, + IN ULONG OpenOptions); + +NTSYSCALLAPI NTSTATUS NTAPI NtCreateFile( + OUT PHANDLE FileHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN PLONGLONG AllocationSize OPTIONAL, + IN ULONG FileAttributes, + IN ULONG ShareAccess, + IN ULONG CreateDisposition, + IN ULONG CreateOptions, + IN PVOID EaBuffer, + IN ULONG EaLength); + +NTSYSCALLAPI NTSTATUS NTAPI NtReadFile( + IN HANDLE FileHandle, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + OUT PVOID Buffer, + IN ULONG Length, + IN PLONGLONG ByteOffset OPTIONAL, + IN PULONG Key OPTIONAL); + +NTSYSCALLAPI NTSTATUS NTAPI NtWriteFile( + IN HANDLE FileHandle, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN PVOID Buffer, + IN ULONG Length, + IN PLONGLONG ByteOffset OPTIONAL, + IN PULONG Key OPTIONAL); + +NTSYSCALLAPI NTSTATUS NTAPI NtFsControlFile( + IN HANDLE FileHandle, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN ULONG FsControlCode, + IN PVOID InputBuffer OPTIONAL, + IN ULONG InputBufferLength, + OUT PVOID OutputBuffer OPTIONAL, + IN ULONG OutputBufferLength); + +NTSYSCALLAPI NTSTATUS NTAPI NtDeviceIoControlFile( + IN HANDLE FileHandle, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN ULONG IoControlCode, + IN PVOID InputBuffer OPTIONAL, + IN ULONG InputBufferLength, + OUT PVOID OutputBuffer OPTIONAL, + IN ULONG OutputBufferLength); + +NTSYSCALLAPI NTSTATUS NTAPI NtAlpcCreatePort( + OUT PHANDLE PortHandle, + IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, + IN PALPC_PORT_ATTRIBUTES PortAttributes OPTIONAL); + +NTSYSCALLAPI NTSTATUS NTAPI NtAlpcSendWaitReceivePort( + IN HANDLE PortHandle, + IN ULONG Flags, + IN PPORT_MESSAGE SendMessage OPTIONAL, + IN OUT PALPC_MESSAGE_ATTRIBUTES SendMessageAttributes OPTIONAL, + OUT PPORT_MESSAGE ReceiveMessage OPTIONAL, + IN OUT PSIZE_T BufferLength OPTIONAL, + IN OUT PALPC_MESSAGE_ATTRIBUTES ReceiveMessageAttributes OPTIONAL, + IN PLARGE_INTEGER Timeout OPTIONAL); + +NTSYSCALLAPI NTSTATUS NTAPI NtAlpcAcceptConnectPort( + OUT PHANDLE PortHandle, + IN HANDLE ConnectionPortHandle, + IN ULONG Flags, + IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, + IN PALPC_PORT_ATTRIBUTES PortAttributes OPTIONAL, + IN PVOID PortContext OPTIONAL, + IN PPORT_MESSAGE ConnectionRequest, + IN OUT PALPC_MESSAGE_ATTRIBUTES ConnectionMessageAttributes OPTIONAL, + IN BOOLEAN AcceptConnection); + +NTSYSCALLAPI NTSTATUS NTAPI NtAlpcConnectPort( + OUT PHANDLE PortHandle, + IN PUNICODE_STRING PortName, + IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, + IN PALPC_PORT_ATTRIBUTES PortAttributes OPTIONAL, + IN ULONG Flags, + IN PSID RequiredServerSid OPTIONAL, + IN OUT PPORT_MESSAGE ConnectionMessage OPTIONAL, + IN OUT PULONG BufferLength OPTIONAL, + IN OUT PALPC_MESSAGE_ATTRIBUTES OutMessageAttributes OPTIONAL, + IN OUT PALPC_MESSAGE_ATTRIBUTES InMessageAttributes OPTIONAL, + IN PLARGE_INTEGER Timeout OPTIONAL); + +NTSYSCALLAPI NTSTATUS NTAPI NtCreatePort( + OUT PHANDLE PortHandle, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN ULONG MaxConnectionInfoLength, + IN ULONG MaxMessageLength, + IN ULONG MaxPoolUsage OPTIONAL); + +NTSYSCALLAPI NTSTATUS NTAPI NtListenPort( + IN HANDLE PortHandle, + OUT PPORT_MESSAGE ConnectionRequest); + +NTSYSCALLAPI NTSTATUS NTAPI NtConnectPort( + OUT PHANDLE PortHandle, + IN PUNICODE_STRING PortName, + IN PSECURITY_QUALITY_OF_SERVICE SecurityQos, + IN OUT PPORT_VIEW ClientView OPTIONAL, + IN OUT PREMOTE_PORT_VIEW ServerView OPTIONAL, + OUT PULONG MaxMessageLength OPTIONAL, + IN OUT PVOID ConnectionInformation OPTIONAL, + IN OUT PULONG ConnectionInformationLength OPTIONAL); + +NTSYSCALLAPI NTSTATUS NTAPI NtAcceptConnectPort( + OUT PHANDLE PortHandle, + IN PVOID PortContext OPTIONAL, + IN PPORT_MESSAGE ConnectionRequest, + IN BOOLEAN AcceptConnection, + IN OUT PPORT_VIEW ServerView OPTIONAL, + OUT PREMOTE_PORT_VIEW ClientView OPTIONAL); + +NTSYSCALLAPI NTSTATUS NTAPI NtCompleteConnectPort( + IN HANDLE PortHandle); + +NTSYSCALLAPI NTSTATUS NTAPI NtReplyPort( + IN HANDLE PortHandle, + IN PPORT_MESSAGE ReplyMessage); + +NTSYSCALLAPI NTSTATUS NTAPI NtReplyWaitReceivePort( + IN HANDLE PortHandle, + OUT PPVOID PortContext OPTIONAL, + IN PPORT_MESSAGE ReplyMessage OPTIONAL, + OUT PPORT_MESSAGE ReceiveMessage); + +NTSYSCALLAPI NTSTATUS NTAPI NtReplyWaitReceivePortEx( + IN HANDLE PortHandle, + OUT PPVOID PortContext OPTIONAL, + IN PPORT_MESSAGE ReplyMessage OPTIONAL, + OUT PPORT_MESSAGE ReceiveMessage, + IN PLARGE_INTEGER Timeout OPTIONAL); + +NTSYSCALLAPI NTSTATUS NTAPI NtReplyWaitReplyPort( + IN HANDLE PortHandle, + IN OUT PPORT_MESSAGE ReplyMessage); + +NTSYSCALLAPI NTSTATUS NTAPI NtRequestPort( + IN HANDLE PortHandle, + IN PPORT_MESSAGE RequestMessage); + +NTSYSCALLAPI NTSTATUS NTAPI NtRequestWaitReplyPort( + IN HANDLE PortHandle, + IN PPORT_MESSAGE RequestMessage, + IN PPORT_MESSAGE ReplyMessage); + +NTSYSCALLAPI NTSTATUS NTAPI NtReadRequestData( + IN HANDLE PortHandle, + IN PPORT_MESSAGE Message, + IN ULONG DataEntryIndex, + OUT PVOID Buffer, + IN SIZE_T BufferSize, + OUT PSIZE_T NumberOfBytesRead OPTIONAL); + +NTSYSCALLAPI NTSTATUS NTAPI NtWriteRequestData( + IN HANDLE PortHandle, + IN PPORT_MESSAGE Message, + IN ULONG DataEntryIndex, + IN PVOID Buffer, + IN SIZE_T BufferSize, + OUT PSIZE_T NumberOfBytesWritten OPTIONAL); + +NTSYSCALLAPI NTSTATUS NTAPI NtCreateUserProcess( + OUT PHANDLE ProcessHandle, + OUT PHANDLE ThreadHandle, + IN ACCESS_MASK ProcessDesiredAccess, + IN ACCESS_MASK ThreadDesiredAccess, + IN POBJECT_ATTRIBUTES ProcessObjectAttributes OPTIONAL, + IN POBJECT_ATTRIBUTES ThreadObjectAttributes OPTIONAL, + IN ULONG ProcessFlags, + IN ULONG ThreadFlags, + IN PRTL_USER_PROCESS_PARAMETERS ProcessParameters, + IN OUT PPS_CREATE_INFO CreateInfo, + IN PPS_ATTRIBUTE_LIST AttributeList OPTIONAL); + +NTSYSCALLAPI NTSTATUS NTAPI NtCreateThreadEx( + OUT PHANDLE ThreadHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN HANDLE ProcessHandle, + IN PUSER_THREAD_START_ROUTINE StartRoutine, + IN PVOID Parameter, + IN ULONG CreateFlags, + IN SIZE_T StackZeroBits, + IN SIZE_T StackSize, + IN SIZE_T MaximumStackSize, + IN OUT PPS_ATTRIBUTE_LIST AttributeList OPTIONAL); + +NTSYSCALLAPI NTSTATUS NTAPI NtDelayExecution( + IN BOOLEAN Alertable, + IN PLONGLONG DelayInterval); + +NTSYSCALLAPI NTSTATUS NTAPI NtCreateTransaction( + OUT PHANDLE TransactionHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, + IN LPGUID Uow OPTIONAL, + IN HANDLE TmHandle OPTIONAL, + IN ULONG CreateOptions OPTIONAL, + IN ULONG IsolationLevel OPTIONAL, // reserved must be 0 + IN ULONG IsolationFlags OPTIONAL, // reserved must be 0 + IN PLONGLONG Timeout OPTIONAL, + IN PUNICODE_STRING Description OPTIONAL); + +NTSYSCALLAPI NTSTATUS NTAPI NtCommitTransaction( + IN HANDLE TransactionHandle, + IN BOOLEAN Synchronous); + +NTSYSCALLAPI NTSTATUS NTAPI NtRollbackTransaction( + IN HANDLE TransactionHandle, + IN BOOLEAN Synchronous); + +NTSYSCALLAPI NTSTATUS NTAPI NtCreateKey( + OUT PHANDLE KeyHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN ULONG TitleIndex, + IN PUNICODE_STRING Class OPTIONAL, + IN ULONG CreateOptions, + OUT PULONG Disposition OPTIONAL); + +NTSYSCALLAPI NTSTATUS NTAPI NtDeleteKey( + IN HANDLE KeyHandle); + +NTSYSCALLAPI NTSTATUS NTAPI NtDeleteValueKey( + IN HANDLE KeyHandle, + IN PUNICODE_STRING ValueName); + +NTSYSCALLAPI NTSTATUS NTAPI NtEnumerateKey( + IN HANDLE KeyHandle, + IN ULONG Index, + IN KEY_INFORMATION_CLASS KeyInformationClass, + OUT PVOID KeyInformation, + IN ULONG Length, + OUT PULONG ResultLength); + +NTSYSCALLAPI NTSTATUS NTAPI NtEnumerateValueKey( + IN HANDLE KeyHandle, + IN ULONG Index, + IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, + OUT PVOID KeyValueInformation, + IN ULONG Length, + OUT PULONG ResultLength); + +NTSYSCALLAPI NTSTATUS NTAPI NtFlushKey( + IN HANDLE KeyHandle); + +NTSYSCALLAPI NTSTATUS NTAPI NtNotifyChangeKey( + IN HANDLE KeyHandle, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN ULONG CompletionFilter, + IN BOOLEAN WatchTree, + OUT PVOID Buffer OPTIONAL, + IN ULONG BufferSize, + IN BOOLEAN Asynchronous); + +NTSYSCALLAPI NTSTATUS NTAPI NtNotifyChangeMultipleKeys( + IN HANDLE MasterKeyHandle, + IN ULONG Count OPTIONAL, + IN OBJECT_ATTRIBUTES SlaveObjects[] OPTIONAL, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN ULONG CompletionFilter, + IN BOOLEAN WatchTree, + OUT PVOID Buffer OPTIONAL, + IN ULONG BufferSize, + IN BOOLEAN Asynchronous); + +NTSYSCALLAPI NTSTATUS NTAPI NtOpenKey( + OUT PHANDLE KeyHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes); + +// OpenOptions is the same as CreateOptions from NtCreateKey. +// OpenOptions can be one, none or both of the following: +// REG_OPTION_OPEN_LINK +// REG_OPTION_BACKUP_RESTORE +// Other values are invalid. +NTSYSCALLAPI NTSTATUS NTAPI NtOpenKeyEx( + OUT PHANDLE KeyHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN ULONG OpenOptions); + +NTSYSCALLAPI NTSTATUS NTAPI NtOpenKeyTransacted( + OUT PHANDLE KeyHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN HANDLE TransactionHandle); + +NTSYSCALLAPI NTSTATUS NTAPI NtOpenKeyTransactedEx( + OUT PHANDLE KeyHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN ULONG OpenOptions, + IN HANDLE TransactionHandle); + +NTSYSCALLAPI NTSTATUS NTAPI NtQueryKey( + IN HANDLE KeyHandle, + IN KEY_INFORMATION_CLASS KeyInformationClass, + OUT PVOID KeyInformation, + IN ULONG Length, + OUT PULONG ResultLength); + +NTSYSCALLAPI NTSTATUS NTAPI NtQueryValueKey( + IN HANDLE KeyHandle, + IN PCUNICODE_STRING ValueName, + IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, + OUT PVOID KeyValueInformation, + IN ULONG Length, + OUT PULONG ResultLength); + +NTSYSCALLAPI NTSTATUS NTAPI NtRestoreKey( + IN HANDLE KeyHandle, + IN HANDLE FileHandle, + IN ULONG Flags); + +NTSYSCALLAPI NTSTATUS NTAPI NtSaveKey( + IN HANDLE KeyHandle, + IN HANDLE FileHandle); + +NTSYSCALLAPI NTSTATUS NTAPI NtSaveKeyEx( + IN HANDLE KeyHandle, + IN HANDLE FileHandle, + IN ULONG Format); + +NTSYSCALLAPI NTSTATUS NTAPI NtSaveMergedKeys( + IN HANDLE HighPrecedenceKeyHandle, + IN HANDLE LowPrecedenceKeyHandle, + IN HANDLE FileHandle); + +NTSYSCALLAPI NTSTATUS NTAPI NtSetValueKey( + IN HANDLE KeyHandle, + IN PUNICODE_STRING ValueName, + IN ULONG TitleIndex OPTIONAL, + IN ULONG Type, + IN PVOID Data OPTIONAL, + IN ULONG DataSize); + +NTSYSCALLAPI NTSTATUS NTAPI NtLoadKey( + IN POBJECT_ATTRIBUTES TargetKey, + IN POBJECT_ATTRIBUTES SourceFile); + +NTSYSCALLAPI NTSTATUS NTAPI NtLoadKey2( + IN POBJECT_ATTRIBUTES TargetKey, + IN POBJECT_ATTRIBUTES SourceFile, + IN ULONG Flags); + +NTSYSCALLAPI NTSTATUS NTAPI NtLoadKeyEx( + IN POBJECT_ATTRIBUTES TargetKey, + IN POBJECT_ATTRIBUTES SourceFile, + IN ULONG Flags, + IN HANDLE TrustClassKey OPTIONAL); + +NTSYSCALLAPI NTSTATUS NTAPI NtUnloadKey( + IN POBJECT_ATTRIBUTES TargetKey); + +NTSYSCALLAPI NTSTATUS NTAPI NtUnloadKey2( + IN POBJECT_ATTRIBUTES TargetKey, + IN ULONG Flags); + +NTSYSCALLAPI NTSTATUS NTAPI NtUnloadKeyEx( + IN POBJECT_ATTRIBUTES TargetKey, + IN HANDLE Event OPTIONAL); + +NTSYSCALLAPI NTSTATUS NTAPI NtSetInformationKey( + IN HANDLE KeyHandle, + IN KEY_SET_INFORMATION_CLASS KeySetInformationClass, + IN PVOID KeySetInformation, + IN ULONG KeySetInformationLength); + +NTSYSCALLAPI NTSTATUS NTAPI NtReplaceKey( + IN POBJECT_ATTRIBUTES NewFile, + IN HANDLE TargetHandle, + IN POBJECT_ATTRIBUTES OldFile); + +NTSYSCALLAPI NTSTATUS NTAPI NtQueryMultipleValueKey( + IN HANDLE KeyHandle, + IN OUT PKEY_VALUE_ENTRY ValueEntries, + IN ULONG EntryCount, + OUT PVOID ValueBuffer, + IN OUT PULONG BufferLength, + OUT PULONG RequiredBufferLength OPTIONAL); + +NTSYSCALLAPI NTSTATUS NTAPI NtQueryOpenSubKeys( + IN POBJECT_ATTRIBUTES TargetKey, + OUT PULONG HandleCount); + +NTSYSCALLAPI NTSTATUS NTAPI NtQueryOpenSubKeysEx( + IN POBJECT_ATTRIBUTES TargetKey, + IN ULONG BufferLength, + OUT PVOID Buffer, + OUT PULONG RequiredSize); + +NTSYSCALLAPI NTSTATUS NTAPI NtRenameKey( + IN HANDLE KeyHandle, + IN PUNICODE_STRING NewName); + +NTSYSCALLAPI NTSTATUS NTAPI NtCompactKeys( + IN ULONG Count, + IN HANDLE KeyArray[]); + +NTSYSCALLAPI NTSTATUS NTAPI NtCompressKey( + IN HANDLE Key); + +NTSYSCALLAPI NTSTATUS NTAPI NtOpenSection( + OUT PHANDLE SectionHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes); + +NTSYSCALLAPI NTSTATUS NTAPI NtCreateSection( + OUT PHANDLE SectionHandle, + IN ULONG DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, + IN PLONGLONG MaximumSize OPTIONAL, + IN ULONG PageAttributes, + IN ULONG SectionAttributes, + IN HANDLE FileHandle OPTIONAL); + +NTSYSCALLAPI NTSTATUS NTAPI NtQuerySection( + IN HANDLE SectionHandle, + IN SECTION_INFORMATION_CLASS SectionInformationClass, + OUT PVOID SectionInformation, + IN SIZE_T SectionInformationLength, + OUT PSIZE_T ReturnLength OPTIONAL); + +NTSYSCALLAPI NTSTATUS NTAPI NtExtendSection( + IN HANDLE SectionHandle, + IN PLONGLONG NewSectionSize); + +NTSYSCALLAPI NTSTATUS NTAPI NtMapViewOfSection( + IN HANDLE SectionHandle, + IN HANDLE ProcessHandle, + IN OUT PPVOID BaseAddress OPTIONAL, + IN ULONG ZeroBits OPTIONAL, + IN SIZE_T CommitSize, + IN OUT PLONGLONG SectionOffset OPTIONAL, + IN OUT PSIZE_T ViewSize, + IN SECTION_INHERIT InheritDisposition, + IN ULONG AllocationType, + IN ULONG MemoryProtection); + +NTSYSCALLAPI NTSTATUS NTAPI NtUnmapViewOfSection( + IN HANDLE ProcessHandle, + IN PVOID BaseAddress); + +NTSYSCALLAPI NTSTATUS NTAPI NtQueueApcThread( + IN HANDLE ThreadHandle, + IN PKNORMAL_ROUTINE ApcRoutine, + IN PVOID NormalContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2); + +NTSYSCALLAPI NTSTATUS NTAPI NtAlertThread( + IN HANDLE ThreadHandle); + +NTSYSCALLAPI NTSTATUS NTAPI NtQuerySystemTime( + OUT PLONGLONG SystemTime); + +NTSYSCALLAPI NTSTATUS NTAPI NtQueryDirectoryFile( + IN HANDLE DirectoryHandle, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + OUT PVOID FileInformation, + IN ULONG FileInformationLength, + IN FILE_INFORMATION_CLASS FileInformationClass, + IN BOOLEAN ReturnSingleEntry, + IN PUNICODE_STRING FileName OPTIONAL, + IN BOOLEAN RestartScan); + +NTSYSCALLAPI NTSTATUS NTAPI NtCreateEvent( + OUT PHANDLE EventHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, + IN EVENT_TYPE EventType, + IN BOOLEAN InitialState); + +NTSYSCALLAPI NTSTATUS NTAPI NtDisplayString( + IN PCUNICODE_STRING String); + +NTSYSCALLAPI NTSTATUS NTAPI NtOpenProcessToken( + IN HANDLE ProcessHandle, + IN ACCESS_MASK DesiredAccess, + OUT PHANDLE TokenHandle); + +NTSYSCALLAPI NTSTATUS NTAPI NtOpenProcessTokenEx( + IN HANDLE ProcessHandle, + IN ACCESS_MASK DesiredAccess, + IN ULONG HandleAttributes, + OUT PHANDLE TokenHandle); + +NTSYSCALLAPI NTSTATUS NTAPI NtOpenThreadToken( + IN HANDLE ThreadHandle, + IN ACCESS_MASK DesiredAccess, + IN BOOLEAN OpenAsSelf, + OUT PHANDLE TokenHandle); + +NTSYSCALLAPI NTSTATUS NTAPI NtOpenThreadTokenEx( + IN HANDLE ThreadHandle, + IN ACCESS_MASK DesiredAccess, + IN BOOLEAN OpenAsSelf, + IN ULONG HandleAttributes, + OUT PHANDLE TokenHandle); + +NTSYSCALLAPI NTSTATUS NTAPI NtQueryInformationToken( + IN HANDLE TokenHandle, + IN TOKEN_INFORMATION_CLASS TokenInformationClass, + OUT PVOID TokenInformation, + IN ULONG TokenInformationLength, + OUT PULONG ReturnLength); + +NTSYSCALLAPI NTSTATUS NTAPI NtPowerInformation( + IN POWER_INFORMATION_LEVEL InformationLevel, + IN PVOID InputBuffer OPTIONAL, + IN ULONG InputBufferLength, + OUT PVOID OutputBuffer OPTIONAL, + IN ULONG OutputBufferLength); + +NTSYSCALLAPI NTSTATUS NTAPI NtCreateDirectoryObject( + OUT PHANDLE DirectoryHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes); + +NTSYSCALLAPI NTSTATUS NTAPI NtOpenDirectoryObject( + OUT PHANDLE DirectoryHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes); + +NTSYSCALLAPI NTSTATUS NTAPI NtSetSecurityObject( + IN HANDLE Handle, + IN SECURITY_INFORMATION SecurityInformation, + IN PSECURITY_DESCRIPTOR SecurityDescriptor); + +NTSYSCALLAPI NTSTATUS NTAPI NtQuerySecurityObject( + IN HANDLE Handle, + IN SECURITY_INFORMATION SecurityInformation, + OUT PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL, + IN ULONG Length, + OUT PULONG LengthNeeded); + +NTSYSCALLAPI NTSTATUS NTAPI NtDuplicateObject( + IN HANDLE SourceProcessHandle, + IN HANDLE SourceHandle, + IN HANDLE TargetProcessHandle OPTIONAL, + OUT PHANDLE TargetHandle, + IN ACCESS_MASK DesiredAccess, + IN ULONG HandleAttributes, + IN ULONG Options); + +NTSYSCALLAPI NTSTATUS NTAPI NtOpenThread( + OUT PHANDLE ThreadHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN PCLIENT_ID ClientId); + +NTSYSCALLAPI NTSTATUS NTAPI NtQueryAttributesFile( + IN POBJECT_ATTRIBUTES ObjectAttributes, + OUT PFILE_BASIC_INFORMATION FileInformation); + +NTSYSCALLAPI NTSTATUS NTAPI NtQueryFullAttributesFile( + IN POBJECT_ATTRIBUTES ObjectAttributes, + OUT PFILE_NETWORK_OPEN_INFORMATION FileInformation); + +NTSYSCALLAPI NTSTATUS NTAPI NtAssignProcessToJobObject( + IN HANDLE JobHandle, + IN HANDLE ProcessHandle); + +#pragma endregion + +#pragma region Nt* function declarations (not in Windows 7) + +NTSYSCALLAPI NTSTATUS NTAPI NtSetInformationVirtualMemory( + IN HANDLE ProcessHandle, + IN VIRTUAL_MEMORY_INFORMATION_CLASS VmInformationClass, + IN ULONG_PTR NumberOfEntries, + IN PMEMORY_RANGE_ENTRY VirtualAddresses, + IN PVOID VmInformation, + IN ULONG VmInformationLength); + +#pragma endregion + +#pragma region NtWow64* function declarations + +typedef NTSTATUS (NTAPI *NT_WOW64_WRITE_VIRTUAL_MEMORY64) ( + IN HANDLE ProcessHandle, + IN PVOID64 BaseAddress, + IN PCVOID Buffer, + IN ULONGLONG BufferSize, + OUT PSIZE_T NumberOfBytesWritten OPTIONAL); + +typedef NTSTATUS (NTAPI *NT_WOW64_READ_VIRTUAL_MEMORY64) ( + IN HANDLE ProcessHandle, + IN PVOID64 BaseAddress, + OUT PVOID Buffer, + IN ULONGLONG BufferSize, + OUT PULONGLONG NumberOfBytesRead OPTIONAL); + +typedef NTSTATUS (NTAPI *NT_WOW64_QUERY_INFORMATION_PROCESS64) ( + IN HANDLE ProcessHandle, + IN PROCESSINFOCLASS ProcessInformationClass, + OUT PVOID ProcessInformation64, + IN ULONG ProcessInformationLength, + OUT PULONG ReturnLength OPTIONAL); + +#pragma endregion + +#pragma region Rtl* function declarations +NTSYSAPI NTSTATUS NTAPI RtlCreateProcessParameters( + OUT PRTL_USER_PROCESS_PARAMETERS *pProcessParameters, + IN PUNICODE_STRING ImagePathName, + IN PUNICODE_STRING DllPath OPTIONAL, + IN PUNICODE_STRING CurrentDirectory OPTIONAL, + IN PUNICODE_STRING CommandLine OPTIONAL, + IN PVOID Environment OPTIONAL, + IN PUNICODE_STRING WindowTitle OPTIONAL, + IN PUNICODE_STRING DesktopInfo OPTIONAL, + IN PUNICODE_STRING ShellInfo OPTIONAL, + IN PUNICODE_STRING RuntimeData OPTIONAL); + +NTSYSAPI NTSTATUS NTAPI RtlCreateUserProcess( + IN PUNICODE_STRING NtImagePathName, + IN ULONG Attributes, + IN PRTL_USER_PROCESS_PARAMETERS ProcessParameters, + IN PSECURITY_DESCRIPTOR ProcessSecurityDescriptor OPTIONAL, + IN PSECURITY_DESCRIPTOR ThreadSecurityDescriptor OPTIONAL, + IN HANDLE ParentProcess OPTIONAL, + IN BOOLEAN InheritHandles, + IN HANDLE DebugPort OPTIONAL, + IN HANDLE ExceptionPort OPTIONAL, + OUT PRTL_USER_PROCESS_INFORMATION ProcessInformation); + +NTSYSAPI NTSTATUS NTAPI RtlCreateProcessParametersEx( + OUT PRTL_USER_PROCESS_PARAMETERS *ProcessParameters, + IN PUNICODE_STRING ImagePathName, + IN PUNICODE_STRING DllPath OPTIONAL, + IN PUNICODE_STRING CurrentDirectory OPTIONAL, + IN PUNICODE_STRING CommandLine OPTIONAL, + IN PVOID Environment OPTIONAL, + IN PUNICODE_STRING WindowTitle OPTIONAL, + IN PUNICODE_STRING DesktopInfo OPTIONAL, + IN PUNICODE_STRING ShellInfo OPTIONAL, + IN PUNICODE_STRING RuntimeData OPTIONAL, + IN ULONG Flags); + +NTSYSAPI NTSTATUS NTAPI RtlDestroyProcessParameters( + IN PRTL_USER_PROCESS_PARAMETERS ProcessParameters); + +NTSYSAPI NTSTATUS NTAPI RtlCreateUserThread( + IN HANDLE Process, + IN PSECURITY_DESCRIPTOR ThreadSecurityDescriptor OPTIONAL, + IN BOOLEAN CreateSuspended, + IN ULONG ZeroBits OPTIONAL, + IN SIZE_T MaximumStackSize OPTIONAL, + IN SIZE_T CommittedStackSize OPTIONAL, + IN PUSER_THREAD_START_ROUTINE StartAddress, + IN PVOID Parameter OPTIONAL, + OUT PHANDLE Thread OPTIONAL, + OUT PCLIENT_ID ClientId OPTIONAL); + +NTSYSAPI NORETURN VOID NTAPI RtlExitUserThread( + IN NTSTATUS ExitStatus); + +NTSYSAPI NORETURN VOID NTAPI RtlExitUserProcess( + IN NTSTATUS ExitStatus); + +NTSYSAPI VOID NTAPI RtlAcquirePebLock( + VOID); + +NTSYSAPI VOID NTAPI RtlReleasePebLock( + VOID); + +NTSYSAPI ULONG NTAPI RtlNtStatusToDosError( + IN NTSTATUS Status); + +NTSYSAPI ULONG NTAPI RtlNtStatusToDosErrorNoTeb( + IN NTSTATUS Status); + +NTSYSAPI VOID NTAPI RtlSetLastWin32Error( + IN LONG Win32Error); + +NTSYSAPI VOID NTAPI RtlInitAnsiString( + OUT PANSI_STRING DestinationString, + IN PCSTR SourceString OPTIONAL); + +NTSYSAPI VOID NTAPI RtlInitUnicodeString( + OUT PUNICODE_STRING DestinationString, + IN PCWSTR SourceString OPTIONAL); + +NTSYSAPI NTSTATUS NTAPI RtlInitAnsiStringEx( + OUT PANSI_STRING DestinationString, + IN PCSTR SourceString OPTIONAL); + +NTSYSAPI NTSTATUS NTAPI RtlInitUnicodeStringEx( + OUT PUNICODE_STRING DestinationString, + IN PCWSTR SourceString OPTIONAL); + +NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString( + OUT PUNICODE_STRING DestinationString, + IN PCANSI_STRING SourceString, + IN BOOLEAN AllocateDestinationString); + +NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeStringFromAsciiz( + OUT PUNICODE_STRING DestinationString, + IN PCSTR SourceString OPTIONAL); + +NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString( + OUT PUNICODE_STRING DestinationString, + IN PCWSTR SourceString); + +NTSYSAPI NTSTATUS NTAPI RtlUpcaseUnicodeString( + OUT PUNICODE_STRING DestinationString, + IN PCUNICODE_STRING SourceString, + IN BOOLEAN AllocateDestinationString); + +NTSYSAPI NTSTATUS NTAPI RtlDowncaseUnicodeString( + OUT PUNICODE_STRING DestinationString, + IN PCUNICODE_STRING SourceString, + IN BOOLEAN AllocateDestinationString); + +NTSYSAPI VOID NTAPI RtlFreeUnicodeString( + IN OUT PUNICODE_STRING UnicodeString); + +NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString( + IN PCUNICODE_STRING String1, + IN PCUNICODE_STRING String2, + IN BOOLEAN CaseInsensitive); + +NTSYSAPI LONG NTAPI RtlCompareUnicodeString( + IN PCUNICODE_STRING String1, + IN PCUNICODE_STRING String2, + IN BOOLEAN CaseInsensitive); + +NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString( + IN PCUNICODE_STRING Prefix, + IN PCUNICODE_STRING String, + IN BOOLEAN CaseInsensitive); + +NTSYSAPI VOID NTAPI RtlCopyString( + OUT PANSI_STRING DestinationString, + IN PCANSI_STRING SourceString OPTIONAL); + +#define RtlCopyAnsiString RtlCopyString + +NTSYSAPI VOID NTAPI RtlCopyUnicodeString( + OUT PUNICODE_STRING DestinationString, + IN PCUNICODE_STRING SourceString OPTIONAL); + +NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeToString( + IN PUNICODE_STRING DestinationString, + IN PCWSTR SourceString OPTIONAL); + +NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString( + IN OUT PUNICODE_STRING DestinationString, + IN PCUNICODE_STRING SourceString); + +NTSYSAPI NTSTATUS NTAPI RtlHashUnicodeString( + IN PCUNICODE_STRING String, + IN BOOLEAN CaseInsensitive, + IN ULONG HashAlgorithm, + OUT PULONG HashValue); + +NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString( + OUT PANSI_STRING DestinationString, + IN PCUNICODE_STRING SourceString, + IN BOOLEAN AllocateDestinationString); + +NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString( + OUT PUNICODE_STRING DestinationString, + IN PCANSI_STRING SourceString, + IN BOOLEAN AllocateDestinationString); + +NTSYSAPI NTSTATUS NTAPI RtlIntegerToUnicodeString( + IN ULONG Value, + IN ULONG Base OPTIONAL, + IN OUT PUNICODE_STRING String); + +NTSYSAPI NTSTATUS NTAPI RtlInt64ToUnicodeString( + IN ULONGLONG Value, + IN ULONG Base, + IN OUT PUNICODE_STRING String); + +NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToInteger( + IN PCUNICODE_STRING String, + IN ULONG Base OPTIONAL, + OUT PULONG Value); + +// Flags can be RTL_FIND_CHAR_IN_UNICODE_STRING_* +NTSYSAPI NTSTATUS NTAPI RtlFindCharInUnicodeString( + IN ULONG Flags, + IN PCUNICODE_STRING StringToSearch, + IN PCUNICODE_STRING CharSet, + OUT PUSHORT NonInclusivePrefixLength); + +NTSYSAPI PVOID NTAPI RtlAllocateHeap( + IN PVOID HeapHandle, + IN ULONG Flags OPTIONAL, + IN SIZE_T Size); + +NTSYSAPI PVOID NTAPI RtlReAllocateHeap( + IN PVOID HeapHAndle, + IN ULONG Flags OPTIONAL, + IN PVOID BaseAddress OPTIONAL, + IN SIZE_T Size); + +NTSYSAPI BOOLEAN NTAPI RtlFreeHeap( + IN PVOID HeapHandle, + IN ULONG Flags OPTIONAL, + IN PVOID BaseAddress OPTIONAL); + +NTSYSAPI SIZE_T NTAPI RtlCompactHeap( + IN PVOID HeapHandle, + IN ULONG Flags); + +NTSYSAPI NTSTATUS NTAPI RtlCreateEnvironment( + IN BOOLEAN CloneCurrentEnvironment, + OUT PVOID *Environment); + +NTSYSAPI NTSTATUS NTAPI RtlDestroyEnvironment( + IN PVOID Environment); + +NTSYSAPI NTSTATUS NTAPI RtlSetCurrentEnvironment( + IN PVOID Environment, + OUT PVOID *PreviousEnvironment OPTIONAL); + +NTSYSAPI NTSTATUS NTAPI RtlQueryEnvironmentVariable_U( + IN PVOID Environment OPTIONAL, + IN PCUNICODE_STRING Name, + IN OUT PUNICODE_STRING Value); + +NTSYSAPI NTSTATUS NTAPI RtlSetEnvironmentVariable( + IN OUT PVOID *Environment OPTIONAL, + IN PCUNICODE_STRING Name, + IN PCUNICODE_STRING Value OPTIONAL); + +NTSYSAPI NTSTATUS NTAPI RtlSetEnvironmentStrings( + IN PWCHAR NewEnvironment, + IN SIZE_T NewEnvironmentSize); + +NTSYSAPI NTSTATUS NTAPI RtlInitializeCriticalSection( + IN PRTL_CRITICAL_SECTION CriticalSection); + +NTSYSAPI NTSTATUS NTAPI RtlInitializeCriticalSectionAndSpinCount( + IN PRTL_CRITICAL_SECTION CriticalSection, + IN ULONG SpinCount); + +NTSYSAPI NTSTATUS NTAPI RtlInitializeCriticalSectionEx( + IN PRTL_CRITICAL_SECTION CriticalSection, + IN ULONG SpinCount, + IN ULONG Flags); // RTL_CRITICAL_SECTION_FLAG_ + +NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection( + IN PRTL_CRITICAL_SECTION CriticalSection); + +NTSYSAPI BOOLEAN NTAPI RtlTryEnterCriticalSection( + IN PRTL_CRITICAL_SECTION CriticalSection); + +NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection( + IN PRTL_CRITICAL_SECTION CriticalSection); + +NTSYSAPI NTSTATUS NTAPI RtlDeleteCriticalSection( + IN PRTL_CRITICAL_SECTION CriticalSection); + +// Note: This is exactly identical to zeroing the memory of the SRW lock. +// If running on Windows 7 only, no need to call this function. +#define RtlInitializeSRWLock(SRWLock) (SRWLock)->Ptr = NULL +#define InitializeSRWLock RtlInitializeSRWLock +//NTSYSAPI VOID NTAPI RtlInitializeSRWLock( +// OUT PRTL_SRWLOCK SRWLock); + +NTSYSAPI VOID NTAPI RtlAcquireSRWLockExclusive( + IN OUT PRTL_SRWLOCK SRWLock); + +NTSYSAPI VOID NTAPI RtlAcquireSRWLockShared( + IN OUT PRTL_SRWLOCK SRWLock); + +NTSYSAPI VOID NTAPI RtlReleaseSRWLockExclusive( + IN OUT PRTL_SRWLOCK SRWLock); + +NTSYSAPI VOID NTAPI RtlReleaseSRWLockShared( + IN OUT PRTL_SRWLOCK SRWLock); + +NTSYSAPI BOOLEAN NTAPI RtlTryAcquireSRWLockExclusive( + IN OUT PRTL_SRWLOCK SRWLock); + +NTSYSAPI BOOLEAN NTAPI RtlTryAcquireSRWLockShared( + IN OUT PRTL_SRWLOCK SRWLock); + +NTSYSAPI NTSTATUS NTAPI RtlGetLengthWithoutLastFullDosOrNtPathElement( + IN ULONG Flags, + IN PCUNICODE_STRING Path, + OUT PULONG CchLengthOut); + +NTSYSAPI NTSTATUS NTAPI RtlQueryRegistryValues( + IN RTL_QUERY_REGISTRY_RELATIVE_TO RelativeTo, + IN PCWSTR Path, + IN PRTL_QUERY_REGISTRY_TABLE QueryTable, + IN PVOID Context OPTIONAL, + IN PVOID Environment OPTIONAL); + +NTSYSAPI PIMAGE_NT_HEADERS NTAPI RtlImageNtHeader( + IN PVOID ImageBaseAddress); + +// ViewSize is only optional when Flags & RTL_IMAGE_NT_HEADER_EX_FLAG_NO_RANGE_CHECK. +NTSYSAPI NTSTATUS NTAPI RtlImageNtHeaderEx( + IN ULONG Flags, + IN PVOID ImageBaseAddress, + IN ULONG64 ViewSize OPTIONAL, + OUT PIMAGE_NT_HEADERS *NtHeadersOut); + +NTSYSAPI PVOID NTAPI RtlImageDirectoryEntryToData( + IN PVOID ImageBaseAddress, + IN BOOLEAN MappedAsImage, + IN USHORT DirectoryEntry, + OUT PULONG Size); + +NTSYSAPI ULONG NTAPI RtlRandom( + IN OUT PULONG Seed); + +NTSYSAPI ULONG NTAPI RtlRandomEx( + IN OUT PULONG Seed); + +NTSYSAPI RTL_PATH_TYPE NTAPI RtlDetermineDosPathNameType_U( + IN PCWSTR String); + +NTSYSAPI RTL_PATH_TYPE NTAPI RtlDetermineDosPathNameType_Ustr( + IN PCUNICODE_STRING String); + +#define RtlDetermineDosPathNameType RtlDetermineDosPathNameType_Ustr + +// May be useful: +// https://googleprojectzero.blogspot.com/2016/02/the-definitive-guide-on-win32-to-nt.html +// Notes on the following 4 APIs: +// The NtFileName output parameter will fill the Buffer member of the UNICODE_STRING +// with a pointer that points to memory newly allocated from the RtlProcessHeap. +// As such, when you are done with it, you should use RtlFreeUnicodeString on the +// *NtFileName parameter. + +NTSYSAPI BOOLEAN NTAPI RtlDosPathNameToRelativeNtPathName_U( + IN PCWSTR DosFileName, + OUT PUNICODE_STRING NtFileName, + OUT PPWSTR FilePart OPTIONAL, + OUT PRTL_RELATIVE_NAME_U RelativeName OPTIONAL); + +NTSYSAPI NTSTATUS NTAPI RtlDosPathNameToRelativeNtPathName_U_WithStatus( + IN PCWSTR DosFileName, + OUT PUNICODE_STRING NtFileName, + OUT PPWSTR FilePart OPTIONAL, + OUT PRTL_RELATIVE_NAME_U RelativeName OPTIONAL); + +NTSYSAPI BOOLEAN NTAPI RtlDosPathNameToNtPathName_U( + IN PCWSTR DosFileName, + OUT PUNICODE_STRING NtFileName, + OUT PPWSTR FilePart OPTIONAL, + OUT PRTL_RELATIVE_NAME_U RelativeName OPTIONAL); + +NTSYSAPI NTSTATUS NTAPI RtlDosPathNameToNtPathName_U_WithStatus( + IN PCWSTR DosFileName, + OUT PUNICODE_STRING NtFileName, + OUT PPWSTR FilePart OPTIONAL, + OUT PRTL_RELATIVE_NAME_U RelativeName OPTIONAL); + +NTSYSAPI BOOLEAN NTAPI RtlCreateHashTable( + IN OUT PRTL_DYNAMIC_HASH_TABLE *HashTable, + IN ULONG Shift OPTIONAL, + IN ULONG Flags OPTIONAL); + +NTSYSAPI BOOLEAN NTAPI RtlDeleteHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable); + +NTSYSAPI BOOLEAN NTAPI RtlInsertEntryHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable, + IN PRTL_DYNAMIC_HASH_TABLE_ENTRY Entry, + IN ULONG_PTR Signature, + IN OUT PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context OPTIONAL); + +NTSYSAPI BOOLEAN NTAPI RtlRemoveEntryHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable, + IN PRTL_DYNAMIC_HASH_TABLE_ENTRY Entry, + IN OUT PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context OPTIONAL); + +NTSYSAPI PRTL_DYNAMIC_HASH_TABLE_ENTRY NTAPI RtlLookupEntryHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable, + IN ULONG_PTR Signature, + OUT PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context OPTIONAL); + +NTSYSAPI PRTL_DYNAMIC_HASH_TABLE_ENTRY NTAPI RtlGetNextEntryHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable, + IN PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context); + +NTSYSAPI BOOLEAN NTAPI RtlInitEnumerationHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable, + OUT PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator); + +NTSYSAPI PRTL_DYNAMIC_HASH_TABLE_ENTRY NTAPI RtlEnumerateEntryHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable, + IN OUT PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator); + +NTSYSAPI VOID NTAPI RtlEndEnumerationHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable, + IN OUT PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator); + +NTSYSAPI BOOLEAN NTAPI RtlInitWeakEnumerationHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable, + OUT PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator); + +NTSYSAPI PRTL_DYNAMIC_HASH_TABLE_ENTRY NTAPI RtlWeaklyEnumerateEntryHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable, + IN OUT PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator); + +NTSYSAPI VOID NTAPI RtlEndWeakEnumerationHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable, + IN OUT PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator); + +NTSYSAPI BOOLEAN NTAPI RtlExpandHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable); + +NTSYSAPI BOOLEAN NTAPI RtlContractHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable); + +NTSYSAPI VOID NTAPI RtlApplicationVerifierStop( + IN ULONG_PTR Code, + IN PCHAR Message, + IN ULONG_PTR Param1, + IN PCHAR Description1, + IN ULONG_PTR Param2, + IN PCHAR Description2, + IN ULONG_PTR Param3, + IN PCHAR Description3, + IN ULONG_PTR Param4, + IN PCHAR Description4); + +NTSYSAPI VOID NTAPI RtlGetNtVersionNumbers( + OUT PULONG MajorVersion OPTIONAL, + OUT PULONG MinorVersion OPTIONAL, + OUT PULONG BuildNumber OPTIONAL); + +NTSYSAPI VOID NTAPI RtlRaiseStatus( + IN NTSTATUS Status); + +NTSYSAPI BOOLEAN NTAPI RtlSetCurrentTransaction( + IN HANDLE TransactionHandle); + +NTSYSAPI HANDLE NTAPI RtlGetCurrentTransaction( + VOID); + +NTSYSAPI VOID NTAPI RtlTimeToTimeFields( + IN PLONGLONG Time, + IN PTIME_FIELDS TimeFields); + +#define RtlSetCurrentDirectory RtlSetCurrentDirectory_U +NTSYSAPI NTSTATUS NTAPI RtlSetCurrentDirectory_U( + IN PCUNICODE_STRING Path); + +NTSYSAPI NTSTATUS NTAPI RtlOpenCurrentUser( + IN ULONG DesiredAccess, + OUT PHANDLE CurrentUserKey); + +#define RtlExpandEnvironmentStrings RtlExpandEnvironmentStrings_U +NTSYSAPI NTSTATUS NTAPI RtlExpandEnvironmentStrings_U( + IN PVOID Environment OPTIONAL, + IN PCUNICODE_STRING Source, + OUT PUNICODE_STRING Destination, + OUT PULONG ReturnedLength OPTIONAL); + +// +// I don't know what any of these MemoryZone APIs are supposed to be used for. +// I just saw them, decompiled them and wrote their prototypes here. +// + +NTSYSAPI NTSTATUS NTAPI RtlCreateMemoryZone( + OUT PRTL_MEMORY_ZONE *MemoryZone, + IN SIZE_T InitialSize, + IN ULONG Flags); // no valid flags - set to 0 + +NTSYSAPI NTSTATUS NTAPI RtlDestroyMemoryZone( + IN PRTL_MEMORY_ZONE MemoryZone); + +NTSYSAPI NTSTATUS NTAPI RtlResetMemoryZone( + IN PRTL_MEMORY_ZONE MemoryZone); + +NTSYSAPI NTSTATUS NTAPI RtlLockMemoryZone( + IN PRTL_MEMORY_ZONE MemoryZone); + +NTSYSAPI NTSTATUS NTAPI RtlUnlockMemoryZone( + IN PRTL_MEMORY_ZONE MemoryZone); + +NTSYSAPI NTSTATUS NTAPI RtlAllocateMemoryZone( + IN PRTL_MEMORY_ZONE MemoryZone, + IN SIZE_T BlockSize, + OUT PVOID Block); + +NTSYSAPI NTSTATUS NTAPI RtlExtendMemoryZone( + IN PRTL_MEMORY_ZONE MemoryZone, + IN SIZE_T Increment); + +// +// These thread profiling functions are more or less documented in their +// Win32 forms, e.g. EnableThreadProfiling. +// + +NTSYSAPI NTSTATUS NTAPI RtlEnableThreadProfiling( + IN HANDLE ThreadHandle, + IN ULONG Flags, + IN ULONGLONG HardwareCounters, + OUT PPVOID PerformanceDataHandle); + +NTSYSAPI NTSTATUS NTAPI RtlDisableThreadProfiling( + IN PVOID PerformanceDataHandle); + +NTSYSAPI NTSTATUS NTAPI RtlQueryThreadProfiling( + IN HANDLE ThreadHandle, + OUT PBOOLEAN Enabled); + +NTSYSAPI NTSTATUS NTAPI RtlReadThreadProfilingData( + IN PVOID PerformanceDataHandle, + IN ULONG Flags, + OUT PPERFORMANCE_DATA Data); + +// +// This function supports the typical * and ? wildcards. +// +NTSYSAPI BOOLEAN NTAPI RtlIsNameInExpression( + IN PCUNICODE_STRING Expression, + IN PCUNICODE_STRING Name, + IN BOOLEAN IgnoreCase, + IN PWCHAR UpcaseTable OPTIONAL); + +NTSYSAPI NTSTATUS NTAPI RtlSetProcessIsCritical( + IN BOOLEAN NewValue, + OUT PBOOLEAN OldValue OPTIONAL, + IN BOOLEAN CheckFlag); + +NTSYSAPI NTSTATUS NTAPI RtlSetThreadIsCritical( + IN BOOLEAN NewValue, + OUT PBOOLEAN OldValue OPTIONAL, + IN BOOLEAN CheckFlag); + +typedef NTSTATUS (NTAPI *PRTL_ENUM_HEAPS_CALLBACK_ROUTINE) ( + IN PVOID HeapHandle, + IN PVOID CallbackContext); + +NTSYSAPI NTSTATUS NTAPI RtlEnumProcessHeaps( + IN PRTL_ENUM_HEAPS_CALLBACK_ROUTINE EnumRoutine, + IN PVOID CallbackContext OPTIONAL); + +NTSYSAPI PVOID NTAPI RtlCreateHeap( + IN ULONG Flags, + IN PVOID HeapBase OPTIONAL, + IN SIZE_T ReserveSize, + IN SIZE_T CommitSize, + IN PVOID Lock OPTIONAL, + IN PVOID Parameters OPTIONAL); + +NTSYSAPI PVOID NTAPI RtlDestroyHeap( + IN PVOID HeapHandle); + +NTSYSAPI NTSTATUS NTAPI RtlVerifyVersionInfo( + IN PRTL_OSVERSIONINFOEXW VersionInfo, + IN ULONG TypeMask, + IN ULONGLONG ConditionMask); + +NTSYSAPI NTSTATUS NTAPI RtlGetVersion( + OUT PRTL_OSVERSIONINFOEXW VersionInfo); + +NTSYSAPI BOOLEAN NTAPI RtlGetNtProductType( + OUT PNT_PRODUCT_TYPE ProductType); + +NTSYSAPI NTSTATUS NTAPI RtlCreateAcl( + OUT PACL Acl, + IN ULONG AclLength, + IN ULONG AclRevision); + +NTSYSAPI NTSTATUS NTAPI RtlAddMandatoryAce( + IN OUT PACL Acl, + IN ULONG Revision, + IN ULONG Flags, + IN PSID LabelSid, + IN UCHAR AceType, + IN ULONG AccessMask); + +NTSYSAPI NTSTATUS NTAPI RtlCreateSecurityDescriptor( + OUT PSECURITY_DESCRIPTOR SecurityDescriptor, + IN ULONG Revision); + +NTSYSAPI NTSTATUS NTAPI RtlSetDaclSecurityDescriptor( + IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, + IN BOOLEAN DaclPresent, + IN PACL Dacl OPTIONAL, + IN BOOLEAN DaclDefaulted); + +NTSYSAPI NTSTATUS NTAPI RtlSetSaclSecurityDescriptor( + IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, + IN BOOLEAN SaclPresent, + IN PACL Sacl OPTIONAL, + IN BOOLEAN SaclDefaulted); + +#ifdef _M_X64 +NTSYSAPI BOOLEAN NTAPI RtlAddFunctionTable( + IN PRUNTIME_FUNCTION FunctionTable, + IN ULONG EntryCount, + IN ULONGLONG BaseAddress); +#endif + +#pragma endregion + +#pragma region Ldr* function declarations +NTSYSAPI NTSTATUS NTAPI LdrRegisterDllNotification( + IN ULONG Flags, // Unused. Must be zero. + IN PLDR_DLL_NOTIFICATION_FUNCTION NotificationFunction, // function called when any DLL is loaded/unloaded + IN PVOID Context OPTIONAL, // opaque data passed to the notification function + OUT PVOID *Cookie); // Store a opaque cookie which you can pass to unregister + +NTSYSAPI NTSTATUS NTAPI LdrUnregisterDllNotification( + IN PVOID Cookie); + +NTSYSAPI NTSTATUS NTAPI LdrLockLoaderLock( + IN ULONG Flags, + OUT PULONG Disposition OPTIONAL, + OUT PPVOID Cookie); + +NTSYSAPI NTSTATUS NTAPI LdrUnlockLoaderLock( + IN ULONG Flags, + IN PVOID Cookie); + +// internally known as RtlQueryImageFileKeyOption. +// https://www.geoffchappell.com/studies/windows/win32/ntdll/api/rtl/rtlexec/queryimagefilekeyoption.htm +NTSYSAPI NTSTATUS NTAPI LdrQueryImageFileKeyOption( + IN HANDLE KeyHandle, + IN PCWSTR Option, + IN ULONG Type, + OUT PVOID Buffer OPTIONAL, + IN ULONG BufferCb, + OUT PULONG BufferCbOut OPTIONAL); + +// https://www.geoffchappell.com/studies/windows/win32/ntdll/api/ldrinit/queryimagefileexecutionoptions.htm +NTSYSAPI NTSTATUS NTAPI LdrQueryImageFileExecutionOptions( + IN PUNICODE_STRING ImagePathName OPTIONAL, + IN PCWSTR OptionName, + IN ULONG Type, + OUT PVOID Buffer, + IN ULONG BufferSize, + OUT PULONG ResultSize); + +// +// The flags in *DllCharacteristics that I know of are: +// IMAGE_FILE_EXECUTABLE_IMAGE +// Does the same thing as DONT_RESOLVE_DLL_REFERENCES from LoadLibrary. +// IMAGE_FILE_SYSTEM +// Same thing as LOAD_IGNORE_CODE_AUTHZ_LEVEL from LoadLibrary +// +// There could be more, and these descriptions could be wrong. Do more research +// if you intend to use these flags. +// + +NTSYSAPI NTSTATUS NTAPI LdrLoadDll( + IN PCWSTR DllPath OPTIONAL, + IN PULONG DllCharacteristics OPTIONAL, + IN PCUNICODE_STRING DllName, + OUT PPVOID DllHandle); + +NTSYSAPI NTSTATUS NTAPI LdrUnloadDll( + IN PVOID DllHandle); + +NTSYSAPI NTSTATUS NTAPI LdrGetDllHandle( + IN PCWSTR DllPath OPTIONAL, + IN PULONG DllCharacteristics OPTIONAL, + IN PCUNICODE_STRING DllName, + OUT PPVOID DllHandle); + +NTSYSAPI NTSTATUS NTAPI LdrGetDllHandleEx( + IN ULONG Flags, // LDR_GET_DLL_HANDLE_EX_* + IN PCWSTR DllPath OPTIONAL, + IN PULONG DllCharacteristics OPTIONAL, + IN PCUNICODE_STRING DllName, + OUT PPVOID DllHandle OPTIONAL); // only optional with LDR_GET_DLL_HANDLE_EX_PIN + +// LdrGetDllHandleByName is better than LdrGetDllHandle for internal use. +// The prior two functions do a lot of extra bullshit that you probably don't need. +// +// NB: It is faster to search for a DLL by its base name rather than its full name, +// since the base names are hashed and stored in a hash table. If you use a full +// name then Ldr needs to search the entire loaded module list. +NTSYSAPI NTSTATUS NTAPI LdrGetDllHandleByName( + IN PUNICODE_STRING DllBaseName OPTIONAL, // one or the other must be specified + IN PUNICODE_STRING DllFullName OPTIONAL, + OUT PPVOID DllHandle); + +// This function is quite strange and I can't think of a good +// reason to use it. If you are thinking about using it, I strongly +// recommend you to decompile it and look at what it does exactly, +// since the nuances of its operation are too long to explain here. +NTSYSAPI NTSTATUS NTAPI LdrGetDllHandleByMapping( + IN PVOID ViewBase, + OUT PPVOID DllHandle); + +NTSYSAPI NTSTATUS NTAPI LdrDisableThreadCalloutsForDll( + IN PVOID DllHandle); + +NTSYSAPI NTSTATUS NTAPI LdrGetProcedureAddress( + IN PVOID DllHandle, + IN PCANSI_STRING ProcedureName OPTIONAL, + IN ULONG ProcedureNumber OPTIONAL, + OUT PPVOID ProcedureAddress); + +NTSYSAPI NTSTATUS NTAPI LdrGetProcedureAddressEx( + IN PVOID DllHandle, + IN PCANSI_STRING ProcedureName OPTIONAL, + IN ULONG ProcedureNumber OPTIONAL, + OUT PPVOID ProcedureAddress, + IN ULONG Flags); // Takes a flag value of 0 or 1 only. Don't know what it does. + +NTSYSAPI NTSTATUS NTAPI LdrFindEntryForAddress( + IN PVOID Address, + OUT PPLDR_DATA_TABLE_ENTRY TableEntry); + +NTSYSAPI VOID NTAPI LdrShutdownThread( + VOID); + +NTSYSAPI VOID NTAPI LdrShutdownProcess( + VOID); + +NTSYSAPI NTSTATUS NTAPI LdrOpenImageFileOptionsKey( + IN PCUNICODE_STRING ImageFileName, + IN BOOLEAN Wow64, // no effect - just set to FALSE + OUT PHANDLE KeyHandle); + +NTSYSAPI NTSTATUS NTAPI LdrEnumerateLoadedModules( + IN ULONG Flags, + IN PLDR_LOADED_MODULE_ENUMERATION_CALLBACK_FUNCTION CallbackFunction, + IN PVOID Context OPTIONAL); + +// +// Non-Exported Functions - Must manually find, or reimplement. +// + +BOOLEAN NTAPI LdrpFindLoadedDllByHandle( + IN PVOID DllHandle, + OUT PPLDR_DATA_TABLE_ENTRY DataTableEntry); + +PLDR_DATA_TABLE_ENTRY NTAPI LdrpAllocateDataTableEntry( + IN PVOID DllBase); + +#pragma endregion + +#pragma region Dbg* function declarations +NTSYSAPI NTSTATUS NTAPI DbgUiConnectToDbg( + VOID); + +NTSYSAPI NTSTATUS NTAPI DbgUiDebugActiveProcess( + IN HANDLE ProcessHandle); + +NTSYSAPI ULONG NTAPI DbgPrint( + IN PCSTR Format, + IN ...); + +NTSYSAPI ULONG NTAPI DbgPrintEx( + IN ULONG ComponentId, + IN ULONG Level, + IN PCSTR Format, + IN ...); +#pragma endregion + +#pragma region Function-like Macros + +#define WELL_FORMED_UNICODE_STRING(s) ((s) != NULL && !((s)->Length & 1) && !((s)->MaximumLength & 1) && ((s)->Length <= (s)->MaximumLength)) +#define VALID_UNICODE_STRING(s) (WELL_FORMED_UNICODE_STRING(s) && (s)->Buffer != NULL && (s)->MaximumLength != 0) + +// example: UNICODE_STRING Name = RTL_CONSTANT_STRING(L"\\??\\pipe\\Something"); +#define RTL_CONSTANT_STRING(s) { sizeof( s ) - sizeof( (s)[0] ), sizeof( s ), s } + +// This macro is compatible with RtlInitUnicodeString when you are initializing +// a UNICODE_STRING using a string literal. +// Initializing local variables at declaration is forbidden by VxKex coding style, +// so use this macro instead of RTL_CONSTANT_STRING whenever possible. +#define RtlInitConstantUnicodeString(UnicodeString, StringLiteral) do { \ + (UnicodeString)->Length = sizeof(StringLiteral) - sizeof((StringLiteral)[0]); \ + (UnicodeString)->MaximumLength = sizeof(StringLiteral); \ + (UnicodeString)->Buffer = StringLiteral; \ +} while(0) +#define RtlInitConstantAnsiString RtlInitConstantUnicodeString + +#define DECLARE_CONST_UNICODE_STRING(_variablename, _string) \ + const WCHAR _variablename ## _buffer[] = _string; \ + const UNICODE_STRING _variablename = { sizeof(_string) - sizeof(WCHAR), sizeof(_string), (PWSTR) _variablename ## _buffer }; + +#define DECLARE_GLOBAL_CONST_UNICODE_STRING(_variablename, _string) \ + DECLSPEC_SELECTANY extern UNICODE_STRING CONST _variablename = RTL_CONSTANT_STRING(_string) + +#define ARGUMENT_PRESENT(Argument) (!!(Argument)) + +#ifndef __INTELLISENSE__ +# define ForEachListEntry(pListHead, pListEntry) for (((PLIST_ENTRY) (pListEntry)) = (pListHead)->Flink; ((PLIST_ENTRY) (pListEntry)) != (pListHead); ((PLIST_ENTRY) (pListEntry)) = ((PLIST_ENTRY) (pListEntry))->Flink) +#else +# define ForEachListEntry(pListHead, pListEntry) +#endif + +#define RtlProcessHeap() (NtCurrentPeb()->ProcessHeap) +#define GetProcessHeap RtlProcessHeap +#define HeapAlloc RtlAllocateHeap +#define HeapFree RtlFreeHeap +#define NtCurrentProcess() ((HANDLE) -1) +#define NtCurrentThread() ((HANDLE) -2) +#define GetCurrentProcess NtCurrentProcess + +#define RtlAnsiStringToUnicodeSize(AnsiString) (((AnsiString)->Length + sizeof(ANSI_NULL)) * sizeof(WCHAR)) +#define RtlUnicodeStringToAnsiSize(UnicodeString) (((UnicodeString)->Length + sizeof(UNICODE_NULL)) / sizeof(WCHAR)) +#define RtlInitEmptyUnicodeString(UnicodeString, InitBuffer, BufferCb) \ + ((UnicodeString)->Buffer = (InitBuffer), \ + (UnicodeString)->Length = 0, \ + (UnicodeString)->MaximumLength = (USHORT)(BufferCb)) +#define RtlInitEmptyAnsiString(AnsiString, InitBuffer, BufferCb) RtlInitEmptyUnicodeString(AnsiString, InitBuffer, BufferCb) + +#define RtlInitEmptyUnicodeStringFromTeb(UnicodeString) \ + ((UnicodeString)->Buffer = NtCurrentTeb()->StaticUnicodeBuffer, \ + (UnicodeString)->Length = 0, \ + (UnicodeString)->MaximumLength = RTL_FIELD_SIZE(TEB, StaticUnicodeBuffer)) +#define RtlInitEmptyAnsiStringFromTeb(AnsiString) RtlInitEmptyUnicodeStringFromTeb(AnsiString) + +#define HASH_ENTRY_KEY(x) ((x)->Signature) + +#define LdrpCallInitRoutine(InitRoutine, DllHandle, Reason, Context) \ + (InitRoutine)((DllHandle), (Reason), (Context)) + +#ifdef _M_X64 +# ifdef __INTELLISENSE__ +# define __readgsdword() 0 +# endif +# define RtlGetLastWin32Error() __readgsdword(0x68) +# define GetCurrentProcessId() __readgsdword(0x40) +# define GetCurrentThreadId() __readgsdword(0x48) +#else +# define RtlGetLastWin32Error() __readfsdword(0x34) +# define GetCurrentProcessId() __readfsdword(0x20) +# define GetCurrentThreadId() __readfsdword(0x24) +#endif + +#define GetLastError RtlGetLastWin32Error +#define CloseHandle NtClose // not technically the same thing, but whatever + +#pragma endregion + +#pragma region Inline Functions + +FORCEINLINE PPEB NtCurrentPeb( + VOID) +{ +#ifdef _M_X64 +# ifndef __INTELLISENSE__ + return (PPEB) __readgsqword(0x60); +# endif +#else + return (PPEB) __readfsdword(0x30); +#endif +} + +FORCEINLINE VOID InitializeObjectAttributes( + OUT POBJECT_ATTRIBUTES ObjectAttributes, + IN PUNICODE_STRING ObjectName, + IN ULONG Attributes, + IN HANDLE RootDirectory, + IN PSECURITY_DESCRIPTOR SecurityDescriptor) +{ + ObjectAttributes->Length = sizeof(OBJECT_ATTRIBUTES); + ObjectAttributes->RootDirectory = RootDirectory; + ObjectAttributes->Attributes = Attributes; + ObjectAttributes->ObjectName = ObjectName; + ObjectAttributes->SecurityDescriptor = SecurityDescriptor; + ObjectAttributes->SecurityQualityOfService = NULL; +} + +// doubly linked list functions + +FORCEINLINE VOID InitializeListHead( + OUT PLIST_ENTRY ListHead) +{ + ListHead->Flink = ListHead; + ListHead->Blink = ListHead; +} + +FORCEINLINE BOOL IsListEmpty( + IN PLIST_ENTRY ListHead) +{ + return ListHead->Flink == ListHead; +} + +FORCEINLINE VOID RemoveEntryList( + OUT PLIST_ENTRY Entry) +{ + PLIST_ENTRY Blink = Entry->Blink; + PLIST_ENTRY Flink = Entry->Flink; + Blink->Flink = Flink; + Flink->Blink = Blink; +} + +FORCEINLINE PLIST_ENTRY RemoveHeadList( + OUT PLIST_ENTRY ListHead) +{ + PLIST_ENTRY Ret = ListHead->Flink; + RemoveEntryList(ListHead->Flink); + return Ret; +} + +FORCEINLINE PLIST_ENTRY RemoveTailList( + OUT PLIST_ENTRY ListHead) +{ + PLIST_ENTRY Blink = ListHead->Blink; + RemoveEntryList(ListHead->Blink); + return Blink; +} + +FORCEINLINE VOID InsertTailList( + OUT PLIST_ENTRY ListHead, + IN PLIST_ENTRY Entry) +{ + Entry->Flink = ListHead; + Entry->Blink = ListHead->Blink; + ListHead->Blink->Flink = Entry; + ListHead->Blink = Entry; +} + +FORCEINLINE VOID InsertHeadList( + OUT PLIST_ENTRY ListHead, + IN PLIST_ENTRY Entry) +{ + Entry->Flink = ListHead->Flink; + Entry->Blink = ListHead; + ListHead->Flink->Blink = Entry; + ListHead->Flink = Entry; +} + +// singly linked list functions + +FORCEINLINE VOID PushEntryList( + OUT PSINGLE_LIST_ENTRY ListHead, + IN PSINGLE_LIST_ENTRY Entry) +{ + Entry->Next = ListHead->Next; + ListHead->Next = Entry; +} + +FORCEINLINE PSINGLE_LIST_ENTRY PopEntryList( + OUT PSINGLE_LIST_ENTRY ListHead) +{ + PSINGLE_LIST_ENTRY FirstEntry = ListHead->Next; + + if (FirstEntry) { + ListHead->Next = FirstEntry->Next; + } + + return FirstEntry; +} + +// hash table functions + +FORCEINLINE VOID RtlInitHashTableContext( + IN OUT PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context) +{ + Context->ChainHead = NULL; + Context->PrevLinkage = NULL; +} + +FORCEINLINE VOID RtlInitHashTableContextFromEnumerator( + IN OUT PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context, + IN PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator) +{ + Context->ChainHead = Enumerator->ChainHead; + Context->PrevLinkage = Enumerator->HashEntry.Linkage.Blink; +} + +FORCEINLINE VOID RtlReleaseHashTableContext( + IN OUT PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context) +{ + return; +} + +FORCEINLINE ULONG RtlTotalBucketsHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable) +{ + return HashTable->TableSize; +} + +FORCEINLINE ULONG RtlNonEmptyBucketsHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable) +{ + return HashTable->NonEmptyBuckets; +} + +FORCEINLINE ULONG RtlEmptyBucketsHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable) +{ + return HashTable->TableSize - HashTable->NonEmptyBuckets; +} + +FORCEINLINE ULONG RtlTotalEntriesHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable) +{ + return HashTable->NumEntries; +} + +FORCEINLINE ULONG RtlActiveEnumeratorsHashTable( + IN PRTL_DYNAMIC_HASH_TABLE HashTable) +{ + return HashTable->NumEnumerators; +} + +#pragma endregion \ No newline at end of file diff --git a/00-Common Headers/NtKrnl.h b/00-Common Headers/NtKrnl.h new file mode 100644 index 0000000..d3ec5f3 --- /dev/null +++ b/00-Common Headers/NtKrnl.h @@ -0,0 +1,1240 @@ +#pragma once + +typedef struct _DRIVER_OBJECT TYPEDEF_TYPE_NAME(DRIVER_OBJECT); +typedef struct _DEVICE_OBJECT TYPEDEF_TYPE_NAME(DEVICE_OBJECT); +typedef struct _IRP TYPEDEF_TYPE_NAME(IRP); +typedef struct _KDPC TYPEDEF_TYPE_NAME(KDPC); +typedef struct _FILE_OBJECT TYPEDEF_TYPE_NAME(FILE_OBJECT); +typedef struct _MDL TYPEDEF_TYPE_NAME(MDL); + +typedef enum _IO_ALLOCATION_ACTION { + KeepObject = 1, + DeallocateObject, + DeallocateObjectKeepRegisters, +} TYPEDEF_TYPE_NAME(IO_ALLOCATION_ACTION); + +typedef IO_ALLOCATION_ACTION (NTAPI *PDRIVER_CONTROL) ( + IN PDEVICE_OBJECT DeviceObject, + IN OUT PIRP Irp, + IN PVOID MapRegisterBase, + IN PVOID Context); + +#define VPB_MOUNTED 0x00000001 +#define VPB_LOCKED 0x00000002 +#define VPB_PERSISTENT 0x00000004 +#define VPB_REMOVE_PENDING 0x00000008 +#define VPB_RAW_MOUNT 0x00000010 +#define VPB_DIRECT_WRITES_ALLOWED 0x00000020 + +#define MAXIMUM_VOLUME_LABEL_LENGTH (32 * sizeof(WCHAR)) // 32 characters + +typedef struct _VPB { + CSHORT Type; + CSHORT Size; + USHORT Flags; // VPB_* + USHORT VolumeLabelLength; // in bytes + PDEVICE_OBJECT DeviceObject; + PDEVICE_OBJECT RealDevice; + ULONG SerialNumber; + ULONG ReferenceCount; + WCHAR VolumeLabel[MAXIMUM_VOLUME_LABEL_LENGTH / sizeof(WCHAR)]; +} TYPEDEF_TYPE_NAME(VPB); + +typedef struct _KDEVICE_QUEUE_ENTRY { + LIST_ENTRY DeviceListEntry; + ULONG SortKey; + BOOLEAN Inserted; +} TYPEDEF_TYPE_NAME(KDEVICE_QUEUE_ENTRY); + +typedef VOID (NTAPI *PKDEFERRED_ROUTINE) ( + IN PKDPC Dpc, + IN PVOID DeferredContext OPTIONAL, + IN PVOID SystemArgument1 OPTIONAL, + IN PVOID SystemArgument2 OPTIONAL); + +typedef struct _KDPC { + UCHAR Type; + UCHAR Importance; + VOLATILE USHORT Number; + LIST_ENTRY DpcListEntry; + PKDEFERRED_ROUTINE DeferredRoutine; + PVOID DeferredContext; + PVOID SystemArgument1; + PVOID SystemArgument2; + VOLATILE PVOID DpcData; +} TYPEDEF_TYPE_NAME(KDPC); + +typedef struct _WAIT_CONTEXT_BLOCK { + KDEVICE_QUEUE_ENTRY WaitQueueEntry; + PDRIVER_CONTROL DeviceRoutine; + PVOID DeviceContext; + ULONG NumberOfMapRegisters; + PDEVICE_OBJECT DeviceObject; + PIRP CurrentIrp; + PKDPC BufferChainingDpc; +} TYPEDEF_TYPE_NAME(WAIT_CONTEXT_BLOCK); + +typedef VOID (NTAPI *PIO_TIMER_ROUTINE) ( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context OPTIONAL); + +typedef struct _IO_TIMER { + CSHORT Type; + CSHORT TimerFlag; + LIST_ENTRY TimerList; + PIO_TIMER_ROUTINE TimerRoutine; + PVOID Context; + PDEVICE_OBJECT DeviceObject; +} TYPEDEF_TYPE_NAME(IO_TIMER); + +typedef struct _KDEVICE_QUEUE { + CSHORT Type; + CSHORT Size; + LIST_ENTRY DeviceListHead; + KSPIN_LOCK Lock; + +#ifdef _M_X64 + union { + BOOLEAN Busy; + struct { + LONGLONG Reserved : 8; + LONGLONG Hint : 56; + }; + }; +#else + BOOLEAN Busy; +#endif +} TYPEDEF_TYPE_NAME(KDEVICE_QUEUE); + +// +// Common dispatcher object header +// +// N.B. The size field contains the number of dwords in the structure. +// + +#define TIMER_EXPIRED_INDEX_BITS 6 +#define TIMER_PROCESSOR_INDEX_BITS 5 + +typedef struct _DISPATCHER_HEADER { + union { + struct { + UCHAR Type; // All (accessible via KOBJECT_TYPE) + + union { + union { // Timer + UCHAR TimerControlFlags; + + struct { + UCHAR Absolute : 1; + UCHAR Coalescable : 1; + UCHAR KeepShifting : 1; // Periodic timer + UCHAR EncodedTolerableDelay : 5; // Periodic timer + }; + }; + + UCHAR Abandoned; // Queue + BOOLEAN Signalling; // Gate/Events + }; + + union { + union { + UCHAR ThreadControlFlags; // Thread + + struct { + UCHAR CpuThrottled : 1; + UCHAR CycleProfiling : 1; + UCHAR CounterProfiling: 1; + UCHAR Reserved : 5; + }; + }; + + UCHAR Hand; // Timer + UCHAR Size; // All other objects + }; + + union { + union { // Timer + UCHAR TimerMiscFlags; + + struct { + +#ifdef _M_X64 + UCHAR Index : TIMER_EXPIRED_INDEX_BITS; +#else + UCHAR Index : 1; + UCHAR Processor : TIMER_PROCESSOR_INDEX_BITS; +#endif + + UCHAR Inserted : 1; + VOLATILE UCHAR Expired : 1; + }; + }; + + union { // Thread + BOOLEAN DebugActive; + + struct { + BOOLEAN ActiveDR7 : 1; + BOOLEAN Instrumented: 1; + BOOLEAN Reserved2 : 4; + BOOLEAN UmsScheduled: 1; + BOOLEAN UmsPrimary : 1; + }; + }; + + BOOLEAN DpcActive; // Mutant + }; + }; + + VOLATILE LONG Lock; // Interlocked + }; + + LONG SignalState; // Object lock + LIST_ENTRY WaitListHead; // Object lock +} TYPEDEF_TYPE_NAME(DISPATCHER_HEADER); + +typedef struct _KEVENT { + DISPATCHER_HEADER Header; +} TYPEDEF_TYPE_NAME(KEVENT); + +typedef struct _DEVOBJ_EXTENSION { + CSHORT Type; + USHORT Size; + PDEVICE_OBJECT DeviceObject; +} TYPEDEF_TYPE_NAME(DEVOBJ_EXTENSION); + +typedef struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) _DEVICE_OBJECT { + CSHORT Type; + CSHORT Size; + LONG ReferenceCount; + + PDRIVER_OBJECT DriverObject; + PDEVICE_OBJECT NextDevice; + PDEVICE_OBJECT AttachedDevice; + PIRP CurrentIrp; + PIO_TIMER Timer; + ULONG Flags; + ULONG Characteristics; + VOLATILE PVPB Vpb; + PVOID DeviceExtension; + DEVICE_TYPE DeviceType; + CCHAR StackSize; + + union { + LIST_ENTRY ListEntry; + WAIT_CONTEXT_BLOCK Wcb; + } Queue; + + ULONG AlignmentRequirement; + KDEVICE_QUEUE DeviceQueue; + KDPC Dpc; + + ULONG ActiveThreadCount; + PSECURITY_DESCRIPTOR SecurityDescriptor; + KEVENT DeviceLock; + + USHORT SectorSize; + USHORT Spare1; + + PDEVOBJ_EXTENSION DeviceObjectExtension; + PVOID Reserved; +} TYPEDEF_TYPE_NAME(DEVICE_OBJECT); + +typedef NTSTATUS (NTAPI *PDRIVER_ADD_DEVICE) ( + IN PDRIVER_OBJECT DriverObject, + IN PDEVICE_OBJECT PhysicalDeviceObject); + +typedef struct _DRIVER_EXTENSION { + PDRIVER_OBJECT DriverObject; + PDRIVER_ADD_DEVICE AddDevice; + ULONG Count; + UNICODE_STRING ServiceKeyName; +} TYPEDEF_TYPE_NAME(DRIVER_EXTENSION); + +typedef struct _SECTION_OBJECT_POINTERS { + PVOID DataSectionObject; + PVOID SharedCacheMap; + PVOID ImageSectionObject; +} TYPEDEF_TYPE_NAME(SECTION_OBJECT_POINTERS); + +typedef struct _IO_COMPLETION_CONTEXT { + PVOID Port; + PVOID Key; +} TYPEDEF_TYPE_NAME(IO_COMPLETION_CONTEXT); + +#define FO_FILE_OPEN 0x00000001 +#define FO_SYNCHRONOUS_IO 0x00000002 +#define FO_ALERTABLE_IO 0x00000004 +#define FO_NO_INTERMEDIATE_BUFFERING 0x00000008 +#define FO_WRITE_THROUGH 0x00000010 +#define FO_SEQUENTIAL_ONLY 0x00000020 +#define FO_CACHE_SUPPORTED 0x00000040 +#define FO_NAMED_PIPE 0x00000080 +#define FO_STREAM_FILE 0x00000100 +#define FO_MAILSLOT 0x00000200 +#define FO_GENERATE_AUDIT_ON_CLOSE 0x00000400 +#define FO_QUEUE_IRP_TO_THREAD FO_GENERATE_AUDIT_ON_CLOSE +#define FO_DIRECT_DEVICE_OPEN 0x00000800 +#define FO_FILE_MODIFIED 0x00001000 +#define FO_FILE_SIZE_CHANGED 0x00002000 +#define FO_CLEANUP_COMPLETE 0x00004000 +#define FO_TEMPORARY_FILE 0x00008000 +#define FO_DELETE_ON_CLOSE 0x00010000 +#define FO_OPENED_CASE_SENSITIVE 0x00020000 +#define FO_HANDLE_CREATED 0x00040000 +#define FO_FILE_FAST_IO_READ 0x00080000 +#define FO_RANDOM_ACCESS 0x00100000 +#define FO_FILE_OPEN_CANCELLED 0x00200000 +#define FO_VOLUME_OPEN 0x00400000 +#define FO_REMOTE_ORIGIN 0x01000000 +#define FO_DISALLOW_EXCLUSIVE 0x02000000 +#define FO_SKIP_COMPLETION_PORT FO_DISALLOW_EXCLUSIVE +#define FO_SKIP_SET_EVENT 0x04000000 +#define FO_SKIP_SET_FAST_IO 0x08000000 + +typedef struct _FILE_OBJECT { + CSHORT Type; + CSHORT Size; + PDEVICE_OBJECT DeviceObject; + PVPB Vpb; + PVOID FsContext; + PVOID FsContext2; + PSECTION_OBJECT_POINTERS SectionObjectPointer; + PVOID PrivateCacheMap; + NTSTATUS FinalStatus; + PFILE_OBJECT RelatedFileObject; + BOOLEAN LockOperation; + BOOLEAN DeletePending; + BOOLEAN ReadAccess; + BOOLEAN WriteAccess; + BOOLEAN DeleteAccess; + BOOLEAN SharedRead; + BOOLEAN SharedWrite; + BOOLEAN SharedDelete; + ULONG Flags; // FO_* + UNICODE_STRING FileName; + LARGE_INTEGER CurrentByteOffset; + VOLATILE ULONG Waiters; + VOLATILE ULONG Busy; + PVOID LastLock; + KEVENT Lock; + KEVENT Event; + VOLATILE PIO_COMPLETION_CONTEXT CompletionContext; + KSPIN_LOCK IrpListLock; + LIST_ENTRY IrpList; + VOLATILE PVOID FileObjectExtension; +} TYPEDEF_TYPE_NAME(FILE_OBJECT); + +#ifdef _M_X64 +# define MAX_PROC_GROUPS 4 +#else +# define MAX_PROC_GROUPS 1 +#endif + +// https://www.geoffchappell.com/studies/windows/km/ntoskrnl/api/ke/affinity/kaffinity_ex.htm +typedef struct _KAFFINITY_EX { + USHORT Count; + USHORT Size; + ULONG Reserved; + KAFFINITY Bitmap[MAX_PROC_GROUPS]; +} TYPEDEF_TYPE_NAME(KAFFINITY_EX); + +// https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/ntos/ke/kexecute_options.htm +typedef union _KEXECUTE_OPTIONS { + struct { + UCHAR ExecuteDisable : 1; + UCHAR ExecuteEnable : 1; + UCHAR DisableThunkEmulation : 1; + UCHAR Permanent : 1; + UCHAR ExecuteDispatchEnable : 1; + UCHAR ImageDispatchEnable : 1; + UCHAR DisableExceptionChainValidation : 1; + UCHAR Spare : 1; + }; + + VOLATILE UCHAR ExecuteOptions; + UCHAR ExecuteOptionsNV; +} TYPEDEF_TYPE_NAME(KEXECUTE_OPTIONS); + +// https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/ntos/ke/kprocess_state.htm +typedef enum _KPROCESS_STATE { + ProcessInMemory, + ProcessOutOfMemory, + ProcessInTransition, + ProcessOutTransition, + ProcessInSwap, + ProcessOutSwap, + ProcessAllSwapStates +} TYPEDEF_TYPE_NAME(KPROCESS_STATE); + +// https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/ntos/ke/kstack_count.htm +typedef union _KSTACK_COUNT { + struct { + VOLATILE ULONG State : 3; // KPROCESS_STATE + ULONG StackCount : 29; + }; + + VOLATILE LONG Value; +} TYPEDEF_TYPE_NAME(KSTACK_COUNT); + +typedef union _KGDTENTRY64 { + struct { + USHORT LimitLow; + USHORT BaseLow; + + struct { + CHAR BaseMiddle; + CHAR Flags1; + CHAR Flags2; + CHAR BaseHigh; + } Bytes; + + ULONG BaseUpper; + ULONG MustBeZero; + }; + + struct { + BYTE gap0[4]; + ULONG BaseMiddle : 8; + ULONG Type : 5; + ULONG Dpl : 2; + ULONG Present : 1; + ULONG LimitHigh : 4; + ULONG System : 1; + ULONG LongMode : 1; + ULONG DefaultBig : 1; + ULONG Granularity : 1; + ULONG BaseHigh : 8; + }; + + ULONG_PTR Alignment; +} TYPEDEF_TYPE_NAME(KGDTENTRY64); + +// https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/ntos/ke/kwait_state.htm +typedef enum _KWAIT_STATE { + WaitInProgress, + WaitCommitted, + WaitAborted, + MaximumWaitState +} TYPEDEF_TYPE_NAME(KWAIT_STATE); + +// https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/ntos/ke/kwait_status_register.htm +typedef struct _KWAIT_STATUS_REGISTER { + UCHAR State : 2; // KWAIT_STATE + UCHAR Affinity : 1; + UCHAR Priority : 1; + UCHAR Apc : 1; + UCHAR UserApc : 1; + UCHAR Alert : 1; + UCHAR Unused : 1; +} TYPEDEF_TYPE_NAME(KWAIT_STATUS_REGISTER); + +typedef struct _KQUEUE { + DISPATCHER_HEADER Header; + LIST_ENTRY EntryListHead; // Object lock + VOLATILE ULONG CurrentCount; // Interlocked + ULONG MaximumCount; + LIST_ENTRY ThreadListHead; // Object lock +} TYPEDEF_TYPE_NAME(KQUEUE); + +// https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/ntos/ke/kthread/late52.htm +typedef struct _KTHREAD { + DISPATCHER_HEADER Header; + VOLATILE ULONGLONG CycleTime; + VOLATILE ULONG HighCycleTime; + ULONGLONG QuantumTarget; + PVOID InitialStack; + VOLATILE PVOID StackLimit; + PVOID KernelStack; + KSPIN_LOCK ThreadLock; + KWAIT_STATUS_REGISTER WaitRegister; + VOLATILE BOOLEAN Running; + BOOLEAN Alerted[2]; + + union { + struct { + ULONG KernelStackResident : 1; + ULONG ProcessReadyQueue : 1; + ULONG WaitNext : 1; + ULONG SystemAffinityActive : 1; + ULONG Alertable : 1; + ULONG GdiFlushActive : 1; + ULONG UserStackWalkActive : 1; + ULONG ApcInterruptRequest : 1; + ULONG ForceDeferSchedule : 1; + ULONG QuantumEndMigrate : 1; + ULONG UmsDirectedSwitchEnable : 1; + ULONG TimerActive : 1; + ULONG Reserved : 19; + }; + + LONG MiscFlags; + }; + + union { + LIST_ENTRY WaitListEntry; + SINGLE_LIST_ENTRY SwapListEntry; + KQUEUE *VOLATILE Queue; + }; + + // There are more members after this. I'm not clear on exactly how they are laid + // out so I will omit them for now. +} TYPEDEF_TYPE_NAME(KTHREAD); + +typedef struct _ETHREAD { + KTHREAD Tcb; + LARGE_INTEGER CreateTime; + + union { + LARGE_INTEGER ExitTime; + LIST_ENTRY KeyedWaitChain; + }; + + LONG ExitStatus; + + // more members later on... +} TYPEDEF_TYPE_NAME(ETHREAD); + +typedef struct _KGATE { + DISPATCHER_HEADER Header; +} TYPEDEF_TYPE_NAME(KGATE); + +typedef struct _KGUARDED_MUTEX { + VOLATILE INT Count; + PKTHREAD Owner; + ULONG Contention; + KGATE Gate; + + union { + struct { + USHORT KernelApcDisable; + USHORT SpecialApcDisable; + }; + + ULONG CombinedApcDisable; + }; +} TYPEDEF_TYPE_NAME(KGUARDED_MUTEX); + +// https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/ntos/ke/kprocess/index.htm +typedef struct DECLSPEC_ALIGN(8) _KPROCESS { + DISPATCHER_HEADER Header; + LIST_ENTRY ProfileListHead; + ULONG_PTR DirectoryTableBase; +#ifndef _M_X64 + KGDTENTRY LdtDescriptor; + KIDTENTRY Int21Descriptor; +#endif + LIST_ENTRY ThreadListHead; + ULONG_PTR ProcessLock; + KAFFINITY_EX Affinity; + LIST_ENTRY ReadyListHead; + SINGLE_LIST_ENTRY SwapListEntry; + KAFFINITY_EX ActiveProcessors; + + union { + struct { + VOLATILE LONG AutoAlignment : 1; + VOLATILE LONG DisableBoost : 1; + VOLATILE LONG DisableQuantum : 1; + VOLATILE ULONG ActiveGroupsMask : MAX_PROC_GROUPS; + }; + + VOLATILE LONG ProcessFlags; + }; + + CHAR BasePriority; + CHAR QuantumReset; + BOOLEAN Visited; + UCHAR Unused3; + ULONG ThreadSeed[4]; + USHORT IdealNode[4]; + USHORT IdealGlobalNode; + KEXECUTE_OPTIONS Flags; + UCHAR Unused1; + +#ifdef _M_X64 + ULONG Unused2; +#else + USHORT IopmOffset; +#endif + + ULONG Unused4; + KSTACK_COUNT StackCount; + LIST_ENTRY ProcessListEntry; + VOLATILE ULONGLONG CycleTime; + ULONG KernelTime; + ULONG UserTime; + +#ifdef _M_X64 + PVOID InstrumentationCallback; + KGDTENTRY64 LdtSystemDescriptor; + PVOID LdtBaseAddress; + KGUARDED_MUTEX LdtProcessLock; + USHORT LdtFreeSelectorHint; + USHORT LdtTableLength; +#else + PVOID VdmTrapcHandler; +#endif +} TYPEDEF_TYPE_NAME(KPROCESS); + +typedef union _EX_PUSH_LOCK { + struct { + ULONG_PTR Locked : 1; + ULONG_PTR Waiting : 1; + ULONG_PTR Waking : 1; + ULONG_PTR MultipleShared : 1; +#ifdef _M_X64 + ULONG_PTR Shared : 60; +#else + ULONG_PTR Shared : 28; +#endif + }; + + ULONG_PTR Value; + PVOID Ptr; +} TYPEDEF_TYPE_NAME(EX_PUSH_LOCK); + +typedef union _EX_RUNDOWN_REF { + ULONG_PTR Count; + PVOID Ptr; +} TYPEDEF_TYPE_NAME(EX_RUNDOWN_REF); + +typedef struct _EPROCESS { + KPROCESS Pcb; + EX_PUSH_LOCK ProcessLock; + LARGE_INTEGER CreateTime; + LARGE_INTEGER ExitTime; + EX_RUNDOWN_REF RundownProtect; + HANDLE UniqueProcessId; + LIST_ENTRY ActiveProcessLinks; + ULONG_PTR ProcessQuotaUsage[2]; + ULONG_PTR ProcessQuotaPeak[2]; + VOLATILE ULONG_PTR CommitCharge; + PVOID QuotaBlock; +// PS_CPU_QUOTA_BLOCK CpuQuotaBlock; +// ULONG_PTR PeakVirtualSize; +// ULONG_PTR VirtualSize; +// LIST_ENTRY SessionProcessLinks; +// PVOID DebugPort; +// +// union { +// PVOID ExceptionPortData; +// ULONG_PTR ExceptionPortValue; +// ULONG_PTR ExceptionPortState : 3; +// }; +// +// PHANDLE_TABLE ObjectTable; +// EX_FAST_REF Token; +// ULONG_PTR WorkingSetPage; +// EX_PUSH_LOCK AddressCreationLock; +// PETHREAD RotateInProcess; +// PETHREAD ForkInProcess; +// ULONG_PTR HardwareTrigger; +// PMM_AVL_TABLE PhysicalVadRoot; +// PVOID CloneRoot; +// VOLATILE ULONG_PTR NumberOfPrivatePages; +// VOLATILE ULONG_PTR NumberOfLockedPages; +// PVOID Win32Process; +// EJOB *VOLATILE Job; +// PVOID SectionObject; +// PVOID SectionBaseAddress; +// ULONG Cookie; +// +//#ifdef _M_X64 +// ULONG UmsScheduledThreads; +//#else +// ULONG Spare8; +//#endif +// +// PPAGEFAULT_HISTORY WorkingSetWatch; +// PVOID Win32WindowStation; +// HANDLE InheritedFromUniqueProcessId; +// PVOID LdtInformation; +// +//#ifdef _M_X64 +// PVOID Spare; +//#else +// PVOID VdmObjects; +//#endif +// +// ULONG_PTR ConsoleHostProcess; +// PVOID DeviceMap; +// PVOID EtwDataSource; +// PVOID FreeTebHint; +// PVOID FreeUmsTebHint; +// +// union { +// HARDWARE_PTE PageDirectoryPte; +// ULONGLONG Filler; +// }; +// +// PVOID Session; +// UCHAR ImageFileName[0x0F]; +// UCHAR PriorityClass; +// LIST_ENTRY JobLinks; +// PVOID LockedPagesList; +// LIST_ENTRY ThreadListHead; +// PVOID SecurityPort; +// +//#ifdef _M_X64 +// PVOID Wow64Process; +//#else +// PVOID PaeTop; +//#endif +// +// VOLATILE ULONG ActiveThreads; +// ULONG ImagePathHash; +// ULONG DefaultHardErrorProcessing; +// LONG LastThreadExitStatus; +// PPEB Peb; +// EX_FAST_REF PrefetchTrace; +// +// LARGE_INTEGER ReadOperationCount; +// LARGE_INTEGER WriteOperationCount; +// LARGE_INTEGER OtherOperationCount; +// LARGE_INTEGER ReadTransferCount; +// LARGE_INTEGER WriteTransferCount; +// LARGE_INTEGER OtherTransferCount; +// +// ULONGLONG CommitChargeLimit; +// VOLATILE ULONGLONG CommitChargePeak; +// PVOID AweInfo; +// SE_AUDIT_PROCESS_CREATION_INFO SeAuditProcessCreationInfo; +// MMSUPPORT Vm; +// LIST_ENTRY MmProcessLinks; +// PVOID HighestUserAddress; +// ULONG ModifiedPageCount; +// +// union { +// struct { +// ULONG JobNotReallyActive:1; +// ULONG AccountingFolded:1; +// ULONG NewProcessReported:1; +// ULONG ExitProcessReported:1; +// ULONG ReportCommitChanges:1; +// ULONG LastReportMemory:1; +// ULONG ReportPhysicalPageChanges:1; +// ULONG HandleTableRundown:1; +// ULONG NeedsHandleRundown:1; +// ULONG RefTraceEnabled:1; +// ULONG NumaAware:1; +// ULONG ProtectedProcess:1; +// ULONG DefaultPagePriority:3; +// ULONG PrimaryTokenFrozen:1; +// ULONG ProcessVerifierTarget:1; +// ULONG StackRandomizationDisabled:1; +// ULONG AffinityPermanent:1; +// ULONG AffinityUpdateEnable:1; +// ULONG PropagateNode:1; +// ULONG ExplicitAffinity:1; +// }; +// +// ULONG Flags2; +// }; +// +// union { +// struct +// { +// ULONG CreateReported:1; +// ULONG NoDebugInherit:1; +// ULONG ProcessExiting:1; +// ULONG ProcessDelete:1; +// ULONG Wow64SplitPages:1; +// ULONG VmDeleted:1; +// ULONG OutswapEnabled:1; +// ULONG Outswapped:1; +// ULONG ForkFailed:1; +// ULONG Wow64VaSpace4Gb:1; +// ULONG AddressSpaceInitialized:2; +// ULONG SetTimerResolution:1; +// ULONG BreakOnTermination:1; +// ULONG DeprioritizeViews:1; +// ULONG WriteWatch:1; +// ULONG ProcessInSession:1; +// ULONG OverrideAddressSpace:1; +// ULONG HasAddressSpace:1; +// ULONG LaunchPrefetched:1; +// ULONG InjectInpageErrors:1; +// ULONG VmTopDown:1; +// ULONG ImageNotifyDone:1; +// ULONG PdeUpdateNeeded:1; +// ULONG VdmAllowed:1; +// ULONG CrossSessionCreate:1; +// ULONG ProcessInserted:1; +// ULONG DefaultIoPriority:3; +// ULONG ProcessSelfDelete:1; +// ULONG SetTimerResolutionLink:1; +// }; +// +// ULONG Flags; +// }; +// +// LONG ExitStatus; +// MM_AVL_TABLE VadRoot; +// ALPC_PROCESS_CONTEXT AlpcContext; +// LIST_ENTRY TimerResolutionLink; +// ULONG RequestedTimerResolution; +// ULONG ActiveThreadsHighWatermark; +// ULONG SmallestTimerResolution; +// PPO_DIAG_STACK_RECORD TimerResolutionStackRecord; +} TYPEDEF_TYPE_NAME(EPROCESS); + +typedef struct _MDL { + PMDL Next; + CSHORT Size; + CSHORT MdlFlags; + PEPROCESS Process; + PVOID MappedSystemVa; + PVOID StartVa; + ULONG ByteCount; + ULONG ByteOffset; +} TYPEDEF_TYPE_NAME(MDL); + +typedef struct _KMUTANT { + DISPATCHER_HEADER Header; + LIST_ENTRY MutantListEntry; + PKTHREAD OwnerThread; + BOOLEAN Abandoned; + UCHAR ApcDisable; +} TYPEDEF_TYPE_NAME(KMUTANT); + +typedef struct _KSEMAPHORE { + DISPATCHER_HEADER Header; + LONG Limit; +} TYPEDEF_TYPE_NAME(KSEMAPHORE); + +typedef ULONG_PTR ERESOURCE_THREAD; +typedef ERESOURCE_THREAD *PERESOURCE_THREAD; + +typedef struct _OWNER_ENTRY { + ERESOURCE_THREAD OwnerThread; + + union { + struct { + ULONG IoPriorityBoosted : 1; + ULONG OwnerReferenced : 1; + ULONG OwnerCount : 30; + }; + + ULONG TableSize; + }; +} TYPEDEF_TYPE_NAME(OWNER_ENTRY); + +typedef struct _ERESOURCE { + LIST_ENTRY SystemResourcesList; + POWNER_ENTRY OwnerTable; + + SHORT ActiveCount; + USHORT Flag; + VOLATILE PKSEMAPHORE SharedWaiters; + VOLATILE PKEVENT ExclusiveWaiters; + + OWNER_ENTRY OwnerEntry; + ULONG ActiveEntries; + ULONG ContentionCount; + ULONG NumberOfSharedWaiters; + ULONG NumberOfExclusiveWaiters; + +#ifdef _M_X64 + PVOID Reserved2; +#endif + + union { + PVOID Address; + ULONG_PTR CreatorBackTraceIndex; + }; + + KSPIN_LOCK SpinLock; +} TYPEDEF_TYPE_NAME(ERESOURCE); + +typedef struct _COMPRESSED_DATA_INFO { + // + // Code for the compression format (and engine) as + // defined in ntrtl.h. Note that COMPRESSION_FORMAT_NONE + // and COMPRESSION_FORMAT_DEFAULT are invalid if + // any of the described chunks are compressed. + // + + USHORT CompressionFormatAndEngine; + + // + // Since chunks and compression units are expected to be + // powers of 2 in size, we express then log2. So, for + // example (1 << ChunkShift) == ChunkSizeInBytes. The + // ClusterShift indicates how much space must be saved + // to successfully compress a compression unit - each + // successfully compressed compression unit must occupy + // at least one cluster less in bytes than an uncompressed + // compression unit. + // + + UCHAR CompressionUnitShift; + UCHAR ChunkShift; + UCHAR ClusterShift; + UCHAR Reserved; + + // + // This is the number of entries in the CompressedChunkSizes + // array. + // + + USHORT NumberOfChunks; + + // + // This is an array of the sizes of all chunks resident + // in the compressed data buffer. There must be one entry + // in this array for each chunk possible in the uncompressed + // buffer size. A size of FSRTL_CHUNK_SIZE indicates the + // corresponding chunk is uncompressed and occupies exactly + // that size. A size of 0 indicates that the corresponding + // chunk contains nothing but binary 0's, and occupies no + // space in the compressed data. All other sizes must be + // less than FSRTL_CHUNK_SIZE, and indicate the exact size + // of the compressed data in bytes. + // + + ULONG CompressedChunkSizes[ANYSIZE_ARRAY]; +} TYPEDEF_TYPE_NAME(COMPRESSED_DATA_INFO); + +typedef BOOLEAN (NTAPI *PFAST_IO_CHECK_IF_POSSIBLE) ( + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN BOOLEAN Wait, + IN ULONG LockKey, + IN BOOLEAN CheckForReadOperation, + OUT PIO_STATUS_BLOCK IoStatus, + IN PDEVICE_OBJECT DeviceObject); + +typedef BOOLEAN (NTAPI *PFAST_IO_READ) ( + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN BOOLEAN Wait, + IN ULONG LockKey, + OUT PVOID Buffer, + OUT PIO_STATUS_BLOCK IoStatus, + IN PDEVICE_OBJECT DeviceObject); + +typedef BOOLEAN (NTAPI *PFAST_IO_WRITE) ( + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN BOOLEAN Wait, + IN ULONG LockKey, + IN PVOID Buffer, + OUT PIO_STATUS_BLOCK IoStatus, + IN PDEVICE_OBJECT DeviceObject); + +typedef BOOLEAN (NTAPI *PFAST_IO_QUERY_BASIC_INFO) ( + IN PFILE_OBJECT FileObject, + IN BOOLEAN Wait, + OUT PFILE_BASIC_INFORMATION Buffer, + OUT PIO_STATUS_BLOCK IoStatus, + IN PDEVICE_OBJECT DeviceObject); + +typedef BOOLEAN (NTAPI *PFAST_IO_QUERY_STANDARD_INFO) ( + IN PFILE_OBJECT FileObject, + IN BOOLEAN Wait, + OUT PFILE_STANDARD_INFORMATION Buffer, + OUT PIO_STATUS_BLOCK IoStatus, + IN PDEVICE_OBJECT DeviceObject); + +typedef BOOLEAN (NTAPI *PFAST_IO_LOCK) ( + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN PLARGE_INTEGER Length, + IN PEPROCESS ProcessId, + IN ULONG Key, + IN BOOLEAN FailImmediately, + IN BOOLEAN ExclusiveLock, + OUT PIO_STATUS_BLOCK IoStatus, + IN PDEVICE_OBJECT DeviceObject); + +typedef BOOLEAN (NTAPI *PFAST_IO_UNLOCK_SINGLE) ( + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN PLARGE_INTEGER Length, + IN PEPROCESS ProcessId, + IN ULONG Key, + OUT PIO_STATUS_BLOCK IoStatus, + IN PDEVICE_OBJECT DeviceObject); + +typedef BOOLEAN (NTAPI *PFAST_IO_UNLOCK_ALL) ( + IN PFILE_OBJECT FileObject, + IN PEPROCESS ProcessId, + OUT PIO_STATUS_BLOCK IoStatus, + IN PDEVICE_OBJECT DeviceObject); + +typedef BOOLEAN (NTAPI *PFAST_IO_UNLOCK_ALL_BY_KEY) ( + IN PFILE_OBJECT FileObject, + IN PVOID ProcessId, + IN ULONG Key, + OUT PIO_STATUS_BLOCK IoStatus, + IN PDEVICE_OBJECT DeviceObject); + +typedef BOOLEAN (NTAPI *PFAST_IO_DEVICE_CONTROL) ( + IN PFILE_OBJECT FileObject, + IN BOOLEAN Wait, + IN PVOID InputBuffer OPTIONAL, + IN ULONG InputBufferLength, + OUT PVOID OutputBuffer OPTIONAL, + IN ULONG OutputBufferLength, + IN ULONG IoControlCode, + OUT PIO_STATUS_BLOCK IoStatus, + IN PDEVICE_OBJECT DeviceObject); + +typedef VOID (NTAPI *PFAST_IO_ACQUIRE_FILE) ( + IN PFILE_OBJECT FileObject); + +typedef VOID (NTAPI *PFAST_IO_RELEASE_FILE) ( + IN PFILE_OBJECT FileObject); + +typedef VOID (NTAPI *PFAST_IO_DETACH_DEVICE) ( + IN PDEVICE_OBJECT SourceDevice, + IN PDEVICE_OBJECT TargetDevice); + +typedef BOOLEAN (NTAPI *PFAST_IO_QUERY_NETWORK_OPEN_INFO) ( + IN PFILE_OBJECT FileObject, + IN BOOLEAN Wait, + OUT PFILE_NETWORK_OPEN_INFORMATION Buffer, + OUT PIO_STATUS_BLOCK IoStatus, + IN PDEVICE_OBJECT DeviceObject); + +typedef BOOLEAN (NTAPI *PFAST_IO_MDL_READ) ( + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN ULONG LockKey, + OUT PMDL *MdlChain, + OUT PIO_STATUS_BLOCK IoStatus, + IN PDEVICE_OBJECT DeviceObject); + +typedef BOOLEAN (NTAPI *PFAST_IO_MDL_READ_COMPLETE) ( + IN PFILE_OBJECT FileObject, + IN PMDL MdlChain, + IN PDEVICE_OBJECT DeviceObject); + +typedef BOOLEAN (NTAPI *PFAST_IO_PREPARE_MDL_WRITE) ( + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN ULONG LockKey, + OUT PMDL *MdlChain, + OUT PIO_STATUS_BLOCK IoStatus, + IN PDEVICE_OBJECT DeviceObject); + +typedef BOOLEAN (NTAPI *PFAST_IO_MDL_WRITE_COMPLETE) ( + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN PMDL MdlChain, + IN PDEVICE_OBJECT DeviceObject); + +typedef NTSTATUS (NTAPI *PFAST_IO_ACQUIRE_FOR_MOD_WRITE) ( + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER EndingOffset, + OUT PERESOURCE *ResourceToRelease, + IN PDEVICE_OBJECT DeviceObject); + +typedef NTSTATUS (NTAPI *PFAST_IO_RELEASE_FOR_MOD_WRITE) ( + IN PFILE_OBJECT FileObject, + IN PERESOURCE ResourceToRelease, + IN PDEVICE_OBJECT DeviceObject); + +typedef NTSTATUS (NTAPI *PFAST_IO_ACQUIRE_FOR_CCFLUSH) ( + IN PFILE_OBJECT FileObject, + IN PDEVICE_OBJECT DeviceObject); + +typedef NTSTATUS (NTAPI *PFAST_IO_RELEASE_FOR_CCFLUSH) ( + IN PFILE_OBJECT FileObject, + IN PDEVICE_OBJECT DeviceObject); + +typedef BOOLEAN (NTAPI *PFAST_IO_READ_COMPRESSED) ( + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN ULONG LockKey, + OUT PVOID Buffer, + OUT PMDL *MdlChain, + OUT PIO_STATUS_BLOCK IoStatus, + OUT PCOMPRESSED_DATA_INFO CompressedDataInfo, + IN ULONG CompressedDataInfoLength, + IN PDEVICE_OBJECT DeviceObject); + +typedef BOOLEAN (NTAPI *PFAST_IO_WRITE_COMPRESSED) ( + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN ULONG LockKey, + IN PVOID Buffer, + OUT PMDL *MdlChain, + OUT PIO_STATUS_BLOCK IoStatus, + IN PCOMPRESSED_DATA_INFO CompressedDataInfo, + IN ULONG CompressedDataInfoLength, + IN PDEVICE_OBJECT DeviceObject); + +typedef BOOLEAN (NTAPI *PFAST_IO_MDL_READ_COMPLETE_COMPRESSED) ( + IN PFILE_OBJECT FileObject, + IN PMDL MdlChain, + IN PDEVICE_OBJECT DeviceObject); + +typedef BOOLEAN (NTAPI *PFAST_IO_MDL_WRITE_COMPLETE_COMPRESSED) ( + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN PMDL MdlChain, + IN PDEVICE_OBJECT DeviceObject); + +typedef BOOLEAN (NTAPI *PFAST_IO_QUERY_OPEN) ( + IN OUT PIRP Irp, + OUT PFILE_NETWORK_OPEN_INFORMATION NetworkInformation, + IN PDEVICE_OBJECT DeviceObject); + +typedef struct _FAST_IO_DISPATCH { + ULONG SizeOfFastIoDispatch; + PFAST_IO_CHECK_IF_POSSIBLE FastIoCheckIfPossible; + PFAST_IO_READ FastIoRead; + PFAST_IO_WRITE FastIoWrite; + PFAST_IO_QUERY_BASIC_INFO FastIoQueryBasicInfo; + PFAST_IO_QUERY_STANDARD_INFO FastIoQueryStandardInfo; + PFAST_IO_LOCK FastIoLock; + PFAST_IO_UNLOCK_SINGLE FastIoUnlockSingle; + PFAST_IO_UNLOCK_ALL FastIoUnlockAll; + PFAST_IO_UNLOCK_ALL_BY_KEY FastIoUnlockAllByKey; + PFAST_IO_DEVICE_CONTROL FastIoDeviceControl; + PFAST_IO_ACQUIRE_FILE AcquireFileForNtCreateSection; + PFAST_IO_RELEASE_FILE ReleaseFileForNtCreateSection; + PFAST_IO_DETACH_DEVICE FastIoDetachDevice; + PFAST_IO_QUERY_NETWORK_OPEN_INFO FastIoQueryNetworkOpenInfo; + PFAST_IO_ACQUIRE_FOR_MOD_WRITE AcquireForModWrite; + PFAST_IO_MDL_READ MdlRead; + PFAST_IO_MDL_READ_COMPLETE MdlReadComplete; + PFAST_IO_PREPARE_MDL_WRITE PrepareMdlWrite; + PFAST_IO_MDL_WRITE_COMPLETE MdlWriteComplete; + PFAST_IO_READ_COMPRESSED FastIoReadCompressed; + PFAST_IO_WRITE_COMPRESSED FastIoWriteCompressed; + PFAST_IO_MDL_READ_COMPLETE_COMPRESSED MdlReadCompleteCompressed; + PFAST_IO_MDL_WRITE_COMPLETE_COMPRESSED MdlWriteCompleteCompressed; + PFAST_IO_QUERY_OPEN FastIoQueryOpen; + PFAST_IO_RELEASE_FOR_MOD_WRITE ReleaseForModWrite; + PFAST_IO_ACQUIRE_FOR_CCFLUSH AcquireForCcFlush; + PFAST_IO_RELEASE_FOR_CCFLUSH ReleaseForCcFlush; +} TYPEDEF_TYPE_NAME(FAST_IO_DISPATCH); + +typedef NTSTATUS (NTAPI *PDRIVER_INITIALIZE) ( + IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath); + +typedef VOID (NTAPI *PDRIVER_STARTIO) ( + IN OUT PDEVICE_OBJECT DeviceObject, + IN OUT PIRP Irp); + +typedef VOID (NTAPI *PDRIVER_UNLOAD) ( + IN PDRIVER_OBJECT DriverObject); + +typedef NTSTATUS (NTAPI *PDRIVER_DISPATCH) ( + IN PDEVICE_OBJECT DeviceObject, + IN OUT PIRP Irp); + +#define IRP_MJ_CREATE 0x00 +#define IRP_MJ_CREATE_NAMED_PIPE 0x01 +#define IRP_MJ_CLOSE 0x02 +#define IRP_MJ_READ 0x03 +#define IRP_MJ_WRITE 0x04 +#define IRP_MJ_QUERY_INFORMATION 0x05 +#define IRP_MJ_SET_INFORMATION 0x06 +#define IRP_MJ_QUERY_EA 0x07 +#define IRP_MJ_SET_EA 0x08 +#define IRP_MJ_FLUSH_BUFFERS 0x09 +#define IRP_MJ_QUERY_VOLUME_INFORMATION 0x0a +#define IRP_MJ_SET_VOLUME_INFORMATION 0x0b +#define IRP_MJ_DIRECTORY_CONTROL 0x0c +#define IRP_MJ_FILE_SYSTEM_CONTROL 0x0d +#define IRP_MJ_DEVICE_CONTROL 0x0e +#define IRP_MJ_INTERNAL_DEVICE_CONTROL 0x0f +#define IRP_MJ_SHUTDOWN 0x10 +#define IRP_MJ_LOCK_CONTROL 0x11 +#define IRP_MJ_CLEANUP 0x12 +#define IRP_MJ_CREATE_MAILSLOT 0x13 +#define IRP_MJ_QUERY_SECURITY 0x14 +#define IRP_MJ_SET_SECURITY 0x15 +#define IRP_MJ_POWER 0x16 +#define IRP_MJ_SYSTEM_CONTROL 0x17 +#define IRP_MJ_DEVICE_CHANGE 0x18 +#define IRP_MJ_QUERY_QUOTA 0x19 +#define IRP_MJ_SET_QUOTA 0x1a +#define IRP_MJ_PNP 0x1b +#define IRP_MJ_PNP_POWER IRP_MJ_PNP // Obsolete.... +#define IRP_MJ_MAXIMUM_FUNCTION 0x1b + +#define DRVO_UNLOAD_INVOKED 0x00000001 +#define DRVO_LEGACY_DRIVER 0x00000002 +#define DRVO_BUILTIN_DRIVER 0x00000004 + +typedef struct _DRIVER_OBJECT { + CSHORT Type; + CSHORT Size; + + PDEVICE_OBJECT DeviceObject; + ULONG Flags; // DRVO_* + + PVOID DriverStart; + ULONG DriverSize; + PVOID DriverSection; + PDRIVER_EXTENSION DriverExtension; + + UNICODE_STRING DriverName; + + PUNICODE_STRING HardwareDatabase; + + PFAST_IO_DISPATCH FastIoDispatch; + + PDRIVER_INITIALIZE DriverInit; + PDRIVER_STARTIO DriverStartIo; + PDRIVER_UNLOAD DriverUnload; + PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1]; +} TYPEDEF_TYPE_NAME(DRIVER_OBJECT); + +#define LOW_LEVEL 0 +#define PASSIVE_LEVEL 0 +#define APC_LEVEL 1 +#define DISPATCH_LEVEL 2 +#define CMCI_LEVEL 5 + +#ifdef _M_X64 +# define CLOCK_LEVEL 13 // Interval clock level +# define IPI_LEVEL 14 // Interprocessor interrupt level +# define DRS_LEVEL 14 // Deferred Recovery Service level +# define POWER_LEVEL 14 // Power failure level +# define PROFILE_LEVEL 15 // timer used for profiling. +# define HIGH_LEVEL 15 // Highest interrupt level +#else +# define PROFILE_LEVEL 27 // timer used for profiling. +# define CLOCK1_LEVEL 28 // Interval clock 1 level - Not used on x86 +# define CLOCK2_LEVEL 28 // Interval clock 2 level +# define IPI_LEVEL 29 // Interprocessor interrupt level +# define POWER_LEVEL 30 // Power failure level +# define HIGH_LEVEL 31 // Highest interrupt level + +# define CLOCK_LEVEL (CLOCK2_LEVEL) +#endif + +typedef UCHAR TYPEDEF_TYPE_NAME(KIRQL); + +// +// NTOSKRNL Functions +// + +KIRQL NTAPI KeGetCurrentIrql( + VOID); + +// +// Function-Like Macros +// + +#if KexIsDebugBuild +# define KdPrint(...) DbgPrint(__VA_ARGS__) +#else +# define KdPrint(...) +#endif + +#define PAGED_CODE() ASSERT (KeGetCurrentIrql() < DISPATCH_LEVEL) \ No newline at end of file diff --git a/00-Common Headers/NtStrSafe.h b/00-Common Headers/NtStrSafe.h new file mode 100644 index 0000000..1862c8c --- /dev/null +++ b/00-Common Headers/NtStrSafe.h @@ -0,0 +1,12588 @@ +/****************************************************************** +* * +* ntstrsafe.h -- This module defines safer C library string * +* routine replacements for drivers. These are * +* meant to make C a bit more safe in reference * +* to security and robustness. A similar file, * +* strsafe.h, is available for applications. * +* * +******************************************************************/ +#ifndef _NTSTRSAFE_H_INCLUDED_ +#define _NTSTRSAFE_H_INCLUDED_ +#if (_MSC_VER > 1000) +#pragma once +#endif + + +#include // for _vsnprintf, _vsnwprintf, getc, getwc +#include // for memset +#include // for va_start, etc. +#include // for __in, etc. + +#if !defined(_W64) +#if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && (_MSC_VER >= 1300) +#define _W64 __w64 +#else +#define _W64 +#endif +#endif + +#if defined(_M_MRX000) || defined(_M_ALPHA) || defined(_M_PPC) || defined(_M_IA64) || defined(_M_AMD64) +#define ALIGNMENT_MACHINE +#define UNALIGNED __unaligned +#if defined(_WIN64) +#define UNALIGNED64 __unaligned +#else +#define UNALIGNED64 +#endif +#else +#undef ALIGNMENT_MACHINE +#define UNALIGNED +#define UNALIGNED64 +#endif + +// typedefs +#ifdef _WIN64 +typedef unsigned __int64 size_t; +#else +typedef _W64 unsigned int size_t; +#endif + +#ifndef _NTSTATUS_DEFINED +#define _NTSTATUS_DEFINED +typedef __success(return >= 0) long NTSTATUS; +#endif + +typedef unsigned long DWORD; + + +#ifndef SORTPP_PASS +// compiletime asserts (failure results in error C2118: negative subscript) +#define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1] +#else +#define C_ASSERT(e) +#endif + +#ifdef __cplusplus +#define EXTERN_C extern "C" +#else +#define EXTERN_C extern +#endif + +// use the new secure crt functions if available +#ifndef NTSTRSAFE_USE_SECURE_CRT +#if defined(__GOT_SECURE_LIB__) && (__GOT_SECURE_LIB__ >= 200402L) +#define NTSTRSAFE_USE_SECURE_CRT 0 +#else +#define NTSTRSAFE_USE_SECURE_CRT 0 +#endif +#endif // !NTSTRSAFE_USE_SECURE_CRT + +#ifdef _M_CEE_PURE +#define NTSTRSAFEDDI __inline NTSTATUS __clrcall +#else +#define NTSTRSAFEDDI __inline NTSTATUS __stdcall +#endif + +#if defined(NTSTRSAFE_LIB_IMPL) || defined(NTSTRSAFE_LIB) +#define NTSTRSAFEWORKERDDI EXTERN_C NTSTATUS __stdcall +#else +#define NTSTRSAFEWORKERDDI static NTSTRSAFEDDI +#endif + +// The following steps are *REQUIRED* if ntstrsafe.h is used for drivers on: +// Windows 2000 +// Windows Millennium Edition +// Windows 98 Second Edition +// Windows 98 +// +// 1. #define NTSTRSAFE_LIB before including the ntstrsafe.h header file. +// 2. Add ntstrsafe.lib to the TARGET_LIBS line in SOURCES +// +// Drivers running on XP and later can skip these steps to create a smaller +// driver by running the functions inline. +#if defined(NTSTRSAFE_LIB) +#pragma comment(lib, "ntstrsafe.lib") +#endif + +// The user can request no "Cb" or no "Cch" fuctions, but not both +#if defined(NTSTRSAFE_NO_CB_FUNCTIONS) && defined(NTSTRSAFE_NO_CCH_FUNCTIONS) +#error cannot specify both NTSTRSAFE_NO_CB_FUNCTIONS and NTSTRSAFE_NO_CCH_FUNCTIONS !! +#endif + +// The user may override NTSTRSAFE_MAX_CCH, but it must always be less than INT_MAX +#ifndef NTSTRSAFE_MAX_CCH +#define NTSTRSAFE_MAX_CCH 2147483647 // max buffer size, in characters, that we support (same as INT_MAX) +#endif +C_ASSERT(NTSTRSAFE_MAX_CCH <= 2147483647); +C_ASSERT(NTSTRSAFE_MAX_CCH > 1); + +#define NTSTRSAFE_MAX_LENGTH (NTSTRSAFE_MAX_CCH - 1) // max buffer length, in characters, that we support + +// The user may override NTSTRSAFE_UNICODE_STRING_MAX_CCH, but it must always be less than (USHORT_MAX / sizeof(wchar_t)) +#ifndef NTSTRSAFE_UNICODE_STRING_MAX_CCH +#define NTSTRSAFE_UNICODE_STRING_MAX_CCH (0xffff / sizeof(wchar_t)) // max buffer size, in characters, for a UNICODE_STRING +#endif +C_ASSERT(NTSTRSAFE_UNICODE_STRING_MAX_CCH <= (0xffff / sizeof(wchar_t))); +C_ASSERT(NTSTRSAFE_UNICODE_STRING_MAX_CCH > 1); + + +// Flags for controling the Ex functions +// +// STRSAFE_FILL_BYTE(0xFF) 0x000000FF // bottom byte specifies fill pattern +#define STRSAFE_IGNORE_NULLS 0x00000100 // treat null string pointers as TEXT("") -- don't fault on NULL buffers +#define STRSAFE_FILL_BEHIND_NULL 0x00000200 // on success, fill in extra space behind the null terminator with fill pattern +#define STRSAFE_FILL_ON_FAILURE 0x00000400 // on failure, overwrite pszDest with fill pattern and null terminate it +#define STRSAFE_NULL_ON_FAILURE 0x00000800 // on failure, set *pszDest = TEXT('\0') +#define STRSAFE_NO_TRUNCATION 0x00001000 // instead of returning a truncated result, copy/append nothing to pszDest and null terminate it + +// Flags for controling UNICODE_STRING Ex functions +// +// STRSAFE_FILL_BYTE(0xFF) 0x000000FF // bottom byte specifies fill pattern +// STRSAFE_IGNORE_NULLS 0x00000100 // don't fault on NULL UNICODE_STRING pointers, and treat null pszSrc as L"" +#define STRSAFE_FILL_BEHIND 0x00000200 // on success, fill in extra space at the end of the UNICODE_STRING Buffer with fill pattern +// STRSAFE_FILL_ON_FAILURE 0x00000400 // on failure, fill the UNICODE_STRING Buffer with fill pattern and set the Length to 0 +#define STRSAFE_ZERO_LENGTH_ON_FAILURE 0x00000800 // on failure, set the UNICODE_STRING Length to 0 +// STRSAFE_NO_TRUNCATION 0x00001000 // instead of returning a truncated result, copy/append nothing to UNICODE_STRING Buffer + + +#define STRSAFE_VALID_FLAGS (0x000000FF | STRSAFE_IGNORE_NULLS | STRSAFE_FILL_BEHIND_NULL | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION) +#define STRSAFE_UNICODE_STRING_VALID_FLAGS (0x000000FF | STRSAFE_IGNORE_NULLS | STRSAFE_FILL_BEHIND | STRSAFE_FILL_ON_FAILURE | STRSAFE_ZERO_LENGTH_ON_FAILURE | STRSAFE_NO_TRUNCATION) + +// helper macro to set the fill character and specify buffer filling +#define STRSAFE_FILL_BYTE(x) ((DWORD)((x & 0x000000FF) | STRSAFE_FILL_BEHIND_NULL)) +#define STRSAFE_FAILURE_BYTE(x) ((DWORD)((x & 0x000000FF) | STRSAFE_FILL_ON_FAILURE)) + +#define STRSAFE_GET_FILL_PATTERN(dwFlags) ((int)(dwFlags & 0x000000FF)) + + +// +// These typedefs are used in places where the string is guaranteed to +// be null terminated. +// +typedef __nullterminated char* NTSTRSAFE_PSTR; +typedef __nullterminated const char* NTSTRSAFE_PCSTR; +typedef __nullterminated wchar_t* NTSTRSAFE_PWSTR; +typedef __nullterminated const wchar_t* NTSTRSAFE_PCWSTR; +typedef __nullterminated const wchar_t UNALIGNED* NTSTRSAFE_PCUWSTR; + +// +// These typedefs are used in places where the string is NOT guaranteed to +// be null terminated. +// +typedef __possibly_notnullterminated const char* STRSAFE_PCNZCH; +typedef __possibly_notnullterminated const wchar_t* STRSAFE_PCNZWCH; +typedef __possibly_notnullterminated const wchar_t UNALIGNED* STRSAFE_PCUNZWCH; + + +// prototypes for the worker functions + +NTSTRSAFEWORKERDDI +RtlStringLengthWorkerA( + __in STRSAFE_PCNZCH psz, + __in __in_range(<=, NTSTRSAFE_MAX_CCH) size_t cchMax, + __out_opt __deref_out_range(<, cchMax) size_t* pcchLength); + +NTSTRSAFEWORKERDDI +RtlStringLengthWorkerW( + __in STRSAFE_PCNZWCH psz, + __in __in_range(<=, NTSTRSAFE_MAX_CCH) size_t cchMax, + __out_opt __deref_out_range(<, cchMax) size_t* pcchLength); + +#ifdef ALIGNMENT_MACHINE +NTSTRSAFEWORKERDDI +RtlUnalignedStringLengthWorkerW( + __in STRSAFE_PCUNZWCH psz, + __in __in_range(<=, NTSTRSAFE_MAX_CCH) size_t cchMax, + __out_opt __deref_out_range(<, cchMax) size_t* pcchLength); +#endif // ALIGNMENT_MACHINE + +NTSTRSAFEWORKERDDI +RtlStringExValidateSrcA( + __deref_in_opt_out NTSTRSAFE_PCSTR* ppszSrc, + __inout_opt __deref_out_range(<, cchMax) size_t* pcchToRead, + __in const size_t cchMax, + __in DWORD dwFlags); + +NTSTRSAFEWORKERDDI +RtlStringExValidateSrcW( + __deref_in_opt_out NTSTRSAFE_PCWSTR* ppszSrc, + __inout_opt __deref_out_range(<, cchMax) size_t* pcchToRead, + __in const size_t cchMax, + __in DWORD dwFlags); + +NTSTRSAFEWORKERDDI +RtlStringValidateDestA( + __in_ecount_opt(cchDest) STRSAFE_PCNZCH pszDest, + __in size_t cchDest, + __in const size_t cchMax); + +NTSTRSAFEWORKERDDI +RtlStringValidateDestAndLengthA( + __in_ecount_opt(cchDest) NTSTRSAFE_PCSTR pszDest, + __in size_t cchDest, + __out __deref_out_range(<, cchDest) size_t* pcchDestLength, + __in const size_t cchMax); + +NTSTRSAFEWORKERDDI +RtlStringValidateDestW( + __in_ecount_opt(cchDest) STRSAFE_PCNZWCH pszDest, + __in size_t cchDest, + __in const size_t cchMax); + +NTSTRSAFEWORKERDDI +RtlStringValidateDestAndLengthW( + __in_ecount_opt(cchDest) NTSTRSAFE_PCWSTR pszDest, + __in size_t cchDest, + __out __deref_out_range(<, cchDest) size_t* pcchDestLength, + __in const size_t cchMax); + +NTSTRSAFEWORKERDDI +RtlStringExValidateDestA( + __in_ecount_opt(cchDest) STRSAFE_PCNZCH pszDest, + __in size_t cchDest, + __in const size_t cchMax, + __in DWORD dwFlags); + +NTSTRSAFEWORKERDDI +RtlStringExValidateDestAndLengthA( + __in_ecount_opt(cchDest) NTSTRSAFE_PCSTR pszDest, + __in size_t cchDest, + __out __deref_out_range(<, cchDest) size_t* pcchDestLength, + __in const size_t cchMax, + __in DWORD dwFlags); + +NTSTRSAFEWORKERDDI +RtlStringExValidateDestW( + __in_ecount_opt(cchDest) STRSAFE_PCNZWCH pszDest, + __in size_t cchDest, + __in const size_t cchMax, + __in DWORD dwFlags); + +NTSTRSAFEWORKERDDI +RtlStringExValidateDestAndLengthW( + __in_ecount_opt(cchDest) NTSTRSAFE_PCWSTR pszDest, + __in size_t cchDest, + __out __deref_out_range(<, cchDest) size_t* pcchDestLength, + __in const size_t cchMax, + __in DWORD dwFlags); + +NTSTRSAFEWORKERDDI +RtlStringCopyWorkerA( + __out_ecount(cchDest) NTSTRSAFE_PSTR pszDest, + __in __in_range(1, NTSTRSAFE_MAX_CCH) size_t cchDest, + __out_opt __deref_out_range(<=, (cchToCopy < cchDest) ? cchToCopy : cchDest - 1) size_t* pcchNewDestLength, + __in_xcount(cchToCopy) STRSAFE_PCNZCH pszSrc, + __in __in_range(<, NTSTRSAFE_MAX_CCH) size_t cchToCopy); + +NTSTRSAFEWORKERDDI +RtlStringCopyWorkerW( + __out_ecount(cchDest) NTSTRSAFE_PWSTR pszDest, + __in __in_range(1, NTSTRSAFE_MAX_CCH) size_t cchDest, + __out_opt __deref_out_range(<=, (cchToCopy < cchDest) ? cchToCopy : cchDest - 1) size_t* pcchNewDestLength, + __in_xcount(cchToCopy) STRSAFE_PCNZWCH pszSrc, + __in __in_range(<, NTSTRSAFE_MAX_CCH) size_t cchToCopy); + +NTSTRSAFEWORKERDDI +RtlStringVPrintfWorkerA( + __out_ecount(cchDest) NTSTRSAFE_PSTR pszDest, + __in __in_range(1, NTSTRSAFE_MAX_CCH) size_t cchDest, + __out_opt __deref_out_range(<=, cchDest - 1) size_t* pcchNewDestLength, + __in __format_string NTSTRSAFE_PCSTR pszFormat, + __in va_list argList); + +NTSTRSAFEWORKERDDI +RtlStringVPrintfWorkerW( + __out_ecount(cchDest) NTSTRSAFE_PWSTR pszDest, + __in __in_range(1, NTSTRSAFE_MAX_CCH) size_t cchDest, + __out_opt __deref_out_range(<=, cchDest - 1) size_t* pcchNewDestLength, + __in __format_string NTSTRSAFE_PCWSTR pszFormat, + __in va_list argList); + +NTSTRSAFEWORKERDDI +RtlStringExHandleFillBehindNullA( + __inout_bcount(cbRemaining) NTSTRSAFE_PSTR pszDestEnd, + __in size_t cbRemaining, + __in DWORD dwFlags); + +NTSTRSAFEWORKERDDI +RtlStringExHandleFillBehindNullW( + __inout_bcount(cbRemaining) NTSTRSAFE_PWSTR pszDestEnd, + __in size_t cbRemaining, + __in DWORD dwFlags); + +NTSTRSAFEWORKERDDI +RtlStringExHandleOtherFlagsA( + __inout_bcount(cbDest) NTSTRSAFE_PSTR pszDest, + __in __in_range(sizeof(char), NTSTRSAFE_MAX_CCH * sizeof(char)) size_t cbDest, + __in __in_range(<, cbDest / sizeof(char)) size_t cchOriginalDestLength, + __deref_inout_ecount(*pcchRemaining) NTSTRSAFE_PSTR* ppszDestEnd, + __out __deref_out_range(<=, cbDest / sizeof(char)) size_t* pcchRemaining, + __in DWORD dwFlags); + +NTSTRSAFEWORKERDDI +RtlStringExHandleOtherFlagsW( + __inout_bcount(cbDest) NTSTRSAFE_PWSTR pszDest, + __in __in_range(sizeof(wchar_t), NTSTRSAFE_MAX_CCH * sizeof(wchar_t)) size_t cbDest, + __in __in_range(<, cbDest / sizeof(wchar_t)) size_t cchOriginalDestLength, + __deref_inout_ecount(*pcchRemaining) NTSTRSAFE_PWSTR* ppszDestEnd, + __out __deref_out_range(<=, cbDest / sizeof(wchar_t)) size_t* pcchRemaining, + __in DWORD dwFlags); + +#ifndef NTSTRSAFE_NO_UNICODE_STRING_FUNCTIONS + +NTSTRSAFEWORKERDDI +RtlUnicodeStringInitWorker( + __out PUNICODE_STRING DestinationString, + __in_opt NTSTRSAFE_PCWSTR pszSrc, + __in const size_t cchMax, + __in DWORD dwFlags); + +NTSTRSAFEWORKERDDI +RtlUnicodeStringValidateWorker( + __in_opt PCUNICODE_STRING SourceString, + __in const size_t cchMax, + __in DWORD dwFlags); + +NTSTRSAFEWORKERDDI +RtlUnicodeStringValidateSrcWorker( + __in PCUNICODE_STRING SourceString, + __deref_out_ecount(*pcchSrcLength) wchar_t** ppszSrc, + __out size_t* pcchSrcLength, + __in const size_t cchMax, + __in DWORD dwFlags); + +NTSTRSAFEWORKERDDI +RtlUnicodeStringValidateDestWorker( + __in PCUNICODE_STRING DestinationString, + __deref_out_ecount(*pcchDest) wchar_t** ppszDest, + __out size_t* pcchDest, + __out_opt size_t* pcchDestLength, + __in const size_t cchMax, + __in DWORD dwFlags); + +NTSTRSAFEWORKERDDI +RtlStringCopyWideCharArrayWorker( + __out_ecount(cchDest) NTSTRSAFE_PWSTR pszDest, + __in size_t cchDest, + __out_opt size_t* pcchNewDestLength, + __in_ecount(cchSrcLength) const wchar_t* pszSrc, + __in size_t cchSrcLength); + +NTSTRSAFEWORKERDDI +RtlWideCharArrayCopyStringWorker( + __out_ecount(cchDest) wchar_t* pszDest, + __in size_t cchDest, + __out size_t* pcchNewDestLength, + __in NTSTRSAFE_PCWSTR pszSrc, + __in size_t cchToCopy); + +NTSTRSAFEWORKERDDI +RtlWideCharArrayCopyWorker( + __out_ecount(cchDest) wchar_t* pszDest, + __in size_t cchDest, + __out size_t* pcchNewDestLength, + __in_ecount(cchSrcLength) const wchar_t* pszSrc, + __in size_t cchSrcLength); + +NTSTRSAFEWORKERDDI +RtlWideCharArrayVPrintfWorker( + __out_ecount(cchDest) wchar_t* pszDest, + __in size_t cchDest, + __out size_t* pcchNewDestLength, + __in __format_string NTSTRSAFE_PCWSTR pszFormat, + __in va_list argList); + +NTSTRSAFEWORKERDDI +RtlUnicodeStringExHandleFill( + __out_ecount(cchRemaining) wchar_t* pszDestEnd, + __in size_t cchRemaining, + __in DWORD dwFlags); + +NTSTRSAFEWORKERDDI +RtlUnicodeStringExHandleOtherFlags( + __inout_ecount(cchDest) wchar_t* pszDest, + __in size_t cchDest, + __in size_t cchOriginalDestLength, + __out size_t* pcchNewDestLength, + __deref_out_ecount(*pcchRemaining) wchar_t** ppszDestEnd, + __out size_t* pcchRemaining, + __in DWORD dwFlags); + +#endif // !NTSTRSAFE_NO_UNICODE_STRING_FUNCTIONS + + +// To allow this to stand alone. +#define __WARNING_CYCLOMATIC_COMPLEXITY 28734 +#define __WARNING_DEREF_NULL_PTR 6011 +#define __WARNING_INVALID_PARAM_VALUE_1 6387 +#define __WARNING_POTENTIAL_BUFFER_OVERFLOW_HIGH_PRIORITY 26015 +#define __WARNING_RETURNING_BAD_RESULT 28196 +#define __WARNING_BANNED_API_USAGE 28719 + +#pragma warning(push) +#if _MSC_VER <= 1400 +#pragma warning(disable: 4616) // turn off warning out of range so prefast pragmas won't show + // show up in build.wrn/build.err +#endif +#pragma warning(disable : 4996) // 'function': was declared deprecated +#pragma warning(disable : 4995) // name was marked as #pragma deprecated +#pragma warning(disable : 4793) // vararg causes native code generation +#pragma warning(disable : __WARNING_CYCLOMATIC_COMPLEXITY) + + +#ifndef NTSTRSAFE_LIB_IMPL + +#ifndef NTSTRSAFE_NO_CCH_FUNCTIONS +/*++ + +NTSTATUS +RtlStringCchCopy( + __out_ecount(cchDest) LPTSTR pszDest, + __in size_t cchDest, + __in LPCTSTR pszSrc + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strcpy'. + The size of the destination buffer (in characters) is a parameter and + this function will not write past the end of this buffer and it will + ALWAYS null terminate the destination buffer (unless it is zero length). + + This routine is not a replacement for strncpy. That function will pad the + destination string with extra null termination characters if the count is + greater than the length of the source string, and it will fail to null + terminate the destination string if the source string length is greater + than or equal to the count. You can not blindly use this instead of strncpy: + it is common for code to use it to "patch" strings and you would introduce + errors if the code started null terminating in the middle of the string. + + This function returns an NTSTATUS value, and not a pointer. It returns + STATUS_SUCCESS if the string was copied without truncation and null terminated, + otherwise it will return a failure code. In failure cases as much of + pszSrc will be copied to pszDest as possible, and pszDest will be null + terminated. + +Arguments: + + pszDest - destination string + + cchDest - size of destination buffer in characters. + length must be = (_tcslen(src) + 1) to hold all of the + source including the null terminator + + pszSrc - source string which must be null terminated + +Notes: + Behavior is undefined if source and destination strings overlap. + + pszDest and pszSrc should not be NULL. See RtlStringCchCopyEx if you require + the handling of NULL values. + +Return Value: + + STATUS_SUCCESS - if there was source data and it was all copied and the + resultant dest string was null terminated + + failure - the operation did not succeed + + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the copy + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result and is + null terminated. This is useful for situations where + truncation is ok + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function. + +--*/ + +NTSTRSAFEDDI +RtlStringCchCopyA( + __out_ecount(cchDest) NTSTRSAFE_PSTR pszDest, + __in size_t cchDest, + __in NTSTRSAFE_PCSTR pszSrc) +{ + NTSTATUS status; + + status = RtlStringValidateDestA(pszDest, cchDest, NTSTRSAFE_MAX_CCH); + + if (NT_SUCCESS(status)) + { + status = RtlStringCopyWorkerA(pszDest, + cchDest, + NULL, + pszSrc, + NTSTRSAFE_MAX_LENGTH); + } + + return status; +} + +NTSTRSAFEDDI +RtlStringCchCopyW( + __out_ecount(cchDest) NTSTRSAFE_PWSTR pszDest, + __in size_t cchDest, + __in NTSTRSAFE_PCWSTR pszSrc) +{ + NTSTATUS status; + + status = RtlStringValidateDestW(pszDest, cchDest, NTSTRSAFE_MAX_CCH); + + if (NT_SUCCESS(status)) + { + status = RtlStringCopyWorkerW(pszDest, + cchDest, + NULL, + pszSrc, + NTSTRSAFE_MAX_LENGTH); + } + + return status; +} +#endif // !NTSTRSAFE_NO_CCH_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CB_FUNCTIONS +/*++ + +NTSTATUS +RtlStringCbCopy( + __out_bcount(cbDest) LPTSTR pszDest, + __in size_t cbDest, + __in LPCTSTR pszSrc + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strcpy'. + The size of the destination buffer (in bytes) is a parameter and this + function will not write past the end of this buffer and it will ALWAYS + null terminate the destination buffer (unless it is zero length). + + This routine is not a replacement for strncpy. That function will pad the + destination string with extra null termination characters if the count is + greater than the length of the source string, and it will fail to null + terminate the destination string if the source string length is greater + than or equal to the count. You can not blindly use this instead of strncpy: + it is common for code to use it to "patch" strings and you would introduce + errors if the code started null terminating in the middle of the string. + + This function returns an NTSTATUS value, and not a pointer. It returns + STATUS_SUCCESS if the string was copied without truncation and null terminated, + otherwise it will return a failure code. In failure cases as much of pszSrc + will be copied to pszDest as possible, and pszDest will be null terminated. + +Arguments: + + pszDest - destination string + + cbDest - size of destination buffer in bytes. + length must be = ((_tcslen(src) + 1) * sizeof(TCHAR)) to + hold all of the source including the null terminator + + pszSrc - source string which must be null terminated + +Notes: + Behavior is undefined if source and destination strings overlap. + + pszDest and pszSrc should not be NULL. See RtlStringCbCopyEx if you require + the handling of NULL values. + +Return Value: + + STATUS_SUCCESS - if there was source data and it was all copied and the + resultant dest string was null terminated + + failure - the operation did not succeed + + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the copy + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result and is + null terminated. This is useful for situations where + truncation is ok + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function. + +--*/ + +NTSTRSAFEDDI +RtlStringCbCopyA( + __out_bcount(cbDest) NTSTRSAFE_PSTR pszDest, + __in size_t cbDest, + __in NTSTRSAFE_PCSTR pszSrc) +{ + NTSTATUS status; + size_t cchDest = cbDest / sizeof(char); + + status = RtlStringValidateDestA(pszDest, cchDest, NTSTRSAFE_MAX_CCH); + + if (NT_SUCCESS(status)) + { + status = RtlStringCopyWorkerA(pszDest, + cchDest, + NULL, + pszSrc, + NTSTRSAFE_MAX_LENGTH); + } + + return status; +} + +NTSTRSAFEDDI +RtlStringCbCopyW( + __out_bcount(cbDest) NTSTRSAFE_PWSTR pszDest, + __in size_t cbDest, + __in NTSTRSAFE_PCWSTR pszSrc) +{ + NTSTATUS status; + size_t cchDest = cbDest / sizeof(wchar_t); + + status = RtlStringValidateDestW(pszDest, cchDest, NTSTRSAFE_MAX_CCH); + + if (NT_SUCCESS(status)) + { + status = RtlStringCopyWorkerW(pszDest, + cchDest, + NULL, + pszSrc, + NTSTRSAFE_MAX_LENGTH); + } + + return status; +} +#endif // !NTSTRSAFE_NO_CB_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CCH_FUNCTIONS +/*++ + +NTSTATUS +RtlStringCchCopyEx( + __out_ecount(cchDest) LPTSTR pszDest OPTIONAL, + __in size_t cchDest, + __in LPCTSTR pszSrc OPTIONAL, + __deref_opt_out_ecount(*pcchRemaining) LPTSTR* ppszDestEnd OPTIONAL, + __out_opt size_t* pcchRemaining OPTIONAL, + __in DWORD dwFlags + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strcpy' with + some additional parameters. In addition to functionality provided by + RtlStringCchCopy, this routine also returns a pointer to the end of the + destination string and the number of characters left in the destination string + including the null terminator. The flags parameter allows additional controls. + +Arguments: + + pszDest - destination string + + cchDest - size of destination buffer in characters. + length must be = (_tcslen(pszSrc) + 1) to hold all of + the source including the null terminator + + pszSrc - source string which must be null terminated + + ppszDestEnd - if ppszDestEnd is non-null, the function will return a + pointer to the end of the destination string. If the + function copied any data, the result will point to the + null termination character + + pcchRemaining - if pcchRemaining is non-null, the function will return the + number of characters left in the destination string, + including the null terminator + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND_NULL + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + behind the null terminator + + STRSAFE_IGNORE_NULLS + treat NULL string pointers like empty strings (TEXT("")). + this flag is useful for emulating functions like lstrcpy + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer, and it will + be null terminated. This will overwrite any truncated + string returned when the failure is + STATUS_BUFFER_OVERFLOW + + STRSAFE_NO_TRUNCATION / + STRSAFE_NULL_ON_FAILURE + if the function fails, the destination buffer will be set + to the empty string. This will overwrite any truncated string + returned when the failure is STATUS_BUFFER_OVERFLOW. + +Notes: + Behavior is undefined if source and destination strings overlap. + + pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag + is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc + may be NULL. An error may still be returned even though NULLS are ignored + due to insufficient space. + +Return Value: + + STATUS_SUCCESS - if there was source data and it was all copied and the + resultant dest string was null terminated + + failure - the operation did not succeed + + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the copy + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result and is + null terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlStringCchCopyExA( + __out_ecount(cchDest) NTSTRSAFE_PSTR pszDest, + __in size_t cchDest, + __in NTSTRSAFE_PCSTR pszSrc, + __deref_opt_out_ecount(*pcchRemaining) NTSTRSAFE_PSTR* ppszDestEnd, + __out_opt size_t* pcchRemaining, + __in DWORD dwFlags) +{ + NTSTATUS status; + + status = RtlStringExValidateDestA(pszDest, cchDest, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + NTSTRSAFE_PSTR pszDestEnd = pszDest; + size_t cchRemaining = cchDest; + + status = RtlStringExValidateSrcA(&pszSrc, NULL, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + + if (cchDest != 0) + { + *pszDest = '\0'; + } + } + else if (cchDest == 0) + { + // only fail if there was actually src data to copy + if (*pszSrc != '\0') + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + size_t cchCopied = 0; + + status = RtlStringCopyWorkerA(pszDest, + cchDest, + &cchCopied, + pszSrc, + NTSTRSAFE_MAX_LENGTH); + + pszDestEnd = pszDest + cchCopied; + cchRemaining = cchDest - cchCopied; + + if (NT_SUCCESS(status) && + (dwFlags & STRSAFE_FILL_BEHIND_NULL) && + (cchRemaining > 1)) + { + size_t cbRemaining; + + // safe to multiply cchRemaining * sizeof(char) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(char) is 1 + cbRemaining = cchRemaining * sizeof(char); + + // handle the STRSAFE_FILL_BEHIND_NULL flag + RtlStringExHandleFillBehindNullA(pszDestEnd, cbRemaining, dwFlags); + } + } + } + else + { + if (cchDest != 0) + { + *pszDest = '\0'; + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)) && + (cchDest != 0)) + { + size_t cbDest; + + // safe to multiply cchDest * sizeof(char) since cchDest < NTSTRSAFE_MAX_CCH and sizeof(char) is 1 + cbDest = cchDest * sizeof(char); + + // handle the STRSAFE_FILL_ON_FAILURE, STRSAFE_NULL_ON_FAILURE, and STRSAFE_NO_TRUNCATION flags + RtlStringExHandleOtherFlagsA(pszDest, + cbDest, + 0, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcchRemaining) + { + *pcchRemaining = cchRemaining; + } + } + } + + return status; +} + +NTSTRSAFEDDI +RtlStringCchCopyExW( + __out_ecount(cchDest) NTSTRSAFE_PWSTR pszDest, + __in size_t cchDest, + __in NTSTRSAFE_PCWSTR pszSrc, + __deref_opt_out_ecount(*pcchRemaining) NTSTRSAFE_PWSTR* ppszDestEnd, + __out_opt size_t* pcchRemaining, + __in DWORD dwFlags) +{ + NTSTATUS status; + + status = RtlStringExValidateDestW(pszDest, cchDest, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + NTSTRSAFE_PWSTR pszDestEnd = pszDest; + size_t cchRemaining = cchDest; + + status = RtlStringExValidateSrcW(&pszSrc, NULL, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + + if (cchDest != 0) + { + *pszDest = L'\0'; + } + } + else if (cchDest == 0) + { + // only fail if there was actually src data to copy + if (*pszSrc != L'\0') + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + size_t cchCopied = 0; + + status = RtlStringCopyWorkerW(pszDest, + cchDest, + &cchCopied, + pszSrc, + NTSTRSAFE_MAX_LENGTH); + + pszDestEnd = pszDest + cchCopied; + cchRemaining = cchDest - cchCopied; + + if (NT_SUCCESS(status) && + (dwFlags & STRSAFE_FILL_BEHIND_NULL) && + (cchRemaining > 1)) + { + size_t cbRemaining; + + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + cbRemaining = cchRemaining * sizeof(wchar_t); + + // handle the STRSAFE_FILL_BEHIND_NULL flag + RtlStringExHandleFillBehindNullW(pszDestEnd, cbRemaining, dwFlags); + } + } + } + else + { + if (cchDest != 0) + { + *pszDest = L'\0'; + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)) && + (cchDest != 0)) + { + size_t cbDest; + + // safe to multiply cchDest * sizeof(wchar_t) since cchDest < NTSTRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + cbDest = cchDest * sizeof(wchar_t); + + // handle the STRSAFE_FILL_ON_FAILURE, STRSAFE_NULL_ON_FAILURE, and STRSAFE_NO_TRUNCATION flags + RtlStringExHandleOtherFlagsW(pszDest, + cbDest, + 0, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcchRemaining) + { + *pcchRemaining = cchRemaining; + } + } + } + + return status; +} +#endif // !NTSTRSAFE_NO_CCH_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CB_FUNCTIONS +/*++ + +NTSTATUS +RtlStringCbCopyEx( + __out_bcount(cbDest) LPTSTR pszDest OPTIONAL, + __in size_t cbDest, + __in LPCTSTR pszSrc OPTIONAL, + __deref_opt_out_bcount(*pcbRemaining) LPTSTR* ppszDestEnd OPTIONAL, + __out_opt size_t* pcbRemaining OPTIONAL, + __in DWORD dwFlags + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strcpy' with + some additional parameters. In addition to functionality provided by + RtlStringCbCopy, this routine also returns a pointer to the end of the + destination string and the number of bytes left in the destination string + including the null terminator. The flags parameter allows additional controls. + +Arguments: + + pszDest - destination string + + cbDest - size of destination buffer in bytes. + length must be ((_tcslen(pszSrc) + 1) * sizeof(TCHAR)) to + hold all of the source including the null terminator + + pszSrc - source string which must be null terminated + + ppszDestEnd - if ppszDestEnd is non-null, the function will return a + pointer to the end of the destination string. If the + function copied any data, the result will point to the + null termination character + + pcbRemaining - pcbRemaining is non-null,the function will return the + number of bytes left in the destination string, + including the null terminator + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND_NULL + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + behind the null terminator + + STRSAFE_IGNORE_NULLS + treat NULL string pointers like empty strings (TEXT("")). + this flag is useful for emulating functions like lstrcpy + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer, and it will + be null terminated. This will overwrite any truncated + string returned when the failure is + STATUS_BUFFER_OVERFLOW + + STRSAFE_NO_TRUNCATION / + STRSAFE_NULL_ON_FAILURE + if the function fails, the destination buffer will be set + to the empty string. This will overwrite any truncated string + returned when the failure is STATUS_BUFFER_OVERFLOW. + +Notes: + Behavior is undefined if source and destination strings overlap. + + pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag + is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc + may be NULL. An error may still be returned even though NULLS are ignored + due to insufficient space. + +Return Value: + + STATUS_SUCCESS - if there was source data and it was all copied and the + resultant dest string was null terminated + + failure - the operation did not succeed + + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the copy + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result and is + null terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlStringCbCopyExA( + __out_bcount(cbDest) NTSTRSAFE_PSTR pszDest, + __in size_t cbDest, + __in NTSTRSAFE_PCSTR pszSrc, + __deref_opt_out_bcount(*pcbRemaining) NTSTRSAFE_PSTR* ppszDestEnd, + __out_opt size_t* pcbRemaining, + __in DWORD dwFlags) +{ + NTSTATUS status; + size_t cchDest = cbDest / sizeof(char); + + status = RtlStringExValidateDestA(pszDest, cchDest, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + NTSTRSAFE_PSTR pszDestEnd = pszDest; + size_t cchRemaining = cchDest; + + status = RtlStringExValidateSrcA(&pszSrc, NULL, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + + if (cchDest != 0) + { + *pszDest = '\0'; + } + } + else if (cchDest == 0) + { + // only fail if there was actually src data to copy + if (*pszSrc != '\0') + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + size_t cchCopied = 0; + + status = RtlStringCopyWorkerA(pszDest, + cchDest, + &cchCopied, + pszSrc, + NTSTRSAFE_MAX_LENGTH); + + pszDestEnd = pszDest + cchCopied; + cchRemaining = cchDest - cchCopied; + + if (NT_SUCCESS(status) && + (dwFlags & STRSAFE_FILL_BEHIND_NULL) && + (cchRemaining > 1)) + { + size_t cbRemaining; + + // safe to multiply cchRemaining * sizeof(char) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(char) is 1 + cbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)); + + // handle the STRSAFE_FILL_BEHIND_NULL flag + RtlStringExHandleFillBehindNullA(pszDestEnd, cbRemaining, dwFlags); + } + } + } + else + { + if (cchDest != 0) + { + *pszDest = '\0'; + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)) && + (cbDest != 0)) + { + // handle the STRSAFE_FILL_ON_FAILURE, STRSAFE_NULL_ON_FAILURE, and STRSAFE_NO_TRUNCATION flags + RtlStringExHandleOtherFlagsA(pszDest, + cbDest, + 0, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcbRemaining) + { + // safe to multiply cchRemaining * sizeof(char) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(char) is 1 + *pcbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)); + } + } + } + + return status; +} + +NTSTRSAFEDDI +RtlStringCbCopyExW( + __out_bcount(cbDest) NTSTRSAFE_PWSTR pszDest, + __in size_t cbDest, + __in NTSTRSAFE_PCWSTR pszSrc, + __deref_opt_out_bcount(*pcbRemaining) NTSTRSAFE_PWSTR* ppszDestEnd, + __out_opt size_t* pcbRemaining, + __in DWORD dwFlags) +{ + NTSTATUS status; + size_t cchDest = cbDest / sizeof(wchar_t); + + status = RtlStringExValidateDestW(pszDest, cchDest, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + NTSTRSAFE_PWSTR pszDestEnd = pszDest; + size_t cchRemaining = cchDest; + + status = RtlStringExValidateSrcW(&pszSrc, NULL, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + + if (cchDest != 0) + { + *pszDest = L'\0'; + } + } + else if (cchDest == 0) + { + // only fail if there was actually src data to copy + if (*pszSrc != L'\0') + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + size_t cchCopied = 0; + + status = RtlStringCopyWorkerW(pszDest, + cchDest, + &cchCopied, + pszSrc, + NTSTRSAFE_MAX_LENGTH); + + pszDestEnd = pszDest + cchCopied; + cchRemaining = cchDest - cchCopied; + + if (NT_SUCCESS(status) && (dwFlags & STRSAFE_FILL_BEHIND_NULL)) + { + size_t cbRemaining; + + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + cbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + + // handle the STRSAFE_FILL_BEHIND_NULL flag + RtlStringExHandleFillBehindNullW(pszDestEnd, cbRemaining, dwFlags); + } + } + } + else + { + if (cchDest != 0) + { + *pszDest = L'\0'; + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)) && + (cbDest != 0)) + { + // handle the STRSAFE_FILL_ON_FAILURE, STRSAFE_NULL_ON_FAILURE, and STRSAFE_NO_TRUNCATION flags + RtlStringExHandleOtherFlagsW(pszDest, + cbDest, + 0, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcbRemaining) + { + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + *pcbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + } + } + } + + return status; +} +#endif // !NTSTRSAFE_NO_CB_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CCH_FUNCTIONS +/*++ + +NTSTATUS +RtlStringCchCopyN( + __out_ecount(cchDest) LPTSTR pszDest, + __in size_t cchDest, + __in LPCTSTR pszSrc, + __in size_t cchToCopy + ); + + +Routine Description: + + This routine is a safer version of the C built-in function 'strncpy'. + The size of the destination buffer (in characters) is a parameter and + this function will not write past the end of this buffer and it will + ALWAYS null terminate the destination buffer (unless it is zero length). + + This routine is meant as a replacement for strncpy, but it does behave + differently. This function will not pad the destination buffer with extra + null termination characters if cchToCopy is greater than the length of pszSrc. + + This function returns an NTSTATUS value, and not a pointer. It returns + STATUS_SUCCESS if the entire string or the first cchToCopy characters were copied + without truncation and the resultant destination string was null terminated, + otherwise it will return a failure code. In failure cases as much of pszSrc + will be copied to pszDest as possible, and pszDest will be null terminated. + +Arguments: + + pszDest - destination string + + cchDest - size of destination buffer in characters. + length must be = (_tcslen(src) + 1) to hold all of the + source including the null terminator + + pszSrc - source string + + cchToCopy - maximum number of characters to copy from source string, + not including the null terminator. + +Notes: + Behavior is undefined if source and destination strings overlap. + + pszDest and pszSrc should not be NULL. See RtlStringCchCopyNEx if you require + the handling of NULL values. + +Return Value: + + STATUS_SUCCESS - if there was source data and it was all copied and the + resultant dest string was null terminated + + failure - the operation did not succeed + + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the copy + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result and is + null terminated. This is useful for situations where + truncation is ok + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function. + +--*/ + +NTSTRSAFEDDI +RtlStringCchCopyNA( + __out_ecount(cchDest) NTSTRSAFE_PSTR pszDest, + __in size_t cchDest, + __in_ecount(cchToCopy) STRSAFE_PCNZCH pszSrc, + __in size_t cchToCopy) +{ + NTSTATUS status; + + status = RtlStringValidateDestA(pszDest, cchDest, NTSTRSAFE_MAX_CCH); + + if (NT_SUCCESS(status)) + { + if (cchToCopy > NTSTRSAFE_MAX_LENGTH) + { + status = STATUS_INVALID_PARAMETER; + + *pszDest = '\0'; + } + else + { + status = RtlStringCopyWorkerA(pszDest, + cchDest, + NULL, + pszSrc, + cchToCopy); + } + } + + return status; +} + +NTSTRSAFEDDI +RtlStringCchCopyNW( + __out_ecount(cchDest) NTSTRSAFE_PWSTR pszDest, + __in size_t cchDest, + __in_ecount(cchToCopy) STRSAFE_PCNZWCH pszSrc, + __in size_t cchToCopy) +{ + NTSTATUS status; + + status = RtlStringValidateDestW(pszDest, cchDest, NTSTRSAFE_MAX_CCH); + + if (NT_SUCCESS(status)) + { + if (cchToCopy > NTSTRSAFE_MAX_LENGTH) + { + status = STATUS_INVALID_PARAMETER; + + *pszDest = L'\0'; + } + else + { + status = RtlStringCopyWorkerW(pszDest, + cchDest, + NULL, + pszSrc, + cchToCopy); + } + } + + return status; +} +#endif // !NTSTRSAFE_NO_CCH_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CB_FUNCTIONS +/*++ + +NTSTATUS +RtlStringCbCopyN( + __out_bcount(cbDest) LPTSTR pszDest, + __in size_t cbDest, + __in LPCTSTR pszSrc, + __in size_t cbToCopy + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strncpy'. + The size of the destination buffer (in bytes) is a parameter and this + function will not write past the end of this buffer and it will ALWAYS + null terminate the destination buffer (unless it is zero length). + + This routine is meant as a replacement for strncpy, but it does behave + differently. This function will not pad the destination buffer with extra + null termination characters if cbToCopy is greater than the size of pszSrc. + + This function returns an NTSTATUS value, and not a pointer. It returns + STATUS_SUCCESS if the entire string or the first cbToCopy characters were + copied without truncation and the resultant destination string was null + terminated, otherwise it will return a failure code. In failure cases as + much of pszSrc will be copied to pszDest as possible, and pszDest will be + null terminated. + +Arguments: + + pszDest - destination string + + cbDest - size of destination buffer in bytes. + length must be = ((_tcslen(src) + 1) * sizeof(TCHAR)) to + hold all of the source including the null terminator + + pszSrc - source string + + cbToCopy - maximum number of bytes to copy from source string, + not including the null terminator. + +Notes: + Behavior is undefined if source and destination strings overlap. + + pszDest and pszSrc should not be NULL. See RtlStringCbCopyEx if you require + the handling of NULL values. + +Return Value: + + STATUS_SUCCESS - if there was source data and it was all copied and the + resultant dest string was null terminated + + failure - the operation did not succeed + + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the copy + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result and is + null terminated. This is useful for situations where + truncation is ok + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function. + +--*/ + +NTSTRSAFEDDI +RtlStringCbCopyNA( + __out_bcount(cbDest) NTSTRSAFE_PSTR pszDest, + __in size_t cbDest, + __in_bcount(cbToCopy) STRSAFE_PCNZCH pszSrc, + __in size_t cbToCopy) +{ + NTSTATUS status; + size_t cchDest = cbDest / sizeof(char); + + status = RtlStringValidateDestA(pszDest, cchDest, NTSTRSAFE_MAX_CCH); + + if (NT_SUCCESS(status)) + { + size_t cchToCopy = cbToCopy / sizeof(char); + + if (cchToCopy > NTSTRSAFE_MAX_LENGTH) + { + status = STATUS_INVALID_PARAMETER; + + *pszDest = '\0'; + } + else + { + status = RtlStringCopyWorkerA(pszDest, + cchDest, + NULL, + pszSrc, + cchToCopy); + } + } + + return status; +} + +NTSTRSAFEDDI +RtlStringCbCopyNW( + __out_bcount(cbDest) NTSTRSAFE_PWSTR pszDest, + __in size_t cbDest, + __in_bcount(cbToCopy) STRSAFE_PCNZWCH pszSrc, + __in size_t cbToCopy) +{ + NTSTATUS status; + size_t cchDest = cbDest / sizeof(wchar_t); + + status = RtlStringValidateDestW(pszDest, cchDest, NTSTRSAFE_MAX_CCH); + + if (NT_SUCCESS(status)) + { + size_t cchToCopy = cbToCopy / sizeof(wchar_t); + + if (cchToCopy > NTSTRSAFE_MAX_LENGTH) + { + status = STATUS_INVALID_PARAMETER; + + // Suppress espx false positive - cchDest cannot be 0 here +#pragma warning(push) +#pragma warning(disable : __WARNING_POTENTIAL_BUFFER_OVERFLOW_HIGH_PRIORITY) + *pszDest = L'\0'; +#pragma warning(pop) + } + else + { + status = RtlStringCopyWorkerW(pszDest, + cchDest, + NULL, + pszSrc, + cchToCopy); + } + } + + return status; +} +#endif // !NTSTRSAFE_NO_CB_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CCH_FUNCTIONS +/*++ + +NTSTATUS +RtlStringCchCopyNEx( + __out_ecount(cchDest) LPTSTR pszDest OPTIONAL, + __in size_t cchDest, + __in LPCTSTR pszSrc OPTIONAL, + __in size_t cchToCopy, + __deref_opt_out_ecount(*pcchRemaining) LPTSTR* ppszDestEnd OPTIONAL, + __out_opt size_t* pcchRemaining OPTIONAL, + __in DWORD dwFlags + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strncpy' with + some additional parameters. In addition to functionality provided by + RtlStringCchCopyN, this routine also returns a pointer to the end of the + destination string and the number of characters left in the destination + string including the null terminator. The flags parameter allows + additional controls. + + This routine is meant as a replacement for strncpy, but it does behave + differently. This function will not pad the destination buffer with extra + null termination characters if cchToCopy is greater than the length of pszSrc. + +Arguments: + + pszDest - destination string + + cchDest - size of destination buffer in characters. + length must be = (_tcslen(pszSrc) + 1) to hold all of + the source including the null terminator + + pszSrc - source string + + cchToCopy - maximum number of characters to copy from the source + string + + ppszDestEnd - if ppszDestEnd is non-null, the function will return a + pointer to the end of the destination string. If the + function copied any data, the result will point to the + null termination character + + pcchRemaining - if pcchRemaining is non-null, the function will return the + number of characters left in the destination string, + including the null terminator + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND_NULL + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + behind the null terminator + + STRSAFE_IGNORE_NULLS + treat NULL string pointers like empty strings (TEXT("")). + this flag is useful for emulating functions like lstrcpy + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer, and it will + be null terminated. This will overwrite any truncated + string returned when the failure is + STATUS_BUFFER_OVERFLOW + + STRSAFE_NO_TRUNCATION / + STRSAFE_NULL_ON_FAILURE + if the function fails, the destination buffer will be set + to the empty string. This will overwrite any truncated string + returned when the failure is STATUS_BUFFER_OVERFLOW. + +Notes: + Behavior is undefined if source and destination strings overlap. + + pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag + is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc + may be NULL. An error may still be returned even though NULLS are ignored + due to insufficient space. + +Return Value: + + STATUS_SUCCESS - if there was source data and it was all copied and the + resultant dest string was null terminated + + failure - the operation did not succeed + + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the copy + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result and is + null terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlStringCchCopyNExA( + __out_ecount(cchDest) NTSTRSAFE_PSTR pszDest, + __in size_t cchDest, + __in_ecount(cchToCopy) STRSAFE_PCNZCH pszSrc, + __in size_t cchToCopy, + __deref_opt_out_ecount(*pcchRemaining) NTSTRSAFE_PSTR* ppszDestEnd, + __out_opt size_t* pcchRemaining, + __in DWORD dwFlags) +{ + NTSTATUS status; + + status = RtlStringExValidateDestA(pszDest, cchDest, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + NTSTRSAFE_PSTR pszDestEnd = pszDest; + size_t cchRemaining = cchDest; + + status = RtlStringExValidateSrcA(&pszSrc, &cchToCopy, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + + if (cchDest != 0) + { + *pszDest = '\0'; + } + } + else if (cchDest == 0) + { + // only fail if there was actually src data to copy + if ((cchToCopy != 0) && (*pszSrc != '\0')) + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + size_t cchCopied = 0; + + status = RtlStringCopyWorkerA(pszDest, + cchDest, + &cchCopied, + pszSrc, + cchToCopy); + + pszDestEnd = pszDest + cchCopied; + cchRemaining = cchDest - cchCopied; + + if (NT_SUCCESS(status) && + (dwFlags & STRSAFE_FILL_BEHIND_NULL) && + (cchRemaining > 1)) + { + size_t cbRemaining; + + // safe to multiply cchRemaining * sizeof(char) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(char) is 1 + cbRemaining = cchRemaining * sizeof(char); + + // handle the STRSAFE_FILL_BEHIND_NULL flag + RtlStringExHandleFillBehindNullA(pszDestEnd, cbRemaining, dwFlags); + } + } + } + else + { + if (cchDest != 0) + { + *pszDest = '\0'; + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)) && + (cchDest != 0)) + { + size_t cbDest; + + // safe to multiply cchDest * sizeof(char) since cchDest < NTSTRSAFE_MAX_CCH and sizeof(char) is 1 + cbDest = cchDest * sizeof(char); + + // handle the STRSAFE_FILL_ON_FAILURE, STRSAFE_NULL_ON_FAILURE, and STRSAFE_NO_TRUNCATION flags + RtlStringExHandleOtherFlagsA(pszDest, + cbDest, + 0, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcchRemaining) + { + *pcchRemaining = cchRemaining; + } + } + } + + return status; +} + +NTSTRSAFEDDI +RtlStringCchCopyNExW( + __out_ecount(cchDest) NTSTRSAFE_PWSTR pszDest, + __in size_t cchDest, + __in_ecount(cchToCopy) STRSAFE_PCNZWCH pszSrc, + __in size_t cchToCopy, + __deref_opt_out_ecount(*pcchRemaining) NTSTRSAFE_PWSTR* ppszDestEnd, + __out_opt size_t* pcchRemaining, + __in DWORD dwFlags) +{ + NTSTATUS status; + + status = RtlStringExValidateDestW(pszDest, cchDest, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + NTSTRSAFE_PWSTR pszDestEnd = pszDest; + size_t cchRemaining = cchDest; + + status = RtlStringExValidateSrcW(&pszSrc, &cchToCopy, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + + if (cchDest != 0) + { + *pszDest = L'\0'; + } + } + else if (cchDest == 0) + { + // only fail if there was actually src data to copy + if ((cchToCopy != 0) && (*pszSrc != L'\0')) + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + size_t cchCopied = 0; + + status = RtlStringCopyWorkerW(pszDest, + cchDest, + &cchCopied, + pszSrc, + cchToCopy); + + pszDestEnd = pszDest + cchCopied; + cchRemaining = cchDest - cchCopied; + + if (NT_SUCCESS(status) && + (dwFlags & STRSAFE_FILL_BEHIND_NULL) && + (cchRemaining > 1)) + { + size_t cbRemaining; + + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + cbRemaining = cchRemaining * sizeof(wchar_t); + + // handle the STRSAFE_FILL_BEHIND_NULL flag + RtlStringExHandleFillBehindNullW(pszDestEnd, cbRemaining, dwFlags); + } + } + } + else + { + if (cchDest != 0) + { + *pszDest = L'\0'; + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)) && + (cchDest != 0)) + { + size_t cbDest; + + // safe to multiply cchDest * sizeof(wchar_t) since cchDest < NTSTRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + cbDest = cchDest * sizeof(wchar_t); + + // handle the STRSAFE_FILL_ON_FAILURE, STRSAFE_NULL_ON_FAILURE, and STRSAFE_NO_TRUNCATION flags + RtlStringExHandleOtherFlagsW(pszDest, + cbDest, + 0, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcchRemaining) + { + *pcchRemaining = cchRemaining; + } + } + } + + return status; +} +#endif // !NTSTRSAFE_NO_CCH_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CB_FUNCTIONS +/*++ + +NTSTATUS +RtlStringCbCopyNEx( + __out_bcount(cbDest) LPTSTR pszDest OPTIONAL, + __in size_t cbDest, + __in LPCTSTR pszSrc OPTIONAL, + __in size_t cbToCopy, + __deref_opt_out_bcount(*pcbRemaining) LPTSTR* ppszDestEnd OPTIONAL, + __out_opt size_t* pcbRemaining OPTIONAL, + __in DWORD dwFlags + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strncpy' with + some additional parameters. In addition to functionality provided by + RtlStringCbCopyN, this routine also returns a pointer to the end of the + destination string and the number of bytes left in the destination string + including the null terminator. The flags parameter allows additional controls. + + This routine is meant as a replacement for strncpy, but it does behave + differently. This function will not pad the destination buffer with extra + null termination characters if cbToCopy is greater than the size of pszSrc. + +Arguments: + + pszDest - destination string + + cbDest - size of destination buffer in bytes. + length must be ((_tcslen(pszSrc) + 1) * sizeof(TCHAR)) to + hold all of the source including the null terminator + + pszSrc - source string + + cbToCopy - maximum number of bytes to copy from source string + + ppszDestEnd - if ppszDestEnd is non-null, the function will return a + pointer to the end of the destination string. If the + function copied any data, the result will point to the + null termination character + + pcbRemaining - pcbRemaining is non-null,the function will return the + number of bytes left in the destination string, + including the null terminator + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND_NULL + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + behind the null terminator + + STRSAFE_IGNORE_NULLS + treat NULL string pointers like empty strings (TEXT("")). + this flag is useful for emulating functions like lstrcpy + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer, and it will + be null terminated. This will overwrite any truncated + string returned when the failure is + STATUS_BUFFER_OVERFLOW + + STRSAFE_NO_TRUNCATION / + STRSAFE_NULL_ON_FAILURE + if the function fails, the destination buffer will be set + to the empty string. This will overwrite any truncated string + returned when the failure is STATUS_BUFFER_OVERFLOW. + +Notes: + Behavior is undefined if source and destination strings overlap. + + pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag + is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc + may be NULL. An error may still be returned even though NULLS are ignored + due to insufficient space. + +Return Value: + + STATUS_SUCCESS - if there was source data and it was all copied and the + resultant dest string was null terminated + + failure - the operation did not succeed + + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the copy + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result and is + null terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlStringCbCopyNExA( + __out_bcount(cbDest) NTSTRSAFE_PSTR pszDest, + __in size_t cbDest, + __in_bcount(cbToCopy) STRSAFE_PCNZCH pszSrc, + __in size_t cbToCopy, + __deref_opt_out_bcount(*pcbRemaining) NTSTRSAFE_PSTR* ppszDestEnd, + __out_opt size_t* pcbRemaining, + __in DWORD dwFlags) +{ + NTSTATUS status; + size_t cchDest = cbDest / sizeof(char); + + status = RtlStringExValidateDestA(pszDest, cchDest, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + NTSTRSAFE_PSTR pszDestEnd = pszDest; + size_t cchRemaining = cchDest; + size_t cchToCopy = cbToCopy / sizeof(char); + + status = RtlStringExValidateSrcA(&pszSrc, &cchToCopy, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + + if (cchDest != 0) + { + *pszDest = '\0'; + } + } + else if (cchDest == 0) + { + // only fail if there was actually src data to copy + if ((cchToCopy != 0) && (*pszSrc != '\0')) + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + size_t cchCopied = 0; + + status = RtlStringCopyWorkerA(pszDest, + cchDest, + &cchCopied, + pszSrc, + cchToCopy); + + pszDestEnd = pszDest + cchCopied; + cchRemaining = cchDest - cchCopied; + + if (NT_SUCCESS(status) && + (dwFlags & STRSAFE_FILL_BEHIND_NULL) && + (cchRemaining > 1)) + { + size_t cbRemaining; + + // safe to multiply cchRemaining * sizeof(char) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(char) is 1 + cbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)); + + // handle the STRSAFE_FILL_BEHIND_NULL flag + RtlStringExHandleFillBehindNullA(pszDestEnd, cbRemaining, dwFlags); + } + } + } + else + { + if (cchDest != 0) + { + *pszDest = '\0'; + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)) && + (cbDest != 0)) + { + // handle the STRSAFE_FILL_ON_FAILURE, STRSAFE_NULL_ON_FAILURE, and STRSAFE_NO_TRUNCATION flags + RtlStringExHandleOtherFlagsA(pszDest, + cbDest, + 0, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcbRemaining) + { + // safe to multiply cchRemaining * sizeof(char) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(char) is 1 + *pcbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)); + } + } + } + + return status; +} + +NTSTRSAFEDDI +RtlStringCbCopyNExW( + __out_bcount(cbDest) NTSTRSAFE_PWSTR pszDest, + __in size_t cbDest, + __in_bcount(cbToCopy) STRSAFE_PCNZWCH pszSrc, + __in size_t cbToCopy, + __deref_opt_out_bcount(*pcbRemaining) NTSTRSAFE_PWSTR* ppszDestEnd, + __out_opt size_t* pcbRemaining, + __in DWORD dwFlags) +{ + NTSTATUS status; + size_t cchDest = cbDest / sizeof(wchar_t); + + status = RtlStringExValidateDestW(pszDest, cchDest, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + NTSTRSAFE_PWSTR pszDestEnd = pszDest; + size_t cchRemaining = cchDest; + size_t cchToCopy = cbToCopy / sizeof(wchar_t); + +#pragma warning(push) +#pragma warning(disable : __WARNING_POTENTIAL_BUFFER_OVERFLOW_HIGH_PRIORITY) + status = RtlStringExValidateSrcW(&pszSrc, &cchToCopy, NTSTRSAFE_MAX_CCH, dwFlags); +#pragma warning(pop) + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + + if (cchDest != 0) + { + *pszDest = L'\0'; + } + } + else if (cchDest == 0) + { + // only fail if there was actually src data to copy + if ((cchToCopy != 0) && (*pszSrc != L'\0')) + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + size_t cchCopied = 0; + + status = RtlStringCopyWorkerW(pszDest, + cchDest, + &cchCopied, + pszSrc, + cchToCopy); + + pszDestEnd = pszDest + cchCopied; + cchRemaining = cchDest - cchCopied; + + if (NT_SUCCESS(status) && (dwFlags & STRSAFE_FILL_BEHIND_NULL)) + { + size_t cbRemaining; + + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + cbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + + // handle the STRSAFE_FILL_BEHIND_NULL flag + RtlStringExHandleFillBehindNullW(pszDestEnd, cbRemaining, dwFlags); + } + } + } + else + { + if (cchDest != 0) + { + *pszDest = L'\0'; + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)) && + (cbDest != 0)) + { + // handle the STRSAFE_FILL_ON_FAILURE, STRSAFE_NULL_ON_FAILURE, and STRSAFE_NO_TRUNCATION flags + RtlStringExHandleOtherFlagsW(pszDest, + cbDest, + 0, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcbRemaining) + { + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + *pcbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + } + } + } + + return status; +} +#endif // !NTSTRSAFE_NO_CB_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CCH_FUNCTIONS +/*++ + +NTSTATUS +RtlStringCchCat( + __inout_ecount(cchDest) LPTSTR pszDest, + __in size_t cchDest, + __in LPCTSTR pszSrc + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strcat'. + The size of the destination buffer (in characters) is a parameter and this + function will not write past the end of this buffer and it will ALWAYS + null terminate the destination buffer (unless it is zero length). + + This function returns an NTSTATUS value, and not a pointer. It returns + STATUS_SUCCESS if the string was concatenated without truncation and null terminated, + otherwise it will return a failure code. In failure cases as much of pszSrc + will be appended to pszDest as possible, and pszDest will be null + terminated. + +Arguments: + + pszDest - destination string which must be null terminated + + cchDest - size of destination buffer in characters. + length must be = (_tcslen(pszDest) + _tcslen(pszSrc) + 1) + to hold all of the combine string plus the null + terminator + + pszSrc - source string which must be null terminated + +Notes: + Behavior is undefined if source and destination strings overlap. + + pszDest and pszSrc should not be NULL. See RtlStringCchCatEx if you require + the handling of NULL values. + +Return Value: + + STATUS_SUCCESS - if there was source data and it was all concatenated and + the resultant dest string was null terminated + + failure - the operation did not succeed + + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the operation + failed due to insufficient space. When this error occurs, + the destination buffer is modified to contain a truncated + version of the ideal result and is null terminated. This + is useful for situations where truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlStringCchCatA( + __inout_ecount(cchDest) NTSTRSAFE_PSTR pszDest, + __in size_t cchDest, + __in NTSTRSAFE_PCSTR pszSrc) +{ + NTSTATUS status; + size_t cchDestLength; + + status = RtlStringValidateDestAndLengthA(pszDest, + cchDest, + &cchDestLength, + NTSTRSAFE_MAX_CCH); + + if (NT_SUCCESS(status)) + { + status = RtlStringCopyWorkerA(pszDest + cchDestLength, + cchDest - cchDestLength, + NULL, + pszSrc, + NTSTRSAFE_MAX_CCH); + } + + return status; +} + +NTSTRSAFEDDI +RtlStringCchCatW( + __inout_ecount(cchDest) NTSTRSAFE_PWSTR pszDest, + __in size_t cchDest, + __in NTSTRSAFE_PCWSTR pszSrc) +{ + NTSTATUS status; + size_t cchDestLength; + + status = RtlStringValidateDestAndLengthW(pszDest, + cchDest, + &cchDestLength, + NTSTRSAFE_MAX_CCH); + + if (NT_SUCCESS(status)) + { + status = RtlStringCopyWorkerW(pszDest + cchDestLength, + cchDest - cchDestLength, + NULL, + pszSrc, + NTSTRSAFE_MAX_CCH); + } + + return status; +} +#endif // !NTSTRSAFE_NO_CCH_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CB_FUNCTIONS +/*++ + +NTSTATUS +RtlStringCbCat( + __inout_bcount(cbDest) LPTSTR pszDest, + __in size_t cbDest, + __in LPCTSTR pszSrc + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strcat'. + The size of the destination buffer (in bytes) is a parameter and this + function will not write past the end of this buffer and it will ALWAYS + null terminate the destination buffer (unless it is zero length). + + This function returns an NTSTATUS value, and not a pointer. It returns + STATUS_SUCCESS if the string was concatenated without truncation and null terminated, + otherwise it will return a failure code. In failure cases as much of pszSrc + will be appended to pszDest as possible, and pszDest will be null + terminated. + +Arguments: + + pszDest - destination string which must be null terminated + + cbDest - size of destination buffer in bytes. + length must be = ((_tcslen(pszDest) + _tcslen(pszSrc) + 1) * sizeof(TCHAR) + to hold all of the combine string plus the null + terminator + + pszSrc - source string which must be null terminated + +Notes: + Behavior is undefined if source and destination strings overlap. + + pszDest and pszSrc should not be NULL. See RtlStringCbCatEx if you require + the handling of NULL values. + +Return Value: + + STATUS_SUCCESS - if there was source data and it was all concatenated and + the resultant dest string was null terminated + + failure - the operation did not succeed + + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the operation + failed due to insufficient space. When this error occurs, + the destination buffer is modified to contain a truncated + version of the ideal result and is null terminated. This + is useful for situations where truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlStringCbCatA( + __inout_bcount(cbDest) NTSTRSAFE_PSTR pszDest, + __in size_t cbDest, + __in NTSTRSAFE_PCSTR pszSrc) +{ + NTSTATUS status; + size_t cchDestLength; + size_t cchDest = cbDest / sizeof(char); + + status = RtlStringValidateDestAndLengthA(pszDest, + cchDest, + &cchDestLength, + NTSTRSAFE_MAX_CCH); + + if (NT_SUCCESS(status)) + { + status = RtlStringCopyWorkerA(pszDest + cchDestLength, + cchDest - cchDestLength, + NULL, + pszSrc, + NTSTRSAFE_MAX_CCH); + } + + return status; +} + +NTSTRSAFEDDI +RtlStringCbCatW( + __inout_bcount(cbDest) NTSTRSAFE_PWSTR pszDest, + __in size_t cbDest, + __in NTSTRSAFE_PCWSTR pszSrc) +{ + NTSTATUS status; + size_t cchDestLength; + size_t cchDest = cbDest / sizeof(wchar_t); + + status = RtlStringValidateDestAndLengthW(pszDest, + cchDest, + &cchDestLength, + NTSTRSAFE_MAX_CCH); + + if (NT_SUCCESS(status)) + { + status = RtlStringCopyWorkerW(pszDest + cchDestLength, + cchDest - cchDestLength, + NULL, + pszSrc, + NTSTRSAFE_MAX_CCH); + } + + return status; +} +#endif // !NTSTRSAFE_NO_CB_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CCH_FUNCTIONS +/*++ + +NTSTATUS +RtlStringCchCatEx( + __inout_ecount(cchDest) LPTSTR pszDest OPTIONAL, + __in size_t cchDest, + __in LPCTSTR pszSrc OPTIONAL, + __deref_opt_out_ecount(*pcchRemaining) LPTSTR* ppszDestEnd OPTIONAL, + __out_opt size_t* pcchRemaining OPTIONAL, + __in DWORD dwFlags + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strcat' with + some additional parameters. In addition to functionality provided by + RtlStringCchCat, this routine also returns a pointer to the end of the + destination string and the number of characters left in the destination string + including the null terminator. The flags parameter allows additional controls. + +Arguments: + + pszDest - destination string which must be null terminated + + cchDest - size of destination buffer in characters + length must be (_tcslen(pszDest) + _tcslen(pszSrc) + 1) + to hold all of the combine string plus the null + terminator. + + pszSrc - source string which must be null terminated + + ppszDestEnd - if ppszDestEnd is non-null, the function will return a + pointer to the end of the destination string. If the + function appended any data, the result will point to the + null termination character + + pcchRemaining - if pcchRemaining is non-null, the function will return the + number of characters left in the destination string, + including the null terminator + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND_NULL + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + behind the null terminator + + STRSAFE_IGNORE_NULLS + treat NULL string pointers like empty strings (TEXT("")). + this flag is useful for emulating functions like lstrcat + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer, and it will + be null terminated. This will overwrite any pre-existing + or truncated string + + STRSAFE_NULL_ON_FAILURE + if the function fails, the destination buffer will be set + to the empty string. This will overwrite any pre-existing or + truncated string + + STRSAFE_NO_TRUNCATION + if the function returns STATUS_BUFFER_OVERFLOW, pszDest + will not contain a truncated string, it will remain unchanged. + +Notes: + Behavior is undefined if source and destination strings overlap. + + pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag + is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc + may be NULL. An error may still be returned even though NULLS are ignored + due to insufficient space. + +Return Value: + + STATUS_SUCCESS - if there was source data and it was all concatenated and + the resultant dest string was null terminated + + failure - the operation did not succeed + + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the operation + failed due to insufficient space. When this error + occurs, the destination buffer is modified to contain + a truncated version of the ideal result and is null + terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlStringCchCatExA( + __inout_ecount(cchDest) NTSTRSAFE_PSTR pszDest, + __in size_t cchDest, + __in NTSTRSAFE_PCSTR pszSrc, + __deref_opt_out_ecount(*pcchRemaining) NTSTRSAFE_PSTR* ppszDestEnd, + __out_opt size_t* pcchRemaining, + __in DWORD dwFlags) +{ + NTSTATUS status; + size_t cchDestLength; + + status = RtlStringExValidateDestAndLengthA(pszDest, + cchDest, + &cchDestLength, + NTSTRSAFE_MAX_CCH, + dwFlags); + + if (NT_SUCCESS(status)) + { + NTSTRSAFE_PSTR pszDestEnd = pszDest + cchDestLength; + size_t cchRemaining = cchDest - cchDestLength; + + status = RtlStringExValidateSrcA(&pszSrc, NULL, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + } + else if (cchRemaining <= 1) + { + // only fail if there was actually src data to append + if (*pszSrc != '\0') + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + size_t cchCopied = 0; + + status = RtlStringCopyWorkerA(pszDestEnd, + cchRemaining, + &cchCopied, + pszSrc, + NTSTRSAFE_MAX_LENGTH); + + pszDestEnd = pszDestEnd + cchCopied; + cchRemaining = cchRemaining - cchCopied; + + if (NT_SUCCESS(status) && + (dwFlags & STRSAFE_FILL_BEHIND_NULL) && + (cchRemaining > 1)) + { + size_t cbRemaining; + + // safe to multiply cchRemaining * sizeof(char) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(char) is 1 + cbRemaining = cchRemaining * sizeof(char); + + // handle the STRSAFE_FILL_BEHIND_NULL flag + RtlStringExHandleFillBehindNullA(pszDestEnd, cbRemaining, dwFlags); + } + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)) && + (cchDest != 0)) + { + size_t cbDest; + + // safe to multiply cchDest * sizeof(char) since cchDest < NTSTRSAFE_MAX_CCH and sizeof(char) is 1 + cbDest = cchDest * sizeof(char); + + // handle the STRSAFE_FILL_ON_FAILURE, STRSAFE_NULL_ON_FAILURE, and STRSAFE_NO_TRUNCATION flags + RtlStringExHandleOtherFlagsA(pszDest, + cbDest, + cchDestLength, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcchRemaining) + { + *pcchRemaining = cchRemaining; + } + } + } + + return status; +} + +NTSTRSAFEDDI +RtlStringCchCatExW( + __inout_ecount(cchDest) NTSTRSAFE_PWSTR pszDest, + __in size_t cchDest, + __in NTSTRSAFE_PCWSTR pszSrc, + __deref_opt_out_ecount(*pcchRemaining) NTSTRSAFE_PWSTR* ppszDestEnd, + __out_opt size_t* pcchRemaining, + __in DWORD dwFlags) +{ + NTSTATUS status; + size_t cchDestLength; + + status = RtlStringExValidateDestAndLengthW(pszDest, + cchDest, + &cchDestLength, + NTSTRSAFE_MAX_CCH, + dwFlags); + + if (NT_SUCCESS(status)) + { + NTSTRSAFE_PWSTR pszDestEnd = pszDest + cchDestLength; + size_t cchRemaining = cchDest - cchDestLength; + + status = RtlStringExValidateSrcW(&pszSrc, NULL, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + } + else if (cchRemaining <= 1) + { + // only fail if there was actually src data to append + if (*pszSrc != L'\0') + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + size_t cchCopied = 0; + + status = RtlStringCopyWorkerW(pszDestEnd, + cchRemaining, + &cchCopied, + pszSrc, + NTSTRSAFE_MAX_LENGTH); + + pszDestEnd = pszDestEnd + cchCopied; + cchRemaining = cchRemaining - cchCopied; + + if (NT_SUCCESS(status) && + (dwFlags & STRSAFE_FILL_BEHIND_NULL) && + (cchRemaining > 1)) + { + size_t cbRemaining; + + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + cbRemaining = cchRemaining * sizeof(wchar_t); + + // handle the STRSAFE_FILL_BEHIND_NULL flag + RtlStringExHandleFillBehindNullW(pszDestEnd, cbRemaining, dwFlags); + } + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)) && + (cchDest != 0)) + { + size_t cbDest; + + // safe to multiply cchDest * sizeof(char) since cchDest < NTSTRSAFE_MAX_CCH and sizeof(char) is 1 + cbDest = cchDest * sizeof(wchar_t); + + // handle the STRSAFE_FILL_ON_FAILURE, STRSAFE_NULL_ON_FAILURE, and STRSAFE_NO_TRUNCATION flags + RtlStringExHandleOtherFlagsW(pszDest, + cbDest, + cchDestLength, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcchRemaining) + { + *pcchRemaining = cchRemaining; + } + } + } + + return status; +} +#endif // !NTSTRSAFE_NO_CCH_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CB_FUNCTIONS +/*++ + +NTSTATUS +RtlStringCbCatEx( + __inout_bcount(cbDest) LPTSTR pszDest OPTIONAL, + __in size_t cbDest, + __in LPCTSTR pszSrc OPTIONAL, + __deref_opt_out_bcount(*pcbRemaining) LPTSTR* ppszDestEnd OPTIONAL, + __out_opt size_t* pcbRemaining OPTIONAL, + __in DWORD dwFlags + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strcat' with + some additional parameters. In addition to functionality provided by + RtlStringCbCat, this routine also returns a pointer to the end of the + destination string and the number of bytes left in the destination string + including the null terminator. The flags parameter allows additional controls. + +Arguments: + + pszDest - destination string which must be null terminated + + cbDest - size of destination buffer in bytes. + length must be ((_tcslen(pszDest) + _tcslen(pszSrc) + 1) * sizeof(TCHAR) + to hold all of the combine string plus the null + terminator. + + pszSrc - source string which must be null terminated + + ppszDestEnd - if ppszDestEnd is non-null, the function will return a + pointer to the end of the destination string. If the + function appended any data, the result will point to the + null termination character + + pcbRemaining - if pcbRemaining is non-null, the function will return + the number of bytes left in the destination string, + including the null terminator + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND_NULL + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + behind the null terminator + + STRSAFE_IGNORE_NULLS + treat NULL string pointers like empty strings (TEXT("")). + this flag is useful for emulating functions like lstrcat + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer, and it will + be null terminated. This will overwrite any pre-existing + or truncated string + + STRSAFE_NULL_ON_FAILURE + if the function fails, the destination buffer will be set + to the empty string. This will overwrite any pre-existing or + truncated string + + STRSAFE_NO_TRUNCATION + if the function returns STATUS_BUFFER_OVERFLOW, pszDest + will not contain a truncated string, it will remain unchanged. + +Notes: + Behavior is undefined if source and destination strings overlap. + + pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag + is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc + may be NULL. An error may still be returned even though NULLS are ignored + due to insufficient space. + +Return Value: + + STATUS_SUCCESS - if there was source data and it was all concatenated + and the resultant dest string was null terminated + + failure - the operation did not succeed + + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the operation + failed due to insufficient space. When this error + occurs, the destination buffer is modified to contain + a truncated version of the ideal result and is null + terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlStringCbCatExA( + __inout_bcount(cbDest) NTSTRSAFE_PSTR pszDest, + __in size_t cbDest, + __in NTSTRSAFE_PCSTR pszSrc, + __deref_opt_out_bcount(*pcbRemaining) NTSTRSAFE_PSTR* ppszDestEnd, + __out_opt size_t* pcbRemaining, + __in DWORD dwFlags) +{ + NTSTATUS status; + size_t cchDest = cbDest / sizeof(char); + size_t cchDestLength; + + status = RtlStringExValidateDestAndLengthA(pszDest, + cchDest, + &cchDestLength, + NTSTRSAFE_MAX_CCH, + dwFlags); + + if (NT_SUCCESS(status)) + { + NTSTRSAFE_PSTR pszDestEnd = pszDest + cchDestLength; + size_t cchRemaining = cchDest - cchDestLength; + + status = RtlStringExValidateSrcA(&pszSrc, NULL, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + } + else if (cchRemaining <= 1) + { + // only fail if there was actually src data to append + if (*pszSrc != '\0') + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + size_t cchCopied = 0; + + status = RtlStringCopyWorkerA(pszDestEnd, + cchRemaining, + &cchCopied, + pszSrc, + NTSTRSAFE_MAX_LENGTH); + + pszDestEnd = pszDestEnd + cchCopied; + cchRemaining = cchRemaining - cchCopied; + + if (NT_SUCCESS(status) && + (dwFlags & STRSAFE_FILL_BEHIND_NULL) && + (cchRemaining > 1)) + { + size_t cbRemaining; + + // safe to multiply cchRemaining * sizeof(char) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(char) is 1 + cbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)); + + // handle the STRSAFE_FILL_BEHIND_NULL flag + RtlStringExHandleFillBehindNullA(pszDestEnd, cbRemaining, dwFlags); + } + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)) && + (cbDest != 0)) + { + // handle the STRSAFE_FILL_ON_FAILURE, STRSAFE_NULL_ON_FAILURE, and STRSAFE_NO_TRUNCATION flags + RtlStringExHandleOtherFlagsA(pszDest, + cbDest, + cchDestLength, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcbRemaining) + { + // safe to multiply cchRemaining * sizeof(char) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(char) is 1 + *pcbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)); + } + } + } + + return status; +} + +NTSTRSAFEDDI +RtlStringCbCatExW( + __inout_bcount(cbDest) NTSTRSAFE_PWSTR pszDest, + __in size_t cbDest, + __in NTSTRSAFE_PCWSTR pszSrc, + __deref_opt_out_bcount(*pcbRemaining) NTSTRSAFE_PWSTR* ppszDestEnd, + __out_opt size_t* pcbRemaining, + __in DWORD dwFlags) +{ + NTSTATUS status; + size_t cchDest = cbDest / sizeof(wchar_t); + size_t cchDestLength; + + status = RtlStringExValidateDestAndLengthW(pszDest, + cchDest, + &cchDestLength, + NTSTRSAFE_MAX_CCH, + dwFlags); + + if (NT_SUCCESS(status)) + { + NTSTRSAFE_PWSTR pszDestEnd = pszDest + cchDestLength; + size_t cchRemaining = cchDest - cchDestLength; + + status = RtlStringExValidateSrcW(&pszSrc, NULL, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + } + else if (cchRemaining <= 1) + { + // only fail if there was actually src data to append + if (*pszSrc != L'\0') + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + size_t cchCopied = 0; + + status = RtlStringCopyWorkerW(pszDestEnd, + cchRemaining, + &cchCopied, + pszSrc, + NTSTRSAFE_MAX_LENGTH); + + pszDestEnd = pszDestEnd + cchCopied; + cchRemaining = cchRemaining - cchCopied; + + if (NT_SUCCESS(status) && (dwFlags & STRSAFE_FILL_BEHIND_NULL)) + { + size_t cbRemaining; + + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + cbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + + // handle the STRSAFE_FILL_BEHIND_NULL flag + RtlStringExHandleFillBehindNullW(pszDestEnd, cbRemaining, dwFlags); + } + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)) && + (cbDest != 0)) + { + // handle the STRSAFE_FILL_ON_FAILURE, STRSAFE_NULL_ON_FAILURE, and STRSAFE_NO_TRUNCATION flags + RtlStringExHandleOtherFlagsW(pszDest, + cbDest, + cchDestLength, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcbRemaining) + { + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + *pcbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + } + } + } + + return status; +} +#endif // !NTSTRSAFE_NO_CB_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CCH_FUNCTIONS +/*++ + +NTSTATUS +RtlStringCchCatN( + __inout_ecount(cchDest) LPTSTR pszDest, + __in size_t cchDest, + __in LPCTSTR pszSrc, + __in size_t cchToAppend + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strncat'. + The size of the destination buffer (in characters) is a parameter as well as + the maximum number of characters to append, excluding the null terminator. + This function will not write past the end of the destination buffer and it will + ALWAYS null terminate pszDest (unless it is zero length). + + This function returns an NTSTATUS value, and not a pointer. It returns + STATUS_SUCCESS if all of pszSrc or the first cchToAppend characters were appended + to the destination string and it was null terminated, otherwise it will + return a failure code. In failure cases as much of pszSrc will be appended + to pszDest as possible, and pszDest will be null terminated. + +Arguments: + + pszDest - destination string which must be null terminated + + cchDest - size of destination buffer in characters. + length must be (_tcslen(pszDest) + min(cchToAppend, _tcslen(pszSrc)) + 1) + to hold all of the combine string plus the null + terminator. + + pszSrc - source string + + cchToAppend - maximum number of characters to append + +Notes: + Behavior is undefined if source and destination strings overlap. + + pszDest and pszSrc should not be NULL. See RtlStringCchCatNEx if you require + the handling of NULL values. + +Return Value: + + STATUS_SUCCESS - if all of pszSrc or the first cchToAppend characters + were concatenated to pszDest and the resultant dest + string was null terminated + + failure - the operation did not succeed + + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the operation + failed due to insufficient space. When this error + occurs, the destination buffer is modified to contain + a truncated version of the ideal result and is null + terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlStringCchCatNA( + __inout_ecount(cchDest) NTSTRSAFE_PSTR pszDest, + __in size_t cchDest, + __in_ecount(cchToAppend) STRSAFE_PCNZCH pszSrc, + __in size_t cchToAppend) +{ + NTSTATUS status; + size_t cchDestLength; + + status = RtlStringValidateDestAndLengthA(pszDest, + cchDest, + &cchDestLength, + NTSTRSAFE_MAX_CCH); + + if (NT_SUCCESS(status)) + { + if (cchToAppend > NTSTRSAFE_MAX_LENGTH) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = RtlStringCopyWorkerA(pszDest + cchDestLength, + cchDest - cchDestLength, + NULL, + pszSrc, + cchToAppend); + } + } + + return status; +} + +NTSTRSAFEDDI +RtlStringCchCatNW( + __inout_ecount(cchDest) NTSTRSAFE_PWSTR pszDest, + __in size_t cchDest, + __in_ecount(cchToAppend) STRSAFE_PCNZWCH pszSrc, + __in size_t cchToAppend) +{ + NTSTATUS status; + size_t cchDestLength; + + status = RtlStringValidateDestAndLengthW(pszDest, + cchDest, + &cchDestLength, + NTSTRSAFE_MAX_CCH); + + if (NT_SUCCESS(status)) + { + if (cchToAppend > NTSTRSAFE_MAX_LENGTH) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = RtlStringCopyWorkerW(pszDest + cchDestLength, + cchDest - cchDestLength, + NULL, + pszSrc, + cchToAppend); + } + } + + return status; +} +#endif // !NTSTRSAFE_NO_CCH_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CB_FUNCTIONS +/*++ + +NTSTATUS +RtlStringCbCatN( + __inout_bcount(cbDest) LPTSTR pszDest, + __in size_t cbDest, + __in LPCTSTR pszSrc, + __in size_t cbToAppend + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strncat'. + The size of the destination buffer (in bytes) is a parameter as well as + the maximum number of bytes to append, excluding the null terminator. + This function will not write past the end of the destination buffer and it will + ALWAYS null terminate pszDest (unless it is zero length). + + This function returns an NTSTATUS value, and not a pointer. It returns + STATUS_SUCCESS if all of pszSrc or the first cbToAppend bytes were appended + to the destination string and it was null terminated, otherwise it will + return a failure code. In failure cases as much of pszSrc will be appended + to pszDest as possible, and pszDest will be null terminated. + +Arguments: + + pszDest - destination string which must be null terminated + + cbDest - size of destination buffer in bytes. + length must be ((_tcslen(pszDest) + min(cbToAppend / sizeof(TCHAR), _tcslen(pszSrc)) + 1) * sizeof(TCHAR) + to hold all of the combine string plus the null + terminator. + + pszSrc - source string + + cbToAppend - maximum number of bytes to append + +Notes: + Behavior is undefined if source and destination strings overlap. + + pszDest and pszSrc should not be NULL. See RtlStringCbCatNEx if you require + the handling of NULL values. + +Return Value: + + STATUS_SUCCESS - if all of pszSrc or the first cbToAppend bytes were + concatenated to pszDest and the resultant dest string + was null terminated + + failure - the operation did not succeed + + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the operation + failed due to insufficient space. When this error + occurs, the destination buffer is modified to contain + a truncated version of the ideal result and is null + terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlStringCbCatNA( + __inout_bcount(cbDest) NTSTRSAFE_PSTR pszDest, + __in size_t cbDest, + __in_bcount(cbToAppend) STRSAFE_PCNZCH pszSrc, + __in size_t cbToAppend) +{ + NTSTATUS status; + size_t cchDest = cbDest / sizeof(char); + size_t cchDestLength; + + status = RtlStringValidateDestAndLengthA(pszDest, + cchDest, + &cchDestLength, + NTSTRSAFE_MAX_CCH); + + if (NT_SUCCESS(status)) + { + size_t cchToAppend = cbToAppend / sizeof(char); + + if (cchToAppend > NTSTRSAFE_MAX_LENGTH) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = RtlStringCopyWorkerA(pszDest + cchDestLength, + cchDest - cchDestLength, + NULL, + pszSrc, + cchToAppend); + } + } + + return status; +} + +NTSTRSAFEDDI +RtlStringCbCatNW( + __inout_bcount(cbDest) NTSTRSAFE_PWSTR pszDest, + __in size_t cbDest, + __in_bcount(cbToAppend) STRSAFE_PCNZWCH pszSrc, + __in size_t cbToAppend) +{ + NTSTATUS status; + size_t cchDest = cbDest / sizeof(wchar_t); + size_t cchDestLength; + + status = RtlStringValidateDestAndLengthW(pszDest, + cchDest, + &cchDestLength, + NTSTRSAFE_MAX_CCH); + + if (NT_SUCCESS(status)) + { + size_t cchToAppend = cbToAppend / sizeof(wchar_t); + + if (cchToAppend > NTSTRSAFE_MAX_LENGTH) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = RtlStringCopyWorkerW(pszDest + cchDestLength, + cchDest - cchDestLength, + NULL, + pszSrc, + cchToAppend); + } + } + + return status; +} +#endif // !NTSTRSAFE_NO_CB_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CCH_FUNCTIONS +/*++ + +NTSTATUS +RtlStringCchCatNEx( + __inout_ecount(cchDest) LPTSTR pszDest OPTIONAL, + __in size_t cchDest, + __in LPCTSTR pszSrc OPTIONAL, + __in size_t cchToAppend, + __deref_opt_out_ecount(*pcchRemaining) LPTSTR* ppszDestEnd OPTIONAL, + __out_opt size_t* pcchRemaining OPTIONAL, + __in DWORD dwFlags + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strncat', with + some additional parameters. In addition to functionality provided by + RtlStringCchCatN, this routine also returns a pointer to the end of the + destination string and the number of characters left in the destination string + including the null terminator. The flags parameter allows additional controls. + +Arguments: + + pszDest - destination string which must be null terminated + + cchDest - size of destination buffer in characters. + length must be (_tcslen(pszDest) + min(cchToAppend, _tcslen(pszSrc)) + 1) + to hold all of the combine string plus the null + terminator. + + pszSrc - source string + + cchToAppend - maximum number of characters to append + + ppszDestEnd - if ppszDestEnd is non-null, the function will return a + pointer to the end of the destination string. If the + function appended any data, the result will point to the + null termination character + + pcchRemaining - if pcchRemaining is non-null, the function will return the + number of characters left in the destination string, + including the null terminator + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND_NULL + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + behind the null terminator + + STRSAFE_IGNORE_NULLS + treat NULL string pointers like empty strings (TEXT("")) + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer, and it will + be null terminated. This will overwrite any pre-existing + or truncated string + + STRSAFE_NULL_ON_FAILURE + if the function fails, the destination buffer will be set + to the empty string. This will overwrite any pre-existing or + truncated string + + STRSAFE_NO_TRUNCATION + if the function returns STATUS_BUFFER_OVERFLOW, pszDest + will not contain a truncated string, it will remain unchanged. + +Notes: + Behavior is undefined if source and destination strings overlap. + + pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag + is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc + may be NULL. An error may still be returned even though NULLS are ignored + due to insufficient space. + +Return Value: + + STATUS_SUCCESS - if all of pszSrc or the first cchToAppend characters + were concatenated to pszDest and the resultant dest + string was null terminated + + failure - the operation did not succeed + + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the operation + failed due to insufficient space. When this error + occurs, the destination buffer is modified to contain + a truncated version of the ideal result and is null + terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlStringCchCatNExA( + __inout_ecount(cchDest) NTSTRSAFE_PSTR pszDest, + __in size_t cchDest, + __in_ecount(cchToAppend) STRSAFE_PCNZCH pszSrc, + __in size_t cchToAppend, + __deref_opt_out_ecount(*pcchRemaining) NTSTRSAFE_PSTR* ppszDestEnd, + __out_opt size_t* pcchRemaining, + __in DWORD dwFlags) +{ + NTSTATUS status; + size_t cchDestLength; + + status = RtlStringExValidateDestAndLengthA(pszDest, + cchDest, + &cchDestLength, + NTSTRSAFE_MAX_CCH, + dwFlags); + + if (NT_SUCCESS(status)) + { + NTSTRSAFE_PSTR pszDestEnd = pszDest + cchDestLength; + size_t cchRemaining = cchDest - cchDestLength; + + status = RtlStringExValidateSrcA(&pszSrc, &cchToAppend, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + } + else if (cchRemaining <= 1) + { + // only fail if there was actually src data to append + if ((cchToAppend != 0) && (*pszSrc != '\0')) + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + size_t cchCopied = 0; + + status = RtlStringCopyWorkerA(pszDestEnd, + cchRemaining, + &cchCopied, + pszSrc, + cchToAppend); + + pszDestEnd = pszDestEnd + cchCopied; + cchRemaining = cchRemaining - cchCopied; + + if (NT_SUCCESS(status) && + (dwFlags & STRSAFE_FILL_BEHIND_NULL) && + (cchRemaining > 1)) + { + size_t cbRemaining; + + // safe to multiply cchRemaining * sizeof(char) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(char) is 1 + cbRemaining = cchRemaining * sizeof(char); + + // handle the STRSAFE_FILL_BEHIND_NULL flag + RtlStringExHandleFillBehindNullA(pszDestEnd, cbRemaining, dwFlags); + } + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)) && + (cchDest != 0)) + { + size_t cbDest; + + // safe to multiply cchDest * sizeof(char) since cchDest < NTSTRSAFE_MAX_CCH and sizeof(char) is 1 + cbDest = cchDest * sizeof(char); + + // handle the STRSAFE_FILL_ON_FAILURE, STRSAFE_NULL_ON_FAILURE, and STRSAFE_NO_TRUNCATION flags + RtlStringExHandleOtherFlagsA(pszDest, + cbDest, + cchDestLength, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcchRemaining) + { + *pcchRemaining = cchRemaining; + } + } + } + + return status; +} + +NTSTRSAFEDDI +RtlStringCchCatNExW( + __inout_ecount(cchDest) NTSTRSAFE_PWSTR pszDest, + __in size_t cchDest, + __in_ecount(cchToAppend) STRSAFE_PCNZWCH pszSrc, + __in size_t cchToAppend, + __deref_opt_out_ecount(*pcchRemaining) NTSTRSAFE_PWSTR* ppszDestEnd, + __out_opt size_t* pcchRemaining, + __in DWORD dwFlags) +{ + NTSTATUS status; + size_t cchDestLength; + + status = RtlStringExValidateDestAndLengthW(pszDest, + cchDest, + &cchDestLength, + NTSTRSAFE_MAX_CCH, + dwFlags); + + if (NT_SUCCESS(status)) + { + NTSTRSAFE_PWSTR pszDestEnd = pszDest + cchDestLength; + size_t cchRemaining = cchDest - cchDestLength; + + status = RtlStringExValidateSrcW(&pszSrc, &cchToAppend, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + } + else if (cchRemaining <= 1) + { + // only fail if there was actually src data to append + if ((cchToAppend != 0) && (*pszSrc != L'\0')) + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + size_t cchCopied = 0; + + status = RtlStringCopyWorkerW(pszDestEnd, + cchRemaining, + &cchCopied, + pszSrc, + cchToAppend); + + pszDestEnd = pszDestEnd + cchCopied; + cchRemaining = cchRemaining - cchCopied; + + if (NT_SUCCESS(status) && + (dwFlags & STRSAFE_FILL_BEHIND_NULL) && + (cchRemaining > 1)) + { + size_t cbRemaining; + + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + cbRemaining = cchRemaining * sizeof(wchar_t); + + // handle the STRSAFE_FILL_BEHIND_NULL flag + RtlStringExHandleFillBehindNullW(pszDestEnd, cbRemaining, dwFlags); + } + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)) && + (cchDest != 0)) + { + size_t cbDest; + + // safe to multiply cchDest * sizeof(wchar_t) since cchDest < NTSTRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + cbDest = cchDest * sizeof(wchar_t); + + // handle the STRSAFE_FILL_ON_FAILURE, STRSAFE_NULL_ON_FAILURE, and STRSAFE_NO_TRUNCATION flags + RtlStringExHandleOtherFlagsW(pszDest, + cbDest, + cchDestLength, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcchRemaining) + { + *pcchRemaining = cchRemaining; + } + } + } + + return status; +} +#endif // !NTSTRSAFE_NO_CCH_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CB_FUNCTIONS +/*++ + +NTSTATUS +RtlStringCbCatNEx( + __inout_bcount(cbDest) LPTSTR pszDest OPTIONAL, + __in size_t cbDest, + __in LPCTSTR pszSrc OPTIONAL, + __in size_t cbToAppend, + __deref_opt_out_bcount(*pcbRemaining) LPTSTR* ppszDestEnd OPTIONAL, + __out_opt size_t* pcchRemaining OPTIONAL, + __in DWORD dwFlags + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strncat', with + some additional parameters. In addition to functionality provided by + RtlStringCbCatN, this routine also returns a pointer to the end of the + destination string and the number of bytes left in the destination string + including the null terminator. The flags parameter allows additional controls. + +Arguments: + + pszDest - destination string which must be null terminated + + cbDest - size of destination buffer in bytes. + length must be ((_tcslen(pszDest) + min(cbToAppend / sizeof(TCHAR), _tcslen(pszSrc)) + 1) * sizeof(TCHAR) + to hold all of the combine string plus the null + terminator. + + pszSrc - source string + + cbToAppend - maximum number of bytes to append + + ppszDestEnd - if ppszDestEnd is non-null, the function will return a + pointer to the end of the destination string. If the + function appended any data, the result will point to the + null termination character + + pcbRemaining - if pcbRemaining is non-null, the function will return the + number of bytes left in the destination string, + including the null terminator + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND_NULL + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + behind the null terminator + + STRSAFE_IGNORE_NULLS + treat NULL string pointers like empty strings (TEXT("")) + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer, and it will + be null terminated. This will overwrite any pre-existing + or truncated string + + STRSAFE_NULL_ON_FAILURE + if the function fails, the destination buffer will be set + to the empty string. This will overwrite any pre-existing or + truncated string + + STRSAFE_NO_TRUNCATION + if the function returns STATUS_BUFFER_OVERFLOW, pszDest + will not contain a truncated string, it will remain unchanged. + +Notes: + Behavior is undefined if source and destination strings overlap. + + pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag + is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc + may be NULL. An error may still be returned even though NULLS are ignored + due to insufficient space. + +Return Value: + + STATUS_SUCCESS - if all of pszSrc or the first cbToAppend bytes were + concatenated to pszDest and the resultant dest string + was null terminated + + failure - the operation did not succeed + + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the operation + failed due to insufficient space. When this error + occurs, the destination buffer is modified to contain + a truncated version of the ideal result and is null + terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlStringCbCatNExA( + __inout_bcount(cbDest) NTSTRSAFE_PSTR pszDest, + __in size_t cbDest, + __in_bcount(cbToAppend) STRSAFE_PCNZCH pszSrc, + __in size_t cbToAppend, + __deref_opt_out_bcount(*pcbRemaining) NTSTRSAFE_PSTR* ppszDestEnd, + __out_opt size_t* pcbRemaining, + __in DWORD dwFlags) +{ + NTSTATUS status; + size_t cchDest = cbDest / sizeof(char); + size_t cchDestLength; + + status = RtlStringExValidateDestAndLengthA(pszDest, + cchDest, + &cchDestLength, + NTSTRSAFE_MAX_CCH, + dwFlags); + + if (NT_SUCCESS(status)) + { + NTSTRSAFE_PSTR pszDestEnd = pszDest + cchDestLength; + size_t cchRemaining = cchDest - cchDestLength; + size_t cchToAppend = cbToAppend / sizeof(char); + + status = RtlStringExValidateSrcA(&pszSrc, &cchToAppend, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + } + else if (cchRemaining <= 1) + { + // only fail if there was actually src data to append + if ((cchToAppend != 0) && (*pszSrc != '\0')) + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + size_t cchCopied = 0; + + status = RtlStringCopyWorkerA(pszDestEnd, + cchRemaining, + &cchCopied, + pszSrc, + cchToAppend); + + pszDestEnd = pszDestEnd + cchCopied; + cchRemaining = cchRemaining - cchCopied; + + if (NT_SUCCESS(status) && + (dwFlags & STRSAFE_FILL_BEHIND_NULL) && + (cchRemaining > 1)) + { + size_t cbRemaining; + + // safe to multiply cchRemaining * sizeof(char) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(char) is 1 + cbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)); + + // handle the STRSAFE_FILL_BEHIND_NULL flag + RtlStringExHandleFillBehindNullA(pszDestEnd, cbRemaining, dwFlags); + } + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)) && + (cbDest != 0)) + { + // handle the STRSAFE_FILL_ON_FAILURE, STRSAFE_NULL_ON_FAILURE, and STRSAFE_NO_TRUNCATION flags + RtlStringExHandleOtherFlagsA(pszDest, + cbDest, + cchDestLength, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcbRemaining) + { + // safe to multiply cchRemaining * sizeof(char) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(char) is 1 + *pcbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)); + } + } + } + + return status; +} + +NTSTRSAFEDDI +RtlStringCbCatNExW( + __inout_bcount(cbDest) NTSTRSAFE_PWSTR pszDest, + __in size_t cbDest, + __in_bcount(cbToAppend) STRSAFE_PCNZWCH pszSrc, + __in size_t cbToAppend, + __deref_opt_out_bcount(*pcbRemaining) NTSTRSAFE_PWSTR* ppszDestEnd, + __out_opt size_t* pcbRemaining, + __in DWORD dwFlags) +{ + NTSTATUS status; + size_t cchDest = cbDest / sizeof(wchar_t); + size_t cchDestLength; + + status = RtlStringExValidateDestAndLengthW(pszDest, + cchDest, + &cchDestLength, + NTSTRSAFE_MAX_CCH, + dwFlags); + + if (NT_SUCCESS(status)) + { + NTSTRSAFE_PWSTR pszDestEnd = pszDest + cchDestLength; + size_t cchRemaining = cchDest - cchDestLength; + size_t cchToAppend = cbToAppend / sizeof(wchar_t); + +#pragma warning(push) +#pragma warning(disable : __WARNING_POTENTIAL_BUFFER_OVERFLOW_HIGH_PRIORITY) + status = RtlStringExValidateSrcW(&pszSrc, &cchToAppend, NTSTRSAFE_MAX_CCH, dwFlags); +#pragma warning(pop) + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + } + else if (cchRemaining <= 1) + { + // only fail if there was actually src data to append + if ((cchToAppend != 0) && (*pszSrc != L'\0')) + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + size_t cchCopied = 0; + + status = RtlStringCopyWorkerW(pszDestEnd, + cchRemaining, + &cchCopied, + pszSrc, + cchToAppend); + + pszDestEnd = pszDestEnd + cchCopied; + cchRemaining = cchRemaining - cchCopied; + + if (NT_SUCCESS(status) && (dwFlags & STRSAFE_FILL_BEHIND_NULL)) + { + size_t cbRemaining; + + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + cbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + + // handle the STRSAFE_FILL_BEHIND_NULL flag + RtlStringExHandleFillBehindNullW(pszDestEnd, cbRemaining, dwFlags); + } + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)) && + (cbDest != 0)) + { + // handle the STRSAFE_FILL_ON_FAILURE, STRSAFE_NULL_ON_FAILURE, and STRSAFE_NO_TRUNCATION flags + RtlStringExHandleOtherFlagsW(pszDest, + cbDest, + cchDestLength, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcbRemaining) + { + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + *pcbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + } + } + } + + return status; +} +#endif // !NTSTRSAFE_NO_CB_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CCH_FUNCTIONS +/*++ + +NTSTATUS +RtlStringCchVPrintf( + __out_ecount(cchDest) LPTSTR pszDest, + __in size_t cchDest, + __in __format_string LPCTSTR pszFormat, + __in va_list argList + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'vsprintf'. + The size of the destination buffer (in characters) is a parameter and + this function will not write past the end of this buffer and it will + ALWAYS null terminate the destination buffer (unless it is zero length). + + This function returns an NTSTATUS value, and not a pointer. It returns + STATUS_SUCCESS if the string was printed without truncation and null terminated, + otherwise it will return a failure code. In failure cases it will return + a truncated version of the ideal result. + +Arguments: + + pszDest - destination string + + cchDest - size of destination buffer in characters + length must be sufficient to hold the resulting formatted + string, including the null terminator. + + pszFormat - format string which must be null terminated + + argList - va_list from the variable arguments according to the + stdarg.h convention + +Notes: + Behavior is undefined if destination, format strings or any arguments + strings overlap. + + pszDest and pszFormat should not be NULL. See RtlStringCchVPrintfEx if you + require the handling of NULL values. + +Return Value: + + STATUS_SUCCESS - if there was sufficient space in the dest buffer for + the resultant string and it was null terminated. + + failure - the operation did not succeed + + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the print + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result and is + null terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlStringCchVPrintfA( + __out_ecount(cchDest) NTSTRSAFE_PSTR pszDest, + __in size_t cchDest, + __in __format_string NTSTRSAFE_PCSTR pszFormat, + __in va_list argList) +{ + NTSTATUS status; + + status = RtlStringValidateDestA(pszDest, cchDest, NTSTRSAFE_MAX_CCH); + + if (NT_SUCCESS(status)) + { + status = RtlStringVPrintfWorkerA(pszDest, + cchDest, + NULL, + pszFormat, + argList); + } + + return status; +} + +NTSTRSAFEDDI +RtlStringCchVPrintfW( + __out_ecount(cchDest) NTSTRSAFE_PWSTR pszDest, + __in size_t cchDest, + __in __format_string NTSTRSAFE_PCWSTR pszFormat, + __in va_list argList) +{ + NTSTATUS status; + + status = RtlStringValidateDestW(pszDest, cchDest, NTSTRSAFE_MAX_CCH); + + if (NT_SUCCESS(status)) + { + status = RtlStringVPrintfWorkerW(pszDest, + cchDest, + NULL, + pszFormat, + argList); + } + + return status; +} +#endif // !NTSTRSAFE_NO_CCH_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CB_FUNCTIONS +/*++ + +NTSTATUS +RtlStringCbVPrintf( + __out_bcount(cbDest) LPTSTR pszDest, + __in size_t cbDest, + __in __format_string LPCTSTR pszFormat, + __in va_list argList + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'vsprintf'. + The size of the destination buffer (in bytes) is a parameter and + this function will not write past the end of this buffer and it will + ALWAYS null terminate the destination buffer (unless it is zero length). + + This function returns an NTSTATUS value, and not a pointer. It returns + STATUS_SUCCESS if the string was printed without truncation and null terminated, + otherwise it will return a failure code. In failure cases it will return + a truncated version of the ideal result. + +Arguments: + + pszDest - destination string + + cbDest - size of destination buffer in bytes + length must be sufficient to hold the resulting formatted + string, including the null terminator. + + pszFormat - format string which must be null terminated + + argList - va_list from the variable arguments according to the + stdarg.h convention + +Notes: + Behavior is undefined if destination, format strings or any arguments + strings overlap. + + pszDest and pszFormat should not be NULL. See RtlStringCbVPrintfEx if you + require the handling of NULL values. + + +Return Value: + + STATUS_SUCCESS - if there was sufficient space in the dest buffer for + the resultant string and it was null terminated. + + failure - the operation did not succeed + + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the print + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result and is + null terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlStringCbVPrintfA( + __out_bcount(cbDest) NTSTRSAFE_PSTR pszDest, + __in size_t cbDest, + __in __format_string NTSTRSAFE_PCSTR pszFormat, + __in va_list argList) +{ + NTSTATUS status; + size_t cchDest = cbDest / sizeof(char); + + status = RtlStringValidateDestA(pszDest, cchDest, NTSTRSAFE_MAX_CCH); + + if (NT_SUCCESS(status)) + { + status = RtlStringVPrintfWorkerA(pszDest, + cchDest, + NULL, + pszFormat, + argList); + } + + return status; +} + +NTSTRSAFEDDI +RtlStringCbVPrintfW( + __out_bcount(cbDest) NTSTRSAFE_PWSTR pszDest, + __in size_t cbDest, + __in __format_string NTSTRSAFE_PCWSTR pszFormat, + __in va_list argList) +{ + NTSTATUS status; + size_t cchDest = cbDest / sizeof(wchar_t); + + status = RtlStringValidateDestW(pszDest, cchDest, NTSTRSAFE_MAX_CCH); + + if (NT_SUCCESS(status)) + { + status = RtlStringVPrintfWorkerW(pszDest, + cchDest, + NULL, + pszFormat, + argList); + } + + return status; +} +#endif // !NTSTRSAFE_NO_CB_FUNCTIONS + + +#ifndef _M_CEE_PURE + +#ifndef NTSTRSAFE_NO_CCH_FUNCTIONS +/*++ + +NTSTATUS +RtlStringCchPrintf( + __out_ecount(cchDest) LPTSTR pszDest, + __in size_t cchDest, + __in __format_string LPCTSTR pszFormat, + ... + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'sprintf'. + The size of the destination buffer (in characters) is a parameter and + this function will not write past the end of this buffer and it will + ALWAYS null terminate the destination buffer (unless it is zero length). + + This function returns an NTSTATUS value, and not a pointer. It returns + STATUS_SUCCESS if the string was printed without truncation and null terminated, + otherwise it will return a failure code. In failure cases it will return + a truncated version of the ideal result. + +Arguments: + + pszDest - destination string + + cchDest - size of destination buffer in characters + length must be sufficient to hold the resulting formatted + string, including the null terminator. + + pszFormat - format string which must be null terminated + + ... - additional parameters to be formatted according to + the format string + +Notes: + Behavior is undefined if destination, format strings or any arguments + strings overlap. + + pszDest and pszFormat should not be NULL. See RtlStringCchPrintfEx if you + require the handling of NULL values. + +Return Value: + + STATUS_SUCCESS - if there was sufficient space in the dest buffer for + the resultant string and it was null terminated. + + failure - the operation did not succeed + + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the print + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result and is + null terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlStringCchPrintfA( + __out_ecount(cchDest) NTSTRSAFE_PSTR pszDest, + __in size_t cchDest, + __in __format_string NTSTRSAFE_PCSTR pszFormat, + ...) +{ + NTSTATUS status; + + status = RtlStringValidateDestA(pszDest, cchDest, NTSTRSAFE_MAX_CCH); + + if (NT_SUCCESS(status)) + { + va_list argList; + + va_start(argList, pszFormat); + + status = RtlStringVPrintfWorkerA(pszDest, + cchDest, + NULL, + pszFormat, + argList); + + va_end(argList); + } + + return status; +} + +NTSTRSAFEDDI +RtlStringCchPrintfW( + __out_ecount(cchDest) NTSTRSAFE_PWSTR pszDest, + __in size_t cchDest, + __in __format_string NTSTRSAFE_PCWSTR pszFormat, + ...) +{ + NTSTATUS status; + + status = RtlStringValidateDestW(pszDest, cchDest, NTSTRSAFE_MAX_CCH); + + if (NT_SUCCESS(status)) + { + va_list argList; + + va_start(argList, pszFormat); + + status = RtlStringVPrintfWorkerW(pszDest, + cchDest, + NULL, + pszFormat, + argList); + + va_end(argList); + } + + return status; +} +#endif // !NTSTRSAFE_NO_CCH_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CB_FUNCTIONS +/*++ + +NTSTATUS +RtlStringCbPrintf( + __out_bcount(cbDest) LPTSTR pszDest, + __in size_t cbDest, + __in __format_string LPCTSTR pszFormat, + ... + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'sprintf'. + The size of the destination buffer (in bytes) is a parameter and + this function will not write past the end of this buffer and it will + ALWAYS null terminate the destination buffer (unless it is zero length). + + This function returns an NTSTATUS value, and not a pointer. It returns + STATUS_SUCCESS if the string was printed without truncation and null terminated, + otherwise it will return a failure code. In failure cases it will return + a truncated version of the ideal result. + +Arguments: + + pszDest - destination string + + cbDest - size of destination buffer in bytes + length must be sufficient to hold the resulting formatted + string, including the null terminator. + + pszFormat - format string which must be null terminated + + ... - additional parameters to be formatted according to + the format string + +Notes: + Behavior is undefined if destination, format strings or any arguments + strings overlap. + + pszDest and pszFormat should not be NULL. See RtlStringCbPrintfEx if you + require the handling of NULL values. + + +Return Value: + + STATUS_SUCCESS - if there was sufficient space in the dest buffer for + the resultant string and it was null terminated. + + failure - the operation did not succeed + + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the print + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result and is + null terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlStringCbPrintfA( + __out_bcount(cbDest) NTSTRSAFE_PSTR pszDest, + __in size_t cbDest, + __in __format_string NTSTRSAFE_PCSTR pszFormat, + ...) +{ + NTSTATUS status; + size_t cchDest = cbDest / sizeof(char); + + status = RtlStringValidateDestA(pszDest, cchDest, NTSTRSAFE_MAX_CCH); + + if (NT_SUCCESS(status)) + { + va_list argList; + + va_start(argList, pszFormat); + + status = RtlStringVPrintfWorkerA(pszDest, + cchDest, + NULL, + pszFormat, + argList); + + va_end(argList); + } + + return status; +} + +NTSTRSAFEDDI +RtlStringCbPrintfW( + __out_bcount(cbDest) NTSTRSAFE_PWSTR pszDest, + __in size_t cbDest, + __in __format_string NTSTRSAFE_PCWSTR pszFormat, + ...) +{ + NTSTATUS status; + size_t cchDest = cbDest / sizeof(wchar_t); + + status = RtlStringValidateDestW(pszDest, cchDest, NTSTRSAFE_MAX_CCH); + + if (NT_SUCCESS(status)) + { + va_list argList; + + va_start(argList, pszFormat); + + status = RtlStringVPrintfWorkerW(pszDest, + cchDest, + NULL, + pszFormat, + argList); + + va_end(argList); + } + + return status; +} +#endif // !NTSTRSAFE_NO_CB_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CCH_FUNCTIONS +/*++ + +NTSTATUS +RtlStringCchPrintfEx( + __out_ecount(cchDest) LPTSTR pszDest OPTIONAL, + __in size_t cchDest, + __deref_opt_out_ecount(*pcchRemaining) LPTSTR* ppszDestEnd OPTIONAL, + __out_opt size_t* pcchRemaining OPTIONAL, + __in DWORD dwFlags, + __in __format_string LPCTSTR pszFormat OPTIONAL, + ... + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'sprintf' with + some additional parameters. In addition to functionality provided by + RtlStringCchPrintf, this routine also returns a pointer to the end of the + destination string and the number of characters left in the destination string + including the null terminator. The flags parameter allows additional controls. + +Arguments: + + pszDest - destination string + + cchDest - size of destination buffer in characters. + length must be sufficient to contain the resulting + formatted string plus the null terminator. + + ppszDestEnd - if ppszDestEnd is non-null, the function will return a + pointer to the end of the destination string. If the + function printed any data, the result will point to the + null termination character + + pcchRemaining - if pcchRemaining is non-null, the function will return + the number of characters left in the destination string, + including the null terminator + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND_NULL + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + behind the null terminator + + STRSAFE_IGNORE_NULLS + treat NULL string pointers like empty strings (TEXT("")) + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer, and it will + be null terminated. This will overwrite any truncated + string returned when the failure is + STATUS_BUFFER_OVERFLOW + + STRSAFE_NO_TRUNCATION / + STRSAFE_NULL_ON_FAILURE + if the function fails, the destination buffer will be set + to the empty string. This will overwrite any truncated string + returned when the failure is STATUS_BUFFER_OVERFLOW. + + pszFormat - format string which must be null terminated + + ... - additional parameters to be formatted according to + the format string + +Notes: + Behavior is undefined if destination, format strings or any arguments + strings overlap. + + pszDest and pszFormat should not be NULL unless the STRSAFE_IGNORE_NULLS + flag is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and + pszFormat may be NULL. An error may still be returned even though NULLS + are ignored due to insufficient space. + +Return Value: + + STATUS_SUCCESS - if there was sufficient space in the dest buffer for + the resultant string and it was null terminated. + + failure - the operation did not succeed + + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the print + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result and is + null terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlStringCchPrintfExA( + __out_ecount(cchDest) NTSTRSAFE_PSTR pszDest, + __in size_t cchDest, + __deref_opt_out_ecount(*pcchRemaining) NTSTRSAFE_PSTR* ppszDestEnd, + __out_opt size_t* pcchRemaining, + __in DWORD dwFlags, + __in __format_string NTSTRSAFE_PCSTR pszFormat, + ...) +{ + NTSTATUS status; + + status = RtlStringExValidateDestA(pszDest, cchDest, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + NTSTRSAFE_PSTR pszDestEnd = pszDest; + size_t cchRemaining = cchDest; + + status = RtlStringExValidateSrcA(&pszFormat, NULL, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + + if (cchDest != 0) + { + *pszDest = '\0'; + } + } + else if (cchDest == 0) + { + // only fail if there was actually a non-empty format string + if (*pszFormat != '\0') + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + size_t cchNewDestLength = 0; + va_list argList; + + va_start(argList, pszFormat); + + status = RtlStringVPrintfWorkerA(pszDest, + cchDest, + &cchNewDestLength, + pszFormat, + argList); + + va_end(argList); + + pszDestEnd = pszDest + cchNewDestLength; + cchRemaining = cchDest - cchNewDestLength; + + if (NT_SUCCESS(status) && + (dwFlags & STRSAFE_FILL_BEHIND_NULL) && + (cchRemaining > 1)) + { + size_t cbRemaining; + + // safe to multiply cchRemaining * sizeof(char) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(char) is 1 + cbRemaining = cchRemaining * sizeof(char); + + // handle the STRSAFE_FILL_BEHIND_NULL flag + RtlStringExHandleFillBehindNullA(pszDestEnd, cbRemaining, dwFlags); + } + } + } + else + { + if (cchDest != 0) + { + *pszDest = '\0'; + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)) && + (cchDest != 0)) + { + size_t cbDest; + + // safe to multiply cchDest * sizeof(char) since cchDest < NTSTRSAFE_MAX_CCH and sizeof(char) is 1 + cbDest = cchDest * sizeof(char); + + // handle the STRSAFE_FILL_ON_FAILURE, STRSAFE_NULL_ON_FAILURE, and STRSAFE_NO_TRUNCATION flags + RtlStringExHandleOtherFlagsA(pszDest, + cbDest, + 0, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcchRemaining) + { + *pcchRemaining = cchRemaining; + } + } + } + + return status; +} + +NTSTRSAFEDDI +RtlStringCchPrintfExW( + __out_ecount(cchDest) NTSTRSAFE_PWSTR pszDest, + __in size_t cchDest, + __deref_opt_out_ecount(*pcchRemaining) NTSTRSAFE_PWSTR* ppszDestEnd, + __out_opt size_t* pcchRemaining, + __in DWORD dwFlags, + __in __format_string NTSTRSAFE_PCWSTR pszFormat, + ...) +{ + NTSTATUS status; + + status = RtlStringExValidateDestW(pszDest, cchDest, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + NTSTRSAFE_PWSTR pszDestEnd = pszDest; + size_t cchRemaining = cchDest; + + status = RtlStringExValidateSrcW(&pszFormat, NULL, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + + if (cchDest != 0) + { + *pszDest = L'\0'; + } + } + else if (cchDest == 0) + { + // only fail if there was actually a non-empty format string + if (*pszFormat != L'\0') + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + size_t cchNewDestLength = 0; + va_list argList; + + va_start(argList, pszFormat); + + status = RtlStringVPrintfWorkerW(pszDest, + cchDest, + &cchNewDestLength, + pszFormat, + argList); + + va_end(argList); + + pszDestEnd = pszDest + cchNewDestLength; + cchRemaining = cchDest - cchNewDestLength; + + if (NT_SUCCESS(status) && + (dwFlags & STRSAFE_FILL_BEHIND_NULL) && + (cchRemaining > 1)) + { + size_t cbRemaining; + + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + cbRemaining = cchRemaining * sizeof(wchar_t); + + // handle the STRSAFE_FILL_BEHIND_NULL flag + RtlStringExHandleFillBehindNullW(pszDestEnd, cbRemaining, dwFlags); + } + } + } + else + { + if (cchDest != 0) + { + *pszDest = L'\0'; + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)) && + (cchDest != 0)) + { + size_t cbDest; + + // safe to multiply cchDest * sizeof(wchar_t) since cchDest < NTSTRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + cbDest = cchDest * sizeof(wchar_t); + + // handle the STRSAFE_FILL_ON_FAILURE, STRSAFE_NULL_ON_FAILURE, and STRSAFE_NO_TRUNCATION flags + RtlStringExHandleOtherFlagsW(pszDest, + cbDest, + 0, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcchRemaining) + { + *pcchRemaining = cchRemaining; + } + } + } + + return status; +} +#endif // !NTSTRSAFE_NO_CCH_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CB_FUNCTIONS +/*++ + +NTSTATUS +RtlStringCbPrintfEx( + __out_bcount(cbDest) LPTSTR pszDest OPTIONAL, + __in size_t cbDest, + __deref_opt_out_bcount(*pcbRemaining) LPTSTR* ppszDestEnd OPTIONAL, + __out_opt size_t* pcbRemaining OPTIONAL, + __in DWORD dwFlags, + __in __format_string LPCTSTR pszFormat OPTIONAL, + ... + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'sprintf' with + some additional parameters. In addition to functionality provided by + RtlStringCbPrintf, this routine also returns a pointer to the end of the + destination string and the number of bytes left in the destination string + including the null terminator. The flags parameter allows additional controls. + +Arguments: + + pszDest - destination string + + cbDest - size of destination buffer in bytes. + length must be sufficient to contain the resulting + formatted string plus the null terminator. + + ppszDestEnd - if ppszDestEnd is non-null, the function will return a + pointer to the end of the destination string. If the + function printed any data, the result will point to the + null termination character + + pcbRemaining - if pcbRemaining is non-null, the function will return + the number of bytes left in the destination string, + including the null terminator + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND_NULL + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + behind the null terminator + + STRSAFE_IGNORE_NULLS + treat NULL string pointers like empty strings (TEXT("")) + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer, and it will + be null terminated. This will overwrite any truncated + string returned when the failure is + STATUS_BUFFER_OVERFLOW + + STRSAFE_NO_TRUNCATION / + STRSAFE_NULL_ON_FAILURE + if the function fails, the destination buffer will be set + to the empty string. This will overwrite any truncated string + returned when the failure is STATUS_BUFFER_OVERFLOW. + + pszFormat - format string which must be null terminated + + ... - additional parameters to be formatted according to + the format string + +Notes: + Behavior is undefined if destination, format strings or any arguments + strings overlap. + + pszDest and pszFormat should not be NULL unless the STRSAFE_IGNORE_NULLS + flag is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and + pszFormat may be NULL. An error may still be returned even though NULLS + are ignored due to insufficient space. + +Return Value: + + STATUS_SUCCESS - if there was source data and it was all concatenated and + the resultant dest string was null terminated + + failure - the operation did not succeed + + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the print + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result and is + null terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlStringCbPrintfExA( + __out_bcount(cbDest) NTSTRSAFE_PSTR pszDest, + __in size_t cbDest, + __deref_opt_out_bcount(*pcbRemaining) NTSTRSAFE_PSTR* ppszDestEnd, + __out_opt size_t* pcbRemaining, + __in DWORD dwFlags, + __in __format_string NTSTRSAFE_PCSTR pszFormat, + ...) +{ + NTSTATUS status; + size_t cchDest = cbDest / sizeof(char); + + status = RtlStringExValidateDestA(pszDest, cchDest, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + NTSTRSAFE_PSTR pszDestEnd = pszDest; + size_t cchRemaining = cchDest; + + status = RtlStringExValidateSrcA(&pszFormat, NULL, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + + if (cchDest != 0) + { + *pszDest = '\0'; + } + } + else if (cchDest == 0) + { + // only fail if there was actually a non-empty format string + if (*pszFormat != '\0') + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + size_t cchNewDestLength = 0; + va_list argList; + + va_start(argList, pszFormat); + + status = RtlStringVPrintfWorkerA(pszDest, + cchDest, + &cchNewDestLength, + pszFormat, + argList); + + va_end(argList); + + pszDestEnd = pszDest + cchNewDestLength; + cchRemaining = cchDest - cchNewDestLength; + + if (NT_SUCCESS(status) && + (dwFlags & STRSAFE_FILL_BEHIND_NULL) && + (cchRemaining > 1)) + { + size_t cbRemaining; + + // safe to multiply cchRemaining * sizeof(char) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(char) is 1 + cbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)); + + // handle the STRSAFE_FILL_BEHIND_NULL flag + RtlStringExHandleFillBehindNullA(pszDestEnd, cbRemaining, dwFlags); + } + } + } + else + { + if (cchDest != 0) + { + *pszDest = '\0'; + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)) && + (cbDest != 0)) + { + // handle the STRSAFE_FILL_ON_FAILURE, STRSAFE_NULL_ON_FAILURE, and STRSAFE_NO_TRUNCATION flags + RtlStringExHandleOtherFlagsA(pszDest, + cbDest, + 0, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcbRemaining) + { + // safe to multiply cchRemaining * sizeof(char) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(char) is 1 + *pcbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)); + } + } + } + + return status; +} + +NTSTRSAFEDDI +RtlStringCbPrintfExW( + __out_bcount(cbDest) NTSTRSAFE_PWSTR pszDest, + __in size_t cbDest, + __deref_opt_out_bcount(*pcbRemaining) NTSTRSAFE_PWSTR* ppszDestEnd, + __out_opt size_t* pcbRemaining, + __in DWORD dwFlags, + __in __format_string NTSTRSAFE_PCWSTR pszFormat, + ...) +{ + NTSTATUS status; + size_t cchDest = cbDest / sizeof(wchar_t); + + status = RtlStringExValidateDestW(pszDest, cchDest, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + NTSTRSAFE_PWSTR pszDestEnd = pszDest; + size_t cchRemaining = cchDest; + + status = RtlStringExValidateSrcW(&pszFormat, NULL, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + + if (cchDest != 0) + { + *pszDest = L'\0'; + } + } + else if (cchDest == 0) + { + // only fail if there was actually a non-empty format string + if (*pszFormat != L'\0') + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + size_t cchNewDestLength = 0; + va_list argList; + + va_start(argList, pszFormat); + + status = RtlStringVPrintfWorkerW(pszDest, + cchDest, + &cchNewDestLength, + pszFormat, + argList); + + va_end(argList); + + pszDestEnd = pszDest + cchNewDestLength; + cchRemaining = cchDest - cchNewDestLength; + + if (NT_SUCCESS(status) && (dwFlags & STRSAFE_FILL_BEHIND_NULL)) + { + size_t cbRemaining; + + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + cbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + + // handle the STRSAFE_FILL_BEHIND_NULL flag + RtlStringExHandleFillBehindNullW(pszDestEnd, cbRemaining, dwFlags); + } + } + } + else + { + if (cchDest != 0) + { + *pszDest = L'\0'; + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)) && + (cbDest != 0)) + { + // handle the STRSAFE_FILL_ON_FAILURE, STRSAFE_NULL_ON_FAILURE, and STRSAFE_NO_TRUNCATION flags + RtlStringExHandleOtherFlagsW(pszDest, + cbDest, + 0, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcbRemaining) + { + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + *pcbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + } + } + } + + return status; +} +#endif // !NTSTRSAFE_NO_CB_FUNCTIONS + +#endif // !_M_CEE_PURE + + +#ifndef NTSTRSAFE_NO_CCH_FUNCTIONS +/*++ + +NTSTATUS +RtlStringCchVPrintfEx( + __out_ecount(cchDest) LPTSTR pszDest OPTIONAL, + __in size_t cchDest, + __deref_opt_out_ecount(*pcchRemaining) LPTSTR* ppszDestEnd OPTIONAL, + __out_opt size_t* pcchRemaining OPTIONAL, + __in DWORD dwFlags, + __in __format_string LPCTSTR pszFormat OPTIONAL, + __in va_list argList + ); + + +Routine Description: + + This routine is a safer version of the C built-in function 'vsprintf' with + some additional parameters. In addition to functionality provided by + RtlStringCchVPrintf, this routine also returns a pointer to the end of the + destination string and the number of characters left in the destination string + including the null terminator. The flags parameter allows additional controls. + +Arguments: + + pszDest - destination string + + cchDest - size of destination buffer in characters. + length must be sufficient to contain the resulting + formatted string plus the null terminator. + + ppszDestEnd - if ppszDestEnd is non-null, the function will return a + pointer to the end of the destination string. If the + function printed any data, the result will point to the + null termination character + + pcchRemaining - if pcchRemaining is non-null, the function will return + the number of characters left in the destination string, + including the null terminator + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND_NULL + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + behind the null terminator + + STRSAFE_IGNORE_NULLS + treat NULL string pointers like empty strings (TEXT("")) + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer, and it will + be null terminated. This will overwrite any truncated + string returned when the failure is + STATUS_BUFFER_OVERFLOW + + STRSAFE_NO_TRUNCATION / + STRSAFE_NULL_ON_FAILURE + if the function fails, the destination buffer will be set + to the empty string. This will overwrite any truncated string + returned when the failure is STATUS_BUFFER_OVERFLOW. + + pszFormat - format string which must be null terminated + + argList - va_list from the variable arguments according to the + stdarg.h convention + +Notes: + Behavior is undefined if destination, format strings or any arguments + strings overlap. + + pszDest and pszFormat should not be NULL unless the STRSAFE_IGNORE_NULLS + flag is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and + pszFormat may be NULL. An error may still be returned even though NULLS + are ignored due to insufficient space. + +Return Value: + + STATUS_SUCCESS - if there was source data and it was all concatenated and + the resultant dest string was null terminated + + failure - the operation did not succeed + + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the print + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result and is + null terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlStringCchVPrintfExA( + __out_ecount(cchDest) NTSTRSAFE_PSTR pszDest, + __in size_t cchDest, + __deref_opt_out_ecount(*pcchRemaining) NTSTRSAFE_PSTR* ppszDestEnd, + __out_opt size_t* pcchRemaining, + __in DWORD dwFlags, + __in __format_string NTSTRSAFE_PCSTR pszFormat, + __in va_list argList) +{ + NTSTATUS status; + + status = RtlStringExValidateDestA(pszDest, cchDest, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + NTSTRSAFE_PSTR pszDestEnd = pszDest; + size_t cchRemaining = cchDest; + + status = RtlStringExValidateSrcA(&pszFormat, NULL, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + + if (cchDest != 0) + { + *pszDest = '\0'; + } + } + else if (cchDest == 0) + { + // only fail if there was actually a non-empty format string + if (*pszFormat != '\0') + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + size_t cchNewDestLength = 0; + + status = RtlStringVPrintfWorkerA(pszDest, + cchDest, + &cchNewDestLength, + pszFormat, + argList); + + pszDestEnd = pszDest + cchNewDestLength; + cchRemaining = cchDest - cchNewDestLength; + + if (NT_SUCCESS(status) && + (dwFlags & STRSAFE_FILL_BEHIND_NULL) && + (cchRemaining > 1)) + { + size_t cbRemaining; + + // safe to multiply cchRemaining * sizeof(char) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(char) is 1 + cbRemaining = cchRemaining * sizeof(char); + + // handle the STRSAFE_FILL_BEHIND_NULL flag + RtlStringExHandleFillBehindNullA(pszDestEnd, cbRemaining, dwFlags); + } + } + } + else + { + if (cchDest != 0) + { + *pszDest = '\0'; + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)) && + (cchDest != 0)) + { + size_t cbDest; + + // safe to multiply cchDest * sizeof(char) since cchDest < NTSTRSAFE_MAX_CCH and sizeof(char) is 1 + cbDest = cchDest * sizeof(char); + + // handle the STRSAFE_FILL_ON_FAILURE, STRSAFE_NULL_ON_FAILURE, and STRSAFE_NO_TRUNCATION flags + RtlStringExHandleOtherFlagsA(pszDest, + cbDest, + 0, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcchRemaining) + { + *pcchRemaining = cchRemaining; + } + } + } + + return status; +} + +NTSTRSAFEDDI +RtlStringCchVPrintfExW( + __out_ecount(cchDest) NTSTRSAFE_PWSTR pszDest, + __in size_t cchDest, + __deref_opt_out_ecount(*pcchRemaining) NTSTRSAFE_PWSTR* ppszDestEnd, + __out_opt size_t* pcchRemaining, + __in DWORD dwFlags, + __in __format_string NTSTRSAFE_PCWSTR pszFormat, + __in va_list argList) +{ + NTSTATUS status; + + status = RtlStringExValidateDestW(pszDest, cchDest, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + NTSTRSAFE_PWSTR pszDestEnd = pszDest; + size_t cchRemaining = cchDest; + + status = RtlStringExValidateSrcW(&pszFormat, NULL, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + + if (cchDest != 0) + { + *pszDest = L'\0'; + } + } + else if (cchDest == 0) + { + // only fail if there was actually a non-empty format string + if (*pszFormat != L'\0') + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + size_t cchNewDestLength = 0; + + status = RtlStringVPrintfWorkerW(pszDest, + cchDest, + &cchNewDestLength, + pszFormat, + argList); + + pszDestEnd = pszDest + cchNewDestLength; + cchRemaining = cchDest - cchNewDestLength; + + if (NT_SUCCESS(status) && + (dwFlags & STRSAFE_FILL_BEHIND_NULL) && + (cchRemaining > 1)) + { + size_t cbRemaining; + + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + cbRemaining = cchRemaining * sizeof(wchar_t); + + // handle the STRSAFE_FILL_BEHIND_NULL flag + RtlStringExHandleFillBehindNullW(pszDestEnd, cbRemaining, dwFlags); + } + } + } + else + { + if (cchDest != 0) + { + *pszDest = L'\0'; + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)) && + (cchDest != 0)) + { + size_t cbDest; + + // safe to multiply cchDest * sizeof(wchar_t) since cchDest < NTSTRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + cbDest = cchDest * sizeof(wchar_t); + + // handle the STRSAFE_FILL_ON_FAILURE, STRSAFE_NULL_ON_FAILURE, and STRSAFE_NO_TRUNCATION flags + RtlStringExHandleOtherFlagsW(pszDest, + cbDest, + 0, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcchRemaining) + { + *pcchRemaining = cchRemaining; + } + } + } + + return status; +} +#endif // !NTSTRSAFE_NO_CCH_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CB_FUNCTIONS +/*++ + +NTSTATUS +RtlStringCbVPrintfEx( + __out_bcount(cbDest) LPTSTR pszDest OPTIONAL, + __in size_t cbDest, + __deref_opt_out_bcount(*pcbRemaining) LPTSTR* ppszDestEnd OPTIONAL, + __out_opt size_t* pcbRemaining OPTIONAL, + __in DWORD dwFlags, + __in __format_string LPCTSTR pszFormat OPTIONAL, + __in va_list argList + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'vsprintf' with + some additional parameters. In addition to functionality provided by + RtlStringCbVPrintf, this routine also returns a pointer to the end of the + destination string and the number of characters left in the destination string + including the null terminator. The flags parameter allows additional controls. + +Arguments: + + pszDest - destination string + + cbDest - size of destination buffer in bytes. + length must be sufficient to contain the resulting + formatted string plus the null terminator. + + ppszDestEnd - if ppszDestEnd is non-null, the function will return + a pointer to the end of the destination string. If the + function printed any data, the result will point to the + null termination character + + pcbRemaining - if pcbRemaining is non-null, the function will return + the number of bytes left in the destination string, + including the null terminator + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND_NULL + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + behind the null terminator + + STRSAFE_IGNORE_NULLS + treat NULL string pointers like empty strings (TEXT("")) + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer, and it will + be null terminated. This will overwrite any truncated + string returned when the failure is + STATUS_BUFFER_OVERFLOW + + STRSAFE_NO_TRUNCATION / + STRSAFE_NULL_ON_FAILURE + if the function fails, the destination buffer will be set + to the empty string. This will overwrite any truncated string + returned when the failure is STATUS_BUFFER_OVERFLOW. + + pszFormat - format string which must be null terminated + + argList - va_list from the variable arguments according to the + stdarg.h convention + +Notes: + Behavior is undefined if destination, format strings or any arguments + strings overlap. + + pszDest and pszFormat should not be NULL unless the STRSAFE_IGNORE_NULLS + flag is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and + pszFormat may be NULL. An error may still be returned even though NULLS + are ignored due to insufficient space. + +Return Value: + + STATUS_SUCCESS - if there was source data and it was all concatenated and + the resultant dest string was null terminated + + failure - the operation did not succeed + + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the print + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result and is + null terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlStringCbVPrintfExA( + __out_bcount(cbDest) NTSTRSAFE_PSTR pszDest, + __in size_t cbDest, + __deref_opt_out_bcount(*pcbRemaining) NTSTRSAFE_PSTR* ppszDestEnd, + __out_opt size_t* pcbRemaining, + __in DWORD dwFlags, + __in __format_string NTSTRSAFE_PCSTR pszFormat, + __in va_list argList) +{ + NTSTATUS status; + size_t cchDest = cbDest / sizeof(char); + + status = RtlStringExValidateDestA(pszDest, cchDest, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + NTSTRSAFE_PSTR pszDestEnd = pszDest; + size_t cchRemaining = cchDest; + + status = RtlStringExValidateSrcA(&pszFormat, NULL, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + + if (cchDest != 0) + { + *pszDest = '\0'; + } + } + else if (cchDest == 0) + { + // only fail if there was actually a non-empty format string + if (*pszFormat != '\0') + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + size_t cchNewDestLength = 0; + + status = RtlStringVPrintfWorkerA(pszDest, + cchDest, + &cchNewDestLength, + pszFormat, + argList); + + pszDestEnd = pszDest + cchNewDestLength; + cchRemaining = cchDest - cchNewDestLength; + + if (NT_SUCCESS(status) && + (dwFlags & STRSAFE_FILL_BEHIND_NULL) && + (cchRemaining > 1)) + { + size_t cbRemaining; + + // safe to multiply cchRemaining * sizeof(char) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(char) is 1 + cbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)); + + // handle the STRSAFE_FILL_BEHIND_NULL flag + RtlStringExHandleFillBehindNullA(pszDestEnd, cbRemaining, dwFlags); + } + } + } + else + { + if (cchDest != 0) + { + *pszDest = '\0'; + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)) && + (cbDest != 0)) + { + // handle the STRSAFE_FILL_ON_FAILURE, STRSAFE_NULL_ON_FAILURE, and STRSAFE_NO_TRUNCATION flags + RtlStringExHandleOtherFlagsA(pszDest, + cbDest, + 0, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcbRemaining) + { + // safe to multiply cchRemaining * sizeof(char) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(char) is 1 + *pcbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)); + } + } + } + + return status; +} + +NTSTRSAFEDDI +RtlStringCbVPrintfExW( + __out_bcount(cbDest) NTSTRSAFE_PWSTR pszDest, + __in size_t cbDest, + __deref_opt_out_bcount(*pcbRemaining) NTSTRSAFE_PWSTR* ppszDestEnd, + __out_opt size_t* pcbRemaining, + __in DWORD dwFlags, + __in __format_string NTSTRSAFE_PCWSTR pszFormat, + __in va_list argList) +{ + NTSTATUS status; + size_t cchDest = cbDest / sizeof(wchar_t); + + status = RtlStringExValidateDestW(pszDest, cchDest, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + NTSTRSAFE_PWSTR pszDestEnd = pszDest; + size_t cchRemaining = cchDest; + + status = RtlStringExValidateSrcW(&pszFormat, NULL, NTSTRSAFE_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + + if (cchDest != 0) + { + *pszDest = L'\0'; + } + } + else if (cchDest == 0) + { + // only fail if there was actually a non-empty format string + if (*pszFormat != L'\0') + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + size_t cchNewDestLength = 0; + + status = RtlStringVPrintfWorkerW(pszDest, + cchDest, + &cchNewDestLength, + pszFormat, + argList); + + pszDestEnd = pszDest + cchNewDestLength; + cchRemaining = cchDest - cchNewDestLength; + + if (NT_SUCCESS(status) && (dwFlags & STRSAFE_FILL_BEHIND_NULL)) + { + size_t cbRemaining; + + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + cbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + + // handle the STRSAFE_FILL_BEHIND_NULL flag + RtlStringExHandleFillBehindNullW(pszDestEnd, cbRemaining, dwFlags); + } + } + } + else + { + if (cchDest != 0) + { + *pszDest = L'\0'; + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)) && + (cbDest != 0)) + { + // handle the STRSAFE_FILL_ON_FAILURE, STRSAFE_NULL_ON_FAILURE, and STRSAFE_NO_TRUNCATION flags + RtlStringExHandleOtherFlagsW(pszDest, + cbDest, + 0, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcbRemaining) + { + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + *pcbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + } + } + } + + return status; +} +#endif // !NTSTRSAFE_NO_CB_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CCH_FUNCTIONS +/*++ + +NTSTATUS +RtlStringCchLength( + __in LPCTSTR psz, + __in __in_range(1, NTSTRSAFE_MAX_CCH) size_t cchMax, + __out_opt __deref_out_range(<, cchMax) size_t* pcchLength OPTIONAL + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strlen'. + It is used to make sure a string is not larger than a given length, and + it optionally returns the current length in characters not including + the null terminator. + + This function returns an NTSTATUS value, and not a pointer. It returns + STATUS_SUCCESS if the string is non-null and the length including the null + terminator is less than or equal to cchMax characters. + +Arguments: + + psz - string to check the length of + + cchMax - maximum number of characters including the null terminator + that psz is allowed to contain + + pcch - if the function succeeds and pcch is non-null, the current length + in characters of psz excluding the null terminator will be returned. + This out parameter is equivalent to the return value of strlen(psz) + +Notes: + psz can be null but the function will fail + + cchMax should be greater than zero or the function will fail + +Return Value: + + STATUS_SUCCESS - psz is non-null and the length including the null + terminator is less than or equal to cchMax characters + + failure - the operation did not succeed + + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function. + +--*/ + +__checkReturn +NTSTRSAFEDDI +RtlStringCchLengthA( + __in STRSAFE_PCNZCH psz, + __in __in_range(1, NTSTRSAFE_MAX_CCH) size_t cchMax, + __out_opt __deref_out_range(<, cchMax) size_t* pcchLength) +{ + NTSTATUS status; + + if ((psz == NULL) || (cchMax > NTSTRSAFE_MAX_CCH)) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = RtlStringLengthWorkerA(psz, cchMax, pcchLength); + } + + if (!NT_SUCCESS(status) && pcchLength) + { + *pcchLength = 0; + } + + return status; +} + +__checkReturn +NTSTRSAFEDDI +RtlStringCchLengthW( + __in STRSAFE_PCNZWCH psz, + __in __in_range(1, NTSTRSAFE_MAX_CCH) size_t cchMax, + __out_opt __deref_out_range(<, cchMax) size_t* pcchLength) +{ + NTSTATUS status; + + if ((psz == NULL) || (cchMax > NTSTRSAFE_MAX_CCH)) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = RtlStringLengthWorkerW(psz, cchMax, pcchLength); + } + + if (!NT_SUCCESS(status) && pcchLength) + { + *pcchLength = 0; + } + + return status; +} +#endif // !NTSTRSAFE_NO_CCH_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CB_FUNCTIONS +/*++ + +NTSTATUS +RtlStringCbLength( + __in LPCTSTR psz, + __in __in_range(1, NTSTRSAFE_MAX_CCH * sizeof(TCHAR)) size_t cbMax, + __out_opt __deref_out_range(<, cbMax) size_t* pcbLength OPTIONAL + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strlen'. + It is used to make sure a string is not larger than a given length, and + it optionally returns the current length in bytes not including + the null terminator. + + This function returns an NTSTATUS value, and not a pointer. It returns + STATUS_SUCCESS if the string is non-null and the length including the null + terminator is less than or equal to cbMax bytes. + +Arguments: + + psz - string to check the length of + + cbMax - maximum number of bytes including the null terminator + that psz is allowed to contain + + pcb - if the function succeeds and pcb is non-null, the current length + in bytes of psz excluding the null terminator will be returned. + This out parameter is equivalent to the return value of strlen(psz) * sizeof(TCHAR) + +Notes: + psz can be null but the function will fail + + cbMax should be greater than or equal to sizeof(TCHAR) or the function will fail + +Return Value: + + STATUS_SUCCESS - psz is non-null and the length including the null + terminator is less than or equal to cbMax bytes + + failure - the operation did not succeed + + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function. + +--*/ + +__checkReturn +NTSTRSAFEDDI +RtlStringCbLengthA( + __in STRSAFE_PCNZCH psz, + __in __in_range(1, NTSTRSAFE_MAX_CCH * sizeof(char)) size_t cbMax, + __out_opt __deref_out_range(<, cbMax) size_t* pcbLength) +{ + NTSTATUS status; + size_t cchMax = cbMax / sizeof(char); + size_t cchLength = 0; + + if ((psz == NULL) || (cchMax > NTSTRSAFE_MAX_CCH)) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = RtlStringLengthWorkerA(psz, cchMax, &cchLength); + } + + if (pcbLength) + { + if (NT_SUCCESS(status)) + { + // safe to multiply cchLength * sizeof(char) since cchLength < NTSTRSAFE_MAX_CCH and sizeof(char) is 1 + *pcbLength = cchLength * sizeof(char); + } + else + { + *pcbLength = 0; + } + } + + return status; +} + +__checkReturn +NTSTRSAFEDDI +RtlStringCbLengthW( + __in STRSAFE_PCNZWCH psz, + __in __in_range(1, NTSTRSAFE_MAX_CCH * sizeof(wchar_t)) size_t cbMax, + __out_opt __deref_out_range(<, cbMax - 1) size_t* pcbLength) +{ + NTSTATUS status; + size_t cchMax = cbMax / sizeof(wchar_t); + size_t cchLength = 0; + + if ((psz == NULL) || (cchMax > NTSTRSAFE_MAX_CCH)) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = RtlStringLengthWorkerW(psz, cchMax, &cchLength); + } + + if (pcbLength) + { + if (NT_SUCCESS(status)) + { + // safe to multiply cchLength * sizeof(wchar_t) since cchLength < NTSTRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + *pcbLength = cchLength * sizeof(wchar_t); + } + else + { + *pcbLength = 0; + } + } + + return status; +} +#endif // !NTSTRSAFE_NO_CB_FUNCTIONS + +#ifndef NTSTRSAFE_NO_CCH_FUNCTIONS +/*++ + +NTSTATUS +RtlUnalignedStringCchLength( + __in LPCUTSTR psz, + __in __in_range(1, NTSTRSAFE_MAX_CCH) size_t cchMax, + __out_opt __deref_out_range(<, cchMax) size_t* pcchLength OPTIONAL + ); + +Routine Description: + + This routine is a version of RtlStringCchLength that accepts an unaligned string pointer. + + This function returns an NTSTATUS value, and not a pointer. It returns + STATUS_SUCCESS if the string is non-null and the length including the null + terminator is less than or equal to cchMax characters. + +Arguments: + + psz - string to check the length of + + cchMax - maximum number of characters including the null terminator + that psz is allowed to contain + + pcch - if the function succeeds and pcch is non-null, the current length + in characters of psz excluding the null terminator will be returned. + This out parameter is equivalent to the return value of strlen(psz) + +Notes: + psz can be null but the function will fail + + cchMax should be greater than zero or the function will fail + +Return Value: + + STATUS_SUCCESS - psz is non-null and the length including the null + terminator is less than or equal to cchMax characters + + failure - the operation did not succeed + + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function. + +--*/ + +#ifdef ALIGNMENT_MACHINE +__checkReturn +NTSTRSAFEDDI +RtlUnalignedStringCchLengthW( + __in STRSAFE_PCUNZWCH psz, + __in __in_range(1, NTSTRSAFE_MAX_CCH) size_t cchMax, + __out_opt __deref_out_range(<, cchMax) size_t* pcchLength) +{ + NTSTATUS status; + + if ((psz == NULL) || (cchMax > NTSTRSAFE_MAX_CCH)) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = RtlUnalignedStringLengthWorkerW(psz, cchMax, pcchLength); + } + + if (!NT_SUCCESS(status) && pcchLength) + { + *pcchLength = 0; + } + + return status; +} +#else +#define RtlUnalignedStringCchLengthW RtlStringCchLengthW +#endif // !ALIGNMENT_MACHINE +#endif // !NTSTRSAFE_NO_CCH_FUNCTIONS + +#ifndef NTSTRSAFE_NO_CB_FUNCTIONS +/*++ + +NTSTATUS +RtlUnalignedStringCbLength( + __in LPCUTSTR psz, + __in __in_range(1, NTSTRSAFE_MAX_CCH * sizeof(TCHAR)) size_t cbMax, + __out_opt __deref_out_range(<, cbMax) size_t* pcbLength OPTIONAL + ); + +Routine Description: + + This routine is a version of RtlStringCbLength that accepts an unaligned string pointer. + + This function returns an NTSTATUS value, and not a pointer. It returns + STATUS_SUCCESS if the string is non-null and the length including the null + terminator is less than or equal to cbMax bytes. + +Arguments: + + psz - string to check the length of + + cbMax - maximum number of bytes including the null terminator + that psz is allowed to contain + + pcb - if the function succeeds and pcb is non-null, the current length + in bytes of psz excluding the null terminator will be returned. + This out parameter is equivalent to the return value of strlen(psz) * sizeof(TCHAR) + +Notes: + psz can be null but the function will fail + + cbMax should be greater than or equal to sizeof(TCHAR) or the function will fail + +Return Value: + + STATUS_SUCCESS - psz is non-null and the length including the null + terminator is less than or equal to cbMax bytes + + failure - the operation did not succeed + + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function. + +--*/ + +#ifdef ALIGNMENT_MACHINE +__checkReturn +NTSTRSAFEDDI +RtlUnalignedStringCbLengthW( + __in STRSAFE_PCUNZWCH psz, + __in __in_range(1, NTSTRSAFE_MAX_CCH * sizeof(wchar_t)) size_t cbMax, + __out_opt __deref_out_range(<, cbMax - 1) size_t* pcbLength) +{ + NTSTATUS status; + size_t cchMax = cbMax / sizeof(wchar_t); + size_t cchLength = 0; + + if ((psz == NULL) || (cchMax > NTSTRSAFE_MAX_CCH)) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = RtlUnalignedStringLengthWorkerW(psz, cchMax, &cchLength); + } + + if (pcbLength) + { + if (NT_SUCCESS(status)) + { + // safe to multiply cchLength * sizeof(wchar_t) since cchLength < NTSTRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + *pcbLength = cchLength * sizeof(wchar_t); + } + else + { + *pcbLength = 0; + } + } + + return status; +} +#else +#define RtlUnalignedStringCbLengthW RtlStringCbLengthW +#endif // !ALIGNMENT_MACHINE +#endif // !NTSTRSAFE_NO_CB_FUNCTIONS + +#ifndef NTSTRSAFE_NO_UNICODE_STRING_FUNCTIONS + +/*++ + +NTSTATUS +RtlUnicodeStringInit( + __out PUNICODE_STRING DestinationString, + __in_opt NTSTRSAFE_PCWSTR pszSrc OPTIONAL + ); + +Routine Description: + + The RtlUnicodeStringInit function initializes a counted unicode string from + pszSrc. + + This function returns an NTSTATUS value. It returns STATUS_SUCCESS if the + counted unicode string was sucessfully initialized from pszSrc. In failure + cases the unicode string buffer will be set to NULL, and the Length and + MaximumLength members will be set to zero. + +Arguments: + + DestinationString - pointer to the counted unicode string to be initialized + + pszSrc - source string which must be null or null terminated + +Notes: + DestinationString should not be NULL. See RtlUnicodeStringInitEx if you require + the handling of NULL values. + +Return Value: + + STATUS_SUCCESS - + + failure - the operation did not succeed + + STATUS_INVALID_PARAMETER + - this return value is an indication that the source string + was too large and DestinationString could not be initialized + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function. + +--*/ + +NTSTRSAFEDDI +RtlUnicodeStringInit( + __out PUNICODE_STRING DestinationString, + __in_opt NTSTRSAFE_PCWSTR pszSrc) +{ + return RtlUnicodeStringInitWorker(DestinationString, + pszSrc, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + 0); +} + + +/*++ + +NTSTATUS +RtlUnicodeStringInitEx( + __out PUNICODE_STRING DestinationString, + __in_opt NTSTRSAFE_PCWSTR pszSrc OPTIONAL, + __in DWORD dwFlags + ); + +Routine Description: + + In addition to functionality provided by RtlUnicodeStringInit, this routine + includes the flags parameter allows additional controls. + + This function returns an NTSTATUS value. It returns STATUS_SUCCESS if the + counted unicode string was sucessfully initialized from pszSrc. In failure + cases the unicode string buffer will be set to NULL, and the Length and + MaximumLength members will be set to zero. + +Arguments: + + DestinationString - pointer to the counted unicode string to be initialized + + pszSrc - source string which must be null terminated + + dwFlags - controls some details of the initialization: + + STRSAFE_IGNORE_NULLS + do not fault on a NULL DestinationString pointer + +Return Value: + + STATUS_SUCCESS - + + failure - the operation did not succeed + + STATUS_INVALID_PARAMETER + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function. + +--*/ + +NTSTRSAFEDDI +RtlUnicodeStringInitEx( + __out PUNICODE_STRING DestinationString, + __in_opt NTSTRSAFE_PCWSTR pszSrc, + __in DWORD dwFlags) +{ + NTSTATUS status; + + if (dwFlags & (~STRSAFE_UNICODE_STRING_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = RtlUnicodeStringInitWorker(DestinationString, + pszSrc, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + dwFlags); + } + + if (!NT_SUCCESS(status) && DestinationString) + { + DestinationString->Length = 0; + DestinationString->MaximumLength = 0; + DestinationString->Buffer = NULL; + } + + return status; +} + + +/*++ + +NTSTATUS +RtlUnicodeStringValidate( + __in PCUNICODE_STRING SourceString + ); + +Routine Description: + + The RtlUnicodeStringValidate function checks the counted unicode string to make + sure that is is valid. + + This function returns an NTSTATUS value. It returns STATUS_SUCCESS if the + counted unicode string is valid. + +Arguments: + + SourceString - pointer to the counted unicode string to be checked + +Notes: + SourceString should not be NULL. See RtlUnicodeStringValidateEx if you require + the handling of NULL values. + +Return Value: + + STATUS_SUCCESS - SourceString is a valid counted unicode string + + failure - the operation did not succeed + + STATUS_INVALID_PARAMETER + - this return value is an indication that SourceString is not a valid + counted unicode string + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function. + +--*/ + +NTSTRSAFEDDI +RtlUnicodeStringValidate( + __in PCUNICODE_STRING SourceString) +{ + return RtlUnicodeStringValidateWorker(SourceString, NTSTRSAFE_UNICODE_STRING_MAX_CCH, 0); +} + + +/*++ + +NTSTATUS +RtlUnicodeStringValidateEx( + __in PCUNICODE_STRING SourceString OPTIONAL, + __in DWORD dwFlags + ); + +Routine Description: + + In addition to functionality provided by RtlUnicodeStringValidate, this routine + includes the flags parameter allows additional controls. + + This function returns an NTSTATUS value. It returns STATUS_SUCCESS if the + counted unicode string is valid. + +Arguments: + + SourceString - pointer to the counted unicode string to be checked + + dwFlags - controls some details of the validation: + + STRSAFE_IGNORE_NULLS + allows SourceString to be NULL (will return STATUS_SUCCESS for this case). + +Return Value: + + STATUS_SUCCESS - SourceString is a valid counted unicode string + + failure - the operation did not succeed + + STATUS_INVALID_PARAMETER + - this return value is an indication that the source string + is not a valide counted unicode string given the flags passed. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function. + +--*/ + +NTSTRSAFEDDI +RtlUnicodeStringValidateEx( + __in PCUNICODE_STRING SourceString, + __in DWORD dwFlags) +{ + NTSTATUS status; + + if (dwFlags & (~STRSAFE_UNICODE_STRING_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = RtlUnicodeStringValidateWorker(SourceString, NTSTRSAFE_UNICODE_STRING_MAX_CCH, dwFlags); + } + + return status; +} + + +/*++ + +NTSTATUS +RtlStringCchCopyUnicodeString( + __out_ecount(cchDest) PWSTR pszDest, + __in size_t cchDest, + __in PCUNICODE_STRING SourceString, + ); + +Routine Description: + + This routine copies a PUNICODE_STRING to a PWSTR. This function will not + write past the end of this buffer and it will ALWAYS null terminate the + destination buffer (unless it is zero length). + + This function returns an NTSTATUS value, and not a pointer. It returns + STATUS_SUCCESS if the string was copied without truncation, otherwise it + will return a failure code. In failure cases as much of SourceString will be + copied to pszDest as possible. + +Arguments: + + pszDest - destination string + + cchDest - size of destination buffer in characters. + length must be = ((DestinationString->Length / sizeof(wchar_t)) + 1) + to hold all of the source and null terminate the string. + + SourceString - pointer to the counted unicode source string + +Notes: + Behavior is undefined if source and destination strings overlap. + + SourceString and pszDest should not be NULL. See RtlStringCchCopyUnicodeStringEx + if you require the handling of NULL values. + +Return Value: + + STATUS_SUCCESS - if there was source data and it was all copied and the + resultant dest string was null terminated + + failure - the operation did not succeed + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the copy + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result and is + null terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function. + +--*/ + +NTSTRSAFEDDI +RtlStringCchCopyUnicodeString( + __out_ecount(cchDest) NTSTRSAFE_PWSTR pszDest, + __in size_t cchDest, + __in PCUNICODE_STRING SourceString) +{ + NTSTATUS status; + + status = RtlStringValidateDestW(pszDest, + cchDest, + NTSTRSAFE_UNICODE_STRING_MAX_CCH); + if (NT_SUCCESS(status)) + { + wchar_t* pszSrc; + size_t cchSrcLength; + + status = RtlUnicodeStringValidateSrcWorker(SourceString, + &pszSrc, + &cchSrcLength, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + 0); + + if (NT_SUCCESS(status)) + { + status = RtlStringCopyWideCharArrayWorker(pszDest, + cchDest, + NULL, + pszSrc, + cchSrcLength); + } + else + { + *pszDest = L'\0'; + } + } + + return status; +} + + +/*++ + +NTSTATUS +RtlStringCbCopyUnicodeString( + __out_bcount(cbDest) PWSTR pszDest, + __in size_t cbDest, + __in PCUNICODE_STRING SourceString, + ); + +Routine Description: + + This routine copies a PUNICODE_STRING to a PWSTR. This function will not + write past the end of this buffer and it will ALWAYS null terminate the + destination buffer (unless it is zero length). + + This function returns an NTSTATUS value, and not a pointer. It returns + STATUS_SUCCESS if the string was copied without truncation, otherwise it + will return a failure code. In failure cases as much of SourceString will be + copied to pszDest as possible. + +Arguments: + + pszDest - destination string + + cbDest - size of destination buffer in bytes. + length must be = (DestinationString->Length + sizeof(wchar_t)) + to hold all of the source and null terminate the string. + + SourceString - pointer to the counted unicode source string + +Notes: + Behavior is undefined if source and destination strings overlap. + + SourceString and pszDest should not be NULL. See RtlStringCbCopyUnicodeStringEx + if you require the handling of NULL values. + +Return Value: + + STATUS_SUCCESS - if there was source data and it was all copied and the + resultant dest string was null terminated + + failure - the operation did not succeed + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the copy + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result and is + null terminated. This is useful for situations where + truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function. + +--*/ + +NTSTRSAFEDDI +RtlStringCbCopyUnicodeString( + __out_bcount(cbDest) NTSTRSAFE_PWSTR pszDest, + __in size_t cbDest, + __in PCUNICODE_STRING SourceString) +{ + NTSTATUS status; + size_t cchDest = cbDest / sizeof(wchar_t); + + status = RtlStringValidateDestW(pszDest, + cchDest, + NTSTRSAFE_UNICODE_STRING_MAX_CCH); + if (NT_SUCCESS(status)) + { + wchar_t* pszSrc; + size_t cchSrcLength; + + status = RtlUnicodeStringValidateSrcWorker(SourceString, + &pszSrc, + &cchSrcLength, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + 0); + + if (NT_SUCCESS(status)) + { + status = RtlStringCopyWideCharArrayWorker(pszDest, + cchDest, + NULL, + pszSrc, + cchSrcLength); + } + else + { + // Suppress espx false positive - cchDest cannot be 0 here +#pragma warning(push) +#pragma warning(disable : __WARNING_POTENTIAL_BUFFER_OVERFLOW_HIGH_PRIORITY) + *pszDest = L'\0'; +#pragma warning(pop) + } + } + + return status; +} + + +/*++ + +NTSTATUS +RtlStringCchCopyUnicodeStringEx( + __out_ecount(cchDest) PWSTR pszDest OPTIONAL, + __in size_t cchDest, + __in PCUNICODE_STRING SourceString OPTIONAL, + __deref_opt_out_ecount(*pcchRemaining) PWSTR* ppszDestEnd OPTIONAL, + __out_opt size_t* pcchRemaining OPTIONAL, + __in DWORD dwFlags + ); + +Routine Description: + + This routine copies a PUNICODE_STRING to a PWSTR. In addition to + functionality provided by RtlStringCchCopyUnicodeString, this routine also + returns a pointer to the end of the destination string and the number of + characters left in the destination string including the null terminator. + The flags parameter allows additional controls. + +Arguments: + + pszDest - destination string + + cchDest - size of destination buffer in characters. + length must be = ((DestinationString->Length / sizeof(wchar_t)) + 1) + to hold all of the source and null terminate the string. + + SourceString - pointer to the counted unicode source string + + ppszDestEnd - if ppszDestEnd is non-null, the function will return a + pointer to the end of the destination string. If the + function copied any data, the result will point to the + null termination character + + pcchRemaining - if pcchRemaining is non-null, the function will return the + number of characters left in the destination string, + including the null terminator + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND_NULL + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + behind the null terminator + + STRSAFE_IGNORE_NULLS + treat NULL string pointers like empty strings (TEXT("")). + this flag is useful for emulating functions like lstrcpy + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer, and it will + be null terminated. This will overwrite any truncated + string returned when the failure is + STATUS_BUFFER_OVERFLOW + + STRSAFE_NO_TRUNCATION / + STRSAFE_NULL_ON_FAILURE + if the function fails, the destination buffer will be set + to the empty string. This will overwrite any truncated string + returned when the failure is STATUS_BUFFER_OVERFLOW. + +Notes: + Behavior is undefined if source and destination strings overlap. + + pszDest and SourceString should not be NULL unless the STRSAFE_IGNORE_NULLS flag + is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and SourceString + may be NULL. An error may still be returned even though NULLS are ignored + due to insufficient space. + +Return Value: + + STATUS_SUCCESS - if there was source data and it was all copied and the + resultant dest string was null terminated + + failure - the operation did not succeed + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the copy + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result. This is + useful for situations where truncation is ok + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function. + +--*/ + +NTSTRSAFEDDI +RtlStringCchCopyUnicodeStringEx( + __out_ecount(cchDest) NTSTRSAFE_PWSTR pszDest, + __in size_t cchDest, + __in PCUNICODE_STRING SourceString, + __deref_opt_out_ecount(*pcchRemaining) NTSTRSAFE_PWSTR* ppszDestEnd, + __out_opt size_t* pcchRemaining, + __in DWORD dwFlags) +{ + NTSTATUS status; + + status = RtlStringExValidateDestW(pszDest, + cchDest, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + dwFlags); + + if (NT_SUCCESS(status)) + { + wchar_t* pszSrc; + size_t cchSrcLength; + wchar_t* pszDestEnd = pszDest; + size_t cchRemaining = cchDest; + + status = RtlUnicodeStringValidateSrcWorker(SourceString, + &pszSrc, + &cchSrcLength, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + dwFlags); + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + + if (cchDest != 0) + { + *pszDest = L'\0'; + } + } + else if (cchDest == 0) + { + // only fail if there was actually src data to copy + if (cchSrcLength != 0) + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + size_t cchCopied = 0; + + status = RtlStringCopyWideCharArrayWorker(pszDest, + cchDest, + &cchCopied, + pszSrc, + cchSrcLength); + + pszDestEnd = pszDest + cchCopied; + cchRemaining = cchDest - cchCopied; + + if (NT_SUCCESS(status) && + (dwFlags & STRSAFE_FILL_BEHIND_NULL) && + (cchRemaining > 1)) + { + size_t cbRemaining; + + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + cbRemaining = cchRemaining * sizeof(wchar_t); + + // handle the STRSAFE_FILL_BEHIND_NULL flag + RtlStringExHandleFillBehindNullW(pszDestEnd, cbRemaining, dwFlags); + } + } + } + else + { + if (cchDest != 0) + { + *pszDest = L'\0'; + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)) && + (cchDest != 0)) + { + size_t cbDest; + + // safe to multiply cchDest * sizeof(wchar_t) since cchDest < NTSTRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + cbDest = cchDest * sizeof(wchar_t); + + // handle the STRSAFE_FILL_ON_FAILURE, STRSAFE_NULL_ON_FAILURE, and STRSAFE_NO_TRUNCATION flags + RtlStringExHandleOtherFlagsW(pszDest, + cbDest, + 0, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcchRemaining) + { + *pcchRemaining = cchRemaining; + } + } + } + + return status; +} + + +/*++ + +NTSTATUS +RtlStringCbCopyUnicodeStringEx( + __out_bcount(cbDest) PWSTR pszDest OPTIONAL, + __in size_t cbDest, + __in PCUNICODE_STRING SourceString OPTIONAL, + __deref_opt_out_bcount(*pcbRemaining) PWSTR* ppszDestEnd OPTIONAL, + __out_opt size_t* pcbRemaining OPTIONAL, + __in DWORD dwFlags + ); + +Routine Description: + + This routine copies a PUNICODE_STRING to a PWSTR. In addition to + functionality provided by RtlStringCbCopyUnicodeString, this routine also + returns a pointer to the end of the destination string and the number of + characters left in the destination string including the null terminator. + The flags parameter allows additional controls. + +Arguments: + + pszDest - destination string + + cchDest - size of destination buffer in characters. + length must be = ((DestinationString->Length / sizeof(wchar_t)) + 1) + to hold all of the source and null terminate the string. + + SourceString - pointer to the counted unicode source string + + ppszDestEnd - if ppszDestEnd is non-null, the function will return a + pointer to the end of the destination string. If the + function copied any data, the result will point to the + null termination character + + pcbRemaining - pcbRemaining is non-null,the function will return the + number of bytes left in the destination string, + including the null terminator + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND_NULL + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + behind the null terminator + + STRSAFE_IGNORE_NULLS + treat NULL string pointers like empty strings (TEXT("")). + this flag is useful for emulating functions like lstrcpy + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer, and it will + be null terminated. This will overwrite any truncated + string returned when the failure is + STATUS_BUFFER_OVERFLOW + + STRSAFE_NO_TRUNCATION / + STRSAFE_NULL_ON_FAILURE + if the function fails, the destination buffer will be set + to the empty string. This will overwrite any truncated string + returned when the failure is STATUS_BUFFER_OVERFLOW. + +Notes: + Behavior is undefined if source and destination strings overlap. + + pszDest and SourceString should not be NULL unless the STRSAFE_IGNORE_NULLS flag + is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and SourceString + may be NULL. An error may still be returned even though NULLS are ignored + due to insufficient space. + +Return Value: + + STATUS_SUCCESS - if there was source data and it was all copied and the + resultant dest string was null terminated + + failure - the operation did not succeed + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the copy + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result. This is + useful for situations where truncation is ok + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function. + +--*/ + +NTSTRSAFEDDI +RtlStringCbCopyUnicodeStringEx( + __out_bcount(cbDest) NTSTRSAFE_PWSTR pszDest, + __in size_t cbDest, + __in PCUNICODE_STRING SourceString, + __deref_opt_out_bcount(*pcbRemaining) NTSTRSAFE_PWSTR* ppszDestEnd, + __out_opt size_t* pcbRemaining, + __in DWORD dwFlags) +{ + NTSTATUS status; + size_t cchDest = cbDest / sizeof(wchar_t); + + status = RtlStringExValidateDestW(pszDest, + cchDest, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + dwFlags); + + if (NT_SUCCESS(status)) + { + wchar_t* pszSrc; + size_t cchSrcLength; + wchar_t* pszDestEnd = pszDest; + size_t cchRemaining = cchDest; + + status = RtlUnicodeStringValidateSrcWorker(SourceString, + &pszSrc, + &cchSrcLength, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + dwFlags); + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + + if (cchDest != 0) + { + *pszDest = L'\0'; + } + } + else if (cchDest == 0) + { + // only fail if there was actually src data to copy + if (cchSrcLength != 0) + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + size_t cchCopied = 0; + + status = RtlStringCopyWideCharArrayWorker(pszDest, + cchDest, + &cchCopied, + pszSrc, + cchSrcLength); + + pszDestEnd = pszDest + cchCopied; + cchRemaining = cchDest - cchCopied; + + if (NT_SUCCESS(status) && (dwFlags & STRSAFE_FILL_BEHIND_NULL)) + { + size_t cbRemaining; + + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + cbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + + // handle the STRSAFE_FILL_BEHIND_NULL flag + RtlStringExHandleFillBehindNullW(pszDestEnd, cbRemaining, dwFlags); + } + } + } + else + { + if (cchDest != 0) + { + *pszDest = L'\0'; + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE)) && + (cbDest != 0)) + { + // handle the STRSAFE_FILL_ON_FAILURE, STRSAFE_NULL_ON_FAILURE, and STRSAFE_NO_TRUNCATION flags + RtlStringExHandleOtherFlagsW(pszDest, + cbDest, + 0, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (ppszDestEnd) + { + *ppszDestEnd = pszDestEnd; + } + + if (pcbRemaining) + { + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_MAX_CCH and sizeof(wchar_t) is 2 + *pcbRemaining = (cchRemaining * sizeof(wchar_t)) + (cbDest % sizeof(wchar_t)); + } + } + } + + return status; +} + + +/*++ + +NTSTATUS +RtlUnicodeStringCopyString( + __out PUNICODE_STRING DestinationString, + __in LPCTSTR pszSrc + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strcpy' for + UNICODE_STRINGs. + + This function returns an NTSTATUS value, and not a pointer. It returns + STATUS_SUCCESS if the string was copied without truncation, otherwise it + will return a failure code. In failure cases as much of pszSrc will be + copied to DestinationString as possible. + +Arguments: + + DestinationString - pointer to the counted unicode destination string + + pszSrc - source string which must be null terminated + +Notes: + Behavior is undefined if source and destination strings overlap. + + DestinationString and pszSrc should not be NULL. See RtlUnicodeStringCopyStringEx + if you require the handling of NULL values. + +Return Value: + + STATUS_SUCCESS - if there was source data and it was all copied + + failure - the operation did not succeed + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the copy + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result. This is + useful for situations where truncation is ok + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function. + +--*/ + +NTSTRSAFEDDI +RtlUnicodeStringCopyString( + __out PUNICODE_STRING DestinationString, + __in NTSTRSAFE_PCWSTR pszSrc) +{ + NTSTATUS status; + wchar_t* pszDest; + size_t cchDest; + + status = RtlUnicodeStringValidateDestWorker(DestinationString, + &pszDest, + &cchDest, + NULL, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + 0); + + if (NT_SUCCESS(status)) + { + size_t cchNewDestLength = 0; + + status = RtlWideCharArrayCopyStringWorker(pszDest, + cchDest, + &cchNewDestLength, + pszSrc, + NTSTRSAFE_UNICODE_STRING_MAX_CCH); + + // safe to multiply cchNewDestLength * sizeof(wchar_t) since cchDest < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + DestinationString->Length = (USHORT)(cchNewDestLength * sizeof(wchar_t)); + } + + return status; +} + + +/*++ + +NTSTATUS +RtlUnicodeStringCopy( + __out PUNICODE_STRING DestinationString, + __in PCUNICODE_STRING SourceString + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strcpy' for + UNICODE_STRINGs. + + This function returns an NTSTATUS value, and not a pointer. It returns + STATUS_SUCCESS if the string was copied without truncation, otherwise it + will return a failure code. In failure cases as much of SourceString + will be copied to Dest as possible. + +Arguments: + + DestinationString - pointer to the counted unicode destination string + + SourceString - pointer to the counted unicode source string + +Notes: + Behavior is undefined if source and destination strings overlap. + + DestinationString and SourceString should not be NULL. See RtlUnicodeStringCopyEx + if you require the handling of NULL values. + +Return Value: + + STATUS_SUCCESS - if there was source data and it was all copied + + failure - the operation did not succeed + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the copy + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result. This is + useful for situations where truncation is ok + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function. + +--*/ + +NTSTRSAFEDDI +RtlUnicodeStringCopy( + __out PUNICODE_STRING DestinationString, + __in PCUNICODE_STRING SourceString) +{ + NTSTATUS status; + wchar_t* pszDest; + size_t cchDest; + + status = RtlUnicodeStringValidateDestWorker(DestinationString, + &pszDest, + &cchDest, + NULL, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + 0); + + if (NT_SUCCESS(status)) + { + wchar_t* pszSrc; + size_t cchSrcLength; + size_t cchNewDestLength = 0; + + status = RtlUnicodeStringValidateSrcWorker(SourceString, + &pszSrc, + &cchSrcLength, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + 0); + + if (NT_SUCCESS(status)) + { + status = RtlWideCharArrayCopyWorker(pszDest, + cchDest, + &cchNewDestLength, + pszSrc, + cchSrcLength); + } + + // safe to multiply cchNewDestLength * sizeof(wchar_t) since cchDest < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + DestinationString->Length = (USHORT)(cchNewDestLength * sizeof(wchar_t)); + } + + return status; +} + + +/*++ + +NTSTATUS +RtlUnicodeStringCopyStringEx( + __out PUNICODE_STRING DestinationString OPTIONAL, + __in LPCTSTR pszSrc OPTIONAL, + __out_opt PUNICODE_STRING RemainingString OPTIONAL, + __in DWORD dwFlags + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strcpy' for + UNICODE_STRINGs with some additional parameters. In addition to the + functionality provided by RtlUnicodeStringCopyString, this routine also + returns a PUNICODE_STRING which points to the end of the destination + string. The flags parameter allows additional controls. + +Arguments: + + DestinationString - pointer to the counted unicode destination string + + pszSrc - source string which must be null terminated + + RemainingString - if RemainingString is non-null, the function will format + the pointer with the remaining buffer and number of + bytes left in the destination string + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + + STRSAFE_IGNORE_NULLS + do not fault if DestinationString is null and treat NULL pszSrc like + empty strings (L""). This flag is useful for emulating + functions like lstrcpy + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer. This will + overwrite any truncated string returned when the failure is + STATUS_BUFFER_OVERFLOW + + STRSAFE_NO_TRUNCATION / + STRSAFE_ZERO_LENGTH_ON_FAILURE + if the function fails, the destination Length will be set + to zero. This will overwrite any truncated string + returned when the failure is STATUS_BUFFER_OVERFLOW. + +Notes: + Behavior is undefined if source and destination strings overlap. + + DestinationString and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag + is specified. If STRSAFE_IGNORE_NULLS is passed, both DestinationString and pszSrc + may be NULL. An error may still be returned even though NULLS are ignored. + + Behavior is undefined if DestinationString and RemainingString are the same pointer. + +Return Value: + + STATUS_SUCCESS - if there was source data and it was all copied + + failure - the operation did not succeed + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the copy + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result. + This is useful for situations where truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlUnicodeStringCopyStringEx( + __out PUNICODE_STRING DestinationString, + __in NTSTRSAFE_PCWSTR pszSrc, + __out_opt PUNICODE_STRING RemainingString, + __in DWORD dwFlags) +{ + NTSTATUS status; + wchar_t* pszDest; + size_t cchDest; + + status = RtlUnicodeStringValidateDestWorker(DestinationString, + &pszDest, + &cchDest, + NULL, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + dwFlags); + + if (NT_SUCCESS(status)) + { + wchar_t* pszDestEnd = pszDest; + size_t cchRemaining = cchDest; + size_t cchNewDestLength = 0; + + status = RtlStringExValidateSrcW(&pszSrc, NULL, NTSTRSAFE_UNICODE_STRING_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_UNICODE_STRING_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + } + else if (cchDest == 0) + { + // only fail if there was actually src data to copy + if (*pszSrc != L'\0') + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + status = RtlWideCharArrayCopyStringWorker(pszDest, + cchDest, + &cchNewDestLength, + pszSrc, + NTSTRSAFE_UNICODE_STRING_MAX_CCH); + + pszDestEnd = pszDest + cchNewDestLength; + cchRemaining = cchDest - cchNewDestLength; + + if (NT_SUCCESS(status) && + (dwFlags & STRSAFE_FILL_BEHIND) && + (cchRemaining != 0)) + { + // handle the STRSAFE_FILL_BEHIND flag + RtlUnicodeStringExHandleFill(pszDestEnd, cchRemaining, dwFlags); + } + } + } + + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_ZERO_LENGTH_ON_FAILURE)) && + (cchDest != 0)) + { + // handle the STRSAFE_NO_TRUNCATION, STRSAFE_FILL_ON_FAILURE, and STRSAFE_ZERO_LENGTH_ON_FAILURE flags + RtlUnicodeStringExHandleOtherFlags(pszDest, + cchDest, + 0, + &cchNewDestLength, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (DestinationString) + { + // safe to multiply cchNewDestLength * sizeof(wchar_t) since cchDest < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + DestinationString->Length = (USHORT)(cchNewDestLength * sizeof(wchar_t)); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (RemainingString) + { + RemainingString->Length = 0; + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + RemainingString->MaximumLength = (USHORT)(cchRemaining * sizeof(wchar_t)); + RemainingString->Buffer = pszDestEnd; + } + } + } + + return status; +} + + +/*++ + +NTSTATUS +RtlUnicodeStringCopyEx( + __out PUNICODE_STRING DestinationString OPTIONAL, + __in PCUNICODE_STRING SourceString OPTIONAL, + __out_opt PUNICODE_STRING RemainingString OPTIONAL, + __in DWORD dwFlags + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strcpy' for + UNICODE_STRINGs with some additional parameters. In addition to the + functionality provided by RtlUnicodeStringCopy, this routine + also returns a PUNICODE_STRING which points to the end of the destination + string. The flags parameter allows additional controls. + +Arguments: + + DestinationString - pointer to the counted unicode destination string + + SourceString - pointer to the counted unicode source string + + RemainingString - if RemainingString is non-null, the function will format + the pointer with the remaining buffer and number of + bytes left in the destination string + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + + STRSAFE_IGNORE_NULLS + do not fault if DestinationString is null and treat NULL pszSrc like + empty strings (L""). This flag is useful for emulating + functions like lstrcpy + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer. This will + overwrite any truncated string returned when the failure is + STATUS_BUFFER_OVERFLOW + + STRSAFE_NO_TRUNCATION / + STRSAFE_ZERO_LENGTH_ON_FAILURE + if the function fails, the destination Length will be set + to zero. This will overwrite any truncated string + returned when the failure is STATUS_BUFFER_OVERFLOW. + +Notes: + Behavior is undefined if source and destination strings overlap. + + DestinationString and SourceString should not be NULL unless the STRSAFE_IGNORE_NULLS flag + is specified. If STRSAFE_IGNORE_NULLS is passed, both DestinationString and SourceString + may be NULL. An error may still be returned even though NULLS are ignored. + + Behavior is undefined if DestinationString and RemainingString are the same pointer. + +Return Value: + + STATUS_SUCCESS - if there was source data and it was all copied + + failure - the operation did not succeed + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the copy + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result. + This is useful for situations where truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlUnicodeStringCopyEx( + __out PUNICODE_STRING DestinationString, + __in PCUNICODE_STRING SourceString, + __out_opt PUNICODE_STRING RemainingString, + __in DWORD dwFlags) +{ + NTSTATUS status; + wchar_t* pszDest; + size_t cchDest; + + status = RtlUnicodeStringValidateDestWorker(DestinationString, + &pszDest, + &cchDest, + NULL, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + dwFlags); + + if (NT_SUCCESS(status)) + { + wchar_t* pszSrc; + size_t cchSrcLength; + wchar_t* pszDestEnd = pszDest; + size_t cchRemaining = cchDest; + size_t cchNewDestLength = 0; + + status = RtlUnicodeStringValidateSrcWorker(SourceString, + &pszSrc, + &cchSrcLength, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + dwFlags); + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_UNICODE_STRING_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + } + else if (cchDest == 0) + { + // only fail if there was actually src data to copy + if (cchSrcLength != 0) + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + status = RtlWideCharArrayCopyWorker(pszDest, + cchDest, + &cchNewDestLength, + pszSrc, + cchSrcLength); + + pszDestEnd = pszDest + cchNewDestLength; + cchRemaining = cchDest - cchNewDestLength; + + if (NT_SUCCESS(status) && + (dwFlags & STRSAFE_FILL_BEHIND) && + (cchRemaining != 0)) + { + // handle the STRSAFE_FILL_BEHIND flag + RtlUnicodeStringExHandleFill(pszDestEnd, cchRemaining, dwFlags); + } + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_ZERO_LENGTH_ON_FAILURE)) && + (cchDest != 0)) + { + // handle the STRSAFE_NO_TRUNCATION, STRSAFE_FILL_ON_FAILURE, and STRSAFE_ZERO_LENGTH_ON_FAILURE flags + RtlUnicodeStringExHandleOtherFlags(pszDest, + cchDest, + 0, + &cchNewDestLength, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (DestinationString) + { + // safe to multiply cchNewDestLength * sizeof(wchar_t) since cchDest < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + DestinationString->Length = (USHORT)(cchNewDestLength * sizeof(wchar_t)); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (RemainingString) + { + RemainingString->Length = 0; + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + RemainingString->MaximumLength = (USHORT)(cchRemaining * sizeof(wchar_t)); + RemainingString->Buffer = pszDestEnd; + } + } + } + + return status; +} + + +#ifndef NTSTRSAFE_NO_CCH_FUNCTIONS +/*++ + +NTSTATUS +RtlUnicodeStringCchCopyStringN( + __out PUNICODE_STRING DestinationString, + __in LPCTSTR pszSrc, + __in size_t cchToCopy + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strncpy' for + PUNICODE_STRINGs. + + This function returns an NTSTATUS value, and not a pointer. It returns + STATUS_SUCCESS if the entire string or the first cchToCopy characters were + copied without truncation, otherwise it will return a failure code. In + failure cases as much of pszSrc will be copied to DestinationString as possible. + +Arguments: + + DestinationString - pointer to the counted unicode destination string + + pszSrc - source string + + cchToCopy - maximum number of characters to copy from source string, + not including the null terminator. + +Notes: + Behavior is undefined if source and destination strings overlap. + + DestinationString and pszSrc should not be NULL. See RtlUnicodeStringCchCopyStringNEx if + you require the handling of NULL values. + +Return Value: + + STATUS_SUCCESS - if there was source data and it was all copied + + failure - the operation did not succeed + + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the copy + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result. This is + useful for situations where truncation is ok + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function. + +--*/ + +NTSTRSAFEDDI +RtlUnicodeStringCchCopyStringN( + __out PUNICODE_STRING DestinationString, + __in NTSTRSAFE_PCWSTR pszSrc, + __in size_t cchToCopy) +{ + NTSTATUS status; + wchar_t* pszDest; + size_t cchDest; + + status = RtlUnicodeStringValidateDestWorker(DestinationString, + &pszDest, + &cchDest, + NULL, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + 0); + + if (NT_SUCCESS(status)) + { + size_t cchNewDestLength = 0; + + if (cchToCopy > NTSTRSAFE_UNICODE_STRING_MAX_CCH) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = RtlWideCharArrayCopyStringWorker(pszDest, + cchDest, + &cchNewDestLength, + pszSrc, + cchToCopy); + } + + // safe to multiply cchNewDestLength * sizeof(wchar_t) since cchDest < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + DestinationString->Length = (USHORT)(cchNewDestLength * sizeof(wchar_t)); + } + + return status; +} +#endif // !NTSTRSAFE_NO_CCH_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CB_FUNCTIONS +/*++ + +NTSTATUS +RtlUnicodeStringCbCopyStringN( + __out PUNICODE_STRING DestinationString, + __in LPCTSTR pszSrc, + __in size_t cbToCopy + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strncpy' for + PUNICODE_STRINGs. + + This function returns an NTSTATUS value, and not a pointer. It returns + STATUS_SUCCESS if the entire string or the first cbToCopy bytes were + copied without truncation, otherwise it will return a failure code. In + failure cases as much of pszSrc will be copied to DestinationString as possible. + +Arguments: + + DestinationString - pointer to the counted unicode destination string + + pszSrc - source string + + cbToCopy - maximum number of bytes to copy from source string, + not including the null terminator. + +Notes: + Behavior is undefined if source and destination strings overlap. + + DestinationString and pszSrc should not be NULL. See RtlUnicodeStringCopyCbStringEx if you require + the handling of NULL values. + +Return Value: + + STATUS_SUCCESS - if there was source data and it was all copied + + failure - the operation did not succeed + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the copy + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result. This is + useful for situations where truncation is ok + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function. + +--*/ + +NTSTRSAFEDDI +RtlUnicodeStringCbCopyStringN( + __out PUNICODE_STRING DestinationString, + __in NTSTRSAFE_PCWSTR pszSrc, + __in size_t cbToCopy) +{ + NTSTATUS status; + wchar_t* pszDest; + size_t cchDest; + + status = RtlUnicodeStringValidateDestWorker(DestinationString, + &pszDest, + &cchDest, + NULL, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + 0); + + if (NT_SUCCESS(status)) + { + size_t cchNewDestLength = 0; + size_t cchToCopy = cbToCopy / sizeof(wchar_t); + + if (cchToCopy > NTSTRSAFE_UNICODE_STRING_MAX_CCH) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = RtlWideCharArrayCopyStringWorker(pszDest, + cchDest, + &cchNewDestLength, + pszSrc, + cchToCopy); + } + + // safe to multiply cchNewDestLength * sizeof(wchar_t) since cchDest < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + DestinationString->Length = (USHORT)(cchNewDestLength * sizeof(wchar_t)); + } + + return status; +} +#endif // !NTSTRSAFE_NO_CB_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CCH_FUNCTIONS +/*++ + +NTSTATUS +RtlUnicodeStringCchCopyN( + __out PUNICODE_STRING DestinationString, + __in PCUNICODE_STRING SourceString, + __in size_t cchToCopy + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strncpy' for + PUNICODE_STRINGs. + + This function returns an NTSTATUS value, and not a pointer. It returns + STATUS_SUCCESS if the entire string or the first cchToCopy characters were + copied without truncation, otherwise it will return a failure code. In + failure cases as much of SourceString will be copied to DestinationString as possible. + +Arguments: + + DestinationString - pointer to the counted unicode destination string + + SourceString - pointer to the counted unicode source string + + cchToCopy - maximum number of characters to copy from source string, + not including the null terminator. + +Notes: + Behavior is undefined if source and destination strings overlap. + + DestinationString and SourceString should not be NULL. See RtlUnicodeStringCchCopyNEx + if you require the handling of NULL values. + +Return Value: + + STATUS_SUCCESS - if there was source data and it was all copied + + failure - the operation did not succeed + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the copy + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result. This is + useful for situations where truncation is ok + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function. + +--*/ + +NTSTRSAFEDDI +RtlUnicodeStringCchCopyN( + __out PUNICODE_STRING DestinationString, + __in PCUNICODE_STRING SourceString, + __in size_t cchToCopy) +{ + NTSTATUS status; + wchar_t* pszDest; + size_t cchDest; + + status = RtlUnicodeStringValidateDestWorker(DestinationString, + &pszDest, + &cchDest, + NULL, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + 0); + + if (NT_SUCCESS(status)) + { + wchar_t* pszSrc; + size_t cchSrcLength; + size_t cchNewDestLength = 0; + + status = RtlUnicodeStringValidateSrcWorker(SourceString, + &pszSrc, + &cchSrcLength, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + 0); + + if (NT_SUCCESS(status)) + { + if (cchToCopy > NTSTRSAFE_UNICODE_STRING_MAX_CCH) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + if (cchSrcLength < cchToCopy) + { + cchToCopy = cchSrcLength; + } + + status = RtlWideCharArrayCopyWorker(pszDest, + cchDest, + &cchNewDestLength, + pszSrc, + cchToCopy); + } + } + + // safe to multiply cchNewDestLength * sizeof(wchar_t) since cchDest < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + DestinationString->Length = (USHORT)(cchNewDestLength * sizeof(wchar_t)); + } + + return status; +} +#endif // !NTSTRSAFE_NO_CCH_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CB_FUNCTIONS +/*++ + +NTSTATUS +RtlUnicodeStringCbCopyN( + __out PUNICODE_STRING DestinationString, + __in PCUNICODE_STRING SourceString, + __in size_t cbToCopy + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strncpy' for + PUNICODE_STRINGs. + + This function returns an NTSTATUS value, and not a pointer. It returns + STATUS_SUCCESS if the entire string or the first cbToCopy bytes were + copied without truncation, otherwise it will return a failure code. In + failure cases as much of SourceString will be copied to DestinationString as possible. + +Arguments: + + DestinationString - pointer to the counted unicode destination string + + SourceString - pointer to the counted unicode source string + + cbToCopy - maximum number of bytes to copy from source string, + not including the null terminator. + +Notes: + Behavior is undefined if source and destination strings overlap. + + DestinationString and SourceString should not be NULL. See RtlUnicodeStringCbCopyNEx + if you require the handling of NULL values. + +Return Value: + + STATUS_SUCCESS - if there was source data and it was all copied + + failure - the operation did not succeed + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the copy + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result. This is + useful for situations where truncation is ok + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function. + +--*/ + + +NTSTRSAFEDDI +RtlUnicodeStringCbCopyN( + __out PUNICODE_STRING DestinationString, + __in PCUNICODE_STRING SourceString, + __in size_t cbToCopy) +{ + NTSTATUS status; + wchar_t* pszDest; + size_t cchDest; + + status = RtlUnicodeStringValidateDestWorker(DestinationString, + &pszDest, + &cchDest, + NULL, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + 0); + + if (NT_SUCCESS(status)) + { + wchar_t* pszSrc; + size_t cchSrcLength; + size_t cchNewDestLength = 0; + + status = RtlUnicodeStringValidateSrcWorker(SourceString, + &pszSrc, + &cchSrcLength, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + 0); + + if (NT_SUCCESS(status)) + { + size_t cchToCopy = cbToCopy / sizeof(wchar_t); + + if (cchToCopy > NTSTRSAFE_UNICODE_STRING_MAX_CCH) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + if (cchSrcLength < cchToCopy) + { + cchToCopy = cchSrcLength; + } + + status = RtlWideCharArrayCopyWorker(pszDest, + cchDest, + &cchNewDestLength, + pszSrc, + cchToCopy); + } + } + + // safe to multiply cchNewDestLength * sizeof(wchar_t) since cchDest < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + DestinationString->Length = (USHORT)(cchNewDestLength * sizeof(wchar_t)); + } + + return status; +} +#endif // !NTSTRSAFE_NO_CB_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CCH_FUNCTIONS +/*++ + +NTSTATUS +RtlUnicodeStringCchCopyStringNEx( + __out PUNICODE_STRING DestinationString OPTIONAL, + __in LPCTSTR pszSrc OPTIONAL, + __in size_t cchToCopy, + __out_opt PUNICODE_STRING RemainingString OPTIONAL, + __in DWORD dwFlags + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strncpy' with + some additional parameters and for PUNICODE_STRINGs. In addition to the + functionality provided by RtlUnicodeStringCchCopyStringN, this routine also + returns a PUNICODE_STRING which points to the end of the destination + string. The flags parameter allows additional controls. + +Arguments: + + DestinationString - pointer to the counted unicode destination string + + pszSrc - source string + + cchToCopy - maximum number of characters to copy from source string + + RemainingString - if RemainingString is non-null, the function will format + the pointer with the remaining buffer and number of + bytes left in the destination string + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + + STRSAFE_IGNORE_NULLS + do not fault if DestinationString is null and treat NULL pszSrc like + empty strings (L""). This flag is useful for emulating + functions like lstrcpy + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer. This will + overwrite any truncated string returned when the failure is + STATUS_BUFFER_OVERFLOW + + STRSAFE_NO_TRUNCATION / + STRSAFE_ZERO_LENGTH_ON_FAILURE + if the function fails, the destination Length will be set + to zero. This will overwrite any truncated string + returned when the failure is STATUS_BUFFER_OVERFLOW. + +Notes: + Behavior is undefined if source and destination strings overlap. + + pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag + is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc + may be NULL. An error may still be returned even though NULLS are ignored + due to insufficient space. + +Return Value: + + STATUS_SUCCESS - if there was source data and it was all copied + + failure - the operation did not succeed + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the copy + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result. + This is useful for situations where truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlUnicodeStringCchCopyStringNEx( + __out PUNICODE_STRING DestinationString, + __in NTSTRSAFE_PCWSTR pszSrc, + __in size_t cchToCopy, + __out_opt PUNICODE_STRING RemainingString, + __in DWORD dwFlags) +{ + NTSTATUS status; + wchar_t* pszDest; + size_t cchDest; + + status = RtlUnicodeStringValidateDestWorker(DestinationString, + &pszDest, + &cchDest, + NULL, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + dwFlags); + + if (NT_SUCCESS(status)) + { + wchar_t* pszDestEnd = pszDest; + size_t cchRemaining = cchDest; + size_t cchNewDestLength = 0; + + status = RtlStringExValidateSrcW(&pszSrc, &cchToCopy, NTSTRSAFE_UNICODE_STRING_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_UNICODE_STRING_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + } + else if (cchDest == 0) + { + // only fail if there was actually src data to copy + if ((cchToCopy != 0) && (*pszSrc != L'\0')) + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + status = RtlWideCharArrayCopyStringWorker(pszDest, + cchDest, + &cchNewDestLength, + pszSrc, + cchToCopy); + + pszDestEnd = pszDest + cchNewDestLength; + cchRemaining = cchDest - cchNewDestLength; + + if (NT_SUCCESS(status) && + (dwFlags & STRSAFE_FILL_BEHIND) && + (cchRemaining != 0)) + { + // handle the STRSAFE_FILL_BEHIND flag + RtlUnicodeStringExHandleFill(pszDestEnd, cchRemaining, dwFlags); + } + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_ZERO_LENGTH_ON_FAILURE)) && + (cchDest != 0)) + { + // handle the STRSAFE_NO_TRUNCATION, STRSAFE_FILL_ON_FAILURE, and STRSAFE_ZERO_LENGTH_ON_FAILURE flags + RtlUnicodeStringExHandleOtherFlags(pszDest, + cchDest, + 0, + &cchNewDestLength, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (DestinationString) + { + // safe to multiply cchNewDestLength * sizeof(wchar_t) since cchDest < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + DestinationString->Length = (USHORT)(cchNewDestLength * sizeof(wchar_t)); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (RemainingString) + { + RemainingString->Length = 0; + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + RemainingString->MaximumLength = (USHORT)(cchRemaining * sizeof(wchar_t)); + RemainingString->Buffer = pszDestEnd; + } + } + } + + return status; +} +#endif // !NTSTRSAFE_NO_CCH_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CB_FUNCTIONS +/*++ + +NTSTATUS +RtlUnicodeStringCbCopyStringNEx( + __out PUNICODE_STRING DestinationString OPTIONAL, + __in LPCTSTR pszSrc OPTIONAL, + __in size_t cbToCopy, + __out_opt PUNICODE_STRING RemainingString OPTIONAL, + __in DWORD dwFlags + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strncpy' with + some additional parameters and for PUNICODE_STRINGs. In addition to the + functionality provided by RtlUnicodeStringCbCopyStringN, this routine also + returns a PUNICODE_STRING which points to the end of the destination + string. The flags parameter allows additional controls. + +Arguments: + + DestinationString - pointer to the counted unicode destination string + + pszSrc - source string + + cbToCopy - maximum number of bytes to copy from source string + + RemainingString - if RemainingString is non-null, the function will format + the pointer with the remaining buffer and number of + bytes left in the destination string + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + + STRSAFE_IGNORE_NULLS + do not fault if DestinationString is null and treat NULL pszSrc like + empty strings (L""). This flag is useful for emulating + functions like lstrcpy + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer. This will + overwrite any truncated string returned when the failure is + STATUS_BUFFER_OVERFLOW + + STRSAFE_NO_TRUNCATION / + STRSAFE_ZERO_LENGTH_ON_FAILURE + if the function fails, the destination Length will be set + to zero. This will overwrite any truncated string + returned when the failure is STATUS_BUFFER_OVERFLOW. + + +Notes: + Behavior is undefined if source and destination strings overlap. + + DestinationString and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag + is specified. If STRSAFE_IGNORE_NULLS is passed, both DestinationString and pszSrc + may be NULL. An error may still be returned even though NULLS are ignored + due to insufficient space. + +Return Value: + + STATUS_SUCCESS - if there was source data and it was all copied + + failure - the operation did not succeed + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the copy + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result. + This is useful for situations where truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlUnicodeStringCbCopyStringNEx( + __out PUNICODE_STRING DestinationString, + __in NTSTRSAFE_PCWSTR pszSrc, + __in size_t cbToCopy, + __out_opt PUNICODE_STRING RemainingString, + __in DWORD dwFlags) +{ + NTSTATUS status; + wchar_t* pszDest; + size_t cchDest; + + status = RtlUnicodeStringValidateDestWorker(DestinationString, + &pszDest, + &cchDest, + NULL, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + dwFlags); + + if (NT_SUCCESS(status)) + { + wchar_t* pszDestEnd = pszDest; + size_t cchRemaining = cchDest; + size_t cchNewDestLength = 0; + size_t cchToCopy = cbToCopy / sizeof(wchar_t); + + status = RtlStringExValidateSrcW(&pszSrc, &cchToCopy, NTSTRSAFE_UNICODE_STRING_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_UNICODE_STRING_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + } + else if (cchDest == 0) + { + // only fail if there was actually src data to copy + if ((cchToCopy != 0) && (*pszSrc != L'\0')) + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + status = RtlWideCharArrayCopyStringWorker(pszDest, + cchDest, + &cchNewDestLength, + pszSrc, + cchToCopy); + + pszDestEnd = pszDest + cchNewDestLength; + cchRemaining = cchDest - cchNewDestLength; + + if (NT_SUCCESS(status) && + (dwFlags & STRSAFE_FILL_BEHIND) && + (cchRemaining != 0)) + { + // handle the STRSAFE_FILL_BEHIND flag + RtlUnicodeStringExHandleFill(pszDestEnd, cchRemaining, dwFlags); + } + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_ZERO_LENGTH_ON_FAILURE)) && + (cchDest != 0)) + { + // handle the STRSAFE_NO_TRUNCATION, STRSAFE_FILL_ON_FAILURE, and STRSAFE_ZERO_LENGTH_ON_FAILURE flags + RtlUnicodeStringExHandleOtherFlags(pszDest, + cchDest, + 0, + &cchNewDestLength, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (DestinationString) + { + // safe to multiply cchNewDestLength * sizeof(wchar_t) since cchDest < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + DestinationString->Length = (USHORT)(cchNewDestLength * sizeof(wchar_t)); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (RemainingString) + { + RemainingString->Length = 0; + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + RemainingString->MaximumLength = (USHORT)(cchRemaining * sizeof(wchar_t)); + RemainingString->Buffer = pszDestEnd; + } + } + } + + return status; +} +#endif // !NTSTRSAFE_NO_CB_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CCH_FUNCTIONS +/*++ + +NTSTATUS +RtlUnicodeStringCchCopyNEx( + __out PUNICODE_STRING DestinationString OPTIONAL, + __in PCUNICODE_STRING SourceString OPTIONAL, + __in size_t cchToCopy, + __out_opt PUNICODE_STRING RemainingString OPTIONAL, + __in DWORD dwFlags + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strncpy' with + some additional parameters and for PUNICODE_STRINGs. In addition to the + functionality provided by RtlUnicodeStringCchCopyN, this + routine also returns a PUNICODE_STRING which points to the end of the + destination string. The flags parameter allows additional controls. + +Arguments: + + DestinationString - pointer to the counted unicode destination string + + SourceString - pointer to the counted unicode source string + + cchToCopy - maximum number of characters to copy from source string + + RemainingString - if RemainingString is non-null, the function will format + the pointer with the remaining buffer and number of + bytes left in the destination string + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + + STRSAFE_IGNORE_NULLS + do not fault if DestinationString is null and treat NULL SourceString like + empty strings (L""). This flag is useful for emulating + functions like lstrcpy + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer. This will + overwrite any truncated string returned when the failure is + STATUS_BUFFER_OVERFLOW + + STRSAFE_NO_TRUNCATION / + STRSAFE_ZERO_LENGTH_ON_FAILURE + if the function fails, the destination Length will be set + to zero. This will overwrite any truncated string + returned when the failure is STATUS_BUFFER_OVERFLOW. +Notes: + Behavior is undefined if source and destination strings overlap. + + DestinationString and SourceString should not be NULL unless the STRSAFE_IGNORE_NULLS flag + is specified. If STRSAFE_IGNORE_NULLS is passed, both DestinationString and SourceString + may be NULL. An error may still be returned even though NULLS are ignored + due to insufficient space. + +Return Value: + + STATUS_SUCCESS - if there was source data and it was all copied + + failure - the operation did not succeed + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the copy + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result. + This is useful for situations where truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlUnicodeStringCchCopyNEx( + __out PUNICODE_STRING DestinationString, + __in PCUNICODE_STRING SourceString, + __in size_t cchToCopy, + __out_opt PUNICODE_STRING RemainingString, + __in DWORD dwFlags) +{ + NTSTATUS status; + wchar_t* pszDest; + size_t cchDest; + + status = RtlUnicodeStringValidateDestWorker(DestinationString, + &pszDest, + &cchDest, + NULL, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + dwFlags); + + if (NT_SUCCESS(status)) + { + wchar_t* pszSrc; + size_t cchSrcLength; + wchar_t* pszDestEnd = pszDest; + size_t cchRemaining = cchDest; + size_t cchNewDestLength = 0; + + status = RtlUnicodeStringValidateSrcWorker(SourceString, + &pszSrc, + &cchSrcLength, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + dwFlags); + + if (NT_SUCCESS(status)) + { + if (cchToCopy > NTSTRSAFE_UNICODE_STRING_MAX_CCH) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + if (cchSrcLength < cchToCopy) + { + cchToCopy = cchSrcLength; + } + + if (dwFlags & (~STRSAFE_UNICODE_STRING_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + } + else if (cchDest == 0) + { + // only fail if there was actually src data to copy + if (cchToCopy != 0) + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + status = RtlWideCharArrayCopyWorker(pszDest, + cchDest, + &cchNewDestLength, + pszSrc, + cchToCopy); + + pszDestEnd = pszDest + cchNewDestLength; + cchRemaining = cchDest - cchNewDestLength; + + if (NT_SUCCESS(status) && + (dwFlags & STRSAFE_FILL_BEHIND) && + (cchRemaining != 0)) + { + // handle the STRSAFE_FILL_BEHIND flag + RtlUnicodeStringExHandleFill(pszDestEnd, cchRemaining, dwFlags); + } + } + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_ZERO_LENGTH_ON_FAILURE)) && + (cchDest != 0)) + { + // handle the STRSAFE_NO_TRUNCATION, STRSAFE_FILL_ON_FAILURE, and STRSAFE_ZERO_LENGTH_ON_FAILURE flags + RtlUnicodeStringExHandleOtherFlags(pszDest, + cchDest, + 0, + &cchNewDestLength, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (DestinationString) + { + // safe to multiply cchNewDestLength * sizeof(wchar_t) since cchDest < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + DestinationString->Length = (USHORT)(cchNewDestLength * sizeof(wchar_t)); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (RemainingString) + { + RemainingString->Length = 0; + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + RemainingString->MaximumLength = (USHORT)(cchRemaining * sizeof(wchar_t)); + RemainingString->Buffer = pszDestEnd; + } + } + } + + return status; +} +#endif // !NTSTRSAFE_NO_CCH_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CB_FUNCTIONS +/*++ + +NTSTATUS +RtlUnicodeStringCbCopyNEx( + __out PUNICODE_STRING DestinationString OPTIONAL, + __in PCUNICODE_STRING SourceString OPTIONAL, + __in size_t cbToCopy, + __out_opt PUNICODE_STRING RemainingString OPTIONAL, + __in DWORD dwFlags + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strncpy' with + some additional parameters and for PUNICODE_STRINGs. In addition to the + functionality provided by RtlUnicodeStringCbCopyN, this + routine also returns a PUNICODE_STRING which points to the end of the + destination string. The flags parameter allows additional controls. + +Arguments: + + DestinationString - pointer to the counted unicode destination string + + SourceString - pointer to the counted unicode source string + + cbToCopy - maximum number of bytes to copy from source string + + RemainingString - if RemainingString is non-null, the function will format + the pointer with the remaining buffer and number of + bytes left in the destination string + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + + STRSAFE_IGNORE_NULLS + do not fault if DestinationString is null and treat NULL SourceString like + empty strings (L""). This flag is useful for emulating + functions like lstrcpy + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer. This will + overwrite any truncated string returned when the failure is + STATUS_BUFFER_OVERFLOW + + STRSAFE_NO_TRUNCATION / + STRSAFE_ZERO_LENGTH_ON_FAILURE + if the function fails, the destination Length will be set + to zero. This will overwrite any truncated string + returned when the failure is STATUS_BUFFER_OVERFLOW. + +Notes: + Behavior is undefined if source and destination strings overlap. + + DestinationString and SourceString should not be NULL unless the STRSAFE_IGNORE_NULLS flag + is specified. If STRSAFE_IGNORE_NULLS is passed, both DestinationString and SourceString + may be NULL. An error may still be returned even though NULLS are ignored + due to insufficient space. + +Return Value: + + STATUS_SUCCESS - if there was source data and it was all copied + + failure - the operation did not succeed + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the copy + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result. + This is useful for situations where truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlUnicodeStringCbCopyNEx( + __out PUNICODE_STRING DestinationString, + __in PCUNICODE_STRING SourceString, + __in size_t cbToCopy, + __out_opt PUNICODE_STRING RemainingString, + __in DWORD dwFlags) +{ + NTSTATUS status; + wchar_t* pszDest; + size_t cchDest; + + status = RtlUnicodeStringValidateDestWorker(DestinationString, + &pszDest, + &cchDest, + NULL, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + dwFlags); + + if (NT_SUCCESS(status)) + { + wchar_t* pszSrc; + size_t cchSrcLength; + wchar_t* pszDestEnd = pszDest; + size_t cchRemaining = cchDest; + size_t cchNewDestLength = 0; + + status = RtlUnicodeStringValidateSrcWorker(SourceString, + &pszSrc, + &cchSrcLength, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + dwFlags); + + if (NT_SUCCESS(status)) + { + size_t cchToCopy = cbToCopy / sizeof(wchar_t); + + if (cchToCopy > NTSTRSAFE_UNICODE_STRING_MAX_CCH) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + if (cchSrcLength < cchToCopy) + { + cchToCopy = cchSrcLength; + } + + if (dwFlags & (~STRSAFE_UNICODE_STRING_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + } + else if (cchDest == 0) + { + // only fail if there was actually src data to copy + if (cchToCopy != 0) + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + status = RtlWideCharArrayCopyWorker(pszDest, + cchDest, + &cchNewDestLength, + pszSrc, + cchToCopy); + + pszDestEnd = pszDest + cchNewDestLength; + cchRemaining = cchDest - cchNewDestLength; + + if (NT_SUCCESS(status) && + (dwFlags & STRSAFE_FILL_BEHIND) && + (cchRemaining != 0)) + { + // handle the STRSAFE_FILL_BEHIND flag + RtlUnicodeStringExHandleFill(pszDestEnd, cchRemaining, dwFlags); + } + } + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_ZERO_LENGTH_ON_FAILURE)) && + (cchDest != 0)) + { + // handle the STRSAFE_NO_TRUNCATION, STRSAFE_FILL_ON_FAILURE, and STRSAFE_ZERO_LENGTH_ON_FAILURE flags + RtlUnicodeStringExHandleOtherFlags(pszDest, + cchDest, + 0, + &cchNewDestLength, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (DestinationString) + { + // safe to multiply cchNewDestLength * sizeof(wchar_t) since cchDest < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + DestinationString->Length = (USHORT)(cchNewDestLength * sizeof(wchar_t)); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (RemainingString) + { + RemainingString->Length = 0; + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + RemainingString->MaximumLength = (USHORT)(cchRemaining * sizeof(wchar_t)); + RemainingString->Buffer = pszDestEnd; + } + } + } + + return status; +} +#endif // !NTSTRSAFE_NO_CB_FUNCTIONS + + +/*++ + +NTSTATUS +RtlUnicodeStringCatString( + __inout PUNICODE_STRING DestinationString, + __in LPCTSTR pszSrc + ); + + Routine Description: + + This routine is a safer version of the C built-in function 'strcat' for + UNICODE_STRINGs. + + This function returns an NTSTATUS value, and not a pointer. It returns + STATUS_SUCCESS if the string was concatenated without truncation, otherwise + it will return a failure code. In failure cases as much of pszSrc will be + appended to DestinationString as possible. + +Arguments: + + DestinationString - pointer to the counted unicode destination string + + pszSrc - source string which must be null terminated + +Notes: + Behavior is undefined if source and destination strings overlap. + + DestinationString and pszSrc should not be NULL. See RtlUnicodeStringCatStringEx + if you require the handling of NULL values. + +Return Value: + + STATUS_SUCCESS - if there was source data and it was all concatenated + + failure - the operation did not succeed + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result. + This is useful for situations where truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function. + +--*/ + +NTSTRSAFEDDI +RtlUnicodeStringCatString( + __inout PUNICODE_STRING DestinationString, + __in NTSTRSAFE_PCWSTR pszSrc) +{ + NTSTATUS status; + wchar_t* pszDest; + size_t cchDest; + size_t cchDestLength; + + status = RtlUnicodeStringValidateDestWorker(DestinationString, + &pszDest, + &cchDest, + &cchDestLength, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + 0); + + if (NT_SUCCESS(status)) + { + size_t cchCopied = 0; + + status = RtlWideCharArrayCopyStringWorker(pszDest + cchDestLength, + cchDest - cchDestLength, + &cchCopied, + pszSrc, + NTSTRSAFE_UNICODE_STRING_MAX_CCH); + + // safe to multiply (cchDestLength + cchCopied) * sizeof(wchar_t) since (cchDestLength + cchCopied) < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + DestinationString->Length = (USHORT)((cchDestLength + cchCopied) * sizeof(wchar_t)); + } + + return status; +} + + +/*++ + +NTSTATUS +RtlUnicodeStringCat( + __inout PUNICODE_STRING DestinationString, + __in PCUNICODE_STRING SourceString + ); + + Routine Description: + + This routine is a safer version of the C built-in function 'strcat' for + UNICODE_STRINGs. + + This function returns an NTSTATUS value, and not a pointer. It returns + STATUS_SUCCESS if the string was concatenated without truncation, otherwise + it will return a failure code. In failure cases as much of SourceString will be + appended to DestinationString as possible. + +Arguments: + + DestinationString - pointer to the counted unicode destination string + + SourceString - pointer to the counted unicode source string + +Notes: + Behavior is undefined if source and destination strings overlap. + + DestinationString and pszSrc should not be NULL. See RtlUnicodeStringCatEx + if you require the handling of NULL values. + +Return Value: + + STATUS_SUCCESS - if there was source data and it was all concatenated + + failure - the operation did not succeed + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result. + This is useful for situations where truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function. + +--*/ + +NTSTRSAFEDDI +RtlUnicodeStringCat( + __inout PUNICODE_STRING DestinationString, + __in PCUNICODE_STRING SourceString) +{ + NTSTATUS status; + wchar_t* pszDest; + size_t cchDest; + size_t cchDestLength; + + status = RtlUnicodeStringValidateDestWorker(DestinationString, + &pszDest, + &cchDest, + &cchDestLength, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + 0); + + if (NT_SUCCESS(status)) + { + wchar_t* pszSrc; + size_t cchSrcLength; + + status = RtlUnicodeStringValidateSrcWorker(SourceString, + &pszSrc, + &cchSrcLength, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + 0); + + if (NT_SUCCESS(status)) + { + size_t cchCopied = 0; + + status = RtlWideCharArrayCopyWorker(pszDest + cchDestLength, + cchDest - cchDestLength, + &cchCopied, + pszSrc, + cchSrcLength); + + // safe to multiply (cchDestLength + cchCopied) * sizeof(wchar_t) since (cchDestLength + cchCopied) < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + DestinationString->Length = (USHORT)((cchDestLength + cchCopied) * sizeof(wchar_t)); + } + } + + return status; +} + + +/*++ + +NTSTATUS +RtlUnicodeStringCatStringEx( + __inout PUNICODE_STRING DestinationString OPTTONAL, + __in LPCTSTR pszSrc OPTIONAL, + __out_opt PUNICODE_STRING RemainingString OPTIONAL, + __in DWORD dwFlags + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strcat' for + PUNICODE_STRINGs with some additional parameters. In addition to the + functionality provided by RtlUnicodeStringCatString, this routine + also returns a PUNICODE_STRING which points to the end of the destination + string. The flags parameter allows additional controls. + +Arguments: + + DestinationString - pointer to the counted unicode destination string + + pszSrc - source string which must be null terminated + + RemainingString - if RemainingString is non-null, the function will format + the pointer with the remaining buffer and number of + bytes left in the destination string + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + + STRSAFE_IGNORE_NULLS + do not fault if DestinationString is null and treat NULL pszSrc like + empty strings (L""). This flag is useful for emulating + functions like lstrcpy + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer. This will + overwrite any truncated string returned when the failure is + STATUS_BUFFER_OVERFLOW + + STRSAFE_ZERO_LENGTH_ON_FAILURE + if the function fails, the destination Length will be set + to zero. This will overwrite any truncated string + returned when the failure is STATUS_BUFFER_OVERFLOW. + + STRSAFE_NO_TRUNCATION + if the function returns STATUS_BUFFER_OVERFLOW, pszDest + will not contain a truncated string, it will remain unchanged. + +Notes: + Behavior is undefined if source and destination strings overlap or if + DestinationString and RemainingString are the same pointer. + + DestinationString and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag + is specified. If STRSAFE_IGNORE_NULLS is passed, both DestinationString and pszSrc + may be NULL. An error may still be returned even though NULLS are ignored + due to insufficient space. + +Return Value: + + STATUS_SUCCESS - if there was source data and it was all concatenated + + failure - the operation did not succeed + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result. + This is useful for situations where truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlUnicodeStringCatStringEx( + __inout PUNICODE_STRING DestinationString, + __in NTSTRSAFE_PCWSTR pszSrc, + __out_opt PUNICODE_STRING RemainingString, + __in DWORD dwFlags) +{ + NTSTATUS status; + wchar_t* pszDest; + size_t cchDest; + size_t cchDestLength; + + status = RtlUnicodeStringValidateDestWorker(DestinationString, + &pszDest, + &cchDest, + &cchDestLength, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + dwFlags); + + if (NT_SUCCESS(status)) + { + wchar_t* pszDestEnd = pszDest + cchDestLength; + size_t cchRemaining = cchDest - cchDestLength; + size_t cchNewDestLength = cchDestLength; + + status = RtlStringExValidateSrcW(&pszSrc, NULL, NTSTRSAFE_UNICODE_STRING_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_UNICODE_STRING_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + } + else if (cchRemaining == 0) + { + // only fail if there was actually src data to append + if (*pszSrc != L'\0') + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + size_t cchCopied = 0; + + status = RtlWideCharArrayCopyStringWorker(pszDestEnd, + cchRemaining, + &cchCopied, + pszSrc, + NTSTRSAFE_UNICODE_STRING_MAX_CCH); + + pszDestEnd = pszDestEnd + cchCopied; + cchRemaining = cchRemaining - cchCopied; + + cchNewDestLength = cchDestLength + cchCopied; + + if (NT_SUCCESS(status) && + (dwFlags & STRSAFE_FILL_BEHIND) && + (cchRemaining != 0)) + { + // handle the STRSAFE_FILL_BEHIND flag + RtlUnicodeStringExHandleFill(pszDestEnd, cchRemaining, dwFlags); + } + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_ZERO_LENGTH_ON_FAILURE)) && + (cchDest != 0)) + { + // handle the STRSAFE_NO_TRUNCATION, STRSAFE_FILL_ON_FAILURE, and STRSAFE_ZERO_LENGTH_ON_FAILURE flags + RtlUnicodeStringExHandleOtherFlags(pszDest, + cchDest, + cchDestLength, + &cchNewDestLength, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (DestinationString) + { + // safe to multiply cchNewDestLength * sizeof(wchar_t) since cchDest < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + DestinationString->Length = (USHORT)(cchNewDestLength * sizeof(wchar_t)); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (RemainingString) + { + RemainingString->Length = 0; + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + RemainingString->MaximumLength = (USHORT)(cchRemaining * sizeof(wchar_t)); + RemainingString->Buffer = pszDestEnd; + } + } + } + + return status; +} + + +/*++ + +NTSTATUS +RtlUnicodeStringCatEx( + __inout PUNICODE_STRING DestinationString OPTIONAL, + __in PCUNICODE_STRING SourceString OPTIONAL, + __out_opt PUNICODE_STRING RemainingString OPTIONAL, + __in DWORD dwFlags + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strcat' for + PUNICODE_STRINGs with some additional parameters. In addition to the + functionality provided by RtlUnicodeStringCat, this routine + also returns a PUNICODE_STRING which points to the end of the destination + string. The flags parameter allows additional controls. + +Arguments: + + DestinationString - pointer to the counted unicode destination string + + SourceString - pointer to the counted unicode source string + + RemainingString - if RemainingString is non-null, the function will format + the pointer with the remaining buffer and number of + bytes left in the destination string + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + + STRSAFE_IGNORE_NULLS + do not fault if DestinationString is null and treat NULL pszSrc like + empty strings (L""). This flag is useful for emulating + functions like lstrcpy + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer. This will + overwrite any truncated string returned when the failure is + STATUS_BUFFER_OVERFLOW + + STRSAFE_ZERO_LENGTH_ON_FAILURE + if the function fails, the destination Length will be set + to zero. This will overwrite any truncated string + returned when the failure is STATUS_BUFFER_OVERFLOW. + + STRSAFE_NO_TRUNCATION + if the function returns STATUS_BUFFER_OVERFLOW, pszDest + will not contain a truncated string, it will remain unchanged. + +Notes: + Behavior is undefined if source and destination strings overlap or if + DestinationString and RemainingString are the same pointer. + + DestinationString and SourceString should not be NULL unless the STRSAFE_IGNORE_NULLS flag + is specified. If STRSAFE_IGNORE_NULLS is passed, both DestinationString and SourceString + may be NULL. An error may still be returned even though NULLS are ignored + due to insufficient space. + +Return Value: + + STATUS_SUCCESS - if there was source data and it was all concatenated + + failure - the operation did not succeed + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result. + This is useful for situations where truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlUnicodeStringCatEx( + __inout PUNICODE_STRING DestinationString, + __in PCUNICODE_STRING SourceString, + __out_opt PUNICODE_STRING RemainingString, + __in DWORD dwFlags) +{ + NTSTATUS status; + wchar_t* pszDest; + size_t cchDest; + size_t cchDestLength; + + status = RtlUnicodeStringValidateDestWorker(DestinationString, + &pszDest, + &cchDest, + &cchDestLength, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + dwFlags); + + if (NT_SUCCESS(status)) + { + wchar_t* pszSrc; + size_t cchSrcLength; + wchar_t* pszDestEnd = pszDest + cchDestLength; + size_t cchRemaining = cchDest - cchDestLength; + size_t cchNewDestLength = cchDestLength; + + status = RtlUnicodeStringValidateSrcWorker(SourceString, + &pszSrc, + &cchSrcLength, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + dwFlags); + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_UNICODE_STRING_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + } + else if (cchRemaining == 0) + { + // only fail if there was actually src data to append + if (cchSrcLength != 0) + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + size_t cchCopied = 0; + + status = RtlWideCharArrayCopyWorker(pszDestEnd, + cchRemaining, + &cchCopied, + pszSrc, + cchSrcLength); + + pszDestEnd = pszDestEnd + cchCopied; + cchRemaining = cchRemaining - cchCopied; + + cchNewDestLength = cchDestLength + cchCopied; + + if (NT_SUCCESS(status) && + (dwFlags & STRSAFE_FILL_BEHIND) && + (cchRemaining != 0)) + { + // handle the STRSAFE_FILL_BEHIND flag + RtlUnicodeStringExHandleFill(pszDestEnd, cchRemaining, dwFlags); + } + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_ZERO_LENGTH_ON_FAILURE)) && + (cchDest != 0)) + { + // handle the STRSAFE_NO_TRUNCATION, STRSAFE_FILL_ON_FAILURE, and STRSAFE_ZERO_LENGTH_ON_FAILURE flags + RtlUnicodeStringExHandleOtherFlags(pszDest, + cchDest, + cchDestLength, + &cchNewDestLength, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (DestinationString) + { + // safe to multiply cchNewDestLength * sizeof(wchar_t) since cchDest < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + DestinationString->Length = (USHORT)(cchNewDestLength * sizeof(wchar_t)); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (RemainingString) + { + RemainingString->Length = 0; + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + RemainingString->MaximumLength = (USHORT)(cchRemaining * sizeof(wchar_t)); + RemainingString->Buffer = pszDestEnd; + } + } + } + + return status; +} + + +#ifndef NTSTRSAFE_NO_CCH_FUNCTIONS +/*++ + +NTSTATUS +RtlUnicodeStringCchCatStringN( + __inout PUNICODE_STRING DestinationString, + __in LPCTSTR pszSrc, + __in size_t cchToAppend + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strncat' for + PUNICODE_STRINGs. + + This function returns an NTSTATUS value, and not a pointer. It returns + STATUS_SUCCESS if all of pszSrc or the first cchToAppend characters were + appended to the destination string, otherwise it will return a failure + code. In failure cases as much of pszSrc will be appended to DestinationString as + possible. + +Arguments: + + DestinationString - pointer to the counted unicode destination string + + pszSrc - source string + + cchToAppend - maximum number of characters to append + +Notes: + Behavior is undefined if source and destination strings overlap. + + DestinationString and pszSrc should not be NULL. See RtlUnicodeStringCchCatStringNEx if + you require the handling of NULL values. + +Return Value: + + STATUS_SUCCESS - if all of pszSrc or the first cchToAppend characters were + concatenated to DestinationString + + failure - the operation did not succeed + + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result. This is + useful for situations where truncation is ok + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlUnicodeStringCchCatStringN( + __inout PUNICODE_STRING DestinationString, + __in NTSTRSAFE_PCWSTR pszSrc, + __in size_t cchToAppend) +{ + NTSTATUS status; + wchar_t* pszDest; + size_t cchDest; + size_t cchDestLength; + + status = RtlUnicodeStringValidateDestWorker(DestinationString, + &pszDest, + &cchDest, + &cchDestLength, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + 0); + + if (NT_SUCCESS(status)) + { + if (cchToAppend > NTSTRSAFE_UNICODE_STRING_MAX_CCH) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + size_t cchCopied = 0; + + status = RtlWideCharArrayCopyStringWorker(pszDest + cchDestLength, + cchDest - cchDestLength, + &cchCopied, + pszSrc, + cchToAppend); + + // safe to multiply (cchDestLength + cchCopied) * sizeof(wchar_t) since (cchDestLength + cchCopied) < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + DestinationString->Length = (USHORT)((cchDestLength + cchCopied) * sizeof(wchar_t)); + } + } + + return status; +} +#endif // !NTSTRSAFE_NO_CCH_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CB_FUNCTIONS +/*++ + +NTSTATUS +RtlUnicodeStringCbCatStringN( + __inout PUNICODE_STRING DestinationString, + __in LPCTSTR pszSrc, + __in size_t cbToAppend + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strncat' for + PUNICODE_STRINGs. + + This function returns an NTSTATUS value, and not a pointer. It returns + STATUS_SUCCESS if all of pszSrc or the first cbToAppend bytes were + appended to the destination string, otherwise it will return a failure + code. In failure cases as much of pszSrc will be appended to DestinationString as + possible. + +Arguments: + + DestinationString - pointer to the counted unicode destination string + + pszSrc - source string + + cbToAppend - maximum number of bytes to append + +Notes: + Behavior is undefined if source and destination strings overlap. + + DestinationString and pszSrc should not be NULL. See RtlUnicodeStringCbCatStringNEx if + you require the handling of NULL values. + +Return Value: + + STATUS_SUCCESS - if all of pszSrc or the first cbToAppend bytes were + concatenated to pszDest + + failure - the operation did not succeed + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result. This is + useful for situations where truncation is ok + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlUnicodeStringCbCatStringN( + __inout PUNICODE_STRING DestinationString, + __in NTSTRSAFE_PCWSTR pszSrc, + __in size_t cbToAppend) +{ + NTSTATUS status; + wchar_t* pszDest; + size_t cchDest; + size_t cchDestLength; + + status = RtlUnicodeStringValidateDestWorker(DestinationString, + &pszDest, + &cchDest, + &cchDestLength, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + 0); + + if (NT_SUCCESS(status)) + { + size_t cchToAppend = cbToAppend / sizeof(wchar_t); + + if (cchToAppend > NTSTRSAFE_UNICODE_STRING_MAX_CCH) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + size_t cchCopied = 0; + + status = RtlWideCharArrayCopyStringWorker(pszDest + cchDestLength, + cchDest - cchDestLength, + &cchCopied, + pszSrc, + cchToAppend); + + // safe to multiply (cchDestLength + cchCopied) * sizeof(wchar_t) since (cchDestLength + cchCopied) < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + DestinationString->Length = (USHORT)((cchDestLength + cchCopied) * sizeof(wchar_t)); + } + } + + return status; +} +#endif // !NTSTRSAFE_NO_CB_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CCH_FUNCTIONS +/*++ + +NTSTATUS +RtlUnicodeStringCchCatN( + __inout PUNICODE_STRING DestinationString, + __in PCUNICODE_STRING SourceString, + __in size_t cchToAppend + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strncat' for + PUNICODE_STRINGs. + + This function returns an NTSTATUS value, and not a pointer. It returns + STATUS_SUCCESS if all of SourceString or the first cchToAppend characters were + appended to the destination string, otherwise it will return a failure + code. In failure cases as much of SourceString will be appended to DestinationString as + possible. + +Arguments: + + DestinationString - pointer to the counted unicode destination string + + SourceString - pointer to the counted unicode source string + + cchToAppend - maximum number of characters to append + +Notes: + Behavior is undefined if source and destination strings overlap. + + DestinationString and SourceString should not be NULL. See RtlUnicodeStringCchCatNEx if + you require the handling of NULL values. + +Return Value: + + STATUS_SUCCESS - if all of SourceString or the first cchToAppend characters were + concatenated to DestinationString + + failure - the operation did not succeed + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result. This is + useful for situations where truncation is ok + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlUnicodeStringCchCatN( + __inout PUNICODE_STRING DestinationString, + __in PCUNICODE_STRING SourceString, + __in size_t cchToAppend) +{ + NTSTATUS status; + wchar_t* pszDest; + size_t cchDest; + size_t cchDestLength; + + status = RtlUnicodeStringValidateDestWorker(DestinationString, + &pszDest, + &cchDest, + &cchDestLength, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + 0); + + if (NT_SUCCESS(status)) + { + wchar_t* pszSrc; + size_t cchSrcLength; + + status = RtlUnicodeStringValidateSrcWorker(SourceString, + &pszSrc, + &cchSrcLength, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + 0); + + if (NT_SUCCESS(status)) + { + if (cchToAppend > NTSTRSAFE_UNICODE_STRING_MAX_CCH) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + size_t cchCopied = 0; + + if (cchSrcLength < cchToAppend) + { + cchToAppend = cchSrcLength; + } + + status = RtlWideCharArrayCopyWorker(pszDest + cchDestLength, + cchDest - cchDestLength, + &cchCopied, + pszSrc, + cchToAppend); + + // safe to multiply (cchDestLength + cchCopied) * sizeof(wchar_t) since (cchDestLength + cchCopied) < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + DestinationString->Length = (USHORT)((cchDestLength + cchCopied) * sizeof(wchar_t)); + } + } + } + + return status; +} +#endif // !NTSTRSAFE_NO_CCH_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CB_FUNCTIONS +/*++ + +NTSTATUS +RtlUnicodeStringCbCatN( + __inout PUNICODE_STRING DestinationString, + __in PCUNICODE_STRING SourceString, + __in size_t cbToAppend + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strncat' for + PUNICODE_STRINGs. + + This function returns an NTSTATUS value, and not a pointer. It returns + STATUS_SUCCESS if all of SourceString or the first cbToAppend bytes were + appended to the destination string, otherwise it will return a failure + code. In failure cases as much of SourceString will be appended to DestinationString as + possible. + +Arguments: + + DestinationString - pointer to the counted unicode destination string + + SourceString - pointer to the counted unicode source string + + cbToAppend - maximum number of bytes to append + +Notes: + Behavior is undefined if source and destination strings overlap. + + DestinationString and SourceString should not be NULL. See RtlUnicodeStringCbCatNEx if + you require the handling of NULL values. + +Return Value: + + STATUS_SUCCESS - if all of SourceString or the first cbToAppend bytes were + concatenated to pszDest + + failure - the operation did not succeed + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result. This is + useful for situations where truncation is ok + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlUnicodeStringCbCatN( + __inout PUNICODE_STRING DestinationString, + __in PCUNICODE_STRING SourceString, + __in size_t cbToAppend) +{ + NTSTATUS status; + wchar_t* pszDest; + size_t cchDest; + size_t cchDestLength; + + status = RtlUnicodeStringValidateDestWorker(DestinationString, + &pszDest, + &cchDest, + &cchDestLength, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + 0); + + if (NT_SUCCESS(status)) + { + wchar_t* pszSrc; + size_t cchSrcLength; + + status = RtlUnicodeStringValidateSrcWorker(SourceString, + &pszSrc, + &cchSrcLength, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + 0); + + if (NT_SUCCESS(status)) + { + size_t cchToAppend = cbToAppend / sizeof(wchar_t); + + if (cchToAppend > NTSTRSAFE_UNICODE_STRING_MAX_CCH) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + size_t cchCopied = 0; + + if (cchSrcLength < cchToAppend) + { + cchToAppend = cchSrcLength; + } + + status = RtlWideCharArrayCopyWorker(pszDest + cchDestLength, + cchDest - cchDestLength, + &cchCopied, + pszSrc, + cchToAppend); + + // safe to multiply (cchDestLength + cchCopied) * sizeof(wchar_t) since (cchDestLength + cchCopied) < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + DestinationString->Length = (USHORT)((cchDestLength + cchCopied) * sizeof(wchar_t)); + } + } + } + + return status; +} +#endif // !NTSTRSAFE_NO_CB_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CCH_FUNCTIONS +/*++ + +NTSTATUS +RtlUnicodeStringCchCatStringNEx( + __inout PUNICODE_STRING DestinationString OPTIONAL, + __in LPCTSTR pszSrc OPTIONAL, + __in size_t cchToAppend, + __out_opt PUNICODE_STRING RemainingString OPTIONAL, + __in DWORD dwFlags + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strncat', with + some additional parameters and for PUNICODE_STRINGs. In addition to the + functionality provided by RtlUnicodeStringCchCatStringN, this routine + also returns a PUNICODE_STRING which points to the end of the destination + string. The flags parameter allows additional controls. + +Arguments: + + DestinationString - pointer to the counted unicode destination string + + pszSrc - source string + + cchToAppend - maximum number of characters to append + + RemainingString - if RemainingString is non-null, the function will format + the pointer with the remaining buffer and number of + bytes left in the destination string + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + + STRSAFE_IGNORE_NULLS + do not fault if DestinationString is null and treat NULL pszSrc like + empty strings (L""). This flag is useful for emulating + functions like lstrcpy + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer. This will + overwrite any truncated string returned when the failure is + STATUS_BUFFER_OVERFLOW + + STRSAFE_ZERO_LENGTH_ON_FAILURE + if the function fails, the destination Length will be set + to zero. This will overwrite any truncated string + returned when the failure is STATUS_BUFFER_OVERFLOW. + + STRSAFE_NO_TRUNCATION + if the function returns STATUS_BUFFER_OVERFLOW, pszDest + will not contain a truncated string, it will remain unchanged. + +Notes: + Behavior is undefined if source and destination strings overlap. + + DestinationString and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag + is specified. If STRSAFE_IGNORE_NULLS is passed, both DestinationString and pszSrc + may be NULL. An error may still be returned even though NULLS are ignored + due to insufficient space. + +Return Value: + + STATUS_SUCCESS - if all of pszSrc or the first cchToAppend characters were + concatenated to DestinationString + + failure - the operation did not succeed + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result. + This is useful for situations where truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlUnicodeStringCchCatStringNEx( + __inout PUNICODE_STRING DestinationString, + __in NTSTRSAFE_PCWSTR pszSrc, + __in size_t cchToAppend, + __out_opt PUNICODE_STRING RemainingString, + __in DWORD dwFlags) +{ + NTSTATUS status; + wchar_t* pszDest; + size_t cchDest; + size_t cchDestLength; + + status = RtlUnicodeStringValidateDestWorker(DestinationString, + &pszDest, + &cchDest, + &cchDestLength, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + dwFlags); + + if (NT_SUCCESS(status)) + { + wchar_t* pszDestEnd = pszDest + cchDestLength; + size_t cchRemaining = cchDest - cchDestLength; + size_t cchNewDestLength = cchDestLength; + + status = RtlStringExValidateSrcW(&pszSrc, &cchToAppend, NTSTRSAFE_UNICODE_STRING_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_UNICODE_STRING_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + } + else if (cchRemaining == 0) + { + // only fail if there was actually src data to append + if ((cchToAppend != 0) && (*pszSrc != L'\0')) + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + size_t cchCopied = 0; + + status = RtlWideCharArrayCopyStringWorker(pszDestEnd, + cchRemaining, + &cchCopied, + pszSrc, + cchToAppend); + + pszDestEnd = pszDestEnd + cchCopied; + cchRemaining = cchRemaining - cchCopied; + + cchNewDestLength = cchDestLength + cchCopied; + + if (NT_SUCCESS(status) && + (dwFlags & STRSAFE_FILL_BEHIND) && + (cchRemaining != 0)) + { + // handle the STRSAFE_FILL_BEHIND flag + RtlUnicodeStringExHandleFill(pszDestEnd, cchRemaining, dwFlags); + } + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_ZERO_LENGTH_ON_FAILURE)) && + (cchDest != 0)) + { + // handle the STRSAFE_NO_TRUNCATION, STRSAFE_FILL_ON_FAILURE, and STRSAFE_ZERO_LENGTH_ON_FAILURE flags + RtlUnicodeStringExHandleOtherFlags(pszDest, + cchDest, + cchDestLength, + &cchNewDestLength, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (DestinationString) + { + // safe to multiply cchNewDestLength * sizeof(wchar_t) since cchDest < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + DestinationString->Length = (USHORT)(cchNewDestLength * sizeof(wchar_t)); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (RemainingString) + { + RemainingString->Length = 0; + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + RemainingString->MaximumLength = (USHORT)(cchRemaining * sizeof(wchar_t)); + RemainingString->Buffer = pszDestEnd; + } + } + } + + return status; +} +#endif // !NTSTRSAFE_NO_CCH_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CB_FUNCTIONS +/*++ + +NTSTATUS +RtlUnicodeStringCbCatStringNEx( + __inout PUNICODE_STRING DestinationString OPTIONAL, + __in LPCTSTR pszSrc OPTIONAL, + __in size_t cbToAppend, + __out_opt PUNICODE_STRING RemainingString OPTIONAL, + __in DWORD dwFlags + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strncat', with + some additional parameters and for PUNICODE_STRINGs. In addition to the + functionality provided by RtlUnicodeStringCbCatStringN, this routine + also returns a PUNICODE_STRING which points to the end of the destination + string. The flags parameter allows additional controls. + +Arguments: + + DestinationString - pointer to the counted unicode destination string + + pszSrc - source string + + cbToAppend - maximum number of bytes to append + + RemainingString - if RemainingString is non-null, the function will format + the pointer with the remaining buffer and number of + bytes left in the destination string + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + + STRSAFE_IGNORE_NULLS + do not fault if DestinationString is null and treat NULL pszSrc like + empty strings (L""). This flag is useful for emulating + functions like lstrcpy + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer. This will + overwrite any truncated string returned when the failure is + STATUS_BUFFER_OVERFLOW + + STRSAFE_ZERO_LENGTH_ON_FAILURE + if the function fails, the destination Length will be set + to zero. This will overwrite any truncated string + returned when the failure is STATUS_BUFFER_OVERFLOW. + + STRSAFE_NO_TRUNCATION + if the function returns STATUS_BUFFER_OVERFLOW, pszDest + will not contain a truncated string, it will remain unchanged. + +Notes: + Behavior is undefined if source and destination strings overlap. + + DestinationString and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag + is specified. If STRSAFE_IGNORE_NULLS is passed, both DestinationString and pszSrc + may be NULL. An error may still be returned even though NULLS are ignored + due to insufficient space. + +Return Value: + + STATUS_SUCCESS - if all of pszSrc or the first cbToAppend bytes were + concatenated to pszDest + + failure - the operation did not succeed + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result. + This is useful for situations where truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlUnicodeStringCbCatStringNEx( + __inout PUNICODE_STRING DestinationString, + __in NTSTRSAFE_PCWSTR pszSrc, + __in size_t cbToAppend, + __out_opt PUNICODE_STRING RemainingString, + __in DWORD dwFlags) +{ + NTSTATUS status; + wchar_t* pszDest; + size_t cchDest; + size_t cchDestLength; + + status = RtlUnicodeStringValidateDestWorker(DestinationString, + &pszDest, + &cchDest, + &cchDestLength, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + dwFlags); + + if (NT_SUCCESS(status)) + { + wchar_t* pszDestEnd = pszDest + cchDestLength; + size_t cchRemaining = cchDest - cchDestLength; + size_t cchNewDestLength = cchDestLength; + size_t cchToAppend = cbToAppend / sizeof(wchar_t); + + status = RtlStringExValidateSrcW(&pszSrc, &cchToAppend, NTSTRSAFE_UNICODE_STRING_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_UNICODE_STRING_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + } + else if (cchRemaining == 0) + { + // only fail if there was actually src data to append + if ((cchToAppend != 0) && (*pszSrc != L'\0')) + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + size_t cchCopied = 0; + + status = RtlWideCharArrayCopyStringWorker(pszDestEnd, + cchRemaining, + &cchCopied, + pszSrc, + cchToAppend); + + pszDestEnd = pszDestEnd + cchCopied; + cchRemaining = cchRemaining - cchCopied; + + cchNewDestLength = cchDestLength + cchCopied; + + if (NT_SUCCESS(status) && + (dwFlags & STRSAFE_FILL_BEHIND) && + (cchRemaining != 0)) + { + // handle the STRSAFE_FILL_BEHIND flag + RtlUnicodeStringExHandleFill(pszDestEnd, cchRemaining, dwFlags); + } + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_ZERO_LENGTH_ON_FAILURE)) && + (cchDest != 0)) + { + // handle the STRSAFE_NO_TRUNCATION, STRSAFE_FILL_ON_FAILURE, and STRSAFE_ZERO_LENGTH_ON_FAILURE flags + RtlUnicodeStringExHandleOtherFlags(pszDest, + cchDest, + cchDestLength, + &cchNewDestLength, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (DestinationString) + { + // safe to multiply cchNewDestLength * sizeof(wchar_t) since cchDest < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + DestinationString->Length = (USHORT)(cchNewDestLength * sizeof(wchar_t)); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (RemainingString) + { + RemainingString->Length = 0; + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + RemainingString->MaximumLength = (USHORT)(cchRemaining * sizeof(wchar_t)); + RemainingString->Buffer = pszDestEnd; + } + } + } + + return status; +} +#endif // !NTSTRSAFE_NO_CB_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CCH_FUNCTIONS +/*++ + +NTSTATUS +RtlUnicodeStringCchCatNEx( + __inout PUNICODE_STRING DestinationString OPTIONAL, + __in PCUNICODE_STRING SourceString OPTIONAL, + __in size_t cchToAppend, + __out_opt PUNICODE_STRING RemainingString OPTIONAL, + __in DWORD dwFlags + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strncat', with + some additional parameters and for PUNICODE_STRINGs. In addition to the + functionality provided by RtlUnicodeStringCchCatN, this routine + also returns a PUNICODE_STRING which points to the end of the destination + string. The flags parameter allows additional controls. + +Arguments: + + DestinationString - pointer to the counted unicode destination string + + SourceString - pointer to the counted unicode source string + + cchToAppend - maximum number of characters to append + + RemainingString - if RemainingString is non-null, the function will format + the pointer with the remaining buffer and number of + bytes left in the destination string + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + + STRSAFE_IGNORE_NULLS + do not fault if DestinationString is null and treat NULL SourceString like + empty strings (L""). This flag is useful for emulating + functions like lstrcpy + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer. This will + overwrite any truncated string returned when the failure is + STATUS_BUFFER_OVERFLOW + + STRSAFE_ZERO_LENGTH_ON_FAILURE + if the function fails, the destination Length will be set + to zero. This will overwrite any truncated string + returned when the failure is STATUS_BUFFER_OVERFLOW. + + STRSAFE_NO_TRUNCATION + if the function returns STATUS_BUFFER_OVERFLOW, pszDest + will not contain a truncated string, it will remain unchanged. + +Notes: + Behavior is undefined if source and destination strings overlap. + + DestinationString and SourceString should not be NULL unless the STRSAFE_IGNORE_NULLS flag + is specified. If STRSAFE_IGNORE_NULLS is passed, both DestinationString and SourceString + may be NULL. An error may still be returned even though NULLS are ignored + due to insufficient space. + +Return Value: + + STATUS_SUCCESS - if all of SourceString or the first cchToAppend characters were + concatenated to DestinationString + + failure - the operation did not succeed + + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result. + This is useful for situations where truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlUnicodeStringCchCatNEx( + __inout PUNICODE_STRING DestinationString, + __in PCUNICODE_STRING SourceString, + __in size_t cchToAppend, + __out_opt PUNICODE_STRING RemainingString, + __in DWORD dwFlags) +{ + NTSTATUS status; + wchar_t* pszDest; + size_t cchDest; + size_t cchDestLength; + + status = RtlUnicodeStringValidateDestWorker(DestinationString, + &pszDest, + &cchDest, + &cchDestLength, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + dwFlags); + + if (NT_SUCCESS(status)) + { + wchar_t* pszSrc; + size_t cchSrcLength; + wchar_t* pszDestEnd = pszDest + cchDestLength; + size_t cchRemaining = cchDest - cchDestLength; + size_t cchNewDestLength = cchDestLength; + + status = RtlUnicodeStringValidateSrcWorker(SourceString, + &pszSrc, + &cchSrcLength, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + dwFlags); + + if (NT_SUCCESS(status)) + { + if (cchToAppend > NTSTRSAFE_UNICODE_STRING_MAX_CCH) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + if (cchSrcLength < cchToAppend) + { + cchToAppend = cchSrcLength; + } + + if (dwFlags & (~STRSAFE_UNICODE_STRING_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + } + else if (cchRemaining == 0) + { + // only fail if there was actually src data to append + if (cchToAppend != 0) + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + size_t cchCopied = 0; + + status = RtlWideCharArrayCopyStringWorker(pszDestEnd, + cchRemaining, + &cchCopied, + pszSrc, + cchToAppend); + + pszDestEnd = pszDestEnd + cchCopied; + cchRemaining = cchRemaining - cchCopied; + + cchNewDestLength = cchDestLength + cchCopied; + + if (NT_SUCCESS(status) && + (dwFlags & STRSAFE_FILL_BEHIND) && + (cchRemaining != 0)) + { + // handle the STRSAFE_FILL_BEHIND flag + RtlUnicodeStringExHandleFill(pszDestEnd, cchRemaining, dwFlags); + } + } + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_ZERO_LENGTH_ON_FAILURE)) && + (cchDest != 0)) + { + // handle the STRSAFE_NO_TRUNCATION, STRSAFE_FILL_ON_FAILURE, and STRSAFE_ZERO_LENGTH_ON_FAILURE flags + RtlUnicodeStringExHandleOtherFlags(pszDest, + cchDest, + cchDestLength, + &cchNewDestLength, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (DestinationString) + { + // safe to multiply cchNewDestLength * sizeof(wchar_t) since cchDest < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + DestinationString->Length = (USHORT)(cchNewDestLength * sizeof(wchar_t)); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (RemainingString) + { + RemainingString->Length = 0; + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + RemainingString->MaximumLength = (USHORT)(cchRemaining * sizeof(wchar_t)); + RemainingString->Buffer = pszDestEnd; + } + } + } + + return status; +} +#endif // !NTSTRSAFE_NO_CCH_FUNCTIONS + + +#ifndef NTSTRSAFE_NO_CB_FUNCTIONS +/*++ + +NTSTATUS +RtlUnicodeStringCbCatNEx( + __inout PUNICODE_STRING DestinationString OPTIONAL, + __in PCUNICODE_STRING SourceString OPTIONAL, + __in size_t cbToAppend, + __out_opt PUNICODE_STRING RemainingString OPTIONAL, + __in DWORD dwFlags + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'strncat', with + some additional parameters and for PUNICODE_STRINGs. In addition to the + functionality provided by RtlUnicodeStringCbCatN, this routine + also returns a PUNICODE_STRING which points to the end of the destination + string. The flags parameter allows additional controls. + +Arguments: + + DestinationString - pointer to the counted unicode destination string + + SourceString - pointer to the counted unicode source string + + cbToAppend - maximum number of bytes to append + + RemainingString - if RemainingString is non-null, the function will format + the pointer with the remaining buffer and number of + bytes left in the destination string + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + + STRSAFE_IGNORE_NULLS + do not fault if DestinationString is null and treat NULL SourceString like + empty strings (L""). This flag is useful for emulating + functions like lstrcpy + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer. This will + overwrite any truncated string returned when the failure is + STATUS_BUFFER_OVERFLOW + + STRSAFE_ZERO_LENGTH_ON_FAILURE + if the function fails, the destination Length will be set + to zero. This will overwrite any truncated string + returned when the failure is STATUS_BUFFER_OVERFLOW. + + STRSAFE_NO_TRUNCATION + if the function returns STATUS_BUFFER_OVERFLOW, pszDest + will not contain a truncated string, it will remain unchanged. + +Notes: + Behavior is undefined if source and destination strings overlap. + + DestinationString and SourceString should not be NULL unless the STRSAFE_IGNORE_NULLS flag + is specified. If STRSAFE_IGNORE_NULLS is passed, both DestinationString and SourceString + may be NULL. An error may still be returned even though NULLS are ignored + due to insufficient space. + +Return Value: + + STATUS_SUCCESS - if all of SourceString or the first cbToAppend bytes were + concatenated to DestinationString + + failure - the operation did not succeed + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result. + This is useful for situations where truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlUnicodeStringCbCatNEx( + __inout PUNICODE_STRING DestinationString, + __in PCUNICODE_STRING SourceString, + __in size_t cbToAppend, + __out_opt PUNICODE_STRING RemainingString, + __in DWORD dwFlags) +{ + NTSTATUS status; + wchar_t* pszDest; + size_t cchDest; + size_t cchDestLength; + + status = RtlUnicodeStringValidateDestWorker(DestinationString, + &pszDest, + &cchDest, + &cchDestLength, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + dwFlags); + + if (NT_SUCCESS(status)) + { + wchar_t* pszSrc; + size_t cchSrcLength; + wchar_t* pszDestEnd = pszDest + cchDestLength; + size_t cchRemaining = cchDest - cchDestLength; + size_t cchNewDestLength = cchDestLength; + + status = RtlUnicodeStringValidateSrcWorker(SourceString, + &pszSrc, + &cchSrcLength, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + dwFlags); + + if (NT_SUCCESS(status)) + { + size_t cchToAppend = cbToAppend / sizeof(wchar_t); + + if (cchToAppend > NTSTRSAFE_UNICODE_STRING_MAX_CCH) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + if (cchSrcLength < cchToAppend) + { + cchToAppend = cchSrcLength; + } + + if (dwFlags & (~STRSAFE_UNICODE_STRING_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + } + else if (cchRemaining == 0) + { + // only fail if there was actually src data to append + if (cchToAppend != 0) + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + size_t cchCopied = 0; + + status = RtlWideCharArrayCopyWorker(pszDestEnd, + cchRemaining, + &cchCopied, + pszSrc, + cchToAppend); + + pszDestEnd = pszDestEnd + cchCopied; + cchRemaining = cchRemaining - cchCopied; + + cchNewDestLength = cchDestLength + cchCopied; + + if (NT_SUCCESS(status) && + (dwFlags & STRSAFE_FILL_BEHIND) && + (cchRemaining != 0)) + { + // handle the STRSAFE_FILL_BEHIND flag + RtlUnicodeStringExHandleFill(pszDestEnd, cchRemaining, dwFlags); + } + } + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_ZERO_LENGTH_ON_FAILURE)) && + (cchDest != 0)) + { + // handle the STRSAFE_NO_TRUNCATION, STRSAFE_FILL_ON_FAILURE, and STRSAFE_ZERO_LENGTH_ON_FAILURE flags + RtlUnicodeStringExHandleOtherFlags(pszDest, + cchDest, + cchDestLength, + &cchNewDestLength, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (DestinationString) + { + // safe to multiply cchNewDestLength * sizeof(wchar_t) since cchDest < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + DestinationString->Length = (USHORT)(cchNewDestLength * sizeof(wchar_t)); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (RemainingString) + { + RemainingString->Length = 0; + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + RemainingString->MaximumLength = (USHORT)(cchRemaining * sizeof(wchar_t)); + RemainingString->Buffer = pszDestEnd; + } + } + } + + return status; +} +#endif // !NTSTRSAFE_NO_CB_FUNCTIONS + + +/*++ + +NTSTATUS +RtlUnicodeStringVPrintf( + __out PUNICODE_STRING DestinationString, + __in __format_string PCWSTR pszFormat, + __in va_list argList + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'vsprintf' for + PUNICODE_STRINGs. + + This function returns an NTSTATUS value, and not a pointer. It returns + STATUS_SUCCESS if the string was printed without truncation, otherwise it + will return a failure code. In failure cases it will return a truncated + version of the ideal result. + +Arguments: + + DestinationString - pointer to the counted unicode destination string + + pszFormat - format string which must be null terminated + + argList - va_list from the variable arguments according to the + stdarg.h convention + +Notes: + Behavior is undefined if destination, format strings or any arguments + strings overlap. + + DestinationString and pszFormat should not be NULL. See RtlUnicodeStringVPrintfEx if you + require the handling of NULL values. + +Return Value: + + STATUS_SUCCESS - if there was sufficient space in the dest buffer for + the resultant string + + failure - the operation did not succeed + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the print + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result. This is + useful for situations where truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlUnicodeStringVPrintf( + __out PUNICODE_STRING DestinationString, + __in __format_string NTSTRSAFE_PCWSTR pszFormat, + __in va_list argList) +{ + NTSTATUS status; + wchar_t* pszDest; + size_t cchDest; + + status = RtlUnicodeStringValidateDestWorker(DestinationString, + &pszDest, + &cchDest, + NULL, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + 0); + + if (NT_SUCCESS(status)) + { + size_t cchNewDestLength = 0; + + status = RtlWideCharArrayVPrintfWorker(pszDest, + cchDest, + &cchNewDestLength, + pszFormat, + argList); + + // safe to multiply cchNewDestLength * sizeof(wchar_t) since cchDest < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + DestinationString->Length = (USHORT)(cchNewDestLength * sizeof(wchar_t)); + } + + return status; +} + + +/*++ + +NTSTATUS +RtlUnicodeStringVPrintfEx( + __out PUNICODE_STRING DestinationString OPTIONAL, + __out_opt PUNICODE_STRING RemainingString OPTIONAL, + __in DWORD dwFlags, + __in __format_string PCWSTR pszFormat OPTIONAL, + __in va_list argList + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'vsprintf' with + some additional parameters for PUNICODE_STRING. In addition to the + functionality provided by RtlUnicodeStringVPrintf, this routine also + returns a PUNICODE_STRING which points to the end of the destination + string. The flags parameter allows additional controls. + +Arguments: + + DestinationString - pointer to the counted unicode destination string + + RemainingString - if RemainingString is non-null, the function will format + the pointer with the remaining buffer and number of + bytes left in the destination string + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + + STRSAFE_IGNORE_NULLS + do not fault if DestinationString is null and treat NULL pszFormat like + empty strings (L""). + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer. This will + overwrite any truncated string returned when the failure is + STATUS_BUFFER_OVERFLOW + + STRSAFE_NO_TRUNCATION / + STRSAFE_ZERO_LENGTH_ON_FAILURE + if the function fails, the destination Length will be set + to zero. This will overwrite any truncated string + returned when the failure is STATUS_BUFFER_OVERFLOW. + + pszFormat - format string which must be null terminated + + argList - va_list from the variable arguments according to the + stdarg.h convention + +Notes: + Behavior is undefined if destination, format strings or any arguments + strings overlap. + + DestinationString and pszFormat should not be NULL unless the STRSAFE_IGNORE_NULLS + flag is specified. If STRSAFE_IGNORE_NULLS is passed, both DestinationString and + pszFormat may be NULL. An error may still be returned even though NULLS + are ignored due to insufficient space. + +Return Value: + + STATUS_SUCCESS - if there was sufficient space in the dest buffer for + the resultant string + + failure - the operation did not succeed + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the print + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result. This is + useful for situations where truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlUnicodeStringVPrintfEx( + __out PUNICODE_STRING DestinationString, + __out_opt PUNICODE_STRING RemainingString, + __in DWORD dwFlags, + __in __format_string NTSTRSAFE_PCWSTR pszFormat, + __in va_list argList) +{ + NTSTATUS status; + wchar_t* pszDest; + size_t cchDest; + + status = RtlUnicodeStringValidateDestWorker(DestinationString, + &pszDest, + &cchDest, + NULL, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + dwFlags); + + if (NT_SUCCESS(status)) + { + wchar_t* pszDestEnd = pszDest; + size_t cchRemaining = cchDest; + size_t cchNewDestLength = 0; + + status = RtlStringExValidateSrcW(&pszFormat, NULL, NTSTRSAFE_UNICODE_STRING_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_UNICODE_STRING_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + } + else if (cchDest == 0) + { + // only fail if there was actually a non-empty format string + if (*pszFormat != L'\0') + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + status = RtlWideCharArrayVPrintfWorker(pszDest, + cchDest, + &cchNewDestLength, + pszFormat, + argList); + + pszDestEnd = pszDest + cchNewDestLength; + cchRemaining = cchDest - cchNewDestLength; + + if (NT_SUCCESS(status) && + (dwFlags & STRSAFE_FILL_BEHIND) && + (cchRemaining != 0)) + { + // handle the STRSAFE_FILL_BEHIND flag + RtlUnicodeStringExHandleFill(pszDestEnd, cchRemaining, dwFlags); + } + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_ZERO_LENGTH_ON_FAILURE)) && + (cchDest != 0)) + { + // handle the STRSAFE_NO_TRUNCATION, STRSAFE_FILL_ON_FAILURE, and STRSAFE_ZERO_LENGTH_ON_FAILURE flags + RtlUnicodeStringExHandleOtherFlags(pszDest, + cchDest, + 0, + &cchNewDestLength, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (DestinationString) + { + // safe to multiply cchNewDestLength * sizeof(wchar_t) since cchDest < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + DestinationString->Length = (USHORT)(cchNewDestLength * sizeof(wchar_t)); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (RemainingString) + { + RemainingString->Length = 0; + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + RemainingString->MaximumLength = (USHORT)(cchRemaining * sizeof(wchar_t)); + RemainingString->Buffer = pszDestEnd; + } + } + } + + return status; +} + + +#ifndef _M_CEE_PURE + +/*++ + +NTSTATUS +RtlUnicodeStringPrintf( + __out PUNICODE_STRING DestinationString, + __in __format_string PCWSTR pszFormat, + ... + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'sprintf' for + PUNICODE_STRINGs. + + This function returns an NTSTATUS value, and not a pointer. It returns + STATUS_SUCCESS if the string was printed without truncation, otherwise it + will return a failure code. In failure cases it will return a truncated + version of the ideal result. + +Arguments: + + DestinationString - pointer to the counted unicode destination string + + pszFormat - format string which must be null terminated + + ... - additional parameters to be formatted according to + the format string + +Notes: + Behavior is undefined if destination, format strings or any arguments + strings overlap. + + DestinationString and pszFormat should not be NULL. See RtlUnicodeStringPrintfEx if you + require the handling of NULL values. + +Return Value: + + STATUS_SUCCESS - if there was sufficient space in the dest buffer for + the resultant string + + failure - the operation did not succeed + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the print + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result. This is + useful for situations where truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlUnicodeStringPrintf( + __out PUNICODE_STRING DestinationString, + __in __format_string NTSTRSAFE_PCWSTR pszFormat, + ...) +{ + NTSTATUS status; + wchar_t* pszDest; + size_t cchDest; + + status = RtlUnicodeStringValidateDestWorker(DestinationString, + &pszDest, + &cchDest, + NULL, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + 0); + + if (NT_SUCCESS(status)) + { + va_list argList; + size_t cchNewDestLength = 0; + + va_start(argList, pszFormat); + + status = RtlWideCharArrayVPrintfWorker(pszDest, + cchDest, + &cchNewDestLength, + pszFormat, + argList); + + va_end(argList); + + // safe to multiply cchNewDestLength * sizeof(wchar_t) since cchDest < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + DestinationString->Length = (USHORT)(cchNewDestLength * sizeof(wchar_t)); + } + + return status; +} + + +/*++ + +NTSTATUS +RtlUnicodeStringPrintfEx( + __out PUNICODE_STRING DestinationString OPTIONAL, + __out_opt PUNICODE_STRING RemainingString OPTIONAL, + __in DWORD dwFlags, + __in __format_string PCWSTR pszFormat OPTIONAL, + ... + ); + +Routine Description: + + This routine is a safer version of the C built-in function 'sprintf' with + some additional parameters for PUNICODE_STRINGs. In addition to the + functionality provided by RtlUnicodeStringPrintf, this routine also + returns a PUNICODE_STRING which points to the end of the destination + string. The flags parameter allows additional controls. + +Arguments: + + DestinationString - pointer to the counted unicode destination string + + RemainingString - if RemainingString is non-null, the function will format + the pointer with the remaining buffer and number of + bytes left in the destination string + + dwFlags - controls some details of the string copy: + + STRSAFE_FILL_BEHIND + if the function succeeds, the low byte of dwFlags will be + used to fill the uninitialize part of destination buffer + + STRSAFE_IGNORE_NULLS + do not fault if DestinationString is null and treat NULL pszFormat like + empty strings (L""). + + STRSAFE_FILL_ON_FAILURE + if the function fails, the low byte of dwFlags will be + used to fill all of the destination buffer. This will + overwrite any truncated string returned when the failure is + STATUS_BUFFER_OVERFLOW + + STRSAFE_NO_TRUNCATION / + STRSAFE_ZERO_LENGTH_ON_FAILURE + if the function fails, the destination Length will be set + to zero. This will overwrite any truncated string + returned when the failure is STATUS_BUFFER_OVERFLOW. + + pszFormat - format string which must be null terminated + + ... - additional parameters to be formatted according to + the format string + +Notes: + Behavior is undefined if destination, format strings or any arguments + strings overlap. + + DestinationString and pszFormat should not be NULL unless the STRSAFE_IGNORE_NULLS + flag is specified. If STRSAFE_IGNORE_NULLS is passed, both DestinationString and + pszFormat may be NULL. An error may still be returned even though NULLS + are ignored due to insufficient space. + +Return Value: + + STATUS_SUCCESS - if there was sufficient space in the dest buffer for + the resultant string + + failure - the operation did not succeed + + + STATUS_BUFFER_OVERFLOW + Note: This status has the severity class Warning - IRPs completed with this + status do have their data copied back to user mode + - this return value is an indication that the print + operation failed due to insufficient space. When this + error occurs, the destination buffer is modified to + contain a truncated version of the ideal result. This is + useful for situations where truncation is ok. + + It is strongly recommended to use the NT_SUCCESS() macro to test the + return value of this function + +--*/ + +NTSTRSAFEDDI +RtlUnicodeStringPrintfEx( + __out PUNICODE_STRING DestinationString, + __out_opt PUNICODE_STRING RemainingString, + __in DWORD dwFlags, + __in __format_string NTSTRSAFE_PCWSTR pszFormat, + ...) +{ + NTSTATUS status; + wchar_t* pszDest; + size_t cchDest; + + status = RtlUnicodeStringValidateDestWorker(DestinationString, + &pszDest, + &cchDest, + NULL, + NTSTRSAFE_UNICODE_STRING_MAX_CCH, + dwFlags); + + if (NT_SUCCESS(status)) + { + wchar_t* pszDestEnd = pszDest; + size_t cchRemaining = cchDest; + size_t cchNewDestLength = 0; + + status = RtlStringExValidateSrcW(&pszFormat, NULL, NTSTRSAFE_UNICODE_STRING_MAX_CCH, dwFlags); + + if (NT_SUCCESS(status)) + { + if (dwFlags & (~STRSAFE_UNICODE_STRING_VALID_FLAGS)) + { + status = STATUS_INVALID_PARAMETER; + } + else if (cchDest == 0) + { + // only fail if there was actually a non-empty format string + if (*pszFormat != L'\0') + { + if (pszDest == NULL) + { + status = STATUS_INVALID_PARAMETER; + } + else + { + status = STATUS_BUFFER_OVERFLOW; + } + } + } + else + { + va_list argList; + + va_start(argList, pszFormat); + + status = RtlWideCharArrayVPrintfWorker(pszDest, + cchDest, + &cchNewDestLength, + pszFormat, + argList); + + va_end(argList); + + pszDestEnd = pszDest + cchNewDestLength; + cchRemaining = cchDest - cchNewDestLength; + + if (NT_SUCCESS(status) && + (dwFlags & STRSAFE_FILL_BEHIND) && + (cchRemaining != 0)) + { + // handle the STRSAFE_FILL_BEHIND flag + RtlUnicodeStringExHandleFill(pszDestEnd, cchRemaining, dwFlags); + } + } + } + + if (!NT_SUCCESS(status) && + (dwFlags & (STRSAFE_NO_TRUNCATION | STRSAFE_FILL_ON_FAILURE | STRSAFE_ZERO_LENGTH_ON_FAILURE)) && + (cchDest != 0)) + { + // handle the STRSAFE_NO_TRUNCATION, STRSAFE_FILL_ON_FAILURE, and STRSAFE_ZERO_LENGTH_ON_FAILURE flags + RtlUnicodeStringExHandleOtherFlags(pszDest, + cchDest, + 0, + &cchNewDestLength, + &pszDestEnd, + &cchRemaining, + dwFlags); + } + + if (DestinationString) + { + // safe to multiply cchNewDestLength * sizeof(wchar_t) since cchDest < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + DestinationString->Length = (USHORT)(cchNewDestLength * sizeof(wchar_t)); + } + + if (NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) + { + if (RemainingString) + { + RemainingString->Length = 0; + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + RemainingString->MaximumLength = (USHORT)(cchRemaining * sizeof(wchar_t)); + RemainingString->Buffer = pszDestEnd; + } + } + } + + return status; +} + +#endif // !_M_CEE_PURE + +#endif // !NTSTRSAFE_NO_UNICODE_STRING_FUNCTIONS + +#endif // !NTSTRSAFE_LIB_IMPL + + +// Below here are the worker functions that actually do the work + +#if defined(NTSTRSAFE_LIB_IMPL) || !defined(NTSTRSAFE_LIB) + +NTSTRSAFEWORKERDDI +RtlStringLengthWorkerA( + __in STRSAFE_PCNZCH psz, + __in __in_range(<=, NTSTRSAFE_MAX_CCH) size_t cchMax, + __out_opt __deref_out_range(<, cchMax) size_t* pcchLength) +{ + NTSTATUS status = STATUS_SUCCESS; + size_t cchOriginalMax = cchMax; + + while (cchMax && (*psz != '\0')) + { + psz++; + cchMax--; + } + + if (cchMax == 0) + { + // the string is longer than cchMax + status = STATUS_INVALID_PARAMETER; + } + + if (pcchLength) + { + if (NT_SUCCESS(status)) + { + *pcchLength = cchOriginalMax - cchMax; + } + else + { + *pcchLength = 0; + } + } + + return status; +} + +NTSTRSAFEWORKERDDI +RtlStringLengthWorkerW( + __in STRSAFE_PCNZWCH psz, + __in __in_range(<=, NTSTRSAFE_MAX_CCH) size_t cchMax, + __out_opt __deref_out_range(<, cchMax) size_t* pcchLength) +{ + NTSTATUS status = STATUS_SUCCESS; + size_t cchOriginalMax = cchMax; + + while (cchMax && (*psz != L'\0')) + { + psz++; + cchMax--; + } + + if (cchMax == 0) + { + // the string is longer than cchMax + status = STATUS_INVALID_PARAMETER; + } + + if (pcchLength) + { + if (NT_SUCCESS(status)) + { + *pcchLength = cchOriginalMax - cchMax; + } + else + { + *pcchLength = 0; + } + } + + return status; +} + +#ifdef ALIGNMENT_MACHINE +NTSTRSAFEWORKERDDI +RtlUnalignedStringLengthWorkerW( + __in STRSAFE_PCUNZWCH psz, + __in __in_range(<=, NTSTRSAFE_MAX_CCH) size_t cchMax, + __out_opt __deref_out_range(<, cchMax) size_t* pcchLength) +{ + NTSTATUS status = STATUS_SUCCESS; + size_t cchOriginalMax = cchMax; + + while (cchMax && (*psz != L'\0')) + { + psz++; + cchMax--; + } + + if (cchMax == 0) + { + // the string is longer than cchMax + status = STATUS_INVALID_PARAMETER; + } + + if (pcchLength) + { + if (NT_SUCCESS(status)) + { + *pcchLength = cchOriginalMax - cchMax; + } + else + { + *pcchLength = 0; + } + } + + return status; +} +#endif // ALIGNMENT_MACHINE + +// Intentionally allow null deref when STRSAFE_IGNORE_NULLS is not present. +#pragma warning(push) +#pragma warning(disable : __WARNING_DEREF_NULL_PTR) +#pragma warning(disable : __WARNING_INVALID_PARAM_VALUE_1) +#pragma warning(disable : __WARNING_RETURNING_BAD_RESULT) + +NTSTRSAFEWORKERDDI +RtlStringExValidateSrcA( + __deref_in_opt_out NTSTRSAFE_PCSTR* ppszSrc, + __inout_opt __deref_out_range(<, cchMax) size_t* pcchToRead, + __in const size_t cchMax, + __in DWORD dwFlags) +{ + NTSTATUS status = STATUS_SUCCESS; + + if (pcchToRead && (*pcchToRead >= cchMax)) + { + status = STATUS_INVALID_PARAMETER; + } + else if ((dwFlags & STRSAFE_IGNORE_NULLS) && (*ppszSrc == NULL)) + { + *ppszSrc = ""; + + if (pcchToRead) + { + *pcchToRead = 0; + } + } + + return status; +} + +NTSTRSAFEWORKERDDI +RtlStringExValidateSrcW( + __deref_in_opt_out NTSTRSAFE_PCWSTR* ppszSrc, + __inout_opt __deref_out_range(<, cchMax) size_t* pcchToRead, + __in const size_t cchMax, + __in DWORD dwFlags) +{ + NTSTATUS status = STATUS_SUCCESS; + + if (pcchToRead && (*pcchToRead >= cchMax)) + { + status = STATUS_INVALID_PARAMETER; + } + else if ((dwFlags & STRSAFE_IGNORE_NULLS) && (*ppszSrc == NULL)) + { + *ppszSrc = L""; + + if (pcchToRead) + { + *pcchToRead = 0; + } + } + + return status; +} + +#pragma warning(pop) // allow null deref + +#pragma warning(push) +#pragma warning(disable : 4100) // Unused parameter (pszDest) +NTSTRSAFEWORKERDDI +RtlStringValidateDestA( + __in_ecount_opt(cchDest) STRSAFE_PCNZCH pszDest, + __in size_t cchDest, + __in const size_t cchMax) +{ + NTSTATUS status = STATUS_SUCCESS; + + if ((cchDest == 0) || (cchDest > cchMax)) + { + status = STATUS_INVALID_PARAMETER; + } + + return status; +} +#pragma warning(pop) + +// Intentionally allow null deref when STRSAFE_IGNORE_NULLS is not present. +#pragma warning(push) +#pragma warning(disable : __WARNING_DEREF_NULL_PTR) +#pragma warning(disable : __WARNING_INVALID_PARAM_VALUE_1) +NTSTRSAFEWORKERDDI +RtlStringValidateDestAndLengthA( + __in_ecount_opt(cchDest) NTSTRSAFE_PCSTR pszDest, + __in size_t cchDest, + __out __deref_out_range(<, cchDest) size_t* pcchDestLength, + __in const size_t cchMax) +{ + NTSTATUS status; + + status = RtlStringValidateDestA(pszDest, cchDest, cchMax); + + if (NT_SUCCESS(status)) + { + status = RtlStringLengthWorkerA(pszDest, cchDest, pcchDestLength); + } + else + { + *pcchDestLength = 0; + } + + return status; +} +// End intentionally allow null deref. +#pragma warning(pop) + +#pragma warning(push) +#pragma warning(disable : 4100) // Unused parameter (pszDest) +NTSTRSAFEWORKERDDI +RtlStringValidateDestW( + __in_ecount_opt(cchDest) STRSAFE_PCNZWCH pszDest, + __in size_t cchDest, + __in const size_t cchMax) +{ + NTSTATUS status = STATUS_SUCCESS; + + if ((cchDest == 0) || (cchDest > cchMax)) + { + status = STATUS_INVALID_PARAMETER; + } + + return status; +} +#pragma warning(pop) + +// Intentionally allow null deref when STRSAFE_IGNORE_NULLS is not present. +#pragma warning(push) +#pragma warning(disable : __WARNING_DEREF_NULL_PTR) +#pragma warning(disable : __WARNING_INVALID_PARAM_VALUE_1) +NTSTRSAFEWORKERDDI +RtlStringValidateDestAndLengthW( + __in_ecount_opt(cchDest) NTSTRSAFE_PCWSTR pszDest, + __in size_t cchDest, + __out __deref_out_range(<, cchDest) size_t* pcchDestLength, + __in const size_t cchMax) +{ + NTSTATUS status; + + status = RtlStringValidateDestW(pszDest, cchDest, cchMax); + + if (NT_SUCCESS(status)) + { + status = RtlStringLengthWorkerW(pszDest, cchDest, pcchDestLength); + } + else + { + *pcchDestLength = 0; + } + + return status; +} +// End intentionally allow null deref. +#pragma warning(pop) + +NTSTRSAFEWORKERDDI +RtlStringExValidateDestA( + __in_ecount_opt(cchDest) STRSAFE_PCNZCH pszDest, + __in size_t cchDest, + __in const size_t cchMax, + __in DWORD dwFlags) +{ + NTSTATUS status = STATUS_SUCCESS; + + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + if (((pszDest == NULL) && (cchDest != 0)) || + (cchDest > cchMax)) + { + status = STATUS_INVALID_PARAMETER; + } + } + else + { + status = RtlStringValidateDestA(pszDest, cchDest, cchMax); + } + + return status; +} + +// Intentionally allow null deref when STRSAFE_IGNORE_NULLS is not present. +#pragma warning(push) +#pragma warning(disable : __WARNING_DEREF_NULL_PTR) +#pragma warning(disable : __WARNING_INVALID_PARAM_VALUE_1) +NTSTRSAFEWORKERDDI +RtlStringExValidateDestAndLengthA( + __in_ecount_opt(cchDest) NTSTRSAFE_PCSTR pszDest, + __in size_t cchDest, + __out __deref_out_range(<, cchDest) size_t* pcchDestLength, + __in const size_t cchMax, + __in DWORD dwFlags) +{ + NTSTATUS status; + + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + status = RtlStringExValidateDestA(pszDest, cchDest, cchMax, dwFlags); + + if (!NT_SUCCESS(status) || (cchDest == 0)) + { + *pcchDestLength = 0; + } + else + { + status = RtlStringLengthWorkerA(pszDest, cchDest, pcchDestLength); + } + } + else + { + status = RtlStringValidateDestAndLengthA(pszDest, + cchDest, + pcchDestLength, + cchMax); + } + + return status; +} +// End intentionally allow null deref. +#pragma warning(pop) + +NTSTRSAFEWORKERDDI +RtlStringExValidateDestW( + __in_ecount_opt(cchDest) STRSAFE_PCNZWCH pszDest, + __in size_t cchDest, + __in const size_t cchMax, + __in DWORD dwFlags) +{ + NTSTATUS status = STATUS_SUCCESS; + + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + if (((pszDest == NULL) && (cchDest != 0)) || + (cchDest > cchMax)) + { + status = STATUS_INVALID_PARAMETER; + } + } + else + { + status = RtlStringValidateDestW(pszDest, cchDest, cchMax); + } + + return status; +} + +// Intentionally allow null deref when STRSAFE_IGNORE_NULLS is not present. +#pragma warning(push) +#pragma warning(disable : __WARNING_DEREF_NULL_PTR) +#pragma warning(disable : __WARNING_INVALID_PARAM_VALUE_1) +NTSTRSAFEWORKERDDI +RtlStringExValidateDestAndLengthW( + __in_ecount_opt(cchDest) NTSTRSAFE_PCWSTR pszDest, + __in size_t cchDest, + __out __deref_out_range(<, cchDest) size_t* pcchDestLength, + __in const size_t cchMax, + __in DWORD dwFlags) +{ + NTSTATUS status; + + if (dwFlags & STRSAFE_IGNORE_NULLS) + { + status = RtlStringExValidateDestW(pszDest, cchDest, cchMax, dwFlags); + + if (!NT_SUCCESS(status) || (cchDest == 0)) + { + *pcchDestLength = 0; + } + else + { + status = RtlStringLengthWorkerW(pszDest, cchDest, pcchDestLength); + } + } + else + { + status = RtlStringValidateDestAndLengthW(pszDest, + cchDest, + pcchDestLength, + cchMax); + } + + return status; +} +// End intentionally allow null deref. +#pragma warning(pop) + +NTSTRSAFEWORKERDDI +RtlStringCopyWorkerA( + __out_ecount(cchDest) NTSTRSAFE_PSTR pszDest, + __in __in_range(1, NTSTRSAFE_MAX_CCH) size_t cchDest, + __out_opt __deref_out_range(<=, (cchToCopy < cchDest) ? cchToCopy : cchDest - 1) size_t* pcchNewDestLength, + __in_xcount(cchToCopy) STRSAFE_PCNZCH pszSrc, + __in __in_range(<, NTSTRSAFE_MAX_CCH) size_t cchToCopy) +{ + NTSTATUS status = STATUS_SUCCESS; + size_t cchNewDestLength = 0; + + // ASSERT(cchDest != 0); + + while (cchDest && cchToCopy && (*pszSrc != '\0')) + { + *pszDest++ = *pszSrc++; + cchDest--; + cchToCopy--; + + cchNewDestLength++; + } + + if (cchDest == 0) + { + // we are going to truncate pszDest + pszDest--; + cchNewDestLength--; + + status = STATUS_BUFFER_OVERFLOW; + } + + *pszDest = '\0'; + + if (pcchNewDestLength) + { + *pcchNewDestLength = cchNewDestLength; + } + + return status; +} + +NTSTRSAFEWORKERDDI +RtlStringCopyWorkerW( + __out_ecount(cchDest) NTSTRSAFE_PWSTR pszDest, + __in __in_range(1, NTSTRSAFE_MAX_CCH) size_t cchDest, + __out_opt __deref_out_range(<=, (cchToCopy < cchDest) ? cchToCopy : cchDest - 1) size_t* pcchNewDestLength, + __in_xcount(cchToCopy) STRSAFE_PCNZWCH pszSrc, + __in __in_range(<, NTSTRSAFE_MAX_CCH) size_t cchToCopy) +{ + NTSTATUS status = STATUS_SUCCESS; + size_t cchNewDestLength = 0; + + // ASSERT(cchDest != 0); + + while (cchDest && cchToCopy && (*pszSrc != L'\0')) + { + *pszDest++ = *pszSrc++; + cchDest--; + cchToCopy--; + + cchNewDestLength++; + } + + if (cchDest == 0) + { + // we are going to truncate pszDest + pszDest--; + cchNewDestLength--; + + status = STATUS_BUFFER_OVERFLOW; + } + + *pszDest = L'\0'; + + if (pcchNewDestLength) + { + *pcchNewDestLength = cchNewDestLength; + } + + return status; +} + +NTSTRSAFEWORKERDDI +RtlStringVPrintfWorkerA( + __out_ecount(cchDest) NTSTRSAFE_PSTR pszDest, + __in __in_range(1, NTSTRSAFE_MAX_CCH) size_t cchDest, + __out_opt __deref_out_range(<=, cchDest - 1) size_t* pcchNewDestLength, + __in __format_string NTSTRSAFE_PCSTR pszFormat, + __in va_list argList) +{ + NTSTATUS status = STATUS_SUCCESS; + int iRet; + size_t cchMax; + size_t cchNewDestLength = 0; + + // leave the last space for the null terminator + cchMax = cchDest - 1; + +#if (NTSTRSAFE_USE_SECURE_CRT == 1) && !defined(NTSTRSAFE_LIB_IMPL) + iRet = _vsnprintf_s(pszDest, cchDest, cchMax, pszFormat, argList); +#else + #pragma warning(push) + #pragma warning(disable: __WARNING_BANNED_API_USAGE)// "STRSAFE not included" + iRet = _vsnprintf(pszDest, cchMax, pszFormat, argList); + #pragma warning(pop) +#endif + // ASSERT((iRet < 0) || (((size_t)iRet) <= cchMax)); + + if ((iRet < 0) || (((size_t)iRet) > cchMax)) + { + // need to null terminate the string + pszDest += cchMax; + *pszDest = '\0'; + + cchNewDestLength = cchMax; + + // we have truncated pszDest + status = STATUS_BUFFER_OVERFLOW; + } + else if (((size_t)iRet) == cchMax) + { + // need to null terminate the string + pszDest += cchMax; + *pszDest = '\0'; + + cchNewDestLength = cchMax; + } + else + { + cchNewDestLength = (size_t)iRet; + } + + if (pcchNewDestLength) + { + *pcchNewDestLength = cchNewDestLength; + } + + return status; +} + +NTSTRSAFEWORKERDDI +RtlStringVPrintfWorkerW( + __out_ecount(cchDest) NTSTRSAFE_PWSTR pszDest, + __in __in_range(1, NTSTRSAFE_MAX_CCH) size_t cchDest, + __out_opt __deref_out_range(<=, cchDest - 1) size_t* pcchNewDestLength, + __in __format_string NTSTRSAFE_PCWSTR pszFormat, + __in va_list argList) +{ + NTSTATUS status = STATUS_SUCCESS; + int iRet; + size_t cchMax; + size_t cchNewDestLength = 0; + + // leave the last space for the null terminator + cchMax = cchDest - 1; + +#if (NTSTRSAFE_USE_SECURE_CRT == 1) && !defined(NTSTRSAFE_LIB_IMPL) + iRet = _vsnwprintf_s(pszDest, cchDest, cchMax, pszFormat, argList); +#else + #pragma warning(push) + #pragma warning(disable: __WARNING_BANNED_API_USAGE)// "STRSAFE not included" + iRet = _vsnwprintf(pszDest, cchMax, pszFormat, argList); + #pragma warning(pop) +#endif + // ASSERT((iRet < 0) || (((size_t)iRet) <= cchMax)); + + if ((iRet < 0) || (((size_t)iRet) > cchMax)) + { + // need to null terminate the string + pszDest += cchMax; + *pszDest = L'\0'; + + cchNewDestLength = cchMax; + + // we have truncated pszDest + status = STATUS_BUFFER_OVERFLOW; + } + else if (((size_t)iRet) == cchMax) + { + // need to null terminate the string + pszDest += cchMax; + *pszDest = L'\0'; + + cchNewDestLength = cchMax; + } + else + { + cchNewDestLength = (size_t)iRet; + } + + if (pcchNewDestLength) + { + *pcchNewDestLength = cchNewDestLength; + } + + return status; +} + + +NTSTRSAFEWORKERDDI +RtlStringExHandleFillBehindNullA( + __inout_bcount(cbRemaining) NTSTRSAFE_PSTR pszDestEnd, + __in size_t cbRemaining, + __in DWORD dwFlags) +{ + if (cbRemaining > sizeof(char)) + { + memset(pszDestEnd + 1, STRSAFE_GET_FILL_PATTERN(dwFlags), cbRemaining - sizeof(char)); + } + + return STATUS_SUCCESS; +} + +NTSTRSAFEWORKERDDI +RtlStringExHandleFillBehindNullW( + __inout_bcount(cbRemaining) NTSTRSAFE_PWSTR pszDestEnd, + __in size_t cbRemaining, + __in DWORD dwFlags) +{ + if (cbRemaining > sizeof(wchar_t)) + { + memset(pszDestEnd + 1, STRSAFE_GET_FILL_PATTERN(dwFlags), cbRemaining - sizeof(wchar_t)); + } + + return STATUS_SUCCESS; +} + +NTSTRSAFEWORKERDDI +RtlStringExHandleOtherFlagsA( + __inout_bcount(cbDest) NTSTRSAFE_PSTR pszDest, + __in __in_range(sizeof(char), NTSTRSAFE_MAX_CCH * sizeof(char)) size_t cbDest, + __in __in_range(<, cbDest / sizeof(char)) size_t cchOriginalDestLength, + __deref_inout_ecount(*pcchRemaining) NTSTRSAFE_PSTR* ppszDestEnd, + __out __deref_out_range(<=, cbDest / sizeof(char)) size_t* pcchRemaining, + __in DWORD dwFlags) +{ + size_t cchDest = cbDest / sizeof(char); + + if ((cchDest > 0) && (dwFlags & STRSAFE_NO_TRUNCATION)) + { + char* pszOriginalDestEnd; + + pszOriginalDestEnd = pszDest + cchOriginalDestLength; + + *ppszDestEnd = pszOriginalDestEnd; + *pcchRemaining = cchDest - cchOriginalDestLength; + + // null terminate the end of the original string + *pszOriginalDestEnd = '\0'; + } + + if (dwFlags & STRSAFE_FILL_ON_FAILURE) + { + memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest); + + if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0) + { + *ppszDestEnd = pszDest; + *pcchRemaining = cchDest; + } + else if (cchDest > 0) + { + char* pszDestEnd; + + pszDestEnd = pszDest + cchDest - 1; + + *ppszDestEnd = pszDestEnd; + *pcchRemaining = 1; + + // null terminate the end of the string + *pszDestEnd = L'\0'; + } + } + + if ((cchDest > 0) && (dwFlags & STRSAFE_NULL_ON_FAILURE)) + { + *ppszDestEnd = pszDest; + *pcchRemaining = cchDest; + + // null terminate the beginning of the string + *pszDest = '\0'; + } + + return STATUS_SUCCESS; +} + +NTSTRSAFEWORKERDDI +RtlStringExHandleOtherFlagsW( + __inout_bcount(cbDest) NTSTRSAFE_PWSTR pszDest, + __in __in_range(sizeof(wchar_t), NTSTRSAFE_MAX_CCH * sizeof(wchar_t)) size_t cbDest, + __in __in_range(<, cbDest / sizeof(wchar_t)) size_t cchOriginalDestLength, + __deref_inout_ecount(*pcchRemaining) NTSTRSAFE_PWSTR* ppszDestEnd, + __out __deref_out_range(<=, cbDest / sizeof(wchar_t)) size_t* pcchRemaining, + __in DWORD dwFlags) +{ + size_t cchDest = cbDest / sizeof(wchar_t); + + if ((cchDest > 0) && (dwFlags & STRSAFE_NO_TRUNCATION)) + { + wchar_t* pszOriginalDestEnd; + + pszOriginalDestEnd = pszDest + cchOriginalDestLength; + + *ppszDestEnd = pszOriginalDestEnd; + *pcchRemaining = cchDest - cchOriginalDestLength; + + // null terminate the end of the original string + *pszOriginalDestEnd = L'\0'; + } + + if (dwFlags & STRSAFE_FILL_ON_FAILURE) + { + memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest); + + if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0) + { + *ppszDestEnd = pszDest; + *pcchRemaining = cchDest; + } + else if (cchDest > 0) + { + wchar_t* pszDestEnd; + + pszDestEnd = pszDest + cchDest - 1; + + *ppszDestEnd = pszDestEnd; + *pcchRemaining = 1; + + // null terminate the end of the string + *pszDestEnd = L'\0'; + } + } + + if ((cchDest > 0) && (dwFlags & STRSAFE_NULL_ON_FAILURE)) + { + *ppszDestEnd = pszDest; + *pcchRemaining = cchDest; + + // null terminate the beginning of the string + *pszDest = L'\0'; + } + + return STATUS_SUCCESS; +} + +#ifndef NTSTRSAFE_NO_UNICODE_STRING_FUNCTIONS + +NTSTRSAFEWORKERDDI +RtlUnicodeStringInitWorker( + __out PUNICODE_STRING DestinationString, + __in_opt NTSTRSAFE_PCWSTR pszSrc, + __in const size_t cchMax, + __in DWORD dwFlags) +{ + NTSTATUS status = STATUS_SUCCESS; + + if (DestinationString || !(dwFlags & STRSAFE_IGNORE_NULLS)) + { + DestinationString->Length = 0; + DestinationString->MaximumLength = 0; + DestinationString->Buffer = NULL; + } + + if (pszSrc) + { + size_t cchSrcLength; + + status = RtlStringLengthWorkerW(pszSrc, cchMax, &cchSrcLength); + + if (NT_SUCCESS(status)) + { + if (DestinationString) + { + size_t cbLength; + + // safe to multiply cchSrcLength * sizeof(wchar_t) since cchSrcLength < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + cbLength = cchSrcLength * sizeof(wchar_t); + + DestinationString->Length = (USHORT)cbLength; + // safe to add cbLength + sizeof(wchar_t) since cchSrcLength < NTSTRSAFE_UNICODE_STRING_MAX_CCH + DestinationString->MaximumLength = (USHORT)(cbLength + sizeof(wchar_t)); + DestinationString->Buffer = (PWSTR)pszSrc; + } + else + { + status = STATUS_INVALID_PARAMETER; + } + } + } + + return status; +} + +// Intentionally allow null deref in error cases. +#pragma warning(push) +#pragma warning(disable : __WARNING_DEREF_NULL_PTR) +#pragma warning(disable : __WARNING_INVALID_PARAM_VALUE_1) +#pragma warning(disable : __WARNING_RETURNING_BAD_RESULT) + +NTSTRSAFEWORKERDDI +RtlUnicodeStringValidateWorker( + __in_opt PCUNICODE_STRING SourceString, + __in const size_t cchMax, + __in DWORD dwFlags) +{ + NTSTATUS status = STATUS_SUCCESS; + + if (SourceString || !(dwFlags & STRSAFE_IGNORE_NULLS)) + { + if (((SourceString->Length % sizeof(wchar_t)) != 0) || + ((SourceString->MaximumLength % sizeof(wchar_t)) != 0) || + (SourceString->Length > SourceString->MaximumLength) || + (SourceString->MaximumLength > (cchMax * sizeof(wchar_t)))) + { + status = STATUS_INVALID_PARAMETER; + } + else if ((SourceString->Buffer == NULL) && + ((SourceString->Length != 0) || (SourceString->MaximumLength != 0))) + { + status = STATUS_INVALID_PARAMETER; + } + } + + return status; +} + +NTSTRSAFEWORKERDDI +RtlUnicodeStringValidateSrcWorker( + __in PCUNICODE_STRING SourceString, + __deref_out_ecount(*pcchSrcLength) wchar_t** ppszSrc, + __out size_t* pcchSrcLength, + __in const size_t cchMax, + __in DWORD dwFlags) +{ + NTSTATUS status; + + *ppszSrc = NULL; + *pcchSrcLength = 0; + + status = RtlUnicodeStringValidateWorker(SourceString, cchMax, dwFlags); + + if (NT_SUCCESS(status)) + { + if (SourceString) + { + *ppszSrc = SourceString->Buffer; + *pcchSrcLength = SourceString->Length / sizeof(wchar_t); + } + + if ((*ppszSrc == NULL) && (dwFlags & STRSAFE_IGNORE_NULLS)) + { + *ppszSrc = L""; + } + } + + return status; +} +// End intentionally allow null deref. +#pragma warning(pop) + +NTSTRSAFEWORKERDDI +RtlUnicodeStringValidateDestWorker( + __in PCUNICODE_STRING DestinationString, + __deref_out_ecount(*pcchDest) wchar_t** ppszDest, + __out size_t* pcchDest, + __out_opt size_t* pcchDestLength, + __in const size_t cchMax, + __in DWORD dwFlags) +{ + NTSTATUS status; + + *ppszDest = NULL; + *pcchDest = 0; + + if (pcchDestLength) + { + *pcchDestLength = 0; + } + + status = RtlUnicodeStringValidateWorker(DestinationString, cchMax, dwFlags); + + if (NT_SUCCESS(status) && DestinationString) + { + *ppszDest = DestinationString->Buffer; + *pcchDest = DestinationString->MaximumLength / sizeof(wchar_t); + + if (pcchDestLength) + { + *pcchDestLength = DestinationString->Length / sizeof(wchar_t); + } + } + + return status; +} + +NTSTRSAFEWORKERDDI +RtlStringCopyWideCharArrayWorker( + __out_ecount(cchDest) NTSTRSAFE_PWSTR pszDest, + __in size_t cchDest, + __out_opt size_t* pcchNewDestLength, + __in_ecount(cchSrcLength) const wchar_t* pszSrc, + __in size_t cchSrcLength) +{ + NTSTATUS status = STATUS_SUCCESS; + size_t cchNewDestLength = 0; + + // ASSERT(cchDest != 0); + + while (cchDest && cchSrcLength) + { + *pszDest++ = *pszSrc++; + cchDest--; + cchSrcLength--; + + cchNewDestLength++; + } + + if (cchDest == 0) + { + // we are going to truncate pszDest + pszDest--; + cchNewDestLength--; + + status = STATUS_BUFFER_OVERFLOW; + } + + *pszDest = L'\0'; + + if (pcchNewDestLength) + { + *pcchNewDestLength = cchNewDestLength; + } + + return status; +} + +NTSTRSAFEWORKERDDI +RtlWideCharArrayCopyStringWorker( + __out_ecount(cchDest) wchar_t* pszDest, + __in size_t cchDest, + __out size_t* pcchNewDestLength, + __in NTSTRSAFE_PCWSTR pszSrc, + __in size_t cchToCopy) +{ + NTSTATUS status = STATUS_SUCCESS; + size_t cchNewDestLength = 0; + + while (cchDest && cchToCopy && (*pszSrc != L'\0')) + { + *pszDest++ = *pszSrc++; + cchDest--; + cchToCopy--; + + cchNewDestLength++; + } + + if ((cchDest == 0) && (cchToCopy != 0) && (*pszSrc != L'\0')) + { + // we are going to truncate pszDest + status = STATUS_BUFFER_OVERFLOW; + } + + *pcchNewDestLength = cchNewDestLength; + + return status; +} + +NTSTRSAFEWORKERDDI +RtlWideCharArrayCopyWorker( + __out_ecount(cchDest) wchar_t* pszDest, + __in size_t cchDest, + __out size_t* pcchNewDestLength, + __in_ecount(cchSrcLength) const wchar_t* pszSrc, + __in size_t cchSrcLength) +{ + NTSTATUS status = STATUS_SUCCESS; + size_t cchNewDestLength = 0; + + while (cchDest && cchSrcLength) + { + *pszDest++ = *pszSrc++; + cchDest--; + cchSrcLength--; + + cchNewDestLength++; + } + + if ((cchDest == 0) && (cchSrcLength != 0)) + { + // we are going to truncate pszDest + status = STATUS_BUFFER_OVERFLOW; + } + + *pcchNewDestLength = cchNewDestLength; + + return status; +} + +NTSTRSAFEWORKERDDI +RtlWideCharArrayVPrintfWorker( + __out_ecount(cchDest) wchar_t* pszDest, + __in size_t cchDest, + __out size_t* pcchNewDestLength, + __in __format_string NTSTRSAFE_PCWSTR pszFormat, + __in va_list argList) +{ + NTSTATUS status = STATUS_SUCCESS; + int iRet; + + #pragma warning(push) + #pragma warning(disable: __WARNING_BANNED_API_USAGE)// "STRSAFE not included" + iRet = _vsnwprintf(pszDest, cchDest, pszFormat, argList); + #pragma warning(pop) + // ASSERT((iRet < 0) || (((size_t)iRet) <= cchMax)); + + if ((iRet < 0) || (((size_t)iRet) > cchDest)) + { + *pcchNewDestLength = cchDest; + + // we have truncated pszDest + status = STATUS_BUFFER_OVERFLOW; + } + else + { + *pcchNewDestLength = (size_t)iRet; + } + + return status; +} + +NTSTRSAFEWORKERDDI +RtlUnicodeStringExHandleFill( + __out_ecount(cchRemaining) wchar_t* pszDestEnd, + __in size_t cchRemaining, + __in DWORD dwFlags) +{ + size_t cbRemaining; + + // safe to multiply cchRemaining * sizeof(wchar_t) since cchRemaining < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + cbRemaining = cchRemaining * sizeof(wchar_t); + + memset(pszDestEnd, STRSAFE_GET_FILL_PATTERN(dwFlags), cbRemaining); + + return STATUS_SUCCESS; +} + +NTSTRSAFEWORKERDDI +RtlUnicodeStringExHandleOtherFlags( + __inout_ecount(cchDest) wchar_t* pszDest, + __in size_t cchDest, + __in size_t cchOriginalDestLength, + __out size_t* pcchNewDestLength, + __deref_out_ecount(*pcchRemaining) wchar_t** ppszDestEnd, + __out size_t* pcchRemaining, + __in DWORD dwFlags) +{ + if (dwFlags & STRSAFE_NO_TRUNCATION) + { + *ppszDestEnd = pszDest + cchOriginalDestLength; + *pcchRemaining = cchDest - cchOriginalDestLength; + + *pcchNewDestLength = cchOriginalDestLength; + } + + if (dwFlags & STRSAFE_FILL_ON_FAILURE) + { + size_t cbDest; + + // safe to multiply cchDest * sizeof(wchar_t) since cchDest < NTSTRSAFE_UNICODE_STRING_MAX_CCH and sizeof(wchar_t) is 2 + cbDest = cchDest * sizeof(wchar_t); + + memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest); + + *ppszDestEnd = pszDest; + *pcchRemaining = cchDest; + + *pcchNewDestLength = 0; + } + + if (dwFlags & STRSAFE_ZERO_LENGTH_ON_FAILURE) + { + *ppszDestEnd = pszDest; + *pcchRemaining = cchDest; + + *pcchNewDestLength = 0; + } + + return STATUS_SUCCESS; +} + +#endif // !NTSTRSAFE_NO_UNICODE_STRING_FUNCTIONS + +#endif // defined(NTSTRSAFE_LIB_IMPL) || !defined(NTSTRSAFE_LIB) + + +// Do not call these functions, they are worker functions for internal use within this file +#ifdef DEPRECATE_SUPPORTED +#pragma deprecated(RtlStringLengthWorkerA) +#pragma deprecated(RtlStringLengthWorkerW) +#pragma deprecated(RtlUnalignedStringLengthWorkerW) +#pragma deprecated(RtlStringExValidateSrcA) +#pragma deprecated(RtlStringExValidateSrcW) +#pragma deprecated(RtlStringValidateDestA) +#pragma deprecated(RtlStringValidateDestAndLengthA) +#pragma deprecated(RtlStringValidateDestW) +#pragma deprecated(RtlStringValidateDestAndLengthW) +#pragma deprecated(RtlStringExValidateDestA) +#pragma deprecated(RtlStringExValidateDestAndLengthA) +#pragma deprecated(RtlStringExValidateDestW) +#pragma deprecated(RtlStringExValidateDestAndLengthW) +#pragma deprecated(RtlStringCopyWorkerA) +#pragma deprecated(RtlStringCopyWorkerW) +#pragma deprecated(RtlStringVPrintfWorkerA) +#pragma deprecated(RtlStringVPrintfWorkerW) +#pragma deprecated(RtlStringExHandleFillBehindNullA) +#pragma deprecated(RtlStringExHandleFillBehindNullW) +#pragma deprecated(RtlStringExHandleOtherFlagsA) +#pragma deprecated(RtlStringExHandleOtherFlagsW) +#pragma deprecated(RtlUnicodeStringInitWorker) +#pragma deprecated(RtlUnicodeStringValidateWorker) +#pragma deprecated(RtlUnicodeStringValidateSrcWorker) +#pragma deprecated(RtlUnicodeStringValidateDestWorker) +#pragma deprecated(RtlStringCopyWideCharArrayWorker) +#pragma deprecated(RtlWideCharArrayCopyStringWorker) +#pragma deprecated(RtlWideCharArrayCopyWorker) +#pragma deprecated(RtlWideCharArrayVPrintfWorker) +#pragma deprecated(RtlUnicodeStringExHandleFill) +#pragma deprecated(RtlUnicodeStringExHandleOtherFlags) +#else +#define RtlStringLengthWorkerA RtlStringLengthWorkerA_instead_use_StringCchLengthA_or_StringCbLengthA +#define RtlStringLengthWorkerW RtlStringLengthWorkerW_instead_use_StringCchLengthW_or_StringCbLengthW +#define RtlUnalignedStringLengthWorkerW RtlUnalignedStringLengthWorkerW_instead_use_UnalignedStringCchLengthW +#define RtlStringExValidateSrcA RtlStringExValidateSrcA_do_not_call_this_function +#define RtlStringExValidateSrcW RtlStringExValidateSrcW_do_not_call_this_function +#define RtlStringValidateDestA RtlStringValidateDestA_do_not_call_this_function +#define RtlStringValidateDestAndLengthA RtlStringValidateDestAndLengthA_do_not_call_this_function +#define RtlStringValidateDestW RtlStringValidateDestW_do_not_call_this_function +#define RtlStringValidateDestAndLengthW RtlStringValidateDestAndLengthW_do_not_call_this_function +#define RtlStringExValidateDestA RtlStringExValidateDestA_do_not_call_this_function +#define RtlStringExValidateDestAndLengthA RtlStringExValidateDestAndLengthA_do_not_call_this_function +#define RtlStringExValidateDestW RtlStringExValidateDestW_do_not_call_this_function +#define RtlStringExValidateDestAndLengthW RtlStringExValidateDestAndLengthW_do_not_call_this_function +#define RtlStringCopyWorkerA RtlStringCopyWorkerA_instead_use_StringCchCopyA_or_StringCbCopyA +#define RtlStringCopyWorkerW RtlStringCopyWorkerW_instead_use_StringCchCopyW_or_StringCbCopyW +#define RtlStringVPrintfWorkerA RtlStringVPrintfWorkerA_instead_use_StringCchVPrintfA_or_StringCbVPrintfA +#define RtlStringVPrintfWorkerW RtlStringVPrintfWorkerW_instead_use_StringCchVPrintfW_or_StringCbVPrintfW +#define RtlStringExHandleFillBehindNullA RtlStringExHandleFillBehindNullA_do_not_call_this_function +#define RtlStringExHandleFillBehindNullW RtlStringExHandleFillBehindNullW_do_not_call_this_function +#define RtlStringExHandleOtherFlagsA RtlStringExHandleOtherFlagsA_do_not_call_this_function +#define RtlStringExHandleOtherFlagsW RtlStringExHandleOtherFlagsW_do_not_call_this_function +#define RtlUnicodeStringInitWorker RtlUnicodeStringInitWorker_instead_use_RtlUnicodeStringInit_or_RtlUnicodeStringInitEx +#define RtlUnicodeStringValidateWorker RtlUnicodeStringValidateWorker_instead_use_RtlUnicodeStringValidate_or_RtlUnicodeStringValidateEx +#define RtlUnicodeStringValidateSrcWorker RtlUnicodeStringValidateSrcWorker_do_not_call_this_function +#define RtlUnicodeStringValidateDestWorker RtlUnicodeStringValidateDestWorker_do_not_call_this_function +#define RtlStringCopyWideCharArrayWorker RtlStringCopyWideCharArrayWorker_instead_use_RtlStringCchCopyUnicodeString_or_RtlStringCbCopyUnicodeString +#define RtlWideCharArrayCopyStringWorker RtlWideCharArrayCopyStringWorker_instead_use_RtlUnicodeStringCopyString_or_RtlUnicodeStringCopyStringEx +#define RtlWideCharArrayCopyWorker RtlWideCharArrayCopyWorker_instead_use_RtlUnicodeStringCopy_or_RtlUnicodeStringCopyEx +#define RtlWideCharArrayVPrintfWorker RtlWideCharArrayVPrintfWorker_instead_use_RtlUnicodeStringVPrintf_or_RtlUnicodeStringPrintf +#define RtlUnicodeStringExHandleFill RtlUnicodeStringExHandleFill_do_not_call_this_function +#define RtlUnicodeStringExHandleOtherFlags RtlUnicodeStringExHandleOtherFlags_do_not_call_this_function +#endif // !DEPRECATE_SUPPORTED + + +#ifndef NTSTRSAFE_NO_DEPRECATE +// Deprecate all of the unsafe functions to generate compiletime errors. If you do not want +// this then you can #define NTSTRSAFE_NO_DEPRECATE before including this file +#ifdef DEPRECATE_SUPPORTED + +#pragma deprecated(strcpy) +#pragma deprecated(wcscpy) +#pragma deprecated(strcat) +#pragma deprecated(wcscat) +#pragma deprecated(sprintf) +#pragma deprecated(swprintf) +#pragma deprecated(vsprintf) +#pragma deprecated(vswprintf) +#pragma deprecated(_snprintf) +#pragma deprecated(_snwprintf) +#pragma deprecated(_vsnprintf) +#pragma deprecated(_vsnwprintf) + +#else // DEPRECATE_SUPPORTED + +#undef strcpy +#define strcpy strcpy_instead_use_StringCchCopyA_or_StringCbCopyA; + +#undef wcscpy +#define wcscpy wcscpy_instead_use_StringCchCopyW_or_StringCbCopyW; + +#undef strcat +#define strcat strcat_instead_use_StringCchCatA_or_StringCbCatA; + +#undef wcscat +#define wcscat wcscat_instead_use_StringCchCatW_or_StringCbCatW; + +#undef sprintf +#define sprintf sprintf_instead_use_StringCchPrintfA_or_StringCbPrintfA; + +#undef swprintf +#define swprintf swprintf_instead_use_StringCchPrintfW_or_StringCbPrintfW; + +#undef vsprintf +#define vsprintf vsprintf_instead_use_StringCchVPrintfA_or_StringCbVPrintfA; + +#undef vswprintf +#define vswprintf vswprintf_instead_use_StringCchVPrintfW_or_StringCbVPrintfW; + +#undef _snprintf +#define _snprintf _snprintf_instead_use_StringCchPrintfA_or_StringCbPrintfA; + +#undef _snwprintf +#define _snwprintf _snwprintf_instead_use_StringCchPrintfW_or_StringCbPrintfW; + +#undef _vsnprintf +#define _vsnprintf _vsnprintf_instead_use_StringCchVPrintfA_or_StringCbVPrintfA; + +#undef _vsnwprintf +#define _vsnwprintf _vsnwprintf_instead_use_StringCchVPrintfW_or_StringCbVPrintfW; + +#endif // DEPRECATE_SUPPORTED +#endif // !NTSTRSAFE_NO_DEPRECATE + +#pragma warning(pop) + +#endif // _NTSTRSAFE_H_INCLUDED_ + diff --git a/00-Common Headers/SafeAlloc.h b/00-Common Headers/SafeAlloc.h new file mode 100644 index 0000000..03a677f --- /dev/null +++ b/00-Common Headers/SafeAlloc.h @@ -0,0 +1,91 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// SafeAlloc.h +// +// Abstract: +// +// Safe memory allocation macros. +// +// SafeAlloc and SafeFree are the safe memory management macros that should +// be strongly preferred for code in VxKex. Advantages include: +// +// 1. No type-casting required in most cases. +// 2. Reduced chance of stupid typo bugs with sizeof(). +// 3. Use-after-free will always result in a crash instead of UB. +// +// Author: +// +// vxiiduu (26-Sep-2022) +// +// Environment: +// +// Anywhere where you can call the NTDLL heap functions. +// +// Revision History: +// +// vxiiduu 26-Sep-2022 Initial creation. +// vxiiduu 30-Sep-2022 Removed *Early and *Nullable variants +// because they are useless. +// vxiiduu 01-Oct-2022 Add *Ex variants +// vxiiduu 22-Oct-2022 Fix SafeReAlloc typos +// vxiiduu 12-Nov-2022 Add *Seh variants +// vxiiduu 20-Nov-2022 Add SafeClose +// vxiiduu 19-Feb-2024 Add SafeRelease +// +/////////////////////////////////////////////////////////////////////////////// + +#pragma once +#include +#include + +#define SafeAllocEx(Heap, Flags, Type, NumberOfElements) \ + ((Type *) RtlAllocateHeap((Heap), (Flags), sizeof(Type) * (NumberOfElements))) + +#define SafeReAllocEx(Heap, Flags, OriginalPointer, Type, NumberOfElements) \ + ((Type *) RtlReAllocateHeap((Heap), (Flags), (OriginalPointer), sizeof(Type) * (NumberOfElements))) + +#define SafeFreeEx(Heap, Flags, Pointer) \ + do { RtlFreeHeap(Heap, Flags, (Pointer)); (Pointer) = NULL; } while (0) + +#define SafeAlloc(Type, NumberOfElements) \ + SafeAllocEx(RtlProcessHeap(), 0, Type, (NumberOfElements)) + +#define SafeReAlloc(OriginalPointer, Type, NumberOfElements) \ + SafeReAllocEx(RtlProcessHeap(), 0, (OriginalPointer), Type, (NumberOfElements)) + +#define SafeFree(Pointer) \ + SafeFreeEx(RtlProcessHeap(), 0, (Pointer)) + +#define SafeAllocSeh(Type, NumberOfElements) \ + SafeAllocEx(RtlProcessHeap(), HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY, Type, (NumberOfElements)) + +#define SafeReAllocSeh(OriginalPointer, Type, NumberOfElements) \ + SafeReAllocEx(RtlProcessHeap(), HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY, (OriginalPointer), Type, (NumberOfElements)) + +#define SafeFreeSeh(Pointer) \ + SafeFreeEx(RtlProcessHeap(), HEAP_GENERATE_EXCEPTIONS, (Pointer)) + +// +// _alloca() is a compiler intrinsic. +// + +#ifndef __cplusplus +PVOID CDECL _alloca( + IN SIZE_T NumberOfBytes); +#endif + +#define StackAlloc(Type, NumberOfElements) ((Type *) _alloca(sizeof(Type) * (NumberOfElements))) + +// +// SafeClose is for handles. +// + +#define SafeClose(Handle) do { if (Handle) { NTSTATUS SafeCloseStatus = NtClose(Handle); ASSERT (NT_SUCCESS(SafeCloseStatus)); (Handle) = NULL; } } while(0) + +// +// SafeRelease is for COM interfaces. +// + +#define SafeRelease(Interface) do { if (Interface) { (Interface)->lpVtbl->Release(Interface); (Interface) = NULL; } } while (0) \ No newline at end of file diff --git a/00-Common Headers/vautogen.h b/00-Common Headers/vautogen.h new file mode 100644 index 0000000..46cb718 Binary files /dev/null and b/00-Common Headers/vautogen.h differ diff --git a/00-Documentation/Application Compatibility List.docx b/00-Documentation/Application Compatibility List.docx new file mode 100644 index 0000000..6388cb3 Binary files /dev/null and b/00-Documentation/Application Compatibility List.docx differ diff --git a/00-Documentation/Changelog.txt b/00-Documentation/Changelog.txt new file mode 100644 index 0000000..bbb7699 Binary files /dev/null and b/00-Documentation/Changelog.txt differ diff --git a/00-Documentation/Debugging KexDll.txt b/00-Documentation/Debugging KexDll.txt new file mode 100644 index 0000000..0cf3910 --- /dev/null +++ b/00-Documentation/Debugging KexDll.txt @@ -0,0 +1,12 @@ +KexDll is not 100% straightforward to debug, since it executes prior to most +other DllMain's and prior to the main exe's entry point. + +However, WinDbg (part of Debugging Tools for Windows, found in the SDK) can +easily debug its code by following these steps: + + 1. Start an application in WinDbg by File->Open Executable. + 2. Type in the command window: "bu KexDll!DllMain" (or any other function) + 3. Re-start the application by Debug->Restart. + +Then, WinDbg will break at any specified function in KexDll and can display +source code, variables, call stack, etc. \ No newline at end of file diff --git a/00-Documentation/KexSetup responsibilities.txt b/00-Documentation/KexSetup responsibilities.txt new file mode 100644 index 0000000..6530717 --- /dev/null +++ b/00-Documentation/KexSetup responsibilities.txt @@ -0,0 +1,31 @@ +The program which installs VxKex on user computers is called KexSetup and its +source code can be found in the main solution. The responsibilities of this +program include: + + - creating an installation folder inside Program files (or another user + selected location) + + - creating registry keys and values: + + \Registry\Machine\Software\VXsoft\VxKex + InstalledVersion (REG_DWORD) + KexDir (REG_SZ) + LogDir (REG_SZ) + + \Registry\User\Software\VXsoft\VxKex + LogDir (REG_SZ) (overrides the HKLM value, if present) + + - placing KexDll into system32 + + - placing auxiliary files and programs, such as the log viewer, the + configuration helper program KexCfg, and the shell extension KexShlEx + into the VxKex installation folder (known as KexDir within the code) + + - placing the system extension DLLs (kxbase, kxuser, etc.) into KexDir + + - registering the VxKex property sheet page shell extension + + - associating .vxl file extension with VxlView + +Of course, the program can also uninstall VxKex and must reverse all the above +procedures when doing so. \ No newline at end of file diff --git a/00-Documentation/Notes on IFEO.txt b/00-Documentation/Notes on IFEO.txt new file mode 100644 index 0000000..06116ef --- /dev/null +++ b/00-Documentation/Notes on IFEO.txt @@ -0,0 +1,115 @@ +Information in this file is based on analysis of Windows 7 SP1 and also +Windows 7 with all latest ESU updates. May not be 100% compatible with all +Win7 builds; if widespread usage is intended, further study is up to the +reader. + +WOW64 Note: On Windows 7 and above, the Image File Execution Options key is +shared for 32-bit and 64-bit processes. There is no need to worry about +WOW64 registry redirection for the IFEO key on Windows 7. + + +The following values are meaningful to Windows 7 when under the IFEO root: + +DevOverrideEnabled + Allows .local redirection for all .exes. + +The following values are meaningful to Windows 7 when under an IFEO exe key: + +== kernel32!CreateProcessInternalW == + +Debugger + +== kernel32!BaseDllInitialize == + +SearchPathMode + passed directly to SetSearchPathMode() on dll init + +== ntdll!RtlpProcessIFEOKeyFilter == + +FilterFullPath + It's fine to use a Win32 path for this value. + +UseFilter + +== ntdll!LdrpInitializeExecutionOptions == + +GlobalFlag(*) + This value ends up in Peb->NtGlobalFlag. + See FLG_* in NtDll.h + +CWDIllegalInDllSearch + 0xFFFFFFFF - Remove the current working directory from the default DLL search order + 0x00000001 - Blocks a DLL load from the current working directory if the CWD is a WebDAV folder + 0x00000002 - Blocks a DLL load from the current working directory if the CWD is a remote folder + +DisableHeapLookaside + +ShutdownFlags + This value is checked by ntdll!RtlDetectHeapLeaks upon proper process + shutdown (i.e. not terminated forcibly). + Possible values are a combination of INSPECT_LEAKS and BREAK_ON_LEAKS + defined in NtDll.h. + +UseImpersonatedDeviceMap (NOT in SP1) +MinimumStackCommitInBytes +MaxDeadActivationContexts +UnloadEventTraceDepth +TracingFlags + +ShowRecursiveDllLoads +BreakOnRecursiveDllLoads +BreakOnInitializeProcessFailure +KeepActivationContextsAlive +TrackActivationContextReleases + +== ntdll!LdrpInitializeProcess == + +DisableUserModeCallbackFilter +StackTraceDatabaseSizeInMb +DebugProcessHeapOnly + +== ntdll!LdrpInitializeApplicationVerifierPackage == + +PageHeapFlags(*) + +== ntdll!AVrfInitializeVerifier == + +VerifierFlags(*) + See RTL_VRF_FLG_*. + Set to 0x80000000 to disable page heap (which is slow as balls). + +HandleTraces(*) + +VerifierDebug(*) + Various flags which control debug printing. + See AVRF_DBG_* in NtDll.h + +VerifierDlls(*) + +== verifier!AVrfpMiniLoadAttach == (only when avrf enabled of course) + +PageHeapSizeRangeStart +PageHeapSizeRangeEnd +PageHeapRandomProbability +PageHeapDllRangeStart +PageHeapDllRangeEnd +PageHeapTargetDlls +PageHeapVirtualMemoryPercent +PageHeapCommitMemoryPercent + + +(*) - Any value thus marked is able to be read from HKCU ifeo key +(HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options) +in addition to the normal one in HKLM, but ONLY if SharedUserData->ImageFileExecutionOptions +has the low-order bit set to 1. + +The Microsoft documentation for the verifier.dll function "VerifierIsPerUserSettingsEnabled" +says that we should set a DWORD registry value "ImageExecutionOptions" in the registry key +HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager to 1, and then the kernel +will set the appropriate value in SharedUserData. + +Usually this would be a good thing for VxKex because we wouldn't have to ask for admin +permissions to change configs, but unfortunately the AVrfOpenCurrentUserImageFileOptionsKey +routine in ntdll doesn't respect the "IFEO key filter" mechanism implemented in +RtlpProcessIFEOKeyFilter. Therefore all of our configuration must be stored in the HKLM +ifeo key. \ No newline at end of file diff --git a/00-Documentation/NtQuerySystemInformation doc and examples.txt b/00-Documentation/NtQuerySystemInformation doc and examples.txt new file mode 100644 index 0000000..5fd0055 --- /dev/null +++ b/00-Documentation/NtQuerySystemInformation doc and examples.txt @@ -0,0 +1,2861 @@ +See Ntdll.h for prototype and structs definition. +NtQuerySystemInformation, SystemModuleInformation, RTL_PROCESS_MODULES + RTL_PROCESS_MODULE_INFORMATION. + +Kernel mode modules are always listed before user mode modules. +NTDLL is always the first user mode module listed, SMSS is always the second. + +NumberOfModules - don't trust this number unless NtQuerySystemInformation returns STATUS_SUCCESS. + +#define LDRP_STATIC_LINK 0x00000002 +#define LDRP_IMAGE_DLL 0x00000004 +#define LDRP_LOAD_IN_PROGRESS 0x00001000 +#define LDRP_UNLOAD_IN_PROGRESS 0x00002000 +#define LDRP_ENTRY_PROCESSED 0x00004000 +#define LDRP_ENTRY_INSERTED 0x00008000 +#define LDRP_CURRENT_LOAD 0x00010000 +#define LDRP_FAILED_BUILTIN_LOAD 0x00020000 +#define LDRP_DONT_CALL_FOR_THREADS 0x00040000 +#define LDRP_PROCESS_ATTACH_CALLED 0x00080000 +#define LDRP_DEBUG_SYMBOLS_LOADED 0x00100000 +#define LDRP_IMAGE_NOT_AT_BASE 0x00200000 +#define LDRP_COR_IMAGE 0x00400000 +#define LDRP_COR_OWNS_UNMAP 0x00800000 +#define LDRP_SYSTEM_MAPPED 0x01000000 +#define LDRP_IMAGE_VERIFYING 0x02000000 +#define LDRP_DRIVER_DEPENDENT_DLL 0x04000000 +#define LDRP_ENTRY_NATIVE 0x08000000 +#define LDRP_REDIRECTED 0x10000000 +#define LDRP_NON_PAGED_DEBUG_INFO 0x20000000 +#define LDRP_MM_LOADED 0x40000000 +#define LDRP_COMPAT_DATABASE_PROCESSED 0x80000000 + +Section - Always uninitialized. +MappedBase - Uninitialized for kernel mode DLLs/drivers, set to 0 for user mode DLLs. +ImageBase - Base of the image. High bit (0x80000000 or 0x8000000000000000) is set for kernel mode images. +ImageSize - Size in bytes of the image. +Flags - Same as KLDR_DATA_TABLE_ENTRY.Flags. LDRP_* +LoadOrderIndex - order which the module loaded in. starts at 0, ntoskrnl.exe is always 0. +LoadCount - reference count of image. +InitOrderIndex - 0 for kernel mode, same as LoadOrderIndex for user mode. +FullPathName - Always null terminated. NT style path, or root drive relative path. Example \SystemRoot\... or \Windows\system32\... + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff80003611000 +ImageSize = 6152192 +Flags = 0x8004000 +LoadOrderIndex = 0 +InitOrderIndex = 0 +LoadCount = 122 +OffsetToFileName= 21 +FullPathName = "\SystemRoot\system32\ntoskrnl.exe" +Base name = "ntoskrnl.exe" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff80003bef000 +ImageSize = 294912 +Flags = 0x8004000 +LoadOrderIndex = 1 +InitOrderIndex = 0 +LoadCount = 32 +OffsetToFileName= 21 +FullPathName = "\SystemRoot\system32\hal.dll" +Base name = "hal.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff80000bb8000 +ImageSize = 40960 +Flags = 0x8004000 +LoadOrderIndex = 2 +InitOrderIndex = 0 +LoadCount = 3 +OffsetToFileName= 21 +FullPathName = "\SystemRoot\system32\kdcom.dll" +Base name = "kdcom.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88000c62000 +ImageSize = 516096 +Flags = 0x9104000 +LoadOrderIndex = 3 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 21 +FullPathName = "\SystemRoot\system32\mcupdate_GenuineIntel.dll" +Base name = "mcupdate_GenuineIntel.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88000ce0000 +ImageSize = 81920 +Flags = 0xd104000 +LoadOrderIndex = 4 +InitOrderIndex = 0 +LoadCount = 3 +OffsetToFileName= 21 +FullPathName = "\SystemRoot\system32\PSHED.dll" +Base name = "PSHED.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88000cf4000 +ImageSize = 409600 +Flags = 0x9104000 +LoadOrderIndex = 5 +InitOrderIndex = 0 +LoadCount = 3 +OffsetToFileName= 21 +FullPathName = "\SystemRoot\system32\CLFS.SYS" +Base name = "CLFS.SYS" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88000d58000 +ImageSize = 475136 +Flags = 0xd104000 +LoadOrderIndex = 6 +InitOrderIndex = 0 +LoadCount = 2 +OffsetToFileName= 21 +FullPathName = "\SystemRoot\system32\CI.dll" +Base name = "CI.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88000ec7000 +ImageSize = 794624 +Flags = 0x9104000 +LoadOrderIndex = 7 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\Wdf01000.sys" +Base name = "Wdf01000.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88000f89000 +ImageSize = 65536 +Flags = 0xd104000 +LoadOrderIndex = 8 +InitOrderIndex = 0 +LoadCount = 15 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\WDFLDR.SYS" +Base name = "WDFLDR.SYS" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88000f99000 +ImageSize = 356352 +Flags = 0x9104000 +LoadOrderIndex = 9 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\ACPI.sys" +Base name = "ACPI.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88000ff0000 +ImageSize = 36864 +Flags = 0xd104000 +LoadOrderIndex = 10 +InitOrderIndex = 0 +LoadCount = 18 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\WMILIB.SYS" +Base name = "WMILIB.SYS" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88000e00000 +ImageSize = 40960 +Flags = 0x9104000 +LoadOrderIndex = 11 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\msisadrv.sys" +Base name = "msisadrv.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88000e0a000 +ImageSize = 208896 +Flags = 0x9104000 +LoadOrderIndex = 12 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\pci.sys" +Base name = "pci.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88000e3d000 +ImageSize = 53248 +Flags = 0x9104000 +LoadOrderIndex = 13 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\vdrvroot.sys" +Base name = "vdrvroot.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88000e4a000 +ImageSize = 86016 +Flags = 0x9104000 +LoadOrderIndex = 14 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\drivers\partmgr.sys" +Base name = "partmgr.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88000e5f000 +ImageSize = 81920 +Flags = 0x9104000 +LoadOrderIndex = 15 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\volmgr.sys" +Base name = "volmgr.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88000c00000 +ImageSize = 376832 +Flags = 0x9104000 +LoadOrderIndex = 16 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\drivers\volmgrx.sys" +Base name = "volmgrx.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88000e73000 +ImageSize = 102400 +Flags = 0x9104000 +LoadOrderIndex = 17 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\vmci.sys" +Base name = "vmci.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88000e8c000 +ImageSize = 94208 +Flags = 0x9104000 +LoadOrderIndex = 18 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\vsock.sys" +Base name = "vsock.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88000ea3000 +ImageSize = 106496 +Flags = 0x9104000 +LoadOrderIndex = 19 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\drivers\mountmgr.sys" +Base name = "mountmgr.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88000ebd000 +ImageSize = 36864 +Flags = 0x9104000 +LoadOrderIndex = 20 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\atapi.sys" +Base name = "atapi.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88000dcc000 +ImageSize = 172032 +Flags = 0xd104000 +LoadOrderIndex = 21 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\ataport.SYS" +Base name = "ataport.SYS" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88001059000 +ImageSize = 45056 +Flags = 0x9104000 +LoadOrderIndex = 22 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\msahci.sys" +Base name = "msahci.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88001064000 +ImageSize = 65536 +Flags = 0xd104000 +LoadOrderIndex = 23 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\PCIIDEX.SYS" +Base name = "PCIIDEX.SYS" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88001074000 +ImageSize = 61440 +Flags = 0x9104000 +LoadOrderIndex = 24 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\stornvme.sys" +Base name = "stornvme.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88001083000 +ImageSize = 413696 +Flags = 0xd104000 +LoadOrderIndex = 25 +InitOrderIndex = 0 +LoadCount = 3 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\storport.sys" +Base name = "storport.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff880010e8000 +ImageSize = 94208 +Flags = 0x9104000 +LoadOrderIndex = 26 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\secnvme.sys" +Base name = "secnvme.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff880010ff000 +ImageSize = 45056 +Flags = 0x9104000 +LoadOrderIndex = 27 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\amdxata.sys" +Base name = "amdxata.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff8800110a000 +ImageSize = 303104 +Flags = 0x9104000 +LoadOrderIndex = 28 +InitOrderIndex = 0 +LoadCount = 4 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\fltmgr.sys" +Base name = "fltmgr.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88001154000 +ImageSize = 81920 +Flags = 0x9104000 +LoadOrderIndex = 29 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\fileinfo.sys" +Base name = "fileinfo.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88001219000 +ImageSize = 1740800 +Flags = 0x9104000 +LoadOrderIndex = 30 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\Drivers\Ntfs.sys" +Base name = "Ntfs.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88001168000 +ImageSize = 380928 +Flags = 0xd104000 +LoadOrderIndex = 31 +InitOrderIndex = 0 +LoadCount = 10 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\Drivers\msrpc.sys" +Base name = "msrpc.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff880013c2000 +ImageSize = 110592 +Flags = 0x9104000 +LoadOrderIndex = 32 +InitOrderIndex = 0 +LoadCount = 21 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\Drivers\ksecdd.sys" +Base name = "ksecdd.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff880014cb000 +ImageSize = 479232 +Flags = 0x9104000 +LoadOrderIndex = 33 +InitOrderIndex = 0 +LoadCount = 3 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\Drivers\cng.sys" +Base name = "cng.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88001540000 +ImageSize = 73728 +Flags = 0x9104020 +LoadOrderIndex = 34 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\drivers\pcw.sys" +Base name = "pcw.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88001552000 +ImageSize = 40960 +Flags = 0x9104000 +LoadOrderIndex = 35 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\Drivers\Fs_Rec.sys" +Base name = "Fs_Rec.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88001679000 +ImageSize = 991232 +Flags = 0x9104000 +LoadOrderIndex = 36 +InitOrderIndex = 0 +LoadCount = 28 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\ndis.sys" +Base name = "ndis.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff8800176b000 +ImageSize = 393216 +Flags = 0xd104000 +LoadOrderIndex = 37 +InitOrderIndex = 0 +LoadCount = 24 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\NETIO.SYS" +Base name = "NETIO.SYS" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff880017cb000 +ImageSize = 176128 +Flags = 0x9104000 +LoadOrderIndex = 38 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\Drivers\ksecpkg.sys" +Base name = "ksecpkg.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88001805000 +ImageSize = 2072576 +Flags = 0x9104020 +LoadOrderIndex = 39 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\drivers\tcpip.sys" +Base name = "tcpip.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88001600000 +ImageSize = 299008 +Flags = 0xd104000 +LoadOrderIndex = 40 +InitOrderIndex = 0 +LoadCount = 8 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\drivers\fwpkclnt.sys" +Base name = "fwpkclnt.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88001649000 +ImageSize = 36864 +Flags = 0x9104000 +LoadOrderIndex = 41 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\wfplwf.sys" +Base name = "wfplwf.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88001652000 +ImageSize = 65536 +Flags = 0x9104000 +LoadOrderIndex = 42 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\vmstorfl.sys" +Base name = "vmstorfl.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff8800155c000 +ImageSize = 311296 +Flags = 0x9104000 +LoadOrderIndex = 43 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\volsnap.sys" +Base name = "volsnap.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88001662000 +ImageSize = 32768 +Flags = 0x9104000 +LoadOrderIndex = 44 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\Drivers\spldr.sys" +Base name = "spldr.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff8800166a000 +ImageSize = 45056 +Flags = 0x9104000 +LoadOrderIndex = 45 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\secnvmeF.sys" +Base name = "secnvmeF.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff880015a8000 +ImageSize = 237568 +Flags = 0x9104000 +LoadOrderIndex = 46 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\drivers\rdyboost.sys" +Base name = "rdyboost.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88001400000 +ImageSize = 126976 +Flags = 0x9104000 +LoadOrderIndex = 47 +InitOrderIndex = 0 +LoadCount = 4 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\Drivers\mup.sys" +Base name = "mup.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff880017f6000 +ImageSize = 36864 +Flags = 0x9104000 +LoadOrderIndex = 48 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\drivers\hwpolicy.sys" +Base name = "hwpolicy.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff8800141f000 +ImageSize = 208896 +Flags = 0x9104000 +LoadOrderIndex = 49 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\DRIVERS\fvevol.sys" +Base name = "fvevol.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88001452000 +ImageSize = 86016 +Flags = 0x9104000 +LoadOrderIndex = 50 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\disk.sys" +Base name = "disk.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88001467000 +ImageSize = 204800 +Flags = 0xd104000 +LoadOrderIndex = 51 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\CLASSPNP.SYS" +Base name = "CLASSPNP.SYS" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff880015f5000 +ImageSize = 36864 +Flags = 0x49104000 +LoadOrderIndex = 52 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\Drivers\Null.SYS" +Base name = "Null.SYS" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff880013dd000 +ImageSize = 28672 +Flags = 0x49104000 +LoadOrderIndex = 53 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\Drivers\Beep.SYS" +Base name = "Beep.SYS" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff880013e4000 +ImageSize = 57344 +Flags = 0x49104000 +LoadOrderIndex = 54 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\drivers\vga.sys" +Base name = "vga.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88001000000 +ImageSize = 151552 +Flags = 0x4d104000 +LoadOrderIndex = 55 +InitOrderIndex = 0 +LoadCount = 5 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\drivers\VIDEOPRT.SYS" +Base name = "VIDEOPRT.SYS" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88001200000 +ImageSize = 65536 +Flags = 0x4d104000 +LoadOrderIndex = 56 +InitOrderIndex = 0 +LoadCount = 5 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\drivers\watchdog.sys" +Base name = "watchdog.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88001210000 +ImageSize = 36864 +Flags = 0x49104000 +LoadOrderIndex = 57 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\DRIVERS\RDPCDD.sys" +Base name = "RDPCDD.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff880013f2000 +ImageSize = 36864 +Flags = 0x49104000 +LoadOrderIndex = 58 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\rdpencdd.sys" +Base name = "rdpencdd.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88001025000 +ImageSize = 36864 +Flags = 0x49104000 +LoadOrderIndex = 59 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\rdprefmp.sys" +Base name = "rdprefmp.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff8800102e000 +ImageSize = 45056 +Flags = 0x49104000 +LoadOrderIndex = 60 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\Drivers\Msfs.SYS" +Base name = "Msfs.SYS" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88001039000 +ImageSize = 69632 +Flags = 0x49104000 +LoadOrderIndex = 61 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\Drivers\Npfs.SYS" +Base name = "Npfs.SYS" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff880011c5000 +ImageSize = 139264 +Flags = 0x49104000 +LoadOrderIndex = 62 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\tdx.sys" +Base name = "tdx.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff880011e7000 +ImageSize = 53248 +Flags = 0x4d104000 +LoadOrderIndex = 63 +InitOrderIndex = 0 +LoadCount = 7 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\TDI.SYS" +Base name = "TDI.SYS" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88002caf000 +ImageSize = 557056 +Flags = 0x49104000 +LoadOrderIndex = 64 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\afd.sys" +Base name = "afd.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88002d37000 +ImageSize = 282624 +Flags = 0x49104000 +LoadOrderIndex = 65 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\DRIVERS\netbt.sys" +Base name = "netbt.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88002d7c000 +ImageSize = 49152 +Flags = 0x49104000 +LoadOrderIndex = 66 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\ws2ifsl.sys" +Base name = "ws2ifsl.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88002d88000 +ImageSize = 155648 +Flags = 0x49104000 +LoadOrderIndex = 67 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\pacer.sys" +Base name = "pacer.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88002dae000 +ImageSize = 61440 +Flags = 0x49104000 +LoadOrderIndex = 68 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\nm3.sys" +Base name = "nm3.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88002dbd000 +ImageSize = 65536 +Flags = 0x49104000 +LoadOrderIndex = 69 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\netbios.sys" +Base name = "netbios.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88002dcd000 +ImageSize = 110592 +Flags = 0x49104000 +LoadOrderIndex = 70 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\wanarp.sys" +Base name = "wanarp.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88002de8000 +ImageSize = 81920 +Flags = 0x49104000 +LoadOrderIndex = 71 +InitOrderIndex = 0 +LoadCount = 4 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\termdd.sys" +Base name = "termdd.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88002c00000 +ImageSize = 339968 +Flags = 0x49104000 +LoadOrderIndex = 72 +InitOrderIndex = 0 +LoadCount = 6 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\rdbss.sys" +Base name = "rdbss.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88002c53000 +ImageSize = 49152 +Flags = 0x49104000 +LoadOrderIndex = 73 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\nsiproxy.sys" +Base name = "nsiproxy.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88002c5f000 +ImageSize = 45056 +Flags = 0x49104000 +LoadOrderIndex = 74 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\mssmbios.sys" +Base name = "mssmbios.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88002c6a000 +ImageSize = 61440 +Flags = 0x49104000 +LoadOrderIndex = 75 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\drivers\discache.sys" +Base name = "discache.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff8800445f000 +ImageSize = 544768 +Flags = 0x49104000 +LoadOrderIndex = 76 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\csc.sys" +Base name = "csc.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff880044e4000 +ImageSize = 135168 +Flags = 0x49104000 +LoadOrderIndex = 77 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\Drivers\dfsc.sys" +Base name = "dfsc.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88004505000 +ImageSize = 69632 +Flags = 0x49104000 +LoadOrderIndex = 78 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\blbdrive.sys" +Base name = "blbdrive.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88004516000 +ImageSize = 155648 +Flags = 0x49104000 +LoadOrderIndex = 79 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\tunnel.sys" +Base name = "tunnel.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff8800729d000 +ImageSize = 11145216 +Flags = 0x49104000 +LoadOrderIndex = 80 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\igdkmd64.sys" +Base name = "igdkmd64.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88004ca8000 +ImageSize = 1003520 +Flags = 0x49104000 +LoadOrderIndex = 81 +InitOrderIndex = 0 +LoadCount = 2 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\drivers\dxgkrnl.sys" +Base name = "dxgkrnl.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88004d9d000 +ImageSize = 286720 +Flags = 0x49104000 +LoadOrderIndex = 82 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\drivers\dxgmms1.sys" +Base name = "dxgmms1.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88004c00000 +ImageSize = 356352 +Flags = 0x49104000 +LoadOrderIndex = 83 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\USBXHCI.SYS" +Base name = "USBXHCI.SYS" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88004c57000 +ImageSize = 229376 +Flags = 0x49104000 +LoadOrderIndex = 84 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\ucx01000.sys" +Base name = "ucx01000.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88007d3e000 +ImageSize = 262144 +Flags = 0x49104000 +LoadOrderIndex = 85 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\TeeDriverx64.sys" +Base name = "TeeDriverx64.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff8800529a000 +ImageSize = 937984 +Flags = 0x49104000 +LoadOrderIndex = 86 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\RtsPer.sys" +Base name = "RtsPer.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff8800537f000 +ImageSize = 147456 +Flags = 0x49104000 +LoadOrderIndex = 87 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\HDAudBus.sys" +Base name = "HDAudBus.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88005200000 +ImageSize = 540672 +Flags = 0x49104000 +LoadOrderIndex = 88 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\e1d62x64.sys" +Base name = "e1d62x64.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88005284000 +ImageSize = 90112 +Flags = 0x49104000 +LoadOrderIndex = 89 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\intelppm.sys" +Base name = "intelppm.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff880053a3000 +ImageSize = 40960 +Flags = 0x49104000 +LoadOrderIndex = 90 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\acpipmi.sys" +Base name = "acpipmi.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff880053ad000 +ImageSize = 36864 +Flags = 0x49104000 +LoadOrderIndex = 91 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\wmiacpi.sys" +Base name = "wmiacpi.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff880053b6000 +ImageSize = 65536 +Flags = 0x49104000 +LoadOrderIndex = 92 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\CompositeBus.sys" +Base name = "CompositeBus.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff880053c6000 +ImageSize = 90112 +Flags = 0x49104000 +LoadOrderIndex = 93 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\AgileVpn.sys" +Base name = "AgileVpn.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88007d7e000 +ImageSize = 151552 +Flags = 0x49104000 +LoadOrderIndex = 94 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\rasl2tp.sys" +Base name = "rasl2tp.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff880053dc000 +ImageSize = 49152 +Flags = 0x49104000 +LoadOrderIndex = 95 +InitOrderIndex = 0 +LoadCount = 2 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\ndistapi.sys" +Base name = "ndistapi.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88007da3000 +ImageSize = 192512 +Flags = 0x49104000 +LoadOrderIndex = 96 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\ndiswan.sys" +Base name = "ndiswan.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88004de3000 +ImageSize = 110592 +Flags = 0x49104000 +LoadOrderIndex = 97 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\raspppoe.sys" +Base name = "raspppoe.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88007dd2000 +ImageSize = 135168 +Flags = 0x49104000 +LoadOrderIndex = 98 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\raspptp.sys" +Base name = "raspptp.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88007200000 +ImageSize = 106496 +Flags = 0x49104000 +LoadOrderIndex = 99 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\rassstp.sys" +Base name = "rassstp.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff880053e8000 +ImageSize = 45056 +Flags = 0x49104000 +LoadOrderIndex = 100 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\rdpbus.sys" +Base name = "rdpbus.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88004c8f000 +ImageSize = 61440 +Flags = 0x49104000 +LoadOrderIndex = 101 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\kbdclass.sys" +Base name = "kbdclass.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff8800721a000 +ImageSize = 61440 +Flags = 0x49104000 +LoadOrderIndex = 102 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\mouclass.sys" +Base name = "mouclass.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88007229000 +ImageSize = 192512 +Flags = 0x41104000 +LoadOrderIndex = 103 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\BazisVirtualCDBus.sys" +Base name = "BazisVirtualCDBus.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff880053f3000 +ImageSize = 8192 +Flags = 0x49104000 +LoadOrderIndex = 104 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\swenum.sys" +Base name = "swenum.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88007258000 +ImageSize = 274432 +Flags = 0x4d104000 +LoadOrderIndex = 105 +InitOrderIndex = 0 +LoadCount = 4 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\ks.sys" +Base name = "ks.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff880053f5000 +ImageSize = 45056 +Flags = 0x49104000 +LoadOrderIndex = 106 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\logi_joy_bus_enum.sys" +Base name = "logi_joy_bus_enum.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff8800453c000 +ImageSize = 73728 +Flags = 0x49104000 +LoadOrderIndex = 107 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\logi_joy_xlcore.sys" +Base name = "logi_joy_xlcore.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff8800454e000 +ImageSize = 73728 +Flags = 0x49104000 +LoadOrderIndex = 108 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\umbus.sys" +Base name = "umbus.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88007df3000 +ImageSize = 45056 +Flags = 0x49104000 +LoadOrderIndex = 109 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\vmnetadapter.sys" +Base name = "vmnetadapter.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88004560000 +ImageSize = 49152 +Flags = 0x4d104000 +LoadOrderIndex = 110 +InitOrderIndex = 0 +LoadCount = 3 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\VMNET.SYS" +Base name = "VMNET.SYS" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff8800456c000 +ImageSize = 86016 +Flags = 0x49104000 +LoadOrderIndex = 111 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\Drivers\NDProxy.SYS" +Base name = "NDProxy.SYS" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88004581000 +ImageSize = 475136 +Flags = 0x49104000 +LoadOrderIndex = 112 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\UsbHub3.sys" +Base name = "UsbHub3.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff880045f5000 +ImageSize = 45056 +Flags = 0x4d104000 +LoadOrderIndex = 113 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\USBD8.SYS" +Base name = "USBD8.SYS" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88004400000 +ImageSize = 376832 +Flags = 0x49104000 +LoadOrderIndex = 114 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\HdAudio.sys" +Base name = "HdAudio.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88006ee0000 +ImageSize = 249856 +Flags = 0x4d104000 +LoadOrderIndex = 115 +InitOrderIndex = 0 +LoadCount = 2 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\portcls.sys" +Base name = "portcls.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88006f1d000 +ImageSize = 139264 +Flags = 0x4d104000 +LoadOrderIndex = 116 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\drmk.sys" +Base name = "drmk.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88006f3f000 +ImageSize = 24576 +Flags = 0x49104000 +LoadOrderIndex = 117 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\ksthunk.sys" +Base name = "ksthunk.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88006f45000 +ImageSize = 487424 +Flags = 0x49104000 +LoadOrderIndex = 118 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\IntcDAud.sys" +Base name = "IntcDAud.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88006fbc000 +ImageSize = 110592 +Flags = 0x49104000 +LoadOrderIndex = 119 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\uaspstor.sys" +Base name = "uaspstor.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88006fd7000 +ImageSize = 8192 +Flags = 0x4d104000 +LoadOrderIndex = 120 +InitOrderIndex = 0 +LoadCount = 3 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\USBD.SYS" +Base name = "USBD.SYS" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88006fd9000 +ImageSize = 57344 +Flags = 0x49104000 +LoadOrderIndex = 121 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\hidusb.sys" +Base name = "hidusb.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88006fe7000 +ImageSize = 102400 +Flags = 0x4d104000 +LoadOrderIndex = 122 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\HIDCLASS.SYS" +Base name = "HIDCLASS.SYS" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88006e00000 +ImageSize = 36864 +Flags = 0x4d104000 +LoadOrderIndex = 123 +InitOrderIndex = 0 +LoadCount = 3 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\HIDPARSE.SYS" +Base name = "HIDPARSE.SYS" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff96000000000 +ImageSize = 3321856 +Flags = 0x69104000 +LoadOrderIndex = 124 +InitOrderIndex = 0 +LoadCount = 5 +OffsetToFileName= 21 +FullPathName = "\SystemRoot\System32\win32k.sys" +Base name = "win32k.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88006e09000 +ImageSize = 49152 +Flags = 0x4d104000 +LoadOrderIndex = 125 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\drivers\Dxapi.sys" +Base name = "Dxapi.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88006e15000 +ImageSize = 118784 +Flags = 0x49104000 +LoadOrderIndex = 126 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\usbccgp.sys" +Base name = "usbccgp.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88006e32000 +ImageSize = 57344 +Flags = 0x49104000 +LoadOrderIndex = 127 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\kbdhid.sys" +Base name = "kbdhid.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88006e40000 +ImageSize = 53248 +Flags = 0x49104000 +LoadOrderIndex = 128 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\mouhid.sys" +Base name = "mouhid.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88006e4d000 +ImageSize = 57344 +Flags = 0x49104000 +LoadOrderIndex = 129 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\monitor.sys" +Base name = "monitor.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88006e5b000 +ImageSize = 57344 +Flags = 0x49104000 +LoadOrderIndex = 130 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\Drivers\crashdmp.sys" +Base name = "crashdmp.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88006e69000 +ImageSize = 40960 +Flags = 0x49104000 +LoadOrderIndex = 131 +InitOrderIndex = 0 +LoadCount = 2 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\Drivers\dump_diskdump.sys" +Base name = "dump_diskdump.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88006e73000 +ImageSize = 94208 +Flags = 0x49104000 +LoadOrderIndex = 132 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\Drivers\dump_secnvme.sys" +Base name = "dump_secnvme.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88006e8a000 +ImageSize = 77824 +Flags = 0x49104020 +LoadOrderIndex = 133 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\Drivers\dump_dumpfve.sys" +Base name = "dump_dumpfve.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff96000430000 +ImageSize = 40960 +Flags = 0x69104000 +LoadOrderIndex = 134 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 21 +FullPathName = "\SystemRoot\System32\TSDDD.dll" +Base name = "TSDDD.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff960006c0000 +ImageSize = 159744 +Flags = 0x69104000 +LoadOrderIndex = 135 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 21 +FullPathName = "\SystemRoot\System32\cdd.dll" +Base name = "cdd.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88006e9d000 +ImageSize = 143360 +Flags = 0x49104000 +LoadOrderIndex = 136 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\luafv.sys" +Base name = "luafv.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88006ec0000 +ImageSize = 73728 +Flags = 0x49104000 +LoadOrderIndex = 137 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\vmnetbridge.sys" +Base name = "vmnetbridge.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88002c79000 +ImageSize = 86016 +Flags = 0x49104000 +LoadOrderIndex = 138 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\lltdio.sys" +Base name = "lltdio.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88002c8e000 +ImageSize = 98304 +Flags = 0x49104000 +LoadOrderIndex = 139 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\rspndr.sys" +Base name = "rspndr.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88006ed2000 +ImageSize = 45056 +Flags = 0x49104000 +LoadOrderIndex = 140 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\vmnetuserif.sys" +Base name = "vmnetuserif.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff880028d9000 +ImageSize = 823296 +Flags = 0x49104000 +LoadOrderIndex = 141 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\HTTP.sys" +Base name = "HTTP.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff880029a2000 +ImageSize = 122880 +Flags = 0x49104000 +LoadOrderIndex = 142 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\bowser.sys" +Base name = "bowser.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff880029c0000 +ImageSize = 98304 +Flags = 0x49104000 +LoadOrderIndex = 143 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\drivers\mpsdrv.sys" +Base name = "mpsdrv.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88002800000 +ImageSize = 188416 +Flags = 0x49104000 +LoadOrderIndex = 144 +InitOrderIndex = 0 +LoadCount = 3 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\mrxsmb.sys" +Base name = "mrxsmb.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff8800282e000 +ImageSize = 319488 +Flags = 0x49104000 +LoadOrderIndex = 145 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\mrxsmb10.sys" +Base name = "mrxsmb10.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff8800287c000 +ImageSize = 147456 +Flags = 0x49104000 +LoadOrderIndex = 146 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\mrxsmb20.sys" +Base name = "mrxsmb20.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff880028a0000 +ImageSize = 131072 +Flags = 0x49104000 +LoadOrderIndex = 147 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\vmx86.sys" +Base name = "vmx86.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff880028c0000 +ImageSize = 86016 +Flags = 0x49104000 +LoadOrderIndex = 148 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\hcmon.sys" +Base name = "hcmon.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff880029d8000 +ImageSize = 32768 +Flags = 0x49104000 +LoadOrderIndex = 149 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 27 +FullPathName = "\??\C:\Program Files\LGHUB\logi_core_temp.sys" +Base name = "logi_core_temp.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88002ac0000 +ImageSize = 696320 +Flags = 0x49104000 +LoadOrderIndex = 150 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\peauth.sys" +Base name = "peauth.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88002b6a000 +ImageSize = 200704 +Flags = 0x49104000 +LoadOrderIndex = 151 +InitOrderIndex = 0 +LoadCount = 3 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\DRIVERS\srvnet.sys" +Base name = "srvnet.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88002b9b000 +ImageSize = 73728 +Flags = 0x49104000 +LoadOrderIndex = 152 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\drivers\tcpipreg.sys" +Base name = "tcpipreg.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88002bad000 +ImageSize = 49152 +Flags = 0x49104020 +LoadOrderIndex = 153 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\SysWOW64\drivers\vstor2-x64.sys" +Base name = "vstor2-x64.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88002a00000 +ImageSize = 425984 +Flags = 0x49104000 +LoadOrderIndex = 154 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\DRIVERS\srv2.sys" +Base name = "srv2.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88003843000 +ImageSize = 618496 +Flags = 0x49104000 +LoadOrderIndex = 155 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\DRIVERS\srv.sys" +Base name = "srv.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff880038da000 +ImageSize = 188416 +Flags = 0x49104000 +LoadOrderIndex = 156 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\drivers\rdpdr.sys" +Base name = "rdpdr.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88003908000 +ImageSize = 45056 +Flags = 0x49104000 +LoadOrderIndex = 157 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\drivers\tdtcp.sys" +Base name = "tdtcp.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88003913000 +ImageSize = 65536 +Flags = 0x49104000 +LoadOrderIndex = 158 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\DRIVERS\tssecsrv.sys" +Base name = "tssecsrv.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff88003923000 +ImageSize = 237568 +Flags = 0x49104000 +LoadOrderIndex = 159 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\System32\Drivers\RDPWD.SYS" +Base name = "RDPWD.SYS" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff96000950000 +ImageSize = 409600 +Flags = 0x69104000 +LoadOrderIndex = 160 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 21 +FullPathName = "\SystemRoot\System32\ATMFD.DLL" +Base name = "ATMFD.DLL" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff880039ce000 +ImageSize = 45056 +Flags = 0x49104000 +LoadOrderIndex = 161 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\asyncmac.sys" +Base name = "asyncmac.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0xbaadf00dbaadf00d +ImageBase = 0xfffff8800395d000 +ImageSize = 348160 +Flags = 0x49104000 +LoadOrderIndex = 162 +InitOrderIndex = 0 +LoadCount = 1 +OffsetToFileName= 29 +FullPathName = "\SystemRoot\system32\DRIVERS\udfs.sys" +Base name = "udfs.sys" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x76e60000 +ImageSize = 1699840 +Flags = 0x0 +LoadOrderIndex = 163 +InitOrderIndex = 163 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\ntdll.dll" +Base name = "ntdll.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x47fe0000 +ImageSize = 131072 +Flags = 0x0 +LoadOrderIndex = 164 +InitOrderIndex = 164 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\smss.exe" +Base name = "smss.exe" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7feff160000 +ImageSize = 327680 +Flags = 0x0 +LoadOrderIndex = 165 +InitOrderIndex = 165 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\apisetschema.dll" +Base name = "apisetschema.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0xff9a0000 +ImageSize = 790528 +Flags = 0x0 +LoadOrderIndex = 166 +InitOrderIndex = 166 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\autochk.exe" +Base name = "autochk.exe" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7feff020000 +ImageSize = 1216512 +Flags = 0x0 +LoadOrderIndex = 167 +InitOrderIndex = 167 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\rpcrt4.dll" +Base name = "rpcrt4.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7feff000000 +ImageSize = 102400 +Flags = 0x0 +LoadOrderIndex = 168 +InitOrderIndex = 168 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\imagehlp.dll" +Base name = "imagehlp.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefefa0000 +ImageSize = 335872 +Flags = 0x0 +LoadOrderIndex = 169 +InitOrderIndex = 169 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\Wldap32.dll" +Base name = "Wldap32.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefef00000 +ImageSize = 618496 +Flags = 0x0 +LoadOrderIndex = 170 +InitOrderIndex = 170 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\comdlg32.dll" +Base name = "comdlg32.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefed70000 +ImageSize = 1613824 +Flags = 0x0 +LoadOrderIndex = 171 +InitOrderIndex = 171 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\urlmon.dll" +Base name = "urlmon.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefecf0000 +ImageSize = 524288 +Flags = 0x0 +LoadOrderIndex = 172 +InitOrderIndex = 172 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\difxapi.dll" +Base name = "difxapi.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x76d60000 +ImageSize = 1028096 +Flags = 0x0 +LoadOrderIndex = 173 +InitOrderIndex = 173 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\user32.dll" +Base name = "user32.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefecd0000 +ImageSize = 126976 +Flags = 0x0 +LoadOrderIndex = 174 +InitOrderIndex = 174 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\sechost.dll" +Base name = "sechost.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefec30000 +ImageSize = 651264 +Flags = 0x0 +LoadOrderIndex = 175 +InitOrderIndex = 175 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\msvcrt.dll" +Base name = "msvcrt.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefea50000 +ImageSize = 1929216 +Flags = 0x0 +LoadOrderIndex = 176 +InitOrderIndex = 176 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\setupapi.dll" +Base name = "setupapi.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x77010000 +ImageSize = 28672 +Flags = 0x0 +LoadOrderIndex = 177 +InitOrderIndex = 177 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\psapi.dll" +Base name = "psapi.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefe970000 +ImageSize = 901120 +Flags = 0x0 +LoadOrderIndex = 178 +InitOrderIndex = 178 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\oleaut32.dll" +Base name = "oleaut32.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefe4c0000 +ImageSize = 4898816 +Flags = 0x0 +LoadOrderIndex = 179 +InitOrderIndex = 179 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\wininet.dll" +Base name = "wininet.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefe420000 +ImageSize = 626688 +Flags = 0x0 +LoadOrderIndex = 180 +InitOrderIndex = 180 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\clbcatq.dll" +Base name = "clbcatq.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefd690000 +ImageSize = 14204928 +Flags = 0x0 +LoadOrderIndex = 181 +InitOrderIndex = 181 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\shell32.dll" +Base name = "shell32.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefd620000 +ImageSize = 430080 +Flags = 0x0 +LoadOrderIndex = 182 +InitOrderIndex = 182 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\gdi32.dll" +Base name = "gdi32.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefd540000 +ImageSize = 913408 +Flags = 0x0 +LoadOrderIndex = 183 +InitOrderIndex = 183 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\advapi32.dll" +Base name = "advapi32.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefd510000 +ImageSize = 188416 +Flags = 0x0 +LoadOrderIndex = 184 +InitOrderIndex = 184 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\imm32.dll" +Base name = "imm32.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefd490000 +ImageSize = 462848 +Flags = 0x0 +LoadOrderIndex = 185 +InitOrderIndex = 185 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\shlwapi.dll" +Base name = "shlwapi.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x77000000 +ImageSize = 12288 +Flags = 0x0 +LoadOrderIndex = 186 +InitOrderIndex = 186 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\normaliz.dll" +Base name = "normaliz.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefd1c0000 +ImageSize = 2940928 +Flags = 0x0 +LoadOrderIndex = 187 +InitOrderIndex = 187 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\iertutil.dll" +Base name = "iertutil.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefcfc0000 +ImageSize = 2097152 +Flags = 0x0 +LoadOrderIndex = 188 +InitOrderIndex = 188 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\ole32.dll" +Base name = "ole32.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefcf70000 +ImageSize = 315392 +Flags = 0x0 +LoadOrderIndex = 189 +InitOrderIndex = 189 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\ws2_32.dll" +Base name = "ws2_32.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x76c40000 +ImageSize = 1175552 +Flags = 0x0 +LoadOrderIndex = 190 +InitOrderIndex = 190 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\kernel32.dll" +Base name = "kernel32.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefcea0000 +ImageSize = 831488 +Flags = 0x0 +LoadOrderIndex = 191 +InitOrderIndex = 191 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\usp10.dll" +Base name = "usp10.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefcd90000 +ImageSize = 1093632 +Flags = 0x0 +LoadOrderIndex = 192 +InitOrderIndex = 192 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\msctf.dll" +Base name = "msctf.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefcd80000 +ImageSize = 57344 +Flags = 0x0 +LoadOrderIndex = 193 +InitOrderIndex = 193 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\lpk.dll" +Base name = "lpk.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefcd70000 +ImageSize = 32768 +Flags = 0x0 +LoadOrderIndex = 194 +InitOrderIndex = 194 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\nsi.dll" +Base name = "nsi.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefcd60000 +ImageSize = 16384 +Flags = 0x0 +LoadOrderIndex = 195 +InitOrderIndex = 195 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\api-ms-win-downlevel-version-l1-1-0.dll" +Base name = "api-ms-win-downlevel-version-l1-1-0.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefcd50000 +ImageSize = 20480 +Flags = 0x0 +LoadOrderIndex = 196 +InitOrderIndex = 196 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\api-ms-win-downlevel-advapi32-l1-1-0.dll" +Base name = "api-ms-win-downlevel-advapi32-l1-1-0.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefcd10000 +ImageSize = 221184 +Flags = 0x0 +LoadOrderIndex = 197 +InitOrderIndex = 197 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\cfgmgr32.dll" +Base name = "cfgmgr32.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefccf0000 +ImageSize = 131072 +Flags = 0x0 +LoadOrderIndex = 198 +InitOrderIndex = 198 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\userenv.dll" +Base name = "userenv.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefcce0000 +ImageSize = 16384 +Flags = 0x0 +LoadOrderIndex = 199 +InitOrderIndex = 199 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\api-ms-win-downlevel-shlwapi-l1-1-0.dll" +Base name = "api-ms-win-downlevel-shlwapi-l1-1-0.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefccd0000 +ImageSize = 12288 +Flags = 0x0 +LoadOrderIndex = 200 +InitOrderIndex = 200 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\api-ms-win-downlevel-normaliz-l1-1-0.dll" +Base name = "api-ms-win-downlevel-normaliz-l1-1-0.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefcc30000 +ImageSize = 655360 +Flags = 0x0 +LoadOrderIndex = 201 +InitOrderIndex = 201 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\comctl32.dll" +Base name = "comctl32.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefcc10000 +ImageSize = 94208 +Flags = 0x0 +LoadOrderIndex = 202 +InitOrderIndex = 202 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\netapi32.dll" +Base name = "netapi32.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefcc00000 +ImageSize = 16384 +Flags = 0x0 +LoadOrderIndex = 203 +InitOrderIndex = 203 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\api-ms-win-downlevel-shell32-l1-1-0.dll" +Base name = "api-ms-win-downlevel-shell32-l1-1-0.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefcbf0000 +ImageSize = 16384 +Flags = 0x0 +LoadOrderIndex = 204 +InitOrderIndex = 204 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\api-ms-win-downlevel-ole32-l1-1-0.dll" +Base name = "api-ms-win-downlevel-ole32-l1-1-0.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefcb80000 +ImageSize = 421888 +Flags = 0x0 +LoadOrderIndex = 205 +InitOrderIndex = 205 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\KernelBase.dll" +Base name = "KernelBase.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefcb60000 +ImageSize = 106496 +Flags = 0x0 +LoadOrderIndex = 206 +InitOrderIndex = 206 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\devobj.dll" +Base name = "devobj.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefcb50000 +ImageSize = 16384 +Flags = 0x0 +LoadOrderIndex = 207 +InitOrderIndex = 207 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\api-ms-win-downlevel-user32-l1-1-0.dll" +Base name = "api-ms-win-downlevel-user32-l1-1-0.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefcb10000 +ImageSize = 245760 +Flags = 0x0 +LoadOrderIndex = 208 +InitOrderIndex = 208 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\wintrust.dll" +Base name = "wintrust.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefc910000 +ImageSize = 2039808 +Flags = 0x0 +LoadOrderIndex = 209 +InitOrderIndex = 209 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\crypt32.dll" +Base name = "crypt32.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefc8e0000 +ImageSize = 143360 +Flags = 0x0 +LoadOrderIndex = 210 +InitOrderIndex = 210 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\srvcli.dll" +Base name = "srvcli.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefc8d0000 +ImageSize = 61440 +Flags = 0x0 +LoadOrderIndex = 211 +InitOrderIndex = 211 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\profapi.dll" +Base name = "profapi.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefc8c0000 +ImageSize = 49152 +Flags = 0x0 +LoadOrderIndex = 212 +InitOrderIndex = 212 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\netutils.dll" +Base name = "netutils.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefc8b0000 +ImageSize = 61440 +Flags = 0x0 +LoadOrderIndex = 213 +InitOrderIndex = 213 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\msasn1.dll" +Base name = "msasn1.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefc890000 +ImageSize = 98304 +Flags = 0x0 +LoadOrderIndex = 214 +InitOrderIndex = 214 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\wkscli.dll" +Base name = "wkscli.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x7fefc860000 +ImageSize = 139264 +Flags = 0x0 +LoadOrderIndex = 215 +InitOrderIndex = 215 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\System32\bcrypt.dll" +Base name = "bcrypt.dll" + +=== MODULE === +Section = 0xbaadf00dbaadf00d +MappedBase = 0x0 +ImageBase = 0x75160000 +ImageSize = 12288 +Flags = 0x0 +LoadOrderIndex = 216 +InitOrderIndex = 216 +LoadCount = 1 +OffsetToFileName= 18 +FullPathName = "\Windows\SysWOW64\normaliz.dll" +Base name = "normaliz.dll" diff --git a/00-Documentation/Source File Header.txt b/00-Documentation/Source File Header.txt new file mode 100644 index 0000000..9c5c307 --- /dev/null +++ b/00-Documentation/Source File Header.txt @@ -0,0 +1,26 @@ +Copypaste this at the top of new source code files. + + +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// file.ext +// +// Abstract: +// +// FILL OUT THIS TEXT +// +// Author: +// +// Author (DD-MMM-YYYY) +// +// Environment: +// +// WHERE CAN THIS PROGRAM/LIBRARY/CODE RUN? +// +// Revision History: +// +// Author DD-MMM-YYYY Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/00-Documentation/VxKex Registry Keys (Legacy).txt b/00-Documentation/VxKex Registry Keys (Legacy).txt new file mode 100644 index 0000000..229eadc --- /dev/null +++ b/00-Documentation/VxKex Registry Keys (Legacy).txt @@ -0,0 +1,20 @@ +Legacy versions of VxKex (0.0.0.3 and prior) used the registry in the following manner: + +HKLM\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options (key) + (key) + Debugger (REG_SZ) + This string would contain "VxKexLdr.exe" somewhere in it. + +HKLM\Software\VXsoft\VxKexLdr (key) + InstalledVersion (REG_DWORD) + KexDir (REG_SZ) + +HKCU\Software\VXsoft\VxKexLdr (key) + Image File Execution Options (key) + + +In order to remove traces of legacy VxKex from the registry, delete the following keys: + + HKLM\Software\VXsoft\VxKexLdr + HKCU\Software\VXsoft\VxKexLdr + Any IFEO key that contains a "Debugger" value that has VxKexLdr.exe in it \ No newline at end of file diff --git a/00-Documentation/VxKex Registry Keys.docx b/00-Documentation/VxKex Registry Keys.docx new file mode 100644 index 0000000..7acb706 Binary files /dev/null and b/00-Documentation/VxKex Registry Keys.docx differ diff --git a/00-Documentation/~$Kex Registry Keys.docx b/00-Documentation/~$Kex Registry Keys.docx new file mode 100644 index 0000000..c31a6a7 Binary files /dev/null and b/00-Documentation/~$Kex Registry Keys.docx differ diff --git a/00-Import Libraries/cfgmgr32_x64.lib b/00-Import Libraries/cfgmgr32_x64.lib new file mode 100644 index 0000000..08b2730 Binary files /dev/null and b/00-Import Libraries/cfgmgr32_x64.lib differ diff --git a/00-Import Libraries/cfgmgr32_x86.lib b/00-Import Libraries/cfgmgr32_x86.lib new file mode 100644 index 0000000..193cf5b Binary files /dev/null and b/00-Import Libraries/cfgmgr32_x86.lib differ diff --git a/00-Import Libraries/dxgi_x64.lib b/00-Import Libraries/dxgi_x64.lib new file mode 100644 index 0000000..7f6165b Binary files /dev/null and b/00-Import Libraries/dxgi_x64.lib differ diff --git a/00-Import Libraries/dxgi_x86.lib b/00-Import Libraries/dxgi_x86.lib new file mode 100644 index 0000000..a9715e3 Binary files /dev/null and b/00-Import Libraries/dxgi_x86.lib differ diff --git a/00-Import Libraries/kernel32_x64.lib b/00-Import Libraries/kernel32_x64.lib new file mode 100644 index 0000000..dffc136 Binary files /dev/null and b/00-Import Libraries/kernel32_x64.lib differ diff --git a/00-Import Libraries/kernel32_x86.lib b/00-Import Libraries/kernel32_x86.lib new file mode 100644 index 0000000..42ea90f Binary files /dev/null and b/00-Import Libraries/kernel32_x86.lib differ diff --git a/00-Import Libraries/kernelbase_x64.lib b/00-Import Libraries/kernelbase_x64.lib new file mode 100644 index 0000000..aaa0f06 Binary files /dev/null and b/00-Import Libraries/kernelbase_x64.lib differ diff --git a/00-Import Libraries/kernelbase_x86.lib b/00-Import Libraries/kernelbase_x86.lib new file mode 100644 index 0000000..2335bef Binary files /dev/null and b/00-Import Libraries/kernelbase_x86.lib differ diff --git a/00-Import Libraries/msvcrt_x64.lib b/00-Import Libraries/msvcrt_x64.lib new file mode 100644 index 0000000..9799670 Binary files /dev/null and b/00-Import Libraries/msvcrt_x64.lib differ diff --git a/00-Import Libraries/msvcrt_x86.lib b/00-Import Libraries/msvcrt_x86.lib new file mode 100644 index 0000000..06e12cb Binary files /dev/null and b/00-Import Libraries/msvcrt_x86.lib differ diff --git a/00-Import Libraries/ntdll_x64.lib b/00-Import Libraries/ntdll_x64.lib new file mode 100644 index 0000000..288a015 Binary files /dev/null and b/00-Import Libraries/ntdll_x64.lib differ diff --git a/00-Import Libraries/ntdll_x86.lib b/00-Import Libraries/ntdll_x86.lib new file mode 100644 index 0000000..b0921fb Binary files /dev/null and b/00-Import Libraries/ntdll_x86.lib differ diff --git a/00-Import Libraries/ntoskrnl_x64.lib b/00-Import Libraries/ntoskrnl_x64.lib new file mode 100644 index 0000000..0b7879b Binary files /dev/null and b/00-Import Libraries/ntoskrnl_x64.lib differ diff --git a/00-Import Libraries/ntoskrnl_x86.lib b/00-Import Libraries/ntoskrnl_x86.lib new file mode 100644 index 0000000..3b5d25a Binary files /dev/null and b/00-Import Libraries/ntoskrnl_x86.lib differ diff --git a/00-Import Libraries/ntstrsafe_x64.lib b/00-Import Libraries/ntstrsafe_x64.lib new file mode 100644 index 0000000..be0d6ab Binary files /dev/null and b/00-Import Libraries/ntstrsafe_x64.lib differ diff --git a/00-Import Libraries/ntstrsafe_x86.lib b/00-Import Libraries/ntstrsafe_x86.lib new file mode 100644 index 0000000..25e3522 Binary files /dev/null and b/00-Import Libraries/ntstrsafe_x86.lib differ diff --git a/00-Import Libraries/seh32.lib b/00-Import Libraries/seh32.lib new file mode 100644 index 0000000..6ee471b Binary files /dev/null and b/00-Import Libraries/seh32.lib differ diff --git a/00-Import Libraries/user32_x64.lib b/00-Import Libraries/user32_x64.lib new file mode 100644 index 0000000..a59c7f1 Binary files /dev/null and b/00-Import Libraries/user32_x64.lib differ diff --git a/00-Import Libraries/user32_x86.lib b/00-Import Libraries/user32_x86.lib new file mode 100644 index 0000000..f9fb37d Binary files /dev/null and b/00-Import Libraries/user32_x86.lib differ diff --git a/01-Development Utilities/7zSfx/7zS2.sfx b/01-Development Utilities/7zSfx/7zS2.sfx new file mode 100644 index 0000000..bfd8158 Binary files /dev/null and b/01-Development Utilities/7zSfx/7zS2.sfx differ diff --git a/01-Development Utilities/7zSfx/7zS2_original.sfx b/01-Development Utilities/7zSfx/7zS2_original.sfx new file mode 100644 index 0000000..4a96dde Binary files /dev/null and b/01-Development Utilities/7zSfx/7zS2_original.sfx differ diff --git a/01-Development Utilities/7zSfx/7zr.exe b/01-Development Utilities/7zSfx/7zr.exe new file mode 100644 index 0000000..fd74f63 Binary files /dev/null and b/01-Development Utilities/7zSfx/7zr.exe differ diff --git a/01-Development Utilities/7zSfx/makesfx.bat b/01-Development Utilities/7zSfx/makesfx.bat new file mode 100644 index 0000000..2522e15 --- /dev/null +++ b/01-Development Utilities/7zSfx/makesfx.bat @@ -0,0 +1,175 @@ +@echo off +cd /D "%~dp0" + +del Archive.7z >nul 2>nul +rd /s /q Archive >nul 2>nul + +if /i "%1"=="/RELEASE" ( + SET DBGREL=Release +) ELSE ( + SET DBGREL=Debug +) + +md Archive +md Archive\Core +md Archive\Core32 +md Archive\Core64 +md Archive\Kex32 +md Archive\Kex64 + +REM +REM Bitness Agnostic Data +REM + +copy ..\..\%DBGREL%\KexSetup.exe Archive\ >nul + +copy "..\..\00-Documentation\Application Compatibility List.docx" Archive\Core\ >nul +copy "..\..\00-Documentation\Changelog.txt" Archive\Core\ >nul + +REM +REM 32-bit Core +REM + +copy ..\..\%DBGREL%\KexDll.dll Archive\Core32\ >nul +copy ..\..\%DBGREL%\KexShlEx.dll Archive\Core32\ >nul +copy ..\..\%DBGREL%\KexCfg.exe Archive\Core32\ >nul +copy ..\..\%DBGREL%\VxlView.exe Archive\Core32\ >nul +copy ..\..\%DBGREL%\CpiwBypa.dll Archive\Core32\ >nul +copy ..\..\%DBGREL%\VxKexLdr.exe Archive\Core32\ >nul + +REM +REM 32-bit Extension +REM + +copy ..\..\%DBGREL%\KxAdvapi.dll Archive\Kex32\ >nul +copy ..\..\%DBGREL%\KxBase.dll Archive\Kex32\ >nul +copy ..\..\%DBGREL%\KxCom.dll Archive\Kex32\ >nul +copy ..\..\%DBGREL%\KxCrt.dll Archive\Kex32\ >nul +copy ..\..\%DBGREL%\KxCryp.dll Archive\Kex32\ >nul +copy ..\..\%DBGREL%\KxDx.dll Archive\Kex32\ >nul +copy ..\..\%DBGREL%\KxMi.dll Archive\Kex32\ >nul +copy ..\..\%DBGREL%\KxNet.dll Archive\Kex32\ >nul +copy ..\..\%DBGREL%\KxNt.dll Archive\Kex32\ >nul +copy ..\..\%DBGREL%\KxUser.dll Archive\Kex32\ >nul + +REM +REM 64-bit Core +REM + +copy ..\..\x64\%DBGREL%\KexDll.dll Archive\Core64\ >nul +copy ..\..\x64\%DBGREL%\KexShlEx.dll Archive\Core64\ >nul +copy ..\..\x64\%DBGREL%\KexCfg.exe Archive\Core64\ >nul +copy ..\..\x64\%DBGREL%\VxlView.exe Archive\Core64\ >nul +copy ..\..\x64\%DBGREL%\CpiwBypa.dll Archive\Core64\ >nul +copy ..\..\x64\%DBGREL%\VxKexLdr.exe Archive\Core64\ >nul + +REM +REM 64-bit Extension +REM + +copy ..\..\x64\%DBGREL%\KxAdvapi.dll Archive\Kex64\ >nul +copy ..\..\x64\%DBGREL%\KxBase.dll Archive\Kex64\ >nul +copy ..\..\x64\%DBGREL%\KxCom.dll Archive\Kex64\ >nul +copy ..\..\x64\%DBGREL%\KxCrt.dll Archive\Kex64\ >nul +copy ..\..\x64\%DBGREL%\KxCryp.dll Archive\Kex64\ >nul +copy ..\..\x64\%DBGREL%\KxDx.dll Archive\Kex64\ >nul +copy ..\..\x64\%DBGREL%\KxMi.dll Archive\Kex64\ >nul +copy ..\..\x64\%DBGREL%\KxNet.dll Archive\Kex64\ >nul +copy ..\..\x64\%DBGREL%\KxNt.dll Archive\Kex64\ >nul +copy ..\..\x64\%DBGREL%\KxUser.dll Archive\Kex64\ >nul + +REM +REM Prebuilt DLLs +REM + +copy "..\..\02-Prebuilt DLLs\x86\*.dll" Archive\Kex32\ >nul +copy "..\..\02-Prebuilt DLLs\x64\*.dll" Archive\Kex64\ >nul + +if %DBGREL%==Debug ( + REM Include PDBs as well + + copy ..\..\%DBGREL%\KexSetup.pdb Archive\ >nul + + copy ..\..\%DBGREL%\KexDll.pdb Archive\Core32\ >nul + copy ..\..\%DBGREL%\KexShlEx.pdb Archive\Core32\ >nul + copy ..\..\%DBGREL%\KexCfg.pdb Archive\Core32\ >nul + copy ..\..\%DBGREL%\VxlView.pdb Archive\Core32\ >nul + copy ..\..\%DBGREL%\CpiwBypa.pdb Archive\Core32\ >nul + copy ..\..\%DBGREL%\VxKexLdr.pdb Archive\Core32\ >nul + + copy ..\..\%DBGREL%\KxAdvapi.pdb Archive\Kex32\ >nul + copy ..\..\%DBGREL%\KxBase.pdb Archive\Kex32\ >nul + copy ..\..\%DBGREL%\KxCom.pdb Archive\Kex32\ >nul + copy ..\..\%DBGREL%\KxCrt.pdb Archive\Kex32\ >nul + copy ..\..\%DBGREL%\KxCryp.pdb Archive\Kex32\ >nul + copy ..\..\%DBGREL%\KxDx.pdb Archive\Kex32\ >nul + copy ..\..\%DBGREL%\KxMi.pdb Archive\Kex32\ >nul + copy ..\..\%DBGREL%\KxNet.pdb Archive\Kex32\ >nul + copy ..\..\%DBGREL%\KxNt.pdb Archive\Kex32\ >nul + copy ..\..\%DBGREL%\KxUser.pdb Archive\Kex32\ >nul + + copy ..\..\x64\%DBGREL%\KexDll.pdb Archive\Core64\ >nul + copy ..\..\x64\%DBGREL%\KexShlEx.pdb Archive\Core64\ >nul + copy ..\..\x64\%DBGREL%\KexCfg.pdb Archive\Core64\ >nul + copy ..\..\x64\%DBGREL%\VxlView.pdb Archive\Core64\ >nul + copy ..\..\x64\%DBGREL%\CpiwBypa.pdb Archive\Core64\ >nul + copy ..\..\x64\%DBGREL%\VxKexLdr.pdb Archive\Core64\ >nul + + copy ..\..\x64\%DBGREL%\KxAdvapi.pdb Archive\Kex64\ >nul + copy ..\..\x64\%DBGREL%\KxBase.pdb Archive\Kex64\ >nul + copy ..\..\x64\%DBGREL%\KxCom.pdb Archive\Kex64\ >nul + copy ..\..\x64\%DBGREL%\KxCrt.pdb Archive\Kex64\ >nul + copy ..\..\x64\%DBGREL%\KxCryp.pdb Archive\Kex64\ >nul + copy ..\..\x64\%DBGREL%\KxDx.pdb Archive\Kex64\ >nul + copy ..\..\x64\%DBGREL%\KxMi.pdb Archive\Kex64\ >nul + copy ..\..\x64\%DBGREL%\KxNet.pdb Archive\Kex64\ >nul + copy ..\..\x64\%DBGREL%\KxNt.pdb Archive\Kex64\ >nul + copy ..\..\x64\%DBGREL%\KxUser.pdb Archive\Kex64\ >nul + + copy "..\..\02-Prebuilt DLLs\x86\*.pdb" Archive\Kex32\ >nul + copy "..\..\02-Prebuilt DLLs\x64\*.pdb" Archive\Kex64\ >nul +) + +copy /y 7zS2.sfx ..\..\KexSetup_%DBGREL%.exe >nul + + +REM vtrplnt copies the version resources from the original kexsetup into +REM the packed SFX version. +REM It has to be run now because otherwise it will clobber the appended +REM 7zip data. + +vtrplnt.exe /%DBGREL% + +REM =========================================================================== +REM FOR FINAL RELEASE: switch to the upper command for higher compression +REM =========================================================================== + +7zr a -y Archive.7z .\Archive\* -mmt1 -mx9 -m0=LZMA:d32 +REM 7zr a -y Archive.7z .\Archive\* -mmt1 -mx1 -m0=LZMA:d32 + +if %errorlevel% neq 0 ( + pause + exit %errorlevel% +) + +rd /s /q Archive + +copy /b ..\..\KexSetup_%DBGREL%.exe + Archive.7z "..\..\KexSetup_%DBGREL%.exe" >nul + +if %errorlevel% neq 0 ( + pause + exit %errorlevel% +) + +del Archive.7z + +REM Now auto-increment the build number, but only for debug builds. + +if %DBGREL%==Debug ( +REM "..\..\01-Development Utilities\vautogen\vautogen.exe" + + if %errorlevel% neq 0 ( + pause + exit %errorlevel% + ) +) \ No newline at end of file diff --git a/01-Development Utilities/7zSfx/vtrplnt.exe b/01-Development Utilities/7zSfx/vtrplnt.exe new file mode 100644 index 0000000..306f449 Binary files /dev/null and b/01-Development Utilities/7zSfx/vtrplnt.exe differ diff --git a/01-Development Utilities/7zSfx/vtrplnt.pdb b/01-Development Utilities/7zSfx/vtrplnt.pdb new file mode 100644 index 0000000..35f1993 Binary files /dev/null and b/01-Development Utilities/7zSfx/vtrplnt.pdb differ diff --git a/01-Development Utilities/KexExprt/KexExprt.rc b/01-Development Utilities/KexExprt/KexExprt.rc new file mode 100644 index 0000000..fcd999e Binary files /dev/null and b/01-Development Utilities/KexExprt/KexExprt.rc differ diff --git a/01-Development Utilities/KexExprt/KexExprt.vcxproj b/01-Development Utilities/KexExprt/KexExprt.vcxproj new file mode 100644 index 0000000..e199a3b --- /dev/null +++ b/01-Development Utilities/KexExprt/KexExprt.vcxproj @@ -0,0 +1,112 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + + {FEC92998-8D28-42CE-886D-21D17A263D24} + Win32Proj + KexExprt + + + + Application + true + Unicode + + + Application + true + Unicode + + + + + + + + + + + + + false + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + false + $(SolutionDir)\00-Common Headers + true + ProgramDatabase + true + false + Default + + + Windows + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + + + $(SolutionDir)\00-Common Headers + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + false + $(SolutionDir)\00-Common Headers + true + ProgramDatabase + true + false + Default + + + Windows + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + + + $(SolutionDir)\00-Common Headers + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/01-Development Utilities/KexExprt/KexExprt.vcxproj.filters b/01-Development Utilities/KexExprt/KexExprt.vcxproj.filters new file mode 100644 index 0000000..d0635db --- /dev/null +++ b/01-Development Utilities/KexExprt/KexExprt.vcxproj.filters @@ -0,0 +1,41 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/01-Development Utilities/KexExprt/KexExprt.vcxproj.user b/01-Development Utilities/KexExprt/KexExprt.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/01-Development Utilities/KexExprt/KexExprt.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/01-Development Utilities/KexExprt/buildcfg.h b/01-Development Utilities/KexExprt/buildcfg.h new file mode 100644 index 0000000..919d273 --- /dev/null +++ b/01-Development Utilities/KexExprt/buildcfg.h @@ -0,0 +1,3 @@ +#define KEX_ENV_WIN32 +#define KEX_TARGET_TYPE_EXE +#define KEX_COMPONENT L"KexExprt" diff --git a/01-Development Utilities/KexExprt/dump.c b/01-Development Utilities/KexExprt/dump.c new file mode 100644 index 0000000..e9f0f37 --- /dev/null +++ b/01-Development Utilities/KexExprt/dump.c @@ -0,0 +1,262 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// dump.c +// +// Abstract: +// +// Main code that is run when the user clicks "Generate" +// +// Author: +// +// vxiiduu (29-Oct-2022) +// +// Revision History: +// +// vxiiduu 29-Oct-2022 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include +#include "resource.h" +#include "kexexprt.h" + +LARGE_UNICODE_STRING Output; + +STATIC VOID AppendToOutput( + IN PCWSTR Format, + IN ...) +{ + HRESULT Result; + ARGLIST ArgList; + SIZE_T TextCch; + PWSTR Text; + + va_start(ArgList, Format); + + Result = StringCchVPrintfBufferLength(&TextCch, Format, ArgList); + if (FAILED(Result)) { + return; + } + + Text = StackAlloc(WCHAR, TextCch); + Result = StringCchVPrintf(Text, TextCch, Format, ArgList); + + if (FAILED(Result)) { + return; + } + + if (!Output.Buffer) { + Output.MaxCch = 1024; + Output.Buffer = SafeAlloc(WCHAR, Output.MaxCch); + Output.Cch = 0; + } + + if (Output.Cch + TextCch > Output.MaxCch) { + Output.MaxCch *= 2; + Output.Buffer = SafeReAlloc(Output.Buffer, WCHAR, Output.MaxCch); + } + + if (!Output.Buffer) { + return; + } + + RtlCopyMemory(Output.Buffer + Output.Cch, Text, TextCch * sizeof(WCHAR)); + Output.Cch += (ULONG) TextCch - 1; +} + +VOID DumpExports( + IN HWND MainWindow, + IN PCWSTR DllPathCString, + IN KEXEXPRT_GENERATE_STYLE Style, + IN BOOLEAN IncludeOrdinals) +{ + BOOLEAN Success; + NTSTATUS Status; + + UNICODE_STRING FilePath; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + HANDLE FileHandle; + HANDLE SectionHandle; + + UNICODE_STRING DllBaseName; + UNICODE_STRING DotDll; + PVOID DllBase; + SIZE_T DllSize; + PIMAGE_EXPORT_DIRECTORY ExportDirectory; + ULONG ImportDescriptorSize; + PDWORD NameRvas; + PUSHORT NameOrdinals; + PBOOLEAN OrdinalHasName; + ULONG Index; + + DllBase = NULL; + DllSize = 0; + FileHandle = NULL; + SectionHandle = NULL; + + Success = RtlDosPathNameToRelativeNtPathName_U( + DllPathCString, + &FilePath, + NULL, + NULL); + + if (!Success) { + ErrorBoxF(L"Failed to convert the input file name from DOS to NT."); + return; + } + + InitializeObjectAttributes(&ObjectAttributes, &FilePath, OBJ_CASE_INSENSITIVE, NULL, NULL); + + Status = NtOpenFile( + &FileHandle, + FILE_GENERIC_READ, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ, + FILE_SYNCHRONOUS_IO_NONALERT); + + if (!NT_SUCCESS(Status)) { + ErrorBoxF(L"Failed to open the specified DLL file \"%wZ\": 0x%08lx: %s", + &FilePath, Status, KexRtlNtStatusToString(Status)); + goto Exit; + } + + Status = NtCreateSection( + &SectionHandle, + SECTION_MAP_READ, + NULL, + 0, + PAGE_READONLY, + SEC_IMAGE, + FileHandle); + + if (!NT_SUCCESS(Status)) { + ErrorBoxF(L"Failed to create section: 0x%08lx: %s", + Status, KexRtlNtStatusToString(Status)); + goto Exit; + } + + Status = NtMapViewOfSection( + SectionHandle, + NtCurrentProcess(), + &DllBase, + 0, + 0, + NULL, + &DllSize, + ViewUnmap, + 0, + PAGE_READONLY); + + if (!NT_SUCCESS(Status)) { + ErrorBoxF(L"Failed to map DLL: 0x%08lx: %s", + Status, KexRtlNtStatusToString(Status)); + goto Exit; + } + + ExportDirectory = (PIMAGE_EXPORT_DIRECTORY) RtlImageDirectoryEntryToData( + DllBase, + TRUE, + IMAGE_DIRECTORY_ENTRY_EXPORT, + &ImportDescriptorSize); + + KexRtlPathFindFileName(&FilePath, &DllBaseName); + NameRvas = (PDWORD) RVA_TO_VA(DllBase, ExportDirectory->AddressOfNames); + NameOrdinals = (PUSHORT) RVA_TO_VA(DllBase, ExportDirectory->AddressOfNameOrdinals); + OrdinalHasName = StackAlloc(BOOLEAN, ExportDirectory->NumberOfFunctions); + RtlZeroMemory(OrdinalHasName, ExportDirectory->NumberOfFunctions * sizeof(BOOLEAN)); + + RtlZeroMemory(&Output, sizeof(Output)); + + switch (Style) { + case GenerateStyleDef: + AppendToOutput(L";; Generated by KexExprt from \"%s\"\r\n", DllPathCString); + AppendToOutput(L"LIBRARY %wZ\r\n", &DllBaseName); + AppendToOutput(L"EXPORTS\r\n"); + break; + case GenerateStylePragma: + AppendToOutput(L"// Generated by KexExprt from \"%s\"\r\n", DllPathCString); + break; + default: + NOT_REACHED; + } + + RtlInitConstantUnicodeString(&DotDll, L".dll"); + + if (KexRtlUnicodeStringEndsWith(&DllBaseName, &DotDll, TRUE)) { + DllBaseName.Length -= 4 * sizeof(WCHAR); + DllBaseName.Buffer[DllBaseName.Length / sizeof(WCHAR)] = '\0'; + } + + for (Index = 0; Index < ExportDirectory->NumberOfNames; ++Index) { + PCSTR FunctionName; + ULONG Ordinal; + + Ordinal = NameOrdinals[Index] + ExportDirectory->Base; + FunctionName = (PCSTR) RVA_TO_VA(DllBase, NameRvas[Index]); + OrdinalHasName[NameOrdinals[Index]] = TRUE; + + switch (Style) { + case GenerateStyleDef: + if (IncludeOrdinals) { + AppendToOutput( + L"\t%hs = %wZ.%hs @%lu\r\n", + FunctionName, &DllBaseName, FunctionName, Ordinal); + } else { + AppendToOutput( + L"\t%hs = %wZ.%hs\r\n", + FunctionName, &DllBaseName, FunctionName); + } + break; + case GenerateStylePragma: + if (IncludeOrdinals) { + AppendToOutput( + L"#pragma comment(linker, \"/EXPORT:%hs=%wZ.%hs,@%lu\")\r\n", + FunctionName, &DllBaseName, FunctionName, Ordinal); + } else { + AppendToOutput( + L"#pragma comment(linker, \"/EXPORT:%hs=%wZ.%hs\")\r\n", + FunctionName, &DllBaseName, FunctionName); + } + break; + default: + NOT_REACHED; + } + } + + for (Index = 0; Index < ExportDirectory->NumberOfFunctions; ++Index) { + ULONG Ordinal; + + Ordinal = Index + ExportDirectory->Base; + + if (!OrdinalHasName[Index]) { + switch (Style) { + case GenerateStyleDef: + AppendToOutput(L"\t__OrdinalFunction%lu = %wZ.#%lu @%lu NONAME\r\n", Ordinal, &DllBaseName, Ordinal, Ordinal); + break; + case GenerateStylePragma: + AppendToOutput(L"#pragma comment(linker, \"/EXPORT:__OrdinalFunction%lu=%wZ.#%lu,@%lu,NONAME\")\r\n", Ordinal, &DllBaseName, Ordinal, Ordinal); + break; + default: + NOT_REACHED; + } + } + } + + SetDlgItemText(MainWindow, IDC_RESULT, Output.Buffer); + +Exit: + SafeFree(Output.Buffer); + SafeFree(FilePath.Buffer); + + if (DllBase) { + NtUnmapViewOfSection(NtCurrentProcess(), DllBase); + } + + SafeClose(FileHandle); + SafeClose(SectionHandle); +} \ No newline at end of file diff --git a/01-Development Utilities/KexExprt/kexexprt.c b/01-Development Utilities/KexExprt/kexexprt.c new file mode 100644 index 0000000..9aa995b --- /dev/null +++ b/01-Development Utilities/KexExprt/kexexprt.c @@ -0,0 +1,198 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// kexexprt.c +// +// Abstract: +// +// DLL export dumper for creating .def files or #pragma directives. +// The differences from the utility of the same name in previous versions +// of VxKex include: +// - minor GUI enhancements +// - ability to operate on DLL files of any bitness, no matter the bitness +// of the tool +// +// Author: +// +// vxiiduu (29-Oct-2022) +// +// Revision History: +// +// vxiiduu 29-Oct-2022 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include +#include "kexexprt.h" +#include "resource.h" + +VOID EntryPoint( + VOID) +{ + HWND MainWindow; + HACCEL Accelerators; + MSG Message; + + KexgApplicationFriendlyName = L"DLL Export Dumper"; + + Accelerators = LoadAccelerators(NULL, MAKEINTRESOURCE(IDA_ACCELERATORS)); + MainWindow = CreateDialog(NULL, MAKEINTRESOURCE(IDD_MAINWND), NULL, MainWndProc); + + while (GetMessage(&Message, NULL, 0, 0)) { + if (TranslateAccelerator(MainWindow, Accelerators, &Message)) { + continue; + } + + if (!IsDialogMessage(MainWindow, &Message)) { + TranslateMessage(&Message); + DispatchMessage(&Message); + } + } + + ExitProcess(0); +} + +INT_PTR CALLBACK MainWndProc( + IN HWND MainWindow, + IN UINT Message, + IN WPARAM WParam, + IN LPARAM LParam) +{ + if (Message == WM_INITDIALOG) { + HDC DeviceContext; + UINT TabStops; + + KexgApplicationMainWindow = MainWindow; + SetWindowText(MainWindow, KexgApplicationFriendlyName); + CheckDlgButton(MainWindow, IDC_RBDEF, TRUE); + DragAcceptFiles(MainWindow, TRUE); + + // Set monospace font for the results edit control + DeviceContext = GetDC(GetDlgItem(MainWindow, IDC_RESULT)); + + SendMessage( + GetDlgItem(MainWindow, IDC_RESULT), + WM_SETFONT, + (WPARAM) CreateFont(-MulDiv(8, GetDeviceCaps(DeviceContext, LOGPIXELSY), 72), + 0, 0, 0, FW_NORMAL, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, + CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, DEFAULT_PITCH | FF_DONTCARE, + L"Consolas"), + MAKELPARAM(TRUE, 0)); + + ReleaseDC(GetDlgItem(MainWindow, IDC_RESULT), DeviceContext); + + TabStops = 16; + Edit_SetTabStops(GetDlgItem(MainWindow, IDC_RESULT), 1, &TabStops); + + ToolTip(MainWindow, IDC_RBDEF, L"Generate module-definition (.def) file statements."); + ToolTip(MainWindow, IDC_RBPRAGMA, L"Generate #pragma preprocessor directives suitable " + L"for embedding in a C/C++ header file."); + } else if (Message == WM_CLOSE) { + EndDialog(MainWindow, 0); + PostQuitMessage(0); + } else if (Message == WM_COMMAND) { + USHORT ControlId = LOWORD(WParam); + + if (ControlId == IDCANCEL) { + PostMessage(MainWindow, WM_CLOSE, 0, 0); + } else if (ControlId == IDC_BROWSE) { + WCHAR DllPath[MAX_PATH]; + WCHAR System32Path[MAX_PATH]; + OPENFILENAME OpenFileInfo; + + StringCchPrintf(System32Path, ARRAYSIZE(System32Path), L"%s\\system32", + SharedUserData->NtSystemRoot); + + DllPath[0] = '\0'; + + ZeroMemory(&OpenFileInfo, sizeof(OpenFileInfo)); + OpenFileInfo.lStructSize = sizeof(OpenFileInfo); + OpenFileInfo.hwndOwner = MainWindow; + OpenFileInfo.lpstrFilter = L"DLL Files (*.dll, *.exe, *.sys)\0*.dll;*.exe;*.sys\0All Files (*.*)\0*.*\0"; + OpenFileInfo.lpstrFile = DllPath; + OpenFileInfo.nMaxFile = ARRAYSIZE(DllPath); + OpenFileInfo.lpstrInitialDir = System32Path; + OpenFileInfo.lpstrTitle = L"Select a DLL..."; + OpenFileInfo.Flags = OFN_FILEMUSTEXIST | OFN_FORCESHOWHIDDEN | OFN_HIDEREADONLY; + OpenFileInfo.lpstrDefExt = L"dll"; + + if (GetOpenFileName(&OpenFileInfo)) { + SetDlgItemText(MainWindow, IDC_FILEPATH, DllPath); + } + } else if (ControlId == IDOK) { + KEXEXPRT_GENERATE_STYLE Style; + WCHAR DllPath[MAX_PATH]; + HWND FilePathWindow; + + FilePathWindow = GetDlgItem(MainWindow, IDC_FILEPATH); + + if (GetWindowTextLength(FilePathWindow) == 0) { + EDITBALLOONTIP BalloonTip; + + BalloonTip.cbStruct = sizeof(BalloonTip); + BalloonTip.pszTitle = L"Specify a path"; + BalloonTip.pszText = L"You must specify the full path to a Portable Executable image file, e.g. a DLL."; + BalloonTip.ttiIcon = TTI_ERROR; + Edit_ShowBalloonTip(FilePathWindow, &BalloonTip); + + return TRUE; + } + + if (IsDlgButtonChecked(MainWindow, IDC_RBDEF)) { + Style = GenerateStyleDef; + } else if (IsDlgButtonChecked(MainWindow, IDC_RBPRAGMA)) { + Style = GenerateStylePragma; + } else { + NOT_REACHED; + } + + GetDlgItemText(MainWindow, IDC_FILEPATH, DllPath, ARRAYSIZE(DllPath)); + DumpExports(MainWindow, DllPath, Style, IsDlgButtonChecked(MainWindow, IDC_INCLUDEORDINALS)); + } else if (ControlId == M_SELECTALL) { + HWND FocusedWindow; + WCHAR ClassName[16]; + + FocusedWindow = GetFocus(); + GetClassName(FocusedWindow, ClassName, ARRAYSIZE(ClassName)); + + if (StringEqual(ClassName, L"Edit")) { + Edit_SetSel(FocusedWindow, 0, INT_MAX); + } + } else { + return FALSE; + } + } else if (Message == WM_DROPFILES) { + HDROP DroppedItem; + WCHAR DroppedFilePath[MAX_PATH]; + + DroppedItem = (HDROP) WParam; + + DragQueryFile(DroppedItem, 0, DroppedFilePath, ARRAYSIZE(DroppedFilePath)); + SetDlgItemText(MainWindow, IDC_FILEPATH, DroppedFilePath); + DragFinish(DroppedItem); + + PostMessage(MainWindow, WM_COMMAND, IDOK, 0); + } else if (Message == WM_CTLCOLORSTATIC) { + HWND Control; + + // + // Make the read-only results edit control have a white background. + // By default, read-only edit controls are greyed out. + // + + Control = (HWND) LParam; + + if (GetWindowLongPtr(Control, GWLP_ID) == IDC_RESULT) { + return (INT_PTR) GetStockObject(WHITE_BRUSH); + } else { + return FALSE; + } + } else { + // unhandled message + return FALSE; + } + + return TRUE; +} \ No newline at end of file diff --git a/01-Development Utilities/KexExprt/kexexprt.h b/01-Development Utilities/KexExprt/kexexprt.h new file mode 100644 index 0000000..b9adfd2 --- /dev/null +++ b/01-Development Utilities/KexExprt/kexexprt.h @@ -0,0 +1,46 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// kexexprt.h +// +// Abstract: +// +// Private header file for KexExprt +// +// Author: +// +// vxiiduu (29-Oct-2022) +// +// Revision History: +// +// vxiiduu 29-Oct-2022 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#pragma once +#include "buildcfg.h" +#include + +typedef struct _LARGE_UNICODE_STRING { + ULONG Cch; + ULONG MaxCch; + PWCHAR Buffer; +} TYPEDEF_TYPE_NAME(LARGE_UNICODE_STRING); + +typedef enum _KEXEXPRT_GENERATE_STYLE { + GenerateStyleDef, + GenerateStylePragma +} TYPEDEF_TYPE_NAME(KEXEXPRT_GENERATE_STYLE); + +INT_PTR CALLBACK MainWndProc( + IN HWND MainWindow, + IN UINT Message, + IN WPARAM WParam, + IN LPARAM LParam); + +VOID DumpExports( + IN HWND MainWindow, + IN PCWSTR DllPath, + IN KEXEXPRT_GENERATE_STYLE Style, + IN BOOLEAN IncludeOrdinals); \ No newline at end of file diff --git a/01-Development Utilities/KexExprt/resource.h b/01-Development Utilities/KexExprt/resource.h new file mode 100644 index 0000000..f152e6f --- /dev/null +++ b/01-Development Utilities/KexExprt/resource.h @@ -0,0 +1,16 @@ +#define MAINWND_WIDTH 400 +#define MAINWND_HEIGHT 300 + +#define IDD_MAINWND 101 +#define IDC_GUIDETEXT 102 +#define IDC_LOCATION 103 +#define IDC_FILEPATH 104 +#define IDC_BROWSE 105 +#define IDC_STYLESEL 106 +#define IDC_RBDEF 107 +#define IDC_RBPRAGMA 108 +#define IDC_RESULT 109 +#define IDC_INCLUDEORDINALS 110 + +#define IDA_ACCELERATORS 120 +#define M_SELECTALL 121 diff --git a/01-Development Utilities/KexExprt/x64/Debug/CL.12108.read.1.tlog b/01-Development Utilities/KexExprt/x64/Debug/CL.12108.read.1.tlog new file mode 100644 index 0000000..46b134b --- /dev/null +++ b/01-Development Utilities/KexExprt/x64/Debug/CL.12108.read.1.tlog @@ -0,0 +1 @@ +ÿþ \ No newline at end of file diff --git a/01-Development Utilities/KexExprt/x64/Debug/CL.12108.write.1.tlog b/01-Development Utilities/KexExprt/x64/Debug/CL.12108.write.1.tlog new file mode 100644 index 0000000..46b134b --- /dev/null +++ b/01-Development Utilities/KexExprt/x64/Debug/CL.12108.write.1.tlog @@ -0,0 +1 @@ +ÿþ \ No newline at end of file diff --git a/01-Development Utilities/KexExprt/x64/Debug/CL.14760.read.1.tlog b/01-Development Utilities/KexExprt/x64/Debug/CL.14760.read.1.tlog new file mode 100644 index 0000000..46b134b --- /dev/null +++ b/01-Development Utilities/KexExprt/x64/Debug/CL.14760.read.1.tlog @@ -0,0 +1 @@ +ÿþ \ No newline at end of file diff --git a/01-Development Utilities/KexExprt/x64/Debug/CL.14760.write.1.tlog b/01-Development Utilities/KexExprt/x64/Debug/CL.14760.write.1.tlog new file mode 100644 index 0000000..46b134b --- /dev/null +++ b/01-Development Utilities/KexExprt/x64/Debug/CL.14760.write.1.tlog @@ -0,0 +1 @@ +ÿþ \ No newline at end of file diff --git a/01-Development Utilities/KexExprt/x64/Debug/CL.1968.read.1.tlog b/01-Development Utilities/KexExprt/x64/Debug/CL.1968.read.1.tlog new file mode 100644 index 0000000..46b134b --- /dev/null +++ b/01-Development Utilities/KexExprt/x64/Debug/CL.1968.read.1.tlog @@ -0,0 +1 @@ +ÿþ \ No newline at end of file diff --git a/01-Development Utilities/KexExprt/x64/Debug/CL.1968.write.1.tlog b/01-Development Utilities/KexExprt/x64/Debug/CL.1968.write.1.tlog new file mode 100644 index 0000000..46b134b --- /dev/null +++ b/01-Development Utilities/KexExprt/x64/Debug/CL.1968.write.1.tlog @@ -0,0 +1 @@ +ÿþ \ No newline at end of file diff --git a/01-Development Utilities/KexExprt/x64/Debug/CL.5364.read.1.tlog b/01-Development Utilities/KexExprt/x64/Debug/CL.5364.read.1.tlog new file mode 100644 index 0000000..46b134b --- /dev/null +++ b/01-Development Utilities/KexExprt/x64/Debug/CL.5364.read.1.tlog @@ -0,0 +1 @@ +ÿþ \ No newline at end of file diff --git a/01-Development Utilities/KexExprt/x64/Debug/CL.5364.write.1.tlog b/01-Development Utilities/KexExprt/x64/Debug/CL.5364.write.1.tlog new file mode 100644 index 0000000..46b134b --- /dev/null +++ b/01-Development Utilities/KexExprt/x64/Debug/CL.5364.write.1.tlog @@ -0,0 +1 @@ +ÿþ \ No newline at end of file diff --git a/01-Development Utilities/KexExprt/x64/Debug/CL.5664.read.1.tlog b/01-Development Utilities/KexExprt/x64/Debug/CL.5664.read.1.tlog new file mode 100644 index 0000000..46b134b --- /dev/null +++ b/01-Development Utilities/KexExprt/x64/Debug/CL.5664.read.1.tlog @@ -0,0 +1 @@ +ÿþ \ No newline at end of file diff --git a/01-Development Utilities/KexExprt/x64/Debug/CL.5664.write.1.tlog b/01-Development Utilities/KexExprt/x64/Debug/CL.5664.write.1.tlog new file mode 100644 index 0000000..46b134b --- /dev/null +++ b/01-Development Utilities/KexExprt/x64/Debug/CL.5664.write.1.tlog @@ -0,0 +1 @@ +ÿþ \ No newline at end of file diff --git a/01-Development Utilities/KexExprt/x64/Debug/CL.7332.read.1.tlog b/01-Development Utilities/KexExprt/x64/Debug/CL.7332.read.1.tlog new file mode 100644 index 0000000..46b134b --- /dev/null +++ b/01-Development Utilities/KexExprt/x64/Debug/CL.7332.read.1.tlog @@ -0,0 +1 @@ +ÿþ \ No newline at end of file diff --git a/01-Development Utilities/KexExprt/x64/Debug/CL.7332.write.1.tlog b/01-Development Utilities/KexExprt/x64/Debug/CL.7332.write.1.tlog new file mode 100644 index 0000000..46b134b --- /dev/null +++ b/01-Development Utilities/KexExprt/x64/Debug/CL.7332.write.1.tlog @@ -0,0 +1 @@ +ÿþ \ No newline at end of file diff --git a/01-Development Utilities/KexExprt/x64/Debug/CL.read.1.tlog b/01-Development Utilities/KexExprt/x64/Debug/CL.read.1.tlog new file mode 100644 index 0000000..edf7faf Binary files /dev/null and b/01-Development Utilities/KexExprt/x64/Debug/CL.read.1.tlog differ diff --git a/01-Development Utilities/KexExprt/x64/Debug/KexExprt.exe.intermediate.manifest b/01-Development Utilities/KexExprt/x64/Debug/KexExprt.exe.intermediate.manifest new file mode 100644 index 0000000..452f07e --- /dev/null +++ b/01-Development Utilities/KexExprt/x64/Debug/KexExprt.exe.intermediate.manifest @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/01-Development Utilities/KexExprt/x64/Debug/KexExprt.lastbuildstate b/01-Development Utilities/KexExprt/x64/Debug/KexExprt.lastbuildstate new file mode 100644 index 0000000..675b950 --- /dev/null +++ b/01-Development Utilities/KexExprt/x64/Debug/KexExprt.lastbuildstate @@ -0,0 +1,2 @@ +#v4.0:v100:false +Debug|x64|C:\Users\vxiiduu\Documents\Visual Studio 2010\Projects\VxKex\| diff --git a/01-Development Utilities/KexExprt/x64/Debug/KexExprt.log b/01-Development Utilities/KexExprt/x64/Debug/KexExprt.log new file mode 100644 index 0000000..b91766f --- /dev/null +++ b/01-Development Utilities/KexExprt/x64/Debug/KexExprt.log @@ -0,0 +1,24 @@ +Build started 17/03/2024 12:43:18. +Project "C:\Users\vxiiduu\Documents\Visual Studio 2010\Projects\VxKex\01-Development Utilities\KexExprt\KexExprt.vcxproj" on node 2 (build target(s)). +InitializeBuildStatus: + Creating "x64\Debug\KexExprt.unsuccessfulbuild" because "AlwaysCreate" was specified. +ClCompile: + C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\x86_amd64\CL.exe /c /I"C:\Users\vxiiduu\Documents\Visual Studio 2010\Projects\VxKex\\00-Common Headers" /Zi /nologo /W3 /WX /MP /Od /D WIN32 /D _DEBUG /D _WINDOWS /D _UNICODE /D UNICODE /Gm- /EHsc /MDd /GS- /fp:precise /Zc:wchar_t /Zc:forScope /Fo"x64\Debug\\" /Fd"x64\Debug\vc100.pdb" /Gd /TC /errorReport:prompt dump.c + dump.c +ResourceCompile: + All outputs are up-to-date. +Link: + C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\x86_amd64\link.exe /ERRORREPORT:PROMPT /OUT:"C:\Users\vxiiduu\Documents\Visual Studio 2010\Projects\VxKex\x64\Debug\KexExprt.exe" /INCREMENTAL:NO /NOLOGO /LIBPATH:"C:\Users\vxiiduu\Documents\Visual Studio 2010\Projects\VxKex\x64\Debug\\" /LIBPATH:"C:\Users\vxiiduu\Documents\Visual Studio 2010\Projects\VxKex\\00-Import Libraries" /MANIFEST /ManifestFile:"x64\Debug\KexExprt.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"C:\Users\vxiiduu\Documents\Visual Studio 2010\Projects\VxKex\x64\Debug\KexExprt.pdb" /SUBSYSTEM:WINDOWS /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"C:\Users\vxiiduu\Documents\Visual Studio 2010\Projects\VxKex\x64\Debug\KexExprt.lib" /MACHINE:X64 x64\Debug\KexExprt.res + x64\Debug\dump.obj + x64\Debug\kexexprt.obj + KexExprt.vcxproj -> C:\Users\vxiiduu\Documents\Visual Studio 2010\Projects\VxKex\x64\Debug\KexExprt.exe +Manifest: + C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\mt.exe /nologo /verbose /outputresource:"C:\Users\vxiiduu\Documents\Visual Studio 2010\Projects\VxKex\x64\Debug\KexExprt.exe;#1" /manifest x64\Debug\KexExprt.exe.intermediate.manifest +FinalizeBuildStatus: + Deleting file "x64\Debug\KexExprt.unsuccessfulbuild". + Touching "x64\Debug\KexExprt.lastbuildstate". +Done Building Project "C:\Users\vxiiduu\Documents\Visual Studio 2010\Projects\VxKex\01-Development Utilities\KexExprt\KexExprt.vcxproj" (build target(s)). + +Build succeeded. + +Time Elapsed 00:00:00.40 diff --git a/01-Development Utilities/KexExprt/x64/Debug/KexExprt.res b/01-Development Utilities/KexExprt/x64/Debug/KexExprt.res new file mode 100644 index 0000000..b85b75e Binary files /dev/null and b/01-Development Utilities/KexExprt/x64/Debug/KexExprt.res differ diff --git a/01-Development Utilities/KexExprt/x64/Debug/KexExprt.vcxprojResolveAssemblyReference.cache b/01-Development Utilities/KexExprt/x64/Debug/KexExprt.vcxprojResolveAssemblyReference.cache new file mode 100644 index 0000000..45114e3 Binary files /dev/null and b/01-Development Utilities/KexExprt/x64/Debug/KexExprt.vcxprojResolveAssemblyReference.cache differ diff --git a/01-Development Utilities/KexExprt/x64/Debug/KexExprt.write.1.tlog b/01-Development Utilities/KexExprt/x64/Debug/KexExprt.write.1.tlog new file mode 100644 index 0000000..e69de29 diff --git a/01-Development Utilities/KexExprt/x64/Debug/cl.command.1.tlog b/01-Development Utilities/KexExprt/x64/Debug/cl.command.1.tlog new file mode 100644 index 0000000..c607224 Binary files /dev/null and b/01-Development Utilities/KexExprt/x64/Debug/cl.command.1.tlog differ diff --git a/01-Development Utilities/KexExprt/x64/Debug/cl.write.1.tlog b/01-Development Utilities/KexExprt/x64/Debug/cl.write.1.tlog new file mode 100644 index 0000000..cef60e8 Binary files /dev/null and b/01-Development Utilities/KexExprt/x64/Debug/cl.write.1.tlog differ diff --git a/01-Development Utilities/KexExprt/x64/Debug/dump.obj b/01-Development Utilities/KexExprt/x64/Debug/dump.obj new file mode 100644 index 0000000..0b89589 Binary files /dev/null and b/01-Development Utilities/KexExprt/x64/Debug/dump.obj differ diff --git a/01-Development Utilities/KexExprt/x64/Debug/kexexprt.obj b/01-Development Utilities/KexExprt/x64/Debug/kexexprt.obj new file mode 100644 index 0000000..d793787 Binary files /dev/null and b/01-Development Utilities/KexExprt/x64/Debug/kexexprt.obj differ diff --git a/01-Development Utilities/KexExprt/x64/Debug/link-cvtres.read.1.tlog b/01-Development Utilities/KexExprt/x64/Debug/link-cvtres.read.1.tlog new file mode 100644 index 0000000..46b134b --- /dev/null +++ b/01-Development Utilities/KexExprt/x64/Debug/link-cvtres.read.1.tlog @@ -0,0 +1 @@ +ÿþ \ No newline at end of file diff --git a/01-Development Utilities/KexExprt/x64/Debug/link-cvtres.write.1.tlog b/01-Development Utilities/KexExprt/x64/Debug/link-cvtres.write.1.tlog new file mode 100644 index 0000000..46b134b --- /dev/null +++ b/01-Development Utilities/KexExprt/x64/Debug/link-cvtres.write.1.tlog @@ -0,0 +1 @@ +ÿþ \ No newline at end of file diff --git a/01-Development Utilities/KexExprt/x64/Debug/link.command.1.tlog b/01-Development Utilities/KexExprt/x64/Debug/link.command.1.tlog new file mode 100644 index 0000000..15d0cef Binary files /dev/null and b/01-Development Utilities/KexExprt/x64/Debug/link.command.1.tlog differ diff --git a/01-Development Utilities/KexExprt/x64/Debug/link.read.1.tlog b/01-Development Utilities/KexExprt/x64/Debug/link.read.1.tlog new file mode 100644 index 0000000..b125628 Binary files /dev/null and b/01-Development Utilities/KexExprt/x64/Debug/link.read.1.tlog differ diff --git a/01-Development Utilities/KexExprt/x64/Debug/link.write.1.tlog b/01-Development Utilities/KexExprt/x64/Debug/link.write.1.tlog new file mode 100644 index 0000000..04d8f08 Binary files /dev/null and b/01-Development Utilities/KexExprt/x64/Debug/link.write.1.tlog differ diff --git a/01-Development Utilities/KexExprt/x64/Debug/mt.command.1.tlog b/01-Development Utilities/KexExprt/x64/Debug/mt.command.1.tlog new file mode 100644 index 0000000..0215abc Binary files /dev/null and b/01-Development Utilities/KexExprt/x64/Debug/mt.command.1.tlog differ diff --git a/01-Development Utilities/KexExprt/x64/Debug/mt.read.1.tlog b/01-Development Utilities/KexExprt/x64/Debug/mt.read.1.tlog new file mode 100644 index 0000000..4e43797 Binary files /dev/null and b/01-Development Utilities/KexExprt/x64/Debug/mt.read.1.tlog differ diff --git a/01-Development Utilities/KexExprt/x64/Debug/mt.write.1.tlog b/01-Development Utilities/KexExprt/x64/Debug/mt.write.1.tlog new file mode 100644 index 0000000..f3c848c Binary files /dev/null and b/01-Development Utilities/KexExprt/x64/Debug/mt.write.1.tlog differ diff --git a/01-Development Utilities/KexExprt/x64/Debug/rc.command.1.tlog b/01-Development Utilities/KexExprt/x64/Debug/rc.command.1.tlog new file mode 100644 index 0000000..de7689a Binary files /dev/null and b/01-Development Utilities/KexExprt/x64/Debug/rc.command.1.tlog differ diff --git a/01-Development Utilities/KexExprt/x64/Debug/rc.read.1.tlog b/01-Development Utilities/KexExprt/x64/Debug/rc.read.1.tlog new file mode 100644 index 0000000..4b01f16 Binary files /dev/null and b/01-Development Utilities/KexExprt/x64/Debug/rc.read.1.tlog differ diff --git a/01-Development Utilities/KexExprt/x64/Debug/rc.write.1.tlog b/01-Development Utilities/KexExprt/x64/Debug/rc.write.1.tlog new file mode 100644 index 0000000..980a74c Binary files /dev/null and b/01-Development Utilities/KexExprt/x64/Debug/rc.write.1.tlog differ diff --git a/01-Development Utilities/KexExprt/x64/Debug/vc100.pdb b/01-Development Utilities/KexExprt/x64/Debug/vc100.pdb new file mode 100644 index 0000000..eb74154 Binary files /dev/null and b/01-Development Utilities/KexExprt/x64/Debug/vc100.pdb differ diff --git a/01-Development Utilities/vautogen/vautogen.exe b/01-Development Utilities/vautogen/vautogen.exe new file mode 100644 index 0000000..a00aa97 Binary files /dev/null and b/01-Development Utilities/vautogen/vautogen.exe differ diff --git a/01-Development Utilities/vautogen/vautogen.ini b/01-Development Utilities/vautogen/vautogen.ini new file mode 100644 index 0000000..270ee87 --- /dev/null +++ b/01-Development Utilities/vautogen/vautogen.ini @@ -0,0 +1,6 @@ +[vautogen] +HeaderFile=..\..\00-Common Headers\vautogen.h +MajorVersion=1 +MinorVersion=1 +PatchLevel=1 +BuildNumber=1375 diff --git a/01-Development Utilities/vautogen/vautogen.pdb b/01-Development Utilities/vautogen/vautogen.pdb new file mode 100644 index 0000000..1e76c61 Binary files /dev/null and b/01-Development Utilities/vautogen/vautogen.pdb differ diff --git a/01-Extended DLLs/KxAdvapi/KxAdvapi.vcxproj b/01-Extended DLLs/KxAdvapi/KxAdvapi.vcxproj new file mode 100644 index 0000000..7630833 --- /dev/null +++ b/01-Extended DLLs/KxAdvapi/KxAdvapi.vcxproj @@ -0,0 +1,243 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {4E267C5E-6A43-4E20-A2B9-8C9526F97215} + Win32Proj + KxAdvapi + + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + + + + + + + + + + + + + + + + + false + false + + + false + false + + + false + false + + + false + false + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;KXADVAPI_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + false + true + true + true + false + Default + false + StdCall + CompileAsC + false + + + Windows + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + true + + + true + kxadvapi.def + + + $(SolutionDir)\00-Common Headers + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;KXADVAPI_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + false + true + true + true + false + Default + false + StdCall + CompileAsC + false + + + Windows + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + true + + + true + kxadvapi.def + + + $(SolutionDir)\00-Common Headers + + + + + Level3 + NotUsing + MinSpace + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;KXADVAPI_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + false + true + true + true + false + Default + false + StdCall + CompileAsC + false + OnlyExplicitInline + Size + true + + + Windows + true + true + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + true + + + true + kxadvapi.def + + + $(SolutionDir)\00-Common Headers + + + + + Level3 + NotUsing + MinSpace + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;KXADVAPI_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + false + true + true + true + false + Default + false + StdCall + CompileAsC + false + OnlyExplicitInline + Size + true + + + Windows + true + true + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + true + + + true + kxadvapi.def + + + $(SolutionDir)\00-Common Headers + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/01-Extended DLLs/KxAdvapi/KxAdvapi.vcxproj.filters b/01-Extended DLLs/KxAdvapi/KxAdvapi.vcxproj.filters new file mode 100644 index 0000000..bdb536f --- /dev/null +++ b/01-Extended DLLs/KxAdvapi/KxAdvapi.vcxproj.filters @@ -0,0 +1,40 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + + + Source Files + + + Source Files + + + + + Resource Files + + + + + Source Files + + + \ No newline at end of file diff --git a/01-Extended DLLs/KxAdvapi/buildcfg.h b/01-Extended DLLs/KxAdvapi/buildcfg.h new file mode 100644 index 0000000..5c49f24 --- /dev/null +++ b/01-Extended DLLs/KxAdvapi/buildcfg.h @@ -0,0 +1,43 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN +#define NOGDICAPMASKS +#define NOVIRTUALKEYCODES +#define NOWINSTYLES +#define NOSYSMETRICS +#define NOMENUS +#define NOICONS +#define NOKEYSTATES +#define NOSYSCOMMANDS +#define NORASTEROPS +#define NOSHOWWINDOW +#define NOATOM +#define NOCLIPBOARD +#define NOCOLOR +#define NODRAWTEXT +#define NOGDI +#define NOKERNEL +#define NOMB +#define NOMEMMGR +#define NOOPENFILE +#define NOSCROLL +#define NOTEXTMETRIC +#define NOWH +#define NOWINOFFSETS +#define NOCOMM +#define NOKANJI +#define NOHELP +#define NOPROFILER +#define NODEFERWINDOWPOS +#define NOMCX +#define NOCRYPT +#define NOMETAFILE +#define NOSERVICE +#define NOSOUND +#define _UXTHEME_H_ + +#pragma comment(lib, "KexDll.lib") + +#define KEX_COMPONENT L"KxAdvapi" +#define KEX_ENV_WIN32 +#define KEX_TARGET_TYPE_DLL diff --git a/01-Extended DLLs/KxAdvapi/dllmain.c b/01-Extended DLLs/KxAdvapi/dllmain.c new file mode 100644 index 0000000..da6c514 --- /dev/null +++ b/01-Extended DLLs/KxAdvapi/dllmain.c @@ -0,0 +1,14 @@ +#include "buildcfg.h" +#include + +BOOL WINAPI DllMain( + IN HMODULE DllHandle, + IN ULONG Reason, + IN PCONTEXT Context) +{ + if (Reason == DLL_PROCESS_ATTACH) { + LdrDisableThreadCalloutsForDll(DllHandle); + } + + return TRUE; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxAdvapi/forwards.c b/01-Extended DLLs/KxAdvapi/forwards.c new file mode 100644 index 0000000..aaffdc3 --- /dev/null +++ b/01-Extended DLLs/KxAdvapi/forwards.c @@ -0,0 +1,811 @@ +// Generated by KexExprt from "advapi32.dll" +#pragma comment(linker, "/EXPORT:A_SHAFinal=advapi32.A_SHAFinal") +#pragma comment(linker, "/EXPORT:A_SHAInit=advapi32.A_SHAInit") +#pragma comment(linker, "/EXPORT:A_SHAUpdate=advapi32.A_SHAUpdate") +#pragma comment(linker, "/EXPORT:AbortSystemShutdownA=advapi32.AbortSystemShutdownA") +#pragma comment(linker, "/EXPORT:AbortSystemShutdownW=advapi32.AbortSystemShutdownW") +#pragma comment(linker, "/EXPORT:AccessCheck=advapi32.AccessCheck") +#pragma comment(linker, "/EXPORT:AccessCheckAndAuditAlarmA=advapi32.AccessCheckAndAuditAlarmA") +#pragma comment(linker, "/EXPORT:AccessCheckAndAuditAlarmW=advapi32.AccessCheckAndAuditAlarmW") +#pragma comment(linker, "/EXPORT:AccessCheckByType=advapi32.AccessCheckByType") +#pragma comment(linker, "/EXPORT:AccessCheckByTypeAndAuditAlarmA=advapi32.AccessCheckByTypeAndAuditAlarmA") +#pragma comment(linker, "/EXPORT:AccessCheckByTypeAndAuditAlarmW=advapi32.AccessCheckByTypeAndAuditAlarmW") +#pragma comment(linker, "/EXPORT:AccessCheckByTypeResultList=advapi32.AccessCheckByTypeResultList") +#pragma comment(linker, "/EXPORT:AccessCheckByTypeResultListAndAuditAlarmA=advapi32.AccessCheckByTypeResultListAndAuditAlarmA") +#pragma comment(linker, "/EXPORT:AccessCheckByTypeResultListAndAuditAlarmByHandleA=advapi32.AccessCheckByTypeResultListAndAuditAlarmByHandleA") +#pragma comment(linker, "/EXPORT:AccessCheckByTypeResultListAndAuditAlarmByHandleW=advapi32.AccessCheckByTypeResultListAndAuditAlarmByHandleW") +#pragma comment(linker, "/EXPORT:AccessCheckByTypeResultListAndAuditAlarmW=advapi32.AccessCheckByTypeResultListAndAuditAlarmW") +#pragma comment(linker, "/EXPORT:AddAccessAllowedAce=advapi32.AddAccessAllowedAce") +#pragma comment(linker, "/EXPORT:AddAccessAllowedAceEx=advapi32.AddAccessAllowedAceEx") +#pragma comment(linker, "/EXPORT:AddAccessAllowedObjectAce=advapi32.AddAccessAllowedObjectAce") +#pragma comment(linker, "/EXPORT:AddAccessDeniedAce=advapi32.AddAccessDeniedAce") +#pragma comment(linker, "/EXPORT:AddAccessDeniedAceEx=advapi32.AddAccessDeniedAceEx") +#pragma comment(linker, "/EXPORT:AddAccessDeniedObjectAce=advapi32.AddAccessDeniedObjectAce") +#pragma comment(linker, "/EXPORT:AddAce=advapi32.AddAce") +#pragma comment(linker, "/EXPORT:AddAuditAccessAce=advapi32.AddAuditAccessAce") +#pragma comment(linker, "/EXPORT:AddAuditAccessAceEx=advapi32.AddAuditAccessAceEx") +#pragma comment(linker, "/EXPORT:AddAuditAccessObjectAce=advapi32.AddAuditAccessObjectAce") +#pragma comment(linker, "/EXPORT:AddConditionalAce=advapi32.AddConditionalAce") +#pragma comment(linker, "/EXPORT:AddMandatoryAce=advapi32.AddMandatoryAce") +#pragma comment(linker, "/EXPORT:AddUsersToEncryptedFile=advapi32.AddUsersToEncryptedFile") +#pragma comment(linker, "/EXPORT:AddUsersToEncryptedFileEx=advapi32.AddUsersToEncryptedFileEx") +#pragma comment(linker, "/EXPORT:AdjustTokenGroups=advapi32.AdjustTokenGroups") +#pragma comment(linker, "/EXPORT:AdjustTokenPrivileges=advapi32.AdjustTokenPrivileges") +#pragma comment(linker, "/EXPORT:AllocateAndInitializeSid=advapi32.AllocateAndInitializeSid") +#pragma comment(linker, "/EXPORT:AllocateLocallyUniqueId=advapi32.AllocateLocallyUniqueId") +#pragma comment(linker, "/EXPORT:AreAllAccessesGranted=advapi32.AreAllAccessesGranted") +#pragma comment(linker, "/EXPORT:AreAnyAccessesGranted=advapi32.AreAnyAccessesGranted") +#pragma comment(linker, "/EXPORT:AuditComputeEffectivePolicyBySid=advapi32.AuditComputeEffectivePolicyBySid") +#pragma comment(linker, "/EXPORT:AuditComputeEffectivePolicyByToken=advapi32.AuditComputeEffectivePolicyByToken") +#pragma comment(linker, "/EXPORT:AuditEnumerateCategories=advapi32.AuditEnumerateCategories") +#pragma comment(linker, "/EXPORT:AuditEnumeratePerUserPolicy=advapi32.AuditEnumeratePerUserPolicy") +#pragma comment(linker, "/EXPORT:AuditEnumerateSubCategories=advapi32.AuditEnumerateSubCategories") +#pragma comment(linker, "/EXPORT:AuditFree=advapi32.AuditFree") +#pragma comment(linker, "/EXPORT:AuditLookupCategoryGuidFromCategoryId=advapi32.AuditLookupCategoryGuidFromCategoryId") +#pragma comment(linker, "/EXPORT:AuditLookupCategoryIdFromCategoryGuid=advapi32.AuditLookupCategoryIdFromCategoryGuid") +#pragma comment(linker, "/EXPORT:AuditLookupCategoryNameA=advapi32.AuditLookupCategoryNameA") +#pragma comment(linker, "/EXPORT:AuditLookupCategoryNameW=advapi32.AuditLookupCategoryNameW") +#pragma comment(linker, "/EXPORT:AuditLookupSubCategoryNameA=advapi32.AuditLookupSubCategoryNameA") +#pragma comment(linker, "/EXPORT:AuditLookupSubCategoryNameW=advapi32.AuditLookupSubCategoryNameW") +#pragma comment(linker, "/EXPORT:AuditQueryGlobalSaclA=advapi32.AuditQueryGlobalSaclA") +#pragma comment(linker, "/EXPORT:AuditQueryGlobalSaclW=advapi32.AuditQueryGlobalSaclW") +#pragma comment(linker, "/EXPORT:AuditQueryPerUserPolicy=advapi32.AuditQueryPerUserPolicy") +#pragma comment(linker, "/EXPORT:AuditQuerySecurity=advapi32.AuditQuerySecurity") +#pragma comment(linker, "/EXPORT:AuditQuerySystemPolicy=advapi32.AuditQuerySystemPolicy") +#pragma comment(linker, "/EXPORT:AuditSetGlobalSaclA=advapi32.AuditSetGlobalSaclA") +#pragma comment(linker, "/EXPORT:AuditSetGlobalSaclW=advapi32.AuditSetGlobalSaclW") +#pragma comment(linker, "/EXPORT:AuditSetPerUserPolicy=advapi32.AuditSetPerUserPolicy") +#pragma comment(linker, "/EXPORT:AuditSetSecurity=advapi32.AuditSetSecurity") +#pragma comment(linker, "/EXPORT:AuditSetSystemPolicy=advapi32.AuditSetSystemPolicy") +#pragma comment(linker, "/EXPORT:BackupEventLogA=advapi32.BackupEventLogA") +#pragma comment(linker, "/EXPORT:BackupEventLogW=advapi32.BackupEventLogW") +#pragma comment(linker, "/EXPORT:BuildExplicitAccessWithNameA=advapi32.BuildExplicitAccessWithNameA") +#pragma comment(linker, "/EXPORT:BuildExplicitAccessWithNameW=advapi32.BuildExplicitAccessWithNameW") +#pragma comment(linker, "/EXPORT:BuildImpersonateExplicitAccessWithNameA=advapi32.BuildImpersonateExplicitAccessWithNameA") +#pragma comment(linker, "/EXPORT:BuildImpersonateExplicitAccessWithNameW=advapi32.BuildImpersonateExplicitAccessWithNameW") +#pragma comment(linker, "/EXPORT:BuildImpersonateTrusteeA=advapi32.BuildImpersonateTrusteeA") +#pragma comment(linker, "/EXPORT:BuildImpersonateTrusteeW=advapi32.BuildImpersonateTrusteeW") +#pragma comment(linker, "/EXPORT:BuildSecurityDescriptorA=advapi32.BuildSecurityDescriptorA") +#pragma comment(linker, "/EXPORT:BuildSecurityDescriptorW=advapi32.BuildSecurityDescriptorW") +#pragma comment(linker, "/EXPORT:BuildTrusteeWithNameA=advapi32.BuildTrusteeWithNameA") +#pragma comment(linker, "/EXPORT:BuildTrusteeWithNameW=advapi32.BuildTrusteeWithNameW") +#pragma comment(linker, "/EXPORT:BuildTrusteeWithObjectsAndNameA=advapi32.BuildTrusteeWithObjectsAndNameA") +#pragma comment(linker, "/EXPORT:BuildTrusteeWithObjectsAndNameW=advapi32.BuildTrusteeWithObjectsAndNameW") +#pragma comment(linker, "/EXPORT:BuildTrusteeWithObjectsAndSidA=advapi32.BuildTrusteeWithObjectsAndSidA") +#pragma comment(linker, "/EXPORT:BuildTrusteeWithObjectsAndSidW=advapi32.BuildTrusteeWithObjectsAndSidW") +#pragma comment(linker, "/EXPORT:BuildTrusteeWithSidA=advapi32.BuildTrusteeWithSidA") +#pragma comment(linker, "/EXPORT:BuildTrusteeWithSidW=advapi32.BuildTrusteeWithSidW") +#pragma comment(linker, "/EXPORT:CancelOverlappedAccess=advapi32.CancelOverlappedAccess") +#pragma comment(linker, "/EXPORT:ChangeServiceConfig2A=advapi32.ChangeServiceConfig2A") +#pragma comment(linker, "/EXPORT:ChangeServiceConfig2W=advapi32.ChangeServiceConfig2W") +#pragma comment(linker, "/EXPORT:ChangeServiceConfigA=advapi32.ChangeServiceConfigA") +#pragma comment(linker, "/EXPORT:ChangeServiceConfigW=advapi32.ChangeServiceConfigW") +#pragma comment(linker, "/EXPORT:CheckTokenMembership=advapi32.CheckTokenMembership") +#pragma comment(linker, "/EXPORT:ClearEventLogA=advapi32.ClearEventLogA") +#pragma comment(linker, "/EXPORT:ClearEventLogW=advapi32.ClearEventLogW") +#pragma comment(linker, "/EXPORT:CloseCodeAuthzLevel=advapi32.CloseCodeAuthzLevel") +#pragma comment(linker, "/EXPORT:CloseEncryptedFileRaw=advapi32.CloseEncryptedFileRaw") +#pragma comment(linker, "/EXPORT:CloseEventLog=advapi32.CloseEventLog") +#pragma comment(linker, "/EXPORT:CloseServiceHandle=advapi32.CloseServiceHandle") +#pragma comment(linker, "/EXPORT:CloseThreadWaitChainSession=advapi32.CloseThreadWaitChainSession") +#pragma comment(linker, "/EXPORT:CloseTrace=advapi32.CloseTrace") +#pragma comment(linker, "/EXPORT:CommandLineFromMsiDescriptor=advapi32.CommandLineFromMsiDescriptor") +#pragma comment(linker, "/EXPORT:ComputeAccessTokenFromCodeAuthzLevel=advapi32.ComputeAccessTokenFromCodeAuthzLevel") +#pragma comment(linker, "/EXPORT:ControlService=advapi32.ControlService") +#pragma comment(linker, "/EXPORT:ControlServiceExA=advapi32.ControlServiceExA") +#pragma comment(linker, "/EXPORT:ControlServiceExW=advapi32.ControlServiceExW") +#pragma comment(linker, "/EXPORT:ControlTraceA=advapi32.ControlTraceA") +#pragma comment(linker, "/EXPORT:ControlTraceW=advapi32.ControlTraceW") +#pragma comment(linker, "/EXPORT:ConvertAccessToSecurityDescriptorA=advapi32.ConvertAccessToSecurityDescriptorA") +#pragma comment(linker, "/EXPORT:ConvertAccessToSecurityDescriptorW=advapi32.ConvertAccessToSecurityDescriptorW") +#pragma comment(linker, "/EXPORT:ConvertSDToStringSDRootDomainA=advapi32.ConvertSDToStringSDRootDomainA") +#pragma comment(linker, "/EXPORT:ConvertSDToStringSDRootDomainW=advapi32.ConvertSDToStringSDRootDomainW") +#pragma comment(linker, "/EXPORT:ConvertSecurityDescriptorToAccessA=advapi32.ConvertSecurityDescriptorToAccessA") +#pragma comment(linker, "/EXPORT:ConvertSecurityDescriptorToAccessNamedA=advapi32.ConvertSecurityDescriptorToAccessNamedA") +#pragma comment(linker, "/EXPORT:ConvertSecurityDescriptorToAccessNamedW=advapi32.ConvertSecurityDescriptorToAccessNamedW") +#pragma comment(linker, "/EXPORT:ConvertSecurityDescriptorToAccessW=advapi32.ConvertSecurityDescriptorToAccessW") +#pragma comment(linker, "/EXPORT:ConvertSecurityDescriptorToStringSecurityDescriptorA=advapi32.ConvertSecurityDescriptorToStringSecurityDescriptorA") +#pragma comment(linker, "/EXPORT:ConvertSecurityDescriptorToStringSecurityDescriptorW=advapi32.ConvertSecurityDescriptorToStringSecurityDescriptorW") +#pragma comment(linker, "/EXPORT:ConvertSidToStringSidA=advapi32.ConvertSidToStringSidA") +#pragma comment(linker, "/EXPORT:ConvertSidToStringSidW=advapi32.ConvertSidToStringSidW") +#pragma comment(linker, "/EXPORT:ConvertStringSDToSDDomainA=advapi32.ConvertStringSDToSDDomainA") +#pragma comment(linker, "/EXPORT:ConvertStringSDToSDDomainW=advapi32.ConvertStringSDToSDDomainW") +#pragma comment(linker, "/EXPORT:ConvertStringSDToSDRootDomainA=advapi32.ConvertStringSDToSDRootDomainA") +#pragma comment(linker, "/EXPORT:ConvertStringSDToSDRootDomainW=advapi32.ConvertStringSDToSDRootDomainW") +#pragma comment(linker, "/EXPORT:ConvertStringSecurityDescriptorToSecurityDescriptorA=advapi32.ConvertStringSecurityDescriptorToSecurityDescriptorA") +#pragma comment(linker, "/EXPORT:ConvertStringSecurityDescriptorToSecurityDescriptorW=advapi32.ConvertStringSecurityDescriptorToSecurityDescriptorW") +#pragma comment(linker, "/EXPORT:ConvertStringSidToSidA=advapi32.ConvertStringSidToSidA") +#pragma comment(linker, "/EXPORT:ConvertStringSidToSidW=advapi32.ConvertStringSidToSidW") +#pragma comment(linker, "/EXPORT:ConvertToAutoInheritPrivateObjectSecurity=advapi32.ConvertToAutoInheritPrivateObjectSecurity") +#pragma comment(linker, "/EXPORT:CopySid=advapi32.CopySid") +#pragma comment(linker, "/EXPORT:CreateCodeAuthzLevel=advapi32.CreateCodeAuthzLevel") +#pragma comment(linker, "/EXPORT:CreatePrivateObjectSecurity=advapi32.CreatePrivateObjectSecurity") +#pragma comment(linker, "/EXPORT:CreatePrivateObjectSecurityEx=advapi32.CreatePrivateObjectSecurityEx") +#pragma comment(linker, "/EXPORT:CreatePrivateObjectSecurityWithMultipleInheritance=advapi32.CreatePrivateObjectSecurityWithMultipleInheritance") +#pragma comment(linker, "/EXPORT:CreateProcessAsUserA=advapi32.CreateProcessAsUserA") +#pragma comment(linker, "/EXPORT:CreateProcessAsUserW=advapi32.CreateProcessAsUserW") +#pragma comment(linker, "/EXPORT:CreateProcessWithLogonW=advapi32.CreateProcessWithLogonW") +#pragma comment(linker, "/EXPORT:CreateProcessWithTokenW=advapi32.CreateProcessWithTokenW") +#pragma comment(linker, "/EXPORT:CreateRestrictedToken=advapi32.CreateRestrictedToken") +#pragma comment(linker, "/EXPORT:CreateServiceA=advapi32.CreateServiceA") +#pragma comment(linker, "/EXPORT:CreateServiceW=advapi32.CreateServiceW") +#pragma comment(linker, "/EXPORT:CreateTraceInstanceId=advapi32.CreateTraceInstanceId") +#pragma comment(linker, "/EXPORT:CreateWellKnownSid=advapi32.CreateWellKnownSid") +#pragma comment(linker, "/EXPORT:CredBackupCredentials=advapi32.CredBackupCredentials") +#pragma comment(linker, "/EXPORT:CredDeleteA=advapi32.CredDeleteA") +#pragma comment(linker, "/EXPORT:CredDeleteW=advapi32.CredDeleteW") +#pragma comment(linker, "/EXPORT:CredEncryptAndMarshalBinaryBlob=advapi32.CredEncryptAndMarshalBinaryBlob") +#pragma comment(linker, "/EXPORT:CredEnumerateA=advapi32.CredEnumerateA") +#pragma comment(linker, "/EXPORT:CredEnumerateW=advapi32.CredEnumerateW") +#pragma comment(linker, "/EXPORT:CredFindBestCredentialA=advapi32.CredFindBestCredentialA") +#pragma comment(linker, "/EXPORT:CredFindBestCredentialW=advapi32.CredFindBestCredentialW") +#pragma comment(linker, "/EXPORT:CredFree=advapi32.CredFree") +#pragma comment(linker, "/EXPORT:CredGetSessionTypes=advapi32.CredGetSessionTypes") +#pragma comment(linker, "/EXPORT:CredGetTargetInfoA=advapi32.CredGetTargetInfoA") +#pragma comment(linker, "/EXPORT:CredGetTargetInfoW=advapi32.CredGetTargetInfoW") +#pragma comment(linker, "/EXPORT:CredIsMarshaledCredentialA=advapi32.CredIsMarshaledCredentialA") +#pragma comment(linker, "/EXPORT:CredIsMarshaledCredentialW=advapi32.CredIsMarshaledCredentialW") +#pragma comment(linker, "/EXPORT:CredIsProtectedA=advapi32.CredIsProtectedA") +#pragma comment(linker, "/EXPORT:CredIsProtectedW=advapi32.CredIsProtectedW") +#pragma comment(linker, "/EXPORT:CredMarshalCredentialA=advapi32.CredMarshalCredentialA") +#pragma comment(linker, "/EXPORT:CredMarshalCredentialW=advapi32.CredMarshalCredentialW") +#pragma comment(linker, "/EXPORT:CredProfileLoaded=advapi32.CredProfileLoaded") +#pragma comment(linker, "/EXPORT:CredProfileUnloaded=advapi32.CredProfileUnloaded") +#pragma comment(linker, "/EXPORT:CredProtectA=advapi32.CredProtectA") +#pragma comment(linker, "/EXPORT:CredProtectW=advapi32.CredProtectW") +#pragma comment(linker, "/EXPORT:CredReadA=advapi32.CredReadA") +#pragma comment(linker, "/EXPORT:CredReadByTokenHandle=advapi32.CredReadByTokenHandle") +#pragma comment(linker, "/EXPORT:CredReadDomainCredentialsA=advapi32.CredReadDomainCredentialsA") +#pragma comment(linker, "/EXPORT:CredReadDomainCredentialsW=advapi32.CredReadDomainCredentialsW") +#pragma comment(linker, "/EXPORT:CredReadW=advapi32.CredReadW") +#pragma comment(linker, "/EXPORT:CredRenameA=advapi32.CredRenameA") +#pragma comment(linker, "/EXPORT:CredRenameW=advapi32.CredRenameW") +#pragma comment(linker, "/EXPORT:CredRestoreCredentials=advapi32.CredRestoreCredentials") +#pragma comment(linker, "/EXPORT:CredUnmarshalCredentialA=advapi32.CredUnmarshalCredentialA") +#pragma comment(linker, "/EXPORT:CredUnmarshalCredentialW=advapi32.CredUnmarshalCredentialW") +#pragma comment(linker, "/EXPORT:CredUnprotectA=advapi32.CredUnprotectA") +#pragma comment(linker, "/EXPORT:CredUnprotectW=advapi32.CredUnprotectW") +#pragma comment(linker, "/EXPORT:CredWriteA=advapi32.CredWriteA") +#pragma comment(linker, "/EXPORT:CredWriteDomainCredentialsA=advapi32.CredWriteDomainCredentialsA") +#pragma comment(linker, "/EXPORT:CredWriteDomainCredentialsW=advapi32.CredWriteDomainCredentialsW") +#pragma comment(linker, "/EXPORT:CredWriteW=advapi32.CredWriteW") +#pragma comment(linker, "/EXPORT:CredpConvertCredential=advapi32.CredpConvertCredential") +#pragma comment(linker, "/EXPORT:CredpConvertOneCredentialSize=advapi32.CredpConvertOneCredentialSize") +#pragma comment(linker, "/EXPORT:CredpConvertTargetInfo=advapi32.CredpConvertTargetInfo") +#pragma comment(linker, "/EXPORT:CredpDecodeCredential=advapi32.CredpDecodeCredential") +#pragma comment(linker, "/EXPORT:CredpEncodeCredential=advapi32.CredpEncodeCredential") +#pragma comment(linker, "/EXPORT:CredpEncodeSecret=advapi32.CredpEncodeSecret") +#pragma comment(linker, "/EXPORT:CryptAcquireContextA=advapi32.CryptAcquireContextA") +#pragma comment(linker, "/EXPORT:CryptAcquireContextW=advapi32.CryptAcquireContextW") +#pragma comment(linker, "/EXPORT:CryptContextAddRef=advapi32.CryptContextAddRef") +#pragma comment(linker, "/EXPORT:CryptCreateHash=advapi32.CryptCreateHash") +#pragma comment(linker, "/EXPORT:CryptDecrypt=advapi32.CryptDecrypt") +#pragma comment(linker, "/EXPORT:CryptDeriveKey=advapi32.CryptDeriveKey") +#pragma comment(linker, "/EXPORT:CryptDestroyHash=advapi32.CryptDestroyHash") +#pragma comment(linker, "/EXPORT:CryptDestroyKey=advapi32.CryptDestroyKey") +#pragma comment(linker, "/EXPORT:CryptDuplicateHash=advapi32.CryptDuplicateHash") +#pragma comment(linker, "/EXPORT:CryptDuplicateKey=advapi32.CryptDuplicateKey") +#pragma comment(linker, "/EXPORT:CryptEncrypt=advapi32.CryptEncrypt") +#pragma comment(linker, "/EXPORT:CryptEnumProviderTypesA=advapi32.CryptEnumProviderTypesA") +#pragma comment(linker, "/EXPORT:CryptEnumProviderTypesW=advapi32.CryptEnumProviderTypesW") +#pragma comment(linker, "/EXPORT:CryptEnumProvidersA=advapi32.CryptEnumProvidersA") +#pragma comment(linker, "/EXPORT:CryptEnumProvidersW=advapi32.CryptEnumProvidersW") +#pragma comment(linker, "/EXPORT:CryptExportKey=advapi32.CryptExportKey") +#pragma comment(linker, "/EXPORT:CryptGenKey=advapi32.CryptGenKey") +#pragma comment(linker, "/EXPORT:CryptGenRandom=advapi32.CryptGenRandom") +#pragma comment(linker, "/EXPORT:CryptGetDefaultProviderA=advapi32.CryptGetDefaultProviderA") +#pragma comment(linker, "/EXPORT:CryptGetDefaultProviderW=advapi32.CryptGetDefaultProviderW") +#pragma comment(linker, "/EXPORT:CryptGetHashParam=advapi32.CryptGetHashParam") +#pragma comment(linker, "/EXPORT:CryptGetKeyParam=advapi32.CryptGetKeyParam") +#pragma comment(linker, "/EXPORT:CryptGetProvParam=advapi32.CryptGetProvParam") +#pragma comment(linker, "/EXPORT:CryptGetUserKey=advapi32.CryptGetUserKey") +#pragma comment(linker, "/EXPORT:CryptHashData=advapi32.CryptHashData") +#pragma comment(linker, "/EXPORT:CryptHashSessionKey=advapi32.CryptHashSessionKey") +#pragma comment(linker, "/EXPORT:CryptImportKey=advapi32.CryptImportKey") +#pragma comment(linker, "/EXPORT:CryptReleaseContext=advapi32.CryptReleaseContext") +#pragma comment(linker, "/EXPORT:CryptSetHashParam=advapi32.CryptSetHashParam") +#pragma comment(linker, "/EXPORT:CryptSetKeyParam=advapi32.CryptSetKeyParam") +#pragma comment(linker, "/EXPORT:CryptSetProvParam=advapi32.CryptSetProvParam") +#pragma comment(linker, "/EXPORT:CryptSetProviderA=advapi32.CryptSetProviderA") +#pragma comment(linker, "/EXPORT:CryptSetProviderExA=advapi32.CryptSetProviderExA") +#pragma comment(linker, "/EXPORT:CryptSetProviderExW=advapi32.CryptSetProviderExW") +#pragma comment(linker, "/EXPORT:CryptSetProviderW=advapi32.CryptSetProviderW") +#pragma comment(linker, "/EXPORT:CryptSignHashA=advapi32.CryptSignHashA") +#pragma comment(linker, "/EXPORT:CryptSignHashW=advapi32.CryptSignHashW") +#pragma comment(linker, "/EXPORT:CryptVerifySignatureA=advapi32.CryptVerifySignatureA") +#pragma comment(linker, "/EXPORT:CryptVerifySignatureW=advapi32.CryptVerifySignatureW") +#pragma comment(linker, "/EXPORT:DecryptFileA=advapi32.DecryptFileA") +#pragma comment(linker, "/EXPORT:DecryptFileW=advapi32.DecryptFileW") +#pragma comment(linker, "/EXPORT:DeleteAce=advapi32.DeleteAce") +#pragma comment(linker, "/EXPORT:DeleteService=advapi32.DeleteService") +#pragma comment(linker, "/EXPORT:DeregisterEventSource=advapi32.DeregisterEventSource") +#pragma comment(linker, "/EXPORT:DestroyPrivateObjectSecurity=advapi32.DestroyPrivateObjectSecurity") +#pragma comment(linker, "/EXPORT:DuplicateEncryptionInfoFile=advapi32.DuplicateEncryptionInfoFile") +#pragma comment(linker, "/EXPORT:DuplicateToken=advapi32.DuplicateToken") +#pragma comment(linker, "/EXPORT:DuplicateTokenEx=advapi32.DuplicateTokenEx") +#pragma comment(linker, "/EXPORT:ElfBackupEventLogFileA=advapi32.ElfBackupEventLogFileA") +#pragma comment(linker, "/EXPORT:ElfBackupEventLogFileW=advapi32.ElfBackupEventLogFileW") +#pragma comment(linker, "/EXPORT:ElfChangeNotify=advapi32.ElfChangeNotify") +#pragma comment(linker, "/EXPORT:ElfClearEventLogFileA=advapi32.ElfClearEventLogFileA") +#pragma comment(linker, "/EXPORT:ElfClearEventLogFileW=advapi32.ElfClearEventLogFileW") +#pragma comment(linker, "/EXPORT:ElfCloseEventLog=advapi32.ElfCloseEventLog") +#pragma comment(linker, "/EXPORT:ElfDeregisterEventSource=advapi32.ElfDeregisterEventSource") +#pragma comment(linker, "/EXPORT:ElfFlushEventLog=advapi32.ElfFlushEventLog") +#pragma comment(linker, "/EXPORT:ElfNumberOfRecords=advapi32.ElfNumberOfRecords") +#pragma comment(linker, "/EXPORT:ElfOldestRecord=advapi32.ElfOldestRecord") +#pragma comment(linker, "/EXPORT:ElfOpenBackupEventLogA=advapi32.ElfOpenBackupEventLogA") +#pragma comment(linker, "/EXPORT:ElfOpenBackupEventLogW=advapi32.ElfOpenBackupEventLogW") +#pragma comment(linker, "/EXPORT:ElfOpenEventLogA=advapi32.ElfOpenEventLogA") +#pragma comment(linker, "/EXPORT:ElfOpenEventLogW=advapi32.ElfOpenEventLogW") +#pragma comment(linker, "/EXPORT:ElfReadEventLogA=advapi32.ElfReadEventLogA") +#pragma comment(linker, "/EXPORT:ElfReadEventLogW=advapi32.ElfReadEventLogW") +#pragma comment(linker, "/EXPORT:ElfRegisterEventSourceA=advapi32.ElfRegisterEventSourceA") +#pragma comment(linker, "/EXPORT:ElfRegisterEventSourceW=advapi32.ElfRegisterEventSourceW") +#pragma comment(linker, "/EXPORT:ElfReportEventA=advapi32.ElfReportEventA") +#pragma comment(linker, "/EXPORT:ElfReportEventAndSourceW=advapi32.ElfReportEventAndSourceW") +#pragma comment(linker, "/EXPORT:ElfReportEventW=advapi32.ElfReportEventW") +#pragma comment(linker, "/EXPORT:EnableTrace=advapi32.EnableTrace") +#pragma comment(linker, "/EXPORT:EnableTraceEx=advapi32.EnableTraceEx") +#pragma comment(linker, "/EXPORT:EnableTraceEx2=advapi32.EnableTraceEx2") +#pragma comment(linker, "/EXPORT:EncryptFileA=advapi32.EncryptFileA") +#pragma comment(linker, "/EXPORT:EncryptFileW=advapi32.EncryptFileW") +#pragma comment(linker, "/EXPORT:EncryptedFileKeyInfo=advapi32.EncryptedFileKeyInfo") +#pragma comment(linker, "/EXPORT:EncryptionDisable=advapi32.EncryptionDisable") +#pragma comment(linker, "/EXPORT:EnumDependentServicesA=advapi32.EnumDependentServicesA") +#pragma comment(linker, "/EXPORT:EnumDependentServicesW=advapi32.EnumDependentServicesW") +#pragma comment(linker, "/EXPORT:EnumServiceGroupW=advapi32.EnumServiceGroupW") +#pragma comment(linker, "/EXPORT:EnumServicesStatusA=advapi32.EnumServicesStatusA") +#pragma comment(linker, "/EXPORT:EnumServicesStatusExA=advapi32.EnumServicesStatusExA") +#pragma comment(linker, "/EXPORT:EnumServicesStatusExW=advapi32.EnumServicesStatusExW") +#pragma comment(linker, "/EXPORT:EnumServicesStatusW=advapi32.EnumServicesStatusW") +#pragma comment(linker, "/EXPORT:EnumerateTraceGuids=advapi32.EnumerateTraceGuids") +#pragma comment(linker, "/EXPORT:EnumerateTraceGuidsEx=advapi32.EnumerateTraceGuidsEx") +#pragma comment(linker, "/EXPORT:EqualDomainSid=advapi32.EqualDomainSid") +#pragma comment(linker, "/EXPORT:EqualPrefixSid=advapi32.EqualPrefixSid") +#pragma comment(linker, "/EXPORT:EqualSid=advapi32.EqualSid") +#pragma comment(linker, "/EXPORT:EventAccessControl=advapi32.EventAccessControl") +#pragma comment(linker, "/EXPORT:EventAccessQuery=advapi32.EventAccessQuery") +#pragma comment(linker, "/EXPORT:EventAccessRemove=advapi32.EventAccessRemove") +#pragma comment(linker, "/EXPORT:EventActivityIdControl=advapi32.EventActivityIdControl") +#pragma comment(linker, "/EXPORT:EventEnabled=advapi32.EventEnabled") +#pragma comment(linker, "/EXPORT:EventProviderEnabled=advapi32.EventProviderEnabled") +#pragma comment(linker, "/EXPORT:EventRegister=advapi32.EventRegister") +//#pragma comment(linker, "/EXPORT:EventSetInformation=advapi32.EventSetInformation") +#pragma comment(linker, "/EXPORT:EventUnregister=advapi32.EventUnregister") +#pragma comment(linker, "/EXPORT:EventWrite=advapi32.EventWrite") +#pragma comment(linker, "/EXPORT:EventWriteEndScenario=advapi32.EventWriteEndScenario") +#pragma comment(linker, "/EXPORT:EventWriteEx=advapi32.EventWriteEx") +#pragma comment(linker, "/EXPORT:EventWriteStartScenario=advapi32.EventWriteStartScenario") +#pragma comment(linker, "/EXPORT:EventWriteString=advapi32.EventWriteString") +#pragma comment(linker, "/EXPORT:EventWriteTransfer=advapi32.EventWriteTransfer") +#pragma comment(linker, "/EXPORT:FileEncryptionStatusA=advapi32.FileEncryptionStatusA") +#pragma comment(linker, "/EXPORT:FileEncryptionStatusW=advapi32.FileEncryptionStatusW") +#pragma comment(linker, "/EXPORT:FindFirstFreeAce=advapi32.FindFirstFreeAce") +#pragma comment(linker, "/EXPORT:FlushEfsCache=advapi32.FlushEfsCache") +#pragma comment(linker, "/EXPORT:FlushTraceA=advapi32.FlushTraceA") +#pragma comment(linker, "/EXPORT:FlushTraceW=advapi32.FlushTraceW") +#pragma comment(linker, "/EXPORT:FreeEncryptedFileKeyInfo=advapi32.FreeEncryptedFileKeyInfo") +#pragma comment(linker, "/EXPORT:FreeEncryptedFileMetadata=advapi32.FreeEncryptedFileMetadata") +#pragma comment(linker, "/EXPORT:FreeEncryptionCertificateHashList=advapi32.FreeEncryptionCertificateHashList") +#pragma comment(linker, "/EXPORT:FreeInheritedFromArray=advapi32.FreeInheritedFromArray") +#pragma comment(linker, "/EXPORT:FreeSid=advapi32.FreeSid") +#pragma comment(linker, "/EXPORT:GetAccessPermissionsForObjectA=advapi32.GetAccessPermissionsForObjectA") +#pragma comment(linker, "/EXPORT:GetAccessPermissionsForObjectW=advapi32.GetAccessPermissionsForObjectW") +#pragma comment(linker, "/EXPORT:GetAce=advapi32.GetAce") +#pragma comment(linker, "/EXPORT:GetAclInformation=advapi32.GetAclInformation") +#pragma comment(linker, "/EXPORT:GetAuditedPermissionsFromAclA=advapi32.GetAuditedPermissionsFromAclA") +#pragma comment(linker, "/EXPORT:GetAuditedPermissionsFromAclW=advapi32.GetAuditedPermissionsFromAclW") +#pragma comment(linker, "/EXPORT:GetCurrentHwProfileA=advapi32.GetCurrentHwProfileA") +#pragma comment(linker, "/EXPORT:GetCurrentHwProfileW=advapi32.GetCurrentHwProfileW") +#pragma comment(linker, "/EXPORT:GetEffectiveRightsFromAclA=advapi32.GetEffectiveRightsFromAclA") +#pragma comment(linker, "/EXPORT:GetEffectiveRightsFromAclW=advapi32.GetEffectiveRightsFromAclW") +#pragma comment(linker, "/EXPORT:GetEncryptedFileMetadata=advapi32.GetEncryptedFileMetadata") +#pragma comment(linker, "/EXPORT:GetEventLogInformation=advapi32.GetEventLogInformation") +#pragma comment(linker, "/EXPORT:GetExplicitEntriesFromAclA=advapi32.GetExplicitEntriesFromAclA") +#pragma comment(linker, "/EXPORT:GetExplicitEntriesFromAclW=advapi32.GetExplicitEntriesFromAclW") +#pragma comment(linker, "/EXPORT:GetFileSecurityA=advapi32.GetFileSecurityA") +#pragma comment(linker, "/EXPORT:GetFileSecurityW=advapi32.GetFileSecurityW") +#pragma comment(linker, "/EXPORT:GetInformationCodeAuthzLevelW=advapi32.GetInformationCodeAuthzLevelW") +#pragma comment(linker, "/EXPORT:GetInformationCodeAuthzPolicyW=advapi32.GetInformationCodeAuthzPolicyW") +#pragma comment(linker, "/EXPORT:GetInheritanceSourceA=advapi32.GetInheritanceSourceA") +#pragma comment(linker, "/EXPORT:GetInheritanceSourceW=advapi32.GetInheritanceSourceW") +#pragma comment(linker, "/EXPORT:GetKernelObjectSecurity=advapi32.GetKernelObjectSecurity") +#pragma comment(linker, "/EXPORT:GetLengthSid=advapi32.GetLengthSid") +#pragma comment(linker, "/EXPORT:GetLocalManagedApplicationData=advapi32.GetLocalManagedApplicationData") +#pragma comment(linker, "/EXPORT:GetLocalManagedApplications=advapi32.GetLocalManagedApplications") +#pragma comment(linker, "/EXPORT:GetManagedApplicationCategories=advapi32.GetManagedApplicationCategories") +#pragma comment(linker, "/EXPORT:GetManagedApplications=advapi32.GetManagedApplications") +#pragma comment(linker, "/EXPORT:GetMultipleTrusteeA=advapi32.GetMultipleTrusteeA") +#pragma comment(linker, "/EXPORT:GetMultipleTrusteeOperationA=advapi32.GetMultipleTrusteeOperationA") +#pragma comment(linker, "/EXPORT:GetMultipleTrusteeOperationW=advapi32.GetMultipleTrusteeOperationW") +#pragma comment(linker, "/EXPORT:GetMultipleTrusteeW=advapi32.GetMultipleTrusteeW") +#pragma comment(linker, "/EXPORT:GetNamedSecurityInfoA=advapi32.GetNamedSecurityInfoA") +#pragma comment(linker, "/EXPORT:GetNamedSecurityInfoExA=advapi32.GetNamedSecurityInfoExA") +#pragma comment(linker, "/EXPORT:GetNamedSecurityInfoExW=advapi32.GetNamedSecurityInfoExW") +#pragma comment(linker, "/EXPORT:GetNamedSecurityInfoW=advapi32.GetNamedSecurityInfoW") +#pragma comment(linker, "/EXPORT:GetNumberOfEventLogRecords=advapi32.GetNumberOfEventLogRecords") +#pragma comment(linker, "/EXPORT:GetOldestEventLogRecord=advapi32.GetOldestEventLogRecord") +#pragma comment(linker, "/EXPORT:GetOverlappedAccessResults=advapi32.GetOverlappedAccessResults") +#pragma comment(linker, "/EXPORT:GetPrivateObjectSecurity=advapi32.GetPrivateObjectSecurity") +#pragma comment(linker, "/EXPORT:GetSecurityDescriptorControl=advapi32.GetSecurityDescriptorControl") +#pragma comment(linker, "/EXPORT:GetSecurityDescriptorDacl=advapi32.GetSecurityDescriptorDacl") +#pragma comment(linker, "/EXPORT:GetSecurityDescriptorGroup=advapi32.GetSecurityDescriptorGroup") +#pragma comment(linker, "/EXPORT:GetSecurityDescriptorLength=advapi32.GetSecurityDescriptorLength") +#pragma comment(linker, "/EXPORT:GetSecurityDescriptorOwner=advapi32.GetSecurityDescriptorOwner") +#pragma comment(linker, "/EXPORT:GetSecurityDescriptorRMControl=advapi32.GetSecurityDescriptorRMControl") +#pragma comment(linker, "/EXPORT:GetSecurityDescriptorSacl=advapi32.GetSecurityDescriptorSacl") +#pragma comment(linker, "/EXPORT:GetSecurityInfo=advapi32.GetSecurityInfo") +#pragma comment(linker, "/EXPORT:GetSecurityInfoExA=advapi32.GetSecurityInfoExA") +#pragma comment(linker, "/EXPORT:GetSecurityInfoExW=advapi32.GetSecurityInfoExW") +#pragma comment(linker, "/EXPORT:GetServiceDisplayNameA=advapi32.GetServiceDisplayNameA") +#pragma comment(linker, "/EXPORT:GetServiceDisplayNameW=advapi32.GetServiceDisplayNameW") +#pragma comment(linker, "/EXPORT:GetServiceKeyNameA=advapi32.GetServiceKeyNameA") +#pragma comment(linker, "/EXPORT:GetServiceKeyNameW=advapi32.GetServiceKeyNameW") +#pragma comment(linker, "/EXPORT:GetSidIdentifierAuthority=advapi32.GetSidIdentifierAuthority") +#pragma comment(linker, "/EXPORT:GetSidLengthRequired=advapi32.GetSidLengthRequired") +#pragma comment(linker, "/EXPORT:GetSidSubAuthority=advapi32.GetSidSubAuthority") +#pragma comment(linker, "/EXPORT:GetSidSubAuthorityCount=advapi32.GetSidSubAuthorityCount") +#pragma comment(linker, "/EXPORT:GetThreadWaitChain=advapi32.GetThreadWaitChain") +#pragma comment(linker, "/EXPORT:GetTokenInformation=advapi32.GetTokenInformation") +#pragma comment(linker, "/EXPORT:GetTraceEnableFlags=advapi32.GetTraceEnableFlags") +#pragma comment(linker, "/EXPORT:GetTraceEnableLevel=advapi32.GetTraceEnableLevel") +#pragma comment(linker, "/EXPORT:GetTraceLoggerHandle=advapi32.GetTraceLoggerHandle") +#pragma comment(linker, "/EXPORT:GetTrusteeFormA=advapi32.GetTrusteeFormA") +#pragma comment(linker, "/EXPORT:GetTrusteeFormW=advapi32.GetTrusteeFormW") +#pragma comment(linker, "/EXPORT:GetTrusteeNameA=advapi32.GetTrusteeNameA") +#pragma comment(linker, "/EXPORT:GetTrusteeNameW=advapi32.GetTrusteeNameW") +#pragma comment(linker, "/EXPORT:GetTrusteeTypeA=advapi32.GetTrusteeTypeA") +#pragma comment(linker, "/EXPORT:GetTrusteeTypeW=advapi32.GetTrusteeTypeW") +#pragma comment(linker, "/EXPORT:GetUserNameA=advapi32.GetUserNameA") +#pragma comment(linker, "/EXPORT:GetUserNameW=advapi32.GetUserNameW") +#pragma comment(linker, "/EXPORT:GetWindowsAccountDomainSid=advapi32.GetWindowsAccountDomainSid") +#pragma comment(linker, "/EXPORT:I_QueryTagInformation=advapi32.I_QueryTagInformation") +#pragma comment(linker, "/EXPORT:I_ScGetCurrentGroupStateW=advapi32.I_ScGetCurrentGroupStateW") +#pragma comment(linker, "/EXPORT:I_ScIsSecurityProcess=advapi32.I_ScIsSecurityProcess") +#pragma comment(linker, "/EXPORT:I_ScPnPGetServiceName=advapi32.I_ScPnPGetServiceName") +#pragma comment(linker, "/EXPORT:I_ScQueryServiceConfig=advapi32.I_ScQueryServiceConfig") +#pragma comment(linker, "/EXPORT:I_ScSendPnPMessage=advapi32.I_ScSendPnPMessage") +#pragma comment(linker, "/EXPORT:I_ScSendTSMessage=advapi32.I_ScSendTSMessage") +#pragma comment(linker, "/EXPORT:I_ScSetServiceBitsA=advapi32.I_ScSetServiceBitsA") +#pragma comment(linker, "/EXPORT:I_ScSetServiceBitsW=advapi32.I_ScSetServiceBitsW") +#pragma comment(linker, "/EXPORT:I_ScValidatePnPService=advapi32.I_ScValidatePnPService") +#pragma comment(linker, "/EXPORT:IdentifyCodeAuthzLevelW=advapi32.IdentifyCodeAuthzLevelW") +#pragma comment(linker, "/EXPORT:ImpersonateAnonymousToken=advapi32.ImpersonateAnonymousToken") +#pragma comment(linker, "/EXPORT:ImpersonateLoggedOnUser=advapi32.ImpersonateLoggedOnUser") +#pragma comment(linker, "/EXPORT:ImpersonateNamedPipeClient=advapi32.ImpersonateNamedPipeClient") +#pragma comment(linker, "/EXPORT:ImpersonateSelf=advapi32.ImpersonateSelf") +#pragma comment(linker, "/EXPORT:InitializeAcl=advapi32.InitializeAcl") +#pragma comment(linker, "/EXPORT:InitializeSecurityDescriptor=advapi32.InitializeSecurityDescriptor") +#pragma comment(linker, "/EXPORT:InitializeSid=advapi32.InitializeSid") +#pragma comment(linker, "/EXPORT:InitiateShutdownA=advapi32.InitiateShutdownA") +#pragma comment(linker, "/EXPORT:InitiateShutdownW=advapi32.InitiateShutdownW") +#pragma comment(linker, "/EXPORT:InitiateSystemShutdownA=advapi32.InitiateSystemShutdownA") +#pragma comment(linker, "/EXPORT:InitiateSystemShutdownExA=advapi32.InitiateSystemShutdownExA") +#pragma comment(linker, "/EXPORT:InitiateSystemShutdownExW=advapi32.InitiateSystemShutdownExW") +#pragma comment(linker, "/EXPORT:InitiateSystemShutdownW=advapi32.InitiateSystemShutdownW") +#pragma comment(linker, "/EXPORT:InstallApplication=advapi32.InstallApplication") +#pragma comment(linker, "/EXPORT:IsTextUnicode=advapi32.IsTextUnicode") +#pragma comment(linker, "/EXPORT:IsTokenRestricted=advapi32.IsTokenRestricted") +#pragma comment(linker, "/EXPORT:IsTokenUntrusted=advapi32.IsTokenUntrusted") +#pragma comment(linker, "/EXPORT:IsValidAcl=advapi32.IsValidAcl") +#pragma comment(linker, "/EXPORT:IsValidRelativeSecurityDescriptor=advapi32.IsValidRelativeSecurityDescriptor") +#pragma comment(linker, "/EXPORT:IsValidSecurityDescriptor=advapi32.IsValidSecurityDescriptor") +#pragma comment(linker, "/EXPORT:IsValidSid=advapi32.IsValidSid") +#pragma comment(linker, "/EXPORT:IsWellKnownSid=advapi32.IsWellKnownSid") +#pragma comment(linker, "/EXPORT:LockServiceDatabase=advapi32.LockServiceDatabase") +#pragma comment(linker, "/EXPORT:LogonUserA=advapi32.LogonUserA") +#pragma comment(linker, "/EXPORT:LogonUserExA=advapi32.LogonUserExA") +#pragma comment(linker, "/EXPORT:LogonUserExExW=advapi32.LogonUserExExW") +#pragma comment(linker, "/EXPORT:LogonUserExW=advapi32.LogonUserExW") +#pragma comment(linker, "/EXPORT:LogonUserW=advapi32.LogonUserW") +#pragma comment(linker, "/EXPORT:LookupAccountNameA=advapi32.LookupAccountNameA") +#pragma comment(linker, "/EXPORT:LookupAccountNameW=advapi32.LookupAccountNameW") +#pragma comment(linker, "/EXPORT:LookupAccountSidA=advapi32.LookupAccountSidA") +#pragma comment(linker, "/EXPORT:LookupAccountSidW=advapi32.LookupAccountSidW") +#pragma comment(linker, "/EXPORT:LookupPrivilegeDisplayNameA=advapi32.LookupPrivilegeDisplayNameA") +#pragma comment(linker, "/EXPORT:LookupPrivilegeDisplayNameW=advapi32.LookupPrivilegeDisplayNameW") +#pragma comment(linker, "/EXPORT:LookupPrivilegeNameA=advapi32.LookupPrivilegeNameA") +#pragma comment(linker, "/EXPORT:LookupPrivilegeNameW=advapi32.LookupPrivilegeNameW") +#pragma comment(linker, "/EXPORT:LookupPrivilegeValueA=advapi32.LookupPrivilegeValueA") +#pragma comment(linker, "/EXPORT:LookupPrivilegeValueW=advapi32.LookupPrivilegeValueW") +#pragma comment(linker, "/EXPORT:LookupSecurityDescriptorPartsA=advapi32.LookupSecurityDescriptorPartsA") +#pragma comment(linker, "/EXPORT:LookupSecurityDescriptorPartsW=advapi32.LookupSecurityDescriptorPartsW") +#pragma comment(linker, "/EXPORT:LsaAddAccountRights=advapi32.LsaAddAccountRights") +#pragma comment(linker, "/EXPORT:LsaAddPrivilegesToAccount=advapi32.LsaAddPrivilegesToAccount") +#pragma comment(linker, "/EXPORT:LsaClearAuditLog=advapi32.LsaClearAuditLog") +#pragma comment(linker, "/EXPORT:LsaClose=advapi32.LsaClose") +#pragma comment(linker, "/EXPORT:LsaCreateAccount=advapi32.LsaCreateAccount") +#pragma comment(linker, "/EXPORT:LsaCreateSecret=advapi32.LsaCreateSecret") +#pragma comment(linker, "/EXPORT:LsaCreateTrustedDomain=advapi32.LsaCreateTrustedDomain") +#pragma comment(linker, "/EXPORT:LsaCreateTrustedDomainEx=advapi32.LsaCreateTrustedDomainEx") +#pragma comment(linker, "/EXPORT:LsaDelete=advapi32.LsaDelete") +#pragma comment(linker, "/EXPORT:LsaDeleteTrustedDomain=advapi32.LsaDeleteTrustedDomain") +#pragma comment(linker, "/EXPORT:LsaEnumerateAccountRights=advapi32.LsaEnumerateAccountRights") +#pragma comment(linker, "/EXPORT:LsaEnumerateAccounts=advapi32.LsaEnumerateAccounts") +#pragma comment(linker, "/EXPORT:LsaEnumerateAccountsWithUserRight=advapi32.LsaEnumerateAccountsWithUserRight") +#pragma comment(linker, "/EXPORT:LsaEnumeratePrivileges=advapi32.LsaEnumeratePrivileges") +#pragma comment(linker, "/EXPORT:LsaEnumeratePrivilegesOfAccount=advapi32.LsaEnumeratePrivilegesOfAccount") +#pragma comment(linker, "/EXPORT:LsaEnumerateTrustedDomains=advapi32.LsaEnumerateTrustedDomains") +#pragma comment(linker, "/EXPORT:LsaEnumerateTrustedDomainsEx=advapi32.LsaEnumerateTrustedDomainsEx") +#pragma comment(linker, "/EXPORT:LsaFreeMemory=advapi32.LsaFreeMemory") +#pragma comment(linker, "/EXPORT:LsaGetQuotasForAccount=advapi32.LsaGetQuotasForAccount") +#pragma comment(linker, "/EXPORT:LsaGetRemoteUserName=advapi32.LsaGetRemoteUserName") +#pragma comment(linker, "/EXPORT:LsaGetSystemAccessAccount=advapi32.LsaGetSystemAccessAccount") +#pragma comment(linker, "/EXPORT:LsaGetUserName=advapi32.LsaGetUserName") +#pragma comment(linker, "/EXPORT:LsaICLookupNames=advapi32.LsaICLookupNames") +#pragma comment(linker, "/EXPORT:LsaICLookupNamesWithCreds=advapi32.LsaICLookupNamesWithCreds") +#pragma comment(linker, "/EXPORT:LsaICLookupSids=advapi32.LsaICLookupSids") +#pragma comment(linker, "/EXPORT:LsaICLookupSidsWithCreds=advapi32.LsaICLookupSidsWithCreds") +#pragma comment(linker, "/EXPORT:LsaInvokeTrustScanner=advapi32.LsaInvokeTrustScanner") +#pragma comment(linker, "/EXPORT:LsaLookupNames=advapi32.LsaLookupNames") +#pragma comment(linker, "/EXPORT:LsaLookupNames2=advapi32.LsaLookupNames2") +#pragma comment(linker, "/EXPORT:LsaLookupPrivilegeDisplayName=advapi32.LsaLookupPrivilegeDisplayName") +#pragma comment(linker, "/EXPORT:LsaLookupPrivilegeName=advapi32.LsaLookupPrivilegeName") +#pragma comment(linker, "/EXPORT:LsaLookupPrivilegeValue=advapi32.LsaLookupPrivilegeValue") +#pragma comment(linker, "/EXPORT:LsaLookupSids=advapi32.LsaLookupSids") +#pragma comment(linker, "/EXPORT:LsaManageSidNameMapping=advapi32.LsaManageSidNameMapping") +#pragma comment(linker, "/EXPORT:LsaNtStatusToWinError=advapi32.LsaNtStatusToWinError") +#pragma comment(linker, "/EXPORT:LsaOpenAccount=advapi32.LsaOpenAccount") +#pragma comment(linker, "/EXPORT:LsaOpenPolicy=advapi32.LsaOpenPolicy") +#pragma comment(linker, "/EXPORT:LsaOpenPolicySce=advapi32.LsaOpenPolicySce") +#pragma comment(linker, "/EXPORT:LsaOpenSecret=advapi32.LsaOpenSecret") +#pragma comment(linker, "/EXPORT:LsaOpenTrustedDomain=advapi32.LsaOpenTrustedDomain") +#pragma comment(linker, "/EXPORT:LsaOpenTrustedDomainByName=advapi32.LsaOpenTrustedDomainByName") +#pragma comment(linker, "/EXPORT:LsaQueryDomainInformationPolicy=advapi32.LsaQueryDomainInformationPolicy") +#pragma comment(linker, "/EXPORT:LsaQueryForestTrustInformation=advapi32.LsaQueryForestTrustInformation") +#pragma comment(linker, "/EXPORT:LsaQueryForestTrustInformation2=advapi32.LsaQueryForestTrustInformation2") +#pragma comment(linker, "/EXPORT:LsaQueryInfoTrustedDomain=advapi32.LsaQueryInfoTrustedDomain") +#pragma comment(linker, "/EXPORT:LsaQueryInformationPolicy=advapi32.LsaQueryInformationPolicy") +#pragma comment(linker, "/EXPORT:LsaQuerySecret=advapi32.LsaQuerySecret") +#pragma comment(linker, "/EXPORT:LsaQuerySecurityObject=advapi32.LsaQuerySecurityObject") +#pragma comment(linker, "/EXPORT:LsaQueryTrustedDomainInfo=advapi32.LsaQueryTrustedDomainInfo") +#pragma comment(linker, "/EXPORT:LsaQueryTrustedDomainInfoByName=advapi32.LsaQueryTrustedDomainInfoByName") +#pragma comment(linker, "/EXPORT:LsaRemoveAccountRights=advapi32.LsaRemoveAccountRights") +#pragma comment(linker, "/EXPORT:LsaRemovePrivilegesFromAccount=advapi32.LsaRemovePrivilegesFromAccount") +#pragma comment(linker, "/EXPORT:LsaRetrievePrivateData=advapi32.LsaRetrievePrivateData") +#pragma comment(linker, "/EXPORT:LsaSetDomainInformationPolicy=advapi32.LsaSetDomainInformationPolicy") +#pragma comment(linker, "/EXPORT:LsaSetForestTrustInformation=advapi32.LsaSetForestTrustInformation") +#pragma comment(linker, "/EXPORT:LsaSetForestTrustInformation2=advapi32.LsaSetForestTrustInformation2") +#pragma comment(linker, "/EXPORT:LsaSetInformationPolicy=advapi32.LsaSetInformationPolicy") +#pragma comment(linker, "/EXPORT:LsaSetInformationTrustedDomain=advapi32.LsaSetInformationTrustedDomain") +#pragma comment(linker, "/EXPORT:LsaSetQuotasForAccount=advapi32.LsaSetQuotasForAccount") +#pragma comment(linker, "/EXPORT:LsaSetSecret=advapi32.LsaSetSecret") +#pragma comment(linker, "/EXPORT:LsaSetSecurityObject=advapi32.LsaSetSecurityObject") +#pragma comment(linker, "/EXPORT:LsaSetSystemAccessAccount=advapi32.LsaSetSystemAccessAccount") +#pragma comment(linker, "/EXPORT:LsaSetTrustedDomainInfoByName=advapi32.LsaSetTrustedDomainInfoByName") +#pragma comment(linker, "/EXPORT:LsaSetTrustedDomainInformation=advapi32.LsaSetTrustedDomainInformation") +#pragma comment(linker, "/EXPORT:LsaStorePrivateData=advapi32.LsaStorePrivateData") +#pragma comment(linker, "/EXPORT:MD4Final=advapi32.MD4Final") +#pragma comment(linker, "/EXPORT:MD4Init=advapi32.MD4Init") +#pragma comment(linker, "/EXPORT:MD4Update=advapi32.MD4Update") +#pragma comment(linker, "/EXPORT:MD5Final=advapi32.MD5Final") +#pragma comment(linker, "/EXPORT:MD5Init=advapi32.MD5Init") +#pragma comment(linker, "/EXPORT:MD5Update=advapi32.MD5Update") +#pragma comment(linker, "/EXPORT:MSChapSrvChangePassword=advapi32.MSChapSrvChangePassword") +#pragma comment(linker, "/EXPORT:MSChapSrvChangePassword2=advapi32.MSChapSrvChangePassword2") +#pragma comment(linker, "/EXPORT:MakeAbsoluteSD=advapi32.MakeAbsoluteSD") +#pragma comment(linker, "/EXPORT:MakeAbsoluteSD2=advapi32.MakeAbsoluteSD2") +#pragma comment(linker, "/EXPORT:MakeSelfRelativeSD=advapi32.MakeSelfRelativeSD") +#pragma comment(linker, "/EXPORT:MapGenericMask=advapi32.MapGenericMask") +#pragma comment(linker, "/EXPORT:NotifyBootConfigStatus=advapi32.NotifyBootConfigStatus") +#pragma comment(linker, "/EXPORT:NotifyChangeEventLog=advapi32.NotifyChangeEventLog") +#pragma comment(linker, "/EXPORT:NotifyServiceStatusChange=advapi32.NotifyServiceStatusChange") +#pragma comment(linker, "/EXPORT:NotifyServiceStatusChangeA=advapi32.NotifyServiceStatusChangeA") +#pragma comment(linker, "/EXPORT:NotifyServiceStatusChangeW=advapi32.NotifyServiceStatusChangeW") +#pragma comment(linker, "/EXPORT:ObjectCloseAuditAlarmA=advapi32.ObjectCloseAuditAlarmA") +#pragma comment(linker, "/EXPORT:ObjectCloseAuditAlarmW=advapi32.ObjectCloseAuditAlarmW") +#pragma comment(linker, "/EXPORT:ObjectDeleteAuditAlarmA=advapi32.ObjectDeleteAuditAlarmA") +#pragma comment(linker, "/EXPORT:ObjectDeleteAuditAlarmW=advapi32.ObjectDeleteAuditAlarmW") +#pragma comment(linker, "/EXPORT:ObjectOpenAuditAlarmA=advapi32.ObjectOpenAuditAlarmA") +#pragma comment(linker, "/EXPORT:ObjectOpenAuditAlarmW=advapi32.ObjectOpenAuditAlarmW") +#pragma comment(linker, "/EXPORT:ObjectPrivilegeAuditAlarmA=advapi32.ObjectPrivilegeAuditAlarmA") +#pragma comment(linker, "/EXPORT:ObjectPrivilegeAuditAlarmW=advapi32.ObjectPrivilegeAuditAlarmW") +#pragma comment(linker, "/EXPORT:OpenBackupEventLogA=advapi32.OpenBackupEventLogA") +#pragma comment(linker, "/EXPORT:OpenBackupEventLogW=advapi32.OpenBackupEventLogW") +#pragma comment(linker, "/EXPORT:OpenEncryptedFileRawA=advapi32.OpenEncryptedFileRawA") +#pragma comment(linker, "/EXPORT:OpenEncryptedFileRawW=advapi32.OpenEncryptedFileRawW") +#pragma comment(linker, "/EXPORT:OpenEventLogA=advapi32.OpenEventLogA") +#pragma comment(linker, "/EXPORT:OpenEventLogW=advapi32.OpenEventLogW") +#pragma comment(linker, "/EXPORT:OpenProcessToken=advapi32.OpenProcessToken") +#pragma comment(linker, "/EXPORT:OpenSCManagerA=advapi32.OpenSCManagerA") +#pragma comment(linker, "/EXPORT:OpenSCManagerW=advapi32.OpenSCManagerW") +#pragma comment(linker, "/EXPORT:OpenServiceA=advapi32.OpenServiceA") +#pragma comment(linker, "/EXPORT:OpenServiceW=advapi32.OpenServiceW") +#pragma comment(linker, "/EXPORT:OpenThreadToken=advapi32.OpenThreadToken") +#pragma comment(linker, "/EXPORT:OpenThreadWaitChainSession=advapi32.OpenThreadWaitChainSession") +#pragma comment(linker, "/EXPORT:OpenTraceA=advapi32.OpenTraceA") +#pragma comment(linker, "/EXPORT:OpenTraceW=advapi32.OpenTraceW") +#pragma comment(linker, "/EXPORT:PerfAddCounters=advapi32.PerfAddCounters") +#pragma comment(linker, "/EXPORT:PerfCloseQueryHandle=advapi32.PerfCloseQueryHandle") +#pragma comment(linker, "/EXPORT:PerfCreateInstance=advapi32.PerfCreateInstance") +#pragma comment(linker, "/EXPORT:PerfDecrementULongCounterValue=advapi32.PerfDecrementULongCounterValue") +#pragma comment(linker, "/EXPORT:PerfDecrementULongLongCounterValue=advapi32.PerfDecrementULongLongCounterValue") +#pragma comment(linker, "/EXPORT:PerfDeleteCounters=advapi32.PerfDeleteCounters") +#pragma comment(linker, "/EXPORT:PerfDeleteInstance=advapi32.PerfDeleteInstance") +#pragma comment(linker, "/EXPORT:PerfEnumerateCounterSet=advapi32.PerfEnumerateCounterSet") +#pragma comment(linker, "/EXPORT:PerfEnumerateCounterSetInstances=advapi32.PerfEnumerateCounterSetInstances") +#pragma comment(linker, "/EXPORT:PerfIncrementULongCounterValue=advapi32.PerfIncrementULongCounterValue") +#pragma comment(linker, "/EXPORT:PerfIncrementULongLongCounterValue=advapi32.PerfIncrementULongLongCounterValue") +#pragma comment(linker, "/EXPORT:PerfOpenQueryHandle=advapi32.PerfOpenQueryHandle") +#pragma comment(linker, "/EXPORT:PerfQueryCounterData=advapi32.PerfQueryCounterData") +#pragma comment(linker, "/EXPORT:PerfQueryCounterInfo=advapi32.PerfQueryCounterInfo") +#pragma comment(linker, "/EXPORT:PerfQueryCounterSetRegistrationInfo=advapi32.PerfQueryCounterSetRegistrationInfo") +#pragma comment(linker, "/EXPORT:PerfQueryInstance=advapi32.PerfQueryInstance") +#pragma comment(linker, "/EXPORT:PerfSetCounterRefValue=advapi32.PerfSetCounterRefValue") +#pragma comment(linker, "/EXPORT:PerfSetCounterSetInfo=advapi32.PerfSetCounterSetInfo") +#pragma comment(linker, "/EXPORT:PerfSetULongCounterValue=advapi32.PerfSetULongCounterValue") +#pragma comment(linker, "/EXPORT:PerfSetULongLongCounterValue=advapi32.PerfSetULongLongCounterValue") +#pragma comment(linker, "/EXPORT:PerfStartProvider=advapi32.PerfStartProvider") +#pragma comment(linker, "/EXPORT:PerfStartProviderEx=advapi32.PerfStartProviderEx") +#pragma comment(linker, "/EXPORT:PerfStopProvider=advapi32.PerfStopProvider") +#pragma comment(linker, "/EXPORT:PrivilegeCheck=advapi32.PrivilegeCheck") +#pragma comment(linker, "/EXPORT:PrivilegedServiceAuditAlarmA=advapi32.PrivilegedServiceAuditAlarmA") +#pragma comment(linker, "/EXPORT:PrivilegedServiceAuditAlarmW=advapi32.PrivilegedServiceAuditAlarmW") +#pragma comment(linker, "/EXPORT:ProcessIdleTasks=advapi32.ProcessIdleTasks") +#pragma comment(linker, "/EXPORT:ProcessIdleTasksW=advapi32.ProcessIdleTasksW") +#pragma comment(linker, "/EXPORT:ProcessTrace=advapi32.ProcessTrace") +#pragma comment(linker, "/EXPORT:QueryAllTracesA=advapi32.QueryAllTracesA") +#pragma comment(linker, "/EXPORT:QueryAllTracesW=advapi32.QueryAllTracesW") +#pragma comment(linker, "/EXPORT:QueryRecoveryAgentsOnEncryptedFile=advapi32.QueryRecoveryAgentsOnEncryptedFile") +#pragma comment(linker, "/EXPORT:QuerySecurityAccessMask=advapi32.QuerySecurityAccessMask") +#pragma comment(linker, "/EXPORT:QueryServiceConfig2A=advapi32.QueryServiceConfig2A") +#pragma comment(linker, "/EXPORT:QueryServiceConfig2W=advapi32.QueryServiceConfig2W") +#pragma comment(linker, "/EXPORT:QueryServiceConfigA=advapi32.QueryServiceConfigA") +#pragma comment(linker, "/EXPORT:QueryServiceConfigW=advapi32.QueryServiceConfigW") +#pragma comment(linker, "/EXPORT:QueryServiceLockStatusA=advapi32.QueryServiceLockStatusA") +#pragma comment(linker, "/EXPORT:QueryServiceLockStatusW=advapi32.QueryServiceLockStatusW") +#pragma comment(linker, "/EXPORT:QueryServiceObjectSecurity=advapi32.QueryServiceObjectSecurity") +#pragma comment(linker, "/EXPORT:QueryServiceStatus=advapi32.QueryServiceStatus") +#pragma comment(linker, "/EXPORT:QueryServiceStatusEx=advapi32.QueryServiceStatusEx") +#pragma comment(linker, "/EXPORT:QueryTraceA=advapi32.QueryTraceA") +#pragma comment(linker, "/EXPORT:QueryTraceW=advapi32.QueryTraceW") +#pragma comment(linker, "/EXPORT:QueryUsersOnEncryptedFile=advapi32.QueryUsersOnEncryptedFile") +#pragma comment(linker, "/EXPORT:ReadEncryptedFileRaw=advapi32.ReadEncryptedFileRaw") +#pragma comment(linker, "/EXPORT:ReadEventLogA=advapi32.ReadEventLogA") +#pragma comment(linker, "/EXPORT:ReadEventLogW=advapi32.ReadEventLogW") +#pragma comment(linker, "/EXPORT:RegCloseKey=advapi32.RegCloseKey") +#pragma comment(linker, "/EXPORT:RegConnectRegistryA=advapi32.RegConnectRegistryA") +#pragma comment(linker, "/EXPORT:RegConnectRegistryExA=advapi32.RegConnectRegistryExA") +#pragma comment(linker, "/EXPORT:RegConnectRegistryExW=advapi32.RegConnectRegistryExW") +#pragma comment(linker, "/EXPORT:RegConnectRegistryW=advapi32.RegConnectRegistryW") +#pragma comment(linker, "/EXPORT:RegCopyTreeA=advapi32.RegCopyTreeA") +#pragma comment(linker, "/EXPORT:RegCopyTreeW=advapi32.RegCopyTreeW") +#pragma comment(linker, "/EXPORT:RegCreateKeyA=advapi32.RegCreateKeyA") +#pragma comment(linker, "/EXPORT:RegCreateKeyExA=advapi32.RegCreateKeyExA") +#pragma comment(linker, "/EXPORT:RegCreateKeyExW=advapi32.RegCreateKeyExW") +#pragma comment(linker, "/EXPORT:RegCreateKeyTransactedA=advapi32.RegCreateKeyTransactedA") +#pragma comment(linker, "/EXPORT:RegCreateKeyTransactedW=advapi32.RegCreateKeyTransactedW") +#pragma comment(linker, "/EXPORT:RegCreateKeyW=advapi32.RegCreateKeyW") +#pragma comment(linker, "/EXPORT:RegDeleteKeyA=advapi32.RegDeleteKeyA") +#pragma comment(linker, "/EXPORT:RegDeleteKeyExA=advapi32.RegDeleteKeyExA") +#pragma comment(linker, "/EXPORT:RegDeleteKeyExW=advapi32.RegDeleteKeyExW") +#pragma comment(linker, "/EXPORT:RegDeleteKeyTransactedA=advapi32.RegDeleteKeyTransactedA") +#pragma comment(linker, "/EXPORT:RegDeleteKeyTransactedW=advapi32.RegDeleteKeyTransactedW") +#pragma comment(linker, "/EXPORT:RegDeleteKeyValueA=advapi32.RegDeleteKeyValueA") +#pragma comment(linker, "/EXPORT:RegDeleteKeyValueW=advapi32.RegDeleteKeyValueW") +#pragma comment(linker, "/EXPORT:RegDeleteKeyW=advapi32.RegDeleteKeyW") +#pragma comment(linker, "/EXPORT:RegDeleteTreeA=advapi32.RegDeleteTreeA") +#pragma comment(linker, "/EXPORT:RegDeleteTreeW=advapi32.RegDeleteTreeW") +#pragma comment(linker, "/EXPORT:RegDeleteValueA=advapi32.RegDeleteValueA") +#pragma comment(linker, "/EXPORT:RegDeleteValueW=advapi32.RegDeleteValueW") +#pragma comment(linker, "/EXPORT:RegDisablePredefinedCache=advapi32.RegDisablePredefinedCache") +#pragma comment(linker, "/EXPORT:RegDisablePredefinedCacheEx=advapi32.RegDisablePredefinedCacheEx") +#pragma comment(linker, "/EXPORT:RegDisableReflectionKey=advapi32.RegDisableReflectionKey") +#pragma comment(linker, "/EXPORT:RegEnableReflectionKey=advapi32.RegEnableReflectionKey") +#pragma comment(linker, "/EXPORT:RegEnumKeyA=advapi32.RegEnumKeyA") +#pragma comment(linker, "/EXPORT:RegEnumKeyExA=advapi32.RegEnumKeyExA") +#pragma comment(linker, "/EXPORT:RegEnumKeyExW=advapi32.RegEnumKeyExW") +#pragma comment(linker, "/EXPORT:RegEnumKeyW=advapi32.RegEnumKeyW") +#pragma comment(linker, "/EXPORT:RegEnumValueA=advapi32.RegEnumValueA") +#pragma comment(linker, "/EXPORT:RegEnumValueW=advapi32.RegEnumValueW") +#pragma comment(linker, "/EXPORT:RegFlushKey=advapi32.RegFlushKey") +#pragma comment(linker, "/EXPORT:RegGetKeySecurity=advapi32.RegGetKeySecurity") +#pragma comment(linker, "/EXPORT:RegGetValueA=advapi32.RegGetValueA") +#pragma comment(linker, "/EXPORT:RegGetValueW=advapi32.RegGetValueW") +#pragma comment(linker, "/EXPORT:RegLoadAppKeyA=advapi32.RegLoadAppKeyA") +#pragma comment(linker, "/EXPORT:RegLoadAppKeyW=advapi32.RegLoadAppKeyW") +#pragma comment(linker, "/EXPORT:RegLoadKeyA=advapi32.RegLoadKeyA") +#pragma comment(linker, "/EXPORT:RegLoadKeyW=advapi32.RegLoadKeyW") +#pragma comment(linker, "/EXPORT:RegLoadMUIStringA=advapi32.RegLoadMUIStringA") +#pragma comment(linker, "/EXPORT:RegLoadMUIStringW=advapi32.RegLoadMUIStringW") +#pragma comment(linker, "/EXPORT:RegNotifyChangeKeyValue=advapi32.RegNotifyChangeKeyValue") +#pragma comment(linker, "/EXPORT:RegOpenCurrentUser=advapi32.RegOpenCurrentUser") +#pragma comment(linker, "/EXPORT:RegOpenKeyA=advapi32.RegOpenKeyA") +#pragma comment(linker, "/EXPORT:RegOpenKeyExA=advapi32.RegOpenKeyExA") +#pragma comment(linker, "/EXPORT:RegOpenKeyExW=advapi32.RegOpenKeyExW") +#pragma comment(linker, "/EXPORT:RegOpenKeyTransactedA=advapi32.RegOpenKeyTransactedA") +#pragma comment(linker, "/EXPORT:RegOpenKeyTransactedW=advapi32.RegOpenKeyTransactedW") +#pragma comment(linker, "/EXPORT:RegOpenKeyW=advapi32.RegOpenKeyW") +#pragma comment(linker, "/EXPORT:RegOpenUserClassesRoot=advapi32.RegOpenUserClassesRoot") +#pragma comment(linker, "/EXPORT:RegOverridePredefKey=advapi32.RegOverridePredefKey") +#pragma comment(linker, "/EXPORT:RegQueryInfoKeyA=advapi32.RegQueryInfoKeyA") +#pragma comment(linker, "/EXPORT:RegQueryInfoKeyW=advapi32.RegQueryInfoKeyW") +#pragma comment(linker, "/EXPORT:RegQueryMultipleValuesA=advapi32.RegQueryMultipleValuesA") +#pragma comment(linker, "/EXPORT:RegQueryMultipleValuesW=advapi32.RegQueryMultipleValuesW") +#pragma comment(linker, "/EXPORT:RegQueryReflectionKey=advapi32.RegQueryReflectionKey") +#pragma comment(linker, "/EXPORT:RegQueryValueA=advapi32.RegQueryValueA") +#pragma comment(linker, "/EXPORT:RegQueryValueExA=advapi32.RegQueryValueExA") +#pragma comment(linker, "/EXPORT:RegQueryValueExW=advapi32.RegQueryValueExW") +#pragma comment(linker, "/EXPORT:RegQueryValueW=advapi32.RegQueryValueW") +#pragma comment(linker, "/EXPORT:RegRenameKey=advapi32.RegRenameKey") +#pragma comment(linker, "/EXPORT:RegReplaceKeyA=advapi32.RegReplaceKeyA") +#pragma comment(linker, "/EXPORT:RegReplaceKeyW=advapi32.RegReplaceKeyW") +#pragma comment(linker, "/EXPORT:RegRestoreKeyA=advapi32.RegRestoreKeyA") +#pragma comment(linker, "/EXPORT:RegRestoreKeyW=advapi32.RegRestoreKeyW") +#pragma comment(linker, "/EXPORT:RegSaveKeyA=advapi32.RegSaveKeyA") +#pragma comment(linker, "/EXPORT:RegSaveKeyExA=advapi32.RegSaveKeyExA") +#pragma comment(linker, "/EXPORT:RegSaveKeyExW=advapi32.RegSaveKeyExW") +#pragma comment(linker, "/EXPORT:RegSaveKeyW=advapi32.RegSaveKeyW") +#pragma comment(linker, "/EXPORT:RegSetKeySecurity=advapi32.RegSetKeySecurity") +#pragma comment(linker, "/EXPORT:RegSetKeyValueA=advapi32.RegSetKeyValueA") +#pragma comment(linker, "/EXPORT:RegSetKeyValueW=advapi32.RegSetKeyValueW") +#pragma comment(linker, "/EXPORT:RegSetValueA=advapi32.RegSetValueA") +#pragma comment(linker, "/EXPORT:RegSetValueExA=advapi32.RegSetValueExA") +#pragma comment(linker, "/EXPORT:RegSetValueExW=advapi32.RegSetValueExW") +#pragma comment(linker, "/EXPORT:RegSetValueW=advapi32.RegSetValueW") +#pragma comment(linker, "/EXPORT:RegUnLoadKeyA=advapi32.RegUnLoadKeyA") +#pragma comment(linker, "/EXPORT:RegUnLoadKeyW=advapi32.RegUnLoadKeyW") +#pragma comment(linker, "/EXPORT:RegisterEventSourceA=advapi32.RegisterEventSourceA") +#pragma comment(linker, "/EXPORT:RegisterEventSourceW=advapi32.RegisterEventSourceW") +#pragma comment(linker, "/EXPORT:RegisterIdleTask=advapi32.RegisterIdleTask") +#pragma comment(linker, "/EXPORT:RegisterServiceCtrlHandlerA=advapi32.RegisterServiceCtrlHandlerA") +#pragma comment(linker, "/EXPORT:RegisterServiceCtrlHandlerExA=advapi32.RegisterServiceCtrlHandlerExA") +#pragma comment(linker, "/EXPORT:RegisterServiceCtrlHandlerExW=advapi32.RegisterServiceCtrlHandlerExW") +#pragma comment(linker, "/EXPORT:RegisterServiceCtrlHandlerW=advapi32.RegisterServiceCtrlHandlerW") +#pragma comment(linker, "/EXPORT:RegisterTraceGuidsA=advapi32.RegisterTraceGuidsA") +#pragma comment(linker, "/EXPORT:RegisterTraceGuidsW=advapi32.RegisterTraceGuidsW") +#pragma comment(linker, "/EXPORT:RegisterWaitChainCOMCallback=advapi32.RegisterWaitChainCOMCallback") +#pragma comment(linker, "/EXPORT:RemoveTraceCallback=advapi32.RemoveTraceCallback") +#pragma comment(linker, "/EXPORT:RemoveUsersFromEncryptedFile=advapi32.RemoveUsersFromEncryptedFile") +#pragma comment(linker, "/EXPORT:ReportEventA=advapi32.ReportEventA") +#pragma comment(linker, "/EXPORT:ReportEventW=advapi32.ReportEventW") +#pragma comment(linker, "/EXPORT:RevertToSelf=advapi32.RevertToSelf") +#pragma comment(linker, "/EXPORT:SaferCloseLevel=advapi32.SaferCloseLevel") +#pragma comment(linker, "/EXPORT:SaferComputeTokenFromLevel=advapi32.SaferComputeTokenFromLevel") +#pragma comment(linker, "/EXPORT:SaferCreateLevel=advapi32.SaferCreateLevel") +#pragma comment(linker, "/EXPORT:SaferGetLevelInformation=advapi32.SaferGetLevelInformation") +#pragma comment(linker, "/EXPORT:SaferGetPolicyInformation=advapi32.SaferGetPolicyInformation") +#pragma comment(linker, "/EXPORT:SaferIdentifyLevel=advapi32.SaferIdentifyLevel") +#pragma comment(linker, "/EXPORT:SaferRecordEventLogEntry=advapi32.SaferRecordEventLogEntry") +#pragma comment(linker, "/EXPORT:SaferSetLevelInformation=advapi32.SaferSetLevelInformation") +#pragma comment(linker, "/EXPORT:SaferSetPolicyInformation=advapi32.SaferSetPolicyInformation") +#pragma comment(linker, "/EXPORT:SaferiChangeRegistryScope=advapi32.SaferiChangeRegistryScope") +#pragma comment(linker, "/EXPORT:SaferiCompareTokenLevels=advapi32.SaferiCompareTokenLevels") +#pragma comment(linker, "/EXPORT:SaferiIsDllAllowed=advapi32.SaferiIsDllAllowed") +#pragma comment(linker, "/EXPORT:SaferiIsExecutableFileType=advapi32.SaferiIsExecutableFileType") +#pragma comment(linker, "/EXPORT:SaferiPopulateDefaultsInRegistry=advapi32.SaferiPopulateDefaultsInRegistry") +#pragma comment(linker, "/EXPORT:SaferiRecordEventLogEntry=advapi32.SaferiRecordEventLogEntry") +#pragma comment(linker, "/EXPORT:SaferiSearchMatchingHashRules=advapi32.SaferiSearchMatchingHashRules") +#pragma comment(linker, "/EXPORT:SetAclInformation=advapi32.SetAclInformation") +#pragma comment(linker, "/EXPORT:SetEncryptedFileMetadata=advapi32.SetEncryptedFileMetadata") +#pragma comment(linker, "/EXPORT:SetEntriesInAccessListA=advapi32.SetEntriesInAccessListA") +#pragma comment(linker, "/EXPORT:SetEntriesInAccessListW=advapi32.SetEntriesInAccessListW") +#pragma comment(linker, "/EXPORT:SetEntriesInAclA=advapi32.SetEntriesInAclA") +#pragma comment(linker, "/EXPORT:SetEntriesInAclW=advapi32.SetEntriesInAclW") +#pragma comment(linker, "/EXPORT:SetEntriesInAuditListA=advapi32.SetEntriesInAuditListA") +#pragma comment(linker, "/EXPORT:SetEntriesInAuditListW=advapi32.SetEntriesInAuditListW") +#pragma comment(linker, "/EXPORT:SetFileSecurityA=advapi32.SetFileSecurityA") +#pragma comment(linker, "/EXPORT:SetFileSecurityW=advapi32.SetFileSecurityW") +#pragma comment(linker, "/EXPORT:SetInformationCodeAuthzLevelW=advapi32.SetInformationCodeAuthzLevelW") +#pragma comment(linker, "/EXPORT:SetInformationCodeAuthzPolicyW=advapi32.SetInformationCodeAuthzPolicyW") +#pragma comment(linker, "/EXPORT:SetKernelObjectSecurity=advapi32.SetKernelObjectSecurity") +#pragma comment(linker, "/EXPORT:SetNamedSecurityInfoA=advapi32.SetNamedSecurityInfoA") +#pragma comment(linker, "/EXPORT:SetNamedSecurityInfoExA=advapi32.SetNamedSecurityInfoExA") +#pragma comment(linker, "/EXPORT:SetNamedSecurityInfoExW=advapi32.SetNamedSecurityInfoExW") +#pragma comment(linker, "/EXPORT:SetNamedSecurityInfoW=advapi32.SetNamedSecurityInfoW") +#pragma comment(linker, "/EXPORT:SetPrivateObjectSecurity=advapi32.SetPrivateObjectSecurity") +#pragma comment(linker, "/EXPORT:SetPrivateObjectSecurityEx=advapi32.SetPrivateObjectSecurityEx") +#pragma comment(linker, "/EXPORT:SetSecurityAccessMask=advapi32.SetSecurityAccessMask") +#pragma comment(linker, "/EXPORT:SetSecurityDescriptorControl=advapi32.SetSecurityDescriptorControl") +#pragma comment(linker, "/EXPORT:SetSecurityDescriptorDacl=advapi32.SetSecurityDescriptorDacl") +#pragma comment(linker, "/EXPORT:SetSecurityDescriptorGroup=advapi32.SetSecurityDescriptorGroup") +#pragma comment(linker, "/EXPORT:SetSecurityDescriptorOwner=advapi32.SetSecurityDescriptorOwner") +#pragma comment(linker, "/EXPORT:SetSecurityDescriptorRMControl=advapi32.SetSecurityDescriptorRMControl") +#pragma comment(linker, "/EXPORT:SetSecurityDescriptorSacl=advapi32.SetSecurityDescriptorSacl") +#pragma comment(linker, "/EXPORT:SetSecurityInfo=advapi32.SetSecurityInfo") +#pragma comment(linker, "/EXPORT:SetSecurityInfoExA=advapi32.SetSecurityInfoExA") +#pragma comment(linker, "/EXPORT:SetSecurityInfoExW=advapi32.SetSecurityInfoExW") +#pragma comment(linker, "/EXPORT:SetServiceBits=advapi32.SetServiceBits") +#pragma comment(linker, "/EXPORT:SetServiceObjectSecurity=advapi32.SetServiceObjectSecurity") +#pragma comment(linker, "/EXPORT:SetServiceStatus=advapi32.SetServiceStatus") +#pragma comment(linker, "/EXPORT:SetThreadToken=advapi32.SetThreadToken") +#pragma comment(linker, "/EXPORT:SetTokenInformation=advapi32.SetTokenInformation") +#pragma comment(linker, "/EXPORT:SetTraceCallback=advapi32.SetTraceCallback") +#pragma comment(linker, "/EXPORT:SetUserFileEncryptionKey=advapi32.SetUserFileEncryptionKey") +#pragma comment(linker, "/EXPORT:SetUserFileEncryptionKeyEx=advapi32.SetUserFileEncryptionKeyEx") +#pragma comment(linker, "/EXPORT:StartServiceA=advapi32.StartServiceA") +#pragma comment(linker, "/EXPORT:StartServiceCtrlDispatcherA=advapi32.StartServiceCtrlDispatcherA") +#pragma comment(linker, "/EXPORT:StartServiceCtrlDispatcherW=advapi32.StartServiceCtrlDispatcherW") +#pragma comment(linker, "/EXPORT:StartServiceW=advapi32.StartServiceW") +#pragma comment(linker, "/EXPORT:StartTraceA=advapi32.StartTraceA") +#pragma comment(linker, "/EXPORT:StartTraceW=advapi32.StartTraceW") +#pragma comment(linker, "/EXPORT:StopTraceA=advapi32.StopTraceA") +#pragma comment(linker, "/EXPORT:StopTraceW=advapi32.StopTraceW") +#pragma comment(linker, "/EXPORT:SystemFunction001=advapi32.SystemFunction001") +#pragma comment(linker, "/EXPORT:SystemFunction002=advapi32.SystemFunction002") +#pragma comment(linker, "/EXPORT:SystemFunction003=advapi32.SystemFunction003") +#pragma comment(linker, "/EXPORT:SystemFunction004=advapi32.SystemFunction004") +#pragma comment(linker, "/EXPORT:SystemFunction005=advapi32.SystemFunction005") +#pragma comment(linker, "/EXPORT:SystemFunction006=advapi32.SystemFunction006") +#pragma comment(linker, "/EXPORT:SystemFunction007=advapi32.SystemFunction007") +#pragma comment(linker, "/EXPORT:SystemFunction008=advapi32.SystemFunction008") +#pragma comment(linker, "/EXPORT:SystemFunction009=advapi32.SystemFunction009") +#pragma comment(linker, "/EXPORT:SystemFunction010=advapi32.SystemFunction010") +#pragma comment(linker, "/EXPORT:SystemFunction011=advapi32.SystemFunction011") +#pragma comment(linker, "/EXPORT:SystemFunction012=advapi32.SystemFunction012") +#pragma comment(linker, "/EXPORT:SystemFunction013=advapi32.SystemFunction013") +#pragma comment(linker, "/EXPORT:SystemFunction014=advapi32.SystemFunction014") +#pragma comment(linker, "/EXPORT:SystemFunction015=advapi32.SystemFunction015") +#pragma comment(linker, "/EXPORT:SystemFunction016=advapi32.SystemFunction016") +#pragma comment(linker, "/EXPORT:SystemFunction017=advapi32.SystemFunction017") +#pragma comment(linker, "/EXPORT:SystemFunction018=advapi32.SystemFunction018") +#pragma comment(linker, "/EXPORT:SystemFunction019=advapi32.SystemFunction019") +#pragma comment(linker, "/EXPORT:SystemFunction020=advapi32.SystemFunction020") +#pragma comment(linker, "/EXPORT:SystemFunction021=advapi32.SystemFunction021") +#pragma comment(linker, "/EXPORT:SystemFunction022=advapi32.SystemFunction022") +#pragma comment(linker, "/EXPORT:SystemFunction023=advapi32.SystemFunction023") +#pragma comment(linker, "/EXPORT:SystemFunction024=advapi32.SystemFunction024") +#pragma comment(linker, "/EXPORT:SystemFunction025=advapi32.SystemFunction025") +#pragma comment(linker, "/EXPORT:SystemFunction026=advapi32.SystemFunction026") +#pragma comment(linker, "/EXPORT:SystemFunction027=advapi32.SystemFunction027") +#pragma comment(linker, "/EXPORT:SystemFunction028=advapi32.SystemFunction028") +#pragma comment(linker, "/EXPORT:SystemFunction029=advapi32.SystemFunction029") +#pragma comment(linker, "/EXPORT:SystemFunction030=advapi32.SystemFunction030") +#pragma comment(linker, "/EXPORT:SystemFunction031=advapi32.SystemFunction031") +#pragma comment(linker, "/EXPORT:SystemFunction032=advapi32.SystemFunction032") +#pragma comment(linker, "/EXPORT:SystemFunction033=advapi32.SystemFunction033") +#pragma comment(linker, "/EXPORT:SystemFunction034=advapi32.SystemFunction034") +#pragma comment(linker, "/EXPORT:SystemFunction035=advapi32.SystemFunction035") +#pragma comment(linker, "/EXPORT:SystemFunction036=advapi32.SystemFunction036") +#pragma comment(linker, "/EXPORT:SystemFunction040=advapi32.SystemFunction040") +#pragma comment(linker, "/EXPORT:SystemFunction041=advapi32.SystemFunction041") +#pragma comment(linker, "/EXPORT:TraceEvent=advapi32.TraceEvent") +#pragma comment(linker, "/EXPORT:TraceEventInstance=advapi32.TraceEventInstance") +#pragma comment(linker, "/EXPORT:TraceMessage=advapi32.TraceMessage") +#pragma comment(linker, "/EXPORT:TraceMessageVa=advapi32.TraceMessageVa") +#pragma comment(linker, "/EXPORT:TraceSetInformation=advapi32.TraceSetInformation") +#pragma comment(linker, "/EXPORT:TreeResetNamedSecurityInfoA=advapi32.TreeResetNamedSecurityInfoA") +#pragma comment(linker, "/EXPORT:TreeResetNamedSecurityInfoW=advapi32.TreeResetNamedSecurityInfoW") +#pragma comment(linker, "/EXPORT:TreeSetNamedSecurityInfoA=advapi32.TreeSetNamedSecurityInfoA") +#pragma comment(linker, "/EXPORT:TreeSetNamedSecurityInfoW=advapi32.TreeSetNamedSecurityInfoW") +#pragma comment(linker, "/EXPORT:TrusteeAccessToObjectA=advapi32.TrusteeAccessToObjectA") +#pragma comment(linker, "/EXPORT:TrusteeAccessToObjectW=advapi32.TrusteeAccessToObjectW") +#pragma comment(linker, "/EXPORT:UninstallApplication=advapi32.UninstallApplication") +#pragma comment(linker, "/EXPORT:UnlockServiceDatabase=advapi32.UnlockServiceDatabase") +#pragma comment(linker, "/EXPORT:UnregisterIdleTask=advapi32.UnregisterIdleTask") +#pragma comment(linker, "/EXPORT:UnregisterTraceGuids=advapi32.UnregisterTraceGuids") +#pragma comment(linker, "/EXPORT:UpdateTraceA=advapi32.UpdateTraceA") +#pragma comment(linker, "/EXPORT:UpdateTraceW=advapi32.UpdateTraceW") +#pragma comment(linker, "/EXPORT:UsePinForEncryptedFilesA=advapi32.UsePinForEncryptedFilesA") +#pragma comment(linker, "/EXPORT:UsePinForEncryptedFilesW=advapi32.UsePinForEncryptedFilesW") +#pragma comment(linker, "/EXPORT:WmiCloseBlock=advapi32.WmiCloseBlock") +#pragma comment(linker, "/EXPORT:WmiDevInstToInstanceNameA=advapi32.WmiDevInstToInstanceNameA") +#pragma comment(linker, "/EXPORT:WmiDevInstToInstanceNameW=advapi32.WmiDevInstToInstanceNameW") +#pragma comment(linker, "/EXPORT:WmiEnumerateGuids=advapi32.WmiEnumerateGuids") +#pragma comment(linker, "/EXPORT:WmiExecuteMethodA=advapi32.WmiExecuteMethodA") +#pragma comment(linker, "/EXPORT:WmiExecuteMethodW=advapi32.WmiExecuteMethodW") +#pragma comment(linker, "/EXPORT:WmiFileHandleToInstanceNameA=advapi32.WmiFileHandleToInstanceNameA") +#pragma comment(linker, "/EXPORT:WmiFileHandleToInstanceNameW=advapi32.WmiFileHandleToInstanceNameW") +#pragma comment(linker, "/EXPORT:WmiFreeBuffer=advapi32.WmiFreeBuffer") +#pragma comment(linker, "/EXPORT:WmiMofEnumerateResourcesA=advapi32.WmiMofEnumerateResourcesA") +#pragma comment(linker, "/EXPORT:WmiMofEnumerateResourcesW=advapi32.WmiMofEnumerateResourcesW") +#pragma comment(linker, "/EXPORT:WmiNotificationRegistrationA=advapi32.WmiNotificationRegistrationA") +#pragma comment(linker, "/EXPORT:WmiNotificationRegistrationW=advapi32.WmiNotificationRegistrationW") +#pragma comment(linker, "/EXPORT:WmiOpenBlock=advapi32.WmiOpenBlock") +#pragma comment(linker, "/EXPORT:WmiQueryAllDataA=advapi32.WmiQueryAllDataA") +#pragma comment(linker, "/EXPORT:WmiQueryAllDataMultipleA=advapi32.WmiQueryAllDataMultipleA") +#pragma comment(linker, "/EXPORT:WmiQueryAllDataMultipleW=advapi32.WmiQueryAllDataMultipleW") +#pragma comment(linker, "/EXPORT:WmiQueryAllDataW=advapi32.WmiQueryAllDataW") +#pragma comment(linker, "/EXPORT:WmiQueryGuidInformation=advapi32.WmiQueryGuidInformation") +#pragma comment(linker, "/EXPORT:WmiQuerySingleInstanceA=advapi32.WmiQuerySingleInstanceA") +#pragma comment(linker, "/EXPORT:WmiQuerySingleInstanceMultipleA=advapi32.WmiQuerySingleInstanceMultipleA") +#pragma comment(linker, "/EXPORT:WmiQuerySingleInstanceMultipleW=advapi32.WmiQuerySingleInstanceMultipleW") +#pragma comment(linker, "/EXPORT:WmiQuerySingleInstanceW=advapi32.WmiQuerySingleInstanceW") +#pragma comment(linker, "/EXPORT:WmiReceiveNotificationsA=advapi32.WmiReceiveNotificationsA") +#pragma comment(linker, "/EXPORT:WmiReceiveNotificationsW=advapi32.WmiReceiveNotificationsW") +#pragma comment(linker, "/EXPORT:WmiSetSingleInstanceA=advapi32.WmiSetSingleInstanceA") +#pragma comment(linker, "/EXPORT:WmiSetSingleInstanceW=advapi32.WmiSetSingleInstanceW") +#pragma comment(linker, "/EXPORT:WmiSetSingleItemA=advapi32.WmiSetSingleItemA") +#pragma comment(linker, "/EXPORT:WmiSetSingleItemW=advapi32.WmiSetSingleItemW") +#pragma comment(linker, "/EXPORT:WriteEncryptedFileRaw=advapi32.WriteEncryptedFileRaw") +#pragma comment(linker, "/EXPORT:__OrdinalFunction1000=advapi32.#1000,@1000,NONAME") diff --git a/01-Extended DLLs/KxAdvapi/kxadvapi.def b/01-Extended DLLs/KxAdvapi/kxadvapi.def new file mode 100644 index 0000000..7e706cc --- /dev/null +++ b/01-Extended DLLs/KxAdvapi/kxadvapi.def @@ -0,0 +1,3 @@ +LIBRARY KxAdvapi +EXPORTS + EventSetInformation = KexDll.KexEtwEventSetInformation \ No newline at end of file diff --git a/01-Extended DLLs/KxAdvapi/kxadvapi.rc b/01-Extended DLLs/KxAdvapi/kxadvapi.rc new file mode 100644 index 0000000..e901fbe Binary files /dev/null and b/01-Extended DLLs/KxAdvapi/kxadvapi.rc differ diff --git a/01-Extended DLLs/KxBase/KxBase.rc b/01-Extended DLLs/KxBase/KxBase.rc new file mode 100644 index 0000000..f5813f6 Binary files /dev/null and b/01-Extended DLLs/KxBase/KxBase.rc differ diff --git a/01-Extended DLLs/KxBase/appmodel.c b/01-Extended DLLs/KxBase/appmodel.c new file mode 100644 index 0000000..95f87d3 --- /dev/null +++ b/01-Extended DLLs/KxBase/appmodel.c @@ -0,0 +1,177 @@ +#include "buildcfg.h" +#include "kxbasep.h" + +KXBASEAPI LONG WINAPI GetCurrentPackageFullName( + IN OUT PULONG PackageFullNameLength, + OUT PWSTR PackageFullName OPTIONAL) +{ + if (!PackageFullNameLength) { + return ERROR_INVALID_PARAMETER; + } + + if (*PackageFullNameLength != 0 && !PackageFullName) { + return ERROR_INVALID_PARAMETER; + } + + return APPMODEL_ERROR_NO_PACKAGE; +} + +KXBASEAPI LONG WINAPI GetCurrentPackageId( + IN OUT PULONG BufferLength, + OUT PBYTE Buffer OPTIONAL) +{ + if (!BufferLength) { + return ERROR_INVALID_PARAMETER; + } + + if (*BufferLength != 0 && !Buffer) { + return ERROR_INVALID_PARAMETER; + } + + return APPMODEL_ERROR_NO_PACKAGE; +} + +KXBASEAPI LONG WINAPI GetPackageFullName( + IN HANDLE ProcessHandle, + IN OUT PULONG NameLength, + OUT PWSTR PackageFullName OPTIONAL) +{ + if (!ProcessHandle || !NameLength || *NameLength && !PackageFullName) { + return ERROR_INVALID_PARAMETER; + } + + *NameLength = 0; + + if (PackageFullName) { + PackageFullName[0] = '\0'; + } + + return APPMODEL_ERROR_NO_PACKAGE; +} + +KXBASEAPI LONG WINAPI GetPackageFamilyName( + IN HANDLE ProcessHandle, + IN OUT PULONG NameLength, + OUT PWSTR PackageFamilyName OPTIONAL) +{ + if (!ProcessHandle || !NameLength || *NameLength && !PackageFamilyName) { + return ERROR_INVALID_PARAMETER; + } + + *NameLength = 0; + + if (PackageFamilyName) { + PackageFamilyName[0] = '\0'; + } + + return APPMODEL_ERROR_NO_PACKAGE; +} + +KXBASEAPI LONG WINAPI GetPackagesByPackageFamily( + IN PCWSTR PackageFamilyName, + IN OUT PULONG Count, + OUT PPWSTR PackageFullNames OPTIONAL, + IN OUT PULONG BufferLength, + OUT PPWSTR Buffer OPTIONAL) +{ + if (!Count || !BufferLength) { + return ERROR_INVALID_PARAMETER; + } + + *Count = 0; + *BufferLength = 0; + + return ERROR_SUCCESS; +} + +KXBASEAPI LONG WINAPI AppPolicyGetProcessTerminationMethod( + IN HANDLE ProcessToken, + OUT PULONG Policy) +{ + if (!ProcessToken || !Policy) { + return RtlNtStatusToDosError(STATUS_INVALID_PARAMETER); + } + + *Policy = 0; + return ERROR_SUCCESS; +} + +KXBASEAPI HRESULT WINAPI AppXGetPackageSid( + IN PCWSTR PackageMoniker, + OUT PSID *PackageSid) +{ + KexLogWarningEvent(L"AppXGetPackageSid called: %s", PackageMoniker); + KexDebugCheckpoint(); + + if (!PackageMoniker || !PackageSid) { + return E_INVALIDARG; + } + + return E_NOTIMPL; +} + +KXBASEAPI VOID WINAPI AppXFreeMemory( + IN PVOID Pointer) +{ + RtlFreeHeap(RtlProcessHeap(), 0, Pointer); +} + +KXBASEAPI ULONG WINAPI PackageFamilyNameFromFullName( + IN PCWSTR PackageFullName, + IN OUT PULONG PackageFamilyNameLength, + OUT PWSTR PackageFamilyName) +{ + if (!PackageFullName || !PackageFamilyNameLength) { + return ERROR_INVALID_PARAMETER; + } + + if (*PackageFamilyNameLength != 0 && !PackageFamilyName) { + return ERROR_INVALID_PARAMETER; + } + + if (*PackageFamilyNameLength != 0) { + PackageFamilyName[0] = '\0'; + } + + *PackageFamilyNameLength = 0; + return ERROR_SUCCESS; +} + +KXBASEAPI LONG WINAPI GetApplicationUserModelId( + IN HANDLE ProcessHandle, + IN OUT PULONG ApplicationUserModelIdLength, + OUT PWSTR ApplicationUserModelId) +{ + return APPMODEL_ERROR_NO_APPLICATION; +} + +KXBASEAPI LONG WINAPI GetCurrentApplicationUserModelId( + IN OUT PULONG Cch, + OUT PWSTR Buffer) +{ + return APPMODEL_ERROR_NO_APPLICATION; +} + +KXBASEAPI LONG WINAPI AppPolicyGetWindowingModel( + IN HANDLE ProcessToken, + OUT PAPP_POLICY_WINDOWING_MODEL WindowingModel) +{ + if (!ProcessToken || !WindowingModel) { + return ERROR_INVALID_PARAMETER; + } + + *WindowingModel = AppPolicyWindowingModel_ClassicDesktop; + return ERROR_SUCCESS; +} + +KXBASEAPI LONG WINAPI AppPolicyGetThreadInitializationType( + IN HANDLE ProcessToken, + OUT PAPP_POLICY_THREAD_INITIALIZATION_TYPE InitializationType) +{ + if (!ProcessToken || !InitializationType) { + return ERROR_INVALID_PARAMETER; + } + + *InitializationType = AppPolicyThreadInitializationType_None; + return ERROR_SUCCESS; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxBase/buildcfg.h b/01-Extended DLLs/KxBase/buildcfg.h new file mode 100644 index 0000000..7e36136 --- /dev/null +++ b/01-Extended DLLs/KxBase/buildcfg.h @@ -0,0 +1,49 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN +#define NOGDICAPMASKS +#define NOVIRTUALKEYCODES +#define NOWINSTYLES +#define NOSYSMETRICS +#define NOMENUS +#define NOICONS +#define NOKEYSTATES +#define NOSYSCOMMANDS +#define NORASTEROPS +#define NOSHOWWINDOW +#define NOATOM +#define NOCLIPBOARD +#define NOCOLOR +#define NODRAWTEXT +#define NOGDI +#define NOKERNEL +#define NOMB +#define NOMEMMGR +#define NOOPENFILE +#define NOSCROLL +#define NOTEXTMETRIC +#define NOWH +#define NOWINOFFSETS +#define NOCOMM +#define NOKANJI +#define NOHELP +#define NOPROFILER +#define NODEFERWINDOWPOS +#define NOMCX +#define NOCRYPT +#define NOMETAFILE +#define NOSERVICE +#define NOSOUND +#define _UXTHEME_H_ + +#define KXBASEAPI + +#ifdef _M_X64 +# pragma comment(lib, "cfgmgr32_x64.lib") +#else +# pragma comment(lib, "cfgmgr32_x86.lib") +#endif + +#define KEX_COMPONENT L"KxBase" +#define KEX_ENV_WIN32 +#define KEX_TARGET_TYPE_DLL diff --git a/01-Extended DLLs/KxBase/cfgmgr.c b/01-Extended DLLs/KxBase/cfgmgr.c new file mode 100644 index 0000000..aec0bd7 --- /dev/null +++ b/01-Extended DLLs/KxBase/cfgmgr.c @@ -0,0 +1,13 @@ +#include "buildcfg.h" +#include "kxbasep.h" + +KXBASEAPI CONFIGRET WINAPI CM_Register_Notification( + IN PCM_NOTIFY_FILTER Filter, + IN PVOID Context OPTIONAL, + IN PCM_NOTIFY_CALLBACK Callback, + OUT PHCMNOTIFICATION NotifyContext) +{ + KexLogWarningEvent(L"Unimplemented function CM_Register_Notification called"); + KexDebugCheckpoint(); + return CR_CALL_NOT_IMPLEMENTED; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxBase/dllmain.c b/01-Extended DLLs/KxBase/dllmain.c new file mode 100644 index 0000000..10683d6 --- /dev/null +++ b/01-Extended DLLs/KxBase/dllmain.c @@ -0,0 +1,77 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// dllmain.c +// +// Abstract: +// +// Main file for KXBASE. +// The DLLs "kernel32" and "kernelbase" are redirected to this DLL. +// +// Author: +// +// vxiiduu (07-Nov-2022) +// +// Environment: +// +// Win32 mode. +// This module can import from NTDLL, KERNEL32, and KERNELBASE. +// +// Revision History: +// +// vxiiduu 07-Nov-2022 Initial creation. +// vxiiduu 10-Feb-2024 Rename to KXBASE (from kernel33). +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kxbasep.h" +#include + +PKEX_PROCESS_DATA KexData = NULL; + +BOOL WINAPI DllMain( + IN PVOID DllBase, + IN ULONG Reason, + IN PCONTEXT Context) +{ + if (Reason == DLL_PROCESS_ATTACH) { + LdrDisableThreadCalloutsForDll(DllBase); + + KexDataInitialize(&KexData); + KexLogDebugEvent(L"DllMain called with DLL_PROCESS_ATTACH"); + + // + // Get the base address of Kernel32 and store it in KexData. + // + + BaseGetBaseDllHandle(); + ASSERT (KexData->BaseDllBase != NULL); + + // + // If we are doing SharedUserData-based version spoofing, we need to + // hook GetSystemTime and GetSystemTimeAsFileTime. + // + + if (KexData->IfeoParameters.StrongVersionSpoof & KEX_STRONGSPOOF_SHAREDUSERDATA) { + KexHkInstallBasicHook(GetSystemTime, KxBasepGetSystemTimeHook, NULL); + KexHkInstallBasicHook(GetSystemTimeAsFileTime, KxBasepGetSystemTimeAsFileTimeHook, NULL); + } + + // + // Patch subsystem version check inside CreateProcessInternalW. + // + + KexPatchCpiwSubsystemVersionCheck(); + + // + // Get base named object directories and put handles to them in KexData. + // + + KexData->BaseNamedObjects = BaseGetNamedObjectDirectory(); + KexData->UntrustedNamedObjects = BaseGetUntrustedNamedObjectDirectory(); + } + + return TRUE; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxBase/file.c b/01-Extended DLLs/KxBase/file.c new file mode 100644 index 0000000..216c765 --- /dev/null +++ b/01-Extended DLLs/KxBase/file.c @@ -0,0 +1,222 @@ +#include "buildcfg.h" +#include "kxbasep.h" + +KXBASEAPI HANDLE WINAPI CreateFile2( + IN PCWSTR FileName, + IN ULONG DesiredAccess, + IN ULONG ShareMode, + IN ULONG CreationDisposition, + IN PCREATEFILE2_EXTENDED_PARAMETERS ExtendedParameters OPTIONAL) +{ + if (ExtendedParameters) { + ULONG FlagsAndAttributes; + + if (ExtendedParameters->dwSize < sizeof(CREATEFILE2_EXTENDED_PARAMETERS)) { + BaseSetLastNTError(STATUS_INVALID_PARAMETER); + return INVALID_HANDLE_VALUE; + } + + FlagsAndAttributes = ExtendedParameters->dwFileFlags | + ExtendedParameters->dwSecurityQosFlags | + ExtendedParameters->dwFileAttributes; + + return CreateFile( + FileName, + DesiredAccess, + ShareMode, + ExtendedParameters->lpSecurityAttributes, + CreationDisposition, + FlagsAndAttributes, + ExtendedParameters->hTemplateFile); + } else { + return CreateFile( + FileName, + DesiredAccess, + ShareMode, + NULL, + CreationDisposition, + 0, + NULL); + } +} + +// +// Technically, these functions are supposed to behave differently when the +// current thread is running under the local SYSTEM account. However, we'll +// cross that bridge when we get there, since very very few programs actually +// run under those conditions. +// +// See Windows 11 kernelbase.dll for more information. +// +// For future reference: +// https://devblogs.microsoft.com/oldnewthing/20210106-00/?p=104669 +// + +KXBASEAPI ULONG WINAPI GetTempPath2A( + IN ULONG BufferCch, + OUT PSTR Buffer) +{ + return GetTempPathA(BufferCch, Buffer); +} + +KXBASEAPI ULONG WINAPI GetTempPath2W( + IN ULONG BufferCch, + OUT PWSTR Buffer) +{ + return GetTempPathW(BufferCch, Buffer); +} + +STATIC DWORD CALLBACK KxBasepCopyFile2ProgressRoutine( + IN LARGE_INTEGER TotalFileSize, + IN LARGE_INTEGER TotalBytesTransferred, + IN LARGE_INTEGER StreamSize, + IN LARGE_INTEGER StreamBytesTransferred, + IN DWORD StreamNumber, + IN DWORD CallbackReason, + IN HANDLE SourceFile, + IN HANDLE DestinationFile, + IN PVOID Context OPTIONAL) +{ + COPYFILE2_MESSAGE Message; + PCOPYFILE2_EXTENDED_PARAMETERS Copyfile2Parameters; + + ASSERT (Context != NULL); + + RtlZeroMemory(&Message, sizeof(Message)); + + switch (CallbackReason) { + case CALLBACK_CHUNK_FINISHED: + Message.Type = COPYFILE2_CALLBACK_CHUNK_FINISHED; + Message.Info.ChunkFinished.dwStreamNumber = StreamNumber; + Message.Info.ChunkFinished.uliTotalFileSize.QuadPart = TotalFileSize.QuadPart; + Message.Info.ChunkFinished.uliTotalBytesTransferred.QuadPart = TotalBytesTransferred.QuadPart; + Message.Info.ChunkFinished.uliStreamSize.QuadPart = StreamSize.QuadPart; + Message.Info.ChunkFinished.uliStreamBytesTransferred.QuadPart = StreamBytesTransferred.QuadPart; + break; + case CALLBACK_STREAM_SWITCH: + Message.Type = COPYFILE2_CALLBACK_STREAM_STARTED; + Message.Info.StreamStarted.dwStreamNumber = StreamNumber; + Message.Info.StreamStarted.hDestinationFile = DestinationFile; + Message.Info.StreamStarted.hSourceFile = SourceFile; + Message.Info.StreamStarted.uliStreamSize.QuadPart = StreamSize.QuadPart; + Message.Info.StreamStarted.uliTotalFileSize.QuadPart = TotalFileSize.QuadPart; + break; + default: + ASSUME (FALSE); + } + + Copyfile2Parameters = (PCOPYFILE2_EXTENDED_PARAMETERS) Context; + + return Copyfile2Parameters->pProgressRoutine( + &Message, + Copyfile2Parameters->pvCallbackContext); +} + +KXBASEAPI HRESULT WINAPI CopyFile2( + IN PCWSTR ExistingFileName, + IN PCWSTR NewFileName, + IN PCOPYFILE2_EXTENDED_PARAMETERS ExtendedParameters OPTIONAL) +{ + BOOL Success; + ULONG EffectiveCopyFlags; + + if (ExtendedParameters == NULL) { + Success = CopyFileW( + ExistingFileName, + NewFileName, + FALSE); + + if (Success) { + return S_OK; + } else { + return HRESULT_FROM_WIN32(GetLastError()); + } + } + + if (ExtendedParameters->dwSize != sizeof(COPYFILE2_EXTENDED_PARAMETERS)) { + // + // Windows 11 defines a COPYFILE2_EXTENDED_PARAMETERS_V2 struture. + // When apps start using it, we will support it too. + // + + KexLogWarningEvent( + L"Unrecognized dwSize member of ExtendedParameters: %lu", + ExtendedParameters->dwSize); + + return E_INVALIDARG; + } + + if (ExtendedParameters->dwCopyFlags & ~COPY_FILE_ALL_VALID_FLAGS) { + return E_INVALIDARG; + } + + EffectiveCopyFlags = ExtendedParameters->dwCopyFlags & COPY_FILE_WIN7_VALID_FLAGS; + + Success = CopyFileExW( + ExistingFileName, + NewFileName, + ExtendedParameters->pProgressRoutine ? KxBasepCopyFile2ProgressRoutine : NULL, + ExtendedParameters, + ExtendedParameters->pfCancel, + EffectiveCopyFlags); + + if (Success) { + return S_OK; + } else { + return HRESULT_FROM_WIN32(GetLastError()); + } +} + +//KXBASEAPI HANDLE WINAPI Ext_CreateFileMappingW( +// IN HANDLE FileHandle, +// IN PSECURITY_ATTRIBUTES SecurityAttributes OPTIONAL, +// IN ULONG PageProtection, +// IN ULONG MaximumSizeHigh, +// IN ULONG MaximumSizeLow, +// IN PCWSTR Name OPTIONAL) +//{ +// HANDLE SectionHandle; +// WCHAR GeneratedName[64]; +// +// // +// // Windows 7 ignores security attributes on unnamed sections. Chromium checks +// // this and crashes. In order to solve this problem we will give a random name +// // to any unnamed section that has a security descriptor. +// // +// +// if (SecurityAttributes && SecurityAttributes->lpSecurityDescriptor && !Name) { +// ULONGLONG RandomIdentifier; +// PTEB Teb; +// +// // +// // Create a random identifier. +// // +// +// Teb = NtCurrentTeb(); +// NtQuerySystemTime((PLONGLONG) &RandomIdentifier); +// RandomIdentifier *= (ULONG_PTR) Teb->ClientId.UniqueThread; +// RandomIdentifier *= RtlRandomEx((PULONG) &RandomIdentifier); +// +// StringCchPrintf( +// GeneratedName, +// ARRAYSIZE(GeneratedName), +// L"VxKexRandomSectionName_%016I64x", +// RandomIdentifier); +// +// Name = GeneratedName; +// } +// +// SectionHandle = CreateFileMappingW( +// FileHandle, +// SecurityAttributes, +// PageProtection, +// MaximumSizeHigh, +// MaximumSizeLow, +// Name); +// +// if (SectionHandle == NULL && Name == GeneratedName) { +// KexDebugCheckpoint(); +// } +// +// return SectionHandle; +//} \ No newline at end of file diff --git a/01-Extended DLLs/KxBase/forwards.c b/01-Extended DLLs/KxBase/forwards.c new file mode 100644 index 0000000..96a9ca2 --- /dev/null +++ b/01-Extended DLLs/KxBase/forwards.c @@ -0,0 +1,1871 @@ +// +// The following contains exports from KERNEL32.DLL that are common between +// 32-bit and 64-bit versions of the DLL. +// + +#pragma comment(linker, "/EXPORT:AcquireSRWLockExclusive=kernel32.AcquireSRWLockExclusive") +#pragma comment(linker, "/EXPORT:AcquireSRWLockShared=kernel32.AcquireSRWLockShared") +#pragma comment(linker, "/EXPORT:ActivateActCtx=kernel32.ActivateActCtx") +#pragma comment(linker, "/EXPORT:AddAtomA=kernel32.AddAtomA") +#pragma comment(linker, "/EXPORT:AddAtomW=kernel32.AddAtomW") +#pragma comment(linker, "/EXPORT:AddConsoleAliasA=kernel32.AddConsoleAliasA") +#pragma comment(linker, "/EXPORT:AddConsoleAliasW=kernel32.AddConsoleAliasW") +//#pragma comment(linker, "/EXPORT:AddDllDirectory=kernel32.AddDllDirectory") +#pragma comment(linker, "/EXPORT:AddIntegrityLabelToBoundaryDescriptor=kernel32.AddIntegrityLabelToBoundaryDescriptor") +#pragma comment(linker, "/EXPORT:AddLocalAlternateComputerNameA=kernel32.AddLocalAlternateComputerNameA") +#pragma comment(linker, "/EXPORT:AddLocalAlternateComputerNameW=kernel32.AddLocalAlternateComputerNameW") +#pragma comment(linker, "/EXPORT:AddRefActCtx=kernel32.AddRefActCtx") +#pragma comment(linker, "/EXPORT:AddSIDToBoundaryDescriptor=kernel32.AddSIDToBoundaryDescriptor") +#pragma comment(linker, "/EXPORT:AddSecureMemoryCacheCallback=kernel32.AddSecureMemoryCacheCallback") +#pragma comment(linker, "/EXPORT:AddVectoredContinueHandler=kernel32.AddVectoredContinueHandler") +#pragma comment(linker, "/EXPORT:AddVectoredExceptionHandler=kernel32.AddVectoredExceptionHandler") +#pragma comment(linker, "/EXPORT:AdjustCalendarDate=kernel32.AdjustCalendarDate") +#pragma comment(linker, "/EXPORT:AllocConsole=kernel32.AllocConsole") +#pragma comment(linker, "/EXPORT:AllocateUserPhysicalPages=kernel32.AllocateUserPhysicalPages") +#pragma comment(linker, "/EXPORT:AllocateUserPhysicalPagesNuma=kernel32.AllocateUserPhysicalPagesNuma") +#pragma comment(linker, "/EXPORT:ApplicationRecoveryFinished=kernel32.ApplicationRecoveryFinished") +#pragma comment(linker, "/EXPORT:ApplicationRecoveryInProgress=kernel32.ApplicationRecoveryInProgress") +#pragma comment(linker, "/EXPORT:AreFileApisANSI=kernel32.AreFileApisANSI") +#pragma comment(linker, "/EXPORT:AssignProcessToJobObject=kernel32.AssignProcessToJobObject") +#pragma comment(linker, "/EXPORT:AttachConsole=kernel32.AttachConsole") +#pragma comment(linker, "/EXPORT:BackupRead=kernel32.BackupRead") +#pragma comment(linker, "/EXPORT:BackupSeek=kernel32.BackupSeek") +#pragma comment(linker, "/EXPORT:BackupWrite=kernel32.BackupWrite") +#pragma comment(linker, "/EXPORT:BaseCheckAppcompatCache=kernel32.BaseCheckAppcompatCache") +#pragma comment(linker, "/EXPORT:BaseCheckAppcompatCacheEx=kernel32.BaseCheckAppcompatCacheEx") +#pragma comment(linker, "/EXPORT:BaseCheckRunApp=kernel32.BaseCheckRunApp") +#pragma comment(linker, "/EXPORT:BaseCleanupAppcompatCacheSupport=kernel32.BaseCleanupAppcompatCacheSupport") +#pragma comment(linker, "/EXPORT:BaseDllReadWriteIniFile=kernel32.BaseDllReadWriteIniFile") +#pragma comment(linker, "/EXPORT:BaseDumpAppcompatCache=kernel32.BaseDumpAppcompatCache") +#pragma comment(linker, "/EXPORT:BaseFlushAppcompatCache=kernel32.BaseFlushAppcompatCache") +#pragma comment(linker, "/EXPORT:BaseFormatObjectAttributes=kernel32.BaseFormatObjectAttributes") +#pragma comment(linker, "/EXPORT:BaseFormatTimeOut=kernel32.BaseFormatTimeOut") +#pragma comment(linker, "/EXPORT:BaseGenerateAppCompatData=kernel32.BaseGenerateAppCompatData") +#pragma comment(linker, "/EXPORT:BaseGetNamedObjectDirectory=kernel32.BaseGetNamedObjectDirectory") +#pragma comment(linker, "/EXPORT:BaseInitAppcompatCacheSupport=kernel32.BaseInitAppcompatCacheSupport") +#pragma comment(linker, "/EXPORT:BaseIsAppcompatInfrastructureDisabled=kernel32.BaseIsAppcompatInfrastructureDisabled") +#pragma comment(linker, "/EXPORT:BaseQueryModuleData=kernel32.BaseQueryModuleData") +#pragma comment(linker, "/EXPORT:BaseSetLastNTError=kernel32.BaseSetLastNTError") +#pragma comment(linker, "/EXPORT:BaseThreadInitThunk=kernel32.BaseThreadInitThunk") +#pragma comment(linker, "/EXPORT:BaseUpdateAppcompatCache=kernel32.BaseUpdateAppcompatCache") +#pragma comment(linker, "/EXPORT:BaseVerifyUnicodeString=kernel32.BaseVerifyUnicodeString") +#pragma comment(linker, "/EXPORT:Basep8BitStringToDynamicUnicodeString=kernel32.Basep8BitStringToDynamicUnicodeString") +#pragma comment(linker, "/EXPORT:BasepAllocateActivationContextActivationBlock=kernel32.BasepAllocateActivationContextActivationBlock") +#pragma comment(linker, "/EXPORT:BasepAnsiStringToDynamicUnicodeString=kernel32.BasepAnsiStringToDynamicUnicodeString") +#pragma comment(linker, "/EXPORT:BasepCheckAppCompat=kernel32.BasepCheckAppCompat") +#pragma comment(linker, "/EXPORT:BasepCheckBadapp=kernel32.BasepCheckBadapp") +#pragma comment(linker, "/EXPORT:BasepCheckWinSaferRestrictions=kernel32.BasepCheckWinSaferRestrictions") +#pragma comment(linker, "/EXPORT:BasepFreeActivationContextActivationBlock=kernel32.BasepFreeActivationContextActivationBlock") +#pragma comment(linker, "/EXPORT:BasepFreeAppCompatData=kernel32.BasepFreeAppCompatData") +#pragma comment(linker, "/EXPORT:BasepMapModuleHandle=kernel32.BasepMapModuleHandle") +#pragma comment(linker, "/EXPORT:Beep=kernel32.Beep") +#pragma comment(linker, "/EXPORT:BeginUpdateResourceA=kernel32.BeginUpdateResourceA") +#pragma comment(linker, "/EXPORT:BeginUpdateResourceW=kernel32.BeginUpdateResourceW") +#pragma comment(linker, "/EXPORT:BindIoCompletionCallback=kernel32.BindIoCompletionCallback") +#pragma comment(linker, "/EXPORT:BuildCommDCBA=kernel32.BuildCommDCBA") +#pragma comment(linker, "/EXPORT:BuildCommDCBAndTimeoutsA=kernel32.BuildCommDCBAndTimeoutsA") +#pragma comment(linker, "/EXPORT:BuildCommDCBAndTimeoutsW=kernel32.BuildCommDCBAndTimeoutsW") +#pragma comment(linker, "/EXPORT:BuildCommDCBW=kernel32.BuildCommDCBW") +#pragma comment(linker, "/EXPORT:CallNamedPipeA=kernel32.CallNamedPipeA") +#pragma comment(linker, "/EXPORT:CallNamedPipeW=kernel32.CallNamedPipeW") +#pragma comment(linker, "/EXPORT:CallbackMayRunLong=kernel32.CallbackMayRunLong") +#pragma comment(linker, "/EXPORT:CancelDeviceWakeupRequest=kernel32.CancelDeviceWakeupRequest") +#pragma comment(linker, "/EXPORT:CancelIo=kernel32.CancelIo") +#pragma comment(linker, "/EXPORT:CancelIoEx=kernel32.CancelIoEx") +#pragma comment(linker, "/EXPORT:CancelSynchronousIo=kernel32.CancelSynchronousIo") +#pragma comment(linker, "/EXPORT:CancelThreadpoolIo=kernel32.CancelThreadpoolIo") +#pragma comment(linker, "/EXPORT:CancelTimerQueueTimer=kernel32.CancelTimerQueueTimer") +#pragma comment(linker, "/EXPORT:CancelWaitableTimer=kernel32.CancelWaitableTimer") +#pragma comment(linker, "/EXPORT:ChangeTimerQueueTimer=kernel32.ChangeTimerQueueTimer") +#pragma comment(linker, "/EXPORT:CheckElevation=kernel32.CheckElevation") +#pragma comment(linker, "/EXPORT:CheckElevationEnabled=kernel32.CheckElevationEnabled") +#pragma comment(linker, "/EXPORT:CheckForReadOnlyResource=kernel32.CheckForReadOnlyResource") +#pragma comment(linker, "/EXPORT:CheckNameLegalDOS8Dot3A=kernel32.CheckNameLegalDOS8Dot3A") +#pragma comment(linker, "/EXPORT:CheckNameLegalDOS8Dot3W=kernel32.CheckNameLegalDOS8Dot3W") +#pragma comment(linker, "/EXPORT:CheckRemoteDebuggerPresent=kernel32.CheckRemoteDebuggerPresent") +#pragma comment(linker, "/EXPORT:ClearCommBreak=kernel32.ClearCommBreak") +#pragma comment(linker, "/EXPORT:ClearCommError=kernel32.ClearCommError") +#pragma comment(linker, "/EXPORT:CloseConsoleHandle=kernel32.CloseConsoleHandle") +#pragma comment(linker, "/EXPORT:CloseHandle=kernel32.CloseHandle") +#pragma comment(linker, "/EXPORT:ClosePrivateNamespace=kernel32.ClosePrivateNamespace") +#pragma comment(linker, "/EXPORT:CloseProfileUserMapping=kernel32.CloseProfileUserMapping") +#pragma comment(linker, "/EXPORT:CloseThreadpool=kernel32.CloseThreadpool") +#pragma comment(linker, "/EXPORT:CloseThreadpoolCleanupGroup=kernel32.CloseThreadpoolCleanupGroup") +#pragma comment(linker, "/EXPORT:CloseThreadpoolCleanupGroupMembers=kernel32.CloseThreadpoolCleanupGroupMembers") +#pragma comment(linker, "/EXPORT:CloseThreadpoolIo=kernel32.CloseThreadpoolIo") +#pragma comment(linker, "/EXPORT:CloseThreadpoolTimer=kernel32.CloseThreadpoolTimer") +#pragma comment(linker, "/EXPORT:CloseThreadpoolWait=kernel32.CloseThreadpoolWait") +#pragma comment(linker, "/EXPORT:CloseThreadpoolWork=kernel32.CloseThreadpoolWork") +#pragma comment(linker, "/EXPORT:CmdBatNotification=kernel32.CmdBatNotification") +#pragma comment(linker, "/EXPORT:CommConfigDialogA=kernel32.CommConfigDialogA") +#pragma comment(linker, "/EXPORT:CommConfigDialogW=kernel32.CommConfigDialogW") +#pragma comment(linker, "/EXPORT:CompareCalendarDates=kernel32.CompareCalendarDates") +#pragma comment(linker, "/EXPORT:CompareFileTime=kernel32.CompareFileTime") +#pragma comment(linker, "/EXPORT:CompareStringA=kernel32.CompareStringA") +#pragma comment(linker, "/EXPORT:CompareStringEx=kernel32.CompareStringEx") +#pragma comment(linker, "/EXPORT:CompareStringOrdinal=kernel32.CompareStringOrdinal") +#pragma comment(linker, "/EXPORT:CompareStringW=kernel32.CompareStringW") +#pragma comment(linker, "/EXPORT:ConnectNamedPipe=kernel32.ConnectNamedPipe") +#pragma comment(linker, "/EXPORT:ConsoleMenuControl=kernel32.ConsoleMenuControl") +#pragma comment(linker, "/EXPORT:ContinueDebugEvent=kernel32.ContinueDebugEvent") +#pragma comment(linker, "/EXPORT:ConvertCalDateTimeToSystemTime=kernel32.ConvertCalDateTimeToSystemTime") +#pragma comment(linker, "/EXPORT:ConvertDefaultLocale=kernel32.ConvertDefaultLocale") +#pragma comment(linker, "/EXPORT:ConvertFiberToThread=kernel32.ConvertFiberToThread") +#pragma comment(linker, "/EXPORT:ConvertNLSDayOfWeekToWin32DayOfWeek=kernel32.ConvertNLSDayOfWeekToWin32DayOfWeek") +#pragma comment(linker, "/EXPORT:ConvertSystemTimeToCalDateTime=kernel32.ConvertSystemTimeToCalDateTime") +#pragma comment(linker, "/EXPORT:ConvertThreadToFiber=kernel32.ConvertThreadToFiber") +#pragma comment(linker, "/EXPORT:ConvertThreadToFiberEx=kernel32.ConvertThreadToFiberEx") +#pragma comment(linker, "/EXPORT:CopyContext=kernel32.CopyContext") +#pragma comment(linker, "/EXPORT:CopyFileA=kernel32.CopyFileA") +#pragma comment(linker, "/EXPORT:CopyFileExA=kernel32.CopyFileExA") +#pragma comment(linker, "/EXPORT:CopyFileExW=kernel32.CopyFileExW") +#pragma comment(linker, "/EXPORT:CopyFileTransactedA=kernel32.CopyFileTransactedA") +#pragma comment(linker, "/EXPORT:CopyFileTransactedW=kernel32.CopyFileTransactedW") +#pragma comment(linker, "/EXPORT:CopyFileW=kernel32.CopyFileW") +#pragma comment(linker, "/EXPORT:CopyLZFile=kernel32.CopyLZFile") +#pragma comment(linker, "/EXPORT:CreateActCtxA=kernel32.CreateActCtxA") +#pragma comment(linker, "/EXPORT:CreateActCtxW=kernel32.CreateActCtxW") +#pragma comment(linker, "/EXPORT:CreateBoundaryDescriptorA=kernel32.CreateBoundaryDescriptorA") +#pragma comment(linker, "/EXPORT:CreateBoundaryDescriptorW=kernel32.CreateBoundaryDescriptorW") +#pragma comment(linker, "/EXPORT:CreateConsoleScreenBuffer=kernel32.CreateConsoleScreenBuffer") +#pragma comment(linker, "/EXPORT:CreateDirectoryA=kernel32.CreateDirectoryA") +#pragma comment(linker, "/EXPORT:CreateDirectoryExA=kernel32.CreateDirectoryExA") +#pragma comment(linker, "/EXPORT:CreateDirectoryExW=kernel32.CreateDirectoryExW") +#pragma comment(linker, "/EXPORT:CreateDirectoryTransactedA=kernel32.CreateDirectoryTransactedA") +#pragma comment(linker, "/EXPORT:CreateDirectoryTransactedW=kernel32.CreateDirectoryTransactedW") +#pragma comment(linker, "/EXPORT:CreateDirectoryW=kernel32.CreateDirectoryW") +#pragma comment(linker, "/EXPORT:CreateEventA=kernel32.CreateEventA") +#pragma comment(linker, "/EXPORT:CreateEventExA=kernel32.CreateEventExA") +#pragma comment(linker, "/EXPORT:CreateEventExW=kernel32.CreateEventExW") +#pragma comment(linker, "/EXPORT:CreateEventW=kernel32.CreateEventW") +#pragma comment(linker, "/EXPORT:CreateFiber=kernel32.CreateFiber") +#pragma comment(linker, "/EXPORT:CreateFiberEx=kernel32.CreateFiberEx") +#pragma comment(linker, "/EXPORT:CreateFileA=kernel32.CreateFileA") +#pragma comment(linker, "/EXPORT:CreateFileMappingA=kernel32.CreateFileMappingA") +#pragma comment(linker, "/EXPORT:CreateFileMappingNumaA=kernel32.CreateFileMappingNumaA") +#pragma comment(linker, "/EXPORT:CreateFileMappingNumaW=kernel32.CreateFileMappingNumaW") +#pragma comment(linker, "/EXPORT:CreateFileMappingW=kernel32.CreateFileMappingW") +#pragma comment(linker, "/EXPORT:CreateFileTransactedA=kernel32.CreateFileTransactedA") +#pragma comment(linker, "/EXPORT:CreateFileTransactedW=kernel32.CreateFileTransactedW") +#pragma comment(linker, "/EXPORT:CreateFileW=kernel32.CreateFileW") +#pragma comment(linker, "/EXPORT:CreateHardLinkA=kernel32.CreateHardLinkA") +#pragma comment(linker, "/EXPORT:CreateHardLinkTransactedA=kernel32.CreateHardLinkTransactedA") +#pragma comment(linker, "/EXPORT:CreateHardLinkTransactedW=kernel32.CreateHardLinkTransactedW") +#pragma comment(linker, "/EXPORT:CreateHardLinkW=kernel32.CreateHardLinkW") +#pragma comment(linker, "/EXPORT:CreateIoCompletionPort=kernel32.CreateIoCompletionPort") +#pragma comment(linker, "/EXPORT:CreateJobObjectA=kernel32.CreateJobObjectA") +#pragma comment(linker, "/EXPORT:CreateJobObjectW=kernel32.CreateJobObjectW") +#pragma comment(linker, "/EXPORT:CreateJobSet=kernel32.CreateJobSet") +#pragma comment(linker, "/EXPORT:CreateMailslotA=kernel32.CreateMailslotA") +#pragma comment(linker, "/EXPORT:CreateMailslotW=kernel32.CreateMailslotW") +#pragma comment(linker, "/EXPORT:CreateMemoryResourceNotification=kernel32.CreateMemoryResourceNotification") +#pragma comment(linker, "/EXPORT:CreateMutexA=kernel32.CreateMutexA") +#pragma comment(linker, "/EXPORT:CreateMutexExA=kernel32.CreateMutexExA") +#pragma comment(linker, "/EXPORT:CreateMutexExW=kernel32.CreateMutexExW") +#pragma comment(linker, "/EXPORT:CreateMutexW=kernel32.CreateMutexW") +#pragma comment(linker, "/EXPORT:CreateNamedPipeA=kernel32.CreateNamedPipeA") +#pragma comment(linker, "/EXPORT:CreateNamedPipeW=kernel32.CreateNamedPipeW") +#pragma comment(linker, "/EXPORT:CreatePipe=kernel32.CreatePipe") +#pragma comment(linker, "/EXPORT:CreatePrivateNamespaceA=kernel32.CreatePrivateNamespaceA") +#pragma comment(linker, "/EXPORT:CreatePrivateNamespaceW=kernel32.CreatePrivateNamespaceW") +#pragma comment(linker, "/EXPORT:CreateProcessA=kernel32.CreateProcessA") +#pragma comment(linker, "/EXPORT:CreateProcessAsUserW=kernel32.CreateProcessAsUserW") +#pragma comment(linker, "/EXPORT:CreateProcessInternalA=kernel32.CreateProcessInternalA") +#pragma comment(linker, "/EXPORT:CreateProcessInternalW=kernel32.CreateProcessInternalW") +#pragma comment(linker, "/EXPORT:CreateProcessW=kernel32.CreateProcessW") +#pragma comment(linker, "/EXPORT:CreateRemoteThread=kernel32.CreateRemoteThread") +#pragma comment(linker, "/EXPORT:CreateRemoteThreadEx=kernel32.CreateRemoteThreadEx") +#pragma comment(linker, "/EXPORT:CreateSemaphoreA=kernel32.CreateSemaphoreA") +#pragma comment(linker, "/EXPORT:CreateSemaphoreExA=kernel32.CreateSemaphoreExA") +#pragma comment(linker, "/EXPORT:CreateSemaphoreExW=kernel32.CreateSemaphoreExW") +#pragma comment(linker, "/EXPORT:CreateSemaphoreW=kernel32.CreateSemaphoreW") +#pragma comment(linker, "/EXPORT:CreateSymbolicLinkA=kernel32.CreateSymbolicLinkA") +#pragma comment(linker, "/EXPORT:CreateSymbolicLinkTransactedA=kernel32.CreateSymbolicLinkTransactedA") +#pragma comment(linker, "/EXPORT:CreateSymbolicLinkTransactedW=kernel32.CreateSymbolicLinkTransactedW") +#pragma comment(linker, "/EXPORT:CreateSymbolicLinkW=kernel32.CreateSymbolicLinkW") +#pragma comment(linker, "/EXPORT:CreateTapePartition=kernel32.CreateTapePartition") +#pragma comment(linker, "/EXPORT:CreateThread=kernel32.CreateThread") +#pragma comment(linker, "/EXPORT:CreateThreadpool=kernel32.CreateThreadpool") +#pragma comment(linker, "/EXPORT:CreateThreadpoolCleanupGroup=kernel32.CreateThreadpoolCleanupGroup") +#pragma comment(linker, "/EXPORT:CreateThreadpoolIo=kernel32.CreateThreadpoolIo") +#pragma comment(linker, "/EXPORT:CreateThreadpoolTimer=kernel32.CreateThreadpoolTimer") +#pragma comment(linker, "/EXPORT:CreateThreadpoolWait=kernel32.CreateThreadpoolWait") +#pragma comment(linker, "/EXPORT:CreateThreadpoolWork=kernel32.CreateThreadpoolWork") +#pragma comment(linker, "/EXPORT:CreateTimerQueue=kernel32.CreateTimerQueue") +#pragma comment(linker, "/EXPORT:CreateTimerQueueTimer=kernel32.CreateTimerQueueTimer") +#pragma comment(linker, "/EXPORT:CreateToolhelp32Snapshot=kernel32.CreateToolhelp32Snapshot") +#pragma comment(linker, "/EXPORT:CreateWaitableTimerA=kernel32.CreateWaitableTimerA") +#pragma comment(linker, "/EXPORT:CreateWaitableTimerExA=kernel32.CreateWaitableTimerExA") +#pragma comment(linker, "/EXPORT:CreateWaitableTimerExW=kernel32.CreateWaitableTimerExW") +#pragma comment(linker, "/EXPORT:CreateWaitableTimerW=kernel32.CreateWaitableTimerW") +#pragma comment(linker, "/EXPORT:CtrlRoutine=kernel32.CtrlRoutine") +#pragma comment(linker, "/EXPORT:DeactivateActCtx=kernel32.DeactivateActCtx") +#pragma comment(linker, "/EXPORT:DebugActiveProcess=kernel32.DebugActiveProcess") +#pragma comment(linker, "/EXPORT:DebugActiveProcessStop=kernel32.DebugActiveProcessStop") +#pragma comment(linker, "/EXPORT:DebugBreak=kernel32.DebugBreak") +#pragma comment(linker, "/EXPORT:DebugBreakProcess=kernel32.DebugBreakProcess") +#pragma comment(linker, "/EXPORT:DebugSetProcessKillOnExit=kernel32.DebugSetProcessKillOnExit") +#pragma comment(linker, "/EXPORT:DecodePointer=kernel32.DecodePointer") +#pragma comment(linker, "/EXPORT:DecodeSystemPointer=kernel32.DecodeSystemPointer") +#pragma comment(linker, "/EXPORT:DefineDosDeviceA=kernel32.DefineDosDeviceA") +#pragma comment(linker, "/EXPORT:DefineDosDeviceW=kernel32.DefineDosDeviceW") +#pragma comment(linker, "/EXPORT:DelayLoadFailureHook=kernel32.DelayLoadFailureHook") +#pragma comment(linker, "/EXPORT:DeleteAtom=kernel32.DeleteAtom") +#pragma comment(linker, "/EXPORT:DeleteBoundaryDescriptor=kernel32.DeleteBoundaryDescriptor") +#pragma comment(linker, "/EXPORT:DeleteCriticalSection=kernel32.DeleteCriticalSection") +#pragma comment(linker, "/EXPORT:DeleteFiber=kernel32.DeleteFiber") +#pragma comment(linker, "/EXPORT:DeleteFileA=kernel32.DeleteFileA") +#pragma comment(linker, "/EXPORT:DeleteFileTransactedA=kernel32.DeleteFileTransactedA") +#pragma comment(linker, "/EXPORT:DeleteFileTransactedW=kernel32.DeleteFileTransactedW") +#pragma comment(linker, "/EXPORT:DeleteFileW=kernel32.DeleteFileW") +#pragma comment(linker, "/EXPORT:DeleteProcThreadAttributeList=kernel32.DeleteProcThreadAttributeList") +#pragma comment(linker, "/EXPORT:DeleteTimerQueue=kernel32.DeleteTimerQueue") +#pragma comment(linker, "/EXPORT:DeleteTimerQueueEx=kernel32.DeleteTimerQueueEx") +#pragma comment(linker, "/EXPORT:DeleteTimerQueueTimer=kernel32.DeleteTimerQueueTimer") +#pragma comment(linker, "/EXPORT:DeleteVolumeMountPointA=kernel32.DeleteVolumeMountPointA") +#pragma comment(linker, "/EXPORT:DeleteVolumeMountPointW=kernel32.DeleteVolumeMountPointW") +#pragma comment(linker, "/EXPORT:DeviceIoControl=kernel32.DeviceIoControl") +#pragma comment(linker, "/EXPORT:DisableThreadLibraryCalls=kernel32.DisableThreadLibraryCalls") +#pragma comment(linker, "/EXPORT:DisableThreadProfiling=kernel32.DisableThreadProfiling") +#pragma comment(linker, "/EXPORT:DisassociateCurrentThreadFromCallback=kernel32.DisassociateCurrentThreadFromCallback") +#pragma comment(linker, "/EXPORT:DisconnectNamedPipe=kernel32.DisconnectNamedPipe") +#pragma comment(linker, "/EXPORT:DnsHostnameToComputerNameA=kernel32.DnsHostnameToComputerNameA") +#pragma comment(linker, "/EXPORT:DnsHostnameToComputerNameW=kernel32.DnsHostnameToComputerNameW") +#pragma comment(linker, "/EXPORT:DosDateTimeToFileTime=kernel32.DosDateTimeToFileTime") +#pragma comment(linker, "/EXPORT:DosPathToSessionPathA=kernel32.DosPathToSessionPathA") +#pragma comment(linker, "/EXPORT:DosPathToSessionPathW=kernel32.DosPathToSessionPathW") +#pragma comment(linker, "/EXPORT:DuplicateConsoleHandle=kernel32.DuplicateConsoleHandle") +//#pragma comment(linker, "/EXPORT:DuplicateHandle=kernel32.DuplicateHandle") +#pragma comment(linker, "/EXPORT:EnableThreadProfiling=kernel32.EnableThreadProfiling") +#pragma comment(linker, "/EXPORT:EncodePointer=kernel32.EncodePointer") +#pragma comment(linker, "/EXPORT:EncodeSystemPointer=kernel32.EncodeSystemPointer") +#pragma comment(linker, "/EXPORT:EndUpdateResourceA=kernel32.EndUpdateResourceA") +#pragma comment(linker, "/EXPORT:EndUpdateResourceW=kernel32.EndUpdateResourceW") +#pragma comment(linker, "/EXPORT:EnterCriticalSection=kernel32.EnterCriticalSection") +#pragma comment(linker, "/EXPORT:EnumCalendarInfoA=kernel32.EnumCalendarInfoA") +#pragma comment(linker, "/EXPORT:EnumCalendarInfoExA=kernel32.EnumCalendarInfoExA") +#pragma comment(linker, "/EXPORT:EnumCalendarInfoExEx=kernel32.EnumCalendarInfoExEx") +#pragma comment(linker, "/EXPORT:EnumCalendarInfoExW=kernel32.EnumCalendarInfoExW") +#pragma comment(linker, "/EXPORT:EnumCalendarInfoW=kernel32.EnumCalendarInfoW") +#pragma comment(linker, "/EXPORT:EnumDateFormatsA=kernel32.EnumDateFormatsA") +#pragma comment(linker, "/EXPORT:EnumDateFormatsExA=kernel32.EnumDateFormatsExA") +#pragma comment(linker, "/EXPORT:EnumDateFormatsExEx=kernel32.EnumDateFormatsExEx") +#pragma comment(linker, "/EXPORT:EnumDateFormatsExW=kernel32.EnumDateFormatsExW") +#pragma comment(linker, "/EXPORT:EnumDateFormatsW=kernel32.EnumDateFormatsW") +#pragma comment(linker, "/EXPORT:EnumLanguageGroupLocalesA=kernel32.EnumLanguageGroupLocalesA") +#pragma comment(linker, "/EXPORT:EnumLanguageGroupLocalesW=kernel32.EnumLanguageGroupLocalesW") +#pragma comment(linker, "/EXPORT:EnumResourceLanguagesA=kernel32.EnumResourceLanguagesA") +#pragma comment(linker, "/EXPORT:EnumResourceLanguagesExA=kernel32.EnumResourceLanguagesExA") +#pragma comment(linker, "/EXPORT:EnumResourceLanguagesExW=kernel32.EnumResourceLanguagesExW") +#pragma comment(linker, "/EXPORT:EnumResourceLanguagesW=kernel32.EnumResourceLanguagesW") +#pragma comment(linker, "/EXPORT:EnumResourceNamesA=kernel32.EnumResourceNamesA") +#pragma comment(linker, "/EXPORT:EnumResourceNamesExA=kernel32.EnumResourceNamesExA") +#pragma comment(linker, "/EXPORT:EnumResourceNamesExW=kernel32.EnumResourceNamesExW") +#pragma comment(linker, "/EXPORT:EnumResourceNamesW=kernel32.EnumResourceNamesW") +#pragma comment(linker, "/EXPORT:EnumResourceTypesA=kernel32.EnumResourceTypesA") +#pragma comment(linker, "/EXPORT:EnumResourceTypesExA=kernel32.EnumResourceTypesExA") +#pragma comment(linker, "/EXPORT:EnumResourceTypesExW=kernel32.EnumResourceTypesExW") +#pragma comment(linker, "/EXPORT:EnumResourceTypesW=kernel32.EnumResourceTypesW") +#pragma comment(linker, "/EXPORT:EnumSystemCodePagesA=kernel32.EnumSystemCodePagesA") +#pragma comment(linker, "/EXPORT:EnumSystemCodePagesW=kernel32.EnumSystemCodePagesW") +#pragma comment(linker, "/EXPORT:EnumSystemFirmwareTables=kernel32.EnumSystemFirmwareTables") +#pragma comment(linker, "/EXPORT:EnumSystemGeoID=kernel32.EnumSystemGeoID") +#pragma comment(linker, "/EXPORT:EnumSystemLanguageGroupsA=kernel32.EnumSystemLanguageGroupsA") +#pragma comment(linker, "/EXPORT:EnumSystemLanguageGroupsW=kernel32.EnumSystemLanguageGroupsW") +#pragma comment(linker, "/EXPORT:EnumSystemLocalesA=kernel32.EnumSystemLocalesA") +#pragma comment(linker, "/EXPORT:EnumSystemLocalesEx=kernel32.EnumSystemLocalesEx") +#pragma comment(linker, "/EXPORT:EnumSystemLocalesW=kernel32.EnumSystemLocalesW") +#pragma comment(linker, "/EXPORT:EnumTimeFormatsA=kernel32.EnumTimeFormatsA") +#pragma comment(linker, "/EXPORT:EnumTimeFormatsEx=kernel32.EnumTimeFormatsEx") +#pragma comment(linker, "/EXPORT:EnumTimeFormatsW=kernel32.EnumTimeFormatsW") +#pragma comment(linker, "/EXPORT:EnumUILanguagesA=kernel32.EnumUILanguagesA") +#pragma comment(linker, "/EXPORT:EnumUILanguagesW=kernel32.EnumUILanguagesW") +#pragma comment(linker, "/EXPORT:EnumerateLocalComputerNamesA=kernel32.EnumerateLocalComputerNamesA") +#pragma comment(linker, "/EXPORT:EnumerateLocalComputerNamesW=kernel32.EnumerateLocalComputerNamesW") +#pragma comment(linker, "/EXPORT:EraseTape=kernel32.EraseTape") +#pragma comment(linker, "/EXPORT:EscapeCommFunction=kernel32.EscapeCommFunction") +#pragma comment(linker, "/EXPORT:ExitProcess=kernel32.ExitProcess") +#pragma comment(linker, "/EXPORT:ExitThread=kernel32.ExitThread") +#pragma comment(linker, "/EXPORT:ExitVDM=kernel32.ExitVDM") +#pragma comment(linker, "/EXPORT:ExpandEnvironmentStringsA=kernel32.ExpandEnvironmentStringsA") +#pragma comment(linker, "/EXPORT:ExpandEnvironmentStringsW=kernel32.ExpandEnvironmentStringsW") +#pragma comment(linker, "/EXPORT:ExpungeConsoleCommandHistoryA=kernel32.ExpungeConsoleCommandHistoryA") +#pragma comment(linker, "/EXPORT:ExpungeConsoleCommandHistoryW=kernel32.ExpungeConsoleCommandHistoryW") +#pragma comment(linker, "/EXPORT:FatalAppExitA=kernel32.FatalAppExitA") +#pragma comment(linker, "/EXPORT:FatalAppExitW=kernel32.FatalAppExitW") +#pragma comment(linker, "/EXPORT:FatalExit=kernel32.FatalExit") +#pragma comment(linker, "/EXPORT:FileTimeToDosDateTime=kernel32.FileTimeToDosDateTime") +#pragma comment(linker, "/EXPORT:FileTimeToLocalFileTime=kernel32.FileTimeToLocalFileTime") +#pragma comment(linker, "/EXPORT:FileTimeToSystemTime=kernel32.FileTimeToSystemTime") +#pragma comment(linker, "/EXPORT:FillConsoleOutputAttribute=kernel32.FillConsoleOutputAttribute") +#pragma comment(linker, "/EXPORT:FillConsoleOutputCharacterA=kernel32.FillConsoleOutputCharacterA") +#pragma comment(linker, "/EXPORT:FillConsoleOutputCharacterW=kernel32.FillConsoleOutputCharacterW") +#pragma comment(linker, "/EXPORT:FindActCtxSectionGuid=kernel32.FindActCtxSectionGuid") +#pragma comment(linker, "/EXPORT:FindActCtxSectionStringA=kernel32.FindActCtxSectionStringA") +#pragma comment(linker, "/EXPORT:FindActCtxSectionStringW=kernel32.FindActCtxSectionStringW") +#pragma comment(linker, "/EXPORT:FindAtomA=kernel32.FindAtomA") +#pragma comment(linker, "/EXPORT:FindAtomW=kernel32.FindAtomW") +#pragma comment(linker, "/EXPORT:FindClose=kernel32.FindClose") +#pragma comment(linker, "/EXPORT:FindCloseChangeNotification=kernel32.FindCloseChangeNotification") +#pragma comment(linker, "/EXPORT:FindFirstChangeNotificationA=kernel32.FindFirstChangeNotificationA") +#pragma comment(linker, "/EXPORT:FindFirstChangeNotificationW=kernel32.FindFirstChangeNotificationW") +#pragma comment(linker, "/EXPORT:FindFirstFileA=kernel32.FindFirstFileA") +#pragma comment(linker, "/EXPORT:FindFirstFileExA=kernel32.FindFirstFileExA") +#pragma comment(linker, "/EXPORT:FindFirstFileExW=kernel32.FindFirstFileExW") +#pragma comment(linker, "/EXPORT:FindFirstFileNameTransactedW=kernel32.FindFirstFileNameTransactedW") +#pragma comment(linker, "/EXPORT:FindFirstFileNameW=kernel32.FindFirstFileNameW") +#pragma comment(linker, "/EXPORT:FindFirstFileTransactedA=kernel32.FindFirstFileTransactedA") +#pragma comment(linker, "/EXPORT:FindFirstFileTransactedW=kernel32.FindFirstFileTransactedW") +#pragma comment(linker, "/EXPORT:FindFirstFileW=kernel32.FindFirstFileW") +#pragma comment(linker, "/EXPORT:FindFirstStreamTransactedW=kernel32.FindFirstStreamTransactedW") +#pragma comment(linker, "/EXPORT:FindFirstStreamW=kernel32.FindFirstStreamW") +#pragma comment(linker, "/EXPORT:FindFirstVolumeA=kernel32.FindFirstVolumeA") +#pragma comment(linker, "/EXPORT:FindFirstVolumeMountPointA=kernel32.FindFirstVolumeMountPointA") +#pragma comment(linker, "/EXPORT:FindFirstVolumeMountPointW=kernel32.FindFirstVolumeMountPointW") +#pragma comment(linker, "/EXPORT:FindFirstVolumeW=kernel32.FindFirstVolumeW") +#pragma comment(linker, "/EXPORT:FindNLSString=kernel32.FindNLSString") +#pragma comment(linker, "/EXPORT:FindNLSStringEx=kernel32.FindNLSStringEx") +#pragma comment(linker, "/EXPORT:FindNextChangeNotification=kernel32.FindNextChangeNotification") +#pragma comment(linker, "/EXPORT:FindNextFileA=kernel32.FindNextFileA") +#pragma comment(linker, "/EXPORT:FindNextFileNameW=kernel32.FindNextFileNameW") +#pragma comment(linker, "/EXPORT:FindNextFileW=kernel32.FindNextFileW") +#pragma comment(linker, "/EXPORT:FindNextStreamW=kernel32.FindNextStreamW") +#pragma comment(linker, "/EXPORT:FindNextVolumeA=kernel32.FindNextVolumeA") +#pragma comment(linker, "/EXPORT:FindNextVolumeMountPointA=kernel32.FindNextVolumeMountPointA") +#pragma comment(linker, "/EXPORT:FindNextVolumeMountPointW=kernel32.FindNextVolumeMountPointW") +#pragma comment(linker, "/EXPORT:FindNextVolumeW=kernel32.FindNextVolumeW") +#pragma comment(linker, "/EXPORT:FindResourceA=kernel32.FindResourceA") +#pragma comment(linker, "/EXPORT:FindResourceExA=kernel32.FindResourceExA") +#pragma comment(linker, "/EXPORT:FindResourceExW=kernel32.FindResourceExW") +#pragma comment(linker, "/EXPORT:FindResourceW=kernel32.FindResourceW") +#pragma comment(linker, "/EXPORT:FindStringOrdinal=kernel32.FindStringOrdinal") +#pragma comment(linker, "/EXPORT:FindVolumeClose=kernel32.FindVolumeClose") +#pragma comment(linker, "/EXPORT:FindVolumeMountPointClose=kernel32.FindVolumeMountPointClose") +#pragma comment(linker, "/EXPORT:FlsAlloc=kernel32.FlsAlloc") +#pragma comment(linker, "/EXPORT:FlsFree=kernel32.FlsFree") +#pragma comment(linker, "/EXPORT:FlsGetValue=kernel32.FlsGetValue") +#pragma comment(linker, "/EXPORT:FlsSetValue=kernel32.FlsSetValue") +#pragma comment(linker, "/EXPORT:FlushConsoleInputBuffer=kernel32.FlushConsoleInputBuffer") +#pragma comment(linker, "/EXPORT:FlushFileBuffers=kernel32.FlushFileBuffers") +#pragma comment(linker, "/EXPORT:FlushInstructionCache=kernel32.FlushInstructionCache") +#pragma comment(linker, "/EXPORT:FlushProcessWriteBuffers=kernel32.FlushProcessWriteBuffers") +#pragma comment(linker, "/EXPORT:FlushViewOfFile=kernel32.FlushViewOfFile") +#pragma comment(linker, "/EXPORT:FoldStringA=kernel32.FoldStringA") +#pragma comment(linker, "/EXPORT:FoldStringW=kernel32.FoldStringW") +#pragma comment(linker, "/EXPORT:FormatMessageA=kernel32.FormatMessageA") +#pragma comment(linker, "/EXPORT:FormatMessageW=kernel32.FormatMessageW") +#pragma comment(linker, "/EXPORT:FreeConsole=kernel32.FreeConsole") +#pragma comment(linker, "/EXPORT:FreeEnvironmentStringsA=kernel32.FreeEnvironmentStringsA") +#pragma comment(linker, "/EXPORT:FreeEnvironmentStringsW=kernel32.FreeEnvironmentStringsW") +#pragma comment(linker, "/EXPORT:FreeLibrary=kernel32.FreeLibrary") +#pragma comment(linker, "/EXPORT:FreeLibraryAndExitThread=kernel32.FreeLibraryAndExitThread") +#pragma comment(linker, "/EXPORT:FreeLibraryWhenCallbackReturns=kernel32.FreeLibraryWhenCallbackReturns") +#pragma comment(linker, "/EXPORT:FreeResource=kernel32.FreeResource") +#pragma comment(linker, "/EXPORT:FreeUserPhysicalPages=kernel32.FreeUserPhysicalPages") +#pragma comment(linker, "/EXPORT:GenerateConsoleCtrlEvent=kernel32.GenerateConsoleCtrlEvent") +#pragma comment(linker, "/EXPORT:GetACP=kernel32.GetACP") +#pragma comment(linker, "/EXPORT:GetActiveProcessorCount=kernel32.GetActiveProcessorCount") +#pragma comment(linker, "/EXPORT:GetActiveProcessorGroupCount=kernel32.GetActiveProcessorGroupCount") +#pragma comment(linker, "/EXPORT:GetApplicationRecoveryCallback=kernel32.GetApplicationRecoveryCallback") +#pragma comment(linker, "/EXPORT:GetApplicationRestartSettings=kernel32.GetApplicationRestartSettings") +#pragma comment(linker, "/EXPORT:GetAtomNameA=kernel32.GetAtomNameA") +#pragma comment(linker, "/EXPORT:GetAtomNameW=kernel32.GetAtomNameW") +#pragma comment(linker, "/EXPORT:GetBinaryType=kernel32.GetBinaryType") +#pragma comment(linker, "/EXPORT:GetBinaryTypeA=kernel32.GetBinaryTypeA") +#pragma comment(linker, "/EXPORT:GetBinaryTypeW=kernel32.GetBinaryTypeW") +#pragma comment(linker, "/EXPORT:GetCPInfo=kernel32.GetCPInfo") +#pragma comment(linker, "/EXPORT:GetCPInfoExA=kernel32.GetCPInfoExA") +#pragma comment(linker, "/EXPORT:GetCPInfoExW=kernel32.GetCPInfoExW") +#pragma comment(linker, "/EXPORT:GetCalendarDateFormat=kernel32.GetCalendarDateFormat") +#pragma comment(linker, "/EXPORT:GetCalendarDateFormatEx=kernel32.GetCalendarDateFormatEx") +#pragma comment(linker, "/EXPORT:GetCalendarDaysInMonth=kernel32.GetCalendarDaysInMonth") +#pragma comment(linker, "/EXPORT:GetCalendarDifferenceInDays=kernel32.GetCalendarDifferenceInDays") +#pragma comment(linker, "/EXPORT:GetCalendarInfoA=kernel32.GetCalendarInfoA") +#pragma comment(linker, "/EXPORT:GetCalendarInfoEx=kernel32.GetCalendarInfoEx") +#pragma comment(linker, "/EXPORT:GetCalendarInfoW=kernel32.GetCalendarInfoW") +#pragma comment(linker, "/EXPORT:GetCalendarMonthsInYear=kernel32.GetCalendarMonthsInYear") +#pragma comment(linker, "/EXPORT:GetCalendarSupportedDateRange=kernel32.GetCalendarSupportedDateRange") +#pragma comment(linker, "/EXPORT:GetCalendarWeekNumber=kernel32.GetCalendarWeekNumber") +#pragma comment(linker, "/EXPORT:GetComPlusPackageInstallStatus=kernel32.GetComPlusPackageInstallStatus") +#pragma comment(linker, "/EXPORT:GetCommConfig=kernel32.GetCommConfig") +#pragma comment(linker, "/EXPORT:GetCommMask=kernel32.GetCommMask") +#pragma comment(linker, "/EXPORT:GetCommModemStatus=kernel32.GetCommModemStatus") +#pragma comment(linker, "/EXPORT:GetCommProperties=kernel32.GetCommProperties") +#pragma comment(linker, "/EXPORT:GetCommState=kernel32.GetCommState") +#pragma comment(linker, "/EXPORT:GetCommTimeouts=kernel32.GetCommTimeouts") +#pragma comment(linker, "/EXPORT:GetCommandLineA=kernel32.GetCommandLineA") +#pragma comment(linker, "/EXPORT:GetCommandLineW=kernel32.GetCommandLineW") +#pragma comment(linker, "/EXPORT:GetCompressedFileSizeA=kernel32.GetCompressedFileSizeA") +#pragma comment(linker, "/EXPORT:GetCompressedFileSizeTransactedA=kernel32.GetCompressedFileSizeTransactedA") +#pragma comment(linker, "/EXPORT:GetCompressedFileSizeTransactedW=kernel32.GetCompressedFileSizeTransactedW") +#pragma comment(linker, "/EXPORT:GetCompressedFileSizeW=kernel32.GetCompressedFileSizeW") +#pragma comment(linker, "/EXPORT:GetComputerNameA=kernel32.GetComputerNameA") +#pragma comment(linker, "/EXPORT:GetComputerNameExA=kernel32.GetComputerNameExA") +#pragma comment(linker, "/EXPORT:GetComputerNameExW=kernel32.GetComputerNameExW") +#pragma comment(linker, "/EXPORT:GetComputerNameW=kernel32.GetComputerNameW") +#pragma comment(linker, "/EXPORT:GetConsoleAliasA=kernel32.GetConsoleAliasA") +#pragma comment(linker, "/EXPORT:GetConsoleAliasExesA=kernel32.GetConsoleAliasExesA") +#pragma comment(linker, "/EXPORT:GetConsoleAliasExesLengthA=kernel32.GetConsoleAliasExesLengthA") +#pragma comment(linker, "/EXPORT:GetConsoleAliasExesLengthW=kernel32.GetConsoleAliasExesLengthW") +#pragma comment(linker, "/EXPORT:GetConsoleAliasExesW=kernel32.GetConsoleAliasExesW") +#pragma comment(linker, "/EXPORT:GetConsoleAliasW=kernel32.GetConsoleAliasW") +#pragma comment(linker, "/EXPORT:GetConsoleAliasesA=kernel32.GetConsoleAliasesA") +#pragma comment(linker, "/EXPORT:GetConsoleAliasesLengthA=kernel32.GetConsoleAliasesLengthA") +#pragma comment(linker, "/EXPORT:GetConsoleAliasesLengthW=kernel32.GetConsoleAliasesLengthW") +#pragma comment(linker, "/EXPORT:GetConsoleAliasesW=kernel32.GetConsoleAliasesW") +#pragma comment(linker, "/EXPORT:GetConsoleCP=kernel32.GetConsoleCP") +#pragma comment(linker, "/EXPORT:GetConsoleCharType=kernel32.GetConsoleCharType") +#pragma comment(linker, "/EXPORT:GetConsoleCommandHistoryA=kernel32.GetConsoleCommandHistoryA") +#pragma comment(linker, "/EXPORT:GetConsoleCommandHistoryLengthA=kernel32.GetConsoleCommandHistoryLengthA") +#pragma comment(linker, "/EXPORT:GetConsoleCommandHistoryLengthW=kernel32.GetConsoleCommandHistoryLengthW") +#pragma comment(linker, "/EXPORT:GetConsoleCommandHistoryW=kernel32.GetConsoleCommandHistoryW") +#pragma comment(linker, "/EXPORT:GetConsoleCursorInfo=kernel32.GetConsoleCursorInfo") +#pragma comment(linker, "/EXPORT:GetConsoleCursorMode=kernel32.GetConsoleCursorMode") +#pragma comment(linker, "/EXPORT:GetConsoleDisplayMode=kernel32.GetConsoleDisplayMode") +#pragma comment(linker, "/EXPORT:GetConsoleFontInfo=kernel32.GetConsoleFontInfo") +#pragma comment(linker, "/EXPORT:GetConsoleFontSize=kernel32.GetConsoleFontSize") +#pragma comment(linker, "/EXPORT:GetConsoleHardwareState=kernel32.GetConsoleHardwareState") +#pragma comment(linker, "/EXPORT:GetConsoleHistoryInfo=kernel32.GetConsoleHistoryInfo") +#pragma comment(linker, "/EXPORT:GetConsoleInputExeNameA=kernel32.GetConsoleInputExeNameA") +#pragma comment(linker, "/EXPORT:GetConsoleInputExeNameW=kernel32.GetConsoleInputExeNameW") +#pragma comment(linker, "/EXPORT:GetConsoleInputWaitHandle=kernel32.GetConsoleInputWaitHandle") +#pragma comment(linker, "/EXPORT:GetConsoleKeyboardLayoutNameA=kernel32.GetConsoleKeyboardLayoutNameA") +#pragma comment(linker, "/EXPORT:GetConsoleKeyboardLayoutNameW=kernel32.GetConsoleKeyboardLayoutNameW") +#pragma comment(linker, "/EXPORT:GetConsoleMode=kernel32.GetConsoleMode") +#pragma comment(linker, "/EXPORT:GetConsoleNlsMode=kernel32.GetConsoleNlsMode") +#pragma comment(linker, "/EXPORT:GetConsoleOriginalTitleA=kernel32.GetConsoleOriginalTitleA") +#pragma comment(linker, "/EXPORT:GetConsoleOriginalTitleW=kernel32.GetConsoleOriginalTitleW") +#pragma comment(linker, "/EXPORT:GetConsoleOutputCP=kernel32.GetConsoleOutputCP") +#pragma comment(linker, "/EXPORT:GetConsoleProcessList=kernel32.GetConsoleProcessList") +#pragma comment(linker, "/EXPORT:GetConsoleScreenBufferInfo=kernel32.GetConsoleScreenBufferInfo") +#pragma comment(linker, "/EXPORT:GetConsoleScreenBufferInfoEx=kernel32.GetConsoleScreenBufferInfoEx") +#pragma comment(linker, "/EXPORT:GetConsoleSelectionInfo=kernel32.GetConsoleSelectionInfo") +#pragma comment(linker, "/EXPORT:GetConsoleTitleA=kernel32.GetConsoleTitleA") +#pragma comment(linker, "/EXPORT:GetConsoleTitleW=kernel32.GetConsoleTitleW") +#pragma comment(linker, "/EXPORT:GetConsoleWindow=kernel32.GetConsoleWindow") +#pragma comment(linker, "/EXPORT:GetCurrencyFormatA=kernel32.GetCurrencyFormatA") +#pragma comment(linker, "/EXPORT:GetCurrencyFormatEx=kernel32.GetCurrencyFormatEx") +#pragma comment(linker, "/EXPORT:GetCurrencyFormatW=kernel32.GetCurrencyFormatW") +#pragma comment(linker, "/EXPORT:GetCurrentActCtx=kernel32.GetCurrentActCtx") +#pragma comment(linker, "/EXPORT:GetCurrentConsoleFont=kernel32.GetCurrentConsoleFont") +#pragma comment(linker, "/EXPORT:GetCurrentConsoleFontEx=kernel32.GetCurrentConsoleFontEx") +#pragma comment(linker, "/EXPORT:GetCurrentDirectoryA=kernel32.GetCurrentDirectoryA") +#pragma comment(linker, "/EXPORT:GetCurrentDirectoryW=kernel32.GetCurrentDirectoryW") +#pragma comment(linker, "/EXPORT:GetCurrentProcess=kernel32.GetCurrentProcess") +#pragma comment(linker, "/EXPORT:GetCurrentProcessId=kernel32.GetCurrentProcessId") +#pragma comment(linker, "/EXPORT:GetCurrentProcessorNumber=kernel32.GetCurrentProcessorNumber") +#pragma comment(linker, "/EXPORT:GetCurrentProcessorNumberEx=kernel32.GetCurrentProcessorNumberEx") +#pragma comment(linker, "/EXPORT:GetCurrentThread=kernel32.GetCurrentThread") +#pragma comment(linker, "/EXPORT:GetCurrentThreadId=kernel32.GetCurrentThreadId") +#pragma comment(linker, "/EXPORT:GetDateFormatA=kernel32.GetDateFormatA") +#pragma comment(linker, "/EXPORT:GetDateFormatEx=kernel32.GetDateFormatEx") +#pragma comment(linker, "/EXPORT:GetDateFormatW=kernel32.GetDateFormatW") +#pragma comment(linker, "/EXPORT:GetDefaultCommConfigA=kernel32.GetDefaultCommConfigA") +#pragma comment(linker, "/EXPORT:GetDefaultCommConfigW=kernel32.GetDefaultCommConfigW") +#pragma comment(linker, "/EXPORT:GetDevicePowerState=kernel32.GetDevicePowerState") +#pragma comment(linker, "/EXPORT:GetDiskFreeSpaceA=kernel32.GetDiskFreeSpaceA") +#pragma comment(linker, "/EXPORT:GetDiskFreeSpaceExA=kernel32.GetDiskFreeSpaceExA") +#pragma comment(linker, "/EXPORT:GetDiskFreeSpaceExW=kernel32.GetDiskFreeSpaceExW") +#pragma comment(linker, "/EXPORT:GetDiskFreeSpaceW=kernel32.GetDiskFreeSpaceW") +#pragma comment(linker, "/EXPORT:GetDllDirectoryA=kernel32.GetDllDirectoryA") +#pragma comment(linker, "/EXPORT:GetDllDirectoryW=kernel32.GetDllDirectoryW") +#pragma comment(linker, "/EXPORT:GetDriveTypeA=kernel32.GetDriveTypeA") +#pragma comment(linker, "/EXPORT:GetDriveTypeW=kernel32.GetDriveTypeW") +#pragma comment(linker, "/EXPORT:GetDurationFormat=kernel32.GetDurationFormat") +#pragma comment(linker, "/EXPORT:GetDurationFormatEx=kernel32.GetDurationFormatEx") +#pragma comment(linker, "/EXPORT:GetDynamicTimeZoneInformation=kernel32.GetDynamicTimeZoneInformation") +#pragma comment(linker, "/EXPORT:GetEnabledXStateFeatures=kernel32.GetEnabledXStateFeatures") +#pragma comment(linker, "/EXPORT:GetEnvironmentStrings=kernel32.GetEnvironmentStrings") +#pragma comment(linker, "/EXPORT:GetEnvironmentStringsA=kernel32.GetEnvironmentStringsA") +#pragma comment(linker, "/EXPORT:GetEnvironmentStringsW=kernel32.GetEnvironmentStringsW") +#pragma comment(linker, "/EXPORT:GetEnvironmentVariableA=kernel32.GetEnvironmentVariableA") +#pragma comment(linker, "/EXPORT:GetEnvironmentVariableW=kernel32.GetEnvironmentVariableW") +#pragma comment(linker, "/EXPORT:GetEraNameCountedString=kernel32.GetEraNameCountedString") +#pragma comment(linker, "/EXPORT:GetErrorMode=kernel32.GetErrorMode") +#pragma comment(linker, "/EXPORT:GetExitCodeProcess=kernel32.GetExitCodeProcess") +#pragma comment(linker, "/EXPORT:GetExitCodeThread=kernel32.GetExitCodeThread") +#pragma comment(linker, "/EXPORT:GetExpandedNameA=kernel32.GetExpandedNameA") +#pragma comment(linker, "/EXPORT:GetExpandedNameW=kernel32.GetExpandedNameW") +#pragma comment(linker, "/EXPORT:GetFileAttributesA=kernel32.GetFileAttributesA") +#pragma comment(linker, "/EXPORT:GetFileAttributesExA=kernel32.GetFileAttributesExA") +#pragma comment(linker, "/EXPORT:GetFileAttributesExW=kernel32.GetFileAttributesExW") +#pragma comment(linker, "/EXPORT:GetFileAttributesTransactedA=kernel32.GetFileAttributesTransactedA") +#pragma comment(linker, "/EXPORT:GetFileAttributesTransactedW=kernel32.GetFileAttributesTransactedW") +#pragma comment(linker, "/EXPORT:GetFileAttributesW=kernel32.GetFileAttributesW") +#pragma comment(linker, "/EXPORT:GetFileBandwidthReservation=kernel32.GetFileBandwidthReservation") +#pragma comment(linker, "/EXPORT:GetFileInformationByHandle=kernel32.GetFileInformationByHandle") +#pragma comment(linker, "/EXPORT:GetFileInformationByHandleEx=kernel32.GetFileInformationByHandleEx") +#pragma comment(linker, "/EXPORT:GetFileMUIInfo=kernel32.GetFileMUIInfo") +#pragma comment(linker, "/EXPORT:GetFileMUIPath=kernel32.GetFileMUIPath") +#pragma comment(linker, "/EXPORT:GetFileSize=kernel32.GetFileSize") +#pragma comment(linker, "/EXPORT:GetFileSizeEx=kernel32.GetFileSizeEx") +#pragma comment(linker, "/EXPORT:GetFileTime=kernel32.GetFileTime") +#pragma comment(linker, "/EXPORT:GetFileType=kernel32.GetFileType") +#pragma comment(linker, "/EXPORT:GetFinalPathNameByHandleA=kernel32.GetFinalPathNameByHandleA") +#pragma comment(linker, "/EXPORT:GetFinalPathNameByHandleW=kernel32.GetFinalPathNameByHandleW") +#pragma comment(linker, "/EXPORT:GetFirmwareEnvironmentVariableA=kernel32.GetFirmwareEnvironmentVariableA") +#pragma comment(linker, "/EXPORT:GetFirmwareEnvironmentVariableW=kernel32.GetFirmwareEnvironmentVariableW") +#pragma comment(linker, "/EXPORT:GetFullPathNameA=kernel32.GetFullPathNameA") +#pragma comment(linker, "/EXPORT:GetFullPathNameTransactedA=kernel32.GetFullPathNameTransactedA") +#pragma comment(linker, "/EXPORT:GetFullPathNameTransactedW=kernel32.GetFullPathNameTransactedW") +#pragma comment(linker, "/EXPORT:GetFullPathNameW=kernel32.GetFullPathNameW") +#pragma comment(linker, "/EXPORT:GetGeoInfoA=kernel32.GetGeoInfoA") +#pragma comment(linker, "/EXPORT:GetGeoInfoW=kernel32.GetGeoInfoW") +#pragma comment(linker, "/EXPORT:GetHandleInformation=kernel32.GetHandleInformation") +#pragma comment(linker, "/EXPORT:GetLargePageMinimum=kernel32.GetLargePageMinimum") +#pragma comment(linker, "/EXPORT:GetLargestConsoleWindowSize=kernel32.GetLargestConsoleWindowSize") +#pragma comment(linker, "/EXPORT:GetLastError=kernel32.GetLastError") +#pragma comment(linker, "/EXPORT:GetLocalTime=kernel32.GetLocalTime") +#pragma comment(linker, "/EXPORT:GetLocaleInfoA=kernel32.GetLocaleInfoA") +#pragma comment(linker, "/EXPORT:GetLocaleInfoEx=kernel32.GetLocaleInfoEx") +#pragma comment(linker, "/EXPORT:GetLocaleInfoW=kernel32.GetLocaleInfoW") +#pragma comment(linker, "/EXPORT:GetLogicalDriveStringsA=kernel32.GetLogicalDriveStringsA") +#pragma comment(linker, "/EXPORT:GetLogicalDriveStringsW=kernel32.GetLogicalDriveStringsW") +#pragma comment(linker, "/EXPORT:GetLogicalDrives=kernel32.GetLogicalDrives") +#pragma comment(linker, "/EXPORT:GetLogicalProcessorInformation=kernel32.GetLogicalProcessorInformation") +#pragma comment(linker, "/EXPORT:GetLogicalProcessorInformationEx=kernel32.GetLogicalProcessorInformationEx") +#pragma comment(linker, "/EXPORT:GetLongPathNameA=kernel32.GetLongPathNameA") +#pragma comment(linker, "/EXPORT:GetLongPathNameTransactedA=kernel32.GetLongPathNameTransactedA") +#pragma comment(linker, "/EXPORT:GetLongPathNameTransactedW=kernel32.GetLongPathNameTransactedW") +#pragma comment(linker, "/EXPORT:GetLongPathNameW=kernel32.GetLongPathNameW") +#pragma comment(linker, "/EXPORT:GetMailslotInfo=kernel32.GetMailslotInfo") +#pragma comment(linker, "/EXPORT:GetMaximumProcessorCount=kernel32.GetMaximumProcessorCount") +#pragma comment(linker, "/EXPORT:GetMaximumProcessorGroupCount=kernel32.GetMaximumProcessorGroupCount") +#pragma comment(linker, "/EXPORT:GetModuleFileNameA=kernel32.GetModuleFileNameA") +#pragma comment(linker, "/EXPORT:GetModuleFileNameW=kernel32.GetModuleFileNameW") +//#pragma comment(linker, "/EXPORT:GetModuleHandleA=kernel32.GetModuleHandleA") +//#pragma comment(linker, "/EXPORT:GetModuleHandleExA=kernel32.GetModuleHandleExA") +//#pragma comment(linker, "/EXPORT:GetModuleHandleExW=kernel32.GetModuleHandleExW") +//#pragma comment(linker, "/EXPORT:GetModuleHandleW=kernel32.GetModuleHandleW") +#pragma comment(linker, "/EXPORT:GetNLSVersion=kernel32.GetNLSVersion") +#pragma comment(linker, "/EXPORT:GetNLSVersionEx=kernel32.GetNLSVersionEx") +#pragma comment(linker, "/EXPORT:GetNamedPipeAttribute=kernel32.GetNamedPipeAttribute") +#pragma comment(linker, "/EXPORT:GetNamedPipeClientComputerNameA=kernel32.GetNamedPipeClientComputerNameA") +#pragma comment(linker, "/EXPORT:GetNamedPipeClientComputerNameW=kernel32.GetNamedPipeClientComputerNameW") +#pragma comment(linker, "/EXPORT:GetNamedPipeClientProcessId=kernel32.GetNamedPipeClientProcessId") +#pragma comment(linker, "/EXPORT:GetNamedPipeClientSessionId=kernel32.GetNamedPipeClientSessionId") +#pragma comment(linker, "/EXPORT:GetNamedPipeHandleStateA=kernel32.GetNamedPipeHandleStateA") +#pragma comment(linker, "/EXPORT:GetNamedPipeHandleStateW=kernel32.GetNamedPipeHandleStateW") +#pragma comment(linker, "/EXPORT:GetNamedPipeInfo=kernel32.GetNamedPipeInfo") +#pragma comment(linker, "/EXPORT:GetNamedPipeServerProcessId=kernel32.GetNamedPipeServerProcessId") +#pragma comment(linker, "/EXPORT:GetNamedPipeServerSessionId=kernel32.GetNamedPipeServerSessionId") +#pragma comment(linker, "/EXPORT:GetNativeSystemInfo=kernel32.GetNativeSystemInfo") +#pragma comment(linker, "/EXPORT:GetNextVDMCommand=kernel32.GetNextVDMCommand") +#pragma comment(linker, "/EXPORT:GetNumaAvailableMemoryNode=kernel32.GetNumaAvailableMemoryNode") +#pragma comment(linker, "/EXPORT:GetNumaAvailableMemoryNodeEx=kernel32.GetNumaAvailableMemoryNodeEx") +#pragma comment(linker, "/EXPORT:GetNumaHighestNodeNumber=kernel32.GetNumaHighestNodeNumber") +#pragma comment(linker, "/EXPORT:GetNumaNodeNumberFromHandle=kernel32.GetNumaNodeNumberFromHandle") +#pragma comment(linker, "/EXPORT:GetNumaNodeProcessorMask=kernel32.GetNumaNodeProcessorMask") +#pragma comment(linker, "/EXPORT:GetNumaNodeProcessorMaskEx=kernel32.GetNumaNodeProcessorMaskEx") +#pragma comment(linker, "/EXPORT:GetNumaProcessorNode=kernel32.GetNumaProcessorNode") +#pragma comment(linker, "/EXPORT:GetNumaProcessorNodeEx=kernel32.GetNumaProcessorNodeEx") +#pragma comment(linker, "/EXPORT:GetNumaProximityNode=kernel32.GetNumaProximityNode") +#pragma comment(linker, "/EXPORT:GetNumaProximityNodeEx=kernel32.GetNumaProximityNodeEx") +#pragma comment(linker, "/EXPORT:GetNumberFormatA=kernel32.GetNumberFormatA") +#pragma comment(linker, "/EXPORT:GetNumberFormatEx=kernel32.GetNumberFormatEx") +#pragma comment(linker, "/EXPORT:GetNumberFormatW=kernel32.GetNumberFormatW") +#pragma comment(linker, "/EXPORT:GetNumberOfConsoleFonts=kernel32.GetNumberOfConsoleFonts") +#pragma comment(linker, "/EXPORT:GetNumberOfConsoleInputEvents=kernel32.GetNumberOfConsoleInputEvents") +#pragma comment(linker, "/EXPORT:GetNumberOfConsoleMouseButtons=kernel32.GetNumberOfConsoleMouseButtons") +#pragma comment(linker, "/EXPORT:GetOEMCP=kernel32.GetOEMCP") +#pragma comment(linker, "/EXPORT:GetOverlappedResult=kernel32.GetOverlappedResult") +#pragma comment(linker, "/EXPORT:GetPhysicallyInstalledSystemMemory=kernel32.GetPhysicallyInstalledSystemMemory") +#pragma comment(linker, "/EXPORT:GetPriorityClass=kernel32.GetPriorityClass") +#pragma comment(linker, "/EXPORT:GetPrivateProfileIntA=kernel32.GetPrivateProfileIntA") +#pragma comment(linker, "/EXPORT:GetPrivateProfileIntW=kernel32.GetPrivateProfileIntW") +#pragma comment(linker, "/EXPORT:GetPrivateProfileSectionA=kernel32.GetPrivateProfileSectionA") +#pragma comment(linker, "/EXPORT:GetPrivateProfileSectionNamesA=kernel32.GetPrivateProfileSectionNamesA") +#pragma comment(linker, "/EXPORT:GetPrivateProfileSectionNamesW=kernel32.GetPrivateProfileSectionNamesW") +#pragma comment(linker, "/EXPORT:GetPrivateProfileSectionW=kernel32.GetPrivateProfileSectionW") +#pragma comment(linker, "/EXPORT:GetPrivateProfileStringA=kernel32.GetPrivateProfileStringA") +#pragma comment(linker, "/EXPORT:GetPrivateProfileStringW=kernel32.GetPrivateProfileStringW") +#pragma comment(linker, "/EXPORT:GetPrivateProfileStructA=kernel32.GetPrivateProfileStructA") +#pragma comment(linker, "/EXPORT:GetPrivateProfileStructW=kernel32.GetPrivateProfileStructW") +#pragma comment(linker, "/EXPORT:GetProcAddress=kernel32.GetProcAddress") +#pragma comment(linker, "/EXPORT:GetProcessAffinityMask=kernel32.GetProcessAffinityMask") +#pragma comment(linker, "/EXPORT:GetProcessDEPPolicy=kernel32.GetProcessDEPPolicy") +#pragma comment(linker, "/EXPORT:GetProcessGroupAffinity=kernel32.GetProcessGroupAffinity") +#pragma comment(linker, "/EXPORT:GetProcessHandleCount=kernel32.GetProcessHandleCount") +#pragma comment(linker, "/EXPORT:GetProcessHeap=kernel32.GetProcessHeap") +#pragma comment(linker, "/EXPORT:GetProcessHeaps=kernel32.GetProcessHeaps") +#pragma comment(linker, "/EXPORT:GetProcessId=kernel32.GetProcessId") +#pragma comment(linker, "/EXPORT:GetProcessIdOfThread=kernel32.GetProcessIdOfThread") +#pragma comment(linker, "/EXPORT:GetProcessIoCounters=kernel32.GetProcessIoCounters") +#pragma comment(linker, "/EXPORT:GetProcessPreferredUILanguages=kernel32.GetProcessPreferredUILanguages") +#pragma comment(linker, "/EXPORT:GetProcessPriorityBoost=kernel32.GetProcessPriorityBoost") +#pragma comment(linker, "/EXPORT:GetProcessShutdownParameters=kernel32.GetProcessShutdownParameters") +#pragma comment(linker, "/EXPORT:GetProcessTimes=kernel32.GetProcessTimes") +#pragma comment(linker, "/EXPORT:GetProcessUserModeExceptionPolicy=kernel32.GetProcessUserModeExceptionPolicy") +#pragma comment(linker, "/EXPORT:GetProcessVersion=kernel32.GetProcessVersion") +#pragma comment(linker, "/EXPORT:GetProcessWorkingSetSize=kernel32.GetProcessWorkingSetSize") +#pragma comment(linker, "/EXPORT:GetProcessWorkingSetSizeEx=kernel32.GetProcessWorkingSetSizeEx") +#pragma comment(linker, "/EXPORT:GetProcessorSystemCycleTime=kernel32.GetProcessorSystemCycleTime") +#pragma comment(linker, "/EXPORT:GetProductInfo=kernel32.GetProductInfo") +#pragma comment(linker, "/EXPORT:GetProfileIntA=kernel32.GetProfileIntA") +#pragma comment(linker, "/EXPORT:GetProfileIntW=kernel32.GetProfileIntW") +#pragma comment(linker, "/EXPORT:GetProfileSectionA=kernel32.GetProfileSectionA") +#pragma comment(linker, "/EXPORT:GetProfileSectionW=kernel32.GetProfileSectionW") +#pragma comment(linker, "/EXPORT:GetProfileStringA=kernel32.GetProfileStringA") +#pragma comment(linker, "/EXPORT:GetProfileStringW=kernel32.GetProfileStringW") +#pragma comment(linker, "/EXPORT:GetQueuedCompletionStatus=kernel32.GetQueuedCompletionStatus") +#pragma comment(linker, "/EXPORT:GetQueuedCompletionStatusEx=kernel32.GetQueuedCompletionStatusEx") +#pragma comment(linker, "/EXPORT:GetShortPathNameA=kernel32.GetShortPathNameA") +#pragma comment(linker, "/EXPORT:GetShortPathNameW=kernel32.GetShortPathNameW") +#pragma comment(linker, "/EXPORT:GetStartupInfoA=kernel32.GetStartupInfoA") +#pragma comment(linker, "/EXPORT:GetStartupInfoW=kernel32.GetStartupInfoW") +#pragma comment(linker, "/EXPORT:GetStdHandle=kernel32.GetStdHandle") +#pragma comment(linker, "/EXPORT:GetStringScripts=kernel32.GetStringScripts") +#pragma comment(linker, "/EXPORT:GetStringTypeA=kernel32.GetStringTypeA") +#pragma comment(linker, "/EXPORT:GetStringTypeExA=kernel32.GetStringTypeExA") +#pragma comment(linker, "/EXPORT:GetStringTypeExW=kernel32.GetStringTypeExW") +#pragma comment(linker, "/EXPORT:GetStringTypeW=kernel32.GetStringTypeW") +#pragma comment(linker, "/EXPORT:GetSystemDEPPolicy=kernel32.GetSystemDEPPolicy") +#pragma comment(linker, "/EXPORT:GetSystemDefaultLCID=kernel32.GetSystemDefaultLCID") +#pragma comment(linker, "/EXPORT:GetSystemDefaultLangID=kernel32.GetSystemDefaultLangID") +#pragma comment(linker, "/EXPORT:GetSystemDefaultLocaleName=kernel32.GetSystemDefaultLocaleName") +#pragma comment(linker, "/EXPORT:GetSystemDefaultUILanguage=kernel32.GetSystemDefaultUILanguage") +#pragma comment(linker, "/EXPORT:GetSystemDirectoryA=kernel32.GetSystemDirectoryA") +#pragma comment(linker, "/EXPORT:GetSystemDirectoryW=kernel32.GetSystemDirectoryW") +#pragma comment(linker, "/EXPORT:GetSystemFileCacheSize=kernel32.GetSystemFileCacheSize") +#pragma comment(linker, "/EXPORT:GetSystemFirmwareTable=kernel32.GetSystemFirmwareTable") +#pragma comment(linker, "/EXPORT:GetSystemInfo=kernel32.GetSystemInfo") +#pragma comment(linker, "/EXPORT:GetSystemPowerStatus=kernel32.GetSystemPowerStatus") +#pragma comment(linker, "/EXPORT:GetSystemPreferredUILanguages=kernel32.GetSystemPreferredUILanguages") +#pragma comment(linker, "/EXPORT:GetSystemRegistryQuota=kernel32.GetSystemRegistryQuota") +#pragma comment(linker, "/EXPORT:GetSystemTime=kernel32.GetSystemTime") +#pragma comment(linker, "/EXPORT:GetSystemTimeAdjustment=kernel32.GetSystemTimeAdjustment") +#pragma comment(linker, "/EXPORT:GetSystemTimeAsFileTime=kernel32.GetSystemTimeAsFileTime") +#pragma comment(linker, "/EXPORT:GetSystemTimes=kernel32.GetSystemTimes") +#pragma comment(linker, "/EXPORT:GetSystemWindowsDirectoryA=kernel32.GetSystemWindowsDirectoryA") +#pragma comment(linker, "/EXPORT:GetSystemWindowsDirectoryW=kernel32.GetSystemWindowsDirectoryW") +#pragma comment(linker, "/EXPORT:GetSystemWow64DirectoryA=kernel32.GetSystemWow64DirectoryA") +#pragma comment(linker, "/EXPORT:GetSystemWow64DirectoryW=kernel32.GetSystemWow64DirectoryW") +#pragma comment(linker, "/EXPORT:GetTapeParameters=kernel32.GetTapeParameters") +#pragma comment(linker, "/EXPORT:GetTapePosition=kernel32.GetTapePosition") +#pragma comment(linker, "/EXPORT:GetTapeStatus=kernel32.GetTapeStatus") +#pragma comment(linker, "/EXPORT:GetTempFileNameA=kernel32.GetTempFileNameA") +#pragma comment(linker, "/EXPORT:GetTempFileNameW=kernel32.GetTempFileNameW") +#pragma comment(linker, "/EXPORT:GetTempPathA=kernel32.GetTempPathA") +#pragma comment(linker, "/EXPORT:GetTempPathW=kernel32.GetTempPathW") +#pragma comment(linker, "/EXPORT:GetThreadContext=kernel32.GetThreadContext") +#pragma comment(linker, "/EXPORT:GetThreadErrorMode=kernel32.GetThreadErrorMode") +#pragma comment(linker, "/EXPORT:GetThreadGroupAffinity=kernel32.GetThreadGroupAffinity") +#pragma comment(linker, "/EXPORT:GetThreadIOPendingFlag=kernel32.GetThreadIOPendingFlag") +#pragma comment(linker, "/EXPORT:GetThreadId=kernel32.GetThreadId") +#pragma comment(linker, "/EXPORT:GetThreadIdealProcessorEx=kernel32.GetThreadIdealProcessorEx") +#pragma comment(linker, "/EXPORT:GetThreadLocale=kernel32.GetThreadLocale") +#pragma comment(linker, "/EXPORT:GetThreadPreferredUILanguages=kernel32.GetThreadPreferredUILanguages") +#pragma comment(linker, "/EXPORT:GetThreadPriority=kernel32.GetThreadPriority") +#pragma comment(linker, "/EXPORT:GetThreadPriorityBoost=kernel32.GetThreadPriorityBoost") +#pragma comment(linker, "/EXPORT:GetThreadSelectorEntry=kernel32.GetThreadSelectorEntry") +#pragma comment(linker, "/EXPORT:GetThreadTimes=kernel32.GetThreadTimes") +#pragma comment(linker, "/EXPORT:GetThreadUILanguage=kernel32.GetThreadUILanguage") +#pragma comment(linker, "/EXPORT:GetTickCount=kernel32.GetTickCount") +#pragma comment(linker, "/EXPORT:GetTickCount64=kernel32.GetTickCount64") +#pragma comment(linker, "/EXPORT:GetTimeFormatA=kernel32.GetTimeFormatA") +#pragma comment(linker, "/EXPORT:GetTimeFormatEx=kernel32.GetTimeFormatEx") +#pragma comment(linker, "/EXPORT:GetTimeFormatW=kernel32.GetTimeFormatW") +#pragma comment(linker, "/EXPORT:GetTimeZoneInformation=kernel32.GetTimeZoneInformation") +#pragma comment(linker, "/EXPORT:GetTimeZoneInformationForYear=kernel32.GetTimeZoneInformationForYear") +#pragma comment(linker, "/EXPORT:GetUILanguageInfo=kernel32.GetUILanguageInfo") +#pragma comment(linker, "/EXPORT:GetUserDefaultLCID=kernel32.GetUserDefaultLCID") +#pragma comment(linker, "/EXPORT:GetUserDefaultLangID=kernel32.GetUserDefaultLangID") +#pragma comment(linker, "/EXPORT:GetUserDefaultLocaleName=kernel32.GetUserDefaultLocaleName") +#pragma comment(linker, "/EXPORT:GetUserDefaultUILanguage=kernel32.GetUserDefaultUILanguage") +#pragma comment(linker, "/EXPORT:GetUserGeoID=kernel32.GetUserGeoID") +#pragma comment(linker, "/EXPORT:GetUserPreferredUILanguages=kernel32.GetUserPreferredUILanguages") +#pragma comment(linker, "/EXPORT:GetVDMCurrentDirectories=kernel32.GetVDMCurrentDirectories") +#pragma comment(linker, "/EXPORT:GetVersion=kernel32.GetVersion") +//#pragma comment(linker, "/EXPORT:GetVersionExA=kernel32.GetVersionExA") +#pragma comment(linker, "/EXPORT:GetVersionExW=kernel32.GetVersionExW") +#pragma comment(linker, "/EXPORT:GetVolumeInformationA=kernel32.GetVolumeInformationA") +#pragma comment(linker, "/EXPORT:GetVolumeInformationByHandleW=kernel32.GetVolumeInformationByHandleW") +#pragma comment(linker, "/EXPORT:GetVolumeInformationW=kernel32.GetVolumeInformationW") +#pragma comment(linker, "/EXPORT:GetVolumeNameForVolumeMountPointA=kernel32.GetVolumeNameForVolumeMountPointA") +#pragma comment(linker, "/EXPORT:GetVolumeNameForVolumeMountPointW=kernel32.GetVolumeNameForVolumeMountPointW") +#pragma comment(linker, "/EXPORT:GetVolumePathNameA=kernel32.GetVolumePathNameA") +#pragma comment(linker, "/EXPORT:GetVolumePathNameW=kernel32.GetVolumePathNameW") +#pragma comment(linker, "/EXPORT:GetVolumePathNamesForVolumeNameA=kernel32.GetVolumePathNamesForVolumeNameA") +#pragma comment(linker, "/EXPORT:GetVolumePathNamesForVolumeNameW=kernel32.GetVolumePathNamesForVolumeNameW") +#pragma comment(linker, "/EXPORT:GetWindowsDirectoryA=kernel32.GetWindowsDirectoryA") +#pragma comment(linker, "/EXPORT:GetWindowsDirectoryW=kernel32.GetWindowsDirectoryW") +#pragma comment(linker, "/EXPORT:GetWriteWatch=kernel32.GetWriteWatch") +#pragma comment(linker, "/EXPORT:GetXStateFeaturesMask=kernel32.GetXStateFeaturesMask") +#pragma comment(linker, "/EXPORT:GlobalAddAtomA=kernel32.GlobalAddAtomA") +#pragma comment(linker, "/EXPORT:GlobalAddAtomW=kernel32.GlobalAddAtomW") +#pragma comment(linker, "/EXPORT:GlobalAlloc=kernel32.GlobalAlloc") +#pragma comment(linker, "/EXPORT:GlobalCompact=kernel32.GlobalCompact") +#pragma comment(linker, "/EXPORT:GlobalDeleteAtom=kernel32.GlobalDeleteAtom") +#pragma comment(linker, "/EXPORT:GlobalFindAtomA=kernel32.GlobalFindAtomA") +#pragma comment(linker, "/EXPORT:GlobalFindAtomW=kernel32.GlobalFindAtomW") +#pragma comment(linker, "/EXPORT:GlobalFix=kernel32.GlobalFix") +#pragma comment(linker, "/EXPORT:GlobalFlags=kernel32.GlobalFlags") +#pragma comment(linker, "/EXPORT:GlobalFree=kernel32.GlobalFree") +#pragma comment(linker, "/EXPORT:GlobalGetAtomNameA=kernel32.GlobalGetAtomNameA") +#pragma comment(linker, "/EXPORT:GlobalGetAtomNameW=kernel32.GlobalGetAtomNameW") +#pragma comment(linker, "/EXPORT:GlobalHandle=kernel32.GlobalHandle") +#pragma comment(linker, "/EXPORT:GlobalLock=kernel32.GlobalLock") +#pragma comment(linker, "/EXPORT:GlobalMemoryStatus=kernel32.GlobalMemoryStatus") +#pragma comment(linker, "/EXPORT:GlobalMemoryStatusEx=kernel32.GlobalMemoryStatusEx") +#pragma comment(linker, "/EXPORT:GlobalReAlloc=kernel32.GlobalReAlloc") +#pragma comment(linker, "/EXPORT:GlobalSize=kernel32.GlobalSize") +#pragma comment(linker, "/EXPORT:GlobalUnWire=kernel32.GlobalUnWire") +#pragma comment(linker, "/EXPORT:GlobalUnfix=kernel32.GlobalUnfix") +#pragma comment(linker, "/EXPORT:GlobalUnlock=kernel32.GlobalUnlock") +#pragma comment(linker, "/EXPORT:GlobalWire=kernel32.GlobalWire") +#pragma comment(linker, "/EXPORT:Heap32First=kernel32.Heap32First") +#pragma comment(linker, "/EXPORT:Heap32ListFirst=kernel32.Heap32ListFirst") +#pragma comment(linker, "/EXPORT:Heap32ListNext=kernel32.Heap32ListNext") +#pragma comment(linker, "/EXPORT:Heap32Next=kernel32.Heap32Next") +#pragma comment(linker, "/EXPORT:HeapAlloc=kernel32.HeapAlloc") +#pragma comment(linker, "/EXPORT:HeapCompact=kernel32.HeapCompact") +//#pragma comment(linker, "/EXPORT:HeapCreate=kernel32.HeapCreate") +#pragma comment(linker, "/EXPORT:HeapDestroy=kernel32.HeapDestroy") +#pragma comment(linker, "/EXPORT:HeapFree=kernel32.HeapFree") +#pragma comment(linker, "/EXPORT:HeapLock=kernel32.HeapLock") +#pragma comment(linker, "/EXPORT:HeapQueryInformation=kernel32.HeapQueryInformation") +#pragma comment(linker, "/EXPORT:HeapReAlloc=kernel32.HeapReAlloc") +#pragma comment(linker, "/EXPORT:HeapSetInformation=kernel32.HeapSetInformation") +#pragma comment(linker, "/EXPORT:HeapSize=kernel32.HeapSize") +#pragma comment(linker, "/EXPORT:HeapSummary=kernel32.HeapSummary") +#pragma comment(linker, "/EXPORT:HeapUnlock=kernel32.HeapUnlock") +#pragma comment(linker, "/EXPORT:HeapValidate=kernel32.HeapValidate") +#pragma comment(linker, "/EXPORT:HeapWalk=kernel32.HeapWalk") +#pragma comment(linker, "/EXPORT:IdnToAscii=kernel32.IdnToAscii") +#pragma comment(linker, "/EXPORT:IdnToNameprepUnicode=kernel32.IdnToNameprepUnicode") +#pragma comment(linker, "/EXPORT:IdnToUnicode=kernel32.IdnToUnicode") +#pragma comment(linker, "/EXPORT:InitAtomTable=kernel32.InitAtomTable") +#pragma comment(linker, "/EXPORT:InitOnceBeginInitialize=kernel32.InitOnceBeginInitialize") +#pragma comment(linker, "/EXPORT:InitOnceComplete=kernel32.InitOnceComplete") +#pragma comment(linker, "/EXPORT:InitOnceExecuteOnce=kernel32.InitOnceExecuteOnce") +#pragma comment(linker, "/EXPORT:InitOnceInitialize=kernel32.InitOnceInitialize") +#pragma comment(linker, "/EXPORT:InitializeConditionVariable=kernel32.InitializeConditionVariable") +#pragma comment(linker, "/EXPORT:InitializeContext=kernel32.InitializeContext") +#pragma comment(linker, "/EXPORT:InitializeCriticalSection=kernel32.InitializeCriticalSection") +#pragma comment(linker, "/EXPORT:InitializeCriticalSectionAndSpinCount=kernel32.InitializeCriticalSectionAndSpinCount") +#pragma comment(linker, "/EXPORT:InitializeCriticalSectionEx=kernel32.InitializeCriticalSectionEx") +#pragma comment(linker, "/EXPORT:InitializeProcThreadAttributeList=kernel32.InitializeProcThreadAttributeList") +#pragma comment(linker, "/EXPORT:InitializeSListHead=kernel32.InitializeSListHead") +#pragma comment(linker, "/EXPORT:InitializeSRWLock=kernel32.InitializeSRWLock") +#pragma comment(linker, "/EXPORT:InterlockedFlushSList=kernel32.InterlockedFlushSList") +#pragma comment(linker, "/EXPORT:InterlockedPopEntrySList=kernel32.InterlockedPopEntrySList") +#pragma comment(linker, "/EXPORT:InterlockedPushEntrySList=kernel32.InterlockedPushEntrySList") +#pragma comment(linker, "/EXPORT:InterlockedPushListSList=kernel32.InterlockedPushListSList") +#pragma comment(linker, "/EXPORT:InvalidateConsoleDIBits=kernel32.InvalidateConsoleDIBits") +#pragma comment(linker, "/EXPORT:IsBadCodePtr=kernel32.IsBadCodePtr") +#pragma comment(linker, "/EXPORT:IsBadHugeReadPtr=kernel32.IsBadHugeReadPtr") +#pragma comment(linker, "/EXPORT:IsBadHugeWritePtr=kernel32.IsBadHugeWritePtr") +#pragma comment(linker, "/EXPORT:IsBadReadPtr=kernel32.IsBadReadPtr") +#pragma comment(linker, "/EXPORT:IsBadStringPtrA=kernel32.IsBadStringPtrA") +#pragma comment(linker, "/EXPORT:IsBadStringPtrW=kernel32.IsBadStringPtrW") +#pragma comment(linker, "/EXPORT:IsBadWritePtr=kernel32.IsBadWritePtr") +#pragma comment(linker, "/EXPORT:IsCalendarLeapDay=kernel32.IsCalendarLeapDay") +#pragma comment(linker, "/EXPORT:IsCalendarLeapMonth=kernel32.IsCalendarLeapMonth") +#pragma comment(linker, "/EXPORT:IsCalendarLeapYear=kernel32.IsCalendarLeapYear") +#pragma comment(linker, "/EXPORT:IsDBCSLeadByte=kernel32.IsDBCSLeadByte") +#pragma comment(linker, "/EXPORT:IsDBCSLeadByteEx=kernel32.IsDBCSLeadByteEx") +#pragma comment(linker, "/EXPORT:IsDebuggerPresent=kernel32.IsDebuggerPresent") +#pragma comment(linker, "/EXPORT:IsNLSDefinedString=kernel32.IsNLSDefinedString") +#pragma comment(linker, "/EXPORT:IsNormalizedString=kernel32.IsNormalizedString") +//#pragma comment(linker, "/EXPORT:IsProcessInJob=kernel32.IsProcessInJob") +#pragma comment(linker, "/EXPORT:IsProcessorFeaturePresent=kernel32.IsProcessorFeaturePresent") +#pragma comment(linker, "/EXPORT:IsSystemResumeAutomatic=kernel32.IsSystemResumeAutomatic") +#pragma comment(linker, "/EXPORT:IsThreadAFiber=kernel32.IsThreadAFiber") +#pragma comment(linker, "/EXPORT:IsThreadpoolTimerSet=kernel32.IsThreadpoolTimerSet") +#pragma comment(linker, "/EXPORT:IsTimeZoneRedirectionEnabled=kernel32.IsTimeZoneRedirectionEnabled") +#pragma comment(linker, "/EXPORT:IsValidCalDateTime=kernel32.IsValidCalDateTime") +#pragma comment(linker, "/EXPORT:IsValidCodePage=kernel32.IsValidCodePage") +#pragma comment(linker, "/EXPORT:IsValidLanguageGroup=kernel32.IsValidLanguageGroup") +#pragma comment(linker, "/EXPORT:IsValidLocale=kernel32.IsValidLocale") +#pragma comment(linker, "/EXPORT:IsValidLocaleName=kernel32.IsValidLocaleName") +#pragma comment(linker, "/EXPORT:IsWow64Process=kernel32.IsWow64Process") +#pragma comment(linker, "/EXPORT:K32EmptyWorkingSet=kernel32.K32EmptyWorkingSet") +#pragma comment(linker, "/EXPORT:K32EnumDeviceDrivers=kernel32.K32EnumDeviceDrivers") +#pragma comment(linker, "/EXPORT:K32EnumPageFilesA=kernel32.K32EnumPageFilesA") +#pragma comment(linker, "/EXPORT:K32EnumPageFilesW=kernel32.K32EnumPageFilesW") +#pragma comment(linker, "/EXPORT:K32EnumProcessModules=kernel32.K32EnumProcessModules") +#pragma comment(linker, "/EXPORT:K32EnumProcessModulesEx=kernel32.K32EnumProcessModulesEx") +#pragma comment(linker, "/EXPORT:K32EnumProcesses=kernel32.K32EnumProcesses") +#pragma comment(linker, "/EXPORT:K32GetDeviceDriverBaseNameA=kernel32.K32GetDeviceDriverBaseNameA") +#pragma comment(linker, "/EXPORT:K32GetDeviceDriverBaseNameW=kernel32.K32GetDeviceDriverBaseNameW") +#pragma comment(linker, "/EXPORT:K32GetDeviceDriverFileNameA=kernel32.K32GetDeviceDriverFileNameA") +#pragma comment(linker, "/EXPORT:K32GetDeviceDriverFileNameW=kernel32.K32GetDeviceDriverFileNameW") +#pragma comment(linker, "/EXPORT:K32GetMappedFileNameA=kernel32.K32GetMappedFileNameA") +#pragma comment(linker, "/EXPORT:K32GetMappedFileNameW=kernel32.K32GetMappedFileNameW") +#pragma comment(linker, "/EXPORT:K32GetModuleBaseNameA=kernel32.K32GetModuleBaseNameA") +#pragma comment(linker, "/EXPORT:K32GetModuleBaseNameW=kernel32.K32GetModuleBaseNameW") +#pragma comment(linker, "/EXPORT:K32GetModuleFileNameExA=kernel32.K32GetModuleFileNameExA") +#pragma comment(linker, "/EXPORT:K32GetModuleFileNameExW=kernel32.K32GetModuleFileNameExW") +#pragma comment(linker, "/EXPORT:K32GetModuleInformation=kernel32.K32GetModuleInformation") +#pragma comment(linker, "/EXPORT:K32GetPerformanceInfo=kernel32.K32GetPerformanceInfo") +#pragma comment(linker, "/EXPORT:K32GetProcessImageFileNameA=kernel32.K32GetProcessImageFileNameA") +#pragma comment(linker, "/EXPORT:K32GetProcessImageFileNameW=kernel32.K32GetProcessImageFileNameW") +#pragma comment(linker, "/EXPORT:K32GetProcessMemoryInfo=kernel32.K32GetProcessMemoryInfo") +#pragma comment(linker, "/EXPORT:K32GetWsChanges=kernel32.K32GetWsChanges") +#pragma comment(linker, "/EXPORT:K32GetWsChangesEx=kernel32.K32GetWsChangesEx") +#pragma comment(linker, "/EXPORT:K32InitializeProcessForWsWatch=kernel32.K32InitializeProcessForWsWatch") +#pragma comment(linker, "/EXPORT:K32QueryWorkingSet=kernel32.K32QueryWorkingSet") +#pragma comment(linker, "/EXPORT:K32QueryWorkingSetEx=kernel32.K32QueryWorkingSetEx") +#pragma comment(linker, "/EXPORT:LCIDToLocaleName=kernel32.LCIDToLocaleName") +#pragma comment(linker, "/EXPORT:LCMapStringA=kernel32.LCMapStringA") +#pragma comment(linker, "/EXPORT:LCMapStringEx=kernel32.LCMapStringEx") +#pragma comment(linker, "/EXPORT:LCMapStringW=kernel32.LCMapStringW") +#pragma comment(linker, "/EXPORT:LZClose=kernel32.LZClose") +#pragma comment(linker, "/EXPORT:LZCloseFile=kernel32.LZCloseFile") +#pragma comment(linker, "/EXPORT:LZCopy=kernel32.LZCopy") +#pragma comment(linker, "/EXPORT:LZCreateFileW=kernel32.LZCreateFileW") +#pragma comment(linker, "/EXPORT:LZDone=kernel32.LZDone") +#pragma comment(linker, "/EXPORT:LZInit=kernel32.LZInit") +#pragma comment(linker, "/EXPORT:LZOpenFileA=kernel32.LZOpenFileA") +#pragma comment(linker, "/EXPORT:LZOpenFileW=kernel32.LZOpenFileW") +#pragma comment(linker, "/EXPORT:LZRead=kernel32.LZRead") +#pragma comment(linker, "/EXPORT:LZSeek=kernel32.LZSeek") +#pragma comment(linker, "/EXPORT:LZStart=kernel32.LZStart") +#pragma comment(linker, "/EXPORT:LeaveCriticalSection=kernel32.LeaveCriticalSection") +#pragma comment(linker, "/EXPORT:LeaveCriticalSectionWhenCallbackReturns=kernel32.LeaveCriticalSectionWhenCallbackReturns") +#pragma comment(linker, "/EXPORT:LoadAppInitDlls=kernel32.LoadAppInitDlls") +//#pragma comment(linker, "/EXPORT:LoadLibraryA=kernel32.LoadLibraryA") +//#pragma comment(linker, "/EXPORT:LoadLibraryExA=kernel32.LoadLibraryExA") +//#pragma comment(linker, "/EXPORT:LoadLibraryExW=kernel32.LoadLibraryExW") +//#pragma comment(linker, "/EXPORT:LoadLibraryW=kernel32.LoadLibraryW") +#pragma comment(linker, "/EXPORT:LoadModule=kernel32.LoadModule") +#pragma comment(linker, "/EXPORT:LoadResource=kernel32.LoadResource") +#pragma comment(linker, "/EXPORT:LoadStringBaseExW=kernel32.LoadStringBaseExW") +#pragma comment(linker, "/EXPORT:LoadStringBaseW=kernel32.LoadStringBaseW") +#pragma comment(linker, "/EXPORT:LocalAlloc=kernel32.LocalAlloc") +#pragma comment(linker, "/EXPORT:LocalCompact=kernel32.LocalCompact") +#pragma comment(linker, "/EXPORT:LocalFileTimeToFileTime=kernel32.LocalFileTimeToFileTime") +#pragma comment(linker, "/EXPORT:LocalFlags=kernel32.LocalFlags") +#pragma comment(linker, "/EXPORT:LocalFree=kernel32.LocalFree") +#pragma comment(linker, "/EXPORT:LocalHandle=kernel32.LocalHandle") +#pragma comment(linker, "/EXPORT:LocalLock=kernel32.LocalLock") +#pragma comment(linker, "/EXPORT:LocalReAlloc=kernel32.LocalReAlloc") +#pragma comment(linker, "/EXPORT:LocalShrink=kernel32.LocalShrink") +#pragma comment(linker, "/EXPORT:LocalSize=kernel32.LocalSize") +#pragma comment(linker, "/EXPORT:LocalUnlock=kernel32.LocalUnlock") +#pragma comment(linker, "/EXPORT:LocaleNameToLCID=kernel32.LocaleNameToLCID") +#pragma comment(linker, "/EXPORT:LocateXStateFeature=kernel32.LocateXStateFeature") +#pragma comment(linker, "/EXPORT:LockFile=kernel32.LockFile") +#pragma comment(linker, "/EXPORT:LockFileEx=kernel32.LockFileEx") +#pragma comment(linker, "/EXPORT:LockResource=kernel32.LockResource") +#pragma comment(linker, "/EXPORT:MapUserPhysicalPages=kernel32.MapUserPhysicalPages") +#pragma comment(linker, "/EXPORT:MapUserPhysicalPagesScatter=kernel32.MapUserPhysicalPagesScatter") +#pragma comment(linker, "/EXPORT:MapViewOfFile=kernel32.MapViewOfFile") +#pragma comment(linker, "/EXPORT:MapViewOfFileEx=kernel32.MapViewOfFileEx") +#pragma comment(linker, "/EXPORT:MapViewOfFileExNuma=kernel32.MapViewOfFileExNuma") +#pragma comment(linker, "/EXPORT:Module32First=kernel32.Module32First") +#pragma comment(linker, "/EXPORT:Module32FirstW=kernel32.Module32FirstW") +#pragma comment(linker, "/EXPORT:Module32Next=kernel32.Module32Next") +#pragma comment(linker, "/EXPORT:Module32NextW=kernel32.Module32NextW") +#pragma comment(linker, "/EXPORT:MoveFileA=kernel32.MoveFileA") +#pragma comment(linker, "/EXPORT:MoveFileExA=kernel32.MoveFileExA") +#pragma comment(linker, "/EXPORT:MoveFileExW=kernel32.MoveFileExW") +#pragma comment(linker, "/EXPORT:MoveFileTransactedA=kernel32.MoveFileTransactedA") +#pragma comment(linker, "/EXPORT:MoveFileTransactedW=kernel32.MoveFileTransactedW") +#pragma comment(linker, "/EXPORT:MoveFileW=kernel32.MoveFileW") +#pragma comment(linker, "/EXPORT:MoveFileWithProgressA=kernel32.MoveFileWithProgressA") +#pragma comment(linker, "/EXPORT:MoveFileWithProgressW=kernel32.MoveFileWithProgressW") +#pragma comment(linker, "/EXPORT:MulDiv=kernel32.MulDiv") +#pragma comment(linker, "/EXPORT:MultiByteToWideChar=kernel32.MultiByteToWideChar") +#pragma comment(linker, "/EXPORT:NeedCurrentDirectoryForExePathA=kernel32.NeedCurrentDirectoryForExePathA") +#pragma comment(linker, "/EXPORT:NeedCurrentDirectoryForExePathW=kernel32.NeedCurrentDirectoryForExePathW") +#pragma comment(linker, "/EXPORT:NlsCheckPolicy=kernel32.NlsCheckPolicy") +#pragma comment(linker, "/EXPORT:NlsEventDataDescCreate=kernel32.NlsEventDataDescCreate") +#pragma comment(linker, "/EXPORT:NlsGetCacheUpdateCount=kernel32.NlsGetCacheUpdateCount") +#pragma comment(linker, "/EXPORT:NlsUpdateLocale=kernel32.NlsUpdateLocale") +#pragma comment(linker, "/EXPORT:NlsUpdateSystemLocale=kernel32.NlsUpdateSystemLocale") +#pragma comment(linker, "/EXPORT:NlsWriteEtwEvent=kernel32.NlsWriteEtwEvent") +#pragma comment(linker, "/EXPORT:NormalizeString=kernel32.NormalizeString") +#pragma comment(linker, "/EXPORT:NotifyMountMgr=kernel32.NotifyMountMgr") +#pragma comment(linker, "/EXPORT:NotifyUILanguageChange=kernel32.NotifyUILanguageChange") +#pragma comment(linker, "/EXPORT:OpenConsoleW=kernel32.OpenConsoleW") +#pragma comment(linker, "/EXPORT:OpenEventA=kernel32.OpenEventA") +#pragma comment(linker, "/EXPORT:OpenEventW=kernel32.OpenEventW") +#pragma comment(linker, "/EXPORT:OpenFile=kernel32.OpenFile") +#pragma comment(linker, "/EXPORT:OpenFileById=kernel32.OpenFileById") +#pragma comment(linker, "/EXPORT:OpenFileMappingA=kernel32.OpenFileMappingA") +#pragma comment(linker, "/EXPORT:OpenFileMappingW=kernel32.OpenFileMappingW") +#pragma comment(linker, "/EXPORT:OpenJobObjectA=kernel32.OpenJobObjectA") +#pragma comment(linker, "/EXPORT:OpenJobObjectW=kernel32.OpenJobObjectW") +#pragma comment(linker, "/EXPORT:OpenMutexA=kernel32.OpenMutexA") +#pragma comment(linker, "/EXPORT:OpenMutexW=kernel32.OpenMutexW") +#pragma comment(linker, "/EXPORT:OpenPrivateNamespaceA=kernel32.OpenPrivateNamespaceA") +#pragma comment(linker, "/EXPORT:OpenPrivateNamespaceW=kernel32.OpenPrivateNamespaceW") +#pragma comment(linker, "/EXPORT:OpenProcess=kernel32.OpenProcess") +#pragma comment(linker, "/EXPORT:OpenProcessToken=kernel32.OpenProcessToken") +#pragma comment(linker, "/EXPORT:OpenProfileUserMapping=kernel32.OpenProfileUserMapping") +#pragma comment(linker, "/EXPORT:OpenSemaphoreA=kernel32.OpenSemaphoreA") +#pragma comment(linker, "/EXPORT:OpenSemaphoreW=kernel32.OpenSemaphoreW") +#pragma comment(linker, "/EXPORT:OpenThread=kernel32.OpenThread") +#pragma comment(linker, "/EXPORT:OpenThreadToken=kernel32.OpenThreadToken") +#pragma comment(linker, "/EXPORT:OpenWaitableTimerA=kernel32.OpenWaitableTimerA") +#pragma comment(linker, "/EXPORT:OpenWaitableTimerW=kernel32.OpenWaitableTimerW") +#pragma comment(linker, "/EXPORT:OutputDebugStringA=kernel32.OutputDebugStringA") +#pragma comment(linker, "/EXPORT:OutputDebugStringW=kernel32.OutputDebugStringW") +#pragma comment(linker, "/EXPORT:PeekConsoleInputA=kernel32.PeekConsoleInputA") +#pragma comment(linker, "/EXPORT:PeekConsoleInputW=kernel32.PeekConsoleInputW") +#pragma comment(linker, "/EXPORT:PeekNamedPipe=kernel32.PeekNamedPipe") +#pragma comment(linker, "/EXPORT:PostQueuedCompletionStatus=kernel32.PostQueuedCompletionStatus") +#pragma comment(linker, "/EXPORT:PowerClearRequest=kernel32.PowerClearRequest") +#pragma comment(linker, "/EXPORT:PowerCreateRequest=kernel32.PowerCreateRequest") +#pragma comment(linker, "/EXPORT:PowerSetRequest=kernel32.PowerSetRequest") +#pragma comment(linker, "/EXPORT:PrepareTape=kernel32.PrepareTape") +#pragma comment(linker, "/EXPORT:PrivCopyFileExW=kernel32.PrivCopyFileExW") +#pragma comment(linker, "/EXPORT:PrivMoveFileIdentityW=kernel32.PrivMoveFileIdentityW") +#pragma comment(linker, "/EXPORT:Process32First=kernel32.Process32First") +#pragma comment(linker, "/EXPORT:Process32FirstW=kernel32.Process32FirstW") +#pragma comment(linker, "/EXPORT:Process32Next=kernel32.Process32Next") +#pragma comment(linker, "/EXPORT:Process32NextW=kernel32.Process32NextW") +#pragma comment(linker, "/EXPORT:ProcessIdToSessionId=kernel32.ProcessIdToSessionId") +#pragma comment(linker, "/EXPORT:PulseEvent=kernel32.PulseEvent") +#pragma comment(linker, "/EXPORT:PurgeComm=kernel32.PurgeComm") +#pragma comment(linker, "/EXPORT:QueryActCtxSettingsW=kernel32.QueryActCtxSettingsW") +#pragma comment(linker, "/EXPORT:QueryActCtxW=kernel32.QueryActCtxW") +#pragma comment(linker, "/EXPORT:QueryDepthSList=kernel32.QueryDepthSList") +#pragma comment(linker, "/EXPORT:QueryDosDeviceA=kernel32.QueryDosDeviceA") +#pragma comment(linker, "/EXPORT:QueryDosDeviceW=kernel32.QueryDosDeviceW") +#pragma comment(linker, "/EXPORT:QueryFullProcessImageNameA=kernel32.QueryFullProcessImageNameA") +#pragma comment(linker, "/EXPORT:QueryFullProcessImageNameW=kernel32.QueryFullProcessImageNameW") +#pragma comment(linker, "/EXPORT:QueryIdleProcessorCycleTime=kernel32.QueryIdleProcessorCycleTime") +#pragma comment(linker, "/EXPORT:QueryIdleProcessorCycleTimeEx=kernel32.QueryIdleProcessorCycleTimeEx") +#pragma comment(linker, "/EXPORT:QueryInformationJobObject=kernel32.QueryInformationJobObject") +#pragma comment(linker, "/EXPORT:QueryMemoryResourceNotification=kernel32.QueryMemoryResourceNotification") +#pragma comment(linker, "/EXPORT:QueryPerformanceCounter=kernel32.QueryPerformanceCounter") +#pragma comment(linker, "/EXPORT:QueryPerformanceFrequency=kernel32.QueryPerformanceFrequency") +#pragma comment(linker, "/EXPORT:QueryProcessAffinityUpdateMode=kernel32.QueryProcessAffinityUpdateMode") +#pragma comment(linker, "/EXPORT:QueryProcessCycleTime=kernel32.QueryProcessCycleTime") +#pragma comment(linker, "/EXPORT:QueryThreadCycleTime=kernel32.QueryThreadCycleTime") +#pragma comment(linker, "/EXPORT:QueryThreadProfiling=kernel32.QueryThreadProfiling") +#pragma comment(linker, "/EXPORT:QueryThreadpoolStackInformation=kernel32.QueryThreadpoolStackInformation") +#pragma comment(linker, "/EXPORT:QueryUnbiasedInterruptTime=kernel32.QueryUnbiasedInterruptTime") +#pragma comment(linker, "/EXPORT:QueueUserAPC=kernel32.QueueUserAPC") +#pragma comment(linker, "/EXPORT:QueueUserWorkItem=kernel32.QueueUserWorkItem") +#pragma comment(linker, "/EXPORT:RaiseException=kernel32.RaiseException") +#pragma comment(linker, "/EXPORT:RaiseFailFastException=kernel32.RaiseFailFastException") +#pragma comment(linker, "/EXPORT:ReOpenFile=kernel32.ReOpenFile") +#pragma comment(linker, "/EXPORT:ReadConsoleA=kernel32.ReadConsoleA") +#pragma comment(linker, "/EXPORT:ReadConsoleInputA=kernel32.ReadConsoleInputA") +#pragma comment(linker, "/EXPORT:ReadConsoleInputExA=kernel32.ReadConsoleInputExA") +#pragma comment(linker, "/EXPORT:ReadConsoleInputExW=kernel32.ReadConsoleInputExW") +#pragma comment(linker, "/EXPORT:ReadConsoleInputW=kernel32.ReadConsoleInputW") +#pragma comment(linker, "/EXPORT:ReadConsoleOutputA=kernel32.ReadConsoleOutputA") +#pragma comment(linker, "/EXPORT:ReadConsoleOutputAttribute=kernel32.ReadConsoleOutputAttribute") +#pragma comment(linker, "/EXPORT:ReadConsoleOutputCharacterA=kernel32.ReadConsoleOutputCharacterA") +#pragma comment(linker, "/EXPORT:ReadConsoleOutputCharacterW=kernel32.ReadConsoleOutputCharacterW") +#pragma comment(linker, "/EXPORT:ReadConsoleOutputW=kernel32.ReadConsoleOutputW") +#pragma comment(linker, "/EXPORT:ReadConsoleW=kernel32.ReadConsoleW") +#pragma comment(linker, "/EXPORT:ReadDirectoryChangesW=kernel32.ReadDirectoryChangesW") +#pragma comment(linker, "/EXPORT:ReadFile=kernel32.ReadFile") +#pragma comment(linker, "/EXPORT:ReadFileEx=kernel32.ReadFileEx") +#pragma comment(linker, "/EXPORT:ReadFileScatter=kernel32.ReadFileScatter") +#pragma comment(linker, "/EXPORT:ReadProcessMemory=kernel32.ReadProcessMemory") +#pragma comment(linker, "/EXPORT:ReadThreadProfilingData=kernel32.ReadThreadProfilingData") +#pragma comment(linker, "/EXPORT:RegCloseKey=kernel32.RegCloseKey") +#pragma comment(linker, "/EXPORT:RegCreateKeyExA=kernel32.RegCreateKeyExA") +#pragma comment(linker, "/EXPORT:RegCreateKeyExW=kernel32.RegCreateKeyExW") +#pragma comment(linker, "/EXPORT:RegDeleteKeyExA=kernel32.RegDeleteKeyExA") +#pragma comment(linker, "/EXPORT:RegDeleteKeyExW=kernel32.RegDeleteKeyExW") +#pragma comment(linker, "/EXPORT:RegDeleteTreeA=kernel32.RegDeleteTreeA") +#pragma comment(linker, "/EXPORT:RegDeleteTreeW=kernel32.RegDeleteTreeW") +#pragma comment(linker, "/EXPORT:RegDeleteValueA=kernel32.RegDeleteValueA") +#pragma comment(linker, "/EXPORT:RegDeleteValueW=kernel32.RegDeleteValueW") +#pragma comment(linker, "/EXPORT:RegDisablePredefinedCacheEx=kernel32.RegDisablePredefinedCacheEx") +#pragma comment(linker, "/EXPORT:RegEnumKeyExA=kernel32.RegEnumKeyExA") +#pragma comment(linker, "/EXPORT:RegEnumKeyExW=kernel32.RegEnumKeyExW") +#pragma comment(linker, "/EXPORT:RegEnumValueA=kernel32.RegEnumValueA") +#pragma comment(linker, "/EXPORT:RegEnumValueW=kernel32.RegEnumValueW") +#pragma comment(linker, "/EXPORT:RegFlushKey=kernel32.RegFlushKey") +#pragma comment(linker, "/EXPORT:RegGetKeySecurity=kernel32.RegGetKeySecurity") +#pragma comment(linker, "/EXPORT:RegGetValueA=kernel32.RegGetValueA") +#pragma comment(linker, "/EXPORT:RegGetValueW=kernel32.RegGetValueW") +#pragma comment(linker, "/EXPORT:RegKrnGetGlobalState=kernel32.RegKrnGetGlobalState") +#pragma comment(linker, "/EXPORT:RegKrnInitialize=kernel32.RegKrnInitialize") +#pragma comment(linker, "/EXPORT:RegLoadKeyA=kernel32.RegLoadKeyA") +#pragma comment(linker, "/EXPORT:RegLoadKeyW=kernel32.RegLoadKeyW") +#pragma comment(linker, "/EXPORT:RegLoadMUIStringA=kernel32.RegLoadMUIStringA") +#pragma comment(linker, "/EXPORT:RegLoadMUIStringW=kernel32.RegLoadMUIStringW") +#pragma comment(linker, "/EXPORT:RegNotifyChangeKeyValue=kernel32.RegNotifyChangeKeyValue") +#pragma comment(linker, "/EXPORT:RegOpenCurrentUser=kernel32.RegOpenCurrentUser") +#pragma comment(linker, "/EXPORT:RegOpenKeyExA=kernel32.RegOpenKeyExA") +#pragma comment(linker, "/EXPORT:RegOpenKeyExW=kernel32.RegOpenKeyExW") +#pragma comment(linker, "/EXPORT:RegOpenUserClassesRoot=kernel32.RegOpenUserClassesRoot") +#pragma comment(linker, "/EXPORT:RegQueryInfoKeyA=kernel32.RegQueryInfoKeyA") +#pragma comment(linker, "/EXPORT:RegQueryInfoKeyW=kernel32.RegQueryInfoKeyW") +#pragma comment(linker, "/EXPORT:RegQueryValueExA=kernel32.RegQueryValueExA") +#pragma comment(linker, "/EXPORT:RegQueryValueExW=kernel32.RegQueryValueExW") +#pragma comment(linker, "/EXPORT:RegRestoreKeyA=kernel32.RegRestoreKeyA") +#pragma comment(linker, "/EXPORT:RegRestoreKeyW=kernel32.RegRestoreKeyW") +#pragma comment(linker, "/EXPORT:RegSaveKeyExA=kernel32.RegSaveKeyExA") +#pragma comment(linker, "/EXPORT:RegSaveKeyExW=kernel32.RegSaveKeyExW") +#pragma comment(linker, "/EXPORT:RegSetKeySecurity=kernel32.RegSetKeySecurity") +#pragma comment(linker, "/EXPORT:RegSetValueExA=kernel32.RegSetValueExA") +#pragma comment(linker, "/EXPORT:RegSetValueExW=kernel32.RegSetValueExW") +#pragma comment(linker, "/EXPORT:RegUnLoadKeyA=kernel32.RegUnLoadKeyA") +#pragma comment(linker, "/EXPORT:RegUnLoadKeyW=kernel32.RegUnLoadKeyW") +#pragma comment(linker, "/EXPORT:RegisterApplicationRecoveryCallback=kernel32.RegisterApplicationRecoveryCallback") +#pragma comment(linker, "/EXPORT:RegisterApplicationRestart=kernel32.RegisterApplicationRestart") +#pragma comment(linker, "/EXPORT:RegisterConsoleIME=kernel32.RegisterConsoleIME") +#pragma comment(linker, "/EXPORT:RegisterConsoleOS2=kernel32.RegisterConsoleOS2") +#pragma comment(linker, "/EXPORT:RegisterConsoleVDM=kernel32.RegisterConsoleVDM") +#pragma comment(linker, "/EXPORT:RegisterWaitForInputIdle=kernel32.RegisterWaitForInputIdle") +#pragma comment(linker, "/EXPORT:RegisterWaitForSingleObject=kernel32.RegisterWaitForSingleObject") +#pragma comment(linker, "/EXPORT:RegisterWaitForSingleObjectEx=kernel32.RegisterWaitForSingleObjectEx") +#pragma comment(linker, "/EXPORT:RegisterWowBaseHandlers=kernel32.RegisterWowBaseHandlers") +#pragma comment(linker, "/EXPORT:RegisterWowExec=kernel32.RegisterWowExec") +#pragma comment(linker, "/EXPORT:ReleaseActCtx=kernel32.ReleaseActCtx") +#pragma comment(linker, "/EXPORT:ReleaseMutex=kernel32.ReleaseMutex") +#pragma comment(linker, "/EXPORT:ReleaseMutexWhenCallbackReturns=kernel32.ReleaseMutexWhenCallbackReturns") +#pragma comment(linker, "/EXPORT:ReleaseSRWLockExclusive=kernel32.ReleaseSRWLockExclusive") +#pragma comment(linker, "/EXPORT:ReleaseSRWLockShared=kernel32.ReleaseSRWLockShared") +#pragma comment(linker, "/EXPORT:ReleaseSemaphore=kernel32.ReleaseSemaphore") +#pragma comment(linker, "/EXPORT:ReleaseSemaphoreWhenCallbackReturns=kernel32.ReleaseSemaphoreWhenCallbackReturns") +#pragma comment(linker, "/EXPORT:RemoveDirectoryA=kernel32.RemoveDirectoryA") +#pragma comment(linker, "/EXPORT:RemoveDirectoryTransactedA=kernel32.RemoveDirectoryTransactedA") +#pragma comment(linker, "/EXPORT:RemoveDirectoryTransactedW=kernel32.RemoveDirectoryTransactedW") +#pragma comment(linker, "/EXPORT:RemoveDirectoryW=kernel32.RemoveDirectoryW") +//#pragma comment(linker, "/EXPORT:RemoveDllDirectory=kernel32.RemoveDllDirectory") +#pragma comment(linker, "/EXPORT:RemoveLocalAlternateComputerNameA=kernel32.RemoveLocalAlternateComputerNameA") +#pragma comment(linker, "/EXPORT:RemoveLocalAlternateComputerNameW=kernel32.RemoveLocalAlternateComputerNameW") +#pragma comment(linker, "/EXPORT:RemoveSecureMemoryCacheCallback=kernel32.RemoveSecureMemoryCacheCallback") +#pragma comment(linker, "/EXPORT:RemoveVectoredContinueHandler=kernel32.RemoveVectoredContinueHandler") +#pragma comment(linker, "/EXPORT:RemoveVectoredExceptionHandler=kernel32.RemoveVectoredExceptionHandler") +#pragma comment(linker, "/EXPORT:ReplaceFile=kernel32.ReplaceFile") +#pragma comment(linker, "/EXPORT:ReplaceFileA=kernel32.ReplaceFileA") +#pragma comment(linker, "/EXPORT:ReplaceFileW=kernel32.ReplaceFileW") +#pragma comment(linker, "/EXPORT:ReplacePartitionUnit=kernel32.ReplacePartitionUnit") +#pragma comment(linker, "/EXPORT:RequestDeviceWakeup=kernel32.RequestDeviceWakeup") +#pragma comment(linker, "/EXPORT:RequestWakeupLatency=kernel32.RequestWakeupLatency") +#pragma comment(linker, "/EXPORT:ResetEvent=kernel32.ResetEvent") +#pragma comment(linker, "/EXPORT:ResetWriteWatch=kernel32.ResetWriteWatch") +#pragma comment(linker, "/EXPORT:ResolveLocaleName=kernel32.ResolveLocaleName") +#pragma comment(linker, "/EXPORT:RestoreLastError=kernel32.RestoreLastError") +#pragma comment(linker, "/EXPORT:ResumeThread=kernel32.ResumeThread") +#pragma comment(linker, "/EXPORT:RtlCaptureContext=kernel32.RtlCaptureContext") +#pragma comment(linker, "/EXPORT:RtlCaptureStackBackTrace=kernel32.RtlCaptureStackBackTrace") +#pragma comment(linker, "/EXPORT:RtlFillMemory=kernel32.RtlFillMemory") +#pragma comment(linker, "/EXPORT:RtlMoveMemory=kernel32.RtlMoveMemory") +#pragma comment(linker, "/EXPORT:RtlUnwind=kernel32.RtlUnwind") +#pragma comment(linker, "/EXPORT:RtlZeroMemory=kernel32.RtlZeroMemory") +#pragma comment(linker, "/EXPORT:ScrollConsoleScreenBufferA=kernel32.ScrollConsoleScreenBufferA") +#pragma comment(linker, "/EXPORT:ScrollConsoleScreenBufferW=kernel32.ScrollConsoleScreenBufferW") +#pragma comment(linker, "/EXPORT:SearchPathA=kernel32.SearchPathA") +#pragma comment(linker, "/EXPORT:SearchPathW=kernel32.SearchPathW") +#pragma comment(linker, "/EXPORT:SetCalendarInfoA=kernel32.SetCalendarInfoA") +#pragma comment(linker, "/EXPORT:SetCalendarInfoW=kernel32.SetCalendarInfoW") +#pragma comment(linker, "/EXPORT:SetClientDynamicTimeZoneInformation=kernel32.SetClientDynamicTimeZoneInformation") +#pragma comment(linker, "/EXPORT:SetClientTimeZoneInformation=kernel32.SetClientTimeZoneInformation") +#pragma comment(linker, "/EXPORT:SetComPlusPackageInstallStatus=kernel32.SetComPlusPackageInstallStatus") +#pragma comment(linker, "/EXPORT:SetCommBreak=kernel32.SetCommBreak") +#pragma comment(linker, "/EXPORT:SetCommConfig=kernel32.SetCommConfig") +#pragma comment(linker, "/EXPORT:SetCommMask=kernel32.SetCommMask") +#pragma comment(linker, "/EXPORT:SetCommState=kernel32.SetCommState") +#pragma comment(linker, "/EXPORT:SetCommTimeouts=kernel32.SetCommTimeouts") +#pragma comment(linker, "/EXPORT:SetComputerNameA=kernel32.SetComputerNameA") +#pragma comment(linker, "/EXPORT:SetComputerNameExA=kernel32.SetComputerNameExA") +#pragma comment(linker, "/EXPORT:SetComputerNameExW=kernel32.SetComputerNameExW") +#pragma comment(linker, "/EXPORT:SetComputerNameW=kernel32.SetComputerNameW") +#pragma comment(linker, "/EXPORT:SetConsoleActiveScreenBuffer=kernel32.SetConsoleActiveScreenBuffer") +#pragma comment(linker, "/EXPORT:SetConsoleCP=kernel32.SetConsoleCP") +#pragma comment(linker, "/EXPORT:SetConsoleCtrlHandler=kernel32.SetConsoleCtrlHandler") +#pragma comment(linker, "/EXPORT:SetConsoleCursor=kernel32.SetConsoleCursor") +#pragma comment(linker, "/EXPORT:SetConsoleCursorInfo=kernel32.SetConsoleCursorInfo") +#pragma comment(linker, "/EXPORT:SetConsoleCursorMode=kernel32.SetConsoleCursorMode") +#pragma comment(linker, "/EXPORT:SetConsoleCursorPosition=kernel32.SetConsoleCursorPosition") +#pragma comment(linker, "/EXPORT:SetConsoleDisplayMode=kernel32.SetConsoleDisplayMode") +#pragma comment(linker, "/EXPORT:SetConsoleFont=kernel32.SetConsoleFont") +#pragma comment(linker, "/EXPORT:SetConsoleHardwareState=kernel32.SetConsoleHardwareState") +#pragma comment(linker, "/EXPORT:SetConsoleHistoryInfo=kernel32.SetConsoleHistoryInfo") +#pragma comment(linker, "/EXPORT:SetConsoleIcon=kernel32.SetConsoleIcon") +#pragma comment(linker, "/EXPORT:SetConsoleInputExeNameA=kernel32.SetConsoleInputExeNameA") +#pragma comment(linker, "/EXPORT:SetConsoleInputExeNameW=kernel32.SetConsoleInputExeNameW") +#pragma comment(linker, "/EXPORT:SetConsoleKeyShortcuts=kernel32.SetConsoleKeyShortcuts") +#pragma comment(linker, "/EXPORT:SetConsoleLocalEUDC=kernel32.SetConsoleLocalEUDC") +#pragma comment(linker, "/EXPORT:SetConsoleMaximumWindowSize=kernel32.SetConsoleMaximumWindowSize") +#pragma comment(linker, "/EXPORT:SetConsoleMenuClose=kernel32.SetConsoleMenuClose") +#pragma comment(linker, "/EXPORT:SetConsoleMode=kernel32.SetConsoleMode") +#pragma comment(linker, "/EXPORT:SetConsoleNlsMode=kernel32.SetConsoleNlsMode") +#pragma comment(linker, "/EXPORT:SetConsoleNumberOfCommandsA=kernel32.SetConsoleNumberOfCommandsA") +#pragma comment(linker, "/EXPORT:SetConsoleNumberOfCommandsW=kernel32.SetConsoleNumberOfCommandsW") +#pragma comment(linker, "/EXPORT:SetConsoleOS2OemFormat=kernel32.SetConsoleOS2OemFormat") +#pragma comment(linker, "/EXPORT:SetConsoleOutputCP=kernel32.SetConsoleOutputCP") +#pragma comment(linker, "/EXPORT:SetConsolePalette=kernel32.SetConsolePalette") +#pragma comment(linker, "/EXPORT:SetConsoleScreenBufferInfoEx=kernel32.SetConsoleScreenBufferInfoEx") +#pragma comment(linker, "/EXPORT:SetConsoleScreenBufferSize=kernel32.SetConsoleScreenBufferSize") +#pragma comment(linker, "/EXPORT:SetConsoleTextAttribute=kernel32.SetConsoleTextAttribute") +#pragma comment(linker, "/EXPORT:SetConsoleTitleA=kernel32.SetConsoleTitleA") +#pragma comment(linker, "/EXPORT:SetConsoleTitleW=kernel32.SetConsoleTitleW") +#pragma comment(linker, "/EXPORT:SetConsoleWindowInfo=kernel32.SetConsoleWindowInfo") +#pragma comment(linker, "/EXPORT:SetCriticalSectionSpinCount=kernel32.SetCriticalSectionSpinCount") +#pragma comment(linker, "/EXPORT:SetCurrentConsoleFontEx=kernel32.SetCurrentConsoleFontEx") +#pragma comment(linker, "/EXPORT:SetCurrentDirectoryA=kernel32.SetCurrentDirectoryA") +#pragma comment(linker, "/EXPORT:SetCurrentDirectoryW=kernel32.SetCurrentDirectoryW") +#pragma comment(linker, "/EXPORT:SetDefaultCommConfigA=kernel32.SetDefaultCommConfigA") +#pragma comment(linker, "/EXPORT:SetDefaultCommConfigW=kernel32.SetDefaultCommConfigW") +//#pragma comment(linker, "/EXPORT:SetDefaultDllDirectories=kernel32.SetDefaultDllDirectories") +#pragma comment(linker, "/EXPORT:SetDllDirectoryA=kernel32.SetDllDirectoryA") +#pragma comment(linker, "/EXPORT:SetDllDirectoryW=kernel32.SetDllDirectoryW") +#pragma comment(linker, "/EXPORT:SetDynamicTimeZoneInformation=kernel32.SetDynamicTimeZoneInformation") +#pragma comment(linker, "/EXPORT:SetEndOfFile=kernel32.SetEndOfFile") +#pragma comment(linker, "/EXPORT:SetEnvironmentStringsA=kernel32.SetEnvironmentStringsA") +#pragma comment(linker, "/EXPORT:SetEnvironmentStringsW=kernel32.SetEnvironmentStringsW") +#pragma comment(linker, "/EXPORT:SetEnvironmentVariableA=kernel32.SetEnvironmentVariableA") +#pragma comment(linker, "/EXPORT:SetEnvironmentVariableW=kernel32.SetEnvironmentVariableW") +#pragma comment(linker, "/EXPORT:SetErrorMode=kernel32.SetErrorMode") +#pragma comment(linker, "/EXPORT:SetEvent=kernel32.SetEvent") +#pragma comment(linker, "/EXPORT:SetEventWhenCallbackReturns=kernel32.SetEventWhenCallbackReturns") +#pragma comment(linker, "/EXPORT:SetFileApisToANSI=kernel32.SetFileApisToANSI") +#pragma comment(linker, "/EXPORT:SetFileApisToOEM=kernel32.SetFileApisToOEM") +#pragma comment(linker, "/EXPORT:SetFileAttributesA=kernel32.SetFileAttributesA") +#pragma comment(linker, "/EXPORT:SetFileAttributesTransactedA=kernel32.SetFileAttributesTransactedA") +#pragma comment(linker, "/EXPORT:SetFileAttributesTransactedW=kernel32.SetFileAttributesTransactedW") +#pragma comment(linker, "/EXPORT:SetFileAttributesW=kernel32.SetFileAttributesW") +#pragma comment(linker, "/EXPORT:SetFileBandwidthReservation=kernel32.SetFileBandwidthReservation") +#pragma comment(linker, "/EXPORT:SetFileCompletionNotificationModes=kernel32.SetFileCompletionNotificationModes") +#pragma comment(linker, "/EXPORT:SetFileInformationByHandle=kernel32.SetFileInformationByHandle") +#pragma comment(linker, "/EXPORT:SetFileIoOverlappedRange=kernel32.SetFileIoOverlappedRange") +#pragma comment(linker, "/EXPORT:SetFilePointer=kernel32.SetFilePointer") +#pragma comment(linker, "/EXPORT:SetFilePointerEx=kernel32.SetFilePointerEx") +#pragma comment(linker, "/EXPORT:SetFileShortNameA=kernel32.SetFileShortNameA") +#pragma comment(linker, "/EXPORT:SetFileShortNameW=kernel32.SetFileShortNameW") +#pragma comment(linker, "/EXPORT:SetFileTime=kernel32.SetFileTime") +#pragma comment(linker, "/EXPORT:SetFileValidData=kernel32.SetFileValidData") +#pragma comment(linker, "/EXPORT:SetFirmwareEnvironmentVariableA=kernel32.SetFirmwareEnvironmentVariableA") +#pragma comment(linker, "/EXPORT:SetFirmwareEnvironmentVariableW=kernel32.SetFirmwareEnvironmentVariableW") +#pragma comment(linker, "/EXPORT:SetHandleCount=kernel32.SetHandleCount") +#pragma comment(linker, "/EXPORT:SetHandleInformation=kernel32.SetHandleInformation") +#pragma comment(linker, "/EXPORT:SetInformationJobObject=kernel32.SetInformationJobObject") +#pragma comment(linker, "/EXPORT:SetLastConsoleEventActive=kernel32.SetLastConsoleEventActive") +#pragma comment(linker, "/EXPORT:SetLastError=kernel32.SetLastError") +#pragma comment(linker, "/EXPORT:SetLocalPrimaryComputerNameA=kernel32.SetLocalPrimaryComputerNameA") +#pragma comment(linker, "/EXPORT:SetLocalPrimaryComputerNameW=kernel32.SetLocalPrimaryComputerNameW") +#pragma comment(linker, "/EXPORT:SetLocalTime=kernel32.SetLocalTime") +#pragma comment(linker, "/EXPORT:SetLocaleInfoA=kernel32.SetLocaleInfoA") +#pragma comment(linker, "/EXPORT:SetLocaleInfoW=kernel32.SetLocaleInfoW") +#pragma comment(linker, "/EXPORT:SetMailslotInfo=kernel32.SetMailslotInfo") +#pragma comment(linker, "/EXPORT:SetMessageWaitingIndicator=kernel32.SetMessageWaitingIndicator") +#pragma comment(linker, "/EXPORT:SetNamedPipeAttribute=kernel32.SetNamedPipeAttribute") +#pragma comment(linker, "/EXPORT:SetNamedPipeHandleState=kernel32.SetNamedPipeHandleState") +#pragma comment(linker, "/EXPORT:SetPriorityClass=kernel32.SetPriorityClass") +#pragma comment(linker, "/EXPORT:SetProcessAffinityMask=kernel32.SetProcessAffinityMask") +#pragma comment(linker, "/EXPORT:SetProcessAffinityUpdateMode=kernel32.SetProcessAffinityUpdateMode") +#pragma comment(linker, "/EXPORT:SetProcessDEPPolicy=kernel32.SetProcessDEPPolicy") +#pragma comment(linker, "/EXPORT:SetProcessPreferredUILanguages=kernel32.SetProcessPreferredUILanguages") +#pragma comment(linker, "/EXPORT:SetProcessPriorityBoost=kernel32.SetProcessPriorityBoost") +#pragma comment(linker, "/EXPORT:SetProcessShutdownParameters=kernel32.SetProcessShutdownParameters") +#pragma comment(linker, "/EXPORT:SetProcessUserModeExceptionPolicy=kernel32.SetProcessUserModeExceptionPolicy") +#pragma comment(linker, "/EXPORT:SetProcessWorkingSetSize=kernel32.SetProcessWorkingSetSize") +#pragma comment(linker, "/EXPORT:SetProcessWorkingSetSizeEx=kernel32.SetProcessWorkingSetSizeEx") +#pragma comment(linker, "/EXPORT:SetSearchPathMode=kernel32.SetSearchPathMode") +#pragma comment(linker, "/EXPORT:SetStdHandle=kernel32.SetStdHandle") +#pragma comment(linker, "/EXPORT:SetStdHandleEx=kernel32.SetStdHandleEx") +#pragma comment(linker, "/EXPORT:SetSystemFileCacheSize=kernel32.SetSystemFileCacheSize") +#pragma comment(linker, "/EXPORT:SetSystemPowerState=kernel32.SetSystemPowerState") +#pragma comment(linker, "/EXPORT:SetSystemTime=kernel32.SetSystemTime") +#pragma comment(linker, "/EXPORT:SetSystemTimeAdjustment=kernel32.SetSystemTimeAdjustment") +#pragma comment(linker, "/EXPORT:SetTapeParameters=kernel32.SetTapeParameters") +#pragma comment(linker, "/EXPORT:SetTapePosition=kernel32.SetTapePosition") +#pragma comment(linker, "/EXPORT:SetTermsrvAppInstallMode=kernel32.SetTermsrvAppInstallMode") +#pragma comment(linker, "/EXPORT:SetThreadAffinityMask=kernel32.SetThreadAffinityMask") +#pragma comment(linker, "/EXPORT:SetThreadContext=kernel32.SetThreadContext") +#pragma comment(linker, "/EXPORT:SetThreadErrorMode=kernel32.SetThreadErrorMode") +#pragma comment(linker, "/EXPORT:SetThreadExecutionState=kernel32.SetThreadExecutionState") +#pragma comment(linker, "/EXPORT:SetThreadGroupAffinity=kernel32.SetThreadGroupAffinity") +#pragma comment(linker, "/EXPORT:SetThreadIdealProcessor=kernel32.SetThreadIdealProcessor") +#pragma comment(linker, "/EXPORT:SetThreadIdealProcessorEx=kernel32.SetThreadIdealProcessorEx") +#pragma comment(linker, "/EXPORT:SetThreadLocale=kernel32.SetThreadLocale") +#pragma comment(linker, "/EXPORT:SetThreadPreferredUILanguages=kernel32.SetThreadPreferredUILanguages") +#pragma comment(linker, "/EXPORT:SetThreadPriority=kernel32.SetThreadPriority") +#pragma comment(linker, "/EXPORT:SetThreadPriorityBoost=kernel32.SetThreadPriorityBoost") +#pragma comment(linker, "/EXPORT:SetThreadStackGuarantee=kernel32.SetThreadStackGuarantee") +#pragma comment(linker, "/EXPORT:SetThreadToken=kernel32.SetThreadToken") +#pragma comment(linker, "/EXPORT:SetThreadUILanguage=kernel32.SetThreadUILanguage") +#pragma comment(linker, "/EXPORT:SetThreadpoolStackInformation=kernel32.SetThreadpoolStackInformation") +#pragma comment(linker, "/EXPORT:SetThreadpoolThreadMaximum=kernel32.SetThreadpoolThreadMaximum") +#pragma comment(linker, "/EXPORT:SetThreadpoolThreadMinimum=kernel32.SetThreadpoolThreadMinimum") +#pragma comment(linker, "/EXPORT:SetThreadpoolTimer=kernel32.SetThreadpoolTimer") +#pragma comment(linker, "/EXPORT:SetThreadpoolWait=kernel32.SetThreadpoolWait") +#pragma comment(linker, "/EXPORT:SetTimeZoneInformation=kernel32.SetTimeZoneInformation") +#pragma comment(linker, "/EXPORT:SetTimerQueueTimer=kernel32.SetTimerQueueTimer") +#pragma comment(linker, "/EXPORT:SetUnhandledExceptionFilter=kernel32.SetUnhandledExceptionFilter") +#pragma comment(linker, "/EXPORT:SetUserGeoID=kernel32.SetUserGeoID") +#pragma comment(linker, "/EXPORT:SetVDMCurrentDirectories=kernel32.SetVDMCurrentDirectories") +#pragma comment(linker, "/EXPORT:SetVolumeLabelA=kernel32.SetVolumeLabelA") +#pragma comment(linker, "/EXPORT:SetVolumeLabelW=kernel32.SetVolumeLabelW") +#pragma comment(linker, "/EXPORT:SetVolumeMountPointA=kernel32.SetVolumeMountPointA") +#pragma comment(linker, "/EXPORT:SetVolumeMountPointW=kernel32.SetVolumeMountPointW") +#pragma comment(linker, "/EXPORT:SetWaitableTimer=kernel32.SetWaitableTimer") +#pragma comment(linker, "/EXPORT:SetWaitableTimerEx=kernel32.SetWaitableTimerEx") +#pragma comment(linker, "/EXPORT:SetXStateFeaturesMask=kernel32.SetXStateFeaturesMask") +#pragma comment(linker, "/EXPORT:SetupComm=kernel32.SetupComm") +#pragma comment(linker, "/EXPORT:ShowConsoleCursor=kernel32.ShowConsoleCursor") +#pragma comment(linker, "/EXPORT:SignalObjectAndWait=kernel32.SignalObjectAndWait") +#pragma comment(linker, "/EXPORT:SizeofResource=kernel32.SizeofResource") +#pragma comment(linker, "/EXPORT:Sleep=kernel32.Sleep") +#pragma comment(linker, "/EXPORT:SleepConditionVariableCS=kernel32.SleepConditionVariableCS") +#pragma comment(linker, "/EXPORT:SleepConditionVariableSRW=kernel32.SleepConditionVariableSRW") +#pragma comment(linker, "/EXPORT:SleepEx=kernel32.SleepEx") +#pragma comment(linker, "/EXPORT:SortCloseHandle=kernel32.SortCloseHandle") +#pragma comment(linker, "/EXPORT:SortGetHandle=kernel32.SortGetHandle") +#pragma comment(linker, "/EXPORT:StartThreadpoolIo=kernel32.StartThreadpoolIo") +#pragma comment(linker, "/EXPORT:SubmitThreadpoolWork=kernel32.SubmitThreadpoolWork") +#pragma comment(linker, "/EXPORT:SuspendThread=kernel32.SuspendThread") +#pragma comment(linker, "/EXPORT:SwitchToFiber=kernel32.SwitchToFiber") +#pragma comment(linker, "/EXPORT:SwitchToThread=kernel32.SwitchToThread") +#pragma comment(linker, "/EXPORT:SystemTimeToFileTime=kernel32.SystemTimeToFileTime") +#pragma comment(linker, "/EXPORT:SystemTimeToTzSpecificLocalTime=kernel32.SystemTimeToTzSpecificLocalTime") +#pragma comment(linker, "/EXPORT:SystemTimeToTzSpecificLocalTimeEx=kernel32.SystemTimeToTzSpecificLocalTimeEx") +#pragma comment(linker, "/EXPORT:TerminateJobObject=kernel32.TerminateJobObject") +#pragma comment(linker, "/EXPORT:TerminateProcess=kernel32.TerminateProcess") +#pragma comment(linker, "/EXPORT:TerminateThread=kernel32.TerminateThread") +#pragma comment(linker, "/EXPORT:TermsrvAppInstallMode=kernel32.TermsrvAppInstallMode") +#pragma comment(linker, "/EXPORT:Thread32First=kernel32.Thread32First") +#pragma comment(linker, "/EXPORT:Thread32Next=kernel32.Thread32Next") +#pragma comment(linker, "/EXPORT:TlsAlloc=kernel32.TlsAlloc") +#pragma comment(linker, "/EXPORT:TlsFree=kernel32.TlsFree") +#pragma comment(linker, "/EXPORT:TlsGetValue=kernel32.TlsGetValue") +#pragma comment(linker, "/EXPORT:TlsSetValue=kernel32.TlsSetValue") +#pragma comment(linker, "/EXPORT:Toolhelp32ReadProcessMemory=kernel32.Toolhelp32ReadProcessMemory") +#pragma comment(linker, "/EXPORT:TransactNamedPipe=kernel32.TransactNamedPipe") +#pragma comment(linker, "/EXPORT:TransmitCommChar=kernel32.TransmitCommChar") +#pragma comment(linker, "/EXPORT:TryAcquireSRWLockExclusive=kernel32.TryAcquireSRWLockExclusive") +#pragma comment(linker, "/EXPORT:TryAcquireSRWLockShared=kernel32.TryAcquireSRWLockShared") +#pragma comment(linker, "/EXPORT:TryEnterCriticalSection=kernel32.TryEnterCriticalSection") +#pragma comment(linker, "/EXPORT:TrySubmitThreadpoolCallback=kernel32.TrySubmitThreadpoolCallback") +#pragma comment(linker, "/EXPORT:TzSpecificLocalTimeToSystemTime=kernel32.TzSpecificLocalTimeToSystemTime") +#pragma comment(linker, "/EXPORT:TzSpecificLocalTimeToSystemTimeEx=kernel32.TzSpecificLocalTimeToSystemTimeEx") +#pragma comment(linker, "/EXPORT:UTRegister=kernel32.UTRegister") +#pragma comment(linker, "/EXPORT:UTUnRegister=kernel32.UTUnRegister") +#pragma comment(linker, "/EXPORT:UnhandledExceptionFilter=kernel32.UnhandledExceptionFilter") +#pragma comment(linker, "/EXPORT:UnlockFile=kernel32.UnlockFile") +#pragma comment(linker, "/EXPORT:UnlockFileEx=kernel32.UnlockFileEx") +#pragma comment(linker, "/EXPORT:UnmapViewOfFile=kernel32.UnmapViewOfFile") +#pragma comment(linker, "/EXPORT:UnregisterApplicationRecoveryCallback=kernel32.UnregisterApplicationRecoveryCallback") +#pragma comment(linker, "/EXPORT:UnregisterApplicationRestart=kernel32.UnregisterApplicationRestart") +#pragma comment(linker, "/EXPORT:UnregisterConsoleIME=kernel32.UnregisterConsoleIME") +#pragma comment(linker, "/EXPORT:UnregisterWait=kernel32.UnregisterWait") +#pragma comment(linker, "/EXPORT:UnregisterWaitEx=kernel32.UnregisterWaitEx") +#pragma comment(linker, "/EXPORT:UpdateCalendarDayOfWeek=kernel32.UpdateCalendarDayOfWeek") +//#pragma comment(linker, "/EXPORT:UpdateProcThreadAttribute=kernel32.UpdateProcThreadAttribute") +#pragma comment(linker, "/EXPORT:UpdateResourceA=kernel32.UpdateResourceA") +#pragma comment(linker, "/EXPORT:UpdateResourceW=kernel32.UpdateResourceW") +#pragma comment(linker, "/EXPORT:VDMConsoleOperation=kernel32.VDMConsoleOperation") +#pragma comment(linker, "/EXPORT:VDMOperationStarted=kernel32.VDMOperationStarted") +#pragma comment(linker, "/EXPORT:VerLanguageNameA=kernel32.VerLanguageNameA") +#pragma comment(linker, "/EXPORT:VerLanguageNameW=kernel32.VerLanguageNameW") +#pragma comment(linker, "/EXPORT:VerSetConditionMask=kernel32.VerSetConditionMask") +#pragma comment(linker, "/EXPORT:VerifyConsoleIoHandle=kernel32.VerifyConsoleIoHandle") +#pragma comment(linker, "/EXPORT:VerifyScripts=kernel32.VerifyScripts") +#pragma comment(linker, "/EXPORT:VerifyVersionInfoA=kernel32.VerifyVersionInfoA") +#pragma comment(linker, "/EXPORT:VerifyVersionInfoW=kernel32.VerifyVersionInfoW") +#pragma comment(linker, "/EXPORT:VirtualAlloc=kernel32.VirtualAlloc") +#pragma comment(linker, "/EXPORT:VirtualAllocEx=kernel32.VirtualAllocEx") +#pragma comment(linker, "/EXPORT:VirtualAllocExNuma=kernel32.VirtualAllocExNuma") +#pragma comment(linker, "/EXPORT:VirtualFree=kernel32.VirtualFree") +#pragma comment(linker, "/EXPORT:VirtualFreeEx=kernel32.VirtualFreeEx") +#pragma comment(linker, "/EXPORT:VirtualLock=kernel32.VirtualLock") +#pragma comment(linker, "/EXPORT:VirtualProtect=kernel32.VirtualProtect") +#pragma comment(linker, "/EXPORT:VirtualProtectEx=kernel32.VirtualProtectEx") +#pragma comment(linker, "/EXPORT:VirtualQuery=kernel32.VirtualQuery") +#pragma comment(linker, "/EXPORT:VirtualQueryEx=kernel32.VirtualQueryEx") +#pragma comment(linker, "/EXPORT:VirtualUnlock=kernel32.VirtualUnlock") +#pragma comment(linker, "/EXPORT:WTSGetActiveConsoleSessionId=kernel32.WTSGetActiveConsoleSessionId") +#pragma comment(linker, "/EXPORT:WaitCommEvent=kernel32.WaitCommEvent") +#pragma comment(linker, "/EXPORT:WaitForDebugEvent=kernel32.WaitForDebugEvent") +#pragma comment(linker, "/EXPORT:WaitForMultipleObjects=kernel32.WaitForMultipleObjects") +#pragma comment(linker, "/EXPORT:WaitForMultipleObjectsEx=kernel32.WaitForMultipleObjectsEx") +#pragma comment(linker, "/EXPORT:WaitForSingleObject=kernel32.WaitForSingleObject") +#pragma comment(linker, "/EXPORT:WaitForSingleObjectEx=kernel32.WaitForSingleObjectEx") +#pragma comment(linker, "/EXPORT:WaitForThreadpoolIoCallbacks=kernel32.WaitForThreadpoolIoCallbacks") +#pragma comment(linker, "/EXPORT:WaitForThreadpoolTimerCallbacks=kernel32.WaitForThreadpoolTimerCallbacks") +#pragma comment(linker, "/EXPORT:WaitForThreadpoolWaitCallbacks=kernel32.WaitForThreadpoolWaitCallbacks") +#pragma comment(linker, "/EXPORT:WaitForThreadpoolWorkCallbacks=kernel32.WaitForThreadpoolWorkCallbacks") +#pragma comment(linker, "/EXPORT:WaitNamedPipeA=kernel32.WaitNamedPipeA") +#pragma comment(linker, "/EXPORT:WaitNamedPipeW=kernel32.WaitNamedPipeW") +#pragma comment(linker, "/EXPORT:WakeAllConditionVariable=kernel32.WakeAllConditionVariable") +#pragma comment(linker, "/EXPORT:WakeConditionVariable=kernel32.WakeConditionVariable") +#pragma comment(linker, "/EXPORT:WerGetFlags=kernel32.WerGetFlags") +#pragma comment(linker, "/EXPORT:WerRegisterFile=kernel32.WerRegisterFile") +#pragma comment(linker, "/EXPORT:WerRegisterMemoryBlock=kernel32.WerRegisterMemoryBlock") +#pragma comment(linker, "/EXPORT:WerRegisterRuntimeExceptionModule=kernel32.WerRegisterRuntimeExceptionModule") +#pragma comment(linker, "/EXPORT:WerSetFlags=kernel32.WerSetFlags") +#pragma comment(linker, "/EXPORT:WerUnregisterFile=kernel32.WerUnregisterFile") +#pragma comment(linker, "/EXPORT:WerUnregisterMemoryBlock=kernel32.WerUnregisterMemoryBlock") +#pragma comment(linker, "/EXPORT:WerUnregisterRuntimeExceptionModule=kernel32.WerUnregisterRuntimeExceptionModule") +#pragma comment(linker, "/EXPORT:WerpCleanupMessageMapping=kernel32.WerpCleanupMessageMapping") +#pragma comment(linker, "/EXPORT:WerpInitiateRemoteRecovery=kernel32.WerpInitiateRemoteRecovery") +#pragma comment(linker, "/EXPORT:WerpNotifyLoadStringResource=kernel32.WerpNotifyLoadStringResource") +#pragma comment(linker, "/EXPORT:WerpNotifyLoadStringResourceEx=kernel32.WerpNotifyLoadStringResourceEx") +#pragma comment(linker, "/EXPORT:WerpNotifyUseStringResource=kernel32.WerpNotifyUseStringResource") +#pragma comment(linker, "/EXPORT:WerpStringLookup=kernel32.WerpStringLookup") +#pragma comment(linker, "/EXPORT:WideCharToMultiByte=kernel32.WideCharToMultiByte") +#pragma comment(linker, "/EXPORT:WinExec=kernel32.WinExec") +#pragma comment(linker, "/EXPORT:Wow64DisableWow64FsRedirection=kernel32.Wow64DisableWow64FsRedirection") +#pragma comment(linker, "/EXPORT:Wow64EnableWow64FsRedirection=kernel32.Wow64EnableWow64FsRedirection") +#pragma comment(linker, "/EXPORT:Wow64GetThreadContext=kernel32.Wow64GetThreadContext") +#pragma comment(linker, "/EXPORT:Wow64GetThreadSelectorEntry=kernel32.Wow64GetThreadSelectorEntry") +#pragma comment(linker, "/EXPORT:Wow64RevertWow64FsRedirection=kernel32.Wow64RevertWow64FsRedirection") +#pragma comment(linker, "/EXPORT:Wow64SetThreadContext=kernel32.Wow64SetThreadContext") +#pragma comment(linker, "/EXPORT:Wow64SuspendThread=kernel32.Wow64SuspendThread") +#pragma comment(linker, "/EXPORT:WriteConsoleA=kernel32.WriteConsoleA") +#pragma comment(linker, "/EXPORT:WriteConsoleInputA=kernel32.WriteConsoleInputA") +#pragma comment(linker, "/EXPORT:WriteConsoleInputVDMA=kernel32.WriteConsoleInputVDMA") +#pragma comment(linker, "/EXPORT:WriteConsoleInputVDMW=kernel32.WriteConsoleInputVDMW") +#pragma comment(linker, "/EXPORT:WriteConsoleInputW=kernel32.WriteConsoleInputW") +#pragma comment(linker, "/EXPORT:WriteConsoleOutputA=kernel32.WriteConsoleOutputA") +#pragma comment(linker, "/EXPORT:WriteConsoleOutputAttribute=kernel32.WriteConsoleOutputAttribute") +#pragma comment(linker, "/EXPORT:WriteConsoleOutputCharacterA=kernel32.WriteConsoleOutputCharacterA") +#pragma comment(linker, "/EXPORT:WriteConsoleOutputCharacterW=kernel32.WriteConsoleOutputCharacterW") +#pragma comment(linker, "/EXPORT:WriteConsoleOutputW=kernel32.WriteConsoleOutputW") +#pragma comment(linker, "/EXPORT:WriteConsoleW=kernel32.WriteConsoleW") +#pragma comment(linker, "/EXPORT:WriteFile=kernel32.WriteFile") +#pragma comment(linker, "/EXPORT:WriteFileEx=kernel32.WriteFileEx") +#pragma comment(linker, "/EXPORT:WriteFileGather=kernel32.WriteFileGather") +#pragma comment(linker, "/EXPORT:WritePrivateProfileSectionA=kernel32.WritePrivateProfileSectionA") +#pragma comment(linker, "/EXPORT:WritePrivateProfileSectionW=kernel32.WritePrivateProfileSectionW") +#pragma comment(linker, "/EXPORT:WritePrivateProfileStringA=kernel32.WritePrivateProfileStringA") +#pragma comment(linker, "/EXPORT:WritePrivateProfileStringW=kernel32.WritePrivateProfileStringW") +#pragma comment(linker, "/EXPORT:WritePrivateProfileStructA=kernel32.WritePrivateProfileStructA") +#pragma comment(linker, "/EXPORT:WritePrivateProfileStructW=kernel32.WritePrivateProfileStructW") +#pragma comment(linker, "/EXPORT:WriteProcessMemory=kernel32.WriteProcessMemory") +#pragma comment(linker, "/EXPORT:WriteProfileSectionA=kernel32.WriteProfileSectionA") +#pragma comment(linker, "/EXPORT:WriteProfileSectionW=kernel32.WriteProfileSectionW") +#pragma comment(linker, "/EXPORT:WriteProfileStringA=kernel32.WriteProfileStringA") +#pragma comment(linker, "/EXPORT:WriteProfileStringW=kernel32.WriteProfileStringW") +#pragma comment(linker, "/EXPORT:WriteTapemark=kernel32.WriteTapemark") +#pragma comment(linker, "/EXPORT:ZombifyActCtx=kernel32.ZombifyActCtx") +#pragma comment(linker, "/EXPORT:lstrcat=kernel32.lstrcat") +#pragma comment(linker, "/EXPORT:lstrcatA=kernel32.lstrcatA") +#pragma comment(linker, "/EXPORT:lstrcatW=kernel32.lstrcatW") +#pragma comment(linker, "/EXPORT:lstrcmp=kernel32.lstrcmp") +#pragma comment(linker, "/EXPORT:lstrcmpA=kernel32.lstrcmpA") +#pragma comment(linker, "/EXPORT:lstrcmpW=kernel32.lstrcmpW") +#pragma comment(linker, "/EXPORT:lstrcmpi=kernel32.lstrcmpi") +#pragma comment(linker, "/EXPORT:lstrcmpiA=kernel32.lstrcmpiA") +#pragma comment(linker, "/EXPORT:lstrcmpiW=kernel32.lstrcmpiW") +#pragma comment(linker, "/EXPORT:lstrcpy=kernel32.lstrcpy") +#pragma comment(linker, "/EXPORT:lstrcpyA=kernel32.lstrcpyA") +#pragma comment(linker, "/EXPORT:lstrcpyW=kernel32.lstrcpyW") +#pragma comment(linker, "/EXPORT:lstrcpyn=kernel32.lstrcpyn") +#pragma comment(linker, "/EXPORT:lstrcpynA=kernel32.lstrcpynA") +#pragma comment(linker, "/EXPORT:lstrcpynW=kernel32.lstrcpynW") +#pragma comment(linker, "/EXPORT:lstrlen=kernel32.lstrlen") +#pragma comment(linker, "/EXPORT:lstrlenA=kernel32.lstrlenA") +#pragma comment(linker, "/EXPORT:lstrlenW=kernel32.lstrlenW") + +#ifdef _M_X64 + + // + // Exports from KERNEL32.DLL which begin with an underscore. + // + + #pragma comment(linker, "/EXPORT:_hread=kernel32._hread") + #pragma comment(linker, "/EXPORT:_hwrite=kernel32._hwrite") + #pragma comment(linker, "/EXPORT:_lclose=kernel32._lclose") + #pragma comment(linker, "/EXPORT:_lcreat=kernel32._lcreat") + #pragma comment(linker, "/EXPORT:_llseek=kernel32._llseek") + #pragma comment(linker, "/EXPORT:_lopen=kernel32._lopen") + #pragma comment(linker, "/EXPORT:_lread=kernel32._lread") + #pragma comment(linker, "/EXPORT:_lwrite=kernel32._lwrite") + +#else + + // + // Exports which begin with an underscore must be written here with an extra + // underscore. Otherwise, the linker will remove the underscore and cause us + // to export the function with the wrong name. + // + + #pragma comment(linker, "/EXPORT:__hread=kernel32._hread") + #pragma comment(linker, "/EXPORT:__hwrite=kernel32._hwrite") + #pragma comment(linker, "/EXPORT:__lclose=kernel32._lclose") + #pragma comment(linker, "/EXPORT:__lcreat=kernel32._lcreat") + #pragma comment(linker, "/EXPORT:__llseek=kernel32._llseek") + #pragma comment(linker, "/EXPORT:__lopen=kernel32._lopen") + #pragma comment(linker, "/EXPORT:__lread=kernel32._lread") + #pragma comment(linker, "/EXPORT:__lwrite=kernel32._lwrite") + +#endif + +#ifdef _M_X64 + + // + // This section contains KERNEL32.DLL exports that are only present in the 64-bit version. + // + + #pragma comment(linker, "/EXPORT:CreateUmsCompletionList=kernel32.CreateUmsCompletionList") + #pragma comment(linker, "/EXPORT:CreateUmsThreadContext=kernel32.CreateUmsThreadContext") + #pragma comment(linker, "/EXPORT:DeleteUmsCompletionList=kernel32.DeleteUmsCompletionList") + #pragma comment(linker, "/EXPORT:DeleteUmsThreadContext=kernel32.DeleteUmsThreadContext") + #pragma comment(linker, "/EXPORT:DequeueUmsCompletionListItems=kernel32.DequeueUmsCompletionListItems") + #pragma comment(linker, "/EXPORT:EnterUmsSchedulingMode=kernel32.EnterUmsSchedulingMode") + #pragma comment(linker, "/EXPORT:ExecuteUmsThread=kernel32.ExecuteUmsThread") + #pragma comment(linker, "/EXPORT:GetCurrentUmsThread=kernel32.GetCurrentUmsThread") + #pragma comment(linker, "/EXPORT:GetNextUmsListItem=kernel32.GetNextUmsListItem") + #pragma comment(linker, "/EXPORT:GetUmsCompletionListEvent=kernel32.GetUmsCompletionListEvent") + #pragma comment(linker, "/EXPORT:GetUmsSystemThreadInformation=kernel32.GetUmsSystemThreadInformation") + #pragma comment(linker, "/EXPORT:QueryUmsThreadInformation=kernel32.QueryUmsThreadInformation") + #pragma comment(linker, "/EXPORT:RtlAddFunctionTable=kernel32.RtlAddFunctionTable") + #pragma comment(linker, "/EXPORT:RtlCompareMemory=kernel32.RtlCompareMemory") + #pragma comment(linker, "/EXPORT:RtlCopyMemory=kernel32.RtlCopyMemory") + #pragma comment(linker, "/EXPORT:RtlDeleteFunctionTable=kernel32.RtlDeleteFunctionTable") + #pragma comment(linker, "/EXPORT:RtlInstallFunctionTableCallback=kernel32.RtlInstallFunctionTableCallback") + #pragma comment(linker, "/EXPORT:RtlLookupFunctionEntry=kernel32.RtlLookupFunctionEntry") + #pragma comment(linker, "/EXPORT:RtlPcToFileHeader=kernel32.RtlPcToFileHeader") + #pragma comment(linker, "/EXPORT:RtlRaiseException=kernel32.RtlRaiseException") + #pragma comment(linker, "/EXPORT:RtlRestoreContext=kernel32.RtlRestoreContext") + #pragma comment(linker, "/EXPORT:RtlUnwindEx=kernel32.RtlUnwindEx") + #pragma comment(linker, "/EXPORT:RtlVirtualUnwind=kernel32.RtlVirtualUnwind") + #pragma comment(linker, "/EXPORT:SetUmsThreadInformation=kernel32.SetUmsThreadInformation") + #pragma comment(linker, "/EXPORT:UmsThreadYield=kernel32.UmsThreadYield") + #pragma comment(linker, "/EXPORT:__C_specific_handler=kernel32.__C_specific_handler") + #pragma comment(linker, "/EXPORT:__chkstk=kernel32.__chkstk") + #pragma comment(linker, "/EXPORT:__misaligned_access=kernel32.__misaligned_access") + #pragma comment(linker, "/EXPORT:_local_unwind=kernel32._local_unwind") + #pragma comment(linker, "/EXPORT:uaw_lstrcmpW=kernel32.uaw_lstrcmpW") + #pragma comment(linker, "/EXPORT:uaw_lstrcmpiW=kernel32.uaw_lstrcmpiW") + #pragma comment(linker, "/EXPORT:uaw_lstrlenW=kernel32.uaw_lstrlenW") + #pragma comment(linker, "/EXPORT:uaw_wcschr=kernel32.uaw_wcschr") + #pragma comment(linker, "/EXPORT:uaw_wcscpy=kernel32.uaw_wcscpy") + #pragma comment(linker, "/EXPORT:uaw_wcsicmp=kernel32.uaw_wcsicmp") + #pragma comment(linker, "/EXPORT:uaw_wcslen=kernel32.uaw_wcslen") + #pragma comment(linker, "/EXPORT:uaw_wcsrchr=kernel32.uaw_wcsrchr") + +#else + + // + // This section contains KERNEL32.DLL exports that are only present in the 32-bit version. + // + + #pragma comment(linker, "/EXPORT:CreateSocketHandle=kernel32.CreateSocketHandle") + #pragma comment(linker, "/EXPORT:GetHandleContext=kernel32.GetHandleContext") + #pragma comment(linker, "/EXPORT:InterlockedCompareExchange=kernel32.InterlockedCompareExchange") + #pragma comment(linker, "/EXPORT:InterlockedCompareExchange64=kernel32.InterlockedCompareExchange64") + #pragma comment(linker, "/EXPORT:InterlockedDecrement=kernel32.InterlockedDecrement") + #pragma comment(linker, "/EXPORT:InterlockedExchange=kernel32.InterlockedExchange") + #pragma comment(linker, "/EXPORT:InterlockedExchangeAdd=kernel32.InterlockedExchangeAdd") + #pragma comment(linker, "/EXPORT:InterlockedIncrement=kernel32.InterlockedIncrement") + #pragma comment(linker, "/EXPORT:SetHandleContext=kernel32.SetHandleContext") + +#endif + +// +// The following section contains the exports that are unique to KERNELBASE.DLL. +// All of these exports are present in both the 32-bit and 64-bit versions of the DLL. +// + +#pragma comment(linker, "/EXPORT:AccessCheck=kernelbase.AccessCheck") +#pragma comment(linker, "/EXPORT:AccessCheckAndAuditAlarmW=kernelbase.AccessCheckAndAuditAlarmW") +#pragma comment(linker, "/EXPORT:AccessCheckByType=kernelbase.AccessCheckByType") +#pragma comment(linker, "/EXPORT:AccessCheckByTypeAndAuditAlarmW=kernelbase.AccessCheckByTypeAndAuditAlarmW") +#pragma comment(linker, "/EXPORT:AccessCheckByTypeResultList=kernelbase.AccessCheckByTypeResultList") +#pragma comment(linker, "/EXPORT:AccessCheckByTypeResultListAndAuditAlarmByHandleW=kernelbase.AccessCheckByTypeResultListAndAuditAlarmByHandleW") +#pragma comment(linker, "/EXPORT:AccessCheckByTypeResultListAndAuditAlarmW=kernelbase.AccessCheckByTypeResultListAndAuditAlarmW") +#pragma comment(linker, "/EXPORT:AddAccessAllowedAce=kernelbase.AddAccessAllowedAce") +#pragma comment(linker, "/EXPORT:AddAccessAllowedAceEx=kernelbase.AddAccessAllowedAceEx") +#pragma comment(linker, "/EXPORT:AddAccessAllowedObjectAce=kernelbase.AddAccessAllowedObjectAce") +#pragma comment(linker, "/EXPORT:AddAccessDeniedAce=kernelbase.AddAccessDeniedAce") +#pragma comment(linker, "/EXPORT:AddAccessDeniedAceEx=kernelbase.AddAccessDeniedAceEx") +#pragma comment(linker, "/EXPORT:AddAccessDeniedObjectAce=kernelbase.AddAccessDeniedObjectAce") +#pragma comment(linker, "/EXPORT:AddAce=kernelbase.AddAce") +#pragma comment(linker, "/EXPORT:AddAuditAccessAce=kernelbase.AddAuditAccessAce") +#pragma comment(linker, "/EXPORT:AddAuditAccessAceEx=kernelbase.AddAuditAccessAceEx") +#pragma comment(linker, "/EXPORT:AddAuditAccessObjectAce=kernelbase.AddAuditAccessObjectAce") +#pragma comment(linker, "/EXPORT:AddMandatoryAce=kernelbase.AddMandatoryAce") +#pragma comment(linker, "/EXPORT:AdjustTokenGroups=kernelbase.AdjustTokenGroups") +#pragma comment(linker, "/EXPORT:AdjustTokenPrivileges=kernelbase.AdjustTokenPrivileges") +#pragma comment(linker, "/EXPORT:AllocateAndInitializeSid=kernelbase.AllocateAndInitializeSid") +#pragma comment(linker, "/EXPORT:AllocateLocallyUniqueId=kernelbase.AllocateLocallyUniqueId") +#pragma comment(linker, "/EXPORT:AreAllAccessesGranted=kernelbase.AreAllAccessesGranted") +#pragma comment(linker, "/EXPORT:AreAnyAccessesGranted=kernelbase.AreAnyAccessesGranted") +#pragma comment(linker, "/EXPORT:BaseDllFreeResourceId=kernelbase.BaseDllFreeResourceId") +#pragma comment(linker, "/EXPORT:BaseDllMapResourceIdW=kernelbase.BaseDllMapResourceIdW") +#pragma comment(linker, "/EXPORT:BaseGetProcessDllPath=kernelbase.BaseGetProcessDllPath") +#pragma comment(linker, "/EXPORT:BaseGetProcessExePath=kernelbase.BaseGetProcessExePath") +#pragma comment(linker, "/EXPORT:BaseInvalidateDllSearchPathCache=kernelbase.BaseInvalidateDllSearchPathCache") +#pragma comment(linker, "/EXPORT:BaseInvalidateProcessSearchPathCache=kernelbase.BaseInvalidateProcessSearchPathCache") +#pragma comment(linker, "/EXPORT:BaseReleaseProcessDllPath=kernelbase.BaseReleaseProcessDllPath") +#pragma comment(linker, "/EXPORT:BaseReleaseProcessExePath=kernelbase.BaseReleaseProcessExePath") +#pragma comment(linker, "/EXPORT:BemCopyReference=kernelbase.BemCopyReference") +#pragma comment(linker, "/EXPORT:BemCreateContractFrom=kernelbase.BemCreateContractFrom") +#pragma comment(linker, "/EXPORT:BemCreateReference=kernelbase.BemCreateReference") +#pragma comment(linker, "/EXPORT:BemFreeContract=kernelbase.BemFreeContract") +#pragma comment(linker, "/EXPORT:BemFreeReference=kernelbase.BemFreeReference") +#pragma comment(linker, "/EXPORT:CheckGroupPolicyEnabled=kernelbase.CheckGroupPolicyEnabled") +#pragma comment(linker, "/EXPORT:CheckTokenMembership=kernelbase.CheckTokenMembership") +#pragma comment(linker, "/EXPORT:ConvertToAutoInheritPrivateObjectSecurity=kernelbase.ConvertToAutoInheritPrivateObjectSecurity") +#pragma comment(linker, "/EXPORT:CopySid=kernelbase.CopySid") +#pragma comment(linker, "/EXPORT:CreatePrivateObjectSecurity=kernelbase.CreatePrivateObjectSecurity") +#pragma comment(linker, "/EXPORT:CreatePrivateObjectSecurityEx=kernelbase.CreatePrivateObjectSecurityEx") +#pragma comment(linker, "/EXPORT:CreatePrivateObjectSecurityWithMultipleInheritance=kernelbase.CreatePrivateObjectSecurityWithMultipleInheritance") +#pragma comment(linker, "/EXPORT:CreateRestrictedToken=kernelbase.CreateRestrictedToken") +#pragma comment(linker, "/EXPORT:CreateWellKnownSid=kernelbase.CreateWellKnownSid") +#pragma comment(linker, "/EXPORT:DeleteAce=kernelbase.DeleteAce") +#pragma comment(linker, "/EXPORT:DestroyPrivateObjectSecurity=kernelbase.DestroyPrivateObjectSecurity") +#pragma comment(linker, "/EXPORT:DuplicateToken=kernelbase.DuplicateToken") +#pragma comment(linker, "/EXPORT:DuplicateTokenEx=kernelbase.DuplicateTokenEx") +#pragma comment(linker, "/EXPORT:EqualDomainSid=kernelbase.EqualDomainSid") +#pragma comment(linker, "/EXPORT:EqualPrefixSid=kernelbase.EqualPrefixSid") +#pragma comment(linker, "/EXPORT:EqualSid=kernelbase.EqualSid") +#pragma comment(linker, "/EXPORT:FindFirstFreeAce=kernelbase.FindFirstFreeAce") +#pragma comment(linker, "/EXPORT:FreeSid=kernelbase.FreeSid") +#pragma comment(linker, "/EXPORT:GetAce=kernelbase.GetAce") +#pragma comment(linker, "/EXPORT:GetAclInformation=kernelbase.GetAclInformation") +#pragma comment(linker, "/EXPORT:GetCPFileNameFromRegistry=kernelbase.GetCPFileNameFromRegistry") +#pragma comment(linker, "/EXPORT:GetCPHashNode=kernelbase.GetCPHashNode") +#pragma comment(linker, "/EXPORT:GetCalendar=kernelbase.GetCalendar") +#pragma comment(linker, "/EXPORT:GetFallbackDisplayName=kernelbase.GetFallbackDisplayName") +#pragma comment(linker, "/EXPORT:GetFileSecurityW=kernelbase.GetFileSecurityW") +#pragma comment(linker, "/EXPORT:GetKernelObjectSecurity=kernelbase.GetKernelObjectSecurity") +#pragma comment(linker, "/EXPORT:GetLengthSid=kernelbase.GetLengthSid") +#pragma comment(linker, "/EXPORT:GetLocaleInfoHelper=kernelbase.GetLocaleInfoHelper") +#pragma comment(linker, "/EXPORT:GetNamedLocaleHashNode=kernelbase.GetNamedLocaleHashNode") +#pragma comment(linker, "/EXPORT:GetPrivateObjectSecurity=kernelbase.GetPrivateObjectSecurity") +#pragma comment(linker, "/EXPORT:GetPtrCalData=kernelbase.GetPtrCalData") +#pragma comment(linker, "/EXPORT:GetPtrCalDataArray=kernelbase.GetPtrCalDataArray") +#pragma comment(linker, "/EXPORT:GetSecurityDescriptorControl=kernelbase.GetSecurityDescriptorControl") +#pragma comment(linker, "/EXPORT:GetSecurityDescriptorDacl=kernelbase.GetSecurityDescriptorDacl") +#pragma comment(linker, "/EXPORT:GetSecurityDescriptorGroup=kernelbase.GetSecurityDescriptorGroup") +#pragma comment(linker, "/EXPORT:GetSecurityDescriptorLength=kernelbase.GetSecurityDescriptorLength") +#pragma comment(linker, "/EXPORT:GetSecurityDescriptorOwner=kernelbase.GetSecurityDescriptorOwner") +#pragma comment(linker, "/EXPORT:GetSecurityDescriptorRMControl=kernelbase.GetSecurityDescriptorRMControl") +#pragma comment(linker, "/EXPORT:GetSecurityDescriptorSacl=kernelbase.GetSecurityDescriptorSacl") +#pragma comment(linker, "/EXPORT:GetSidIdentifierAuthority=kernelbase.GetSidIdentifierAuthority") +#pragma comment(linker, "/EXPORT:GetSidLengthRequired=kernelbase.GetSidLengthRequired") +#pragma comment(linker, "/EXPORT:GetSidSubAuthority=kernelbase.GetSidSubAuthority") +#pragma comment(linker, "/EXPORT:GetSidSubAuthorityCount=kernelbase.GetSidSubAuthorityCount") +#pragma comment(linker, "/EXPORT:GetStringTableEntry=kernelbase.GetStringTableEntry") +#pragma comment(linker, "/EXPORT:GetTokenInformation=kernelbase.GetTokenInformation") +#pragma comment(linker, "/EXPORT:GetUserInfo=kernelbase.GetUserInfo") +#pragma comment(linker, "/EXPORT:GetUserInfoWord=kernelbase.GetUserInfoWord") +#pragma comment(linker, "/EXPORT:GetWindowsAccountDomainSid=kernelbase.GetWindowsAccountDomainSid") +#pragma comment(linker, "/EXPORT:ImpersonateAnonymousToken=kernelbase.ImpersonateAnonymousToken") +#pragma comment(linker, "/EXPORT:ImpersonateLoggedOnUser=kernelbase.ImpersonateLoggedOnUser") +#pragma comment(linker, "/EXPORT:ImpersonateNamedPipeClient=kernelbase.ImpersonateNamedPipeClient") +#pragma comment(linker, "/EXPORT:ImpersonateSelf=kernelbase.ImpersonateSelf") +#pragma comment(linker, "/EXPORT:InitializeAcl=kernelbase.InitializeAcl") +#pragma comment(linker, "/EXPORT:InitializeSecurityDescriptor=kernelbase.InitializeSecurityDescriptor") +#pragma comment(linker, "/EXPORT:InitializeSid=kernelbase.InitializeSid") +#pragma comment(linker, "/EXPORT:InternalLcidToName=kernelbase.InternalLcidToName") +#pragma comment(linker, "/EXPORT:Internal_EnumCalendarInfo=kernelbase.Internal_EnumCalendarInfo") +#pragma comment(linker, "/EXPORT:Internal_EnumDateFormats=kernelbase.Internal_EnumDateFormats") +#pragma comment(linker, "/EXPORT:Internal_EnumLanguageGroupLocales=kernelbase.Internal_EnumLanguageGroupLocales") +#pragma comment(linker, "/EXPORT:Internal_EnumSystemCodePages=kernelbase.Internal_EnumSystemCodePages") +#pragma comment(linker, "/EXPORT:Internal_EnumSystemLanguageGroups=kernelbase.Internal_EnumSystemLanguageGroups") +#pragma comment(linker, "/EXPORT:Internal_EnumSystemLocales=kernelbase.Internal_EnumSystemLocales") +#pragma comment(linker, "/EXPORT:Internal_EnumTimeFormats=kernelbase.Internal_EnumTimeFormats") +#pragma comment(linker, "/EXPORT:Internal_EnumUILanguages=kernelbase.Internal_EnumUILanguages") +#pragma comment(linker, "/EXPORT:InvalidateTzSpecificCache=kernelbase.InvalidateTzSpecificCache") +#pragma comment(linker, "/EXPORT:IsTokenRestricted=kernelbase.IsTokenRestricted") +#pragma comment(linker, "/EXPORT:IsValidAcl=kernelbase.IsValidAcl") +#pragma comment(linker, "/EXPORT:IsValidRelativeSecurityDescriptor=kernelbase.IsValidRelativeSecurityDescriptor") +#pragma comment(linker, "/EXPORT:IsValidSecurityDescriptor=kernelbase.IsValidSecurityDescriptor") +#pragma comment(linker, "/EXPORT:IsValidSid=kernelbase.IsValidSid") +#pragma comment(linker, "/EXPORT:IsWellKnownSid=kernelbase.IsWellKnownSid") +#pragma comment(linker, "/EXPORT:KernelBaseGetGlobalData=kernelbase.KernelBaseGetGlobalData") +#pragma comment(linker, "/EXPORT:LoadStringA=kernelbase.LoadStringA") +#pragma comment(linker, "/EXPORT:LoadStringByReference=kernelbase.LoadStringByReference") +#pragma comment(linker, "/EXPORT:LoadStringW=kernelbase.LoadStringW") +#pragma comment(linker, "/EXPORT:MakeAbsoluteSD=kernelbase.MakeAbsoluteSD") +#pragma comment(linker, "/EXPORT:MakeAbsoluteSD2=kernelbase.MakeAbsoluteSD2") +#pragma comment(linker, "/EXPORT:MakeSelfRelativeSD=kernelbase.MakeSelfRelativeSD") +#pragma comment(linker, "/EXPORT:MapGenericMask=kernelbase.MapGenericMask") +#pragma comment(linker, "/EXPORT:NlsDispatchAnsiEnumProc=kernelbase.NlsDispatchAnsiEnumProc") +#pragma comment(linker, "/EXPORT:NlsGetACPFromLocale=kernelbase.NlsGetACPFromLocale") +#pragma comment(linker, "/EXPORT:NlsIsUserDefaultLocale=kernelbase.NlsIsUserDefaultLocale") +#pragma comment(linker, "/EXPORT:NlsValidateLocale=kernelbase.NlsValidateLocale") +#pragma comment(linker, "/EXPORT:NotifyRedirectedStringChange=kernelbase.NotifyRedirectedStringChange") +#pragma comment(linker, "/EXPORT:ObjectCloseAuditAlarmW=kernelbase.ObjectCloseAuditAlarmW") +#pragma comment(linker, "/EXPORT:ObjectDeleteAuditAlarmW=kernelbase.ObjectDeleteAuditAlarmW") +#pragma comment(linker, "/EXPORT:ObjectOpenAuditAlarmW=kernelbase.ObjectOpenAuditAlarmW") +#pragma comment(linker, "/EXPORT:ObjectPrivilegeAuditAlarmW=kernelbase.ObjectPrivilegeAuditAlarmW") +#pragma comment(linker, "/EXPORT:OpenRegKey=kernelbase.OpenRegKey") +#pragma comment(linker, "/EXPORT:PrivilegeCheck=kernelbase.PrivilegeCheck") +#pragma comment(linker, "/EXPORT:PrivilegedServiceAuditAlarmW=kernelbase.PrivilegedServiceAuditAlarmW") +#pragma comment(linker, "/EXPORT:QuerySecurityAccessMask=kernelbase.QuerySecurityAccessMask") +#pragma comment(linker, "/EXPORT:RevertToSelf=kernelbase.RevertToSelf") +#pragma comment(linker, "/EXPORT:SetAclInformation=kernelbase.SetAclInformation") +#pragma comment(linker, "/EXPORT:SetFileSecurityW=kernelbase.SetFileSecurityW") +#pragma comment(linker, "/EXPORT:SetKernelObjectSecurity=kernelbase.SetKernelObjectSecurity") +#pragma comment(linker, "/EXPORT:SetPrivateObjectSecurity=kernelbase.SetPrivateObjectSecurity") +#pragma comment(linker, "/EXPORT:SetPrivateObjectSecurityEx=kernelbase.SetPrivateObjectSecurityEx") +#pragma comment(linker, "/EXPORT:SetSecurityAccessMask=kernelbase.SetSecurityAccessMask") +#pragma comment(linker, "/EXPORT:SetSecurityDescriptorControl=kernelbase.SetSecurityDescriptorControl") +#pragma comment(linker, "/EXPORT:SetSecurityDescriptorDacl=kernelbase.SetSecurityDescriptorDacl") +#pragma comment(linker, "/EXPORT:SetSecurityDescriptorGroup=kernelbase.SetSecurityDescriptorGroup") +#pragma comment(linker, "/EXPORT:SetSecurityDescriptorOwner=kernelbase.SetSecurityDescriptorOwner") +#pragma comment(linker, "/EXPORT:SetSecurityDescriptorRMControl=kernelbase.SetSecurityDescriptorRMControl") +#pragma comment(linker, "/EXPORT:SetSecurityDescriptorSacl=kernelbase.SetSecurityDescriptorSacl") +#pragma comment(linker, "/EXPORT:SetTokenInformation=kernelbase.SetTokenInformation") +#pragma comment(linker, "/EXPORT:SpecialMBToWC=kernelbase.SpecialMBToWC") + +// +// The following section contains functions that moved to KERNEL32.DLL or +// KERNELBASE.DLL in Windows 10, but are actually in another DLL on +// Windows 7. +// + +#pragma comment(linker, "/EXPORT:EventActivityIdControl=kxadvapi.EventActivityIdControl") +#pragma comment(linker, "/EXPORT:EventEnabled=kxadvapi.EventEnabled") +#pragma comment(linker, "/EXPORT:EventProviderEnabled=kxadvapi.EventProviderEnabled") +#pragma comment(linker, "/EXPORT:EventRegister=kxadvapi.EventRegister") +#pragma comment(linker, "/EXPORT:EventSetInformation=kxadvapi.EventSetInformation") +#pragma comment(linker, "/EXPORT:EventUnregister=kxadvapi.EventUnregister") +#pragma comment(linker, "/EXPORT:EventWrite=kxadvapi.EventWrite") +#pragma comment(linker, "/EXPORT:EventWriteEx=kxadvapi.EventWriteEx") +#pragma comment(linker, "/EXPORT:EventWriteString=kxadvapi.EventWriteString") +#pragma comment(linker, "/EXPORT:EventWriteTransfer=kxadvapi.EventWriteTransfer") + +// +// The following section contains exports from CFGMGR32.DLL. +// + +#pragma comment(linker, "/EXPORT:CMP_GetBlockedDriverInfo=cfgmgr32.CMP_GetBlockedDriverInfo") +#pragma comment(linker, "/EXPORT:CMP_GetServerSideDeviceInstallFlags=cfgmgr32.CMP_GetServerSideDeviceInstallFlags") +#pragma comment(linker, "/EXPORT:CMP_Init_Detection=cfgmgr32.CMP_Init_Detection") +#pragma comment(linker, "/EXPORT:CMP_RegisterNotification=cfgmgr32.CMP_RegisterNotification") +#pragma comment(linker, "/EXPORT:CMP_Report_LogOn=cfgmgr32.CMP_Report_LogOn") +#pragma comment(linker, "/EXPORT:CMP_UnregisterNotification=cfgmgr32.CMP_UnregisterNotification") +#pragma comment(linker, "/EXPORT:CMP_WaitNoPendingInstallEvents=cfgmgr32.CMP_WaitNoPendingInstallEvents") +#pragma comment(linker, "/EXPORT:CMP_WaitServicesAvailable=cfgmgr32.CMP_WaitServicesAvailable") +#pragma comment(linker, "/EXPORT:CM_Add_Driver_PackageW=cfgmgr32.CM_Add_Driver_PackageW") +#pragma comment(linker, "/EXPORT:CM_Add_Driver_Package_ExW=cfgmgr32.CM_Add_Driver_Package_ExW") +#pragma comment(linker, "/EXPORT:CM_Add_Empty_Log_Conf=cfgmgr32.CM_Add_Empty_Log_Conf") +#pragma comment(linker, "/EXPORT:CM_Add_Empty_Log_Conf_Ex=cfgmgr32.CM_Add_Empty_Log_Conf_Ex") +#pragma comment(linker, "/EXPORT:CM_Add_IDA=cfgmgr32.CM_Add_IDA") +#pragma comment(linker, "/EXPORT:CM_Add_IDW=cfgmgr32.CM_Add_IDW") +#pragma comment(linker, "/EXPORT:CM_Add_ID_ExA=cfgmgr32.CM_Add_ID_ExA") +#pragma comment(linker, "/EXPORT:CM_Add_ID_ExW=cfgmgr32.CM_Add_ID_ExW") +#pragma comment(linker, "/EXPORT:CM_Add_Range=cfgmgr32.CM_Add_Range") +#pragma comment(linker, "/EXPORT:CM_Add_Res_Des=cfgmgr32.CM_Add_Res_Des") +#pragma comment(linker, "/EXPORT:CM_Add_Res_Des_Ex=cfgmgr32.CM_Add_Res_Des_Ex") +#pragma comment(linker, "/EXPORT:CM_Apply_PowerScheme=cfgmgr32.CM_Apply_PowerScheme") +#pragma comment(linker, "/EXPORT:CM_Connect_MachineA=cfgmgr32.CM_Connect_MachineA") +#pragma comment(linker, "/EXPORT:CM_Connect_MachineW=cfgmgr32.CM_Connect_MachineW") +#pragma comment(linker, "/EXPORT:CM_Create_DevNodeA=cfgmgr32.CM_Create_DevNodeA") +#pragma comment(linker, "/EXPORT:CM_Create_DevNodeW=cfgmgr32.CM_Create_DevNodeW") +#pragma comment(linker, "/EXPORT:CM_Create_DevNode_ExA=cfgmgr32.CM_Create_DevNode_ExA") +#pragma comment(linker, "/EXPORT:CM_Create_DevNode_ExW=cfgmgr32.CM_Create_DevNode_ExW") +#pragma comment(linker, "/EXPORT:CM_Create_Range_List=cfgmgr32.CM_Create_Range_List") +#pragma comment(linker, "/EXPORT:CM_Delete_Class_Key=cfgmgr32.CM_Delete_Class_Key") +#pragma comment(linker, "/EXPORT:CM_Delete_Class_Key_Ex=cfgmgr32.CM_Delete_Class_Key_Ex") +#pragma comment(linker, "/EXPORT:CM_Delete_DevNode_Key=cfgmgr32.CM_Delete_DevNode_Key") +#pragma comment(linker, "/EXPORT:CM_Delete_DevNode_Key_Ex=cfgmgr32.CM_Delete_DevNode_Key_Ex") +#pragma comment(linker, "/EXPORT:CM_Delete_Device_Interface_KeyA=cfgmgr32.CM_Delete_Device_Interface_KeyA") +#pragma comment(linker, "/EXPORT:CM_Delete_Device_Interface_KeyW=cfgmgr32.CM_Delete_Device_Interface_KeyW") +#pragma comment(linker, "/EXPORT:CM_Delete_Device_Interface_Key_ExA=cfgmgr32.CM_Delete_Device_Interface_Key_ExA") +#pragma comment(linker, "/EXPORT:CM_Delete_Device_Interface_Key_ExW=cfgmgr32.CM_Delete_Device_Interface_Key_ExW") +#pragma comment(linker, "/EXPORT:CM_Delete_Driver_PackageW=cfgmgr32.CM_Delete_Driver_PackageW") +#pragma comment(linker, "/EXPORT:CM_Delete_Driver_Package_ExW=cfgmgr32.CM_Delete_Driver_Package_ExW") +#pragma comment(linker, "/EXPORT:CM_Delete_PowerScheme=cfgmgr32.CM_Delete_PowerScheme") +#pragma comment(linker, "/EXPORT:CM_Delete_Range=cfgmgr32.CM_Delete_Range") +#pragma comment(linker, "/EXPORT:CM_Detect_Resource_Conflict=cfgmgr32.CM_Detect_Resource_Conflict") +#pragma comment(linker, "/EXPORT:CM_Detect_Resource_Conflict_Ex=cfgmgr32.CM_Detect_Resource_Conflict_Ex") +#pragma comment(linker, "/EXPORT:CM_Disable_DevNode=cfgmgr32.CM_Disable_DevNode") +#pragma comment(linker, "/EXPORT:CM_Disable_DevNode_Ex=cfgmgr32.CM_Disable_DevNode_Ex") +#pragma comment(linker, "/EXPORT:CM_Disconnect_Machine=cfgmgr32.CM_Disconnect_Machine") +#pragma comment(linker, "/EXPORT:CM_Dup_Range_List=cfgmgr32.CM_Dup_Range_List") +#pragma comment(linker, "/EXPORT:CM_Duplicate_PowerScheme=cfgmgr32.CM_Duplicate_PowerScheme") +#pragma comment(linker, "/EXPORT:CM_Enable_DevNode=cfgmgr32.CM_Enable_DevNode") +#pragma comment(linker, "/EXPORT:CM_Enable_DevNode_Ex=cfgmgr32.CM_Enable_DevNode_Ex") +#pragma comment(linker, "/EXPORT:CM_Enumerate_Classes=cfgmgr32.CM_Enumerate_Classes") +#pragma comment(linker, "/EXPORT:CM_Enumerate_Classes_Ex=cfgmgr32.CM_Enumerate_Classes_Ex") +#pragma comment(linker, "/EXPORT:CM_Enumerate_EnumeratorsA=cfgmgr32.CM_Enumerate_EnumeratorsA") +#pragma comment(linker, "/EXPORT:CM_Enumerate_EnumeratorsW=cfgmgr32.CM_Enumerate_EnumeratorsW") +#pragma comment(linker, "/EXPORT:CM_Enumerate_Enumerators_ExA=cfgmgr32.CM_Enumerate_Enumerators_ExA") +#pragma comment(linker, "/EXPORT:CM_Enumerate_Enumerators_ExW=cfgmgr32.CM_Enumerate_Enumerators_ExW") +#pragma comment(linker, "/EXPORT:CM_Find_Range=cfgmgr32.CM_Find_Range") +#pragma comment(linker, "/EXPORT:CM_First_Range=cfgmgr32.CM_First_Range") +#pragma comment(linker, "/EXPORT:CM_Free_Log_Conf=cfgmgr32.CM_Free_Log_Conf") +#pragma comment(linker, "/EXPORT:CM_Free_Log_Conf_Ex=cfgmgr32.CM_Free_Log_Conf_Ex") +#pragma comment(linker, "/EXPORT:CM_Free_Log_Conf_Handle=cfgmgr32.CM_Free_Log_Conf_Handle") +#pragma comment(linker, "/EXPORT:CM_Free_Range_List=cfgmgr32.CM_Free_Range_List") +#pragma comment(linker, "/EXPORT:CM_Free_Res_Des=cfgmgr32.CM_Free_Res_Des") +#pragma comment(linker, "/EXPORT:CM_Free_Res_Des_Ex=cfgmgr32.CM_Free_Res_Des_Ex") +#pragma comment(linker, "/EXPORT:CM_Free_Res_Des_Handle=cfgmgr32.CM_Free_Res_Des_Handle") +#pragma comment(linker, "/EXPORT:CM_Free_Resource_Conflict_Handle=cfgmgr32.CM_Free_Resource_Conflict_Handle") +#pragma comment(linker, "/EXPORT:CM_Get_Child=cfgmgr32.CM_Get_Child") +#pragma comment(linker, "/EXPORT:CM_Get_Child_Ex=cfgmgr32.CM_Get_Child_Ex") +#pragma comment(linker, "/EXPORT:CM_Get_Class_Key_NameA=cfgmgr32.CM_Get_Class_Key_NameA") +#pragma comment(linker, "/EXPORT:CM_Get_Class_Key_NameW=cfgmgr32.CM_Get_Class_Key_NameW") +#pragma comment(linker, "/EXPORT:CM_Get_Class_Key_Name_ExA=cfgmgr32.CM_Get_Class_Key_Name_ExA") +#pragma comment(linker, "/EXPORT:CM_Get_Class_Key_Name_ExW=cfgmgr32.CM_Get_Class_Key_Name_ExW") +#pragma comment(linker, "/EXPORT:CM_Get_Class_NameA=cfgmgr32.CM_Get_Class_NameA") +#pragma comment(linker, "/EXPORT:CM_Get_Class_NameW=cfgmgr32.CM_Get_Class_NameW") +#pragma comment(linker, "/EXPORT:CM_Get_Class_Name_ExA=cfgmgr32.CM_Get_Class_Name_ExA") +#pragma comment(linker, "/EXPORT:CM_Get_Class_Name_ExW=cfgmgr32.CM_Get_Class_Name_ExW") +#pragma comment(linker, "/EXPORT:CM_Get_Class_PropertyW=cfgmgr32.CM_Get_Class_PropertyW") +#pragma comment(linker, "/EXPORT:CM_Get_Class_Property_ExW=cfgmgr32.CM_Get_Class_Property_ExW") +#pragma comment(linker, "/EXPORT:CM_Get_Class_Property_Keys=cfgmgr32.CM_Get_Class_Property_Keys") +#pragma comment(linker, "/EXPORT:CM_Get_Class_Property_Keys_Ex=cfgmgr32.CM_Get_Class_Property_Keys_Ex") +#pragma comment(linker, "/EXPORT:CM_Get_Class_Registry_PropertyA=cfgmgr32.CM_Get_Class_Registry_PropertyA") +#pragma comment(linker, "/EXPORT:CM_Get_Class_Registry_PropertyW=cfgmgr32.CM_Get_Class_Registry_PropertyW") +#pragma comment(linker, "/EXPORT:CM_Get_Depth=cfgmgr32.CM_Get_Depth") +#pragma comment(linker, "/EXPORT:CM_Get_Depth_Ex=cfgmgr32.CM_Get_Depth_Ex") +#pragma comment(linker, "/EXPORT:CM_Get_DevNode_Custom_PropertyA=cfgmgr32.CM_Get_DevNode_Custom_PropertyA") +#pragma comment(linker, "/EXPORT:CM_Get_DevNode_Custom_PropertyW=cfgmgr32.CM_Get_DevNode_Custom_PropertyW") +#pragma comment(linker, "/EXPORT:CM_Get_DevNode_Custom_Property_ExA=cfgmgr32.CM_Get_DevNode_Custom_Property_ExA") +#pragma comment(linker, "/EXPORT:CM_Get_DevNode_Custom_Property_ExW=cfgmgr32.CM_Get_DevNode_Custom_Property_ExW") +#pragma comment(linker, "/EXPORT:CM_Get_DevNode_PropertyW=cfgmgr32.CM_Get_DevNode_PropertyW") +#pragma comment(linker, "/EXPORT:CM_Get_DevNode_Property_ExW=cfgmgr32.CM_Get_DevNode_Property_ExW") +#pragma comment(linker, "/EXPORT:CM_Get_DevNode_Property_Keys=cfgmgr32.CM_Get_DevNode_Property_Keys") +#pragma comment(linker, "/EXPORT:CM_Get_DevNode_Property_Keys_Ex=cfgmgr32.CM_Get_DevNode_Property_Keys_Ex") +#pragma comment(linker, "/EXPORT:CM_Get_DevNode_Registry_PropertyA=cfgmgr32.CM_Get_DevNode_Registry_PropertyA") +#pragma comment(linker, "/EXPORT:CM_Get_DevNode_Registry_PropertyW=cfgmgr32.CM_Get_DevNode_Registry_PropertyW") +#pragma comment(linker, "/EXPORT:CM_Get_DevNode_Registry_Property_ExA=cfgmgr32.CM_Get_DevNode_Registry_Property_ExA") +#pragma comment(linker, "/EXPORT:CM_Get_DevNode_Registry_Property_ExW=cfgmgr32.CM_Get_DevNode_Registry_Property_ExW") +#pragma comment(linker, "/EXPORT:CM_Get_DevNode_Status=cfgmgr32.CM_Get_DevNode_Status") +#pragma comment(linker, "/EXPORT:CM_Get_DevNode_Status_Ex=cfgmgr32.CM_Get_DevNode_Status_Ex") +#pragma comment(linker, "/EXPORT:CM_Get_Device_IDA=cfgmgr32.CM_Get_Device_IDA") +#pragma comment(linker, "/EXPORT:CM_Get_Device_IDW=cfgmgr32.CM_Get_Device_IDW") +#pragma comment(linker, "/EXPORT:CM_Get_Device_ID_ExA=cfgmgr32.CM_Get_Device_ID_ExA") +#pragma comment(linker, "/EXPORT:CM_Get_Device_ID_ExW=cfgmgr32.CM_Get_Device_ID_ExW") +#pragma comment(linker, "/EXPORT:CM_Get_Device_ID_ListA=cfgmgr32.CM_Get_Device_ID_ListA") +#pragma comment(linker, "/EXPORT:CM_Get_Device_ID_ListW=cfgmgr32.CM_Get_Device_ID_ListW") +#pragma comment(linker, "/EXPORT:CM_Get_Device_ID_List_ExA=cfgmgr32.CM_Get_Device_ID_List_ExA") +#pragma comment(linker, "/EXPORT:CM_Get_Device_ID_List_ExW=cfgmgr32.CM_Get_Device_ID_List_ExW") +#pragma comment(linker, "/EXPORT:CM_Get_Device_ID_List_SizeA=cfgmgr32.CM_Get_Device_ID_List_SizeA") +#pragma comment(linker, "/EXPORT:CM_Get_Device_ID_List_SizeW=cfgmgr32.CM_Get_Device_ID_List_SizeW") +#pragma comment(linker, "/EXPORT:CM_Get_Device_ID_List_Size_ExA=cfgmgr32.CM_Get_Device_ID_List_Size_ExA") +#pragma comment(linker, "/EXPORT:CM_Get_Device_ID_List_Size_ExW=cfgmgr32.CM_Get_Device_ID_List_Size_ExW") +#pragma comment(linker, "/EXPORT:CM_Get_Device_ID_Size=cfgmgr32.CM_Get_Device_ID_Size") +#pragma comment(linker, "/EXPORT:CM_Get_Device_ID_Size_Ex=cfgmgr32.CM_Get_Device_ID_Size_Ex") +#pragma comment(linker, "/EXPORT:CM_Get_Device_Interface_AliasA=cfgmgr32.CM_Get_Device_Interface_AliasA") +#pragma comment(linker, "/EXPORT:CM_Get_Device_Interface_AliasW=cfgmgr32.CM_Get_Device_Interface_AliasW") +#pragma comment(linker, "/EXPORT:CM_Get_Device_Interface_Alias_ExA=cfgmgr32.CM_Get_Device_Interface_Alias_ExA") +#pragma comment(linker, "/EXPORT:CM_Get_Device_Interface_Alias_ExW=cfgmgr32.CM_Get_Device_Interface_Alias_ExW") +#pragma comment(linker, "/EXPORT:CM_Get_Device_Interface_ListA=cfgmgr32.CM_Get_Device_Interface_ListA") +#pragma comment(linker, "/EXPORT:CM_Get_Device_Interface_ListW=cfgmgr32.CM_Get_Device_Interface_ListW") +#pragma comment(linker, "/EXPORT:CM_Get_Device_Interface_List_ExA=cfgmgr32.CM_Get_Device_Interface_List_ExA") +#pragma comment(linker, "/EXPORT:CM_Get_Device_Interface_List_ExW=cfgmgr32.CM_Get_Device_Interface_List_ExW") +#pragma comment(linker, "/EXPORT:CM_Get_Device_Interface_List_SizeA=cfgmgr32.CM_Get_Device_Interface_List_SizeA") +#pragma comment(linker, "/EXPORT:CM_Get_Device_Interface_List_SizeW=cfgmgr32.CM_Get_Device_Interface_List_SizeW") +#pragma comment(linker, "/EXPORT:CM_Get_Device_Interface_List_Size_ExA=cfgmgr32.CM_Get_Device_Interface_List_Size_ExA") +#pragma comment(linker, "/EXPORT:CM_Get_Device_Interface_List_Size_ExW=cfgmgr32.CM_Get_Device_Interface_List_Size_ExW") +#pragma comment(linker, "/EXPORT:CM_Get_Device_Interface_PropertyW=cfgmgr32.CM_Get_Device_Interface_PropertyW") +#pragma comment(linker, "/EXPORT:CM_Get_Device_Interface_Property_ExW=cfgmgr32.CM_Get_Device_Interface_Property_ExW") +#pragma comment(linker, "/EXPORT:CM_Get_Device_Interface_Property_KeysW=cfgmgr32.CM_Get_Device_Interface_Property_KeysW") +#pragma comment(linker, "/EXPORT:CM_Get_Device_Interface_Property_Keys_ExW=cfgmgr32.CM_Get_Device_Interface_Property_Keys_ExW") +#pragma comment(linker, "/EXPORT:CM_Get_First_Log_Conf=cfgmgr32.CM_Get_First_Log_Conf") +#pragma comment(linker, "/EXPORT:CM_Get_First_Log_Conf_Ex=cfgmgr32.CM_Get_First_Log_Conf_Ex") +#pragma comment(linker, "/EXPORT:CM_Get_Global_State=cfgmgr32.CM_Get_Global_State") +#pragma comment(linker, "/EXPORT:CM_Get_Global_State_Ex=cfgmgr32.CM_Get_Global_State_Ex") +#pragma comment(linker, "/EXPORT:CM_Get_HW_Prof_FlagsA=cfgmgr32.CM_Get_HW_Prof_FlagsA") +#pragma comment(linker, "/EXPORT:CM_Get_HW_Prof_FlagsW=cfgmgr32.CM_Get_HW_Prof_FlagsW") +#pragma comment(linker, "/EXPORT:CM_Get_HW_Prof_Flags_ExA=cfgmgr32.CM_Get_HW_Prof_Flags_ExA") +#pragma comment(linker, "/EXPORT:CM_Get_HW_Prof_Flags_ExW=cfgmgr32.CM_Get_HW_Prof_Flags_ExW") +#pragma comment(linker, "/EXPORT:CM_Get_Hardware_Profile_InfoA=cfgmgr32.CM_Get_Hardware_Profile_InfoA") +#pragma comment(linker, "/EXPORT:CM_Get_Hardware_Profile_InfoW=cfgmgr32.CM_Get_Hardware_Profile_InfoW") +#pragma comment(linker, "/EXPORT:CM_Get_Hardware_Profile_Info_ExA=cfgmgr32.CM_Get_Hardware_Profile_Info_ExA") +#pragma comment(linker, "/EXPORT:CM_Get_Hardware_Profile_Info_ExW=cfgmgr32.CM_Get_Hardware_Profile_Info_ExW") +#pragma comment(linker, "/EXPORT:CM_Get_Log_Conf_Priority=cfgmgr32.CM_Get_Log_Conf_Priority") +#pragma comment(linker, "/EXPORT:CM_Get_Log_Conf_Priority_Ex=cfgmgr32.CM_Get_Log_Conf_Priority_Ex") +#pragma comment(linker, "/EXPORT:CM_Get_Next_Log_Conf=cfgmgr32.CM_Get_Next_Log_Conf") +#pragma comment(linker, "/EXPORT:CM_Get_Next_Log_Conf_Ex=cfgmgr32.CM_Get_Next_Log_Conf_Ex") +#pragma comment(linker, "/EXPORT:CM_Get_Next_Res_Des=cfgmgr32.CM_Get_Next_Res_Des") +#pragma comment(linker, "/EXPORT:CM_Get_Next_Res_Des_Ex=cfgmgr32.CM_Get_Next_Res_Des_Ex") +#pragma comment(linker, "/EXPORT:CM_Get_Parent=cfgmgr32.CM_Get_Parent") +#pragma comment(linker, "/EXPORT:CM_Get_Parent_Ex=cfgmgr32.CM_Get_Parent_Ex") +#pragma comment(linker, "/EXPORT:CM_Get_Res_Des_Data=cfgmgr32.CM_Get_Res_Des_Data") +#pragma comment(linker, "/EXPORT:CM_Get_Res_Des_Data_Ex=cfgmgr32.CM_Get_Res_Des_Data_Ex") +#pragma comment(linker, "/EXPORT:CM_Get_Res_Des_Data_Size=cfgmgr32.CM_Get_Res_Des_Data_Size") +#pragma comment(linker, "/EXPORT:CM_Get_Res_Des_Data_Size_Ex=cfgmgr32.CM_Get_Res_Des_Data_Size_Ex") +#pragma comment(linker, "/EXPORT:CM_Get_Resource_Conflict_Count=cfgmgr32.CM_Get_Resource_Conflict_Count") +#pragma comment(linker, "/EXPORT:CM_Get_Resource_Conflict_DetailsA=cfgmgr32.CM_Get_Resource_Conflict_DetailsA") +#pragma comment(linker, "/EXPORT:CM_Get_Resource_Conflict_DetailsW=cfgmgr32.CM_Get_Resource_Conflict_DetailsW") +#pragma comment(linker, "/EXPORT:CM_Get_Sibling=cfgmgr32.CM_Get_Sibling") +#pragma comment(linker, "/EXPORT:CM_Get_Sibling_Ex=cfgmgr32.CM_Get_Sibling_Ex") +#pragma comment(linker, "/EXPORT:CM_Get_Version=cfgmgr32.CM_Get_Version") +#pragma comment(linker, "/EXPORT:CM_Get_Version_Ex=cfgmgr32.CM_Get_Version_Ex") +#pragma comment(linker, "/EXPORT:CM_Import_PowerScheme=cfgmgr32.CM_Import_PowerScheme") +#pragma comment(linker, "/EXPORT:CM_Install_DevNodeW=cfgmgr32.CM_Install_DevNodeW") +#pragma comment(linker, "/EXPORT:CM_Install_DevNode_ExW=cfgmgr32.CM_Install_DevNode_ExW") +#pragma comment(linker, "/EXPORT:CM_Intersect_Range_List=cfgmgr32.CM_Intersect_Range_List") +#pragma comment(linker, "/EXPORT:CM_Invert_Range_List=cfgmgr32.CM_Invert_Range_List") +#pragma comment(linker, "/EXPORT:CM_Is_Dock_Station_Present=cfgmgr32.CM_Is_Dock_Station_Present") +#pragma comment(linker, "/EXPORT:CM_Is_Dock_Station_Present_Ex=cfgmgr32.CM_Is_Dock_Station_Present_Ex") +#pragma comment(linker, "/EXPORT:CM_Is_Version_Available=cfgmgr32.CM_Is_Version_Available") +#pragma comment(linker, "/EXPORT:CM_Is_Version_Available_Ex=cfgmgr32.CM_Is_Version_Available_Ex") +#pragma comment(linker, "/EXPORT:CM_Locate_DevNodeA=cfgmgr32.CM_Locate_DevNodeA") +#pragma comment(linker, "/EXPORT:CM_Locate_DevNodeW=cfgmgr32.CM_Locate_DevNodeW") +#pragma comment(linker, "/EXPORT:CM_Locate_DevNode_ExA=cfgmgr32.CM_Locate_DevNode_ExA") +#pragma comment(linker, "/EXPORT:CM_Locate_DevNode_ExW=cfgmgr32.CM_Locate_DevNode_ExW") +#pragma comment(linker, "/EXPORT:CM_MapCrToSpErr=cfgmgr32.CM_MapCrToSpErr") +#pragma comment(linker, "/EXPORT:CM_MapCrToWin32Err=cfgmgr32.CM_MapCrToWin32Err") +#pragma comment(linker, "/EXPORT:CM_Merge_Range_List=cfgmgr32.CM_Merge_Range_List") +#pragma comment(linker, "/EXPORT:CM_Modify_Res_Des=cfgmgr32.CM_Modify_Res_Des") +#pragma comment(linker, "/EXPORT:CM_Modify_Res_Des_Ex=cfgmgr32.CM_Modify_Res_Des_Ex") +#pragma comment(linker, "/EXPORT:CM_Move_DevNode=cfgmgr32.CM_Move_DevNode") +#pragma comment(linker, "/EXPORT:CM_Move_DevNode_Ex=cfgmgr32.CM_Move_DevNode_Ex") +#pragma comment(linker, "/EXPORT:CM_Next_Range=cfgmgr32.CM_Next_Range") +#pragma comment(linker, "/EXPORT:CM_Open_Class_KeyA=cfgmgr32.CM_Open_Class_KeyA") +#pragma comment(linker, "/EXPORT:CM_Open_Class_KeyW=cfgmgr32.CM_Open_Class_KeyW") +#pragma comment(linker, "/EXPORT:CM_Open_Class_Key_ExA=cfgmgr32.CM_Open_Class_Key_ExA") +#pragma comment(linker, "/EXPORT:CM_Open_Class_Key_ExW=cfgmgr32.CM_Open_Class_Key_ExW") +#pragma comment(linker, "/EXPORT:CM_Open_DevNode_Key=cfgmgr32.CM_Open_DevNode_Key") +#pragma comment(linker, "/EXPORT:CM_Open_DevNode_Key_Ex=cfgmgr32.CM_Open_DevNode_Key_Ex") +#pragma comment(linker, "/EXPORT:CM_Open_Device_Interface_KeyA=cfgmgr32.CM_Open_Device_Interface_KeyA") +#pragma comment(linker, "/EXPORT:CM_Open_Device_Interface_KeyW=cfgmgr32.CM_Open_Device_Interface_KeyW") +#pragma comment(linker, "/EXPORT:CM_Open_Device_Interface_Key_ExA=cfgmgr32.CM_Open_Device_Interface_Key_ExA") +#pragma comment(linker, "/EXPORT:CM_Open_Device_Interface_Key_ExW=cfgmgr32.CM_Open_Device_Interface_Key_ExW") +#pragma comment(linker, "/EXPORT:CM_Query_And_Remove_SubTreeA=cfgmgr32.CM_Query_And_Remove_SubTreeA") +#pragma comment(linker, "/EXPORT:CM_Query_And_Remove_SubTreeW=cfgmgr32.CM_Query_And_Remove_SubTreeW") +#pragma comment(linker, "/EXPORT:CM_Query_And_Remove_SubTree_ExA=cfgmgr32.CM_Query_And_Remove_SubTree_ExA") +#pragma comment(linker, "/EXPORT:CM_Query_And_Remove_SubTree_ExW=cfgmgr32.CM_Query_And_Remove_SubTree_ExW") +#pragma comment(linker, "/EXPORT:CM_Query_Arbitrator_Free_Data=cfgmgr32.CM_Query_Arbitrator_Free_Data") +#pragma comment(linker, "/EXPORT:CM_Query_Arbitrator_Free_Data_Ex=cfgmgr32.CM_Query_Arbitrator_Free_Data_Ex") +#pragma comment(linker, "/EXPORT:CM_Query_Arbitrator_Free_Size=cfgmgr32.CM_Query_Arbitrator_Free_Size") +#pragma comment(linker, "/EXPORT:CM_Query_Arbitrator_Free_Size_Ex=cfgmgr32.CM_Query_Arbitrator_Free_Size_Ex") +#pragma comment(linker, "/EXPORT:CM_Query_Remove_SubTree=cfgmgr32.CM_Query_Remove_SubTree") +#pragma comment(linker, "/EXPORT:CM_Query_Remove_SubTree_Ex=cfgmgr32.CM_Query_Remove_SubTree_Ex") +#pragma comment(linker, "/EXPORT:CM_Query_Resource_Conflict_List=cfgmgr32.CM_Query_Resource_Conflict_List") +#pragma comment(linker, "/EXPORT:CM_Reenumerate_DevNode=cfgmgr32.CM_Reenumerate_DevNode") +#pragma comment(linker, "/EXPORT:CM_Reenumerate_DevNode_Ex=cfgmgr32.CM_Reenumerate_DevNode_Ex") +#pragma comment(linker, "/EXPORT:CM_Register_Device_Driver=cfgmgr32.CM_Register_Device_Driver") +#pragma comment(linker, "/EXPORT:CM_Register_Device_Driver_Ex=cfgmgr32.CM_Register_Device_Driver_Ex") +#pragma comment(linker, "/EXPORT:CM_Register_Device_InterfaceA=cfgmgr32.CM_Register_Device_InterfaceA") +#pragma comment(linker, "/EXPORT:CM_Register_Device_InterfaceW=cfgmgr32.CM_Register_Device_InterfaceW") +#pragma comment(linker, "/EXPORT:CM_Register_Device_Interface_ExA=cfgmgr32.CM_Register_Device_Interface_ExA") +#pragma comment(linker, "/EXPORT:CM_Register_Device_Interface_ExW=cfgmgr32.CM_Register_Device_Interface_ExW") +#pragma comment(linker, "/EXPORT:CM_Remove_SubTree=cfgmgr32.CM_Remove_SubTree") +#pragma comment(linker, "/EXPORT:CM_Remove_SubTree_Ex=cfgmgr32.CM_Remove_SubTree_Ex") +#pragma comment(linker, "/EXPORT:CM_Request_Device_EjectA=cfgmgr32.CM_Request_Device_EjectA") +#pragma comment(linker, "/EXPORT:CM_Request_Device_EjectW=cfgmgr32.CM_Request_Device_EjectW") +#pragma comment(linker, "/EXPORT:CM_Request_Device_Eject_ExA=cfgmgr32.CM_Request_Device_Eject_ExA") +#pragma comment(linker, "/EXPORT:CM_Request_Device_Eject_ExW=cfgmgr32.CM_Request_Device_Eject_ExW") +#pragma comment(linker, "/EXPORT:CM_Request_Eject_PC=cfgmgr32.CM_Request_Eject_PC") +#pragma comment(linker, "/EXPORT:CM_Request_Eject_PC_Ex=cfgmgr32.CM_Request_Eject_PC_Ex") +#pragma comment(linker, "/EXPORT:CM_RestoreAll_DefaultPowerSchemes=cfgmgr32.CM_RestoreAll_DefaultPowerSchemes") +#pragma comment(linker, "/EXPORT:CM_Restore_DefaultPowerScheme=cfgmgr32.CM_Restore_DefaultPowerScheme") +#pragma comment(linker, "/EXPORT:CM_Run_Detection=cfgmgr32.CM_Run_Detection") +#pragma comment(linker, "/EXPORT:CM_Run_Detection_Ex=cfgmgr32.CM_Run_Detection_Ex") +#pragma comment(linker, "/EXPORT:CM_Set_ActiveScheme=cfgmgr32.CM_Set_ActiveScheme") +#pragma comment(linker, "/EXPORT:CM_Set_Class_PropertyW=cfgmgr32.CM_Set_Class_PropertyW") +#pragma comment(linker, "/EXPORT:CM_Set_Class_Property_ExW=cfgmgr32.CM_Set_Class_Property_ExW") +#pragma comment(linker, "/EXPORT:CM_Set_Class_Registry_PropertyA=cfgmgr32.CM_Set_Class_Registry_PropertyA") +#pragma comment(linker, "/EXPORT:CM_Set_Class_Registry_PropertyW=cfgmgr32.CM_Set_Class_Registry_PropertyW") +#pragma comment(linker, "/EXPORT:CM_Set_DevNode_Problem=cfgmgr32.CM_Set_DevNode_Problem") +#pragma comment(linker, "/EXPORT:CM_Set_DevNode_Problem_Ex=cfgmgr32.CM_Set_DevNode_Problem_Ex") +#pragma comment(linker, "/EXPORT:CM_Set_DevNode_PropertyW=cfgmgr32.CM_Set_DevNode_PropertyW") +#pragma comment(linker, "/EXPORT:CM_Set_DevNode_Property_ExW=cfgmgr32.CM_Set_DevNode_Property_ExW") +#pragma comment(linker, "/EXPORT:CM_Set_DevNode_Registry_PropertyA=cfgmgr32.CM_Set_DevNode_Registry_PropertyA") +#pragma comment(linker, "/EXPORT:CM_Set_DevNode_Registry_PropertyW=cfgmgr32.CM_Set_DevNode_Registry_PropertyW") +#pragma comment(linker, "/EXPORT:CM_Set_DevNode_Registry_Property_ExA=cfgmgr32.CM_Set_DevNode_Registry_Property_ExA") +#pragma comment(linker, "/EXPORT:CM_Set_DevNode_Registry_Property_ExW=cfgmgr32.CM_Set_DevNode_Registry_Property_ExW") +#pragma comment(linker, "/EXPORT:CM_Set_Device_Interface_PropertyW=cfgmgr32.CM_Set_Device_Interface_PropertyW") +#pragma comment(linker, "/EXPORT:CM_Set_Device_Interface_Property_ExW=cfgmgr32.CM_Set_Device_Interface_Property_ExW") +#pragma comment(linker, "/EXPORT:CM_Set_HW_Prof=cfgmgr32.CM_Set_HW_Prof") +#pragma comment(linker, "/EXPORT:CM_Set_HW_Prof_Ex=cfgmgr32.CM_Set_HW_Prof_Ex") +#pragma comment(linker, "/EXPORT:CM_Set_HW_Prof_FlagsA=cfgmgr32.CM_Set_HW_Prof_FlagsA") +#pragma comment(linker, "/EXPORT:CM_Set_HW_Prof_FlagsW=cfgmgr32.CM_Set_HW_Prof_FlagsW") +#pragma comment(linker, "/EXPORT:CM_Set_HW_Prof_Flags_ExA=cfgmgr32.CM_Set_HW_Prof_Flags_ExA") +#pragma comment(linker, "/EXPORT:CM_Set_HW_Prof_Flags_ExW=cfgmgr32.CM_Set_HW_Prof_Flags_ExW") +#pragma comment(linker, "/EXPORT:CM_Setup_DevNode=cfgmgr32.CM_Setup_DevNode") +#pragma comment(linker, "/EXPORT:CM_Setup_DevNode_Ex=cfgmgr32.CM_Setup_DevNode_Ex") +#pragma comment(linker, "/EXPORT:CM_Test_Range_Available=cfgmgr32.CM_Test_Range_Available") +#pragma comment(linker, "/EXPORT:CM_Uninstall_DevNode=cfgmgr32.CM_Uninstall_DevNode") +#pragma comment(linker, "/EXPORT:CM_Uninstall_DevNode_Ex=cfgmgr32.CM_Uninstall_DevNode_Ex") +#pragma comment(linker, "/EXPORT:CM_Unregister_Device_InterfaceA=cfgmgr32.CM_Unregister_Device_InterfaceA") +#pragma comment(linker, "/EXPORT:CM_Unregister_Device_InterfaceW=cfgmgr32.CM_Unregister_Device_InterfaceW") +#pragma comment(linker, "/EXPORT:CM_Unregister_Device_Interface_ExA=cfgmgr32.CM_Unregister_Device_Interface_ExA") +#pragma comment(linker, "/EXPORT:CM_Unregister_Device_Interface_ExW=cfgmgr32.CM_Unregister_Device_Interface_ExW") +#pragma comment(linker, "/EXPORT:CM_Write_UserPowerKey=cfgmgr32.CM_Write_UserPowerKey") \ No newline at end of file diff --git a/01-Extended DLLs/KxBase/heap.c b/01-Extended DLLs/KxBase/heap.c new file mode 100644 index 0000000..5c4dc14 --- /dev/null +++ b/01-Extended DLLs/KxBase/heap.c @@ -0,0 +1,50 @@ +#include "buildcfg.h" +#include "kxbasep.h" + +KXBASEAPI HANDLE WINAPI Ext_HeapCreate( + IN ULONG Flags, + IN SIZE_T InitialSize, + IN SIZE_T MaximumSize) +{ + HANDLE HeapHandle; + + Flags &= HEAP_GENERATE_EXCEPTIONS | HEAP_NO_SERIALIZE | HEAP_CREATE_ENABLE_EXECUTE; + Flags |= HEAP_CLASS_1; + + if (MaximumSize < PAGE_SIZE) { + if (MaximumSize == 0) { + Flags |= HEAP_GROWABLE; + } else { + // Round up to the page size. + MaximumSize = PAGE_SIZE; + } + } + + if (!(Flags & HEAP_GROWABLE) && InitialSize > MaximumSize) { + MaximumSize = InitialSize; + } + + // + // The following line of code is the important part and is the reason why we have + // rewritten the HeapCreate function. + // Adding the following flag prevents RtlCreateHeap from trying to create a + // "debug heap", which causes lots of problems with some applications (and it's + // also slower, I'd presume). + // + + Flags |= HEAP_SKIP_VALIDATION_CHECKS; + + HeapHandle = RtlCreateHeap( + Flags, + NULL, + MaximumSize, + InitialSize, + NULL, + NULL); + + if (HeapHandle == NULL) { + RtlSetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); + } + + return HeapHandle; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxBase/kxbase.def b/01-Extended DLLs/KxBase/kxbase.def new file mode 100644 index 0000000..d4de031 --- /dev/null +++ b/01-Extended DLLs/KxBase/kxbase.def @@ -0,0 +1,147 @@ +LIBRARY KxBase +EXPORTS + ;; + ;; VxKex New Functions + ;; + + ResolveDelayLoadedAPI = KexDll.KexLdrResolveDelayLoadedAPI + + ;; thread.c + GetThreadDescription + SetThreadDescription + GetCurrentThreadStackLimits + SetThreadInformation + GetThreadInformation + SetThreadSelectedCpuSets + SetThreadSelectedCpuSetMasks + GetThreadSelectedCpuSets + GetThreadSelectedCpuSetMasks + + ;; process.c + GetProcessInformation + SetProcessInformation + SetProcessDefaultCpuSets + SetProcessDefaultCpuSetMasks + GetProcessDefaultCpuSets + GetProcessDefaultCpuSetMasks + SetProcessMitigationPolicy + GetProcessMitigationPolicy + + ;; pssapi.c + PssCaptureSnapshot + PssFreeSnapshot + PssQuerySnapshot + PssWalkMarkerCreate + + ;; cfgmgr.c + CM_Register_Notification + + ;; module.c + LoadPackagedLibrary + + ;; misc.c + GetOsSafeBootMode + GetFirmwareType + + ;; file.c + CreateFile2 + GetTempPath2A + GetTempPath2W + CopyFile2 + + ;; time.c + GetSystemTimePreciseAsFileTime + QueryUnbiasedInterruptTimePrecise + + ;; appmodel.c + AppPolicyGetProcessTerminationMethod + AppPolicyGetThreadInitializationType + AppPolicyGetWindowingModel + AppXGetPackageSid + AppXFreeMemory + GetApplicationUserModelId + GetCurrentApplicationUserModelId + GetCurrentPackageFullName + GetCurrentPackageId + GetPackageFamilyName + GetPackageFullName + GetPackagesByPackageFamily + PackageFamilyNameFromFullName + + ;; synch.c + WaitOnAddress + WakeByAddressSingle = KexDll.KexRtlWakeAddressSingle + WakeByAddressAll = KexDll.KexRtlWakeAddressAll + + ;; wow64.c + IsWow64Process2 + + ;; vmem.c + DiscardVirtualMemory + OfferVirtualMemory + ReclaimVirtualMemory + PrefetchVirtualMemory + CreateFileMappingFromApp + MapViewOfFileFromApp + VirtualAllocFromApp + VirtualProtectFromApp + OpenFileMappingFromApp + MapViewOfFileNuma2 + UnmapViewOfFile2 + UnmapViewOfFileEx + MapViewOfFile3 + MapViewOfFile3FromApp + + ;; KexPathCch + PathAllocCanonicalize + PathAllocCombine + PathCchAddBackslash + PathCchAddBackslashEx + PathCchAddExtension + PathCchAppend + PathCchAppendEx + PathCchCanonicalize + PathCchCanonicalizeEx + PathCchCombine + PathCchCombineEx + PathCchFindExtension + PathCchIsRoot + PathCchRemoveBackslash + PathCchRemoveBackslashEx + PathCchRemoveExtension + PathCchRemoveFileSpec + PathCchRenameExtension + PathCchSkipRoot + PathCchStripPrefix + PathCchStripToRoot + PathIsUNCEx + + ;; + ;; VxKex Extended Functions + ;; + + ;; process.c + IsProcessInJob = Ext_IsProcessInJob + UpdateProcThreadAttribute = Ext_UpdateProcThreadAttribute + + ;; module.c + GetModuleHandleA = Ext_GetModuleHandleA + GetModuleHandleW = Ext_GetModuleHandleW + GetModuleHandleExA = Ext_GetModuleHandleExA + GetModuleHandleExW = Ext_GetModuleHandleExW + LoadLibraryA = Ext_LoadLibraryA + LoadLibraryW = Ext_LoadLibraryW + LoadLibraryExA = Ext_LoadLibraryExA + LoadLibraryExW = Ext_LoadLibraryExW + AddDllDirectory = Ext_AddDllDirectory + RemoveDllDirectory = Ext_RemoveDllDirectory + SetDefaultDllDirectories = Ext_SetDefaultDllDirectories + + ;; verspoof.c + GetVersionExA = Ext_GetVersionExA + + ;; stubs.c + DuplicateHandle = Ext_DuplicateHandle + + ;; heap.c + HeapCreate = Ext_HeapCreate \ No newline at end of file diff --git a/01-Extended DLLs/KxBase/kxbase.vcxproj b/01-Extended DLLs/KxBase/kxbase.vcxproj new file mode 100644 index 0000000..3786ff7 --- /dev/null +++ b/01-Extended DLLs/KxBase/kxbase.vcxproj @@ -0,0 +1,253 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {0AF7A2B2-BB6A-49EF-99BF-886525F51821} + Win32Proj + kxbase + KxBase + + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + + + + + + + + + + + + + + + + + false + false + + + false + false + + + false + false + + + false + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;KXBASE_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + true + false + StdCall + ProgramDatabase + true + false + false + Default + + + Windows + true + kxbase.def + $(TargetDir);$(SolutionDir)\00-Import Libraries + true + + + + + + + $(SolutionDir)\00-Common Headers + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;KXBASE_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + true + false + StdCall + ProgramDatabase + true + false + false + Default + + + Windows + true + kxbase.def + $(TargetDir);$(SolutionDir)\00-Import Libraries + true + + + + + + + $(SolutionDir)\00-Common Headers + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;KXBASE_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + true + false + StdCall + ProgramDatabase + true + false + false + Default + + + Windows + true + true + true + kxbase.def + $(TargetDir);$(SolutionDir)\00-Import Libraries + true + + + + + + + $(SolutionDir)\00-Common Headers + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;KXBASE_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + true + false + StdCall + ProgramDatabase + true + false + false + Default + + + Windows + true + true + true + kxbase.def + $(TargetDir);$(SolutionDir)\00-Import Libraries + true + + + + + + + $(SolutionDir)\00-Common Headers + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/01-Extended DLLs/KxBase/kxbase.vcxproj.filters b/01-Extended DLLs/KxBase/kxbase.vcxproj.filters new file mode 100644 index 0000000..62b0efc --- /dev/null +++ b/01-Extended DLLs/KxBase/kxbase.vcxproj.filters @@ -0,0 +1,97 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Source Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/01-Extended DLLs/KxBase/kxbasep.h b/01-Extended DLLs/KxBase/kxbasep.h new file mode 100644 index 0000000..45de482 --- /dev/null +++ b/01-Extended DLLs/KxBase/kxbasep.h @@ -0,0 +1,115 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// kexdllp.h +// +// Abstract: +// +// Private header file for KxBase. +// +// Author: +// +// vxiiduu (07-Nov-2022) +// +// Revision History: +// +// vxiiduu 07-Nov-2022 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include +#include + +EXTERN PKEX_PROCESS_DATA KexData; +EXTERN HANDLE KsecDD; + +// +// module.c +// + +KXBASEAPI HMODULE WINAPI Ext_GetModuleHandleA( + IN PCSTR ModuleName); + +KXBASEAPI HMODULE WINAPI Ext_GetModuleHandleW( + IN PCWSTR ModuleName); + +KXBASEAPI BOOL WINAPI Ext_GetModuleHandleExA( + IN ULONG Flags, + IN PCSTR ModuleName, + OUT HMODULE *ModuleHandleOut); + +KXBASEAPI BOOL WINAPI Ext_GetModuleHandleExW( + IN ULONG Flags, + IN PCWSTR ModuleName, + OUT HMODULE *ModuleHandleOut); + +KXBASEAPI ULONG WINAPI Ext_GetModuleFileNameA( + IN HMODULE ModuleHandle, + OUT PSTR FileName, + IN ULONG FileNameCch); + +KXBASEAPI ULONG WINAPI Ext_GetModuleFileNameW( + IN HMODULE ModuleHandle, + OUT PWSTR FileName, + IN ULONG FileNameCch); + +KXBASEAPI HMODULE WINAPI Ext_LoadLibraryA( + IN PCSTR FileName); + +KXBASEAPI HMODULE WINAPI Ext_LoadLibraryW( + IN PCWSTR FileName); + +KXBASEAPI HMODULE WINAPI Ext_LoadLibraryExA( + IN PCSTR FileName, + IN HANDLE FileHandle, + IN ULONG Flags); + +KXBASEAPI HMODULE WINAPI Ext_LoadLibraryExW( + IN PCWSTR FileName, + IN HANDLE FileHandle, + IN ULONG Flags); + +// +// time.c +// + +KXBASEAPI VOID WINAPI KxBasepGetSystemTimeAsFileTimeHook( + OUT PFILETIME SystemTimeAsFileTime); + +KXBASEAPI VOID WINAPI KxBasepGetSystemTimeHook( + OUT PSYSTEMTIME SystemTime); + +// +// support.c +// + +PLARGE_INTEGER BaseFormatTimeOut( + OUT PLARGE_INTEGER TimeOut, + IN ULONG Milliseconds); + +HANDLE WINAPI BaseGetNamedObjectDirectory( + VOID); + +HANDLE WINAPI BaseGetUntrustedNamedObjectDirectory( + VOID); + +PVOID BaseGetBaseDllHandle( + VOID); + +// +// dllpath.c +// + +VOID KxBaseAddKex3264ToBaseDefaultPath( + VOID); + +// +// crypto.c +// + +NTSTATUS BaseInitializeCrypto( + VOID); \ No newline at end of file diff --git a/01-Extended DLLs/KxBase/misc.c b/01-Extended DLLs/KxBase/misc.c new file mode 100644 index 0000000..56df0f3 --- /dev/null +++ b/01-Extended DLLs/KxBase/misc.c @@ -0,0 +1,16 @@ +#include "buildcfg.h" +#include "kxbasep.h" + +KXBASEAPI BOOL WINAPI GetOsSafeBootMode( + OUT PBOOL IsSafeBootMode) +{ + *IsSafeBootMode = FALSE; + return TRUE; +} + +KXBASEAPI BOOL WINAPI GetFirmwareType( + OUT PFIRMWARE_TYPE FirmwareType) +{ + *FirmwareType = FirmwareTypeUnknown; + return TRUE; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxBase/module.c b/01-Extended DLLs/KxBase/module.c new file mode 100644 index 0000000..d7633bb --- /dev/null +++ b/01-Extended DLLs/KxBase/module.c @@ -0,0 +1,320 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// module.c +// +// Abstract: +// +// Thjs file contains functions related to DLL loading. +// The main purpose of the files in here is to rewrite the names of DLLs +// which the application requests to dynamically load. +// +// Author: +// +// Author (10-Feb-2024) +// +// Environment: +// +// Win32 mode. +// +// Revision History: +// +// vxiiduu 10-Feb-2024 Initial creation. +// vxiiduu 02-Mar-2024 Fix GetModuleHandleExW logging when +// GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS +// flag is passed. +// vxiiduu 13-Mar-2024 Move most of the code here to kexldr. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kxbasep.h" +#include +#include + +// +// These two utility functions make use of an unused field in the TEB. +// Their purpose is to set KexLdrShouldRewriteDll to 1 whenever +// Ext_GetModuleHandle(Ex)(A/W) or Ext_LoadLibrary(Ex)(A/W) is present in +// the call stack. +// +// When this happens, it means that an EXE or DLL outside of WinDir and KexDir +// has called GetModuleHandle or LoadLibrary. It signals to Ext_LdrLoadDll +// and Ext_LdrGetDllHandle so that they can avoid rewriting imports when it +// isn't desired. +// + +STATIC INLINE VOID InterceptedKernelBaseLoaderCallEntry( + OUT PBOOLEAN ReEntrant) +{ + PTEB Teb; + + Teb = NtCurrentTeb(); + *ReEntrant = Teb->KexLdrShouldRewriteDll; + Teb->KexLdrShouldRewriteDll = TRUE; +} + +STATIC INLINE VOID InterceptedKernelBaseLoaderCallReturn( + IN BOOLEAN ReEntrant) +{ + if (!ReEntrant) { + NtCurrentTeb()->KexLdrShouldRewriteDll = FALSE; + } +} + +KXBASEAPI HMODULE WINAPI Ext_GetModuleHandleA( + IN PCSTR ModuleName) +{ + HMODULE ModuleHandle; + BOOLEAN ReEntrant; + + InterceptedKernelBaseLoaderCallEntry(&ReEntrant); + ModuleHandle = GetModuleHandleA(ModuleName); + InterceptedKernelBaseLoaderCallReturn(ReEntrant); + + return ModuleHandle; +} + +KXBASEAPI HMODULE WINAPI Ext_GetModuleHandleW( + IN PCWSTR ModuleName) +{ + HMODULE ModuleHandle; + BOOLEAN ReEntrant; + + // + // APPSPECIFICHACK: Chromium-based software uses a bootleg knockoff version of + // GetProcAddress that fails miserably and crashes the whole app when we rewrite + // NTDLL, because their shitty implementation doesn't work properly with + // the export forwarders in KxNt. Neither does it properly work with stubs, + // because they actually scan the instruction code of system calls. + // + if ((KexData->Flags & KEXDATA_FLAG_CHROMIUM) && + ModuleName != NULL && + StringEqual(ModuleName, L"ntdll.dll")) { + + KexLogDebugEvent(L"Not rewriting NTDLL for Chromium compatibility"); + return (HMODULE) KexData->SystemDllBase; + } + + InterceptedKernelBaseLoaderCallEntry(&ReEntrant); + ModuleHandle = GetModuleHandleW(ModuleName); + InterceptedKernelBaseLoaderCallReturn(ReEntrant); + + return ModuleHandle; +} + +KXBASEAPI BOOL WINAPI Ext_GetModuleHandleExA( + IN ULONG Flags, + IN PCSTR ModuleName, + OUT HMODULE *ModuleHandleOut) +{ + BOOL Success; + BOOLEAN ReEntrant; + + InterceptedKernelBaseLoaderCallEntry(&ReEntrant); + Success = GetModuleHandleExA(Flags, ModuleName, ModuleHandleOut); + InterceptedKernelBaseLoaderCallReturn(ReEntrant); + + return Success; +} + +KXBASEAPI BOOL WINAPI Ext_GetModuleHandleExW( + IN ULONG Flags, + IN PCWSTR ModuleName, + OUT HMODULE *ModuleHandleOut) +{ + BOOL Success; + BOOLEAN ReEntrant; + + InterceptedKernelBaseLoaderCallEntry(&ReEntrant); + Success = GetModuleHandleExW(Flags, ModuleName, ModuleHandleOut); + InterceptedKernelBaseLoaderCallReturn(ReEntrant); + + return Success; +} + +KXBASEAPI HMODULE WINAPI Ext_LoadLibraryA( + IN PCSTR FileName) +{ + HMODULE ModuleHandle; + BOOLEAN ReEntrant; + + InterceptedKernelBaseLoaderCallEntry(&ReEntrant); + ModuleHandle = LoadLibraryA(FileName); + InterceptedKernelBaseLoaderCallReturn(ReEntrant); + + return ModuleHandle; +} + +KXBASEAPI HMODULE WINAPI Ext_LoadLibraryW( + IN PCWSTR FileName) +{ + HMODULE ModuleHandle; + BOOLEAN ReEntrant; + + InterceptedKernelBaseLoaderCallEntry(&ReEntrant); + ModuleHandle = LoadLibraryW(FileName); + InterceptedKernelBaseLoaderCallReturn(ReEntrant); + + return ModuleHandle; +} + +KXBASEAPI HMODULE WINAPI Ext_LoadLibraryExA( + IN PCSTR FileName, + IN HANDLE FileHandle, + IN ULONG Flags) +{ + HMODULE ModuleHandle; + BOOLEAN ReEntrant; + + InterceptedKernelBaseLoaderCallEntry(&ReEntrant); + ModuleHandle = LoadLibraryExA(FileName, FileHandle, Flags); + InterceptedKernelBaseLoaderCallReturn(ReEntrant); + + return ModuleHandle; +} + +KXBASEAPI HMODULE WINAPI Ext_LoadLibraryExW( + IN PCWSTR FileName, + IN HANDLE FileHandle, + IN ULONG Flags) +{ + HMODULE ModuleHandle; + BOOLEAN ReEntrant; + + InterceptedKernelBaseLoaderCallEntry(&ReEntrant); + ModuleHandle = LoadLibraryExW(FileName, FileHandle, Flags); + InterceptedKernelBaseLoaderCallReturn(ReEntrant); + + return ModuleHandle; +} + +KXBASEAPI HMODULE WINAPI LoadPackagedLibrary( + IN PCWSTR LibFileName, + IN ULONG Reserved) +{ + RTL_PATH_TYPE PathType; + ULONG Index; + + if (Reserved) { + BaseSetLastNTError(STATUS_INVALID_PARAMETER); + return NULL; + } + + PathType = RtlDetermineDosPathNameType_U(LibFileName); + + if (PathType != RtlPathTypeRelative) { + BaseSetLastNTError(STATUS_INVALID_PARAMETER); + return NULL; + } + + for (Index = 0; LibFileName[Index] != '\0'; ++Index) { + if (LibFileName[Index] == '.' && LibFileName[Index+1] == '.' && + (LibFileName[Index+2] == '\\' || LibFileName[Index+2] == '/')) { + + BaseSetLastNTError(STATUS_INVALID_PARAMETER); + return NULL; + } + + do { + ++Index; + } until (LibFileName[Index] == '\0' || + LibFileName[Index] == '\\' || + LibFileName[Index] == '/'); + } + + // On Windows 8 this would be the point where this function would call + // LoadLibraryExW with the undocumented flag 0x04. However, this flag and + // its underlying implementation inside LdrLoadDll is not present on Windows + // 7, so we will just return an error straight away (as documented). + RtlSetLastWin32Error(APPMODEL_ERROR_NO_PACKAGE); + return NULL; +} + +STATIC NTSTATUS BasepGetDllDirectoryProcedure( + IN PCSTR ProcedureName, + IN OUT PPVOID ProcedureAddress) +{ + NTSTATUS Status; + + Status = STATUS_SUCCESS; + + ASSERT (ProcedureName != NULL); + ASSERT (ProcedureAddress != NULL); + + if (!*ProcedureAddress) { + ANSI_STRING ProcedureNameAS; + + Status = RtlInitAnsiStringEx(&ProcedureNameAS, ProcedureName); + if (!NT_SUCCESS(Status)) { + return Status; + } + + ASSUME (KexData->BaseDllBase != NULL); + + Status = LdrGetProcedureAddress( + KexData->BaseDllBase, + &ProcedureNameAS, + 0, + ProcedureAddress); + + if (!NT_SUCCESS(Status)) { + KexLogErrorEvent( + L"%hs is not available on this computer\r\n\r\n" + L"This function is only available on Windows 7 with the KB2533623 " + L"security update.", ProcedureName); + + BaseSetLastNTError(Status); + } + } + + if (NT_SUCCESS(Status)) { + ASSUME (*ProcedureAddress != NULL); + } + + return Status; +} + +KXBASEAPI DLL_DIRECTORY_COOKIE WINAPI Ext_AddDllDirectory( + IN PCWSTR NewDirectory) +{ + STATIC DLL_DIRECTORY_COOKIE (WINAPI *AddDllDirectory) (PCWSTR) = NULL; + + BasepGetDllDirectoryProcedure("AddDllDirectory", (PPVOID) &AddDllDirectory); + + if (AddDllDirectory) { + return AddDllDirectory(NewDirectory); + } else { + return NULL; + } +} + +KXBASEAPI BOOL WINAPI Ext_RemoveDllDirectory( + IN DLL_DIRECTORY_COOKIE Cookie) +{ + STATIC BOOL (WINAPI *RemoveDllDirectory) (DLL_DIRECTORY_COOKIE) = NULL; + + BasepGetDllDirectoryProcedure("RemoveDllDirectory", (PPVOID) &RemoveDllDirectory); + + if (RemoveDllDirectory) { + return RemoveDllDirectory(Cookie); + } else { + return FALSE; + } +} + +KXBASEAPI BOOL WINAPI Ext_SetDefaultDllDirectories( + IN ULONG DirectoryFlags) +{ + STATIC BOOL (WINAPI *SetDefaultDllDirectories) (ULONG) = NULL; + + BasepGetDllDirectoryProcedure("SetDefaultDllDirectories", (PPVOID) &SetDefaultDllDirectories); + + if (SetDefaultDllDirectories) { + DirectoryFlags |= LOAD_LIBRARY_SEARCH_USER_DIRS; + return SetDefaultDllDirectories(DirectoryFlags); + } else { + return FALSE; + } +} \ No newline at end of file diff --git a/01-Extended DLLs/KxBase/process.c b/01-Extended DLLs/KxBase/process.c new file mode 100644 index 0000000..dbe75b8 --- /dev/null +++ b/01-Extended DLLs/KxBase/process.c @@ -0,0 +1,297 @@ +#include "buildcfg.h" +#include "kxbasep.h" + +KXBASEAPI BOOL WINAPI GetProcessInformation( + IN HANDLE ProcessHandle, + IN PROCESS_INFORMATION_CLASS ProcessInformationClass, + OUT PVOID ProcessInformation, + IN ULONG ProcessInformationSize) +{ + // TODO + BaseSetLastNTError(STATUS_NOT_IMPLEMENTED); + return FALSE; +} + +KXBASEAPI BOOL WINAPI SetProcessInformation( + IN HANDLE ProcessHandle, + IN PROCESS_INFORMATION_CLASS ProcessInformationClass, + IN PVOID ProcessInformation, + IN ULONG ProcessInformationSize) +{ + // TODO + BaseSetLastNTError(STATUS_NOT_IMPLEMENTED); + return FALSE; +} + +KXBASEAPI BOOL WINAPI SetProcessDefaultCpuSets( + IN HANDLE ProcessHandle, + IN PULONG CpuSetIds, + IN ULONG NumberOfCpuSetIds) +{ + if (CpuSetIds == NULL) { + if (NumberOfCpuSetIds != 0) { + BaseSetLastNTError(STATUS_INVALID_PARAMETER); + return FALSE; + } + } + + return TRUE; +} + +KXBASEAPI BOOL WINAPI SetProcessDefaultCpuSetMasks( + IN HANDLE ProcessHandle, + IN PGROUP_AFFINITY CpuSetMasks, + IN ULONG NumberOfCpuSetMasks) +{ + if (CpuSetMasks == NULL) { + if (NumberOfCpuSetMasks != 0) { + BaseSetLastNTError(STATUS_INVALID_PARAMETER); + return FALSE; + } + } + + return TRUE; +} + +KXBASEAPI BOOL WINAPI GetProcessDefaultCpuSets( + IN HANDLE ProcessHandle, + OUT PULONG CpuSetIds, + IN ULONG CpuSetIdArraySize, + OUT PULONG ReturnCount) +{ + *ReturnCount = 0; + + if (CpuSetIds == NULL) { + if (CpuSetIdArraySize != 0) { + BaseSetLastNTError(STATUS_INVALID_PARAMETER); + return FALSE; + } + } + + return TRUE; +} + +KXBASEAPI BOOL WINAPI GetProcessDefaultCpuSetMasks( + IN HANDLE ProcessHandle, + OUT PGROUP_AFFINITY CpuSetMasks, + IN ULONG CpuSetMaskArraySize, + OUT PULONG ReturnCount) +{ + *ReturnCount = 0; + + if (CpuSetMasks == NULL) { + if (CpuSetMaskArraySize != 0) { + BaseSetLastNTError(STATUS_INVALID_PARAMETER); + return FALSE; + } + } + + return TRUE; +} + +KXBASEAPI BOOL WINAPI SetProcessMitigationPolicy( + IN PROCESS_MITIGATION_POLICY MitigationPolicy, + IN PVOID Buffer, + IN SIZE_T BufferCb) +{ + // + // Note that Windows 7 has SetProcessDEPPolicy but it doesn't do anything + // for x64. + // + + if (KexRtlCurrentProcessBitness() == 32 && MitigationPolicy == ProcessDEPPolicy) { + PPROCESS_MITIGATION_DEP_POLICY DepPolicy; + + if (BufferCb != sizeof(PROCESS_MITIGATION_DEP_POLICY)) { + BaseSetLastNTError(STATUS_INVALID_BUFFER_SIZE); + return FALSE; + } + + DepPolicy = (PPROCESS_MITIGATION_DEP_POLICY) Buffer; + + if (DepPolicy->Flags.ReservedFlags) { + BaseSetLastNTError(STATUS_INVALID_PARAMETER); + return FALSE; + } + + return SetProcessDEPPolicy(DepPolicy->Flags.AsUlong); + } else { + KexLogWarningEvent( + L"SetProcessMitigationPolicy called with unsupported MitigationPolicy value %d", + MitigationPolicy); + + // Fall through and pretend we succeeded. + } + + return TRUE; +} + +KXBASEAPI BOOL WINAPI GetProcessMitigationPolicy( + IN HANDLE ProcessHandle, + IN PROCESS_MITIGATION_POLICY MitigationPolicy, + OUT PVOID Buffer, + IN SIZE_T BufferCb) +{ + if (MitigationPolicy == ProcessMitigationOptionsMask) { + PULONGLONG Mask; + + // + // Buffer is a pointer to either one or two ULONGLONGs. + // The first one contains PROCESS_CREATION_MITIGATION_POLICY_*. + // The second one if present contains PROCESS_CREATION_MITIGATION_POLICY2_* + // + + if (BufferCb != 8 && BufferCb != 16) { + BaseSetLastNTError(STATUS_INVALID_PARAMETER); + return FALSE; + } + + Mask = (PULONGLONG) Buffer; + + Mask[0] = PROCESS_CREATION_MITIGATION_POLICY_VALID_MASK; + + if (BufferCb > 8) { + Mask[1] = 0; + } + + return TRUE; + } else if (MitigationPolicy == ProcessDEPPolicy) { + BOOLEAN Success; + PPROCESS_MITIGATION_DEP_POLICY DepPolicy; + BOOL Permanent; + + if (BufferCb != sizeof(PROCESS_MITIGATION_DEP_POLICY)) { + BaseSetLastNTError(STATUS_INVALID_BUFFER_SIZE); + return FALSE; + } + + DepPolicy = (PPROCESS_MITIGATION_DEP_POLICY) Buffer; + + Success = GetProcessDEPPolicy( + NtCurrentProcess(), + &DepPolicy->Flags.AsUlong, + &Permanent); + + DepPolicy->Permanent = Permanent; + return Success; + } else { + KexLogWarningEvent( + L"GetProcessMitigationPolicy called with unsupported MitigationPolicy value %d", + MitigationPolicy); + } + + BaseSetLastNTError(STATUS_NOT_SUPPORTED); + return FALSE; +} + +KXBASEAPI BOOL WINAPI Ext_IsProcessInJob( + IN HANDLE ProcessHandle, + IN HANDLE JobHandle, + OUT PBOOL IsInJob) +{ + // + // APPSPECIFICHACK: Make Chromium non-official builds not meddle with the IAT. + // See sandbox\policy\win\sandbox_win.cc SandboxWin::InitBrokerServices. + // This function should only be called in one place. + // + + if ((KexData->Flags & KEXDATA_FLAG_CHROMIUM) && + AshModuleBaseNameIs(ReturnAddress(), L"chrome.dll")) { + + ASSERT (ProcessHandle == NtCurrentProcess()); + ASSERT (JobHandle == NULL); + ASSERT (IsInJob != NULL); + + KexLogDebugEvent(L"Returning fake IsProcessInJob return value for Chrome compatibility"); + + if (ProcessHandle == NtCurrentProcess() && + JobHandle == NULL && + IsInJob != NULL) { + + *IsInJob = TRUE; + return TRUE; + } + } + + return IsProcessInJob(ProcessHandle, JobHandle, IsInJob); +} + +KXBASEAPI BOOL WINAPI Ext_UpdateProcThreadAttribute( + IN OUT PPROC_THREAD_ATTRIBUTE_LIST AttributeList, + IN ULONG Flags, + IN ULONG_PTR Attribute, + IN PVOID Value, + IN SIZE_T Size, + OUT PVOID PreviousValue OPTIONAL, + OUT PSIZE_T ReturnSize OPTIONAL) +{ + BOOLEAN Success; + BOOLEAN AlreadyTriedAgain; + ULONG MitigationPolicy; + + AlreadyTriedAgain = FALSE; + +TryAgain: + Success = UpdateProcThreadAttribute( + AttributeList, + Flags, + Attribute, + Value, + Size, + PreviousValue, + ReturnSize); + + if (!Success) { + ULONG LastError; + + // Save last-error code so we can restore it. The code below might modify it + // by accident. + LastError = GetLastError(); + + if (AlreadyTriedAgain) { + KexLogWarningEvent( + L"UpdateProcThreadAttribute failed despite modifying parameters.\r\n\r\n" + L"Win32 error: (%d) %s", + LastError, Win32ErrorAsString(LastError)); + + ASSERT (FALSE); + } else { + if (LastError == ERROR_NOT_SUPPORTED) { + switch (Attribute) { + case PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY: + // + // Edit the mitigation policy and go try again. + // + + if (!AlreadyTriedAgain) { + KexLogDebugEvent(L"Unsupported mitigation policies specified. Stripping."); + + if (Size > sizeof(ULONG)) { + ASSERT (Size == sizeof(ULONGLONG) || Size == 2 * sizeof(ULONGLONG)); + Size = sizeof(ULONG); + } + + MitigationPolicy = (*(PULONG) Value) & PROCESS_CREATION_MITIGATION_POLICY_VALID_MASK; + Value = &MitigationPolicy; + + AlreadyTriedAgain = TRUE; + goto TryAgain; + } + + break; + default: + // Just pretend we succeeded and hope nothing bad happens. + // Most of the extra mitigation policies don't really do anything anyway, + // so it should be fine to just pretend it succeeded. + Success = TRUE; + LastError = ERROR_SUCCESS; + break; + } + } + } + + SetLastError(LastError); + } + + return Success; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxBase/pssapi.c b/01-Extended DLLs/KxBase/pssapi.c new file mode 100644 index 0000000..94c5bd9 --- /dev/null +++ b/01-Extended DLLs/KxBase/pssapi.c @@ -0,0 +1,74 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// pssapi.c +// +// Abstract: +// +// This file contains the kxbase-side implementation of the Process +// Snapshots API introduced in Windows 8.1. These APIs are used by Python. +// +// Currently these APIs are all stubs. It is, however, possible to fully +// implement them under Windows 7 if it is found that programs are making +// significant use of them. +// +// As of 15-Mar-2024 the Python issue has been alleviated by this pull +// request I made: https://github.com/python/cpython/issues/116195 +// +// Author: +// +// vxiiduu (01-Mar-2024) +// +// Environment: +// +// WHERE CAN THIS PROGRAM/LIBRARY/CODE RUN? +// +// Revision History: +// +// vxiiduu 01-Mar-2024 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kxbasep.h" + +KXBASEAPI ULONG WINAPI PssCaptureSnapshot( + IN HANDLE ProcessHandle, + IN PSS_CAPTURE_FLAGS CaptureFlags, + IN ULONG ThreadContextFlags OPTIONAL, + OUT PHPSS SnapshotHandle) +{ + KexLogWarningEvent(L"Stub API called: PssCaptureSnapshot"); + KexDebugCheckpoint(); + return ERROR_NOT_SUPPORTED; +} + +KXBASEAPI ULONG WINAPI PssFreeSnapshot( + IN HANDLE ProcessHandle, + IN HPSS SnapshotHandle) +{ + KexLogWarningEvent(L"Stub API called: PssFreeSnapshot"); + KexDebugCheckpoint(); + return ERROR_NOT_SUPPORTED; +} + +KXBASEAPI ULONG WINAPI PssQuerySnapshot( + IN HPSS SnapshotHandle, + IN PSS_QUERY_INFORMATION_CLASS InformationClass, + OUT PVOID Buffer, + IN ULONG BufferLength) +{ + KexLogWarningEvent(L"Stub API called: PssQuerySnapshot"); + KexDebugCheckpoint(); + return ERROR_NOT_SUPPORTED; +} + +KXBASEAPI ULONG WINAPI PssWalkMarkerCreate( + IN PCPSS_ALLOCATOR Allocator, + OUT HPSSWALK WalkMarkerHandle) +{ + KexLogWarningEvent(L"Stub API called: PssWalkMarkerCreate"); + KexDebugCheckpoint(); + return ERROR_NOT_SUPPORTED; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxBase/stubs.c b/01-Extended DLLs/KxBase/stubs.c new file mode 100644 index 0000000..b166bc8 --- /dev/null +++ b/01-Extended DLLs/KxBase/stubs.c @@ -0,0 +1,47 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// file.ext +// +// Abstract: +// +// Forwarder stubs that do nothing except for calling the original function. +// These exist because some stupid software such as Chromium is not +// compatible with export forwarders. +// +// Author: +// +// vxiiduu (09-Mar-2024) +// +// Environment: +// +// Win32 +// +// Revision History: +// +// vxiiduu 09-Mar-2024 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kxbasep.h" + +KXBASEAPI BOOL WINAPI Ext_DuplicateHandle( + IN HANDLE SourceProcessHandle, + IN HANDLE SourceHandle, + IN HANDLE TargetProcessHandle, + OUT PHANDLE TargetHandle, + IN ACCESS_MASK DesiredAccess, + IN BOOL Inherit, + IN ULONG Options) +{ + return DuplicateHandle( + SourceProcessHandle, + SourceHandle, + TargetProcessHandle, + TargetHandle, + DesiredAccess, + Inherit, + Options); +} \ No newline at end of file diff --git a/01-Extended DLLs/KxBase/support.c b/01-Extended DLLs/KxBase/support.c new file mode 100644 index 0000000..a7a92d5 --- /dev/null +++ b/01-Extended DLLs/KxBase/support.c @@ -0,0 +1,236 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// support.c +// +// Abstract: +// +// Contains miscellaneous support routines used by KXBASE. +// +// Author: +// +// vxiiduu (11-Feb-2022) +// +// Environment: +// +// Win32 mode. +// +// Revision History: +// +// vxiiduu 11-Feb-2022 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kxbasep.h" + +// +// This function translates a Win32-style timeout (milliseconds) into a +// NT-style timeout (100-nanosecond intervals). +// +// The return value of this function can be directly passed to most +// NT APIs that accept a timeout parameter. +// +PLARGE_INTEGER BaseFormatTimeOut( + OUT PLARGE_INTEGER TimeOut, + IN ULONG Milliseconds) +{ + if (Milliseconds == INFINITE) { + return NULL; + } + + TimeOut->QuadPart = UInt32x32To64(Milliseconds, 10000); + TimeOut->QuadPart *= -1; + return TimeOut; +} + +HANDLE WINAPI BaseGetNamedObjectDirectory( + VOID) +{ + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE OriginalTokenHandle; + HANDLE DirectoryHandle; + UNICODE_STRING DirectoryName; + PPEB Peb; + + if (KexData->BaseNamedObjects) { + ASSERT (VALID_HANDLE(KexData->BaseNamedObjects)); + return KexData->BaseNamedObjects; + } + + // + // Get a pointer to BASE_STATIC_SERVER_DATA. + // We want the NamedObjectDirectory member, which is a UNICODE_STRING which might + // look like "\Sessions\1\BaseNamedObjects". + // + // Note: Peb->ReadOnlyStaticServerData is NULL prior to the initialization of the + // BASE DLLs. + // + + Peb = NtCurrentPeb(); + ASSERT (Peb->ReadOnlyStaticServerData != NULL); + + if (Peb->ReadOnlyStaticServerData == NULL) { + return NULL; + } + + if (KexRtlOperatingSystemBitness() != KexRtlCurrentProcessBitness()) { + PCBASE_STATIC_SERVER_DATA_WOW64 BaseStaticServerData; + + ASSERT (KexRtlCurrentProcessBitness() == 32); + ASSERT (KexRtlOperatingSystemBitness() == 64); + + // + // On WOW64, BASE_STATIC_SERVER_DATA is still a 64-bit structure. + // That's why we need to use the special WOW64 version of the structure. + // Note that all the pointers are still guaranteed to be within the + // 32-bit range. + // + + BaseStaticServerData = (PBASE_STATIC_SERVER_DATA_WOW64) Peb->ReadOnlyStaticServerData[2]; + ASSERT (BaseStaticServerData != NULL); + + DirectoryName.Length = BaseStaticServerData->NamedObjectDirectory.Length; + DirectoryName.MaximumLength = BaseStaticServerData->NamedObjectDirectory.MaximumLength; + DirectoryName.Buffer = BaseStaticServerData->NamedObjectDirectory.Buffer; + } else { + PCBASE_STATIC_SERVER_DATA BaseStaticServerData; + + BaseStaticServerData = (PBASE_STATIC_SERVER_DATA) Peb->ReadOnlyStaticServerData[1]; + ASSERT (BaseStaticServerData != NULL); + + DirectoryName = BaseStaticServerData->NamedObjectDirectory; + } + + ASSERT (NtCurrentPeb()->IsProtectedProcess == 0); + ASSERT (VALID_UNICODE_STRING(&DirectoryName)); + + // + // If we're impersonating, save the impersonation token, and revert + // to self for the duration of directory creation. + // + + if (NtCurrentTeb()->IsImpersonating) { + HANDLE NewToken; + + Status = NtOpenThreadToken( + NtCurrentThread(), + TOKEN_IMPERSONATE, + TRUE, + &OriginalTokenHandle); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + return NULL; + } + + NewToken = NULL; + + Status = NtSetInformationThread( + NtCurrentThread(), + ThreadImpersonationToken, + &NewToken, + sizeof(NewToken)); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + SafeClose(OriginalTokenHandle); + return NULL; + } + } else { + OriginalTokenHandle = NULL; + } + + InitializeObjectAttributes( + &ObjectAttributes, + &DirectoryName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtOpenDirectoryObject( + &DirectoryHandle, + DIRECTORY_ALL_ACCESS & ~(STANDARD_RIGHTS_REQUIRED), + &ObjectAttributes); + + ASSERT (NT_SUCCESS(Status)); + ASSERT (VALID_HANDLE(DirectoryHandle)); + + if (!NT_SUCCESS(Status)) { + DirectoryHandle = NULL; + } + + if (OriginalTokenHandle) { + Status = NtSetInformationThread( + NtCurrentThread(), + ThreadImpersonationToken, + &OriginalTokenHandle, + sizeof(OriginalTokenHandle)); + + ASSERT (NT_SUCCESS(Status)); + SafeClose(OriginalTokenHandle); + } + + return DirectoryHandle; +} + +HANDLE WINAPI BaseGetUntrustedNamedObjectDirectory( + VOID) +{ + NTSTATUS Status; + UNICODE_STRING DirectoryName; + OBJECT_ATTRIBUTES ObjectAttributes; + + if (KexData->UntrustedNamedObjects) { + return KexData->UntrustedNamedObjects; + } + + RtlInitConstantUnicodeString(&DirectoryName, L"Untrusted"); + InitializeObjectAttributes( + &ObjectAttributes, + &DirectoryName, + OBJ_CASE_INSENSITIVE | OBJ_OPENIF, + KexData->BaseNamedObjects, + NULL); + + Status = KexRtlCreateUntrustedDirectoryObject( + &KexData->UntrustedNamedObjects, + DIRECTORY_ALL_ACCESS & ~STANDARD_RIGHTS_REQUIRED, + &ObjectAttributes); + + ASSERT (NT_SUCCESS(Status)); + + return KexData->UntrustedNamedObjects; +} + +PVOID BaseGetBaseDllHandle( + VOID) +{ + NTSTATUS Status; + UNICODE_STRING Kernel32; + + if (KexData->BaseDllBase) { + return KexData->BaseDllBase; + } + + RtlInitConstantUnicodeString(&Kernel32, L"kernel32.dll"); + + Status = LdrGetDllHandleByName( + &Kernel32, + NULL, + &KexData->BaseDllBase); + + ASSERT (NT_SUCCESS(Status)); + ASSERT (KexData->BaseDllBase != NULL); + + if (!NT_SUCCESS(Status)) { + BaseSetLastNTError(Status); + return NULL; + } + + return KexData->BaseDllBase; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxBase/synch.c b/01-Extended DLLs/KxBase/synch.c new file mode 100644 index 0000000..5eba2f1 --- /dev/null +++ b/01-Extended DLLs/KxBase/synch.c @@ -0,0 +1,56 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// synch.c +// +// Abstract: +// +// Contains functions related to thread synchronization. +// +// Author: +// +// vxiiduu (11-Feb-2022) +// +// Environment: +// +// Win32 mode. +// +// Revision History: +// +// vxiiduu 11-Feb-2022 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kxbasep.h" + +// +// This function is a wrapper around (Kex)RtlWaitOnAddress. +// +KXBASEAPI BOOL WINAPI WaitOnAddress( + IN VOLATILE VOID *Address, + IN PVOID CompareAddress, + IN SIZE_T AddressSize, + IN DWORD Milliseconds OPTIONAL) +{ + NTSTATUS Status; + PLARGE_INTEGER TimeOutPointer; + LARGE_INTEGER TimeOut; + + TimeOutPointer = BaseFormatTimeOut(&TimeOut, Milliseconds); + + Status = KexRtlWaitOnAddress( + Address, + CompareAddress, + AddressSize, + TimeOutPointer); + + BaseSetLastNTError(Status); + + if (NT_SUCCESS(Status) && Status != STATUS_TIMEOUT) { + return TRUE; + } else { + return FALSE; + } +} \ No newline at end of file diff --git a/01-Extended DLLs/KxBase/thread.c b/01-Extended DLLs/KxBase/thread.c new file mode 100644 index 0000000..00ffa98 --- /dev/null +++ b/01-Extended DLLs/KxBase/thread.c @@ -0,0 +1,350 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// thread.c +// +// Abstract: +// +// Extended functions for dealing with threads. +// +// Author: +// +// vxiiduu (07-Nov-2022) +// +// Revision History: +// +// vxiiduu 07-Nov-2022 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kxbasep.h" + +// +// Retrieves the description that was assigned to a thread by calling +// SetThreadDescription. +// +// Parameters: +// +// ThreadHandle +// A handle to the thread for which to retrieve the description. The handle +// must have THREAD_QUERY_LIMITED_INFORMATION access. +// +// ThreadDescription +// A Unicode string that contains the description of the thread. +// +// Return value: +// +// If the function succeeds, the return value is the HRESULT that denotes a +// successful operation. If the function fails, the return value is an HRESULT +// that denotes the error. +// +// Remarks: +// +// The description for a thread can change at any time. For example, a different +// thread can change the description of a thread of interest while you try to +// retrieve that description. +// +// Thread descriptions do not need to be unique. +// +// To free the memory for the thread description, call the LocalFree method. +// +KXBASEAPI HRESULT WINAPI GetThreadDescription( + IN HANDLE ThreadHandle, + OUT PPWSTR ThreadDescription) +{ + NTSTATUS Status; + PUNICODE_STRING Description; + ULONG DescriptionCb; + + *ThreadDescription = NULL; + Description = NULL; + DescriptionCb = 64 * sizeof(WCHAR); + + // + // The thread description can be changed at any time by another + // thread. Therefore, we need to put the code in the loop in case + // the length changes. + // + + while (TRUE) { + Description = (PUNICODE_STRING) SafeAlloc(BYTE, DescriptionCb); + + if (!Description) { + Status = STATUS_NO_MEMORY; + break; + } + + Status = NtQueryInformationThread( + ThreadHandle, + ThreadNameInformation, + &Description, + DescriptionCb, + &DescriptionCb); + + // + // If the call succeeded, or if there was a failure caused by + // anything other than our buffer being too small, break out of + // the loop. + // + + if (Status != STATUS_INFO_LENGTH_MISMATCH && + Status != STATUS_BUFFER_TOO_SMALL && + Status != STATUS_BUFFER_OVERFLOW) { + break; + } + + SafeFree(Description); + } + + if (NT_SUCCESS(Status)) { + PWSTR ReturnDescription; + ULONG DescriptionCch; + + // + // Shift the buffer of the UNICODE_STRING backwards onto its + // base address, and make sure it's null terminated. + // + + ReturnDescription = (PWSTR) Description; + DescriptionCch = Description->Length / sizeof(WCHAR); + RtlMoveMemory(ReturnDescription, Description->Buffer, Description->Length); + ReturnDescription[DescriptionCch] = L'\0'; + + *ThreadDescription = ReturnDescription; + Description = NULL; + } + + SafeFree(Description); + return HRESULT_FROM_NT(Status); +} + +// +// Assigns a description to a thread. +// +// Parameters: +// +// ThreadHandle +// A handle for the thread for which you want to set the description. +// The handle must have THREAD_SET_LIMITED_INFORMATION access. +// +// ThreadDescription +// A Unicode string that specifies the description of the thread. +// +// Return value: +// +// If the function succeeds, the return value is the HRESULT that denotes +// a successful operation. If the function fails, the return value is an +// HRESULT that denotes the error. +// +// Remarks: +// +// The description of a thread can be set more than once; the most recently +// set value is used. You can retrieve the description of a thread by +// calling GetThreadDescription. +// +KXBASEAPI HRESULT WINAPI SetThreadDescription( + IN HANDLE ThreadHandle, + IN PCWSTR ThreadDescription) +{ + NTSTATUS Status; + UNICODE_STRING Description; + + Status = RtlInitUnicodeStringEx(&Description, ThreadDescription); + + if (NT_SUCCESS(Status)) { + Status = NtSetInformationThread( + ThreadHandle, + ThreadNameInformation, + &Description, + sizeof(Description)); + } + + return HRESULT_FROM_NT(Status); +} + +// +// This very simple function was introduced in Windows 8 as a documented way +// to query a few values out of the TEB. +// +KXBASEAPI VOID WINAPI GetCurrentThreadStackLimits( + OUT PULONG_PTR LowLimit, + OUT PULONG_PTR HighLimit) +{ + PTEB Teb; + + Teb = NtCurrentTeb(); + + *LowLimit = (ULONG_PTR) Teb->DeallocationStack; + *HighLimit = (ULONG_PTR) Teb->NtTib.StackBase; +} + +KXBASEAPI BOOL WINAPI SetThreadInformation( + IN HANDLE ThreadHandle, + IN THREAD_INFORMATION_CLASS ThreadInformationClass, + IN PVOID ThreadInformation, + IN ULONG ThreadInformationSize) +{ + NTSTATUS Status; + THREADINFOCLASS ThreadInformationClassNt; + THREAD_POWER_THROTTLING_STATE ThrottlingState; + + switch (ThreadInformationClass) { + case ThreadMemoryPriority: + ThreadInformationClassNt = ThreadPagePriority; + break; + case ThreadAbsoluteCpuPriority: + ThreadInformationClassNt = ThreadActualBasePriority; + break; + case ThreadDynamicCodePolicy: + ThreadInformationClassNt = ThreadDynamicCodePolicyInfo; + break; + case ThreadPowerThrottling: + ThreadInformationClassNt = ThreadPowerThrottlingState; + break; + default: + Status = STATUS_INVALID_PARAMETER; + goto Exit; + } + + if (ThreadInformationClass == ThreadPowerThrottling) { + if (ThreadInformationSize < sizeof(THREAD_POWER_THROTTLING_STATE)) { + Status = STATUS_INVALID_PARAMETER; + goto Exit; + } + + ThreadInformationSize = sizeof(THREAD_POWER_THROTTLING_STATE); + ThrottlingState = *(PTHREAD_POWER_THROTTLING_STATE) ThreadInformation; + + if (ThrottlingState.Version > 1 || + (ThrottlingState.ControlMask & 0xFFFFFFFE) != 0 || + (~ThrottlingState.ControlMask & ThrottlingState.StateMask) != 0) { + + Status = STATUS_INVALID_PARAMETER; + goto Exit; + } + + ThrottlingState.Version = 1; + + ThreadInformation = &ThrottlingState; + } + + Status = NtSetInformationThread( + ThreadHandle, + ThreadInformationClassNt, + ThreadInformation, + ThreadInformationSize); + +Exit: + if (!NT_SUCCESS(Status)) { + BaseSetLastNTError(Status); + } + + return NT_SUCCESS(Status); +} + +KXBASEAPI BOOL WINAPI GetThreadInformation( + IN HANDLE ThreadHandle, + IN THREAD_INFORMATION_CLASS ThreadInformationClass, + OUT PVOID ThreadInformation, + IN ULONG ThreadInformationSize) +{ + NTSTATUS Status; + THREADINFOCLASS ThreadInformationClassNt; + + switch (ThreadInformationClass) { + case ThreadMemoryPriority: + ThreadInformationClassNt = ThreadPagePriority; + break; + case ThreadAbsoluteCpuPriority: + ThreadInformationClassNt = ThreadActualBasePriority; + break; + case ThreadDynamicCodePolicy: + ThreadInformationClassNt = ThreadDynamicCodePolicyInfo; + break; + default: + Status = STATUS_INVALID_PARAMETER; + goto Exit; + } + + Status = NtQueryInformationThread( + ThreadHandle, + ThreadInformationClassNt, + ThreadInformation, + ThreadInformationSize, + NULL); + +Exit: + if (!NT_SUCCESS(Status)) { + BaseSetLastNTError(Status); + } + + return NT_SUCCESS(Status); +} + +KXBASEAPI BOOL WINAPI SetThreadSelectedCpuSets( + IN HANDLE ThreadHandle, + IN PULONG CpuSetIds, + IN ULONG NumberOfCpuSetIds) +{ + if (CpuSetIds == NULL) { + if (NumberOfCpuSetIds != 0) { + BaseSetLastNTError(STATUS_INVALID_PARAMETER); + return FALSE; + } + } + + return TRUE; +} + +KXBASEAPI BOOL WINAPI SetThreadSelectedCpuSetMasks( + IN HANDLE ThreadHandle, + IN PGROUP_AFFINITY CpuSetMasks, + IN ULONG NumberOfCpuSetMasks) +{ + if (CpuSetMasks == NULL) { + if (NumberOfCpuSetMasks != 0) { + BaseSetLastNTError(STATUS_INVALID_PARAMETER); + return FALSE; + } + } + + return TRUE; +} + +KXBASEAPI BOOL WINAPI GetThreadSelectedCpuSets( + IN HANDLE ThreadHandle, + OUT PULONG CpuSetIds, + IN ULONG CpuSetIdArraySize, + OUT PULONG ReturnCount) +{ + *ReturnCount = 0; + + if (CpuSetIds == NULL) { + if (CpuSetIdArraySize != 0) { + BaseSetLastNTError(STATUS_INVALID_PARAMETER); + return FALSE; + } + } + + return TRUE; +} + +KXBASEAPI BOOL WINAPI GetThreadSelectedCpuSetMasks( + IN HANDLE ThreadHandle, + OUT PGROUP_AFFINITY CpuSetMasks, + IN ULONG CpuSetMaskArraySize, + OUT PULONG ReturnCount) +{ + *ReturnCount = 0; + + if (CpuSetMasks == NULL) { + if (CpuSetMaskArraySize != 0) { + BaseSetLastNTError(STATUS_INVALID_PARAMETER); + return FALSE; + } + } + + return TRUE; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxBase/time.c b/01-Extended DLLs/KxBase/time.c new file mode 100644 index 0000000..e6b2b5e --- /dev/null +++ b/01-Extended DLLs/KxBase/time.c @@ -0,0 +1,65 @@ +#include "buildcfg.h" +#include "kxbasep.h" + +// +// If strong SharedUserData spoofing is enabled, this function +// supersedes KernelBase!GetSystemTimeAsFileTime because the original +// function reads system time from SharedUserData. +// +KXBASEAPI VOID WINAPI KxBasepGetSystemTimeAsFileTimeHook( + OUT PFILETIME SystemTimeAsFileTime) +{ + ASSERT (KexData->IfeoParameters.StrongVersionSpoof & KEX_STRONGSPOOF_SHAREDUSERDATA); + KexNtQuerySystemTime((PLONGLONG) SystemTimeAsFileTime); +} + +// +// Same as above but this function supersedes GetSystemTime when doing +// SharedUserData-based version spoofing. +// +KXBASEAPI VOID WINAPI KxBasepGetSystemTimeHook( + OUT PSYSTEMTIME SystemTime) +{ + LONGLONG Time; + TIME_FIELDS TimeFields; + + ASSERT (KexData->IfeoParameters.StrongVersionSpoof & KEX_STRONGSPOOF_SHAREDUSERDATA); + + KexNtQuerySystemTime(&Time); + RtlTimeToTimeFields(&Time, &TimeFields); + + // + // Annoyingly, the TIME_FIELDS structure is not directly compatible with + // the SYSTEMTIME structure... + // + + SystemTime->wYear = TimeFields.Year; + SystemTime->wMonth = TimeFields.Month; + SystemTime->wDay = TimeFields.Day; + SystemTime->wDayOfWeek = TimeFields.Weekday; + SystemTime->wHour = TimeFields.Hour; + SystemTime->wMinute = TimeFields.Minute; + SystemTime->wSecond = TimeFields.Second; + SystemTime->wMilliseconds = TimeFields.Milliseconds; +} + +KXBASEAPI VOID WINAPI GetSystemTimePreciseAsFileTime( + OUT PFILETIME SystemTimeAsFileTime) +{ + // + // The real NtQuerySystemTime export from NTDLL is actually just a jump to + // RtlQuerySystemTime, which reads from SharedUserData. + // + // However, if we are doing SharedUserData-based version spoofing, we will + // overwrite that stub function with KexNtQuerySystemTime, so it is the best + // of both worlds in terms of speed and actually working. + // + + NtQuerySystemTime((PLONGLONG) SystemTimeAsFileTime); +} + +KXBASEAPI VOID WINAPI QueryUnbiasedInterruptTimePrecise( + OUT PULONGLONG UnbiasedInterruptTimePrecise) +{ + QueryUnbiasedInterruptTime(UnbiasedInterruptTimePrecise); +} \ No newline at end of file diff --git a/01-Extended DLLs/KxBase/token.c b/01-Extended DLLs/KxBase/token.c new file mode 100644 index 0000000..1895c4a --- /dev/null +++ b/01-Extended DLLs/KxBase/token.c @@ -0,0 +1,19 @@ +#include "buildcfg.h" +#include "kxbasep.h" + +KXBASEAPI BOOL WINAPI Ext_SetTokenInformation( + IN HANDLE TokenHandle, + IN TOKEN_INFORMATION_CLASS TokenInformationClass, + IN PVOID TokenInformation, + IN ULONG TokenInformationLength) +{ + if (TokenInformationClass == TokenIntegrityLevel) { + return TRUE; + } + + return SetTokenInformation( + TokenHandle, + TokenInformationClass, + TokenInformation, + TokenInformationLength); +} \ No newline at end of file diff --git a/01-Extended DLLs/KxBase/verspoof.c b/01-Extended DLLs/KxBase/verspoof.c new file mode 100644 index 0000000..19f75d0 --- /dev/null +++ b/01-Extended DLLs/KxBase/verspoof.c @@ -0,0 +1,28 @@ +#include "buildcfg.h" +#include "kxbasep.h" +#include + +// +// Iertutil.dll contains a version check which will end up causing errors (failure +// to open files with ShellExecute including with shell context menus) if the reported +// OS version is higher than 6.1. +// +// This function un-spoofs the OS version for Windows DLLs, and preserves normal behavior +// for all other situations. +// + +KXBASEAPI BOOL WINAPI Ext_GetVersionExA( + IN OUT POSVERSIONINFOA VersionInfo) +{ + BOOL Success; + + Success = GetVersionExA(VersionInfo); + + if (Success && AshModuleIsWindowsModule(ReturnAddress())) { + VersionInfo->dwMajorVersion = 6; + VersionInfo->dwMinorVersion = 1; + VersionInfo->dwBuildNumber = 7601; + } + + return Success; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxBase/vmem.c b/01-Extended DLLs/KxBase/vmem.c new file mode 100644 index 0000000..0570b8e --- /dev/null +++ b/01-Extended DLLs/KxBase/vmem.c @@ -0,0 +1,453 @@ +#include "buildcfg.h" +#include "kxbasep.h" + +STATIC ULONG OfferVirtualMemoryInternal( + IN PVOID VirtualAddress, + IN SIZE_T Size, + IN OFFER_PRIORITY Priority, + IN BOOL DiscardMemory) +{ + NTSTATUS Status; + MEMORY_BASIC_INFORMATION BasicInformation; + PVOID VirtualAllocResult; + ULONG OldProtect; + + // + // Parameter validation. + // + + if (!VirtualAddress || !Size) { + return ERROR_INVALID_PARAMETER; + } + + if ((ULONG_PTR) VirtualAddress & 0xFFF) { + // The virtual address must be page-aligned. + return ERROR_INVALID_PARAMETER; + } + + if (Size & 0xFFF) { + // The size must be a multiple of the page size. + return ERROR_INVALID_PARAMETER; + } + + ASSERT (Priority && Priority < VMOfferPriorityMaximum); + + // + // Check to see if the memory region provided is valid. + // The entire region must be readable, writable, and committed. + // + + Status = NtQueryVirtualMemory( + NtCurrentProcess(), + VirtualAddress, + MemoryBasicInformation, + &BasicInformation, + sizeof(BasicInformation), + NULL); + + if (!NT_SUCCESS(Status)) { + return RtlNtStatusToDosError(Status); + } + + if (BasicInformation.RegionSize < Size || + BasicInformation.Protect != PAGE_READWRITE || + BasicInformation.State != MEM_COMMIT) { + + Status = STATUS_INVALID_PAGE_PROTECTION; + return RtlNtStatusToDosError(Status); + } + + // + // Tell the kernel that we won't be needing the contents of this memory + // anymore. + // + + VirtualAllocResult = VirtualAlloc( + VirtualAddress, + Size, + MEM_RESET, + PAGE_READWRITE); + + if (VirtualAllocResult != VirtualAddress) { + return GetLastError(); + } + + if (DiscardMemory) { + VirtualUnlock(VirtualAddress, Size); + } else { + // If OfferVirtualMemory was called, then make those pages + // inaccessible. + VirtualProtect(VirtualAddress, Size, PAGE_NOACCESS, &OldProtect); + } + + return ERROR_SUCCESS; +} + +KXBASEAPI ULONG WINAPI OfferVirtualMemory( + IN PVOID VirtualAddress, + IN SIZE_T Size, + IN OFFER_PRIORITY Priority) +{ + KexLogDebugEvent( + L"OfferVirtualMemory called\r\n\r\n" + L"VirtualAddress: 0x%p\r\n" + L"Size: %lu", + VirtualAddress, + Size); + + if (!Priority || Priority >= VMOfferPriorityMaximum) { + return ERROR_INVALID_PARAMETER; + } + + return OfferVirtualMemoryInternal(VirtualAddress, Size, Priority, FALSE); +} + +KXBASEAPI ULONG WINAPI DiscardVirtualMemory( + IN PVOID VirtualAddress, + IN SIZE_T Size) +{ + KexLogDebugEvent( + L"DiscardVirtualMemory called\r\n\r\n" + L"VirtualAddress: 0x%p\r\n" + L"Size: %lu", + VirtualAddress, + Size); + + return OfferVirtualMemoryInternal(VirtualAddress, Size, VMOfferPriorityVeryLow, TRUE); +} + +KXBASEAPI ULONG WINAPI ReclaimVirtualMemory( + IN PVOID VirtualAddress, + IN SIZE_T Size) +{ + NTSTATUS Status; + MEMORY_BASIC_INFORMATION BasicInformation; + ULONG OldProtect; + + KexLogDebugEvent( + L"ReclaimVirtualMemory called\r\n\r\n" + L"VirtualAddress: 0x%p\r\n" + L"Size: %lu", + VirtualAddress, + Size); + + if (!VirtualAddress || !Size) { + return ERROR_INVALID_PARAMETER; + } + + if ((ULONG_PTR) VirtualAddress & 0xFFF) { + // The virtual address must be page-aligned. + return ERROR_INVALID_PARAMETER; + } + + if (Size & 0xFFF) { + // The size must be a multiple of the page size. + return ERROR_INVALID_PARAMETER; + } + + // + // Check to see whether the memory region provided is valid. + // ReclaimVirtualMemory is only intended to be called as a counterpart + // to OfferVirtualMemory, so ensure the page protections and memory + // status are consistent with the intended usage. + // + + Status = NtQueryVirtualMemory( + NtCurrentProcess(), + VirtualAddress, + MemoryBasicInformation, + &BasicInformation, + sizeof(BasicInformation), + NULL); + + if (!NT_SUCCESS(Status)) { + return RtlNtStatusToDosError(Status); + } + + if (BasicInformation.RegionSize < Size || + BasicInformation.Protect != PAGE_NOACCESS || + BasicInformation.State != MEM_COMMIT) { + + Status = STATUS_INVALID_PAGE_PROTECTION; + return RtlNtStatusToDosError(Status); + } + + // + // Make the memory region accessible again. + // + + VirtualProtect(VirtualAddress, Size, PAGE_READWRITE, &OldProtect); + + // + // Since Windows 7 does not have the MEM_RESET_UNDO functionality, we + // will always return ERROR_BUSY here. + // + // In the future, if we find an application that responds poorly to this, + // we can add an app-specific hack that makes OfferVirtualMemory and + // ReclaimVirtualMemory a no-op for that application. + // + + return ERROR_BUSY; +} + +KXBASEAPI BOOL WINAPI PrefetchVirtualMemory( + IN HANDLE ProcessHandle, + IN ULONG_PTR NumberOfEntries, + IN PWIN32_MEMORY_RANGE_ENTRY VirtualAddresses, + IN ULONG Flags) +{ + // + // This function is a no-op. + // + + BaseSetLastNTError(STATUS_NOT_IMPLEMENTED); + return FALSE; +} + +KXBASEAPI HANDLE WINAPI CreateFileMappingFromApp( + IN HANDLE FileHandle, + IN LPSECURITY_ATTRIBUTES SecurityAttributes, + IN ULONG PageProtection, + IN ULONGLONG MaximumSize, + IN PCWSTR Name OPTIONAL) +{ + return CreateFileMappingW( + FileHandle, + SecurityAttributes, + PageProtection, + HIDWORD(MaximumSize), + LODWORD(MaximumSize), + Name); +} + +KXBASEAPI PVOID WINAPI MapViewOfFileFromApp( + IN HANDLE SectionHandle, + IN ULONG DesiredAccess, + IN ULONGLONG FileOffset, + IN SIZE_T FileMappingSize) +{ + if ((DesiredAccess & FILE_MAP_EXECUTE) && + (DesiredAccess & (FILE_MAP_COPY | FILE_MAP_WRITE))) { + + RtlSetLastWin32Error(ERROR_INVALID_PARAMETER); + return NULL; + } + + return MapViewOfFile( + SectionHandle, + DesiredAccess, + HIDWORD(FileOffset), + LODWORD(FileOffset), + FileMappingSize); +} + +KXBASEAPI PVOID WINAPI VirtualAllocFromApp( + IN PVOID Address OPTIONAL, + IN SIZE_T Size, + IN ULONG AllocationType, + IN ULONG PageProtection) +{ + if (PageProtection & (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)) { + RtlSetLastWin32Error(ERROR_INVALID_PARAMETER); + return NULL; + } + + return VirtualAlloc(Address, Size, AllocationType, PageProtection); +} + +KXBASEAPI BOOL WINAPI VirtualProtectFromApp( + IN PVOID Address, + IN SIZE_T Size, + IN ULONG NewPageProtection, + OUT PULONG OldProtect) +{ + return VirtualProtect(Address, Size, NewPageProtection, OldProtect); +} + +KXBASEAPI HANDLE WINAPI OpenFileMappingFromApp( + IN ULONG DesiredAccess, + IN BOOL InheritableHandle, + IN PCWSTR Name) +{ + // Limit boolean value to TRUE and FALSE only. + unless (InheritableHandle == TRUE || InheritableHandle == FALSE) { + RtlSetLastWin32Error(ERROR_INVALID_PARAMETER); + return NULL; + } + + return OpenFileMapping(DesiredAccess, InheritableHandle, Name); +} + +KXBASEAPI PVOID WINAPI MapViewOfFileNuma2( + IN HANDLE SectionHandle, + IN HANDLE ProcessHandle, + IN ULONGLONG Offset, + IN PVOID BaseAddress OPTIONAL, + IN SIZE_T ViewSize, + IN ULONG AllocationType, + IN ULONG PageProtection, + IN ULONG PreferredNumaNode) +{ + NTSTATUS Status; + + if (AllocationType & ~(MEM_LARGE_PAGES | MEM_TOP_DOWN | MEM_RESERVE | MEM_ROTATE)) { + RtlSetLastWin32Error(ERROR_INVALID_PARAMETER); + return NULL; + } + + if (PreferredNumaNode != NUMA_NO_PREFERRED_NODE && PreferredNumaNode >= 64) { + RtlSetLastWin32Error(ERROR_INVALID_PARAMETER); + return NULL; + } + + Status = NtMapViewOfSection( + SectionHandle, + ProcessHandle, + &BaseAddress, + 0, + 0, + (PLONGLONG) &Offset, + &ViewSize, + ViewShare, + AllocationType | (PreferredNumaNode + 1), + PageProtection); + + if (!NT_SUCCESS(Status)) { + BaseSetLastNTError(Status); + return NULL; + } + + return BaseAddress; +} + +KXBASEAPI BOOL WINAPI UnmapViewOfFile2( + IN HANDLE ProcessHandle, + IN PVOID BaseAddress, + IN ULONG UnmapFlags) +{ + NTSTATUS Status; + + if (UnmapFlags) { + KexLogWarningEvent(L"UnmapViewOfFile2 called with flags: 0x%08lx", UnmapFlags); + + if (UnmapFlags & ~MEM_UNMAP_VALID_FLAGS) { + BaseSetLastNTError(STATUS_INVALID_PARAMETER); + return FALSE; + } + } + + Status = NtUnmapViewOfSection(ProcessHandle, BaseAddress); + if (!NT_SUCCESS(Status)) { + BaseSetLastNTError(Status); + return FALSE; + } + + return TRUE; +} + +KXBASEAPI BOOL WINAPI UnmapViewOfFileEx( + IN PVOID BaseAddress, + IN ULONG UnmapFlags) +{ + return UnmapViewOfFile2(NtCurrentProcess(), BaseAddress, UnmapFlags); +} + +KXBASEAPI PVOID WINAPI MapViewOfFile3( + IN HANDLE SectionHandle, + IN HANDLE ProcessHandle OPTIONAL, + IN PVOID BaseAddress OPTIONAL, + IN ULONGLONG Offset, + IN SIZE_T ViewSize, + IN ULONG AllocationType, + IN ULONG PageProtection, + IN OUT MEM_EXTENDED_PARAMETER *ExtendedParameters OPTIONAL, + IN ULONG ParameterCount) +{ + NTSTATUS Status; + ULONG PreferredNumaNode; + + PreferredNumaNode = NUMA_NO_PREFERRED_NODE; + + if (AllocationType & ~(MEM_REPLACE_PLACEHOLDER | MEM_LARGE_PAGES | MEM_TOP_DOWN | MEM_RESERVE | MEM_ROTATE)) { + BaseSetLastNTError(STATUS_INVALID_PARAMETER); + return NULL; + } + + if (ExtendedParameters) { + ULONG Index; + + for (Index = 0; Index < ParameterCount; ++Index) { + switch (ExtendedParameters[Index].Type) { + case MemExtendedParameterAddressRequirements: + // TODO: Unimplemented. It's possible to do this but I couldn't + // be bothered at the moment especially since the implementation + // for this will be moved to kernel mode later on anyway. + KexLogWarningEvent(L"Address requirements were specified to MapViewOfFile3"); + BaseSetLastNTError(STATUS_INVALID_PARAMETER); + return NULL; + case MemExtendedParameterNumaNode: + PreferredNumaNode = ExtendedParameters[Index].ULong; + break; + default: + BaseSetLastNTError(STATUS_INVALID_PARAMETER); + return NULL; + } + } + } + + if (ProcessHandle == NULL) { + ProcessHandle = NtCurrentProcess(); + } + + Status = NtMapViewOfSection( + SectionHandle, + ProcessHandle, + &BaseAddress, + 0, + 0, + (PLONGLONG) &Offset, + &ViewSize, + ViewShare, + AllocationType | (PreferredNumaNode + 1), + PageProtection); + + if (!NT_SUCCESS(Status)) { + BaseSetLastNTError(Status); + return NULL; + } + + return BaseAddress; +} + +KXBASEAPI PVOID WINAPI MapViewOfFile3FromApp( + IN HANDLE SectionHandle, + IN HANDLE ProcessHandle OPTIONAL, + IN PVOID BaseAddress OPTIONAL, + IN ULONGLONG Offset, + IN SIZE_T ViewSize, + IN ULONG AllocationType, + IN ULONG PageProtection, + IN OUT MEM_EXTENDED_PARAMETER *ExtendedParameters OPTIONAL, + IN ULONG ParameterCount) +{ + if (PageProtection & (PAGE_EXECUTE_WRITECOPY | PAGE_EXECUTE_READWRITE)) { + RtlSetLastWin32Error(ERROR_INVALID_PARAMETER); + return NULL; + } + + if (BaseAddress != NULL && (AllocationType & MEM_REPLACE_PLACEHOLDER)) { + RtlSetLastWin32Error(ERROR_INVALID_PARAMETER); + return NULL; + } + + return MapViewOfFile3( + SectionHandle, + ProcessHandle, + BaseAddress, + Offset, + ViewSize, + AllocationType, + PageProtection, + ExtendedParameters, + ParameterCount); +} \ No newline at end of file diff --git a/01-Extended DLLs/KxBase/wow64.c b/01-Extended DLLs/KxBase/wow64.c new file mode 100644 index 0000000..0eb415c --- /dev/null +++ b/01-Extended DLLs/KxBase/wow64.c @@ -0,0 +1,19 @@ +#include "buildcfg.h" +#include "kxbasep.h" + +KXBASEAPI BOOL WINAPI IsWow64Process2( + IN HANDLE ProcessHandle, + OUT PUSHORT ProcessMachine, + OUT PUSHORT NativeMachine) +{ + NTSTATUS Status; + + Status = KexRtlWow64GetProcessMachines(ProcessHandle, ProcessMachine, NativeMachine); + + if (!NT_SUCCESS(Status)) { + BaseSetLastNTError(Status); + return FALSE; + } + + return TRUE; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxCom/KxCom.rc b/01-Extended DLLs/KxCom/KxCom.rc new file mode 100644 index 0000000..e0c3ada Binary files /dev/null and b/01-Extended DLLs/KxCom/KxCom.rc differ diff --git a/01-Extended DLLs/KxCom/KxCom.vcxproj b/01-Extended DLLs/KxCom/KxCom.vcxproj new file mode 100644 index 0000000..eefc138 --- /dev/null +++ b/01-Extended DLLs/KxCom/KxCom.vcxproj @@ -0,0 +1,262 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {A5627E7A-6C18-4D04-A7DE-5445F39E1CAB} + Win32Proj + KxCom + + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + + + + + + + + + + + + + + + + + false + false + + + false + false + + + false + false + + + false + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;KXCOM_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + false + false + Default + false + StdCall + CompileAsC + + + Windows + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + DllMain + true + kxcom.def + /ignore:4104 %(AdditionalOptions) + urlmon.dll;shell32.dll + + + $(SolutionDir)\00-Common Headers + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;KXCOM_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + false + false + Default + false + StdCall + CompileAsC + + + Windows + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + DllMain + true + kxcom.def + /ignore:4104 %(AdditionalOptions) + urlmon.dll;shell32.dll + + + $(SolutionDir)\00-Common Headers + + + + + Level3 + + + MinSpace + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;KXCOM_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + false + false + Default + false + StdCall + CompileAsC + OnlyExplicitInline + Size + true + + + Windows + true + true + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + DllMain + true + kxcom.def + /ignore:4104 %(AdditionalOptions) + urlmon.dll;shell32.dll + + + $(SolutionDir)\00-Common Headers + + + + + Level3 + + + MinSpace + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;KXCOM_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + false + false + Default + false + StdCall + CompileAsC + OnlyExplicitInline + Size + true + + + Windows + true + true + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + DllMain + true + kxcom.def + /ignore:4104 %(AdditionalOptions) + urlmon.dll;shell32.dll + + + $(SolutionDir)\00-Common Headers + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/01-Extended DLLs/KxCom/KxCom.vcxproj.filters b/01-Extended DLLs/KxCom/KxCom.vcxproj.filters new file mode 100644 index 0000000..486f93d --- /dev/null +++ b/01-Extended DLLs/KxCom/KxCom.vcxproj.filters @@ -0,0 +1,85 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/01-Extended DLLs/KxCom/actfact.c b/01-Extended DLLs/KxCom/actfact.c new file mode 100644 index 0000000..f1b6ccc --- /dev/null +++ b/01-Extended DLLs/KxCom/actfact.c @@ -0,0 +1,145 @@ +#include "buildcfg.h" +#include "kxcomp.h" + +// +// Implements the IActivationFactory interface that is returned by +// RoGetActivationFactory. +// + +KXCOMAPI HRESULT STDMETHODCALLTYPE CActivationFactory_QueryInterface( + IN IActivationFactory *This, + IN REFIID RefIID, + OUT PPVOID Object) +{ + LPOLESTR RefIIDAsString; + + ASSERT (This != NULL); + ASSERT (RefIID != NULL); + ASSERT (Object != NULL); + + if (KexIsDebugBuild) { + StringFromIID(RefIID, &RefIIDAsString); + } + + *Object = NULL; + + if (IsEqualIID(RefIID, &IID_IUnknown) || + IsEqualIID(RefIID, &IID_IAgileObject) || + IsEqualIID(RefIID, &IID_IInspectable) || + IsEqualIID(RefIID, &IID_IActivationFactory)) { + + *Object = This; + } else if (IsEqualIID(RefIID, &IID_IGlobalizationPreferencesStatics)) { + *Object = &CGlobalizationPreferencesStatics; + } else if (IsEqualIID(RefIID, &IID_IUIViewSettingsInterop)) { + *Object = &CUIViewSettingsInterop; + } else if (IsEqualIID(RefIID, &IID_IUIViewSettings)) { + *Object = &CUIViewSettings; + } else if (IsEqualIID(RefIID, &IID_IUISettings)) { + *Object = &CUISettings; + } else if (IsEqualIID(RefIID, &IID_IUISettings3)) { + *Object = &CUISettings3; + } else if (IsEqualIID(RefIID, &IID_IUriRuntimeClassFactory)) { + *Object = &CUriRuntimeClassFactory; + } else if (IsEqualIID(RefIID, &IID_ILauncherStatics)) { + *Object = &CLauncherStatics; + } else { + if (!KexIsDebugBuild) { + StringFromIID(RefIID, &RefIIDAsString); + } + + KexLogWarningEvent( + L"The Windows Runtime activation factory was queried for an unsupported interface.\r\n\r\n" + L"IID: %s", + RefIIDAsString); + + CoTaskMemFree(RefIIDAsString); + return E_NOINTERFACE; + } + + if (KexIsDebugBuild) { + KexLogDebugEvent(L"WinRT activation factory queried: %s", RefIIDAsString); + CoTaskMemFree(RefIIDAsString); + } + + return S_OK; +} + +KXCOMAPI ULONG STDMETHODCALLTYPE CActivationFactory_AddRef( + IN IActivationFactory *This) +{ + return 1; +} + +KXCOMAPI ULONG STDMETHODCALLTYPE CActivationFactory_Release( + IN IActivationFactory *This) +{ + return 1; +} + +KXCOMAPI HRESULT STDMETHODCALLTYPE CActivationFactory_GetIids( + IN IActivationFactory *This, + OUT PULONG NumberOfIids, + OUT IID **IidArray) +{ + IID *Array; + ULONG Count; + + ASSERT (NumberOfIids != NULL); + ASSERT (IidArray != NULL); + + Count = 1; + + Array = (IID *) CoTaskMemAlloc(Count * sizeof(IID)); + if (!Array) { + return E_OUTOFMEMORY; + } + + *NumberOfIids = Count; + Array[0] = IID_IActivationFactory; + + return S_OK; +} + +KXCOMAPI HRESULT STDMETHODCALLTYPE CActivationFactory_GetRuntimeClassName( + IN IActivationFactory *This, + OUT HSTRING *ClassName) +{ + PCWSTR Name = L"IActivationFactory"; + ASSERT (ClassName != NULL); + return WindowsCreateString(Name, (ULONG) wcslen(Name), ClassName); +} + +KXCOMAPI HRESULT STDMETHODCALLTYPE CActivationFactory_GetTrustLevel( + IN IActivationFactory *This, + OUT TrustLevel *Level) +{ + ASSERT (Level != NULL); + *Level = BaseTrust; + return S_OK; +} + +KXCOMAPI HRESULT STDMETHODCALLTYPE CActivationFactory_ActivateInstance( + IN IActivationFactory *This, + OUT IInspectable **Object) +{ + ASSERT (This != NULL); + ASSERT (Object != NULL); + + *Object = (IInspectable *) This; + return S_OK; +} + +IActivationFactoryVtbl CActivationFactoryVtbl = { + CActivationFactory_QueryInterface, + CActivationFactory_AddRef, + CActivationFactory_Release, + CActivationFactory_GetIids, + CActivationFactory_GetRuntimeClassName, + CActivationFactory_GetTrustLevel, + CActivationFactory_ActivateInstance +}; + +IActivationFactory CActivationFactory = { + &CActivationFactoryVtbl +}; \ No newline at end of file diff --git a/01-Extended DLLs/KxCom/buildcfg.h b/01-Extended DLLs/KxCom/buildcfg.h new file mode 100644 index 0000000..acb70d1 --- /dev/null +++ b/01-Extended DLLs/KxCom/buildcfg.h @@ -0,0 +1,41 @@ +#define KXCOMAPI + +#define WIN32_LEAN_AND_MEAN +#define NOGDICAPMASKS +#define NOVIRTUALKEYCODES +#define NOWINSTYLES +#define NOMENUS +#define NOICONS +#define NOKEYSTATES +#define NOSYSCOMMANDS +#define NORASTEROPS +#define NOATOM +#define NOCLIPBOARD +#define NODRAWTEXT +#define NOKERNEL +#define NOMB +#define NOMEMMGR +#define NOOPENFILE +#define NOSCROLL +#define NOTEXTMETRIC +#define NOWH +#define NOWINOFFSETS +#define NOCOMM +#define NOKANJI +#define NOHELP +#define NOPROFILER +#define NODEFERWINDOWPOS +#define NOMCX +#define NOCRYPT +#define NOMETAFILE +#define NOSERVICE +#define NOSOUND +#define _UXTHEME_H_ + +#pragma comment(lib, "ole32.lib") +#pragma comment(lib, "oleaut32.lib") +#pragma comment(lib, "urlmon.lib") + +#define KEX_ENV_WIN32 +#define KEX_TARGET_TYPE_DLL +#define KEX_COMPONENT L"KxCom" diff --git a/01-Extended DLLs/KxCom/dllmain.c b/01-Extended DLLs/KxCom/dllmain.c new file mode 100644 index 0000000..51703a7 --- /dev/null +++ b/01-Extended DLLs/KxCom/dllmain.c @@ -0,0 +1,21 @@ +#define KXCOM_WANT_INITGUID + +#include "buildcfg.h" +#include "kxcomp.h" + +PKEX_PROCESS_DATA KexData; + +BOOL WINAPI DllMain( + IN PVOID DllBase, + IN ULONG Reason, + IN PCONTEXT Context) +{ + if (Reason == DLL_PROCESS_ATTACH) { + LdrDisableThreadCalloutsForDll(DllBase); + + KexDataInitialize(&KexData); + KexLogDebugEvent(L"DllMain called with DLL_PROCESS_ATTACH"); + } + + return TRUE; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxCom/forwards.c b/01-Extended DLLs/KxCom/forwards.c new file mode 100644 index 0000000..738c03b --- /dev/null +++ b/01-Extended DLLs/KxCom/forwards.c @@ -0,0 +1,473 @@ +// +// The following section contains OLE32.DLL exports that are present in both +// 32-bit and 64-bit versions of the DLL. +// + +#pragma comment(linker, "/EXPORT:BindMoniker=ole32.BindMoniker") +#pragma comment(linker, "/EXPORT:CLIPFORMAT_UserFree=ole32.CLIPFORMAT_UserFree") +#pragma comment(linker, "/EXPORT:CLIPFORMAT_UserMarshal=ole32.CLIPFORMAT_UserMarshal") +#pragma comment(linker, "/EXPORT:CLIPFORMAT_UserSize=ole32.CLIPFORMAT_UserSize") +#pragma comment(linker, "/EXPORT:CLIPFORMAT_UserUnmarshal=ole32.CLIPFORMAT_UserUnmarshal") +#pragma comment(linker, "/EXPORT:CLSIDFromOle1Class=ole32.CLSIDFromOle1Class") +#pragma comment(linker, "/EXPORT:CLSIDFromProgID=ole32.CLSIDFromProgID") +#pragma comment(linker, "/EXPORT:CLSIDFromProgIDEx=ole32.CLSIDFromProgIDEx") +#pragma comment(linker, "/EXPORT:CLSIDFromString=ole32.CLSIDFromString") +#pragma comment(linker, "/EXPORT:CoAddRefServerProcess=ole32.CoAddRefServerProcess") +#pragma comment(linker, "/EXPORT:CoAllowSetForegroundWindow=ole32.CoAllowSetForegroundWindow") +#pragma comment(linker, "/EXPORT:CoBuildVersion=ole32.CoBuildVersion") +#pragma comment(linker, "/EXPORT:CoCancelCall=ole32.CoCancelCall") +#pragma comment(linker, "/EXPORT:CoCopyProxy=ole32.CoCopyProxy") +#pragma comment(linker, "/EXPORT:CoCreateFreeThreadedMarshaler=ole32.CoCreateFreeThreadedMarshaler") +#pragma comment(linker, "/EXPORT:CoCreateGuid=ole32.CoCreateGuid") +#pragma comment(linker, "/EXPORT:CoCreateInstance=ole32.CoCreateInstance") +#pragma comment(linker, "/EXPORT:CoCreateInstanceEx=ole32.CoCreateInstanceEx") +#pragma comment(linker, "/EXPORT:CoCreateObjectInContext=ole32.CoCreateObjectInContext") +#pragma comment(linker, "/EXPORT:CoDeactivateObject=ole32.CoDeactivateObject") +#pragma comment(linker, "/EXPORT:CoDisableCallCancellation=ole32.CoDisableCallCancellation") +#pragma comment(linker, "/EXPORT:CoDisconnectContext=ole32.CoDisconnectContext") +#pragma comment(linker, "/EXPORT:CoDisconnectObject=ole32.CoDisconnectObject") +#pragma comment(linker, "/EXPORT:CoDosDateTimeToFileTime=ole32.CoDosDateTimeToFileTime") +#pragma comment(linker, "/EXPORT:CoEnableCallCancellation=ole32.CoEnableCallCancellation") +#pragma comment(linker, "/EXPORT:CoFileTimeNow=ole32.CoFileTimeNow") +#pragma comment(linker, "/EXPORT:CoFileTimeToDosDateTime=ole32.CoFileTimeToDosDateTime") +#pragma comment(linker, "/EXPORT:CoFreeAllLibraries=ole32.CoFreeAllLibraries") +#pragma comment(linker, "/EXPORT:CoFreeLibrary=ole32.CoFreeLibrary") +#pragma comment(linker, "/EXPORT:CoFreeUnusedLibraries=ole32.CoFreeUnusedLibraries") +#pragma comment(linker, "/EXPORT:CoFreeUnusedLibrariesEx=ole32.CoFreeUnusedLibrariesEx") +#pragma comment(linker, "/EXPORT:CoGetActivationState=ole32.CoGetActivationState") +#pragma comment(linker, "/EXPORT:CoGetApartmentID=ole32.CoGetApartmentID") +#pragma comment(linker, "/EXPORT:CoGetApartmentType=ole32.CoGetApartmentType") +#pragma comment(linker, "/EXPORT:CoGetCallContext=ole32.CoGetCallContext") +#pragma comment(linker, "/EXPORT:CoGetCallState=ole32.CoGetCallState") +#pragma comment(linker, "/EXPORT:CoGetCallerTID=ole32.CoGetCallerTID") +#pragma comment(linker, "/EXPORT:CoGetCancelObject=ole32.CoGetCancelObject") +#pragma comment(linker, "/EXPORT:CoGetClassObject=ole32.CoGetClassObject") +#pragma comment(linker, "/EXPORT:CoGetClassVersion=ole32.CoGetClassVersion") +#pragma comment(linker, "/EXPORT:CoGetComCatalog=ole32.CoGetComCatalog") +#pragma comment(linker, "/EXPORT:CoGetContextToken=ole32.CoGetContextToken") +#pragma comment(linker, "/EXPORT:CoGetCurrentLogicalThreadId=ole32.CoGetCurrentLogicalThreadId") +#pragma comment(linker, "/EXPORT:CoGetCurrentProcess=ole32.CoGetCurrentProcess") +#pragma comment(linker, "/EXPORT:CoGetDefaultContext=ole32.CoGetDefaultContext") +#pragma comment(linker, "/EXPORT:CoGetInstanceFromFile=ole32.CoGetInstanceFromFile") +#pragma comment(linker, "/EXPORT:CoGetInstanceFromIStorage=ole32.CoGetInstanceFromIStorage") +#pragma comment(linker, "/EXPORT:CoGetInterceptor=ole32.CoGetInterceptor") +#pragma comment(linker, "/EXPORT:CoGetInterceptorFromTypeInfo=ole32.CoGetInterceptorFromTypeInfo") +#pragma comment(linker, "/EXPORT:CoGetInterfaceAndReleaseStream=ole32.CoGetInterfaceAndReleaseStream") +#pragma comment(linker, "/EXPORT:CoGetMalloc=ole32.CoGetMalloc") +#pragma comment(linker, "/EXPORT:CoGetMarshalSizeMax=ole32.CoGetMarshalSizeMax") +#pragma comment(linker, "/EXPORT:CoGetModuleType=ole32.CoGetModuleType") +#pragma comment(linker, "/EXPORT:CoGetObject=ole32.CoGetObject") +#pragma comment(linker, "/EXPORT:CoGetObjectContext=ole32.CoGetObjectContext") +#pragma comment(linker, "/EXPORT:CoGetPSClsid=ole32.CoGetPSClsid") +#pragma comment(linker, "/EXPORT:CoGetProcessIdentifier=ole32.CoGetProcessIdentifier") +#pragma comment(linker, "/EXPORT:CoGetStandardMarshal=ole32.CoGetStandardMarshal") +#pragma comment(linker, "/EXPORT:CoGetStdMarshalEx=ole32.CoGetStdMarshalEx") +#pragma comment(linker, "/EXPORT:CoGetSystemSecurityPermissions=ole32.CoGetSystemSecurityPermissions") +#pragma comment(linker, "/EXPORT:CoGetTreatAsClass=ole32.CoGetTreatAsClass") +#pragma comment(linker, "/EXPORT:CoImpersonateClient=ole32.CoImpersonateClient") +#pragma comment(linker, "/EXPORT:CoInitialize=ole32.CoInitialize") +#pragma comment(linker, "/EXPORT:CoInitializeEx=ole32.CoInitializeEx") +#pragma comment(linker, "/EXPORT:CoInitializeSecurity=ole32.CoInitializeSecurity") +#pragma comment(linker, "/EXPORT:CoInitializeWOW=ole32.CoInitializeWOW") +#pragma comment(linker, "/EXPORT:CoInstall=ole32.CoInstall") +#pragma comment(linker, "/EXPORT:CoInvalidateRemoteMachineBindings=ole32.CoInvalidateRemoteMachineBindings") +#pragma comment(linker, "/EXPORT:CoIsHandlerConnected=ole32.CoIsHandlerConnected") +#pragma comment(linker, "/EXPORT:CoIsOle1Class=ole32.CoIsOle1Class") +#pragma comment(linker, "/EXPORT:CoLoadLibrary=ole32.CoLoadLibrary") +#pragma comment(linker, "/EXPORT:CoLockObjectExternal=ole32.CoLockObjectExternal") +#pragma comment(linker, "/EXPORT:CoMarshalHresult=ole32.CoMarshalHresult") +#pragma comment(linker, "/EXPORT:CoMarshalInterThreadInterfaceInStream=ole32.CoMarshalInterThreadInterfaceInStream") +#pragma comment(linker, "/EXPORT:CoMarshalInterface=ole32.CoMarshalInterface") +#pragma comment(linker, "/EXPORT:CoPopServiceDomain=ole32.CoPopServiceDomain") +#pragma comment(linker, "/EXPORT:CoPushServiceDomain=ole32.CoPushServiceDomain") +#pragma comment(linker, "/EXPORT:CoQueryAuthenticationServices=ole32.CoQueryAuthenticationServices") +#pragma comment(linker, "/EXPORT:CoQueryClientBlanket=ole32.CoQueryClientBlanket") +#pragma comment(linker, "/EXPORT:CoQueryProxyBlanket=ole32.CoQueryProxyBlanket") +#pragma comment(linker, "/EXPORT:CoQueryReleaseObject=ole32.CoQueryReleaseObject") +#pragma comment(linker, "/EXPORT:CoReactivateObject=ole32.CoReactivateObject") +#pragma comment(linker, "/EXPORT:CoRegisterActivationFilter=ole32.CoRegisterActivationFilter") +#pragma comment(linker, "/EXPORT:CoRegisterChannelHook=ole32.CoRegisterChannelHook") +#pragma comment(linker, "/EXPORT:CoRegisterClassObject=ole32.CoRegisterClassObject") +#pragma comment(linker, "/EXPORT:CoRegisterInitializeSpy=ole32.CoRegisterInitializeSpy") +#pragma comment(linker, "/EXPORT:CoRegisterMallocSpy=ole32.CoRegisterMallocSpy") +#pragma comment(linker, "/EXPORT:CoRegisterMessageFilter=ole32.CoRegisterMessageFilter") +#pragma comment(linker, "/EXPORT:CoRegisterPSClsid=ole32.CoRegisterPSClsid") +#pragma comment(linker, "/EXPORT:CoRegisterSurrogate=ole32.CoRegisterSurrogate") +#pragma comment(linker, "/EXPORT:CoRegisterSurrogateEx=ole32.CoRegisterSurrogateEx") +#pragma comment(linker, "/EXPORT:CoReleaseMarshalData=ole32.CoReleaseMarshalData") +#pragma comment(linker, "/EXPORT:CoReleaseServerProcess=ole32.CoReleaseServerProcess") +#pragma comment(linker, "/EXPORT:CoResumeClassObjects=ole32.CoResumeClassObjects") +#pragma comment(linker, "/EXPORT:CoRetireServer=ole32.CoRetireServer") +#pragma comment(linker, "/EXPORT:CoRevertToSelf=ole32.CoRevertToSelf") +#pragma comment(linker, "/EXPORT:CoRevokeClassObject=ole32.CoRevokeClassObject") +#pragma comment(linker, "/EXPORT:CoRevokeInitializeSpy=ole32.CoRevokeInitializeSpy") +#pragma comment(linker, "/EXPORT:CoRevokeMallocSpy=ole32.CoRevokeMallocSpy") +#pragma comment(linker, "/EXPORT:CoSetCancelObject=ole32.CoSetCancelObject") +#pragma comment(linker, "/EXPORT:CoSetProxyBlanket=ole32.CoSetProxyBlanket") +#pragma comment(linker, "/EXPORT:CoSetState=ole32.CoSetState") +#pragma comment(linker, "/EXPORT:CoSuspendClassObjects=ole32.CoSuspendClassObjects") +#pragma comment(linker, "/EXPORT:CoSwitchCallContext=ole32.CoSwitchCallContext") +#pragma comment(linker, "/EXPORT:CoTaskMemAlloc=ole32.CoTaskMemAlloc") +#pragma comment(linker, "/EXPORT:CoTaskMemFree=ole32.CoTaskMemFree") +#pragma comment(linker, "/EXPORT:CoTaskMemRealloc=ole32.CoTaskMemRealloc") +#pragma comment(linker, "/EXPORT:CoTestCancel=ole32.CoTestCancel") +#pragma comment(linker, "/EXPORT:CoTreatAsClass=ole32.CoTreatAsClass") +#pragma comment(linker, "/EXPORT:CoUninitialize=ole32.CoUninitialize") +#pragma comment(linker, "/EXPORT:CoUnloadingWOW=ole32.CoUnloadingWOW") +#pragma comment(linker, "/EXPORT:CoUnmarshalHresult=ole32.CoUnmarshalHresult") +#pragma comment(linker, "/EXPORT:CoUnmarshalInterface=ole32.CoUnmarshalInterface") +#pragma comment(linker, "/EXPORT:CoVrfCheckThreadState=ole32.CoVrfCheckThreadState") +#pragma comment(linker, "/EXPORT:CoVrfGetThreadState=ole32.CoVrfGetThreadState") +#pragma comment(linker, "/EXPORT:CoVrfReleaseThreadState=ole32.CoVrfReleaseThreadState") +#pragma comment(linker, "/EXPORT:CoWaitForMultipleHandles=ole32.CoWaitForMultipleHandles") +#pragma comment(linker, "/EXPORT:ComPs_NdrDllCanUnloadNow=ole32.ComPs_NdrDllCanUnloadNow") +#pragma comment(linker, "/EXPORT:ComPs_NdrDllGetClassObject=ole32.ComPs_NdrDllGetClassObject") +#pragma comment(linker, "/EXPORT:ComPs_NdrDllRegisterProxy=ole32.ComPs_NdrDllRegisterProxy") +#pragma comment(linker, "/EXPORT:ComPs_NdrDllUnregisterProxy=ole32.ComPs_NdrDllUnregisterProxy") +#pragma comment(linker, "/EXPORT:CreateAntiMoniker=ole32.CreateAntiMoniker") +#pragma comment(linker, "/EXPORT:CreateBindCtx=ole32.CreateBindCtx") +#pragma comment(linker, "/EXPORT:CreateClassMoniker=ole32.CreateClassMoniker") +#pragma comment(linker, "/EXPORT:CreateDataAdviseHolder=ole32.CreateDataAdviseHolder") +#pragma comment(linker, "/EXPORT:CreateDataCache=ole32.CreateDataCache") +#pragma comment(linker, "/EXPORT:CreateErrorInfo=ole32.CreateErrorInfo") +#pragma comment(linker, "/EXPORT:CreateFileMoniker=ole32.CreateFileMoniker") +#pragma comment(linker, "/EXPORT:CreateGenericComposite=ole32.CreateGenericComposite") +#pragma comment(linker, "/EXPORT:CreateILockBytesOnHGlobal=ole32.CreateILockBytesOnHGlobal") +#pragma comment(linker, "/EXPORT:CreateItemMoniker=ole32.CreateItemMoniker") +#pragma comment(linker, "/EXPORT:CreateObjrefMoniker=ole32.CreateObjrefMoniker") +#pragma comment(linker, "/EXPORT:CreateOleAdviseHolder=ole32.CreateOleAdviseHolder") +#pragma comment(linker, "/EXPORT:CreatePointerMoniker=ole32.CreatePointerMoniker") +#pragma comment(linker, "/EXPORT:CreateStdProgressIndicator=ole32.CreateStdProgressIndicator") +#pragma comment(linker, "/EXPORT:CreateStreamOnHGlobal=ole32.CreateStreamOnHGlobal") +#pragma comment(linker, "/EXPORT:DcomChannelSetHResult=ole32.DcomChannelSetHResult") +#pragma comment(linker, "/EXPORT:DllDebugObjectRPCHook=ole32.DllDebugObjectRPCHook") +#pragma comment(linker, "/EXPORT:DllGetClassObject=ole32.DllGetClassObject") +#pragma comment(linker, "/EXPORT:DllGetClassObjectWOW=ole32.DllGetClassObjectWOW") +#pragma comment(linker, "/EXPORT:DllRegisterServer=ole32.DllRegisterServer") +#pragma comment(linker, "/EXPORT:DoDragDrop=ole32.DoDragDrop") +#pragma comment(linker, "/EXPORT:EnableHookObject=ole32.EnableHookObject") +#pragma comment(linker, "/EXPORT:FmtIdToPropStgName=ole32.FmtIdToPropStgName") +#pragma comment(linker, "/EXPORT:FreePropVariantArray=ole32.FreePropVariantArray") +#pragma comment(linker, "/EXPORT:GetClassFile=ole32.GetClassFile") +#pragma comment(linker, "/EXPORT:GetConvertStg=ole32.GetConvertStg") +#pragma comment(linker, "/EXPORT:GetDocumentBitStg=ole32.GetDocumentBitStg") +#pragma comment(linker, "/EXPORT:GetErrorInfo=ole32.GetErrorInfo") +#pragma comment(linker, "/EXPORT:GetHGlobalFromILockBytes=ole32.GetHGlobalFromILockBytes") +#pragma comment(linker, "/EXPORT:GetHGlobalFromStream=ole32.GetHGlobalFromStream") +#pragma comment(linker, "/EXPORT:GetHookInterface=ole32.GetHookInterface") +#pragma comment(linker, "/EXPORT:GetRunningObjectTable=ole32.GetRunningObjectTable") +#pragma comment(linker, "/EXPORT:HACCEL_UserFree=ole32.HACCEL_UserFree") +#pragma comment(linker, "/EXPORT:HACCEL_UserMarshal=ole32.HACCEL_UserMarshal") +#pragma comment(linker, "/EXPORT:HACCEL_UserSize=ole32.HACCEL_UserSize") +#pragma comment(linker, "/EXPORT:HACCEL_UserUnmarshal=ole32.HACCEL_UserUnmarshal") +#pragma comment(linker, "/EXPORT:HBITMAP_UserFree=ole32.HBITMAP_UserFree") +#pragma comment(linker, "/EXPORT:HBITMAP_UserMarshal=ole32.HBITMAP_UserMarshal") +#pragma comment(linker, "/EXPORT:HBITMAP_UserSize=ole32.HBITMAP_UserSize") +#pragma comment(linker, "/EXPORT:HBITMAP_UserUnmarshal=ole32.HBITMAP_UserUnmarshal") +#pragma comment(linker, "/EXPORT:HBRUSH_UserFree=ole32.HBRUSH_UserFree") +#pragma comment(linker, "/EXPORT:HBRUSH_UserMarshal=ole32.HBRUSH_UserMarshal") +#pragma comment(linker, "/EXPORT:HBRUSH_UserSize=ole32.HBRUSH_UserSize") +#pragma comment(linker, "/EXPORT:HBRUSH_UserUnmarshal=ole32.HBRUSH_UserUnmarshal") +#pragma comment(linker, "/EXPORT:HDC_UserFree=ole32.HDC_UserFree") +#pragma comment(linker, "/EXPORT:HDC_UserMarshal=ole32.HDC_UserMarshal") +#pragma comment(linker, "/EXPORT:HDC_UserSize=ole32.HDC_UserSize") +#pragma comment(linker, "/EXPORT:HDC_UserUnmarshal=ole32.HDC_UserUnmarshal") +#pragma comment(linker, "/EXPORT:HENHMETAFILE_UserFree=ole32.HENHMETAFILE_UserFree") +#pragma comment(linker, "/EXPORT:HENHMETAFILE_UserMarshal=ole32.HENHMETAFILE_UserMarshal") +#pragma comment(linker, "/EXPORT:HENHMETAFILE_UserSize=ole32.HENHMETAFILE_UserSize") +#pragma comment(linker, "/EXPORT:HENHMETAFILE_UserUnmarshal=ole32.HENHMETAFILE_UserUnmarshal") +#pragma comment(linker, "/EXPORT:HGLOBAL_UserFree=ole32.HGLOBAL_UserFree") +#pragma comment(linker, "/EXPORT:HGLOBAL_UserMarshal=ole32.HGLOBAL_UserMarshal") +#pragma comment(linker, "/EXPORT:HGLOBAL_UserSize=ole32.HGLOBAL_UserSize") +#pragma comment(linker, "/EXPORT:HGLOBAL_UserUnmarshal=ole32.HGLOBAL_UserUnmarshal") +#pragma comment(linker, "/EXPORT:HICON_UserFree=ole32.HICON_UserFree") +#pragma comment(linker, "/EXPORT:HICON_UserMarshal=ole32.HICON_UserMarshal") +#pragma comment(linker, "/EXPORT:HICON_UserSize=ole32.HICON_UserSize") +#pragma comment(linker, "/EXPORT:HICON_UserUnmarshal=ole32.HICON_UserUnmarshal") +#pragma comment(linker, "/EXPORT:HMENU_UserFree=ole32.HMENU_UserFree") +#pragma comment(linker, "/EXPORT:HMENU_UserMarshal=ole32.HMENU_UserMarshal") +#pragma comment(linker, "/EXPORT:HMENU_UserSize=ole32.HMENU_UserSize") +#pragma comment(linker, "/EXPORT:HMENU_UserUnmarshal=ole32.HMENU_UserUnmarshal") +#pragma comment(linker, "/EXPORT:HMETAFILEPICT_UserFree=ole32.HMETAFILEPICT_UserFree") +#pragma comment(linker, "/EXPORT:HMETAFILEPICT_UserMarshal=ole32.HMETAFILEPICT_UserMarshal") +#pragma comment(linker, "/EXPORT:HMETAFILEPICT_UserSize=ole32.HMETAFILEPICT_UserSize") +#pragma comment(linker, "/EXPORT:HMETAFILEPICT_UserUnmarshal=ole32.HMETAFILEPICT_UserUnmarshal") +#pragma comment(linker, "/EXPORT:HMETAFILE_UserFree=ole32.HMETAFILE_UserFree") +#pragma comment(linker, "/EXPORT:HMETAFILE_UserMarshal=ole32.HMETAFILE_UserMarshal") +#pragma comment(linker, "/EXPORT:HMETAFILE_UserSize=ole32.HMETAFILE_UserSize") +#pragma comment(linker, "/EXPORT:HMETAFILE_UserUnmarshal=ole32.HMETAFILE_UserUnmarshal") +#pragma comment(linker, "/EXPORT:HPALETTE_UserFree=ole32.HPALETTE_UserFree") +#pragma comment(linker, "/EXPORT:HPALETTE_UserMarshal=ole32.HPALETTE_UserMarshal") +#pragma comment(linker, "/EXPORT:HPALETTE_UserSize=ole32.HPALETTE_UserSize") +#pragma comment(linker, "/EXPORT:HPALETTE_UserUnmarshal=ole32.HPALETTE_UserUnmarshal") +#pragma comment(linker, "/EXPORT:HRGN_UserFree=ole32.HRGN_UserFree") +#pragma comment(linker, "/EXPORT:HRGN_UserMarshal=ole32.HRGN_UserMarshal") +#pragma comment(linker, "/EXPORT:HRGN_UserSize=ole32.HRGN_UserSize") +#pragma comment(linker, "/EXPORT:HRGN_UserUnmarshal=ole32.HRGN_UserUnmarshal") +#pragma comment(linker, "/EXPORT:HWND_UserFree=ole32.HWND_UserFree") +#pragma comment(linker, "/EXPORT:HWND_UserMarshal=ole32.HWND_UserMarshal") +#pragma comment(linker, "/EXPORT:HWND_UserSize=ole32.HWND_UserSize") +#pragma comment(linker, "/EXPORT:HWND_UserUnmarshal=ole32.HWND_UserUnmarshal") +#pragma comment(linker, "/EXPORT:HkOleRegisterObject=ole32.HkOleRegisterObject") +#pragma comment(linker, "/EXPORT:IIDFromString=ole32.IIDFromString") +#pragma comment(linker, "/EXPORT:IsAccelerator=ole32.IsAccelerator") +#pragma comment(linker, "/EXPORT:IsEqualGUID=ole32.IsEqualGUID") +#pragma comment(linker, "/EXPORT:IsValidIid=ole32.IsValidIid") +#pragma comment(linker, "/EXPORT:IsValidInterface=ole32.IsValidInterface") +#pragma comment(linker, "/EXPORT:IsValidPtrIn=ole32.IsValidPtrIn") +#pragma comment(linker, "/EXPORT:IsValidPtrOut=ole32.IsValidPtrOut") +#pragma comment(linker, "/EXPORT:MkParseDisplayName=ole32.MkParseDisplayName") +#pragma comment(linker, "/EXPORT:MonikerCommonPrefixWith=ole32.MonikerCommonPrefixWith") +#pragma comment(linker, "/EXPORT:MonikerRelativePathTo=ole32.MonikerRelativePathTo") +#pragma comment(linker, "/EXPORT:NdrOleInitializeExtension=ole32.NdrOleInitializeExtension") +#pragma comment(linker, "/EXPORT:NdrProxyForwardingFunction10=ole32.NdrProxyForwardingFunction10") +#pragma comment(linker, "/EXPORT:NdrProxyForwardingFunction11=ole32.NdrProxyForwardingFunction11") +#pragma comment(linker, "/EXPORT:NdrProxyForwardingFunction12=ole32.NdrProxyForwardingFunction12") +#pragma comment(linker, "/EXPORT:NdrProxyForwardingFunction13=ole32.NdrProxyForwardingFunction13") +#pragma comment(linker, "/EXPORT:NdrProxyForwardingFunction14=ole32.NdrProxyForwardingFunction14") +#pragma comment(linker, "/EXPORT:NdrProxyForwardingFunction15=ole32.NdrProxyForwardingFunction15") +#pragma comment(linker, "/EXPORT:NdrProxyForwardingFunction16=ole32.NdrProxyForwardingFunction16") +#pragma comment(linker, "/EXPORT:NdrProxyForwardingFunction17=ole32.NdrProxyForwardingFunction17") +#pragma comment(linker, "/EXPORT:NdrProxyForwardingFunction18=ole32.NdrProxyForwardingFunction18") +#pragma comment(linker, "/EXPORT:NdrProxyForwardingFunction19=ole32.NdrProxyForwardingFunction19") +#pragma comment(linker, "/EXPORT:NdrProxyForwardingFunction20=ole32.NdrProxyForwardingFunction20") +#pragma comment(linker, "/EXPORT:NdrProxyForwardingFunction21=ole32.NdrProxyForwardingFunction21") +#pragma comment(linker, "/EXPORT:NdrProxyForwardingFunction22=ole32.NdrProxyForwardingFunction22") +#pragma comment(linker, "/EXPORT:NdrProxyForwardingFunction23=ole32.NdrProxyForwardingFunction23") +#pragma comment(linker, "/EXPORT:NdrProxyForwardingFunction24=ole32.NdrProxyForwardingFunction24") +#pragma comment(linker, "/EXPORT:NdrProxyForwardingFunction25=ole32.NdrProxyForwardingFunction25") +#pragma comment(linker, "/EXPORT:NdrProxyForwardingFunction26=ole32.NdrProxyForwardingFunction26") +#pragma comment(linker, "/EXPORT:NdrProxyForwardingFunction27=ole32.NdrProxyForwardingFunction27") +#pragma comment(linker, "/EXPORT:NdrProxyForwardingFunction28=ole32.NdrProxyForwardingFunction28") +#pragma comment(linker, "/EXPORT:NdrProxyForwardingFunction29=ole32.NdrProxyForwardingFunction29") +#pragma comment(linker, "/EXPORT:NdrProxyForwardingFunction3=ole32.NdrProxyForwardingFunction3") +#pragma comment(linker, "/EXPORT:NdrProxyForwardingFunction30=ole32.NdrProxyForwardingFunction30") +#pragma comment(linker, "/EXPORT:NdrProxyForwardingFunction31=ole32.NdrProxyForwardingFunction31") +#pragma comment(linker, "/EXPORT:NdrProxyForwardingFunction32=ole32.NdrProxyForwardingFunction32") +#pragma comment(linker, "/EXPORT:NdrProxyForwardingFunction4=ole32.NdrProxyForwardingFunction4") +#pragma comment(linker, "/EXPORT:NdrProxyForwardingFunction5=ole32.NdrProxyForwardingFunction5") +#pragma comment(linker, "/EXPORT:NdrProxyForwardingFunction6=ole32.NdrProxyForwardingFunction6") +#pragma comment(linker, "/EXPORT:NdrProxyForwardingFunction7=ole32.NdrProxyForwardingFunction7") +#pragma comment(linker, "/EXPORT:NdrProxyForwardingFunction8=ole32.NdrProxyForwardingFunction8") +#pragma comment(linker, "/EXPORT:NdrProxyForwardingFunction9=ole32.NdrProxyForwardingFunction9") +#pragma comment(linker, "/EXPORT:ObjectStublessClient10=ole32.ObjectStublessClient10") +#pragma comment(linker, "/EXPORT:ObjectStublessClient11=ole32.ObjectStublessClient11") +#pragma comment(linker, "/EXPORT:ObjectStublessClient12=ole32.ObjectStublessClient12") +#pragma comment(linker, "/EXPORT:ObjectStublessClient13=ole32.ObjectStublessClient13") +#pragma comment(linker, "/EXPORT:ObjectStublessClient14=ole32.ObjectStublessClient14") +#pragma comment(linker, "/EXPORT:ObjectStublessClient15=ole32.ObjectStublessClient15") +#pragma comment(linker, "/EXPORT:ObjectStublessClient16=ole32.ObjectStublessClient16") +#pragma comment(linker, "/EXPORT:ObjectStublessClient17=ole32.ObjectStublessClient17") +#pragma comment(linker, "/EXPORT:ObjectStublessClient18=ole32.ObjectStublessClient18") +#pragma comment(linker, "/EXPORT:ObjectStublessClient19=ole32.ObjectStublessClient19") +#pragma comment(linker, "/EXPORT:ObjectStublessClient20=ole32.ObjectStublessClient20") +#pragma comment(linker, "/EXPORT:ObjectStublessClient21=ole32.ObjectStublessClient21") +#pragma comment(linker, "/EXPORT:ObjectStublessClient22=ole32.ObjectStublessClient22") +#pragma comment(linker, "/EXPORT:ObjectStublessClient23=ole32.ObjectStublessClient23") +#pragma comment(linker, "/EXPORT:ObjectStublessClient24=ole32.ObjectStublessClient24") +#pragma comment(linker, "/EXPORT:ObjectStublessClient25=ole32.ObjectStublessClient25") +#pragma comment(linker, "/EXPORT:ObjectStublessClient26=ole32.ObjectStublessClient26") +#pragma comment(linker, "/EXPORT:ObjectStublessClient27=ole32.ObjectStublessClient27") +#pragma comment(linker, "/EXPORT:ObjectStublessClient28=ole32.ObjectStublessClient28") +#pragma comment(linker, "/EXPORT:ObjectStublessClient29=ole32.ObjectStublessClient29") +#pragma comment(linker, "/EXPORT:ObjectStublessClient3=ole32.ObjectStublessClient3") +#pragma comment(linker, "/EXPORT:ObjectStublessClient30=ole32.ObjectStublessClient30") +#pragma comment(linker, "/EXPORT:ObjectStublessClient31=ole32.ObjectStublessClient31") +#pragma comment(linker, "/EXPORT:ObjectStublessClient32=ole32.ObjectStublessClient32") +#pragma comment(linker, "/EXPORT:ObjectStublessClient4=ole32.ObjectStublessClient4") +#pragma comment(linker, "/EXPORT:ObjectStublessClient5=ole32.ObjectStublessClient5") +#pragma comment(linker, "/EXPORT:ObjectStublessClient6=ole32.ObjectStublessClient6") +#pragma comment(linker, "/EXPORT:ObjectStublessClient7=ole32.ObjectStublessClient7") +#pragma comment(linker, "/EXPORT:ObjectStublessClient8=ole32.ObjectStublessClient8") +#pragma comment(linker, "/EXPORT:ObjectStublessClient9=ole32.ObjectStublessClient9") +#pragma comment(linker, "/EXPORT:OleBuildVersion=ole32.OleBuildVersion") +#pragma comment(linker, "/EXPORT:OleConvertIStorageToOLESTREAM=ole32.OleConvertIStorageToOLESTREAM") +#pragma comment(linker, "/EXPORT:OleConvertIStorageToOLESTREAMEx=ole32.OleConvertIStorageToOLESTREAMEx") +#pragma comment(linker, "/EXPORT:OleConvertOLESTREAMToIStorage=ole32.OleConvertOLESTREAMToIStorage") +#pragma comment(linker, "/EXPORT:OleConvertOLESTREAMToIStorageEx=ole32.OleConvertOLESTREAMToIStorageEx") +#pragma comment(linker, "/EXPORT:OleCreate=ole32.OleCreate") +#pragma comment(linker, "/EXPORT:OleCreateDefaultHandler=ole32.OleCreateDefaultHandler") +#pragma comment(linker, "/EXPORT:OleCreateEmbeddingHelper=ole32.OleCreateEmbeddingHelper") +#pragma comment(linker, "/EXPORT:OleCreateEx=ole32.OleCreateEx") +#pragma comment(linker, "/EXPORT:OleCreateFromData=ole32.OleCreateFromData") +#pragma comment(linker, "/EXPORT:OleCreateFromDataEx=ole32.OleCreateFromDataEx") +#pragma comment(linker, "/EXPORT:OleCreateFromFile=ole32.OleCreateFromFile") +#pragma comment(linker, "/EXPORT:OleCreateFromFileEx=ole32.OleCreateFromFileEx") +#pragma comment(linker, "/EXPORT:OleCreateLink=ole32.OleCreateLink") +#pragma comment(linker, "/EXPORT:OleCreateLinkEx=ole32.OleCreateLinkEx") +#pragma comment(linker, "/EXPORT:OleCreateLinkFromData=ole32.OleCreateLinkFromData") +#pragma comment(linker, "/EXPORT:OleCreateLinkFromDataEx=ole32.OleCreateLinkFromDataEx") +#pragma comment(linker, "/EXPORT:OleCreateLinkToFile=ole32.OleCreateLinkToFile") +#pragma comment(linker, "/EXPORT:OleCreateLinkToFileEx=ole32.OleCreateLinkToFileEx") +#pragma comment(linker, "/EXPORT:OleCreateMenuDescriptor=ole32.OleCreateMenuDescriptor") +#pragma comment(linker, "/EXPORT:OleCreateStaticFromData=ole32.OleCreateStaticFromData") +#pragma comment(linker, "/EXPORT:OleDestroyMenuDescriptor=ole32.OleDestroyMenuDescriptor") +#pragma comment(linker, "/EXPORT:OleDoAutoConvert=ole32.OleDoAutoConvert") +#pragma comment(linker, "/EXPORT:OleDraw=ole32.OleDraw") +#pragma comment(linker, "/EXPORT:OleDuplicateData=ole32.OleDuplicateData") +#pragma comment(linker, "/EXPORT:OleFlushClipboard=ole32.OleFlushClipboard") +#pragma comment(linker, "/EXPORT:OleGetAutoConvert=ole32.OleGetAutoConvert") +#pragma comment(linker, "/EXPORT:OleGetClipboard=ole32.OleGetClipboard") +#pragma comment(linker, "/EXPORT:OleGetIconOfClass=ole32.OleGetIconOfClass") +#pragma comment(linker, "/EXPORT:OleGetIconOfFile=ole32.OleGetIconOfFile") +#pragma comment(linker, "/EXPORT:OleInitialize=ole32.OleInitialize") +#pragma comment(linker, "/EXPORT:OleInitializeWOW=ole32.OleInitializeWOW") +#pragma comment(linker, "/EXPORT:OleIsCurrentClipboard=ole32.OleIsCurrentClipboard") +#pragma comment(linker, "/EXPORT:OleIsRunning=ole32.OleIsRunning") +#pragma comment(linker, "/EXPORT:OleLoad=ole32.OleLoad") +#pragma comment(linker, "/EXPORT:OleLoadFromStream=ole32.OleLoadFromStream") +#pragma comment(linker, "/EXPORT:OleLockRunning=ole32.OleLockRunning") +#pragma comment(linker, "/EXPORT:OleMetafilePictFromIconAndLabel=ole32.OleMetafilePictFromIconAndLabel") +#pragma comment(linker, "/EXPORT:OleNoteObjectVisible=ole32.OleNoteObjectVisible") +#pragma comment(linker, "/EXPORT:OleQueryCreateFromData=ole32.OleQueryCreateFromData") +#pragma comment(linker, "/EXPORT:OleQueryLinkFromData=ole32.OleQueryLinkFromData") +#pragma comment(linker, "/EXPORT:OleRegEnumFormatEtc=ole32.OleRegEnumFormatEtc") +#pragma comment(linker, "/EXPORT:OleRegEnumVerbs=ole32.OleRegEnumVerbs") +#pragma comment(linker, "/EXPORT:OleRegGetMiscStatus=ole32.OleRegGetMiscStatus") +#pragma comment(linker, "/EXPORT:OleRegGetUserType=ole32.OleRegGetUserType") +#pragma comment(linker, "/EXPORT:OleRun=ole32.OleRun") +#pragma comment(linker, "/EXPORT:OleSave=ole32.OleSave") +#pragma comment(linker, "/EXPORT:OleSaveToStream=ole32.OleSaveToStream") +#pragma comment(linker, "/EXPORT:OleSetAutoConvert=ole32.OleSetAutoConvert") +#pragma comment(linker, "/EXPORT:OleSetClipboard=ole32.OleSetClipboard") +#pragma comment(linker, "/EXPORT:OleSetContainedObject=ole32.OleSetContainedObject") +#pragma comment(linker, "/EXPORT:OleSetMenuDescriptor=ole32.OleSetMenuDescriptor") +#pragma comment(linker, "/EXPORT:OleTranslateAccelerator=ole32.OleTranslateAccelerator") +#pragma comment(linker, "/EXPORT:OleUninitialize=ole32.OleUninitialize") +#pragma comment(linker, "/EXPORT:OpenOrCreateStream=ole32.OpenOrCreateStream") +#pragma comment(linker, "/EXPORT:ProgIDFromCLSID=ole32.ProgIDFromCLSID") +#pragma comment(linker, "/EXPORT:PropStgNameToFmtId=ole32.PropStgNameToFmtId") +#pragma comment(linker, "/EXPORT:PropSysAllocString=ole32.PropSysAllocString") +#pragma comment(linker, "/EXPORT:PropSysFreeString=ole32.PropSysFreeString") +#pragma comment(linker, "/EXPORT:PropVariantChangeType=ole32.PropVariantChangeType") +#pragma comment(linker, "/EXPORT:PropVariantClear=ole32.PropVariantClear") +#pragma comment(linker, "/EXPORT:PropVariantCopy=ole32.PropVariantCopy") +#pragma comment(linker, "/EXPORT:ReadClassStg=ole32.ReadClassStg") +#pragma comment(linker, "/EXPORT:ReadClassStm=ole32.ReadClassStm") +#pragma comment(linker, "/EXPORT:ReadFmtUserTypeStg=ole32.ReadFmtUserTypeStg") +#pragma comment(linker, "/EXPORT:ReadOleStg=ole32.ReadOleStg") +#pragma comment(linker, "/EXPORT:ReadStringStream=ole32.ReadStringStream") +#pragma comment(linker, "/EXPORT:RegisterDragDrop=ole32.RegisterDragDrop") +#pragma comment(linker, "/EXPORT:ReleaseStgMedium=ole32.ReleaseStgMedium") +#pragma comment(linker, "/EXPORT:RevokeDragDrop=ole32.RevokeDragDrop") +#pragma comment(linker, "/EXPORT:SNB_UserFree=ole32.SNB_UserFree") +#pragma comment(linker, "/EXPORT:SNB_UserMarshal=ole32.SNB_UserMarshal") +#pragma comment(linker, "/EXPORT:SNB_UserSize=ole32.SNB_UserSize") +#pragma comment(linker, "/EXPORT:SNB_UserUnmarshal=ole32.SNB_UserUnmarshal") +#pragma comment(linker, "/EXPORT:STGMEDIUM_UserFree=ole32.STGMEDIUM_UserFree") +#pragma comment(linker, "/EXPORT:STGMEDIUM_UserMarshal=ole32.STGMEDIUM_UserMarshal") +#pragma comment(linker, "/EXPORT:STGMEDIUM_UserSize=ole32.STGMEDIUM_UserSize") +#pragma comment(linker, "/EXPORT:STGMEDIUM_UserUnmarshal=ole32.STGMEDIUM_UserUnmarshal") +#pragma comment(linker, "/EXPORT:SetConvertStg=ole32.SetConvertStg") +#pragma comment(linker, "/EXPORT:SetDocumentBitStg=ole32.SetDocumentBitStg") +#pragma comment(linker, "/EXPORT:SetErrorInfo=ole32.SetErrorInfo") +#pragma comment(linker, "/EXPORT:StgConvertPropertyToVariant=ole32.StgConvertPropertyToVariant") +#pragma comment(linker, "/EXPORT:StgConvertVariantToProperty=ole32.StgConvertVariantToProperty") +#pragma comment(linker, "/EXPORT:StgCreateDocfile=ole32.StgCreateDocfile") +#pragma comment(linker, "/EXPORT:StgCreateDocfileOnILockBytes=ole32.StgCreateDocfileOnILockBytes") +#pragma comment(linker, "/EXPORT:StgCreatePropSetStg=ole32.StgCreatePropSetStg") +#pragma comment(linker, "/EXPORT:StgCreatePropStg=ole32.StgCreatePropStg") +#pragma comment(linker, "/EXPORT:StgCreateStorageEx=ole32.StgCreateStorageEx") +#pragma comment(linker, "/EXPORT:StgGetIFillLockBytesOnFile=ole32.StgGetIFillLockBytesOnFile") +#pragma comment(linker, "/EXPORT:StgGetIFillLockBytesOnILockBytes=ole32.StgGetIFillLockBytesOnILockBytes") +#pragma comment(linker, "/EXPORT:StgIsStorageFile=ole32.StgIsStorageFile") +#pragma comment(linker, "/EXPORT:StgIsStorageILockBytes=ole32.StgIsStorageILockBytes") +#pragma comment(linker, "/EXPORT:StgOpenAsyncDocfileOnIFillLockBytes=ole32.StgOpenAsyncDocfileOnIFillLockBytes") +#pragma comment(linker, "/EXPORT:StgOpenPropStg=ole32.StgOpenPropStg") +#pragma comment(linker, "/EXPORT:StgOpenStorage=ole32.StgOpenStorage") +#pragma comment(linker, "/EXPORT:StgOpenStorageEx=ole32.StgOpenStorageEx") +#pragma comment(linker, "/EXPORT:StgOpenStorageOnHandle=ole32.StgOpenStorageOnHandle") +#pragma comment(linker, "/EXPORT:StgOpenStorageOnILockBytes=ole32.StgOpenStorageOnILockBytes") +#pragma comment(linker, "/EXPORT:StgPropertyLengthAsVariant=ole32.StgPropertyLengthAsVariant") +#pragma comment(linker, "/EXPORT:StgSetTimes=ole32.StgSetTimes") +#pragma comment(linker, "/EXPORT:StringFromCLSID=ole32.StringFromCLSID") +#pragma comment(linker, "/EXPORT:StringFromGUID2=ole32.StringFromGUID2") +#pragma comment(linker, "/EXPORT:StringFromIID=ole32.StringFromIID") +#pragma comment(linker, "/EXPORT:UpdateDCOMSettings=ole32.UpdateDCOMSettings") +#pragma comment(linker, "/EXPORT:UpdateProcessTracing=ole32.UpdateProcessTracing") +#pragma comment(linker, "/EXPORT:UtConvertDvtd16toDvtd32=ole32.UtConvertDvtd16toDvtd32") +#pragma comment(linker, "/EXPORT:UtConvertDvtd32toDvtd16=ole32.UtConvertDvtd32toDvtd16") +#pragma comment(linker, "/EXPORT:UtGetDvtd16Info=ole32.UtGetDvtd16Info") +#pragma comment(linker, "/EXPORT:UtGetDvtd32Info=ole32.UtGetDvtd32Info") +#pragma comment(linker, "/EXPORT:WdtpInterfacePointer_UserFree=ole32.WdtpInterfacePointer_UserFree") +#pragma comment(linker, "/EXPORT:WdtpInterfacePointer_UserMarshal=ole32.WdtpInterfacePointer_UserMarshal") +#pragma comment(linker, "/EXPORT:WdtpInterfacePointer_UserSize=ole32.WdtpInterfacePointer_UserSize") +#pragma comment(linker, "/EXPORT:WdtpInterfacePointer_UserUnmarshal=ole32.WdtpInterfacePointer_UserUnmarshal") +#pragma comment(linker, "/EXPORT:WriteClassStg=ole32.WriteClassStg") +#pragma comment(linker, "/EXPORT:WriteClassStm=ole32.WriteClassStm") +#pragma comment(linker, "/EXPORT:WriteFmtUserTypeStg=ole32.WriteFmtUserTypeStg") +#pragma comment(linker, "/EXPORT:WriteOleStg=ole32.WriteOleStg") +#pragma comment(linker, "/EXPORT:WriteStringStream=ole32.WriteStringStream") + +#ifdef _M_X64 +// +// The following section contains OLE32.DLL exports that are only present in +// the 64-bit version of the DLL. +// + +#pragma comment(linker, "/EXPORT:CLIPFORMAT_UserFree64=ole32.CLIPFORMAT_UserFree64") +#pragma comment(linker, "/EXPORT:CLIPFORMAT_UserMarshal64=ole32.CLIPFORMAT_UserMarshal64") +#pragma comment(linker, "/EXPORT:CLIPFORMAT_UserSize64=ole32.CLIPFORMAT_UserSize64") +#pragma comment(linker, "/EXPORT:CLIPFORMAT_UserUnmarshal64=ole32.CLIPFORMAT_UserUnmarshal64") +#pragma comment(linker, "/EXPORT:HACCEL_UserFree64=ole32.HACCEL_UserFree64") +#pragma comment(linker, "/EXPORT:HACCEL_UserMarshal64=ole32.HACCEL_UserMarshal64") +#pragma comment(linker, "/EXPORT:HACCEL_UserSize64=ole32.HACCEL_UserSize64") +#pragma comment(linker, "/EXPORT:HACCEL_UserUnmarshal64=ole32.HACCEL_UserUnmarshal64") +#pragma comment(linker, "/EXPORT:HBITMAP_UserFree64=ole32.HBITMAP_UserFree64") +#pragma comment(linker, "/EXPORT:HBITMAP_UserMarshal64=ole32.HBITMAP_UserMarshal64") +#pragma comment(linker, "/EXPORT:HBITMAP_UserSize64=ole32.HBITMAP_UserSize64") +#pragma comment(linker, "/EXPORT:HBITMAP_UserUnmarshal64=ole32.HBITMAP_UserUnmarshal64") +#pragma comment(linker, "/EXPORT:HBRUSH_UserFree64=ole32.HBRUSH_UserFree64") +#pragma comment(linker, "/EXPORT:HBRUSH_UserMarshal64=ole32.HBRUSH_UserMarshal64") +#pragma comment(linker, "/EXPORT:HBRUSH_UserSize64=ole32.HBRUSH_UserSize64") +#pragma comment(linker, "/EXPORT:HBRUSH_UserUnmarshal64=ole32.HBRUSH_UserUnmarshal64") +#pragma comment(linker, "/EXPORT:HDC_UserFree64=ole32.HDC_UserFree64") +#pragma comment(linker, "/EXPORT:HDC_UserMarshal64=ole32.HDC_UserMarshal64") +#pragma comment(linker, "/EXPORT:HDC_UserSize64=ole32.HDC_UserSize64") +#pragma comment(linker, "/EXPORT:HDC_UserUnmarshal64=ole32.HDC_UserUnmarshal64") +#pragma comment(linker, "/EXPORT:HENHMETAFILE_UserFree64=ole32.HENHMETAFILE_UserFree64") +#pragma comment(linker, "/EXPORT:HENHMETAFILE_UserMarshal64=ole32.HENHMETAFILE_UserMarshal64") +#pragma comment(linker, "/EXPORT:HENHMETAFILE_UserSize64=ole32.HENHMETAFILE_UserSize64") +#pragma comment(linker, "/EXPORT:HENHMETAFILE_UserUnmarshal64=ole32.HENHMETAFILE_UserUnmarshal64") +#pragma comment(linker, "/EXPORT:HGLOBAL_UserFree64=ole32.HGLOBAL_UserFree64") +#pragma comment(linker, "/EXPORT:HGLOBAL_UserMarshal64=ole32.HGLOBAL_UserMarshal64") +#pragma comment(linker, "/EXPORT:HGLOBAL_UserSize64=ole32.HGLOBAL_UserSize64") +#pragma comment(linker, "/EXPORT:HGLOBAL_UserUnmarshal64=ole32.HGLOBAL_UserUnmarshal64") +#pragma comment(linker, "/EXPORT:HICON_UserFree64=ole32.HICON_UserFree64") +#pragma comment(linker, "/EXPORT:HICON_UserMarshal64=ole32.HICON_UserMarshal64") +#pragma comment(linker, "/EXPORT:HICON_UserSize64=ole32.HICON_UserSize64") +#pragma comment(linker, "/EXPORT:HICON_UserUnmarshal64=ole32.HICON_UserUnmarshal64") +#pragma comment(linker, "/EXPORT:HMENU_UserFree64=ole32.HMENU_UserFree64") +#pragma comment(linker, "/EXPORT:HMENU_UserMarshal64=ole32.HMENU_UserMarshal64") +#pragma comment(linker, "/EXPORT:HMENU_UserSize64=ole32.HMENU_UserSize64") +#pragma comment(linker, "/EXPORT:HMENU_UserUnmarshal64=ole32.HMENU_UserUnmarshal64") +#pragma comment(linker, "/EXPORT:HMETAFILEPICT_UserFree64=ole32.HMETAFILEPICT_UserFree64") +#pragma comment(linker, "/EXPORT:HMETAFILEPICT_UserMarshal64=ole32.HMETAFILEPICT_UserMarshal64") +#pragma comment(linker, "/EXPORT:HMETAFILEPICT_UserSize64=ole32.HMETAFILEPICT_UserSize64") +#pragma comment(linker, "/EXPORT:HMETAFILEPICT_UserUnmarshal64=ole32.HMETAFILEPICT_UserUnmarshal64") +#pragma comment(linker, "/EXPORT:HMETAFILE_UserFree64=ole32.HMETAFILE_UserFree64") +#pragma comment(linker, "/EXPORT:HMETAFILE_UserMarshal64=ole32.HMETAFILE_UserMarshal64") +#pragma comment(linker, "/EXPORT:HMETAFILE_UserSize64=ole32.HMETAFILE_UserSize64") +#pragma comment(linker, "/EXPORT:HMETAFILE_UserUnmarshal64=ole32.HMETAFILE_UserUnmarshal64") +#pragma comment(linker, "/EXPORT:HPALETTE_UserFree64=ole32.HPALETTE_UserFree64") +#pragma comment(linker, "/EXPORT:HPALETTE_UserMarshal64=ole32.HPALETTE_UserMarshal64") +#pragma comment(linker, "/EXPORT:HPALETTE_UserSize64=ole32.HPALETTE_UserSize64") +#pragma comment(linker, "/EXPORT:HPALETTE_UserUnmarshal64=ole32.HPALETTE_UserUnmarshal64") +#pragma comment(linker, "/EXPORT:HWND_UserFree64=ole32.HWND_UserFree64") +#pragma comment(linker, "/EXPORT:HWND_UserMarshal64=ole32.HWND_UserMarshal64") +#pragma comment(linker, "/EXPORT:HWND_UserSize64=ole32.HWND_UserSize64") +#pragma comment(linker, "/EXPORT:HWND_UserUnmarshal64=ole32.HWND_UserUnmarshal64") +#pragma comment(linker, "/EXPORT:SNB_UserFree64=ole32.SNB_UserFree64") +#pragma comment(linker, "/EXPORT:SNB_UserMarshal64=ole32.SNB_UserMarshal64") +#pragma comment(linker, "/EXPORT:SNB_UserSize64=ole32.SNB_UserSize64") +#pragma comment(linker, "/EXPORT:SNB_UserUnmarshal64=ole32.SNB_UserUnmarshal64") +#pragma comment(linker, "/EXPORT:STGMEDIUM_UserFree64=ole32.STGMEDIUM_UserFree64") +#pragma comment(linker, "/EXPORT:STGMEDIUM_UserMarshal64=ole32.STGMEDIUM_UserMarshal64") +#pragma comment(linker, "/EXPORT:STGMEDIUM_UserSize64=ole32.STGMEDIUM_UserSize64") +#pragma comment(linker, "/EXPORT:STGMEDIUM_UserUnmarshal64=ole32.STGMEDIUM_UserUnmarshal64") +#pragma comment(linker, "/EXPORT:WdtpInterfacePointer_UserFree64=ole32.WdtpInterfacePointer_UserFree64") +#pragma comment(linker, "/EXPORT:WdtpInterfacePointer_UserMarshal64=ole32.WdtpInterfacePointer_UserMarshal64") +#pragma comment(linker, "/EXPORT:WdtpInterfacePointer_UserSize64=ole32.WdtpInterfacePointer_UserSize64") +#pragma comment(linker, "/EXPORT:WdtpInterfacePointer_UserUnmarshal64=ole32.WdtpInterfacePointer_UserUnmarshal64") + +#endif \ No newline at end of file diff --git a/01-Extended DLLs/KxCom/glprstat.c b/01-Extended DLLs/KxCom/glprstat.c new file mode 100644 index 0000000..1ac27fd --- /dev/null +++ b/01-Extended DLLs/KxCom/glprstat.c @@ -0,0 +1,480 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// glprstat.c +// +// Abstract: +// +// Implementation of IGlobalizationPreferencesStatics and all the other +// crappy boilerplate interfaces and functions that go along with it. Some Qt +// applications require this interface and will crash if it's not available. +// +// Can't emphasize how much I hate COM, WinRT, and C++ bullshit +// STOP USING THESE FUCKING CLASSES +// FUCKING NIGGERS +// GetUserPreferredUILanguages IS RIGHT THERE DIPSHIT! USE IT! +// +// Author: +// +// vxiiduu (18-Feb-2024) +// +// Environment: +// +// inside some bloatware c++ junk +// +// Revision History: +// +// vxiiduu 18-Feb-2024 Initial creation. +// vxiiduu 03-Mar-2024 Increase the level of implementation +// so that this interface is no longer for +// ASH usage only. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kxcomp.h" + +STATIC HRESULT STDMETHODCALLTYPE CVectorView_HSTRING_QueryInterface( + IN IVectorView_HSTRING *This, + IN REFIID RefIID, + OUT PPVOID Interface) +{ + ASSERT (This != NULL); + ASSERT (RefIID != NULL); + ASSERT (Interface != NULL); + + *Interface = NULL; + + if (IsEqualIID(RefIID, &IID_IUnknown) || + IsEqualIID(RefIID, &IID_IAgileObject) || + IsEqualIID(RefIID, &IID_IInspectable) || + IsEqualIID(RefIID, &IID_IVectorView)) { + + This->lpVtbl->AddRef(This); + *Interface = This; + } else { + return E_NOINTERFACE; + } + + return S_OK; +} + +STATIC ULONG STDMETHODCALLTYPE CVectorView_HSTRING_AddRef( + IN IVectorView_HSTRING *This) +{ + ASSERT (This != NULL); + return InterlockedIncrement(&This->RefCount); +} + +STATIC ULONG STDMETHODCALLTYPE CVectorView_HSTRING_Release( + IN IVectorView_HSTRING *This) +{ + LONG NewRefCount; + + ASSERT (This != NULL); + + NewRefCount = InterlockedDecrement(&This->RefCount); + + if (NewRefCount == 0) { + until (This->NumberOfHstrings == 0) { + // get rid of all hstrings in array + WindowsDeleteString(This->HstringArray[--This->NumberOfHstrings]); + } + + SafeFree(This->HstringArray); + SafeFree(This); + } + + return NewRefCount; +} + +STATIC HRESULT STDMETHODCALLTYPE CVectorView_HSTRING_GetIids( + IN IVectorView_HSTRING *This, + OUT PULONG NumberOfIids, + OUT IID **IidArray) +{ + IID *Array; + ULONG Count; + + ASSERT (NumberOfIids != NULL); + ASSERT (IidArray != NULL); + + Count = 1; + + Array = (IID *) CoTaskMemAlloc(Count * sizeof(IID)); + if (!Array) { + return E_OUTOFMEMORY; + } + + *NumberOfIids = Count; + Array[0] = IID_IVectorView; + + return S_OK; +} + +STATIC HRESULT STDMETHODCALLTYPE CVectorView_HSTRING_GetRuntimeClassName( + IN IVectorView_HSTRING *This, + OUT HSTRING *ClassName) +{ + PCWSTR Name = L"Windows.Foundation.Collections.IVector"; + ASSERT (ClassName != NULL); + return WindowsCreateString(Name, (ULONG) wcslen(Name), ClassName); +} + +STATIC HRESULT STDMETHODCALLTYPE CVectorView_HSTRING_GetTrustLevel( + IN IVectorView_HSTRING *This, + OUT TrustLevel *TrustLevel) +{ + ASSERT (TrustLevel != NULL); + *TrustLevel = BaseTrust; + return S_OK; +} + +STATIC HRESULT STDMETHODCALLTYPE CVectorView_HSTRING_GetAt( + IN IVectorView_HSTRING *This, + IN ULONG Index, + OUT HSTRING *Value) +{ + ASSERT (This != NULL); + ASSERT (Value != NULL); + + *Value = NULL; + + if (Index >= This->NumberOfHstrings) { + return E_BOUNDS; + } + + return WindowsDuplicateString(This->HstringArray[Index], Value); +} + +STATIC HRESULT STDMETHODCALLTYPE CVectorView_HSTRING_get_Size( + IN IVectorView_HSTRING *This, + OUT PULONG NumberOfElements) +{ + ASSERT (This != NULL); + ASSERT (NumberOfElements != NULL); + + *NumberOfElements = This->NumberOfHstrings; + return S_OK; +} + +STATIC HRESULT STDMETHODCALLTYPE CVectorView_HSTRING_IndexOf( + IN IVectorView_HSTRING *This, + IN HSTRING String, + OUT PULONG IndexOut, + OUT PBOOLEAN WasFound) +{ + ULONG Index; + + ASSERT (This != NULL); + ASSERT (IndexOut != NULL); + ASSERT (WasFound != NULL); + + for (Index = 0; Index < This->NumberOfHstrings; ++Index) { + HRESULT Result; + INT ComparisonResult; + + Result = WindowsCompareStringOrdinal( + String, + This->HstringArray[Index], + &ComparisonResult); + + if (SUCCEEDED(Result) && ComparisonResult == 0) { + *IndexOut = Index; + *WasFound = TRUE; + return S_OK; + } + } + + *IndexOut = 0; + *WasFound = FALSE; + return S_OK; +} + +STATIC HRESULT STDMETHODCALLTYPE CVectorView_HSTRING_GetMany( + IN IVectorView_HSTRING *This, + IN ULONG StartIndex, + IN ULONG NumberOfItems, + OUT HSTRING *Items, + OUT PULONG NumberOfItemsOut) +{ + ULONG Index; + + ASSERT (This != NULL); + ASSERT (Items != NULL); + ASSERT (NumberOfItemsOut != NULL); + + RtlZeroMemory(Items, NumberOfItems * sizeof(*Items)); + *NumberOfItemsOut = 0; + + for (Index = StartIndex; Index < This->NumberOfHstrings; ++Index) { + HRESULT Result; + + Result = WindowsDuplicateString( + This->HstringArray[Index], + &Items[Index - StartIndex]); + + if (FAILED(Result)) { + // deallocate all strings that were created up to this point and return + // a failure status + + until (Index == StartIndex) { + --Index; + WindowsDeleteString(Items[Index - StartIndex]); + } + + *NumberOfItemsOut = 0; + return Result; + } + + ++*NumberOfItemsOut; + + if (*NumberOfItemsOut == NumberOfItems) { + break; + } + } + + return S_OK; +} + +IVectorView_HSTRINGVtbl CVectorView_HSTRINGVtbl = { + CVectorView_HSTRING_QueryInterface, + CVectorView_HSTRING_AddRef, + CVectorView_HSTRING_Release, + + CVectorView_HSTRING_GetIids, + CVectorView_HSTRING_GetRuntimeClassName, + CVectorView_HSTRING_GetTrustLevel, + + CVectorView_HSTRING_GetAt, + CVectorView_HSTRING_get_Size, + CVectorView_HSTRING_IndexOf, + CVectorView_HSTRING_GetMany, +}; + +IVectorView_HSTRING CVectorView_HSTRING_Template = { + &CVectorView_HSTRINGVtbl, // lpVtbl + 1, // RefCount +}; + +typedef struct _IGlobalizationPreferencesStatics IGlobalizationPreferencesStatics; + +STATIC HRESULT STDMETHODCALLTYPE CGlobalizationPreferencesStatics_QueryInterface( + IN IGlobalizationPreferencesStatics *This, + IN REFIID RefIID, + OUT PPVOID Interface) +{ + ASSERT (This != NULL); + ASSERT (RefIID != NULL); + ASSERT (Interface != NULL); + + *Interface = NULL; + + if (IsEqualIID(RefIID, &IID_IUnknown) || + IsEqualIID(RefIID, &IID_IAgileObject) || + IsEqualIID(RefIID, &IID_IInspectable) || + IsEqualIID(RefIID, &IID_IGlobalizationPreferencesStatics)) { + + *Interface = This; + } else { + return E_NOINTERFACE; + } + + return S_OK; +} + +STATIC ULONG STDMETHODCALLTYPE CGlobalizationPreferencesStatics_AddRef( + IN IGlobalizationPreferencesStatics *This) +{ + return 1; +} + +STATIC ULONG STDMETHODCALLTYPE CGlobalizationPreferencesStatics_Release( + IN IGlobalizationPreferencesStatics *This) +{ + return 1; +} + +STATIC HRESULT STDMETHODCALLTYPE CGlobalizationPreferencesStatics_GetIids( + IN IGlobalizationPreferencesStatics *This, + OUT PULONG NumberOfIids, + OUT IID **IidArray) +{ + IID *Array; + ULONG Count; + + ASSERT (NumberOfIids != NULL); + ASSERT (IidArray != NULL); + + Count = 1; + + Array = (IID *) CoTaskMemAlloc(Count * sizeof(IID)); + if (!Array) { + return E_OUTOFMEMORY; + } + + *NumberOfIids = Count; + Array[0] = IID_IGlobalizationPreferencesStatics; + + return S_OK; +} + +STATIC HRESULT STDMETHODCALLTYPE CGlobalizationPreferencesStatics_GetRuntimeClassName( + IN IGlobalizationPreferencesStatics *This, + OUT HSTRING *ClassName) +{ + PCWSTR Name = L"Windows.System.UserProfile.GlobalizationPreferences"; + ASSERT (ClassName != NULL); + return WindowsCreateString(Name, (ULONG) wcslen(Name), ClassName); +} + +STATIC HRESULT STDMETHODCALLTYPE CGlobalizationPreferencesStatics_GetTrustLevel( + IN IGlobalizationPreferencesStatics *This, + OUT TrustLevel *Level) +{ + ASSERT (Level != NULL); + *Level = BaseTrust; + return S_OK; +} + +// Couldn't be bothered to implement the rest. +// I'll come back and finish this bullshit off if I see apps using them +STATIC HRESULT STDMETHODCALLTYPE CGlobalizationPreferencesStatics_NotImplemented( + IN IGlobalizationPreferencesStatics *This, + OUT IVectorView_HSTRING **VectorView) +{ + KexLogWarningEvent(L"Unimplemented method of IGlobalizationPreferencesStatics called"); + return E_NOTIMPL; +} + +STATIC HRESULT STDMETHODCALLTYPE CGlobalizationPreferencesStatics_get_Languages( + IN IGlobalizationPreferencesStatics *This, + OUT IVectorView_HSTRING **VectorView) +{ + HRESULT Result; + WCHAR LocaleName[LOCALE_NAME_MAX_LENGTH]; + ULONG LocaleNameCch; + HSTRING LocaleNameHstring; + IVectorView_HSTRING *NewVectorView; + + // + // Get the user's locale name and make a HSTRING out of it. + // + + LocaleNameCch = ARRAYSIZE(LocaleName); + LocaleNameCch = GetUserDefaultLocaleName(LocaleName, LocaleNameCch); + ASSERT (LocaleNameCch != 0); + + if (LocaleNameCch == 0) { + return HRESULT_FROM_WIN32(GetLastError()); + } + + Result = WindowsCreateString(LocaleName, LocaleNameCch - 1, &LocaleNameHstring); + ASSERT (SUCCEEDED(Result)); + + if (FAILED(Result)) { + return Result; + } + + // + // Create an IVectorView interface and put the previously created + // HSTRING into it. + // + + NewVectorView = SafeAlloc(IVectorView_HSTRING, 1); + if (!NewVectorView) { + return E_OUTOFMEMORY; + } + + *NewVectorView = CVectorView_HSTRING_Template; + NewVectorView->NumberOfHstrings = 1; + NewVectorView->HstringArray = SafeAlloc(HSTRING, NewVectorView->NumberOfHstrings); + + if (!NewVectorView->HstringArray) { + SafeFree(NewVectorView); + return E_OUTOFMEMORY; + } + + NewVectorView->HstringArray[0] = LocaleNameHstring; + *VectorView = NewVectorView; + return S_OK; +} + +STATIC HRESULT STDMETHODCALLTYPE CGlobalizationPreferencesStatics_get_HomeGeographicRegion( + IN IGlobalizationPreferencesStatics *This, + OUT HSTRING *Country) +{ + ULONG ResultCch; + WCHAR CountryName[8]; + + ASSERT (Country != NULL); + + ResultCch = GetLocaleInfoEx( + LOCALE_NAME_USER_DEFAULT, + LOCALE_ICOUNTRY, + CountryName, + ARRAYSIZE(CountryName)); + + ASSERT (ResultCch != 0); + + if (ResultCch == 0) { + return HRESULT_FROM_WIN32(GetLastError()); + } + + return WindowsCreateString(CountryName, (ULONG) wcslen(CountryName), Country); +} + +STATIC HRESULT STDMETHODCALLTYPE CGlobalizationPreferencesStatics_get_WeekStartsOn( + IN IGlobalizationPreferencesStatics *This, + OUT DayOfWeek *StartsOn) +{ + ULONG ResultCch; + ULONG WeekStartsOn; + + ASSERT (StartsOn != NULL); + + ResultCch = GetLocaleInfoEx( + LOCALE_NAME_USER_DEFAULT, + LOCALE_RETURN_NUMBER | LOCALE_IFIRSTDAYOFWEEK, + (PWSTR) &WeekStartsOn, + 2); + + ASSERT (ResultCch == 2); + ASSERT (WeekStartsOn <= 6); + + if (ResultCch == 0) { + return HRESULT_FROM_WIN32(GetLastError()); + } + + // Retarded WinRT people thought it was a great idea to use numerical constants + // that are different from what is returned by existing functions. + if (WeekStartsOn == 6) { + *StartsOn = DayOfWeek_Sunday; + } else { + *StartsOn = (DayOfWeek) (WeekStartsOn + 1); + } + + return S_OK; +} + +IGlobalizationPreferencesStaticsVtbl CGlobalizationPreferencesStaticsVtbl = { + CGlobalizationPreferencesStatics_QueryInterface, + CGlobalizationPreferencesStatics_AddRef, + CGlobalizationPreferencesStatics_Release, + + CGlobalizationPreferencesStatics_GetIids, + CGlobalizationPreferencesStatics_GetRuntimeClassName, + CGlobalizationPreferencesStatics_GetTrustLevel, + + CGlobalizationPreferencesStatics_NotImplemented, + CGlobalizationPreferencesStatics_NotImplemented, + CGlobalizationPreferencesStatics_NotImplemented, + CGlobalizationPreferencesStatics_get_Languages, + CGlobalizationPreferencesStatics_get_HomeGeographicRegion, + CGlobalizationPreferencesStatics_get_WeekStartsOn +}; + +IGlobalizationPreferencesStatics CGlobalizationPreferencesStatics = { + &CGlobalizationPreferencesStaticsVtbl +}; \ No newline at end of file diff --git a/01-Extended DLLs/KxCom/kxcom.def b/01-Extended DLLs/KxCom/kxcom.def new file mode 100644 index 0000000..9f03af9 --- /dev/null +++ b/01-Extended DLLs/KxCom/kxcom.def @@ -0,0 +1,46 @@ +LIBRARY KxCom +EXPORTS + + CoCreateInstanceFromApp = ole32.CoCreateInstanceEx + + RoInitialize + RoUninitialize + RoGetActivationFactory + RoActivateInstance + RoOriginateError + RoOriginateErrorW + RoTransformError + RoTransformErrorW + RoGetAgileReference + RoOriginateLanguageException + RoGetBufferMarshaler + + GetRestrictedErrorInfo + SetRestrictedErrorInfo + + ;; + ;; mta.c + ;; + + CoIncrementMTAUsage + CoDecrementMTAUsage + + ;; + ;; winrt.c + ;; + + WindowsCompareStringOrdinal + WindowsCreateString + WindowsCreateStringReference + WindowsDeleteString + WindowsDuplicateString + WindowsGetStringLen + WindowsGetStringRawBuffer + WindowsIsStringEmpty + WindowsStringHasEmbeddedNull + WindowsSubstring + WindowsSubstringWithSpecifiedLength + WindowsConcatString + WindowsPreallocateStringBuffer + WindowsDeleteStringBuffer + WindowsPromoteStringBuffer \ No newline at end of file diff --git a/01-Extended DLLs/KxCom/kxcomp.h b/01-Extended DLLs/KxCom/kxcomp.h new file mode 100644 index 0000000..a8847a9 --- /dev/null +++ b/01-Extended DLLs/KxCom/kxcomp.h @@ -0,0 +1,12 @@ +#pragma once + +#include +#include +#include + +EXTERN PKEX_PROCESS_DATA KexData; + +KXCOMAPI HRESULT STDMETHODCALLTYPE CActivationFactory_QueryInterface( + IN IActivationFactory *This, + IN REFIID RefIID, + OUT PPVOID Object); \ No newline at end of file diff --git a/01-Extended DLLs/KxCom/launcher.c b/01-Extended DLLs/KxCom/launcher.c new file mode 100644 index 0000000..ad2e106 --- /dev/null +++ b/01-Extended DLLs/KxCom/launcher.c @@ -0,0 +1,162 @@ +#include "buildcfg.h" +#include "kxcomp.h" +#include + +HRESULT STDMETHODCALLTYPE CLauncherStatics_QueryInterface( + IN ILauncherStatics *This, + IN REFIID RefIID, + OUT PPVOID Interface) +{ + ASSERT (This != NULL); + ASSERT (RefIID != NULL); + ASSERT (Interface != NULL); + + *Interface = NULL; + + if (IsEqualIID(RefIID, &IID_IUnknown) || + IsEqualIID(RefIID, &IID_IAgileObject) || + IsEqualIID(RefIID, &IID_IInspectable) || + IsEqualIID(RefIID, &IID_ILauncherStatics)) { + + *Interface = This; + return S_OK; + } + + return E_NOINTERFACE; +} + +ULONG STDMETHODCALLTYPE CLauncherStatics_AddRef( + IN ILauncherStatics *This) +{ + return 1; +} + +ULONG STDMETHODCALLTYPE CLauncherStatics_Release( + IN ILauncherStatics *This) +{ + return 1; +} + +HRESULT STDMETHODCALLTYPE CLauncherStatics_GetIids( + IN ILauncherStatics *This, + OUT PULONG NumberOfIids, + OUT IID **IidArray) +{ + IID *Array; + ULONG Count; + + ASSERT (NumberOfIids != NULL); + ASSERT (IidArray != NULL); + + Count = 1; + + Array = (IID *) CoTaskMemAlloc(Count * sizeof(IID)); + if (!Array) { + return E_OUTOFMEMORY; + } + + *NumberOfIids = Count; + Array[0] = IID_ILauncherStatics; + + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CLauncherStatics_GetRuntimeClassName( + IN ILauncherStatics *This, + OUT HSTRING *ClassName) +{ + PCWSTR Name = L"Windows.System.Launcher"; + ASSERT (ClassName != NULL); + return WindowsCreateString(Name, (ULONG) wcslen(Name), ClassName); +} + +HRESULT STDMETHODCALLTYPE CLauncherStatics_GetTrustLevel( + IN ILauncherStatics *This, + OUT TrustLevel *Level) +{ + ASSERT (Level != NULL); + *Level = BaseTrust; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CLauncherStatics_LaunchFileAsync( + IN ILauncherStatics *This, + IN IUnknown *StorageFile, + OUT IAsyncOperation **AsyncOperation) +{ + KexDebugCheckpoint(); // not properly implemented + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CLauncherStatics_LaunchFileWithOptionsAsync( + IN ILauncherStatics *This, + IN IUnknown *StorageFile, + IN IUnknown *LauncherOptions, + OUT IAsyncOperation **AsyncOperation) +{ + KexDebugCheckpoint(); // not properly implemented + return CLauncherStatics_LaunchFileAsync(This, StorageFile, AsyncOperation); +} + +HRESULT STDMETHODCALLTYPE CLauncherStatics_LaunchUriAsync( + IN ILauncherStatics *This, + IN IUriRuntimeClass *Uri, + OUT IAsyncOperation **AsyncOperation) +{ + HRESULT Result; + HSTRING RawUri; + HINSTANCE ShellExecuteResult; + + Result = Uri->lpVtbl->get_AbsoluteUri(Uri, &RawUri); + if (FAILED(Result)) { + return Result; + } + + ShellExecuteResult = ShellExecute( + NULL, + L"open", + WindowsGetStringRawBuffer(RawUri, NULL), + NULL, + NULL, + SW_SHOW); + + WindowsDeleteString(RawUri); + + if (((ULONG) ShellExecuteResult) <= 32) { + return E_FAIL; + } + + // HACK: Some apps (e.g. Spotify) require a valid pointer to be passed out. + // However it seems to do fine if we just pass a pointer to some random + // interface such as ourselves. + *AsyncOperation = (IAsyncOperation *) This; + + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CLauncherStatics_LaunchUriWithOptionsAsync( + IN ILauncherStatics *This, + IN IUriRuntimeClass *Uri, + IN IUnknown *LauncherOptions, + OUT IAsyncOperation **AsyncOperation) +{ + KexDebugCheckpoint(); // not properly implemented + return CLauncherStatics_LaunchUriAsync(This, Uri, AsyncOperation); +} + +ILauncherStaticsVtbl CLauncherStaticsVtbl = { + CLauncherStatics_QueryInterface, + CLauncherStatics_AddRef, + CLauncherStatics_Release, + CLauncherStatics_GetIids, + CLauncherStatics_GetRuntimeClassName, + CLauncherStatics_GetTrustLevel, + CLauncherStatics_LaunchFileAsync, + CLauncherStatics_LaunchFileWithOptionsAsync, + CLauncherStatics_LaunchUriAsync, + CLauncherStatics_LaunchUriWithOptionsAsync +}; + +ILauncherStatics CLauncherStatics = { + &CLauncherStaticsVtbl +}; \ No newline at end of file diff --git a/01-Extended DLLs/KxCom/mta.c b/01-Extended DLLs/KxCom/mta.c new file mode 100644 index 0000000..8d6cb45 --- /dev/null +++ b/01-Extended DLLs/KxCom/mta.c @@ -0,0 +1,57 @@ +#include "buildcfg.h" +#include "kxcomp.h" + +// +// Note: The authentic Windows 8+ API uses a structure pointer +// as the cookie rather than a HANDLE. +// + +STATIC DWORD WINAPI KxCompMTAUsageIncrementerThread( + IN PVOID Parameter) +{ + CoInitializeEx(NULL, COINIT_MULTITHREADED); + SleepEx(INFINITE, TRUE); + CoUninitialize(); + return 0; +} + +KXCOMAPI HRESULT WINAPI CoIncrementMTAUsage( + OUT PCO_MTA_USAGE_COOKIE Cookie) +{ + if (!Cookie) { + return E_INVALIDARG; + } + + *Cookie = CreateThread( + NULL, + 0, + KxCompMTAUsageIncrementerThread, + NULL, + 0, + NULL); + + if (!*Cookie) { + return HRESULT_FROM_WIN32(GetLastError()); + } + + return S_OK; +} + +KXCOMAPI HRESULT WINAPI CoDecrementMTAUsage( + IN CO_MTA_USAGE_COOKIE Cookie) +{ + NTSTATUS Status; + + if (!Cookie) { + return E_INVALIDARG; + } + + Status = NtAlertThread(Cookie); + NtClose(Cookie); + + if (NT_SUCCESS(Status)) { + return S_OK; + } else { + return HRESULT_FROM_WIN32(RtlNtStatusToDosError(Status)); + } +} \ No newline at end of file diff --git a/01-Extended DLLs/KxCom/roapi.c b/01-Extended DLLs/KxCom/roapi.c new file mode 100644 index 0000000..5ace92c --- /dev/null +++ b/01-Extended DLLs/KxCom/roapi.c @@ -0,0 +1,12 @@ +#include "buildcfg.h" +#include "kxcomp.h" + +KXCOMAPI HRESULT WINAPI RoGetAgileReference( + IN ULONG Options, + IN REFIID RefIID, + IN IUnknown *pUnknown, + OUT IUnknown **AgileReference) +{ + KexLogWarningEvent(L"Unimplemented stub function RoGetAgileReference was called"); + return E_NOTIMPL; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxCom/robuffer.c b/01-Extended DLLs/KxCom/robuffer.c new file mode 100644 index 0000000..b629a3c --- /dev/null +++ b/01-Extended DLLs/KxCom/robuffer.c @@ -0,0 +1,8 @@ +#include "buildcfg.h" +#include "kxcomp.h" + +KXCOMAPI HRESULT WINAPI RoGetBufferMarshaler( + OUT IUnknown **BufferMarshaler) +{ + return E_NOTIMPL; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxCom/roerror.c b/01-Extended DLLs/KxCom/roerror.c new file mode 100644 index 0000000..fcb44a5 --- /dev/null +++ b/01-Extended DLLs/KxCom/roerror.c @@ -0,0 +1,165 @@ +#include "buildcfg.h" +#include "kxcomp.h" +#include + +BOOL WINAPI RoOriginateErrorW( + IN HRESULT Result, + IN ULONG Length, + IN PCWSTR Message OPTIONAL) +{ + NTSTATUS Status; + + if (!FAILED(Result)) { + return FALSE; + } + + Status = VxlWriteLogEx( + KexData->LogHandle, + KEX_COMPONENT, + __FILEW__, + __LINE__, + L"RoOriginateError", + LogSeverityDebug, + L"WINRT: %s: %s", Win32ErrorAsString(Result), Message); + + return NT_SUCCESS(Status); +} + +BOOL WINAPI RoOriginateError( + IN HRESULT Result, + IN HSTRING Message) +{ + return RoOriginateErrorW( + Result, + WindowsGetStringLen(Message), + WindowsGetStringRawBuffer(Message, NULL)); +} + +KXCOMAPI BOOL WINAPI RoOriginateLanguageException( + IN HRESULT Result, + IN HSTRING Message, + IN IUnknown *LanguageException OPTIONAL) +{ + NTSTATUS Status; + UNICODE_STRING FaultingModuleName; + + if (SUCCEEDED(Result)) { + return FALSE; + } + + RtlInitEmptyUnicodeStringFromTeb(&FaultingModuleName); + Status = KexLdrGetDllFullNameFromAddress(ReturnAddress(), &FaultingModuleName); + + if (!NT_SUCCESS(Status)) { + RtlInitConstantUnicodeString(&FaultingModuleName, L""); + } + + KexLogWarningEvent( + L"Windows Runtime language exception: %s\r\n" + L"Name of the faulting module: %wZ\r\n" + L"Result: 0x%08lx\r\n" + L"Message: %s\r\n" + L"LanguageException: 0x%p", + Win32ErrorAsString(Result), + &FaultingModuleName, + Result, + WindowsGetStringRawBuffer(Message, NULL), + LanguageException); + + return TRUE; +} + +STATIC HRESULT IsRestrictedErrorObject( + IN IRestrictedErrorInfo *RestrictedErrorInfo) +{ + HRESULT Result; + IUnknown *InternalErrorInfo; + + ASSERT (RestrictedErrorInfo != NULL); + + InternalErrorInfo = NULL; + + Result = RestrictedErrorInfo->lpVtbl->QueryInterface( + RestrictedErrorInfo, + &IID_IInternalErrorInfo, + (PPVOID) &InternalErrorInfo); + + if (Result == E_NOINTERFACE) { + Result = E_INVALIDARG; + RoOriginateErrorW(Result, 0, L"RestrictedErrorInfo"); + } + + SafeRelease(InternalErrorInfo); + return Result; +} + +HRESULT WINAPI GetRestrictedErrorInfo( + OUT IUnknown **RestrictedErrorInfo) +{ + // TODO: implement this better + KexLogWarningEvent(L"Unimplemented function GetRestrictedErrorInfo called."); + return S_FALSE; +} + +KXCOMAPI HRESULT WINAPI SetRestrictedErrorInfo( + IN IRestrictedErrorInfo *RestrictedErrorInfo OPTIONAL) +{ + HRESULT Result; + IErrorInfo *ErrorInfo; + + Result = S_OK; + ErrorInfo = NULL; + + if (RestrictedErrorInfo) { + Result = IsRestrictedErrorObject(RestrictedErrorInfo); + if (FAILED(Result)) { + goto Exit; + } + + Result = RestrictedErrorInfo->lpVtbl->QueryInterface( + RestrictedErrorInfo, + &IID_IErrorInfo, + (PPVOID) &ErrorInfo); + } + + if (SUCCEEDED(Result)) { + Result = SetErrorInfo(0, ErrorInfo); + } + +Exit: + SafeRelease(ErrorInfo); + return Result; +} + +KXCOMAPI BOOL WINAPI RoTransformErrorW( + IN HRESULT OldError, + IN HRESULT NewError, + IN ULONG MessageLength, + IN PCWSTR Message OPTIONAL) +{ + if (OldError == NewError) { + return FALSE; + } + + if (SUCCEEDED(OldError) && SUCCEEDED(NewError)) { + return FALSE; + } + + return RoOriginateErrorW(NewError, MessageLength, Message); +} + +KXCOMAPI BOOL WINAPI RoTransformError( + IN HRESULT OldError, + IN HRESULT NewError, + IN HSTRING Message) +{ + if (OldError == NewError) { + return FALSE; + } + + if (SUCCEEDED(OldError) && SUCCEEDED(NewError)) { + return FALSE; + } + + return RoOriginateError(NewError, Message); +} \ No newline at end of file diff --git a/01-Extended DLLs/KxCom/rofactry.c b/01-Extended DLLs/KxCom/rofactry.c new file mode 100644 index 0000000..271748b --- /dev/null +++ b/01-Extended DLLs/KxCom/rofactry.c @@ -0,0 +1,37 @@ +#include "buildcfg.h" +#include "kxcomp.h" + +KXCOMAPI HRESULT WINAPI RoGetActivationFactory( + IN HSTRING ActivatableClassId, + IN REFIID RefIID, + OUT PPVOID Factory) +{ + LPOLESTR RefIIDAsString; + + StringFromIID(RefIID, &RefIIDAsString); + + KexLogDetailEvent( + L"RoGetActivationFactory called\r\n\r\n" + L"ActivatableClassId: %s\r\n" + L"IID: %s", + WindowsGetStringRawBuffer(ActivatableClassId, NULL), + RefIIDAsString); + + CoTaskMemFree(RefIIDAsString); + + return CActivationFactory_QueryInterface(&CActivationFactory, RefIID, Factory); +} + +KXCOMAPI HRESULT WINAPI RoActivateInstance( + IN HSTRING ActivatableClassId, + OUT IInspectable **Instance) +{ + ASSERT (Instance != NULL); + + KexLogDetailEvent( + L"RoActivateInstance called: %s", + WindowsGetStringRawBuffer(ActivatableClassId, NULL)); + + *Instance = (IInspectable *) &CActivationFactory; + return S_OK; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxCom/roinit.c b/01-Extended DLLs/KxCom/roinit.c new file mode 100644 index 0000000..20747aa --- /dev/null +++ b/01-Extended DLLs/KxCom/roinit.c @@ -0,0 +1,21 @@ +#include "buildcfg.h" +#include "kxcomp.h" + +KXCOMAPI HRESULT WINAPI RoInitialize( + IN RO_INIT_TYPE InitType) +{ + if (InitType == RO_INIT_SINGLETHREADED) { + return CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + } else if (InitType == RO_INIT_MULTITHREADED) { + return CoInitializeEx(NULL, COINIT_MULTITHREADED); + } else { + return E_INVALIDARG; + } +} + +KXCOMAPI VOID WINAPI RoUninitialize( + VOID) +{ + // yes, this is all it does on win8. + CoUninitialize(); +} \ No newline at end of file diff --git a/01-Extended DLLs/KxCom/uisettings.c b/01-Extended DLLs/KxCom/uisettings.c new file mode 100644 index 0000000..07964ae --- /dev/null +++ b/01-Extended DLLs/KxCom/uisettings.c @@ -0,0 +1,400 @@ +#include "buildcfg.h" +#include "kxcomp.h" + +// +// Implements IUISettings and IUISettings3. +// Most of this crap is just a wrapper around basic win32 functions like +// SystemParametersInfo, GetSystemMetrics, GetSysColor, etc. +// + +int _fltused; + +STATIC HRESULT InternalGetSystemMetricHeightAndWidth( + IN INT WidthIndex, + IN INT HeightIndex, + OUT UISettingsSize *Size) +{ + INT Width; + INT Height; + + Size->Width = 0.0f; + Size->Height = 0.0f; + + Width = GetSystemMetrics(WidthIndex); + Height = GetSystemMetrics(HeightIndex); + + if (!Width || !Height) { + return HRESULT_FROM_WIN32(GetLastError()); + } + + Size->Width = (FLOAT) Width; + Size->Height = (FLOAT) Height; + return S_OK; +} + +KXCOMAPI HRESULT STDMETHODCALLTYPE CUISettings_QueryInterface( + IN IUISettings *This, + IN REFIID RefIID, + OUT PPVOID Object) +{ + ASSERT (This != NULL); + ASSERT (RefIID != NULL); + ASSERT (Object != NULL); + + *Object = NULL; + + if (IsEqualIID(RefIID, &IID_IUnknown) || + IsEqualIID(RefIID, &IID_IAgileObject) || + IsEqualIID(RefIID, &IID_IInspectable) || + IsEqualIID(RefIID, &IID_IUISettings)) { + + *Object = This; + } else if (IsEqualIID(RefIID, &IID_IUISettings3)) { + *Object = &CUISettings3; + } else { + LPOLESTR IidAsString; + + StringFromIID(RefIID, &IidAsString); + + KexLogWarningEvent( + L"QueryInterface called with unsupported IID: %s", + IidAsString); + + CoTaskMemFree(IidAsString); + return E_NOINTERFACE; + } + + return S_OK; +} + +KXCOMAPI ULONG STDMETHODCALLTYPE CUISettings_AddRef( + IN IUISettings *This) +{ + return 1; +} + +KXCOMAPI ULONG STDMETHODCALLTYPE CUISettings_Release( + IN IUISettings *This) +{ + return 1; +} + +KXCOMAPI HRESULT STDMETHODCALLTYPE CUISettings_GetIids( + IN IUISettings *This, + OUT PULONG NumberOfIids, + OUT IID **IidArray) +{ + IID *Array; + ULONG Count; + + ASSERT (NumberOfIids != NULL); + ASSERT (IidArray != NULL); + + Count = 1; + + Array = (IID *) CoTaskMemAlloc(Count * sizeof(IID)); + if (!Array) { + return E_OUTOFMEMORY; + } + + *NumberOfIids = Count; + Array[0] = IID_IUISettings; + + return S_OK; +} + +KXCOMAPI HRESULT STDMETHODCALLTYPE CUISettings_GetRuntimeClassName( + IN IUISettings *This, + OUT HSTRING *ClassName) +{ + PCWSTR Name = L"Windows.UI.ViewManagement.UISettings"; + ASSERT (ClassName != NULL); + return WindowsCreateString(Name, (ULONG) wcslen(Name), ClassName); +} + +KXCOMAPI HRESULT STDMETHODCALLTYPE CUISettings_GetTrustLevel( + IN IUISettings *This, + OUT TrustLevel *Level) +{ + ASSERT (Level != NULL); + *Level = BaseTrust; + return S_OK; +} + +KXCOMAPI HRESULT STDMETHODCALLTYPE CUISettings_get_HandPreference( + IN IUISettings *This, + OUT UIHandPreference *HandPreference) +{ + ULONG RightHanded; + BOOLEAN Success; + + *HandPreference = HandPreference_RightHanded; + + Success = SystemParametersInfo(SPI_GETMENUDROPALIGNMENT, 0, &RightHanded, FALSE); + if (!Success) { + return HRESULT_FROM_WIN32(GetLastError()); + } + + *HandPreference = (RightHanded == TRUE) ? HandPreference_RightHanded : HandPreference_LeftHanded; + return S_OK; +} + +KXCOMAPI HRESULT STDMETHODCALLTYPE CUISettings_get_CursorSize( + IN IUISettings *This, + OUT UISettingsSize *Size) +{ + return InternalGetSystemMetricHeightAndWidth(SM_CXCURSOR, SM_CYCURSOR, Size); +} + +KXCOMAPI HRESULT STDMETHODCALLTYPE CUISettings_get_ScrollBarSize( + IN IUISettings *This, + OUT UISettingsSize *Size) +{ + return InternalGetSystemMetricHeightAndWidth(SM_CYHSCROLL, SM_CXVSCROLL, Size); +} + +KXCOMAPI HRESULT STDMETHODCALLTYPE CUISettings_get_ScrollBarArrowSize( + IN IUISettings *This, + OUT UISettingsSize *Size) +{ + return InternalGetSystemMetricHeightAndWidth(SM_CXHSCROLL, SM_CYVSCROLL, Size); +} + +KXCOMAPI HRESULT STDMETHODCALLTYPE CUISettings_get_ScrollBarThumbBoxSize( + IN IUISettings *This, + OUT UISettingsSize *Size) +{ + return InternalGetSystemMetricHeightAndWidth(SM_CXHTHUMB, SM_CYVTHUMB, Size); +} + +KXCOMAPI HRESULT STDMETHODCALLTYPE CUISettings_get_MessageDuration( + IN IUISettings *This, + OUT PULONG Duration) +{ + BOOLEAN Success; + + *Duration = 0; + + Success = SystemParametersInfo(SPI_GETMESSAGEDURATION, 0, Duration, FALSE); + if (!Success) { + return HRESULT_FROM_WIN32(GetLastError()); + } + + return S_OK; +} + +KXCOMAPI HRESULT STDMETHODCALLTYPE CUISettings_get_AnimationsEnabled( + IN IUISettings *This, + OUT PBOOLEAN Enabled) +{ + BOOLEAN Success; + BOOL EnabledI32; + + Success = SystemParametersInfo(SPI_GETCLIENTAREAANIMATION, 0, &EnabledI32, FALSE); + if (!Success) { + *Enabled = FALSE; + return HRESULT_FROM_WIN32(GetLastError()); + } + + *Enabled = !!EnabledI32; + return S_OK; +} + +// NB: This value is not natively supported in Win7. +#define SPI_GETCARETBROWSING 0x104C + +KXCOMAPI HRESULT STDMETHODCALLTYPE CUISettings_get_CaretBrowsingEnabled( + IN IUISettings *This, + OUT PBOOLEAN Enabled) +{ + BOOLEAN Success; + BOOL EnabledI32; + + Success = SystemParametersInfo(SPI_GETCARETBROWSING, 0, &EnabledI32, FALSE); + if (!Success) { + *Enabled = FALSE; + return HRESULT_FROM_WIN32(GetLastError()); + } + + *Enabled = !!EnabledI32; + return S_OK; +} + +KXCOMAPI HRESULT STDMETHODCALLTYPE CUISettings_get_CaretBlinkRate( + IN IUISettings *This, + OUT PULONG BlinkRate) +{ + *BlinkRate = GetCaretBlinkTime(); + return S_OK; +} + +KXCOMAPI HRESULT STDMETHODCALLTYPE CUISettings_get_CaretWidth( + IN IUISettings *This, + OUT PULONG Width) +{ + BOOLEAN Success; + + Success = SystemParametersInfo(SPI_GETCARETWIDTH, 0, Width, FALSE); + if (!Success) { + return HRESULT_FROM_WIN32(GetLastError()); + } + + return S_OK; +} + +KXCOMAPI HRESULT STDMETHODCALLTYPE CUISettings_get_DoubleClickTime( + IN IUISettings *This, + OUT PULONG DoubleClickTime) +{ + *DoubleClickTime = GetDoubleClickTime(); + return S_OK; +} + +KXCOMAPI HRESULT STDMETHODCALLTYPE CUISettings_get_MouseHoverTime( + IN IUISettings *This, + OUT PULONG MouseHoverTime) +{ + BOOLEAN Success; + + Success = SystemParametersInfo(SPI_GETMOUSEHOVERTIME, 0, MouseHoverTime, FALSE); + if (!Success) { + return HRESULT_FROM_WIN32(GetLastError()); + } + + return S_OK; +} + +KXCOMAPI HRESULT STDMETHODCALLTYPE CUISettings_UIElementColor( + IN IUISettings *This, + IN UIElementType Type, + OUT UIColor *Color) +{ + ULONG ColorIndex; + ULONG ColorI32; + + switch (Type) { + case UIElementType_ActiveCaption: ColorIndex = COLOR_ACTIVECAPTION; break; + case UIElementType_Background: ColorIndex = COLOR_BACKGROUND; break; + case UIElementType_ButtonFace: ColorIndex = COLOR_BTNFACE; break; + case UIElementType_ButtonText: ColorIndex = COLOR_BTNTEXT; break; + case UIElementType_CaptionText: ColorIndex = COLOR_CAPTIONTEXT; break; + case UIElementType_GrayText: ColorIndex = COLOR_GRAYTEXT; break; + case UIElementType_Highlight: ColorIndex = COLOR_HIGHLIGHT; break; + case UIElementType_HighlightText: ColorIndex = COLOR_HIGHLIGHTTEXT; break; + case UIElementType_Hotlight: ColorIndex = COLOR_HOTLIGHT; break; + case UIElementType_InactiveCaption: ColorIndex = COLOR_INACTIVECAPTION; break; + case UIElementType_InactiveCaptionText: ColorIndex = COLOR_INACTIVECAPTIONTEXT; break; + case UIElementType_Window: ColorIndex = COLOR_WINDOW; break; + case UIElementType_WindowText: ColorIndex = COLOR_WINDOWTEXT; break; + default: + RtlZeroMemory(Color, sizeof(*Color)); + return S_OK; + } + + ColorI32 = GetSysColor(ColorIndex); + Color->A = 0xFF; // Opaque + Color->R = GetRValue(ColorI32); + Color->G = GetGValue(ColorI32); + Color->B = GetBValue(ColorI32); + + return S_OK; +} + +IUISettingsVtbl CUISettingsVtbl = { + CUISettings_QueryInterface, + CUISettings_AddRef, + CUISettings_Release, + + CUISettings_GetIids, + CUISettings_GetRuntimeClassName, + CUISettings_GetTrustLevel, + + CUISettings_get_HandPreference, + CUISettings_get_CursorSize, + CUISettings_get_ScrollBarSize, + CUISettings_get_ScrollBarArrowSize, + CUISettings_get_ScrollBarThumbBoxSize, + CUISettings_get_MessageDuration, + CUISettings_get_AnimationsEnabled, + CUISettings_get_CaretBrowsingEnabled, + CUISettings_get_CaretBlinkRate, + CUISettings_get_CaretWidth, + CUISettings_get_DoubleClickTime, + CUISettings_get_MouseHoverTime, + CUISettings_UIElementColor +}; + +IUISettings CUISettings = { + &CUISettingsVtbl +}; + +KXCOMAPI HRESULT STDMETHODCALLTYPE CUISettings3_GetColorValue( + IN IUISettings3 *This, + IN UIColorType DesiredColor, + OUT UIColor *ColorValue) +{ + ULONG SysColor; + ULONG ColorI32; + + switch (DesiredColor) { + case UIColorType_Background: SysColor = COLOR_WINDOW; break; + case UIColorType_Foreground: SysColor = COLOR_WINDOWTEXT; break; + case UIColorType_AccentDark3: SysColor = COLOR_3DDKSHADOW; break; + case UIColorType_AccentDark2: SysColor = COLOR_3DDKSHADOW; break; + case UIColorType_AccentDark1: SysColor = COLOR_3DDKSHADOW; break; + case UIColorType_Accent: SysColor = COLOR_3DSHADOW; break; + case UIColorType_AccentLight1: SysColor = COLOR_3DLIGHT; break; + case UIColorType_AccentLight2: SysColor = COLOR_3DLIGHT; break; + case UIColorType_AccentLight3: SysColor = COLOR_3DLIGHT; break; + default: + return E_INVALIDARG; + } + + ColorI32 = GetSysColor(SysColor); + ColorValue->A = 0xFF; + ColorValue->R = GetRValue(ColorI32); + ColorValue->G = GetGValue(ColorI32); + ColorValue->B = GetBValue(ColorI32); + + return S_OK; +} + +KXCOMAPI HRESULT STDMETHODCALLTYPE CUISettings3_add_ColorValuesChanged( + IN IUISettings3 *This, + IN PVOID Callback, + OUT PPVOID Cookie) +{ + *Cookie = (PVOID) (ULONG_PTR) 0x12345678; + return S_OK; +} + +KXCOMAPI HRESULT STDMETHODCALLTYPE CUISettings3_remove_ColorValuesChanged( + IN IUISettings3 *This, + IN PVOID Cookie) +{ + if (((ULONG_PTR) Cookie) != 0x12345678) { + return E_INVALIDARG; + } + + return S_OK; +} + +#pragma warning(disable:4028) +IUISettings3Vtbl CUISettings3Vtbl = { + CUISettings_QueryInterface, + CUISettings_AddRef, + CUISettings_Release, + + CUISettings_GetIids, + CUISettings_GetRuntimeClassName, + CUISettings_GetTrustLevel, + + CUISettings3_GetColorValue, + CUISettings3_add_ColorValuesChanged, + CUISettings3_remove_ColorValuesChanged +}; +#pragma warning(default:4028) + +IUISettings3 CUISettings3 = { + &CUISettings3Vtbl +}; \ No newline at end of file diff --git a/01-Extended DLLs/KxCom/uiview.c b/01-Extended DLLs/KxCom/uiview.c new file mode 100644 index 0000000..9735487 --- /dev/null +++ b/01-Extended DLLs/KxCom/uiview.c @@ -0,0 +1,249 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// uiview.c +// +// Abstract: +// +// IUIViewSettingsInterop and IUIViewSettings. +// +// Author: +// +// vxiiduu (06-Mar-2024) +// +// Environment: +// +// inside some bloatware c++ junk +// +// Revision History: +// +// vxiiduu 06-Mar-2024 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kxcomp.h" + +HRESULT STDMETHODCALLTYPE CUIViewSettingsInterop_QueryInterface( + IN IUIViewSettingsInterop *This, + IN REFIID RefIID, + OUT PPVOID Interface) +{ + ASSERT (This != NULL); + ASSERT (RefIID != NULL); + ASSERT (Interface != NULL); + + *Interface = NULL; + + if (IsEqualIID(RefIID, &IID_IUnknown) || + IsEqualIID(RefIID, &IID_IAgileObject) || + IsEqualIID(RefIID, &IID_IInspectable) || + IsEqualIID(RefIID, &IID_IUIViewSettingsInterop)) { + + *Interface = This; + return S_OK; + } + + return E_NOINTERFACE; +} + +ULONG STDMETHODCALLTYPE CUIViewSettingsInterop_AddRef( + IN IUIViewSettingsInterop *This) +{ + return 1; +} + +ULONG STDMETHODCALLTYPE CUIViewSettingsInterop_Release( + IN IUIViewSettingsInterop *This) +{ + return 1; +} + +HRESULT STDMETHODCALLTYPE CUIViewSettingsInterop_GetIids( + IN IUIViewSettingsInterop *This, + OUT PULONG NumberOfIids, + OUT IID **IidArray) +{ + IID *Array; + ULONG Count; + + ASSERT (NumberOfIids != NULL); + ASSERT (IidArray != NULL); + + Count = 1; + + Array = (IID *) CoTaskMemAlloc(Count * sizeof(IID)); + if (!Array) { + return E_OUTOFMEMORY; + } + + *NumberOfIids = Count; + Array[0] = IID_IUIViewSettingsInterop; + + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CUIViewSettingsInterop_GetRuntimeClassName( + IN IUIViewSettingsInterop *This, + OUT HSTRING *ClassName) +{ + PCWSTR Name = L"Windows.UI.ViewManagement.UISettings"; + ASSERT (ClassName != NULL); + return WindowsCreateString(Name, (ULONG) wcslen(Name), ClassName); +} + +HRESULT STDMETHODCALLTYPE CUIViewSettingsInterop_GetTrustLevel( + IN IUIViewSettingsInterop *This, + OUT TrustLevel *Level) +{ + ASSERT (Level != NULL); + *Level = BaseTrust; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CUIViewSettingsInterop_GetForWindow( + IN IUIViewSettingsInterop *This, + IN HWND Window, + IN REFIID RefIID, + OUT PPVOID Interface) +{ + ASSERT (This != NULL); + ASSERT (RefIID != NULL); + ASSERT (Interface != NULL); + + *Interface = NULL; + + if (!IsWindow(Window)) { + return HRESULT_FROM_WIN32(ERROR_INVALID_WINDOW_HANDLE); + } + + if (!IsEqualIID(RefIID, &IID_IUIViewSettings)) { + return E_NOINTERFACE; + } + + *Interface = &CUIViewSettings; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CUIViewSettings_QueryInterface( + IN IUIViewSettings *This, + IN REFIID RefIID, + OUT PPVOID Interface) +{ + ASSERT (This != NULL); + ASSERT (RefIID != NULL); + ASSERT (Interface != NULL); + + *Interface = NULL; + + if (IsEqualIID(RefIID, &IID_IUnknown) || + IsEqualIID(RefIID, &IID_IAgileObject) || + IsEqualIID(RefIID, &IID_IInspectable) || + IsEqualIID(RefIID, &IID_IUIViewSettings)) { + + *Interface = This; + return S_OK; + } + + return E_NOINTERFACE; +} + +ULONG STDMETHODCALLTYPE CUIViewSettings_AddRef( + IN IUIViewSettings *This) +{ + return 1; +} + +ULONG STDMETHODCALLTYPE CUIViewSettings_Release( + IN IUIViewSettings *This) +{ + return 1; +} + +HRESULT STDMETHODCALLTYPE CUIViewSettings_GetIids( + IN IUIViewSettings *This, + OUT PULONG NumberOfIids, + OUT IID **IidArray) +{ + IID *Array; + ULONG Count; + + ASSERT (NumberOfIids != NULL); + ASSERT (IidArray != NULL); + + Count = 1; + + Array = (IID *) CoTaskMemAlloc(Count * sizeof(IID)); + if (!Array) { + return E_OUTOFMEMORY; + } + + *NumberOfIids = Count; + Array[0] = IID_IUIViewSettings; + + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CUIViewSettings_GetRuntimeClassName( + IN IUIViewSettings *This, + OUT HSTRING *ClassName) +{ + PCWSTR Name = L"Windows.UI.ViewManagement.UISettings"; + ASSERT (ClassName != NULL); + return WindowsCreateString(Name, (ULONG) wcslen(Name), ClassName); +} + +HRESULT STDMETHODCALLTYPE CUIViewSettings_GetTrustLevel( + IN IUIViewSettings *This, + OUT TrustLevel *Level) +{ + ASSERT (Level != NULL); + *Level = BaseTrust; + return S_OK; +} + +// this, ladies and gentlemen, is what this entire 200+ LINE FILE boils +// down to. this is the only function in the whole file that actually +// "does something" (and even that's a bit of a stretch). the rest is +// literally just copypasted boilerplate COM junk. +HRESULT STDMETHODCALLTYPE CUIViewSettings_get_UserInteractionMode( + IN IUIViewSettings *This, + OUT UserInteractionMode *InteractionMode) +{ + ASSERT (InteractionMode != NULL); + *InteractionMode = UserInteractionMode_Mouse; + return S_OK; +} + +IUIViewSettingsInteropVtbl CUIViewSettingsInteropVtbl = { + CUIViewSettingsInterop_QueryInterface, + CUIViewSettingsInterop_AddRef, + CUIViewSettingsInterop_Release, + + CUIViewSettingsInterop_GetIids, + CUIViewSettingsInterop_GetRuntimeClassName, + CUIViewSettingsInterop_GetTrustLevel, + + CUIViewSettingsInterop_GetForWindow +}; + +IUIViewSettingsInterop CUIViewSettingsInterop = { + &CUIViewSettingsInteropVtbl +}; + +IUIViewSettingsVtbl CUIViewSettingsVtbl = { + CUIViewSettings_QueryInterface, + CUIViewSettings_AddRef, + CUIViewSettings_Release, + + CUIViewSettings_GetIids, + CUIViewSettings_GetRuntimeClassName, + CUIViewSettings_GetTrustLevel, + + CUIViewSettings_get_UserInteractionMode +}; + +IUIViewSettings CUIViewSettings = { + &CUIViewSettingsVtbl +}; \ No newline at end of file diff --git a/01-Extended DLLs/KxCom/uri.c b/01-Extended DLLs/KxCom/uri.c new file mode 100644 index 0000000..257daeb --- /dev/null +++ b/01-Extended DLLs/KxCom/uri.c @@ -0,0 +1,518 @@ +#include "buildcfg.h" +#include "kxcomp.h" + +HRESULT STDMETHODCALLTYPE CUriRuntimeClass_QueryInterface( + IN IUriRuntimeClass *This, + IN REFIID RefIID, + OUT PPVOID Interface) +{ + ASSERT (This != NULL); + ASSERT (RefIID != NULL); + ASSERT (Interface != NULL); + + *Interface = NULL; + + if (IsEqualIID(RefIID, &IID_IUnknown) || + IsEqualIID(RefIID, &IID_IAgileObject) || + IsEqualIID(RefIID, &IID_IInspectable) || + IsEqualIID(RefIID, &IID_IUriRuntimeClass)) { + + *Interface = This; + InterlockedIncrement(&This->RefCount); + return S_OK; + } + + return E_NOINTERFACE; +} + +ULONG STDMETHODCALLTYPE CUriRuntimeClass_AddRef( + IN IUriRuntimeClass *This) +{ + return InterlockedIncrement(&This->RefCount); +} + +ULONG STDMETHODCALLTYPE CUriRuntimeClass_Release( + IN IUriRuntimeClass *This) +{ + ULONG NewRefCount; + + NewRefCount = InterlockedDecrement(&This->RefCount); + + if (NewRefCount == 0) { + SafeFree(This); + } + + return NewRefCount; +} + +HRESULT STDMETHODCALLTYPE CUriRuntimeClass_GetIids( + IN IUriRuntimeClass *This, + OUT PULONG NumberOfIids, + OUT IID **IidArray) +{ + IID *Array; + ULONG Count; + + ASSERT (NumberOfIids != NULL); + ASSERT (IidArray != NULL); + + Count = 1; + + Array = (IID *) CoTaskMemAlloc(Count * sizeof(IID)); + if (!Array) { + return E_OUTOFMEMORY; + } + + *NumberOfIids = Count; + Array[0] = IID_IUriRuntimeClass; + + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CUriRuntimeClass_GetRuntimeClassName( + IN IUriRuntimeClass *This, + OUT HSTRING *ClassName) +{ + PCWSTR Name = L"Windows.Foundation.Uri"; + ASSERT (ClassName != NULL); + return WindowsCreateString(Name, (ULONG) wcslen(Name), ClassName); +} + +HRESULT STDMETHODCALLTYPE CUriRuntimeClass_GetTrustLevel( + IN IUriRuntimeClass *This, + OUT TrustLevel *Level) +{ + ASSERT (Level != NULL); + *Level = BaseTrust; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CUriRuntimeClass_get_AbsoluteUri( + IN IUriRuntimeClass *This, + OUT HSTRING *AbsoluteUri) +{ + HRESULT Result; + BSTR Output; + + Result = This->Uri->lpVtbl->GetAbsoluteUri(This->Uri, &Output); + if (FAILED(Result)) { + return Result; + } + + Result = WindowsCreateString(Output, (ULONG) wcslen(Output), AbsoluteUri); + SysFreeString(Output); + + return Result; +} + +HRESULT STDMETHODCALLTYPE CUriRuntimeClass_get_DisplayUri( + IN IUriRuntimeClass *This, + OUT HSTRING *DisplayUri) +{ + HRESULT Result; + BSTR Output; + + Result = This->Uri->lpVtbl->GetDisplayUri(This->Uri, &Output); + if (FAILED(Result)) { + return Result; + } + + Result = WindowsCreateString(Output, (ULONG) wcslen(Output), DisplayUri); + SysFreeString(Output); + + return Result; +} + +HRESULT STDMETHODCALLTYPE CUriRuntimeClass_get_Domain( + IN IUriRuntimeClass *This, + OUT HSTRING *Domain) +{ + HRESULT Result; + BSTR Output; + + Result = This->Uri->lpVtbl->GetDomain(This->Uri, &Output); + if (FAILED(Result)) { + return Result; + } + + Result = WindowsCreateString(Output, (ULONG) wcslen(Output), Domain); + SysFreeString(Output); + + return Result; +} + +HRESULT STDMETHODCALLTYPE CUriRuntimeClass_get_Extension( + IN IUriRuntimeClass *This, + OUT HSTRING *Extension) +{ + HRESULT Result; + BSTR Output; + + Result = This->Uri->lpVtbl->GetExtension(This->Uri, &Output); + if (FAILED(Result)) { + return Result; + } + + Result = WindowsCreateString(Output, (ULONG) wcslen(Output), Extension); + SysFreeString(Output); + + return Result; +} + +HRESULT STDMETHODCALLTYPE CUriRuntimeClass_get_Fragment( + IN IUriRuntimeClass *This, + OUT HSTRING *Fragment) +{ + HRESULT Result; + BSTR Output; + + Result = This->Uri->lpVtbl->GetFragment(This->Uri, &Output); + if (FAILED(Result)) { + return Result; + } + + Result = WindowsCreateString(Output, (ULONG) wcslen(Output), Fragment); + SysFreeString(Output); + + return Result; +} + +HRESULT STDMETHODCALLTYPE CUriRuntimeClass_get_Host( + IN IUriRuntimeClass *This, + OUT HSTRING *Host) +{ + HRESULT Result; + BSTR Output; + + Result = This->Uri->lpVtbl->GetHost(This->Uri, &Output); + if (FAILED(Result)) { + return Result; + } + + Result = WindowsCreateString(Output, (ULONG) wcslen(Output), Host); + SysFreeString(Output); + + return Result; +} + +HRESULT STDMETHODCALLTYPE CUriRuntimeClass_get_Password( + IN IUriRuntimeClass *This, + OUT HSTRING *Password) +{ + HRESULT Result; + BSTR Output; + + Result = This->Uri->lpVtbl->GetPassword(This->Uri, &Output); + if (FAILED(Result)) { + return Result; + } + + Result = WindowsCreateString(Output, (ULONG) wcslen(Output), Password); + SysFreeString(Output); + + return Result; +} + +HRESULT STDMETHODCALLTYPE CUriRuntimeClass_get_Path( + IN IUriRuntimeClass *This, + OUT HSTRING *Path) +{ + HRESULT Result; + BSTR Output; + + Result = This->Uri->lpVtbl->GetPath(This->Uri, &Output); + if (FAILED(Result)) { + return Result; + } + + Result = WindowsCreateString(Output, (ULONG) wcslen(Output), Path); + SysFreeString(Output); + + return Result; +} + +HRESULT STDMETHODCALLTYPE CUriRuntimeClass_get_Query( + IN IUriRuntimeClass *This, + OUT HSTRING *Query) +{ + HRESULT Result; + BSTR Output; + + Result = This->Uri->lpVtbl->GetQuery(This->Uri, &Output); + if (FAILED(Result)) { + return Result; + } + + Result = WindowsCreateString(Output, (ULONG) wcslen(Output), Query); + SysFreeString(Output); + + return Result; +} + +HRESULT STDMETHODCALLTYPE CUriRuntimeClass_get_QueryParsed( + IN IUriRuntimeClass *This, + OUT IUnknown **QueryParsed) +{ + KexDebugCheckpoint(); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CUriRuntimeClass_get_RawUri( + IN IUriRuntimeClass *This, + OUT HSTRING *RawUri) +{ + HRESULT Result; + BSTR Output; + + Result = This->Uri->lpVtbl->GetRawUri(This->Uri, &Output); + if (FAILED(Result)) { + return Result; + } + + Result = WindowsCreateString(Output, (ULONG) wcslen(Output), RawUri); + SysFreeString(Output); + + return Result; +} + +HRESULT STDMETHODCALLTYPE CUriRuntimeClass_get_SchemeName( + IN IUriRuntimeClass *This, + OUT HSTRING *SchemeName) +{ + HRESULT Result; + BSTR Output; + + Result = This->Uri->lpVtbl->GetSchemeName(This->Uri, &Output); + if (FAILED(Result)) { + return Result; + } + + Result = WindowsCreateString(Output, (ULONG) wcslen(Output), SchemeName); + SysFreeString(Output); + + return Result; +} + +HRESULT STDMETHODCALLTYPE CUriRuntimeClass_get_UserName( + IN IUriRuntimeClass *This, + OUT HSTRING *UserName) +{ + HRESULT Result; + BSTR Output; + + Result = This->Uri->lpVtbl->GetUserName(This->Uri, &Output); + if (FAILED(Result)) { + return Result; + } + + Result = WindowsCreateString(Output, (ULONG) wcslen(Output), UserName); + SysFreeString(Output); + + return Result; +} + +HRESULT STDMETHODCALLTYPE CUriRuntimeClass_get_Port( + IN IUriRuntimeClass *This, + OUT PULONG Port) +{ + return This->Uri->lpVtbl->GetPort(This->Uri, Port); +} + +HRESULT STDMETHODCALLTYPE CUriRuntimeClass_get_Suspicious( + IN IUriRuntimeClass *This, + OUT PBOOLEAN Suspicious) +{ + KexDebugCheckpoint(); + + *Suspicious = FALSE; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CUriRuntimeClass_Equals( + IN IUriRuntimeClass *This, + IN IUriRuntimeClass *OtherUri, + OUT PBOOLEAN IsEqual) +{ + HRESULT Result; + BOOL Equal; + + Result = This->Uri->lpVtbl->IsEqual(This->Uri, OtherUri->Uri, &Equal); + + *IsEqual = Equal; + return Result; +} + +HRESULT STDMETHODCALLTYPE CUriRuntimeClass_CombineUri( + IN IUriRuntimeClass *This, + IN HSTRING ExtraPart, + OUT IUriRuntimeClass **NewUri) +{ + KexDebugCheckpoint(); + return E_NOTIMPL; +} + +IUriRuntimeClassVtbl CUriRuntimeClassVtbl = { + CUriRuntimeClass_QueryInterface, + CUriRuntimeClass_AddRef, + CUriRuntimeClass_Release, + CUriRuntimeClass_GetIids, + CUriRuntimeClass_GetRuntimeClassName, + CUriRuntimeClass_GetTrustLevel, + + CUriRuntimeClass_get_AbsoluteUri, + CUriRuntimeClass_get_DisplayUri, + CUriRuntimeClass_get_Domain, + CUriRuntimeClass_get_Extension, + CUriRuntimeClass_get_Fragment, + CUriRuntimeClass_get_Host, + CUriRuntimeClass_get_Password, + CUriRuntimeClass_get_Path, + CUriRuntimeClass_get_Query, + CUriRuntimeClass_get_QueryParsed, + CUriRuntimeClass_get_RawUri, + CUriRuntimeClass_get_SchemeName, + CUriRuntimeClass_get_UserName, + CUriRuntimeClass_get_Port, + CUriRuntimeClass_get_Suspicious, + CUriRuntimeClass_Equals, + CUriRuntimeClass_CombineUri +}; + +HRESULT STDMETHODCALLTYPE CUriRuntimeClassFactory_QueryInterface( + IN IUriRuntimeClassFactory *This, + IN REFIID RefIID, + OUT PPVOID Interface) +{ + ASSERT (This != NULL); + ASSERT (RefIID != NULL); + ASSERT (Interface != NULL); + + *Interface = NULL; + + if (IsEqualIID(RefIID, &IID_IUnknown) || + IsEqualIID(RefIID, &IID_IAgileObject) || + IsEqualIID(RefIID, &IID_IInspectable) || + IsEqualIID(RefIID, &IID_IUriRuntimeClassFactory)) { + + *Interface = This; + return S_OK; + } + + return E_NOINTERFACE; +} + +ULONG STDMETHODCALLTYPE CUriRuntimeClassFactory_AddRef( + IN IUriRuntimeClassFactory *This) +{ + return 1; +} + +ULONG STDMETHODCALLTYPE CUriRuntimeClassFactory_Release( + IN IUriRuntimeClassFactory *This) +{ + return 1; +} + +HRESULT STDMETHODCALLTYPE CUriRuntimeClassFactory_GetIids( + IN IUriRuntimeClassFactory *This, + OUT PULONG NumberOfIids, + OUT IID **IidArray) +{ + IID *Array; + ULONG Count; + + ASSERT (NumberOfIids != NULL); + ASSERT (IidArray != NULL); + + Count = 1; + + Array = (IID *) CoTaskMemAlloc(Count * sizeof(IID)); + if (!Array) { + return E_OUTOFMEMORY; + } + + *NumberOfIids = Count; + Array[0] = IID_IUriRuntimeClassFactory; + + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CUriRuntimeClassFactory_GetRuntimeClassName( + IN IUriRuntimeClassFactory *This, + OUT HSTRING *ClassName) +{ + PCWSTR Name = L"Windows.Foundation.Uri"; + ASSERT (ClassName != NULL); + return WindowsCreateString(Name, (ULONG) wcslen(Name), ClassName); +} + +HRESULT STDMETHODCALLTYPE CUriRuntimeClassFactory_GetTrustLevel( + IN IUriRuntimeClassFactory *This, + OUT TrustLevel *Level) +{ + ASSERT (Level != NULL); + *Level = BaseTrust; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CUriRuntimeClassFactory_CreateUri( + IN IUriRuntimeClassFactory *This, + IN HSTRING Uri, + OUT IUriRuntimeClass **UriRuntimeClass) +{ + HRESULT Result; + IUriRuntimeClass *RuntimeClass; + + ASSERT (UriRuntimeClass != NULL); + + RuntimeClass = SafeAlloc(IUriRuntimeClass, 1); + if (!RuntimeClass) { + return E_OUTOFMEMORY; + } + + RuntimeClass->lpVtbl = &CUriRuntimeClassVtbl; + RuntimeClass->RefCount = 1; + + Result = CreateUri( + WindowsGetStringRawBuffer(Uri, NULL), + Uri_CREATE_NO_IE_SETTINGS | Uri_CREATE_PRE_PROCESS_HTML_URI | + Uri_CREATE_CRACK_UNKNOWN_SCHEMES | Uri_CREATE_CANONICALIZE | + Uri_CREATE_NO_DECODE_EXTRA_INFO | Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME, + 0, + &RuntimeClass->Uri); + + if (FAILED(Result)) { + KexDebugCheckpoint(); + SafeFree(RuntimeClass); + return Result; + } + + ASSERT (RuntimeClass != NULL); + *UriRuntimeClass = RuntimeClass; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CUriRuntimeClassFactory_CreateWithRelativeUri( + IN IUriRuntimeClassFactory *This, + IN HSTRING BaseUri, + IN HSTRING RelativeUri, + OUT IUriRuntimeClass **UriRuntimeClass) +{ + KexDebugCheckpoint(); + return E_NOTIMPL; +} + +IUriRuntimeClassFactoryVtbl CUriRuntimeClassFactoryVtbl = { + CUriRuntimeClassFactory_QueryInterface, + CUriRuntimeClassFactory_AddRef, + CUriRuntimeClassFactory_Release, + CUriRuntimeClassFactory_GetIids, + CUriRuntimeClassFactory_GetRuntimeClassName, + CUriRuntimeClassFactory_GetTrustLevel, + CUriRuntimeClassFactory_CreateUri, + CUriRuntimeClassFactory_CreateWithRelativeUri +}; + +IUriRuntimeClassFactory CUriRuntimeClassFactory = { + &CUriRuntimeClassFactoryVtbl +}; \ No newline at end of file diff --git a/01-Extended DLLs/KxCom/winrt.c b/01-Extended DLLs/KxCom/winrt.c new file mode 100644 index 0000000..f3f70f4 --- /dev/null +++ b/01-Extended DLLs/KxCom/winrt.c @@ -0,0 +1,532 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// winrt.c +// +// Abstract: +// +// Implements the Windows Runtime HSTRING functions. +// +// Author: +// +// vxiiduu (11-Feb-2024) +// +// Environment: +// +// Win32 mode +// +// Revision History: +// +// vxiiduu 11-Feb-2024 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kxcomp.h" + +KXCOMAPI ULONG WINAPI WindowsGetStringLen( + IN HSTRING String) +{ + if (String) { + return String->Length; + } + + return 0; +} + +KXCOMAPI PCWSTR WINAPI WindowsGetStringRawBuffer( + IN HSTRING String, + OUT PULONG Length OPTIONAL) +{ + if (Length) { + *Length = WindowsGetStringLen(String); + } + + if (String) { + return String->StringRef; + } else { + return L""; + } +} + +STATIC HRESULT WINAPI WindowsCreateStringInternal( + IN ULONG SourceStringCch, + OUT HSTRING_ALLOCATED **AllocatedStringOut) +{ + ULONG AllocationCb; + HSTRING_ALLOCATED *AllocatedString; + + AllocationCb = SourceStringCch * 2; + + // check for overflow + if (AllocationCb < SourceStringCch) { + return MEM_E_INVALID_SIZE; + } + + if (AllocationCb + sizeof(HSTRING_ALLOCATED) < AllocationCb) { + return MEM_E_INVALID_SIZE; + } + + AllocationCb += sizeof(HSTRING_ALLOCATED); + + AllocatedString = (HSTRING_ALLOCATED *) SafeAlloc(BYTE, AllocationCb); + if (!AllocatedString) { + return E_OUTOFMEMORY; + } + + AllocatedString->Header.Flags = WRHF_NONE; + AllocatedString->Header.Length = SourceStringCch; + AllocatedString->Header.StringRef = AllocatedString->Data; + AllocatedString->RefCount = 1; + + *AllocatedStringOut = AllocatedString; + return S_OK; +} + +KXCOMAPI HRESULT WINAPI WindowsCreateString( + IN PCNZWCH SourceString, + IN ULONG SourceStringCch, + OUT HSTRING *String) +{ + HSTRING_ALLOCATED *AllocatedString; + HRESULT Result; + + if (!String) { + return E_INVALIDARG; + } + + *String = NULL; + + if (!SourceStringCch) { + // just leave a null pointer in *String + return S_OK; + } + + // allocate the new blank string + Result = WindowsCreateStringInternal(SourceStringCch, &AllocatedString); + if (FAILED(Result)) { + return Result; + } + + // copy and null terminate the string data + RtlCopyMemory(AllocatedString->Data, SourceString, SourceStringCch * sizeof(WCHAR)); + AllocatedString->Data[SourceStringCch] = '\0'; + + *String = &AllocatedString->Header; + return S_OK; +} + +KXCOMAPI HRESULT WINAPI WindowsCreateStringReference( + IN PCWSTR SourceString, + IN ULONG SourceStringCch, + OUT HSTRING_HEADER *StringHeader, + OUT HSTRING *String) +{ + if (!String || !StringHeader) { + return E_INVALIDARG; + } + + *String = NULL; + + if (SourceString && SourceString[SourceStringCch] != '\0') { + return E_STRING_NOT_NULL_TERMINATED; + } + + if (SourceStringCch && !SourceString) { + return E_POINTER; + } + + if (SourceStringCch != 0) { + StringHeader->Flags = WRHF_STRING_REFERENCE; + StringHeader->Length = SourceStringCch; + StringHeader->StringRef = SourceString; + *String = StringHeader; + } + + return S_OK; +} + +KXCOMAPI HRESULT WINAPI WindowsDuplicateString( + IN HSTRING OriginalString, + OUT HSTRING *DuplicatedString) +{ + if (!DuplicatedString) { + return E_INVALIDARG; + } + + *DuplicatedString = NULL; + + if (!OriginalString) { + // leave it as NULL + return S_OK; + } + + if (OriginalString->Flags & WRHF_STRING_REFERENCE) { + // allocate a copy + return WindowsCreateString( + OriginalString->StringRef, + OriginalString->Length, + DuplicatedString); + } else { + HSTRING_ALLOCATED *AllocatedString; + + AllocatedString = (HSTRING_ALLOCATED *) OriginalString; + + // just increment the ref count + InterlockedIncrement(&AllocatedString->RefCount); + *DuplicatedString = OriginalString; + } + + return S_OK; +} + +KXCOMAPI HRESULT WINAPI WindowsDeleteString( + IN HSTRING String) +{ + if (String) { + if (!(String->Flags & WRHF_STRING_REFERENCE)) { + HSTRING_ALLOCATED *AllocatedString; + + AllocatedString = (HSTRING_ALLOCATED *) String; + + if (InterlockedDecrement(&AllocatedString->RefCount) == 0) { + SafeFree(AllocatedString); + } + } + } + + return S_OK; +} + +KXCOMAPI BOOL WINAPI WindowsIsStringEmpty( + IN HSTRING String) +{ + if (String != NULL && String->Length == 0) { + return TRUE; + } + + return FALSE; +} + +KXCOMAPI HRESULT WINAPI WindowsStringHasEmbeddedNull( + IN HSTRING String, + OUT PBOOL HasEmbeddedNull) +{ + PCWCHAR Pointer; + PCWCHAR EndOfString; + + if (HasEmbeddedNull == NULL) { + return E_INVALIDARG; + } + + *HasEmbeddedNull = FALSE; + + if (!String || String->Length == 0) { + return S_OK; + } + + if (String->Flags & WRHF_EMBEDDED_NULLS_COMPUTED) { + // We know whether or not this string has embedded nulls, because + // this string has already been through this function at least once. + *HasEmbeddedNull = (String->Flags & WRHF_HAS_EMBEDDED_NULLS); + return S_OK; + } + + // + // We don't know yet whether this string has embedded nulls. + // + + Pointer = String->StringRef; + EndOfString = &String->StringRef[String->Length]; + + while (Pointer < EndOfString) { + if (*Pointer == '\0') { + String->Flags |= WRHF_HAS_EMBEDDED_NULLS; + *HasEmbeddedNull = TRUE; + break; + } + + ++Pointer; + } + + // + // Note down that we have already calculated whether this string has + // embedded null characters in it, so next time this function is called, + // we don't have to do much work. + // + + String->Flags |= WRHF_EMBEDDED_NULLS_COMPUTED; + return S_OK; +} + +// +// *ComparisonResult will be: +// -1 if String2 is "greater than" String1 +// 0 if the strings are equal +// 1 if String1 is "greater than" String2 +// +KXCOMAPI HRESULT WINAPI WindowsCompareStringOrdinal( + IN HSTRING String1, + IN HSTRING String2, + OUT PINT ComparisonResult) +{ + INT TemporaryComparisonResult; + BOOLEAN String2WasNull; + + if (ComparisonResult == NULL) { + return E_INVALIDARG; + } + + if (String1 == String2) { + // the string pointers are equal so the strings must be equal + *ComparisonResult = 0; + return S_OK; + } + + if (String2 == NULL) { + // I have no idea what this is intended to accomplish, but it's in the original + // Windows function... + String2 = String1; + String1 = NULL; + String2WasNull = TRUE; + } + + if (String1 == NULL) { + if (String2->Length == 0) { + *ComparisonResult = 0; + } else { + if (String2WasNull) { + *ComparisonResult = 1; + } else { + *ComparisonResult = -1; + } + } + + return S_OK; + } + + TemporaryComparisonResult = CompareStringOrdinal( + String1->StringRef, + String1->Length, + String2->StringRef, + String2->Length, + FALSE); + + *ComparisonResult = 0; + + if (TemporaryComparisonResult == CSTR_LESS_THAN) { + *ComparisonResult = -1; + } else if (TemporaryComparisonResult == CSTR_GREATER_THAN) { + *ComparisonResult = 1; + } + + return S_OK; +} + +KXCOMAPI HRESULT WINAPI WindowsSubstring( + IN HSTRING String, + IN ULONG StartIndex, + OUT HSTRING *NewString) +{ + if (!NewString) { + return E_INVALIDARG; + } + + *NewString = NULL; + + if (String != NULL && StartIndex > String->Length || + String == NULL && StartIndex != 0) { + + // start index is beyond the end of the original string + return E_BOUNDS; + } + + if (String == NULL || String->Length == 0 || StartIndex == String->Length) { + // leave an empty (NULL) string as the output + return S_OK; + } + + return WindowsCreateString( + &String->StringRef[StartIndex], + String->Length - StartIndex, + NewString); +} + +KXCOMAPI HRESULT WINAPI WindowsSubstringWithSpecifiedLength( + IN HSTRING OriginalString, + IN ULONG StartIndex, + IN ULONG SubstringLength, + OUT HSTRING *NewString) +{ + if (!NewString) { + return E_INVALIDARG; + } + + *NewString = NULL; + + if (OriginalString != NULL && StartIndex > OriginalString->Length || + OriginalString == NULL && (StartIndex != 0 || SubstringLength != 0)) { + + return E_BOUNDS; + } + + if (StartIndex + SubstringLength < StartIndex) { + return HRESULT_ARITHMETIC_OVERFLOW; + } + + if (OriginalString != NULL && StartIndex + SubstringLength > OriginalString->Length) { + return E_BOUNDS; + } + + if (!OriginalString || OriginalString->Length == 0 || SubstringLength == 0) { + // leave empty NULL string as *NewString + return S_OK; + } + + return WindowsCreateString( + &OriginalString->StringRef[StartIndex], + SubstringLength, + NewString); +} + +KXCOMAPI HRESULT WINAPI WindowsConcatString( + IN HSTRING String1, + IN HSTRING String2, + OUT HSTRING *NewString) +{ + HRESULT Result; + ULONG NewStringLength; + HSTRING_ALLOCATED *AllocatedString; + + if (!NewString) { + return E_INVALIDARG; + } + + *NewString = NULL; + + if (!String1 && !String2) { + // leave NULL in NewString + return S_OK; + } + + if (!String1 || !String2) { + HSTRING NonNullString; + + // I would use a bitwise OR operation here, but the compiler was making me + // put in a lot of casts so I gave up. + NonNullString = String1 ? String1 : String2; + ASSERT (NonNullString != NULL); + + return WindowsDuplicateString(NonNullString, NewString); + } + + ASSERT (String1 && String2); + + // + // Figure out the length of the new string by adding the two source strings' + // lengths together while handling overflow. + // + + if (String1->Length + String2->Length < String1->Length) { + return HRESULT_ARITHMETIC_OVERFLOW; + } + + NewStringLength = String1->Length + String2->Length; + + // + // Allocate a new string. + // + + Result = WindowsCreateStringInternal(NewStringLength, &AllocatedString); + if (FAILED(Result)) { + return Result; + } + + // + // Copy and null terminate the string data. + // + + RtlCopyMemory(AllocatedString->Data, String1->StringRef, String1->Length); + RtlCopyMemory(AllocatedString->Data + String1->Length, String2->StringRef, String2->Length); + AllocatedString->Data[NewStringLength] = '\0'; + + *NewString = &AllocatedString->Header; + return S_OK; +} + +KXCOMAPI HRESULT WINAPI WindowsPreallocateStringBuffer( + IN ULONG Length, + OUT PPWSTR CharacterBuffer, + OUT PHSTRING_BUFFER BufferHandle) +{ + HRESULT Result; + HSTRING_ALLOCATED *AllocatedString; + + if (!CharacterBuffer || !BufferHandle) { + return E_POINTER; + } + + if (Length == 0) { + *CharacterBuffer = L""; + *BufferHandle = NULL; + return S_OK; + } + + Result = WindowsCreateStringInternal(Length + 1, &AllocatedString); + if (FAILED(Result)) { + return Result; + } + + // this magic number is here for WindowsPromoteStringBuffer and + // WindowsDeleteStringBuffer. + AllocatedString->Header.Flags = WRHF_STRING_BUFFER_MAGIC; + AllocatedString->Data[Length] = '\0'; + + *CharacterBuffer = AllocatedString->Data; + *BufferHandle = AllocatedString; + + return S_OK; +} + +KXCOMAPI HRESULT WINAPI WindowsDeleteStringBuffer( + IN HSTRING_BUFFER BufferHandle) +{ + if (!BufferHandle) { + return S_OK; + } + + if (BufferHandle->Header.Flags != WRHF_STRING_BUFFER_MAGIC) { + RaiseException(STATUS_INVALID_PARAMETER, EXCEPTION_NONCONTINUABLE, 0, NULL); + NOT_REACHED; + } + + return WindowsDeleteString(&BufferHandle->Header); +} + +KXCOMAPI HRESULT WINAPI WindowsPromoteStringBuffer( + IN HSTRING_BUFFER BufferHandle, + OUT HSTRING *NewString) +{ + if (!NewString) { + return E_POINTER; + } + + *NewString = NULL; + + if (!BufferHandle) { + // leave NULL in NewString + return S_OK; + } + + if (BufferHandle->Header.Flags != WRHF_STRING_BUFFER_MAGIC || + BufferHandle->Data[BufferHandle->Header.Length] != '\0') { + + return E_INVALIDARG; + } + + BufferHandle->Header.Flags = WRHF_NONE; + *NewString = &BufferHandle->Header; + + return S_OK; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxCrt/KxCrt.rc b/01-Extended DLLs/KxCrt/KxCrt.rc new file mode 100644 index 0000000..839f723 --- /dev/null +++ b/01-Extended DLLs/KxCrt/KxCrt.rc @@ -0,0 +1,30 @@ +#include "buildcfg.h" +#include +#include + +1 VERSIONINFO + FILEVERSION KEX_VERSION_FV + FILEOS VOS_NT +#if defined(KEX_TARGET_TYPE_EXE) + FILETYPE VFT_APP +#elif defined(KEX_TARGET_TYPE_DLL) + FILETYPE VFT_DLL +#endif +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904B0" + BEGIN + VALUE "LegalCopyright", KEX_WEB_STR + VALUE "FileDescription", "VxKex CRT Extension DLL" + VALUE "FileVersion", KEX_VERSION_STR + VALUE "InternalName", KEX_COMPONENT + VALUE "OriginalFilename", "KXCRT.DLL" + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409 0x04B0 + END +END \ No newline at end of file diff --git a/01-Extended DLLs/KxCrt/KxCrt.vcxproj b/01-Extended DLLs/KxCrt/KxCrt.vcxproj new file mode 100644 index 0000000..e67993c --- /dev/null +++ b/01-Extended DLLs/KxCrt/KxCrt.vcxproj @@ -0,0 +1,238 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {64D4ABD4-4C7D-47AC-A7E2-BCB6D1F1CF81} + Win32Proj + KxCrt + + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + + + + + + + + + + + + + + + + + false + false + + + false + false + + + false + false + + + false + false + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;KXCRT_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + false + true + true + true + false + Default + false + Cdecl + CompileAsC + false + + + Windows + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + kxcrt.def + true + /ignore:4102 %(AdditionalOptions) + + + $(SolutionDir)\00-Common Headers + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;KXCRT_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + false + true + true + true + false + Default + false + Cdecl + CompileAsC + false + + + Windows + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + kxcrt.def + true + /ignore:4102 %(AdditionalOptions) + + + $(SolutionDir)\00-Common Headers + + + + + Level3 + NotUsing + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;KXCRT_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + false + true + true + true + false + Default + false + Cdecl + CompileAsC + false + + + Windows + true + true + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + kxcrt.def + true + /ignore:4102 %(AdditionalOptions) + + + $(SolutionDir)\00-Common Headers + + + + + Level3 + NotUsing + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;KXCRT_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + false + true + true + true + false + Default + false + Cdecl + CompileAsC + false + + + Windows + true + true + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + kxcrt.def + true + /ignore:4102 %(AdditionalOptions) + + + $(SolutionDir)\00-Common Headers + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/01-Extended DLLs/KxCrt/KxCrt.vcxproj.filters b/01-Extended DLLs/KxCrt/KxCrt.vcxproj.filters new file mode 100644 index 0000000..56cadad --- /dev/null +++ b/01-Extended DLLs/KxCrt/KxCrt.vcxproj.filters @@ -0,0 +1,43 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + + + Resource Files + + + + + Source Files + + + \ No newline at end of file diff --git a/01-Extended DLLs/KxCrt/buildcfg.h b/01-Extended DLLs/KxCrt/buildcfg.h new file mode 100644 index 0000000..4e6830e --- /dev/null +++ b/01-Extended DLLs/KxCrt/buildcfg.h @@ -0,0 +1,54 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN +#define NOGDICAPMASKS +#define NOVIRTUALKEYCODES +#define NOWINMESSAGES +#define NOWINSTYLES +#define NOSYSMETRICS +#define NOMENUS +#define NOICONS +#define NOKEYSTATES +#define NOSYSCOMMANDS +#define NORASTEROPS +#define NOSHOWWINDOW +#define NOATOM +#define NOCLIPBOARD +#define NOCOLOR +#define NOCTLMGR +#define NODRAWTEXT +#define NOGDI +#define NOKERNEL +#define NOUSER +#define NONLS +#define NOMB +#define NOMEMMGR +#define NOMSG +#define NOOPENFILE +#define NOSCROLL +#define NOTEXTMETRIC +#define NOWH +#define NOWINOFFSETS +#define NOCOMM +#define NOKANJI +#define NOHELP +#define NOPROFILER +#define NODEFERWINDOWPOS +#define NOMCX +#define NOCRYPT +#define NOMETAFILE +#define NOSERVICE +#define NOSOUND +#define _UXTHEME_H_ + +#define KXCRTAPI + +#ifdef _M_X64 +# pragma comment(lib, "msvcrt_x64.lib") +#else +# pragma comment(lib, "msvcrt_x86.lib") +#endif + +#define KEX_COMPONENT L"KxCrt" +#define KEX_ENV_WIN32 +#define KEX_TARGET_TYPE_DLL diff --git a/01-Extended DLLs/KxCrt/dllmain.c b/01-Extended DLLs/KxCrt/dllmain.c new file mode 100644 index 0000000..da6c514 --- /dev/null +++ b/01-Extended DLLs/KxCrt/dllmain.c @@ -0,0 +1,14 @@ +#include "buildcfg.h" +#include + +BOOL WINAPI DllMain( + IN HMODULE DllHandle, + IN ULONG Reason, + IN PCONTEXT Context) +{ + if (Reason == DLL_PROCESS_ATTACH) { + LdrDisableThreadCalloutsForDll(DllHandle); + } + + return TRUE; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxCrt/forwards.c b/01-Extended DLLs/KxCrt/forwards.c new file mode 100644 index 0000000..50a2d66 --- /dev/null +++ b/01-Extended DLLs/KxCrt/forwards.c @@ -0,0 +1,2704 @@ +#ifdef _M_X64 + +// Generated by KexExprt from "C:\Windows\system32\msvcrt.dll" +#pragma comment(linker, "/EXPORT:??0__non_rtti_object@@QEAA@AEBV0@@Z=msvcrt.??0__non_rtti_object@@QEAA@AEBV0@@Z") +#pragma comment(linker, "/EXPORT:??0__non_rtti_object@@QEAA@PEBD@Z=msvcrt.??0__non_rtti_object@@QEAA@PEBD@Z") +#pragma comment(linker, "/EXPORT:??0bad_cast@@AAE@PBQBD@Z=msvcrt.??0bad_cast@@AAE@PBQBD@Z") +#pragma comment(linker, "/EXPORT:??0bad_cast@@AEAA@PEBQEBD@Z=msvcrt.??0bad_cast@@AEAA@PEBQEBD@Z") +#pragma comment(linker, "/EXPORT:??0bad_cast@@QAE@ABQBD@Z=msvcrt.??0bad_cast@@QAE@ABQBD@Z") +#pragma comment(linker, "/EXPORT:??0bad_cast@@QEAA@AEBQEBD@Z=msvcrt.??0bad_cast@@QEAA@AEBQEBD@Z") +#pragma comment(linker, "/EXPORT:??0bad_cast@@QEAA@AEBV0@@Z=msvcrt.??0bad_cast@@QEAA@AEBV0@@Z") +#pragma comment(linker, "/EXPORT:??0bad_cast@@QEAA@PEBD@Z=msvcrt.??0bad_cast@@QEAA@PEBD@Z") +#pragma comment(linker, "/EXPORT:??0bad_typeid@@QEAA@AEBV0@@Z=msvcrt.??0bad_typeid@@QEAA@AEBV0@@Z") +#pragma comment(linker, "/EXPORT:??0bad_typeid@@QEAA@PEBD@Z=msvcrt.??0bad_typeid@@QEAA@PEBD@Z") +#pragma comment(linker, "/EXPORT:??0exception@@QEAA@AEBQEBD@Z=msvcrt.??0exception@@QEAA@AEBQEBD@Z") +#pragma comment(linker, "/EXPORT:??0exception@@QEAA@AEBQEBDH@Z=msvcrt.??0exception@@QEAA@AEBQEBDH@Z") +#pragma comment(linker, "/EXPORT:??0exception@@QEAA@AEBV0@@Z=msvcrt.??0exception@@QEAA@AEBV0@@Z") +#pragma comment(linker, "/EXPORT:??0exception@@QEAA@XZ=msvcrt.??0exception@@QEAA@XZ") +#pragma comment(linker, "/EXPORT:??1__non_rtti_object@@UEAA@XZ=msvcrt.??1__non_rtti_object@@UEAA@XZ") +#pragma comment(linker, "/EXPORT:??1bad_cast@@UEAA@XZ=msvcrt.??1bad_cast@@UEAA@XZ") +#pragma comment(linker, "/EXPORT:??1bad_typeid@@UEAA@XZ=msvcrt.??1bad_typeid@@UEAA@XZ") +#pragma comment(linker, "/EXPORT:??1exception@@UEAA@XZ=msvcrt.??1exception@@UEAA@XZ") +#pragma comment(linker, "/EXPORT:??1type_info@@UEAA@XZ=msvcrt.??1type_info@@UEAA@XZ") +#pragma comment(linker, "/EXPORT:??2@YAPEAX_K@Z=msvcrt.??2@YAPEAX_K@Z") +#pragma comment(linker, "/EXPORT:??2@YAPEAX_KHPEBDH@Z=msvcrt.??2@YAPEAX_KHPEBDH@Z") +#pragma comment(linker, "/EXPORT:??3@YAXPEAX@Z=msvcrt.??3@YAXPEAX@Z") +#pragma comment(linker, "/EXPORT:??4__non_rtti_object@@QEAAAEAV0@AEBV0@@Z=msvcrt.??4__non_rtti_object@@QEAAAEAV0@AEBV0@@Z") +#pragma comment(linker, "/EXPORT:??4bad_cast@@QEAAAEAV0@AEBV0@@Z=msvcrt.??4bad_cast@@QEAAAEAV0@AEBV0@@Z") +#pragma comment(linker, "/EXPORT:??4bad_typeid@@QEAAAEAV0@AEBV0@@Z=msvcrt.??4bad_typeid@@QEAAAEAV0@AEBV0@@Z") +#pragma comment(linker, "/EXPORT:??4exception@@QEAAAEAV0@AEBV0@@Z=msvcrt.??4exception@@QEAAAEAV0@AEBV0@@Z") +#pragma comment(linker, "/EXPORT:??8type_info@@QEBAHAEBV0@@Z=msvcrt.??8type_info@@QEBAHAEBV0@@Z") +#pragma comment(linker, "/EXPORT:??9type_info@@QEBAHAEBV0@@Z=msvcrt.??9type_info@@QEBAHAEBV0@@Z") +#pragma comment(linker, "/EXPORT:??_7__non_rtti_object@@6B@=msvcrt.??_7__non_rtti_object@@6B@") +#pragma comment(linker, "/EXPORT:??_7bad_cast@@6B@=msvcrt.??_7bad_cast@@6B@") +#pragma comment(linker, "/EXPORT:??_7bad_typeid@@6B@=msvcrt.??_7bad_typeid@@6B@") +#pragma comment(linker, "/EXPORT:??_7exception@@6B@=msvcrt.??_7exception@@6B@") +#pragma comment(linker, "/EXPORT:??_Fbad_cast@@QEAAXXZ=msvcrt.??_Fbad_cast@@QEAAXXZ") +#pragma comment(linker, "/EXPORT:??_Fbad_typeid@@QEAAXXZ=msvcrt.??_Fbad_typeid@@QEAAXXZ") +#pragma comment(linker, "/EXPORT:??_U@YAPEAX_K@Z=msvcrt.??_U@YAPEAX_K@Z") +#pragma comment(linker, "/EXPORT:??_U@YAPEAX_KHPEBDH@Z=msvcrt.??_U@YAPEAX_KHPEBDH@Z") +#pragma comment(linker, "/EXPORT:??_V@YAXPEAX@Z=msvcrt.??_V@YAXPEAX@Z") +#pragma comment(linker, "/EXPORT:?_query_new_handler@@YAP6AH_K@ZXZ=msvcrt.?_query_new_handler@@YAP6AH_K@ZXZ") +#pragma comment(linker, "/EXPORT:?_query_new_mode@@YAHXZ=msvcrt.?_query_new_mode@@YAHXZ") +#pragma comment(linker, "/EXPORT:?_set_new_handler@@YAP6AH_K@ZP6AH0@Z@Z=msvcrt.?_set_new_handler@@YAP6AH_K@ZP6AH0@Z@Z") +#pragma comment(linker, "/EXPORT:?_set_new_mode@@YAHH@Z=msvcrt.?_set_new_mode@@YAHH@Z") +#pragma comment(linker, "/EXPORT:?_set_se_translator@@YAP6AXIPEAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z=msvcrt.?_set_se_translator@@YAP6AXIPEAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z") +#pragma comment(linker, "/EXPORT:?before@type_info@@QEBAHAEBV1@@Z=msvcrt.?before@type_info@@QEBAHAEBV1@@Z") +#pragma comment(linker, "/EXPORT:?name@type_info@@QEBAPEBDXZ=msvcrt.?name@type_info@@QEBAPEBDXZ") +#pragma comment(linker, "/EXPORT:?raw_name@type_info@@QEBAPEBDXZ=msvcrt.?raw_name@type_info@@QEBAPEBDXZ") +#pragma comment(linker, "/EXPORT:?set_new_handler@@YAP6AXXZP6AXXZ@Z=msvcrt.?set_new_handler@@YAP6AXXZP6AXXZ@Z") +#pragma comment(linker, "/EXPORT:?set_terminate@@YAP6AXXZP6AXXZ@Z=msvcrt.?set_terminate@@YAP6AXXZP6AXXZ@Z") +#pragma comment(linker, "/EXPORT:?set_unexpected@@YAP6AXXZP6AXXZ@Z=msvcrt.?set_unexpected@@YAP6AXXZP6AXXZ@Z") +#pragma comment(linker, "/EXPORT:?terminate@@YAXXZ=msvcrt.?terminate@@YAXXZ") +#pragma comment(linker, "/EXPORT:?unexpected@@YAXXZ=msvcrt.?unexpected@@YAXXZ") +#pragma comment(linker, "/EXPORT:?what@exception@@UEBAPEBDXZ=msvcrt.?what@exception@@UEBAPEBDXZ") +#pragma comment(linker, "/EXPORT:_CrtCheckMemory=msvcrt._CrtCheckMemory") +#pragma comment(linker, "/EXPORT:_CrtDbgBreak=msvcrt._CrtDbgBreak") +#pragma comment(linker, "/EXPORT:_CrtDbgReport=msvcrt._CrtDbgReport") +#pragma comment(linker, "/EXPORT:_CrtDbgReportV=msvcrt._CrtDbgReportV") +#pragma comment(linker, "/EXPORT:_CrtDbgReportW=msvcrt._CrtDbgReportW") +#pragma comment(linker, "/EXPORT:_CrtDbgReportWV=msvcrt._CrtDbgReportWV") +#pragma comment(linker, "/EXPORT:_CrtDoForAllClientObjects=msvcrt._CrtDoForAllClientObjects") +#pragma comment(linker, "/EXPORT:_CrtDumpMemoryLeaks=msvcrt._CrtDumpMemoryLeaks") +#pragma comment(linker, "/EXPORT:_CrtIsMemoryBlock=msvcrt._CrtIsMemoryBlock") +#pragma comment(linker, "/EXPORT:_CrtIsValidHeapPointer=msvcrt._CrtIsValidHeapPointer") +#pragma comment(linker, "/EXPORT:_CrtIsValidPointer=msvcrt._CrtIsValidPointer") +#pragma comment(linker, "/EXPORT:_CrtMemCheckpoint=msvcrt._CrtMemCheckpoint") +#pragma comment(linker, "/EXPORT:_CrtMemDifference=msvcrt._CrtMemDifference") +#pragma comment(linker, "/EXPORT:_CrtMemDumpAllObjectsSince=msvcrt._CrtMemDumpAllObjectsSince") +#pragma comment(linker, "/EXPORT:_CrtMemDumpStatistics=msvcrt._CrtMemDumpStatistics") +#pragma comment(linker, "/EXPORT:_CrtReportBlockType=msvcrt._CrtReportBlockType") +#pragma comment(linker, "/EXPORT:_CrtSetAllocHook=msvcrt._CrtSetAllocHook") +#pragma comment(linker, "/EXPORT:_CrtSetBreakAlloc=msvcrt._CrtSetBreakAlloc") +#pragma comment(linker, "/EXPORT:_CrtSetDbgBlockType=msvcrt._CrtSetDbgBlockType") +#pragma comment(linker, "/EXPORT:_CrtSetDbgFlag=msvcrt._CrtSetDbgFlag") +#pragma comment(linker, "/EXPORT:_CrtSetDumpClient=msvcrt._CrtSetDumpClient") +#pragma comment(linker, "/EXPORT:_CrtSetReportFile=msvcrt._CrtSetReportFile") +#pragma comment(linker, "/EXPORT:_CrtSetReportHook=msvcrt._CrtSetReportHook") +#pragma comment(linker, "/EXPORT:_CrtSetReportHook2=msvcrt._CrtSetReportHook2") +#pragma comment(linker, "/EXPORT:_CrtSetReportMode=msvcrt._CrtSetReportMode") +#pragma comment(linker, "/EXPORT:_CxxThrowException=msvcrt._CxxThrowException") +#pragma comment(linker, "/EXPORT:_Getdays=msvcrt._Getdays") +#pragma comment(linker, "/EXPORT:_Getmonths=msvcrt._Getmonths") +#pragma comment(linker, "/EXPORT:_Gettnames=msvcrt._Gettnames") +#pragma comment(linker, "/EXPORT:_HUGE=msvcrt._HUGE") +#pragma comment(linker, "/EXPORT:_Strftime=msvcrt._Strftime") +#pragma comment(linker, "/EXPORT:_XcptFilter=msvcrt._XcptFilter") +#pragma comment(linker, "/EXPORT:__C_specific_handler=msvcrt.__C_specific_handler") +#pragma comment(linker, "/EXPORT:__CppXcptFilter=msvcrt.__CppXcptFilter") +#pragma comment(linker, "/EXPORT:__CxxFrameHandler=msvcrt.__CxxFrameHandler") +#pragma comment(linker, "/EXPORT:__CxxFrameHandler2=msvcrt.__CxxFrameHandler2") +#pragma comment(linker, "/EXPORT:__CxxFrameHandler3=msvcrt.__CxxFrameHandler3") +#pragma comment(linker, "/EXPORT:__DestructExceptionObject=msvcrt.__DestructExceptionObject") +#pragma comment(linker, "/EXPORT:__RTCastToVoid=msvcrt.__RTCastToVoid") +#pragma comment(linker, "/EXPORT:__RTDynamicCast=msvcrt.__RTDynamicCast") +#pragma comment(linker, "/EXPORT:__RTtypeid=msvcrt.__RTtypeid") +#pragma comment(linker, "/EXPORT:__STRINGTOLD=msvcrt.__STRINGTOLD") +#pragma comment(linker, "/EXPORT:___lc_codepage_func=msvcrt.___lc_codepage_func") +#pragma comment(linker, "/EXPORT:___lc_collate_cp_func=msvcrt.___lc_collate_cp_func") +#pragma comment(linker, "/EXPORT:___lc_handle_func=msvcrt.___lc_handle_func") +#pragma comment(linker, "/EXPORT:___mb_cur_max_func=msvcrt.___mb_cur_max_func") +#pragma comment(linker, "/EXPORT:___setlc_active_func=msvcrt.___setlc_active_func") +#pragma comment(linker, "/EXPORT:___unguarded_readlc_active_add_func=msvcrt.___unguarded_readlc_active_add_func") +#pragma comment(linker, "/EXPORT:__argc=msvcrt.__argc") +#pragma comment(linker, "/EXPORT:__argv=msvcrt.__argv") +#pragma comment(linker, "/EXPORT:__badioinfo=msvcrt.__badioinfo") +#pragma comment(linker, "/EXPORT:__crtCompareStringA=msvcrt.__crtCompareStringA") +#pragma comment(linker, "/EXPORT:__crtCompareStringW=msvcrt.__crtCompareStringW") +#pragma comment(linker, "/EXPORT:__crtGetLocaleInfoW=msvcrt.__crtGetLocaleInfoW") +#pragma comment(linker, "/EXPORT:__crtGetStringTypeW=msvcrt.__crtGetStringTypeW") +#pragma comment(linker, "/EXPORT:__crtLCMapStringA=msvcrt.__crtLCMapStringA") +#pragma comment(linker, "/EXPORT:__crtLCMapStringW=msvcrt.__crtLCMapStringW") +#pragma comment(linker, "/EXPORT:__daylight=msvcrt.__daylight") +#pragma comment(linker, "/EXPORT:__dllonexit=msvcrt.__dllonexit") +#pragma comment(linker, "/EXPORT:__doserrno=msvcrt.__doserrno") +#pragma comment(linker, "/EXPORT:__dstbias=msvcrt.__dstbias") +#pragma comment(linker, "/EXPORT:__fpecode=msvcrt.__fpecode") +#pragma comment(linker, "/EXPORT:__getmainargs=msvcrt.__getmainargs") +#pragma comment(linker, "/EXPORT:__initenv=msvcrt.__initenv") +#pragma comment(linker, "/EXPORT:__iob_func=msvcrt.__iob_func") +#pragma comment(linker, "/EXPORT:__isascii=msvcrt.__isascii") +#pragma comment(linker, "/EXPORT:__iscsym=msvcrt.__iscsym") +#pragma comment(linker, "/EXPORT:__iscsymf=msvcrt.__iscsymf") +#pragma comment(linker, "/EXPORT:__lc_codepage=msvcrt.__lc_codepage") +#pragma comment(linker, "/EXPORT:__lc_collate_cp=msvcrt.__lc_collate_cp") +#pragma comment(linker, "/EXPORT:__lc_handle=msvcrt.__lc_handle") +#pragma comment(linker, "/EXPORT:__lconv_init=msvcrt.__lconv_init") +#pragma comment(linker, "/EXPORT:__mb_cur_max=msvcrt.__mb_cur_max") +#pragma comment(linker, "/EXPORT:__pctype_func=msvcrt.__pctype_func") +#pragma comment(linker, "/EXPORT:__pioinfo=msvcrt.__pioinfo") +#pragma comment(linker, "/EXPORT:__pwctype_func=msvcrt.__pwctype_func") +#pragma comment(linker, "/EXPORT:__pxcptinfoptrs=msvcrt.__pxcptinfoptrs") +#pragma comment(linker, "/EXPORT:__set_app_type=msvcrt.__set_app_type") +#pragma comment(linker, "/EXPORT:__setlc_active=msvcrt.__setlc_active") +#pragma comment(linker, "/EXPORT:__setusermatherr=msvcrt.__setusermatherr") +#pragma comment(linker, "/EXPORT:__strncnt=msvcrt.__strncnt") +#pragma comment(linker, "/EXPORT:__threadhandle=msvcrt.__threadhandle") +#pragma comment(linker, "/EXPORT:__threadid=msvcrt.__threadid") +#pragma comment(linker, "/EXPORT:__toascii=msvcrt.__toascii") +#pragma comment(linker, "/EXPORT:__unDName=msvcrt.__unDName") +#pragma comment(linker, "/EXPORT:__unDNameEx=msvcrt.__unDNameEx") +#pragma comment(linker, "/EXPORT:__uncaught_exception=msvcrt.__uncaught_exception") +#pragma comment(linker, "/EXPORT:__unguarded_readlc_active=msvcrt.__unguarded_readlc_active") +#pragma comment(linker, "/EXPORT:__wargv=msvcrt.__wargv") +#pragma comment(linker, "/EXPORT:__wcserror=msvcrt.__wcserror") +#pragma comment(linker, "/EXPORT:__wcserror_s=msvcrt.__wcserror_s") +#pragma comment(linker, "/EXPORT:__wcsncnt=msvcrt.__wcsncnt") +#pragma comment(linker, "/EXPORT:__wgetmainargs=msvcrt.__wgetmainargs") +#pragma comment(linker, "/EXPORT:__winitenv=msvcrt.__winitenv") +#pragma comment(linker, "/EXPORT:_abs64=msvcrt._abs64") +#pragma comment(linker, "/EXPORT:_access=msvcrt._access") +#pragma comment(linker, "/EXPORT:_access_s=msvcrt._access_s") +#pragma comment(linker, "/EXPORT:_acmdln=msvcrt._acmdln") +#pragma comment(linker, "/EXPORT:_aexit_rtn=msvcrt._aexit_rtn") +#pragma comment(linker, "/EXPORT:_aligned_free=msvcrt._aligned_free") +#pragma comment(linker, "/EXPORT:_aligned_free_dbg=msvcrt._aligned_free_dbg") +#pragma comment(linker, "/EXPORT:_aligned_malloc=msvcrt._aligned_malloc") +#pragma comment(linker, "/EXPORT:_aligned_malloc_dbg=msvcrt._aligned_malloc_dbg") +#pragma comment(linker, "/EXPORT:_aligned_offset_malloc=msvcrt._aligned_offset_malloc") +#pragma comment(linker, "/EXPORT:_aligned_offset_malloc_dbg=msvcrt._aligned_offset_malloc_dbg") +#pragma comment(linker, "/EXPORT:_aligned_offset_realloc=msvcrt._aligned_offset_realloc") +#pragma comment(linker, "/EXPORT:_aligned_offset_realloc_dbg=msvcrt._aligned_offset_realloc_dbg") +#pragma comment(linker, "/EXPORT:_aligned_realloc=msvcrt._aligned_realloc") +#pragma comment(linker, "/EXPORT:_aligned_realloc_dbg=msvcrt._aligned_realloc_dbg") +#pragma comment(linker, "/EXPORT:_amsg_exit=msvcrt._amsg_exit") +#pragma comment(linker, "/EXPORT:_assert=msvcrt._assert") +#pragma comment(linker, "/EXPORT:_atodbl=msvcrt._atodbl") +#pragma comment(linker, "/EXPORT:_atodbl_l=msvcrt._atodbl_l") +#pragma comment(linker, "/EXPORT:_atof_l=msvcrt._atof_l") +#pragma comment(linker, "/EXPORT:_atoflt_l=msvcrt._atoflt_l") +#pragma comment(linker, "/EXPORT:_atoi64=msvcrt._atoi64") +#pragma comment(linker, "/EXPORT:_atoi64_l=msvcrt._atoi64_l") +#pragma comment(linker, "/EXPORT:_atoi_l=msvcrt._atoi_l") +#pragma comment(linker, "/EXPORT:_atol_l=msvcrt._atol_l") +#pragma comment(linker, "/EXPORT:_atoldbl=msvcrt._atoldbl") +#pragma comment(linker, "/EXPORT:_atoldbl_l=msvcrt._atoldbl_l") +#pragma comment(linker, "/EXPORT:_beep=msvcrt._beep") +#pragma comment(linker, "/EXPORT:_beginthread=msvcrt._beginthread") +#pragma comment(linker, "/EXPORT:_beginthreadex=msvcrt._beginthreadex") +#pragma comment(linker, "/EXPORT:_c_exit=msvcrt._c_exit") +#pragma comment(linker, "/EXPORT:_cabs=msvcrt._cabs") +#pragma comment(linker, "/EXPORT:_callnewh=msvcrt._callnewh") +#pragma comment(linker, "/EXPORT:_calloc_dbg=msvcrt._calloc_dbg") +#pragma comment(linker, "/EXPORT:_cexit=msvcrt._cexit") +#pragma comment(linker, "/EXPORT:_cgets=msvcrt._cgets") +#pragma comment(linker, "/EXPORT:_cgets_s=msvcrt._cgets_s") +#pragma comment(linker, "/EXPORT:_cgetws=msvcrt._cgetws") +#pragma comment(linker, "/EXPORT:_cgetws_s=msvcrt._cgetws_s") +#pragma comment(linker, "/EXPORT:_chdir=msvcrt._chdir") +#pragma comment(linker, "/EXPORT:_chdrive=msvcrt._chdrive") +#pragma comment(linker, "/EXPORT:_chgsign=msvcrt._chgsign") +#pragma comment(linker, "/EXPORT:_chgsignf=msvcrt._chgsignf") +#pragma comment(linker, "/EXPORT:_chmod=msvcrt._chmod") +#pragma comment(linker, "/EXPORT:_chsize=msvcrt._chsize") +#pragma comment(linker, "/EXPORT:_chsize_s=msvcrt._chsize_s") +#pragma comment(linker, "/EXPORT:_chvalidator=msvcrt._chvalidator") +#pragma comment(linker, "/EXPORT:_chvalidator_l=msvcrt._chvalidator_l") +#pragma comment(linker, "/EXPORT:_clearfp=msvcrt._clearfp") +#pragma comment(linker, "/EXPORT:_close=msvcrt._close") +#pragma comment(linker, "/EXPORT:_commit=msvcrt._commit") +#pragma comment(linker, "/EXPORT:_commode=msvcrt._commode") +#pragma comment(linker, "/EXPORT:_control87=msvcrt._control87") +#pragma comment(linker, "/EXPORT:_controlfp=msvcrt._controlfp") +#pragma comment(linker, "/EXPORT:_controlfp_s=msvcrt._controlfp_s") +#pragma comment(linker, "/EXPORT:_copysign=msvcrt._copysign") +#pragma comment(linker, "/EXPORT:_copysignf=msvcrt._copysignf") +#pragma comment(linker, "/EXPORT:_cprintf=msvcrt._cprintf") +#pragma comment(linker, "/EXPORT:_cprintf_l=msvcrt._cprintf_l") +#pragma comment(linker, "/EXPORT:_cprintf_p=msvcrt._cprintf_p") +#pragma comment(linker, "/EXPORT:_cprintf_p_l=msvcrt._cprintf_p_l") +#pragma comment(linker, "/EXPORT:_cprintf_s=msvcrt._cprintf_s") +#pragma comment(linker, "/EXPORT:_cprintf_s_l=msvcrt._cprintf_s_l") +#pragma comment(linker, "/EXPORT:_cputs=msvcrt._cputs") +#pragma comment(linker, "/EXPORT:_cputws=msvcrt._cputws") +#pragma comment(linker, "/EXPORT:_creat=msvcrt._creat") +#pragma comment(linker, "/EXPORT:_crtAssertBusy=msvcrt._crtAssertBusy") +#pragma comment(linker, "/EXPORT:_crtBreakAlloc=msvcrt._crtBreakAlloc") +#pragma comment(linker, "/EXPORT:_crtDbgFlag=msvcrt._crtDbgFlag") +#pragma comment(linker, "/EXPORT:_cscanf=msvcrt._cscanf") +#pragma comment(linker, "/EXPORT:_cscanf_l=msvcrt._cscanf_l") +#pragma comment(linker, "/EXPORT:_cscanf_s=msvcrt._cscanf_s") +#pragma comment(linker, "/EXPORT:_cscanf_s_l=msvcrt._cscanf_s_l") +#pragma comment(linker, "/EXPORT:_ctime32=msvcrt._ctime32") +#pragma comment(linker, "/EXPORT:_ctime32_s=msvcrt._ctime32_s") +#pragma comment(linker, "/EXPORT:_ctime64=msvcrt._ctime64") +#pragma comment(linker, "/EXPORT:_ctime64_s=msvcrt._ctime64_s") +#pragma comment(linker, "/EXPORT:_ctype=msvcrt._ctype") +#pragma comment(linker, "/EXPORT:_cwait=msvcrt._cwait") +#pragma comment(linker, "/EXPORT:_cwprintf=msvcrt._cwprintf") +#pragma comment(linker, "/EXPORT:_cwprintf_l=msvcrt._cwprintf_l") +#pragma comment(linker, "/EXPORT:_cwprintf_p=msvcrt._cwprintf_p") +#pragma comment(linker, "/EXPORT:_cwprintf_p_l=msvcrt._cwprintf_p_l") +#pragma comment(linker, "/EXPORT:_cwprintf_s=msvcrt._cwprintf_s") +#pragma comment(linker, "/EXPORT:_cwprintf_s_l=msvcrt._cwprintf_s_l") +#pragma comment(linker, "/EXPORT:_cwscanf=msvcrt._cwscanf") +#pragma comment(linker, "/EXPORT:_cwscanf_l=msvcrt._cwscanf_l") +#pragma comment(linker, "/EXPORT:_cwscanf_s=msvcrt._cwscanf_s") +#pragma comment(linker, "/EXPORT:_cwscanf_s_l=msvcrt._cwscanf_s_l") +#pragma comment(linker, "/EXPORT:_daylight=msvcrt._daylight") +#pragma comment(linker, "/EXPORT:_difftime32=msvcrt._difftime32") +#pragma comment(linker, "/EXPORT:_difftime64=msvcrt._difftime64") +#pragma comment(linker, "/EXPORT:_dstbias=msvcrt._dstbias") +#pragma comment(linker, "/EXPORT:_dup=msvcrt._dup") +#pragma comment(linker, "/EXPORT:_dup2=msvcrt._dup2") +#pragma comment(linker, "/EXPORT:_ecvt=msvcrt._ecvt") +#pragma comment(linker, "/EXPORT:_ecvt_s=msvcrt._ecvt_s") +#pragma comment(linker, "/EXPORT:_endthread=msvcrt._endthread") +#pragma comment(linker, "/EXPORT:_endthreadex=msvcrt._endthreadex") +#pragma comment(linker, "/EXPORT:_environ=msvcrt._environ") +#pragma comment(linker, "/EXPORT:_eof=msvcrt._eof") +#pragma comment(linker, "/EXPORT:_errno=msvcrt._errno") +#pragma comment(linker, "/EXPORT:_execl=msvcrt._execl") +#pragma comment(linker, "/EXPORT:_execle=msvcrt._execle") +#pragma comment(linker, "/EXPORT:_execlp=msvcrt._execlp") +#pragma comment(linker, "/EXPORT:_execlpe=msvcrt._execlpe") +#pragma comment(linker, "/EXPORT:_execv=msvcrt._execv") +#pragma comment(linker, "/EXPORT:_execve=msvcrt._execve") +#pragma comment(linker, "/EXPORT:_execvp=msvcrt._execvp") +#pragma comment(linker, "/EXPORT:_execvpe=msvcrt._execvpe") +#pragma comment(linker, "/EXPORT:_exit=msvcrt._exit") +#pragma comment(linker, "/EXPORT:_expand=msvcrt._expand") +#pragma comment(linker, "/EXPORT:_expand_dbg=msvcrt._expand_dbg") +#pragma comment(linker, "/EXPORT:_fcloseall=msvcrt._fcloseall") +#pragma comment(linker, "/EXPORT:_fcvt=msvcrt._fcvt") +#pragma comment(linker, "/EXPORT:_fcvt_s=msvcrt._fcvt_s") +#pragma comment(linker, "/EXPORT:_fdopen=msvcrt._fdopen") +#pragma comment(linker, "/EXPORT:_fgetchar=msvcrt._fgetchar") +#pragma comment(linker, "/EXPORT:_fgetwchar=msvcrt._fgetwchar") +#pragma comment(linker, "/EXPORT:_filbuf=msvcrt._filbuf") +#pragma comment(linker, "/EXPORT:_fileinfo=msvcrt._fileinfo") +#pragma comment(linker, "/EXPORT:_filelength=msvcrt._filelength") +#pragma comment(linker, "/EXPORT:_filelengthi64=msvcrt._filelengthi64") +#pragma comment(linker, "/EXPORT:_fileno=msvcrt._fileno") +#pragma comment(linker, "/EXPORT:_findclose=msvcrt._findclose") +#pragma comment(linker, "/EXPORT:_findfirst=msvcrt._findfirst") +#pragma comment(linker, "/EXPORT:_findfirst64=msvcrt._findfirst64") +#pragma comment(linker, "/EXPORT:_findfirsti64=msvcrt._findfirsti64") +#pragma comment(linker, "/EXPORT:_findnext=msvcrt._findnext") +#pragma comment(linker, "/EXPORT:_findnext64=msvcrt._findnext64") +#pragma comment(linker, "/EXPORT:_findnexti64=msvcrt._findnexti64") +#pragma comment(linker, "/EXPORT:_finite=msvcrt._finite") +#pragma comment(linker, "/EXPORT:_finitef=msvcrt._finitef") +#pragma comment(linker, "/EXPORT:_flsbuf=msvcrt._flsbuf") +#pragma comment(linker, "/EXPORT:_flushall=msvcrt._flushall") +#pragma comment(linker, "/EXPORT:_fmode=msvcrt._fmode") +#pragma comment(linker, "/EXPORT:_fpclass=msvcrt._fpclass") +#pragma comment(linker, "/EXPORT:_fpclassf=msvcrt._fpclassf") +#pragma comment(linker, "/EXPORT:_fpreset=msvcrt._fpreset") +#pragma comment(linker, "/EXPORT:_fprintf_l=msvcrt._fprintf_l") +#pragma comment(linker, "/EXPORT:_fprintf_p=msvcrt._fprintf_p") +#pragma comment(linker, "/EXPORT:_fprintf_p_l=msvcrt._fprintf_p_l") +#pragma comment(linker, "/EXPORT:_fprintf_s_l=msvcrt._fprintf_s_l") +#pragma comment(linker, "/EXPORT:_fputchar=msvcrt._fputchar") +#pragma comment(linker, "/EXPORT:_fputwchar=msvcrt._fputwchar") +#pragma comment(linker, "/EXPORT:_free_dbg=msvcrt._free_dbg") +#pragma comment(linker, "/EXPORT:_freea=msvcrt._freea") +#pragma comment(linker, "/EXPORT:_freea_s=msvcrt._freea_s") +#pragma comment(linker, "/EXPORT:_fscanf_l=msvcrt._fscanf_l") +#pragma comment(linker, "/EXPORT:_fscanf_s_l=msvcrt._fscanf_s_l") +#pragma comment(linker, "/EXPORT:_fseeki64=msvcrt._fseeki64") +#pragma comment(linker, "/EXPORT:_fsopen=msvcrt._fsopen") +#pragma comment(linker, "/EXPORT:_fstat=msvcrt._fstat") +#pragma comment(linker, "/EXPORT:_fstat64=msvcrt._fstat64") +#pragma comment(linker, "/EXPORT:_fstati64=msvcrt._fstati64") +#pragma comment(linker, "/EXPORT:_ftime=msvcrt._ftime") +#pragma comment(linker, "/EXPORT:_ftime32=msvcrt._ftime32") +#pragma comment(linker, "/EXPORT:_ftime32_s=msvcrt._ftime32_s") +#pragma comment(linker, "/EXPORT:_ftime64=msvcrt._ftime64") +#pragma comment(linker, "/EXPORT:_ftime64_s=msvcrt._ftime64_s") +#pragma comment(linker, "/EXPORT:_fullpath=msvcrt._fullpath") +#pragma comment(linker, "/EXPORT:_fullpath_dbg=msvcrt._fullpath_dbg") +#pragma comment(linker, "/EXPORT:_futime=msvcrt._futime") +#pragma comment(linker, "/EXPORT:_futime32=msvcrt._futime32") +#pragma comment(linker, "/EXPORT:_futime64=msvcrt._futime64") +#pragma comment(linker, "/EXPORT:_fwprintf_l=msvcrt._fwprintf_l") +#pragma comment(linker, "/EXPORT:_fwprintf_p=msvcrt._fwprintf_p") +#pragma comment(linker, "/EXPORT:_fwprintf_p_l=msvcrt._fwprintf_p_l") +#pragma comment(linker, "/EXPORT:_fwprintf_s_l=msvcrt._fwprintf_s_l") +#pragma comment(linker, "/EXPORT:_fwscanf_l=msvcrt._fwscanf_l") +#pragma comment(linker, "/EXPORT:_fwscanf_s_l=msvcrt._fwscanf_s_l") +#pragma comment(linker, "/EXPORT:_gcvt=msvcrt._gcvt") +#pragma comment(linker, "/EXPORT:_gcvt_s=msvcrt._gcvt_s") +#pragma comment(linker, "/EXPORT:_get_doserrno=msvcrt._get_doserrno") +#pragma comment(linker, "/EXPORT:_get_environ=msvcrt._get_environ") +#pragma comment(linker, "/EXPORT:_get_errno=msvcrt._get_errno") +#pragma comment(linker, "/EXPORT:_get_fileinfo=msvcrt._get_fileinfo") +#pragma comment(linker, "/EXPORT:_get_fmode=msvcrt._get_fmode") +#pragma comment(linker, "/EXPORT:_get_heap_handle=msvcrt._get_heap_handle") +#pragma comment(linker, "/EXPORT:_get_osfhandle=msvcrt._get_osfhandle") +#pragma comment(linker, "/EXPORT:_get_osplatform=msvcrt._get_osplatform") +#pragma comment(linker, "/EXPORT:_get_osver=msvcrt._get_osver") +#pragma comment(linker, "/EXPORT:_get_output_format=msvcrt._get_output_format") +#pragma comment(linker, "/EXPORT:_get_pgmptr=msvcrt._get_pgmptr") +#pragma comment(linker, "/EXPORT:_get_sbh_threshold=msvcrt._get_sbh_threshold") +#pragma comment(linker, "/EXPORT:_get_wenviron=msvcrt._get_wenviron") +#pragma comment(linker, "/EXPORT:_get_winmajor=msvcrt._get_winmajor") +#pragma comment(linker, "/EXPORT:_get_winminor=msvcrt._get_winminor") +#pragma comment(linker, "/EXPORT:_get_winver=msvcrt._get_winver") +#pragma comment(linker, "/EXPORT:_get_wpgmptr=msvcrt._get_wpgmptr") +#pragma comment(linker, "/EXPORT:_getch=msvcrt._getch") +#pragma comment(linker, "/EXPORT:_getche=msvcrt._getche") +#pragma comment(linker, "/EXPORT:_getcwd=msvcrt._getcwd") +#pragma comment(linker, "/EXPORT:_getdcwd=msvcrt._getdcwd") +#pragma comment(linker, "/EXPORT:_getdiskfree=msvcrt._getdiskfree") +#pragma comment(linker, "/EXPORT:_getdrive=msvcrt._getdrive") +#pragma comment(linker, "/EXPORT:_getdrives=msvcrt._getdrives") +#pragma comment(linker, "/EXPORT:_getmaxstdio=msvcrt._getmaxstdio") +#pragma comment(linker, "/EXPORT:_getmbcp=msvcrt._getmbcp") +#pragma comment(linker, "/EXPORT:_getpid=msvcrt._getpid") +#pragma comment(linker, "/EXPORT:_getsystime=msvcrt._getsystime") +#pragma comment(linker, "/EXPORT:_getw=msvcrt._getw") +#pragma comment(linker, "/EXPORT:_getwch=msvcrt._getwch") +#pragma comment(linker, "/EXPORT:_getwche=msvcrt._getwche") +#pragma comment(linker, "/EXPORT:_getws=msvcrt._getws") +#pragma comment(linker, "/EXPORT:_gmtime32=msvcrt._gmtime32") +#pragma comment(linker, "/EXPORT:_gmtime32_s=msvcrt._gmtime32_s") +#pragma comment(linker, "/EXPORT:_gmtime64=msvcrt._gmtime64") +#pragma comment(linker, "/EXPORT:_gmtime64_s=msvcrt._gmtime64_s") +#pragma comment(linker, "/EXPORT:_heapchk=msvcrt._heapchk") +#pragma comment(linker, "/EXPORT:_heapmin=msvcrt._heapmin") +#pragma comment(linker, "/EXPORT:_heapset=msvcrt._heapset") +#pragma comment(linker, "/EXPORT:_heapwalk=msvcrt._heapwalk") +#pragma comment(linker, "/EXPORT:_hypot=msvcrt._hypot") +#pragma comment(linker, "/EXPORT:_hypotf=msvcrt._hypotf") +#pragma comment(linker, "/EXPORT:_i64toa=msvcrt._i64toa") +#pragma comment(linker, "/EXPORT:_i64toa_s=msvcrt._i64toa_s") +#pragma comment(linker, "/EXPORT:_i64tow=msvcrt._i64tow") +#pragma comment(linker, "/EXPORT:_i64tow_s=msvcrt._i64tow_s") +#pragma comment(linker, "/EXPORT:_initterm=msvcrt._initterm") +#pragma comment(linker, "/EXPORT:_initterm_e=msvcrt._initterm_e") +#pragma comment(linker, "/EXPORT:_invalid_parameter=msvcrt._invalid_parameter") +#pragma comment(linker, "/EXPORT:_iob=msvcrt._iob") +#pragma comment(linker, "/EXPORT:_isalnum_l=msvcrt._isalnum_l") +#pragma comment(linker, "/EXPORT:_isalpha_l=msvcrt._isalpha_l") +#pragma comment(linker, "/EXPORT:_isatty=msvcrt._isatty") +#pragma comment(linker, "/EXPORT:_iscntrl_l=msvcrt._iscntrl_l") +#pragma comment(linker, "/EXPORT:_isctype=msvcrt._isctype") +#pragma comment(linker, "/EXPORT:_isctype_l=msvcrt._isctype_l") +#pragma comment(linker, "/EXPORT:_isdigit_l=msvcrt._isdigit_l") +#pragma comment(linker, "/EXPORT:_isgraph_l=msvcrt._isgraph_l") +#pragma comment(linker, "/EXPORT:_isleadbyte_l=msvcrt._isleadbyte_l") +#pragma comment(linker, "/EXPORT:_islower_l=msvcrt._islower_l") +#pragma comment(linker, "/EXPORT:_ismbbalnum=msvcrt._ismbbalnum") +#pragma comment(linker, "/EXPORT:_ismbbalnum_l=msvcrt._ismbbalnum_l") +#pragma comment(linker, "/EXPORT:_ismbbalpha=msvcrt._ismbbalpha") +#pragma comment(linker, "/EXPORT:_ismbbalpha_l=msvcrt._ismbbalpha_l") +#pragma comment(linker, "/EXPORT:_ismbbgraph=msvcrt._ismbbgraph") +#pragma comment(linker, "/EXPORT:_ismbbgraph_l=msvcrt._ismbbgraph_l") +#pragma comment(linker, "/EXPORT:_ismbbkalnum=msvcrt._ismbbkalnum") +#pragma comment(linker, "/EXPORT:_ismbbkalnum_l=msvcrt._ismbbkalnum_l") +#pragma comment(linker, "/EXPORT:_ismbbkana=msvcrt._ismbbkana") +#pragma comment(linker, "/EXPORT:_ismbbkana_l=msvcrt._ismbbkana_l") +#pragma comment(linker, "/EXPORT:_ismbbkprint=msvcrt._ismbbkprint") +#pragma comment(linker, "/EXPORT:_ismbbkprint_l=msvcrt._ismbbkprint_l") +#pragma comment(linker, "/EXPORT:_ismbbkpunct=msvcrt._ismbbkpunct") +#pragma comment(linker, "/EXPORT:_ismbbkpunct_l=msvcrt._ismbbkpunct_l") +#pragma comment(linker, "/EXPORT:_ismbblead=msvcrt._ismbblead") +#pragma comment(linker, "/EXPORT:_ismbblead_l=msvcrt._ismbblead_l") +#pragma comment(linker, "/EXPORT:_ismbbprint=msvcrt._ismbbprint") +#pragma comment(linker, "/EXPORT:_ismbbprint_l=msvcrt._ismbbprint_l") +#pragma comment(linker, "/EXPORT:_ismbbpunct=msvcrt._ismbbpunct") +#pragma comment(linker, "/EXPORT:_ismbbpunct_l=msvcrt._ismbbpunct_l") +#pragma comment(linker, "/EXPORT:_ismbbtrail=msvcrt._ismbbtrail") +#pragma comment(linker, "/EXPORT:_ismbbtrail_l=msvcrt._ismbbtrail_l") +#pragma comment(linker, "/EXPORT:_ismbcalnum=msvcrt._ismbcalnum") +#pragma comment(linker, "/EXPORT:_ismbcalnum_l=msvcrt._ismbcalnum_l") +#pragma comment(linker, "/EXPORT:_ismbcalpha=msvcrt._ismbcalpha") +#pragma comment(linker, "/EXPORT:_ismbcalpha_l=msvcrt._ismbcalpha_l") +#pragma comment(linker, "/EXPORT:_ismbcdigit=msvcrt._ismbcdigit") +#pragma comment(linker, "/EXPORT:_ismbcdigit_l=msvcrt._ismbcdigit_l") +#pragma comment(linker, "/EXPORT:_ismbcgraph=msvcrt._ismbcgraph") +#pragma comment(linker, "/EXPORT:_ismbcgraph_l=msvcrt._ismbcgraph_l") +#pragma comment(linker, "/EXPORT:_ismbchira=msvcrt._ismbchira") +#pragma comment(linker, "/EXPORT:_ismbchira_l=msvcrt._ismbchira_l") +#pragma comment(linker, "/EXPORT:_ismbckata=msvcrt._ismbckata") +#pragma comment(linker, "/EXPORT:_ismbckata_l=msvcrt._ismbckata_l") +#pragma comment(linker, "/EXPORT:_ismbcl0=msvcrt._ismbcl0") +#pragma comment(linker, "/EXPORT:_ismbcl0_l=msvcrt._ismbcl0_l") +#pragma comment(linker, "/EXPORT:_ismbcl1=msvcrt._ismbcl1") +#pragma comment(linker, "/EXPORT:_ismbcl1_l=msvcrt._ismbcl1_l") +#pragma comment(linker, "/EXPORT:_ismbcl2=msvcrt._ismbcl2") +#pragma comment(linker, "/EXPORT:_ismbcl2_l=msvcrt._ismbcl2_l") +#pragma comment(linker, "/EXPORT:_ismbclegal=msvcrt._ismbclegal") +#pragma comment(linker, "/EXPORT:_ismbclegal_l=msvcrt._ismbclegal_l") +#pragma comment(linker, "/EXPORT:_ismbclower=msvcrt._ismbclower") +#pragma comment(linker, "/EXPORT:_ismbclower_l=msvcrt._ismbclower_l") +#pragma comment(linker, "/EXPORT:_ismbcprint=msvcrt._ismbcprint") +#pragma comment(linker, "/EXPORT:_ismbcprint_l=msvcrt._ismbcprint_l") +#pragma comment(linker, "/EXPORT:_ismbcpunct=msvcrt._ismbcpunct") +#pragma comment(linker, "/EXPORT:_ismbcpunct_l=msvcrt._ismbcpunct_l") +#pragma comment(linker, "/EXPORT:_ismbcspace=msvcrt._ismbcspace") +#pragma comment(linker, "/EXPORT:_ismbcspace_l=msvcrt._ismbcspace_l") +#pragma comment(linker, "/EXPORT:_ismbcsymbol=msvcrt._ismbcsymbol") +#pragma comment(linker, "/EXPORT:_ismbcsymbol_l=msvcrt._ismbcsymbol_l") +#pragma comment(linker, "/EXPORT:_ismbcupper=msvcrt._ismbcupper") +#pragma comment(linker, "/EXPORT:_ismbcupper_l=msvcrt._ismbcupper_l") +#pragma comment(linker, "/EXPORT:_ismbslead=msvcrt._ismbslead") +#pragma comment(linker, "/EXPORT:_ismbslead_l=msvcrt._ismbslead_l") +#pragma comment(linker, "/EXPORT:_ismbstrail=msvcrt._ismbstrail") +#pragma comment(linker, "/EXPORT:_ismbstrail_l=msvcrt._ismbstrail_l") +#pragma comment(linker, "/EXPORT:_isnan=msvcrt._isnan") +#pragma comment(linker, "/EXPORT:_isnanf=msvcrt._isnanf") +#pragma comment(linker, "/EXPORT:_isprint_l=msvcrt._isprint_l") +#pragma comment(linker, "/EXPORT:_isspace_l=msvcrt._isspace_l") +#pragma comment(linker, "/EXPORT:_isupper_l=msvcrt._isupper_l") +#pragma comment(linker, "/EXPORT:_iswalnum_l=msvcrt._iswalnum_l") +#pragma comment(linker, "/EXPORT:_iswalpha_l=msvcrt._iswalpha_l") +#pragma comment(linker, "/EXPORT:_iswcntrl_l=msvcrt._iswcntrl_l") +#pragma comment(linker, "/EXPORT:_iswctype_l=msvcrt._iswctype_l") +#pragma comment(linker, "/EXPORT:_iswdigit_l=msvcrt._iswdigit_l") +#pragma comment(linker, "/EXPORT:_iswgraph_l=msvcrt._iswgraph_l") +#pragma comment(linker, "/EXPORT:_iswlower_l=msvcrt._iswlower_l") +#pragma comment(linker, "/EXPORT:_iswprint_l=msvcrt._iswprint_l") +#pragma comment(linker, "/EXPORT:_iswpunct_l=msvcrt._iswpunct_l") +#pragma comment(linker, "/EXPORT:_iswspace_l=msvcrt._iswspace_l") +#pragma comment(linker, "/EXPORT:_iswupper_l=msvcrt._iswupper_l") +#pragma comment(linker, "/EXPORT:_iswxdigit_l=msvcrt._iswxdigit_l") +#pragma comment(linker, "/EXPORT:_isxdigit_l=msvcrt._isxdigit_l") +#pragma comment(linker, "/EXPORT:_itoa=msvcrt._itoa") +#pragma comment(linker, "/EXPORT:_itoa_s=msvcrt._itoa_s") +#pragma comment(linker, "/EXPORT:_itow=msvcrt._itow") +#pragma comment(linker, "/EXPORT:_itow_s=msvcrt._itow_s") +#pragma comment(linker, "/EXPORT:_j0=msvcrt._j0") +#pragma comment(linker, "/EXPORT:_j1=msvcrt._j1") +#pragma comment(linker, "/EXPORT:_jn=msvcrt._jn") +#pragma comment(linker, "/EXPORT:_kbhit=msvcrt._kbhit") +#pragma comment(linker, "/EXPORT:_lfind=msvcrt._lfind") +#pragma comment(linker, "/EXPORT:_lfind_s=msvcrt._lfind_s") +#pragma comment(linker, "/EXPORT:_local_unwind=msvcrt._local_unwind") +#pragma comment(linker, "/EXPORT:_localtime32=msvcrt._localtime32") +#pragma comment(linker, "/EXPORT:_localtime32_s=msvcrt._localtime32_s") +#pragma comment(linker, "/EXPORT:_localtime64=msvcrt._localtime64") +#pragma comment(linker, "/EXPORT:_localtime64_s=msvcrt._localtime64_s") +#pragma comment(linker, "/EXPORT:_lock=msvcrt._lock") +#pragma comment(linker, "/EXPORT:_locking=msvcrt._locking") +#pragma comment(linker, "/EXPORT:_logb=msvcrt._logb") +#pragma comment(linker, "/EXPORT:_logbf=msvcrt._logbf") +#pragma comment(linker, "/EXPORT:_lrotl=msvcrt._lrotl") +#pragma comment(linker, "/EXPORT:_lrotr=msvcrt._lrotr") +#pragma comment(linker, "/EXPORT:_lsearch=msvcrt._lsearch") +#pragma comment(linker, "/EXPORT:_lsearch_s=msvcrt._lsearch_s") +#pragma comment(linker, "/EXPORT:_lseek=msvcrt._lseek") +#pragma comment(linker, "/EXPORT:_lseeki64=msvcrt._lseeki64") +#pragma comment(linker, "/EXPORT:_ltoa=msvcrt._ltoa") +#pragma comment(linker, "/EXPORT:_ltoa_s=msvcrt._ltoa_s") +#pragma comment(linker, "/EXPORT:_ltow=msvcrt._ltow") +#pragma comment(linker, "/EXPORT:_ltow_s=msvcrt._ltow_s") +#pragma comment(linker, "/EXPORT:_makepath=msvcrt._makepath") +#pragma comment(linker, "/EXPORT:_makepath_s=msvcrt._makepath_s") +#pragma comment(linker, "/EXPORT:_malloc_dbg=msvcrt._malloc_dbg") +#pragma comment(linker, "/EXPORT:_mbbtombc=msvcrt._mbbtombc") +#pragma comment(linker, "/EXPORT:_mbbtombc_l=msvcrt._mbbtombc_l") +#pragma comment(linker, "/EXPORT:_mbbtype=msvcrt._mbbtype") +#pragma comment(linker, "/EXPORT:_mbcasemap=msvcrt._mbcasemap") +#pragma comment(linker, "/EXPORT:_mbccpy=msvcrt._mbccpy") +#pragma comment(linker, "/EXPORT:_mbccpy_l=msvcrt._mbccpy_l") +#pragma comment(linker, "/EXPORT:_mbccpy_s=msvcrt._mbccpy_s") +#pragma comment(linker, "/EXPORT:_mbccpy_s_l=msvcrt._mbccpy_s_l") +#pragma comment(linker, "/EXPORT:_mbcjistojms=msvcrt._mbcjistojms") +#pragma comment(linker, "/EXPORT:_mbcjistojms_l=msvcrt._mbcjistojms_l") +#pragma comment(linker, "/EXPORT:_mbcjmstojis=msvcrt._mbcjmstojis") +#pragma comment(linker, "/EXPORT:_mbcjmstojis_l=msvcrt._mbcjmstojis_l") +#pragma comment(linker, "/EXPORT:_mbclen=msvcrt._mbclen") +#pragma comment(linker, "/EXPORT:_mbclen_l=msvcrt._mbclen_l") +#pragma comment(linker, "/EXPORT:_mbctohira=msvcrt._mbctohira") +#pragma comment(linker, "/EXPORT:_mbctohira_l=msvcrt._mbctohira_l") +#pragma comment(linker, "/EXPORT:_mbctokata=msvcrt._mbctokata") +#pragma comment(linker, "/EXPORT:_mbctokata_l=msvcrt._mbctokata_l") +#pragma comment(linker, "/EXPORT:_mbctolower=msvcrt._mbctolower") +#pragma comment(linker, "/EXPORT:_mbctolower_l=msvcrt._mbctolower_l") +#pragma comment(linker, "/EXPORT:_mbctombb=msvcrt._mbctombb") +#pragma comment(linker, "/EXPORT:_mbctombb_l=msvcrt._mbctombb_l") +#pragma comment(linker, "/EXPORT:_mbctoupper=msvcrt._mbctoupper") +#pragma comment(linker, "/EXPORT:_mbctoupper_l=msvcrt._mbctoupper_l") +#pragma comment(linker, "/EXPORT:_mbctype=msvcrt._mbctype") +#pragma comment(linker, "/EXPORT:_mblen_l=msvcrt._mblen_l") +#pragma comment(linker, "/EXPORT:_mbsbtype=msvcrt._mbsbtype") +#pragma comment(linker, "/EXPORT:_mbsbtype_l=msvcrt._mbsbtype_l") +#pragma comment(linker, "/EXPORT:_mbscat=msvcrt._mbscat") +#pragma comment(linker, "/EXPORT:_mbscat_s=msvcrt._mbscat_s") +#pragma comment(linker, "/EXPORT:_mbscat_s_l=msvcrt._mbscat_s_l") +#pragma comment(linker, "/EXPORT:_mbschr=msvcrt._mbschr") +#pragma comment(linker, "/EXPORT:_mbschr_l=msvcrt._mbschr_l") +#pragma comment(linker, "/EXPORT:_mbscmp=msvcrt._mbscmp") +#pragma comment(linker, "/EXPORT:_mbscmp_l=msvcrt._mbscmp_l") +#pragma comment(linker, "/EXPORT:_mbscoll=msvcrt._mbscoll") +#pragma comment(linker, "/EXPORT:_mbscoll_l=msvcrt._mbscoll_l") +#pragma comment(linker, "/EXPORT:_mbscpy=msvcrt._mbscpy") +#pragma comment(linker, "/EXPORT:_mbscpy_s=msvcrt._mbscpy_s") +#pragma comment(linker, "/EXPORT:_mbscpy_s_l=msvcrt._mbscpy_s_l") +#pragma comment(linker, "/EXPORT:_mbscspn=msvcrt._mbscspn") +#pragma comment(linker, "/EXPORT:_mbscspn_l=msvcrt._mbscspn_l") +#pragma comment(linker, "/EXPORT:_mbsdec=msvcrt._mbsdec") +#pragma comment(linker, "/EXPORT:_mbsdec_l=msvcrt._mbsdec_l") +#pragma comment(linker, "/EXPORT:_mbsdup=msvcrt._mbsdup") +#pragma comment(linker, "/EXPORT:_mbsicmp=msvcrt._mbsicmp") +#pragma comment(linker, "/EXPORT:_mbsicmp_l=msvcrt._mbsicmp_l") +#pragma comment(linker, "/EXPORT:_mbsicoll=msvcrt._mbsicoll") +#pragma comment(linker, "/EXPORT:_mbsicoll_l=msvcrt._mbsicoll_l") +#pragma comment(linker, "/EXPORT:_mbsinc=msvcrt._mbsinc") +#pragma comment(linker, "/EXPORT:_mbsinc_l=msvcrt._mbsinc_l") +#pragma comment(linker, "/EXPORT:_mbslen=msvcrt._mbslen") +#pragma comment(linker, "/EXPORT:_mbslen_l=msvcrt._mbslen_l") +#pragma comment(linker, "/EXPORT:_mbslwr=msvcrt._mbslwr") +#pragma comment(linker, "/EXPORT:_mbslwr_l=msvcrt._mbslwr_l") +#pragma comment(linker, "/EXPORT:_mbslwr_s=msvcrt._mbslwr_s") +#pragma comment(linker, "/EXPORT:_mbslwr_s_l=msvcrt._mbslwr_s_l") +#pragma comment(linker, "/EXPORT:_mbsnbcat=msvcrt._mbsnbcat") +#pragma comment(linker, "/EXPORT:_mbsnbcat_l=msvcrt._mbsnbcat_l") +#pragma comment(linker, "/EXPORT:_mbsnbcat_s=msvcrt._mbsnbcat_s") +#pragma comment(linker, "/EXPORT:_mbsnbcat_s_l=msvcrt._mbsnbcat_s_l") +#pragma comment(linker, "/EXPORT:_mbsnbcmp=msvcrt._mbsnbcmp") +#pragma comment(linker, "/EXPORT:_mbsnbcmp_l=msvcrt._mbsnbcmp_l") +#pragma comment(linker, "/EXPORT:_mbsnbcnt=msvcrt._mbsnbcnt") +#pragma comment(linker, "/EXPORT:_mbsnbcnt_l=msvcrt._mbsnbcnt_l") +#pragma comment(linker, "/EXPORT:_mbsnbcoll=msvcrt._mbsnbcoll") +#pragma comment(linker, "/EXPORT:_mbsnbcoll_l=msvcrt._mbsnbcoll_l") +#pragma comment(linker, "/EXPORT:_mbsnbcpy=msvcrt._mbsnbcpy") +#pragma comment(linker, "/EXPORT:_mbsnbcpy_l=msvcrt._mbsnbcpy_l") +#pragma comment(linker, "/EXPORT:_mbsnbcpy_s=msvcrt._mbsnbcpy_s") +#pragma comment(linker, "/EXPORT:_mbsnbcpy_s_l=msvcrt._mbsnbcpy_s_l") +#pragma comment(linker, "/EXPORT:_mbsnbicmp=msvcrt._mbsnbicmp") +#pragma comment(linker, "/EXPORT:_mbsnbicmp_l=msvcrt._mbsnbicmp_l") +#pragma comment(linker, "/EXPORT:_mbsnbicoll=msvcrt._mbsnbicoll") +#pragma comment(linker, "/EXPORT:_mbsnbicoll_l=msvcrt._mbsnbicoll_l") +#pragma comment(linker, "/EXPORT:_mbsnbset=msvcrt._mbsnbset") +#pragma comment(linker, "/EXPORT:_mbsnbset_l=msvcrt._mbsnbset_l") +#pragma comment(linker, "/EXPORT:_mbsnbset_s=msvcrt._mbsnbset_s") +#pragma comment(linker, "/EXPORT:_mbsnbset_s_l=msvcrt._mbsnbset_s_l") +#pragma comment(linker, "/EXPORT:_mbsncat=msvcrt._mbsncat") +#pragma comment(linker, "/EXPORT:_mbsncat_l=msvcrt._mbsncat_l") +#pragma comment(linker, "/EXPORT:_mbsncat_s=msvcrt._mbsncat_s") +#pragma comment(linker, "/EXPORT:_mbsncat_s_l=msvcrt._mbsncat_s_l") +#pragma comment(linker, "/EXPORT:_mbsnccnt=msvcrt._mbsnccnt") +#pragma comment(linker, "/EXPORT:_mbsnccnt_l=msvcrt._mbsnccnt_l") +#pragma comment(linker, "/EXPORT:_mbsncmp=msvcrt._mbsncmp") +#pragma comment(linker, "/EXPORT:_mbsncmp_l=msvcrt._mbsncmp_l") +#pragma comment(linker, "/EXPORT:_mbsncoll=msvcrt._mbsncoll") +#pragma comment(linker, "/EXPORT:_mbsncoll_l=msvcrt._mbsncoll_l") +#pragma comment(linker, "/EXPORT:_mbsncpy=msvcrt._mbsncpy") +#pragma comment(linker, "/EXPORT:_mbsncpy_l=msvcrt._mbsncpy_l") +#pragma comment(linker, "/EXPORT:_mbsncpy_s=msvcrt._mbsncpy_s") +#pragma comment(linker, "/EXPORT:_mbsncpy_s_l=msvcrt._mbsncpy_s_l") +#pragma comment(linker, "/EXPORT:_mbsnextc=msvcrt._mbsnextc") +#pragma comment(linker, "/EXPORT:_mbsnextc_l=msvcrt._mbsnextc_l") +#pragma comment(linker, "/EXPORT:_mbsnicmp=msvcrt._mbsnicmp") +#pragma comment(linker, "/EXPORT:_mbsnicmp_l=msvcrt._mbsnicmp_l") +#pragma comment(linker, "/EXPORT:_mbsnicoll=msvcrt._mbsnicoll") +#pragma comment(linker, "/EXPORT:_mbsnicoll_l=msvcrt._mbsnicoll_l") +#pragma comment(linker, "/EXPORT:_mbsninc=msvcrt._mbsninc") +#pragma comment(linker, "/EXPORT:_mbsninc_l=msvcrt._mbsninc_l") +#pragma comment(linker, "/EXPORT:_mbsnlen=msvcrt._mbsnlen") +#pragma comment(linker, "/EXPORT:_mbsnlen_l=msvcrt._mbsnlen_l") +#pragma comment(linker, "/EXPORT:_mbsnset=msvcrt._mbsnset") +#pragma comment(linker, "/EXPORT:_mbsnset_l=msvcrt._mbsnset_l") +#pragma comment(linker, "/EXPORT:_mbsnset_s=msvcrt._mbsnset_s") +#pragma comment(linker, "/EXPORT:_mbsnset_s_l=msvcrt._mbsnset_s_l") +#pragma comment(linker, "/EXPORT:_mbspbrk=msvcrt._mbspbrk") +#pragma comment(linker, "/EXPORT:_mbspbrk_l=msvcrt._mbspbrk_l") +#pragma comment(linker, "/EXPORT:_mbsrchr=msvcrt._mbsrchr") +#pragma comment(linker, "/EXPORT:_mbsrchr_l=msvcrt._mbsrchr_l") +#pragma comment(linker, "/EXPORT:_mbsrev=msvcrt._mbsrev") +#pragma comment(linker, "/EXPORT:_mbsrev_l=msvcrt._mbsrev_l") +#pragma comment(linker, "/EXPORT:_mbsset=msvcrt._mbsset") +#pragma comment(linker, "/EXPORT:_mbsset_l=msvcrt._mbsset_l") +#pragma comment(linker, "/EXPORT:_mbsset_s=msvcrt._mbsset_s") +#pragma comment(linker, "/EXPORT:_mbsset_s_l=msvcrt._mbsset_s_l") +#pragma comment(linker, "/EXPORT:_mbsspn=msvcrt._mbsspn") +#pragma comment(linker, "/EXPORT:_mbsspn_l=msvcrt._mbsspn_l") +#pragma comment(linker, "/EXPORT:_mbsspnp=msvcrt._mbsspnp") +#pragma comment(linker, "/EXPORT:_mbsspnp_l=msvcrt._mbsspnp_l") +#pragma comment(linker, "/EXPORT:_mbsstr=msvcrt._mbsstr") +#pragma comment(linker, "/EXPORT:_mbsstr_l=msvcrt._mbsstr_l") +#pragma comment(linker, "/EXPORT:_mbstok=msvcrt._mbstok") +#pragma comment(linker, "/EXPORT:_mbstok_l=msvcrt._mbstok_l") +#pragma comment(linker, "/EXPORT:_mbstok_s=msvcrt._mbstok_s") +#pragma comment(linker, "/EXPORT:_mbstok_s_l=msvcrt._mbstok_s_l") +#pragma comment(linker, "/EXPORT:_mbstowcs_l=msvcrt._mbstowcs_l") +#pragma comment(linker, "/EXPORT:_mbstowcs_s_l=msvcrt._mbstowcs_s_l") +#pragma comment(linker, "/EXPORT:_mbstrlen=msvcrt._mbstrlen") +#pragma comment(linker, "/EXPORT:_mbstrlen_l=msvcrt._mbstrlen_l") +#pragma comment(linker, "/EXPORT:_mbstrnlen=msvcrt._mbstrnlen") +#pragma comment(linker, "/EXPORT:_mbstrnlen_l=msvcrt._mbstrnlen_l") +#pragma comment(linker, "/EXPORT:_mbsupr=msvcrt._mbsupr") +#pragma comment(linker, "/EXPORT:_mbsupr_l=msvcrt._mbsupr_l") +#pragma comment(linker, "/EXPORT:_mbsupr_s=msvcrt._mbsupr_s") +#pragma comment(linker, "/EXPORT:_mbsupr_s_l=msvcrt._mbsupr_s_l") +#pragma comment(linker, "/EXPORT:_mbtowc_l=msvcrt._mbtowc_l") +#pragma comment(linker, "/EXPORT:_memccpy=msvcrt._memccpy") +#pragma comment(linker, "/EXPORT:_memicmp=msvcrt._memicmp") +#pragma comment(linker, "/EXPORT:_memicmp_l=msvcrt._memicmp_l") +#pragma comment(linker, "/EXPORT:_mkdir=msvcrt._mkdir") +#pragma comment(linker, "/EXPORT:_mkgmtime=msvcrt._mkgmtime") +#pragma comment(linker, "/EXPORT:_mkgmtime32=msvcrt._mkgmtime32") +#pragma comment(linker, "/EXPORT:_mkgmtime64=msvcrt._mkgmtime64") +#pragma comment(linker, "/EXPORT:_mktemp=msvcrt._mktemp") +#pragma comment(linker, "/EXPORT:_mktemp_s=msvcrt._mktemp_s") +#pragma comment(linker, "/EXPORT:_mktime32=msvcrt._mktime32") +#pragma comment(linker, "/EXPORT:_mktime64=msvcrt._mktime64") +#pragma comment(linker, "/EXPORT:_msize=msvcrt._msize") +#pragma comment(linker, "/EXPORT:_msize_dbg=msvcrt._msize_dbg") +#pragma comment(linker, "/EXPORT:_nextafter=msvcrt._nextafter") +#pragma comment(linker, "/EXPORT:_nextafterf=msvcrt._nextafterf") +#pragma comment(linker, "/EXPORT:_onexit=msvcrt._onexit") +#pragma comment(linker, "/EXPORT:_open=msvcrt._open") +#pragma comment(linker, "/EXPORT:_open_osfhandle=msvcrt._open_osfhandle") +#pragma comment(linker, "/EXPORT:_osplatform=msvcrt._osplatform") +#pragma comment(linker, "/EXPORT:_osver=msvcrt._osver") +#pragma comment(linker, "/EXPORT:_pclose=msvcrt._pclose") +#pragma comment(linker, "/EXPORT:_pctype=msvcrt._pctype") +#pragma comment(linker, "/EXPORT:_pgmptr=msvcrt._pgmptr") +#pragma comment(linker, "/EXPORT:_pipe=msvcrt._pipe") +#pragma comment(linker, "/EXPORT:_popen=msvcrt._popen") +#pragma comment(linker, "/EXPORT:_printf_l=msvcrt._printf_l") +#pragma comment(linker, "/EXPORT:_printf_p=msvcrt._printf_p") +#pragma comment(linker, "/EXPORT:_printf_p_l=msvcrt._printf_p_l") +#pragma comment(linker, "/EXPORT:_printf_s_l=msvcrt._printf_s_l") +#pragma comment(linker, "/EXPORT:_purecall=msvcrt._purecall") +#pragma comment(linker, "/EXPORT:_putch=msvcrt._putch") +#pragma comment(linker, "/EXPORT:_putenv=msvcrt._putenv") +#pragma comment(linker, "/EXPORT:_putenv_s=msvcrt._putenv_s") +#pragma comment(linker, "/EXPORT:_putw=msvcrt._putw") +#pragma comment(linker, "/EXPORT:_putwch=msvcrt._putwch") +#pragma comment(linker, "/EXPORT:_putws=msvcrt._putws") +#pragma comment(linker, "/EXPORT:_pwctype=msvcrt._pwctype") +#pragma comment(linker, "/EXPORT:_read=msvcrt._read") +#pragma comment(linker, "/EXPORT:_realloc_dbg=msvcrt._realloc_dbg") +#pragma comment(linker, "/EXPORT:_resetstkoflw=msvcrt._resetstkoflw") +#pragma comment(linker, "/EXPORT:_rmdir=msvcrt._rmdir") +#pragma comment(linker, "/EXPORT:_rmtmp=msvcrt._rmtmp") +#pragma comment(linker, "/EXPORT:_rotl=msvcrt._rotl") +#pragma comment(linker, "/EXPORT:_rotl64=msvcrt._rotl64") +#pragma comment(linker, "/EXPORT:_rotr=msvcrt._rotr") +#pragma comment(linker, "/EXPORT:_rotr64=msvcrt._rotr64") +#pragma comment(linker, "/EXPORT:_scalb=msvcrt._scalb") +#pragma comment(linker, "/EXPORT:_scalbf=msvcrt._scalbf") +#pragma comment(linker, "/EXPORT:_scanf_l=msvcrt._scanf_l") +#pragma comment(linker, "/EXPORT:_scanf_s_l=msvcrt._scanf_s_l") +#pragma comment(linker, "/EXPORT:_scprintf=msvcrt._scprintf") +#pragma comment(linker, "/EXPORT:_scprintf_l=msvcrt._scprintf_l") +#pragma comment(linker, "/EXPORT:_scprintf_p_l=msvcrt._scprintf_p_l") +#pragma comment(linker, "/EXPORT:_scwprintf=msvcrt._scwprintf") +#pragma comment(linker, "/EXPORT:_scwprintf_l=msvcrt._scwprintf_l") +#pragma comment(linker, "/EXPORT:_scwprintf_p_l=msvcrt._scwprintf_p_l") +#pragma comment(linker, "/EXPORT:_searchenv=msvcrt._searchenv") +#pragma comment(linker, "/EXPORT:_searchenv_s=msvcrt._searchenv_s") +#pragma comment(linker, "/EXPORT:_set_controlfp=msvcrt._set_controlfp") +#pragma comment(linker, "/EXPORT:_set_doserrno=msvcrt._set_doserrno") +#pragma comment(linker, "/EXPORT:_set_errno=msvcrt._set_errno") +#pragma comment(linker, "/EXPORT:_set_error_mode=msvcrt._set_error_mode") +#pragma comment(linker, "/EXPORT:_set_fileinfo=msvcrt._set_fileinfo") +#pragma comment(linker, "/EXPORT:_set_fmode=msvcrt._set_fmode") +#pragma comment(linker, "/EXPORT:_set_output_format=msvcrt._set_output_format") +#pragma comment(linker, "/EXPORT:_set_sbh_threshold=msvcrt._set_sbh_threshold") +#pragma comment(linker, "/EXPORT:_seterrormode=msvcrt._seterrormode") +#pragma comment(linker, "/EXPORT:_setjmp=msvcrt._setjmp") +#pragma comment(linker, "/EXPORT:_setjmpex=msvcrt._setjmpex") +#pragma comment(linker, "/EXPORT:_setmaxstdio=msvcrt._setmaxstdio") +#pragma comment(linker, "/EXPORT:_setmbcp=msvcrt._setmbcp") +#pragma comment(linker, "/EXPORT:_setmode=msvcrt._setmode") +#pragma comment(linker, "/EXPORT:_setsystime=msvcrt._setsystime") +#pragma comment(linker, "/EXPORT:_sleep=msvcrt._sleep") +#pragma comment(linker, "/EXPORT:_snprintf=msvcrt._snprintf") +#pragma comment(linker, "/EXPORT:_snprintf_c=msvcrt._snprintf_c") +#pragma comment(linker, "/EXPORT:_snprintf_c_l=msvcrt._snprintf_c_l") +#pragma comment(linker, "/EXPORT:_snprintf_l=msvcrt._snprintf_l") +#pragma comment(linker, "/EXPORT:_snprintf_s=msvcrt._snprintf_s") +#pragma comment(linker, "/EXPORT:_snprintf_s_l=msvcrt._snprintf_s_l") +#pragma comment(linker, "/EXPORT:_snscanf=msvcrt._snscanf") +#pragma comment(linker, "/EXPORT:_snscanf_l=msvcrt._snscanf_l") +#pragma comment(linker, "/EXPORT:_snscanf_s=msvcrt._snscanf_s") +#pragma comment(linker, "/EXPORT:_snscanf_s_l=msvcrt._snscanf_s_l") +#pragma comment(linker, "/EXPORT:_snwprintf=msvcrt._snwprintf") +#pragma comment(linker, "/EXPORT:_snwprintf_l=msvcrt._snwprintf_l") +#pragma comment(linker, "/EXPORT:_snwprintf_s=msvcrt._snwprintf_s") +#pragma comment(linker, "/EXPORT:_snwprintf_s_l=msvcrt._snwprintf_s_l") +#pragma comment(linker, "/EXPORT:_snwscanf=msvcrt._snwscanf") +#pragma comment(linker, "/EXPORT:_snwscanf_l=msvcrt._snwscanf_l") +#pragma comment(linker, "/EXPORT:_snwscanf_s=msvcrt._snwscanf_s") +#pragma comment(linker, "/EXPORT:_snwscanf_s_l=msvcrt._snwscanf_s_l") +#pragma comment(linker, "/EXPORT:_sopen=msvcrt._sopen") +#pragma comment(linker, "/EXPORT:_sopen_s=msvcrt._sopen_s") +#pragma comment(linker, "/EXPORT:_spawnl=msvcrt._spawnl") +#pragma comment(linker, "/EXPORT:_spawnle=msvcrt._spawnle") +#pragma comment(linker, "/EXPORT:_spawnlp=msvcrt._spawnlp") +#pragma comment(linker, "/EXPORT:_spawnlpe=msvcrt._spawnlpe") +#pragma comment(linker, "/EXPORT:_spawnv=msvcrt._spawnv") +#pragma comment(linker, "/EXPORT:_spawnve=msvcrt._spawnve") +#pragma comment(linker, "/EXPORT:_spawnvp=msvcrt._spawnvp") +#pragma comment(linker, "/EXPORT:_spawnvpe=msvcrt._spawnvpe") +#pragma comment(linker, "/EXPORT:_splitpath=msvcrt._splitpath") +#pragma comment(linker, "/EXPORT:_splitpath_s=msvcrt._splitpath_s") +#pragma comment(linker, "/EXPORT:_sprintf_l=msvcrt._sprintf_l") +#pragma comment(linker, "/EXPORT:_sprintf_p_l=msvcrt._sprintf_p_l") +#pragma comment(linker, "/EXPORT:_sprintf_s_l=msvcrt._sprintf_s_l") +#pragma comment(linker, "/EXPORT:_sscanf_l=msvcrt._sscanf_l") +#pragma comment(linker, "/EXPORT:_sscanf_s_l=msvcrt._sscanf_s_l") +#pragma comment(linker, "/EXPORT:_stat=msvcrt._stat") +#pragma comment(linker, "/EXPORT:_stat64=msvcrt._stat64") +#pragma comment(linker, "/EXPORT:_stati64=msvcrt._stati64") +#pragma comment(linker, "/EXPORT:_statusfp=msvcrt._statusfp") +#pragma comment(linker, "/EXPORT:_strcmpi=msvcrt._strcmpi") +#pragma comment(linker, "/EXPORT:_strcoll_l=msvcrt._strcoll_l") +#pragma comment(linker, "/EXPORT:_strdate=msvcrt._strdate") +#pragma comment(linker, "/EXPORT:_strdate_s=msvcrt._strdate_s") +#pragma comment(linker, "/EXPORT:_strdup=msvcrt._strdup") +#pragma comment(linker, "/EXPORT:_strdup_dbg=msvcrt._strdup_dbg") +#pragma comment(linker, "/EXPORT:_strerror=msvcrt._strerror") +#pragma comment(linker, "/EXPORT:_strerror_s=msvcrt._strerror_s") +#pragma comment(linker, "/EXPORT:_stricmp=msvcrt._stricmp") +#pragma comment(linker, "/EXPORT:_stricmp_l=msvcrt._stricmp_l") +#pragma comment(linker, "/EXPORT:_stricoll=msvcrt._stricoll") +#pragma comment(linker, "/EXPORT:_stricoll_l=msvcrt._stricoll_l") +#pragma comment(linker, "/EXPORT:_strlwr=msvcrt._strlwr") +#pragma comment(linker, "/EXPORT:_strlwr_l=msvcrt._strlwr_l") +#pragma comment(linker, "/EXPORT:_strlwr_s=msvcrt._strlwr_s") +#pragma comment(linker, "/EXPORT:_strlwr_s_l=msvcrt._strlwr_s_l") +#pragma comment(linker, "/EXPORT:_strncoll=msvcrt._strncoll") +#pragma comment(linker, "/EXPORT:_strncoll_l=msvcrt._strncoll_l") +#pragma comment(linker, "/EXPORT:_strnicmp=msvcrt._strnicmp") +#pragma comment(linker, "/EXPORT:_strnicmp_l=msvcrt._strnicmp_l") +#pragma comment(linker, "/EXPORT:_strnicoll=msvcrt._strnicoll") +#pragma comment(linker, "/EXPORT:_strnicoll_l=msvcrt._strnicoll_l") +#pragma comment(linker, "/EXPORT:_strnset=msvcrt._strnset") +#pragma comment(linker, "/EXPORT:_strnset_s=msvcrt._strnset_s") +#pragma comment(linker, "/EXPORT:_strrev=msvcrt._strrev") +#pragma comment(linker, "/EXPORT:_strset=msvcrt._strset") +#pragma comment(linker, "/EXPORT:_strset_s=msvcrt._strset_s") +#pragma comment(linker, "/EXPORT:_strtime=msvcrt._strtime") +#pragma comment(linker, "/EXPORT:_strtime_s=msvcrt._strtime_s") +#pragma comment(linker, "/EXPORT:_strtod_l=msvcrt._strtod_l") +#pragma comment(linker, "/EXPORT:_strtoi64=msvcrt._strtoi64") +#pragma comment(linker, "/EXPORT:_strtoi64_l=msvcrt._strtoi64_l") +#pragma comment(linker, "/EXPORT:_strtol_l=msvcrt._strtol_l") +#pragma comment(linker, "/EXPORT:_strtoui64=msvcrt._strtoui64") +#pragma comment(linker, "/EXPORT:_strtoui64_l=msvcrt._strtoui64_l") +#pragma comment(linker, "/EXPORT:_strtoul_l=msvcrt._strtoul_l") +#pragma comment(linker, "/EXPORT:_strupr=msvcrt._strupr") +#pragma comment(linker, "/EXPORT:_strupr_l=msvcrt._strupr_l") +#pragma comment(linker, "/EXPORT:_strupr_s=msvcrt._strupr_s") +#pragma comment(linker, "/EXPORT:_strupr_s_l=msvcrt._strupr_s_l") +#pragma comment(linker, "/EXPORT:_strxfrm_l=msvcrt._strxfrm_l") +#pragma comment(linker, "/EXPORT:_swab=msvcrt._swab") +#pragma comment(linker, "/EXPORT:_swprintf=msvcrt._swprintf") +#pragma comment(linker, "/EXPORT:_swprintf_c=msvcrt._swprintf_c") +#pragma comment(linker, "/EXPORT:_swprintf_c_l=msvcrt._swprintf_c_l") +#pragma comment(linker, "/EXPORT:_swprintf_p_l=msvcrt._swprintf_p_l") +#pragma comment(linker, "/EXPORT:_swprintf_s_l=msvcrt._swprintf_s_l") +#pragma comment(linker, "/EXPORT:_swscanf_l=msvcrt._swscanf_l") +#pragma comment(linker, "/EXPORT:_swscanf_s_l=msvcrt._swscanf_s_l") +#pragma comment(linker, "/EXPORT:_sys_errlist=msvcrt._sys_errlist") +#pragma comment(linker, "/EXPORT:_sys_nerr=msvcrt._sys_nerr") +#pragma comment(linker, "/EXPORT:_tell=msvcrt._tell") +#pragma comment(linker, "/EXPORT:_telli64=msvcrt._telli64") +#pragma comment(linker, "/EXPORT:_tempnam=msvcrt._tempnam") +#pragma comment(linker, "/EXPORT:_tempnam_dbg=msvcrt._tempnam_dbg") +#pragma comment(linker, "/EXPORT:_time32=msvcrt._time32") +#pragma comment(linker, "/EXPORT:_time64=msvcrt._time64") +#pragma comment(linker, "/EXPORT:_timezone=msvcrt._timezone") +#pragma comment(linker, "/EXPORT:_tolower=msvcrt._tolower") +#pragma comment(linker, "/EXPORT:_tolower_l=msvcrt._tolower_l") +#pragma comment(linker, "/EXPORT:_toupper=msvcrt._toupper") +#pragma comment(linker, "/EXPORT:_toupper_l=msvcrt._toupper_l") +#pragma comment(linker, "/EXPORT:_towlower_l=msvcrt._towlower_l") +#pragma comment(linker, "/EXPORT:_towupper_l=msvcrt._towupper_l") +#pragma comment(linker, "/EXPORT:_tzname=msvcrt._tzname") +#pragma comment(linker, "/EXPORT:_tzset=msvcrt._tzset") +#pragma comment(linker, "/EXPORT:_ui64toa=msvcrt._ui64toa") +#pragma comment(linker, "/EXPORT:_ui64toa_s=msvcrt._ui64toa_s") +#pragma comment(linker, "/EXPORT:_ui64tow=msvcrt._ui64tow") +#pragma comment(linker, "/EXPORT:_ui64tow_s=msvcrt._ui64tow_s") +#pragma comment(linker, "/EXPORT:_ultoa=msvcrt._ultoa") +#pragma comment(linker, "/EXPORT:_ultoa_s=msvcrt._ultoa_s") +#pragma comment(linker, "/EXPORT:_ultow=msvcrt._ultow") +#pragma comment(linker, "/EXPORT:_ultow_s=msvcrt._ultow_s") +#pragma comment(linker, "/EXPORT:_umask=msvcrt._umask") +#pragma comment(linker, "/EXPORT:_umask_s=msvcrt._umask_s") +#pragma comment(linker, "/EXPORT:_ungetch=msvcrt._ungetch") +#pragma comment(linker, "/EXPORT:_ungetwch=msvcrt._ungetwch") +#pragma comment(linker, "/EXPORT:_unlink=msvcrt._unlink") +#pragma comment(linker, "/EXPORT:_unlock=msvcrt._unlock") +#pragma comment(linker, "/EXPORT:_utime=msvcrt._utime") +#pragma comment(linker, "/EXPORT:_utime32=msvcrt._utime32") +#pragma comment(linker, "/EXPORT:_utime64=msvcrt._utime64") +#pragma comment(linker, "/EXPORT:_vcprintf=msvcrt._vcprintf") +#pragma comment(linker, "/EXPORT:_vcprintf_l=msvcrt._vcprintf_l") +#pragma comment(linker, "/EXPORT:_vcprintf_p=msvcrt._vcprintf_p") +#pragma comment(linker, "/EXPORT:_vcprintf_p_l=msvcrt._vcprintf_p_l") +#pragma comment(linker, "/EXPORT:_vcprintf_s=msvcrt._vcprintf_s") +#pragma comment(linker, "/EXPORT:_vcprintf_s_l=msvcrt._vcprintf_s_l") +#pragma comment(linker, "/EXPORT:_vcwprintf=msvcrt._vcwprintf") +#pragma comment(linker, "/EXPORT:_vcwprintf_l=msvcrt._vcwprintf_l") +#pragma comment(linker, "/EXPORT:_vcwprintf_p=msvcrt._vcwprintf_p") +#pragma comment(linker, "/EXPORT:_vcwprintf_p_l=msvcrt._vcwprintf_p_l") +#pragma comment(linker, "/EXPORT:_vcwprintf_s=msvcrt._vcwprintf_s") +#pragma comment(linker, "/EXPORT:_vcwprintf_s_l=msvcrt._vcwprintf_s_l") +#pragma comment(linker, "/EXPORT:_vfprintf_l=msvcrt._vfprintf_l") +#pragma comment(linker, "/EXPORT:_vfprintf_p=msvcrt._vfprintf_p") +#pragma comment(linker, "/EXPORT:_vfprintf_p_l=msvcrt._vfprintf_p_l") +#pragma comment(linker, "/EXPORT:_vfprintf_s_l=msvcrt._vfprintf_s_l") +#pragma comment(linker, "/EXPORT:_vfwprintf_l=msvcrt._vfwprintf_l") +#pragma comment(linker, "/EXPORT:_vfwprintf_p=msvcrt._vfwprintf_p") +#pragma comment(linker, "/EXPORT:_vfwprintf_p_l=msvcrt._vfwprintf_p_l") +#pragma comment(linker, "/EXPORT:_vfwprintf_s_l=msvcrt._vfwprintf_s_l") +#pragma comment(linker, "/EXPORT:_vprintf_l=msvcrt._vprintf_l") +#pragma comment(linker, "/EXPORT:_vprintf_p=msvcrt._vprintf_p") +#pragma comment(linker, "/EXPORT:_vprintf_p_l=msvcrt._vprintf_p_l") +#pragma comment(linker, "/EXPORT:_vprintf_s_l=msvcrt._vprintf_s_l") +#pragma comment(linker, "/EXPORT:_vscprintf=msvcrt._vscprintf") +#pragma comment(linker, "/EXPORT:_vscprintf_l=msvcrt._vscprintf_l") +#pragma comment(linker, "/EXPORT:_vscprintf_p_l=msvcrt._vscprintf_p_l") +#pragma comment(linker, "/EXPORT:_vscwprintf=msvcrt._vscwprintf") +#pragma comment(linker, "/EXPORT:_vscwprintf_l=msvcrt._vscwprintf_l") +#pragma comment(linker, "/EXPORT:_vscwprintf_p_l=msvcrt._vscwprintf_p_l") +#pragma comment(linker, "/EXPORT:_vsnprintf=msvcrt._vsnprintf") +#pragma comment(linker, "/EXPORT:_vsnprintf_c=msvcrt._vsnprintf_c") +#pragma comment(linker, "/EXPORT:_vsnprintf_c_l=msvcrt._vsnprintf_c_l") +#pragma comment(linker, "/EXPORT:_vsnprintf_l=msvcrt._vsnprintf_l") +#pragma comment(linker, "/EXPORT:_vsnprintf_s=msvcrt._vsnprintf_s") +#pragma comment(linker, "/EXPORT:_vsnprintf_s_l=msvcrt._vsnprintf_s_l") +#pragma comment(linker, "/EXPORT:_vsnwprintf=msvcrt._vsnwprintf") +#pragma comment(linker, "/EXPORT:_vsnwprintf_l=msvcrt._vsnwprintf_l") +#pragma comment(linker, "/EXPORT:_vsnwprintf_s=msvcrt._vsnwprintf_s") +#pragma comment(linker, "/EXPORT:_vsnwprintf_s_l=msvcrt._vsnwprintf_s_l") +#pragma comment(linker, "/EXPORT:_vsprintf_l=msvcrt._vsprintf_l") +#pragma comment(linker, "/EXPORT:_vsprintf_p=msvcrt._vsprintf_p") +#pragma comment(linker, "/EXPORT:_vsprintf_p_l=msvcrt._vsprintf_p_l") +#pragma comment(linker, "/EXPORT:_vsprintf_s_l=msvcrt._vsprintf_s_l") +#pragma comment(linker, "/EXPORT:_vswprintf=msvcrt._vswprintf") +#pragma comment(linker, "/EXPORT:_vswprintf_c=msvcrt._vswprintf_c") +#pragma comment(linker, "/EXPORT:_vswprintf_c_l=msvcrt._vswprintf_c_l") +#pragma comment(linker, "/EXPORT:_vswprintf_l=msvcrt._vswprintf_l") +#pragma comment(linker, "/EXPORT:_vswprintf_p_l=msvcrt._vswprintf_p_l") +#pragma comment(linker, "/EXPORT:_vswprintf_s_l=msvcrt._vswprintf_s_l") +#pragma comment(linker, "/EXPORT:_vwprintf_l=msvcrt._vwprintf_l") +#pragma comment(linker, "/EXPORT:_vwprintf_p=msvcrt._vwprintf_p") +#pragma comment(linker, "/EXPORT:_vwprintf_p_l=msvcrt._vwprintf_p_l") +#pragma comment(linker, "/EXPORT:_vwprintf_s_l=msvcrt._vwprintf_s_l") +#pragma comment(linker, "/EXPORT:_waccess=msvcrt._waccess") +#pragma comment(linker, "/EXPORT:_waccess_s=msvcrt._waccess_s") +#pragma comment(linker, "/EXPORT:_wasctime=msvcrt._wasctime") +#pragma comment(linker, "/EXPORT:_wasctime_s=msvcrt._wasctime_s") +#pragma comment(linker, "/EXPORT:_wassert=msvcrt._wassert") +#pragma comment(linker, "/EXPORT:_wchdir=msvcrt._wchdir") +#pragma comment(linker, "/EXPORT:_wchmod=msvcrt._wchmod") +#pragma comment(linker, "/EXPORT:_wcmdln=msvcrt._wcmdln") +#pragma comment(linker, "/EXPORT:_wcreat=msvcrt._wcreat") +#pragma comment(linker, "/EXPORT:_wcscoll_l=msvcrt._wcscoll_l") +#pragma comment(linker, "/EXPORT:_wcsdup=msvcrt._wcsdup") +#pragma comment(linker, "/EXPORT:_wcsdup_dbg=msvcrt._wcsdup_dbg") +#pragma comment(linker, "/EXPORT:_wcserror=msvcrt._wcserror") +#pragma comment(linker, "/EXPORT:_wcserror_s=msvcrt._wcserror_s") +#pragma comment(linker, "/EXPORT:_wcsftime_l=msvcrt._wcsftime_l") +#pragma comment(linker, "/EXPORT:_wcsicmp=msvcrt._wcsicmp") +#pragma comment(linker, "/EXPORT:_wcsicmp_l=msvcrt._wcsicmp_l") +#pragma comment(linker, "/EXPORT:_wcsicoll=msvcrt._wcsicoll") +#pragma comment(linker, "/EXPORT:_wcsicoll_l=msvcrt._wcsicoll_l") +#pragma comment(linker, "/EXPORT:_wcslwr=msvcrt._wcslwr") +#pragma comment(linker, "/EXPORT:_wcslwr_l=msvcrt._wcslwr_l") +#pragma comment(linker, "/EXPORT:_wcslwr_s=msvcrt._wcslwr_s") +#pragma comment(linker, "/EXPORT:_wcslwr_s_l=msvcrt._wcslwr_s_l") +#pragma comment(linker, "/EXPORT:_wcsncoll=msvcrt._wcsncoll") +#pragma comment(linker, "/EXPORT:_wcsncoll_l=msvcrt._wcsncoll_l") +#pragma comment(linker, "/EXPORT:_wcsnicmp=msvcrt._wcsnicmp") +#pragma comment(linker, "/EXPORT:_wcsnicmp_l=msvcrt._wcsnicmp_l") +#pragma comment(linker, "/EXPORT:_wcsnicoll=msvcrt._wcsnicoll") +#pragma comment(linker, "/EXPORT:_wcsnicoll_l=msvcrt._wcsnicoll_l") +#pragma comment(linker, "/EXPORT:_wcsnset=msvcrt._wcsnset") +#pragma comment(linker, "/EXPORT:_wcsnset_s=msvcrt._wcsnset_s") +#pragma comment(linker, "/EXPORT:_wcsrev=msvcrt._wcsrev") +#pragma comment(linker, "/EXPORT:_wcsset=msvcrt._wcsset") +#pragma comment(linker, "/EXPORT:_wcsset_s=msvcrt._wcsset_s") +#pragma comment(linker, "/EXPORT:_wcstoi64=msvcrt._wcstoi64") +#pragma comment(linker, "/EXPORT:_wcstoi64_l=msvcrt._wcstoi64_l") +#pragma comment(linker, "/EXPORT:_wcstol_l=msvcrt._wcstol_l") +#pragma comment(linker, "/EXPORT:_wcstombs_l=msvcrt._wcstombs_l") +#pragma comment(linker, "/EXPORT:_wcstombs_s_l=msvcrt._wcstombs_s_l") +#pragma comment(linker, "/EXPORT:_wcstoui64=msvcrt._wcstoui64") +#pragma comment(linker, "/EXPORT:_wcstoui64_l=msvcrt._wcstoui64_l") +#pragma comment(linker, "/EXPORT:_wcstoul_l=msvcrt._wcstoul_l") +#pragma comment(linker, "/EXPORT:_wcsupr=msvcrt._wcsupr") +#pragma comment(linker, "/EXPORT:_wcsupr_l=msvcrt._wcsupr_l") +#pragma comment(linker, "/EXPORT:_wcsupr_s=msvcrt._wcsupr_s") +#pragma comment(linker, "/EXPORT:_wcsupr_s_l=msvcrt._wcsupr_s_l") +#pragma comment(linker, "/EXPORT:_wcsxfrm_l=msvcrt._wcsxfrm_l") +#pragma comment(linker, "/EXPORT:_wctime=msvcrt._wctime") +#pragma comment(linker, "/EXPORT:_wctime32=msvcrt._wctime32") +#pragma comment(linker, "/EXPORT:_wctime32_s=msvcrt._wctime32_s") +#pragma comment(linker, "/EXPORT:_wctime64=msvcrt._wctime64") +#pragma comment(linker, "/EXPORT:_wctime64_s=msvcrt._wctime64_s") +#pragma comment(linker, "/EXPORT:_wctomb_l=msvcrt._wctomb_l") +#pragma comment(linker, "/EXPORT:_wctomb_s_l=msvcrt._wctomb_s_l") +#pragma comment(linker, "/EXPORT:_wctype=msvcrt._wctype") +#pragma comment(linker, "/EXPORT:_wenviron=msvcrt._wenviron") +#pragma comment(linker, "/EXPORT:_wexecl=msvcrt._wexecl") +#pragma comment(linker, "/EXPORT:_wexecle=msvcrt._wexecle") +#pragma comment(linker, "/EXPORT:_wexeclp=msvcrt._wexeclp") +#pragma comment(linker, "/EXPORT:_wexeclpe=msvcrt._wexeclpe") +#pragma comment(linker, "/EXPORT:_wexecv=msvcrt._wexecv") +#pragma comment(linker, "/EXPORT:_wexecve=msvcrt._wexecve") +#pragma comment(linker, "/EXPORT:_wexecvp=msvcrt._wexecvp") +#pragma comment(linker, "/EXPORT:_wexecvpe=msvcrt._wexecvpe") +#pragma comment(linker, "/EXPORT:_wfdopen=msvcrt._wfdopen") +#pragma comment(linker, "/EXPORT:_wfindfirst=msvcrt._wfindfirst") +#pragma comment(linker, "/EXPORT:_wfindfirst64=msvcrt._wfindfirst64") +#pragma comment(linker, "/EXPORT:_wfindfirsti64=msvcrt._wfindfirsti64") +#pragma comment(linker, "/EXPORT:_wfindnext=msvcrt._wfindnext") +#pragma comment(linker, "/EXPORT:_wfindnext64=msvcrt._wfindnext64") +#pragma comment(linker, "/EXPORT:_wfindnexti64=msvcrt._wfindnexti64") +#pragma comment(linker, "/EXPORT:_wfopen=msvcrt._wfopen") +#pragma comment(linker, "/EXPORT:_wfopen_s=msvcrt._wfopen_s") +#pragma comment(linker, "/EXPORT:_wfreopen=msvcrt._wfreopen") +#pragma comment(linker, "/EXPORT:_wfreopen_s=msvcrt._wfreopen_s") +#pragma comment(linker, "/EXPORT:_wfsopen=msvcrt._wfsopen") +#pragma comment(linker, "/EXPORT:_wfullpath=msvcrt._wfullpath") +#pragma comment(linker, "/EXPORT:_wfullpath_dbg=msvcrt._wfullpath_dbg") +#pragma comment(linker, "/EXPORT:_wgetcwd=msvcrt._wgetcwd") +#pragma comment(linker, "/EXPORT:_wgetdcwd=msvcrt._wgetdcwd") +#pragma comment(linker, "/EXPORT:_wgetenv=msvcrt._wgetenv") +#pragma comment(linker, "/EXPORT:_wgetenv_s=msvcrt._wgetenv_s") +#pragma comment(linker, "/EXPORT:_winmajor=msvcrt._winmajor") +#pragma comment(linker, "/EXPORT:_winminor=msvcrt._winminor") +#pragma comment(linker, "/EXPORT:_winput_s=msvcrt._winput_s") +#pragma comment(linker, "/EXPORT:_winver=msvcrt._winver") +#pragma comment(linker, "/EXPORT:_wmakepath=msvcrt._wmakepath") +#pragma comment(linker, "/EXPORT:_wmakepath_s=msvcrt._wmakepath_s") +#pragma comment(linker, "/EXPORT:_wmkdir=msvcrt._wmkdir") +#pragma comment(linker, "/EXPORT:_wmktemp=msvcrt._wmktemp") +#pragma comment(linker, "/EXPORT:_wmktemp_s=msvcrt._wmktemp_s") +#pragma comment(linker, "/EXPORT:_wopen=msvcrt._wopen") +#pragma comment(linker, "/EXPORT:_woutput_s=msvcrt._woutput_s") +#pragma comment(linker, "/EXPORT:_wperror=msvcrt._wperror") +#pragma comment(linker, "/EXPORT:_wpgmptr=msvcrt._wpgmptr") +#pragma comment(linker, "/EXPORT:_wpopen=msvcrt._wpopen") +#pragma comment(linker, "/EXPORT:_wprintf_l=msvcrt._wprintf_l") +#pragma comment(linker, "/EXPORT:_wprintf_p=msvcrt._wprintf_p") +#pragma comment(linker, "/EXPORT:_wprintf_p_l=msvcrt._wprintf_p_l") +#pragma comment(linker, "/EXPORT:_wprintf_s_l=msvcrt._wprintf_s_l") +#pragma comment(linker, "/EXPORT:_wputenv=msvcrt._wputenv") +#pragma comment(linker, "/EXPORT:_wputenv_s=msvcrt._wputenv_s") +#pragma comment(linker, "/EXPORT:_wremove=msvcrt._wremove") +#pragma comment(linker, "/EXPORT:_wrename=msvcrt._wrename") +#pragma comment(linker, "/EXPORT:_write=msvcrt._write") +#pragma comment(linker, "/EXPORT:_wrmdir=msvcrt._wrmdir") +#pragma comment(linker, "/EXPORT:_wscanf_l=msvcrt._wscanf_l") +#pragma comment(linker, "/EXPORT:_wscanf_s_l=msvcrt._wscanf_s_l") +#pragma comment(linker, "/EXPORT:_wsearchenv=msvcrt._wsearchenv") +#pragma comment(linker, "/EXPORT:_wsearchenv_s=msvcrt._wsearchenv_s") +#pragma comment(linker, "/EXPORT:_wsetlocale=msvcrt._wsetlocale") +#pragma comment(linker, "/EXPORT:_wsopen=msvcrt._wsopen") +#pragma comment(linker, "/EXPORT:_wsopen_s=msvcrt._wsopen_s") +#pragma comment(linker, "/EXPORT:_wspawnl=msvcrt._wspawnl") +#pragma comment(linker, "/EXPORT:_wspawnle=msvcrt._wspawnle") +#pragma comment(linker, "/EXPORT:_wspawnlp=msvcrt._wspawnlp") +#pragma comment(linker, "/EXPORT:_wspawnlpe=msvcrt._wspawnlpe") +#pragma comment(linker, "/EXPORT:_wspawnv=msvcrt._wspawnv") +#pragma comment(linker, "/EXPORT:_wspawnve=msvcrt._wspawnve") +#pragma comment(linker, "/EXPORT:_wspawnvp=msvcrt._wspawnvp") +#pragma comment(linker, "/EXPORT:_wspawnvpe=msvcrt._wspawnvpe") +#pragma comment(linker, "/EXPORT:_wsplitpath=msvcrt._wsplitpath") +#pragma comment(linker, "/EXPORT:_wsplitpath_s=msvcrt._wsplitpath_s") +#pragma comment(linker, "/EXPORT:_wstat=msvcrt._wstat") +#pragma comment(linker, "/EXPORT:_wstat64=msvcrt._wstat64") +#pragma comment(linker, "/EXPORT:_wstati64=msvcrt._wstati64") +#pragma comment(linker, "/EXPORT:_wstrdate=msvcrt._wstrdate") +#pragma comment(linker, "/EXPORT:_wstrdate_s=msvcrt._wstrdate_s") +#pragma comment(linker, "/EXPORT:_wstrtime=msvcrt._wstrtime") +#pragma comment(linker, "/EXPORT:_wstrtime_s=msvcrt._wstrtime_s") +#pragma comment(linker, "/EXPORT:_wsystem=msvcrt._wsystem") +#pragma comment(linker, "/EXPORT:_wtempnam=msvcrt._wtempnam") +#pragma comment(linker, "/EXPORT:_wtempnam_dbg=msvcrt._wtempnam_dbg") +#pragma comment(linker, "/EXPORT:_wtmpnam=msvcrt._wtmpnam") +#pragma comment(linker, "/EXPORT:_wtmpnam_s=msvcrt._wtmpnam_s") +#pragma comment(linker, "/EXPORT:_wtof=msvcrt._wtof") +#pragma comment(linker, "/EXPORT:_wtof_l=msvcrt._wtof_l") +#pragma comment(linker, "/EXPORT:_wtoi=msvcrt._wtoi") +#pragma comment(linker, "/EXPORT:_wtoi64=msvcrt._wtoi64") +#pragma comment(linker, "/EXPORT:_wtoi64_l=msvcrt._wtoi64_l") +#pragma comment(linker, "/EXPORT:_wtoi_l=msvcrt._wtoi_l") +#pragma comment(linker, "/EXPORT:_wtol=msvcrt._wtol") +#pragma comment(linker, "/EXPORT:_wtol_l=msvcrt._wtol_l") +#pragma comment(linker, "/EXPORT:_wunlink=msvcrt._wunlink") +#pragma comment(linker, "/EXPORT:_wutime=msvcrt._wutime") +#pragma comment(linker, "/EXPORT:_wutime32=msvcrt._wutime32") +#pragma comment(linker, "/EXPORT:_wutime64=msvcrt._wutime64") +#pragma comment(linker, "/EXPORT:_y0=msvcrt._y0") +#pragma comment(linker, "/EXPORT:_y1=msvcrt._y1") +#pragma comment(linker, "/EXPORT:_yn=msvcrt._yn") +#pragma comment(linker, "/EXPORT:abort=msvcrt.abort") +#pragma comment(linker, "/EXPORT:abs=msvcrt.abs") +#pragma comment(linker, "/EXPORT:acos=msvcrt.acos") +#pragma comment(linker, "/EXPORT:acosf=msvcrt.acosf") +#pragma comment(linker, "/EXPORT:asctime=msvcrt.asctime") +#pragma comment(linker, "/EXPORT:asctime_s=msvcrt.asctime_s") +#pragma comment(linker, "/EXPORT:asin=msvcrt.asin") +#pragma comment(linker, "/EXPORT:asinf=msvcrt.asinf") +#pragma comment(linker, "/EXPORT:atan=msvcrt.atan") +#pragma comment(linker, "/EXPORT:atan2=msvcrt.atan2") +#pragma comment(linker, "/EXPORT:atan2f=msvcrt.atan2f") +#pragma comment(linker, "/EXPORT:atanf=msvcrt.atanf") +#pragma comment(linker, "/EXPORT:atexit=msvcrt.atexit") +#pragma comment(linker, "/EXPORT:atof=msvcrt.atof") +#pragma comment(linker, "/EXPORT:atoi=msvcrt.atoi") +#pragma comment(linker, "/EXPORT:atol=msvcrt.atol") +#pragma comment(linker, "/EXPORT:bsearch=msvcrt.bsearch") +#pragma comment(linker, "/EXPORT:bsearch_s=msvcrt.bsearch_s") +#pragma comment(linker, "/EXPORT:btowc=msvcrt.btowc") +#pragma comment(linker, "/EXPORT:calloc=msvcrt.calloc") +#pragma comment(linker, "/EXPORT:ceil=msvcrt.ceil") +#pragma comment(linker, "/EXPORT:ceilf=msvcrt.ceilf") +#pragma comment(linker, "/EXPORT:clearerr=msvcrt.clearerr") +#pragma comment(linker, "/EXPORT:clearerr_s=msvcrt.clearerr_s") +#pragma comment(linker, "/EXPORT:clock=msvcrt.clock") +#pragma comment(linker, "/EXPORT:cos=msvcrt.cos") +#pragma comment(linker, "/EXPORT:cosf=msvcrt.cosf") +#pragma comment(linker, "/EXPORT:cosh=msvcrt.cosh") +#pragma comment(linker, "/EXPORT:coshf=msvcrt.coshf") +#pragma comment(linker, "/EXPORT:ctime=msvcrt.ctime") +#pragma comment(linker, "/EXPORT:difftime=msvcrt.difftime") +#pragma comment(linker, "/EXPORT:div=msvcrt.div") +#pragma comment(linker, "/EXPORT:exit=msvcrt.exit") +#pragma comment(linker, "/EXPORT:exp=msvcrt.exp") +#pragma comment(linker, "/EXPORT:expf=msvcrt.expf") +#pragma comment(linker, "/EXPORT:fabs=msvcrt.fabs") +#pragma comment(linker, "/EXPORT:fclose=msvcrt.fclose") +#pragma comment(linker, "/EXPORT:feof=msvcrt.feof") +#pragma comment(linker, "/EXPORT:ferror=msvcrt.ferror") +#pragma comment(linker, "/EXPORT:fflush=msvcrt.fflush") +#pragma comment(linker, "/EXPORT:fgetc=msvcrt.fgetc") +#pragma comment(linker, "/EXPORT:fgetpos=msvcrt.fgetpos") +#pragma comment(linker, "/EXPORT:fgets=msvcrt.fgets") +#pragma comment(linker, "/EXPORT:fgetwc=msvcrt.fgetwc") +#pragma comment(linker, "/EXPORT:fgetws=msvcrt.fgetws") +#pragma comment(linker, "/EXPORT:floor=msvcrt.floor") +#pragma comment(linker, "/EXPORT:floorf=msvcrt.floorf") +#pragma comment(linker, "/EXPORT:fmod=msvcrt.fmod") +#pragma comment(linker, "/EXPORT:fmodf=msvcrt.fmodf") +#pragma comment(linker, "/EXPORT:fopen=msvcrt.fopen") +#pragma comment(linker, "/EXPORT:fopen_s=msvcrt.fopen_s") +#pragma comment(linker, "/EXPORT:fprintf=msvcrt.fprintf") +#pragma comment(linker, "/EXPORT:fprintf_s=msvcrt.fprintf_s") +#pragma comment(linker, "/EXPORT:fputc=msvcrt.fputc") +#pragma comment(linker, "/EXPORT:fputs=msvcrt.fputs") +#pragma comment(linker, "/EXPORT:fputwc=msvcrt.fputwc") +#pragma comment(linker, "/EXPORT:fputws=msvcrt.fputws") +#pragma comment(linker, "/EXPORT:fread=msvcrt.fread") +#pragma comment(linker, "/EXPORT:free=msvcrt.free") +#pragma comment(linker, "/EXPORT:freopen=msvcrt.freopen") +#pragma comment(linker, "/EXPORT:freopen_s=msvcrt.freopen_s") +#pragma comment(linker, "/EXPORT:frexp=msvcrt.frexp") +#pragma comment(linker, "/EXPORT:fscanf=msvcrt.fscanf") +#pragma comment(linker, "/EXPORT:fscanf_s=msvcrt.fscanf_s") +#pragma comment(linker, "/EXPORT:fseek=msvcrt.fseek") +#pragma comment(linker, "/EXPORT:fsetpos=msvcrt.fsetpos") +#pragma comment(linker, "/EXPORT:ftell=msvcrt.ftell") +#pragma comment(linker, "/EXPORT:fwprintf=msvcrt.fwprintf") +#pragma comment(linker, "/EXPORT:fwprintf_s=msvcrt.fwprintf_s") +#pragma comment(linker, "/EXPORT:fwrite=msvcrt.fwrite") +#pragma comment(linker, "/EXPORT:fwscanf=msvcrt.fwscanf") +#pragma comment(linker, "/EXPORT:fwscanf_s=msvcrt.fwscanf_s") +#pragma comment(linker, "/EXPORT:getc=msvcrt.getc") +#pragma comment(linker, "/EXPORT:getchar=msvcrt.getchar") +#pragma comment(linker, "/EXPORT:getenv=msvcrt.getenv") +#pragma comment(linker, "/EXPORT:getenv_s=msvcrt.getenv_s") +#pragma comment(linker, "/EXPORT:gets=msvcrt.gets") +#pragma comment(linker, "/EXPORT:getwc=msvcrt.getwc") +#pragma comment(linker, "/EXPORT:getwchar=msvcrt.getwchar") +#pragma comment(linker, "/EXPORT:gmtime=msvcrt.gmtime") +#pragma comment(linker, "/EXPORT:is_wctype=msvcrt.is_wctype") +#pragma comment(linker, "/EXPORT:isalnum=msvcrt.isalnum") +#pragma comment(linker, "/EXPORT:isalpha=msvcrt.isalpha") +#pragma comment(linker, "/EXPORT:iscntrl=msvcrt.iscntrl") +#pragma comment(linker, "/EXPORT:isdigit=msvcrt.isdigit") +#pragma comment(linker, "/EXPORT:isgraph=msvcrt.isgraph") +#pragma comment(linker, "/EXPORT:isleadbyte=msvcrt.isleadbyte") +#pragma comment(linker, "/EXPORT:islower=msvcrt.islower") +#pragma comment(linker, "/EXPORT:isprint=msvcrt.isprint") +#pragma comment(linker, "/EXPORT:ispunct=msvcrt.ispunct") +#pragma comment(linker, "/EXPORT:isspace=msvcrt.isspace") +#pragma comment(linker, "/EXPORT:isupper=msvcrt.isupper") +#pragma comment(linker, "/EXPORT:iswalnum=msvcrt.iswalnum") +#pragma comment(linker, "/EXPORT:iswalpha=msvcrt.iswalpha") +#pragma comment(linker, "/EXPORT:iswascii=msvcrt.iswascii") +#pragma comment(linker, "/EXPORT:iswcntrl=msvcrt.iswcntrl") +#pragma comment(linker, "/EXPORT:iswctype=msvcrt.iswctype") +#pragma comment(linker, "/EXPORT:iswdigit=msvcrt.iswdigit") +#pragma comment(linker, "/EXPORT:iswgraph=msvcrt.iswgraph") +#pragma comment(linker, "/EXPORT:iswlower=msvcrt.iswlower") +#pragma comment(linker, "/EXPORT:iswprint=msvcrt.iswprint") +#pragma comment(linker, "/EXPORT:iswpunct=msvcrt.iswpunct") +#pragma comment(linker, "/EXPORT:iswspace=msvcrt.iswspace") +#pragma comment(linker, "/EXPORT:iswupper=msvcrt.iswupper") +#pragma comment(linker, "/EXPORT:iswxdigit=msvcrt.iswxdigit") +#pragma comment(linker, "/EXPORT:isxdigit=msvcrt.isxdigit") +#pragma comment(linker, "/EXPORT:labs=msvcrt.labs") +#pragma comment(linker, "/EXPORT:ldexp=msvcrt.ldexp") +#pragma comment(linker, "/EXPORT:ldiv=msvcrt.ldiv") +#pragma comment(linker, "/EXPORT:localeconv=msvcrt.localeconv") +#pragma comment(linker, "/EXPORT:localtime=msvcrt.localtime") +#pragma comment(linker, "/EXPORT:log=msvcrt.log") +#pragma comment(linker, "/EXPORT:log10=msvcrt.log10") +#pragma comment(linker, "/EXPORT:log10f=msvcrt.log10f") +#pragma comment(linker, "/EXPORT:logf=msvcrt.logf") +#pragma comment(linker, "/EXPORT:longjmp=msvcrt.longjmp") +#pragma comment(linker, "/EXPORT:malloc=msvcrt.malloc") +#pragma comment(linker, "/EXPORT:mblen=msvcrt.mblen") +#pragma comment(linker, "/EXPORT:mbrlen=msvcrt.mbrlen") +#pragma comment(linker, "/EXPORT:mbrtowc=msvcrt.mbrtowc") +#pragma comment(linker, "/EXPORT:mbsdup_dbg=msvcrt.mbsdup_dbg") +#pragma comment(linker, "/EXPORT:mbsrtowcs=msvcrt.mbsrtowcs") +#pragma comment(linker, "/EXPORT:mbsrtowcs_s=msvcrt.mbsrtowcs_s") +#pragma comment(linker, "/EXPORT:mbstowcs=msvcrt.mbstowcs") +#pragma comment(linker, "/EXPORT:mbstowcs_s=msvcrt.mbstowcs_s") +#pragma comment(linker, "/EXPORT:mbtowc=msvcrt.mbtowc") +#pragma comment(linker, "/EXPORT:memchr=msvcrt.memchr") +#pragma comment(linker, "/EXPORT:memcmp=msvcrt.memcmp") +#pragma comment(linker, "/EXPORT:memcpy=msvcrt.memcpy") +#pragma comment(linker, "/EXPORT:memcpy_s=msvcrt.memcpy_s") +#pragma comment(linker, "/EXPORT:memmove=msvcrt.memmove") +#pragma comment(linker, "/EXPORT:memmove_s=msvcrt.memmove_s") +#pragma comment(linker, "/EXPORT:memset=msvcrt.memset") +#pragma comment(linker, "/EXPORT:mktime=msvcrt.mktime") +#pragma comment(linker, "/EXPORT:modf=msvcrt.modf") +#pragma comment(linker, "/EXPORT:modff=msvcrt.modff") +#pragma comment(linker, "/EXPORT:perror=msvcrt.perror") +#pragma comment(linker, "/EXPORT:pow=msvcrt.pow") +#pragma comment(linker, "/EXPORT:powf=msvcrt.powf") +#pragma comment(linker, "/EXPORT:printf=msvcrt.printf") +#pragma comment(linker, "/EXPORT:printf_s=msvcrt.printf_s") +#pragma comment(linker, "/EXPORT:putc=msvcrt.putc") +#pragma comment(linker, "/EXPORT:putchar=msvcrt.putchar") +#pragma comment(linker, "/EXPORT:puts=msvcrt.puts") +#pragma comment(linker, "/EXPORT:putwc=msvcrt.putwc") +#pragma comment(linker, "/EXPORT:putwchar=msvcrt.putwchar") +#pragma comment(linker, "/EXPORT:qsort=msvcrt.qsort") +#pragma comment(linker, "/EXPORT:qsort_s=msvcrt.qsort_s") +#pragma comment(linker, "/EXPORT:raise=msvcrt.raise") +#pragma comment(linker, "/EXPORT:rand=msvcrt.rand") +#pragma comment(linker, "/EXPORT:rand_s=msvcrt.rand_s") +#pragma comment(linker, "/EXPORT:realloc=msvcrt.realloc") +#pragma comment(linker, "/EXPORT:remove=msvcrt.remove") +#pragma comment(linker, "/EXPORT:rename=msvcrt.rename") +#pragma comment(linker, "/EXPORT:rewind=msvcrt.rewind") +#pragma comment(linker, "/EXPORT:scanf=msvcrt.scanf") +#pragma comment(linker, "/EXPORT:scanf_s=msvcrt.scanf_s") +#pragma comment(linker, "/EXPORT:setbuf=msvcrt.setbuf") +#pragma comment(linker, "/EXPORT:setjmp=msvcrt.setjmp") +#pragma comment(linker, "/EXPORT:setlocale=msvcrt.setlocale") +#pragma comment(linker, "/EXPORT:setvbuf=msvcrt.setvbuf") +#pragma comment(linker, "/EXPORT:signal=msvcrt.signal") +#pragma comment(linker, "/EXPORT:sin=msvcrt.sin") +#pragma comment(linker, "/EXPORT:sinf=msvcrt.sinf") +#pragma comment(linker, "/EXPORT:sinh=msvcrt.sinh") +#pragma comment(linker, "/EXPORT:sinhf=msvcrt.sinhf") +#pragma comment(linker, "/EXPORT:sprintf=msvcrt.sprintf") +#pragma comment(linker, "/EXPORT:sprintf_s=msvcrt.sprintf_s") +#pragma comment(linker, "/EXPORT:sqrt=msvcrt.sqrt") +#pragma comment(linker, "/EXPORT:sqrtf=msvcrt.sqrtf") +#pragma comment(linker, "/EXPORT:srand=msvcrt.srand") +#pragma comment(linker, "/EXPORT:sscanf=msvcrt.sscanf") +#pragma comment(linker, "/EXPORT:sscanf_s=msvcrt.sscanf_s") +#pragma comment(linker, "/EXPORT:strcat=msvcrt.strcat") +#pragma comment(linker, "/EXPORT:strcat_s=msvcrt.strcat_s") +#pragma comment(linker, "/EXPORT:strchr=msvcrt.strchr") +#pragma comment(linker, "/EXPORT:strcmp=msvcrt.strcmp") +#pragma comment(linker, "/EXPORT:strcoll=msvcrt.strcoll") +#pragma comment(linker, "/EXPORT:strcpy=msvcrt.strcpy") +#pragma comment(linker, "/EXPORT:strcpy_s=msvcrt.strcpy_s") +#pragma comment(linker, "/EXPORT:strcspn=msvcrt.strcspn") +#pragma comment(linker, "/EXPORT:strerror=msvcrt.strerror") +#pragma comment(linker, "/EXPORT:strerror_s=msvcrt.strerror_s") +#pragma comment(linker, "/EXPORT:strftime=msvcrt.strftime") +#pragma comment(linker, "/EXPORT:strlen=msvcrt.strlen") +#pragma comment(linker, "/EXPORT:strncat=msvcrt.strncat") +#pragma comment(linker, "/EXPORT:strncat_s=msvcrt.strncat_s") +#pragma comment(linker, "/EXPORT:strncmp=msvcrt.strncmp") +#pragma comment(linker, "/EXPORT:strncpy=msvcrt.strncpy") +#pragma comment(linker, "/EXPORT:strncpy_s=msvcrt.strncpy_s") +#pragma comment(linker, "/EXPORT:strnlen=msvcrt.strnlen") +#pragma comment(linker, "/EXPORT:strpbrk=msvcrt.strpbrk") +#pragma comment(linker, "/EXPORT:strrchr=msvcrt.strrchr") +#pragma comment(linker, "/EXPORT:strspn=msvcrt.strspn") +#pragma comment(linker, "/EXPORT:strstr=msvcrt.strstr") +#pragma comment(linker, "/EXPORT:strtod=msvcrt.strtod") +#pragma comment(linker, "/EXPORT:strtok=msvcrt.strtok") +#pragma comment(linker, "/EXPORT:strtok_s=msvcrt.strtok_s") +#pragma comment(linker, "/EXPORT:strtol=msvcrt.strtol") +#pragma comment(linker, "/EXPORT:strtoul=msvcrt.strtoul") +#pragma comment(linker, "/EXPORT:strxfrm=msvcrt.strxfrm") +#pragma comment(linker, "/EXPORT:swprintf=msvcrt.swprintf") +#pragma comment(linker, "/EXPORT:swprintf_s=msvcrt.swprintf_s") +#pragma comment(linker, "/EXPORT:swscanf=msvcrt.swscanf") +#pragma comment(linker, "/EXPORT:swscanf_s=msvcrt.swscanf_s") +#pragma comment(linker, "/EXPORT:system=msvcrt.system") +#pragma comment(linker, "/EXPORT:tan=msvcrt.tan") +#pragma comment(linker, "/EXPORT:tanf=msvcrt.tanf") +#pragma comment(linker, "/EXPORT:tanh=msvcrt.tanh") +#pragma comment(linker, "/EXPORT:tanhf=msvcrt.tanhf") +#pragma comment(linker, "/EXPORT:time=msvcrt.time") +#pragma comment(linker, "/EXPORT:tmpfile=msvcrt.tmpfile") +#pragma comment(linker, "/EXPORT:tmpfile_s=msvcrt.tmpfile_s") +#pragma comment(linker, "/EXPORT:tmpnam=msvcrt.tmpnam") +#pragma comment(linker, "/EXPORT:tmpnam_s=msvcrt.tmpnam_s") +#pragma comment(linker, "/EXPORT:tolower=msvcrt.tolower") +#pragma comment(linker, "/EXPORT:toupper=msvcrt.toupper") +#pragma comment(linker, "/EXPORT:towlower=msvcrt.towlower") +#pragma comment(linker, "/EXPORT:towupper=msvcrt.towupper") +#pragma comment(linker, "/EXPORT:ungetc=msvcrt.ungetc") +#pragma comment(linker, "/EXPORT:ungetwc=msvcrt.ungetwc") +#pragma comment(linker, "/EXPORT:utime=msvcrt.utime") +#pragma comment(linker, "/EXPORT:vfprintf=msvcrt.vfprintf") +#pragma comment(linker, "/EXPORT:vfprintf_s=msvcrt.vfprintf_s") +#pragma comment(linker, "/EXPORT:vfwprintf=msvcrt.vfwprintf") +#pragma comment(linker, "/EXPORT:vfwprintf_s=msvcrt.vfwprintf_s") +#pragma comment(linker, "/EXPORT:vprintf=msvcrt.vprintf") +#pragma comment(linker, "/EXPORT:vprintf_s=msvcrt.vprintf_s") +#pragma comment(linker, "/EXPORT:vsnprintf=msvcrt.vsnprintf") +#pragma comment(linker, "/EXPORT:vsprintf=msvcrt.vsprintf") +#pragma comment(linker, "/EXPORT:vsprintf_s=msvcrt.vsprintf_s") +#pragma comment(linker, "/EXPORT:vswprintf=msvcrt.vswprintf") +#pragma comment(linker, "/EXPORT:vswprintf_s=msvcrt.vswprintf_s") +#pragma comment(linker, "/EXPORT:vwprintf=msvcrt.vwprintf") +#pragma comment(linker, "/EXPORT:vwprintf_s=msvcrt.vwprintf_s") +#pragma comment(linker, "/EXPORT:wcrtomb=msvcrt.wcrtomb") +#pragma comment(linker, "/EXPORT:wcrtomb_s=msvcrt.wcrtomb_s") +#pragma comment(linker, "/EXPORT:wcscat=msvcrt.wcscat") +#pragma comment(linker, "/EXPORT:wcscat_s=msvcrt.wcscat_s") +#pragma comment(linker, "/EXPORT:wcschr=msvcrt.wcschr") +#pragma comment(linker, "/EXPORT:wcscmp=msvcrt.wcscmp") +#pragma comment(linker, "/EXPORT:wcscoll=msvcrt.wcscoll") +#pragma comment(linker, "/EXPORT:wcscpy=msvcrt.wcscpy") +#pragma comment(linker, "/EXPORT:wcscpy_s=msvcrt.wcscpy_s") +#pragma comment(linker, "/EXPORT:wcscspn=msvcrt.wcscspn") +#pragma comment(linker, "/EXPORT:wcsftime=msvcrt.wcsftime") +#pragma comment(linker, "/EXPORT:wcslen=msvcrt.wcslen") +#pragma comment(linker, "/EXPORT:wcsncat=msvcrt.wcsncat") +#pragma comment(linker, "/EXPORT:wcsncat_s=msvcrt.wcsncat_s") +#pragma comment(linker, "/EXPORT:wcsncmp=msvcrt.wcsncmp") +#pragma comment(linker, "/EXPORT:wcsncpy=msvcrt.wcsncpy") +#pragma comment(linker, "/EXPORT:wcsncpy_s=msvcrt.wcsncpy_s") +#pragma comment(linker, "/EXPORT:wcsnlen=msvcrt.wcsnlen") +#pragma comment(linker, "/EXPORT:wcspbrk=msvcrt.wcspbrk") +#pragma comment(linker, "/EXPORT:wcsrchr=msvcrt.wcsrchr") +#pragma comment(linker, "/EXPORT:wcsrtombs=msvcrt.wcsrtombs") +#pragma comment(linker, "/EXPORT:wcsrtombs_s=msvcrt.wcsrtombs_s") +#pragma comment(linker, "/EXPORT:wcsspn=msvcrt.wcsspn") +#pragma comment(linker, "/EXPORT:wcsstr=msvcrt.wcsstr") +#pragma comment(linker, "/EXPORT:wcstod=msvcrt.wcstod") +#pragma comment(linker, "/EXPORT:wcstok=msvcrt.wcstok") +#pragma comment(linker, "/EXPORT:wcstok_s=msvcrt.wcstok_s") +#pragma comment(linker, "/EXPORT:wcstol=msvcrt.wcstol") +#pragma comment(linker, "/EXPORT:wcstombs=msvcrt.wcstombs") +#pragma comment(linker, "/EXPORT:wcstombs_s=msvcrt.wcstombs_s") +#pragma comment(linker, "/EXPORT:wcstoul=msvcrt.wcstoul") +#pragma comment(linker, "/EXPORT:wcsxfrm=msvcrt.wcsxfrm") +#pragma comment(linker, "/EXPORT:wctob=msvcrt.wctob") +#pragma comment(linker, "/EXPORT:wctomb=msvcrt.wctomb") +#pragma comment(linker, "/EXPORT:wctomb_s=msvcrt.wctomb_s") +#pragma comment(linker, "/EXPORT:wprintf=msvcrt.wprintf") +#pragma comment(linker, "/EXPORT:wprintf_s=msvcrt.wprintf_s") +#pragma comment(linker, "/EXPORT:wscanf=msvcrt.wscanf") +#pragma comment(linker, "/EXPORT:wscanf_s=msvcrt.wscanf_s") + +#else + +// Generated by KexExprt from "C:\Windows\syswow64\msvcrt.dll" +#pragma comment(linker, "/EXPORT:$I10_OUTPUT=msvcrt.$I10_OUTPUT") +#pragma comment(linker, "/EXPORT:??0__non_rtti_object@@QAE@ABV0@@Z=msvcrt.??0__non_rtti_object@@QAE@ABV0@@Z") +#pragma comment(linker, "/EXPORT:??0__non_rtti_object@@QAE@PBD@Z=msvcrt.??0__non_rtti_object@@QAE@PBD@Z") +#pragma comment(linker, "/EXPORT:??0bad_cast@@AAE@PBQBD@Z=msvcrt.??0bad_cast@@AAE@PBQBD@Z") +#pragma comment(linker, "/EXPORT:??0bad_cast@@QAE@ABQBD@Z=msvcrt.??0bad_cast@@QAE@ABQBD@Z") +#pragma comment(linker, "/EXPORT:??0bad_cast@@QAE@ABV0@@Z=msvcrt.??0bad_cast@@QAE@ABV0@@Z") +#pragma comment(linker, "/EXPORT:??0bad_cast@@QAE@PBD@Z=msvcrt.??0bad_cast@@QAE@PBD@Z") +#pragma comment(linker, "/EXPORT:??0bad_typeid@@QAE@ABV0@@Z=msvcrt.??0bad_typeid@@QAE@ABV0@@Z") +#pragma comment(linker, "/EXPORT:??0bad_typeid@@QAE@PBD@Z=msvcrt.??0bad_typeid@@QAE@PBD@Z") +#pragma comment(linker, "/EXPORT:??0exception@@QAE@ABQBD@Z=msvcrt.??0exception@@QAE@ABQBD@Z") +#pragma comment(linker, "/EXPORT:??0exception@@QAE@ABQBDH@Z=msvcrt.??0exception@@QAE@ABQBDH@Z") +#pragma comment(linker, "/EXPORT:??0exception@@QAE@ABV0@@Z=msvcrt.??0exception@@QAE@ABV0@@Z") +#pragma comment(linker, "/EXPORT:??0exception@@QAE@XZ=msvcrt.??0exception@@QAE@XZ") +#pragma comment(linker, "/EXPORT:??1__non_rtti_object@@UAE@XZ=msvcrt.??1__non_rtti_object@@UAE@XZ") +#pragma comment(linker, "/EXPORT:??1bad_cast@@UAE@XZ=msvcrt.??1bad_cast@@UAE@XZ") +#pragma comment(linker, "/EXPORT:??1bad_typeid@@UAE@XZ=msvcrt.??1bad_typeid@@UAE@XZ") +#pragma comment(linker, "/EXPORT:??1exception@@UAE@XZ=msvcrt.??1exception@@UAE@XZ") +#pragma comment(linker, "/EXPORT:??1type_info@@UAE@XZ=msvcrt.??1type_info@@UAE@XZ") +#pragma comment(linker, "/EXPORT:??2@YAPAXI@Z=msvcrt.??2@YAPAXI@Z") +#pragma comment(linker, "/EXPORT:??2@YAPAXIHPBDH@Z=msvcrt.??2@YAPAXIHPBDH@Z") +#pragma comment(linker, "/EXPORT:??3@YAXPAX@Z=msvcrt.??3@YAXPAX@Z") +#pragma comment(linker, "/EXPORT:??4__non_rtti_object@@QAEAAV0@ABV0@@Z=msvcrt.??4__non_rtti_object@@QAEAAV0@ABV0@@Z") +#pragma comment(linker, "/EXPORT:??4bad_cast@@QAEAAV0@ABV0@@Z=msvcrt.??4bad_cast@@QAEAAV0@ABV0@@Z") +#pragma comment(linker, "/EXPORT:??4bad_typeid@@QAEAAV0@ABV0@@Z=msvcrt.??4bad_typeid@@QAEAAV0@ABV0@@Z") +#pragma comment(linker, "/EXPORT:??4exception@@QAEAAV0@ABV0@@Z=msvcrt.??4exception@@QAEAAV0@ABV0@@Z") +#pragma comment(linker, "/EXPORT:??8type_info@@QBEHABV0@@Z=msvcrt.??8type_info@@QBEHABV0@@Z") +#pragma comment(linker, "/EXPORT:??9type_info@@QBEHABV0@@Z=msvcrt.??9type_info@@QBEHABV0@@Z") +#pragma comment(linker, "/EXPORT:??_7__non_rtti_object@@6B@=msvcrt.??_7__non_rtti_object@@6B@") +#pragma comment(linker, "/EXPORT:??_7bad_cast@@6B@=msvcrt.??_7bad_cast@@6B@") +#pragma comment(linker, "/EXPORT:??_7bad_typeid@@6B@=msvcrt.??_7bad_typeid@@6B@") +#pragma comment(linker, "/EXPORT:??_7exception@@6B@=msvcrt.??_7exception@@6B@") +#pragma comment(linker, "/EXPORT:??_E__non_rtti_object@@UAEPAXI@Z=msvcrt.??_E__non_rtti_object@@UAEPAXI@Z") +#pragma comment(linker, "/EXPORT:??_Ebad_cast@@UAEPAXI@Z=msvcrt.??_Ebad_cast@@UAEPAXI@Z") +#pragma comment(linker, "/EXPORT:??_Ebad_typeid@@UAEPAXI@Z=msvcrt.??_Ebad_typeid@@UAEPAXI@Z") +#pragma comment(linker, "/EXPORT:??_Eexception@@UAEPAXI@Z=msvcrt.??_Eexception@@UAEPAXI@Z") +#pragma comment(linker, "/EXPORT:??_Fbad_cast@@QAEXXZ=msvcrt.??_Fbad_cast@@QAEXXZ") +#pragma comment(linker, "/EXPORT:??_Fbad_typeid@@QAEXXZ=msvcrt.??_Fbad_typeid@@QAEXXZ") +#pragma comment(linker, "/EXPORT:??_G__non_rtti_object@@UAEPAXI@Z=msvcrt.??_G__non_rtti_object@@UAEPAXI@Z") +#pragma comment(linker, "/EXPORT:??_Gbad_cast@@UAEPAXI@Z=msvcrt.??_Gbad_cast@@UAEPAXI@Z") +#pragma comment(linker, "/EXPORT:??_Gbad_typeid@@UAEPAXI@Z=msvcrt.??_Gbad_typeid@@UAEPAXI@Z") +#pragma comment(linker, "/EXPORT:??_Gexception@@UAEPAXI@Z=msvcrt.??_Gexception@@UAEPAXI@Z") +#pragma comment(linker, "/EXPORT:??_U@YAPAXI@Z=msvcrt.??_U@YAPAXI@Z") +#pragma comment(linker, "/EXPORT:??_U@YAPAXIHPBDH@Z=msvcrt.??_U@YAPAXIHPBDH@Z") +#pragma comment(linker, "/EXPORT:??_V@YAXPAX@Z=msvcrt.??_V@YAXPAX@Z") +#pragma comment(linker, "/EXPORT:?_query_new_handler@@YAP6AHI@ZXZ=msvcrt.?_query_new_handler@@YAP6AHI@ZXZ") +#pragma comment(linker, "/EXPORT:?_query_new_mode@@YAHXZ=msvcrt.?_query_new_mode@@YAHXZ") +#pragma comment(linker, "/EXPORT:?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z=msvcrt.?_set_new_handler@@YAP6AHI@ZP6AHI@Z@Z") +#pragma comment(linker, "/EXPORT:?_set_new_mode@@YAHH@Z=msvcrt.?_set_new_mode@@YAHH@Z") +#pragma comment(linker, "/EXPORT:?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z=msvcrt.?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z") +#pragma comment(linker, "/EXPORT:?before@type_info@@QBEHABV1@@Z=msvcrt.?before@type_info@@QBEHABV1@@Z") +#pragma comment(linker, "/EXPORT:?name@type_info@@QBEPBDXZ=msvcrt.?name@type_info@@QBEPBDXZ") +#pragma comment(linker, "/EXPORT:?raw_name@type_info@@QBEPBDXZ=msvcrt.?raw_name@type_info@@QBEPBDXZ") +#pragma comment(linker, "/EXPORT:?set_new_handler@@YAP6AXXZP6AXXZ@Z=msvcrt.?set_new_handler@@YAP6AXXZP6AXXZ@Z") +#pragma comment(linker, "/EXPORT:?set_terminate@@YAP6AXXZP6AXXZ@Z=msvcrt.?set_terminate@@YAP6AXXZP6AXXZ@Z") +#pragma comment(linker, "/EXPORT:?set_unexpected@@YAP6AXXZP6AXXZ@Z=msvcrt.?set_unexpected@@YAP6AXXZP6AXXZ@Z") +#pragma comment(linker, "/EXPORT:?terminate@@YAXXZ=msvcrt.?terminate@@YAXXZ") +#pragma comment(linker, "/EXPORT:?unexpected@@YAXXZ=msvcrt.?unexpected@@YAXXZ") +#pragma comment(linker, "/EXPORT:?what@exception@@UBEPBDXZ=msvcrt.?what@exception@@UBEPBDXZ") +#pragma comment(linker, "/EXPORT:___CIacos=msvcrt._CIacos") +#pragma comment(linker, "/EXPORT:___CIasin=msvcrt._CIasin") +#pragma comment(linker, "/EXPORT:___CIatan=msvcrt._CIatan") +#pragma comment(linker, "/EXPORT:___CIatan2=msvcrt._CIatan2") +#pragma comment(linker, "/EXPORT:__CIcos=msvcrt._CIcos") +#pragma comment(linker, "/EXPORT:__CIcosh=msvcrt._CIcosh") +#pragma comment(linker, "/EXPORT:__CIexp=msvcrt._CIexp") +#pragma comment(linker, "/EXPORT:__CIfmod=msvcrt._CIfmod") +#pragma comment(linker, "/EXPORT:__CIlog=msvcrt._CIlog") +#pragma comment(linker, "/EXPORT:__CIlog10=msvcrt._CIlog10") +#pragma comment(linker, "/EXPORT:__CIpow=msvcrt._CIpow") +#pragma comment(linker, "/EXPORT:__CIsin=msvcrt._CIsin") +#pragma comment(linker, "/EXPORT:__CIsinh=msvcrt._CIsinh") +#pragma comment(linker, "/EXPORT:__CIsqrt=msvcrt._CIsqrt") +#pragma comment(linker, "/EXPORT:__CItan=msvcrt._CItan") +#pragma comment(linker, "/EXPORT:__CItanh=msvcrt._CItanh") +#pragma comment(linker, "/EXPORT:__CrtCheckMemory=msvcrt._CrtCheckMemory") +#pragma comment(linker, "/EXPORT:__CrtDbgBreak=msvcrt._CrtDbgBreak") +#pragma comment(linker, "/EXPORT:__CrtDbgReport=msvcrt._CrtDbgReport") +#pragma comment(linker, "/EXPORT:__CrtDbgReportV=msvcrt._CrtDbgReportV") +#pragma comment(linker, "/EXPORT:__CrtDbgReportW=msvcrt._CrtDbgReportW") +#pragma comment(linker, "/EXPORT:__CrtDbgReportWV=msvcrt._CrtDbgReportWV") +#pragma comment(linker, "/EXPORT:__CrtDoForAllClientObjects=msvcrt._CrtDoForAllClientObjects") +#pragma comment(linker, "/EXPORT:__CrtDumpMemoryLeaks=msvcrt._CrtDumpMemoryLeaks") +#pragma comment(linker, "/EXPORT:__CrtIsMemoryBlock=msvcrt._CrtIsMemoryBlock") +#pragma comment(linker, "/EXPORT:__CrtIsValidHeapPointer=msvcrt._CrtIsValidHeapPointer") +#pragma comment(linker, "/EXPORT:__CrtIsValidPointer=msvcrt._CrtIsValidPointer") +#pragma comment(linker, "/EXPORT:__CrtMemCheckpoint=msvcrt._CrtMemCheckpoint") +#pragma comment(linker, "/EXPORT:__CrtMemDifference=msvcrt._CrtMemDifference") +#pragma comment(linker, "/EXPORT:__CrtMemDumpAllObjectsSince=msvcrt._CrtMemDumpAllObjectsSince") +#pragma comment(linker, "/EXPORT:__CrtMemDumpStatistics=msvcrt._CrtMemDumpStatistics") +#pragma comment(linker, "/EXPORT:__CrtReportBlockType=msvcrt._CrtReportBlockType") +#pragma comment(linker, "/EXPORT:__CrtSetAllocHook=msvcrt._CrtSetAllocHook") +#pragma comment(linker, "/EXPORT:__CrtSetBreakAlloc=msvcrt._CrtSetBreakAlloc") +#pragma comment(linker, "/EXPORT:__CrtSetDbgBlockType=msvcrt._CrtSetDbgBlockType") +#pragma comment(linker, "/EXPORT:__CrtSetDbgFlag=msvcrt._CrtSetDbgFlag") +#pragma comment(linker, "/EXPORT:__CrtSetDumpClient=msvcrt._CrtSetDumpClient") +#pragma comment(linker, "/EXPORT:__CrtSetReportFile=msvcrt._CrtSetReportFile") +#pragma comment(linker, "/EXPORT:__CrtSetReportHook=msvcrt._CrtSetReportHook") +#pragma comment(linker, "/EXPORT:__CrtSetReportHook2=msvcrt._CrtSetReportHook2") +#pragma comment(linker, "/EXPORT:__CrtSetReportMode=msvcrt._CrtSetReportMode") +#pragma comment(linker, "/EXPORT:__CxxThrowException=msvcrt._CxxThrowException") +#pragma comment(linker, "/EXPORT:__EH_prolog=msvcrt._EH_prolog") +#pragma comment(linker, "/EXPORT:__Getdays=msvcrt._Getdays") +#pragma comment(linker, "/EXPORT:__Getmonths=msvcrt._Getmonths") +#pragma comment(linker, "/EXPORT:__Gettnames=msvcrt._Gettnames") +#pragma comment(linker, "/EXPORT:__HUGE=msvcrt._HUGE") +#pragma comment(linker, "/EXPORT:__Strftime=msvcrt._Strftime") +#pragma comment(linker, "/EXPORT:__XcptFilter=msvcrt._XcptFilter") +#pragma comment(linker, "/EXPORT:___CppXcptFilter=msvcrt.__CppXcptFilter") +#pragma comment(linker, "/EXPORT:___CxxCallUnwindDelDtor=msvcrt.__CxxCallUnwindDelDtor") +#pragma comment(linker, "/EXPORT:___CxxCallUnwindDtor=msvcrt.__CxxCallUnwindDtor") +#pragma comment(linker, "/EXPORT:___CxxCallUnwindVecDtor=msvcrt.__CxxCallUnwindVecDtor") +#pragma comment(linker, "/EXPORT:___CxxDetectRethrow=msvcrt.__CxxDetectRethrow") +#pragma comment(linker, "/EXPORT:___CxxExceptionFilter=msvcrt.__CxxExceptionFilter") +#pragma comment(linker, "/EXPORT:___CxxFrameHandler=msvcrt.__CxxFrameHandler") +#pragma comment(linker, "/EXPORT:___CxxFrameHandler2=msvcrt.__CxxFrameHandler2") +#pragma comment(linker, "/EXPORT:___CxxFrameHandler3=msvcrt.__CxxFrameHandler3") +#pragma comment(linker, "/EXPORT:___CxxLongjmpUnwind=msvcrt.__CxxLongjmpUnwind") +#pragma comment(linker, "/EXPORT:___CxxQueryExceptionSize=msvcrt.__CxxQueryExceptionSize") +#pragma comment(linker, "/EXPORT:___CxxRegisterExceptionObject=msvcrt.__CxxRegisterExceptionObject") +#pragma comment(linker, "/EXPORT:___CxxUnregisterExceptionObject=msvcrt.__CxxUnregisterExceptionObject") +#pragma comment(linker, "/EXPORT:___DestructExceptionObject=msvcrt.__DestructExceptionObject") +#pragma comment(linker, "/EXPORT:___RTCastToVoid=msvcrt.__RTCastToVoid") +#pragma comment(linker, "/EXPORT:___RTDynamicCast=msvcrt.__RTDynamicCast") +#pragma comment(linker, "/EXPORT:___RTtypeid=msvcrt.__RTtypeid") +#pragma comment(linker, "/EXPORT:___STRINGTOLD=msvcrt.__STRINGTOLD") +#pragma comment(linker, "/EXPORT:____lc_codepage_func=msvcrt.___lc_codepage_func") +#pragma comment(linker, "/EXPORT:____lc_collate_cp_func=msvcrt.___lc_collate_cp_func") +#pragma comment(linker, "/EXPORT:____lc_handle_func=msvcrt.___lc_handle_func") +#pragma comment(linker, "/EXPORT:____mb_cur_max_func=msvcrt.___mb_cur_max_func") +#pragma comment(linker, "/EXPORT:____setlc_active_func=msvcrt.___setlc_active_func") +#pragma comment(linker, "/EXPORT:____unguarded_readlc_active_add_func=msvcrt.___unguarded_readlc_active_add_func") +#pragma comment(linker, "/EXPORT:___argc=msvcrt.__argc") +#pragma comment(linker, "/EXPORT:___argv=msvcrt.__argv") +#pragma comment(linker, "/EXPORT:___badioinfo=msvcrt.__badioinfo") +#pragma comment(linker, "/EXPORT:___crtCompareStringA=msvcrt.__crtCompareStringA") +#pragma comment(linker, "/EXPORT:___crtCompareStringW=msvcrt.__crtCompareStringW") +#pragma comment(linker, "/EXPORT:___crtGetLocaleInfoW=msvcrt.__crtGetLocaleInfoW") +#pragma comment(linker, "/EXPORT:___crtGetStringTypeW=msvcrt.__crtGetStringTypeW") +#pragma comment(linker, "/EXPORT:___crtLCMapStringA=msvcrt.__crtLCMapStringA") +#pragma comment(linker, "/EXPORT:___crtLCMapStringW=msvcrt.__crtLCMapStringW") +#pragma comment(linker, "/EXPORT:___daylight=msvcrt.__daylight") +#pragma comment(linker, "/EXPORT:___dllonexit=msvcrt.__dllonexit") +#pragma comment(linker, "/EXPORT:___doserrno=msvcrt.__doserrno") +#pragma comment(linker, "/EXPORT:___dstbias=msvcrt.__dstbias") +#pragma comment(linker, "/EXPORT:___fpecode=msvcrt.__fpecode") +#pragma comment(linker, "/EXPORT:___getmainargs=msvcrt.__getmainargs") +#pragma comment(linker, "/EXPORT:___initenv=msvcrt.__initenv") +#pragma comment(linker, "/EXPORT:___iob_func=msvcrt.__iob_func") +#pragma comment(linker, "/EXPORT:___isascii=msvcrt.__isascii") +#pragma comment(linker, "/EXPORT:___iscsym=msvcrt.__iscsym") +#pragma comment(linker, "/EXPORT:___iscsymf=msvcrt.__iscsymf") +#pragma comment(linker, "/EXPORT:___lc_codepage=msvcrt.__lc_codepage") +#pragma comment(linker, "/EXPORT:___lc_collate_cp=msvcrt.__lc_collate_cp") +#pragma comment(linker, "/EXPORT:___lc_handle=msvcrt.__lc_handle") +#pragma comment(linker, "/EXPORT:___lconv_init=msvcrt.__lconv_init") +#pragma comment(linker, "/EXPORT:___libm_sse2_acos=msvcrt.__libm_sse2_acos") +#pragma comment(linker, "/EXPORT:___libm_sse2_acosf=msvcrt.__libm_sse2_acosf") +#pragma comment(linker, "/EXPORT:___libm_sse2_asin=msvcrt.__libm_sse2_asin") +#pragma comment(linker, "/EXPORT:___libm_sse2_asinf=msvcrt.__libm_sse2_asinf") +#pragma comment(linker, "/EXPORT:___libm_sse2_atan=msvcrt.__libm_sse2_atan") +#pragma comment(linker, "/EXPORT:___libm_sse2_atan2=msvcrt.__libm_sse2_atan2") +#pragma comment(linker, "/EXPORT:___libm_sse2_atanf=msvcrt.__libm_sse2_atanf") +#pragma comment(linker, "/EXPORT:___libm_sse2_cos=msvcrt.__libm_sse2_cos") +#pragma comment(linker, "/EXPORT:___libm_sse2_cosf=msvcrt.__libm_sse2_cosf") +#pragma comment(linker, "/EXPORT:___libm_sse2_exp=msvcrt.__libm_sse2_exp") +#pragma comment(linker, "/EXPORT:___libm_sse2_expf=msvcrt.__libm_sse2_expf") +#pragma comment(linker, "/EXPORT:___libm_sse2_log=msvcrt.__libm_sse2_log") +#pragma comment(linker, "/EXPORT:___libm_sse2_log10=msvcrt.__libm_sse2_log10") +#pragma comment(linker, "/EXPORT:___libm_sse2_log10f=msvcrt.__libm_sse2_log10f") +#pragma comment(linker, "/EXPORT:___libm_sse2_logf=msvcrt.__libm_sse2_logf") +#pragma comment(linker, "/EXPORT:___libm_sse2_pow=msvcrt.__libm_sse2_pow") +#pragma comment(linker, "/EXPORT:___libm_sse2_powf=msvcrt.__libm_sse2_powf") +#pragma comment(linker, "/EXPORT:___libm_sse2_sin=msvcrt.__libm_sse2_sin") +#pragma comment(linker, "/EXPORT:___libm_sse2_sinf=msvcrt.__libm_sse2_sinf") +#pragma comment(linker, "/EXPORT:___libm_sse2_tan=msvcrt.__libm_sse2_tan") +#pragma comment(linker, "/EXPORT:___libm_sse2_tanf=msvcrt.__libm_sse2_tanf") +#pragma comment(linker, "/EXPORT:___mb_cur_max=msvcrt.__mb_cur_max") +#pragma comment(linker, "/EXPORT:___p___argc=msvcrt.__p___argc") +#pragma comment(linker, "/EXPORT:___p___argv=msvcrt.__p___argv") +#pragma comment(linker, "/EXPORT:___p___initenv=msvcrt.__p___initenv") +#pragma comment(linker, "/EXPORT:___p___mb_cur_max=msvcrt.__p___mb_cur_max") +#pragma comment(linker, "/EXPORT:___p___wargv=msvcrt.__p___wargv") +#pragma comment(linker, "/EXPORT:___p___winitenv=msvcrt.__p___winitenv") +#pragma comment(linker, "/EXPORT:___p__acmdln=msvcrt.__p__acmdln") +#pragma comment(linker, "/EXPORT:___p__amblksiz=msvcrt.__p__amblksiz") +#pragma comment(linker, "/EXPORT:___p__commode=msvcrt.__p__commode") +#pragma comment(linker, "/EXPORT:___p__daylight=msvcrt.__p__daylight") +#pragma comment(linker, "/EXPORT:___p__dstbias=msvcrt.__p__dstbias") +#pragma comment(linker, "/EXPORT:___p__environ=msvcrt.__p__environ") +#pragma comment(linker, "/EXPORT:___p__fileinfo=msvcrt.__p__fileinfo") +#pragma comment(linker, "/EXPORT:___p__fmode=msvcrt.__p__fmode") +#pragma comment(linker, "/EXPORT:___p__iob=msvcrt.__p__iob") +#pragma comment(linker, "/EXPORT:___p__mbcasemap=msvcrt.__p__mbcasemap") +#pragma comment(linker, "/EXPORT:___p__mbctype=msvcrt.__p__mbctype") +#pragma comment(linker, "/EXPORT:___p__osver=msvcrt.__p__osver") +#pragma comment(linker, "/EXPORT:___p__pctype=msvcrt.__p__pctype") +#pragma comment(linker, "/EXPORT:___p__pgmptr=msvcrt.__p__pgmptr") +#pragma comment(linker, "/EXPORT:___p__pwctype=msvcrt.__p__pwctype") +#pragma comment(linker, "/EXPORT:___p__timezone=msvcrt.__p__timezone") +#pragma comment(linker, "/EXPORT:___p__tzname=msvcrt.__p__tzname") +#pragma comment(linker, "/EXPORT:___p__wcmdln=msvcrt.__p__wcmdln") +#pragma comment(linker, "/EXPORT:___p__wenviron=msvcrt.__p__wenviron") +#pragma comment(linker, "/EXPORT:___p__winmajor=msvcrt.__p__winmajor") +#pragma comment(linker, "/EXPORT:___p__winminor=msvcrt.__p__winminor") +#pragma comment(linker, "/EXPORT:___p__winver=msvcrt.__p__winver") +#pragma comment(linker, "/EXPORT:___p__wpgmptr=msvcrt.__p__wpgmptr") +#pragma comment(linker, "/EXPORT:___pctype_func=msvcrt.__pctype_func") +#pragma comment(linker, "/EXPORT:___pioinfo=msvcrt.__pioinfo") +#pragma comment(linker, "/EXPORT:___pwctype_func=msvcrt.__pwctype_func") +#pragma comment(linker, "/EXPORT:___pxcptinfoptrs=msvcrt.__pxcptinfoptrs") +#pragma comment(linker, "/EXPORT:___set_app_type=msvcrt.__set_app_type") +#pragma comment(linker, "/EXPORT:___setlc_active=msvcrt.__setlc_active") +#pragma comment(linker, "/EXPORT:___setusermatherr=msvcrt.__setusermatherr") +#pragma comment(linker, "/EXPORT:___strncnt=msvcrt.__strncnt") +#pragma comment(linker, "/EXPORT:___threadhandle=msvcrt.__threadhandle") +#pragma comment(linker, "/EXPORT:___threadid=msvcrt.__threadid") +#pragma comment(linker, "/EXPORT:___toascii=msvcrt.__toascii") +#pragma comment(linker, "/EXPORT:___unDName=msvcrt.__unDName") +#pragma comment(linker, "/EXPORT:___unDNameEx=msvcrt.__unDNameEx") +#pragma comment(linker, "/EXPORT:___uncaught_exception=msvcrt.__uncaught_exception") +#pragma comment(linker, "/EXPORT:___unguarded_readlc_active=msvcrt.__unguarded_readlc_active") +#pragma comment(linker, "/EXPORT:___wargv=msvcrt.__wargv") +#pragma comment(linker, "/EXPORT:___wcserror=msvcrt.__wcserror") +#pragma comment(linker, "/EXPORT:___wcserror_s=msvcrt.__wcserror_s") +#pragma comment(linker, "/EXPORT:___wcsncnt=msvcrt.__wcsncnt") +#pragma comment(linker, "/EXPORT:___wgetmainargs=msvcrt.__wgetmainargs") +#pragma comment(linker, "/EXPORT:___winitenv=msvcrt.__winitenv") +#pragma comment(linker, "/EXPORT:__abnormal_termination=msvcrt._abnormal_termination") +#pragma comment(linker, "/EXPORT:__abs64=msvcrt._abs64") +#pragma comment(linker, "/EXPORT:__access=msvcrt._access") +#pragma comment(linker, "/EXPORT:__access_s=msvcrt._access_s") +#pragma comment(linker, "/EXPORT:__acmdln=msvcrt._acmdln") +#pragma comment(linker, "/EXPORT:__adj_fdiv_m16i=msvcrt._adj_fdiv_m16i") +#pragma comment(linker, "/EXPORT:__adj_fdiv_m32=msvcrt._adj_fdiv_m32") +#pragma comment(linker, "/EXPORT:__adj_fdiv_m32i=msvcrt._adj_fdiv_m32i") +#pragma comment(linker, "/EXPORT:__adj_fdiv_m64=msvcrt._adj_fdiv_m64") +#pragma comment(linker, "/EXPORT:__adj_fdiv_r=msvcrt._adj_fdiv_r") +#pragma comment(linker, "/EXPORT:__adj_fdivr_m16i=msvcrt._adj_fdivr_m16i") +#pragma comment(linker, "/EXPORT:__adj_fdivr_m32=msvcrt._adj_fdivr_m32") +#pragma comment(linker, "/EXPORT:__adj_fdivr_m32i=msvcrt._adj_fdivr_m32i") +#pragma comment(linker, "/EXPORT:__adj_fdivr_m64=msvcrt._adj_fdivr_m64") +#pragma comment(linker, "/EXPORT:__adj_fpatan=msvcrt._adj_fpatan") +#pragma comment(linker, "/EXPORT:__adj_fprem=msvcrt._adj_fprem") +#pragma comment(linker, "/EXPORT:__adj_fprem1=msvcrt._adj_fprem1") +#pragma comment(linker, "/EXPORT:__adj_fptan=msvcrt._adj_fptan") +#pragma comment(linker, "/EXPORT:__adjust_fdiv=msvcrt._adjust_fdiv") +#pragma comment(linker, "/EXPORT:__aexit_rtn=msvcrt._aexit_rtn") +#pragma comment(linker, "/EXPORT:__aligned_free=msvcrt._aligned_free") +#pragma comment(linker, "/EXPORT:__aligned_free_dbg=msvcrt._aligned_free_dbg") +#pragma comment(linker, "/EXPORT:__aligned_malloc=msvcrt._aligned_malloc") +#pragma comment(linker, "/EXPORT:__aligned_malloc_dbg=msvcrt._aligned_malloc_dbg") +#pragma comment(linker, "/EXPORT:__aligned_offset_malloc=msvcrt._aligned_offset_malloc") +#pragma comment(linker, "/EXPORT:__aligned_offset_malloc_dbg=msvcrt._aligned_offset_malloc_dbg") +#pragma comment(linker, "/EXPORT:__aligned_offset_realloc=msvcrt._aligned_offset_realloc") +#pragma comment(linker, "/EXPORT:__aligned_offset_realloc_dbg=msvcrt._aligned_offset_realloc_dbg") +#pragma comment(linker, "/EXPORT:__aligned_realloc=msvcrt._aligned_realloc") +#pragma comment(linker, "/EXPORT:__aligned_realloc_dbg=msvcrt._aligned_realloc_dbg") +#pragma comment(linker, "/EXPORT:__amsg_exit=msvcrt._amsg_exit") +#pragma comment(linker, "/EXPORT:__assert=msvcrt._assert") +#pragma comment(linker, "/EXPORT:__atodbl=msvcrt._atodbl") +#pragma comment(linker, "/EXPORT:__atodbl_l=msvcrt._atodbl_l") +#pragma comment(linker, "/EXPORT:__atof_l=msvcrt._atof_l") +#pragma comment(linker, "/EXPORT:__atoflt_l=msvcrt._atoflt_l") +#pragma comment(linker, "/EXPORT:__atoi64=msvcrt._atoi64") +#pragma comment(linker, "/EXPORT:__atoi64_l=msvcrt._atoi64_l") +#pragma comment(linker, "/EXPORT:__atoi_l=msvcrt._atoi_l") +#pragma comment(linker, "/EXPORT:__atol_l=msvcrt._atol_l") +#pragma comment(linker, "/EXPORT:__atoldbl=msvcrt._atoldbl") +#pragma comment(linker, "/EXPORT:__atoldbl_l=msvcrt._atoldbl_l") +#pragma comment(linker, "/EXPORT:__beep=msvcrt._beep") +#pragma comment(linker, "/EXPORT:__beginthread=msvcrt._beginthread") +#pragma comment(linker, "/EXPORT:__beginthreadex=msvcrt._beginthreadex") +#pragma comment(linker, "/EXPORT:__c_exit=msvcrt._c_exit") +#pragma comment(linker, "/EXPORT:__cabs=msvcrt._cabs") +#pragma comment(linker, "/EXPORT:__callnewh=msvcrt._callnewh") +#pragma comment(linker, "/EXPORT:__calloc_dbg=msvcrt._calloc_dbg") +#pragma comment(linker, "/EXPORT:__cexit=msvcrt._cexit") +#pragma comment(linker, "/EXPORT:__cgets=msvcrt._cgets") +#pragma comment(linker, "/EXPORT:__cgets_s=msvcrt._cgets_s") +#pragma comment(linker, "/EXPORT:__cgetws=msvcrt._cgetws") +#pragma comment(linker, "/EXPORT:__cgetws_s=msvcrt._cgetws_s") +#pragma comment(linker, "/EXPORT:__chdir=msvcrt._chdir") +#pragma comment(linker, "/EXPORT:__chdrive=msvcrt._chdrive") +#pragma comment(linker, "/EXPORT:__chgsign=msvcrt._chgsign") +#pragma comment(linker, "/EXPORT:__chkesp=msvcrt._chkesp") +#pragma comment(linker, "/EXPORT:__chmod=msvcrt._chmod") +#pragma comment(linker, "/EXPORT:__chsize=msvcrt._chsize") +#pragma comment(linker, "/EXPORT:__chsize_s=msvcrt._chsize_s") +#pragma comment(linker, "/EXPORT:__chvalidator=msvcrt._chvalidator") +#pragma comment(linker, "/EXPORT:__chvalidator_l=msvcrt._chvalidator_l") +#pragma comment(linker, "/EXPORT:__clearfp=msvcrt._clearfp") +#pragma comment(linker, "/EXPORT:__close=msvcrt._close") +#pragma comment(linker, "/EXPORT:__commit=msvcrt._commit") +#pragma comment(linker, "/EXPORT:__commode=msvcrt._commode") +#pragma comment(linker, "/EXPORT:__control87=msvcrt._control87") +#pragma comment(linker, "/EXPORT:__controlfp=msvcrt._controlfp") +#pragma comment(linker, "/EXPORT:__controlfp_s=msvcrt._controlfp_s") +#pragma comment(linker, "/EXPORT:__copysign=msvcrt._copysign") +#pragma comment(linker, "/EXPORT:__cprintf=msvcrt._cprintf") +#pragma comment(linker, "/EXPORT:__cprintf_l=msvcrt._cprintf_l") +#pragma comment(linker, "/EXPORT:__cprintf_p=msvcrt._cprintf_p") +#pragma comment(linker, "/EXPORT:__cprintf_p_l=msvcrt._cprintf_p_l") +#pragma comment(linker, "/EXPORT:__cprintf_s=msvcrt._cprintf_s") +#pragma comment(linker, "/EXPORT:__cprintf_s_l=msvcrt._cprintf_s_l") +#pragma comment(linker, "/EXPORT:__cputs=msvcrt._cputs") +#pragma comment(linker, "/EXPORT:__cputws=msvcrt._cputws") +#pragma comment(linker, "/EXPORT:__creat=msvcrt._creat") +#pragma comment(linker, "/EXPORT:__crtAssertBusy=msvcrt._crtAssertBusy") +#pragma comment(linker, "/EXPORT:__crtBreakAlloc=msvcrt._crtBreakAlloc") +#pragma comment(linker, "/EXPORT:__crtDbgFlag=msvcrt._crtDbgFlag") +#pragma comment(linker, "/EXPORT:__cscanf=msvcrt._cscanf") +#pragma comment(linker, "/EXPORT:__cscanf_l=msvcrt._cscanf_l") +#pragma comment(linker, "/EXPORT:__cscanf_s=msvcrt._cscanf_s") +#pragma comment(linker, "/EXPORT:__cscanf_s_l=msvcrt._cscanf_s_l") +#pragma comment(linker, "/EXPORT:__ctime32=msvcrt._ctime32") +#pragma comment(linker, "/EXPORT:__ctime32_s=msvcrt._ctime32_s") +#pragma comment(linker, "/EXPORT:__ctime64=msvcrt._ctime64") +#pragma comment(linker, "/EXPORT:__ctime64_s=msvcrt._ctime64_s") +#pragma comment(linker, "/EXPORT:__ctype=msvcrt._ctype") +#pragma comment(linker, "/EXPORT:__cwait=msvcrt._cwait") +#pragma comment(linker, "/EXPORT:__cwprintf=msvcrt._cwprintf") +#pragma comment(linker, "/EXPORT:__cwprintf_l=msvcrt._cwprintf_l") +#pragma comment(linker, "/EXPORT:__cwprintf_p=msvcrt._cwprintf_p") +#pragma comment(linker, "/EXPORT:__cwprintf_p_l=msvcrt._cwprintf_p_l") +#pragma comment(linker, "/EXPORT:__cwprintf_s=msvcrt._cwprintf_s") +#pragma comment(linker, "/EXPORT:__cwprintf_s_l=msvcrt._cwprintf_s_l") +#pragma comment(linker, "/EXPORT:__cwscanf=msvcrt._cwscanf") +#pragma comment(linker, "/EXPORT:__cwscanf_l=msvcrt._cwscanf_l") +#pragma comment(linker, "/EXPORT:__cwscanf_s=msvcrt._cwscanf_s") +#pragma comment(linker, "/EXPORT:__cwscanf_s_l=msvcrt._cwscanf_s_l") +#pragma comment(linker, "/EXPORT:__daylight=msvcrt._daylight") +#pragma comment(linker, "/EXPORT:__difftime32=msvcrt._difftime32") +#pragma comment(linker, "/EXPORT:__difftime64=msvcrt._difftime64") +#pragma comment(linker, "/EXPORT:__dstbias=msvcrt._dstbias") +#pragma comment(linker, "/EXPORT:__dup=msvcrt._dup") +#pragma comment(linker, "/EXPORT:__dup2=msvcrt._dup2") +#pragma comment(linker, "/EXPORT:__ecvt=msvcrt._ecvt") +#pragma comment(linker, "/EXPORT:__ecvt_s=msvcrt._ecvt_s") +#pragma comment(linker, "/EXPORT:__endthread=msvcrt._endthread") +#pragma comment(linker, "/EXPORT:__endthreadex=msvcrt._endthreadex") +#pragma comment(linker, "/EXPORT:__environ=msvcrt._environ") +#pragma comment(linker, "/EXPORT:__eof=msvcrt._eof") +#pragma comment(linker, "/EXPORT:__errno=msvcrt._errno") +#pragma comment(linker, "/EXPORT:__except_handler2=msvcrt._except_handler2") +#pragma comment(linker, "/EXPORT:__except_handler3=msvcrt._except_handler3") +#pragma comment(linker, "/EXPORT:__except_handler4_common=msvcrt._except_handler4_common") +#pragma comment(linker, "/EXPORT:__execl=msvcrt._execl") +#pragma comment(linker, "/EXPORT:__execle=msvcrt._execle") +#pragma comment(linker, "/EXPORT:__execlp=msvcrt._execlp") +#pragma comment(linker, "/EXPORT:__execlpe=msvcrt._execlpe") +#pragma comment(linker, "/EXPORT:__execv=msvcrt._execv") +#pragma comment(linker, "/EXPORT:__execve=msvcrt._execve") +#pragma comment(linker, "/EXPORT:__execvp=msvcrt._execvp") +#pragma comment(linker, "/EXPORT:__execvpe=msvcrt._execvpe") +#pragma comment(linker, "/EXPORT:__exit=msvcrt._exit") +#pragma comment(linker, "/EXPORT:__expand=msvcrt._expand") +#pragma comment(linker, "/EXPORT:__expand_dbg=msvcrt._expand_dbg") +#pragma comment(linker, "/EXPORT:__fcloseall=msvcrt._fcloseall") +#pragma comment(linker, "/EXPORT:__fcvt=msvcrt._fcvt") +#pragma comment(linker, "/EXPORT:__fcvt_s=msvcrt._fcvt_s") +#pragma comment(linker, "/EXPORT:__fdopen=msvcrt._fdopen") +#pragma comment(linker, "/EXPORT:__fgetchar=msvcrt._fgetchar") +#pragma comment(linker, "/EXPORT:__fgetwchar=msvcrt._fgetwchar") +#pragma comment(linker, "/EXPORT:__filbuf=msvcrt._filbuf") +#pragma comment(linker, "/EXPORT:__fileinfo=msvcrt._fileinfo") +#pragma comment(linker, "/EXPORT:__filelength=msvcrt._filelength") +#pragma comment(linker, "/EXPORT:__filelengthi64=msvcrt._filelengthi64") +#pragma comment(linker, "/EXPORT:__fileno=msvcrt._fileno") +#pragma comment(linker, "/EXPORT:__findclose=msvcrt._findclose") +#pragma comment(linker, "/EXPORT:__findfirst=msvcrt._findfirst") +#pragma comment(linker, "/EXPORT:__findfirst64=msvcrt._findfirst64") +#pragma comment(linker, "/EXPORT:__findfirsti64=msvcrt._findfirsti64") +#pragma comment(linker, "/EXPORT:__findnext=msvcrt._findnext") +#pragma comment(linker, "/EXPORT:__findnext64=msvcrt._findnext64") +#pragma comment(linker, "/EXPORT:__findnexti64=msvcrt._findnexti64") +#pragma comment(linker, "/EXPORT:__finite=msvcrt._finite") +#pragma comment(linker, "/EXPORT:__flsbuf=msvcrt._flsbuf") +#pragma comment(linker, "/EXPORT:__flushall=msvcrt._flushall") +#pragma comment(linker, "/EXPORT:__fmode=msvcrt._fmode") +#pragma comment(linker, "/EXPORT:__fpclass=msvcrt._fpclass") +#pragma comment(linker, "/EXPORT:__fpieee_flt=msvcrt._fpieee_flt") +#pragma comment(linker, "/EXPORT:__fpreset=msvcrt._fpreset") +#pragma comment(linker, "/EXPORT:__fprintf_l=msvcrt._fprintf_l") +#pragma comment(linker, "/EXPORT:__fprintf_p=msvcrt._fprintf_p") +#pragma comment(linker, "/EXPORT:__fprintf_p_l=msvcrt._fprintf_p_l") +#pragma comment(linker, "/EXPORT:__fprintf_s_l=msvcrt._fprintf_s_l") +#pragma comment(linker, "/EXPORT:__fputchar=msvcrt._fputchar") +#pragma comment(linker, "/EXPORT:__fputwchar=msvcrt._fputwchar") +#pragma comment(linker, "/EXPORT:__free_dbg=msvcrt._free_dbg") +#pragma comment(linker, "/EXPORT:__freea=msvcrt._freea") +#pragma comment(linker, "/EXPORT:__freea_s=msvcrt._freea_s") +#pragma comment(linker, "/EXPORT:__fscanf_l=msvcrt._fscanf_l") +#pragma comment(linker, "/EXPORT:__fscanf_s_l=msvcrt._fscanf_s_l") +#pragma comment(linker, "/EXPORT:__fseeki64=msvcrt._fseeki64") +#pragma comment(linker, "/EXPORT:__fsopen=msvcrt._fsopen") +#pragma comment(linker, "/EXPORT:__fstat=msvcrt._fstat") +#pragma comment(linker, "/EXPORT:__fstat64=msvcrt._fstat64") +#pragma comment(linker, "/EXPORT:__fstati64=msvcrt._fstati64") +#pragma comment(linker, "/EXPORT:__ftime=msvcrt._ftime") +#pragma comment(linker, "/EXPORT:__ftime32=msvcrt._ftime32") +#pragma comment(linker, "/EXPORT:__ftime32_s=msvcrt._ftime32_s") +#pragma comment(linker, "/EXPORT:__ftime64=msvcrt._ftime64") +#pragma comment(linker, "/EXPORT:__ftime64_s=msvcrt._ftime64_s") +#pragma comment(linker, "/EXPORT:__ftol=msvcrt._ftol") +#pragma comment(linker, "/EXPORT:__ftol2=msvcrt._ftol2") +#pragma comment(linker, "/EXPORT:__ftol2_sse=msvcrt._ftol2_sse") +#pragma comment(linker, "/EXPORT:__ftol2_sse_excpt=msvcrt._ftol2_sse_excpt") +#pragma comment(linker, "/EXPORT:__fullpath=msvcrt._fullpath") +#pragma comment(linker, "/EXPORT:__fullpath_dbg=msvcrt._fullpath_dbg") +#pragma comment(linker, "/EXPORT:__futime=msvcrt._futime") +#pragma comment(linker, "/EXPORT:__futime32=msvcrt._futime32") +#pragma comment(linker, "/EXPORT:__futime64=msvcrt._futime64") +#pragma comment(linker, "/EXPORT:__fwprintf_l=msvcrt._fwprintf_l") +#pragma comment(linker, "/EXPORT:__fwprintf_p=msvcrt._fwprintf_p") +#pragma comment(linker, "/EXPORT:__fwprintf_p_l=msvcrt._fwprintf_p_l") +#pragma comment(linker, "/EXPORT:__fwprintf_s_l=msvcrt._fwprintf_s_l") +#pragma comment(linker, "/EXPORT:__fwscanf_l=msvcrt._fwscanf_l") +#pragma comment(linker, "/EXPORT:__fwscanf_s_l=msvcrt._fwscanf_s_l") +#pragma comment(linker, "/EXPORT:__gcvt=msvcrt._gcvt") +#pragma comment(linker, "/EXPORT:__gcvt_s=msvcrt._gcvt_s") +#pragma comment(linker, "/EXPORT:__get_doserrno=msvcrt._get_doserrno") +#pragma comment(linker, "/EXPORT:__get_environ=msvcrt._get_environ") +#pragma comment(linker, "/EXPORT:__get_errno=msvcrt._get_errno") +#pragma comment(linker, "/EXPORT:__get_fileinfo=msvcrt._get_fileinfo") +#pragma comment(linker, "/EXPORT:__get_fmode=msvcrt._get_fmode") +#pragma comment(linker, "/EXPORT:__get_heap_handle=msvcrt._get_heap_handle") +#pragma comment(linker, "/EXPORT:__get_osfhandle=msvcrt._get_osfhandle") +#pragma comment(linker, "/EXPORT:__get_osplatform=msvcrt._get_osplatform") +#pragma comment(linker, "/EXPORT:__get_osver=msvcrt._get_osver") +#pragma comment(linker, "/EXPORT:__get_output_format=msvcrt._get_output_format") +#pragma comment(linker, "/EXPORT:__get_pgmptr=msvcrt._get_pgmptr") +#pragma comment(linker, "/EXPORT:__get_sbh_threshold=msvcrt._get_sbh_threshold") +#pragma comment(linker, "/EXPORT:__get_wenviron=msvcrt._get_wenviron") +#pragma comment(linker, "/EXPORT:__get_winmajor=msvcrt._get_winmajor") +#pragma comment(linker, "/EXPORT:__get_winminor=msvcrt._get_winminor") +#pragma comment(linker, "/EXPORT:__get_winver=msvcrt._get_winver") +#pragma comment(linker, "/EXPORT:__get_wpgmptr=msvcrt._get_wpgmptr") +#pragma comment(linker, "/EXPORT:__getch=msvcrt._getch") +#pragma comment(linker, "/EXPORT:__getche=msvcrt._getche") +#pragma comment(linker, "/EXPORT:__getcwd=msvcrt._getcwd") +#pragma comment(linker, "/EXPORT:__getdcwd=msvcrt._getdcwd") +#pragma comment(linker, "/EXPORT:__getdiskfree=msvcrt._getdiskfree") +#pragma comment(linker, "/EXPORT:__getdllprocaddr=msvcrt._getdllprocaddr") +#pragma comment(linker, "/EXPORT:__getdrive=msvcrt._getdrive") +#pragma comment(linker, "/EXPORT:__getdrives=msvcrt._getdrives") +#pragma comment(linker, "/EXPORT:__getmaxstdio=msvcrt._getmaxstdio") +#pragma comment(linker, "/EXPORT:__getmbcp=msvcrt._getmbcp") +#pragma comment(linker, "/EXPORT:__getpid=msvcrt._getpid") +#pragma comment(linker, "/EXPORT:__getsystime=msvcrt._getsystime") +#pragma comment(linker, "/EXPORT:__getw=msvcrt._getw") +#pragma comment(linker, "/EXPORT:__getwch=msvcrt._getwch") +#pragma comment(linker, "/EXPORT:__getwche=msvcrt._getwche") +#pragma comment(linker, "/EXPORT:__getws=msvcrt._getws") +#pragma comment(linker, "/EXPORT:__global_unwind2=msvcrt._global_unwind2") +#pragma comment(linker, "/EXPORT:__gmtime32=msvcrt._gmtime32") +#pragma comment(linker, "/EXPORT:__gmtime32_s=msvcrt._gmtime32_s") +#pragma comment(linker, "/EXPORT:__gmtime64=msvcrt._gmtime64") +#pragma comment(linker, "/EXPORT:__gmtime64_s=msvcrt._gmtime64_s") +#pragma comment(linker, "/EXPORT:__heapadd=msvcrt._heapadd") +#pragma comment(linker, "/EXPORT:__heapchk=msvcrt._heapchk") +#pragma comment(linker, "/EXPORT:__heapmin=msvcrt._heapmin") +#pragma comment(linker, "/EXPORT:__heapset=msvcrt._heapset") +#pragma comment(linker, "/EXPORT:__heapused=msvcrt._heapused") +#pragma comment(linker, "/EXPORT:__heapwalk=msvcrt._heapwalk") +#pragma comment(linker, "/EXPORT:__hypot=msvcrt._hypot") +#pragma comment(linker, "/EXPORT:__i64toa=msvcrt._i64toa") +#pragma comment(linker, "/EXPORT:__i64toa_s=msvcrt._i64toa_s") +#pragma comment(linker, "/EXPORT:__i64tow=msvcrt._i64tow") +#pragma comment(linker, "/EXPORT:__i64tow_s=msvcrt._i64tow_s") +#pragma comment(linker, "/EXPORT:__initterm=msvcrt._initterm") +#pragma comment(linker, "/EXPORT:__initterm_e=msvcrt._initterm_e") +#pragma comment(linker, "/EXPORT:__inp=msvcrt._inp") +#pragma comment(linker, "/EXPORT:__inpd=msvcrt._inpd") +#pragma comment(linker, "/EXPORT:__inpw=msvcrt._inpw") +#pragma comment(linker, "/EXPORT:__invalid_parameter=msvcrt._invalid_parameter") +#pragma comment(linker, "/EXPORT:__iob=msvcrt._iob") +#pragma comment(linker, "/EXPORT:__isalnum_l=msvcrt._isalnum_l") +#pragma comment(linker, "/EXPORT:__isalpha_l=msvcrt._isalpha_l") +#pragma comment(linker, "/EXPORT:__isatty=msvcrt._isatty") +#pragma comment(linker, "/EXPORT:__iscntrl_l=msvcrt._iscntrl_l") +#pragma comment(linker, "/EXPORT:__isctype=msvcrt._isctype") +#pragma comment(linker, "/EXPORT:__isctype_l=msvcrt._isctype_l") +#pragma comment(linker, "/EXPORT:__isdigit_l=msvcrt._isdigit_l") +#pragma comment(linker, "/EXPORT:__isgraph_l=msvcrt._isgraph_l") +#pragma comment(linker, "/EXPORT:__isleadbyte_l=msvcrt._isleadbyte_l") +#pragma comment(linker, "/EXPORT:__islower_l=msvcrt._islower_l") +#pragma comment(linker, "/EXPORT:__ismbbalnum=msvcrt._ismbbalnum") +#pragma comment(linker, "/EXPORT:__ismbbalnum_l=msvcrt._ismbbalnum_l") +#pragma comment(linker, "/EXPORT:__ismbbalpha=msvcrt._ismbbalpha") +#pragma comment(linker, "/EXPORT:__ismbbalpha_l=msvcrt._ismbbalpha_l") +#pragma comment(linker, "/EXPORT:__ismbbgraph=msvcrt._ismbbgraph") +#pragma comment(linker, "/EXPORT:__ismbbgraph_l=msvcrt._ismbbgraph_l") +#pragma comment(linker, "/EXPORT:__ismbbkalnum=msvcrt._ismbbkalnum") +#pragma comment(linker, "/EXPORT:__ismbbkalnum_l=msvcrt._ismbbkalnum_l") +#pragma comment(linker, "/EXPORT:__ismbbkana=msvcrt._ismbbkana") +#pragma comment(linker, "/EXPORT:__ismbbkana_l=msvcrt._ismbbkana_l") +#pragma comment(linker, "/EXPORT:__ismbbkprint=msvcrt._ismbbkprint") +#pragma comment(linker, "/EXPORT:__ismbbkprint_l=msvcrt._ismbbkprint_l") +#pragma comment(linker, "/EXPORT:__ismbbkpunct=msvcrt._ismbbkpunct") +#pragma comment(linker, "/EXPORT:__ismbbkpunct_l=msvcrt._ismbbkpunct_l") +#pragma comment(linker, "/EXPORT:__ismbblead=msvcrt._ismbblead") +#pragma comment(linker, "/EXPORT:__ismbblead_l=msvcrt._ismbblead_l") +#pragma comment(linker, "/EXPORT:__ismbbprint=msvcrt._ismbbprint") +#pragma comment(linker, "/EXPORT:__ismbbprint_l=msvcrt._ismbbprint_l") +#pragma comment(linker, "/EXPORT:__ismbbpunct=msvcrt._ismbbpunct") +#pragma comment(linker, "/EXPORT:__ismbbpunct_l=msvcrt._ismbbpunct_l") +#pragma comment(linker, "/EXPORT:__ismbbtrail=msvcrt._ismbbtrail") +#pragma comment(linker, "/EXPORT:__ismbbtrail_l=msvcrt._ismbbtrail_l") +#pragma comment(linker, "/EXPORT:__ismbcalnum=msvcrt._ismbcalnum") +#pragma comment(linker, "/EXPORT:__ismbcalnum_l=msvcrt._ismbcalnum_l") +#pragma comment(linker, "/EXPORT:__ismbcalpha=msvcrt._ismbcalpha") +#pragma comment(linker, "/EXPORT:__ismbcalpha_l=msvcrt._ismbcalpha_l") +#pragma comment(linker, "/EXPORT:__ismbcdigit=msvcrt._ismbcdigit") +#pragma comment(linker, "/EXPORT:__ismbcdigit_l=msvcrt._ismbcdigit_l") +#pragma comment(linker, "/EXPORT:__ismbcgraph=msvcrt._ismbcgraph") +#pragma comment(linker, "/EXPORT:__ismbcgraph_l=msvcrt._ismbcgraph_l") +#pragma comment(linker, "/EXPORT:__ismbchira=msvcrt._ismbchira") +#pragma comment(linker, "/EXPORT:__ismbchira_l=msvcrt._ismbchira_l") +#pragma comment(linker, "/EXPORT:__ismbckata=msvcrt._ismbckata") +#pragma comment(linker, "/EXPORT:__ismbckata_l=msvcrt._ismbckata_l") +#pragma comment(linker, "/EXPORT:__ismbcl0=msvcrt._ismbcl0") +#pragma comment(linker, "/EXPORT:__ismbcl0_l=msvcrt._ismbcl0_l") +#pragma comment(linker, "/EXPORT:__ismbcl1=msvcrt._ismbcl1") +#pragma comment(linker, "/EXPORT:__ismbcl1_l=msvcrt._ismbcl1_l") +#pragma comment(linker, "/EXPORT:__ismbcl2=msvcrt._ismbcl2") +#pragma comment(linker, "/EXPORT:__ismbcl2_l=msvcrt._ismbcl2_l") +#pragma comment(linker, "/EXPORT:__ismbclegal=msvcrt._ismbclegal") +#pragma comment(linker, "/EXPORT:__ismbclegal_l=msvcrt._ismbclegal_l") +#pragma comment(linker, "/EXPORT:__ismbclower=msvcrt._ismbclower") +#pragma comment(linker, "/EXPORT:__ismbclower_l=msvcrt._ismbclower_l") +#pragma comment(linker, "/EXPORT:__ismbcprint=msvcrt._ismbcprint") +#pragma comment(linker, "/EXPORT:__ismbcprint_l=msvcrt._ismbcprint_l") +#pragma comment(linker, "/EXPORT:__ismbcpunct=msvcrt._ismbcpunct") +#pragma comment(linker, "/EXPORT:__ismbcpunct_l=msvcrt._ismbcpunct_l") +#pragma comment(linker, "/EXPORT:__ismbcspace=msvcrt._ismbcspace") +#pragma comment(linker, "/EXPORT:__ismbcspace_l=msvcrt._ismbcspace_l") +#pragma comment(linker, "/EXPORT:__ismbcsymbol=msvcrt._ismbcsymbol") +#pragma comment(linker, "/EXPORT:__ismbcsymbol_l=msvcrt._ismbcsymbol_l") +#pragma comment(linker, "/EXPORT:__ismbcupper=msvcrt._ismbcupper") +#pragma comment(linker, "/EXPORT:__ismbcupper_l=msvcrt._ismbcupper_l") +#pragma comment(linker, "/EXPORT:__ismbslead=msvcrt._ismbslead") +#pragma comment(linker, "/EXPORT:__ismbslead_l=msvcrt._ismbslead_l") +#pragma comment(linker, "/EXPORT:__ismbstrail=msvcrt._ismbstrail") +#pragma comment(linker, "/EXPORT:__ismbstrail_l=msvcrt._ismbstrail_l") +#pragma comment(linker, "/EXPORT:__isnan=msvcrt._isnan") +#pragma comment(linker, "/EXPORT:__isprint_l=msvcrt._isprint_l") +#pragma comment(linker, "/EXPORT:__isspace_l=msvcrt._isspace_l") +#pragma comment(linker, "/EXPORT:__isupper_l=msvcrt._isupper_l") +#pragma comment(linker, "/EXPORT:__iswalnum_l=msvcrt._iswalnum_l") +#pragma comment(linker, "/EXPORT:__iswalpha_l=msvcrt._iswalpha_l") +#pragma comment(linker, "/EXPORT:__iswcntrl_l=msvcrt._iswcntrl_l") +#pragma comment(linker, "/EXPORT:__iswctype_l=msvcrt._iswctype_l") +#pragma comment(linker, "/EXPORT:__iswdigit_l=msvcrt._iswdigit_l") +#pragma comment(linker, "/EXPORT:__iswgraph_l=msvcrt._iswgraph_l") +#pragma comment(linker, "/EXPORT:__iswlower_l=msvcrt._iswlower_l") +#pragma comment(linker, "/EXPORT:__iswprint_l=msvcrt._iswprint_l") +#pragma comment(linker, "/EXPORT:__iswpunct_l=msvcrt._iswpunct_l") +#pragma comment(linker, "/EXPORT:__iswspace_l=msvcrt._iswspace_l") +#pragma comment(linker, "/EXPORT:__iswupper_l=msvcrt._iswupper_l") +#pragma comment(linker, "/EXPORT:__iswxdigit_l=msvcrt._iswxdigit_l") +#pragma comment(linker, "/EXPORT:__isxdigit_l=msvcrt._isxdigit_l") +#pragma comment(linker, "/EXPORT:__itoa=msvcrt._itoa") +#pragma comment(linker, "/EXPORT:__itoa_s=msvcrt._itoa_s") +#pragma comment(linker, "/EXPORT:__itow=msvcrt._itow") +#pragma comment(linker, "/EXPORT:__itow_s=msvcrt._itow_s") +#pragma comment(linker, "/EXPORT:__j0=msvcrt._j0") +#pragma comment(linker, "/EXPORT:__j1=msvcrt._j1") +#pragma comment(linker, "/EXPORT:__jn=msvcrt._jn") +#pragma comment(linker, "/EXPORT:__kbhit=msvcrt._kbhit") +#pragma comment(linker, "/EXPORT:__lfind=msvcrt._lfind") +#pragma comment(linker, "/EXPORT:__lfind_s=msvcrt._lfind_s") +#pragma comment(linker, "/EXPORT:__loaddll=msvcrt._loaddll") +#pragma comment(linker, "/EXPORT:__local_unwind2=msvcrt._local_unwind2") +#pragma comment(linker, "/EXPORT:__local_unwind4=msvcrt._local_unwind4") +#pragma comment(linker, "/EXPORT:__localtime32=msvcrt._localtime32") +#pragma comment(linker, "/EXPORT:__localtime32_s=msvcrt._localtime32_s") +#pragma comment(linker, "/EXPORT:__localtime64=msvcrt._localtime64") +#pragma comment(linker, "/EXPORT:__localtime64_s=msvcrt._localtime64_s") +#pragma comment(linker, "/EXPORT:__lock=msvcrt._lock") +#pragma comment(linker, "/EXPORT:__locking=msvcrt._locking") +#pragma comment(linker, "/EXPORT:__logb=msvcrt._logb") +#pragma comment(linker, "/EXPORT:__longjmpex=msvcrt._longjmpex") +#pragma comment(linker, "/EXPORT:__lrotl=msvcrt._lrotl") +#pragma comment(linker, "/EXPORT:__lrotr=msvcrt._lrotr") +#pragma comment(linker, "/EXPORT:__lsearch=msvcrt._lsearch") +#pragma comment(linker, "/EXPORT:__lsearch_s=msvcrt._lsearch_s") +#pragma comment(linker, "/EXPORT:__lseek=msvcrt._lseek") +#pragma comment(linker, "/EXPORT:__lseeki64=msvcrt._lseeki64") +#pragma comment(linker, "/EXPORT:__ltoa=msvcrt._ltoa") +#pragma comment(linker, "/EXPORT:__ltoa_s=msvcrt._ltoa_s") +#pragma comment(linker, "/EXPORT:__ltow=msvcrt._ltow") +#pragma comment(linker, "/EXPORT:__ltow_s=msvcrt._ltow_s") +#pragma comment(linker, "/EXPORT:__makepath=msvcrt._makepath") +#pragma comment(linker, "/EXPORT:__makepath_s=msvcrt._makepath_s") +#pragma comment(linker, "/EXPORT:__malloc_dbg=msvcrt._malloc_dbg") +#pragma comment(linker, "/EXPORT:__mbbtombc=msvcrt._mbbtombc") +#pragma comment(linker, "/EXPORT:__mbbtombc_l=msvcrt._mbbtombc_l") +#pragma comment(linker, "/EXPORT:__mbbtype=msvcrt._mbbtype") +#pragma comment(linker, "/EXPORT:__mbcasemap=msvcrt._mbcasemap") +#pragma comment(linker, "/EXPORT:__mbccpy=msvcrt._mbccpy") +#pragma comment(linker, "/EXPORT:__mbccpy_l=msvcrt._mbccpy_l") +#pragma comment(linker, "/EXPORT:__mbccpy_s=msvcrt._mbccpy_s") +#pragma comment(linker, "/EXPORT:__mbccpy_s_l=msvcrt._mbccpy_s_l") +#pragma comment(linker, "/EXPORT:__mbcjistojms=msvcrt._mbcjistojms") +#pragma comment(linker, "/EXPORT:__mbcjistojms_l=msvcrt._mbcjistojms_l") +#pragma comment(linker, "/EXPORT:__mbcjmstojis=msvcrt._mbcjmstojis") +#pragma comment(linker, "/EXPORT:__mbcjmstojis_l=msvcrt._mbcjmstojis_l") +#pragma comment(linker, "/EXPORT:__mbclen=msvcrt._mbclen") +#pragma comment(linker, "/EXPORT:__mbclen_l=msvcrt._mbclen_l") +#pragma comment(linker, "/EXPORT:__mbctohira=msvcrt._mbctohira") +#pragma comment(linker, "/EXPORT:__mbctohira_l=msvcrt._mbctohira_l") +#pragma comment(linker, "/EXPORT:__mbctokata=msvcrt._mbctokata") +#pragma comment(linker, "/EXPORT:__mbctokata_l=msvcrt._mbctokata_l") +#pragma comment(linker, "/EXPORT:__mbctolower=msvcrt._mbctolower") +#pragma comment(linker, "/EXPORT:__mbctolower_l=msvcrt._mbctolower_l") +#pragma comment(linker, "/EXPORT:__mbctombb=msvcrt._mbctombb") +#pragma comment(linker, "/EXPORT:__mbctombb_l=msvcrt._mbctombb_l") +#pragma comment(linker, "/EXPORT:__mbctoupper=msvcrt._mbctoupper") +#pragma comment(linker, "/EXPORT:__mbctoupper_l=msvcrt._mbctoupper_l") +#pragma comment(linker, "/EXPORT:__mbctype=msvcrt._mbctype") +#pragma comment(linker, "/EXPORT:__mblen_l=msvcrt._mblen_l") +#pragma comment(linker, "/EXPORT:__mbsbtype=msvcrt._mbsbtype") +#pragma comment(linker, "/EXPORT:__mbsbtype_l=msvcrt._mbsbtype_l") +#pragma comment(linker, "/EXPORT:__mbscat=msvcrt._mbscat") +#pragma comment(linker, "/EXPORT:__mbscat_s=msvcrt._mbscat_s") +#pragma comment(linker, "/EXPORT:__mbscat_s_l=msvcrt._mbscat_s_l") +#pragma comment(linker, "/EXPORT:__mbschr=msvcrt._mbschr") +#pragma comment(linker, "/EXPORT:__mbschr_l=msvcrt._mbschr_l") +#pragma comment(linker, "/EXPORT:__mbscmp=msvcrt._mbscmp") +#pragma comment(linker, "/EXPORT:__mbscmp_l=msvcrt._mbscmp_l") +#pragma comment(linker, "/EXPORT:__mbscoll=msvcrt._mbscoll") +#pragma comment(linker, "/EXPORT:__mbscoll_l=msvcrt._mbscoll_l") +#pragma comment(linker, "/EXPORT:__mbscpy=msvcrt._mbscpy") +#pragma comment(linker, "/EXPORT:__mbscpy_s=msvcrt._mbscpy_s") +#pragma comment(linker, "/EXPORT:__mbscpy_s_l=msvcrt._mbscpy_s_l") +#pragma comment(linker, "/EXPORT:__mbscspn=msvcrt._mbscspn") +#pragma comment(linker, "/EXPORT:__mbscspn_l=msvcrt._mbscspn_l") +#pragma comment(linker, "/EXPORT:__mbsdec=msvcrt._mbsdec") +#pragma comment(linker, "/EXPORT:__mbsdec_l=msvcrt._mbsdec_l") +#pragma comment(linker, "/EXPORT:__mbsdup=msvcrt._mbsdup") +#pragma comment(linker, "/EXPORT:__mbsicmp=msvcrt._mbsicmp") +#pragma comment(linker, "/EXPORT:__mbsicmp_l=msvcrt._mbsicmp_l") +#pragma comment(linker, "/EXPORT:__mbsicoll=msvcrt._mbsicoll") +#pragma comment(linker, "/EXPORT:__mbsicoll_l=msvcrt._mbsicoll_l") +#pragma comment(linker, "/EXPORT:__mbsinc=msvcrt._mbsinc") +#pragma comment(linker, "/EXPORT:__mbsinc_l=msvcrt._mbsinc_l") +#pragma comment(linker, "/EXPORT:__mbslen=msvcrt._mbslen") +#pragma comment(linker, "/EXPORT:__mbslen_l=msvcrt._mbslen_l") +#pragma comment(linker, "/EXPORT:__mbslwr=msvcrt._mbslwr") +#pragma comment(linker, "/EXPORT:__mbslwr_l=msvcrt._mbslwr_l") +#pragma comment(linker, "/EXPORT:__mbslwr_s=msvcrt._mbslwr_s") +#pragma comment(linker, "/EXPORT:__mbslwr_s_l=msvcrt._mbslwr_s_l") +#pragma comment(linker, "/EXPORT:__mbsnbcat=msvcrt._mbsnbcat") +#pragma comment(linker, "/EXPORT:__mbsnbcat_l=msvcrt._mbsnbcat_l") +#pragma comment(linker, "/EXPORT:__mbsnbcat_s=msvcrt._mbsnbcat_s") +#pragma comment(linker, "/EXPORT:__mbsnbcat_s_l=msvcrt._mbsnbcat_s_l") +#pragma comment(linker, "/EXPORT:__mbsnbcmp=msvcrt._mbsnbcmp") +#pragma comment(linker, "/EXPORT:__mbsnbcmp_l=msvcrt._mbsnbcmp_l") +#pragma comment(linker, "/EXPORT:__mbsnbcnt=msvcrt._mbsnbcnt") +#pragma comment(linker, "/EXPORT:__mbsnbcnt_l=msvcrt._mbsnbcnt_l") +#pragma comment(linker, "/EXPORT:__mbsnbcoll=msvcrt._mbsnbcoll") +#pragma comment(linker, "/EXPORT:__mbsnbcoll_l=msvcrt._mbsnbcoll_l") +#pragma comment(linker, "/EXPORT:__mbsnbcpy=msvcrt._mbsnbcpy") +#pragma comment(linker, "/EXPORT:__mbsnbcpy_l=msvcrt._mbsnbcpy_l") +#pragma comment(linker, "/EXPORT:__mbsnbcpy_s=msvcrt._mbsnbcpy_s") +#pragma comment(linker, "/EXPORT:__mbsnbcpy_s_l=msvcrt._mbsnbcpy_s_l") +#pragma comment(linker, "/EXPORT:__mbsnbicmp=msvcrt._mbsnbicmp") +#pragma comment(linker, "/EXPORT:__mbsnbicmp_l=msvcrt._mbsnbicmp_l") +#pragma comment(linker, "/EXPORT:__mbsnbicoll=msvcrt._mbsnbicoll") +#pragma comment(linker, "/EXPORT:__mbsnbicoll_l=msvcrt._mbsnbicoll_l") +#pragma comment(linker, "/EXPORT:__mbsnbset=msvcrt._mbsnbset") +#pragma comment(linker, "/EXPORT:__mbsnbset_l=msvcrt._mbsnbset_l") +#pragma comment(linker, "/EXPORT:__mbsnbset_s=msvcrt._mbsnbset_s") +#pragma comment(linker, "/EXPORT:__mbsnbset_s_l=msvcrt._mbsnbset_s_l") +#pragma comment(linker, "/EXPORT:__mbsncat=msvcrt._mbsncat") +#pragma comment(linker, "/EXPORT:__mbsncat_l=msvcrt._mbsncat_l") +#pragma comment(linker, "/EXPORT:__mbsncat_s=msvcrt._mbsncat_s") +#pragma comment(linker, "/EXPORT:__mbsncat_s_l=msvcrt._mbsncat_s_l") +#pragma comment(linker, "/EXPORT:__mbsnccnt=msvcrt._mbsnccnt") +#pragma comment(linker, "/EXPORT:__mbsnccnt_l=msvcrt._mbsnccnt_l") +#pragma comment(linker, "/EXPORT:__mbsncmp=msvcrt._mbsncmp") +#pragma comment(linker, "/EXPORT:__mbsncmp_l=msvcrt._mbsncmp_l") +#pragma comment(linker, "/EXPORT:__mbsncoll=msvcrt._mbsncoll") +#pragma comment(linker, "/EXPORT:__mbsncoll_l=msvcrt._mbsncoll_l") +#pragma comment(linker, "/EXPORT:__mbsncpy=msvcrt._mbsncpy") +#pragma comment(linker, "/EXPORT:__mbsncpy_l=msvcrt._mbsncpy_l") +#pragma comment(linker, "/EXPORT:__mbsncpy_s=msvcrt._mbsncpy_s") +#pragma comment(linker, "/EXPORT:__mbsncpy_s_l=msvcrt._mbsncpy_s_l") +#pragma comment(linker, "/EXPORT:__mbsnextc=msvcrt._mbsnextc") +#pragma comment(linker, "/EXPORT:__mbsnextc_l=msvcrt._mbsnextc_l") +#pragma comment(linker, "/EXPORT:__mbsnicmp=msvcrt._mbsnicmp") +#pragma comment(linker, "/EXPORT:__mbsnicmp_l=msvcrt._mbsnicmp_l") +#pragma comment(linker, "/EXPORT:__mbsnicoll=msvcrt._mbsnicoll") +#pragma comment(linker, "/EXPORT:__mbsnicoll_l=msvcrt._mbsnicoll_l") +#pragma comment(linker, "/EXPORT:__mbsninc=msvcrt._mbsninc") +#pragma comment(linker, "/EXPORT:__mbsninc_l=msvcrt._mbsninc_l") +#pragma comment(linker, "/EXPORT:__mbsnlen=msvcrt._mbsnlen") +#pragma comment(linker, "/EXPORT:__mbsnlen_l=msvcrt._mbsnlen_l") +#pragma comment(linker, "/EXPORT:__mbsnset=msvcrt._mbsnset") +#pragma comment(linker, "/EXPORT:__mbsnset_l=msvcrt._mbsnset_l") +#pragma comment(linker, "/EXPORT:__mbsnset_s=msvcrt._mbsnset_s") +#pragma comment(linker, "/EXPORT:__mbsnset_s_l=msvcrt._mbsnset_s_l") +#pragma comment(linker, "/EXPORT:__mbspbrk=msvcrt._mbspbrk") +#pragma comment(linker, "/EXPORT:__mbspbrk_l=msvcrt._mbspbrk_l") +#pragma comment(linker, "/EXPORT:__mbsrchr=msvcrt._mbsrchr") +#pragma comment(linker, "/EXPORT:__mbsrchr_l=msvcrt._mbsrchr_l") +#pragma comment(linker, "/EXPORT:__mbsrev=msvcrt._mbsrev") +#pragma comment(linker, "/EXPORT:__mbsrev_l=msvcrt._mbsrev_l") +#pragma comment(linker, "/EXPORT:__mbsset=msvcrt._mbsset") +#pragma comment(linker, "/EXPORT:__mbsset_l=msvcrt._mbsset_l") +#pragma comment(linker, "/EXPORT:__mbsset_s=msvcrt._mbsset_s") +#pragma comment(linker, "/EXPORT:__mbsset_s_l=msvcrt._mbsset_s_l") +#pragma comment(linker, "/EXPORT:__mbsspn=msvcrt._mbsspn") +#pragma comment(linker, "/EXPORT:__mbsspn_l=msvcrt._mbsspn_l") +#pragma comment(linker, "/EXPORT:__mbsspnp=msvcrt._mbsspnp") +#pragma comment(linker, "/EXPORT:__mbsspnp_l=msvcrt._mbsspnp_l") +#pragma comment(linker, "/EXPORT:__mbsstr=msvcrt._mbsstr") +#pragma comment(linker, "/EXPORT:__mbsstr_l=msvcrt._mbsstr_l") +#pragma comment(linker, "/EXPORT:__mbstok=msvcrt._mbstok") +#pragma comment(linker, "/EXPORT:__mbstok_l=msvcrt._mbstok_l") +#pragma comment(linker, "/EXPORT:__mbstok_s=msvcrt._mbstok_s") +#pragma comment(linker, "/EXPORT:__mbstok_s_l=msvcrt._mbstok_s_l") +#pragma comment(linker, "/EXPORT:__mbstowcs_l=msvcrt._mbstowcs_l") +#pragma comment(linker, "/EXPORT:__mbstowcs_s_l=msvcrt._mbstowcs_s_l") +#pragma comment(linker, "/EXPORT:__mbstrlen=msvcrt._mbstrlen") +#pragma comment(linker, "/EXPORT:__mbstrlen_l=msvcrt._mbstrlen_l") +#pragma comment(linker, "/EXPORT:__mbstrnlen=msvcrt._mbstrnlen") +#pragma comment(linker, "/EXPORT:__mbstrnlen_l=msvcrt._mbstrnlen_l") +#pragma comment(linker, "/EXPORT:__mbsupr=msvcrt._mbsupr") +#pragma comment(linker, "/EXPORT:__mbsupr_l=msvcrt._mbsupr_l") +#pragma comment(linker, "/EXPORT:__mbsupr_s=msvcrt._mbsupr_s") +#pragma comment(linker, "/EXPORT:__mbsupr_s_l=msvcrt._mbsupr_s_l") +#pragma comment(linker, "/EXPORT:__mbtowc_l=msvcrt._mbtowc_l") +#pragma comment(linker, "/EXPORT:__memccpy=msvcrt._memccpy") +#pragma comment(linker, "/EXPORT:__memicmp=msvcrt._memicmp") +#pragma comment(linker, "/EXPORT:__memicmp_l=msvcrt._memicmp_l") +#pragma comment(linker, "/EXPORT:__mkdir=msvcrt._mkdir") +#pragma comment(linker, "/EXPORT:__mkgmtime=msvcrt._mkgmtime") +#pragma comment(linker, "/EXPORT:__mkgmtime32=msvcrt._mkgmtime32") +#pragma comment(linker, "/EXPORT:__mkgmtime64=msvcrt._mkgmtime64") +#pragma comment(linker, "/EXPORT:__mktemp=msvcrt._mktemp") +#pragma comment(linker, "/EXPORT:__mktemp_s=msvcrt._mktemp_s") +#pragma comment(linker, "/EXPORT:__mktime32=msvcrt._mktime32") +#pragma comment(linker, "/EXPORT:__mktime64=msvcrt._mktime64") +#pragma comment(linker, "/EXPORT:__msize=msvcrt._msize") +#pragma comment(linker, "/EXPORT:__msize_debug=msvcrt._msize_debug") +#pragma comment(linker, "/EXPORT:__nextafter=msvcrt._nextafter") +#pragma comment(linker, "/EXPORT:__onexit=msvcrt._onexit") +#pragma comment(linker, "/EXPORT:__open=msvcrt._open") +#pragma comment(linker, "/EXPORT:__open_osfhandle=msvcrt._open_osfhandle") +#pragma comment(linker, "/EXPORT:__osplatform=msvcrt._osplatform") +#pragma comment(linker, "/EXPORT:__osver=msvcrt._osver") +#pragma comment(linker, "/EXPORT:__outp=msvcrt._outp") +#pragma comment(linker, "/EXPORT:__outpd=msvcrt._outpd") +#pragma comment(linker, "/EXPORT:__outpw=msvcrt._outpw") +#pragma comment(linker, "/EXPORT:__pclose=msvcrt._pclose") +#pragma comment(linker, "/EXPORT:__pctype=msvcrt._pctype") +#pragma comment(linker, "/EXPORT:__pgmptr=msvcrt._pgmptr") +#pragma comment(linker, "/EXPORT:__pipe=msvcrt._pipe") +#pragma comment(linker, "/EXPORT:__popen=msvcrt._popen") +#pragma comment(linker, "/EXPORT:__printf_l=msvcrt._printf_l") +#pragma comment(linker, "/EXPORT:__printf_p=msvcrt._printf_p") +#pragma comment(linker, "/EXPORT:__printf_p_l=msvcrt._printf_p_l") +#pragma comment(linker, "/EXPORT:__printf_s_l=msvcrt._printf_s_l") +#pragma comment(linker, "/EXPORT:__purecall=msvcrt._purecall") +#pragma comment(linker, "/EXPORT:__putch=msvcrt._putch") +#pragma comment(linker, "/EXPORT:__putenv=msvcrt._putenv") +#pragma comment(linker, "/EXPORT:__putenv_s=msvcrt._putenv_s") +#pragma comment(linker, "/EXPORT:__putw=msvcrt._putw") +#pragma comment(linker, "/EXPORT:__putwch=msvcrt._putwch") +#pragma comment(linker, "/EXPORT:__putws=msvcrt._putws") +#pragma comment(linker, "/EXPORT:__pwctype=msvcrt._pwctype") +#pragma comment(linker, "/EXPORT:__read=msvcrt._read") +#pragma comment(linker, "/EXPORT:__realloc_dbg=msvcrt._realloc_dbg") +#pragma comment(linker, "/EXPORT:__resetstkoflw=msvcrt._resetstkoflw") +#pragma comment(linker, "/EXPORT:__rmdir=msvcrt._rmdir") +#pragma comment(linker, "/EXPORT:__rmtmp=msvcrt._rmtmp") +#pragma comment(linker, "/EXPORT:__rotl=msvcrt._rotl") +#pragma comment(linker, "/EXPORT:__rotl64=msvcrt._rotl64") +#pragma comment(linker, "/EXPORT:__rotr=msvcrt._rotr") +#pragma comment(linker, "/EXPORT:__rotr64=msvcrt._rotr64") +#pragma comment(linker, "/EXPORT:__safe_fdiv=msvcrt._safe_fdiv") +#pragma comment(linker, "/EXPORT:__safe_fdivr=msvcrt._safe_fdivr") +#pragma comment(linker, "/EXPORT:__safe_fprem=msvcrt._safe_fprem") +#pragma comment(linker, "/EXPORT:__safe_fprem1=msvcrt._safe_fprem1") +#pragma comment(linker, "/EXPORT:__scalb=msvcrt._scalb") +#pragma comment(linker, "/EXPORT:__scanf_l=msvcrt._scanf_l") +#pragma comment(linker, "/EXPORT:__scanf_s_l=msvcrt._scanf_s_l") +#pragma comment(linker, "/EXPORT:__scprintf=msvcrt._scprintf") +#pragma comment(linker, "/EXPORT:__scprintf_l=msvcrt._scprintf_l") +#pragma comment(linker, "/EXPORT:__scprintf_p_l=msvcrt._scprintf_p_l") +#pragma comment(linker, "/EXPORT:__scwprintf=msvcrt._scwprintf") +#pragma comment(linker, "/EXPORT:__scwprintf_l=msvcrt._scwprintf_l") +#pragma comment(linker, "/EXPORT:__scwprintf_p_l=msvcrt._scwprintf_p_l") +#pragma comment(linker, "/EXPORT:__searchenv=msvcrt._searchenv") +#pragma comment(linker, "/EXPORT:__searchenv_s=msvcrt._searchenv_s") +#pragma comment(linker, "/EXPORT:__seh_longjmp_unwind=msvcrt._seh_longjmp_unwind") +#pragma comment(linker, "/EXPORT:__seh_longjmp_unwind4=msvcrt._seh_longjmp_unwind4") +#pragma comment(linker, "/EXPORT:__set_SSE2_enable=msvcrt._set_SSE2_enable") +#pragma comment(linker, "/EXPORT:__set_controlfp=msvcrt._set_controlfp") +#pragma comment(linker, "/EXPORT:__set_doserrno=msvcrt._set_doserrno") +#pragma comment(linker, "/EXPORT:__set_errno=msvcrt._set_errno") +#pragma comment(linker, "/EXPORT:__set_error_mode=msvcrt._set_error_mode") +#pragma comment(linker, "/EXPORT:__set_fileinfo=msvcrt._set_fileinfo") +#pragma comment(linker, "/EXPORT:__set_fmode=msvcrt._set_fmode") +#pragma comment(linker, "/EXPORT:__set_output_format=msvcrt._set_output_format") +#pragma comment(linker, "/EXPORT:__set_sbh_threshold=msvcrt._set_sbh_threshold") +#pragma comment(linker, "/EXPORT:__seterrormode=msvcrt._seterrormode") +#pragma comment(linker, "/EXPORT:__setjmp=msvcrt._setjmp") +#pragma comment(linker, "/EXPORT:__setjmp3=msvcrt._setjmp3") +#pragma comment(linker, "/EXPORT:__setmaxstdio=msvcrt._setmaxstdio") +#pragma comment(linker, "/EXPORT:__setmbcp=msvcrt._setmbcp") +#pragma comment(linker, "/EXPORT:__setmode=msvcrt._setmode") +#pragma comment(linker, "/EXPORT:__setsystime=msvcrt._setsystime") +#pragma comment(linker, "/EXPORT:__sleep=msvcrt._sleep") +#pragma comment(linker, "/EXPORT:__snprintf=msvcrt._snprintf") +#pragma comment(linker, "/EXPORT:__snprintf_c=msvcrt._snprintf_c") +#pragma comment(linker, "/EXPORT:__snprintf_c_l=msvcrt._snprintf_c_l") +#pragma comment(linker, "/EXPORT:__snprintf_l=msvcrt._snprintf_l") +#pragma comment(linker, "/EXPORT:__snprintf_s=msvcrt._snprintf_s") +#pragma comment(linker, "/EXPORT:__snprintf_s_l=msvcrt._snprintf_s_l") +#pragma comment(linker, "/EXPORT:__snscanf=msvcrt._snscanf") +#pragma comment(linker, "/EXPORT:__snscanf_l=msvcrt._snscanf_l") +#pragma comment(linker, "/EXPORT:__snscanf_s=msvcrt._snscanf_s") +#pragma comment(linker, "/EXPORT:__snscanf_s_l=msvcrt._snscanf_s_l") +#pragma comment(linker, "/EXPORT:__snwprintf=msvcrt._snwprintf") +#pragma comment(linker, "/EXPORT:__snwprintf_l=msvcrt._snwprintf_l") +#pragma comment(linker, "/EXPORT:__snwprintf_s=msvcrt._snwprintf_s") +#pragma comment(linker, "/EXPORT:__snwprintf_s_l=msvcrt._snwprintf_s_l") +#pragma comment(linker, "/EXPORT:__snwscanf=msvcrt._snwscanf") +#pragma comment(linker, "/EXPORT:__snwscanf_l=msvcrt._snwscanf_l") +#pragma comment(linker, "/EXPORT:__snwscanf_s=msvcrt._snwscanf_s") +#pragma comment(linker, "/EXPORT:__snwscanf_s_l=msvcrt._snwscanf_s_l") +#pragma comment(linker, "/EXPORT:__sopen=msvcrt._sopen") +#pragma comment(linker, "/EXPORT:__sopen_s=msvcrt._sopen_s") +#pragma comment(linker, "/EXPORT:__spawnl=msvcrt._spawnl") +#pragma comment(linker, "/EXPORT:__spawnle=msvcrt._spawnle") +#pragma comment(linker, "/EXPORT:__spawnlp=msvcrt._spawnlp") +#pragma comment(linker, "/EXPORT:__spawnlpe=msvcrt._spawnlpe") +#pragma comment(linker, "/EXPORT:__spawnv=msvcrt._spawnv") +#pragma comment(linker, "/EXPORT:__spawnve=msvcrt._spawnve") +#pragma comment(linker, "/EXPORT:__spawnvp=msvcrt._spawnvp") +#pragma comment(linker, "/EXPORT:__spawnvpe=msvcrt._spawnvpe") +#pragma comment(linker, "/EXPORT:__splitpath=msvcrt._splitpath") +#pragma comment(linker, "/EXPORT:__splitpath_s=msvcrt._splitpath_s") +#pragma comment(linker, "/EXPORT:__sprintf_l=msvcrt._sprintf_l") +#pragma comment(linker, "/EXPORT:__sprintf_p_l=msvcrt._sprintf_p_l") +#pragma comment(linker, "/EXPORT:__sprintf_s_l=msvcrt._sprintf_s_l") +#pragma comment(linker, "/EXPORT:__sscanf_l=msvcrt._sscanf_l") +#pragma comment(linker, "/EXPORT:__sscanf_s_l=msvcrt._sscanf_s_l") +#pragma comment(linker, "/EXPORT:__stat=msvcrt._stat") +#pragma comment(linker, "/EXPORT:__stat64=msvcrt._stat64") +#pragma comment(linker, "/EXPORT:__stati64=msvcrt._stati64") +#pragma comment(linker, "/EXPORT:__statusfp=msvcrt._statusfp") +#pragma comment(linker, "/EXPORT:__strcmpi=msvcrt._strcmpi") +#pragma comment(linker, "/EXPORT:__strcoll_l=msvcrt._strcoll_l") +#pragma comment(linker, "/EXPORT:__strdate=msvcrt._strdate") +#pragma comment(linker, "/EXPORT:__strdate_s=msvcrt._strdate_s") +#pragma comment(linker, "/EXPORT:__strdup=msvcrt._strdup") +#pragma comment(linker, "/EXPORT:__strdup_dbg=msvcrt._strdup_dbg") +#pragma comment(linker, "/EXPORT:__strerror=msvcrt._strerror") +#pragma comment(linker, "/EXPORT:__strerror_s=msvcrt._strerror_s") +#pragma comment(linker, "/EXPORT:__stricmp=msvcrt._stricmp") +#pragma comment(linker, "/EXPORT:__stricmp_l=msvcrt._stricmp_l") +#pragma comment(linker, "/EXPORT:__stricoll=msvcrt._stricoll") +#pragma comment(linker, "/EXPORT:__stricoll_l=msvcrt._stricoll_l") +#pragma comment(linker, "/EXPORT:__strlwr=msvcrt._strlwr") +#pragma comment(linker, "/EXPORT:__strlwr_l=msvcrt._strlwr_l") +#pragma comment(linker, "/EXPORT:__strlwr_s=msvcrt._strlwr_s") +#pragma comment(linker, "/EXPORT:__strlwr_s_l=msvcrt._strlwr_s_l") +#pragma comment(linker, "/EXPORT:__strncoll=msvcrt._strncoll") +#pragma comment(linker, "/EXPORT:__strncoll_l=msvcrt._strncoll_l") +#pragma comment(linker, "/EXPORT:__strnicmp=msvcrt._strnicmp") +#pragma comment(linker, "/EXPORT:__strnicmp_l=msvcrt._strnicmp_l") +#pragma comment(linker, "/EXPORT:__strnicoll=msvcrt._strnicoll") +#pragma comment(linker, "/EXPORT:__strnicoll_l=msvcrt._strnicoll_l") +#pragma comment(linker, "/EXPORT:__strnset=msvcrt._strnset") +#pragma comment(linker, "/EXPORT:__strnset_s=msvcrt._strnset_s") +#pragma comment(linker, "/EXPORT:__strrev=msvcrt._strrev") +#pragma comment(linker, "/EXPORT:__strset=msvcrt._strset") +#pragma comment(linker, "/EXPORT:__strset_s=msvcrt._strset_s") +#pragma comment(linker, "/EXPORT:__strtime=msvcrt._strtime") +#pragma comment(linker, "/EXPORT:__strtime_s=msvcrt._strtime_s") +#pragma comment(linker, "/EXPORT:__strtod_l=msvcrt._strtod_l") +#pragma comment(linker, "/EXPORT:__strtoi64=msvcrt._strtoi64") +#pragma comment(linker, "/EXPORT:__strtoi64_l=msvcrt._strtoi64_l") +#pragma comment(linker, "/EXPORT:__strtol_l=msvcrt._strtol_l") +#pragma comment(linker, "/EXPORT:__strtoui64=msvcrt._strtoui64") +#pragma comment(linker, "/EXPORT:__strtoui64_l=msvcrt._strtoui64_l") +#pragma comment(linker, "/EXPORT:__strtoul_l=msvcrt._strtoul_l") +#pragma comment(linker, "/EXPORT:__strupr=msvcrt._strupr") +#pragma comment(linker, "/EXPORT:__strupr_l=msvcrt._strupr_l") +#pragma comment(linker, "/EXPORT:__strupr_s=msvcrt._strupr_s") +#pragma comment(linker, "/EXPORT:__strupr_s_l=msvcrt._strupr_s_l") +#pragma comment(linker, "/EXPORT:__strxfrm_l=msvcrt._strxfrm_l") +#pragma comment(linker, "/EXPORT:__swab=msvcrt._swab") +#pragma comment(linker, "/EXPORT:__swprintf=msvcrt._swprintf") +#pragma comment(linker, "/EXPORT:__swprintf_c=msvcrt._swprintf_c") +#pragma comment(linker, "/EXPORT:__swprintf_c_l=msvcrt._swprintf_c_l") +#pragma comment(linker, "/EXPORT:__swprintf_p_l=msvcrt._swprintf_p_l") +#pragma comment(linker, "/EXPORT:__swprintf_s_l=msvcrt._swprintf_s_l") +#pragma comment(linker, "/EXPORT:__swscanf_l=msvcrt._swscanf_l") +#pragma comment(linker, "/EXPORT:__swscanf_s_l=msvcrt._swscanf_s_l") +#pragma comment(linker, "/EXPORT:__sys_errlist=msvcrt._sys_errlist") +#pragma comment(linker, "/EXPORT:__sys_nerr=msvcrt._sys_nerr") +#pragma comment(linker, "/EXPORT:__tell=msvcrt._tell") +#pragma comment(linker, "/EXPORT:__telli64=msvcrt._telli64") +#pragma comment(linker, "/EXPORT:__tempnam=msvcrt._tempnam") +#pragma comment(linker, "/EXPORT:__tempnam_dbg=msvcrt._tempnam_dbg") +#pragma comment(linker, "/EXPORT:__time32=msvcrt._time32") +#pragma comment(linker, "/EXPORT:__time64=msvcrt._time64") +#pragma comment(linker, "/EXPORT:__timezone=msvcrt._timezone") +#pragma comment(linker, "/EXPORT:__tolower=msvcrt._tolower") +#pragma comment(linker, "/EXPORT:__tolower_l=msvcrt._tolower_l") +#pragma comment(linker, "/EXPORT:__toupper=msvcrt._toupper") +#pragma comment(linker, "/EXPORT:__toupper_l=msvcrt._toupper_l") +#pragma comment(linker, "/EXPORT:__towlower_l=msvcrt._towlower_l") +#pragma comment(linker, "/EXPORT:__towupper_l=msvcrt._towupper_l") +#pragma comment(linker, "/EXPORT:__tzname=msvcrt._tzname") +#pragma comment(linker, "/EXPORT:__tzset=msvcrt._tzset") +#pragma comment(linker, "/EXPORT:__ui64toa=msvcrt._ui64toa") +#pragma comment(linker, "/EXPORT:__ui64toa_s=msvcrt._ui64toa_s") +#pragma comment(linker, "/EXPORT:__ui64tow=msvcrt._ui64tow") +#pragma comment(linker, "/EXPORT:__ui64tow_s=msvcrt._ui64tow_s") +#pragma comment(linker, "/EXPORT:__ultoa=msvcrt._ultoa") +#pragma comment(linker, "/EXPORT:__ultoa_s=msvcrt._ultoa_s") +#pragma comment(linker, "/EXPORT:__ultow=msvcrt._ultow") +#pragma comment(linker, "/EXPORT:__ultow_s=msvcrt._ultow_s") +#pragma comment(linker, "/EXPORT:__umask=msvcrt._umask") +#pragma comment(linker, "/EXPORT:__umask_s=msvcrt._umask_s") +#pragma comment(linker, "/EXPORT:__ungetch=msvcrt._ungetch") +#pragma comment(linker, "/EXPORT:__ungetwch=msvcrt._ungetwch") +#pragma comment(linker, "/EXPORT:__unlink=msvcrt._unlink") +#pragma comment(linker, "/EXPORT:__unloaddll=msvcrt._unloaddll") +#pragma comment(linker, "/EXPORT:__unlock=msvcrt._unlock") +#pragma comment(linker, "/EXPORT:__utime=msvcrt._utime") +#pragma comment(linker, "/EXPORT:__utime32=msvcrt._utime32") +#pragma comment(linker, "/EXPORT:__utime64=msvcrt._utime64") +#pragma comment(linker, "/EXPORT:__vcprintf=msvcrt._vcprintf") +#pragma comment(linker, "/EXPORT:__vcprintf_l=msvcrt._vcprintf_l") +#pragma comment(linker, "/EXPORT:__vcprintf_p=msvcrt._vcprintf_p") +#pragma comment(linker, "/EXPORT:__vcprintf_p_l=msvcrt._vcprintf_p_l") +#pragma comment(linker, "/EXPORT:__vcprintf_s=msvcrt._vcprintf_s") +#pragma comment(linker, "/EXPORT:__vcprintf_s_l=msvcrt._vcprintf_s_l") +#pragma comment(linker, "/EXPORT:__vcwprintf=msvcrt._vcwprintf") +#pragma comment(linker, "/EXPORT:__vcwprintf_l=msvcrt._vcwprintf_l") +#pragma comment(linker, "/EXPORT:__vcwprintf_p=msvcrt._vcwprintf_p") +#pragma comment(linker, "/EXPORT:__vcwprintf_p_l=msvcrt._vcwprintf_p_l") +#pragma comment(linker, "/EXPORT:__vcwprintf_s=msvcrt._vcwprintf_s") +#pragma comment(linker, "/EXPORT:__vcwprintf_s_l=msvcrt._vcwprintf_s_l") +#pragma comment(linker, "/EXPORT:__vfprintf_l=msvcrt._vfprintf_l") +#pragma comment(linker, "/EXPORT:__vfprintf_p=msvcrt._vfprintf_p") +#pragma comment(linker, "/EXPORT:__vfprintf_p_l=msvcrt._vfprintf_p_l") +#pragma comment(linker, "/EXPORT:__vfprintf_s_l=msvcrt._vfprintf_s_l") +#pragma comment(linker, "/EXPORT:__vfwprintf_l=msvcrt._vfwprintf_l") +#pragma comment(linker, "/EXPORT:__vfwprintf_p=msvcrt._vfwprintf_p") +#pragma comment(linker, "/EXPORT:__vfwprintf_p_l=msvcrt._vfwprintf_p_l") +#pragma comment(linker, "/EXPORT:__vfwprintf_s_l=msvcrt._vfwprintf_s_l") +#pragma comment(linker, "/EXPORT:__vprintf_l=msvcrt._vprintf_l") +#pragma comment(linker, "/EXPORT:__vprintf_p=msvcrt._vprintf_p") +#pragma comment(linker, "/EXPORT:__vprintf_p_l=msvcrt._vprintf_p_l") +#pragma comment(linker, "/EXPORT:__vprintf_s_l=msvcrt._vprintf_s_l") +#pragma comment(linker, "/EXPORT:__vscprintf=msvcrt._vscprintf") +#pragma comment(linker, "/EXPORT:__vscprintf_l=msvcrt._vscprintf_l") +#pragma comment(linker, "/EXPORT:__vscprintf_p_l=msvcrt._vscprintf_p_l") +#pragma comment(linker, "/EXPORT:__vscwprintf=msvcrt._vscwprintf") +#pragma comment(linker, "/EXPORT:__vscwprintf_l=msvcrt._vscwprintf_l") +#pragma comment(linker, "/EXPORT:__vscwprintf_p_l=msvcrt._vscwprintf_p_l") +#pragma comment(linker, "/EXPORT:__vsnprintf=msvcrt._vsnprintf") +#pragma comment(linker, "/EXPORT:__vsnprintf_c=msvcrt._vsnprintf_c") +#pragma comment(linker, "/EXPORT:__vsnprintf_c_l=msvcrt._vsnprintf_c_l") +#pragma comment(linker, "/EXPORT:__vsnprintf_l=msvcrt._vsnprintf_l") +#pragma comment(linker, "/EXPORT:__vsnprintf_s=msvcrt._vsnprintf_s") +#pragma comment(linker, "/EXPORT:__vsnprintf_s_l=msvcrt._vsnprintf_s_l") +#pragma comment(linker, "/EXPORT:__vsnwprintf=msvcrt._vsnwprintf") +#pragma comment(linker, "/EXPORT:__vsnwprintf_l=msvcrt._vsnwprintf_l") +#pragma comment(linker, "/EXPORT:__vsnwprintf_s=msvcrt._vsnwprintf_s") +#pragma comment(linker, "/EXPORT:__vsnwprintf_s_l=msvcrt._vsnwprintf_s_l") +#pragma comment(linker, "/EXPORT:__vsprintf_l=msvcrt._vsprintf_l") +#pragma comment(linker, "/EXPORT:__vsprintf_p=msvcrt._vsprintf_p") +#pragma comment(linker, "/EXPORT:__vsprintf_p_l=msvcrt._vsprintf_p_l") +#pragma comment(linker, "/EXPORT:__vsprintf_s_l=msvcrt._vsprintf_s_l") +#pragma comment(linker, "/EXPORT:__vswprintf=msvcrt._vswprintf") +#pragma comment(linker, "/EXPORT:__vswprintf_c=msvcrt._vswprintf_c") +#pragma comment(linker, "/EXPORT:__vswprintf_c_l=msvcrt._vswprintf_c_l") +#pragma comment(linker, "/EXPORT:__vswprintf_l=msvcrt._vswprintf_l") +#pragma comment(linker, "/EXPORT:__vswprintf_p_l=msvcrt._vswprintf_p_l") +#pragma comment(linker, "/EXPORT:__vswprintf_s_l=msvcrt._vswprintf_s_l") +#pragma comment(linker, "/EXPORT:__vwprintf_l=msvcrt._vwprintf_l") +#pragma comment(linker, "/EXPORT:__vwprintf_p=msvcrt._vwprintf_p") +#pragma comment(linker, "/EXPORT:__vwprintf_p_l=msvcrt._vwprintf_p_l") +#pragma comment(linker, "/EXPORT:__vwprintf_s_l=msvcrt._vwprintf_s_l") +#pragma comment(linker, "/EXPORT:__waccess=msvcrt._waccess") +#pragma comment(linker, "/EXPORT:__waccess_s=msvcrt._waccess_s") +#pragma comment(linker, "/EXPORT:__wasctime=msvcrt._wasctime") +#pragma comment(linker, "/EXPORT:__wasctime_s=msvcrt._wasctime_s") +#pragma comment(linker, "/EXPORT:__wassert=msvcrt._wassert") +#pragma comment(linker, "/EXPORT:__wchdir=msvcrt._wchdir") +#pragma comment(linker, "/EXPORT:__wchmod=msvcrt._wchmod") +#pragma comment(linker, "/EXPORT:__wcmdln=msvcrt._wcmdln") +#pragma comment(linker, "/EXPORT:__wcreat=msvcrt._wcreat") +#pragma comment(linker, "/EXPORT:__wcscoll_l=msvcrt._wcscoll_l") +#pragma comment(linker, "/EXPORT:__wcsdup=msvcrt._wcsdup") +#pragma comment(linker, "/EXPORT:__wcsdup_dbg=msvcrt._wcsdup_dbg") +#pragma comment(linker, "/EXPORT:__wcserror=msvcrt._wcserror") +#pragma comment(linker, "/EXPORT:__wcserror_s=msvcrt._wcserror_s") +#pragma comment(linker, "/EXPORT:__wcsftime_l=msvcrt._wcsftime_l") +#pragma comment(linker, "/EXPORT:__wcsicmp=msvcrt._wcsicmp") +#pragma comment(linker, "/EXPORT:__wcsicmp_l=msvcrt._wcsicmp_l") +#pragma comment(linker, "/EXPORT:__wcsicoll=msvcrt._wcsicoll") +#pragma comment(linker, "/EXPORT:__wcsicoll_l=msvcrt._wcsicoll_l") +#pragma comment(linker, "/EXPORT:__wcslwr=msvcrt._wcslwr") +#pragma comment(linker, "/EXPORT:__wcslwr_l=msvcrt._wcslwr_l") +#pragma comment(linker, "/EXPORT:__wcslwr_s=msvcrt._wcslwr_s") +#pragma comment(linker, "/EXPORT:__wcslwr_s_l=msvcrt._wcslwr_s_l") +#pragma comment(linker, "/EXPORT:__wcsncoll=msvcrt._wcsncoll") +#pragma comment(linker, "/EXPORT:__wcsncoll_l=msvcrt._wcsncoll_l") +#pragma comment(linker, "/EXPORT:__wcsnicmp=msvcrt._wcsnicmp") +#pragma comment(linker, "/EXPORT:__wcsnicmp_l=msvcrt._wcsnicmp_l") +#pragma comment(linker, "/EXPORT:__wcsnicoll=msvcrt._wcsnicoll") +#pragma comment(linker, "/EXPORT:__wcsnicoll_l=msvcrt._wcsnicoll_l") +#pragma comment(linker, "/EXPORT:__wcsnset=msvcrt._wcsnset") +#pragma comment(linker, "/EXPORT:__wcsnset_s=msvcrt._wcsnset_s") +#pragma comment(linker, "/EXPORT:__wcsrev=msvcrt._wcsrev") +#pragma comment(linker, "/EXPORT:__wcsset=msvcrt._wcsset") +#pragma comment(linker, "/EXPORT:__wcsset_s=msvcrt._wcsset_s") +#pragma comment(linker, "/EXPORT:__wcstoi64=msvcrt._wcstoi64") +#pragma comment(linker, "/EXPORT:__wcstoi64_l=msvcrt._wcstoi64_l") +#pragma comment(linker, "/EXPORT:__wcstol_l=msvcrt._wcstol_l") +#pragma comment(linker, "/EXPORT:__wcstombs_l=msvcrt._wcstombs_l") +#pragma comment(linker, "/EXPORT:__wcstombs_s_l=msvcrt._wcstombs_s_l") +#pragma comment(linker, "/EXPORT:__wcstoui64=msvcrt._wcstoui64") +#pragma comment(linker, "/EXPORT:__wcstoui64_l=msvcrt._wcstoui64_l") +#pragma comment(linker, "/EXPORT:__wcstoul_l=msvcrt._wcstoul_l") +#pragma comment(linker, "/EXPORT:__wcsupr=msvcrt._wcsupr") +#pragma comment(linker, "/EXPORT:__wcsupr_l=msvcrt._wcsupr_l") +#pragma comment(linker, "/EXPORT:__wcsupr_s=msvcrt._wcsupr_s") +#pragma comment(linker, "/EXPORT:__wcsupr_s_l=msvcrt._wcsupr_s_l") +#pragma comment(linker, "/EXPORT:__wcsxfrm_l=msvcrt._wcsxfrm_l") +#pragma comment(linker, "/EXPORT:__wctime=msvcrt._wctime") +#pragma comment(linker, "/EXPORT:__wctime32=msvcrt._wctime32") +#pragma comment(linker, "/EXPORT:__wctime32_s=msvcrt._wctime32_s") +#pragma comment(linker, "/EXPORT:__wctime64=msvcrt._wctime64") +#pragma comment(linker, "/EXPORT:__wctime64_s=msvcrt._wctime64_s") +#pragma comment(linker, "/EXPORT:__wctomb_l=msvcrt._wctomb_l") +#pragma comment(linker, "/EXPORT:__wctomb_s_l=msvcrt._wctomb_s_l") +#pragma comment(linker, "/EXPORT:__wctype=msvcrt._wctype") +#pragma comment(linker, "/EXPORT:__wenviron=msvcrt._wenviron") +#pragma comment(linker, "/EXPORT:__wexecl=msvcrt._wexecl") +#pragma comment(linker, "/EXPORT:__wexecle=msvcrt._wexecle") +#pragma comment(linker, "/EXPORT:__wexeclp=msvcrt._wexeclp") +#pragma comment(linker, "/EXPORT:__wexeclpe=msvcrt._wexeclpe") +#pragma comment(linker, "/EXPORT:__wexecv=msvcrt._wexecv") +#pragma comment(linker, "/EXPORT:__wexecve=msvcrt._wexecve") +#pragma comment(linker, "/EXPORT:__wexecvp=msvcrt._wexecvp") +#pragma comment(linker, "/EXPORT:__wexecvpe=msvcrt._wexecvpe") +#pragma comment(linker, "/EXPORT:__wfdopen=msvcrt._wfdopen") +#pragma comment(linker, "/EXPORT:__wfindfirst=msvcrt._wfindfirst") +#pragma comment(linker, "/EXPORT:__wfindfirst64=msvcrt._wfindfirst64") +#pragma comment(linker, "/EXPORT:__wfindfirsti64=msvcrt._wfindfirsti64") +#pragma comment(linker, "/EXPORT:__wfindnext=msvcrt._wfindnext") +#pragma comment(linker, "/EXPORT:__wfindnext64=msvcrt._wfindnext64") +#pragma comment(linker, "/EXPORT:__wfindnexti64=msvcrt._wfindnexti64") +#pragma comment(linker, "/EXPORT:__wfopen=msvcrt._wfopen") +#pragma comment(linker, "/EXPORT:__wfopen_s=msvcrt._wfopen_s") +#pragma comment(linker, "/EXPORT:__wfreopen=msvcrt._wfreopen") +#pragma comment(linker, "/EXPORT:__wfreopen_s=msvcrt._wfreopen_s") +#pragma comment(linker, "/EXPORT:__wfsopen=msvcrt._wfsopen") +#pragma comment(linker, "/EXPORT:__wfullpath=msvcrt._wfullpath") +#pragma comment(linker, "/EXPORT:__wfullpath_dbg=msvcrt._wfullpath_dbg") +#pragma comment(linker, "/EXPORT:__wgetcwd=msvcrt._wgetcwd") +#pragma comment(linker, "/EXPORT:__wgetdcwd=msvcrt._wgetdcwd") +#pragma comment(linker, "/EXPORT:__wgetenv=msvcrt._wgetenv") +#pragma comment(linker, "/EXPORT:__wgetenv_s=msvcrt._wgetenv_s") +#pragma comment(linker, "/EXPORT:__winmajor=msvcrt._winmajor") +#pragma comment(linker, "/EXPORT:__winminor=msvcrt._winminor") +#pragma comment(linker, "/EXPORT:__winput_s=msvcrt._winput_s") +#pragma comment(linker, "/EXPORT:__winver=msvcrt._winver") +#pragma comment(linker, "/EXPORT:__wmakepath=msvcrt._wmakepath") +#pragma comment(linker, "/EXPORT:__wmakepath_s=msvcrt._wmakepath_s") +#pragma comment(linker, "/EXPORT:__wmkdir=msvcrt._wmkdir") +#pragma comment(linker, "/EXPORT:__wmktemp=msvcrt._wmktemp") +#pragma comment(linker, "/EXPORT:__wmktemp_s=msvcrt._wmktemp_s") +#pragma comment(linker, "/EXPORT:__wopen=msvcrt._wopen") +#pragma comment(linker, "/EXPORT:__woutput_s=msvcrt._woutput_s") +#pragma comment(linker, "/EXPORT:__wperror=msvcrt._wperror") +#pragma comment(linker, "/EXPORT:__wpgmptr=msvcrt._wpgmptr") +#pragma comment(linker, "/EXPORT:__wpopen=msvcrt._wpopen") +#pragma comment(linker, "/EXPORT:__wprintf_l=msvcrt._wprintf_l") +#pragma comment(linker, "/EXPORT:__wprintf_p=msvcrt._wprintf_p") +#pragma comment(linker, "/EXPORT:__wprintf_p_l=msvcrt._wprintf_p_l") +#pragma comment(linker, "/EXPORT:__wprintf_s_l=msvcrt._wprintf_s_l") +#pragma comment(linker, "/EXPORT:__wputenv=msvcrt._wputenv") +#pragma comment(linker, "/EXPORT:__wputenv_s=msvcrt._wputenv_s") +#pragma comment(linker, "/EXPORT:__wremove=msvcrt._wremove") +#pragma comment(linker, "/EXPORT:__wrename=msvcrt._wrename") +#pragma comment(linker, "/EXPORT:__write=msvcrt._write") +#pragma comment(linker, "/EXPORT:__wrmdir=msvcrt._wrmdir") +#pragma comment(linker, "/EXPORT:__wscanf_l=msvcrt._wscanf_l") +#pragma comment(linker, "/EXPORT:__wscanf_s_l=msvcrt._wscanf_s_l") +#pragma comment(linker, "/EXPORT:__wsearchenv=msvcrt._wsearchenv") +#pragma comment(linker, "/EXPORT:__wsearchenv_s=msvcrt._wsearchenv_s") +#pragma comment(linker, "/EXPORT:__wsetlocale=msvcrt._wsetlocale") +#pragma comment(linker, "/EXPORT:__wsopen=msvcrt._wsopen") +#pragma comment(linker, "/EXPORT:__wsopen_s=msvcrt._wsopen_s") +#pragma comment(linker, "/EXPORT:__wspawnl=msvcrt._wspawnl") +#pragma comment(linker, "/EXPORT:__wspawnle=msvcrt._wspawnle") +#pragma comment(linker, "/EXPORT:__wspawnlp=msvcrt._wspawnlp") +#pragma comment(linker, "/EXPORT:__wspawnlpe=msvcrt._wspawnlpe") +#pragma comment(linker, "/EXPORT:__wspawnv=msvcrt._wspawnv") +#pragma comment(linker, "/EXPORT:__wspawnve=msvcrt._wspawnve") +#pragma comment(linker, "/EXPORT:__wspawnvp=msvcrt._wspawnvp") +#pragma comment(linker, "/EXPORT:__wspawnvpe=msvcrt._wspawnvpe") +#pragma comment(linker, "/EXPORT:__wsplitpath=msvcrt._wsplitpath") +#pragma comment(linker, "/EXPORT:__wsplitpath_s=msvcrt._wsplitpath_s") +#pragma comment(linker, "/EXPORT:__wstat=msvcrt._wstat") +#pragma comment(linker, "/EXPORT:__wstat64=msvcrt._wstat64") +#pragma comment(linker, "/EXPORT:__wstati64=msvcrt._wstati64") +#pragma comment(linker, "/EXPORT:__wstrdate=msvcrt._wstrdate") +#pragma comment(linker, "/EXPORT:__wstrdate_s=msvcrt._wstrdate_s") +#pragma comment(linker, "/EXPORT:__wstrtime=msvcrt._wstrtime") +#pragma comment(linker, "/EXPORT:__wstrtime_s=msvcrt._wstrtime_s") +#pragma comment(linker, "/EXPORT:__wsystem=msvcrt._wsystem") +#pragma comment(linker, "/EXPORT:__wtempnam=msvcrt._wtempnam") +#pragma comment(linker, "/EXPORT:__wtempnam_dbg=msvcrt._wtempnam_dbg") +#pragma comment(linker, "/EXPORT:__wtmpnam=msvcrt._wtmpnam") +#pragma comment(linker, "/EXPORT:__wtmpnam_s=msvcrt._wtmpnam_s") +#pragma comment(linker, "/EXPORT:__wtof=msvcrt._wtof") +#pragma comment(linker, "/EXPORT:__wtof_l=msvcrt._wtof_l") +#pragma comment(linker, "/EXPORT:__wtoi=msvcrt._wtoi") +#pragma comment(linker, "/EXPORT:__wtoi64=msvcrt._wtoi64") +#pragma comment(linker, "/EXPORT:__wtoi64_l=msvcrt._wtoi64_l") +#pragma comment(linker, "/EXPORT:__wtoi_l=msvcrt._wtoi_l") +#pragma comment(linker, "/EXPORT:__wtol=msvcrt._wtol") +#pragma comment(linker, "/EXPORT:__wtol_l=msvcrt._wtol_l") +#pragma comment(linker, "/EXPORT:__wunlink=msvcrt._wunlink") +#pragma comment(linker, "/EXPORT:__wutime=msvcrt._wutime") +#pragma comment(linker, "/EXPORT:__wutime32=msvcrt._wutime32") +#pragma comment(linker, "/EXPORT:__wutime64=msvcrt._wutime64") +#pragma comment(linker, "/EXPORT:__y0=msvcrt._y0") +#pragma comment(linker, "/EXPORT:__y1=msvcrt._y1") +#pragma comment(linker, "/EXPORT:__yn=msvcrt._yn") +#pragma comment(linker, "/EXPORT:abort=msvcrt.abort") +#pragma comment(linker, "/EXPORT:abs=msvcrt.abs") +#pragma comment(linker, "/EXPORT:acos=msvcrt.acos") +#pragma comment(linker, "/EXPORT:asctime=msvcrt.asctime") +#pragma comment(linker, "/EXPORT:asctime_s=msvcrt.asctime_s") +#pragma comment(linker, "/EXPORT:asin=msvcrt.asin") +#pragma comment(linker, "/EXPORT:atan=msvcrt.atan") +#pragma comment(linker, "/EXPORT:atan2=msvcrt.atan2") +#pragma comment(linker, "/EXPORT:atexit=msvcrt.atexit") +#pragma comment(linker, "/EXPORT:atof=msvcrt.atof") +#pragma comment(linker, "/EXPORT:atoi=msvcrt.atoi") +#pragma comment(linker, "/EXPORT:atol=msvcrt.atol") +#pragma comment(linker, "/EXPORT:bsearch=msvcrt.bsearch") +#pragma comment(linker, "/EXPORT:bsearch_s=msvcrt.bsearch_s") +#pragma comment(linker, "/EXPORT:btowc=msvcrt.btowc") +#pragma comment(linker, "/EXPORT:calloc=msvcrt.calloc") +#pragma comment(linker, "/EXPORT:ceil=msvcrt.ceil") +#pragma comment(linker, "/EXPORT:clearerr=msvcrt.clearerr") +#pragma comment(linker, "/EXPORT:clearerr_s=msvcrt.clearerr_s") +#pragma comment(linker, "/EXPORT:clock=msvcrt.clock") +#pragma comment(linker, "/EXPORT:cos=msvcrt.cos") +#pragma comment(linker, "/EXPORT:cosh=msvcrt.cosh") +#pragma comment(linker, "/EXPORT:ctime=msvcrt.ctime") +#pragma comment(linker, "/EXPORT:difftime=msvcrt.difftime") +#pragma comment(linker, "/EXPORT:div=msvcrt.div") +#pragma comment(linker, "/EXPORT:exit=msvcrt.exit") +#pragma comment(linker, "/EXPORT:exp=msvcrt.exp") +#pragma comment(linker, "/EXPORT:fabs=msvcrt.fabs") +#pragma comment(linker, "/EXPORT:fclose=msvcrt.fclose") +#pragma comment(linker, "/EXPORT:feof=msvcrt.feof") +#pragma comment(linker, "/EXPORT:ferror=msvcrt.ferror") +#pragma comment(linker, "/EXPORT:fflush=msvcrt.fflush") +#pragma comment(linker, "/EXPORT:fgetc=msvcrt.fgetc") +#pragma comment(linker, "/EXPORT:fgetpos=msvcrt.fgetpos") +#pragma comment(linker, "/EXPORT:fgets=msvcrt.fgets") +#pragma comment(linker, "/EXPORT:fgetwc=msvcrt.fgetwc") +#pragma comment(linker, "/EXPORT:fgetws=msvcrt.fgetws") +#pragma comment(linker, "/EXPORT:floor=msvcrt.floor") +#pragma comment(linker, "/EXPORT:fmod=msvcrt.fmod") +#pragma comment(linker, "/EXPORT:fopen=msvcrt.fopen") +#pragma comment(linker, "/EXPORT:fopen_s=msvcrt.fopen_s") +#pragma comment(linker, "/EXPORT:fprintf=msvcrt.fprintf") +#pragma comment(linker, "/EXPORT:fprintf_s=msvcrt.fprintf_s") +#pragma comment(linker, "/EXPORT:fputc=msvcrt.fputc") +#pragma comment(linker, "/EXPORT:fputs=msvcrt.fputs") +#pragma comment(linker, "/EXPORT:fputwc=msvcrt.fputwc") +#pragma comment(linker, "/EXPORT:fputws=msvcrt.fputws") +#pragma comment(linker, "/EXPORT:fread=msvcrt.fread") +#pragma comment(linker, "/EXPORT:free=msvcrt.free") +#pragma comment(linker, "/EXPORT:freopen=msvcrt.freopen") +#pragma comment(linker, "/EXPORT:freopen_s=msvcrt.freopen_s") +#pragma comment(linker, "/EXPORT:frexp=msvcrt.frexp") +#pragma comment(linker, "/EXPORT:fscanf=msvcrt.fscanf") +#pragma comment(linker, "/EXPORT:fscanf_s=msvcrt.fscanf_s") +#pragma comment(linker, "/EXPORT:fseek=msvcrt.fseek") +#pragma comment(linker, "/EXPORT:fsetpos=msvcrt.fsetpos") +#pragma comment(linker, "/EXPORT:ftell=msvcrt.ftell") +#pragma comment(linker, "/EXPORT:fwprintf=msvcrt.fwprintf") +#pragma comment(linker, "/EXPORT:fwprintf_s=msvcrt.fwprintf_s") +#pragma comment(linker, "/EXPORT:fwrite=msvcrt.fwrite") +#pragma comment(linker, "/EXPORT:fwscanf=msvcrt.fwscanf") +#pragma comment(linker, "/EXPORT:fwscanf_s=msvcrt.fwscanf_s") +#pragma comment(linker, "/EXPORT:getc=msvcrt.getc") +#pragma comment(linker, "/EXPORT:getchar=msvcrt.getchar") +#pragma comment(linker, "/EXPORT:getenv=msvcrt.getenv") +#pragma comment(linker, "/EXPORT:getenv_s=msvcrt.getenv_s") +#pragma comment(linker, "/EXPORT:gets=msvcrt.gets") +#pragma comment(linker, "/EXPORT:getwc=msvcrt.getwc") +#pragma comment(linker, "/EXPORT:getwchar=msvcrt.getwchar") +#pragma comment(linker, "/EXPORT:gmtime=msvcrt.gmtime") +#pragma comment(linker, "/EXPORT:is_wctype=msvcrt.is_wctype") +#pragma comment(linker, "/EXPORT:isalnum=msvcrt.isalnum") +#pragma comment(linker, "/EXPORT:isalpha=msvcrt.isalpha") +#pragma comment(linker, "/EXPORT:iscntrl=msvcrt.iscntrl") +#pragma comment(linker, "/EXPORT:isdigit=msvcrt.isdigit") +#pragma comment(linker, "/EXPORT:isgraph=msvcrt.isgraph") +#pragma comment(linker, "/EXPORT:isleadbyte=msvcrt.isleadbyte") +#pragma comment(linker, "/EXPORT:islower=msvcrt.islower") +#pragma comment(linker, "/EXPORT:isprint=msvcrt.isprint") +#pragma comment(linker, "/EXPORT:ispunct=msvcrt.ispunct") +#pragma comment(linker, "/EXPORT:isspace=msvcrt.isspace") +#pragma comment(linker, "/EXPORT:isupper=msvcrt.isupper") +#pragma comment(linker, "/EXPORT:iswalnum=msvcrt.iswalnum") +#pragma comment(linker, "/EXPORT:iswalpha=msvcrt.iswalpha") +#pragma comment(linker, "/EXPORT:iswascii=msvcrt.iswascii") +#pragma comment(linker, "/EXPORT:iswcntrl=msvcrt.iswcntrl") +#pragma comment(linker, "/EXPORT:iswctype=msvcrt.iswctype") +#pragma comment(linker, "/EXPORT:iswdigit=msvcrt.iswdigit") +#pragma comment(linker, "/EXPORT:iswgraph=msvcrt.iswgraph") +#pragma comment(linker, "/EXPORT:iswlower=msvcrt.iswlower") +#pragma comment(linker, "/EXPORT:iswprint=msvcrt.iswprint") +#pragma comment(linker, "/EXPORT:iswpunct=msvcrt.iswpunct") +#pragma comment(linker, "/EXPORT:iswspace=msvcrt.iswspace") +#pragma comment(linker, "/EXPORT:iswupper=msvcrt.iswupper") +#pragma comment(linker, "/EXPORT:iswxdigit=msvcrt.iswxdigit") +#pragma comment(linker, "/EXPORT:isxdigit=msvcrt.isxdigit") +#pragma comment(linker, "/EXPORT:labs=msvcrt.labs") +#pragma comment(linker, "/EXPORT:ldexp=msvcrt.ldexp") +#pragma comment(linker, "/EXPORT:ldiv=msvcrt.ldiv") +#pragma comment(linker, "/EXPORT:localeconv=msvcrt.localeconv") +#pragma comment(linker, "/EXPORT:localtime=msvcrt.localtime") +#pragma comment(linker, "/EXPORT:log=msvcrt.log") +#pragma comment(linker, "/EXPORT:log10=msvcrt.log10") +#pragma comment(linker, "/EXPORT:longjmp=msvcrt.longjmp") +#pragma comment(linker, "/EXPORT:malloc=msvcrt.malloc") +#pragma comment(linker, "/EXPORT:mblen=msvcrt.mblen") +#pragma comment(linker, "/EXPORT:mbrlen=msvcrt.mbrlen") +#pragma comment(linker, "/EXPORT:mbrtowc=msvcrt.mbrtowc") +#pragma comment(linker, "/EXPORT:mbsdup_dbg=msvcrt.mbsdup_dbg") +#pragma comment(linker, "/EXPORT:mbsrtowcs=msvcrt.mbsrtowcs") +#pragma comment(linker, "/EXPORT:mbsrtowcs_s=msvcrt.mbsrtowcs_s") +#pragma comment(linker, "/EXPORT:mbstowcs=msvcrt.mbstowcs") +#pragma comment(linker, "/EXPORT:mbstowcs_s=msvcrt.mbstowcs_s") +#pragma comment(linker, "/EXPORT:mbtowc=msvcrt.mbtowc") +#pragma comment(linker, "/EXPORT:memchr=msvcrt.memchr") +#pragma comment(linker, "/EXPORT:memcmp=msvcrt.memcmp") +#pragma comment(linker, "/EXPORT:memcpy=msvcrt.memcpy") +#pragma comment(linker, "/EXPORT:memcpy_s=msvcrt.memcpy_s") +#pragma comment(linker, "/EXPORT:memmove=msvcrt.memmove") +#pragma comment(linker, "/EXPORT:memmove_s=msvcrt.memmove_s") +#pragma comment(linker, "/EXPORT:memset=msvcrt.memset") +#pragma comment(linker, "/EXPORT:mktime=msvcrt.mktime") +#pragma comment(linker, "/EXPORT:modf=msvcrt.modf") +#pragma comment(linker, "/EXPORT:perror=msvcrt.perror") +#pragma comment(linker, "/EXPORT:pow=msvcrt.pow") +#pragma comment(linker, "/EXPORT:printf=msvcrt.printf") +#pragma comment(linker, "/EXPORT:printf_s=msvcrt.printf_s") +#pragma comment(linker, "/EXPORT:putc=msvcrt.putc") +#pragma comment(linker, "/EXPORT:putchar=msvcrt.putchar") +#pragma comment(linker, "/EXPORT:puts=msvcrt.puts") +#pragma comment(linker, "/EXPORT:putwc=msvcrt.putwc") +#pragma comment(linker, "/EXPORT:putwchar=msvcrt.putwchar") +#pragma comment(linker, "/EXPORT:qsort=msvcrt.qsort") +#pragma comment(linker, "/EXPORT:qsort_s=msvcrt.qsort_s") +#pragma comment(linker, "/EXPORT:raise=msvcrt.raise") +#pragma comment(linker, "/EXPORT:rand=msvcrt.rand") +#pragma comment(linker, "/EXPORT:rand_s=msvcrt.rand_s") +#pragma comment(linker, "/EXPORT:realloc=msvcrt.realloc") +#pragma comment(linker, "/EXPORT:remove=msvcrt.remove") +#pragma comment(linker, "/EXPORT:rename=msvcrt.rename") +#pragma comment(linker, "/EXPORT:rewind=msvcrt.rewind") +#pragma comment(linker, "/EXPORT:scanf=msvcrt.scanf") +#pragma comment(linker, "/EXPORT:scanf_s=msvcrt.scanf_s") +#pragma comment(linker, "/EXPORT:setbuf=msvcrt.setbuf") +#pragma comment(linker, "/EXPORT:setlocale=msvcrt.setlocale") +#pragma comment(linker, "/EXPORT:setvbuf=msvcrt.setvbuf") +#pragma comment(linker, "/EXPORT:signal=msvcrt.signal") +#pragma comment(linker, "/EXPORT:sin=msvcrt.sin") +#pragma comment(linker, "/EXPORT:sinh=msvcrt.sinh") +#pragma comment(linker, "/EXPORT:sprintf=msvcrt.sprintf") +#pragma comment(linker, "/EXPORT:sprintf_s=msvcrt.sprintf_s") +#pragma comment(linker, "/EXPORT:sqrt=msvcrt.sqrt") +#pragma comment(linker, "/EXPORT:srand=msvcrt.srand") +#pragma comment(linker, "/EXPORT:sscanf=msvcrt.sscanf") +#pragma comment(linker, "/EXPORT:sscanf_s=msvcrt.sscanf_s") +#pragma comment(linker, "/EXPORT:strcat=msvcrt.strcat") +#pragma comment(linker, "/EXPORT:strcat_s=msvcrt.strcat_s") +#pragma comment(linker, "/EXPORT:strchr=msvcrt.strchr") +#pragma comment(linker, "/EXPORT:strcmp=msvcrt.strcmp") +#pragma comment(linker, "/EXPORT:strcoll=msvcrt.strcoll") +#pragma comment(linker, "/EXPORT:strcpy=msvcrt.strcpy") +#pragma comment(linker, "/EXPORT:strcpy_s=msvcrt.strcpy_s") +#pragma comment(linker, "/EXPORT:strcspn=msvcrt.strcspn") +#pragma comment(linker, "/EXPORT:strerror=msvcrt.strerror") +#pragma comment(linker, "/EXPORT:strerror_s=msvcrt.strerror_s") +#pragma comment(linker, "/EXPORT:strftime=msvcrt.strftime") +#pragma comment(linker, "/EXPORT:strlen=msvcrt.strlen") +#pragma comment(linker, "/EXPORT:strncat=msvcrt.strncat") +#pragma comment(linker, "/EXPORT:strncat_s=msvcrt.strncat_s") +#pragma comment(linker, "/EXPORT:strncmp=msvcrt.strncmp") +#pragma comment(linker, "/EXPORT:strncpy=msvcrt.strncpy") +#pragma comment(linker, "/EXPORT:strncpy_s=msvcrt.strncpy_s") +#pragma comment(linker, "/EXPORT:strnlen=msvcrt.strnlen") +#pragma comment(linker, "/EXPORT:strpbrk=msvcrt.strpbrk") +#pragma comment(linker, "/EXPORT:strrchr=msvcrt.strrchr") +#pragma comment(linker, "/EXPORT:strspn=msvcrt.strspn") +#pragma comment(linker, "/EXPORT:strstr=msvcrt.strstr") +#pragma comment(linker, "/EXPORT:strtod=msvcrt.strtod") +#pragma comment(linker, "/EXPORT:strtok=msvcrt.strtok") +#pragma comment(linker, "/EXPORT:strtok_s=msvcrt.strtok_s") +#pragma comment(linker, "/EXPORT:strtol=msvcrt.strtol") +#pragma comment(linker, "/EXPORT:strtoul=msvcrt.strtoul") +#pragma comment(linker, "/EXPORT:strxfrm=msvcrt.strxfrm") +#pragma comment(linker, "/EXPORT:swprintf=msvcrt.swprintf") +#pragma comment(linker, "/EXPORT:swprintf_s=msvcrt.swprintf_s") +#pragma comment(linker, "/EXPORT:swscanf=msvcrt.swscanf") +#pragma comment(linker, "/EXPORT:swscanf_s=msvcrt.swscanf_s") +#pragma comment(linker, "/EXPORT:system=msvcrt.system") +#pragma comment(linker, "/EXPORT:tan=msvcrt.tan") +#pragma comment(linker, "/EXPORT:tanh=msvcrt.tanh") +#pragma comment(linker, "/EXPORT:time=msvcrt.time") +#pragma comment(linker, "/EXPORT:tmpfile=msvcrt.tmpfile") +#pragma comment(linker, "/EXPORT:tmpfile_s=msvcrt.tmpfile_s") +#pragma comment(linker, "/EXPORT:tmpnam=msvcrt.tmpnam") +#pragma comment(linker, "/EXPORT:tmpnam_s=msvcrt.tmpnam_s") +#pragma comment(linker, "/EXPORT:tolower=msvcrt.tolower") +#pragma comment(linker, "/EXPORT:toupper=msvcrt.toupper") +#pragma comment(linker, "/EXPORT:towlower=msvcrt.towlower") +#pragma comment(linker, "/EXPORT:towupper=msvcrt.towupper") +#pragma comment(linker, "/EXPORT:ungetc=msvcrt.ungetc") +#pragma comment(linker, "/EXPORT:ungetwc=msvcrt.ungetwc") +#pragma comment(linker, "/EXPORT:utime=msvcrt.utime") +#pragma comment(linker, "/EXPORT:vfprintf=msvcrt.vfprintf") +#pragma comment(linker, "/EXPORT:vfprintf_s=msvcrt.vfprintf_s") +#pragma comment(linker, "/EXPORT:vfwprintf=msvcrt.vfwprintf") +#pragma comment(linker, "/EXPORT:vfwprintf_s=msvcrt.vfwprintf_s") +#pragma comment(linker, "/EXPORT:vprintf=msvcrt.vprintf") +#pragma comment(linker, "/EXPORT:vprintf_s=msvcrt.vprintf_s") +#pragma comment(linker, "/EXPORT:vsnprintf=msvcrt.vsnprintf") +#pragma comment(linker, "/EXPORT:vsprintf=msvcrt.vsprintf") +#pragma comment(linker, "/EXPORT:vsprintf_s=msvcrt.vsprintf_s") +#pragma comment(linker, "/EXPORT:vswprintf=msvcrt.vswprintf") +#pragma comment(linker, "/EXPORT:vswprintf_s=msvcrt.vswprintf_s") +#pragma comment(linker, "/EXPORT:vwprintf=msvcrt.vwprintf") +#pragma comment(linker, "/EXPORT:vwprintf_s=msvcrt.vwprintf_s") +#pragma comment(linker, "/EXPORT:wcrtomb=msvcrt.wcrtomb") +#pragma comment(linker, "/EXPORT:wcrtomb_s=msvcrt.wcrtomb_s") +#pragma comment(linker, "/EXPORT:wcscat=msvcrt.wcscat") +#pragma comment(linker, "/EXPORT:wcscat_s=msvcrt.wcscat_s") +#pragma comment(linker, "/EXPORT:wcschr=msvcrt.wcschr") +#pragma comment(linker, "/EXPORT:wcscmp=msvcrt.wcscmp") +#pragma comment(linker, "/EXPORT:wcscoll=msvcrt.wcscoll") +#pragma comment(linker, "/EXPORT:wcscpy=msvcrt.wcscpy") +#pragma comment(linker, "/EXPORT:wcscpy_s=msvcrt.wcscpy_s") +#pragma comment(linker, "/EXPORT:wcscspn=msvcrt.wcscspn") +#pragma comment(linker, "/EXPORT:wcsftime=msvcrt.wcsftime") +#pragma comment(linker, "/EXPORT:wcslen=msvcrt.wcslen") +#pragma comment(linker, "/EXPORT:wcsncat=msvcrt.wcsncat") +#pragma comment(linker, "/EXPORT:wcsncat_s=msvcrt.wcsncat_s") +#pragma comment(linker, "/EXPORT:wcsncmp=msvcrt.wcsncmp") +#pragma comment(linker, "/EXPORT:wcsncpy=msvcrt.wcsncpy") +#pragma comment(linker, "/EXPORT:wcsncpy_s=msvcrt.wcsncpy_s") +#pragma comment(linker, "/EXPORT:wcsnlen=msvcrt.wcsnlen") +#pragma comment(linker, "/EXPORT:wcspbrk=msvcrt.wcspbrk") +#pragma comment(linker, "/EXPORT:wcsrchr=msvcrt.wcsrchr") +#pragma comment(linker, "/EXPORT:wcsrtombs=msvcrt.wcsrtombs") +#pragma comment(linker, "/EXPORT:wcsrtombs_s=msvcrt.wcsrtombs_s") +#pragma comment(linker, "/EXPORT:wcsspn=msvcrt.wcsspn") +#pragma comment(linker, "/EXPORT:wcsstr=msvcrt.wcsstr") +#pragma comment(linker, "/EXPORT:wcstod=msvcrt.wcstod") +#pragma comment(linker, "/EXPORT:wcstok=msvcrt.wcstok") +#pragma comment(linker, "/EXPORT:wcstok_s=msvcrt.wcstok_s") +#pragma comment(linker, "/EXPORT:wcstol=msvcrt.wcstol") +#pragma comment(linker, "/EXPORT:wcstombs=msvcrt.wcstombs") +#pragma comment(linker, "/EXPORT:wcstombs_s=msvcrt.wcstombs_s") +#pragma comment(linker, "/EXPORT:wcstoul=msvcrt.wcstoul") +#pragma comment(linker, "/EXPORT:wcsxfrm=msvcrt.wcsxfrm") +#pragma comment(linker, "/EXPORT:wctob=msvcrt.wctob") +#pragma comment(linker, "/EXPORT:wctomb=msvcrt.wctomb") +#pragma comment(linker, "/EXPORT:wctomb_s=msvcrt.wctomb_s") +#pragma comment(linker, "/EXPORT:wprintf=msvcrt.wprintf") +#pragma comment(linker, "/EXPORT:wprintf_s=msvcrt.wprintf_s") +#pragma comment(linker, "/EXPORT:wscanf=msvcrt.wscanf") +#pragma comment(linker, "/EXPORT:wscanf_s=msvcrt.wscanf_s") + + +#endif \ No newline at end of file diff --git a/01-Extended DLLs/KxCrt/kxcrt.def b/01-Extended DLLs/KxCrt/kxcrt.def new file mode 100644 index 0000000..ca27946 --- /dev/null +++ b/01-Extended DLLs/KxCrt/kxcrt.def @@ -0,0 +1,5 @@ +LIBRARY KxCrt +EXPORTS + _W_Getdays + _W_Getmonths + _W_Gettnames \ No newline at end of file diff --git a/01-Extended DLLs/KxCrt/wcsftime.c b/01-Extended DLLs/KxCrt/wcsftime.c new file mode 100644 index 0000000..9181e43 --- /dev/null +++ b/01-Extended DLLs/KxCrt/wcsftime.c @@ -0,0 +1,224 @@ +#include "buildcfg.h" +#include + +// +// The functions in this file mostly proxy over to the _W_ functions in +// ucrtbase.dll. The reason we need proxy functions and not just export +// forwarders is because msvcrt.dll and ucrtbase.dll use different private +// heaps, and using the wrong one will cause a crash. +// + +typedef PWSTR (CDECL *P_W_GETDAYS)(VOID); +typedef PWSTR (CDECL *P_W_GETMONTHS)(VOID); +typedef PWSTR (CDECL *P_W_GETTNAMES)(VOID); +typedef VOID (CDECL *PFREE)(PVOID); + +STATIC NTSTATUS GetUcrtProcAddress( + IN PCSTR ProcedureName, + OUT PPVOID ProcedureAddress) +{ + NTSTATUS Status; + STATIC PVOID UcrtDllHandle = NULL; + ANSI_STRING ProcedureNameAS; + + ASSUME (ProcedureName != NULL); + ASSUME (ProcedureAddress != NULL); + + *ProcedureAddress = NULL; + + if (!UcrtDllHandle) { + UNICODE_STRING UcrtDllName; + + RtlInitConstantUnicodeString(&UcrtDllName, L"ucrtbase.dll"); + + Status = LdrLoadDll( + NULL, + NULL, + &UcrtDllName, + &UcrtDllHandle); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + return Status; + } + } + + ASSUME (UcrtDllHandle != NULL); + + Status = RtlInitAnsiStringEx(&ProcedureNameAS, ProcedureName); + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + return Status; + } + + Status = LdrGetProcedureAddress( + UcrtDllHandle, + &ProcedureNameAS, + 0, + ProcedureAddress); + + ASSERT (NT_SUCCESS(Status)); + + return Status; +} + +STATIC NTSTATUS TransferToMsvcrtHeap( + IN OUT PPVOID Pointer, + IN SIZE_T Size) +{ + NTSTATUS Status; + PVOID NewPointer; + STATIC PFREE UcrtFree = NULL; + + ASSUME (Pointer != NULL); + ASSUME (*Pointer != NULL); + ASSUME (Size != 0); + + if (!UcrtFree) { + Status = GetUcrtProcAddress("free", (PPVOID) &UcrtFree); + if (!NT_SUCCESS(Status)) { + return Status; + } + } + + ASSUME (UcrtFree != NULL); + + NewPointer = malloc(Size); + ASSERT (NewPointer != NULL); + + if (!NewPointer) { + return STATUS_NO_MEMORY; + } + + RtlCopyMemory(NewPointer, *Pointer, Size); + UcrtFree(*Pointer); + *Pointer = NewPointer; + + return STATUS_SUCCESS; +} + +PWSTR CDECL _W_Getdays( + VOID) +{ + NTSTATUS Status; + PWSTR UcrtGetdaysResult; + STATIC P_W_GETDAYS UcrtWGetdays = NULL; + + if (!UcrtWGetdays) { + Status = GetUcrtProcAddress("_W_Getdays", (PPVOID) &UcrtWGetdays); + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + return NULL; + } + } + + ASSUME (UcrtWGetdays != NULL); + + UcrtGetdaysResult = UcrtWGetdays(); + ASSERT (UcrtGetdaysResult != NULL); + + if (!UcrtGetdaysResult) { + return NULL; + } + + Status = TransferToMsvcrtHeap( + (PPVOID) &UcrtGetdaysResult, + (wcslen(UcrtGetdaysResult) + 1) * sizeof(WCHAR)); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + return NULL; + } + + return UcrtGetdaysResult; +} + +PWSTR CDECL _W_Getmonths( + VOID) +{ + NTSTATUS Status; + PWSTR UcrtGetmonthsResult; + STATIC P_W_GETMONTHS UcrtWGetmonths = NULL; + + if (!UcrtWGetmonths) { + Status = GetUcrtProcAddress("_W_Getmonths", (PPVOID) &UcrtWGetmonths); + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + return NULL; + } + } + + ASSUME (UcrtWGetmonths != NULL); + + UcrtGetmonthsResult = UcrtWGetmonths(); + ASSERT (UcrtGetmonthsResult != NULL); + + if (!UcrtGetmonthsResult) { + return NULL; + } + + Status = TransferToMsvcrtHeap( + (PPVOID) &UcrtGetmonthsResult, + (wcslen(UcrtGetmonthsResult) + 1) * sizeof(WCHAR)); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + return NULL; + } + + return UcrtGetmonthsResult; +} + +PWSTR CDECL _W_Gettnames( + VOID) +{ + NTSTATUS Status; + PWSTR UcrtGettnamesResult; + STATIC P_W_GETTNAMES UcrtWGettnames = NULL; + + if (!UcrtWGettnames) { + Status = GetUcrtProcAddress("_W_Gettnames", (PPVOID) &UcrtWGettnames); + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + return NULL; + } + } + + ASSUME (UcrtWGettnames != NULL); + + UcrtGettnamesResult = UcrtWGettnames(); + ASSERT (UcrtGettnamesResult != NULL); + + if (!UcrtGettnamesResult) { + return NULL; + } + + Status = TransferToMsvcrtHeap( + (PPVOID) &UcrtGettnamesResult, + (wcslen(UcrtGettnamesResult) + 1) * sizeof(WCHAR)); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + return NULL; + } + + return UcrtGettnamesResult; +} + +// +// A note on _Wcsftime: This function is implemented by calling _Wcsftime_l, +// which is present but non-exported in Win7 msvcrt. We can grab its location +// out of the functions wcsftime or _wcsftime_l, which are just stubs that +// call _Wcsftime_l. +// +// I will only bother doing that if there are actually apps that call it, +// though. +// \ No newline at end of file diff --git a/01-Extended DLLs/KxCryp/KxCryp.vcxproj b/01-Extended DLLs/KxCryp/KxCryp.vcxproj new file mode 100644 index 0000000..a4a5c92 --- /dev/null +++ b/01-Extended DLLs/KxCryp/KxCryp.vcxproj @@ -0,0 +1,241 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {FA376FCE-E31C-4601-B4A7-3B976911E777} + Win32Proj + KxCryp + + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + + + + + + + + + + + + + + + + + false + false + false + + + false + false + false + + + false + false + false + + + false + false + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;KXCRYP_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + false + true + true + true + false + Default + false + + + Windows + true + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + true + true + kxcryp.def + + + $(SolutionDir)\00-Common Headers + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;KXCRYP_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + false + true + true + true + false + Default + false + + + Windows + true + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + true + true + kxcryp.def + + + $(SolutionDir)\00-Common Headers + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;KXCRYP_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + false + true + true + true + false + Default + false + + + Windows + true + true + true + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + true + true + kxcryp.def + + + $(SolutionDir)\00-Common Headers + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;KXCRYP_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + false + true + true + true + false + Default + false + + + Windows + true + true + true + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + true + true + kxcryp.def + + + $(SolutionDir)\00-Common Headers + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/01-Extended DLLs/KxCryp/KxCryp.vcxproj.filters b/01-Extended DLLs/KxCryp/KxCryp.vcxproj.filters new file mode 100644 index 0000000..06fcfd3 --- /dev/null +++ b/01-Extended DLLs/KxCryp/KxCryp.vcxproj.filters @@ -0,0 +1,52 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + + + Resource Files + + + + + Source Files + + + \ No newline at end of file diff --git a/01-Extended DLLs/KxCryp/bcrypt.c b/01-Extended DLLs/KxCryp/bcrypt.c new file mode 100644 index 0000000..7e1e902 --- /dev/null +++ b/01-Extended DLLs/KxCryp/bcrypt.c @@ -0,0 +1,40 @@ +#include "buildcfg.h" +#include "kxcrypp.h" + +// +// This is just a convenience function which wraps other functions in bcrypt.dll. +// + +KXCRYPAPI NTSTATUS WINAPI BCryptHash( + IN BCRYPT_ALG_HANDLE Algorithm, + IN PBYTE Secret OPTIONAL, + IN ULONG SecretCb, + IN PBYTE Input, + IN ULONG InputCb, + OUT PBYTE Output, + IN ULONG OutputCb) +{ + NTSTATUS Status; + BCRYPT_HASH_HANDLE HashHandle; + + HashHandle = NULL; + + Status = BCryptCreateHash(Algorithm, &HashHandle, 0, 0, Secret, SecretCb, 0); + if (!NT_SUCCESS(Status)) { + goto CleanupExit; + } + + Status = BCryptHashData(HashHandle, Input, InputCb, 0); + if (!NT_SUCCESS(Status)) { + goto CleanupExit; + } + + Status = BCryptFinishHash(HashHandle, Output, OutputCb, 0); + +CleanupExit: + if (HashHandle) { + BCryptDestroyHash(HashHandle); + } + + return Status; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxCryp/buildcfg.h b/01-Extended DLLs/KxCryp/buildcfg.h new file mode 100644 index 0000000..9395520 --- /dev/null +++ b/01-Extended DLLs/KxCryp/buildcfg.h @@ -0,0 +1,46 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN +#define NOGDICAPMASKS +#define NOVIRTUALKEYCODES +#define NOWINSTYLES +#define NOSYSMETRICS +#define NOMENUS +#define NOICONS +#define NOKEYSTATES +#define NOSYSCOMMANDS +#define NORASTEROPS +#define NOSHOWWINDOW +#define NOATOM +#define NOCLIPBOARD +#define NOCOLOR +#define NODRAWTEXT +#define NOGDI +#define NOKERNEL +#define NOMB +#define NOMEMMGR +#define NOOPENFILE +#define NOSCROLL +#define NOTEXTMETRIC +#define NOWH +#define NOWINOFFSETS +#define NOCOMM +#define NOKANJI +#define NOHELP +#define NOPROFILER +#define NODEFERWINDOWPOS +#define NOMCX +#define NOCRYPT +#define NOMETAFILE +#define NOSERVICE +#define NOSOUND +#define _UXTHEME_H_ + +#define KXCRYPAPI + +#pragma comment(lib, "bcrypt.lib") +#pragma comment(lib, "secur32.lib") + +#define KEX_COMPONENT L"KxCryp" +#define KEX_ENV_WIN32 +#define KEX_TARGET_TYPE_DLL diff --git a/01-Extended DLLs/KxCryp/dllmain.c b/01-Extended DLLs/KxCryp/dllmain.c new file mode 100644 index 0000000..af27a65 --- /dev/null +++ b/01-Extended DLLs/KxCryp/dllmain.c @@ -0,0 +1,17 @@ +#include "buildcfg.h" +#include "kxcrypp.h" + +PKEX_PROCESS_DATA KexData; + +BOOL WINAPI DllMain( + IN HMODULE DllHandle, + IN ULONG Reason, + IN PCONTEXT Context) +{ + if (Reason == DLL_PROCESS_ATTACH) { + LdrDisableThreadCalloutsForDll(DllHandle); + KexDataInitialize(&KexData); + } + + return TRUE; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxCryp/forwards.c b/01-Extended DLLs/KxCryp/forwards.c new file mode 100644 index 0000000..830f757 --- /dev/null +++ b/01-Extended DLLs/KxCryp/forwards.c @@ -0,0 +1,167 @@ +// Generated by KexExprt from "bcrypt.dll" +#pragma comment(linker, "/EXPORT:BCryptAddContextFunction=bcrypt.BCryptAddContextFunction") +#pragma comment(linker, "/EXPORT:BCryptAddContextFunctionProvider=bcrypt.BCryptAddContextFunctionProvider") +#pragma comment(linker, "/EXPORT:BCryptCloseAlgorithmProvider=bcrypt.BCryptCloseAlgorithmProvider") +#pragma comment(linker, "/EXPORT:BCryptConfigureContext=bcrypt.BCryptConfigureContext") +#pragma comment(linker, "/EXPORT:BCryptConfigureContextFunction=bcrypt.BCryptConfigureContextFunction") +#pragma comment(linker, "/EXPORT:BCryptCreateContext=bcrypt.BCryptCreateContext") +#pragma comment(linker, "/EXPORT:BCryptCreateHash=bcrypt.BCryptCreateHash") +#pragma comment(linker, "/EXPORT:BCryptDecrypt=bcrypt.BCryptDecrypt") +#pragma comment(linker, "/EXPORT:BCryptDeleteContext=bcrypt.BCryptDeleteContext") +#pragma comment(linker, "/EXPORT:BCryptDeriveKey=bcrypt.BCryptDeriveKey") +#pragma comment(linker, "/EXPORT:BCryptDeriveKeyCapi=bcrypt.BCryptDeriveKeyCapi") +#pragma comment(linker, "/EXPORT:BCryptDeriveKeyPBKDF2=bcrypt.BCryptDeriveKeyPBKDF2") +#pragma comment(linker, "/EXPORT:BCryptDestroyHash=bcrypt.BCryptDestroyHash") +#pragma comment(linker, "/EXPORT:BCryptDestroyKey=bcrypt.BCryptDestroyKey") +#pragma comment(linker, "/EXPORT:BCryptDestroySecret=bcrypt.BCryptDestroySecret") +#pragma comment(linker, "/EXPORT:BCryptDuplicateHash=bcrypt.BCryptDuplicateHash") +#pragma comment(linker, "/EXPORT:BCryptDuplicateKey=bcrypt.BCryptDuplicateKey") +#pragma comment(linker, "/EXPORT:BCryptEncrypt=bcrypt.BCryptEncrypt") +#pragma comment(linker, "/EXPORT:BCryptEnumAlgorithms=bcrypt.BCryptEnumAlgorithms") +#pragma comment(linker, "/EXPORT:BCryptEnumContextFunctionProviders=bcrypt.BCryptEnumContextFunctionProviders") +#pragma comment(linker, "/EXPORT:BCryptEnumContextFunctions=bcrypt.BCryptEnumContextFunctions") +#pragma comment(linker, "/EXPORT:BCryptEnumContexts=bcrypt.BCryptEnumContexts") +#pragma comment(linker, "/EXPORT:BCryptEnumProviders=bcrypt.BCryptEnumProviders") +#pragma comment(linker, "/EXPORT:BCryptEnumRegisteredProviders=bcrypt.BCryptEnumRegisteredProviders") +#pragma comment(linker, "/EXPORT:BCryptExportKey=bcrypt.BCryptExportKey") +#pragma comment(linker, "/EXPORT:BCryptFinalizeKeyPair=bcrypt.BCryptFinalizeKeyPair") +#pragma comment(linker, "/EXPORT:BCryptFinishHash=bcrypt.BCryptFinishHash") +#pragma comment(linker, "/EXPORT:BCryptFreeBuffer=bcrypt.BCryptFreeBuffer") +#pragma comment(linker, "/EXPORT:BCryptGenRandom=bcrypt.BCryptGenRandom") +#pragma comment(linker, "/EXPORT:BCryptGenerateKeyPair=bcrypt.BCryptGenerateKeyPair") +#pragma comment(linker, "/EXPORT:BCryptGenerateSymmetricKey=bcrypt.BCryptGenerateSymmetricKey") +#pragma comment(linker, "/EXPORT:BCryptGetFipsAlgorithmMode=bcrypt.BCryptGetFipsAlgorithmMode") +#pragma comment(linker, "/EXPORT:BCryptGetProperty=bcrypt.BCryptGetProperty") +#pragma comment(linker, "/EXPORT:BCryptHashData=bcrypt.BCryptHashData") +#pragma comment(linker, "/EXPORT:BCryptImportKey=bcrypt.BCryptImportKey") +#pragma comment(linker, "/EXPORT:BCryptImportKeyPair=bcrypt.BCryptImportKeyPair") +#pragma comment(linker, "/EXPORT:BCryptOpenAlgorithmProvider=bcrypt.BCryptOpenAlgorithmProvider") +#pragma comment(linker, "/EXPORT:BCryptQueryContextConfiguration=bcrypt.BCryptQueryContextConfiguration") +#pragma comment(linker, "/EXPORT:BCryptQueryContextFunctionConfiguration=bcrypt.BCryptQueryContextFunctionConfiguration") +#pragma comment(linker, "/EXPORT:BCryptQueryContextFunctionProperty=bcrypt.BCryptQueryContextFunctionProperty") +#pragma comment(linker, "/EXPORT:BCryptQueryProviderRegistration=bcrypt.BCryptQueryProviderRegistration") +#pragma comment(linker, "/EXPORT:BCryptRegisterConfigChangeNotify=bcrypt.BCryptRegisterConfigChangeNotify") +#pragma comment(linker, "/EXPORT:BCryptRegisterProvider=bcrypt.BCryptRegisterProvider") +#pragma comment(linker, "/EXPORT:BCryptRemoveContextFunction=bcrypt.BCryptRemoveContextFunction") +#pragma comment(linker, "/EXPORT:BCryptRemoveContextFunctionProvider=bcrypt.BCryptRemoveContextFunctionProvider") +#pragma comment(linker, "/EXPORT:BCryptResolveProviders=bcrypt.BCryptResolveProviders") +#pragma comment(linker, "/EXPORT:BCryptSecretAgreement=bcrypt.BCryptSecretAgreement") +#pragma comment(linker, "/EXPORT:BCryptSetAuditingInterface=bcrypt.BCryptSetAuditingInterface") +#pragma comment(linker, "/EXPORT:BCryptSetContextFunctionProperty=bcrypt.BCryptSetContextFunctionProperty") +#pragma comment(linker, "/EXPORT:BCryptSetProperty=bcrypt.BCryptSetProperty") +#pragma comment(linker, "/EXPORT:BCryptSignHash=bcrypt.BCryptSignHash") +#pragma comment(linker, "/EXPORT:BCryptUnregisterConfigChangeNotify=bcrypt.BCryptUnregisterConfigChangeNotify") +#pragma comment(linker, "/EXPORT:BCryptUnregisterProvider=bcrypt.BCryptUnregisterProvider") +#pragma comment(linker, "/EXPORT:BCryptVerifySignature=bcrypt.BCryptVerifySignature") + +// Generated by KexExprt from "bcryptprimitives.dll" +#pragma comment(linker, "/EXPORT:GetAsymmetricEncryptionInterface=bcryptprimitives.GetAsymmetricEncryptionInterface") +#pragma comment(linker, "/EXPORT:GetCipherInterface=bcryptprimitives.GetCipherInterface") +#pragma comment(linker, "/EXPORT:GetHashInterface=bcryptprimitives.GetHashInterface") +#pragma comment(linker, "/EXPORT:GetRngInterface=bcryptprimitives.GetRngInterface") +#pragma comment(linker, "/EXPORT:GetSecretAgreementInterface=bcryptprimitives.GetSecretAgreementInterface") +#pragma comment(linker, "/EXPORT:GetSignatureInterface=bcryptprimitives.GetSignatureInterface") + +// Generated by KexExprt from "C:\Windows\system32\secur32.dll" +#pragma comment(linker, "/EXPORT:AcceptSecurityContext=secur32.AcceptSecurityContext") +#pragma comment(linker, "/EXPORT:AcquireCredentialsHandleA=secur32.AcquireCredentialsHandleA") +//#pragma comment(linker, "/EXPORT:AcquireCredentialsHandleW=secur32.AcquireCredentialsHandleW") +#pragma comment(linker, "/EXPORT:AddCredentialsA=secur32.AddCredentialsA") +#pragma comment(linker, "/EXPORT:AddCredentialsW=secur32.AddCredentialsW") +#pragma comment(linker, "/EXPORT:AddSecurityPackageA=secur32.AddSecurityPackageA") +#pragma comment(linker, "/EXPORT:AddSecurityPackageW=secur32.AddSecurityPackageW") +#pragma comment(linker, "/EXPORT:ApplyControlToken=secur32.ApplyControlToken") +#pragma comment(linker, "/EXPORT:ChangeAccountPasswordA=secur32.ChangeAccountPasswordA") +#pragma comment(linker, "/EXPORT:ChangeAccountPasswordW=secur32.ChangeAccountPasswordW") +#pragma comment(linker, "/EXPORT:CloseLsaPerformanceData=secur32.CloseLsaPerformanceData") +#pragma comment(linker, "/EXPORT:CollectLsaPerformanceData=secur32.CollectLsaPerformanceData") +#pragma comment(linker, "/EXPORT:CompleteAuthToken=secur32.CompleteAuthToken") +#pragma comment(linker, "/EXPORT:CredMarshalTargetInfo=secur32.CredMarshalTargetInfo") +#pragma comment(linker, "/EXPORT:CredParseUserNameWithType=secur32.CredParseUserNameWithType") +#pragma comment(linker, "/EXPORT:CredUnmarshalTargetInfo=secur32.CredUnmarshalTargetInfo") +#pragma comment(linker, "/EXPORT:DecryptMessage=secur32.DecryptMessage") +#pragma comment(linker, "/EXPORT:DeleteSecurityContext=secur32.DeleteSecurityContext") +#pragma comment(linker, "/EXPORT:DeleteSecurityPackageA=secur32.DeleteSecurityPackageA") +#pragma comment(linker, "/EXPORT:DeleteSecurityPackageW=secur32.DeleteSecurityPackageW") +#pragma comment(linker, "/EXPORT:EncryptMessage=secur32.EncryptMessage") +#pragma comment(linker, "/EXPORT:EnumerateSecurityPackagesA=secur32.EnumerateSecurityPackagesA") +#pragma comment(linker, "/EXPORT:EnumerateSecurityPackagesW=secur32.EnumerateSecurityPackagesW") +#pragma comment(linker, "/EXPORT:ExportSecurityContext=secur32.ExportSecurityContext") +#pragma comment(linker, "/EXPORT:FreeContextBuffer=secur32.FreeContextBuffer") +#pragma comment(linker, "/EXPORT:FreeCredentialsHandle=secur32.FreeCredentialsHandle") +#pragma comment(linker, "/EXPORT:GetComputerObjectNameA=secur32.GetComputerObjectNameA") +#pragma comment(linker, "/EXPORT:GetComputerObjectNameW=secur32.GetComputerObjectNameW") +#pragma comment(linker, "/EXPORT:GetSecurityUserInfo=secur32.GetSecurityUserInfo") +#pragma comment(linker, "/EXPORT:GetUserNameExA=secur32.GetUserNameExA") +#pragma comment(linker, "/EXPORT:GetUserNameExW=secur32.GetUserNameExW") +#pragma comment(linker, "/EXPORT:ImpersonateSecurityContext=secur32.ImpersonateSecurityContext") +#pragma comment(linker, "/EXPORT:ImportSecurityContextA=secur32.ImportSecurityContextA") +#pragma comment(linker, "/EXPORT:ImportSecurityContextW=secur32.ImportSecurityContextW") +#pragma comment(linker, "/EXPORT:InitSecurityInterfaceA=secur32.InitSecurityInterfaceA") +#pragma comment(linker, "/EXPORT:InitSecurityInterfaceW=secur32.InitSecurityInterfaceW") +#pragma comment(linker, "/EXPORT:InitializeSecurityContextA=secur32.InitializeSecurityContextA") +#pragma comment(linker, "/EXPORT:InitializeSecurityContextW=secur32.InitializeSecurityContextW") +#pragma comment(linker, "/EXPORT:LsaCallAuthenticationPackage=secur32.LsaCallAuthenticationPackage") +#pragma comment(linker, "/EXPORT:LsaConnectUntrusted=secur32.LsaConnectUntrusted") +#pragma comment(linker, "/EXPORT:LsaDeregisterLogonProcess=secur32.LsaDeregisterLogonProcess") +#pragma comment(linker, "/EXPORT:LsaEnumerateLogonSessions=secur32.LsaEnumerateLogonSessions") +#pragma comment(linker, "/EXPORT:LsaFreeReturnBuffer=secur32.LsaFreeReturnBuffer") +#pragma comment(linker, "/EXPORT:LsaGetLogonSessionData=secur32.LsaGetLogonSessionData") +#pragma comment(linker, "/EXPORT:LsaLogonUser=secur32.LsaLogonUser") +#pragma comment(linker, "/EXPORT:LsaLookupAuthenticationPackage=secur32.LsaLookupAuthenticationPackage") +#pragma comment(linker, "/EXPORT:LsaRegisterLogonProcess=secur32.LsaRegisterLogonProcess") +#pragma comment(linker, "/EXPORT:LsaRegisterPolicyChangeNotification=secur32.LsaRegisterPolicyChangeNotification") +#pragma comment(linker, "/EXPORT:LsaUnregisterPolicyChangeNotification=secur32.LsaUnregisterPolicyChangeNotification") +#pragma comment(linker, "/EXPORT:MakeSignature=secur32.MakeSignature") +#pragma comment(linker, "/EXPORT:OpenLsaPerformanceData=secur32.OpenLsaPerformanceData") +#pragma comment(linker, "/EXPORT:QueryContextAttributesA=secur32.QueryContextAttributesA") +#pragma comment(linker, "/EXPORT:QueryContextAttributesW=secur32.QueryContextAttributesW") +#pragma comment(linker, "/EXPORT:QueryCredentialsAttributesA=secur32.QueryCredentialsAttributesA") +#pragma comment(linker, "/EXPORT:QueryCredentialsAttributesW=secur32.QueryCredentialsAttributesW") +#pragma comment(linker, "/EXPORT:QuerySecurityContextToken=secur32.QuerySecurityContextToken") +#pragma comment(linker, "/EXPORT:QuerySecurityPackageInfoA=secur32.QuerySecurityPackageInfoA") +#pragma comment(linker, "/EXPORT:QuerySecurityPackageInfoW=secur32.QuerySecurityPackageInfoW") +#pragma comment(linker, "/EXPORT:RevertSecurityContext=secur32.RevertSecurityContext") +#pragma comment(linker, "/EXPORT:SaslAcceptSecurityContext=secur32.SaslAcceptSecurityContext") +#pragma comment(linker, "/EXPORT:SaslEnumerateProfilesA=secur32.SaslEnumerateProfilesA") +#pragma comment(linker, "/EXPORT:SaslEnumerateProfilesW=secur32.SaslEnumerateProfilesW") +#pragma comment(linker, "/EXPORT:SaslGetContextOption=secur32.SaslGetContextOption") +#pragma comment(linker, "/EXPORT:SaslGetProfilePackageA=secur32.SaslGetProfilePackageA") +#pragma comment(linker, "/EXPORT:SaslGetProfilePackageW=secur32.SaslGetProfilePackageW") +#pragma comment(linker, "/EXPORT:SaslIdentifyPackageA=secur32.SaslIdentifyPackageA") +#pragma comment(linker, "/EXPORT:SaslIdentifyPackageW=secur32.SaslIdentifyPackageW") +#pragma comment(linker, "/EXPORT:SaslInitializeSecurityContextA=secur32.SaslInitializeSecurityContextA") +#pragma comment(linker, "/EXPORT:SaslInitializeSecurityContextW=secur32.SaslInitializeSecurityContextW") +#pragma comment(linker, "/EXPORT:SaslSetContextOption=secur32.SaslSetContextOption") +#pragma comment(linker, "/EXPORT:SealMessage=secur32.SealMessage") +#pragma comment(linker, "/EXPORT:SeciAllocateAndSetCallFlags=secur32.SeciAllocateAndSetCallFlags") +#pragma comment(linker, "/EXPORT:SeciAllocateAndSetIPAddress=secur32.SeciAllocateAndSetIPAddress") +#pragma comment(linker, "/EXPORT:SeciFreeCallContext=secur32.SeciFreeCallContext") +#pragma comment(linker, "/EXPORT:SecpFreeMemory=secur32.SecpFreeMemory") +#pragma comment(linker, "/EXPORT:SecpTranslateName=secur32.SecpTranslateName") +#pragma comment(linker, "/EXPORT:SecpTranslateNameEx=secur32.SecpTranslateNameEx") +#pragma comment(linker, "/EXPORT:SetContextAttributesA=secur32.SetContextAttributesA") +#pragma comment(linker, "/EXPORT:SetContextAttributesW=secur32.SetContextAttributesW") +#pragma comment(linker, "/EXPORT:SetCredentialsAttributesA=secur32.SetCredentialsAttributesA") +#pragma comment(linker, "/EXPORT:SetCredentialsAttributesW=secur32.SetCredentialsAttributesW") +#pragma comment(linker, "/EXPORT:SspiCompareAuthIdentities=secur32.SspiCompareAuthIdentities") +#pragma comment(linker, "/EXPORT:SspiCopyAuthIdentity=secur32.SspiCopyAuthIdentity") +#pragma comment(linker, "/EXPORT:SspiDecryptAuthIdentity=secur32.SspiDecryptAuthIdentity") +#pragma comment(linker, "/EXPORT:SspiEncodeAuthIdentityAsStrings=secur32.SspiEncodeAuthIdentityAsStrings") +#pragma comment(linker, "/EXPORT:SspiEncodeStringsAsAuthIdentity=secur32.SspiEncodeStringsAsAuthIdentity") +#pragma comment(linker, "/EXPORT:SspiEncryptAuthIdentity=secur32.SspiEncryptAuthIdentity") +#pragma comment(linker, "/EXPORT:SspiExcludePackage=secur32.SspiExcludePackage") +#pragma comment(linker, "/EXPORT:SspiFreeAuthIdentity=secur32.SspiFreeAuthIdentity") +#pragma comment(linker, "/EXPORT:SspiGetTargetHostName=secur32.SspiGetTargetHostName") +#pragma comment(linker, "/EXPORT:SspiIsAuthIdentityEncrypted=secur32.SspiIsAuthIdentityEncrypted") +#pragma comment(linker, "/EXPORT:SspiLocalFree=secur32.SspiLocalFree") +#pragma comment(linker, "/EXPORT:SspiMarshalAuthIdentity=secur32.SspiMarshalAuthIdentity") +#pragma comment(linker, "/EXPORT:SspiPrepareForCredRead=secur32.SspiPrepareForCredRead") +#pragma comment(linker, "/EXPORT:SspiPrepareForCredWrite=secur32.SspiPrepareForCredWrite") +#pragma comment(linker, "/EXPORT:SspiUnmarshalAuthIdentity=secur32.SspiUnmarshalAuthIdentity") +#pragma comment(linker, "/EXPORT:SspiValidateAuthIdentity=secur32.SspiValidateAuthIdentity") +#pragma comment(linker, "/EXPORT:SspiZeroAuthIdentity=secur32.SspiZeroAuthIdentity") +#pragma comment(linker, "/EXPORT:TranslateNameA=secur32.TranslateNameA") +#pragma comment(linker, "/EXPORT:TranslateNameW=secur32.TranslateNameW") +#pragma comment(linker, "/EXPORT:UnsealMessage=secur32.UnsealMessage") +#pragma comment(linker, "/EXPORT:VerifySignature=secur32.VerifySignature") diff --git a/01-Extended DLLs/KxCryp/kxcryp.def b/01-Extended DLLs/KxCryp/kxcryp.def new file mode 100644 index 0000000..2863b34 --- /dev/null +++ b/01-Extended DLLs/KxCryp/kxcryp.def @@ -0,0 +1,11 @@ +LIBRARY KxCryp +EXPORTS + ;; bcrypt.c + BCryptHash + + ;; rng.c + ProcessPrng + + ;; schannel.c +; AcquireCredentialsHandleA = Ext_AcquireCredentialsHandleA + AcquireCredentialsHandleW = Ext_AcquireCredentialsHandleW \ No newline at end of file diff --git a/01-Extended DLLs/KxCryp/kxcryp.rc b/01-Extended DLLs/KxCryp/kxcryp.rc new file mode 100644 index 0000000..39dab31 Binary files /dev/null and b/01-Extended DLLs/KxCryp/kxcryp.rc differ diff --git a/01-Extended DLLs/KxCryp/kxcrypp.h b/01-Extended DLLs/KxCryp/kxcrypp.h new file mode 100644 index 0000000..5721ef5 --- /dev/null +++ b/01-Extended DLLs/KxCryp/kxcrypp.h @@ -0,0 +1,78 @@ +#include "buildcfg.h" +#include +#include + +#define SECURITY_WIN32 +#include +#include + +EXTERN PKEX_PROCESS_DATA KexData; + +#define IOCTL_KSEC_RANDOM_FILL_BUFFER CTL_CODE(FILE_DEVICE_KSEC, 0x02, METHOD_BUFFERED, FILE_ANY_ACCESS) + +typedef enum _TLS_ALGORITHM_USAGE { + TlsParametersCngAlgUsageKeyExchange, // Key exchange algorithm. RSA, ECHDE, DHE, etc. + TlsParametersCngAlgUsageSignature, // Signature algorithm. RSA, DSA, ECDSA, etc. + TlsParametersCngAlgUsageCipher, // Encryption algorithm. AES, DES, RC4, etc. + TlsParametersCngAlgUsageDigest, // Digest of cipher suite. SHA1, SHA256, SHA384, etc. + TlsParametersCngAlgUsageCertSig // Signature and/or hash used to sign certificate. RSA, DSA, ECDSA, SHA1, SHA256, etc. +} TYPEDEF_TYPE_NAME(TLS_ALGORITHM_USAGE); + +typedef struct _CRYPTO_SETTINGS { + TLS_ALGORITHM_USAGE AlgorithmUSage; + UNICODE_STRING AlgorithmId; + ULONG NumberOfChainingModes; + PUNICODE_STRING ChainingModes; + ULONG MinimumBitLength; + ULONG MaximumBitLength; +} TYPEDEF_TYPE_NAME(CRYPTO_SETTINGS); + +typedef struct _TLS_PARAMETERS { + ULONG NumberOfAlpnIds; + PUNICODE_STRING AlpnIds; + ULONG DisabledProtocols; // bit field + ULONG NumberOfCryptoSettings; + PCRYPTO_SETTINGS DisabledCryptoAlgorithms; + ULONG Flags; +} TYPEDEF_TYPE_NAME(TLS_PARAMETERS); + +#define SCH_CRED_V4 4 +#define SCH_CRED_V5 5 + +// added in win8 +#define SCH_SEND_AUX_RECORD 0x00200000 + +#define SCH_WIN7_VALID_FLAGS (SCH_CRED_NO_SYSTEM_MAPPER | \ + SCH_CRED_NO_SERVERNAME_CHECK | \ + SCH_CRED_MANUAL_CRED_VALIDATION | \ + SCH_CRED_NO_DEFAULT_CREDS | \ + SCH_CRED_AUTO_CRED_VALIDATION | \ + SCH_CRED_USE_DEFAULT_CREDS | \ + SCH_CRED_DISABLE_RECONNECTS | \ + SCH_CRED_REVOCATION_CHECK_END_CERT | \ + SCH_CRED_REVOCATION_CHECK_CHAIN | \ + SCH_CRED_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT | \ + SCH_CRED_IGNORE_NO_REVOCATION_CHECK | \ + SCH_CRED_IGNORE_REVOCATION_OFFLINE | \ + SCH_CRED_RESTRICTED_ROOTS | \ + SCH_CRED_REVOCATION_CHECK_CACHE_ONLY | \ + SCH_CRED_CACHE_ONLY_URL_RETRIEVAL | \ + SCH_CRED_MEMORY_STORE_CERT | \ + SCH_CRED_CACHE_ONLY_URL_RETRIEVAL_ON_CREATE | \ + SCH_SEND_ROOT_CERT) + +// This is the Win10+ version of SCHANNEL_CRED. +// The naming scheme is retarded. +typedef struct _SCH_CREDENTIALS { + ULONG Version; // always 5 (SCH_CRED_V5) + ULONG CredentialsFormat; + ULONG NumberOfCertificateContexts; + PCCERT_CONTEXT *CertificateContexts; + HCERTSTORE RootStore; + ULONG NumberOfMappers; + struct _HMAPPER **Mappers; + ULONG SessionLifespan; + ULONG Flags; + ULONG NumberOfTlsParameters; + PTLS_PARAMETERS TlsParameters; +} TYPEDEF_TYPE_NAME(SCH_CREDENTIALS); \ No newline at end of file diff --git a/01-Extended DLLs/KxCryp/rng.c b/01-Extended DLLs/KxCryp/rng.c new file mode 100644 index 0000000..96cd8f9 --- /dev/null +++ b/01-Extended DLLs/KxCryp/rng.c @@ -0,0 +1,74 @@ +#include "buildcfg.h" +#include "kxcrypp.h" + +STATIC HANDLE KsecDD = NULL; + +STATIC NTSTATUS InitializeRng( + VOID) +{ + NTSTATUS Status; + UNICODE_STRING DeviceName; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + + RtlInitConstantUnicodeString(&DeviceName, L"\\Device\\KsecDD"); + + InitializeObjectAttributes( + &ObjectAttributes, + &DeviceName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = NtOpenFile( + &KsecDD, + FILE_READ_DATA | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + FILE_SYNCHRONOUS_IO_NONALERT); + + ASSERT (NT_SUCCESS(Status)); + ASSERT (VALID_HANDLE(KsecDD)); + + return Status; +} + +// +// This function creates random data and places it into the specified +// buffer. +// +KXCRYPAPI BOOL WINAPI ProcessPrng( + OUT PBYTE Buffer, + IN SIZE_T BufferCb) +{ + NTSTATUS Status; + IO_STATUS_BLOCK IoStatusBlock; + + ASSERT (Buffer != NULL); + ASSERT (BufferCb <= ULONG_MAX); + + if (!KsecDD) { + Status = InitializeRng(); + if (!NT_SUCCESS(Status)) { + return FALSE; + } + } + + ASSERT (VALID_HANDLE(KsecDD)); + + Status = NtDeviceIoControlFile( + KsecDD, + NULL, + NULL, + NULL, + &IoStatusBlock, + IOCTL_KSEC_RANDOM_FILL_BUFFER, + NULL, + 0, + Buffer, + (ULONG) BufferCb); + + ASSERT (NT_SUCCESS(Status)); + return NT_SUCCESS(Status); +} \ No newline at end of file diff --git a/01-Extended DLLs/KxCryp/schannel.c b/01-Extended DLLs/KxCryp/schannel.c new file mode 100644 index 0000000..18c4953 --- /dev/null +++ b/01-Extended DLLs/KxCryp/schannel.c @@ -0,0 +1,101 @@ +#include "buildcfg.h" +#include "kxcrypp.h" + +// +// TODO: Implement the ANSI version of this function. +// + +KXCRYPAPI SECURITY_STATUS SEC_ENTRY Ext_AcquireCredentialsHandleW( + IN PWSTR Principal OPTIONAL, + IN PWSTR Package, + IN ULONG CredentialUseFlags, // SECPKG_CRED_* + IN PLUID LogonId OPTIONAL, + IN PVOID AuthData OPTIONAL, + IN SEC_GET_KEY_FN GetKeyFunction OPTIONAL, + IN PVOID GetKeyFunctionArgument OPTIONAL, + OUT PCredHandle CredentialHandle, + OUT PTimeStamp ExpiryTime OPTIONAL) +{ + SECURITY_STATUS SecurityStatus; + PSCH_CREDENTIALS Credentials; + SCHANNEL_CRED ConvertedCredentials; + + if (StringEqual(Package, UNISP_NAME) && AuthData != NULL) { + Credentials = (PSCH_CREDENTIALS) AuthData; + + // + // The target application is using the SChannel SSP. + // + + if (Credentials->Version == SCH_CRED_V5) { + // + // Win10+ version of the structure. We need to convert the + // SCH_CREDENTIALS structure into a SCHANNEL_CRED structure. + // + + RtlZeroMemory(&ConvertedCredentials, sizeof(ConvertedCredentials)); + ConvertedCredentials.dwVersion = SCH_CRED_V4; + ConvertedCredentials.cCreds = Credentials->NumberOfCertificateContexts; + ConvertedCredentials.paCred = Credentials->CertificateContexts; + ConvertedCredentials.hRootStore = Credentials->RootStore; + ConvertedCredentials.cMappers = Credentials->NumberOfMappers; + ConvertedCredentials.aphMappers = Credentials->Mappers; + ConvertedCredentials.dwSessionLifespan = Credentials->SessionLifespan; + ConvertedCredentials.dwFlags = Credentials->Flags & SCH_WIN7_VALID_FLAGS; + + ASSERT ((Credentials->Flags & ~SCH_WIN7_VALID_FLAGS) == 0); + ASSERT (Credentials->NumberOfTlsParameters <= 1); + + if (Credentials->NumberOfTlsParameters >= 1 && + Credentials->TlsParameters != NULL) { + + PTLS_PARAMETERS TlsParameters; + + TlsParameters = Credentials->TlsParameters; + + ASSERT (TlsParameters->NumberOfAlpnIds == 0); + ASSERT (TlsParameters->AlpnIds == NULL); + + ConvertedCredentials.grbitEnabledProtocols = ~(TlsParameters->DisabledProtocols); + } + + // + // Make AcquireCredentialsHandleW use the structure we made. + // + + AuthData = &ConvertedCredentials; + KexLogDebugEvent(L"Converted v5 SChannel credentials structure to v4."); + } else if (Credentials->Version > SCH_CRED_V5) { + // + // This could be a bug in the target application, or it could be + // some future version of the structure they will make in newer + // versions of Windows. Who knows what it will be named. Probably + // something ridiculous like SCHANL_CREDS. + // + + KexLogWarningEvent( + L"SChannel credentials structure version is too high.\r\n\r\n" + L"The application is requesting version %lu.", + Credentials->Version); + + KexDebugCheckpoint(); + } + } + + SecurityStatus = AcquireCredentialsHandle( + Principal, + Package, + CredentialUseFlags, + LogonId, + AuthData, + GetKeyFunction, + GetKeyFunctionArgument, + CredentialHandle, + ExpiryTime); + + if (SecurityStatus != SEC_E_OK) { + KexDebugCheckpoint(); + } + + return SecurityStatus; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxDx/KxDx.rc b/01-Extended DLLs/KxDx/KxDx.rc new file mode 100644 index 0000000..38f2525 Binary files /dev/null and b/01-Extended DLLs/KxDx/KxDx.rc differ diff --git a/01-Extended DLLs/KxDx/KxDx.vcxproj b/01-Extended DLLs/KxDx/KxDx.vcxproj new file mode 100644 index 0000000..d1f9f2a --- /dev/null +++ b/01-Extended DLLs/KxDx/KxDx.vcxproj @@ -0,0 +1,240 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {8C66849E-892F-41DD-AF5D-11DC22FCA013} + Win32Proj + KxDx + + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + + + + + + + + + + + + + + + + + false + false + + + false + false + + + false + false + + + false + false + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;KXDX_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + false + false + Default + false + StdCall + CompileAsC + + + Windows + true + kxdx.def + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + DllMain + true + + + $(SolutionDir)\00-Common Headers + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;KXDX_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + false + false + Default + false + StdCall + CompileAsC + + + Windows + true + kxdx.def + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + DllMain + true + + + $(SolutionDir)\00-Common Headers + + + + + Level3 + NotUsing + MinSpace + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;KXDX_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + false + false + Default + false + StdCall + CompileAsC + OnlyExplicitInline + Size + true + + + Windows + true + true + true + kxdx.def + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + DllMain + true + + + $(SolutionDir)\00-Common Headers + + + + + Level3 + NotUsing + MinSpace + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;KXDX_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + false + false + Default + false + StdCall + CompileAsC + OnlyExplicitInline + Size + true + + + Windows + true + true + true + kxdx.def + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + DllMain + true + + + $(SolutionDir)\00-Common Headers + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/01-Extended DLLs/KxDx/KxDx.vcxproj.filters b/01-Extended DLLs/KxDx/KxDx.vcxproj.filters new file mode 100644 index 0000000..5d1d01b --- /dev/null +++ b/01-Extended DLLs/KxDx/KxDx.vcxproj.filters @@ -0,0 +1,55 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Source Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/01-Extended DLLs/KxDx/buildcfg.h b/01-Extended DLLs/KxDx/buildcfg.h new file mode 100644 index 0000000..c2cdf52 --- /dev/null +++ b/01-Extended DLLs/KxDx/buildcfg.h @@ -0,0 +1,47 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN +#define NOGDICAPMASKS +#define NOVIRTUALKEYCODES +#define NOWINSTYLES +#define NOSYSMETRICS +#define NOMENUS +#define NOICONS +#define NOKEYSTATES +#define NOSYSCOMMANDS +#define NORASTEROPS +#define NOSHOWWINDOW +#define NOATOM +#define NOCLIPBOARD +#define NOCOLOR +#define NODRAWTEXT +#define NOGDI +#define NOKERNEL +#define NONLS +#define NOMB +#define NOMEMMGR +#define NOOPENFILE +#define NOSCROLL +#define NOTEXTMETRIC +#define NOWH +#define NOWINOFFSETS +#define NOCOMM +#define NOKANJI +#define NOHELP +#define NOPROFILER +#define NODEFERWINDOWPOS +#define NOMCX +#define NOCRYPT +#define NOMETAFILE +#define NOSERVICE +#define NOSOUND +#define _UXTHEME_H_ + +#define KXDXAPI + +#pragma comment(lib, "dxgi.lib") +#pragma comment(lib, "oleaut32.lib") + +#define KEX_ENV_WIN32 +#define KEX_TARGET_TYPE_DLL +#define KEX_COMPONENT L"KxDx" diff --git a/01-Extended DLLs/KxDx/dllmain.c b/01-Extended DLLs/KxDx/dllmain.c new file mode 100644 index 0000000..a1f4d16 --- /dev/null +++ b/01-Extended DLLs/KxDx/dllmain.c @@ -0,0 +1,19 @@ +#include "buildcfg.h" +#include "kxdxp.h" + +PKEX_PROCESS_DATA KexData = NULL; + +BOOL WINAPI DllMain( + IN PVOID DllBase, + IN ULONG Reason, + IN PCONTEXT Context) +{ + if (Reason == DLL_PROCESS_ATTACH) { + LdrDisableThreadCalloutsForDll(DllBase); + + KexDataInitialize(&KexData); + KexLogDebugEvent(L"DllMain called with DLL_PROCESS_ATTACH"); + } + + return TRUE; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxDx/dx12stub.c b/01-Extended DLLs/KxDx/dx12stub.c new file mode 100644 index 0000000..116cb0e --- /dev/null +++ b/01-Extended DLLs/KxDx/dx12stub.c @@ -0,0 +1,109 @@ +#include "buildcfg.h" +#include "kxdxp.h" +#include + +// +// These stubs are intended for applications that have d3d12.dll in the import table, +// but do not actually call them. (Or for applications that have a fallback in case +// D3D12 is not available.) +// + +KXDXAPI HRESULT WINAPI D3D12CreateDevice( + IN IUnknown *Adapter OPTIONAL, + IN D3D_FEATURE_LEVEL MinimumFeatureLevel, + IN REFIID RefIID, + OUT PPVOID Device OPTIONAL) +{ + if (Device) { + *Device = NULL; + } + + return DXGI_ERROR_UNSUPPORTED; +} + +KXDXAPI HRESULT WINAPI D3D12CreateRootSignatureDeserializer( + IN PCVOID SourceData, + IN SIZE_T SourceDataCb, + IN REFIID RefIID, + OUT PPVOID Deserializer) +{ + if (Deserializer) { + *Deserializer = NULL; + } + + return DXGI_ERROR_UNSUPPORTED; +} + +KXDXAPI HRESULT WINAPI D3D12CreateVersionedRootSignatureDeserializer( + IN PCVOID SourceData, + IN SIZE_T SourceDataCb, + IN REFIID RefIID, + OUT PPVOID Deserializer) +{ + if (Deserializer) { + *Deserializer = NULL; + } + + return DXGI_ERROR_UNSUPPORTED; +} + +KXDXAPI HRESULT WINAPI D3D12EnableExperimentalFeatures( + IN ULONG NumberOfFeatures, + IN REFIID *RefIIDs, + IN PVOID ConfigurationStructs, + IN PULONG ConfigurationStructSizes) +{ + return DXGI_ERROR_UNSUPPORTED; +} + +KXDXAPI HRESULT WINAPI D3D12GetDebugInterface( + IN REFIID RefIID, + OUT PPVOID DebugInterface OPTIONAL) +{ + if (DebugInterface) { + *DebugInterface = NULL; + } + + return E_NOINTERFACE; +} + +KXDXAPI HRESULT WINAPI D3D12GetInterface( + IN REFCLSID RefCLSID, + IN REFIID RefIID, + OUT PPVOID Interface OPTIONAL) +{ + if (Interface) { + *Interface = NULL; + } + + return E_NOINTERFACE; +} + +KXDXAPI HRESULT WINAPI D3D12SerializeRootSignature( + IN PVOID RootSignature, + IN ULONG Version, + OUT PPVOID Blob, + OUT PPVOID ErrorBlob OPTIONAL) +{ + *Blob = NULL; + + if (ErrorBlob) { + *ErrorBlob = NULL; + } + + return E_NOTIMPL; +} + +KXDXAPI HRESULT WINAPI D3D12SerializeVersionedRootSignature( + IN PVOID RootSignature, + OUT PPVOID Blob, + OUT PPVOID ErrorBlob OPTIONAL) +{ + *Blob = NULL; + + if (ErrorBlob) { + *ErrorBlob = NULL; + } + + return E_NOTIMPL; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxDx/factory.c b/01-Extended DLLs/KxDx/factory.c new file mode 100644 index 0000000..b326777 --- /dev/null +++ b/01-Extended DLLs/KxDx/factory.c @@ -0,0 +1,58 @@ +#include "buildcfg.h" +#include "kxdxp.h" +#include +#include + +// +// Function introduced in Windows 8.1. +// The IDXGIFactory2 interface is actually supported in Windows 7 but only with +// Platform Update. +// +HRESULT WINAPI CreateDXGIFactory2( + IN ULONG Flags, + IN REFIID RefIID, + OUT PPVOID Factory) +{ + HRESULT Result; + + Result = CreateDXGIFactory1( + RefIID, + Factory); + + if (FAILED(Result)) { + if (IsEqualIID(RefIID, &IID_IDXGIFactory2)) { + KexLogErrorEvent( + L"Failed to create IDXGIFactory2\r\n\r\n" + L"HRESULT error code: 0x%08lx: %s\r\n" + L"This interface is only supported by Windows 7 with Platform Update. " + L"In order to solve this error, install Platform Update.", + Result, Win32ErrorAsString(Result)); + } else { + HRESULT Result2; + BSTR IidAsString; + + // + // TODO: Paint.NET depends on IDXGIFactory7. + // See if we can implement that in a satisfactory way. + // + + Result2 = StringFromIID(RefIID, &IidAsString); + ASSERT (SUCCEEDED(Result2)); + + if (FAILED(Result2)) { + IidAsString = L"{unknown}"; + } + + KexLogErrorEvent( + L"Failed to create DXGI factory: %s\r\n\r\n" + L"HRESULT error code: 0x%08lx: %s", + IidAsString, + Result, Win32ErrorAsString(Result)); + + KexDebugCheckpoint(); + SysFreeString(IidAsString); + } + } + + return Result; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxDx/forwards.c b/01-Extended DLLs/KxDx/forwards.c new file mode 100644 index 0000000..1d5052f --- /dev/null +++ b/01-Extended DLLs/KxDx/forwards.c @@ -0,0 +1,426 @@ +#ifdef _M_X64 +// Generated by KexExprt from "C:\Windows\system32\dxgi.dll" +#pragma comment(linker, "/EXPORT:CheckETWTLS=dxgi.CheckETWTLS") +#pragma comment(linker, "/EXPORT:CompatString=dxgi.CompatString") +#pragma comment(linker, "/EXPORT:CompatValue=dxgi.CompatValue") +#pragma comment(linker, "/EXPORT:CreateDXGIFactory=dxgi.CreateDXGIFactory") +#pragma comment(linker, "/EXPORT:CreateDXGIFactory1=dxgi.CreateDXGIFactory1") +#pragma comment(linker, "/EXPORT:D3DKMTCloseAdapter=dxgi.D3DKMTCloseAdapter") +#pragma comment(linker, "/EXPORT:D3DKMTCreateAllocation=dxgi.D3DKMTCreateAllocation") +#pragma comment(linker, "/EXPORT:D3DKMTCreateContext=dxgi.D3DKMTCreateContext") +#pragma comment(linker, "/EXPORT:D3DKMTCreateDevice=dxgi.D3DKMTCreateDevice") +#pragma comment(linker, "/EXPORT:D3DKMTCreateSynchronizationObject=dxgi.D3DKMTCreateSynchronizationObject") +#pragma comment(linker, "/EXPORT:D3DKMTDestroyAllocation=dxgi.D3DKMTDestroyAllocation") +#pragma comment(linker, "/EXPORT:D3DKMTDestroyContext=dxgi.D3DKMTDestroyContext") +#pragma comment(linker, "/EXPORT:D3DKMTDestroyDevice=dxgi.D3DKMTDestroyDevice") +#pragma comment(linker, "/EXPORT:D3DKMTDestroySynchronizationObject=dxgi.D3DKMTDestroySynchronizationObject") +#pragma comment(linker, "/EXPORT:D3DKMTEscape=dxgi.D3DKMTEscape") +#pragma comment(linker, "/EXPORT:D3DKMTGetContextSchedulingPriority=dxgi.D3DKMTGetContextSchedulingPriority") +#pragma comment(linker, "/EXPORT:D3DKMTGetDeviceState=dxgi.D3DKMTGetDeviceState") +#pragma comment(linker, "/EXPORT:D3DKMTGetDisplayModeList=dxgi.D3DKMTGetDisplayModeList") +#pragma comment(linker, "/EXPORT:D3DKMTGetMultisampleMethodList=dxgi.D3DKMTGetMultisampleMethodList") +#pragma comment(linker, "/EXPORT:D3DKMTGetRuntimeData=dxgi.D3DKMTGetRuntimeData") +#pragma comment(linker, "/EXPORT:D3DKMTGetSharedPrimaryHandle=dxgi.D3DKMTGetSharedPrimaryHandle") +#pragma comment(linker, "/EXPORT:D3DKMTLock=dxgi.D3DKMTLock") +#pragma comment(linker, "/EXPORT:D3DKMTOpenAdapterFromHdc=dxgi.D3DKMTOpenAdapterFromHdc") +#pragma comment(linker, "/EXPORT:D3DKMTOpenResource=dxgi.D3DKMTOpenResource") +#pragma comment(linker, "/EXPORT:D3DKMTPresent=dxgi.D3DKMTPresent") +#pragma comment(linker, "/EXPORT:D3DKMTQueryAdapterInfo=dxgi.D3DKMTQueryAdapterInfo") +#pragma comment(linker, "/EXPORT:D3DKMTQueryAllocationResidency=dxgi.D3DKMTQueryAllocationResidency") +#pragma comment(linker, "/EXPORT:D3DKMTQueryResourceInfo=dxgi.D3DKMTQueryResourceInfo") +#pragma comment(linker, "/EXPORT:D3DKMTRender=dxgi.D3DKMTRender") +#pragma comment(linker, "/EXPORT:D3DKMTSetAllocationPriority=dxgi.D3DKMTSetAllocationPriority") +#pragma comment(linker, "/EXPORT:D3DKMTSetContextSchedulingPriority=dxgi.D3DKMTSetContextSchedulingPriority") +#pragma comment(linker, "/EXPORT:D3DKMTSetDisplayMode=dxgi.D3DKMTSetDisplayMode") +#pragma comment(linker, "/EXPORT:D3DKMTSetDisplayPrivateDriverFormat=dxgi.D3DKMTSetDisplayPrivateDriverFormat") +#pragma comment(linker, "/EXPORT:D3DKMTSetGammaRamp=dxgi.D3DKMTSetGammaRamp") +#pragma comment(linker, "/EXPORT:D3DKMTSetVidPnSourceOwner=dxgi.D3DKMTSetVidPnSourceOwner") +#pragma comment(linker, "/EXPORT:D3DKMTSignalSynchronizationObject=dxgi.D3DKMTSignalSynchronizationObject") +#pragma comment(linker, "/EXPORT:D3DKMTUnlock=dxgi.D3DKMTUnlock") +#pragma comment(linker, "/EXPORT:D3DKMTWaitForSynchronizationObject=dxgi.D3DKMTWaitForSynchronizationObject") +#pragma comment(linker, "/EXPORT:D3DKMTWaitForVerticalBlankEvent=dxgi.D3DKMTWaitForVerticalBlankEvent") +#pragma comment(linker, "/EXPORT:DXGID3D10CreateDevice=dxgi.DXGID3D10CreateDevice") +#pragma comment(linker, "/EXPORT:DXGID3D10CreateLayeredDevice=dxgi.DXGID3D10CreateLayeredDevice") +#pragma comment(linker, "/EXPORT:DXGID3D10ETWRundown=dxgi.DXGID3D10ETWRundown") +#pragma comment(linker, "/EXPORT:DXGID3D10GetLayeredDeviceSize=dxgi.DXGID3D10GetLayeredDeviceSize") +#pragma comment(linker, "/EXPORT:DXGID3D10RegisterLayers=dxgi.DXGID3D10RegisterLayers") +#pragma comment(linker, "/EXPORT:DXGIDumpJournal=dxgi.DXGIDumpJournal") +#pragma comment(linker, "/EXPORT:DXGIReportAdapterConfiguration=dxgi.DXGIReportAdapterConfiguration") +#pragma comment(linker, "/EXPORT:DXGIRevertToSxS=dxgi.DXGIRevertToSxS") +#pragma comment(linker, "/EXPORT:OpenAdapter10=dxgi.OpenAdapter10") +#pragma comment(linker, "/EXPORT:OpenAdapter10_2=dxgi.OpenAdapter10_2") +#pragma comment(linker, "/EXPORT:SetAppCompatStringPointer=dxgi.SetAppCompatStringPointer") + +// Generated by KexExprt from "C:\Windows\system32\MFPlat.dll" +#pragma comment(linker, "/EXPORT:CopyPropVariant=MFPlat.CopyPropVariant") +#pragma comment(linker, "/EXPORT:CreatePropVariant=MFPlat.CreatePropVariant") +#pragma comment(linker, "/EXPORT:CreatePropertyStore=MFPlat.CreatePropertyStore") +#pragma comment(linker, "/EXPORT:DestroyPropVariant=MFPlat.DestroyPropVariant") +#pragma comment(linker, "/EXPORT:FormatTagFromWfx=MFPlat.FormatTagFromWfx") +#pragma comment(linker, "/EXPORT:GetAMSubtypeFromD3DFormat=MFPlat.GetAMSubtypeFromD3DFormat") +#pragma comment(linker, "/EXPORT:GetD3DFormatFromMFSubtype=MFPlat.GetD3DFormatFromMFSubtype") +#pragma comment(linker, "/EXPORT:LFGetGlobalPool=MFPlat.LFGetGlobalPool") +#pragma comment(linker, "/EXPORT:MFAddPeriodicCallback=MFPlat.MFAddPeriodicCallback") +#pragma comment(linker, "/EXPORT:MFAllocateWorkQueue=MFPlat.MFAllocateWorkQueue") +#pragma comment(linker, "/EXPORT:MFAllocateWorkQueueEx=MFPlat.MFAllocateWorkQueueEx") +#pragma comment(linker, "/EXPORT:MFAppendCollection=MFPlat.MFAppendCollection") +#pragma comment(linker, "/EXPORT:MFAverageTimePerFrameToFrameRate=MFPlat.MFAverageTimePerFrameToFrameRate") +#pragma comment(linker, "/EXPORT:MFBeginCreateFile=MFPlat.MFBeginCreateFile") +#pragma comment(linker, "/EXPORT:MFBeginGetHostByName=MFPlat.MFBeginGetHostByName") +#pragma comment(linker, "/EXPORT:MFBeginRegisterWorkQueueWithMMCSS=MFPlat.MFBeginRegisterWorkQueueWithMMCSS") +#pragma comment(linker, "/EXPORT:MFBeginUnregisterWorkQueueWithMMCSS=MFPlat.MFBeginUnregisterWorkQueueWithMMCSS") +#pragma comment(linker, "/EXPORT:MFBlockThread=MFPlat.MFBlockThread") +#pragma comment(linker, "/EXPORT:MFCalculateBitmapImageSize=MFPlat.MFCalculateBitmapImageSize") +#pragma comment(linker, "/EXPORT:MFCalculateImageSize=MFPlat.MFCalculateImageSize") +#pragma comment(linker, "/EXPORT:MFCancelCreateFile=MFPlat.MFCancelCreateFile") +#pragma comment(linker, "/EXPORT:MFCancelWorkItem=MFPlat.MFCancelWorkItem") +#pragma comment(linker, "/EXPORT:MFCompareFullToPartialMediaType=MFPlat.MFCompareFullToPartialMediaType") +#pragma comment(linker, "/EXPORT:MFCompareSockaddrAddresses=MFPlat.MFCompareSockaddrAddresses") +#pragma comment(linker, "/EXPORT:MFConvertColorInfoFromDXVA=MFPlat.MFConvertColorInfoFromDXVA") +#pragma comment(linker, "/EXPORT:MFConvertColorInfoToDXVA=MFPlat.MFConvertColorInfoToDXVA") +#pragma comment(linker, "/EXPORT:MFConvertFromFP16Array=MFPlat.MFConvertFromFP16Array") +#pragma comment(linker, "/EXPORT:MFConvertToFP16Array=MFPlat.MFConvertToFP16Array") +#pragma comment(linker, "/EXPORT:MFCopyImage=MFPlat.MFCopyImage") +#pragma comment(linker, "/EXPORT:MFCreateAMMediaTypeFromMFMediaType=MFPlat.MFCreateAMMediaTypeFromMFMediaType") +#pragma comment(linker, "/EXPORT:MFCreateAlignedMemoryBuffer=MFPlat.MFCreateAlignedMemoryBuffer") +#pragma comment(linker, "/EXPORT:MFCreateAsyncResult=MFPlat.MFCreateAsyncResult") +#pragma comment(linker, "/EXPORT:MFCreateAttributes=MFPlat.MFCreateAttributes") +#pragma comment(linker, "/EXPORT:MFCreateAudioMediaType=MFPlat.MFCreateAudioMediaType") +#pragma comment(linker, "/EXPORT:MFCreateCollection=MFPlat.MFCreateCollection") +#pragma comment(linker, "/EXPORT:MFCreateEventQueue=MFPlat.MFCreateEventQueue") +#pragma comment(linker, "/EXPORT:MFCreateFile=MFPlat.MFCreateFile") +#pragma comment(linker, "/EXPORT:MFCreateGuid=MFPlat.MFCreateGuid") +#pragma comment(linker, "/EXPORT:MFCreateLegacyMediaBufferOnMFMediaBuffer=MFPlat.MFCreateLegacyMediaBufferOnMFMediaBuffer") +#pragma comment(linker, "/EXPORT:MFCreateMFByteStreamOnStream=MFPlat.MFCreateMFByteStreamOnStream") +#pragma comment(linker, "/EXPORT:MFCreateMFVideoFormatFromMFMediaType=MFPlat.MFCreateMFVideoFormatFromMFMediaType") +#pragma comment(linker, "/EXPORT:MFCreateMediaBufferWrapper=MFPlat.MFCreateMediaBufferWrapper") +#pragma comment(linker, "/EXPORT:MFCreateMediaEvent=MFPlat.MFCreateMediaEvent") +#pragma comment(linker, "/EXPORT:MFCreateMediaType=MFPlat.MFCreateMediaType") +#pragma comment(linker, "/EXPORT:MFCreateMediaTypeFromRepresentation=MFPlat.MFCreateMediaTypeFromRepresentation") +#pragma comment(linker, "/EXPORT:MFCreateMemoryBuffer=MFPlat.MFCreateMemoryBuffer") +#pragma comment(linker, "/EXPORT:MFCreateMemoryStream=MFPlat.MFCreateMemoryStream") +#pragma comment(linker, "/EXPORT:MFCreatePathFromURL=MFPlat.MFCreatePathFromURL") +#pragma comment(linker, "/EXPORT:MFCreatePresentationDescriptor=MFPlat.MFCreatePresentationDescriptor") +#pragma comment(linker, "/EXPORT:MFCreateSample=MFPlat.MFCreateSample") +#pragma comment(linker, "/EXPORT:MFCreateSocket=MFPlat.MFCreateSocket") +#pragma comment(linker, "/EXPORT:MFCreateSocketListener=MFPlat.MFCreateSocketListener") +#pragma comment(linker, "/EXPORT:MFCreateSourceResolver=MFPlat.MFCreateSourceResolver") +#pragma comment(linker, "/EXPORT:MFCreateStreamDescriptor=MFPlat.MFCreateStreamDescriptor") +#pragma comment(linker, "/EXPORT:MFCreateSystemTimeSource=MFPlat.MFCreateSystemTimeSource") +#pragma comment(linker, "/EXPORT:MFCreateSystemUnderlyingClock=MFPlat.MFCreateSystemUnderlyingClock") +#pragma comment(linker, "/EXPORT:MFCreateTempFile=MFPlat.MFCreateTempFile") +#pragma comment(linker, "/EXPORT:MFCreateTransformActivate=MFPlat.MFCreateTransformActivate") +#pragma comment(linker, "/EXPORT:MFCreateURLFromPath=MFPlat.MFCreateURLFromPath") +#pragma comment(linker, "/EXPORT:MFCreateUdpSockets=MFPlat.MFCreateUdpSockets") +#pragma comment(linker, "/EXPORT:MFCreateVideoMediaType=MFPlat.MFCreateVideoMediaType") +#pragma comment(linker, "/EXPORT:MFCreateVideoMediaTypeFromBitMapInfoHeader=MFPlat.MFCreateVideoMediaTypeFromBitMapInfoHeader") +#pragma comment(linker, "/EXPORT:MFCreateVideoMediaTypeFromBitMapInfoHeaderEx=MFPlat.MFCreateVideoMediaTypeFromBitMapInfoHeaderEx") +#pragma comment(linker, "/EXPORT:MFCreateVideoMediaTypeFromSubtype=MFPlat.MFCreateVideoMediaTypeFromSubtype") +#pragma comment(linker, "/EXPORT:MFCreateVideoMediaTypeFromVideoInfoHeader=MFPlat.MFCreateVideoMediaTypeFromVideoInfoHeader") +#pragma comment(linker, "/EXPORT:MFCreateVideoMediaTypeFromVideoInfoHeader2=MFPlat.MFCreateVideoMediaTypeFromVideoInfoHeader2") +#pragma comment(linker, "/EXPORT:MFCreateWaveFormatExFromMFMediaType=MFPlat.MFCreateWaveFormatExFromMFMediaType") +#pragma comment(linker, "/EXPORT:MFDeserializeAttributesFromStream=MFPlat.MFDeserializeAttributesFromStream") +#pragma comment(linker, "/EXPORT:MFDeserializeEvent=MFPlat.MFDeserializeEvent") +#pragma comment(linker, "/EXPORT:MFDeserializeMediaTypeFromStream=MFPlat.MFDeserializeMediaTypeFromStream") +#pragma comment(linker, "/EXPORT:MFDeserializePresentationDescriptor=MFPlat.MFDeserializePresentationDescriptor") +#pragma comment(linker, "/EXPORT:MFEndCreateFile=MFPlat.MFEndCreateFile") +#pragma comment(linker, "/EXPORT:MFEndGetHostByName=MFPlat.MFEndGetHostByName") +#pragma comment(linker, "/EXPORT:MFEndRegisterWorkQueueWithMMCSS=MFPlat.MFEndRegisterWorkQueueWithMMCSS") +#pragma comment(linker, "/EXPORT:MFEndUnregisterWorkQueueWithMMCSS=MFPlat.MFEndUnregisterWorkQueueWithMMCSS") +#pragma comment(linker, "/EXPORT:MFFrameRateToAverageTimePerFrame=MFPlat.MFFrameRateToAverageTimePerFrame") +#pragma comment(linker, "/EXPORT:MFFreeAdaptersAddresses=MFPlat.MFFreeAdaptersAddresses") +#pragma comment(linker, "/EXPORT:MFGetAdaptersAddresses=MFPlat.MFGetAdaptersAddresses") +#pragma comment(linker, "/EXPORT:MFGetAttributesAsBlob=MFPlat.MFGetAttributesAsBlob") +#pragma comment(linker, "/EXPORT:MFGetAttributesAsBlobSize=MFPlat.MFGetAttributesAsBlobSize") +#pragma comment(linker, "/EXPORT:MFGetConfigurationDWORD=MFPlat.MFGetConfigurationDWORD") +#pragma comment(linker, "/EXPORT:MFGetConfigurationPolicy=MFPlat.MFGetConfigurationPolicy") +#pragma comment(linker, "/EXPORT:MFGetConfigurationStore=MFPlat.MFGetConfigurationStore") +#pragma comment(linker, "/EXPORT:MFGetConfigurationString=MFPlat.MFGetConfigurationString") +#pragma comment(linker, "/EXPORT:MFGetIoPortHandle=MFPlat.MFGetIoPortHandle") +#pragma comment(linker, "/EXPORT:MFGetMFTMerit=MFPlat.MFGetMFTMerit") +#pragma comment(linker, "/EXPORT:MFGetNumericNameFromSockaddr=MFPlat.MFGetNumericNameFromSockaddr") +#pragma comment(linker, "/EXPORT:MFGetPlaneSize=MFPlat.MFGetPlaneSize") +#pragma comment(linker, "/EXPORT:MFGetPlatform=MFPlat.MFGetPlatform") +#pragma comment(linker, "/EXPORT:MFGetPlatformVersion=MFPlat.MFGetPlatformVersion") +#pragma comment(linker, "/EXPORT:MFGetPluginControl=MFPlat.MFGetPluginControl") +#pragma comment(linker, "/EXPORT:MFGetPrivateWorkqueues=MFPlat.MFGetPrivateWorkqueues") +#pragma comment(linker, "/EXPORT:MFGetRandomNumber=MFPlat.MFGetRandomNumber") +#pragma comment(linker, "/EXPORT:MFGetSockaddrFromNumericName=MFPlat.MFGetSockaddrFromNumericName") +#pragma comment(linker, "/EXPORT:MFGetStrideForBitmapInfoHeader=MFPlat.MFGetStrideForBitmapInfoHeader") +#pragma comment(linker, "/EXPORT:MFGetSystemTime=MFPlat.MFGetSystemTime") +#pragma comment(linker, "/EXPORT:MFGetTimerPeriodicity=MFPlat.MFGetTimerPeriodicity") +#pragma comment(linker, "/EXPORT:MFGetUncompressedVideoFormat=MFPlat.MFGetUncompressedVideoFormat") +#pragma comment(linker, "/EXPORT:MFGetWorkQueueMMCSSClass=MFPlat.MFGetWorkQueueMMCSSClass") +#pragma comment(linker, "/EXPORT:MFGetWorkQueueMMCSSTaskId=MFPlat.MFGetWorkQueueMMCSSTaskId") +#pragma comment(linker, "/EXPORT:MFHeapAlloc=MFPlat.MFHeapAlloc") +#pragma comment(linker, "/EXPORT:MFHeapFree=MFPlat.MFHeapFree") +#pragma comment(linker, "/EXPORT:MFInitAMMediaTypeFromMFMediaType=MFPlat.MFInitAMMediaTypeFromMFMediaType") +#pragma comment(linker, "/EXPORT:MFInitAttributesFromBlob=MFPlat.MFInitAttributesFromBlob") +#pragma comment(linker, "/EXPORT:MFInitMediaTypeFromAMMediaType=MFPlat.MFInitMediaTypeFromAMMediaType") +#pragma comment(linker, "/EXPORT:MFInitMediaTypeFromMFVideoFormat=MFPlat.MFInitMediaTypeFromMFVideoFormat") +#pragma comment(linker, "/EXPORT:MFInitMediaTypeFromMPEG1VideoInfo=MFPlat.MFInitMediaTypeFromMPEG1VideoInfo") +#pragma comment(linker, "/EXPORT:MFInitMediaTypeFromMPEG2VideoInfo=MFPlat.MFInitMediaTypeFromMPEG2VideoInfo") +#pragma comment(linker, "/EXPORT:MFInitMediaTypeFromVideoInfoHeader=MFPlat.MFInitMediaTypeFromVideoInfoHeader") +#pragma comment(linker, "/EXPORT:MFInitMediaTypeFromVideoInfoHeader2=MFPlat.MFInitMediaTypeFromVideoInfoHeader2") +#pragma comment(linker, "/EXPORT:MFInitMediaTypeFromWaveFormatEx=MFPlat.MFInitMediaTypeFromWaveFormatEx") +#pragma comment(linker, "/EXPORT:MFInitVideoFormat=MFPlat.MFInitVideoFormat") +#pragma comment(linker, "/EXPORT:MFInitVideoFormat_RGB=MFPlat.MFInitVideoFormat_RGB") +#pragma comment(linker, "/EXPORT:MFInvokeCallback=MFPlat.MFInvokeCallback") +#pragma comment(linker, "/EXPORT:MFIsFeatureEnabled=MFPlat.MFIsFeatureEnabled") +#pragma comment(linker, "/EXPORT:MFIsQueueThread=MFPlat.MFIsQueueThread") +#pragma comment(linker, "/EXPORT:MFJoinIoPort=MFPlat.MFJoinIoPort") +#pragma comment(linker, "/EXPORT:MFLockPlatform=MFPlat.MFLockPlatform") +#pragma comment(linker, "/EXPORT:MFLockWorkQueue=MFPlat.MFLockWorkQueue") +#pragma comment(linker, "/EXPORT:MFPlatformBigEndian=MFPlat.MFPlatformBigEndian") +#pragma comment(linker, "/EXPORT:MFPlatformLittleEndian=MFPlat.MFPlatformLittleEndian") +#pragma comment(linker, "/EXPORT:MFPutWorkItem=MFPlat.MFPutWorkItem") +#pragma comment(linker, "/EXPORT:MFPutWorkItemEx=MFPlat.MFPutWorkItemEx") +#pragma comment(linker, "/EXPORT:MFRecordError=MFPlat.MFRecordError") +#pragma comment(linker, "/EXPORT:MFRemovePeriodicCallback=MFPlat.MFRemovePeriodicCallback") +#pragma comment(linker, "/EXPORT:MFScheduleWorkItem=MFPlat.MFScheduleWorkItem") +#pragma comment(linker, "/EXPORT:MFScheduleWorkItemEx=MFPlat.MFScheduleWorkItemEx") +#pragma comment(linker, "/EXPORT:MFSerializeAttributesToStream=MFPlat.MFSerializeAttributesToStream") +#pragma comment(linker, "/EXPORT:MFSerializeEvent=MFPlat.MFSerializeEvent") +#pragma comment(linker, "/EXPORT:MFSerializeMediaTypeToStream=MFPlat.MFSerializeMediaTypeToStream") +#pragma comment(linker, "/EXPORT:MFSerializePresentationDescriptor=MFPlat.MFSerializePresentationDescriptor") +#pragma comment(linker, "/EXPORT:MFSetSockaddrAny=MFPlat.MFSetSockaddrAny") +#pragma comment(linker, "/EXPORT:MFShutdown=MFPlat.MFShutdown") +#pragma comment(linker, "/EXPORT:MFStartup=MFPlat.MFStartup") +#pragma comment(linker, "/EXPORT:MFStreamDescriptorProtectMediaType=MFPlat.MFStreamDescriptorProtectMediaType") +#pragma comment(linker, "/EXPORT:MFTEnum=MFPlat.MFTEnum") +#pragma comment(linker, "/EXPORT:MFTEnumEx=MFPlat.MFTEnumEx") +#pragma comment(linker, "/EXPORT:MFTGetInfo=MFPlat.MFTGetInfo") +#pragma comment(linker, "/EXPORT:MFTRegister=MFPlat.MFTRegister") +#pragma comment(linker, "/EXPORT:MFTRegisterLocal=MFPlat.MFTRegisterLocal") +#pragma comment(linker, "/EXPORT:MFTRegisterLocalByCLSID=MFPlat.MFTRegisterLocalByCLSID") +#pragma comment(linker, "/EXPORT:MFTUnregister=MFPlat.MFTUnregister") +#pragma comment(linker, "/EXPORT:MFTUnregisterLocal=MFPlat.MFTUnregisterLocal") +#pragma comment(linker, "/EXPORT:MFTUnregisterLocalByCLSID=MFPlat.MFTUnregisterLocalByCLSID") +#pragma comment(linker, "/EXPORT:MFTraceError=MFPlat.MFTraceError") +#pragma comment(linker, "/EXPORT:MFTraceFuncEnter=MFPlat.MFTraceFuncEnter") +#pragma comment(linker, "/EXPORT:MFUnblockThread=MFPlat.MFUnblockThread") +#pragma comment(linker, "/EXPORT:MFUnlockPlatform=MFPlat.MFUnlockPlatform") +#pragma comment(linker, "/EXPORT:MFUnlockWorkQueue=MFPlat.MFUnlockWorkQueue") +#pragma comment(linker, "/EXPORT:MFUnwrapMediaType=MFPlat.MFUnwrapMediaType") +#pragma comment(linker, "/EXPORT:MFValidateMediaTypeSize=MFPlat.MFValidateMediaTypeSize") +#pragma comment(linker, "/EXPORT:MFWrapMediaType=MFPlat.MFWrapMediaType") +#pragma comment(linker, "/EXPORT:MFllMulDiv=MFPlat.MFllMulDiv") +#pragma comment(linker, "/EXPORT:PropVariantFromStream=MFPlat.PropVariantFromStream") +#pragma comment(linker, "/EXPORT:PropVariantToStream=MFPlat.PropVariantToStream") +#pragma comment(linker, "/EXPORT:ValidateWaveFormat=MFPlat.ValidateWaveFormat") + + +#else + +// Generated by KexExprt from "C:\Windows\syswow64\dxgi.dll" +#pragma comment(linker, "/EXPORT:CheckETWTLS=dxgi.CheckETWTLS") +#pragma comment(linker, "/EXPORT:CompatString=dxgi.CompatString") +#pragma comment(linker, "/EXPORT:CompatValue=dxgi.CompatValue") +#pragma comment(linker, "/EXPORT:CreateDXGIFactory=dxgi.CreateDXGIFactory") +#pragma comment(linker, "/EXPORT:CreateDXGIFactory1=dxgi.CreateDXGIFactory1") +#pragma comment(linker, "/EXPORT:D3DKMTCloseAdapter=dxgi.D3DKMTCloseAdapter") +#pragma comment(linker, "/EXPORT:D3DKMTCreateAllocation=dxgi.D3DKMTCreateAllocation") +#pragma comment(linker, "/EXPORT:D3DKMTCreateContext=dxgi.D3DKMTCreateContext") +#pragma comment(linker, "/EXPORT:D3DKMTCreateDevice=dxgi.D3DKMTCreateDevice") +#pragma comment(linker, "/EXPORT:D3DKMTCreateSynchronizationObject=dxgi.D3DKMTCreateSynchronizationObject") +#pragma comment(linker, "/EXPORT:D3DKMTDestroyAllocation=dxgi.D3DKMTDestroyAllocation") +#pragma comment(linker, "/EXPORT:D3DKMTDestroyContext=dxgi.D3DKMTDestroyContext") +#pragma comment(linker, "/EXPORT:D3DKMTDestroyDevice=dxgi.D3DKMTDestroyDevice") +#pragma comment(linker, "/EXPORT:D3DKMTDestroySynchronizationObject=dxgi.D3DKMTDestroySynchronizationObject") +#pragma comment(linker, "/EXPORT:D3DKMTEscape=dxgi.D3DKMTEscape") +#pragma comment(linker, "/EXPORT:D3DKMTGetContextSchedulingPriority=dxgi.D3DKMTGetContextSchedulingPriority") +#pragma comment(linker, "/EXPORT:D3DKMTGetDeviceState=dxgi.D3DKMTGetDeviceState") +#pragma comment(linker, "/EXPORT:D3DKMTGetDisplayModeList=dxgi.D3DKMTGetDisplayModeList") +#pragma comment(linker, "/EXPORT:D3DKMTGetMultisampleMethodList=dxgi.D3DKMTGetMultisampleMethodList") +#pragma comment(linker, "/EXPORT:D3DKMTGetRuntimeData=dxgi.D3DKMTGetRuntimeData") +#pragma comment(linker, "/EXPORT:D3DKMTGetSharedPrimaryHandle=dxgi.D3DKMTGetSharedPrimaryHandle") +#pragma comment(linker, "/EXPORT:D3DKMTLock=dxgi.D3DKMTLock") +#pragma comment(linker, "/EXPORT:D3DKMTOpenAdapterFromHdc=dxgi.D3DKMTOpenAdapterFromHdc") +#pragma comment(linker, "/EXPORT:D3DKMTOpenResource=dxgi.D3DKMTOpenResource") +#pragma comment(linker, "/EXPORT:D3DKMTPresent=dxgi.D3DKMTPresent") +#pragma comment(linker, "/EXPORT:D3DKMTQueryAdapterInfo=dxgi.D3DKMTQueryAdapterInfo") +#pragma comment(linker, "/EXPORT:D3DKMTQueryAllocationResidency=dxgi.D3DKMTQueryAllocationResidency") +#pragma comment(linker, "/EXPORT:D3DKMTQueryResourceInfo=dxgi.D3DKMTQueryResourceInfo") +#pragma comment(linker, "/EXPORT:D3DKMTRender=dxgi.D3DKMTRender") +#pragma comment(linker, "/EXPORT:D3DKMTSetAllocationPriority=dxgi.D3DKMTSetAllocationPriority") +#pragma comment(linker, "/EXPORT:D3DKMTSetContextSchedulingPriority=dxgi.D3DKMTSetContextSchedulingPriority") +#pragma comment(linker, "/EXPORT:D3DKMTSetDisplayMode=dxgi.D3DKMTSetDisplayMode") +#pragma comment(linker, "/EXPORT:D3DKMTSetDisplayPrivateDriverFormat=dxgi.D3DKMTSetDisplayPrivateDriverFormat") +#pragma comment(linker, "/EXPORT:D3DKMTSetGammaRamp=dxgi.D3DKMTSetGammaRamp") +#pragma comment(linker, "/EXPORT:D3DKMTSetVidPnSourceOwner=dxgi.D3DKMTSetVidPnSourceOwner") +#pragma comment(linker, "/EXPORT:D3DKMTSignalSynchronizationObject=dxgi.D3DKMTSignalSynchronizationObject") +#pragma comment(linker, "/EXPORT:D3DKMTUnlock=dxgi.D3DKMTUnlock") +#pragma comment(linker, "/EXPORT:D3DKMTWaitForSynchronizationObject=dxgi.D3DKMTWaitForSynchronizationObject") +#pragma comment(linker, "/EXPORT:D3DKMTWaitForVerticalBlankEvent=dxgi.D3DKMTWaitForVerticalBlankEvent") +#pragma comment(linker, "/EXPORT:DXGID3D10CreateDevice=dxgi.DXGID3D10CreateDevice") +#pragma comment(linker, "/EXPORT:DXGID3D10CreateLayeredDevice=dxgi.DXGID3D10CreateLayeredDevice") +#pragma comment(linker, "/EXPORT:DXGID3D10ETWRundown=dxgi.DXGID3D10ETWRundown") +#pragma comment(linker, "/EXPORT:DXGID3D10GetLayeredDeviceSize=dxgi.DXGID3D10GetLayeredDeviceSize") +#pragma comment(linker, "/EXPORT:DXGID3D10RegisterLayers=dxgi.DXGID3D10RegisterLayers") +#pragma comment(linker, "/EXPORT:DXGIDumpJournal=dxgi.DXGIDumpJournal") +#pragma comment(linker, "/EXPORT:DXGIReportAdapterConfiguration=dxgi.DXGIReportAdapterConfiguration") +#pragma comment(linker, "/EXPORT:DXGIRevertToSxS=dxgi.DXGIRevertToSxS") +#pragma comment(linker, "/EXPORT:OpenAdapter10=dxgi.OpenAdapter10") +#pragma comment(linker, "/EXPORT:OpenAdapter10_2=dxgi.OpenAdapter10_2") +#pragma comment(linker, "/EXPORT:SetAppCompatStringPointer=dxgi.SetAppCompatStringPointer") + +// Generated by KexExprt from "C:\Windows\syswow64\MFPlat.dll" +#pragma comment(linker, "/EXPORT:CopyPropVariant=MFPlat.CopyPropVariant") +#pragma comment(linker, "/EXPORT:CreatePropVariant=MFPlat.CreatePropVariant") +#pragma comment(linker, "/EXPORT:CreatePropertyStore=MFPlat.CreatePropertyStore") +#pragma comment(linker, "/EXPORT:DestroyPropVariant=MFPlat.DestroyPropVariant") +#pragma comment(linker, "/EXPORT:FormatTagFromWfx=MFPlat.FormatTagFromWfx") +#pragma comment(linker, "/EXPORT:GetAMSubtypeFromD3DFormat=MFPlat.GetAMSubtypeFromD3DFormat") +#pragma comment(linker, "/EXPORT:GetD3DFormatFromMFSubtype=MFPlat.GetD3DFormatFromMFSubtype") +#pragma comment(linker, "/EXPORT:LFGetGlobalPool=MFPlat.LFGetGlobalPool") +#pragma comment(linker, "/EXPORT:MFAddPeriodicCallback=MFPlat.MFAddPeriodicCallback") +#pragma comment(linker, "/EXPORT:MFAllocateWorkQueue=MFPlat.MFAllocateWorkQueue") +#pragma comment(linker, "/EXPORT:MFAllocateWorkQueueEx=MFPlat.MFAllocateWorkQueueEx") +#pragma comment(linker, "/EXPORT:MFAppendCollection=MFPlat.MFAppendCollection") +#pragma comment(linker, "/EXPORT:MFAverageTimePerFrameToFrameRate=MFPlat.MFAverageTimePerFrameToFrameRate") +#pragma comment(linker, "/EXPORT:MFBeginCreateFile=MFPlat.MFBeginCreateFile") +#pragma comment(linker, "/EXPORT:MFBeginGetHostByName=MFPlat.MFBeginGetHostByName") +#pragma comment(linker, "/EXPORT:MFBeginRegisterWorkQueueWithMMCSS=MFPlat.MFBeginRegisterWorkQueueWithMMCSS") +#pragma comment(linker, "/EXPORT:MFBeginUnregisterWorkQueueWithMMCSS=MFPlat.MFBeginUnregisterWorkQueueWithMMCSS") +#pragma comment(linker, "/EXPORT:MFBlockThread=MFPlat.MFBlockThread") +#pragma comment(linker, "/EXPORT:MFCalculateBitmapImageSize=MFPlat.MFCalculateBitmapImageSize") +#pragma comment(linker, "/EXPORT:MFCalculateImageSize=MFPlat.MFCalculateImageSize") +#pragma comment(linker, "/EXPORT:MFCancelCreateFile=MFPlat.MFCancelCreateFile") +#pragma comment(linker, "/EXPORT:MFCancelWorkItem=MFPlat.MFCancelWorkItem") +#pragma comment(linker, "/EXPORT:MFCompareFullToPartialMediaType=MFPlat.MFCompareFullToPartialMediaType") +#pragma comment(linker, "/EXPORT:MFCompareSockaddrAddresses=MFPlat.MFCompareSockaddrAddresses") +#pragma comment(linker, "/EXPORT:MFConvertColorInfoFromDXVA=MFPlat.MFConvertColorInfoFromDXVA") +#pragma comment(linker, "/EXPORT:MFConvertColorInfoToDXVA=MFPlat.MFConvertColorInfoToDXVA") +#pragma comment(linker, "/EXPORT:MFConvertFromFP16Array=MFPlat.MFConvertFromFP16Array") +#pragma comment(linker, "/EXPORT:MFConvertToFP16Array=MFPlat.MFConvertToFP16Array") +#pragma comment(linker, "/EXPORT:MFCopyImage=MFPlat.MFCopyImage") +#pragma comment(linker, "/EXPORT:MFCreateAMMediaTypeFromMFMediaType=MFPlat.MFCreateAMMediaTypeFromMFMediaType") +#pragma comment(linker, "/EXPORT:MFCreateAlignedMemoryBuffer=MFPlat.MFCreateAlignedMemoryBuffer") +#pragma comment(linker, "/EXPORT:MFCreateAsyncResult=MFPlat.MFCreateAsyncResult") +#pragma comment(linker, "/EXPORT:MFCreateAttributes=MFPlat.MFCreateAttributes") +#pragma comment(linker, "/EXPORT:MFCreateAudioMediaType=MFPlat.MFCreateAudioMediaType") +#pragma comment(linker, "/EXPORT:MFCreateCollection=MFPlat.MFCreateCollection") +#pragma comment(linker, "/EXPORT:MFCreateEventQueue=MFPlat.MFCreateEventQueue") +#pragma comment(linker, "/EXPORT:MFCreateFile=MFPlat.MFCreateFile") +#pragma comment(linker, "/EXPORT:MFCreateGuid=MFPlat.MFCreateGuid") +#pragma comment(linker, "/EXPORT:MFCreateLegacyMediaBufferOnMFMediaBuffer=MFPlat.MFCreateLegacyMediaBufferOnMFMediaBuffer") +#pragma comment(linker, "/EXPORT:MFCreateMFByteStreamOnStream=MFPlat.MFCreateMFByteStreamOnStream") +#pragma comment(linker, "/EXPORT:MFCreateMFVideoFormatFromMFMediaType=MFPlat.MFCreateMFVideoFormatFromMFMediaType") +#pragma comment(linker, "/EXPORT:MFCreateMediaBufferWrapper=MFPlat.MFCreateMediaBufferWrapper") +#pragma comment(linker, "/EXPORT:MFCreateMediaEvent=MFPlat.MFCreateMediaEvent") +#pragma comment(linker, "/EXPORT:MFCreateMediaType=MFPlat.MFCreateMediaType") +#pragma comment(linker, "/EXPORT:MFCreateMediaTypeFromRepresentation=MFPlat.MFCreateMediaTypeFromRepresentation") +#pragma comment(linker, "/EXPORT:MFCreateMemoryBuffer=MFPlat.MFCreateMemoryBuffer") +#pragma comment(linker, "/EXPORT:MFCreateMemoryStream=MFPlat.MFCreateMemoryStream") +#pragma comment(linker, "/EXPORT:MFCreatePathFromURL=MFPlat.MFCreatePathFromURL") +#pragma comment(linker, "/EXPORT:MFCreatePresentationDescriptor=MFPlat.MFCreatePresentationDescriptor") +#pragma comment(linker, "/EXPORT:MFCreateSample=MFPlat.MFCreateSample") +#pragma comment(linker, "/EXPORT:MFCreateSocket=MFPlat.MFCreateSocket") +#pragma comment(linker, "/EXPORT:MFCreateSocketListener=MFPlat.MFCreateSocketListener") +#pragma comment(linker, "/EXPORT:MFCreateSourceResolver=MFPlat.MFCreateSourceResolver") +#pragma comment(linker, "/EXPORT:MFCreateStreamDescriptor=MFPlat.MFCreateStreamDescriptor") +#pragma comment(linker, "/EXPORT:MFCreateSystemTimeSource=MFPlat.MFCreateSystemTimeSource") +#pragma comment(linker, "/EXPORT:MFCreateSystemUnderlyingClock=MFPlat.MFCreateSystemUnderlyingClock") +#pragma comment(linker, "/EXPORT:MFCreateTempFile=MFPlat.MFCreateTempFile") +#pragma comment(linker, "/EXPORT:MFCreateTransformActivate=MFPlat.MFCreateTransformActivate") +#pragma comment(linker, "/EXPORT:MFCreateURLFromPath=MFPlat.MFCreateURLFromPath") +#pragma comment(linker, "/EXPORT:MFCreateUdpSockets=MFPlat.MFCreateUdpSockets") +#pragma comment(linker, "/EXPORT:MFCreateVideoMediaType=MFPlat.MFCreateVideoMediaType") +#pragma comment(linker, "/EXPORT:MFCreateVideoMediaTypeFromBitMapInfoHeader=MFPlat.MFCreateVideoMediaTypeFromBitMapInfoHeader") +#pragma comment(linker, "/EXPORT:MFCreateVideoMediaTypeFromBitMapInfoHeaderEx=MFPlat.MFCreateVideoMediaTypeFromBitMapInfoHeaderEx") +#pragma comment(linker, "/EXPORT:MFCreateVideoMediaTypeFromSubtype=MFPlat.MFCreateVideoMediaTypeFromSubtype") +#pragma comment(linker, "/EXPORT:MFCreateVideoMediaTypeFromVideoInfoHeader=MFPlat.MFCreateVideoMediaTypeFromVideoInfoHeader") +#pragma comment(linker, "/EXPORT:MFCreateVideoMediaTypeFromVideoInfoHeader2=MFPlat.MFCreateVideoMediaTypeFromVideoInfoHeader2") +#pragma comment(linker, "/EXPORT:MFCreateWaveFormatExFromMFMediaType=MFPlat.MFCreateWaveFormatExFromMFMediaType") +#pragma comment(linker, "/EXPORT:MFDeserializeAttributesFromStream=MFPlat.MFDeserializeAttributesFromStream") +#pragma comment(linker, "/EXPORT:MFDeserializeEvent=MFPlat.MFDeserializeEvent") +#pragma comment(linker, "/EXPORT:MFDeserializeMediaTypeFromStream=MFPlat.MFDeserializeMediaTypeFromStream") +#pragma comment(linker, "/EXPORT:MFDeserializePresentationDescriptor=MFPlat.MFDeserializePresentationDescriptor") +#pragma comment(linker, "/EXPORT:MFEndCreateFile=MFPlat.MFEndCreateFile") +#pragma comment(linker, "/EXPORT:MFEndGetHostByName=MFPlat.MFEndGetHostByName") +#pragma comment(linker, "/EXPORT:MFEndRegisterWorkQueueWithMMCSS=MFPlat.MFEndRegisterWorkQueueWithMMCSS") +#pragma comment(linker, "/EXPORT:MFEndUnregisterWorkQueueWithMMCSS=MFPlat.MFEndUnregisterWorkQueueWithMMCSS") +#pragma comment(linker, "/EXPORT:MFFrameRateToAverageTimePerFrame=MFPlat.MFFrameRateToAverageTimePerFrame") +#pragma comment(linker, "/EXPORT:MFFreeAdaptersAddresses=MFPlat.MFFreeAdaptersAddresses") +#pragma comment(linker, "/EXPORT:MFGetAdaptersAddresses=MFPlat.MFGetAdaptersAddresses") +#pragma comment(linker, "/EXPORT:MFGetAttributesAsBlob=MFPlat.MFGetAttributesAsBlob") +#pragma comment(linker, "/EXPORT:MFGetAttributesAsBlobSize=MFPlat.MFGetAttributesAsBlobSize") +#pragma comment(linker, "/EXPORT:MFGetConfigurationDWORD=MFPlat.MFGetConfigurationDWORD") +#pragma comment(linker, "/EXPORT:MFGetConfigurationPolicy=MFPlat.MFGetConfigurationPolicy") +#pragma comment(linker, "/EXPORT:MFGetConfigurationStore=MFPlat.MFGetConfigurationStore") +#pragma comment(linker, "/EXPORT:MFGetConfigurationString=MFPlat.MFGetConfigurationString") +#pragma comment(linker, "/EXPORT:MFGetIoPortHandle=MFPlat.MFGetIoPortHandle") +#pragma comment(linker, "/EXPORT:MFGetMFTMerit=MFPlat.MFGetMFTMerit") +#pragma comment(linker, "/EXPORT:MFGetNumericNameFromSockaddr=MFPlat.MFGetNumericNameFromSockaddr") +#pragma comment(linker, "/EXPORT:MFGetPlaneSize=MFPlat.MFGetPlaneSize") +#pragma comment(linker, "/EXPORT:MFGetPlatform=MFPlat.MFGetPlatform") +#pragma comment(linker, "/EXPORT:MFGetPlatformVersion=MFPlat.MFGetPlatformVersion") +#pragma comment(linker, "/EXPORT:MFGetPluginControl=MFPlat.MFGetPluginControl") +#pragma comment(linker, "/EXPORT:MFGetPrivateWorkqueues=MFPlat.MFGetPrivateWorkqueues") +#pragma comment(linker, "/EXPORT:MFGetRandomNumber=MFPlat.MFGetRandomNumber") +#pragma comment(linker, "/EXPORT:MFGetSockaddrFromNumericName=MFPlat.MFGetSockaddrFromNumericName") +#pragma comment(linker, "/EXPORT:MFGetStrideForBitmapInfoHeader=MFPlat.MFGetStrideForBitmapInfoHeader") +#pragma comment(linker, "/EXPORT:MFGetSystemTime=MFPlat.MFGetSystemTime") +#pragma comment(linker, "/EXPORT:MFGetTimerPeriodicity=MFPlat.MFGetTimerPeriodicity") +#pragma comment(linker, "/EXPORT:MFGetUncompressedVideoFormat=MFPlat.MFGetUncompressedVideoFormat") +#pragma comment(linker, "/EXPORT:MFGetWorkQueueMMCSSClass=MFPlat.MFGetWorkQueueMMCSSClass") +#pragma comment(linker, "/EXPORT:MFGetWorkQueueMMCSSTaskId=MFPlat.MFGetWorkQueueMMCSSTaskId") +#pragma comment(linker, "/EXPORT:MFHeapAlloc=MFPlat.MFHeapAlloc") +#pragma comment(linker, "/EXPORT:MFHeapFree=MFPlat.MFHeapFree") +#pragma comment(linker, "/EXPORT:MFInitAMMediaTypeFromMFMediaType=MFPlat.MFInitAMMediaTypeFromMFMediaType") +#pragma comment(linker, "/EXPORT:MFInitAttributesFromBlob=MFPlat.MFInitAttributesFromBlob") +#pragma comment(linker, "/EXPORT:MFInitMediaTypeFromAMMediaType=MFPlat.MFInitMediaTypeFromAMMediaType") +#pragma comment(linker, "/EXPORT:MFInitMediaTypeFromMFVideoFormat=MFPlat.MFInitMediaTypeFromMFVideoFormat") +#pragma comment(linker, "/EXPORT:MFInitMediaTypeFromMPEG1VideoInfo=MFPlat.MFInitMediaTypeFromMPEG1VideoInfo") +#pragma comment(linker, "/EXPORT:MFInitMediaTypeFromMPEG2VideoInfo=MFPlat.MFInitMediaTypeFromMPEG2VideoInfo") +#pragma comment(linker, "/EXPORT:MFInitMediaTypeFromVideoInfoHeader=MFPlat.MFInitMediaTypeFromVideoInfoHeader") +#pragma comment(linker, "/EXPORT:MFInitMediaTypeFromVideoInfoHeader2=MFPlat.MFInitMediaTypeFromVideoInfoHeader2") +#pragma comment(linker, "/EXPORT:MFInitMediaTypeFromWaveFormatEx=MFPlat.MFInitMediaTypeFromWaveFormatEx") +#pragma comment(linker, "/EXPORT:MFInitVideoFormat=MFPlat.MFInitVideoFormat") +#pragma comment(linker, "/EXPORT:MFInitVideoFormat_RGB=MFPlat.MFInitVideoFormat_RGB") +#pragma comment(linker, "/EXPORT:MFInvokeCallback=MFPlat.MFInvokeCallback") +#pragma comment(linker, "/EXPORT:MFIsFeatureEnabled=MFPlat.MFIsFeatureEnabled") +#pragma comment(linker, "/EXPORT:MFIsQueueThread=MFPlat.MFIsQueueThread") +#pragma comment(linker, "/EXPORT:MFJoinIoPort=MFPlat.MFJoinIoPort") +#pragma comment(linker, "/EXPORT:MFLockPlatform=MFPlat.MFLockPlatform") +#pragma comment(linker, "/EXPORT:MFLockWorkQueue=MFPlat.MFLockWorkQueue") +#pragma comment(linker, "/EXPORT:MFPlatformBigEndian=MFPlat.MFPlatformBigEndian") +#pragma comment(linker, "/EXPORT:MFPlatformLittleEndian=MFPlat.MFPlatformLittleEndian") +#pragma comment(linker, "/EXPORT:MFPutWorkItem=MFPlat.MFPutWorkItem") +#pragma comment(linker, "/EXPORT:MFPutWorkItemEx=MFPlat.MFPutWorkItemEx") +#pragma comment(linker, "/EXPORT:MFRecordError=MFPlat.MFRecordError") +#pragma comment(linker, "/EXPORT:MFRemovePeriodicCallback=MFPlat.MFRemovePeriodicCallback") +#pragma comment(linker, "/EXPORT:MFScheduleWorkItem=MFPlat.MFScheduleWorkItem") +#pragma comment(linker, "/EXPORT:MFScheduleWorkItemEx=MFPlat.MFScheduleWorkItemEx") +#pragma comment(linker, "/EXPORT:MFSerializeAttributesToStream=MFPlat.MFSerializeAttributesToStream") +#pragma comment(linker, "/EXPORT:MFSerializeEvent=MFPlat.MFSerializeEvent") +#pragma comment(linker, "/EXPORT:MFSerializeMediaTypeToStream=MFPlat.MFSerializeMediaTypeToStream") +#pragma comment(linker, "/EXPORT:MFSerializePresentationDescriptor=MFPlat.MFSerializePresentationDescriptor") +#pragma comment(linker, "/EXPORT:MFSetSockaddrAny=MFPlat.MFSetSockaddrAny") +#pragma comment(linker, "/EXPORT:MFShutdown=MFPlat.MFShutdown") +#pragma comment(linker, "/EXPORT:MFStartup=MFPlat.MFStartup") +#pragma comment(linker, "/EXPORT:MFStreamDescriptorProtectMediaType=MFPlat.MFStreamDescriptorProtectMediaType") +#pragma comment(linker, "/EXPORT:MFTEnum=MFPlat.MFTEnum") +#pragma comment(linker, "/EXPORT:MFTEnumEx=MFPlat.MFTEnumEx") +#pragma comment(linker, "/EXPORT:MFTGetInfo=MFPlat.MFTGetInfo") +#pragma comment(linker, "/EXPORT:MFTRegister=MFPlat.MFTRegister") +#pragma comment(linker, "/EXPORT:MFTRegisterLocal=MFPlat.MFTRegisterLocal") +#pragma comment(linker, "/EXPORT:MFTRegisterLocalByCLSID=MFPlat.MFTRegisterLocalByCLSID") +#pragma comment(linker, "/EXPORT:MFTUnregister=MFPlat.MFTUnregister") +#pragma comment(linker, "/EXPORT:MFTUnregisterLocal=MFPlat.MFTUnregisterLocal") +#pragma comment(linker, "/EXPORT:MFTUnregisterLocalByCLSID=MFPlat.MFTUnregisterLocalByCLSID") +#pragma comment(linker, "/EXPORT:MFTraceError=MFPlat.MFTraceError") +#pragma comment(linker, "/EXPORT:MFTraceFuncEnter=MFPlat.MFTraceFuncEnter") +#pragma comment(linker, "/EXPORT:MFUnblockThread=MFPlat.MFUnblockThread") +#pragma comment(linker, "/EXPORT:MFUnlockPlatform=MFPlat.MFUnlockPlatform") +#pragma comment(linker, "/EXPORT:MFUnlockWorkQueue=MFPlat.MFUnlockWorkQueue") +#pragma comment(linker, "/EXPORT:MFUnwrapMediaType=MFPlat.MFUnwrapMediaType") +#pragma comment(linker, "/EXPORT:MFValidateMediaTypeSize=MFPlat.MFValidateMediaTypeSize") +#pragma comment(linker, "/EXPORT:MFWrapMediaType=MFPlat.MFWrapMediaType") +#pragma comment(linker, "/EXPORT:MFllMulDiv=MFPlat.MFllMulDiv") +#pragma comment(linker, "/EXPORT:PropVariantFromStream=MFPlat.PropVariantFromStream") +#pragma comment(linker, "/EXPORT:PropVariantToStream=MFPlat.PropVariantToStream") +#pragma comment(linker, "/EXPORT:ValidateWaveFormat=MFPlat.ValidateWaveFormat") + + +#endif \ No newline at end of file diff --git a/01-Extended DLLs/KxDx/iid.c b/01-Extended DLLs/KxDx/iid.c new file mode 100644 index 0000000..146a16e --- /dev/null +++ b/01-Extended DLLs/KxDx/iid.c @@ -0,0 +1,10 @@ +#include +DEFINE_GUID(IID_IDXGIDisplayControl,0xea9dbf1a,0xc88e,0x4486,0x85,0x4a,0x98,0xaa,0x01,0x38,0xf3,0x0c); +DEFINE_GUID(IID_IDXGIOutputDuplication,0x191cfac3,0xa341,0x470d,0xb2,0x6e,0xa8,0x64,0xf4,0x28,0x31,0x9c); +DEFINE_GUID(IID_IDXGISurface2,0xaba496dd,0xb617,0x4cb8,0xa8,0x66,0xbc,0x44,0xd7,0xeb,0x1f,0xa2); +DEFINE_GUID(IID_IDXGIResource1,0x30961379,0x4609,0x4a41,0x99,0x8e,0x54,0xfe,0x56,0x7e,0xe0,0xc1); +DEFINE_GUID(IID_IDXGIDevice2,0x05008617,0xfbfd,0x4051,0xa7,0x90,0x14,0x48,0x84,0xb4,0xf6,0xa9); +DEFINE_GUID(IID_IDXGISwapChain1,0x790a45f7,0x0d42,0x4876,0x98,0x3a,0x0a,0x55,0xcf,0xe6,0xf4,0xaa); +DEFINE_GUID(IID_IDXGIFactory2,0x50c83a1c,0xe072,0x4c48,0x87,0xb0,0x36,0x30,0xfa,0x36,0xa6,0xd0); +DEFINE_GUID(IID_IDXGIAdapter2,0x0AA1AE0A,0xFA0E,0x4B84,0x86,0x44,0xE0,0x5F,0xF8,0xE5,0xAC,0xB5); +DEFINE_GUID(IID_IDXGIOutput1,0x00cddea8,0x939b,0x4b83,0xa3,0x40,0xa6,0x85,0x22,0x66,0x66,0xcc); \ No newline at end of file diff --git a/01-Extended DLLs/KxDx/kxdx.def b/01-Extended DLLs/KxDx/kxdx.def new file mode 100644 index 0000000..0cefe51 --- /dev/null +++ b/01-Extended DLLs/KxDx/kxdx.def @@ -0,0 +1,16 @@ +LIBRARY KxDx +EXPORTS + CreateDXGIFactory2 + + MFCreateDXGIDeviceManager + + ;; These must be exported with ordinal. A lot of programs import by ordinal + ;; from d3d12 for some reason. + D3D12CreateDevice @101 + D3D12CreateRootSignatureDeserializer @107 + D3D12CreateVersionedRootSignatureDeserializer @108 + D3D12EnableExperimentalFeatures @110 + D3D12GetDebugInterface @102 + D3D12GetInterface + D3D12SerializeRootSignature @115 + D3D12SerializeVersionedRootSignature @116 \ No newline at end of file diff --git a/01-Extended DLLs/KxDx/kxdxp.h b/01-Extended DLLs/KxDx/kxdxp.h new file mode 100644 index 0000000..4fa582d --- /dev/null +++ b/01-Extended DLLs/KxDx/kxdxp.h @@ -0,0 +1,7 @@ +#pragma once + +#include +#include +#include + +EXTERN PKEX_PROCESS_DATA KexData; \ No newline at end of file diff --git a/01-Extended DLLs/KxDx/mfdevmgr.c b/01-Extended DLLs/KxDx/mfdevmgr.c new file mode 100644 index 0000000..1967d44 --- /dev/null +++ b/01-Extended DLLs/KxDx/mfdevmgr.c @@ -0,0 +1,12 @@ +#include "buildcfg.h" +#include "kxdxp.h" + +KXDXAPI HRESULT WINAPI MFCreateDXGIDeviceManager( + OUT PUINT ResetToken, + OUT PPVOID DeviceManager) +{ + KexLogWarningEvent(L"Unimplemented function MFCreateDXGIDeviceManager called"); + + *DeviceManager = NULL; + return E_NOINTERFACE; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxMi/KxMi.vcxproj b/01-Extended DLLs/KxMi/KxMi.vcxproj new file mode 100644 index 0000000..eac7538 --- /dev/null +++ b/01-Extended DLLs/KxMi/KxMi.vcxproj @@ -0,0 +1,242 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {4168C61E-16EF-4196-9E3D-D21F18234CAF} + Win32Proj + KxMi + + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + + + + + + + + + + + + + + + + + false + false + + + false + false + + + false + false + + + false + false + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;KXMI_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + false + true + true + true + false + false + Default + false + StdCall + CompileAsC + + + Windows + true + kxmi.def + $(TargetDir);$(SolutionDir)\00-Import Libraries + true + + + true + + + $(SolutionDir)\00-Common Headers + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;KXMI_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + false + true + true + true + false + false + Default + false + StdCall + CompileAsC + + + Windows + true + kxmi.def + $(TargetDir);$(SolutionDir)\00-Import Libraries + true + + + true + + + $(SolutionDir)\00-Common Headers + + + + + Level3 + NotUsing + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;KXMI_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + false + true + true + true + false + false + Default + false + StdCall + CompileAsC + + + Windows + true + true + true + kxmi.def + $(TargetDir);$(SolutionDir)\00-Import Libraries + true + + + true + + + $(SolutionDir)\00-Common Headers + + + + + Level3 + NotUsing + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;KXMI_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + false + true + true + true + false + false + Default + false + StdCall + CompileAsC + + + Windows + true + true + true + kxmi.def + $(TargetDir);$(SolutionDir)\00-Import Libraries + true + + + true + + + $(SolutionDir)\00-Common Headers + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/01-Extended DLLs/KxMi/KxMi.vcxproj.filters b/01-Extended DLLs/KxMi/KxMi.vcxproj.filters new file mode 100644 index 0000000..7e51cf2 --- /dev/null +++ b/01-Extended DLLs/KxMi/KxMi.vcxproj.filters @@ -0,0 +1,55 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + + + Resource Files + + + + + Source Files + + + \ No newline at end of file diff --git a/01-Extended DLLs/KxMi/buildcfg.h b/01-Extended DLLs/KxMi/buildcfg.h new file mode 100644 index 0000000..c62f380 --- /dev/null +++ b/01-Extended DLLs/KxMi/buildcfg.h @@ -0,0 +1,46 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN +#define NOGDICAPMASKS +#define NOVIRTUALKEYCODES +#define NOWINSTYLES +#define NOSYSMETRICS +#define NOMENUS +#define NOICONS +#define NOKEYSTATES +#define NOSYSCOMMANDS +#define NORASTEROPS +#define NOSHOWWINDOW +#define NOATOM +#define NOCLIPBOARD +#define NOCOLOR +#define NODRAWTEXT +#define NOGDI +#define NOKERNEL +#define NOMB +#define NOMEMMGR +#define NOOPENFILE +#define NOSCROLL +#define NOTEXTMETRIC +#define NOWH +#define NOWINOFFSETS +#define NOCOMM +#define NOKANJI +#define NOHELP +#define NOPROFILER +#define NODEFERWINDOWPOS +#define NOMCX +#define NOCRYPT +#define NOMETAFILE +#define NOSERVICE +#define NOSOUND +#define _UXTHEME_H_ + +#define KXMIAPI + +#pragma comment(lib, "version.lib") +#pragma comment(lib, "powrprof.lib") + +#define KEX_COMPONENT L"KxMi" +#define KEX_ENV_WIN32 +#define KEX_TARGET_TYPE_DLL diff --git a/01-Extended DLLs/KxMi/dllmain.c b/01-Extended DLLs/KxMi/dllmain.c new file mode 100644 index 0000000..ab7eece --- /dev/null +++ b/01-Extended DLLs/KxMi/dllmain.c @@ -0,0 +1,17 @@ +#include "buildcfg.h" +#include "kxmip.h" + +PKEX_PROCESS_DATA KexData = NULL; + +BOOL WINAPI DllMain( + IN HMODULE DllHandle, + IN ULONG Reason, + IN PCONTEXT Context) +{ + if (Reason == DLL_PROCESS_ATTACH) { + LdrDisableThreadCalloutsForDll(DllHandle); + KexDataInitialize(&KexData); + } + + return TRUE; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxMi/forwards.c b/01-Extended DLLs/KxMi/forwards.c new file mode 100644 index 0000000..fd8052c --- /dev/null +++ b/01-Extended DLLs/KxMi/forwards.c @@ -0,0 +1,223 @@ +// Generated by KexExprt from "C:\Windows\system32\powrprof.dll" +#pragma comment(linker, "/EXPORT:CallNtPowerInformation=powrprof.CallNtPowerInformation") +#pragma comment(linker, "/EXPORT:CanUserWritePwrScheme=powrprof.CanUserWritePwrScheme") +#pragma comment(linker, "/EXPORT:DeletePwrScheme=powrprof.DeletePwrScheme") +#pragma comment(linker, "/EXPORT:DevicePowerClose=powrprof.DevicePowerClose") +#pragma comment(linker, "/EXPORT:DevicePowerEnumDevices=powrprof.DevicePowerEnumDevices") +#pragma comment(linker, "/EXPORT:DevicePowerOpen=powrprof.DevicePowerOpen") +#pragma comment(linker, "/EXPORT:DevicePowerSetDeviceState=powrprof.DevicePowerSetDeviceState") +#pragma comment(linker, "/EXPORT:EnumPwrSchemes=powrprof.EnumPwrSchemes") +#pragma comment(linker, "/EXPORT:GUIDFormatToGlobalPowerPolicy=powrprof.GUIDFormatToGlobalPowerPolicy") +#pragma comment(linker, "/EXPORT:GUIDFormatToPowerPolicy=powrprof.GUIDFormatToPowerPolicy") +#pragma comment(linker, "/EXPORT:GetActivePwrScheme=powrprof.GetActivePwrScheme") +#pragma comment(linker, "/EXPORT:GetCurrentPowerPolicies=powrprof.GetCurrentPowerPolicies") +#pragma comment(linker, "/EXPORT:GetPwrCapabilities=powrprof.GetPwrCapabilities") +#pragma comment(linker, "/EXPORT:GetPwrDiskSpindownRange=powrprof.GetPwrDiskSpindownRange") +#pragma comment(linker, "/EXPORT:IsAdminOverrideActive=powrprof.IsAdminOverrideActive") +#pragma comment(linker, "/EXPORT:IsPwrHibernateAllowed=powrprof.IsPwrHibernateAllowed") +#pragma comment(linker, "/EXPORT:IsPwrShutdownAllowed=powrprof.IsPwrShutdownAllowed") +#pragma comment(linker, "/EXPORT:IsPwrSuspendAllowed=powrprof.IsPwrSuspendAllowed") +#pragma comment(linker, "/EXPORT:LoadCurrentPwrScheme=powrprof.LoadCurrentPwrScheme") +#pragma comment(linker, "/EXPORT:MergeLegacyPwrScheme=powrprof.MergeLegacyPwrScheme") +#pragma comment(linker, "/EXPORT:PowerApplyPowerRequestOverride=powrprof.PowerApplyPowerRequestOverride") +#pragma comment(linker, "/EXPORT:PowerCanRestoreIndividualDefaultPowerScheme=powrprof.PowerCanRestoreIndividualDefaultPowerScheme") +#pragma comment(linker, "/EXPORT:PowerCreatePossibleSetting=powrprof.PowerCreatePossibleSetting") +#pragma comment(linker, "/EXPORT:PowerCreateSetting=powrprof.PowerCreateSetting") +#pragma comment(linker, "/EXPORT:PowerCustomizePlatformPowerSettings=powrprof.PowerCustomizePlatformPowerSettings") +#pragma comment(linker, "/EXPORT:PowerDebugDifPowerPolicies=powrprof.PowerDebugDifPowerPolicies") +#pragma comment(linker, "/EXPORT:PowerDebugDifSystemPowerPolicies=powrprof.PowerDebugDifSystemPowerPolicies") +#pragma comment(linker, "/EXPORT:PowerDebugDumpPowerPolicy=powrprof.PowerDebugDumpPowerPolicy") +#pragma comment(linker, "/EXPORT:PowerDebugDumpPowerScheme=powrprof.PowerDebugDumpPowerScheme") +#pragma comment(linker, "/EXPORT:PowerDebugDumpSystemPowerCapabilities=powrprof.PowerDebugDumpSystemPowerCapabilities") +#pragma comment(linker, "/EXPORT:PowerDebugDumpSystemPowerPolicy=powrprof.PowerDebugDumpSystemPowerPolicy") +#pragma comment(linker, "/EXPORT:PowerDeleteScheme=powrprof.PowerDeleteScheme") +#pragma comment(linker, "/EXPORT:PowerDeterminePlatformRole=powrprof.PowerDeterminePlatformRole") +#pragma comment(linker, "/EXPORT:PowerDisableCoreParkingSelectively=powrprof.PowerDisableCoreParkingSelectively") +#pragma comment(linker, "/EXPORT:PowerDuplicateScheme=powrprof.PowerDuplicateScheme") +#pragma comment(linker, "/EXPORT:PowerEnumerate=powrprof.PowerEnumerate") +#pragma comment(linker, "/EXPORT:PowerGetActiveScheme=powrprof.PowerGetActiveScheme") +#pragma comment(linker, "/EXPORT:PowerImportPowerScheme=powrprof.PowerImportPowerScheme") +#pragma comment(linker, "/EXPORT:PowerOpenSystemPowerKey=powrprof.PowerOpenSystemPowerKey") +#pragma comment(linker, "/EXPORT:PowerOpenUserPowerKey=powrprof.PowerOpenUserPowerKey") +#pragma comment(linker, "/EXPORT:PowerPolicyToGUIDFormat=powrprof.PowerPolicyToGUIDFormat") +#pragma comment(linker, "/EXPORT:PowerReadACDefaultIndex=powrprof.PowerReadACDefaultIndex") +#pragma comment(linker, "/EXPORT:PowerReadACValue=powrprof.PowerReadACValue") +#pragma comment(linker, "/EXPORT:PowerReadACValueIndex=powrprof.PowerReadACValueIndex") +#pragma comment(linker, "/EXPORT:PowerReadDCDefaultIndex=powrprof.PowerReadDCDefaultIndex") +#pragma comment(linker, "/EXPORT:PowerReadDCValue=powrprof.PowerReadDCValue") +#pragma comment(linker, "/EXPORT:PowerReadDCValueIndex=powrprof.PowerReadDCValueIndex") +#pragma comment(linker, "/EXPORT:PowerReadDescription=powrprof.PowerReadDescription") +#pragma comment(linker, "/EXPORT:PowerReadFriendlyName=powrprof.PowerReadFriendlyName") +#pragma comment(linker, "/EXPORT:PowerReadIconResourceSpecifier=powrprof.PowerReadIconResourceSpecifier") +#pragma comment(linker, "/EXPORT:PowerReadPossibleDescription=powrprof.PowerReadPossibleDescription") +#pragma comment(linker, "/EXPORT:PowerReadPossibleFriendlyName=powrprof.PowerReadPossibleFriendlyName") +#pragma comment(linker, "/EXPORT:PowerReadPossibleValue=powrprof.PowerReadPossibleValue") +#pragma comment(linker, "/EXPORT:PowerReadSecurityDescriptor=powrprof.PowerReadSecurityDescriptor") +#pragma comment(linker, "/EXPORT:PowerReadSettingAttributes=powrprof.PowerReadSettingAttributes") +#pragma comment(linker, "/EXPORT:PowerReadValueIncrement=powrprof.PowerReadValueIncrement") +#pragma comment(linker, "/EXPORT:PowerReadValueMax=powrprof.PowerReadValueMax") +#pragma comment(linker, "/EXPORT:PowerReadValueMin=powrprof.PowerReadValueMin") +#pragma comment(linker, "/EXPORT:PowerReadValueUnitsSpecifier=powrprof.PowerReadValueUnitsSpecifier") +#pragma comment(linker, "/EXPORT:PowerRemovePowerSetting=powrprof.PowerRemovePowerSetting") +#pragma comment(linker, "/EXPORT:PowerReplaceDefaultPowerSchemes=powrprof.PowerReplaceDefaultPowerSchemes") +#pragma comment(linker, "/EXPORT:PowerRestoreDefaultPowerSchemes=powrprof.PowerRestoreDefaultPowerSchemes") +#pragma comment(linker, "/EXPORT:PowerRestoreIndividualDefaultPowerScheme=powrprof.PowerRestoreIndividualDefaultPowerScheme") +#pragma comment(linker, "/EXPORT:PowerSetActiveScheme=powrprof.PowerSetActiveScheme") +#pragma comment(linker, "/EXPORT:PowerSetAlsBrightnessOffset=powrprof.PowerSetAlsBrightnessOffset") +#pragma comment(linker, "/EXPORT:PowerSettingAccessCheck=powrprof.PowerSettingAccessCheck") +#pragma comment(linker, "/EXPORT:PowerSettingRegisterNotification=powrprof.PowerSettingRegisterNotification") +#pragma comment(linker, "/EXPORT:PowerSettingUnregisterNotification=powrprof.PowerSettingUnregisterNotification") +#pragma comment(linker, "/EXPORT:PowerWriteACDefaultIndex=powrprof.PowerWriteACDefaultIndex") +#pragma comment(linker, "/EXPORT:PowerWriteACValueIndex=powrprof.PowerWriteACValueIndex") +#pragma comment(linker, "/EXPORT:PowerWriteDCDefaultIndex=powrprof.PowerWriteDCDefaultIndex") +#pragma comment(linker, "/EXPORT:PowerWriteDCValueIndex=powrprof.PowerWriteDCValueIndex") +#pragma comment(linker, "/EXPORT:PowerWriteDescription=powrprof.PowerWriteDescription") +#pragma comment(linker, "/EXPORT:PowerWriteFriendlyName=powrprof.PowerWriteFriendlyName") +#pragma comment(linker, "/EXPORT:PowerWriteIconResourceSpecifier=powrprof.PowerWriteIconResourceSpecifier") +#pragma comment(linker, "/EXPORT:PowerWritePossibleDescription=powrprof.PowerWritePossibleDescription") +#pragma comment(linker, "/EXPORT:PowerWritePossibleFriendlyName=powrprof.PowerWritePossibleFriendlyName") +#pragma comment(linker, "/EXPORT:PowerWritePossibleValue=powrprof.PowerWritePossibleValue") +#pragma comment(linker, "/EXPORT:PowerWriteSecurityDescriptor=powrprof.PowerWriteSecurityDescriptor") +#pragma comment(linker, "/EXPORT:PowerWriteSettingAttributes=powrprof.PowerWriteSettingAttributes") +#pragma comment(linker, "/EXPORT:PowerWriteValueIncrement=powrprof.PowerWriteValueIncrement") +#pragma comment(linker, "/EXPORT:PowerWriteValueMax=powrprof.PowerWriteValueMax") +#pragma comment(linker, "/EXPORT:PowerWriteValueMin=powrprof.PowerWriteValueMin") +#pragma comment(linker, "/EXPORT:PowerWriteValueUnitsSpecifier=powrprof.PowerWriteValueUnitsSpecifier") +#pragma comment(linker, "/EXPORT:ReadGlobalPwrPolicy=powrprof.ReadGlobalPwrPolicy") +#pragma comment(linker, "/EXPORT:ReadProcessorPwrScheme=powrprof.ReadProcessorPwrScheme") +#pragma comment(linker, "/EXPORT:ReadPwrScheme=powrprof.ReadPwrScheme") +#pragma comment(linker, "/EXPORT:SetActivePwrScheme=powrprof.SetActivePwrScheme") +#pragma comment(linker, "/EXPORT:SetSuspendState=powrprof.SetSuspendState") +#pragma comment(linker, "/EXPORT:ValidatePowerPolicies=powrprof.ValidatePowerPolicies") +#pragma comment(linker, "/EXPORT:WriteGlobalPwrPolicy=powrprof.WriteGlobalPwrPolicy") +#pragma comment(linker, "/EXPORT:WriteProcessorPwrScheme=powrprof.WriteProcessorPwrScheme") +#pragma comment(linker, "/EXPORT:WritePwrScheme=powrprof.WritePwrScheme") + +// Generated by KexExprt from "C:\Windows\system32\userenv.dll" +#pragma comment(linker, "/EXPORT:CreateEnvironmentBlock=userenv.CreateEnvironmentBlock") +#pragma comment(linker, "/EXPORT:CreateProfile=userenv.CreateProfile") +#pragma comment(linker, "/EXPORT:DeleteProfileA=userenv.DeleteProfileA") +#pragma comment(linker, "/EXPORT:DeleteProfileW=userenv.DeleteProfileW") +#pragma comment(linker, "/EXPORT:DestroyEnvironmentBlock=userenv.DestroyEnvironmentBlock") +#pragma comment(linker, "/EXPORT:DllGetContractDescription=userenv.DllGetContractDescription") +#pragma comment(linker, "/EXPORT:EnterCriticalPolicySection=userenv.EnterCriticalPolicySection") +#pragma comment(linker, "/EXPORT:ExpandEnvironmentStringsForUserA=userenv.ExpandEnvironmentStringsForUserA") +#pragma comment(linker, "/EXPORT:ExpandEnvironmentStringsForUserW=userenv.ExpandEnvironmentStringsForUserW") +#pragma comment(linker, "/EXPORT:ForceSyncFgPolicy=userenv.ForceSyncFgPolicy") +#pragma comment(linker, "/EXPORT:FreeGPOListA=userenv.FreeGPOListA") +#pragma comment(linker, "/EXPORT:FreeGPOListW=userenv.FreeGPOListW") +#pragma comment(linker, "/EXPORT:GetAllUsersProfileDirectoryA=userenv.GetAllUsersProfileDirectoryA") +#pragma comment(linker, "/EXPORT:GetAllUsersProfileDirectoryW=userenv.GetAllUsersProfileDirectoryW") +#pragma comment(linker, "/EXPORT:GetAppliedGPOListA=userenv.GetAppliedGPOListA") +#pragma comment(linker, "/EXPORT:GetAppliedGPOListW=userenv.GetAppliedGPOListW") +#pragma comment(linker, "/EXPORT:GetDefaultUserProfileDirectoryA=userenv.GetDefaultUserProfileDirectoryA") +#pragma comment(linker, "/EXPORT:GetDefaultUserProfileDirectoryW=userenv.GetDefaultUserProfileDirectoryW") +#pragma comment(linker, "/EXPORT:GetGPOListA=userenv.GetGPOListA") +#pragma comment(linker, "/EXPORT:GetGPOListW=userenv.GetGPOListW") +#pragma comment(linker, "/EXPORT:GetNextFgPolicyRefreshInfo=userenv.GetNextFgPolicyRefreshInfo") +#pragma comment(linker, "/EXPORT:GetPreviousFgPolicyRefreshInfo=userenv.GetPreviousFgPolicyRefreshInfo") +#pragma comment(linker, "/EXPORT:GetProfileType=userenv.GetProfileType") +#pragma comment(linker, "/EXPORT:GetProfilesDirectoryA=userenv.GetProfilesDirectoryA") +#pragma comment(linker, "/EXPORT:GetProfilesDirectoryW=userenv.GetProfilesDirectoryW") +#pragma comment(linker, "/EXPORT:GetUserProfileDirectoryA=userenv.GetUserProfileDirectoryA") +#pragma comment(linker, "/EXPORT:GetUserProfileDirectoryW=userenv.GetUserProfileDirectoryW") +#pragma comment(linker, "/EXPORT:LeaveCriticalPolicySection=userenv.LeaveCriticalPolicySection") +#pragma comment(linker, "/EXPORT:LoadUserProfileA=userenv.LoadUserProfileA") +#pragma comment(linker, "/EXPORT:LoadUserProfileW=userenv.LoadUserProfileW") +#pragma comment(linker, "/EXPORT:ProcessGroupPolicyCompleted=userenv.ProcessGroupPolicyCompleted") +#pragma comment(linker, "/EXPORT:ProcessGroupPolicyCompletedEx=userenv.ProcessGroupPolicyCompletedEx") +#pragma comment(linker, "/EXPORT:RefreshPolicy=userenv.RefreshPolicy") +#pragma comment(linker, "/EXPORT:RefreshPolicyEx=userenv.RefreshPolicyEx") +#pragma comment(linker, "/EXPORT:RegisterGPNotification=userenv.RegisterGPNotification") +#pragma comment(linker, "/EXPORT:RsopAccessCheckByType=userenv.RsopAccessCheckByType") +#pragma comment(linker, "/EXPORT:RsopFileAccessCheck=userenv.RsopFileAccessCheck") +#pragma comment(linker, "/EXPORT:RsopLoggingEnabled=userenv.RsopLoggingEnabled") +#pragma comment(linker, "/EXPORT:RsopResetPolicySettingStatus=userenv.RsopResetPolicySettingStatus") +#pragma comment(linker, "/EXPORT:RsopSetPolicySettingStatus=userenv.RsopSetPolicySettingStatus") +#pragma comment(linker, "/EXPORT:UnloadUserProfile=userenv.UnloadUserProfile") +#pragma comment(linker, "/EXPORT:UnregisterGPNotification=userenv.UnregisterGPNotification") +#pragma comment(linker, "/EXPORT:WaitForMachinePolicyForegroundProcessing=userenv.WaitForMachinePolicyForegroundProcessing") +#pragma comment(linker, "/EXPORT:WaitForUserPolicyForegroundProcessing=userenv.WaitForUserPolicyForegroundProcessing") +#pragma comment(linker, "/EXPORT:__OrdinalFunction104=userenv.#104,@104,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction122=userenv.#122,@122,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction135=userenv.#135,@135,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction137=userenv.#137,@137,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction139=userenv.#139,@139,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction157=userenv.#157,@157,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction158=userenv.#158,@158,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction159=userenv.#159,@159,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction160=userenv.#160,@160,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction161=userenv.#161,@161,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction162=userenv.#162,@162,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction163=userenv.#163,@163,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction164=userenv.#164,@164,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction165=userenv.#165,@165,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction166=userenv.#166,@166,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction167=userenv.#167,@167,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction168=userenv.#168,@168,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction169=userenv.#169,@169,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction170=userenv.#170,@170,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction171=userenv.#171,@171,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction172=userenv.#172,@172,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction173=userenv.#173,@173,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction174=userenv.#174,@174,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction175=userenv.#175,@175,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction176=userenv.#176,@176,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction177=userenv.#177,@177,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction178=userenv.#178,@178,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction179=userenv.#179,@179,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction180=userenv.#180,@180,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction181=userenv.#181,@181,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction182=userenv.#182,@182,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction183=userenv.#183,@183,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction184=userenv.#184,@184,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction185=userenv.#185,@185,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction186=userenv.#186,@186,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction187=userenv.#187,@187,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction188=userenv.#188,@188,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction189=userenv.#189,@189,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction190=userenv.#190,@190,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction191=userenv.#191,@191,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction192=userenv.#192,@192,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction193=userenv.#193,@193,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction194=userenv.#194,@194,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction195=userenv.#195,@195,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction196=userenv.#196,@196,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction197=userenv.#197,@197,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction198=userenv.#198,@198,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction199=userenv.#199,@199,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction200=userenv.#200,@200,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction201=userenv.#201,@201,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction202=userenv.#202,@202,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction203=userenv.#203,@203,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction204=userenv.#204,@204,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction205=userenv.#205,@205,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction206=userenv.#206,@206,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction207=userenv.#207,@207,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction208=userenv.#208,@208,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction209=userenv.#209,@209,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction210=userenv.#210,@210,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction211=userenv.#211,@211,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction212=userenv.#212,@212,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction213=userenv.#213,@213,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction214=userenv.#214,@214,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction215=userenv.#215,@215,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction216=userenv.#216,@216,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction217=userenv.#217,@217,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction218=userenv.#218,@218,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction219=userenv.#219,@219,NONAME") + +// Generated by KexExprt from "C:\Windows\system32\version.dll" +#pragma comment(linker, "/EXPORT:GetFileVersionInfoA=version.GetFileVersionInfoA") +#pragma comment(linker, "/EXPORT:GetFileVersionInfoByHandle=version.GetFileVersionInfoByHandle") +#pragma comment(linker, "/EXPORT:GetFileVersionInfoExW=version.GetFileVersionInfoExW") +#pragma comment(linker, "/EXPORT:GetFileVersionInfoSizeA=version.GetFileVersionInfoSizeA") +#pragma comment(linker, "/EXPORT:GetFileVersionInfoSizeExW=version.GetFileVersionInfoSizeExW") +#pragma comment(linker, "/EXPORT:GetFileVersionInfoSizeW=version.GetFileVersionInfoSizeW") +//#pragma comment(linker, "/EXPORT:GetFileVersionInfoW=version.GetFileVersionInfoW") +#pragma comment(linker, "/EXPORT:VerFindFileA=version.VerFindFileA") +#pragma comment(linker, "/EXPORT:VerFindFileW=version.VerFindFileW") +#pragma comment(linker, "/EXPORT:VerInstallFileA=version.VerInstallFileA") +#pragma comment(linker, "/EXPORT:VerInstallFileW=version.VerInstallFileW") +#pragma comment(linker, "/EXPORT:VerQueryValueA=version.VerQueryValueA") +#pragma comment(linker, "/EXPORT:VerQueryValueW=version.VerQueryValueW") \ No newline at end of file diff --git a/01-Extended DLLs/KxMi/kxmi.def b/01-Extended DLLs/KxMi/kxmi.def new file mode 100644 index 0000000..4e0602d --- /dev/null +++ b/01-Extended DLLs/KxMi/kxmi.def @@ -0,0 +1,19 @@ +LIBRARY KxMi +EXPORTS + ;; powrprof.c + PowerDeterminePlatformRoleEx + PowerRegisterSuspendResumeNotification + PowerUnregisterSuspendResumeNotification + + ;; userenv.c + CreateAppContainerProfile + DeleteAppContainerProfile + DeriveAppContainerSidFromAppContainerName + GetAppContainerFolderPath + GetAppContainerRegistryLocation + + ;; verspoof.c + GetFileVersionInfoW = Ext_GetFileVersionInfoW + + ;; wldp.c + WldpQueryWindowsLockdownMode \ No newline at end of file diff --git a/01-Extended DLLs/KxMi/kxmi.rc b/01-Extended DLLs/KxMi/kxmi.rc new file mode 100644 index 0000000..c7ff605 --- /dev/null +++ b/01-Extended DLLs/KxMi/kxmi.rc @@ -0,0 +1,30 @@ +#include "buildcfg.h" +#include +#include + +1 VERSIONINFO + FILEVERSION KEX_VERSION_FV + FILEOS VOS_NT +#if defined(KEX_TARGET_TYPE_EXE) + FILETYPE VFT_APP +#elif defined(KEX_TARGET_TYPE_DLL) + FILETYPE VFT_DLL +#endif +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904B0" + BEGIN + VALUE "LegalCopyright", KEX_WEB_STR + VALUE "FileDescription", "VxKex Miscellaneous API Extension DLL" + VALUE "FileVersion", KEX_VERSION_STR + VALUE "InternalName", KEX_COMPONENT + VALUE "OriginalFilename", "KXMI.DLL" + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409 0x04B0 + END +END \ No newline at end of file diff --git a/01-Extended DLLs/KxMi/kxmip.h b/01-Extended DLLs/KxMi/kxmip.h new file mode 100644 index 0000000..50fa764 --- /dev/null +++ b/01-Extended DLLs/KxMi/kxmip.h @@ -0,0 +1,23 @@ +#include "buildcfg.h" +#include +#include +#include + +EXTERN PKEX_PROCESS_DATA KexData; + +typedef enum _WLDP_WINDOWS_LOCKDOWN_MODE { + WLDP_WINDOWS_LOCKDOWN_MODE_UNLOCKED, + WLDP_WINDOWS_LOCKDOWN_MODE_TRIAL, + WLDP_WINDOWS_LOCKDOWN_MODE_LOCKED, + WLDP_WINDOWS_LOCKDOWN_MODE_MAX +} TYPEDEF_TYPE_NAME(WLDP_WINDOWS_LOCKDOWN_MODE); + +typedef struct _VERHEAD { + WORD wTotLen; + WORD wValLen; + WORD wType; + WCHAR szKey[(sizeof("VS_VERSION_INFO") + 3) & ~3]; + VS_FIXEDFILEINFO vsf; +} TYPEDEF_TYPE_NAME(VERHEAD); + +#define DEVICE_NOTIFY_CALLBACK 2 \ No newline at end of file diff --git a/01-Extended DLLs/KxMi/powrprof.c b/01-Extended DLLs/KxMi/powrprof.c new file mode 100644 index 0000000..694502d --- /dev/null +++ b/01-Extended DLLs/KxMi/powrprof.c @@ -0,0 +1,38 @@ +#include "buildcfg.h" +#include "kxmip.h" + +KXMIAPI POWER_PLATFORM_ROLE WINAPI PowerDeterminePlatformRoleEx( + IN ULONG Version) +{ + return PowerDeterminePlatformRole(); +} + +// +// Note: It is technically possible to make these work on Windows 7. +// However, it seems unlikely that applications actually use these in a +// useful manner, so they are stubbed for now. +// + +KXMIAPI ULONG WINAPI PowerRegisterSuspendResumeNotification( + IN ULONG Flags, + IN HANDLE Recipient, + OUT PHPOWERNOTIFY RegistrationHandle) +{ + KexLogWarningEvent(L"Unimplemented API PowerRegisterSuspendResumeNotification called"); + KexDebugCheckpoint(); + + if (Flags != DEVICE_NOTIFY_CALLBACK) { + return RtlNtStatusToDosError(STATUS_INVALID_PARAMETER); + } + + return RtlNtStatusToDosError(STATUS_NOT_SUPPORTED); +} + +KXMIAPI ULONG WINAPI PowerUnregisterSuspendResumeNotification( + IN OUT HPOWERNOTIFY RegistrationHandle) +{ + KexLogWarningEvent(L"Unimplemented API PowerUnregisterSuspendResumeNotification called"); + KexDebugCheckpoint(); + + return RtlNtStatusToDosError(STATUS_NOT_SUPPORTED); +} \ No newline at end of file diff --git a/01-Extended DLLs/KxMi/userenv.c b/01-Extended DLLs/KxMi/userenv.c new file mode 100644 index 0000000..488c6fe --- /dev/null +++ b/01-Extended DLLs/KxMi/userenv.c @@ -0,0 +1,71 @@ +#include "buildcfg.h" +#include "kxmip.h" + +KXMIAPI HRESULT WINAPI CreateAppContainerProfile( + IN PCWSTR AppContainerName, + IN PCWSTR DisplayName, + IN PCWSTR Description, + IN PSID_AND_ATTRIBUTES Capabilities, + IN ULONG NumberOfCapabilities, + OUT PSID *AppContainerSid) +{ + KexLogWarningEvent( + L"CreateAppContainerProfile called: %s\r\n\r\n" + L"DisplayName: %s\r\n" + L"NumberOfCapabilities: %lu", + AppContainerName, + DisplayName, + Description, + NumberOfCapabilities); + + KexDebugCheckpoint(); + + return E_NOTIMPL; +} + +KXMIAPI HRESULT WINAPI DeleteAppContainerProfile( + IN PCWSTR AppContainerName) +{ + KexLogWarningEvent( + L"DeleteAppContainerProfile called: %s", + AppContainerName); + + KexDebugCheckpoint(); + + return S_OK; +} + +KXMIAPI HRESULT WINAPI DeriveAppContainerSidFromAppContainerName( + IN PCWSTR AppContainerName, + OUT PSID *AppContainerSid) +{ + KexLogWarningEvent( + L"DeriveAppContainerSidFromAppContainerName called: %s", + AppContainerName); + + KexDebugCheckpoint(); + + return E_NOTIMPL; +} + +KXMIAPI HRESULT WINAPI GetAppContainerFolderPath( + IN PCWSTR AppContainerName, + OUT PPWSTR FolderPath) +{ + KexLogWarningEvent( + L"GetAppContainerFolderPath called: %s", + AppContainerName); + + KexDebugCheckpoint(); + + return E_NOTIMPL; +} + +KXMIAPI HRESULT WINAPI GetAppContainerRegistryLocation( + IN REGSAM DesiredAccess, + OUT PHKEY AppContainerKey) +{ + KexLogWarningEvent(L"GetAppContainerRegistryLocation called"); + KexDebugCheckpoint(); + return E_NOTIMPL; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxMi/verspoof.c b/01-Extended DLLs/KxMi/verspoof.c new file mode 100644 index 0000000..4288b57 --- /dev/null +++ b/01-Extended DLLs/KxMi/verspoof.c @@ -0,0 +1,58 @@ +#include "buildcfg.h" +#include "kxmip.h" + +// +// Chromium checks the OS version by calling GetFileVersionInfo on kernel32. +// For versions of Chromium above 118, this spoof is necessary to get it to run, +// and on prior versions, this spoof removes the annoying Windows 7 deprecation +// notice. +// + +KXMIAPI BOOL WINAPI Ext_GetFileVersionInfoW( + IN PCWSTR FileName, + IN ULONG Unused, + IN ULONG BufferCb, + OUT PVOID VersionInfo) +{ + BOOLEAN Success; + + Success = GetFileVersionInfoW(FileName, Unused, BufferCb, VersionInfo); + + if (!Success) { + return FALSE; + } + + // + // APPSPECIFICHACK: Spoof kernel32.dll version for Chromium. + // + if (KexData->Flags & KEXDATA_FLAG_CHROMIUM) { + ASSERT (FileName != NULL); + + if (StringEqual(FileName, L"kernel32.dll") || StringEqual(FileName, L"kernelbase.dll")) { + PVERHEAD VerHead; + + ASSERT (VersionInfo != NULL); + ASSERT (BufferCb >= sizeof(VERHEAD)); + + if (BufferCb < sizeof(VERHEAD)) { + // bail out and don't do anything + return Success; + } + + VerHead = (PVERHEAD) VersionInfo; + + KexLogDebugEvent( + L"Spoofing Kernel32/Kernelbase file version for Chromium\r\n\r\n" + L"Original dwFileVersionMS = 0x%08lx\r\n" + L"Original dwFileVersionLS = 0x%08lx\r\n", + VerHead->vsf.dwFileVersionMS, + VerHead->vsf.dwFileVersionLS); + + // 10.0.10240.0 (Windows 10 1504, aka "RTM") + VerHead->vsf.dwFileVersionMS = 0x000A0000; + VerHead->vsf.dwFileVersionLS = 0x28000000; + } + } + + return Success; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxMi/wldp.c b/01-Extended DLLs/KxMi/wldp.c new file mode 100644 index 0000000..620bf44 --- /dev/null +++ b/01-Extended DLLs/KxMi/wldp.c @@ -0,0 +1,11 @@ +#include "buildcfg.h" +#include "kxmip.h" + +KXMIAPI HRESULT WINAPI WldpQueryWindowsLockdownMode( + OUT PWLDP_WINDOWS_LOCKDOWN_MODE LockdownMode) +{ + ASSERT (LockdownMode != NULL); + + *LockdownMode = WLDP_WINDOWS_LOCKDOWN_MODE_UNLOCKED; + return S_OK; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxNet/KxNet.vcxproj b/01-Extended DLLs/KxNet/KxNet.vcxproj new file mode 100644 index 0000000..8c6a635 --- /dev/null +++ b/01-Extended DLLs/KxNet/KxNet.vcxproj @@ -0,0 +1,243 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {36F79680-796A-465E-9C87-0E76034AF16B} + Win32Proj + KxNet + + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + + + + + + + + + + + + + + + + + false + false + + + false + false + + + false + false + + + false + false + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;KXNET_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + true + false + false + Default + false + StdCall + CompileAsC + + + Windows + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + true + true + kxnet.def + + + $(SolutionDir)\00-Common Headers + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;KXNET_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + true + false + false + Default + false + StdCall + CompileAsC + + + Windows + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + true + true + kxnet.def + + + $(SolutionDir)\00-Common Headers + + + + + Level3 + NotUsing + MinSpace + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;KXNET_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + true + false + false + Default + false + StdCall + CompileAsC + OnlyExplicitInline + Size + true + + + Windows + true + true + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + true + true + kxnet.def + + + $(SolutionDir)\00-Common Headers + + + + + Level3 + NotUsing + MinSpace + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;KXNET_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + true + false + false + Default + false + StdCall + CompileAsC + OnlyExplicitInline + Size + true + + + Windows + true + true + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + true + true + kxnet.def + + + $(SolutionDir)\00-Common Headers + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/01-Extended DLLs/KxNet/KxNet.vcxproj.filters b/01-Extended DLLs/KxNet/KxNet.vcxproj.filters new file mode 100644 index 0000000..e088131 --- /dev/null +++ b/01-Extended DLLs/KxNet/KxNet.vcxproj.filters @@ -0,0 +1,52 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + + + Resource Files + + + + + Source Files + + + \ No newline at end of file diff --git a/01-Extended DLLs/KxNet/buildcfg.h b/01-Extended DLLs/KxNet/buildcfg.h new file mode 100644 index 0000000..d96602e --- /dev/null +++ b/01-Extended DLLs/KxNet/buildcfg.h @@ -0,0 +1,46 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN +#define NOGDICAPMASKS +#define NOVIRTUALKEYCODES +#define NOWINSTYLES +#define NOSYSMETRICS +#define NOMENUS +#define NOICONS +#define NOKEYSTATES +#define NOSYSCOMMANDS +#define NORASTEROPS +#define NOSHOWWINDOW +#define NOATOM +#define NOCLIPBOARD +#define NOCOLOR +#define NODRAWTEXT +#define NOGDI +#define NOKERNEL +#define NOMB +#define NOMEMMGR +#define NOOPENFILE +#define NOSCROLL +#define NOTEXTMETRIC +#define NOWH +#define NOWINOFFSETS +#define NOCOMM +#define NOKANJI +#define NOHELP +#define NOPROFILER +#define NODEFERWINDOWPOS +#define NOMCX +#define NOCRYPT +#define NOMETAFILE +#define NOSERVICE +#define NOSOUND +#define _UXTHEME_H_ + +#pragma comment(lib, "dnsapi.lib") +#pragma comment(lib, "ws2_32.lib") + +#define KXNETAPI + +#define KEX_COMPONENT L"KxNet" +#define KEX_ENV_WIN32 +#define KEX_TARGET_TYPE_DLL diff --git a/01-Extended DLLs/KxNet/dllmain.c b/01-Extended DLLs/KxNet/dllmain.c new file mode 100644 index 0000000..f2e1c1c --- /dev/null +++ b/01-Extended DLLs/KxNet/dllmain.c @@ -0,0 +1,17 @@ +#include "buildcfg.h" +#include + +PKEX_PROCESS_DATA KexData = NULL; + +BOOL WINAPI DllMain( + IN HMODULE DllHandle, + IN ULONG Reason, + IN PCONTEXT Context) +{ + if (Reason == DLL_PROCESS_ATTACH) { + LdrDisableThreadCalloutsForDll(DllHandle); + KexDataInitialize(&KexData); + } + + return TRUE; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxNet/dns.c b/01-Extended DLLs/KxNet/dns.c new file mode 100644 index 0000000..e129193 --- /dev/null +++ b/01-Extended DLLs/KxNet/dns.c @@ -0,0 +1,91 @@ +#include "buildcfg.h" +#include "kxnetp.h" + +// +// This DnsQueryEx implementation mainly exists to support Qt6Network. +// It does not support asynchronous queries. If we need to support any +// extra functionality in the future, have a look into DnsQueryExW which +// is present in nt5src - this has the capabilities to do everything we +// want, but requires a lot more effort and research since it's not +// documented. +// +KXNETAPI DNS_STATUS WINAPI DnsQueryEx( + IN PDNS_QUERY_REQUEST Request, + IN OUT PDNS_QUERY_RESULT Result, + IN OUT PDNS_QUERY_CANCEL Cancel OPTIONAL) +{ + DNS_STATUS DnsStatus; + + ASSERT (Request != NULL); + ASSERT (Result != NULL); + ASSERT (Cancel == NULL); + ASSERT (Request->Version == 1); + ASSERT (Request->QueryCompletionCallback == NULL); + ASSERT (Result->Version == 1); + + // + // Validate parameters. + // + + if (!Request || !Result) { + return ERROR_INVALID_PARAMETER; + } + + KexLogDebugEvent( + L"DnsQueryEx called\r\n\r\n" + L"Request->Version: %d\r\n" + L"Request->QueryName: %s\r\n" + L"Request->QueryType: %hu\r\n" + L"Request->QueryOptions: 0x%016I64u\r\n" + L"Request->DnsServerList: 0x%p\r\n" + L"Request->InterfaceIndex: %d\r\n" + L"Request->QueryCompletionCallback: 0x%p\r\n" + L"Request->QueryContext: 0x%p", + Request->Version, + Request->QueryName, + Request->QueryType, + Request->QueryOptions, + Request->DnsServerList, + Request->InterfaceIndex, + Request->QueryCompletionCallback, + Request->QueryContext); + + if (Request->Version != 1 || Result->Version != 1) { + // Version could be 3, which is only available in Win11 and above. + KexDebugCheckpoint(); + return ERROR_INVALID_PARAMETER; + } + + if (Request->QueryCompletionCallback) { + KexDebugCheckpoint(); + return DNS_RCODE_NOT_IMPLEMENTED; + } + + if (Cancel) { + KexDebugCheckpoint(); + return DNS_RCODE_NOT_IMPLEMENTED; + } + + // + // Perform the query. + // Note: the current implementation ignores DnsServerList and InterfaceIndex. + // + + DnsStatus = DnsQuery( + Request->QueryName, + Request->QueryType, + (ULONG) Request->QueryOptions, + NULL, + &Result->QueryRecords, + NULL); + + // + // Fill out remaining fields of DNS_QUERY_RESULT. + // + + Result->QueryStatus = DnsStatus; + Result->QueryOptions = Request->QueryOptions; + Result->Reserved = NULL; + + return DnsStatus; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxNet/forwards.c b/01-Extended DLLs/KxNet/forwards.c new file mode 100644 index 0000000..545c33d --- /dev/null +++ b/01-Extended DLLs/KxNet/forwards.c @@ -0,0 +1,762 @@ +// Generated by KexExprt from "dnsapi.dll" +#pragma comment(linker, "/EXPORT:BreakRecordsIntoBlob=dnsapi.BreakRecordsIntoBlob") +#pragma comment(linker, "/EXPORT:CombineRecordsInBlob=dnsapi.CombineRecordsInBlob") +#pragma comment(linker, "/EXPORT:DnsAcquireContextHandle_A=dnsapi.DnsAcquireContextHandle_A") +#pragma comment(linker, "/EXPORT:DnsAcquireContextHandle_W=dnsapi.DnsAcquireContextHandle_W") +#pragma comment(linker, "/EXPORT:DnsAllocateRecord=dnsapi.DnsAllocateRecord") +#pragma comment(linker, "/EXPORT:DnsApiAlloc=dnsapi.DnsApiAlloc") +#pragma comment(linker, "/EXPORT:DnsApiAllocZero=dnsapi.DnsApiAllocZero") +#pragma comment(linker, "/EXPORT:DnsApiFree=dnsapi.DnsApiFree") +#pragma comment(linker, "/EXPORT:DnsApiHeapReset=dnsapi.DnsApiHeapReset") +#pragma comment(linker, "/EXPORT:DnsApiRealloc=dnsapi.DnsApiRealloc") +#pragma comment(linker, "/EXPORT:DnsApiSetDebugGlobals=dnsapi.DnsApiSetDebugGlobals") +#pragma comment(linker, "/EXPORT:DnsAsyncRegisterHostAddrs=dnsapi.DnsAsyncRegisterHostAddrs") +#pragma comment(linker, "/EXPORT:DnsAsyncRegisterInit=dnsapi.DnsAsyncRegisterInit") +#pragma comment(linker, "/EXPORT:DnsAsyncRegisterTerm=dnsapi.DnsAsyncRegisterTerm") +#pragma comment(linker, "/EXPORT:DnsCopyStringEx=dnsapi.DnsCopyStringEx") +#pragma comment(linker, "/EXPORT:DnsCreateReverseNameStringForIpAddress=dnsapi.DnsCreateReverseNameStringForIpAddress") +#pragma comment(linker, "/EXPORT:DnsCreateStandardDnsNameCopy=dnsapi.DnsCreateStandardDnsNameCopy") +#pragma comment(linker, "/EXPORT:DnsCreateStringCopy=dnsapi.DnsCreateStringCopy") +#pragma comment(linker, "/EXPORT:DnsDhcpRegisterAddrs=dnsapi.DnsDhcpRegisterAddrs") +#pragma comment(linker, "/EXPORT:DnsDhcpRegisterHostAddrs=dnsapi.DnsDhcpRegisterHostAddrs") +#pragma comment(linker, "/EXPORT:DnsDhcpRegisterInit=dnsapi.DnsDhcpRegisterInit") +#pragma comment(linker, "/EXPORT:DnsDhcpRegisterTerm=dnsapi.DnsDhcpRegisterTerm") +#pragma comment(linker, "/EXPORT:DnsDhcpRemoveRegistrations=dnsapi.DnsDhcpRemoveRegistrations") +#pragma comment(linker, "/EXPORT:DnsDhcpSrvRegisterHostAddr=dnsapi.DnsDhcpSrvRegisterHostAddr") +#pragma comment(linker, "/EXPORT:DnsDhcpSrvRegisterHostAddrEx=dnsapi.DnsDhcpSrvRegisterHostAddrEx") +#pragma comment(linker, "/EXPORT:DnsDhcpSrvRegisterHostName=dnsapi.DnsDhcpSrvRegisterHostName") +#pragma comment(linker, "/EXPORT:DnsDhcpSrvRegisterHostNameEx=dnsapi.DnsDhcpSrvRegisterHostNameEx") +#pragma comment(linker, "/EXPORT:DnsDhcpSrvRegisterInit=dnsapi.DnsDhcpSrvRegisterInit") +#pragma comment(linker, "/EXPORT:DnsDhcpSrvRegisterInitialize=dnsapi.DnsDhcpSrvRegisterInitialize") +#pragma comment(linker, "/EXPORT:DnsDhcpSrvRegisterTerm=dnsapi.DnsDhcpSrvRegisterTerm") +#pragma comment(linker, "/EXPORT:DnsDowncaseDnsNameLabel=dnsapi.DnsDowncaseDnsNameLabel") +#pragma comment(linker, "/EXPORT:DnsExtractRecordsFromMessage_UTF8=dnsapi.DnsExtractRecordsFromMessage_UTF8") +#pragma comment(linker, "/EXPORT:DnsExtractRecordsFromMessage_W=dnsapi.DnsExtractRecordsFromMessage_W") +#pragma comment(linker, "/EXPORT:DnsFindAuthoritativeZone=dnsapi.DnsFindAuthoritativeZone") +#pragma comment(linker, "/EXPORT:DnsFlushResolverCache=dnsapi.DnsFlushResolverCache") +#pragma comment(linker, "/EXPORT:DnsFlushResolverCacheEntry_A=dnsapi.DnsFlushResolverCacheEntry_A") +#pragma comment(linker, "/EXPORT:DnsFlushResolverCacheEntry_UTF8=dnsapi.DnsFlushResolverCacheEntry_UTF8") +#pragma comment(linker, "/EXPORT:DnsFlushResolverCacheEntry_W=dnsapi.DnsFlushResolverCacheEntry_W") +#pragma comment(linker, "/EXPORT:DnsFree=dnsapi.DnsFree") +#pragma comment(linker, "/EXPORT:DnsFreeConfigStructure=dnsapi.DnsFreeConfigStructure") +#pragma comment(linker, "/EXPORT:DnsFreePolicyConfig=dnsapi.DnsFreePolicyConfig") +#pragma comment(linker, "/EXPORT:DnsFreeProxyName=dnsapi.DnsFreeProxyName") +#pragma comment(linker, "/EXPORT:DnsGetBufferLengthForStringCopy=dnsapi.DnsGetBufferLengthForStringCopy") +#pragma comment(linker, "/EXPORT:DnsGetCacheDataTable=dnsapi.DnsGetCacheDataTable") +#pragma comment(linker, "/EXPORT:DnsGetDnsServerList=dnsapi.DnsGetDnsServerList") +#pragma comment(linker, "/EXPORT:DnsGetDomainName=dnsapi.DnsGetDomainName") +#pragma comment(linker, "/EXPORT:DnsGetLastFailedUpdateInfo=dnsapi.DnsGetLastFailedUpdateInfo") +#pragma comment(linker, "/EXPORT:DnsGetPolicyTableInfo=dnsapi.DnsGetPolicyTableInfo") +#pragma comment(linker, "/EXPORT:DnsGetPolicyTableInfoPrivate=dnsapi.DnsGetPolicyTableInfoPrivate") +#pragma comment(linker, "/EXPORT:DnsGetPrimaryDomainName_A=dnsapi.DnsGetPrimaryDomainName_A") +#pragma comment(linker, "/EXPORT:DnsGetProxyInfoPrivate=dnsapi.DnsGetProxyInfoPrivate") +#pragma comment(linker, "/EXPORT:DnsGetProxyInformation=dnsapi.DnsGetProxyInformation") +#pragma comment(linker, "/EXPORT:DnsGlobals=dnsapi.DnsGlobals") +#pragma comment(linker, "/EXPORT:DnsIpv6AddressToString=dnsapi.DnsIpv6AddressToString") +#pragma comment(linker, "/EXPORT:DnsIpv6StringToAddress=dnsapi.DnsIpv6StringToAddress") +#pragma comment(linker, "/EXPORT:DnsIsAMailboxType=dnsapi.DnsIsAMailboxType") +#pragma comment(linker, "/EXPORT:DnsIsStatusRcode=dnsapi.DnsIsStatusRcode") +#pragma comment(linker, "/EXPORT:DnsIsStringCountValidForTextType=dnsapi.DnsIsStringCountValidForTextType") +#pragma comment(linker, "/EXPORT:DnsLogEvent=dnsapi.DnsLogEvent") +#pragma comment(linker, "/EXPORT:DnsLogIn=dnsapi.DnsLogIn") +#pragma comment(linker, "/EXPORT:DnsLogInit=dnsapi.DnsLogInit") +#pragma comment(linker, "/EXPORT:DnsLogIt=dnsapi.DnsLogIt") +#pragma comment(linker, "/EXPORT:DnsLogOut=dnsapi.DnsLogOut") +#pragma comment(linker, "/EXPORT:DnsLogTime=dnsapi.DnsLogTime") +#pragma comment(linker, "/EXPORT:DnsMapRcodeToStatus=dnsapi.DnsMapRcodeToStatus") +#pragma comment(linker, "/EXPORT:DnsModifyRecordsInSet_A=dnsapi.DnsModifyRecordsInSet_A") +#pragma comment(linker, "/EXPORT:DnsModifyRecordsInSet_UTF8=dnsapi.DnsModifyRecordsInSet_UTF8") +#pragma comment(linker, "/EXPORT:DnsModifyRecordsInSet_W=dnsapi.DnsModifyRecordsInSet_W") +#pragma comment(linker, "/EXPORT:DnsNameCompareEx_A=dnsapi.DnsNameCompareEx_A") +#pragma comment(linker, "/EXPORT:DnsNameCompareEx_UTF8=dnsapi.DnsNameCompareEx_UTF8") +#pragma comment(linker, "/EXPORT:DnsNameCompareEx_W=dnsapi.DnsNameCompareEx_W") +#pragma comment(linker, "/EXPORT:DnsNameCompare_A=dnsapi.DnsNameCompare_A") +#pragma comment(linker, "/EXPORT:DnsNameCompare_UTF8=dnsapi.DnsNameCompare_UTF8") +#pragma comment(linker, "/EXPORT:DnsNameCompare_W=dnsapi.DnsNameCompare_W") +#pragma comment(linker, "/EXPORT:DnsNameCopy=dnsapi.DnsNameCopy") +#pragma comment(linker, "/EXPORT:DnsNameCopyAllocate=dnsapi.DnsNameCopyAllocate") +#pragma comment(linker, "/EXPORT:DnsNetworkInfo_CreateFromFAZ=dnsapi.DnsNetworkInfo_CreateFromFAZ") +#pragma comment(linker, "/EXPORT:DnsNetworkInformation_CreateFromFAZ=dnsapi.DnsNetworkInformation_CreateFromFAZ") +#pragma comment(linker, "/EXPORT:DnsNotifyResolver=dnsapi.DnsNotifyResolver") +#pragma comment(linker, "/EXPORT:DnsNotifyResolverClusterIp=dnsapi.DnsNotifyResolverClusterIp") +#pragma comment(linker, "/EXPORT:DnsNotifyResolverEx=dnsapi.DnsNotifyResolverEx") +#pragma comment(linker, "/EXPORT:DnsQueryConfig=dnsapi.DnsQueryConfig") +#pragma comment(linker, "/EXPORT:DnsQueryConfigAllocEx=dnsapi.DnsQueryConfigAllocEx") +#pragma comment(linker, "/EXPORT:DnsQueryConfigDword=dnsapi.DnsQueryConfigDword") +#pragma comment(linker, "/EXPORT:DnsQueryExA=dnsapi.DnsQueryExA") +#pragma comment(linker, "/EXPORT:DnsQueryExUTF8=dnsapi.DnsQueryExUTF8") +#pragma comment(linker, "/EXPORT:DnsQueryExW=dnsapi.DnsQueryExW") +#pragma comment(linker, "/EXPORT:DnsQuery_A=dnsapi.DnsQuery_A") +#pragma comment(linker, "/EXPORT:DnsQuery_UTF8=dnsapi.DnsQuery_UTF8") +#pragma comment(linker, "/EXPORT:DnsQuery_W=dnsapi.DnsQuery_W") +#pragma comment(linker, "/EXPORT:DnsRecordBuild_UTF8=dnsapi.DnsRecordBuild_UTF8") +#pragma comment(linker, "/EXPORT:DnsRecordBuild_W=dnsapi.DnsRecordBuild_W") +#pragma comment(linker, "/EXPORT:DnsRecordCompare=dnsapi.DnsRecordCompare") +#pragma comment(linker, "/EXPORT:DnsRecordCopyEx=dnsapi.DnsRecordCopyEx") +#pragma comment(linker, "/EXPORT:DnsRecordListFree=dnsapi.DnsRecordListFree") +#pragma comment(linker, "/EXPORT:DnsRecordSetCompare=dnsapi.DnsRecordSetCompare") +#pragma comment(linker, "/EXPORT:DnsRecordSetCopyEx=dnsapi.DnsRecordSetCopyEx") +#pragma comment(linker, "/EXPORT:DnsRecordSetDetach=dnsapi.DnsRecordSetDetach") +#pragma comment(linker, "/EXPORT:DnsRecordStringForType=dnsapi.DnsRecordStringForType") +#pragma comment(linker, "/EXPORT:DnsRecordStringForWritableType=dnsapi.DnsRecordStringForWritableType") +#pragma comment(linker, "/EXPORT:DnsRecordTypeForName=dnsapi.DnsRecordTypeForName") +#pragma comment(linker, "/EXPORT:DnsRegisterClusterAddress=dnsapi.DnsRegisterClusterAddress") +#pragma comment(linker, "/EXPORT:DnsReleaseContextHandle=dnsapi.DnsReleaseContextHandle") +#pragma comment(linker, "/EXPORT:DnsRemoveRegistrations=dnsapi.DnsRemoveRegistrations") +#pragma comment(linker, "/EXPORT:DnsReplaceRecordSetA=dnsapi.DnsReplaceRecordSetA") +#pragma comment(linker, "/EXPORT:DnsReplaceRecordSetUTF8=dnsapi.DnsReplaceRecordSetUTF8") +#pragma comment(linker, "/EXPORT:DnsReplaceRecordSetW=dnsapi.DnsReplaceRecordSetW") +#pragma comment(linker, "/EXPORT:DnsResolverOp=dnsapi.DnsResolverOp") +#pragma comment(linker, "/EXPORT:DnsScreenLocalAddrsForRegistration=dnsapi.DnsScreenLocalAddrsForRegistration") +#pragma comment(linker, "/EXPORT:DnsSetConfigDword=dnsapi.DnsSetConfigDword") +#pragma comment(linker, "/EXPORT:DnsStatusString=dnsapi.DnsStatusString") +#pragma comment(linker, "/EXPORT:DnsStringCopyAllocateEx=dnsapi.DnsStringCopyAllocateEx") +#pragma comment(linker, "/EXPORT:DnsTraceServerConfig=dnsapi.DnsTraceServerConfig") +#pragma comment(linker, "/EXPORT:DnsUnicodeToUtf8=dnsapi.DnsUnicodeToUtf8") +#pragma comment(linker, "/EXPORT:DnsUpdate=dnsapi.DnsUpdate") +#pragma comment(linker, "/EXPORT:DnsUpdateMachinePresence=dnsapi.DnsUpdateMachinePresence") +#pragma comment(linker, "/EXPORT:DnsUpdateTest_A=dnsapi.DnsUpdateTest_A") +#pragma comment(linker, "/EXPORT:DnsUpdateTest_UTF8=dnsapi.DnsUpdateTest_UTF8") +#pragma comment(linker, "/EXPORT:DnsUpdateTest_W=dnsapi.DnsUpdateTest_W") +#pragma comment(linker, "/EXPORT:DnsUtf8ToUnicode=dnsapi.DnsUtf8ToUnicode") +#pragma comment(linker, "/EXPORT:DnsValidateNameOrIp_TempW=dnsapi.DnsValidateNameOrIp_TempW") +#pragma comment(linker, "/EXPORT:DnsValidateName_A=dnsapi.DnsValidateName_A") +#pragma comment(linker, "/EXPORT:DnsValidateName_UTF8=dnsapi.DnsValidateName_UTF8") +#pragma comment(linker, "/EXPORT:DnsValidateName_W=dnsapi.DnsValidateName_W") +#pragma comment(linker, "/EXPORT:DnsValidateServerArray_A=dnsapi.DnsValidateServerArray_A") +#pragma comment(linker, "/EXPORT:DnsValidateServerArray_W=dnsapi.DnsValidateServerArray_W") +#pragma comment(linker, "/EXPORT:DnsValidateServerStatus=dnsapi.DnsValidateServerStatus") +#pragma comment(linker, "/EXPORT:DnsValidateServer_A=dnsapi.DnsValidateServer_A") +#pragma comment(linker, "/EXPORT:DnsValidateServer_W=dnsapi.DnsValidateServer_W") +#pragma comment(linker, "/EXPORT:DnsValidateUtf8Byte=dnsapi.DnsValidateUtf8Byte") +#pragma comment(linker, "/EXPORT:DnsWriteQuestionToBuffer_UTF8=dnsapi.DnsWriteQuestionToBuffer_UTF8") +#pragma comment(linker, "/EXPORT:DnsWriteQuestionToBuffer_W=dnsapi.DnsWriteQuestionToBuffer_W") +#pragma comment(linker, "/EXPORT:DnsWriteReverseNameStringForIpAddress=dnsapi.DnsWriteReverseNameStringForIpAddress") +#pragma comment(linker, "/EXPORT:Dns_AddRecordsToMessage=dnsapi.Dns_AddRecordsToMessage") +#pragma comment(linker, "/EXPORT:Dns_AllocateMsgBuf=dnsapi.Dns_AllocateMsgBuf") +#pragma comment(linker, "/EXPORT:Dns_BuildPacket=dnsapi.Dns_BuildPacket") +#pragma comment(linker, "/EXPORT:Dns_CleanupWinsock=dnsapi.Dns_CleanupWinsock") +#pragma comment(linker, "/EXPORT:Dns_CloseConnection=dnsapi.Dns_CloseConnection") +#pragma comment(linker, "/EXPORT:Dns_CloseSocket=dnsapi.Dns_CloseSocket") +#pragma comment(linker, "/EXPORT:Dns_CreateMulticastSocket=dnsapi.Dns_CreateMulticastSocket") +#pragma comment(linker, "/EXPORT:Dns_CreateSocket=dnsapi.Dns_CreateSocket") +#pragma comment(linker, "/EXPORT:Dns_CreateSocketEx=dnsapi.Dns_CreateSocketEx") +#pragma comment(linker, "/EXPORT:Dns_ExtractRecordsFromMessage=dnsapi.Dns_ExtractRecordsFromMessage") +#pragma comment(linker, "/EXPORT:Dns_FindAuthoritativeZoneLib=dnsapi.Dns_FindAuthoritativeZoneLib") +#pragma comment(linker, "/EXPORT:Dns_FreeMsgBuf=dnsapi.Dns_FreeMsgBuf") +#pragma comment(linker, "/EXPORT:Dns_GetRandomXid=dnsapi.Dns_GetRandomXid") +#pragma comment(linker, "/EXPORT:Dns_InitializeMsgBuf=dnsapi.Dns_InitializeMsgBuf") +#pragma comment(linker, "/EXPORT:Dns_InitializeMsgRemoteSockaddr=dnsapi.Dns_InitializeMsgRemoteSockaddr") +#pragma comment(linker, "/EXPORT:Dns_InitializeWinsock=dnsapi.Dns_InitializeWinsock") +#pragma comment(linker, "/EXPORT:Dns_OpenTcpConnectionAndSend=dnsapi.Dns_OpenTcpConnectionAndSend") +#pragma comment(linker, "/EXPORT:Dns_ParseMessage=dnsapi.Dns_ParseMessage") +#pragma comment(linker, "/EXPORT:Dns_ParsePacketRecord=dnsapi.Dns_ParsePacketRecord") +#pragma comment(linker, "/EXPORT:Dns_PingAdapterServers=dnsapi.Dns_PingAdapterServers") +#pragma comment(linker, "/EXPORT:Dns_ReadPacketName=dnsapi.Dns_ReadPacketName") +#pragma comment(linker, "/EXPORT:Dns_ReadPacketNameAllocate=dnsapi.Dns_ReadPacketNameAllocate") +#pragma comment(linker, "/EXPORT:Dns_ReadRecordStructureFromPacket=dnsapi.Dns_ReadRecordStructureFromPacket") +#pragma comment(linker, "/EXPORT:Dns_RecvTcp=dnsapi.Dns_RecvTcp") +#pragma comment(linker, "/EXPORT:Dns_ResetNetworkInfo=dnsapi.Dns_ResetNetworkInfo") +#pragma comment(linker, "/EXPORT:Dns_SendAndRecvUdp=dnsapi.Dns_SendAndRecvUdp") +#pragma comment(linker, "/EXPORT:Dns_SendEx=dnsapi.Dns_SendEx") +#pragma comment(linker, "/EXPORT:Dns_SetRecordDatalength=dnsapi.Dns_SetRecordDatalength") +#pragma comment(linker, "/EXPORT:Dns_SetRecordsSection=dnsapi.Dns_SetRecordsSection") +#pragma comment(linker, "/EXPORT:Dns_SetRecordsTtl=dnsapi.Dns_SetRecordsTtl") +#pragma comment(linker, "/EXPORT:Dns_SkipPacketName=dnsapi.Dns_SkipPacketName") +#pragma comment(linker, "/EXPORT:Dns_SkipToRecord=dnsapi.Dns_SkipToRecord") +#pragma comment(linker, "/EXPORT:Dns_UpdateLib=dnsapi.Dns_UpdateLib") +#pragma comment(linker, "/EXPORT:Dns_UpdateLibEx=dnsapi.Dns_UpdateLibEx") +#pragma comment(linker, "/EXPORT:Dns_WriteDottedNameToPacket=dnsapi.Dns_WriteDottedNameToPacket") +#pragma comment(linker, "/EXPORT:Dns_WriteQuestionToMessage=dnsapi.Dns_WriteQuestionToMessage") +#pragma comment(linker, "/EXPORT:Dns_WriteRecordStructureToPacketEx=dnsapi.Dns_WriteRecordStructureToPacketEx") +#pragma comment(linker, "/EXPORT:ExtraInfo_Init=dnsapi.ExtraInfo_Init") +#pragma comment(linker, "/EXPORT:Faz_AreServerListsInSameNameSpace=dnsapi.Faz_AreServerListsInSameNameSpace") +#pragma comment(linker, "/EXPORT:FlushDnsPolicyUnreachableStatus=dnsapi.FlushDnsPolicyUnreachableStatus") +#pragma comment(linker, "/EXPORT:GetCurrentTimeInSeconds=dnsapi.GetCurrentTimeInSeconds") +#pragma comment(linker, "/EXPORT:HostsFile_Close=dnsapi.HostsFile_Close") +#pragma comment(linker, "/EXPORT:HostsFile_Open=dnsapi.HostsFile_Open") +#pragma comment(linker, "/EXPORT:HostsFile_ReadLine=dnsapi.HostsFile_ReadLine") +#pragma comment(linker, "/EXPORT:IpHelp_IsAddrOnLink=dnsapi.IpHelp_IsAddrOnLink") +#pragma comment(linker, "/EXPORT:Local_GetRecordsForLocalName=dnsapi.Local_GetRecordsForLocalName") +#pragma comment(linker, "/EXPORT:Local_GetRecordsForLocalNameEx=dnsapi.Local_GetRecordsForLocalNameEx") +#pragma comment(linker, "/EXPORT:NetInfo_Build=dnsapi.NetInfo_Build") +#pragma comment(linker, "/EXPORT:NetInfo_Clean=dnsapi.NetInfo_Clean") +#pragma comment(linker, "/EXPORT:NetInfo_Copy=dnsapi.NetInfo_Copy") +#pragma comment(linker, "/EXPORT:NetInfo_Free=dnsapi.NetInfo_Free") +#pragma comment(linker, "/EXPORT:NetInfo_GetAdapterByAddress=dnsapi.NetInfo_GetAdapterByAddress") +#pragma comment(linker, "/EXPORT:NetInfo_GetAdapterByInterfaceIndex=dnsapi.NetInfo_GetAdapterByInterfaceIndex") +#pragma comment(linker, "/EXPORT:NetInfo_GetAdapterByName=dnsapi.NetInfo_GetAdapterByName") +#pragma comment(linker, "/EXPORT:NetInfo_IsAddrConfig=dnsapi.NetInfo_IsAddrConfig") +#pragma comment(linker, "/EXPORT:NetInfo_IsForUpdate=dnsapi.NetInfo_IsForUpdate") +#pragma comment(linker, "/EXPORT:NetInfo_ResetServerPriorities=dnsapi.NetInfo_ResetServerPriorities") +#pragma comment(linker, "/EXPORT:NetInfo_UpdateServerReachability=dnsapi.NetInfo_UpdateServerReachability") +#pragma comment(linker, "/EXPORT:QueryDirectEx=dnsapi.QueryDirectEx") +#pragma comment(linker, "/EXPORT:Query_Main=dnsapi.Query_Main") +#pragma comment(linker, "/EXPORT:Reg_FreeUpdateInfo=dnsapi.Reg_FreeUpdateInfo") +#pragma comment(linker, "/EXPORT:Reg_GetValueEx=dnsapi.Reg_GetValueEx") +#pragma comment(linker, "/EXPORT:Reg_ReadGlobalsEx=dnsapi.Reg_ReadGlobalsEx") +#pragma comment(linker, "/EXPORT:Reg_ReadUpdateInfo=dnsapi.Reg_ReadUpdateInfo") +#pragma comment(linker, "/EXPORT:Security_ContextListTimeout=dnsapi.Security_ContextListTimeout") +#pragma comment(linker, "/EXPORT:Send_AndRecvUdpWithParam=dnsapi.Send_AndRecvUdpWithParam") +#pragma comment(linker, "/EXPORT:Send_MessagePrivate=dnsapi.Send_MessagePrivate") +#pragma comment(linker, "/EXPORT:Send_OpenTcpConnectionAndSend=dnsapi.Send_OpenTcpConnectionAndSend") +#pragma comment(linker, "/EXPORT:Socket_CacheCleanup=dnsapi.Socket_CacheCleanup") +#pragma comment(linker, "/EXPORT:Socket_CacheInit=dnsapi.Socket_CacheInit") +#pragma comment(linker, "/EXPORT:Socket_CleanupWinsock=dnsapi.Socket_CleanupWinsock") +#pragma comment(linker, "/EXPORT:Socket_ClearMessageSockets=dnsapi.Socket_ClearMessageSockets") +#pragma comment(linker, "/EXPORT:Socket_CloseEx=dnsapi.Socket_CloseEx") +#pragma comment(linker, "/EXPORT:Socket_CloseMessageSockets=dnsapi.Socket_CloseMessageSockets") +#pragma comment(linker, "/EXPORT:Socket_Create=dnsapi.Socket_Create") +#pragma comment(linker, "/EXPORT:Socket_CreateMulticast=dnsapi.Socket_CreateMulticast") +#pragma comment(linker, "/EXPORT:Socket_InitWinsock=dnsapi.Socket_InitWinsock") +#pragma comment(linker, "/EXPORT:Socket_JoinMulticast=dnsapi.Socket_JoinMulticast") +#pragma comment(linker, "/EXPORT:Socket_RecvFrom=dnsapi.Socket_RecvFrom") +#pragma comment(linker, "/EXPORT:Socket_SetMulticastInterface=dnsapi.Socket_SetMulticastInterface") +#pragma comment(linker, "/EXPORT:Socket_SetMulticastLoopBack=dnsapi.Socket_SetMulticastLoopBack") +#pragma comment(linker, "/EXPORT:Socket_SetTtl=dnsapi.Socket_SetTtl") +#pragma comment(linker, "/EXPORT:Socket_TcpListen=dnsapi.Socket_TcpListen") +#pragma comment(linker, "/EXPORT:Trace_Reset=dnsapi.Trace_Reset") +#pragma comment(linker, "/EXPORT:Update_ReplaceAddressRecordsW=dnsapi.Update_ReplaceAddressRecordsW") +#pragma comment(linker, "/EXPORT:Util_IsIp6Running=dnsapi.Util_IsIp6Running") + +// Generated by KexExprt from "winhttp.dll" +#pragma comment(linker, "/EXPORT:DllCanUnloadNow=winhttp.DllCanUnloadNow,PRIVATE") +#pragma comment(linker, "/EXPORT:DllGetClassObject=winhttp.DllGetClassObject,PRIVATE") +#pragma comment(linker, "/EXPORT:Private1=winhttp.Private1") +#pragma comment(linker, "/EXPORT:SvchostPushServiceGlobals=winhttp.SvchostPushServiceGlobals") +#pragma comment(linker, "/EXPORT:WinHttpAddRequestHeaders=winhttp.WinHttpAddRequestHeaders") +#pragma comment(linker, "/EXPORT:WinHttpAutoProxySvcMain=winhttp.WinHttpAutoProxySvcMain") +#pragma comment(linker, "/EXPORT:WinHttpCheckPlatform=winhttp.WinHttpCheckPlatform") +#pragma comment(linker, "/EXPORT:WinHttpCloseHandle=winhttp.WinHttpCloseHandle") +#pragma comment(linker, "/EXPORT:WinHttpConnect=winhttp.WinHttpConnect") +#pragma comment(linker, "/EXPORT:WinHttpCrackUrl=winhttp.WinHttpCrackUrl") +#pragma comment(linker, "/EXPORT:WinHttpCreateUrl=winhttp.WinHttpCreateUrl") +#pragma comment(linker, "/EXPORT:WinHttpDetectAutoProxyConfigUrl=winhttp.WinHttpDetectAutoProxyConfigUrl") +#pragma comment(linker, "/EXPORT:WinHttpGetDefaultProxyConfiguration=winhttp.WinHttpGetDefaultProxyConfiguration") +#pragma comment(linker, "/EXPORT:WinHttpGetIEProxyConfigForCurrentUser=winhttp.WinHttpGetIEProxyConfigForCurrentUser") +#pragma comment(linker, "/EXPORT:WinHttpGetProxyForUrl=winhttp.WinHttpGetProxyForUrl") +#pragma comment(linker, "/EXPORT:WinHttpOpen=winhttp.WinHttpOpen") +#pragma comment(linker, "/EXPORT:WinHttpOpenRequest=winhttp.WinHttpOpenRequest") +#pragma comment(linker, "/EXPORT:WinHttpQueryAuthSchemes=winhttp.WinHttpQueryAuthSchemes") +#pragma comment(linker, "/EXPORT:WinHttpQueryDataAvailable=winhttp.WinHttpQueryDataAvailable") +#pragma comment(linker, "/EXPORT:WinHttpQueryHeaders=winhttp.WinHttpQueryHeaders") +#pragma comment(linker, "/EXPORT:WinHttpQueryOption=winhttp.WinHttpQueryOption") +#pragma comment(linker, "/EXPORT:WinHttpReadData=winhttp.WinHttpReadData") +#pragma comment(linker, "/EXPORT:WinHttpReceiveResponse=winhttp.WinHttpReceiveResponse") +#pragma comment(linker, "/EXPORT:WinHttpSendRequest=winhttp.WinHttpSendRequest") +#pragma comment(linker, "/EXPORT:WinHttpSetCredentials=winhttp.WinHttpSetCredentials") +#pragma comment(linker, "/EXPORT:WinHttpSetDefaultProxyConfiguration=winhttp.WinHttpSetDefaultProxyConfiguration") +#pragma comment(linker, "/EXPORT:WinHttpSetOption=winhttp.WinHttpSetOption") +#pragma comment(linker, "/EXPORT:WinHttpSetStatusCallback=winhttp.WinHttpSetStatusCallback") +#pragma comment(linker, "/EXPORT:WinHttpSetTimeouts=winhttp.WinHttpSetTimeouts") +#pragma comment(linker, "/EXPORT:WinHttpTimeFromSystemTime=winhttp.WinHttpTimeFromSystemTime") +#pragma comment(linker, "/EXPORT:WinHttpTimeToSystemTime=winhttp.WinHttpTimeToSystemTime") +#pragma comment(linker, "/EXPORT:WinHttpWriteData=winhttp.WinHttpWriteData") + +// Generated by KexExprt from "C:\Windows\system32\ws2_32.dll" +#pragma comment(linker, "/EXPORT:FreeAddrInfoEx=ws2_32.FreeAddrInfoEx,@25") +#pragma comment(linker, "/EXPORT:FreeAddrInfoExW=ws2_32.FreeAddrInfoExW,@26") +#pragma comment(linker, "/EXPORT:FreeAddrInfoW=ws2_32.FreeAddrInfoW,@27") +#pragma comment(linker, "/EXPORT:GetAddrInfoExA=ws2_32.GetAddrInfoExA,@28") +#pragma comment(linker, "/EXPORT:GetAddrInfoExW=ws2_32.GetAddrInfoExW,@29") +#pragma comment(linker, "/EXPORT:GetAddrInfoW=ws2_32.GetAddrInfoW,@30") +#pragma comment(linker, "/EXPORT:GetNameInfoW=ws2_32.GetNameInfoW,@31") +#pragma comment(linker, "/EXPORT:InetNtopW=ws2_32.InetNtopW,@32") +#pragma comment(linker, "/EXPORT:InetPtonW=ws2_32.InetPtonW,@33") +#pragma comment(linker, "/EXPORT:SetAddrInfoExA=ws2_32.SetAddrInfoExA,@34") +#pragma comment(linker, "/EXPORT:SetAddrInfoExW=ws2_32.SetAddrInfoExW,@35") +#pragma comment(linker, "/EXPORT:WEP=ws2_32.WEP,@500") +#pragma comment(linker, "/EXPORT:WPUCompleteOverlappedRequest=ws2_32.WPUCompleteOverlappedRequest,@36") +#pragma comment(linker, "/EXPORT:WSAAccept=ws2_32.WSAAccept,@37") +#pragma comment(linker, "/EXPORT:WSAAddressToStringA=ws2_32.WSAAddressToStringA,@38") +#pragma comment(linker, "/EXPORT:WSAAddressToStringW=ws2_32.WSAAddressToStringW,@39") +#pragma comment(linker, "/EXPORT:WSAAdvertiseProvider=ws2_32.WSAAdvertiseProvider,@40") +#pragma comment(linker, "/EXPORT:WSAAsyncGetHostByAddr=ws2_32.WSAAsyncGetHostByAddr,@102") +#pragma comment(linker, "/EXPORT:WSAAsyncGetHostByName=ws2_32.WSAAsyncGetHostByName,@103") +#pragma comment(linker, "/EXPORT:WSAAsyncGetProtoByName=ws2_32.WSAAsyncGetProtoByName,@105") +#pragma comment(linker, "/EXPORT:WSAAsyncGetProtoByNumber=ws2_32.WSAAsyncGetProtoByNumber,@104") +#pragma comment(linker, "/EXPORT:WSAAsyncGetServByName=ws2_32.WSAAsyncGetServByName,@107") +#pragma comment(linker, "/EXPORT:WSAAsyncGetServByPort=ws2_32.WSAAsyncGetServByPort,@106") +#pragma comment(linker, "/EXPORT:WSAAsyncSelect=ws2_32.WSAAsyncSelect,@101") +#pragma comment(linker, "/EXPORT:WSACancelAsyncRequest=ws2_32.WSACancelAsyncRequest,@108") +#pragma comment(linker, "/EXPORT:WSACancelBlockingCall=ws2_32.WSACancelBlockingCall,@113") +#pragma comment(linker, "/EXPORT:WSACleanup=ws2_32.WSACleanup,@116") +#pragma comment(linker, "/EXPORT:WSACloseEvent=ws2_32.WSACloseEvent,@41") +#pragma comment(linker, "/EXPORT:WSAConnect=ws2_32.WSAConnect,@42") +#pragma comment(linker, "/EXPORT:WSAConnectByList=ws2_32.WSAConnectByList,@43") +#pragma comment(linker, "/EXPORT:WSAConnectByNameA=ws2_32.WSAConnectByNameA,@44") +#pragma comment(linker, "/EXPORT:WSAConnectByNameW=ws2_32.WSAConnectByNameW,@45") +#pragma comment(linker, "/EXPORT:WSACreateEvent=ws2_32.WSACreateEvent,@46") +#pragma comment(linker, "/EXPORT:WSADuplicateSocketA=ws2_32.WSADuplicateSocketA,@47") +#pragma comment(linker, "/EXPORT:WSADuplicateSocketW=ws2_32.WSADuplicateSocketW,@48") +#pragma comment(linker, "/EXPORT:WSAEnumNameSpaceProvidersA=ws2_32.WSAEnumNameSpaceProvidersA,@49") +#pragma comment(linker, "/EXPORT:WSAEnumNameSpaceProvidersExA=ws2_32.WSAEnumNameSpaceProvidersExA,@50") +#pragma comment(linker, "/EXPORT:WSAEnumNameSpaceProvidersExW=ws2_32.WSAEnumNameSpaceProvidersExW,@58") +#pragma comment(linker, "/EXPORT:WSAEnumNameSpaceProvidersW=ws2_32.WSAEnumNameSpaceProvidersW,@59") +#pragma comment(linker, "/EXPORT:WSAEnumNetworkEvents=ws2_32.WSAEnumNetworkEvents,@60") +#pragma comment(linker, "/EXPORT:WSAEnumProtocolsA=ws2_32.WSAEnumProtocolsA,@61") +#pragma comment(linker, "/EXPORT:WSAEnumProtocolsW=ws2_32.WSAEnumProtocolsW,@62") +#pragma comment(linker, "/EXPORT:WSAEventSelect=ws2_32.WSAEventSelect,@63") +#pragma comment(linker, "/EXPORT:WSAGetLastError=ws2_32.WSAGetLastError,@111") +#pragma comment(linker, "/EXPORT:WSAGetOverlappedResult=ws2_32.WSAGetOverlappedResult,@64") +#pragma comment(linker, "/EXPORT:WSAGetQOSByName=ws2_32.WSAGetQOSByName,@65") +#pragma comment(linker, "/EXPORT:WSAGetServiceClassInfoA=ws2_32.WSAGetServiceClassInfoA,@66") +#pragma comment(linker, "/EXPORT:WSAGetServiceClassInfoW=ws2_32.WSAGetServiceClassInfoW,@67") +#pragma comment(linker, "/EXPORT:WSAGetServiceClassNameByClassIdA=ws2_32.WSAGetServiceClassNameByClassIdA,@68") +#pragma comment(linker, "/EXPORT:WSAGetServiceClassNameByClassIdW=ws2_32.WSAGetServiceClassNameByClassIdW,@69") +#pragma comment(linker, "/EXPORT:WSAHtonl=ws2_32.WSAHtonl,@70") +#pragma comment(linker, "/EXPORT:WSAHtons=ws2_32.WSAHtons,@71") +#pragma comment(linker, "/EXPORT:WSAInstallServiceClassA=ws2_32.WSAInstallServiceClassA,@72") +#pragma comment(linker, "/EXPORT:WSAInstallServiceClassW=ws2_32.WSAInstallServiceClassW,@73") +#pragma comment(linker, "/EXPORT:WSAIoctl=ws2_32.WSAIoctl,@74") +#pragma comment(linker, "/EXPORT:WSAIsBlocking=ws2_32.WSAIsBlocking,@114") +#pragma comment(linker, "/EXPORT:WSAJoinLeaf=ws2_32.WSAJoinLeaf,@75") +#pragma comment(linker, "/EXPORT:WSALookupServiceBeginA=ws2_32.WSALookupServiceBeginA,@76") +#pragma comment(linker, "/EXPORT:WSALookupServiceBeginW=ws2_32.WSALookupServiceBeginW,@77") +#pragma comment(linker, "/EXPORT:WSALookupServiceEnd=ws2_32.WSALookupServiceEnd,@78") +#pragma comment(linker, "/EXPORT:WSALookupServiceNextA=ws2_32.WSALookupServiceNextA,@79") +#pragma comment(linker, "/EXPORT:WSALookupServiceNextW=ws2_32.WSALookupServiceNextW,@80") +#pragma comment(linker, "/EXPORT:WSANSPIoctl=ws2_32.WSANSPIoctl,@81") +#pragma comment(linker, "/EXPORT:WSANtohl=ws2_32.WSANtohl,@82") +#pragma comment(linker, "/EXPORT:WSANtohs=ws2_32.WSANtohs,@83") +#pragma comment(linker, "/EXPORT:WSAPoll=ws2_32.WSAPoll,@84") +#pragma comment(linker, "/EXPORT:WSAProviderCompleteAsyncCall=ws2_32.WSAProviderCompleteAsyncCall,@85") +#pragma comment(linker, "/EXPORT:WSAProviderConfigChange=ws2_32.WSAProviderConfigChange,@86") +#pragma comment(linker, "/EXPORT:WSARecv=ws2_32.WSARecv,@87") +#pragma comment(linker, "/EXPORT:WSARecvDisconnect=ws2_32.WSARecvDisconnect,@88") +#pragma comment(linker, "/EXPORT:WSARecvFrom=ws2_32.WSARecvFrom,@89") +#pragma comment(linker, "/EXPORT:WSARemoveServiceClass=ws2_32.WSARemoveServiceClass,@90") +#pragma comment(linker, "/EXPORT:WSAResetEvent=ws2_32.WSAResetEvent,@91") +#pragma comment(linker, "/EXPORT:WSASend=ws2_32.WSASend,@92") +#pragma comment(linker, "/EXPORT:WSASendDisconnect=ws2_32.WSASendDisconnect,@93") +#pragma comment(linker, "/EXPORT:WSASendMsg=ws2_32.WSASendMsg,@94") +#pragma comment(linker, "/EXPORT:WSASendTo=ws2_32.WSASendTo,@95") +#pragma comment(linker, "/EXPORT:WSASetBlockingHook=ws2_32.WSASetBlockingHook,@109") +#pragma comment(linker, "/EXPORT:WSASetEvent=ws2_32.WSASetEvent,@96") +#pragma comment(linker, "/EXPORT:WSASetLastError=ws2_32.WSASetLastError,@112") +#pragma comment(linker, "/EXPORT:WSASetServiceA=ws2_32.WSASetServiceA,@97") +#pragma comment(linker, "/EXPORT:WSASetServiceW=ws2_32.WSASetServiceW,@98") +#pragma comment(linker, "/EXPORT:WSASocketA=ws2_32.WSASocketA,@99") +#pragma comment(linker, "/EXPORT:WSASocketW=ws2_32.WSASocketW,@100") +#pragma comment(linker, "/EXPORT:WSAStartup=ws2_32.WSAStartup,@115") +#pragma comment(linker, "/EXPORT:WSAStringToAddressA=ws2_32.WSAStringToAddressA,@117") +#pragma comment(linker, "/EXPORT:WSAStringToAddressW=ws2_32.WSAStringToAddressW,@118") +#pragma comment(linker, "/EXPORT:WSAUnadvertiseProvider=ws2_32.WSAUnadvertiseProvider,@119") +#pragma comment(linker, "/EXPORT:WSAUnhookBlockingHook=ws2_32.WSAUnhookBlockingHook,@110") +#pragma comment(linker, "/EXPORT:WSAWaitForMultipleEvents=ws2_32.WSAWaitForMultipleEvents,@120") +#pragma comment(linker, "/EXPORT:WSApSetPostRoutine=ws2_32.WSApSetPostRoutine,@24") +#pragma comment(linker, "/EXPORT:WSCDeinstallProvider=ws2_32.WSCDeinstallProvider,@121") +#pragma comment(linker, "/EXPORT:WSCDeinstallProvider32=ws2_32.WSCDeinstallProvider32,@122") +#pragma comment(linker, "/EXPORT:WSCEnableNSProvider=ws2_32.WSCEnableNSProvider,@123") +#pragma comment(linker, "/EXPORT:WSCEnableNSProvider32=ws2_32.WSCEnableNSProvider32,@124") +#pragma comment(linker, "/EXPORT:WSCEnumNameSpaceProviders32=ws2_32.WSCEnumNameSpaceProviders32,@125") +#pragma comment(linker, "/EXPORT:WSCEnumNameSpaceProvidersEx32=ws2_32.WSCEnumNameSpaceProvidersEx32,@126") +#pragma comment(linker, "/EXPORT:WSCEnumProtocols=ws2_32.WSCEnumProtocols,@127") +#pragma comment(linker, "/EXPORT:WSCEnumProtocols32=ws2_32.WSCEnumProtocols32,@128") +#pragma comment(linker, "/EXPORT:WSCGetApplicationCategory=ws2_32.WSCGetApplicationCategory,@129") +#pragma comment(linker, "/EXPORT:WSCGetProviderInfo=ws2_32.WSCGetProviderInfo,@130") +#pragma comment(linker, "/EXPORT:WSCGetProviderInfo32=ws2_32.WSCGetProviderInfo32,@131") +#pragma comment(linker, "/EXPORT:WSCGetProviderPath=ws2_32.WSCGetProviderPath,@132") +#pragma comment(linker, "/EXPORT:WSCGetProviderPath32=ws2_32.WSCGetProviderPath32,@133") +#pragma comment(linker, "/EXPORT:WSCInstallNameSpace=ws2_32.WSCInstallNameSpace,@134") +#pragma comment(linker, "/EXPORT:WSCInstallNameSpace32=ws2_32.WSCInstallNameSpace32,@135") +#pragma comment(linker, "/EXPORT:WSCInstallNameSpaceEx=ws2_32.WSCInstallNameSpaceEx,@136") +#pragma comment(linker, "/EXPORT:WSCInstallNameSpaceEx32=ws2_32.WSCInstallNameSpaceEx32,@137") +#pragma comment(linker, "/EXPORT:WSCInstallProvider=ws2_32.WSCInstallProvider,@138") +#pragma comment(linker, "/EXPORT:WSCInstallProvider64_32=ws2_32.WSCInstallProvider64_32,@139") +#pragma comment(linker, "/EXPORT:WSCInstallProviderAndChains64_32=ws2_32.WSCInstallProviderAndChains64_32,@140") +#pragma comment(linker, "/EXPORT:WSCSetApplicationCategory=ws2_32.WSCSetApplicationCategory,@141") +#pragma comment(linker, "/EXPORT:WSCSetProviderInfo=ws2_32.WSCSetProviderInfo,@142") +#pragma comment(linker, "/EXPORT:WSCSetProviderInfo32=ws2_32.WSCSetProviderInfo32,@143") +#pragma comment(linker, "/EXPORT:WSCUnInstallNameSpace=ws2_32.WSCUnInstallNameSpace,@144") +#pragma comment(linker, "/EXPORT:WSCUnInstallNameSpace32=ws2_32.WSCUnInstallNameSpace32,@145") +#pragma comment(linker, "/EXPORT:WSCUpdateProvider=ws2_32.WSCUpdateProvider,@146") +#pragma comment(linker, "/EXPORT:WSCUpdateProvider32=ws2_32.WSCUpdateProvider32,@147") +#pragma comment(linker, "/EXPORT:WSCWriteNameSpaceOrder=ws2_32.WSCWriteNameSpaceOrder,@148") +#pragma comment(linker, "/EXPORT:WSCWriteNameSpaceOrder32=ws2_32.WSCWriteNameSpaceOrder32,@149") +#pragma comment(linker, "/EXPORT:WSCWriteProviderOrder=ws2_32.WSCWriteProviderOrder,@150") +#pragma comment(linker, "/EXPORT:WSCWriteProviderOrder32=ws2_32.WSCWriteProviderOrder32,@152") +#pragma comment(linker, "/EXPORT:WahCloseApcHelper=ws2_32.WahCloseApcHelper,@153") +#pragma comment(linker, "/EXPORT:WahCloseHandleHelper=ws2_32.WahCloseHandleHelper,@154") +#pragma comment(linker, "/EXPORT:WahCloseNotificationHandleHelper=ws2_32.WahCloseNotificationHandleHelper,@155") +#pragma comment(linker, "/EXPORT:WahCloseSocketHandle=ws2_32.WahCloseSocketHandle,@156") +#pragma comment(linker, "/EXPORT:WahCloseThread=ws2_32.WahCloseThread,@157") +#pragma comment(linker, "/EXPORT:WahCompleteRequest=ws2_32.WahCompleteRequest,@158") +#pragma comment(linker, "/EXPORT:WahCreateHandleContextTable=ws2_32.WahCreateHandleContextTable,@159") +#pragma comment(linker, "/EXPORT:WahCreateNotificationHandle=ws2_32.WahCreateNotificationHandle,@160") +#pragma comment(linker, "/EXPORT:WahCreateSocketHandle=ws2_32.WahCreateSocketHandle,@161") +#pragma comment(linker, "/EXPORT:WahDestroyHandleContextTable=ws2_32.WahDestroyHandleContextTable,@162") +#pragma comment(linker, "/EXPORT:WahDisableNonIFSHandleSupport=ws2_32.WahDisableNonIFSHandleSupport,@163") +#pragma comment(linker, "/EXPORT:WahEnableNonIFSHandleSupport=ws2_32.WahEnableNonIFSHandleSupport,@164") +#pragma comment(linker, "/EXPORT:WahEnumerateHandleContexts=ws2_32.WahEnumerateHandleContexts,@165") +#pragma comment(linker, "/EXPORT:WahInsertHandleContext=ws2_32.WahInsertHandleContext,@166") +#pragma comment(linker, "/EXPORT:WahNotifyAllProcesses=ws2_32.WahNotifyAllProcesses,@167") +#pragma comment(linker, "/EXPORT:WahOpenApcHelper=ws2_32.WahOpenApcHelper,@168") +#pragma comment(linker, "/EXPORT:WahOpenCurrentThread=ws2_32.WahOpenCurrentThread,@169") +#pragma comment(linker, "/EXPORT:WahOpenHandleHelper=ws2_32.WahOpenHandleHelper,@170") +#pragma comment(linker, "/EXPORT:WahOpenNotificationHandleHelper=ws2_32.WahOpenNotificationHandleHelper,@171") +#pragma comment(linker, "/EXPORT:WahQueueUserApc=ws2_32.WahQueueUserApc,@172") +#pragma comment(linker, "/EXPORT:WahReferenceContextByHandle=ws2_32.WahReferenceContextByHandle,@173") +#pragma comment(linker, "/EXPORT:WahRemoveHandleContext=ws2_32.WahRemoveHandleContext,@174") +#pragma comment(linker, "/EXPORT:WahWaitForNotification=ws2_32.WahWaitForNotification,@175") +#pragma comment(linker, "/EXPORT:WahWriteLSPEvent=ws2_32.WahWriteLSPEvent,@176") + +#ifdef _M_X64 +# pragma comment(linker, "/EXPORT:__WSAFDIsSet=ws2_32.__WSAFDIsSet,@151") +#else +# pragma comment(linker, "/EXPORT:___WSAFDIsSet=ws2_32.__WSAFDIsSet,@151") +#endif + +#pragma comment(linker, "/EXPORT:accept=ws2_32.accept,@1") +#pragma comment(linker, "/EXPORT:bind=ws2_32.bind,@2") +#pragma comment(linker, "/EXPORT:closesocket=ws2_32.closesocket,@3") +#pragma comment(linker, "/EXPORT:connect=ws2_32.connect,@4") +#pragma comment(linker, "/EXPORT:freeaddrinfo=ws2_32.freeaddrinfo,@177") +#pragma comment(linker, "/EXPORT:getaddrinfo=ws2_32.getaddrinfo,@178") +#pragma comment(linker, "/EXPORT:gethostbyaddr=ws2_32.gethostbyaddr,@51") +#pragma comment(linker, "/EXPORT:gethostbyname=ws2_32.gethostbyname,@52") +#pragma comment(linker, "/EXPORT:gethostname=ws2_32.gethostname,@57") +#pragma comment(linker, "/EXPORT:getnameinfo=ws2_32.getnameinfo,@179") +#pragma comment(linker, "/EXPORT:getpeername=ws2_32.getpeername,@5") +#pragma comment(linker, "/EXPORT:getprotobyname=ws2_32.getprotobyname,@53") +#pragma comment(linker, "/EXPORT:getprotobynumber=ws2_32.getprotobynumber,@54") +#pragma comment(linker, "/EXPORT:getservbyname=ws2_32.getservbyname,@55") +#pragma comment(linker, "/EXPORT:getservbyport=ws2_32.getservbyport,@56") +#pragma comment(linker, "/EXPORT:getsockname=ws2_32.getsockname,@6") +#pragma comment(linker, "/EXPORT:getsockopt=ws2_32.getsockopt,@7") +#pragma comment(linker, "/EXPORT:htonl=ws2_32.htonl,@8") +#pragma comment(linker, "/EXPORT:htons=ws2_32.htons,@9") +#pragma comment(linker, "/EXPORT:inet_addr=ws2_32.inet_addr,@11") +#pragma comment(linker, "/EXPORT:inet_ntoa=ws2_32.inet_ntoa,@12") +#pragma comment(linker, "/EXPORT:inet_ntop=ws2_32.inet_ntop,@180") +#pragma comment(linker, "/EXPORT:inet_pton=ws2_32.inet_pton,@181") +#pragma comment(linker, "/EXPORT:ioctlsocket=ws2_32.ioctlsocket,@10") +#pragma comment(linker, "/EXPORT:listen=ws2_32.listen,@13") +#pragma comment(linker, "/EXPORT:ntohl=ws2_32.ntohl,@14") +#pragma comment(linker, "/EXPORT:ntohs=ws2_32.ntohs,@15") +#pragma comment(linker, "/EXPORT:recv=ws2_32.recv,@16") +#pragma comment(linker, "/EXPORT:recvfrom=ws2_32.recvfrom,@17") +#pragma comment(linker, "/EXPORT:select=ws2_32.select,@18") +#pragma comment(linker, "/EXPORT:send=ws2_32.send,@19") +#pragma comment(linker, "/EXPORT:sendto=ws2_32.sendto,@20") +#pragma comment(linker, "/EXPORT:setsockopt=ws2_32.setsockopt,@21") +#pragma comment(linker, "/EXPORT:shutdown=ws2_32.shutdown,@22") +#pragma comment(linker, "/EXPORT:socket=ws2_32.socket,@23") +#pragma comment(linker, "/EXPORT:__OrdinalFunction182=ws2_32.#182,@182,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction183=ws2_32.#183,@183,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction184=ws2_32.#184,@184,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction185=ws2_32.#185,@185,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction186=ws2_32.#186,@186,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction187=ws2_32.#187,@187,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction188=ws2_32.#188,@188,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction189=ws2_32.#189,@189,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction190=ws2_32.#190,@190,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction191=ws2_32.#191,@191,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction192=ws2_32.#192,@192,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction193=ws2_32.#193,@193,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction194=ws2_32.#194,@194,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction195=ws2_32.#195,@195,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction196=ws2_32.#196,@196,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction197=ws2_32.#197,@197,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction198=ws2_32.#198,@198,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction199=ws2_32.#199,@199,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction200=ws2_32.#200,@200,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction201=ws2_32.#201,@201,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction202=ws2_32.#202,@202,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction203=ws2_32.#203,@203,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction204=ws2_32.#204,@204,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction205=ws2_32.#205,@205,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction206=ws2_32.#206,@206,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction207=ws2_32.#207,@207,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction208=ws2_32.#208,@208,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction209=ws2_32.#209,@209,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction210=ws2_32.#210,@210,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction211=ws2_32.#211,@211,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction212=ws2_32.#212,@212,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction213=ws2_32.#213,@213,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction214=ws2_32.#214,@214,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction215=ws2_32.#215,@215,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction216=ws2_32.#216,@216,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction217=ws2_32.#217,@217,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction218=ws2_32.#218,@218,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction219=ws2_32.#219,@219,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction220=ws2_32.#220,@220,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction221=ws2_32.#221,@221,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction222=ws2_32.#222,@222,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction223=ws2_32.#223,@223,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction224=ws2_32.#224,@224,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction225=ws2_32.#225,@225,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction226=ws2_32.#226,@226,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction227=ws2_32.#227,@227,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction228=ws2_32.#228,@228,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction229=ws2_32.#229,@229,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction230=ws2_32.#230,@230,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction231=ws2_32.#231,@231,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction232=ws2_32.#232,@232,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction233=ws2_32.#233,@233,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction234=ws2_32.#234,@234,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction235=ws2_32.#235,@235,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction236=ws2_32.#236,@236,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction237=ws2_32.#237,@237,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction238=ws2_32.#238,@238,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction239=ws2_32.#239,@239,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction240=ws2_32.#240,@240,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction241=ws2_32.#241,@241,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction242=ws2_32.#242,@242,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction243=ws2_32.#243,@243,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction244=ws2_32.#244,@244,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction245=ws2_32.#245,@245,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction246=ws2_32.#246,@246,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction247=ws2_32.#247,@247,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction248=ws2_32.#248,@248,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction249=ws2_32.#249,@249,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction250=ws2_32.#250,@250,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction251=ws2_32.#251,@251,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction252=ws2_32.#252,@252,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction253=ws2_32.#253,@253,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction254=ws2_32.#254,@254,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction255=ws2_32.#255,@255,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction256=ws2_32.#256,@256,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction257=ws2_32.#257,@257,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction258=ws2_32.#258,@258,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction259=ws2_32.#259,@259,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction260=ws2_32.#260,@260,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction261=ws2_32.#261,@261,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction262=ws2_32.#262,@262,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction263=ws2_32.#263,@263,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction264=ws2_32.#264,@264,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction265=ws2_32.#265,@265,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction266=ws2_32.#266,@266,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction267=ws2_32.#267,@267,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction268=ws2_32.#268,@268,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction269=ws2_32.#269,@269,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction270=ws2_32.#270,@270,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction271=ws2_32.#271,@271,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction272=ws2_32.#272,@272,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction273=ws2_32.#273,@273,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction274=ws2_32.#274,@274,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction275=ws2_32.#275,@275,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction276=ws2_32.#276,@276,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction277=ws2_32.#277,@277,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction278=ws2_32.#278,@278,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction279=ws2_32.#279,@279,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction280=ws2_32.#280,@280,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction281=ws2_32.#281,@281,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction282=ws2_32.#282,@282,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction283=ws2_32.#283,@283,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction284=ws2_32.#284,@284,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction285=ws2_32.#285,@285,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction286=ws2_32.#286,@286,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction287=ws2_32.#287,@287,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction288=ws2_32.#288,@288,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction289=ws2_32.#289,@289,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction290=ws2_32.#290,@290,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction291=ws2_32.#291,@291,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction292=ws2_32.#292,@292,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction293=ws2_32.#293,@293,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction294=ws2_32.#294,@294,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction295=ws2_32.#295,@295,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction296=ws2_32.#296,@296,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction297=ws2_32.#297,@297,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction298=ws2_32.#298,@298,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction299=ws2_32.#299,@299,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction300=ws2_32.#300,@300,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction301=ws2_32.#301,@301,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction302=ws2_32.#302,@302,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction303=ws2_32.#303,@303,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction304=ws2_32.#304,@304,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction305=ws2_32.#305,@305,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction306=ws2_32.#306,@306,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction307=ws2_32.#307,@307,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction308=ws2_32.#308,@308,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction309=ws2_32.#309,@309,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction310=ws2_32.#310,@310,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction311=ws2_32.#311,@311,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction312=ws2_32.#312,@312,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction313=ws2_32.#313,@313,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction314=ws2_32.#314,@314,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction315=ws2_32.#315,@315,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction316=ws2_32.#316,@316,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction317=ws2_32.#317,@317,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction318=ws2_32.#318,@318,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction319=ws2_32.#319,@319,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction320=ws2_32.#320,@320,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction321=ws2_32.#321,@321,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction322=ws2_32.#322,@322,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction323=ws2_32.#323,@323,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction324=ws2_32.#324,@324,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction325=ws2_32.#325,@325,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction326=ws2_32.#326,@326,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction327=ws2_32.#327,@327,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction328=ws2_32.#328,@328,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction329=ws2_32.#329,@329,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction330=ws2_32.#330,@330,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction331=ws2_32.#331,@331,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction332=ws2_32.#332,@332,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction333=ws2_32.#333,@333,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction334=ws2_32.#334,@334,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction335=ws2_32.#335,@335,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction336=ws2_32.#336,@336,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction337=ws2_32.#337,@337,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction338=ws2_32.#338,@338,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction339=ws2_32.#339,@339,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction340=ws2_32.#340,@340,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction341=ws2_32.#341,@341,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction342=ws2_32.#342,@342,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction343=ws2_32.#343,@343,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction344=ws2_32.#344,@344,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction345=ws2_32.#345,@345,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction346=ws2_32.#346,@346,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction347=ws2_32.#347,@347,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction348=ws2_32.#348,@348,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction349=ws2_32.#349,@349,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction350=ws2_32.#350,@350,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction351=ws2_32.#351,@351,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction352=ws2_32.#352,@352,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction353=ws2_32.#353,@353,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction354=ws2_32.#354,@354,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction355=ws2_32.#355,@355,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction356=ws2_32.#356,@356,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction357=ws2_32.#357,@357,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction358=ws2_32.#358,@358,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction359=ws2_32.#359,@359,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction360=ws2_32.#360,@360,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction361=ws2_32.#361,@361,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction362=ws2_32.#362,@362,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction363=ws2_32.#363,@363,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction364=ws2_32.#364,@364,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction365=ws2_32.#365,@365,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction366=ws2_32.#366,@366,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction367=ws2_32.#367,@367,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction368=ws2_32.#368,@368,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction369=ws2_32.#369,@369,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction370=ws2_32.#370,@370,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction371=ws2_32.#371,@371,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction372=ws2_32.#372,@372,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction373=ws2_32.#373,@373,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction374=ws2_32.#374,@374,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction375=ws2_32.#375,@375,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction376=ws2_32.#376,@376,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction377=ws2_32.#377,@377,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction378=ws2_32.#378,@378,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction379=ws2_32.#379,@379,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction380=ws2_32.#380,@380,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction381=ws2_32.#381,@381,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction382=ws2_32.#382,@382,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction383=ws2_32.#383,@383,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction384=ws2_32.#384,@384,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction385=ws2_32.#385,@385,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction386=ws2_32.#386,@386,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction387=ws2_32.#387,@387,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction388=ws2_32.#388,@388,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction389=ws2_32.#389,@389,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction390=ws2_32.#390,@390,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction391=ws2_32.#391,@391,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction392=ws2_32.#392,@392,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction393=ws2_32.#393,@393,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction394=ws2_32.#394,@394,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction395=ws2_32.#395,@395,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction396=ws2_32.#396,@396,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction397=ws2_32.#397,@397,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction398=ws2_32.#398,@398,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction399=ws2_32.#399,@399,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction400=ws2_32.#400,@400,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction401=ws2_32.#401,@401,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction402=ws2_32.#402,@402,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction403=ws2_32.#403,@403,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction404=ws2_32.#404,@404,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction405=ws2_32.#405,@405,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction406=ws2_32.#406,@406,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction407=ws2_32.#407,@407,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction408=ws2_32.#408,@408,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction409=ws2_32.#409,@409,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction410=ws2_32.#410,@410,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction411=ws2_32.#411,@411,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction412=ws2_32.#412,@412,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction413=ws2_32.#413,@413,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction414=ws2_32.#414,@414,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction415=ws2_32.#415,@415,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction416=ws2_32.#416,@416,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction417=ws2_32.#417,@417,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction418=ws2_32.#418,@418,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction419=ws2_32.#419,@419,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction420=ws2_32.#420,@420,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction421=ws2_32.#421,@421,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction422=ws2_32.#422,@422,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction423=ws2_32.#423,@423,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction424=ws2_32.#424,@424,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction425=ws2_32.#425,@425,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction426=ws2_32.#426,@426,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction427=ws2_32.#427,@427,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction428=ws2_32.#428,@428,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction429=ws2_32.#429,@429,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction430=ws2_32.#430,@430,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction431=ws2_32.#431,@431,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction432=ws2_32.#432,@432,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction433=ws2_32.#433,@433,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction434=ws2_32.#434,@434,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction435=ws2_32.#435,@435,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction436=ws2_32.#436,@436,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction437=ws2_32.#437,@437,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction438=ws2_32.#438,@438,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction439=ws2_32.#439,@439,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction440=ws2_32.#440,@440,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction441=ws2_32.#441,@441,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction442=ws2_32.#442,@442,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction443=ws2_32.#443,@443,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction444=ws2_32.#444,@444,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction445=ws2_32.#445,@445,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction446=ws2_32.#446,@446,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction447=ws2_32.#447,@447,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction448=ws2_32.#448,@448,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction449=ws2_32.#449,@449,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction450=ws2_32.#450,@450,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction451=ws2_32.#451,@451,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction452=ws2_32.#452,@452,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction453=ws2_32.#453,@453,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction454=ws2_32.#454,@454,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction455=ws2_32.#455,@455,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction456=ws2_32.#456,@456,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction457=ws2_32.#457,@457,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction458=ws2_32.#458,@458,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction459=ws2_32.#459,@459,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction460=ws2_32.#460,@460,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction461=ws2_32.#461,@461,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction462=ws2_32.#462,@462,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction463=ws2_32.#463,@463,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction464=ws2_32.#464,@464,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction465=ws2_32.#465,@465,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction466=ws2_32.#466,@466,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction467=ws2_32.#467,@467,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction468=ws2_32.#468,@468,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction469=ws2_32.#469,@469,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction470=ws2_32.#470,@470,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction471=ws2_32.#471,@471,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction472=ws2_32.#472,@472,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction473=ws2_32.#473,@473,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction474=ws2_32.#474,@474,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction475=ws2_32.#475,@475,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction476=ws2_32.#476,@476,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction477=ws2_32.#477,@477,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction478=ws2_32.#478,@478,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction479=ws2_32.#479,@479,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction480=ws2_32.#480,@480,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction481=ws2_32.#481,@481,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction482=ws2_32.#482,@482,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction483=ws2_32.#483,@483,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction484=ws2_32.#484,@484,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction485=ws2_32.#485,@485,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction486=ws2_32.#486,@486,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction487=ws2_32.#487,@487,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction488=ws2_32.#488,@488,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction489=ws2_32.#489,@489,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction490=ws2_32.#490,@490,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction491=ws2_32.#491,@491,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction492=ws2_32.#492,@492,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction493=ws2_32.#493,@493,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction494=ws2_32.#494,@494,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction495=ws2_32.#495,@495,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction496=ws2_32.#496,@496,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction497=ws2_32.#497,@497,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction498=ws2_32.#498,@498,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction499=ws2_32.#499,@499,NONAME") diff --git a/01-Extended DLLs/KxNet/kxnet.def b/01-Extended DLLs/KxNet/kxnet.def new file mode 100644 index 0000000..2b7116a --- /dev/null +++ b/01-Extended DLLs/KxNet/kxnet.def @@ -0,0 +1,13 @@ +LIBRARY KxNet +EXPORTS + ;; dns.c + DnsQueryEx + + ;; winhttp.c + WinHttpCreateProxyResolver + WinHttpGetProxyForUrlEx + WinHttpGetProxyResult + WinHttpFreeProxyResult + + ;; winsock.c + GetHostNameW \ No newline at end of file diff --git a/01-Extended DLLs/KxNet/kxnet.rc b/01-Extended DLLs/KxNet/kxnet.rc new file mode 100644 index 0000000..479d852 --- /dev/null +++ b/01-Extended DLLs/KxNet/kxnet.rc @@ -0,0 +1,30 @@ +#include "buildcfg.h" +#include +#include + +1 VERSIONINFO + FILEVERSION KEX_VERSION_FV + FILEOS VOS_NT +#if defined(KEX_TARGET_TYPE_EXE) + FILETYPE VFT_APP +#elif defined(KEX_TARGET_TYPE_DLL) + FILETYPE VFT_DLL +#endif +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904B0" + BEGIN + VALUE "LegalCopyright", KEX_WEB_STR + VALUE "FileDescription", "VxKex Network & Internet API Extension DLL" + VALUE "FileVersion", KEX_VERSION_STR + VALUE "InternalName", KEX_COMPONENT + VALUE "OriginalFilename", "KXNET.DLL" + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409 0x04B0 + END +END \ No newline at end of file diff --git a/01-Extended DLLs/KxNet/kxnetp.h b/01-Extended DLLs/KxNet/kxnetp.h new file mode 100644 index 0000000..9965f96 --- /dev/null +++ b/01-Extended DLLs/KxNet/kxnetp.h @@ -0,0 +1,124 @@ +#include "buildcfg.h" +#include +#include +#include + +EXTERN PKEX_PROCESS_DATA KexData; + +#define DNS_ADDR_MAX_SOCKADDR_LENGTH 32 + +typedef struct _DNS_ADDR { + CHAR MaxSa[DNS_ADDR_MAX_SOCKADDR_LENGTH]; + ULONG DnsAddrUserDword[8]; +} TYPEDEF_TYPE_NAME(DNS_ADDR); + +typedef struct _DNS_ADDR_ARRAY { + ULONG MaxCount; + ULONG NumberOfAddresses; + ULONG Tag; + USHORT Family; + USHORT Reserved1; + ULONG Flags; + ULONG MatchFlag; + ULONG Reserved2; + ULONG Reserved3; + DNS_ADDR Addresses[]; +} TYPEDEF_TYPE_NAME(DNS_ADDR_ARRAY); + +typedef struct _DNS_QUERY_RESULT { + ULONG Version; + DNS_STATUS QueryStatus; + ULONGLONG QueryOptions; + PDNS_RECORD QueryRecords; + PVOID Reserved; +} TYPEDEF_TYPE_NAME(DNS_QUERY_RESULT); + +typedef VOID (CALLBACK *PDNS_QUERY_COMPLETION_ROUTINE) ( + IN PVOID QueryContext, + IN OUT PDNS_QUERY_RESULT QueryResults); + +typedef struct _DNS_QUERY_REQUEST { + ULONG Version; + PCWSTR QueryName; + USHORT QueryType; + ULONGLONG QueryOptions; + PDNS_ADDR_ARRAY DnsServerList; + ULONG InterfaceIndex; + PDNS_QUERY_COMPLETION_ROUTINE QueryCompletionCallback; + PVOID QueryContext; +} TYPEDEF_TYPE_NAME(DNS_QUERY_REQUEST); + +typedef struct _DNS_QUERY_CANCEL { + BYTE Unknown[32]; +} TYPEDEF_TYPE_NAME(DNS_QUERY_CANCEL); + +typedef struct _DNS_RESULTS_BASIC { + DNS_STATUS Status; + USHORT ResponseCode; + DNS_ADDR ServerAddr; +} TYPEDEF_TYPE_NAME(DNS_RESULTS_BASIC); + +#define DNS_MAX_ALIAS_COUNT 8 + +typedef struct _DNS_SOCKADDR_RESULTS { + PWSTR Name; + PDNS_ADDR_ARRAY AddressArray; + PVOID Hostent; + ULONG AliasCount; + ULONG Reserved; + PWSTR AliasArray[DNS_MAX_ALIAS_COUNT]; +} TYPEDEF_TYPE_NAME(DNS_SOCKADDR_RESULTS); + +typedef struct _DNS_EXTRA_INFO *PDNS_EXTRA_INFO; +#define DNS_MAX_PRIVATE_EXTRA_INFO_SIZE 72 + +typedef struct _DNS_EXTRA_INFO { + PDNS_EXTRA_INFO Next; + ULONG Id; + + union { + CHAR Flat[DNS_MAX_PRIVATE_EXTRA_INFO_SIZE]; + + struct { + DNS_STATUS Status; + USHORT ResponseCode; + IP4_ADDRESS ServerIp4; + IP6_ADDRESS ServerIp6; + } ResultsV1; + + DNS_RESULTS_BASIC ResultsBasic; + DNS_SOCKADDR_RESULTS SaResults; + + PDNS_ADDR_ARRAY ServerList; + PIP4_ARRAY ServerList4; + }; +} TYPEDEF_TYPE_NAME(DNS_EXTRA_INFO); + +typedef struct _DNS_QUERY_INFO { + ULONG Size; + ULONG Version; + PWSTR QueryName; + USHORT QueryType; + USHORT ResponseCode; + ULONG Flags; + DNS_STATUS Status; + DNS_CHARSET CharSet; + + PDNS_RECORD AnswerRecords; + PDNS_RECORD AliasRecords; + PDNS_RECORD AdditionalRecords; + PDNS_RECORD AuthorityRecords; + + HANDLE EventHandle; + PDNS_EXTRA_INFO ExtraInfo; + + PVOID ServerList; + PIP4_ARRAY ServerListIp4; + + PVOID Message; + PVOID ReservedName; +} TYPEDEF_TYPE_NAME(DNS_QUERY_INFO); + +// Undocumented function from dnsapi.dll +DNS_STATUS WINAPI DnsQueryExW( + IN OUT PDNS_QUERY_INFO QueryInfo); \ No newline at end of file diff --git a/01-Extended DLLs/KxNet/winhttp.c b/01-Extended DLLs/KxNet/winhttp.c new file mode 100644 index 0000000..8660a81 --- /dev/null +++ b/01-Extended DLLs/KxNet/winhttp.c @@ -0,0 +1,39 @@ +#include "buildcfg.h" +#include "kxnetp.h" + +KXNETAPI ULONG WINAPI WinHttpCreateProxyResolver( + IN HINTERNET SessionHandle, + OUT HINTERNET *Resolver) +{ + KexLogWarningEvent(L"Unimplemented WinHTTP function called"); + KexDebugCheckpoint(); + *Resolver = (HINTERNET) 0x12345678; + return ERROR_SUCCESS; +} + +KXNETAPI ULONG WINAPI WinHttpGetProxyForUrlEx( + IN HINTERNET Resolver, + IN PCWSTR Url, + IN PVOID AutoProxyOptions, + IN ULONG_PTR Context) +{ + KexLogWarningEvent(L"Unimplemented WinHTTP function called"); + KexDebugCheckpoint(); + return ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT; +} + +KXNETAPI ULONG WINAPI WinHttpGetProxyResult( + IN HINTERNET Resolver, + OUT PVOID ProxyResult) +{ + KexLogWarningEvent(L"Unimplemented WinHTTP function called"); + KexDebugCheckpoint(); + return ERROR_WINHTTP_INCORRECT_HANDLE_STATE; +} + +KXNETAPI VOID WINAPI WinHttpFreeProxyResult( + IN OUT PVOID ProxyResult) +{ + KexLogWarningEvent(L"Unimplemented WinHTTP function called"); + KexDebugCheckpoint(); +} \ No newline at end of file diff --git a/01-Extended DLLs/KxNet/winsock.c b/01-Extended DLLs/KxNet/winsock.c new file mode 100644 index 0000000..f7a3dc5 --- /dev/null +++ b/01-Extended DLLs/KxNet/winsock.c @@ -0,0 +1,44 @@ +#include "buildcfg.h" +#include "kxnetp.h" +#include + +// +// libuv (which is used by some random node.js package that a lot of electron +// apps, such as VSCode, Signal, etc.) depends on GetHostNameW and will shit +// itself if not found. +// +KXNETAPI INT WINAPI GetHostNameW( + OUT PWSTR Name, + IN INT NameCch) +{ + INT ReturnValue; + INT ConvertedCch; + PCHAR NameAnsi; + + if (!NameCch) { + WSASetLastError(WSAEFAULT); + return SOCKET_ERROR; + } + + NameAnsi = StackAlloc(CHAR, NameCch); + ReturnValue = gethostname(NameAnsi, NameCch); + + if (ReturnValue == SOCKET_ERROR) { + return ReturnValue; + } + + ConvertedCch = MultiByteToWideChar( + CP_ACP, + 0, + NameAnsi, + -1, + Name, + NameCch); + + if (ConvertedCch == 0) { + WSASetLastError(WSAEFAULT); + return SOCKET_ERROR; + } + + return ReturnValue; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxNt/KxNt.rc b/01-Extended DLLs/KxNt/KxNt.rc new file mode 100644 index 0000000..acf45fe Binary files /dev/null and b/01-Extended DLLs/KxNt/KxNt.rc differ diff --git a/01-Extended DLLs/KxNt/KxNt.vcxproj b/01-Extended DLLs/KxNt/KxNt.vcxproj new file mode 100644 index 0000000..454901a --- /dev/null +++ b/01-Extended DLLs/KxNt/KxNt.vcxproj @@ -0,0 +1,235 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {7B17BE9E-D4A6-4652-BDE8-80FDE0DDC7D4} + Win32Proj + KxNt + + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + + + + + + + + + + + + + + + + + false + false + + + false + false + + + false + false + + + false + false + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;KXNT_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + true + true + false + false + Default + false + StdCall + CompileAsC + ProgramDatabase + + + Windows + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + KexDll.lib + DllMain + true + kxnt.def + true + + + $(SolutionDir)\00-Common Headers + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;KXNT_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + true + true + false + false + Default + false + StdCall + CompileAsC + ProgramDatabase + + + Windows + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + KexDll.lib + DllMain + true + kxnt.def + true + + + $(SolutionDir)\00-Common Headers + + + + + Level3 + NotUsing + MinSpace + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;KXNT_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + true + true + false + false + Default + false + StdCall + CompileAsC + OnlyExplicitInline + Size + true + ProgramDatabase + + + Windows + true + true + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + KexDll.lib + DllMain + true + kxnt.def + true + + + $(SolutionDir)\00-Common Headers + + + + + Level3 + NotUsing + MinSpace + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;KXNT_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + true + true + false + false + Default + false + StdCall + CompileAsC + OnlyExplicitInline + Size + true + ProgramDatabase + + + Windows + true + true + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + KexDll.lib + DllMain + true + kxnt.def + true + + + $(SolutionDir)\00-Common Headers + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/01-Extended DLLs/KxNt/KxNt.vcxproj.filters b/01-Extended DLLs/KxNt/KxNt.vcxproj.filters new file mode 100644 index 0000000..bc63dcd --- /dev/null +++ b/01-Extended DLLs/KxNt/KxNt.vcxproj.filters @@ -0,0 +1,40 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + + + Source Files + + + Source Files + + + + + Source Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/01-Extended DLLs/KxNt/buildcfg.h b/01-Extended DLLs/KxNt/buildcfg.h new file mode 100644 index 0000000..1f40e77 --- /dev/null +++ b/01-Extended DLLs/KxNt/buildcfg.h @@ -0,0 +1,45 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN +#define NOGDICAPMASKS +#define NOVIRTUALKEYCODES +#define NOWINMESSAGES +#define NOWINSTYLES +#define NOSYSMETRICS +#define NOMENUS +#define NOICONS +#define NOKEYSTATES +#define NOSYSCOMMANDS +#define NORASTEROPS +#define NOSHOWWINDOW +#define NOATOM +#define NOCLIPBOARD +#define NOCOLOR +#define NOCTLMGR +#define NODRAWTEXT +#define NOGDI +#define NOKERNEL +#define NOUSER +#define NONLS +#define NOMB +#define NOMEMMGR +#define NOMSG +#define NOOPENFILE +#define NOSCROLL +#define NOTEXTMETRIC +#define NOWH +#define NOWINOFFSETS +#define NOCOMM +#define NOKANJI +#define NOHELP +#define NOPROFILER +#define NODEFERWINDOWPOS +#define NOMCX +#define NOCRYPT +#define NOMETAFILE +#define NOSERVICE +#define NOSOUND + +#define KEX_ENV_NATIVE +#define KEX_TARGET_TYPE_DLL +#define KEX_COMPONENT L"KxNt" diff --git a/01-Extended DLLs/KxNt/dllmain.c b/01-Extended DLLs/KxNt/dllmain.c new file mode 100644 index 0000000..c1de868 --- /dev/null +++ b/01-Extended DLLs/KxNt/dllmain.c @@ -0,0 +1,14 @@ +#include "buildcfg.h" +#include + +BOOL WINAPI DllMain( + IN PVOID DllBase, + IN ULONG Reason, + IN PCONTEXT Context) +{ + if (Reason == DLL_PROCESS_ATTACH) { + LdrDisableThreadCalloutsForDll(DllBase); + } + + return TRUE; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxNt/forwards.c b/01-Extended DLLs/KxNt/forwards.c new file mode 100644 index 0000000..6a13d64 --- /dev/null +++ b/01-Extended DLLs/KxNt/forwards.c @@ -0,0 +1,4037 @@ +#ifdef _M_X64 +// Generated by KexExprt from "C:\Windows\system32\ntdll.dll" +#pragma comment(linker, "/EXPORT:A_SHAFinal=ntdll.A_SHAFinal,@9") +#pragma comment(linker, "/EXPORT:A_SHAInit=ntdll.A_SHAInit,@10") +#pragma comment(linker, "/EXPORT:A_SHAUpdate=ntdll.A_SHAUpdate,@11") +#pragma comment(linker, "/EXPORT:AlpcAdjustCompletionListConcurrencyCount=ntdll.AlpcAdjustCompletionListConcurrencyCount,@12") +#pragma comment(linker, "/EXPORT:AlpcFreeCompletionListMessage=ntdll.AlpcFreeCompletionListMessage,@13") +#pragma comment(linker, "/EXPORT:AlpcGetCompletionListLastMessageInformation=ntdll.AlpcGetCompletionListLastMessageInformation,@14") +#pragma comment(linker, "/EXPORT:AlpcGetCompletionListMessageAttributes=ntdll.AlpcGetCompletionListMessageAttributes,@15") +#pragma comment(linker, "/EXPORT:AlpcGetHeaderSize=ntdll.AlpcGetHeaderSize,@16") +#pragma comment(linker, "/EXPORT:AlpcGetMessageAttribute=ntdll.AlpcGetMessageAttribute,@17") +#pragma comment(linker, "/EXPORT:AlpcGetMessageFromCompletionList=ntdll.AlpcGetMessageFromCompletionList,@18") +#pragma comment(linker, "/EXPORT:AlpcGetOutstandingCompletionListMessageCount=ntdll.AlpcGetOutstandingCompletionListMessageCount,@19") +#pragma comment(linker, "/EXPORT:AlpcInitializeMessageAttribute=ntdll.AlpcInitializeMessageAttribute,@20") +#pragma comment(linker, "/EXPORT:AlpcMaxAllowedMessageLength=ntdll.AlpcMaxAllowedMessageLength,@21") +#pragma comment(linker, "/EXPORT:AlpcRegisterCompletionList=ntdll.AlpcRegisterCompletionList,@22") +#pragma comment(linker, "/EXPORT:AlpcRegisterCompletionListWorkerThread=ntdll.AlpcRegisterCompletionListWorkerThread,@23") +#pragma comment(linker, "/EXPORT:AlpcRundownCompletionList=ntdll.AlpcRundownCompletionList,@24") +#pragma comment(linker, "/EXPORT:AlpcUnregisterCompletionList=ntdll.AlpcUnregisterCompletionList,@25") +#pragma comment(linker, "/EXPORT:AlpcUnregisterCompletionListWorkerThread=ntdll.AlpcUnregisterCompletionListWorkerThread,@26") +#pragma comment(linker, "/EXPORT:CsrAllocateCaptureBuffer=ntdll.CsrAllocateCaptureBuffer,@27") +#pragma comment(linker, "/EXPORT:CsrAllocateMessagePointer=ntdll.CsrAllocateMessagePointer,@28") +#pragma comment(linker, "/EXPORT:CsrCaptureMessageBuffer=ntdll.CsrCaptureMessageBuffer,@29") +#pragma comment(linker, "/EXPORT:CsrCaptureMessageMultiUnicodeStringsInPlace=ntdll.CsrCaptureMessageMultiUnicodeStringsInPlace,@30") +#pragma comment(linker, "/EXPORT:CsrCaptureMessageString=ntdll.CsrCaptureMessageString,@31") +#pragma comment(linker, "/EXPORT:CsrCaptureTimeout=ntdll.CsrCaptureTimeout,@32") +#pragma comment(linker, "/EXPORT:CsrClientCallServer=ntdll.CsrClientCallServer,@33") +#pragma comment(linker, "/EXPORT:CsrClientConnectToServer=ntdll.CsrClientConnectToServer,@34") +#pragma comment(linker, "/EXPORT:CsrFreeCaptureBuffer=ntdll.CsrFreeCaptureBuffer,@35") +#pragma comment(linker, "/EXPORT:CsrGetProcessId=ntdll.CsrGetProcessId,@36") +#pragma comment(linker, "/EXPORT:CsrIdentifyAlertableThread=ntdll.CsrIdentifyAlertableThread,@37") +#pragma comment(linker, "/EXPORT:CsrSetPriorityClass=ntdll.CsrSetPriorityClass,@38") +#pragma comment(linker, "/EXPORT:CsrVerifyRegion=ntdll.CsrVerifyRegion,@39") +#pragma comment(linker, "/EXPORT:DbgBreakPoint=ntdll.DbgBreakPoint,@40") +#pragma comment(linker, "/EXPORT:DbgPrint=ntdll.DbgPrint,@41") +#pragma comment(linker, "/EXPORT:DbgPrintEx=ntdll.DbgPrintEx,@42") +#pragma comment(linker, "/EXPORT:DbgPrintReturnControlC=ntdll.DbgPrintReturnControlC,@43") +#pragma comment(linker, "/EXPORT:DbgPrompt=ntdll.DbgPrompt,@44") +#pragma comment(linker, "/EXPORT:DbgQueryDebugFilterState=ntdll.DbgQueryDebugFilterState,@45") +#pragma comment(linker, "/EXPORT:DbgSetDebugFilterState=ntdll.DbgSetDebugFilterState,@46") +#pragma comment(linker, "/EXPORT:DbgUiConnectToDbg=ntdll.DbgUiConnectToDbg,@47") +#pragma comment(linker, "/EXPORT:DbgUiContinue=ntdll.DbgUiContinue,@48") +#pragma comment(linker, "/EXPORT:DbgUiConvertStateChangeStructure=ntdll.DbgUiConvertStateChangeStructure,@49") +#pragma comment(linker, "/EXPORT:DbgUiDebugActiveProcess=ntdll.DbgUiDebugActiveProcess,@50") +#pragma comment(linker, "/EXPORT:DbgUiGetThreadDebugObject=ntdll.DbgUiGetThreadDebugObject,@51") +#pragma comment(linker, "/EXPORT:DbgUiIssueRemoteBreakin=ntdll.DbgUiIssueRemoteBreakin,@52") +#pragma comment(linker, "/EXPORT:DbgUiRemoteBreakin=ntdll.DbgUiRemoteBreakin,@53") +#pragma comment(linker, "/EXPORT:DbgUiSetThreadDebugObject=ntdll.DbgUiSetThreadDebugObject,@54") +#pragma comment(linker, "/EXPORT:DbgUiStopDebugging=ntdll.DbgUiStopDebugging,@55") +#pragma comment(linker, "/EXPORT:DbgUiWaitStateChange=ntdll.DbgUiWaitStateChange,@56") +#pragma comment(linker, "/EXPORT:DbgUserBreakPoint=ntdll.DbgUserBreakPoint,@57") +#pragma comment(linker, "/EXPORT:EtwCreateTraceInstanceId=ntdll.EtwCreateTraceInstanceId,@58") +#pragma comment(linker, "/EXPORT:EtwDeliverDataBlock=ntdll.EtwDeliverDataBlock,@59") +#pragma comment(linker, "/EXPORT:EtwEnumerateProcessRegGuids=ntdll.EtwEnumerateProcessRegGuids,@60") +#pragma comment(linker, "/EXPORT:EtwEventActivityIdControl=ntdll.EtwEventActivityIdControl,@61") +#pragma comment(linker, "/EXPORT:EtwEventEnabled=ntdll.EtwEventEnabled,@62") +#pragma comment(linker, "/EXPORT:EtwEventProviderEnabled=ntdll.EtwEventProviderEnabled,@63") +#pragma comment(linker, "/EXPORT:EtwEventRegister=ntdll.EtwEventRegister,@64") +//#pragma comment(linker, "/EXPORT:EtwEventSetInformation=ntdll.EtwEventSetInformation,@65") +#pragma comment(linker, "/EXPORT:EtwEventUnregister=ntdll.EtwEventUnregister,@66") +#pragma comment(linker, "/EXPORT:EtwEventWrite=ntdll.EtwEventWrite,@67") +#pragma comment(linker, "/EXPORT:EtwEventWriteEndScenario=ntdll.EtwEventWriteEndScenario,@68") +#pragma comment(linker, "/EXPORT:EtwEventWriteEx=ntdll.EtwEventWriteEx,@69") +#pragma comment(linker, "/EXPORT:EtwEventWriteFull=ntdll.EtwEventWriteFull,@70") +#pragma comment(linker, "/EXPORT:EtwEventWriteNoRegistration=ntdll.EtwEventWriteNoRegistration,@71") +#pragma comment(linker, "/EXPORT:EtwEventWriteStartScenario=ntdll.EtwEventWriteStartScenario,@72") +#pragma comment(linker, "/EXPORT:EtwEventWriteString=ntdll.EtwEventWriteString,@73") +#pragma comment(linker, "/EXPORT:EtwEventWriteTransfer=ntdll.EtwEventWriteTransfer,@74") +#pragma comment(linker, "/EXPORT:EtwGetTraceEnableFlags=ntdll.EtwGetTraceEnableFlags,@75") +#pragma comment(linker, "/EXPORT:EtwGetTraceEnableLevel=ntdll.EtwGetTraceEnableLevel,@76") +#pragma comment(linker, "/EXPORT:EtwGetTraceLoggerHandle=ntdll.EtwGetTraceLoggerHandle,@77") +#pragma comment(linker, "/EXPORT:EtwLogTraceEvent=ntdll.EtwLogTraceEvent,@78") +#pragma comment(linker, "/EXPORT:EtwNotificationRegister=ntdll.EtwNotificationRegister,@79") +#pragma comment(linker, "/EXPORT:EtwNotificationUnregister=ntdll.EtwNotificationUnregister,@80") +#pragma comment(linker, "/EXPORT:EtwProcessPrivateLoggerRequest=ntdll.EtwProcessPrivateLoggerRequest,@81") +#pragma comment(linker, "/EXPORT:EtwRegisterSecurityProvider=ntdll.EtwRegisterSecurityProvider,@82") +#pragma comment(linker, "/EXPORT:EtwRegisterTraceGuidsA=ntdll.EtwRegisterTraceGuidsA,@83") +#pragma comment(linker, "/EXPORT:EtwRegisterTraceGuidsW=ntdll.EtwRegisterTraceGuidsW,@84") +#pragma comment(linker, "/EXPORT:EtwReplyNotification=ntdll.EtwReplyNotification,@85") +#pragma comment(linker, "/EXPORT:EtwSendNotification=ntdll.EtwSendNotification,@86") +#pragma comment(linker, "/EXPORT:EtwSetMark=ntdll.EtwSetMark,@87") +#pragma comment(linker, "/EXPORT:EtwTraceEventInstance=ntdll.EtwTraceEventInstance,@88") +#pragma comment(linker, "/EXPORT:EtwTraceMessage=ntdll.EtwTraceMessage,@89") +#pragma comment(linker, "/EXPORT:EtwTraceMessageVa=ntdll.EtwTraceMessageVa,@90") +#pragma comment(linker, "/EXPORT:EtwUnregisterTraceGuids=ntdll.EtwUnregisterTraceGuids,@91") +#pragma comment(linker, "/EXPORT:EtwWriteUMSecurityEvent=ntdll.EtwWriteUMSecurityEvent,@92") +#pragma comment(linker, "/EXPORT:EtwpCreateEtwThread=ntdll.EtwpCreateEtwThread,@93") +#pragma comment(linker, "/EXPORT:EtwpGetCpuSpeed=ntdll.EtwpGetCpuSpeed,@94") +#pragma comment(linker, "/EXPORT:EtwpNotificationThread=ntdll.EtwpNotificationThread,@95") +#pragma comment(linker, "/EXPORT:EvtIntReportAuthzEventAndSourceAsync=ntdll.EvtIntReportAuthzEventAndSourceAsync,@96") +#pragma comment(linker, "/EXPORT:EvtIntReportEventAndSourceAsync=ntdll.EvtIntReportEventAndSourceAsync,@97") +#pragma comment(linker, "/EXPORT:ExpInterlockedPopEntrySListEnd=ntdll.ExpInterlockedPopEntrySListEnd,@98") +#pragma comment(linker, "/EXPORT:ExpInterlockedPopEntrySListEnd16=ntdll.ExpInterlockedPopEntrySListEnd16,@99") +#pragma comment(linker, "/EXPORT:ExpInterlockedPopEntrySListFault=ntdll.ExpInterlockedPopEntrySListFault,@100") +#pragma comment(linker, "/EXPORT:ExpInterlockedPopEntrySListFault16=ntdll.ExpInterlockedPopEntrySListFault16,@101") +#pragma comment(linker, "/EXPORT:ExpInterlockedPopEntrySListResume=ntdll.ExpInterlockedPopEntrySListResume,@102") +#pragma comment(linker, "/EXPORT:ExpInterlockedPopEntrySListResume16=ntdll.ExpInterlockedPopEntrySListResume16,@103") +#pragma comment(linker, "/EXPORT:KiRaiseUserExceptionDispatcher=ntdll.KiRaiseUserExceptionDispatcher,@104") +#pragma comment(linker, "/EXPORT:KiUserApcDispatcher=ntdll.KiUserApcDispatcher,@105") +#pragma comment(linker, "/EXPORT:KiUserCallbackDispatcher=ntdll.KiUserCallbackDispatcher,@106") +#pragma comment(linker, "/EXPORT:KiUserExceptionDispatcher=ntdll.KiUserExceptionDispatcher,@107") +#pragma comment(linker, "/EXPORT:LdrAccessResource=ntdll.LdrAccessResource,@108") +#pragma comment(linker, "/EXPORT:LdrAddLoadAsDataTable=ntdll.LdrAddLoadAsDataTable,@109") +#pragma comment(linker, "/EXPORT:LdrAddRefDll=ntdll.LdrAddRefDll,@110") +#pragma comment(linker, "/EXPORT:LdrDisableThreadCalloutsForDll=ntdll.LdrDisableThreadCalloutsForDll,@111") +#pragma comment(linker, "/EXPORT:LdrEnumResources=ntdll.LdrEnumResources,@112") +#pragma comment(linker, "/EXPORT:LdrEnumerateLoadedModules=ntdll.LdrEnumerateLoadedModules,@113") +#pragma comment(linker, "/EXPORT:LdrFindEntryForAddress=ntdll.LdrFindEntryForAddress,@114") +#pragma comment(linker, "/EXPORT:LdrFindResourceDirectory_U=ntdll.LdrFindResourceDirectory_U,@115") +#pragma comment(linker, "/EXPORT:LdrFindResourceEx_U=ntdll.LdrFindResourceEx_U,@116") +#pragma comment(linker, "/EXPORT:LdrFindResource_U=ntdll.LdrFindResource_U,@117") +#pragma comment(linker, "/EXPORT:LdrFlushAlternateResourceModules=ntdll.LdrFlushAlternateResourceModules,@118") +//#pragma comment(linker, "/EXPORT:LdrGetDllHandle=ntdll.LdrGetDllHandle,@119") +#pragma comment(linker, "/EXPORT:LdrGetDllHandleByMapping=ntdll.LdrGetDllHandleByMapping,@120") +#pragma comment(linker, "/EXPORT:LdrGetDllHandleByName=ntdll.LdrGetDllHandleByName,@121") +//#pragma comment(linker, "/EXPORT:LdrGetDllHandleEx=ntdll.LdrGetDllHandleEx,@122") +#pragma comment(linker, "/EXPORT:LdrGetFailureData=ntdll.LdrGetFailureData,@123") +#pragma comment(linker, "/EXPORT:LdrGetFileNameFromLoadAsDataTable=ntdll.LdrGetFileNameFromLoadAsDataTable,@124") +#pragma comment(linker, "/EXPORT:LdrGetKnownDllSectionHandle=ntdll.LdrGetKnownDllSectionHandle,@125") +//#pragma comment(linker, "/EXPORT:LdrGetProcedureAddress=ntdll.LdrGetProcedureAddress,@126") +//#pragma comment(linker, "/EXPORT:LdrGetProcedureAddressEx=ntdll.LdrGetProcedureAddressEx,@127") +#pragma comment(linker, "/EXPORT:LdrHotPatchRoutine=ntdll.LdrHotPatchRoutine,@128") +#pragma comment(linker, "/EXPORT:LdrInitShimEngineDynamic=ntdll.LdrInitShimEngineDynamic,@129") +#pragma comment(linker, "/EXPORT:LdrInitializeThunk=ntdll.LdrInitializeThunk,@130") +#pragma comment(linker, "/EXPORT:LdrLoadAlternateResourceModule=ntdll.LdrLoadAlternateResourceModule,@131") +#pragma comment(linker, "/EXPORT:LdrLoadAlternateResourceModuleEx=ntdll.LdrLoadAlternateResourceModuleEx,@132") +//#pragma comment(linker, "/EXPORT:LdrLoadDll=ntdll.LdrLoadDll,@133") +#pragma comment(linker, "/EXPORT:LdrLockLoaderLock=ntdll.LdrLockLoaderLock,@134") +#pragma comment(linker, "/EXPORT:LdrOpenImageFileOptionsKey=ntdll.LdrOpenImageFileOptionsKey,@135") +#pragma comment(linker, "/EXPORT:LdrProcessInitializationComplete=ntdll.LdrProcessInitializationComplete,@136") +#pragma comment(linker, "/EXPORT:LdrProcessRelocationBlock=ntdll.LdrProcessRelocationBlock,@137") +#pragma comment(linker, "/EXPORT:LdrQueryImageFileExecutionOptions=ntdll.LdrQueryImageFileExecutionOptions,@138") +#pragma comment(linker, "/EXPORT:LdrQueryImageFileExecutionOptionsEx=ntdll.LdrQueryImageFileExecutionOptionsEx,@139") +#pragma comment(linker, "/EXPORT:LdrQueryImageFileKeyOption=ntdll.LdrQueryImageFileKeyOption,@140") +#pragma comment(linker, "/EXPORT:LdrQueryModuleServiceTags=ntdll.LdrQueryModuleServiceTags,@141") +#pragma comment(linker, "/EXPORT:LdrQueryProcessModuleInformation=ntdll.LdrQueryProcessModuleInformation,@142") +#pragma comment(linker, "/EXPORT:LdrRegisterDllNotification=ntdll.LdrRegisterDllNotification,@143") +#pragma comment(linker, "/EXPORT:LdrRemoveLoadAsDataTable=ntdll.LdrRemoveLoadAsDataTable,@144") +#pragma comment(linker, "/EXPORT:LdrResFindResource=ntdll.LdrResFindResource,@145") +#pragma comment(linker, "/EXPORT:LdrResFindResourceDirectory=ntdll.LdrResFindResourceDirectory,@146") +#pragma comment(linker, "/EXPORT:LdrResGetRCConfig=ntdll.LdrResGetRCConfig,@147") +#pragma comment(linker, "/EXPORT:LdrResRelease=ntdll.LdrResRelease,@148") +#pragma comment(linker, "/EXPORT:LdrResSearchResource=ntdll.LdrResSearchResource,@149") +#pragma comment(linker, "/EXPORT:LdrRscIsTypeExist=ntdll.LdrRscIsTypeExist,@150") +#pragma comment(linker, "/EXPORT:LdrSetAppCompatDllRedirectionCallback=ntdll.LdrSetAppCompatDllRedirectionCallback,@151") +#pragma comment(linker, "/EXPORT:LdrSetDllManifestProber=ntdll.LdrSetDllManifestProber,@152") +#pragma comment(linker, "/EXPORT:LdrSetMUICacheType=ntdll.LdrSetMUICacheType,@153") +#pragma comment(linker, "/EXPORT:LdrShutdownProcess=ntdll.LdrShutdownProcess,@154") +#pragma comment(linker, "/EXPORT:LdrShutdownThread=ntdll.LdrShutdownThread,@155") +#pragma comment(linker, "/EXPORT:LdrSystemDllInitBlock=ntdll.LdrSystemDllInitBlock,@156") +#pragma comment(linker, "/EXPORT:LdrUnloadAlternateResourceModule=ntdll.LdrUnloadAlternateResourceModule,@157") +#pragma comment(linker, "/EXPORT:LdrUnloadAlternateResourceModuleEx=ntdll.LdrUnloadAlternateResourceModuleEx,@158") +#pragma comment(linker, "/EXPORT:LdrUnloadDll=ntdll.LdrUnloadDll,@159") +#pragma comment(linker, "/EXPORT:LdrUnlockLoaderLock=ntdll.LdrUnlockLoaderLock,@160") +#pragma comment(linker, "/EXPORT:LdrUnregisterDllNotification=ntdll.LdrUnregisterDllNotification,@161") +#pragma comment(linker, "/EXPORT:LdrVerifyImageMatchesChecksum=ntdll.LdrVerifyImageMatchesChecksum,@162") +#pragma comment(linker, "/EXPORT:LdrVerifyImageMatchesChecksumEx=ntdll.LdrVerifyImageMatchesChecksumEx,@163") +#pragma comment(linker, "/EXPORT:LdrpResGetMappingSize=ntdll.LdrpResGetMappingSize,@164") +#pragma comment(linker, "/EXPORT:LdrpResGetResourceDirectory=ntdll.LdrpResGetResourceDirectory,@165") +#pragma comment(linker, "/EXPORT:MD4Final=ntdll.MD4Final,@166") +#pragma comment(linker, "/EXPORT:MD4Init=ntdll.MD4Init,@167") +#pragma comment(linker, "/EXPORT:MD4Update=ntdll.MD4Update,@168") +#pragma comment(linker, "/EXPORT:MD5Final=ntdll.MD5Final,@169") +#pragma comment(linker, "/EXPORT:MD5Init=ntdll.MD5Init,@170") +#pragma comment(linker, "/EXPORT:MD5Update=ntdll.MD5Update,@171") +#pragma comment(linker, "/EXPORT:NlsAnsiCodePage=ntdll.NlsAnsiCodePage,@172") +#pragma comment(linker, "/EXPORT:NlsMbCodePageTag=ntdll.NlsMbCodePageTag,@173") +#pragma comment(linker, "/EXPORT:NlsMbOemCodePageTag=ntdll.NlsMbOemCodePageTag,@174") +#pragma comment(linker, "/EXPORT:NtAcceptConnectPort=ntdll.NtAcceptConnectPort,@175") +#pragma comment(linker, "/EXPORT:NtAccessCheck=ntdll.NtAccessCheck,@176") +#pragma comment(linker, "/EXPORT:NtAccessCheckAndAuditAlarm=ntdll.NtAccessCheckAndAuditAlarm,@177") +#pragma comment(linker, "/EXPORT:NtAccessCheckByType=ntdll.NtAccessCheckByType,@178") +#pragma comment(linker, "/EXPORT:NtAccessCheckByTypeAndAuditAlarm=ntdll.NtAccessCheckByTypeAndAuditAlarm,@179") +#pragma comment(linker, "/EXPORT:NtAccessCheckByTypeResultList=ntdll.NtAccessCheckByTypeResultList,@180") +#pragma comment(linker, "/EXPORT:NtAccessCheckByTypeResultListAndAuditAlarm=ntdll.NtAccessCheckByTypeResultListAndAuditAlarm,@181") +#pragma comment(linker, "/EXPORT:NtAccessCheckByTypeResultListAndAuditAlarmByHandle=ntdll.NtAccessCheckByTypeResultListAndAuditAlarmByHandle,@182") +#pragma comment(linker, "/EXPORT:NtAddAtom=ntdll.NtAddAtom,@183") +#pragma comment(linker, "/EXPORT:NtAddBootEntry=ntdll.NtAddBootEntry,@184") +#pragma comment(linker, "/EXPORT:NtAddDriverEntry=ntdll.NtAddDriverEntry,@185") +#pragma comment(linker, "/EXPORT:NtAdjustGroupsToken=ntdll.NtAdjustGroupsToken,@186") +#pragma comment(linker, "/EXPORT:NtAdjustPrivilegesToken=ntdll.NtAdjustPrivilegesToken,@187") +#pragma comment(linker, "/EXPORT:NtAlertResumeThread=ntdll.NtAlertResumeThread,@188") +#pragma comment(linker, "/EXPORT:NtAlertThread=ntdll.NtAlertThread,@189") +#pragma comment(linker, "/EXPORT:NtAllocateLocallyUniqueId=ntdll.NtAllocateLocallyUniqueId,@190") +#pragma comment(linker, "/EXPORT:NtAllocateReserveObject=ntdll.NtAllocateReserveObject,@191") +#pragma comment(linker, "/EXPORT:NtAllocateUserPhysicalPages=ntdll.NtAllocateUserPhysicalPages,@192") +#pragma comment(linker, "/EXPORT:NtAllocateUuids=ntdll.NtAllocateUuids,@193") +#pragma comment(linker, "/EXPORT:NtAllocateVirtualMemory=ntdll.NtAllocateVirtualMemory,@194") +#pragma comment(linker, "/EXPORT:NtAlpcAcceptConnectPort=ntdll.NtAlpcAcceptConnectPort,@195") +#pragma comment(linker, "/EXPORT:NtAlpcCancelMessage=ntdll.NtAlpcCancelMessage,@196") +#pragma comment(linker, "/EXPORT:NtAlpcConnectPort=ntdll.NtAlpcConnectPort,@197") +#pragma comment(linker, "/EXPORT:NtAlpcCreatePort=ntdll.NtAlpcCreatePort,@198") +#pragma comment(linker, "/EXPORT:NtAlpcCreatePortSection=ntdll.NtAlpcCreatePortSection,@199") +#pragma comment(linker, "/EXPORT:NtAlpcCreateResourceReserve=ntdll.NtAlpcCreateResourceReserve,@200") +#pragma comment(linker, "/EXPORT:NtAlpcCreateSectionView=ntdll.NtAlpcCreateSectionView,@201") +#pragma comment(linker, "/EXPORT:NtAlpcCreateSecurityContext=ntdll.NtAlpcCreateSecurityContext,@202") +#pragma comment(linker, "/EXPORT:NtAlpcDeletePortSection=ntdll.NtAlpcDeletePortSection,@203") +#pragma comment(linker, "/EXPORT:NtAlpcDeleteResourceReserve=ntdll.NtAlpcDeleteResourceReserve,@204") +#pragma comment(linker, "/EXPORT:NtAlpcDeleteSectionView=ntdll.NtAlpcDeleteSectionView,@205") +#pragma comment(linker, "/EXPORT:NtAlpcDeleteSecurityContext=ntdll.NtAlpcDeleteSecurityContext,@206") +#pragma comment(linker, "/EXPORT:NtAlpcDisconnectPort=ntdll.NtAlpcDisconnectPort,@207") +#pragma comment(linker, "/EXPORT:NtAlpcImpersonateClientOfPort=ntdll.NtAlpcImpersonateClientOfPort,@208") +#pragma comment(linker, "/EXPORT:NtAlpcOpenSenderProcess=ntdll.NtAlpcOpenSenderProcess,@209") +#pragma comment(linker, "/EXPORT:NtAlpcOpenSenderThread=ntdll.NtAlpcOpenSenderThread,@210") +#pragma comment(linker, "/EXPORT:NtAlpcQueryInformation=ntdll.NtAlpcQueryInformation,@211") +#pragma comment(linker, "/EXPORT:NtAlpcQueryInformationMessage=ntdll.NtAlpcQueryInformationMessage,@212") +#pragma comment(linker, "/EXPORT:NtAlpcRevokeSecurityContext=ntdll.NtAlpcRevokeSecurityContext,@213") +#pragma comment(linker, "/EXPORT:NtAlpcSendWaitReceivePort=ntdll.NtAlpcSendWaitReceivePort,@214") +#pragma comment(linker, "/EXPORT:NtAlpcSetInformation=ntdll.NtAlpcSetInformation,@215") +#pragma comment(linker, "/EXPORT:NtApphelpCacheControl=ntdll.NtApphelpCacheControl,@216") +#pragma comment(linker, "/EXPORT:NtAreMappedFilesTheSame=ntdll.NtAreMappedFilesTheSame,@217") +#pragma comment(linker, "/EXPORT:NtAssignProcessToJobObject=ntdll.NtAssignProcessToJobObject,@218") +#pragma comment(linker, "/EXPORT:NtCallbackReturn=ntdll.NtCallbackReturn,@219") +#pragma comment(linker, "/EXPORT:NtCancelIoFile=ntdll.NtCancelIoFile,@220") +#pragma comment(linker, "/EXPORT:NtCancelIoFileEx=ntdll.NtCancelIoFileEx,@221") +#pragma comment(linker, "/EXPORT:NtCancelSynchronousIoFile=ntdll.NtCancelSynchronousIoFile,@222") +#pragma comment(linker, "/EXPORT:NtCancelTimer=ntdll.NtCancelTimer,@223") +#pragma comment(linker, "/EXPORT:NtClearEvent=ntdll.NtClearEvent,@224") +#pragma comment(linker, "/EXPORT:NtClose=ntdll.NtClose,@225") +#pragma comment(linker, "/EXPORT:NtCloseObjectAuditAlarm=ntdll.NtCloseObjectAuditAlarm,@226") +#pragma comment(linker, "/EXPORT:NtCommitComplete=ntdll.NtCommitComplete,@227") +#pragma comment(linker, "/EXPORT:NtCommitEnlistment=ntdll.NtCommitEnlistment,@228") +#pragma comment(linker, "/EXPORT:NtCommitTransaction=ntdll.NtCommitTransaction,@229") +#pragma comment(linker, "/EXPORT:NtCompactKeys=ntdll.NtCompactKeys,@230") +#pragma comment(linker, "/EXPORT:NtCompareTokens=ntdll.NtCompareTokens,@231") +#pragma comment(linker, "/EXPORT:NtCompleteConnectPort=ntdll.NtCompleteConnectPort,@232") +#pragma comment(linker, "/EXPORT:NtCompressKey=ntdll.NtCompressKey,@233") +#pragma comment(linker, "/EXPORT:NtConnectPort=ntdll.NtConnectPort,@234") +#pragma comment(linker, "/EXPORT:NtContinue=ntdll.NtContinue,@235") +#pragma comment(linker, "/EXPORT:NtCreateDebugObject=ntdll.NtCreateDebugObject,@236") +#pragma comment(linker, "/EXPORT:NtCreateDirectoryObject=ntdll.NtCreateDirectoryObject,@237") +#pragma comment(linker, "/EXPORT:NtCreateEnlistment=ntdll.NtCreateEnlistment,@238") +#pragma comment(linker, "/EXPORT:NtCreateEvent=ntdll.NtCreateEvent,@239") +#pragma comment(linker, "/EXPORT:NtCreateEventPair=ntdll.NtCreateEventPair,@240") +#pragma comment(linker, "/EXPORT:NtCreateFile=ntdll.NtCreateFile,@241") +#pragma comment(linker, "/EXPORT:NtCreateIoCompletion=ntdll.NtCreateIoCompletion,@242") +#pragma comment(linker, "/EXPORT:NtCreateJobObject=ntdll.NtCreateJobObject,@243") +#pragma comment(linker, "/EXPORT:NtCreateJobSet=ntdll.NtCreateJobSet,@244") +#pragma comment(linker, "/EXPORT:NtCreateKey=ntdll.NtCreateKey,@245") +#pragma comment(linker, "/EXPORT:NtCreateKeyTransacted=ntdll.NtCreateKeyTransacted,@246") +#pragma comment(linker, "/EXPORT:NtCreateKeyedEvent=ntdll.NtCreateKeyedEvent,@247") +#pragma comment(linker, "/EXPORT:NtCreateMailslotFile=ntdll.NtCreateMailslotFile,@248") +#pragma comment(linker, "/EXPORT:NtCreateMutant=ntdll.NtCreateMutant,@249") +#pragma comment(linker, "/EXPORT:NtCreateNamedPipeFile=ntdll.NtCreateNamedPipeFile,@250") +#pragma comment(linker, "/EXPORT:NtCreatePagingFile=ntdll.NtCreatePagingFile,@251") +#pragma comment(linker, "/EXPORT:NtCreatePort=ntdll.NtCreatePort,@252") +#pragma comment(linker, "/EXPORT:NtCreatePrivateNamespace=ntdll.NtCreatePrivateNamespace,@253") +#pragma comment(linker, "/EXPORT:NtCreateProcess=ntdll.NtCreateProcess,@254") +#pragma comment(linker, "/EXPORT:NtCreateProcessEx=ntdll.NtCreateProcessEx,@255") +#pragma comment(linker, "/EXPORT:NtCreateProfile=ntdll.NtCreateProfile,@256") +#pragma comment(linker, "/EXPORT:NtCreateProfileEx=ntdll.NtCreateProfileEx,@257") +#pragma comment(linker, "/EXPORT:NtCreateResourceManager=ntdll.NtCreateResourceManager,@258") +#pragma comment(linker, "/EXPORT:NtCreateSection=ntdll.NtCreateSection,@259") +#pragma comment(linker, "/EXPORT:NtCreateSemaphore=ntdll.NtCreateSemaphore,@260") +#pragma comment(linker, "/EXPORT:NtCreateSymbolicLinkObject=ntdll.NtCreateSymbolicLinkObject,@261") +#pragma comment(linker, "/EXPORT:NtCreateThread=ntdll.NtCreateThread,@262") +#pragma comment(linker, "/EXPORT:NtCreateThreadEx=ntdll.NtCreateThreadEx,@263") +#pragma comment(linker, "/EXPORT:NtCreateTimer=ntdll.NtCreateTimer,@264") +#pragma comment(linker, "/EXPORT:NtCreateToken=ntdll.NtCreateToken,@265") +#pragma comment(linker, "/EXPORT:NtCreateTransaction=ntdll.NtCreateTransaction,@266") +#pragma comment(linker, "/EXPORT:NtCreateTransactionManager=ntdll.NtCreateTransactionManager,@267") +#pragma comment(linker, "/EXPORT:NtCreateUserProcess=ntdll.NtCreateUserProcess,@268") +#pragma comment(linker, "/EXPORT:NtCreateWaitablePort=ntdll.NtCreateWaitablePort,@269") +#pragma comment(linker, "/EXPORT:NtCreateWorkerFactory=ntdll.NtCreateWorkerFactory,@270") +#pragma comment(linker, "/EXPORT:NtDebugActiveProcess=ntdll.NtDebugActiveProcess,@271") +#pragma comment(linker, "/EXPORT:NtDebugContinue=ntdll.NtDebugContinue,@272") +#pragma comment(linker, "/EXPORT:NtDelayExecution=ntdll.NtDelayExecution,@273") +#pragma comment(linker, "/EXPORT:NtDeleteAtom=ntdll.NtDeleteAtom,@274") +#pragma comment(linker, "/EXPORT:NtDeleteBootEntry=ntdll.NtDeleteBootEntry,@275") +#pragma comment(linker, "/EXPORT:NtDeleteDriverEntry=ntdll.NtDeleteDriverEntry,@276") +#pragma comment(linker, "/EXPORT:NtDeleteFile=ntdll.NtDeleteFile,@277") +#pragma comment(linker, "/EXPORT:NtDeleteKey=ntdll.NtDeleteKey,@278") +#pragma comment(linker, "/EXPORT:NtDeleteObjectAuditAlarm=ntdll.NtDeleteObjectAuditAlarm,@279") +#pragma comment(linker, "/EXPORT:NtDeletePrivateNamespace=ntdll.NtDeletePrivateNamespace,@280") +#pragma comment(linker, "/EXPORT:NtDeleteValueKey=ntdll.NtDeleteValueKey,@281") +#pragma comment(linker, "/EXPORT:NtDeviceIoControlFile=ntdll.NtDeviceIoControlFile,@282") +#pragma comment(linker, "/EXPORT:NtDisableLastKnownGood=ntdll.NtDisableLastKnownGood,@283") +#pragma comment(linker, "/EXPORT:NtDisplayString=ntdll.NtDisplayString,@284") +#pragma comment(linker, "/EXPORT:NtDrawText=ntdll.NtDrawText,@285") +#pragma comment(linker, "/EXPORT:NtDuplicateObject=ntdll.NtDuplicateObject,@286") +#pragma comment(linker, "/EXPORT:NtDuplicateToken=ntdll.NtDuplicateToken,@287") +#pragma comment(linker, "/EXPORT:NtEnableLastKnownGood=ntdll.NtEnableLastKnownGood,@288") +#pragma comment(linker, "/EXPORT:NtEnumerateBootEntries=ntdll.NtEnumerateBootEntries,@289") +#pragma comment(linker, "/EXPORT:NtEnumerateDriverEntries=ntdll.NtEnumerateDriverEntries,@290") +#pragma comment(linker, "/EXPORT:NtEnumerateKey=ntdll.NtEnumerateKey,@291") +#pragma comment(linker, "/EXPORT:NtEnumerateSystemEnvironmentValuesEx=ntdll.NtEnumerateSystemEnvironmentValuesEx,@292") +#pragma comment(linker, "/EXPORT:NtEnumerateTransactionObject=ntdll.NtEnumerateTransactionObject,@293") +#pragma comment(linker, "/EXPORT:NtEnumerateValueKey=ntdll.NtEnumerateValueKey,@294") +#pragma comment(linker, "/EXPORT:NtExtendSection=ntdll.NtExtendSection,@295") +#pragma comment(linker, "/EXPORT:NtFilterToken=ntdll.NtFilterToken,@296") +#pragma comment(linker, "/EXPORT:NtFindAtom=ntdll.NtFindAtom,@297") +#pragma comment(linker, "/EXPORT:NtFlushBuffersFile=ntdll.NtFlushBuffersFile,@298") +#pragma comment(linker, "/EXPORT:NtFlushInstallUILanguage=ntdll.NtFlushInstallUILanguage,@299") +#pragma comment(linker, "/EXPORT:NtFlushInstructionCache=ntdll.NtFlushInstructionCache,@300") +#pragma comment(linker, "/EXPORT:NtFlushKey=ntdll.NtFlushKey,@301") +#pragma comment(linker, "/EXPORT:NtFlushProcessWriteBuffers=ntdll.NtFlushProcessWriteBuffers,@302") +#pragma comment(linker, "/EXPORT:NtFlushVirtualMemory=ntdll.NtFlushVirtualMemory,@303") +#pragma comment(linker, "/EXPORT:NtFlushWriteBuffer=ntdll.NtFlushWriteBuffer,@304") +#pragma comment(linker, "/EXPORT:NtFreeUserPhysicalPages=ntdll.NtFreeUserPhysicalPages,@305") +#pragma comment(linker, "/EXPORT:NtFreeVirtualMemory=ntdll.NtFreeVirtualMemory,@306") +#pragma comment(linker, "/EXPORT:NtFreezeRegistry=ntdll.NtFreezeRegistry,@307") +#pragma comment(linker, "/EXPORT:NtFreezeTransactions=ntdll.NtFreezeTransactions,@308") +#pragma comment(linker, "/EXPORT:NtFsControlFile=ntdll.NtFsControlFile,@309") +#pragma comment(linker, "/EXPORT:NtGetContextThread=ntdll.NtGetContextThread,@310") +#pragma comment(linker, "/EXPORT:NtGetCurrentProcessorNumber=ntdll.NtGetCurrentProcessorNumber,@311") +#pragma comment(linker, "/EXPORT:NtGetDevicePowerState=ntdll.NtGetDevicePowerState,@312") +#pragma comment(linker, "/EXPORT:NtGetMUIRegistryInfo=ntdll.NtGetMUIRegistryInfo,@313") +#pragma comment(linker, "/EXPORT:NtGetNextProcess=ntdll.NtGetNextProcess,@314") +#pragma comment(linker, "/EXPORT:NtGetNextThread=ntdll.NtGetNextThread,@315") +#pragma comment(linker, "/EXPORT:NtGetNlsSectionPtr=ntdll.NtGetNlsSectionPtr,@316") +#pragma comment(linker, "/EXPORT:NtGetNotificationResourceManager=ntdll.NtGetNotificationResourceManager,@317") +#pragma comment(linker, "/EXPORT:NtGetPlugPlayEvent=ntdll.NtGetPlugPlayEvent,@318") +#pragma comment(linker, "/EXPORT:NtGetTickCount=ntdll.NtGetTickCount,@319") +#pragma comment(linker, "/EXPORT:NtGetWriteWatch=ntdll.NtGetWriteWatch,@320") +#pragma comment(linker, "/EXPORT:NtImpersonateAnonymousToken=ntdll.NtImpersonateAnonymousToken,@321") +#pragma comment(linker, "/EXPORT:NtImpersonateClientOfPort=ntdll.NtImpersonateClientOfPort,@322") +#pragma comment(linker, "/EXPORT:NtImpersonateThread=ntdll.NtImpersonateThread,@323") +#pragma comment(linker, "/EXPORT:NtInitializeNlsFiles=ntdll.NtInitializeNlsFiles,@324") +#pragma comment(linker, "/EXPORT:NtInitializeRegistry=ntdll.NtInitializeRegistry,@325") +#pragma comment(linker, "/EXPORT:NtInitiatePowerAction=ntdll.NtInitiatePowerAction,@326") +#pragma comment(linker, "/EXPORT:NtIsProcessInJob=ntdll.NtIsProcessInJob,@327") +#pragma comment(linker, "/EXPORT:NtIsSystemResumeAutomatic=ntdll.NtIsSystemResumeAutomatic,@328") +#pragma comment(linker, "/EXPORT:NtIsUILanguageComitted=ntdll.NtIsUILanguageComitted,@329") +#pragma comment(linker, "/EXPORT:NtListenPort=ntdll.NtListenPort,@330") +#pragma comment(linker, "/EXPORT:NtLoadDriver=ntdll.NtLoadDriver,@331") +#pragma comment(linker, "/EXPORT:NtLoadKey=ntdll.NtLoadKey,@332") +#pragma comment(linker, "/EXPORT:NtLoadKey2=ntdll.NtLoadKey2,@333") +#pragma comment(linker, "/EXPORT:NtLoadKey3=ntdll.NtLoadKey3,@334") +#pragma comment(linker, "/EXPORT:NtLoadKeyEx=ntdll.NtLoadKeyEx,@335") +#pragma comment(linker, "/EXPORT:NtLockFile=ntdll.NtLockFile,@336") +#pragma comment(linker, "/EXPORT:NtLockProductActivationKeys=ntdll.NtLockProductActivationKeys,@337") +#pragma comment(linker, "/EXPORT:NtLockRegistryKey=ntdll.NtLockRegistryKey,@338") +#pragma comment(linker, "/EXPORT:NtLockVirtualMemory=ntdll.NtLockVirtualMemory,@339") +#pragma comment(linker, "/EXPORT:NtMakePermanentObject=ntdll.NtMakePermanentObject,@340") +#pragma comment(linker, "/EXPORT:NtMakeTemporaryObject=ntdll.NtMakeTemporaryObject,@341") +#pragma comment(linker, "/EXPORT:NtMapCMFModule=ntdll.NtMapCMFModule,@342") +#pragma comment(linker, "/EXPORT:NtMapUserPhysicalPages=ntdll.NtMapUserPhysicalPages,@343") +#pragma comment(linker, "/EXPORT:NtMapUserPhysicalPagesScatter=ntdll.NtMapUserPhysicalPagesScatter,@344") +#pragma comment(linker, "/EXPORT:NtMapViewOfSection=ntdll.NtMapViewOfSection,@345") +#pragma comment(linker, "/EXPORT:NtModifyBootEntry=ntdll.NtModifyBootEntry,@346") +#pragma comment(linker, "/EXPORT:NtModifyDriverEntry=ntdll.NtModifyDriverEntry,@347") +#pragma comment(linker, "/EXPORT:NtNotifyChangeDirectoryFile=ntdll.NtNotifyChangeDirectoryFile,@348") +#pragma comment(linker, "/EXPORT:NtNotifyChangeKey=ntdll.NtNotifyChangeKey,@349") +#pragma comment(linker, "/EXPORT:NtNotifyChangeMultipleKeys=ntdll.NtNotifyChangeMultipleKeys,@350") +#pragma comment(linker, "/EXPORT:NtNotifyChangeSession=ntdll.NtNotifyChangeSession,@351") +#pragma comment(linker, "/EXPORT:NtOpenDirectoryObject=ntdll.NtOpenDirectoryObject,@352") +#pragma comment(linker, "/EXPORT:NtOpenEnlistment=ntdll.NtOpenEnlistment,@353") +#pragma comment(linker, "/EXPORT:NtOpenEvent=ntdll.NtOpenEvent,@354") +#pragma comment(linker, "/EXPORT:NtOpenEventPair=ntdll.NtOpenEventPair,@355") +#pragma comment(linker, "/EXPORT:NtOpenFile=ntdll.NtOpenFile,@356") +#pragma comment(linker, "/EXPORT:NtOpenIoCompletion=ntdll.NtOpenIoCompletion,@357") +#pragma comment(linker, "/EXPORT:NtOpenJobObject=ntdll.NtOpenJobObject,@358") +#pragma comment(linker, "/EXPORT:NtOpenKey=ntdll.NtOpenKey,@359") +#pragma comment(linker, "/EXPORT:NtOpenKeyEx=ntdll.NtOpenKeyEx,@360") +#pragma comment(linker, "/EXPORT:NtOpenKeyTransacted=ntdll.NtOpenKeyTransacted,@361") +#pragma comment(linker, "/EXPORT:NtOpenKeyTransactedEx=ntdll.NtOpenKeyTransactedEx,@362") +#pragma comment(linker, "/EXPORT:NtOpenKeyedEvent=ntdll.NtOpenKeyedEvent,@363") +#pragma comment(linker, "/EXPORT:NtOpenMutant=ntdll.NtOpenMutant,@364") +#pragma comment(linker, "/EXPORT:NtOpenObjectAuditAlarm=ntdll.NtOpenObjectAuditAlarm,@365") +#pragma comment(linker, "/EXPORT:NtOpenPrivateNamespace=ntdll.NtOpenPrivateNamespace,@366") +#pragma comment(linker, "/EXPORT:NtOpenProcess=ntdll.NtOpenProcess,@367") +#pragma comment(linker, "/EXPORT:NtOpenProcessToken=ntdll.NtOpenProcessToken,@368") +#pragma comment(linker, "/EXPORT:NtOpenProcessTokenEx=ntdll.NtOpenProcessTokenEx,@369") +#pragma comment(linker, "/EXPORT:NtOpenResourceManager=ntdll.NtOpenResourceManager,@370") +#pragma comment(linker, "/EXPORT:NtOpenSection=ntdll.NtOpenSection,@371") +#pragma comment(linker, "/EXPORT:NtOpenSemaphore=ntdll.NtOpenSemaphore,@372") +#pragma comment(linker, "/EXPORT:NtOpenSession=ntdll.NtOpenSession,@373") +#pragma comment(linker, "/EXPORT:NtOpenSymbolicLinkObject=ntdll.NtOpenSymbolicLinkObject,@374") +#pragma comment(linker, "/EXPORT:NtOpenThread=ntdll.NtOpenThread,@375") +#pragma comment(linker, "/EXPORT:NtOpenThreadToken=ntdll.NtOpenThreadToken,@376") +#pragma comment(linker, "/EXPORT:NtOpenThreadTokenEx=ntdll.NtOpenThreadTokenEx,@377") +#pragma comment(linker, "/EXPORT:NtOpenTimer=ntdll.NtOpenTimer,@378") +#pragma comment(linker, "/EXPORT:NtOpenTransaction=ntdll.NtOpenTransaction,@379") +#pragma comment(linker, "/EXPORT:NtOpenTransactionManager=ntdll.NtOpenTransactionManager,@380") +#pragma comment(linker, "/EXPORT:NtPlugPlayControl=ntdll.NtPlugPlayControl,@381") +#pragma comment(linker, "/EXPORT:NtPowerInformation=ntdll.NtPowerInformation,@382") +#pragma comment(linker, "/EXPORT:NtPrePrepareComplete=ntdll.NtPrePrepareComplete,@383") +#pragma comment(linker, "/EXPORT:NtPrePrepareEnlistment=ntdll.NtPrePrepareEnlistment,@384") +#pragma comment(linker, "/EXPORT:NtPrepareComplete=ntdll.NtPrepareComplete,@385") +#pragma comment(linker, "/EXPORT:NtPrepareEnlistment=ntdll.NtPrepareEnlistment,@386") +#pragma comment(linker, "/EXPORT:NtPrivilegeCheck=ntdll.NtPrivilegeCheck,@387") +#pragma comment(linker, "/EXPORT:NtPrivilegeObjectAuditAlarm=ntdll.NtPrivilegeObjectAuditAlarm,@388") +#pragma comment(linker, "/EXPORT:NtPrivilegedServiceAuditAlarm=ntdll.NtPrivilegedServiceAuditAlarm,@389") +#pragma comment(linker, "/EXPORT:NtPropagationComplete=ntdll.NtPropagationComplete,@390") +#pragma comment(linker, "/EXPORT:NtPropagationFailed=ntdll.NtPropagationFailed,@391") +#pragma comment(linker, "/EXPORT:NtProtectVirtualMemory=ntdll.NtProtectVirtualMemory,@392") +#pragma comment(linker, "/EXPORT:NtPulseEvent=ntdll.NtPulseEvent,@393") +#pragma comment(linker, "/EXPORT:NtQueryAttributesFile=ntdll.NtQueryAttributesFile,@394") +#pragma comment(linker, "/EXPORT:NtQueryBootEntryOrder=ntdll.NtQueryBootEntryOrder,@395") +#pragma comment(linker, "/EXPORT:NtQueryBootOptions=ntdll.NtQueryBootOptions,@396") +#pragma comment(linker, "/EXPORT:NtQueryDebugFilterState=ntdll.NtQueryDebugFilterState,@397") +#pragma comment(linker, "/EXPORT:NtQueryDefaultLocale=ntdll.NtQueryDefaultLocale,@398") +#pragma comment(linker, "/EXPORT:NtQueryDefaultUILanguage=ntdll.NtQueryDefaultUILanguage,@399") +#pragma comment(linker, "/EXPORT:NtQueryDirectoryFile=ntdll.NtQueryDirectoryFile,@400") +#pragma comment(linker, "/EXPORT:NtQueryDirectoryObject=ntdll.NtQueryDirectoryObject,@401") +#pragma comment(linker, "/EXPORT:NtQueryDriverEntryOrder=ntdll.NtQueryDriverEntryOrder,@402") +#pragma comment(linker, "/EXPORT:NtQueryEaFile=ntdll.NtQueryEaFile,@403") +#pragma comment(linker, "/EXPORT:NtQueryEvent=ntdll.NtQueryEvent,@404") +#pragma comment(linker, "/EXPORT:NtQueryFullAttributesFile=ntdll.NtQueryFullAttributesFile,@405") +#pragma comment(linker, "/EXPORT:NtQueryInformationAtom=ntdll.NtQueryInformationAtom,@406") +#pragma comment(linker, "/EXPORT:NtQueryInformationEnlistment=ntdll.NtQueryInformationEnlistment,@407") +#pragma comment(linker, "/EXPORT:NtQueryInformationFile=ntdll.NtQueryInformationFile,@408") +#pragma comment(linker, "/EXPORT:NtQueryInformationJobObject=ntdll.NtQueryInformationJobObject,@409") +#pragma comment(linker, "/EXPORT:NtQueryInformationPort=ntdll.NtQueryInformationPort,@410") +#pragma comment(linker, "/EXPORT:NtQueryInformationProcess=ntdll.NtQueryInformationProcess,@411") +#pragma comment(linker, "/EXPORT:NtQueryInformationResourceManager=ntdll.NtQueryInformationResourceManager,@412") +#pragma comment(linker, "/EXPORT:NtQueryInformationThread=ntdll.NtQueryInformationThread,@413") +#pragma comment(linker, "/EXPORT:NtQueryInformationToken=ntdll.NtQueryInformationToken,@414") +#pragma comment(linker, "/EXPORT:NtQueryInformationTransaction=ntdll.NtQueryInformationTransaction,@415") +#pragma comment(linker, "/EXPORT:NtQueryInformationTransactionManager=ntdll.NtQueryInformationTransactionManager,@416") +#pragma comment(linker, "/EXPORT:NtQueryInformationWorkerFactory=ntdll.NtQueryInformationWorkerFactory,@417") +#pragma comment(linker, "/EXPORT:NtQueryInstallUILanguage=ntdll.NtQueryInstallUILanguage,@418") +#pragma comment(linker, "/EXPORT:NtQueryIntervalProfile=ntdll.NtQueryIntervalProfile,@419") +#pragma comment(linker, "/EXPORT:NtQueryIoCompletion=ntdll.NtQueryIoCompletion,@420") +#pragma comment(linker, "/EXPORT:NtQueryKey=ntdll.NtQueryKey,@421") +#pragma comment(linker, "/EXPORT:NtQueryLicenseValue=ntdll.NtQueryLicenseValue,@422") +#pragma comment(linker, "/EXPORT:NtQueryMultipleValueKey=ntdll.NtQueryMultipleValueKey,@423") +#pragma comment(linker, "/EXPORT:NtQueryMutant=ntdll.NtQueryMutant,@424") +#pragma comment(linker, "/EXPORT:NtQueryObject=ntdll.NtQueryObject,@425") +#pragma comment(linker, "/EXPORT:NtQueryOpenSubKeys=ntdll.NtQueryOpenSubKeys,@426") +#pragma comment(linker, "/EXPORT:NtQueryOpenSubKeysEx=ntdll.NtQueryOpenSubKeysEx,@427") +#pragma comment(linker, "/EXPORT:NtQueryPerformanceCounter=ntdll.NtQueryPerformanceCounter,@428") +#pragma comment(linker, "/EXPORT:NtQueryPortInformationProcess=ntdll.NtQueryPortInformationProcess,@429") +#pragma comment(linker, "/EXPORT:NtQueryQuotaInformationFile=ntdll.NtQueryQuotaInformationFile,@430") +#pragma comment(linker, "/EXPORT:NtQuerySection=ntdll.NtQuerySection,@431") +#pragma comment(linker, "/EXPORT:NtQuerySecurityAttributesToken=ntdll.NtQuerySecurityAttributesToken,@432") +#pragma comment(linker, "/EXPORT:NtQuerySecurityObject=ntdll.NtQuerySecurityObject,@433") +#pragma comment(linker, "/EXPORT:NtQuerySemaphore=ntdll.NtQuerySemaphore,@434") +#pragma comment(linker, "/EXPORT:NtQuerySymbolicLinkObject=ntdll.NtQuerySymbolicLinkObject,@435") +#pragma comment(linker, "/EXPORT:NtQuerySystemEnvironmentValue=ntdll.NtQuerySystemEnvironmentValue,@436") +#pragma comment(linker, "/EXPORT:NtQuerySystemEnvironmentValueEx=ntdll.NtQuerySystemEnvironmentValueEx,@437") +#pragma comment(linker, "/EXPORT:NtQuerySystemInformation=ntdll.NtQuerySystemInformation,@438") +#pragma comment(linker, "/EXPORT:NtQuerySystemInformationEx=ntdll.NtQuerySystemInformationEx,@439") +#pragma comment(linker, "/EXPORT:NtQuerySystemTime=ntdll.NtQuerySystemTime,@440") +#pragma comment(linker, "/EXPORT:NtQueryTimer=ntdll.NtQueryTimer,@441") +#pragma comment(linker, "/EXPORT:NtQueryTimerResolution=ntdll.NtQueryTimerResolution,@442") +#pragma comment(linker, "/EXPORT:NtQueryValueKey=ntdll.NtQueryValueKey,@443") +#pragma comment(linker, "/EXPORT:NtQueryVirtualMemory=ntdll.NtQueryVirtualMemory,@444") +#pragma comment(linker, "/EXPORT:NtQueryVolumeInformationFile=ntdll.NtQueryVolumeInformationFile,@445") +#pragma comment(linker, "/EXPORT:NtQueueApcThread=ntdll.NtQueueApcThread,@446") +#pragma comment(linker, "/EXPORT:NtQueueApcThreadEx=ntdll.NtQueueApcThreadEx,@447") +#pragma comment(linker, "/EXPORT:NtRaiseException=ntdll.NtRaiseException,@448") +#pragma comment(linker, "/EXPORT:NtRaiseHardError=ntdll.NtRaiseHardError,@449") +#pragma comment(linker, "/EXPORT:NtReadFile=ntdll.NtReadFile,@450") +#pragma comment(linker, "/EXPORT:NtReadFileScatter=ntdll.NtReadFileScatter,@451") +#pragma comment(linker, "/EXPORT:NtReadOnlyEnlistment=ntdll.NtReadOnlyEnlistment,@452") +#pragma comment(linker, "/EXPORT:NtReadRequestData=ntdll.NtReadRequestData,@453") +#pragma comment(linker, "/EXPORT:NtReadVirtualMemory=ntdll.NtReadVirtualMemory,@454") +#pragma comment(linker, "/EXPORT:NtRecoverEnlistment=ntdll.NtRecoverEnlistment,@455") +#pragma comment(linker, "/EXPORT:NtRecoverResourceManager=ntdll.NtRecoverResourceManager,@456") +#pragma comment(linker, "/EXPORT:NtRecoverTransactionManager=ntdll.NtRecoverTransactionManager,@457") +#pragma comment(linker, "/EXPORT:NtRegisterProtocolAddressInformation=ntdll.NtRegisterProtocolAddressInformation,@458") +#pragma comment(linker, "/EXPORT:NtRegisterThreadTerminatePort=ntdll.NtRegisterThreadTerminatePort,@459") +#pragma comment(linker, "/EXPORT:NtReleaseKeyedEvent=ntdll.NtReleaseKeyedEvent,@460") +#pragma comment(linker, "/EXPORT:NtReleaseMutant=ntdll.NtReleaseMutant,@461") +#pragma comment(linker, "/EXPORT:NtReleaseSemaphore=ntdll.NtReleaseSemaphore,@462") +#pragma comment(linker, "/EXPORT:NtReleaseWorkerFactoryWorker=ntdll.NtReleaseWorkerFactoryWorker,@463") +#pragma comment(linker, "/EXPORT:NtRemoveIoCompletion=ntdll.NtRemoveIoCompletion,@464") +#pragma comment(linker, "/EXPORT:NtRemoveIoCompletionEx=ntdll.NtRemoveIoCompletionEx,@465") +#pragma comment(linker, "/EXPORT:NtRemoveProcessDebug=ntdll.NtRemoveProcessDebug,@466") +#pragma comment(linker, "/EXPORT:NtRenameKey=ntdll.NtRenameKey,@467") +#pragma comment(linker, "/EXPORT:NtRenameTransactionManager=ntdll.NtRenameTransactionManager,@468") +#pragma comment(linker, "/EXPORT:NtReplaceKey=ntdll.NtReplaceKey,@469") +#pragma comment(linker, "/EXPORT:NtReplacePartitionUnit=ntdll.NtReplacePartitionUnit,@470") +#pragma comment(linker, "/EXPORT:NtReplyPort=ntdll.NtReplyPort,@471") +#pragma comment(linker, "/EXPORT:NtReplyWaitReceivePort=ntdll.NtReplyWaitReceivePort,@472") +#pragma comment(linker, "/EXPORT:NtReplyWaitReceivePortEx=ntdll.NtReplyWaitReceivePortEx,@473") +#pragma comment(linker, "/EXPORT:NtReplyWaitReplyPort=ntdll.NtReplyWaitReplyPort,@474") +#pragma comment(linker, "/EXPORT:NtRequestPort=ntdll.NtRequestPort,@475") +#pragma comment(linker, "/EXPORT:NtRequestWaitReplyPort=ntdll.NtRequestWaitReplyPort,@476") +#pragma comment(linker, "/EXPORT:NtResetEvent=ntdll.NtResetEvent,@477") +#pragma comment(linker, "/EXPORT:NtResetWriteWatch=ntdll.NtResetWriteWatch,@478") +#pragma comment(linker, "/EXPORT:NtRestoreKey=ntdll.NtRestoreKey,@479") +#pragma comment(linker, "/EXPORT:NtResumeProcess=ntdll.NtResumeProcess,@480") +#pragma comment(linker, "/EXPORT:NtResumeThread=ntdll.NtResumeThread,@481") +#pragma comment(linker, "/EXPORT:NtRollbackComplete=ntdll.NtRollbackComplete,@482") +#pragma comment(linker, "/EXPORT:NtRollbackEnlistment=ntdll.NtRollbackEnlistment,@483") +#pragma comment(linker, "/EXPORT:NtRollbackTransaction=ntdll.NtRollbackTransaction,@484") +#pragma comment(linker, "/EXPORT:NtRollforwardTransactionManager=ntdll.NtRollforwardTransactionManager,@485") +#pragma comment(linker, "/EXPORT:NtSaveKey=ntdll.NtSaveKey,@486") +#pragma comment(linker, "/EXPORT:NtSaveKeyEx=ntdll.NtSaveKeyEx,@487") +#pragma comment(linker, "/EXPORT:NtSaveMergedKeys=ntdll.NtSaveMergedKeys,@488") +#pragma comment(linker, "/EXPORT:NtSecureConnectPort=ntdll.NtSecureConnectPort,@489") +#pragma comment(linker, "/EXPORT:NtSerializeBoot=ntdll.NtSerializeBoot,@490") +#pragma comment(linker, "/EXPORT:NtSetBootEntryOrder=ntdll.NtSetBootEntryOrder,@491") +#pragma comment(linker, "/EXPORT:NtSetBootOptions=ntdll.NtSetBootOptions,@492") +#pragma comment(linker, "/EXPORT:NtSetContextThread=ntdll.NtSetContextThread,@493") +#pragma comment(linker, "/EXPORT:NtSetDebugFilterState=ntdll.NtSetDebugFilterState,@494") +#pragma comment(linker, "/EXPORT:NtSetDefaultHardErrorPort=ntdll.NtSetDefaultHardErrorPort,@495") +#pragma comment(linker, "/EXPORT:NtSetDefaultLocale=ntdll.NtSetDefaultLocale,@496") +#pragma comment(linker, "/EXPORT:NtSetDefaultUILanguage=ntdll.NtSetDefaultUILanguage,@497") +#pragma comment(linker, "/EXPORT:NtSetDriverEntryOrder=ntdll.NtSetDriverEntryOrder,@498") +#pragma comment(linker, "/EXPORT:NtSetEaFile=ntdll.NtSetEaFile,@499") +#pragma comment(linker, "/EXPORT:NtSetEvent=ntdll.NtSetEvent,@500") +#pragma comment(linker, "/EXPORT:NtSetEventBoostPriority=ntdll.NtSetEventBoostPriority,@501") +#pragma comment(linker, "/EXPORT:NtSetHighEventPair=ntdll.NtSetHighEventPair,@502") +#pragma comment(linker, "/EXPORT:NtSetHighWaitLowEventPair=ntdll.NtSetHighWaitLowEventPair,@503") +#pragma comment(linker, "/EXPORT:NtSetInformationDebugObject=ntdll.NtSetInformationDebugObject,@504") +#pragma comment(linker, "/EXPORT:NtSetInformationEnlistment=ntdll.NtSetInformationEnlistment,@505") +#pragma comment(linker, "/EXPORT:NtSetInformationFile=ntdll.NtSetInformationFile,@506") +#pragma comment(linker, "/EXPORT:NtSetInformationJobObject=ntdll.NtSetInformationJobObject,@507") +#pragma comment(linker, "/EXPORT:NtSetInformationKey=ntdll.NtSetInformationKey,@508") +#pragma comment(linker, "/EXPORT:NtSetInformationObject=ntdll.NtSetInformationObject,@509") +#pragma comment(linker, "/EXPORT:NtSetInformationProcess=ntdll.NtSetInformationProcess,@510") +#pragma comment(linker, "/EXPORT:NtSetInformationResourceManager=ntdll.NtSetInformationResourceManager,@511") +#pragma comment(linker, "/EXPORT:NtSetInformationThread=ntdll.NtSetInformationThread,@512") +#pragma comment(linker, "/EXPORT:NtSetInformationToken=ntdll.NtSetInformationToken,@513") +#pragma comment(linker, "/EXPORT:NtSetInformationTransaction=ntdll.NtSetInformationTransaction,@514") +#pragma comment(linker, "/EXPORT:NtSetInformationTransactionManager=ntdll.NtSetInformationTransactionManager,@515") +#pragma comment(linker, "/EXPORT:NtSetInformationWorkerFactory=ntdll.NtSetInformationWorkerFactory,@516") +#pragma comment(linker, "/EXPORT:NtSetIntervalProfile=ntdll.NtSetIntervalProfile,@517") +#pragma comment(linker, "/EXPORT:NtSetIoCompletion=ntdll.NtSetIoCompletion,@518") +#pragma comment(linker, "/EXPORT:NtSetIoCompletionEx=ntdll.NtSetIoCompletionEx,@519") +#pragma comment(linker, "/EXPORT:NtSetLdtEntries=ntdll.NtSetLdtEntries,@520") +#pragma comment(linker, "/EXPORT:NtSetLowEventPair=ntdll.NtSetLowEventPair,@521") +#pragma comment(linker, "/EXPORT:NtSetLowWaitHighEventPair=ntdll.NtSetLowWaitHighEventPair,@522") +#pragma comment(linker, "/EXPORT:NtSetQuotaInformationFile=ntdll.NtSetQuotaInformationFile,@523") +#pragma comment(linker, "/EXPORT:NtSetSecurityObject=ntdll.NtSetSecurityObject,@524") +#pragma comment(linker, "/EXPORT:NtSetSystemEnvironmentValue=ntdll.NtSetSystemEnvironmentValue,@525") +#pragma comment(linker, "/EXPORT:NtSetSystemEnvironmentValueEx=ntdll.NtSetSystemEnvironmentValueEx,@526") +#pragma comment(linker, "/EXPORT:NtSetSystemInformation=ntdll.NtSetSystemInformation,@527") +#pragma comment(linker, "/EXPORT:NtSetSystemPowerState=ntdll.NtSetSystemPowerState,@528") +#pragma comment(linker, "/EXPORT:NtSetSystemTime=ntdll.NtSetSystemTime,@529") +#pragma comment(linker, "/EXPORT:NtSetThreadExecutionState=ntdll.NtSetThreadExecutionState,@530") +#pragma comment(linker, "/EXPORT:NtSetTimer=ntdll.NtSetTimer,@531") +#pragma comment(linker, "/EXPORT:NtSetTimerEx=ntdll.NtSetTimerEx,@532") +#pragma comment(linker, "/EXPORT:NtSetTimerResolution=ntdll.NtSetTimerResolution,@533") +#pragma comment(linker, "/EXPORT:NtSetUuidSeed=ntdll.NtSetUuidSeed,@534") +#pragma comment(linker, "/EXPORT:NtSetValueKey=ntdll.NtSetValueKey,@535") +#pragma comment(linker, "/EXPORT:NtSetVolumeInformationFile=ntdll.NtSetVolumeInformationFile,@536") +#pragma comment(linker, "/EXPORT:NtShutdownSystem=ntdll.NtShutdownSystem,@537") +#pragma comment(linker, "/EXPORT:NtShutdownWorkerFactory=ntdll.NtShutdownWorkerFactory,@538") +#pragma comment(linker, "/EXPORT:NtSignalAndWaitForSingleObject=ntdll.NtSignalAndWaitForSingleObject,@539") +#pragma comment(linker, "/EXPORT:NtSinglePhaseReject=ntdll.NtSinglePhaseReject,@540") +#pragma comment(linker, "/EXPORT:NtStartProfile=ntdll.NtStartProfile,@541") +#pragma comment(linker, "/EXPORT:NtStopProfile=ntdll.NtStopProfile,@542") +#pragma comment(linker, "/EXPORT:NtSuspendProcess=ntdll.NtSuspendProcess,@543") +#pragma comment(linker, "/EXPORT:NtSuspendThread=ntdll.NtSuspendThread,@544") +#pragma comment(linker, "/EXPORT:NtSystemDebugControl=ntdll.NtSystemDebugControl,@545") +#pragma comment(linker, "/EXPORT:NtTerminateJobObject=ntdll.NtTerminateJobObject,@546") +#pragma comment(linker, "/EXPORT:NtTerminateProcess=ntdll.NtTerminateProcess,@547") +#pragma comment(linker, "/EXPORT:NtTerminateThread=ntdll.NtTerminateThread,@548") +#pragma comment(linker, "/EXPORT:NtTestAlert=ntdll.NtTestAlert,@549") +#pragma comment(linker, "/EXPORT:NtThawRegistry=ntdll.NtThawRegistry,@550") +#pragma comment(linker, "/EXPORT:NtThawTransactions=ntdll.NtThawTransactions,@551") +#pragma comment(linker, "/EXPORT:NtTraceControl=ntdll.NtTraceControl,@552") +#pragma comment(linker, "/EXPORT:NtTraceEvent=ntdll.NtTraceEvent,@553") +#pragma comment(linker, "/EXPORT:NtTranslateFilePath=ntdll.NtTranslateFilePath,@554") +#pragma comment(linker, "/EXPORT:NtUmsThreadYield=ntdll.NtUmsThreadYield,@555") +#pragma comment(linker, "/EXPORT:NtUnloadDriver=ntdll.NtUnloadDriver,@556") +#pragma comment(linker, "/EXPORT:NtUnloadKey=ntdll.NtUnloadKey,@557") +#pragma comment(linker, "/EXPORT:NtUnloadKey2=ntdll.NtUnloadKey2,@558") +#pragma comment(linker, "/EXPORT:NtUnloadKeyEx=ntdll.NtUnloadKeyEx,@559") +#pragma comment(linker, "/EXPORT:NtUnlockFile=ntdll.NtUnlockFile,@560") +#pragma comment(linker, "/EXPORT:NtUnlockVirtualMemory=ntdll.NtUnlockVirtualMemory,@561") +#pragma comment(linker, "/EXPORT:NtUnmapViewOfSection=ntdll.NtUnmapViewOfSection,@562") +#pragma comment(linker, "/EXPORT:NtVdmControl=ntdll.NtVdmControl,@563") +#pragma comment(linker, "/EXPORT:NtWaitForDebugEvent=ntdll.NtWaitForDebugEvent,@564") +#pragma comment(linker, "/EXPORT:NtWaitForKeyedEvent=ntdll.NtWaitForKeyedEvent,@565") +#pragma comment(linker, "/EXPORT:NtWaitForMultipleObjects=ntdll.NtWaitForMultipleObjects,@566") +#pragma comment(linker, "/EXPORT:NtWaitForMultipleObjects32=ntdll.NtWaitForMultipleObjects32,@567") +#pragma comment(linker, "/EXPORT:NtWaitForSingleObject=ntdll.NtWaitForSingleObject,@568") +#pragma comment(linker, "/EXPORT:NtWaitForWorkViaWorkerFactory=ntdll.NtWaitForWorkViaWorkerFactory,@569") +#pragma comment(linker, "/EXPORT:NtWaitHighEventPair=ntdll.NtWaitHighEventPair,@570") +#pragma comment(linker, "/EXPORT:NtWaitLowEventPair=ntdll.NtWaitLowEventPair,@571") +#pragma comment(linker, "/EXPORT:NtWorkerFactoryWorkerReady=ntdll.NtWorkerFactoryWorkerReady,@572") +#pragma comment(linker, "/EXPORT:NtWriteFile=ntdll.NtWriteFile,@573") +#pragma comment(linker, "/EXPORT:NtWriteFileGather=ntdll.NtWriteFileGather,@574") +#pragma comment(linker, "/EXPORT:NtWriteRequestData=ntdll.NtWriteRequestData,@575") +#pragma comment(linker, "/EXPORT:NtWriteVirtualMemory=ntdll.NtWriteVirtualMemory,@576") +#pragma comment(linker, "/EXPORT:NtYieldExecution=ntdll.NtYieldExecution,@577") +#pragma comment(linker, "/EXPORT:NtdllDefWindowProc_A=ntdll.NtdllDefWindowProc_A,@578") +#pragma comment(linker, "/EXPORT:NtdllDefWindowProc_W=ntdll.NtdllDefWindowProc_W,@579") +#pragma comment(linker, "/EXPORT:NtdllDialogWndProc_A=ntdll.NtdllDialogWndProc_A,@580") +#pragma comment(linker, "/EXPORT:NtdllDialogWndProc_W=ntdll.NtdllDialogWndProc_W,@581") +#pragma comment(linker, "/EXPORT:PfxFindPrefix=ntdll.PfxFindPrefix,@582") +#pragma comment(linker, "/EXPORT:PfxInitialize=ntdll.PfxInitialize,@583") +#pragma comment(linker, "/EXPORT:PfxInsertPrefix=ntdll.PfxInsertPrefix,@584") +#pragma comment(linker, "/EXPORT:PfxRemovePrefix=ntdll.PfxRemovePrefix,@585") +#pragma comment(linker, "/EXPORT:RtlAbortRXact=ntdll.RtlAbortRXact,@586") +#pragma comment(linker, "/EXPORT:RtlAbsoluteToSelfRelativeSD=ntdll.RtlAbsoluteToSelfRelativeSD,@587") +#pragma comment(linker, "/EXPORT:RtlAcquirePebLock=ntdll.RtlAcquirePebLock,@588") +#pragma comment(linker, "/EXPORT:RtlAcquirePrivilege=ntdll.RtlAcquirePrivilege,@589") +#pragma comment(linker, "/EXPORT:RtlAcquireReleaseSRWLockExclusive=ntdll.RtlAcquireReleaseSRWLockExclusive,@590") +#pragma comment(linker, "/EXPORT:RtlAcquireResourceExclusive=ntdll.RtlAcquireResourceExclusive,@591") +#pragma comment(linker, "/EXPORT:RtlAcquireResourceShared=ntdll.RtlAcquireResourceShared,@592") +#pragma comment(linker, "/EXPORT:RtlAcquireSRWLockExclusive=ntdll.RtlAcquireSRWLockExclusive,@593") +#pragma comment(linker, "/EXPORT:RtlAcquireSRWLockShared=ntdll.RtlAcquireSRWLockShared,@594") +#pragma comment(linker, "/EXPORT:RtlActivateActivationContext=ntdll.RtlActivateActivationContext,@595") +#pragma comment(linker, "/EXPORT:RtlActivateActivationContextEx=ntdll.RtlActivateActivationContextEx,@596") +#pragma comment(linker, "/EXPORT:RtlActivateActivationContextUnsafeFast=ntdll.RtlActivateActivationContextUnsafeFast,@597") +#pragma comment(linker, "/EXPORT:RtlAddAccessAllowedAce=ntdll.RtlAddAccessAllowedAce,@598") +#pragma comment(linker, "/EXPORT:RtlAddAccessAllowedAceEx=ntdll.RtlAddAccessAllowedAceEx,@599") +#pragma comment(linker, "/EXPORT:RtlAddAccessAllowedObjectAce=ntdll.RtlAddAccessAllowedObjectAce,@600") +#pragma comment(linker, "/EXPORT:RtlAddAccessDeniedAce=ntdll.RtlAddAccessDeniedAce,@601") +#pragma comment(linker, "/EXPORT:RtlAddAccessDeniedAceEx=ntdll.RtlAddAccessDeniedAceEx,@602") +#pragma comment(linker, "/EXPORT:RtlAddAccessDeniedObjectAce=ntdll.RtlAddAccessDeniedObjectAce,@603") +#pragma comment(linker, "/EXPORT:RtlAddAce=ntdll.RtlAddAce,@604") +#pragma comment(linker, "/EXPORT:RtlAddActionToRXact=ntdll.RtlAddActionToRXact,@605") +#pragma comment(linker, "/EXPORT:RtlAddAtomToAtomTable=ntdll.RtlAddAtomToAtomTable,@606") +#pragma comment(linker, "/EXPORT:RtlAddAttributeActionToRXact=ntdll.RtlAddAttributeActionToRXact,@607") +#pragma comment(linker, "/EXPORT:RtlAddAuditAccessAce=ntdll.RtlAddAuditAccessAce,@608") +#pragma comment(linker, "/EXPORT:RtlAddAuditAccessAceEx=ntdll.RtlAddAuditAccessAceEx,@609") +#pragma comment(linker, "/EXPORT:RtlAddAuditAccessObjectAce=ntdll.RtlAddAuditAccessObjectAce,@610") +#pragma comment(linker, "/EXPORT:RtlAddCompoundAce=ntdll.RtlAddCompoundAce,@611") +#pragma comment(linker, "/EXPORT:RtlAddFunctionTable=ntdll.RtlAddFunctionTable,@612") +#pragma comment(linker, "/EXPORT:RtlAddIntegrityLabelToBoundaryDescriptor=ntdll.RtlAddIntegrityLabelToBoundaryDescriptor,@613") +#pragma comment(linker, "/EXPORT:RtlAddMandatoryAce=ntdll.RtlAddMandatoryAce,@614") +#pragma comment(linker, "/EXPORT:RtlAddRefActivationContext=ntdll.RtlAddRefActivationContext,@615") +#pragma comment(linker, "/EXPORT:RtlAddRefMemoryStream=ntdll.RtlAddRefMemoryStream,@616") +#pragma comment(linker, "/EXPORT:RtlAddSIDToBoundaryDescriptor=ntdll.RtlAddSIDToBoundaryDescriptor,@617") +#pragma comment(linker, "/EXPORT:RtlAddVectoredContinueHandler=ntdll.RtlAddVectoredContinueHandler,@618") +#pragma comment(linker, "/EXPORT:RtlAddVectoredExceptionHandler=ntdll.RtlAddVectoredExceptionHandler,@619") +#pragma comment(linker, "/EXPORT:RtlAddressInSectionTable=ntdll.RtlAddressInSectionTable,@620") +#pragma comment(linker, "/EXPORT:RtlAdjustPrivilege=ntdll.RtlAdjustPrivilege,@621") +#pragma comment(linker, "/EXPORT:RtlAllocateActivationContextStack=ntdll.RtlAllocateActivationContextStack,@622") +#pragma comment(linker, "/EXPORT:RtlAllocateAndInitializeSid=ntdll.RtlAllocateAndInitializeSid,@623") +#pragma comment(linker, "/EXPORT:RtlAllocateHandle=ntdll.RtlAllocateHandle,@624") +#pragma comment(linker, "/EXPORT:RtlAllocateHeap=ntdll.RtlAllocateHeap,@625") +#pragma comment(linker, "/EXPORT:RtlAllocateMemoryBlockLookaside=ntdll.RtlAllocateMemoryBlockLookaside,@626") +#pragma comment(linker, "/EXPORT:RtlAllocateMemoryZone=ntdll.RtlAllocateMemoryZone,@627") +#pragma comment(linker, "/EXPORT:RtlAnsiCharToUnicodeChar=ntdll.RtlAnsiCharToUnicodeChar,@628") +#pragma comment(linker, "/EXPORT:RtlAnsiStringToUnicodeSize=ntdll.RtlAnsiStringToUnicodeSize,@629") +#pragma comment(linker, "/EXPORT:RtlAnsiStringToUnicodeString=ntdll.RtlAnsiStringToUnicodeString,@630") +#pragma comment(linker, "/EXPORT:RtlAppendAsciizToString=ntdll.RtlAppendAsciizToString,@631") +#pragma comment(linker, "/EXPORT:RtlAppendPathElement=ntdll.RtlAppendPathElement,@632") +#pragma comment(linker, "/EXPORT:RtlAppendStringToString=ntdll.RtlAppendStringToString,@633") +#pragma comment(linker, "/EXPORT:RtlAppendUnicodeStringToString=ntdll.RtlAppendUnicodeStringToString,@634") +#pragma comment(linker, "/EXPORT:RtlAppendUnicodeToString=ntdll.RtlAppendUnicodeToString,@635") +#pragma comment(linker, "/EXPORT:RtlApplicationVerifierStop=ntdll.RtlApplicationVerifierStop,@636") +#pragma comment(linker, "/EXPORT:RtlApplyRXact=ntdll.RtlApplyRXact,@637") +#pragma comment(linker, "/EXPORT:RtlApplyRXactNoFlush=ntdll.RtlApplyRXactNoFlush,@638") +#pragma comment(linker, "/EXPORT:RtlAreAllAccessesGranted=ntdll.RtlAreAllAccessesGranted,@639") +#pragma comment(linker, "/EXPORT:RtlAreAnyAccessesGranted=ntdll.RtlAreAnyAccessesGranted,@640") +#pragma comment(linker, "/EXPORT:RtlAreBitsClear=ntdll.RtlAreBitsClear,@641") +#pragma comment(linker, "/EXPORT:RtlAreBitsSet=ntdll.RtlAreBitsSet,@642") +#pragma comment(linker, "/EXPORT:RtlAssert=ntdll.RtlAssert,@643") +#pragma comment(linker, "/EXPORT:RtlBarrier=ntdll.RtlBarrier,@644") +#pragma comment(linker, "/EXPORT:RtlBarrierForDelete=ntdll.RtlBarrierForDelete,@645") +#pragma comment(linker, "/EXPORT:RtlCancelTimer=ntdll.RtlCancelTimer,@646") +#pragma comment(linker, "/EXPORT:RtlCaptureContext=ntdll.RtlCaptureContext,@647") +#pragma comment(linker, "/EXPORT:RtlCaptureStackBackTrace=ntdll.RtlCaptureStackBackTrace,@648") +#pragma comment(linker, "/EXPORT:RtlCharToInteger=ntdll.RtlCharToInteger,@649") +#pragma comment(linker, "/EXPORT:RtlCheckForOrphanedCriticalSections=ntdll.RtlCheckForOrphanedCriticalSections,@650") +#pragma comment(linker, "/EXPORT:RtlCheckRegistryKey=ntdll.RtlCheckRegistryKey,@651") +#pragma comment(linker, "/EXPORT:RtlCheckSandboxedToken=ntdll.RtlCheckSandboxedToken,@652") +#pragma comment(linker, "/EXPORT:RtlCleanUpTEBLangLists=ntdll.RtlCleanUpTEBLangLists,@653") +#pragma comment(linker, "/EXPORT:RtlClearAllBits=ntdll.RtlClearAllBits,@654") +#pragma comment(linker, "/EXPORT:RtlClearBits=ntdll.RtlClearBits,@655") +#pragma comment(linker, "/EXPORT:RtlCloneMemoryStream=ntdll.RtlCloneMemoryStream,@656") +#pragma comment(linker, "/EXPORT:RtlCloneUserProcess=ntdll.RtlCloneUserProcess,@657") +#pragma comment(linker, "/EXPORT:RtlCmDecodeMemIoResource=ntdll.RtlCmDecodeMemIoResource,@658") +#pragma comment(linker, "/EXPORT:RtlCmEncodeMemIoResource=ntdll.RtlCmEncodeMemIoResource,@659") +#pragma comment(linker, "/EXPORT:RtlCommitDebugInfo=ntdll.RtlCommitDebugInfo,@660") +#pragma comment(linker, "/EXPORT:RtlCommitMemoryStream=ntdll.RtlCommitMemoryStream,@661") +#pragma comment(linker, "/EXPORT:RtlCompactHeap=ntdll.RtlCompactHeap,@662") +#pragma comment(linker, "/EXPORT:RtlCompareAltitudes=ntdll.RtlCompareAltitudes,@663") +#pragma comment(linker, "/EXPORT:RtlCompareMemory=ntdll.RtlCompareMemory,@664") +#pragma comment(linker, "/EXPORT:RtlCompareMemoryUlong=ntdll.RtlCompareMemoryUlong,@665") +#pragma comment(linker, "/EXPORT:RtlCompareString=ntdll.RtlCompareString,@666") +#pragma comment(linker, "/EXPORT:RtlCompareUnicodeString=ntdll.RtlCompareUnicodeString,@667") +#pragma comment(linker, "/EXPORT:RtlCompareUnicodeStrings=ntdll.RtlCompareUnicodeStrings,@668") +#pragma comment(linker, "/EXPORT:RtlCompleteProcessCloning=ntdll.RtlCompleteProcessCloning,@669") +#pragma comment(linker, "/EXPORT:RtlCompressBuffer=ntdll.RtlCompressBuffer,@670") +#pragma comment(linker, "/EXPORT:RtlComputeCrc32=ntdll.RtlComputeCrc32,@671") +#pragma comment(linker, "/EXPORT:RtlComputeImportTableHash=ntdll.RtlComputeImportTableHash,@672") +#pragma comment(linker, "/EXPORT:RtlComputePrivatizedDllName_U=ntdll.RtlComputePrivatizedDllName_U,@673") +#pragma comment(linker, "/EXPORT:RtlConnectToSm=ntdll.RtlConnectToSm,@674") +#pragma comment(linker, "/EXPORT:RtlConsoleMultiByteToUnicodeN=ntdll.RtlConsoleMultiByteToUnicodeN,@675") +#pragma comment(linker, "/EXPORT:RtlContractHashTable=ntdll.RtlContractHashTable,@676") +#pragma comment(linker, "/EXPORT:RtlConvertExclusiveToShared=ntdll.RtlConvertExclusiveToShared,@677") +#pragma comment(linker, "/EXPORT:RtlConvertLCIDToString=ntdll.RtlConvertLCIDToString,@678") +#pragma comment(linker, "/EXPORT:RtlConvertSharedToExclusive=ntdll.RtlConvertSharedToExclusive,@679") +#pragma comment(linker, "/EXPORT:RtlConvertSidToUnicodeString=ntdll.RtlConvertSidToUnicodeString,@680") +#pragma comment(linker, "/EXPORT:RtlConvertToAutoInheritSecurityObject=ntdll.RtlConvertToAutoInheritSecurityObject,@681") +#pragma comment(linker, "/EXPORT:RtlConvertUiListToApiList=ntdll.RtlConvertUiListToApiList,@682") +#pragma comment(linker, "/EXPORT:RtlCopyContext=ntdll.RtlCopyContext,@683") +#pragma comment(linker, "/EXPORT:RtlCopyExtendedContext=ntdll.RtlCopyExtendedContext,@684") +#pragma comment(linker, "/EXPORT:RtlCopyLuid=ntdll.RtlCopyLuid,@685") +#pragma comment(linker, "/EXPORT:RtlCopyLuidAndAttributesArray=ntdll.RtlCopyLuidAndAttributesArray,@686") +#pragma comment(linker, "/EXPORT:RtlCopyMappedMemory=ntdll.RtlCopyMappedMemory,@687") +#pragma comment(linker, "/EXPORT:RtlCopyMemory=ntdll.RtlCopyMemory,@688") +#pragma comment(linker, "/EXPORT:RtlCopyMemoryNonTemporal=ntdll.RtlCopyMemoryNonTemporal,@689") +#pragma comment(linker, "/EXPORT:RtlCopyMemoryStreamTo=ntdll.RtlCopyMemoryStreamTo,@690") +#pragma comment(linker, "/EXPORT:RtlCopyOutOfProcessMemoryStreamTo=ntdll.RtlCopyOutOfProcessMemoryStreamTo,@691") +#pragma comment(linker, "/EXPORT:RtlCopySecurityDescriptor=ntdll.RtlCopySecurityDescriptor,@692") +#pragma comment(linker, "/EXPORT:RtlCopySid=ntdll.RtlCopySid,@693") +#pragma comment(linker, "/EXPORT:RtlCopySidAndAttributesArray=ntdll.RtlCopySidAndAttributesArray,@694") +#pragma comment(linker, "/EXPORT:RtlCopyString=ntdll.RtlCopyString,@695") +#pragma comment(linker, "/EXPORT:RtlCopyUnicodeString=ntdll.RtlCopyUnicodeString,@696") +#pragma comment(linker, "/EXPORT:RtlCreateAcl=ntdll.RtlCreateAcl,@697") +#pragma comment(linker, "/EXPORT:RtlCreateActivationContext=ntdll.RtlCreateActivationContext,@698") +#pragma comment(linker, "/EXPORT:RtlCreateAndSetSD=ntdll.RtlCreateAndSetSD,@699") +#pragma comment(linker, "/EXPORT:RtlCreateAtomTable=ntdll.RtlCreateAtomTable,@700") +#pragma comment(linker, "/EXPORT:RtlCreateBootStatusDataFile=ntdll.RtlCreateBootStatusDataFile,@701") +#pragma comment(linker, "/EXPORT:RtlCreateBoundaryDescriptor=ntdll.RtlCreateBoundaryDescriptor,@702") +#pragma comment(linker, "/EXPORT:RtlCreateEnvironment=ntdll.RtlCreateEnvironment,@703") +#pragma comment(linker, "/EXPORT:RtlCreateEnvironmentEx=ntdll.RtlCreateEnvironmentEx,@704") +#pragma comment(linker, "/EXPORT:RtlCreateHashTable=ntdll.RtlCreateHashTable,@705") +#pragma comment(linker, "/EXPORT:RtlCreateHeap=ntdll.RtlCreateHeap,@706") +#pragma comment(linker, "/EXPORT:RtlCreateMemoryBlockLookaside=ntdll.RtlCreateMemoryBlockLookaside,@707") +#pragma comment(linker, "/EXPORT:RtlCreateMemoryZone=ntdll.RtlCreateMemoryZone,@708") +#pragma comment(linker, "/EXPORT:RtlCreateProcessParameters=ntdll.RtlCreateProcessParameters,@709") +#pragma comment(linker, "/EXPORT:RtlCreateProcessParametersEx=ntdll.RtlCreateProcessParametersEx,@710") +#pragma comment(linker, "/EXPORT:RtlCreateProcessReflection=ntdll.RtlCreateProcessReflection,@711") +#pragma comment(linker, "/EXPORT:RtlCreateQueryDebugBuffer=ntdll.RtlCreateQueryDebugBuffer,@712") +#pragma comment(linker, "/EXPORT:RtlCreateRegistryKey=ntdll.RtlCreateRegistryKey,@713") +#pragma comment(linker, "/EXPORT:RtlCreateSecurityDescriptor=ntdll.RtlCreateSecurityDescriptor,@714") +#pragma comment(linker, "/EXPORT:RtlCreateServiceSid=ntdll.RtlCreateServiceSid,@715") +#pragma comment(linker, "/EXPORT:RtlCreateSystemVolumeInformationFolder=ntdll.RtlCreateSystemVolumeInformationFolder,@716") +#pragma comment(linker, "/EXPORT:RtlCreateTagHeap=ntdll.RtlCreateTagHeap,@717") +#pragma comment(linker, "/EXPORT:RtlCreateTimer=ntdll.RtlCreateTimer,@718") +#pragma comment(linker, "/EXPORT:RtlCreateTimerQueue=ntdll.RtlCreateTimerQueue,@719") +#pragma comment(linker, "/EXPORT:RtlCreateUmsCompletionList=ntdll.RtlCreateUmsCompletionList,@720") +#pragma comment(linker, "/EXPORT:RtlCreateUmsThread=ntdll.RtlCreateUmsThread,@721") +#pragma comment(linker, "/EXPORT:RtlCreateUmsThreadContext=ntdll.RtlCreateUmsThreadContext,@722") +#pragma comment(linker, "/EXPORT:RtlCreateUnicodeString=ntdll.RtlCreateUnicodeString,@723") +#pragma comment(linker, "/EXPORT:RtlCreateUnicodeStringFromAsciiz=ntdll.RtlCreateUnicodeStringFromAsciiz,@724") +#pragma comment(linker, "/EXPORT:RtlCreateUserProcess=ntdll.RtlCreateUserProcess,@725") +#pragma comment(linker, "/EXPORT:RtlCreateUserSecurityObject=ntdll.RtlCreateUserSecurityObject,@726") +#pragma comment(linker, "/EXPORT:RtlCreateUserStack=ntdll.RtlCreateUserStack,@727") +#pragma comment(linker, "/EXPORT:RtlCreateUserThread=ntdll.RtlCreateUserThread,@728") +#pragma comment(linker, "/EXPORT:RtlCreateVirtualAccountSid=ntdll.RtlCreateVirtualAccountSid,@729") +#pragma comment(linker, "/EXPORT:RtlCultureNameToLCID=ntdll.RtlCultureNameToLCID,@730") +#pragma comment(linker, "/EXPORT:RtlCustomCPToUnicodeN=ntdll.RtlCustomCPToUnicodeN,@731") +#pragma comment(linker, "/EXPORT:RtlCutoverTimeToSystemTime=ntdll.RtlCutoverTimeToSystemTime,@732") +#pragma comment(linker, "/EXPORT:RtlDeCommitDebugInfo=ntdll.RtlDeCommitDebugInfo,@733") +#pragma comment(linker, "/EXPORT:RtlDeNormalizeProcessParams=ntdll.RtlDeNormalizeProcessParams,@734") +#pragma comment(linker, "/EXPORT:RtlDeactivateActivationContext=ntdll.RtlDeactivateActivationContext,@735") +#pragma comment(linker, "/EXPORT:RtlDeactivateActivationContextUnsafeFast=ntdll.RtlDeactivateActivationContextUnsafeFast,@736") +#pragma comment(linker, "/EXPORT:RtlDebugPrintTimes=ntdll.RtlDebugPrintTimes,@737") +#pragma comment(linker, "/EXPORT:RtlDecodePointer=ntdll.RtlDecodePointer,@738") +#pragma comment(linker, "/EXPORT:RtlDecodeSystemPointer=ntdll.RtlDecodeSystemPointer,@739") +#pragma comment(linker, "/EXPORT:RtlDecompressBuffer=ntdll.RtlDecompressBuffer,@740") +#pragma comment(linker, "/EXPORT:RtlDecompressFragment=ntdll.RtlDecompressFragment,@741") +#pragma comment(linker, "/EXPORT:RtlDefaultNpAcl=ntdll.RtlDefaultNpAcl,@742") +#pragma comment(linker, "/EXPORT:RtlDelete=ntdll.RtlDelete,@743") +#pragma comment(linker, "/EXPORT:RtlDeleteAce=ntdll.RtlDeleteAce,@744") +#pragma comment(linker, "/EXPORT:RtlDeleteAtomFromAtomTable=ntdll.RtlDeleteAtomFromAtomTable,@745") +#pragma comment(linker, "/EXPORT:RtlDeleteBarrier=ntdll.RtlDeleteBarrier,@746") +#pragma comment(linker, "/EXPORT:RtlDeleteBoundaryDescriptor=ntdll.RtlDeleteBoundaryDescriptor,@747") +#pragma comment(linker, "/EXPORT:RtlDeleteCriticalSection=ntdll.RtlDeleteCriticalSection,@748") +#pragma comment(linker, "/EXPORT:RtlDeleteElementGenericTable=ntdll.RtlDeleteElementGenericTable,@749") +#pragma comment(linker, "/EXPORT:RtlDeleteElementGenericTableAvl=ntdll.RtlDeleteElementGenericTableAvl,@750") +#pragma comment(linker, "/EXPORT:RtlDeleteFunctionTable=ntdll.RtlDeleteFunctionTable,@751") +#pragma comment(linker, "/EXPORT:RtlDeleteHashTable=ntdll.RtlDeleteHashTable,@752") +#pragma comment(linker, "/EXPORT:RtlDeleteNoSplay=ntdll.RtlDeleteNoSplay,@753") +#pragma comment(linker, "/EXPORT:RtlDeleteRegistryValue=ntdll.RtlDeleteRegistryValue,@754") +#pragma comment(linker, "/EXPORT:RtlDeleteResource=ntdll.RtlDeleteResource,@755") +#pragma comment(linker, "/EXPORT:RtlDeleteSecurityObject=ntdll.RtlDeleteSecurityObject,@756") +#pragma comment(linker, "/EXPORT:RtlDeleteTimer=ntdll.RtlDeleteTimer,@757") +#pragma comment(linker, "/EXPORT:RtlDeleteTimerQueue=ntdll.RtlDeleteTimerQueue,@758") +#pragma comment(linker, "/EXPORT:RtlDeleteTimerQueueEx=ntdll.RtlDeleteTimerQueueEx,@759") +#pragma comment(linker, "/EXPORT:RtlDeleteUmsCompletionList=ntdll.RtlDeleteUmsCompletionList,@760") +#pragma comment(linker, "/EXPORT:RtlDeleteUmsThreadContext=ntdll.RtlDeleteUmsThreadContext,@761") +#pragma comment(linker, "/EXPORT:RtlDequeueUmsCompletionListItems=ntdll.RtlDequeueUmsCompletionListItems,@762") +#pragma comment(linker, "/EXPORT:RtlDeregisterSecureMemoryCacheCallback=ntdll.RtlDeregisterSecureMemoryCacheCallback,@763") +#pragma comment(linker, "/EXPORT:RtlDeregisterWait=ntdll.RtlDeregisterWait,@764") +#pragma comment(linker, "/EXPORT:RtlDeregisterWaitEx=ntdll.RtlDeregisterWaitEx,@765") +#pragma comment(linker, "/EXPORT:RtlDestroyAtomTable=ntdll.RtlDestroyAtomTable,@766") +#pragma comment(linker, "/EXPORT:RtlDestroyEnvironment=ntdll.RtlDestroyEnvironment,@767") +#pragma comment(linker, "/EXPORT:RtlDestroyHandleTable=ntdll.RtlDestroyHandleTable,@768") +#pragma comment(linker, "/EXPORT:RtlDestroyHeap=ntdll.RtlDestroyHeap,@769") +#pragma comment(linker, "/EXPORT:RtlDestroyMemoryBlockLookaside=ntdll.RtlDestroyMemoryBlockLookaside,@770") +#pragma comment(linker, "/EXPORT:RtlDestroyMemoryZone=ntdll.RtlDestroyMemoryZone,@771") +#pragma comment(linker, "/EXPORT:RtlDestroyProcessParameters=ntdll.RtlDestroyProcessParameters,@772") +#pragma comment(linker, "/EXPORT:RtlDestroyQueryDebugBuffer=ntdll.RtlDestroyQueryDebugBuffer,@773") +#pragma comment(linker, "/EXPORT:RtlDetectHeapLeaks=ntdll.RtlDetectHeapLeaks,@774") +#pragma comment(linker, "/EXPORT:RtlDetermineDosPathNameType_U=ntdll.RtlDetermineDosPathNameType_U,@775") +#pragma comment(linker, "/EXPORT:RtlDisableThreadProfiling=ntdll.RtlDisableThreadProfiling,@776") +#pragma comment(linker, "/EXPORT:RtlDllShutdownInProgress=ntdll.RtlDllShutdownInProgress,@777") +#pragma comment(linker, "/EXPORT:RtlDnsHostNameToComputerName=ntdll.RtlDnsHostNameToComputerName,@778") +#pragma comment(linker, "/EXPORT:RtlDoesFileExists_U=ntdll.RtlDoesFileExists_U,@779") +#pragma comment(linker, "/EXPORT:RtlDosApplyFileIsolationRedirection_Ustr=ntdll.RtlDosApplyFileIsolationRedirection_Ustr,@780") +#pragma comment(linker, "/EXPORT:RtlDosPathNameToNtPathName_U=ntdll.RtlDosPathNameToNtPathName_U,@781") +#pragma comment(linker, "/EXPORT:RtlDosPathNameToNtPathName_U_WithStatus=ntdll.RtlDosPathNameToNtPathName_U_WithStatus,@782") +#pragma comment(linker, "/EXPORT:RtlDosPathNameToRelativeNtPathName_U=ntdll.RtlDosPathNameToRelativeNtPathName_U,@783") +#pragma comment(linker, "/EXPORT:RtlDosPathNameToRelativeNtPathName_U_WithStatus=ntdll.RtlDosPathNameToRelativeNtPathName_U_WithStatus,@784") +#pragma comment(linker, "/EXPORT:RtlDosSearchPath_U=ntdll.RtlDosSearchPath_U,@785") +#pragma comment(linker, "/EXPORT:RtlDosSearchPath_Ustr=ntdll.RtlDosSearchPath_Ustr,@786") +#pragma comment(linker, "/EXPORT:RtlDowncaseUnicodeChar=ntdll.RtlDowncaseUnicodeChar,@787") +#pragma comment(linker, "/EXPORT:RtlDowncaseUnicodeString=ntdll.RtlDowncaseUnicodeString,@788") +#pragma comment(linker, "/EXPORT:RtlDumpResource=ntdll.RtlDumpResource,@789") +#pragma comment(linker, "/EXPORT:RtlDuplicateUnicodeString=ntdll.RtlDuplicateUnicodeString,@790") +#pragma comment(linker, "/EXPORT:RtlEmptyAtomTable=ntdll.RtlEmptyAtomTable,@791") +#pragma comment(linker, "/EXPORT:RtlEnableEarlyCriticalSectionEventCreation=ntdll.RtlEnableEarlyCriticalSectionEventCreation,@792") +#pragma comment(linker, "/EXPORT:RtlEnableThreadProfiling=ntdll.RtlEnableThreadProfiling,@793") +#pragma comment(linker, "/EXPORT:RtlEncodePointer=ntdll.RtlEncodePointer,@794") +#pragma comment(linker, "/EXPORT:RtlEncodeSystemPointer=ntdll.RtlEncodeSystemPointer,@795") +#pragma comment(linker, "/EXPORT:RtlEndEnumerationHashTable=ntdll.RtlEndEnumerationHashTable,@796") +#pragma comment(linker, "/EXPORT:RtlEndWeakEnumerationHashTable=ntdll.RtlEndWeakEnumerationHashTable,@797") +#pragma comment(linker, "/EXPORT:RtlEnterCriticalSection=ntdll.RtlEnterCriticalSection,@798") +#pragma comment(linker, "/EXPORT:RtlEnterUmsSchedulingMode=ntdll.RtlEnterUmsSchedulingMode,@799") +#pragma comment(linker, "/EXPORT:RtlEnumProcessHeaps=ntdll.RtlEnumProcessHeaps,@800") +#pragma comment(linker, "/EXPORT:RtlEnumerateEntryHashTable=ntdll.RtlEnumerateEntryHashTable,@801") +#pragma comment(linker, "/EXPORT:RtlEnumerateGenericTable=ntdll.RtlEnumerateGenericTable,@802") +#pragma comment(linker, "/EXPORT:RtlEnumerateGenericTableAvl=ntdll.RtlEnumerateGenericTableAvl,@803") +#pragma comment(linker, "/EXPORT:RtlEnumerateGenericTableLikeADirectory=ntdll.RtlEnumerateGenericTableLikeADirectory,@804") +#pragma comment(linker, "/EXPORT:RtlEnumerateGenericTableWithoutSplaying=ntdll.RtlEnumerateGenericTableWithoutSplaying,@805") +#pragma comment(linker, "/EXPORT:RtlEnumerateGenericTableWithoutSplayingAvl=ntdll.RtlEnumerateGenericTableWithoutSplayingAvl,@806") +#pragma comment(linker, "/EXPORT:RtlEqualComputerName=ntdll.RtlEqualComputerName,@807") +#pragma comment(linker, "/EXPORT:RtlEqualDomainName=ntdll.RtlEqualDomainName,@808") +#pragma comment(linker, "/EXPORT:RtlEqualLuid=ntdll.RtlEqualLuid,@809") +#pragma comment(linker, "/EXPORT:RtlEqualPrefixSid=ntdll.RtlEqualPrefixSid,@810") +#pragma comment(linker, "/EXPORT:RtlEqualSid=ntdll.RtlEqualSid,@811") +#pragma comment(linker, "/EXPORT:RtlEqualString=ntdll.RtlEqualString,@812") +#pragma comment(linker, "/EXPORT:RtlEqualUnicodeString=ntdll.RtlEqualUnicodeString,@813") +#pragma comment(linker, "/EXPORT:RtlEraseUnicodeString=ntdll.RtlEraseUnicodeString,@814") +#pragma comment(linker, "/EXPORT:RtlEthernetAddressToStringA=ntdll.RtlEthernetAddressToStringA,@815") +#pragma comment(linker, "/EXPORT:RtlEthernetAddressToStringW=ntdll.RtlEthernetAddressToStringW,@816") +#pragma comment(linker, "/EXPORT:RtlEthernetStringToAddressA=ntdll.RtlEthernetStringToAddressA,@817") +#pragma comment(linker, "/EXPORT:RtlEthernetStringToAddressW=ntdll.RtlEthernetStringToAddressW,@818") +#pragma comment(linker, "/EXPORT:RtlExecuteUmsThread=ntdll.RtlExecuteUmsThread,@819") +#pragma comment(linker, "/EXPORT:RtlExitUserProcess=ntdll.RtlExitUserProcess,@820") +#pragma comment(linker, "/EXPORT:RtlExitUserThread=ntdll.RtlExitUserThread,@821") +#pragma comment(linker, "/EXPORT:RtlExpandEnvironmentStrings=ntdll.RtlExpandEnvironmentStrings,@822") +#pragma comment(linker, "/EXPORT:RtlExpandEnvironmentStrings_U=ntdll.RtlExpandEnvironmentStrings_U,@823") +#pragma comment(linker, "/EXPORT:RtlExpandHashTable=ntdll.RtlExpandHashTable,@824") +#pragma comment(linker, "/EXPORT:RtlExtendMemoryBlockLookaside=ntdll.RtlExtendMemoryBlockLookaside,@825") +#pragma comment(linker, "/EXPORT:RtlExtendMemoryZone=ntdll.RtlExtendMemoryZone,@826") +#pragma comment(linker, "/EXPORT:RtlFillMemory=ntdll.RtlFillMemory,@827") +#pragma comment(linker, "/EXPORT:RtlFinalReleaseOutOfProcessMemoryStream=ntdll.RtlFinalReleaseOutOfProcessMemoryStream,@828") +#pragma comment(linker, "/EXPORT:RtlFindAceByType=ntdll.RtlFindAceByType,@829") +#pragma comment(linker, "/EXPORT:RtlFindActivationContextSectionGuid=ntdll.RtlFindActivationContextSectionGuid,@830") +#pragma comment(linker, "/EXPORT:RtlFindActivationContextSectionString=ntdll.RtlFindActivationContextSectionString,@831") +#pragma comment(linker, "/EXPORT:RtlFindCharInUnicodeString=ntdll.RtlFindCharInUnicodeString,@832") +#pragma comment(linker, "/EXPORT:RtlFindClearBits=ntdll.RtlFindClearBits,@833") +#pragma comment(linker, "/EXPORT:RtlFindClearBitsAndSet=ntdll.RtlFindClearBitsAndSet,@834") +#pragma comment(linker, "/EXPORT:RtlFindClearRuns=ntdll.RtlFindClearRuns,@835") +#pragma comment(linker, "/EXPORT:RtlFindClosestEncodableLength=ntdll.RtlFindClosestEncodableLength,@836") +#pragma comment(linker, "/EXPORT:RtlFindLastBackwardRunClear=ntdll.RtlFindLastBackwardRunClear,@837") +#pragma comment(linker, "/EXPORT:RtlFindLeastSignificantBit=ntdll.RtlFindLeastSignificantBit,@838") +#pragma comment(linker, "/EXPORT:RtlFindLongestRunClear=ntdll.RtlFindLongestRunClear,@839") +#pragma comment(linker, "/EXPORT:RtlFindMessage=ntdll.RtlFindMessage,@840") +#pragma comment(linker, "/EXPORT:RtlFindMostSignificantBit=ntdll.RtlFindMostSignificantBit,@841") +#pragma comment(linker, "/EXPORT:RtlFindNextForwardRunClear=ntdll.RtlFindNextForwardRunClear,@842") +#pragma comment(linker, "/EXPORT:RtlFindSetBits=ntdll.RtlFindSetBits,@843") +#pragma comment(linker, "/EXPORT:RtlFindSetBitsAndClear=ntdll.RtlFindSetBitsAndClear,@844") +#pragma comment(linker, "/EXPORT:RtlFirstEntrySList=ntdll.RtlFirstEntrySList,@845") +#pragma comment(linker, "/EXPORT:RtlFirstFreeAce=ntdll.RtlFirstFreeAce,@846") +#pragma comment(linker, "/EXPORT:RtlFlsAlloc=ntdll.RtlFlsAlloc,@847") +#pragma comment(linker, "/EXPORT:RtlFlsFree=ntdll.RtlFlsFree,@848") +#pragma comment(linker, "/EXPORT:RtlFlushSecureMemoryCache=ntdll.RtlFlushSecureMemoryCache,@849") +#pragma comment(linker, "/EXPORT:RtlFormatCurrentUserKeyPath=ntdll.RtlFormatCurrentUserKeyPath,@850") +#pragma comment(linker, "/EXPORT:RtlFormatMessage=ntdll.RtlFormatMessage,@851") +#pragma comment(linker, "/EXPORT:RtlFormatMessageEx=ntdll.RtlFormatMessageEx,@852") +#pragma comment(linker, "/EXPORT:RtlFreeActivationContextStack=ntdll.RtlFreeActivationContextStack,@853") +#pragma comment(linker, "/EXPORT:RtlFreeAnsiString=ntdll.RtlFreeAnsiString,@854") +#pragma comment(linker, "/EXPORT:RtlFreeHandle=ntdll.RtlFreeHandle,@855") +#pragma comment(linker, "/EXPORT:RtlFreeHeap=ntdll.RtlFreeHeap,@856") +#pragma comment(linker, "/EXPORT:RtlFreeMemoryBlockLookaside=ntdll.RtlFreeMemoryBlockLookaside,@857") +#pragma comment(linker, "/EXPORT:RtlFreeOemString=ntdll.RtlFreeOemString,@858") +#pragma comment(linker, "/EXPORT:RtlFreeSid=ntdll.RtlFreeSid,@859") +#pragma comment(linker, "/EXPORT:RtlFreeThreadActivationContextStack=ntdll.RtlFreeThreadActivationContextStack,@860") +#pragma comment(linker, "/EXPORT:RtlFreeUnicodeString=ntdll.RtlFreeUnicodeString,@861") +#pragma comment(linker, "/EXPORT:RtlFreeUserStack=ntdll.RtlFreeUserStack,@862") +#pragma comment(linker, "/EXPORT:RtlGUIDFromString=ntdll.RtlGUIDFromString,@863") +#pragma comment(linker, "/EXPORT:RtlGenerate8dot3Name=ntdll.RtlGenerate8dot3Name,@864") +#pragma comment(linker, "/EXPORT:RtlGetAce=ntdll.RtlGetAce,@865") +#pragma comment(linker, "/EXPORT:RtlGetActiveActivationContext=ntdll.RtlGetActiveActivationContext,@866") +#pragma comment(linker, "/EXPORT:RtlGetCallersAddress=ntdll.RtlGetCallersAddress,@867") +#pragma comment(linker, "/EXPORT:RtlGetCompressionWorkSpaceSize=ntdll.RtlGetCompressionWorkSpaceSize,@868") +#pragma comment(linker, "/EXPORT:RtlGetControlSecurityDescriptor=ntdll.RtlGetControlSecurityDescriptor,@869") +#pragma comment(linker, "/EXPORT:RtlGetCriticalSectionRecursionCount=ntdll.RtlGetCriticalSectionRecursionCount,@870") +#pragma comment(linker, "/EXPORT:RtlGetCurrentDirectory_U=ntdll.RtlGetCurrentDirectory_U,@871") +#pragma comment(linker, "/EXPORT:RtlGetCurrentPeb=ntdll.RtlGetCurrentPeb,@872") +#pragma comment(linker, "/EXPORT:RtlGetCurrentProcessorNumber=ntdll.RtlGetCurrentProcessorNumber,@873") +#pragma comment(linker, "/EXPORT:RtlGetCurrentProcessorNumberEx=ntdll.RtlGetCurrentProcessorNumberEx,@874") +#pragma comment(linker, "/EXPORT:RtlGetCurrentTransaction=ntdll.RtlGetCurrentTransaction,@875") +#pragma comment(linker, "/EXPORT:RtlGetCurrentUmsThread=ntdll.RtlGetCurrentUmsThread,@876") +#pragma comment(linker, "/EXPORT:RtlGetDaclSecurityDescriptor=ntdll.RtlGetDaclSecurityDescriptor,@877") +#pragma comment(linker, "/EXPORT:RtlGetElementGenericTable=ntdll.RtlGetElementGenericTable,@878") +#pragma comment(linker, "/EXPORT:RtlGetElementGenericTableAvl=ntdll.RtlGetElementGenericTableAvl,@879") +#pragma comment(linker, "/EXPORT:RtlGetEnabledExtendedFeatures=ntdll.RtlGetEnabledExtendedFeatures,@880") +#pragma comment(linker, "/EXPORT:RtlGetExtendedContextLength=ntdll.RtlGetExtendedContextLength,@881") +#pragma comment(linker, "/EXPORT:RtlGetExtendedFeaturesMask=ntdll.RtlGetExtendedFeaturesMask,@882") +#pragma comment(linker, "/EXPORT:RtlGetFileMUIPath=ntdll.RtlGetFileMUIPath,@883") +#pragma comment(linker, "/EXPORT:RtlGetFrame=ntdll.RtlGetFrame,@884") +#pragma comment(linker, "/EXPORT:RtlGetFullPathName_U=ntdll.RtlGetFullPathName_U,@885") +#pragma comment(linker, "/EXPORT:RtlGetFullPathName_UEx=ntdll.RtlGetFullPathName_UEx,@886") +#pragma comment(linker, "/EXPORT:RtlGetFullPathName_UstrEx=ntdll.RtlGetFullPathName_UstrEx,@887") +#pragma comment(linker, "/EXPORT:RtlGetFunctionTableListHead=ntdll.RtlGetFunctionTableListHead,@888") +#pragma comment(linker, "/EXPORT:RtlGetGroupSecurityDescriptor=ntdll.RtlGetGroupSecurityDescriptor,@889") +#pragma comment(linker, "/EXPORT:RtlGetIntegerAtom=ntdll.RtlGetIntegerAtom,@890") +#pragma comment(linker, "/EXPORT:RtlGetLastNtStatus=ntdll.RtlGetLastNtStatus,@891") +#pragma comment(linker, "/EXPORT:RtlGetLastWin32Error=ntdll.RtlGetLastWin32Error,@892") +#pragma comment(linker, "/EXPORT:RtlGetLengthWithoutLastFullDosOrNtPathElement=ntdll.RtlGetLengthWithoutLastFullDosOrNtPathElement,@893") +#pragma comment(linker, "/EXPORT:RtlGetLengthWithoutTrailingPathSeperators=ntdll.RtlGetLengthWithoutTrailingPathSeperators,@894") +#pragma comment(linker, "/EXPORT:RtlGetLocaleFileMappingAddress=ntdll.RtlGetLocaleFileMappingAddress,@895") +#pragma comment(linker, "/EXPORT:RtlGetLongestNtPathLength=ntdll.RtlGetLongestNtPathLength,@896") +#pragma comment(linker, "/EXPORT:RtlGetNativeSystemInformation=ntdll.RtlGetNativeSystemInformation,@897") +#pragma comment(linker, "/EXPORT:RtlGetNextEntryHashTable=ntdll.RtlGetNextEntryHashTable,@898") +#pragma comment(linker, "/EXPORT:RtlGetNextUmsListItem=ntdll.RtlGetNextUmsListItem,@899") +#pragma comment(linker, "/EXPORT:RtlGetNtGlobalFlags=ntdll.RtlGetNtGlobalFlags,@900") +#pragma comment(linker, "/EXPORT:RtlGetNtProductType=ntdll.RtlGetNtProductType,@901") +#pragma comment(linker, "/EXPORT:RtlGetNtVersionNumbers=ntdll.RtlGetNtVersionNumbers,@902") +#pragma comment(linker, "/EXPORT:RtlGetOwnerSecurityDescriptor=ntdll.RtlGetOwnerSecurityDescriptor,@903") +#pragma comment(linker, "/EXPORT:RtlGetParentLocaleName=ntdll.RtlGetParentLocaleName,@904") +#pragma comment(linker, "/EXPORT:RtlGetProcessHeaps=ntdll.RtlGetProcessHeaps,@905") +#pragma comment(linker, "/EXPORT:RtlGetProcessPreferredUILanguages=ntdll.RtlGetProcessPreferredUILanguages,@906") +#pragma comment(linker, "/EXPORT:RtlGetProductInfo=ntdll.RtlGetProductInfo,@907") +#pragma comment(linker, "/EXPORT:RtlGetSaclSecurityDescriptor=ntdll.RtlGetSaclSecurityDescriptor,@908") +#pragma comment(linker, "/EXPORT:RtlGetSecurityDescriptorRMControl=ntdll.RtlGetSecurityDescriptorRMControl,@909") +#pragma comment(linker, "/EXPORT:RtlGetSetBootStatusData=ntdll.RtlGetSetBootStatusData,@910") +#pragma comment(linker, "/EXPORT:RtlGetSystemPreferredUILanguages=ntdll.RtlGetSystemPreferredUILanguages,@911") +#pragma comment(linker, "/EXPORT:RtlGetThreadErrorMode=ntdll.RtlGetThreadErrorMode,@912") +#pragma comment(linker, "/EXPORT:RtlGetThreadLangIdByIndex=ntdll.RtlGetThreadLangIdByIndex,@913") +#pragma comment(linker, "/EXPORT:RtlGetThreadPreferredUILanguages=ntdll.RtlGetThreadPreferredUILanguages,@914") +#pragma comment(linker, "/EXPORT:RtlGetUILanguageInfo=ntdll.RtlGetUILanguageInfo,@915") +#pragma comment(linker, "/EXPORT:RtlGetUmsCompletionListEvent=ntdll.RtlGetUmsCompletionListEvent,@916") +#pragma comment(linker, "/EXPORT:RtlGetUnloadEventTrace=ntdll.RtlGetUnloadEventTrace,@917") +#pragma comment(linker, "/EXPORT:RtlGetUnloadEventTraceEx=ntdll.RtlGetUnloadEventTraceEx,@918") +#pragma comment(linker, "/EXPORT:RtlGetUserInfoHeap=ntdll.RtlGetUserInfoHeap,@919") +#pragma comment(linker, "/EXPORT:RtlGetUserPreferredUILanguages=ntdll.RtlGetUserPreferredUILanguages,@920") +#pragma comment(linker, "/EXPORT:RtlGetVersion=ntdll.RtlGetVersion,@921") +#pragma comment(linker, "/EXPORT:RtlHashUnicodeString=ntdll.RtlHashUnicodeString,@922") +#pragma comment(linker, "/EXPORT:RtlHeapTrkInitialize=ntdll.RtlHeapTrkInitialize,@923") +#pragma comment(linker, "/EXPORT:RtlIdentifierAuthoritySid=ntdll.RtlIdentifierAuthoritySid,@924") +#pragma comment(linker, "/EXPORT:RtlIdnToAscii=ntdll.RtlIdnToAscii,@925") +#pragma comment(linker, "/EXPORT:RtlIdnToNameprepUnicode=ntdll.RtlIdnToNameprepUnicode,@926") +#pragma comment(linker, "/EXPORT:RtlIdnToUnicode=ntdll.RtlIdnToUnicode,@927") +#pragma comment(linker, "/EXPORT:RtlImageDirectoryEntryToData=ntdll.RtlImageDirectoryEntryToData,@928") +#pragma comment(linker, "/EXPORT:RtlImageNtHeader=ntdll.RtlImageNtHeader,@929") +#pragma comment(linker, "/EXPORT:RtlImageNtHeaderEx=ntdll.RtlImageNtHeaderEx,@930") +#pragma comment(linker, "/EXPORT:RtlImageRvaToSection=ntdll.RtlImageRvaToSection,@931") +#pragma comment(linker, "/EXPORT:RtlImageRvaToVa=ntdll.RtlImageRvaToVa,@932") +#pragma comment(linker, "/EXPORT:RtlImpersonateSelf=ntdll.RtlImpersonateSelf,@933") +#pragma comment(linker, "/EXPORT:RtlImpersonateSelfEx=ntdll.RtlImpersonateSelfEx,@934") +#pragma comment(linker, "/EXPORT:RtlInitAnsiString=ntdll.RtlInitAnsiString,@935") +#pragma comment(linker, "/EXPORT:RtlInitAnsiStringEx=ntdll.RtlInitAnsiStringEx,@936") +#pragma comment(linker, "/EXPORT:RtlInitBarrier=ntdll.RtlInitBarrier,@937") +#pragma comment(linker, "/EXPORT:RtlInitCodePageTable=ntdll.RtlInitCodePageTable,@938") +#pragma comment(linker, "/EXPORT:RtlInitEnumerationHashTable=ntdll.RtlInitEnumerationHashTable,@939") +#pragma comment(linker, "/EXPORT:RtlInitMemoryStream=ntdll.RtlInitMemoryStream,@940") +#pragma comment(linker, "/EXPORT:RtlInitNlsTables=ntdll.RtlInitNlsTables,@941") +#pragma comment(linker, "/EXPORT:RtlInitOutOfProcessMemoryStream=ntdll.RtlInitOutOfProcessMemoryStream,@942") +#pragma comment(linker, "/EXPORT:RtlInitString=ntdll.RtlInitString,@943") +#pragma comment(linker, "/EXPORT:RtlInitUnicodeString=ntdll.RtlInitUnicodeString,@944") +#pragma comment(linker, "/EXPORT:RtlInitUnicodeStringEx=ntdll.RtlInitUnicodeStringEx,@945") +#pragma comment(linker, "/EXPORT:RtlInitWeakEnumerationHashTable=ntdll.RtlInitWeakEnumerationHashTable,@946") +#pragma comment(linker, "/EXPORT:RtlInitializeAtomPackage=ntdll.RtlInitializeAtomPackage,@947") +#pragma comment(linker, "/EXPORT:RtlInitializeBitMap=ntdll.RtlInitializeBitMap,@948") +#pragma comment(linker, "/EXPORT:RtlInitializeConditionVariable=ntdll.RtlInitializeConditionVariable,@949") +#pragma comment(linker, "/EXPORT:RtlInitializeContext=ntdll.RtlInitializeContext,@950") +#pragma comment(linker, "/EXPORT:RtlInitializeCriticalSection=ntdll.RtlInitializeCriticalSection,@951") +#pragma comment(linker, "/EXPORT:RtlInitializeCriticalSectionAndSpinCount=ntdll.RtlInitializeCriticalSectionAndSpinCount,@952") +#pragma comment(linker, "/EXPORT:RtlInitializeCriticalSectionEx=ntdll.RtlInitializeCriticalSectionEx,@953") +#pragma comment(linker, "/EXPORT:RtlInitializeExtendedContext=ntdll.RtlInitializeExtendedContext,@954") +#pragma comment(linker, "/EXPORT:RtlInitializeGenericTable=ntdll.RtlInitializeGenericTable,@955") +#pragma comment(linker, "/EXPORT:RtlInitializeGenericTableAvl=ntdll.RtlInitializeGenericTableAvl,@956") +#pragma comment(linker, "/EXPORT:RtlInitializeHandleTable=ntdll.RtlInitializeHandleTable,@957") +#pragma comment(linker, "/EXPORT:RtlInitializeNtUserPfn=ntdll.RtlInitializeNtUserPfn,@958") +#pragma comment(linker, "/EXPORT:RtlInitializeRXact=ntdll.RtlInitializeRXact,@959") +#pragma comment(linker, "/EXPORT:RtlInitializeResource=ntdll.RtlInitializeResource,@960") +#pragma comment(linker, "/EXPORT:RtlInitializeSListHead=ntdll.RtlInitializeSListHead,@961") +#pragma comment(linker, "/EXPORT:RtlInitializeSRWLock=ntdll.RtlInitializeSRWLock,@962") +#pragma comment(linker, "/EXPORT:RtlInitializeSid=ntdll.RtlInitializeSid,@963") +#pragma comment(linker, "/EXPORT:RtlInsertElementGenericTable=ntdll.RtlInsertElementGenericTable,@964") +#pragma comment(linker, "/EXPORT:RtlInsertElementGenericTableAvl=ntdll.RtlInsertElementGenericTableAvl,@965") +#pragma comment(linker, "/EXPORT:RtlInsertElementGenericTableFull=ntdll.RtlInsertElementGenericTableFull,@966") +#pragma comment(linker, "/EXPORT:RtlInsertElementGenericTableFullAvl=ntdll.RtlInsertElementGenericTableFullAvl,@967") +#pragma comment(linker, "/EXPORT:RtlInsertEntryHashTable=ntdll.RtlInsertEntryHashTable,@968") +#pragma comment(linker, "/EXPORT:RtlInstallFunctionTableCallback=ntdll.RtlInstallFunctionTableCallback,@969") +#pragma comment(linker, "/EXPORT:RtlInt64ToUnicodeString=ntdll.RtlInt64ToUnicodeString,@970") +#pragma comment(linker, "/EXPORT:RtlIntegerToChar=ntdll.RtlIntegerToChar,@971") +#pragma comment(linker, "/EXPORT:RtlIntegerToUnicodeString=ntdll.RtlIntegerToUnicodeString,@972") +#pragma comment(linker, "/EXPORT:RtlInterlockedClearBitRun=ntdll.RtlInterlockedClearBitRun,@973") +#pragma comment(linker, "/EXPORT:RtlInterlockedFlushSList=ntdll.RtlInterlockedFlushSList,@974") +#pragma comment(linker, "/EXPORT:RtlInterlockedPopEntrySList=ntdll.RtlInterlockedPopEntrySList,@975") +#pragma comment(linker, "/EXPORT:RtlInterlockedPushEntrySList=ntdll.RtlInterlockedPushEntrySList,@976") +#pragma comment(linker, "/EXPORT:RtlInterlockedPushListSList=ntdll.RtlInterlockedPushListSList,@977") +#pragma comment(linker, "/EXPORT:RtlInterlockedSetBitRun=ntdll.RtlInterlockedSetBitRun,@978") +#pragma comment(linker, "/EXPORT:RtlIoDecodeMemIoResource=ntdll.RtlIoDecodeMemIoResource,@979") +#pragma comment(linker, "/EXPORT:RtlIoEncodeMemIoResource=ntdll.RtlIoEncodeMemIoResource,@980") +#pragma comment(linker, "/EXPORT:RtlIpv4AddressToStringA=ntdll.RtlIpv4AddressToStringA,@981") +#pragma comment(linker, "/EXPORT:RtlIpv4AddressToStringExA=ntdll.RtlIpv4AddressToStringExA,@982") +#pragma comment(linker, "/EXPORT:RtlIpv4AddressToStringExW=ntdll.RtlIpv4AddressToStringExW,@983") +#pragma comment(linker, "/EXPORT:RtlIpv4AddressToStringW=ntdll.RtlIpv4AddressToStringW,@984") +#pragma comment(linker, "/EXPORT:RtlIpv4StringToAddressA=ntdll.RtlIpv4StringToAddressA,@985") +#pragma comment(linker, "/EXPORT:RtlIpv4StringToAddressExA=ntdll.RtlIpv4StringToAddressExA,@986") +#pragma comment(linker, "/EXPORT:RtlIpv4StringToAddressExW=ntdll.RtlIpv4StringToAddressExW,@987") +#pragma comment(linker, "/EXPORT:RtlIpv4StringToAddressW=ntdll.RtlIpv4StringToAddressW,@988") +#pragma comment(linker, "/EXPORT:RtlIpv6AddressToStringA=ntdll.RtlIpv6AddressToStringA,@989") +#pragma comment(linker, "/EXPORT:RtlIpv6AddressToStringExA=ntdll.RtlIpv6AddressToStringExA,@990") +#pragma comment(linker, "/EXPORT:RtlIpv6AddressToStringExW=ntdll.RtlIpv6AddressToStringExW,@991") +#pragma comment(linker, "/EXPORT:RtlIpv6AddressToStringW=ntdll.RtlIpv6AddressToStringW,@992") +#pragma comment(linker, "/EXPORT:RtlIpv6StringToAddressA=ntdll.RtlIpv6StringToAddressA,@993") +#pragma comment(linker, "/EXPORT:RtlIpv6StringToAddressExA=ntdll.RtlIpv6StringToAddressExA,@994") +#pragma comment(linker, "/EXPORT:RtlIpv6StringToAddressExW=ntdll.RtlIpv6StringToAddressExW,@995") +#pragma comment(linker, "/EXPORT:RtlIpv6StringToAddressW=ntdll.RtlIpv6StringToAddressW,@996") +#pragma comment(linker, "/EXPORT:RtlIsActivationContextActive=ntdll.RtlIsActivationContextActive,@997") +#pragma comment(linker, "/EXPORT:RtlIsCriticalSectionLocked=ntdll.RtlIsCriticalSectionLocked,@998") +#pragma comment(linker, "/EXPORT:RtlIsCriticalSectionLockedByThread=ntdll.RtlIsCriticalSectionLockedByThread,@999") +#pragma comment(linker, "/EXPORT:RtlIsCurrentThreadAttachExempt=ntdll.RtlIsCurrentThreadAttachExempt,@1000") +#pragma comment(linker, "/EXPORT:RtlIsDosDeviceName_U=ntdll.RtlIsDosDeviceName_U,@1001") +#pragma comment(linker, "/EXPORT:RtlIsGenericTableEmpty=ntdll.RtlIsGenericTableEmpty,@1002") +#pragma comment(linker, "/EXPORT:RtlIsGenericTableEmptyAvl=ntdll.RtlIsGenericTableEmptyAvl,@1003") +#pragma comment(linker, "/EXPORT:RtlIsNameInExpression=ntdll.RtlIsNameInExpression,@1004") +#pragma comment(linker, "/EXPORT:RtlIsNameLegalDOS8Dot3=ntdll.RtlIsNameLegalDOS8Dot3,@1005") +#pragma comment(linker, "/EXPORT:RtlIsNormalizedString=ntdll.RtlIsNormalizedString,@1006") +#pragma comment(linker, "/EXPORT:RtlIsTextUnicode=ntdll.RtlIsTextUnicode,@1007") +#pragma comment(linker, "/EXPORT:RtlIsThreadWithinLoaderCallout=ntdll.RtlIsThreadWithinLoaderCallout,@1008") +#pragma comment(linker, "/EXPORT:RtlIsValidHandle=ntdll.RtlIsValidHandle,@1009") +#pragma comment(linker, "/EXPORT:RtlIsValidIndexHandle=ntdll.RtlIsValidIndexHandle,@1010") +#pragma comment(linker, "/EXPORT:RtlIsValidLocaleName=ntdll.RtlIsValidLocaleName,@1011") +#pragma comment(linker, "/EXPORT:RtlKnownExceptionFilter=ntdll.RtlKnownExceptionFilter,@1012") +#pragma comment(linker, "/EXPORT:RtlLCIDToCultureName=ntdll.RtlLCIDToCultureName,@1013") +#pragma comment(linker, "/EXPORT:RtlLargeIntegerToChar=ntdll.RtlLargeIntegerToChar,@1014") +#pragma comment(linker, "/EXPORT:RtlLcidToLocaleName=ntdll.RtlLcidToLocaleName,@1015") +#pragma comment(linker, "/EXPORT:RtlLeaveCriticalSection=ntdll.RtlLeaveCriticalSection,@1016") +#pragma comment(linker, "/EXPORT:RtlLengthRequiredSid=ntdll.RtlLengthRequiredSid,@1017") +#pragma comment(linker, "/EXPORT:RtlLengthSecurityDescriptor=ntdll.RtlLengthSecurityDescriptor,@1018") +#pragma comment(linker, "/EXPORT:RtlLengthSid=ntdll.RtlLengthSid,@1019") +#pragma comment(linker, "/EXPORT:RtlLoadString=ntdll.RtlLoadString,@1020") +#pragma comment(linker, "/EXPORT:RtlLocalTimeToSystemTime=ntdll.RtlLocalTimeToSystemTime,@1021") +#pragma comment(linker, "/EXPORT:RtlLocaleNameToLcid=ntdll.RtlLocaleNameToLcid,@1022") +#pragma comment(linker, "/EXPORT:RtlLocateExtendedFeature=ntdll.RtlLocateExtendedFeature,@1023") +#pragma comment(linker, "/EXPORT:RtlLocateLegacyContext=ntdll.RtlLocateLegacyContext,@1024") +#pragma comment(linker, "/EXPORT:RtlLockBootStatusData=ntdll.RtlLockBootStatusData,@1025") +#pragma comment(linker, "/EXPORT:RtlLockCurrentThread=ntdll.RtlLockCurrentThread,@1026") +#pragma comment(linker, "/EXPORT:RtlLockHeap=ntdll.RtlLockHeap,@1027") +#pragma comment(linker, "/EXPORT:RtlLockMemoryBlockLookaside=ntdll.RtlLockMemoryBlockLookaside,@1028") +#pragma comment(linker, "/EXPORT:RtlLockMemoryStreamRegion=ntdll.RtlLockMemoryStreamRegion,@1029") +#pragma comment(linker, "/EXPORT:RtlLockMemoryZone=ntdll.RtlLockMemoryZone,@1030") +#pragma comment(linker, "/EXPORT:RtlLockModuleSection=ntdll.RtlLockModuleSection,@1031") +#pragma comment(linker, "/EXPORT:RtlLogStackBackTrace=ntdll.RtlLogStackBackTrace,@1032") +#pragma comment(linker, "/EXPORT:RtlLookupAtomInAtomTable=ntdll.RtlLookupAtomInAtomTable,@1033") +#pragma comment(linker, "/EXPORT:RtlLookupElementGenericTable=ntdll.RtlLookupElementGenericTable,@1034") +#pragma comment(linker, "/EXPORT:RtlLookupElementGenericTableAvl=ntdll.RtlLookupElementGenericTableAvl,@1035") +#pragma comment(linker, "/EXPORT:RtlLookupElementGenericTableFull=ntdll.RtlLookupElementGenericTableFull,@1036") +#pragma comment(linker, "/EXPORT:RtlLookupElementGenericTableFullAvl=ntdll.RtlLookupElementGenericTableFullAvl,@1037") +#pragma comment(linker, "/EXPORT:RtlLookupEntryHashTable=ntdll.RtlLookupEntryHashTable,@1038") +#pragma comment(linker, "/EXPORT:RtlLookupFunctionEntry=ntdll.RtlLookupFunctionEntry,@1039") +#pragma comment(linker, "/EXPORT:RtlLookupFunctionTable=ntdll.RtlLookupFunctionTable,@1040") +#pragma comment(linker, "/EXPORT:RtlMakeSelfRelativeSD=ntdll.RtlMakeSelfRelativeSD,@1041") +#pragma comment(linker, "/EXPORT:RtlMapGenericMask=ntdll.RtlMapGenericMask,@1042") +#pragma comment(linker, "/EXPORT:RtlMapSecurityErrorToNtStatus=ntdll.RtlMapSecurityErrorToNtStatus,@1043") +#pragma comment(linker, "/EXPORT:RtlMoveMemory=ntdll.RtlMoveMemory,@1044") +#pragma comment(linker, "/EXPORT:RtlMultiAppendUnicodeStringBuffer=ntdll.RtlMultiAppendUnicodeStringBuffer,@1045") +#pragma comment(linker, "/EXPORT:RtlMultiByteToUnicodeN=ntdll.RtlMultiByteToUnicodeN,@1046") +#pragma comment(linker, "/EXPORT:RtlMultiByteToUnicodeSize=ntdll.RtlMultiByteToUnicodeSize,@1047") +#pragma comment(linker, "/EXPORT:RtlMultipleAllocateHeap=ntdll.RtlMultipleAllocateHeap,@1048") +#pragma comment(linker, "/EXPORT:RtlMultipleFreeHeap=ntdll.RtlMultipleFreeHeap,@1049") +#pragma comment(linker, "/EXPORT:RtlNewInstanceSecurityObject=ntdll.RtlNewInstanceSecurityObject,@1050") +#pragma comment(linker, "/EXPORT:RtlNewSecurityGrantedAccess=ntdll.RtlNewSecurityGrantedAccess,@1051") +#pragma comment(linker, "/EXPORT:RtlNewSecurityObject=ntdll.RtlNewSecurityObject,@1052") +#pragma comment(linker, "/EXPORT:RtlNewSecurityObjectEx=ntdll.RtlNewSecurityObjectEx,@1053") +#pragma comment(linker, "/EXPORT:RtlNewSecurityObjectWithMultipleInheritance=ntdll.RtlNewSecurityObjectWithMultipleInheritance,@1054") +#pragma comment(linker, "/EXPORT:RtlNormalizeProcessParams=ntdll.RtlNormalizeProcessParams,@1055") +#pragma comment(linker, "/EXPORT:RtlNormalizeString=ntdll.RtlNormalizeString,@1056") +#pragma comment(linker, "/EXPORT:RtlNtPathNameToDosPathName=ntdll.RtlNtPathNameToDosPathName,@1057") +#pragma comment(linker, "/EXPORT:RtlNtStatusToDosError=ntdll.RtlNtStatusToDosError,@1058") +#pragma comment(linker, "/EXPORT:RtlNtStatusToDosErrorNoTeb=ntdll.RtlNtStatusToDosErrorNoTeb,@1059") +#pragma comment(linker, "/EXPORT:RtlNtdllName=ntdll.RtlNtdllName,@1060") +#pragma comment(linker, "/EXPORT:RtlNumberGenericTableElements=ntdll.RtlNumberGenericTableElements,@1061") +#pragma comment(linker, "/EXPORT:RtlNumberGenericTableElementsAvl=ntdll.RtlNumberGenericTableElementsAvl,@1062") +#pragma comment(linker, "/EXPORT:RtlNumberOfClearBits=ntdll.RtlNumberOfClearBits,@1063") +#pragma comment(linker, "/EXPORT:RtlNumberOfSetBits=ntdll.RtlNumberOfSetBits,@1064") +#pragma comment(linker, "/EXPORT:RtlNumberOfSetBitsUlongPtr=ntdll.RtlNumberOfSetBitsUlongPtr,@1065") +#pragma comment(linker, "/EXPORT:RtlOemStringToUnicodeSize=ntdll.RtlOemStringToUnicodeSize,@1066") +#pragma comment(linker, "/EXPORT:RtlOemStringToUnicodeString=ntdll.RtlOemStringToUnicodeString,@1067") +#pragma comment(linker, "/EXPORT:RtlOemToUnicodeN=ntdll.RtlOemToUnicodeN,@1068") +#pragma comment(linker, "/EXPORT:RtlOpenCurrentUser=ntdll.RtlOpenCurrentUser,@1069") +#pragma comment(linker, "/EXPORT:RtlOwnerAcesPresent=ntdll.RtlOwnerAcesPresent,@1070") +#pragma comment(linker, "/EXPORT:RtlPcToFileHeader=ntdll.RtlPcToFileHeader,@1071") +#pragma comment(linker, "/EXPORT:RtlPinAtomInAtomTable=ntdll.RtlPinAtomInAtomTable,@1072") +#pragma comment(linker, "/EXPORT:RtlPopFrame=ntdll.RtlPopFrame,@1073") +#pragma comment(linker, "/EXPORT:RtlPrefixString=ntdll.RtlPrefixString,@1074") +#pragma comment(linker, "/EXPORT:RtlPrefixUnicodeString=ntdll.RtlPrefixUnicodeString,@1075") +#pragma comment(linker, "/EXPORT:RtlPrepareForProcessCloning=ntdll.RtlPrepareForProcessCloning,@1076") +#pragma comment(linker, "/EXPORT:RtlProcessFlsData=ntdll.RtlProcessFlsData,@1077") +#pragma comment(linker, "/EXPORT:RtlProtectHeap=ntdll.RtlProtectHeap,@1078") +#pragma comment(linker, "/EXPORT:RtlPushFrame=ntdll.RtlPushFrame,@1079") +#pragma comment(linker, "/EXPORT:RtlQueryActivationContextApplicationSettings=ntdll.RtlQueryActivationContextApplicationSettings,@1080") +#pragma comment(linker, "/EXPORT:RtlQueryAtomInAtomTable=ntdll.RtlQueryAtomInAtomTable,@1081") +#pragma comment(linker, "/EXPORT:RtlQueryCriticalSectionOwner=ntdll.RtlQueryCriticalSectionOwner,@1082") +#pragma comment(linker, "/EXPORT:RtlQueryDepthSList=ntdll.RtlQueryDepthSList,@1083") +#pragma comment(linker, "/EXPORT:RtlQueryDynamicTimeZoneInformation=ntdll.RtlQueryDynamicTimeZoneInformation,@1084") +#pragma comment(linker, "/EXPORT:RtlQueryElevationFlags=ntdll.RtlQueryElevationFlags,@1085") +#pragma comment(linker, "/EXPORT:RtlQueryEnvironmentVariable=ntdll.RtlQueryEnvironmentVariable,@1086") +#pragma comment(linker, "/EXPORT:RtlQueryEnvironmentVariable_U=ntdll.RtlQueryEnvironmentVariable_U,@1087") +#pragma comment(linker, "/EXPORT:RtlQueryHeapInformation=ntdll.RtlQueryHeapInformation,@1088") +#pragma comment(linker, "/EXPORT:RtlQueryInformationAcl=ntdll.RtlQueryInformationAcl,@1089") +#pragma comment(linker, "/EXPORT:RtlQueryInformationActivationContext=ntdll.RtlQueryInformationActivationContext,@1090") +#pragma comment(linker, "/EXPORT:RtlQueryInformationActiveActivationContext=ntdll.RtlQueryInformationActiveActivationContext,@1091") +#pragma comment(linker, "/EXPORT:RtlQueryInterfaceMemoryStream=ntdll.RtlQueryInterfaceMemoryStream,@1092") +#pragma comment(linker, "/EXPORT:RtlQueryModuleInformation=ntdll.RtlQueryModuleInformation,@1093") +#pragma comment(linker, "/EXPORT:RtlQueryPerformanceCounter=ntdll.RtlQueryPerformanceCounter,@1094") +#pragma comment(linker, "/EXPORT:RtlQueryPerformanceFrequency=ntdll.RtlQueryPerformanceFrequency,@1095") +#pragma comment(linker, "/EXPORT:RtlQueryProcessBackTraceInformation=ntdll.RtlQueryProcessBackTraceInformation,@1096") +#pragma comment(linker, "/EXPORT:RtlQueryProcessDebugInformation=ntdll.RtlQueryProcessDebugInformation,@1097") +#pragma comment(linker, "/EXPORT:RtlQueryProcessHeapInformation=ntdll.RtlQueryProcessHeapInformation,@1098") +#pragma comment(linker, "/EXPORT:RtlQueryProcessLockInformation=ntdll.RtlQueryProcessLockInformation,@1099") +#pragma comment(linker, "/EXPORT:RtlQueryRegistryValues=ntdll.RtlQueryRegistryValues,@1100") +#pragma comment(linker, "/EXPORT:RtlQuerySecurityObject=ntdll.RtlQuerySecurityObject,@1101") +#pragma comment(linker, "/EXPORT:RtlQueryTagHeap=ntdll.RtlQueryTagHeap,@1102") +#pragma comment(linker, "/EXPORT:RtlQueryThreadProfiling=ntdll.RtlQueryThreadProfiling,@1103") +#pragma comment(linker, "/EXPORT:RtlQueryTimeZoneInformation=ntdll.RtlQueryTimeZoneInformation,@1104") +#pragma comment(linker, "/EXPORT:RtlQueryUmsThreadInformation=ntdll.RtlQueryUmsThreadInformation,@1105") +#pragma comment(linker, "/EXPORT:RtlQueueApcWow64Thread=ntdll.RtlQueueApcWow64Thread,@1106") +#pragma comment(linker, "/EXPORT:RtlQueueWorkItem=ntdll.RtlQueueWorkItem,@1107") +#pragma comment(linker, "/EXPORT:RtlRaiseException=ntdll.RtlRaiseException,@1108") +#pragma comment(linker, "/EXPORT:RtlRaiseStatus=ntdll.RtlRaiseStatus,@1109") +#pragma comment(linker, "/EXPORT:RtlRandom=ntdll.RtlRandom,@1110") +#pragma comment(linker, "/EXPORT:RtlRandomEx=ntdll.RtlRandomEx,@1111") +#pragma comment(linker, "/EXPORT:RtlReAllocateHeap=ntdll.RtlReAllocateHeap,@1112") +#pragma comment(linker, "/EXPORT:RtlReadMemoryStream=ntdll.RtlReadMemoryStream,@1113") +#pragma comment(linker, "/EXPORT:RtlReadOutOfProcessMemoryStream=ntdll.RtlReadOutOfProcessMemoryStream,@1114") +#pragma comment(linker, "/EXPORT:RtlReadThreadProfilingData=ntdll.RtlReadThreadProfilingData,@1115") +#pragma comment(linker, "/EXPORT:RtlRealPredecessor=ntdll.RtlRealPredecessor,@1116") +#pragma comment(linker, "/EXPORT:RtlRealSuccessor=ntdll.RtlRealSuccessor,@1117") +#pragma comment(linker, "/EXPORT:RtlRegisterSecureMemoryCacheCallback=ntdll.RtlRegisterSecureMemoryCacheCallback,@1118") +#pragma comment(linker, "/EXPORT:RtlRegisterThreadWithCsrss=ntdll.RtlRegisterThreadWithCsrss,@1119") +#pragma comment(linker, "/EXPORT:RtlRegisterWait=ntdll.RtlRegisterWait,@1120") +#pragma comment(linker, "/EXPORT:RtlReleaseActivationContext=ntdll.RtlReleaseActivationContext,@1121") +#pragma comment(linker, "/EXPORT:RtlReleaseMemoryStream=ntdll.RtlReleaseMemoryStream,@1122") +#pragma comment(linker, "/EXPORT:RtlReleasePebLock=ntdll.RtlReleasePebLock,@1123") +#pragma comment(linker, "/EXPORT:RtlReleasePrivilege=ntdll.RtlReleasePrivilege,@1124") +#pragma comment(linker, "/EXPORT:RtlReleaseRelativeName=ntdll.RtlReleaseRelativeName,@1125") +#pragma comment(linker, "/EXPORT:RtlReleaseResource=ntdll.RtlReleaseResource,@1126") +#pragma comment(linker, "/EXPORT:RtlReleaseSRWLockExclusive=ntdll.RtlReleaseSRWLockExclusive,@1127") +#pragma comment(linker, "/EXPORT:RtlReleaseSRWLockShared=ntdll.RtlReleaseSRWLockShared,@1128") +#pragma comment(linker, "/EXPORT:RtlRemoteCall=ntdll.RtlRemoteCall,@1129") +#pragma comment(linker, "/EXPORT:RtlRemoveEntryHashTable=ntdll.RtlRemoveEntryHashTable,@1130") +#pragma comment(linker, "/EXPORT:RtlRemovePrivileges=ntdll.RtlRemovePrivileges,@1131") +#pragma comment(linker, "/EXPORT:RtlRemoveVectoredContinueHandler=ntdll.RtlRemoveVectoredContinueHandler,@1132") +#pragma comment(linker, "/EXPORT:RtlRemoveVectoredExceptionHandler=ntdll.RtlRemoveVectoredExceptionHandler,@1133") +#pragma comment(linker, "/EXPORT:RtlReplaceSidInSd=ntdll.RtlReplaceSidInSd,@1134") +#pragma comment(linker, "/EXPORT:RtlReportException=ntdll.RtlReportException,@1135") +#pragma comment(linker, "/EXPORT:RtlReportSilentProcessExit=ntdll.RtlReportSilentProcessExit,@1136") +#pragma comment(linker, "/EXPORT:RtlReportSqmEscalation=ntdll.RtlReportSqmEscalation,@1137") +#pragma comment(linker, "/EXPORT:RtlResetMemoryBlockLookaside=ntdll.RtlResetMemoryBlockLookaside,@1138") +#pragma comment(linker, "/EXPORT:RtlResetMemoryZone=ntdll.RtlResetMemoryZone,@1139") +#pragma comment(linker, "/EXPORT:RtlResetRtlTranslations=ntdll.RtlResetRtlTranslations,@1140") +#pragma comment(linker, "/EXPORT:RtlRestoreContext=ntdll.RtlRestoreContext,@1141") +#pragma comment(linker, "/EXPORT:RtlRestoreLastWin32Error=ntdll.RtlRestoreLastWin32Error,@1142") +#pragma comment(linker, "/EXPORT:RtlRetrieveNtUserPfn=ntdll.RtlRetrieveNtUserPfn,@1143") +#pragma comment(linker, "/EXPORT:RtlRevertMemoryStream=ntdll.RtlRevertMemoryStream,@1144") +#pragma comment(linker, "/EXPORT:RtlRunDecodeUnicodeString=ntdll.RtlRunDecodeUnicodeString,@1145") +#pragma comment(linker, "/EXPORT:RtlRunEncodeUnicodeString=ntdll.RtlRunEncodeUnicodeString,@1146") +#pragma comment(linker, "/EXPORT:RtlRunOnceBeginInitialize=ntdll.RtlRunOnceBeginInitialize,@1147") +#pragma comment(linker, "/EXPORT:RtlRunOnceComplete=ntdll.RtlRunOnceComplete,@1148") +#pragma comment(linker, "/EXPORT:RtlRunOnceExecuteOnce=ntdll.RtlRunOnceExecuteOnce,@1149") +#pragma comment(linker, "/EXPORT:RtlRunOnceInitialize=ntdll.RtlRunOnceInitialize,@1150") +#pragma comment(linker, "/EXPORT:RtlSecondsSince1970ToTime=ntdll.RtlSecondsSince1970ToTime,@1151") +#pragma comment(linker, "/EXPORT:RtlSecondsSince1980ToTime=ntdll.RtlSecondsSince1980ToTime,@1152") +#pragma comment(linker, "/EXPORT:RtlSeekMemoryStream=ntdll.RtlSeekMemoryStream,@1153") +#pragma comment(linker, "/EXPORT:RtlSelfRelativeToAbsoluteSD=ntdll.RtlSelfRelativeToAbsoluteSD,@1154") +#pragma comment(linker, "/EXPORT:RtlSelfRelativeToAbsoluteSD2=ntdll.RtlSelfRelativeToAbsoluteSD2,@1155") +#pragma comment(linker, "/EXPORT:RtlSendMsgToSm=ntdll.RtlSendMsgToSm,@1156") +#pragma comment(linker, "/EXPORT:RtlSetAllBits=ntdll.RtlSetAllBits,@1157") +#pragma comment(linker, "/EXPORT:RtlSetAttributesSecurityDescriptor=ntdll.RtlSetAttributesSecurityDescriptor,@1158") +#pragma comment(linker, "/EXPORT:RtlSetBits=ntdll.RtlSetBits,@1159") +#pragma comment(linker, "/EXPORT:RtlSetControlSecurityDescriptor=ntdll.RtlSetControlSecurityDescriptor,@1160") +#pragma comment(linker, "/EXPORT:RtlSetCriticalSectionSpinCount=ntdll.RtlSetCriticalSectionSpinCount,@1161") +#pragma comment(linker, "/EXPORT:RtlSetCurrentDirectory_U=ntdll.RtlSetCurrentDirectory_U,@1162") +#pragma comment(linker, "/EXPORT:RtlSetCurrentEnvironment=ntdll.RtlSetCurrentEnvironment,@1163") +#pragma comment(linker, "/EXPORT:RtlSetCurrentTransaction=ntdll.RtlSetCurrentTransaction,@1164") +#pragma comment(linker, "/EXPORT:RtlSetDaclSecurityDescriptor=ntdll.RtlSetDaclSecurityDescriptor,@1165") +#pragma comment(linker, "/EXPORT:RtlSetDynamicTimeZoneInformation=ntdll.RtlSetDynamicTimeZoneInformation,@1166") +#pragma comment(linker, "/EXPORT:RtlSetEnvironmentStrings=ntdll.RtlSetEnvironmentStrings,@1167") +#pragma comment(linker, "/EXPORT:RtlSetEnvironmentVar=ntdll.RtlSetEnvironmentVar,@1168") +#pragma comment(linker, "/EXPORT:RtlSetEnvironmentVariable=ntdll.RtlSetEnvironmentVariable,@1169") +#pragma comment(linker, "/EXPORT:RtlSetExtendedFeaturesMask=ntdll.RtlSetExtendedFeaturesMask,@1170") +#pragma comment(linker, "/EXPORT:RtlSetGroupSecurityDescriptor=ntdll.RtlSetGroupSecurityDescriptor,@1171") +#pragma comment(linker, "/EXPORT:RtlSetHeapInformation=ntdll.RtlSetHeapInformation,@1172") +#pragma comment(linker, "/EXPORT:RtlSetInformationAcl=ntdll.RtlSetInformationAcl,@1173") +#pragma comment(linker, "/EXPORT:RtlSetIoCompletionCallback=ntdll.RtlSetIoCompletionCallback,@1174") +#pragma comment(linker, "/EXPORT:RtlSetLastWin32Error=ntdll.RtlSetLastWin32Error,@1175") +#pragma comment(linker, "/EXPORT:RtlSetLastWin32ErrorAndNtStatusFromNtStatus=ntdll.RtlSetLastWin32ErrorAndNtStatusFromNtStatus,@1176") +#pragma comment(linker, "/EXPORT:RtlSetMemoryStreamSize=ntdll.RtlSetMemoryStreamSize,@1177") +#pragma comment(linker, "/EXPORT:RtlSetOwnerSecurityDescriptor=ntdll.RtlSetOwnerSecurityDescriptor,@1178") +#pragma comment(linker, "/EXPORT:RtlSetProcessDebugInformation=ntdll.RtlSetProcessDebugInformation,@1179") +#pragma comment(linker, "/EXPORT:RtlSetProcessIsCritical=ntdll.RtlSetProcessIsCritical,@1180") +#pragma comment(linker, "/EXPORT:RtlSetProcessPreferredUILanguages=ntdll.RtlSetProcessPreferredUILanguages,@1181") +#pragma comment(linker, "/EXPORT:RtlSetSaclSecurityDescriptor=ntdll.RtlSetSaclSecurityDescriptor,@1182") +#pragma comment(linker, "/EXPORT:RtlSetSecurityDescriptorRMControl=ntdll.RtlSetSecurityDescriptorRMControl,@1183") +#pragma comment(linker, "/EXPORT:RtlSetSecurityObject=ntdll.RtlSetSecurityObject,@1184") +#pragma comment(linker, "/EXPORT:RtlSetSecurityObjectEx=ntdll.RtlSetSecurityObjectEx,@1185") +#pragma comment(linker, "/EXPORT:RtlSetThreadErrorMode=ntdll.RtlSetThreadErrorMode,@1186") +#pragma comment(linker, "/EXPORT:RtlSetThreadIsCritical=ntdll.RtlSetThreadIsCritical,@1187") +#pragma comment(linker, "/EXPORT:RtlSetThreadPoolStartFunc=ntdll.RtlSetThreadPoolStartFunc,@1188") +#pragma comment(linker, "/EXPORT:RtlSetThreadPreferredUILanguages=ntdll.RtlSetThreadPreferredUILanguages,@1189") +#pragma comment(linker, "/EXPORT:RtlSetTimeZoneInformation=ntdll.RtlSetTimeZoneInformation,@1190") +#pragma comment(linker, "/EXPORT:RtlSetTimer=ntdll.RtlSetTimer,@1191") +#pragma comment(linker, "/EXPORT:RtlSetUmsThreadInformation=ntdll.RtlSetUmsThreadInformation,@1192") +#pragma comment(linker, "/EXPORT:RtlSetUnhandledExceptionFilter=ntdll.RtlSetUnhandledExceptionFilter,@1193") +#pragma comment(linker, "/EXPORT:RtlSetUserFlagsHeap=ntdll.RtlSetUserFlagsHeap,@1194") +#pragma comment(linker, "/EXPORT:RtlSetUserValueHeap=ntdll.RtlSetUserValueHeap,@1195") +#pragma comment(linker, "/EXPORT:RtlSidDominates=ntdll.RtlSidDominates,@1196") +#pragma comment(linker, "/EXPORT:RtlSidEqualLevel=ntdll.RtlSidEqualLevel,@1197") +#pragma comment(linker, "/EXPORT:RtlSidHashInitialize=ntdll.RtlSidHashInitialize,@1198") +#pragma comment(linker, "/EXPORT:RtlSidHashLookup=ntdll.RtlSidHashLookup,@1199") +#pragma comment(linker, "/EXPORT:RtlSidIsHigherLevel=ntdll.RtlSidIsHigherLevel,@1200") +#pragma comment(linker, "/EXPORT:RtlSizeHeap=ntdll.RtlSizeHeap,@1201") +#pragma comment(linker, "/EXPORT:RtlSleepConditionVariableCS=ntdll.RtlSleepConditionVariableCS,@1202") +#pragma comment(linker, "/EXPORT:RtlSleepConditionVariableSRW=ntdll.RtlSleepConditionVariableSRW,@1203") +#pragma comment(linker, "/EXPORT:RtlSplay=ntdll.RtlSplay,@1204") +#pragma comment(linker, "/EXPORT:RtlStartRXact=ntdll.RtlStartRXact,@1205") +#pragma comment(linker, "/EXPORT:RtlStatMemoryStream=ntdll.RtlStatMemoryStream,@1206") +#pragma comment(linker, "/EXPORT:RtlStringFromGUID=ntdll.RtlStringFromGUID,@1207") +#pragma comment(linker, "/EXPORT:RtlSubAuthorityCountSid=ntdll.RtlSubAuthorityCountSid,@1208") +#pragma comment(linker, "/EXPORT:RtlSubAuthoritySid=ntdll.RtlSubAuthoritySid,@1209") +#pragma comment(linker, "/EXPORT:RtlSubtreePredecessor=ntdll.RtlSubtreePredecessor,@1210") +#pragma comment(linker, "/EXPORT:RtlSubtreeSuccessor=ntdll.RtlSubtreeSuccessor,@1211") +#pragma comment(linker, "/EXPORT:RtlSystemTimeToLocalTime=ntdll.RtlSystemTimeToLocalTime,@1212") +#pragma comment(linker, "/EXPORT:RtlTestBit=ntdll.RtlTestBit,@1213") +#pragma comment(linker, "/EXPORT:RtlTimeFieldsToTime=ntdll.RtlTimeFieldsToTime,@1214") +#pragma comment(linker, "/EXPORT:RtlTimeToElapsedTimeFields=ntdll.RtlTimeToElapsedTimeFields,@1215") +#pragma comment(linker, "/EXPORT:RtlTimeToSecondsSince1970=ntdll.RtlTimeToSecondsSince1970,@1216") +#pragma comment(linker, "/EXPORT:RtlTimeToSecondsSince1980=ntdll.RtlTimeToSecondsSince1980,@1217") +#pragma comment(linker, "/EXPORT:RtlTimeToTimeFields=ntdll.RtlTimeToTimeFields,@1218") +#pragma comment(linker, "/EXPORT:RtlTraceDatabaseAdd=ntdll.RtlTraceDatabaseAdd,@1219") +#pragma comment(linker, "/EXPORT:RtlTraceDatabaseCreate=ntdll.RtlTraceDatabaseCreate,@1220") +#pragma comment(linker, "/EXPORT:RtlTraceDatabaseDestroy=ntdll.RtlTraceDatabaseDestroy,@1221") +#pragma comment(linker, "/EXPORT:RtlTraceDatabaseEnumerate=ntdll.RtlTraceDatabaseEnumerate,@1222") +#pragma comment(linker, "/EXPORT:RtlTraceDatabaseFind=ntdll.RtlTraceDatabaseFind,@1223") +#pragma comment(linker, "/EXPORT:RtlTraceDatabaseLock=ntdll.RtlTraceDatabaseLock,@1224") +#pragma comment(linker, "/EXPORT:RtlTraceDatabaseUnlock=ntdll.RtlTraceDatabaseUnlock,@1225") +#pragma comment(linker, "/EXPORT:RtlTraceDatabaseValidate=ntdll.RtlTraceDatabaseValidate,@1226") +#pragma comment(linker, "/EXPORT:RtlTryAcquirePebLock=ntdll.RtlTryAcquirePebLock,@1227") +#pragma comment(linker, "/EXPORT:RtlTryAcquireSRWLockExclusive=ntdll.RtlTryAcquireSRWLockExclusive,@1228") +#pragma comment(linker, "/EXPORT:RtlTryAcquireSRWLockShared=ntdll.RtlTryAcquireSRWLockShared,@1229") +#pragma comment(linker, "/EXPORT:RtlTryEnterCriticalSection=ntdll.RtlTryEnterCriticalSection,@1230") +#pragma comment(linker, "/EXPORT:RtlUTF8ToUnicodeN=ntdll.RtlUTF8ToUnicodeN,@1231") +#pragma comment(linker, "/EXPORT:RtlUmsThreadYield=ntdll.RtlUmsThreadYield,@1232") +#pragma comment(linker, "/EXPORT:RtlUnhandledExceptionFilter=ntdll.RtlUnhandledExceptionFilter,@1233") +#pragma comment(linker, "/EXPORT:RtlUnhandledExceptionFilter2=ntdll.RtlUnhandledExceptionFilter2,@1234") +#pragma comment(linker, "/EXPORT:RtlUnicodeStringToAnsiSize=ntdll.RtlUnicodeStringToAnsiSize,@1235") +#pragma comment(linker, "/EXPORT:RtlUnicodeStringToAnsiString=ntdll.RtlUnicodeStringToAnsiString,@1236") +#pragma comment(linker, "/EXPORT:RtlUnicodeStringToCountedOemString=ntdll.RtlUnicodeStringToCountedOemString,@1237") +#pragma comment(linker, "/EXPORT:RtlUnicodeStringToInteger=ntdll.RtlUnicodeStringToInteger,@1238") +#pragma comment(linker, "/EXPORT:RtlUnicodeStringToOemSize=ntdll.RtlUnicodeStringToOemSize,@1239") +#pragma comment(linker, "/EXPORT:RtlUnicodeStringToOemString=ntdll.RtlUnicodeStringToOemString,@1240") +#pragma comment(linker, "/EXPORT:RtlUnicodeToCustomCPN=ntdll.RtlUnicodeToCustomCPN,@1241") +#pragma comment(linker, "/EXPORT:RtlUnicodeToMultiByteN=ntdll.RtlUnicodeToMultiByteN,@1242") +#pragma comment(linker, "/EXPORT:RtlUnicodeToMultiByteSize=ntdll.RtlUnicodeToMultiByteSize,@1243") +#pragma comment(linker, "/EXPORT:RtlUnicodeToOemN=ntdll.RtlUnicodeToOemN,@1244") +#pragma comment(linker, "/EXPORT:RtlUnicodeToUTF8N=ntdll.RtlUnicodeToUTF8N,@1245") +#pragma comment(linker, "/EXPORT:RtlUniform=ntdll.RtlUniform,@1246") +#pragma comment(linker, "/EXPORT:RtlUnlockBootStatusData=ntdll.RtlUnlockBootStatusData,@1247") +#pragma comment(linker, "/EXPORT:RtlUnlockCurrentThread=ntdll.RtlUnlockCurrentThread,@1248") +#pragma comment(linker, "/EXPORT:RtlUnlockHeap=ntdll.RtlUnlockHeap,@1249") +#pragma comment(linker, "/EXPORT:RtlUnlockMemoryBlockLookaside=ntdll.RtlUnlockMemoryBlockLookaside,@1250") +#pragma comment(linker, "/EXPORT:RtlUnlockMemoryStreamRegion=ntdll.RtlUnlockMemoryStreamRegion,@1251") +#pragma comment(linker, "/EXPORT:RtlUnlockMemoryZone=ntdll.RtlUnlockMemoryZone,@1252") +#pragma comment(linker, "/EXPORT:RtlUnlockModuleSection=ntdll.RtlUnlockModuleSection,@1253") +#pragma comment(linker, "/EXPORT:RtlUnwind=ntdll.RtlUnwind,@1254") +#pragma comment(linker, "/EXPORT:RtlUnwindEx=ntdll.RtlUnwindEx,@1255") +#pragma comment(linker, "/EXPORT:RtlUpcaseUnicodeChar=ntdll.RtlUpcaseUnicodeChar,@1256") +#pragma comment(linker, "/EXPORT:RtlUpcaseUnicodeString=ntdll.RtlUpcaseUnicodeString,@1257") +#pragma comment(linker, "/EXPORT:RtlUpcaseUnicodeStringToAnsiString=ntdll.RtlUpcaseUnicodeStringToAnsiString,@1258") +#pragma comment(linker, "/EXPORT:RtlUpcaseUnicodeStringToCountedOemString=ntdll.RtlUpcaseUnicodeStringToCountedOemString,@1259") +#pragma comment(linker, "/EXPORT:RtlUpcaseUnicodeStringToOemString=ntdll.RtlUpcaseUnicodeStringToOemString,@1260") +#pragma comment(linker, "/EXPORT:RtlUpcaseUnicodeToCustomCPN=ntdll.RtlUpcaseUnicodeToCustomCPN,@1261") +#pragma comment(linker, "/EXPORT:RtlUpcaseUnicodeToMultiByteN=ntdll.RtlUpcaseUnicodeToMultiByteN,@1262") +#pragma comment(linker, "/EXPORT:RtlUpcaseUnicodeToOemN=ntdll.RtlUpcaseUnicodeToOemN,@1263") +#pragma comment(linker, "/EXPORT:RtlUpdateClonedCriticalSection=ntdll.RtlUpdateClonedCriticalSection,@1264") +#pragma comment(linker, "/EXPORT:RtlUpdateClonedSRWLock=ntdll.RtlUpdateClonedSRWLock,@1265") +#pragma comment(linker, "/EXPORT:RtlUpdateTimer=ntdll.RtlUpdateTimer,@1266") +#pragma comment(linker, "/EXPORT:RtlUpperChar=ntdll.RtlUpperChar,@1267") +#pragma comment(linker, "/EXPORT:RtlUpperString=ntdll.RtlUpperString,@1268") +#pragma comment(linker, "/EXPORT:RtlUserThreadStart=ntdll.RtlUserThreadStart,@1269") +#pragma comment(linker, "/EXPORT:RtlValidAcl=ntdll.RtlValidAcl,@1270") +#pragma comment(linker, "/EXPORT:RtlValidRelativeSecurityDescriptor=ntdll.RtlValidRelativeSecurityDescriptor,@1271") +#pragma comment(linker, "/EXPORT:RtlValidSecurityDescriptor=ntdll.RtlValidSecurityDescriptor,@1272") +#pragma comment(linker, "/EXPORT:RtlValidSid=ntdll.RtlValidSid,@1273") +#pragma comment(linker, "/EXPORT:RtlValidateHeap=ntdll.RtlValidateHeap,@1274") +#pragma comment(linker, "/EXPORT:RtlValidateProcessHeaps=ntdll.RtlValidateProcessHeaps,@1275") +#pragma comment(linker, "/EXPORT:RtlValidateUnicodeString=ntdll.RtlValidateUnicodeString,@1276") +#pragma comment(linker, "/EXPORT:RtlVerifyVersionInfo=ntdll.RtlVerifyVersionInfo,@1277") +#pragma comment(linker, "/EXPORT:RtlVirtualUnwind=ntdll.RtlVirtualUnwind,@1278") +#pragma comment(linker, "/EXPORT:RtlWakeAllConditionVariable=ntdll.RtlWakeAllConditionVariable,@1279") +#pragma comment(linker, "/EXPORT:RtlWakeConditionVariable=ntdll.RtlWakeConditionVariable,@1280") +#pragma comment(linker, "/EXPORT:RtlWalkFrameChain=ntdll.RtlWalkFrameChain,@1281") +#pragma comment(linker, "/EXPORT:RtlWalkHeap=ntdll.RtlWalkHeap,@1282") +#pragma comment(linker, "/EXPORT:RtlWeaklyEnumerateEntryHashTable=ntdll.RtlWeaklyEnumerateEntryHashTable,@1283") +#pragma comment(linker, "/EXPORT:RtlWerpReportException=ntdll.RtlWerpReportException,@1284") +#pragma comment(linker, "/EXPORT:RtlWow64CallFunction64=ntdll.RtlWow64CallFunction64,@1285") +#pragma comment(linker, "/EXPORT:RtlWow64EnableFsRedirection=ntdll.RtlWow64EnableFsRedirection,@1286") +#pragma comment(linker, "/EXPORT:RtlWow64EnableFsRedirectionEx=ntdll.RtlWow64EnableFsRedirectionEx,@1287") +#pragma comment(linker, "/EXPORT:RtlWow64GetThreadContext=ntdll.RtlWow64GetThreadContext,@1288") +#pragma comment(linker, "/EXPORT:RtlWow64GetThreadSelectorEntry=ntdll.RtlWow64GetThreadSelectorEntry,@1289") +#pragma comment(linker, "/EXPORT:RtlWow64LogMessageInEventLogger=ntdll.RtlWow64LogMessageInEventLogger,@1290") +#pragma comment(linker, "/EXPORT:RtlWow64SetThreadContext=ntdll.RtlWow64SetThreadContext,@1291") +#pragma comment(linker, "/EXPORT:RtlWow64SuspendThread=ntdll.RtlWow64SuspendThread,@1292") +#pragma comment(linker, "/EXPORT:RtlWriteMemoryStream=ntdll.RtlWriteMemoryStream,@1293") +#pragma comment(linker, "/EXPORT:RtlWriteRegistryValue=ntdll.RtlWriteRegistryValue,@1294") +#pragma comment(linker, "/EXPORT:RtlZeroHeap=ntdll.RtlZeroHeap,@1295") +#pragma comment(linker, "/EXPORT:RtlZeroMemory=ntdll.RtlZeroMemory,@1296") +#pragma comment(linker, "/EXPORT:RtlZombifyActivationContext=ntdll.RtlZombifyActivationContext,@1297") +#pragma comment(linker, "/EXPORT:RtlpApplyLengthFunction=ntdll.RtlpApplyLengthFunction,@1298") +#pragma comment(linker, "/EXPORT:RtlpCheckDynamicTimeZoneInformation=ntdll.RtlpCheckDynamicTimeZoneInformation,@1299") +#pragma comment(linker, "/EXPORT:RtlpCleanupRegistryKeys=ntdll.RtlpCleanupRegistryKeys,@1300") +#pragma comment(linker, "/EXPORT:RtlpConvertCultureNamesToLCIDs=ntdll.RtlpConvertCultureNamesToLCIDs,@1301") +#pragma comment(linker, "/EXPORT:RtlpConvertLCIDsToCultureNames=ntdll.RtlpConvertLCIDsToCultureNames,@1302") +#pragma comment(linker, "/EXPORT:RtlpCreateProcessRegistryInfo=ntdll.RtlpCreateProcessRegistryInfo,@1303") +#pragma comment(linker, "/EXPORT:RtlpEnsureBufferSize=ntdll.RtlpEnsureBufferSize,@1304") +#pragma comment(linker, "/EXPORT:RtlpExecuteUmsThread=ntdll.RtlpExecuteUmsThread,@1305") +#pragma comment(linker, "/EXPORT:RtlpGetLCIDFromLangInfoNode=ntdll.RtlpGetLCIDFromLangInfoNode,@1306") +#pragma comment(linker, "/EXPORT:RtlpGetNameFromLangInfoNode=ntdll.RtlpGetNameFromLangInfoNode,@1307") +#pragma comment(linker, "/EXPORT:RtlpGetSystemDefaultUILanguage=ntdll.RtlpGetSystemDefaultUILanguage,@1308") +#pragma comment(linker, "/EXPORT:RtlpGetUserOrMachineUILanguage4NLS=ntdll.RtlpGetUserOrMachineUILanguage4NLS,@1309") +#pragma comment(linker, "/EXPORT:RtlpInitializeLangRegistryInfo=ntdll.RtlpInitializeLangRegistryInfo,@1310") +#pragma comment(linker, "/EXPORT:RtlpIsQualifiedLanguage=ntdll.RtlpIsQualifiedLanguage,@1311") +#pragma comment(linker, "/EXPORT:RtlpLoadMachineUIByPolicy=ntdll.RtlpLoadMachineUIByPolicy,@1312") +#pragma comment(linker, "/EXPORT:RtlpLoadUserUIByPolicy=ntdll.RtlpLoadUserUIByPolicy,@1313") +#pragma comment(linker, "/EXPORT:RtlpMuiFreeLangRegistryInfo=ntdll.RtlpMuiFreeLangRegistryInfo,@1314") +#pragma comment(linker, "/EXPORT:RtlpMuiRegCreateRegistryInfo=ntdll.RtlpMuiRegCreateRegistryInfo,@1315") +#pragma comment(linker, "/EXPORT:RtlpMuiRegFreeRegistryInfo=ntdll.RtlpMuiRegFreeRegistryInfo,@1316") +#pragma comment(linker, "/EXPORT:RtlpMuiRegLoadRegistryInfo=ntdll.RtlpMuiRegLoadRegistryInfo,@1317") +#pragma comment(linker, "/EXPORT:RtlpNotOwnerCriticalSection=ntdll.RtlpNotOwnerCriticalSection,@1318") +#pragma comment(linker, "/EXPORT:RtlpNtCreateKey=ntdll.RtlpNtCreateKey,@1319") +#pragma comment(linker, "/EXPORT:RtlpNtEnumerateSubKey=ntdll.RtlpNtEnumerateSubKey,@1320") +#pragma comment(linker, "/EXPORT:RtlpNtMakeTemporaryKey=ntdll.RtlpNtMakeTemporaryKey,@1321") +#pragma comment(linker, "/EXPORT:RtlpNtOpenKey=ntdll.RtlpNtOpenKey,@1322") +#pragma comment(linker, "/EXPORT:RtlpNtQueryValueKey=ntdll.RtlpNtQueryValueKey,@1323") +#pragma comment(linker, "/EXPORT:RtlpNtSetValueKey=ntdll.RtlpNtSetValueKey,@1324") +#pragma comment(linker, "/EXPORT:RtlpQueryDefaultUILanguage=ntdll.RtlpQueryDefaultUILanguage,@1325") +#pragma comment(linker, "/EXPORT:RtlpQueryProcessDebugInformationFromWow64=ntdll.RtlpQueryProcessDebugInformationFromWow64,@1326") +#pragma comment(linker, "/EXPORT:RtlpRefreshCachedUILanguage=ntdll.RtlpRefreshCachedUILanguage,@1327") +#pragma comment(linker, "/EXPORT:RtlpSetInstallLanguage=ntdll.RtlpSetInstallLanguage,@1328") +#pragma comment(linker, "/EXPORT:RtlpSetPreferredUILanguages=ntdll.RtlpSetPreferredUILanguages,@1329") +#pragma comment(linker, "/EXPORT:RtlpSetUserPreferredUILanguages=ntdll.RtlpSetUserPreferredUILanguages,@1330") +#pragma comment(linker, "/EXPORT:RtlpUmsExecuteYieldThreadEnd=ntdll.RtlpUmsExecuteYieldThreadEnd,@1331") +#pragma comment(linker, "/EXPORT:RtlpUmsThreadYield=ntdll.RtlpUmsThreadYield,@1332") +#pragma comment(linker, "/EXPORT:RtlpUnWaitCriticalSection=ntdll.RtlpUnWaitCriticalSection,@1333") +#pragma comment(linker, "/EXPORT:RtlpVerifyAndCommitUILanguageSettings=ntdll.RtlpVerifyAndCommitUILanguageSettings,@1334") +#pragma comment(linker, "/EXPORT:RtlpWaitForCriticalSection=ntdll.RtlpWaitForCriticalSection,@1335") +#pragma comment(linker, "/EXPORT:RtlxAnsiStringToUnicodeSize=ntdll.RtlxAnsiStringToUnicodeSize,@1336") +#pragma comment(linker, "/EXPORT:RtlxOemStringToUnicodeSize=ntdll.RtlxOemStringToUnicodeSize,@1337") +#pragma comment(linker, "/EXPORT:RtlxUnicodeStringToAnsiSize=ntdll.RtlxUnicodeStringToAnsiSize,@1338") +#pragma comment(linker, "/EXPORT:RtlxUnicodeStringToOemSize=ntdll.RtlxUnicodeStringToOemSize,@1339") +#pragma comment(linker, "/EXPORT:SbExecuteProcedure=ntdll.SbExecuteProcedure,@1340") +#pragma comment(linker, "/EXPORT:SbSelectProcedure=ntdll.SbSelectProcedure,@1341") +#pragma comment(linker, "/EXPORT:ShipAssert=ntdll.ShipAssert,@1342") +#pragma comment(linker, "/EXPORT:ShipAssertGetBufferInfo=ntdll.ShipAssertGetBufferInfo,@1343") +#pragma comment(linker, "/EXPORT:ShipAssertMsgA=ntdll.ShipAssertMsgA,@1344") +#pragma comment(linker, "/EXPORT:ShipAssertMsgW=ntdll.ShipAssertMsgW,@1345") +#pragma comment(linker, "/EXPORT:TpAllocAlpcCompletion=ntdll.TpAllocAlpcCompletion,@1346") +#pragma comment(linker, "/EXPORT:TpAllocAlpcCompletionEx=ntdll.TpAllocAlpcCompletionEx,@1347") +#pragma comment(linker, "/EXPORT:TpAllocCleanupGroup=ntdll.TpAllocCleanupGroup,@1348") +#pragma comment(linker, "/EXPORT:TpAllocIoCompletion=ntdll.TpAllocIoCompletion,@1349") +#pragma comment(linker, "/EXPORT:TpAllocPool=ntdll.TpAllocPool,@1350") +#pragma comment(linker, "/EXPORT:TpAllocTimer=ntdll.TpAllocTimer,@1351") +#pragma comment(linker, "/EXPORT:TpAllocWait=ntdll.TpAllocWait,@1352") +#pragma comment(linker, "/EXPORT:TpAllocWork=ntdll.TpAllocWork,@1353") +#pragma comment(linker, "/EXPORT:TpAlpcRegisterCompletionList=ntdll.TpAlpcRegisterCompletionList,@1354") +#pragma comment(linker, "/EXPORT:TpAlpcUnregisterCompletionList=ntdll.TpAlpcUnregisterCompletionList,@1355") +#pragma comment(linker, "/EXPORT:TpCallbackIndependent=ntdll.TpCallbackIndependent,@1356") +#pragma comment(linker, "/EXPORT:TpCallbackLeaveCriticalSectionOnCompletion=ntdll.TpCallbackLeaveCriticalSectionOnCompletion,@1357") +#pragma comment(linker, "/EXPORT:TpCallbackMayRunLong=ntdll.TpCallbackMayRunLong,@1358") +#pragma comment(linker, "/EXPORT:TpCallbackReleaseMutexOnCompletion=ntdll.TpCallbackReleaseMutexOnCompletion,@1359") +#pragma comment(linker, "/EXPORT:TpCallbackReleaseSemaphoreOnCompletion=ntdll.TpCallbackReleaseSemaphoreOnCompletion,@1360") +#pragma comment(linker, "/EXPORT:TpCallbackSetEventOnCompletion=ntdll.TpCallbackSetEventOnCompletion,@1361") +#pragma comment(linker, "/EXPORT:TpCallbackUnloadDllOnCompletion=ntdll.TpCallbackUnloadDllOnCompletion,@1362") +#pragma comment(linker, "/EXPORT:TpCancelAsyncIoOperation=ntdll.TpCancelAsyncIoOperation,@1363") +#pragma comment(linker, "/EXPORT:TpCaptureCaller=ntdll.TpCaptureCaller,@1364") +#pragma comment(linker, "/EXPORT:TpCheckTerminateWorker=ntdll.TpCheckTerminateWorker,@1365") +#pragma comment(linker, "/EXPORT:TpDbgDumpHeapUsage=ntdll.TpDbgDumpHeapUsage,@1366") +#pragma comment(linker, "/EXPORT:TpDbgSetLogRoutine=ntdll.TpDbgSetLogRoutine,@1367") +#pragma comment(linker, "/EXPORT:TpDisablePoolCallbackChecks=ntdll.TpDisablePoolCallbackChecks,@1368") +#pragma comment(linker, "/EXPORT:TpDisassociateCallback=ntdll.TpDisassociateCallback,@1369") +#pragma comment(linker, "/EXPORT:TpIsTimerSet=ntdll.TpIsTimerSet,@1370") +#pragma comment(linker, "/EXPORT:TpPostWork=ntdll.TpPostWork,@1371") +#pragma comment(linker, "/EXPORT:TpQueryPoolStackInformation=ntdll.TpQueryPoolStackInformation,@1372") +#pragma comment(linker, "/EXPORT:TpReleaseAlpcCompletion=ntdll.TpReleaseAlpcCompletion,@1373") +#pragma comment(linker, "/EXPORT:TpReleaseCleanupGroup=ntdll.TpReleaseCleanupGroup,@1374") +#pragma comment(linker, "/EXPORT:TpReleaseCleanupGroupMembers=ntdll.TpReleaseCleanupGroupMembers,@1375") +#pragma comment(linker, "/EXPORT:TpReleaseIoCompletion=ntdll.TpReleaseIoCompletion,@1376") +#pragma comment(linker, "/EXPORT:TpReleasePool=ntdll.TpReleasePool,@1377") +#pragma comment(linker, "/EXPORT:TpReleaseTimer=ntdll.TpReleaseTimer,@1378") +#pragma comment(linker, "/EXPORT:TpReleaseWait=ntdll.TpReleaseWait,@1379") +#pragma comment(linker, "/EXPORT:TpReleaseWork=ntdll.TpReleaseWork,@1380") +#pragma comment(linker, "/EXPORT:TpSetDefaultPoolMaxThreads=ntdll.TpSetDefaultPoolMaxThreads,@1381") +#pragma comment(linker, "/EXPORT:TpSetDefaultPoolStackInformation=ntdll.TpSetDefaultPoolStackInformation,@1382") +#pragma comment(linker, "/EXPORT:TpSetPoolMaxThreads=ntdll.TpSetPoolMaxThreads,@1383") +#pragma comment(linker, "/EXPORT:TpSetPoolMinThreads=ntdll.TpSetPoolMinThreads,@1384") +#pragma comment(linker, "/EXPORT:TpSetPoolStackInformation=ntdll.TpSetPoolStackInformation,@1385") +#pragma comment(linker, "/EXPORT:TpSetTimer=ntdll.TpSetTimer,@1386") +#pragma comment(linker, "/EXPORT:TpSetWait=ntdll.TpSetWait,@1387") +#pragma comment(linker, "/EXPORT:TpSimpleTryPost=ntdll.TpSimpleTryPost,@1388") +#pragma comment(linker, "/EXPORT:TpStartAsyncIoOperation=ntdll.TpStartAsyncIoOperation,@1389") +#pragma comment(linker, "/EXPORT:TpWaitForAlpcCompletion=ntdll.TpWaitForAlpcCompletion,@1390") +#pragma comment(linker, "/EXPORT:TpWaitForIoCompletion=ntdll.TpWaitForIoCompletion,@1391") +#pragma comment(linker, "/EXPORT:TpWaitForTimer=ntdll.TpWaitForTimer,@1392") +#pragma comment(linker, "/EXPORT:TpWaitForWait=ntdll.TpWaitForWait,@1393") +#pragma comment(linker, "/EXPORT:TpWaitForWork=ntdll.TpWaitForWork,@1394") +#pragma comment(linker, "/EXPORT:VerSetConditionMask=ntdll.VerSetConditionMask,@1395") +#pragma comment(linker, "/EXPORT:WerReportSQMEvent=ntdll.WerReportSQMEvent,@1396") +#pragma comment(linker, "/EXPORT:WinSqmAddToAverageDWORD=ntdll.WinSqmAddToAverageDWORD,@1397") +#pragma comment(linker, "/EXPORT:WinSqmAddToStream=ntdll.WinSqmAddToStream,@1398") +#pragma comment(linker, "/EXPORT:WinSqmAddToStreamEx=ntdll.WinSqmAddToStreamEx,@1399") +#pragma comment(linker, "/EXPORT:WinSqmCheckEscalationAddToStreamEx=ntdll.WinSqmCheckEscalationAddToStreamEx,@1400") +#pragma comment(linker, "/EXPORT:WinSqmCheckEscalationSetDWORD=ntdll.WinSqmCheckEscalationSetDWORD,@1401") +#pragma comment(linker, "/EXPORT:WinSqmCheckEscalationSetDWORD64=ntdll.WinSqmCheckEscalationSetDWORD64,@1402") +#pragma comment(linker, "/EXPORT:WinSqmCheckEscalationSetString=ntdll.WinSqmCheckEscalationSetString,@1403") +#pragma comment(linker, "/EXPORT:WinSqmCommonDatapointDelete=ntdll.WinSqmCommonDatapointDelete,@1404") +#pragma comment(linker, "/EXPORT:WinSqmCommonDatapointSetDWORD=ntdll.WinSqmCommonDatapointSetDWORD,@1405") +#pragma comment(linker, "/EXPORT:WinSqmCommonDatapointSetDWORD64=ntdll.WinSqmCommonDatapointSetDWORD64,@1406") +#pragma comment(linker, "/EXPORT:WinSqmCommonDatapointSetStreamEx=ntdll.WinSqmCommonDatapointSetStreamEx,@1407") +#pragma comment(linker, "/EXPORT:WinSqmCommonDatapointSetString=ntdll.WinSqmCommonDatapointSetString,@1408") +#pragma comment(linker, "/EXPORT:WinSqmEndSession=ntdll.WinSqmEndSession,@1409") +#pragma comment(linker, "/EXPORT:WinSqmEventEnabled=ntdll.WinSqmEventEnabled,@1410") +#pragma comment(linker, "/EXPORT:WinSqmEventWrite=ntdll.WinSqmEventWrite,@1411") +#pragma comment(linker, "/EXPORT:WinSqmGetEscalationRuleStatus=ntdll.WinSqmGetEscalationRuleStatus,@1412") +#pragma comment(linker, "/EXPORT:WinSqmGetInstrumentationProperty=ntdll.WinSqmGetInstrumentationProperty,@1413") +#pragma comment(linker, "/EXPORT:WinSqmIncrementDWORD=ntdll.WinSqmIncrementDWORD,@1414") +#pragma comment(linker, "/EXPORT:WinSqmIsOptedIn=ntdll.WinSqmIsOptedIn,@1415") +#pragma comment(linker, "/EXPORT:WinSqmIsOptedInEx=ntdll.WinSqmIsOptedInEx,@1416") +#pragma comment(linker, "/EXPORT:WinSqmSetDWORD=ntdll.WinSqmSetDWORD,@1417") +#pragma comment(linker, "/EXPORT:WinSqmSetDWORD64=ntdll.WinSqmSetDWORD64,@1418") +#pragma comment(linker, "/EXPORT:WinSqmSetEscalationInfo=ntdll.WinSqmSetEscalationInfo,@1419") +#pragma comment(linker, "/EXPORT:WinSqmSetIfMaxDWORD=ntdll.WinSqmSetIfMaxDWORD,@1420") +#pragma comment(linker, "/EXPORT:WinSqmSetIfMinDWORD=ntdll.WinSqmSetIfMinDWORD,@1421") +#pragma comment(linker, "/EXPORT:WinSqmSetString=ntdll.WinSqmSetString,@1422") +#pragma comment(linker, "/EXPORT:WinSqmStartSession=ntdll.WinSqmStartSession,@1423") +#pragma comment(linker, "/EXPORT:ZwAcceptConnectPort=ntdll.ZwAcceptConnectPort,@1424") +#pragma comment(linker, "/EXPORT:ZwAccessCheck=ntdll.ZwAccessCheck,@1425") +#pragma comment(linker, "/EXPORT:ZwAccessCheckAndAuditAlarm=ntdll.ZwAccessCheckAndAuditAlarm,@1426") +#pragma comment(linker, "/EXPORT:ZwAccessCheckByType=ntdll.ZwAccessCheckByType,@1427") +#pragma comment(linker, "/EXPORT:ZwAccessCheckByTypeAndAuditAlarm=ntdll.ZwAccessCheckByTypeAndAuditAlarm,@1428") +#pragma comment(linker, "/EXPORT:ZwAccessCheckByTypeResultList=ntdll.ZwAccessCheckByTypeResultList,@1429") +#pragma comment(linker, "/EXPORT:ZwAccessCheckByTypeResultListAndAuditAlarm=ntdll.ZwAccessCheckByTypeResultListAndAuditAlarm,@1430") +#pragma comment(linker, "/EXPORT:ZwAccessCheckByTypeResultListAndAuditAlarmByHandle=ntdll.ZwAccessCheckByTypeResultListAndAuditAlarmByHandle,@1431") +#pragma comment(linker, "/EXPORT:ZwAddAtom=ntdll.ZwAddAtom,@1432") +#pragma comment(linker, "/EXPORT:ZwAddBootEntry=ntdll.ZwAddBootEntry,@1433") +#pragma comment(linker, "/EXPORT:ZwAddDriverEntry=ntdll.ZwAddDriverEntry,@1434") +#pragma comment(linker, "/EXPORT:ZwAdjustGroupsToken=ntdll.ZwAdjustGroupsToken,@1435") +#pragma comment(linker, "/EXPORT:ZwAdjustPrivilegesToken=ntdll.ZwAdjustPrivilegesToken,@1436") +#pragma comment(linker, "/EXPORT:ZwAlertResumeThread=ntdll.ZwAlertResumeThread,@1437") +#pragma comment(linker, "/EXPORT:ZwAlertThread=ntdll.ZwAlertThread,@1438") +#pragma comment(linker, "/EXPORT:ZwAllocateLocallyUniqueId=ntdll.ZwAllocateLocallyUniqueId,@1439") +#pragma comment(linker, "/EXPORT:ZwAllocateReserveObject=ntdll.ZwAllocateReserveObject,@1440") +#pragma comment(linker, "/EXPORT:ZwAllocateUserPhysicalPages=ntdll.ZwAllocateUserPhysicalPages,@1441") +#pragma comment(linker, "/EXPORT:ZwAllocateUuids=ntdll.ZwAllocateUuids,@1442") +#pragma comment(linker, "/EXPORT:ZwAllocateVirtualMemory=ntdll.ZwAllocateVirtualMemory,@1443") +#pragma comment(linker, "/EXPORT:ZwAlpcAcceptConnectPort=ntdll.ZwAlpcAcceptConnectPort,@1444") +#pragma comment(linker, "/EXPORT:ZwAlpcCancelMessage=ntdll.ZwAlpcCancelMessage,@1445") +#pragma comment(linker, "/EXPORT:ZwAlpcConnectPort=ntdll.ZwAlpcConnectPort,@1446") +#pragma comment(linker, "/EXPORT:ZwAlpcCreatePort=ntdll.ZwAlpcCreatePort,@1447") +#pragma comment(linker, "/EXPORT:ZwAlpcCreatePortSection=ntdll.ZwAlpcCreatePortSection,@1448") +#pragma comment(linker, "/EXPORT:ZwAlpcCreateResourceReserve=ntdll.ZwAlpcCreateResourceReserve,@1449") +#pragma comment(linker, "/EXPORT:ZwAlpcCreateSectionView=ntdll.ZwAlpcCreateSectionView,@1450") +#pragma comment(linker, "/EXPORT:ZwAlpcCreateSecurityContext=ntdll.ZwAlpcCreateSecurityContext,@1451") +#pragma comment(linker, "/EXPORT:ZwAlpcDeletePortSection=ntdll.ZwAlpcDeletePortSection,@1452") +#pragma comment(linker, "/EXPORT:ZwAlpcDeleteResourceReserve=ntdll.ZwAlpcDeleteResourceReserve,@1453") +#pragma comment(linker, "/EXPORT:ZwAlpcDeleteSectionView=ntdll.ZwAlpcDeleteSectionView,@1454") +#pragma comment(linker, "/EXPORT:ZwAlpcDeleteSecurityContext=ntdll.ZwAlpcDeleteSecurityContext,@1455") +#pragma comment(linker, "/EXPORT:ZwAlpcDisconnectPort=ntdll.ZwAlpcDisconnectPort,@1456") +#pragma comment(linker, "/EXPORT:ZwAlpcImpersonateClientOfPort=ntdll.ZwAlpcImpersonateClientOfPort,@1457") +#pragma comment(linker, "/EXPORT:ZwAlpcOpenSenderProcess=ntdll.ZwAlpcOpenSenderProcess,@1458") +#pragma comment(linker, "/EXPORT:ZwAlpcOpenSenderThread=ntdll.ZwAlpcOpenSenderThread,@1459") +#pragma comment(linker, "/EXPORT:ZwAlpcQueryInformation=ntdll.ZwAlpcQueryInformation,@1460") +#pragma comment(linker, "/EXPORT:ZwAlpcQueryInformationMessage=ntdll.ZwAlpcQueryInformationMessage,@1461") +#pragma comment(linker, "/EXPORT:ZwAlpcRevokeSecurityContext=ntdll.ZwAlpcRevokeSecurityContext,@1462") +#pragma comment(linker, "/EXPORT:ZwAlpcSendWaitReceivePort=ntdll.ZwAlpcSendWaitReceivePort,@1463") +#pragma comment(linker, "/EXPORT:ZwAlpcSetInformation=ntdll.ZwAlpcSetInformation,@1464") +#pragma comment(linker, "/EXPORT:ZwApphelpCacheControl=ntdll.ZwApphelpCacheControl,@1465") +#pragma comment(linker, "/EXPORT:ZwAreMappedFilesTheSame=ntdll.ZwAreMappedFilesTheSame,@1466") +#pragma comment(linker, "/EXPORT:ZwAssignProcessToJobObject=ntdll.ZwAssignProcessToJobObject,@1467") +#pragma comment(linker, "/EXPORT:ZwCallbackReturn=ntdll.ZwCallbackReturn,@1468") +#pragma comment(linker, "/EXPORT:ZwCancelIoFile=ntdll.ZwCancelIoFile,@1469") +#pragma comment(linker, "/EXPORT:ZwCancelIoFileEx=ntdll.ZwCancelIoFileEx,@1470") +#pragma comment(linker, "/EXPORT:ZwCancelSynchronousIoFile=ntdll.ZwCancelSynchronousIoFile,@1471") +#pragma comment(linker, "/EXPORT:ZwCancelTimer=ntdll.ZwCancelTimer,@1472") +#pragma comment(linker, "/EXPORT:ZwClearEvent=ntdll.ZwClearEvent,@1473") +#pragma comment(linker, "/EXPORT:ZwClose=ntdll.ZwClose,@1474") +#pragma comment(linker, "/EXPORT:ZwCloseObjectAuditAlarm=ntdll.ZwCloseObjectAuditAlarm,@1475") +#pragma comment(linker, "/EXPORT:ZwCommitComplete=ntdll.ZwCommitComplete,@1476") +#pragma comment(linker, "/EXPORT:ZwCommitEnlistment=ntdll.ZwCommitEnlistment,@1477") +#pragma comment(linker, "/EXPORT:ZwCommitTransaction=ntdll.ZwCommitTransaction,@1478") +#pragma comment(linker, "/EXPORT:ZwCompactKeys=ntdll.ZwCompactKeys,@1479") +#pragma comment(linker, "/EXPORT:ZwCompareTokens=ntdll.ZwCompareTokens,@1480") +#pragma comment(linker, "/EXPORT:ZwCompleteConnectPort=ntdll.ZwCompleteConnectPort,@1481") +#pragma comment(linker, "/EXPORT:ZwCompressKey=ntdll.ZwCompressKey,@1482") +#pragma comment(linker, "/EXPORT:ZwConnectPort=ntdll.ZwConnectPort,@1483") +#pragma comment(linker, "/EXPORT:ZwContinue=ntdll.ZwContinue,@1484") +#pragma comment(linker, "/EXPORT:ZwCreateDebugObject=ntdll.ZwCreateDebugObject,@1485") +#pragma comment(linker, "/EXPORT:ZwCreateDirectoryObject=ntdll.ZwCreateDirectoryObject,@1486") +#pragma comment(linker, "/EXPORT:ZwCreateEnlistment=ntdll.ZwCreateEnlistment,@1487") +#pragma comment(linker, "/EXPORT:ZwCreateEvent=ntdll.ZwCreateEvent,@1488") +#pragma comment(linker, "/EXPORT:ZwCreateEventPair=ntdll.ZwCreateEventPair,@1489") +#pragma comment(linker, "/EXPORT:ZwCreateFile=ntdll.ZwCreateFile,@1490") +#pragma comment(linker, "/EXPORT:ZwCreateIoCompletion=ntdll.ZwCreateIoCompletion,@1491") +#pragma comment(linker, "/EXPORT:ZwCreateJobObject=ntdll.ZwCreateJobObject,@1492") +#pragma comment(linker, "/EXPORT:ZwCreateJobSet=ntdll.ZwCreateJobSet,@1493") +#pragma comment(linker, "/EXPORT:ZwCreateKey=ntdll.ZwCreateKey,@1494") +#pragma comment(linker, "/EXPORT:ZwCreateKeyTransacted=ntdll.ZwCreateKeyTransacted,@1495") +#pragma comment(linker, "/EXPORT:ZwCreateKeyedEvent=ntdll.ZwCreateKeyedEvent,@1496") +#pragma comment(linker, "/EXPORT:ZwCreateMailslotFile=ntdll.ZwCreateMailslotFile,@1497") +#pragma comment(linker, "/EXPORT:ZwCreateMutant=ntdll.ZwCreateMutant,@1498") +#pragma comment(linker, "/EXPORT:ZwCreateNamedPipeFile=ntdll.ZwCreateNamedPipeFile,@1499") +#pragma comment(linker, "/EXPORT:ZwCreatePagingFile=ntdll.ZwCreatePagingFile,@1500") +#pragma comment(linker, "/EXPORT:ZwCreatePort=ntdll.ZwCreatePort,@1501") +#pragma comment(linker, "/EXPORT:ZwCreatePrivateNamespace=ntdll.ZwCreatePrivateNamespace,@1502") +#pragma comment(linker, "/EXPORT:ZwCreateProcess=ntdll.ZwCreateProcess,@1503") +#pragma comment(linker, "/EXPORT:ZwCreateProcessEx=ntdll.ZwCreateProcessEx,@1504") +#pragma comment(linker, "/EXPORT:ZwCreateProfile=ntdll.ZwCreateProfile,@1505") +#pragma comment(linker, "/EXPORT:ZwCreateProfileEx=ntdll.ZwCreateProfileEx,@1506") +#pragma comment(linker, "/EXPORT:ZwCreateResourceManager=ntdll.ZwCreateResourceManager,@1507") +#pragma comment(linker, "/EXPORT:ZwCreateSection=ntdll.ZwCreateSection,@1508") +#pragma comment(linker, "/EXPORT:ZwCreateSemaphore=ntdll.ZwCreateSemaphore,@1509") +#pragma comment(linker, "/EXPORT:ZwCreateSymbolicLinkObject=ntdll.ZwCreateSymbolicLinkObject,@1510") +#pragma comment(linker, "/EXPORT:ZwCreateThread=ntdll.ZwCreateThread,@1511") +#pragma comment(linker, "/EXPORT:ZwCreateThreadEx=ntdll.ZwCreateThreadEx,@1512") +#pragma comment(linker, "/EXPORT:ZwCreateTimer=ntdll.ZwCreateTimer,@1513") +#pragma comment(linker, "/EXPORT:ZwCreateToken=ntdll.ZwCreateToken,@1514") +#pragma comment(linker, "/EXPORT:ZwCreateTransaction=ntdll.ZwCreateTransaction,@1515") +#pragma comment(linker, "/EXPORT:ZwCreateTransactionManager=ntdll.ZwCreateTransactionManager,@1516") +#pragma comment(linker, "/EXPORT:ZwCreateUserProcess=ntdll.ZwCreateUserProcess,@1517") +#pragma comment(linker, "/EXPORT:ZwCreateWaitablePort=ntdll.ZwCreateWaitablePort,@1518") +#pragma comment(linker, "/EXPORT:ZwCreateWorkerFactory=ntdll.ZwCreateWorkerFactory,@1519") +#pragma comment(linker, "/EXPORT:ZwDebugActiveProcess=ntdll.ZwDebugActiveProcess,@1520") +#pragma comment(linker, "/EXPORT:ZwDebugContinue=ntdll.ZwDebugContinue,@1521") +#pragma comment(linker, "/EXPORT:ZwDelayExecution=ntdll.ZwDelayExecution,@1522") +#pragma comment(linker, "/EXPORT:ZwDeleteAtom=ntdll.ZwDeleteAtom,@1523") +#pragma comment(linker, "/EXPORT:ZwDeleteBootEntry=ntdll.ZwDeleteBootEntry,@1524") +#pragma comment(linker, "/EXPORT:ZwDeleteDriverEntry=ntdll.ZwDeleteDriverEntry,@1525") +#pragma comment(linker, "/EXPORT:ZwDeleteFile=ntdll.ZwDeleteFile,@1526") +#pragma comment(linker, "/EXPORT:ZwDeleteKey=ntdll.ZwDeleteKey,@1527") +#pragma comment(linker, "/EXPORT:ZwDeleteObjectAuditAlarm=ntdll.ZwDeleteObjectAuditAlarm,@1528") +#pragma comment(linker, "/EXPORT:ZwDeletePrivateNamespace=ntdll.ZwDeletePrivateNamespace,@1529") +#pragma comment(linker, "/EXPORT:ZwDeleteValueKey=ntdll.ZwDeleteValueKey,@1530") +#pragma comment(linker, "/EXPORT:ZwDeviceIoControlFile=ntdll.ZwDeviceIoControlFile,@1531") +#pragma comment(linker, "/EXPORT:ZwDisableLastKnownGood=ntdll.ZwDisableLastKnownGood,@1532") +#pragma comment(linker, "/EXPORT:ZwDisplayString=ntdll.ZwDisplayString,@1533") +#pragma comment(linker, "/EXPORT:ZwDrawText=ntdll.ZwDrawText,@1534") +#pragma comment(linker, "/EXPORT:ZwDuplicateObject=ntdll.ZwDuplicateObject,@1535") +#pragma comment(linker, "/EXPORT:ZwDuplicateToken=ntdll.ZwDuplicateToken,@1536") +#pragma comment(linker, "/EXPORT:ZwEnableLastKnownGood=ntdll.ZwEnableLastKnownGood,@1537") +#pragma comment(linker, "/EXPORT:ZwEnumerateBootEntries=ntdll.ZwEnumerateBootEntries,@1538") +#pragma comment(linker, "/EXPORT:ZwEnumerateDriverEntries=ntdll.ZwEnumerateDriverEntries,@1539") +#pragma comment(linker, "/EXPORT:ZwEnumerateKey=ntdll.ZwEnumerateKey,@1540") +#pragma comment(linker, "/EXPORT:ZwEnumerateSystemEnvironmentValuesEx=ntdll.ZwEnumerateSystemEnvironmentValuesEx,@1541") +#pragma comment(linker, "/EXPORT:ZwEnumerateTransactionObject=ntdll.ZwEnumerateTransactionObject,@1542") +#pragma comment(linker, "/EXPORT:ZwEnumerateValueKey=ntdll.ZwEnumerateValueKey,@1543") +#pragma comment(linker, "/EXPORT:ZwExtendSection=ntdll.ZwExtendSection,@1544") +#pragma comment(linker, "/EXPORT:ZwFilterToken=ntdll.ZwFilterToken,@1545") +#pragma comment(linker, "/EXPORT:ZwFindAtom=ntdll.ZwFindAtom,@1546") +#pragma comment(linker, "/EXPORT:ZwFlushBuffersFile=ntdll.ZwFlushBuffersFile,@1547") +#pragma comment(linker, "/EXPORT:ZwFlushInstallUILanguage=ntdll.ZwFlushInstallUILanguage,@1548") +#pragma comment(linker, "/EXPORT:ZwFlushInstructionCache=ntdll.ZwFlushInstructionCache,@1549") +#pragma comment(linker, "/EXPORT:ZwFlushKey=ntdll.ZwFlushKey,@1550") +#pragma comment(linker, "/EXPORT:ZwFlushProcessWriteBuffers=ntdll.ZwFlushProcessWriteBuffers,@1551") +#pragma comment(linker, "/EXPORT:ZwFlushVirtualMemory=ntdll.ZwFlushVirtualMemory,@1552") +#pragma comment(linker, "/EXPORT:ZwFlushWriteBuffer=ntdll.ZwFlushWriteBuffer,@1553") +#pragma comment(linker, "/EXPORT:ZwFreeUserPhysicalPages=ntdll.ZwFreeUserPhysicalPages,@1554") +#pragma comment(linker, "/EXPORT:ZwFreeVirtualMemory=ntdll.ZwFreeVirtualMemory,@1555") +#pragma comment(linker, "/EXPORT:ZwFreezeRegistry=ntdll.ZwFreezeRegistry,@1556") +#pragma comment(linker, "/EXPORT:ZwFreezeTransactions=ntdll.ZwFreezeTransactions,@1557") +#pragma comment(linker, "/EXPORT:ZwFsControlFile=ntdll.ZwFsControlFile,@1558") +#pragma comment(linker, "/EXPORT:ZwGetContextThread=ntdll.ZwGetContextThread,@1559") +#pragma comment(linker, "/EXPORT:ZwGetCurrentProcessorNumber=ntdll.ZwGetCurrentProcessorNumber,@1560") +#pragma comment(linker, "/EXPORT:ZwGetDevicePowerState=ntdll.ZwGetDevicePowerState,@1561") +#pragma comment(linker, "/EXPORT:ZwGetMUIRegistryInfo=ntdll.ZwGetMUIRegistryInfo,@1562") +#pragma comment(linker, "/EXPORT:ZwGetNextProcess=ntdll.ZwGetNextProcess,@1563") +#pragma comment(linker, "/EXPORT:ZwGetNextThread=ntdll.ZwGetNextThread,@1564") +#pragma comment(linker, "/EXPORT:ZwGetNlsSectionPtr=ntdll.ZwGetNlsSectionPtr,@1565") +#pragma comment(linker, "/EXPORT:ZwGetNotificationResourceManager=ntdll.ZwGetNotificationResourceManager,@1566") +#pragma comment(linker, "/EXPORT:ZwGetPlugPlayEvent=ntdll.ZwGetPlugPlayEvent,@1567") +#pragma comment(linker, "/EXPORT:ZwGetWriteWatch=ntdll.ZwGetWriteWatch,@1568") +#pragma comment(linker, "/EXPORT:ZwImpersonateAnonymousToken=ntdll.ZwImpersonateAnonymousToken,@1569") +#pragma comment(linker, "/EXPORT:ZwImpersonateClientOfPort=ntdll.ZwImpersonateClientOfPort,@1570") +#pragma comment(linker, "/EXPORT:ZwImpersonateThread=ntdll.ZwImpersonateThread,@1571") +#pragma comment(linker, "/EXPORT:ZwInitializeNlsFiles=ntdll.ZwInitializeNlsFiles,@1572") +#pragma comment(linker, "/EXPORT:ZwInitializeRegistry=ntdll.ZwInitializeRegistry,@1573") +#pragma comment(linker, "/EXPORT:ZwInitiatePowerAction=ntdll.ZwInitiatePowerAction,@1574") +#pragma comment(linker, "/EXPORT:ZwIsProcessInJob=ntdll.ZwIsProcessInJob,@1575") +#pragma comment(linker, "/EXPORT:ZwIsSystemResumeAutomatic=ntdll.ZwIsSystemResumeAutomatic,@1576") +#pragma comment(linker, "/EXPORT:ZwIsUILanguageComitted=ntdll.ZwIsUILanguageComitted,@1577") +#pragma comment(linker, "/EXPORT:ZwListenPort=ntdll.ZwListenPort,@1578") +#pragma comment(linker, "/EXPORT:ZwLoadDriver=ntdll.ZwLoadDriver,@1579") +#pragma comment(linker, "/EXPORT:ZwLoadKey=ntdll.ZwLoadKey,@1580") +#pragma comment(linker, "/EXPORT:ZwLoadKey2=ntdll.ZwLoadKey2,@1581") +#pragma comment(linker, "/EXPORT:ZwLoadKey3=ntdll.ZwLoadKey3,@1582") +#pragma comment(linker, "/EXPORT:ZwLoadKeyEx=ntdll.ZwLoadKeyEx,@1583") +#pragma comment(linker, "/EXPORT:ZwLockFile=ntdll.ZwLockFile,@1584") +#pragma comment(linker, "/EXPORT:ZwLockProductActivationKeys=ntdll.ZwLockProductActivationKeys,@1585") +#pragma comment(linker, "/EXPORT:ZwLockRegistryKey=ntdll.ZwLockRegistryKey,@1586") +#pragma comment(linker, "/EXPORT:ZwLockVirtualMemory=ntdll.ZwLockVirtualMemory,@1587") +#pragma comment(linker, "/EXPORT:ZwMakePermanentObject=ntdll.ZwMakePermanentObject,@1588") +#pragma comment(linker, "/EXPORT:ZwMakeTemporaryObject=ntdll.ZwMakeTemporaryObject,@1589") +#pragma comment(linker, "/EXPORT:ZwMapCMFModule=ntdll.ZwMapCMFModule,@1590") +#pragma comment(linker, "/EXPORT:ZwMapUserPhysicalPages=ntdll.ZwMapUserPhysicalPages,@1591") +#pragma comment(linker, "/EXPORT:ZwMapUserPhysicalPagesScatter=ntdll.ZwMapUserPhysicalPagesScatter,@1592") +#pragma comment(linker, "/EXPORT:ZwMapViewOfSection=ntdll.ZwMapViewOfSection,@1593") +#pragma comment(linker, "/EXPORT:ZwModifyBootEntry=ntdll.ZwModifyBootEntry,@1594") +#pragma comment(linker, "/EXPORT:ZwModifyDriverEntry=ntdll.ZwModifyDriverEntry,@1595") +#pragma comment(linker, "/EXPORT:ZwNotifyChangeDirectoryFile=ntdll.ZwNotifyChangeDirectoryFile,@1596") +#pragma comment(linker, "/EXPORT:ZwNotifyChangeKey=ntdll.ZwNotifyChangeKey,@1597") +#pragma comment(linker, "/EXPORT:ZwNotifyChangeMultipleKeys=ntdll.ZwNotifyChangeMultipleKeys,@1598") +#pragma comment(linker, "/EXPORT:ZwNotifyChangeSession=ntdll.ZwNotifyChangeSession,@1599") +#pragma comment(linker, "/EXPORT:ZwOpenDirectoryObject=ntdll.ZwOpenDirectoryObject,@1600") +#pragma comment(linker, "/EXPORT:ZwOpenEnlistment=ntdll.ZwOpenEnlistment,@1601") +#pragma comment(linker, "/EXPORT:ZwOpenEvent=ntdll.ZwOpenEvent,@1602") +#pragma comment(linker, "/EXPORT:ZwOpenEventPair=ntdll.ZwOpenEventPair,@1603") +#pragma comment(linker, "/EXPORT:ZwOpenFile=ntdll.ZwOpenFile,@1604") +#pragma comment(linker, "/EXPORT:ZwOpenIoCompletion=ntdll.ZwOpenIoCompletion,@1605") +#pragma comment(linker, "/EXPORT:ZwOpenJobObject=ntdll.ZwOpenJobObject,@1606") +#pragma comment(linker, "/EXPORT:ZwOpenKey=ntdll.ZwOpenKey,@1607") +#pragma comment(linker, "/EXPORT:ZwOpenKeyEx=ntdll.ZwOpenKeyEx,@1608") +#pragma comment(linker, "/EXPORT:ZwOpenKeyTransacted=ntdll.ZwOpenKeyTransacted,@1609") +#pragma comment(linker, "/EXPORT:ZwOpenKeyTransactedEx=ntdll.ZwOpenKeyTransactedEx,@1610") +#pragma comment(linker, "/EXPORT:ZwOpenKeyedEvent=ntdll.ZwOpenKeyedEvent,@1611") +#pragma comment(linker, "/EXPORT:ZwOpenMutant=ntdll.ZwOpenMutant,@1612") +#pragma comment(linker, "/EXPORT:ZwOpenObjectAuditAlarm=ntdll.ZwOpenObjectAuditAlarm,@1613") +#pragma comment(linker, "/EXPORT:ZwOpenPrivateNamespace=ntdll.ZwOpenPrivateNamespace,@1614") +#pragma comment(linker, "/EXPORT:ZwOpenProcess=ntdll.ZwOpenProcess,@1615") +#pragma comment(linker, "/EXPORT:ZwOpenProcessToken=ntdll.ZwOpenProcessToken,@1616") +#pragma comment(linker, "/EXPORT:ZwOpenProcessTokenEx=ntdll.ZwOpenProcessTokenEx,@1617") +#pragma comment(linker, "/EXPORT:ZwOpenResourceManager=ntdll.ZwOpenResourceManager,@1618") +#pragma comment(linker, "/EXPORT:ZwOpenSection=ntdll.ZwOpenSection,@1619") +#pragma comment(linker, "/EXPORT:ZwOpenSemaphore=ntdll.ZwOpenSemaphore,@1620") +#pragma comment(linker, "/EXPORT:ZwOpenSession=ntdll.ZwOpenSession,@1621") +#pragma comment(linker, "/EXPORT:ZwOpenSymbolicLinkObject=ntdll.ZwOpenSymbolicLinkObject,@1622") +#pragma comment(linker, "/EXPORT:ZwOpenThread=ntdll.ZwOpenThread,@1623") +#pragma comment(linker, "/EXPORT:ZwOpenThreadToken=ntdll.ZwOpenThreadToken,@1624") +#pragma comment(linker, "/EXPORT:ZwOpenThreadTokenEx=ntdll.ZwOpenThreadTokenEx,@1625") +#pragma comment(linker, "/EXPORT:ZwOpenTimer=ntdll.ZwOpenTimer,@1626") +#pragma comment(linker, "/EXPORT:ZwOpenTransaction=ntdll.ZwOpenTransaction,@1627") +#pragma comment(linker, "/EXPORT:ZwOpenTransactionManager=ntdll.ZwOpenTransactionManager,@1628") +#pragma comment(linker, "/EXPORT:ZwPlugPlayControl=ntdll.ZwPlugPlayControl,@1629") +#pragma comment(linker, "/EXPORT:ZwPowerInformation=ntdll.ZwPowerInformation,@1630") +#pragma comment(linker, "/EXPORT:ZwPrePrepareComplete=ntdll.ZwPrePrepareComplete,@1631") +#pragma comment(linker, "/EXPORT:ZwPrePrepareEnlistment=ntdll.ZwPrePrepareEnlistment,@1632") +#pragma comment(linker, "/EXPORT:ZwPrepareComplete=ntdll.ZwPrepareComplete,@1633") +#pragma comment(linker, "/EXPORT:ZwPrepareEnlistment=ntdll.ZwPrepareEnlistment,@1634") +#pragma comment(linker, "/EXPORT:ZwPrivilegeCheck=ntdll.ZwPrivilegeCheck,@1635") +#pragma comment(linker, "/EXPORT:ZwPrivilegeObjectAuditAlarm=ntdll.ZwPrivilegeObjectAuditAlarm,@1636") +#pragma comment(linker, "/EXPORT:ZwPrivilegedServiceAuditAlarm=ntdll.ZwPrivilegedServiceAuditAlarm,@1637") +#pragma comment(linker, "/EXPORT:ZwPropagationComplete=ntdll.ZwPropagationComplete,@1638") +#pragma comment(linker, "/EXPORT:ZwPropagationFailed=ntdll.ZwPropagationFailed,@1639") +#pragma comment(linker, "/EXPORT:ZwProtectVirtualMemory=ntdll.ZwProtectVirtualMemory,@1640") +#pragma comment(linker, "/EXPORT:ZwPulseEvent=ntdll.ZwPulseEvent,@1641") +#pragma comment(linker, "/EXPORT:ZwQueryAttributesFile=ntdll.ZwQueryAttributesFile,@1642") +#pragma comment(linker, "/EXPORT:ZwQueryBootEntryOrder=ntdll.ZwQueryBootEntryOrder,@1643") +#pragma comment(linker, "/EXPORT:ZwQueryBootOptions=ntdll.ZwQueryBootOptions,@1644") +#pragma comment(linker, "/EXPORT:ZwQueryDebugFilterState=ntdll.ZwQueryDebugFilterState,@1645") +#pragma comment(linker, "/EXPORT:ZwQueryDefaultLocale=ntdll.ZwQueryDefaultLocale,@1646") +#pragma comment(linker, "/EXPORT:ZwQueryDefaultUILanguage=ntdll.ZwQueryDefaultUILanguage,@1647") +#pragma comment(linker, "/EXPORT:ZwQueryDirectoryFile=ntdll.ZwQueryDirectoryFile,@1648") +#pragma comment(linker, "/EXPORT:ZwQueryDirectoryObject=ntdll.ZwQueryDirectoryObject,@1649") +#pragma comment(linker, "/EXPORT:ZwQueryDriverEntryOrder=ntdll.ZwQueryDriverEntryOrder,@1650") +#pragma comment(linker, "/EXPORT:ZwQueryEaFile=ntdll.ZwQueryEaFile,@1651") +#pragma comment(linker, "/EXPORT:ZwQueryEvent=ntdll.ZwQueryEvent,@1652") +#pragma comment(linker, "/EXPORT:ZwQueryFullAttributesFile=ntdll.ZwQueryFullAttributesFile,@1653") +#pragma comment(linker, "/EXPORT:ZwQueryInformationAtom=ntdll.ZwQueryInformationAtom,@1654") +#pragma comment(linker, "/EXPORT:ZwQueryInformationEnlistment=ntdll.ZwQueryInformationEnlistment,@1655") +#pragma comment(linker, "/EXPORT:ZwQueryInformationFile=ntdll.ZwQueryInformationFile,@1656") +#pragma comment(linker, "/EXPORT:ZwQueryInformationJobObject=ntdll.ZwQueryInformationJobObject,@1657") +#pragma comment(linker, "/EXPORT:ZwQueryInformationPort=ntdll.ZwQueryInformationPort,@1658") +#pragma comment(linker, "/EXPORT:ZwQueryInformationProcess=ntdll.ZwQueryInformationProcess,@1659") +#pragma comment(linker, "/EXPORT:ZwQueryInformationResourceManager=ntdll.ZwQueryInformationResourceManager,@1660") +#pragma comment(linker, "/EXPORT:ZwQueryInformationThread=ntdll.ZwQueryInformationThread,@1661") +#pragma comment(linker, "/EXPORT:ZwQueryInformationToken=ntdll.ZwQueryInformationToken,@1662") +#pragma comment(linker, "/EXPORT:ZwQueryInformationTransaction=ntdll.ZwQueryInformationTransaction,@1663") +#pragma comment(linker, "/EXPORT:ZwQueryInformationTransactionManager=ntdll.ZwQueryInformationTransactionManager,@1664") +#pragma comment(linker, "/EXPORT:ZwQueryInformationWorkerFactory=ntdll.ZwQueryInformationWorkerFactory,@1665") +#pragma comment(linker, "/EXPORT:ZwQueryInstallUILanguage=ntdll.ZwQueryInstallUILanguage,@1666") +#pragma comment(linker, "/EXPORT:ZwQueryIntervalProfile=ntdll.ZwQueryIntervalProfile,@1667") +#pragma comment(linker, "/EXPORT:ZwQueryIoCompletion=ntdll.ZwQueryIoCompletion,@1668") +#pragma comment(linker, "/EXPORT:ZwQueryKey=ntdll.ZwQueryKey,@1669") +#pragma comment(linker, "/EXPORT:ZwQueryLicenseValue=ntdll.ZwQueryLicenseValue,@1670") +#pragma comment(linker, "/EXPORT:ZwQueryMultipleValueKey=ntdll.ZwQueryMultipleValueKey,@1671") +#pragma comment(linker, "/EXPORT:ZwQueryMutant=ntdll.ZwQueryMutant,@1672") +#pragma comment(linker, "/EXPORT:ZwQueryObject=ntdll.ZwQueryObject,@1673") +#pragma comment(linker, "/EXPORT:ZwQueryOpenSubKeys=ntdll.ZwQueryOpenSubKeys,@1674") +#pragma comment(linker, "/EXPORT:ZwQueryOpenSubKeysEx=ntdll.ZwQueryOpenSubKeysEx,@1675") +#pragma comment(linker, "/EXPORT:ZwQueryPerformanceCounter=ntdll.ZwQueryPerformanceCounter,@1676") +#pragma comment(linker, "/EXPORT:ZwQueryPortInformationProcess=ntdll.ZwQueryPortInformationProcess,@1677") +#pragma comment(linker, "/EXPORT:ZwQueryQuotaInformationFile=ntdll.ZwQueryQuotaInformationFile,@1678") +#pragma comment(linker, "/EXPORT:ZwQuerySection=ntdll.ZwQuerySection,@1679") +#pragma comment(linker, "/EXPORT:ZwQuerySecurityAttributesToken=ntdll.ZwQuerySecurityAttributesToken,@1680") +#pragma comment(linker, "/EXPORT:ZwQuerySecurityObject=ntdll.ZwQuerySecurityObject,@1681") +#pragma comment(linker, "/EXPORT:ZwQuerySemaphore=ntdll.ZwQuerySemaphore,@1682") +#pragma comment(linker, "/EXPORT:ZwQuerySymbolicLinkObject=ntdll.ZwQuerySymbolicLinkObject,@1683") +#pragma comment(linker, "/EXPORT:ZwQuerySystemEnvironmentValue=ntdll.ZwQuerySystemEnvironmentValue,@1684") +#pragma comment(linker, "/EXPORT:ZwQuerySystemEnvironmentValueEx=ntdll.ZwQuerySystemEnvironmentValueEx,@1685") +#pragma comment(linker, "/EXPORT:ZwQuerySystemInformation=ntdll.ZwQuerySystemInformation,@1686") +#pragma comment(linker, "/EXPORT:ZwQuerySystemInformationEx=ntdll.ZwQuerySystemInformationEx,@1687") +#pragma comment(linker, "/EXPORT:ZwQuerySystemTime=ntdll.ZwQuerySystemTime,@1688") +#pragma comment(linker, "/EXPORT:ZwQueryTimer=ntdll.ZwQueryTimer,@1689") +#pragma comment(linker, "/EXPORT:ZwQueryTimerResolution=ntdll.ZwQueryTimerResolution,@1690") +#pragma comment(linker, "/EXPORT:ZwQueryValueKey=ntdll.ZwQueryValueKey,@1691") +#pragma comment(linker, "/EXPORT:ZwQueryVirtualMemory=ntdll.ZwQueryVirtualMemory,@1692") +#pragma comment(linker, "/EXPORT:ZwQueryVolumeInformationFile=ntdll.ZwQueryVolumeInformationFile,@1693") +#pragma comment(linker, "/EXPORT:ZwQueueApcThread=ntdll.ZwQueueApcThread,@1694") +#pragma comment(linker, "/EXPORT:ZwQueueApcThreadEx=ntdll.ZwQueueApcThreadEx,@1695") +#pragma comment(linker, "/EXPORT:ZwRaiseException=ntdll.ZwRaiseException,@1696") +#pragma comment(linker, "/EXPORT:ZwRaiseHardError=ntdll.ZwRaiseHardError,@1697") +#pragma comment(linker, "/EXPORT:ZwReadFile=ntdll.ZwReadFile,@1698") +#pragma comment(linker, "/EXPORT:ZwReadFileScatter=ntdll.ZwReadFileScatter,@1699") +#pragma comment(linker, "/EXPORT:ZwReadOnlyEnlistment=ntdll.ZwReadOnlyEnlistment,@1700") +#pragma comment(linker, "/EXPORT:ZwReadRequestData=ntdll.ZwReadRequestData,@1701") +#pragma comment(linker, "/EXPORT:ZwReadVirtualMemory=ntdll.ZwReadVirtualMemory,@1702") +#pragma comment(linker, "/EXPORT:ZwRecoverEnlistment=ntdll.ZwRecoverEnlistment,@1703") +#pragma comment(linker, "/EXPORT:ZwRecoverResourceManager=ntdll.ZwRecoverResourceManager,@1704") +#pragma comment(linker, "/EXPORT:ZwRecoverTransactionManager=ntdll.ZwRecoverTransactionManager,@1705") +#pragma comment(linker, "/EXPORT:ZwRegisterProtocolAddressInformation=ntdll.ZwRegisterProtocolAddressInformation,@1706") +#pragma comment(linker, "/EXPORT:ZwRegisterThreadTerminatePort=ntdll.ZwRegisterThreadTerminatePort,@1707") +#pragma comment(linker, "/EXPORT:ZwReleaseKeyedEvent=ntdll.ZwReleaseKeyedEvent,@1708") +#pragma comment(linker, "/EXPORT:ZwReleaseMutant=ntdll.ZwReleaseMutant,@1709") +#pragma comment(linker, "/EXPORT:ZwReleaseSemaphore=ntdll.ZwReleaseSemaphore,@1710") +#pragma comment(linker, "/EXPORT:ZwReleaseWorkerFactoryWorker=ntdll.ZwReleaseWorkerFactoryWorker,@1711") +#pragma comment(linker, "/EXPORT:ZwRemoveIoCompletion=ntdll.ZwRemoveIoCompletion,@1712") +#pragma comment(linker, "/EXPORT:ZwRemoveIoCompletionEx=ntdll.ZwRemoveIoCompletionEx,@1713") +#pragma comment(linker, "/EXPORT:ZwRemoveProcessDebug=ntdll.ZwRemoveProcessDebug,@1714") +#pragma comment(linker, "/EXPORT:ZwRenameKey=ntdll.ZwRenameKey,@1715") +#pragma comment(linker, "/EXPORT:ZwRenameTransactionManager=ntdll.ZwRenameTransactionManager,@1716") +#pragma comment(linker, "/EXPORT:ZwReplaceKey=ntdll.ZwReplaceKey,@1717") +#pragma comment(linker, "/EXPORT:ZwReplacePartitionUnit=ntdll.ZwReplacePartitionUnit,@1718") +#pragma comment(linker, "/EXPORT:ZwReplyPort=ntdll.ZwReplyPort,@1719") +#pragma comment(linker, "/EXPORT:ZwReplyWaitReceivePort=ntdll.ZwReplyWaitReceivePort,@1720") +#pragma comment(linker, "/EXPORT:ZwReplyWaitReceivePortEx=ntdll.ZwReplyWaitReceivePortEx,@1721") +#pragma comment(linker, "/EXPORT:ZwReplyWaitReplyPort=ntdll.ZwReplyWaitReplyPort,@1722") +#pragma comment(linker, "/EXPORT:ZwRequestPort=ntdll.ZwRequestPort,@1723") +#pragma comment(linker, "/EXPORT:ZwRequestWaitReplyPort=ntdll.ZwRequestWaitReplyPort,@1724") +#pragma comment(linker, "/EXPORT:ZwResetEvent=ntdll.ZwResetEvent,@1725") +#pragma comment(linker, "/EXPORT:ZwResetWriteWatch=ntdll.ZwResetWriteWatch,@1726") +#pragma comment(linker, "/EXPORT:ZwRestoreKey=ntdll.ZwRestoreKey,@1727") +#pragma comment(linker, "/EXPORT:ZwResumeProcess=ntdll.ZwResumeProcess,@1728") +#pragma comment(linker, "/EXPORT:ZwResumeThread=ntdll.ZwResumeThread,@1729") +#pragma comment(linker, "/EXPORT:ZwRollbackComplete=ntdll.ZwRollbackComplete,@1730") +#pragma comment(linker, "/EXPORT:ZwRollbackEnlistment=ntdll.ZwRollbackEnlistment,@1731") +#pragma comment(linker, "/EXPORT:ZwRollbackTransaction=ntdll.ZwRollbackTransaction,@1732") +#pragma comment(linker, "/EXPORT:ZwRollforwardTransactionManager=ntdll.ZwRollforwardTransactionManager,@1733") +#pragma comment(linker, "/EXPORT:ZwSaveKey=ntdll.ZwSaveKey,@1734") +#pragma comment(linker, "/EXPORT:ZwSaveKeyEx=ntdll.ZwSaveKeyEx,@1735") +#pragma comment(linker, "/EXPORT:ZwSaveMergedKeys=ntdll.ZwSaveMergedKeys,@1736") +#pragma comment(linker, "/EXPORT:ZwSecureConnectPort=ntdll.ZwSecureConnectPort,@1737") +#pragma comment(linker, "/EXPORT:ZwSerializeBoot=ntdll.ZwSerializeBoot,@1738") +#pragma comment(linker, "/EXPORT:ZwSetBootEntryOrder=ntdll.ZwSetBootEntryOrder,@1739") +#pragma comment(linker, "/EXPORT:ZwSetBootOptions=ntdll.ZwSetBootOptions,@1740") +#pragma comment(linker, "/EXPORT:ZwSetContextThread=ntdll.ZwSetContextThread,@1741") +#pragma comment(linker, "/EXPORT:ZwSetDebugFilterState=ntdll.ZwSetDebugFilterState,@1742") +#pragma comment(linker, "/EXPORT:ZwSetDefaultHardErrorPort=ntdll.ZwSetDefaultHardErrorPort,@1743") +#pragma comment(linker, "/EXPORT:ZwSetDefaultLocale=ntdll.ZwSetDefaultLocale,@1744") +#pragma comment(linker, "/EXPORT:ZwSetDefaultUILanguage=ntdll.ZwSetDefaultUILanguage,@1745") +#pragma comment(linker, "/EXPORT:ZwSetDriverEntryOrder=ntdll.ZwSetDriverEntryOrder,@1746") +#pragma comment(linker, "/EXPORT:ZwSetEaFile=ntdll.ZwSetEaFile,@1747") +#pragma comment(linker, "/EXPORT:ZwSetEvent=ntdll.ZwSetEvent,@1748") +#pragma comment(linker, "/EXPORT:ZwSetEventBoostPriority=ntdll.ZwSetEventBoostPriority,@1749") +#pragma comment(linker, "/EXPORT:ZwSetHighEventPair=ntdll.ZwSetHighEventPair,@1750") +#pragma comment(linker, "/EXPORT:ZwSetHighWaitLowEventPair=ntdll.ZwSetHighWaitLowEventPair,@1751") +#pragma comment(linker, "/EXPORT:ZwSetInformationDebugObject=ntdll.ZwSetInformationDebugObject,@1752") +#pragma comment(linker, "/EXPORT:ZwSetInformationEnlistment=ntdll.ZwSetInformationEnlistment,@1753") +#pragma comment(linker, "/EXPORT:ZwSetInformationFile=ntdll.ZwSetInformationFile,@1754") +#pragma comment(linker, "/EXPORT:ZwSetInformationJobObject=ntdll.ZwSetInformationJobObject,@1755") +#pragma comment(linker, "/EXPORT:ZwSetInformationKey=ntdll.ZwSetInformationKey,@1756") +#pragma comment(linker, "/EXPORT:ZwSetInformationObject=ntdll.ZwSetInformationObject,@1757") +#pragma comment(linker, "/EXPORT:ZwSetInformationProcess=ntdll.ZwSetInformationProcess,@1758") +#pragma comment(linker, "/EXPORT:ZwSetInformationResourceManager=ntdll.ZwSetInformationResourceManager,@1759") +#pragma comment(linker, "/EXPORT:ZwSetInformationThread=ntdll.ZwSetInformationThread,@1760") +#pragma comment(linker, "/EXPORT:ZwSetInformationToken=ntdll.ZwSetInformationToken,@1761") +#pragma comment(linker, "/EXPORT:ZwSetInformationTransaction=ntdll.ZwSetInformationTransaction,@1762") +#pragma comment(linker, "/EXPORT:ZwSetInformationTransactionManager=ntdll.ZwSetInformationTransactionManager,@1763") +#pragma comment(linker, "/EXPORT:ZwSetInformationWorkerFactory=ntdll.ZwSetInformationWorkerFactory,@1764") +#pragma comment(linker, "/EXPORT:ZwSetIntervalProfile=ntdll.ZwSetIntervalProfile,@1765") +#pragma comment(linker, "/EXPORT:ZwSetIoCompletion=ntdll.ZwSetIoCompletion,@1766") +#pragma comment(linker, "/EXPORT:ZwSetIoCompletionEx=ntdll.ZwSetIoCompletionEx,@1767") +#pragma comment(linker, "/EXPORT:ZwSetLdtEntries=ntdll.ZwSetLdtEntries,@1768") +#pragma comment(linker, "/EXPORT:ZwSetLowEventPair=ntdll.ZwSetLowEventPair,@1769") +#pragma comment(linker, "/EXPORT:ZwSetLowWaitHighEventPair=ntdll.ZwSetLowWaitHighEventPair,@1770") +#pragma comment(linker, "/EXPORT:ZwSetQuotaInformationFile=ntdll.ZwSetQuotaInformationFile,@1771") +#pragma comment(linker, "/EXPORT:ZwSetSecurityObject=ntdll.ZwSetSecurityObject,@1772") +#pragma comment(linker, "/EXPORT:ZwSetSystemEnvironmentValue=ntdll.ZwSetSystemEnvironmentValue,@1773") +#pragma comment(linker, "/EXPORT:ZwSetSystemEnvironmentValueEx=ntdll.ZwSetSystemEnvironmentValueEx,@1774") +#pragma comment(linker, "/EXPORT:ZwSetSystemInformation=ntdll.ZwSetSystemInformation,@1775") +#pragma comment(linker, "/EXPORT:ZwSetSystemPowerState=ntdll.ZwSetSystemPowerState,@1776") +#pragma comment(linker, "/EXPORT:ZwSetSystemTime=ntdll.ZwSetSystemTime,@1777") +#pragma comment(linker, "/EXPORT:ZwSetThreadExecutionState=ntdll.ZwSetThreadExecutionState,@1778") +#pragma comment(linker, "/EXPORT:ZwSetTimer=ntdll.ZwSetTimer,@1779") +#pragma comment(linker, "/EXPORT:ZwSetTimerEx=ntdll.ZwSetTimerEx,@1780") +#pragma comment(linker, "/EXPORT:ZwSetTimerResolution=ntdll.ZwSetTimerResolution,@1781") +#pragma comment(linker, "/EXPORT:ZwSetUuidSeed=ntdll.ZwSetUuidSeed,@1782") +#pragma comment(linker, "/EXPORT:ZwSetValueKey=ntdll.ZwSetValueKey,@1783") +#pragma comment(linker, "/EXPORT:ZwSetVolumeInformationFile=ntdll.ZwSetVolumeInformationFile,@1784") +#pragma comment(linker, "/EXPORT:ZwShutdownSystem=ntdll.ZwShutdownSystem,@1785") +#pragma comment(linker, "/EXPORT:ZwShutdownWorkerFactory=ntdll.ZwShutdownWorkerFactory,@1786") +#pragma comment(linker, "/EXPORT:ZwSignalAndWaitForSingleObject=ntdll.ZwSignalAndWaitForSingleObject,@1787") +#pragma comment(linker, "/EXPORT:ZwSinglePhaseReject=ntdll.ZwSinglePhaseReject,@1788") +#pragma comment(linker, "/EXPORT:ZwStartProfile=ntdll.ZwStartProfile,@1789") +#pragma comment(linker, "/EXPORT:ZwStopProfile=ntdll.ZwStopProfile,@1790") +#pragma comment(linker, "/EXPORT:ZwSuspendProcess=ntdll.ZwSuspendProcess,@1791") +#pragma comment(linker, "/EXPORT:ZwSuspendThread=ntdll.ZwSuspendThread,@1792") +#pragma comment(linker, "/EXPORT:ZwSystemDebugControl=ntdll.ZwSystemDebugControl,@1793") +#pragma comment(linker, "/EXPORT:ZwTerminateJobObject=ntdll.ZwTerminateJobObject,@1794") +#pragma comment(linker, "/EXPORT:ZwTerminateProcess=ntdll.ZwTerminateProcess,@1795") +#pragma comment(linker, "/EXPORT:ZwTerminateThread=ntdll.ZwTerminateThread,@1796") +#pragma comment(linker, "/EXPORT:ZwTestAlert=ntdll.ZwTestAlert,@1797") +#pragma comment(linker, "/EXPORT:ZwThawRegistry=ntdll.ZwThawRegistry,@1798") +#pragma comment(linker, "/EXPORT:ZwThawTransactions=ntdll.ZwThawTransactions,@1799") +#pragma comment(linker, "/EXPORT:ZwTraceControl=ntdll.ZwTraceControl,@1800") +#pragma comment(linker, "/EXPORT:ZwTraceEvent=ntdll.ZwTraceEvent,@1801") +#pragma comment(linker, "/EXPORT:ZwTranslateFilePath=ntdll.ZwTranslateFilePath,@1802") +#pragma comment(linker, "/EXPORT:ZwUmsThreadYield=ntdll.ZwUmsThreadYield,@1803") +#pragma comment(linker, "/EXPORT:ZwUnloadDriver=ntdll.ZwUnloadDriver,@1804") +#pragma comment(linker, "/EXPORT:ZwUnloadKey=ntdll.ZwUnloadKey,@1805") +#pragma comment(linker, "/EXPORT:ZwUnloadKey2=ntdll.ZwUnloadKey2,@1806") +#pragma comment(linker, "/EXPORT:ZwUnloadKeyEx=ntdll.ZwUnloadKeyEx,@1807") +#pragma comment(linker, "/EXPORT:ZwUnlockFile=ntdll.ZwUnlockFile,@1808") +#pragma comment(linker, "/EXPORT:ZwUnlockVirtualMemory=ntdll.ZwUnlockVirtualMemory,@1809") +#pragma comment(linker, "/EXPORT:ZwUnmapViewOfSection=ntdll.ZwUnmapViewOfSection,@1810") +#pragma comment(linker, "/EXPORT:ZwVdmControl=ntdll.ZwVdmControl,@1811") +#pragma comment(linker, "/EXPORT:ZwWaitForDebugEvent=ntdll.ZwWaitForDebugEvent,@1812") +#pragma comment(linker, "/EXPORT:ZwWaitForKeyedEvent=ntdll.ZwWaitForKeyedEvent,@1813") +#pragma comment(linker, "/EXPORT:ZwWaitForMultipleObjects=ntdll.ZwWaitForMultipleObjects,@1814") +#pragma comment(linker, "/EXPORT:ZwWaitForMultipleObjects32=ntdll.ZwWaitForMultipleObjects32,@1815") +#pragma comment(linker, "/EXPORT:ZwWaitForSingleObject=ntdll.ZwWaitForSingleObject,@1816") +#pragma comment(linker, "/EXPORT:ZwWaitForWorkViaWorkerFactory=ntdll.ZwWaitForWorkViaWorkerFactory,@1817") +#pragma comment(linker, "/EXPORT:ZwWaitHighEventPair=ntdll.ZwWaitHighEventPair,@1818") +#pragma comment(linker, "/EXPORT:ZwWaitLowEventPair=ntdll.ZwWaitLowEventPair,@1819") +#pragma comment(linker, "/EXPORT:ZwWorkerFactoryWorkerReady=ntdll.ZwWorkerFactoryWorkerReady,@1820") +#pragma comment(linker, "/EXPORT:ZwWriteFile=ntdll.ZwWriteFile,@1821") +#pragma comment(linker, "/EXPORT:ZwWriteFileGather=ntdll.ZwWriteFileGather,@1822") +#pragma comment(linker, "/EXPORT:ZwWriteRequestData=ntdll.ZwWriteRequestData,@1823") +#pragma comment(linker, "/EXPORT:ZwWriteVirtualMemory=ntdll.ZwWriteVirtualMemory,@1824") +#pragma comment(linker, "/EXPORT:ZwYieldExecution=ntdll.ZwYieldExecution,@1825") +#pragma comment(linker, "/EXPORT:__C_specific_handler=ntdll.__C_specific_handler,@1826") +#pragma comment(linker, "/EXPORT:__chkstk=ntdll.__chkstk,@1827") +#pragma comment(linker, "/EXPORT:__isascii=ntdll.__isascii,@1828") +#pragma comment(linker, "/EXPORT:__iscsym=ntdll.__iscsym,@1829") +#pragma comment(linker, "/EXPORT:__iscsymf=ntdll.__iscsymf,@1830") +#pragma comment(linker, "/EXPORT:__misaligned_access=ntdll.__misaligned_access,@1831") +#pragma comment(linker, "/EXPORT:__toascii=ntdll.__toascii,@1832") +#pragma comment(linker, "/EXPORT:_atoi64=ntdll._atoi64,@1833") +#pragma comment(linker, "/EXPORT:_fltused=ntdll._fltused,@1834") +#pragma comment(linker, "/EXPORT:_i64toa=ntdll._i64toa,@1835") +#pragma comment(linker, "/EXPORT:_i64toa_s=ntdll._i64toa_s,@1836") +#pragma comment(linker, "/EXPORT:_i64tow=ntdll._i64tow,@1837") +#pragma comment(linker, "/EXPORT:_i64tow_s=ntdll._i64tow_s,@1838") +#pragma comment(linker, "/EXPORT:_itoa=ntdll._itoa,@1839") +#pragma comment(linker, "/EXPORT:_itoa_s=ntdll._itoa_s,@1840") +#pragma comment(linker, "/EXPORT:_itow=ntdll._itow,@1841") +#pragma comment(linker, "/EXPORT:_itow_s=ntdll._itow_s,@1842") +#pragma comment(linker, "/EXPORT:_lfind=ntdll._lfind,@1843") +#pragma comment(linker, "/EXPORT:_local_unwind=ntdll._local_unwind,@1844") +#pragma comment(linker, "/EXPORT:_ltoa=ntdll._ltoa,@1845") +#pragma comment(linker, "/EXPORT:_ltoa_s=ntdll._ltoa_s,@1846") +#pragma comment(linker, "/EXPORT:_ltow=ntdll._ltow,@1847") +#pragma comment(linker, "/EXPORT:_ltow_s=ntdll._ltow_s,@1848") +#pragma comment(linker, "/EXPORT:_makepath_s=ntdll._makepath_s,@1849") +#pragma comment(linker, "/EXPORT:_memccpy=ntdll._memccpy,@1850") +#pragma comment(linker, "/EXPORT:_memicmp=ntdll._memicmp,@1851") +#pragma comment(linker, "/EXPORT:_setjmp=ntdll._setjmp,@1852") +#pragma comment(linker, "/EXPORT:_setjmpex=ntdll._setjmpex,@1853") +#pragma comment(linker, "/EXPORT:_snprintf=ntdll._snprintf,@1854") +#pragma comment(linker, "/EXPORT:_snprintf_s=ntdll._snprintf_s,@1855") +#pragma comment(linker, "/EXPORT:_snscanf_s=ntdll._snscanf_s,@1856") +#pragma comment(linker, "/EXPORT:_snwprintf=ntdll._snwprintf,@1857") +#pragma comment(linker, "/EXPORT:_snwprintf_s=ntdll._snwprintf_s,@1858") +#pragma comment(linker, "/EXPORT:_snwscanf_s=ntdll._snwscanf_s,@1859") +#pragma comment(linker, "/EXPORT:_splitpath=ntdll._splitpath,@1860") +#pragma comment(linker, "/EXPORT:_splitpath_s=ntdll._splitpath_s,@1861") +#pragma comment(linker, "/EXPORT:_strcmpi=ntdll._strcmpi,@1862") +#pragma comment(linker, "/EXPORT:_stricmp=ntdll._stricmp,@1863") +#pragma comment(linker, "/EXPORT:_strlwr=ntdll._strlwr,@1864") +#pragma comment(linker, "/EXPORT:_strnicmp=ntdll._strnicmp,@1865") +#pragma comment(linker, "/EXPORT:_strnset_s=ntdll._strnset_s,@1866") +#pragma comment(linker, "/EXPORT:_strset_s=ntdll._strset_s,@1867") +#pragma comment(linker, "/EXPORT:_strupr=ntdll._strupr,@1868") +#pragma comment(linker, "/EXPORT:_swprintf=ntdll._swprintf,@1869") +#pragma comment(linker, "/EXPORT:_ui64toa=ntdll._ui64toa,@1870") +#pragma comment(linker, "/EXPORT:_ui64toa_s=ntdll._ui64toa_s,@1871") +#pragma comment(linker, "/EXPORT:_ui64tow=ntdll._ui64tow,@1872") +#pragma comment(linker, "/EXPORT:_ui64tow_s=ntdll._ui64tow_s,@1873") +#pragma comment(linker, "/EXPORT:_ultoa=ntdll._ultoa,@1874") +#pragma comment(linker, "/EXPORT:_ultoa_s=ntdll._ultoa_s,@1875") +#pragma comment(linker, "/EXPORT:_ultow=ntdll._ultow,@1876") +#pragma comment(linker, "/EXPORT:_ultow_s=ntdll._ultow_s,@1877") +#pragma comment(linker, "/EXPORT:_vscwprintf=ntdll._vscwprintf,@1878") +#pragma comment(linker, "/EXPORT:_vsnprintf=ntdll._vsnprintf,@1879") +#pragma comment(linker, "/EXPORT:_vsnprintf_s=ntdll._vsnprintf_s,@1880") +#pragma comment(linker, "/EXPORT:_vsnwprintf=ntdll._vsnwprintf,@1881") +#pragma comment(linker, "/EXPORT:_vsnwprintf_s=ntdll._vsnwprintf_s,@1882") +#pragma comment(linker, "/EXPORT:_vswprintf=ntdll._vswprintf,@1883") +#pragma comment(linker, "/EXPORT:_wcsicmp=ntdll._wcsicmp,@1884") +#pragma comment(linker, "/EXPORT:_wcslwr=ntdll._wcslwr,@1885") +#pragma comment(linker, "/EXPORT:_wcsnicmp=ntdll._wcsnicmp,@1886") +#pragma comment(linker, "/EXPORT:_wcsnset_s=ntdll._wcsnset_s,@1887") +#pragma comment(linker, "/EXPORT:_wcsset_s=ntdll._wcsset_s,@1888") +#pragma comment(linker, "/EXPORT:_wcstoui64=ntdll._wcstoui64,@1889") +#pragma comment(linker, "/EXPORT:_wcsupr=ntdll._wcsupr,@1890") +#pragma comment(linker, "/EXPORT:_wmakepath_s=ntdll._wmakepath_s,@1891") +#pragma comment(linker, "/EXPORT:_wsplitpath_s=ntdll._wsplitpath_s,@1892") +#pragma comment(linker, "/EXPORT:_wtoi=ntdll._wtoi,@1893") +#pragma comment(linker, "/EXPORT:_wtoi64=ntdll._wtoi64,@1894") +#pragma comment(linker, "/EXPORT:_wtol=ntdll._wtol,@1895") +#pragma comment(linker, "/EXPORT:abs=ntdll.abs,@1896") +#pragma comment(linker, "/EXPORT:atan=ntdll.atan,@1897") +#pragma comment(linker, "/EXPORT:atoi=ntdll.atoi,@1898") +#pragma comment(linker, "/EXPORT:atol=ntdll.atol,@1899") +#pragma comment(linker, "/EXPORT:bsearch=ntdll.bsearch,@1900") +#pragma comment(linker, "/EXPORT:ceil=ntdll.ceil,@1901") +#pragma comment(linker, "/EXPORT:cos=ntdll.cos,@1902") +#pragma comment(linker, "/EXPORT:fabs=ntdll.fabs,@1903") +#pragma comment(linker, "/EXPORT:floor=ntdll.floor,@1904") +#pragma comment(linker, "/EXPORT:isalnum=ntdll.isalnum,@1905") +#pragma comment(linker, "/EXPORT:isalpha=ntdll.isalpha,@1906") +#pragma comment(linker, "/EXPORT:iscntrl=ntdll.iscntrl,@1907") +#pragma comment(linker, "/EXPORT:isdigit=ntdll.isdigit,@1908") +#pragma comment(linker, "/EXPORT:isgraph=ntdll.isgraph,@1909") +#pragma comment(linker, "/EXPORT:islower=ntdll.islower,@1910") +#pragma comment(linker, "/EXPORT:isprint=ntdll.isprint,@1911") +#pragma comment(linker, "/EXPORT:ispunct=ntdll.ispunct,@1912") +#pragma comment(linker, "/EXPORT:isspace=ntdll.isspace,@1913") +#pragma comment(linker, "/EXPORT:isupper=ntdll.isupper,@1914") +#pragma comment(linker, "/EXPORT:iswalpha=ntdll.iswalpha,@1915") +#pragma comment(linker, "/EXPORT:iswctype=ntdll.iswctype,@1916") +#pragma comment(linker, "/EXPORT:iswdigit=ntdll.iswdigit,@1917") +#pragma comment(linker, "/EXPORT:iswlower=ntdll.iswlower,@1918") +#pragma comment(linker, "/EXPORT:iswspace=ntdll.iswspace,@1919") +#pragma comment(linker, "/EXPORT:iswxdigit=ntdll.iswxdigit,@1920") +#pragma comment(linker, "/EXPORT:isxdigit=ntdll.isxdigit,@1921") +#pragma comment(linker, "/EXPORT:labs=ntdll.labs,@1922") +#pragma comment(linker, "/EXPORT:log=ntdll.log,@1923") +#pragma comment(linker, "/EXPORT:longjmp=ntdll.longjmp,@1924") +#pragma comment(linker, "/EXPORT:mbstowcs=ntdll.mbstowcs,@1925") +#pragma comment(linker, "/EXPORT:memchr=ntdll.memchr,@1926") +#pragma comment(linker, "/EXPORT:memcmp=ntdll.memcmp,@1927") +#pragma comment(linker, "/EXPORT:memcpy=ntdll.memcpy,@1928") +#pragma comment(linker, "/EXPORT:memcpy_s=ntdll.memcpy_s,@1929") +#pragma comment(linker, "/EXPORT:memmove=ntdll.memmove,@1930") +#pragma comment(linker, "/EXPORT:memmove_s=ntdll.memmove_s,@1931") +#pragma comment(linker, "/EXPORT:memset=ntdll.memset,@1932") +#pragma comment(linker, "/EXPORT:pow=ntdll.pow,@1933") +#pragma comment(linker, "/EXPORT:qsort=ntdll.qsort,@1934") +#pragma comment(linker, "/EXPORT:sin=ntdll.sin,@1935") +#pragma comment(linker, "/EXPORT:sprintf=ntdll.sprintf,@1936") +#pragma comment(linker, "/EXPORT:sprintf_s=ntdll.sprintf_s,@1937") +#pragma comment(linker, "/EXPORT:sqrt=ntdll.sqrt,@1938") +#pragma comment(linker, "/EXPORT:sscanf=ntdll.sscanf,@1939") +#pragma comment(linker, "/EXPORT:sscanf_s=ntdll.sscanf_s,@1940") +#pragma comment(linker, "/EXPORT:strcat=ntdll.strcat,@1941") +#pragma comment(linker, "/EXPORT:strcat_s=ntdll.strcat_s,@1942") +#pragma comment(linker, "/EXPORT:strchr=ntdll.strchr,@1943") +#pragma comment(linker, "/EXPORT:strcmp=ntdll.strcmp,@1944") +#pragma comment(linker, "/EXPORT:strcpy=ntdll.strcpy,@1945") +#pragma comment(linker, "/EXPORT:strcpy_s=ntdll.strcpy_s,@1946") +#pragma comment(linker, "/EXPORT:strcspn=ntdll.strcspn,@1947") +#pragma comment(linker, "/EXPORT:strlen=ntdll.strlen,@1948") +#pragma comment(linker, "/EXPORT:strncat=ntdll.strncat,@1949") +#pragma comment(linker, "/EXPORT:strncat_s=ntdll.strncat_s,@1950") +#pragma comment(linker, "/EXPORT:strncmp=ntdll.strncmp,@1951") +#pragma comment(linker, "/EXPORT:strncpy=ntdll.strncpy,@1952") +#pragma comment(linker, "/EXPORT:strncpy_s=ntdll.strncpy_s,@1953") +#pragma comment(linker, "/EXPORT:strnlen=ntdll.strnlen,@1954") +#pragma comment(linker, "/EXPORT:strpbrk=ntdll.strpbrk,@1955") +#pragma comment(linker, "/EXPORT:strrchr=ntdll.strrchr,@1956") +#pragma comment(linker, "/EXPORT:strspn=ntdll.strspn,@1957") +#pragma comment(linker, "/EXPORT:strstr=ntdll.strstr,@1958") +#pragma comment(linker, "/EXPORT:strtok_s=ntdll.strtok_s,@1959") +#pragma comment(linker, "/EXPORT:strtol=ntdll.strtol,@1960") +#pragma comment(linker, "/EXPORT:strtoul=ntdll.strtoul,@1961") +#pragma comment(linker, "/EXPORT:swprintf=ntdll.swprintf,@1962") +#pragma comment(linker, "/EXPORT:swprintf_s=ntdll.swprintf_s,@1963") +#pragma comment(linker, "/EXPORT:swscanf_s=ntdll.swscanf_s,@1964") +#pragma comment(linker, "/EXPORT:tan=ntdll.tan,@1965") +#pragma comment(linker, "/EXPORT:tolower=ntdll.tolower,@1966") +#pragma comment(linker, "/EXPORT:toupper=ntdll.toupper,@1967") +#pragma comment(linker, "/EXPORT:towlower=ntdll.towlower,@1968") +#pragma comment(linker, "/EXPORT:towupper=ntdll.towupper,@1969") +#pragma comment(linker, "/EXPORT:vDbgPrintEx=ntdll.vDbgPrintEx,@1970") +#pragma comment(linker, "/EXPORT:vDbgPrintExWithPrefix=ntdll.vDbgPrintExWithPrefix,@1971") +#pragma comment(linker, "/EXPORT:vsprintf=ntdll.vsprintf,@1972") +#pragma comment(linker, "/EXPORT:vsprintf_s=ntdll.vsprintf_s,@1973") +#pragma comment(linker, "/EXPORT:vswprintf_s=ntdll.vswprintf_s,@1974") +#pragma comment(linker, "/EXPORT:wcscat=ntdll.wcscat,@1975") +#pragma comment(linker, "/EXPORT:wcscat_s=ntdll.wcscat_s,@1976") +#pragma comment(linker, "/EXPORT:wcschr=ntdll.wcschr,@1977") +#pragma comment(linker, "/EXPORT:wcscmp=ntdll.wcscmp,@1978") +#pragma comment(linker, "/EXPORT:wcscpy=ntdll.wcscpy,@1979") +#pragma comment(linker, "/EXPORT:wcscpy_s=ntdll.wcscpy_s,@1980") +#pragma comment(linker, "/EXPORT:wcscspn=ntdll.wcscspn,@1981") +#pragma comment(linker, "/EXPORT:wcslen=ntdll.wcslen,@1982") +#pragma comment(linker, "/EXPORT:wcsncat=ntdll.wcsncat,@1983") +#pragma comment(linker, "/EXPORT:wcsncat_s=ntdll.wcsncat_s,@1984") +#pragma comment(linker, "/EXPORT:wcsncmp=ntdll.wcsncmp,@1985") +#pragma comment(linker, "/EXPORT:wcsncpy=ntdll.wcsncpy,@1986") +#pragma comment(linker, "/EXPORT:wcsncpy_s=ntdll.wcsncpy_s,@1987") +#pragma comment(linker, "/EXPORT:wcsnlen=ntdll.wcsnlen,@1988") +#pragma comment(linker, "/EXPORT:wcspbrk=ntdll.wcspbrk,@1989") +#pragma comment(linker, "/EXPORT:wcsrchr=ntdll.wcsrchr,@1990") +#pragma comment(linker, "/EXPORT:wcsspn=ntdll.wcsspn,@1991") +#pragma comment(linker, "/EXPORT:wcsstr=ntdll.wcsstr,@1992") +#pragma comment(linker, "/EXPORT:wcstol=ntdll.wcstol,@1993") +#pragma comment(linker, "/EXPORT:wcstombs=ntdll.wcstombs,@1994") +#pragma comment(linker, "/EXPORT:wcstoul=ntdll.wcstoul,@1995") +#pragma comment(linker, "/EXPORT:__OrdinalFunction1=ntdll.#1,@1,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2=ntdll.#2,@2,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction3=ntdll.#3,@3,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction4=ntdll.#4,@4,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction5=ntdll.#5,@5,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction6=ntdll.#6,@6,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction7=ntdll.#7,@7,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction8=ntdll.#8,@8,NONAME") + +#else +// Generated by KexExprt from "C:\Windows\syswow64\ntdll.dll" +#pragma comment(linker, "/EXPORT:A_SHAFinal=ntdll.A_SHAFinal,@18") +#pragma comment(linker, "/EXPORT:A_SHAInit=ntdll.A_SHAInit,@19") +#pragma comment(linker, "/EXPORT:A_SHAUpdate=ntdll.A_SHAUpdate,@20") +#pragma comment(linker, "/EXPORT:AlpcAdjustCompletionListConcurrencyCount=ntdll.AlpcAdjustCompletionListConcurrencyCount,@21") +#pragma comment(linker, "/EXPORT:AlpcFreeCompletionListMessage=ntdll.AlpcFreeCompletionListMessage,@22") +#pragma comment(linker, "/EXPORT:AlpcGetCompletionListLastMessageInformation=ntdll.AlpcGetCompletionListLastMessageInformation,@23") +#pragma comment(linker, "/EXPORT:AlpcGetCompletionListMessageAttributes=ntdll.AlpcGetCompletionListMessageAttributes,@24") +#pragma comment(linker, "/EXPORT:AlpcGetHeaderSize=ntdll.AlpcGetHeaderSize,@25") +#pragma comment(linker, "/EXPORT:AlpcGetMessageAttribute=ntdll.AlpcGetMessageAttribute,@26") +#pragma comment(linker, "/EXPORT:AlpcGetMessageFromCompletionList=ntdll.AlpcGetMessageFromCompletionList,@27") +#pragma comment(linker, "/EXPORT:AlpcGetOutstandingCompletionListMessageCount=ntdll.AlpcGetOutstandingCompletionListMessageCount,@28") +#pragma comment(linker, "/EXPORT:AlpcInitializeMessageAttribute=ntdll.AlpcInitializeMessageAttribute,@29") +#pragma comment(linker, "/EXPORT:AlpcMaxAllowedMessageLength=ntdll.AlpcMaxAllowedMessageLength,@30") +#pragma comment(linker, "/EXPORT:AlpcRegisterCompletionList=ntdll.AlpcRegisterCompletionList,@31") +#pragma comment(linker, "/EXPORT:AlpcRegisterCompletionListWorkerThread=ntdll.AlpcRegisterCompletionListWorkerThread,@32") +#pragma comment(linker, "/EXPORT:AlpcRundownCompletionList=ntdll.AlpcRundownCompletionList,@33") +#pragma comment(linker, "/EXPORT:AlpcUnregisterCompletionList=ntdll.AlpcUnregisterCompletionList,@34") +#pragma comment(linker, "/EXPORT:AlpcUnregisterCompletionListWorkerThread=ntdll.AlpcUnregisterCompletionListWorkerThread,@35") +#pragma comment(linker, "/EXPORT:CsrAllocateCaptureBuffer=ntdll.CsrAllocateCaptureBuffer,@36") +#pragma comment(linker, "/EXPORT:CsrAllocateMessagePointer=ntdll.CsrAllocateMessagePointer,@37") +#pragma comment(linker, "/EXPORT:CsrCaptureMessageBuffer=ntdll.CsrCaptureMessageBuffer,@38") +#pragma comment(linker, "/EXPORT:CsrCaptureMessageMultiUnicodeStringsInPlace=ntdll.CsrCaptureMessageMultiUnicodeStringsInPlace,@39") +#pragma comment(linker, "/EXPORT:CsrCaptureMessageString=ntdll.CsrCaptureMessageString,@40") +#pragma comment(linker, "/EXPORT:CsrCaptureTimeout=ntdll.CsrCaptureTimeout,@41") +#pragma comment(linker, "/EXPORT:CsrClientCallServer=ntdll.CsrClientCallServer,@42") +#pragma comment(linker, "/EXPORT:CsrClientConnectToServer=ntdll.CsrClientConnectToServer,@43") +#pragma comment(linker, "/EXPORT:CsrFreeCaptureBuffer=ntdll.CsrFreeCaptureBuffer,@44") +#pragma comment(linker, "/EXPORT:CsrGetProcessId=ntdll.CsrGetProcessId,@45") +#pragma comment(linker, "/EXPORT:CsrIdentifyAlertableThread=ntdll.CsrIdentifyAlertableThread,@46") +#pragma comment(linker, "/EXPORT:CsrSetPriorityClass=ntdll.CsrSetPriorityClass,@47") +#pragma comment(linker, "/EXPORT:CsrVerifyRegion=ntdll.CsrVerifyRegion,@48") +#pragma comment(linker, "/EXPORT:DbgBreakPoint=ntdll.DbgBreakPoint,@49") +#pragma comment(linker, "/EXPORT:DbgPrint=ntdll.DbgPrint,@50") +#pragma comment(linker, "/EXPORT:DbgPrintEx=ntdll.DbgPrintEx,@51") +#pragma comment(linker, "/EXPORT:DbgPrintReturnControlC=ntdll.DbgPrintReturnControlC,@52") +#pragma comment(linker, "/EXPORT:DbgPrompt=ntdll.DbgPrompt,@53") +#pragma comment(linker, "/EXPORT:DbgQueryDebugFilterState=ntdll.DbgQueryDebugFilterState,@54") +#pragma comment(linker, "/EXPORT:DbgSetDebugFilterState=ntdll.DbgSetDebugFilterState,@55") +#pragma comment(linker, "/EXPORT:DbgUiConnectToDbg=ntdll.DbgUiConnectToDbg,@56") +#pragma comment(linker, "/EXPORT:DbgUiContinue=ntdll.DbgUiContinue,@57") +#pragma comment(linker, "/EXPORT:DbgUiConvertStateChangeStructure=ntdll.DbgUiConvertStateChangeStructure,@58") +#pragma comment(linker, "/EXPORT:DbgUiDebugActiveProcess=ntdll.DbgUiDebugActiveProcess,@59") +#pragma comment(linker, "/EXPORT:DbgUiGetThreadDebugObject=ntdll.DbgUiGetThreadDebugObject,@60") +#pragma comment(linker, "/EXPORT:DbgUiIssueRemoteBreakin=ntdll.DbgUiIssueRemoteBreakin,@61") +#pragma comment(linker, "/EXPORT:DbgUiRemoteBreakin=ntdll.DbgUiRemoteBreakin,@62") +#pragma comment(linker, "/EXPORT:DbgUiSetThreadDebugObject=ntdll.DbgUiSetThreadDebugObject,@63") +#pragma comment(linker, "/EXPORT:DbgUiStopDebugging=ntdll.DbgUiStopDebugging,@64") +#pragma comment(linker, "/EXPORT:DbgUiWaitStateChange=ntdll.DbgUiWaitStateChange,@65") +#pragma comment(linker, "/EXPORT:DbgUserBreakPoint=ntdll.DbgUserBreakPoint,@66") +#pragma comment(linker, "/EXPORT:EtwCreateTraceInstanceId=ntdll.EtwCreateTraceInstanceId,@67") +#pragma comment(linker, "/EXPORT:EtwDeliverDataBlock=ntdll.EtwDeliverDataBlock,@68") +#pragma comment(linker, "/EXPORT:EtwEnumerateProcessRegGuids=ntdll.EtwEnumerateProcessRegGuids,@69") +#pragma comment(linker, "/EXPORT:EtwEventActivityIdControl=ntdll.EtwEventActivityIdControl,@70") +#pragma comment(linker, "/EXPORT:EtwEventEnabled=ntdll.EtwEventEnabled,@71") +#pragma comment(linker, "/EXPORT:EtwEventProviderEnabled=ntdll.EtwEventProviderEnabled,@72") +#pragma comment(linker, "/EXPORT:EtwEventRegister=ntdll.EtwEventRegister,@73") +//#pragma comment(linker, "/EXPORT:EtwEventSetInformation=ntdll.EtwEventSetInformation,@74") +#pragma comment(linker, "/EXPORT:EtwEventUnregister=ntdll.EtwEventUnregister,@75") +#pragma comment(linker, "/EXPORT:EtwEventWrite=ntdll.EtwEventWrite,@76") +#pragma comment(linker, "/EXPORT:EtwEventWriteEndScenario=ntdll.EtwEventWriteEndScenario,@77") +#pragma comment(linker, "/EXPORT:EtwEventWriteEx=ntdll.EtwEventWriteEx,@78") +#pragma comment(linker, "/EXPORT:EtwEventWriteFull=ntdll.EtwEventWriteFull,@79") +#pragma comment(linker, "/EXPORT:EtwEventWriteNoRegistration=ntdll.EtwEventWriteNoRegistration,@80") +#pragma comment(linker, "/EXPORT:EtwEventWriteStartScenario=ntdll.EtwEventWriteStartScenario,@81") +#pragma comment(linker, "/EXPORT:EtwEventWriteString=ntdll.EtwEventWriteString,@82") +#pragma comment(linker, "/EXPORT:EtwEventWriteTransfer=ntdll.EtwEventWriteTransfer,@83") +#pragma comment(linker, "/EXPORT:EtwGetTraceEnableFlags=ntdll.EtwGetTraceEnableFlags,@84") +#pragma comment(linker, "/EXPORT:EtwGetTraceEnableLevel=ntdll.EtwGetTraceEnableLevel,@85") +#pragma comment(linker, "/EXPORT:EtwGetTraceLoggerHandle=ntdll.EtwGetTraceLoggerHandle,@86") +#pragma comment(linker, "/EXPORT:EtwLogTraceEvent=ntdll.EtwLogTraceEvent,@87") +#pragma comment(linker, "/EXPORT:EtwNotificationRegister=ntdll.EtwNotificationRegister,@88") +#pragma comment(linker, "/EXPORT:EtwNotificationUnregister=ntdll.EtwNotificationUnregister,@89") +#pragma comment(linker, "/EXPORT:EtwProcessPrivateLoggerRequest=ntdll.EtwProcessPrivateLoggerRequest,@90") +#pragma comment(linker, "/EXPORT:EtwRegisterSecurityProvider=ntdll.EtwRegisterSecurityProvider,@91") +#pragma comment(linker, "/EXPORT:EtwRegisterTraceGuidsA=ntdll.EtwRegisterTraceGuidsA,@92") +#pragma comment(linker, "/EXPORT:EtwRegisterTraceGuidsW=ntdll.EtwRegisterTraceGuidsW,@93") +#pragma comment(linker, "/EXPORT:EtwReplyNotification=ntdll.EtwReplyNotification,@94") +#pragma comment(linker, "/EXPORT:EtwSendNotification=ntdll.EtwSendNotification,@95") +#pragma comment(linker, "/EXPORT:EtwSetMark=ntdll.EtwSetMark,@96") +#pragma comment(linker, "/EXPORT:EtwTraceEventInstance=ntdll.EtwTraceEventInstance,@97") +#pragma comment(linker, "/EXPORT:EtwTraceMessage=ntdll.EtwTraceMessage,@98") +#pragma comment(linker, "/EXPORT:EtwTraceMessageVa=ntdll.EtwTraceMessageVa,@99") +#pragma comment(linker, "/EXPORT:EtwUnregisterTraceGuids=ntdll.EtwUnregisterTraceGuids,@100") +#pragma comment(linker, "/EXPORT:EtwWriteUMSecurityEvent=ntdll.EtwWriteUMSecurityEvent,@101") +#pragma comment(linker, "/EXPORT:EtwpCreateEtwThread=ntdll.EtwpCreateEtwThread,@102") +#pragma comment(linker, "/EXPORT:EtwpGetCpuSpeed=ntdll.EtwpGetCpuSpeed,@103") +#pragma comment(linker, "/EXPORT:EtwpNotificationThread=ntdll.EtwpNotificationThread,@104") +#pragma comment(linker, "/EXPORT:EvtIntReportAuthzEventAndSourceAsync=ntdll.EvtIntReportAuthzEventAndSourceAsync,@105") +#pragma comment(linker, "/EXPORT:EvtIntReportEventAndSourceAsync=ntdll.EvtIntReportEventAndSourceAsync,@106") +#pragma comment(linker, "/EXPORT:ExpInterlockedPopEntrySListEnd=ntdll.ExpInterlockedPopEntrySListEnd,@15") +#pragma comment(linker, "/EXPORT:ExpInterlockedPopEntrySListFault=ntdll.ExpInterlockedPopEntrySListFault,@16") +#pragma comment(linker, "/EXPORT:ExpInterlockedPopEntrySListResume=ntdll.ExpInterlockedPopEntrySListResume,@17") +#pragma comment(linker, "/EXPORT:KiFastSystemCall=ntdll.KiFastSystemCall,@107") +#pragma comment(linker, "/EXPORT:KiFastSystemCallRet=ntdll.KiFastSystemCallRet,@108") +#pragma comment(linker, "/EXPORT:KiIntSystemCall=ntdll.KiIntSystemCall,@109") +#pragma comment(linker, "/EXPORT:KiRaiseUserExceptionDispatcher=ntdll.KiRaiseUserExceptionDispatcher,@110") +#pragma comment(linker, "/EXPORT:KiUserApcDispatcher=ntdll.KiUserApcDispatcher,@111") +#pragma comment(linker, "/EXPORT:KiUserCallbackDispatcher=ntdll.KiUserCallbackDispatcher,@112") +#pragma comment(linker, "/EXPORT:KiUserExceptionDispatcher=ntdll.KiUserExceptionDispatcher,@113") +#pragma comment(linker, "/EXPORT:LdrAccessResource=ntdll.LdrAccessResource,@114") +#pragma comment(linker, "/EXPORT:LdrAddLoadAsDataTable=ntdll.LdrAddLoadAsDataTable,@115") +#pragma comment(linker, "/EXPORT:LdrAddRefDll=ntdll.LdrAddRefDll,@116") +#pragma comment(linker, "/EXPORT:LdrDisableThreadCalloutsForDll=ntdll.LdrDisableThreadCalloutsForDll,@117") +#pragma comment(linker, "/EXPORT:LdrEnumResources=ntdll.LdrEnumResources,@118") +#pragma comment(linker, "/EXPORT:LdrEnumerateLoadedModules=ntdll.LdrEnumerateLoadedModules,@119") +#pragma comment(linker, "/EXPORT:LdrFindEntryForAddress=ntdll.LdrFindEntryForAddress,@120") +#pragma comment(linker, "/EXPORT:LdrFindResourceDirectory_U=ntdll.LdrFindResourceDirectory_U,@121") +#pragma comment(linker, "/EXPORT:LdrFindResourceEx_U=ntdll.LdrFindResourceEx_U,@122") +#pragma comment(linker, "/EXPORT:LdrFindResource_U=ntdll.LdrFindResource_U,@123") +#pragma comment(linker, "/EXPORT:LdrFlushAlternateResourceModules=ntdll.LdrFlushAlternateResourceModules,@124") +//#pragma comment(linker, "/EXPORT:LdrGetDllHandle=ntdll.LdrGetDllHandle,@125") +#pragma comment(linker, "/EXPORT:LdrGetDllHandleByMapping=ntdll.LdrGetDllHandleByMapping,@126") +#pragma comment(linker, "/EXPORT:LdrGetDllHandleByName=ntdll.LdrGetDllHandleByName,@127") +//#pragma comment(linker, "/EXPORT:LdrGetDllHandleEx=ntdll.LdrGetDllHandleEx,@128") +#pragma comment(linker, "/EXPORT:LdrGetFailureData=ntdll.LdrGetFailureData,@129") +#pragma comment(linker, "/EXPORT:LdrGetFileNameFromLoadAsDataTable=ntdll.LdrGetFileNameFromLoadAsDataTable,@130") +//#pragma comment(linker, "/EXPORT:LdrGetProcedureAddress=ntdll.LdrGetProcedureAddress,@131") +//#pragma comment(linker, "/EXPORT:LdrGetProcedureAddressEx=ntdll.LdrGetProcedureAddressEx,@132") +#pragma comment(linker, "/EXPORT:LdrHotPatchRoutine=ntdll.LdrHotPatchRoutine,@133") +#pragma comment(linker, "/EXPORT:LdrInitShimEngineDynamic=ntdll.LdrInitShimEngineDynamic,@134") +#pragma comment(linker, "/EXPORT:LdrInitializeThunk=ntdll.LdrInitializeThunk,@135") +#pragma comment(linker, "/EXPORT:LdrLoadAlternateResourceModule=ntdll.LdrLoadAlternateResourceModule,@136") +#pragma comment(linker, "/EXPORT:LdrLoadAlternateResourceModuleEx=ntdll.LdrLoadAlternateResourceModuleEx,@137") +//#pragma comment(linker, "/EXPORT:LdrLoadDll=ntdll.LdrLoadDll,@138") +#pragma comment(linker, "/EXPORT:LdrLockLoaderLock=ntdll.LdrLockLoaderLock,@139") +#pragma comment(linker, "/EXPORT:LdrOpenImageFileOptionsKey=ntdll.LdrOpenImageFileOptionsKey,@140") +#pragma comment(linker, "/EXPORT:LdrProcessRelocationBlock=ntdll.LdrProcessRelocationBlock,@141") +#pragma comment(linker, "/EXPORT:LdrQueryImageFileExecutionOptions=ntdll.LdrQueryImageFileExecutionOptions,@142") +#pragma comment(linker, "/EXPORT:LdrQueryImageFileExecutionOptionsEx=ntdll.LdrQueryImageFileExecutionOptionsEx,@143") +#pragma comment(linker, "/EXPORT:LdrQueryImageFileKeyOption=ntdll.LdrQueryImageFileKeyOption,@144") +#pragma comment(linker, "/EXPORT:LdrQueryModuleServiceTags=ntdll.LdrQueryModuleServiceTags,@145") +#pragma comment(linker, "/EXPORT:LdrQueryProcessModuleInformation=ntdll.LdrQueryProcessModuleInformation,@146") +#pragma comment(linker, "/EXPORT:LdrRegisterDllNotification=ntdll.LdrRegisterDllNotification,@147") +#pragma comment(linker, "/EXPORT:LdrRemoveLoadAsDataTable=ntdll.LdrRemoveLoadAsDataTable,@148") +#pragma comment(linker, "/EXPORT:LdrResFindResource=ntdll.LdrResFindResource,@149") +#pragma comment(linker, "/EXPORT:LdrResFindResourceDirectory=ntdll.LdrResFindResourceDirectory,@150") +#pragma comment(linker, "/EXPORT:LdrResGetRCConfig=ntdll.LdrResGetRCConfig,@151") +#pragma comment(linker, "/EXPORT:LdrResRelease=ntdll.LdrResRelease,@152") +#pragma comment(linker, "/EXPORT:LdrResSearchResource=ntdll.LdrResSearchResource,@153") +#pragma comment(linker, "/EXPORT:LdrRscIsTypeExist=ntdll.LdrRscIsTypeExist,@154") +#pragma comment(linker, "/EXPORT:LdrSetAppCompatDllRedirectionCallback=ntdll.LdrSetAppCompatDllRedirectionCallback,@155") +#pragma comment(linker, "/EXPORT:LdrSetDllManifestProber=ntdll.LdrSetDllManifestProber,@156") +#pragma comment(linker, "/EXPORT:LdrSetMUICacheType=ntdll.LdrSetMUICacheType,@157") +#pragma comment(linker, "/EXPORT:LdrShutdownProcess=ntdll.LdrShutdownProcess,@158") +#pragma comment(linker, "/EXPORT:LdrShutdownThread=ntdll.LdrShutdownThread,@159") +#pragma comment(linker, "/EXPORT:LdrSystemDllInitBlock=ntdll.LdrSystemDllInitBlock,@160") +#pragma comment(linker, "/EXPORT:LdrUnloadAlternateResourceModule=ntdll.LdrUnloadAlternateResourceModule,@161") +#pragma comment(linker, "/EXPORT:LdrUnloadAlternateResourceModuleEx=ntdll.LdrUnloadAlternateResourceModuleEx,@162") +#pragma comment(linker, "/EXPORT:LdrUnloadDll=ntdll.LdrUnloadDll,@163") +#pragma comment(linker, "/EXPORT:LdrUnlockLoaderLock=ntdll.LdrUnlockLoaderLock,@164") +#pragma comment(linker, "/EXPORT:LdrUnregisterDllNotification=ntdll.LdrUnregisterDllNotification,@165") +#pragma comment(linker, "/EXPORT:LdrVerifyImageMatchesChecksum=ntdll.LdrVerifyImageMatchesChecksum,@166") +#pragma comment(linker, "/EXPORT:LdrVerifyImageMatchesChecksumEx=ntdll.LdrVerifyImageMatchesChecksumEx,@167") +#pragma comment(linker, "/EXPORT:LdrWx86FormatVirtualImage=ntdll.LdrWx86FormatVirtualImage,@168") +#pragma comment(linker, "/EXPORT:LdrpResGetMappingSize=ntdll.LdrpResGetMappingSize,@169") +#pragma comment(linker, "/EXPORT:LdrpResGetResourceDirectory=ntdll.LdrpResGetResourceDirectory,@170") +#pragma comment(linker, "/EXPORT:MD4Final=ntdll.MD4Final,@171") +#pragma comment(linker, "/EXPORT:MD4Init=ntdll.MD4Init,@172") +#pragma comment(linker, "/EXPORT:MD4Update=ntdll.MD4Update,@173") +#pragma comment(linker, "/EXPORT:MD5Final=ntdll.MD5Final,@174") +#pragma comment(linker, "/EXPORT:MD5Init=ntdll.MD5Init,@175") +#pragma comment(linker, "/EXPORT:MD5Update=ntdll.MD5Update,@176") +#pragma comment(linker, "/EXPORT:NlsAnsiCodePage=ntdll.NlsAnsiCodePage,@177") +#pragma comment(linker, "/EXPORT:NlsMbCodePageTag=ntdll.NlsMbCodePageTag,@178") +#pragma comment(linker, "/EXPORT:NlsMbOemCodePageTag=ntdll.NlsMbOemCodePageTag,@179") +#pragma comment(linker, "/EXPORT:NtAcceptConnectPort=ntdll.NtAcceptConnectPort,@180") +#pragma comment(linker, "/EXPORT:NtAccessCheck=ntdll.NtAccessCheck,@181") +#pragma comment(linker, "/EXPORT:NtAccessCheckAndAuditAlarm=ntdll.NtAccessCheckAndAuditAlarm,@182") +#pragma comment(linker, "/EXPORT:NtAccessCheckByType=ntdll.NtAccessCheckByType,@183") +#pragma comment(linker, "/EXPORT:NtAccessCheckByTypeAndAuditAlarm=ntdll.NtAccessCheckByTypeAndAuditAlarm,@184") +#pragma comment(linker, "/EXPORT:NtAccessCheckByTypeResultList=ntdll.NtAccessCheckByTypeResultList,@185") +#pragma comment(linker, "/EXPORT:NtAccessCheckByTypeResultListAndAuditAlarm=ntdll.NtAccessCheckByTypeResultListAndAuditAlarm,@186") +#pragma comment(linker, "/EXPORT:NtAccessCheckByTypeResultListAndAuditAlarmByHandle=ntdll.NtAccessCheckByTypeResultListAndAuditAlarmByHandle,@187") +#pragma comment(linker, "/EXPORT:NtAddAtom=ntdll.NtAddAtom,@188") +#pragma comment(linker, "/EXPORT:NtAddBootEntry=ntdll.NtAddBootEntry,@189") +#pragma comment(linker, "/EXPORT:NtAddDriverEntry=ntdll.NtAddDriverEntry,@190") +#pragma comment(linker, "/EXPORT:NtAdjustGroupsToken=ntdll.NtAdjustGroupsToken,@191") +#pragma comment(linker, "/EXPORT:NtAdjustPrivilegesToken=ntdll.NtAdjustPrivilegesToken,@192") +#pragma comment(linker, "/EXPORT:NtAlertResumeThread=ntdll.NtAlertResumeThread,@193") +#pragma comment(linker, "/EXPORT:NtAlertThread=ntdll.NtAlertThread,@194") +#pragma comment(linker, "/EXPORT:NtAllocateLocallyUniqueId=ntdll.NtAllocateLocallyUniqueId,@195") +#pragma comment(linker, "/EXPORT:NtAllocateReserveObject=ntdll.NtAllocateReserveObject,@196") +#pragma comment(linker, "/EXPORT:NtAllocateUserPhysicalPages=ntdll.NtAllocateUserPhysicalPages,@197") +#pragma comment(linker, "/EXPORT:NtAllocateUuids=ntdll.NtAllocateUuids,@198") +#pragma comment(linker, "/EXPORT:NtAllocateVirtualMemory=ntdll.NtAllocateVirtualMemory,@199") +#pragma comment(linker, "/EXPORT:NtAlpcAcceptConnectPort=ntdll.NtAlpcAcceptConnectPort,@200") +#pragma comment(linker, "/EXPORT:NtAlpcCancelMessage=ntdll.NtAlpcCancelMessage,@201") +#pragma comment(linker, "/EXPORT:NtAlpcConnectPort=ntdll.NtAlpcConnectPort,@202") +#pragma comment(linker, "/EXPORT:NtAlpcCreatePort=ntdll.NtAlpcCreatePort,@203") +#pragma comment(linker, "/EXPORT:NtAlpcCreatePortSection=ntdll.NtAlpcCreatePortSection,@204") +#pragma comment(linker, "/EXPORT:NtAlpcCreateResourceReserve=ntdll.NtAlpcCreateResourceReserve,@205") +#pragma comment(linker, "/EXPORT:NtAlpcCreateSectionView=ntdll.NtAlpcCreateSectionView,@206") +#pragma comment(linker, "/EXPORT:NtAlpcCreateSecurityContext=ntdll.NtAlpcCreateSecurityContext,@207") +#pragma comment(linker, "/EXPORT:NtAlpcDeletePortSection=ntdll.NtAlpcDeletePortSection,@208") +#pragma comment(linker, "/EXPORT:NtAlpcDeleteResourceReserve=ntdll.NtAlpcDeleteResourceReserve,@209") +#pragma comment(linker, "/EXPORT:NtAlpcDeleteSectionView=ntdll.NtAlpcDeleteSectionView,@210") +#pragma comment(linker, "/EXPORT:NtAlpcDeleteSecurityContext=ntdll.NtAlpcDeleteSecurityContext,@211") +#pragma comment(linker, "/EXPORT:NtAlpcDisconnectPort=ntdll.NtAlpcDisconnectPort,@212") +#pragma comment(linker, "/EXPORT:NtAlpcImpersonateClientOfPort=ntdll.NtAlpcImpersonateClientOfPort,@213") +#pragma comment(linker, "/EXPORT:NtAlpcOpenSenderProcess=ntdll.NtAlpcOpenSenderProcess,@214") +#pragma comment(linker, "/EXPORT:NtAlpcOpenSenderThread=ntdll.NtAlpcOpenSenderThread,@215") +#pragma comment(linker, "/EXPORT:NtAlpcQueryInformation=ntdll.NtAlpcQueryInformation,@216") +#pragma comment(linker, "/EXPORT:NtAlpcQueryInformationMessage=ntdll.NtAlpcQueryInformationMessage,@217") +#pragma comment(linker, "/EXPORT:NtAlpcRevokeSecurityContext=ntdll.NtAlpcRevokeSecurityContext,@218") +#pragma comment(linker, "/EXPORT:NtAlpcSendWaitReceivePort=ntdll.NtAlpcSendWaitReceivePort,@219") +#pragma comment(linker, "/EXPORT:NtAlpcSetInformation=ntdll.NtAlpcSetInformation,@220") +#pragma comment(linker, "/EXPORT:NtApphelpCacheControl=ntdll.NtApphelpCacheControl,@221") +#pragma comment(linker, "/EXPORT:NtAreMappedFilesTheSame=ntdll.NtAreMappedFilesTheSame,@222") +#pragma comment(linker, "/EXPORT:NtAssignProcessToJobObject=ntdll.NtAssignProcessToJobObject,@223") +#pragma comment(linker, "/EXPORT:NtCallbackReturn=ntdll.NtCallbackReturn,@224") +#pragma comment(linker, "/EXPORT:NtCancelIoFile=ntdll.NtCancelIoFile,@225") +#pragma comment(linker, "/EXPORT:NtCancelIoFileEx=ntdll.NtCancelIoFileEx,@226") +#pragma comment(linker, "/EXPORT:NtCancelSynchronousIoFile=ntdll.NtCancelSynchronousIoFile,@227") +#pragma comment(linker, "/EXPORT:NtCancelTimer=ntdll.NtCancelTimer,@228") +#pragma comment(linker, "/EXPORT:NtClearEvent=ntdll.NtClearEvent,@229") +#pragma comment(linker, "/EXPORT:NtClose=ntdll.NtClose,@230") +#pragma comment(linker, "/EXPORT:NtCloseObjectAuditAlarm=ntdll.NtCloseObjectAuditAlarm,@231") +#pragma comment(linker, "/EXPORT:NtCommitComplete=ntdll.NtCommitComplete,@232") +#pragma comment(linker, "/EXPORT:NtCommitEnlistment=ntdll.NtCommitEnlistment,@233") +#pragma comment(linker, "/EXPORT:NtCommitTransaction=ntdll.NtCommitTransaction,@234") +#pragma comment(linker, "/EXPORT:NtCompactKeys=ntdll.NtCompactKeys,@235") +#pragma comment(linker, "/EXPORT:NtCompareTokens=ntdll.NtCompareTokens,@236") +#pragma comment(linker, "/EXPORT:NtCompleteConnectPort=ntdll.NtCompleteConnectPort,@237") +#pragma comment(linker, "/EXPORT:NtCompressKey=ntdll.NtCompressKey,@238") +#pragma comment(linker, "/EXPORT:NtConnectPort=ntdll.NtConnectPort,@239") +#pragma comment(linker, "/EXPORT:NtContinue=ntdll.NtContinue,@240") +#pragma comment(linker, "/EXPORT:NtCreateDebugObject=ntdll.NtCreateDebugObject,@241") +#pragma comment(linker, "/EXPORT:NtCreateDirectoryObject=ntdll.NtCreateDirectoryObject,@242") +#pragma comment(linker, "/EXPORT:NtCreateEnlistment=ntdll.NtCreateEnlistment,@243") +#pragma comment(linker, "/EXPORT:NtCreateEvent=ntdll.NtCreateEvent,@244") +#pragma comment(linker, "/EXPORT:NtCreateEventPair=ntdll.NtCreateEventPair,@245") +#pragma comment(linker, "/EXPORT:NtCreateFile=ntdll.NtCreateFile,@246") +#pragma comment(linker, "/EXPORT:NtCreateIoCompletion=ntdll.NtCreateIoCompletion,@247") +#pragma comment(linker, "/EXPORT:NtCreateJobObject=ntdll.NtCreateJobObject,@248") +#pragma comment(linker, "/EXPORT:NtCreateJobSet=ntdll.NtCreateJobSet,@249") +#pragma comment(linker, "/EXPORT:NtCreateKey=ntdll.NtCreateKey,@250") +#pragma comment(linker, "/EXPORT:NtCreateKeyTransacted=ntdll.NtCreateKeyTransacted,@251") +#pragma comment(linker, "/EXPORT:NtCreateKeyedEvent=ntdll.NtCreateKeyedEvent,@252") +#pragma comment(linker, "/EXPORT:NtCreateMailslotFile=ntdll.NtCreateMailslotFile,@253") +#pragma comment(linker, "/EXPORT:NtCreateMutant=ntdll.NtCreateMutant,@254") +#pragma comment(linker, "/EXPORT:NtCreateNamedPipeFile=ntdll.NtCreateNamedPipeFile,@255") +#pragma comment(linker, "/EXPORT:NtCreatePagingFile=ntdll.NtCreatePagingFile,@256") +#pragma comment(linker, "/EXPORT:NtCreatePort=ntdll.NtCreatePort,@257") +#pragma comment(linker, "/EXPORT:NtCreatePrivateNamespace=ntdll.NtCreatePrivateNamespace,@258") +#pragma comment(linker, "/EXPORT:NtCreateProcess=ntdll.NtCreateProcess,@259") +#pragma comment(linker, "/EXPORT:NtCreateProcessEx=ntdll.NtCreateProcessEx,@260") +#pragma comment(linker, "/EXPORT:NtCreateProfile=ntdll.NtCreateProfile,@261") +#pragma comment(linker, "/EXPORT:NtCreateProfileEx=ntdll.NtCreateProfileEx,@262") +#pragma comment(linker, "/EXPORT:NtCreateResourceManager=ntdll.NtCreateResourceManager,@263") +#pragma comment(linker, "/EXPORT:NtCreateSection=ntdll.NtCreateSection,@264") +#pragma comment(linker, "/EXPORT:NtCreateSemaphore=ntdll.NtCreateSemaphore,@265") +#pragma comment(linker, "/EXPORT:NtCreateSymbolicLinkObject=ntdll.NtCreateSymbolicLinkObject,@266") +#pragma comment(linker, "/EXPORT:NtCreateThread=ntdll.NtCreateThread,@267") +#pragma comment(linker, "/EXPORT:NtCreateThreadEx=ntdll.NtCreateThreadEx,@268") +#pragma comment(linker, "/EXPORT:NtCreateTimer=ntdll.NtCreateTimer,@269") +#pragma comment(linker, "/EXPORT:NtCreateToken=ntdll.NtCreateToken,@270") +#pragma comment(linker, "/EXPORT:NtCreateTransaction=ntdll.NtCreateTransaction,@271") +#pragma comment(linker, "/EXPORT:NtCreateTransactionManager=ntdll.NtCreateTransactionManager,@272") +#pragma comment(linker, "/EXPORT:NtCreateUserProcess=ntdll.NtCreateUserProcess,@273") +#pragma comment(linker, "/EXPORT:NtCreateWaitablePort=ntdll.NtCreateWaitablePort,@274") +#pragma comment(linker, "/EXPORT:NtCreateWorkerFactory=ntdll.NtCreateWorkerFactory,@275") +#pragma comment(linker, "/EXPORT:NtCurrentTeb=ntdll.NtCurrentTeb,@276") +#pragma comment(linker, "/EXPORT:NtDebugActiveProcess=ntdll.NtDebugActiveProcess,@277") +#pragma comment(linker, "/EXPORT:NtDebugContinue=ntdll.NtDebugContinue,@278") +#pragma comment(linker, "/EXPORT:NtDelayExecution=ntdll.NtDelayExecution,@279") +#pragma comment(linker, "/EXPORT:NtDeleteAtom=ntdll.NtDeleteAtom,@280") +#pragma comment(linker, "/EXPORT:NtDeleteBootEntry=ntdll.NtDeleteBootEntry,@281") +#pragma comment(linker, "/EXPORT:NtDeleteDriverEntry=ntdll.NtDeleteDriverEntry,@282") +#pragma comment(linker, "/EXPORT:NtDeleteFile=ntdll.NtDeleteFile,@283") +#pragma comment(linker, "/EXPORT:NtDeleteKey=ntdll.NtDeleteKey,@284") +#pragma comment(linker, "/EXPORT:NtDeleteObjectAuditAlarm=ntdll.NtDeleteObjectAuditAlarm,@285") +#pragma comment(linker, "/EXPORT:NtDeletePrivateNamespace=ntdll.NtDeletePrivateNamespace,@286") +#pragma comment(linker, "/EXPORT:NtDeleteValueKey=ntdll.NtDeleteValueKey,@287") +#pragma comment(linker, "/EXPORT:NtDeviceIoControlFile=ntdll.NtDeviceIoControlFile,@288") +#pragma comment(linker, "/EXPORT:NtDisableLastKnownGood=ntdll.NtDisableLastKnownGood,@289") +#pragma comment(linker, "/EXPORT:NtDisplayString=ntdll.NtDisplayString,@290") +#pragma comment(linker, "/EXPORT:NtDrawText=ntdll.NtDrawText,@291") +#pragma comment(linker, "/EXPORT:NtDuplicateObject=ntdll.NtDuplicateObject,@292") +#pragma comment(linker, "/EXPORT:NtDuplicateToken=ntdll.NtDuplicateToken,@293") +#pragma comment(linker, "/EXPORT:NtEnableLastKnownGood=ntdll.NtEnableLastKnownGood,@294") +#pragma comment(linker, "/EXPORT:NtEnumerateBootEntries=ntdll.NtEnumerateBootEntries,@295") +#pragma comment(linker, "/EXPORT:NtEnumerateDriverEntries=ntdll.NtEnumerateDriverEntries,@296") +#pragma comment(linker, "/EXPORT:NtEnumerateKey=ntdll.NtEnumerateKey,@297") +#pragma comment(linker, "/EXPORT:NtEnumerateSystemEnvironmentValuesEx=ntdll.NtEnumerateSystemEnvironmentValuesEx,@298") +#pragma comment(linker, "/EXPORT:NtEnumerateTransactionObject=ntdll.NtEnumerateTransactionObject,@299") +#pragma comment(linker, "/EXPORT:NtEnumerateValueKey=ntdll.NtEnumerateValueKey,@300") +#pragma comment(linker, "/EXPORT:NtExtendSection=ntdll.NtExtendSection,@301") +#pragma comment(linker, "/EXPORT:NtFilterToken=ntdll.NtFilterToken,@302") +#pragma comment(linker, "/EXPORT:NtFindAtom=ntdll.NtFindAtom,@303") +#pragma comment(linker, "/EXPORT:NtFlushBuffersFile=ntdll.NtFlushBuffersFile,@304") +#pragma comment(linker, "/EXPORT:NtFlushInstallUILanguage=ntdll.NtFlushInstallUILanguage,@305") +#pragma comment(linker, "/EXPORT:NtFlushInstructionCache=ntdll.NtFlushInstructionCache,@306") +#pragma comment(linker, "/EXPORT:NtFlushKey=ntdll.NtFlushKey,@307") +#pragma comment(linker, "/EXPORT:NtFlushProcessWriteBuffers=ntdll.NtFlushProcessWriteBuffers,@308") +#pragma comment(linker, "/EXPORT:NtFlushVirtualMemory=ntdll.NtFlushVirtualMemory,@309") +#pragma comment(linker, "/EXPORT:NtFlushWriteBuffer=ntdll.NtFlushWriteBuffer,@310") +#pragma comment(linker, "/EXPORT:NtFreeUserPhysicalPages=ntdll.NtFreeUserPhysicalPages,@311") +#pragma comment(linker, "/EXPORT:NtFreeVirtualMemory=ntdll.NtFreeVirtualMemory,@312") +#pragma comment(linker, "/EXPORT:NtFreezeRegistry=ntdll.NtFreezeRegistry,@313") +#pragma comment(linker, "/EXPORT:NtFreezeTransactions=ntdll.NtFreezeTransactions,@314") +#pragma comment(linker, "/EXPORT:NtFsControlFile=ntdll.NtFsControlFile,@315") +#pragma comment(linker, "/EXPORT:NtGetContextThread=ntdll.NtGetContextThread,@316") +#pragma comment(linker, "/EXPORT:NtGetCurrentProcessorNumber=ntdll.NtGetCurrentProcessorNumber,@317") +#pragma comment(linker, "/EXPORT:NtGetDevicePowerState=ntdll.NtGetDevicePowerState,@318") +#pragma comment(linker, "/EXPORT:NtGetMUIRegistryInfo=ntdll.NtGetMUIRegistryInfo,@319") +#pragma comment(linker, "/EXPORT:NtGetNextProcess=ntdll.NtGetNextProcess,@320") +#pragma comment(linker, "/EXPORT:NtGetNextThread=ntdll.NtGetNextThread,@321") +#pragma comment(linker, "/EXPORT:NtGetNlsSectionPtr=ntdll.NtGetNlsSectionPtr,@322") +#pragma comment(linker, "/EXPORT:NtGetNotificationResourceManager=ntdll.NtGetNotificationResourceManager,@323") +#pragma comment(linker, "/EXPORT:NtGetPlugPlayEvent=ntdll.NtGetPlugPlayEvent,@324") +#pragma comment(linker, "/EXPORT:NtGetTickCount=ntdll.NtGetTickCount,@325") +#pragma comment(linker, "/EXPORT:NtGetWriteWatch=ntdll.NtGetWriteWatch,@326") +#pragma comment(linker, "/EXPORT:NtImpersonateAnonymousToken=ntdll.NtImpersonateAnonymousToken,@327") +#pragma comment(linker, "/EXPORT:NtImpersonateClientOfPort=ntdll.NtImpersonateClientOfPort,@328") +#pragma comment(linker, "/EXPORT:NtImpersonateThread=ntdll.NtImpersonateThread,@329") +#pragma comment(linker, "/EXPORT:NtInitializeNlsFiles=ntdll.NtInitializeNlsFiles,@330") +#pragma comment(linker, "/EXPORT:NtInitializeRegistry=ntdll.NtInitializeRegistry,@331") +#pragma comment(linker, "/EXPORT:NtInitiatePowerAction=ntdll.NtInitiatePowerAction,@332") +#pragma comment(linker, "/EXPORT:NtIsProcessInJob=ntdll.NtIsProcessInJob,@333") +#pragma comment(linker, "/EXPORT:NtIsSystemResumeAutomatic=ntdll.NtIsSystemResumeAutomatic,@334") +#pragma comment(linker, "/EXPORT:NtIsUILanguageComitted=ntdll.NtIsUILanguageComitted,@335") +#pragma comment(linker, "/EXPORT:NtListenPort=ntdll.NtListenPort,@336") +#pragma comment(linker, "/EXPORT:NtLoadDriver=ntdll.NtLoadDriver,@337") +#pragma comment(linker, "/EXPORT:NtLoadKey=ntdll.NtLoadKey,@340") +#pragma comment(linker, "/EXPORT:NtLoadKey2=ntdll.NtLoadKey2,@338") +#pragma comment(linker, "/EXPORT:NtLoadKey3=ntdll.NtLoadKey3,@339") +#pragma comment(linker, "/EXPORT:NtLoadKeyEx=ntdll.NtLoadKeyEx,@341") +#pragma comment(linker, "/EXPORT:NtLockFile=ntdll.NtLockFile,@342") +#pragma comment(linker, "/EXPORT:NtLockProductActivationKeys=ntdll.NtLockProductActivationKeys,@343") +#pragma comment(linker, "/EXPORT:NtLockRegistryKey=ntdll.NtLockRegistryKey,@344") +#pragma comment(linker, "/EXPORT:NtLockVirtualMemory=ntdll.NtLockVirtualMemory,@345") +#pragma comment(linker, "/EXPORT:NtMakePermanentObject=ntdll.NtMakePermanentObject,@346") +#pragma comment(linker, "/EXPORT:NtMakeTemporaryObject=ntdll.NtMakeTemporaryObject,@347") +#pragma comment(linker, "/EXPORT:NtMapCMFModule=ntdll.NtMapCMFModule,@348") +#pragma comment(linker, "/EXPORT:NtMapUserPhysicalPages=ntdll.NtMapUserPhysicalPages,@349") +#pragma comment(linker, "/EXPORT:NtMapUserPhysicalPagesScatter=ntdll.NtMapUserPhysicalPagesScatter,@350") +#pragma comment(linker, "/EXPORT:NtMapViewOfSection=ntdll.NtMapViewOfSection,@351") +#pragma comment(linker, "/EXPORT:NtModifyBootEntry=ntdll.NtModifyBootEntry,@352") +#pragma comment(linker, "/EXPORT:NtModifyDriverEntry=ntdll.NtModifyDriverEntry,@353") +#pragma comment(linker, "/EXPORT:NtNotifyChangeDirectoryFile=ntdll.NtNotifyChangeDirectoryFile,@354") +#pragma comment(linker, "/EXPORT:NtNotifyChangeKey=ntdll.NtNotifyChangeKey,@355") +#pragma comment(linker, "/EXPORT:NtNotifyChangeMultipleKeys=ntdll.NtNotifyChangeMultipleKeys,@356") +#pragma comment(linker, "/EXPORT:NtNotifyChangeSession=ntdll.NtNotifyChangeSession,@357") +#pragma comment(linker, "/EXPORT:NtOpenDirectoryObject=ntdll.NtOpenDirectoryObject,@358") +#pragma comment(linker, "/EXPORT:NtOpenEnlistment=ntdll.NtOpenEnlistment,@359") +#pragma comment(linker, "/EXPORT:NtOpenEvent=ntdll.NtOpenEvent,@360") +#pragma comment(linker, "/EXPORT:NtOpenEventPair=ntdll.NtOpenEventPair,@361") +#pragma comment(linker, "/EXPORT:NtOpenFile=ntdll.NtOpenFile,@362") +#pragma comment(linker, "/EXPORT:NtOpenIoCompletion=ntdll.NtOpenIoCompletion,@363") +#pragma comment(linker, "/EXPORT:NtOpenJobObject=ntdll.NtOpenJobObject,@364") +#pragma comment(linker, "/EXPORT:NtOpenKey=ntdll.NtOpenKey,@365") +#pragma comment(linker, "/EXPORT:NtOpenKeyEx=ntdll.NtOpenKeyEx,@366") +#pragma comment(linker, "/EXPORT:NtOpenKeyTransacted=ntdll.NtOpenKeyTransacted,@367") +#pragma comment(linker, "/EXPORT:NtOpenKeyTransactedEx=ntdll.NtOpenKeyTransactedEx,@368") +#pragma comment(linker, "/EXPORT:NtOpenKeyedEvent=ntdll.NtOpenKeyedEvent,@369") +#pragma comment(linker, "/EXPORT:NtOpenMutant=ntdll.NtOpenMutant,@370") +#pragma comment(linker, "/EXPORT:NtOpenObjectAuditAlarm=ntdll.NtOpenObjectAuditAlarm,@371") +#pragma comment(linker, "/EXPORT:NtOpenPrivateNamespace=ntdll.NtOpenPrivateNamespace,@372") +#pragma comment(linker, "/EXPORT:NtOpenProcess=ntdll.NtOpenProcess,@373") +#pragma comment(linker, "/EXPORT:NtOpenProcessToken=ntdll.NtOpenProcessToken,@374") +#pragma comment(linker, "/EXPORT:NtOpenProcessTokenEx=ntdll.NtOpenProcessTokenEx,@375") +#pragma comment(linker, "/EXPORT:NtOpenResourceManager=ntdll.NtOpenResourceManager,@376") +#pragma comment(linker, "/EXPORT:NtOpenSection=ntdll.NtOpenSection,@377") +#pragma comment(linker, "/EXPORT:NtOpenSemaphore=ntdll.NtOpenSemaphore,@378") +#pragma comment(linker, "/EXPORT:NtOpenSession=ntdll.NtOpenSession,@379") +#pragma comment(linker, "/EXPORT:NtOpenSymbolicLinkObject=ntdll.NtOpenSymbolicLinkObject,@380") +#pragma comment(linker, "/EXPORT:NtOpenThread=ntdll.NtOpenThread,@381") +#pragma comment(linker, "/EXPORT:NtOpenThreadToken=ntdll.NtOpenThreadToken,@382") +#pragma comment(linker, "/EXPORT:NtOpenThreadTokenEx=ntdll.NtOpenThreadTokenEx,@383") +#pragma comment(linker, "/EXPORT:NtOpenTimer=ntdll.NtOpenTimer,@384") +#pragma comment(linker, "/EXPORT:NtOpenTransaction=ntdll.NtOpenTransaction,@385") +#pragma comment(linker, "/EXPORT:NtOpenTransactionManager=ntdll.NtOpenTransactionManager,@386") +#pragma comment(linker, "/EXPORT:NtPlugPlayControl=ntdll.NtPlugPlayControl,@387") +#pragma comment(linker, "/EXPORT:NtPowerInformation=ntdll.NtPowerInformation,@388") +#pragma comment(linker, "/EXPORT:NtPrePrepareComplete=ntdll.NtPrePrepareComplete,@389") +#pragma comment(linker, "/EXPORT:NtPrePrepareEnlistment=ntdll.NtPrePrepareEnlistment,@390") +#pragma comment(linker, "/EXPORT:NtPrepareComplete=ntdll.NtPrepareComplete,@391") +#pragma comment(linker, "/EXPORT:NtPrepareEnlistment=ntdll.NtPrepareEnlistment,@392") +#pragma comment(linker, "/EXPORT:NtPrivilegeCheck=ntdll.NtPrivilegeCheck,@393") +#pragma comment(linker, "/EXPORT:NtPrivilegeObjectAuditAlarm=ntdll.NtPrivilegeObjectAuditAlarm,@394") +#pragma comment(linker, "/EXPORT:NtPrivilegedServiceAuditAlarm=ntdll.NtPrivilegedServiceAuditAlarm,@395") +#pragma comment(linker, "/EXPORT:NtPropagationComplete=ntdll.NtPropagationComplete,@396") +#pragma comment(linker, "/EXPORT:NtPropagationFailed=ntdll.NtPropagationFailed,@397") +#pragma comment(linker, "/EXPORT:NtProtectVirtualMemory=ntdll.NtProtectVirtualMemory,@398") +#pragma comment(linker, "/EXPORT:NtPulseEvent=ntdll.NtPulseEvent,@399") +#pragma comment(linker, "/EXPORT:NtQueryAttributesFile=ntdll.NtQueryAttributesFile,@400") +#pragma comment(linker, "/EXPORT:NtQueryBootEntryOrder=ntdll.NtQueryBootEntryOrder,@401") +#pragma comment(linker, "/EXPORT:NtQueryBootOptions=ntdll.NtQueryBootOptions,@402") +#pragma comment(linker, "/EXPORT:NtQueryDebugFilterState=ntdll.NtQueryDebugFilterState,@403") +#pragma comment(linker, "/EXPORT:NtQueryDefaultLocale=ntdll.NtQueryDefaultLocale,@404") +#pragma comment(linker, "/EXPORT:NtQueryDefaultUILanguage=ntdll.NtQueryDefaultUILanguage,@405") +#pragma comment(linker, "/EXPORT:NtQueryDirectoryFile=ntdll.NtQueryDirectoryFile,@406") +#pragma comment(linker, "/EXPORT:NtQueryDirectoryObject=ntdll.NtQueryDirectoryObject,@407") +#pragma comment(linker, "/EXPORT:NtQueryDriverEntryOrder=ntdll.NtQueryDriverEntryOrder,@408") +#pragma comment(linker, "/EXPORT:NtQueryEaFile=ntdll.NtQueryEaFile,@409") +#pragma comment(linker, "/EXPORT:NtQueryEvent=ntdll.NtQueryEvent,@410") +#pragma comment(linker, "/EXPORT:NtQueryFullAttributesFile=ntdll.NtQueryFullAttributesFile,@411") +#pragma comment(linker, "/EXPORT:NtQueryInformationAtom=ntdll.NtQueryInformationAtom,@412") +#pragma comment(linker, "/EXPORT:NtQueryInformationEnlistment=ntdll.NtQueryInformationEnlistment,@413") +#pragma comment(linker, "/EXPORT:NtQueryInformationFile=ntdll.NtQueryInformationFile,@414") +#pragma comment(linker, "/EXPORT:NtQueryInformationJobObject=ntdll.NtQueryInformationJobObject,@415") +#pragma comment(linker, "/EXPORT:NtQueryInformationPort=ntdll.NtQueryInformationPort,@416") +#pragma comment(linker, "/EXPORT:NtQueryInformationProcess=ntdll.NtQueryInformationProcess,@417") +#pragma comment(linker, "/EXPORT:NtQueryInformationResourceManager=ntdll.NtQueryInformationResourceManager,@418") +#pragma comment(linker, "/EXPORT:NtQueryInformationThread=ntdll.NtQueryInformationThread,@419") +#pragma comment(linker, "/EXPORT:NtQueryInformationToken=ntdll.NtQueryInformationToken,@420") +#pragma comment(linker, "/EXPORT:NtQueryInformationTransaction=ntdll.NtQueryInformationTransaction,@421") +#pragma comment(linker, "/EXPORT:NtQueryInformationTransactionManager=ntdll.NtQueryInformationTransactionManager,@422") +#pragma comment(linker, "/EXPORT:NtQueryInformationWorkerFactory=ntdll.NtQueryInformationWorkerFactory,@423") +#pragma comment(linker, "/EXPORT:NtQueryInstallUILanguage=ntdll.NtQueryInstallUILanguage,@424") +#pragma comment(linker, "/EXPORT:NtQueryIntervalProfile=ntdll.NtQueryIntervalProfile,@425") +#pragma comment(linker, "/EXPORT:NtQueryIoCompletion=ntdll.NtQueryIoCompletion,@426") +#pragma comment(linker, "/EXPORT:NtQueryKey=ntdll.NtQueryKey,@427") +#pragma comment(linker, "/EXPORT:NtQueryLicenseValue=ntdll.NtQueryLicenseValue,@428") +#pragma comment(linker, "/EXPORT:NtQueryMultipleValueKey=ntdll.NtQueryMultipleValueKey,@429") +#pragma comment(linker, "/EXPORT:NtQueryMutant=ntdll.NtQueryMutant,@430") +#pragma comment(linker, "/EXPORT:NtQueryObject=ntdll.NtQueryObject,@431") +#pragma comment(linker, "/EXPORT:NtQueryOpenSubKeys=ntdll.NtQueryOpenSubKeys,@432") +#pragma comment(linker, "/EXPORT:NtQueryOpenSubKeysEx=ntdll.NtQueryOpenSubKeysEx,@433") +#pragma comment(linker, "/EXPORT:NtQueryPerformanceCounter=ntdll.NtQueryPerformanceCounter,@434") +#pragma comment(linker, "/EXPORT:NtQueryPortInformationProcess=ntdll.NtQueryPortInformationProcess,@435") +#pragma comment(linker, "/EXPORT:NtQueryQuotaInformationFile=ntdll.NtQueryQuotaInformationFile,@436") +#pragma comment(linker, "/EXPORT:NtQuerySection=ntdll.NtQuerySection,@437") +#pragma comment(linker, "/EXPORT:NtQuerySecurityAttributesToken=ntdll.NtQuerySecurityAttributesToken,@438") +#pragma comment(linker, "/EXPORT:NtQuerySecurityObject=ntdll.NtQuerySecurityObject,@439") +#pragma comment(linker, "/EXPORT:NtQuerySemaphore=ntdll.NtQuerySemaphore,@440") +#pragma comment(linker, "/EXPORT:NtQuerySymbolicLinkObject=ntdll.NtQuerySymbolicLinkObject,@441") +#pragma comment(linker, "/EXPORT:NtQuerySystemEnvironmentValue=ntdll.NtQuerySystemEnvironmentValue,@442") +#pragma comment(linker, "/EXPORT:NtQuerySystemEnvironmentValueEx=ntdll.NtQuerySystemEnvironmentValueEx,@443") +#pragma comment(linker, "/EXPORT:NtQuerySystemInformation=ntdll.NtQuerySystemInformation,@444") +#pragma comment(linker, "/EXPORT:NtQuerySystemInformationEx=ntdll.NtQuerySystemInformationEx,@445") +#pragma comment(linker, "/EXPORT:NtQuerySystemTime=ntdll.NtQuerySystemTime,@446") +#pragma comment(linker, "/EXPORT:NtQueryTimer=ntdll.NtQueryTimer,@447") +#pragma comment(linker, "/EXPORT:NtQueryTimerResolution=ntdll.NtQueryTimerResolution,@448") +#pragma comment(linker, "/EXPORT:NtQueryValueKey=ntdll.NtQueryValueKey,@449") +#pragma comment(linker, "/EXPORT:NtQueryVirtualMemory=ntdll.NtQueryVirtualMemory,@450") +#pragma comment(linker, "/EXPORT:NtQueryVolumeInformationFile=ntdll.NtQueryVolumeInformationFile,@451") +#pragma comment(linker, "/EXPORT:NtQueueApcThread=ntdll.NtQueueApcThread,@452") +#pragma comment(linker, "/EXPORT:NtQueueApcThreadEx=ntdll.NtQueueApcThreadEx,@453") +#pragma comment(linker, "/EXPORT:NtRaiseException=ntdll.NtRaiseException,@454") +#pragma comment(linker, "/EXPORT:NtRaiseHardError=ntdll.NtRaiseHardError,@455") +#pragma comment(linker, "/EXPORT:NtReadFile=ntdll.NtReadFile,@456") +#pragma comment(linker, "/EXPORT:NtReadFileScatter=ntdll.NtReadFileScatter,@457") +#pragma comment(linker, "/EXPORT:NtReadOnlyEnlistment=ntdll.NtReadOnlyEnlistment,@458") +#pragma comment(linker, "/EXPORT:NtReadRequestData=ntdll.NtReadRequestData,@459") +#pragma comment(linker, "/EXPORT:NtReadVirtualMemory=ntdll.NtReadVirtualMemory,@460") +#pragma comment(linker, "/EXPORT:NtRecoverEnlistment=ntdll.NtRecoverEnlistment,@461") +#pragma comment(linker, "/EXPORT:NtRecoverResourceManager=ntdll.NtRecoverResourceManager,@462") +#pragma comment(linker, "/EXPORT:NtRecoverTransactionManager=ntdll.NtRecoverTransactionManager,@463") +#pragma comment(linker, "/EXPORT:NtRegisterProtocolAddressInformation=ntdll.NtRegisterProtocolAddressInformation,@464") +#pragma comment(linker, "/EXPORT:NtRegisterThreadTerminatePort=ntdll.NtRegisterThreadTerminatePort,@465") +#pragma comment(linker, "/EXPORT:NtReleaseKeyedEvent=ntdll.NtReleaseKeyedEvent,@466") +#pragma comment(linker, "/EXPORT:NtReleaseMutant=ntdll.NtReleaseMutant,@467") +#pragma comment(linker, "/EXPORT:NtReleaseSemaphore=ntdll.NtReleaseSemaphore,@468") +#pragma comment(linker, "/EXPORT:NtReleaseWorkerFactoryWorker=ntdll.NtReleaseWorkerFactoryWorker,@469") +#pragma comment(linker, "/EXPORT:NtRemoveIoCompletion=ntdll.NtRemoveIoCompletion,@470") +#pragma comment(linker, "/EXPORT:NtRemoveIoCompletionEx=ntdll.NtRemoveIoCompletionEx,@471") +#pragma comment(linker, "/EXPORT:NtRemoveProcessDebug=ntdll.NtRemoveProcessDebug,@472") +#pragma comment(linker, "/EXPORT:NtRenameKey=ntdll.NtRenameKey,@473") +#pragma comment(linker, "/EXPORT:NtRenameTransactionManager=ntdll.NtRenameTransactionManager,@474") +#pragma comment(linker, "/EXPORT:NtReplaceKey=ntdll.NtReplaceKey,@475") +#pragma comment(linker, "/EXPORT:NtReplacePartitionUnit=ntdll.NtReplacePartitionUnit,@476") +#pragma comment(linker, "/EXPORT:NtReplyPort=ntdll.NtReplyPort,@477") +#pragma comment(linker, "/EXPORT:NtReplyWaitReceivePort=ntdll.NtReplyWaitReceivePort,@478") +#pragma comment(linker, "/EXPORT:NtReplyWaitReceivePortEx=ntdll.NtReplyWaitReceivePortEx,@479") +#pragma comment(linker, "/EXPORT:NtReplyWaitReplyPort=ntdll.NtReplyWaitReplyPort,@480") +#pragma comment(linker, "/EXPORT:NtRequestPort=ntdll.NtRequestPort,@481") +#pragma comment(linker, "/EXPORT:NtRequestWaitReplyPort=ntdll.NtRequestWaitReplyPort,@482") +#pragma comment(linker, "/EXPORT:NtResetEvent=ntdll.NtResetEvent,@483") +#pragma comment(linker, "/EXPORT:NtResetWriteWatch=ntdll.NtResetWriteWatch,@484") +#pragma comment(linker, "/EXPORT:NtRestoreKey=ntdll.NtRestoreKey,@485") +#pragma comment(linker, "/EXPORT:NtResumeProcess=ntdll.NtResumeProcess,@486") +#pragma comment(linker, "/EXPORT:NtResumeThread=ntdll.NtResumeThread,@487") +#pragma comment(linker, "/EXPORT:NtRollbackComplete=ntdll.NtRollbackComplete,@488") +#pragma comment(linker, "/EXPORT:NtRollbackEnlistment=ntdll.NtRollbackEnlistment,@489") +#pragma comment(linker, "/EXPORT:NtRollbackTransaction=ntdll.NtRollbackTransaction,@490") +#pragma comment(linker, "/EXPORT:NtRollforwardTransactionManager=ntdll.NtRollforwardTransactionManager,@491") +#pragma comment(linker, "/EXPORT:NtSaveKey=ntdll.NtSaveKey,@492") +#pragma comment(linker, "/EXPORT:NtSaveKeyEx=ntdll.NtSaveKeyEx,@493") +#pragma comment(linker, "/EXPORT:NtSaveMergedKeys=ntdll.NtSaveMergedKeys,@494") +#pragma comment(linker, "/EXPORT:NtSecureConnectPort=ntdll.NtSecureConnectPort,@495") +#pragma comment(linker, "/EXPORT:NtSerializeBoot=ntdll.NtSerializeBoot,@496") +#pragma comment(linker, "/EXPORT:NtSetBootEntryOrder=ntdll.NtSetBootEntryOrder,@497") +#pragma comment(linker, "/EXPORT:NtSetBootOptions=ntdll.NtSetBootOptions,@498") +#pragma comment(linker, "/EXPORT:NtSetContextThread=ntdll.NtSetContextThread,@499") +#pragma comment(linker, "/EXPORT:NtSetDebugFilterState=ntdll.NtSetDebugFilterState,@500") +#pragma comment(linker, "/EXPORT:NtSetDefaultHardErrorPort=ntdll.NtSetDefaultHardErrorPort,@501") +#pragma comment(linker, "/EXPORT:NtSetDefaultLocale=ntdll.NtSetDefaultLocale,@502") +#pragma comment(linker, "/EXPORT:NtSetDefaultUILanguage=ntdll.NtSetDefaultUILanguage,@503") +#pragma comment(linker, "/EXPORT:NtSetDriverEntryOrder=ntdll.NtSetDriverEntryOrder,@504") +#pragma comment(linker, "/EXPORT:NtSetEaFile=ntdll.NtSetEaFile,@505") +#pragma comment(linker, "/EXPORT:NtSetEvent=ntdll.NtSetEvent,@506") +#pragma comment(linker, "/EXPORT:NtSetEventBoostPriority=ntdll.NtSetEventBoostPriority,@507") +#pragma comment(linker, "/EXPORT:NtSetHighEventPair=ntdll.NtSetHighEventPair,@508") +#pragma comment(linker, "/EXPORT:NtSetHighWaitLowEventPair=ntdll.NtSetHighWaitLowEventPair,@509") +#pragma comment(linker, "/EXPORT:NtSetInformationDebugObject=ntdll.NtSetInformationDebugObject,@510") +#pragma comment(linker, "/EXPORT:NtSetInformationEnlistment=ntdll.NtSetInformationEnlistment,@511") +#pragma comment(linker, "/EXPORT:NtSetInformationFile=ntdll.NtSetInformationFile,@512") +#pragma comment(linker, "/EXPORT:NtSetInformationJobObject=ntdll.NtSetInformationJobObject,@513") +#pragma comment(linker, "/EXPORT:NtSetInformationKey=ntdll.NtSetInformationKey,@514") +#pragma comment(linker, "/EXPORT:NtSetInformationObject=ntdll.NtSetInformationObject,@515") +#pragma comment(linker, "/EXPORT:NtSetInformationProcess=ntdll.NtSetInformationProcess,@516") +#pragma comment(linker, "/EXPORT:NtSetInformationResourceManager=ntdll.NtSetInformationResourceManager,@517") +#pragma comment(linker, "/EXPORT:NtSetInformationThread=ntdll.NtSetInformationThread,@518") +#pragma comment(linker, "/EXPORT:NtSetInformationToken=ntdll.NtSetInformationToken,@519") +#pragma comment(linker, "/EXPORT:NtSetInformationTransaction=ntdll.NtSetInformationTransaction,@520") +#pragma comment(linker, "/EXPORT:NtSetInformationTransactionManager=ntdll.NtSetInformationTransactionManager,@521") +#pragma comment(linker, "/EXPORT:NtSetInformationWorkerFactory=ntdll.NtSetInformationWorkerFactory,@522") +#pragma comment(linker, "/EXPORT:NtSetIntervalProfile=ntdll.NtSetIntervalProfile,@523") +#pragma comment(linker, "/EXPORT:NtSetIoCompletion=ntdll.NtSetIoCompletion,@524") +#pragma comment(linker, "/EXPORT:NtSetIoCompletionEx=ntdll.NtSetIoCompletionEx,@525") +#pragma comment(linker, "/EXPORT:NtSetLdtEntries=ntdll.NtSetLdtEntries,@526") +#pragma comment(linker, "/EXPORT:NtSetLowEventPair=ntdll.NtSetLowEventPair,@527") +#pragma comment(linker, "/EXPORT:NtSetLowWaitHighEventPair=ntdll.NtSetLowWaitHighEventPair,@528") +#pragma comment(linker, "/EXPORT:NtSetQuotaInformationFile=ntdll.NtSetQuotaInformationFile,@529") +#pragma comment(linker, "/EXPORT:NtSetSecurityObject=ntdll.NtSetSecurityObject,@530") +#pragma comment(linker, "/EXPORT:NtSetSystemEnvironmentValue=ntdll.NtSetSystemEnvironmentValue,@531") +#pragma comment(linker, "/EXPORT:NtSetSystemEnvironmentValueEx=ntdll.NtSetSystemEnvironmentValueEx,@532") +#pragma comment(linker, "/EXPORT:NtSetSystemInformation=ntdll.NtSetSystemInformation,@533") +#pragma comment(linker, "/EXPORT:NtSetSystemPowerState=ntdll.NtSetSystemPowerState,@534") +#pragma comment(linker, "/EXPORT:NtSetSystemTime=ntdll.NtSetSystemTime,@535") +#pragma comment(linker, "/EXPORT:NtSetThreadExecutionState=ntdll.NtSetThreadExecutionState,@536") +#pragma comment(linker, "/EXPORT:NtSetTimer=ntdll.NtSetTimer,@537") +#pragma comment(linker, "/EXPORT:NtSetTimerEx=ntdll.NtSetTimerEx,@538") +#pragma comment(linker, "/EXPORT:NtSetTimerResolution=ntdll.NtSetTimerResolution,@539") +#pragma comment(linker, "/EXPORT:NtSetUuidSeed=ntdll.NtSetUuidSeed,@540") +#pragma comment(linker, "/EXPORT:NtSetValueKey=ntdll.NtSetValueKey,@541") +#pragma comment(linker, "/EXPORT:NtSetVolumeInformationFile=ntdll.NtSetVolumeInformationFile,@542") +#pragma comment(linker, "/EXPORT:NtShutdownSystem=ntdll.NtShutdownSystem,@543") +#pragma comment(linker, "/EXPORT:NtShutdownWorkerFactory=ntdll.NtShutdownWorkerFactory,@544") +#pragma comment(linker, "/EXPORT:NtSignalAndWaitForSingleObject=ntdll.NtSignalAndWaitForSingleObject,@545") +#pragma comment(linker, "/EXPORT:NtSinglePhaseReject=ntdll.NtSinglePhaseReject,@546") +#pragma comment(linker, "/EXPORT:NtStartProfile=ntdll.NtStartProfile,@547") +#pragma comment(linker, "/EXPORT:NtStopProfile=ntdll.NtStopProfile,@548") +#pragma comment(linker, "/EXPORT:NtSuspendProcess=ntdll.NtSuspendProcess,@549") +#pragma comment(linker, "/EXPORT:NtSuspendThread=ntdll.NtSuspendThread,@550") +#pragma comment(linker, "/EXPORT:NtSystemDebugControl=ntdll.NtSystemDebugControl,@551") +#pragma comment(linker, "/EXPORT:NtTerminateJobObject=ntdll.NtTerminateJobObject,@552") +#pragma comment(linker, "/EXPORT:NtTerminateProcess=ntdll.NtTerminateProcess,@553") +#pragma comment(linker, "/EXPORT:NtTerminateThread=ntdll.NtTerminateThread,@554") +#pragma comment(linker, "/EXPORT:NtTestAlert=ntdll.NtTestAlert,@555") +#pragma comment(linker, "/EXPORT:NtThawRegistry=ntdll.NtThawRegistry,@556") +#pragma comment(linker, "/EXPORT:NtThawTransactions=ntdll.NtThawTransactions,@557") +#pragma comment(linker, "/EXPORT:NtTraceControl=ntdll.NtTraceControl,@558") +#pragma comment(linker, "/EXPORT:NtTraceEvent=ntdll.NtTraceEvent,@559") +#pragma comment(linker, "/EXPORT:NtTranslateFilePath=ntdll.NtTranslateFilePath,@560") +#pragma comment(linker, "/EXPORT:NtUmsThreadYield=ntdll.NtUmsThreadYield,@561") +#pragma comment(linker, "/EXPORT:NtUnloadDriver=ntdll.NtUnloadDriver,@562") +#pragma comment(linker, "/EXPORT:NtUnloadKey=ntdll.NtUnloadKey,@564") +#pragma comment(linker, "/EXPORT:NtUnloadKey2=ntdll.NtUnloadKey2,@563") +#pragma comment(linker, "/EXPORT:NtUnloadKeyEx=ntdll.NtUnloadKeyEx,@565") +#pragma comment(linker, "/EXPORT:NtUnlockFile=ntdll.NtUnlockFile,@566") +#pragma comment(linker, "/EXPORT:NtUnlockVirtualMemory=ntdll.NtUnlockVirtualMemory,@567") +#pragma comment(linker, "/EXPORT:NtUnmapViewOfSection=ntdll.NtUnmapViewOfSection,@568") +#pragma comment(linker, "/EXPORT:NtVdmControl=ntdll.NtVdmControl,@569") +#pragma comment(linker, "/EXPORT:NtWaitForDebugEvent=ntdll.NtWaitForDebugEvent,@570") +#pragma comment(linker, "/EXPORT:NtWaitForKeyedEvent=ntdll.NtWaitForKeyedEvent,@571") +#pragma comment(linker, "/EXPORT:NtWaitForMultipleObjects=ntdll.NtWaitForMultipleObjects,@573") +#pragma comment(linker, "/EXPORT:NtWaitForMultipleObjects32=ntdll.NtWaitForMultipleObjects32,@572") +#pragma comment(linker, "/EXPORT:NtWaitForSingleObject=ntdll.NtWaitForSingleObject,@574") +#pragma comment(linker, "/EXPORT:NtWaitForWorkViaWorkerFactory=ntdll.NtWaitForWorkViaWorkerFactory,@575") +#pragma comment(linker, "/EXPORT:NtWaitHighEventPair=ntdll.NtWaitHighEventPair,@576") +#pragma comment(linker, "/EXPORT:NtWaitLowEventPair=ntdll.NtWaitLowEventPair,@577") +#pragma comment(linker, "/EXPORT:NtWorkerFactoryWorkerReady=ntdll.NtWorkerFactoryWorkerReady,@578") +#pragma comment(linker, "/EXPORT:NtWow64CallFunction64=ntdll.NtWow64CallFunction64,@579") +#pragma comment(linker, "/EXPORT:NtWow64CsrAllocateCaptureBuffer=ntdll.NtWow64CsrAllocateCaptureBuffer,@580") +#pragma comment(linker, "/EXPORT:NtWow64CsrAllocateMessagePointer=ntdll.NtWow64CsrAllocateMessagePointer,@581") +#pragma comment(linker, "/EXPORT:NtWow64CsrCaptureMessageBuffer=ntdll.NtWow64CsrCaptureMessageBuffer,@582") +#pragma comment(linker, "/EXPORT:NtWow64CsrCaptureMessageString=ntdll.NtWow64CsrCaptureMessageString,@583") +#pragma comment(linker, "/EXPORT:NtWow64CsrClientCallServer=ntdll.NtWow64CsrClientCallServer,@584") +#pragma comment(linker, "/EXPORT:NtWow64CsrClientConnectToServer=ntdll.NtWow64CsrClientConnectToServer,@585") +#pragma comment(linker, "/EXPORT:NtWow64CsrFreeCaptureBuffer=ntdll.NtWow64CsrFreeCaptureBuffer,@586") +#pragma comment(linker, "/EXPORT:NtWow64CsrGetProcessId=ntdll.NtWow64CsrGetProcessId,@587") +#pragma comment(linker, "/EXPORT:NtWow64CsrIdentifyAlertableThread=ntdll.NtWow64CsrIdentifyAlertableThread,@588") +#pragma comment(linker, "/EXPORT:NtWow64CsrVerifyRegion=ntdll.NtWow64CsrVerifyRegion,@589") +#pragma comment(linker, "/EXPORT:NtWow64DebuggerCall=ntdll.NtWow64DebuggerCall,@590") +#pragma comment(linker, "/EXPORT:NtWow64GetCurrentProcessorNumberEx=ntdll.NtWow64GetCurrentProcessorNumberEx,@591") +#pragma comment(linker, "/EXPORT:NtWow64GetNativeSystemInformation=ntdll.NtWow64GetNativeSystemInformation,@592") +#pragma comment(linker, "/EXPORT:NtWow64InterlockedPopEntrySList=ntdll.NtWow64InterlockedPopEntrySList,@593") +#pragma comment(linker, "/EXPORT:NtWow64QueryInformationProcess64=ntdll.NtWow64QueryInformationProcess64,@594") +#pragma comment(linker, "/EXPORT:NtWow64QueryVirtualMemory64=ntdll.NtWow64QueryVirtualMemory64,@595") +#pragma comment(linker, "/EXPORT:NtWow64ReadVirtualMemory64=ntdll.NtWow64ReadVirtualMemory64,@596") +#pragma comment(linker, "/EXPORT:NtWow64WriteVirtualMemory64=ntdll.NtWow64WriteVirtualMemory64,@597") +#pragma comment(linker, "/EXPORT:NtWriteFile=ntdll.NtWriteFile,@598") +#pragma comment(linker, "/EXPORT:NtWriteFileGather=ntdll.NtWriteFileGather,@599") +#pragma comment(linker, "/EXPORT:NtWriteRequestData=ntdll.NtWriteRequestData,@600") +#pragma comment(linker, "/EXPORT:NtWriteVirtualMemory=ntdll.NtWriteVirtualMemory,@601") +#pragma comment(linker, "/EXPORT:NtYieldExecution=ntdll.NtYieldExecution,@602") +#pragma comment(linker, "/EXPORT:NtdllDefWindowProc_A=ntdll.NtdllDefWindowProc_A,@603") +#pragma comment(linker, "/EXPORT:NtdllDefWindowProc_W=ntdll.NtdllDefWindowProc_W,@604") +#pragma comment(linker, "/EXPORT:NtdllDialogWndProc_A=ntdll.NtdllDialogWndProc_A,@605") +#pragma comment(linker, "/EXPORT:NtdllDialogWndProc_W=ntdll.NtdllDialogWndProc_W,@606") +#pragma comment(linker, "/EXPORT:PfxFindPrefix=ntdll.PfxFindPrefix,@607") +#pragma comment(linker, "/EXPORT:PfxInitialize=ntdll.PfxInitialize,@608") +#pragma comment(linker, "/EXPORT:PfxInsertPrefix=ntdll.PfxInsertPrefix,@609") +#pragma comment(linker, "/EXPORT:PfxRemovePrefix=ntdll.PfxRemovePrefix,@610") +#pragma comment(linker, "/EXPORT:RtlAbortRXact=ntdll.RtlAbortRXact,@611") +#pragma comment(linker, "/EXPORT:RtlAbsoluteToSelfRelativeSD=ntdll.RtlAbsoluteToSelfRelativeSD,@612") +#pragma comment(linker, "/EXPORT:RtlAcquirePebLock=ntdll.RtlAcquirePebLock,@613") +#pragma comment(linker, "/EXPORT:RtlAcquirePrivilege=ntdll.RtlAcquirePrivilege,@614") +#pragma comment(linker, "/EXPORT:RtlAcquireReleaseSRWLockExclusive=ntdll.RtlAcquireReleaseSRWLockExclusive,@615") +#pragma comment(linker, "/EXPORT:RtlAcquireResourceExclusive=ntdll.RtlAcquireResourceExclusive,@616") +#pragma comment(linker, "/EXPORT:RtlAcquireResourceShared=ntdll.RtlAcquireResourceShared,@617") +#pragma comment(linker, "/EXPORT:RtlAcquireSRWLockExclusive=ntdll.RtlAcquireSRWLockExclusive,@618") +#pragma comment(linker, "/EXPORT:RtlAcquireSRWLockShared=ntdll.RtlAcquireSRWLockShared,@619") +#pragma comment(linker, "/EXPORT:RtlActivateActivationContext=ntdll.RtlActivateActivationContext,@620") +#pragma comment(linker, "/EXPORT:RtlActivateActivationContextEx=ntdll.RtlActivateActivationContextEx,@621") +#pragma comment(linker, "/EXPORT:RtlActivateActivationContextUnsafeFast=ntdll.RtlActivateActivationContextUnsafeFast,@9") +#pragma comment(linker, "/EXPORT:RtlAddAccessAllowedAce=ntdll.RtlAddAccessAllowedAce,@622") +#pragma comment(linker, "/EXPORT:RtlAddAccessAllowedAceEx=ntdll.RtlAddAccessAllowedAceEx,@623") +#pragma comment(linker, "/EXPORT:RtlAddAccessAllowedObjectAce=ntdll.RtlAddAccessAllowedObjectAce,@624") +#pragma comment(linker, "/EXPORT:RtlAddAccessDeniedAce=ntdll.RtlAddAccessDeniedAce,@625") +#pragma comment(linker, "/EXPORT:RtlAddAccessDeniedAceEx=ntdll.RtlAddAccessDeniedAceEx,@626") +#pragma comment(linker, "/EXPORT:RtlAddAccessDeniedObjectAce=ntdll.RtlAddAccessDeniedObjectAce,@627") +#pragma comment(linker, "/EXPORT:RtlAddAce=ntdll.RtlAddAce,@628") +#pragma comment(linker, "/EXPORT:RtlAddActionToRXact=ntdll.RtlAddActionToRXact,@629") +#pragma comment(linker, "/EXPORT:RtlAddAtomToAtomTable=ntdll.RtlAddAtomToAtomTable,@630") +#pragma comment(linker, "/EXPORT:RtlAddAttributeActionToRXact=ntdll.RtlAddAttributeActionToRXact,@631") +#pragma comment(linker, "/EXPORT:RtlAddAuditAccessAce=ntdll.RtlAddAuditAccessAce,@632") +#pragma comment(linker, "/EXPORT:RtlAddAuditAccessAceEx=ntdll.RtlAddAuditAccessAceEx,@633") +#pragma comment(linker, "/EXPORT:RtlAddAuditAccessObjectAce=ntdll.RtlAddAuditAccessObjectAce,@634") +#pragma comment(linker, "/EXPORT:RtlAddCompoundAce=ntdll.RtlAddCompoundAce,@635") +#pragma comment(linker, "/EXPORT:RtlAddIntegrityLabelToBoundaryDescriptor=ntdll.RtlAddIntegrityLabelToBoundaryDescriptor,@636") +#pragma comment(linker, "/EXPORT:RtlAddMandatoryAce=ntdll.RtlAddMandatoryAce,@637") +#pragma comment(linker, "/EXPORT:RtlAddRefActivationContext=ntdll.RtlAddRefActivationContext,@638") +#pragma comment(linker, "/EXPORT:RtlAddRefMemoryStream=ntdll.RtlAddRefMemoryStream,@639") +#pragma comment(linker, "/EXPORT:RtlAddSIDToBoundaryDescriptor=ntdll.RtlAddSIDToBoundaryDescriptor,@640") +#pragma comment(linker, "/EXPORT:RtlAddVectoredContinueHandler=ntdll.RtlAddVectoredContinueHandler,@641") +#pragma comment(linker, "/EXPORT:RtlAddVectoredExceptionHandler=ntdll.RtlAddVectoredExceptionHandler,@642") +#pragma comment(linker, "/EXPORT:RtlAddressInSectionTable=ntdll.RtlAddressInSectionTable,@643") +#pragma comment(linker, "/EXPORT:RtlAdjustPrivilege=ntdll.RtlAdjustPrivilege,@644") +#pragma comment(linker, "/EXPORT:RtlAllocateActivationContextStack=ntdll.RtlAllocateActivationContextStack,@645") +#pragma comment(linker, "/EXPORT:RtlAllocateAndInitializeSid=ntdll.RtlAllocateAndInitializeSid,@646") +#pragma comment(linker, "/EXPORT:RtlAllocateHandle=ntdll.RtlAllocateHandle,@647") +#pragma comment(linker, "/EXPORT:RtlAllocateHeap=ntdll.RtlAllocateHeap,@648") +#pragma comment(linker, "/EXPORT:RtlAllocateMemoryBlockLookaside=ntdll.RtlAllocateMemoryBlockLookaside,@649") +#pragma comment(linker, "/EXPORT:RtlAllocateMemoryZone=ntdll.RtlAllocateMemoryZone,@650") +#pragma comment(linker, "/EXPORT:RtlAnsiCharToUnicodeChar=ntdll.RtlAnsiCharToUnicodeChar,@651") +#pragma comment(linker, "/EXPORT:RtlAnsiStringToUnicodeSize=ntdll.RtlAnsiStringToUnicodeSize,@652") +#pragma comment(linker, "/EXPORT:RtlAnsiStringToUnicodeString=ntdll.RtlAnsiStringToUnicodeString,@653") +#pragma comment(linker, "/EXPORT:RtlAppendAsciizToString=ntdll.RtlAppendAsciizToString,@654") +#pragma comment(linker, "/EXPORT:RtlAppendPathElement=ntdll.RtlAppendPathElement,@655") +#pragma comment(linker, "/EXPORT:RtlAppendStringToString=ntdll.RtlAppendStringToString,@656") +#pragma comment(linker, "/EXPORT:RtlAppendUnicodeStringToString=ntdll.RtlAppendUnicodeStringToString,@657") +#pragma comment(linker, "/EXPORT:RtlAppendUnicodeToString=ntdll.RtlAppendUnicodeToString,@658") +#pragma comment(linker, "/EXPORT:RtlApplicationVerifierStop=ntdll.RtlApplicationVerifierStop,@659") +#pragma comment(linker, "/EXPORT:RtlApplyRXact=ntdll.RtlApplyRXact,@660") +#pragma comment(linker, "/EXPORT:RtlApplyRXactNoFlush=ntdll.RtlApplyRXactNoFlush,@661") +#pragma comment(linker, "/EXPORT:RtlAreAllAccessesGranted=ntdll.RtlAreAllAccessesGranted,@662") +#pragma comment(linker, "/EXPORT:RtlAreAnyAccessesGranted=ntdll.RtlAreAnyAccessesGranted,@663") +#pragma comment(linker, "/EXPORT:RtlAreBitsClear=ntdll.RtlAreBitsClear,@664") +#pragma comment(linker, "/EXPORT:RtlAreBitsSet=ntdll.RtlAreBitsSet,@665") +#pragma comment(linker, "/EXPORT:RtlAssert=ntdll.RtlAssert,@666") +#pragma comment(linker, "/EXPORT:RtlBarrier=ntdll.RtlBarrier,@667") +#pragma comment(linker, "/EXPORT:RtlBarrierForDelete=ntdll.RtlBarrierForDelete,@668") +#pragma comment(linker, "/EXPORT:RtlCancelTimer=ntdll.RtlCancelTimer,@669") +#pragma comment(linker, "/EXPORT:RtlCaptureContext=ntdll.RtlCaptureContext,@670") +#pragma comment(linker, "/EXPORT:RtlCaptureStackBackTrace=ntdll.RtlCaptureStackBackTrace,@671") +#pragma comment(linker, "/EXPORT:RtlCaptureStackContext=ntdll.RtlCaptureStackContext,@672") +#pragma comment(linker, "/EXPORT:RtlCharToInteger=ntdll.RtlCharToInteger,@673") +#pragma comment(linker, "/EXPORT:RtlCheckForOrphanedCriticalSections=ntdll.RtlCheckForOrphanedCriticalSections,@674") +#pragma comment(linker, "/EXPORT:RtlCheckRegistryKey=ntdll.RtlCheckRegistryKey,@675") +#pragma comment(linker, "/EXPORT:RtlCheckSandboxedToken=ntdll.RtlCheckSandboxedToken,@676") +#pragma comment(linker, "/EXPORT:RtlCleanUpTEBLangLists=ntdll.RtlCleanUpTEBLangLists,@677") +#pragma comment(linker, "/EXPORT:RtlClearAllBits=ntdll.RtlClearAllBits,@678") +#pragma comment(linker, "/EXPORT:RtlClearBits=ntdll.RtlClearBits,@679") +#pragma comment(linker, "/EXPORT:RtlCloneMemoryStream=ntdll.RtlCloneMemoryStream,@680") +#pragma comment(linker, "/EXPORT:RtlCloneUserProcess=ntdll.RtlCloneUserProcess,@681") +#pragma comment(linker, "/EXPORT:RtlCmDecodeMemIoResource=ntdll.RtlCmDecodeMemIoResource,@682") +#pragma comment(linker, "/EXPORT:RtlCmEncodeMemIoResource=ntdll.RtlCmEncodeMemIoResource,@683") +#pragma comment(linker, "/EXPORT:RtlCommitDebugInfo=ntdll.RtlCommitDebugInfo,@684") +#pragma comment(linker, "/EXPORT:RtlCommitMemoryStream=ntdll.RtlCommitMemoryStream,@685") +#pragma comment(linker, "/EXPORT:RtlCompactHeap=ntdll.RtlCompactHeap,@686") +#pragma comment(linker, "/EXPORT:RtlCompareAltitudes=ntdll.RtlCompareAltitudes,@687") +#pragma comment(linker, "/EXPORT:RtlCompareMemory=ntdll.RtlCompareMemory,@688") +#pragma comment(linker, "/EXPORT:RtlCompareMemoryUlong=ntdll.RtlCompareMemoryUlong,@689") +#pragma comment(linker, "/EXPORT:RtlCompareString=ntdll.RtlCompareString,@690") +#pragma comment(linker, "/EXPORT:RtlCompareUnicodeString=ntdll.RtlCompareUnicodeString,@691") +#pragma comment(linker, "/EXPORT:RtlCompareUnicodeStrings=ntdll.RtlCompareUnicodeStrings,@692") +#pragma comment(linker, "/EXPORT:RtlCompressBuffer=ntdll.RtlCompressBuffer,@693") +#pragma comment(linker, "/EXPORT:RtlComputeCrc32=ntdll.RtlComputeCrc32,@694") +#pragma comment(linker, "/EXPORT:RtlComputeImportTableHash=ntdll.RtlComputeImportTableHash,@695") +#pragma comment(linker, "/EXPORT:RtlComputePrivatizedDllName_U=ntdll.RtlComputePrivatizedDllName_U,@696") +#pragma comment(linker, "/EXPORT:RtlConnectToSm=ntdll.RtlConnectToSm,@697") +#pragma comment(linker, "/EXPORT:RtlConsoleMultiByteToUnicodeN=ntdll.RtlConsoleMultiByteToUnicodeN,@698") +#pragma comment(linker, "/EXPORT:RtlContractHashTable=ntdll.RtlContractHashTable,@699") +#pragma comment(linker, "/EXPORT:RtlConvertExclusiveToShared=ntdll.RtlConvertExclusiveToShared,@700") +#pragma comment(linker, "/EXPORT:RtlConvertLCIDToString=ntdll.RtlConvertLCIDToString,@701") +#pragma comment(linker, "/EXPORT:RtlConvertLongToLargeInteger=ntdll.RtlConvertLongToLargeInteger,@702") +#pragma comment(linker, "/EXPORT:RtlConvertSharedToExclusive=ntdll.RtlConvertSharedToExclusive,@703") +#pragma comment(linker, "/EXPORT:RtlConvertSidToUnicodeString=ntdll.RtlConvertSidToUnicodeString,@704") +#pragma comment(linker, "/EXPORT:RtlConvertToAutoInheritSecurityObject=ntdll.RtlConvertToAutoInheritSecurityObject,@705") +#pragma comment(linker, "/EXPORT:RtlConvertUiListToApiList=ntdll.RtlConvertUiListToApiList,@706") +#pragma comment(linker, "/EXPORT:RtlConvertUlongToLargeInteger=ntdll.RtlConvertUlongToLargeInteger,@707") +#pragma comment(linker, "/EXPORT:RtlCopyContext=ntdll.RtlCopyContext,@708") +#pragma comment(linker, "/EXPORT:RtlCopyExtendedContext=ntdll.RtlCopyExtendedContext,@709") +#pragma comment(linker, "/EXPORT:RtlCopyLuid=ntdll.RtlCopyLuid,@710") +#pragma comment(linker, "/EXPORT:RtlCopyLuidAndAttributesArray=ntdll.RtlCopyLuidAndAttributesArray,@711") +#pragma comment(linker, "/EXPORT:RtlCopyMappedMemory=ntdll.RtlCopyMappedMemory,@712") +#pragma comment(linker, "/EXPORT:RtlCopyMemoryStreamTo=ntdll.RtlCopyMemoryStreamTo,@713") +#pragma comment(linker, "/EXPORT:RtlCopyOutOfProcessMemoryStreamTo=ntdll.RtlCopyOutOfProcessMemoryStreamTo,@714") +#pragma comment(linker, "/EXPORT:RtlCopySecurityDescriptor=ntdll.RtlCopySecurityDescriptor,@715") +#pragma comment(linker, "/EXPORT:RtlCopySid=ntdll.RtlCopySid,@716") +#pragma comment(linker, "/EXPORT:RtlCopySidAndAttributesArray=ntdll.RtlCopySidAndAttributesArray,@717") +#pragma comment(linker, "/EXPORT:RtlCopyString=ntdll.RtlCopyString,@718") +#pragma comment(linker, "/EXPORT:RtlCopyUnicodeString=ntdll.RtlCopyUnicodeString,@719") +#pragma comment(linker, "/EXPORT:RtlCreateAcl=ntdll.RtlCreateAcl,@720") +#pragma comment(linker, "/EXPORT:RtlCreateActivationContext=ntdll.RtlCreateActivationContext,@721") +#pragma comment(linker, "/EXPORT:RtlCreateAndSetSD=ntdll.RtlCreateAndSetSD,@722") +#pragma comment(linker, "/EXPORT:RtlCreateAtomTable=ntdll.RtlCreateAtomTable,@723") +#pragma comment(linker, "/EXPORT:RtlCreateBootStatusDataFile=ntdll.RtlCreateBootStatusDataFile,@724") +#pragma comment(linker, "/EXPORT:RtlCreateBoundaryDescriptor=ntdll.RtlCreateBoundaryDescriptor,@725") +#pragma comment(linker, "/EXPORT:RtlCreateEnvironment=ntdll.RtlCreateEnvironment,@726") +#pragma comment(linker, "/EXPORT:RtlCreateEnvironmentEx=ntdll.RtlCreateEnvironmentEx,@727") +#pragma comment(linker, "/EXPORT:RtlCreateHashTable=ntdll.RtlCreateHashTable,@728") +#pragma comment(linker, "/EXPORT:RtlCreateHeap=ntdll.RtlCreateHeap,@729") +#pragma comment(linker, "/EXPORT:RtlCreateMemoryBlockLookaside=ntdll.RtlCreateMemoryBlockLookaside,@730") +#pragma comment(linker, "/EXPORT:RtlCreateMemoryZone=ntdll.RtlCreateMemoryZone,@731") +#pragma comment(linker, "/EXPORT:RtlCreateProcessParameters=ntdll.RtlCreateProcessParameters,@732") +#pragma comment(linker, "/EXPORT:RtlCreateProcessParametersEx=ntdll.RtlCreateProcessParametersEx,@733") +#pragma comment(linker, "/EXPORT:RtlCreateProcessReflection=ntdll.RtlCreateProcessReflection,@734") +#pragma comment(linker, "/EXPORT:RtlCreateQueryDebugBuffer=ntdll.RtlCreateQueryDebugBuffer,@735") +#pragma comment(linker, "/EXPORT:RtlCreateRegistryKey=ntdll.RtlCreateRegistryKey,@736") +#pragma comment(linker, "/EXPORT:RtlCreateSecurityDescriptor=ntdll.RtlCreateSecurityDescriptor,@737") +#pragma comment(linker, "/EXPORT:RtlCreateServiceSid=ntdll.RtlCreateServiceSid,@738") +#pragma comment(linker, "/EXPORT:RtlCreateSystemVolumeInformationFolder=ntdll.RtlCreateSystemVolumeInformationFolder,@739") +#pragma comment(linker, "/EXPORT:RtlCreateTagHeap=ntdll.RtlCreateTagHeap,@740") +#pragma comment(linker, "/EXPORT:RtlCreateTimer=ntdll.RtlCreateTimer,@741") +#pragma comment(linker, "/EXPORT:RtlCreateTimerQueue=ntdll.RtlCreateTimerQueue,@742") +#pragma comment(linker, "/EXPORT:RtlCreateUnicodeString=ntdll.RtlCreateUnicodeString,@743") +#pragma comment(linker, "/EXPORT:RtlCreateUnicodeStringFromAsciiz=ntdll.RtlCreateUnicodeStringFromAsciiz,@744") +#pragma comment(linker, "/EXPORT:RtlCreateUserProcess=ntdll.RtlCreateUserProcess,@745") +#pragma comment(linker, "/EXPORT:RtlCreateUserSecurityObject=ntdll.RtlCreateUserSecurityObject,@746") +#pragma comment(linker, "/EXPORT:RtlCreateUserStack=ntdll.RtlCreateUserStack,@747") +#pragma comment(linker, "/EXPORT:RtlCreateUserThread=ntdll.RtlCreateUserThread,@748") +#pragma comment(linker, "/EXPORT:RtlCreateVirtualAccountSid=ntdll.RtlCreateVirtualAccountSid,@749") +#pragma comment(linker, "/EXPORT:RtlCultureNameToLCID=ntdll.RtlCultureNameToLCID,@750") +#pragma comment(linker, "/EXPORT:RtlCustomCPToUnicodeN=ntdll.RtlCustomCPToUnicodeN,@751") +#pragma comment(linker, "/EXPORT:RtlCutoverTimeToSystemTime=ntdll.RtlCutoverTimeToSystemTime,@752") +#pragma comment(linker, "/EXPORT:RtlDeCommitDebugInfo=ntdll.RtlDeCommitDebugInfo,@753") +#pragma comment(linker, "/EXPORT:RtlDeNormalizeProcessParams=ntdll.RtlDeNormalizeProcessParams,@754") +#pragma comment(linker, "/EXPORT:RtlDeactivateActivationContext=ntdll.RtlDeactivateActivationContext,@755") +#pragma comment(linker, "/EXPORT:RtlDeactivateActivationContextUnsafeFast=ntdll.RtlDeactivateActivationContextUnsafeFast,@10") +#pragma comment(linker, "/EXPORT:RtlDebugPrintTimes=ntdll.RtlDebugPrintTimes,@756") +#pragma comment(linker, "/EXPORT:RtlDecodePointer=ntdll.RtlDecodePointer,@757") +#pragma comment(linker, "/EXPORT:RtlDecodeSystemPointer=ntdll.RtlDecodeSystemPointer,@758") +#pragma comment(linker, "/EXPORT:RtlDecompressBuffer=ntdll.RtlDecompressBuffer,@759") +#pragma comment(linker, "/EXPORT:RtlDecompressFragment=ntdll.RtlDecompressFragment,@760") +#pragma comment(linker, "/EXPORT:RtlDefaultNpAcl=ntdll.RtlDefaultNpAcl,@761") +#pragma comment(linker, "/EXPORT:RtlDelete=ntdll.RtlDelete,@762") +#pragma comment(linker, "/EXPORT:RtlDeleteAce=ntdll.RtlDeleteAce,@763") +#pragma comment(linker, "/EXPORT:RtlDeleteAtomFromAtomTable=ntdll.RtlDeleteAtomFromAtomTable,@764") +#pragma comment(linker, "/EXPORT:RtlDeleteBarrier=ntdll.RtlDeleteBarrier,@765") +#pragma comment(linker, "/EXPORT:RtlDeleteBoundaryDescriptor=ntdll.RtlDeleteBoundaryDescriptor,@766") +#pragma comment(linker, "/EXPORT:RtlDeleteCriticalSection=ntdll.RtlDeleteCriticalSection,@767") +#pragma comment(linker, "/EXPORT:RtlDeleteElementGenericTable=ntdll.RtlDeleteElementGenericTable,@768") +#pragma comment(linker, "/EXPORT:RtlDeleteElementGenericTableAvl=ntdll.RtlDeleteElementGenericTableAvl,@769") +#pragma comment(linker, "/EXPORT:RtlDeleteHashTable=ntdll.RtlDeleteHashTable,@770") +#pragma comment(linker, "/EXPORT:RtlDeleteNoSplay=ntdll.RtlDeleteNoSplay,@771") +#pragma comment(linker, "/EXPORT:RtlDeleteRegistryValue=ntdll.RtlDeleteRegistryValue,@772") +#pragma comment(linker, "/EXPORT:RtlDeleteResource=ntdll.RtlDeleteResource,@773") +#pragma comment(linker, "/EXPORT:RtlDeleteSecurityObject=ntdll.RtlDeleteSecurityObject,@774") +#pragma comment(linker, "/EXPORT:RtlDeleteTimer=ntdll.RtlDeleteTimer,@775") +#pragma comment(linker, "/EXPORT:RtlDeleteTimerQueue=ntdll.RtlDeleteTimerQueue,@776") +#pragma comment(linker, "/EXPORT:RtlDeleteTimerQueueEx=ntdll.RtlDeleteTimerQueueEx,@777") +#pragma comment(linker, "/EXPORT:RtlDeregisterSecureMemoryCacheCallback=ntdll.RtlDeregisterSecureMemoryCacheCallback,@778") +#pragma comment(linker, "/EXPORT:RtlDeregisterWait=ntdll.RtlDeregisterWait,@779") +#pragma comment(linker, "/EXPORT:RtlDeregisterWaitEx=ntdll.RtlDeregisterWaitEx,@780") +#pragma comment(linker, "/EXPORT:RtlDestroyAtomTable=ntdll.RtlDestroyAtomTable,@781") +#pragma comment(linker, "/EXPORT:RtlDestroyEnvironment=ntdll.RtlDestroyEnvironment,@782") +#pragma comment(linker, "/EXPORT:RtlDestroyHandleTable=ntdll.RtlDestroyHandleTable,@783") +#pragma comment(linker, "/EXPORT:RtlDestroyHeap=ntdll.RtlDestroyHeap,@784") +#pragma comment(linker, "/EXPORT:RtlDestroyMemoryBlockLookaside=ntdll.RtlDestroyMemoryBlockLookaside,@785") +#pragma comment(linker, "/EXPORT:RtlDestroyMemoryZone=ntdll.RtlDestroyMemoryZone,@786") +#pragma comment(linker, "/EXPORT:RtlDestroyProcessParameters=ntdll.RtlDestroyProcessParameters,@787") +#pragma comment(linker, "/EXPORT:RtlDestroyQueryDebugBuffer=ntdll.RtlDestroyQueryDebugBuffer,@788") +#pragma comment(linker, "/EXPORT:RtlDetectHeapLeaks=ntdll.RtlDetectHeapLeaks,@789") +#pragma comment(linker, "/EXPORT:RtlDetermineDosPathNameType_U=ntdll.RtlDetermineDosPathNameType_U,@790") +#pragma comment(linker, "/EXPORT:RtlDisableThreadProfiling=ntdll.RtlDisableThreadProfiling,@791") +#pragma comment(linker, "/EXPORT:RtlDllShutdownInProgress=ntdll.RtlDllShutdownInProgress,@792") +#pragma comment(linker, "/EXPORT:RtlDnsHostNameToComputerName=ntdll.RtlDnsHostNameToComputerName,@793") +#pragma comment(linker, "/EXPORT:RtlDoesFileExists_U=ntdll.RtlDoesFileExists_U,@794") +#pragma comment(linker, "/EXPORT:RtlDosApplyFileIsolationRedirection_Ustr=ntdll.RtlDosApplyFileIsolationRedirection_Ustr,@795") +#pragma comment(linker, "/EXPORT:RtlDosPathNameToNtPathName_U=ntdll.RtlDosPathNameToNtPathName_U,@796") +#pragma comment(linker, "/EXPORT:RtlDosPathNameToNtPathName_U_WithStatus=ntdll.RtlDosPathNameToNtPathName_U_WithStatus,@797") +#pragma comment(linker, "/EXPORT:RtlDosPathNameToRelativeNtPathName_U=ntdll.RtlDosPathNameToRelativeNtPathName_U,@798") +#pragma comment(linker, "/EXPORT:RtlDosPathNameToRelativeNtPathName_U_WithStatus=ntdll.RtlDosPathNameToRelativeNtPathName_U_WithStatus,@799") +#pragma comment(linker, "/EXPORT:RtlDosSearchPath_U=ntdll.RtlDosSearchPath_U,@800") +#pragma comment(linker, "/EXPORT:RtlDosSearchPath_Ustr=ntdll.RtlDosSearchPath_Ustr,@801") +#pragma comment(linker, "/EXPORT:RtlDowncaseUnicodeChar=ntdll.RtlDowncaseUnicodeChar,@802") +#pragma comment(linker, "/EXPORT:RtlDowncaseUnicodeString=ntdll.RtlDowncaseUnicodeString,@803") +#pragma comment(linker, "/EXPORT:RtlDumpResource=ntdll.RtlDumpResource,@804") +#pragma comment(linker, "/EXPORT:RtlDuplicateUnicodeString=ntdll.RtlDuplicateUnicodeString,@805") +#pragma comment(linker, "/EXPORT:RtlEmptyAtomTable=ntdll.RtlEmptyAtomTable,@806") +#pragma comment(linker, "/EXPORT:RtlEnableEarlyCriticalSectionEventCreation=ntdll.RtlEnableEarlyCriticalSectionEventCreation,@807") +#pragma comment(linker, "/EXPORT:RtlEnableThreadProfiling=ntdll.RtlEnableThreadProfiling,@808") +#pragma comment(linker, "/EXPORT:RtlEncodePointer=ntdll.RtlEncodePointer,@809") +#pragma comment(linker, "/EXPORT:RtlEncodeSystemPointer=ntdll.RtlEncodeSystemPointer,@810") +#pragma comment(linker, "/EXPORT:RtlEndEnumerationHashTable=ntdll.RtlEndEnumerationHashTable,@811") +#pragma comment(linker, "/EXPORT:RtlEndWeakEnumerationHashTable=ntdll.RtlEndWeakEnumerationHashTable,@812") +#pragma comment(linker, "/EXPORT:RtlEnlargedIntegerMultiply=ntdll.RtlEnlargedIntegerMultiply,@813") +#pragma comment(linker, "/EXPORT:RtlEnlargedUnsignedDivide=ntdll.RtlEnlargedUnsignedDivide,@814") +#pragma comment(linker, "/EXPORT:RtlEnlargedUnsignedMultiply=ntdll.RtlEnlargedUnsignedMultiply,@815") +#pragma comment(linker, "/EXPORT:RtlEnterCriticalSection=ntdll.RtlEnterCriticalSection,@816") +#pragma comment(linker, "/EXPORT:RtlEnumProcessHeaps=ntdll.RtlEnumProcessHeaps,@817") +#pragma comment(linker, "/EXPORT:RtlEnumerateEntryHashTable=ntdll.RtlEnumerateEntryHashTable,@818") +#pragma comment(linker, "/EXPORT:RtlEnumerateGenericTable=ntdll.RtlEnumerateGenericTable,@819") +#pragma comment(linker, "/EXPORT:RtlEnumerateGenericTableAvl=ntdll.RtlEnumerateGenericTableAvl,@820") +#pragma comment(linker, "/EXPORT:RtlEnumerateGenericTableLikeADirectory=ntdll.RtlEnumerateGenericTableLikeADirectory,@821") +#pragma comment(linker, "/EXPORT:RtlEnumerateGenericTableWithoutSplaying=ntdll.RtlEnumerateGenericTableWithoutSplaying,@822") +#pragma comment(linker, "/EXPORT:RtlEnumerateGenericTableWithoutSplayingAvl=ntdll.RtlEnumerateGenericTableWithoutSplayingAvl,@823") +#pragma comment(linker, "/EXPORT:RtlEqualComputerName=ntdll.RtlEqualComputerName,@824") +#pragma comment(linker, "/EXPORT:RtlEqualDomainName=ntdll.RtlEqualDomainName,@825") +#pragma comment(linker, "/EXPORT:RtlEqualLuid=ntdll.RtlEqualLuid,@826") +#pragma comment(linker, "/EXPORT:RtlEqualPrefixSid=ntdll.RtlEqualPrefixSid,@827") +#pragma comment(linker, "/EXPORT:RtlEqualSid=ntdll.RtlEqualSid,@828") +#pragma comment(linker, "/EXPORT:RtlEqualString=ntdll.RtlEqualString,@829") +#pragma comment(linker, "/EXPORT:RtlEqualUnicodeString=ntdll.RtlEqualUnicodeString,@830") +#pragma comment(linker, "/EXPORT:RtlEraseUnicodeString=ntdll.RtlEraseUnicodeString,@831") +#pragma comment(linker, "/EXPORT:RtlEthernetAddressToStringA=ntdll.RtlEthernetAddressToStringA,@832") +#pragma comment(linker, "/EXPORT:RtlEthernetAddressToStringW=ntdll.RtlEthernetAddressToStringW,@833") +#pragma comment(linker, "/EXPORT:RtlEthernetStringToAddressA=ntdll.RtlEthernetStringToAddressA,@834") +#pragma comment(linker, "/EXPORT:RtlEthernetStringToAddressW=ntdll.RtlEthernetStringToAddressW,@835") +#pragma comment(linker, "/EXPORT:RtlExitUserProcess=ntdll.RtlExitUserProcess,@836") +#pragma comment(linker, "/EXPORT:RtlExitUserThread=ntdll.RtlExitUserThread,@837") +#pragma comment(linker, "/EXPORT:RtlExpandEnvironmentStrings=ntdll.RtlExpandEnvironmentStrings,@838") +#pragma comment(linker, "/EXPORT:RtlExpandEnvironmentStrings_U=ntdll.RtlExpandEnvironmentStrings_U,@839") +#pragma comment(linker, "/EXPORT:RtlExpandHashTable=ntdll.RtlExpandHashTable,@840") +#pragma comment(linker, "/EXPORT:RtlExtendMemoryBlockLookaside=ntdll.RtlExtendMemoryBlockLookaside,@841") +#pragma comment(linker, "/EXPORT:RtlExtendMemoryZone=ntdll.RtlExtendMemoryZone,@842") +#pragma comment(linker, "/EXPORT:RtlExtendedIntegerMultiply=ntdll.RtlExtendedIntegerMultiply,@843") +#pragma comment(linker, "/EXPORT:RtlExtendedLargeIntegerDivide=ntdll.RtlExtendedLargeIntegerDivide,@844") +#pragma comment(linker, "/EXPORT:RtlExtendedMagicDivide=ntdll.RtlExtendedMagicDivide,@845") +#pragma comment(linker, "/EXPORT:RtlFillMemory=ntdll.RtlFillMemory,@846") +#pragma comment(linker, "/EXPORT:RtlFillMemoryUlong=ntdll.RtlFillMemoryUlong,@847") +#pragma comment(linker, "/EXPORT:RtlFillMemoryUlonglong=ntdll.RtlFillMemoryUlonglong,@848") +#pragma comment(linker, "/EXPORT:RtlFinalReleaseOutOfProcessMemoryStream=ntdll.RtlFinalReleaseOutOfProcessMemoryStream,@849") +#pragma comment(linker, "/EXPORT:RtlFindAceByType=ntdll.RtlFindAceByType,@850") +#pragma comment(linker, "/EXPORT:RtlFindActivationContextSectionGuid=ntdll.RtlFindActivationContextSectionGuid,@851") +#pragma comment(linker, "/EXPORT:RtlFindActivationContextSectionString=ntdll.RtlFindActivationContextSectionString,@852") +#pragma comment(linker, "/EXPORT:RtlFindCharInUnicodeString=ntdll.RtlFindCharInUnicodeString,@853") +#pragma comment(linker, "/EXPORT:RtlFindClearBits=ntdll.RtlFindClearBits,@854") +#pragma comment(linker, "/EXPORT:RtlFindClearBitsAndSet=ntdll.RtlFindClearBitsAndSet,@855") +#pragma comment(linker, "/EXPORT:RtlFindClearRuns=ntdll.RtlFindClearRuns,@856") +#pragma comment(linker, "/EXPORT:RtlFindClosestEncodableLength=ntdll.RtlFindClosestEncodableLength,@857") +#pragma comment(linker, "/EXPORT:RtlFindLastBackwardRunClear=ntdll.RtlFindLastBackwardRunClear,@858") +#pragma comment(linker, "/EXPORT:RtlFindLeastSignificantBit=ntdll.RtlFindLeastSignificantBit,@859") +#pragma comment(linker, "/EXPORT:RtlFindLongestRunClear=ntdll.RtlFindLongestRunClear,@860") +#pragma comment(linker, "/EXPORT:RtlFindMessage=ntdll.RtlFindMessage,@861") +#pragma comment(linker, "/EXPORT:RtlFindMostSignificantBit=ntdll.RtlFindMostSignificantBit,@862") +#pragma comment(linker, "/EXPORT:RtlFindNextForwardRunClear=ntdll.RtlFindNextForwardRunClear,@863") +#pragma comment(linker, "/EXPORT:RtlFindSetBits=ntdll.RtlFindSetBits,@864") +#pragma comment(linker, "/EXPORT:RtlFindSetBitsAndClear=ntdll.RtlFindSetBitsAndClear,@865") +#pragma comment(linker, "/EXPORT:RtlFirstEntrySList=ntdll.RtlFirstEntrySList,@866") +#pragma comment(linker, "/EXPORT:RtlFirstFreeAce=ntdll.RtlFirstFreeAce,@867") +#pragma comment(linker, "/EXPORT:RtlFlsAlloc=ntdll.RtlFlsAlloc,@868") +#pragma comment(linker, "/EXPORT:RtlFlsFree=ntdll.RtlFlsFree,@869") +#pragma comment(linker, "/EXPORT:RtlFlushSecureMemoryCache=ntdll.RtlFlushSecureMemoryCache,@870") +#pragma comment(linker, "/EXPORT:RtlFormatCurrentUserKeyPath=ntdll.RtlFormatCurrentUserKeyPath,@871") +#pragma comment(linker, "/EXPORT:RtlFormatMessage=ntdll.RtlFormatMessage,@872") +#pragma comment(linker, "/EXPORT:RtlFormatMessageEx=ntdll.RtlFormatMessageEx,@873") +#pragma comment(linker, "/EXPORT:RtlFreeActivationContextStack=ntdll.RtlFreeActivationContextStack,@874") +#pragma comment(linker, "/EXPORT:RtlFreeAnsiString=ntdll.RtlFreeAnsiString,@875") +#pragma comment(linker, "/EXPORT:RtlFreeHandle=ntdll.RtlFreeHandle,@876") +#pragma comment(linker, "/EXPORT:RtlFreeHeap=ntdll.RtlFreeHeap,@877") +#pragma comment(linker, "/EXPORT:RtlFreeMemoryBlockLookaside=ntdll.RtlFreeMemoryBlockLookaside,@878") +#pragma comment(linker, "/EXPORT:RtlFreeOemString=ntdll.RtlFreeOemString,@879") +#pragma comment(linker, "/EXPORT:RtlFreeSid=ntdll.RtlFreeSid,@880") +#pragma comment(linker, "/EXPORT:RtlFreeThreadActivationContextStack=ntdll.RtlFreeThreadActivationContextStack,@881") +#pragma comment(linker, "/EXPORT:RtlFreeUnicodeString=ntdll.RtlFreeUnicodeString,@882") +#pragma comment(linker, "/EXPORT:RtlFreeUserStack=ntdll.RtlFreeUserStack,@883") +#pragma comment(linker, "/EXPORT:RtlGUIDFromString=ntdll.RtlGUIDFromString,@884") +#pragma comment(linker, "/EXPORT:RtlGenerate8dot3Name=ntdll.RtlGenerate8dot3Name,@885") +#pragma comment(linker, "/EXPORT:RtlGetAce=ntdll.RtlGetAce,@886") +#pragma comment(linker, "/EXPORT:RtlGetActiveActivationContext=ntdll.RtlGetActiveActivationContext,@887") +#pragma comment(linker, "/EXPORT:RtlGetCallersAddress=ntdll.RtlGetCallersAddress,@888") +#pragma comment(linker, "/EXPORT:RtlGetCompressionWorkSpaceSize=ntdll.RtlGetCompressionWorkSpaceSize,@889") +#pragma comment(linker, "/EXPORT:RtlGetControlSecurityDescriptor=ntdll.RtlGetControlSecurityDescriptor,@890") +#pragma comment(linker, "/EXPORT:RtlGetCriticalSectionRecursionCount=ntdll.RtlGetCriticalSectionRecursionCount,@891") +#pragma comment(linker, "/EXPORT:RtlGetCurrentDirectory_U=ntdll.RtlGetCurrentDirectory_U,@892") +#pragma comment(linker, "/EXPORT:RtlGetCurrentPeb=ntdll.RtlGetCurrentPeb,@893") +#pragma comment(linker, "/EXPORT:RtlGetCurrentProcessorNumber=ntdll.RtlGetCurrentProcessorNumber,@894") +#pragma comment(linker, "/EXPORT:RtlGetCurrentProcessorNumberEx=ntdll.RtlGetCurrentProcessorNumberEx,@895") +#pragma comment(linker, "/EXPORT:RtlGetCurrentTransaction=ntdll.RtlGetCurrentTransaction,@896") +#pragma comment(linker, "/EXPORT:RtlGetDaclSecurityDescriptor=ntdll.RtlGetDaclSecurityDescriptor,@897") +#pragma comment(linker, "/EXPORT:RtlGetElementGenericTable=ntdll.RtlGetElementGenericTable,@898") +#pragma comment(linker, "/EXPORT:RtlGetElementGenericTableAvl=ntdll.RtlGetElementGenericTableAvl,@899") +#pragma comment(linker, "/EXPORT:RtlGetEnabledExtendedFeatures=ntdll.RtlGetEnabledExtendedFeatures,@900") +#pragma comment(linker, "/EXPORT:RtlGetExtendedContextLength=ntdll.RtlGetExtendedContextLength,@901") +#pragma comment(linker, "/EXPORT:RtlGetExtendedFeaturesMask=ntdll.RtlGetExtendedFeaturesMask,@902") +#pragma comment(linker, "/EXPORT:RtlGetFileMUIPath=ntdll.RtlGetFileMUIPath,@903") +#pragma comment(linker, "/EXPORT:RtlGetFrame=ntdll.RtlGetFrame,@904") +#pragma comment(linker, "/EXPORT:RtlGetFullPathName_U=ntdll.RtlGetFullPathName_U,@905") +#pragma comment(linker, "/EXPORT:RtlGetFullPathName_UEx=ntdll.RtlGetFullPathName_UEx,@906") +#pragma comment(linker, "/EXPORT:RtlGetFullPathName_UstrEx=ntdll.RtlGetFullPathName_UstrEx,@907") +#pragma comment(linker, "/EXPORT:RtlGetGroupSecurityDescriptor=ntdll.RtlGetGroupSecurityDescriptor,@908") +#pragma comment(linker, "/EXPORT:RtlGetIntegerAtom=ntdll.RtlGetIntegerAtom,@909") +#pragma comment(linker, "/EXPORT:RtlGetLastNtStatus=ntdll.RtlGetLastNtStatus,@910") +#pragma comment(linker, "/EXPORT:RtlGetLastWin32Error=ntdll.RtlGetLastWin32Error,@911") +#pragma comment(linker, "/EXPORT:RtlGetLengthWithoutLastFullDosOrNtPathElement=ntdll.RtlGetLengthWithoutLastFullDosOrNtPathElement,@912") +#pragma comment(linker, "/EXPORT:RtlGetLengthWithoutTrailingPathSeperators=ntdll.RtlGetLengthWithoutTrailingPathSeperators,@913") +#pragma comment(linker, "/EXPORT:RtlGetLocaleFileMappingAddress=ntdll.RtlGetLocaleFileMappingAddress,@914") +#pragma comment(linker, "/EXPORT:RtlGetLongestNtPathLength=ntdll.RtlGetLongestNtPathLength,@915") +#pragma comment(linker, "/EXPORT:RtlGetNativeSystemInformation=ntdll.RtlGetNativeSystemInformation,@916") +#pragma comment(linker, "/EXPORT:RtlGetNextEntryHashTable=ntdll.RtlGetNextEntryHashTable,@917") +#pragma comment(linker, "/EXPORT:RtlGetNtGlobalFlags=ntdll.RtlGetNtGlobalFlags,@918") +#pragma comment(linker, "/EXPORT:RtlGetNtProductType=ntdll.RtlGetNtProductType,@919") +#pragma comment(linker, "/EXPORT:RtlGetNtVersionNumbers=ntdll.RtlGetNtVersionNumbers,@920") +#pragma comment(linker, "/EXPORT:RtlGetOwnerSecurityDescriptor=ntdll.RtlGetOwnerSecurityDescriptor,@921") +#pragma comment(linker, "/EXPORT:RtlGetParentLocaleName=ntdll.RtlGetParentLocaleName,@922") +#pragma comment(linker, "/EXPORT:RtlGetProcessHeaps=ntdll.RtlGetProcessHeaps,@923") +#pragma comment(linker, "/EXPORT:RtlGetProcessPreferredUILanguages=ntdll.RtlGetProcessPreferredUILanguages,@924") +#pragma comment(linker, "/EXPORT:RtlGetProductInfo=ntdll.RtlGetProductInfo,@925") +#pragma comment(linker, "/EXPORT:RtlGetSaclSecurityDescriptor=ntdll.RtlGetSaclSecurityDescriptor,@926") +#pragma comment(linker, "/EXPORT:RtlGetSecurityDescriptorRMControl=ntdll.RtlGetSecurityDescriptorRMControl,@927") +#pragma comment(linker, "/EXPORT:RtlGetSetBootStatusData=ntdll.RtlGetSetBootStatusData,@928") +#pragma comment(linker, "/EXPORT:RtlGetSystemPreferredUILanguages=ntdll.RtlGetSystemPreferredUILanguages,@929") +#pragma comment(linker, "/EXPORT:RtlGetThreadErrorMode=ntdll.RtlGetThreadErrorMode,@930") +#pragma comment(linker, "/EXPORT:RtlGetThreadLangIdByIndex=ntdll.RtlGetThreadLangIdByIndex,@931") +#pragma comment(linker, "/EXPORT:RtlGetThreadPreferredUILanguages=ntdll.RtlGetThreadPreferredUILanguages,@932") +#pragma comment(linker, "/EXPORT:RtlGetUILanguageInfo=ntdll.RtlGetUILanguageInfo,@933") +#pragma comment(linker, "/EXPORT:RtlGetUnloadEventTrace=ntdll.RtlGetUnloadEventTrace,@934") +#pragma comment(linker, "/EXPORT:RtlGetUnloadEventTraceEx=ntdll.RtlGetUnloadEventTraceEx,@935") +#pragma comment(linker, "/EXPORT:RtlGetUserInfoHeap=ntdll.RtlGetUserInfoHeap,@936") +#pragma comment(linker, "/EXPORT:RtlGetUserPreferredUILanguages=ntdll.RtlGetUserPreferredUILanguages,@937") +#pragma comment(linker, "/EXPORT:RtlGetVersion=ntdll.RtlGetVersion,@938") +#pragma comment(linker, "/EXPORT:RtlHashUnicodeString=ntdll.RtlHashUnicodeString,@939") +#pragma comment(linker, "/EXPORT:RtlHeapTrkInitialize=ntdll.RtlHeapTrkInitialize,@940") +#pragma comment(linker, "/EXPORT:RtlIdentifierAuthoritySid=ntdll.RtlIdentifierAuthoritySid,@941") +#pragma comment(linker, "/EXPORT:RtlIdnToAscii=ntdll.RtlIdnToAscii,@942") +#pragma comment(linker, "/EXPORT:RtlIdnToNameprepUnicode=ntdll.RtlIdnToNameprepUnicode,@943") +#pragma comment(linker, "/EXPORT:RtlIdnToUnicode=ntdll.RtlIdnToUnicode,@944") +#pragma comment(linker, "/EXPORT:RtlImageDirectoryEntryToData=ntdll.RtlImageDirectoryEntryToData,@945") +#pragma comment(linker, "/EXPORT:RtlImageNtHeader=ntdll.RtlImageNtHeader,@946") +#pragma comment(linker, "/EXPORT:RtlImageNtHeaderEx=ntdll.RtlImageNtHeaderEx,@947") +#pragma comment(linker, "/EXPORT:RtlImageRvaToSection=ntdll.RtlImageRvaToSection,@948") +#pragma comment(linker, "/EXPORT:RtlImageRvaToVa=ntdll.RtlImageRvaToVa,@949") +#pragma comment(linker, "/EXPORT:RtlImpersonateSelf=ntdll.RtlImpersonateSelf,@950") +#pragma comment(linker, "/EXPORT:RtlImpersonateSelfEx=ntdll.RtlImpersonateSelfEx,@951") +#pragma comment(linker, "/EXPORT:RtlInitAnsiString=ntdll.RtlInitAnsiString,@952") +#pragma comment(linker, "/EXPORT:RtlInitAnsiStringEx=ntdll.RtlInitAnsiStringEx,@953") +#pragma comment(linker, "/EXPORT:RtlInitBarrier=ntdll.RtlInitBarrier,@954") +#pragma comment(linker, "/EXPORT:RtlInitCodePageTable=ntdll.RtlInitCodePageTable,@955") +#pragma comment(linker, "/EXPORT:RtlInitEnumerationHashTable=ntdll.RtlInitEnumerationHashTable,@956") +#pragma comment(linker, "/EXPORT:RtlInitMemoryStream=ntdll.RtlInitMemoryStream,@957") +#pragma comment(linker, "/EXPORT:RtlInitNlsTables=ntdll.RtlInitNlsTables,@958") +#pragma comment(linker, "/EXPORT:RtlInitOutOfProcessMemoryStream=ntdll.RtlInitOutOfProcessMemoryStream,@959") +#pragma comment(linker, "/EXPORT:RtlInitString=ntdll.RtlInitString,@960") +#pragma comment(linker, "/EXPORT:RtlInitUnicodeString=ntdll.RtlInitUnicodeString,@961") +#pragma comment(linker, "/EXPORT:RtlInitUnicodeStringEx=ntdll.RtlInitUnicodeStringEx,@962") +#pragma comment(linker, "/EXPORT:RtlInitWeakEnumerationHashTable=ntdll.RtlInitWeakEnumerationHashTable,@963") +#pragma comment(linker, "/EXPORT:RtlInitializeAtomPackage=ntdll.RtlInitializeAtomPackage,@964") +#pragma comment(linker, "/EXPORT:RtlInitializeBitMap=ntdll.RtlInitializeBitMap,@965") +#pragma comment(linker, "/EXPORT:RtlInitializeConditionVariable=ntdll.RtlInitializeConditionVariable,@966") +#pragma comment(linker, "/EXPORT:RtlInitializeContext=ntdll.RtlInitializeContext,@967") +#pragma comment(linker, "/EXPORT:RtlInitializeCriticalSection=ntdll.RtlInitializeCriticalSection,@968") +#pragma comment(linker, "/EXPORT:RtlInitializeCriticalSectionAndSpinCount=ntdll.RtlInitializeCriticalSectionAndSpinCount,@969") +#pragma comment(linker, "/EXPORT:RtlInitializeCriticalSectionEx=ntdll.RtlInitializeCriticalSectionEx,@970") +#pragma comment(linker, "/EXPORT:RtlInitializeExceptionChain=ntdll.RtlInitializeExceptionChain,@971") +#pragma comment(linker, "/EXPORT:RtlInitializeExtendedContext=ntdll.RtlInitializeExtendedContext,@972") +#pragma comment(linker, "/EXPORT:RtlInitializeGenericTable=ntdll.RtlInitializeGenericTable,@973") +#pragma comment(linker, "/EXPORT:RtlInitializeGenericTableAvl=ntdll.RtlInitializeGenericTableAvl,@974") +#pragma comment(linker, "/EXPORT:RtlInitializeHandleTable=ntdll.RtlInitializeHandleTable,@975") +#pragma comment(linker, "/EXPORT:RtlInitializeNtUserPfn=ntdll.RtlInitializeNtUserPfn,@976") +#pragma comment(linker, "/EXPORT:RtlInitializeRXact=ntdll.RtlInitializeRXact,@977") +#pragma comment(linker, "/EXPORT:RtlInitializeResource=ntdll.RtlInitializeResource,@978") +#pragma comment(linker, "/EXPORT:RtlInitializeSListHead=ntdll.RtlInitializeSListHead,@979") +#pragma comment(linker, "/EXPORT:RtlInitializeSRWLock=ntdll.RtlInitializeSRWLock,@980") +#pragma comment(linker, "/EXPORT:RtlInitializeSid=ntdll.RtlInitializeSid,@981") +#pragma comment(linker, "/EXPORT:RtlInsertElementGenericTable=ntdll.RtlInsertElementGenericTable,@982") +#pragma comment(linker, "/EXPORT:RtlInsertElementGenericTableAvl=ntdll.RtlInsertElementGenericTableAvl,@983") +#pragma comment(linker, "/EXPORT:RtlInsertElementGenericTableFull=ntdll.RtlInsertElementGenericTableFull,@984") +#pragma comment(linker, "/EXPORT:RtlInsertElementGenericTableFullAvl=ntdll.RtlInsertElementGenericTableFullAvl,@985") +#pragma comment(linker, "/EXPORT:RtlInsertEntryHashTable=ntdll.RtlInsertEntryHashTable,@986") +#pragma comment(linker, "/EXPORT:RtlInt64ToUnicodeString=ntdll.RtlInt64ToUnicodeString,@987") +#pragma comment(linker, "/EXPORT:RtlIntegerToChar=ntdll.RtlIntegerToChar,@988") +#pragma comment(linker, "/EXPORT:RtlIntegerToUnicodeString=ntdll.RtlIntegerToUnicodeString,@989") +#pragma comment(linker, "/EXPORT:RtlInterlockedClearBitRun=ntdll.RtlInterlockedClearBitRun,@990") +#pragma comment(linker, "/EXPORT:RtlInterlockedCompareExchange64=ntdll.RtlInterlockedCompareExchange64,@991") +#pragma comment(linker, "/EXPORT:RtlInterlockedFlushSList=ntdll.RtlInterlockedFlushSList,@992") +#pragma comment(linker, "/EXPORT:RtlInterlockedPopEntrySList=ntdll.RtlInterlockedPopEntrySList,@993") +#pragma comment(linker, "/EXPORT:RtlInterlockedPushEntrySList=ntdll.RtlInterlockedPushEntrySList,@994") +#pragma comment(linker, "/EXPORT:RtlInterlockedPushListSList=ntdll.RtlInterlockedPushListSList,@11") +#pragma comment(linker, "/EXPORT:RtlInterlockedSetBitRun=ntdll.RtlInterlockedSetBitRun,@995") +#pragma comment(linker, "/EXPORT:RtlIoDecodeMemIoResource=ntdll.RtlIoDecodeMemIoResource,@996") +#pragma comment(linker, "/EXPORT:RtlIoEncodeMemIoResource=ntdll.RtlIoEncodeMemIoResource,@997") +#pragma comment(linker, "/EXPORT:RtlIpv4AddressToStringA=ntdll.RtlIpv4AddressToStringA,@998") +#pragma comment(linker, "/EXPORT:RtlIpv4AddressToStringExA=ntdll.RtlIpv4AddressToStringExA,@999") +#pragma comment(linker, "/EXPORT:RtlIpv4AddressToStringExW=ntdll.RtlIpv4AddressToStringExW,@1000") +#pragma comment(linker, "/EXPORT:RtlIpv4AddressToStringW=ntdll.RtlIpv4AddressToStringW,@1001") +#pragma comment(linker, "/EXPORT:RtlIpv4StringToAddressA=ntdll.RtlIpv4StringToAddressA,@1002") +#pragma comment(linker, "/EXPORT:RtlIpv4StringToAddressExA=ntdll.RtlIpv4StringToAddressExA,@1003") +#pragma comment(linker, "/EXPORT:RtlIpv4StringToAddressExW=ntdll.RtlIpv4StringToAddressExW,@1004") +#pragma comment(linker, "/EXPORT:RtlIpv4StringToAddressW=ntdll.RtlIpv4StringToAddressW,@1005") +#pragma comment(linker, "/EXPORT:RtlIpv6AddressToStringA=ntdll.RtlIpv6AddressToStringA,@1006") +#pragma comment(linker, "/EXPORT:RtlIpv6AddressToStringExA=ntdll.RtlIpv6AddressToStringExA,@1007") +#pragma comment(linker, "/EXPORT:RtlIpv6AddressToStringExW=ntdll.RtlIpv6AddressToStringExW,@1008") +#pragma comment(linker, "/EXPORT:RtlIpv6AddressToStringW=ntdll.RtlIpv6AddressToStringW,@1009") +#pragma comment(linker, "/EXPORT:RtlIpv6StringToAddressA=ntdll.RtlIpv6StringToAddressA,@1010") +#pragma comment(linker, "/EXPORT:RtlIpv6StringToAddressExA=ntdll.RtlIpv6StringToAddressExA,@1011") +#pragma comment(linker, "/EXPORT:RtlIpv6StringToAddressExW=ntdll.RtlIpv6StringToAddressExW,@1012") +#pragma comment(linker, "/EXPORT:RtlIpv6StringToAddressW=ntdll.RtlIpv6StringToAddressW,@1013") +#pragma comment(linker, "/EXPORT:RtlIsActivationContextActive=ntdll.RtlIsActivationContextActive,@1014") +#pragma comment(linker, "/EXPORT:RtlIsCriticalSectionLocked=ntdll.RtlIsCriticalSectionLocked,@1015") +#pragma comment(linker, "/EXPORT:RtlIsCriticalSectionLockedByThread=ntdll.RtlIsCriticalSectionLockedByThread,@1016") +#pragma comment(linker, "/EXPORT:RtlIsCurrentThreadAttachExempt=ntdll.RtlIsCurrentThreadAttachExempt,@1017") +#pragma comment(linker, "/EXPORT:RtlIsDosDeviceName_U=ntdll.RtlIsDosDeviceName_U,@1018") +#pragma comment(linker, "/EXPORT:RtlIsGenericTableEmpty=ntdll.RtlIsGenericTableEmpty,@1019") +#pragma comment(linker, "/EXPORT:RtlIsGenericTableEmptyAvl=ntdll.RtlIsGenericTableEmptyAvl,@1020") +#pragma comment(linker, "/EXPORT:RtlIsNameInExpression=ntdll.RtlIsNameInExpression,@1021") +#pragma comment(linker, "/EXPORT:RtlIsNameLegalDOS8Dot3=ntdll.RtlIsNameLegalDOS8Dot3,@1022") +#pragma comment(linker, "/EXPORT:RtlIsNormalizedString=ntdll.RtlIsNormalizedString,@1023") +#pragma comment(linker, "/EXPORT:RtlIsTextUnicode=ntdll.RtlIsTextUnicode,@1024") +#pragma comment(linker, "/EXPORT:RtlIsThreadWithinLoaderCallout=ntdll.RtlIsThreadWithinLoaderCallout,@1025") +#pragma comment(linker, "/EXPORT:RtlIsValidHandle=ntdll.RtlIsValidHandle,@1026") +#pragma comment(linker, "/EXPORT:RtlIsValidIndexHandle=ntdll.RtlIsValidIndexHandle,@1027") +#pragma comment(linker, "/EXPORT:RtlIsValidLocaleName=ntdll.RtlIsValidLocaleName,@1028") +#pragma comment(linker, "/EXPORT:RtlKnownExceptionFilter=ntdll.RtlKnownExceptionFilter,@1029") +#pragma comment(linker, "/EXPORT:RtlLCIDToCultureName=ntdll.RtlLCIDToCultureName,@1030") +#pragma comment(linker, "/EXPORT:RtlLargeIntegerAdd=ntdll.RtlLargeIntegerAdd,@1031") +#pragma comment(linker, "/EXPORT:RtlLargeIntegerArithmeticShift=ntdll.RtlLargeIntegerArithmeticShift,@1032") +#pragma comment(linker, "/EXPORT:RtlLargeIntegerDivide=ntdll.RtlLargeIntegerDivide,@1033") +#pragma comment(linker, "/EXPORT:RtlLargeIntegerNegate=ntdll.RtlLargeIntegerNegate,@1034") +#pragma comment(linker, "/EXPORT:RtlLargeIntegerShiftLeft=ntdll.RtlLargeIntegerShiftLeft,@1035") +#pragma comment(linker, "/EXPORT:RtlLargeIntegerShiftRight=ntdll.RtlLargeIntegerShiftRight,@1036") +#pragma comment(linker, "/EXPORT:RtlLargeIntegerSubtract=ntdll.RtlLargeIntegerSubtract,@1037") +#pragma comment(linker, "/EXPORT:RtlLargeIntegerToChar=ntdll.RtlLargeIntegerToChar,@1038") +#pragma comment(linker, "/EXPORT:RtlLcidToLocaleName=ntdll.RtlLcidToLocaleName,@1039") +#pragma comment(linker, "/EXPORT:RtlLeaveCriticalSection=ntdll.RtlLeaveCriticalSection,@1040") +#pragma comment(linker, "/EXPORT:RtlLengthRequiredSid=ntdll.RtlLengthRequiredSid,@1041") +#pragma comment(linker, "/EXPORT:RtlLengthSecurityDescriptor=ntdll.RtlLengthSecurityDescriptor,@1042") +#pragma comment(linker, "/EXPORT:RtlLengthSid=ntdll.RtlLengthSid,@1043") +#pragma comment(linker, "/EXPORT:RtlLoadString=ntdll.RtlLoadString,@1044") +#pragma comment(linker, "/EXPORT:RtlLocalTimeToSystemTime=ntdll.RtlLocalTimeToSystemTime,@1045") +#pragma comment(linker, "/EXPORT:RtlLocaleNameToLcid=ntdll.RtlLocaleNameToLcid,@1046") +#pragma comment(linker, "/EXPORT:RtlLocateExtendedFeature=ntdll.RtlLocateExtendedFeature,@1047") +#pragma comment(linker, "/EXPORT:RtlLocateLegacyContext=ntdll.RtlLocateLegacyContext,@1048") +#pragma comment(linker, "/EXPORT:RtlLockBootStatusData=ntdll.RtlLockBootStatusData,@1049") +#pragma comment(linker, "/EXPORT:RtlLockCurrentThread=ntdll.RtlLockCurrentThread,@1050") +#pragma comment(linker, "/EXPORT:RtlLockHeap=ntdll.RtlLockHeap,@1051") +#pragma comment(linker, "/EXPORT:RtlLockMemoryBlockLookaside=ntdll.RtlLockMemoryBlockLookaside,@1052") +#pragma comment(linker, "/EXPORT:RtlLockMemoryStreamRegion=ntdll.RtlLockMemoryStreamRegion,@1053") +#pragma comment(linker, "/EXPORT:RtlLockMemoryZone=ntdll.RtlLockMemoryZone,@1054") +#pragma comment(linker, "/EXPORT:RtlLockModuleSection=ntdll.RtlLockModuleSection,@1055") +#pragma comment(linker, "/EXPORT:RtlLogStackBackTrace=ntdll.RtlLogStackBackTrace,@1056") +#pragma comment(linker, "/EXPORT:RtlLookupAtomInAtomTable=ntdll.RtlLookupAtomInAtomTable,@1057") +#pragma comment(linker, "/EXPORT:RtlLookupElementGenericTable=ntdll.RtlLookupElementGenericTable,@1058") +#pragma comment(linker, "/EXPORT:RtlLookupElementGenericTableAvl=ntdll.RtlLookupElementGenericTableAvl,@1059") +#pragma comment(linker, "/EXPORT:RtlLookupElementGenericTableFull=ntdll.RtlLookupElementGenericTableFull,@1060") +#pragma comment(linker, "/EXPORT:RtlLookupElementGenericTableFullAvl=ntdll.RtlLookupElementGenericTableFullAvl,@1061") +#pragma comment(linker, "/EXPORT:RtlLookupEntryHashTable=ntdll.RtlLookupEntryHashTable,@1062") +#pragma comment(linker, "/EXPORT:RtlMakeSelfRelativeSD=ntdll.RtlMakeSelfRelativeSD,@1063") +#pragma comment(linker, "/EXPORT:RtlMapGenericMask=ntdll.RtlMapGenericMask,@1064") +#pragma comment(linker, "/EXPORT:RtlMapSecurityErrorToNtStatus=ntdll.RtlMapSecurityErrorToNtStatus,@1065") +#pragma comment(linker, "/EXPORT:RtlMoveMemory=ntdll.RtlMoveMemory,@1066") +#pragma comment(linker, "/EXPORT:RtlMultiAppendUnicodeStringBuffer=ntdll.RtlMultiAppendUnicodeStringBuffer,@1067") +#pragma comment(linker, "/EXPORT:RtlMultiByteToUnicodeN=ntdll.RtlMultiByteToUnicodeN,@1068") +#pragma comment(linker, "/EXPORT:RtlMultiByteToUnicodeSize=ntdll.RtlMultiByteToUnicodeSize,@1069") +#pragma comment(linker, "/EXPORT:RtlMultipleAllocateHeap=ntdll.RtlMultipleAllocateHeap,@1070") +#pragma comment(linker, "/EXPORT:RtlMultipleFreeHeap=ntdll.RtlMultipleFreeHeap,@1071") +#pragma comment(linker, "/EXPORT:RtlNewInstanceSecurityObject=ntdll.RtlNewInstanceSecurityObject,@1072") +#pragma comment(linker, "/EXPORT:RtlNewSecurityGrantedAccess=ntdll.RtlNewSecurityGrantedAccess,@1073") +#pragma comment(linker, "/EXPORT:RtlNewSecurityObject=ntdll.RtlNewSecurityObject,@1074") +#pragma comment(linker, "/EXPORT:RtlNewSecurityObjectEx=ntdll.RtlNewSecurityObjectEx,@1075") +#pragma comment(linker, "/EXPORT:RtlNewSecurityObjectWithMultipleInheritance=ntdll.RtlNewSecurityObjectWithMultipleInheritance,@1076") +#pragma comment(linker, "/EXPORT:RtlNormalizeProcessParams=ntdll.RtlNormalizeProcessParams,@1077") +#pragma comment(linker, "/EXPORT:RtlNormalizeString=ntdll.RtlNormalizeString,@1078") +#pragma comment(linker, "/EXPORT:RtlNtPathNameToDosPathName=ntdll.RtlNtPathNameToDosPathName,@1079") +#pragma comment(linker, "/EXPORT:RtlNtStatusToDosError=ntdll.RtlNtStatusToDosError,@1080") +#pragma comment(linker, "/EXPORT:RtlNtStatusToDosErrorNoTeb=ntdll.RtlNtStatusToDosErrorNoTeb,@1081") +#pragma comment(linker, "/EXPORT:RtlNumberGenericTableElements=ntdll.RtlNumberGenericTableElements,@1082") +#pragma comment(linker, "/EXPORT:RtlNumberGenericTableElementsAvl=ntdll.RtlNumberGenericTableElementsAvl,@1083") +#pragma comment(linker, "/EXPORT:RtlNumberOfClearBits=ntdll.RtlNumberOfClearBits,@1084") +#pragma comment(linker, "/EXPORT:RtlNumberOfSetBits=ntdll.RtlNumberOfSetBits,@1085") +#pragma comment(linker, "/EXPORT:RtlNumberOfSetBitsUlongPtr=ntdll.RtlNumberOfSetBitsUlongPtr,@1086") +#pragma comment(linker, "/EXPORT:RtlOemStringToUnicodeSize=ntdll.RtlOemStringToUnicodeSize,@1087") +#pragma comment(linker, "/EXPORT:RtlOemStringToUnicodeString=ntdll.RtlOemStringToUnicodeString,@1088") +#pragma comment(linker, "/EXPORT:RtlOemToUnicodeN=ntdll.RtlOemToUnicodeN,@1089") +#pragma comment(linker, "/EXPORT:RtlOpenCurrentUser=ntdll.RtlOpenCurrentUser,@1090") +#pragma comment(linker, "/EXPORT:RtlOwnerAcesPresent=ntdll.RtlOwnerAcesPresent,@1091") +#pragma comment(linker, "/EXPORT:RtlPcToFileHeader=ntdll.RtlPcToFileHeader,@1092") +#pragma comment(linker, "/EXPORT:RtlPinAtomInAtomTable=ntdll.RtlPinAtomInAtomTable,@1093") +#pragma comment(linker, "/EXPORT:RtlPopFrame=ntdll.RtlPopFrame,@1094") +#pragma comment(linker, "/EXPORT:RtlPrefixString=ntdll.RtlPrefixString,@1095") +#pragma comment(linker, "/EXPORT:RtlPrefixUnicodeString=ntdll.RtlPrefixUnicodeString,@1096") +#pragma comment(linker, "/EXPORT:RtlProcessFlsData=ntdll.RtlProcessFlsData,@1097") +#pragma comment(linker, "/EXPORT:RtlProtectHeap=ntdll.RtlProtectHeap,@1098") +#pragma comment(linker, "/EXPORT:RtlPushFrame=ntdll.RtlPushFrame,@1099") +#pragma comment(linker, "/EXPORT:RtlQueryActivationContextApplicationSettings=ntdll.RtlQueryActivationContextApplicationSettings,@1100") +#pragma comment(linker, "/EXPORT:RtlQueryAtomInAtomTable=ntdll.RtlQueryAtomInAtomTable,@1101") +#pragma comment(linker, "/EXPORT:RtlQueryCriticalSectionOwner=ntdll.RtlQueryCriticalSectionOwner,@1102") +#pragma comment(linker, "/EXPORT:RtlQueryDepthSList=ntdll.RtlQueryDepthSList,@1103") +#pragma comment(linker, "/EXPORT:RtlQueryDynamicTimeZoneInformation=ntdll.RtlQueryDynamicTimeZoneInformation,@1104") +#pragma comment(linker, "/EXPORT:RtlQueryElevationFlags=ntdll.RtlQueryElevationFlags,@1105") +#pragma comment(linker, "/EXPORT:RtlQueryEnvironmentVariable=ntdll.RtlQueryEnvironmentVariable,@1106") +#pragma comment(linker, "/EXPORT:RtlQueryEnvironmentVariable_U=ntdll.RtlQueryEnvironmentVariable_U,@1107") +#pragma comment(linker, "/EXPORT:RtlQueryHeapInformation=ntdll.RtlQueryHeapInformation,@1108") +#pragma comment(linker, "/EXPORT:RtlQueryInformationAcl=ntdll.RtlQueryInformationAcl,@1109") +#pragma comment(linker, "/EXPORT:RtlQueryInformationActivationContext=ntdll.RtlQueryInformationActivationContext,@1110") +#pragma comment(linker, "/EXPORT:RtlQueryInformationActiveActivationContext=ntdll.RtlQueryInformationActiveActivationContext,@1111") +#pragma comment(linker, "/EXPORT:RtlQueryInterfaceMemoryStream=ntdll.RtlQueryInterfaceMemoryStream,@1112") +#pragma comment(linker, "/EXPORT:RtlQueryModuleInformation=ntdll.RtlQueryModuleInformation,@1113") +#pragma comment(linker, "/EXPORT:RtlQueryPerformanceCounter=ntdll.RtlQueryPerformanceCounter,@1114") +#pragma comment(linker, "/EXPORT:RtlQueryPerformanceFrequency=ntdll.RtlQueryPerformanceFrequency,@1115") +#pragma comment(linker, "/EXPORT:RtlQueryProcessBackTraceInformation=ntdll.RtlQueryProcessBackTraceInformation,@1116") +#pragma comment(linker, "/EXPORT:RtlQueryProcessDebugInformation=ntdll.RtlQueryProcessDebugInformation,@1117") +#pragma comment(linker, "/EXPORT:RtlQueryProcessHeapInformation=ntdll.RtlQueryProcessHeapInformation,@1118") +#pragma comment(linker, "/EXPORT:RtlQueryProcessLockInformation=ntdll.RtlQueryProcessLockInformation,@1119") +#pragma comment(linker, "/EXPORT:RtlQueryRegistryValues=ntdll.RtlQueryRegistryValues,@1120") +#pragma comment(linker, "/EXPORT:RtlQuerySecurityObject=ntdll.RtlQuerySecurityObject,@1121") +#pragma comment(linker, "/EXPORT:RtlQueryTagHeap=ntdll.RtlQueryTagHeap,@1122") +#pragma comment(linker, "/EXPORT:RtlQueryThreadProfiling=ntdll.RtlQueryThreadProfiling,@1123") +#pragma comment(linker, "/EXPORT:RtlQueryTimeZoneInformation=ntdll.RtlQueryTimeZoneInformation,@1124") +#pragma comment(linker, "/EXPORT:RtlQueueApcWow64Thread=ntdll.RtlQueueApcWow64Thread,@1125") +#pragma comment(linker, "/EXPORT:RtlQueueWorkItem=ntdll.RtlQueueWorkItem,@1126") +#pragma comment(linker, "/EXPORT:RtlRaiseException=ntdll.RtlRaiseException,@1127") +#pragma comment(linker, "/EXPORT:RtlRaiseStatus=ntdll.RtlRaiseStatus,@1128") +#pragma comment(linker, "/EXPORT:RtlRandom=ntdll.RtlRandom,@1129") +#pragma comment(linker, "/EXPORT:RtlRandomEx=ntdll.RtlRandomEx,@1130") +#pragma comment(linker, "/EXPORT:RtlReAllocateHeap=ntdll.RtlReAllocateHeap,@1131") +#pragma comment(linker, "/EXPORT:RtlReadMemoryStream=ntdll.RtlReadMemoryStream,@1132") +#pragma comment(linker, "/EXPORT:RtlReadOutOfProcessMemoryStream=ntdll.RtlReadOutOfProcessMemoryStream,@1133") +#pragma comment(linker, "/EXPORT:RtlReadThreadProfilingData=ntdll.RtlReadThreadProfilingData,@1134") +#pragma comment(linker, "/EXPORT:RtlRealPredecessor=ntdll.RtlRealPredecessor,@1135") +#pragma comment(linker, "/EXPORT:RtlRealSuccessor=ntdll.RtlRealSuccessor,@1136") +#pragma comment(linker, "/EXPORT:RtlRegisterSecureMemoryCacheCallback=ntdll.RtlRegisterSecureMemoryCacheCallback,@1137") +#pragma comment(linker, "/EXPORT:RtlRegisterThreadWithCsrss=ntdll.RtlRegisterThreadWithCsrss,@1138") +#pragma comment(linker, "/EXPORT:RtlRegisterWait=ntdll.RtlRegisterWait,@1139") +#pragma comment(linker, "/EXPORT:RtlReleaseActivationContext=ntdll.RtlReleaseActivationContext,@1140") +#pragma comment(linker, "/EXPORT:RtlReleaseMemoryStream=ntdll.RtlReleaseMemoryStream,@1141") +#pragma comment(linker, "/EXPORT:RtlReleasePebLock=ntdll.RtlReleasePebLock,@1142") +#pragma comment(linker, "/EXPORT:RtlReleasePrivilege=ntdll.RtlReleasePrivilege,@1143") +#pragma comment(linker, "/EXPORT:RtlReleaseRelativeName=ntdll.RtlReleaseRelativeName,@1144") +#pragma comment(linker, "/EXPORT:RtlReleaseResource=ntdll.RtlReleaseResource,@1145") +#pragma comment(linker, "/EXPORT:RtlReleaseSRWLockExclusive=ntdll.RtlReleaseSRWLockExclusive,@1146") +#pragma comment(linker, "/EXPORT:RtlReleaseSRWLockShared=ntdll.RtlReleaseSRWLockShared,@1147") +#pragma comment(linker, "/EXPORT:RtlRemoteCall=ntdll.RtlRemoteCall,@1148") +#pragma comment(linker, "/EXPORT:RtlRemoveEntryHashTable=ntdll.RtlRemoveEntryHashTable,@1149") +#pragma comment(linker, "/EXPORT:RtlRemovePrivileges=ntdll.RtlRemovePrivileges,@1150") +#pragma comment(linker, "/EXPORT:RtlRemoveVectoredContinueHandler=ntdll.RtlRemoveVectoredContinueHandler,@1151") +#pragma comment(linker, "/EXPORT:RtlRemoveVectoredExceptionHandler=ntdll.RtlRemoveVectoredExceptionHandler,@1152") +#pragma comment(linker, "/EXPORT:RtlReplaceSidInSd=ntdll.RtlReplaceSidInSd,@1153") +#pragma comment(linker, "/EXPORT:RtlReportException=ntdll.RtlReportException,@1154") +#pragma comment(linker, "/EXPORT:RtlReportSilentProcessExit=ntdll.RtlReportSilentProcessExit,@1155") +#pragma comment(linker, "/EXPORT:RtlReportSqmEscalation=ntdll.RtlReportSqmEscalation,@1156") +#pragma comment(linker, "/EXPORT:RtlResetMemoryBlockLookaside=ntdll.RtlResetMemoryBlockLookaside,@1157") +#pragma comment(linker, "/EXPORT:RtlResetMemoryZone=ntdll.RtlResetMemoryZone,@1158") +#pragma comment(linker, "/EXPORT:RtlResetRtlTranslations=ntdll.RtlResetRtlTranslations,@1159") +#pragma comment(linker, "/EXPORT:RtlRestoreLastWin32Error=ntdll.RtlRestoreLastWin32Error,@1160") +#pragma comment(linker, "/EXPORT:RtlRetrieveNtUserPfn=ntdll.RtlRetrieveNtUserPfn,@1161") +#pragma comment(linker, "/EXPORT:RtlRevertMemoryStream=ntdll.RtlRevertMemoryStream,@1162") +#pragma comment(linker, "/EXPORT:RtlRunDecodeUnicodeString=ntdll.RtlRunDecodeUnicodeString,@1163") +#pragma comment(linker, "/EXPORT:RtlRunEncodeUnicodeString=ntdll.RtlRunEncodeUnicodeString,@1164") +#pragma comment(linker, "/EXPORT:RtlRunOnceBeginInitialize=ntdll.RtlRunOnceBeginInitialize,@1165") +#pragma comment(linker, "/EXPORT:RtlRunOnceComplete=ntdll.RtlRunOnceComplete,@1166") +#pragma comment(linker, "/EXPORT:RtlRunOnceExecuteOnce=ntdll.RtlRunOnceExecuteOnce,@1167") +#pragma comment(linker, "/EXPORT:RtlRunOnceInitialize=ntdll.RtlRunOnceInitialize,@1168") +#pragma comment(linker, "/EXPORT:RtlSecondsSince1970ToTime=ntdll.RtlSecondsSince1970ToTime,@1169") +#pragma comment(linker, "/EXPORT:RtlSecondsSince1980ToTime=ntdll.RtlSecondsSince1980ToTime,@1170") +#pragma comment(linker, "/EXPORT:RtlSeekMemoryStream=ntdll.RtlSeekMemoryStream,@1171") +#pragma comment(linker, "/EXPORT:RtlSelfRelativeToAbsoluteSD=ntdll.RtlSelfRelativeToAbsoluteSD,@1173") +#pragma comment(linker, "/EXPORT:RtlSelfRelativeToAbsoluteSD2=ntdll.RtlSelfRelativeToAbsoluteSD2,@1172") +#pragma comment(linker, "/EXPORT:RtlSendMsgToSm=ntdll.RtlSendMsgToSm,@1174") +#pragma comment(linker, "/EXPORT:RtlSetAllBits=ntdll.RtlSetAllBits,@1175") +#pragma comment(linker, "/EXPORT:RtlSetAttributesSecurityDescriptor=ntdll.RtlSetAttributesSecurityDescriptor,@1176") +#pragma comment(linker, "/EXPORT:RtlSetBits=ntdll.RtlSetBits,@1177") +#pragma comment(linker, "/EXPORT:RtlSetControlSecurityDescriptor=ntdll.RtlSetControlSecurityDescriptor,@1178") +#pragma comment(linker, "/EXPORT:RtlSetCriticalSectionSpinCount=ntdll.RtlSetCriticalSectionSpinCount,@1179") +#pragma comment(linker, "/EXPORT:RtlSetCurrentDirectory_U=ntdll.RtlSetCurrentDirectory_U,@1180") +#pragma comment(linker, "/EXPORT:RtlSetCurrentEnvironment=ntdll.RtlSetCurrentEnvironment,@1181") +#pragma comment(linker, "/EXPORT:RtlSetCurrentTransaction=ntdll.RtlSetCurrentTransaction,@1182") +#pragma comment(linker, "/EXPORT:RtlSetDaclSecurityDescriptor=ntdll.RtlSetDaclSecurityDescriptor,@1183") +#pragma comment(linker, "/EXPORT:RtlSetDynamicTimeZoneInformation=ntdll.RtlSetDynamicTimeZoneInformation,@1184") +#pragma comment(linker, "/EXPORT:RtlSetEnvironmentStrings=ntdll.RtlSetEnvironmentStrings,@1185") +#pragma comment(linker, "/EXPORT:RtlSetEnvironmentVar=ntdll.RtlSetEnvironmentVar,@1186") +#pragma comment(linker, "/EXPORT:RtlSetEnvironmentVariable=ntdll.RtlSetEnvironmentVariable,@1187") +#pragma comment(linker, "/EXPORT:RtlSetExtendedFeaturesMask=ntdll.RtlSetExtendedFeaturesMask,@1188") +#pragma comment(linker, "/EXPORT:RtlSetGroupSecurityDescriptor=ntdll.RtlSetGroupSecurityDescriptor,@1189") +#pragma comment(linker, "/EXPORT:RtlSetHeapInformation=ntdll.RtlSetHeapInformation,@1190") +#pragma comment(linker, "/EXPORT:RtlSetInformationAcl=ntdll.RtlSetInformationAcl,@1191") +#pragma comment(linker, "/EXPORT:RtlSetIoCompletionCallback=ntdll.RtlSetIoCompletionCallback,@1192") +#pragma comment(linker, "/EXPORT:RtlSetLastWin32Error=ntdll.RtlSetLastWin32Error,@1193") +#pragma comment(linker, "/EXPORT:RtlSetLastWin32ErrorAndNtStatusFromNtStatus=ntdll.RtlSetLastWin32ErrorAndNtStatusFromNtStatus,@1194") +#pragma comment(linker, "/EXPORT:RtlSetMemoryStreamSize=ntdll.RtlSetMemoryStreamSize,@1195") +#pragma comment(linker, "/EXPORT:RtlSetOwnerSecurityDescriptor=ntdll.RtlSetOwnerSecurityDescriptor,@1196") +#pragma comment(linker, "/EXPORT:RtlSetProcessDebugInformation=ntdll.RtlSetProcessDebugInformation,@1197") +#pragma comment(linker, "/EXPORT:RtlSetProcessIsCritical=ntdll.RtlSetProcessIsCritical,@1198") +#pragma comment(linker, "/EXPORT:RtlSetProcessPreferredUILanguages=ntdll.RtlSetProcessPreferredUILanguages,@1199") +#pragma comment(linker, "/EXPORT:RtlSetSaclSecurityDescriptor=ntdll.RtlSetSaclSecurityDescriptor,@1200") +#pragma comment(linker, "/EXPORT:RtlSetSecurityDescriptorRMControl=ntdll.RtlSetSecurityDescriptorRMControl,@1201") +#pragma comment(linker, "/EXPORT:RtlSetSecurityObject=ntdll.RtlSetSecurityObject,@1202") +#pragma comment(linker, "/EXPORT:RtlSetSecurityObjectEx=ntdll.RtlSetSecurityObjectEx,@1203") +#pragma comment(linker, "/EXPORT:RtlSetThreadErrorMode=ntdll.RtlSetThreadErrorMode,@1204") +#pragma comment(linker, "/EXPORT:RtlSetThreadIsCritical=ntdll.RtlSetThreadIsCritical,@1205") +#pragma comment(linker, "/EXPORT:RtlSetThreadPoolStartFunc=ntdll.RtlSetThreadPoolStartFunc,@1206") +#pragma comment(linker, "/EXPORT:RtlSetThreadPreferredUILanguages=ntdll.RtlSetThreadPreferredUILanguages,@1207") +#pragma comment(linker, "/EXPORT:RtlSetTimeZoneInformation=ntdll.RtlSetTimeZoneInformation,@1208") +#pragma comment(linker, "/EXPORT:RtlSetTimer=ntdll.RtlSetTimer,@1209") +#pragma comment(linker, "/EXPORT:RtlSetUnhandledExceptionFilter=ntdll.RtlSetUnhandledExceptionFilter,@1210") +#pragma comment(linker, "/EXPORT:RtlSetUserCallbackExceptionFilter=ntdll.RtlSetUserCallbackExceptionFilter,@1211") +#pragma comment(linker, "/EXPORT:RtlSetUserFlagsHeap=ntdll.RtlSetUserFlagsHeap,@1212") +#pragma comment(linker, "/EXPORT:RtlSetUserValueHeap=ntdll.RtlSetUserValueHeap,@1213") +#pragma comment(linker, "/EXPORT:RtlSidDominates=ntdll.RtlSidDominates,@1214") +#pragma comment(linker, "/EXPORT:RtlSidEqualLevel=ntdll.RtlSidEqualLevel,@1215") +#pragma comment(linker, "/EXPORT:RtlSidHashInitialize=ntdll.RtlSidHashInitialize,@1216") +#pragma comment(linker, "/EXPORT:RtlSidHashLookup=ntdll.RtlSidHashLookup,@1217") +#pragma comment(linker, "/EXPORT:RtlSidIsHigherLevel=ntdll.RtlSidIsHigherLevel,@1218") +#pragma comment(linker, "/EXPORT:RtlSizeHeap=ntdll.RtlSizeHeap,@1219") +#pragma comment(linker, "/EXPORT:RtlSleepConditionVariableCS=ntdll.RtlSleepConditionVariableCS,@1220") +#pragma comment(linker, "/EXPORT:RtlSleepConditionVariableSRW=ntdll.RtlSleepConditionVariableSRW,@1221") +#pragma comment(linker, "/EXPORT:RtlSplay=ntdll.RtlSplay,@1222") +#pragma comment(linker, "/EXPORT:RtlStartRXact=ntdll.RtlStartRXact,@1223") +#pragma comment(linker, "/EXPORT:RtlStatMemoryStream=ntdll.RtlStatMemoryStream,@1224") +#pragma comment(linker, "/EXPORT:RtlStringFromGUID=ntdll.RtlStringFromGUID,@1225") +#pragma comment(linker, "/EXPORT:RtlSubAuthorityCountSid=ntdll.RtlSubAuthorityCountSid,@1226") +#pragma comment(linker, "/EXPORT:RtlSubAuthoritySid=ntdll.RtlSubAuthoritySid,@1227") +#pragma comment(linker, "/EXPORT:RtlSubtreePredecessor=ntdll.RtlSubtreePredecessor,@1228") +#pragma comment(linker, "/EXPORT:RtlSubtreeSuccessor=ntdll.RtlSubtreeSuccessor,@1229") +#pragma comment(linker, "/EXPORT:RtlSystemTimeToLocalTime=ntdll.RtlSystemTimeToLocalTime,@1230") +#pragma comment(linker, "/EXPORT:RtlTestBit=ntdll.RtlTestBit,@1231") +#pragma comment(linker, "/EXPORT:RtlTimeFieldsToTime=ntdll.RtlTimeFieldsToTime,@1232") +#pragma comment(linker, "/EXPORT:RtlTimeToElapsedTimeFields=ntdll.RtlTimeToElapsedTimeFields,@1233") +#pragma comment(linker, "/EXPORT:RtlTimeToSecondsSince1970=ntdll.RtlTimeToSecondsSince1970,@1234") +#pragma comment(linker, "/EXPORT:RtlTimeToSecondsSince1980=ntdll.RtlTimeToSecondsSince1980,@1235") +#pragma comment(linker, "/EXPORT:RtlTimeToTimeFields=ntdll.RtlTimeToTimeFields,@1236") +#pragma comment(linker, "/EXPORT:RtlTraceDatabaseAdd=ntdll.RtlTraceDatabaseAdd,@1237") +#pragma comment(linker, "/EXPORT:RtlTraceDatabaseCreate=ntdll.RtlTraceDatabaseCreate,@1238") +#pragma comment(linker, "/EXPORT:RtlTraceDatabaseDestroy=ntdll.RtlTraceDatabaseDestroy,@1239") +#pragma comment(linker, "/EXPORT:RtlTraceDatabaseEnumerate=ntdll.RtlTraceDatabaseEnumerate,@1240") +#pragma comment(linker, "/EXPORT:RtlTraceDatabaseFind=ntdll.RtlTraceDatabaseFind,@1241") +#pragma comment(linker, "/EXPORT:RtlTraceDatabaseLock=ntdll.RtlTraceDatabaseLock,@1242") +#pragma comment(linker, "/EXPORT:RtlTraceDatabaseUnlock=ntdll.RtlTraceDatabaseUnlock,@1243") +#pragma comment(linker, "/EXPORT:RtlTraceDatabaseValidate=ntdll.RtlTraceDatabaseValidate,@1244") +#pragma comment(linker, "/EXPORT:RtlTryAcquirePebLock=ntdll.RtlTryAcquirePebLock,@1245") +#pragma comment(linker, "/EXPORT:RtlTryAcquireSRWLockExclusive=ntdll.RtlTryAcquireSRWLockExclusive,@1246") +#pragma comment(linker, "/EXPORT:RtlTryAcquireSRWLockShared=ntdll.RtlTryAcquireSRWLockShared,@1247") +#pragma comment(linker, "/EXPORT:RtlTryEnterCriticalSection=ntdll.RtlTryEnterCriticalSection,@1248") +#pragma comment(linker, "/EXPORT:RtlUTF8ToUnicodeN=ntdll.RtlUTF8ToUnicodeN,@1249") +#pragma comment(linker, "/EXPORT:RtlUlongByteSwap=ntdll.RtlUlongByteSwap,@12") +#pragma comment(linker, "/EXPORT:RtlUlonglongByteSwap=ntdll.RtlUlonglongByteSwap,@13") +#pragma comment(linker, "/EXPORT:RtlUnhandledExceptionFilter=ntdll.RtlUnhandledExceptionFilter,@1251") +#pragma comment(linker, "/EXPORT:RtlUnhandledExceptionFilter2=ntdll.RtlUnhandledExceptionFilter2,@1250") +#pragma comment(linker, "/EXPORT:RtlUnicodeStringToAnsiSize=ntdll.RtlUnicodeStringToAnsiSize,@1252") +#pragma comment(linker, "/EXPORT:RtlUnicodeStringToAnsiString=ntdll.RtlUnicodeStringToAnsiString,@1253") +#pragma comment(linker, "/EXPORT:RtlUnicodeStringToCountedOemString=ntdll.RtlUnicodeStringToCountedOemString,@1254") +#pragma comment(linker, "/EXPORT:RtlUnicodeStringToInteger=ntdll.RtlUnicodeStringToInteger,@1255") +#pragma comment(linker, "/EXPORT:RtlUnicodeStringToOemSize=ntdll.RtlUnicodeStringToOemSize,@1256") +#pragma comment(linker, "/EXPORT:RtlUnicodeStringToOemString=ntdll.RtlUnicodeStringToOemString,@1257") +#pragma comment(linker, "/EXPORT:RtlUnicodeToCustomCPN=ntdll.RtlUnicodeToCustomCPN,@1258") +#pragma comment(linker, "/EXPORT:RtlUnicodeToMultiByteN=ntdll.RtlUnicodeToMultiByteN,@1259") +#pragma comment(linker, "/EXPORT:RtlUnicodeToMultiByteSize=ntdll.RtlUnicodeToMultiByteSize,@1260") +#pragma comment(linker, "/EXPORT:RtlUnicodeToOemN=ntdll.RtlUnicodeToOemN,@1261") +#pragma comment(linker, "/EXPORT:RtlUnicodeToUTF8N=ntdll.RtlUnicodeToUTF8N,@1262") +#pragma comment(linker, "/EXPORT:RtlUniform=ntdll.RtlUniform,@1263") +#pragma comment(linker, "/EXPORT:RtlUnlockBootStatusData=ntdll.RtlUnlockBootStatusData,@1264") +#pragma comment(linker, "/EXPORT:RtlUnlockCurrentThread=ntdll.RtlUnlockCurrentThread,@1265") +#pragma comment(linker, "/EXPORT:RtlUnlockHeap=ntdll.RtlUnlockHeap,@1266") +#pragma comment(linker, "/EXPORT:RtlUnlockMemoryBlockLookaside=ntdll.RtlUnlockMemoryBlockLookaside,@1267") +#pragma comment(linker, "/EXPORT:RtlUnlockMemoryStreamRegion=ntdll.RtlUnlockMemoryStreamRegion,@1268") +#pragma comment(linker, "/EXPORT:RtlUnlockMemoryZone=ntdll.RtlUnlockMemoryZone,@1269") +#pragma comment(linker, "/EXPORT:RtlUnlockModuleSection=ntdll.RtlUnlockModuleSection,@1270") +#pragma comment(linker, "/EXPORT:RtlUnwind=ntdll.RtlUnwind,@1271") +#pragma comment(linker, "/EXPORT:RtlUpcaseUnicodeChar=ntdll.RtlUpcaseUnicodeChar,@1272") +#pragma comment(linker, "/EXPORT:RtlUpcaseUnicodeString=ntdll.RtlUpcaseUnicodeString,@1273") +#pragma comment(linker, "/EXPORT:RtlUpcaseUnicodeStringToAnsiString=ntdll.RtlUpcaseUnicodeStringToAnsiString,@1274") +#pragma comment(linker, "/EXPORT:RtlUpcaseUnicodeStringToCountedOemString=ntdll.RtlUpcaseUnicodeStringToCountedOemString,@1275") +#pragma comment(linker, "/EXPORT:RtlUpcaseUnicodeStringToOemString=ntdll.RtlUpcaseUnicodeStringToOemString,@1276") +#pragma comment(linker, "/EXPORT:RtlUpcaseUnicodeToCustomCPN=ntdll.RtlUpcaseUnicodeToCustomCPN,@1277") +#pragma comment(linker, "/EXPORT:RtlUpcaseUnicodeToMultiByteN=ntdll.RtlUpcaseUnicodeToMultiByteN,@1278") +#pragma comment(linker, "/EXPORT:RtlUpcaseUnicodeToOemN=ntdll.RtlUpcaseUnicodeToOemN,@1279") +#pragma comment(linker, "/EXPORT:RtlUpdateClonedCriticalSection=ntdll.RtlUpdateClonedCriticalSection,@1280") +#pragma comment(linker, "/EXPORT:RtlUpdateClonedSRWLock=ntdll.RtlUpdateClonedSRWLock,@1281") +#pragma comment(linker, "/EXPORT:RtlUpdateTimer=ntdll.RtlUpdateTimer,@1282") +#pragma comment(linker, "/EXPORT:RtlUpperChar=ntdll.RtlUpperChar,@1283") +#pragma comment(linker, "/EXPORT:RtlUpperString=ntdll.RtlUpperString,@1284") +#pragma comment(linker, "/EXPORT:RtlUserThreadStart=ntdll.RtlUserThreadStart,@1285") +#pragma comment(linker, "/EXPORT:RtlUshortByteSwap=ntdll.RtlUshortByteSwap,@14") +#pragma comment(linker, "/EXPORT:RtlValidAcl=ntdll.RtlValidAcl,@1286") +#pragma comment(linker, "/EXPORT:RtlValidRelativeSecurityDescriptor=ntdll.RtlValidRelativeSecurityDescriptor,@1287") +#pragma comment(linker, "/EXPORT:RtlValidSecurityDescriptor=ntdll.RtlValidSecurityDescriptor,@1288") +#pragma comment(linker, "/EXPORT:RtlValidSid=ntdll.RtlValidSid,@1289") +#pragma comment(linker, "/EXPORT:RtlValidateHeap=ntdll.RtlValidateHeap,@1290") +#pragma comment(linker, "/EXPORT:RtlValidateProcessHeaps=ntdll.RtlValidateProcessHeaps,@1291") +#pragma comment(linker, "/EXPORT:RtlValidateUnicodeString=ntdll.RtlValidateUnicodeString,@1292") +#pragma comment(linker, "/EXPORT:RtlVerifyVersionInfo=ntdll.RtlVerifyVersionInfo,@1293") +#pragma comment(linker, "/EXPORT:RtlWakeAllConditionVariable=ntdll.RtlWakeAllConditionVariable,@1294") +#pragma comment(linker, "/EXPORT:RtlWakeConditionVariable=ntdll.RtlWakeConditionVariable,@1295") +#pragma comment(linker, "/EXPORT:RtlWalkFrameChain=ntdll.RtlWalkFrameChain,@1296") +#pragma comment(linker, "/EXPORT:RtlWalkHeap=ntdll.RtlWalkHeap,@1297") +#pragma comment(linker, "/EXPORT:RtlWeaklyEnumerateEntryHashTable=ntdll.RtlWeaklyEnumerateEntryHashTable,@1298") +#pragma comment(linker, "/EXPORT:RtlWerpReportException=ntdll.RtlWerpReportException,@1299") +#pragma comment(linker, "/EXPORT:RtlWow64CallFunction64=ntdll.RtlWow64CallFunction64,@1300") +#pragma comment(linker, "/EXPORT:RtlWow64EnableFsRedirection=ntdll.RtlWow64EnableFsRedirection,@1301") +#pragma comment(linker, "/EXPORT:RtlWow64EnableFsRedirectionEx=ntdll.RtlWow64EnableFsRedirectionEx,@1302") +#pragma comment(linker, "/EXPORT:RtlWow64LogMessageInEventLogger=ntdll.RtlWow64LogMessageInEventLogger,@1303") +#pragma comment(linker, "/EXPORT:RtlWriteMemoryStream=ntdll.RtlWriteMemoryStream,@1304") +#pragma comment(linker, "/EXPORT:RtlWriteRegistryValue=ntdll.RtlWriteRegistryValue,@1305") +#pragma comment(linker, "/EXPORT:RtlZeroHeap=ntdll.RtlZeroHeap,@1306") +#pragma comment(linker, "/EXPORT:RtlZeroMemory=ntdll.RtlZeroMemory,@1307") +#pragma comment(linker, "/EXPORT:RtlZombifyActivationContext=ntdll.RtlZombifyActivationContext,@1308") +#pragma comment(linker, "/EXPORT:RtlpApplyLengthFunction=ntdll.RtlpApplyLengthFunction,@1309") +#pragma comment(linker, "/EXPORT:RtlpCheckDynamicTimeZoneInformation=ntdll.RtlpCheckDynamicTimeZoneInformation,@1310") +#pragma comment(linker, "/EXPORT:RtlpCleanupRegistryKeys=ntdll.RtlpCleanupRegistryKeys,@1311") +#pragma comment(linker, "/EXPORT:RtlpConvertCultureNamesToLCIDs=ntdll.RtlpConvertCultureNamesToLCIDs,@1312") +#pragma comment(linker, "/EXPORT:RtlpConvertLCIDsToCultureNames=ntdll.RtlpConvertLCIDsToCultureNames,@1313") +#pragma comment(linker, "/EXPORT:RtlpCreateProcessRegistryInfo=ntdll.RtlpCreateProcessRegistryInfo,@1314") +#pragma comment(linker, "/EXPORT:RtlpEnsureBufferSize=ntdll.RtlpEnsureBufferSize,@1315") +#pragma comment(linker, "/EXPORT:RtlpGetLCIDFromLangInfoNode=ntdll.RtlpGetLCIDFromLangInfoNode,@1316") +#pragma comment(linker, "/EXPORT:RtlpGetNameFromLangInfoNode=ntdll.RtlpGetNameFromLangInfoNode,@1317") +#pragma comment(linker, "/EXPORT:RtlpGetSystemDefaultUILanguage=ntdll.RtlpGetSystemDefaultUILanguage,@1318") +#pragma comment(linker, "/EXPORT:RtlpGetUserOrMachineUILanguage4NLS=ntdll.RtlpGetUserOrMachineUILanguage4NLS,@1319") +#pragma comment(linker, "/EXPORT:RtlpInitializeLangRegistryInfo=ntdll.RtlpInitializeLangRegistryInfo,@1320") +#pragma comment(linker, "/EXPORT:RtlpIsQualifiedLanguage=ntdll.RtlpIsQualifiedLanguage,@1321") +#pragma comment(linker, "/EXPORT:RtlpLoadMachineUIByPolicy=ntdll.RtlpLoadMachineUIByPolicy,@1322") +#pragma comment(linker, "/EXPORT:RtlpLoadUserUIByPolicy=ntdll.RtlpLoadUserUIByPolicy,@1323") +#pragma comment(linker, "/EXPORT:RtlpMuiFreeLangRegistryInfo=ntdll.RtlpMuiFreeLangRegistryInfo,@1324") +#pragma comment(linker, "/EXPORT:RtlpMuiRegCreateRegistryInfo=ntdll.RtlpMuiRegCreateRegistryInfo,@1325") +#pragma comment(linker, "/EXPORT:RtlpMuiRegFreeRegistryInfo=ntdll.RtlpMuiRegFreeRegistryInfo,@1326") +#pragma comment(linker, "/EXPORT:RtlpMuiRegLoadRegistryInfo=ntdll.RtlpMuiRegLoadRegistryInfo,@1327") +#pragma comment(linker, "/EXPORT:RtlpNotOwnerCriticalSection=ntdll.RtlpNotOwnerCriticalSection,@1328") +#pragma comment(linker, "/EXPORT:RtlpNtCreateKey=ntdll.RtlpNtCreateKey,@1329") +#pragma comment(linker, "/EXPORT:RtlpNtEnumerateSubKey=ntdll.RtlpNtEnumerateSubKey,@1330") +#pragma comment(linker, "/EXPORT:RtlpNtMakeTemporaryKey=ntdll.RtlpNtMakeTemporaryKey,@1331") +#pragma comment(linker, "/EXPORT:RtlpNtOpenKey=ntdll.RtlpNtOpenKey,@1332") +#pragma comment(linker, "/EXPORT:RtlpNtQueryValueKey=ntdll.RtlpNtQueryValueKey,@1333") +#pragma comment(linker, "/EXPORT:RtlpNtSetValueKey=ntdll.RtlpNtSetValueKey,@1334") +#pragma comment(linker, "/EXPORT:RtlpQueryDefaultUILanguage=ntdll.RtlpQueryDefaultUILanguage,@1335") +#pragma comment(linker, "/EXPORT:RtlpQueryProcessDebugInformationRemote=ntdll.RtlpQueryProcessDebugInformationRemote,@1336") +#pragma comment(linker, "/EXPORT:RtlpRefreshCachedUILanguage=ntdll.RtlpRefreshCachedUILanguage,@1337") +#pragma comment(linker, "/EXPORT:RtlpSetInstallLanguage=ntdll.RtlpSetInstallLanguage,@1338") +#pragma comment(linker, "/EXPORT:RtlpSetPreferredUILanguages=ntdll.RtlpSetPreferredUILanguages,@1339") +#pragma comment(linker, "/EXPORT:RtlpSetUserPreferredUILanguages=ntdll.RtlpSetUserPreferredUILanguages,@1340") +#pragma comment(linker, "/EXPORT:RtlpUnWaitCriticalSection=ntdll.RtlpUnWaitCriticalSection,@1341") +#pragma comment(linker, "/EXPORT:RtlpVerifyAndCommitUILanguageSettings=ntdll.RtlpVerifyAndCommitUILanguageSettings,@1342") +#pragma comment(linker, "/EXPORT:RtlpWaitForCriticalSection=ntdll.RtlpWaitForCriticalSection,@1343") +#pragma comment(linker, "/EXPORT:RtlxAnsiStringToUnicodeSize=ntdll.RtlxAnsiStringToUnicodeSize,@1344") +#pragma comment(linker, "/EXPORT:RtlxOemStringToUnicodeSize=ntdll.RtlxOemStringToUnicodeSize,@1345") +#pragma comment(linker, "/EXPORT:RtlxUnicodeStringToAnsiSize=ntdll.RtlxUnicodeStringToAnsiSize,@1346") +#pragma comment(linker, "/EXPORT:RtlxUnicodeStringToOemSize=ntdll.RtlxUnicodeStringToOemSize,@1347") +#pragma comment(linker, "/EXPORT:SbExecuteProcedure=ntdll.SbExecuteProcedure,@1348") +#pragma comment(linker, "/EXPORT:SbSelectProcedure=ntdll.SbSelectProcedure,@1349") +#pragma comment(linker, "/EXPORT:ShipAssert=ntdll.ShipAssert,@1350") +#pragma comment(linker, "/EXPORT:ShipAssertGetBufferInfo=ntdll.ShipAssertGetBufferInfo,@1351") +#pragma comment(linker, "/EXPORT:ShipAssertMsgA=ntdll.ShipAssertMsgA,@1352") +#pragma comment(linker, "/EXPORT:ShipAssertMsgW=ntdll.ShipAssertMsgW,@1353") +#pragma comment(linker, "/EXPORT:TpAllocAlpcCompletion=ntdll.TpAllocAlpcCompletion,@1354") +#pragma comment(linker, "/EXPORT:TpAllocAlpcCompletionEx=ntdll.TpAllocAlpcCompletionEx,@1355") +#pragma comment(linker, "/EXPORT:TpAllocCleanupGroup=ntdll.TpAllocCleanupGroup,@1356") +#pragma comment(linker, "/EXPORT:TpAllocIoCompletion=ntdll.TpAllocIoCompletion,@1357") +#pragma comment(linker, "/EXPORT:TpAllocPool=ntdll.TpAllocPool,@1358") +#pragma comment(linker, "/EXPORT:TpAllocTimer=ntdll.TpAllocTimer,@1359") +#pragma comment(linker, "/EXPORT:TpAllocWait=ntdll.TpAllocWait,@1360") +#pragma comment(linker, "/EXPORT:TpAllocWork=ntdll.TpAllocWork,@1361") +#pragma comment(linker, "/EXPORT:TpAlpcRegisterCompletionList=ntdll.TpAlpcRegisterCompletionList,@1362") +#pragma comment(linker, "/EXPORT:TpAlpcUnregisterCompletionList=ntdll.TpAlpcUnregisterCompletionList,@1363") +#pragma comment(linker, "/EXPORT:TpCallbackIndependent=ntdll.TpCallbackIndependent,@1364") +#pragma comment(linker, "/EXPORT:TpCallbackLeaveCriticalSectionOnCompletion=ntdll.TpCallbackLeaveCriticalSectionOnCompletion,@1365") +#pragma comment(linker, "/EXPORT:TpCallbackMayRunLong=ntdll.TpCallbackMayRunLong,@1366") +#pragma comment(linker, "/EXPORT:TpCallbackReleaseMutexOnCompletion=ntdll.TpCallbackReleaseMutexOnCompletion,@1367") +#pragma comment(linker, "/EXPORT:TpCallbackReleaseSemaphoreOnCompletion=ntdll.TpCallbackReleaseSemaphoreOnCompletion,@1368") +#pragma comment(linker, "/EXPORT:TpCallbackSetEventOnCompletion=ntdll.TpCallbackSetEventOnCompletion,@1369") +#pragma comment(linker, "/EXPORT:TpCallbackUnloadDllOnCompletion=ntdll.TpCallbackUnloadDllOnCompletion,@1370") +#pragma comment(linker, "/EXPORT:TpCancelAsyncIoOperation=ntdll.TpCancelAsyncIoOperation,@1371") +#pragma comment(linker, "/EXPORT:TpCaptureCaller=ntdll.TpCaptureCaller,@1372") +#pragma comment(linker, "/EXPORT:TpCheckTerminateWorker=ntdll.TpCheckTerminateWorker,@1373") +#pragma comment(linker, "/EXPORT:TpDbgDumpHeapUsage=ntdll.TpDbgDumpHeapUsage,@1374") +#pragma comment(linker, "/EXPORT:TpDbgSetLogRoutine=ntdll.TpDbgSetLogRoutine,@1375") +#pragma comment(linker, "/EXPORT:TpDisablePoolCallbackChecks=ntdll.TpDisablePoolCallbackChecks,@1376") +#pragma comment(linker, "/EXPORT:TpDisassociateCallback=ntdll.TpDisassociateCallback,@1377") +#pragma comment(linker, "/EXPORT:TpIsTimerSet=ntdll.TpIsTimerSet,@1378") +#pragma comment(linker, "/EXPORT:TpPostWork=ntdll.TpPostWork,@1379") +#pragma comment(linker, "/EXPORT:TpQueryPoolStackInformation=ntdll.TpQueryPoolStackInformation,@1380") +#pragma comment(linker, "/EXPORT:TpReleaseAlpcCompletion=ntdll.TpReleaseAlpcCompletion,@1381") +#pragma comment(linker, "/EXPORT:TpReleaseCleanupGroup=ntdll.TpReleaseCleanupGroup,@1382") +#pragma comment(linker, "/EXPORT:TpReleaseCleanupGroupMembers=ntdll.TpReleaseCleanupGroupMembers,@1383") +#pragma comment(linker, "/EXPORT:TpReleaseIoCompletion=ntdll.TpReleaseIoCompletion,@1384") +#pragma comment(linker, "/EXPORT:TpReleasePool=ntdll.TpReleasePool,@1385") +#pragma comment(linker, "/EXPORT:TpReleaseTimer=ntdll.TpReleaseTimer,@1386") +#pragma comment(linker, "/EXPORT:TpReleaseWait=ntdll.TpReleaseWait,@1387") +#pragma comment(linker, "/EXPORT:TpReleaseWork=ntdll.TpReleaseWork,@1388") +#pragma comment(linker, "/EXPORT:TpSetDefaultPoolMaxThreads=ntdll.TpSetDefaultPoolMaxThreads,@1389") +#pragma comment(linker, "/EXPORT:TpSetDefaultPoolStackInformation=ntdll.TpSetDefaultPoolStackInformation,@1390") +#pragma comment(linker, "/EXPORT:TpSetPoolMaxThreads=ntdll.TpSetPoolMaxThreads,@1391") +#pragma comment(linker, "/EXPORT:TpSetPoolMinThreads=ntdll.TpSetPoolMinThreads,@1392") +#pragma comment(linker, "/EXPORT:TpSetPoolStackInformation=ntdll.TpSetPoolStackInformation,@1393") +#pragma comment(linker, "/EXPORT:TpSetTimer=ntdll.TpSetTimer,@1394") +#pragma comment(linker, "/EXPORT:TpSetWait=ntdll.TpSetWait,@1395") +#pragma comment(linker, "/EXPORT:TpSimpleTryPost=ntdll.TpSimpleTryPost,@1396") +#pragma comment(linker, "/EXPORT:TpStartAsyncIoOperation=ntdll.TpStartAsyncIoOperation,@1397") +#pragma comment(linker, "/EXPORT:TpWaitForAlpcCompletion=ntdll.TpWaitForAlpcCompletion,@1398") +#pragma comment(linker, "/EXPORT:TpWaitForIoCompletion=ntdll.TpWaitForIoCompletion,@1399") +#pragma comment(linker, "/EXPORT:TpWaitForTimer=ntdll.TpWaitForTimer,@1400") +#pragma comment(linker, "/EXPORT:TpWaitForWait=ntdll.TpWaitForWait,@1401") +#pragma comment(linker, "/EXPORT:TpWaitForWork=ntdll.TpWaitForWork,@1402") +#pragma comment(linker, "/EXPORT:VerSetConditionMask=ntdll.VerSetConditionMask,@1403") +#pragma comment(linker, "/EXPORT:WerReportSQMEvent=ntdll.WerReportSQMEvent,@1404") +#pragma comment(linker, "/EXPORT:WinSqmAddToAverageDWORD=ntdll.WinSqmAddToAverageDWORD,@1405") +#pragma comment(linker, "/EXPORT:WinSqmAddToStream=ntdll.WinSqmAddToStream,@1406") +#pragma comment(linker, "/EXPORT:WinSqmAddToStreamEx=ntdll.WinSqmAddToStreamEx,@1407") +#pragma comment(linker, "/EXPORT:WinSqmCheckEscalationAddToStreamEx=ntdll.WinSqmCheckEscalationAddToStreamEx,@1408") +#pragma comment(linker, "/EXPORT:WinSqmCheckEscalationSetDWORD=ntdll.WinSqmCheckEscalationSetDWORD,@1410") +#pragma comment(linker, "/EXPORT:WinSqmCheckEscalationSetDWORD64=ntdll.WinSqmCheckEscalationSetDWORD64,@1409") +#pragma comment(linker, "/EXPORT:WinSqmCheckEscalationSetString=ntdll.WinSqmCheckEscalationSetString,@1411") +#pragma comment(linker, "/EXPORT:WinSqmCommonDatapointDelete=ntdll.WinSqmCommonDatapointDelete,@1412") +#pragma comment(linker, "/EXPORT:WinSqmCommonDatapointSetDWORD=ntdll.WinSqmCommonDatapointSetDWORD,@1414") +#pragma comment(linker, "/EXPORT:WinSqmCommonDatapointSetDWORD64=ntdll.WinSqmCommonDatapointSetDWORD64,@1413") +#pragma comment(linker, "/EXPORT:WinSqmCommonDatapointSetStreamEx=ntdll.WinSqmCommonDatapointSetStreamEx,@1415") +#pragma comment(linker, "/EXPORT:WinSqmCommonDatapointSetString=ntdll.WinSqmCommonDatapointSetString,@1416") +#pragma comment(linker, "/EXPORT:WinSqmEndSession=ntdll.WinSqmEndSession,@1417") +#pragma comment(linker, "/EXPORT:WinSqmEventEnabled=ntdll.WinSqmEventEnabled,@1418") +#pragma comment(linker, "/EXPORT:WinSqmEventWrite=ntdll.WinSqmEventWrite,@1419") +#pragma comment(linker, "/EXPORT:WinSqmGetEscalationRuleStatus=ntdll.WinSqmGetEscalationRuleStatus,@1420") +#pragma comment(linker, "/EXPORT:WinSqmGetInstrumentationProperty=ntdll.WinSqmGetInstrumentationProperty,@1421") +#pragma comment(linker, "/EXPORT:WinSqmIncrementDWORD=ntdll.WinSqmIncrementDWORD,@1422") +#pragma comment(linker, "/EXPORT:WinSqmIsOptedIn=ntdll.WinSqmIsOptedIn,@1423") +#pragma comment(linker, "/EXPORT:WinSqmIsOptedInEx=ntdll.WinSqmIsOptedInEx,@1424") +#pragma comment(linker, "/EXPORT:WinSqmSetDWORD=ntdll.WinSqmSetDWORD,@1426") +#pragma comment(linker, "/EXPORT:WinSqmSetDWORD64=ntdll.WinSqmSetDWORD64,@1425") +#pragma comment(linker, "/EXPORT:WinSqmSetEscalationInfo=ntdll.WinSqmSetEscalationInfo,@1427") +#pragma comment(linker, "/EXPORT:WinSqmSetIfMaxDWORD=ntdll.WinSqmSetIfMaxDWORD,@1428") +#pragma comment(linker, "/EXPORT:WinSqmSetIfMinDWORD=ntdll.WinSqmSetIfMinDWORD,@1429") +#pragma comment(linker, "/EXPORT:WinSqmSetString=ntdll.WinSqmSetString,@1430") +#pragma comment(linker, "/EXPORT:WinSqmStartSession=ntdll.WinSqmStartSession,@1431") +#pragma comment(linker, "/EXPORT:ZwAcceptConnectPort=ntdll.ZwAcceptConnectPort,@1432") +#pragma comment(linker, "/EXPORT:ZwAccessCheck=ntdll.ZwAccessCheck,@1433") +#pragma comment(linker, "/EXPORT:ZwAccessCheckAndAuditAlarm=ntdll.ZwAccessCheckAndAuditAlarm,@1434") +#pragma comment(linker, "/EXPORT:ZwAccessCheckByType=ntdll.ZwAccessCheckByType,@1435") +#pragma comment(linker, "/EXPORT:ZwAccessCheckByTypeAndAuditAlarm=ntdll.ZwAccessCheckByTypeAndAuditAlarm,@1436") +#pragma comment(linker, "/EXPORT:ZwAccessCheckByTypeResultList=ntdll.ZwAccessCheckByTypeResultList,@1437") +#pragma comment(linker, "/EXPORT:ZwAccessCheckByTypeResultListAndAuditAlarm=ntdll.ZwAccessCheckByTypeResultListAndAuditAlarm,@1438") +#pragma comment(linker, "/EXPORT:ZwAccessCheckByTypeResultListAndAuditAlarmByHandle=ntdll.ZwAccessCheckByTypeResultListAndAuditAlarmByHandle,@1439") +#pragma comment(linker, "/EXPORT:ZwAddAtom=ntdll.ZwAddAtom,@1440") +#pragma comment(linker, "/EXPORT:ZwAddBootEntry=ntdll.ZwAddBootEntry,@1441") +#pragma comment(linker, "/EXPORT:ZwAddDriverEntry=ntdll.ZwAddDriverEntry,@1442") +#pragma comment(linker, "/EXPORT:ZwAdjustGroupsToken=ntdll.ZwAdjustGroupsToken,@1443") +#pragma comment(linker, "/EXPORT:ZwAdjustPrivilegesToken=ntdll.ZwAdjustPrivilegesToken,@1444") +#pragma comment(linker, "/EXPORT:ZwAlertResumeThread=ntdll.ZwAlertResumeThread,@1445") +#pragma comment(linker, "/EXPORT:ZwAlertThread=ntdll.ZwAlertThread,@1446") +#pragma comment(linker, "/EXPORT:ZwAllocateLocallyUniqueId=ntdll.ZwAllocateLocallyUniqueId,@1447") +#pragma comment(linker, "/EXPORT:ZwAllocateReserveObject=ntdll.ZwAllocateReserveObject,@1448") +#pragma comment(linker, "/EXPORT:ZwAllocateUserPhysicalPages=ntdll.ZwAllocateUserPhysicalPages,@1449") +#pragma comment(linker, "/EXPORT:ZwAllocateUuids=ntdll.ZwAllocateUuids,@1450") +#pragma comment(linker, "/EXPORT:ZwAllocateVirtualMemory=ntdll.ZwAllocateVirtualMemory,@1451") +#pragma comment(linker, "/EXPORT:ZwAlpcAcceptConnectPort=ntdll.ZwAlpcAcceptConnectPort,@1452") +#pragma comment(linker, "/EXPORT:ZwAlpcCancelMessage=ntdll.ZwAlpcCancelMessage,@1453") +#pragma comment(linker, "/EXPORT:ZwAlpcConnectPort=ntdll.ZwAlpcConnectPort,@1454") +#pragma comment(linker, "/EXPORT:ZwAlpcCreatePort=ntdll.ZwAlpcCreatePort,@1455") +#pragma comment(linker, "/EXPORT:ZwAlpcCreatePortSection=ntdll.ZwAlpcCreatePortSection,@1456") +#pragma comment(linker, "/EXPORT:ZwAlpcCreateResourceReserve=ntdll.ZwAlpcCreateResourceReserve,@1457") +#pragma comment(linker, "/EXPORT:ZwAlpcCreateSectionView=ntdll.ZwAlpcCreateSectionView,@1458") +#pragma comment(linker, "/EXPORT:ZwAlpcCreateSecurityContext=ntdll.ZwAlpcCreateSecurityContext,@1459") +#pragma comment(linker, "/EXPORT:ZwAlpcDeletePortSection=ntdll.ZwAlpcDeletePortSection,@1460") +#pragma comment(linker, "/EXPORT:ZwAlpcDeleteResourceReserve=ntdll.ZwAlpcDeleteResourceReserve,@1461") +#pragma comment(linker, "/EXPORT:ZwAlpcDeleteSectionView=ntdll.ZwAlpcDeleteSectionView,@1462") +#pragma comment(linker, "/EXPORT:ZwAlpcDeleteSecurityContext=ntdll.ZwAlpcDeleteSecurityContext,@1463") +#pragma comment(linker, "/EXPORT:ZwAlpcDisconnectPort=ntdll.ZwAlpcDisconnectPort,@1464") +#pragma comment(linker, "/EXPORT:ZwAlpcImpersonateClientOfPort=ntdll.ZwAlpcImpersonateClientOfPort,@1465") +#pragma comment(linker, "/EXPORT:ZwAlpcOpenSenderProcess=ntdll.ZwAlpcOpenSenderProcess,@1466") +#pragma comment(linker, "/EXPORT:ZwAlpcOpenSenderThread=ntdll.ZwAlpcOpenSenderThread,@1467") +#pragma comment(linker, "/EXPORT:ZwAlpcQueryInformation=ntdll.ZwAlpcQueryInformation,@1468") +#pragma comment(linker, "/EXPORT:ZwAlpcQueryInformationMessage=ntdll.ZwAlpcQueryInformationMessage,@1469") +#pragma comment(linker, "/EXPORT:ZwAlpcRevokeSecurityContext=ntdll.ZwAlpcRevokeSecurityContext,@1470") +#pragma comment(linker, "/EXPORT:ZwAlpcSendWaitReceivePort=ntdll.ZwAlpcSendWaitReceivePort,@1471") +#pragma comment(linker, "/EXPORT:ZwAlpcSetInformation=ntdll.ZwAlpcSetInformation,@1472") +#pragma comment(linker, "/EXPORT:ZwApphelpCacheControl=ntdll.ZwApphelpCacheControl,@1473") +#pragma comment(linker, "/EXPORT:ZwAreMappedFilesTheSame=ntdll.ZwAreMappedFilesTheSame,@1474") +#pragma comment(linker, "/EXPORT:ZwAssignProcessToJobObject=ntdll.ZwAssignProcessToJobObject,@1475") +#pragma comment(linker, "/EXPORT:ZwCallbackReturn=ntdll.ZwCallbackReturn,@1476") +#pragma comment(linker, "/EXPORT:ZwCancelIoFile=ntdll.ZwCancelIoFile,@1477") +#pragma comment(linker, "/EXPORT:ZwCancelIoFileEx=ntdll.ZwCancelIoFileEx,@1478") +#pragma comment(linker, "/EXPORT:ZwCancelSynchronousIoFile=ntdll.ZwCancelSynchronousIoFile,@1479") +#pragma comment(linker, "/EXPORT:ZwCancelTimer=ntdll.ZwCancelTimer,@1480") +#pragma comment(linker, "/EXPORT:ZwClearEvent=ntdll.ZwClearEvent,@1481") +#pragma comment(linker, "/EXPORT:ZwClose=ntdll.ZwClose,@1482") +#pragma comment(linker, "/EXPORT:ZwCloseObjectAuditAlarm=ntdll.ZwCloseObjectAuditAlarm,@1483") +#pragma comment(linker, "/EXPORT:ZwCommitComplete=ntdll.ZwCommitComplete,@1484") +#pragma comment(linker, "/EXPORT:ZwCommitEnlistment=ntdll.ZwCommitEnlistment,@1485") +#pragma comment(linker, "/EXPORT:ZwCommitTransaction=ntdll.ZwCommitTransaction,@1486") +#pragma comment(linker, "/EXPORT:ZwCompactKeys=ntdll.ZwCompactKeys,@1487") +#pragma comment(linker, "/EXPORT:ZwCompareTokens=ntdll.ZwCompareTokens,@1488") +#pragma comment(linker, "/EXPORT:ZwCompleteConnectPort=ntdll.ZwCompleteConnectPort,@1489") +#pragma comment(linker, "/EXPORT:ZwCompressKey=ntdll.ZwCompressKey,@1490") +#pragma comment(linker, "/EXPORT:ZwConnectPort=ntdll.ZwConnectPort,@1491") +#pragma comment(linker, "/EXPORT:ZwContinue=ntdll.ZwContinue,@1492") +#pragma comment(linker, "/EXPORT:ZwCreateDebugObject=ntdll.ZwCreateDebugObject,@1493") +#pragma comment(linker, "/EXPORT:ZwCreateDirectoryObject=ntdll.ZwCreateDirectoryObject,@1494") +#pragma comment(linker, "/EXPORT:ZwCreateEnlistment=ntdll.ZwCreateEnlistment,@1495") +#pragma comment(linker, "/EXPORT:ZwCreateEvent=ntdll.ZwCreateEvent,@1496") +#pragma comment(linker, "/EXPORT:ZwCreateEventPair=ntdll.ZwCreateEventPair,@1497") +#pragma comment(linker, "/EXPORT:ZwCreateFile=ntdll.ZwCreateFile,@1498") +#pragma comment(linker, "/EXPORT:ZwCreateIoCompletion=ntdll.ZwCreateIoCompletion,@1499") +#pragma comment(linker, "/EXPORT:ZwCreateJobObject=ntdll.ZwCreateJobObject,@1500") +#pragma comment(linker, "/EXPORT:ZwCreateJobSet=ntdll.ZwCreateJobSet,@1501") +#pragma comment(linker, "/EXPORT:ZwCreateKey=ntdll.ZwCreateKey,@1502") +#pragma comment(linker, "/EXPORT:ZwCreateKeyTransacted=ntdll.ZwCreateKeyTransacted,@1503") +#pragma comment(linker, "/EXPORT:ZwCreateKeyedEvent=ntdll.ZwCreateKeyedEvent,@1504") +#pragma comment(linker, "/EXPORT:ZwCreateMailslotFile=ntdll.ZwCreateMailslotFile,@1505") +#pragma comment(linker, "/EXPORT:ZwCreateMutant=ntdll.ZwCreateMutant,@1506") +#pragma comment(linker, "/EXPORT:ZwCreateNamedPipeFile=ntdll.ZwCreateNamedPipeFile,@1507") +#pragma comment(linker, "/EXPORT:ZwCreatePagingFile=ntdll.ZwCreatePagingFile,@1508") +#pragma comment(linker, "/EXPORT:ZwCreatePort=ntdll.ZwCreatePort,@1509") +#pragma comment(linker, "/EXPORT:ZwCreatePrivateNamespace=ntdll.ZwCreatePrivateNamespace,@1510") +#pragma comment(linker, "/EXPORT:ZwCreateProcess=ntdll.ZwCreateProcess,@1511") +#pragma comment(linker, "/EXPORT:ZwCreateProcessEx=ntdll.ZwCreateProcessEx,@1512") +#pragma comment(linker, "/EXPORT:ZwCreateProfile=ntdll.ZwCreateProfile,@1513") +#pragma comment(linker, "/EXPORT:ZwCreateProfileEx=ntdll.ZwCreateProfileEx,@1514") +#pragma comment(linker, "/EXPORT:ZwCreateResourceManager=ntdll.ZwCreateResourceManager,@1515") +#pragma comment(linker, "/EXPORT:ZwCreateSection=ntdll.ZwCreateSection,@1516") +#pragma comment(linker, "/EXPORT:ZwCreateSemaphore=ntdll.ZwCreateSemaphore,@1517") +#pragma comment(linker, "/EXPORT:ZwCreateSymbolicLinkObject=ntdll.ZwCreateSymbolicLinkObject,@1518") +#pragma comment(linker, "/EXPORT:ZwCreateThread=ntdll.ZwCreateThread,@1519") +#pragma comment(linker, "/EXPORT:ZwCreateThreadEx=ntdll.ZwCreateThreadEx,@1520") +#pragma comment(linker, "/EXPORT:ZwCreateTimer=ntdll.ZwCreateTimer,@1521") +#pragma comment(linker, "/EXPORT:ZwCreateToken=ntdll.ZwCreateToken,@1522") +#pragma comment(linker, "/EXPORT:ZwCreateTransaction=ntdll.ZwCreateTransaction,@1523") +#pragma comment(linker, "/EXPORT:ZwCreateTransactionManager=ntdll.ZwCreateTransactionManager,@1524") +#pragma comment(linker, "/EXPORT:ZwCreateUserProcess=ntdll.ZwCreateUserProcess,@1525") +#pragma comment(linker, "/EXPORT:ZwCreateWaitablePort=ntdll.ZwCreateWaitablePort,@1526") +#pragma comment(linker, "/EXPORT:ZwCreateWorkerFactory=ntdll.ZwCreateWorkerFactory,@1527") +#pragma comment(linker, "/EXPORT:ZwDebugActiveProcess=ntdll.ZwDebugActiveProcess,@1528") +#pragma comment(linker, "/EXPORT:ZwDebugContinue=ntdll.ZwDebugContinue,@1529") +#pragma comment(linker, "/EXPORT:ZwDelayExecution=ntdll.ZwDelayExecution,@1530") +#pragma comment(linker, "/EXPORT:ZwDeleteAtom=ntdll.ZwDeleteAtom,@1531") +#pragma comment(linker, "/EXPORT:ZwDeleteBootEntry=ntdll.ZwDeleteBootEntry,@1532") +#pragma comment(linker, "/EXPORT:ZwDeleteDriverEntry=ntdll.ZwDeleteDriverEntry,@1533") +#pragma comment(linker, "/EXPORT:ZwDeleteFile=ntdll.ZwDeleteFile,@1534") +#pragma comment(linker, "/EXPORT:ZwDeleteKey=ntdll.ZwDeleteKey,@1535") +#pragma comment(linker, "/EXPORT:ZwDeleteObjectAuditAlarm=ntdll.ZwDeleteObjectAuditAlarm,@1536") +#pragma comment(linker, "/EXPORT:ZwDeletePrivateNamespace=ntdll.ZwDeletePrivateNamespace,@1537") +#pragma comment(linker, "/EXPORT:ZwDeleteValueKey=ntdll.ZwDeleteValueKey,@1538") +#pragma comment(linker, "/EXPORT:ZwDeviceIoControlFile=ntdll.ZwDeviceIoControlFile,@1539") +#pragma comment(linker, "/EXPORT:ZwDisableLastKnownGood=ntdll.ZwDisableLastKnownGood,@1540") +#pragma comment(linker, "/EXPORT:ZwDisplayString=ntdll.ZwDisplayString,@1541") +#pragma comment(linker, "/EXPORT:ZwDrawText=ntdll.ZwDrawText,@1542") +#pragma comment(linker, "/EXPORT:ZwDuplicateObject=ntdll.ZwDuplicateObject,@1543") +#pragma comment(linker, "/EXPORT:ZwDuplicateToken=ntdll.ZwDuplicateToken,@1544") +#pragma comment(linker, "/EXPORT:ZwEnableLastKnownGood=ntdll.ZwEnableLastKnownGood,@1545") +#pragma comment(linker, "/EXPORT:ZwEnumerateBootEntries=ntdll.ZwEnumerateBootEntries,@1546") +#pragma comment(linker, "/EXPORT:ZwEnumerateDriverEntries=ntdll.ZwEnumerateDriverEntries,@1547") +#pragma comment(linker, "/EXPORT:ZwEnumerateKey=ntdll.ZwEnumerateKey,@1548") +#pragma comment(linker, "/EXPORT:ZwEnumerateSystemEnvironmentValuesEx=ntdll.ZwEnumerateSystemEnvironmentValuesEx,@1549") +#pragma comment(linker, "/EXPORT:ZwEnumerateTransactionObject=ntdll.ZwEnumerateTransactionObject,@1550") +#pragma comment(linker, "/EXPORT:ZwEnumerateValueKey=ntdll.ZwEnumerateValueKey,@1551") +#pragma comment(linker, "/EXPORT:ZwExtendSection=ntdll.ZwExtendSection,@1552") +#pragma comment(linker, "/EXPORT:ZwFilterToken=ntdll.ZwFilterToken,@1553") +#pragma comment(linker, "/EXPORT:ZwFindAtom=ntdll.ZwFindAtom,@1554") +#pragma comment(linker, "/EXPORT:ZwFlushBuffersFile=ntdll.ZwFlushBuffersFile,@1555") +#pragma comment(linker, "/EXPORT:ZwFlushInstallUILanguage=ntdll.ZwFlushInstallUILanguage,@1556") +#pragma comment(linker, "/EXPORT:ZwFlushInstructionCache=ntdll.ZwFlushInstructionCache,@1557") +#pragma comment(linker, "/EXPORT:ZwFlushKey=ntdll.ZwFlushKey,@1558") +#pragma comment(linker, "/EXPORT:ZwFlushProcessWriteBuffers=ntdll.ZwFlushProcessWriteBuffers,@1559") +#pragma comment(linker, "/EXPORT:ZwFlushVirtualMemory=ntdll.ZwFlushVirtualMemory,@1560") +#pragma comment(linker, "/EXPORT:ZwFlushWriteBuffer=ntdll.ZwFlushWriteBuffer,@1561") +#pragma comment(linker, "/EXPORT:ZwFreeUserPhysicalPages=ntdll.ZwFreeUserPhysicalPages,@1562") +#pragma comment(linker, "/EXPORT:ZwFreeVirtualMemory=ntdll.ZwFreeVirtualMemory,@1563") +#pragma comment(linker, "/EXPORT:ZwFreezeRegistry=ntdll.ZwFreezeRegistry,@1564") +#pragma comment(linker, "/EXPORT:ZwFreezeTransactions=ntdll.ZwFreezeTransactions,@1565") +#pragma comment(linker, "/EXPORT:ZwFsControlFile=ntdll.ZwFsControlFile,@1566") +#pragma comment(linker, "/EXPORT:ZwGetContextThread=ntdll.ZwGetContextThread,@1567") +#pragma comment(linker, "/EXPORT:ZwGetCurrentProcessorNumber=ntdll.ZwGetCurrentProcessorNumber,@1568") +#pragma comment(linker, "/EXPORT:ZwGetDevicePowerState=ntdll.ZwGetDevicePowerState,@1569") +#pragma comment(linker, "/EXPORT:ZwGetMUIRegistryInfo=ntdll.ZwGetMUIRegistryInfo,@1570") +#pragma comment(linker, "/EXPORT:ZwGetNextProcess=ntdll.ZwGetNextProcess,@1571") +#pragma comment(linker, "/EXPORT:ZwGetNextThread=ntdll.ZwGetNextThread,@1572") +#pragma comment(linker, "/EXPORT:ZwGetNlsSectionPtr=ntdll.ZwGetNlsSectionPtr,@1573") +#pragma comment(linker, "/EXPORT:ZwGetNotificationResourceManager=ntdll.ZwGetNotificationResourceManager,@1574") +#pragma comment(linker, "/EXPORT:ZwGetPlugPlayEvent=ntdll.ZwGetPlugPlayEvent,@1575") +#pragma comment(linker, "/EXPORT:ZwGetWriteWatch=ntdll.ZwGetWriteWatch,@1576") +#pragma comment(linker, "/EXPORT:ZwImpersonateAnonymousToken=ntdll.ZwImpersonateAnonymousToken,@1577") +#pragma comment(linker, "/EXPORT:ZwImpersonateClientOfPort=ntdll.ZwImpersonateClientOfPort,@1578") +#pragma comment(linker, "/EXPORT:ZwImpersonateThread=ntdll.ZwImpersonateThread,@1579") +#pragma comment(linker, "/EXPORT:ZwInitializeNlsFiles=ntdll.ZwInitializeNlsFiles,@1580") +#pragma comment(linker, "/EXPORT:ZwInitializeRegistry=ntdll.ZwInitializeRegistry,@1581") +#pragma comment(linker, "/EXPORT:ZwInitiatePowerAction=ntdll.ZwInitiatePowerAction,@1582") +#pragma comment(linker, "/EXPORT:ZwIsProcessInJob=ntdll.ZwIsProcessInJob,@1583") +#pragma comment(linker, "/EXPORT:ZwIsSystemResumeAutomatic=ntdll.ZwIsSystemResumeAutomatic,@1584") +#pragma comment(linker, "/EXPORT:ZwIsUILanguageComitted=ntdll.ZwIsUILanguageComitted,@1585") +#pragma comment(linker, "/EXPORT:ZwListenPort=ntdll.ZwListenPort,@1586") +#pragma comment(linker, "/EXPORT:ZwLoadDriver=ntdll.ZwLoadDriver,@1587") +#pragma comment(linker, "/EXPORT:ZwLoadKey=ntdll.ZwLoadKey,@1590") +#pragma comment(linker, "/EXPORT:ZwLoadKey2=ntdll.ZwLoadKey2,@1588") +#pragma comment(linker, "/EXPORT:ZwLoadKey3=ntdll.ZwLoadKey3,@1589") +#pragma comment(linker, "/EXPORT:ZwLoadKeyEx=ntdll.ZwLoadKeyEx,@1591") +#pragma comment(linker, "/EXPORT:ZwLockFile=ntdll.ZwLockFile,@1592") +#pragma comment(linker, "/EXPORT:ZwLockProductActivationKeys=ntdll.ZwLockProductActivationKeys,@1593") +#pragma comment(linker, "/EXPORT:ZwLockRegistryKey=ntdll.ZwLockRegistryKey,@1594") +#pragma comment(linker, "/EXPORT:ZwLockVirtualMemory=ntdll.ZwLockVirtualMemory,@1595") +#pragma comment(linker, "/EXPORT:ZwMakePermanentObject=ntdll.ZwMakePermanentObject,@1596") +#pragma comment(linker, "/EXPORT:ZwMakeTemporaryObject=ntdll.ZwMakeTemporaryObject,@1597") +#pragma comment(linker, "/EXPORT:ZwMapCMFModule=ntdll.ZwMapCMFModule,@1598") +#pragma comment(linker, "/EXPORT:ZwMapUserPhysicalPages=ntdll.ZwMapUserPhysicalPages,@1599") +#pragma comment(linker, "/EXPORT:ZwMapUserPhysicalPagesScatter=ntdll.ZwMapUserPhysicalPagesScatter,@1600") +#pragma comment(linker, "/EXPORT:ZwMapViewOfSection=ntdll.ZwMapViewOfSection,@1601") +#pragma comment(linker, "/EXPORT:ZwModifyBootEntry=ntdll.ZwModifyBootEntry,@1602") +#pragma comment(linker, "/EXPORT:ZwModifyDriverEntry=ntdll.ZwModifyDriverEntry,@1603") +#pragma comment(linker, "/EXPORT:ZwNotifyChangeDirectoryFile=ntdll.ZwNotifyChangeDirectoryFile,@1604") +#pragma comment(linker, "/EXPORT:ZwNotifyChangeKey=ntdll.ZwNotifyChangeKey,@1605") +#pragma comment(linker, "/EXPORT:ZwNotifyChangeMultipleKeys=ntdll.ZwNotifyChangeMultipleKeys,@1606") +#pragma comment(linker, "/EXPORT:ZwNotifyChangeSession=ntdll.ZwNotifyChangeSession,@1607") +#pragma comment(linker, "/EXPORT:ZwOpenDirectoryObject=ntdll.ZwOpenDirectoryObject,@1608") +#pragma comment(linker, "/EXPORT:ZwOpenEnlistment=ntdll.ZwOpenEnlistment,@1609") +#pragma comment(linker, "/EXPORT:ZwOpenEvent=ntdll.ZwOpenEvent,@1610") +#pragma comment(linker, "/EXPORT:ZwOpenEventPair=ntdll.ZwOpenEventPair,@1611") +#pragma comment(linker, "/EXPORT:ZwOpenFile=ntdll.ZwOpenFile,@1612") +#pragma comment(linker, "/EXPORT:ZwOpenIoCompletion=ntdll.ZwOpenIoCompletion,@1613") +#pragma comment(linker, "/EXPORT:ZwOpenJobObject=ntdll.ZwOpenJobObject,@1614") +#pragma comment(linker, "/EXPORT:ZwOpenKey=ntdll.ZwOpenKey,@1615") +#pragma comment(linker, "/EXPORT:ZwOpenKeyEx=ntdll.ZwOpenKeyEx,@1616") +#pragma comment(linker, "/EXPORT:ZwOpenKeyTransacted=ntdll.ZwOpenKeyTransacted,@1617") +#pragma comment(linker, "/EXPORT:ZwOpenKeyTransactedEx=ntdll.ZwOpenKeyTransactedEx,@1618") +#pragma comment(linker, "/EXPORT:ZwOpenKeyedEvent=ntdll.ZwOpenKeyedEvent,@1619") +#pragma comment(linker, "/EXPORT:ZwOpenMutant=ntdll.ZwOpenMutant,@1620") +#pragma comment(linker, "/EXPORT:ZwOpenObjectAuditAlarm=ntdll.ZwOpenObjectAuditAlarm,@1621") +#pragma comment(linker, "/EXPORT:ZwOpenPrivateNamespace=ntdll.ZwOpenPrivateNamespace,@1622") +#pragma comment(linker, "/EXPORT:ZwOpenProcess=ntdll.ZwOpenProcess,@1623") +#pragma comment(linker, "/EXPORT:ZwOpenProcessToken=ntdll.ZwOpenProcessToken,@1624") +#pragma comment(linker, "/EXPORT:ZwOpenProcessTokenEx=ntdll.ZwOpenProcessTokenEx,@1625") +#pragma comment(linker, "/EXPORT:ZwOpenResourceManager=ntdll.ZwOpenResourceManager,@1626") +#pragma comment(linker, "/EXPORT:ZwOpenSection=ntdll.ZwOpenSection,@1627") +#pragma comment(linker, "/EXPORT:ZwOpenSemaphore=ntdll.ZwOpenSemaphore,@1628") +#pragma comment(linker, "/EXPORT:ZwOpenSession=ntdll.ZwOpenSession,@1629") +#pragma comment(linker, "/EXPORT:ZwOpenSymbolicLinkObject=ntdll.ZwOpenSymbolicLinkObject,@1630") +#pragma comment(linker, "/EXPORT:ZwOpenThread=ntdll.ZwOpenThread,@1631") +#pragma comment(linker, "/EXPORT:ZwOpenThreadToken=ntdll.ZwOpenThreadToken,@1632") +#pragma comment(linker, "/EXPORT:ZwOpenThreadTokenEx=ntdll.ZwOpenThreadTokenEx,@1633") +#pragma comment(linker, "/EXPORT:ZwOpenTimer=ntdll.ZwOpenTimer,@1634") +#pragma comment(linker, "/EXPORT:ZwOpenTransaction=ntdll.ZwOpenTransaction,@1635") +#pragma comment(linker, "/EXPORT:ZwOpenTransactionManager=ntdll.ZwOpenTransactionManager,@1636") +#pragma comment(linker, "/EXPORT:ZwPlugPlayControl=ntdll.ZwPlugPlayControl,@1637") +#pragma comment(linker, "/EXPORT:ZwPowerInformation=ntdll.ZwPowerInformation,@1638") +#pragma comment(linker, "/EXPORT:ZwPrePrepareComplete=ntdll.ZwPrePrepareComplete,@1639") +#pragma comment(linker, "/EXPORT:ZwPrePrepareEnlistment=ntdll.ZwPrePrepareEnlistment,@1640") +#pragma comment(linker, "/EXPORT:ZwPrepareComplete=ntdll.ZwPrepareComplete,@1641") +#pragma comment(linker, "/EXPORT:ZwPrepareEnlistment=ntdll.ZwPrepareEnlistment,@1642") +#pragma comment(linker, "/EXPORT:ZwPrivilegeCheck=ntdll.ZwPrivilegeCheck,@1643") +#pragma comment(linker, "/EXPORT:ZwPrivilegeObjectAuditAlarm=ntdll.ZwPrivilegeObjectAuditAlarm,@1644") +#pragma comment(linker, "/EXPORT:ZwPrivilegedServiceAuditAlarm=ntdll.ZwPrivilegedServiceAuditAlarm,@1645") +#pragma comment(linker, "/EXPORT:ZwPropagationComplete=ntdll.ZwPropagationComplete,@1646") +#pragma comment(linker, "/EXPORT:ZwPropagationFailed=ntdll.ZwPropagationFailed,@1647") +#pragma comment(linker, "/EXPORT:ZwProtectVirtualMemory=ntdll.ZwProtectVirtualMemory,@1648") +#pragma comment(linker, "/EXPORT:ZwPulseEvent=ntdll.ZwPulseEvent,@1649") +#pragma comment(linker, "/EXPORT:ZwQueryAttributesFile=ntdll.ZwQueryAttributesFile,@1650") +#pragma comment(linker, "/EXPORT:ZwQueryBootEntryOrder=ntdll.ZwQueryBootEntryOrder,@1651") +#pragma comment(linker, "/EXPORT:ZwQueryBootOptions=ntdll.ZwQueryBootOptions,@1652") +#pragma comment(linker, "/EXPORT:ZwQueryDebugFilterState=ntdll.ZwQueryDebugFilterState,@1653") +#pragma comment(linker, "/EXPORT:ZwQueryDefaultLocale=ntdll.ZwQueryDefaultLocale,@1654") +#pragma comment(linker, "/EXPORT:ZwQueryDefaultUILanguage=ntdll.ZwQueryDefaultUILanguage,@1655") +#pragma comment(linker, "/EXPORT:ZwQueryDirectoryFile=ntdll.ZwQueryDirectoryFile,@1656") +#pragma comment(linker, "/EXPORT:ZwQueryDirectoryObject=ntdll.ZwQueryDirectoryObject,@1657") +#pragma comment(linker, "/EXPORT:ZwQueryDriverEntryOrder=ntdll.ZwQueryDriverEntryOrder,@1658") +#pragma comment(linker, "/EXPORT:ZwQueryEaFile=ntdll.ZwQueryEaFile,@1659") +#pragma comment(linker, "/EXPORT:ZwQueryEvent=ntdll.ZwQueryEvent,@1660") +#pragma comment(linker, "/EXPORT:ZwQueryFullAttributesFile=ntdll.ZwQueryFullAttributesFile,@1661") +#pragma comment(linker, "/EXPORT:ZwQueryInformationAtom=ntdll.ZwQueryInformationAtom,@1662") +#pragma comment(linker, "/EXPORT:ZwQueryInformationEnlistment=ntdll.ZwQueryInformationEnlistment,@1663") +#pragma comment(linker, "/EXPORT:ZwQueryInformationFile=ntdll.ZwQueryInformationFile,@1664") +#pragma comment(linker, "/EXPORT:ZwQueryInformationJobObject=ntdll.ZwQueryInformationJobObject,@1665") +#pragma comment(linker, "/EXPORT:ZwQueryInformationPort=ntdll.ZwQueryInformationPort,@1666") +#pragma comment(linker, "/EXPORT:ZwQueryInformationProcess=ntdll.ZwQueryInformationProcess,@1667") +#pragma comment(linker, "/EXPORT:ZwQueryInformationResourceManager=ntdll.ZwQueryInformationResourceManager,@1668") +#pragma comment(linker, "/EXPORT:ZwQueryInformationThread=ntdll.ZwQueryInformationThread,@1669") +#pragma comment(linker, "/EXPORT:ZwQueryInformationToken=ntdll.ZwQueryInformationToken,@1670") +#pragma comment(linker, "/EXPORT:ZwQueryInformationTransaction=ntdll.ZwQueryInformationTransaction,@1671") +#pragma comment(linker, "/EXPORT:ZwQueryInformationTransactionManager=ntdll.ZwQueryInformationTransactionManager,@1672") +#pragma comment(linker, "/EXPORT:ZwQueryInformationWorkerFactory=ntdll.ZwQueryInformationWorkerFactory,@1673") +#pragma comment(linker, "/EXPORT:ZwQueryInstallUILanguage=ntdll.ZwQueryInstallUILanguage,@1674") +#pragma comment(linker, "/EXPORT:ZwQueryIntervalProfile=ntdll.ZwQueryIntervalProfile,@1675") +#pragma comment(linker, "/EXPORT:ZwQueryIoCompletion=ntdll.ZwQueryIoCompletion,@1676") +#pragma comment(linker, "/EXPORT:ZwQueryKey=ntdll.ZwQueryKey,@1677") +#pragma comment(linker, "/EXPORT:ZwQueryLicenseValue=ntdll.ZwQueryLicenseValue,@1678") +#pragma comment(linker, "/EXPORT:ZwQueryMultipleValueKey=ntdll.ZwQueryMultipleValueKey,@1679") +#pragma comment(linker, "/EXPORT:ZwQueryMutant=ntdll.ZwQueryMutant,@1680") +#pragma comment(linker, "/EXPORT:ZwQueryObject=ntdll.ZwQueryObject,@1681") +#pragma comment(linker, "/EXPORT:ZwQueryOpenSubKeys=ntdll.ZwQueryOpenSubKeys,@1682") +#pragma comment(linker, "/EXPORT:ZwQueryOpenSubKeysEx=ntdll.ZwQueryOpenSubKeysEx,@1683") +#pragma comment(linker, "/EXPORT:ZwQueryPerformanceCounter=ntdll.ZwQueryPerformanceCounter,@1684") +#pragma comment(linker, "/EXPORT:ZwQueryPortInformationProcess=ntdll.ZwQueryPortInformationProcess,@1685") +#pragma comment(linker, "/EXPORT:ZwQueryQuotaInformationFile=ntdll.ZwQueryQuotaInformationFile,@1686") +#pragma comment(linker, "/EXPORT:ZwQuerySection=ntdll.ZwQuerySection,@1687") +#pragma comment(linker, "/EXPORT:ZwQuerySecurityAttributesToken=ntdll.ZwQuerySecurityAttributesToken,@1688") +#pragma comment(linker, "/EXPORT:ZwQuerySecurityObject=ntdll.ZwQuerySecurityObject,@1689") +#pragma comment(linker, "/EXPORT:ZwQuerySemaphore=ntdll.ZwQuerySemaphore,@1690") +#pragma comment(linker, "/EXPORT:ZwQuerySymbolicLinkObject=ntdll.ZwQuerySymbolicLinkObject,@1691") +#pragma comment(linker, "/EXPORT:ZwQuerySystemEnvironmentValue=ntdll.ZwQuerySystemEnvironmentValue,@1692") +#pragma comment(linker, "/EXPORT:ZwQuerySystemEnvironmentValueEx=ntdll.ZwQuerySystemEnvironmentValueEx,@1693") +#pragma comment(linker, "/EXPORT:ZwQuerySystemInformation=ntdll.ZwQuerySystemInformation,@1694") +#pragma comment(linker, "/EXPORT:ZwQuerySystemInformationEx=ntdll.ZwQuerySystemInformationEx,@1695") +#pragma comment(linker, "/EXPORT:ZwQuerySystemTime=ntdll.ZwQuerySystemTime,@1696") +#pragma comment(linker, "/EXPORT:ZwQueryTimer=ntdll.ZwQueryTimer,@1697") +#pragma comment(linker, "/EXPORT:ZwQueryTimerResolution=ntdll.ZwQueryTimerResolution,@1698") +#pragma comment(linker, "/EXPORT:ZwQueryValueKey=ntdll.ZwQueryValueKey,@1699") +#pragma comment(linker, "/EXPORT:ZwQueryVirtualMemory=ntdll.ZwQueryVirtualMemory,@1700") +#pragma comment(linker, "/EXPORT:ZwQueryVolumeInformationFile=ntdll.ZwQueryVolumeInformationFile,@1701") +#pragma comment(linker, "/EXPORT:ZwQueueApcThread=ntdll.ZwQueueApcThread,@1702") +#pragma comment(linker, "/EXPORT:ZwQueueApcThreadEx=ntdll.ZwQueueApcThreadEx,@1703") +#pragma comment(linker, "/EXPORT:ZwRaiseException=ntdll.ZwRaiseException,@1704") +#pragma comment(linker, "/EXPORT:ZwRaiseHardError=ntdll.ZwRaiseHardError,@1705") +#pragma comment(linker, "/EXPORT:ZwReadFile=ntdll.ZwReadFile,@1706") +#pragma comment(linker, "/EXPORT:ZwReadFileScatter=ntdll.ZwReadFileScatter,@1707") +#pragma comment(linker, "/EXPORT:ZwReadOnlyEnlistment=ntdll.ZwReadOnlyEnlistment,@1708") +#pragma comment(linker, "/EXPORT:ZwReadRequestData=ntdll.ZwReadRequestData,@1709") +#pragma comment(linker, "/EXPORT:ZwReadVirtualMemory=ntdll.ZwReadVirtualMemory,@1710") +#pragma comment(linker, "/EXPORT:ZwRecoverEnlistment=ntdll.ZwRecoverEnlistment,@1711") +#pragma comment(linker, "/EXPORT:ZwRecoverResourceManager=ntdll.ZwRecoverResourceManager,@1712") +#pragma comment(linker, "/EXPORT:ZwRecoverTransactionManager=ntdll.ZwRecoverTransactionManager,@1713") +#pragma comment(linker, "/EXPORT:ZwRegisterProtocolAddressInformation=ntdll.ZwRegisterProtocolAddressInformation,@1714") +#pragma comment(linker, "/EXPORT:ZwRegisterThreadTerminatePort=ntdll.ZwRegisterThreadTerminatePort,@1715") +#pragma comment(linker, "/EXPORT:ZwReleaseKeyedEvent=ntdll.ZwReleaseKeyedEvent,@1716") +#pragma comment(linker, "/EXPORT:ZwReleaseMutant=ntdll.ZwReleaseMutant,@1717") +#pragma comment(linker, "/EXPORT:ZwReleaseSemaphore=ntdll.ZwReleaseSemaphore,@1718") +#pragma comment(linker, "/EXPORT:ZwReleaseWorkerFactoryWorker=ntdll.ZwReleaseWorkerFactoryWorker,@1719") +#pragma comment(linker, "/EXPORT:ZwRemoveIoCompletion=ntdll.ZwRemoveIoCompletion,@1720") +#pragma comment(linker, "/EXPORT:ZwRemoveIoCompletionEx=ntdll.ZwRemoveIoCompletionEx,@1721") +#pragma comment(linker, "/EXPORT:ZwRemoveProcessDebug=ntdll.ZwRemoveProcessDebug,@1722") +#pragma comment(linker, "/EXPORT:ZwRenameKey=ntdll.ZwRenameKey,@1723") +#pragma comment(linker, "/EXPORT:ZwRenameTransactionManager=ntdll.ZwRenameTransactionManager,@1724") +#pragma comment(linker, "/EXPORT:ZwReplaceKey=ntdll.ZwReplaceKey,@1725") +#pragma comment(linker, "/EXPORT:ZwReplacePartitionUnit=ntdll.ZwReplacePartitionUnit,@1726") +#pragma comment(linker, "/EXPORT:ZwReplyPort=ntdll.ZwReplyPort,@1727") +#pragma comment(linker, "/EXPORT:ZwReplyWaitReceivePort=ntdll.ZwReplyWaitReceivePort,@1728") +#pragma comment(linker, "/EXPORT:ZwReplyWaitReceivePortEx=ntdll.ZwReplyWaitReceivePortEx,@1729") +#pragma comment(linker, "/EXPORT:ZwReplyWaitReplyPort=ntdll.ZwReplyWaitReplyPort,@1730") +#pragma comment(linker, "/EXPORT:ZwRequestPort=ntdll.ZwRequestPort,@1731") +#pragma comment(linker, "/EXPORT:ZwRequestWaitReplyPort=ntdll.ZwRequestWaitReplyPort,@1732") +#pragma comment(linker, "/EXPORT:ZwResetEvent=ntdll.ZwResetEvent,@1733") +#pragma comment(linker, "/EXPORT:ZwResetWriteWatch=ntdll.ZwResetWriteWatch,@1734") +#pragma comment(linker, "/EXPORT:ZwRestoreKey=ntdll.ZwRestoreKey,@1735") +#pragma comment(linker, "/EXPORT:ZwResumeProcess=ntdll.ZwResumeProcess,@1736") +#pragma comment(linker, "/EXPORT:ZwResumeThread=ntdll.ZwResumeThread,@1737") +#pragma comment(linker, "/EXPORT:ZwRollbackComplete=ntdll.ZwRollbackComplete,@1738") +#pragma comment(linker, "/EXPORT:ZwRollbackEnlistment=ntdll.ZwRollbackEnlistment,@1739") +#pragma comment(linker, "/EXPORT:ZwRollbackTransaction=ntdll.ZwRollbackTransaction,@1740") +#pragma comment(linker, "/EXPORT:ZwRollforwardTransactionManager=ntdll.ZwRollforwardTransactionManager,@1741") +#pragma comment(linker, "/EXPORT:ZwSaveKey=ntdll.ZwSaveKey,@1742") +#pragma comment(linker, "/EXPORT:ZwSaveKeyEx=ntdll.ZwSaveKeyEx,@1743") +#pragma comment(linker, "/EXPORT:ZwSaveMergedKeys=ntdll.ZwSaveMergedKeys,@1744") +#pragma comment(linker, "/EXPORT:ZwSecureConnectPort=ntdll.ZwSecureConnectPort,@1745") +#pragma comment(linker, "/EXPORT:ZwSerializeBoot=ntdll.ZwSerializeBoot,@1746") +#pragma comment(linker, "/EXPORT:ZwSetBootEntryOrder=ntdll.ZwSetBootEntryOrder,@1747") +#pragma comment(linker, "/EXPORT:ZwSetBootOptions=ntdll.ZwSetBootOptions,@1748") +#pragma comment(linker, "/EXPORT:ZwSetContextThread=ntdll.ZwSetContextThread,@1749") +#pragma comment(linker, "/EXPORT:ZwSetDebugFilterState=ntdll.ZwSetDebugFilterState,@1750") +#pragma comment(linker, "/EXPORT:ZwSetDefaultHardErrorPort=ntdll.ZwSetDefaultHardErrorPort,@1751") +#pragma comment(linker, "/EXPORT:ZwSetDefaultLocale=ntdll.ZwSetDefaultLocale,@1752") +#pragma comment(linker, "/EXPORT:ZwSetDefaultUILanguage=ntdll.ZwSetDefaultUILanguage,@1753") +#pragma comment(linker, "/EXPORT:ZwSetDriverEntryOrder=ntdll.ZwSetDriverEntryOrder,@1754") +#pragma comment(linker, "/EXPORT:ZwSetEaFile=ntdll.ZwSetEaFile,@1755") +#pragma comment(linker, "/EXPORT:ZwSetEvent=ntdll.ZwSetEvent,@1756") +#pragma comment(linker, "/EXPORT:ZwSetEventBoostPriority=ntdll.ZwSetEventBoostPriority,@1757") +#pragma comment(linker, "/EXPORT:ZwSetHighEventPair=ntdll.ZwSetHighEventPair,@1758") +#pragma comment(linker, "/EXPORT:ZwSetHighWaitLowEventPair=ntdll.ZwSetHighWaitLowEventPair,@1759") +#pragma comment(linker, "/EXPORT:ZwSetInformationDebugObject=ntdll.ZwSetInformationDebugObject,@1760") +#pragma comment(linker, "/EXPORT:ZwSetInformationEnlistment=ntdll.ZwSetInformationEnlistment,@1761") +#pragma comment(linker, "/EXPORT:ZwSetInformationFile=ntdll.ZwSetInformationFile,@1762") +#pragma comment(linker, "/EXPORT:ZwSetInformationJobObject=ntdll.ZwSetInformationJobObject,@1763") +#pragma comment(linker, "/EXPORT:ZwSetInformationKey=ntdll.ZwSetInformationKey,@1764") +#pragma comment(linker, "/EXPORT:ZwSetInformationObject=ntdll.ZwSetInformationObject,@1765") +#pragma comment(linker, "/EXPORT:ZwSetInformationProcess=ntdll.ZwSetInformationProcess,@1766") +#pragma comment(linker, "/EXPORT:ZwSetInformationResourceManager=ntdll.ZwSetInformationResourceManager,@1767") +#pragma comment(linker, "/EXPORT:ZwSetInformationThread=ntdll.ZwSetInformationThread,@1768") +#pragma comment(linker, "/EXPORT:ZwSetInformationToken=ntdll.ZwSetInformationToken,@1769") +#pragma comment(linker, "/EXPORT:ZwSetInformationTransaction=ntdll.ZwSetInformationTransaction,@1770") +#pragma comment(linker, "/EXPORT:ZwSetInformationTransactionManager=ntdll.ZwSetInformationTransactionManager,@1771") +#pragma comment(linker, "/EXPORT:ZwSetInformationWorkerFactory=ntdll.ZwSetInformationWorkerFactory,@1772") +#pragma comment(linker, "/EXPORT:ZwSetIntervalProfile=ntdll.ZwSetIntervalProfile,@1773") +#pragma comment(linker, "/EXPORT:ZwSetIoCompletion=ntdll.ZwSetIoCompletion,@1774") +#pragma comment(linker, "/EXPORT:ZwSetIoCompletionEx=ntdll.ZwSetIoCompletionEx,@1775") +#pragma comment(linker, "/EXPORT:ZwSetLdtEntries=ntdll.ZwSetLdtEntries,@1776") +#pragma comment(linker, "/EXPORT:ZwSetLowEventPair=ntdll.ZwSetLowEventPair,@1777") +#pragma comment(linker, "/EXPORT:ZwSetLowWaitHighEventPair=ntdll.ZwSetLowWaitHighEventPair,@1778") +#pragma comment(linker, "/EXPORT:ZwSetQuotaInformationFile=ntdll.ZwSetQuotaInformationFile,@1779") +#pragma comment(linker, "/EXPORT:ZwSetSecurityObject=ntdll.ZwSetSecurityObject,@1780") +#pragma comment(linker, "/EXPORT:ZwSetSystemEnvironmentValue=ntdll.ZwSetSystemEnvironmentValue,@1781") +#pragma comment(linker, "/EXPORT:ZwSetSystemEnvironmentValueEx=ntdll.ZwSetSystemEnvironmentValueEx,@1782") +#pragma comment(linker, "/EXPORT:ZwSetSystemInformation=ntdll.ZwSetSystemInformation,@1783") +#pragma comment(linker, "/EXPORT:ZwSetSystemPowerState=ntdll.ZwSetSystemPowerState,@1784") +#pragma comment(linker, "/EXPORT:ZwSetSystemTime=ntdll.ZwSetSystemTime,@1785") +#pragma comment(linker, "/EXPORT:ZwSetThreadExecutionState=ntdll.ZwSetThreadExecutionState,@1786") +#pragma comment(linker, "/EXPORT:ZwSetTimer=ntdll.ZwSetTimer,@1787") +#pragma comment(linker, "/EXPORT:ZwSetTimerEx=ntdll.ZwSetTimerEx,@1788") +#pragma comment(linker, "/EXPORT:ZwSetTimerResolution=ntdll.ZwSetTimerResolution,@1789") +#pragma comment(linker, "/EXPORT:ZwSetUuidSeed=ntdll.ZwSetUuidSeed,@1790") +#pragma comment(linker, "/EXPORT:ZwSetValueKey=ntdll.ZwSetValueKey,@1791") +#pragma comment(linker, "/EXPORT:ZwSetVolumeInformationFile=ntdll.ZwSetVolumeInformationFile,@1792") +#pragma comment(linker, "/EXPORT:ZwShutdownSystem=ntdll.ZwShutdownSystem,@1793") +#pragma comment(linker, "/EXPORT:ZwShutdownWorkerFactory=ntdll.ZwShutdownWorkerFactory,@1794") +#pragma comment(linker, "/EXPORT:ZwSignalAndWaitForSingleObject=ntdll.ZwSignalAndWaitForSingleObject,@1795") +#pragma comment(linker, "/EXPORT:ZwSinglePhaseReject=ntdll.ZwSinglePhaseReject,@1796") +#pragma comment(linker, "/EXPORT:ZwStartProfile=ntdll.ZwStartProfile,@1797") +#pragma comment(linker, "/EXPORT:ZwStopProfile=ntdll.ZwStopProfile,@1798") +#pragma comment(linker, "/EXPORT:ZwSuspendProcess=ntdll.ZwSuspendProcess,@1799") +#pragma comment(linker, "/EXPORT:ZwSuspendThread=ntdll.ZwSuspendThread,@1800") +#pragma comment(linker, "/EXPORT:ZwSystemDebugControl=ntdll.ZwSystemDebugControl,@1801") +#pragma comment(linker, "/EXPORT:ZwTerminateJobObject=ntdll.ZwTerminateJobObject,@1802") +#pragma comment(linker, "/EXPORT:ZwTerminateProcess=ntdll.ZwTerminateProcess,@1803") +#pragma comment(linker, "/EXPORT:ZwTerminateThread=ntdll.ZwTerminateThread,@1804") +#pragma comment(linker, "/EXPORT:ZwTestAlert=ntdll.ZwTestAlert,@1805") +#pragma comment(linker, "/EXPORT:ZwThawRegistry=ntdll.ZwThawRegistry,@1806") +#pragma comment(linker, "/EXPORT:ZwThawTransactions=ntdll.ZwThawTransactions,@1807") +#pragma comment(linker, "/EXPORT:ZwTraceControl=ntdll.ZwTraceControl,@1808") +#pragma comment(linker, "/EXPORT:ZwTraceEvent=ntdll.ZwTraceEvent,@1809") +#pragma comment(linker, "/EXPORT:ZwTranslateFilePath=ntdll.ZwTranslateFilePath,@1810") +#pragma comment(linker, "/EXPORT:ZwUmsThreadYield=ntdll.ZwUmsThreadYield,@1811") +#pragma comment(linker, "/EXPORT:ZwUnloadDriver=ntdll.ZwUnloadDriver,@1812") +#pragma comment(linker, "/EXPORT:ZwUnloadKey=ntdll.ZwUnloadKey,@1814") +#pragma comment(linker, "/EXPORT:ZwUnloadKey2=ntdll.ZwUnloadKey2,@1813") +#pragma comment(linker, "/EXPORT:ZwUnloadKeyEx=ntdll.ZwUnloadKeyEx,@1815") +#pragma comment(linker, "/EXPORT:ZwUnlockFile=ntdll.ZwUnlockFile,@1816") +#pragma comment(linker, "/EXPORT:ZwUnlockVirtualMemory=ntdll.ZwUnlockVirtualMemory,@1817") +#pragma comment(linker, "/EXPORT:ZwUnmapViewOfSection=ntdll.ZwUnmapViewOfSection,@1818") +#pragma comment(linker, "/EXPORT:ZwVdmControl=ntdll.ZwVdmControl,@1819") +#pragma comment(linker, "/EXPORT:ZwWaitForDebugEvent=ntdll.ZwWaitForDebugEvent,@1820") +#pragma comment(linker, "/EXPORT:ZwWaitForKeyedEvent=ntdll.ZwWaitForKeyedEvent,@1821") +#pragma comment(linker, "/EXPORT:ZwWaitForMultipleObjects=ntdll.ZwWaitForMultipleObjects,@1823") +#pragma comment(linker, "/EXPORT:ZwWaitForMultipleObjects32=ntdll.ZwWaitForMultipleObjects32,@1822") +#pragma comment(linker, "/EXPORT:ZwWaitForSingleObject=ntdll.ZwWaitForSingleObject,@1824") +#pragma comment(linker, "/EXPORT:ZwWaitForWorkViaWorkerFactory=ntdll.ZwWaitForWorkViaWorkerFactory,@1825") +#pragma comment(linker, "/EXPORT:ZwWaitHighEventPair=ntdll.ZwWaitHighEventPair,@1826") +#pragma comment(linker, "/EXPORT:ZwWaitLowEventPair=ntdll.ZwWaitLowEventPair,@1827") +#pragma comment(linker, "/EXPORT:ZwWorkerFactoryWorkerReady=ntdll.ZwWorkerFactoryWorkerReady,@1828") +#pragma comment(linker, "/EXPORT:ZwWow64CallFunction64=ntdll.ZwWow64CallFunction64,@1829") +#pragma comment(linker, "/EXPORT:ZwWow64CsrAllocateCaptureBuffer=ntdll.ZwWow64CsrAllocateCaptureBuffer,@1830") +#pragma comment(linker, "/EXPORT:ZwWow64CsrAllocateMessagePointer=ntdll.ZwWow64CsrAllocateMessagePointer,@1831") +#pragma comment(linker, "/EXPORT:ZwWow64CsrCaptureMessageBuffer=ntdll.ZwWow64CsrCaptureMessageBuffer,@1832") +#pragma comment(linker, "/EXPORT:ZwWow64CsrCaptureMessageString=ntdll.ZwWow64CsrCaptureMessageString,@1833") +#pragma comment(linker, "/EXPORT:ZwWow64CsrClientCallServer=ntdll.ZwWow64CsrClientCallServer,@1834") +#pragma comment(linker, "/EXPORT:ZwWow64CsrClientConnectToServer=ntdll.ZwWow64CsrClientConnectToServer,@1835") +#pragma comment(linker, "/EXPORT:ZwWow64CsrFreeCaptureBuffer=ntdll.ZwWow64CsrFreeCaptureBuffer,@1836") +#pragma comment(linker, "/EXPORT:ZwWow64CsrGetProcessId=ntdll.ZwWow64CsrGetProcessId,@1837") +#pragma comment(linker, "/EXPORT:ZwWow64CsrIdentifyAlertableThread=ntdll.ZwWow64CsrIdentifyAlertableThread,@1838") +#pragma comment(linker, "/EXPORT:ZwWow64CsrVerifyRegion=ntdll.ZwWow64CsrVerifyRegion,@1839") +#pragma comment(linker, "/EXPORT:ZwWow64DebuggerCall=ntdll.ZwWow64DebuggerCall,@1840") +#pragma comment(linker, "/EXPORT:ZwWow64GetCurrentProcessorNumberEx=ntdll.ZwWow64GetCurrentProcessorNumberEx,@1841") +#pragma comment(linker, "/EXPORT:ZwWow64GetNativeSystemInformation=ntdll.ZwWow64GetNativeSystemInformation,@1842") +#pragma comment(linker, "/EXPORT:ZwWow64InterlockedPopEntrySList=ntdll.ZwWow64InterlockedPopEntrySList,@1843") +#pragma comment(linker, "/EXPORT:ZwWow64QueryInformationProcess64=ntdll.ZwWow64QueryInformationProcess64,@1844") +#pragma comment(linker, "/EXPORT:ZwWow64QueryVirtualMemory64=ntdll.ZwWow64QueryVirtualMemory64,@1845") +#pragma comment(linker, "/EXPORT:ZwWow64ReadVirtualMemory64=ntdll.ZwWow64ReadVirtualMemory64,@1846") +#pragma comment(linker, "/EXPORT:ZwWow64WriteVirtualMemory64=ntdll.ZwWow64WriteVirtualMemory64,@1847") +#pragma comment(linker, "/EXPORT:ZwWriteFile=ntdll.ZwWriteFile,@1848") +#pragma comment(linker, "/EXPORT:ZwWriteFileGather=ntdll.ZwWriteFileGather,@1849") +#pragma comment(linker, "/EXPORT:ZwWriteRequestData=ntdll.ZwWriteRequestData,@1850") +#pragma comment(linker, "/EXPORT:ZwWriteVirtualMemory=ntdll.ZwWriteVirtualMemory,@1851") +#pragma comment(linker, "/EXPORT:ZwYieldExecution=ntdll.ZwYieldExecution,@1852") +#pragma comment(linker, "/EXPORT:__CIcos=ntdll._CIcos,@1853") +#pragma comment(linker, "/EXPORT:__CIlog=ntdll._CIlog,@1854") +#pragma comment(linker, "/EXPORT:__CIpow=ntdll._CIpow,@1855") +#pragma comment(linker, "/EXPORT:__CIsin=ntdll._CIsin,@1856") +#pragma comment(linker, "/EXPORT:__CIsqrt=ntdll._CIsqrt,@1857") +#pragma comment(linker, "/EXPORT:___isascii=ntdll.__isascii,@1858") +#pragma comment(linker, "/EXPORT:___iscsym=ntdll.__iscsym,@1859") +#pragma comment(linker, "/EXPORT:___iscsymf=ntdll.__iscsymf,@1860") +#pragma comment(linker, "/EXPORT:___toascii=ntdll.__toascii,@1861") +#pragma comment(linker, "/EXPORT:__alldiv=ntdll._alldiv,@1862") +#pragma comment(linker, "/EXPORT:__alldvrm=ntdll._alldvrm,@1863") +#pragma comment(linker, "/EXPORT:__allmul=ntdll._allmul,@1864") +#pragma comment(linker, "/EXPORT:__alloca_probe=ntdll._alloca_probe,@1865") +#pragma comment(linker, "/EXPORT:__alloca_probe_16=ntdll._alloca_probe_16,@1866") +#pragma comment(linker, "/EXPORT:__alloca_probe_8=ntdll._alloca_probe_8,@1867") +#pragma comment(linker, "/EXPORT:__allrem=ntdll._allrem,@1868") +#pragma comment(linker, "/EXPORT:__allshl=ntdll._allshl,@1869") +#pragma comment(linker, "/EXPORT:__allshr=ntdll._allshr,@1870") +#pragma comment(linker, "/EXPORT:__atoi64=ntdll._atoi64,@1871") +#pragma comment(linker, "/EXPORT:__aulldiv=ntdll._aulldiv,@1872") +#pragma comment(linker, "/EXPORT:__aulldvrm=ntdll._aulldvrm,@1873") +#pragma comment(linker, "/EXPORT:__aullrem=ntdll._aullrem,@1874") +#pragma comment(linker, "/EXPORT:__aullshr=ntdll._aullshr,@1875") +#pragma comment(linker, "/EXPORT:__chkstk=ntdll._chkstk,@1876") +#pragma comment(linker, "/EXPORT:__fltused=ntdll._fltused,@1877") +#pragma comment(linker, "/EXPORT:__ftol=ntdll._ftol,@1878") +#pragma comment(linker, "/EXPORT:__i64toa=ntdll._i64toa,@1879") +#pragma comment(linker, "/EXPORT:__i64toa_s=ntdll._i64toa_s,@1880") +#pragma comment(linker, "/EXPORT:__i64tow=ntdll._i64tow,@1881") +#pragma comment(linker, "/EXPORT:__i64tow_s=ntdll._i64tow_s,@1882") +#pragma comment(linker, "/EXPORT:__itoa=ntdll._itoa,@1883") +#pragma comment(linker, "/EXPORT:__itoa_s=ntdll._itoa_s,@1884") +#pragma comment(linker, "/EXPORT:__itow=ntdll._itow,@1885") +#pragma comment(linker, "/EXPORT:__itow_s=ntdll._itow_s,@1886") +#pragma comment(linker, "/EXPORT:__lfind=ntdll._lfind,@1887") +#pragma comment(linker, "/EXPORT:__ltoa=ntdll._ltoa,@1888") +#pragma comment(linker, "/EXPORT:__ltoa_s=ntdll._ltoa_s,@1889") +#pragma comment(linker, "/EXPORT:__ltow=ntdll._ltow,@1890") +#pragma comment(linker, "/EXPORT:__ltow_s=ntdll._ltow_s,@1891") +#pragma comment(linker, "/EXPORT:__makepath_s=ntdll._makepath_s,@1892") +#pragma comment(linker, "/EXPORT:__memccpy=ntdll._memccpy,@1893") +#pragma comment(linker, "/EXPORT:__memicmp=ntdll._memicmp,@1894") +#pragma comment(linker, "/EXPORT:__snprintf=ntdll._snprintf,@1895") +#pragma comment(linker, "/EXPORT:__snprintf_s=ntdll._snprintf_s,@1896") +#pragma comment(linker, "/EXPORT:__snscanf_s=ntdll._snscanf_s,@1897") +#pragma comment(linker, "/EXPORT:__snwprintf=ntdll._snwprintf,@1898") +#pragma comment(linker, "/EXPORT:__snwprintf_s=ntdll._snwprintf_s,@1899") +#pragma comment(linker, "/EXPORT:__snwscanf_s=ntdll._snwscanf_s,@1900") +#pragma comment(linker, "/EXPORT:__splitpath=ntdll._splitpath,@1901") +#pragma comment(linker, "/EXPORT:__splitpath_s=ntdll._splitpath_s,@1902") +#pragma comment(linker, "/EXPORT:__strcmpi=ntdll._strcmpi,@1903") +#pragma comment(linker, "/EXPORT:__stricmp=ntdll._stricmp,@1904") +#pragma comment(linker, "/EXPORT:__strlwr=ntdll._strlwr,@1905") +#pragma comment(linker, "/EXPORT:__strnicmp=ntdll._strnicmp,@1906") +#pragma comment(linker, "/EXPORT:__strnset_s=ntdll._strnset_s,@1907") +#pragma comment(linker, "/EXPORT:__strset_s=ntdll._strset_s,@1908") +#pragma comment(linker, "/EXPORT:__strupr=ntdll._strupr,@1909") +#pragma comment(linker, "/EXPORT:__swprintf=ntdll._swprintf,@1910") +#pragma comment(linker, "/EXPORT:__ui64toa=ntdll._ui64toa,@1911") +#pragma comment(linker, "/EXPORT:__ui64toa_s=ntdll._ui64toa_s,@1912") +#pragma comment(linker, "/EXPORT:__ui64tow=ntdll._ui64tow,@1913") +#pragma comment(linker, "/EXPORT:__ui64tow_s=ntdll._ui64tow_s,@1914") +#pragma comment(linker, "/EXPORT:__ultoa=ntdll._ultoa,@1915") +#pragma comment(linker, "/EXPORT:__ultoa_s=ntdll._ultoa_s,@1916") +#pragma comment(linker, "/EXPORT:__ultow=ntdll._ultow,@1917") +#pragma comment(linker, "/EXPORT:__ultow_s=ntdll._ultow_s,@1918") +#pragma comment(linker, "/EXPORT:__vscwprintf=ntdll._vscwprintf,@1919") +#pragma comment(linker, "/EXPORT:__vsnprintf=ntdll._vsnprintf,@1920") +#pragma comment(linker, "/EXPORT:__vsnprintf_s=ntdll._vsnprintf_s,@1921") +#pragma comment(linker, "/EXPORT:__vsnwprintf=ntdll._vsnwprintf,@1922") +#pragma comment(linker, "/EXPORT:__vsnwprintf_s=ntdll._vsnwprintf_s,@1923") +#pragma comment(linker, "/EXPORT:__vswprintf=ntdll._vswprintf,@1924") +#pragma comment(linker, "/EXPORT:__wcsicmp=ntdll._wcsicmp,@1925") +#pragma comment(linker, "/EXPORT:__wcslwr=ntdll._wcslwr,@1926") +#pragma comment(linker, "/EXPORT:__wcsnicmp=ntdll._wcsnicmp,@1927") +#pragma comment(linker, "/EXPORT:__wcsnset_s=ntdll._wcsnset_s,@1928") +#pragma comment(linker, "/EXPORT:__wcsset_s=ntdll._wcsset_s,@1929") +#pragma comment(linker, "/EXPORT:__wcstoui64=ntdll._wcstoui64,@1930") +#pragma comment(linker, "/EXPORT:__wcsupr=ntdll._wcsupr,@1931") +#pragma comment(linker, "/EXPORT:__wmakepath_s=ntdll._wmakepath_s,@1932") +#pragma comment(linker, "/EXPORT:__wsplitpath_s=ntdll._wsplitpath_s,@1933") +#pragma comment(linker, "/EXPORT:__wtoi=ntdll._wtoi,@1934") +#pragma comment(linker, "/EXPORT:__wtoi64=ntdll._wtoi64,@1935") +#pragma comment(linker, "/EXPORT:__wtol=ntdll._wtol,@1936") +#pragma comment(linker, "/EXPORT:abs=ntdll.abs,@1937") +#pragma comment(linker, "/EXPORT:atan=ntdll.atan,@1938") +#pragma comment(linker, "/EXPORT:atoi=ntdll.atoi,@1939") +#pragma comment(linker, "/EXPORT:atol=ntdll.atol,@1940") +#pragma comment(linker, "/EXPORT:bsearch=ntdll.bsearch,@1941") +#pragma comment(linker, "/EXPORT:ceil=ntdll.ceil,@1942") +#pragma comment(linker, "/EXPORT:cos=ntdll.cos,@1943") +#pragma comment(linker, "/EXPORT:fabs=ntdll.fabs,@1944") +#pragma comment(linker, "/EXPORT:floor=ntdll.floor,@1945") +#pragma comment(linker, "/EXPORT:isalnum=ntdll.isalnum,@1946") +#pragma comment(linker, "/EXPORT:isalpha=ntdll.isalpha,@1947") +#pragma comment(linker, "/EXPORT:iscntrl=ntdll.iscntrl,@1948") +#pragma comment(linker, "/EXPORT:isdigit=ntdll.isdigit,@1949") +#pragma comment(linker, "/EXPORT:isgraph=ntdll.isgraph,@1950") +#pragma comment(linker, "/EXPORT:islower=ntdll.islower,@1951") +#pragma comment(linker, "/EXPORT:isprint=ntdll.isprint,@1952") +#pragma comment(linker, "/EXPORT:ispunct=ntdll.ispunct,@1953") +#pragma comment(linker, "/EXPORT:isspace=ntdll.isspace,@1954") +#pragma comment(linker, "/EXPORT:isupper=ntdll.isupper,@1955") +#pragma comment(linker, "/EXPORT:iswalpha=ntdll.iswalpha,@1956") +#pragma comment(linker, "/EXPORT:iswctype=ntdll.iswctype,@1957") +#pragma comment(linker, "/EXPORT:iswdigit=ntdll.iswdigit,@1958") +#pragma comment(linker, "/EXPORT:iswlower=ntdll.iswlower,@1959") +#pragma comment(linker, "/EXPORT:iswspace=ntdll.iswspace,@1960") +#pragma comment(linker, "/EXPORT:iswxdigit=ntdll.iswxdigit,@1961") +#pragma comment(linker, "/EXPORT:isxdigit=ntdll.isxdigit,@1962") +#pragma comment(linker, "/EXPORT:labs=ntdll.labs,@1963") +#pragma comment(linker, "/EXPORT:log=ntdll.log,@1964") +#pragma comment(linker, "/EXPORT:mbstowcs=ntdll.mbstowcs,@1965") +#pragma comment(linker, "/EXPORT:memchr=ntdll.memchr,@1966") +#pragma comment(linker, "/EXPORT:memcmp=ntdll.memcmp,@1967") +#pragma comment(linker, "/EXPORT:memcpy=ntdll.memcpy,@1968") +#pragma comment(linker, "/EXPORT:memcpy_s=ntdll.memcpy_s,@1969") +#pragma comment(linker, "/EXPORT:memmove=ntdll.memmove,@1970") +#pragma comment(linker, "/EXPORT:memmove_s=ntdll.memmove_s,@1971") +#pragma comment(linker, "/EXPORT:memset=ntdll.memset,@1972") +#pragma comment(linker, "/EXPORT:pow=ntdll.pow,@1973") +#pragma comment(linker, "/EXPORT:qsort=ntdll.qsort,@1974") +#pragma comment(linker, "/EXPORT:sin=ntdll.sin,@1975") +#pragma comment(linker, "/EXPORT:sprintf=ntdll.sprintf,@1976") +#pragma comment(linker, "/EXPORT:sprintf_s=ntdll.sprintf_s,@1977") +#pragma comment(linker, "/EXPORT:sqrt=ntdll.sqrt,@1978") +#pragma comment(linker, "/EXPORT:sscanf=ntdll.sscanf,@1979") +#pragma comment(linker, "/EXPORT:sscanf_s=ntdll.sscanf_s,@1980") +#pragma comment(linker, "/EXPORT:strcat=ntdll.strcat,@1981") +#pragma comment(linker, "/EXPORT:strcat_s=ntdll.strcat_s,@1982") +#pragma comment(linker, "/EXPORT:strchr=ntdll.strchr,@1983") +#pragma comment(linker, "/EXPORT:strcmp=ntdll.strcmp,@1984") +#pragma comment(linker, "/EXPORT:strcpy=ntdll.strcpy,@1985") +#pragma comment(linker, "/EXPORT:strcpy_s=ntdll.strcpy_s,@1986") +#pragma comment(linker, "/EXPORT:strcspn=ntdll.strcspn,@1987") +#pragma comment(linker, "/EXPORT:strlen=ntdll.strlen,@1988") +#pragma comment(linker, "/EXPORT:strncat=ntdll.strncat,@1989") +#pragma comment(linker, "/EXPORT:strncat_s=ntdll.strncat_s,@1990") +#pragma comment(linker, "/EXPORT:strncmp=ntdll.strncmp,@1991") +#pragma comment(linker, "/EXPORT:strncpy=ntdll.strncpy,@1992") +#pragma comment(linker, "/EXPORT:strncpy_s=ntdll.strncpy_s,@1993") +#pragma comment(linker, "/EXPORT:strnlen=ntdll.strnlen,@1994") +#pragma comment(linker, "/EXPORT:strpbrk=ntdll.strpbrk,@1995") +#pragma comment(linker, "/EXPORT:strrchr=ntdll.strrchr,@1996") +#pragma comment(linker, "/EXPORT:strspn=ntdll.strspn,@1997") +#pragma comment(linker, "/EXPORT:strstr=ntdll.strstr,@1998") +#pragma comment(linker, "/EXPORT:strtok_s=ntdll.strtok_s,@1999") +#pragma comment(linker, "/EXPORT:strtol=ntdll.strtol,@2000") +#pragma comment(linker, "/EXPORT:strtoul=ntdll.strtoul,@2001") +#pragma comment(linker, "/EXPORT:swprintf=ntdll.swprintf,@2002") +#pragma comment(linker, "/EXPORT:swprintf_s=ntdll.swprintf_s,@2003") +#pragma comment(linker, "/EXPORT:swscanf_s=ntdll.swscanf_s,@2004") +#pragma comment(linker, "/EXPORT:tan=ntdll.tan,@2005") +#pragma comment(linker, "/EXPORT:tolower=ntdll.tolower,@2006") +#pragma comment(linker, "/EXPORT:toupper=ntdll.toupper,@2007") +#pragma comment(linker, "/EXPORT:towlower=ntdll.towlower,@2008") +#pragma comment(linker, "/EXPORT:towupper=ntdll.towupper,@2009") +#pragma comment(linker, "/EXPORT:vDbgPrintEx=ntdll.vDbgPrintEx,@2010") +#pragma comment(linker, "/EXPORT:vDbgPrintExWithPrefix=ntdll.vDbgPrintExWithPrefix,@2011") +#pragma comment(linker, "/EXPORT:vsprintf=ntdll.vsprintf,@2012") +#pragma comment(linker, "/EXPORT:vsprintf_s=ntdll.vsprintf_s,@2013") +#pragma comment(linker, "/EXPORT:vswprintf_s=ntdll.vswprintf_s,@2014") +#pragma comment(linker, "/EXPORT:wcscat=ntdll.wcscat,@2015") +#pragma comment(linker, "/EXPORT:wcscat_s=ntdll.wcscat_s,@2016") +#pragma comment(linker, "/EXPORT:wcschr=ntdll.wcschr,@2017") +#pragma comment(linker, "/EXPORT:wcscmp=ntdll.wcscmp,@2018") +#pragma comment(linker, "/EXPORT:wcscpy=ntdll.wcscpy,@2019") +#pragma comment(linker, "/EXPORT:wcscpy_s=ntdll.wcscpy_s,@2020") +#pragma comment(linker, "/EXPORT:wcscspn=ntdll.wcscspn,@2021") +#pragma comment(linker, "/EXPORT:wcslen=ntdll.wcslen,@2022") +#pragma comment(linker, "/EXPORT:wcsncat=ntdll.wcsncat,@2023") +#pragma comment(linker, "/EXPORT:wcsncat_s=ntdll.wcsncat_s,@2024") +#pragma comment(linker, "/EXPORT:wcsncmp=ntdll.wcsncmp,@2025") +#pragma comment(linker, "/EXPORT:wcsncpy=ntdll.wcsncpy,@2026") +#pragma comment(linker, "/EXPORT:wcsncpy_s=ntdll.wcsncpy_s,@2027") +#pragma comment(linker, "/EXPORT:wcsnlen=ntdll.wcsnlen,@2028") +#pragma comment(linker, "/EXPORT:wcspbrk=ntdll.wcspbrk,@2029") +#pragma comment(linker, "/EXPORT:wcsrchr=ntdll.wcsrchr,@2030") +#pragma comment(linker, "/EXPORT:wcsspn=ntdll.wcsspn,@2031") +#pragma comment(linker, "/EXPORT:wcsstr=ntdll.wcsstr,@2032") +#pragma comment(linker, "/EXPORT:wcstol=ntdll.wcstol,@2033") +#pragma comment(linker, "/EXPORT:wcstombs=ntdll.wcstombs,@2034") +#pragma comment(linker, "/EXPORT:wcstoul=ntdll.wcstoul,@2035") +#pragma comment(linker, "/EXPORT:__OrdinalFunction1=ntdll.#1,@1,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2=ntdll.#2,@2,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction3=ntdll.#3,@3,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction4=ntdll.#4,@4,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction5=ntdll.#5,@5,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction6=ntdll.#6,@6,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction7=ntdll.#7,@7,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction8=ntdll.#8,@8,NONAME") + +#endif \ No newline at end of file diff --git a/01-Extended DLLs/KxNt/kxnt.def b/01-Extended DLLs/KxNt/kxnt.def new file mode 100644 index 0000000..df67569 --- /dev/null +++ b/01-Extended DLLs/KxNt/kxnt.def @@ -0,0 +1,30 @@ +LIBRARY KxNt +EXPORTS + + LdrResolveDelayLoadedAPI = KexDll.KexLdrResolveDelayLoadedAPI + LdrGetDllFullName = KexDll.KexLdrGetDllFullName + + LdrLoadDll = KexDll.KexLdrLoadDll + LdrGetDllHandle = KexDll.KexLdrGetDllHandle + LdrGetDllHandleEx = KexDll.KexLdrGetDllHandleEx + LdrGetProcedureAddress = KexDll.KexLdrGetProcedureAddress + LdrGetProcedureAddressEx = KexDll.KexLdrGetProcedureAddressEx + + RtlWaitOnAddress = KexDll.KexRtlWaitOnAddress + RtlWakeAddressAll = KexDll.KexRtlWakeAddressAll + RtlWakeAddressSingle = KexDll.KexRtlWakeAddressSingle + RtlWow64GetProcessMachines = KexDll.KexRtlWow64GetProcessMachines + RtlSetBit = KexDll.KexRtlSetBit + RtlClearBit = KexDll.KexRtlClearBit + RtlQueryPackageIdentity = KexDll.KexRtlQueryPackageIdentity + RtlQueryPackageIdentityEx = KexDll.KexRtlQueryPackageIdentityEx + RtlCheckPortableOperatingSystem = KexDll.KexRtlCheckPortableOperatingSystem + RtlUnsubscribeWnfStateChangeNotification = KexDll.KexRtlUnsubscribeWnfStateChangeNotification + RtlQueryWnfStateData = KexDll.KexRtlQueryWnfStateData + RtlPublishWnfStateData = KexDll.KexRtlPublishWnfStateData + RtlSubscribeWnfStateChangeNotification = KexDll.KexRtlSubscribeWnfStateChangeNotification + RtlAddGrowableFunctionTable = KexDll.KexRtlAddGrowableFunctionTable + + ApiSetQueryApiSetPresence = KexDll.ApiSetQueryApiSetPresence + + EtwEventSetInformation = KexDll.KexEtwEventSetInformation \ No newline at end of file diff --git a/01-Extended DLLs/KxUser/KxUser.rc b/01-Extended DLLs/KxUser/KxUser.rc new file mode 100644 index 0000000..a9c87a2 Binary files /dev/null and b/01-Extended DLLs/KxUser/KxUser.rc differ diff --git a/01-Extended DLLs/KxUser/KxUser.vcxproj b/01-Extended DLLs/KxUser/KxUser.vcxproj new file mode 100644 index 0000000..3dc43f4 --- /dev/null +++ b/01-Extended DLLs/KxUser/KxUser.vcxproj @@ -0,0 +1,249 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {BB5B3C11-F77A-4C46-AE5A-76153DD0CA79} + Win32Proj + KxUser + + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + + + + + + + + + + + + + + + + + false + false + + + false + false + + + false + false + + + false + false + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;KXUSER_EXPORTS;%(PreprocessorDefinitions) + false + false + Default + false + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + StdCall + CompileAsC + + + Windows + true + kxuser.def + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + DllMain + true + /ignore:4104 /ignore:4197 %(AdditionalOptions) + + + $(SolutionDir)\00-Common Headers + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;KXUSER_EXPORTS;%(PreprocessorDefinitions) + false + false + Default + false + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + StdCall + CompileAsC + + + Windows + true + kxuser.def + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + DllMain + true + /ignore:4104 /ignore:4197 %(AdditionalOptions) + + + $(SolutionDir)\00-Common Headers + + + + + Level3 + NotUsing + MinSpace + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;KXUSER_EXPORTS;%(PreprocessorDefinitions) + false + false + Default + false + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + StdCall + CompileAsC + OnlyExplicitInline + Size + true + + + Windows + true + true + true + kxuser.def + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + DllMain + true + /ignore:4104 /ignore:4197 %(AdditionalOptions) + + + $(SolutionDir)\00-Common Headers + + + + + Level3 + NotUsing + MinSpace + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;KXUSER_EXPORTS;%(PreprocessorDefinitions) + false + false + Default + false + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + StdCall + CompileAsC + OnlyExplicitInline + Size + true + + + Windows + true + true + true + kxuser.def + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + DllMain + true + /ignore:4104 /ignore:4197 %(AdditionalOptions) + + + $(SolutionDir)\00-Common Headers + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/01-Extended DLLs/KxUser/KxUser.vcxproj.filters b/01-Extended DLLs/KxUser/KxUser.vcxproj.filters new file mode 100644 index 0000000..767359f --- /dev/null +++ b/01-Extended DLLs/KxUser/KxUser.vcxproj.filters @@ -0,0 +1,70 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Source Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/01-Extended DLLs/KxUser/autorot.c b/01-Extended DLLs/KxUser/autorot.c new file mode 100644 index 0000000..b015b46 --- /dev/null +++ b/01-Extended DLLs/KxUser/autorot.c @@ -0,0 +1,15 @@ +#include "buildcfg.h" +#include "kxuserp.h" + +BOOL WINAPI SetDisplayAutoRotationPreferences( + IN ORIENTATION_PREFERENCE Orientation) +{ + return TRUE; +} + +BOOL WINAPI GetDisplayAutoRotationPreferences( + OUT PORIENTATION_PREFERENCE Orientation) +{ + *Orientation = ORIENTATION_PREFERENCE_NONE; + return TRUE; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxUser/blutooth.c b/01-Extended DLLs/KxUser/blutooth.c new file mode 100644 index 0000000..0bac3d5 --- /dev/null +++ b/01-Extended DLLs/KxUser/blutooth.c @@ -0,0 +1,134 @@ +#include "buildcfg.h" +#include "kxuserp.h" + +// +// These are all stubs. No idea how to begin implementing them properly. +// Let's see if they are even that important. +// + +KXUSERAPI HRESULT WINAPI BluetoothGATTAbortReliableWrite( + IN HANDLE Device, + IN ULONG ReliableWriteContext, + IN ULONG Flags) +{ + return ERROR_NOT_SUPPORTED; +} + +KXUSERAPI HRESULT WINAPI BluetoothGATTBeginReliableWrite( + IN HANDLE Device, + OUT PVOID ReliableWriteContext, + IN ULONG Flags) +{ + return ERROR_NOT_SUPPORTED; +} + +KXUSERAPI HRESULT WINAPI BluetoothGATTEndReliableWrite( + IN HANDLE Device, + IN ULONG ReliableWriteContext, + IN ULONG Flags) +{ + return ERROR_NOT_SUPPORTED; +} + +KXUSERAPI HRESULT WINAPI BluetoothGATTGetCharacteristics( + IN HANDLE Device, + IN PVOID Service OPTIONAL, + IN USHORT CharacteristicsBufferCount, + OUT PVOID CharacteristicsBuffer OPTIONAL, + OUT PUSHORT CharacteristicsBufferActual, + IN ULONG Flags) +{ + return ERROR_NOT_SUPPORTED; +} + +KXUSERAPI HRESULT WINAPI BluetoothGATTGetCharacteristicValue( + IN HANDLE Device, + IN PVOID Characteristic, + IN ULONG CharacteristicValueDataSize, + OUT PVOID CharacteristicValue OPTIONAL, + OUT PUSHORT CharacteristicValueSizeRequired OPTIONAL, + IN ULONG Flags) +{ + return ERROR_NOT_SUPPORTED; +} + +KXUSERAPI HRESULT WINAPI BluetoothGATTGetDescriptors( + IN HANDLE Device, + IN PVOID Characteristic, + IN USHORT DescriptorsBufferCount, + OUT PVOID DescriptorsBuffer OPTIONAL, + OUT PUSHORT DescriptorsBufferActual, + IN ULONG Flags) +{ + return ERROR_NOT_SUPPORTED; +} + +KXUSERAPI HRESULT WINAPI BluetoothGATTGetDescriptorValue( + IN HANDLE Device, + IN PVOID Descriptor, + IN ULONG DescriptorValueDataSize, + OUT PVOID DescriptorValue OPTIONAL, + OUT PUSHORT DescriptorValueSizeRequired OPTIONAL, + IN ULONG Flags) +{ + return ERROR_NOT_SUPPORTED; +} + +KXUSERAPI HRESULT WINAPI BluetoothGATTGetIncludedServices( + IN HANDLE Device, + IN PVOID ParentService OPTIONAL, + IN USHORT IncludedServicesBufferCount, + OUT PVOID IncludedServicesBuffer OPTIONAL, + OUT PUSHORT IncludedServicesBufferActual, + IN ULONG Flags) +{ + return ERROR_NOT_SUPPORTED; +} + +KXUSERAPI HRESULT WINAPI BluetoothGATTGetServices( + IN HANDLE Device, + IN USHORT ServicesBufferCount, + OUT PVOID ServicesBuffer OPTIONAL, + OUT PUSHORT ServicesBufferActual, + IN ULONG Flags) +{ + return ERROR_NOT_SUPPORTED; +} + +KXUSERAPI HRESULT WINAPI BluetoothGATTRegisterEvent( + IN HANDLE Service, + IN ULONG EventType, + IN PVOID EventParameterIn, + IN PVOID Callback, + IN PVOID CallbackContext OPTIONAL, + OUT PVOID EventHandle, + IN ULONG Flags) +{ + return ERROR_NOT_SUPPORTED; +} + +KXUSERAPI HRESULT WINAPI BluetoothGATTSetCharacteristicValue( + IN HANDLE Device, + IN PVOID Characteristic, + IN PVOID CharacteristicValue, + IN PVOID ReliableWriteContext OPTIONAL, + IN ULONG Flags) +{ + return ERROR_NOT_SUPPORTED; +} + +KXUSERAPI HRESULT WINAPI BluetoothGATTSetDescriptorValue( + IN HANDLE Device, + IN PVOID Descriptor, + IN PVOID DescriptorValue, + IN ULONG Flags) +{ + return ERROR_NOT_SUPPORTED; +} + +KXUSERAPI HRESULT WINAPI BluetoothGATTUnregisterEvent( + IN HANDLE EventHandle, + IN ULONG Flags) +{ + return ERROR_NOT_SUPPORTED; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxUser/buildcfg.h b/01-Extended DLLs/KxUser/buildcfg.h new file mode 100644 index 0000000..b4fcd35 --- /dev/null +++ b/01-Extended DLLs/KxUser/buildcfg.h @@ -0,0 +1,50 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN +#define NOGDICAPMASKS +#define NOVIRTUALKEYCODES +#define NOWINSTYLES +#define NOMENUS +#define NOICONS +#define NOKEYSTATES +#define NOSYSCOMMANDS +#define NORASTEROPS +#define NOSHOWWINDOW +#define NOATOM +#define NOCLIPBOARD +#define NOCOLOR +#define NODRAWTEXT +#define NOKERNEL +#define NONLS +#define NOMB +#define NOMEMMGR +#define NOOPENFILE +#define NOSCROLL +#define NOTEXTMETRIC +#define NOWH +#define NOWINOFFSETS +#define NOCOMM +#define NOKANJI +#define NOHELP +#define NOPROFILER +#define NODEFERWINDOWPOS +#define NOMCX +#define NOCRYPT +#define NOMETAFILE +#define NOSERVICE +#define NOSOUND +#define _UXTHEME_H_ + +#ifdef _M_X64 +# pragma comment(lib, "user32_x64.lib") +#else +# pragma comment(lib, "user32_x86.lib") +#endif + +#pragma comment(lib, "gdi32.lib") + +#define KXUSERAPI + +#define KEX_TARGET_TYPE_DLL +#define KEX_ENV_WIN32 +#define KEX_COMPONENT L"KxUser" diff --git a/01-Extended DLLs/KxUser/dllmain.c b/01-Extended DLLs/KxUser/dllmain.c new file mode 100644 index 0000000..246c2bb --- /dev/null +++ b/01-Extended DLLs/KxUser/dllmain.c @@ -0,0 +1,43 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// dllmain.c +// +// Abstract: +// +// Main file for KXBASE. +// +// Author: +// +// vxiiduu (10-Feb-2022) +// +// Environment: +// +// Win32 mode. +// +// Revision History: +// +// vxiiduu 10-Feb-2024 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kxuserp.h" + +PKEX_PROCESS_DATA KexData = NULL; + +BOOL WINAPI DllMain( + IN PVOID DllBase, + IN ULONG Reason, + IN PCONTEXT Context) +{ + if (Reason == DLL_PROCESS_ATTACH) { + LdrDisableThreadCalloutsForDll(DllBase); + + KexDataInitialize(&KexData); + KexLogDebugEvent(L"DllMain called with DLL_PROCESS_ATTACH"); + } + + return TRUE; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxUser/forwards.c b/01-Extended DLLs/KxUser/forwards.c new file mode 100644 index 0000000..5610d63 --- /dev/null +++ b/01-Extended DLLs/KxUser/forwards.c @@ -0,0 +1,4571 @@ +#ifdef _M_X64 +// Generated by KexExprt from "C:\Windows\system32\user32.dll" +#pragma comment(linker, "/EXPORT:ActivateKeyboardLayout=user32.ActivateKeyboardLayout") +#pragma comment(linker, "/EXPORT:AddClipboardFormatListener=user32.AddClipboardFormatListener") +#pragma comment(linker, "/EXPORT:AdjustWindowRect=user32.AdjustWindowRect") +#pragma comment(linker, "/EXPORT:AdjustWindowRectEx=user32.AdjustWindowRectEx") +#pragma comment(linker, "/EXPORT:AlignRects=user32.AlignRects") +#pragma comment(linker, "/EXPORT:AllowForegroundActivation=user32.AllowForegroundActivation") +#pragma comment(linker, "/EXPORT:AllowSetForegroundWindow=user32.AllowSetForegroundWindow") +#pragma comment(linker, "/EXPORT:AnimateWindow=user32.AnimateWindow") +#pragma comment(linker, "/EXPORT:AnyPopup=user32.AnyPopup") +#pragma comment(linker, "/EXPORT:AppendMenuA=user32.AppendMenuA") +#pragma comment(linker, "/EXPORT:AppendMenuW=user32.AppendMenuW") +#pragma comment(linker, "/EXPORT:ArrangeIconicWindows=user32.ArrangeIconicWindows") +#pragma comment(linker, "/EXPORT:AttachThreadInput=user32.AttachThreadInput") +#pragma comment(linker, "/EXPORT:BeginDeferWindowPos=user32.BeginDeferWindowPos") +#pragma comment(linker, "/EXPORT:BeginPaint=user32.BeginPaint") +#pragma comment(linker, "/EXPORT:BlockInput=user32.BlockInput") +#pragma comment(linker, "/EXPORT:BringWindowToTop=user32.BringWindowToTop") +#pragma comment(linker, "/EXPORT:BroadcastSystemMessage=user32.BroadcastSystemMessage") +#pragma comment(linker, "/EXPORT:BroadcastSystemMessageA=user32.BroadcastSystemMessageA") +#pragma comment(linker, "/EXPORT:BroadcastSystemMessageExA=user32.BroadcastSystemMessageExA") +#pragma comment(linker, "/EXPORT:BroadcastSystemMessageExW=user32.BroadcastSystemMessageExW") +#pragma comment(linker, "/EXPORT:BroadcastSystemMessageW=user32.BroadcastSystemMessageW") +#pragma comment(linker, "/EXPORT:BuildReasonArray=user32.BuildReasonArray") +#pragma comment(linker, "/EXPORT:CalcMenuBar=user32.CalcMenuBar") +#pragma comment(linker, "/EXPORT:CalculatePopupWindowPosition=user32.CalculatePopupWindowPosition") +#pragma comment(linker, "/EXPORT:CallMsgFilter=user32.CallMsgFilter") +#pragma comment(linker, "/EXPORT:CallMsgFilterA=user32.CallMsgFilterA") +#pragma comment(linker, "/EXPORT:CallMsgFilterW=user32.CallMsgFilterW") +#pragma comment(linker, "/EXPORT:CallNextHookEx=user32.CallNextHookEx") +#pragma comment(linker, "/EXPORT:CallWindowProcA=user32.CallWindowProcA") +#pragma comment(linker, "/EXPORT:CallWindowProcW=user32.CallWindowProcW") +#pragma comment(linker, "/EXPORT:CancelShutdown=user32.CancelShutdown") +#pragma comment(linker, "/EXPORT:CascadeChildWindows=user32.CascadeChildWindows") +#pragma comment(linker, "/EXPORT:CascadeWindows=user32.CascadeWindows") +#pragma comment(linker, "/EXPORT:ChangeClipboardChain=user32.ChangeClipboardChain") +#pragma comment(linker, "/EXPORT:ChangeDisplaySettingsA=user32.ChangeDisplaySettingsA") +#pragma comment(linker, "/EXPORT:ChangeDisplaySettingsExA=user32.ChangeDisplaySettingsExA") +#pragma comment(linker, "/EXPORT:ChangeDisplaySettingsExW=user32.ChangeDisplaySettingsExW") +#pragma comment(linker, "/EXPORT:ChangeDisplaySettingsW=user32.ChangeDisplaySettingsW") +#pragma comment(linker, "/EXPORT:ChangeMenuA=user32.ChangeMenuA") +#pragma comment(linker, "/EXPORT:ChangeMenuW=user32.ChangeMenuW") +#pragma comment(linker, "/EXPORT:ChangeWindowMessageFilter=user32.ChangeWindowMessageFilter") +#pragma comment(linker, "/EXPORT:ChangeWindowMessageFilterEx=user32.ChangeWindowMessageFilterEx") +#pragma comment(linker, "/EXPORT:CharLowerA=user32.CharLowerA") +#pragma comment(linker, "/EXPORT:CharLowerBuffA=user32.CharLowerBuffA") +#pragma comment(linker, "/EXPORT:CharLowerBuffW=user32.CharLowerBuffW") +#pragma comment(linker, "/EXPORT:CharLowerW=user32.CharLowerW") +#pragma comment(linker, "/EXPORT:CharNextA=user32.CharNextA") +#pragma comment(linker, "/EXPORT:CharNextExA=user32.CharNextExA") +#pragma comment(linker, "/EXPORT:CharNextW=user32.CharNextW") +#pragma comment(linker, "/EXPORT:CharPrevA=user32.CharPrevA") +#pragma comment(linker, "/EXPORT:CharPrevExA=user32.CharPrevExA") +#pragma comment(linker, "/EXPORT:CharPrevW=user32.CharPrevW") +#pragma comment(linker, "/EXPORT:CharToOemA=user32.CharToOemA") +#pragma comment(linker, "/EXPORT:CharToOemBuffA=user32.CharToOemBuffA") +#pragma comment(linker, "/EXPORT:CharToOemBuffW=user32.CharToOemBuffW") +#pragma comment(linker, "/EXPORT:CharToOemW=user32.CharToOemW") +#pragma comment(linker, "/EXPORT:CharUpperA=user32.CharUpperA") +#pragma comment(linker, "/EXPORT:CharUpperBuffA=user32.CharUpperBuffA") +#pragma comment(linker, "/EXPORT:CharUpperBuffW=user32.CharUpperBuffW") +#pragma comment(linker, "/EXPORT:CharUpperW=user32.CharUpperW") +#pragma comment(linker, "/EXPORT:CheckDesktopByThreadId=user32.CheckDesktopByThreadId") +#pragma comment(linker, "/EXPORT:CheckDlgButton=user32.CheckDlgButton") +#pragma comment(linker, "/EXPORT:CheckMenuItem=user32.CheckMenuItem") +#pragma comment(linker, "/EXPORT:CheckMenuRadioItem=user32.CheckMenuRadioItem") +#pragma comment(linker, "/EXPORT:CheckRadioButton=user32.CheckRadioButton") +#pragma comment(linker, "/EXPORT:CheckWindowThreadDesktop=user32.CheckWindowThreadDesktop") +#pragma comment(linker, "/EXPORT:ChildWindowFromPoint=user32.ChildWindowFromPoint") +#pragma comment(linker, "/EXPORT:ChildWindowFromPointEx=user32.ChildWindowFromPointEx") +#pragma comment(linker, "/EXPORT:CliImmSetHotKey=user32.CliImmSetHotKey") +#pragma comment(linker, "/EXPORT:ClientThreadSetup=user32.ClientThreadSetup") +#pragma comment(linker, "/EXPORT:ClientToScreen=user32.ClientToScreen") +#pragma comment(linker, "/EXPORT:ClipCursor=user32.ClipCursor") +#pragma comment(linker, "/EXPORT:CloseClipboard=user32.CloseClipboard") +#pragma comment(linker, "/EXPORT:CloseDesktop=user32.CloseDesktop") +#pragma comment(linker, "/EXPORT:CloseGestureInfoHandle=user32.CloseGestureInfoHandle") +#pragma comment(linker, "/EXPORT:CloseTouchInputHandle=user32.CloseTouchInputHandle") +#pragma comment(linker, "/EXPORT:CloseWindow=user32.CloseWindow") +#pragma comment(linker, "/EXPORT:CloseWindowStation=user32.CloseWindowStation") +#pragma comment(linker, "/EXPORT:ConsoleControl=user32.ConsoleControl") +#pragma comment(linker, "/EXPORT:ControlMagnification=user32.ControlMagnification") +#pragma comment(linker, "/EXPORT:CopyAcceleratorTableA=user32.CopyAcceleratorTableA") +#pragma comment(linker, "/EXPORT:CopyAcceleratorTableW=user32.CopyAcceleratorTableW") +#pragma comment(linker, "/EXPORT:CopyIcon=user32.CopyIcon") +#pragma comment(linker, "/EXPORT:CopyImage=user32.CopyImage") +#pragma comment(linker, "/EXPORT:CopyRect=user32.CopyRect") +#pragma comment(linker, "/EXPORT:CountClipboardFormats=user32.CountClipboardFormats") +#pragma comment(linker, "/EXPORT:CreateAcceleratorTableA=user32.CreateAcceleratorTableA") +#pragma comment(linker, "/EXPORT:CreateAcceleratorTableW=user32.CreateAcceleratorTableW") +#pragma comment(linker, "/EXPORT:CreateCaret=user32.CreateCaret") +#pragma comment(linker, "/EXPORT:CreateCursor=user32.CreateCursor") +#pragma comment(linker, "/EXPORT:CreateDesktopA=user32.CreateDesktopA") +#pragma comment(linker, "/EXPORT:CreateDesktopExA=user32.CreateDesktopExA") +#pragma comment(linker, "/EXPORT:CreateDesktopExW=user32.CreateDesktopExW") +#pragma comment(linker, "/EXPORT:CreateDesktopW=user32.CreateDesktopW") +#pragma comment(linker, "/EXPORT:CreateDialogIndirectParamA=user32.CreateDialogIndirectParamA") +#pragma comment(linker, "/EXPORT:CreateDialogIndirectParamAorW=user32.CreateDialogIndirectParamAorW") +#pragma comment(linker, "/EXPORT:CreateDialogIndirectParamW=user32.CreateDialogIndirectParamW") +#pragma comment(linker, "/EXPORT:CreateDialogParamA=user32.CreateDialogParamA") +#pragma comment(linker, "/EXPORT:CreateDialogParamW=user32.CreateDialogParamW") +#pragma comment(linker, "/EXPORT:CreateIcon=user32.CreateIcon") +#pragma comment(linker, "/EXPORT:CreateIconFromResource=user32.CreateIconFromResource") +#pragma comment(linker, "/EXPORT:CreateIconFromResourceEx=user32.CreateIconFromResourceEx") +#pragma comment(linker, "/EXPORT:CreateIconIndirect=user32.CreateIconIndirect") +#pragma comment(linker, "/EXPORT:CreateMDIWindowA=user32.CreateMDIWindowA") +#pragma comment(linker, "/EXPORT:CreateMDIWindowW=user32.CreateMDIWindowW") +#pragma comment(linker, "/EXPORT:CreateMenu=user32.CreateMenu") +#pragma comment(linker, "/EXPORT:CreatePopupMenu=user32.CreatePopupMenu") +#pragma comment(linker, "/EXPORT:CreateSystemThreads=user32.CreateSystemThreads") +#pragma comment(linker, "/EXPORT:CreateWindowExA=user32.CreateWindowExA") +#pragma comment(linker, "/EXPORT:CreateWindowExW=user32.CreateWindowExW") +#pragma comment(linker, "/EXPORT:CreateWindowStationA=user32.CreateWindowStationA") +#pragma comment(linker, "/EXPORT:CreateWindowStationW=user32.CreateWindowStationW") +#pragma comment(linker, "/EXPORT:CsrBroadcastSystemMessageExW=user32.CsrBroadcastSystemMessageExW") +#pragma comment(linker, "/EXPORT:CtxInitUser32=user32.CtxInitUser32") +#pragma comment(linker, "/EXPORT:DdeAbandonTransaction=user32.DdeAbandonTransaction") +#pragma comment(linker, "/EXPORT:DdeAccessData=user32.DdeAccessData") +#pragma comment(linker, "/EXPORT:DdeAddData=user32.DdeAddData") +#pragma comment(linker, "/EXPORT:DdeClientTransaction=user32.DdeClientTransaction") +#pragma comment(linker, "/EXPORT:DdeCmpStringHandles=user32.DdeCmpStringHandles") +#pragma comment(linker, "/EXPORT:DdeConnect=user32.DdeConnect") +#pragma comment(linker, "/EXPORT:DdeConnectList=user32.DdeConnectList") +#pragma comment(linker, "/EXPORT:DdeCreateDataHandle=user32.DdeCreateDataHandle") +#pragma comment(linker, "/EXPORT:DdeCreateStringHandleA=user32.DdeCreateStringHandleA") +#pragma comment(linker, "/EXPORT:DdeCreateStringHandleW=user32.DdeCreateStringHandleW") +#pragma comment(linker, "/EXPORT:DdeDisconnect=user32.DdeDisconnect") +#pragma comment(linker, "/EXPORT:DdeDisconnectList=user32.DdeDisconnectList") +#pragma comment(linker, "/EXPORT:DdeEnableCallback=user32.DdeEnableCallback") +#pragma comment(linker, "/EXPORT:DdeFreeDataHandle=user32.DdeFreeDataHandle") +#pragma comment(linker, "/EXPORT:DdeFreeStringHandle=user32.DdeFreeStringHandle") +#pragma comment(linker, "/EXPORT:DdeGetData=user32.DdeGetData") +#pragma comment(linker, "/EXPORT:DdeGetLastError=user32.DdeGetLastError") +#pragma comment(linker, "/EXPORT:DdeGetQualityOfService=user32.DdeGetQualityOfService") +#pragma comment(linker, "/EXPORT:DdeImpersonateClient=user32.DdeImpersonateClient") +#pragma comment(linker, "/EXPORT:DdeInitializeA=user32.DdeInitializeA") +#pragma comment(linker, "/EXPORT:DdeInitializeW=user32.DdeInitializeW") +#pragma comment(linker, "/EXPORT:DdeKeepStringHandle=user32.DdeKeepStringHandle") +#pragma comment(linker, "/EXPORT:DdeNameService=user32.DdeNameService") +#pragma comment(linker, "/EXPORT:DdePostAdvise=user32.DdePostAdvise") +#pragma comment(linker, "/EXPORT:DdeQueryConvInfo=user32.DdeQueryConvInfo") +#pragma comment(linker, "/EXPORT:DdeQueryNextServer=user32.DdeQueryNextServer") +#pragma comment(linker, "/EXPORT:DdeQueryStringA=user32.DdeQueryStringA") +#pragma comment(linker, "/EXPORT:DdeQueryStringW=user32.DdeQueryStringW") +#pragma comment(linker, "/EXPORT:DdeReconnect=user32.DdeReconnect") +#pragma comment(linker, "/EXPORT:DdeSetQualityOfService=user32.DdeSetQualityOfService") +#pragma comment(linker, "/EXPORT:DdeSetUserHandle=user32.DdeSetUserHandle") +#pragma comment(linker, "/EXPORT:DdeUnaccessData=user32.DdeUnaccessData") +#pragma comment(linker, "/EXPORT:DdeUninitialize=user32.DdeUninitialize") +#pragma comment(linker, "/EXPORT:DefDlgProcA=user32.DefDlgProcA") +#pragma comment(linker, "/EXPORT:DefDlgProcW=user32.DefDlgProcW") +#pragma comment(linker, "/EXPORT:DefFrameProcA=user32.DefFrameProcA") +#pragma comment(linker, "/EXPORT:DefFrameProcW=user32.DefFrameProcW") +#pragma comment(linker, "/EXPORT:DefMDIChildProcA=user32.DefMDIChildProcA") +#pragma comment(linker, "/EXPORT:DefMDIChildProcW=user32.DefMDIChildProcW") +#pragma comment(linker, "/EXPORT:DefRawInputProc=user32.DefRawInputProc") +#pragma comment(linker, "/EXPORT:DefWindowProcA=user32.DefWindowProcA") +#pragma comment(linker, "/EXPORT:DefWindowProcW=user32.DefWindowProcW") +#pragma comment(linker, "/EXPORT:DeferWindowPos=user32.DeferWindowPos") +#pragma comment(linker, "/EXPORT:DeleteMenu=user32.DeleteMenu") +#pragma comment(linker, "/EXPORT:DeregisterShellHookWindow=user32.DeregisterShellHookWindow") +#pragma comment(linker, "/EXPORT:DestroyAcceleratorTable=user32.DestroyAcceleratorTable") +#pragma comment(linker, "/EXPORT:DestroyCaret=user32.DestroyCaret") +#pragma comment(linker, "/EXPORT:DestroyCursor=user32.DestroyCursor") +#pragma comment(linker, "/EXPORT:DestroyIcon=user32.DestroyIcon") +#pragma comment(linker, "/EXPORT:DestroyMenu=user32.DestroyMenu") +#pragma comment(linker, "/EXPORT:DestroyReasons=user32.DestroyReasons") +#pragma comment(linker, "/EXPORT:DestroyWindow=user32.DestroyWindow") +#pragma comment(linker, "/EXPORT:DeviceEventWorker=user32.DeviceEventWorker") +#pragma comment(linker, "/EXPORT:DialogBoxIndirectParamA=user32.DialogBoxIndirectParamA") +#pragma comment(linker, "/EXPORT:DialogBoxIndirectParamAorW=user32.DialogBoxIndirectParamAorW") +#pragma comment(linker, "/EXPORT:DialogBoxIndirectParamW=user32.DialogBoxIndirectParamW") +#pragma comment(linker, "/EXPORT:DialogBoxParamA=user32.DialogBoxParamA") +#pragma comment(linker, "/EXPORT:DialogBoxParamW=user32.DialogBoxParamW") +#pragma comment(linker, "/EXPORT:DisableProcessWindowsGhosting=user32.DisableProcessWindowsGhosting") +#pragma comment(linker, "/EXPORT:DispatchMessageA=user32.DispatchMessageA") +#pragma comment(linker, "/EXPORT:DispatchMessageW=user32.DispatchMessageW") +#pragma comment(linker, "/EXPORT:DisplayConfigGetDeviceInfo=user32.DisplayConfigGetDeviceInfo") +#pragma comment(linker, "/EXPORT:DisplayConfigSetDeviceInfo=user32.DisplayConfigSetDeviceInfo") +#pragma comment(linker, "/EXPORT:DisplayExitWindowsWarnings=user32.DisplayExitWindowsWarnings") +#pragma comment(linker, "/EXPORT:DlgDirListA=user32.DlgDirListA") +#pragma comment(linker, "/EXPORT:DlgDirListComboBoxA=user32.DlgDirListComboBoxA") +#pragma comment(linker, "/EXPORT:DlgDirListComboBoxW=user32.DlgDirListComboBoxW") +#pragma comment(linker, "/EXPORT:DlgDirListW=user32.DlgDirListW") +#pragma comment(linker, "/EXPORT:DlgDirSelectComboBoxExA=user32.DlgDirSelectComboBoxExA") +#pragma comment(linker, "/EXPORT:DlgDirSelectComboBoxExW=user32.DlgDirSelectComboBoxExW") +#pragma comment(linker, "/EXPORT:DlgDirSelectExA=user32.DlgDirSelectExA") +#pragma comment(linker, "/EXPORT:DlgDirSelectExW=user32.DlgDirSelectExW") +#pragma comment(linker, "/EXPORT:DoSoundConnect=user32.DoSoundConnect") +#pragma comment(linker, "/EXPORT:DoSoundDisconnect=user32.DoSoundDisconnect") +#pragma comment(linker, "/EXPORT:DragDetect=user32.DragDetect") +#pragma comment(linker, "/EXPORT:DragObject=user32.DragObject") +#pragma comment(linker, "/EXPORT:DrawAnimatedRects=user32.DrawAnimatedRects") +#pragma comment(linker, "/EXPORT:DrawCaption=user32.DrawCaption") +#pragma comment(linker, "/EXPORT:DrawCaptionTempA=user32.DrawCaptionTempA") +#pragma comment(linker, "/EXPORT:DrawCaptionTempW=user32.DrawCaptionTempW") +#pragma comment(linker, "/EXPORT:DrawEdge=user32.DrawEdge") +#pragma comment(linker, "/EXPORT:DrawFocusRect=user32.DrawFocusRect") +#pragma comment(linker, "/EXPORT:DrawFrame=user32.DrawFrame") +#pragma comment(linker, "/EXPORT:DrawFrameControl=user32.DrawFrameControl") +#pragma comment(linker, "/EXPORT:DrawIcon=user32.DrawIcon") +#pragma comment(linker, "/EXPORT:DrawIconEx=user32.DrawIconEx") +#pragma comment(linker, "/EXPORT:DrawMenuBar=user32.DrawMenuBar") +#pragma comment(linker, "/EXPORT:DrawMenuBarTemp=user32.DrawMenuBarTemp") +#pragma comment(linker, "/EXPORT:DrawStateA=user32.DrawStateA") +#pragma comment(linker, "/EXPORT:DrawStateW=user32.DrawStateW") +#pragma comment(linker, "/EXPORT:DrawTextA=user32.DrawTextA") +#pragma comment(linker, "/EXPORT:DrawTextExA=user32.DrawTextExA") +#pragma comment(linker, "/EXPORT:DrawTextExW=user32.DrawTextExW") +#pragma comment(linker, "/EXPORT:DrawTextW=user32.DrawTextW") +#pragma comment(linker, "/EXPORT:DwmGetDxSharedSurface=user32.DwmGetDxSharedSurface") +#pragma comment(linker, "/EXPORT:DwmStartRedirection=user32.DwmStartRedirection") +#pragma comment(linker, "/EXPORT:DwmStopRedirection=user32.DwmStopRedirection") +#pragma comment(linker, "/EXPORT:EditWndProc=user32.EditWndProc") +#pragma comment(linker, "/EXPORT:EmptyClipboard=user32.EmptyClipboard") +#pragma comment(linker, "/EXPORT:EnableMenuItem=user32.EnableMenuItem") +#pragma comment(linker, "/EXPORT:EnableScrollBar=user32.EnableScrollBar") +#pragma comment(linker, "/EXPORT:EnableWindow=user32.EnableWindow") +#pragma comment(linker, "/EXPORT:EndDeferWindowPos=user32.EndDeferWindowPos") +#pragma comment(linker, "/EXPORT:EndDialog=user32.EndDialog") +#pragma comment(linker, "/EXPORT:EndMenu=user32.EndMenu") +#pragma comment(linker, "/EXPORT:EndPaint=user32.EndPaint") +#pragma comment(linker, "/EXPORT:EndTask=user32.EndTask") +#pragma comment(linker, "/EXPORT:EnterReaderModeHelper=user32.EnterReaderModeHelper") +#pragma comment(linker, "/EXPORT:EnumChildWindows=user32.EnumChildWindows") +#pragma comment(linker, "/EXPORT:EnumClipboardFormats=user32.EnumClipboardFormats") +#pragma comment(linker, "/EXPORT:EnumDesktopWindows=user32.EnumDesktopWindows") +#pragma comment(linker, "/EXPORT:EnumDesktopsA=user32.EnumDesktopsA") +#pragma comment(linker, "/EXPORT:EnumDesktopsW=user32.EnumDesktopsW") +#pragma comment(linker, "/EXPORT:EnumDisplayDevicesA=user32.EnumDisplayDevicesA") +#pragma comment(linker, "/EXPORT:EnumDisplayDevicesW=user32.EnumDisplayDevicesW") +#pragma comment(linker, "/EXPORT:EnumDisplayMonitors=user32.EnumDisplayMonitors") +#pragma comment(linker, "/EXPORT:EnumDisplaySettingsA=user32.EnumDisplaySettingsA") +#pragma comment(linker, "/EXPORT:EnumDisplaySettingsExA=user32.EnumDisplaySettingsExA") +#pragma comment(linker, "/EXPORT:EnumDisplaySettingsExW=user32.EnumDisplaySettingsExW") +#pragma comment(linker, "/EXPORT:EnumDisplaySettingsW=user32.EnumDisplaySettingsW") +#pragma comment(linker, "/EXPORT:EnumPropsA=user32.EnumPropsA") +#pragma comment(linker, "/EXPORT:EnumPropsExA=user32.EnumPropsExA") +#pragma comment(linker, "/EXPORT:EnumPropsExW=user32.EnumPropsExW") +#pragma comment(linker, "/EXPORT:EnumPropsW=user32.EnumPropsW") +#pragma comment(linker, "/EXPORT:EnumThreadWindows=user32.EnumThreadWindows") +#pragma comment(linker, "/EXPORT:EnumWindowStationsA=user32.EnumWindowStationsA") +#pragma comment(linker, "/EXPORT:EnumWindowStationsW=user32.EnumWindowStationsW") +#pragma comment(linker, "/EXPORT:EnumWindows=user32.EnumWindows") +#pragma comment(linker, "/EXPORT:EqualRect=user32.EqualRect") +#pragma comment(linker, "/EXPORT:ExcludeUpdateRgn=user32.ExcludeUpdateRgn") +#pragma comment(linker, "/EXPORT:ExitWindowsEx=user32.ExitWindowsEx") +#pragma comment(linker, "/EXPORT:FillRect=user32.FillRect") +#pragma comment(linker, "/EXPORT:FindWindowA=user32.FindWindowA") +#pragma comment(linker, "/EXPORT:FindWindowExA=user32.FindWindowExA") +#pragma comment(linker, "/EXPORT:FindWindowExW=user32.FindWindowExW") +#pragma comment(linker, "/EXPORT:FindWindowW=user32.FindWindowW") +#pragma comment(linker, "/EXPORT:FlashWindow=user32.FlashWindow") +#pragma comment(linker, "/EXPORT:FlashWindowEx=user32.FlashWindowEx") +#pragma comment(linker, "/EXPORT:FrameRect=user32.FrameRect") +#pragma comment(linker, "/EXPORT:FreeDDElParam=user32.FreeDDElParam") +#pragma comment(linker, "/EXPORT:FrostCrashedWindow=user32.FrostCrashedWindow") +#pragma comment(linker, "/EXPORT:GetActiveWindow=user32.GetActiveWindow") +#pragma comment(linker, "/EXPORT:GetAltTabInfo=user32.GetAltTabInfo") +#pragma comment(linker, "/EXPORT:GetAltTabInfoA=user32.GetAltTabInfoA") +#pragma comment(linker, "/EXPORT:GetAltTabInfoW=user32.GetAltTabInfoW") +#pragma comment(linker, "/EXPORT:GetAncestor=user32.GetAncestor") +#pragma comment(linker, "/EXPORT:GetAppCompatFlags=user32.GetAppCompatFlags") +#pragma comment(linker, "/EXPORT:GetAppCompatFlags2=user32.GetAppCompatFlags2") +#pragma comment(linker, "/EXPORT:GetAsyncKeyState=user32.GetAsyncKeyState") +#pragma comment(linker, "/EXPORT:GetCapture=user32.GetCapture") +#pragma comment(linker, "/EXPORT:GetCaretBlinkTime=user32.GetCaretBlinkTime") +#pragma comment(linker, "/EXPORT:GetCaretPos=user32.GetCaretPos") +#pragma comment(linker, "/EXPORT:GetClassInfoA=user32.GetClassInfoA") +#pragma comment(linker, "/EXPORT:GetClassInfoExA=user32.GetClassInfoExA") +#pragma comment(linker, "/EXPORT:GetClassInfoExW=user32.GetClassInfoExW") +#pragma comment(linker, "/EXPORT:GetClassInfoW=user32.GetClassInfoW") +#pragma comment(linker, "/EXPORT:GetClassLongA=user32.GetClassLongA") +#pragma comment(linker, "/EXPORT:GetClassLongPtrA=user32.GetClassLongPtrA") +#pragma comment(linker, "/EXPORT:GetClassLongPtrW=user32.GetClassLongPtrW") +#pragma comment(linker, "/EXPORT:GetClassLongW=user32.GetClassLongW") +#pragma comment(linker, "/EXPORT:GetClassNameA=user32.GetClassNameA") +#pragma comment(linker, "/EXPORT:GetClassNameW=user32.GetClassNameW") +#pragma comment(linker, "/EXPORT:GetClassWord=user32.GetClassWord") +#pragma comment(linker, "/EXPORT:GetClientRect=user32.GetClientRect") +#pragma comment(linker, "/EXPORT:GetClipCursor=user32.GetClipCursor") +#pragma comment(linker, "/EXPORT:GetClipboardData=user32.GetClipboardData") +#pragma comment(linker, "/EXPORT:GetClipboardFormatNameA=user32.GetClipboardFormatNameA") +#pragma comment(linker, "/EXPORT:GetClipboardFormatNameW=user32.GetClipboardFormatNameW") +#pragma comment(linker, "/EXPORT:GetClipboardOwner=user32.GetClipboardOwner") +#pragma comment(linker, "/EXPORT:GetClipboardSequenceNumber=user32.GetClipboardSequenceNumber") +#pragma comment(linker, "/EXPORT:GetClipboardViewer=user32.GetClipboardViewer") +#pragma comment(linker, "/EXPORT:GetComboBoxInfo=user32.GetComboBoxInfo") +#pragma comment(linker, "/EXPORT:GetCursor=user32.GetCursor") +#pragma comment(linker, "/EXPORT:GetCursorFrameInfo=user32.GetCursorFrameInfo") +#pragma comment(linker, "/EXPORT:GetCursorInfo=user32.GetCursorInfo") +#pragma comment(linker, "/EXPORT:GetCursorPos=user32.GetCursorPos") +#pragma comment(linker, "/EXPORT:GetDC=user32.GetDC") +#pragma comment(linker, "/EXPORT:GetDCEx=user32.GetDCEx") +#pragma comment(linker, "/EXPORT:GetDesktopWindow=user32.GetDesktopWindow") +#pragma comment(linker, "/EXPORT:GetDialogBaseUnits=user32.GetDialogBaseUnits") +#pragma comment(linker, "/EXPORT:GetDisplayConfigBufferSizes=user32.GetDisplayConfigBufferSizes") +#pragma comment(linker, "/EXPORT:GetDlgCtrlID=user32.GetDlgCtrlID") +#pragma comment(linker, "/EXPORT:GetDlgItem=user32.GetDlgItem") +#pragma comment(linker, "/EXPORT:GetDlgItemInt=user32.GetDlgItemInt") +#pragma comment(linker, "/EXPORT:GetDlgItemTextA=user32.GetDlgItemTextA") +#pragma comment(linker, "/EXPORT:GetDlgItemTextW=user32.GetDlgItemTextW") +#pragma comment(linker, "/EXPORT:GetDoubleClickTime=user32.GetDoubleClickTime") +#pragma comment(linker, "/EXPORT:GetFocus=user32.GetFocus") +#pragma comment(linker, "/EXPORT:GetForegroundWindow=user32.GetForegroundWindow") +#pragma comment(linker, "/EXPORT:GetGUIThreadInfo=user32.GetGUIThreadInfo") +#pragma comment(linker, "/EXPORT:GetGestureConfig=user32.GetGestureConfig") +#pragma comment(linker, "/EXPORT:GetGestureExtraArgs=user32.GetGestureExtraArgs") +#pragma comment(linker, "/EXPORT:GetGestureInfo=user32.GetGestureInfo") +#pragma comment(linker, "/EXPORT:GetGuiResources=user32.GetGuiResources") +#pragma comment(linker, "/EXPORT:GetIconInfo=user32.GetIconInfo") +#pragma comment(linker, "/EXPORT:GetIconInfoExA=user32.GetIconInfoExA") +#pragma comment(linker, "/EXPORT:GetIconInfoExW=user32.GetIconInfoExW") +#pragma comment(linker, "/EXPORT:GetInputDesktop=user32.GetInputDesktop") +#pragma comment(linker, "/EXPORT:GetInputLocaleInfo=user32.GetInputLocaleInfo") +#pragma comment(linker, "/EXPORT:GetInputState=user32.GetInputState") +#pragma comment(linker, "/EXPORT:GetInternalWindowPos=user32.GetInternalWindowPos") +#pragma comment(linker, "/EXPORT:GetKBCodePage=user32.GetKBCodePage") +#pragma comment(linker, "/EXPORT:GetKeyNameTextA=user32.GetKeyNameTextA") +#pragma comment(linker, "/EXPORT:GetKeyNameTextW=user32.GetKeyNameTextW") +#pragma comment(linker, "/EXPORT:GetKeyState=user32.GetKeyState") +#pragma comment(linker, "/EXPORT:GetKeyboardLayout=user32.GetKeyboardLayout") +#pragma comment(linker, "/EXPORT:GetKeyboardLayoutList=user32.GetKeyboardLayoutList") +#pragma comment(linker, "/EXPORT:GetKeyboardLayoutNameA=user32.GetKeyboardLayoutNameA") +#pragma comment(linker, "/EXPORT:GetKeyboardLayoutNameW=user32.GetKeyboardLayoutNameW") +#pragma comment(linker, "/EXPORT:GetKeyboardState=user32.GetKeyboardState") +#pragma comment(linker, "/EXPORT:GetKeyboardType=user32.GetKeyboardType") +#pragma comment(linker, "/EXPORT:GetLastActivePopup=user32.GetLastActivePopup") +#pragma comment(linker, "/EXPORT:GetLastInputInfo=user32.GetLastInputInfo") +#pragma comment(linker, "/EXPORT:GetLayeredWindowAttributes=user32.GetLayeredWindowAttributes") +#pragma comment(linker, "/EXPORT:GetListBoxInfo=user32.GetListBoxInfo") +#pragma comment(linker, "/EXPORT:GetMagnificationDesktopColorEffect=user32.GetMagnificationDesktopColorEffect") +#pragma comment(linker, "/EXPORT:GetMagnificationDesktopMagnification=user32.GetMagnificationDesktopMagnification") +#pragma comment(linker, "/EXPORT:GetMagnificationLensCtxInformation=user32.GetMagnificationLensCtxInformation") +#pragma comment(linker, "/EXPORT:GetMenu=user32.GetMenu") +#pragma comment(linker, "/EXPORT:GetMenuBarInfo=user32.GetMenuBarInfo") +#pragma comment(linker, "/EXPORT:GetMenuCheckMarkDimensions=user32.GetMenuCheckMarkDimensions") +#pragma comment(linker, "/EXPORT:GetMenuContextHelpId=user32.GetMenuContextHelpId") +#pragma comment(linker, "/EXPORT:GetMenuDefaultItem=user32.GetMenuDefaultItem") +#pragma comment(linker, "/EXPORT:GetMenuInfo=user32.GetMenuInfo") +#pragma comment(linker, "/EXPORT:GetMenuItemCount=user32.GetMenuItemCount") +#pragma comment(linker, "/EXPORT:GetMenuItemID=user32.GetMenuItemID") +#pragma comment(linker, "/EXPORT:GetMenuItemInfoA=user32.GetMenuItemInfoA") +#pragma comment(linker, "/EXPORT:GetMenuItemInfoW=user32.GetMenuItemInfoW") +#pragma comment(linker, "/EXPORT:GetMenuItemRect=user32.GetMenuItemRect") +#pragma comment(linker, "/EXPORT:GetMenuState=user32.GetMenuState") +#pragma comment(linker, "/EXPORT:GetMenuStringA=user32.GetMenuStringA") +#pragma comment(linker, "/EXPORT:GetMenuStringW=user32.GetMenuStringW") +#pragma comment(linker, "/EXPORT:GetMessageA=user32.GetMessageA") +#pragma comment(linker, "/EXPORT:GetMessageExtraInfo=user32.GetMessageExtraInfo") +#pragma comment(linker, "/EXPORT:GetMessagePos=user32.GetMessagePos") +#pragma comment(linker, "/EXPORT:GetMessageTime=user32.GetMessageTime") +#pragma comment(linker, "/EXPORT:GetMessageW=user32.GetMessageW") +#pragma comment(linker, "/EXPORT:GetMonitorInfoA=user32.GetMonitorInfoA") +#pragma comment(linker, "/EXPORT:GetMonitorInfoW=user32.GetMonitorInfoW") +#pragma comment(linker, "/EXPORT:GetMouseMovePointsEx=user32.GetMouseMovePointsEx") +#pragma comment(linker, "/EXPORT:GetNextDlgGroupItem=user32.GetNextDlgGroupItem") +#pragma comment(linker, "/EXPORT:GetNextDlgTabItem=user32.GetNextDlgTabItem") +#pragma comment(linker, "/EXPORT:GetOpenClipboardWindow=user32.GetOpenClipboardWindow") +#pragma comment(linker, "/EXPORT:GetParent=user32.GetParent") +#pragma comment(linker, "/EXPORT:GetPhysicalCursorPos=user32.GetPhysicalCursorPos") +#pragma comment(linker, "/EXPORT:GetPriorityClipboardFormat=user32.GetPriorityClipboardFormat") +#pragma comment(linker, "/EXPORT:GetProcessDefaultLayout=user32.GetProcessDefaultLayout") +#pragma comment(linker, "/EXPORT:GetProcessWindowStation=user32.GetProcessWindowStation") +#pragma comment(linker, "/EXPORT:GetProgmanWindow=user32.GetProgmanWindow") +#pragma comment(linker, "/EXPORT:GetPropA=user32.GetPropA") +#pragma comment(linker, "/EXPORT:GetPropW=user32.GetPropW") +#pragma comment(linker, "/EXPORT:GetQueueStatus=user32.GetQueueStatus") +#pragma comment(linker, "/EXPORT:GetRawInputBuffer=user32.GetRawInputBuffer") +#pragma comment(linker, "/EXPORT:GetRawInputData=user32.GetRawInputData") +#pragma comment(linker, "/EXPORT:GetRawInputDeviceInfoA=user32.GetRawInputDeviceInfoA") +#pragma comment(linker, "/EXPORT:GetRawInputDeviceInfoW=user32.GetRawInputDeviceInfoW") +#pragma comment(linker, "/EXPORT:GetRawInputDeviceList=user32.GetRawInputDeviceList") +#pragma comment(linker, "/EXPORT:GetReasonTitleFromReasonCode=user32.GetReasonTitleFromReasonCode") +#pragma comment(linker, "/EXPORT:GetRegisteredRawInputDevices=user32.GetRegisteredRawInputDevices") +#pragma comment(linker, "/EXPORT:GetScrollBarInfo=user32.GetScrollBarInfo") +#pragma comment(linker, "/EXPORT:GetScrollInfo=user32.GetScrollInfo") +#pragma comment(linker, "/EXPORT:GetScrollPos=user32.GetScrollPos") +#pragma comment(linker, "/EXPORT:GetScrollRange=user32.GetScrollRange") +#pragma comment(linker, "/EXPORT:GetSendMessageReceiver=user32.GetSendMessageReceiver") +#pragma comment(linker, "/EXPORT:GetShellWindow=user32.GetShellWindow") +#pragma comment(linker, "/EXPORT:GetSubMenu=user32.GetSubMenu") +#pragma comment(linker, "/EXPORT:GetSysColor=user32.GetSysColor") +#pragma comment(linker, "/EXPORT:GetSysColorBrush=user32.GetSysColorBrush") +#pragma comment(linker, "/EXPORT:GetSystemMenu=user32.GetSystemMenu") +#pragma comment(linker, "/EXPORT:GetSystemMetrics=user32.GetSystemMetrics") +#pragma comment(linker, "/EXPORT:GetTabbedTextExtentA=user32.GetTabbedTextExtentA") +#pragma comment(linker, "/EXPORT:GetTabbedTextExtentW=user32.GetTabbedTextExtentW") +#pragma comment(linker, "/EXPORT:GetTaskmanWindow=user32.GetTaskmanWindow") +#pragma comment(linker, "/EXPORT:GetThreadDesktop=user32.GetThreadDesktop") +#pragma comment(linker, "/EXPORT:GetTitleBarInfo=user32.GetTitleBarInfo") +#pragma comment(linker, "/EXPORT:GetTopLevelWindow=user32.GetTopLevelWindow") +#pragma comment(linker, "/EXPORT:GetTopWindow=user32.GetTopWindow") +#pragma comment(linker, "/EXPORT:GetTouchInputInfo=user32.GetTouchInputInfo") +#pragma comment(linker, "/EXPORT:GetUpdateRect=user32.GetUpdateRect") +#pragma comment(linker, "/EXPORT:GetUpdateRgn=user32.GetUpdateRgn") +#pragma comment(linker, "/EXPORT:GetUpdatedClipboardFormats=user32.GetUpdatedClipboardFormats") +#pragma comment(linker, "/EXPORT:GetUserObjectInformationA=user32.GetUserObjectInformationA") +#pragma comment(linker, "/EXPORT:GetUserObjectInformationW=user32.GetUserObjectInformationW") +#pragma comment(linker, "/EXPORT:GetUserObjectSecurity=user32.GetUserObjectSecurity") +#pragma comment(linker, "/EXPORT:GetWinStationInfo=user32.GetWinStationInfo") +#pragma comment(linker, "/EXPORT:GetWindow=user32.GetWindow") +#pragma comment(linker, "/EXPORT:GetWindowCompositionAttribute=user32.GetWindowCompositionAttribute") +#pragma comment(linker, "/EXPORT:GetWindowCompositionInfo=user32.GetWindowCompositionInfo") +#pragma comment(linker, "/EXPORT:GetWindowContextHelpId=user32.GetWindowContextHelpId") +#pragma comment(linker, "/EXPORT:GetWindowDC=user32.GetWindowDC") +#pragma comment(linker, "/EXPORT:GetWindowDisplayAffinity=user32.GetWindowDisplayAffinity") +#pragma comment(linker, "/EXPORT:GetWindowInfo=user32.GetWindowInfo") +#pragma comment(linker, "/EXPORT:GetWindowLongA=user32.GetWindowLongA") +#pragma comment(linker, "/EXPORT:GetWindowLongPtrA=user32.GetWindowLongPtrA") +#pragma comment(linker, "/EXPORT:GetWindowLongPtrW=user32.GetWindowLongPtrW") +#pragma comment(linker, "/EXPORT:GetWindowLongW=user32.GetWindowLongW") +#pragma comment(linker, "/EXPORT:GetWindowMinimizeRect=user32.GetWindowMinimizeRect") +#pragma comment(linker, "/EXPORT:GetWindowModuleFileName=user32.GetWindowModuleFileName") +#pragma comment(linker, "/EXPORT:GetWindowModuleFileNameA=user32.GetWindowModuleFileNameA") +#pragma comment(linker, "/EXPORT:GetWindowModuleFileNameW=user32.GetWindowModuleFileNameW") +#pragma comment(linker, "/EXPORT:GetWindowPlacement=user32.GetWindowPlacement") +#pragma comment(linker, "/EXPORT:GetWindowRect=user32.GetWindowRect") +#pragma comment(linker, "/EXPORT:GetWindowRgn=user32.GetWindowRgn") +#pragma comment(linker, "/EXPORT:GetWindowRgnBox=user32.GetWindowRgnBox") +#pragma comment(linker, "/EXPORT:GetWindowRgnEx=user32.GetWindowRgnEx") +#pragma comment(linker, "/EXPORT:GetWindowTextA=user32.GetWindowTextA") +#pragma comment(linker, "/EXPORT:GetWindowTextLengthA=user32.GetWindowTextLengthA") +#pragma comment(linker, "/EXPORT:GetWindowTextLengthW=user32.GetWindowTextLengthW") +#pragma comment(linker, "/EXPORT:GetWindowTextW=user32.GetWindowTextW") +#pragma comment(linker, "/EXPORT:GetWindowThreadProcessId=user32.GetWindowThreadProcessId") +#pragma comment(linker, "/EXPORT:GetWindowWord=user32.GetWindowWord") +#pragma comment(linker, "/EXPORT:GhostWindowFromHungWindow=user32.GhostWindowFromHungWindow") +#pragma comment(linker, "/EXPORT:GrayStringA=user32.GrayStringA") +#pragma comment(linker, "/EXPORT:GrayStringW=user32.GrayStringW") +#pragma comment(linker, "/EXPORT:HideCaret=user32.HideCaret") +#pragma comment(linker, "/EXPORT:HiliteMenuItem=user32.HiliteMenuItem") +#pragma comment(linker, "/EXPORT:HungWindowFromGhostWindow=user32.HungWindowFromGhostWindow") +#pragma comment(linker, "/EXPORT:IMPGetIMEA=user32.IMPGetIMEA") +#pragma comment(linker, "/EXPORT:IMPGetIMEW=user32.IMPGetIMEW") +#pragma comment(linker, "/EXPORT:IMPQueryIMEA=user32.IMPQueryIMEA") +#pragma comment(linker, "/EXPORT:IMPQueryIMEW=user32.IMPQueryIMEW") +#pragma comment(linker, "/EXPORT:IMPSetIMEA=user32.IMPSetIMEA") +#pragma comment(linker, "/EXPORT:IMPSetIMEW=user32.IMPSetIMEW") +#pragma comment(linker, "/EXPORT:ImpersonateDdeClientWindow=user32.ImpersonateDdeClientWindow") +#pragma comment(linker, "/EXPORT:InSendMessage=user32.InSendMessage") +#pragma comment(linker, "/EXPORT:InSendMessageEx=user32.InSendMessageEx") +#pragma comment(linker, "/EXPORT:InflateRect=user32.InflateRect") +#pragma comment(linker, "/EXPORT:InitializeLpkHooks=user32.InitializeLpkHooks") +#pragma comment(linker, "/EXPORT:InsertMenuA=user32.InsertMenuA") +#pragma comment(linker, "/EXPORT:InsertMenuItemA=user32.InsertMenuItemA") +#pragma comment(linker, "/EXPORT:InsertMenuItemW=user32.InsertMenuItemW") +#pragma comment(linker, "/EXPORT:InsertMenuW=user32.InsertMenuW") +#pragma comment(linker, "/EXPORT:InternalGetWindowIcon=user32.InternalGetWindowIcon") +#pragma comment(linker, "/EXPORT:InternalGetWindowText=user32.InternalGetWindowText") +#pragma comment(linker, "/EXPORT:IntersectRect=user32.IntersectRect") +#pragma comment(linker, "/EXPORT:InvalidateRect=user32.InvalidateRect") +#pragma comment(linker, "/EXPORT:InvalidateRgn=user32.InvalidateRgn") +#pragma comment(linker, "/EXPORT:InvertRect=user32.InvertRect") +#pragma comment(linker, "/EXPORT:IsCharAlphaA=user32.IsCharAlphaA") +#pragma comment(linker, "/EXPORT:IsCharAlphaNumericA=user32.IsCharAlphaNumericA") +#pragma comment(linker, "/EXPORT:IsCharAlphaNumericW=user32.IsCharAlphaNumericW") +#pragma comment(linker, "/EXPORT:IsCharAlphaW=user32.IsCharAlphaW") +#pragma comment(linker, "/EXPORT:IsCharLowerA=user32.IsCharLowerA") +#pragma comment(linker, "/EXPORT:IsCharLowerW=user32.IsCharLowerW") +#pragma comment(linker, "/EXPORT:IsCharUpperA=user32.IsCharUpperA") +#pragma comment(linker, "/EXPORT:IsCharUpperW=user32.IsCharUpperW") +#pragma comment(linker, "/EXPORT:IsChild=user32.IsChild") +#pragma comment(linker, "/EXPORT:IsClipboardFormatAvailable=user32.IsClipboardFormatAvailable") +#pragma comment(linker, "/EXPORT:IsDialogMessage=user32.IsDialogMessage") +#pragma comment(linker, "/EXPORT:IsDialogMessageA=user32.IsDialogMessageA") +#pragma comment(linker, "/EXPORT:IsDialogMessageW=user32.IsDialogMessageW") +#pragma comment(linker, "/EXPORT:IsDlgButtonChecked=user32.IsDlgButtonChecked") +#pragma comment(linker, "/EXPORT:IsGUIThread=user32.IsGUIThread") +#pragma comment(linker, "/EXPORT:IsHungAppWindow=user32.IsHungAppWindow") +#pragma comment(linker, "/EXPORT:IsIconic=user32.IsIconic") +#pragma comment(linker, "/EXPORT:IsMenu=user32.IsMenu") +#pragma comment(linker, "/EXPORT:IsProcessDPIAware=user32.IsProcessDPIAware") +#pragma comment(linker, "/EXPORT:IsRectEmpty=user32.IsRectEmpty") +#pragma comment(linker, "/EXPORT:IsSETEnabled=user32.IsSETEnabled") +#pragma comment(linker, "/EXPORT:IsServerSideWindow=user32.IsServerSideWindow") +#pragma comment(linker, "/EXPORT:IsThreadDesktopComposited=user32.IsThreadDesktopComposited") +#pragma comment(linker, "/EXPORT:IsTopLevelWindow=user32.IsTopLevelWindow") +#pragma comment(linker, "/EXPORT:IsTouchWindow=user32.IsTouchWindow") +#pragma comment(linker, "/EXPORT:IsWinEventHookInstalled=user32.IsWinEventHookInstalled") +#pragma comment(linker, "/EXPORT:IsWindow=user32.IsWindow") +#pragma comment(linker, "/EXPORT:IsWindowEnabled=user32.IsWindowEnabled") +#pragma comment(linker, "/EXPORT:IsWindowInDestroy=user32.IsWindowInDestroy") +#pragma comment(linker, "/EXPORT:IsWindowRedirectedForPrint=user32.IsWindowRedirectedForPrint") +#pragma comment(linker, "/EXPORT:IsWindowUnicode=user32.IsWindowUnicode") +#pragma comment(linker, "/EXPORT:IsWindowVisible=user32.IsWindowVisible") +#pragma comment(linker, "/EXPORT:IsWow64Message=user32.IsWow64Message") +#pragma comment(linker, "/EXPORT:IsZoomed=user32.IsZoomed") +#pragma comment(linker, "/EXPORT:KillTimer=user32.KillTimer") +#pragma comment(linker, "/EXPORT:LoadAcceleratorsA=user32.LoadAcceleratorsA") +#pragma comment(linker, "/EXPORT:LoadAcceleratorsW=user32.LoadAcceleratorsW") +#pragma comment(linker, "/EXPORT:LoadBitmapA=user32.LoadBitmapA") +#pragma comment(linker, "/EXPORT:LoadBitmapW=user32.LoadBitmapW") +#pragma comment(linker, "/EXPORT:LoadCursorA=user32.LoadCursorA") +#pragma comment(linker, "/EXPORT:LoadCursorFromFileA=user32.LoadCursorFromFileA") +#pragma comment(linker, "/EXPORT:LoadCursorFromFileW=user32.LoadCursorFromFileW") +#pragma comment(linker, "/EXPORT:LoadCursorW=user32.LoadCursorW") +#pragma comment(linker, "/EXPORT:LoadIconA=user32.LoadIconA") +#pragma comment(linker, "/EXPORT:LoadIconW=user32.LoadIconW") +#pragma comment(linker, "/EXPORT:LoadImageA=user32.LoadImageA") +#pragma comment(linker, "/EXPORT:LoadImageW=user32.LoadImageW") +#pragma comment(linker, "/EXPORT:LoadKeyboardLayoutA=user32.LoadKeyboardLayoutA") +#pragma comment(linker, "/EXPORT:LoadKeyboardLayoutEx=user32.LoadKeyboardLayoutEx") +#pragma comment(linker, "/EXPORT:LoadKeyboardLayoutW=user32.LoadKeyboardLayoutW") +#pragma comment(linker, "/EXPORT:LoadLocalFonts=user32.LoadLocalFonts") +#pragma comment(linker, "/EXPORT:LoadMenuA=user32.LoadMenuA") +#pragma comment(linker, "/EXPORT:LoadMenuIndirectA=user32.LoadMenuIndirectA") +#pragma comment(linker, "/EXPORT:LoadMenuIndirectW=user32.LoadMenuIndirectW") +#pragma comment(linker, "/EXPORT:LoadMenuW=user32.LoadMenuW") +#pragma comment(linker, "/EXPORT:LoadRemoteFonts=user32.LoadRemoteFonts") +#pragma comment(linker, "/EXPORT:LoadStringA=user32.LoadStringA") +#pragma comment(linker, "/EXPORT:LoadStringW=user32.LoadStringW") +#pragma comment(linker, "/EXPORT:LockSetForegroundWindow=user32.LockSetForegroundWindow") +#pragma comment(linker, "/EXPORT:LockWindowStation=user32.LockWindowStation") +#pragma comment(linker, "/EXPORT:LockWindowUpdate=user32.LockWindowUpdate") +#pragma comment(linker, "/EXPORT:LockWorkStation=user32.LockWorkStation") +#pragma comment(linker, "/EXPORT:LogicalToPhysicalPoint=user32.LogicalToPhysicalPoint") +#pragma comment(linker, "/EXPORT:LookupIconIdFromDirectory=user32.LookupIconIdFromDirectory") +#pragma comment(linker, "/EXPORT:LookupIconIdFromDirectoryEx=user32.LookupIconIdFromDirectoryEx") +#pragma comment(linker, "/EXPORT:MBToWCSEx=user32.MBToWCSEx") +#pragma comment(linker, "/EXPORT:MB_GetString=user32.MB_GetString") +#pragma comment(linker, "/EXPORT:MapDialogRect=user32.MapDialogRect") +#pragma comment(linker, "/EXPORT:MapVirtualKeyA=user32.MapVirtualKeyA") +#pragma comment(linker, "/EXPORT:MapVirtualKeyExA=user32.MapVirtualKeyExA") +#pragma comment(linker, "/EXPORT:MapVirtualKeyExW=user32.MapVirtualKeyExW") +#pragma comment(linker, "/EXPORT:MapVirtualKeyW=user32.MapVirtualKeyW") +#pragma comment(linker, "/EXPORT:MapWindowPoints=user32.MapWindowPoints") +#pragma comment(linker, "/EXPORT:MenuItemFromPoint=user32.MenuItemFromPoint") +#pragma comment(linker, "/EXPORT:MenuWindowProcA=user32.MenuWindowProcA") +#pragma comment(linker, "/EXPORT:MenuWindowProcW=user32.MenuWindowProcW") +#pragma comment(linker, "/EXPORT:MessageBeep=user32.MessageBeep") +#pragma comment(linker, "/EXPORT:MessageBoxA=user32.MessageBoxA") +#pragma comment(linker, "/EXPORT:MessageBoxExA=user32.MessageBoxExA") +#pragma comment(linker, "/EXPORT:MessageBoxExW=user32.MessageBoxExW") +#pragma comment(linker, "/EXPORT:MessageBoxIndirectA=user32.MessageBoxIndirectA") +#pragma comment(linker, "/EXPORT:MessageBoxIndirectW=user32.MessageBoxIndirectW") +#pragma comment(linker, "/EXPORT:MessageBoxTimeoutA=user32.MessageBoxTimeoutA") +#pragma comment(linker, "/EXPORT:MessageBoxTimeoutW=user32.MessageBoxTimeoutW") +#pragma comment(linker, "/EXPORT:MessageBoxW=user32.MessageBoxW") +#pragma comment(linker, "/EXPORT:ModifyMenuA=user32.ModifyMenuA") +#pragma comment(linker, "/EXPORT:ModifyMenuW=user32.ModifyMenuW") +#pragma comment(linker, "/EXPORT:MonitorFromPoint=user32.MonitorFromPoint") +#pragma comment(linker, "/EXPORT:MonitorFromRect=user32.MonitorFromRect") +#pragma comment(linker, "/EXPORT:MonitorFromWindow=user32.MonitorFromWindow") +#pragma comment(linker, "/EXPORT:MoveWindow=user32.MoveWindow") +#pragma comment(linker, "/EXPORT:MsgWaitForMultipleObjects=user32.MsgWaitForMultipleObjects") +#pragma comment(linker, "/EXPORT:MsgWaitForMultipleObjectsEx=user32.MsgWaitForMultipleObjectsEx") +#pragma comment(linker, "/EXPORT:NotifyOverlayWindow=user32.NotifyOverlayWindow") +#pragma comment(linker, "/EXPORT:NotifyWinEvent=user32.NotifyWinEvent") +#pragma comment(linker, "/EXPORT:OemKeyScan=user32.OemKeyScan") +#pragma comment(linker, "/EXPORT:OemToCharA=user32.OemToCharA") +#pragma comment(linker, "/EXPORT:OemToCharBuffA=user32.OemToCharBuffA") +#pragma comment(linker, "/EXPORT:OemToCharBuffW=user32.OemToCharBuffW") +#pragma comment(linker, "/EXPORT:OemToCharW=user32.OemToCharW") +#pragma comment(linker, "/EXPORT:OffsetRect=user32.OffsetRect") +#pragma comment(linker, "/EXPORT:OpenClipboard=user32.OpenClipboard") +#pragma comment(linker, "/EXPORT:OpenDesktopA=user32.OpenDesktopA") +#pragma comment(linker, "/EXPORT:OpenDesktopW=user32.OpenDesktopW") +#pragma comment(linker, "/EXPORT:OpenIcon=user32.OpenIcon") +#pragma comment(linker, "/EXPORT:OpenInputDesktop=user32.OpenInputDesktop") +#pragma comment(linker, "/EXPORT:OpenThreadDesktop=user32.OpenThreadDesktop") +#pragma comment(linker, "/EXPORT:OpenWindowStationA=user32.OpenWindowStationA") +#pragma comment(linker, "/EXPORT:OpenWindowStationW=user32.OpenWindowStationW") +#pragma comment(linker, "/EXPORT:PackDDElParam=user32.PackDDElParam") +#pragma comment(linker, "/EXPORT:PaintDesktop=user32.PaintDesktop") +#pragma comment(linker, "/EXPORT:PaintMenuBar=user32.PaintMenuBar") +#pragma comment(linker, "/EXPORT:PaintMonitor=user32.PaintMonitor") +#pragma comment(linker, "/EXPORT:PeekMessageA=user32.PeekMessageA") +#pragma comment(linker, "/EXPORT:PeekMessageW=user32.PeekMessageW") +#pragma comment(linker, "/EXPORT:PhysicalToLogicalPoint=user32.PhysicalToLogicalPoint") +#pragma comment(linker, "/EXPORT:PostMessageA=user32.PostMessageA") +#pragma comment(linker, "/EXPORT:PostMessageW=user32.PostMessageW") +#pragma comment(linker, "/EXPORT:PostQuitMessage=user32.PostQuitMessage") +#pragma comment(linker, "/EXPORT:PostThreadMessageA=user32.PostThreadMessageA") +#pragma comment(linker, "/EXPORT:PostThreadMessageW=user32.PostThreadMessageW") +#pragma comment(linker, "/EXPORT:PrintWindow=user32.PrintWindow") +#pragma comment(linker, "/EXPORT:PrivateExtractIconExA=user32.PrivateExtractIconExA") +#pragma comment(linker, "/EXPORT:PrivateExtractIconExW=user32.PrivateExtractIconExW") +#pragma comment(linker, "/EXPORT:PrivateExtractIconsA=user32.PrivateExtractIconsA") +#pragma comment(linker, "/EXPORT:PrivateExtractIconsW=user32.PrivateExtractIconsW") +#pragma comment(linker, "/EXPORT:PrivateRegisterICSProc=user32.PrivateRegisterICSProc") +#pragma comment(linker, "/EXPORT:PtInRect=user32.PtInRect") +#pragma comment(linker, "/EXPORT:QueryDisplayConfig=user32.QueryDisplayConfig") +#pragma comment(linker, "/EXPORT:QuerySendMessage=user32.QuerySendMessage") +#pragma comment(linker, "/EXPORT:RealChildWindowFromPoint=user32.RealChildWindowFromPoint") +#pragma comment(linker, "/EXPORT:RealGetWindowClass=user32.RealGetWindowClass") +#pragma comment(linker, "/EXPORT:RealGetWindowClassA=user32.RealGetWindowClassA") +#pragma comment(linker, "/EXPORT:RealGetWindowClassW=user32.RealGetWindowClassW") +#pragma comment(linker, "/EXPORT:ReasonCodeNeedsBugID=user32.ReasonCodeNeedsBugID") +#pragma comment(linker, "/EXPORT:ReasonCodeNeedsComment=user32.ReasonCodeNeedsComment") +#pragma comment(linker, "/EXPORT:RecordShutdownReason=user32.RecordShutdownReason") +#pragma comment(linker, "/EXPORT:RedrawWindow=user32.RedrawWindow") +#pragma comment(linker, "/EXPORT:RegisterClassA=user32.RegisterClassA") +#pragma comment(linker, "/EXPORT:RegisterClassExA=user32.RegisterClassExA") +#pragma comment(linker, "/EXPORT:RegisterClassExW=user32.RegisterClassExW") +#pragma comment(linker, "/EXPORT:RegisterClassW=user32.RegisterClassW") +#pragma comment(linker, "/EXPORT:RegisterClipboardFormatA=user32.RegisterClipboardFormatA") +#pragma comment(linker, "/EXPORT:RegisterClipboardFormatW=user32.RegisterClipboardFormatW") +#pragma comment(linker, "/EXPORT:RegisterDeviceNotificationA=user32.RegisterDeviceNotificationA") +#pragma comment(linker, "/EXPORT:RegisterDeviceNotificationW=user32.RegisterDeviceNotificationW") +#pragma comment(linker, "/EXPORT:RegisterErrorReportingDialog=user32.RegisterErrorReportingDialog") +#pragma comment(linker, "/EXPORT:RegisterFrostWindow=user32.RegisterFrostWindow") +#pragma comment(linker, "/EXPORT:RegisterGhostWindow=user32.RegisterGhostWindow") +#pragma comment(linker, "/EXPORT:RegisterHotKey=user32.RegisterHotKey") +#pragma comment(linker, "/EXPORT:RegisterLogonProcess=user32.RegisterLogonProcess") +#pragma comment(linker, "/EXPORT:RegisterMessagePumpHook=user32.RegisterMessagePumpHook") +#pragma comment(linker, "/EXPORT:RegisterPowerSettingNotification=user32.RegisterPowerSettingNotification") +#pragma comment(linker, "/EXPORT:RegisterRawInputDevices=user32.RegisterRawInputDevices") +#pragma comment(linker, "/EXPORT:RegisterServicesProcess=user32.RegisterServicesProcess") +#pragma comment(linker, "/EXPORT:RegisterSessionPort=user32.RegisterSessionPort") +#pragma comment(linker, "/EXPORT:RegisterShellHookWindow=user32.RegisterShellHookWindow") +#pragma comment(linker, "/EXPORT:RegisterSystemThread=user32.RegisterSystemThread") +#pragma comment(linker, "/EXPORT:RegisterTasklist=user32.RegisterTasklist") +#pragma comment(linker, "/EXPORT:RegisterTouchWindow=user32.RegisterTouchWindow") +#pragma comment(linker, "/EXPORT:RegisterUserApiHook=user32.RegisterUserApiHook") +#pragma comment(linker, "/EXPORT:RegisterWindowMessageA=user32.RegisterWindowMessageA") +#pragma comment(linker, "/EXPORT:RegisterWindowMessageW=user32.RegisterWindowMessageW") +#pragma comment(linker, "/EXPORT:ReleaseCapture=user32.ReleaseCapture") +#pragma comment(linker, "/EXPORT:ReleaseDC=user32.ReleaseDC") +#pragma comment(linker, "/EXPORT:RemoveClipboardFormatListener=user32.RemoveClipboardFormatListener") +#pragma comment(linker, "/EXPORT:RemoveMenu=user32.RemoveMenu") +#pragma comment(linker, "/EXPORT:RemovePropA=user32.RemovePropA") +#pragma comment(linker, "/EXPORT:RemovePropW=user32.RemovePropW") +#pragma comment(linker, "/EXPORT:ReplyMessage=user32.ReplyMessage") +#pragma comment(linker, "/EXPORT:ResolveDesktopForWOW=user32.ResolveDesktopForWOW") +#pragma comment(linker, "/EXPORT:ReuseDDElParam=user32.ReuseDDElParam") +#pragma comment(linker, "/EXPORT:ScreenToClient=user32.ScreenToClient") +#pragma comment(linker, "/EXPORT:ScrollChildren=user32.ScrollChildren") +#pragma comment(linker, "/EXPORT:ScrollDC=user32.ScrollDC") +#pragma comment(linker, "/EXPORT:ScrollWindow=user32.ScrollWindow") +#pragma comment(linker, "/EXPORT:ScrollWindowEx=user32.ScrollWindowEx") +#pragma comment(linker, "/EXPORT:SendDlgItemMessageA=user32.SendDlgItemMessageA") +#pragma comment(linker, "/EXPORT:SendDlgItemMessageW=user32.SendDlgItemMessageW") +#pragma comment(linker, "/EXPORT:SendIMEMessageExA=user32.SendIMEMessageExA") +#pragma comment(linker, "/EXPORT:SendIMEMessageExW=user32.SendIMEMessageExW") +#pragma comment(linker, "/EXPORT:SendInput=user32.SendInput") +#pragma comment(linker, "/EXPORT:SendMessageA=user32.SendMessageA") +#pragma comment(linker, "/EXPORT:SendMessageCallbackA=user32.SendMessageCallbackA") +#pragma comment(linker, "/EXPORT:SendMessageCallbackW=user32.SendMessageCallbackW") +#pragma comment(linker, "/EXPORT:SendMessageTimeoutA=user32.SendMessageTimeoutA") +#pragma comment(linker, "/EXPORT:SendMessageTimeoutW=user32.SendMessageTimeoutW") +#pragma comment(linker, "/EXPORT:SendMessageW=user32.SendMessageW") +#pragma comment(linker, "/EXPORT:SendNotifyMessageA=user32.SendNotifyMessageA") +#pragma comment(linker, "/EXPORT:SendNotifyMessageW=user32.SendNotifyMessageW") +#pragma comment(linker, "/EXPORT:SetActiveWindow=user32.SetActiveWindow") +#pragma comment(linker, "/EXPORT:SetCapture=user32.SetCapture") +#pragma comment(linker, "/EXPORT:SetCaretBlinkTime=user32.SetCaretBlinkTime") +#pragma comment(linker, "/EXPORT:SetCaretPos=user32.SetCaretPos") +#pragma comment(linker, "/EXPORT:SetClassLongA=user32.SetClassLongA") +#pragma comment(linker, "/EXPORT:SetClassLongPtrA=user32.SetClassLongPtrA") +#pragma comment(linker, "/EXPORT:SetClassLongPtrW=user32.SetClassLongPtrW") +#pragma comment(linker, "/EXPORT:SetClassLongW=user32.SetClassLongW") +#pragma comment(linker, "/EXPORT:SetClassWord=user32.SetClassWord") +#pragma comment(linker, "/EXPORT:SetClipboardData=user32.SetClipboardData") +#pragma comment(linker, "/EXPORT:SetClipboardViewer=user32.SetClipboardViewer") +#pragma comment(linker, "/EXPORT:SetCursor=user32.SetCursor") +#pragma comment(linker, "/EXPORT:SetCursorContents=user32.SetCursorContents") +#pragma comment(linker, "/EXPORT:SetCursorPos=user32.SetCursorPos") +#pragma comment(linker, "/EXPORT:SetDebugErrorLevel=user32.SetDebugErrorLevel") +#pragma comment(linker, "/EXPORT:SetDeskWallpaper=user32.SetDeskWallpaper") +#pragma comment(linker, "/EXPORT:SetDisplayConfig=user32.SetDisplayConfig") +#pragma comment(linker, "/EXPORT:SetDlgItemInt=user32.SetDlgItemInt") +#pragma comment(linker, "/EXPORT:SetDlgItemTextA=user32.SetDlgItemTextA") +#pragma comment(linker, "/EXPORT:SetDlgItemTextW=user32.SetDlgItemTextW") +#pragma comment(linker, "/EXPORT:SetDoubleClickTime=user32.SetDoubleClickTime") +#pragma comment(linker, "/EXPORT:SetFocus=user32.SetFocus") +#pragma comment(linker, "/EXPORT:SetForegroundWindow=user32.SetForegroundWindow") +#pragma comment(linker, "/EXPORT:SetGestureConfig=user32.SetGestureConfig") +#pragma comment(linker, "/EXPORT:SetInternalWindowPos=user32.SetInternalWindowPos") +#pragma comment(linker, "/EXPORT:SetKeyboardState=user32.SetKeyboardState") +#pragma comment(linker, "/EXPORT:SetLastErrorEx=user32.SetLastErrorEx") +#pragma comment(linker, "/EXPORT:SetLayeredWindowAttributes=user32.SetLayeredWindowAttributes") +#pragma comment(linker, "/EXPORT:SetMagnificationDesktopColorEffect=user32.SetMagnificationDesktopColorEffect") +#pragma comment(linker, "/EXPORT:SetMagnificationDesktopMagnification=user32.SetMagnificationDesktopMagnification") +#pragma comment(linker, "/EXPORT:SetMagnificationLensCtxInformation=user32.SetMagnificationLensCtxInformation") +#pragma comment(linker, "/EXPORT:SetMenu=user32.SetMenu") +#pragma comment(linker, "/EXPORT:SetMenuContextHelpId=user32.SetMenuContextHelpId") +#pragma comment(linker, "/EXPORT:SetMenuDefaultItem=user32.SetMenuDefaultItem") +#pragma comment(linker, "/EXPORT:SetMenuInfo=user32.SetMenuInfo") +#pragma comment(linker, "/EXPORT:SetMenuItemBitmaps=user32.SetMenuItemBitmaps") +#pragma comment(linker, "/EXPORT:SetMenuItemInfoA=user32.SetMenuItemInfoA") +#pragma comment(linker, "/EXPORT:SetMenuItemInfoW=user32.SetMenuItemInfoW") +#pragma comment(linker, "/EXPORT:SetMessageExtraInfo=user32.SetMessageExtraInfo") +#pragma comment(linker, "/EXPORT:SetMessageQueue=user32.SetMessageQueue") +#pragma comment(linker, "/EXPORT:SetMirrorRendering=user32.SetMirrorRendering") +#pragma comment(linker, "/EXPORT:SetParent=user32.SetParent") +#pragma comment(linker, "/EXPORT:SetPhysicalCursorPos=user32.SetPhysicalCursorPos") +#pragma comment(linker, "/EXPORT:SetProcessDPIAware=user32.SetProcessDPIAware") +#pragma comment(linker, "/EXPORT:SetProcessDefaultLayout=user32.SetProcessDefaultLayout") +#pragma comment(linker, "/EXPORT:SetProcessWindowStation=user32.SetProcessWindowStation") +#pragma comment(linker, "/EXPORT:SetProgmanWindow=user32.SetProgmanWindow") +#pragma comment(linker, "/EXPORT:SetPropA=user32.SetPropA") +#pragma comment(linker, "/EXPORT:SetPropW=user32.SetPropW") +#pragma comment(linker, "/EXPORT:SetRect=user32.SetRect") +#pragma comment(linker, "/EXPORT:SetRectEmpty=user32.SetRectEmpty") +#pragma comment(linker, "/EXPORT:SetScrollInfo=user32.SetScrollInfo") +#pragma comment(linker, "/EXPORT:SetScrollPos=user32.SetScrollPos") +#pragma comment(linker, "/EXPORT:SetScrollRange=user32.SetScrollRange") +#pragma comment(linker, "/EXPORT:SetShellWindow=user32.SetShellWindow") +#pragma comment(linker, "/EXPORT:SetShellWindowEx=user32.SetShellWindowEx") +#pragma comment(linker, "/EXPORT:SetSysColors=user32.SetSysColors") +#pragma comment(linker, "/EXPORT:SetSysColorsTemp=user32.SetSysColorsTemp") +#pragma comment(linker, "/EXPORT:SetSystemCursor=user32.SetSystemCursor") +#pragma comment(linker, "/EXPORT:SetSystemMenu=user32.SetSystemMenu") +#pragma comment(linker, "/EXPORT:SetTaskmanWindow=user32.SetTaskmanWindow") +#pragma comment(linker, "/EXPORT:SetThreadDesktop=user32.SetThreadDesktop") +#pragma comment(linker, "/EXPORT:SetTimer=user32.SetTimer") +#pragma comment(linker, "/EXPORT:SetUserObjectInformationA=user32.SetUserObjectInformationA") +#pragma comment(linker, "/EXPORT:SetUserObjectInformationW=user32.SetUserObjectInformationW") +#pragma comment(linker, "/EXPORT:SetUserObjectSecurity=user32.SetUserObjectSecurity") +#pragma comment(linker, "/EXPORT:SetWinEventHook=user32.SetWinEventHook") +#pragma comment(linker, "/EXPORT:SetWindowCompositionAttribute=user32.SetWindowCompositionAttribute") +#pragma comment(linker, "/EXPORT:SetWindowContextHelpId=user32.SetWindowContextHelpId") +#pragma comment(linker, "/EXPORT:SetWindowDisplayAffinity=user32.SetWindowDisplayAffinity") +#pragma comment(linker, "/EXPORT:SetWindowLongA=user32.SetWindowLongA") +#pragma comment(linker, "/EXPORT:SetWindowLongPtrA=user32.SetWindowLongPtrA") +#pragma comment(linker, "/EXPORT:SetWindowLongPtrW=user32.SetWindowLongPtrW") +#pragma comment(linker, "/EXPORT:SetWindowLongW=user32.SetWindowLongW") +#pragma comment(linker, "/EXPORT:SetWindowPlacement=user32.SetWindowPlacement") +#pragma comment(linker, "/EXPORT:SetWindowPos=user32.SetWindowPos") +#pragma comment(linker, "/EXPORT:SetWindowRgn=user32.SetWindowRgn") +#pragma comment(linker, "/EXPORT:SetWindowRgnEx=user32.SetWindowRgnEx") +#pragma comment(linker, "/EXPORT:SetWindowStationUser=user32.SetWindowStationUser") +#pragma comment(linker, "/EXPORT:SetWindowTextA=user32.SetWindowTextA") +#pragma comment(linker, "/EXPORT:SetWindowTextW=user32.SetWindowTextW") +#pragma comment(linker, "/EXPORT:SetWindowWord=user32.SetWindowWord") +#pragma comment(linker, "/EXPORT:SetWindowsHookA=user32.SetWindowsHookA") +#pragma comment(linker, "/EXPORT:SetWindowsHookExA=user32.SetWindowsHookExA") +#pragma comment(linker, "/EXPORT:SetWindowsHookExW=user32.SetWindowsHookExW") +#pragma comment(linker, "/EXPORT:SetWindowsHookW=user32.SetWindowsHookW") +#pragma comment(linker, "/EXPORT:SfmDxBindSwapChain=user32.SfmDxBindSwapChain") +#pragma comment(linker, "/EXPORT:SfmDxGetSwapChainStats=user32.SfmDxGetSwapChainStats") +#pragma comment(linker, "/EXPORT:SfmDxOpenSwapChain=user32.SfmDxOpenSwapChain") +#pragma comment(linker, "/EXPORT:SfmDxQuerySwapChainBindingStatus=user32.SfmDxQuerySwapChainBindingStatus") +#pragma comment(linker, "/EXPORT:SfmDxReleaseSwapChain=user32.SfmDxReleaseSwapChain") +#pragma comment(linker, "/EXPORT:SfmDxReportPendingBindingsToDwm=user32.SfmDxReportPendingBindingsToDwm") +#pragma comment(linker, "/EXPORT:SfmDxSetSwapChainBindingStatus=user32.SfmDxSetSwapChainBindingStatus") +#pragma comment(linker, "/EXPORT:SfmDxSetSwapChainStats=user32.SfmDxSetSwapChainStats") +#pragma comment(linker, "/EXPORT:ShowCaret=user32.ShowCaret") +#pragma comment(linker, "/EXPORT:ShowCursor=user32.ShowCursor") +#pragma comment(linker, "/EXPORT:ShowOwnedPopups=user32.ShowOwnedPopups") +#pragma comment(linker, "/EXPORT:ShowScrollBar=user32.ShowScrollBar") +#pragma comment(linker, "/EXPORT:ShowStartGlass=user32.ShowStartGlass") +#pragma comment(linker, "/EXPORT:ShowSystemCursor=user32.ShowSystemCursor") +#pragma comment(linker, "/EXPORT:ShowWindow=user32.ShowWindow") +#pragma comment(linker, "/EXPORT:ShowWindowAsync=user32.ShowWindowAsync") +#pragma comment(linker, "/EXPORT:ShutdownBlockReasonCreate=user32.ShutdownBlockReasonCreate") +#pragma comment(linker, "/EXPORT:ShutdownBlockReasonDestroy=user32.ShutdownBlockReasonDestroy") +#pragma comment(linker, "/EXPORT:ShutdownBlockReasonQuery=user32.ShutdownBlockReasonQuery") +#pragma comment(linker, "/EXPORT:SoftModalMessageBox=user32.SoftModalMessageBox") +#pragma comment(linker, "/EXPORT:SoundSentry=user32.SoundSentry") +#pragma comment(linker, "/EXPORT:SubtractRect=user32.SubtractRect") +#pragma comment(linker, "/EXPORT:SwapMouseButton=user32.SwapMouseButton") +#pragma comment(linker, "/EXPORT:SwitchDesktop=user32.SwitchDesktop") +#pragma comment(linker, "/EXPORT:SwitchDesktopWithFade=user32.SwitchDesktopWithFade") +#pragma comment(linker, "/EXPORT:SwitchToThisWindow=user32.SwitchToThisWindow") +#pragma comment(linker, "/EXPORT:SystemParametersInfoA=user32.SystemParametersInfoA") +#pragma comment(linker, "/EXPORT:SystemParametersInfoW=user32.SystemParametersInfoW") +#pragma comment(linker, "/EXPORT:TabbedTextOutA=user32.TabbedTextOutA") +#pragma comment(linker, "/EXPORT:TabbedTextOutW=user32.TabbedTextOutW") +#pragma comment(linker, "/EXPORT:TileChildWindows=user32.TileChildWindows") +#pragma comment(linker, "/EXPORT:TileWindows=user32.TileWindows") +#pragma comment(linker, "/EXPORT:ToAscii=user32.ToAscii") +#pragma comment(linker, "/EXPORT:ToAsciiEx=user32.ToAsciiEx") +#pragma comment(linker, "/EXPORT:ToUnicode=user32.ToUnicode") +#pragma comment(linker, "/EXPORT:ToUnicodeEx=user32.ToUnicodeEx") +#pragma comment(linker, "/EXPORT:TrackMouseEvent=user32.TrackMouseEvent") +#pragma comment(linker, "/EXPORT:TrackPopupMenu=user32.TrackPopupMenu") +#pragma comment(linker, "/EXPORT:TrackPopupMenuEx=user32.TrackPopupMenuEx") +#pragma comment(linker, "/EXPORT:TranslateAccelerator=user32.TranslateAccelerator") +#pragma comment(linker, "/EXPORT:TranslateAcceleratorA=user32.TranslateAcceleratorA") +#pragma comment(linker, "/EXPORT:TranslateAcceleratorW=user32.TranslateAcceleratorW") +#pragma comment(linker, "/EXPORT:TranslateMDISysAccel=user32.TranslateMDISysAccel") +#pragma comment(linker, "/EXPORT:TranslateMessage=user32.TranslateMessage") +#pragma comment(linker, "/EXPORT:TranslateMessageEx=user32.TranslateMessageEx") +#pragma comment(linker, "/EXPORT:UnhookWinEvent=user32.UnhookWinEvent") +#pragma comment(linker, "/EXPORT:UnhookWindowsHook=user32.UnhookWindowsHook") +#pragma comment(linker, "/EXPORT:UnhookWindowsHookEx=user32.UnhookWindowsHookEx") +#pragma comment(linker, "/EXPORT:UnionRect=user32.UnionRect") +#pragma comment(linker, "/EXPORT:UnloadKeyboardLayout=user32.UnloadKeyboardLayout") +#pragma comment(linker, "/EXPORT:UnlockWindowStation=user32.UnlockWindowStation") +#pragma comment(linker, "/EXPORT:UnpackDDElParam=user32.UnpackDDElParam") +#pragma comment(linker, "/EXPORT:UnregisterClassA=user32.UnregisterClassA") +#pragma comment(linker, "/EXPORT:UnregisterClassW=user32.UnregisterClassW") +#pragma comment(linker, "/EXPORT:UnregisterDeviceNotification=user32.UnregisterDeviceNotification") +#pragma comment(linker, "/EXPORT:UnregisterHotKey=user32.UnregisterHotKey") +#pragma comment(linker, "/EXPORT:UnregisterMessagePumpHook=user32.UnregisterMessagePumpHook") +#pragma comment(linker, "/EXPORT:UnregisterPowerSettingNotification=user32.UnregisterPowerSettingNotification") +#pragma comment(linker, "/EXPORT:UnregisterSessionPort=user32.UnregisterSessionPort") +#pragma comment(linker, "/EXPORT:UnregisterTouchWindow=user32.UnregisterTouchWindow") +#pragma comment(linker, "/EXPORT:UnregisterUserApiHook=user32.UnregisterUserApiHook") +#pragma comment(linker, "/EXPORT:UpdateLayeredWindow=user32.UpdateLayeredWindow") +#pragma comment(linker, "/EXPORT:UpdateLayeredWindowIndirect=user32.UpdateLayeredWindowIndirect") +#pragma comment(linker, "/EXPORT:UpdatePerUserSystemParameters=user32.UpdatePerUserSystemParameters") +#pragma comment(linker, "/EXPORT:UpdateWindow=user32.UpdateWindow") +#pragma comment(linker, "/EXPORT:UpdateWindowTransform=user32.UpdateWindowTransform") +#pragma comment(linker, "/EXPORT:User32InitializeImmEntryTable=user32.User32InitializeImmEntryTable") +#pragma comment(linker, "/EXPORT:UserClientDllInitialize=user32.UserClientDllInitialize") +#pragma comment(linker, "/EXPORT:UserHandleGrantAccess=user32.UserHandleGrantAccess") +#pragma comment(linker, "/EXPORT:UserLpkPSMTextOut=user32.UserLpkPSMTextOut") +#pragma comment(linker, "/EXPORT:UserLpkTabbedTextOut=user32.UserLpkTabbedTextOut") +#pragma comment(linker, "/EXPORT:UserRealizePalette=user32.UserRealizePalette") +#pragma comment(linker, "/EXPORT:UserRegisterWowHandlers=user32.UserRegisterWowHandlers") +#pragma comment(linker, "/EXPORT:VRipOutput=user32.VRipOutput") +#pragma comment(linker, "/EXPORT:VTagOutput=user32.VTagOutput") +#pragma comment(linker, "/EXPORT:ValidateRect=user32.ValidateRect") +#pragma comment(linker, "/EXPORT:ValidateRgn=user32.ValidateRgn") +#pragma comment(linker, "/EXPORT:VkKeyScanA=user32.VkKeyScanA") +#pragma comment(linker, "/EXPORT:VkKeyScanExA=user32.VkKeyScanExA") +#pragma comment(linker, "/EXPORT:VkKeyScanExW=user32.VkKeyScanExW") +#pragma comment(linker, "/EXPORT:VkKeyScanW=user32.VkKeyScanW") +#pragma comment(linker, "/EXPORT:WCSToMBEx=user32.WCSToMBEx") +#pragma comment(linker, "/EXPORT:WINNLSEnableIME=user32.WINNLSEnableIME") +#pragma comment(linker, "/EXPORT:WINNLSGetEnableStatus=user32.WINNLSGetEnableStatus") +#pragma comment(linker, "/EXPORT:WINNLSGetIMEHotkey=user32.WINNLSGetIMEHotkey") +#pragma comment(linker, "/EXPORT:WaitForInputIdle=user32.WaitForInputIdle") +#pragma comment(linker, "/EXPORT:WaitMessage=user32.WaitMessage") +#pragma comment(linker, "/EXPORT:WinHelpA=user32.WinHelpA") +#pragma comment(linker, "/EXPORT:WinHelpW=user32.WinHelpW") +#pragma comment(linker, "/EXPORT:WindowFromDC=user32.WindowFromDC") +#pragma comment(linker, "/EXPORT:WindowFromPhysicalPoint=user32.WindowFromPhysicalPoint") +#pragma comment(linker, "/EXPORT:WindowFromPoint=user32.WindowFromPoint") +#pragma comment(linker, "/EXPORT:_UserTestTokenForInteractive=user32._UserTestTokenForInteractive") +#pragma comment(linker, "/EXPORT:gSharedInfo=user32.gSharedInfo") +#pragma comment(linker, "/EXPORT:gapfnScSendMessage=user32.gapfnScSendMessage") +#pragma comment(linker, "/EXPORT:keybd_event=user32.keybd_event") +#pragma comment(linker, "/EXPORT:mouse_event=user32.mouse_event") +#pragma comment(linker, "/EXPORT:wsprintfA=user32.wsprintfA") +#pragma comment(linker, "/EXPORT:wsprintfW=user32.wsprintfW") +#pragma comment(linker, "/EXPORT:wvsprintfA=user32.wvsprintfA") +#pragma comment(linker, "/EXPORT:wvsprintfW=user32.wvsprintfW") +#pragma comment(linker, "/EXPORT:__OrdinalFunction1500=user32.#1500,@1500,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction1501=user32.#1501,@1501,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction1550=user32.#1550,@1550,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction1551=user32.#1551,@1551,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction1552=user32.#1552,@1552,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction1553=user32.#1553,@1553,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction1554=user32.#1554,@1554,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction1555=user32.#1555,@1555,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction1556=user32.#1556,@1556,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2000=user32.#2000,@2000,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2001=user32.#2001,@2001,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2002=user32.#2002,@2002,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2005=user32.#2005,@2005,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2343=user32.#2343,@2343,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2344=user32.#2344,@2344,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2345=user32.#2345,@2345,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2346=user32.#2346,@2346,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2347=user32.#2347,@2347,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2348=user32.#2348,@2348,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2349=user32.#2349,@2349,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2350=user32.#2350,@2350,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2351=user32.#2351,@2351,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2352=user32.#2352,@2352,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2353=user32.#2353,@2353,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2354=user32.#2354,@2354,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2355=user32.#2355,@2355,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2356=user32.#2356,@2356,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2357=user32.#2357,@2357,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2358=user32.#2358,@2358,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2359=user32.#2359,@2359,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2360=user32.#2360,@2360,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2361=user32.#2361,@2361,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2362=user32.#2362,@2362,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2363=user32.#2363,@2363,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2364=user32.#2364,@2364,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2365=user32.#2365,@2365,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2366=user32.#2366,@2366,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2367=user32.#2367,@2367,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2368=user32.#2368,@2368,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2369=user32.#2369,@2369,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2370=user32.#2370,@2370,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2371=user32.#2371,@2371,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2372=user32.#2372,@2372,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2373=user32.#2373,@2373,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2374=user32.#2374,@2374,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2375=user32.#2375,@2375,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2376=user32.#2376,@2376,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2377=user32.#2377,@2377,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2378=user32.#2378,@2378,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2379=user32.#2379,@2379,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2380=user32.#2380,@2380,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2381=user32.#2381,@2381,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2382=user32.#2382,@2382,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2383=user32.#2383,@2383,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2384=user32.#2384,@2384,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2385=user32.#2385,@2385,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2386=user32.#2386,@2386,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2387=user32.#2387,@2387,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2388=user32.#2388,@2388,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2389=user32.#2389,@2389,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2390=user32.#2390,@2390,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2391=user32.#2391,@2391,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2392=user32.#2392,@2392,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2393=user32.#2393,@2393,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2394=user32.#2394,@2394,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2395=user32.#2395,@2395,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2396=user32.#2396,@2396,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2397=user32.#2397,@2397,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2398=user32.#2398,@2398,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2399=user32.#2399,@2399,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2400=user32.#2400,@2400,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2401=user32.#2401,@2401,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2402=user32.#2402,@2402,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2403=user32.#2403,@2403,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2404=user32.#2404,@2404,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2405=user32.#2405,@2405,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2406=user32.#2406,@2406,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2407=user32.#2407,@2407,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2408=user32.#2408,@2408,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2409=user32.#2409,@2409,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2410=user32.#2410,@2410,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2411=user32.#2411,@2411,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2412=user32.#2412,@2412,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2413=user32.#2413,@2413,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2414=user32.#2414,@2414,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2415=user32.#2415,@2415,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2416=user32.#2416,@2416,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2417=user32.#2417,@2417,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2418=user32.#2418,@2418,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2419=user32.#2419,@2419,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2420=user32.#2420,@2420,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2421=user32.#2421,@2421,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2422=user32.#2422,@2422,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2423=user32.#2423,@2423,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2424=user32.#2424,@2424,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2425=user32.#2425,@2425,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2426=user32.#2426,@2426,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2427=user32.#2427,@2427,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2428=user32.#2428,@2428,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2429=user32.#2429,@2429,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2430=user32.#2430,@2430,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2431=user32.#2431,@2431,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2432=user32.#2432,@2432,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2433=user32.#2433,@2433,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2434=user32.#2434,@2434,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2435=user32.#2435,@2435,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2436=user32.#2436,@2436,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2437=user32.#2437,@2437,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2438=user32.#2438,@2438,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2439=user32.#2439,@2439,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2440=user32.#2440,@2440,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2441=user32.#2441,@2441,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2442=user32.#2442,@2442,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2443=user32.#2443,@2443,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2444=user32.#2444,@2444,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2445=user32.#2445,@2445,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2446=user32.#2446,@2446,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2447=user32.#2447,@2447,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2448=user32.#2448,@2448,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2449=user32.#2449,@2449,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2450=user32.#2450,@2450,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2451=user32.#2451,@2451,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2452=user32.#2452,@2452,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2453=user32.#2453,@2453,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2454=user32.#2454,@2454,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2455=user32.#2455,@2455,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2456=user32.#2456,@2456,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2457=user32.#2457,@2457,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2458=user32.#2458,@2458,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2459=user32.#2459,@2459,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2460=user32.#2460,@2460,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2461=user32.#2461,@2461,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2462=user32.#2462,@2462,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2463=user32.#2463,@2463,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2464=user32.#2464,@2464,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2465=user32.#2465,@2465,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2466=user32.#2466,@2466,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2467=user32.#2467,@2467,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2468=user32.#2468,@2468,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2469=user32.#2469,@2469,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2470=user32.#2470,@2470,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2471=user32.#2471,@2471,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2472=user32.#2472,@2472,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2473=user32.#2473,@2473,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2474=user32.#2474,@2474,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2475=user32.#2475,@2475,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2476=user32.#2476,@2476,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2477=user32.#2477,@2477,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2478=user32.#2478,@2478,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2479=user32.#2479,@2479,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2480=user32.#2480,@2480,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2481=user32.#2481,@2481,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2482=user32.#2482,@2482,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2483=user32.#2483,@2483,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2484=user32.#2484,@2484,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2485=user32.#2485,@2485,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2486=user32.#2486,@2486,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2487=user32.#2487,@2487,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2488=user32.#2488,@2488,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2489=user32.#2489,@2489,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2490=user32.#2490,@2490,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2491=user32.#2491,@2491,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2492=user32.#2492,@2492,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2493=user32.#2493,@2493,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2494=user32.#2494,@2494,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2495=user32.#2495,@2495,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2496=user32.#2496,@2496,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2497=user32.#2497,@2497,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2498=user32.#2498,@2498,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2499=user32.#2499,@2499,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2500=user32.#2500,@2500,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2501=user32.#2501,@2501,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2502=user32.#2502,@2502,NONAME") + +// Generated by KexExprt from "C:\Windows\system32\shell32.dll" +#pragma comment(linker, "/EXPORT:AppCompat_RunDLLW=shell32.AppCompat_RunDLLW") +#pragma comment(linker, "/EXPORT:AssocCreateForClasses=shell32.AssocCreateForClasses") +#pragma comment(linker, "/EXPORT:AssocGetDetailsOfPropKey=shell32.AssocGetDetailsOfPropKey") +#pragma comment(linker, "/EXPORT:CDefFolderMenu_Create2=shell32.CDefFolderMenu_Create2") +#pragma comment(linker, "/EXPORT:CIDLData_CreateFromIDArray=shell32.CIDLData_CreateFromIDArray") +#pragma comment(linker, "/EXPORT:CheckEscapesW=shell32.CheckEscapesW") +#pragma comment(linker, "/EXPORT:CommandLineToArgvW=shell32.CommandLineToArgvW") +#pragma comment(linker, "/EXPORT:Control_RunDLL=shell32.Control_RunDLL") +#pragma comment(linker, "/EXPORT:Control_RunDLLA=shell32.Control_RunDLLA") +#pragma comment(linker, "/EXPORT:Control_RunDLLAsUserW=shell32.Control_RunDLLAsUserW") +#pragma comment(linker, "/EXPORT:Control_RunDLLW=shell32.Control_RunDLLW") +#pragma comment(linker, "/EXPORT:DAD_AutoScroll=shell32.DAD_AutoScroll") +#pragma comment(linker, "/EXPORT:DAD_DragEnterEx=shell32.DAD_DragEnterEx") +#pragma comment(linker, "/EXPORT:DAD_DragEnterEx2=shell32.DAD_DragEnterEx2") +#pragma comment(linker, "/EXPORT:DAD_DragLeave=shell32.DAD_DragLeave") +#pragma comment(linker, "/EXPORT:DAD_DragMove=shell32.DAD_DragMove") +#pragma comment(linker, "/EXPORT:DAD_SetDragImage=shell32.DAD_SetDragImage") +#pragma comment(linker, "/EXPORT:DAD_ShowDragImage=shell32.DAD_ShowDragImage") +#pragma comment(linker, "/EXPORT:DllCanUnloadNow=shell32.DllCanUnloadNow") +#pragma comment(linker, "/EXPORT:DllGetClassObject=shell32.DllGetClassObject") +#pragma comment(linker, "/EXPORT:DllGetVersion=shell32.DllGetVersion") +#pragma comment(linker, "/EXPORT:DllInstall=shell32.DllInstall") +#pragma comment(linker, "/EXPORT:DllRegisterServer=shell32.DllRegisterServer") +#pragma comment(linker, "/EXPORT:DllUnregisterServer=shell32.DllUnregisterServer") +#pragma comment(linker, "/EXPORT:DoEnvironmentSubstA=shell32.DoEnvironmentSubstA") +#pragma comment(linker, "/EXPORT:DoEnvironmentSubstW=shell32.DoEnvironmentSubstW") +#pragma comment(linker, "/EXPORT:DragAcceptFiles=shell32.DragAcceptFiles") +#pragma comment(linker, "/EXPORT:DragFinish=shell32.DragFinish") +#pragma comment(linker, "/EXPORT:DragQueryFile=shell32.DragQueryFile") +#pragma comment(linker, "/EXPORT:DragQueryFileA=shell32.DragQueryFileA") +#pragma comment(linker, "/EXPORT:DragQueryFileAorW=shell32.DragQueryFileAorW") +#pragma comment(linker, "/EXPORT:DragQueryFileW=shell32.DragQueryFileW") +#pragma comment(linker, "/EXPORT:DragQueryPoint=shell32.DragQueryPoint") +#pragma comment(linker, "/EXPORT:DriveType=shell32.DriveType") +#pragma comment(linker, "/EXPORT:DuplicateIcon=shell32.DuplicateIcon") +#pragma comment(linker, "/EXPORT:ExtractAssociatedIconA=shell32.ExtractAssociatedIconA") +#pragma comment(linker, "/EXPORT:ExtractAssociatedIconExA=shell32.ExtractAssociatedIconExA") +#pragma comment(linker, "/EXPORT:ExtractAssociatedIconExW=shell32.ExtractAssociatedIconExW") +#pragma comment(linker, "/EXPORT:ExtractAssociatedIconW=shell32.ExtractAssociatedIconW") +#pragma comment(linker, "/EXPORT:ExtractIconA=shell32.ExtractIconA") +#pragma comment(linker, "/EXPORT:ExtractIconEx=shell32.ExtractIconEx") +#pragma comment(linker, "/EXPORT:ExtractIconExA=shell32.ExtractIconExA") +#pragma comment(linker, "/EXPORT:ExtractIconExW=shell32.ExtractIconExW") +#pragma comment(linker, "/EXPORT:ExtractIconW=shell32.ExtractIconW") +#pragma comment(linker, "/EXPORT:FindExecutableA=shell32.FindExecutableA") +#pragma comment(linker, "/EXPORT:FindExecutableW=shell32.FindExecutableW") +#pragma comment(linker, "/EXPORT:FreeIconList=shell32.FreeIconList") +#pragma comment(linker, "/EXPORT:GetCurrentProcessExplicitAppUserModelID=shell32.GetCurrentProcessExplicitAppUserModelID") +#pragma comment(linker, "/EXPORT:GetFileNameFromBrowse=shell32.GetFileNameFromBrowse") +#pragma comment(linker, "/EXPORT:ILAppendID=shell32.ILAppendID") +#pragma comment(linker, "/EXPORT:ILClone=shell32.ILClone") +#pragma comment(linker, "/EXPORT:ILCloneFirst=shell32.ILCloneFirst") +#pragma comment(linker, "/EXPORT:ILCombine=shell32.ILCombine") +#pragma comment(linker, "/EXPORT:ILCreateFromPath=shell32.ILCreateFromPath") +#pragma comment(linker, "/EXPORT:ILCreateFromPathA=shell32.ILCreateFromPathA") +#pragma comment(linker, "/EXPORT:ILCreateFromPathW=shell32.ILCreateFromPathW") +#pragma comment(linker, "/EXPORT:ILFindChild=shell32.ILFindChild") +#pragma comment(linker, "/EXPORT:ILFindLastID=shell32.ILFindLastID") +#pragma comment(linker, "/EXPORT:ILFree=shell32.ILFree") +#pragma comment(linker, "/EXPORT:ILGetNext=shell32.ILGetNext") +#pragma comment(linker, "/EXPORT:ILGetSize=shell32.ILGetSize") +#pragma comment(linker, "/EXPORT:ILIsEqual=shell32.ILIsEqual") +#pragma comment(linker, "/EXPORT:ILIsParent=shell32.ILIsParent") +#pragma comment(linker, "/EXPORT:ILLoadFromStreamEx=shell32.ILLoadFromStreamEx") +#pragma comment(linker, "/EXPORT:ILRemoveLastID=shell32.ILRemoveLastID") +#pragma comment(linker, "/EXPORT:ILSaveToStream=shell32.ILSaveToStream") +#pragma comment(linker, "/EXPORT:InitNetworkAddressControl=shell32.InitNetworkAddressControl") +#pragma comment(linker, "/EXPORT:InternalExtractIconListA=shell32.InternalExtractIconListA") +#pragma comment(linker, "/EXPORT:InternalExtractIconListW=shell32.InternalExtractIconListW") +#pragma comment(linker, "/EXPORT:IsLFNDrive=shell32.IsLFNDrive") +#pragma comment(linker, "/EXPORT:IsLFNDriveA=shell32.IsLFNDriveA") +#pragma comment(linker, "/EXPORT:IsLFNDriveW=shell32.IsLFNDriveW") +#pragma comment(linker, "/EXPORT:IsNetDrive=shell32.IsNetDrive") +#pragma comment(linker, "/EXPORT:IsUserAnAdmin=shell32.IsUserAnAdmin") +#pragma comment(linker, "/EXPORT:LaunchMSHelp_RunDLLW=shell32.LaunchMSHelp_RunDLLW") +#pragma comment(linker, "/EXPORT:OpenAs_RunDLL=shell32.OpenAs_RunDLL") +#pragma comment(linker, "/EXPORT:OpenAs_RunDLLA=shell32.OpenAs_RunDLLA") +#pragma comment(linker, "/EXPORT:OpenAs_RunDLLW=shell32.OpenAs_RunDLLW") +#pragma comment(linker, "/EXPORT:OpenRegStream=shell32.OpenRegStream") +#pragma comment(linker, "/EXPORT:Options_RunDLL=shell32.Options_RunDLL") +#pragma comment(linker, "/EXPORT:Options_RunDLLA=shell32.Options_RunDLLA") +#pragma comment(linker, "/EXPORT:Options_RunDLLW=shell32.Options_RunDLLW") +#pragma comment(linker, "/EXPORT:PathCleanupSpec=shell32.PathCleanupSpec") +#pragma comment(linker, "/EXPORT:PathGetShortPath=shell32.PathGetShortPath") +#pragma comment(linker, "/EXPORT:PathIsExe=shell32.PathIsExe") +#pragma comment(linker, "/EXPORT:PathIsSlowA=shell32.PathIsSlowA") +#pragma comment(linker, "/EXPORT:PathIsSlowW=shell32.PathIsSlowW") +#pragma comment(linker, "/EXPORT:PathMakeUniqueName=shell32.PathMakeUniqueName") +#pragma comment(linker, "/EXPORT:PathQualify=shell32.PathQualify") +#pragma comment(linker, "/EXPORT:PathResolve=shell32.PathResolve") +#pragma comment(linker, "/EXPORT:PathYetAnotherMakeUniqueName=shell32.PathYetAnotherMakeUniqueName") +#pragma comment(linker, "/EXPORT:PickIconDlg=shell32.PickIconDlg") +#pragma comment(linker, "/EXPORT:PifMgr_CloseProperties=shell32.PifMgr_CloseProperties") +#pragma comment(linker, "/EXPORT:PifMgr_GetProperties=shell32.PifMgr_GetProperties") +#pragma comment(linker, "/EXPORT:PifMgr_OpenProperties=shell32.PifMgr_OpenProperties") +#pragma comment(linker, "/EXPORT:PifMgr_SetProperties=shell32.PifMgr_SetProperties") +#pragma comment(linker, "/EXPORT:PrepareDiscForBurnRunDllW=shell32.PrepareDiscForBurnRunDllW") +#pragma comment(linker, "/EXPORT:PrintersGetCommand_RunDLL=shell32.PrintersGetCommand_RunDLL") +#pragma comment(linker, "/EXPORT:PrintersGetCommand_RunDLLA=shell32.PrintersGetCommand_RunDLLA") +#pragma comment(linker, "/EXPORT:PrintersGetCommand_RunDLLW=shell32.PrintersGetCommand_RunDLLW") +#pragma comment(linker, "/EXPORT:ReadCabinetState=shell32.ReadCabinetState") +#pragma comment(linker, "/EXPORT:RealDriveType=shell32.RealDriveType") +#pragma comment(linker, "/EXPORT:RealShellExecuteA=shell32.RealShellExecuteA") +#pragma comment(linker, "/EXPORT:RealShellExecuteExA=shell32.RealShellExecuteExA") +#pragma comment(linker, "/EXPORT:RealShellExecuteExW=shell32.RealShellExecuteExW") +#pragma comment(linker, "/EXPORT:RealShellExecuteW=shell32.RealShellExecuteW") +#pragma comment(linker, "/EXPORT:RegenerateUserEnvironment=shell32.RegenerateUserEnvironment") +#pragma comment(linker, "/EXPORT:RestartDialog=shell32.RestartDialog") +#pragma comment(linker, "/EXPORT:RestartDialogEx=shell32.RestartDialogEx") +#pragma comment(linker, "/EXPORT:RunAsNewUser_RunDLLW=shell32.RunAsNewUser_RunDLLW") +#pragma comment(linker, "/EXPORT:SHAddDefaultPropertiesByExt=shell32.SHAddDefaultPropertiesByExt") +#pragma comment(linker, "/EXPORT:SHAddFromPropSheetExtArray=shell32.SHAddFromPropSheetExtArray") +#pragma comment(linker, "/EXPORT:SHAddToRecentDocs=shell32.SHAddToRecentDocs") +#pragma comment(linker, "/EXPORT:SHAlloc=shell32.SHAlloc") +#pragma comment(linker, "/EXPORT:SHAppBarMessage=shell32.SHAppBarMessage") +#pragma comment(linker, "/EXPORT:SHAssocEnumHandlers=shell32.SHAssocEnumHandlers") +#pragma comment(linker, "/EXPORT:SHAssocEnumHandlersForProtocolByApplication=shell32.SHAssocEnumHandlersForProtocolByApplication") +#pragma comment(linker, "/EXPORT:SHBindToFolderIDListParent=shell32.SHBindToFolderIDListParent") +#pragma comment(linker, "/EXPORT:SHBindToFolderIDListParentEx=shell32.SHBindToFolderIDListParentEx") +#pragma comment(linker, "/EXPORT:SHBindToObject=shell32.SHBindToObject") +#pragma comment(linker, "/EXPORT:SHBindToParent=shell32.SHBindToParent") +#pragma comment(linker, "/EXPORT:SHBrowseForFolder=shell32.SHBrowseForFolder") +#pragma comment(linker, "/EXPORT:SHBrowseForFolderA=shell32.SHBrowseForFolderA") +#pragma comment(linker, "/EXPORT:SHBrowseForFolderW=shell32.SHBrowseForFolderW") +#pragma comment(linker, "/EXPORT:SHCLSIDFromString=shell32.SHCLSIDFromString") +#pragma comment(linker, "/EXPORT:SHChangeNotification_Lock=shell32.SHChangeNotification_Lock") +#pragma comment(linker, "/EXPORT:SHChangeNotification_Unlock=shell32.SHChangeNotification_Unlock") +#pragma comment(linker, "/EXPORT:SHChangeNotify=shell32.SHChangeNotify") +#pragma comment(linker, "/EXPORT:SHChangeNotifyDeregister=shell32.SHChangeNotifyDeregister") +#pragma comment(linker, "/EXPORT:SHChangeNotifyRegister=shell32.SHChangeNotifyRegister") +#pragma comment(linker, "/EXPORT:SHChangeNotifyRegisterThread=shell32.SHChangeNotifyRegisterThread") +#pragma comment(linker, "/EXPORT:SHChangeNotifySuspendResume=shell32.SHChangeNotifySuspendResume") +#pragma comment(linker, "/EXPORT:SHCloneSpecialIDList=shell32.SHCloneSpecialIDList") +#pragma comment(linker, "/EXPORT:SHCoCreateInstance=shell32.SHCoCreateInstance") +#pragma comment(linker, "/EXPORT:SHCreateAssociationRegistration=shell32.SHCreateAssociationRegistration") +#pragma comment(linker, "/EXPORT:SHCreateDataObject=shell32.SHCreateDataObject") +#pragma comment(linker, "/EXPORT:SHCreateDefaultContextMenu=shell32.SHCreateDefaultContextMenu") +#pragma comment(linker, "/EXPORT:SHCreateDefaultExtractIcon=shell32.SHCreateDefaultExtractIcon") +#pragma comment(linker, "/EXPORT:SHCreateDefaultPropertiesOp=shell32.SHCreateDefaultPropertiesOp") +#pragma comment(linker, "/EXPORT:SHCreateDirectory=shell32.SHCreateDirectory") +#pragma comment(linker, "/EXPORT:SHCreateDirectoryExA=shell32.SHCreateDirectoryExA") +#pragma comment(linker, "/EXPORT:SHCreateDirectoryExW=shell32.SHCreateDirectoryExW") +#pragma comment(linker, "/EXPORT:SHCreateFileExtractIconW=shell32.SHCreateFileExtractIconW") +#pragma comment(linker, "/EXPORT:SHCreateItemFromIDList=shell32.SHCreateItemFromIDList") +#pragma comment(linker, "/EXPORT:SHCreateItemFromParsingName=shell32.SHCreateItemFromParsingName") +#pragma comment(linker, "/EXPORT:SHCreateItemFromRelativeName=shell32.SHCreateItemFromRelativeName") +#pragma comment(linker, "/EXPORT:SHCreateItemInKnownFolder=shell32.SHCreateItemInKnownFolder") +#pragma comment(linker, "/EXPORT:SHCreateItemWithParent=shell32.SHCreateItemWithParent") +#pragma comment(linker, "/EXPORT:SHCreateLocalServerRunDll=shell32.SHCreateLocalServerRunDll") +#pragma comment(linker, "/EXPORT:SHCreateProcessAsUserW=shell32.SHCreateProcessAsUserW") +#pragma comment(linker, "/EXPORT:SHCreatePropSheetExtArray=shell32.SHCreatePropSheetExtArray") +#pragma comment(linker, "/EXPORT:SHCreateQueryCancelAutoPlayMoniker=shell32.SHCreateQueryCancelAutoPlayMoniker") +#pragma comment(linker, "/EXPORT:SHCreateShellFolderView=shell32.SHCreateShellFolderView") +#pragma comment(linker, "/EXPORT:SHCreateShellFolderViewEx=shell32.SHCreateShellFolderViewEx") +#pragma comment(linker, "/EXPORT:SHCreateShellItem=shell32.SHCreateShellItem") +#pragma comment(linker, "/EXPORT:SHCreateShellItemArray=shell32.SHCreateShellItemArray") +#pragma comment(linker, "/EXPORT:SHCreateShellItemArrayFromDataObject=shell32.SHCreateShellItemArrayFromDataObject") +#pragma comment(linker, "/EXPORT:SHCreateShellItemArrayFromIDLists=shell32.SHCreateShellItemArrayFromIDLists") +#pragma comment(linker, "/EXPORT:SHCreateShellItemArrayFromShellItem=shell32.SHCreateShellItemArrayFromShellItem") +#pragma comment(linker, "/EXPORT:SHCreateStdEnumFmtEtc=shell32.SHCreateStdEnumFmtEtc") +#pragma comment(linker, "/EXPORT:SHDefExtractIconA=shell32.SHDefExtractIconA") +#pragma comment(linker, "/EXPORT:SHDefExtractIconW=shell32.SHDefExtractIconW") +#pragma comment(linker, "/EXPORT:SHDestroyPropSheetExtArray=shell32.SHDestroyPropSheetExtArray") +#pragma comment(linker, "/EXPORT:SHDoDragDrop=shell32.SHDoDragDrop") +#pragma comment(linker, "/EXPORT:SHEmptyRecycleBinA=shell32.SHEmptyRecycleBinA") +#pragma comment(linker, "/EXPORT:SHEmptyRecycleBinW=shell32.SHEmptyRecycleBinW") +#pragma comment(linker, "/EXPORT:SHEnableServiceObject=shell32.SHEnableServiceObject") +#pragma comment(linker, "/EXPORT:SHEnumerateUnreadMailAccountsW=shell32.SHEnumerateUnreadMailAccountsW") +#pragma comment(linker, "/EXPORT:SHEvaluateSystemCommandTemplate=shell32.SHEvaluateSystemCommandTemplate") +#pragma comment(linker, "/EXPORT:SHExtractIconsW=shell32.SHExtractIconsW") +#pragma comment(linker, "/EXPORT:SHFileOperation=shell32.SHFileOperation") +#pragma comment(linker, "/EXPORT:SHFileOperationA=shell32.SHFileOperationA") +#pragma comment(linker, "/EXPORT:SHFileOperationW=shell32.SHFileOperationW") +#pragma comment(linker, "/EXPORT:SHFindFiles=shell32.SHFindFiles") +#pragma comment(linker, "/EXPORT:SHFind_InitMenuPopup=shell32.SHFind_InitMenuPopup") +#pragma comment(linker, "/EXPORT:SHFlushSFCache=shell32.SHFlushSFCache") +#pragma comment(linker, "/EXPORT:SHFormatDrive=shell32.SHFormatDrive") +#pragma comment(linker, "/EXPORT:SHFree=shell32.SHFree") +#pragma comment(linker, "/EXPORT:SHFreeNameMappings=shell32.SHFreeNameMappings") +#pragma comment(linker, "/EXPORT:SHGetAttributesFromDataObject=shell32.SHGetAttributesFromDataObject") +#pragma comment(linker, "/EXPORT:SHGetDataFromIDListA=shell32.SHGetDataFromIDListA") +#pragma comment(linker, "/EXPORT:SHGetDataFromIDListW=shell32.SHGetDataFromIDListW") +#pragma comment(linker, "/EXPORT:SHGetDesktopFolder=shell32.SHGetDesktopFolder") +#pragma comment(linker, "/EXPORT:SHGetDiskFreeSpaceA=shell32.SHGetDiskFreeSpaceA") +#pragma comment(linker, "/EXPORT:SHGetDiskFreeSpaceExA=shell32.SHGetDiskFreeSpaceExA") +#pragma comment(linker, "/EXPORT:SHGetDiskFreeSpaceExW=shell32.SHGetDiskFreeSpaceExW") +#pragma comment(linker, "/EXPORT:SHGetDriveMedia=shell32.SHGetDriveMedia") +#pragma comment(linker, "/EXPORT:SHGetFileInfo=shell32.SHGetFileInfo") +#pragma comment(linker, "/EXPORT:SHGetFileInfoA=shell32.SHGetFileInfoA") +#pragma comment(linker, "/EXPORT:SHGetFileInfoW=shell32.SHGetFileInfoW") +#pragma comment(linker, "/EXPORT:SHGetFolderLocation=shell32.SHGetFolderLocation") +#pragma comment(linker, "/EXPORT:SHGetFolderPathA=shell32.SHGetFolderPathA") +#pragma comment(linker, "/EXPORT:SHGetFolderPathAndSubDirA=shell32.SHGetFolderPathAndSubDirA") +#pragma comment(linker, "/EXPORT:SHGetFolderPathAndSubDirW=shell32.SHGetFolderPathAndSubDirW") +#pragma comment(linker, "/EXPORT:SHGetFolderPathEx=shell32.SHGetFolderPathEx") +#pragma comment(linker, "/EXPORT:SHGetFolderPathW=shell32.SHGetFolderPathW") +#pragma comment(linker, "/EXPORT:SHGetIDListFromObject=shell32.SHGetIDListFromObject") +#pragma comment(linker, "/EXPORT:SHGetIconOverlayIndexA=shell32.SHGetIconOverlayIndexA") +#pragma comment(linker, "/EXPORT:SHGetIconOverlayIndexW=shell32.SHGetIconOverlayIndexW") +#pragma comment(linker, "/EXPORT:SHGetImageList=shell32.SHGetImageList") +#pragma comment(linker, "/EXPORT:SHGetInstanceExplorer=shell32.SHGetInstanceExplorer") +#pragma comment(linker, "/EXPORT:SHGetItemFromDataObject=shell32.SHGetItemFromDataObject") +#pragma comment(linker, "/EXPORT:SHGetItemFromObject=shell32.SHGetItemFromObject") +#pragma comment(linker, "/EXPORT:SHGetKnownFolderIDList=shell32.SHGetKnownFolderIDList") +#pragma comment(linker, "/EXPORT:SHGetKnownFolderItem=shell32.SHGetKnownFolderItem") +#pragma comment(linker, "/EXPORT:SHGetKnownFolderPath=shell32.SHGetKnownFolderPath") +#pragma comment(linker, "/EXPORT:SHGetLocalizedName=shell32.SHGetLocalizedName") +#pragma comment(linker, "/EXPORT:SHGetMalloc=shell32.SHGetMalloc") +#pragma comment(linker, "/EXPORT:SHGetNameFromIDList=shell32.SHGetNameFromIDList") +#pragma comment(linker, "/EXPORT:SHGetNewLinkInfo=shell32.SHGetNewLinkInfo") +#pragma comment(linker, "/EXPORT:SHGetNewLinkInfoA=shell32.SHGetNewLinkInfoA") +#pragma comment(linker, "/EXPORT:SHGetNewLinkInfoW=shell32.SHGetNewLinkInfoW") +#pragma comment(linker, "/EXPORT:SHGetPathFromIDList=shell32.SHGetPathFromIDList") +#pragma comment(linker, "/EXPORT:SHGetPathFromIDListA=shell32.SHGetPathFromIDListA") +#pragma comment(linker, "/EXPORT:SHGetPathFromIDListEx=shell32.SHGetPathFromIDListEx") +#pragma comment(linker, "/EXPORT:SHGetPathFromIDListW=shell32.SHGetPathFromIDListW") +#pragma comment(linker, "/EXPORT:SHGetPropertyStoreForWindow=shell32.SHGetPropertyStoreForWindow") +#pragma comment(linker, "/EXPORT:SHGetPropertyStoreFromIDList=shell32.SHGetPropertyStoreFromIDList") +#pragma comment(linker, "/EXPORT:SHGetPropertyStoreFromParsingName=shell32.SHGetPropertyStoreFromParsingName") +#pragma comment(linker, "/EXPORT:SHGetRealIDL=shell32.SHGetRealIDL") +#pragma comment(linker, "/EXPORT:SHGetSetFolderCustomSettings=shell32.SHGetSetFolderCustomSettings") +#pragma comment(linker, "/EXPORT:SHGetSetSettings=shell32.SHGetSetSettings") +#pragma comment(linker, "/EXPORT:SHGetSettings=shell32.SHGetSettings") +#pragma comment(linker, "/EXPORT:SHGetSpecialFolderLocation=shell32.SHGetSpecialFolderLocation") +#pragma comment(linker, "/EXPORT:SHGetSpecialFolderPathA=shell32.SHGetSpecialFolderPathA") +#pragma comment(linker, "/EXPORT:SHGetSpecialFolderPathW=shell32.SHGetSpecialFolderPathW") +#pragma comment(linker, "/EXPORT:SHGetStockIconInfo=shell32.SHGetStockIconInfo") +#pragma comment(linker, "/EXPORT:SHGetTemporaryPropertyForItem=shell32.SHGetTemporaryPropertyForItem") +#pragma comment(linker, "/EXPORT:SHGetUnreadMailCountW=shell32.SHGetUnreadMailCountW") +#pragma comment(linker, "/EXPORT:SHHandleUpdateImage=shell32.SHHandleUpdateImage") +#pragma comment(linker, "/EXPORT:SHHelpShortcuts_RunDLL=shell32.SHHelpShortcuts_RunDLL") +#pragma comment(linker, "/EXPORT:SHHelpShortcuts_RunDLLA=shell32.SHHelpShortcuts_RunDLLA") +#pragma comment(linker, "/EXPORT:SHHelpShortcuts_RunDLLW=shell32.SHHelpShortcuts_RunDLLW") +#pragma comment(linker, "/EXPORT:SHILCreateFromPath=shell32.SHILCreateFromPath") +#pragma comment(linker, "/EXPORT:SHInvokePrinterCommandA=shell32.SHInvokePrinterCommandA") +#pragma comment(linker, "/EXPORT:SHInvokePrinterCommandW=shell32.SHInvokePrinterCommandW") +#pragma comment(linker, "/EXPORT:SHIsFileAvailableOffline=shell32.SHIsFileAvailableOffline") +#pragma comment(linker, "/EXPORT:SHLimitInputEdit=shell32.SHLimitInputEdit") +#pragma comment(linker, "/EXPORT:SHLoadInProc=shell32.SHLoadInProc") +#pragma comment(linker, "/EXPORT:SHLoadNonloadedIconOverlayIdentifiers=shell32.SHLoadNonloadedIconOverlayIdentifiers") +#pragma comment(linker, "/EXPORT:SHMapPIDLToSystemImageListIndex=shell32.SHMapPIDLToSystemImageListIndex") +#pragma comment(linker, "/EXPORT:SHMultiFileProperties=shell32.SHMultiFileProperties") +#pragma comment(linker, "/EXPORT:SHObjectProperties=shell32.SHObjectProperties") +#pragma comment(linker, "/EXPORT:SHOpenFolderAndSelectItems=shell32.SHOpenFolderAndSelectItems") +#pragma comment(linker, "/EXPORT:SHOpenPropSheetW=shell32.SHOpenPropSheetW") +#pragma comment(linker, "/EXPORT:SHOpenWithDialog=shell32.SHOpenWithDialog") +#pragma comment(linker, "/EXPORT:SHParseDisplayName=shell32.SHParseDisplayName") +#pragma comment(linker, "/EXPORT:SHPathPrepareForWriteA=shell32.SHPathPrepareForWriteA") +#pragma comment(linker, "/EXPORT:SHPathPrepareForWriteW=shell32.SHPathPrepareForWriteW") +#pragma comment(linker, "/EXPORT:SHPropStgCreate=shell32.SHPropStgCreate") +#pragma comment(linker, "/EXPORT:SHPropStgReadMultiple=shell32.SHPropStgReadMultiple") +#pragma comment(linker, "/EXPORT:SHPropStgWriteMultiple=shell32.SHPropStgWriteMultiple") +#pragma comment(linker, "/EXPORT:SHQueryRecycleBinA=shell32.SHQueryRecycleBinA") +#pragma comment(linker, "/EXPORT:SHQueryRecycleBinW=shell32.SHQueryRecycleBinW") +#pragma comment(linker, "/EXPORT:SHQueryUserNotificationState=shell32.SHQueryUserNotificationState") +#pragma comment(linker, "/EXPORT:SHRemoveLocalizedName=shell32.SHRemoveLocalizedName") +#pragma comment(linker, "/EXPORT:SHReplaceFromPropSheetExtArray=shell32.SHReplaceFromPropSheetExtArray") +#pragma comment(linker, "/EXPORT:SHResolveLibrary=shell32.SHResolveLibrary") +#pragma comment(linker, "/EXPORT:SHRestricted=shell32.SHRestricted") +#pragma comment(linker, "/EXPORT:SHSetDefaultProperties=shell32.SHSetDefaultProperties") +#pragma comment(linker, "/EXPORT:SHSetFolderPathA=shell32.SHSetFolderPathA") +#pragma comment(linker, "/EXPORT:SHSetFolderPathW=shell32.SHSetFolderPathW") +#pragma comment(linker, "/EXPORT:SHSetInstanceExplorer=shell32.SHSetInstanceExplorer") +#pragma comment(linker, "/EXPORT:SHSetKnownFolderPath=shell32.SHSetKnownFolderPath") +#pragma comment(linker, "/EXPORT:SHSetLocalizedName=shell32.SHSetLocalizedName") +#pragma comment(linker, "/EXPORT:SHSetTemporaryPropertyForItem=shell32.SHSetTemporaryPropertyForItem") +#pragma comment(linker, "/EXPORT:SHSetUnreadMailCountW=shell32.SHSetUnreadMailCountW") +#pragma comment(linker, "/EXPORT:SHShellFolderView_Message=shell32.SHShellFolderView_Message") +#pragma comment(linker, "/EXPORT:SHShowManageLibraryUI=shell32.SHShowManageLibraryUI") +#pragma comment(linker, "/EXPORT:SHSimpleIDListFromPath=shell32.SHSimpleIDListFromPath") +#pragma comment(linker, "/EXPORT:SHStartNetConnectionDialogW=shell32.SHStartNetConnectionDialogW") +#pragma comment(linker, "/EXPORT:SHTestTokenMembership=shell32.SHTestTokenMembership") +#pragma comment(linker, "/EXPORT:SHUpdateImageA=shell32.SHUpdateImageA") +#pragma comment(linker, "/EXPORT:SHUpdateImageW=shell32.SHUpdateImageW") +#pragma comment(linker, "/EXPORT:SHUpdateRecycleBinIcon=shell32.SHUpdateRecycleBinIcon") +#pragma comment(linker, "/EXPORT:SHValidateUNC=shell32.SHValidateUNC") +#pragma comment(linker, "/EXPORT:SetCurrentProcessExplicitAppUserModelID=shell32.SetCurrentProcessExplicitAppUserModelID") +#pragma comment(linker, "/EXPORT:SheChangeDirA=shell32.SheChangeDirA") +#pragma comment(linker, "/EXPORT:SheChangeDirExW=shell32.SheChangeDirExW") +#pragma comment(linker, "/EXPORT:SheGetDirA=shell32.SheGetDirA") +#pragma comment(linker, "/EXPORT:SheSetCurDrive=shell32.SheSetCurDrive") +#pragma comment(linker, "/EXPORT:ShellAboutA=shell32.ShellAboutA") +#pragma comment(linker, "/EXPORT:ShellAboutW=shell32.ShellAboutW") +#pragma comment(linker, "/EXPORT:ShellExec_RunDLL=shell32.ShellExec_RunDLL") +#pragma comment(linker, "/EXPORT:ShellExec_RunDLLA=shell32.ShellExec_RunDLLA") +#pragma comment(linker, "/EXPORT:ShellExec_RunDLLW=shell32.ShellExec_RunDLLW") +#pragma comment(linker, "/EXPORT:ShellExecuteA=shell32.ShellExecuteA") +#pragma comment(linker, "/EXPORT:ShellExecuteEx=shell32.ShellExecuteEx") +#pragma comment(linker, "/EXPORT:ShellExecuteExA=shell32.ShellExecuteExA") +#pragma comment(linker, "/EXPORT:ShellExecuteExW=shell32.ShellExecuteExW") +#pragma comment(linker, "/EXPORT:ShellExecuteW=shell32.ShellExecuteW") +#pragma comment(linker, "/EXPORT:ShellHookProc=shell32.ShellHookProc") +#pragma comment(linker, "/EXPORT:ShellMessageBoxA=shell32.ShellMessageBoxA") +#pragma comment(linker, "/EXPORT:ShellMessageBoxW=shell32.ShellMessageBoxW") +#pragma comment(linker, "/EXPORT:Shell_GetCachedImageIndex=shell32.Shell_GetCachedImageIndex") +#pragma comment(linker, "/EXPORT:Shell_GetCachedImageIndexA=shell32.Shell_GetCachedImageIndexA") +#pragma comment(linker, "/EXPORT:Shell_GetCachedImageIndexW=shell32.Shell_GetCachedImageIndexW") +#pragma comment(linker, "/EXPORT:Shell_GetImageLists=shell32.Shell_GetImageLists") +#pragma comment(linker, "/EXPORT:Shell_MergeMenus=shell32.Shell_MergeMenus") +#pragma comment(linker, "/EXPORT:Shell_NotifyIcon=shell32.Shell_NotifyIcon") +#pragma comment(linker, "/EXPORT:Shell_NotifyIconA=shell32.Shell_NotifyIconA") +#pragma comment(linker, "/EXPORT:Shell_NotifyIconGetRect=shell32.Shell_NotifyIconGetRect") +#pragma comment(linker, "/EXPORT:Shell_NotifyIconW=shell32.Shell_NotifyIconW") +#pragma comment(linker, "/EXPORT:SignalFileOpen=shell32.SignalFileOpen") +#pragma comment(linker, "/EXPORT:StgMakeUniqueName=shell32.StgMakeUniqueName") +#pragma comment(linker, "/EXPORT:StrChrA=shell32.StrChrA") +#pragma comment(linker, "/EXPORT:StrChrIA=shell32.StrChrIA") +#pragma comment(linker, "/EXPORT:StrChrIW=shell32.StrChrIW") +#pragma comment(linker, "/EXPORT:StrChrW=shell32.StrChrW") +#pragma comment(linker, "/EXPORT:StrCmpNA=shell32.StrCmpNA") +#pragma comment(linker, "/EXPORT:StrCmpNIA=shell32.StrCmpNIA") +#pragma comment(linker, "/EXPORT:StrCmpNIW=shell32.StrCmpNIW") +#pragma comment(linker, "/EXPORT:StrCmpNW=shell32.StrCmpNW") +#pragma comment(linker, "/EXPORT:StrNCmpA=shell32.StrNCmpA") +#pragma comment(linker, "/EXPORT:StrNCmpIA=shell32.StrNCmpIA") +#pragma comment(linker, "/EXPORT:StrNCmpIW=shell32.StrNCmpIW") +#pragma comment(linker, "/EXPORT:StrNCmpW=shell32.StrNCmpW") +#pragma comment(linker, "/EXPORT:StrRChrA=shell32.StrRChrA") +#pragma comment(linker, "/EXPORT:StrRChrIA=shell32.StrRChrIA") +#pragma comment(linker, "/EXPORT:StrRChrIW=shell32.StrRChrIW") +#pragma comment(linker, "/EXPORT:StrRChrW=shell32.StrRChrW") +#pragma comment(linker, "/EXPORT:StrRStrA=shell32.StrRStrA") +#pragma comment(linker, "/EXPORT:StrRStrIA=shell32.StrRStrIA") +#pragma comment(linker, "/EXPORT:StrRStrIW=shell32.StrRStrIW") +#pragma comment(linker, "/EXPORT:StrRStrW=shell32.StrRStrW") +#pragma comment(linker, "/EXPORT:StrStrA=shell32.StrStrA") +#pragma comment(linker, "/EXPORT:StrStrIA=shell32.StrStrIA") +#pragma comment(linker, "/EXPORT:StrStrIW=shell32.StrStrIW") +#pragma comment(linker, "/EXPORT:StrStrW=shell32.StrStrW") +#pragma comment(linker, "/EXPORT:WOWShellExecute=shell32.WOWShellExecute") +#pragma comment(linker, "/EXPORT:WaitForExplorerRestartW=shell32.WaitForExplorerRestartW") +#pragma comment(linker, "/EXPORT:Win32DeleteFile=shell32.Win32DeleteFile") +#pragma comment(linker, "/EXPORT:WriteCabinetState=shell32.WriteCabinetState") +#pragma comment(linker, "/EXPORT:__OrdinalFunction5=shell32.#5,@5,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction7=shell32.#7,@7,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction8=shell32.#8,@8,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction12=shell32.#12,@12,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction15=shell32.#15,@15,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction20=shell32.#20,@20,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction26=shell32.#26,@26,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction29=shell32.#29,@29,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction30=shell32.#30,@30,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction31=shell32.#31,@31,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction32=shell32.#32,@32,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction33=shell32.#33,@33,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction34=shell32.#34,@34,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction35=shell32.#35,@35,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction36=shell32.#36,@36,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction37=shell32.#37,@37,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction38=shell32.#38,@38,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction39=shell32.#39,@39,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction40=shell32.#40,@40,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction44=shell32.#44,@44,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction45=shell32.#45,@45,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction46=shell32.#46,@46,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction48=shell32.#48,@48,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction50=shell32.#50,@50,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction52=shell32.#52,@52,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction53=shell32.#53,@53,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction54=shell32.#54,@54,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction55=shell32.#55,@55,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction56=shell32.#56,@56,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction57=shell32.#57,@57,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction58=shell32.#58,@58,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction60=shell32.#60,@60,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction61=shell32.#61,@61,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction65=shell32.#65,@65,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction69=shell32.#69,@69,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction70=shell32.#70,@70,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction76=shell32.#76,@76,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction78=shell32.#78,@78,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction79=shell32.#79,@79,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction82=shell32.#82,@82,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction84=shell32.#84,@84,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction86=shell32.#86,@86,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction87=shell32.#87,@87,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction91=shell32.#91,@91,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction93=shell32.#93,@93,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction94=shell32.#94,@94,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction95=shell32.#95,@95,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction96=shell32.#96,@96,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction97=shell32.#97,@97,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction99=shell32.#99,@99,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction101=shell32.#101,@101,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction104=shell32.#104,@104,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction105=shell32.#105,@105,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction106=shell32.#106,@106,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction107=shell32.#107,@107,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction108=shell32.#108,@108,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction109=shell32.#109,@109,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction110=shell32.#110,@110,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction111=shell32.#111,@111,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction112=shell32.#112,@112,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction113=shell32.#113,@113,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction114=shell32.#114,@114,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction115=shell32.#115,@115,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction116=shell32.#116,@116,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction117=shell32.#117,@117,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction118=shell32.#118,@118,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction120=shell32.#120,@120,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction121=shell32.#121,@121,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction122=shell32.#122,@122,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction123=shell32.#123,@123,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction124=shell32.#124,@124,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction126=shell32.#126,@126,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction127=shell32.#127,@127,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction128=shell32.#128,@128,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction130=shell32.#130,@130,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction140=shell32.#140,@140,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction141=shell32.#141,@141,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction142=shell32.#142,@142,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction143=shell32.#143,@143,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction144=shell32.#144,@144,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction145=shell32.#145,@145,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction146=shell32.#146,@146,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction148=shell32.#148,@148,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction151=shell32.#151,@151,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction156=shell32.#156,@156,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction158=shell32.#158,@158,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction159=shell32.#159,@159,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction160=shell32.#160,@160,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction161=shell32.#161,@161,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction163=shell32.#163,@163,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction166=shell32.#166,@166,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction172=shell32.#172,@172,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction175=shell32.#175,@175,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction177=shell32.#177,@177,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction181=shell32.#181,@181,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction184=shell32.#184,@184,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction185=shell32.#185,@185,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction186=shell32.#186,@186,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction187=shell32.#187,@187,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction188=shell32.#188,@188,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction194=shell32.#194,@194,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction197=shell32.#197,@197,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction198=shell32.#198,@198,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction200=shell32.#200,@200,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction201=shell32.#201,@201,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction202=shell32.#202,@202,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction203=shell32.#203,@203,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction204=shell32.#204,@204,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction205=shell32.#205,@205,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction209=shell32.#209,@209,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction210=shell32.#210,@210,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction211=shell32.#211,@211,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction212=shell32.#212,@212,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction213=shell32.#213,@213,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction214=shell32.#214,@214,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction215=shell32.#215,@215,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction216=shell32.#216,@216,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction217=shell32.#217,@217,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction218=shell32.#218,@218,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction219=shell32.#219,@219,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction220=shell32.#220,@220,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction221=shell32.#221,@221,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction222=shell32.#222,@222,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction223=shell32.#223,@223,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction224=shell32.#224,@224,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction225=shell32.#225,@225,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction227=shell32.#227,@227,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction230=shell32.#230,@230,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction233=shell32.#233,@233,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction234=shell32.#234,@234,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction235=shell32.#235,@235,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction236=shell32.#236,@236,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction237=shell32.#237,@237,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction241=shell32.#241,@241,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction242=shell32.#242,@242,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction243=shell32.#243,@243,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction244=shell32.#244,@244,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction246=shell32.#246,@246,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction247=shell32.#247,@247,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction248=shell32.#248,@248,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction249=shell32.#249,@249,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction250=shell32.#250,@250,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction251=shell32.#251,@251,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction252=shell32.#252,@252,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction253=shell32.#253,@253,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction254=shell32.#254,@254,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction257=shell32.#257,@257,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction258=shell32.#258,@258,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction259=shell32.#259,@259,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction260=shell32.#260,@260,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction261=shell32.#261,@261,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction262=shell32.#262,@262,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction264=shell32.#264,@264,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction265=shell32.#265,@265,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction266=shell32.#266,@266,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction270=shell32.#270,@270,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction471=shell32.#471,@471,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction472=shell32.#472,@472,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction473=shell32.#473,@473,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction474=shell32.#474,@474,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction475=shell32.#475,@475,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction476=shell32.#476,@476,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction477=shell32.#477,@477,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction478=shell32.#478,@478,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction479=shell32.#479,@479,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction480=shell32.#480,@480,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction481=shell32.#481,@481,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction482=shell32.#482,@482,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction483=shell32.#483,@483,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction484=shell32.#484,@484,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction485=shell32.#485,@485,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction486=shell32.#486,@486,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction487=shell32.#487,@487,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction488=shell32.#488,@488,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction489=shell32.#489,@489,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction490=shell32.#490,@490,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction491=shell32.#491,@491,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction492=shell32.#492,@492,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction493=shell32.#493,@493,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction494=shell32.#494,@494,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction495=shell32.#495,@495,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction496=shell32.#496,@496,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction497=shell32.#497,@497,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction498=shell32.#498,@498,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction499=shell32.#499,@499,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction500=shell32.#500,@500,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction501=shell32.#501,@501,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction502=shell32.#502,@502,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction503=shell32.#503,@503,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction504=shell32.#504,@504,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction505=shell32.#505,@505,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction506=shell32.#506,@506,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction507=shell32.#507,@507,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction508=shell32.#508,@508,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction509=shell32.#509,@509,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction510=shell32.#510,@510,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction511=shell32.#511,@511,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction512=shell32.#512,@512,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction513=shell32.#513,@513,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction514=shell32.#514,@514,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction515=shell32.#515,@515,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction516=shell32.#516,@516,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction517=shell32.#517,@517,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction518=shell32.#518,@518,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction519=shell32.#519,@519,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction520=shell32.#520,@520,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction521=shell32.#521,@521,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction522=shell32.#522,@522,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction523=shell32.#523,@523,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction525=shell32.#525,@525,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction527=shell32.#527,@527,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction528=shell32.#528,@528,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction529=shell32.#529,@529,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction530=shell32.#530,@530,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction531=shell32.#531,@531,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction532=shell32.#532,@532,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction533=shell32.#533,@533,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction534=shell32.#534,@534,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction535=shell32.#535,@535,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction536=shell32.#536,@536,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction537=shell32.#537,@537,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction538=shell32.#538,@538,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction539=shell32.#539,@539,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction540=shell32.#540,@540,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction541=shell32.#541,@541,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction542=shell32.#542,@542,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction543=shell32.#543,@543,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction544=shell32.#544,@544,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction545=shell32.#545,@545,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction546=shell32.#546,@546,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction547=shell32.#547,@547,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction548=shell32.#548,@548,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction549=shell32.#549,@549,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction550=shell32.#550,@550,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction551=shell32.#551,@551,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction552=shell32.#552,@552,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction553=shell32.#553,@553,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction554=shell32.#554,@554,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction555=shell32.#555,@555,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction556=shell32.#556,@556,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction557=shell32.#557,@557,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction558=shell32.#558,@558,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction559=shell32.#559,@559,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction560=shell32.#560,@560,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction561=shell32.#561,@561,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction562=shell32.#562,@562,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction563=shell32.#563,@563,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction564=shell32.#564,@564,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction565=shell32.#565,@565,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction566=shell32.#566,@566,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction567=shell32.#567,@567,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction568=shell32.#568,@568,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction569=shell32.#569,@569,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction570=shell32.#570,@570,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction571=shell32.#571,@571,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction572=shell32.#572,@572,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction573=shell32.#573,@573,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction574=shell32.#574,@574,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction575=shell32.#575,@575,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction576=shell32.#576,@576,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction577=shell32.#577,@577,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction578=shell32.#578,@578,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction579=shell32.#579,@579,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction580=shell32.#580,@580,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction581=shell32.#581,@581,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction582=shell32.#582,@582,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction583=shell32.#583,@583,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction584=shell32.#584,@584,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction585=shell32.#585,@585,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction586=shell32.#586,@586,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction587=shell32.#587,@587,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction588=shell32.#588,@588,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction589=shell32.#589,@589,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction590=shell32.#590,@590,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction591=shell32.#591,@591,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction592=shell32.#592,@592,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction593=shell32.#593,@593,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction594=shell32.#594,@594,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction595=shell32.#595,@595,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction596=shell32.#596,@596,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction597=shell32.#597,@597,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction598=shell32.#598,@598,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction599=shell32.#599,@599,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction600=shell32.#600,@600,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction601=shell32.#601,@601,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction602=shell32.#602,@602,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction603=shell32.#603,@603,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction604=shell32.#604,@604,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction605=shell32.#605,@605,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction606=shell32.#606,@606,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction607=shell32.#607,@607,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction608=shell32.#608,@608,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction609=shell32.#609,@609,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction610=shell32.#610,@610,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction611=shell32.#611,@611,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction612=shell32.#612,@612,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction613=shell32.#613,@613,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction614=shell32.#614,@614,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction615=shell32.#615,@615,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction616=shell32.#616,@616,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction617=shell32.#617,@617,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction618=shell32.#618,@618,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction619=shell32.#619,@619,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction620=shell32.#620,@620,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction621=shell32.#621,@621,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction622=shell32.#622,@622,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction623=shell32.#623,@623,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction624=shell32.#624,@624,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction625=shell32.#625,@625,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction626=shell32.#626,@626,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction627=shell32.#627,@627,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction628=shell32.#628,@628,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction629=shell32.#629,@629,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction630=shell32.#630,@630,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction631=shell32.#631,@631,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction632=shell32.#632,@632,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction633=shell32.#633,@633,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction634=shell32.#634,@634,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction635=shell32.#635,@635,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction636=shell32.#636,@636,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction637=shell32.#637,@637,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction638=shell32.#638,@638,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction639=shell32.#639,@639,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction640=shell32.#640,@640,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction641=shell32.#641,@641,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction642=shell32.#642,@642,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction643=shell32.#643,@643,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction646=shell32.#646,@646,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction647=shell32.#647,@647,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction648=shell32.#648,@648,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction649=shell32.#649,@649,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction650=shell32.#650,@650,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction651=shell32.#651,@651,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction653=shell32.#653,@653,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction655=shell32.#655,@655,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction656=shell32.#656,@656,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction657=shell32.#657,@657,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction658=shell32.#658,@658,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction659=shell32.#659,@659,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction660=shell32.#660,@660,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction661=shell32.#661,@661,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction662=shell32.#662,@662,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction663=shell32.#663,@663,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction664=shell32.#664,@664,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction665=shell32.#665,@665,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction666=shell32.#666,@666,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction667=shell32.#667,@667,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction668=shell32.#668,@668,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction669=shell32.#669,@669,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction670=shell32.#670,@670,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction671=shell32.#671,@671,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction672=shell32.#672,@672,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction673=shell32.#673,@673,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction674=shell32.#674,@674,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction675=shell32.#675,@675,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction676=shell32.#676,@676,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction677=shell32.#677,@677,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction678=shell32.#678,@678,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction679=shell32.#679,@679,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction681=shell32.#681,@681,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction683=shell32.#683,@683,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction684=shell32.#684,@684,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction686=shell32.#686,@686,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction687=shell32.#687,@687,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction690=shell32.#690,@690,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction691=shell32.#691,@691,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction692=shell32.#692,@692,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction693=shell32.#693,@693,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction694=shell32.#694,@694,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction695=shell32.#695,@695,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction696=shell32.#696,@696,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction697=shell32.#697,@697,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction698=shell32.#698,@698,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction699=shell32.#699,@699,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction700=shell32.#700,@700,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction702=shell32.#702,@702,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction703=shell32.#703,@703,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction704=shell32.#704,@704,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction705=shell32.#705,@705,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction706=shell32.#706,@706,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction707=shell32.#707,@707,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction708=shell32.#708,@708,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction710=shell32.#710,@710,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction711=shell32.#711,@711,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction712=shell32.#712,@712,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction713=shell32.#713,@713,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction714=shell32.#714,@714,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction715=shell32.#715,@715,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction717=shell32.#717,@717,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction718=shell32.#718,@718,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction719=shell32.#719,@719,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction720=shell32.#720,@720,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction721=shell32.#721,@721,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction722=shell32.#722,@722,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction723=shell32.#723,@723,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction724=shell32.#724,@724,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction725=shell32.#725,@725,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction726=shell32.#726,@726,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction728=shell32.#728,@728,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction729=shell32.#729,@729,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction731=shell32.#731,@731,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction732=shell32.#732,@732,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction733=shell32.#733,@733,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction734=shell32.#734,@734,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction735=shell32.#735,@735,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction736=shell32.#736,@736,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction737=shell32.#737,@737,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction738=shell32.#738,@738,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction739=shell32.#739,@739,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction740=shell32.#740,@740,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction741=shell32.#741,@741,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction742=shell32.#742,@742,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction744=shell32.#744,@744,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction745=shell32.#745,@745,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction746=shell32.#746,@746,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction748=shell32.#748,@748,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction749=shell32.#749,@749,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction751=shell32.#751,@751,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction752=shell32.#752,@752,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction753=shell32.#753,@753,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction754=shell32.#754,@754,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction755=shell32.#755,@755,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction756=shell32.#756,@756,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction757=shell32.#757,@757,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction758=shell32.#758,@758,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction759=shell32.#759,@759,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction760=shell32.#760,@760,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction761=shell32.#761,@761,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction762=shell32.#762,@762,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction763=shell32.#763,@763,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction764=shell32.#764,@764,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction765=shell32.#765,@765,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction766=shell32.#766,@766,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction767=shell32.#767,@767,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction768=shell32.#768,@768,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction769=shell32.#769,@769,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction770=shell32.#770,@770,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction771=shell32.#771,@771,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction772=shell32.#772,@772,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction773=shell32.#773,@773,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction774=shell32.#774,@774,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction775=shell32.#775,@775,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction776=shell32.#776,@776,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction777=shell32.#777,@777,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction778=shell32.#778,@778,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction779=shell32.#779,@779,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction780=shell32.#780,@780,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction781=shell32.#781,@781,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction782=shell32.#782,@782,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction783=shell32.#783,@783,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction784=shell32.#784,@784,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction785=shell32.#785,@785,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction786=shell32.#786,@786,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction787=shell32.#787,@787,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction788=shell32.#788,@788,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction789=shell32.#789,@789,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction790=shell32.#790,@790,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction791=shell32.#791,@791,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction792=shell32.#792,@792,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction793=shell32.#793,@793,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction794=shell32.#794,@794,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction795=shell32.#795,@795,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction796=shell32.#796,@796,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction797=shell32.#797,@797,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction798=shell32.#798,@798,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction799=shell32.#799,@799,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction800=shell32.#800,@800,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction801=shell32.#801,@801,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction802=shell32.#802,@802,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction803=shell32.#803,@803,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction804=shell32.#804,@804,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction805=shell32.#805,@805,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction806=shell32.#806,@806,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction807=shell32.#807,@807,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction808=shell32.#808,@808,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction809=shell32.#809,@809,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction810=shell32.#810,@810,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction811=shell32.#811,@811,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction812=shell32.#812,@812,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction813=shell32.#813,@813,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction814=shell32.#814,@814,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction815=shell32.#815,@815,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction816=shell32.#816,@816,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction817=shell32.#817,@817,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction818=shell32.#818,@818,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction819=shell32.#819,@819,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction820=shell32.#820,@820,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction821=shell32.#821,@821,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction822=shell32.#822,@822,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction823=shell32.#823,@823,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction824=shell32.#824,@824,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction825=shell32.#825,@825,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction826=shell32.#826,@826,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction827=shell32.#827,@827,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction828=shell32.#828,@828,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction829=shell32.#829,@829,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction830=shell32.#830,@830,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction831=shell32.#831,@831,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction832=shell32.#832,@832,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction833=shell32.#833,@833,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction834=shell32.#834,@834,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction835=shell32.#835,@835,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction836=shell32.#836,@836,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction837=shell32.#837,@837,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction838=shell32.#838,@838,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction839=shell32.#839,@839,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction840=shell32.#840,@840,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction841=shell32.#841,@841,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction842=shell32.#842,@842,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction843=shell32.#843,@843,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction844=shell32.#844,@844,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction845=shell32.#845,@845,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction847=shell32.#847,@847,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction848=shell32.#848,@848,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction849=shell32.#849,@849,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction850=shell32.#850,@850,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction851=shell32.#851,@851,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction852=shell32.#852,@852,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction853=shell32.#853,@853,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction854=shell32.#854,@854,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction855=shell32.#855,@855,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction856=shell32.#856,@856,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction857=shell32.#857,@857,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction858=shell32.#858,@858,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction859=shell32.#859,@859,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction860=shell32.#860,@860,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction861=shell32.#861,@861,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction862=shell32.#862,@862,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction863=shell32.#863,@863,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction864=shell32.#864,@864,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction865=shell32.#865,@865,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction866=shell32.#866,@866,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction867=shell32.#867,@867,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction868=shell32.#868,@868,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction869=shell32.#869,@869,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction870=shell32.#870,@870,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction871=shell32.#871,@871,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction872=shell32.#872,@872,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction873=shell32.#873,@873,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction874=shell32.#874,@874,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction875=shell32.#875,@875,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction876=shell32.#876,@876,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction877=shell32.#877,@877,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction878=shell32.#878,@878,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction879=shell32.#879,@879,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction880=shell32.#880,@880,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction881=shell32.#881,@881,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction882=shell32.#882,@882,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction883=shell32.#883,@883,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction884=shell32.#884,@884,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction885=shell32.#885,@885,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction886=shell32.#886,@886,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction887=shell32.#887,@887,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction888=shell32.#888,@888,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction889=shell32.#889,@889,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction890=shell32.#890,@890,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction891=shell32.#891,@891,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction892=shell32.#892,@892,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction893=shell32.#893,@893,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction894=shell32.#894,@894,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction895=shell32.#895,@895,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction896=shell32.#896,@896,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction897=shell32.#897,@897,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction898=shell32.#898,@898,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction899=shell32.#899,@899,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction900=shell32.#900,@900,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction901=shell32.#901,@901,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction902=shell32.#902,@902,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction903=shell32.#903,@903,NONAME") + +// Generated by KexExprt from "C:\Windows\system32\shlwapi.dll" +#pragma comment(linker, "/EXPORT:AssocCreate=shlwapi.AssocCreate") +#pragma comment(linker, "/EXPORT:AssocGetPerceivedType=shlwapi.AssocGetPerceivedType") +#pragma comment(linker, "/EXPORT:AssocIsDangerous=shlwapi.AssocIsDangerous") +#pragma comment(linker, "/EXPORT:AssocQueryKeyA=shlwapi.AssocQueryKeyA") +#pragma comment(linker, "/EXPORT:AssocQueryKeyW=shlwapi.AssocQueryKeyW") +#pragma comment(linker, "/EXPORT:AssocQueryStringA=shlwapi.AssocQueryStringA") +#pragma comment(linker, "/EXPORT:AssocQueryStringByKeyA=shlwapi.AssocQueryStringByKeyA") +#pragma comment(linker, "/EXPORT:AssocQueryStringByKeyW=shlwapi.AssocQueryStringByKeyW") +#pragma comment(linker, "/EXPORT:AssocQueryStringW=shlwapi.AssocQueryStringW") +#pragma comment(linker, "/EXPORT:ChrCmpIA=shlwapi.ChrCmpIA") +#pragma comment(linker, "/EXPORT:ChrCmpIW=shlwapi.ChrCmpIW") +#pragma comment(linker, "/EXPORT:ColorAdjustLuma=shlwapi.ColorAdjustLuma") +#pragma comment(linker, "/EXPORT:ColorHLSToRGB=shlwapi.ColorHLSToRGB") +#pragma comment(linker, "/EXPORT:ColorRGBToHLS=shlwapi.ColorRGBToHLS") +#pragma comment(linker, "/EXPORT:ConnectToConnectionPoint=shlwapi.ConnectToConnectionPoint") +#pragma comment(linker, "/EXPORT:DelayLoadFailureHook=shlwapi.DelayLoadFailureHook") +#pragma comment(linker, "/EXPORT:DllGetVersion=shlwapi.DllGetVersion") +#pragma comment(linker, "/EXPORT:GetAcceptLanguagesA=shlwapi.GetAcceptLanguagesA") +#pragma comment(linker, "/EXPORT:GetAcceptLanguagesW=shlwapi.GetAcceptLanguagesW") +#pragma comment(linker, "/EXPORT:GetMenuPosFromID=shlwapi.GetMenuPosFromID") +#pragma comment(linker, "/EXPORT:HashData=shlwapi.HashData") +#pragma comment(linker, "/EXPORT:IStream_Copy=shlwapi.IStream_Copy") +#pragma comment(linker, "/EXPORT:IStream_Read=shlwapi.IStream_Read") +#pragma comment(linker, "/EXPORT:IStream_ReadPidl=shlwapi.IStream_ReadPidl") +#pragma comment(linker, "/EXPORT:IStream_ReadStr=shlwapi.IStream_ReadStr") +#pragma comment(linker, "/EXPORT:IStream_Reset=shlwapi.IStream_Reset") +#pragma comment(linker, "/EXPORT:IStream_Size=shlwapi.IStream_Size") +#pragma comment(linker, "/EXPORT:IStream_Write=shlwapi.IStream_Write") +#pragma comment(linker, "/EXPORT:IStream_WritePidl=shlwapi.IStream_WritePidl") +#pragma comment(linker, "/EXPORT:IStream_WriteStr=shlwapi.IStream_WriteStr") +#pragma comment(linker, "/EXPORT:IUnknown_AtomicRelease=shlwapi.IUnknown_AtomicRelease") +#pragma comment(linker, "/EXPORT:IUnknown_GetSite=shlwapi.IUnknown_GetSite") +#pragma comment(linker, "/EXPORT:IUnknown_GetWindow=shlwapi.IUnknown_GetWindow") +#pragma comment(linker, "/EXPORT:IUnknown_QueryService=shlwapi.IUnknown_QueryService") +#pragma comment(linker, "/EXPORT:IUnknown_Set=shlwapi.IUnknown_Set") +#pragma comment(linker, "/EXPORT:IUnknown_SetSite=shlwapi.IUnknown_SetSite") +#pragma comment(linker, "/EXPORT:IntlStrEqWorkerA=shlwapi.IntlStrEqWorkerA") +#pragma comment(linker, "/EXPORT:IntlStrEqWorkerW=shlwapi.IntlStrEqWorkerW") +#pragma comment(linker, "/EXPORT:IsCharSpaceA=shlwapi.IsCharSpaceA") +#pragma comment(linker, "/EXPORT:IsCharSpaceW=shlwapi.IsCharSpaceW") +#pragma comment(linker, "/EXPORT:IsInternetESCEnabled=shlwapi.IsInternetESCEnabled") +#pragma comment(linker, "/EXPORT:IsOS=shlwapi.IsOS") +#pragma comment(linker, "/EXPORT:MLFreeLibrary=shlwapi.MLFreeLibrary") +#pragma comment(linker, "/EXPORT:MLLoadLibraryA=shlwapi.MLLoadLibraryA") +#pragma comment(linker, "/EXPORT:MLLoadLibraryW=shlwapi.MLLoadLibraryW") +#pragma comment(linker, "/EXPORT:ParseURLA=shlwapi.ParseURLA") +#pragma comment(linker, "/EXPORT:ParseURLW=shlwapi.ParseURLW") +#pragma comment(linker, "/EXPORT:PathAddBackslashA=shlwapi.PathAddBackslashA") +#pragma comment(linker, "/EXPORT:PathAddBackslashW=shlwapi.PathAddBackslashW") +#pragma comment(linker, "/EXPORT:PathAddExtensionA=shlwapi.PathAddExtensionA") +#pragma comment(linker, "/EXPORT:PathAddExtensionW=shlwapi.PathAddExtensionW") +#pragma comment(linker, "/EXPORT:PathAppendA=shlwapi.PathAppendA") +#pragma comment(linker, "/EXPORT:PathAppendW=shlwapi.PathAppendW") +#pragma comment(linker, "/EXPORT:PathBuildRootA=shlwapi.PathBuildRootA") +#pragma comment(linker, "/EXPORT:PathBuildRootW=shlwapi.PathBuildRootW") +#pragma comment(linker, "/EXPORT:PathCanonicalizeA=shlwapi.PathCanonicalizeA") +#pragma comment(linker, "/EXPORT:PathCanonicalizeW=shlwapi.PathCanonicalizeW") +#pragma comment(linker, "/EXPORT:PathCombineA=shlwapi.PathCombineA") +#pragma comment(linker, "/EXPORT:PathCombineW=shlwapi.PathCombineW") +#pragma comment(linker, "/EXPORT:PathCommonPrefixA=shlwapi.PathCommonPrefixA") +#pragma comment(linker, "/EXPORT:PathCommonPrefixW=shlwapi.PathCommonPrefixW") +#pragma comment(linker, "/EXPORT:PathCompactPathA=shlwapi.PathCompactPathA") +#pragma comment(linker, "/EXPORT:PathCompactPathExA=shlwapi.PathCompactPathExA") +#pragma comment(linker, "/EXPORT:PathCompactPathExW=shlwapi.PathCompactPathExW") +#pragma comment(linker, "/EXPORT:PathCompactPathW=shlwapi.PathCompactPathW") +#pragma comment(linker, "/EXPORT:PathCreateFromUrlA=shlwapi.PathCreateFromUrlA") +#pragma comment(linker, "/EXPORT:PathCreateFromUrlAlloc=shlwapi.PathCreateFromUrlAlloc") +#pragma comment(linker, "/EXPORT:PathCreateFromUrlW=shlwapi.PathCreateFromUrlW") +#pragma comment(linker, "/EXPORT:PathFileExistsA=shlwapi.PathFileExistsA") +#pragma comment(linker, "/EXPORT:PathFileExistsW=shlwapi.PathFileExistsW") +#pragma comment(linker, "/EXPORT:PathFindExtensionA=shlwapi.PathFindExtensionA") +#pragma comment(linker, "/EXPORT:PathFindExtensionW=shlwapi.PathFindExtensionW") +#pragma comment(linker, "/EXPORT:PathFindFileNameA=shlwapi.PathFindFileNameA") +#pragma comment(linker, "/EXPORT:PathFindFileNameW=shlwapi.PathFindFileNameW") +#pragma comment(linker, "/EXPORT:PathFindNextComponentA=shlwapi.PathFindNextComponentA") +#pragma comment(linker, "/EXPORT:PathFindNextComponentW=shlwapi.PathFindNextComponentW") +#pragma comment(linker, "/EXPORT:PathFindOnPathA=shlwapi.PathFindOnPathA") +#pragma comment(linker, "/EXPORT:PathFindOnPathW=shlwapi.PathFindOnPathW") +#pragma comment(linker, "/EXPORT:PathFindSuffixArrayA=shlwapi.PathFindSuffixArrayA") +#pragma comment(linker, "/EXPORT:PathFindSuffixArrayW=shlwapi.PathFindSuffixArrayW") +#pragma comment(linker, "/EXPORT:PathGetArgsA=shlwapi.PathGetArgsA") +#pragma comment(linker, "/EXPORT:PathGetArgsW=shlwapi.PathGetArgsW") +#pragma comment(linker, "/EXPORT:PathGetCharTypeA=shlwapi.PathGetCharTypeA") +#pragma comment(linker, "/EXPORT:PathGetCharTypeW=shlwapi.PathGetCharTypeW") +#pragma comment(linker, "/EXPORT:PathGetDriveNumberA=shlwapi.PathGetDriveNumberA") +#pragma comment(linker, "/EXPORT:PathGetDriveNumberW=shlwapi.PathGetDriveNumberW") +#pragma comment(linker, "/EXPORT:PathIsContentTypeA=shlwapi.PathIsContentTypeA") +#pragma comment(linker, "/EXPORT:PathIsContentTypeW=shlwapi.PathIsContentTypeW") +#pragma comment(linker, "/EXPORT:PathIsDirectoryA=shlwapi.PathIsDirectoryA") +#pragma comment(linker, "/EXPORT:PathIsDirectoryEmptyA=shlwapi.PathIsDirectoryEmptyA") +#pragma comment(linker, "/EXPORT:PathIsDirectoryEmptyW=shlwapi.PathIsDirectoryEmptyW") +#pragma comment(linker, "/EXPORT:PathIsDirectoryW=shlwapi.PathIsDirectoryW") +#pragma comment(linker, "/EXPORT:PathIsFileSpecA=shlwapi.PathIsFileSpecA") +#pragma comment(linker, "/EXPORT:PathIsFileSpecW=shlwapi.PathIsFileSpecW") +#pragma comment(linker, "/EXPORT:PathIsLFNFileSpecA=shlwapi.PathIsLFNFileSpecA") +#pragma comment(linker, "/EXPORT:PathIsLFNFileSpecW=shlwapi.PathIsLFNFileSpecW") +#pragma comment(linker, "/EXPORT:PathIsNetworkPathA=shlwapi.PathIsNetworkPathA") +#pragma comment(linker, "/EXPORT:PathIsNetworkPathW=shlwapi.PathIsNetworkPathW") +#pragma comment(linker, "/EXPORT:PathIsPrefixA=shlwapi.PathIsPrefixA") +#pragma comment(linker, "/EXPORT:PathIsPrefixW=shlwapi.PathIsPrefixW") +#pragma comment(linker, "/EXPORT:PathIsRelativeA=shlwapi.PathIsRelativeA") +#pragma comment(linker, "/EXPORT:PathIsRelativeW=shlwapi.PathIsRelativeW") +#pragma comment(linker, "/EXPORT:PathIsRootA=shlwapi.PathIsRootA") +#pragma comment(linker, "/EXPORT:PathIsRootW=shlwapi.PathIsRootW") +#pragma comment(linker, "/EXPORT:PathIsSameRootA=shlwapi.PathIsSameRootA") +#pragma comment(linker, "/EXPORT:PathIsSameRootW=shlwapi.PathIsSameRootW") +#pragma comment(linker, "/EXPORT:PathIsSystemFolderA=shlwapi.PathIsSystemFolderA") +#pragma comment(linker, "/EXPORT:PathIsSystemFolderW=shlwapi.PathIsSystemFolderW") +#pragma comment(linker, "/EXPORT:PathIsUNCA=shlwapi.PathIsUNCA") +#pragma comment(linker, "/EXPORT:PathIsUNCServerA=shlwapi.PathIsUNCServerA") +#pragma comment(linker, "/EXPORT:PathIsUNCServerShareA=shlwapi.PathIsUNCServerShareA") +#pragma comment(linker, "/EXPORT:PathIsUNCServerShareW=shlwapi.PathIsUNCServerShareW") +#pragma comment(linker, "/EXPORT:PathIsUNCServerW=shlwapi.PathIsUNCServerW") +#pragma comment(linker, "/EXPORT:PathIsUNCW=shlwapi.PathIsUNCW") +#pragma comment(linker, "/EXPORT:PathIsURLA=shlwapi.PathIsURLA") +#pragma comment(linker, "/EXPORT:PathIsURLW=shlwapi.PathIsURLW") +#pragma comment(linker, "/EXPORT:PathMakePrettyA=shlwapi.PathMakePrettyA") +#pragma comment(linker, "/EXPORT:PathMakePrettyW=shlwapi.PathMakePrettyW") +#pragma comment(linker, "/EXPORT:PathMakeSystemFolderA=shlwapi.PathMakeSystemFolderA") +#pragma comment(linker, "/EXPORT:PathMakeSystemFolderW=shlwapi.PathMakeSystemFolderW") +#pragma comment(linker, "/EXPORT:PathMatchSpecA=shlwapi.PathMatchSpecA") +#pragma comment(linker, "/EXPORT:PathMatchSpecExA=shlwapi.PathMatchSpecExA") +#pragma comment(linker, "/EXPORT:PathMatchSpecExW=shlwapi.PathMatchSpecExW") +#pragma comment(linker, "/EXPORT:PathMatchSpecW=shlwapi.PathMatchSpecW") +#pragma comment(linker, "/EXPORT:PathParseIconLocationA=shlwapi.PathParseIconLocationA") +#pragma comment(linker, "/EXPORT:PathParseIconLocationW=shlwapi.PathParseIconLocationW") +#pragma comment(linker, "/EXPORT:PathQuoteSpacesA=shlwapi.PathQuoteSpacesA") +#pragma comment(linker, "/EXPORT:PathQuoteSpacesW=shlwapi.PathQuoteSpacesW") +#pragma comment(linker, "/EXPORT:PathRelativePathToA=shlwapi.PathRelativePathToA") +#pragma comment(linker, "/EXPORT:PathRelativePathToW=shlwapi.PathRelativePathToW") +#pragma comment(linker, "/EXPORT:PathRemoveArgsA=shlwapi.PathRemoveArgsA") +#pragma comment(linker, "/EXPORT:PathRemoveArgsW=shlwapi.PathRemoveArgsW") +#pragma comment(linker, "/EXPORT:PathRemoveBackslashA=shlwapi.PathRemoveBackslashA") +#pragma comment(linker, "/EXPORT:PathRemoveBackslashW=shlwapi.PathRemoveBackslashW") +#pragma comment(linker, "/EXPORT:PathRemoveBlanksA=shlwapi.PathRemoveBlanksA") +#pragma comment(linker, "/EXPORT:PathRemoveBlanksW=shlwapi.PathRemoveBlanksW") +#pragma comment(linker, "/EXPORT:PathRemoveExtensionA=shlwapi.PathRemoveExtensionA") +#pragma comment(linker, "/EXPORT:PathRemoveExtensionW=shlwapi.PathRemoveExtensionW") +#pragma comment(linker, "/EXPORT:PathRemoveFileSpecA=shlwapi.PathRemoveFileSpecA") +#pragma comment(linker, "/EXPORT:PathRemoveFileSpecW=shlwapi.PathRemoveFileSpecW") +#pragma comment(linker, "/EXPORT:PathRenameExtensionA=shlwapi.PathRenameExtensionA") +#pragma comment(linker, "/EXPORT:PathRenameExtensionW=shlwapi.PathRenameExtensionW") +#pragma comment(linker, "/EXPORT:PathSearchAndQualifyA=shlwapi.PathSearchAndQualifyA") +#pragma comment(linker, "/EXPORT:PathSearchAndQualifyW=shlwapi.PathSearchAndQualifyW") +#pragma comment(linker, "/EXPORT:PathSetDlgItemPathA=shlwapi.PathSetDlgItemPathA") +#pragma comment(linker, "/EXPORT:PathSetDlgItemPathW=shlwapi.PathSetDlgItemPathW") +#pragma comment(linker, "/EXPORT:PathSkipRootA=shlwapi.PathSkipRootA") +#pragma comment(linker, "/EXPORT:PathSkipRootW=shlwapi.PathSkipRootW") +#pragma comment(linker, "/EXPORT:PathStripPathA=shlwapi.PathStripPathA") +#pragma comment(linker, "/EXPORT:PathStripPathW=shlwapi.PathStripPathW") +#pragma comment(linker, "/EXPORT:PathStripToRootA=shlwapi.PathStripToRootA") +#pragma comment(linker, "/EXPORT:PathStripToRootW=shlwapi.PathStripToRootW") +#pragma comment(linker, "/EXPORT:PathUnExpandEnvStringsA=shlwapi.PathUnExpandEnvStringsA") +#pragma comment(linker, "/EXPORT:PathUnExpandEnvStringsW=shlwapi.PathUnExpandEnvStringsW") +#pragma comment(linker, "/EXPORT:PathUndecorateA=shlwapi.PathUndecorateA") +#pragma comment(linker, "/EXPORT:PathUndecorateW=shlwapi.PathUndecorateW") +#pragma comment(linker, "/EXPORT:PathUnmakeSystemFolderA=shlwapi.PathUnmakeSystemFolderA") +#pragma comment(linker, "/EXPORT:PathUnmakeSystemFolderW=shlwapi.PathUnmakeSystemFolderW") +#pragma comment(linker, "/EXPORT:PathUnquoteSpacesA=shlwapi.PathUnquoteSpacesA") +#pragma comment(linker, "/EXPORT:PathUnquoteSpacesW=shlwapi.PathUnquoteSpacesW") +#pragma comment(linker, "/EXPORT:QISearch=shlwapi.QISearch") +#pragma comment(linker, "/EXPORT:SHAllocShared=shlwapi.SHAllocShared") +#pragma comment(linker, "/EXPORT:SHAnsiToAnsi=shlwapi.SHAnsiToAnsi") +#pragma comment(linker, "/EXPORT:SHAnsiToUnicode=shlwapi.SHAnsiToUnicode") +#pragma comment(linker, "/EXPORT:SHAutoComplete=shlwapi.SHAutoComplete") +#pragma comment(linker, "/EXPORT:SHCopyKeyA=shlwapi.SHCopyKeyA") +#pragma comment(linker, "/EXPORT:SHCopyKeyW=shlwapi.SHCopyKeyW") +#pragma comment(linker, "/EXPORT:SHCreateMemStream=shlwapi.SHCreateMemStream") +#pragma comment(linker, "/EXPORT:SHCreateShellPalette=shlwapi.SHCreateShellPalette") +#pragma comment(linker, "/EXPORT:SHCreateStreamOnFileA=shlwapi.SHCreateStreamOnFileA") +#pragma comment(linker, "/EXPORT:SHCreateStreamOnFileEx=shlwapi.SHCreateStreamOnFileEx") +#pragma comment(linker, "/EXPORT:SHCreateStreamOnFileW=shlwapi.SHCreateStreamOnFileW") +#pragma comment(linker, "/EXPORT:SHCreateStreamWrapper=shlwapi.SHCreateStreamWrapper") +#pragma comment(linker, "/EXPORT:SHCreateThread=shlwapi.SHCreateThread") +#pragma comment(linker, "/EXPORT:SHCreateThreadRef=shlwapi.SHCreateThreadRef") +#pragma comment(linker, "/EXPORT:SHCreateThreadWithHandle=shlwapi.SHCreateThreadWithHandle") +#pragma comment(linker, "/EXPORT:SHDeleteEmptyKeyA=shlwapi.SHDeleteEmptyKeyA") +#pragma comment(linker, "/EXPORT:SHDeleteEmptyKeyW=shlwapi.SHDeleteEmptyKeyW") +#pragma comment(linker, "/EXPORT:SHDeleteKeyA=shlwapi.SHDeleteKeyA") +#pragma comment(linker, "/EXPORT:SHDeleteKeyW=shlwapi.SHDeleteKeyW") +#pragma comment(linker, "/EXPORT:SHDeleteOrphanKeyA=shlwapi.SHDeleteOrphanKeyA") +#pragma comment(linker, "/EXPORT:SHDeleteOrphanKeyW=shlwapi.SHDeleteOrphanKeyW") +#pragma comment(linker, "/EXPORT:SHDeleteValueA=shlwapi.SHDeleteValueA") +#pragma comment(linker, "/EXPORT:SHDeleteValueW=shlwapi.SHDeleteValueW") +#pragma comment(linker, "/EXPORT:SHEnumKeyExA=shlwapi.SHEnumKeyExA") +#pragma comment(linker, "/EXPORT:SHEnumKeyExW=shlwapi.SHEnumKeyExW") +#pragma comment(linker, "/EXPORT:SHEnumValueA=shlwapi.SHEnumValueA") +#pragma comment(linker, "/EXPORT:SHEnumValueW=shlwapi.SHEnumValueW") +#pragma comment(linker, "/EXPORT:SHFormatDateTimeA=shlwapi.SHFormatDateTimeA") +#pragma comment(linker, "/EXPORT:SHFormatDateTimeW=shlwapi.SHFormatDateTimeW") +#pragma comment(linker, "/EXPORT:SHFreeShared=shlwapi.SHFreeShared") +#pragma comment(linker, "/EXPORT:SHGetInverseCMAP=shlwapi.SHGetInverseCMAP") +#pragma comment(linker, "/EXPORT:SHGetThreadRef=shlwapi.SHGetThreadRef") +#pragma comment(linker, "/EXPORT:SHGetValueA=shlwapi.SHGetValueA") +#pragma comment(linker, "/EXPORT:SHGetValueW=shlwapi.SHGetValueW") +#pragma comment(linker, "/EXPORT:SHGetViewStatePropertyBag=shlwapi.SHGetViewStatePropertyBag") +#pragma comment(linker, "/EXPORT:SHIsChildOrSelf=shlwapi.SHIsChildOrSelf") +#pragma comment(linker, "/EXPORT:SHIsLowMemoryMachine=shlwapi.SHIsLowMemoryMachine") +#pragma comment(linker, "/EXPORT:SHLoadIndirectString=shlwapi.SHLoadIndirectString") +#pragma comment(linker, "/EXPORT:SHLockShared=shlwapi.SHLockShared") +#pragma comment(linker, "/EXPORT:SHMessageBoxCheckA=shlwapi.SHMessageBoxCheckA") +#pragma comment(linker, "/EXPORT:SHMessageBoxCheckW=shlwapi.SHMessageBoxCheckW") +#pragma comment(linker, "/EXPORT:SHOpenRegStream2A=shlwapi.SHOpenRegStream2A") +#pragma comment(linker, "/EXPORT:SHOpenRegStream2W=shlwapi.SHOpenRegStream2W") +#pragma comment(linker, "/EXPORT:SHOpenRegStreamA=shlwapi.SHOpenRegStreamA") +#pragma comment(linker, "/EXPORT:SHOpenRegStreamW=shlwapi.SHOpenRegStreamW") +#pragma comment(linker, "/EXPORT:SHPropertyBag_ReadStrAlloc=shlwapi.SHPropertyBag_ReadStrAlloc") +#pragma comment(linker, "/EXPORT:SHPropertyBag_WriteBSTR=shlwapi.SHPropertyBag_WriteBSTR") +#pragma comment(linker, "/EXPORT:SHQueryInfoKeyA=shlwapi.SHQueryInfoKeyA") +#pragma comment(linker, "/EXPORT:SHQueryInfoKeyW=shlwapi.SHQueryInfoKeyW") +#pragma comment(linker, "/EXPORT:SHQueryValueExA=shlwapi.SHQueryValueExA") +#pragma comment(linker, "/EXPORT:SHQueryValueExW=shlwapi.SHQueryValueExW") +#pragma comment(linker, "/EXPORT:SHRegCloseUSKey=shlwapi.SHRegCloseUSKey") +#pragma comment(linker, "/EXPORT:SHRegCreateUSKeyA=shlwapi.SHRegCreateUSKeyA") +#pragma comment(linker, "/EXPORT:SHRegCreateUSKeyW=shlwapi.SHRegCreateUSKeyW") +#pragma comment(linker, "/EXPORT:SHRegDeleteEmptyUSKeyA=shlwapi.SHRegDeleteEmptyUSKeyA") +#pragma comment(linker, "/EXPORT:SHRegDeleteEmptyUSKeyW=shlwapi.SHRegDeleteEmptyUSKeyW") +#pragma comment(linker, "/EXPORT:SHRegDeleteUSValueA=shlwapi.SHRegDeleteUSValueA") +#pragma comment(linker, "/EXPORT:SHRegDeleteUSValueW=shlwapi.SHRegDeleteUSValueW") +#pragma comment(linker, "/EXPORT:SHRegDuplicateHKey=shlwapi.SHRegDuplicateHKey") +#pragma comment(linker, "/EXPORT:SHRegEnumUSKeyA=shlwapi.SHRegEnumUSKeyA") +#pragma comment(linker, "/EXPORT:SHRegEnumUSKeyW=shlwapi.SHRegEnumUSKeyW") +#pragma comment(linker, "/EXPORT:SHRegEnumUSValueA=shlwapi.SHRegEnumUSValueA") +#pragma comment(linker, "/EXPORT:SHRegEnumUSValueW=shlwapi.SHRegEnumUSValueW") +#pragma comment(linker, "/EXPORT:SHRegGetBoolUSValueA=shlwapi.SHRegGetBoolUSValueA") +#pragma comment(linker, "/EXPORT:SHRegGetBoolUSValueW=shlwapi.SHRegGetBoolUSValueW") +#pragma comment(linker, "/EXPORT:SHRegGetIntW=shlwapi.SHRegGetIntW") +#pragma comment(linker, "/EXPORT:SHRegGetPathA=shlwapi.SHRegGetPathA") +#pragma comment(linker, "/EXPORT:SHRegGetPathW=shlwapi.SHRegGetPathW") +#pragma comment(linker, "/EXPORT:SHRegGetUSValueA=shlwapi.SHRegGetUSValueA") +#pragma comment(linker, "/EXPORT:SHRegGetUSValueW=shlwapi.SHRegGetUSValueW") +#pragma comment(linker, "/EXPORT:SHRegGetValueA=shlwapi.SHRegGetValueA") +#pragma comment(linker, "/EXPORT:SHRegGetValueW=shlwapi.SHRegGetValueW") +#pragma comment(linker, "/EXPORT:SHRegOpenUSKeyA=shlwapi.SHRegOpenUSKeyA") +#pragma comment(linker, "/EXPORT:SHRegOpenUSKeyW=shlwapi.SHRegOpenUSKeyW") +#pragma comment(linker, "/EXPORT:SHRegQueryInfoUSKeyA=shlwapi.SHRegQueryInfoUSKeyA") +#pragma comment(linker, "/EXPORT:SHRegQueryInfoUSKeyW=shlwapi.SHRegQueryInfoUSKeyW") +#pragma comment(linker, "/EXPORT:SHRegQueryUSValueA=shlwapi.SHRegQueryUSValueA") +#pragma comment(linker, "/EXPORT:SHRegQueryUSValueW=shlwapi.SHRegQueryUSValueW") +#pragma comment(linker, "/EXPORT:SHRegSetPathA=shlwapi.SHRegSetPathA") +#pragma comment(linker, "/EXPORT:SHRegSetPathW=shlwapi.SHRegSetPathW") +#pragma comment(linker, "/EXPORT:SHRegSetUSValueA=shlwapi.SHRegSetUSValueA") +#pragma comment(linker, "/EXPORT:SHRegSetUSValueW=shlwapi.SHRegSetUSValueW") +#pragma comment(linker, "/EXPORT:SHRegWriteUSValueA=shlwapi.SHRegWriteUSValueA") +#pragma comment(linker, "/EXPORT:SHRegWriteUSValueW=shlwapi.SHRegWriteUSValueW") +#pragma comment(linker, "/EXPORT:SHRegisterValidateTemplate=shlwapi.SHRegisterValidateTemplate") +#pragma comment(linker, "/EXPORT:SHReleaseThreadRef=shlwapi.SHReleaseThreadRef") +#pragma comment(linker, "/EXPORT:SHRunIndirectRegClientCommand=shlwapi.SHRunIndirectRegClientCommand") +#pragma comment(linker, "/EXPORT:SHSendMessageBroadcastA=shlwapi.SHSendMessageBroadcastA") +#pragma comment(linker, "/EXPORT:SHSendMessageBroadcastW=shlwapi.SHSendMessageBroadcastW") +#pragma comment(linker, "/EXPORT:SHSetThreadRef=shlwapi.SHSetThreadRef") +#pragma comment(linker, "/EXPORT:SHSetValueA=shlwapi.SHSetValueA") +#pragma comment(linker, "/EXPORT:SHSetValueW=shlwapi.SHSetValueW") +#pragma comment(linker, "/EXPORT:SHSkipJunction=shlwapi.SHSkipJunction") +#pragma comment(linker, "/EXPORT:SHStrDupA=shlwapi.SHStrDupA") +#pragma comment(linker, "/EXPORT:SHStrDupW=shlwapi.SHStrDupW") +#pragma comment(linker, "/EXPORT:SHStripMneumonicA=shlwapi.SHStripMneumonicA") +#pragma comment(linker, "/EXPORT:SHStripMneumonicW=shlwapi.SHStripMneumonicW") +#pragma comment(linker, "/EXPORT:SHUnicodeToAnsi=shlwapi.SHUnicodeToAnsi") +#pragma comment(linker, "/EXPORT:SHUnicodeToUnicode=shlwapi.SHUnicodeToUnicode") +#pragma comment(linker, "/EXPORT:SHUnlockShared=shlwapi.SHUnlockShared") +#pragma comment(linker, "/EXPORT:ShellMessageBoxA=shlwapi.ShellMessageBoxA") +#pragma comment(linker, "/EXPORT:ShellMessageBoxW=shlwapi.ShellMessageBoxW") +#pragma comment(linker, "/EXPORT:StrCSpnA=shlwapi.StrCSpnA") +#pragma comment(linker, "/EXPORT:StrCSpnIA=shlwapi.StrCSpnIA") +#pragma comment(linker, "/EXPORT:StrCSpnIW=shlwapi.StrCSpnIW") +#pragma comment(linker, "/EXPORT:StrCSpnW=shlwapi.StrCSpnW") +#pragma comment(linker, "/EXPORT:StrCatBuffA=shlwapi.StrCatBuffA") +#pragma comment(linker, "/EXPORT:StrCatBuffW=shlwapi.StrCatBuffW") +#pragma comment(linker, "/EXPORT:StrCatChainW=shlwapi.StrCatChainW") +#pragma comment(linker, "/EXPORT:StrCatW=shlwapi.StrCatW") +#pragma comment(linker, "/EXPORT:StrChrA=shlwapi.StrChrA") +#pragma comment(linker, "/EXPORT:StrChrIA=shlwapi.StrChrIA") +#pragma comment(linker, "/EXPORT:StrChrIW=shlwapi.StrChrIW") +#pragma comment(linker, "/EXPORT:StrChrNIW=shlwapi.StrChrNIW") +#pragma comment(linker, "/EXPORT:StrChrNW=shlwapi.StrChrNW") +#pragma comment(linker, "/EXPORT:StrChrW=shlwapi.StrChrW") +#pragma comment(linker, "/EXPORT:StrCmpCA=shlwapi.StrCmpCA") +#pragma comment(linker, "/EXPORT:StrCmpCW=shlwapi.StrCmpCW") +#pragma comment(linker, "/EXPORT:StrCmpICA=shlwapi.StrCmpICA") +#pragma comment(linker, "/EXPORT:StrCmpICW=shlwapi.StrCmpICW") +#pragma comment(linker, "/EXPORT:StrCmpIW=shlwapi.StrCmpIW") +#pragma comment(linker, "/EXPORT:StrCmpLogicalW=shlwapi.StrCmpLogicalW") +#pragma comment(linker, "/EXPORT:StrCmpNA=shlwapi.StrCmpNA") +#pragma comment(linker, "/EXPORT:StrCmpNCA=shlwapi.StrCmpNCA") +#pragma comment(linker, "/EXPORT:StrCmpNCW=shlwapi.StrCmpNCW") +#pragma comment(linker, "/EXPORT:StrCmpNIA=shlwapi.StrCmpNIA") +#pragma comment(linker, "/EXPORT:StrCmpNICA=shlwapi.StrCmpNICA") +#pragma comment(linker, "/EXPORT:StrCmpNICW=shlwapi.StrCmpNICW") +#pragma comment(linker, "/EXPORT:StrCmpNIW=shlwapi.StrCmpNIW") +#pragma comment(linker, "/EXPORT:StrCmpNW=shlwapi.StrCmpNW") +#pragma comment(linker, "/EXPORT:StrCmpW=shlwapi.StrCmpW") +#pragma comment(linker, "/EXPORT:StrCpyNW=shlwapi.StrCpyNW") +#pragma comment(linker, "/EXPORT:StrCpyW=shlwapi.StrCpyW") +#pragma comment(linker, "/EXPORT:StrDupA=shlwapi.StrDupA") +#pragma comment(linker, "/EXPORT:StrDupW=shlwapi.StrDupW") +#pragma comment(linker, "/EXPORT:StrFormatByteSize64A=shlwapi.StrFormatByteSize64A") +#pragma comment(linker, "/EXPORT:StrFormatByteSizeA=shlwapi.StrFormatByteSizeA") +#pragma comment(linker, "/EXPORT:StrFormatByteSizeEx=shlwapi.StrFormatByteSizeEx") +#pragma comment(linker, "/EXPORT:StrFormatByteSizeW=shlwapi.StrFormatByteSizeW") +#pragma comment(linker, "/EXPORT:StrFormatKBSizeA=shlwapi.StrFormatKBSizeA") +#pragma comment(linker, "/EXPORT:StrFormatKBSizeW=shlwapi.StrFormatKBSizeW") +#pragma comment(linker, "/EXPORT:StrFromTimeIntervalA=shlwapi.StrFromTimeIntervalA") +#pragma comment(linker, "/EXPORT:StrFromTimeIntervalW=shlwapi.StrFromTimeIntervalW") +#pragma comment(linker, "/EXPORT:StrIsIntlEqualA=shlwapi.StrIsIntlEqualA") +#pragma comment(linker, "/EXPORT:StrIsIntlEqualW=shlwapi.StrIsIntlEqualW") +#pragma comment(linker, "/EXPORT:StrNCatA=shlwapi.StrNCatA") +#pragma comment(linker, "/EXPORT:StrNCatW=shlwapi.StrNCatW") +#pragma comment(linker, "/EXPORT:StrPBrkA=shlwapi.StrPBrkA") +#pragma comment(linker, "/EXPORT:StrPBrkW=shlwapi.StrPBrkW") +#pragma comment(linker, "/EXPORT:StrRChrA=shlwapi.StrRChrA") +#pragma comment(linker, "/EXPORT:StrRChrIA=shlwapi.StrRChrIA") +#pragma comment(linker, "/EXPORT:StrRChrIW=shlwapi.StrRChrIW") +#pragma comment(linker, "/EXPORT:StrRChrW=shlwapi.StrRChrW") +#pragma comment(linker, "/EXPORT:StrRStrIA=shlwapi.StrRStrIA") +#pragma comment(linker, "/EXPORT:StrRStrIW=shlwapi.StrRStrIW") +#pragma comment(linker, "/EXPORT:StrRetToBSTR=shlwapi.StrRetToBSTR") +#pragma comment(linker, "/EXPORT:StrRetToBufA=shlwapi.StrRetToBufA") +#pragma comment(linker, "/EXPORT:StrRetToBufW=shlwapi.StrRetToBufW") +#pragma comment(linker, "/EXPORT:StrRetToStrA=shlwapi.StrRetToStrA") +#pragma comment(linker, "/EXPORT:StrRetToStrW=shlwapi.StrRetToStrW") +#pragma comment(linker, "/EXPORT:StrSpnA=shlwapi.StrSpnA") +#pragma comment(linker, "/EXPORT:StrSpnW=shlwapi.StrSpnW") +#pragma comment(linker, "/EXPORT:StrStrA=shlwapi.StrStrA") +#pragma comment(linker, "/EXPORT:StrStrIA=shlwapi.StrStrIA") +#pragma comment(linker, "/EXPORT:StrStrIW=shlwapi.StrStrIW") +#pragma comment(linker, "/EXPORT:StrStrNIW=shlwapi.StrStrNIW") +#pragma comment(linker, "/EXPORT:StrStrNW=shlwapi.StrStrNW") +#pragma comment(linker, "/EXPORT:StrStrW=shlwapi.StrStrW") +#pragma comment(linker, "/EXPORT:StrToInt64ExA=shlwapi.StrToInt64ExA") +#pragma comment(linker, "/EXPORT:StrToInt64ExW=shlwapi.StrToInt64ExW") +#pragma comment(linker, "/EXPORT:StrToIntA=shlwapi.StrToIntA") +#pragma comment(linker, "/EXPORT:StrToIntExA=shlwapi.StrToIntExA") +#pragma comment(linker, "/EXPORT:StrToIntExW=shlwapi.StrToIntExW") +#pragma comment(linker, "/EXPORT:StrToIntW=shlwapi.StrToIntW") +#pragma comment(linker, "/EXPORT:StrTrimA=shlwapi.StrTrimA") +#pragma comment(linker, "/EXPORT:StrTrimW=shlwapi.StrTrimW") +#pragma comment(linker, "/EXPORT:UrlApplySchemeA=shlwapi.UrlApplySchemeA") +#pragma comment(linker, "/EXPORT:UrlApplySchemeW=shlwapi.UrlApplySchemeW") +#pragma comment(linker, "/EXPORT:UrlCanonicalizeA=shlwapi.UrlCanonicalizeA") +#pragma comment(linker, "/EXPORT:UrlCanonicalizeW=shlwapi.UrlCanonicalizeW") +#pragma comment(linker, "/EXPORT:UrlCombineA=shlwapi.UrlCombineA") +#pragma comment(linker, "/EXPORT:UrlCombineW=shlwapi.UrlCombineW") +#pragma comment(linker, "/EXPORT:UrlCompareA=shlwapi.UrlCompareA") +#pragma comment(linker, "/EXPORT:UrlCompareW=shlwapi.UrlCompareW") +#pragma comment(linker, "/EXPORT:UrlCreateFromPathA=shlwapi.UrlCreateFromPathA") +#pragma comment(linker, "/EXPORT:UrlCreateFromPathW=shlwapi.UrlCreateFromPathW") +#pragma comment(linker, "/EXPORT:UrlEscapeA=shlwapi.UrlEscapeA") +#pragma comment(linker, "/EXPORT:UrlEscapeW=shlwapi.UrlEscapeW") +#pragma comment(linker, "/EXPORT:UrlFixupW=shlwapi.UrlFixupW") +#pragma comment(linker, "/EXPORT:UrlGetLocationA=shlwapi.UrlGetLocationA") +#pragma comment(linker, "/EXPORT:UrlGetLocationW=shlwapi.UrlGetLocationW") +#pragma comment(linker, "/EXPORT:UrlGetPartA=shlwapi.UrlGetPartA") +#pragma comment(linker, "/EXPORT:UrlGetPartW=shlwapi.UrlGetPartW") +#pragma comment(linker, "/EXPORT:UrlHashA=shlwapi.UrlHashA") +#pragma comment(linker, "/EXPORT:UrlHashW=shlwapi.UrlHashW") +#pragma comment(linker, "/EXPORT:UrlIsA=shlwapi.UrlIsA") +#pragma comment(linker, "/EXPORT:UrlIsNoHistoryA=shlwapi.UrlIsNoHistoryA") +#pragma comment(linker, "/EXPORT:UrlIsNoHistoryW=shlwapi.UrlIsNoHistoryW") +#pragma comment(linker, "/EXPORT:UrlIsOpaqueA=shlwapi.UrlIsOpaqueA") +#pragma comment(linker, "/EXPORT:UrlIsOpaqueW=shlwapi.UrlIsOpaqueW") +#pragma comment(linker, "/EXPORT:UrlIsW=shlwapi.UrlIsW") +#pragma comment(linker, "/EXPORT:UrlUnescapeA=shlwapi.UrlUnescapeA") +#pragma comment(linker, "/EXPORT:UrlUnescapeW=shlwapi.UrlUnescapeW") +#pragma comment(linker, "/EXPORT:WhichPlatform=shlwapi.WhichPlatform") +#pragma comment(linker, "/EXPORT:wnsprintfA=shlwapi.wnsprintfA") +#pragma comment(linker, "/EXPORT:wnsprintfW=shlwapi.wnsprintfW") +#pragma comment(linker, "/EXPORT:wvnsprintfA=shlwapi.wvnsprintfA") +#pragma comment(linker, "/EXPORT:wvnsprintfW=shlwapi.wvnsprintfW") + +#pragma comment(linker, "/EXPORT:SHExpandEnvironmentStringsA=shlwapi.#459,@459") +#pragma comment(linker, "/EXPORT:SHExpandEnvironmentStringsW=shlwapi.#460,@460") + +#else + +// Generated by KexExprt from "C:\Windows\syswow64\user32.dll" +#pragma comment(linker, "/EXPORT:ActivateKeyboardLayout=user32.ActivateKeyboardLayout") +#pragma comment(linker, "/EXPORT:AddClipboardFormatListener=user32.AddClipboardFormatListener") +#pragma comment(linker, "/EXPORT:AdjustWindowRect=user32.AdjustWindowRect") +#pragma comment(linker, "/EXPORT:AdjustWindowRectEx=user32.AdjustWindowRectEx") +#pragma comment(linker, "/EXPORT:AlignRects=user32.AlignRects") +#pragma comment(linker, "/EXPORT:AllowForegroundActivation=user32.AllowForegroundActivation") +#pragma comment(linker, "/EXPORT:AllowSetForegroundWindow=user32.AllowSetForegroundWindow") +#pragma comment(linker, "/EXPORT:AnimateWindow=user32.AnimateWindow") +#pragma comment(linker, "/EXPORT:AnyPopup=user32.AnyPopup") +#pragma comment(linker, "/EXPORT:AppendMenuA=user32.AppendMenuA") +#pragma comment(linker, "/EXPORT:AppendMenuW=user32.AppendMenuW") +#pragma comment(linker, "/EXPORT:ArrangeIconicWindows=user32.ArrangeIconicWindows") +#pragma comment(linker, "/EXPORT:AttachThreadInput=user32.AttachThreadInput") +#pragma comment(linker, "/EXPORT:BeginDeferWindowPos=user32.BeginDeferWindowPos") +#pragma comment(linker, "/EXPORT:BeginPaint=user32.BeginPaint") +#pragma comment(linker, "/EXPORT:BlockInput=user32.BlockInput") +#pragma comment(linker, "/EXPORT:BringWindowToTop=user32.BringWindowToTop") +#pragma comment(linker, "/EXPORT:BroadcastSystemMessage=user32.BroadcastSystemMessage") +#pragma comment(linker, "/EXPORT:BroadcastSystemMessageA=user32.BroadcastSystemMessageA") +#pragma comment(linker, "/EXPORT:BroadcastSystemMessageExA=user32.BroadcastSystemMessageExA") +#pragma comment(linker, "/EXPORT:BroadcastSystemMessageExW=user32.BroadcastSystemMessageExW") +#pragma comment(linker, "/EXPORT:BroadcastSystemMessageW=user32.BroadcastSystemMessageW") +#pragma comment(linker, "/EXPORT:BuildReasonArray=user32.BuildReasonArray") +#pragma comment(linker, "/EXPORT:CalcMenuBar=user32.CalcMenuBar") +#pragma comment(linker, "/EXPORT:CalculatePopupWindowPosition=user32.CalculatePopupWindowPosition") +#pragma comment(linker, "/EXPORT:CallMsgFilter=user32.CallMsgFilter") +#pragma comment(linker, "/EXPORT:CallMsgFilterA=user32.CallMsgFilterA") +#pragma comment(linker, "/EXPORT:CallMsgFilterW=user32.CallMsgFilterW") +#pragma comment(linker, "/EXPORT:CallNextHookEx=user32.CallNextHookEx") +#pragma comment(linker, "/EXPORT:CallWindowProcA=user32.CallWindowProcA") +#pragma comment(linker, "/EXPORT:CallWindowProcW=user32.CallWindowProcW") +#pragma comment(linker, "/EXPORT:CancelShutdown=user32.CancelShutdown") +#pragma comment(linker, "/EXPORT:CascadeChildWindows=user32.CascadeChildWindows") +#pragma comment(linker, "/EXPORT:CascadeWindows=user32.CascadeWindows") +#pragma comment(linker, "/EXPORT:ChangeClipboardChain=user32.ChangeClipboardChain") +#pragma comment(linker, "/EXPORT:ChangeDisplaySettingsA=user32.ChangeDisplaySettingsA") +#pragma comment(linker, "/EXPORT:ChangeDisplaySettingsExA=user32.ChangeDisplaySettingsExA") +#pragma comment(linker, "/EXPORT:ChangeDisplaySettingsExW=user32.ChangeDisplaySettingsExW") +#pragma comment(linker, "/EXPORT:ChangeDisplaySettingsW=user32.ChangeDisplaySettingsW") +#pragma comment(linker, "/EXPORT:ChangeMenuA=user32.ChangeMenuA") +#pragma comment(linker, "/EXPORT:ChangeMenuW=user32.ChangeMenuW") +#pragma comment(linker, "/EXPORT:ChangeWindowMessageFilter=user32.ChangeWindowMessageFilter") +#pragma comment(linker, "/EXPORT:ChangeWindowMessageFilterEx=user32.ChangeWindowMessageFilterEx") +#pragma comment(linker, "/EXPORT:CharLowerA=user32.CharLowerA") +#pragma comment(linker, "/EXPORT:CharLowerBuffA=user32.CharLowerBuffA") +#pragma comment(linker, "/EXPORT:CharLowerBuffW=user32.CharLowerBuffW") +#pragma comment(linker, "/EXPORT:CharLowerW=user32.CharLowerW") +#pragma comment(linker, "/EXPORT:CharNextA=user32.CharNextA") +#pragma comment(linker, "/EXPORT:CharNextExA=user32.CharNextExA") +#pragma comment(linker, "/EXPORT:CharNextW=user32.CharNextW") +#pragma comment(linker, "/EXPORT:CharPrevA=user32.CharPrevA") +#pragma comment(linker, "/EXPORT:CharPrevExA=user32.CharPrevExA") +#pragma comment(linker, "/EXPORT:CharPrevW=user32.CharPrevW") +#pragma comment(linker, "/EXPORT:CharToOemA=user32.CharToOemA") +#pragma comment(linker, "/EXPORT:CharToOemBuffA=user32.CharToOemBuffA") +#pragma comment(linker, "/EXPORT:CharToOemBuffW=user32.CharToOemBuffW") +#pragma comment(linker, "/EXPORT:CharToOemW=user32.CharToOemW") +#pragma comment(linker, "/EXPORT:CharUpperA=user32.CharUpperA") +#pragma comment(linker, "/EXPORT:CharUpperBuffA=user32.CharUpperBuffA") +#pragma comment(linker, "/EXPORT:CharUpperBuffW=user32.CharUpperBuffW") +#pragma comment(linker, "/EXPORT:CharUpperW=user32.CharUpperW") +#pragma comment(linker, "/EXPORT:CheckDesktopByThreadId=user32.CheckDesktopByThreadId") +#pragma comment(linker, "/EXPORT:CheckDlgButton=user32.CheckDlgButton") +#pragma comment(linker, "/EXPORT:CheckMenuItem=user32.CheckMenuItem") +#pragma comment(linker, "/EXPORT:CheckMenuRadioItem=user32.CheckMenuRadioItem") +#pragma comment(linker, "/EXPORT:CheckRadioButton=user32.CheckRadioButton") +#pragma comment(linker, "/EXPORT:CheckWindowThreadDesktop=user32.CheckWindowThreadDesktop") +#pragma comment(linker, "/EXPORT:ChildWindowFromPoint=user32.ChildWindowFromPoint") +#pragma comment(linker, "/EXPORT:ChildWindowFromPointEx=user32.ChildWindowFromPointEx") +#pragma comment(linker, "/EXPORT:CliImmSetHotKey=user32.CliImmSetHotKey") +#pragma comment(linker, "/EXPORT:ClientThreadSetup=user32.ClientThreadSetup") +#pragma comment(linker, "/EXPORT:ClientToScreen=user32.ClientToScreen") +#pragma comment(linker, "/EXPORT:ClipCursor=user32.ClipCursor") +#pragma comment(linker, "/EXPORT:CloseClipboard=user32.CloseClipboard") +#pragma comment(linker, "/EXPORT:CloseDesktop=user32.CloseDesktop") +#pragma comment(linker, "/EXPORT:CloseGestureInfoHandle=user32.CloseGestureInfoHandle") +#pragma comment(linker, "/EXPORT:CloseTouchInputHandle=user32.CloseTouchInputHandle") +#pragma comment(linker, "/EXPORT:CloseWindow=user32.CloseWindow") +#pragma comment(linker, "/EXPORT:CloseWindowStation=user32.CloseWindowStation") +#pragma comment(linker, "/EXPORT:ConsoleControl=user32.ConsoleControl") +#pragma comment(linker, "/EXPORT:ControlMagnification=user32.ControlMagnification") +#pragma comment(linker, "/EXPORT:CopyAcceleratorTableA=user32.CopyAcceleratorTableA") +#pragma comment(linker, "/EXPORT:CopyAcceleratorTableW=user32.CopyAcceleratorTableW") +#pragma comment(linker, "/EXPORT:CopyIcon=user32.CopyIcon") +#pragma comment(linker, "/EXPORT:CopyImage=user32.CopyImage") +#pragma comment(linker, "/EXPORT:CopyRect=user32.CopyRect") +#pragma comment(linker, "/EXPORT:CountClipboardFormats=user32.CountClipboardFormats") +#pragma comment(linker, "/EXPORT:CreateAcceleratorTableA=user32.CreateAcceleratorTableA") +#pragma comment(linker, "/EXPORT:CreateAcceleratorTableW=user32.CreateAcceleratorTableW") +#pragma comment(linker, "/EXPORT:CreateCaret=user32.CreateCaret") +#pragma comment(linker, "/EXPORT:CreateCursor=user32.CreateCursor") +#pragma comment(linker, "/EXPORT:CreateDesktopA=user32.CreateDesktopA") +#pragma comment(linker, "/EXPORT:CreateDesktopExA=user32.CreateDesktopExA") +#pragma comment(linker, "/EXPORT:CreateDesktopExW=user32.CreateDesktopExW") +#pragma comment(linker, "/EXPORT:CreateDesktopW=user32.CreateDesktopW") +#pragma comment(linker, "/EXPORT:CreateDialogIndirectParamA=user32.CreateDialogIndirectParamA") +#pragma comment(linker, "/EXPORT:CreateDialogIndirectParamAorW=user32.CreateDialogIndirectParamAorW") +#pragma comment(linker, "/EXPORT:CreateDialogIndirectParamW=user32.CreateDialogIndirectParamW") +#pragma comment(linker, "/EXPORT:CreateDialogParamA=user32.CreateDialogParamA") +#pragma comment(linker, "/EXPORT:CreateDialogParamW=user32.CreateDialogParamW") +#pragma comment(linker, "/EXPORT:CreateIcon=user32.CreateIcon") +#pragma comment(linker, "/EXPORT:CreateIconFromResource=user32.CreateIconFromResource") +#pragma comment(linker, "/EXPORT:CreateIconFromResourceEx=user32.CreateIconFromResourceEx") +#pragma comment(linker, "/EXPORT:CreateIconIndirect=user32.CreateIconIndirect") +#pragma comment(linker, "/EXPORT:CreateMDIWindowA=user32.CreateMDIWindowA") +#pragma comment(linker, "/EXPORT:CreateMDIWindowW=user32.CreateMDIWindowW") +#pragma comment(linker, "/EXPORT:CreateMenu=user32.CreateMenu") +#pragma comment(linker, "/EXPORT:CreatePopupMenu=user32.CreatePopupMenu") +#pragma comment(linker, "/EXPORT:CreateSystemThreads=user32.CreateSystemThreads") +#pragma comment(linker, "/EXPORT:CreateWindowExA=user32.CreateWindowExA") +#pragma comment(linker, "/EXPORT:CreateWindowExW=user32.CreateWindowExW") +#pragma comment(linker, "/EXPORT:CreateWindowStationA=user32.CreateWindowStationA") +#pragma comment(linker, "/EXPORT:CreateWindowStationW=user32.CreateWindowStationW") +#pragma comment(linker, "/EXPORT:CsrBroadcastSystemMessageExW=user32.CsrBroadcastSystemMessageExW") +#pragma comment(linker, "/EXPORT:CtxInitUser32=user32.CtxInitUser32") +#pragma comment(linker, "/EXPORT:DdeAbandonTransaction=user32.DdeAbandonTransaction") +#pragma comment(linker, "/EXPORT:DdeAccessData=user32.DdeAccessData") +#pragma comment(linker, "/EXPORT:DdeAddData=user32.DdeAddData") +#pragma comment(linker, "/EXPORT:DdeClientTransaction=user32.DdeClientTransaction") +#pragma comment(linker, "/EXPORT:DdeCmpStringHandles=user32.DdeCmpStringHandles") +#pragma comment(linker, "/EXPORT:DdeConnect=user32.DdeConnect") +#pragma comment(linker, "/EXPORT:DdeConnectList=user32.DdeConnectList") +#pragma comment(linker, "/EXPORT:DdeCreateDataHandle=user32.DdeCreateDataHandle") +#pragma comment(linker, "/EXPORT:DdeCreateStringHandleA=user32.DdeCreateStringHandleA") +#pragma comment(linker, "/EXPORT:DdeCreateStringHandleW=user32.DdeCreateStringHandleW") +#pragma comment(linker, "/EXPORT:DdeDisconnect=user32.DdeDisconnect") +#pragma comment(linker, "/EXPORT:DdeDisconnectList=user32.DdeDisconnectList") +#pragma comment(linker, "/EXPORT:DdeEnableCallback=user32.DdeEnableCallback") +#pragma comment(linker, "/EXPORT:DdeFreeDataHandle=user32.DdeFreeDataHandle") +#pragma comment(linker, "/EXPORT:DdeFreeStringHandle=user32.DdeFreeStringHandle") +#pragma comment(linker, "/EXPORT:DdeGetData=user32.DdeGetData") +#pragma comment(linker, "/EXPORT:DdeGetLastError=user32.DdeGetLastError") +#pragma comment(linker, "/EXPORT:DdeGetQualityOfService=user32.DdeGetQualityOfService") +#pragma comment(linker, "/EXPORT:DdeImpersonateClient=user32.DdeImpersonateClient") +#pragma comment(linker, "/EXPORT:DdeInitializeA=user32.DdeInitializeA") +#pragma comment(linker, "/EXPORT:DdeInitializeW=user32.DdeInitializeW") +#pragma comment(linker, "/EXPORT:DdeKeepStringHandle=user32.DdeKeepStringHandle") +#pragma comment(linker, "/EXPORT:DdeNameService=user32.DdeNameService") +#pragma comment(linker, "/EXPORT:DdePostAdvise=user32.DdePostAdvise") +#pragma comment(linker, "/EXPORT:DdeQueryConvInfo=user32.DdeQueryConvInfo") +#pragma comment(linker, "/EXPORT:DdeQueryNextServer=user32.DdeQueryNextServer") +#pragma comment(linker, "/EXPORT:DdeQueryStringA=user32.DdeQueryStringA") +#pragma comment(linker, "/EXPORT:DdeQueryStringW=user32.DdeQueryStringW") +#pragma comment(linker, "/EXPORT:DdeReconnect=user32.DdeReconnect") +#pragma comment(linker, "/EXPORT:DdeSetQualityOfService=user32.DdeSetQualityOfService") +#pragma comment(linker, "/EXPORT:DdeSetUserHandle=user32.DdeSetUserHandle") +#pragma comment(linker, "/EXPORT:DdeUnaccessData=user32.DdeUnaccessData") +#pragma comment(linker, "/EXPORT:DdeUninitialize=user32.DdeUninitialize") +#pragma comment(linker, "/EXPORT:DefDlgProcA=user32.DefDlgProcA") +#pragma comment(linker, "/EXPORT:DefDlgProcW=user32.DefDlgProcW") +#pragma comment(linker, "/EXPORT:DefFrameProcA=user32.DefFrameProcA") +#pragma comment(linker, "/EXPORT:DefFrameProcW=user32.DefFrameProcW") +#pragma comment(linker, "/EXPORT:DefMDIChildProcA=user32.DefMDIChildProcA") +#pragma comment(linker, "/EXPORT:DefMDIChildProcW=user32.DefMDIChildProcW") +#pragma comment(linker, "/EXPORT:DefRawInputProc=user32.DefRawInputProc") +#pragma comment(linker, "/EXPORT:DefWindowProcA=user32.DefWindowProcA") +#pragma comment(linker, "/EXPORT:DefWindowProcW=user32.DefWindowProcW") +#pragma comment(linker, "/EXPORT:DeferWindowPos=user32.DeferWindowPos") +#pragma comment(linker, "/EXPORT:DeleteMenu=user32.DeleteMenu") +#pragma comment(linker, "/EXPORT:DeregisterShellHookWindow=user32.DeregisterShellHookWindow") +#pragma comment(linker, "/EXPORT:DestroyAcceleratorTable=user32.DestroyAcceleratorTable") +#pragma comment(linker, "/EXPORT:DestroyCaret=user32.DestroyCaret") +#pragma comment(linker, "/EXPORT:DestroyCursor=user32.DestroyCursor") +#pragma comment(linker, "/EXPORT:DestroyIcon=user32.DestroyIcon") +#pragma comment(linker, "/EXPORT:DestroyMenu=user32.DestroyMenu") +#pragma comment(linker, "/EXPORT:DestroyReasons=user32.DestroyReasons") +#pragma comment(linker, "/EXPORT:DestroyWindow=user32.DestroyWindow") +#pragma comment(linker, "/EXPORT:DeviceEventWorker=user32.DeviceEventWorker") +#pragma comment(linker, "/EXPORT:DialogBoxIndirectParamA=user32.DialogBoxIndirectParamA") +#pragma comment(linker, "/EXPORT:DialogBoxIndirectParamAorW=user32.DialogBoxIndirectParamAorW") +#pragma comment(linker, "/EXPORT:DialogBoxIndirectParamW=user32.DialogBoxIndirectParamW") +#pragma comment(linker, "/EXPORT:DialogBoxParamA=user32.DialogBoxParamA") +#pragma comment(linker, "/EXPORT:DialogBoxParamW=user32.DialogBoxParamW") +#pragma comment(linker, "/EXPORT:DisableProcessWindowsGhosting=user32.DisableProcessWindowsGhosting") +#pragma comment(linker, "/EXPORT:DispatchMessageA=user32.DispatchMessageA") +#pragma comment(linker, "/EXPORT:DispatchMessageW=user32.DispatchMessageW") +#pragma comment(linker, "/EXPORT:DisplayConfigGetDeviceInfo=user32.DisplayConfigGetDeviceInfo") +#pragma comment(linker, "/EXPORT:DisplayConfigSetDeviceInfo=user32.DisplayConfigSetDeviceInfo") +#pragma comment(linker, "/EXPORT:DisplayExitWindowsWarnings=user32.DisplayExitWindowsWarnings") +#pragma comment(linker, "/EXPORT:DlgDirListA=user32.DlgDirListA") +#pragma comment(linker, "/EXPORT:DlgDirListComboBoxA=user32.DlgDirListComboBoxA") +#pragma comment(linker, "/EXPORT:DlgDirListComboBoxW=user32.DlgDirListComboBoxW") +#pragma comment(linker, "/EXPORT:DlgDirListW=user32.DlgDirListW") +#pragma comment(linker, "/EXPORT:DlgDirSelectComboBoxExA=user32.DlgDirSelectComboBoxExA") +#pragma comment(linker, "/EXPORT:DlgDirSelectComboBoxExW=user32.DlgDirSelectComboBoxExW") +#pragma comment(linker, "/EXPORT:DlgDirSelectExA=user32.DlgDirSelectExA") +#pragma comment(linker, "/EXPORT:DlgDirSelectExW=user32.DlgDirSelectExW") +#pragma comment(linker, "/EXPORT:DoSoundConnect=user32.DoSoundConnect") +#pragma comment(linker, "/EXPORT:DoSoundDisconnect=user32.DoSoundDisconnect") +#pragma comment(linker, "/EXPORT:DragDetect=user32.DragDetect") +#pragma comment(linker, "/EXPORT:DragObject=user32.DragObject") +#pragma comment(linker, "/EXPORT:DrawAnimatedRects=user32.DrawAnimatedRects") +#pragma comment(linker, "/EXPORT:DrawCaption=user32.DrawCaption") +#pragma comment(linker, "/EXPORT:DrawCaptionTempA=user32.DrawCaptionTempA") +#pragma comment(linker, "/EXPORT:DrawCaptionTempW=user32.DrawCaptionTempW") +#pragma comment(linker, "/EXPORT:DrawEdge=user32.DrawEdge") +#pragma comment(linker, "/EXPORT:DrawFocusRect=user32.DrawFocusRect") +#pragma comment(linker, "/EXPORT:DrawFrame=user32.DrawFrame") +#pragma comment(linker, "/EXPORT:DrawFrameControl=user32.DrawFrameControl") +#pragma comment(linker, "/EXPORT:DrawIcon=user32.DrawIcon") +#pragma comment(linker, "/EXPORT:DrawIconEx=user32.DrawIconEx") +#pragma comment(linker, "/EXPORT:DrawMenuBar=user32.DrawMenuBar") +#pragma comment(linker, "/EXPORT:DrawMenuBarTemp=user32.DrawMenuBarTemp") +#pragma comment(linker, "/EXPORT:DrawStateA=user32.DrawStateA") +#pragma comment(linker, "/EXPORT:DrawStateW=user32.DrawStateW") +#pragma comment(linker, "/EXPORT:DrawTextA=user32.DrawTextA") +#pragma comment(linker, "/EXPORT:DrawTextExA=user32.DrawTextExA") +#pragma comment(linker, "/EXPORT:DrawTextExW=user32.DrawTextExW") +#pragma comment(linker, "/EXPORT:DrawTextW=user32.DrawTextW") +#pragma comment(linker, "/EXPORT:DwmGetDxSharedSurface=user32.DwmGetDxSharedSurface") +#pragma comment(linker, "/EXPORT:DwmStartRedirection=user32.DwmStartRedirection") +#pragma comment(linker, "/EXPORT:DwmStopRedirection=user32.DwmStopRedirection") +#pragma comment(linker, "/EXPORT:EditWndProc=user32.EditWndProc") +#pragma comment(linker, "/EXPORT:EmptyClipboard=user32.EmptyClipboard") +#pragma comment(linker, "/EXPORT:EnableMenuItem=user32.EnableMenuItem") +#pragma comment(linker, "/EXPORT:EnableScrollBar=user32.EnableScrollBar") +#pragma comment(linker, "/EXPORT:EnableWindow=user32.EnableWindow") +#pragma comment(linker, "/EXPORT:EndDeferWindowPos=user32.EndDeferWindowPos") +#pragma comment(linker, "/EXPORT:EndDialog=user32.EndDialog") +#pragma comment(linker, "/EXPORT:EndMenu=user32.EndMenu") +#pragma comment(linker, "/EXPORT:EndPaint=user32.EndPaint") +#pragma comment(linker, "/EXPORT:EndTask=user32.EndTask") +#pragma comment(linker, "/EXPORT:EnterReaderModeHelper=user32.EnterReaderModeHelper") +#pragma comment(linker, "/EXPORT:EnumChildWindows=user32.EnumChildWindows") +#pragma comment(linker, "/EXPORT:EnumClipboardFormats=user32.EnumClipboardFormats") +#pragma comment(linker, "/EXPORT:EnumDesktopWindows=user32.EnumDesktopWindows") +#pragma comment(linker, "/EXPORT:EnumDesktopsA=user32.EnumDesktopsA") +#pragma comment(linker, "/EXPORT:EnumDesktopsW=user32.EnumDesktopsW") +#pragma comment(linker, "/EXPORT:EnumDisplayDevicesA=user32.EnumDisplayDevicesA") +#pragma comment(linker, "/EXPORT:EnumDisplayDevicesW=user32.EnumDisplayDevicesW") +#pragma comment(linker, "/EXPORT:EnumDisplayMonitors=user32.EnumDisplayMonitors") +#pragma comment(linker, "/EXPORT:EnumDisplaySettingsA=user32.EnumDisplaySettingsA") +#pragma comment(linker, "/EXPORT:EnumDisplaySettingsExA=user32.EnumDisplaySettingsExA") +#pragma comment(linker, "/EXPORT:EnumDisplaySettingsExW=user32.EnumDisplaySettingsExW") +#pragma comment(linker, "/EXPORT:EnumDisplaySettingsW=user32.EnumDisplaySettingsW") +#pragma comment(linker, "/EXPORT:EnumPropsA=user32.EnumPropsA") +#pragma comment(linker, "/EXPORT:EnumPropsExA=user32.EnumPropsExA") +#pragma comment(linker, "/EXPORT:EnumPropsExW=user32.EnumPropsExW") +#pragma comment(linker, "/EXPORT:EnumPropsW=user32.EnumPropsW") +#pragma comment(linker, "/EXPORT:EnumThreadWindows=user32.EnumThreadWindows") +#pragma comment(linker, "/EXPORT:EnumWindowStationsA=user32.EnumWindowStationsA") +#pragma comment(linker, "/EXPORT:EnumWindowStationsW=user32.EnumWindowStationsW") +#pragma comment(linker, "/EXPORT:EnumWindows=user32.EnumWindows") +#pragma comment(linker, "/EXPORT:EqualRect=user32.EqualRect") +#pragma comment(linker, "/EXPORT:ExcludeUpdateRgn=user32.ExcludeUpdateRgn") +#pragma comment(linker, "/EXPORT:ExitWindowsEx=user32.ExitWindowsEx") +#pragma comment(linker, "/EXPORT:FillRect=user32.FillRect") +#pragma comment(linker, "/EXPORT:FindWindowA=user32.FindWindowA") +#pragma comment(linker, "/EXPORT:FindWindowExA=user32.FindWindowExA") +#pragma comment(linker, "/EXPORT:FindWindowExW=user32.FindWindowExW") +#pragma comment(linker, "/EXPORT:FindWindowW=user32.FindWindowW") +#pragma comment(linker, "/EXPORT:FlashWindow=user32.FlashWindow") +#pragma comment(linker, "/EXPORT:FlashWindowEx=user32.FlashWindowEx") +#pragma comment(linker, "/EXPORT:FrameRect=user32.FrameRect") +#pragma comment(linker, "/EXPORT:FreeDDElParam=user32.FreeDDElParam") +#pragma comment(linker, "/EXPORT:FrostCrashedWindow=user32.FrostCrashedWindow") +#pragma comment(linker, "/EXPORT:GetActiveWindow=user32.GetActiveWindow") +#pragma comment(linker, "/EXPORT:GetAltTabInfo=user32.GetAltTabInfo") +#pragma comment(linker, "/EXPORT:GetAltTabInfoA=user32.GetAltTabInfoA") +#pragma comment(linker, "/EXPORT:GetAltTabInfoW=user32.GetAltTabInfoW") +#pragma comment(linker, "/EXPORT:GetAncestor=user32.GetAncestor") +#pragma comment(linker, "/EXPORT:GetAppCompatFlags=user32.GetAppCompatFlags") +#pragma comment(linker, "/EXPORT:GetAppCompatFlags2=user32.GetAppCompatFlags2") +#pragma comment(linker, "/EXPORT:GetAsyncKeyState=user32.GetAsyncKeyState") +#pragma comment(linker, "/EXPORT:GetCapture=user32.GetCapture") +#pragma comment(linker, "/EXPORT:GetCaretBlinkTime=user32.GetCaretBlinkTime") +#pragma comment(linker, "/EXPORT:GetCaretPos=user32.GetCaretPos") +#pragma comment(linker, "/EXPORT:GetClassInfoA=user32.GetClassInfoA") +#pragma comment(linker, "/EXPORT:GetClassInfoExA=user32.GetClassInfoExA") +#pragma comment(linker, "/EXPORT:GetClassInfoExW=user32.GetClassInfoExW") +#pragma comment(linker, "/EXPORT:GetClassInfoW=user32.GetClassInfoW") +#pragma comment(linker, "/EXPORT:GetClassLongA=user32.GetClassLongA") +#pragma comment(linker, "/EXPORT:GetClassLongW=user32.GetClassLongW") +#pragma comment(linker, "/EXPORT:GetClassNameA=user32.GetClassNameA") +#pragma comment(linker, "/EXPORT:GetClassNameW=user32.GetClassNameW") +#pragma comment(linker, "/EXPORT:GetClassWord=user32.GetClassWord") +#pragma comment(linker, "/EXPORT:GetClientRect=user32.GetClientRect") +#pragma comment(linker, "/EXPORT:GetClipCursor=user32.GetClipCursor") +#pragma comment(linker, "/EXPORT:GetClipboardData=user32.GetClipboardData") +#pragma comment(linker, "/EXPORT:GetClipboardFormatNameA=user32.GetClipboardFormatNameA") +#pragma comment(linker, "/EXPORT:GetClipboardFormatNameW=user32.GetClipboardFormatNameW") +#pragma comment(linker, "/EXPORT:GetClipboardOwner=user32.GetClipboardOwner") +#pragma comment(linker, "/EXPORT:GetClipboardSequenceNumber=user32.GetClipboardSequenceNumber") +#pragma comment(linker, "/EXPORT:GetClipboardViewer=user32.GetClipboardViewer") +#pragma comment(linker, "/EXPORT:GetComboBoxInfo=user32.GetComboBoxInfo") +#pragma comment(linker, "/EXPORT:GetCursor=user32.GetCursor") +#pragma comment(linker, "/EXPORT:GetCursorFrameInfo=user32.GetCursorFrameInfo") +#pragma comment(linker, "/EXPORT:GetCursorInfo=user32.GetCursorInfo") +#pragma comment(linker, "/EXPORT:GetCursorPos=user32.GetCursorPos") +#pragma comment(linker, "/EXPORT:GetDC=user32.GetDC") +#pragma comment(linker, "/EXPORT:GetDCEx=user32.GetDCEx") +#pragma comment(linker, "/EXPORT:GetDesktopWindow=user32.GetDesktopWindow") +#pragma comment(linker, "/EXPORT:GetDialogBaseUnits=user32.GetDialogBaseUnits") +#pragma comment(linker, "/EXPORT:GetDisplayConfigBufferSizes=user32.GetDisplayConfigBufferSizes") +#pragma comment(linker, "/EXPORT:GetDlgCtrlID=user32.GetDlgCtrlID") +#pragma comment(linker, "/EXPORT:GetDlgItem=user32.GetDlgItem") +#pragma comment(linker, "/EXPORT:GetDlgItemInt=user32.GetDlgItemInt") +#pragma comment(linker, "/EXPORT:GetDlgItemTextA=user32.GetDlgItemTextA") +#pragma comment(linker, "/EXPORT:GetDlgItemTextW=user32.GetDlgItemTextW") +#pragma comment(linker, "/EXPORT:GetDoubleClickTime=user32.GetDoubleClickTime") +#pragma comment(linker, "/EXPORT:GetFocus=user32.GetFocus") +#pragma comment(linker, "/EXPORT:GetForegroundWindow=user32.GetForegroundWindow") +#pragma comment(linker, "/EXPORT:GetGUIThreadInfo=user32.GetGUIThreadInfo") +#pragma comment(linker, "/EXPORT:GetGestureConfig=user32.GetGestureConfig") +#pragma comment(linker, "/EXPORT:GetGestureExtraArgs=user32.GetGestureExtraArgs") +#pragma comment(linker, "/EXPORT:GetGestureInfo=user32.GetGestureInfo") +#pragma comment(linker, "/EXPORT:GetGuiResources=user32.GetGuiResources") +#pragma comment(linker, "/EXPORT:GetIconInfo=user32.GetIconInfo") +#pragma comment(linker, "/EXPORT:GetIconInfoExA=user32.GetIconInfoExA") +#pragma comment(linker, "/EXPORT:GetIconInfoExW=user32.GetIconInfoExW") +#pragma comment(linker, "/EXPORT:GetInputDesktop=user32.GetInputDesktop") +#pragma comment(linker, "/EXPORT:GetInputLocaleInfo=user32.GetInputLocaleInfo") +#pragma comment(linker, "/EXPORT:GetInputState=user32.GetInputState") +#pragma comment(linker, "/EXPORT:GetInternalWindowPos=user32.GetInternalWindowPos") +#pragma comment(linker, "/EXPORT:GetKBCodePage=user32.GetKBCodePage") +#pragma comment(linker, "/EXPORT:GetKeyNameTextA=user32.GetKeyNameTextA") +#pragma comment(linker, "/EXPORT:GetKeyNameTextW=user32.GetKeyNameTextW") +#pragma comment(linker, "/EXPORT:GetKeyState=user32.GetKeyState") +#pragma comment(linker, "/EXPORT:GetKeyboardLayout=user32.GetKeyboardLayout") +#pragma comment(linker, "/EXPORT:GetKeyboardLayoutList=user32.GetKeyboardLayoutList") +#pragma comment(linker, "/EXPORT:GetKeyboardLayoutNameA=user32.GetKeyboardLayoutNameA") +#pragma comment(linker, "/EXPORT:GetKeyboardLayoutNameW=user32.GetKeyboardLayoutNameW") +#pragma comment(linker, "/EXPORT:GetKeyboardState=user32.GetKeyboardState") +#pragma comment(linker, "/EXPORT:GetKeyboardType=user32.GetKeyboardType") +#pragma comment(linker, "/EXPORT:GetLastActivePopup=user32.GetLastActivePopup") +#pragma comment(linker, "/EXPORT:GetLastInputInfo=user32.GetLastInputInfo") +#pragma comment(linker, "/EXPORT:GetLayeredWindowAttributes=user32.GetLayeredWindowAttributes") +#pragma comment(linker, "/EXPORT:GetListBoxInfo=user32.GetListBoxInfo") +#pragma comment(linker, "/EXPORT:GetMagnificationDesktopColorEffect=user32.GetMagnificationDesktopColorEffect") +#pragma comment(linker, "/EXPORT:GetMagnificationDesktopMagnification=user32.GetMagnificationDesktopMagnification") +#pragma comment(linker, "/EXPORT:GetMagnificationLensCtxInformation=user32.GetMagnificationLensCtxInformation") +#pragma comment(linker, "/EXPORT:GetMenu=user32.GetMenu") +#pragma comment(linker, "/EXPORT:GetMenuBarInfo=user32.GetMenuBarInfo") +#pragma comment(linker, "/EXPORT:GetMenuCheckMarkDimensions=user32.GetMenuCheckMarkDimensions") +#pragma comment(linker, "/EXPORT:GetMenuContextHelpId=user32.GetMenuContextHelpId") +#pragma comment(linker, "/EXPORT:GetMenuDefaultItem=user32.GetMenuDefaultItem") +#pragma comment(linker, "/EXPORT:GetMenuInfo=user32.GetMenuInfo") +#pragma comment(linker, "/EXPORT:GetMenuItemCount=user32.GetMenuItemCount") +#pragma comment(linker, "/EXPORT:GetMenuItemID=user32.GetMenuItemID") +#pragma comment(linker, "/EXPORT:GetMenuItemInfoA=user32.GetMenuItemInfoA") +#pragma comment(linker, "/EXPORT:GetMenuItemInfoW=user32.GetMenuItemInfoW") +#pragma comment(linker, "/EXPORT:GetMenuItemRect=user32.GetMenuItemRect") +#pragma comment(linker, "/EXPORT:GetMenuState=user32.GetMenuState") +#pragma comment(linker, "/EXPORT:GetMenuStringA=user32.GetMenuStringA") +#pragma comment(linker, "/EXPORT:GetMenuStringW=user32.GetMenuStringW") +#pragma comment(linker, "/EXPORT:GetMessageA=user32.GetMessageA") +#pragma comment(linker, "/EXPORT:GetMessageExtraInfo=user32.GetMessageExtraInfo") +#pragma comment(linker, "/EXPORT:GetMessagePos=user32.GetMessagePos") +#pragma comment(linker, "/EXPORT:GetMessageTime=user32.GetMessageTime") +#pragma comment(linker, "/EXPORT:GetMessageW=user32.GetMessageW") +#pragma comment(linker, "/EXPORT:GetMonitorInfoA=user32.GetMonitorInfoA") +#pragma comment(linker, "/EXPORT:GetMonitorInfoW=user32.GetMonitorInfoW") +#pragma comment(linker, "/EXPORT:GetMouseMovePointsEx=user32.GetMouseMovePointsEx") +#pragma comment(linker, "/EXPORT:GetNextDlgGroupItem=user32.GetNextDlgGroupItem") +#pragma comment(linker, "/EXPORT:GetNextDlgTabItem=user32.GetNextDlgTabItem") +#pragma comment(linker, "/EXPORT:GetOpenClipboardWindow=user32.GetOpenClipboardWindow") +#pragma comment(linker, "/EXPORT:GetParent=user32.GetParent") +#pragma comment(linker, "/EXPORT:GetPhysicalCursorPos=user32.GetPhysicalCursorPos") +#pragma comment(linker, "/EXPORT:GetPriorityClipboardFormat=user32.GetPriorityClipboardFormat") +#pragma comment(linker, "/EXPORT:GetProcessDefaultLayout=user32.GetProcessDefaultLayout") +#pragma comment(linker, "/EXPORT:GetProcessWindowStation=user32.GetProcessWindowStation") +#pragma comment(linker, "/EXPORT:GetProgmanWindow=user32.GetProgmanWindow") +#pragma comment(linker, "/EXPORT:GetPropA=user32.GetPropA") +#pragma comment(linker, "/EXPORT:GetPropW=user32.GetPropW") +#pragma comment(linker, "/EXPORT:GetQueueStatus=user32.GetQueueStatus") +#pragma comment(linker, "/EXPORT:GetRawInputBuffer=user32.GetRawInputBuffer") +#pragma comment(linker, "/EXPORT:GetRawInputData=user32.GetRawInputData") +#pragma comment(linker, "/EXPORT:GetRawInputDeviceInfoA=user32.GetRawInputDeviceInfoA") +#pragma comment(linker, "/EXPORT:GetRawInputDeviceInfoW=user32.GetRawInputDeviceInfoW") +#pragma comment(linker, "/EXPORT:GetRawInputDeviceList=user32.GetRawInputDeviceList") +#pragma comment(linker, "/EXPORT:GetReasonTitleFromReasonCode=user32.GetReasonTitleFromReasonCode") +#pragma comment(linker, "/EXPORT:GetRegisteredRawInputDevices=user32.GetRegisteredRawInputDevices") +#pragma comment(linker, "/EXPORT:GetScrollBarInfo=user32.GetScrollBarInfo") +#pragma comment(linker, "/EXPORT:GetScrollInfo=user32.GetScrollInfo") +#pragma comment(linker, "/EXPORT:GetScrollPos=user32.GetScrollPos") +#pragma comment(linker, "/EXPORT:GetScrollRange=user32.GetScrollRange") +#pragma comment(linker, "/EXPORT:GetSendMessageReceiver=user32.GetSendMessageReceiver") +#pragma comment(linker, "/EXPORT:GetShellWindow=user32.GetShellWindow") +#pragma comment(linker, "/EXPORT:GetSubMenu=user32.GetSubMenu") +#pragma comment(linker, "/EXPORT:GetSysColor=user32.GetSysColor") +#pragma comment(linker, "/EXPORT:GetSysColorBrush=user32.GetSysColorBrush") +#pragma comment(linker, "/EXPORT:GetSystemMenu=user32.GetSystemMenu") +#pragma comment(linker, "/EXPORT:GetSystemMetrics=user32.GetSystemMetrics") +#pragma comment(linker, "/EXPORT:GetTabbedTextExtentA=user32.GetTabbedTextExtentA") +#pragma comment(linker, "/EXPORT:GetTabbedTextExtentW=user32.GetTabbedTextExtentW") +#pragma comment(linker, "/EXPORT:GetTaskmanWindow=user32.GetTaskmanWindow") +#pragma comment(linker, "/EXPORT:GetThreadDesktop=user32.GetThreadDesktop") +#pragma comment(linker, "/EXPORT:GetTitleBarInfo=user32.GetTitleBarInfo") +#pragma comment(linker, "/EXPORT:GetTopLevelWindow=user32.GetTopLevelWindow") +#pragma comment(linker, "/EXPORT:GetTopWindow=user32.GetTopWindow") +#pragma comment(linker, "/EXPORT:GetTouchInputInfo=user32.GetTouchInputInfo") +#pragma comment(linker, "/EXPORT:GetUpdateRect=user32.GetUpdateRect") +#pragma comment(linker, "/EXPORT:GetUpdateRgn=user32.GetUpdateRgn") +#pragma comment(linker, "/EXPORT:GetUpdatedClipboardFormats=user32.GetUpdatedClipboardFormats") +#pragma comment(linker, "/EXPORT:GetUserObjectInformationA=user32.GetUserObjectInformationA") +#pragma comment(linker, "/EXPORT:GetUserObjectInformationW=user32.GetUserObjectInformationW") +#pragma comment(linker, "/EXPORT:GetUserObjectSecurity=user32.GetUserObjectSecurity") +#pragma comment(linker, "/EXPORT:GetWinStationInfo=user32.GetWinStationInfo") +#pragma comment(linker, "/EXPORT:GetWindow=user32.GetWindow") +#pragma comment(linker, "/EXPORT:GetWindowCompositionAttribute=user32.GetWindowCompositionAttribute") +#pragma comment(linker, "/EXPORT:GetWindowCompositionInfo=user32.GetWindowCompositionInfo") +#pragma comment(linker, "/EXPORT:GetWindowContextHelpId=user32.GetWindowContextHelpId") +#pragma comment(linker, "/EXPORT:GetWindowDC=user32.GetWindowDC") +#pragma comment(linker, "/EXPORT:GetWindowDisplayAffinity=user32.GetWindowDisplayAffinity") +#pragma comment(linker, "/EXPORT:GetWindowInfo=user32.GetWindowInfo") +#pragma comment(linker, "/EXPORT:GetWindowLongA=user32.GetWindowLongA") +#pragma comment(linker, "/EXPORT:GetWindowLongW=user32.GetWindowLongW") +#pragma comment(linker, "/EXPORT:GetWindowMinimizeRect=user32.GetWindowMinimizeRect") +#pragma comment(linker, "/EXPORT:GetWindowModuleFileName=user32.GetWindowModuleFileName") +#pragma comment(linker, "/EXPORT:GetWindowModuleFileNameA=user32.GetWindowModuleFileNameA") +#pragma comment(linker, "/EXPORT:GetWindowModuleFileNameW=user32.GetWindowModuleFileNameW") +#pragma comment(linker, "/EXPORT:GetWindowPlacement=user32.GetWindowPlacement") +#pragma comment(linker, "/EXPORT:GetWindowRect=user32.GetWindowRect") +#pragma comment(linker, "/EXPORT:GetWindowRgn=user32.GetWindowRgn") +#pragma comment(linker, "/EXPORT:GetWindowRgnBox=user32.GetWindowRgnBox") +#pragma comment(linker, "/EXPORT:GetWindowRgnEx=user32.GetWindowRgnEx") +#pragma comment(linker, "/EXPORT:GetWindowTextA=user32.GetWindowTextA") +#pragma comment(linker, "/EXPORT:GetWindowTextLengthA=user32.GetWindowTextLengthA") +#pragma comment(linker, "/EXPORT:GetWindowTextLengthW=user32.GetWindowTextLengthW") +#pragma comment(linker, "/EXPORT:GetWindowTextW=user32.GetWindowTextW") +#pragma comment(linker, "/EXPORT:GetWindowThreadProcessId=user32.GetWindowThreadProcessId") +#pragma comment(linker, "/EXPORT:GetWindowWord=user32.GetWindowWord") +#pragma comment(linker, "/EXPORT:GhostWindowFromHungWindow=user32.GhostWindowFromHungWindow") +#pragma comment(linker, "/EXPORT:GrayStringA=user32.GrayStringA") +#pragma comment(linker, "/EXPORT:GrayStringW=user32.GrayStringW") +#pragma comment(linker, "/EXPORT:HideCaret=user32.HideCaret") +#pragma comment(linker, "/EXPORT:HiliteMenuItem=user32.HiliteMenuItem") +#pragma comment(linker, "/EXPORT:HungWindowFromGhostWindow=user32.HungWindowFromGhostWindow") +#pragma comment(linker, "/EXPORT:IMPGetIMEA=user32.IMPGetIMEA") +#pragma comment(linker, "/EXPORT:IMPGetIMEW=user32.IMPGetIMEW") +#pragma comment(linker, "/EXPORT:IMPQueryIMEA=user32.IMPQueryIMEA") +#pragma comment(linker, "/EXPORT:IMPQueryIMEW=user32.IMPQueryIMEW") +#pragma comment(linker, "/EXPORT:IMPSetIMEA=user32.IMPSetIMEA") +#pragma comment(linker, "/EXPORT:IMPSetIMEW=user32.IMPSetIMEW") +#pragma comment(linker, "/EXPORT:ImpersonateDdeClientWindow=user32.ImpersonateDdeClientWindow") +#pragma comment(linker, "/EXPORT:InSendMessage=user32.InSendMessage") +#pragma comment(linker, "/EXPORT:InSendMessageEx=user32.InSendMessageEx") +#pragma comment(linker, "/EXPORT:InflateRect=user32.InflateRect") +#pragma comment(linker, "/EXPORT:InitializeLpkHooks=user32.InitializeLpkHooks") +#pragma comment(linker, "/EXPORT:InsertMenuA=user32.InsertMenuA") +#pragma comment(linker, "/EXPORT:InsertMenuItemA=user32.InsertMenuItemA") +#pragma comment(linker, "/EXPORT:InsertMenuItemW=user32.InsertMenuItemW") +#pragma comment(linker, "/EXPORT:InsertMenuW=user32.InsertMenuW") +#pragma comment(linker, "/EXPORT:InternalGetWindowIcon=user32.InternalGetWindowIcon") +#pragma comment(linker, "/EXPORT:InternalGetWindowText=user32.InternalGetWindowText") +#pragma comment(linker, "/EXPORT:IntersectRect=user32.IntersectRect") +#pragma comment(linker, "/EXPORT:InvalidateRect=user32.InvalidateRect") +#pragma comment(linker, "/EXPORT:InvalidateRgn=user32.InvalidateRgn") +#pragma comment(linker, "/EXPORT:InvertRect=user32.InvertRect") +#pragma comment(linker, "/EXPORT:IsCharAlphaA=user32.IsCharAlphaA") +#pragma comment(linker, "/EXPORT:IsCharAlphaNumericA=user32.IsCharAlphaNumericA") +#pragma comment(linker, "/EXPORT:IsCharAlphaNumericW=user32.IsCharAlphaNumericW") +#pragma comment(linker, "/EXPORT:IsCharAlphaW=user32.IsCharAlphaW") +#pragma comment(linker, "/EXPORT:IsCharLowerA=user32.IsCharLowerA") +#pragma comment(linker, "/EXPORT:IsCharLowerW=user32.IsCharLowerW") +#pragma comment(linker, "/EXPORT:IsCharUpperA=user32.IsCharUpperA") +#pragma comment(linker, "/EXPORT:IsCharUpperW=user32.IsCharUpperW") +#pragma comment(linker, "/EXPORT:IsChild=user32.IsChild") +#pragma comment(linker, "/EXPORT:IsClipboardFormatAvailable=user32.IsClipboardFormatAvailable") +#pragma comment(linker, "/EXPORT:IsDialogMessage=user32.IsDialogMessage") +#pragma comment(linker, "/EXPORT:IsDialogMessageA=user32.IsDialogMessageA") +#pragma comment(linker, "/EXPORT:IsDialogMessageW=user32.IsDialogMessageW") +#pragma comment(linker, "/EXPORT:IsDlgButtonChecked=user32.IsDlgButtonChecked") +#pragma comment(linker, "/EXPORT:IsGUIThread=user32.IsGUIThread") +#pragma comment(linker, "/EXPORT:IsHungAppWindow=user32.IsHungAppWindow") +#pragma comment(linker, "/EXPORT:IsIconic=user32.IsIconic") +#pragma comment(linker, "/EXPORT:IsMenu=user32.IsMenu") +#pragma comment(linker, "/EXPORT:IsProcessDPIAware=user32.IsProcessDPIAware") +#pragma comment(linker, "/EXPORT:IsRectEmpty=user32.IsRectEmpty") +#pragma comment(linker, "/EXPORT:IsSETEnabled=user32.IsSETEnabled") +#pragma comment(linker, "/EXPORT:IsServerSideWindow=user32.IsServerSideWindow") +#pragma comment(linker, "/EXPORT:IsThreadDesktopComposited=user32.IsThreadDesktopComposited") +#pragma comment(linker, "/EXPORT:IsTopLevelWindow=user32.IsTopLevelWindow") +#pragma comment(linker, "/EXPORT:IsTouchWindow=user32.IsTouchWindow") +#pragma comment(linker, "/EXPORT:IsWinEventHookInstalled=user32.IsWinEventHookInstalled") +#pragma comment(linker, "/EXPORT:IsWindow=user32.IsWindow") +#pragma comment(linker, "/EXPORT:IsWindowEnabled=user32.IsWindowEnabled") +#pragma comment(linker, "/EXPORT:IsWindowInDestroy=user32.IsWindowInDestroy") +#pragma comment(linker, "/EXPORT:IsWindowRedirectedForPrint=user32.IsWindowRedirectedForPrint") +#pragma comment(linker, "/EXPORT:IsWindowUnicode=user32.IsWindowUnicode") +#pragma comment(linker, "/EXPORT:IsWindowVisible=user32.IsWindowVisible") +#pragma comment(linker, "/EXPORT:IsWow64Message=user32.IsWow64Message") +#pragma comment(linker, "/EXPORT:IsZoomed=user32.IsZoomed") +#pragma comment(linker, "/EXPORT:KillTimer=user32.KillTimer") +#pragma comment(linker, "/EXPORT:LoadAcceleratorsA=user32.LoadAcceleratorsA") +#pragma comment(linker, "/EXPORT:LoadAcceleratorsW=user32.LoadAcceleratorsW") +#pragma comment(linker, "/EXPORT:LoadBitmapA=user32.LoadBitmapA") +#pragma comment(linker, "/EXPORT:LoadBitmapW=user32.LoadBitmapW") +#pragma comment(linker, "/EXPORT:LoadCursorA=user32.LoadCursorA") +#pragma comment(linker, "/EXPORT:LoadCursorFromFileA=user32.LoadCursorFromFileA") +#pragma comment(linker, "/EXPORT:LoadCursorFromFileW=user32.LoadCursorFromFileW") +#pragma comment(linker, "/EXPORT:LoadCursorW=user32.LoadCursorW") +#pragma comment(linker, "/EXPORT:LoadIconA=user32.LoadIconA") +#pragma comment(linker, "/EXPORT:LoadIconW=user32.LoadIconW") +#pragma comment(linker, "/EXPORT:LoadImageA=user32.LoadImageA") +#pragma comment(linker, "/EXPORT:LoadImageW=user32.LoadImageW") +#pragma comment(linker, "/EXPORT:LoadKeyboardLayoutA=user32.LoadKeyboardLayoutA") +#pragma comment(linker, "/EXPORT:LoadKeyboardLayoutEx=user32.LoadKeyboardLayoutEx") +#pragma comment(linker, "/EXPORT:LoadKeyboardLayoutW=user32.LoadKeyboardLayoutW") +#pragma comment(linker, "/EXPORT:LoadLocalFonts=user32.LoadLocalFonts") +#pragma comment(linker, "/EXPORT:LoadMenuA=user32.LoadMenuA") +#pragma comment(linker, "/EXPORT:LoadMenuIndirectA=user32.LoadMenuIndirectA") +#pragma comment(linker, "/EXPORT:LoadMenuIndirectW=user32.LoadMenuIndirectW") +#pragma comment(linker, "/EXPORT:LoadMenuW=user32.LoadMenuW") +#pragma comment(linker, "/EXPORT:LoadRemoteFonts=user32.LoadRemoteFonts") +#pragma comment(linker, "/EXPORT:LoadStringA=user32.LoadStringA") +#pragma comment(linker, "/EXPORT:LoadStringW=user32.LoadStringW") +#pragma comment(linker, "/EXPORT:LockSetForegroundWindow=user32.LockSetForegroundWindow") +#pragma comment(linker, "/EXPORT:LockWindowStation=user32.LockWindowStation") +#pragma comment(linker, "/EXPORT:LockWindowUpdate=user32.LockWindowUpdate") +#pragma comment(linker, "/EXPORT:LockWorkStation=user32.LockWorkStation") +#pragma comment(linker, "/EXPORT:LogicalToPhysicalPoint=user32.LogicalToPhysicalPoint") +#pragma comment(linker, "/EXPORT:LookupIconIdFromDirectory=user32.LookupIconIdFromDirectory") +#pragma comment(linker, "/EXPORT:LookupIconIdFromDirectoryEx=user32.LookupIconIdFromDirectoryEx") +#pragma comment(linker, "/EXPORT:MBToWCSEx=user32.MBToWCSEx") +#pragma comment(linker, "/EXPORT:MB_GetString=user32.MB_GetString") +#pragma comment(linker, "/EXPORT:MapDialogRect=user32.MapDialogRect") +#pragma comment(linker, "/EXPORT:MapVirtualKeyA=user32.MapVirtualKeyA") +#pragma comment(linker, "/EXPORT:MapVirtualKeyExA=user32.MapVirtualKeyExA") +#pragma comment(linker, "/EXPORT:MapVirtualKeyExW=user32.MapVirtualKeyExW") +#pragma comment(linker, "/EXPORT:MapVirtualKeyW=user32.MapVirtualKeyW") +#pragma comment(linker, "/EXPORT:MapWindowPoints=user32.MapWindowPoints") +#pragma comment(linker, "/EXPORT:MenuItemFromPoint=user32.MenuItemFromPoint") +#pragma comment(linker, "/EXPORT:MenuWindowProcA=user32.MenuWindowProcA") +#pragma comment(linker, "/EXPORT:MenuWindowProcW=user32.MenuWindowProcW") +#pragma comment(linker, "/EXPORT:MessageBeep=user32.MessageBeep") +#pragma comment(linker, "/EXPORT:MessageBoxA=user32.MessageBoxA") +#pragma comment(linker, "/EXPORT:MessageBoxExA=user32.MessageBoxExA") +#pragma comment(linker, "/EXPORT:MessageBoxExW=user32.MessageBoxExW") +#pragma comment(linker, "/EXPORT:MessageBoxIndirectA=user32.MessageBoxIndirectA") +#pragma comment(linker, "/EXPORT:MessageBoxIndirectW=user32.MessageBoxIndirectW") +#pragma comment(linker, "/EXPORT:MessageBoxTimeoutA=user32.MessageBoxTimeoutA") +#pragma comment(linker, "/EXPORT:MessageBoxTimeoutW=user32.MessageBoxTimeoutW") +#pragma comment(linker, "/EXPORT:MessageBoxW=user32.MessageBoxW") +#pragma comment(linker, "/EXPORT:ModifyMenuA=user32.ModifyMenuA") +#pragma comment(linker, "/EXPORT:ModifyMenuW=user32.ModifyMenuW") +#pragma comment(linker, "/EXPORT:MonitorFromPoint=user32.MonitorFromPoint") +#pragma comment(linker, "/EXPORT:MonitorFromRect=user32.MonitorFromRect") +#pragma comment(linker, "/EXPORT:MonitorFromWindow=user32.MonitorFromWindow") +#pragma comment(linker, "/EXPORT:MoveWindow=user32.MoveWindow") +#pragma comment(linker, "/EXPORT:MsgWaitForMultipleObjects=user32.MsgWaitForMultipleObjects") +#pragma comment(linker, "/EXPORT:MsgWaitForMultipleObjectsEx=user32.MsgWaitForMultipleObjectsEx") +#pragma comment(linker, "/EXPORT:NotifyOverlayWindow=user32.NotifyOverlayWindow") +#pragma comment(linker, "/EXPORT:NotifyWinEvent=user32.NotifyWinEvent") +#pragma comment(linker, "/EXPORT:OemKeyScan=user32.OemKeyScan") +#pragma comment(linker, "/EXPORT:OemToCharA=user32.OemToCharA") +#pragma comment(linker, "/EXPORT:OemToCharBuffA=user32.OemToCharBuffA") +#pragma comment(linker, "/EXPORT:OemToCharBuffW=user32.OemToCharBuffW") +#pragma comment(linker, "/EXPORT:OemToCharW=user32.OemToCharW") +#pragma comment(linker, "/EXPORT:OffsetRect=user32.OffsetRect") +#pragma comment(linker, "/EXPORT:OpenClipboard=user32.OpenClipboard") +#pragma comment(linker, "/EXPORT:OpenDesktopA=user32.OpenDesktopA") +#pragma comment(linker, "/EXPORT:OpenDesktopW=user32.OpenDesktopW") +#pragma comment(linker, "/EXPORT:OpenIcon=user32.OpenIcon") +#pragma comment(linker, "/EXPORT:OpenInputDesktop=user32.OpenInputDesktop") +#pragma comment(linker, "/EXPORT:OpenThreadDesktop=user32.OpenThreadDesktop") +#pragma comment(linker, "/EXPORT:OpenWindowStationA=user32.OpenWindowStationA") +#pragma comment(linker, "/EXPORT:OpenWindowStationW=user32.OpenWindowStationW") +#pragma comment(linker, "/EXPORT:PackDDElParam=user32.PackDDElParam") +#pragma comment(linker, "/EXPORT:PaintDesktop=user32.PaintDesktop") +#pragma comment(linker, "/EXPORT:PaintMenuBar=user32.PaintMenuBar") +#pragma comment(linker, "/EXPORT:PaintMonitor=user32.PaintMonitor") +#pragma comment(linker, "/EXPORT:PeekMessageA=user32.PeekMessageA") +#pragma comment(linker, "/EXPORT:PeekMessageW=user32.PeekMessageW") +#pragma comment(linker, "/EXPORT:PhysicalToLogicalPoint=user32.PhysicalToLogicalPoint") +#pragma comment(linker, "/EXPORT:PostMessageA=user32.PostMessageA") +#pragma comment(linker, "/EXPORT:PostMessageW=user32.PostMessageW") +#pragma comment(linker, "/EXPORT:PostQuitMessage=user32.PostQuitMessage") +#pragma comment(linker, "/EXPORT:PostThreadMessageA=user32.PostThreadMessageA") +#pragma comment(linker, "/EXPORT:PostThreadMessageW=user32.PostThreadMessageW") +#pragma comment(linker, "/EXPORT:PrintWindow=user32.PrintWindow") +#pragma comment(linker, "/EXPORT:PrivateExtractIconExA=user32.PrivateExtractIconExA") +#pragma comment(linker, "/EXPORT:PrivateExtractIconExW=user32.PrivateExtractIconExW") +#pragma comment(linker, "/EXPORT:PrivateExtractIconsA=user32.PrivateExtractIconsA") +#pragma comment(linker, "/EXPORT:PrivateExtractIconsW=user32.PrivateExtractIconsW") +#pragma comment(linker, "/EXPORT:PrivateRegisterICSProc=user32.PrivateRegisterICSProc") +#pragma comment(linker, "/EXPORT:PtInRect=user32.PtInRect") +#pragma comment(linker, "/EXPORT:QueryDisplayConfig=user32.QueryDisplayConfig") +#pragma comment(linker, "/EXPORT:QuerySendMessage=user32.QuerySendMessage") +#pragma comment(linker, "/EXPORT:RealChildWindowFromPoint=user32.RealChildWindowFromPoint") +#pragma comment(linker, "/EXPORT:RealGetWindowClass=user32.RealGetWindowClass") +#pragma comment(linker, "/EXPORT:RealGetWindowClassA=user32.RealGetWindowClassA") +#pragma comment(linker, "/EXPORT:RealGetWindowClassW=user32.RealGetWindowClassW") +#pragma comment(linker, "/EXPORT:ReasonCodeNeedsBugID=user32.ReasonCodeNeedsBugID") +#pragma comment(linker, "/EXPORT:ReasonCodeNeedsComment=user32.ReasonCodeNeedsComment") +#pragma comment(linker, "/EXPORT:RecordShutdownReason=user32.RecordShutdownReason") +#pragma comment(linker, "/EXPORT:RedrawWindow=user32.RedrawWindow") +#pragma comment(linker, "/EXPORT:RegisterClassA=user32.RegisterClassA") +#pragma comment(linker, "/EXPORT:RegisterClassExA=user32.RegisterClassExA") +#pragma comment(linker, "/EXPORT:RegisterClassExW=user32.RegisterClassExW") +#pragma comment(linker, "/EXPORT:RegisterClassW=user32.RegisterClassW") +#pragma comment(linker, "/EXPORT:RegisterClipboardFormatA=user32.RegisterClipboardFormatA") +#pragma comment(linker, "/EXPORT:RegisterClipboardFormatW=user32.RegisterClipboardFormatW") +#pragma comment(linker, "/EXPORT:RegisterDeviceNotificationA=user32.RegisterDeviceNotificationA") +#pragma comment(linker, "/EXPORT:RegisterDeviceNotificationW=user32.RegisterDeviceNotificationW") +#pragma comment(linker, "/EXPORT:RegisterErrorReportingDialog=user32.RegisterErrorReportingDialog") +#pragma comment(linker, "/EXPORT:RegisterFrostWindow=user32.RegisterFrostWindow") +#pragma comment(linker, "/EXPORT:RegisterGhostWindow=user32.RegisterGhostWindow") +#pragma comment(linker, "/EXPORT:RegisterHotKey=user32.RegisterHotKey") +#pragma comment(linker, "/EXPORT:RegisterLogonProcess=user32.RegisterLogonProcess") +#pragma comment(linker, "/EXPORT:RegisterMessagePumpHook=user32.RegisterMessagePumpHook") +#pragma comment(linker, "/EXPORT:RegisterPowerSettingNotification=user32.RegisterPowerSettingNotification") +#pragma comment(linker, "/EXPORT:RegisterRawInputDevices=user32.RegisterRawInputDevices") +#pragma comment(linker, "/EXPORT:RegisterServicesProcess=user32.RegisterServicesProcess") +#pragma comment(linker, "/EXPORT:RegisterSessionPort=user32.RegisterSessionPort") +#pragma comment(linker, "/EXPORT:RegisterShellHookWindow=user32.RegisterShellHookWindow") +#pragma comment(linker, "/EXPORT:RegisterSystemThread=user32.RegisterSystemThread") +#pragma comment(linker, "/EXPORT:RegisterTasklist=user32.RegisterTasklist") +#pragma comment(linker, "/EXPORT:RegisterTouchWindow=user32.RegisterTouchWindow") +#pragma comment(linker, "/EXPORT:RegisterUserApiHook=user32.RegisterUserApiHook") +#pragma comment(linker, "/EXPORT:RegisterWindowMessageA=user32.RegisterWindowMessageA") +#pragma comment(linker, "/EXPORT:RegisterWindowMessageW=user32.RegisterWindowMessageW") +#pragma comment(linker, "/EXPORT:ReleaseCapture=user32.ReleaseCapture") +#pragma comment(linker, "/EXPORT:ReleaseDC=user32.ReleaseDC") +#pragma comment(linker, "/EXPORT:RemoveClipboardFormatListener=user32.RemoveClipboardFormatListener") +#pragma comment(linker, "/EXPORT:RemoveMenu=user32.RemoveMenu") +#pragma comment(linker, "/EXPORT:RemovePropA=user32.RemovePropA") +#pragma comment(linker, "/EXPORT:RemovePropW=user32.RemovePropW") +#pragma comment(linker, "/EXPORT:ReplyMessage=user32.ReplyMessage") +#pragma comment(linker, "/EXPORT:ResolveDesktopForWOW=user32.ResolveDesktopForWOW") +#pragma comment(linker, "/EXPORT:ReuseDDElParam=user32.ReuseDDElParam") +#pragma comment(linker, "/EXPORT:ScreenToClient=user32.ScreenToClient") +#pragma comment(linker, "/EXPORT:ScrollChildren=user32.ScrollChildren") +#pragma comment(linker, "/EXPORT:ScrollDC=user32.ScrollDC") +#pragma comment(linker, "/EXPORT:ScrollWindow=user32.ScrollWindow") +#pragma comment(linker, "/EXPORT:ScrollWindowEx=user32.ScrollWindowEx") +#pragma comment(linker, "/EXPORT:SendDlgItemMessageA=user32.SendDlgItemMessageA") +#pragma comment(linker, "/EXPORT:SendDlgItemMessageW=user32.SendDlgItemMessageW") +#pragma comment(linker, "/EXPORT:SendIMEMessageExA=user32.SendIMEMessageExA") +#pragma comment(linker, "/EXPORT:SendIMEMessageExW=user32.SendIMEMessageExW") +#pragma comment(linker, "/EXPORT:SendInput=user32.SendInput") +#pragma comment(linker, "/EXPORT:SendMessageA=user32.SendMessageA") +#pragma comment(linker, "/EXPORT:SendMessageCallbackA=user32.SendMessageCallbackA") +#pragma comment(linker, "/EXPORT:SendMessageCallbackW=user32.SendMessageCallbackW") +#pragma comment(linker, "/EXPORT:SendMessageTimeoutA=user32.SendMessageTimeoutA") +#pragma comment(linker, "/EXPORT:SendMessageTimeoutW=user32.SendMessageTimeoutW") +#pragma comment(linker, "/EXPORT:SendMessageW=user32.SendMessageW") +#pragma comment(linker, "/EXPORT:SendNotifyMessageA=user32.SendNotifyMessageA") +#pragma comment(linker, "/EXPORT:SendNotifyMessageW=user32.SendNotifyMessageW") +#pragma comment(linker, "/EXPORT:SetActiveWindow=user32.SetActiveWindow") +#pragma comment(linker, "/EXPORT:SetCapture=user32.SetCapture") +#pragma comment(linker, "/EXPORT:SetCaretBlinkTime=user32.SetCaretBlinkTime") +#pragma comment(linker, "/EXPORT:SetCaretPos=user32.SetCaretPos") +#pragma comment(linker, "/EXPORT:SetClassLongA=user32.SetClassLongA") +#pragma comment(linker, "/EXPORT:SetClassLongW=user32.SetClassLongW") +#pragma comment(linker, "/EXPORT:SetClassWord=user32.SetClassWord") +#pragma comment(linker, "/EXPORT:SetClipboardData=user32.SetClipboardData") +#pragma comment(linker, "/EXPORT:SetClipboardViewer=user32.SetClipboardViewer") +#pragma comment(linker, "/EXPORT:SetCursor=user32.SetCursor") +#pragma comment(linker, "/EXPORT:SetCursorContents=user32.SetCursorContents") +#pragma comment(linker, "/EXPORT:SetCursorPos=user32.SetCursorPos") +#pragma comment(linker, "/EXPORT:SetDebugErrorLevel=user32.SetDebugErrorLevel") +#pragma comment(linker, "/EXPORT:SetDeskWallpaper=user32.SetDeskWallpaper") +#pragma comment(linker, "/EXPORT:SetDisplayConfig=user32.SetDisplayConfig") +#pragma comment(linker, "/EXPORT:SetDlgItemInt=user32.SetDlgItemInt") +#pragma comment(linker, "/EXPORT:SetDlgItemTextA=user32.SetDlgItemTextA") +#pragma comment(linker, "/EXPORT:SetDlgItemTextW=user32.SetDlgItemTextW") +#pragma comment(linker, "/EXPORT:SetDoubleClickTime=user32.SetDoubleClickTime") +#pragma comment(linker, "/EXPORT:SetFocus=user32.SetFocus") +#pragma comment(linker, "/EXPORT:SetForegroundWindow=user32.SetForegroundWindow") +#pragma comment(linker, "/EXPORT:SetGestureConfig=user32.SetGestureConfig") +#pragma comment(linker, "/EXPORT:SetInternalWindowPos=user32.SetInternalWindowPos") +#pragma comment(linker, "/EXPORT:SetKeyboardState=user32.SetKeyboardState") +#pragma comment(linker, "/EXPORT:SetLastErrorEx=user32.SetLastErrorEx") +#pragma comment(linker, "/EXPORT:SetLayeredWindowAttributes=user32.SetLayeredWindowAttributes") +#pragma comment(linker, "/EXPORT:SetMagnificationDesktopColorEffect=user32.SetMagnificationDesktopColorEffect") +#pragma comment(linker, "/EXPORT:SetMagnificationDesktopMagnification=user32.SetMagnificationDesktopMagnification") +#pragma comment(linker, "/EXPORT:SetMagnificationLensCtxInformation=user32.SetMagnificationLensCtxInformation") +#pragma comment(linker, "/EXPORT:SetMenu=user32.SetMenu") +#pragma comment(linker, "/EXPORT:SetMenuContextHelpId=user32.SetMenuContextHelpId") +#pragma comment(linker, "/EXPORT:SetMenuDefaultItem=user32.SetMenuDefaultItem") +#pragma comment(linker, "/EXPORT:SetMenuInfo=user32.SetMenuInfo") +#pragma comment(linker, "/EXPORT:SetMenuItemBitmaps=user32.SetMenuItemBitmaps") +#pragma comment(linker, "/EXPORT:SetMenuItemInfoA=user32.SetMenuItemInfoA") +#pragma comment(linker, "/EXPORT:SetMenuItemInfoW=user32.SetMenuItemInfoW") +#pragma comment(linker, "/EXPORT:SetMessageExtraInfo=user32.SetMessageExtraInfo") +#pragma comment(linker, "/EXPORT:SetMessageQueue=user32.SetMessageQueue") +#pragma comment(linker, "/EXPORT:SetMirrorRendering=user32.SetMirrorRendering") +#pragma comment(linker, "/EXPORT:SetParent=user32.SetParent") +#pragma comment(linker, "/EXPORT:SetPhysicalCursorPos=user32.SetPhysicalCursorPos") +#pragma comment(linker, "/EXPORT:SetProcessDPIAware=user32.SetProcessDPIAware") +#pragma comment(linker, "/EXPORT:SetProcessDefaultLayout=user32.SetProcessDefaultLayout") +#pragma comment(linker, "/EXPORT:SetProcessWindowStation=user32.SetProcessWindowStation") +#pragma comment(linker, "/EXPORT:SetProgmanWindow=user32.SetProgmanWindow") +#pragma comment(linker, "/EXPORT:SetPropA=user32.SetPropA") +#pragma comment(linker, "/EXPORT:SetPropW=user32.SetPropW") +#pragma comment(linker, "/EXPORT:SetRect=user32.SetRect") +#pragma comment(linker, "/EXPORT:SetRectEmpty=user32.SetRectEmpty") +#pragma comment(linker, "/EXPORT:SetScrollInfo=user32.SetScrollInfo") +#pragma comment(linker, "/EXPORT:SetScrollPos=user32.SetScrollPos") +#pragma comment(linker, "/EXPORT:SetScrollRange=user32.SetScrollRange") +#pragma comment(linker, "/EXPORT:SetShellWindow=user32.SetShellWindow") +#pragma comment(linker, "/EXPORT:SetShellWindowEx=user32.SetShellWindowEx") +#pragma comment(linker, "/EXPORT:SetSysColors=user32.SetSysColors") +#pragma comment(linker, "/EXPORT:SetSysColorsTemp=user32.SetSysColorsTemp") +#pragma comment(linker, "/EXPORT:SetSystemCursor=user32.SetSystemCursor") +#pragma comment(linker, "/EXPORT:SetSystemMenu=user32.SetSystemMenu") +#pragma comment(linker, "/EXPORT:SetTaskmanWindow=user32.SetTaskmanWindow") +#pragma comment(linker, "/EXPORT:SetThreadDesktop=user32.SetThreadDesktop") +#pragma comment(linker, "/EXPORT:SetTimer=user32.SetTimer") +#pragma comment(linker, "/EXPORT:SetUserObjectInformationA=user32.SetUserObjectInformationA") +#pragma comment(linker, "/EXPORT:SetUserObjectInformationW=user32.SetUserObjectInformationW") +#pragma comment(linker, "/EXPORT:SetUserObjectSecurity=user32.SetUserObjectSecurity") +#pragma comment(linker, "/EXPORT:SetWinEventHook=user32.SetWinEventHook") +#pragma comment(linker, "/EXPORT:SetWindowCompositionAttribute=user32.SetWindowCompositionAttribute") +#pragma comment(linker, "/EXPORT:SetWindowContextHelpId=user32.SetWindowContextHelpId") +#pragma comment(linker, "/EXPORT:SetWindowDisplayAffinity=user32.SetWindowDisplayAffinity") +#pragma comment(linker, "/EXPORT:SetWindowLongA=user32.SetWindowLongA") +#pragma comment(linker, "/EXPORT:SetWindowLongW=user32.SetWindowLongW") +#pragma comment(linker, "/EXPORT:SetWindowPlacement=user32.SetWindowPlacement") +#pragma comment(linker, "/EXPORT:SetWindowPos=user32.SetWindowPos") +#pragma comment(linker, "/EXPORT:SetWindowRgn=user32.SetWindowRgn") +#pragma comment(linker, "/EXPORT:SetWindowRgnEx=user32.SetWindowRgnEx") +#pragma comment(linker, "/EXPORT:SetWindowStationUser=user32.SetWindowStationUser") +#pragma comment(linker, "/EXPORT:SetWindowTextA=user32.SetWindowTextA") +#pragma comment(linker, "/EXPORT:SetWindowTextW=user32.SetWindowTextW") +#pragma comment(linker, "/EXPORT:SetWindowWord=user32.SetWindowWord") +#pragma comment(linker, "/EXPORT:SetWindowsHookA=user32.SetWindowsHookA") +#pragma comment(linker, "/EXPORT:SetWindowsHookExA=user32.SetWindowsHookExA") +#pragma comment(linker, "/EXPORT:SetWindowsHookExW=user32.SetWindowsHookExW") +#pragma comment(linker, "/EXPORT:SetWindowsHookW=user32.SetWindowsHookW") +#pragma comment(linker, "/EXPORT:SfmDxBindSwapChain=user32.SfmDxBindSwapChain") +#pragma comment(linker, "/EXPORT:SfmDxGetSwapChainStats=user32.SfmDxGetSwapChainStats") +#pragma comment(linker, "/EXPORT:SfmDxOpenSwapChain=user32.SfmDxOpenSwapChain") +#pragma comment(linker, "/EXPORT:SfmDxQuerySwapChainBindingStatus=user32.SfmDxQuerySwapChainBindingStatus") +#pragma comment(linker, "/EXPORT:SfmDxReleaseSwapChain=user32.SfmDxReleaseSwapChain") +#pragma comment(linker, "/EXPORT:SfmDxReportPendingBindingsToDwm=user32.SfmDxReportPendingBindingsToDwm") +#pragma comment(linker, "/EXPORT:SfmDxSetSwapChainBindingStatus=user32.SfmDxSetSwapChainBindingStatus") +#pragma comment(linker, "/EXPORT:SfmDxSetSwapChainStats=user32.SfmDxSetSwapChainStats") +#pragma comment(linker, "/EXPORT:ShowCaret=user32.ShowCaret") +#pragma comment(linker, "/EXPORT:ShowCursor=user32.ShowCursor") +#pragma comment(linker, "/EXPORT:ShowOwnedPopups=user32.ShowOwnedPopups") +#pragma comment(linker, "/EXPORT:ShowScrollBar=user32.ShowScrollBar") +#pragma comment(linker, "/EXPORT:ShowStartGlass=user32.ShowStartGlass") +#pragma comment(linker, "/EXPORT:ShowSystemCursor=user32.ShowSystemCursor") +#pragma comment(linker, "/EXPORT:ShowWindow=user32.ShowWindow") +#pragma comment(linker, "/EXPORT:ShowWindowAsync=user32.ShowWindowAsync") +#pragma comment(linker, "/EXPORT:ShutdownBlockReasonCreate=user32.ShutdownBlockReasonCreate") +#pragma comment(linker, "/EXPORT:ShutdownBlockReasonDestroy=user32.ShutdownBlockReasonDestroy") +#pragma comment(linker, "/EXPORT:ShutdownBlockReasonQuery=user32.ShutdownBlockReasonQuery") +#pragma comment(linker, "/EXPORT:SoftModalMessageBox=user32.SoftModalMessageBox") +#pragma comment(linker, "/EXPORT:SoundSentry=user32.SoundSentry") +#pragma comment(linker, "/EXPORT:SubtractRect=user32.SubtractRect") +#pragma comment(linker, "/EXPORT:SwapMouseButton=user32.SwapMouseButton") +#pragma comment(linker, "/EXPORT:SwitchDesktop=user32.SwitchDesktop") +#pragma comment(linker, "/EXPORT:SwitchDesktopWithFade=user32.SwitchDesktopWithFade") +#pragma comment(linker, "/EXPORT:SwitchToThisWindow=user32.SwitchToThisWindow") +#pragma comment(linker, "/EXPORT:SystemParametersInfoA=user32.SystemParametersInfoA") +#pragma comment(linker, "/EXPORT:SystemParametersInfoW=user32.SystemParametersInfoW") +#pragma comment(linker, "/EXPORT:TabbedTextOutA=user32.TabbedTextOutA") +#pragma comment(linker, "/EXPORT:TabbedTextOutW=user32.TabbedTextOutW") +#pragma comment(linker, "/EXPORT:TileChildWindows=user32.TileChildWindows") +#pragma comment(linker, "/EXPORT:TileWindows=user32.TileWindows") +#pragma comment(linker, "/EXPORT:ToAscii=user32.ToAscii") +#pragma comment(linker, "/EXPORT:ToAsciiEx=user32.ToAsciiEx") +#pragma comment(linker, "/EXPORT:ToUnicode=user32.ToUnicode") +#pragma comment(linker, "/EXPORT:ToUnicodeEx=user32.ToUnicodeEx") +#pragma comment(linker, "/EXPORT:TrackMouseEvent=user32.TrackMouseEvent") +#pragma comment(linker, "/EXPORT:TrackPopupMenu=user32.TrackPopupMenu") +#pragma comment(linker, "/EXPORT:TrackPopupMenuEx=user32.TrackPopupMenuEx") +#pragma comment(linker, "/EXPORT:TranslateAccelerator=user32.TranslateAccelerator") +#pragma comment(linker, "/EXPORT:TranslateAcceleratorA=user32.TranslateAcceleratorA") +#pragma comment(linker, "/EXPORT:TranslateAcceleratorW=user32.TranslateAcceleratorW") +#pragma comment(linker, "/EXPORT:TranslateMDISysAccel=user32.TranslateMDISysAccel") +#pragma comment(linker, "/EXPORT:TranslateMessage=user32.TranslateMessage") +#pragma comment(linker, "/EXPORT:TranslateMessageEx=user32.TranslateMessageEx") +#pragma comment(linker, "/EXPORT:UnhookWinEvent=user32.UnhookWinEvent") +#pragma comment(linker, "/EXPORT:UnhookWindowsHook=user32.UnhookWindowsHook") +#pragma comment(linker, "/EXPORT:UnhookWindowsHookEx=user32.UnhookWindowsHookEx") +#pragma comment(linker, "/EXPORT:UnionRect=user32.UnionRect") +#pragma comment(linker, "/EXPORT:UnloadKeyboardLayout=user32.UnloadKeyboardLayout") +#pragma comment(linker, "/EXPORT:UnlockWindowStation=user32.UnlockWindowStation") +#pragma comment(linker, "/EXPORT:UnpackDDElParam=user32.UnpackDDElParam") +#pragma comment(linker, "/EXPORT:UnregisterClassA=user32.UnregisterClassA") +#pragma comment(linker, "/EXPORT:UnregisterClassW=user32.UnregisterClassW") +#pragma comment(linker, "/EXPORT:UnregisterDeviceNotification=user32.UnregisterDeviceNotification") +#pragma comment(linker, "/EXPORT:UnregisterHotKey=user32.UnregisterHotKey") +#pragma comment(linker, "/EXPORT:UnregisterMessagePumpHook=user32.UnregisterMessagePumpHook") +#pragma comment(linker, "/EXPORT:UnregisterPowerSettingNotification=user32.UnregisterPowerSettingNotification") +#pragma comment(linker, "/EXPORT:UnregisterSessionPort=user32.UnregisterSessionPort") +#pragma comment(linker, "/EXPORT:UnregisterTouchWindow=user32.UnregisterTouchWindow") +#pragma comment(linker, "/EXPORT:UnregisterUserApiHook=user32.UnregisterUserApiHook") +#pragma comment(linker, "/EXPORT:UpdateLayeredWindow=user32.UpdateLayeredWindow") +#pragma comment(linker, "/EXPORT:UpdateLayeredWindowIndirect=user32.UpdateLayeredWindowIndirect") +#pragma comment(linker, "/EXPORT:UpdatePerUserSystemParameters=user32.UpdatePerUserSystemParameters") +#pragma comment(linker, "/EXPORT:UpdateWindow=user32.UpdateWindow") +#pragma comment(linker, "/EXPORT:UpdateWindowTransform=user32.UpdateWindowTransform") +#pragma comment(linker, "/EXPORT:User32InitializeImmEntryTable=user32.User32InitializeImmEntryTable") +#pragma comment(linker, "/EXPORT:UserClientDllInitialize=user32.UserClientDllInitialize") +#pragma comment(linker, "/EXPORT:UserHandleGrantAccess=user32.UserHandleGrantAccess") +#pragma comment(linker, "/EXPORT:UserLpkPSMTextOut=user32.UserLpkPSMTextOut") +#pragma comment(linker, "/EXPORT:UserLpkTabbedTextOut=user32.UserLpkTabbedTextOut") +#pragma comment(linker, "/EXPORT:UserRealizePalette=user32.UserRealizePalette") +#pragma comment(linker, "/EXPORT:UserRegisterWowHandlers=user32.UserRegisterWowHandlers") +#pragma comment(linker, "/EXPORT:VRipOutput=user32.VRipOutput") +#pragma comment(linker, "/EXPORT:VTagOutput=user32.VTagOutput") +#pragma comment(linker, "/EXPORT:ValidateRect=user32.ValidateRect") +#pragma comment(linker, "/EXPORT:ValidateRgn=user32.ValidateRgn") +#pragma comment(linker, "/EXPORT:VkKeyScanA=user32.VkKeyScanA") +#pragma comment(linker, "/EXPORT:VkKeyScanExA=user32.VkKeyScanExA") +#pragma comment(linker, "/EXPORT:VkKeyScanExW=user32.VkKeyScanExW") +#pragma comment(linker, "/EXPORT:VkKeyScanW=user32.VkKeyScanW") +#pragma comment(linker, "/EXPORT:WCSToMBEx=user32.WCSToMBEx") +#pragma comment(linker, "/EXPORT:WINNLSEnableIME=user32.WINNLSEnableIME") +#pragma comment(linker, "/EXPORT:WINNLSGetEnableStatus=user32.WINNLSGetEnableStatus") +#pragma comment(linker, "/EXPORT:WINNLSGetIMEHotkey=user32.WINNLSGetIMEHotkey") +#pragma comment(linker, "/EXPORT:WaitForInputIdle=user32.WaitForInputIdle") +#pragma comment(linker, "/EXPORT:WaitMessage=user32.WaitMessage") +#pragma comment(linker, "/EXPORT:WinHelpA=user32.WinHelpA") +#pragma comment(linker, "/EXPORT:WinHelpW=user32.WinHelpW") +#pragma comment(linker, "/EXPORT:WindowFromDC=user32.WindowFromDC") +#pragma comment(linker, "/EXPORT:WindowFromPhysicalPoint=user32.WindowFromPhysicalPoint") +#pragma comment(linker, "/EXPORT:WindowFromPoint=user32.WindowFromPoint") +#pragma comment(linker, "/EXPORT:__UserTestTokenForInteractive=user32._UserTestTokenForInteractive") +#pragma comment(linker, "/EXPORT:gSharedInfo=user32.gSharedInfo") +#pragma comment(linker, "/EXPORT:gapfnScSendMessage=user32.gapfnScSendMessage") +#pragma comment(linker, "/EXPORT:keybd_event=user32.keybd_event") +#pragma comment(linker, "/EXPORT:mouse_event=user32.mouse_event") +#pragma comment(linker, "/EXPORT:wsprintfA=user32.wsprintfA") +#pragma comment(linker, "/EXPORT:wsprintfW=user32.wsprintfW") +#pragma comment(linker, "/EXPORT:wvsprintfA=user32.wvsprintfA") +#pragma comment(linker, "/EXPORT:wvsprintfW=user32.wvsprintfW") +#pragma comment(linker, "/EXPORT:__OrdinalFunction1500=user32.#1500,@1500,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction1501=user32.#1501,@1501,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction1550=user32.#1550,@1550,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction1551=user32.#1551,@1551,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction1552=user32.#1552,@1552,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction1553=user32.#1553,@1553,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction1554=user32.#1554,@1554,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction1555=user32.#1555,@1555,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction1556=user32.#1556,@1556,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2000=user32.#2000,@2000,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2001=user32.#2001,@2001,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2002=user32.#2002,@2002,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2005=user32.#2005,@2005,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2335=user32.#2335,@2335,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2336=user32.#2336,@2336,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2337=user32.#2337,@2337,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2338=user32.#2338,@2338,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2339=user32.#2339,@2339,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2340=user32.#2340,@2340,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2341=user32.#2341,@2341,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2342=user32.#2342,@2342,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2343=user32.#2343,@2343,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2344=user32.#2344,@2344,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2345=user32.#2345,@2345,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2346=user32.#2346,@2346,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2347=user32.#2347,@2347,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2348=user32.#2348,@2348,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2349=user32.#2349,@2349,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2350=user32.#2350,@2350,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2351=user32.#2351,@2351,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2352=user32.#2352,@2352,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2353=user32.#2353,@2353,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2354=user32.#2354,@2354,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2355=user32.#2355,@2355,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2356=user32.#2356,@2356,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2357=user32.#2357,@2357,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2358=user32.#2358,@2358,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2359=user32.#2359,@2359,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2360=user32.#2360,@2360,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2361=user32.#2361,@2361,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2362=user32.#2362,@2362,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2363=user32.#2363,@2363,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2364=user32.#2364,@2364,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2365=user32.#2365,@2365,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2366=user32.#2366,@2366,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2367=user32.#2367,@2367,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2368=user32.#2368,@2368,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2369=user32.#2369,@2369,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2370=user32.#2370,@2370,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2371=user32.#2371,@2371,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2372=user32.#2372,@2372,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2373=user32.#2373,@2373,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2374=user32.#2374,@2374,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2375=user32.#2375,@2375,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2376=user32.#2376,@2376,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2377=user32.#2377,@2377,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2378=user32.#2378,@2378,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2379=user32.#2379,@2379,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2380=user32.#2380,@2380,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2381=user32.#2381,@2381,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2382=user32.#2382,@2382,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2383=user32.#2383,@2383,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2384=user32.#2384,@2384,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2385=user32.#2385,@2385,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2386=user32.#2386,@2386,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2387=user32.#2387,@2387,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2388=user32.#2388,@2388,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2389=user32.#2389,@2389,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2390=user32.#2390,@2390,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2391=user32.#2391,@2391,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2392=user32.#2392,@2392,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2393=user32.#2393,@2393,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2394=user32.#2394,@2394,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2395=user32.#2395,@2395,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2396=user32.#2396,@2396,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2397=user32.#2397,@2397,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2398=user32.#2398,@2398,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2399=user32.#2399,@2399,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2400=user32.#2400,@2400,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2401=user32.#2401,@2401,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2402=user32.#2402,@2402,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2403=user32.#2403,@2403,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2404=user32.#2404,@2404,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2405=user32.#2405,@2405,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2406=user32.#2406,@2406,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2407=user32.#2407,@2407,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2408=user32.#2408,@2408,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2409=user32.#2409,@2409,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2410=user32.#2410,@2410,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2411=user32.#2411,@2411,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2412=user32.#2412,@2412,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2413=user32.#2413,@2413,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2414=user32.#2414,@2414,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2415=user32.#2415,@2415,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2416=user32.#2416,@2416,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2417=user32.#2417,@2417,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2418=user32.#2418,@2418,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2419=user32.#2419,@2419,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2420=user32.#2420,@2420,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2421=user32.#2421,@2421,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2422=user32.#2422,@2422,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2423=user32.#2423,@2423,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2424=user32.#2424,@2424,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2425=user32.#2425,@2425,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2426=user32.#2426,@2426,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2427=user32.#2427,@2427,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2428=user32.#2428,@2428,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2429=user32.#2429,@2429,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2430=user32.#2430,@2430,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2431=user32.#2431,@2431,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2432=user32.#2432,@2432,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2433=user32.#2433,@2433,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2434=user32.#2434,@2434,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2435=user32.#2435,@2435,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2436=user32.#2436,@2436,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2437=user32.#2437,@2437,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2438=user32.#2438,@2438,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2439=user32.#2439,@2439,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2440=user32.#2440,@2440,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2441=user32.#2441,@2441,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2442=user32.#2442,@2442,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2443=user32.#2443,@2443,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2444=user32.#2444,@2444,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2445=user32.#2445,@2445,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2446=user32.#2446,@2446,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2447=user32.#2447,@2447,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2448=user32.#2448,@2448,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2449=user32.#2449,@2449,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2450=user32.#2450,@2450,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2451=user32.#2451,@2451,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2452=user32.#2452,@2452,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2453=user32.#2453,@2453,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2454=user32.#2454,@2454,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2455=user32.#2455,@2455,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2456=user32.#2456,@2456,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2457=user32.#2457,@2457,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2458=user32.#2458,@2458,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2459=user32.#2459,@2459,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2460=user32.#2460,@2460,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2461=user32.#2461,@2461,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2462=user32.#2462,@2462,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2463=user32.#2463,@2463,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2464=user32.#2464,@2464,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2465=user32.#2465,@2465,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2466=user32.#2466,@2466,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2467=user32.#2467,@2467,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2468=user32.#2468,@2468,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2469=user32.#2469,@2469,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2470=user32.#2470,@2470,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2471=user32.#2471,@2471,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2472=user32.#2472,@2472,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2473=user32.#2473,@2473,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2474=user32.#2474,@2474,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2475=user32.#2475,@2475,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2476=user32.#2476,@2476,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2477=user32.#2477,@2477,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2478=user32.#2478,@2478,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2479=user32.#2479,@2479,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2480=user32.#2480,@2480,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2481=user32.#2481,@2481,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2482=user32.#2482,@2482,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2483=user32.#2483,@2483,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2484=user32.#2484,@2484,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2485=user32.#2485,@2485,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2486=user32.#2486,@2486,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2487=user32.#2487,@2487,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2488=user32.#2488,@2488,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2489=user32.#2489,@2489,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2490=user32.#2490,@2490,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2491=user32.#2491,@2491,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2492=user32.#2492,@2492,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2493=user32.#2493,@2493,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2494=user32.#2494,@2494,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2495=user32.#2495,@2495,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2496=user32.#2496,@2496,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2497=user32.#2497,@2497,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2498=user32.#2498,@2498,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2499=user32.#2499,@2499,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2500=user32.#2500,@2500,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2501=user32.#2501,@2501,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction2502=user32.#2502,@2502,NONAME") + + +// Generated by KexExprt from "C:\Windows\syswow64\shell32.dll" +#pragma comment(linker, "/EXPORT:AppCompat_RunDLLW=shell32.AppCompat_RunDLLW") +#pragma comment(linker, "/EXPORT:AssocCreateForClasses=shell32.AssocCreateForClasses") +#pragma comment(linker, "/EXPORT:AssocGetDetailsOfPropKey=shell32.AssocGetDetailsOfPropKey") +#pragma comment(linker, "/EXPORT:CDefFolderMenu_Create2=shell32.CDefFolderMenu_Create2") +#pragma comment(linker, "/EXPORT:CIDLData_CreateFromIDArray=shell32.CIDLData_CreateFromIDArray") +#pragma comment(linker, "/EXPORT:CheckEscapesW=shell32.CheckEscapesW") +#pragma comment(linker, "/EXPORT:CommandLineToArgvW=shell32.CommandLineToArgvW") +#pragma comment(linker, "/EXPORT:Control_RunDLL=shell32.Control_RunDLL") +#pragma comment(linker, "/EXPORT:Control_RunDLLA=shell32.Control_RunDLLA") +#pragma comment(linker, "/EXPORT:Control_RunDLLAsUserW=shell32.Control_RunDLLAsUserW") +#pragma comment(linker, "/EXPORT:Control_RunDLLW=shell32.Control_RunDLLW") +#pragma comment(linker, "/EXPORT:DAD_AutoScroll=shell32.DAD_AutoScroll") +#pragma comment(linker, "/EXPORT:DAD_DragEnterEx=shell32.DAD_DragEnterEx") +#pragma comment(linker, "/EXPORT:DAD_DragEnterEx2=shell32.DAD_DragEnterEx2") +#pragma comment(linker, "/EXPORT:DAD_DragLeave=shell32.DAD_DragLeave") +#pragma comment(linker, "/EXPORT:DAD_DragMove=shell32.DAD_DragMove") +#pragma comment(linker, "/EXPORT:DAD_SetDragImage=shell32.DAD_SetDragImage") +#pragma comment(linker, "/EXPORT:DAD_ShowDragImage=shell32.DAD_ShowDragImage") +#pragma comment(linker, "/EXPORT:DllCanUnloadNow=shell32.DllCanUnloadNow") +#pragma comment(linker, "/EXPORT:DllGetClassObject=shell32.DllGetClassObject") +#pragma comment(linker, "/EXPORT:DllGetVersion=shell32.DllGetVersion") +#pragma comment(linker, "/EXPORT:DllInstall=shell32.DllInstall") +#pragma comment(linker, "/EXPORT:DllRegisterServer=shell32.DllRegisterServer") +#pragma comment(linker, "/EXPORT:DllUnregisterServer=shell32.DllUnregisterServer") +#pragma comment(linker, "/EXPORT:DoEnvironmentSubstA=shell32.DoEnvironmentSubstA") +#pragma comment(linker, "/EXPORT:DoEnvironmentSubstW=shell32.DoEnvironmentSubstW") +#pragma comment(linker, "/EXPORT:DragAcceptFiles=shell32.DragAcceptFiles") +#pragma comment(linker, "/EXPORT:DragFinish=shell32.DragFinish") +#pragma comment(linker, "/EXPORT:DragQueryFile=shell32.DragQueryFile") +#pragma comment(linker, "/EXPORT:DragQueryFileA=shell32.DragQueryFileA") +#pragma comment(linker, "/EXPORT:DragQueryFileAorW=shell32.DragQueryFileAorW") +#pragma comment(linker, "/EXPORT:DragQueryFileW=shell32.DragQueryFileW") +#pragma comment(linker, "/EXPORT:DragQueryPoint=shell32.DragQueryPoint") +#pragma comment(linker, "/EXPORT:DriveType=shell32.DriveType") +#pragma comment(linker, "/EXPORT:DuplicateIcon=shell32.DuplicateIcon") +#pragma comment(linker, "/EXPORT:ExtractAssociatedIconA=shell32.ExtractAssociatedIconA") +#pragma comment(linker, "/EXPORT:ExtractAssociatedIconExA=shell32.ExtractAssociatedIconExA") +#pragma comment(linker, "/EXPORT:ExtractAssociatedIconExW=shell32.ExtractAssociatedIconExW") +#pragma comment(linker, "/EXPORT:ExtractAssociatedIconW=shell32.ExtractAssociatedIconW") +#pragma comment(linker, "/EXPORT:ExtractIconA=shell32.ExtractIconA") +#pragma comment(linker, "/EXPORT:ExtractIconEx=shell32.ExtractIconEx") +#pragma comment(linker, "/EXPORT:ExtractIconExA=shell32.ExtractIconExA") +#pragma comment(linker, "/EXPORT:ExtractIconExW=shell32.ExtractIconExW") +#pragma comment(linker, "/EXPORT:ExtractIconW=shell32.ExtractIconW") +#pragma comment(linker, "/EXPORT:FindExecutableA=shell32.FindExecutableA") +#pragma comment(linker, "/EXPORT:FindExecutableW=shell32.FindExecutableW") +#pragma comment(linker, "/EXPORT:FreeIconList=shell32.FreeIconList") +#pragma comment(linker, "/EXPORT:GetCurrentProcessExplicitAppUserModelID=shell32.GetCurrentProcessExplicitAppUserModelID") +#pragma comment(linker, "/EXPORT:GetFileNameFromBrowse=shell32.GetFileNameFromBrowse") +#pragma comment(linker, "/EXPORT:ILAppendID=shell32.ILAppendID") +#pragma comment(linker, "/EXPORT:ILClone=shell32.ILClone") +#pragma comment(linker, "/EXPORT:ILCloneFirst=shell32.ILCloneFirst") +#pragma comment(linker, "/EXPORT:ILCombine=shell32.ILCombine") +#pragma comment(linker, "/EXPORT:ILCreateFromPath=shell32.ILCreateFromPath") +#pragma comment(linker, "/EXPORT:ILCreateFromPathA=shell32.ILCreateFromPathA") +#pragma comment(linker, "/EXPORT:ILCreateFromPathW=shell32.ILCreateFromPathW") +#pragma comment(linker, "/EXPORT:ILFindChild=shell32.ILFindChild") +#pragma comment(linker, "/EXPORT:ILFindLastID=shell32.ILFindLastID") +#pragma comment(linker, "/EXPORT:ILFree=shell32.ILFree") +#pragma comment(linker, "/EXPORT:ILGetNext=shell32.ILGetNext") +#pragma comment(linker, "/EXPORT:ILGetSize=shell32.ILGetSize") +#pragma comment(linker, "/EXPORT:ILIsEqual=shell32.ILIsEqual") +#pragma comment(linker, "/EXPORT:ILIsParent=shell32.ILIsParent") +#pragma comment(linker, "/EXPORT:ILLoadFromStreamEx=shell32.ILLoadFromStreamEx") +#pragma comment(linker, "/EXPORT:ILRemoveLastID=shell32.ILRemoveLastID") +#pragma comment(linker, "/EXPORT:ILSaveToStream=shell32.ILSaveToStream") +#pragma comment(linker, "/EXPORT:InitNetworkAddressControl=shell32.InitNetworkAddressControl") +#pragma comment(linker, "/EXPORT:InternalExtractIconListA=shell32.InternalExtractIconListA") +#pragma comment(linker, "/EXPORT:InternalExtractIconListW=shell32.InternalExtractIconListW") +#pragma comment(linker, "/EXPORT:IsLFNDrive=shell32.IsLFNDrive") +#pragma comment(linker, "/EXPORT:IsLFNDriveA=shell32.IsLFNDriveA") +#pragma comment(linker, "/EXPORT:IsLFNDriveW=shell32.IsLFNDriveW") +#pragma comment(linker, "/EXPORT:IsNetDrive=shell32.IsNetDrive") +#pragma comment(linker, "/EXPORT:IsUserAnAdmin=shell32.IsUserAnAdmin") +#pragma comment(linker, "/EXPORT:LaunchMSHelp_RunDLLW=shell32.LaunchMSHelp_RunDLLW") +#pragma comment(linker, "/EXPORT:OpenAs_RunDLL=shell32.OpenAs_RunDLL") +#pragma comment(linker, "/EXPORT:OpenAs_RunDLLA=shell32.OpenAs_RunDLLA") +#pragma comment(linker, "/EXPORT:OpenAs_RunDLLW=shell32.OpenAs_RunDLLW") +#pragma comment(linker, "/EXPORT:OpenRegStream=shell32.OpenRegStream") +#pragma comment(linker, "/EXPORT:Options_RunDLL=shell32.Options_RunDLL") +#pragma comment(linker, "/EXPORT:Options_RunDLLA=shell32.Options_RunDLLA") +#pragma comment(linker, "/EXPORT:Options_RunDLLW=shell32.Options_RunDLLW") +#pragma comment(linker, "/EXPORT:PathCleanupSpec=shell32.PathCleanupSpec") +#pragma comment(linker, "/EXPORT:PathGetShortPath=shell32.PathGetShortPath") +#pragma comment(linker, "/EXPORT:PathIsExe=shell32.PathIsExe") +#pragma comment(linker, "/EXPORT:PathIsSlowA=shell32.PathIsSlowA") +#pragma comment(linker, "/EXPORT:PathIsSlowW=shell32.PathIsSlowW") +#pragma comment(linker, "/EXPORT:PathMakeUniqueName=shell32.PathMakeUniqueName") +#pragma comment(linker, "/EXPORT:PathQualify=shell32.PathQualify") +#pragma comment(linker, "/EXPORT:PathResolve=shell32.PathResolve") +#pragma comment(linker, "/EXPORT:PathYetAnotherMakeUniqueName=shell32.PathYetAnotherMakeUniqueName") +#pragma comment(linker, "/EXPORT:PickIconDlg=shell32.PickIconDlg") +#pragma comment(linker, "/EXPORT:PifMgr_CloseProperties=shell32.PifMgr_CloseProperties") +#pragma comment(linker, "/EXPORT:PifMgr_GetProperties=shell32.PifMgr_GetProperties") +#pragma comment(linker, "/EXPORT:PifMgr_OpenProperties=shell32.PifMgr_OpenProperties") +#pragma comment(linker, "/EXPORT:PifMgr_SetProperties=shell32.PifMgr_SetProperties") +#pragma comment(linker, "/EXPORT:PrepareDiscForBurnRunDllW=shell32.PrepareDiscForBurnRunDllW") +#pragma comment(linker, "/EXPORT:PrintersGetCommand_RunDLL=shell32.PrintersGetCommand_RunDLL") +#pragma comment(linker, "/EXPORT:PrintersGetCommand_RunDLLA=shell32.PrintersGetCommand_RunDLLA") +#pragma comment(linker, "/EXPORT:PrintersGetCommand_RunDLLW=shell32.PrintersGetCommand_RunDLLW") +#pragma comment(linker, "/EXPORT:ReadCabinetState=shell32.ReadCabinetState") +#pragma comment(linker, "/EXPORT:RealDriveType=shell32.RealDriveType") +#pragma comment(linker, "/EXPORT:RealShellExecuteA=shell32.RealShellExecuteA") +#pragma comment(linker, "/EXPORT:RealShellExecuteExA=shell32.RealShellExecuteExA") +#pragma comment(linker, "/EXPORT:RealShellExecuteExW=shell32.RealShellExecuteExW") +#pragma comment(linker, "/EXPORT:RealShellExecuteW=shell32.RealShellExecuteW") +#pragma comment(linker, "/EXPORT:RegenerateUserEnvironment=shell32.RegenerateUserEnvironment") +#pragma comment(linker, "/EXPORT:RestartDialog=shell32.RestartDialog") +#pragma comment(linker, "/EXPORT:RestartDialogEx=shell32.RestartDialogEx") +#pragma comment(linker, "/EXPORT:RunAsNewUser_RunDLLW=shell32.RunAsNewUser_RunDLLW") +#pragma comment(linker, "/EXPORT:SHAddDefaultPropertiesByExt=shell32.SHAddDefaultPropertiesByExt") +#pragma comment(linker, "/EXPORT:SHAddFromPropSheetExtArray=shell32.SHAddFromPropSheetExtArray") +#pragma comment(linker, "/EXPORT:SHAddToRecentDocs=shell32.SHAddToRecentDocs") +#pragma comment(linker, "/EXPORT:SHAlloc=shell32.SHAlloc") +#pragma comment(linker, "/EXPORT:SHAppBarMessage=shell32.SHAppBarMessage") +#pragma comment(linker, "/EXPORT:SHAssocEnumHandlers=shell32.SHAssocEnumHandlers") +#pragma comment(linker, "/EXPORT:SHAssocEnumHandlersForProtocolByApplication=shell32.SHAssocEnumHandlersForProtocolByApplication") +#pragma comment(linker, "/EXPORT:SHBindToFolderIDListParent=shell32.SHBindToFolderIDListParent") +#pragma comment(linker, "/EXPORT:SHBindToFolderIDListParentEx=shell32.SHBindToFolderIDListParentEx") +#pragma comment(linker, "/EXPORT:SHBindToObject=shell32.SHBindToObject") +#pragma comment(linker, "/EXPORT:SHBindToParent=shell32.SHBindToParent") +#pragma comment(linker, "/EXPORT:SHBrowseForFolder=shell32.SHBrowseForFolder") +#pragma comment(linker, "/EXPORT:SHBrowseForFolderA=shell32.SHBrowseForFolderA") +#pragma comment(linker, "/EXPORT:SHBrowseForFolderW=shell32.SHBrowseForFolderW") +#pragma comment(linker, "/EXPORT:SHCLSIDFromString=shell32.SHCLSIDFromString") +#pragma comment(linker, "/EXPORT:SHChangeNotification_Lock=shell32.SHChangeNotification_Lock") +#pragma comment(linker, "/EXPORT:SHChangeNotification_Unlock=shell32.SHChangeNotification_Unlock") +#pragma comment(linker, "/EXPORT:SHChangeNotify=shell32.SHChangeNotify") +#pragma comment(linker, "/EXPORT:SHChangeNotifyDeregister=shell32.SHChangeNotifyDeregister") +#pragma comment(linker, "/EXPORT:SHChangeNotifyRegister=shell32.SHChangeNotifyRegister") +#pragma comment(linker, "/EXPORT:SHChangeNotifyRegisterThread=shell32.SHChangeNotifyRegisterThread") +#pragma comment(linker, "/EXPORT:SHChangeNotifySuspendResume=shell32.SHChangeNotifySuspendResume") +#pragma comment(linker, "/EXPORT:SHCloneSpecialIDList=shell32.SHCloneSpecialIDList") +#pragma comment(linker, "/EXPORT:SHCoCreateInstance=shell32.SHCoCreateInstance") +#pragma comment(linker, "/EXPORT:SHCreateAssociationRegistration=shell32.SHCreateAssociationRegistration") +#pragma comment(linker, "/EXPORT:SHCreateDataObject=shell32.SHCreateDataObject") +#pragma comment(linker, "/EXPORT:SHCreateDefaultContextMenu=shell32.SHCreateDefaultContextMenu") +#pragma comment(linker, "/EXPORT:SHCreateDefaultExtractIcon=shell32.SHCreateDefaultExtractIcon") +#pragma comment(linker, "/EXPORT:SHCreateDefaultPropertiesOp=shell32.SHCreateDefaultPropertiesOp") +#pragma comment(linker, "/EXPORT:SHCreateDirectory=shell32.SHCreateDirectory") +#pragma comment(linker, "/EXPORT:SHCreateDirectoryExA=shell32.SHCreateDirectoryExA") +#pragma comment(linker, "/EXPORT:SHCreateDirectoryExW=shell32.SHCreateDirectoryExW") +#pragma comment(linker, "/EXPORT:SHCreateFileExtractIconW=shell32.SHCreateFileExtractIconW") +#pragma comment(linker, "/EXPORT:SHCreateItemFromIDList=shell32.SHCreateItemFromIDList") +#pragma comment(linker, "/EXPORT:SHCreateItemFromParsingName=shell32.SHCreateItemFromParsingName") +#pragma comment(linker, "/EXPORT:SHCreateItemFromRelativeName=shell32.SHCreateItemFromRelativeName") +#pragma comment(linker, "/EXPORT:SHCreateItemInKnownFolder=shell32.SHCreateItemInKnownFolder") +#pragma comment(linker, "/EXPORT:SHCreateItemWithParent=shell32.SHCreateItemWithParent") +#pragma comment(linker, "/EXPORT:SHCreateLocalServerRunDll=shell32.SHCreateLocalServerRunDll") +#pragma comment(linker, "/EXPORT:SHCreateProcessAsUserW=shell32.SHCreateProcessAsUserW") +#pragma comment(linker, "/EXPORT:SHCreatePropSheetExtArray=shell32.SHCreatePropSheetExtArray") +#pragma comment(linker, "/EXPORT:SHCreateQueryCancelAutoPlayMoniker=shell32.SHCreateQueryCancelAutoPlayMoniker") +#pragma comment(linker, "/EXPORT:SHCreateShellFolderView=shell32.SHCreateShellFolderView") +#pragma comment(linker, "/EXPORT:SHCreateShellFolderViewEx=shell32.SHCreateShellFolderViewEx") +#pragma comment(linker, "/EXPORT:SHCreateShellItem=shell32.SHCreateShellItem") +#pragma comment(linker, "/EXPORT:SHCreateShellItemArray=shell32.SHCreateShellItemArray") +#pragma comment(linker, "/EXPORT:SHCreateShellItemArrayFromDataObject=shell32.SHCreateShellItemArrayFromDataObject") +#pragma comment(linker, "/EXPORT:SHCreateShellItemArrayFromIDLists=shell32.SHCreateShellItemArrayFromIDLists") +#pragma comment(linker, "/EXPORT:SHCreateShellItemArrayFromShellItem=shell32.SHCreateShellItemArrayFromShellItem") +#pragma comment(linker, "/EXPORT:SHCreateStdEnumFmtEtc=shell32.SHCreateStdEnumFmtEtc") +#pragma comment(linker, "/EXPORT:SHDefExtractIconA=shell32.SHDefExtractIconA") +#pragma comment(linker, "/EXPORT:SHDefExtractIconW=shell32.SHDefExtractIconW") +#pragma comment(linker, "/EXPORT:SHDestroyPropSheetExtArray=shell32.SHDestroyPropSheetExtArray") +#pragma comment(linker, "/EXPORT:SHDoDragDrop=shell32.SHDoDragDrop") +#pragma comment(linker, "/EXPORT:SHEmptyRecycleBinA=shell32.SHEmptyRecycleBinA") +#pragma comment(linker, "/EXPORT:SHEmptyRecycleBinW=shell32.SHEmptyRecycleBinW") +#pragma comment(linker, "/EXPORT:SHEnableServiceObject=shell32.SHEnableServiceObject") +#pragma comment(linker, "/EXPORT:SHEnumerateUnreadMailAccountsW=shell32.SHEnumerateUnreadMailAccountsW") +#pragma comment(linker, "/EXPORT:SHEvaluateSystemCommandTemplate=shell32.SHEvaluateSystemCommandTemplate") +#pragma comment(linker, "/EXPORT:SHExtractIconsW=shell32.SHExtractIconsW") +#pragma comment(linker, "/EXPORT:SHFileOperation=shell32.SHFileOperation") +#pragma comment(linker, "/EXPORT:SHFileOperationA=shell32.SHFileOperationA") +#pragma comment(linker, "/EXPORT:SHFileOperationW=shell32.SHFileOperationW") +#pragma comment(linker, "/EXPORT:SHFindFiles=shell32.SHFindFiles") +#pragma comment(linker, "/EXPORT:SHFind_InitMenuPopup=shell32.SHFind_InitMenuPopup") +#pragma comment(linker, "/EXPORT:SHFlushSFCache=shell32.SHFlushSFCache") +#pragma comment(linker, "/EXPORT:SHFormatDrive=shell32.SHFormatDrive") +#pragma comment(linker, "/EXPORT:SHFree=shell32.SHFree") +#pragma comment(linker, "/EXPORT:SHFreeNameMappings=shell32.SHFreeNameMappings") +#pragma comment(linker, "/EXPORT:SHGetAttributesFromDataObject=shell32.SHGetAttributesFromDataObject") +#pragma comment(linker, "/EXPORT:SHGetDataFromIDListA=shell32.SHGetDataFromIDListA") +#pragma comment(linker, "/EXPORT:SHGetDataFromIDListW=shell32.SHGetDataFromIDListW") +#pragma comment(linker, "/EXPORT:SHGetDesktopFolder=shell32.SHGetDesktopFolder") +#pragma comment(linker, "/EXPORT:SHGetDiskFreeSpaceA=shell32.SHGetDiskFreeSpaceA") +#pragma comment(linker, "/EXPORT:SHGetDiskFreeSpaceExA=shell32.SHGetDiskFreeSpaceExA") +#pragma comment(linker, "/EXPORT:SHGetDiskFreeSpaceExW=shell32.SHGetDiskFreeSpaceExW") +#pragma comment(linker, "/EXPORT:SHGetDriveMedia=shell32.SHGetDriveMedia") +#pragma comment(linker, "/EXPORT:SHGetFileInfo=shell32.SHGetFileInfo") +#pragma comment(linker, "/EXPORT:SHGetFileInfoA=shell32.SHGetFileInfoA") +#pragma comment(linker, "/EXPORT:SHGetFileInfoW=shell32.SHGetFileInfoW") +#pragma comment(linker, "/EXPORT:SHGetFolderLocation=shell32.SHGetFolderLocation") +#pragma comment(linker, "/EXPORT:SHGetFolderPathA=shell32.SHGetFolderPathA") +#pragma comment(linker, "/EXPORT:SHGetFolderPathAndSubDirA=shell32.SHGetFolderPathAndSubDirA") +#pragma comment(linker, "/EXPORT:SHGetFolderPathAndSubDirW=shell32.SHGetFolderPathAndSubDirW") +#pragma comment(linker, "/EXPORT:SHGetFolderPathEx=shell32.SHGetFolderPathEx") +#pragma comment(linker, "/EXPORT:SHGetFolderPathW=shell32.SHGetFolderPathW") +#pragma comment(linker, "/EXPORT:SHGetIDListFromObject=shell32.SHGetIDListFromObject") +#pragma comment(linker, "/EXPORT:SHGetIconOverlayIndexA=shell32.SHGetIconOverlayIndexA") +#pragma comment(linker, "/EXPORT:SHGetIconOverlayIndexW=shell32.SHGetIconOverlayIndexW") +#pragma comment(linker, "/EXPORT:SHGetImageList=shell32.SHGetImageList") +#pragma comment(linker, "/EXPORT:SHGetInstanceExplorer=shell32.SHGetInstanceExplorer") +#pragma comment(linker, "/EXPORT:SHGetItemFromDataObject=shell32.SHGetItemFromDataObject") +#pragma comment(linker, "/EXPORT:SHGetItemFromObject=shell32.SHGetItemFromObject") +#pragma comment(linker, "/EXPORT:SHGetKnownFolderIDList=shell32.SHGetKnownFolderIDList") +#pragma comment(linker, "/EXPORT:SHGetKnownFolderItem=shell32.SHGetKnownFolderItem") +#pragma comment(linker, "/EXPORT:SHGetKnownFolderPath=shell32.SHGetKnownFolderPath") +#pragma comment(linker, "/EXPORT:SHGetLocalizedName=shell32.SHGetLocalizedName") +#pragma comment(linker, "/EXPORT:SHGetMalloc=shell32.SHGetMalloc") +#pragma comment(linker, "/EXPORT:SHGetNameFromIDList=shell32.SHGetNameFromIDList") +#pragma comment(linker, "/EXPORT:SHGetNewLinkInfo=shell32.SHGetNewLinkInfo") +#pragma comment(linker, "/EXPORT:SHGetNewLinkInfoA=shell32.SHGetNewLinkInfoA") +#pragma comment(linker, "/EXPORT:SHGetNewLinkInfoW=shell32.SHGetNewLinkInfoW") +#pragma comment(linker, "/EXPORT:SHGetPathFromIDList=shell32.SHGetPathFromIDList") +#pragma comment(linker, "/EXPORT:SHGetPathFromIDListA=shell32.SHGetPathFromIDListA") +#pragma comment(linker, "/EXPORT:SHGetPathFromIDListEx=shell32.SHGetPathFromIDListEx") +#pragma comment(linker, "/EXPORT:SHGetPathFromIDListW=shell32.SHGetPathFromIDListW") +#pragma comment(linker, "/EXPORT:SHGetPropertyStoreForWindow=shell32.SHGetPropertyStoreForWindow") +#pragma comment(linker, "/EXPORT:SHGetPropertyStoreFromIDList=shell32.SHGetPropertyStoreFromIDList") +#pragma comment(linker, "/EXPORT:SHGetPropertyStoreFromParsingName=shell32.SHGetPropertyStoreFromParsingName") +#pragma comment(linker, "/EXPORT:SHGetRealIDL=shell32.SHGetRealIDL") +#pragma comment(linker, "/EXPORT:SHGetSetFolderCustomSettings=shell32.SHGetSetFolderCustomSettings") +#pragma comment(linker, "/EXPORT:SHGetSetSettings=shell32.SHGetSetSettings") +#pragma comment(linker, "/EXPORT:SHGetSettings=shell32.SHGetSettings") +#pragma comment(linker, "/EXPORT:SHGetSpecialFolderLocation=shell32.SHGetSpecialFolderLocation") +#pragma comment(linker, "/EXPORT:SHGetSpecialFolderPathA=shell32.SHGetSpecialFolderPathA") +#pragma comment(linker, "/EXPORT:SHGetSpecialFolderPathW=shell32.SHGetSpecialFolderPathW") +#pragma comment(linker, "/EXPORT:SHGetStockIconInfo=shell32.SHGetStockIconInfo") +#pragma comment(linker, "/EXPORT:SHGetTemporaryPropertyForItem=shell32.SHGetTemporaryPropertyForItem") +#pragma comment(linker, "/EXPORT:SHGetUnreadMailCountW=shell32.SHGetUnreadMailCountW") +#pragma comment(linker, "/EXPORT:SHHandleUpdateImage=shell32.SHHandleUpdateImage") +#pragma comment(linker, "/EXPORT:SHHelpShortcuts_RunDLL=shell32.SHHelpShortcuts_RunDLL") +#pragma comment(linker, "/EXPORT:SHHelpShortcuts_RunDLLA=shell32.SHHelpShortcuts_RunDLLA") +#pragma comment(linker, "/EXPORT:SHHelpShortcuts_RunDLLW=shell32.SHHelpShortcuts_RunDLLW") +#pragma comment(linker, "/EXPORT:SHILCreateFromPath=shell32.SHILCreateFromPath") +#pragma comment(linker, "/EXPORT:SHInvokePrinterCommandA=shell32.SHInvokePrinterCommandA") +#pragma comment(linker, "/EXPORT:SHInvokePrinterCommandW=shell32.SHInvokePrinterCommandW") +#pragma comment(linker, "/EXPORT:SHIsFileAvailableOffline=shell32.SHIsFileAvailableOffline") +#pragma comment(linker, "/EXPORT:SHLimitInputEdit=shell32.SHLimitInputEdit") +#pragma comment(linker, "/EXPORT:SHLoadInProc=shell32.SHLoadInProc") +#pragma comment(linker, "/EXPORT:SHLoadNonloadedIconOverlayIdentifiers=shell32.SHLoadNonloadedIconOverlayIdentifiers") +#pragma comment(linker, "/EXPORT:SHMapPIDLToSystemImageListIndex=shell32.SHMapPIDLToSystemImageListIndex") +#pragma comment(linker, "/EXPORT:SHMultiFileProperties=shell32.SHMultiFileProperties") +#pragma comment(linker, "/EXPORT:SHObjectProperties=shell32.SHObjectProperties") +#pragma comment(linker, "/EXPORT:SHOpenFolderAndSelectItems=shell32.SHOpenFolderAndSelectItems") +#pragma comment(linker, "/EXPORT:SHOpenPropSheetW=shell32.SHOpenPropSheetW") +#pragma comment(linker, "/EXPORT:SHOpenWithDialog=shell32.SHOpenWithDialog") +#pragma comment(linker, "/EXPORT:SHParseDisplayName=shell32.SHParseDisplayName") +#pragma comment(linker, "/EXPORT:SHPathPrepareForWriteA=shell32.SHPathPrepareForWriteA") +#pragma comment(linker, "/EXPORT:SHPathPrepareForWriteW=shell32.SHPathPrepareForWriteW") +#pragma comment(linker, "/EXPORT:SHPropStgCreate=shell32.SHPropStgCreate") +#pragma comment(linker, "/EXPORT:SHPropStgReadMultiple=shell32.SHPropStgReadMultiple") +#pragma comment(linker, "/EXPORT:SHPropStgWriteMultiple=shell32.SHPropStgWriteMultiple") +#pragma comment(linker, "/EXPORT:SHQueryRecycleBinA=shell32.SHQueryRecycleBinA") +#pragma comment(linker, "/EXPORT:SHQueryRecycleBinW=shell32.SHQueryRecycleBinW") +#pragma comment(linker, "/EXPORT:SHQueryUserNotificationState=shell32.SHQueryUserNotificationState") +#pragma comment(linker, "/EXPORT:SHRemoveLocalizedName=shell32.SHRemoveLocalizedName") +#pragma comment(linker, "/EXPORT:SHReplaceFromPropSheetExtArray=shell32.SHReplaceFromPropSheetExtArray") +#pragma comment(linker, "/EXPORT:SHResolveLibrary=shell32.SHResolveLibrary") +#pragma comment(linker, "/EXPORT:SHRestricted=shell32.SHRestricted") +#pragma comment(linker, "/EXPORT:SHSetDefaultProperties=shell32.SHSetDefaultProperties") +#pragma comment(linker, "/EXPORT:SHSetFolderPathA=shell32.SHSetFolderPathA") +#pragma comment(linker, "/EXPORT:SHSetFolderPathW=shell32.SHSetFolderPathW") +#pragma comment(linker, "/EXPORT:SHSetInstanceExplorer=shell32.SHSetInstanceExplorer") +#pragma comment(linker, "/EXPORT:SHSetKnownFolderPath=shell32.SHSetKnownFolderPath") +#pragma comment(linker, "/EXPORT:SHSetLocalizedName=shell32.SHSetLocalizedName") +#pragma comment(linker, "/EXPORT:SHSetTemporaryPropertyForItem=shell32.SHSetTemporaryPropertyForItem") +#pragma comment(linker, "/EXPORT:SHSetUnreadMailCountW=shell32.SHSetUnreadMailCountW") +#pragma comment(linker, "/EXPORT:SHShellFolderView_Message=shell32.SHShellFolderView_Message") +#pragma comment(linker, "/EXPORT:SHShowManageLibraryUI=shell32.SHShowManageLibraryUI") +#pragma comment(linker, "/EXPORT:SHSimpleIDListFromPath=shell32.SHSimpleIDListFromPath") +#pragma comment(linker, "/EXPORT:SHStartNetConnectionDialogW=shell32.SHStartNetConnectionDialogW") +#pragma comment(linker, "/EXPORT:SHTestTokenMembership=shell32.SHTestTokenMembership") +#pragma comment(linker, "/EXPORT:SHUpdateImageA=shell32.SHUpdateImageA") +#pragma comment(linker, "/EXPORT:SHUpdateImageW=shell32.SHUpdateImageW") +#pragma comment(linker, "/EXPORT:SHUpdateRecycleBinIcon=shell32.SHUpdateRecycleBinIcon") +#pragma comment(linker, "/EXPORT:SHValidateUNC=shell32.SHValidateUNC") +#pragma comment(linker, "/EXPORT:SetCurrentProcessExplicitAppUserModelID=shell32.SetCurrentProcessExplicitAppUserModelID") +#pragma comment(linker, "/EXPORT:SheChangeDirA=shell32.SheChangeDirA") +#pragma comment(linker, "/EXPORT:SheChangeDirExW=shell32.SheChangeDirExW") +#pragma comment(linker, "/EXPORT:SheGetDirA=shell32.SheGetDirA") +#pragma comment(linker, "/EXPORT:SheSetCurDrive=shell32.SheSetCurDrive") +#pragma comment(linker, "/EXPORT:ShellAboutA=shell32.ShellAboutA") +#pragma comment(linker, "/EXPORT:ShellAboutW=shell32.ShellAboutW") +#pragma comment(linker, "/EXPORT:ShellExec_RunDLL=shell32.ShellExec_RunDLL") +#pragma comment(linker, "/EXPORT:ShellExec_RunDLLA=shell32.ShellExec_RunDLLA") +#pragma comment(linker, "/EXPORT:ShellExec_RunDLLW=shell32.ShellExec_RunDLLW") +#pragma comment(linker, "/EXPORT:ShellExecuteA=shell32.ShellExecuteA") +#pragma comment(linker, "/EXPORT:ShellExecuteEx=shell32.ShellExecuteEx") +#pragma comment(linker, "/EXPORT:ShellExecuteExA=shell32.ShellExecuteExA") +#pragma comment(linker, "/EXPORT:ShellExecuteExW=shell32.ShellExecuteExW") +#pragma comment(linker, "/EXPORT:ShellExecuteW=shell32.ShellExecuteW") +#pragma comment(linker, "/EXPORT:ShellHookProc=shell32.ShellHookProc") +#pragma comment(linker, "/EXPORT:ShellMessageBoxA=shell32.ShellMessageBoxA") +#pragma comment(linker, "/EXPORT:ShellMessageBoxW=shell32.ShellMessageBoxW") +#pragma comment(linker, "/EXPORT:Shell_GetCachedImageIndex=shell32.Shell_GetCachedImageIndex") +#pragma comment(linker, "/EXPORT:Shell_GetCachedImageIndexA=shell32.Shell_GetCachedImageIndexA") +#pragma comment(linker, "/EXPORT:Shell_GetCachedImageIndexW=shell32.Shell_GetCachedImageIndexW") +#pragma comment(linker, "/EXPORT:Shell_GetImageLists=shell32.Shell_GetImageLists") +#pragma comment(linker, "/EXPORT:Shell_MergeMenus=shell32.Shell_MergeMenus") +#pragma comment(linker, "/EXPORT:Shell_NotifyIcon=shell32.Shell_NotifyIcon") +#pragma comment(linker, "/EXPORT:Shell_NotifyIconA=shell32.Shell_NotifyIconA") +#pragma comment(linker, "/EXPORT:Shell_NotifyIconGetRect=shell32.Shell_NotifyIconGetRect") +#pragma comment(linker, "/EXPORT:Shell_NotifyIconW=shell32.Shell_NotifyIconW") +#pragma comment(linker, "/EXPORT:SignalFileOpen=shell32.SignalFileOpen") +#pragma comment(linker, "/EXPORT:StgMakeUniqueName=shell32.StgMakeUniqueName") +#pragma comment(linker, "/EXPORT:StrChrA=shell32.StrChrA") +#pragma comment(linker, "/EXPORT:StrChrIA=shell32.StrChrIA") +#pragma comment(linker, "/EXPORT:StrChrIW=shell32.StrChrIW") +#pragma comment(linker, "/EXPORT:StrChrW=shell32.StrChrW") +#pragma comment(linker, "/EXPORT:StrCmpNA=shell32.StrCmpNA") +#pragma comment(linker, "/EXPORT:StrCmpNIA=shell32.StrCmpNIA") +#pragma comment(linker, "/EXPORT:StrCmpNIW=shell32.StrCmpNIW") +#pragma comment(linker, "/EXPORT:StrCmpNW=shell32.StrCmpNW") +#pragma comment(linker, "/EXPORT:StrNCmpA=shell32.StrNCmpA") +#pragma comment(linker, "/EXPORT:StrNCmpIA=shell32.StrNCmpIA") +#pragma comment(linker, "/EXPORT:StrNCmpIW=shell32.StrNCmpIW") +#pragma comment(linker, "/EXPORT:StrNCmpW=shell32.StrNCmpW") +#pragma comment(linker, "/EXPORT:StrRChrA=shell32.StrRChrA") +#pragma comment(linker, "/EXPORT:StrRChrIA=shell32.StrRChrIA") +#pragma comment(linker, "/EXPORT:StrRChrIW=shell32.StrRChrIW") +#pragma comment(linker, "/EXPORT:StrRChrW=shell32.StrRChrW") +#pragma comment(linker, "/EXPORT:StrRStrA=shell32.StrRStrA") +#pragma comment(linker, "/EXPORT:StrRStrIA=shell32.StrRStrIA") +#pragma comment(linker, "/EXPORT:StrRStrIW=shell32.StrRStrIW") +#pragma comment(linker, "/EXPORT:StrRStrW=shell32.StrRStrW") +#pragma comment(linker, "/EXPORT:StrStrA=shell32.StrStrA") +#pragma comment(linker, "/EXPORT:StrStrIA=shell32.StrStrIA") +#pragma comment(linker, "/EXPORT:StrStrIW=shell32.StrStrIW") +#pragma comment(linker, "/EXPORT:StrStrW=shell32.StrStrW") +#pragma comment(linker, "/EXPORT:WOWShellExecute=shell32.WOWShellExecute") +#pragma comment(linker, "/EXPORT:WaitForExplorerRestartW=shell32.WaitForExplorerRestartW") +#pragma comment(linker, "/EXPORT:Win32DeleteFile=shell32.Win32DeleteFile") +#pragma comment(linker, "/EXPORT:WriteCabinetState=shell32.WriteCabinetState") +#pragma comment(linker, "/EXPORT:__OrdinalFunction5=shell32.#5,@5,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction7=shell32.#7,@7,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction8=shell32.#8,@8,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction12=shell32.#12,@12,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction15=shell32.#15,@15,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction20=shell32.#20,@20,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction26=shell32.#26,@26,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction29=shell32.#29,@29,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction30=shell32.#30,@30,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction31=shell32.#31,@31,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction32=shell32.#32,@32,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction33=shell32.#33,@33,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction34=shell32.#34,@34,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction35=shell32.#35,@35,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction36=shell32.#36,@36,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction37=shell32.#37,@37,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction38=shell32.#38,@38,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction39=shell32.#39,@39,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction40=shell32.#40,@40,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction44=shell32.#44,@44,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction45=shell32.#45,@45,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction46=shell32.#46,@46,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction48=shell32.#48,@48,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction50=shell32.#50,@50,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction52=shell32.#52,@52,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction53=shell32.#53,@53,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction54=shell32.#54,@54,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction55=shell32.#55,@55,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction56=shell32.#56,@56,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction57=shell32.#57,@57,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction58=shell32.#58,@58,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction60=shell32.#60,@60,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction61=shell32.#61,@61,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction65=shell32.#65,@65,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction69=shell32.#69,@69,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction70=shell32.#70,@70,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction76=shell32.#76,@76,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction78=shell32.#78,@78,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction79=shell32.#79,@79,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction82=shell32.#82,@82,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction84=shell32.#84,@84,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction86=shell32.#86,@86,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction87=shell32.#87,@87,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction91=shell32.#91,@91,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction93=shell32.#93,@93,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction94=shell32.#94,@94,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction95=shell32.#95,@95,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction96=shell32.#96,@96,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction97=shell32.#97,@97,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction99=shell32.#99,@99,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction101=shell32.#101,@101,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction104=shell32.#104,@104,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction105=shell32.#105,@105,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction106=shell32.#106,@106,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction107=shell32.#107,@107,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction108=shell32.#108,@108,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction109=shell32.#109,@109,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction110=shell32.#110,@110,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction111=shell32.#111,@111,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction112=shell32.#112,@112,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction113=shell32.#113,@113,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction114=shell32.#114,@114,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction115=shell32.#115,@115,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction116=shell32.#116,@116,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction117=shell32.#117,@117,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction118=shell32.#118,@118,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction120=shell32.#120,@120,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction121=shell32.#121,@121,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction122=shell32.#122,@122,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction123=shell32.#123,@123,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction124=shell32.#124,@124,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction126=shell32.#126,@126,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction127=shell32.#127,@127,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction128=shell32.#128,@128,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction130=shell32.#130,@130,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction140=shell32.#140,@140,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction141=shell32.#141,@141,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction142=shell32.#142,@142,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction143=shell32.#143,@143,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction144=shell32.#144,@144,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction145=shell32.#145,@145,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction146=shell32.#146,@146,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction148=shell32.#148,@148,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction151=shell32.#151,@151,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction156=shell32.#156,@156,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction158=shell32.#158,@158,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction159=shell32.#159,@159,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction160=shell32.#160,@160,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction161=shell32.#161,@161,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction163=shell32.#163,@163,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction166=shell32.#166,@166,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction172=shell32.#172,@172,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction175=shell32.#175,@175,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction177=shell32.#177,@177,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction181=shell32.#181,@181,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction184=shell32.#184,@184,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction185=shell32.#185,@185,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction186=shell32.#186,@186,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction187=shell32.#187,@187,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction188=shell32.#188,@188,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction194=shell32.#194,@194,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction197=shell32.#197,@197,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction198=shell32.#198,@198,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction200=shell32.#200,@200,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction201=shell32.#201,@201,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction202=shell32.#202,@202,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction203=shell32.#203,@203,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction204=shell32.#204,@204,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction205=shell32.#205,@205,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction209=shell32.#209,@209,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction210=shell32.#210,@210,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction211=shell32.#211,@211,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction212=shell32.#212,@212,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction213=shell32.#213,@213,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction214=shell32.#214,@214,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction215=shell32.#215,@215,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction216=shell32.#216,@216,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction217=shell32.#217,@217,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction218=shell32.#218,@218,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction219=shell32.#219,@219,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction220=shell32.#220,@220,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction221=shell32.#221,@221,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction222=shell32.#222,@222,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction223=shell32.#223,@223,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction224=shell32.#224,@224,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction225=shell32.#225,@225,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction227=shell32.#227,@227,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction230=shell32.#230,@230,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction233=shell32.#233,@233,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction234=shell32.#234,@234,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction235=shell32.#235,@235,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction236=shell32.#236,@236,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction237=shell32.#237,@237,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction241=shell32.#241,@241,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction242=shell32.#242,@242,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction243=shell32.#243,@243,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction244=shell32.#244,@244,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction246=shell32.#246,@246,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction247=shell32.#247,@247,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction248=shell32.#248,@248,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction249=shell32.#249,@249,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction250=shell32.#250,@250,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction251=shell32.#251,@251,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction252=shell32.#252,@252,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction253=shell32.#253,@253,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction254=shell32.#254,@254,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction257=shell32.#257,@257,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction258=shell32.#258,@258,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction259=shell32.#259,@259,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction260=shell32.#260,@260,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction261=shell32.#261,@261,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction262=shell32.#262,@262,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction264=shell32.#264,@264,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction265=shell32.#265,@265,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction266=shell32.#266,@266,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction270=shell32.#270,@270,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction471=shell32.#471,@471,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction472=shell32.#472,@472,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction473=shell32.#473,@473,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction474=shell32.#474,@474,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction475=shell32.#475,@475,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction476=shell32.#476,@476,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction477=shell32.#477,@477,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction478=shell32.#478,@478,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction479=shell32.#479,@479,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction480=shell32.#480,@480,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction481=shell32.#481,@481,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction482=shell32.#482,@482,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction483=shell32.#483,@483,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction484=shell32.#484,@484,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction485=shell32.#485,@485,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction486=shell32.#486,@486,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction487=shell32.#487,@487,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction488=shell32.#488,@488,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction489=shell32.#489,@489,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction490=shell32.#490,@490,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction491=shell32.#491,@491,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction492=shell32.#492,@492,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction493=shell32.#493,@493,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction494=shell32.#494,@494,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction495=shell32.#495,@495,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction496=shell32.#496,@496,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction497=shell32.#497,@497,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction498=shell32.#498,@498,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction499=shell32.#499,@499,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction500=shell32.#500,@500,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction501=shell32.#501,@501,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction502=shell32.#502,@502,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction503=shell32.#503,@503,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction504=shell32.#504,@504,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction505=shell32.#505,@505,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction506=shell32.#506,@506,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction507=shell32.#507,@507,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction508=shell32.#508,@508,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction509=shell32.#509,@509,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction510=shell32.#510,@510,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction511=shell32.#511,@511,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction512=shell32.#512,@512,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction513=shell32.#513,@513,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction514=shell32.#514,@514,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction515=shell32.#515,@515,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction516=shell32.#516,@516,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction517=shell32.#517,@517,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction518=shell32.#518,@518,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction519=shell32.#519,@519,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction520=shell32.#520,@520,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction521=shell32.#521,@521,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction522=shell32.#522,@522,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction523=shell32.#523,@523,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction525=shell32.#525,@525,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction527=shell32.#527,@527,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction528=shell32.#528,@528,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction529=shell32.#529,@529,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction530=shell32.#530,@530,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction531=shell32.#531,@531,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction532=shell32.#532,@532,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction533=shell32.#533,@533,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction534=shell32.#534,@534,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction535=shell32.#535,@535,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction536=shell32.#536,@536,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction537=shell32.#537,@537,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction538=shell32.#538,@538,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction539=shell32.#539,@539,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction540=shell32.#540,@540,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction541=shell32.#541,@541,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction542=shell32.#542,@542,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction543=shell32.#543,@543,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction544=shell32.#544,@544,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction545=shell32.#545,@545,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction546=shell32.#546,@546,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction547=shell32.#547,@547,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction548=shell32.#548,@548,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction549=shell32.#549,@549,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction550=shell32.#550,@550,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction551=shell32.#551,@551,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction552=shell32.#552,@552,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction553=shell32.#553,@553,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction554=shell32.#554,@554,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction555=shell32.#555,@555,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction556=shell32.#556,@556,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction557=shell32.#557,@557,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction558=shell32.#558,@558,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction559=shell32.#559,@559,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction560=shell32.#560,@560,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction561=shell32.#561,@561,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction562=shell32.#562,@562,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction563=shell32.#563,@563,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction564=shell32.#564,@564,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction565=shell32.#565,@565,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction566=shell32.#566,@566,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction567=shell32.#567,@567,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction568=shell32.#568,@568,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction569=shell32.#569,@569,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction570=shell32.#570,@570,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction571=shell32.#571,@571,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction572=shell32.#572,@572,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction573=shell32.#573,@573,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction574=shell32.#574,@574,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction575=shell32.#575,@575,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction576=shell32.#576,@576,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction577=shell32.#577,@577,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction578=shell32.#578,@578,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction579=shell32.#579,@579,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction580=shell32.#580,@580,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction581=shell32.#581,@581,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction582=shell32.#582,@582,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction583=shell32.#583,@583,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction584=shell32.#584,@584,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction585=shell32.#585,@585,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction586=shell32.#586,@586,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction587=shell32.#587,@587,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction588=shell32.#588,@588,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction589=shell32.#589,@589,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction590=shell32.#590,@590,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction591=shell32.#591,@591,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction592=shell32.#592,@592,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction593=shell32.#593,@593,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction594=shell32.#594,@594,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction595=shell32.#595,@595,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction596=shell32.#596,@596,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction597=shell32.#597,@597,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction598=shell32.#598,@598,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction599=shell32.#599,@599,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction600=shell32.#600,@600,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction601=shell32.#601,@601,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction602=shell32.#602,@602,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction603=shell32.#603,@603,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction604=shell32.#604,@604,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction605=shell32.#605,@605,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction606=shell32.#606,@606,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction607=shell32.#607,@607,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction608=shell32.#608,@608,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction609=shell32.#609,@609,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction610=shell32.#610,@610,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction611=shell32.#611,@611,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction612=shell32.#612,@612,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction613=shell32.#613,@613,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction614=shell32.#614,@614,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction615=shell32.#615,@615,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction616=shell32.#616,@616,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction617=shell32.#617,@617,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction618=shell32.#618,@618,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction619=shell32.#619,@619,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction620=shell32.#620,@620,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction621=shell32.#621,@621,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction622=shell32.#622,@622,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction623=shell32.#623,@623,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction624=shell32.#624,@624,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction625=shell32.#625,@625,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction626=shell32.#626,@626,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction627=shell32.#627,@627,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction628=shell32.#628,@628,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction629=shell32.#629,@629,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction630=shell32.#630,@630,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction631=shell32.#631,@631,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction632=shell32.#632,@632,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction633=shell32.#633,@633,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction634=shell32.#634,@634,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction635=shell32.#635,@635,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction636=shell32.#636,@636,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction637=shell32.#637,@637,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction638=shell32.#638,@638,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction639=shell32.#639,@639,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction640=shell32.#640,@640,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction641=shell32.#641,@641,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction642=shell32.#642,@642,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction643=shell32.#643,@643,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction646=shell32.#646,@646,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction647=shell32.#647,@647,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction648=shell32.#648,@648,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction649=shell32.#649,@649,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction650=shell32.#650,@650,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction651=shell32.#651,@651,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction653=shell32.#653,@653,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction655=shell32.#655,@655,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction656=shell32.#656,@656,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction657=shell32.#657,@657,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction658=shell32.#658,@658,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction659=shell32.#659,@659,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction660=shell32.#660,@660,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction661=shell32.#661,@661,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction662=shell32.#662,@662,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction663=shell32.#663,@663,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction664=shell32.#664,@664,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction665=shell32.#665,@665,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction666=shell32.#666,@666,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction667=shell32.#667,@667,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction668=shell32.#668,@668,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction669=shell32.#669,@669,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction670=shell32.#670,@670,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction671=shell32.#671,@671,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction672=shell32.#672,@672,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction673=shell32.#673,@673,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction674=shell32.#674,@674,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction675=shell32.#675,@675,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction676=shell32.#676,@676,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction677=shell32.#677,@677,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction678=shell32.#678,@678,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction679=shell32.#679,@679,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction681=shell32.#681,@681,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction683=shell32.#683,@683,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction684=shell32.#684,@684,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction686=shell32.#686,@686,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction687=shell32.#687,@687,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction690=shell32.#690,@690,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction691=shell32.#691,@691,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction692=shell32.#692,@692,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction693=shell32.#693,@693,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction694=shell32.#694,@694,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction695=shell32.#695,@695,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction696=shell32.#696,@696,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction697=shell32.#697,@697,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction698=shell32.#698,@698,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction699=shell32.#699,@699,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction700=shell32.#700,@700,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction702=shell32.#702,@702,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction703=shell32.#703,@703,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction704=shell32.#704,@704,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction705=shell32.#705,@705,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction706=shell32.#706,@706,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction707=shell32.#707,@707,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction708=shell32.#708,@708,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction710=shell32.#710,@710,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction711=shell32.#711,@711,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction712=shell32.#712,@712,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction713=shell32.#713,@713,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction714=shell32.#714,@714,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction715=shell32.#715,@715,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction717=shell32.#717,@717,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction718=shell32.#718,@718,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction719=shell32.#719,@719,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction720=shell32.#720,@720,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction721=shell32.#721,@721,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction722=shell32.#722,@722,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction723=shell32.#723,@723,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction724=shell32.#724,@724,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction725=shell32.#725,@725,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction726=shell32.#726,@726,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction728=shell32.#728,@728,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction729=shell32.#729,@729,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction731=shell32.#731,@731,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction732=shell32.#732,@732,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction733=shell32.#733,@733,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction734=shell32.#734,@734,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction735=shell32.#735,@735,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction736=shell32.#736,@736,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction737=shell32.#737,@737,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction738=shell32.#738,@738,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction739=shell32.#739,@739,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction740=shell32.#740,@740,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction741=shell32.#741,@741,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction742=shell32.#742,@742,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction744=shell32.#744,@744,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction745=shell32.#745,@745,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction746=shell32.#746,@746,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction748=shell32.#748,@748,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction749=shell32.#749,@749,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction751=shell32.#751,@751,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction752=shell32.#752,@752,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction753=shell32.#753,@753,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction754=shell32.#754,@754,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction755=shell32.#755,@755,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction756=shell32.#756,@756,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction757=shell32.#757,@757,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction758=shell32.#758,@758,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction759=shell32.#759,@759,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction760=shell32.#760,@760,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction761=shell32.#761,@761,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction762=shell32.#762,@762,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction763=shell32.#763,@763,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction764=shell32.#764,@764,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction765=shell32.#765,@765,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction766=shell32.#766,@766,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction767=shell32.#767,@767,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction768=shell32.#768,@768,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction769=shell32.#769,@769,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction770=shell32.#770,@770,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction771=shell32.#771,@771,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction772=shell32.#772,@772,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction773=shell32.#773,@773,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction774=shell32.#774,@774,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction775=shell32.#775,@775,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction776=shell32.#776,@776,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction777=shell32.#777,@777,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction778=shell32.#778,@778,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction779=shell32.#779,@779,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction780=shell32.#780,@780,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction781=shell32.#781,@781,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction782=shell32.#782,@782,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction783=shell32.#783,@783,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction784=shell32.#784,@784,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction785=shell32.#785,@785,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction786=shell32.#786,@786,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction787=shell32.#787,@787,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction788=shell32.#788,@788,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction789=shell32.#789,@789,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction790=shell32.#790,@790,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction791=shell32.#791,@791,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction792=shell32.#792,@792,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction793=shell32.#793,@793,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction794=shell32.#794,@794,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction795=shell32.#795,@795,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction796=shell32.#796,@796,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction797=shell32.#797,@797,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction798=shell32.#798,@798,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction799=shell32.#799,@799,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction800=shell32.#800,@800,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction801=shell32.#801,@801,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction802=shell32.#802,@802,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction803=shell32.#803,@803,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction804=shell32.#804,@804,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction805=shell32.#805,@805,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction806=shell32.#806,@806,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction807=shell32.#807,@807,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction808=shell32.#808,@808,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction809=shell32.#809,@809,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction810=shell32.#810,@810,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction811=shell32.#811,@811,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction812=shell32.#812,@812,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction813=shell32.#813,@813,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction814=shell32.#814,@814,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction815=shell32.#815,@815,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction816=shell32.#816,@816,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction817=shell32.#817,@817,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction818=shell32.#818,@818,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction819=shell32.#819,@819,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction820=shell32.#820,@820,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction821=shell32.#821,@821,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction822=shell32.#822,@822,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction823=shell32.#823,@823,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction824=shell32.#824,@824,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction825=shell32.#825,@825,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction826=shell32.#826,@826,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction827=shell32.#827,@827,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction828=shell32.#828,@828,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction829=shell32.#829,@829,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction830=shell32.#830,@830,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction831=shell32.#831,@831,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction832=shell32.#832,@832,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction833=shell32.#833,@833,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction834=shell32.#834,@834,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction835=shell32.#835,@835,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction836=shell32.#836,@836,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction837=shell32.#837,@837,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction838=shell32.#838,@838,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction839=shell32.#839,@839,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction840=shell32.#840,@840,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction841=shell32.#841,@841,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction842=shell32.#842,@842,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction843=shell32.#843,@843,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction844=shell32.#844,@844,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction845=shell32.#845,@845,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction847=shell32.#847,@847,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction848=shell32.#848,@848,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction849=shell32.#849,@849,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction850=shell32.#850,@850,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction851=shell32.#851,@851,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction852=shell32.#852,@852,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction853=shell32.#853,@853,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction854=shell32.#854,@854,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction855=shell32.#855,@855,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction856=shell32.#856,@856,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction857=shell32.#857,@857,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction858=shell32.#858,@858,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction859=shell32.#859,@859,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction860=shell32.#860,@860,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction861=shell32.#861,@861,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction862=shell32.#862,@862,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction863=shell32.#863,@863,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction864=shell32.#864,@864,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction865=shell32.#865,@865,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction866=shell32.#866,@866,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction867=shell32.#867,@867,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction868=shell32.#868,@868,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction869=shell32.#869,@869,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction870=shell32.#870,@870,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction871=shell32.#871,@871,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction872=shell32.#872,@872,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction873=shell32.#873,@873,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction874=shell32.#874,@874,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction875=shell32.#875,@875,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction876=shell32.#876,@876,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction877=shell32.#877,@877,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction878=shell32.#878,@878,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction879=shell32.#879,@879,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction880=shell32.#880,@880,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction881=shell32.#881,@881,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction882=shell32.#882,@882,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction883=shell32.#883,@883,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction884=shell32.#884,@884,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction885=shell32.#885,@885,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction886=shell32.#886,@886,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction887=shell32.#887,@887,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction888=shell32.#888,@888,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction889=shell32.#889,@889,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction890=shell32.#890,@890,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction891=shell32.#891,@891,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction892=shell32.#892,@892,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction893=shell32.#893,@893,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction894=shell32.#894,@894,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction895=shell32.#895,@895,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction896=shell32.#896,@896,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction897=shell32.#897,@897,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction898=shell32.#898,@898,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction899=shell32.#899,@899,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction900=shell32.#900,@900,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction901=shell32.#901,@901,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction902=shell32.#902,@902,NONAME") +#pragma comment(linker, "/EXPORT:__OrdinalFunction903=shell32.#903,@903,NONAME") + +// Generated by KexExprt from "C:\Windows\syswow64\shlwapi.dll" +#pragma comment(linker, "/EXPORT:AssocCreate=shlwapi.AssocCreate") +#pragma comment(linker, "/EXPORT:AssocGetPerceivedType=shlwapi.AssocGetPerceivedType") +#pragma comment(linker, "/EXPORT:AssocIsDangerous=shlwapi.AssocIsDangerous") +#pragma comment(linker, "/EXPORT:AssocQueryKeyA=shlwapi.AssocQueryKeyA") +#pragma comment(linker, "/EXPORT:AssocQueryKeyW=shlwapi.AssocQueryKeyW") +#pragma comment(linker, "/EXPORT:AssocQueryStringA=shlwapi.AssocQueryStringA") +#pragma comment(linker, "/EXPORT:AssocQueryStringByKeyA=shlwapi.AssocQueryStringByKeyA") +#pragma comment(linker, "/EXPORT:AssocQueryStringByKeyW=shlwapi.AssocQueryStringByKeyW") +#pragma comment(linker, "/EXPORT:AssocQueryStringW=shlwapi.AssocQueryStringW") +#pragma comment(linker, "/EXPORT:ChrCmpIA=shlwapi.ChrCmpIA") +#pragma comment(linker, "/EXPORT:ChrCmpIW=shlwapi.ChrCmpIW") +#pragma comment(linker, "/EXPORT:ColorAdjustLuma=shlwapi.ColorAdjustLuma") +#pragma comment(linker, "/EXPORT:ColorHLSToRGB=shlwapi.ColorHLSToRGB") +#pragma comment(linker, "/EXPORT:ColorRGBToHLS=shlwapi.ColorRGBToHLS") +#pragma comment(linker, "/EXPORT:ConnectToConnectionPoint=shlwapi.ConnectToConnectionPoint") +#pragma comment(linker, "/EXPORT:DelayLoadFailureHook=shlwapi.DelayLoadFailureHook") +#pragma comment(linker, "/EXPORT:DllGetVersion=shlwapi.DllGetVersion") +#pragma comment(linker, "/EXPORT:GetAcceptLanguagesA=shlwapi.GetAcceptLanguagesA") +#pragma comment(linker, "/EXPORT:GetAcceptLanguagesW=shlwapi.GetAcceptLanguagesW") +#pragma comment(linker, "/EXPORT:GetMenuPosFromID=shlwapi.GetMenuPosFromID") +#pragma comment(linker, "/EXPORT:HashData=shlwapi.HashData") +#pragma comment(linker, "/EXPORT:IStream_Copy=shlwapi.IStream_Copy") +#pragma comment(linker, "/EXPORT:IStream_Read=shlwapi.IStream_Read") +#pragma comment(linker, "/EXPORT:IStream_ReadPidl=shlwapi.IStream_ReadPidl") +#pragma comment(linker, "/EXPORT:IStream_ReadStr=shlwapi.IStream_ReadStr") +#pragma comment(linker, "/EXPORT:IStream_Reset=shlwapi.IStream_Reset") +#pragma comment(linker, "/EXPORT:IStream_Size=shlwapi.IStream_Size") +#pragma comment(linker, "/EXPORT:IStream_Write=shlwapi.IStream_Write") +#pragma comment(linker, "/EXPORT:IStream_WritePidl=shlwapi.IStream_WritePidl") +#pragma comment(linker, "/EXPORT:IStream_WriteStr=shlwapi.IStream_WriteStr") +#pragma comment(linker, "/EXPORT:IUnknown_AtomicRelease=shlwapi.IUnknown_AtomicRelease") +#pragma comment(linker, "/EXPORT:IUnknown_GetSite=shlwapi.IUnknown_GetSite") +#pragma comment(linker, "/EXPORT:IUnknown_GetWindow=shlwapi.IUnknown_GetWindow") +#pragma comment(linker, "/EXPORT:IUnknown_QueryService=shlwapi.IUnknown_QueryService") +#pragma comment(linker, "/EXPORT:IUnknown_Set=shlwapi.IUnknown_Set") +#pragma comment(linker, "/EXPORT:IUnknown_SetSite=shlwapi.IUnknown_SetSite") +#pragma comment(linker, "/EXPORT:IntlStrEqWorkerA=shlwapi.IntlStrEqWorkerA") +#pragma comment(linker, "/EXPORT:IntlStrEqWorkerW=shlwapi.IntlStrEqWorkerW") +#pragma comment(linker, "/EXPORT:IsCharSpaceA=shlwapi.IsCharSpaceA") +#pragma comment(linker, "/EXPORT:IsCharSpaceW=shlwapi.IsCharSpaceW") +#pragma comment(linker, "/EXPORT:IsInternetESCEnabled=shlwapi.IsInternetESCEnabled") +#pragma comment(linker, "/EXPORT:IsOS=shlwapi.IsOS") +#pragma comment(linker, "/EXPORT:MLFreeLibrary=shlwapi.MLFreeLibrary") +#pragma comment(linker, "/EXPORT:MLLoadLibraryA=shlwapi.MLLoadLibraryA") +#pragma comment(linker, "/EXPORT:MLLoadLibraryW=shlwapi.MLLoadLibraryW") +#pragma comment(linker, "/EXPORT:ParseURLA=shlwapi.ParseURLA") +#pragma comment(linker, "/EXPORT:ParseURLW=shlwapi.ParseURLW") +#pragma comment(linker, "/EXPORT:PathAddBackslashA=shlwapi.PathAddBackslashA") +#pragma comment(linker, "/EXPORT:PathAddBackslashW=shlwapi.PathAddBackslashW") +#pragma comment(linker, "/EXPORT:PathAddExtensionA=shlwapi.PathAddExtensionA") +#pragma comment(linker, "/EXPORT:PathAddExtensionW=shlwapi.PathAddExtensionW") +#pragma comment(linker, "/EXPORT:PathAppendA=shlwapi.PathAppendA") +#pragma comment(linker, "/EXPORT:PathAppendW=shlwapi.PathAppendW") +#pragma comment(linker, "/EXPORT:PathBuildRootA=shlwapi.PathBuildRootA") +#pragma comment(linker, "/EXPORT:PathBuildRootW=shlwapi.PathBuildRootW") +#pragma comment(linker, "/EXPORT:PathCanonicalizeA=shlwapi.PathCanonicalizeA") +#pragma comment(linker, "/EXPORT:PathCanonicalizeW=shlwapi.PathCanonicalizeW") +#pragma comment(linker, "/EXPORT:PathCombineA=shlwapi.PathCombineA") +#pragma comment(linker, "/EXPORT:PathCombineW=shlwapi.PathCombineW") +#pragma comment(linker, "/EXPORT:PathCommonPrefixA=shlwapi.PathCommonPrefixA") +#pragma comment(linker, "/EXPORT:PathCommonPrefixW=shlwapi.PathCommonPrefixW") +#pragma comment(linker, "/EXPORT:PathCompactPathA=shlwapi.PathCompactPathA") +#pragma comment(linker, "/EXPORT:PathCompactPathExA=shlwapi.PathCompactPathExA") +#pragma comment(linker, "/EXPORT:PathCompactPathExW=shlwapi.PathCompactPathExW") +#pragma comment(linker, "/EXPORT:PathCompactPathW=shlwapi.PathCompactPathW") +#pragma comment(linker, "/EXPORT:PathCreateFromUrlA=shlwapi.PathCreateFromUrlA") +#pragma comment(linker, "/EXPORT:PathCreateFromUrlAlloc=shlwapi.PathCreateFromUrlAlloc") +#pragma comment(linker, "/EXPORT:PathCreateFromUrlW=shlwapi.PathCreateFromUrlW") +#pragma comment(linker, "/EXPORT:PathFileExistsA=shlwapi.PathFileExistsA") +#pragma comment(linker, "/EXPORT:PathFileExistsW=shlwapi.PathFileExistsW") +#pragma comment(linker, "/EXPORT:PathFindExtensionA=shlwapi.PathFindExtensionA") +#pragma comment(linker, "/EXPORT:PathFindExtensionW=shlwapi.PathFindExtensionW") +#pragma comment(linker, "/EXPORT:PathFindFileNameA=shlwapi.PathFindFileNameA") +#pragma comment(linker, "/EXPORT:PathFindFileNameW=shlwapi.PathFindFileNameW") +#pragma comment(linker, "/EXPORT:PathFindNextComponentA=shlwapi.PathFindNextComponentA") +#pragma comment(linker, "/EXPORT:PathFindNextComponentW=shlwapi.PathFindNextComponentW") +#pragma comment(linker, "/EXPORT:PathFindOnPathA=shlwapi.PathFindOnPathA") +#pragma comment(linker, "/EXPORT:PathFindOnPathW=shlwapi.PathFindOnPathW") +#pragma comment(linker, "/EXPORT:PathFindSuffixArrayA=shlwapi.PathFindSuffixArrayA") +#pragma comment(linker, "/EXPORT:PathFindSuffixArrayW=shlwapi.PathFindSuffixArrayW") +#pragma comment(linker, "/EXPORT:PathGetArgsA=shlwapi.PathGetArgsA") +#pragma comment(linker, "/EXPORT:PathGetArgsW=shlwapi.PathGetArgsW") +#pragma comment(linker, "/EXPORT:PathGetCharTypeA=shlwapi.PathGetCharTypeA") +#pragma comment(linker, "/EXPORT:PathGetCharTypeW=shlwapi.PathGetCharTypeW") +#pragma comment(linker, "/EXPORT:PathGetDriveNumberA=shlwapi.PathGetDriveNumberA") +#pragma comment(linker, "/EXPORT:PathGetDriveNumberW=shlwapi.PathGetDriveNumberW") +#pragma comment(linker, "/EXPORT:PathIsContentTypeA=shlwapi.PathIsContentTypeA") +#pragma comment(linker, "/EXPORT:PathIsContentTypeW=shlwapi.PathIsContentTypeW") +#pragma comment(linker, "/EXPORT:PathIsDirectoryA=shlwapi.PathIsDirectoryA") +#pragma comment(linker, "/EXPORT:PathIsDirectoryEmptyA=shlwapi.PathIsDirectoryEmptyA") +#pragma comment(linker, "/EXPORT:PathIsDirectoryEmptyW=shlwapi.PathIsDirectoryEmptyW") +#pragma comment(linker, "/EXPORT:PathIsDirectoryW=shlwapi.PathIsDirectoryW") +#pragma comment(linker, "/EXPORT:PathIsFileSpecA=shlwapi.PathIsFileSpecA") +#pragma comment(linker, "/EXPORT:PathIsFileSpecW=shlwapi.PathIsFileSpecW") +#pragma comment(linker, "/EXPORT:PathIsLFNFileSpecA=shlwapi.PathIsLFNFileSpecA") +#pragma comment(linker, "/EXPORT:PathIsLFNFileSpecW=shlwapi.PathIsLFNFileSpecW") +#pragma comment(linker, "/EXPORT:PathIsNetworkPathA=shlwapi.PathIsNetworkPathA") +#pragma comment(linker, "/EXPORT:PathIsNetworkPathW=shlwapi.PathIsNetworkPathW") +#pragma comment(linker, "/EXPORT:PathIsPrefixA=shlwapi.PathIsPrefixA") +#pragma comment(linker, "/EXPORT:PathIsPrefixW=shlwapi.PathIsPrefixW") +#pragma comment(linker, "/EXPORT:PathIsRelativeA=shlwapi.PathIsRelativeA") +#pragma comment(linker, "/EXPORT:PathIsRelativeW=shlwapi.PathIsRelativeW") +#pragma comment(linker, "/EXPORT:PathIsRootA=shlwapi.PathIsRootA") +#pragma comment(linker, "/EXPORT:PathIsRootW=shlwapi.PathIsRootW") +#pragma comment(linker, "/EXPORT:PathIsSameRootA=shlwapi.PathIsSameRootA") +#pragma comment(linker, "/EXPORT:PathIsSameRootW=shlwapi.PathIsSameRootW") +#pragma comment(linker, "/EXPORT:PathIsSystemFolderA=shlwapi.PathIsSystemFolderA") +#pragma comment(linker, "/EXPORT:PathIsSystemFolderW=shlwapi.PathIsSystemFolderW") +#pragma comment(linker, "/EXPORT:PathIsUNCA=shlwapi.PathIsUNCA") +#pragma comment(linker, "/EXPORT:PathIsUNCServerA=shlwapi.PathIsUNCServerA") +#pragma comment(linker, "/EXPORT:PathIsUNCServerShareA=shlwapi.PathIsUNCServerShareA") +#pragma comment(linker, "/EXPORT:PathIsUNCServerShareW=shlwapi.PathIsUNCServerShareW") +#pragma comment(linker, "/EXPORT:PathIsUNCServerW=shlwapi.PathIsUNCServerW") +#pragma comment(linker, "/EXPORT:PathIsUNCW=shlwapi.PathIsUNCW") +#pragma comment(linker, "/EXPORT:PathIsURLA=shlwapi.PathIsURLA") +#pragma comment(linker, "/EXPORT:PathIsURLW=shlwapi.PathIsURLW") +#pragma comment(linker, "/EXPORT:PathMakePrettyA=shlwapi.PathMakePrettyA") +#pragma comment(linker, "/EXPORT:PathMakePrettyW=shlwapi.PathMakePrettyW") +#pragma comment(linker, "/EXPORT:PathMakeSystemFolderA=shlwapi.PathMakeSystemFolderA") +#pragma comment(linker, "/EXPORT:PathMakeSystemFolderW=shlwapi.PathMakeSystemFolderW") +#pragma comment(linker, "/EXPORT:PathMatchSpecA=shlwapi.PathMatchSpecA") +#pragma comment(linker, "/EXPORT:PathMatchSpecExA=shlwapi.PathMatchSpecExA") +#pragma comment(linker, "/EXPORT:PathMatchSpecExW=shlwapi.PathMatchSpecExW") +#pragma comment(linker, "/EXPORT:PathMatchSpecW=shlwapi.PathMatchSpecW") +#pragma comment(linker, "/EXPORT:PathParseIconLocationA=shlwapi.PathParseIconLocationA") +#pragma comment(linker, "/EXPORT:PathParseIconLocationW=shlwapi.PathParseIconLocationW") +#pragma comment(linker, "/EXPORT:PathQuoteSpacesA=shlwapi.PathQuoteSpacesA") +#pragma comment(linker, "/EXPORT:PathQuoteSpacesW=shlwapi.PathQuoteSpacesW") +#pragma comment(linker, "/EXPORT:PathRelativePathToA=shlwapi.PathRelativePathToA") +#pragma comment(linker, "/EXPORT:PathRelativePathToW=shlwapi.PathRelativePathToW") +#pragma comment(linker, "/EXPORT:PathRemoveArgsA=shlwapi.PathRemoveArgsA") +#pragma comment(linker, "/EXPORT:PathRemoveArgsW=shlwapi.PathRemoveArgsW") +#pragma comment(linker, "/EXPORT:PathRemoveBackslashA=shlwapi.PathRemoveBackslashA") +#pragma comment(linker, "/EXPORT:PathRemoveBackslashW=shlwapi.PathRemoveBackslashW") +#pragma comment(linker, "/EXPORT:PathRemoveBlanksA=shlwapi.PathRemoveBlanksA") +#pragma comment(linker, "/EXPORT:PathRemoveBlanksW=shlwapi.PathRemoveBlanksW") +#pragma comment(linker, "/EXPORT:PathRemoveExtensionA=shlwapi.PathRemoveExtensionA") +#pragma comment(linker, "/EXPORT:PathRemoveExtensionW=shlwapi.PathRemoveExtensionW") +#pragma comment(linker, "/EXPORT:PathRemoveFileSpecA=shlwapi.PathRemoveFileSpecA") +#pragma comment(linker, "/EXPORT:PathRemoveFileSpecW=shlwapi.PathRemoveFileSpecW") +#pragma comment(linker, "/EXPORT:PathRenameExtensionA=shlwapi.PathRenameExtensionA") +#pragma comment(linker, "/EXPORT:PathRenameExtensionW=shlwapi.PathRenameExtensionW") +#pragma comment(linker, "/EXPORT:PathSearchAndQualifyA=shlwapi.PathSearchAndQualifyA") +#pragma comment(linker, "/EXPORT:PathSearchAndQualifyW=shlwapi.PathSearchAndQualifyW") +#pragma comment(linker, "/EXPORT:PathSetDlgItemPathA=shlwapi.PathSetDlgItemPathA") +#pragma comment(linker, "/EXPORT:PathSetDlgItemPathW=shlwapi.PathSetDlgItemPathW") +#pragma comment(linker, "/EXPORT:PathSkipRootA=shlwapi.PathSkipRootA") +#pragma comment(linker, "/EXPORT:PathSkipRootW=shlwapi.PathSkipRootW") +#pragma comment(linker, "/EXPORT:PathStripPathA=shlwapi.PathStripPathA") +#pragma comment(linker, "/EXPORT:PathStripPathW=shlwapi.PathStripPathW") +#pragma comment(linker, "/EXPORT:PathStripToRootA=shlwapi.PathStripToRootA") +#pragma comment(linker, "/EXPORT:PathStripToRootW=shlwapi.PathStripToRootW") +#pragma comment(linker, "/EXPORT:PathUnExpandEnvStringsA=shlwapi.PathUnExpandEnvStringsA") +#pragma comment(linker, "/EXPORT:PathUnExpandEnvStringsW=shlwapi.PathUnExpandEnvStringsW") +#pragma comment(linker, "/EXPORT:PathUndecorateA=shlwapi.PathUndecorateA") +#pragma comment(linker, "/EXPORT:PathUndecorateW=shlwapi.PathUndecorateW") +#pragma comment(linker, "/EXPORT:PathUnmakeSystemFolderA=shlwapi.PathUnmakeSystemFolderA") +#pragma comment(linker, "/EXPORT:PathUnmakeSystemFolderW=shlwapi.PathUnmakeSystemFolderW") +#pragma comment(linker, "/EXPORT:PathUnquoteSpacesA=shlwapi.PathUnquoteSpacesA") +#pragma comment(linker, "/EXPORT:PathUnquoteSpacesW=shlwapi.PathUnquoteSpacesW") +#pragma comment(linker, "/EXPORT:QISearch=shlwapi.QISearch") +#pragma comment(linker, "/EXPORT:SHAllocShared=shlwapi.SHAllocShared") +#pragma comment(linker, "/EXPORT:SHAnsiToAnsi=shlwapi.SHAnsiToAnsi") +#pragma comment(linker, "/EXPORT:SHAnsiToUnicode=shlwapi.SHAnsiToUnicode") +#pragma comment(linker, "/EXPORT:SHAutoComplete=shlwapi.SHAutoComplete") +#pragma comment(linker, "/EXPORT:SHCopyKeyA=shlwapi.SHCopyKeyA") +#pragma comment(linker, "/EXPORT:SHCopyKeyW=shlwapi.SHCopyKeyW") +#pragma comment(linker, "/EXPORT:SHCreateMemStream=shlwapi.SHCreateMemStream") +#pragma comment(linker, "/EXPORT:SHCreateShellPalette=shlwapi.SHCreateShellPalette") +#pragma comment(linker, "/EXPORT:SHCreateStreamOnFileA=shlwapi.SHCreateStreamOnFileA") +#pragma comment(linker, "/EXPORT:SHCreateStreamOnFileEx=shlwapi.SHCreateStreamOnFileEx") +#pragma comment(linker, "/EXPORT:SHCreateStreamOnFileW=shlwapi.SHCreateStreamOnFileW") +#pragma comment(linker, "/EXPORT:SHCreateStreamWrapper=shlwapi.SHCreateStreamWrapper") +#pragma comment(linker, "/EXPORT:SHCreateThread=shlwapi.SHCreateThread") +#pragma comment(linker, "/EXPORT:SHCreateThreadRef=shlwapi.SHCreateThreadRef") +#pragma comment(linker, "/EXPORT:SHCreateThreadWithHandle=shlwapi.SHCreateThreadWithHandle") +#pragma comment(linker, "/EXPORT:SHDeleteEmptyKeyA=shlwapi.SHDeleteEmptyKeyA") +#pragma comment(linker, "/EXPORT:SHDeleteEmptyKeyW=shlwapi.SHDeleteEmptyKeyW") +#pragma comment(linker, "/EXPORT:SHDeleteKeyA=shlwapi.SHDeleteKeyA") +#pragma comment(linker, "/EXPORT:SHDeleteKeyW=shlwapi.SHDeleteKeyW") +#pragma comment(linker, "/EXPORT:SHDeleteOrphanKeyA=shlwapi.SHDeleteOrphanKeyA") +#pragma comment(linker, "/EXPORT:SHDeleteOrphanKeyW=shlwapi.SHDeleteOrphanKeyW") +#pragma comment(linker, "/EXPORT:SHDeleteValueA=shlwapi.SHDeleteValueA") +#pragma comment(linker, "/EXPORT:SHDeleteValueW=shlwapi.SHDeleteValueW") +#pragma comment(linker, "/EXPORT:SHEnumKeyExA=shlwapi.SHEnumKeyExA") +#pragma comment(linker, "/EXPORT:SHEnumKeyExW=shlwapi.SHEnumKeyExW") +#pragma comment(linker, "/EXPORT:SHEnumValueA=shlwapi.SHEnumValueA") +#pragma comment(linker, "/EXPORT:SHEnumValueW=shlwapi.SHEnumValueW") +#pragma comment(linker, "/EXPORT:SHFormatDateTimeA=shlwapi.SHFormatDateTimeA") +#pragma comment(linker, "/EXPORT:SHFormatDateTimeW=shlwapi.SHFormatDateTimeW") +#pragma comment(linker, "/EXPORT:SHFreeShared=shlwapi.SHFreeShared") +#pragma comment(linker, "/EXPORT:SHGetInverseCMAP=shlwapi.SHGetInverseCMAP") +#pragma comment(linker, "/EXPORT:SHGetThreadRef=shlwapi.SHGetThreadRef") +#pragma comment(linker, "/EXPORT:SHGetValueA=shlwapi.SHGetValueA") +#pragma comment(linker, "/EXPORT:SHGetValueW=shlwapi.SHGetValueW") +#pragma comment(linker, "/EXPORT:SHGetViewStatePropertyBag=shlwapi.SHGetViewStatePropertyBag") +#pragma comment(linker, "/EXPORT:SHIsChildOrSelf=shlwapi.SHIsChildOrSelf") +#pragma comment(linker, "/EXPORT:SHIsLowMemoryMachine=shlwapi.SHIsLowMemoryMachine") +#pragma comment(linker, "/EXPORT:SHLoadIndirectString=shlwapi.SHLoadIndirectString") +#pragma comment(linker, "/EXPORT:SHLockShared=shlwapi.SHLockShared") +#pragma comment(linker, "/EXPORT:SHMessageBoxCheckA=shlwapi.SHMessageBoxCheckA") +#pragma comment(linker, "/EXPORT:SHMessageBoxCheckW=shlwapi.SHMessageBoxCheckW") +#pragma comment(linker, "/EXPORT:SHOpenRegStream2A=shlwapi.SHOpenRegStream2A") +#pragma comment(linker, "/EXPORT:SHOpenRegStream2W=shlwapi.SHOpenRegStream2W") +#pragma comment(linker, "/EXPORT:SHOpenRegStreamA=shlwapi.SHOpenRegStreamA") +#pragma comment(linker, "/EXPORT:SHOpenRegStreamW=shlwapi.SHOpenRegStreamW") +#pragma comment(linker, "/EXPORT:SHPropertyBag_ReadStrAlloc=shlwapi.SHPropertyBag_ReadStrAlloc") +#pragma comment(linker, "/EXPORT:SHPropertyBag_WriteBSTR=shlwapi.SHPropertyBag_WriteBSTR") +#pragma comment(linker, "/EXPORT:SHQueryInfoKeyA=shlwapi.SHQueryInfoKeyA") +#pragma comment(linker, "/EXPORT:SHQueryInfoKeyW=shlwapi.SHQueryInfoKeyW") +#pragma comment(linker, "/EXPORT:SHQueryValueExA=shlwapi.SHQueryValueExA") +#pragma comment(linker, "/EXPORT:SHQueryValueExW=shlwapi.SHQueryValueExW") +#pragma comment(linker, "/EXPORT:SHRegCloseUSKey=shlwapi.SHRegCloseUSKey") +#pragma comment(linker, "/EXPORT:SHRegCreateUSKeyA=shlwapi.SHRegCreateUSKeyA") +#pragma comment(linker, "/EXPORT:SHRegCreateUSKeyW=shlwapi.SHRegCreateUSKeyW") +#pragma comment(linker, "/EXPORT:SHRegDeleteEmptyUSKeyA=shlwapi.SHRegDeleteEmptyUSKeyA") +#pragma comment(linker, "/EXPORT:SHRegDeleteEmptyUSKeyW=shlwapi.SHRegDeleteEmptyUSKeyW") +#pragma comment(linker, "/EXPORT:SHRegDeleteUSValueA=shlwapi.SHRegDeleteUSValueA") +#pragma comment(linker, "/EXPORT:SHRegDeleteUSValueW=shlwapi.SHRegDeleteUSValueW") +#pragma comment(linker, "/EXPORT:SHRegDuplicateHKey=shlwapi.SHRegDuplicateHKey") +#pragma comment(linker, "/EXPORT:SHRegEnumUSKeyA=shlwapi.SHRegEnumUSKeyA") +#pragma comment(linker, "/EXPORT:SHRegEnumUSKeyW=shlwapi.SHRegEnumUSKeyW") +#pragma comment(linker, "/EXPORT:SHRegEnumUSValueA=shlwapi.SHRegEnumUSValueA") +#pragma comment(linker, "/EXPORT:SHRegEnumUSValueW=shlwapi.SHRegEnumUSValueW") +#pragma comment(linker, "/EXPORT:SHRegGetBoolUSValueA=shlwapi.SHRegGetBoolUSValueA") +#pragma comment(linker, "/EXPORT:SHRegGetBoolUSValueW=shlwapi.SHRegGetBoolUSValueW") +#pragma comment(linker, "/EXPORT:SHRegGetIntW=shlwapi.SHRegGetIntW") +#pragma comment(linker, "/EXPORT:SHRegGetPathA=shlwapi.SHRegGetPathA") +#pragma comment(linker, "/EXPORT:SHRegGetPathW=shlwapi.SHRegGetPathW") +#pragma comment(linker, "/EXPORT:SHRegGetUSValueA=shlwapi.SHRegGetUSValueA") +#pragma comment(linker, "/EXPORT:SHRegGetUSValueW=shlwapi.SHRegGetUSValueW") +#pragma comment(linker, "/EXPORT:SHRegGetValueA=shlwapi.SHRegGetValueA") +#pragma comment(linker, "/EXPORT:SHRegGetValueW=shlwapi.SHRegGetValueW") +#pragma comment(linker, "/EXPORT:SHRegOpenUSKeyA=shlwapi.SHRegOpenUSKeyA") +#pragma comment(linker, "/EXPORT:SHRegOpenUSKeyW=shlwapi.SHRegOpenUSKeyW") +#pragma comment(linker, "/EXPORT:SHRegQueryInfoUSKeyA=shlwapi.SHRegQueryInfoUSKeyA") +#pragma comment(linker, "/EXPORT:SHRegQueryInfoUSKeyW=shlwapi.SHRegQueryInfoUSKeyW") +#pragma comment(linker, "/EXPORT:SHRegQueryUSValueA=shlwapi.SHRegQueryUSValueA") +#pragma comment(linker, "/EXPORT:SHRegQueryUSValueW=shlwapi.SHRegQueryUSValueW") +#pragma comment(linker, "/EXPORT:SHRegSetPathA=shlwapi.SHRegSetPathA") +#pragma comment(linker, "/EXPORT:SHRegSetPathW=shlwapi.SHRegSetPathW") +#pragma comment(linker, "/EXPORT:SHRegSetUSValueA=shlwapi.SHRegSetUSValueA") +#pragma comment(linker, "/EXPORT:SHRegSetUSValueW=shlwapi.SHRegSetUSValueW") +#pragma comment(linker, "/EXPORT:SHRegWriteUSValueA=shlwapi.SHRegWriteUSValueA") +#pragma comment(linker, "/EXPORT:SHRegWriteUSValueW=shlwapi.SHRegWriteUSValueW") +#pragma comment(linker, "/EXPORT:SHRegisterValidateTemplate=shlwapi.SHRegisterValidateTemplate") +#pragma comment(linker, "/EXPORT:SHReleaseThreadRef=shlwapi.SHReleaseThreadRef") +#pragma comment(linker, "/EXPORT:SHRunIndirectRegClientCommand=shlwapi.SHRunIndirectRegClientCommand") +#pragma comment(linker, "/EXPORT:SHSendMessageBroadcastA=shlwapi.SHSendMessageBroadcastA") +#pragma comment(linker, "/EXPORT:SHSendMessageBroadcastW=shlwapi.SHSendMessageBroadcastW") +#pragma comment(linker, "/EXPORT:SHSetThreadRef=shlwapi.SHSetThreadRef") +#pragma comment(linker, "/EXPORT:SHSetValueA=shlwapi.SHSetValueA") +#pragma comment(linker, "/EXPORT:SHSetValueW=shlwapi.SHSetValueW") +#pragma comment(linker, "/EXPORT:SHSkipJunction=shlwapi.SHSkipJunction") +#pragma comment(linker, "/EXPORT:SHStrDupA=shlwapi.SHStrDupA") +#pragma comment(linker, "/EXPORT:SHStrDupW=shlwapi.SHStrDupW") +#pragma comment(linker, "/EXPORT:SHStripMneumonicA=shlwapi.SHStripMneumonicA") +#pragma comment(linker, "/EXPORT:SHStripMneumonicW=shlwapi.SHStripMneumonicW") +#pragma comment(linker, "/EXPORT:SHUnicodeToAnsi=shlwapi.SHUnicodeToAnsi") +#pragma comment(linker, "/EXPORT:SHUnicodeToUnicode=shlwapi.SHUnicodeToUnicode") +#pragma comment(linker, "/EXPORT:SHUnlockShared=shlwapi.SHUnlockShared") +#pragma comment(linker, "/EXPORT:ShellMessageBoxA=shlwapi.ShellMessageBoxA") +#pragma comment(linker, "/EXPORT:ShellMessageBoxW=shlwapi.ShellMessageBoxW") +#pragma comment(linker, "/EXPORT:StrCSpnA=shlwapi.StrCSpnA") +#pragma comment(linker, "/EXPORT:StrCSpnIA=shlwapi.StrCSpnIA") +#pragma comment(linker, "/EXPORT:StrCSpnIW=shlwapi.StrCSpnIW") +#pragma comment(linker, "/EXPORT:StrCSpnW=shlwapi.StrCSpnW") +#pragma comment(linker, "/EXPORT:StrCatBuffA=shlwapi.StrCatBuffA") +#pragma comment(linker, "/EXPORT:StrCatBuffW=shlwapi.StrCatBuffW") +#pragma comment(linker, "/EXPORT:StrCatChainW=shlwapi.StrCatChainW") +#pragma comment(linker, "/EXPORT:StrCatW=shlwapi.StrCatW") +#pragma comment(linker, "/EXPORT:StrChrA=shlwapi.StrChrA") +#pragma comment(linker, "/EXPORT:StrChrIA=shlwapi.StrChrIA") +#pragma comment(linker, "/EXPORT:StrChrIW=shlwapi.StrChrIW") +#pragma comment(linker, "/EXPORT:StrChrNIW=shlwapi.StrChrNIW") +#pragma comment(linker, "/EXPORT:StrChrNW=shlwapi.StrChrNW") +#pragma comment(linker, "/EXPORT:StrChrW=shlwapi.StrChrW") +#pragma comment(linker, "/EXPORT:StrCmpCA=shlwapi.StrCmpCA") +#pragma comment(linker, "/EXPORT:StrCmpCW=shlwapi.StrCmpCW") +#pragma comment(linker, "/EXPORT:StrCmpICA=shlwapi.StrCmpICA") +#pragma comment(linker, "/EXPORT:StrCmpICW=shlwapi.StrCmpICW") +#pragma comment(linker, "/EXPORT:StrCmpIW=shlwapi.StrCmpIW") +#pragma comment(linker, "/EXPORT:StrCmpLogicalW=shlwapi.StrCmpLogicalW") +#pragma comment(linker, "/EXPORT:StrCmpNA=shlwapi.StrCmpNA") +#pragma comment(linker, "/EXPORT:StrCmpNCA=shlwapi.StrCmpNCA") +#pragma comment(linker, "/EXPORT:StrCmpNCW=shlwapi.StrCmpNCW") +#pragma comment(linker, "/EXPORT:StrCmpNIA=shlwapi.StrCmpNIA") +#pragma comment(linker, "/EXPORT:StrCmpNICA=shlwapi.StrCmpNICA") +#pragma comment(linker, "/EXPORT:StrCmpNICW=shlwapi.StrCmpNICW") +#pragma comment(linker, "/EXPORT:StrCmpNIW=shlwapi.StrCmpNIW") +#pragma comment(linker, "/EXPORT:StrCmpNW=shlwapi.StrCmpNW") +#pragma comment(linker, "/EXPORT:StrCmpW=shlwapi.StrCmpW") +#pragma comment(linker, "/EXPORT:StrCpyNW=shlwapi.StrCpyNW") +#pragma comment(linker, "/EXPORT:StrCpyW=shlwapi.StrCpyW") +#pragma comment(linker, "/EXPORT:StrDupA=shlwapi.StrDupA") +#pragma comment(linker, "/EXPORT:StrDupW=shlwapi.StrDupW") +#pragma comment(linker, "/EXPORT:StrFormatByteSize64A=shlwapi.StrFormatByteSize64A") +#pragma comment(linker, "/EXPORT:StrFormatByteSizeA=shlwapi.StrFormatByteSizeA") +#pragma comment(linker, "/EXPORT:StrFormatByteSizeEx=shlwapi.StrFormatByteSizeEx") +#pragma comment(linker, "/EXPORT:StrFormatByteSizeW=shlwapi.StrFormatByteSizeW") +#pragma comment(linker, "/EXPORT:StrFormatKBSizeA=shlwapi.StrFormatKBSizeA") +#pragma comment(linker, "/EXPORT:StrFormatKBSizeW=shlwapi.StrFormatKBSizeW") +#pragma comment(linker, "/EXPORT:StrFromTimeIntervalA=shlwapi.StrFromTimeIntervalA") +#pragma comment(linker, "/EXPORT:StrFromTimeIntervalW=shlwapi.StrFromTimeIntervalW") +#pragma comment(linker, "/EXPORT:StrIsIntlEqualA=shlwapi.StrIsIntlEqualA") +#pragma comment(linker, "/EXPORT:StrIsIntlEqualW=shlwapi.StrIsIntlEqualW") +#pragma comment(linker, "/EXPORT:StrNCatA=shlwapi.StrNCatA") +#pragma comment(linker, "/EXPORT:StrNCatW=shlwapi.StrNCatW") +#pragma comment(linker, "/EXPORT:StrPBrkA=shlwapi.StrPBrkA") +#pragma comment(linker, "/EXPORT:StrPBrkW=shlwapi.StrPBrkW") +#pragma comment(linker, "/EXPORT:StrRChrA=shlwapi.StrRChrA") +#pragma comment(linker, "/EXPORT:StrRChrIA=shlwapi.StrRChrIA") +#pragma comment(linker, "/EXPORT:StrRChrIW=shlwapi.StrRChrIW") +#pragma comment(linker, "/EXPORT:StrRChrW=shlwapi.StrRChrW") +#pragma comment(linker, "/EXPORT:StrRStrIA=shlwapi.StrRStrIA") +#pragma comment(linker, "/EXPORT:StrRStrIW=shlwapi.StrRStrIW") +#pragma comment(linker, "/EXPORT:StrRetToBSTR=shlwapi.StrRetToBSTR") +#pragma comment(linker, "/EXPORT:StrRetToBufA=shlwapi.StrRetToBufA") +#pragma comment(linker, "/EXPORT:StrRetToBufW=shlwapi.StrRetToBufW") +#pragma comment(linker, "/EXPORT:StrRetToStrA=shlwapi.StrRetToStrA") +#pragma comment(linker, "/EXPORT:StrRetToStrW=shlwapi.StrRetToStrW") +#pragma comment(linker, "/EXPORT:StrSpnA=shlwapi.StrSpnA") +#pragma comment(linker, "/EXPORT:StrSpnW=shlwapi.StrSpnW") +#pragma comment(linker, "/EXPORT:StrStrA=shlwapi.StrStrA") +#pragma comment(linker, "/EXPORT:StrStrIA=shlwapi.StrStrIA") +#pragma comment(linker, "/EXPORT:StrStrIW=shlwapi.StrStrIW") +#pragma comment(linker, "/EXPORT:StrStrNIW=shlwapi.StrStrNIW") +#pragma comment(linker, "/EXPORT:StrStrNW=shlwapi.StrStrNW") +#pragma comment(linker, "/EXPORT:StrStrW=shlwapi.StrStrW") +#pragma comment(linker, "/EXPORT:StrToInt64ExA=shlwapi.StrToInt64ExA") +#pragma comment(linker, "/EXPORT:StrToInt64ExW=shlwapi.StrToInt64ExW") +#pragma comment(linker, "/EXPORT:StrToIntA=shlwapi.StrToIntA") +#pragma comment(linker, "/EXPORT:StrToIntExA=shlwapi.StrToIntExA") +#pragma comment(linker, "/EXPORT:StrToIntExW=shlwapi.StrToIntExW") +#pragma comment(linker, "/EXPORT:StrToIntW=shlwapi.StrToIntW") +#pragma comment(linker, "/EXPORT:StrTrimA=shlwapi.StrTrimA") +#pragma comment(linker, "/EXPORT:StrTrimW=shlwapi.StrTrimW") +#pragma comment(linker, "/EXPORT:UrlApplySchemeA=shlwapi.UrlApplySchemeA") +#pragma comment(linker, "/EXPORT:UrlApplySchemeW=shlwapi.UrlApplySchemeW") +#pragma comment(linker, "/EXPORT:UrlCanonicalizeA=shlwapi.UrlCanonicalizeA") +#pragma comment(linker, "/EXPORT:UrlCanonicalizeW=shlwapi.UrlCanonicalizeW") +#pragma comment(linker, "/EXPORT:UrlCombineA=shlwapi.UrlCombineA") +#pragma comment(linker, "/EXPORT:UrlCombineW=shlwapi.UrlCombineW") +#pragma comment(linker, "/EXPORT:UrlCompareA=shlwapi.UrlCompareA") +#pragma comment(linker, "/EXPORT:UrlCompareW=shlwapi.UrlCompareW") +#pragma comment(linker, "/EXPORT:UrlCreateFromPathA=shlwapi.UrlCreateFromPathA") +#pragma comment(linker, "/EXPORT:UrlCreateFromPathW=shlwapi.UrlCreateFromPathW") +#pragma comment(linker, "/EXPORT:UrlEscapeA=shlwapi.UrlEscapeA") +#pragma comment(linker, "/EXPORT:UrlEscapeW=shlwapi.UrlEscapeW") +#pragma comment(linker, "/EXPORT:UrlFixupW=shlwapi.UrlFixupW") +#pragma comment(linker, "/EXPORT:UrlGetLocationA=shlwapi.UrlGetLocationA") +#pragma comment(linker, "/EXPORT:UrlGetLocationW=shlwapi.UrlGetLocationW") +#pragma comment(linker, "/EXPORT:UrlGetPartA=shlwapi.UrlGetPartA") +#pragma comment(linker, "/EXPORT:UrlGetPartW=shlwapi.UrlGetPartW") +#pragma comment(linker, "/EXPORT:UrlHashA=shlwapi.UrlHashA") +#pragma comment(linker, "/EXPORT:UrlHashW=shlwapi.UrlHashW") +#pragma comment(linker, "/EXPORT:UrlIsA=shlwapi.UrlIsA") +#pragma comment(linker, "/EXPORT:UrlIsNoHistoryA=shlwapi.UrlIsNoHistoryA") +#pragma comment(linker, "/EXPORT:UrlIsNoHistoryW=shlwapi.UrlIsNoHistoryW") +#pragma comment(linker, "/EXPORT:UrlIsOpaqueA=shlwapi.UrlIsOpaqueA") +#pragma comment(linker, "/EXPORT:UrlIsOpaqueW=shlwapi.UrlIsOpaqueW") +#pragma comment(linker, "/EXPORT:UrlIsW=shlwapi.UrlIsW") +#pragma comment(linker, "/EXPORT:UrlUnescapeA=shlwapi.UrlUnescapeA") +#pragma comment(linker, "/EXPORT:UrlUnescapeW=shlwapi.UrlUnescapeW") +#pragma comment(linker, "/EXPORT:WhichPlatform=shlwapi.WhichPlatform") +#pragma comment(linker, "/EXPORT:wnsprintfA=shlwapi.wnsprintfA") +#pragma comment(linker, "/EXPORT:wnsprintfW=shlwapi.wnsprintfW") +#pragma comment(linker, "/EXPORT:wvnsprintfA=shlwapi.wvnsprintfA") +#pragma comment(linker, "/EXPORT:wvnsprintfW=shlwapi.wvnsprintfW") + +#pragma comment(linker, "/EXPORT:SHExpandEnvironmentStringsA=shlwapi.#459,@459") +#pragma comment(linker, "/EXPORT:SHExpandEnvironmentStringsW=shlwapi.#460,@460") + +#endif \ No newline at end of file diff --git a/01-Extended DLLs/KxUser/kxuser.def b/01-Extended DLLs/KxUser/kxuser.def new file mode 100644 index 0000000..5ebcaf3 --- /dev/null +++ b/01-Extended DLLs/KxUser/kxuser.def @@ -0,0 +1,94 @@ +LIBRARY KxUser +EXPORTS + ;; + ;; autorot.c + ;; + + SetDisplayAutoRotationPreferences + GetDisplayAutoRotationPreferences + + ;; + ;; blutooth.c + ;; + + BluetoothGATTAbortReliableWrite + BluetoothGATTBeginReliableWrite + BluetoothGATTEndReliableWrite + BluetoothGATTGetCharacteristics + BluetoothGATTGetCharacteristicValue + BluetoothGATTGetDescriptors + BluetoothGATTGetDescriptorValue + BluetoothGATTGetIncludedServices + BluetoothGATTGetServices + BluetoothGATTRegisterEvent + BluetoothGATTSetCharacteristicValue + BluetoothGATTSetDescriptorValue + BluetoothGATTUnregisterEvent + + ;; + ;; misc.c + ;; + + CreateWindowInBand + GetWindowBand + GetProcessUIContextInformation @2521 NONAME + GetCurrentInputMessageSource + IsImmersiveProcess + + ;; + ;; pointer.c + ;; + + GetPointerDevices + GetPointerType + GetPointerInfo + GetPointerTouchInfo + GetPointerFrameTouchInfo + GetPointerFrameTouchInfoHistory + GetPointerPenInfo + GetPointerPenInfoHistory + SkipPointerFrameMessages + GetPointerDeviceRects + EnableMouseInPointer + + ;; + ;; pwrnotfy.c + ;; + + RegisterSuspendResumeNotification + UnregisterSuspendResumeNotification + + ;; + ;; scaling.c + ;; + + GetDpiForSystem + GetDpiForWindow + GetDpiForMonitor + GetScaleFactorForMonitor + GetProcessDpiAwareness + GetProcessDpiAwarenessInternal + SetProcessDpiAwareness + GetThreadDpiAwarenessContext + SetThreadDpiAwarenessContext + SetProcessDpiAwarenessContext + SetProcessDpiAwarenessInternal + AdjustWindowRectExForDpi + GetAwarenessFromDpiAwarenessContext + GetWindowDpiAwarenessContext + EnableNonClientDpiScaling + AreDpiAwarenessContextsEqual + IsValidDpiAwarenessContext + + ;; + ;; sysmetrc.c + ;; + + GetSystemMetricsForDpi + SystemParametersInfoForDpi + + ;; + ;; timer.c + ;; + + SetCoalescableTimer \ No newline at end of file diff --git a/01-Extended DLLs/KxUser/kxuserp.h b/01-Extended DLLs/KxUser/kxuserp.h new file mode 100644 index 0000000..86898a8 --- /dev/null +++ b/01-Extended DLLs/KxUser/kxuserp.h @@ -0,0 +1,27 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// kxuserp.h +// +// Abstract: +// +// Private header file for KxUser. +// +// Author: +// +// vxiiduu (10-Feb-2022) +// +// Revision History: +// +// vxiiduu 10-Feb-2022 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include +#include + +EXTERN PKEX_PROCESS_DATA KexData; \ No newline at end of file diff --git a/01-Extended DLLs/KxUser/misc.c b/01-Extended DLLs/KxUser/misc.c new file mode 100644 index 0000000..154a1a1 --- /dev/null +++ b/01-Extended DLLs/KxUser/misc.c @@ -0,0 +1,90 @@ +#include "buildcfg.h" +#include "kxuserp.h" + +KXUSERAPI BOOL WINAPI GetProcessUIContextInformation( + IN HANDLE ProcessHandle, + OUT PPROCESS_UICONTEXT_INFORMATION UIContextInformation) +{ + if (!UIContextInformation) { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + UIContextInformation->UIContext = PROCESS_UICONTEXT_DESKTOP; + UIContextInformation->Flags = PROCESS_UIF_NONE; + + return TRUE; +} + +KXUSERAPI HWND WINAPI CreateWindowInBand( + IN DWORD dwExStyle, + IN PCWSTR lpClassName, + IN PCWSTR lpWindowName, + IN DWORD dwStyle, + IN INT X, + IN INT Y, + IN INT nWidth, + IN INT nHeight, + IN HWND hWndParent, + IN HMENU hMenu, + IN HINSTANCE hInstance, + IN PVOID lpParam, + IN ZBID zbid) +{ + return CreateWindowExW( + dwExStyle, + lpClassName, + lpWindowName, + dwStyle, + X, + Y, + nWidth, + nHeight, + hWndParent, + hMenu, + hInstance, + lpParam); +} + +KXUSERAPI BOOL WINAPI GetWindowBand( + IN HWND Window, + OUT PZBID Band) +{ + if (!IsWindow(Window)) { + SetLastError(ERROR_INVALID_WINDOW_HANDLE); + return FALSE; + } + + if (!Band) { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + if (Window == GetDesktopWindow()) { + *Band = ZBID_DESKTOP; + } else { + *Band = ZBID_DEFAULT; + } + + return TRUE; +} + +KXUSERAPI BOOL WINAPI GetCurrentInputMessageSource( + OUT PINPUT_MESSAGE_SOURCE MessageSource) +{ + if (!MessageSource) { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + MessageSource->DeviceType = IMDT_UNAVAILABLE; + MessageSource->OriginId = IMO_UNAVAILABLE; + return TRUE; +} + +KXUSERAPI BOOL WINAPI IsImmersiveProcess( + IN HANDLE ProcessHandle) +{ + SetLastError(ERROR_SUCCESS); + return FALSE; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxUser/pointer.c b/01-Extended DLLs/KxUser/pointer.c new file mode 100644 index 0000000..9ec8a59 --- /dev/null +++ b/01-Extended DLLs/KxUser/pointer.c @@ -0,0 +1,111 @@ +#include "buildcfg.h" +#include "kxuserp.h" + +BOOL WINAPI GetPointerDevices( + IN OUT UINT32 *DeviceCount, + OUT POINTER_DEVICE_INFO *PointerDevices) +{ + *DeviceCount = 0; + return TRUE; +} + +BOOL WINAPI GetPointerType( + IN DWORD PointerId, + OUT POINTER_INPUT_TYPE *PointerType) +{ + *PointerType = PT_MOUSE; + return TRUE; +} + +BOOL WINAPI GetPointerInfo( + IN DWORD PointerId, + OUT POINTER_INFO *PointerInfo) +{ + PointerInfo->pointerType = PT_MOUSE; + PointerInfo->pointerId = PointerId; + PointerInfo->frameId = 0; + PointerInfo->pointerFlags = POINTER_FLAG_NONE; + PointerInfo->sourceDevice = NULL; + PointerInfo->hwndTarget = NULL; + GetCursorPos(&PointerInfo->ptPixelLocation); + GetCursorPos(&PointerInfo->ptHimetricLocation); + GetCursorPos(&PointerInfo->ptPixelLocationRaw); + GetCursorPos(&PointerInfo->ptHimetricLocationRaw); + PointerInfo->dwTime = 0; + PointerInfo->historyCount = 1; + PointerInfo->InputData = 0; + PointerInfo->dwKeyStates = 0; + PointerInfo->PerformanceCount = 0; + PointerInfo->ButtonChangeType = POINTER_CHANGE_NONE; + + return TRUE; +} + +BOOL WINAPI GetPointerTouchInfo( + IN DWORD PointerId, + OUT LPVOID TouchInfo) +{ + return FALSE; +} + +BOOL WINAPI GetPointerFrameTouchInfo( + IN DWORD PointerId, + IN OUT LPDWORD PointerCount, + OUT LPVOID TouchInfo) +{ + return FALSE; +} + +BOOL WINAPI GetPointerFrameTouchInfoHistory( + IN DWORD PointerId, + IN OUT DWORD EntriesCount, + IN OUT LPDWORD PointerCount, + OUT LPVOID TouchInfo) +{ + return FALSE; +} + +BOOL WINAPI GetPointerPenInfo( + IN DWORD PointerId, + OUT LPVOID PenInfo) +{ + return FALSE; +} + +BOOL WINAPI GetPointerPenInfoHistory( + IN DWORD PointerId, + IN OUT LPDWORD EntriesCount, + OUT LPVOID PenInfo) +{ + return FALSE; +} + +BOOL WINAPI SkipPointerFrameMessages( + IN DWORD PointerId) +{ + return TRUE; +} + +BOOL WINAPI GetPointerDeviceRects( + IN HANDLE Device, + OUT LPRECT PointerDeviceRect, + OUT LPRECT DisplayRect) +{ + PointerDeviceRect->top = 0; + PointerDeviceRect->left = 0; + PointerDeviceRect->bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN); + PointerDeviceRect->right = GetSystemMetrics(SM_CXVIRTUALSCREEN); + + DisplayRect->top = 0; + DisplayRect->left = 0; + DisplayRect->bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN); + DisplayRect->right = GetSystemMetrics(SM_CXVIRTUALSCREEN); + + return TRUE; +} + +BOOL WINAPI EnableMouseInPointer( + IN BOOL Enable) +{ + return FALSE; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxUser/pwrnotfy.c b/01-Extended DLLs/KxUser/pwrnotfy.c new file mode 100644 index 0000000..4c82c0f --- /dev/null +++ b/01-Extended DLLs/KxUser/pwrnotfy.c @@ -0,0 +1,54 @@ +#include "buildcfg.h" +#include "kxuserp.h" +#include + +STATIC ULONG CALLBACK PowerSuspendResumeCallback( + IN PVOID Context OPTIONAL, + IN ULONG Type, + IN PVOID Setting) +{ + return 0; +} + +KXUSERAPI BOOL WINAPI RegisterSuspendResumeNotification( + IN HANDLE Recipient, + IN ULONG Flags) +{ + ULONG ErrorCode; + HPOWERNOTIFY RegistrationHandle; + DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS NotifySubscribeParameters; + + if (Flags == DEVICE_NOTIFY_WINDOW_HANDLE) { + NotifySubscribeParameters.Callback = PowerSuspendResumeCallback; + NotifySubscribeParameters.Context = (HWND) Recipient; + } else { + NotifySubscribeParameters = *(PDEVICE_NOTIFY_SUBSCRIBE_PARAMETERS) Recipient; + } + + ErrorCode = PowerRegisterSuspendResumeNotification( + Flags, + &NotifySubscribeParameters, + &RegistrationHandle); + + if (ErrorCode != ERROR_SUCCESS) { + SetLastError(ErrorCode); + return FALSE; + } + + return TRUE; +} + +KXUSERAPI BOOL WINAPI UnregisterSuspendResumeNotification( + IN OUT HPOWERNOTIFY Handle) +{ + ULONG ErrorCode; + + ErrorCode = PowerUnregisterSuspendResumeNotification(Handle); + + if (ErrorCode != ERROR_SUCCESS) { + SetLastError(ErrorCode); + return FALSE; + } + + return TRUE; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxUser/scaling.c b/01-Extended DLLs/KxUser/scaling.c new file mode 100644 index 0000000..ed97811 --- /dev/null +++ b/01-Extended DLLs/KxUser/scaling.c @@ -0,0 +1,320 @@ +#include "buildcfg.h" +#include "kxuserp.h" + +KXUSERAPI BOOL WINAPI AreDpiAwarenessContextsEqual( + IN DPI_AWARENESS_CONTEXT Value1, + IN DPI_AWARENESS_CONTEXT Value2) +{ + return (Value1 == Value2); +} + +KXUSERAPI BOOL WINAPI IsValidDpiAwarenessContext( + IN DPI_AWARENESS_CONTEXT Value) +{ + switch (Value) { + case DPI_AWARENESS_CONTEXT_UNAWARE: + case DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED: + case DPI_AWARENESS_CONTEXT_SYSTEM_AWARE: + case DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE: + case DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2: + return TRUE; + default: + return FALSE; + } +} + +KXUSERAPI DPI_AWARENESS WINAPI GetAwarenessFromDpiAwarenessContext( + IN DPI_AWARENESS_CONTEXT Value) +{ + switch (Value) { + case DPI_AWARENESS_CONTEXT_UNAWARE: + case DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED: + return DPI_AWARENESS_UNAWARE; + case DPI_AWARENESS_CONTEXT_SYSTEM_AWARE: + return DPI_AWARENESS_SYSTEM_AWARE; + case DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE: + case DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2: + return DPI_AWARENESS_PER_MONITOR_AWARE; + default: + return DPI_AWARENESS_INVALID; + } +} + +KXUSERAPI DPI_AWARENESS_CONTEXT WINAPI GetThreadDpiAwarenessContext( + VOID) +{ + if (IsProcessDPIAware()) { + return DPI_AWARENESS_CONTEXT_SYSTEM_AWARE; + } else { + return DPI_AWARENESS_CONTEXT_UNAWARE; + } +} + +KXUSERAPI DPI_AWARENESS_CONTEXT WINAPI SetThreadDpiAwarenessContext( + IN DPI_AWARENESS_CONTEXT DpiContext) +{ + BOOLEAN OldDpiAwareness; + + OldDpiAwareness = IsProcessDPIAware(); + + switch (DpiContext) { + case DPI_AWARENESS_CONTEXT_UNAWARE: + NOTHING; + break; + case DPI_AWARENESS_CONTEXT_SYSTEM_AWARE: + case DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE: + SetProcessDPIAware(); + break; + default: + return 0; + } + + if (OldDpiAwareness) { + return DPI_AWARENESS_CONTEXT_SYSTEM_AWARE; + } else { + return DPI_AWARENESS_CONTEXT_UNAWARE; + } +} + +KXUSERAPI BOOL WINAPI SetProcessDpiAwarenessContext( + IN DPI_AWARENESS_CONTEXT DpiContext) +{ + switch (DpiContext) { + case DPI_AWARENESS_CONTEXT_UNAWARE: + NOTHING; + break; + case DPI_AWARENESS_CONTEXT_SYSTEM_AWARE: + case DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE: + case DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2: + SetProcessDPIAware(); + break; + default: + return FALSE; + } + + return TRUE; +} + +KXUSERAPI DPI_AWARENESS_CONTEXT WINAPI GetWindowDpiAwarenessContext( + IN HWND Window) +{ + ULONG WindowThreadId; + ULONG WindowProcessId; + + WindowThreadId = GetWindowThreadProcessId(Window, &WindowProcessId); + if (!WindowThreadId) { + return 0; + } + + if (WindowProcessId = (ULONG) NtCurrentTeb()->ClientId.UniqueProcess) { + return GetThreadDpiAwarenessContext(); + } + + return DPI_AWARENESS_CONTEXT_UNAWARE; +} + +KXUSERAPI BOOL WINAPI GetProcessDpiAwarenessInternal( + IN HANDLE ProcessHandle, + OUT PROCESS_DPI_AWARENESS *DpiAwareness) +{ + if (ProcessHandle == NULL || + ProcessHandle == NtCurrentProcess() || + GetProcessId(ProcessHandle) == (ULONG) NtCurrentTeb()->ClientId.UniqueProcess) { + + *DpiAwareness = IsProcessDPIAware() ? PROCESS_SYSTEM_DPI_AWARE : PROCESS_DPI_UNAWARE; + } else { + *DpiAwareness = PROCESS_DPI_UNAWARE; + } + + return TRUE; +} + +KXUSERAPI HRESULT WINAPI GetProcessDpiAwareness( + IN HANDLE ProcessHandle, + OUT PROCESS_DPI_AWARENESS *DpiAwareness) +{ + BOOLEAN Success; + + Success = GetProcessDpiAwarenessInternal(ProcessHandle, DpiAwareness); + + if (!Success) { + return HRESULT_FROM_WIN32(GetLastError()); + } + + return S_OK; +} + +KXUSERAPI BOOL WINAPI SetProcessDpiAwarenessInternal( + IN PROCESS_DPI_AWARENESS DpiAwareness) +{ + if (DpiAwareness >= PROCESS_MAX_DPI_AWARENESS) { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + if (DpiAwareness != PROCESS_DPI_UNAWARE) { + // On Windows 7, SetProcessDPIAware() always returns TRUE + // no matter what, so there is no point in checking its + // return value. + SetProcessDPIAware(); + } + + return TRUE; +} + +KXUSERAPI HRESULT WINAPI SetProcessDpiAwareness( + IN PROCESS_DPI_AWARENESS Awareness) +{ + BOOLEAN Success; + + Success = SetProcessDpiAwarenessInternal(Awareness); + + if (!Success) { + return HRESULT_FROM_WIN32(GetLastError()); + } + + return S_OK; +} + +KXUSERAPI HRESULT WINAPI GetDpiForMonitor( + IN HMONITOR Monitor, + IN MONITOR_DPI_TYPE DpiType, + OUT PULONG DpiX, + OUT PULONG DpiY) +{ + HDC DeviceContext; + + if (DpiType >= MDT_MAXIMUM_DPI) { + return E_INVALIDARG; + } + + if (!DpiX || !DpiY) { + return E_INVALIDARG; + } + + if (!IsProcessDPIAware()) { + *DpiX = USER_DEFAULT_SCREEN_DPI; + *DpiY = USER_DEFAULT_SCREEN_DPI; + return S_OK; + } + + DeviceContext = GetDC(NULL); + if (!DeviceContext) { + *DpiX = USER_DEFAULT_SCREEN_DPI; + *DpiY = USER_DEFAULT_SCREEN_DPI; + return S_OK; + } + + *DpiX = GetDeviceCaps(DeviceContext, LOGPIXELSX); + *DpiY = GetDeviceCaps(DeviceContext, LOGPIXELSY); + + if (DpiType == MDT_EFFECTIVE_DPI) { + DEVICE_SCALE_FACTOR ScaleFactor; + + // We have to multiply the DPI values by the scaling factor. + GetScaleFactorForMonitor(Monitor, &ScaleFactor); + + *DpiX *= ScaleFactor; + *DpiY *= ScaleFactor; + *DpiX /= 100; + *DpiY /= 100; + } + + ReleaseDC(NULL, DeviceContext); + return S_OK; +} + +KXUSERAPI HRESULT WINAPI GetScaleFactorForMonitor( + IN HMONITOR Monitor, + OUT PDEVICE_SCALE_FACTOR ScaleFactor) +{ + HDC DeviceContext; + ULONG LogPixelsX; + + DeviceContext = GetDC(NULL); + if (!DeviceContext) { + *ScaleFactor = SCALE_100_PERCENT; + return S_OK; + } + + LogPixelsX = GetDeviceCaps(DeviceContext, LOGPIXELSX); + ReleaseDC(NULL, DeviceContext); + + *ScaleFactor = (DEVICE_SCALE_FACTOR) (9600 / LogPixelsX); + return S_OK; +} + +KXUSERAPI UINT WINAPI GetDpiForSystem( + VOID) +{ + HDC DeviceContext; + ULONG LogPixelsX; + + if (!IsProcessDPIAware()) { + return 96; + } + + DeviceContext = GetDC(NULL); + if (!DeviceContext) { + return 96; + } + + LogPixelsX = GetDeviceCaps(DeviceContext, LOGPIXELSX); + ReleaseDC(NULL, DeviceContext); + + return LogPixelsX; +} + +KXUSERAPI UINT WINAPI GetDpiForWindow( + IN HWND Window) +{ + if (!IsWindow(Window)) { + return 0; + } + + return GetDpiForSystem(); +} + +KXUSERAPI BOOL WINAPI AdjustWindowRectExForDpi( + IN OUT LPRECT Rect, + IN ULONG WindowStyle, + IN BOOL HasMenu, + IN ULONG WindowExStyle, + IN ULONG Dpi) +{ + // I'm not sure how to implement this function properly. + // If it turns out to be important, I'll have to do some testing + // on a Win10 VM. + + return AdjustWindowRectEx( + Rect, + WindowStyle, + HasMenu, + WindowExStyle); +} + +KXUSERAPI UINT WINAPI GetDpiForShellUIComponent( + IN SHELL_UI_COMPONENT component) +{ + return GetDpiForSystem(); +}; + +KXUSERAPI BOOL WINAPI LogicalToPhysicalPointForPerMonitorDPI( + IN HWND Window, + IN OUT PPOINT Point) +{ + return LogicalToPhysicalPoint(Window, Point); +} + +KXUSERAPI BOOL WINAPI PhysicalToLogicalPointForPerMonitorDPI( + IN HWND Window, + IN OUT PPOINT Point) +{ + return PhysicalToLogicalPoint(Window, Point); +} + +KXUSERAPI BOOL WINAPI EnableNonClientDpiScaling( + IN HWND Window) +{ + return TRUE; +} \ No newline at end of file diff --git a/01-Extended DLLs/KxUser/sysmetrc.c b/01-Extended DLLs/KxUser/sysmetrc.c new file mode 100644 index 0000000..9e1975d --- /dev/null +++ b/01-Extended DLLs/KxUser/sysmetrc.c @@ -0,0 +1,119 @@ +#include "buildcfg.h" +#include "kxuserp.h" + +INT WINAPI GetSystemMetricsForDpi( + IN INT Index, + IN UINT Dpi) +{ + INT Value; + + Value = GetSystemMetrics(Index); + + switch (Index) { + case SM_CXVSCROLL: + case SM_CYHSCROLL: + case SM_CYCAPTION: + case SM_CYVTHUMB: + case SM_CXHTHUMB: + case SM_CXICON: + case SM_CYICON: + case SM_CXCURSOR: + case SM_CYCURSOR: + case SM_CYMENU: + case SM_CYVSCROLL: + case SM_CXHSCROLL: + case SM_CXMIN: + case SM_CXMINTRACK: + case SM_CYMIN: + case SM_CYMINTRACK: + case SM_CXSIZE: + case SM_CXFRAME: + case SM_CYFRAME: + case SM_CXICONSPACING: + case SM_CYICONSPACING: + case SM_CXSMICON: + case SM_CYSMICON: + case SM_CYSMCAPTION: + case SM_CXSMSIZE: + case SM_CYSMSIZE: + case SM_CXMENUSIZE: + case SM_CYMENUSIZE: + case SM_CXMENUCHECK: + case SM_CYMENUCHECK: + // These are pixel values that have to be scaled according to DPI. + Value *= Dpi; + Value /= USER_DEFAULT_SCREEN_DPI; + break; + } + + return Value; +} + +BOOL WINAPI SystemParametersInfoForDpi( + IN UINT Action, + IN UINT Parameter, + IN OUT PVOID Data, + IN UINT WinIni, + IN UINT Dpi) +{ + switch (Action) { + case SPI_GETICONTITLELOGFONT: + return SystemParametersInfo(Action, Parameter, Data, 0); + case SPI_GETICONMETRICS: + { + BOOL Success; + PICONMETRICS IconMetrics; + + Success = SystemParametersInfo(Action, Parameter, Data, 0); + + if (Success) { + IconMetrics = (PICONMETRICS) Data; + + IconMetrics->iHorzSpacing *= Dpi; + IconMetrics->iVertSpacing *= Dpi; + IconMetrics->iHorzSpacing /= USER_DEFAULT_SCREEN_DPI; + IconMetrics->iVertSpacing /= USER_DEFAULT_SCREEN_DPI; + } + + return Success; + } + case SPI_GETNONCLIENTMETRICS: + { + BOOL Success; + PNONCLIENTMETRICS NonClientMetrics; + + Success = SystemParametersInfo(Action, Parameter, Data, 0); + + if (Success) { + NonClientMetrics = (PNONCLIENTMETRICS) Data; + + NonClientMetrics->iBorderWidth *= Dpi; + NonClientMetrics->iScrollWidth *= Dpi; + NonClientMetrics->iScrollHeight *= Dpi; + NonClientMetrics->iCaptionWidth *= Dpi; + NonClientMetrics->iCaptionHeight *= Dpi; + NonClientMetrics->iSmCaptionWidth *= Dpi; + NonClientMetrics->iSmCaptionHeight *= Dpi; + NonClientMetrics->iMenuWidth *= Dpi; + NonClientMetrics->iMenuHeight *= Dpi; + NonClientMetrics->iPaddedBorderWidth *= Dpi; + + NonClientMetrics->iBorderWidth /= USER_DEFAULT_SCREEN_DPI; + NonClientMetrics->iScrollWidth /= USER_DEFAULT_SCREEN_DPI; + NonClientMetrics->iScrollHeight /= USER_DEFAULT_SCREEN_DPI; + NonClientMetrics->iCaptionWidth /= USER_DEFAULT_SCREEN_DPI; + NonClientMetrics->iCaptionHeight /= USER_DEFAULT_SCREEN_DPI; + NonClientMetrics->iSmCaptionWidth /= USER_DEFAULT_SCREEN_DPI; + NonClientMetrics->iSmCaptionHeight /= USER_DEFAULT_SCREEN_DPI; + NonClientMetrics->iMenuWidth /= USER_DEFAULT_SCREEN_DPI; + NonClientMetrics->iMenuHeight /= USER_DEFAULT_SCREEN_DPI; + NonClientMetrics->iPaddedBorderWidth /= USER_DEFAULT_SCREEN_DPI; + } + + return Success; + } + default: + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } +} \ No newline at end of file diff --git a/01-Extended DLLs/KxUser/timer.c b/01-Extended DLLs/KxUser/timer.c new file mode 100644 index 0000000..4d91d5b --- /dev/null +++ b/01-Extended DLLs/KxUser/timer.c @@ -0,0 +1,27 @@ +#include "buildcfg.h" +#include "kxuserp.h" + +// +// Coalescable timers are a power-saving feature. They reduce the timer precision +// in exchange for greater energy efficiency, since timers can be "coalesced" and +// batches of timers can be handled at once. This also means that we can just proxy +// it directly to SetTimer() without causing any big problems. +// +// As an aside, on Windows 8, the uToleranceDelay parameter was added to the win32k +// function NtUserSetTimer, and SetCoalescableTimer is directly forwarded to +// NtUserSetTimer. The ordinary SetTimer is just a stub that calls NtUserSetTimer +// with the uToleranceDelay parameter set to zero. +// +// Windows 7 supports coalescable timers with SetWaitableTimerEx, but it is not +// simple to integrate that functionality with the User timers, so we don't bother. +// + +KXUSERAPI UINT_PTR WINAPI SetCoalescableTimer( + IN HWND hwnd, + IN UINT_PTR nIdEvent, + IN UINT uElapse, + IN TIMERPROC lpTimerFunc, + IN ULONG uToleranceDelay) +{ + return SetTimer(hwnd, nIdEvent, uElapse, lpTimerFunc); +} \ No newline at end of file diff --git a/01-Tests/loggingtest/loggingtest.vcxproj b/01-Tests/loggingtest/loggingtest.vcxproj new file mode 100644 index 0000000..61dfc9f --- /dev/null +++ b/01-Tests/loggingtest/loggingtest.vcxproj @@ -0,0 +1,167 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {8EEB6A31-BBE4-450C-AEF6-E4F81F63EF46} + Win32Proj + loggingtest + + + + Application + true + Unicode + + + Application + true + Unicode + + + Application + false + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + false + ProgramDatabase + + + Windows + true + $(SolutionDir)\00-Import Libraries;$(TargetDir) + + + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + false + ProgramDatabase + + + Windows + true + $(SolutionDir)\00-Import Libraries;$(TargetDir) + + + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + false + ProgramDatabase + + + Windows + true + true + true + $(SolutionDir)\00-Import Libraries;$(TargetDir) + + + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + false + ProgramDatabase + + + Windows + true + true + true + $(SolutionDir)\00-Import Libraries;$(TargetDir) + + + + + + + + + + + \ No newline at end of file diff --git a/01-Tests/loggingtest/loggingtest.vcxproj.filters b/01-Tests/loggingtest/loggingtest.vcxproj.filters new file mode 100644 index 0000000..38d25ce --- /dev/null +++ b/01-Tests/loggingtest/loggingtest.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + \ No newline at end of file diff --git a/01-Tests/loggingtest/test.c b/01-Tests/loggingtest/test.c new file mode 100644 index 0000000..ec81293 --- /dev/null +++ b/01-Tests/loggingtest/test.c @@ -0,0 +1,164 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// test.c +// +// Abstract: +// +// Utility for testing VXLL and creating large log files to test the +// performance of VxlView. +// +// Author: +// +// vxiiduu (14-Oct-2022) +// +// Revision History: +// +// vxiiduu 14-Oct-2022 Initial creation. +// vxiiduu 05-Jan-2023 Convert to user friendly NTSTATUS. +// +/////////////////////////////////////////////////////////////////////////////// + +#define KEX_TARGET_TYPE_EXE +#define KEX_COMPONENT L"LoggingTest" +#include +#include + +#define TEST_LOG_FILE_NAME L"\\??\\C:\\Users\\vxiiduu\\Desktop\\Test.vxl" +VXLHANDLE LogHandle; + +NTSTATUS NTAPI ThreadProc( + IN PVOID Parameter) +{ + NTSTATUS Status; + ULONG Index; + VXLSEVERITY Severity; + + Severity = (VXLSEVERITY) (ULONG) Parameter; + + for (Index = 0; Index < 100000; ++Index) { + Status = VxlWriteLog( + LogHandle, + KEX_COMPONENT, + Severity, + L"This is the %ld'th %s log entry.", + Index, + VxlSeverityToText(Severity, FALSE)); + + if (!NT_SUCCESS(Status)) { + DbgPrint("Failed to write log entry %ld of severity %ws: 0x%08lx\r\n", + Index, VxlSeverityToText(Severity, FALSE), Status); + } + } + + return Status; +} + +NTSTATUS NTAPI EntryPoint( + IN PVOID Parameter) +{ + NTSTATUS Status; + HRESULT Result; + UNICODE_STRING SourceApplication; + UNICODE_STRING LogFileName; + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE ThreadHandles[6]; + ULONG Index; + + RtlInitConstantUnicodeString(&SourceApplication, L"VxKex"); + RtlInitConstantUnicodeString(&LogFileName, TEST_LOG_FILE_NAME); + InitializeObjectAttributes(&ObjectAttributes, &LogFileName, OBJ_CASE_INSENSITIVE, NULL, NULL); + + Status = VxlOpenLog( + &LogHandle, + &SourceApplication, + &ObjectAttributes, + GENERIC_WRITE, + FILE_OPEN_IF); + + VxlWriteLog( + LogHandle, + KEX_COMPONENT, + LogSeverityInformation, + L"Logging Test application has been started\r\n\r\n" + L"This is a demonstration of multi-line log entries"); + + // + // Test making a shitload of source files, source functions and source components + // + + for (Index = 0; Index < 70; ++Index) { + WCHAR SourceFileString[64]; + WCHAR SourceFunctionString[64]; + WCHAR SourceComponentString[64]; + + Result = StringCchPrintf( + SourceFileString, + ARRAYSIZE(SourceFileString), + L"File%d", Index); + + Result = StringCchPrintf( + SourceFunctionString, + ARRAYSIZE(SourceFunctionString), + L"Function%d", Index); + + Result = StringCchPrintf( + SourceComponentString, + ARRAYSIZE(SourceComponentString), + L"Component%d", Index); + + Status = VxlWriteLogEx( + LogHandle, + SourceComponentString, + SourceFileString, + 69420, + SourceFunctionString, + LogSeverityDebug, + L"Test source file/function/component exceeding limit"); + + if (!NT_SUCCESS(Status)) { + DbgPrint("VxlWriteLogEx failed at iteration %d NTSTATUS 0x%08lx\r\n", Index, Status); + break; + } + } + + for (Index = 0; Index < 6; ++Index) { + Status = RtlCreateUserThread( + NtCurrentProcess(), + NULL, + FALSE, + 0, + 0, + 0, + ThreadProc, + (PVOID) Index, + &ThreadHandles[Index], + NULL); + + if (!NT_SUCCESS(Status)) { + DbgPrint("Failed to create thread #%d. NTSTATUS error code: %ws\r\n", + Index, KexRtlNtStatusToString(Status)); + NtTerminateProcess(NtCurrentProcess(), Status); + } + } + + Status = NtWaitForMultipleObjects( + ARRAYSIZE(ThreadHandles), + ThreadHandles, + WaitAllObject, + FALSE, + NULL); + + if (!NT_SUCCESS(Status)) { + DbgPrint("Failed to wait for threads to exit. NTSTATUS error code: %ws\r\n", + KexRtlNtStatusToString(Status)); + NtTerminateProcess(NtCurrentProcess(), Status); + } + + Status = VxlCloseLog(&LogHandle); + + // no need to bother closing thread handles + LdrShutdownProcess(); + return NtTerminateProcess(NtCurrentProcess(), Status); +} \ No newline at end of file diff --git a/02-Prebuilt DLLs/Readme.txt b/02-Prebuilt DLLs/Readme.txt new file mode 100644 index 0000000..5d5acaf --- /dev/null +++ b/02-Prebuilt DLLs/Readme.txt @@ -0,0 +1,3 @@ +These are pre-built DLLs from third party sources. +Most of the time, they are DLLs extracted from newer versions of Windows, +which may or may not have been modified to work with VxKex. \ No newline at end of file diff --git a/02-Prebuilt DLLs/x64/dcow8.dll b/02-Prebuilt DLLs/x64/dcow8.dll new file mode 100644 index 0000000..b228cb9 Binary files /dev/null and b/02-Prebuilt DLLs/x64/dcow8.dll differ diff --git a/02-Prebuilt DLLs/x64/dcow8.pdb b/02-Prebuilt DLLs/x64/dcow8.pdb new file mode 100644 index 0000000..47fe11a Binary files /dev/null and b/02-Prebuilt DLLs/x64/dcow8.pdb differ diff --git a/02-Prebuilt DLLs/x64/dwrw10.dll b/02-Prebuilt DLLs/x64/dwrw10.dll new file mode 100644 index 0000000..b0b6449 Binary files /dev/null and b/02-Prebuilt DLLs/x64/dwrw10.dll differ diff --git a/02-Prebuilt DLLs/x64/dwrw10.pdb b/02-Prebuilt DLLs/x64/dwrw10.pdb new file mode 100644 index 0000000..9c99070 Binary files /dev/null and b/02-Prebuilt DLLs/x64/dwrw10.pdb differ diff --git a/02-Prebuilt DLLs/x64/ucrtbase.dll b/02-Prebuilt DLLs/x64/ucrtbase.dll new file mode 100644 index 0000000..6129e68 Binary files /dev/null and b/02-Prebuilt DLLs/x64/ucrtbase.dll differ diff --git a/02-Prebuilt DLLs/x64/ucrtbase.pdb b/02-Prebuilt DLLs/x64/ucrtbase.pdb new file mode 100644 index 0000000..6c36ba8 Binary files /dev/null and b/02-Prebuilt DLLs/x64/ucrtbase.pdb differ diff --git a/02-Prebuilt DLLs/x86/dcow8.dll b/02-Prebuilt DLLs/x86/dcow8.dll new file mode 100644 index 0000000..1d25464 Binary files /dev/null and b/02-Prebuilt DLLs/x86/dcow8.dll differ diff --git a/02-Prebuilt DLLs/x86/dcow8.pdb b/02-Prebuilt DLLs/x86/dcow8.pdb new file mode 100644 index 0000000..c7193dd Binary files /dev/null and b/02-Prebuilt DLLs/x86/dcow8.pdb differ diff --git a/02-Prebuilt DLLs/x86/dwrw10.dll b/02-Prebuilt DLLs/x86/dwrw10.dll new file mode 100644 index 0000000..ffb7fc1 Binary files /dev/null and b/02-Prebuilt DLLs/x86/dwrw10.dll differ diff --git a/02-Prebuilt DLLs/x86/dwrw10.pdb b/02-Prebuilt DLLs/x86/dwrw10.pdb new file mode 100644 index 0000000..7a642df Binary files /dev/null and b/02-Prebuilt DLLs/x86/dwrw10.pdb differ diff --git a/02-Prebuilt DLLs/x86/ucrtbase.dll b/02-Prebuilt DLLs/x86/ucrtbase.dll new file mode 100644 index 0000000..c4f964b Binary files /dev/null and b/02-Prebuilt DLLs/x86/ucrtbase.dll differ diff --git a/02-Prebuilt DLLs/x86/ucrtbase.pdb b/02-Prebuilt DLLs/x86/ucrtbase.pdb new file mode 100644 index 0000000..81107b4 Binary files /dev/null and b/02-Prebuilt DLLs/x86/ucrtbase.pdb differ diff --git a/CpiwBypa/CpiwBypa.rc b/CpiwBypa/CpiwBypa.rc new file mode 100644 index 0000000..77126d6 --- /dev/null +++ b/CpiwBypa/CpiwBypa.rc @@ -0,0 +1,30 @@ +#include "buildcfg.h" +#include +#include + +1 VERSIONINFO + FILEVERSION KEX_VERSION_FV + FILEOS VOS_NT +#if defined(KEX_TARGET_TYPE_EXE) + FILETYPE VFT_APP +#elif defined(KEX_TARGET_TYPE_DLL) + FILETYPE VFT_DLL +#endif +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904B0" + BEGIN + VALUE "LegalCopyright", KEX_WEB_STR + VALUE "FileDescription", "Windows Explorer CPIW Version Check Bypass DLL" + VALUE "FileVersion", KEX_VERSION_STR + VALUE "InternalName", KEX_COMPONENT + VALUE "OriginalFilename", "CPIWBYPA.DLL" + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409 0x04B0 + END +END \ No newline at end of file diff --git a/CpiwBypa/CpiwBypa.vcxproj b/CpiwBypa/CpiwBypa.vcxproj new file mode 100644 index 0000000..0162f0f --- /dev/null +++ b/CpiwBypa/CpiwBypa.vcxproj @@ -0,0 +1,241 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {FED853B7-B02A-49FC-9FA9-DFCF8479841A} + Win32Proj + CpiwBypa + + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + + + + + + + + + + + + + + + + + false + false + + + false + false + + + false + false + + + false + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;CPIWBYPA_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + false + false + Default + false + StdCall + CompileAsC + + + + + Windows + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + DllMain + false + true + + + $(SolutionDir)\00-Common Headers + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;CPIWBYPA_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + false + false + Default + false + StdCall + CompileAsC + + + + + Windows + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + DllMain + false + true + + + $(SolutionDir)\00-Common Headers + + + + + Level3 + + + MinSpace + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;CPIWBYPA_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + false + false + Default + false + StdCall + CompileAsC + Size + true + + + + + Windows + true + true + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + DllMain + false + true + + + $(SolutionDir)\00-Common Headers + + + + + Level3 + + + MinSpace + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;CPIWBYPA_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + false + false + Default + false + StdCall + CompileAsC + Size + true + + + + + Windows + true + true + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + DllMain + false + true + + + $(SolutionDir)\00-Common Headers + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CpiwBypa/CpiwBypa.vcxproj.filters b/CpiwBypa/CpiwBypa.vcxproj.filters new file mode 100644 index 0000000..90df77d --- /dev/null +++ b/CpiwBypa/CpiwBypa.vcxproj.filters @@ -0,0 +1,32 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + Resource Files + + + + + Header Files + + + \ No newline at end of file diff --git a/CpiwBypa/buildcfg.h b/CpiwBypa/buildcfg.h new file mode 100644 index 0000000..bfd3514 --- /dev/null +++ b/CpiwBypa/buildcfg.h @@ -0,0 +1,42 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN +#define NOGDICAPMASKS +#define NOVIRTUALKEYCODES +#define NOWINSTYLES +#define NOSYSMETRICS +#define NOMENUS +#define NOICONS +#define NOKEYSTATES +#define NOSYSCOMMANDS +#define NORASTEROPS +#define NOSHOWWINDOW +#define NOATOM +#define NOCLIPBOARD +#define NOCOLOR +#define NODRAWTEXT +#define NOGDI +#define NOKERNEL +#define NONLS +#define NOMB +#define NOMEMMGR +#define NOOPENFILE +#define NOSCROLL +#define NOTEXTMETRIC +#define NOWH +#define NOWINOFFSETS +#define NOCOMM +#define NOKANJI +#define NOHELP +#define NOPROFILER +#define NODEFERWINDOWPOS +#define NOMCX +#define NOCRYPT +#define NOMETAFILE +#define NOSERVICE +#define NOSOUND +#define _UXTHEME_H_ + +#define KEX_COMPONENT L"CpiwBypa" +#define KEX_ENV_WIN32 +#define KEX_TARGET_TYPE_DLL diff --git a/CpiwBypa/dllmain.c b/CpiwBypa/dllmain.c new file mode 100644 index 0000000..ad56984 --- /dev/null +++ b/CpiwBypa/dllmain.c @@ -0,0 +1,116 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// dllmain.c +// +// Abstract: +// +// This DLL is a very small stub that gets loaded into Explorer at startup +// if the user hasn't disabled CPIW bypass for Explorer. +// +// The mechanism of loading is by being registered as a browser helper +// object (BHO). This means it can get loaded into Internet Explorer and +// potentially other processes as well, so we have to check whether we are +// actually loaded into %SystemRoot%\explorer.exe. KxCfgHlp does set some +// registry keys to stop this from happening but it's better safe than +// sorry. +// +// Its job is to patch CreateProcessInternalW to bypass the subsystem +// version check and then get unloaded (by returning FALSE from dllmain). +// +// Author: +// +// Author (DD-MMM-YYYY) +// +// Environment: +// +// WHERE CAN THIS PROGRAM/LIBRARY/CODE RUN? +// +// Revision History: +// +// Author DD-MMM-YYYY Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include + +BOOL WINAPI DllMain( + IN HMODULE DllHandle, + IN ULONG Reason, + IN PCONTEXT Context OPTIONAL) +{ + WCHAR KexDllFullPath[MAX_PATH]; + PPEB Peb; + HMODULE KexDll; + NTSTATUS (NTAPI *pKexPatchCpiwSubsystemVersionCheck)(VOID); + + if (KexIsDebugBuild) { + WCHAR ExplorerFullPath[MAX_PATH]; + WCHAR ExeFullPath[MAX_PATH]; + + // + // Check if we are loaded into Windows Explorer or KexCfg. + // + + GetModuleFileName(NULL, ExeFullPath, ARRAYSIZE(ExeFullPath)); + GetWindowsDirectory(ExplorerFullPath, ARRAYSIZE(ExplorerFullPath)); + PathCchAppend(ExplorerFullPath, ARRAYSIZE(ExplorerFullPath), L"explorer.exe"); + + if (!StringEqualI(ExeFullPath, ExplorerFullPath) && + !StringEqualI(PathFindFileName(ExeFullPath), L"KexCfg.exe")) { + + // Neither explorer nor kexcfg, this shouldn't happen. + ASSERT (FALSE); + } + } + + // + // Check if we have already patched CPIW subsystem check in this process. + // See comment further down. + // + + Peb = NtCurrentPeb(); + + if (Peb->SpareBits0 & 1) { + // Already patched. + return FALSE; + } + + // + // We will go ahead with the patching. First, load KexDll so we can use its + // routine to patch the required locations in kernel32. + // + + GetSystemDirectory(KexDllFullPath, ARRAYSIZE(KexDllFullPath)); + PathCchAppend(KexDllFullPath, ARRAYSIZE(KexDllFullPath), L"KexDll.dll"); + KexDll = LoadLibrary(KexDllFullPath); + + if (!KexDll) { + return FALSE; + } + + pKexPatchCpiwSubsystemVersionCheck = (NTSTATUS (NTAPI *) (VOID)) GetProcAddress( + KexDll, + "KexPatchCpiwSubsystemVersionCheck"); + + if (!pKexPatchCpiwSubsystemVersionCheck) { + return FALSE; + } + + pKexPatchCpiwSubsystemVersionCheck(); + + // + // Signal to potential future instances of this DLL that we've already patched + // the version check, and prevent us from trying to patch it again. + // + // I chose the spare bits in the PEB bitfield because it seemed like a good place + // to stash a boolean value. + // + + Peb->SpareBits0 |= 1; + + FreeLibrary(KexDll); + return FALSE; +} \ No newline at end of file diff --git a/KexCfg/KexCfg.ico b/KexCfg/KexCfg.ico new file mode 100644 index 0000000..177c57f Binary files /dev/null and b/KexCfg/KexCfg.ico differ diff --git a/KexCfg/KexCfg.rc b/KexCfg/KexCfg.rc new file mode 100644 index 0000000..60bce24 Binary files /dev/null and b/KexCfg/KexCfg.rc differ diff --git a/KexCfg/KexCfg.vcxproj b/KexCfg/KexCfg.vcxproj new file mode 100644 index 0000000..e113959 --- /dev/null +++ b/KexCfg/KexCfg.vcxproj @@ -0,0 +1,268 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {F6B2D0CE-1772-4A76-BB46-FEB7C179370A} + Win32Proj + KexCfg + + + + Application + true + Unicode + + + Application + true + Unicode + + + Application + false + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + + + + + + + false + true + + + false + true + + + false + true + + + false + true + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + false + false + Default + + + false + StdCall + CompileAsC + + + Windows + true + + + $(TargetDir);$(SolutionDir)\00-Import Libraries + EntryPoint + true + wtsapi32.dll;uxtheme.dll;user32.dll;shell32.dll;ole32.dll;oleaut32.dll;comctl32.dll;comdlg32.dll + + + $(SolutionDir)\00-Common Headers + + + + + true + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + false + false + Default + + + false + StdCall + CompileAsC + + + Windows + true + + + $(TargetDir);$(SolutionDir)\00-Import Libraries + EntryPoint + true + wtsapi32.dll;uxtheme.dll;user32.dll;shell32.dll;ole32.dll;oleaut32.dll;comctl32.dll;comdlg32.dll + + + $(SolutionDir)\00-Common Headers + + + + + true + + + + + Level3 + + + MinSpace + true + true + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + false + false + Default + + + false + StdCall + CompileAsC + OnlyExplicitInline + Size + true + + + Windows + true + true + true + + + $(TargetDir);$(SolutionDir)\00-Import Libraries + EntryPoint + true + wtsapi32.dll;uxtheme.dll;user32.dll;shell32.dll;ole32.dll;oleaut32.dll;comctl32.dll;comdlg32.dll + + + $(SolutionDir)\00-Common Headers + + + + + true + + + + + Level3 + + + MinSpace + true + true + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + false + false + Default + + + false + StdCall + CompileAsC + OnlyExplicitInline + Size + true + + + Windows + true + true + true + + + $(TargetDir);$(SolutionDir)\00-Import Libraries + EntryPoint + true + wtsapi32.dll;uxtheme.dll;user32.dll;shell32.dll;ole32.dll;oleaut32.dll;comctl32.dll;comdlg32.dll + + + $(SolutionDir)\00-Common Headers + + + + + true + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/KexCfg/KexCfg.vcxproj.filters b/KexCfg/KexCfg.vcxproj.filters new file mode 100644 index 0000000..9b10630 --- /dev/null +++ b/KexCfg/KexCfg.vcxproj.filters @@ -0,0 +1,47 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/KexCfg/buildcfg.h b/KexCfg/buildcfg.h new file mode 100644 index 0000000..c9ec80a --- /dev/null +++ b/KexCfg/buildcfg.h @@ -0,0 +1,13 @@ +#pragma once + +#pragma comment(lib, "wtsapi32.lib") +#pragma comment(lib, "uxtheme.lib") + +// The graphical asserts use task dialogs which we won't have access to +// when running as local SYSTEM. +#define KEX_DISABLE_GRAPHICAL_ASSERTS + +#define KEX_TARGET_TYPE_EXE +#define KEX_ENV_WIN32 +#define KEX_COMPONENT L"KexCfg" +#define FRIENDLYAPPNAME L"VxKex Configuration Tool" diff --git a/KexCfg/cmdline.c b/KexCfg/cmdline.c new file mode 100644 index 0000000..566c77d --- /dev/null +++ b/KexCfg/cmdline.c @@ -0,0 +1,377 @@ +#include "buildcfg.h" +#include "kexcfg.h" + +STATIC VOID DisplayHelpMessage( + VOID) +{ + KexCfgMessageBox( + NULL, + L"KexCfg takes the following command-line parameters:\r\n" + L"\r\n" + L"/HELP or /? - Display this help message\r\n" + L"/EXE:\"\" - Specifies the full path of the executable to configure\r\n" + L"/ENABLE: - Specifies whether VxKex will be enabled or disabled\r\n" + L"/DISABLEFORCHILD: - Configures whether VxKex will be enabled or disabled for child processes\r\n" + L"/DISABLEAPPSPECIFIC: - Configures whether app-specific hacks will be used\r\n" + L"/WINVERSPOOF: - Configures the spoofed Windows version\r\n" + L"/STRONGSPOOF: - Configures options for strong version spoofing\r\n" + L"\r\n" + L"The argument must be a full absolute path to a file with a .exe extension.\r\n" + L"Boolean parameters TRUE, YES, 1, FALSE, NO, or 0 are recognized.\r\n" + L"The /WINVERSPOOF parameter can be a member of the KEX_WIN_VER_SPOOF enumeration or one of the following " + L"string values: NONE, WIN7SP1, WIN8, WIN81, WIN10, or WIN11.\r\n" + L"The /STRONGSPOOF parameter takes one or more of the KEX_STRONGSPOOF_* bit flags, defined in KexDll.h.\r\n" + L"\r\n" + L"Any values which are not specified on the command line will use default values.", + FRIENDLYAPPNAME, + MB_OK); +} + +// +// Since we might be running with elevated privileges, we'll be extra +// careful in the command line parsing code. +// +VOID KexCfgHandleCommandLine( + IN PCWSTR CommandLine) +{ + BOOLEAN Success; + NTSTATUS Status; + PCWSTR Parameter; + WCHAR ExeFullPathTemp[MAX_PATH]; + WCHAR ExeFullPath[MAX_PATH]; + KXCFG_PROGRAM_CONFIGURATION Configuration; + HANDLE TransactionHandle; + + ExeFullPath[0] = '\0'; + + if (StringSearchI(CommandLine, L"/HELP") || StringSearchI(CommandLine, L"/?")) { + DisplayHelpMessage(); + ExitProcess(STATUS_SUCCESS); + } + + if (StringSearchI(CommandLine, L"/SCHTASK $(Arg0)")) { + KexCfgMessageBox( + NULL, + L"This scheduled task is not designed to be invoked by the user.", + FRIENDLYAPPNAME, + MB_ICONINFORMATION | MB_OK); + + ExitProcess(STATUS_NOT_SUPPORTED); + } + + // + // Handle the /EXE parameter. + // + + Parameter = StringFindI(CommandLine, L"/EXE:"); + if (Parameter) { + BOOLEAN HasQuotes; + + Parameter += StringLiteralLength(L"/EXE:"); + + if (Parameter[0] == '\0') { + KexCfgMessageBox( + NULL, + L"/EXE was specified without an executable name.", + FRIENDLYAPPNAME, + MB_ICONERROR | MB_OK); + + ExitProcess(STATUS_INVALID_PARAMETER); + } + + if (Parameter[0] == '"') { + HasQuotes = TRUE; + ++Parameter; + } + + StringCchCopy(ExeFullPathTemp, ARRAYSIZE(ExeFullPathTemp), Parameter); + + if (HasQuotes) { + PWCHAR EndQuote; + + // Find the matching quote and remove it. + EndQuote = (PWCHAR) StringFind(ExeFullPathTemp, L"\""); + + if (!EndQuote) { + KexCfgMessageBox( + NULL, + L"The argument to /EXE was too long or missing an end quote.", + FRIENDLYAPPNAME, + MB_ICONERROR | MB_OK); + + ExitProcess(STATUS_INVALID_PARAMETER); + } + + *EndQuote = '\0'; + } else { + PWCHAR EndSpace; + + // A space delimits the end of the argument. + EndSpace = (PWCHAR) StringFind(ExeFullPathTemp, L" "); + + if (EndSpace) { + *EndSpace = '\0'; + } + } + + // + // Canonicalize the path. + // + + if (FAILED(PathCchCanonicalize(ExeFullPath, ARRAYSIZE(ExeFullPath), ExeFullPathTemp))) { + KexCfgMessageBox( + NULL, + L"The argument to /EXE could not be canonicalized and is invalid.", + FRIENDLYAPPNAME, + MB_ICONERROR | MB_OK); + + ExitProcess(STATUS_INVALID_PARAMETER); + } + + // + // Validate the path. If it contains any forward slashes, it's invalid. + // And it has to have a .exe or .msi extension at the end. + // + + if (!isalpha(ExeFullPath[0]) || ExeFullPath[1] != ':' || ExeFullPath[2] != '\\') { + KexCfgMessageBox( + NULL, + L"The argument to /EXE must be an absolute path with a drive letter. " + L"If this program is on a network share, you must map the share as a " + L"network drive (right click -> Map network drive...).", + FRIENDLYAPPNAME, + MB_ICONERROR | MB_OK); + + ExitProcess(STATUS_INVALID_PARAMETER); + } + + { + WCHAR WinDir[MAX_PATH]; + WCHAR KexDir[MAX_PATH]; + + GetWindowsDirectory(WinDir, ARRAYSIZE(WinDir)); + KxCfgGetKexDir(KexDir, ARRAYSIZE(KexDir)); + + if (PathIsPrefix(WinDir, ExeFullPath) || PathIsPrefix(KexDir, ExeFullPath)) { + KexCfgMessageBox( + NULL, + L"The argument to /EXE cannot be in the Windows directory " + L"or the VxKex installation directory.", + FRIENDLYAPPNAME, + MB_ICONERROR | MB_OK); + + ExitProcess(STATUS_INVALID_PARAMETER); + } + } + + if (PathFindFileName(ExeFullPath) == PathFindExtension(ExeFullPath) || + PathFindFileName(ExeFullPath) == ExeFullPath) { + + KexCfgMessageBox( + NULL, + L"The argument to /EXE must have a file name, not just an extension.", + FRIENDLYAPPNAME, + MB_ICONERROR | MB_OK); + + ExitProcess(STATUS_INVALID_PARAMETER); + } + + if (!StringEqualI(PathFindExtension(ExeFullPath), L".exe") && + !StringEqualI(PathFindExtension(ExeFullPath), L".msi")) { + + KexCfgMessageBox( + NULL, + L"The argument to /EXE must have a .exe or .msi file extension.", + FRIENDLYAPPNAME, + MB_ICONERROR | MB_OK); + + ExitProcess(STATUS_INVALID_PARAMETER); + } + } else { + KexCfgMessageBox( + NULL, + L"/EXE must be specified.", + FRIENDLYAPPNAME, + MB_ICONERROR | MB_OK); + + ExitProcess(STATUS_INVALID_PARAMETER); + } + + // + // Now that we have an EXE name, we will fetch the existing configuration for + // this program (if it exists). + // + + Success = KxCfgGetConfiguration( + ExeFullPath, + &Configuration); + + if (!Success) { + ZeroMemory(&Configuration, sizeof(Configuration)); + } + + // + // Handle the /ENABLE, /DISABLEFORCHILD and /DISABLEAPPSPECIFIC + // boolean parameters. + // + + Parameter = StringFindI(CommandLine, L"/ENABLE:"); + if (Parameter) { + Parameter += StringLiteralLength(L"/ENABLE:"); + Configuration.Enabled = KexCfgParseBooleanParameter(Parameter); + } + + Parameter = StringFindI(CommandLine, L"/DISABLEFORCHILD:"); + if (Parameter) { + Parameter += StringLiteralLength(L"/DISABLEFORCHILD:"); + Configuration.DisableForChild = KexCfgParseBooleanParameter(Parameter); + } + + Parameter = StringFindI(CommandLine, L"/DISABLEAPPSPECIFIC:"); + if (Parameter) { + Parameter += StringLiteralLength(L"/DISABLEAPPSPECIFIC:"); + Configuration.DisableAppSpecificHacks = KexCfgParseBooleanParameter(Parameter); + } + + // + // Handle /WINVERSPOOF + // + + Parameter = StringFindI(CommandLine, L"/WINVERSPOOF:"); + if (Parameter) { + Parameter += StringLiteralLength(L"/WINVERSPOOF:"); + + if (StringBeginsWithI(Parameter, L"NONE")) { + Configuration.WinVerSpoof = WinVerSpoofNone; + } else if (StringBeginsWithI(Parameter, L"WIN7SP1")) { + Configuration.WinVerSpoof = WinVerSpoofWin7; + } else if (StringBeginsWithI(Parameter, L"WIN81")) { + Configuration.WinVerSpoof = WinVerSpoofWin8Point1; + } else if (StringBeginsWithI(Parameter, L"WIN8")) { + Configuration.WinVerSpoof = WinVerSpoofWin8; + } else if (StringBeginsWithI(Parameter, L"WIN10")) { + Configuration.WinVerSpoof = WinVerSpoofWin10; + } else if (StringBeginsWithI(Parameter, L"WIN11")) { + Configuration.WinVerSpoof = WinVerSpoofWin11; + } else { + ULONG Value; + + if (swscanf_s(Parameter, L"%lu", &Value) != 1) { + KexCfgMessageBox( + NULL, + L"The argument to /WINVERSPOOF could not be parsed.", + FRIENDLYAPPNAME, + MB_ICONERROR | MB_OK); + + ExitProcess(STATUS_INVALID_PARAMETER); + } + + if (Value >= WinVerSpoofMax) { + KexCfgMessageBox( + NULL, + L"The decimal argument to /WINVERSPOOF is out of range.", + FRIENDLYAPPNAME, + MB_ICONERROR | MB_OK); + + ExitProcess(STATUS_INVALID_PARAMETER); + } + + Configuration.WinVerSpoof = (KEX_WIN_VER_SPOOF) Value; + } + } + + // + // Handle /STRONGSPOOF + // + + Parameter = StringFindI(CommandLine, L"/STRONGSPOOF:"); + if (Parameter) { + ULONG Value; + + Parameter += StringLiteralLength(L"/STRONGSPOOF:"); + + if (StringBeginsWithI(Parameter, L"0x")) { + Parameter += ARRAYSIZE(L"0x"); + } + + if (swscanf_s(Parameter, L"%lx", &Value) != 1) { + KexCfgMessageBox( + NULL, + L"The argument to /STRONGSPOOF could not be parsed.", + FRIENDLYAPPNAME, + MB_ICONERROR | MB_OK); + + ExitProcess(STATUS_INVALID_PARAMETER); + } + + if (Value & (~KEX_STRONGSPOOF_VALID_MASK)) { + KexCfgMessageBox( + NULL, + L"The argument to /STRONGSPOOF contained invalid flags.", + FRIENDLYAPPNAME, + MB_ICONERROR | MB_OK); + + ExitProcess(STATUS_INVALID_PARAMETER); + } + + Configuration.StrongSpoofOptions = Value; + } + + // + // Apply the new configuration to the program. + // + + TransactionHandle = CreateSimpleTransaction(L"VxKex Configuration Tool Transaction"); + + Success = KxCfgSetConfiguration( + ExeFullPath, + &Configuration, + TransactionHandle); + + if (Success) { + Status = NtCommitTransaction(TransactionHandle, TRUE); + SafeClose(TransactionHandle); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + WCHAR ErrorMessage[256]; + + StringCchPrintf( + ErrorMessage, + ARRAYSIZE(ErrorMessage), + L"The transaction for this operation could not be committed. %s", + NtStatusAsString(Status)); + + KexCfgMessageBox( + NULL, + ErrorMessage, + FRIENDLYAPPNAME, + MB_ICONERROR | MB_OK); + + ExitProcess(Status); + } + } else { + WCHAR ErrorMessage[256]; + + Status = NtRollbackTransaction(TransactionHandle, TRUE); + SafeClose(TransactionHandle); + + ASSERT (NT_SUCCESS(Status)); + + StringCchPrintf( + ErrorMessage, + ARRAYSIZE(ErrorMessage), + L"The VxKex configuration for \"%s\" could not be applied due to the following error: %s", + ExeFullPath, + GetLastErrorAsString()); + + KexCfgMessageBox( + NULL, + ErrorMessage, + FRIENDLYAPPNAME, + MB_ICONERROR | MB_OK); + + ExitProcess(STATUS_UNSUCCESSFUL); + } +} \ No newline at end of file diff --git a/KexCfg/gui.c b/KexCfg/gui.c new file mode 100644 index 0000000..e1c33c0 --- /dev/null +++ b/KexCfg/gui.c @@ -0,0 +1,959 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// util.c +// +// Abstract: +// +// Implements the main GUI of KexCfg. +// +// Author: +// +// vxiiduu (09-Feb-2024) +// +// Environment: +// +// Win32 mode. This part of the program is not run as SYSTEM. +// +// Revision History: +// +// vxiiduu 09-Feb-2024 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kexcfg.h" +#include "resource.h" +#include +#include + +STATIC HWND MainWindow = NULL; +STATIC HWND ListViewWindow = NULL; +STATIC BOOLEAN UnsavedChanges; +STATIC BOOLEAN SortOrderIsDescendingForColumn[2] = {0}; + +STATIC VOID KexCfgGuiPopulateGlobalConfiguration( + VOID) +{ + BOOLEAN ExtendedContextMenu; + BOOLEAN LoggingEnabled; + WCHAR LogDir[MAX_PATH]; + + // + // Populate the Logging control group + // + + KxCfgQueryLoggingSettings(&LoggingEnabled, LogDir, ARRAYSIZE(LogDir)); + CheckDlgButton(MainWindow, IDC_ENABLELOGGING, LoggingEnabled); + SetDlgItemText(MainWindow, IDC_LOGDIR, LogDir); + + // + // Populate the System Integration control group + // + + CheckDlgButton(MainWindow, IDC_ENABLEFORMSI, KxCfgQueryVxKexEnabledForMsiexec()); + CheckDlgButton(MainWindow, IDC_CPIWBYPA, KxCfgQueryExplorerCpiwBypass()); + + if (KxCfgQueryShellContextMenuEntries(&ExtendedContextMenu)) { + CheckDlgButton(MainWindow, IDC_ADDTOMENU, TRUE); + ComboBox_SetCurSel(GetDlgItem(MainWindow, IDC_WHICHCONTEXTMENU), ExtendedContextMenu ? 0 : 1); + } else { + CheckDlgButton(MainWindow, IDC_ADDTOMENU, FALSE); + } +} + +STATIC VOID KexCfgGuiApplyGlobalConfiguration( + VOID) +{ + BOOLEAN Success; + HANDLE TransactionHandle; + BOOLEAN EnableLogging; + BOOLEAN EnableForMsiexec; + BOOLEAN EnableCpiwbypa; + BOOLEAN EnableContextMenu; + BOOLEAN ExtendedContextMenu; + WCHAR LogDir[MAX_PATH]; + + // + // Gather inputs + // + + EnableForMsiexec = IsDlgButtonChecked(MainWindow, IDC_ENABLEFORMSI); + EnableCpiwbypa = IsDlgButtonChecked(MainWindow, IDC_CPIWBYPA); + EnableContextMenu = IsDlgButtonChecked(MainWindow, IDC_ADDTOMENU); + ExtendedContextMenu = (ComboBox_GetCurSel(GetDlgItem(MainWindow, IDC_WHICHCONTEXTMENU)) == 0); + EnableLogging = IsDlgButtonChecked(MainWindow, IDC_ENABLELOGGING); + + GetDlgItemText(MainWindow, IDC_LOGDIR, LogDir, ARRAYSIZE(LogDir)); + + // + // Create transaction for the operation + // + + TransactionHandle = CreateSimpleTransaction(L"VxKex Configuration Tool (GUI) Transaction"); + + if (!TransactionHandle) { + ErrorBoxF( + L"A transaction for this operation could not be created. %s", + GetLastErrorAsString()); + + return; + } + + // + // Apply Logging settings + // + + Success = KxCfgConfigureLoggingSettings( + EnableLogging, + LogDir, + TransactionHandle); + + // + // Apply system integration settings + // + + Success = KxCfgEnableVxKexForMsiexec(EnableForMsiexec, TransactionHandle); + if (!Success) { + goto Fail; + } + + Success = KxCfgEnableExplorerCpiwBypass(EnableCpiwbypa, TransactionHandle); + if (!Success) { + goto Fail; + } + + Success = KxCfgConfigureShellContextMenuEntries(EnableContextMenu, ExtendedContextMenu, TransactionHandle); + if (!Success) { + goto Fail; + } + + NtCommitTransaction(TransactionHandle, TRUE); + SafeClose(TransactionHandle); + + UnsavedChanges = FALSE; + return; + +Fail: + NtRollbackTransaction(TransactionHandle, TRUE); + SafeClose(TransactionHandle); + + ErrorBoxF(L"The settings could not be applied. %s", GetLastErrorAsString()); +} + +BOOLEAN CALLBACK ConfigurationCallback( + IN PCWSTR ExeFullPathOrBaseName, + IN BOOLEAN IsLegacyConfiguration, + IN PVOID ExtraParameter) +{ + WCHAR ExeContainingFolder[MAX_PATH]; + PWSTR ExeBaseName; + LVITEM ListViewItem; + SHFILEINFO ShellFileInfo; + ULONG_PTR Success; + + if (IsLegacyConfiguration) { + // The installer should've removed all this crap + ASSERT (!IsLegacyConfiguration); + return TRUE; + } + + StringCchCopy( + ExeContainingFolder, + ARRAYSIZE(ExeContainingFolder), + ExeFullPathOrBaseName); + + PathCchRemoveFileSpec(ExeContainingFolder, ARRAYSIZE(ExeContainingFolder)); + ExeBaseName = PathFindFileName(ExeFullPathOrBaseName); + + if (StringEqualI(ExeBaseName, L"msiexec.exe")) { + // Special case. This is represented by a checkbox in the system integration + // group, so we don't show it here. + return TRUE; + } + + // + // Get icon of file. SHGetFileInfo works for all types of files including + // MSI files, and gives us the same icon that would be displayed in Windows + // Explorer. + // + + Success = SHGetFileInfo( + ExeFullPathOrBaseName, + 0, + &ShellFileInfo, + sizeof(ShellFileInfo), + SHGFI_ICON | SHGFI_SMALLICON | SHGFI_SYSICONINDEX); + + RtlZeroMemory(&ListViewItem, sizeof(ListViewItem)); + + if (Success) { + ListViewItem.mask |= LVIF_IMAGE; + ListViewItem.iImage = ShellFileInfo.iIcon; + DestroyIcon(ShellFileInfo.hIcon); + } + + ListViewItem.mask |= LVIF_TEXT; + ListViewItem.iItem = INT_MAX; + ListViewItem.pszText = ExeBaseName; + + // + // Insert the item and set text for all columns. + // + + ListViewItem.iItem = ListView_InsertItem(ListViewWindow, &ListViewItem); + ListView_SetItemText(ListViewWindow, ListViewItem.iItem, 1, ExeContainingFolder); + + return TRUE; +} + +STATIC VOID KexCfgGuiPopulateApplicationList( + VOID) +{ + SetWindowRedraw(ListViewWindow, FALSE); + + ListView_DeleteAllItems(ListViewWindow); + KxCfgEnumerateConfiguration(ConfigurationCallback, NULL); + + if (ListView_GetItemCount(ListViewWindow) != 0) { + // reflow column widths + ListView_SetColumnWidth(ListViewWindow, 0, LVSCW_AUTOSIZE); + ListView_SetColumnWidth(ListViewWindow, 1, LVSCW_AUTOSIZE_USEHEADER); + } + + SetWindowRedraw(ListViewWindow, TRUE); +} + +STATIC PCWSTR GetProgramFullPathFromListViewIndex( + IN ULONG ItemIndex) +{ + STATIC WCHAR FilePath[MAX_PATH]; + WCHAR FileName[MAX_PATH]; + + ListView_GetItemText(ListViewWindow, ItemIndex, 0, FileName, ARRAYSIZE(FileName)); + ListView_GetItemText(ListViewWindow, ItemIndex, 1, FilePath, ARRAYSIZE(FilePath)); + PathCchAppend(FilePath, ARRAYSIZE(FilePath), FileName); + + return FilePath; +} + +STATIC VOID RemoveSelectedPrograms( + VOID) +{ + ULONG ItemIndex; + HANDLE TransactionHandle; + + TransactionHandle = CreateSimpleTransaction(L"VxKex Configuration Tool (GUI) Transaction"); + + if (!TransactionHandle) { + ErrorBoxF( + L"A transaction for this operation could not be created. %s", + GetLastErrorAsString()); + + return; + } + + ItemIndex = ListView_GetNextItem(ListViewWindow, -1, LVNI_SELECTED); + + while (ItemIndex != -1) { + PCWSTR ExeFullPath; + BOOLEAN Success; + + ExeFullPath = GetProgramFullPathFromListViewIndex(ItemIndex); + + Success = KxCfgDeleteConfiguration(ExeFullPath, TransactionHandle); + if (!Success) { + ErrorBoxF( + L"There was an error applying settings for \"%s\". %s", + ExeFullPath, GetLastErrorAsString()); + + NtRollbackTransaction(TransactionHandle, TRUE); + SafeClose(TransactionHandle); + return; + } + + ItemIndex = ListView_GetNextItem(ListViewWindow, ItemIndex, LVNI_SELECTED); + } + + NtCommitTransaction(TransactionHandle, TRUE); + SafeClose(TransactionHandle); + + // refresh the list of enabled applications (since we removed some) + KexCfgGuiPopulateApplicationList(); +} + +STATIC VOID AddProgram( + VOID) +{ + WCHAR FileNames[1024]; + WCHAR FileFullPath[MAX_PATH]; + WCHAR KexDir[MAX_PATH]; + PCWSTR DirectoryName; + PCWSTR FileName; + ULONG DirectoryNameCch; + OPENFILENAME OpenFileInfo; + KXCFG_PROGRAM_CONFIGURATION Configuration; + HANDLE TransactionHandle; + + // + // Get a list of one or more programs from the user. + // + + FileNames[0] = '\0'; + + RtlZeroMemory(&OpenFileInfo, sizeof(OpenFileInfo)); + OpenFileInfo.lStructSize = sizeof(OpenFileInfo); + OpenFileInfo.hwndOwner = MainWindow; + OpenFileInfo.lpstrFilter = L"Programs (*.exe, *.msi)\0*.exe;*.msi\0"; + OpenFileInfo.lpstrFile = FileNames; + OpenFileInfo.nMaxFile = ARRAYSIZE(FileNames); + OpenFileInfo.lpstrTitle = L"Select Program(s)"; + OpenFileInfo.Flags = OFN_EXPLORER | OFN_ALLOWMULTISELECT | + OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; + OpenFileInfo.lpstrDefExt = L"exe"; + + if (GetOpenFileName(&OpenFileInfo) == FALSE) { + ASSERT (CommDlgExtendedError() == 0); + return; + } + + ASSERT (FileNames[0] != '\0'); + + DirectoryName = FileNames; + DirectoryNameCch = (ULONG) wcslen(DirectoryName); + ASSERT (DirectoryNameCch != 0); + ASSERT (DirectoryNameCch < MAX_PATH); + + if (StringBeginsWithI(DirectoryName, SharedUserData->NtSystemRoot)) { + // program(s) are in the Windows directory - do not allow + ErrorBoxF(L"You cannot enable VxKex for programs in the Windows directory."); + return; + } + + KxCfgGetKexDir(KexDir, ARRAYSIZE(KexDir)); + + if (StringBeginsWithI(DirectoryName, KexDir)) { + ErrorBoxF(L"You cannot enable VxKex for programs in the VxKex installation directory."); + return; + } + + if (OpenFileInfo.nFileOffset >= DirectoryNameCch) { + // User selected more than one file. + RtlCopyMemory(FileFullPath, DirectoryName, DirectoryNameCch * sizeof(WCHAR)); + FileFullPath[DirectoryNameCch] = '\\'; + FileFullPath[DirectoryNameCch + 1] = '\0'; + ++DirectoryNameCch; + + FileName = FileNames + DirectoryNameCch; + } else { + // User selected only one file. + FileName = FileNames; + FileNames[DirectoryNameCch + 1] = '\0'; + DirectoryNameCch = 0; + } + + ASSERT (FileName[0] != '\0'); + + RtlZeroMemory(&Configuration, sizeof(Configuration)); + Configuration.Enabled = 1; + + // + // Create transaction for the operation. + // + + TransactionHandle = CreateSimpleTransaction(L"VxKex Configuration Tool (GUI) Transaction"); + + if (!TransactionHandle) { + ErrorBoxF( + L"A transaction for this operation could not be created. %s", + GetLastErrorAsString()); + + return; + } + + // + // Enable VxKex for each of the selected programs. + // + + until (FileName[0] == '\0') { + BOOLEAN Success; + + StringCchCopy( + FileFullPath + DirectoryNameCch, + ARRAYSIZE(FileFullPath) - DirectoryNameCch, + FileName); + + Success = KxCfgSetConfiguration( + FileFullPath, + &Configuration, + TransactionHandle); + + if (!Success) { + ErrorBoxF( + L"There was an error applying settings for \"%s\". %s", + FileFullPath, GetLastErrorAsString()); + + NtRollbackTransaction(TransactionHandle, TRUE); + SafeClose(TransactionHandle); + return; + } + + FileName = FileName + wcslen(FileName) + 1; + } + + NtCommitTransaction(TransactionHandle, TRUE); + SafeClose(TransactionHandle); + + KexCfgGuiPopulateApplicationList(); +} + +STATIC VOID ProgramNotFoundUserPrompt( + IN PCWSTR ProgramFullPath) +{ + INT UserResponse; + + UserResponse = MessageBoxF( + TDCBF_YES_BUTTON | TDCBF_NO_BUTTON, + NULL, + FRIENDLYAPPNAME, + L"The selected program cannot be found", + L"The program \"%s\" was moved or deleted. " + L"Would you like to remove this entry from the list of VxKex-enabled applications?", + ProgramFullPath); + + if (UserResponse == IDYES) { + RemoveSelectedPrograms(); + } +} + +STATIC VOID OpenSelectedItemLocation( + VOID) +{ + HRESULT Result; + ULONG ItemIndex; + PCWSTR ProgramFullPath; + + ASSERT (IsWindow(ListViewWindow)); + ASSERT (ListView_GetSelectedCount(ListViewWindow) == 1); + + ItemIndex = ListView_GetNextItem(ListViewWindow, -1, LVIS_SELECTED); + ProgramFullPath = GetProgramFullPathFromListViewIndex(ItemIndex); + + Result = OpenFileLocation(ProgramFullPath, 0); + + if (FAILED(Result)) { + if (Result == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) { + // + // Special case for file not found. We will ask the user whether he wants + // to remove this entry since the EXE doesn't exist anymore. + // + + ProgramNotFoundUserPrompt(ProgramFullPath); + } else { + // display generic error box + ErrorBoxF(L"Couldn't open file location. %s", Win32ErrorAsString(Result)); + } + } +} + +STATIC VOID OpenSelectedItemProperties( + VOID) +{ + BOOLEAN Success; + PCWSTR ProgramFullPath; + ULONG ItemIndex; + + ASSERT (ListView_GetSelectedCount(ListViewWindow) == 1); + + ItemIndex = ListView_GetNextItem(ListViewWindow, -1, LVIS_SELECTED); + ProgramFullPath = GetProgramFullPathFromListViewIndex(ItemIndex); + + Success = ShowPropertiesDialog(ProgramFullPath, SW_SHOW); + if (!Success) { + ULONG ErrorCode; + + ErrorCode = GetLastError(); + + if (ErrorCode == ERROR_FILE_NOT_FOUND) { + ProgramNotFoundUserPrompt(ProgramFullPath); + } else { + ErrorBoxF(L"Couldn't open file properties. %s", Win32ErrorAsString(ErrorCode)); + } + } +} + +STATIC VOID RunSelectedProgram( + VOID) +{ + PCWSTR ProgramFullPath; + PCWSTR ErrorMessage; + ULONG_PTR ErrorCode; + ULONG ItemIndex; + + ItemIndex = ListView_GetNextItem(ListViewWindow, -1, LVIS_SELECTED); + ProgramFullPath = GetProgramFullPathFromListViewIndex(ItemIndex); + + // + // Check if CPIW bypass has been applied from a previous call to this function. + // If not, load cpiwbypa so that we have the ability to run programs with a + // subsystem version higher than 6.1. + // + + if (!(NtCurrentPeb()->SpareBits0 & 1)) { + LoadLibrary(L"cpiwbypa.dll"); + ASSERT (NtCurrentPeb()->SpareBits0 & 1); + } + + // why ShellExecute and not CreateProcess? because we can have .msi files too. + ErrorCode = (ULONG_PTR) ShellExecute( + MainWindow, + L"open", + ProgramFullPath, + NULL, + NULL, + SW_SHOWDEFAULT); + + ErrorMessage = NULL; + + if (ErrorCode <= 32) { + switch (ErrorCode) { + case SE_ERR_FNF: + case SE_ERR_PNF: + ProgramNotFoundUserPrompt(ProgramFullPath); + break; + case SE_ERR_ACCESSDENIED: + ErrorMessage = L"Access was denied or the executable file format is invalid."; + break; + case SE_ERR_OOM: + ErrorMessage = L"There was not enough memory to complete the operation."; + break; + case SE_ERR_SHARE: + ErrorMessage = L"A sharing violation occurred."; + break; + case SE_ERR_ASSOCINCOMPLETE: + ErrorMessage = L"SE_ERR_ASSOCINCOMPLETE"; + break; + case SE_ERR_DDETIMEOUT: + ErrorMessage = L"SE_ERR_DDETIMEOUT"; + break; + case SE_ERR_DDEFAIL: + ErrorMessage = L"SE_ERR_DDEFAIL"; + break; + case SE_ERR_DDEBUSY: + ErrorMessage = L"SE_ERR_DDEBUSY"; + break; + case SE_ERR_NOASSOC: + ErrorMessage = L"SE_ERR_NOASSOC"; + break; + case SE_ERR_DLLNOTFOUND: + ErrorMessage = L"The specified DLL was not found."; + break; + default: + ErrorMessage = L"An unknown error has occurred."; + break; + } + } + + if (ErrorMessage) { + ErrorBoxF(L"\"%s\": %s", ProgramFullPath, ErrorMessage); + } +} + +STATIC VOID HandleListViewContextMenu( + IN PPOINT ClickPoint) +{ + HWND HeaderWindow; + RECT HeaderWindowRect; + LVHITTESTINFO HitTestInfo; + ULONG ItemIndex; + USHORT MenuId; + INT DefaultMenuItem; + ULONG MenuSelection; + ULONG ListViewSelectedCount; + + HeaderWindow = ListView_GetHeader(ListViewWindow); + GetWindowRect(HeaderWindow, &HeaderWindowRect); + + if (PtInRect(&HeaderWindowRect, *ClickPoint)) { + // The user has right clicked on the list view header. + return; + } + + HitTestInfo.pt = *ClickPoint; + ScreenToClient(ListViewWindow, &HitTestInfo.pt); + ItemIndex = ListView_HitTest(ListViewWindow, &HitTestInfo); + ListViewSelectedCount = ListView_GetSelectedCount(ListViewWindow); + DefaultMenuItem = -1; + + if (ItemIndex == -1) { + // The user has right clicked on a blank space in the list view. + MenuId = IDM_LISTVIEWBLANKSPACEMENU; + } else { + // The user has right clicked on one or more items. + if (ListViewSelectedCount == 1) { + MenuId = IDM_LISTVIEWITEMMENU; + DefaultMenuItem = M_OPENFILELOCATION; + } else if (ListViewSelectedCount > 1) { + // more than 1 item + MenuId = IDM_LISTVIEWMULTIITEMMENU; + } else { + // can happen if Ctrl key is held down. + // in this situation, programs like Windows Explorer will display + // the same menu as for right clicking on blank space. + MenuId = IDM_LISTVIEWBLANKSPACEMENU; + } + } + + MenuSelection = ContextMenuEx(ListViewWindow, MenuId, ClickPoint, DefaultMenuItem); + if (!MenuSelection) { + return; + } + + if (MenuSelection == M_OPENFILELOCATION) { + ASSERT (ListViewSelectedCount == 1); + OpenSelectedItemLocation(); + } else if (MenuSelection == M_RUNPROGRAM) { + ASSERT (ListViewSelectedCount == 1); + RunSelectedProgram(); + } else if (MenuSelection == M_PROPERTIES) { + ASSERT (ListViewSelectedCount == 1); + OpenSelectedItemProperties(); + } else if (MenuSelection == M_REMOVE) { + RemoveSelectedPrograms(); + } else if (MenuSelection == M_ADDPROGRAM) { + AddProgram(); + } +} + +STATIC INT CALLBACK KexCfgGuiSortListViewItems( + IN LPARAM LParam1, + IN LPARAM LParam2, + IN LPARAM ColumnIndex) +{ + WCHAR Text1[MAX_PATH]; + WCHAR Text2[MAX_PATH]; + ULONG Length1; + ULONG Length2; + INT ComparisonResult; + + ListView_GetItemTextEx(ListViewWindow, LParam1, (INT) ColumnIndex, Text1, ARRAYSIZE(Text1), &Length1); + ListView_GetItemTextEx(ListViewWindow, LParam2, (INT) ColumnIndex, Text2, ARRAYSIZE(Text2), &Length2); + + ComparisonResult = CompareString( + LOCALE_USER_DEFAULT, + 0, + Text1, + Length1, + Text2, + Length2); + + ASSERT (ComparisonResult != 0); + ComparisonResult -= 2; + + ASSERT (ColumnIndex < ARRAYSIZE(SortOrderIsDescendingForColumn)); + + if (SortOrderIsDescendingForColumn[ColumnIndex]) { + ComparisonResult = -ComparisonResult; + } + + return ComparisonResult; +} + +STATIC INT_PTR CALLBACK DialogProc( + IN HWND Window, + IN UINT Message, + IN WPARAM WParam, + IN LPARAM LParam) +{ + if (Message == WM_INITDIALOG) { + BOOLEAN Success; + HWND ComboBoxWindow; + HWND LogDirWindow; + LVCOLUMN Column; + HIMAGELIST SystemSmallImageList = NULL; + HIMAGELIST SystemLargeImageList = NULL; + + MainWindow = Window; + KexgApplicationMainWindow = Window; + SetWindowIcon(Window, IDI_APPICON); + + // + // Limit the max length of the log directory path to 200 characters. + // Make the path edit box autocomplete paths. + // + + LogDirWindow = GetDlgItem(Window, IDC_LOGDIR); + Edit_LimitText(LogDirWindow, 200); + SHAutoComplete(LogDirWindow, SHACF_FILESYS_DIRS | SHACF_USETAB); + + // + // Initialize the context menu selection combo box. + // + + ComboBoxWindow = GetDlgItem(Window, IDC_WHICHCONTEXTMENU); + ComboBox_AddString(ComboBoxWindow, L"extended context menu"); + ComboBox_AddString(ComboBoxWindow, L"normal context menu"); + ComboBox_SetCurSel(ComboBoxWindow, 0); + + // + // Initialize the application list view. + // + + ListViewWindow = GetDlgItem(Window, IDC_LISTVIEW); + SetWindowTheme(ListViewWindow, L"Explorer", NULL); + + Success = Shell_GetImageLists(&SystemLargeImageList, &SystemSmallImageList); + ASSERT (Success); + + if (Success) { + ListView_SetImageList(ListViewWindow, SystemSmallImageList, LVSIL_SMALL); + ListView_SetImageList(ListViewWindow, SystemLargeImageList, LVSIL_NORMAL); + } + + ListView_SetExtendedListViewStyle( + ListViewWindow, + LVS_EX_FULLROWSELECT | + LVS_EX_LABELTIP | + LVS_EX_DOUBLEBUFFER); + + RtlZeroMemory(&Column, sizeof(Column)); + Column.mask = LVCF_TEXT | LVCF_WIDTH; + + Column.pszText = L"Application"; + Column.cx = DpiScaleX(100); + ListView_InsertColumn(ListViewWindow, 0, &Column); + + Column.pszText = L"Containing folder"; + ListView_InsertColumn(ListViewWindow, 1, &Column); + ListView_SetColumnWidth(ListViewWindow, 1, LVSCW_AUTOSIZE_USEHEADER); + + // + // Add tool tips. + // + + ToolTip(Window, IDC_ENABLELOGGING, + L"If you enable logging, VxKex will create log files in the specified " + L"folder every time you run an application which has VxKex enabled."); + ToolTip(Window, IDC_ENABLEFORMSI, + L"This option allows VxKex to work with MSI installers.\r\n" + L"If you encounter unexpected problems with MSI installers, try disabling this option."); + ToolTip(Window, IDC_CPIWBYPA, + L"This option causes a DLL to be loaded into Windows Explorer at startup in order " + L"to remove the version check for certain programs.\r\n" + L"If you encounter unexpected problems with Windows Explorer, try disabling this " + L"option."); + ToolTip(Window, IDC_ADDTOMENU, + L"Add \"Run with VxKex\" options to the context menu for .exe and .msi files."); + ToolTip(Window, IDC_WHICHCONTEXTMENU, + L"Shift+Right Click on a .exe or .msi file opens the extended context menu.\r\n" + L"Right clicking without holding the Shift key opens the normal context menu."); + + // + // Populate the top section (global configuration) and the apps list. + // + + KexCfgGuiPopulateGlobalConfiguration(); + KexCfgGuiPopulateApplicationList(); + + // + // Update the state of certain interdependent controls (i.e. controls + // that are supposed to be enabled/disabled based on the state of a + // checkbox) + // + + DialogProc(Window, WM_COMMAND, IDC_ENABLELOGGING, 0); + DialogProc(Window, WM_COMMAND, IDC_ADDTOMENU, 0); + + UnsavedChanges = FALSE; + EnableWindow(GetDlgItem(Window, IDC_APPLY), FALSE); + } else if (Message == WM_COMMAND) { + ULONG ControlId; + ULONG NotificationCode; + + ControlId = LOWORD(WParam); + NotificationCode = HIWORD(WParam); + + if (ControlId == IDC_ENABLELOGGING || + ControlId == IDC_ENABLEFORMSI || + ControlId == IDC_CPIWBYPA || + ControlId == IDC_ADDTOMENU || + (ControlId == IDC_WHICHCONTEXTMENU && NotificationCode == CBN_SELCHANGE) || + (ControlId == IDC_LOGDIR && NotificationCode == EN_CHANGE)) { + + if (UnsavedChanges == FALSE) { + UnsavedChanges = TRUE; + EnableWindow(GetDlgItem(Window, IDC_APPLY), TRUE); + } + } + + if (ControlId == IDC_CANCEL) { + if (UnsavedChanges) { + INT UserResponse; + + UserResponse = MessageBoxF( + TDCBF_YES_BUTTON | TDCBF_NO_BUTTON, + 0, + FRIENDLYAPPNAME, + L"Are you sure you want to exit?", + L"Changes that are not applied will be discarded."); + + if (UserResponse == IDYES) { + EndDialog(Window, 0); + } + } else { + EndDialog(Window, 0); + } + } else if (ControlId == IDC_OK) { + if (UnsavedChanges) { + KexCfgGuiApplyGlobalConfiguration(); + } + + unless (UnsavedChanges) { + EndDialog(Window, 0); + } + } else if (ControlId == IDC_APPLY) { + if (UnsavedChanges) { + KexCfgGuiApplyGlobalConfiguration(); + } + + unless (UnsavedChanges) { + EnableWindow(GetDlgItem(Window, ControlId), FALSE); + } + } else if (ControlId == IDC_BROWSELOGDIR) { + BOOLEAN Success; + WCHAR NewLogDir[MAX_PATH]; + + GetDlgItemText(Window, IDC_LOGDIR, NewLogDir, ARRAYSIZE(NewLogDir)); + Success = PickFolder(Window, NULL, 0, NewLogDir, ARRAYSIZE(NewLogDir)); + + if (Success) { + SetDlgItemText(Window, IDC_LOGDIR, NewLogDir); + } + } else if (ControlId == IDC_ENABLELOGGING) { + BOOLEAN LoggingEnabled; + + LoggingEnabled = IsDlgButtonChecked(Window, ControlId); + + EnableWindow(GetDlgItem(Window, IDC_LOGDIR), LoggingEnabled); + EnableWindow(GetDlgItem(Window, IDC_BROWSELOGDIR), LoggingEnabled); + } else if (ControlId == IDC_ADDTOMENU) { + EnableWindow( + GetDlgItem(Window, IDC_WHICHCONTEXTMENU), + IsDlgButtonChecked(Window, ControlId)); + } else if (ControlId == IDC_NEWAPP) { + AddProgram(); + } else if (ControlId == IDC_REMOVEAPPS) { + RemoveSelectedPrograms(); + } else if (ControlId == IDC_PROPERTIES) { + ULONG ItemIndex; + + ItemIndex = ListView_GetNextItem(ListViewWindow, -1, LVIS_SELECTED); + + ShowPropertiesDialog( + GetProgramFullPathFromListViewIndex(ItemIndex), + SW_SHOWDEFAULT); + } else { + return FALSE; + } + } else if (Message == WM_NOTIFY) { + LPNMHDR Notification; + + Notification = (LPNMHDR) LParam; + + if (Notification->idFrom == IDC_LISTVIEW) { + if (Notification->code == LVN_ITEMCHANGED) { + ULONG ListViewSelectedCount; + + ListViewSelectedCount = ListView_GetSelectedCount(ListViewWindow); + + if (ListViewSelectedCount == 0) { + // no items selected + EnableWindow(GetDlgItem(Window, IDC_REMOVEAPPS), FALSE); + EnableWindow(GetDlgItem(Window, IDC_PROPERTIES), FALSE); + } else { + // one or more items selected + EnableWindow(GetDlgItem(Window, IDC_REMOVEAPPS), TRUE); + + if (ListViewSelectedCount == 1) { + EnableWindow(GetDlgItem(Window, IDC_PROPERTIES), TRUE); + } else { + // no properties button for >1 item selected + EnableWindow(GetDlgItem(Window, IDC_PROPERTIES), FALSE); + } + } + } else if (Notification->code == LVN_DELETEITEM) { + // after items are deleted, no items will be selected anymore + EnableWindow(GetDlgItem(Window, IDC_REMOVEAPPS), FALSE); + EnableWindow(GetDlgItem(Window, IDC_PROPERTIES), FALSE); + } else if (Notification->code == NM_DBLCLK) { + // + // User double clicked on a list-view item. + // We will open the location of that file. + // + + OpenSelectedItemLocation(); + } else if (Notification->code == LVN_COLUMNCLICK) { + ULONG ColumnIndex; + + ColumnIndex = ((LPNMLISTVIEW) LParam)->iSubItem; + + // toggle sort order + ASSERT (ColumnIndex < ARRAYSIZE(SortOrderIsDescendingForColumn)); + SortOrderIsDescendingForColumn[ColumnIndex] ^= 1; + + // User has clicked on a column header. + // We are now going to sort that column. + ListView_SortItemsEx( + ListViewWindow, + KexCfgGuiSortListViewItems, + ColumnIndex); + } + } else { + return FALSE; + } + } else if (Message == WM_CONTEXTMENU) { + HWND ContextMenuWindow; + + ContextMenuWindow = (HWND) WParam; + + if (ContextMenuWindow == ListViewWindow) { + POINT ClickPoint; + ClickPoint.x = GET_X_LPARAM(LParam); + ClickPoint.y = GET_Y_LPARAM(LParam); + HandleListViewContextMenu(&ClickPoint); + } + } else if (Message == WM_CLOSE) { + DialogProc(Window, WM_COMMAND, IDC_CANCEL, 0); + } else { + return FALSE; + } + + return TRUE; +} + +VOID KexCfgOpenGUI( + VOID) +{ + if (!IsUserAnAdmin()) { + // + // Elevate the application. + // Many of the settings that can be changed here are located under the HKLM + // registry key so we'll require admin to run this program. + // + + ShellExecute( + NULL, + L"runas", + NtCurrentPeb()->ProcessParameters->ImagePathName.Buffer, + NULL, + NULL, + SW_SHOWDEFAULT); + + return; + } + + CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); + KexgApplicationFriendlyName = FRIENDLYAPPNAME; + DialogBox(NULL, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DialogProc); +} \ No newline at end of file diff --git a/KexCfg/kexcfg.h b/KexCfg/kexcfg.h new file mode 100644 index 0000000..4d7e98d --- /dev/null +++ b/KexCfg/kexcfg.h @@ -0,0 +1,45 @@ +#pragma once + +#include "buildcfg.h" +#include +#include + +// Use KexCfgMessageBox instead +#undef MessageBox + +// +// cmdline.c +// + +VOID KexCfgHandleCommandLine( + IN PCWSTR CommandLine); + +// +// gui.c +// + +VOID KexCfgOpenGUI( + VOID); + +// +// main.c +// + +EXTERN BOOLEAN Interactive; +EXTERN ULONG SessionId; + +// +// util.c +// + +BOOLEAN RunningInInteractiveWindowStation( + VOID); + +INT KexCfgMessageBox( + IN HWND ParentWindow OPTIONAL, + IN PWSTR Message, + IN PWSTR Title, + IN ULONG Flags); + +BOOLEAN KexCfgParseBooleanParameter( + IN PCWSTR Parameter); \ No newline at end of file diff --git a/KexCfg/main.c b/KexCfg/main.c new file mode 100644 index 0000000..385c5db --- /dev/null +++ b/KexCfg/main.c @@ -0,0 +1,91 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// main.c +// +// Abstract: +// +// Main file for KexCfg. +// +// Author: +// +// vxiiduu (09-Feb-2024) +// +// Environment: +// +// Win32 mode. Sometimes this program is run as Administrator, sometimes +// as a standard account, sometimes as the local SYSTEM account. +// +// Revision History: +// +// vxiiduu 09-Feb-2024 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "kexcfg.h" +#include + +BOOLEAN Interactive; +ULONG SessionId; + +VOID EntryPoint( + VOID) +{ + PCWSTR CommandLine; + + // + // When we are running as the local SYSTEM account, we cannot just call + // MessageBox to display information to the user, because processes running + // as the SYSTEM account run on a non-interactive session for security + // reasons (on Windows Vista and later). + // + // The WTSSendMessage function allows us to display a message box on the + // interactive desktop. But in order to do so, we need to have a session ID, + // which we can determine by enumerating all sessions and finding the first + // one which is "active" (i.e. logged in with a user). + // + + Interactive = RunningInInteractiveWindowStation(); + + if (Interactive) { + SessionId = WTS_CURRENT_SESSION; + } else { + BOOLEAN Success; + PWTS_SESSION_INFO SessionInfo; + ULONG NumberOfSessions; + + Success = WTSEnumerateSessions( + WTS_CURRENT_SERVER, + 0, 1, + &SessionInfo, + &NumberOfSessions); + + try { + ULONG Index; + + for (Index = 0; Index < NumberOfSessions; ++Index) { + if (SessionInfo[Index].State == WTSActive) { + SessionId = SessionInfo[Index].SessionId; + } + } + } finally { + WTSFreeMemory(SessionInfo); + } + } + + // + // If we have no command line options, then we will open the GUI. + // Otherwise we will process and act upon our command line arguments. + // + + CommandLine = GetCommandLineWithoutImageName();; + + if (CommandLine[0] == '\0') { + KexCfgOpenGUI(); + } else { + KexCfgHandleCommandLine(CommandLine); + } + + ExitProcess(STATUS_SUCCESS); +} \ No newline at end of file diff --git a/KexCfg/resource.h b/KexCfg/resource.h new file mode 100644 index 0000000..ca4e3ee --- /dev/null +++ b/KexCfg/resource.h @@ -0,0 +1,44 @@ +#pragma once + +#define IDSTATIC -1 + + +#define IDD_DIALOG1 100 + +#define IDC_ENABLELOGGING 101 +#define IDC_LOGDIR 102 +#define IDC_BROWSELOGDIR 103 + +#define IDC_ENABLEFORMSI 110 +#define IDC_CPIWBYPA 111 +#define IDC_ADDTOMENU 112 +#define IDC_WHICHCONTEXTMENU 113 + +#define IDC_LISTVIEW 120 +#define IDC_NEWAPP 121 +#define IDC_REMOVEAPPS 122 +#define IDC_PROPERTIES 123 + + +#define IDM_LISTVIEWITEMMENU 200 +#define M_OPENFILELOCATION 201 +#define M_RUNPROGRAM 202 +#define M_REMOVE 203 +#define M_PROPERTIES 204 + +#define IDM_LISTVIEWBLANKSPACEMENU 210 +#define M_ADDPROGRAM 211 + +#define IDM_LISTVIEWMULTIITEMMENU 220 + + +#define IDC_APPLY 190 +#define IDC_OK 191 +#define IDC_CANCEL 192 + + +#define IDI_APPICON 501 + + + + diff --git a/KexCfg/util.c b/KexCfg/util.c new file mode 100644 index 0000000..7b79493 --- /dev/null +++ b/KexCfg/util.c @@ -0,0 +1,140 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// util.c +// +// Abstract: +// +// Miscellaneous utility functions for KexCfg +// +// Author: +// +// vxiiduu (09-Feb-2024) +// +// Environment: +// +// Win32 mode. Sometimes this program is run as Administrator, sometimes +// as a standard account, sometimes as the local SYSTEM account. +// +// Revision History: +// +// vxiiduu 09-Feb-2024 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include +#include + +BOOLEAN Interactive; +ULONG SessionId; + +BOOLEAN RunningInInteractiveWindowStation( + VOID) +{ + BOOLEAN Success; + WCHAR WindowStationName[16]; + HWINSTA WindowStation; + + WindowStation = GetProcessWindowStation(); + if (WindowStation == NULL) { + return FALSE; + } + + Success = GetUserObjectInformation( + WindowStation, + UOI_NAME, + WindowStationName, + sizeof(WindowStationName), + NULL); + + if (!Success) { + return FALSE; + } + + return StringEqualI(WindowStationName, L"WinSta0"); +} + +INT KexCfgMessageBox( + IN HWND ParentWindow OPTIONAL, + IN PWSTR Message, + IN PWSTR Title, + IN ULONG Flags) +{ + BOOLEAN Success; + ULONG Response; + + if (Interactive) { + // + // Use the normal MessageBox function when running interactively. + // This allows the message box to have comctl v6 themes. + // + + return MessageBox( + ParentWindow, + Message, + Title, + Flags); + } else { + if (Title == NULL) { + // WTSSendMessage will error out upon receiving a NULL pointer + // for Title. + Title = L"Error"; + } + + Success = WTSSendMessage( + WTS_CURRENT_SERVER_HANDLE, + SessionId, + Title, + (ULONG) wcslen(Title) * sizeof(WCHAR), + Message, + (ULONG) wcslen(Message) * sizeof(WCHAR), + Flags, + 0, + &Response, + TRUE); + } + + if (!Success) { + return 0; + } + + return Response; +} + +BOOLEAN KexCfgParseBooleanParameter( + IN PCWSTR Parameter) +{ + WCHAR ParameterValue[32]; + ULONG Index; + + Index = 0; + + until (Parameter[Index] == ' ' || Parameter[Index] == '\0' || Index >= ARRAYSIZE(ParameterValue - 2)) { + ParameterValue[Index] = Parameter[Index]; + ++Index; + } + + ParameterValue[Index] = '\0'; + + if (StringEqualI(ParameterValue, L"TRUE") || + StringEqualI(ParameterValue, L"YES") || + StringEqualI(ParameterValue, L"1")) { + + return TRUE; + } else if (StringEqualI(ParameterValue, L"FALSE") || + StringEqualI(ParameterValue, L"NO") || + StringEqualI(ParameterValue, L"0")) { + + return FALSE; + } else { + KexCfgMessageBox( + NULL, + L"A boolean argument was invalid. Pass the /? argument for more information.", + FRIENDLYAPPNAME, + MB_ICONERROR | MB_OK); + + ExitProcess(STATUS_INVALID_PARAMETER); + } +} \ No newline at end of file diff --git a/KexDll/KexDll.def b/KexDll/KexDll.def new file mode 100644 index 0000000..93501c7 --- /dev/null +++ b/KexDll/KexDll.def @@ -0,0 +1,107 @@ +LIBRARY "KexDll.dll" +EXPORTS + KexDataInitialize + KexInitializePropagation + KexDllProtectedFunctionExceptionFilter + + KexRtlPathFindFileName + KexRtlPathRemoveExtension + KexRtlPathReplaceIllegalCharacters + KexRtlGetProcessImageBaseName + KexRtlQueryKeyValueData + KexRtlQueryKeyMultipleValueData + KexRtlUnicodeStringEndsWith + KexRtlFindUnicodeSubstring + KexRtlAdvanceUnicodeString + KexRtlRetreatUnicodeString + KexRtlShiftUnicodeString + KexRtlWriteProcessMemory + KexRtlCreateDirectoryRecursive + KexRtlNtStatusToString + KexRtlCreateStringMapper + KexRtlDeleteStringMapper + KexRtlInsertEntryStringMapper + KexRtlLookupEntryStringMapper + KexRtlRemoveEntryStringMapper + KexRtlApplyStringMapper + KexRtlInsertMultipleEntriesStringMapper + KexRtlLookupMultipleEntriesStringMapper + KexRtlBatchApplyStringMapper + KexRtlSectionTableFromRva + KexRtlNullTerminateUnicodeString + KexRtlCreateUntrustedDirectoryObject + + KexRtlWow64GetProcessMachines + KexRtlSetBit + KexRtlClearBit + KexRtlQueryPackageIdentity + KexRtlQueryPackageIdentityEx + KexRtlCheckPortableOperatingSystem + KexRtlUnsubscribeWnfStateChangeNotification + KexRtlQueryWnfStateData + KexRtlPublishWnfStateData + KexRtlSubscribeWnfStateChangeNotification + KexRtlAddGrowableFunctionTable + + KexRtlWaitOnAddress + KexRtlWakeAddressSingle + KexRtlWakeAddressAll + + KexEtwEventSetInformation + + KexLdrGetSystemDllBase + KexLdrGetRemoteSystemDllBase + KexLdrGetNativeSystemDllBase + KexLdrMiniGetProcedureAddress + KexLdrFindDllInitRoutine + KexLdrGetDllFullName + KexLdrGetDllFullNameFromAddress + KexLdrProtectImageImportSection + + KexLdrLoadDll + KexLdrGetDllHandle + KexLdrGetDllHandleEx + KexLdrGetProcedureAddress + KexLdrGetProcedureAddressEx + + KexLdrResolveDelayLoadedAPI + + ApiSetQueryApiSetPresence + + KexHkInstallBasicHook + KexHkRemoveBasicHook + + KexMessageBox + KexMessageBoxF + KexRewriteDllPath + KexPatchCpiwSubsystemVersionCheck + + AshExeBaseNameIs + AshModuleBaseNameIs + AshModuleIsWindowsModule + + VxlOpenLog + VxlCloseLog + VxlQueryInformationLog + VxlWriteLogEx + VxlReadLog + VxlReadMultipleEntriesLog + VxlSeverityToText + + KexNtQuerySystemTime + KexNtCreateUserProcess + KexNtProtectVirtualMemory + KexNtAllocateVirtualMemory + KexNtQueryVirtualMemory + KexNtFreeVirtualMemory + KexNtOpenKeyEx + KexNtQueryObject + KexNtOpenFile + KexNtWriteFile + KexNtRaiseHardError + KexNtQueryInformationThread + KexNtSetInformationThread + KexNtNotifyChangeKey + KexNtNotifyChangeMultipleKeys + KexNtCreateSection + KexNtAssignProcessToJobObject \ No newline at end of file diff --git a/KexDll/KexDll.rc b/KexDll/KexDll.rc new file mode 100644 index 0000000..e38f6f0 Binary files /dev/null and b/KexDll/KexDll.rc differ diff --git a/KexDll/KexDll.vcxproj b/KexDll/KexDll.vcxproj new file mode 100644 index 0000000..7f7e7de --- /dev/null +++ b/KexDll/KexDll.vcxproj @@ -0,0 +1,323 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {7656FF69-D1A3-4FA1-AB04-7C0089777CA7} + Win32Proj + KexDll + + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + + + + + + + + + + + + + + + + + + false + false + + + false + false + + + false + false + + + false + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;KEXDLL_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + true + false + StdCall + ProgramDatabase + true + true + false + false + Default + + + Native + true + $(SolutionDir)\00-Import Libraries;$(TargetDir) + + + KexDll.def + + + true + DllMain + true + false + delayimp.lib + + + $(SolutionDir)\00-Common Headers + + + + + 0 + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;KEXDLL_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + true + false + StdCall + ProgramDatabase + true + true + false + false + Default + + + Native + true + $(SolutionDir)\00-Import Libraries;$(TargetDir) + + + KexDll.def + + + true + DllMain + true + false + delayimp.lib + + + $(SolutionDir)\00-Common Headers + + + 0 + + + + + + + Level3 + + + MinSpace + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;KEXDLL_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + true + false + StdCall + ProgramDatabase + true + true + false + false + Default + AnySuitable + Size + true + + + Native + true + true + true + $(SolutionDir)\00-Import Libraries;$(TargetDir) + + + KexDll.def + + + true + DllMain + true + false + delayimp.lib + + + $(SolutionDir)\00-Common Headers + + + + + 0 + + + + + Level3 + + + MinSpace + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;KEXDLL_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + true + false + StdCall + ProgramDatabase + true + true + false + false + Default + AnySuitable + Size + true + + + Native + true + true + true + $(SolutionDir)\00-Import Libraries;$(TargetDir) + + + KexDll.def + + + true + DllMain + true + false + delayimp.lib + + + $(SolutionDir)\00-Common Headers + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/KexDll/KexDll.vcxproj.filters b/KexDll/KexDll.vcxproj.filters new file mode 100644 index 0000000..8eb64fd --- /dev/null +++ b/KexDll/KexDll.vcxproj.filters @@ -0,0 +1,162 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Source Files + + + + + Resource Files + + + + + Source Files + + + \ No newline at end of file diff --git a/KexDll/apiset.c b/KexDll/apiset.c new file mode 100644 index 0000000..707ba6b --- /dev/null +++ b/KexDll/apiset.c @@ -0,0 +1,11 @@ +#include "buildcfg.h" +#include "kexdllp.h" + +NTSTATUS NTAPI ApiSetQueryApiSetPresence( + IN PUNICODE_STRING Namespace, + OUT PBOOLEAN Present) +{ + KexLogDebugEvent(L"ApiSetQueryApiSetPresence called with \"%wZ\"", Namespace); + *Present = TRUE; + return STATUS_SUCCESS; +} \ No newline at end of file diff --git a/KexDll/ash.c b/KexDll/ash.c new file mode 100644 index 0000000..c3d0430 --- /dev/null +++ b/KexDll/ash.c @@ -0,0 +1,157 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// ash.c +// +// Abstract: +// +// This file contains helper routines for app-specific hacks. +// +// Author: +// +// vxiiduu (16-Feb-2024) +// +// Environment: +// +// Native mode +// +// Revision History: +// +// vxiiduu 16-Feb-2024 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kexdllp.h" + +// +// ExeName must include the .exe extension. +// +KEXAPI BOOLEAN NTAPI AshExeBaseNameIs( + IN PCWSTR ExeName) +{ + NTSTATUS Status; + UNICODE_STRING ExeNameUS; + + ASSERT (KexData != NULL); + + Status = RtlInitUnicodeStringEx(&ExeNameUS, ExeName); + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + return FALSE; + } + + return RtlEqualUnicodeString(&KexData->ImageBaseName, &ExeNameUS, TRUE); +} + +// +// This function is intended to be used like this: +// +// if (AshModuleBaseNameIs(ReturnAddress(), L"kernel32.dll")) +// +// File extension (.dll, .exe etc.) is required. +// +KEXAPI BOOLEAN NTAPI AshModuleBaseNameIs( + IN PVOID AddressInsideModule, + IN PCWSTR ModuleName) +{ + NTSTATUS Status; + UNICODE_STRING DllFullPath; + UNICODE_STRING DllBaseName; + UNICODE_STRING ComparisonBaseName; + + RtlInitEmptyUnicodeStringFromTeb(&DllFullPath); + + // + // Get the name of the DLL in which the specified address resides. + // + + Status = KexLdrGetDllFullNameFromAddress( + AddressInsideModule, + &DllFullPath); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + return FALSE; + } + + // + // Convert full path into base name. + // + + Status = KexRtlPathFindFileName(&DllFullPath, &DllBaseName); + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + return FALSE; + } + + Status = RtlInitUnicodeStringEx(&ComparisonBaseName, ModuleName); + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + return FALSE; + } + + return RtlEqualUnicodeString(&DllBaseName, &ComparisonBaseName, TRUE); +} + +// +// As with AshModuleBaseNameIs, this is designed to be used with the +// ReturnAddress() macro as the argument. +// +KEXAPI BOOLEAN NTAPI AshModuleIsWindowsModule( + IN PVOID AddressInsideModule) +{ + NTSTATUS Status; + UNICODE_STRING DllFullPath; + + RtlInitEmptyUnicodeStringFromTeb(&DllFullPath); + + // + // Get the name of the DLL in which the specified address resides. + // + + Status = KexLdrGetDllFullNameFromAddress( + AddressInsideModule, + &DllFullPath); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + return FALSE; + } + + // + // See if it starts with %SystemRoot%. + // + + if (RtlPrefixUnicodeString(&KexData->WinDir, &DllFullPath, TRUE)) { + return TRUE; + } else { + return FALSE; + } +} + +VOID AshApplyQBittorrentEnvironmentVariableHacks( + VOID) +{ + UNICODE_STRING VariableName; + UNICODE_STRING VariableValue; + + // + // APPSPECIFICHACK: Applying the environment variable below will eliminate + // the problem of bad kerning from qBittorrent. If more Qt apps are found + // which have bad kerning, this may help fix those too. + // + + if (AshExeBaseNameIs(L"qbittorrent.exe")) { + KexLogInformationEvent(L"App-Specific Hack applied for qBittorrent"); + RtlInitConstantUnicodeString(&VariableName, L"QT_SCALE_FACTOR"); + RtlInitConstantUnicodeString(&VariableValue, L"1.0000001"); + RtlSetEnvironmentVariable(NULL, &VariableName, &VariableValue); + } +} \ No newline at end of file diff --git a/KexDll/ashcrsup.c b/KexDll/ashcrsup.c new file mode 100644 index 0000000..adad4a7 --- /dev/null +++ b/KexDll/ashcrsup.c @@ -0,0 +1,157 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// ashcrsup.c +// +// Abstract: +// +// This file contains routines which detect Chromium-based browsers and +// frameworks. +// +// Author: +// +// vxiiduu (16-Mar-2024) +// +// Environment: +// +// Native mode +// +// Revision History: +// +// vxiiduu 16-Mar-2024 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kexdllp.h" + +// +// This function is called when we reach a conclusion that the current process +// either is Chromium/Electron, or has loaded a Chromium-based framework. +// +STATIC NTSTATUS AshpSetIsChromiumProcess( + VOID) +{ + NTSTATUS Status; + + ASSUME (!(KexData->Flags & KEXDATA_FLAG_CHROMIUM)); + + KexLogInformationEvent(L"Detected Chromium, applying compatibility fixes"); + + // + // Chromium uses dwrite factories introduced in win10. + // Will AV if we don't use the win10 dwrite. + // + + Status = AshSelectDWriteImplementation(DWriteWindows10Implementation); + ASSERT (NT_SUCCESS(Status)); + + KexData->Flags |= KEXDATA_FLAG_CHROMIUM; + + return Status; +} + +// +// This function is called from within the DLL notification routine (dllnotif.c) +// and we're supposed to infer from the loaded DLL whether it's some kind of +// Chromium DLL. +// +// Here, we detect CEF and qtwebengine because those are the main Chromium- +// based frameworks which get loaded in external DLLs. Electron can be detected +// through module exports of the main EXE, and actual Chrome/Opera/Firefox +// browsers can be detected through the same method. +// +// TODO: Get rid of this somehow. It's extra crap that gets called for every +// loaded DLL, although we have somewhat mitigated this penalty in the DLL +// notification function by only calling this function when a non-Windows DLL +// is loaded. +// +NTSTATUS AshPerformChromiumDetectionFromLoadedDll( + IN PCLDR_DLL_NOTIFICATION_DATA NotificationData) +{ + NTSTATUS Status; + UNICODE_STRING LibCef; + UNICODE_STRING Qt6WebEngineCore; + UNICODE_STRING BaseName; + + ASSUME (!(KexData->Flags & KEXDATA_FLAG_CHROMIUM)); + + Status = KexRtlPathFindFileName(NotificationData->FullDllName, &BaseName); + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + return Status; + } + + RtlInitConstantUnicodeString(&LibCef, L"libcef.dll"); + RtlInitConstantUnicodeString(&Qt6WebEngineCore, L"Qt6WebEngineCore.dll"); + + if (RtlEqualUnicodeString(&BaseName, &LibCef, TRUE) || + RtlEqualUnicodeString(&BaseName, &Qt6WebEngineCore, TRUE)) { + + Status = AshpSetIsChromiumProcess(); + ASSERT (NT_SUCCESS(Status)); + } + + return Status; +} + +NTSTATUS AshPerformChromiumDetectionFromModuleExports( + IN PVOID ModuleBase) +{ + NTSTATUS Status; + ANSI_STRING GetHandleVerifier; + ANSI_STRING IsSandboxedProcess; + PVOID ProcedureAddress; + + ASSUME (ModuleBase != NULL); + + RtlInitConstantAnsiString(&GetHandleVerifier, "GetHandleVerifier"); + RtlInitConstantAnsiString(&IsSandboxedProcess, "IsSandboxedProcess"); + + // + // These two function names are exported from Chrome and Electron + // EXEs. Also from firefox too because firefox uses the same sandbox + // as chrome. + // + + Status = LdrGetProcedureAddress( + ModuleBase, + &GetHandleVerifier, + 0, + &ProcedureAddress); + + ASSERT ( + NT_SUCCESS(Status) || + Status == STATUS_PROCEDURE_NOT_FOUND || + Status == STATUS_ENTRYPOINT_NOT_FOUND); + + if (!NT_SUCCESS(Status)) { + return Status; + } + + Status = LdrGetProcedureAddress( + ModuleBase, + &IsSandboxedProcess, + 0, + &ProcedureAddress); + + ASSERT ( + NT_SUCCESS(Status) || + Status == STATUS_PROCEDURE_NOT_FOUND || + Status == STATUS_ENTRYPOINT_NOT_FOUND); + + if (!NT_SUCCESS(Status)) { + return Status; + } + + // + // Both functions found. This is a chromium process. + // + + Status = AshpSetIsChromiumProcess(); + ASSERT (NT_SUCCESS(Status)); + + return Status; +} \ No newline at end of file diff --git a/KexDll/ashselec.c b/KexDll/ashselec.c new file mode 100644 index 0000000..97caf09 --- /dev/null +++ b/KexDll/ashselec.c @@ -0,0 +1,75 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// ashselec.c +// +// Abstract: +// +// This file contains routines which dynamically select between different +// implementations of DLLs by changing the DLL rewrite entries. +// +// Author: +// +// vxiiduu (16-Mar-2024) +// +// Environment: +// +// Native mode +// +// Revision History: +// +// vxiiduu 16-Mar-2024 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kexdllp.h" + +STATIC NTSTATUS AshpAddUpdateRemoveDllRewriteEntry( + IN PCUNICODE_STRING DllName, + IN PCUNICODE_STRING RewrittenDllName OPTIONAL) +{ + NTSTATUS Status; + + ASSUME (VALID_UNICODE_STRING(DllName)); + ASSUME (RewrittenDllName == NULL || WELL_FORMED_UNICODE_STRING(RewrittenDllName)); + + Status = KexRemoveDllRewriteEntry(DllName); + ASSERT (NT_SUCCESS(Status) || Status == STATUS_STRING_MAPPER_ENTRY_NOT_FOUND); + + if (!NT_SUCCESS(Status) && Status != STATUS_STRING_MAPPER_ENTRY_NOT_FOUND) { + return Status; + } + + if (RewrittenDllName && RewrittenDllName->Buffer != NULL) { + Status = KexAddDllRewriteEntry(DllName, RewrittenDllName); + } else { + Status = STATUS_SUCCESS; + } + + ASSERT (NT_SUCCESS(Status)); + return Status; +} + +NTSTATUS AshSelectDWriteImplementation( + IN KEX_DWRITE_IMPLEMENTATION Implementation) +{ + UNICODE_STRING DllName; + UNICODE_STRING RewrittenDllName; + + RtlInitConstantUnicodeString(&DllName, L"DWrite"); + + switch (Implementation) { + case DWriteNoImplementation: + RtlInitEmptyUnicodeString(&RewrittenDllName, NULL, 0); + break; + case DWriteWindows10Implementation: + RtlInitConstantUnicodeString(&RewrittenDllName, L"dwrw10"); + break; + default: + NOT_REACHED; + } + + return AshpAddUpdateRemoveDllRewriteEntry(&DllName, &RewrittenDllName); +} \ No newline at end of file diff --git a/KexDll/avrf.c b/KexDll/avrf.c new file mode 100644 index 0000000..3fb7b6c --- /dev/null +++ b/KexDll/avrf.c @@ -0,0 +1,82 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// avrf.c +// +// Abstract: +// +// Functions for dealing with Application Verifier. +// +// Author: +// +// vxiiduu (03-Nov-2022) +// +// Revision History: +// +// vxiiduu 03-Nov-2022 Initial creation. +// vxiiduu 05-Jan-2023 Convert to user friendly NTSTATUS. +// vxiiduu 16-Mar-2024 Add more assertions. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kexdllp.h" + +// +// Disable as many application verifier functionality as we can. +// This reduces the intrusiveness of VxKex, and also does stuff like stopping +// app verifier from intercepting some heap calls etc. +// Doesn't totally get rid of it though. We still can't totally unload verifier.dll +// without causing crashes. +// +NTSTATUS KexDisableAVrf( + VOID) +{ + NTSTATUS Status; + UNICODE_STRING VerifierDllName; + PVOID VerifierDllBase; + PDLL_INIT_ROUTINE VerifierDllMain; + + RtlInitConstantUnicodeString(&VerifierDllName, L"verifier.dll"); + + Status = LdrGetDllHandleByName(&VerifierDllName, NULL, &VerifierDllBase); + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + // This function was probably already called. + return STATUS_UNSUCCESSFUL; + } + + Status = KexLdrFindDllInitRoutine( + VerifierDllBase, + (PPVOID) &VerifierDllMain); + + ASSERT (NT_SUCCESS(Status)); + + if (NT_SUCCESS(Status) && VerifierDllMain != NULL) { + if (!VerifierDllMain(VerifierDllBase, DLL_PROCESS_DETACH, NULL)) { + KexLogWarningEvent(L"Verifier.dll failed to de-initialize."); + ASSERT (FALSE); + } + } + + NtCurrentPeb()->NtGlobalFlag &= ~(FLG_APPLICATION_VERIFIER | FLG_HEAP_PAGE_ALLOCS); + + Status = NtSetInformationProcess( + NtCurrentProcess(), + ProcessHandleTracing, + NULL, + 0); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + KexLogWarningEvent( + L"Failed to disable process handle tracing.\r\n\r\n" + L"NTSTATUS error code: %s", + KexRtlNtStatusToString(Status)); + } + + return STATUS_SUCCESS; +} \ No newline at end of file diff --git a/KexDll/buildcfg.h b/KexDll/buildcfg.h new file mode 100644 index 0000000..9b094e8 --- /dev/null +++ b/KexDll/buildcfg.h @@ -0,0 +1,13 @@ +#define KEXAPI + +// +// Set to TRUE to disable the PROTECTED_FUNCTION macro. +// Perhaps useful for debug builds, to catch exceptions under the +// debugger more quickly - however this will prevent exceptions from +// being logged through VXL. +// +#define DISABLE_PROTECTED_FUNCTION FALSE + +#define KEX_COMPONENT L"KexDll" +#define KEX_ENV_NATIVE +#define KEX_TARGET_TYPE_DLL diff --git a/KexDll/cpiwbypa.c b/KexDll/cpiwbypa.c new file mode 100644 index 0000000..abb45ee --- /dev/null +++ b/KexDll/cpiwbypa.c @@ -0,0 +1,278 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// cpiwbypa.c +// +// Abstract: +// +// This file contains functions which patch CreateProcessInternalW inside +// kernel32. +// +// CreateProcessInternalW is the function which causes the famous error +// message "This is not a valid Win32 application" when trying to launch +// executables which have a major/minor subsystem version which is too +// high. +// +// In order to launch these executables we need to patch the code inside +// CreateProcessInternalW which is responsible for checking the major and +// minor subsystem version of executables. +// +// TODO: Exploit the fact that kernel32 is always at the same base address +// within the same boot of the system. Perhaps cache the locations of the +// two patch addresses in an ephemeral registry key. This should be +// benchmarked as well to see if it's faster than simply scanning kernel32 +// every time. +// +// Author: +// +// vxiiduu (19-Feb-2024) +// +// Environment: +// +// Native mode. This routine should not be run while there are other threads +// in the process, but even if you do so, it should be fine. +// +// Revision History: +// +// vxiiduu 19-Feb-2024 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kexdllp.h" + +// +// The version check inside kernel32 is located inside the (exported!) function +// CreateProcessInternalW. The code checks the subsystem major and minor versions +// inside the EXE header and compares them with SharedUserData->NtMajorVersion +// and SharedUserData->NtMinorVersion. +// +// The function within the Windows source code that performs this check is called +// BasepCheckImageVersion. (Trivia: on Windows XP, this function used to be named +// BasepIsImageVersionOk). +// +// Regardless of 32-bit or 64-bit, this code accesses the exact same memory +// locations as a absolute addresses. These two addresses are: +// +// 0x7FFE026C SharedUserData->NtMajorVersion +// 0x7FFE0270 SharedUserData->NtMinorVersion +// +// Now, you might wonder, what is the relevance of this? Well, as a stroke of luck, +// in all builds of Windows 7 kernel32.dll that are known to me (including debug- +// checked versions, 32-bit versions, and WOW64 versions), simply searching for +// either of these addresses as a 32-bit integer yields only one result, and that +// is the one we must patch. +// +// Somewhat less fortunately is the fact that exactly where this value is inside +// kernel32 varies quite a lot over the various builds due to varying compiler +// optimizations. So what we will have to do is scan the entire .text section +// of the DLL for these two byte patterns and patch them. +// +// And what are we going to patch them to? Well, there is a value inside the +// SharedUserData that is guaranteed to be large enough that no version of Windows +// is ever going to have a large enough version number to fail the check. This +// value is SharedUserData->NumberOfPhysicalPages, which is set at boot time to +// the number of bytes of physical memory available divided by 4096 (the page size +// on x86 and x64). As long as we are booting with more than about 50kb of memory, +// this value is sure to be large enough ;) +// +// The address of SharedUserData->NumberOfPhysicalPages is 0x7FFE02E8. +// + +KEXAPI NTSTATUS NTAPI KexPatchCpiwSubsystemVersionCheck( + VOID) +{ + NTSTATUS Status; + UNICODE_STRING Kernel32Name; + ANSI_STRING CreateProcessInternalWName; + PVOID Kernel32; + PVOID CreateProcessInternalW; + PBYTE ExecutableSection; + PBYTE EndOfExecutableSection; + ULONG SizeOfExecutableSection; + PIMAGE_NT_HEADERS NtHeaders; + PIMAGE_SECTION_HEADER TextSectionHeader; + BOOLEAN FoundAddressOfNtMajorVersion; + BOOLEAN FoundAddressOfNtMinorVersion; + STATIC BOOLEAN AlreadyPatched = FALSE; + + if (AlreadyPatched) { + ASSERT (!AlreadyPatched); + return STATUS_ALREADY_INITIALIZED; + } + + // + // Get the address of kernel32.dll. + // + + RtlInitConstantUnicodeString(&Kernel32Name, L"kernel32.dll"); + + Status = LdrGetDllHandleByName( + &Kernel32Name, + NULL, + &Kernel32); + + ASSERT (NT_SUCCESS(Status)); + ASSERT (Kernel32 != NULL); + + if (!NT_SUCCESS(Status)) { + KexLogErrorEvent(L"Could not find the address of kernel32.dll."); + return Status; + } + + // + // Get the address of CreateProcessInternalW within kernel32.dll. + // + + RtlInitConstantAnsiString(&CreateProcessInternalWName, "CreateProcessInternalW"); + + Status = LdrGetProcedureAddress( + Kernel32, + &CreateProcessInternalWName, + 0, + &CreateProcessInternalW); + + ASSERT (NT_SUCCESS(Status)); + ASSERT (CreateProcessInternalW != NULL); + + if (!NT_SUCCESS(Status)) { + KexLogErrorEvent(L"Could not find the address of CreateProcessInternalW."); + return Status; + } + + // + // Find which section contains CreateProcessInternalW. We will assume that + // this section also contains the code which checks the subsystem version (which + // is a true assumption, considering there is only ever one executable section + // inside kernel32.dll). + // + + Status = RtlImageNtHeaderEx( + RTL_IMAGE_NT_HEADER_EX_FLAG_NO_RANGE_CHECK, + Kernel32, + 0, + &NtHeaders); + + ASSERT (NT_SUCCESS(Status)); + ASSERT (NtHeaders != NULL); + + if (!NT_SUCCESS(Status)) { + KexLogErrorEvent(L"Could not find the address of IMAGE_NT_HEADERS inside kernel32."); + return Status; + } + + TextSectionHeader = KexRtlSectionTableFromRva( + NtHeaders, + (ULONG) VA_TO_RVA(Kernel32, CreateProcessInternalW)); + + ASSERT (TextSectionHeader != NULL); + + if (TextSectionHeader == NULL) { + KexLogErrorEvent(L"Could not find the address of the executable section inside kernel32."); + return STATUS_IMAGE_SECTION_NOT_FOUND; + } + + // + // Find the real address and size of the executable section. + // + + ExecutableSection = (PBYTE) RVA_TO_VA(Kernel32, TextSectionHeader->VirtualAddress); + SizeOfExecutableSection = TextSectionHeader->SizeOfRawData; + EndOfExecutableSection = ExecutableSection + SizeOfExecutableSection - sizeof(ULONG); + + // + // Scan for the addresses of SharedUserData->NtMajorVersion and + // SharedUserData->NtMinorVersion. + // + + FoundAddressOfNtMajorVersion = FALSE; + FoundAddressOfNtMinorVersion = FALSE; + + do { + + if (*(PULONG) ExecutableSection == (ULONG) &SharedUserData->NtMajorVersion || + *(PULONG) ExecutableSection == (ULONG) &SharedUserData->NtMinorVersion) { + + PVOID BaseAddress; + SIZE_T RegionSize; + ULONG OldProtect; + + // + // We've found the address of either NtMajorVersion or NtMinorVersion. + // + + if (*(PULONG) ExecutableSection == (ULONG) &SharedUserData->NtMajorVersion) { + ASSERT (FoundAddressOfNtMajorVersion == FALSE); + FoundAddressOfNtMajorVersion = TRUE; + } else if (*(PULONG) ExecutableSection == (ULONG) &SharedUserData->NtMinorVersion) { + ASSERT (FoundAddressOfNtMinorVersion == FALSE); + FoundAddressOfNtMinorVersion = TRUE; + } else { + NOT_REACHED; + } + + BaseAddress = ExecutableSection; + RegionSize = sizeof(ULONG); + + Status = NtProtectVirtualMemory( + NtCurrentProcess(), + &BaseAddress, + &RegionSize, + PAGE_EXECUTE_READWRITE, + &OldProtect); + + ASSERT (NT_SUCCESS(Status)); + + if (NT_SUCCESS(Status)) { + // + // Overwrite the address to that of SharedUserData->NumberOfPhysicalPages. + // + + *(PULONG) ExecutableSection = (ULONG) &SharedUserData->NumberOfPhysicalPages; + + Status = NtProtectVirtualMemory( + NtCurrentProcess(), + &BaseAddress, + &RegionSize, + OldProtect, + &OldProtect); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + KexLogWarningEvent( + L"Failed to restore original page protections.\r\n\r\n" + L"Address: 0x%p\r\n" + L"Region size: %lu", + BaseAddress, + RegionSize); + } + } else { + KexLogErrorEvent( + L"Failed to apply PAGE_EXECUTE_READWRITE protection\r\n\r\n" + L"Address: 0x%p\r\n" + L"Region size: %lu", + BaseAddress, + RegionSize); + } + + if (FoundAddressOfNtMajorVersion && FoundAddressOfNtMinorVersion) { + break; + } + } + + ++ExecutableSection; + + } until (ExecutableSection >= EndOfExecutableSection); + + if (!FoundAddressOfNtMajorVersion || !FoundAddressOfNtMinorVersion) { + KexLogErrorEvent(L"Could not find the address of one of the patch locations."); + return STATUS_NOT_FOUND; + } + + AlreadyPatched = TRUE; + + KexLogInformationEvent(L"Successfully bypassed subsystem version check in CreateProcessInternalW."); + return STATUS_SUCCESS; +} \ No newline at end of file diff --git a/KexDll/dllmain.c b/KexDll/dllmain.c new file mode 100644 index 0000000..5c9a6eb --- /dev/null +++ b/KexDll/dllmain.c @@ -0,0 +1,254 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// dllmain.c +// +// Abstract: +// +// Main file for KexDll. +// +// KexDll is loaded at process initialization of every kex process and +// is what makes it a kex process (by rewriting dlls, etc.). +// +// Author: +// +// vxiiduu (17-Oct-2022) +// +// Environment: +// +// Native mode. +// This DLL is loaded before kernel32, and it can only import from NTDLL. +// +// Revision History: +// +// vxiiduu 17-Oct-2022 Initial creation. +// vxiiduu 05-Jan-2023 Convert to user friendly NTSTATUS. +// vxiiduu 23-Feb-2024 Remove support for advanced logging. +// vxiiduu 23-Feb-2024 Remove unneeded debug logging +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kexdllp.h" + +INT WINAPI MessageBoxAHookProc(HWND, PCSTR, PCSTR, UINT); + +STATIC RTL_VERIFIER_DLL_DESCRIPTOR AVrfDllDescriptor[] = { + {NULL, 0, NULL, NULL} +}; + +STATIC RTL_VERIFIER_PROVIDER_DESCRIPTOR AVrfProviderDescriptor = { + sizeof(RTL_VERIFIER_PROVIDER_DESCRIPTOR), // Length + AVrfDllDescriptor, // ProviderDlls + NULL, // ProviderDllLoadCallback + NULL, // ProviderDllUnloadCallback + + NULL, // VerifierImage + 0, // VerifierFlags + 0, // VerifierDebug + NULL, // RtlpGetStackTraceAddress + NULL, // RtlpDebugPageHeapCreate + NULL, // RtlpDebugPageHeapDestroy + + NULL // ProviderNtdllHeapFreeCallback +}; + +// +// DllMain is called 3 times during process initialization. +// +// 1. DLL_PROCESS_VERIFIER, with a valid pointer as the Descriptor parameter +// which we have to fill out +// +// 2. DLL_PROCESS_ATTACH, with a valid pointer as the Descriptor parameter +// (this time, the structure is filled out by the system) +// +// 3. DLL_PROCESS_ATTACH, with NULL as the Descriptor parameter. This is the +// "normal" DLL_PROCESS_ATTACH call, the previous call being made by the +// application verifier machinery inside NTDLL. +// +BOOL WINAPI DllMain( + IN PVOID DllBase, + IN ULONG Reason, + IN PRTL_VERIFIER_PROVIDER_DESCRIPTOR *Descriptor) +{ + NTSTATUS Status; + PVOID DllNotificationCookie; + + if (Reason == DLL_PROCESS_VERIFIER) { + // + // Register a useless descriptor with app verifier system. + // We don't make use of any app verifier apis or specific functionality + // at the moment, but if we don't do this the process will crash. + // + + *Descriptor = &AVrfProviderDescriptor; + } + + if (!KexData) { + // + // Initialize the KexData structure, since it contains some basic data + // which we will need for logging, etc. + // + + KexDataInitialize(&KexData); + KexData->KexDllBase = DllBase; + } + + if ((KexData->Flags & KEXDATA_FLAG_MSIEXEC) && + !(KexData->Flags & KEXDATA_FLAG_ENABLED_FOR_MSI) && + NtCurrentPeb()->SubSystemData == NULL) { + + // + // This is MSIEXEC, but the MSI it is processing does not have VxKex enabled, + // and we weren't simply propagated from another application. + // Do nothing. + // + + return TRUE; + } + + if (Reason == DLL_PROCESS_VERIFIER) { + PPEB Peb; + + ASSERT (KexData != NULL); + + Peb = NtCurrentPeb(); + + // + // Open log file. + // + + KexOpenVxlLogForCurrentApplication(&KexData->LogHandle); + + // + // Log some basic information such as command-line parameters to + // the log. + // + + KexLogInformationEvent( + L"Process created\r\n\r\n" + L"Full path to the EXE: %wZ\r\n" + L"Command line: %wZ\r\n", + &Peb->ProcessParameters->ImagePathName, + &Peb->ProcessParameters->CommandLine); + + // + // Try to get rid of as much Application verifier functionality as + // possible. + // + + KexDisableAVrf(); + + // + // Initialize Propagation subsystem. + // + + KexInitializePropagation(); + + // + // After the propagation system is initialized, the IfeoParameters are + // finalized, so print them out to the log. + // + + KexLogInformationEvent( + L"IfeoParameters values are finalized.\r\n\r\n" + L"DisableForChild: %d\r\n" + L"DisableAppSpecific: %d\r\n" + L"WinVerSpoof: %d\r\n" + L"StrongVersionSpoof: 0x%08lx", + KexData->IfeoParameters.DisableForChild, + KexData->IfeoParameters.DisableAppSpecific, + KexData->IfeoParameters.WinVerSpoof, + KexData->IfeoParameters.StrongVersionSpoof); + + // + // Hook any other NT system calls we are going to hook. + // + + KexHkInstallBasicHook(NtQueryInformationThread, Ext_NtQueryInformationThread, NULL); + KexHkInstallBasicHook(NtSetInformationThread, Ext_NtSetInformationThread, NULL); + KexHkInstallBasicHook(NtQueryInformationProcess, Ext_NtQueryInformationProcess, NULL); + KexHkInstallBasicHook(NtNotifyChangeKey, Ext_NtNotifyChangeKey, NULL); + KexHkInstallBasicHook(NtNotifyChangeMultipleKeys, Ext_NtNotifyChangeMultipleKeys, NULL); + KexHkInstallBasicHook(NtCreateSection, Ext_NtCreateSection, NULL); + KexHkInstallBasicHook(NtRaiseHardError, Ext_NtRaiseHardError, NULL); + KexHkInstallBasicHook(NtAssignProcessToJobObject, Ext_NtAssignProcessToJobObject, NULL); + + // + // Perform version spoofing, if required. + // + + KexApplyVersionSpoof(); + + // + // Initialize DLL rewrite subsystem. + // + + Status = KexInitializeDllRewrite(); + ASSERT (NT_SUCCESS(Status)); + + // + // Register our DLL load/unload callback. + // + + Status = LdrRegisterDllNotification( + 0, + KexDllNotificationCallback, + NULL, + &DllNotificationCookie); + + ASSERT (NT_SUCCESS(Status)); + + // + // Perform any app-specific hacks that need to be done before any further + // process initialization occurs. + // This must be done before rewriting the imports of the main EXE because + // we might change the DLL rewrite settings based on what we detect here. + // + + unless (KexData->IfeoParameters.DisableAppSpecific) { + // APPSPECIFICHACK: Environment variable hack for QBittorrent to fix + // bad kerning. + if (AshExeBaseNameIs(L"qbittorrent.exe")) { + AshApplyQBittorrentEnvironmentVariableHacks(); + } + + // APPSPECIFICHACK: Detect Chromium based on EXE exports. + AshPerformChromiumDetectionFromModuleExports(Peb->ImageBaseAddress); + } + + // + // Rewrite DLL Imports of our main application EXE. + // + + Status = KexRewriteImageImportDirectory( + NtCurrentPeb()->ImageBaseAddress, + &KexData->ImageBaseName, + &NtCurrentPeb()->ProcessParameters->ImagePathName); + + if (!NT_SUCCESS(Status) && Status != STATUS_IMAGE_NO_IMPORT_DIRECTORY) { + KexLogCriticalEvent( + L"Failed to rewrite DLL imports of the main process image.\r\n\r\n" + L"NTSTATUS error code: %s (0x%08lx)\r\n" + L"Image base address: 0x%p\r\n", + KexRtlNtStatusToString(Status), Status, + NtCurrentPeb()->ImageBaseAddress); + + KexHeErrorBox( + L"VxKex could not start because the DLL imports of the main " + L"process image could not be rewritten. If the problem persists, " + L"please disable VxKex for this program."); + + NOT_REACHED; + } + + } else if (Reason == DLL_PROCESS_ATTACH && Descriptor == NULL) { + Status = LdrDisableThreadCalloutsForDll(DllBase); + ASSERT (NT_SUCCESS(Status)); + } else if (Reason == DLL_PROCESS_DETACH) { + VxlCloseLog(&KexData->LogHandle); + } + + return TRUE; +} \ No newline at end of file diff --git a/KexDll/dllnotif.c b/KexDll/dllnotif.c new file mode 100644 index 0000000..f02cedf --- /dev/null +++ b/KexDll/dllnotif.c @@ -0,0 +1,91 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// dllnotif.c +// +// Abstract: +// +// Contains a routine which is called after a DLL is mapped into the +// process, but before its imports are resolved. This is the opportune +// moment to rewrite DLL imports. +// +// Author: +// +// vxiiduu (18-Oct-2022) +// +// Revision History: +// +// vxiiduu 18-Oct-2022 Initial creation. +// vxiiduu 23-Feb-2024 Change wording from "loaded" to "mapped" +// in order to better reflect reality. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kexdllp.h" + +// +// This function is called within a try/except block inside NTDLL. So if we +// fuck up here, nothing super bad is going to happen, although of course it +// should still be avoided. +// +// NotificationData->Flags contains values starting with LDR_DLL_LOADED_FLAG_ +// and it can (in Windows XP) only be 0 or 1. A value of 1 means that the DLL +// has been relocated. In Windows 7, NotificationData->Flags is always zero +// and there is no information that can be gathered through this flag. +// +// This function is not called to notify for DLL unloads if the process is +// exiting. This is because, as an optimization, the LdrUnloadDll (XP) or +// LdrpUnloadDll (Win7) routine does not actually unmap any DLLs when the +// process is exiting. +// +VOID NTAPI KexDllNotificationCallback( + IN LDR_DLL_NOTIFICATION_REASON Reason, + IN PCLDR_DLL_NOTIFICATION_DATA NotificationData, + IN PVOID Context OPTIONAL) +{ + NTSTATUS Status; + STATIC CONST PCWSTR ReasonToStringLookup[] = { + L"(unknown)", + L"mapped", + L"unmapped", + L"(unknown)" + }; + + KexLogDetailEvent( + L"The DLL %wZ was %s\r\n\r\n" + L"Full path to the DLL: \"%wZ\"\r\n" + L"Loaded at 0x%p (size: %I32u bytes)", + NotificationData->BaseDllName, + ARRAY_LOOKUP_BOUNDS_CHECKED(ReasonToStringLookup, Reason), + NotificationData->FullDllName, + NotificationData->DllBase, + NotificationData->SizeOfImage); + + if (Reason == LDR_DLL_NOTIFICATION_REASON_LOADED) { + BOOLEAN ShouldRewriteImports; + + ShouldRewriteImports = KexShouldRewriteImportsOfDll( + NotificationData->FullDllName); + + unless (KexData->IfeoParameters.DisableAppSpecific) { + if (ShouldRewriteImports) { + if (!(KexData->Flags & KEXDATA_FLAG_CHROMIUM)) { + // + // APPSPECIFICHACK: Perform heuristic-based Chromium detection if we don't + // already know that this is a Chromium process. + // + AshPerformChromiumDetectionFromLoadedDll(NotificationData); + } + } + } + + if (ShouldRewriteImports) { + Status = KexRewriteImageImportDirectory( + NotificationData->DllBase, + NotificationData->BaseDllName, + NotificationData->FullDllName); + } + } +} \ No newline at end of file diff --git a/KexDll/dllpath.c b/KexDll/dllpath.c new file mode 100644 index 0000000..14e4a63 --- /dev/null +++ b/KexDll/dllpath.c @@ -0,0 +1,312 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// dllpath.c +// +// Abstract: +// +// Contains routines for adding the Kex32/64 directory to the loader +// search path, so that the process can load our extended DLLs. The +// loader search path is a UNICODE_STRING structure, contained within +// Peb->ProcessParameters->DllPath. This string contains semicolon- +// separated Win32 paths, which is the same format as used in the %Path% +// environment variable. +// +// This is a relatively complex problem with a number of constraints. +// +// 1. We need to add KexDir\Kex32 or KexDir\Kex64 to the loader search +// path, based on whether this is a 32 bit or 64 bit process. +// +// 2. The old length of the search path must be maintained, as the loader +// caches the length value. Therefore, the search path cannot be +// extended or contracted. +// +// 3. We must not disturb the presence or the order of existing search +// path entries at all. +// +// Fortunately, a number of factors make this possible in most cases: +// +// 1. The loader does not cache the actual data inside DllPath.Buffer, +// so we can modify this buffer and influence the loader. +// +// 2 & 3. We can contract the length of the search path by removing +// duplicate path entries. For example, %WinDir%\system32, +// %WinDir%\system, and %WinDir% are all almost always duplicated +// (since the system places them at the beginning, and then pastes +// the %Path% environment variable after them, which contains +// identical entries). +// +// Sometimes, it is possible to collapse the length by removing +// duplicate semicolons; however, this is much less likely to produce +// a useful result and the current code implementation does not use +// this method. +// +// We can also pad the length of the search path out to the original +// length by simply filling unused space with semicolons. +// +// Keep in mind that the loader search path described above is only applicable +// to process initialization AND when LdrLoadDll is called with NULL as the +// first parameter (the DllPath parameter). +// +// When DLLs are loaded using Kernel32/KernelBase functions such as +// LoadLibrary, then the BASE dlls supply their own DllPath parameter to +// LdrLoadDll which is passed down throughout the entire DLL load sequence +// including the resolution of static imports. Therefore, the default loader +// DllPath which is accessible through the PEB is not applicable after the +// end of process initialization (except for the unlikely event of someone +// calling LdrLoadDll with NULL as the first parameter). +// +// In order to ensure that DLLs subsequently loaded have their static imports +// correctly written and resolved, we will also need to modify the %PATH% +// environment variable (which is relatively easy compared with modifying the +// default loader DllPath). +// +// Author: +// +// vxiiduu (30-Oct-2022) +// +// Revision History: +// +// vxiiduu 30-Oct-2022 Initial creation. +// vxiiduu 31-Oct-2022 Fix bugs and finalize implementation. +// vxiiduu 18-Mar-2024 Fix a bug where forward slashes in the +// DllPath could impede the ability of +// KexpShrinkDllPathLength to do its job. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kexdllp.h" + +STATIC INLINE NTSTATUS KexpShrinkDllPathLength( + IN PUNICODE_STRING DllPath, + IN USHORT TargetLength); + +STATIC INLINE NTSTATUS KexpPadDllPathToOriginalLength( + IN PUNICODE_STRING DllPath, + IN USHORT OriginalLength); + +STATIC INLINE VOID KexpNormalizeDllPathBackslashes( + IN OUT PUNICODE_STRING DllPath); + +NTSTATUS KexpAddKex3264ToDllPath( + VOID) +{ + NTSTATUS Status; + PUNICODE_STRING DllPath; + UNICODE_STRING NewDllPath; + USHORT DllPathOriginalLength; + + ASSERT (VALID_UNICODE_STRING(&KexData->Kex3264DirPath)); + ASSERT (KexData->Kex3264DirPath.Length != 0); + + DllPath = &NtCurrentPeb()->ProcessParameters->DllPath; + DllPathOriginalLength = DllPath->Length; + + KexLogInformationEvent( + L"Shrinking default loader DLL path\r\n\r\n" + L"The original DLL path is: \"%wZ\"", + DllPath); + + // + // Convert all forward slashes in the DllPath to backslashes. + // At least one real world case has been observed where a user's computer + // had the Path environment variable contain forward slashes instead of + // backslashes for some reason. + // + // Without normalizing the path separators, KexpShrinkDllPathLength would + // fail. This would cause VxKex to not work. + // + + KexpNormalizeDllPathBackslashes(DllPath); + + // + // Call a helper function to shrink DllPath by *at least* the length + // of our prepend string. + // + + Status = KexpShrinkDllPathLength(DllPath, DllPath->Length - KexData->Kex3264DirPath.Length); + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + return Status; + } + + // + // Create a temporary buffer to hold the new DllPath. + // + + NewDllPath.Length = 0; + NewDllPath.MaximumLength = DllPath->Length + KexData->Kex3264DirPath.Length; + NewDllPath.Buffer = StackAlloc(WCHAR, KexRtlUnicodeStringBufferCch(&NewDllPath)); + + // + // Build the new DllPath. + // + + Status = RtlAppendUnicodeStringToString(&NewDllPath, &KexData->Kex3264DirPath); + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + return Status; + } + + Status = RtlAppendUnicodeStringToString(&NewDllPath, DllPath); + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + return Status; + } + + // + // Copy new DllPath to old DllPath and finally pad to original length. + // + + RtlCopyUnicodeString(DllPath, &NewDllPath); + + Status = KexpPadDllPathToOriginalLength(DllPath, DllPathOriginalLength); + ASSERT (NT_SUCCESS(Status)); + + return Status; +} + +// +// Try to shrink the DllPath length to equal or less than "Length" by +// removing duplicate entries. +// +STATIC INLINE NTSTATUS KexpShrinkDllPathLength( + IN PUNICODE_STRING DllPath, + IN USHORT TargetLength) +{ + NTSTATUS Status; + UNICODE_STRING DllPathAfterCurrentEntry; + UNICODE_STRING CurrentPathEntry; + UNICODE_STRING DuplicatePathEntry; + UNICODE_STRING Semicolon; + + RtlInitConstantUnicodeString(&Semicolon, L";"); + DllPathAfterCurrentEntry = *DllPath; + + until (DllPath->Length <= TargetLength) { + + // + // Fetch a path entry + // + + Status = RtlFindCharInUnicodeString( + 0, + &DllPathAfterCurrentEntry, + &Semicolon, + &CurrentPathEntry.Length); + + if (!NT_SUCCESS(Status)) { + KexLogErrorEvent( + L"RtlFindCharInUnicodeString returned an error\r\n\r\n" + L"NTSTATUS error code: %s", + KexRtlNtStatusToString(Status)); + return Status; + } + + CurrentPathEntry.Length -= sizeof(WCHAR); // it includes the semicolon - get rid of it + CurrentPathEntry.Buffer = DllPathAfterCurrentEntry.Buffer; + CurrentPathEntry.MaximumLength = CurrentPathEntry.Length; + KexRtlAdvanceUnicodeString(&DllPathAfterCurrentEntry, CurrentPathEntry.Length + sizeof(WCHAR)); + + // + // Look for one or more duplicate entries later in the path. + // + + do { + DuplicatePathEntry.Buffer = KexRtlFindUnicodeSubstring( + &DllPathAfterCurrentEntry, + &CurrentPathEntry, + TRUE); + + if (DuplicatePathEntry.Buffer) { + UNICODE_STRING AfterDuplicate; + + DuplicatePathEntry.Length = CurrentPathEntry.Length; + DuplicatePathEntry.MaximumLength = (USHORT) + ((KexRtlEndOfUnicodeString(DllPath) - DuplicatePathEntry.Buffer) * sizeof(WCHAR)); + + // + // We want only full path entries, i.e. surrounded by semicolons, or at + // the end of the string. + // + + // the -1 is safe because we know DuplicatePathEntry is always ahead of DllPath + if (DuplicatePathEntry.Buffer[-1] != ';') { + break; + } + + if (KexRtlEndOfUnicodeString(&DuplicatePathEntry) != KexRtlEndOfUnicodeString(DllPath)) { + if (*(KexRtlEndOfUnicodeString(&DuplicatePathEntry)) != L';') { + break; + } + } + + // + // We need to cut this path entry out of the original DllPath and update the + // length field accordingly. To do this, we will copy all characters from + // the end of the duplicate path entry over top of the beginning of the + // duplicate entry. + // + + AfterDuplicate.Buffer = KexRtlEndOfUnicodeString(&DuplicatePathEntry); + AfterDuplicate.Length = (USHORT) ((KexRtlEndOfUnicodeString(DllPath) - AfterDuplicate.Buffer) * sizeof(WCHAR)); + AfterDuplicate.MaximumLength = AfterDuplicate.Length; + + DllPath->Length -= DuplicatePathEntry.Length; + RtlCopyUnicodeString(&DuplicatePathEntry, &AfterDuplicate); + } + } while (DuplicatePathEntry.Buffer); + } + + return STATUS_SUCCESS; +} + +STATIC INLINE NTSTATUS KexpPadDllPathToOriginalLength( + IN PUNICODE_STRING DllPath, + IN USHORT OriginalLength) +{ + PWCHAR Pointer; + + if (DllPath->Length > OriginalLength) { + return STATUS_INTERNAL_ERROR; + } + + // + // Add semicolons to the end until DllPath reaches the correct length. + // + + Pointer = KexRtlEndOfUnicodeString(DllPath); + DllPath->Length = OriginalLength; + + while (Pointer < KexRtlEndOfUnicodeString(DllPath)) { + *Pointer++ = L';'; + } + + return STATUS_SUCCESS; +} + +// +// Convert all slashes in the specified DllPath to backslashes. +// +STATIC INLINE VOID KexpNormalizeDllPathBackslashes( + IN OUT PUNICODE_STRING DllPath) +{ + ULONG Index; + ULONG DllPathCch; + + ASSUME (VALID_UNICODE_STRING(DllPath)); + + DllPathCch = KexRtlUnicodeStringCch(DllPath); + ASSUME (DllPathCch > 0); + + for (Index = 0; Index < DllPathCch; ++Index) { + if (DllPath->Buffer[Index] == '/') { + DllPath->Buffer[Index] = '\\'; + } + } +} \ No newline at end of file diff --git a/KexDll/dllrewrt.c b/KexDll/dllrewrt.c new file mode 100644 index 0000000..2f812ca --- /dev/null +++ b/KexDll/dllrewrt.c @@ -0,0 +1,700 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// dllrewrt.c +// +// Abstract: +// +// Contains routines related to DLL rewriting - more precisely, rewriting +// the names of DLLs imported from a PE image (which itself may be an EXE +// or a DLL). +// +// Author: +// +// vxiiduu (18-Oct-2022) +// +// Revision History: +// +// vxiiduu 18-Oct-2022 Initial creation. +// vxiiduu 22-Oct-2022 Bound imports are now erased +// vxiiduu 03-Nov-2022 Optimize KexRewriteImageImportDirectory +// vxiiduu 05-Jan-2023 Convert to user friendly NTSTATUS. +// vxiiduu 11-Feb-2024 Refactor DLL rewrite lookup code. +// vxiiduu 13-Mar-2024 Move DLL redirects into a static table +// instead of reading them from registry. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kexdllp.h" + +STATIC PKEX_RTL_STRING_MAPPER DllRewriteStringMapper = NULL; + +// This header file contains the definition of the DLL rewrite table. +#include "redirects.h" + +NTSTATUS KexAddDllRewriteEntry( + IN PCUNICODE_STRING DllName, + IN PCUNICODE_STRING RewrittenDllName) +{ + ASSUME (DllRewriteStringMapper != NULL); + ASSUME (VALID_UNICODE_STRING(DllName)); + ASSUME (VALID_UNICODE_STRING(RewrittenDllName)); + + return KexRtlInsertEntryStringMapper( + DllRewriteStringMapper, + DllName, + RewrittenDllName); +} + +NTSTATUS KexRemoveDllRewriteEntry( + IN PCUNICODE_STRING DllName) +{ + ASSUME (DllRewriteStringMapper != NULL); + ASSUME (VALID_UNICODE_STRING(DllName)); + + return KexRtlRemoveEntryStringMapper( + DllRewriteStringMapper, + DllName); +} + +// +// Initialize the DLL rewrite subsystem. +// + +NTSTATUS KexInitializeDllRewrite( + VOID) +{ + NTSTATUS Status; + ULONG Index; + + ASSERT (DllRewriteStringMapper == NULL); + + // + // Create the DLL rewrite string mapper. + // + + Status = KexRtlCreateStringMapper( + &DllRewriteStringMapper, + KEX_RTL_STRING_MAPPER_CASE_INSENSITIVE_KEYS); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + return Status; + } + + ASSERT (DllRewriteStringMapper != NULL); + + // + // Populate the DLL rewrite string mapper. + // + + ForEachArrayItem (DllRedirects, Index) { + ASSERT (VALID_UNICODE_STRING(&DllRedirects[Index][0])); + ASSERT (VALID_UNICODE_STRING(&DllRedirects[Index][1])); + + Status = KexAddDllRewriteEntry( + &DllRedirects[Index][0], + &DllRedirects[Index][1]); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + return Status; + } + } + + // + // Add the Kex32 or Kex64 directory to the default loader search path. + // + + Status = KexpAddKex3264ToDllPath(); + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + // + // This can happen if, for example, the user chooses to install VxKex into a + // directory with a long path name. + // + + KexLogErrorEvent( + L"Failed to append Kex32/64 to the DLL search path.\r\n\r\n" + L"NTSTATUS error code: %s", + KexRtlNtStatusToString(Status)); + } else { + KexLogInformationEvent( + L"Successfully initialized DLL rewrite subsystem.\r\n\r\n" + L"The new default DLL search path is:\r\n\r\n" + L"\"%wZ\"", + &NtCurrentPeb()->ProcessParameters->DllPath); + } + + return Status; +} + +// +// This function accepts DLL base names only. They may or may not have a .dll +// extension. +// +// Callers are forbidden from editing the contents of RewrittenDllName->Buffer. +// If you do that, then you will modify the entry inside the string mapper +// itself, and cause a lot of problems. +// +STATIC NTSTATUS KexpLookupDllRewriteEntry( + IN PCUNICODE_STRING DllName, + OUT PUNICODE_STRING RewrittenDllName) +{ + NTSTATUS Status; + UNICODE_STRING CleanDllName; + UNICODE_STRING DotDll; + UNICODE_STRING ApiPrefix; + UNICODE_STRING ExtPrefix; + USHORT MaximumRewrittenLength; + + ASSERT (DllRewriteStringMapper != NULL); + ASSERT (VALID_UNICODE_STRING(DllName)); + ASSERT (RewrittenDllName != NULL); + + CleanDllName = *DllName; + + RtlInitConstantUnicodeString(&DotDll, L".dll"); + RtlInitConstantUnicodeString(&ApiPrefix, L"api-"); + RtlInitConstantUnicodeString(&ExtPrefix, L"ext-"); + + // + // If the name of the DLL has a .dll extension, shorten the length of it + // so that it doesn't have a .dll extension anymore. + // This allows image files to import from DLLs with no extension without + // choking up the dll rewrite. + // + + MaximumRewrittenLength = CleanDllName.Length; + + if (KexRtlUnicodeStringEndsWith(&CleanDllName, &DotDll, TRUE)) { + CleanDllName.Length -= KexRtlUnicodeStringCch(&DotDll) * sizeof(WCHAR); + } + + // + // If the name of the DLL starts with "api-" or "ext-" (i.e. it's an API set DLL), + // then remove the -lX-Y-Z suffix as well. + // This code will have to be revised when API sets start appearing with + // individual X-Y-Z numbers greater than 9. + // + + if (RtlPrefixUnicodeString(&ApiPrefix, &CleanDllName, TRUE) || + RtlPrefixUnicodeString(&ExtPrefix, &CleanDllName, TRUE)) { + + CleanDllName.Length -= 7 * sizeof(WCHAR); + } + + // + // Now look up the DLL in the DLL rewrite string mapper to see whether we + // have a rewrite entry for it. + // + + Status = KexRtlLookupEntryStringMapper( + DllRewriteStringMapper, + &CleanDllName, + RewrittenDllName); + + ASSERT (NT_SUCCESS(Status) || Status == STATUS_STRING_MAPPER_ENTRY_NOT_FOUND); + + if (!NT_SUCCESS(Status)) { + return Status; + } + + // + // Check to see that the cch of the rewritten DLL is not greater than the + // cch of the original DLL. This shouldn't happen unless someone has made + // a mistake with the DLL rewrite table. + // + + ASSERT (RewrittenDllName->Length <= MaximumRewrittenLength); + ASSERT (VALID_UNICODE_STRING(RewrittenDllName)); + + return STATUS_SUCCESS; +} + +// +// Rewrite a DLL name based on the string mapper entries. +// This function is meant to operate directly on the import directories of +// loaded images, not for general use. +// +STATIC NTSTATUS KexpRewriteImportTableDllNameInPlace( + IN OUT PANSI_STRING AnsiDllName) +{ + NTSTATUS Status; + UNICODE_STRING DllName; + UNICODE_STRING RewrittenDllName; + + ASSERT (AnsiDllName != NULL); + ASSERT (AnsiDllName->Length != 0); + ASSERT (AnsiDllName->MaximumLength >= AnsiDllName->Length); + ASSERT (AnsiDllName->Buffer != NULL); + + // + // This Unicode DLL name gets allocated from the heap. + // We have to remember to free it. + // + + Status = RtlAnsiStringToUnicodeString(&DllName, AnsiDllName, TRUE); + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + return Status; + } + + // + // Lookup the name of the DLL to see whether we should rewrite it. + // If no entry was found in the string mapper, or another error occurred, + // just return and leave the original DLL name un-modified. + // + + Status = KexpLookupDllRewriteEntry( + &DllName, + &RewrittenDllName); + + ASSERT (NT_SUCCESS(Status) || Status == STATUS_STRING_MAPPER_ENTRY_NOT_FOUND); + + if (!NT_SUCCESS(Status)) { + goto Exit; + } + + try { + // + // Convert to ANSI. This will result in RtlUnicodeStringToAnsiString writing + // directly into the import table of an image file, so that's why we put + // this code in a try-except block (in case we screwed up with memory access + // flags earlier, or some weirdly formatted DLL file lays things out in an + // unexpected way). + // + + Status = RtlUnicodeStringToAnsiString( + AnsiDllName, + &RewrittenDllName, + FALSE); + + ASSERT (NT_SUCCESS(Status)); + + } except (GetExceptionCode() == STATUS_ACCESS_VIOLATION) { + Status = GetExceptionCode(); + + KexLogErrorEvent( + L"Failed to rewrite DLL import (%wZ -> %wZ): STATUS_ACCESS_VIOLATION", + &DllName, + &RewrittenDllName); + + ASSERT (FALSE); + } + +Exit: + if (NT_SUCCESS(Status)) { + KexLogDetailEvent(L"Rewrote DLL import: %wZ -> %wZ", &DllName, &RewrittenDllName); + } + + RtlFreeUnicodeString(&DllName); + return Status; +} + +// +// Determine whether the imports of a particular DLL (identified by name and +// path) should be rewritten. +// +// Returns a pointer to the string mapper object which is to be used for +// rewriting the imports of the specified DLL. If this function returns NULL, +// it means the imports of the specified DLL must not be rewritten. +// +BOOLEAN KexShouldRewriteImportsOfDll( + IN PCUNICODE_STRING FullDllName) +{ + NTSTATUS Status; + UNICODE_STRING BaseDllName; + + // + // Find the file name of the DLL. + // + + Status = KexRtlPathFindFileName(FullDllName, &BaseDllName); + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + return FALSE; + } + + if (RtlPrefixUnicodeString(&KexData->WinDir, FullDllName, TRUE)) { + UNICODE_STRING Kernel; + + // + // The DLL is in the Windows directory. + // + + if (KexData->IfeoParameters.WinVerSpoof > WinVerSpoofWin7) { + UNICODE_STRING Iertutil; + + RtlInitConstantUnicodeString(&Iertutil, L"iertutil.dll"); + + if (RtlEqualUnicodeString(&BaseDllName, &Iertutil, TRUE)) { + // + // iertutil.dll checks versions and can shit itself if the + // version number is too high. So we need to rewrite its + // imports so our KXBASE version functions get applied. + // + + return TRUE; + } + } + + RtlInitConstantUnicodeString(&Kernel, L"kernel"); + + if (RtlPrefixUnicodeString(&Kernel, &BaseDllName, TRUE)) { + // + // Rewrite the imports of kernelbase and kernel32. We want to do this + // so that certain functions such as LoadLibrary and CreateFileMapping + // end up going through KxNt (LdrLoadDll/NtCreateSection). + // + + return TRUE; + } + + // + // Otherwise, do not rewrite imports of Windows DLLs. + // + + return FALSE; + } + + // + // If this DLL is a part of VxKex, do not rewrite its imports. + // + + if (RtlPrefixUnicodeString(&KexData->KexDir, FullDllName, TRUE)) { + return FALSE; + } + + unless (KexData->IfeoParameters.DisableAppSpecific) { + UNICODE_STRING TargetDllName; + + // + // APPSPECIFICHACK: This is some sort of .NET DLL that will screw up if we + // rewrite its imports. No idea why. What typically happens if you allow its + // imports to be rewritten is you get a blank window that can be interacted + // with (i.e. all the buttons and things are "working") but you just can't + // see anything the app is drawing. + // + + RtlInitConstantUnicodeString(&TargetDllName, L"wpfgfx_cor3.dll"); + + if (KexRtlUnicodeStringEndsWith(FullDllName, &TargetDllName, TRUE)) { + return FALSE; + } + + // + // APPSPECIFICHACK: Although Mirillis Action supports Windows 7, it installs + // global hooks which cause crashes when dxgi is rewritten to kxdx. + // + + if (KexRtlCurrentProcessBitness() == 64) { + RtlInitConstantUnicodeString(&TargetDllName, L"action_x64.dll"); + } else { + RtlInitConstantUnicodeString(&TargetDllName, L"action_x86.dll"); + } + + if (KexRtlUnicodeStringEndsWith(FullDllName, &TargetDllName, TRUE)) { + return FALSE; + } + } + + // + // If there's no other rules that apply to this DLL, then we will rewrite + // its imports. + // + + return TRUE; +} + +NTSTATUS KexRewriteImageImportDirectory( + IN PVOID ImageBase, + IN PCUNICODE_STRING BaseImageName, + IN PCUNICODE_STRING FullImageName) +{ + NTSTATUS Status; + PIMAGE_NT_HEADERS NtHeaders; + PIMAGE_FILE_HEADER CoffHeader; + PIMAGE_OPTIONAL_HEADER OptionalHeader; + PIMAGE_DATA_DIRECTORY ImportDirectory; + PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor; + UNICODE_STRING Kernel32; + BOOLEAN AtLeastOneImportWasRewritten; + ULONG OldProtect; + + AtLeastOneImportWasRewritten = FALSE; + + ASSERT (DllRewriteStringMapper != NULL); + ASSERT (ImageBase != NULL); + ASSERT (VALID_UNICODE_STRING(BaseImageName)); + ASSERT (VALID_UNICODE_STRING(FullImageName)); + + Status = RtlImageNtHeaderEx( + RTL_IMAGE_NT_HEADER_EX_FLAG_NO_RANGE_CHECK, + ImageBase, + 0, + &NtHeaders); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + return Status; + } + + CoffHeader = &NtHeaders->FileHeader; + OptionalHeader = &NtHeaders->OptionalHeader; + ImportDirectory = &OptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; + + if ((KexRtlCurrentProcessBitness() == 64) != (CoffHeader->Machine == 0x8664)) { + // + // 32-bit dll loaded in 64-bit process or vice versa + // This can happen with resource-only DLLs, in which case there are no + // imports to rewrite anyway. Many .NET dlls have this characteristic. + // + + return STATUS_IMAGE_MACHINE_TYPE_MISMATCH; + } + + if (OptionalHeader->NumberOfRvaAndSizes < (IMAGE_DIRECTORY_ENTRY_IMPORT + 1) || + ImportDirectory->VirtualAddress == 0) { + // + // There is no import directory in the image (e.g. resource-only DLL). + // + + return STATUS_IMAGE_NO_IMPORT_DIRECTORY; + } + + ImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR) RVA_TO_VA(ImageBase, ImportDirectory->VirtualAddress); + + if (ImportDescriptor->Name == 0) { + // + // There shouldn't be an import directory if it has no entries. + // + + return STATUS_INVALID_IMAGE_FORMAT; + } + + // + // Set the entire section that contains the image import directory to read-write. + // + + Status = KexLdrProtectImageImportSection( + ImageBase, + PAGE_READWRITE, + &OldProtect); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + return Status; + } + + // + // Check if this is kernel32. + // + + RtlInitConstantUnicodeString(&Kernel32, L"kernel32.dll"); + + if (RtlEqualUnicodeString(BaseImageName, &Kernel32, TRUE)) { + PSTR NtdllImport; + + // On Windows 7, NTDLL is always the 2nd import of kernel32. + NtdllImport = (PSTR) RVA_TO_VA(ImageBase, ImportDescriptor[1].Name); + ASSERT (StringEqualA(NtdllImport, "ntdll.dll")); + + RtlCopyMemory(NtdllImport, "kxnt.dll", sizeof("kxnt.dll")); + AtLeastOneImportWasRewritten = TRUE; + goto SkipNormalImportRewrite; + } + + // + // Walk through imports and rewrite each one if necessary. + // + + do { + PSTR DllNameBuffer; + ANSI_STRING ImportedDllNameAnsi; + + DllNameBuffer = (PSTR) RVA_TO_VA(ImageBase, ImportDescriptor->Name); + RtlInitAnsiString(&ImportedDllNameAnsi, DllNameBuffer); + + Status = KexpRewriteImportTableDllNameInPlace( + &ImportedDllNameAnsi); + + ASSERT (NT_SUCCESS(Status) || Status == STATUS_STRING_MAPPER_ENTRY_NOT_FOUND); + + if (NT_SUCCESS(Status)) { + AtLeastOneImportWasRewritten = TRUE; + } + } while ((++ImportDescriptor)->Name != 0); + +SkipNormalImportRewrite: + + // restore old permissions + Status = KexLdrProtectImageImportSection( + ImageBase, + OldProtect, + &OldProtect); + + ASSERT (NT_SUCCESS(Status)); + + if (AtLeastOneImportWasRewritten) { + PIMAGE_DATA_DIRECTORY BoundImportDirectory; + PVOID DataDirectoryPtr; + SIZE_T DataDirectorySize; + + // + // A Bound Import Directory will cause process initialization to fail if we have rewritten + // anything. So we simply zero it out. + // Bound imports are a performance optimization, but basically we can't use it because + // the bound import addresses are dependent on the "real" function addresses within the + // imported DLL - and since we have replaced one or more imported DLLs, these pre-calculated + // function addresses are no longer valid, so we just have to delete it. + // + + BoundImportDirectory = &OptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT]; + + DataDirectoryPtr = BoundImportDirectory; + DataDirectorySize = sizeof(IMAGE_DATA_DIRECTORY); + + Status = NtProtectVirtualMemory( + NtCurrentProcess(), + &DataDirectoryPtr, + &DataDirectorySize, + PAGE_READWRITE, + &OldProtect); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + return Status; + } + + // Zero it out. + RtlZeroMemory(BoundImportDirectory, sizeof(*BoundImportDirectory)); + + Status = NtProtectVirtualMemory( + NtCurrentProcess(), + &DataDirectoryPtr, + &DataDirectorySize, + OldProtect, + &OldProtect); + + ASSERT (NT_SUCCESS(Status)); + } + + return STATUS_SUCCESS; +} + +// +// This function expects Win32 paths. +// +// The path may be omitted from the DllPath argument, i.e. "kernel32.dll". +// The rewritten path will always be a DLL base name without extension, for +// example "kxbase". +// +// The RewrittenDllPath argument must have the Buffer element set to an +// appropriate Unicode buffer, and the MaximumLength element set to the size +// in bytes of that buffer. +// +// It's OK to have DllPath->Buffer and RewrittenDllNameOut->Buffer point to +// the same buffer. However, DllPath and RewrittenDllNameOut must not point +// to the same UNICODE_STRING structure. +// + +NTSTATUS KexRewriteDllPath( + IN PCUNICODE_STRING DllPath, + OUT PUNICODE_STRING RewrittenDllNameOut) +{ + NTSTATUS Status; + UNICODE_STRING DllFileName; + UNICODE_STRING RewrittenDllName; + + // + // Validate parameters. + // + + ASSERT (DllRewriteStringMapper != NULL); + + ASSERT (VALID_UNICODE_STRING(DllPath)); + ASSERT (DllPath->Length != 0); + ASSERT (DllPath->Buffer != NULL); + + ASSERT (VALID_UNICODE_STRING(RewrittenDllNameOut)); + ASSERT (RewrittenDllNameOut->MaximumLength != 0); + ASSERT (RewrittenDllNameOut->Buffer != NULL); + + ASSERT (DllPath != RewrittenDllNameOut); + ASSERT (RewrittenDllNameOut->MaximumLength >= DllPath->Length); + + // + // Set the output length to zero. We will append to it later. + // + + RewrittenDllNameOut->Length = 0; + + // + // Get the file-name component of the path. + // If the path consists of only a filename, that's ok too. + // + + Status = KexRtlPathFindFileName( + DllPath, + &DllFileName); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + return Status; + } + + // + // If the original DLL path (when specified) is *not* in the Windows directory, + // we will not rewrite this DLL name. VxKex only involves itself in replacing + // Windows DLLs, not other DLLs bundled with the application. + // + + if (DllFileName.Buffer != DllPath->Buffer) { + // A full path was specified, not just a DLL name. + + if (!RtlPrefixUnicodeString(&KexData->WinDir, DllPath, TRUE)) { + // the requested DLL isn't inside the Windows directory + return STATUS_DLL_NOT_IN_SYSTEM_ROOT; + } + } + + // + // Lookup the DLL rewrite entry. + // Keep in mind that the output (RewrittenDllName) of this function + // is a DLL base name without .dll extension, e.g. "kxbase". + // + + Status = KexpLookupDllRewriteEntry( + &DllFileName, + &RewrittenDllName); + + ASSERT (NT_SUCCESS(Status) || Status == STATUS_STRING_MAPPER_ENTRY_NOT_FOUND); + + if (!NT_SUCCESS(Status)) { + return Status; + } + + KexLogDebugEvent( + L"DLL name or path was successfully rewritten: %wZ -> %wZ\r\n\r\n" + L"Original DLL name or path: %wZ", + &DllFileName, + &RewrittenDllName, + DllPath); + + RtlCopyUnicodeString(RewrittenDllNameOut, &RewrittenDllName); + + ASSERT (VALID_UNICODE_STRING(RewrittenDllNameOut)); + return Status; +} \ No newline at end of file diff --git a/KexDll/dload.c b/KexDll/dload.c new file mode 100644 index 0000000..e2e8503 --- /dev/null +++ b/KexDll/dload.c @@ -0,0 +1,324 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// dload.c +// +// Abstract: +// +// Implements the LdrResolveDelayLoadedAPI function, which is found on +// Windows 8 and above. This function is required by many Windows 8 DLLs. +// +// Author: +// +// vxiiduu (14-Feb-2024) +// +// Environment: +// +// At any time when other DLLs are present. +// +// Revision History: +// +// vxiiduu 14-Feb-2024 Initial creation. +// vxiiduu 23-Feb-2024 Rework DLL load part of the function. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kexdllp.h" + +// +// This function is essentially a combination of LoadLibrary and GetProcAddress. +// Its job is to resolve a singular DLL API function and write it into a +// particular location. +// +// If we fail to do so, and there are failure hooks provided, we need to call +// those in an attempt to remedy the missing API functions. (But in practice +// those failure hooks are either not provided or don't do anything useful.) +// +PVOID NTAPI KexLdrResolveDelayLoadedAPI( + IN PVOID ParentModuleBase, + IN PCIMAGE_DELAYLOAD_DESCRIPTOR DelayloadDescriptor, + IN PDELAYLOAD_FAILURE_DLL_CALLBACK FailureDllHook OPTIONAL, + IN PDELAYLOAD_FAILURE_SYSTEM_ROUTINE FailureSystemHook OPTIONAL, + OUT PIMAGE_THUNK_DATA ThunkAddress, + IN ULONG Flags) +{ + NTSTATUS Status; + PPVOID DelayLoadedDllHandle; + PIMAGE_THUNK_DATA ImportAddressTable; + PIMAGE_THUNK_DATA ImportNameTable; + PCSTR NameOfDllToLoad; + PCSTR NameOfDelayLoadedAPI; + USHORT OrdinalOfDelayLoadedAPI; + PVOID ProcedureAddress; + ULONG Index; + + ProcedureAddress = NULL; + + // + // Validate parameters. + // + + ASSERT (ParentModuleBase != NULL); + ASSERT (DelayloadDescriptor != NULL); + ASSERT (ThunkAddress != NULL); + + if (Flags) { + // The Flags parameter is reserved. + return NULL; + } + + if (DelayloadDescriptor->Attributes.RvaBased == 0) { + // This function does not handle v1 delay load descriptors. + return NULL; + } + + // + // Decode some RVAs. + // + + NameOfDllToLoad = (PCSTR) RVA_TO_VA(ParentModuleBase, DelayloadDescriptor->DllNameRVA); + DelayLoadedDllHandle = (PPVOID) RVA_TO_VA(ParentModuleBase, DelayloadDescriptor->ModuleHandleRVA); + ImportAddressTable = (PIMAGE_THUNK_DATA) RVA_TO_VA(ParentModuleBase, DelayloadDescriptor->ImportAddressTableRVA); + ImportNameTable = (PIMAGE_THUNK_DATA) RVA_TO_VA(ParentModuleBase, DelayloadDescriptor->ImportNameTableRVA); + Index = (ULONG) (ThunkAddress - ImportAddressTable); + + if (IMAGE_SNAP_BY_ORDINAL(ImportNameTable[Index].u1.Ordinal)) { + NameOfDelayLoadedAPI = NULL; + OrdinalOfDelayLoadedAPI = (USHORT) ImportNameTable[Index].u1.Ordinal; + } else { + PIMAGE_IMPORT_BY_NAME ImportByName; + + ImportByName = (PIMAGE_IMPORT_BY_NAME) RVA_TO_VA(ParentModuleBase, ImportNameTable[Index].u1.AddressOfData); + NameOfDelayLoadedAPI = (PCSTR) ImportByName->Name; + OrdinalOfDelayLoadedAPI = 0; + } + + if (*DelayLoadedDllHandle == NULL) { + ANSI_STRING NameOfDllToLoadAS; + UNICODE_STRING NameOfDllToLoadUS; + UNICODE_STRING RewrittenDllName; + + // + // DLL not loaded, we need to load it. + // + + RtlInitEmptyUnicodeStringFromTeb(&NameOfDllToLoadUS); + + Status = RtlInitAnsiStringEx(&NameOfDllToLoadAS, NameOfDllToLoad); + ASSERT (NT_SUCCESS(Status)); + + Status = RtlAnsiStringToUnicodeString(&NameOfDllToLoadUS, &NameOfDllToLoadAS, FALSE); + ASSERT (NT_SUCCESS(Status)); + + // + // Rewrite DLL name. + // + + RewrittenDllName = NameOfDllToLoadUS; + + Status = KexRewriteDllPath( + &NameOfDllToLoadUS, + &RewrittenDllName); + + ASSERT (NT_SUCCESS(Status) || Status == STATUS_STRING_MAPPER_ENTRY_NOT_FOUND); + + if (NT_SUCCESS(Status)) { + NameOfDllToLoadUS = RewrittenDllName; + + // + // The DLL name was rewritten. + // Allocate a temporary stack buffer, and convert the DLL name back + // to ANSI and put that in the global variable NameOfDllToLoad for the + // rest of this function to use. + // + + NameOfDllToLoadAS.Length = RtlUnicodeStringToAnsiSize(&NameOfDllToLoadUS); + NameOfDllToLoadAS.MaximumLength = NameOfDllToLoadAS.Length; + NameOfDllToLoadAS.Buffer = StackAlloc(CHAR, NameOfDllToLoadAS.MaximumLength); + + Status = RtlUnicodeStringToAnsiString(&NameOfDllToLoadAS, &NameOfDllToLoadUS, FALSE); + ASSERT (NT_SUCCESS(Status)); + + NameOfDllToLoad = NameOfDllToLoadAS.Buffer; + } + + Status = LdrLoadDll( + NULL, + NULL, + &NameOfDllToLoadUS, + DelayLoadedDllHandle); + + if (!NT_SUCCESS(Status)) { + KexLogErrorEvent( + L"The DLL %wZ could not be delay-loaded.\r\n\r\n" + L"NTSTATUS error code: %s (0x%08lx)", + &NameOfDllToLoadUS, + KexRtlNtStatusToString(Status), Status); + + goto Failure; + } + } + + ASSERT (*DelayLoadedDllHandle != NULL); + + // + // Now that the DLL is loaded, we need to find the procedure address that + // we're looking for. + // + + if (NameOfDelayLoadedAPI) { + ANSI_STRING NameOfDelayLoadedAPIAS; + + // + // Import by procedure name. + // + + Status = RtlInitAnsiStringEx(&NameOfDelayLoadedAPIAS, NameOfDelayLoadedAPI); + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + goto Failure; + } + + Status = LdrGetProcedureAddress( + *DelayLoadedDllHandle, + &NameOfDelayLoadedAPIAS, + 0, + &ProcedureAddress); + } else { + // + // Import by procedure ordinal number. + // + + Status = LdrGetProcedureAddress( + *DelayLoadedDllHandle, + NULL, + OrdinalOfDelayLoadedAPI, + &ProcedureAddress); + } + + if (!NT_SUCCESS(Status)) { + if (NameOfDelayLoadedAPI) { + KexLogErrorEvent( + L"The procedure %hs was not found in %hs.\r\n\r\n" + L"NTSTATUS error code: %s (0x%08lx)", + NameOfDelayLoadedAPI, + NameOfDllToLoad, + KexRtlNtStatusToString(Status), Status); + } else { + KexLogErrorEvent( + L"The ordinal #%hu was not found in %hs.\r\n\r\n" + L"NTSTATUS error code: %s (0x%08lx)", + OrdinalOfDelayLoadedAPI, + NameOfDllToLoad, + KexRtlNtStatusToString(Status), Status); + } + + goto Failure; + } + +Failure: + if (!ProcedureAddress) { + if (FailureDllHook) { + DELAYLOAD_INFO DelayLoadInfo; + + // + // The application that has delay loaded some APIs has an opportunity + // to recover from the situation where he tries to call some delay loaded + // API but it can't be found. + // + // In most applications, the pointer to this hook is named + // _pfnDefaultDliFailureHook2 and is provided by the C runtime, but its value + // is often NULL because devs don't care about providing a fallback when the + // precious API they depend on isn't available. + // + + RtlZeroMemory(&DelayLoadInfo, sizeof(DelayLoadInfo)); + + DelayLoadInfo.Size = sizeof(DelayLoadInfo); + DelayLoadInfo.DelayloadDescriptor = DelayloadDescriptor; + DelayLoadInfo.ThunkAddress = ThunkAddress; + DelayLoadInfo.TargetDllName = NameOfDllToLoad; + DelayLoadInfo.TargetModuleBase = *DelayLoadedDllHandle; + DelayLoadInfo.LastError = RtlNtStatusToDosErrorNoTeb(Status); + + if (NameOfDelayLoadedAPI) { + DelayLoadInfo.TargetApiDescriptor.ImportDescribedByName = TRUE; + DelayLoadInfo.TargetApiDescriptor.Description.Name = NameOfDelayLoadedAPI; + } else { + DelayLoadInfo.TargetApiDescriptor.ImportDescribedByName = FALSE; + DelayLoadInfo.TargetApiDescriptor.Description.Ordinal = OrdinalOfDelayLoadedAPI; + } + + KexLogDebugEvent(L"Calling failure DLL hook"); + + ProcedureAddress = FailureDllHook( + DELAYLOAD_GPA_FAILURE, + &DelayLoadInfo); + } + + if (!ProcedureAddress) { + // + // If there was no application-provided failure hook, or the failure hook + // itself failed to solve the problem, there is a system failure hook pointer + // provided as well. + // + // Most likely, this is a pointer to the function DelayLoadFailureHook located + // inside kernel32.dll. This function is available on Windows 2000 and above, + // despite the Microsoft documentation saying it is only available on Windows 8 + // and above. (On Windows 8 it is physically located inside kernelbase instead.) + // + // The Windows 7 version of DelayLoadFailureHook at least seems quite similar + // to the version from the leaked Windows XP source code, so have a look at that + // if you want to know what it does. (I haven't bothered.) + // + + KexLogDebugEvent(L"Calling failure system hook"); + + if (FailureSystemHook) { + ProcedureAddress = FailureSystemHook( + NameOfDllToLoad, + NameOfDelayLoadedAPI); + } + } + } + + if (ProcedureAddress) { + ImportAddressTable[Index].u1.Function = (ULONG_PTR) ProcedureAddress; + + if (NameOfDelayLoadedAPI) { + KexLogDebugEvent( + L"The procedure %hs was successfully delay-loaded from %hs", + NameOfDelayLoadedAPI, + NameOfDllToLoad); + } else { + KexLogDebugEvent( + L"The ordinal #%hu was successfully delay-loaded from %hs", + OrdinalOfDelayLoadedAPI, + NameOfDllToLoad); + } + } + + return ProcedureAddress; +} + +// +// This is the delay-load helper function used by KexDll itself. +// + +EXTERN PVOID __ImageBase; + +STATIC PVOID WINAPI __delayLoadHelper2( + IN PCIMAGE_DELAYLOAD_DESCRIPTOR DelayloadDescriptor, + OUT PIMAGE_THUNK_DATA ThunkData) +{ + return KexLdrResolveDelayLoadedAPI( + &__ImageBase, + DelayloadDescriptor, + NULL, + NULL, + ThunkData, + 0); +} \ No newline at end of file diff --git a/KexDll/etw.c b/KexDll/etw.c new file mode 100644 index 0000000..f9fbcae --- /dev/null +++ b/KexDll/etw.c @@ -0,0 +1,78 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// etw.c +// +// Abstract: +// +// Contains implementations of some ETW (Event Tracing for Windows) +// functions. +// +// Author: +// +// vxiiduu (16-Mar-2024) +// +// Environment: +// +// Native mode. +// +// Revision History: +// +// vxiiduu 16-Mar-2024 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kexdllp.h" +#include + +typedef ULONG EVENT_INFO_CLASS; + +// +// EtwEventSetInformation (which is forwarded from advapi32!EventSetInformation) +// is available only on later builds of Windows 7. This function is here as a +// proxy, so that earlier builds of Windows 7 do not fail to launch applications +// due to the lack of this non-essential function. +// + +KEXAPI ULONG NTAPI KexEtwEventSetInformation( + IN REGHANDLE Handle, + IN EVENT_INFO_CLASS InformationClass, + IN PVOID EventInformation, + IN ULONG InformationLength) +{ + STATIC ULONG (NTAPI *EtwEventSetInformation) (REGHANDLE, EVENT_INFO_CLASS, PVOID, ULONG) = NULL; + + if (!EtwEventSetInformation) { + NTSTATUS Status; + ANSI_STRING ProcedureName; + + RtlInitConstantAnsiString(&ProcedureName, "EtwEventSetInformation"); + + Status = LdrGetProcedureAddress( + KexData->SystemDllBase, + &ProcedureName, + 0, + (PPVOID) &EtwEventSetInformation); + + if (!NT_SUCCESS(Status)) { + ASSUME (EtwEventSetInformation == NULL); + + KexLogInformationEvent( + L"EtwEventSetInformation is not available on this computer\r\n\r\n" + L"This function was made available in later updates to Windows 7. " + L"VxKex will return ERROR_NOT_SUPPORTED to the calling application."); + } + + if (NT_SUCCESS(Status)) { + ASSUME (EtwEventSetInformation != NULL); + } + } + + if (!EtwEventSetInformation) { + return ERROR_NOT_SUPPORTED; + } + + return EtwEventSetInformation(Handle, InformationClass, EventInformation, InformationLength); +} \ No newline at end of file diff --git a/KexDll/except.c b/KexDll/except.c new file mode 100644 index 0000000..3513e91 --- /dev/null +++ b/KexDll/except.c @@ -0,0 +1,84 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// except.c +// +// Abstract: +// +// Contains the exception filter for general protected functions in KexDll. +// +// Author: +// +// vxiiduu (30-Oct-2022) +// +// Revision History: +// +// vxiiduu 30-Oct-2022 Initial creation. +// vxiiduu 23-Feb-2024 VxlWriteLogEx is no longer a protected +// function - remove extra SEH wrapping +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kexdllp.h" + +// +// This function cannot contain any errors or bugs. +// +ULONG KexDllProtectedFunctionExceptionFilter( + IN PCWSTR FunctionName, + IN NTSTATUS ExceptionCode, + IN PEXCEPTION_POINTERS ExceptionPointers) +{ + PEXCEPTION_RECORD ExceptionRecord; + + if (ExceptionCode == STATUS_ASSERTION_FAILURE || + ExceptionCode == STATUS_BREAKPOINT) { + + // Do not catch assertions and breakpoints. + // Otherwise it would be harder to debug. + return EXCEPTION_CONTINUE_SEARCH; + } + + ExceptionRecord = ExceptionPointers->ExceptionRecord; + + if (ExceptionCode == STATUS_ACCESS_VIOLATION) { + PCWSTR AccessType; + + switch (ExceptionRecord->ExceptionInformation[0]) { + case 0: + AccessType = L"read"; + break; + case 1: + AccessType = L"write"; + break; + case 8: + AccessType = L"execute"; + break; + default: + NOT_REACHED; + } + + KexLogErrorEvent( + L"UNHANDLED EXCEPTION in %s\r\n\r\n" + L"Exception code: %s (0x%08lx)\r\n" + L"Exception address: 0x%p\r\n\r\n" + L"Attempt to %s the inaccessible location 0x%p.", + FunctionName, + KexRtlNtStatusToString(ExceptionCode), ExceptionCode, + ExceptionRecord->ExceptionAddress, + AccessType, + ExceptionRecord->ExceptionInformation[1]); + } else { + KexLogErrorEvent( + L"UNHANDLED EXCEPTION in %s\r\n\r\n" + L"Exception code: %s (0x%08lx)\r\n" + L"Exception address: 0x%p", + FunctionName, + KexRtlNtStatusToString(ExceptionCode), ExceptionCode, + ExceptionRecord->ExceptionAddress); + } + + return EXCEPTION_EXECUTE_HANDLER; +} \ No newline at end of file diff --git a/KexDll/kexdata.c b/KexDll/kexdata.c new file mode 100644 index 0000000..4c1dba8 --- /dev/null +++ b/KexDll/kexdata.c @@ -0,0 +1,400 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// kexdata.c +// +// Abstract: +// +// Contains a definition and an initialization routine for the +// KEX_PROCESS_DATA structure. +// +// Author: +// +// vxiiduu (18-Oct-2022) +// +// Revision History: +// +// vxiiduu 18-Oct-2022 Initial creation. +// vxiiduu 06-Nov-2022 Add IFEO parameter reading. +// vxiiduu 07-Nov-2022 Remove spurious range check. +// vxiiduu 23-Feb-2024 Add setting to disable logging. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kexdllp.h" + +STATIC WCHAR KexDirBuffer[MAX_PATH]; +STATIC WCHAR LogDirBuffer[MAX_PATH]; +STATIC WCHAR ImageBaseNameBuffer[MAX_PATH]; +STATIC WCHAR Kex3264DirBuffer[MAX_PATH]; + +KEX_PROCESS_DATA _KexData = { + 0, // Flags + {0}, // IfeoParameters + + {0, 0, NULL}, // WinDir + {0, ARRAYSIZE(KexDirBuffer), KexDirBuffer}, // KexDir + {0, ARRAYSIZE(LogDirBuffer), LogDirBuffer}, // LogDir + {0, ARRAYSIZE(Kex3264DirBuffer), Kex3264DirBuffer}, // Kex3264Dir + {0, ARRAYSIZE(ImageBaseNameBuffer), ImageBaseNameBuffer}, // ImageBaseName + + NULL, // LogHandle + NULL, // KexDllBase + NULL, // SystemDllBase + NULL, // NativeSystemDllBase + NULL, // BaseDllBase + NULL, // BaseNamedObjects + NULL, // UntrustedBaseNamedObjects +}; + +PKEX_PROCESS_DATA KexData = NULL; + +#define GENERATE_QKMV_TABLE_ENTRY(Name, Restrict) \ + { \ + RTL_CONSTANT_STRING(L#Name), \ + 0, \ + sizeof(_KexData.Name), \ + &_KexData.Name, \ + Restrict, \ + 0 \ + } + +#define GENERATE_QKMV_TABLE_ENTRY_UNICODE_STRING(Name) \ + { \ + RTL_CONSTANT_STRING(L#Name), \ + 0, \ + _KexData.Name.MaximumLength, \ + _KexData.Name.Buffer, \ + REG_RESTRICT_SZ | REG_RESTRICT_EXPAND_SZ, \ + 0 \ + } + +STATIC NTSTATUS KexpInitializeGlobalConfig( + VOID) +{ + NTSTATUS Status; + HANDLE KeyHandle; + UNICODE_STRING KeyName; + OBJECT_ATTRIBUTES ObjectAttributes; + ULONG DisableLogging; + + ULONG QueryTableNumberOfElements; + KEX_RTL_QUERY_KEY_MULTIPLE_VARIABLE_TABLE_ENTRY QueryTable[] = { + {RTL_CONSTANT_STRING(L"DisableLogging"), 0, 8, &DisableLogging, REG_RESTRICT_DWORD, 0}, + GENERATE_QKMV_TABLE_ENTRY_UNICODE_STRING (KexDir), + GENERATE_QKMV_TABLE_ENTRY_UNICODE_STRING (LogDir) + }; + + DisableLogging = 0; + + // + // Open the vxkex HKLM key. + // + + RtlInitConstantUnicodeString(&KeyName, L"\\Registry\\Machine\\Software\\VXsoft\\VxKex"); + InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); + + Status = NtOpenKey( + &KeyHandle, + KEY_READ | KEY_WOW64_64KEY, + &ObjectAttributes); + + if (!NT_SUCCESS(Status)) { + return Status; + } + + // + // Query global configuration values. + // + + QueryTableNumberOfElements = ARRAYSIZE(QueryTable); + KexRtlQueryKeyMultipleValueData( + KeyHandle, + QueryTable, + &QueryTableNumberOfElements, + 0); + + if (DisableLogging) { + _KexData.Flags |= KEXDATA_FLAG_DISABLE_LOGGING; + } + + // + // Fixup lengths of UNICODE_STRINGs read from the registry. + // + + KexRtlUpdateNullTerminatedUnicodeStringLength(&_KexData.KexDir); + KexRtlUpdateNullTerminatedUnicodeStringLength(&_KexData.LogDir); + + SafeClose(KeyHandle); + return Status; +} + +// +// Local configuration is read from HKCU and overrides global configuration. +// + +STATIC NTSTATUS KexpInitializeLocalConfig( + VOID) +{ + NTSTATUS Status; + HANDLE CurrentUserKeyHandle; + HANDLE KeyHandle; + UNICODE_STRING KeyName; + OBJECT_ATTRIBUTES ObjectAttributes; + ULONG DisableLogging; + + ULONG QueryTableNumberOfElements; + KEX_RTL_QUERY_KEY_MULTIPLE_VARIABLE_TABLE_ENTRY QueryTable[] = { + {RTL_CONSTANT_STRING(L"DisableLogging"), 0, 8, &DisableLogging, REG_RESTRICT_DWORD, 0}, + GENERATE_QKMV_TABLE_ENTRY_UNICODE_STRING (LogDir) + }; + + DisableLogging = _KexData.Flags & KEXDATA_FLAG_DISABLE_LOGGING; + + Status = RtlOpenCurrentUser(KEY_ENUMERATE_SUB_KEYS, &CurrentUserKeyHandle); + if (!NT_SUCCESS(Status)) { + return Status; + } + + RtlInitConstantUnicodeString(&KeyName, L"Software\\VXsoft\\VxKex"); + + InitializeObjectAttributes( + &ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + CurrentUserKeyHandle, + NULL); + + Status = NtOpenKey( + &KeyHandle, + KEY_READ | KEY_WOW64_64KEY, + &ObjectAttributes); + + SafeClose(CurrentUserKeyHandle); + + if (!NT_SUCCESS(Status)) { + return Status; + } + + QueryTableNumberOfElements = ARRAYSIZE(QueryTable); + KexRtlQueryKeyMultipleValueData( + KeyHandle, + QueryTable, + &QueryTableNumberOfElements, + 0); + + if (DisableLogging) { + _KexData.Flags |= KEXDATA_FLAG_DISABLE_LOGGING; + } else { + _KexData.Flags &= ~KEXDATA_FLAG_DISABLE_LOGGING; + } + + KexRtlUpdateNullTerminatedUnicodeStringLength(&_KexData.LogDir); + + SafeClose(KeyHandle); + return Status; +} + +STATIC NTSTATUS KexpInitializeIfeoParameters( + OUT PKEX_PROCESS_DATA Data) +{ + NTSTATUS Status; + ULONG NoKexOptionsInRegistry; + HANDLE IfeoKeyHandle; + UNICODE_STRING MsiexecFullPath; + PKEX_IFEO_PARAMETERS IfeoParameters; + PPEB Peb; + + Peb = NtCurrentPeb(); + IfeoParameters = &Data->IfeoParameters; + + NoKexOptionsInRegistry = 0xffffffff; + + RtlInitEmptyUnicodeStringFromTeb(&MsiexecFullPath); + RtlAppendUnicodeStringToString(&MsiexecFullPath, &Data->WinDir); + RtlAppendUnicodeToString(&MsiexecFullPath, L"\\system32\\msiexec.exe"); + + if (RtlEqualUnicodeString(&Peb->ProcessParameters->ImagePathName, &MsiexecFullPath, TRUE)) { + UNICODE_STRING CommandLine; + UNICODE_STRING MsiFullPath; + UNICODE_STRING DotMsi; + PWCHAR DotMsiLocation; + + Data->Flags |= KEXDATA_FLAG_MSIEXEC; + Status = STATUS_OBJECT_NAME_NOT_FOUND; + + // + // We are currently loaded into %SystemRoot%\system32\msiexec.exe. + // Open the IFEO key for the .msi file, not the one for msiexec.exe itself. + // This is going to require us to parse command line arguments. + // + + CommandLine = Peb->ProcessParameters->CommandLine; + RtlInitConstantUnicodeString(&DotMsi, L".MSI\""); + + DotMsiLocation = KexRtlFindUnicodeSubstring(&CommandLine, &DotMsi, TRUE); + + if (DotMsiLocation) { + MsiFullPath.Length = DotMsi.Length; + MsiFullPath.MaximumLength = DotMsi.Length; + MsiFullPath.Buffer = DotMsiLocation; + + // we've found the .msi extension and the close quote, now retreat the + // string until we find the start quote. + until (MsiFullPath.Buffer[0] == '"' || MsiFullPath.Buffer == CommandLine.Buffer) { + KexRtlRetreatUnicodeString(&MsiFullPath, sizeof(WCHAR)); + } + + if (MsiFullPath.Buffer[0] == '"') { + KexRtlAdvanceUnicodeString(&MsiFullPath, sizeof(WCHAR)); + MsiFullPath.Length -= sizeof(WCHAR); + + Status = LdrOpenImageFileOptionsKey( + &MsiFullPath, + FALSE, + &IfeoKeyHandle); + + if (NT_SUCCESS(Status)) { + Data->Flags |= KEXDATA_FLAG_ENABLED_FOR_MSI; + } + } + } + } else { + // + // Open the IFEO key for the current executable. + // + + Status = LdrOpenImageFileOptionsKey( + &Peb->ProcessParameters->ImagePathName, + FALSE, + &IfeoKeyHandle); + } + + if (!NT_SUCCESS(Status)) { + goto Exit; + } + + NoKexOptionsInRegistry &= LdrQueryImageFileKeyOption( + IfeoKeyHandle, + L"KEX_DisableForChild", + REG_DWORD, + &IfeoParameters->DisableForChild, + sizeof(IfeoParameters->DisableForChild), + NULL); + + NoKexOptionsInRegistry &= LdrQueryImageFileKeyOption( + IfeoKeyHandle, + L"KEX_DisableAppSpecific", + REG_DWORD, + &IfeoParameters->DisableAppSpecific, + sizeof(IfeoParameters->DisableAppSpecific), + NULL); + + NoKexOptionsInRegistry &= LdrQueryImageFileKeyOption( + IfeoKeyHandle, + L"KEX_WinVerSpoof", + REG_DWORD, + &IfeoParameters->WinVerSpoof, + sizeof(IfeoParameters->WinVerSpoof), + NULL); + + NoKexOptionsInRegistry &= LdrQueryImageFileKeyOption( + IfeoKeyHandle, + L"KEX_StrongVersionSpoof", + REG_DWORD, + &IfeoParameters->StrongVersionSpoof, + sizeof(IfeoParameters->StrongVersionSpoof), + NULL); + + SafeClose(IfeoKeyHandle); + +Exit: + unless (NoKexOptionsInRegistry) { + // Indicate that this process has VxKex options present in the registry. + Data->Flags |= KEXDATA_FLAG_IFEO_OPTIONS_PRESENT; + } + + return Status; +} + +KEXAPI NTSTATUS NTAPI KexDataInitialize( + OUT PPKEX_PROCESS_DATA KexDataOut OPTIONAL) +{ + NTSTATUS Status; + + if (KexData) { + if (KexDataOut) { + *KexDataOut = KexData; + } + + return STATUS_ALREADY_INITIALIZED; + } + + // + // Grab windir from SharedUserData. It's faster and more reliable + // than trying to query environment variables or registry. + // + + RtlInitUnicodeString(&_KexData.WinDir, SharedUserData->NtSystemRoot); + + KexRtlGetProcessImageBaseName(&_KexData.ImageBaseName); + KexpInitializeIfeoParameters(&_KexData); + KexpInitializeGlobalConfig(); + KexpInitializeLocalConfig(); + + // + // Assemble Kex3264Dir + // + + RtlCopyUnicodeString(&_KexData.Kex3264DirPath, &_KexData.KexDir); + + if (KexIs64BitBuild) { + Status = RtlAppendUnicodeToString(&_KexData.Kex3264DirPath, L"\\Kex64;"); + } else { + Status = RtlAppendUnicodeToString(&_KexData.Kex3264DirPath, L"\\Kex32;"); + } + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + return Status; + } + + Status = KexRtlNullTerminateUnicodeString(&_KexData.Kex3264DirPath); + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + return Status; + } + + // + // Get NTDLL base address. + // + + _KexData.SystemDllBase = KexLdrGetSystemDllBase(); + _KexData.NativeSystemDllBase = KexLdrGetNativeSystemDllBase(); + + ASSERT (_KexData.SystemDllBase != NULL); + ASSERT (_KexData.NativeSystemDllBase != NULL); + + if (KexRtlCurrentProcessBitness() != KexRtlOperatingSystemBitness()) { + ASSERT (_KexData.SystemDllBase != _KexData.NativeSystemDllBase); + } + + // + // All done + // + + KexData = &_KexData; + + if (KexDataOut) { + *KexDataOut = KexData; + } + + return STATUS_SUCCESS; +} + +#undef GENERATE_QKMV_TABLE_ENTRY +#undef GENERATE_QKMV_TABLE_ENTRY_UNICODE_STRING \ No newline at end of file diff --git a/KexDll/kexdllp.h b/KexDll/kexdllp.h new file mode 100644 index 0000000..483b330 --- /dev/null +++ b/KexDll/kexdllp.h @@ -0,0 +1,214 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// kexdllp.h +// +// Abstract: +// +// Private header file for KexDll. +// +// Author: +// +// vxiiduu (18-Oct-2022) +// +// Revision History: +// +// vxiiduu 18-Oct-2022 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "buildcfg.h" +#include +#include + +// +// These flags are the same as the ones in WinUser.h. +// Pass to KexMessageBox. +// + +#define MB_ICONERROR 0x00000010 +#define MB_ICONQUESTION 0x00000020 +#define MB_ICONEXCLAMATION 0x00000030 +#define MB_ICONINFORMATION 0x00000040 + +#define MB_OK 0x00000000 + +// +// Data type definitions +// + +typedef enum _KEX_DWRITE_IMPLEMENTATION { + DWriteNoImplementation, + DWriteWindows10Implementation +} TYPEDEF_TYPE_NAME(KEX_DWRITE_IMPLEMENTATION); + +// +// Protected Function Macros should be used on every function in KexDll. +// Usage of PROTECTED_FUNCTION(_END(_NOLOG)) wraps each function with SEH. +// It is particularly useful for creating syscall implementations or +// wrappers, since "real" syscalls never crash (unless there's a bug in the +// kernel). +// +// PROTECTED_FUNCTION_END_NOLOG causes the error not to be logged. This +// macro should only be used on functions that are directly involved in +// logging errors in order to avoid an infinite loop and stack overflow. +// +// PROTECTED_FUNCTION_END_BOOLEAN returns FALSE instead of a NTSTATUS. +// + +ULONG KexDllProtectedFunctionExceptionFilter( + IN PCWSTR FunctionName, + IN NTSTATUS ExceptionCode, + IN PEXCEPTION_POINTERS ExceptionPointers); + +#if DISABLE_PROTECTED_FUNCTION == FALSE +# define PROTECTED_FUNCTION { try + +# define PROTECTED_FUNCTION_END \ + except (KexDllProtectedFunctionExceptionFilter(__FUNCTIONW__, GetExceptionCode(), GetExceptionInformation())) { \ + return GetExceptionCode(); \ + }} +#else +# define PROTECTED_FUNCTION +# define PROTECTED_FUNCTION_END +#endif + +// +// ash.c +// + +VOID AshApplyQBittorrentEnvironmentVariableHacks( + VOID); + +// +// ashcrsup.c +// + +NTSTATUS AshPerformChromiumDetectionFromLoadedDll( + IN PCLDR_DLL_NOTIFICATION_DATA NotificationData); + +NTSTATUS AshPerformChromiumDetectionFromModuleExports( + IN PVOID ModuleBase); + +// +// ashselec.c +// + +NTSTATUS AshSelectDWriteImplementation( + IN KEX_DWRITE_IMPLEMENTATION Implementation); + +// +// avrf.c +// + +NTSTATUS KexDisableAVrf( + VOID); + +// +// dllnotif.c +// + +VOID NTAPI KexDllNotificationCallback( + IN LDR_DLL_NOTIFICATION_REASON Reason, + IN PCLDR_DLL_NOTIFICATION_DATA NotificationData, + IN PVOID Context); + +// +// dllpath.c +// + +NTSTATUS KexpAddKex3264ToDllPath( + VOID); + +// +// dllrewrt.c +// + +NTSTATUS KexInitializeDllRewrite( + VOID); + +BOOLEAN KexShouldRewriteImportsOfDll( + IN PCUNICODE_STRING FullDllName); + +NTSTATUS KexRewriteImageImportDirectory( + IN PVOID ImageBase, + IN PCUNICODE_STRING BaseImageName, + IN PCUNICODE_STRING FullImageName); + +NTSTATUS KexRewriteDllPath( + IN PCUNICODE_STRING DllPath, + OUT PUNICODE_STRING RewrittenDllNameOut); + +NTSTATUS KexAddDllRewriteEntry( + IN PCUNICODE_STRING DllName, + IN PCUNICODE_STRING RewrittenDllName); + +NTSTATUS KexRemoveDllRewriteEntry( + IN PCUNICODE_STRING DllName); + +// +// kexdata.c +// + +EXTERN PKEX_PROCESS_DATA KexData; + +// +// kexhe.c +// + +NTSTATUS NTAPI Ext_NtRaiseHardError( + IN NTSTATUS ErrorStatus, + IN ULONG NumberOfParameters, + IN ULONG UnicodeStringParameterMask, + IN PULONG_PTR Parameters, + IN ULONG ValidResponseOptions, + OUT PULONG Response); + +NORETURN VOID KexHeErrorBox( + IN PCWSTR ErrorMessage); + +// +// logging.c +// + +NTSTATUS KexOpenVxlLogForCurrentApplication( + OUT PVXLHANDLE LogHandle); + +// +// verspoof.c +// + +VOID KexApplyVersionSpoof( + VOID); + +// +// vxlpriv.c +// + +NTSTATUS VxlpFlushLogFileHeader( + IN VXLHANDLE LogHandle); + +ULONG VxlpGetTotalLogEntryCount( + IN VXLHANDLE LogHandle); + +NTSTATUS VxlpFindOrCreateSourceComponentIndex( + IN VXLHANDLE LogHandle, + IN PCWSTR SourceComponent, + OUT PUCHAR SourceComponentIndex); + +NTSTATUS VxlpFindOrCreateSourceFileIndex( + IN VXLHANDLE LogHandle, + IN PCWSTR SourceFile, + OUT PUCHAR SourceFileIndex); + +NTSTATUS VxlpFindOrCreateSourceFunctionIndex( + IN VXLHANDLE LogHandle, + IN PCWSTR SourceFunction, + OUT PUCHAR SourceFunctionIndex); + +NTSTATUS VxlpBuildIndex( + IN VXLHANDLE LogHandle); + diff --git a/KexDll/kexhe.c b/KexDll/kexhe.c new file mode 100644 index 0000000..01efb7b --- /dev/null +++ b/KexDll/kexhe.c @@ -0,0 +1,197 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// kexhe.c +// +// Abstract: +// +// Hard Error handler. +// +// TODO: long term, perhaps add some more user friendly UI like in +// 0.0.0.3? however, in the absence of kexsrv this might be difficult. +// +// Author: +// +// vxiiduu (29-Oct-2022) +// +// Environment: +// +// During static import resolution. The hard error handler in this file +// is specifically tailored for the subset of NTSTATUS values that can be +// passed by NTDLL while loading static imports. +// +// Revision History: +// +// vxiiduu 29-Oct-2022 Initial creation. +// vxiiduu 05-Nov-2022 Remove ability to remove the HE hook. +// vxiiduu 06-Nov-2022 KEXDLL init failure message now works +// even if KexSrv is not running. +// vxiiduu 05-Jan-2023 Convert to user friendly NTSTATUS. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kexdllp.h" + +// +// Log hard errors. +// +NTSTATUS NTAPI Ext_NtRaiseHardError( + IN NTSTATUS ErrorStatus, + IN ULONG NumberOfParameters, + IN ULONG UnicodeStringParameterMask, + IN PULONG_PTR Parameters, + IN ULONG ValidResponseOptions, + OUT PULONG Response) PROTECTED_FUNCTION +{ + NTSTATUS Status; + ULONG UlongParameter; + PCUNICODE_STRING StringParameter1; + PCUNICODE_STRING StringParameter2; + CONST UNICODE_STRING BlankString = RTL_CONSTANT_STRING(L""); + + StringParameter1 = &BlankString; + StringParameter2 = &BlankString; + + // + // Check the parameters. If anything seems strange, just bail out and + // let the original code deal with it. + // + + if (NumberOfParameters == 0 || NumberOfParameters > 2) { + // All valid error codes here have 1 or 2 params. + goto BailOut; + } + + if (NumberOfParameters == 2 && UnicodeStringParameterMask == 0) { + // Can't have two ULONG parameters + goto BailOut; + } + + // + // Check which members of the Parameters array are strings. + // + + if (UnicodeStringParameterMask & 1) { + StringParameter1 = (PCUNICODE_STRING) Parameters[0]; + } else { + UlongParameter = (ULONG) Parameters[0]; + } + + if (NumberOfParameters >= 2) { + if (UnicodeStringParameterMask & 2) { + StringParameter2 = (PCUNICODE_STRING) Parameters[1]; + } else { + UlongParameter = (ULONG) Parameters[1]; + } + } + + KexLogErrorEvent( + L"Hard Error handler has been called.\r\n\r\n" + L"ErrorStatus: %s (0x%08lx)\r\n" + L"NumberOfParameters: 0x%08lx\r\n" + L"UnicodeStringParameterMask: 0x%08lx\r\n" + L"Parameters: 0x%p\r\n" + L"ValidResponseOptions: %lu\r\n" + L"Response: 0x%p\r\n\r\n" + L"UlongParameter: 0x%08lx\r\n" + L"StringParameter1: \"%wZ\"\r\n" + L"StringParameter2: \"%wZ\"\r\n", + KexRtlNtStatusToString(ErrorStatus), + ErrorStatus, + NumberOfParameters, + UnicodeStringParameterMask, + Parameters, + ValidResponseOptions, + Response, + UlongParameter, + StringParameter1, + StringParameter2); + + // + // call original NtRaiseHardError + // + +BailOut: + KexDebugCheckpoint(); + + Status = KexNtRaiseHardError( + ErrorStatus, + NumberOfParameters, + UnicodeStringParameterMask, + Parameters, + ValidResponseOptions, + Response); + + return Status; +} PROTECTED_FUNCTION_END + +VOID KexMessageBox( + IN ULONG Flags, + IN PCWSTR Caption OPTIONAL, + IN PCWSTR Message OPTIONAL) +{ + UNICODE_STRING MessageUS; + UNICODE_STRING CaptionUS; + ULONG_PTR Parameters[4]; + ULONG Response; + + if (!Message) { + Message = L""; + } + + if (!Caption) { + Caption = L"VxKex"; + } + + RtlInitUnicodeString(&CaptionUS, Caption); + RtlInitUnicodeString(&MessageUS, Message); + + Parameters[0] = (ULONG_PTR) &MessageUS; + Parameters[1] = (ULONG_PTR) &CaptionUS; + Parameters[2] = Flags; // MB_* from kexdllp.h + Parameters[3] = INFINITE; // Timeout in milliseconds + + KexNtRaiseHardError( + STATUS_SERVICE_NOTIFICATION | HARDERROR_OVERRIDE_ERRORMODE, + ARRAYSIZE(Parameters), + 3, + Parameters, + 0, + &Response); +} + +VOID KexMessageBoxF( + IN ULONG Flags, + IN PCWSTR Caption OPTIONAL, + IN PCWSTR Message OPTIONAL, + IN ...) +{ + HRESULT Result; + WCHAR Buffer[512]; + ARGLIST ArgList; + + va_start(ArgList, Message); + + Result = StringCchVPrintf( + Buffer, + ARRAYSIZE(Buffer), + Message, + ArgList); + + va_end(ArgList); + + ASSERT (SUCCEEDED(Result)); + + if (SUCCEEDED(Result)) { + KexMessageBox(Flags, Caption, Buffer); + } +} + +NORETURN VOID KexHeErrorBox( + IN PCWSTR ErrorMessage) +{ + KexMessageBox(MB_ICONERROR, L"Application Error (VxKex)", ErrorMessage); + NtTerminateProcess(NtCurrentProcess(), STATUS_KEXDLL_INITIALIZATION_FAILURE); +} \ No newline at end of file diff --git a/KexDll/kexhk.c b/KexDll/kexhk.c new file mode 100644 index 0000000..c192291 --- /dev/null +++ b/KexDll/kexhk.c @@ -0,0 +1,189 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// kexhk.c +// +// Abstract: +// +// Routines for hooking code. +// +// Intended for usage only during early process initialization, e.g. to +// hook Nt* functions permanently, or temporarily hook functions while +// running in a strictly single-threaded environment. +// +// The only situation where you can safely keep Basic hooks active when +// multiple threads are running is when you never unhook or hook anything +// else. In other terms, only if you have a complete re-implementation of +// the function you are hooking (which is easy for Nt* syscall stubs). +// +// Author: +// +// vxiiduu (23-Oct-2022) +// +// Environment: +// +// Early process creation ONLY. For reasons of simplicity these functions +// are not thread safe at all. +// +// Revision History: +// +// vxiiduu 23-Oct-2022 Initial creation. +// vxiiduu 22-Feb-2024 Add some assertions. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kexdllp.h" + +STATIC BYTE BasicHookTemplate[BASIC_HOOK_LENGTH] = { +#ifdef KEX_ARCH_X64 + 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, // JMP [FuncPtr] + 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC // FuncPtr: DQ 0xCCCCCCCCCCCCCCCC +#else + 0x68, 0xCC, 0xCC, 0xCC, 0xCC, // PUSH 0xCCCCCCCC + 0xC3 // RET +#endif +}; + +// +// Install a hook on a given API routine. +// +// ApiAddress +// Address of a function that you want to hook. +// +// RedirectedAddress +// Address of your function with an identical call signature that you +// want to get called instead of the hooked function. +// +// HookContext +// Optional parameter that allows you to undo the hook later, e.g. if +// you want to uninstall the hook or if you want to call the original API. +// If this parameter is NULL, the hook is permanent. +// +KEXAPI NTSTATUS NTAPI KexHkInstallBasicHook( + IN PVOID ApiAddress, + IN PVOID RedirectedAddress, + OUT PKEX_BASIC_HOOK_CONTEXT HookContext OPTIONAL) +{ + NTSTATUS Status; + PVOID ApiPageAddress; + SIZE_T HookLength; + ULONG OldProtect; + + ASSERT (ApiAddress != NULL); + ASSERT (RedirectedAddress != NULL); + + if (!ApiAddress) { + return STATUS_INVALID_PARAMETER_1; + } + + if (!RedirectedAddress) { + return STATUS_INVALID_PARAMETER_2; + } + + ApiPageAddress = ApiAddress; + HookLength = sizeof(BasicHookTemplate); + + // + // Fill out hook context fields, copy the original bytes (so + // we can undo the hook later), and prepare the hook template for + // writing. + // + + if (HookContext) { + HookContext->OriginalApiAddress = ApiAddress; + + KexRtlCopyMemory( + HookContext->OriginalInstructions, + ApiAddress, + sizeof(BasicHookTemplate)); + } + + *(PPVOID) (&BasicHookTemplate[BASIC_HOOK_DESTINATION_OFFSET]) = RedirectedAddress; + + // + // Let us write to the address of the hooked API. + // We use the KexNt* private syscall stub because otherwise we risk changing + // memory protection on the NtProtectVirtualMemory stub itself, and therefore + // causing recursive access violation exceptions upon return from the system + // call. (This actually happened, not just theoretical.) + // + + Status = KexNtProtectVirtualMemory( + NtCurrentProcess(), + &ApiPageAddress, + &HookLength, + PAGE_READWRITE, + &OldProtect); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + return Status; + } + + // + // Hook the function and restore old page protections. + // + + KexRtlCopyMemory(ApiAddress, BasicHookTemplate, sizeof(BasicHookTemplate)); + + Status = KexNtProtectVirtualMemory( + NtCurrentProcess(), + &ApiPageAddress, + &HookLength, + OldProtect, + &OldProtect); + + ASSERT (NT_SUCCESS(Status)); + + return STATUS_SUCCESS; +} + +KEXAPI NTSTATUS NTAPI KexHkRemoveBasicHook( + IN PKEX_BASIC_HOOK_CONTEXT HookContext) +{ + NTSTATUS Status; + PVOID ApiPageAddress; + SIZE_T HookLength; + ULONG OldProtect; + + ASSERT (HookContext != NULL); + + if (!HookContext) { + return STATUS_INVALID_PARAMETER_1; + } + + ApiPageAddress = HookContext->OriginalApiAddress; + HookLength = sizeof(BasicHookTemplate); + + Status = NtProtectVirtualMemory( + NtCurrentProcess(), + &ApiPageAddress, + &HookLength, + PAGE_READWRITE, + &OldProtect); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + return Status; + } + + RtlCopyMemory( + HookContext->OriginalApiAddress, + HookContext->OriginalInstructions, + sizeof(BasicHookTemplate)); + + Status = NtProtectVirtualMemory( + NtCurrentProcess(), + &ApiPageAddress, + &HookLength, + OldProtect, + &OldProtect); + + ASSERT (NT_SUCCESS(Status)); + + return STATUS_SUCCESS; +} \ No newline at end of file diff --git a/KexDll/kexldr.c b/KexDll/kexldr.c new file mode 100644 index 0000000..73d6885 --- /dev/null +++ b/KexDll/kexldr.c @@ -0,0 +1,766 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// kexldr.c +// +// Abstract: +// +// Functions for dealing with PE images and the loader subsystem. +// +// Author: +// +// vxiiduu (06-Nov-2022) +// +// Revision History: +// +// vxiiduu 06-Nov-2022 Initial creation. +// vxiiduu 06-Nov-2022 Rework KexLdrGetDllFullNameFromAddress +// vxiiduu 22-Feb-2024 Add some asserts. +// vxiiduu 27-Feb-2024 Improve efficiency of routines which +// find NTDLL base addresses. +// vxiiduu 29-Feb-2024 Revert previous change (wrong assumption). +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kexdllp.h" + +// +// Compatible with Win8. +// In Windows 8, this function forms the basis of GetModuleFileName, +// whereas in Win7 and before, the scanning of the loader data table +// is done directly in kernelbase.dll (or kernel32.dll). +// +NTSTATUS NTAPI KexLdrGetDllFullName( + IN PVOID DllBase OPTIONAL, + OUT PUNICODE_STRING DllFullPath) +{ + PUNICODE_STRING FullPath; + + if (DllBase) { + PLDR_DATA_TABLE_ENTRY Entry; + + if (!LdrpFindLoadedDllByHandle(DllBase, &Entry)) { + return STATUS_DLL_NOT_FOUND; + } + + FullPath = &Entry->FullDllName; + } else { + FullPath = &NtCurrentPeb()->ProcessParameters->ImagePathName; + } + + if (FullPath) { + RtlCopyUnicodeString(DllFullPath, FullPath); + } else { + DllFullPath->Length = 0; + } + + if (FullPath->Length > DllFullPath->MaximumLength) { + // should technically be STATUS_BUFFER_OVERFLOW because at this + // point we've already written the data, but go complain to the + // win8 devs. + return STATUS_BUFFER_TOO_SMALL; + } + + return STATUS_SUCCESS; +} + +// +// This function matches for any address inside the DLL instead of +// only its base address. It is therefore less efficient than using +// KexLdrGetDllFullName, but required for e.g. figuring out which +// DLL a function call comes from. +// +NTSTATUS NTAPI KexLdrGetDllFullNameFromAddress( + IN PVOID Address, + OUT PUNICODE_STRING DllFullPath) +{ + NTSTATUS Status; + PLDR_DATA_TABLE_ENTRY Entry; + + if (!Address || !DllFullPath) { + return STATUS_INVALID_PARAMETER; + } + + Status = LdrFindEntryForAddress(Address, &Entry); + if (!NT_SUCCESS(Status)) { + return Status; + } + + if (Entry->FullDllName.Length > DllFullPath->MaximumLength) { + return STATUS_BUFFER_TOO_SMALL; + } + + RtlCopyUnicodeString(DllFullPath, &Entry->FullDllName); + return STATUS_SUCCESS; +} + +// +// Find location of a DLL's init routine (i.e. DllMain). +// +NTSTATUS NTAPI KexLdrFindDllInitRoutine( + IN PVOID DllBase, + OUT PPVOID InitRoutine) +{ + PIMAGE_NT_HEADERS NtHeaders; + + ASSERT (DllBase != NULL); + ASSERT (InitRoutine != NULL); + + if (!DllBase || !InitRoutine) { + return STATUS_INVALID_PARAMETER; + } + + *InitRoutine = NULL; + + NtHeaders = RtlImageNtHeader(DllBase); + ASSERT (NtHeaders != NULL); + + if (!NtHeaders) { + return STATUS_INVALID_IMAGE_FORMAT; + } + + if (NtHeaders->OptionalHeader.AddressOfEntryPoint == 0) { + return STATUS_ENTRYPOINT_NOT_FOUND; + } + + *InitRoutine = RVA_TO_VA(DllBase, NtHeaders->OptionalHeader.AddressOfEntryPoint); + return STATUS_SUCCESS; +} + +// +// Main reason for using this is to: +// - get proc address in DLLs mapped but not registered with loader +// - get proc address in "wrong" bitness dlls (e.g. native ntdll.dll from +// wow64 process or vice versa) +// +// However, for DLLs registered with loader, this function is not useful +// as it is far slower than LdrGetProcedureAddress. +// +NTSTATUS NTAPI KexLdrMiniGetProcedureAddress( + IN PVOID DllBase, + IN PCSTR ProcedureName, + OUT PPVOID ProcedureAddress) +{ + PIMAGE_EXPORT_DIRECTORY ExportDirectory; + ULONG ExportDirectorySize; + PULONG NameRvas; + PULONG FunctionRvas; + PUSHORT NameOrdinals; + ULONG Index; + + ASSERT (DllBase != NULL); + ASSERT (ProcedureName != NULL); + ASSERT (ProcedureAddress != NULL); + + if (!DllBase || !ProcedureName || !ProcedureAddress) { + return STATUS_INVALID_PARAMETER; + } + + *ProcedureAddress = NULL; + + ExportDirectory = (PIMAGE_EXPORT_DIRECTORY) RtlImageDirectoryEntryToData( + DllBase, + TRUE, + IMAGE_DIRECTORY_ENTRY_EXPORT, + &ExportDirectorySize); + + ASSERT (ExportDirectory != NULL); + + if (!ExportDirectory) { + return STATUS_INVALID_IMAGE_FORMAT; + } + + NameRvas = (PULONG) RVA_TO_VA(DllBase, ExportDirectory->AddressOfNames); + FunctionRvas = (PULONG) RVA_TO_VA(DllBase, ExportDirectory->AddressOfFunctions); + NameOrdinals = (PUSHORT) RVA_TO_VA(DllBase, ExportDirectory->AddressOfNameOrdinals); + + for (Index = 0; Index < ExportDirectory->NumberOfNames; ++Index) { + PCSTR CurrentProcedureName; + + CurrentProcedureName = (PCSTR) RVA_TO_VA(DllBase, NameRvas[Index]); + + if (StringEqualA(ProcedureName, CurrentProcedureName)) { + *ProcedureAddress = RVA_TO_VA(DllBase, FunctionRvas[NameOrdinals[Index]]); + return STATUS_SUCCESS; + } + } + + return STATUS_ENTRYPOINT_NOT_FOUND; +} + +// +// Get the base address of NTDLL. +// +KEXAPI PVOID NTAPI KexLdrGetSystemDllBase( + VOID) +{ + NTSTATUS Status; + UNICODE_STRING NtdllBaseName; + PVOID NtdllBaseAddress; + + RtlInitConstantUnicodeString(&NtdllBaseName, L"ntdll.dll"); + + Status = LdrGetDllHandleByName(&NtdllBaseName, NULL, &NtdllBaseAddress); + ASSERT (NT_SUCCESS(Status)); + + if (NT_SUCCESS(Status)) { + return NtdllBaseAddress; + } else { + return NULL; + } +} + +// +// Get the base address of NTDLL for another process. +// This function returns the address of 32-bit NTDLL for a +// 32-bit process, and 64-bit NTDLL for a 64-bit process. +// +KEXAPI PVOID NTAPI KexLdrGetRemoteSystemDllBase( + IN HANDLE ProcessHandle) +{ + NTSTATUS Status; + UNICODE_STRING NtdllPathFragment; + UNICODE_STRING NtdllBaseName; + ULONG_PTR NtdllBaseAddress; + PUNICODE_STRING MappedFileNameInformation; + ULONG MappedFileNameLength; + ULONG RemoteProcessBitness; + + RtlInitConstantUnicodeString(&NtdllBaseName, L"ntdll.dll"); + + RemoteProcessBitness = KexRtlRemoteProcessBitness(ProcessHandle); + + // + // We can avoid scanning for NTDLL if we are the same bitness as the + // remote process, or if we are a WOW64 process + // + + if (KexRtlCurrentProcessBitness() == RemoteProcessBitness) { + ASSERT (KexData->SystemDllBase != NULL); + + return KexData->SystemDllBase; + } else if (KexRtlCurrentProcessBitness() != KexRtlOperatingSystemBitness()) { + ASSERT (KexRtlCurrentProcessBitness() == 32); + ASSERT (RemoteProcessBitness == 64); + ASSERT (KexData->NativeSystemDllBase != NULL); + + return KexData->NativeSystemDllBase; + } + + // + // We must search for NTDLL if we are a 64 bit process looking for the + // WOW64 NTDLL. + // + + ASSUME (KexRtlCurrentProcessBitness() == 64); + ASSUME (KexRtlOperatingSystemBitness() == 64); + ASSUME (RemoteProcessBitness == 32); + + MappedFileNameLength = 256; + MappedFileNameInformation = (PUNICODE_STRING) StackAlloc(BYTE, MappedFileNameLength); + + RtlInitConstantUnicodeString(&NtdllPathFragment, L"syswow64\\ntdll.dll"); + + for (NtdllBaseAddress = 0x7FFD0000; NtdllBaseAddress >= 0x70000000; NtdllBaseAddress -= 0x10000) { + MEMORY_BASIC_INFORMATION BasicInformation; + + Status = NtQueryVirtualMemory( + ProcessHandle, + (PVOID) NtdllBaseAddress, + MemoryMappedFilenameInformation, + MappedFileNameInformation, + MappedFileNameLength, + NULL); + + if (!NT_SUCCESS(Status)) { + continue; + } + + KexLogDebugEvent( + L"Found mapped file in remote process: %wZ", + MappedFileNameInformation); + + // + // Check if this memory-mapped image is NTDLL. + // + + if (!KexRtlUnicodeStringEndsWith(MappedFileNameInformation, &NtdllPathFragment, TRUE)) { + continue; + } + + // + // We will now confirm that this file is an image, and find + // the base address of this image file. + // + + Status = NtQueryVirtualMemory( + ProcessHandle, + (PVOID) NtdllBaseAddress, + MemoryBasicInformation, + &BasicInformation, + sizeof(BasicInformation), + NULL); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + continue; + } + + if (BasicInformation.Type != MEM_IMAGE) { + continue; + } + + NtdllBaseAddress = (ULONG_PTR) BasicInformation.AllocationBase; + + return (PVOID) NtdllBaseAddress; + } + + // + // Could not find. + // + + ASSERT (FALSE); + return NULL; +} + +// +// Get the base address of the native NTDLL. In other words: +// if this is a 32-bit process running on a 64-bit operating +// system, get the 64-bit NTDLL, and so on. +// +KEXAPI PVOID NTAPI KexLdrGetNativeSystemDllBase( + VOID) +{ + NTSTATUS Status; + UNICODE_STRING NtdllPathFragment; + UNICODE_STRING NtdllBaseName; + ULONG_PTR NtdllBaseAddress; + PUNICODE_STRING MappedFileNameInformation; + ULONG MappedFileNameLength; + + // + // 64-bit NTDLL is mapped between 0x7FFD0000 and 0x70000000 on + // boundaries of 0x10000 (due to ASLR). This gives us 256 + // possibilities we need to search for. To avoid this penalty, + // we will avoid performing the search if we could just get + // NTDLL's base address from the loader subsystem. + // + + RtlInitConstantUnicodeString(&NtdllBaseName, L"ntdll.dll"); + + if (KexRtlCurrentProcessBitness() == KexRtlOperatingSystemBitness()) { + Status = LdrGetDllHandleByName(&NtdllBaseName, NULL, (PPVOID) &NtdllBaseAddress); + ASSERT (NT_SUCCESS(Status)); + return (PVOID) NtdllBaseAddress; + } + + ASSUME (KexRtlCurrentProcessBitness() == 32); + ASSUME (KexRtlOperatingSystemBitness() == 64); + + // + // This is a 32-bit process running on a 64-bit operating system. We must + // search for the 64-bit NTDLL as described. + // + + MappedFileNameLength = 256; + MappedFileNameInformation = (PUNICODE_STRING) StackAlloc(BYTE, MappedFileNameLength); + RtlInitConstantUnicodeString(&NtdllPathFragment, L"system32\\ntdll.dll"); + + for (NtdllBaseAddress = 0x7FFD0000; NtdllBaseAddress >= 0x70000000; NtdllBaseAddress -= 0x10000) { + MEMORY_BASIC_INFORMATION BasicInformation; + + Status = NtQueryVirtualMemory( + NtCurrentProcess(), + (PVOID) NtdllBaseAddress, + MemoryMappedFilenameInformation, + MappedFileNameInformation, + MappedFileNameLength, + NULL); + + if (!NT_SUCCESS(Status)) { + continue; + } + + // + // Confirm that this memory-mapped image is in fact the native + // NTDLL inside the system32 directory. + // + + if (!KexRtlUnicodeStringEndsWith(MappedFileNameInformation, &NtdllPathFragment, TRUE)) { + continue; + } + + // + // We now have a pointer to a memory mapped file. + // We will now determine whether this file is an image, and also + // the base address of this image file. + // + + Status = NtQueryVirtualMemory( + NtCurrentProcess(), + (PVOID) NtdllBaseAddress, + MemoryBasicInformation, + &BasicInformation, + sizeof(BasicInformation), + NULL); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + continue; + } + + if (BasicInformation.Type != MEM_IMAGE) { + continue; + } + + NtdllBaseAddress = (ULONG_PTR) BasicInformation.AllocationBase; + return (PVOID) NtdllBaseAddress; + } + + // + // Could not find. + // + + ASSERT (FALSE); + return NULL; +} + +// +// This function changes the page protections on the entire section which +// contains the import directory. +// + +KEXAPI NTSTATUS NTAPI KexLdrProtectImageImportSection( + IN PVOID ImageBase, + IN ULONG PageProtection, + OUT PULONG OldProtection) +{ + NTSTATUS Status; + PIMAGE_NT_HEADERS NtHeaders; + PIMAGE_FILE_HEADER CoffHeader; + PIMAGE_OPTIONAL_HEADER OptionalHeader; + PIMAGE_DATA_DIRECTORY ImportDirectory; + PIMAGE_SECTION_HEADER ImportSectionHeader; + PVOID ImportSectionAddress; + SIZE_T ImportSectionSize; + + ASSERT (ImageBase != NULL); + ASSERT (OldProtection != NULL); + + Status = RtlImageNtHeaderEx( + RTL_IMAGE_NT_HEADER_EX_FLAG_NO_RANGE_CHECK, + ImageBase, + 0, + &NtHeaders); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + KexLogErrorEvent( + L"Failed to retrieve the address of the image NT headers for the " + L"image at base: 0x%p\r\n\r\n" + L"NTSTATUS error code: %s", + ImageBase, + KexRtlNtStatusToString(Status)); + + return Status; + } + + CoffHeader = &NtHeaders->FileHeader; + OptionalHeader = &NtHeaders->OptionalHeader; + ImportDirectory = &OptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; + + // + // Find the section that contains the import directory. + // + + ImportSectionHeader = KexRtlSectionTableFromRva( + NtHeaders, + ImportDirectory->VirtualAddress); + + if (!ImportSectionHeader) { + return STATUS_IMAGE_SECTION_NOT_FOUND; + } + + ImportSectionAddress = RVA_TO_VA(ImageBase, ImportSectionHeader->VirtualAddress); + ImportSectionSize = ImportSectionHeader->Misc.VirtualSize; + + ASSERT (ImportSectionAddress != ImageBase); + ASSERT (ImportSectionSize != 0); + + // + // Set our page protections. + // + + Status = NtProtectVirtualMemory( + NtCurrentProcess(), + &ImportSectionAddress, + &ImportSectionSize, + PageProtection, + OldProtection); + + ASSERT (NT_SUCCESS(Status)); + + return Status; +} + +// +// DllPath is a string containing semicolon-separated Win32 directory paths (similar +// to the PATH environment variable). +// DllName is a Win32 path. +// +// DllCharacteristics can be a combination of the following: +// +// DLL_CHARACTERISTIC_IGNORE_CODE_AUTHZ_LEVEL - equivalent to LOAD_IGNORE_CODE_AUTHZ_LEVEL +// DLL_CHARACTERISTIC_LOAD_AS_DATA - equivalent to DONT_RESOLVE_DLL_REFERENCES +// DLL_CHARACTERISTIC_REQUIRE_SIGNATURE - equivalent to LOAD_LIBRARY_REQUIRE_SIGNED_TARGET +// +KEXAPI NTSTATUS NTAPI KexLdrLoadDll( + IN PCWSTR DllPath OPTIONAL, + IN PULONG DllCharacteristicsIndirect OPTIONAL, + IN PCUNICODE_STRING DllName, + OUT PPVOID DllHandle) +{ + NTSTATUS Status; + PCWSTR OriginalDllPath; + ULONG DllCharacteristics; + UNICODE_STRING RewrittenDll; + + ASSERT (VALID_UNICODE_STRING(DllName)); + ASSERT (DllHandle != NULL); + + OriginalDllPath = DllPath; + DllCharacteristics = DllCharacteristicsIndirect ? *DllCharacteristicsIndirect : 0; + + // + // Very weird shit going on here, not sure why this is needed, but it is. + // This stuff was added in an update after Win7 SP1. If the least significant + // bit of DllPath is set, that means DllPath is actually a pointer to an array + // of 2 PCWSTRs. The first one is the regular DLL path and the 2nd one is an + // alternate path. + // + + if (DllPath && (((ULONG_PTR) DllPath) & 1)) { + ULONG_PTR DllPathPointer; + PPCWSTR DllPathIndirect; + + DllPathPointer = (ULONG_PTR) DllPath; + DllPathPointer &= ~1; + DllPathIndirect = (PPCWSTR) DllPathPointer; + DllPath = *DllPathIndirect; + } + + if (!NtCurrentTeb()->KexLdrShouldRewriteDll) { + // KxBase has not asked us to rewrite DLL names, so we won't. + goto BailOut; + } + + if (DllCharacteristics & DLL_CHARACTERISTIC_LOAD_AS_DATA) { + // They are probably trying to get resources or something out of + // the DLL. + goto BailOut; + } + + // + // Try to rewrite the DLL name or path. + // + + RtlInitEmptyUnicodeStringFromTeb(&RewrittenDll); + + Status = KexRewriteDllPath(DllName, &RewrittenDll); + + ASSERT (NT_SUCCESS(Status) || + Status == STATUS_STRING_MAPPER_ENTRY_NOT_FOUND || + Status == STATUS_DLL_NOT_IN_SYSTEM_ROOT); + + if (!NT_SUCCESS(Status)) { + goto BailOut; + } + + // + // We've successfully rewritten the DLL name. + // Set the DLL search path to the default (NULL). + // Remove any problematic DLL characteristics. + // + + DllName = &RewrittenDll; + DllPath = NULL; + DllCharacteristics &= ~DLL_CHARACTERISTIC_REQUIRE_SIGNATURE; + DllCharacteristicsIndirect = &DllCharacteristics; + +BailOut: + if (DllPath) { + PWSTR NewDllPathBuffer; + SIZE_T NewDllPathCch; + UNICODE_STRING NewDllPath; + + // + // Prepend Kex3264Dir in front of the original DLL path. + // + + NewDllPathCch = wcslen(DllPath) + KexRtlUnicodeStringCch(&KexData->Kex3264DirPath) + 1; + NewDllPathBuffer = StackAlloc(WCHAR, NewDllPathCch); + RtlInitEmptyUnicodeString(&NewDllPath, NewDllPathBuffer, NewDllPathCch * sizeof(WCHAR)); + + RtlCopyUnicodeString(&NewDllPath, &KexData->Kex3264DirPath); + RtlAppendUnicodeToString(&NewDllPath, DllPath); + + KexRtlNullTerminateUnicodeString(&NewDllPath); + DllPath = NewDllPath.Buffer; + + ASSERT (((ULONG_PTR) DllPath & 1) == 0); + } + + Status = LdrLoadDll( + DllPath, + DllCharacteristicsIndirect, + DllName, + DllHandle); + + if (!NT_SUCCESS(Status)) { + KexLogWarningEvent( + L"Failed to dynamically load %wZ.\r\n\r\n" + L"DllPath: \"%s\"\r\n" + L"DllCharacteristics: 0x%08lx\r\n" + L"NTSTATUS error code: %s (0x%08lx)", + DllName, + DllPath, + DllCharacteristics, + KexRtlNtStatusToString(Status), Status); + } + + return Status; +} + +KEXAPI NTSTATUS NTAPI KexLdrGetDllHandleEx( + IN ULONG Flags, + IN PCWSTR DllPath OPTIONAL, + IN PULONG DllCharacteristics OPTIONAL, + IN PCUNICODE_STRING DllName, + OUT PPVOID DllHandle) +{ + NTSTATUS Status; + UNICODE_STRING RewrittenDll; + + if (!NtCurrentTeb()->KexLdrShouldRewriteDll) { + goto BailOut; + } + + // + // Try to rewrite DLL. + // + + RtlInitEmptyUnicodeStringFromTeb(&RewrittenDll); + + Status = KexRewriteDllPath(DllName, &RewrittenDll); + + ASSERT (NT_SUCCESS(Status) || + Status == STATUS_STRING_MAPPER_ENTRY_NOT_FOUND || + Status == STATUS_DLL_NOT_IN_SYSTEM_ROOT); + + if (!NT_SUCCESS(Status)) { + goto BailOut; + } + + // + // The DLL was rewritten. + // + + DllPath = NULL; + DllCharacteristics = NULL; + DllName = &RewrittenDll; + +BailOut: + return LdrGetDllHandleEx( + Flags, + DllPath, + DllCharacteristics, + DllName, + DllHandle); +} + +KEXAPI NTSTATUS NTAPI KexLdrGetDllHandle( + IN PCWSTR DllPath OPTIONAL, + IN PULONG DllCharacteristics OPTIONAL, + IN PCUNICODE_STRING DllName, + OUT PPVOID DllHandle) +{ + return KexLdrGetDllHandleEx( + LDR_GET_DLL_HANDLE_EX_UNCHANGED_REFCOUNT, + DllPath, + DllCharacteristics, + DllName, + DllHandle); +} + +KEXAPI NTSTATUS NTAPI KexLdrGetProcedureAddressEx( + IN PVOID DllHandle, + IN PCANSI_STRING ProcedureName OPTIONAL, + IN ULONG ProcedureNumber OPTIONAL, + OUT PPVOID ProcedureAddress, + IN ULONG Flags) +{ + NTSTATUS Status; + + Status = LdrGetProcedureAddressEx( + DllHandle, + ProcedureName, + ProcedureNumber, + ProcedureAddress, + Flags); + + if (!NT_SUCCESS(Status)) { + NTSTATUS Status2; + UNICODE_STRING FullDllName; + UNICODE_STRING BaseDllName; + + RtlInitEmptyUnicodeStringFromTeb(&FullDllName); + Status2 = KexLdrGetDllFullName(DllHandle, &FullDllName); + ASSERT (NT_SUCCESS(Status2)); + + if (!NT_SUCCESS(Status2)) { + RtlInitConstantUnicodeString(&FullDllName, L"(unknown)"); + } + + Status2 = KexRtlPathFindFileName(&FullDllName, &BaseDllName); + ASSERT (NT_SUCCESS(Status2)); + + if (!NT_SUCCESS(Status2)) { + RtlInitConstantUnicodeString(&BaseDllName, L"(unknown)"); + } + + KexLogWarningEvent( + L"Failed to resolve %hZ (#%lu) from %wZ\r\n\r\n" + L"DLL base address: 0x%p\r\n" + L"Full path to the DLL: %wZ\r\n" + L"Flags: 0x%08lx\r\n" + L"NTSTATUS error code: %s (0x%08lx)", + ProcedureName, + ProcedureNumber, + &BaseDllName, + DllHandle, + &FullDllName, + Flags, + KexRtlNtStatusToString(Status), Status); + } + + return Status; +} + +KEXAPI NTSTATUS NTAPI KexLdrGetProcedureAddress( + IN PVOID DllHandle, + IN PCANSI_STRING ProcedureName OPTIONAL, + IN ULONG ProcedureNumber OPTIONAL, + OUT PPVOID ProcedureAddress) +{ + return KexLdrGetProcedureAddressEx( + DllHandle, + ProcedureName, + ProcedureNumber, + ProcedureAddress, + 0); +} \ No newline at end of file diff --git a/KexDll/kexrtl.c b/KexDll/kexrtl.c new file mode 100644 index 0000000..669b71a --- /dev/null +++ b/KexDll/kexrtl.c @@ -0,0 +1,966 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// kexrtl.c +// +// Abstract: +// +// Various useful run-time routines. +// +// Author: +// +// vxiiduu (17-Oct-2022) +// +// Revision History: +// +// vxiiduu 17-Oct-2022 Initial creation. +// vxiiduu 29-Oct-2022 Fix bug in KexRtlPathFindFileName +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kexdllp.h" + +// Examples: +// C:\Windows\system32\notepad.exe -> notepad.exe +// notepad.exe -> notepad.exe +// dir1\dir2\notepad.exe -> dir1\dir2\notepad.exe +// +// (As you can see, this function only works on FULL paths - otherwise, +// the output path is unchanged.) +// +// It's ok to specify the same pointer for Path and FileName, if you want to remove +// the file path in-place. +KEXAPI NTSTATUS NTAPI KexRtlPathFindFileName( + IN PCUNICODE_STRING Path, + OUT PUNICODE_STRING FileName) +{ + ULONG LengthWithoutLastElement; + + if (!Path) { + return STATUS_INVALID_PARAMETER_1; + } + + if (!FileName) { + return STATUS_INVALID_PARAMETER_2; + } + + // + // If Path->Buffer contains a path with no backslashes, this function + // will fail and set LengthWithoutLastElement to zero. This is desired + // and that's why the return value is not checked. + // + RtlGetLengthWithoutLastFullDosOrNtPathElement(0, Path, &LengthWithoutLastElement); + + FileName->Buffer = Path->Buffer + LengthWithoutLastElement; + FileName->Length = Path->Length - (USHORT) (LengthWithoutLastElement * sizeof(WCHAR)); + FileName->MaximumLength = Path->MaximumLength - (USHORT) (LengthWithoutLastElement * sizeof(WCHAR)); + + return STATUS_SUCCESS; +} + +// Examples: +// C:\Windows\system32\notepad.exe -> C:\Windows\system32\notepad +// C:\Users\bob.smith\Videos -> C:\Users\bob.smith\Videos +// C:\Users\bob.smith\ -> C:\Users\bob.smith\ +// C:\Users\bob.smith -> C:\Users\bob +// file.txt -> file +// file -> file +// file. -> file +// .file -> +// +// Returns STATUS_SUCCESS if the extension was successfully removed, +// or STATUS_NOT_FOUND if no extension was removed. + +KEXAPI NTSTATUS NTAPI KexRtlPathRemoveExtension( + IN PCUNICODE_STRING Path, + OUT PUNICODE_STRING PathWithoutExtension) +{ + NTSTATUS Status; + UNICODE_STRING Stops; + USHORT PrefixLength; + + if (!Path || !PathWithoutExtension || Path->Length == 0) { + return STATUS_INVALID_PARAMETER; + } + + *PathWithoutExtension = *Path; + + RtlInitConstantUnicodeString(&Stops, L".\\/"); + Status = RtlFindCharInUnicodeString( + RTL_FIND_CHAR_IN_UNICODE_STRING_START_AT_END, + PathWithoutExtension, + &Stops, + &PrefixLength); + + if (NT_SUCCESS(Status)) { + if (PathWithoutExtension->Buffer[PrefixLength / sizeof(WCHAR)] == '.') { + PathWithoutExtension->Length = PrefixLength; + } + } + + return Status; +} + +KEXAPI BOOLEAN NTAPI KexRtlPathReplaceIllegalCharacters( + IN OUT PUNICODE_STRING Path, + IN WCHAR ReplacementCharacter OPTIONAL, + IN BOOLEAN AllowPathSeparators) +{ + PWSTR PathBuffer; + PCWSTR PathEnd; + BOOLEAN AtLeastOneCharacterWasReplaced; + + ASSERT (Path != NULL); + ASSERT (Path->Length != 0); + ASSERT (Path->Buffer != NULL); + + if (!Path || !Path->Length || !Path->Buffer) { + return FALSE; + } + + if (!ReplacementCharacter) { + ReplacementCharacter = '_'; + } + + AtLeastOneCharacterWasReplaced = FALSE; + PathBuffer = Path->Buffer; + PathEnd = KexRtlEndOfUnicodeString(Path); + + until (PathBuffer == PathEnd) { + switch (*PathBuffer) { + case '<': + case '>': + case ':': + case '"': + case '|': + case '?': + case '*': + *PathBuffer = ReplacementCharacter; + AtLeastOneCharacterWasReplaced = TRUE; + break; + case '/': + case '\\': + unless (AllowPathSeparators) { + *PathBuffer = ReplacementCharacter; + AtLeastOneCharacterWasReplaced = TRUE; + } + break; + } + + PathBuffer++; + } + + return AtLeastOneCharacterWasReplaced; +} + +KEXAPI NTSTATUS NTAPI KexRtlGetProcessImageBaseName( + OUT PUNICODE_STRING FileName) +{ + return KexRtlPathFindFileName(&NtCurrentPeb()->ProcessParameters->ImagePathName, FileName); +} + +// +// NtQueryKeyValue is too annoying to use in everyday code, RtlQueryRegistryValues +// is unsafe, and RtlpNtQueryKeyValue only supports the default/unnamed key. So +// here is an API that essentially mimics the function of win32 RegGetValue. +// +// KeyHandle - Handle to an open registry key. +// +// ValueName - Name of the value to query. +// +// ValueDataCb - Points to size, in bytes, of the buffer indicated by ValueData. +// Upon successful return, contains the size of the data retrieved +// from the registry. +// If this value is 0 before the function is called, the function +// will return with STATUS_INSUFFICIENT_BUFFER, not check the +// ValueData parameter, and place the correct buffer size required +// to store the requested registry data in *ValueDataCb. +// +// ValueData - Buffer which holds the returned data. If NULL, the function will +// fail with STATUS_INVALID_PARAMETER (unless ValueDataCb is zero). +// +// ValueDataTypeRestrict - Indicates which data types are allowed to be returned. +// One or more flags from the REG_RESTRICT_* set can be +// passed. If the data type of the value in the registry +// does not match these filters, the function will return +// STATUS_OBJECT_TYPE_MISMATCH and *ValueDataType will +// contain the type of the registry data. +// +// ValueDataType - If function returns successfully, contains the data type of the +// data read from the registry. +// +// If this function returns with a failure code, the buffer pointed to by ValueData +// is unmodified. +// +KEXAPI NTSTATUS NTAPI KexRtlQueryKeyValueData( + IN HANDLE KeyHandle, + IN PCUNICODE_STRING ValueName, + IN OUT PULONG ValueDataCb, + OUT PVOID ValueData OPTIONAL, + IN ULONG ValueDataTypeRestrict, + OUT PULONG ValueDataType OPTIONAL) +{ + NTSTATUS Status; + PVOID KeyValueBuffer; + ULONG KeyValueBufferCb; + PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation; + + // + // Validate parameters. + // + if (!KeyHandle || KeyHandle == INVALID_HANDLE_VALUE) { + return STATUS_INVALID_PARAMETER_1; + } + + if (!ValueName) { + return STATUS_INVALID_PARAMETER_2; + } + + if (!ValueDataCb) { + return STATUS_INVALID_PARAMETER_3; + } + + if (ValueData != NULL && *ValueDataCb == 0) { + return STATUS_INVALID_PARAMETER_MIX; + } + + if (!ValueData && *ValueDataCb != 0) { + return STATUS_INVALID_PARAMETER_MIX; + } + + if (!ValueDataTypeRestrict || (ValueDataTypeRestrict & (~LEGAL_REG_RESTRICT_MASK))) { + return STATUS_INVALID_PARAMETER_5; + } + + // + // First of all, check if the caller just wants to know the length + // of buffer required. + // + + if (*ValueDataCb == 0) { + Status = NtQueryValueKey( + KeyHandle, + ValueName, + KeyValuePartialInformation, + NULL, + 0, + ValueDataCb); + + if (Status == STATUS_BUFFER_TOO_SMALL) { + *ValueDataCb -= sizeof(KEY_VALUE_PARTIAL_INFORMATION); + } + + return Status; + } + + // + // Now we allocate a buffer to store the KEY_VALUE_PARTIAL_INFORMATION + // structure in addition to any data read from the registry. + // + + KeyValueBufferCb = *ValueDataCb + sizeof(KEY_VALUE_PARTIAL_INFORMATION); + KeyValueBuffer = SafeAlloc(BYTE, KeyValueBufferCb); + + if (!KeyValueBuffer) { + return STATUS_NO_MEMORY; + } + + Status = NtQueryValueKey( + KeyHandle, + ValueName, + KeyValuePartialInformation, + KeyValueBuffer, + KeyValueBufferCb, + ValueDataCb); + + if (!NT_SUCCESS(Status)) { + goto Exit; + } + + *ValueDataCb -= sizeof(KEY_VALUE_PARTIAL_INFORMATION); + KeyValueInformation = (PKEY_VALUE_PARTIAL_INFORMATION) KeyValueBuffer; + + // + // Now, we check the data type of the returned value to make sure it + // is matched by the ValueDataTypeRestrict filter. + // + + unless (ValueDataTypeRestrict & (1 << KeyValueInformation->Type)) { + Status = STATUS_OBJECT_TYPE_MISMATCH; + goto Exit; + } + + // + // Copy the result into the caller's buffer. + // + + RtlCopyMemory(ValueData, KeyValueInformation->Data, KeyValueInformation->DataLength); + +Exit: + if (NT_SUCCESS(Status) || Status == STATUS_OBJECT_TYPE_MISMATCH) { + if (ValueDataType) { + *ValueDataType = KeyValueInformation->Type; + } + } + + SafeFree(KeyValueBuffer); + return Status; +} + +// +// Query multiple values of a key. +// +// KeyHandle +// Handle to an open registry key under which to query values. +// +// QueryTable +// Pointer to an array of KEX_RTL_QUERY_KEY_MULTIPLE_VARIABLE_TABLE_ENTRY +// structures which provide space to store input and output parameters to +// the KexRtlQueryKeyValueData routine. +// +// NumberOfQueryTableElements +// Pointer to number of elements in the array pointed to by QueryTable. +// Upon return, the number pointed to by this parameter contains the number +// of values successfully queried. +// +// Flags +// Valid "Flags" parameters start with QUERY_KEY_MULTIPLE_VALUE_: +// +// QUERY_KEY_MULTIPLE_VALUE_FAIL_FAST (1) +// Fail and return a failure code if one of the values in the query +// table cannot be queried. By default, on failure to query a value +// this function will simply record failure status inside the query +// table entry, continue to the next entry and return success once +// all values have been queried. +// +KEXAPI NTSTATUS NTAPI KexRtlQueryKeyMultipleValueData( + IN HANDLE KeyHandle, + IN PKEX_RTL_QUERY_KEY_MULTIPLE_VARIABLE_TABLE_ENTRY QueryTable, + IN OUT PULONG NumberOfQueryTableElements, + IN ULONG Flags) +{ + ULONG Counter; + + if (!QueryTable) { + return STATUS_INVALID_PARAMETER_2; + } + + if (!NumberOfQueryTableElements || *NumberOfQueryTableElements == 0) { + return STATUS_INVALID_PARAMETER_3; + } + + Counter = *NumberOfQueryTableElements; + *NumberOfQueryTableElements = 0; + + if (Flags & ~(QUERY_KEY_MULTIPLE_VALUE_FAIL_FAST)) { + return STATUS_INVALID_PARAMETER_4; + } + + do { + QueryTable->Status = KexRtlQueryKeyValueData( + KeyHandle, + &QueryTable->ValueName, + &QueryTable->ValueDataCb, + QueryTable->ValueData, + QueryTable->ValueDataTypeRestrict, + &QueryTable->ValueDataType); + + if (Flags & QUERY_KEY_MULTIPLE_VALUE_FAIL_FAST) { + if (!NT_SUCCESS(QueryTable->Status)) { + return STATUS_UNSUCCESSFUL; + } + } + + ++QueryTable; + ++*NumberOfQueryTableElements; + } while (--Counter); + + return STATUS_SUCCESS; +} + +// +// Check whether a string ends with another string. +// For example, you can use this to see if a filename has a particular +// extension. +// +KEXAPI BOOLEAN NTAPI KexRtlUnicodeStringEndsWith( + IN PCUNICODE_STRING String, + IN PCUNICODE_STRING EndsWith, + IN BOOLEAN CaseInsensitive) +{ + UNICODE_STRING EndOfString; + + // + // Create a subset of the String that just contains the + // end of it (with the number of characters that EndsWith + // contains). + // + + EndOfString.Buffer = String->Buffer + KexRtlUnicodeStringCch(String) - KexRtlUnicodeStringCch(EndsWith); + EndOfString.Length = EndsWith->Length; + EndOfString.MaximumLength = EndsWith->Length; + + if (EndOfString.Buffer < String->Buffer) { + // EndsWith length greater than String length + return FALSE; + } + + // + // Now perform the actual check. + // + + return RtlEqualUnicodeString(&EndOfString, EndsWith, CaseInsensitive); +} + +// +// Similar to RtlFindUnicodeSubstring in Win10 NTDLL (but does not +// respect NLS). +// Returns the address of the character in Haystack where Needle starts, +// or NULL if Needle could not be found. +// +KEXAPI PWCHAR NTAPI KexRtlFindUnicodeSubstring( + PCUNICODE_STRING Haystack, + PCUNICODE_STRING Needle, + BOOLEAN CaseInsensitive) +{ + ULONG LengthOfNeedle; + ULONG LengthOfHaystack; + PWCHAR NeedleBuffer; + PWCHAR NeedleBufferEnd; + PWCHAR HaystackBuffer; + PWCHAR HaystackBufferEnd; + PWCHAR HaystackBufferRealEnd; + PWCHAR StartOfNeedleInHaystack; + WCHAR NeedleFirst; + + LengthOfNeedle = Needle->Length & ~1; + LengthOfHaystack = Haystack->Length & ~1; + + if (LengthOfNeedle > LengthOfHaystack || !LengthOfHaystack || !LengthOfNeedle) { + return NULL; + } + + NeedleBuffer = Needle->Buffer; + NeedleBufferEnd = (PWCHAR) (((PBYTE) NeedleBuffer) + LengthOfNeedle); + HaystackBuffer = Haystack->Buffer; + HaystackBufferEnd = (PWCHAR) (((PBYTE) HaystackBuffer) + LengthOfHaystack - LengthOfNeedle); + HaystackBufferRealEnd = (PWCHAR) (((PBYTE) HaystackBufferEnd) + LengthOfNeedle); + + if (CaseInsensitive) { + NeedleFirst = ToUpper(*NeedleBuffer); + + while (TRUE) { + NeedleBuffer = Needle->Buffer + 1; + + while (ToUpper(*HaystackBuffer) != NeedleFirst) { + ++HaystackBuffer; // Multiple evaluation. Can't increment inside macro + + if (HaystackBuffer > HaystackBufferEnd) { + return NULL; + } + } + + StartOfNeedleInHaystack = HaystackBuffer++; + + while (ToUpper(*HaystackBuffer) == ToUpper(*NeedleBuffer)) { + ++HaystackBuffer; + ++NeedleBuffer; + + if (HaystackBuffer > HaystackBufferRealEnd) { + break; + } else if (NeedleBuffer >= NeedleBufferEnd) { + return StartOfNeedleInHaystack; + } + } + } + } else { + NeedleFirst = *NeedleBuffer; + + while (TRUE) { + NeedleBuffer = Needle->Buffer + 1; + + while (*HaystackBuffer++ != NeedleFirst) { + if (HaystackBuffer > HaystackBufferEnd) { + return NULL; + } + } + + StartOfNeedleInHaystack = HaystackBuffer - 1; + + while (*HaystackBuffer++ == *NeedleBuffer++) { + if (HaystackBuffer > HaystackBufferRealEnd) { + break; + } else if (NeedleBuffer >= NeedleBufferEnd) { + return StartOfNeedleInHaystack; + } + } + } + } +} + +KEXAPI VOID NTAPI KexRtlAdvanceUnicodeString( + OUT PUNICODE_STRING String, + IN USHORT AdvanceCb) +{ + String->Buffer += (AdvanceCb / sizeof(WCHAR)); + String->Length -= AdvanceCb; + String->MaximumLength -= AdvanceCb; +} + +KEXAPI VOID NTAPI KexRtlRetreatUnicodeString( + OUT PUNICODE_STRING String, + IN USHORT RetreatCb) +{ + String->Buffer -= (RetreatCb / sizeof(WCHAR)); + String->Length += RetreatCb; + String->MaximumLength += RetreatCb; +} + +KEXAPI NTSTATUS NTAPI KexRtlShiftUnicodeString( + IN OUT PUNICODE_STRING String, + IN USHORT ShiftCch, + IN WCHAR LeftFillCharacter OPTIONAL) +{ + USHORT ShiftCb; + NTSTATUS Status; + + if (!String || !ShiftCch) { + return STATUS_INVALID_PARAMETER; + } + + ShiftCb = ShiftCch * sizeof(WCHAR); + + if (ShiftCb > String->MaximumLength) { + return STATUS_BUFFER_TOO_SMALL; + } + + if (!LeftFillCharacter) { + LeftFillCharacter = ' '; + } + + Status = STATUS_SUCCESS; + + if (String->Length + ShiftCb > String->MaximumLength) { + String->Length = String->MaximumLength - ShiftCb; + Status = STATUS_BUFFER_OVERFLOW; + } + + RtlMoveMemory(String->Buffer + ShiftCch, String->Buffer, String->Length); + __stosw((PUSHORT) String->Buffer, LeftFillCharacter, ShiftCch); + String->Length += ShiftCb; + + return Status; +} + +KEXAPI ULONG NTAPI KexRtlRemoteProcessBitness( + IN HANDLE ProcessHandle) +{ + NTSTATUS Status; + ULONG_PTR Peb32; + + if (KexRtlOperatingSystemBitness() == 32) { + return 32; + } + + Status = NtQueryInformationProcess( + ProcessHandle, + ProcessWow64Information, + &Peb32, + sizeof(Peb32), + NULL); + + ASSERT (NT_SUCCESS(Status)); + + if (NT_SUCCESS(Status) && Peb32) { + return 32; + } else { + return 64; + } +} + +// +// This API will automatically change the memory protections for you +// and then set them back to what they originally were. +// +KEXAPI NTSTATUS NTAPI KexRtlWriteProcessMemory( + IN HANDLE ProcessHandle, + IN ULONG_PTR Destination, + IN PVOID Source, + IN SIZE_T Cb) +{ + PVOID DestinationPageAddress; + SIZE_T DestinationPageSize; + ULONG OldProtect; + NTSTATUS Status; + NTSTATUS Status2; + + DestinationPageAddress = (PVOID) Destination; + DestinationPageSize = Cb; + + // + // Note to future self: NtProtectVirtualMemory can return + // STATUS_CONFLICTING_ADDRESSES when the address specified in the remote + // process is not allocated. + // + + Status = NtProtectVirtualMemory( + ProcessHandle, + &DestinationPageAddress, + &DestinationPageSize, + PAGE_READWRITE, + &OldProtect); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + return Status; + } + + Status = NtWriteVirtualMemory( + ProcessHandle, + (PVOID) Destination, + Source, + Cb, + NULL); + + ASSERT (NT_SUCCESS(Status)); + + Status2 = NtProtectVirtualMemory( + ProcessHandle, + &DestinationPageAddress, + &DestinationPageSize, + OldProtect, + &OldProtect); + + ASSERT (NT_SUCCESS(Status2)); + + return Status; +} + +// +// Recursively create or open a directory. +// +KEXAPI NTSTATUS NTAPI KexRtlCreateDirectoryRecursive( + OUT PHANDLE DirectoryHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN ULONG ShareAccess) +{ + NTSTATUS Status; + IO_STATUS_BLOCK IoStatusBlock; + BOOLEAN AlreadyRetried; + + AlreadyRetried = FALSE; + + // + // Attempt to create the directory. + // + +Retry: + Status = NtCreateFile( + DirectoryHandle, + DesiredAccess | SYNCHRONIZE, + ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + ShareAccess, + FILE_OPEN_IF, + FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, + NULL, + 0); + + if (!NT_SUCCESS(Status) && !AlreadyRetried) { + HANDLE TemporaryHandle; + OBJECT_ATTRIBUTES NewObjectAttributes; + UNICODE_STRING ShorterPath; + ULONG NewLength; + + // + // If failed, chop off the last path element and try again. + // + + NewObjectAttributes = *ObjectAttributes; + ShorterPath = *ObjectAttributes->ObjectName; + NewObjectAttributes.ObjectName = &ShorterPath; + + if (!ShorterPath.Length) { + // + // Already chopped off all path elements, so that means the root + // of the path must not exist. + // + + return STATUS_OBJECT_PATH_NOT_FOUND; + } + + Status = RtlGetLengthWithoutLastFullDosOrNtPathElement( + 0, + &ShorterPath, + &NewLength); + + if (!NT_SUCCESS(Status)) { + return Status; + } + + NewLength *= sizeof(WCHAR); + ASSERT (NewLength < ShorterPath.Length); + + ShorterPath.Length = (USHORT) NewLength; + + Status = KexRtlCreateDirectoryRecursive( + &TemporaryHandle, + 0, + &NewObjectAttributes, + 0); + + if (NT_SUCCESS(Status)) { + // + // If we succeeded, now go back and retry creating the original + // directory again. + // + + NtClose(TemporaryHandle); + AlreadyRetried = TRUE; + goto Retry; + } + } + + return Status; +} + +// +// See ntdll!RtlSectionTableFromVirtualAddress for more info. +// It's a shame that function wasn't exported because I could've avoided +// rewriting a function that does the same thing. +// +// Returns a pointer to an IMAGE_SECTION_HEADER structure on success. +// Returns NULL on failure. +// +KEXAPI PIMAGE_SECTION_HEADER NTAPI KexRtlSectionTableFromRva( + IN PIMAGE_NT_HEADERS NtHeaders, + IN ULONG ImageRva) +{ + PIMAGE_SECTION_HEADER SectionHeader; + ULONG NumberOfSections; + ULONG SectionIndex; + ULONG SectionRva; + + SectionIndex = 0; + NumberOfSections = NtHeaders->FileHeader.NumberOfSections; + + if (NumberOfSections == 0) { + // There are no sections in the image. + return NULL; + } + + // + // The first section header in the section table starts at the byte + // directly after the optional header. + // + + SectionHeader = (PIMAGE_SECTION_HEADER) RVA_TO_VA( + &NtHeaders->OptionalHeader, + NtHeaders->FileHeader.SizeOfOptionalHeader); + + // + // Search through all the sections and find one that contains our RVA. + // + + while (SectionIndex < NumberOfSections) { + SectionRva = SectionHeader->VirtualAddress; + + if (ImageRva >= SectionRva && ImageRva < SectionRva + SectionHeader->SizeOfRawData) { + return SectionHeader; + } + + ++SectionIndex; + ++SectionHeader; + } + + // The section could not be found. + return NULL; +} + +// This function ensures that String->Buffer member is suitable for passing to +// functions that expect C-strings. +KEXAPI NTSTATUS NTAPI KexRtlNullTerminateUnicodeString( + IN PUNICODE_STRING String) +{ + if (!String || !String->Buffer) { + return STATUS_INVALID_PARAMETER; + } + + if (String->MaximumLength < String->Length) { + return STATUS_INVALID_PARAMETER; + } + + if (String->MaximumLength - String->Length < sizeof(WCHAR)) { + return STATUS_BUFFER_TOO_SMALL; + } + + *KexRtlEndOfUnicodeString(String) = '\0'; + return STATUS_SUCCESS; +} + +// Create an object directory which is accessible to untrusted processes. +KEXAPI NTSTATUS NTAPI KexRtlCreateUntrustedDirectoryObject( + OUT PHANDLE DirectoryHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes) +{ + NTSTATUS Status; + SECURITY_DESCRIPTOR SecurityDescriptor; + BYTE UntrustedSidBuffer[] = {1, 1, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0}; + BYTE SaclBuffer[sizeof(UntrustedSidBuffer) + sizeof(ACL) + sizeof(ACE_HEADER) + sizeof(ACCESS_MASK)]; + PSID UntrustedSid; + PACL Sacl; + + ASSERT (DirectoryHandle != NULL); + ASSERT (ObjectAttributes != NULL); + ASSERT (ObjectAttributes->SecurityDescriptor == NULL); + + UntrustedSid = (PSID)UntrustedSidBuffer; + Sacl = (PACL) SaclBuffer; + + Status = RtlCreateAcl(Sacl, sizeof(SaclBuffer), ACL_REVISION); + ASSERT (NT_SUCCESS(Status)); + Status = RtlAddMandatoryAce(Sacl, ACL_REVISION, 0, UntrustedSid, SYSTEM_MANDATORY_LABEL_ACE_TYPE, 0); + ASSERT (NT_SUCCESS(Status)); + + Status = RtlCreateSecurityDescriptor(&SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION); + ASSERT (NT_SUCCESS(Status)); + Status = RtlSetDaclSecurityDescriptor(&SecurityDescriptor, TRUE, NULL, FALSE); + ASSERT (NT_SUCCESS(Status)); + Status = RtlSetSaclSecurityDescriptor(&SecurityDescriptor, TRUE, Sacl, FALSE); + ASSERT (NT_SUCCESS(Status)); + + ObjectAttributes->SecurityDescriptor = &SecurityDescriptor; + + Status = NtCreateDirectoryObject( + DirectoryHandle, + DesiredAccess, + ObjectAttributes); + + ObjectAttributes->SecurityDescriptor = NULL; + + return Status; +} + +// Compatible with RtlSetBit from win8+. +KEXAPI VOID NTAPI KexRtlSetBit( + IN PRTL_BITMAP BitmapHeader, + IN ULONG BitNumber) +{ + _bittestandset((PLONG) BitmapHeader->Buffer, BitNumber); +} + +// Compatible with RtlClearBit from win8+. +KEXAPI VOID NTAPI KexRtlClearBit( + IN PRTL_BITMAP BitmapHeader, + IN ULONG BitNumber) +{ + _bittestandreset((PLONG) BitmapHeader->Buffer, BitNumber); +} + +// +// Stubs. +// + +KEXAPI NTSTATUS NTAPI KexRtlQueryPackageIdentity( + IN PVOID TokenObject, + OUT PWSTR PackageFullName, + IN OUT PSIZE_T PackageSize, + OUT PWSTR AppId, + IN OUT PSIZE_T AppIdSize, + OUT PBOOLEAN Packaged) +{ + return STATUS_NOT_FOUND; +} + +KEXAPI NTSTATUS NTAPI KexRtlQueryPackageIdentityEx( + IN PVOID TokenObject, + OUT PWSTR PackageFullName, + IN OUT PSIZE_T PackageSize, + OUT PWSTR AppId, + IN OUT PSIZE_T AppIdSize, + OUT LPGUID DynamicId OPTIONAL, + OUT PULONG64 Flags) +{ + return STATUS_NOT_FOUND; +} + +KEXAPI NTSTATUS NTAPI KexRtlCheckPortableOperatingSystem( + OUT PBOOLEAN IsPortable) +{ + *IsPortable = FALSE; + return STATUS_SUCCESS; +} + +KEXAPI NTSTATUS NTAPI KexRtlUnsubscribeWnfStateChangeNotification( + IN PVOID Subscription) +{ + return STATUS_NOT_IMPLEMENTED; +} + +KEXAPI NTSTATUS NTAPI KexRtlQueryWnfStateData( + PULONG ChangeStamp, + ULONGLONG StateName, + PVOID Callback, + PVOID CallbackContext, + PULONG TypeId) +{ + return STATUS_NOT_IMPLEMENTED; +} + +KEXAPI NTSTATUS NTAPI KexRtlPublishWnfStateData( + ULONGLONG StateName, + PVOID TypeId, + PVOID StateData, + ULONG StateDataLength, + PCVOID ExplicitScope) +{ + return STATUS_NOT_IMPLEMENTED; +} + +KEXAPI NTSTATUS NTAPI KexRtlSubscribeWnfStateChangeNotification( + PVOID Subscription, + ULONGLONG StateName, + ULONG ChangeStamp, + PVOID Callback, + PVOID CallbackContext, + PVOID TypeId, + ULONG SerializationGroupIndex) +{ + return STATUS_NOT_IMPLEMENTED; +} + +#ifndef _M_X64 +typedef PVOID TYPEDEF_TYPE_NAME(RUNTIME_FUNCTION); +#endif + +KEXAPI NTSTATUS NTAPI KexRtlAddGrowableFunctionTable( + OUT PPVOID DynamicTable, + IN PRUNTIME_FUNCTION FunctionTable, + IN ULONG EntryCount, + IN ULONG MaximumEntryCount, + IN ULONG_PTR RangeBase, + IN ULONG_PTR RangeEnd) +{ +#ifdef _M_X64 + BOOLEAN Success; + + Success = RtlAddFunctionTable(FunctionTable, EntryCount, RangeBase); + + if (Success) { + *DynamicTable = NULL; + return STATUS_SUCCESS; + } else { + return STATUS_UNSUCCESSFUL; + } +#else + ASSERT (FALSE); + return STATUS_NOT_IMPLEMENTED; +#endif +} \ No newline at end of file diff --git a/KexDll/logging.c b/KexDll/logging.c new file mode 100644 index 0000000..850cb7c --- /dev/null +++ b/KexDll/logging.c @@ -0,0 +1,142 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// logging.c +// +// Abstract: +// +// Logging-related utility functions. +// +// Author: +// +// vxiiduu (23-Feb-2024) +// +// Environment: +// +// During initialization. +// +// Revision History: +// +// vxiiduu 23-Feb-2024 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kexdllp.h" + +NTSTATUS KexOpenVxlLogForCurrentApplication( + OUT PVXLHANDLE LogHandle) +{ + NTSTATUS Status; + UNICODE_STRING LogDir; + WCHAR LogFileBuffer[MAX_PATH]; + UNICODE_STRING LogFileName; + UNICODE_STRING SourceApplication; + HANDLE LogDirHandle; + OBJECT_ATTRIBUTES ObjectAttributes; + USHORT TemporaryLength; + + ASSERT (LogHandle != NULL); + ASSERT (KexData != NULL); + ASSERT (KexData->LogHandle == NULL); + + if (KexData->Flags & KEXDATA_FLAG_DISABLE_LOGGING) { + // Don't open a log file. + *LogHandle = NULL; + return STATUS_USER_DISABLED; + } + + Status = RtlDosPathNameToNtPathName_U_WithStatus( + KexData->LogDir.Buffer, + &LogDir, + NULL, + NULL); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + return Status; + } + + LogDirHandle = NULL; + + try { + // + // Open the root log directory. + // + + InitializeObjectAttributes( + &ObjectAttributes, + &LogDir, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + Status = KexRtlCreateDirectoryRecursive( + &LogDirHandle, + FILE_TRAVERSE, + &ObjectAttributes, + FILE_SHARE_READ | FILE_SHARE_WRITE); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + return Status; + } + + // + // Assemble the log file name. + // + + RtlInitEmptyUnicodeString(&LogFileName, LogFileBuffer, ARRAYSIZE(LogFileBuffer)); + RtlAppendUnicodeStringToString(&LogFileName, &KexData->ImageBaseName); + KexRtlPathRemoveExtension(&LogFileName, &LogFileName); + + // append system time, zero-padded to 20 characters for easy sorting + RtlAppendUnicodeToString(&LogFileName, L"-"); + TemporaryLength = LogFileName.Length; + KexRtlAdvanceUnicodeString(&LogFileName, TemporaryLength); + RtlInt64ToUnicodeString(*(PULONGLONG) &SharedUserData->SystemTime, 10, &LogFileName); + KexRtlShiftUnicodeString(&LogFileName, 20 - (LogFileName.Length / sizeof(WCHAR)), '0'); + KexRtlRetreatUnicodeString(&LogFileName, TemporaryLength); + + // Append process ID. This combats situations where 2 processes with same name are + // started at the same time. + RtlAppendUnicodeToString(&LogFileName, L"-"); + TemporaryLength = LogFileName.Length; + KexRtlAdvanceUnicodeString(&LogFileName, TemporaryLength); + RtlIntegerToUnicodeString((ULONG) NtCurrentTeb()->ClientId.UniqueProcess, 10, &LogFileName); + KexRtlRetreatUnicodeString(&LogFileName, TemporaryLength); + + RtlAppendUnicodeToString(&LogFileName, L".vxl"); + + // + // Open the log file. + // + + InitializeObjectAttributes( + &ObjectAttributes, + &LogFileName, + OBJ_CASE_INSENSITIVE, + LogDirHandle, + NULL); + + RtlInitConstantUnicodeString(&SourceApplication, L"VxKex"); + Status = VxlOpenLog( + LogHandle, + &SourceApplication, + &ObjectAttributes, + GENERIC_WRITE, + FILE_OVERWRITE_IF); + + // We can get STATUS_ACCESS_DENIED if running in a sandboxed Chromium process. + // This is normal and there's nothing wrong. + ASSERT (NT_SUCCESS(Status) || Status == STATUS_ACCESS_DENIED); + } finally { + RtlFreeUnicodeString(&LogDir); + SafeClose(LogDirHandle); + } + + return Status; +} \ No newline at end of file diff --git a/KexDll/ntjob.c b/KexDll/ntjob.c new file mode 100644 index 0000000..e0db5f2 --- /dev/null +++ b/KexDll/ntjob.c @@ -0,0 +1,25 @@ +#include "buildcfg.h" +#include "kexdllp.h" + +KEXAPI NTSTATUS NTAPI Ext_NtAssignProcessToJobObject( + IN HANDLE JobHandle, + IN HANDLE ProcessHandle) +{ + NTSTATUS Status; + + Status = KexNtAssignProcessToJobObject( + JobHandle, + ProcessHandle); + + // + // In some situations, Chromium can shit itself by trying to launch child + // processes over and over if it sees this fail. + // + + if (Status == STATUS_ACCESS_DENIED && (KexData->Flags & KEXDATA_FLAG_CHROMIUM)) { + KexLogDebugEvent(L"Faking NtAssignProcessToJobObject success for Chromium compatibility"); + Status = STATUS_SUCCESS; + } + + return Status; +} \ No newline at end of file diff --git a/KexDll/ntpriv.c b/KexDll/ntpriv.c new file mode 100644 index 0000000..6b4afc3 --- /dev/null +++ b/KexDll/ntpriv.c @@ -0,0 +1,86 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// ntpriv.c +// +// Abstract: +// +// Re-implementations of some small non-exported functions. +// Mostly based on decompilation of Win7. +// +// Author: +// +// vxiiduu (23-Oct-2022) +// +// Revision History: +// +// vxiiduu 23-Oct-2022 Initial creation. +// vxiiduu 06-Nov-2022 Add LdrpFindLoadedDllByHandle +// Remove incorrect comment (LdrpHeap is +// actually the same as the process heap) +// vxiiduu 08-Mar-2024 Add BaseGetNamedObjectDirectory. +// vxiiduu 11-Mar-2024 Move BaseGetNamedObjectDirectory to +// KxBase. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kexdllp.h" +#include + +PLDR_DATA_TABLE_ENTRY NTAPI LdrpAllocateDataTableEntry( + IN PVOID DllBase) +{ + PLDR_DATA_TABLE_ENTRY Entry; + PIMAGE_NT_HEADERS NtHeaders; + + NtHeaders = RtlImageNtHeader(DllBase); + if (!NtHeaders) { + return NULL; + } + + Entry = SafeAlloc(LDR_DATA_TABLE_ENTRY, 1); + if (!Entry) { + return NULL; + } + + RtlZeroMemory(Entry, sizeof(*Entry)); + + Entry->DllBase = DllBase; + Entry->SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage; + Entry->TimeDateStamp = NtHeaders->FileHeader.TimeDateStamp; + Entry->PatchInformation = NULL; + + InitializeListHead(&Entry->ForwarderLinks); + InitializeListHead(&Entry->ServiceTagLinks); + InitializeListHead(&Entry->StaticLinks); + + return Entry; +} + +BOOLEAN NTAPI LdrpFindLoadedDllByHandle( + IN PVOID DllHandle, + OUT PPLDR_DATA_TABLE_ENTRY DataTableEntry) +{ + PLDR_DATA_TABLE_ENTRY Entry; + PPEB_LDR_DATA PebLdr; + + PebLdr = NtCurrentPeb()->Ldr; + Entry = (PLDR_DATA_TABLE_ENTRY) PebLdr->InLoadOrderModuleList.Flink; + + if (IsListEmpty(&PebLdr->InLoadOrderModuleList)) { + return FALSE; + } + + while (Entry->DllBase != DllHandle || !Entry->InMemoryOrderLinks.Flink) { + Entry = (PLDR_DATA_TABLE_ENTRY) Entry->InLoadOrderLinks.Flink; + + if ((PLIST_ENTRY) Entry == &PebLdr->InLoadOrderModuleList) { + return FALSE; + } + } + + *DataTableEntry = Entry; + return TRUE; +} \ No newline at end of file diff --git a/KexDll/ntps.c b/KexDll/ntps.c new file mode 100644 index 0000000..3a58e1d --- /dev/null +++ b/KexDll/ntps.c @@ -0,0 +1,28 @@ +#include "buildcfg.h" +#include "kexdllp.h" + +NTSTATUS NTAPI Ext_NtQueryInformationProcess( + IN HANDLE ProcessHandle, + IN PROCESSINFOCLASS ProcessInformationClass, + OUT PVOID ProcessInformation, + IN ULONG ProcessInformationLength, + OUT PULONG ReturnLength OPTIONAL) +{ + // TODO + if (ProcessInformationClass == 58) { + KexLogWarningEvent(L"ProcessInformationClass == 58"); + KexDebugCheckpoint(); + } + + if (ProcessInformationClass >= 51) { + KexLogWarningEvent(L"ProcessInformationClass >= 51"); + KexDebugCheckpoint(); + } + + return KexNtQueryInformationProcess( + ProcessHandle, + ProcessInformationClass, + ProcessInformation, + ProcessInformationLength, + ReturnLength); +} \ No newline at end of file diff --git a/KexDll/ntreg.c b/KexDll/ntreg.c new file mode 100644 index 0000000..d0373bf --- /dev/null +++ b/KexDll/ntreg.c @@ -0,0 +1,78 @@ +#include "buildcfg.h" +#include "kexdllp.h" + +#define REG_NOTIFY_THREAD_AGNOSTIC 0x10000000 + +NTSTATUS NTAPI Ext_NtNotifyChangeMultipleKeys( + IN HANDLE MasterKeyHandle, + IN ULONG Count OPTIONAL, + IN OBJECT_ATTRIBUTES SlaveObjects[] OPTIONAL, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN ULONG CompletionFilter, + IN BOOLEAN WatchTree, + OUT PVOID Buffer OPTIONAL, + IN ULONG BufferSize, + IN BOOLEAN Asynchronous) +{ + // + // If CompletionFilter contains REG_NOTIFY_THREAD_AGNOSTIC, simply + // strip it out. + // TODO: Implement this properly. + // + + if (CompletionFilter & REG_NOTIFY_THREAD_AGNOSTIC) { + KexLogDebugEvent(L"Stripping REG_NOTIFY_THREAD_AGNOSTIC flag from CompletionFilter"); + } + + CompletionFilter &= ~REG_NOTIFY_THREAD_AGNOSTIC; + + return KexNtNotifyChangeMultipleKeys( + MasterKeyHandle, + Count, + SlaveObjects, + Event, + ApcRoutine, + ApcContext, + IoStatusBlock, + CompletionFilter, + WatchTree, + Buffer, + BufferSize, + Asynchronous); +} + +NTSTATUS NTAPI Ext_NtNotifyChangeKey( + IN HANDLE KeyHandle, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN ULONG CompletionFilter, + IN BOOLEAN WatchTree, + OUT PVOID Buffer OPTIONAL, + IN ULONG BufferSize, + IN BOOLEAN Asynchronous) +{ + // + // Pass through to NtNotifyChangeMultipleKeys to avoid code duplication. + // This is how the NtNotifyChangeKey function is implemented in the kernel anyway, + // so there should be no issues in doing this. + // + + return Ext_NtNotifyChangeMultipleKeys( + KeyHandle, + 0, + NULL, + Event, + ApcRoutine, + ApcContext, + IoStatusBlock, + CompletionFilter, + WatchTree, + Buffer, + BufferSize, + Asynchronous); +} \ No newline at end of file diff --git a/KexDll/ntsect.c b/KexDll/ntsect.c new file mode 100644 index 0000000..0b5c349 --- /dev/null +++ b/KexDll/ntsect.c @@ -0,0 +1,124 @@ +#include "buildcfg.h" +#include "kexdllp.h" + +// Windows 8+ flag which is invalid on Win7. +#define SEC_IMAGE_NO_EXECUTE (SEC_IMAGE | SEC_NOCACHE) + +NTSTATUS NTAPI Ext_NtCreateSection( + OUT PHANDLE SectionHandle, + IN ULONG DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, + IN PLONGLONG MaximumSize OPTIONAL, + IN ULONG PageAttributes, + IN ULONG SectionAttributes, + IN HANDLE FileHandle OPTIONAL) PROTECTED_FUNCTION +{ + NTSTATUS Status; + BOOLEAN HaveRenamedObject; + BOOLEAN NonDuplicableHandle; + POBJECT_ATTRIBUTES OriginalObjectAttributes; + OBJECT_ATTRIBUTES NewObjectAttributes; + UNICODE_STRING NewObjectName; + + NonDuplicableHandle = FALSE; + HaveRenamedObject = FALSE; + + if ((SectionAttributes & SEC_IMAGE_NO_EXECUTE) == SEC_IMAGE_NO_EXECUTE) { + // + // SEC_IMAGE_NO_EXECUTE is a combination of SEC_IMAGE and SEC_NOCACHE. + // This combination is invalid on Win7, so we will remove SEC_NOCACHE. + // SEC_IMAGE is still valid and desired in this case. + // + + SectionAttributes &= ~SEC_NOCACHE; + } + + // + // Windows 7 ignores security attributes on unnamed sections. Chromium checks + // this and crashes. In order to solve this problem we will give a random name + // to any unnamed section that has a DACL. + // + + if (ObjectAttributes && + ObjectAttributes->RootDirectory == NULL && + ObjectAttributes->ObjectName == NULL && + ObjectAttributes->SecurityDescriptor != NULL && + KexData->BaseNamedObjects != NULL) { + + WCHAR ObjectName[64]; + ULONGLONG RandomIdentifier; + ULONG AdvancedLength; + PTEB Teb; + + Teb = NtCurrentTeb(); + + // + // Create a random identifier. + // + + NtQuerySystemTime((PLONGLONG) &RandomIdentifier); + RandomIdentifier *= (ULONG_PTR) Teb->ClientId.UniqueProcess; + RandomIdentifier *= (ULONG_PTR) Teb->ClientId.UniqueThread; + RandomIdentifier += RtlRandomEx((PULONG) &RandomIdentifier); + + RtlInitEmptyUnicodeString(&NewObjectName, ObjectName, sizeof(ObjectName)); + Status = RtlAppendUnicodeToString(&NewObjectName, L"VxKexRandomSectionName_"); + ASSERT (NT_SUCCESS(Status)); + AdvancedLength = NewObjectName.Length; + KexRtlAdvanceUnicodeString(&NewObjectName, NewObjectName.Length); + Status = RtlInt64ToUnicodeString(RandomIdentifier, 16, &NewObjectName); + ASSERT (NT_SUCCESS(Status)); + KexRtlRetreatUnicodeString(&NewObjectName, (USHORT) AdvancedLength); + + // + // Fill out the new OBJECT_ATTRIBUTES structure which we will use instead + // of the caller-supplied one. + // + + ASSERT (VALID_HANDLE(KexData->BaseNamedObjects)); + NewObjectAttributes = *ObjectAttributes; + NewObjectAttributes.RootDirectory = KexData->BaseNamedObjects; + NewObjectAttributes.ObjectName = &NewObjectName; + + // + // TODO: set some kind of security which stops other people opening this + // named object. + // + + OriginalObjectAttributes = ObjectAttributes; + ObjectAttributes = &NewObjectAttributes; + + HaveRenamedObject = TRUE; + } + +RetryAfterError: + Status = KexNtCreateSection( + SectionHandle, + DesiredAccess, + ObjectAttributes, + MaximumSize, + PageAttributes, + SectionAttributes, + FileHandle); + + if (HaveRenamedObject && !NT_SUCCESS(Status)) { + if (ObjectAttributes->RootDirectory == KexData->UntrustedNamedObjects) { + KexDebugCheckpoint(); + + // + // TODO: handle STATUS_OBJECT_NAME_COLLISION by retrying. + // + + // fall back to original ObjectAttributes structure + ObjectAttributes = OriginalObjectAttributes; + HaveRenamedObject = FALSE; + } else { + ASSERT (VALID_HANDLE(KexData->UntrustedNamedObjects)); + ObjectAttributes->RootDirectory = KexData->UntrustedNamedObjects; + } + + goto RetryAfterError; + } + + return Status; +} PROTECTED_FUNCTION_END \ No newline at end of file diff --git a/KexDll/ntthread.c b/KexDll/ntthread.c new file mode 100644 index 0000000..552ba17 --- /dev/null +++ b/KexDll/ntthread.c @@ -0,0 +1,112 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// ntthread.c +// +// Abstract: +// +// Extended functions for dealing with threads. +// +// Author: +// +// vxiiduu (07-Nov-2022) +// +// Revision History: +// +// vxiiduu 07-Nov-2022 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kexdllp.h" + +NTSTATUS NTAPI Ext_NtQueryInformationThread( + IN HANDLE ThreadHandle, + IN THREADINFOCLASS ThreadInformationClass, + OUT PVOID ThreadInformation, + IN ULONG ThreadInformationLength, + OUT PULONG ReturnLength OPTIONAL) PROTECTED_FUNCTION +{ + NTSTATUS Status; + + if (ThreadInformationClass <= ThreadIdealProcessorEx) { + + // + // fall through and call original NtQueryInformationThread + // + + NOTHING; + + } else if (ThreadInformationClass == ThreadNameInformation) { + OBJECT_BASIC_INFORMATION ThreadHandleInformation; + + // + // Check for THREAD_QUERY_LIMITED_INFORMATION access. + // + + Status = KexNtQueryObject( + ThreadHandle, + ObjectBasicInformation, + &ThreadHandleInformation, + sizeof(ThreadHandleInformation), + NULL); + + if (!NT_SUCCESS(Status)) { + return Status; + } + + unless (ThreadHandleInformation.GrantedAccess & THREAD_QUERY_LIMITED_INFORMATION) { + return STATUS_ACCESS_DENIED; + } + + // + // TODO: Implement ThreadNameInformation here. + // + + return STATUS_INVALID_INFO_CLASS; + } else { + KexLogWarningEvent( + L"NtQueryInformationThread called with an unsupported extended information class %d", + ThreadInformationClass); + } + + return KexNtQueryInformationThread( + ThreadHandle, + ThreadInformationClass, + ThreadInformation, + ThreadInformationLength, + ReturnLength); +} PROTECTED_FUNCTION_END + +NTSTATUS NTAPI Ext_NtSetInformationThread( + IN HANDLE ThreadHandle, + IN THREADINFOCLASS ThreadInformationClass, + IN PVOID ThreadInformation, + IN ULONG ThreadInformationLength) PROTECTED_FUNCTION +{ + // + // TODO: Implement ThreadNameInformation + // + + return KexNtSetInformationThread( + ThreadHandle, + ThreadInformationClass, + ThreadInformation, + ThreadInformationLength); +} PROTECTED_FUNCTION_END + +NTSTATUS NTAPI NtAlertThreadByThreadId( + IN HANDLE UniqueThread) PROTECTED_FUNCTION +{ + // TODO + return STATUS_NOT_IMPLEMENTED; +} PROTECTED_FUNCTION_END + +NTSTATUS NTAPI NtWaitForAlertByThreadId( + IN PVOID Hint, + IN PLONGLONG Timeout) PROTECTED_FUNCTION +{ + // TODO + return STATUS_NOT_IMPLEMENTED; +} PROTECTED_FUNCTION_END \ No newline at end of file diff --git a/KexDll/propagte.c b/KexDll/propagte.c new file mode 100644 index 0000000..d578899 --- /dev/null +++ b/KexDll/propagte.c @@ -0,0 +1,1097 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// propagte.c +// +// Abstract: +// +// Implements functionality required to propagate VxKex to child processes. +// The basic gist of it is that we will hook NtCreateUserProcess. When +// our NtCreateUserProcess hook is called, it will create the child process +// and then install hooks on NtOpenKey/NtOpenKeyEx. +// +// When the NtOpenKey/NtOpenKeyEx hooks are called, they will rewrite any +// attempt to access IFEO keys to a virtualized key. This will cause the +// loader to load KexDll and then the rest of the initialization proceeds +// as usual. +// +// Author: +// +// vxiiduu (23-Oct-2022) +// +// Revision History: +// +// vxiiduu 23-Oct-2022 Initial creation. +// vxiiduu 05-Nov-2022 Propagation working for 64 bit. +// vxiiduu 05-Jan-2023 Convert to user friendly NTSTATUS +// vxiiduu 12-Feb-2024 Fix propagation on WOW64 +// vxiiduu 03-Mar-2024 Fix propagation for 32-bit OSes +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kexdllp.h" + +STATIC NTSTATUS NTAPI Ext_NtCreateUserProcess( + OUT CONST PHANDLE ProcessHandle, + OUT CONST PHANDLE ThreadHandle, + IN CONST ACCESS_MASK ProcessDesiredAccess, + IN CONST ACCESS_MASK ThreadDesiredAccess, + IN CONST POBJECT_ATTRIBUTES ProcessObjectAttributes OPTIONAL, + IN CONST POBJECT_ATTRIBUTES ThreadObjectAttributes OPTIONAL, + IN CONST ULONG ProcessFlags, + IN CONST ULONG ThreadFlags, + IN CONST PRTL_USER_PROCESS_PARAMETERS ProcessParameters, + IN OUT CONST PPS_CREATE_INFO CreateInfo, + IN CONST PPS_ATTRIBUTE_LIST AttributeList OPTIONAL); + +STATIC ULONG_PTR NativeNtOpenKeyRva; +STATIC ULONG_PTR Wow64NtOpenKeyRva; +STATIC NT_WOW64_QUERY_INFORMATION_PROCESS64 NtWow64QueryInformationProcess64; +STATIC NT_WOW64_WRITE_VIRTUAL_MEMORY64 NtWow64WriteVirtualMemory64; + +STATIC CONST BYTE KexpNtOpenKeyHook32[] = { + 0xE8, 0x00, 0x00, 0x00, 0x00, 0x58, 0x83, 0xC0, 0x06, 0xEB, 0x43, 0x00, 0x38, 0x00, 0x3A, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7B, 0x00, 0x56, 0x00, 0x78, 0x00, 0x4B, 0x00, 0x65, 0x00, 0x78, 0x00, + 0x50, 0x00, 0x72, 0x00, 0x6F, 0x00, 0x70, 0x00, 0x61, 0x00, 0x67, 0x00, 0x61, 0x00, 0x74, 0x00, + 0x69, 0x00, 0x6F, 0x00, 0x6E, 0x00, 0x56, 0x00, 0x69, 0x00, 0x72, 0x00, 0x74, 0x00, 0x75, 0x00, + 0x61, 0x00, 0x6C, 0x00, 0x4B, 0x00, 0x65, 0x00, 0x79, 0x00, 0x7D, 0x00, 0x00, 0x00, 0x80, 0x38, + 0x00, 0x75, 0x2A, 0x64, 0x8B, 0x15, 0x30, 0x00, 0x00, 0x00, 0x8B, 0x52, 0x10, 0x81, 0x62, 0x08, + 0xFF, 0xBF, 0xFF, 0xFF, 0x8B, 0x54, 0x24, 0x0C, 0x8B, 0x4A, 0x04, 0x85, 0xC9, 0x74, 0x0E, 0xFE, + 0x00, 0x8D, 0x48, 0x01, 0x83, 0xC0, 0x09, 0x89, 0x41, 0x04, 0x89, 0x4A, 0x08, 0xB8, 0xB6, 0x00, + 0x00, 0x00, 0xBA, 0x00, 0x03, 0xFE, 0x7F, 0x83, 0x3A, 0x00, 0x74, 0x05, 0xFF, 0x12, 0xC2, 0x0C, + 0x00, 0xB8, 0x0F, 0x00, 0x00, 0x00, 0x31, 0xC9, 0x8D, 0x54, 0x24, 0x04, 0x64, 0xFF, 0x15, 0xC0, + 0x00, 0x00, 0x00, 0x83, 0xC4, 0x04, 0xC2, 0x0C, 0x00 +}; + +STATIC CONST BYTE KexpNtOpenKeyHook64[] = { + 0x80, 0x3D, 0x43, 0x00, 0x00, 0x00, 0x00, 0x75, 0x36, 0x65, 0x48, 0x8B, 0x04, 0x25, 0x60, 0x00, + 0x00, 0x00, 0x48, 0x8B, 0x40, 0x20, 0x81, 0x60, 0x08, 0xFF, 0xBF, 0xFF, 0xFF, 0x49, 0x8B, 0x40, + 0x08, 0x85, 0xC0, 0x74, 0x1A, 0xFE, 0x05, 0x1F, 0x00, 0x00, 0x00, 0x48, 0x8D, 0x05, 0x1E, 0x00, + 0x00, 0x00, 0x48, 0x89, 0x40, 0x08, 0x48, 0x83, 0x40, 0x08, 0x10, 0x49, 0x89, 0x40, 0x10, 0x49, + 0x89, 0xCA, 0xB8, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x05, 0xC3, 0x00, 0x90, 0x90, 0x90, 0x90, 0x90, + 0x38, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7B, 0x00, 0x56, 0x00, 0x78, 0x00, 0x4B, 0x00, 0x65, 0x00, 0x78, 0x00, 0x50, 0x00, 0x72, 0x00, + 0x6F, 0x00, 0x70, 0x00, 0x61, 0x00, 0x67, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6F, 0x00, + 0x6E, 0x00, 0x56, 0x00, 0x69, 0x00, 0x72, 0x00, 0x74, 0x00, 0x75, 0x00, 0x61, 0x00, 0x6C, 0x00, + 0x4B, 0x00, 0x65, 0x00, 0x79, 0x00, 0x7D, 0x00, 0x00, 0x00 +}; + +// +// This function unhooks NtOpenKey/NtOpenKeyEx and unmaps the +// temporary KexDll from the current process. +// +STATIC VOID KexpCleanupPropagationRemains( + VOID) +{ + NTSTATUS Status; + PBYTE Function; + PVOID HookDestination; + + unless (KexData->Flags & KEXDATA_FLAG_PROPAGATED) { + KexLogDebugEvent(L"Propagation flag not set."); + return; + } + + // + // Inspect the entry points of the native NtOpenKey and see if they + // look like a hook template that has previously been written. + // + + Function = (PBYTE) NtOpenKey; + HookDestination = NULL; + + if (KexRtlCurrentProcessBitness() == 64) { + // + // Look for 0xFF 0x25 0x00 0x00 0x00 0x00, followed by 8 byte address + // + + if (Function[0] == 0xFF && Function[1] == 0x25 && *((PULONG) &Function[2]) == 0) { + HookDestination = (PVOID) *((PULONGLONG) &Function[6]); + } + } else { + // + // Look for 0x68, followed by 4 byte address and then 0xC3 + // + + if (Function[0] == 0x68 && Function[5] == 0xC3) { + HookDestination = (PVOID) *((PULONG) &Function[1]); + } + } + + if (!HookDestination) { + KexLogWarningEvent(L"Propagation flag set, but no propagation remains found."); + return; + } else { + ULONG OldProtect; + PVOID BaseAddress; + SIZE_T RegionSize; + + BaseAddress = HookDestination; + RegionSize = 4096; // page size + ASSERT (max(sizeof(KexpNtOpenKeyHook32), sizeof(KexpNtOpenKeyHook64)) <= RegionSize); + + Status = NtFreeVirtualMemory( + NtCurrentProcess(), + &BaseAddress, + &RegionSize, + MEM_RELEASE); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + KexLogWarningEvent( + L"Failed to free memory from NtOpenKey hook procedure.\r\n\r\n" + L"NTSTATUS error code: %s (0x%08lx)", + KexRtlNtStatusToString(Status), Status); + } else { + KexLogDebugEvent( + L"Successfully freed memory from NtOpenKey hook procedure.\r\n\r\n" + L"Base address: 0x%p", + BaseAddress); + } + + // + // Restore original syscalls. + // TODO: Rearrange this code so that a failure to set memory protection does not + // crash the process by making it impossible to call NtOpenKey. + // TODO: Why is region size just set to 15??? + // + + BaseAddress = NtOpenKey; + RegionSize = 15; + + Status = NtProtectVirtualMemory( + NtCurrentProcess(), + &BaseAddress, + &RegionSize, + PAGE_EXECUTE_WRITECOPY, + &OldProtect); + + ASSERT (NT_SUCCESS(Status)); + + if (KexRtlCurrentProcessBitness() == 64) { + // + // We are 64 bit, native + // + + CONST BYTE SyscallTemplate[] = { + 0x4C, 0x8B, 0xD1, // mov r10, rcx + 0xB8, 0x0F, 0x00, 0x00, 0x00, // mov eax, 0x0F + 0x0F, 0x05, // syscall + 0xC3 // ret + }; + + RtlCopyMemory(NtOpenKey, SyscallTemplate, sizeof(SyscallTemplate)); + } else if (KexRtlOperatingSystemBitness() == 64) { + // + // We are 32 bit, WOW64 + // + + CONST BYTE SyscallTemplate[] = { + 0xB8, 0x0F, 0x00, 0x00, 0x00, // mov eax, 0x0F + 0x33, 0xC9, // xor ecx, ecx + 0x8D, 0x54, 0x24, 0x04, // lea edx, [esp+4] + 0x64, 0xFF, 0x15, 0xC0, 0x00, 0x00, 0x00, // call [fs:0xC0] + 0x83, 0xC4, 0x04, // add esp, 4 + 0xC2, 0x0C, 0x00 // ret 12 + }; + + RtlCopyMemory(NtOpenKey, SyscallTemplate, sizeof(SyscallTemplate)); + } else { + // + // We are 32 bit, native + // + + CONST BYTE SyscallTemplate[] = { + 0xB8, 0xB6, 0x00, 0x00, 0x00, // mov eax, 0xB6 + 0xBA, 0x00, 0x03, 0xFE, 0x7F, // mov edx, 0x7ffe0300 + 0xFF, 0x12, // call [edx] + 0xC2, 0x0C, 0x00 // ret 12 + }; + + RtlCopyMemory(NtOpenKey, SyscallTemplate, sizeof(SyscallTemplate)); + } + + Status = NtProtectVirtualMemory( + NtCurrentProcess(), + &BaseAddress, + &RegionSize, + OldProtect, + &OldProtect); + + ASSERT (NT_SUCCESS(Status)); + } +} + +KEXAPI NTSTATUS NTAPI KexInitializePropagation( + VOID) +{ + NTSTATUS Status; + PPEB Peb; + + NtWow64QueryInformationProcess64 = NULL; + NtWow64WriteVirtualMemory64 = NULL; + NativeNtOpenKeyRva = 0; + Wow64NtOpenKeyRva = 0; + + // + // Check the SubSystemData pointer. If it's non-null, it points to a + // KEX_IFEO_PARAMETERS structure inherited from the parent process, and + // it means we are propagated. + // + + Peb = NtCurrentPeb(); + + if (Peb->SubSystemData) { + NTSTATUS Status; + PKEX_IFEO_PARAMETERS InheritedIfeoParameters; + SIZE_T RegionSize; + + KexData->Flags |= KEXDATA_FLAG_PROPAGATED; + InheritedIfeoParameters = (PKEX_IFEO_PARAMETERS) Peb->SubSystemData; + + KexLogDebugEvent( + L"Found Peb->SubSystemData pointer 0x%p", + Peb->SubSystemData); + + // + // Do a quick validity check to make sure this isn't garbage data. + // + + ASSERT ((InheritedIfeoParameters->DisableForChild & ~1) == 0); + ASSERT ((InheritedIfeoParameters->DisableAppSpecific & ~1) == 0); + ASSERT ((InheritedIfeoParameters->StrongVersionSpoof & ~KEX_STRONGSPOOF_VALID_MASK) == 0); + ASSERT (InheritedIfeoParameters->WinVerSpoof < WinVerSpoofMax); + + // + // Copy the inherited process parameters into KexData if we didn't already + // have KEX_ options read from IFEO. In other words, if the user specifically + // configured VxKex options in the shell extension, we won't override them + // with the propagated values. + // + + if (!(KexData->Flags & KEXDATA_FLAG_IFEO_OPTIONS_PRESENT)) { + KexData->IfeoParameters = *InheritedIfeoParameters; + } + + // + // De-allocate the inherited structure. + // + + RegionSize = 0; + + Status = NtFreeVirtualMemory( + NtCurrentProcess(), + (PPVOID) &InheritedIfeoParameters, + &RegionSize, + MEM_RELEASE); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + KexLogWarningEvent( + L"Failed to free the temporary propagation KEX_IFEO_PARAMETERS.\r\n\r\n" + L"NTSTATUS error code: %s (0x%08lx)", + KexRtlNtStatusToString(Status), Status); + } + + Peb->SubSystemData = NULL; + } else { + KexLogDebugEvent(L"Could not find any inherited KEX_IFEO_PARAMETERS."); + } + + // + // Remove any NtOpenKey hook that may be there. + // + + KexpCleanupPropagationRemains(); + + // + // At this point we are done cleaning up. + // If the user doesn't want us to propagate to child processes we can stop + // right here. + // + + if (KexData->IfeoParameters.DisableForChild) { + KexLogInformationEvent(L"Not enabling propagation due to user preferences."); + return STATUS_USER_DISABLED; + } + + // + // If we are a WOW64 process, then we need to calculate the RVAs of the + // NtOpenKey export in the native (i.e. 64-bit) NTDLL. + // + // If we are a 64-bit process, then we need to calculate the RVA of + // NtOpenKey in the WOW64 NTDLL. + // + + if (KexRtlOperatingSystemBitness() != KexRtlCurrentProcessBitness()) { + ANSI_STRING NtWow64QueryInformationProcess64Name; + ANSI_STRING NtWow64WriteVirtualMemory64Name; + + // + // We are a WOW64 process running in a 64-bit OS. + // Get the RVA of the NtOpenKey in the native NTDLL. + // + + Status = KexLdrMiniGetProcedureAddress( + KexData->NativeSystemDllBase, + "NtOpenKey", + (PPVOID) &NativeNtOpenKeyRva); + + ASSERT (NT_SUCCESS(Status)); + ASSERT (NativeNtOpenKeyRva != 0); + + if (!NT_SUCCESS(Status)) { + return Status; + } + + NativeNtOpenKeyRva = VA_TO_RVA(KexData->NativeSystemDllBase, NativeNtOpenKeyRva); + ASSERT (NativeNtOpenKeyRva != 0); + + // + // We're a 32 bit process, but we might need to write data to 64-bit processes. + // Luckily the WOW64 NTDLL contains some useful functions for that. + // + + RtlInitConstantAnsiString(&NtWow64QueryInformationProcess64Name, "NtWow64QueryInformationProcess64"); + RtlInitConstantAnsiString(&NtWow64WriteVirtualMemory64Name, "NtWow64WriteVirtualMemory64"); + ASSERT (KexData->SystemDllBase != NULL); + + Status = LdrGetProcedureAddress( + KexData->SystemDllBase, + &NtWow64QueryInformationProcess64Name, + 0, + (PPVOID) &NtWow64QueryInformationProcess64); + + ASSERT (NT_SUCCESS(Status)); + ASSERT (NtWow64QueryInformationProcess64 != NULL); + + if (!NT_SUCCESS(Status)) { + KexLogWarningEvent( + L"Failed to get procedure address of NtWow64QueryInformationProcess64\r\n\r\n" + L"NTSTATUS error code: %s (0x%08lx)", + KexRtlNtStatusToString(Status), Status); + return Status; + } + + Status = LdrGetProcedureAddress( + KexData->SystemDllBase, + &NtWow64WriteVirtualMemory64Name, + 0, + (PPVOID) &NtWow64WriteVirtualMemory64); + + ASSERT (NT_SUCCESS(Status)); + ASSERT (NtWow64WriteVirtualMemory64 != NULL); + + if (!NT_SUCCESS(Status)) { + KexLogWarningEvent( + L"Failed to get procedure address of NtWow64WriteVirtualMemory64\r\n\r\n" + L"NTSTATUS error code: %s (0x%08lx)", + KexRtlNtStatusToString(Status), Status); + return Status; + } + } else if (KexRtlCurrentProcessBitness() == 64) { + UNICODE_STRING Wow64NtdllPath; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + HANDLE Wow64NtdllFileHandle; + HANDLE Wow64NtdllSectionHandle; + PVOID Wow64NtdllMappedBase; + SIZE_T Wow64NtdllMappedSize; + + // + // We are a 64-bit process. + // This is actually more of a pain than the other case, because now we need to + // manually map the WOW64 NTDLL first. + // + + RtlInitConstantUnicodeString(&Wow64NtdllPath, L"\\SystemRoot\\syswow64\\ntdll.dll"); + InitializeObjectAttributes(&ObjectAttributes, &Wow64NtdllPath, OBJ_CASE_INSENSITIVE, NULL, NULL); + + Status = NtOpenFile( + &Wow64NtdllFileHandle, + GENERIC_READ | GENERIC_EXECUTE, + &ObjectAttributes, + &IoStatusBlock, + FILE_SHARE_READ, + 0); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + KexLogWarningEvent( + L"Failed to open WOW64 NTDLL.\r\n\r\n" + L"NTSTATUS error code: %s (0x%08lx)", + KexRtlNtStatusToString(Status), Status); + + return Status; + } + + Status = NtCreateSection( + &Wow64NtdllSectionHandle, + SECTION_ALL_ACCESS, + NULL, + NULL, + PAGE_EXECUTE, + SEC_IMAGE, + Wow64NtdllFileHandle); + + SafeClose(Wow64NtdllFileHandle); // don't need this anymore + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + KexLogWarningEvent( + L"Failed to create section for WOW64 NTDLL.\r\n\r\n" + L"NTSTATUS error code: %s (0x%08lx)", + KexRtlNtStatusToString(Status), Status); + + return Status; + } + + Wow64NtdllMappedBase = NULL; + Wow64NtdllMappedSize = 0; + + Status = NtMapViewOfSection( + Wow64NtdllSectionHandle, + NtCurrentProcess(), + &Wow64NtdllMappedBase, + 0, + 0, + NULL, + &Wow64NtdllMappedSize, + ViewUnmap, + 0, + PAGE_READWRITE); + + SafeClose(Wow64NtdllSectionHandle); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + KexLogWarningEvent( + L"Failed to map WOW64 NTDLL into current process.\r\n\r\n" + L"NTSTATUS error code: %s (0x%08lx)", + KexRtlNtStatusToString(Status), Status); + + return Status; + } + + Status = KexLdrMiniGetProcedureAddress( + Wow64NtdllMappedBase, + "NtOpenKey", + (PPVOID) &Wow64NtOpenKeyRva); + + NtUnmapViewOfSection(NtCurrentProcess(), Wow64NtdllMappedBase); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + KexLogWarningEvent( + L"Failed to find procedure address of NtOpenKey in WOW64 NTDLL.\r\n\r\n" + L"NTSTATUS error code: %s (0x%08lx)", + KexRtlNtStatusToString(Status), Status); + + return Status; + } + + Wow64NtOpenKeyRva = VA_TO_RVA(Wow64NtdllMappedBase, Wow64NtOpenKeyRva); + } else { + NOT_REACHED; + } + + ASSERT (NativeNtOpenKeyRva != 0 || Wow64NtOpenKeyRva != 0); + + // + // Install a permanent hook, because our hook function will directly do + // a syscall when it wants to call the original function. + // + + Status = KexHkInstallBasicHook(&NtCreateUserProcess, Ext_NtCreateUserProcess, NULL); + + if (NT_SUCCESS(Status)) { + KexLogInformationEvent(L"Successfully initialized propagation system."); + } else { + KexLogErrorEvent( + L"Failed to install hook on NtCreateUserProcess.\r\n\r\n" + L"NTSTATUS error code: %s (0x%08lx)", + KexRtlNtStatusToString(Status), Status); + } + + return Status; +} + +STATIC NTSTATUS NTAPI Ext_NtCreateUserProcess( + OUT CONST PHANDLE ProcessHandle, + OUT CONST PHANDLE ThreadHandle, + IN CONST ACCESS_MASK ProcessDesiredAccess, + IN CONST ACCESS_MASK ThreadDesiredAccess, + IN CONST POBJECT_ATTRIBUTES ProcessObjectAttributes OPTIONAL, + IN CONST POBJECT_ATTRIBUTES ThreadObjectAttributes OPTIONAL, + IN CONST ULONG ProcessFlags, + IN CONST ULONG ThreadFlags, + IN CONST PRTL_USER_PROCESS_PARAMETERS ProcessParameters, + IN OUT CONST PPS_CREATE_INFO CreateInfo, + IN CONST PPS_ATTRIBUTE_LIST AttributeList OPTIONAL) PROTECTED_FUNCTION +{ + NTSTATUS Status; + + ULONG ModifiedThreadFlags; + ULONG ModifiedProcessDesiredAccess; + ULONG ModifiedThreadDesiredAccess; + + ULONG ChildProcessBitness; + + PBYTE HookTemplate; + ULONG HookTemplateCb; + PVOID RemoteHookBaseAddress; + SIZE_T RemoteHookSize; + ULONG_PTR RemoteNtOpenKey; + + PVOID IfeoParametersBaseAddress; + SIZE_T IfeoParametersSize; + + RemoteNtOpenKey = 0; + + ModifiedProcessDesiredAccess = ProcessDesiredAccess; + ModifiedThreadDesiredAccess = ThreadDesiredAccess; + ModifiedThreadFlags = ThreadFlags; + + // + // 1. We need to be able to write to the new process's memory space + // in order to install hooks on NtOpenKey/NtOpenKeyEx. + // + // 2. We may need to be able to resume the new thread after creating + // it suspended. + // + // 3. We need to create the initial thread of the process suspended + // so that we can install the hooks and have them called at the + // appropriate time. + // + + ModifiedProcessDesiredAccess |= PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE; + ModifiedThreadDesiredAccess |= THREAD_SUSPEND_RESUME; + ModifiedThreadFlags |= THREAD_CREATE_FLAGS_CREATE_SUSPENDED; + + Status = KexNtCreateUserProcess( + ProcessHandle, + ThreadHandle, + ModifiedProcessDesiredAccess, + ModifiedThreadDesiredAccess, + ProcessObjectAttributes, + ThreadObjectAttributes, + ProcessFlags, + ModifiedThreadFlags, + ProcessParameters, + CreateInfo, + AttributeList); + + if (!NT_SUCCESS(Status)) { + NTSTATUS Status2; + + // + // Perhaps it failed due to the desired access/flags changes. + // Retry again but with the exact original parameters passed by + // the caller. Of course, this means that VxKex will not be + // enabled for the child process. + // + Status2 = KexNtCreateUserProcess( + ProcessHandle, + ThreadHandle, + ProcessDesiredAccess, + ThreadDesiredAccess, + ProcessObjectAttributes, + ThreadObjectAttributes, + ProcessFlags, + ThreadFlags, + ProcessParameters, + CreateInfo, + AttributeList); + + if (NT_SUCCESS(Status2)) { + // 2nd call succeeded where the 1st one failed... Investigate this. + ASSERT (NT_SUCCESS(Status)); + + KexLogWarningEvent( + L"Failed to create user process with modified parameters.\r\n\r\n" + L"Reversion to system standard behavior caused the call to succeed.\r\n" + L"NTSTATUS error code for modified call: %s (0x%08lx)", + KexRtlNtStatusToString(Status), Status); + } + + return Status2; + } + + // + // Now we've created the child process suspended, find out whether it + // is 64 bit. + // + + ChildProcessBitness = KexRtlRemoteProcessBitness(*ProcessHandle); + + KexLogDebugEvent( + L"The current process is %d-bit and the remote process is %d-bit.", + KexRtlCurrentProcessBitness(), + ChildProcessBitness); + + // + // Allocate space for the hook procedure inside the child process. + // The page protections must be set to RWX because the hook procedure + // blobs contain modifiable data. + // + + RemoteHookBaseAddress = NULL; + + if (ChildProcessBitness == 64) { + RemoteHookSize = sizeof(KexpNtOpenKeyHook64); + } else { + RemoteHookSize = sizeof(KexpNtOpenKeyHook32); + } + + Status = NtAllocateVirtualMemory( + *ProcessHandle, + &RemoteHookBaseAddress, + 2, + &RemoteHookSize, + MEM_COMMIT | MEM_RESERVE, + PAGE_EXECUTE_READWRITE); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + KexLogWarningEvent( + L"Failed to allocate virtual memory for NtOpenKey hook procedure in the parent process.\r\n\r\n" + L"NTSTATUS error code: %s (0x%08lx)", + KexRtlNtStatusToString(Status), Status); + + goto BailOut; + } + + // + // Write the hook procedures into the allocated memory. + // + + if (ChildProcessBitness == 64) { + Status = NtWriteVirtualMemory( + *ProcessHandle, + RemoteHookBaseAddress, + KexpNtOpenKeyHook64, + sizeof(KexpNtOpenKeyHook64), + NULL); + } else { + Status = NtWriteVirtualMemory( + *ProcessHandle, + RemoteHookBaseAddress, + KexpNtOpenKeyHook32, + sizeof(KexpNtOpenKeyHook32), + NULL); + } + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + KexLogWarningEvent( + L"Failed to copy NtOpenKey hook procedure to the parent process.\r\n\r\n" + L"NTSTATUS error code: %s (0x%08lx)", + KexRtlNtStatusToString(Status), Status); + + goto BailOut; + } + + // + // Find out where the address of NtOpenKey is in the context of the + // child process. + // + + if (ChildProcessBitness == KexRtlCurrentProcessBitness()) { + RemoteNtOpenKey = (ULONG_PTR) NtOpenKey; + } else { + PVOID RemoteNtdllBase; + + RemoteNtdllBase = KexLdrGetRemoteSystemDllBase(*ProcessHandle); + + // + // Make sure the remote NTDLL base was found and looks valid. + // + + ASSERT (RemoteNtdllBase != NULL); + ASSERT ((ULONG_PTR) RemoteNtdllBase >= 0x70000000); + ASSERT ((ULONG_PTR) RemoteNtdllBase <= 0x7FFD0000); + + if (RemoteNtdllBase == NULL || + (ULONG_PTR) RemoteNtdllBase < 0x70000000 || + (ULONG_PTR) RemoteNtdllBase > 0x7FFD0000) { + + KexLogWarningEvent(L"Failed to get NTDLL address in the child process."); + goto BailOut; + } + + KexLogDebugEvent(L"Child process NTDLL address: 0x%p", RemoteNtdllBase); + + if (ChildProcessBitness == 64) { + // Child is 64 bit, we are 32 bit. + ASSERT (KexRtlCurrentProcessBitness() == 32); + ASSERT (NativeNtOpenKeyRva != 0); + RemoteNtOpenKey = (ULONG_PTR) RVA_TO_VA(RemoteNtdllBase, NativeNtOpenKeyRva); + } else { + // Child is 32 bit, we are 64 bit. + ASSERT (KexRtlCurrentProcessBitness() == 64); + ASSERT (Wow64NtOpenKeyRva != 0); + RemoteNtOpenKey = (ULONG_PTR) RVA_TO_VA(RemoteNtdllBase, Wow64NtOpenKeyRva); + } + } + + ASSERT (RemoteNtOpenKey != 0); + + // + // Create hook template. + // + + if (ChildProcessBitness == 64) { + HookTemplateCb = 14; + HookTemplate = StackAlloc(BYTE, HookTemplateCb); + RtlZeroMemory(HookTemplate, HookTemplateCb); + + // JMP QWORD PTR [rip+0], followed by 64-byte address + HookTemplate[0] = 0xFF; + HookTemplate[1] = 0x25; + *((PULONGLONG) &HookTemplate[6]) = (ULONGLONG) RemoteHookBaseAddress; + } else { + HookTemplateCb = 6; + HookTemplate = StackAlloc(BYTE, HookTemplateCb); + RtlZeroMemory(HookTemplate, HookTemplateCb); + + // PUSH imm32, followed by RET + HookTemplate[0] = 0x68; + HookTemplate[5] = 0xC3; + *((PULONG) &HookTemplate[1]) = (ULONG) RemoteHookBaseAddress; + } + + // + // Write hook into remote process. + // + + Status = KexRtlWriteProcessMemory( + *ProcessHandle, + RemoteNtOpenKey, + HookTemplate, + HookTemplateCb); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + KexLogWarningEvent( + L"Failed to write hook template to remote process.\r\n\r\n" + L"NTSTATUS error code: %s (0x%08lx)", + KexRtlNtStatusToString(Status), Status); + goto BailOut; + } + + // + // Pass down the VxKex IFEO parameters into the child process. + // We will allocate memory for the parameters, copy the data, and then + // place a pointer into the PEB of the child process. + // + // If the child process is a WOW64 process, then we will use the 32-bit + // PEB. If the child process is a 64-bit process, we will use the 64-bit + // PEB. + // + + IfeoParametersBaseAddress = NULL; + IfeoParametersSize = sizeof(KEX_IFEO_PARAMETERS); + + Status = NtAllocateVirtualMemory( + *ProcessHandle, + &IfeoParametersBaseAddress, + 0, + &IfeoParametersSize, + MEM_COMMIT | MEM_RESERVE, + PAGE_READWRITE); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + KexLogWarningEvent( + L"Failed to allocate for KEX_IFEO_PARAMETERS in child process.\r\n\r\n" + L"NTSTATUS error code: %s", + KexRtlNtStatusToString(Status)); + goto BailOut; + } + + Status = NtWriteVirtualMemory( + *ProcessHandle, + IfeoParametersBaseAddress, + &KexData->IfeoParameters, + sizeof(KexData->IfeoParameters), + NULL); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + KexLogWarningEvent( + L"Failed to write KEX_IFEO_PARAMETERS into child process.\r\n\r\n" + L"NTSTATUS error code: %s (0x%08lx)", + KexRtlNtStatusToString(Status), Status); + goto BailOut; + } + + if (KexRtlCurrentProcessBitness() == 32 && ChildProcessBitness == 64) { + PROCESS_BASIC_INFORMATION64 BasicInformation64; + PVOID64 IfeoParametersBaseAddress64; + ULONGLONG RemoteSubSystemData; + + // + // Get the address of the 64-bit PEB in the child process. + // + + Status = NtWow64QueryInformationProcess64( + *ProcessHandle, + ProcessBasicInformation, + &BasicInformation64, + sizeof(BasicInformation64), + NULL); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + KexLogWarningEvent( + L"Failed to query PEB address of 64-bit process\r\n\r\n" + L"NTSTATUS error code: %s (0x%08lx)", + KexRtlNtStatusToString(Status), Status); + goto BailOut; + } + + KexLogDebugEvent( + L"PEB address of 64-bit child process: 0x%I64x", + BasicInformation64.PebBaseAddress); + + // + // Write the pointer to the IFEO parameters data into the SubSystemData of the + // child process's PEB. + // + + IfeoParametersBaseAddress64 = IfeoParametersBaseAddress; + + // + // careful with the math here - otherwise things will accidentally get truncated + // to 32 bit and we will get STATUS_ACCESS_VIOLATION or crash the child process + // if unlucky. + // + // The 0x28 is a hard-coded offset for the 64-bit FIELD_OFFSET(PEB, SubSystemData). + // + + RemoteSubSystemData = (ULONGLONG) (BasicInformation64.PebBaseAddress); + RemoteSubSystemData += 0x28; + + Status = NtWow64WriteVirtualMemory64( + *ProcessHandle, + (PVOID64) RemoteSubSystemData, + &IfeoParametersBaseAddress64, + sizeof(IfeoParametersBaseAddress64), + NULL); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + KexLogWarningEvent( + L"Failed to write Peb->SubSystemData of 64-bit process\r\n\r\n" + L"NTSTATUS error code: %s (0x%08lx)", + KexRtlNtStatusToString(Status), Status); + goto BailOut; + } + } else { + ULONG_PTR RemotePeb; + ULONG_PTR RemoteSubSystemData; + + if (ChildProcessBitness == KexRtlOperatingSystemBitness()) { + PROCESS_BASIC_INFORMATION BasicInformation; + + Status = NtQueryInformationProcess( + *ProcessHandle, + ProcessBasicInformation, + &BasicInformation, + sizeof(BasicInformation), + NULL); + + RemotePeb = (ULONG_PTR) BasicInformation.PebBaseAddress; + } else { + // + // Query the location of the WOW64 PEB. + // NtQueryInformationProcess+ProcessBasicInformation will tell us the location of + // the 64-bit PEB, which is not what we want. + // + + Status = NtQueryInformationProcess( + *ProcessHandle, + ProcessWow64Information, + &RemotePeb, + sizeof(RemotePeb), + NULL); + } + + ASSERT (NT_SUCCESS(Status)); + ASSERT (RemotePeb != 0); + + if (ChildProcessBitness == 32) { + ASSERT (RemotePeb < ULONG_MAX); + } + + if (!NT_SUCCESS(Status)) { + KexLogWarningEvent( + L"Failed to query PEB address of child process\r\n\r\n" + L"NTSTATUS error code: %s (0x%08lx)", + KexRtlNtStatusToString(Status), Status); + goto BailOut; + } + + KexLogDebugEvent(L"PEB address of child process: 0x%p", RemotePeb); + + if (ChildProcessBitness == 64) { + RemoteSubSystemData = RemotePeb + 0x28; + } else { + RemoteSubSystemData = RemotePeb + 0x14; + } + + Status = NtWriteVirtualMemory( + *ProcessHandle, + (PVOID) RemoteSubSystemData, + &IfeoParametersBaseAddress, + ChildProcessBitness / 8, + NULL); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + KexLogWarningEvent( + L"Failed to write Peb->SubSystemData of child process\r\n\r\n" + L"NTSTATUS error code: %s (0x%08lx)", + KexRtlNtStatusToString(Status), Status); + goto BailOut; + } + + if (KexRtlOperatingSystemBitness() == 32) { + ULONG_PTR RemoteProcessParametersFlags; + ULONG ProcessParametersFlags; + + ASSUME (KexRtlCurrentProcessBitness() == 32); + ASSUME (ChildProcessBitness == 32); + + // + // Clear RTL_USER_PROCESS_PARAMETERS_IMAGE_KEY_MISSING in the remote + // Peb->ProcessParameters->Flags. + // + // This is necessary because the kernel sets that flag if it doesn't see any IFEO + // options for the process, and if NTDLL sees the flag, it will not bother checking + // IFEO, which is bad because we won't successfully propagate. + // + // You might wonder, "why can't you just clear that flag from within the NtOpenKey + // hook?" This method actually works on 64-bit operating systems, and it's a lot + // easier and faster, but unfortunately on 32-bit operating systems the flag is + // checked before NtOpenKey is ever called. On 64-bit operating systems (including + // on WOW64), the flag is checked after the first time NtOpenKey is called, so it's + // OK. + // + // The difference is caused by the fact that 64-bit operating systems check for + // the DisableUserModeCallbackFilter IFEO value prior to doing the usual GlobalFlag, + // VerifierDlls etc. checks. + // + // For reference, the function responsible for performing this check is called + // LdrpIsSystemwideUserCallbackExceptionFilterDisabled (it got inlined on some x64 + // builds). + // + + RemoteProcessParametersFlags = RemotePeb + FIELD_OFFSET(PEB, ProcessParameters); + + Status = NtReadVirtualMemory( + *ProcessHandle, + (PVOID) RemoteProcessParametersFlags, + &RemoteProcessParametersFlags, + ChildProcessBitness / 8, + NULL); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + KexLogWarningEvent( + L"Failed to read Peb->ProcessParameters pointer of child process\r\n\r\n" + L"NTSTATUS error code: %s (0x%08lx)", + KexRtlNtStatusToString(Status), Status); + goto BailOut; + } + + // + // RemoteProcessParametersFlags now contains a pointer to a + // RTL_USER_PROCESS_PARAMETERS structure within the child process. + // + + RemoteProcessParametersFlags += FIELD_OFFSET(RTL_USER_PROCESS_PARAMETERS, Flags); + + Status = NtReadVirtualMemory( + *ProcessHandle, + (PVOID) RemoteProcessParametersFlags, + &ProcessParametersFlags, + sizeof(ProcessParametersFlags), + NULL); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + KexLogWarningEvent( + L"Failed to read ProcessParameters->Flags of child process\r\n\r\n" + L"NTSTATUS error code: %s (0x%08lx)", + KexRtlNtStatusToString(Status), Status); + goto BailOut; + } + + // + // Clear the flag and write back the new value to the child process. + // + + ProcessParametersFlags &= ~RTL_USER_PROCESS_PARAMETERS_IMAGE_KEY_MISSING; + + Status = NtWriteVirtualMemory( + *ProcessHandle, + (PVOID) RemoteProcessParametersFlags, + &ProcessParametersFlags, + sizeof(ProcessParametersFlags), + NULL); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + KexLogWarningEvent( + L"Failed to write ProcessParameters->Flags of child process\r\n\r\n" + L"NTSTATUS error code: %s (0x%08lx)", + KexRtlNtStatusToString(Status), Status); + goto BailOut; + } + } + } + +BailOut: + Status = STATUS_SUCCESS; + + // + // Finally, resume the initial thread (unless the original caller + // wanted the thread to remain suspended). + // + // Note that CreateProcess always requests the thread to be created + // suspended anyway. + // + + unless (ThreadFlags & THREAD_CREATE_FLAGS_CREATE_SUSPENDED) { + Status = NtResumeThread(*ThreadHandle, NULL); + + if (!NT_SUCCESS(Status)) { + KexLogWarningEvent( + L"Failed to resume the initial thread of the remote process.\r\n\r\n" + L"NTSTATUS error code: %s", + KexRtlNtStatusToString(Status)); + } + } + + return Status; +} PROTECTED_FUNCTION_END \ No newline at end of file diff --git a/KexDll/redirects.h b/KexDll/redirects.h new file mode 100644 index 0000000..b33d6cb --- /dev/null +++ b/KexDll/redirects.h @@ -0,0 +1,174 @@ +// +// General DLL Redirects. These apply to applications, application DLLs, and DLLs +// outside of KexDir and WinDir. The DLL redirect routine strips the .dll suffix, +// if present, from the DLL name. +// + +#define DLL_REDIRECT(Key, Value) {RTL_CONSTANT_STRING(_L(Key)), RTL_CONSTANT_STRING(_L(Value))}, + +STATIC CONST UNICODE_STRING DllRedirects[][2] = { + DLL_REDIRECT("ntdll", "kxnt" ) + + DLL_REDIRECT("cfgmgr32", "kxbase" ) + DLL_REDIRECT("kernel32", "kxbase" ) + DLL_REDIRECT("kernelbase", "kxbase" ) + + DLL_REDIRECT("bcrypt", "kxcryp" ) + DLL_REDIRECT("bcryptprimitives", "kxcryp" ) + DLL_REDIRECT("secur32", "kxcryp" ) + + DLL_REDIRECT("BluetoothApis", "kxuser" ) + DLL_REDIRECT("shcore", "kxuser" ) + DLL_REDIRECT("user32", "kxuser" ) + + DLL_REDIRECT("combase", "kxcom" ) + DLL_REDIRECT("ole32", "kxcom" ) + + DLL_REDIRECT("msvcrt", "kxcrt" ) + + DLL_REDIRECT("d3d12", "kxdx" ) + DLL_REDIRECT("dxgi", "kxdx" ) + DLL_REDIRECT("MFPlat", "kxdx" ) + DLL_REDIRECT("xinput1_4", "xinput1_3" ) + + DLL_REDIRECT("dcomp", "dcow8" ) + + DLL_REDIRECT("powrprof", "kxmi" ) + DLL_REDIRECT("userenv", "kxmi" ) + DLL_REDIRECT("version", "kxmi" ) + DLL_REDIRECT("wldp", "kxmi" ) + + DLL_REDIRECT("dnsapi", "kxnet" ) + DLL_REDIRECT("winhttp", "kxnet" ) + DLL_REDIRECT("ws2_32", "kxnet" ) + + DLL_REDIRECT("advapi32", "kxadvapi" ) + + // + // The DLL rewriting routine strips the -lX-Y-Z suffix from the API set name to + // avoid excessive duplication. + // Keep this list in alphabetical order to avoid accidental duplicates. + // + + DLL_REDIRECT("api-ms-win-appmodel-identity", "kxbase" ) + DLL_REDIRECT("api-ms-win-appmodel-runtime", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-apiquery", "kxnt" ) + DLL_REDIRECT("api-ms-win-core-atoms", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-crt", "kxcrt" ) + DLL_REDIRECT("api-ms-win-core-com", "kxcom" ) + DLL_REDIRECT("api-ms-win-core-console", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-datetime", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-debug", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-delayload", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-errorhandling", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-fibers", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-file", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-handle", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-heap", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-heap-obsolete", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-interlocked", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-io", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-job", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-kernel32-legacy", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-largeinteger", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-libraryloader", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-localization-ansi", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-localization", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-localization-obsolete", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-memory", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-namedpipe-ansi", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-namedpipe", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-path", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-privateprofile", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-processenvironment", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-processsnapshot", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-processthreads", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-processtopology", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-processtopology-obsolete", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-profile", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-psapi", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-quirks", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-realtime", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-registry", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-rtlsupport", "kxnt" ) + DLL_REDIRECT("api-ms-win-core-shlwapi-legacy", "kxuser" ) + DLL_REDIRECT("api-ms-win-core-shlwapi-obsolete", "kxuser" ) + DLL_REDIRECT("api-ms-win-core-string-obsolete", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-sidebyside", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-string", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-string-obsolete", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-synch", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-synch-ansi", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-sysinfo", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-systemtopology", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-threadpool", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-threadpool-legacy", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-threadpool-private", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-toolhelp", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-timezone", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-url", "kxuser" ) + DLL_REDIRECT("api-ms-win-core-util", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-version", "version" ) + DLL_REDIRECT("api-ms-win-core-versionansi", "version" ) + DLL_REDIRECT("api-ms-win-core-windowserrorreporting", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-winrt", "kxcom" ) + DLL_REDIRECT("api-ms-win-core-winrt-error", "kxcom" ) + DLL_REDIRECT("api-ms-win-core-winrt-robuffer", "kxcom" ) + DLL_REDIRECT("api-ms-win-core-winrt-string", "kxcom" ) + DLL_REDIRECT("api-ms-win-core-wow64", "kxbase" ) + DLL_REDIRECT("api-ms-win-core-xstate", "kxnt" ) + DLL_REDIRECT("api-ms-win-crt-conio", "ucrtbase" ) + DLL_REDIRECT("api-ms-win-crt-convert", "ucrtbase" ) + DLL_REDIRECT("api-ms-win-crt-environment", "ucrtbase" ) + DLL_REDIRECT("api-ms-win-crt-filesystem", "ucrtbase" ) + DLL_REDIRECT("api-ms-win-crt-heap", "ucrtbase" ) + DLL_REDIRECT("api-ms-win-crt-locale", "ucrtbase" ) + DLL_REDIRECT("api-ms-win-crt-math", "ucrtbase" ) + DLL_REDIRECT("api-ms-win-crt-multibyte", "ucrtbase" ) + DLL_REDIRECT("api-ms-win-crt-private", "ucrtbase" ) + DLL_REDIRECT("api-ms-win-crt-process", "ucrtbase" ) + DLL_REDIRECT("api-ms-win-crt-runtime", "ucrtbase" ) + DLL_REDIRECT("api-ms-win-crt-stdio", "ucrtbase" ) + DLL_REDIRECT("api-ms-win-crt-string", "ucrtbase" ) + DLL_REDIRECT("api-ms-win-crt-time", "ucrtbase" ) + DLL_REDIRECT("api-ms-win-crt-utility", "ucrtbase" ) + DLL_REDIRECT("api-ms-win-downlevel-kernel32", "kxbase" ) + DLL_REDIRECT("api-ms-win-downlevel-ole32", "kxcom" ) + DLL_REDIRECT("api-ms-win-eventing-classicprovider", "kxadvapi" ) + DLL_REDIRECT("api-ms-win-eventing-provider", "kxadvapi" ) + DLL_REDIRECT("api-ms-win-kernel32-package-current", "kxbase" ) + DLL_REDIRECT("api-ms-win-mm-time", "winmm" ) + DLL_REDIRECT("api-ms-win-ntuser-sysparams", "kxuser" ) + DLL_REDIRECT("api-ms-win-power-base", "kxmi" ) + DLL_REDIRECT("api-ms-win-power-setting", "kxmi" ) + DLL_REDIRECT("api-ms-win-security-base-ansi", "kxadvapi" ) + DLL_REDIRECT("api-ms-win-security-base", "kxbase" ) + DLL_REDIRECT("api-ms-win-security-cryptoapi", "cryptsp" ) + DLL_REDIRECT("api-ms-win-security-lsalookup-ansi", "kxadvapi" ) + DLL_REDIRECT("api-ms-win-security-lsalookup", "sechost" ) + DLL_REDIRECT("api-ms-win-security-sddl-ansi", "kxadvapi" ) + DLL_REDIRECT("api-ms-win-security-sddl", "sechost" ) + DLL_REDIRECT("api-ms-win-security-systemfunctions", "kxadvapi" ) + DLL_REDIRECT("api-ms-win-service-core-ansi", "kxadvapi" ) + DLL_REDIRECT("api-ms-win-service-core", "sechost" ) + DLL_REDIRECT("api-ms-win-service-management", "kxadvapi" ) + DLL_REDIRECT("api-ms-win-service-private", "sechost" ) + DLL_REDIRECT("api-ms-win-service-winsvc", "sechost" ) + DLL_REDIRECT("api-ms-win-shcore-obsolete", "kxuser" ) + DLL_REDIRECT("api-ms-win-shcore-scaling", "kxuser" ) + DLL_REDIRECT("api-ms-win-shell-namespace", "kxuser" ) + + DLL_REDIRECT("ext-ms-win-gdi-dc", "gdi32" ) + DLL_REDIRECT("ext-ms-win-gdi-dc-create", "gdi32" ) + DLL_REDIRECT("ext-ms-win-gdi-draw", "gdi32" ) + DLL_REDIRECT("ext-ms-win-gdi-font", "gdi32" ) + DLL_REDIRECT("ext-ms-win-gdi-path", "gdi32" ) + DLL_REDIRECT("ext-ms-win-ntuser-rotationmanager", "kxuser" ) + DLL_REDIRECT("ext-ms-win-rtcore-gdi-devcaps", "gdi32" ) + DLL_REDIRECT("ext-ms-win-rtcore-gdi-object", "gdi32" ) + DLL_REDIRECT("ext-ms-win-rtcore-gdi-rgn", "gdi32" ) + DLL_REDIRECT("ext-ms-win-rtcore-ntuser-sysparams", "kxuser" ) + DLL_REDIRECT("ext-ms-win-uiacore", "uiautomationcore" ) +}; + +#undef DLL_REDIRECT \ No newline at end of file diff --git a/KexDll/rtlwoa.c b/KexDll/rtlwoa.c new file mode 100644 index 0000000..c01f5a9 --- /dev/null +++ b/KexDll/rtlwoa.c @@ -0,0 +1,335 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// rtlwoa.c +// +// Abstract: +// +// Implementation of WaitOnAddress and friends. +// +// Author: +// +// vxiiduu (11-Feb-2024) +// +// Revision History: +// +// vxiiduu 11-Feb-2024 Initial creation. +// vxiiduu 15-Feb-2024 Fix a typing error. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kexdllp.h" + +typedef struct _KEX_RTL_WAIT_ON_ADDRESS_WAIT_BLOCK *PKEX_RTL_WAIT_ON_ADDRESS_WAIT_BLOCK; + +typedef struct _KEX_RTL_WAIT_ON_ADDRESS_WAIT_BLOCK { + // + // The address that the thread is waiting on. + // + PVOID Address; + + // + // The event handle upon which this thread is waiting. + // + HANDLE EventHandle; + + // + // Links to the next and previous RTL_WAIT_ON_ADDRESS_WAIT_BLOCK structure + // in the linked list. + // + PKEX_RTL_WAIT_ON_ADDRESS_WAIT_BLOCK Next; + PKEX_RTL_WAIT_ON_ADDRESS_WAIT_BLOCK Previous; +} TYPEDEF_TYPE_NAME(KEX_RTL_WAIT_ON_ADDRESS_WAIT_BLOCK); + +typedef struct _KEX_RTL_WAIT_ON_ADDRESS_HASH_BUCKET { + // + // Locks the hash bucket. Threads calling WoA or one of the wake functions + // for a particular address (range) will be blocked until all pending linked + // list operations are complete. + // + RTL_SRWLOCK Lock; + + // + // This item will be NULL if no threads are waiting on the addresses that + // fall under this hash bucket. + // + PKEX_RTL_WAIT_ON_ADDRESS_WAIT_BLOCK WaitBlocks; +} TYPEDEF_TYPE_NAME(KEX_RTL_WAIT_ON_ADDRESS_HASH_BUCKET); + +// +// 128 entries is what's used in Windows 8. +// Perhaps it's a little excessive. +// The size of this array can be freely adjusted here. The code that uses it +// will automatically adapt to the changed size. +// If you change it, it must remain a power of two. Otherwise, the code that +// hashes addresses will become larger and slower by more than a factor of 2. +// demo: https://godbolt.org/z/K9q9KheYj +// +STATIC KEX_RTL_WAIT_ON_ADDRESS_HASH_BUCKET KexRtlWaitOnAddressHashTable[32] = {0}; + +#pragma warning(disable:4715) // not all control paths return a value +STATIC INLINE BOOLEAN KexRtlpEqualVolatileMemory( + IN VOLATILE VOID *Address1, + IN PCVOID Address2, + IN SIZE_T Size) +{ + switch (Size) { + case 1: return (*(PUCHAR) Address1 == *(PUCHAR) Address2); + case 2: return (*(PUSHORT) Address1 == *(PUSHORT) Address2); + case 4: return (*(PULONG) Address1 == *(PULONG) Address2); + case 8: return (*(PULONGLONG) Address1 == *(PULONGLONG) Address2); + default: ASSUME (FALSE); + } +} +#pragma warning(default:4715) + +STATIC FORCEINLINE PKEX_RTL_WAIT_ON_ADDRESS_HASH_BUCKET KexRtlpGetWoaHashBucket( + IN VOLATILE VOID *Address) +{ + return &KexRtlWaitOnAddressHashTable[ + (((ULONG_PTR) Address) >> 4) % ARRAYSIZE(KexRtlWaitOnAddressHashTable)]; +} + +// +// This function must be called while the hash bucket is locked. +// +STATIC INLINE VOID KexRtlpRemoveWoaWaitBlock( + IN PKEX_RTL_WAIT_ON_ADDRESS_HASH_BUCKET HashBucket, + IN PKEX_RTL_WAIT_ON_ADDRESS_WAIT_BLOCK WaitBlock) +{ + if (WaitBlock->Previous == NULL) { + // this is a signal that we do NOT touch anything + return; + } else if (WaitBlock->Next == WaitBlock) { + // this wait block is the only entry in the list + HashBucket->WaitBlocks = NULL; + } else { + // there's more than one wait block in the list so we have to + // remove it "properly" + + if (WaitBlock == HashBucket->WaitBlocks) { + // this wait block is at the beginning so we have to update + // the pointer in the hash bucket + HashBucket->WaitBlocks = WaitBlock->Next; + } + + WaitBlock->Previous->Next = WaitBlock->Next; + WaitBlock->Next->Previous = WaitBlock->Previous; + } +} + +// +// This function is the implementation of the WaitOnAddress extended API. +// See WaitOnAddress in KxBase\synch.c and the MSDN docs. +// +KEXAPI NTSTATUS NTAPI KexRtlWaitOnAddress( + IN VOLATILE VOID *Address, + IN PVOID CompareAddress, + IN SIZE_T AddressSize, + IN PLARGE_INTEGER Timeout OPTIONAL) +{ + NTSTATUS Status; + PKEX_RTL_WAIT_ON_ADDRESS_HASH_BUCKET HashBucket; + KEX_RTL_WAIT_ON_ADDRESS_WAIT_BLOCK WaitBlock; + + ASSERT (PopulationCount(ARRAYSIZE(KexRtlWaitOnAddressHashTable)) == 1); + ASSERT (Address != NULL); + ASSERT (CompareAddress != NULL); + + ASSERT (AddressSize == 1 || AddressSize == 2 || + AddressSize == 4 || AddressSize == 8); + + if (AddressSize != 1 && AddressSize != 2 && + AddressSize != 4 && AddressSize != 8) { + + return STATUS_INVALID_PARAMETER; + } + + // + // Figure out which hash bucket we belong in. + // + + HashBucket = KexRtlpGetWoaHashBucket(Address); + + RtlAcquireSRWLockExclusive(&HashBucket->Lock); + + // + // Check that the values at *Address and *CompareAddress are the same + // before continuing. + // + + if (!KexRtlpEqualVolatileMemory(Address, CompareAddress, AddressSize)) { + // Values are different, so we can return straight away. + RtlReleaseSRWLockExclusive(&HashBucket->Lock); + return STATUS_SUCCESS; + } + + // + // The values are different. + // Create the event upon which we will wait. + // + + Status = NtCreateEvent( + &WaitBlock.EventHandle, + SYNCHRONIZE | EVENT_MODIFY_STATE, + NULL, + NotificationEvent, + FALSE); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + RtlReleaseSRWLockExclusive(&HashBucket->Lock); + return Status; + } + + // + // Add ourselves into the linked list. + // + + WaitBlock.Address = (PVOID) Address; + + if (HashBucket->WaitBlocks == NULL) { + // No existing wait blocks. + WaitBlock.Previous = &WaitBlock; + WaitBlock.Next = &WaitBlock; + HashBucket->WaitBlocks = &WaitBlock; + } else { + // One or more wait blocks already exist. + // Add ourselves to the end of the list. + WaitBlock.Previous = HashBucket->WaitBlocks->Previous; + WaitBlock.Next = HashBucket->WaitBlocks; + HashBucket->WaitBlocks->Previous->Next = &WaitBlock; + HashBucket->WaitBlocks->Previous = &WaitBlock; + } + + // + // Wait. + // + + RtlReleaseSRWLockExclusive(&HashBucket->Lock); + + Status = NtWaitForSingleObject( + WaitBlock.EventHandle, + FALSE, + Timeout); + + ASSERT (NT_SUCCESS(Status)); + + // + // The thread that woke us up is in charge of removing us from the + // list. However, if we timed out, there is no such thread, so if the + // status from NtWaitForSingleObject is STATUS_TIMEOUT or some other + // error code, we have to do that ourselves. + // + + if (Status == STATUS_TIMEOUT || !NT_SUCCESS(Status)) { + RtlAcquireSRWLockExclusive(&HashBucket->Lock); + KexRtlpRemoveWoaWaitBlock(HashBucket, &WaitBlock); + RtlReleaseSRWLockExclusive(&HashBucket->Lock); + } + + NtClose(WaitBlock.EventHandle); + return Status; +} + +// +// This function is the implementation of the WakeByAddressSingle and +// WakeByAddressAll extended APIs. +// See KexRtlWakeByAddressSingle, KexRtlWakeByAddressAll, and the MSDN +// docs. +// +STATIC VOID KexRtlpWakeByAddress( + IN PVOID Address, + IN BOOLEAN WakeAll) +{ + PKEX_RTL_WAIT_ON_ADDRESS_HASH_BUCKET HashBucket; + PKEX_RTL_WAIT_ON_ADDRESS_WAIT_BLOCK WaitBlock; + + HashBucket = KexRtlpGetWoaHashBucket(Address); + + RtlAcquireSRWLockExclusive(&HashBucket->Lock); + + if (HashBucket->WaitBlocks == NULL) { + RtlReleaseSRWLockExclusive(&HashBucket->Lock); + return; + } + + // + // Traverse the list starting from the beginning. + // The API documentation from MS states that threads are woken starting + // from the one that first started waiting. + // + + WaitBlock = HashBucket->WaitBlocks; + + while (TRUE) { + PKEX_RTL_WAIT_ON_ADDRESS_WAIT_BLOCK NextWaitBlock; + + NextWaitBlock = WaitBlock->Next; + + if (WaitBlock->Address == Address) { + NTSTATUS Status; + + KexRtlpRemoveWoaWaitBlock(HashBucket, WaitBlock); + + // + // Signal to future invocations of KexRtlpRemoveWoaWaitBlock to tell it + // that we've already removed this block from the list. + // We need to do this due to the possibility of the following situation: + // 1. A thread calls WaitOnAddress with a timeout. + // 2. NtWaitForSingleObject returns with STATUS_TIMEOUT. + // 3. In between the STATUS_TIMEOUT return and when that thread removes + // itself from the list, someone calls WakeByAddress and we get to + // this point in the code. + // 4. We remove the list entry from the list. + // 5. The other thread that timed out removes the list entry from the + // list a 2nd time and potentially causes corruption. + // + // It's a rare edge case but the cost to eliminate it is luckily very small. + // + + WaitBlock->Previous = NULL; + + // + // Wake up the thread. + // + + Status = NtSetEvent(WaitBlock->EventHandle, NULL); + ASSERT (NT_SUCCESS(Status)); + + // + // After the call to NtSetEvent, the contents of WaitBlock should be + // considered undefined, since when the KexRtlWaitOnAddress call returns + // the contents of the stack are no longer defined. + // + + if (!WakeAll) { + // we only want to wake this one + break; + } + } + + if (HashBucket->WaitBlocks == NULL || NextWaitBlock == HashBucket->WaitBlocks) { + break; + } + + WaitBlock = NextWaitBlock; + } + + RtlReleaseSRWLockExclusive(&HashBucket->Lock); +} + +KEXAPI VOID NTAPI KexRtlWakeAddressSingle( + IN PVOID Address) +{ + KexRtlpWakeByAddress(Address, FALSE); +} + +KEXAPI VOID NTAPI KexRtlWakeAddressAll( + IN PVOID Address) +{ + KexRtlpWakeByAddress(Address, TRUE); +} \ No newline at end of file diff --git a/KexDll/rtlwow64.c b/KexDll/rtlwow64.c new file mode 100644 index 0000000..9082ea0 --- /dev/null +++ b/KexDll/rtlwow64.c @@ -0,0 +1,76 @@ +#include "buildcfg.h" +#include "kexdllp.h" + +KEXAPI NTSTATUS NTAPI KexRtlWow64GetProcessMachines( + IN HANDLE ProcessHandle, + OUT PUSHORT ProcessMachine, + OUT PUSHORT NativeMachine OPTIONAL) +{ + NTSTATUS Status; + + // + // The KexRtlOperatingSystemBitness macro checks a field in SharedUserData in order + // to determine whether the operating system is 64-bit or 32-bit (independently of + // whether this is a WOW64 process or not). + // + + if (KexRtlOperatingSystemBitness() == 64) { + // + // The OS is 64 bit. Processes can be either 32 bit or 64 bit. + // + + if (ProcessHandle == NtCurrentProcess()) { + // + // We know the bitness of the current process because we know at + // compile time whether we are running as 32-bit code or 64-bit code. + // There is no need to ask the kernel. + // + + if (KexIs64BitBuild) { + *ProcessMachine = IMAGE_FILE_MACHINE_AMD64; + } else { + *ProcessMachine = IMAGE_FILE_MACHINE_I386; + } + } else { + ULONG_PTR AddressOf32BitPeb; + + // + // We know the OS is 64-bit, but we want to see if another process is 32-bit. + // We need to query the kernel to see whether that process is WOW64. + // + + Status = NtQueryInformationProcess( + ProcessHandle, + ProcessWow64Information, + &AddressOf32BitPeb, + sizeof(AddressOf32BitPeb), + NULL); + + if (!NT_SUCCESS(Status)) { + return Status; + } + + if (ProcessWow64Information) { + *ProcessMachine = IMAGE_FILE_MACHINE_I386; + } else { + *ProcessMachine = IMAGE_FILE_MACHINE_AMD64; + } + } + + if (NativeMachine != NULL) { + *NativeMachine = IMAGE_FILE_MACHINE_AMD64; + } + } else { + // + // The OS is 32 bit, so everything must be 32 bit. No need to check anything. + // + + *ProcessMachine = IMAGE_FILE_MACHINE_I386; + + if (NativeMachine != NULL) { + *NativeMachine = IMAGE_FILE_MACHINE_I386; + } + } + + return STATUS_SUCCESS; +} \ No newline at end of file diff --git a/KexDll/status.c b/KexDll/status.c new file mode 100644 index 0000000..f43507c --- /dev/null +++ b/KexDll/status.c @@ -0,0 +1,1939 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// status.c +// +// Abstract: +// +// Contains routines for translating NTSTATUS codes into human-readable +// text. +// +// Author: +// +// vxiiduu (01-Jan-2023) +// +// Revision History: +// +// vxiiduu 01-Jan-2023 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kexdllp.h" + +PCWSTR NTAPI KexRtlNtStatusToString( + IN NTSTATUS Status) +{ + switch (Status) { + // + // VxKex specific status codes + // + + case STATUS_USER_DISABLED: return L"STATUS_USER_DISABLED"; + case STATUS_ALREADY_INITIALIZED: return L"STATUS_ALREADY_INITIALIZED"; + case STATUS_ALREADY_CONNECTED: return L"STATUS_ALREADY_CONNECTED"; + + case STATUS_IMAGE_NO_IMPORT_DIRECTORY: return L"STATUS_IMAGE_NO_IMPORT_DIRECTORY"; + case STATUS_STRING_MAPPER_ENTRY_NOT_FOUND: return L"STATUS_STRING_MAPPER_ENTRY_NOT_FOUND"; + case STATUS_REG_DATA_TYPE_MISMATCH: return L"STATUS_REG_DATA_TYPE_MISMATCH"; + case STATUS_KEXDLL_INITIALIZATION_FAILURE: return L"STATUS_KEXDLL_INITIALIZATION_FAILURE"; + case STATUS_VERSION_MISMATCH: return L"STATUS_VERSION_MISMATCH"; + case STATUS_SOURCE_APPLICATION_MISMATCH: return L"STATUS_SOURCE_APPLICATION_MISMATCH"; + case STATUS_TOO_MANY_INDICES: return L"STATUS_TOO_MANY_INDICES"; + case STATUS_INVALID_OPEN_MODE: return L"STATUS_INVALID_OPEN_MODE"; + case STATUS_KEXDATA_NOT_INITIALIZED: return L"STATUS_KEXDATA_NOT_INITIALIZED"; + case STATUS_KEXSETUP_FAILURE: return L"STATUS_KEXSETUP_FAILURE"; + case STATUS_IMAGE_SECTION_NOT_FOUND: return L"STATUS_IMAGE_SECTION_NOT_FOUND"; + case STATUS_DLL_NOT_IN_SYSTEM_ROOT: return L"STATUS_DLL_NOT_IN_SYSTEM_ROOT"; + + // + // All this other stuff is auto generated with a powershell script + // from ntstatus.h, no need to touch it + // + + case STATUS_SUCCESS: return L"STATUS_SUCCESS"; + case STATUS_WAIT_1: return L"STATUS_WAIT_1"; + case STATUS_WAIT_2: return L"STATUS_WAIT_2"; + case STATUS_WAIT_3: return L"STATUS_WAIT_3"; + case STATUS_WAIT_63: return L"STATUS_WAIT_63"; + case STATUS_ABANDONED: return L"STATUS_ABANDONED"; + case STATUS_ABANDONED_WAIT_63: return L"STATUS_ABANDONED_WAIT_63"; + case STATUS_USER_APC: return L"STATUS_USER_APC"; + case STATUS_KERNEL_APC: return L"STATUS_KERNEL_APC"; + case STATUS_ALERTED: return L"STATUS_ALERTED"; + case STATUS_TIMEOUT: return L"STATUS_TIMEOUT"; + case STATUS_PENDING: return L"STATUS_PENDING"; + case STATUS_REPARSE: return L"STATUS_REPARSE"; + case STATUS_MORE_ENTRIES: return L"STATUS_MORE_ENTRIES"; + case STATUS_NOT_ALL_ASSIGNED: return L"STATUS_NOT_ALL_ASSIGNED"; + case STATUS_SOME_NOT_MAPPED: return L"STATUS_SOME_NOT_MAPPED"; + case STATUS_OPLOCK_BREAK_IN_PROGRESS: return L"STATUS_OPLOCK_BREAK_IN_PROGRESS"; + case STATUS_VOLUME_MOUNTED: return L"STATUS_VOLUME_MOUNTED"; + case STATUS_RXACT_COMMITTED: return L"STATUS_RXACT_COMMITTED"; + case STATUS_NOTIFY_CLEANUP: return L"STATUS_NOTIFY_CLEANUP"; + case STATUS_NOTIFY_ENUM_DIR: return L"STATUS_NOTIFY_ENUM_DIR"; + case STATUS_NO_QUOTAS_FOR_ACCOUNT: return L"STATUS_NO_QUOTAS_FOR_ACCOUNT"; + case STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED: return L"STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED"; + case STATUS_PAGE_FAULT_TRANSITION: return L"STATUS_PAGE_FAULT_TRANSITION"; + case STATUS_PAGE_FAULT_DEMAND_ZERO: return L"STATUS_PAGE_FAULT_DEMAND_ZERO"; + case STATUS_PAGE_FAULT_COPY_ON_WRITE: return L"STATUS_PAGE_FAULT_COPY_ON_WRITE"; + case STATUS_PAGE_FAULT_GUARD_PAGE: return L"STATUS_PAGE_FAULT_GUARD_PAGE"; + case STATUS_PAGE_FAULT_PAGING_FILE: return L"STATUS_PAGE_FAULT_PAGING_FILE"; + case STATUS_CACHE_PAGE_LOCKED: return L"STATUS_CACHE_PAGE_LOCKED"; + case STATUS_CRASH_DUMP: return L"STATUS_CRASH_DUMP"; + case STATUS_BUFFER_ALL_ZEROS: return L"STATUS_BUFFER_ALL_ZEROS"; + case STATUS_REPARSE_OBJECT: return L"STATUS_REPARSE_OBJECT"; + case STATUS_RESOURCE_REQUIREMENTS_CHANGED: return L"STATUS_RESOURCE_REQUIREMENTS_CHANGED"; + case STATUS_TRANSLATION_COMPLETE: return L"STATUS_TRANSLATION_COMPLETE"; + case STATUS_DS_MEMBERSHIP_EVALUATED_LOCALLY: return L"STATUS_DS_MEMBERSHIP_EVALUATED_LOCALLY"; + case STATUS_NOTHING_TO_TERMINATE: return L"STATUS_NOTHING_TO_TERMINATE"; + case STATUS_PROCESS_NOT_IN_JOB: return L"STATUS_PROCESS_NOT_IN_JOB"; + case STATUS_PROCESS_IN_JOB: return L"STATUS_PROCESS_IN_JOB"; + case STATUS_VOLSNAP_HIBERNATE_READY: return L"STATUS_VOLSNAP_HIBERNATE_READY"; + case STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY: return L"STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY"; + case STATUS_INTERRUPT_VECTOR_ALREADY_CONNECTED: return L"STATUS_INTERRUPT_VECTOR_ALREADY_CONNECTED"; + case STATUS_INTERRUPT_STILL_CONNECTED: return L"STATUS_INTERRUPT_STILL_CONNECTED"; + case STATUS_PROCESS_CLONED: return L"STATUS_PROCESS_CLONED"; + case STATUS_FILE_LOCKED_WITH_ONLY_READERS: return L"STATUS_FILE_LOCKED_WITH_ONLY_READERS"; + case STATUS_FILE_LOCKED_WITH_WRITERS: return L"STATUS_FILE_LOCKED_WITH_WRITERS"; + case STATUS_RESOURCEMANAGER_READ_ONLY: return L"STATUS_RESOURCEMANAGER_READ_ONLY"; + case STATUS_RING_PREVIOUSLY_EMPTY: return L"STATUS_RING_PREVIOUSLY_EMPTY"; + case STATUS_RING_PREVIOUSLY_FULL: return L"STATUS_RING_PREVIOUSLY_FULL"; + case STATUS_RING_PREVIOUSLY_ABOVE_QUOTA: return L"STATUS_RING_PREVIOUSLY_ABOVE_QUOTA"; + case STATUS_RING_NEWLY_EMPTY: return L"STATUS_RING_NEWLY_EMPTY"; + case STATUS_RING_SIGNAL_OPPOSITE_ENDPOINT: return L"STATUS_RING_SIGNAL_OPPOSITE_ENDPOINT"; + case STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE: return L"STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE"; + case STATUS_OPLOCK_HANDLE_CLOSED: return L"STATUS_OPLOCK_HANDLE_CLOSED"; + case STATUS_WAIT_FOR_OPLOCK: return L"STATUS_WAIT_FOR_OPLOCK"; + case STATUS_FLT_IO_COMPLETE: return L"STATUS_FLT_IO_COMPLETE"; + case STATUS_DIS_ATTRIBUTE_BUILT: return L"STATUS_DIS_ATTRIBUTE_BUILT"; + case STATUS_OBJECT_NAME_EXISTS: return L"STATUS_OBJECT_NAME_EXISTS"; + case STATUS_THREAD_WAS_SUSPENDED: return L"STATUS_THREAD_WAS_SUSPENDED"; + case STATUS_WORKING_SET_LIMIT_RANGE: return L"STATUS_WORKING_SET_LIMIT_RANGE"; + case STATUS_IMAGE_NOT_AT_BASE: return L"STATUS_IMAGE_NOT_AT_BASE"; + case STATUS_RXACT_STATE_CREATED: return L"STATUS_RXACT_STATE_CREATED"; + case STATUS_SEGMENT_NOTIFICATION: return L"STATUS_SEGMENT_NOTIFICATION"; + case STATUS_LOCAL_USER_SESSION_KEY: return L"STATUS_LOCAL_USER_SESSION_KEY"; + case STATUS_BAD_CURRENT_DIRECTORY: return L"STATUS_BAD_CURRENT_DIRECTORY"; + case STATUS_SERIAL_MORE_WRITES: return L"STATUS_SERIAL_MORE_WRITES"; + case STATUS_REGISTRY_RECOVERED: return L"STATUS_REGISTRY_RECOVERED"; + case STATUS_FT_READ_RECOVERY_FROM_BACKUP: return L"STATUS_FT_READ_RECOVERY_FROM_BACKUP"; + case STATUS_FT_WRITE_RECOVERY: return L"STATUS_FT_WRITE_RECOVERY"; + case STATUS_SERIAL_COUNTER_TIMEOUT: return L"STATUS_SERIAL_COUNTER_TIMEOUT"; + case STATUS_NULL_LM_PASSWORD: return L"STATUS_NULL_LM_PASSWORD"; + case STATUS_IMAGE_MACHINE_TYPE_MISMATCH: return L"STATUS_IMAGE_MACHINE_TYPE_MISMATCH"; + case STATUS_RECEIVE_PARTIAL: return L"STATUS_RECEIVE_PARTIAL"; + case STATUS_RECEIVE_EXPEDITED: return L"STATUS_RECEIVE_EXPEDITED"; + case STATUS_RECEIVE_PARTIAL_EXPEDITED: return L"STATUS_RECEIVE_PARTIAL_EXPEDITED"; + case STATUS_EVENT_DONE: return L"STATUS_EVENT_DONE"; + case STATUS_EVENT_PENDING: return L"STATUS_EVENT_PENDING"; + case STATUS_CHECKING_FILE_SYSTEM: return L"STATUS_CHECKING_FILE_SYSTEM"; + case STATUS_FATAL_APP_EXIT: return L"STATUS_FATAL_APP_EXIT"; + case STATUS_PREDEFINED_HANDLE: return L"STATUS_PREDEFINED_HANDLE"; + case STATUS_WAS_UNLOCKED: return L"STATUS_WAS_UNLOCKED"; + case STATUS_SERVICE_NOTIFICATION: return L"STATUS_SERVICE_NOTIFICATION"; + case STATUS_WAS_LOCKED: return L"STATUS_WAS_LOCKED"; + case STATUS_LOG_HARD_ERROR: return L"STATUS_LOG_HARD_ERROR"; + case STATUS_ALREADY_WIN32: return L"STATUS_ALREADY_WIN32"; + case STATUS_WX86_UNSIMULATE: return L"STATUS_WX86_UNSIMULATE"; + case STATUS_WX86_CONTINUE: return L"STATUS_WX86_CONTINUE"; + case STATUS_WX86_SINGLE_STEP: return L"STATUS_WX86_SINGLE_STEP"; + case STATUS_WX86_BREAKPOINT: return L"STATUS_WX86_BREAKPOINT"; + case STATUS_WX86_EXCEPTION_CONTINUE: return L"STATUS_WX86_EXCEPTION_CONTINUE"; + case STATUS_WX86_EXCEPTION_LASTCHANCE: return L"STATUS_WX86_EXCEPTION_LASTCHANCE"; + case STATUS_WX86_EXCEPTION_CHAIN: return L"STATUS_WX86_EXCEPTION_CHAIN"; + case STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE: return L"STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE"; + case STATUS_NO_YIELD_PERFORMED: return L"STATUS_NO_YIELD_PERFORMED"; + case STATUS_TIMER_RESUME_IGNORED: return L"STATUS_TIMER_RESUME_IGNORED"; + case STATUS_ARBITRATION_UNHANDLED: return L"STATUS_ARBITRATION_UNHANDLED"; + case STATUS_CARDBUS_NOT_SUPPORTED: return L"STATUS_CARDBUS_NOT_SUPPORTED"; + case STATUS_WX86_CREATEWX86TIB: return L"STATUS_WX86_CREATEWX86TIB"; + case STATUS_MP_PROCESSOR_MISMATCH: return L"STATUS_MP_PROCESSOR_MISMATCH"; + case STATUS_HIBERNATED: return L"STATUS_HIBERNATED"; + case STATUS_RESUME_HIBERNATION: return L"STATUS_RESUME_HIBERNATION"; + case STATUS_FIRMWARE_UPDATED: return L"STATUS_FIRMWARE_UPDATED"; + case STATUS_DRIVERS_LEAKING_LOCKED_PAGES: return L"STATUS_DRIVERS_LEAKING_LOCKED_PAGES"; + case STATUS_MESSAGE_RETRIEVED: return L"STATUS_MESSAGE_RETRIEVED"; + case STATUS_SYSTEM_POWERSTATE_TRANSITION: return L"STATUS_SYSTEM_POWERSTATE_TRANSITION"; + case STATUS_ALPC_CHECK_COMPLETION_LIST: return L"STATUS_ALPC_CHECK_COMPLETION_LIST"; + case STATUS_SYSTEM_POWERSTATE_COMPLEX_TRANSITION: return L"STATUS_SYSTEM_POWERSTATE_COMPLEX_TRANSITION"; + case STATUS_ACCESS_AUDIT_BY_POLICY: return L"STATUS_ACCESS_AUDIT_BY_POLICY"; + case STATUS_ABANDON_HIBERFILE: return L"STATUS_ABANDON_HIBERFILE"; + case STATUS_BIZRULES_NOT_ENABLED: return L"STATUS_BIZRULES_NOT_ENABLED"; + case STATUS_HEURISTIC_DAMAGE_POSSIBLE: return L"STATUS_HEURISTIC_DAMAGE_POSSIBLE"; + case STATUS_GUARD_PAGE_VIOLATION: return L"STATUS_GUARD_PAGE_VIOLATION"; + case STATUS_DATATYPE_MISALIGNMENT: return L"STATUS_DATATYPE_MISALIGNMENT"; + case STATUS_BREAKPOINT: return L"STATUS_BREAKPOINT"; + case STATUS_SINGLE_STEP: return L"STATUS_SINGLE_STEP"; + case STATUS_BUFFER_OVERFLOW: return L"STATUS_BUFFER_OVERFLOW"; + case STATUS_NO_MORE_FILES: return L"STATUS_NO_MORE_FILES"; + case STATUS_WAKE_SYSTEM_DEBUGGER: return L"STATUS_WAKE_SYSTEM_DEBUGGER"; + case STATUS_HANDLES_CLOSED: return L"STATUS_HANDLES_CLOSED"; + case STATUS_NO_INHERITANCE: return L"STATUS_NO_INHERITANCE"; + case STATUS_GUID_SUBSTITUTION_MADE: return L"STATUS_GUID_SUBSTITUTION_MADE"; + case STATUS_PARTIAL_COPY: return L"STATUS_PARTIAL_COPY"; + case STATUS_DEVICE_PAPER_EMPTY: return L"STATUS_DEVICE_PAPER_EMPTY"; + case STATUS_DEVICE_POWERED_OFF: return L"STATUS_DEVICE_POWERED_OFF"; + case STATUS_DEVICE_OFF_LINE: return L"STATUS_DEVICE_OFF_LINE"; + case STATUS_DEVICE_BUSY: return L"STATUS_DEVICE_BUSY"; + case STATUS_NO_MORE_EAS: return L"STATUS_NO_MORE_EAS"; + case STATUS_INVALID_EA_NAME: return L"STATUS_INVALID_EA_NAME"; + case STATUS_EA_LIST_INCONSISTENT: return L"STATUS_EA_LIST_INCONSISTENT"; + case STATUS_INVALID_EA_FLAG: return L"STATUS_INVALID_EA_FLAG"; + case STATUS_VERIFY_REQUIRED: return L"STATUS_VERIFY_REQUIRED"; + case STATUS_EXTRANEOUS_INFORMATION: return L"STATUS_EXTRANEOUS_INFORMATION"; + case STATUS_RXACT_COMMIT_NECESSARY: return L"STATUS_RXACT_COMMIT_NECESSARY"; + case STATUS_NO_MORE_ENTRIES: return L"STATUS_NO_MORE_ENTRIES"; + case STATUS_FILEMARK_DETECTED: return L"STATUS_FILEMARK_DETECTED"; + case STATUS_MEDIA_CHANGED: return L"STATUS_MEDIA_CHANGED"; + case STATUS_BUS_RESET: return L"STATUS_BUS_RESET"; + case STATUS_END_OF_MEDIA: return L"STATUS_END_OF_MEDIA"; + case STATUS_BEGINNING_OF_MEDIA: return L"STATUS_BEGINNING_OF_MEDIA"; + case STATUS_MEDIA_CHECK: return L"STATUS_MEDIA_CHECK"; + case STATUS_SETMARK_DETECTED: return L"STATUS_SETMARK_DETECTED"; + case STATUS_NO_DATA_DETECTED: return L"STATUS_NO_DATA_DETECTED"; + case STATUS_REDIRECTOR_HAS_OPEN_HANDLES: return L"STATUS_REDIRECTOR_HAS_OPEN_HANDLES"; + case STATUS_SERVER_HAS_OPEN_HANDLES: return L"STATUS_SERVER_HAS_OPEN_HANDLES"; + case STATUS_ALREADY_DISCONNECTED: return L"STATUS_ALREADY_DISCONNECTED"; + case STATUS_LONGJUMP: return L"STATUS_LONGJUMP"; + case STATUS_CLEANER_CARTRIDGE_INSTALLED: return L"STATUS_CLEANER_CARTRIDGE_INSTALLED"; + case STATUS_PLUGPLAY_QUERY_VETOED: return L"STATUS_PLUGPLAY_QUERY_VETOED"; + case STATUS_UNWIND_CONSOLIDATE: return L"STATUS_UNWIND_CONSOLIDATE"; + case STATUS_REGISTRY_HIVE_RECOVERED: return L"STATUS_REGISTRY_HIVE_RECOVERED"; + case STATUS_DLL_MIGHT_BE_INSECURE: return L"STATUS_DLL_MIGHT_BE_INSECURE"; + case STATUS_DLL_MIGHT_BE_INCOMPATIBLE: return L"STATUS_DLL_MIGHT_BE_INCOMPATIBLE"; + case STATUS_STOPPED_ON_SYMLINK: return L"STATUS_STOPPED_ON_SYMLINK"; + case STATUS_CANNOT_GRANT_REQUESTED_OPLOCK: return L"STATUS_CANNOT_GRANT_REQUESTED_OPLOCK"; + case STATUS_NO_ACE_CONDITION: return L"STATUS_NO_ACE_CONDITION"; + case STATUS_CLUSTER_NODE_ALREADY_UP: return L"STATUS_CLUSTER_NODE_ALREADY_UP"; + case STATUS_CLUSTER_NODE_ALREADY_DOWN: return L"STATUS_CLUSTER_NODE_ALREADY_DOWN"; + case STATUS_CLUSTER_NETWORK_ALREADY_ONLINE: return L"STATUS_CLUSTER_NETWORK_ALREADY_ONLINE"; + case STATUS_CLUSTER_NETWORK_ALREADY_OFFLINE: return L"STATUS_CLUSTER_NETWORK_ALREADY_OFFLINE"; + case STATUS_CLUSTER_NODE_ALREADY_MEMBER: return L"STATUS_CLUSTER_NODE_ALREADY_MEMBER"; + case STATUS_FLT_BUFFER_TOO_SMALL: return L"STATUS_FLT_BUFFER_TOO_SMALL"; + case STATUS_FVE_PARTIAL_METADATA: return L"STATUS_FVE_PARTIAL_METADATA"; + case STATUS_FVE_TRANSIENT_STATE: return L"STATUS_FVE_TRANSIENT_STATE"; + case STATUS_UNSUCCESSFUL: return L"STATUS_UNSUCCESSFUL"; + case STATUS_NOT_IMPLEMENTED: return L"STATUS_NOT_IMPLEMENTED"; + case STATUS_INVALID_INFO_CLASS: return L"STATUS_INVALID_INFO_CLASS"; + case STATUS_INFO_LENGTH_MISMATCH: return L"STATUS_INFO_LENGTH_MISMATCH"; + case STATUS_ACCESS_VIOLATION: return L"STATUS_ACCESS_VIOLATION"; + case STATUS_IN_PAGE_ERROR: return L"STATUS_IN_PAGE_ERROR"; + case STATUS_PAGEFILE_QUOTA: return L"STATUS_PAGEFILE_QUOTA"; + case STATUS_INVALID_HANDLE: return L"STATUS_INVALID_HANDLE"; + case STATUS_BAD_INITIAL_STACK: return L"STATUS_BAD_INITIAL_STACK"; + case STATUS_BAD_INITIAL_PC: return L"STATUS_BAD_INITIAL_PC"; + case STATUS_INVALID_CID: return L"STATUS_INVALID_CID"; + case STATUS_TIMER_NOT_CANCELED: return L"STATUS_TIMER_NOT_CANCELED"; + case STATUS_INVALID_PARAMETER: return L"STATUS_INVALID_PARAMETER"; + case STATUS_NO_SUCH_DEVICE: return L"STATUS_NO_SUCH_DEVICE"; + case STATUS_NO_SUCH_FILE: return L"STATUS_NO_SUCH_FILE"; + case STATUS_INVALID_DEVICE_REQUEST: return L"STATUS_INVALID_DEVICE_REQUEST"; + case STATUS_END_OF_FILE: return L"STATUS_END_OF_FILE"; + case STATUS_WRONG_VOLUME: return L"STATUS_WRONG_VOLUME"; + case STATUS_NO_MEDIA_IN_DEVICE: return L"STATUS_NO_MEDIA_IN_DEVICE"; + case STATUS_UNRECOGNIZED_MEDIA: return L"STATUS_UNRECOGNIZED_MEDIA"; + case STATUS_NONEXISTENT_SECTOR: return L"STATUS_NONEXISTENT_SECTOR"; + case STATUS_MORE_PROCESSING_REQUIRED: return L"STATUS_MORE_PROCESSING_REQUIRED"; + case STATUS_NO_MEMORY: return L"STATUS_NO_MEMORY"; + case STATUS_CONFLICTING_ADDRESSES: return L"STATUS_CONFLICTING_ADDRESSES"; + case STATUS_NOT_MAPPED_VIEW: return L"STATUS_NOT_MAPPED_VIEW"; + case STATUS_UNABLE_TO_FREE_VM: return L"STATUS_UNABLE_TO_FREE_VM"; + case STATUS_UNABLE_TO_DELETE_SECTION: return L"STATUS_UNABLE_TO_DELETE_SECTION"; + case STATUS_INVALID_SYSTEM_SERVICE: return L"STATUS_INVALID_SYSTEM_SERVICE"; + case STATUS_ILLEGAL_INSTRUCTION: return L"STATUS_ILLEGAL_INSTRUCTION"; + case STATUS_INVALID_LOCK_SEQUENCE: return L"STATUS_INVALID_LOCK_SEQUENCE"; + case STATUS_INVALID_VIEW_SIZE: return L"STATUS_INVALID_VIEW_SIZE"; + case STATUS_INVALID_FILE_FOR_SECTION: return L"STATUS_INVALID_FILE_FOR_SECTION"; + case STATUS_ALREADY_COMMITTED: return L"STATUS_ALREADY_COMMITTED"; + case STATUS_ACCESS_DENIED: return L"STATUS_ACCESS_DENIED"; + case STATUS_BUFFER_TOO_SMALL: return L"STATUS_BUFFER_TOO_SMALL"; + case STATUS_OBJECT_TYPE_MISMATCH: return L"STATUS_OBJECT_TYPE_MISMATCH"; + case STATUS_NONCONTINUABLE_EXCEPTION: return L"STATUS_NONCONTINUABLE_EXCEPTION"; + case STATUS_INVALID_DISPOSITION: return L"STATUS_INVALID_DISPOSITION"; + case STATUS_UNWIND: return L"STATUS_UNWIND"; + case STATUS_BAD_STACK: return L"STATUS_BAD_STACK"; + case STATUS_INVALID_UNWIND_TARGET: return L"STATUS_INVALID_UNWIND_TARGET"; + case STATUS_NOT_LOCKED: return L"STATUS_NOT_LOCKED"; + case STATUS_PARITY_ERROR: return L"STATUS_PARITY_ERROR"; + case STATUS_UNABLE_TO_DECOMMIT_VM: return L"STATUS_UNABLE_TO_DECOMMIT_VM"; + case STATUS_NOT_COMMITTED: return L"STATUS_NOT_COMMITTED"; + case STATUS_INVALID_PORT_ATTRIBUTES: return L"STATUS_INVALID_PORT_ATTRIBUTES"; + case STATUS_PORT_MESSAGE_TOO_LONG: return L"STATUS_PORT_MESSAGE_TOO_LONG"; + case STATUS_INVALID_PARAMETER_MIX: return L"STATUS_INVALID_PARAMETER_MIX"; + case STATUS_INVALID_QUOTA_LOWER: return L"STATUS_INVALID_QUOTA_LOWER"; + case STATUS_DISK_CORRUPT_ERROR: return L"STATUS_DISK_CORRUPT_ERROR"; + case STATUS_OBJECT_NAME_INVALID: return L"STATUS_OBJECT_NAME_INVALID"; + case STATUS_OBJECT_NAME_NOT_FOUND: return L"STATUS_OBJECT_NAME_NOT_FOUND"; + case STATUS_OBJECT_NAME_COLLISION: return L"STATUS_OBJECT_NAME_COLLISION"; + case STATUS_PORT_DISCONNECTED: return L"STATUS_PORT_DISCONNECTED"; + case STATUS_DEVICE_ALREADY_ATTACHED: return L"STATUS_DEVICE_ALREADY_ATTACHED"; + case STATUS_OBJECT_PATH_INVALID: return L"STATUS_OBJECT_PATH_INVALID"; + case STATUS_OBJECT_PATH_NOT_FOUND: return L"STATUS_OBJECT_PATH_NOT_FOUND"; + case STATUS_OBJECT_PATH_SYNTAX_BAD: return L"STATUS_OBJECT_PATH_SYNTAX_BAD"; + case STATUS_DATA_OVERRUN: return L"STATUS_DATA_OVERRUN"; + case STATUS_DATA_LATE_ERROR: return L"STATUS_DATA_LATE_ERROR"; + case STATUS_DATA_ERROR: return L"STATUS_DATA_ERROR"; + case STATUS_CRC_ERROR: return L"STATUS_CRC_ERROR"; + case STATUS_SECTION_TOO_BIG: return L"STATUS_SECTION_TOO_BIG"; + case STATUS_PORT_CONNECTION_REFUSED: return L"STATUS_PORT_CONNECTION_REFUSED"; + case STATUS_INVALID_PORT_HANDLE: return L"STATUS_INVALID_PORT_HANDLE"; + case STATUS_SHARING_VIOLATION: return L"STATUS_SHARING_VIOLATION"; + case STATUS_QUOTA_EXCEEDED: return L"STATUS_QUOTA_EXCEEDED"; + case STATUS_INVALID_PAGE_PROTECTION: return L"STATUS_INVALID_PAGE_PROTECTION"; + case STATUS_MUTANT_NOT_OWNED: return L"STATUS_MUTANT_NOT_OWNED"; + case STATUS_SEMAPHORE_LIMIT_EXCEEDED: return L"STATUS_SEMAPHORE_LIMIT_EXCEEDED"; + case STATUS_PORT_ALREADY_SET: return L"STATUS_PORT_ALREADY_SET"; + case STATUS_SECTION_NOT_IMAGE: return L"STATUS_SECTION_NOT_IMAGE"; + case STATUS_SUSPEND_COUNT_EXCEEDED: return L"STATUS_SUSPEND_COUNT_EXCEEDED"; + case STATUS_THREAD_IS_TERMINATING: return L"STATUS_THREAD_IS_TERMINATING"; + case STATUS_BAD_WORKING_SET_LIMIT: return L"STATUS_BAD_WORKING_SET_LIMIT"; + case STATUS_INCOMPATIBLE_FILE_MAP: return L"STATUS_INCOMPATIBLE_FILE_MAP"; + case STATUS_SECTION_PROTECTION: return L"STATUS_SECTION_PROTECTION"; + case STATUS_EAS_NOT_SUPPORTED: return L"STATUS_EAS_NOT_SUPPORTED"; + case STATUS_EA_TOO_LARGE: return L"STATUS_EA_TOO_LARGE"; + case STATUS_NONEXISTENT_EA_ENTRY: return L"STATUS_NONEXISTENT_EA_ENTRY"; + case STATUS_NO_EAS_ON_FILE: return L"STATUS_NO_EAS_ON_FILE"; + case STATUS_EA_CORRUPT_ERROR: return L"STATUS_EA_CORRUPT_ERROR"; + case STATUS_FILE_LOCK_CONFLICT: return L"STATUS_FILE_LOCK_CONFLICT"; + case STATUS_LOCK_NOT_GRANTED: return L"STATUS_LOCK_NOT_GRANTED"; + case STATUS_DELETE_PENDING: return L"STATUS_DELETE_PENDING"; + case STATUS_CTL_FILE_NOT_SUPPORTED: return L"STATUS_CTL_FILE_NOT_SUPPORTED"; + case STATUS_UNKNOWN_REVISION: return L"STATUS_UNKNOWN_REVISION"; + case STATUS_REVISION_MISMATCH: return L"STATUS_REVISION_MISMATCH"; + case STATUS_INVALID_OWNER: return L"STATUS_INVALID_OWNER"; + case STATUS_INVALID_PRIMARY_GROUP: return L"STATUS_INVALID_PRIMARY_GROUP"; + case STATUS_NO_IMPERSONATION_TOKEN: return L"STATUS_NO_IMPERSONATION_TOKEN"; + case STATUS_CANT_DISABLE_MANDATORY: return L"STATUS_CANT_DISABLE_MANDATORY"; + case STATUS_NO_LOGON_SERVERS: return L"STATUS_NO_LOGON_SERVERS"; + case STATUS_NO_SUCH_LOGON_SESSION: return L"STATUS_NO_SUCH_LOGON_SESSION"; + case STATUS_NO_SUCH_PRIVILEGE: return L"STATUS_NO_SUCH_PRIVILEGE"; + case STATUS_PRIVILEGE_NOT_HELD: return L"STATUS_PRIVILEGE_NOT_HELD"; + case STATUS_INVALID_ACCOUNT_NAME: return L"STATUS_INVALID_ACCOUNT_NAME"; + case STATUS_USER_EXISTS: return L"STATUS_USER_EXISTS"; + case STATUS_NO_SUCH_USER: return L"STATUS_NO_SUCH_USER"; + case STATUS_GROUP_EXISTS: return L"STATUS_GROUP_EXISTS"; + case STATUS_NO_SUCH_GROUP: return L"STATUS_NO_SUCH_GROUP"; + case STATUS_MEMBER_IN_GROUP: return L"STATUS_MEMBER_IN_GROUP"; + case STATUS_MEMBER_NOT_IN_GROUP: return L"STATUS_MEMBER_NOT_IN_GROUP"; + case STATUS_LAST_ADMIN: return L"STATUS_LAST_ADMIN"; + case STATUS_WRONG_PASSWORD: return L"STATUS_WRONG_PASSWORD"; + case STATUS_ILL_FORMED_PASSWORD: return L"STATUS_ILL_FORMED_PASSWORD"; + case STATUS_PASSWORD_RESTRICTION: return L"STATUS_PASSWORD_RESTRICTION"; + case STATUS_LOGON_FAILURE: return L"STATUS_LOGON_FAILURE"; + case STATUS_ACCOUNT_RESTRICTION: return L"STATUS_ACCOUNT_RESTRICTION"; + case STATUS_INVALID_LOGON_HOURS: return L"STATUS_INVALID_LOGON_HOURS"; + case STATUS_INVALID_WORKSTATION: return L"STATUS_INVALID_WORKSTATION"; + case STATUS_PASSWORD_EXPIRED: return L"STATUS_PASSWORD_EXPIRED"; + case STATUS_ACCOUNT_DISABLED: return L"STATUS_ACCOUNT_DISABLED"; + case STATUS_NONE_MAPPED: return L"STATUS_NONE_MAPPED"; + case STATUS_TOO_MANY_LUIDS_REQUESTED: return L"STATUS_TOO_MANY_LUIDS_REQUESTED"; + case STATUS_LUIDS_EXHAUSTED: return L"STATUS_LUIDS_EXHAUSTED"; + case STATUS_INVALID_SUB_AUTHORITY: return L"STATUS_INVALID_SUB_AUTHORITY"; + case STATUS_INVALID_ACL: return L"STATUS_INVALID_ACL"; + case STATUS_INVALID_SID: return L"STATUS_INVALID_SID"; + case STATUS_INVALID_SECURITY_DESCR: return L"STATUS_INVALID_SECURITY_DESCR"; + case STATUS_PROCEDURE_NOT_FOUND: return L"STATUS_PROCEDURE_NOT_FOUND"; + case STATUS_INVALID_IMAGE_FORMAT: return L"STATUS_INVALID_IMAGE_FORMAT"; + case STATUS_NO_TOKEN: return L"STATUS_NO_TOKEN"; + case STATUS_BAD_INHERITANCE_ACL: return L"STATUS_BAD_INHERITANCE_ACL"; + case STATUS_RANGE_NOT_LOCKED: return L"STATUS_RANGE_NOT_LOCKED"; + case STATUS_DISK_FULL: return L"STATUS_DISK_FULL"; + case STATUS_SERVER_DISABLED: return L"STATUS_SERVER_DISABLED"; + case STATUS_SERVER_NOT_DISABLED: return L"STATUS_SERVER_NOT_DISABLED"; + case STATUS_TOO_MANY_GUIDS_REQUESTED: return L"STATUS_TOO_MANY_GUIDS_REQUESTED"; + case STATUS_GUIDS_EXHAUSTED: return L"STATUS_GUIDS_EXHAUSTED"; + case STATUS_INVALID_ID_AUTHORITY: return L"STATUS_INVALID_ID_AUTHORITY"; + case STATUS_AGENTS_EXHAUSTED: return L"STATUS_AGENTS_EXHAUSTED"; + case STATUS_INVALID_VOLUME_LABEL: return L"STATUS_INVALID_VOLUME_LABEL"; + case STATUS_SECTION_NOT_EXTENDED: return L"STATUS_SECTION_NOT_EXTENDED"; + case STATUS_NOT_MAPPED_DATA: return L"STATUS_NOT_MAPPED_DATA"; + case STATUS_RESOURCE_DATA_NOT_FOUND: return L"STATUS_RESOURCE_DATA_NOT_FOUND"; + case STATUS_RESOURCE_TYPE_NOT_FOUND: return L"STATUS_RESOURCE_TYPE_NOT_FOUND"; + case STATUS_RESOURCE_NAME_NOT_FOUND: return L"STATUS_RESOURCE_NAME_NOT_FOUND"; + case STATUS_ARRAY_BOUNDS_EXCEEDED: return L"STATUS_ARRAY_BOUNDS_EXCEEDED"; + case STATUS_FLOAT_DENORMAL_OPERAND: return L"STATUS_FLOAT_DENORMAL_OPERAND"; + case STATUS_FLOAT_DIVIDE_BY_ZERO: return L"STATUS_FLOAT_DIVIDE_BY_ZERO"; + case STATUS_FLOAT_INEXACT_RESULT: return L"STATUS_FLOAT_INEXACT_RESULT"; + case STATUS_FLOAT_INVALID_OPERATION: return L"STATUS_FLOAT_INVALID_OPERATION"; + case STATUS_FLOAT_OVERFLOW: return L"STATUS_FLOAT_OVERFLOW"; + case STATUS_FLOAT_STACK_CHECK: return L"STATUS_FLOAT_STACK_CHECK"; + case STATUS_FLOAT_UNDERFLOW: return L"STATUS_FLOAT_UNDERFLOW"; + case STATUS_INTEGER_DIVIDE_BY_ZERO: return L"STATUS_INTEGER_DIVIDE_BY_ZERO"; + case STATUS_INTEGER_OVERFLOW: return L"STATUS_INTEGER_OVERFLOW"; + case STATUS_PRIVILEGED_INSTRUCTION: return L"STATUS_PRIVILEGED_INSTRUCTION"; + case STATUS_TOO_MANY_PAGING_FILES: return L"STATUS_TOO_MANY_PAGING_FILES"; + case STATUS_FILE_INVALID: return L"STATUS_FILE_INVALID"; + case STATUS_ALLOTTED_SPACE_EXCEEDED: return L"STATUS_ALLOTTED_SPACE_EXCEEDED"; + case STATUS_INSUFFICIENT_RESOURCES: return L"STATUS_INSUFFICIENT_RESOURCES"; + case STATUS_DFS_EXIT_PATH_FOUND: return L"STATUS_DFS_EXIT_PATH_FOUND"; + case STATUS_DEVICE_DATA_ERROR: return L"STATUS_DEVICE_DATA_ERROR"; + case STATUS_DEVICE_NOT_CONNECTED: return L"STATUS_DEVICE_NOT_CONNECTED"; + case STATUS_DEVICE_POWER_FAILURE: return L"STATUS_DEVICE_POWER_FAILURE"; + case STATUS_FREE_VM_NOT_AT_BASE: return L"STATUS_FREE_VM_NOT_AT_BASE"; + case STATUS_MEMORY_NOT_ALLOCATED: return L"STATUS_MEMORY_NOT_ALLOCATED"; + case STATUS_WORKING_SET_QUOTA: return L"STATUS_WORKING_SET_QUOTA"; + case STATUS_MEDIA_WRITE_PROTECTED: return L"STATUS_MEDIA_WRITE_PROTECTED"; + case STATUS_DEVICE_NOT_READY: return L"STATUS_DEVICE_NOT_READY"; + case STATUS_INVALID_GROUP_ATTRIBUTES: return L"STATUS_INVALID_GROUP_ATTRIBUTES"; + case STATUS_BAD_IMPERSONATION_LEVEL: return L"STATUS_BAD_IMPERSONATION_LEVEL"; + case STATUS_CANT_OPEN_ANONYMOUS: return L"STATUS_CANT_OPEN_ANONYMOUS"; + case STATUS_BAD_VALIDATION_CLASS: return L"STATUS_BAD_VALIDATION_CLASS"; + case STATUS_BAD_TOKEN_TYPE: return L"STATUS_BAD_TOKEN_TYPE"; + case STATUS_BAD_MASTER_BOOT_RECORD: return L"STATUS_BAD_MASTER_BOOT_RECORD"; + case STATUS_INSTRUCTION_MISALIGNMENT: return L"STATUS_INSTRUCTION_MISALIGNMENT"; + case STATUS_INSTANCE_NOT_AVAILABLE: return L"STATUS_INSTANCE_NOT_AVAILABLE"; + case STATUS_PIPE_NOT_AVAILABLE: return L"STATUS_PIPE_NOT_AVAILABLE"; + case STATUS_INVALID_PIPE_STATE: return L"STATUS_INVALID_PIPE_STATE"; + case STATUS_PIPE_BUSY: return L"STATUS_PIPE_BUSY"; + case STATUS_ILLEGAL_FUNCTION: return L"STATUS_ILLEGAL_FUNCTION"; + case STATUS_PIPE_DISCONNECTED: return L"STATUS_PIPE_DISCONNECTED"; + case STATUS_PIPE_CLOSING: return L"STATUS_PIPE_CLOSING"; + case STATUS_PIPE_CONNECTED: return L"STATUS_PIPE_CONNECTED"; + case STATUS_PIPE_LISTENING: return L"STATUS_PIPE_LISTENING"; + case STATUS_INVALID_READ_MODE: return L"STATUS_INVALID_READ_MODE"; + case STATUS_IO_TIMEOUT: return L"STATUS_IO_TIMEOUT"; + case STATUS_FILE_FORCED_CLOSED: return L"STATUS_FILE_FORCED_CLOSED"; + case STATUS_PROFILING_NOT_STARTED: return L"STATUS_PROFILING_NOT_STARTED"; + case STATUS_PROFILING_NOT_STOPPED: return L"STATUS_PROFILING_NOT_STOPPED"; + case STATUS_COULD_NOT_INTERPRET: return L"STATUS_COULD_NOT_INTERPRET"; + case STATUS_FILE_IS_A_DIRECTORY: return L"STATUS_FILE_IS_A_DIRECTORY"; + case STATUS_NOT_SUPPORTED: return L"STATUS_NOT_SUPPORTED"; + case STATUS_REMOTE_NOT_LISTENING: return L"STATUS_REMOTE_NOT_LISTENING"; + case STATUS_DUPLICATE_NAME: return L"STATUS_DUPLICATE_NAME"; + case STATUS_BAD_NETWORK_PATH: return L"STATUS_BAD_NETWORK_PATH"; + case STATUS_NETWORK_BUSY: return L"STATUS_NETWORK_BUSY"; + case STATUS_DEVICE_DOES_NOT_EXIST: return L"STATUS_DEVICE_DOES_NOT_EXIST"; + case STATUS_TOO_MANY_COMMANDS: return L"STATUS_TOO_MANY_COMMANDS"; + case STATUS_ADAPTER_HARDWARE_ERROR: return L"STATUS_ADAPTER_HARDWARE_ERROR"; + case STATUS_INVALID_NETWORK_RESPONSE: return L"STATUS_INVALID_NETWORK_RESPONSE"; + case STATUS_UNEXPECTED_NETWORK_ERROR: return L"STATUS_UNEXPECTED_NETWORK_ERROR"; + case STATUS_BAD_REMOTE_ADAPTER: return L"STATUS_BAD_REMOTE_ADAPTER"; + case STATUS_PRINT_QUEUE_FULL: return L"STATUS_PRINT_QUEUE_FULL"; + case STATUS_NO_SPOOL_SPACE: return L"STATUS_NO_SPOOL_SPACE"; + case STATUS_PRINT_CANCELLED: return L"STATUS_PRINT_CANCELLED"; + case STATUS_NETWORK_NAME_DELETED: return L"STATUS_NETWORK_NAME_DELETED"; + case STATUS_NETWORK_ACCESS_DENIED: return L"STATUS_NETWORK_ACCESS_DENIED"; + case STATUS_BAD_DEVICE_TYPE: return L"STATUS_BAD_DEVICE_TYPE"; + case STATUS_BAD_NETWORK_NAME: return L"STATUS_BAD_NETWORK_NAME"; + case STATUS_TOO_MANY_NAMES: return L"STATUS_TOO_MANY_NAMES"; + case STATUS_TOO_MANY_SESSIONS: return L"STATUS_TOO_MANY_SESSIONS"; + case STATUS_SHARING_PAUSED: return L"STATUS_SHARING_PAUSED"; + case STATUS_REQUEST_NOT_ACCEPTED: return L"STATUS_REQUEST_NOT_ACCEPTED"; + case STATUS_REDIRECTOR_PAUSED: return L"STATUS_REDIRECTOR_PAUSED"; + case STATUS_NET_WRITE_FAULT: return L"STATUS_NET_WRITE_FAULT"; + case STATUS_PROFILING_AT_LIMIT: return L"STATUS_PROFILING_AT_LIMIT"; + case STATUS_NOT_SAME_DEVICE: return L"STATUS_NOT_SAME_DEVICE"; + case STATUS_FILE_RENAMED: return L"STATUS_FILE_RENAMED"; + case STATUS_VIRTUAL_CIRCUIT_CLOSED: return L"STATUS_VIRTUAL_CIRCUIT_CLOSED"; + case STATUS_NO_SECURITY_ON_OBJECT: return L"STATUS_NO_SECURITY_ON_OBJECT"; + case STATUS_CANT_WAIT: return L"STATUS_CANT_WAIT"; + case STATUS_PIPE_EMPTY: return L"STATUS_PIPE_EMPTY"; + case STATUS_CANT_ACCESS_DOMAIN_INFO: return L"STATUS_CANT_ACCESS_DOMAIN_INFO"; + case STATUS_CANT_TERMINATE_SELF: return L"STATUS_CANT_TERMINATE_SELF"; + case STATUS_INVALID_SERVER_STATE: return L"STATUS_INVALID_SERVER_STATE"; + case STATUS_INVALID_DOMAIN_STATE: return L"STATUS_INVALID_DOMAIN_STATE"; + case STATUS_INVALID_DOMAIN_ROLE: return L"STATUS_INVALID_DOMAIN_ROLE"; + case STATUS_NO_SUCH_DOMAIN: return L"STATUS_NO_SUCH_DOMAIN"; + case STATUS_DOMAIN_EXISTS: return L"STATUS_DOMAIN_EXISTS"; + case STATUS_DOMAIN_LIMIT_EXCEEDED: return L"STATUS_DOMAIN_LIMIT_EXCEEDED"; + case STATUS_OPLOCK_NOT_GRANTED: return L"STATUS_OPLOCK_NOT_GRANTED"; + case STATUS_INVALID_OPLOCK_PROTOCOL: return L"STATUS_INVALID_OPLOCK_PROTOCOL"; + case STATUS_INTERNAL_DB_CORRUPTION: return L"STATUS_INTERNAL_DB_CORRUPTION"; + case STATUS_INTERNAL_ERROR: return L"STATUS_INTERNAL_ERROR"; + case STATUS_GENERIC_NOT_MAPPED: return L"STATUS_GENERIC_NOT_MAPPED"; + case STATUS_BAD_DESCRIPTOR_FORMAT: return L"STATUS_BAD_DESCRIPTOR_FORMAT"; + case STATUS_INVALID_USER_BUFFER: return L"STATUS_INVALID_USER_BUFFER"; + case STATUS_UNEXPECTED_IO_ERROR: return L"STATUS_UNEXPECTED_IO_ERROR"; + case STATUS_UNEXPECTED_MM_CREATE_ERR: return L"STATUS_UNEXPECTED_MM_CREATE_ERR"; + case STATUS_UNEXPECTED_MM_MAP_ERROR: return L"STATUS_UNEXPECTED_MM_MAP_ERROR"; + case STATUS_UNEXPECTED_MM_EXTEND_ERR: return L"STATUS_UNEXPECTED_MM_EXTEND_ERR"; + case STATUS_NOT_LOGON_PROCESS: return L"STATUS_NOT_LOGON_PROCESS"; + case STATUS_LOGON_SESSION_EXISTS: return L"STATUS_LOGON_SESSION_EXISTS"; + case STATUS_INVALID_PARAMETER_1: return L"STATUS_INVALID_PARAMETER_1"; + case STATUS_INVALID_PARAMETER_2: return L"STATUS_INVALID_PARAMETER_2"; + case STATUS_INVALID_PARAMETER_3: return L"STATUS_INVALID_PARAMETER_3"; + case STATUS_INVALID_PARAMETER_4: return L"STATUS_INVALID_PARAMETER_4"; + case STATUS_INVALID_PARAMETER_5: return L"STATUS_INVALID_PARAMETER_5"; + case STATUS_INVALID_PARAMETER_6: return L"STATUS_INVALID_PARAMETER_6"; + case STATUS_INVALID_PARAMETER_7: return L"STATUS_INVALID_PARAMETER_7"; + case STATUS_INVALID_PARAMETER_8: return L"STATUS_INVALID_PARAMETER_8"; + case STATUS_INVALID_PARAMETER_9: return L"STATUS_INVALID_PARAMETER_9"; + case STATUS_INVALID_PARAMETER_10: return L"STATUS_INVALID_PARAMETER_10"; + case STATUS_INVALID_PARAMETER_11: return L"STATUS_INVALID_PARAMETER_11"; + case STATUS_INVALID_PARAMETER_12: return L"STATUS_INVALID_PARAMETER_12"; + case STATUS_REDIRECTOR_NOT_STARTED: return L"STATUS_REDIRECTOR_NOT_STARTED"; + case STATUS_REDIRECTOR_STARTED: return L"STATUS_REDIRECTOR_STARTED"; + case STATUS_STACK_OVERFLOW: return L"STATUS_STACK_OVERFLOW"; + case STATUS_NO_SUCH_PACKAGE: return L"STATUS_NO_SUCH_PACKAGE"; + case STATUS_BAD_FUNCTION_TABLE: return L"STATUS_BAD_FUNCTION_TABLE"; + case STATUS_VARIABLE_NOT_FOUND: return L"STATUS_VARIABLE_NOT_FOUND"; + case STATUS_DIRECTORY_NOT_EMPTY: return L"STATUS_DIRECTORY_NOT_EMPTY"; + case STATUS_FILE_CORRUPT_ERROR: return L"STATUS_FILE_CORRUPT_ERROR"; + case STATUS_NOT_A_DIRECTORY: return L"STATUS_NOT_A_DIRECTORY"; + case STATUS_BAD_LOGON_SESSION_STATE: return L"STATUS_BAD_LOGON_SESSION_STATE"; + case STATUS_LOGON_SESSION_COLLISION: return L"STATUS_LOGON_SESSION_COLLISION"; + case STATUS_NAME_TOO_LONG: return L"STATUS_NAME_TOO_LONG"; + case STATUS_FILES_OPEN: return L"STATUS_FILES_OPEN"; + case STATUS_CONNECTION_IN_USE: return L"STATUS_CONNECTION_IN_USE"; + case STATUS_MESSAGE_NOT_FOUND: return L"STATUS_MESSAGE_NOT_FOUND"; + case STATUS_PROCESS_IS_TERMINATING: return L"STATUS_PROCESS_IS_TERMINATING"; + case STATUS_INVALID_LOGON_TYPE: return L"STATUS_INVALID_LOGON_TYPE"; + case STATUS_NO_GUID_TRANSLATION: return L"STATUS_NO_GUID_TRANSLATION"; + case STATUS_CANNOT_IMPERSONATE: return L"STATUS_CANNOT_IMPERSONATE"; + case STATUS_IMAGE_ALREADY_LOADED: return L"STATUS_IMAGE_ALREADY_LOADED"; + case STATUS_ABIOS_NOT_PRESENT: return L"STATUS_ABIOS_NOT_PRESENT"; + case STATUS_ABIOS_LID_NOT_EXIST: return L"STATUS_ABIOS_LID_NOT_EXIST"; + case STATUS_ABIOS_LID_ALREADY_OWNED: return L"STATUS_ABIOS_LID_ALREADY_OWNED"; + case STATUS_ABIOS_NOT_LID_OWNER: return L"STATUS_ABIOS_NOT_LID_OWNER"; + case STATUS_ABIOS_INVALID_COMMAND: return L"STATUS_ABIOS_INVALID_COMMAND"; + case STATUS_ABIOS_INVALID_LID: return L"STATUS_ABIOS_INVALID_LID"; + case STATUS_ABIOS_SELECTOR_NOT_AVAILABLE: return L"STATUS_ABIOS_SELECTOR_NOT_AVAILABLE"; + case STATUS_ABIOS_INVALID_SELECTOR: return L"STATUS_ABIOS_INVALID_SELECTOR"; + case STATUS_NO_LDT: return L"STATUS_NO_LDT"; + case STATUS_INVALID_LDT_SIZE: return L"STATUS_INVALID_LDT_SIZE"; + case STATUS_INVALID_LDT_OFFSET: return L"STATUS_INVALID_LDT_OFFSET"; + case STATUS_INVALID_LDT_DESCRIPTOR: return L"STATUS_INVALID_LDT_DESCRIPTOR"; + case STATUS_INVALID_IMAGE_NE_FORMAT: return L"STATUS_INVALID_IMAGE_NE_FORMAT"; + case STATUS_RXACT_INVALID_STATE: return L"STATUS_RXACT_INVALID_STATE"; + case STATUS_RXACT_COMMIT_FAILURE: return L"STATUS_RXACT_COMMIT_FAILURE"; + case STATUS_MAPPED_FILE_SIZE_ZERO: return L"STATUS_MAPPED_FILE_SIZE_ZERO"; + case STATUS_TOO_MANY_OPENED_FILES: return L"STATUS_TOO_MANY_OPENED_FILES"; + case STATUS_CANCELLED: return L"STATUS_CANCELLED"; + case STATUS_CANNOT_DELETE: return L"STATUS_CANNOT_DELETE"; + case STATUS_INVALID_COMPUTER_NAME: return L"STATUS_INVALID_COMPUTER_NAME"; + case STATUS_FILE_DELETED: return L"STATUS_FILE_DELETED"; + case STATUS_SPECIAL_ACCOUNT: return L"STATUS_SPECIAL_ACCOUNT"; + case STATUS_SPECIAL_GROUP: return L"STATUS_SPECIAL_GROUP"; + case STATUS_SPECIAL_USER: return L"STATUS_SPECIAL_USER"; + case STATUS_MEMBERS_PRIMARY_GROUP: return L"STATUS_MEMBERS_PRIMARY_GROUP"; + case STATUS_FILE_CLOSED: return L"STATUS_FILE_CLOSED"; + case STATUS_TOO_MANY_THREADS: return L"STATUS_TOO_MANY_THREADS"; + case STATUS_THREAD_NOT_IN_PROCESS: return L"STATUS_THREAD_NOT_IN_PROCESS"; + case STATUS_TOKEN_ALREADY_IN_USE: return L"STATUS_TOKEN_ALREADY_IN_USE"; + case STATUS_PAGEFILE_QUOTA_EXCEEDED: return L"STATUS_PAGEFILE_QUOTA_EXCEEDED"; + case STATUS_COMMITMENT_LIMIT: return L"STATUS_COMMITMENT_LIMIT"; + case STATUS_INVALID_IMAGE_LE_FORMAT: return L"STATUS_INVALID_IMAGE_LE_FORMAT"; + case STATUS_INVALID_IMAGE_NOT_MZ: return L"STATUS_INVALID_IMAGE_NOT_MZ"; + case STATUS_INVALID_IMAGE_PROTECT: return L"STATUS_INVALID_IMAGE_PROTECT"; + case STATUS_INVALID_IMAGE_WIN_16: return L"STATUS_INVALID_IMAGE_WIN_16"; + case STATUS_LOGON_SERVER_CONFLICT: return L"STATUS_LOGON_SERVER_CONFLICT"; + case STATUS_TIME_DIFFERENCE_AT_DC: return L"STATUS_TIME_DIFFERENCE_AT_DC"; + case STATUS_SYNCHRONIZATION_REQUIRED: return L"STATUS_SYNCHRONIZATION_REQUIRED"; + case STATUS_DLL_NOT_FOUND: return L"STATUS_DLL_NOT_FOUND"; + case STATUS_OPEN_FAILED: return L"STATUS_OPEN_FAILED"; + case STATUS_IO_PRIVILEGE_FAILED: return L"STATUS_IO_PRIVILEGE_FAILED"; + case STATUS_ORDINAL_NOT_FOUND: return L"STATUS_ORDINAL_NOT_FOUND"; + case STATUS_ENTRYPOINT_NOT_FOUND: return L"STATUS_ENTRYPOINT_NOT_FOUND"; + case STATUS_CONTROL_C_EXIT: return L"STATUS_CONTROL_C_EXIT"; + case STATUS_LOCAL_DISCONNECT: return L"STATUS_LOCAL_DISCONNECT"; + case STATUS_REMOTE_DISCONNECT: return L"STATUS_REMOTE_DISCONNECT"; + case STATUS_REMOTE_RESOURCES: return L"STATUS_REMOTE_RESOURCES"; + case STATUS_LINK_FAILED: return L"STATUS_LINK_FAILED"; + case STATUS_LINK_TIMEOUT: return L"STATUS_LINK_TIMEOUT"; + case STATUS_INVALID_CONNECTION: return L"STATUS_INVALID_CONNECTION"; + case STATUS_INVALID_ADDRESS: return L"STATUS_INVALID_ADDRESS"; + case STATUS_DLL_INIT_FAILED: return L"STATUS_DLL_INIT_FAILED"; + case STATUS_MISSING_SYSTEMFILE: return L"STATUS_MISSING_SYSTEMFILE"; + case STATUS_UNHANDLED_EXCEPTION: return L"STATUS_UNHANDLED_EXCEPTION"; + case STATUS_APP_INIT_FAILURE: return L"STATUS_APP_INIT_FAILURE"; + case STATUS_PAGEFILE_CREATE_FAILED: return L"STATUS_PAGEFILE_CREATE_FAILED"; + case STATUS_NO_PAGEFILE: return L"STATUS_NO_PAGEFILE"; + case STATUS_INVALID_LEVEL: return L"STATUS_INVALID_LEVEL"; + case STATUS_WRONG_PASSWORD_CORE: return L"STATUS_WRONG_PASSWORD_CORE"; + case STATUS_ILLEGAL_FLOAT_CONTEXT: return L"STATUS_ILLEGAL_FLOAT_CONTEXT"; + case STATUS_PIPE_BROKEN: return L"STATUS_PIPE_BROKEN"; + case STATUS_REGISTRY_CORRUPT: return L"STATUS_REGISTRY_CORRUPT"; + case STATUS_REGISTRY_IO_FAILED: return L"STATUS_REGISTRY_IO_FAILED"; + case STATUS_NO_EVENT_PAIR: return L"STATUS_NO_EVENT_PAIR"; + case STATUS_UNRECOGNIZED_VOLUME: return L"STATUS_UNRECOGNIZED_VOLUME"; + case STATUS_SERIAL_NO_DEVICE_INITED: return L"STATUS_SERIAL_NO_DEVICE_INITED"; + case STATUS_NO_SUCH_ALIAS: return L"STATUS_NO_SUCH_ALIAS"; + case STATUS_MEMBER_NOT_IN_ALIAS: return L"STATUS_MEMBER_NOT_IN_ALIAS"; + case STATUS_MEMBER_IN_ALIAS: return L"STATUS_MEMBER_IN_ALIAS"; + case STATUS_ALIAS_EXISTS: return L"STATUS_ALIAS_EXISTS"; + case STATUS_LOGON_NOT_GRANTED: return L"STATUS_LOGON_NOT_GRANTED"; + case STATUS_TOO_MANY_SECRETS: return L"STATUS_TOO_MANY_SECRETS"; + case STATUS_SECRET_TOO_LONG: return L"STATUS_SECRET_TOO_LONG"; + case STATUS_INTERNAL_DB_ERROR: return L"STATUS_INTERNAL_DB_ERROR"; + case STATUS_FULLSCREEN_MODE: return L"STATUS_FULLSCREEN_MODE"; + case STATUS_TOO_MANY_CONTEXT_IDS: return L"STATUS_TOO_MANY_CONTEXT_IDS"; + case STATUS_LOGON_TYPE_NOT_GRANTED: return L"STATUS_LOGON_TYPE_NOT_GRANTED"; + case STATUS_NOT_REGISTRY_FILE: return L"STATUS_NOT_REGISTRY_FILE"; + case STATUS_NT_CROSS_ENCRYPTION_REQUIRED: return L"STATUS_NT_CROSS_ENCRYPTION_REQUIRED"; + case STATUS_DOMAIN_CTRLR_CONFIG_ERROR: return L"STATUS_DOMAIN_CTRLR_CONFIG_ERROR"; + case STATUS_FT_MISSING_MEMBER: return L"STATUS_FT_MISSING_MEMBER"; + case STATUS_ILL_FORMED_SERVICE_ENTRY: return L"STATUS_ILL_FORMED_SERVICE_ENTRY"; + case STATUS_ILLEGAL_CHARACTER: return L"STATUS_ILLEGAL_CHARACTER"; + case STATUS_UNMAPPABLE_CHARACTER: return L"STATUS_UNMAPPABLE_CHARACTER"; + case STATUS_UNDEFINED_CHARACTER: return L"STATUS_UNDEFINED_CHARACTER"; + case STATUS_FLOPPY_VOLUME: return L"STATUS_FLOPPY_VOLUME"; + case STATUS_FLOPPY_ID_MARK_NOT_FOUND: return L"STATUS_FLOPPY_ID_MARK_NOT_FOUND"; + case STATUS_FLOPPY_WRONG_CYLINDER: return L"STATUS_FLOPPY_WRONG_CYLINDER"; + case STATUS_FLOPPY_UNKNOWN_ERROR: return L"STATUS_FLOPPY_UNKNOWN_ERROR"; + case STATUS_FLOPPY_BAD_REGISTERS: return L"STATUS_FLOPPY_BAD_REGISTERS"; + case STATUS_DISK_RECALIBRATE_FAILED: return L"STATUS_DISK_RECALIBRATE_FAILED"; + case STATUS_DISK_OPERATION_FAILED: return L"STATUS_DISK_OPERATION_FAILED"; + case STATUS_DISK_RESET_FAILED: return L"STATUS_DISK_RESET_FAILED"; + case STATUS_SHARED_IRQ_BUSY: return L"STATUS_SHARED_IRQ_BUSY"; + case STATUS_FT_ORPHANING: return L"STATUS_FT_ORPHANING"; + case STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT: return L"STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT"; + case STATUS_PARTITION_FAILURE: return L"STATUS_PARTITION_FAILURE"; + case STATUS_INVALID_BLOCK_LENGTH: return L"STATUS_INVALID_BLOCK_LENGTH"; + case STATUS_DEVICE_NOT_PARTITIONED: return L"STATUS_DEVICE_NOT_PARTITIONED"; + case STATUS_UNABLE_TO_LOCK_MEDIA: return L"STATUS_UNABLE_TO_LOCK_MEDIA"; + case STATUS_UNABLE_TO_UNLOAD_MEDIA: return L"STATUS_UNABLE_TO_UNLOAD_MEDIA"; + case STATUS_EOM_OVERFLOW: return L"STATUS_EOM_OVERFLOW"; + case STATUS_NO_MEDIA: return L"STATUS_NO_MEDIA"; + case STATUS_NO_SUCH_MEMBER: return L"STATUS_NO_SUCH_MEMBER"; + case STATUS_INVALID_MEMBER: return L"STATUS_INVALID_MEMBER"; + case STATUS_KEY_DELETED: return L"STATUS_KEY_DELETED"; + case STATUS_NO_LOG_SPACE: return L"STATUS_NO_LOG_SPACE"; + case STATUS_TOO_MANY_SIDS: return L"STATUS_TOO_MANY_SIDS"; + case STATUS_LM_CROSS_ENCRYPTION_REQUIRED: return L"STATUS_LM_CROSS_ENCRYPTION_REQUIRED"; + case STATUS_KEY_HAS_CHILDREN: return L"STATUS_KEY_HAS_CHILDREN"; + case STATUS_CHILD_MUST_BE_VOLATILE: return L"STATUS_CHILD_MUST_BE_VOLATILE"; + case STATUS_DEVICE_CONFIGURATION_ERROR: return L"STATUS_DEVICE_CONFIGURATION_ERROR"; + case STATUS_DRIVER_INTERNAL_ERROR: return L"STATUS_DRIVER_INTERNAL_ERROR"; + case STATUS_INVALID_DEVICE_STATE: return L"STATUS_INVALID_DEVICE_STATE"; + case STATUS_IO_DEVICE_ERROR: return L"STATUS_IO_DEVICE_ERROR"; + case STATUS_DEVICE_PROTOCOL_ERROR: return L"STATUS_DEVICE_PROTOCOL_ERROR"; + case STATUS_BACKUP_CONTROLLER: return L"STATUS_BACKUP_CONTROLLER"; + case STATUS_LOG_FILE_FULL: return L"STATUS_LOG_FILE_FULL"; + case STATUS_TOO_LATE: return L"STATUS_TOO_LATE"; + case STATUS_NO_TRUST_LSA_SECRET: return L"STATUS_NO_TRUST_LSA_SECRET"; + case STATUS_NO_TRUST_SAM_ACCOUNT: return L"STATUS_NO_TRUST_SAM_ACCOUNT"; + case STATUS_TRUSTED_DOMAIN_FAILURE: return L"STATUS_TRUSTED_DOMAIN_FAILURE"; + case STATUS_TRUSTED_RELATIONSHIP_FAILURE: return L"STATUS_TRUSTED_RELATIONSHIP_FAILURE"; + case STATUS_EVENTLOG_FILE_CORRUPT: return L"STATUS_EVENTLOG_FILE_CORRUPT"; + case STATUS_EVENTLOG_CANT_START: return L"STATUS_EVENTLOG_CANT_START"; + case STATUS_TRUST_FAILURE: return L"STATUS_TRUST_FAILURE"; + case STATUS_MUTANT_LIMIT_EXCEEDED: return L"STATUS_MUTANT_LIMIT_EXCEEDED"; + case STATUS_NETLOGON_NOT_STARTED: return L"STATUS_NETLOGON_NOT_STARTED"; + case STATUS_ACCOUNT_EXPIRED: return L"STATUS_ACCOUNT_EXPIRED"; + case STATUS_POSSIBLE_DEADLOCK: return L"STATUS_POSSIBLE_DEADLOCK"; + case STATUS_NETWORK_CREDENTIAL_CONFLICT: return L"STATUS_NETWORK_CREDENTIAL_CONFLICT"; + case STATUS_REMOTE_SESSION_LIMIT: return L"STATUS_REMOTE_SESSION_LIMIT"; + case STATUS_EVENTLOG_FILE_CHANGED: return L"STATUS_EVENTLOG_FILE_CHANGED"; + case STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT: return L"STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT"; + case STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT: return L"STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT"; + case STATUS_NOLOGON_SERVER_TRUST_ACCOUNT: return L"STATUS_NOLOGON_SERVER_TRUST_ACCOUNT"; + case STATUS_DOMAIN_TRUST_INCONSISTENT: return L"STATUS_DOMAIN_TRUST_INCONSISTENT"; + case STATUS_FS_DRIVER_REQUIRED: return L"STATUS_FS_DRIVER_REQUIRED"; + case STATUS_IMAGE_ALREADY_LOADED_AS_DLL: return L"STATUS_IMAGE_ALREADY_LOADED_AS_DLL"; + case STATUS_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING: return L"STATUS_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING"; + case STATUS_SHORT_NAMES_NOT_ENABLED_ON_VOLUME: return L"STATUS_SHORT_NAMES_NOT_ENABLED_ON_VOLUME"; + case STATUS_SECURITY_STREAM_IS_INCONSISTENT: return L"STATUS_SECURITY_STREAM_IS_INCONSISTENT"; + case STATUS_INVALID_LOCK_RANGE: return L"STATUS_INVALID_LOCK_RANGE"; + case STATUS_INVALID_ACE_CONDITION: return L"STATUS_INVALID_ACE_CONDITION"; + case STATUS_IMAGE_SUBSYSTEM_NOT_PRESENT: return L"STATUS_IMAGE_SUBSYSTEM_NOT_PRESENT"; + case STATUS_NOTIFICATION_GUID_ALREADY_DEFINED: return L"STATUS_NOTIFICATION_GUID_ALREADY_DEFINED"; + case STATUS_NETWORK_OPEN_RESTRICTION: return L"STATUS_NETWORK_OPEN_RESTRICTION"; + case STATUS_NO_USER_SESSION_KEY: return L"STATUS_NO_USER_SESSION_KEY"; + case STATUS_USER_SESSION_DELETED: return L"STATUS_USER_SESSION_DELETED"; + case STATUS_RESOURCE_LANG_NOT_FOUND: return L"STATUS_RESOURCE_LANG_NOT_FOUND"; + case STATUS_INSUFF_SERVER_RESOURCES: return L"STATUS_INSUFF_SERVER_RESOURCES"; + case STATUS_INVALID_BUFFER_SIZE: return L"STATUS_INVALID_BUFFER_SIZE"; + case STATUS_INVALID_ADDRESS_COMPONENT: return L"STATUS_INVALID_ADDRESS_COMPONENT"; + case STATUS_INVALID_ADDRESS_WILDCARD: return L"STATUS_INVALID_ADDRESS_WILDCARD"; + case STATUS_TOO_MANY_ADDRESSES: return L"STATUS_TOO_MANY_ADDRESSES"; + case STATUS_ADDRESS_ALREADY_EXISTS: return L"STATUS_ADDRESS_ALREADY_EXISTS"; + case STATUS_ADDRESS_CLOSED: return L"STATUS_ADDRESS_CLOSED"; + case STATUS_CONNECTION_DISCONNECTED: return L"STATUS_CONNECTION_DISCONNECTED"; + case STATUS_CONNECTION_RESET: return L"STATUS_CONNECTION_RESET"; + case STATUS_TOO_MANY_NODES: return L"STATUS_TOO_MANY_NODES"; + case STATUS_TRANSACTION_ABORTED: return L"STATUS_TRANSACTION_ABORTED"; + case STATUS_TRANSACTION_TIMED_OUT: return L"STATUS_TRANSACTION_TIMED_OUT"; + case STATUS_TRANSACTION_NO_RELEASE: return L"STATUS_TRANSACTION_NO_RELEASE"; + case STATUS_TRANSACTION_NO_MATCH: return L"STATUS_TRANSACTION_NO_MATCH"; + case STATUS_TRANSACTION_RESPONDED: return L"STATUS_TRANSACTION_RESPONDED"; + case STATUS_TRANSACTION_INVALID_ID: return L"STATUS_TRANSACTION_INVALID_ID"; + case STATUS_TRANSACTION_INVALID_TYPE: return L"STATUS_TRANSACTION_INVALID_TYPE"; + case STATUS_NOT_SERVER_SESSION: return L"STATUS_NOT_SERVER_SESSION"; + case STATUS_NOT_CLIENT_SESSION: return L"STATUS_NOT_CLIENT_SESSION"; + case STATUS_CANNOT_LOAD_REGISTRY_FILE: return L"STATUS_CANNOT_LOAD_REGISTRY_FILE"; + case STATUS_DEBUG_ATTACH_FAILED: return L"STATUS_DEBUG_ATTACH_FAILED"; + case STATUS_SYSTEM_PROCESS_TERMINATED: return L"STATUS_SYSTEM_PROCESS_TERMINATED"; + case STATUS_DATA_NOT_ACCEPTED: return L"STATUS_DATA_NOT_ACCEPTED"; + case STATUS_NO_BROWSER_SERVERS_FOUND: return L"STATUS_NO_BROWSER_SERVERS_FOUND"; + case STATUS_VDM_HARD_ERROR: return L"STATUS_VDM_HARD_ERROR"; + case STATUS_DRIVER_CANCEL_TIMEOUT: return L"STATUS_DRIVER_CANCEL_TIMEOUT"; + case STATUS_REPLY_MESSAGE_MISMATCH: return L"STATUS_REPLY_MESSAGE_MISMATCH"; + case STATUS_MAPPED_ALIGNMENT: return L"STATUS_MAPPED_ALIGNMENT"; + case STATUS_IMAGE_CHECKSUM_MISMATCH: return L"STATUS_IMAGE_CHECKSUM_MISMATCH"; + case STATUS_LOST_WRITEBEHIND_DATA: return L"STATUS_LOST_WRITEBEHIND_DATA"; + case STATUS_CLIENT_SERVER_PARAMETERS_INVALID: return L"STATUS_CLIENT_SERVER_PARAMETERS_INVALID"; + case STATUS_PASSWORD_MUST_CHANGE: return L"STATUS_PASSWORD_MUST_CHANGE"; + case STATUS_NOT_FOUND: return L"STATUS_NOT_FOUND"; + case STATUS_NOT_TINY_STREAM: return L"STATUS_NOT_TINY_STREAM"; + case STATUS_RECOVERY_FAILURE: return L"STATUS_RECOVERY_FAILURE"; + case STATUS_STACK_OVERFLOW_READ: return L"STATUS_STACK_OVERFLOW_READ"; + case STATUS_FAIL_CHECK: return L"STATUS_FAIL_CHECK"; + case STATUS_DUPLICATE_OBJECTID: return L"STATUS_DUPLICATE_OBJECTID"; + case STATUS_OBJECTID_EXISTS: return L"STATUS_OBJECTID_EXISTS"; + case STATUS_CONVERT_TO_LARGE: return L"STATUS_CONVERT_TO_LARGE"; + case STATUS_RETRY: return L"STATUS_RETRY"; + case STATUS_FOUND_OUT_OF_SCOPE: return L"STATUS_FOUND_OUT_OF_SCOPE"; + case STATUS_ALLOCATE_BUCKET: return L"STATUS_ALLOCATE_BUCKET"; + case STATUS_PROPSET_NOT_FOUND: return L"STATUS_PROPSET_NOT_FOUND"; + case STATUS_MARSHALL_OVERFLOW: return L"STATUS_MARSHALL_OVERFLOW"; + case STATUS_INVALID_VARIANT: return L"STATUS_INVALID_VARIANT"; + case STATUS_DOMAIN_CONTROLLER_NOT_FOUND: return L"STATUS_DOMAIN_CONTROLLER_NOT_FOUND"; + case STATUS_ACCOUNT_LOCKED_OUT: return L"STATUS_ACCOUNT_LOCKED_OUT"; + case STATUS_HANDLE_NOT_CLOSABLE: return L"STATUS_HANDLE_NOT_CLOSABLE"; + case STATUS_CONNECTION_REFUSED: return L"STATUS_CONNECTION_REFUSED"; + case STATUS_GRACEFUL_DISCONNECT: return L"STATUS_GRACEFUL_DISCONNECT"; + case STATUS_ADDRESS_ALREADY_ASSOCIATED: return L"STATUS_ADDRESS_ALREADY_ASSOCIATED"; + case STATUS_ADDRESS_NOT_ASSOCIATED: return L"STATUS_ADDRESS_NOT_ASSOCIATED"; + case STATUS_CONNECTION_INVALID: return L"STATUS_CONNECTION_INVALID"; + case STATUS_CONNECTION_ACTIVE: return L"STATUS_CONNECTION_ACTIVE"; + case STATUS_NETWORK_UNREACHABLE: return L"STATUS_NETWORK_UNREACHABLE"; + case STATUS_HOST_UNREACHABLE: return L"STATUS_HOST_UNREACHABLE"; + case STATUS_PROTOCOL_UNREACHABLE: return L"STATUS_PROTOCOL_UNREACHABLE"; + case STATUS_PORT_UNREACHABLE: return L"STATUS_PORT_UNREACHABLE"; + case STATUS_REQUEST_ABORTED: return L"STATUS_REQUEST_ABORTED"; + case STATUS_CONNECTION_ABORTED: return L"STATUS_CONNECTION_ABORTED"; + case STATUS_BAD_COMPRESSION_BUFFER: return L"STATUS_BAD_COMPRESSION_BUFFER"; + case STATUS_USER_MAPPED_FILE: return L"STATUS_USER_MAPPED_FILE"; + case STATUS_AUDIT_FAILED: return L"STATUS_AUDIT_FAILED"; + case STATUS_TIMER_RESOLUTION_NOT_SET: return L"STATUS_TIMER_RESOLUTION_NOT_SET"; + case STATUS_CONNECTION_COUNT_LIMIT: return L"STATUS_CONNECTION_COUNT_LIMIT"; + case STATUS_LOGIN_TIME_RESTRICTION: return L"STATUS_LOGIN_TIME_RESTRICTION"; + case STATUS_LOGIN_WKSTA_RESTRICTION: return L"STATUS_LOGIN_WKSTA_RESTRICTION"; + case STATUS_IMAGE_MP_UP_MISMATCH: return L"STATUS_IMAGE_MP_UP_MISMATCH"; + case STATUS_INSUFFICIENT_LOGON_INFO: return L"STATUS_INSUFFICIENT_LOGON_INFO"; + case STATUS_BAD_DLL_ENTRYPOINT: return L"STATUS_BAD_DLL_ENTRYPOINT"; + case STATUS_BAD_SERVICE_ENTRYPOINT: return L"STATUS_BAD_SERVICE_ENTRYPOINT"; + case STATUS_LPC_REPLY_LOST: return L"STATUS_LPC_REPLY_LOST"; + case STATUS_IP_ADDRESS_CONFLICT1: return L"STATUS_IP_ADDRESS_CONFLICT1"; + case STATUS_IP_ADDRESS_CONFLICT2: return L"STATUS_IP_ADDRESS_CONFLICT2"; + case STATUS_REGISTRY_QUOTA_LIMIT: return L"STATUS_REGISTRY_QUOTA_LIMIT"; + case STATUS_PATH_NOT_COVERED: return L"STATUS_PATH_NOT_COVERED"; + case STATUS_NO_CALLBACK_ACTIVE: return L"STATUS_NO_CALLBACK_ACTIVE"; + case STATUS_LICENSE_QUOTA_EXCEEDED: return L"STATUS_LICENSE_QUOTA_EXCEEDED"; + case STATUS_PWD_TOO_SHORT: return L"STATUS_PWD_TOO_SHORT"; + case STATUS_PWD_TOO_RECENT: return L"STATUS_PWD_TOO_RECENT"; + case STATUS_PWD_HISTORY_CONFLICT: return L"STATUS_PWD_HISTORY_CONFLICT"; + case STATUS_PLUGPLAY_NO_DEVICE: return L"STATUS_PLUGPLAY_NO_DEVICE"; + case STATUS_UNSUPPORTED_COMPRESSION: return L"STATUS_UNSUPPORTED_COMPRESSION"; + case STATUS_INVALID_HW_PROFILE: return L"STATUS_INVALID_HW_PROFILE"; + case STATUS_INVALID_PLUGPLAY_DEVICE_PATH: return L"STATUS_INVALID_PLUGPLAY_DEVICE_PATH"; + case STATUS_DRIVER_ORDINAL_NOT_FOUND: return L"STATUS_DRIVER_ORDINAL_NOT_FOUND"; + case STATUS_DRIVER_ENTRYPOINT_NOT_FOUND: return L"STATUS_DRIVER_ENTRYPOINT_NOT_FOUND"; + case STATUS_RESOURCE_NOT_OWNED: return L"STATUS_RESOURCE_NOT_OWNED"; + case STATUS_TOO_MANY_LINKS: return L"STATUS_TOO_MANY_LINKS"; + case STATUS_QUOTA_LIST_INCONSISTENT: return L"STATUS_QUOTA_LIST_INCONSISTENT"; + case STATUS_FILE_IS_OFFLINE: return L"STATUS_FILE_IS_OFFLINE"; + case STATUS_EVALUATION_EXPIRATION: return L"STATUS_EVALUATION_EXPIRATION"; + case STATUS_ILLEGAL_DLL_RELOCATION: return L"STATUS_ILLEGAL_DLL_RELOCATION"; + case STATUS_LICENSE_VIOLATION: return L"STATUS_LICENSE_VIOLATION"; + case STATUS_DLL_INIT_FAILED_LOGOFF: return L"STATUS_DLL_INIT_FAILED_LOGOFF"; + case STATUS_DRIVER_UNABLE_TO_LOAD: return L"STATUS_DRIVER_UNABLE_TO_LOAD"; + case STATUS_DFS_UNAVAILABLE: return L"STATUS_DFS_UNAVAILABLE"; + case STATUS_VOLUME_DISMOUNTED: return L"STATUS_VOLUME_DISMOUNTED"; + case STATUS_WX86_INTERNAL_ERROR: return L"STATUS_WX86_INTERNAL_ERROR"; + case STATUS_WX86_FLOAT_STACK_CHECK: return L"STATUS_WX86_FLOAT_STACK_CHECK"; + case STATUS_VALIDATE_CONTINUE: return L"STATUS_VALIDATE_CONTINUE"; + case STATUS_NO_MATCH: return L"STATUS_NO_MATCH"; + case STATUS_NO_MORE_MATCHES: return L"STATUS_NO_MORE_MATCHES"; + case STATUS_NOT_A_REPARSE_POINT: return L"STATUS_NOT_A_REPARSE_POINT"; + case STATUS_IO_REPARSE_TAG_INVALID: return L"STATUS_IO_REPARSE_TAG_INVALID"; + case STATUS_IO_REPARSE_TAG_MISMATCH: return L"STATUS_IO_REPARSE_TAG_MISMATCH"; + case STATUS_IO_REPARSE_DATA_INVALID: return L"STATUS_IO_REPARSE_DATA_INVALID"; + case STATUS_IO_REPARSE_TAG_NOT_HANDLED: return L"STATUS_IO_REPARSE_TAG_NOT_HANDLED"; + case STATUS_REPARSE_POINT_NOT_RESOLVED: return L"STATUS_REPARSE_POINT_NOT_RESOLVED"; + case STATUS_DIRECTORY_IS_A_REPARSE_POINT: return L"STATUS_DIRECTORY_IS_A_REPARSE_POINT"; + case STATUS_RANGE_LIST_CONFLICT: return L"STATUS_RANGE_LIST_CONFLICT"; + case STATUS_SOURCE_ELEMENT_EMPTY: return L"STATUS_SOURCE_ELEMENT_EMPTY"; + case STATUS_DESTINATION_ELEMENT_FULL: return L"STATUS_DESTINATION_ELEMENT_FULL"; + case STATUS_ILLEGAL_ELEMENT_ADDRESS: return L"STATUS_ILLEGAL_ELEMENT_ADDRESS"; + case STATUS_MAGAZINE_NOT_PRESENT: return L"STATUS_MAGAZINE_NOT_PRESENT"; + case STATUS_REINITIALIZATION_NEEDED: return L"STATUS_REINITIALIZATION_NEEDED"; + case STATUS_DEVICE_REQUIRES_CLEANING: return L"STATUS_DEVICE_REQUIRES_CLEANING"; + case STATUS_DEVICE_DOOR_OPEN: return L"STATUS_DEVICE_DOOR_OPEN"; + case STATUS_ENCRYPTION_FAILED: return L"STATUS_ENCRYPTION_FAILED"; + case STATUS_DECRYPTION_FAILED: return L"STATUS_DECRYPTION_FAILED"; + case STATUS_RANGE_NOT_FOUND: return L"STATUS_RANGE_NOT_FOUND"; + case STATUS_NO_RECOVERY_POLICY: return L"STATUS_NO_RECOVERY_POLICY"; + case STATUS_NO_EFS: return L"STATUS_NO_EFS"; + case STATUS_WRONG_EFS: return L"STATUS_WRONG_EFS"; + case STATUS_NO_USER_KEYS: return L"STATUS_NO_USER_KEYS"; + case STATUS_FILE_NOT_ENCRYPTED: return L"STATUS_FILE_NOT_ENCRYPTED"; + case STATUS_NOT_EXPORT_FORMAT: return L"STATUS_NOT_EXPORT_FORMAT"; + case STATUS_FILE_ENCRYPTED: return L"STATUS_FILE_ENCRYPTED"; + case STATUS_WAKE_SYSTEM: return L"STATUS_WAKE_SYSTEM"; + case STATUS_WMI_GUID_NOT_FOUND: return L"STATUS_WMI_GUID_NOT_FOUND"; + case STATUS_WMI_INSTANCE_NOT_FOUND: return L"STATUS_WMI_INSTANCE_NOT_FOUND"; + case STATUS_WMI_ITEMID_NOT_FOUND: return L"STATUS_WMI_ITEMID_NOT_FOUND"; + case STATUS_WMI_TRY_AGAIN: return L"STATUS_WMI_TRY_AGAIN"; + case STATUS_SHARED_POLICY: return L"STATUS_SHARED_POLICY"; + case STATUS_POLICY_OBJECT_NOT_FOUND: return L"STATUS_POLICY_OBJECT_NOT_FOUND"; + case STATUS_POLICY_ONLY_IN_DS: return L"STATUS_POLICY_ONLY_IN_DS"; + case STATUS_VOLUME_NOT_UPGRADED: return L"STATUS_VOLUME_NOT_UPGRADED"; + case STATUS_REMOTE_STORAGE_NOT_ACTIVE: return L"STATUS_REMOTE_STORAGE_NOT_ACTIVE"; + case STATUS_REMOTE_STORAGE_MEDIA_ERROR: return L"STATUS_REMOTE_STORAGE_MEDIA_ERROR"; + case STATUS_NO_TRACKING_SERVICE: return L"STATUS_NO_TRACKING_SERVICE"; + case STATUS_SERVER_SID_MISMATCH: return L"STATUS_SERVER_SID_MISMATCH"; + case STATUS_DS_NO_ATTRIBUTE_OR_VALUE: return L"STATUS_DS_NO_ATTRIBUTE_OR_VALUE"; + case STATUS_DS_INVALID_ATTRIBUTE_SYNTAX: return L"STATUS_DS_INVALID_ATTRIBUTE_SYNTAX"; + case STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED: return L"STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED"; + case STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS: return L"STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS"; + case STATUS_DS_BUSY: return L"STATUS_DS_BUSY"; + case STATUS_DS_UNAVAILABLE: return L"STATUS_DS_UNAVAILABLE"; + case STATUS_DS_NO_RIDS_ALLOCATED: return L"STATUS_DS_NO_RIDS_ALLOCATED"; + case STATUS_DS_NO_MORE_RIDS: return L"STATUS_DS_NO_MORE_RIDS"; + case STATUS_DS_INCORRECT_ROLE_OWNER: return L"STATUS_DS_INCORRECT_ROLE_OWNER"; + case STATUS_DS_RIDMGR_INIT_ERROR: return L"STATUS_DS_RIDMGR_INIT_ERROR"; + case STATUS_DS_OBJ_CLASS_VIOLATION: return L"STATUS_DS_OBJ_CLASS_VIOLATION"; + case STATUS_DS_CANT_ON_NON_LEAF: return L"STATUS_DS_CANT_ON_NON_LEAF"; + case STATUS_DS_CANT_ON_RDN: return L"STATUS_DS_CANT_ON_RDN"; + case STATUS_DS_CANT_MOD_OBJ_CLASS: return L"STATUS_DS_CANT_MOD_OBJ_CLASS"; + case STATUS_DS_CROSS_DOM_MOVE_FAILED: return L"STATUS_DS_CROSS_DOM_MOVE_FAILED"; + case STATUS_DS_GC_NOT_AVAILABLE: return L"STATUS_DS_GC_NOT_AVAILABLE"; + case STATUS_DIRECTORY_SERVICE_REQUIRED: return L"STATUS_DIRECTORY_SERVICE_REQUIRED"; + case STATUS_REPARSE_ATTRIBUTE_CONFLICT: return L"STATUS_REPARSE_ATTRIBUTE_CONFLICT"; + case STATUS_CANT_ENABLE_DENY_ONLY: return L"STATUS_CANT_ENABLE_DENY_ONLY"; + case STATUS_FLOAT_MULTIPLE_FAULTS: return L"STATUS_FLOAT_MULTIPLE_FAULTS"; + case STATUS_FLOAT_MULTIPLE_TRAPS: return L"STATUS_FLOAT_MULTIPLE_TRAPS"; + case STATUS_DEVICE_REMOVED: return L"STATUS_DEVICE_REMOVED"; + case STATUS_JOURNAL_DELETE_IN_PROGRESS: return L"STATUS_JOURNAL_DELETE_IN_PROGRESS"; + case STATUS_JOURNAL_NOT_ACTIVE: return L"STATUS_JOURNAL_NOT_ACTIVE"; + case STATUS_NOINTERFACE: return L"STATUS_NOINTERFACE"; + case STATUS_DS_ADMIN_LIMIT_EXCEEDED: return L"STATUS_DS_ADMIN_LIMIT_EXCEEDED"; + case STATUS_DRIVER_FAILED_SLEEP: return L"STATUS_DRIVER_FAILED_SLEEP"; + case STATUS_MUTUAL_AUTHENTICATION_FAILED: return L"STATUS_MUTUAL_AUTHENTICATION_FAILED"; + case STATUS_CORRUPT_SYSTEM_FILE: return L"STATUS_CORRUPT_SYSTEM_FILE"; + case STATUS_DATATYPE_MISALIGNMENT_ERROR: return L"STATUS_DATATYPE_MISALIGNMENT_ERROR"; + case STATUS_WMI_READ_ONLY: return L"STATUS_WMI_READ_ONLY"; + case STATUS_WMI_SET_FAILURE: return L"STATUS_WMI_SET_FAILURE"; + case STATUS_COMMITMENT_MINIMUM: return L"STATUS_COMMITMENT_MINIMUM"; + case STATUS_REG_NAT_CONSUMPTION: return L"STATUS_REG_NAT_CONSUMPTION"; + case STATUS_TRANSPORT_FULL: return L"STATUS_TRANSPORT_FULL"; + case STATUS_DS_SAM_INIT_FAILURE: return L"STATUS_DS_SAM_INIT_FAILURE"; + case STATUS_ONLY_IF_CONNECTED: return L"STATUS_ONLY_IF_CONNECTED"; + case STATUS_DS_SENSITIVE_GROUP_VIOLATION: return L"STATUS_DS_SENSITIVE_GROUP_VIOLATION"; + case STATUS_PNP_RESTART_ENUMERATION: return L"STATUS_PNP_RESTART_ENUMERATION"; + case STATUS_JOURNAL_ENTRY_DELETED: return L"STATUS_JOURNAL_ENTRY_DELETED"; + case STATUS_DS_CANT_MOD_PRIMARYGROUPID: return L"STATUS_DS_CANT_MOD_PRIMARYGROUPID"; + case STATUS_SYSTEM_IMAGE_BAD_SIGNATURE: return L"STATUS_SYSTEM_IMAGE_BAD_SIGNATURE"; + case STATUS_PNP_REBOOT_REQUIRED: return L"STATUS_PNP_REBOOT_REQUIRED"; + case STATUS_POWER_STATE_INVALID: return L"STATUS_POWER_STATE_INVALID"; + case STATUS_DS_INVALID_GROUP_TYPE: return L"STATUS_DS_INVALID_GROUP_TYPE"; + case STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN: return L"STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN"; + case STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN: return L"STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN"; + case STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER: return L"STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER"; + case STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER: return L"STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER"; + case STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER: return L"STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER"; + case STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER: return L"STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER"; + case STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER: return L"STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER"; + case STATUS_DS_HAVE_PRIMARY_MEMBERS: return L"STATUS_DS_HAVE_PRIMARY_MEMBERS"; + case STATUS_WMI_NOT_SUPPORTED: return L"STATUS_WMI_NOT_SUPPORTED"; + case STATUS_INSUFFICIENT_POWER: return L"STATUS_INSUFFICIENT_POWER"; + case STATUS_SAM_NEED_BOOTKEY_PASSWORD: return L"STATUS_SAM_NEED_BOOTKEY_PASSWORD"; + case STATUS_SAM_NEED_BOOTKEY_FLOPPY: return L"STATUS_SAM_NEED_BOOTKEY_FLOPPY"; + case STATUS_DS_CANT_START: return L"STATUS_DS_CANT_START"; + case STATUS_DS_INIT_FAILURE: return L"STATUS_DS_INIT_FAILURE"; + case STATUS_SAM_INIT_FAILURE: return L"STATUS_SAM_INIT_FAILURE"; + case STATUS_DS_GC_REQUIRED: return L"STATUS_DS_GC_REQUIRED"; + case STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY: return L"STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY"; + case STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS: return L"STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS"; + case STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED: return L"STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED"; + case STATUS_MULTIPLE_FAULT_VIOLATION: return L"STATUS_MULTIPLE_FAULT_VIOLATION"; + case STATUS_CURRENT_DOMAIN_NOT_ALLOWED: return L"STATUS_CURRENT_DOMAIN_NOT_ALLOWED"; + case STATUS_CANNOT_MAKE: return L"STATUS_CANNOT_MAKE"; + case STATUS_SYSTEM_SHUTDOWN: return L"STATUS_SYSTEM_SHUTDOWN"; + case STATUS_DS_INIT_FAILURE_CONSOLE: return L"STATUS_DS_INIT_FAILURE_CONSOLE"; + case STATUS_DS_SAM_INIT_FAILURE_CONSOLE: return L"STATUS_DS_SAM_INIT_FAILURE_CONSOLE"; + case STATUS_UNFINISHED_CONTEXT_DELETED: return L"STATUS_UNFINISHED_CONTEXT_DELETED"; + case STATUS_NO_TGT_REPLY: return L"STATUS_NO_TGT_REPLY"; + case STATUS_OBJECTID_NOT_FOUND: return L"STATUS_OBJECTID_NOT_FOUND"; + case STATUS_NO_IP_ADDRESSES: return L"STATUS_NO_IP_ADDRESSES"; + case STATUS_WRONG_CREDENTIAL_HANDLE: return L"STATUS_WRONG_CREDENTIAL_HANDLE"; + case STATUS_CRYPTO_SYSTEM_INVALID: return L"STATUS_CRYPTO_SYSTEM_INVALID"; + case STATUS_MAX_REFERRALS_EXCEEDED: return L"STATUS_MAX_REFERRALS_EXCEEDED"; + case STATUS_MUST_BE_KDC: return L"STATUS_MUST_BE_KDC"; + case STATUS_STRONG_CRYPTO_NOT_SUPPORTED: return L"STATUS_STRONG_CRYPTO_NOT_SUPPORTED"; + case STATUS_TOO_MANY_PRINCIPALS: return L"STATUS_TOO_MANY_PRINCIPALS"; + case STATUS_NO_PA_DATA: return L"STATUS_NO_PA_DATA"; + case STATUS_PKINIT_NAME_MISMATCH: return L"STATUS_PKINIT_NAME_MISMATCH"; + case STATUS_SMARTCARD_LOGON_REQUIRED: return L"STATUS_SMARTCARD_LOGON_REQUIRED"; + case STATUS_KDC_INVALID_REQUEST: return L"STATUS_KDC_INVALID_REQUEST"; + case STATUS_KDC_UNABLE_TO_REFER: return L"STATUS_KDC_UNABLE_TO_REFER"; + case STATUS_KDC_UNKNOWN_ETYPE: return L"STATUS_KDC_UNKNOWN_ETYPE"; + case STATUS_SHUTDOWN_IN_PROGRESS: return L"STATUS_SHUTDOWN_IN_PROGRESS"; + case STATUS_SERVER_SHUTDOWN_IN_PROGRESS: return L"STATUS_SERVER_SHUTDOWN_IN_PROGRESS"; + case STATUS_NOT_SUPPORTED_ON_SBS: return L"STATUS_NOT_SUPPORTED_ON_SBS"; + case STATUS_WMI_GUID_DISCONNECTED: return L"STATUS_WMI_GUID_DISCONNECTED"; + case STATUS_WMI_ALREADY_DISABLED: return L"STATUS_WMI_ALREADY_DISABLED"; + case STATUS_WMI_ALREADY_ENABLED: return L"STATUS_WMI_ALREADY_ENABLED"; + case STATUS_MFT_TOO_FRAGMENTED: return L"STATUS_MFT_TOO_FRAGMENTED"; + case STATUS_COPY_PROTECTION_FAILURE: return L"STATUS_COPY_PROTECTION_FAILURE"; + case STATUS_CSS_AUTHENTICATION_FAILURE: return L"STATUS_CSS_AUTHENTICATION_FAILURE"; + case STATUS_CSS_KEY_NOT_PRESENT: return L"STATUS_CSS_KEY_NOT_PRESENT"; + case STATUS_CSS_KEY_NOT_ESTABLISHED: return L"STATUS_CSS_KEY_NOT_ESTABLISHED"; + case STATUS_CSS_SCRAMBLED_SECTOR: return L"STATUS_CSS_SCRAMBLED_SECTOR"; + case STATUS_CSS_REGION_MISMATCH: return L"STATUS_CSS_REGION_MISMATCH"; + case STATUS_CSS_RESETS_EXHAUSTED: return L"STATUS_CSS_RESETS_EXHAUSTED"; + case STATUS_PKINIT_FAILURE: return L"STATUS_PKINIT_FAILURE"; + case STATUS_SMARTCARD_SUBSYSTEM_FAILURE: return L"STATUS_SMARTCARD_SUBSYSTEM_FAILURE"; + case STATUS_NO_KERB_KEY: return L"STATUS_NO_KERB_KEY"; + case STATUS_HOST_DOWN: return L"STATUS_HOST_DOWN"; + case STATUS_UNSUPPORTED_PREAUTH: return L"STATUS_UNSUPPORTED_PREAUTH"; + case STATUS_EFS_ALG_BLOB_TOO_BIG: return L"STATUS_EFS_ALG_BLOB_TOO_BIG"; + case STATUS_PORT_NOT_SET: return L"STATUS_PORT_NOT_SET"; + case STATUS_DEBUGGER_INACTIVE: return L"STATUS_DEBUGGER_INACTIVE"; + case STATUS_DS_VERSION_CHECK_FAILURE: return L"STATUS_DS_VERSION_CHECK_FAILURE"; + case STATUS_AUDITING_DISABLED: return L"STATUS_AUDITING_DISABLED"; + case STATUS_PRENT4_MACHINE_ACCOUNT: return L"STATUS_PRENT4_MACHINE_ACCOUNT"; + case STATUS_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER: return L"STATUS_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER"; + case STATUS_INVALID_IMAGE_WIN_32: return L"STATUS_INVALID_IMAGE_WIN_32"; + case STATUS_INVALID_IMAGE_WIN_64: return L"STATUS_INVALID_IMAGE_WIN_64"; + case STATUS_BAD_BINDINGS: return L"STATUS_BAD_BINDINGS"; + case STATUS_NETWORK_SESSION_EXPIRED: return L"STATUS_NETWORK_SESSION_EXPIRED"; + case STATUS_APPHELP_BLOCK: return L"STATUS_APPHELP_BLOCK"; + case STATUS_ALL_SIDS_FILTERED: return L"STATUS_ALL_SIDS_FILTERED"; + case STATUS_NOT_SAFE_MODE_DRIVER: return L"STATUS_NOT_SAFE_MODE_DRIVER"; + case STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT: return L"STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT"; + case STATUS_ACCESS_DISABLED_BY_POLICY_PATH: return L"STATUS_ACCESS_DISABLED_BY_POLICY_PATH"; + case STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER: return L"STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER"; + case STATUS_ACCESS_DISABLED_BY_POLICY_OTHER: return L"STATUS_ACCESS_DISABLED_BY_POLICY_OTHER"; + case STATUS_FAILED_DRIVER_ENTRY: return L"STATUS_FAILED_DRIVER_ENTRY"; + case STATUS_DEVICE_ENUMERATION_ERROR: return L"STATUS_DEVICE_ENUMERATION_ERROR"; + case STATUS_MOUNT_POINT_NOT_RESOLVED: return L"STATUS_MOUNT_POINT_NOT_RESOLVED"; + case STATUS_INVALID_DEVICE_OBJECT_PARAMETER: return L"STATUS_INVALID_DEVICE_OBJECT_PARAMETER"; + case STATUS_MCA_OCCURED: return L"STATUS_MCA_OCCURED"; + case STATUS_DRIVER_BLOCKED_CRITICAL: return L"STATUS_DRIVER_BLOCKED_CRITICAL"; + case STATUS_DRIVER_BLOCKED: return L"STATUS_DRIVER_BLOCKED"; + case STATUS_DRIVER_DATABASE_ERROR: return L"STATUS_DRIVER_DATABASE_ERROR"; + case STATUS_SYSTEM_HIVE_TOO_LARGE: return L"STATUS_SYSTEM_HIVE_TOO_LARGE"; + case STATUS_INVALID_IMPORT_OF_NON_DLL: return L"STATUS_INVALID_IMPORT_OF_NON_DLL"; + case STATUS_DS_SHUTTING_DOWN: return L"STATUS_DS_SHUTTING_DOWN"; + case STATUS_NO_SECRETS: return L"STATUS_NO_SECRETS"; + case STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY: return L"STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY"; + case STATUS_FAILED_STACK_SWITCH: return L"STATUS_FAILED_STACK_SWITCH"; + case STATUS_HEAP_CORRUPTION: return L"STATUS_HEAP_CORRUPTION"; + case STATUS_SMARTCARD_WRONG_PIN: return L"STATUS_SMARTCARD_WRONG_PIN"; + case STATUS_SMARTCARD_CARD_BLOCKED: return L"STATUS_SMARTCARD_CARD_BLOCKED"; + case STATUS_SMARTCARD_CARD_NOT_AUTHENTICATED: return L"STATUS_SMARTCARD_CARD_NOT_AUTHENTICATED"; + case STATUS_SMARTCARD_NO_CARD: return L"STATUS_SMARTCARD_NO_CARD"; + case STATUS_SMARTCARD_NO_KEY_CONTAINER: return L"STATUS_SMARTCARD_NO_KEY_CONTAINER"; + case STATUS_SMARTCARD_NO_CERTIFICATE: return L"STATUS_SMARTCARD_NO_CERTIFICATE"; + case STATUS_SMARTCARD_NO_KEYSET: return L"STATUS_SMARTCARD_NO_KEYSET"; + case STATUS_SMARTCARD_IO_ERROR: return L"STATUS_SMARTCARD_IO_ERROR"; + case STATUS_DOWNGRADE_DETECTED: return L"STATUS_DOWNGRADE_DETECTED"; + case STATUS_SMARTCARD_CERT_REVOKED: return L"STATUS_SMARTCARD_CERT_REVOKED"; + case STATUS_ISSUING_CA_UNTRUSTED: return L"STATUS_ISSUING_CA_UNTRUSTED"; + case STATUS_REVOCATION_OFFLINE_C: return L"STATUS_REVOCATION_OFFLINE_C"; + case STATUS_PKINIT_CLIENT_FAILURE: return L"STATUS_PKINIT_CLIENT_FAILURE"; + case STATUS_SMARTCARD_CERT_EXPIRED: return L"STATUS_SMARTCARD_CERT_EXPIRED"; + case STATUS_DRIVER_FAILED_PRIOR_UNLOAD: return L"STATUS_DRIVER_FAILED_PRIOR_UNLOAD"; + case STATUS_SMARTCARD_SILENT_CONTEXT: return L"STATUS_SMARTCARD_SILENT_CONTEXT"; + case STATUS_PER_USER_TRUST_QUOTA_EXCEEDED: return L"STATUS_PER_USER_TRUST_QUOTA_EXCEEDED"; + case STATUS_ALL_USER_TRUST_QUOTA_EXCEEDED: return L"STATUS_ALL_USER_TRUST_QUOTA_EXCEEDED"; + case STATUS_USER_DELETE_TRUST_QUOTA_EXCEEDED: return L"STATUS_USER_DELETE_TRUST_QUOTA_EXCEEDED"; + case STATUS_DS_NAME_NOT_UNIQUE: return L"STATUS_DS_NAME_NOT_UNIQUE"; + case STATUS_DS_DUPLICATE_ID_FOUND: return L"STATUS_DS_DUPLICATE_ID_FOUND"; + case STATUS_DS_GROUP_CONVERSION_ERROR: return L"STATUS_DS_GROUP_CONVERSION_ERROR"; + case STATUS_VOLSNAP_PREPARE_HIBERNATE: return L"STATUS_VOLSNAP_PREPARE_HIBERNATE"; + case STATUS_USER2USER_REQUIRED: return L"STATUS_USER2USER_REQUIRED"; + case STATUS_STACK_BUFFER_OVERRUN: return L"STATUS_STACK_BUFFER_OVERRUN"; + case STATUS_NO_S4U_PROT_SUPPORT: return L"STATUS_NO_S4U_PROT_SUPPORT"; + case STATUS_CROSSREALM_DELEGATION_FAILURE: return L"STATUS_CROSSREALM_DELEGATION_FAILURE"; + case STATUS_REVOCATION_OFFLINE_KDC: return L"STATUS_REVOCATION_OFFLINE_KDC"; + case STATUS_ISSUING_CA_UNTRUSTED_KDC: return L"STATUS_ISSUING_CA_UNTRUSTED_KDC"; + case STATUS_KDC_CERT_EXPIRED: return L"STATUS_KDC_CERT_EXPIRED"; + case STATUS_KDC_CERT_REVOKED: return L"STATUS_KDC_CERT_REVOKED"; + case STATUS_PARAMETER_QUOTA_EXCEEDED: return L"STATUS_PARAMETER_QUOTA_EXCEEDED"; + case STATUS_HIBERNATION_FAILURE: return L"STATUS_HIBERNATION_FAILURE"; + case STATUS_DELAY_LOAD_FAILED: return L"STATUS_DELAY_LOAD_FAILED"; + case STATUS_AUTHENTICATION_FIREWALL_FAILED: return L"STATUS_AUTHENTICATION_FIREWALL_FAILED"; + case STATUS_VDM_DISALLOWED: return L"STATUS_VDM_DISALLOWED"; + case STATUS_HUNG_DISPLAY_DRIVER_THREAD: return L"STATUS_HUNG_DISPLAY_DRIVER_THREAD"; + case STATUS_INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE: return L"STATUS_INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE"; + case STATUS_INVALID_CRUNTIME_PARAMETER: return L"STATUS_INVALID_CRUNTIME_PARAMETER"; + case STATUS_NTLM_BLOCKED: return L"STATUS_NTLM_BLOCKED"; + case STATUS_DS_SRC_SID_EXISTS_IN_FOREST: return L"STATUS_DS_SRC_SID_EXISTS_IN_FOREST"; + case STATUS_DS_DOMAIN_NAME_EXISTS_IN_FOREST: return L"STATUS_DS_DOMAIN_NAME_EXISTS_IN_FOREST"; + case STATUS_DS_FLAT_NAME_EXISTS_IN_FOREST: return L"STATUS_DS_FLAT_NAME_EXISTS_IN_FOREST"; + case STATUS_INVALID_USER_PRINCIPAL_NAME: return L"STATUS_INVALID_USER_PRINCIPAL_NAME"; + case STATUS_FATAL_USER_CALLBACK_EXCEPTION: return L"STATUS_FATAL_USER_CALLBACK_EXCEPTION"; + case STATUS_ASSERTION_FAILURE: return L"STATUS_ASSERTION_FAILURE"; + case STATUS_VERIFIER_STOP: return L"STATUS_VERIFIER_STOP"; + case STATUS_CALLBACK_POP_STACK: return L"STATUS_CALLBACK_POP_STACK"; + case STATUS_INCOMPATIBLE_DRIVER_BLOCKED: return L"STATUS_INCOMPATIBLE_DRIVER_BLOCKED"; + case STATUS_HIVE_UNLOADED: return L"STATUS_HIVE_UNLOADED"; + case STATUS_COMPRESSION_DISABLED: return L"STATUS_COMPRESSION_DISABLED"; + case STATUS_FILE_SYSTEM_LIMITATION: return L"STATUS_FILE_SYSTEM_LIMITATION"; + case STATUS_INVALID_IMAGE_HASH: return L"STATUS_INVALID_IMAGE_HASH"; + case STATUS_NOT_CAPABLE: return L"STATUS_NOT_CAPABLE"; + case STATUS_REQUEST_OUT_OF_SEQUENCE: return L"STATUS_REQUEST_OUT_OF_SEQUENCE"; + case STATUS_IMPLEMENTATION_LIMIT: return L"STATUS_IMPLEMENTATION_LIMIT"; + case STATUS_ELEVATION_REQUIRED: return L"STATUS_ELEVATION_REQUIRED"; + case STATUS_NO_SECURITY_CONTEXT: return L"STATUS_NO_SECURITY_CONTEXT"; + case STATUS_PKU2U_CERT_FAILURE: return L"STATUS_PKU2U_CERT_FAILURE"; + case STATUS_BEYOND_VDL: return L"STATUS_BEYOND_VDL"; + case STATUS_ENCOUNTERED_WRITE_IN_PROGRESS: return L"STATUS_ENCOUNTERED_WRITE_IN_PROGRESS"; + case STATUS_PTE_CHANGED: return L"STATUS_PTE_CHANGED"; + case STATUS_PURGE_FAILED: return L"STATUS_PURGE_FAILED"; + case STATUS_CRED_REQUIRES_CONFIRMATION: return L"STATUS_CRED_REQUIRES_CONFIRMATION"; + case STATUS_CS_ENCRYPTION_INVALID_SERVER_RESPONSE: return L"STATUS_CS_ENCRYPTION_INVALID_SERVER_RESPONSE"; + case STATUS_CS_ENCRYPTION_UNSUPPORTED_SERVER: return L"STATUS_CS_ENCRYPTION_UNSUPPORTED_SERVER"; + case STATUS_CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE: return L"STATUS_CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE"; + case STATUS_CS_ENCRYPTION_NEW_ENCRYPTED_FILE: return L"STATUS_CS_ENCRYPTION_NEW_ENCRYPTED_FILE"; + case STATUS_CS_ENCRYPTION_FILE_NOT_CSE: return L"STATUS_CS_ENCRYPTION_FILE_NOT_CSE"; + case STATUS_INVALID_LABEL: return L"STATUS_INVALID_LABEL"; + case STATUS_DRIVER_PROCESS_TERMINATED: return L"STATUS_DRIVER_PROCESS_TERMINATED"; + case STATUS_AMBIGUOUS_SYSTEM_DEVICE: return L"STATUS_AMBIGUOUS_SYSTEM_DEVICE"; + case STATUS_SYSTEM_DEVICE_NOT_FOUND: return L"STATUS_SYSTEM_DEVICE_NOT_FOUND"; + case STATUS_RESTART_BOOT_APPLICATION: return L"STATUS_RESTART_BOOT_APPLICATION"; + case STATUS_INSUFFICIENT_NVRAM_RESOURCES: return L"STATUS_INSUFFICIENT_NVRAM_RESOURCES"; + case STATUS_INVALID_TASK_NAME: return L"STATUS_INVALID_TASK_NAME"; + case STATUS_INVALID_TASK_INDEX: return L"STATUS_INVALID_TASK_INDEX"; + case STATUS_THREAD_ALREADY_IN_TASK: return L"STATUS_THREAD_ALREADY_IN_TASK"; + case STATUS_CALLBACK_BYPASS: return L"STATUS_CALLBACK_BYPASS"; + case STATUS_FAIL_FAST_EXCEPTION: return L"STATUS_FAIL_FAST_EXCEPTION"; + case STATUS_IMAGE_CERT_REVOKED: return L"STATUS_IMAGE_CERT_REVOKED"; + case STATUS_PORT_CLOSED: return L"STATUS_PORT_CLOSED"; + case STATUS_MESSAGE_LOST: return L"STATUS_MESSAGE_LOST"; + case STATUS_INVALID_MESSAGE: return L"STATUS_INVALID_MESSAGE"; + case STATUS_REQUEST_CANCELED: return L"STATUS_REQUEST_CANCELED"; + case STATUS_RECURSIVE_DISPATCH: return L"STATUS_RECURSIVE_DISPATCH"; + case STATUS_LPC_RECEIVE_BUFFER_EXPECTED: return L"STATUS_LPC_RECEIVE_BUFFER_EXPECTED"; + case STATUS_LPC_INVALID_CONNECTION_USAGE: return L"STATUS_LPC_INVALID_CONNECTION_USAGE"; + case STATUS_LPC_REQUESTS_NOT_ALLOWED: return L"STATUS_LPC_REQUESTS_NOT_ALLOWED"; + case STATUS_RESOURCE_IN_USE: return L"STATUS_RESOURCE_IN_USE"; + case STATUS_HARDWARE_MEMORY_ERROR: return L"STATUS_HARDWARE_MEMORY_ERROR"; + case STATUS_THREADPOOL_HANDLE_EXCEPTION: return L"STATUS_THREADPOOL_HANDLE_EXCEPTION"; + case STATUS_THREADPOOL_SET_EVENT_ON_COMPLETION_FAILED: return L"STATUS_THREADPOOL_SET_EVENT_ON_COMPLETION_FAILED"; + case STATUS_THREADPOOL_RELEASE_SEMAPHORE_ON_COMPLETION_FAILED: return L"STATUS_THREADPOOL_RELEASE_SEMAPHORE_ON_COMPLETION_FAILED"; + case STATUS_THREADPOOL_RELEASE_MUTEX_ON_COMPLETION_FAILED: return L"STATUS_THREADPOOL_RELEASE_MUTEX_ON_COMPLETION_FAILED"; + case STATUS_THREADPOOL_FREE_LIBRARY_ON_COMPLETION_FAILED: return L"STATUS_THREADPOOL_FREE_LIBRARY_ON_COMPLETION_FAILED"; + case STATUS_THREADPOOL_RELEASED_DURING_OPERATION: return L"STATUS_THREADPOOL_RELEASED_DURING_OPERATION"; + case STATUS_CALLBACK_RETURNED_WHILE_IMPERSONATING: return L"STATUS_CALLBACK_RETURNED_WHILE_IMPERSONATING"; + case STATUS_APC_RETURNED_WHILE_IMPERSONATING: return L"STATUS_APC_RETURNED_WHILE_IMPERSONATING"; + case STATUS_PROCESS_IS_PROTECTED: return L"STATUS_PROCESS_IS_PROTECTED"; + case STATUS_MCA_EXCEPTION: return L"STATUS_MCA_EXCEPTION"; + case STATUS_CERTIFICATE_MAPPING_NOT_UNIQUE: return L"STATUS_CERTIFICATE_MAPPING_NOT_UNIQUE"; + case STATUS_SYMLINK_CLASS_DISABLED: return L"STATUS_SYMLINK_CLASS_DISABLED"; + case STATUS_INVALID_IDN_NORMALIZATION: return L"STATUS_INVALID_IDN_NORMALIZATION"; + case STATUS_NO_UNICODE_TRANSLATION: return L"STATUS_NO_UNICODE_TRANSLATION"; + case STATUS_ALREADY_REGISTERED: return L"STATUS_ALREADY_REGISTERED"; + case STATUS_CONTEXT_MISMATCH: return L"STATUS_CONTEXT_MISMATCH"; + case STATUS_PORT_ALREADY_HAS_COMPLETION_LIST: return L"STATUS_PORT_ALREADY_HAS_COMPLETION_LIST"; + case STATUS_CALLBACK_RETURNED_THREAD_PRIORITY: return L"STATUS_CALLBACK_RETURNED_THREAD_PRIORITY"; + case STATUS_INVALID_THREAD: return L"STATUS_INVALID_THREAD"; + case STATUS_CALLBACK_RETURNED_TRANSACTION: return L"STATUS_CALLBACK_RETURNED_TRANSACTION"; + case STATUS_CALLBACK_RETURNED_LDR_LOCK: return L"STATUS_CALLBACK_RETURNED_LDR_LOCK"; + case STATUS_CALLBACK_RETURNED_LANG: return L"STATUS_CALLBACK_RETURNED_LANG"; + case STATUS_CALLBACK_RETURNED_PRI_BACK: return L"STATUS_CALLBACK_RETURNED_PRI_BACK"; + case STATUS_CALLBACK_RETURNED_THREAD_AFFINITY: return L"STATUS_CALLBACK_RETURNED_THREAD_AFFINITY"; + case STATUS_DISK_REPAIR_DISABLED: return L"STATUS_DISK_REPAIR_DISABLED"; + case STATUS_DS_DOMAIN_RENAME_IN_PROGRESS: return L"STATUS_DS_DOMAIN_RENAME_IN_PROGRESS"; + case STATUS_DISK_QUOTA_EXCEEDED: return L"STATUS_DISK_QUOTA_EXCEEDED"; + case STATUS_DATA_LOST_REPAIR: return L"STATUS_DATA_LOST_REPAIR"; + case STATUS_CONTENT_BLOCKED: return L"STATUS_CONTENT_BLOCKED"; + case STATUS_BAD_CLUSTERS: return L"STATUS_BAD_CLUSTERS"; + case STATUS_VOLUME_DIRTY: return L"STATUS_VOLUME_DIRTY"; + case STATUS_FILE_CHECKED_OUT: return L"STATUS_FILE_CHECKED_OUT"; + case STATUS_CHECKOUT_REQUIRED: return L"STATUS_CHECKOUT_REQUIRED"; + case STATUS_BAD_FILE_TYPE: return L"STATUS_BAD_FILE_TYPE"; + case STATUS_FILE_TOO_LARGE: return L"STATUS_FILE_TOO_LARGE"; + case STATUS_FORMS_AUTH_REQUIRED: return L"STATUS_FORMS_AUTH_REQUIRED"; + case STATUS_VIRUS_INFECTED: return L"STATUS_VIRUS_INFECTED"; + case STATUS_VIRUS_DELETED: return L"STATUS_VIRUS_DELETED"; + case STATUS_BAD_MCFG_TABLE: return L"STATUS_BAD_MCFG_TABLE"; + case STATUS_CANNOT_BREAK_OPLOCK: return L"STATUS_CANNOT_BREAK_OPLOCK"; + case STATUS_WOW_ASSERTION: return L"STATUS_WOW_ASSERTION"; + case STATUS_INVALID_SIGNATURE: return L"STATUS_INVALID_SIGNATURE"; + case STATUS_HMAC_NOT_SUPPORTED: return L"STATUS_HMAC_NOT_SUPPORTED"; + case STATUS_AUTH_TAG_MISMATCH: return L"STATUS_AUTH_TAG_MISMATCH"; + case STATUS_IPSEC_QUEUE_OVERFLOW: return L"STATUS_IPSEC_QUEUE_OVERFLOW"; + case STATUS_ND_QUEUE_OVERFLOW: return L"STATUS_ND_QUEUE_OVERFLOW"; + case STATUS_HOPLIMIT_EXCEEDED: return L"STATUS_HOPLIMIT_EXCEEDED"; + case STATUS_PROTOCOL_NOT_SUPPORTED: return L"STATUS_PROTOCOL_NOT_SUPPORTED"; + case STATUS_FASTPATH_REJECTED: return L"STATUS_FASTPATH_REJECTED"; + case STATUS_LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED: return L"STATUS_LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED"; + case STATUS_LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR: return L"STATUS_LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR"; + case STATUS_LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR: return L"STATUS_LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR"; + case STATUS_XML_PARSE_ERROR: return L"STATUS_XML_PARSE_ERROR"; + case STATUS_XMLDSIG_ERROR: return L"STATUS_XMLDSIG_ERROR"; + case STATUS_WRONG_COMPARTMENT: return L"STATUS_WRONG_COMPARTMENT"; + case STATUS_AUTHIP_FAILURE: return L"STATUS_AUTHIP_FAILURE"; + case STATUS_DS_OID_MAPPED_GROUP_CANT_HAVE_MEMBERS: return L"STATUS_DS_OID_MAPPED_GROUP_CANT_HAVE_MEMBERS"; + case STATUS_DS_OID_NOT_FOUND: return L"STATUS_DS_OID_NOT_FOUND"; + case STATUS_HASH_NOT_SUPPORTED: return L"STATUS_HASH_NOT_SUPPORTED"; + case STATUS_HASH_NOT_PRESENT: return L"STATUS_HASH_NOT_PRESENT"; + case STATUS_ACPI_INVALID_OPCODE: return L"STATUS_ACPI_INVALID_OPCODE"; + case STATUS_ACPI_STACK_OVERFLOW: return L"STATUS_ACPI_STACK_OVERFLOW"; + case STATUS_ACPI_ASSERT_FAILED: return L"STATUS_ACPI_ASSERT_FAILED"; + case STATUS_ACPI_INVALID_INDEX: return L"STATUS_ACPI_INVALID_INDEX"; + case STATUS_ACPI_INVALID_ARGUMENT: return L"STATUS_ACPI_INVALID_ARGUMENT"; + case STATUS_ACPI_FATAL: return L"STATUS_ACPI_FATAL"; + case STATUS_ACPI_INVALID_SUPERNAME: return L"STATUS_ACPI_INVALID_SUPERNAME"; + case STATUS_ACPI_INVALID_ARGTYPE: return L"STATUS_ACPI_INVALID_ARGTYPE"; + case STATUS_ACPI_INVALID_OBJTYPE: return L"STATUS_ACPI_INVALID_OBJTYPE"; + case STATUS_ACPI_INVALID_TARGETTYPE: return L"STATUS_ACPI_INVALID_TARGETTYPE"; + case STATUS_ACPI_INCORRECT_ARGUMENT_COUNT: return L"STATUS_ACPI_INCORRECT_ARGUMENT_COUNT"; + case STATUS_ACPI_ADDRESS_NOT_MAPPED: return L"STATUS_ACPI_ADDRESS_NOT_MAPPED"; + case STATUS_ACPI_INVALID_EVENTTYPE: return L"STATUS_ACPI_INVALID_EVENTTYPE"; + case STATUS_ACPI_HANDLER_COLLISION: return L"STATUS_ACPI_HANDLER_COLLISION"; + case STATUS_ACPI_INVALID_DATA: return L"STATUS_ACPI_INVALID_DATA"; + case STATUS_ACPI_INVALID_REGION: return L"STATUS_ACPI_INVALID_REGION"; + case STATUS_ACPI_INVALID_ACCESS_SIZE: return L"STATUS_ACPI_INVALID_ACCESS_SIZE"; + case STATUS_ACPI_ACQUIRE_GLOBAL_LOCK: return L"STATUS_ACPI_ACQUIRE_GLOBAL_LOCK"; + case STATUS_ACPI_ALREADY_INITIALIZED: return L"STATUS_ACPI_ALREADY_INITIALIZED"; + case STATUS_ACPI_NOT_INITIALIZED: return L"STATUS_ACPI_NOT_INITIALIZED"; + case STATUS_ACPI_INVALID_MUTEX_LEVEL: return L"STATUS_ACPI_INVALID_MUTEX_LEVEL"; + case STATUS_ACPI_MUTEX_NOT_OWNED: return L"STATUS_ACPI_MUTEX_NOT_OWNED"; + case STATUS_ACPI_MUTEX_NOT_OWNER: return L"STATUS_ACPI_MUTEX_NOT_OWNER"; + case STATUS_ACPI_RS_ACCESS: return L"STATUS_ACPI_RS_ACCESS"; + case STATUS_ACPI_INVALID_TABLE: return L"STATUS_ACPI_INVALID_TABLE"; + case STATUS_ACPI_REG_HANDLER_FAILED: return L"STATUS_ACPI_REG_HANDLER_FAILED"; + case STATUS_ACPI_POWER_REQUEST_FAILED: return L"STATUS_ACPI_POWER_REQUEST_FAILED"; + case STATUS_CTX_WINSTATION_NAME_INVALID: return L"STATUS_CTX_WINSTATION_NAME_INVALID"; + case STATUS_CTX_INVALID_PD: return L"STATUS_CTX_INVALID_PD"; + case STATUS_CTX_PD_NOT_FOUND: return L"STATUS_CTX_PD_NOT_FOUND"; + case STATUS_CTX_CDM_CONNECT: return L"STATUS_CTX_CDM_CONNECT"; + case STATUS_CTX_CDM_DISCONNECT: return L"STATUS_CTX_CDM_DISCONNECT"; + case STATUS_CTX_CLOSE_PENDING: return L"STATUS_CTX_CLOSE_PENDING"; + case STATUS_CTX_NO_OUTBUF: return L"STATUS_CTX_NO_OUTBUF"; + case STATUS_CTX_MODEM_INF_NOT_FOUND: return L"STATUS_CTX_MODEM_INF_NOT_FOUND"; + case STATUS_CTX_INVALID_MODEMNAME: return L"STATUS_CTX_INVALID_MODEMNAME"; + case STATUS_CTX_RESPONSE_ERROR: return L"STATUS_CTX_RESPONSE_ERROR"; + case STATUS_CTX_MODEM_RESPONSE_TIMEOUT: return L"STATUS_CTX_MODEM_RESPONSE_TIMEOUT"; + case STATUS_CTX_MODEM_RESPONSE_NO_CARRIER: return L"STATUS_CTX_MODEM_RESPONSE_NO_CARRIER"; + case STATUS_CTX_MODEM_RESPONSE_NO_DIALTONE: return L"STATUS_CTX_MODEM_RESPONSE_NO_DIALTONE"; + case STATUS_CTX_MODEM_RESPONSE_BUSY: return L"STATUS_CTX_MODEM_RESPONSE_BUSY"; + case STATUS_CTX_MODEM_RESPONSE_VOICE: return L"STATUS_CTX_MODEM_RESPONSE_VOICE"; + case STATUS_CTX_TD_ERROR: return L"STATUS_CTX_TD_ERROR"; + case STATUS_CTX_LICENSE_CLIENT_INVALID: return L"STATUS_CTX_LICENSE_CLIENT_INVALID"; + case STATUS_CTX_LICENSE_NOT_AVAILABLE: return L"STATUS_CTX_LICENSE_NOT_AVAILABLE"; + case STATUS_CTX_LICENSE_EXPIRED: return L"STATUS_CTX_LICENSE_EXPIRED"; + case STATUS_CTX_WINSTATION_NOT_FOUND: return L"STATUS_CTX_WINSTATION_NOT_FOUND"; + case STATUS_CTX_WINSTATION_NAME_COLLISION: return L"STATUS_CTX_WINSTATION_NAME_COLLISION"; + case STATUS_CTX_WINSTATION_BUSY: return L"STATUS_CTX_WINSTATION_BUSY"; + case STATUS_CTX_BAD_VIDEO_MODE: return L"STATUS_CTX_BAD_VIDEO_MODE"; + case STATUS_CTX_GRAPHICS_INVALID: return L"STATUS_CTX_GRAPHICS_INVALID"; + case STATUS_CTX_NOT_CONSOLE: return L"STATUS_CTX_NOT_CONSOLE"; + case STATUS_CTX_CLIENT_QUERY_TIMEOUT: return L"STATUS_CTX_CLIENT_QUERY_TIMEOUT"; + case STATUS_CTX_CONSOLE_DISCONNECT: return L"STATUS_CTX_CONSOLE_DISCONNECT"; + case STATUS_CTX_CONSOLE_CONNECT: return L"STATUS_CTX_CONSOLE_CONNECT"; + case STATUS_CTX_SHADOW_DENIED: return L"STATUS_CTX_SHADOW_DENIED"; + case STATUS_CTX_WINSTATION_ACCESS_DENIED: return L"STATUS_CTX_WINSTATION_ACCESS_DENIED"; + case STATUS_CTX_INVALID_WD: return L"STATUS_CTX_INVALID_WD"; + case STATUS_CTX_WD_NOT_FOUND: return L"STATUS_CTX_WD_NOT_FOUND"; + case STATUS_CTX_SHADOW_INVALID: return L"STATUS_CTX_SHADOW_INVALID"; + case STATUS_CTX_SHADOW_DISABLED: return L"STATUS_CTX_SHADOW_DISABLED"; + case STATUS_RDP_PROTOCOL_ERROR: return L"STATUS_RDP_PROTOCOL_ERROR"; + case STATUS_CTX_CLIENT_LICENSE_NOT_SET: return L"STATUS_CTX_CLIENT_LICENSE_NOT_SET"; + case STATUS_CTX_CLIENT_LICENSE_IN_USE: return L"STATUS_CTX_CLIENT_LICENSE_IN_USE"; + case STATUS_CTX_SHADOW_ENDED_BY_MODE_CHANGE: return L"STATUS_CTX_SHADOW_ENDED_BY_MODE_CHANGE"; + case STATUS_CTX_SHADOW_NOT_RUNNING: return L"STATUS_CTX_SHADOW_NOT_RUNNING"; + case STATUS_CTX_LOGON_DISABLED: return L"STATUS_CTX_LOGON_DISABLED"; + case STATUS_CTX_SECURITY_LAYER_ERROR: return L"STATUS_CTX_SECURITY_LAYER_ERROR"; + case STATUS_TS_INCOMPATIBLE_SESSIONS: return L"STATUS_TS_INCOMPATIBLE_SESSIONS"; + case STATUS_TS_VIDEO_SUBSYSTEM_ERROR: return L"STATUS_TS_VIDEO_SUBSYSTEM_ERROR"; + case STATUS_PNP_BAD_MPS_TABLE: return L"STATUS_PNP_BAD_MPS_TABLE"; + case STATUS_PNP_TRANSLATION_FAILED: return L"STATUS_PNP_TRANSLATION_FAILED"; + case STATUS_PNP_IRQ_TRANSLATION_FAILED: return L"STATUS_PNP_IRQ_TRANSLATION_FAILED"; + case STATUS_PNP_INVALID_ID: return L"STATUS_PNP_INVALID_ID"; + case STATUS_IO_REISSUE_AS_CACHED: return L"STATUS_IO_REISSUE_AS_CACHED"; + case STATUS_MUI_FILE_NOT_FOUND: return L"STATUS_MUI_FILE_NOT_FOUND"; + case STATUS_MUI_INVALID_FILE: return L"STATUS_MUI_INVALID_FILE"; + case STATUS_MUI_INVALID_RC_CONFIG: return L"STATUS_MUI_INVALID_RC_CONFIG"; + case STATUS_MUI_INVALID_LOCALE_NAME: return L"STATUS_MUI_INVALID_LOCALE_NAME"; + case STATUS_MUI_INVALID_ULTIMATEFALLBACK_NAME: return L"STATUS_MUI_INVALID_ULTIMATEFALLBACK_NAME"; + case STATUS_MUI_FILE_NOT_LOADED: return L"STATUS_MUI_FILE_NOT_LOADED"; + case STATUS_RESOURCE_ENUM_USER_STOP: return L"STATUS_RESOURCE_ENUM_USER_STOP"; + case STATUS_FLT_NO_HANDLER_DEFINED: return L"STATUS_FLT_NO_HANDLER_DEFINED"; + case STATUS_FLT_CONTEXT_ALREADY_DEFINED: return L"STATUS_FLT_CONTEXT_ALREADY_DEFINED"; + case STATUS_FLT_INVALID_ASYNCHRONOUS_REQUEST: return L"STATUS_FLT_INVALID_ASYNCHRONOUS_REQUEST"; + case STATUS_FLT_DISALLOW_FAST_IO: return L"STATUS_FLT_DISALLOW_FAST_IO"; + case STATUS_FLT_INVALID_NAME_REQUEST: return L"STATUS_FLT_INVALID_NAME_REQUEST"; + case STATUS_FLT_NOT_SAFE_TO_POST_OPERATION: return L"STATUS_FLT_NOT_SAFE_TO_POST_OPERATION"; + case STATUS_FLT_NOT_INITIALIZED: return L"STATUS_FLT_NOT_INITIALIZED"; + case STATUS_FLT_FILTER_NOT_READY: return L"STATUS_FLT_FILTER_NOT_READY"; + case STATUS_FLT_POST_OPERATION_CLEANUP: return L"STATUS_FLT_POST_OPERATION_CLEANUP"; + case STATUS_FLT_INTERNAL_ERROR: return L"STATUS_FLT_INTERNAL_ERROR"; + case STATUS_FLT_DELETING_OBJECT: return L"STATUS_FLT_DELETING_OBJECT"; + case STATUS_FLT_MUST_BE_NONPAGED_POOL: return L"STATUS_FLT_MUST_BE_NONPAGED_POOL"; + case STATUS_FLT_DUPLICATE_ENTRY: return L"STATUS_FLT_DUPLICATE_ENTRY"; + case STATUS_FLT_CBDQ_DISABLED: return L"STATUS_FLT_CBDQ_DISABLED"; + case STATUS_FLT_DO_NOT_ATTACH: return L"STATUS_FLT_DO_NOT_ATTACH"; + case STATUS_FLT_DO_NOT_DETACH: return L"STATUS_FLT_DO_NOT_DETACH"; + case STATUS_FLT_INSTANCE_ALTITUDE_COLLISION: return L"STATUS_FLT_INSTANCE_ALTITUDE_COLLISION"; + case STATUS_FLT_INSTANCE_NAME_COLLISION: return L"STATUS_FLT_INSTANCE_NAME_COLLISION"; + case STATUS_FLT_FILTER_NOT_FOUND: return L"STATUS_FLT_FILTER_NOT_FOUND"; + case STATUS_FLT_VOLUME_NOT_FOUND: return L"STATUS_FLT_VOLUME_NOT_FOUND"; + case STATUS_FLT_INSTANCE_NOT_FOUND: return L"STATUS_FLT_INSTANCE_NOT_FOUND"; + case STATUS_FLT_CONTEXT_ALLOCATION_NOT_FOUND: return L"STATUS_FLT_CONTEXT_ALLOCATION_NOT_FOUND"; + case STATUS_FLT_INVALID_CONTEXT_REGISTRATION: return L"STATUS_FLT_INVALID_CONTEXT_REGISTRATION"; + case STATUS_FLT_NAME_CACHE_MISS: return L"STATUS_FLT_NAME_CACHE_MISS"; + case STATUS_FLT_NO_DEVICE_OBJECT: return L"STATUS_FLT_NO_DEVICE_OBJECT"; + case STATUS_FLT_VOLUME_ALREADY_MOUNTED: return L"STATUS_FLT_VOLUME_ALREADY_MOUNTED"; + case STATUS_FLT_ALREADY_ENLISTED: return L"STATUS_FLT_ALREADY_ENLISTED"; + case STATUS_FLT_CONTEXT_ALREADY_LINKED: return L"STATUS_FLT_CONTEXT_ALREADY_LINKED"; + case STATUS_FLT_NO_WAITER_FOR_REPLY: return L"STATUS_FLT_NO_WAITER_FOR_REPLY"; + case STATUS_SXS_SECTION_NOT_FOUND: return L"STATUS_SXS_SECTION_NOT_FOUND"; + case STATUS_SXS_CANT_GEN_ACTCTX: return L"STATUS_SXS_CANT_GEN_ACTCTX"; + case STATUS_SXS_INVALID_ACTCTXDATA_FORMAT: return L"STATUS_SXS_INVALID_ACTCTXDATA_FORMAT"; + case STATUS_SXS_ASSEMBLY_NOT_FOUND: return L"STATUS_SXS_ASSEMBLY_NOT_FOUND"; + case STATUS_SXS_MANIFEST_FORMAT_ERROR: return L"STATUS_SXS_MANIFEST_FORMAT_ERROR"; + case STATUS_SXS_MANIFEST_PARSE_ERROR: return L"STATUS_SXS_MANIFEST_PARSE_ERROR"; + case STATUS_SXS_ACTIVATION_CONTEXT_DISABLED: return L"STATUS_SXS_ACTIVATION_CONTEXT_DISABLED"; + case STATUS_SXS_KEY_NOT_FOUND: return L"STATUS_SXS_KEY_NOT_FOUND"; + case STATUS_SXS_VERSION_CONFLICT: return L"STATUS_SXS_VERSION_CONFLICT"; + case STATUS_SXS_WRONG_SECTION_TYPE: return L"STATUS_SXS_WRONG_SECTION_TYPE"; + case STATUS_SXS_THREAD_QUERIES_DISABLED: return L"STATUS_SXS_THREAD_QUERIES_DISABLED"; + case STATUS_SXS_ASSEMBLY_MISSING: return L"STATUS_SXS_ASSEMBLY_MISSING"; + case STATUS_SXS_RELEASE_ACTIVATION_CONTEXT: return L"STATUS_SXS_RELEASE_ACTIVATION_CONTEXT"; + case STATUS_SXS_PROCESS_DEFAULT_ALREADY_SET: return L"STATUS_SXS_PROCESS_DEFAULT_ALREADY_SET"; + case STATUS_SXS_EARLY_DEACTIVATION: return L"STATUS_SXS_EARLY_DEACTIVATION"; + case STATUS_SXS_INVALID_DEACTIVATION: return L"STATUS_SXS_INVALID_DEACTIVATION"; + case STATUS_SXS_MULTIPLE_DEACTIVATION: return L"STATUS_SXS_MULTIPLE_DEACTIVATION"; + case STATUS_SXS_SYSTEM_DEFAULT_ACTIVATION_CONTEXT_EMPTY: return L"STATUS_SXS_SYSTEM_DEFAULT_ACTIVATION_CONTEXT_EMPTY"; + case STATUS_SXS_PROCESS_TERMINATION_REQUESTED: return L"STATUS_SXS_PROCESS_TERMINATION_REQUESTED"; + case STATUS_SXS_CORRUPT_ACTIVATION_STACK: return L"STATUS_SXS_CORRUPT_ACTIVATION_STACK"; + case STATUS_SXS_CORRUPTION: return L"STATUS_SXS_CORRUPTION"; + case STATUS_SXS_INVALID_IDENTITY_ATTRIBUTE_VALUE: return L"STATUS_SXS_INVALID_IDENTITY_ATTRIBUTE_VALUE"; + case STATUS_SXS_INVALID_IDENTITY_ATTRIBUTE_NAME: return L"STATUS_SXS_INVALID_IDENTITY_ATTRIBUTE_NAME"; + case STATUS_SXS_IDENTITY_DUPLICATE_ATTRIBUTE: return L"STATUS_SXS_IDENTITY_DUPLICATE_ATTRIBUTE"; + case STATUS_SXS_IDENTITY_PARSE_ERROR: return L"STATUS_SXS_IDENTITY_PARSE_ERROR"; + case STATUS_SXS_COMPONENT_STORE_CORRUPT: return L"STATUS_SXS_COMPONENT_STORE_CORRUPT"; + case STATUS_SXS_FILE_HASH_MISMATCH: return L"STATUS_SXS_FILE_HASH_MISMATCH"; + case STATUS_SXS_MANIFEST_IDENTITY_SAME_BUT_CONTENTS_DIFFERENT: return L"STATUS_SXS_MANIFEST_IDENTITY_SAME_BUT_CONTENTS_DIFFERENT"; + case STATUS_SXS_IDENTITIES_DIFFERENT: return L"STATUS_SXS_IDENTITIES_DIFFERENT"; + case STATUS_SXS_ASSEMBLY_IS_NOT_A_DEPLOYMENT: return L"STATUS_SXS_ASSEMBLY_IS_NOT_A_DEPLOYMENT"; + case STATUS_SXS_FILE_NOT_PART_OF_ASSEMBLY: return L"STATUS_SXS_FILE_NOT_PART_OF_ASSEMBLY"; + case STATUS_ADVANCED_INSTALLER_FAILED: return L"STATUS_ADVANCED_INSTALLER_FAILED"; + case STATUS_XML_ENCODING_MISMATCH: return L"STATUS_XML_ENCODING_MISMATCH"; + case STATUS_SXS_MANIFEST_TOO_BIG: return L"STATUS_SXS_MANIFEST_TOO_BIG"; + case STATUS_SXS_SETTING_NOT_REGISTERED: return L"STATUS_SXS_SETTING_NOT_REGISTERED"; + case STATUS_SXS_TRANSACTION_CLOSURE_INCOMPLETE: return L"STATUS_SXS_TRANSACTION_CLOSURE_INCOMPLETE"; + case STATUS_SMI_PRIMITIVE_INSTALLER_FAILED: return L"STATUS_SMI_PRIMITIVE_INSTALLER_FAILED"; + case STATUS_GENERIC_COMMAND_FAILED: return L"STATUS_GENERIC_COMMAND_FAILED"; + case STATUS_SXS_FILE_HASH_MISSING: return L"STATUS_SXS_FILE_HASH_MISSING"; + case STATUS_CLUSTER_INVALID_NODE: return L"STATUS_CLUSTER_INVALID_NODE"; + case STATUS_CLUSTER_NODE_EXISTS: return L"STATUS_CLUSTER_NODE_EXISTS"; + case STATUS_CLUSTER_JOIN_IN_PROGRESS: return L"STATUS_CLUSTER_JOIN_IN_PROGRESS"; + case STATUS_CLUSTER_NODE_NOT_FOUND: return L"STATUS_CLUSTER_NODE_NOT_FOUND"; + case STATUS_CLUSTER_LOCAL_NODE_NOT_FOUND: return L"STATUS_CLUSTER_LOCAL_NODE_NOT_FOUND"; + case STATUS_CLUSTER_NETWORK_EXISTS: return L"STATUS_CLUSTER_NETWORK_EXISTS"; + case STATUS_CLUSTER_NETWORK_NOT_FOUND: return L"STATUS_CLUSTER_NETWORK_NOT_FOUND"; + case STATUS_CLUSTER_NETINTERFACE_EXISTS: return L"STATUS_CLUSTER_NETINTERFACE_EXISTS"; + case STATUS_CLUSTER_NETINTERFACE_NOT_FOUND: return L"STATUS_CLUSTER_NETINTERFACE_NOT_FOUND"; + case STATUS_CLUSTER_INVALID_REQUEST: return L"STATUS_CLUSTER_INVALID_REQUEST"; + case STATUS_CLUSTER_INVALID_NETWORK_PROVIDER: return L"STATUS_CLUSTER_INVALID_NETWORK_PROVIDER"; + case STATUS_CLUSTER_NODE_DOWN: return L"STATUS_CLUSTER_NODE_DOWN"; + case STATUS_CLUSTER_NODE_UNREACHABLE: return L"STATUS_CLUSTER_NODE_UNREACHABLE"; + case STATUS_CLUSTER_NODE_NOT_MEMBER: return L"STATUS_CLUSTER_NODE_NOT_MEMBER"; + case STATUS_CLUSTER_JOIN_NOT_IN_PROGRESS: return L"STATUS_CLUSTER_JOIN_NOT_IN_PROGRESS"; + case STATUS_CLUSTER_INVALID_NETWORK: return L"STATUS_CLUSTER_INVALID_NETWORK"; + case STATUS_CLUSTER_NO_NET_ADAPTERS: return L"STATUS_CLUSTER_NO_NET_ADAPTERS"; + case STATUS_CLUSTER_NODE_UP: return L"STATUS_CLUSTER_NODE_UP"; + case STATUS_CLUSTER_NODE_PAUSED: return L"STATUS_CLUSTER_NODE_PAUSED"; + case STATUS_CLUSTER_NODE_NOT_PAUSED: return L"STATUS_CLUSTER_NODE_NOT_PAUSED"; + case STATUS_CLUSTER_NO_SECURITY_CONTEXT: return L"STATUS_CLUSTER_NO_SECURITY_CONTEXT"; + case STATUS_CLUSTER_NETWORK_NOT_INTERNAL: return L"STATUS_CLUSTER_NETWORK_NOT_INTERNAL"; + case STATUS_CLUSTER_POISONED: return L"STATUS_CLUSTER_POISONED"; + case STATUS_CLUSTER_NON_CSV_PATH: return L"STATUS_CLUSTER_NON_CSV_PATH"; + case STATUS_CLUSTER_CSV_VOLUME_NOT_LOCAL: return L"STATUS_CLUSTER_CSV_VOLUME_NOT_LOCAL"; + case STATUS_TRANSACTIONAL_CONFLICT: return L"STATUS_TRANSACTIONAL_CONFLICT"; + case STATUS_INVALID_TRANSACTION: return L"STATUS_INVALID_TRANSACTION"; + case STATUS_TRANSACTION_NOT_ACTIVE: return L"STATUS_TRANSACTION_NOT_ACTIVE"; + case STATUS_TM_INITIALIZATION_FAILED: return L"STATUS_TM_INITIALIZATION_FAILED"; + case STATUS_RM_NOT_ACTIVE: return L"STATUS_RM_NOT_ACTIVE"; + case STATUS_RM_METADATA_CORRUPT: return L"STATUS_RM_METADATA_CORRUPT"; + case STATUS_TRANSACTION_NOT_JOINED: return L"STATUS_TRANSACTION_NOT_JOINED"; + case STATUS_DIRECTORY_NOT_RM: return L"STATUS_DIRECTORY_NOT_RM"; + case STATUS_COULD_NOT_RESIZE_LOG: return L"STATUS_COULD_NOT_RESIZE_LOG"; + case STATUS_TRANSACTIONS_UNSUPPORTED_REMOTE: return L"STATUS_TRANSACTIONS_UNSUPPORTED_REMOTE"; + case STATUS_LOG_RESIZE_INVALID_SIZE: return L"STATUS_LOG_RESIZE_INVALID_SIZE"; + case STATUS_REMOTE_FILE_VERSION_MISMATCH: return L"STATUS_REMOTE_FILE_VERSION_MISMATCH"; + case STATUS_CRM_PROTOCOL_ALREADY_EXISTS: return L"STATUS_CRM_PROTOCOL_ALREADY_EXISTS"; + case STATUS_TRANSACTION_PROPAGATION_FAILED: return L"STATUS_TRANSACTION_PROPAGATION_FAILED"; + case STATUS_CRM_PROTOCOL_NOT_FOUND: return L"STATUS_CRM_PROTOCOL_NOT_FOUND"; + case STATUS_TRANSACTION_SUPERIOR_EXISTS: return L"STATUS_TRANSACTION_SUPERIOR_EXISTS"; + case STATUS_TRANSACTION_REQUEST_NOT_VALID: return L"STATUS_TRANSACTION_REQUEST_NOT_VALID"; + case STATUS_TRANSACTION_NOT_REQUESTED: return L"STATUS_TRANSACTION_NOT_REQUESTED"; + case STATUS_TRANSACTION_ALREADY_ABORTED: return L"STATUS_TRANSACTION_ALREADY_ABORTED"; + case STATUS_TRANSACTION_ALREADY_COMMITTED: return L"STATUS_TRANSACTION_ALREADY_COMMITTED"; + case STATUS_TRANSACTION_INVALID_MARSHALL_BUFFER: return L"STATUS_TRANSACTION_INVALID_MARSHALL_BUFFER"; + case STATUS_CURRENT_TRANSACTION_NOT_VALID: return L"STATUS_CURRENT_TRANSACTION_NOT_VALID"; + case STATUS_LOG_GROWTH_FAILED: return L"STATUS_LOG_GROWTH_FAILED"; + case STATUS_OBJECT_NO_LONGER_EXISTS: return L"STATUS_OBJECT_NO_LONGER_EXISTS"; + case STATUS_STREAM_MINIVERSION_NOT_FOUND: return L"STATUS_STREAM_MINIVERSION_NOT_FOUND"; + case STATUS_STREAM_MINIVERSION_NOT_VALID: return L"STATUS_STREAM_MINIVERSION_NOT_VALID"; + case STATUS_MINIVERSION_INACCESSIBLE_FROM_SPECIFIED_TRANSACTION: return L"STATUS_MINIVERSION_INACCESSIBLE_FROM_SPECIFIED_TRANSACTION"; + case STATUS_CANT_OPEN_MINIVERSION_WITH_MODIFY_INTENT: return L"STATUS_CANT_OPEN_MINIVERSION_WITH_MODIFY_INTENT"; + case STATUS_CANT_CREATE_MORE_STREAM_MINIVERSIONS: return L"STATUS_CANT_CREATE_MORE_STREAM_MINIVERSIONS"; + case STATUS_HANDLE_NO_LONGER_VALID: return L"STATUS_HANDLE_NO_LONGER_VALID"; + case STATUS_NO_TXF_METADATA: return L"STATUS_NO_TXF_METADATA"; + case STATUS_LOG_CORRUPTION_DETECTED: return L"STATUS_LOG_CORRUPTION_DETECTED"; + case STATUS_CANT_RECOVER_WITH_HANDLE_OPEN: return L"STATUS_CANT_RECOVER_WITH_HANDLE_OPEN"; + case STATUS_RM_DISCONNECTED: return L"STATUS_RM_DISCONNECTED"; + case STATUS_ENLISTMENT_NOT_SUPERIOR: return L"STATUS_ENLISTMENT_NOT_SUPERIOR"; + case STATUS_RECOVERY_NOT_NEEDED: return L"STATUS_RECOVERY_NOT_NEEDED"; + case STATUS_RM_ALREADY_STARTED: return L"STATUS_RM_ALREADY_STARTED"; + case STATUS_FILE_IDENTITY_NOT_PERSISTENT: return L"STATUS_FILE_IDENTITY_NOT_PERSISTENT"; + case STATUS_CANT_BREAK_TRANSACTIONAL_DEPENDENCY: return L"STATUS_CANT_BREAK_TRANSACTIONAL_DEPENDENCY"; + case STATUS_CANT_CROSS_RM_BOUNDARY: return L"STATUS_CANT_CROSS_RM_BOUNDARY"; + case STATUS_TXF_DIR_NOT_EMPTY: return L"STATUS_TXF_DIR_NOT_EMPTY"; + case STATUS_INDOUBT_TRANSACTIONS_EXIST: return L"STATUS_INDOUBT_TRANSACTIONS_EXIST"; + case STATUS_TM_VOLATILE: return L"STATUS_TM_VOLATILE"; + case STATUS_ROLLBACK_TIMER_EXPIRED: return L"STATUS_ROLLBACK_TIMER_EXPIRED"; + case STATUS_TXF_ATTRIBUTE_CORRUPT: return L"STATUS_TXF_ATTRIBUTE_CORRUPT"; + case STATUS_EFS_NOT_ALLOWED_IN_TRANSACTION: return L"STATUS_EFS_NOT_ALLOWED_IN_TRANSACTION"; + case STATUS_TRANSACTIONAL_OPEN_NOT_ALLOWED: return L"STATUS_TRANSACTIONAL_OPEN_NOT_ALLOWED"; + case STATUS_TRANSACTED_MAPPING_UNSUPPORTED_REMOTE: return L"STATUS_TRANSACTED_MAPPING_UNSUPPORTED_REMOTE"; + case STATUS_TXF_METADATA_ALREADY_PRESENT: return L"STATUS_TXF_METADATA_ALREADY_PRESENT"; + case STATUS_TRANSACTION_SCOPE_CALLBACKS_NOT_SET: return L"STATUS_TRANSACTION_SCOPE_CALLBACKS_NOT_SET"; + case STATUS_TRANSACTION_REQUIRED_PROMOTION: return L"STATUS_TRANSACTION_REQUIRED_PROMOTION"; + case STATUS_CANNOT_EXECUTE_FILE_IN_TRANSACTION: return L"STATUS_CANNOT_EXECUTE_FILE_IN_TRANSACTION"; + case STATUS_TRANSACTIONS_NOT_FROZEN: return L"STATUS_TRANSACTIONS_NOT_FROZEN"; + case STATUS_TRANSACTION_FREEZE_IN_PROGRESS: return L"STATUS_TRANSACTION_FREEZE_IN_PROGRESS"; + case STATUS_NOT_SNAPSHOT_VOLUME: return L"STATUS_NOT_SNAPSHOT_VOLUME"; + case STATUS_NO_SAVEPOINT_WITH_OPEN_FILES: return L"STATUS_NO_SAVEPOINT_WITH_OPEN_FILES"; + case STATUS_SPARSE_NOT_ALLOWED_IN_TRANSACTION: return L"STATUS_SPARSE_NOT_ALLOWED_IN_TRANSACTION"; + case STATUS_TM_IDENTITY_MISMATCH: return L"STATUS_TM_IDENTITY_MISMATCH"; + case STATUS_FLOATED_SECTION: return L"STATUS_FLOATED_SECTION"; + case STATUS_CANNOT_ACCEPT_TRANSACTED_WORK: return L"STATUS_CANNOT_ACCEPT_TRANSACTED_WORK"; + case STATUS_CANNOT_ABORT_TRANSACTIONS: return L"STATUS_CANNOT_ABORT_TRANSACTIONS"; + case STATUS_TRANSACTION_NOT_FOUND: return L"STATUS_TRANSACTION_NOT_FOUND"; + case STATUS_RESOURCEMANAGER_NOT_FOUND: return L"STATUS_RESOURCEMANAGER_NOT_FOUND"; + case STATUS_ENLISTMENT_NOT_FOUND: return L"STATUS_ENLISTMENT_NOT_FOUND"; + case STATUS_TRANSACTIONMANAGER_NOT_FOUND: return L"STATUS_TRANSACTIONMANAGER_NOT_FOUND"; + case STATUS_TRANSACTIONMANAGER_NOT_ONLINE: return L"STATUS_TRANSACTIONMANAGER_NOT_ONLINE"; + case STATUS_TRANSACTIONMANAGER_RECOVERY_NAME_COLLISION: return L"STATUS_TRANSACTIONMANAGER_RECOVERY_NAME_COLLISION"; + case STATUS_TRANSACTION_NOT_ROOT: return L"STATUS_TRANSACTION_NOT_ROOT"; + case STATUS_TRANSACTION_OBJECT_EXPIRED: return L"STATUS_TRANSACTION_OBJECT_EXPIRED"; + case STATUS_COMPRESSION_NOT_ALLOWED_IN_TRANSACTION: return L"STATUS_COMPRESSION_NOT_ALLOWED_IN_TRANSACTION"; + case STATUS_TRANSACTION_RESPONSE_NOT_ENLISTED: return L"STATUS_TRANSACTION_RESPONSE_NOT_ENLISTED"; + case STATUS_TRANSACTION_RECORD_TOO_LONG: return L"STATUS_TRANSACTION_RECORD_TOO_LONG"; + case STATUS_NO_LINK_TRACKING_IN_TRANSACTION: return L"STATUS_NO_LINK_TRACKING_IN_TRANSACTION"; + case STATUS_OPERATION_NOT_SUPPORTED_IN_TRANSACTION: return L"STATUS_OPERATION_NOT_SUPPORTED_IN_TRANSACTION"; + case STATUS_TRANSACTION_INTEGRITY_VIOLATED: return L"STATUS_TRANSACTION_INTEGRITY_VIOLATED"; + case STATUS_TRANSACTIONMANAGER_IDENTITY_MISMATCH: return L"STATUS_TRANSACTIONMANAGER_IDENTITY_MISMATCH"; + case STATUS_RM_CANNOT_BE_FROZEN_FOR_SNAPSHOT: return L"STATUS_RM_CANNOT_BE_FROZEN_FOR_SNAPSHOT"; + case STATUS_TRANSACTION_MUST_WRITETHROUGH: return L"STATUS_TRANSACTION_MUST_WRITETHROUGH"; + case STATUS_TRANSACTION_NO_SUPERIOR: return L"STATUS_TRANSACTION_NO_SUPERIOR"; + case STATUS_EXPIRED_HANDLE: return L"STATUS_EXPIRED_HANDLE"; + case STATUS_TRANSACTION_NOT_ENLISTED: return L"STATUS_TRANSACTION_NOT_ENLISTED"; + case STATUS_LOG_SECTOR_INVALID: return L"STATUS_LOG_SECTOR_INVALID"; + case STATUS_LOG_SECTOR_PARITY_INVALID: return L"STATUS_LOG_SECTOR_PARITY_INVALID"; + case STATUS_LOG_SECTOR_REMAPPED: return L"STATUS_LOG_SECTOR_REMAPPED"; + case STATUS_LOG_BLOCK_INCOMPLETE: return L"STATUS_LOG_BLOCK_INCOMPLETE"; + case STATUS_LOG_INVALID_RANGE: return L"STATUS_LOG_INVALID_RANGE"; + case STATUS_LOG_BLOCKS_EXHAUSTED: return L"STATUS_LOG_BLOCKS_EXHAUSTED"; + case STATUS_LOG_READ_CONTEXT_INVALID: return L"STATUS_LOG_READ_CONTEXT_INVALID"; + case STATUS_LOG_RESTART_INVALID: return L"STATUS_LOG_RESTART_INVALID"; + case STATUS_LOG_BLOCK_VERSION: return L"STATUS_LOG_BLOCK_VERSION"; + case STATUS_LOG_BLOCK_INVALID: return L"STATUS_LOG_BLOCK_INVALID"; + case STATUS_LOG_READ_MODE_INVALID: return L"STATUS_LOG_READ_MODE_INVALID"; + case STATUS_LOG_NO_RESTART: return L"STATUS_LOG_NO_RESTART"; + case STATUS_LOG_METADATA_CORRUPT: return L"STATUS_LOG_METADATA_CORRUPT"; + case STATUS_LOG_METADATA_INVALID: return L"STATUS_LOG_METADATA_INVALID"; + case STATUS_LOG_METADATA_INCONSISTENT: return L"STATUS_LOG_METADATA_INCONSISTENT"; + case STATUS_LOG_RESERVATION_INVALID: return L"STATUS_LOG_RESERVATION_INVALID"; + case STATUS_LOG_CANT_DELETE: return L"STATUS_LOG_CANT_DELETE"; + case STATUS_LOG_CONTAINER_LIMIT_EXCEEDED: return L"STATUS_LOG_CONTAINER_LIMIT_EXCEEDED"; + case STATUS_LOG_START_OF_LOG: return L"STATUS_LOG_START_OF_LOG"; + case STATUS_LOG_POLICY_ALREADY_INSTALLED: return L"STATUS_LOG_POLICY_ALREADY_INSTALLED"; + case STATUS_LOG_POLICY_NOT_INSTALLED: return L"STATUS_LOG_POLICY_NOT_INSTALLED"; + case STATUS_LOG_POLICY_INVALID: return L"STATUS_LOG_POLICY_INVALID"; + case STATUS_LOG_POLICY_CONFLICT: return L"STATUS_LOG_POLICY_CONFLICT"; + case STATUS_LOG_PINNED_ARCHIVE_TAIL: return L"STATUS_LOG_PINNED_ARCHIVE_TAIL"; + case STATUS_LOG_RECORD_NONEXISTENT: return L"STATUS_LOG_RECORD_NONEXISTENT"; + case STATUS_LOG_RECORDS_RESERVED_INVALID: return L"STATUS_LOG_RECORDS_RESERVED_INVALID"; + case STATUS_LOG_SPACE_RESERVED_INVALID: return L"STATUS_LOG_SPACE_RESERVED_INVALID"; + case STATUS_LOG_TAIL_INVALID: return L"STATUS_LOG_TAIL_INVALID"; + case STATUS_LOG_FULL: return L"STATUS_LOG_FULL"; + case STATUS_LOG_MULTIPLEXED: return L"STATUS_LOG_MULTIPLEXED"; + case STATUS_LOG_DEDICATED: return L"STATUS_LOG_DEDICATED"; + case STATUS_LOG_ARCHIVE_NOT_IN_PROGRESS: return L"STATUS_LOG_ARCHIVE_NOT_IN_PROGRESS"; + case STATUS_LOG_ARCHIVE_IN_PROGRESS: return L"STATUS_LOG_ARCHIVE_IN_PROGRESS"; + case STATUS_LOG_EPHEMERAL: return L"STATUS_LOG_EPHEMERAL"; + case STATUS_LOG_NOT_ENOUGH_CONTAINERS: return L"STATUS_LOG_NOT_ENOUGH_CONTAINERS"; + case STATUS_LOG_CLIENT_ALREADY_REGISTERED: return L"STATUS_LOG_CLIENT_ALREADY_REGISTERED"; + case STATUS_LOG_CLIENT_NOT_REGISTERED: return L"STATUS_LOG_CLIENT_NOT_REGISTERED"; + case STATUS_LOG_FULL_HANDLER_IN_PROGRESS: return L"STATUS_LOG_FULL_HANDLER_IN_PROGRESS"; + case STATUS_LOG_CONTAINER_READ_FAILED: return L"STATUS_LOG_CONTAINER_READ_FAILED"; + case STATUS_LOG_CONTAINER_WRITE_FAILED: return L"STATUS_LOG_CONTAINER_WRITE_FAILED"; + case STATUS_LOG_CONTAINER_OPEN_FAILED: return L"STATUS_LOG_CONTAINER_OPEN_FAILED"; + case STATUS_LOG_CONTAINER_STATE_INVALID: return L"STATUS_LOG_CONTAINER_STATE_INVALID"; + case STATUS_LOG_STATE_INVALID: return L"STATUS_LOG_STATE_INVALID"; + case STATUS_LOG_PINNED: return L"STATUS_LOG_PINNED"; + case STATUS_LOG_METADATA_FLUSH_FAILED: return L"STATUS_LOG_METADATA_FLUSH_FAILED"; + case STATUS_LOG_INCONSISTENT_SECURITY: return L"STATUS_LOG_INCONSISTENT_SECURITY"; + case STATUS_LOG_APPENDED_FLUSH_FAILED: return L"STATUS_LOG_APPENDED_FLUSH_FAILED"; + case STATUS_LOG_PINNED_RESERVATION: return L"STATUS_LOG_PINNED_RESERVATION"; + case STATUS_VIDEO_HUNG_DISPLAY_DRIVER_THREAD: return L"STATUS_VIDEO_HUNG_DISPLAY_DRIVER_THREAD"; + case STATUS_VIDEO_HUNG_DISPLAY_DRIVER_THREAD_RECOVERED: return L"STATUS_VIDEO_HUNG_DISPLAY_DRIVER_THREAD_RECOVERED"; + case STATUS_VIDEO_DRIVER_DEBUG_REPORT_REQUEST: return L"STATUS_VIDEO_DRIVER_DEBUG_REPORT_REQUEST"; + case STATUS_MONITOR_NO_DESCRIPTOR: return L"STATUS_MONITOR_NO_DESCRIPTOR"; + case STATUS_MONITOR_UNKNOWN_DESCRIPTOR_FORMAT: return L"STATUS_MONITOR_UNKNOWN_DESCRIPTOR_FORMAT"; + case STATUS_MONITOR_INVALID_DESCRIPTOR_CHECKSUM: return L"STATUS_MONITOR_INVALID_DESCRIPTOR_CHECKSUM"; + case STATUS_MONITOR_INVALID_STANDARD_TIMING_BLOCK: return L"STATUS_MONITOR_INVALID_STANDARD_TIMING_BLOCK"; + case STATUS_MONITOR_WMI_DATABLOCK_REGISTRATION_FAILED: return L"STATUS_MONITOR_WMI_DATABLOCK_REGISTRATION_FAILED"; + case STATUS_MONITOR_INVALID_SERIAL_NUMBER_MONDSC_BLOCK: return L"STATUS_MONITOR_INVALID_SERIAL_NUMBER_MONDSC_BLOCK"; + case STATUS_MONITOR_INVALID_USER_FRIENDLY_MONDSC_BLOCK: return L"STATUS_MONITOR_INVALID_USER_FRIENDLY_MONDSC_BLOCK"; + case STATUS_MONITOR_NO_MORE_DESCRIPTOR_DATA: return L"STATUS_MONITOR_NO_MORE_DESCRIPTOR_DATA"; + case STATUS_MONITOR_INVALID_DETAILED_TIMING_BLOCK: return L"STATUS_MONITOR_INVALID_DETAILED_TIMING_BLOCK"; + case STATUS_MONITOR_INVALID_MANUFACTURE_DATE: return L"STATUS_MONITOR_INVALID_MANUFACTURE_DATE"; + case STATUS_GRAPHICS_NOT_EXCLUSIVE_MODE_OWNER: return L"STATUS_GRAPHICS_NOT_EXCLUSIVE_MODE_OWNER"; + case STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER: return L"STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER"; + case STATUS_GRAPHICS_INVALID_DISPLAY_ADAPTER: return L"STATUS_GRAPHICS_INVALID_DISPLAY_ADAPTER"; + case STATUS_GRAPHICS_ADAPTER_WAS_RESET: return L"STATUS_GRAPHICS_ADAPTER_WAS_RESET"; + case STATUS_GRAPHICS_INVALID_DRIVER_MODEL: return L"STATUS_GRAPHICS_INVALID_DRIVER_MODEL"; + case STATUS_GRAPHICS_PRESENT_MODE_CHANGED: return L"STATUS_GRAPHICS_PRESENT_MODE_CHANGED"; + case STATUS_GRAPHICS_PRESENT_OCCLUDED: return L"STATUS_GRAPHICS_PRESENT_OCCLUDED"; + case STATUS_GRAPHICS_PRESENT_DENIED: return L"STATUS_GRAPHICS_PRESENT_DENIED"; + case STATUS_GRAPHICS_CANNOTCOLORCONVERT: return L"STATUS_GRAPHICS_CANNOTCOLORCONVERT"; + case STATUS_GRAPHICS_DRIVER_MISMATCH: return L"STATUS_GRAPHICS_DRIVER_MISMATCH"; + case STATUS_GRAPHICS_PARTIAL_DATA_POPULATED: return L"STATUS_GRAPHICS_PARTIAL_DATA_POPULATED"; + case STATUS_GRAPHICS_PRESENT_REDIRECTION_DISABLED: return L"STATUS_GRAPHICS_PRESENT_REDIRECTION_DISABLED"; + case STATUS_GRAPHICS_PRESENT_UNOCCLUDED: return L"STATUS_GRAPHICS_PRESENT_UNOCCLUDED"; + case STATUS_GRAPHICS_NO_VIDEO_MEMORY: return L"STATUS_GRAPHICS_NO_VIDEO_MEMORY"; + case STATUS_GRAPHICS_CANT_LOCK_MEMORY: return L"STATUS_GRAPHICS_CANT_LOCK_MEMORY"; + case STATUS_GRAPHICS_ALLOCATION_BUSY: return L"STATUS_GRAPHICS_ALLOCATION_BUSY"; + case STATUS_GRAPHICS_TOO_MANY_REFERENCES: return L"STATUS_GRAPHICS_TOO_MANY_REFERENCES"; + case STATUS_GRAPHICS_TRY_AGAIN_LATER: return L"STATUS_GRAPHICS_TRY_AGAIN_LATER"; + case STATUS_GRAPHICS_TRY_AGAIN_NOW: return L"STATUS_GRAPHICS_TRY_AGAIN_NOW"; + case STATUS_GRAPHICS_ALLOCATION_INVALID: return L"STATUS_GRAPHICS_ALLOCATION_INVALID"; + case STATUS_GRAPHICS_UNSWIZZLING_APERTURE_UNAVAILABLE: return L"STATUS_GRAPHICS_UNSWIZZLING_APERTURE_UNAVAILABLE"; + case STATUS_GRAPHICS_UNSWIZZLING_APERTURE_UNSUPPORTED: return L"STATUS_GRAPHICS_UNSWIZZLING_APERTURE_UNSUPPORTED"; + case STATUS_GRAPHICS_CANT_EVICT_PINNED_ALLOCATION: return L"STATUS_GRAPHICS_CANT_EVICT_PINNED_ALLOCATION"; + case STATUS_GRAPHICS_INVALID_ALLOCATION_USAGE: return L"STATUS_GRAPHICS_INVALID_ALLOCATION_USAGE"; + case STATUS_GRAPHICS_CANT_RENDER_LOCKED_ALLOCATION: return L"STATUS_GRAPHICS_CANT_RENDER_LOCKED_ALLOCATION"; + case STATUS_GRAPHICS_ALLOCATION_CLOSED: return L"STATUS_GRAPHICS_ALLOCATION_CLOSED"; + case STATUS_GRAPHICS_INVALID_ALLOCATION_INSTANCE: return L"STATUS_GRAPHICS_INVALID_ALLOCATION_INSTANCE"; + case STATUS_GRAPHICS_INVALID_ALLOCATION_HANDLE: return L"STATUS_GRAPHICS_INVALID_ALLOCATION_HANDLE"; + case STATUS_GRAPHICS_WRONG_ALLOCATION_DEVICE: return L"STATUS_GRAPHICS_WRONG_ALLOCATION_DEVICE"; + case STATUS_GRAPHICS_ALLOCATION_CONTENT_LOST: return L"STATUS_GRAPHICS_ALLOCATION_CONTENT_LOST"; + case STATUS_GRAPHICS_GPU_EXCEPTION_ON_DEVICE: return L"STATUS_GRAPHICS_GPU_EXCEPTION_ON_DEVICE"; + case STATUS_GRAPHICS_INVALID_VIDPN_TOPOLOGY: return L"STATUS_GRAPHICS_INVALID_VIDPN_TOPOLOGY"; + case STATUS_GRAPHICS_VIDPN_TOPOLOGY_NOT_SUPPORTED: return L"STATUS_GRAPHICS_VIDPN_TOPOLOGY_NOT_SUPPORTED"; + case STATUS_GRAPHICS_VIDPN_TOPOLOGY_CURRENTLY_NOT_SUPPORTED: return L"STATUS_GRAPHICS_VIDPN_TOPOLOGY_CURRENTLY_NOT_SUPPORTED"; + case STATUS_GRAPHICS_INVALID_VIDPN: return L"STATUS_GRAPHICS_INVALID_VIDPN"; + case STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE: return L"STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE"; + case STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_TARGET: return L"STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_TARGET"; + case STATUS_GRAPHICS_VIDPN_MODALITY_NOT_SUPPORTED: return L"STATUS_GRAPHICS_VIDPN_MODALITY_NOT_SUPPORTED"; + case STATUS_GRAPHICS_MODE_NOT_PINNED: return L"STATUS_GRAPHICS_MODE_NOT_PINNED"; + case STATUS_GRAPHICS_INVALID_VIDPN_SOURCEMODESET: return L"STATUS_GRAPHICS_INVALID_VIDPN_SOURCEMODESET"; + case STATUS_GRAPHICS_INVALID_VIDPN_TARGETMODESET: return L"STATUS_GRAPHICS_INVALID_VIDPN_TARGETMODESET"; + case STATUS_GRAPHICS_INVALID_FREQUENCY: return L"STATUS_GRAPHICS_INVALID_FREQUENCY"; + case STATUS_GRAPHICS_INVALID_ACTIVE_REGION: return L"STATUS_GRAPHICS_INVALID_ACTIVE_REGION"; + case STATUS_GRAPHICS_INVALID_TOTAL_REGION: return L"STATUS_GRAPHICS_INVALID_TOTAL_REGION"; + case STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE_MODE: return L"STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE_MODE"; + case STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_TARGET_MODE: return L"STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_TARGET_MODE"; + case STATUS_GRAPHICS_PINNED_MODE_MUST_REMAIN_IN_SET: return L"STATUS_GRAPHICS_PINNED_MODE_MUST_REMAIN_IN_SET"; + case STATUS_GRAPHICS_PATH_ALREADY_IN_TOPOLOGY: return L"STATUS_GRAPHICS_PATH_ALREADY_IN_TOPOLOGY"; + case STATUS_GRAPHICS_MODE_ALREADY_IN_MODESET: return L"STATUS_GRAPHICS_MODE_ALREADY_IN_MODESET"; + case STATUS_GRAPHICS_INVALID_VIDEOPRESENTSOURCESET: return L"STATUS_GRAPHICS_INVALID_VIDEOPRESENTSOURCESET"; + case STATUS_GRAPHICS_INVALID_VIDEOPRESENTTARGETSET: return L"STATUS_GRAPHICS_INVALID_VIDEOPRESENTTARGETSET"; + case STATUS_GRAPHICS_SOURCE_ALREADY_IN_SET: return L"STATUS_GRAPHICS_SOURCE_ALREADY_IN_SET"; + case STATUS_GRAPHICS_TARGET_ALREADY_IN_SET: return L"STATUS_GRAPHICS_TARGET_ALREADY_IN_SET"; + case STATUS_GRAPHICS_INVALID_VIDPN_PRESENT_PATH: return L"STATUS_GRAPHICS_INVALID_VIDPN_PRESENT_PATH"; + case STATUS_GRAPHICS_NO_RECOMMENDED_VIDPN_TOPOLOGY: return L"STATUS_GRAPHICS_NO_RECOMMENDED_VIDPN_TOPOLOGY"; + case STATUS_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGESET: return L"STATUS_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGESET"; + case STATUS_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGE: return L"STATUS_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGE"; + case STATUS_GRAPHICS_FREQUENCYRANGE_NOT_IN_SET: return L"STATUS_GRAPHICS_FREQUENCYRANGE_NOT_IN_SET"; + case STATUS_GRAPHICS_NO_PREFERRED_MODE: return L"STATUS_GRAPHICS_NO_PREFERRED_MODE"; + case STATUS_GRAPHICS_FREQUENCYRANGE_ALREADY_IN_SET: return L"STATUS_GRAPHICS_FREQUENCYRANGE_ALREADY_IN_SET"; + case STATUS_GRAPHICS_STALE_MODESET: return L"STATUS_GRAPHICS_STALE_MODESET"; + case STATUS_GRAPHICS_INVALID_MONITOR_SOURCEMODESET: return L"STATUS_GRAPHICS_INVALID_MONITOR_SOURCEMODESET"; + case STATUS_GRAPHICS_INVALID_MONITOR_SOURCE_MODE: return L"STATUS_GRAPHICS_INVALID_MONITOR_SOURCE_MODE"; + case STATUS_GRAPHICS_NO_RECOMMENDED_FUNCTIONAL_VIDPN: return L"STATUS_GRAPHICS_NO_RECOMMENDED_FUNCTIONAL_VIDPN"; + case STATUS_GRAPHICS_MODE_ID_MUST_BE_UNIQUE: return L"STATUS_GRAPHICS_MODE_ID_MUST_BE_UNIQUE"; + case STATUS_GRAPHICS_EMPTY_ADAPTER_MONITOR_MODE_SUPPORT_INTERSECTION: return L"STATUS_GRAPHICS_EMPTY_ADAPTER_MONITOR_MODE_SUPPORT_INTERSECTION"; + case STATUS_GRAPHICS_VIDEO_PRESENT_TARGETS_LESS_THAN_SOURCES: return L"STATUS_GRAPHICS_VIDEO_PRESENT_TARGETS_LESS_THAN_SOURCES"; + case STATUS_GRAPHICS_PATH_NOT_IN_TOPOLOGY: return L"STATUS_GRAPHICS_PATH_NOT_IN_TOPOLOGY"; + case STATUS_GRAPHICS_ADAPTER_MUST_HAVE_AT_LEAST_ONE_SOURCE: return L"STATUS_GRAPHICS_ADAPTER_MUST_HAVE_AT_LEAST_ONE_SOURCE"; + case STATUS_GRAPHICS_ADAPTER_MUST_HAVE_AT_LEAST_ONE_TARGET: return L"STATUS_GRAPHICS_ADAPTER_MUST_HAVE_AT_LEAST_ONE_TARGET"; + case STATUS_GRAPHICS_INVALID_MONITORDESCRIPTORSET: return L"STATUS_GRAPHICS_INVALID_MONITORDESCRIPTORSET"; + case STATUS_GRAPHICS_INVALID_MONITORDESCRIPTOR: return L"STATUS_GRAPHICS_INVALID_MONITORDESCRIPTOR"; + case STATUS_GRAPHICS_MONITORDESCRIPTOR_NOT_IN_SET: return L"STATUS_GRAPHICS_MONITORDESCRIPTOR_NOT_IN_SET"; + case STATUS_GRAPHICS_MONITORDESCRIPTOR_ALREADY_IN_SET: return L"STATUS_GRAPHICS_MONITORDESCRIPTOR_ALREADY_IN_SET"; + case STATUS_GRAPHICS_MONITORDESCRIPTOR_ID_MUST_BE_UNIQUE: return L"STATUS_GRAPHICS_MONITORDESCRIPTOR_ID_MUST_BE_UNIQUE"; + case STATUS_GRAPHICS_INVALID_VIDPN_TARGET_SUBSET_TYPE: return L"STATUS_GRAPHICS_INVALID_VIDPN_TARGET_SUBSET_TYPE"; + case STATUS_GRAPHICS_RESOURCES_NOT_RELATED: return L"STATUS_GRAPHICS_RESOURCES_NOT_RELATED"; + case STATUS_GRAPHICS_SOURCE_ID_MUST_BE_UNIQUE: return L"STATUS_GRAPHICS_SOURCE_ID_MUST_BE_UNIQUE"; + case STATUS_GRAPHICS_TARGET_ID_MUST_BE_UNIQUE: return L"STATUS_GRAPHICS_TARGET_ID_MUST_BE_UNIQUE"; + case STATUS_GRAPHICS_NO_AVAILABLE_VIDPN_TARGET: return L"STATUS_GRAPHICS_NO_AVAILABLE_VIDPN_TARGET"; + case STATUS_GRAPHICS_MONITOR_COULD_NOT_BE_ASSOCIATED_WITH_ADAPTER: return L"STATUS_GRAPHICS_MONITOR_COULD_NOT_BE_ASSOCIATED_WITH_ADAPTER"; + case STATUS_GRAPHICS_NO_VIDPNMGR: return L"STATUS_GRAPHICS_NO_VIDPNMGR"; + case STATUS_GRAPHICS_NO_ACTIVE_VIDPN: return L"STATUS_GRAPHICS_NO_ACTIVE_VIDPN"; + case STATUS_GRAPHICS_STALE_VIDPN_TOPOLOGY: return L"STATUS_GRAPHICS_STALE_VIDPN_TOPOLOGY"; + case STATUS_GRAPHICS_MONITOR_NOT_CONNECTED: return L"STATUS_GRAPHICS_MONITOR_NOT_CONNECTED"; + case STATUS_GRAPHICS_SOURCE_NOT_IN_TOPOLOGY: return L"STATUS_GRAPHICS_SOURCE_NOT_IN_TOPOLOGY"; + case STATUS_GRAPHICS_INVALID_PRIMARYSURFACE_SIZE: return L"STATUS_GRAPHICS_INVALID_PRIMARYSURFACE_SIZE"; + case STATUS_GRAPHICS_INVALID_VISIBLEREGION_SIZE: return L"STATUS_GRAPHICS_INVALID_VISIBLEREGION_SIZE"; + case STATUS_GRAPHICS_INVALID_STRIDE: return L"STATUS_GRAPHICS_INVALID_STRIDE"; + case STATUS_GRAPHICS_INVALID_PIXELFORMAT: return L"STATUS_GRAPHICS_INVALID_PIXELFORMAT"; + case STATUS_GRAPHICS_INVALID_COLORBASIS: return L"STATUS_GRAPHICS_INVALID_COLORBASIS"; + case STATUS_GRAPHICS_INVALID_PIXELVALUEACCESSMODE: return L"STATUS_GRAPHICS_INVALID_PIXELVALUEACCESSMODE"; + case STATUS_GRAPHICS_TARGET_NOT_IN_TOPOLOGY: return L"STATUS_GRAPHICS_TARGET_NOT_IN_TOPOLOGY"; + case STATUS_GRAPHICS_NO_DISPLAY_MODE_MANAGEMENT_SUPPORT: return L"STATUS_GRAPHICS_NO_DISPLAY_MODE_MANAGEMENT_SUPPORT"; + case STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE: return L"STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE"; + case STATUS_GRAPHICS_CANT_ACCESS_ACTIVE_VIDPN: return L"STATUS_GRAPHICS_CANT_ACCESS_ACTIVE_VIDPN"; + case STATUS_GRAPHICS_INVALID_PATH_IMPORTANCE_ORDINAL: return L"STATUS_GRAPHICS_INVALID_PATH_IMPORTANCE_ORDINAL"; + case STATUS_GRAPHICS_INVALID_PATH_CONTENT_GEOMETRY_TRANSFORMATION: return L"STATUS_GRAPHICS_INVALID_PATH_CONTENT_GEOMETRY_TRANSFORMATION"; + case STATUS_GRAPHICS_PATH_CONTENT_GEOMETRY_TRANSFORMATION_NOT_SUPPORTED: return L"STATUS_GRAPHICS_PATH_CONTENT_GEOMETRY_TRANSFORMATION_NOT_SUPPORTED"; + case STATUS_GRAPHICS_INVALID_GAMMA_RAMP: return L"STATUS_GRAPHICS_INVALID_GAMMA_RAMP"; + case STATUS_GRAPHICS_GAMMA_RAMP_NOT_SUPPORTED: return L"STATUS_GRAPHICS_GAMMA_RAMP_NOT_SUPPORTED"; + case STATUS_GRAPHICS_MULTISAMPLING_NOT_SUPPORTED: return L"STATUS_GRAPHICS_MULTISAMPLING_NOT_SUPPORTED"; + case STATUS_GRAPHICS_MODE_NOT_IN_MODESET: return L"STATUS_GRAPHICS_MODE_NOT_IN_MODESET"; + case STATUS_GRAPHICS_DATASET_IS_EMPTY: return L"STATUS_GRAPHICS_DATASET_IS_EMPTY"; + case STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET: return L"STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET"; + case STATUS_GRAPHICS_INVALID_VIDPN_TOPOLOGY_RECOMMENDATION_REASON: return L"STATUS_GRAPHICS_INVALID_VIDPN_TOPOLOGY_RECOMMENDATION_REASON"; + case STATUS_GRAPHICS_INVALID_PATH_CONTENT_TYPE: return L"STATUS_GRAPHICS_INVALID_PATH_CONTENT_TYPE"; + case STATUS_GRAPHICS_INVALID_COPYPROTECTION_TYPE: return L"STATUS_GRAPHICS_INVALID_COPYPROTECTION_TYPE"; + case STATUS_GRAPHICS_UNASSIGNED_MODESET_ALREADY_EXISTS: return L"STATUS_GRAPHICS_UNASSIGNED_MODESET_ALREADY_EXISTS"; + case STATUS_GRAPHICS_PATH_CONTENT_GEOMETRY_TRANSFORMATION_NOT_PINNED: return L"STATUS_GRAPHICS_PATH_CONTENT_GEOMETRY_TRANSFORMATION_NOT_PINNED"; + case STATUS_GRAPHICS_INVALID_SCANLINE_ORDERING: return L"STATUS_GRAPHICS_INVALID_SCANLINE_ORDERING"; + case STATUS_GRAPHICS_TOPOLOGY_CHANGES_NOT_ALLOWED: return L"STATUS_GRAPHICS_TOPOLOGY_CHANGES_NOT_ALLOWED"; + case STATUS_GRAPHICS_NO_AVAILABLE_IMPORTANCE_ORDINALS: return L"STATUS_GRAPHICS_NO_AVAILABLE_IMPORTANCE_ORDINALS"; + case STATUS_GRAPHICS_INCOMPATIBLE_PRIVATE_FORMAT: return L"STATUS_GRAPHICS_INCOMPATIBLE_PRIVATE_FORMAT"; + case STATUS_GRAPHICS_INVALID_MODE_PRUNING_ALGORITHM: return L"STATUS_GRAPHICS_INVALID_MODE_PRUNING_ALGORITHM"; + case STATUS_GRAPHICS_INVALID_MONITOR_CAPABILITY_ORIGIN: return L"STATUS_GRAPHICS_INVALID_MONITOR_CAPABILITY_ORIGIN"; + case STATUS_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGE_CONSTRAINT: return L"STATUS_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGE_CONSTRAINT"; + case STATUS_GRAPHICS_MAX_NUM_PATHS_REACHED: return L"STATUS_GRAPHICS_MAX_NUM_PATHS_REACHED"; + case STATUS_GRAPHICS_CANCEL_VIDPN_TOPOLOGY_AUGMENTATION: return L"STATUS_GRAPHICS_CANCEL_VIDPN_TOPOLOGY_AUGMENTATION"; + case STATUS_GRAPHICS_INVALID_CLIENT_TYPE: return L"STATUS_GRAPHICS_INVALID_CLIENT_TYPE"; + case STATUS_GRAPHICS_CLIENTVIDPN_NOT_SET: return L"STATUS_GRAPHICS_CLIENTVIDPN_NOT_SET"; + case STATUS_GRAPHICS_SPECIFIED_CHILD_ALREADY_CONNECTED: return L"STATUS_GRAPHICS_SPECIFIED_CHILD_ALREADY_CONNECTED"; + case STATUS_GRAPHICS_CHILD_DESCRIPTOR_NOT_SUPPORTED: return L"STATUS_GRAPHICS_CHILD_DESCRIPTOR_NOT_SUPPORTED"; + case STATUS_GRAPHICS_UNKNOWN_CHILD_STATUS: return L"STATUS_GRAPHICS_UNKNOWN_CHILD_STATUS"; + case STATUS_GRAPHICS_NOT_A_LINKED_ADAPTER: return L"STATUS_GRAPHICS_NOT_A_LINKED_ADAPTER"; + case STATUS_GRAPHICS_LEADLINK_NOT_ENUMERATED: return L"STATUS_GRAPHICS_LEADLINK_NOT_ENUMERATED"; + case STATUS_GRAPHICS_CHAINLINKS_NOT_ENUMERATED: return L"STATUS_GRAPHICS_CHAINLINKS_NOT_ENUMERATED"; + case STATUS_GRAPHICS_ADAPTER_CHAIN_NOT_READY: return L"STATUS_GRAPHICS_ADAPTER_CHAIN_NOT_READY"; + case STATUS_GRAPHICS_CHAINLINKS_NOT_STARTED: return L"STATUS_GRAPHICS_CHAINLINKS_NOT_STARTED"; + case STATUS_GRAPHICS_CHAINLINKS_NOT_POWERED_ON: return L"STATUS_GRAPHICS_CHAINLINKS_NOT_POWERED_ON"; + case STATUS_GRAPHICS_INCONSISTENT_DEVICE_LINK_STATE: return L"STATUS_GRAPHICS_INCONSISTENT_DEVICE_LINK_STATE"; + case STATUS_GRAPHICS_LEADLINK_START_DEFERRED: return L"STATUS_GRAPHICS_LEADLINK_START_DEFERRED"; + case STATUS_GRAPHICS_NOT_POST_DEVICE_DRIVER: return L"STATUS_GRAPHICS_NOT_POST_DEVICE_DRIVER"; + case STATUS_GRAPHICS_POLLING_TOO_FREQUENTLY: return L"STATUS_GRAPHICS_POLLING_TOO_FREQUENTLY"; + case STATUS_GRAPHICS_START_DEFERRED: return L"STATUS_GRAPHICS_START_DEFERRED"; + case STATUS_GRAPHICS_ADAPTER_ACCESS_NOT_EXCLUDED: return L"STATUS_GRAPHICS_ADAPTER_ACCESS_NOT_EXCLUDED"; + case STATUS_GRAPHICS_OPM_NOT_SUPPORTED: return L"STATUS_GRAPHICS_OPM_NOT_SUPPORTED"; + case STATUS_GRAPHICS_COPP_NOT_SUPPORTED: return L"STATUS_GRAPHICS_COPP_NOT_SUPPORTED"; + case STATUS_GRAPHICS_UAB_NOT_SUPPORTED: return L"STATUS_GRAPHICS_UAB_NOT_SUPPORTED"; + case STATUS_GRAPHICS_OPM_INVALID_ENCRYPTED_PARAMETERS: return L"STATUS_GRAPHICS_OPM_INVALID_ENCRYPTED_PARAMETERS"; + case STATUS_GRAPHICS_OPM_NO_PROTECTED_OUTPUTS_EXIST: return L"STATUS_GRAPHICS_OPM_NO_PROTECTED_OUTPUTS_EXIST"; + case STATUS_GRAPHICS_OPM_INTERNAL_ERROR: return L"STATUS_GRAPHICS_OPM_INTERNAL_ERROR"; + case STATUS_GRAPHICS_OPM_INVALID_HANDLE: return L"STATUS_GRAPHICS_OPM_INVALID_HANDLE"; + case STATUS_GRAPHICS_PVP_INVALID_CERTIFICATE_LENGTH: return L"STATUS_GRAPHICS_PVP_INVALID_CERTIFICATE_LENGTH"; + case STATUS_GRAPHICS_OPM_SPANNING_MODE_ENABLED: return L"STATUS_GRAPHICS_OPM_SPANNING_MODE_ENABLED"; + case STATUS_GRAPHICS_OPM_THEATER_MODE_ENABLED: return L"STATUS_GRAPHICS_OPM_THEATER_MODE_ENABLED"; + case STATUS_GRAPHICS_PVP_HFS_FAILED: return L"STATUS_GRAPHICS_PVP_HFS_FAILED"; + case STATUS_GRAPHICS_OPM_INVALID_SRM: return L"STATUS_GRAPHICS_OPM_INVALID_SRM"; + case STATUS_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_HDCP: return L"STATUS_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_HDCP"; + case STATUS_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_ACP: return L"STATUS_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_ACP"; + case STATUS_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_CGMSA: return L"STATUS_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_CGMSA"; + case STATUS_GRAPHICS_OPM_HDCP_SRM_NEVER_SET: return L"STATUS_GRAPHICS_OPM_HDCP_SRM_NEVER_SET"; + case STATUS_GRAPHICS_OPM_RESOLUTION_TOO_HIGH: return L"STATUS_GRAPHICS_OPM_RESOLUTION_TOO_HIGH"; + case STATUS_GRAPHICS_OPM_ALL_HDCP_HARDWARE_ALREADY_IN_USE: return L"STATUS_GRAPHICS_OPM_ALL_HDCP_HARDWARE_ALREADY_IN_USE"; + case STATUS_GRAPHICS_OPM_PROTECTED_OUTPUT_NO_LONGER_EXISTS: return L"STATUS_GRAPHICS_OPM_PROTECTED_OUTPUT_NO_LONGER_EXISTS"; + case STATUS_GRAPHICS_OPM_PROTECTED_OUTPUT_DOES_NOT_HAVE_COPP_SEMANTICS: return L"STATUS_GRAPHICS_OPM_PROTECTED_OUTPUT_DOES_NOT_HAVE_COPP_SEMANTICS"; + case STATUS_GRAPHICS_OPM_INVALID_INFORMATION_REQUEST: return L"STATUS_GRAPHICS_OPM_INVALID_INFORMATION_REQUEST"; + case STATUS_GRAPHICS_OPM_DRIVER_INTERNAL_ERROR: return L"STATUS_GRAPHICS_OPM_DRIVER_INTERNAL_ERROR"; + case STATUS_GRAPHICS_OPM_PROTECTED_OUTPUT_DOES_NOT_HAVE_OPM_SEMANTICS: return L"STATUS_GRAPHICS_OPM_PROTECTED_OUTPUT_DOES_NOT_HAVE_OPM_SEMANTICS"; + case STATUS_GRAPHICS_OPM_SIGNALING_NOT_SUPPORTED: return L"STATUS_GRAPHICS_OPM_SIGNALING_NOT_SUPPORTED"; + case STATUS_GRAPHICS_OPM_INVALID_CONFIGURATION_REQUEST: return L"STATUS_GRAPHICS_OPM_INVALID_CONFIGURATION_REQUEST"; + case STATUS_GRAPHICS_I2C_NOT_SUPPORTED: return L"STATUS_GRAPHICS_I2C_NOT_SUPPORTED"; + case STATUS_GRAPHICS_I2C_DEVICE_DOES_NOT_EXIST: return L"STATUS_GRAPHICS_I2C_DEVICE_DOES_NOT_EXIST"; + case STATUS_GRAPHICS_I2C_ERROR_TRANSMITTING_DATA: return L"STATUS_GRAPHICS_I2C_ERROR_TRANSMITTING_DATA"; + case STATUS_GRAPHICS_I2C_ERROR_RECEIVING_DATA: return L"STATUS_GRAPHICS_I2C_ERROR_RECEIVING_DATA"; + case STATUS_GRAPHICS_DDCCI_VCP_NOT_SUPPORTED: return L"STATUS_GRAPHICS_DDCCI_VCP_NOT_SUPPORTED"; + case STATUS_GRAPHICS_DDCCI_INVALID_DATA: return L"STATUS_GRAPHICS_DDCCI_INVALID_DATA"; + case STATUS_GRAPHICS_DDCCI_MONITOR_RETURNED_INVALID_TIMING_STATUS_BYTE: return L"STATUS_GRAPHICS_DDCCI_MONITOR_RETURNED_INVALID_TIMING_STATUS_BYTE"; + case STATUS_GRAPHICS_DDCCI_INVALID_CAPABILITIES_STRING: return L"STATUS_GRAPHICS_DDCCI_INVALID_CAPABILITIES_STRING"; + case STATUS_GRAPHICS_MCA_INTERNAL_ERROR: return L"STATUS_GRAPHICS_MCA_INTERNAL_ERROR"; + case STATUS_GRAPHICS_DDCCI_INVALID_MESSAGE_COMMAND: return L"STATUS_GRAPHICS_DDCCI_INVALID_MESSAGE_COMMAND"; + case STATUS_GRAPHICS_DDCCI_INVALID_MESSAGE_LENGTH: return L"STATUS_GRAPHICS_DDCCI_INVALID_MESSAGE_LENGTH"; + case STATUS_GRAPHICS_DDCCI_INVALID_MESSAGE_CHECKSUM: return L"STATUS_GRAPHICS_DDCCI_INVALID_MESSAGE_CHECKSUM"; + case STATUS_GRAPHICS_INVALID_PHYSICAL_MONITOR_HANDLE: return L"STATUS_GRAPHICS_INVALID_PHYSICAL_MONITOR_HANDLE"; + case STATUS_GRAPHICS_MONITOR_NO_LONGER_EXISTS: return L"STATUS_GRAPHICS_MONITOR_NO_LONGER_EXISTS"; + case STATUS_GRAPHICS_ONLY_CONSOLE_SESSION_SUPPORTED: return L"STATUS_GRAPHICS_ONLY_CONSOLE_SESSION_SUPPORTED"; + case STATUS_GRAPHICS_NO_DISPLAY_DEVICE_CORRESPONDS_TO_NAME: return L"STATUS_GRAPHICS_NO_DISPLAY_DEVICE_CORRESPONDS_TO_NAME"; + case STATUS_GRAPHICS_DISPLAY_DEVICE_NOT_ATTACHED_TO_DESKTOP: return L"STATUS_GRAPHICS_DISPLAY_DEVICE_NOT_ATTACHED_TO_DESKTOP"; + case STATUS_GRAPHICS_MIRRORING_DEVICES_NOT_SUPPORTED: return L"STATUS_GRAPHICS_MIRRORING_DEVICES_NOT_SUPPORTED"; + case STATUS_GRAPHICS_INVALID_POINTER: return L"STATUS_GRAPHICS_INVALID_POINTER"; + case STATUS_GRAPHICS_NO_MONITORS_CORRESPOND_TO_DISPLAY_DEVICE: return L"STATUS_GRAPHICS_NO_MONITORS_CORRESPOND_TO_DISPLAY_DEVICE"; + case STATUS_GRAPHICS_PARAMETER_ARRAY_TOO_SMALL: return L"STATUS_GRAPHICS_PARAMETER_ARRAY_TOO_SMALL"; + case STATUS_GRAPHICS_INTERNAL_ERROR: return L"STATUS_GRAPHICS_INTERNAL_ERROR"; + case STATUS_GRAPHICS_SESSION_TYPE_CHANGE_IN_PROGRESS: return L"STATUS_GRAPHICS_SESSION_TYPE_CHANGE_IN_PROGRESS"; + case STATUS_FVE_LOCKED_VOLUME: return L"STATUS_FVE_LOCKED_VOLUME"; + case STATUS_FVE_NOT_ENCRYPTED: return L"STATUS_FVE_NOT_ENCRYPTED"; + case STATUS_FVE_BAD_INFORMATION: return L"STATUS_FVE_BAD_INFORMATION"; + case STATUS_FVE_TOO_SMALL: return L"STATUS_FVE_TOO_SMALL"; + case STATUS_FVE_FAILED_WRONG_FS: return L"STATUS_FVE_FAILED_WRONG_FS"; + case STATUS_FVE_BAD_PARTITION_SIZE: return L"STATUS_FVE_BAD_PARTITION_SIZE"; + case STATUS_FVE_FS_NOT_EXTENDED: return L"STATUS_FVE_FS_NOT_EXTENDED"; + case STATUS_FVE_FS_MOUNTED: return L"STATUS_FVE_FS_MOUNTED"; + case STATUS_FVE_NO_LICENSE: return L"STATUS_FVE_NO_LICENSE"; + case STATUS_FVE_ACTION_NOT_ALLOWED: return L"STATUS_FVE_ACTION_NOT_ALLOWED"; + case STATUS_FVE_BAD_DATA: return L"STATUS_FVE_BAD_DATA"; + case STATUS_FVE_VOLUME_NOT_BOUND: return L"STATUS_FVE_VOLUME_NOT_BOUND"; + case STATUS_FVE_NOT_DATA_VOLUME: return L"STATUS_FVE_NOT_DATA_VOLUME"; + case STATUS_FVE_CONV_READ_ERROR: return L"STATUS_FVE_CONV_READ_ERROR"; + case STATUS_FVE_CONV_WRITE_ERROR: return L"STATUS_FVE_CONV_WRITE_ERROR"; + case STATUS_FVE_OVERLAPPED_UPDATE: return L"STATUS_FVE_OVERLAPPED_UPDATE"; + case STATUS_FVE_FAILED_SECTOR_SIZE: return L"STATUS_FVE_FAILED_SECTOR_SIZE"; + case STATUS_FVE_FAILED_AUTHENTICATION: return L"STATUS_FVE_FAILED_AUTHENTICATION"; + case STATUS_FVE_NOT_OS_VOLUME: return L"STATUS_FVE_NOT_OS_VOLUME"; + case STATUS_FVE_KEYFILE_NOT_FOUND: return L"STATUS_FVE_KEYFILE_NOT_FOUND"; + case STATUS_FVE_KEYFILE_INVALID: return L"STATUS_FVE_KEYFILE_INVALID"; + case STATUS_FVE_KEYFILE_NO_VMK: return L"STATUS_FVE_KEYFILE_NO_VMK"; + case STATUS_FVE_TPM_DISABLED: return L"STATUS_FVE_TPM_DISABLED"; + case STATUS_FVE_TPM_SRK_AUTH_NOT_ZERO: return L"STATUS_FVE_TPM_SRK_AUTH_NOT_ZERO"; + case STATUS_FVE_TPM_INVALID_PCR: return L"STATUS_FVE_TPM_INVALID_PCR"; + case STATUS_FVE_TPM_NO_VMK: return L"STATUS_FVE_TPM_NO_VMK"; + case STATUS_FVE_PIN_INVALID: return L"STATUS_FVE_PIN_INVALID"; + case STATUS_FVE_AUTH_INVALID_APPLICATION: return L"STATUS_FVE_AUTH_INVALID_APPLICATION"; + case STATUS_FVE_AUTH_INVALID_CONFIG: return L"STATUS_FVE_AUTH_INVALID_CONFIG"; + case STATUS_FVE_DEBUGGER_ENABLED: return L"STATUS_FVE_DEBUGGER_ENABLED"; + case STATUS_FVE_DRY_RUN_FAILED: return L"STATUS_FVE_DRY_RUN_FAILED"; + case STATUS_FVE_BAD_METADATA_POINTER: return L"STATUS_FVE_BAD_METADATA_POINTER"; + case STATUS_FVE_OLD_METADATA_COPY: return L"STATUS_FVE_OLD_METADATA_COPY"; + case STATUS_FVE_REBOOT_REQUIRED: return L"STATUS_FVE_REBOOT_REQUIRED"; + case STATUS_FVE_RAW_ACCESS: return L"STATUS_FVE_RAW_ACCESS"; + case STATUS_FVE_RAW_BLOCKED: return L"STATUS_FVE_RAW_BLOCKED"; + case STATUS_FVE_NO_AUTOUNLOCK_MASTER_KEY: return L"STATUS_FVE_NO_AUTOUNLOCK_MASTER_KEY"; + case STATUS_FVE_MOR_FAILED: return L"STATUS_FVE_MOR_FAILED"; + case STATUS_FVE_NO_FEATURE_LICENSE: return L"STATUS_FVE_NO_FEATURE_LICENSE"; + case STATUS_FVE_POLICY_USER_DISABLE_RDV_NOT_ALLOWED: return L"STATUS_FVE_POLICY_USER_DISABLE_RDV_NOT_ALLOWED"; + case STATUS_FVE_CONV_RECOVERY_FAILED: return L"STATUS_FVE_CONV_RECOVERY_FAILED"; + case STATUS_FVE_VIRTUALIZED_SPACE_TOO_BIG: return L"STATUS_FVE_VIRTUALIZED_SPACE_TOO_BIG"; + case STATUS_FVE_INVALID_DATUM_TYPE: return L"STATUS_FVE_INVALID_DATUM_TYPE"; + case STATUS_FVE_VOLUME_TOO_SMALL: return L"STATUS_FVE_VOLUME_TOO_SMALL"; + case STATUS_FVE_ENH_PIN_INVALID: return L"STATUS_FVE_ENH_PIN_INVALID"; + case STATUS_FWP_CALLOUT_NOT_FOUND: return L"STATUS_FWP_CALLOUT_NOT_FOUND"; + case STATUS_FWP_CONDITION_NOT_FOUND: return L"STATUS_FWP_CONDITION_NOT_FOUND"; + case STATUS_FWP_FILTER_NOT_FOUND: return L"STATUS_FWP_FILTER_NOT_FOUND"; + case STATUS_FWP_LAYER_NOT_FOUND: return L"STATUS_FWP_LAYER_NOT_FOUND"; + case STATUS_FWP_PROVIDER_NOT_FOUND: return L"STATUS_FWP_PROVIDER_NOT_FOUND"; + case STATUS_FWP_PROVIDER_CONTEXT_NOT_FOUND: return L"STATUS_FWP_PROVIDER_CONTEXT_NOT_FOUND"; + case STATUS_FWP_SUBLAYER_NOT_FOUND: return L"STATUS_FWP_SUBLAYER_NOT_FOUND"; + case STATUS_FWP_NOT_FOUND: return L"STATUS_FWP_NOT_FOUND"; + case STATUS_FWP_ALREADY_EXISTS: return L"STATUS_FWP_ALREADY_EXISTS"; + case STATUS_FWP_IN_USE: return L"STATUS_FWP_IN_USE"; + case STATUS_FWP_DYNAMIC_SESSION_IN_PROGRESS: return L"STATUS_FWP_DYNAMIC_SESSION_IN_PROGRESS"; + case STATUS_FWP_WRONG_SESSION: return L"STATUS_FWP_WRONG_SESSION"; + case STATUS_FWP_NO_TXN_IN_PROGRESS: return L"STATUS_FWP_NO_TXN_IN_PROGRESS"; + case STATUS_FWP_TXN_IN_PROGRESS: return L"STATUS_FWP_TXN_IN_PROGRESS"; + case STATUS_FWP_TXN_ABORTED: return L"STATUS_FWP_TXN_ABORTED"; + case STATUS_FWP_SESSION_ABORTED: return L"STATUS_FWP_SESSION_ABORTED"; + case STATUS_FWP_INCOMPATIBLE_TXN: return L"STATUS_FWP_INCOMPATIBLE_TXN"; + case STATUS_FWP_TIMEOUT: return L"STATUS_FWP_TIMEOUT"; + case STATUS_FWP_NET_EVENTS_DISABLED: return L"STATUS_FWP_NET_EVENTS_DISABLED"; + case STATUS_FWP_INCOMPATIBLE_LAYER: return L"STATUS_FWP_INCOMPATIBLE_LAYER"; + case STATUS_FWP_KM_CLIENTS_ONLY: return L"STATUS_FWP_KM_CLIENTS_ONLY"; + case STATUS_FWP_LIFETIME_MISMATCH: return L"STATUS_FWP_LIFETIME_MISMATCH"; + case STATUS_FWP_BUILTIN_OBJECT: return L"STATUS_FWP_BUILTIN_OBJECT"; + case STATUS_FWP_TOO_MANY_CALLOUTS: return L"STATUS_FWP_TOO_MANY_CALLOUTS"; + case STATUS_FWP_NOTIFICATION_DROPPED: return L"STATUS_FWP_NOTIFICATION_DROPPED"; + case STATUS_FWP_TRAFFIC_MISMATCH: return L"STATUS_FWP_TRAFFIC_MISMATCH"; + case STATUS_FWP_INCOMPATIBLE_SA_STATE: return L"STATUS_FWP_INCOMPATIBLE_SA_STATE"; + case STATUS_FWP_NULL_POINTER: return L"STATUS_FWP_NULL_POINTER"; + case STATUS_FWP_INVALID_ENUMERATOR: return L"STATUS_FWP_INVALID_ENUMERATOR"; + case STATUS_FWP_INVALID_FLAGS: return L"STATUS_FWP_INVALID_FLAGS"; + case STATUS_FWP_INVALID_NET_MASK: return L"STATUS_FWP_INVALID_NET_MASK"; + case STATUS_FWP_INVALID_RANGE: return L"STATUS_FWP_INVALID_RANGE"; + case STATUS_FWP_INVALID_INTERVAL: return L"STATUS_FWP_INVALID_INTERVAL"; + case STATUS_FWP_ZERO_LENGTH_ARRAY: return L"STATUS_FWP_ZERO_LENGTH_ARRAY"; + case STATUS_FWP_NULL_DISPLAY_NAME: return L"STATUS_FWP_NULL_DISPLAY_NAME"; + case STATUS_FWP_INVALID_ACTION_TYPE: return L"STATUS_FWP_INVALID_ACTION_TYPE"; + case STATUS_FWP_INVALID_WEIGHT: return L"STATUS_FWP_INVALID_WEIGHT"; + case STATUS_FWP_MATCH_TYPE_MISMATCH: return L"STATUS_FWP_MATCH_TYPE_MISMATCH"; + case STATUS_FWP_TYPE_MISMATCH: return L"STATUS_FWP_TYPE_MISMATCH"; + case STATUS_FWP_OUT_OF_BOUNDS: return L"STATUS_FWP_OUT_OF_BOUNDS"; + case STATUS_FWP_RESERVED: return L"STATUS_FWP_RESERVED"; + case STATUS_FWP_DUPLICATE_CONDITION: return L"STATUS_FWP_DUPLICATE_CONDITION"; + case STATUS_FWP_DUPLICATE_KEYMOD: return L"STATUS_FWP_DUPLICATE_KEYMOD"; + case STATUS_FWP_ACTION_INCOMPATIBLE_WITH_LAYER: return L"STATUS_FWP_ACTION_INCOMPATIBLE_WITH_LAYER"; + case STATUS_FWP_ACTION_INCOMPATIBLE_WITH_SUBLAYER: return L"STATUS_FWP_ACTION_INCOMPATIBLE_WITH_SUBLAYER"; + case STATUS_FWP_CONTEXT_INCOMPATIBLE_WITH_LAYER: return L"STATUS_FWP_CONTEXT_INCOMPATIBLE_WITH_LAYER"; + case STATUS_FWP_CONTEXT_INCOMPATIBLE_WITH_CALLOUT: return L"STATUS_FWP_CONTEXT_INCOMPATIBLE_WITH_CALLOUT"; + case STATUS_FWP_INCOMPATIBLE_AUTH_METHOD: return L"STATUS_FWP_INCOMPATIBLE_AUTH_METHOD"; + case STATUS_FWP_INCOMPATIBLE_DH_GROUP: return L"STATUS_FWP_INCOMPATIBLE_DH_GROUP"; + case STATUS_FWP_EM_NOT_SUPPORTED: return L"STATUS_FWP_EM_NOT_SUPPORTED"; + case STATUS_FWP_NEVER_MATCH: return L"STATUS_FWP_NEVER_MATCH"; + case STATUS_FWP_PROVIDER_CONTEXT_MISMATCH: return L"STATUS_FWP_PROVIDER_CONTEXT_MISMATCH"; + case STATUS_FWP_INVALID_PARAMETER: return L"STATUS_FWP_INVALID_PARAMETER"; + case STATUS_FWP_TOO_MANY_SUBLAYERS: return L"STATUS_FWP_TOO_MANY_SUBLAYERS"; + case STATUS_FWP_CALLOUT_NOTIFICATION_FAILED: return L"STATUS_FWP_CALLOUT_NOTIFICATION_FAILED"; + case STATUS_FWP_INVALID_AUTH_TRANSFORM: return L"STATUS_FWP_INVALID_AUTH_TRANSFORM"; + case STATUS_FWP_INVALID_CIPHER_TRANSFORM: return L"STATUS_FWP_INVALID_CIPHER_TRANSFORM"; + case STATUS_FWP_INCOMPATIBLE_CIPHER_TRANSFORM: return L"STATUS_FWP_INCOMPATIBLE_CIPHER_TRANSFORM"; + case STATUS_FWP_INVALID_TRANSFORM_COMBINATION: return L"STATUS_FWP_INVALID_TRANSFORM_COMBINATION"; + case STATUS_FWP_DUPLICATE_AUTH_METHOD: return L"STATUS_FWP_DUPLICATE_AUTH_METHOD"; + case STATUS_FWP_TCPIP_NOT_READY: return L"STATUS_FWP_TCPIP_NOT_READY"; + case STATUS_FWP_INJECT_HANDLE_CLOSING: return L"STATUS_FWP_INJECT_HANDLE_CLOSING"; + case STATUS_FWP_INJECT_HANDLE_STALE: return L"STATUS_FWP_INJECT_HANDLE_STALE"; + case STATUS_FWP_CANNOT_PEND: return L"STATUS_FWP_CANNOT_PEND"; + case STATUS_FWP_DROP_NOICMP: return L"STATUS_FWP_DROP_NOICMP"; + case STATUS_NDIS_CLOSING: return L"STATUS_NDIS_CLOSING"; + case STATUS_NDIS_BAD_VERSION: return L"STATUS_NDIS_BAD_VERSION"; + case STATUS_NDIS_BAD_CHARACTERISTICS: return L"STATUS_NDIS_BAD_CHARACTERISTICS"; + case STATUS_NDIS_ADAPTER_NOT_FOUND: return L"STATUS_NDIS_ADAPTER_NOT_FOUND"; + case STATUS_NDIS_OPEN_FAILED: return L"STATUS_NDIS_OPEN_FAILED"; + case STATUS_NDIS_DEVICE_FAILED: return L"STATUS_NDIS_DEVICE_FAILED"; + case STATUS_NDIS_MULTICAST_FULL: return L"STATUS_NDIS_MULTICAST_FULL"; + case STATUS_NDIS_MULTICAST_EXISTS: return L"STATUS_NDIS_MULTICAST_EXISTS"; + case STATUS_NDIS_MULTICAST_NOT_FOUND: return L"STATUS_NDIS_MULTICAST_NOT_FOUND"; + case STATUS_NDIS_REQUEST_ABORTED: return L"STATUS_NDIS_REQUEST_ABORTED"; + case STATUS_NDIS_RESET_IN_PROGRESS: return L"STATUS_NDIS_RESET_IN_PROGRESS"; + case STATUS_NDIS_NOT_SUPPORTED: return L"STATUS_NDIS_NOT_SUPPORTED"; + case STATUS_NDIS_INVALID_PACKET: return L"STATUS_NDIS_INVALID_PACKET"; + case STATUS_NDIS_ADAPTER_NOT_READY: return L"STATUS_NDIS_ADAPTER_NOT_READY"; + case STATUS_NDIS_INVALID_LENGTH: return L"STATUS_NDIS_INVALID_LENGTH"; + case STATUS_NDIS_INVALID_DATA: return L"STATUS_NDIS_INVALID_DATA"; + case STATUS_NDIS_BUFFER_TOO_SHORT: return L"STATUS_NDIS_BUFFER_TOO_SHORT"; + case STATUS_NDIS_INVALID_OID: return L"STATUS_NDIS_INVALID_OID"; + case STATUS_NDIS_ADAPTER_REMOVED: return L"STATUS_NDIS_ADAPTER_REMOVED"; + case STATUS_NDIS_UNSUPPORTED_MEDIA: return L"STATUS_NDIS_UNSUPPORTED_MEDIA"; + case STATUS_NDIS_GROUP_ADDRESS_IN_USE: return L"STATUS_NDIS_GROUP_ADDRESS_IN_USE"; + case STATUS_NDIS_FILE_NOT_FOUND: return L"STATUS_NDIS_FILE_NOT_FOUND"; + case STATUS_NDIS_ERROR_READING_FILE: return L"STATUS_NDIS_ERROR_READING_FILE"; + case STATUS_NDIS_ALREADY_MAPPED: return L"STATUS_NDIS_ALREADY_MAPPED"; + case STATUS_NDIS_RESOURCE_CONFLICT: return L"STATUS_NDIS_RESOURCE_CONFLICT"; + case STATUS_NDIS_MEDIA_DISCONNECTED: return L"STATUS_NDIS_MEDIA_DISCONNECTED"; + case STATUS_NDIS_INVALID_ADDRESS: return L"STATUS_NDIS_INVALID_ADDRESS"; + case STATUS_NDIS_INVALID_DEVICE_REQUEST: return L"STATUS_NDIS_INVALID_DEVICE_REQUEST"; + case STATUS_NDIS_PAUSED: return L"STATUS_NDIS_PAUSED"; + case STATUS_NDIS_INTERFACE_NOT_FOUND: return L"STATUS_NDIS_INTERFACE_NOT_FOUND"; + case STATUS_NDIS_UNSUPPORTED_REVISION: return L"STATUS_NDIS_UNSUPPORTED_REVISION"; + case STATUS_NDIS_INVALID_PORT: return L"STATUS_NDIS_INVALID_PORT"; + case STATUS_NDIS_INVALID_PORT_STATE: return L"STATUS_NDIS_INVALID_PORT_STATE"; + case STATUS_NDIS_LOW_POWER_STATE: return L"STATUS_NDIS_LOW_POWER_STATE"; + case STATUS_NDIS_DOT11_AUTO_CONFIG_ENABLED: return L"STATUS_NDIS_DOT11_AUTO_CONFIG_ENABLED"; + case STATUS_NDIS_DOT11_MEDIA_IN_USE: return L"STATUS_NDIS_DOT11_MEDIA_IN_USE"; + case STATUS_NDIS_DOT11_POWER_STATE_INVALID: return L"STATUS_NDIS_DOT11_POWER_STATE_INVALID"; + case STATUS_NDIS_PM_WOL_PATTERN_LIST_FULL: return L"STATUS_NDIS_PM_WOL_PATTERN_LIST_FULL"; + case STATUS_NDIS_PM_PROTOCOL_OFFLOAD_LIST_FULL: return L"STATUS_NDIS_PM_PROTOCOL_OFFLOAD_LIST_FULL"; + case STATUS_NDIS_INDICATION_REQUIRED: return L"STATUS_NDIS_INDICATION_REQUIRED"; + case STATUS_NDIS_OFFLOAD_POLICY: return L"STATUS_NDIS_OFFLOAD_POLICY"; + case STATUS_NDIS_OFFLOAD_CONNECTION_REJECTED: return L"STATUS_NDIS_OFFLOAD_CONNECTION_REJECTED"; + case STATUS_NDIS_OFFLOAD_PATH_REJECTED: return L"STATUS_NDIS_OFFLOAD_PATH_REJECTED"; + case STATUS_HV_INVALID_HYPERCALL_CODE: return L"STATUS_HV_INVALID_HYPERCALL_CODE"; + case STATUS_HV_INVALID_HYPERCALL_INPUT: return L"STATUS_HV_INVALID_HYPERCALL_INPUT"; + case STATUS_HV_INVALID_ALIGNMENT: return L"STATUS_HV_INVALID_ALIGNMENT"; + case STATUS_HV_INVALID_PARAMETER: return L"STATUS_HV_INVALID_PARAMETER"; + case STATUS_HV_ACCESS_DENIED: return L"STATUS_HV_ACCESS_DENIED"; + case STATUS_HV_INVALID_PARTITION_STATE: return L"STATUS_HV_INVALID_PARTITION_STATE"; + case STATUS_HV_OPERATION_DENIED: return L"STATUS_HV_OPERATION_DENIED"; + case STATUS_HV_UNKNOWN_PROPERTY: return L"STATUS_HV_UNKNOWN_PROPERTY"; + case STATUS_HV_PROPERTY_VALUE_OUT_OF_RANGE: return L"STATUS_HV_PROPERTY_VALUE_OUT_OF_RANGE"; + case STATUS_HV_INSUFFICIENT_MEMORY: return L"STATUS_HV_INSUFFICIENT_MEMORY"; + case STATUS_HV_PARTITION_TOO_DEEP: return L"STATUS_HV_PARTITION_TOO_DEEP"; + case STATUS_HV_INVALID_PARTITION_ID: return L"STATUS_HV_INVALID_PARTITION_ID"; + case STATUS_HV_INVALID_VP_INDEX: return L"STATUS_HV_INVALID_VP_INDEX"; + case STATUS_HV_INVALID_PORT_ID: return L"STATUS_HV_INVALID_PORT_ID"; + case STATUS_HV_INVALID_CONNECTION_ID: return L"STATUS_HV_INVALID_CONNECTION_ID"; + case STATUS_HV_INSUFFICIENT_BUFFERS: return L"STATUS_HV_INSUFFICIENT_BUFFERS"; + case STATUS_HV_NOT_ACKNOWLEDGED: return L"STATUS_HV_NOT_ACKNOWLEDGED"; + case STATUS_HV_ACKNOWLEDGED: return L"STATUS_HV_ACKNOWLEDGED"; + case STATUS_HV_INVALID_SAVE_RESTORE_STATE: return L"STATUS_HV_INVALID_SAVE_RESTORE_STATE"; + case STATUS_HV_INVALID_SYNIC_STATE: return L"STATUS_HV_INVALID_SYNIC_STATE"; + case STATUS_HV_OBJECT_IN_USE: return L"STATUS_HV_OBJECT_IN_USE"; + case STATUS_HV_INVALID_PROXIMITY_DOMAIN_INFO: return L"STATUS_HV_INVALID_PROXIMITY_DOMAIN_INFO"; + case STATUS_HV_NO_DATA: return L"STATUS_HV_NO_DATA"; + case STATUS_HV_INACTIVE: return L"STATUS_HV_INACTIVE"; + case STATUS_HV_NO_RESOURCES: return L"STATUS_HV_NO_RESOURCES"; + case STATUS_HV_FEATURE_UNAVAILABLE: return L"STATUS_HV_FEATURE_UNAVAILABLE"; + case STATUS_HV_NOT_PRESENT: return L"STATUS_HV_NOT_PRESENT"; + case STATUS_VID_DUPLICATE_HANDLER: return L"STATUS_VID_DUPLICATE_HANDLER"; + case STATUS_VID_TOO_MANY_HANDLERS: return L"STATUS_VID_TOO_MANY_HANDLERS"; + case STATUS_VID_QUEUE_FULL: return L"STATUS_VID_QUEUE_FULL"; + case STATUS_VID_HANDLER_NOT_PRESENT: return L"STATUS_VID_HANDLER_NOT_PRESENT"; + case STATUS_VID_INVALID_OBJECT_NAME: return L"STATUS_VID_INVALID_OBJECT_NAME"; + case STATUS_VID_PARTITION_NAME_TOO_LONG: return L"STATUS_VID_PARTITION_NAME_TOO_LONG"; + case STATUS_VID_MESSAGE_QUEUE_NAME_TOO_LONG: return L"STATUS_VID_MESSAGE_QUEUE_NAME_TOO_LONG"; + case STATUS_VID_PARTITION_ALREADY_EXISTS: return L"STATUS_VID_PARTITION_ALREADY_EXISTS"; + case STATUS_VID_PARTITION_DOES_NOT_EXIST: return L"STATUS_VID_PARTITION_DOES_NOT_EXIST"; + case STATUS_VID_PARTITION_NAME_NOT_FOUND: return L"STATUS_VID_PARTITION_NAME_NOT_FOUND"; + case STATUS_VID_MESSAGE_QUEUE_ALREADY_EXISTS: return L"STATUS_VID_MESSAGE_QUEUE_ALREADY_EXISTS"; + case STATUS_VID_EXCEEDED_MBP_ENTRY_MAP_LIMIT: return L"STATUS_VID_EXCEEDED_MBP_ENTRY_MAP_LIMIT"; + case STATUS_VID_MB_STILL_REFERENCED: return L"STATUS_VID_MB_STILL_REFERENCED"; + case STATUS_VID_CHILD_GPA_PAGE_SET_CORRUPTED: return L"STATUS_VID_CHILD_GPA_PAGE_SET_CORRUPTED"; + case STATUS_VID_INVALID_NUMA_SETTINGS: return L"STATUS_VID_INVALID_NUMA_SETTINGS"; + case STATUS_VID_INVALID_NUMA_NODE_INDEX: return L"STATUS_VID_INVALID_NUMA_NODE_INDEX"; + case STATUS_VID_NOTIFICATION_QUEUE_ALREADY_ASSOCIATED: return L"STATUS_VID_NOTIFICATION_QUEUE_ALREADY_ASSOCIATED"; + case STATUS_VID_INVALID_MEMORY_BLOCK_HANDLE: return L"STATUS_VID_INVALID_MEMORY_BLOCK_HANDLE"; + case STATUS_VID_PAGE_RANGE_OVERFLOW: return L"STATUS_VID_PAGE_RANGE_OVERFLOW"; + case STATUS_VID_INVALID_MESSAGE_QUEUE_HANDLE: return L"STATUS_VID_INVALID_MESSAGE_QUEUE_HANDLE"; + case STATUS_VID_INVALID_GPA_RANGE_HANDLE: return L"STATUS_VID_INVALID_GPA_RANGE_HANDLE"; + case STATUS_VID_NO_MEMORY_BLOCK_NOTIFICATION_QUEUE: return L"STATUS_VID_NO_MEMORY_BLOCK_NOTIFICATION_QUEUE"; + case STATUS_VID_MEMORY_BLOCK_LOCK_COUNT_EXCEEDED: return L"STATUS_VID_MEMORY_BLOCK_LOCK_COUNT_EXCEEDED"; + case STATUS_VID_INVALID_PPM_HANDLE: return L"STATUS_VID_INVALID_PPM_HANDLE"; + case STATUS_VID_MBPS_ARE_LOCKED: return L"STATUS_VID_MBPS_ARE_LOCKED"; + case STATUS_VID_MESSAGE_QUEUE_CLOSED: return L"STATUS_VID_MESSAGE_QUEUE_CLOSED"; + case STATUS_VID_VIRTUAL_PROCESSOR_LIMIT_EXCEEDED: return L"STATUS_VID_VIRTUAL_PROCESSOR_LIMIT_EXCEEDED"; + case STATUS_VID_STOP_PENDING: return L"STATUS_VID_STOP_PENDING"; + case STATUS_VID_INVALID_PROCESSOR_STATE: return L"STATUS_VID_INVALID_PROCESSOR_STATE"; + case STATUS_VID_EXCEEDED_KM_CONTEXT_COUNT_LIMIT: return L"STATUS_VID_EXCEEDED_KM_CONTEXT_COUNT_LIMIT"; + case STATUS_VID_KM_INTERFACE_ALREADY_INITIALIZED: return L"STATUS_VID_KM_INTERFACE_ALREADY_INITIALIZED"; + case STATUS_VID_MB_PROPERTY_ALREADY_SET_RESET: return L"STATUS_VID_MB_PROPERTY_ALREADY_SET_RESET"; + case STATUS_VID_MMIO_RANGE_DESTROYED: return L"STATUS_VID_MMIO_RANGE_DESTROYED"; + case STATUS_VID_INVALID_CHILD_GPA_PAGE_SET: return L"STATUS_VID_INVALID_CHILD_GPA_PAGE_SET"; + case STATUS_VID_RESERVE_PAGE_SET_IS_BEING_USED: return L"STATUS_VID_RESERVE_PAGE_SET_IS_BEING_USED"; + case STATUS_VID_RESERVE_PAGE_SET_TOO_SMALL: return L"STATUS_VID_RESERVE_PAGE_SET_TOO_SMALL"; + case STATUS_VID_MBP_ALREADY_LOCKED_USING_RESERVED_PAGE: return L"STATUS_VID_MBP_ALREADY_LOCKED_USING_RESERVED_PAGE"; + case STATUS_VID_MBP_COUNT_EXCEEDED_LIMIT: return L"STATUS_VID_MBP_COUNT_EXCEEDED_LIMIT"; + case STATUS_VID_SAVED_STATE_CORRUPT: return L"STATUS_VID_SAVED_STATE_CORRUPT"; + case STATUS_VID_SAVED_STATE_UNRECOGNIZED_ITEM: return L"STATUS_VID_SAVED_STATE_UNRECOGNIZED_ITEM"; + case STATUS_VID_SAVED_STATE_INCOMPATIBLE: return L"STATUS_VID_SAVED_STATE_INCOMPATIBLE"; + case STATUS_VID_REMOTE_NODE_PARENT_GPA_PAGES_USED: return L"STATUS_VID_REMOTE_NODE_PARENT_GPA_PAGES_USED"; + case STATUS_IPSEC_BAD_SPI: return L"STATUS_IPSEC_BAD_SPI"; + case STATUS_IPSEC_SA_LIFETIME_EXPIRED: return L"STATUS_IPSEC_SA_LIFETIME_EXPIRED"; + case STATUS_IPSEC_WRONG_SA: return L"STATUS_IPSEC_WRONG_SA"; + case STATUS_IPSEC_REPLAY_CHECK_FAILED: return L"STATUS_IPSEC_REPLAY_CHECK_FAILED"; + case STATUS_IPSEC_INVALID_PACKET: return L"STATUS_IPSEC_INVALID_PACKET"; + case STATUS_IPSEC_INTEGRITY_CHECK_FAILED: return L"STATUS_IPSEC_INTEGRITY_CHECK_FAILED"; + case STATUS_IPSEC_CLEAR_TEXT_DROP: return L"STATUS_IPSEC_CLEAR_TEXT_DROP"; + case STATUS_IPSEC_AUTH_FIREWALL_DROP: return L"STATUS_IPSEC_AUTH_FIREWALL_DROP"; + case STATUS_IPSEC_THROTTLE_DROP: return L"STATUS_IPSEC_THROTTLE_DROP"; + case STATUS_IPSEC_DOSP_BLOCK: return L"STATUS_IPSEC_DOSP_BLOCK"; + case STATUS_IPSEC_DOSP_RECEIVED_MULTICAST: return L"STATUS_IPSEC_DOSP_RECEIVED_MULTICAST"; + case STATUS_IPSEC_DOSP_INVALID_PACKET: return L"STATUS_IPSEC_DOSP_INVALID_PACKET"; + case STATUS_IPSEC_DOSP_STATE_LOOKUP_FAILED: return L"STATUS_IPSEC_DOSP_STATE_LOOKUP_FAILED"; + case STATUS_IPSEC_DOSP_MAX_ENTRIES: return L"STATUS_IPSEC_DOSP_MAX_ENTRIES"; + case STATUS_IPSEC_DOSP_KEYMOD_NOT_ALLOWED: return L"STATUS_IPSEC_DOSP_KEYMOD_NOT_ALLOWED"; + case STATUS_IPSEC_DOSP_MAX_PER_IP_RATELIMIT_QUEUES: return L"STATUS_IPSEC_DOSP_MAX_PER_IP_RATELIMIT_QUEUES"; + case STATUS_VOLMGR_INCOMPLETE_REGENERATION: return L"STATUS_VOLMGR_INCOMPLETE_REGENERATION"; + case STATUS_VOLMGR_INCOMPLETE_DISK_MIGRATION: return L"STATUS_VOLMGR_INCOMPLETE_DISK_MIGRATION"; + case STATUS_VOLMGR_DATABASE_FULL: return L"STATUS_VOLMGR_DATABASE_FULL"; + case STATUS_VOLMGR_DISK_CONFIGURATION_CORRUPTED: return L"STATUS_VOLMGR_DISK_CONFIGURATION_CORRUPTED"; + case STATUS_VOLMGR_DISK_CONFIGURATION_NOT_IN_SYNC: return L"STATUS_VOLMGR_DISK_CONFIGURATION_NOT_IN_SYNC"; + case STATUS_VOLMGR_PACK_CONFIG_UPDATE_FAILED: return L"STATUS_VOLMGR_PACK_CONFIG_UPDATE_FAILED"; + case STATUS_VOLMGR_DISK_CONTAINS_NON_SIMPLE_VOLUME: return L"STATUS_VOLMGR_DISK_CONTAINS_NON_SIMPLE_VOLUME"; + case STATUS_VOLMGR_DISK_DUPLICATE: return L"STATUS_VOLMGR_DISK_DUPLICATE"; + case STATUS_VOLMGR_DISK_DYNAMIC: return L"STATUS_VOLMGR_DISK_DYNAMIC"; + case STATUS_VOLMGR_DISK_ID_INVALID: return L"STATUS_VOLMGR_DISK_ID_INVALID"; + case STATUS_VOLMGR_DISK_INVALID: return L"STATUS_VOLMGR_DISK_INVALID"; + case STATUS_VOLMGR_DISK_LAST_VOTER: return L"STATUS_VOLMGR_DISK_LAST_VOTER"; + case STATUS_VOLMGR_DISK_LAYOUT_INVALID: return L"STATUS_VOLMGR_DISK_LAYOUT_INVALID"; + case STATUS_VOLMGR_DISK_LAYOUT_NON_BASIC_BETWEEN_BASIC_PARTITIONS: return L"STATUS_VOLMGR_DISK_LAYOUT_NON_BASIC_BETWEEN_BASIC_PARTITIONS"; + case STATUS_VOLMGR_DISK_LAYOUT_NOT_CYLINDER_ALIGNED: return L"STATUS_VOLMGR_DISK_LAYOUT_NOT_CYLINDER_ALIGNED"; + case STATUS_VOLMGR_DISK_LAYOUT_PARTITIONS_TOO_SMALL: return L"STATUS_VOLMGR_DISK_LAYOUT_PARTITIONS_TOO_SMALL"; + case STATUS_VOLMGR_DISK_LAYOUT_PRIMARY_BETWEEN_LOGICAL_PARTITIONS: return L"STATUS_VOLMGR_DISK_LAYOUT_PRIMARY_BETWEEN_LOGICAL_PARTITIONS"; + case STATUS_VOLMGR_DISK_LAYOUT_TOO_MANY_PARTITIONS: return L"STATUS_VOLMGR_DISK_LAYOUT_TOO_MANY_PARTITIONS"; + case STATUS_VOLMGR_DISK_MISSING: return L"STATUS_VOLMGR_DISK_MISSING"; + case STATUS_VOLMGR_DISK_NOT_EMPTY: return L"STATUS_VOLMGR_DISK_NOT_EMPTY"; + case STATUS_VOLMGR_DISK_NOT_ENOUGH_SPACE: return L"STATUS_VOLMGR_DISK_NOT_ENOUGH_SPACE"; + case STATUS_VOLMGR_DISK_REVECTORING_FAILED: return L"STATUS_VOLMGR_DISK_REVECTORING_FAILED"; + case STATUS_VOLMGR_DISK_SECTOR_SIZE_INVALID: return L"STATUS_VOLMGR_DISK_SECTOR_SIZE_INVALID"; + case STATUS_VOLMGR_DISK_SET_NOT_CONTAINED: return L"STATUS_VOLMGR_DISK_SET_NOT_CONTAINED"; + case STATUS_VOLMGR_DISK_USED_BY_MULTIPLE_MEMBERS: return L"STATUS_VOLMGR_DISK_USED_BY_MULTIPLE_MEMBERS"; + case STATUS_VOLMGR_DISK_USED_BY_MULTIPLE_PLEXES: return L"STATUS_VOLMGR_DISK_USED_BY_MULTIPLE_PLEXES"; + case STATUS_VOLMGR_DYNAMIC_DISK_NOT_SUPPORTED: return L"STATUS_VOLMGR_DYNAMIC_DISK_NOT_SUPPORTED"; + case STATUS_VOLMGR_EXTENT_ALREADY_USED: return L"STATUS_VOLMGR_EXTENT_ALREADY_USED"; + case STATUS_VOLMGR_EXTENT_NOT_CONTIGUOUS: return L"STATUS_VOLMGR_EXTENT_NOT_CONTIGUOUS"; + case STATUS_VOLMGR_EXTENT_NOT_IN_PUBLIC_REGION: return L"STATUS_VOLMGR_EXTENT_NOT_IN_PUBLIC_REGION"; + case STATUS_VOLMGR_EXTENT_NOT_SECTOR_ALIGNED: return L"STATUS_VOLMGR_EXTENT_NOT_SECTOR_ALIGNED"; + case STATUS_VOLMGR_EXTENT_OVERLAPS_EBR_PARTITION: return L"STATUS_VOLMGR_EXTENT_OVERLAPS_EBR_PARTITION"; + case STATUS_VOLMGR_EXTENT_VOLUME_LENGTHS_DO_NOT_MATCH: return L"STATUS_VOLMGR_EXTENT_VOLUME_LENGTHS_DO_NOT_MATCH"; + case STATUS_VOLMGR_FAULT_TOLERANT_NOT_SUPPORTED: return L"STATUS_VOLMGR_FAULT_TOLERANT_NOT_SUPPORTED"; + case STATUS_VOLMGR_INTERLEAVE_LENGTH_INVALID: return L"STATUS_VOLMGR_INTERLEAVE_LENGTH_INVALID"; + case STATUS_VOLMGR_MAXIMUM_REGISTERED_USERS: return L"STATUS_VOLMGR_MAXIMUM_REGISTERED_USERS"; + case STATUS_VOLMGR_MEMBER_IN_SYNC: return L"STATUS_VOLMGR_MEMBER_IN_SYNC"; + case STATUS_VOLMGR_MEMBER_INDEX_DUPLICATE: return L"STATUS_VOLMGR_MEMBER_INDEX_DUPLICATE"; + case STATUS_VOLMGR_MEMBER_INDEX_INVALID: return L"STATUS_VOLMGR_MEMBER_INDEX_INVALID"; + case STATUS_VOLMGR_MEMBER_MISSING: return L"STATUS_VOLMGR_MEMBER_MISSING"; + case STATUS_VOLMGR_MEMBER_NOT_DETACHED: return L"STATUS_VOLMGR_MEMBER_NOT_DETACHED"; + case STATUS_VOLMGR_MEMBER_REGENERATING: return L"STATUS_VOLMGR_MEMBER_REGENERATING"; + case STATUS_VOLMGR_ALL_DISKS_FAILED: return L"STATUS_VOLMGR_ALL_DISKS_FAILED"; + case STATUS_VOLMGR_NO_REGISTERED_USERS: return L"STATUS_VOLMGR_NO_REGISTERED_USERS"; + case STATUS_VOLMGR_NO_SUCH_USER: return L"STATUS_VOLMGR_NO_SUCH_USER"; + case STATUS_VOLMGR_NOTIFICATION_RESET: return L"STATUS_VOLMGR_NOTIFICATION_RESET"; + case STATUS_VOLMGR_NUMBER_OF_MEMBERS_INVALID: return L"STATUS_VOLMGR_NUMBER_OF_MEMBERS_INVALID"; + case STATUS_VOLMGR_NUMBER_OF_PLEXES_INVALID: return L"STATUS_VOLMGR_NUMBER_OF_PLEXES_INVALID"; + case STATUS_VOLMGR_PACK_DUPLICATE: return L"STATUS_VOLMGR_PACK_DUPLICATE"; + case STATUS_VOLMGR_PACK_ID_INVALID: return L"STATUS_VOLMGR_PACK_ID_INVALID"; + case STATUS_VOLMGR_PACK_INVALID: return L"STATUS_VOLMGR_PACK_INVALID"; + case STATUS_VOLMGR_PACK_NAME_INVALID: return L"STATUS_VOLMGR_PACK_NAME_INVALID"; + case STATUS_VOLMGR_PACK_OFFLINE: return L"STATUS_VOLMGR_PACK_OFFLINE"; + case STATUS_VOLMGR_PACK_HAS_QUORUM: return L"STATUS_VOLMGR_PACK_HAS_QUORUM"; + case STATUS_VOLMGR_PACK_WITHOUT_QUORUM: return L"STATUS_VOLMGR_PACK_WITHOUT_QUORUM"; + case STATUS_VOLMGR_PARTITION_STYLE_INVALID: return L"STATUS_VOLMGR_PARTITION_STYLE_INVALID"; + case STATUS_VOLMGR_PARTITION_UPDATE_FAILED: return L"STATUS_VOLMGR_PARTITION_UPDATE_FAILED"; + case STATUS_VOLMGR_PLEX_IN_SYNC: return L"STATUS_VOLMGR_PLEX_IN_SYNC"; + case STATUS_VOLMGR_PLEX_INDEX_DUPLICATE: return L"STATUS_VOLMGR_PLEX_INDEX_DUPLICATE"; + case STATUS_VOLMGR_PLEX_INDEX_INVALID: return L"STATUS_VOLMGR_PLEX_INDEX_INVALID"; + case STATUS_VOLMGR_PLEX_LAST_ACTIVE: return L"STATUS_VOLMGR_PLEX_LAST_ACTIVE"; + case STATUS_VOLMGR_PLEX_MISSING: return L"STATUS_VOLMGR_PLEX_MISSING"; + case STATUS_VOLMGR_PLEX_REGENERATING: return L"STATUS_VOLMGR_PLEX_REGENERATING"; + case STATUS_VOLMGR_PLEX_TYPE_INVALID: return L"STATUS_VOLMGR_PLEX_TYPE_INVALID"; + case STATUS_VOLMGR_PLEX_NOT_RAID5: return L"STATUS_VOLMGR_PLEX_NOT_RAID5"; + case STATUS_VOLMGR_PLEX_NOT_SIMPLE: return L"STATUS_VOLMGR_PLEX_NOT_SIMPLE"; + case STATUS_VOLMGR_STRUCTURE_SIZE_INVALID: return L"STATUS_VOLMGR_STRUCTURE_SIZE_INVALID"; + case STATUS_VOLMGR_TOO_MANY_NOTIFICATION_REQUESTS: return L"STATUS_VOLMGR_TOO_MANY_NOTIFICATION_REQUESTS"; + case STATUS_VOLMGR_TRANSACTION_IN_PROGRESS: return L"STATUS_VOLMGR_TRANSACTION_IN_PROGRESS"; + case STATUS_VOLMGR_UNEXPECTED_DISK_LAYOUT_CHANGE: return L"STATUS_VOLMGR_UNEXPECTED_DISK_LAYOUT_CHANGE"; + case STATUS_VOLMGR_VOLUME_CONTAINS_MISSING_DISK: return L"STATUS_VOLMGR_VOLUME_CONTAINS_MISSING_DISK"; + case STATUS_VOLMGR_VOLUME_ID_INVALID: return L"STATUS_VOLMGR_VOLUME_ID_INVALID"; + case STATUS_VOLMGR_VOLUME_LENGTH_INVALID: return L"STATUS_VOLMGR_VOLUME_LENGTH_INVALID"; + case STATUS_VOLMGR_VOLUME_LENGTH_NOT_SECTOR_SIZE_MULTIPLE: return L"STATUS_VOLMGR_VOLUME_LENGTH_NOT_SECTOR_SIZE_MULTIPLE"; + case STATUS_VOLMGR_VOLUME_NOT_MIRRORED: return L"STATUS_VOLMGR_VOLUME_NOT_MIRRORED"; + case STATUS_VOLMGR_VOLUME_NOT_RETAINED: return L"STATUS_VOLMGR_VOLUME_NOT_RETAINED"; + case STATUS_VOLMGR_VOLUME_OFFLINE: return L"STATUS_VOLMGR_VOLUME_OFFLINE"; + case STATUS_VOLMGR_VOLUME_RETAINED: return L"STATUS_VOLMGR_VOLUME_RETAINED"; + case STATUS_VOLMGR_NUMBER_OF_EXTENTS_INVALID: return L"STATUS_VOLMGR_NUMBER_OF_EXTENTS_INVALID"; + case STATUS_VOLMGR_DIFFERENT_SECTOR_SIZE: return L"STATUS_VOLMGR_DIFFERENT_SECTOR_SIZE"; + case STATUS_VOLMGR_BAD_BOOT_DISK: return L"STATUS_VOLMGR_BAD_BOOT_DISK"; + case STATUS_VOLMGR_PACK_CONFIG_OFFLINE: return L"STATUS_VOLMGR_PACK_CONFIG_OFFLINE"; + case STATUS_VOLMGR_PACK_CONFIG_ONLINE: return L"STATUS_VOLMGR_PACK_CONFIG_ONLINE"; + case STATUS_VOLMGR_NOT_PRIMARY_PACK: return L"STATUS_VOLMGR_NOT_PRIMARY_PACK"; + case STATUS_VOLMGR_PACK_LOG_UPDATE_FAILED: return L"STATUS_VOLMGR_PACK_LOG_UPDATE_FAILED"; + case STATUS_VOLMGR_NUMBER_OF_DISKS_IN_PLEX_INVALID: return L"STATUS_VOLMGR_NUMBER_OF_DISKS_IN_PLEX_INVALID"; + case STATUS_VOLMGR_NUMBER_OF_DISKS_IN_MEMBER_INVALID: return L"STATUS_VOLMGR_NUMBER_OF_DISKS_IN_MEMBER_INVALID"; + case STATUS_VOLMGR_VOLUME_MIRRORED: return L"STATUS_VOLMGR_VOLUME_MIRRORED"; + case STATUS_VOLMGR_PLEX_NOT_SIMPLE_SPANNED: return L"STATUS_VOLMGR_PLEX_NOT_SIMPLE_SPANNED"; + case STATUS_VOLMGR_NO_VALID_LOG_COPIES: return L"STATUS_VOLMGR_NO_VALID_LOG_COPIES"; + case STATUS_VOLMGR_PRIMARY_PACK_PRESENT: return L"STATUS_VOLMGR_PRIMARY_PACK_PRESENT"; + case STATUS_VOLMGR_NUMBER_OF_DISKS_INVALID: return L"STATUS_VOLMGR_NUMBER_OF_DISKS_INVALID"; + case STATUS_VOLMGR_MIRROR_NOT_SUPPORTED: return L"STATUS_VOLMGR_MIRROR_NOT_SUPPORTED"; + case STATUS_VOLMGR_RAID5_NOT_SUPPORTED: return L"STATUS_VOLMGR_RAID5_NOT_SUPPORTED"; + case STATUS_BCD_NOT_ALL_ENTRIES_IMPORTED: return L"STATUS_BCD_NOT_ALL_ENTRIES_IMPORTED"; + case STATUS_BCD_TOO_MANY_ELEMENTS: return L"STATUS_BCD_TOO_MANY_ELEMENTS"; + case STATUS_BCD_NOT_ALL_ENTRIES_SYNCHRONIZED: return L"STATUS_BCD_NOT_ALL_ENTRIES_SYNCHRONIZED"; + case STATUS_VHD_DRIVE_FOOTER_MISSING: return L"STATUS_VHD_DRIVE_FOOTER_MISSING"; + case STATUS_VHD_DRIVE_FOOTER_CHECKSUM_MISMATCH: return L"STATUS_VHD_DRIVE_FOOTER_CHECKSUM_MISMATCH"; + case STATUS_VHD_DRIVE_FOOTER_CORRUPT: return L"STATUS_VHD_DRIVE_FOOTER_CORRUPT"; + case STATUS_VHD_FORMAT_UNKNOWN: return L"STATUS_VHD_FORMAT_UNKNOWN"; + case STATUS_VHD_FORMAT_UNSUPPORTED_VERSION: return L"STATUS_VHD_FORMAT_UNSUPPORTED_VERSION"; + case STATUS_VHD_SPARSE_HEADER_CHECKSUM_MISMATCH: return L"STATUS_VHD_SPARSE_HEADER_CHECKSUM_MISMATCH"; + case STATUS_VHD_SPARSE_HEADER_UNSUPPORTED_VERSION: return L"STATUS_VHD_SPARSE_HEADER_UNSUPPORTED_VERSION"; + case STATUS_VHD_SPARSE_HEADER_CORRUPT: return L"STATUS_VHD_SPARSE_HEADER_CORRUPT"; + case STATUS_VHD_BLOCK_ALLOCATION_FAILURE: return L"STATUS_VHD_BLOCK_ALLOCATION_FAILURE"; + case STATUS_VHD_BLOCK_ALLOCATION_TABLE_CORRUPT: return L"STATUS_VHD_BLOCK_ALLOCATION_TABLE_CORRUPT"; + case STATUS_VHD_INVALID_BLOCK_SIZE: return L"STATUS_VHD_INVALID_BLOCK_SIZE"; + case STATUS_VHD_BITMAP_MISMATCH: return L"STATUS_VHD_BITMAP_MISMATCH"; + case STATUS_VHD_PARENT_VHD_NOT_FOUND: return L"STATUS_VHD_PARENT_VHD_NOT_FOUND"; + case STATUS_VHD_CHILD_PARENT_ID_MISMATCH: return L"STATUS_VHD_CHILD_PARENT_ID_MISMATCH"; + case STATUS_VHD_CHILD_PARENT_TIMESTAMP_MISMATCH: return L"STATUS_VHD_CHILD_PARENT_TIMESTAMP_MISMATCH"; + case STATUS_VHD_METADATA_READ_FAILURE: return L"STATUS_VHD_METADATA_READ_FAILURE"; + case STATUS_VHD_METADATA_WRITE_FAILURE: return L"STATUS_VHD_METADATA_WRITE_FAILURE"; + case STATUS_VHD_INVALID_SIZE: return L"STATUS_VHD_INVALID_SIZE"; + case STATUS_VHD_INVALID_FILE_SIZE: return L"STATUS_VHD_INVALID_FILE_SIZE"; + case STATUS_VIRTDISK_PROVIDER_NOT_FOUND: return L"STATUS_VIRTDISK_PROVIDER_NOT_FOUND"; + case STATUS_VIRTDISK_NOT_VIRTUAL_DISK: return L"STATUS_VIRTDISK_NOT_VIRTUAL_DISK"; + case STATUS_VHD_PARENT_VHD_ACCESS_DENIED: return L"STATUS_VHD_PARENT_VHD_ACCESS_DENIED"; + case STATUS_VHD_CHILD_PARENT_SIZE_MISMATCH: return L"STATUS_VHD_CHILD_PARENT_SIZE_MISMATCH"; + case STATUS_VHD_DIFFERENCING_CHAIN_CYCLE_DETECTED: return L"STATUS_VHD_DIFFERENCING_CHAIN_CYCLE_DETECTED"; + case STATUS_VHD_DIFFERENCING_CHAIN_ERROR_IN_PARENT: return L"STATUS_VHD_DIFFERENCING_CHAIN_ERROR_IN_PARENT"; + case STATUS_VIRTUAL_DISK_LIMITATION: return L"STATUS_VIRTUAL_DISK_LIMITATION"; + case STATUS_VHD_INVALID_TYPE: return L"STATUS_VHD_INVALID_TYPE"; + case STATUS_VHD_INVALID_STATE: return L"STATUS_VHD_INVALID_STATE"; + case STATUS_VIRTDISK_UNSUPPORTED_DISK_SECTOR_SIZE: return L"STATUS_VIRTDISK_UNSUPPORTED_DISK_SECTOR_SIZE"; + case STATUS_QUERY_STORAGE_ERROR: return L"STATUS_QUERY_STORAGE_ERROR"; + case STATUS_DIS_NOT_PRESENT: return L"STATUS_DIS_NOT_PRESENT"; + case STATUS_DIS_ATTRIBUTE_NOT_FOUND: return L"STATUS_DIS_ATTRIBUTE_NOT_FOUND"; + case STATUS_DIS_UNRECOGNIZED_ATTRIBUTE: return L"STATUS_DIS_UNRECOGNIZED_ATTRIBUTE"; + case STATUS_DIS_PARTIAL_DATA: return L"STATUS_DIS_PARTIAL_DATA"; + default: return L"UNKNOWN_NTSTATUS_VALUE"; + } +} \ No newline at end of file diff --git a/KexDll/strmap.c b/KexDll/strmap.c new file mode 100644 index 0000000..f853dfe --- /dev/null +++ b/KexDll/strmap.c @@ -0,0 +1,469 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// strmap.c +// +// Abstract: +// +// This module contains the String Mapper API. +// +// A string mapper is a data structure that lets you map one string to +// another. In VxKex it is used as part of the mechanism that rewrites +// the import directory of an image file. +// +// Author: +// +// vxiiduu (21-Oct-2022) +// +// Environment: +// +// String mappers can be used after the RTL heap system is initialized and +// the process heap has been created. +// +// Revision History: +// +// vxiiduu 21-Oct-2022 Initial creation. +// vxiiduu 16-Mar-2024 Remove erroneous OPTIONAL qualifier on +// the 2nd argument to InsertEntry. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kexdllp.h" + +// +// Create a new string mapper. +// +// StringMapper +// Pointer that receives the address of the opaque string +// mapper object. +// +// Flags +// May contain any of the KEX_RTL_STRING_MAPPER_* flags. +// Invalid flags will cause STATUS_INVALID_PARAMETER_2. +// +KEXAPI NTSTATUS NTAPI KexRtlCreateStringMapper( + OUT PPKEX_RTL_STRING_MAPPER StringMapper, + IN ULONG Flags OPTIONAL) +{ + PKEX_RTL_STRING_MAPPER Mapper; + PRTL_DYNAMIC_HASH_TABLE HashTable; + BOOLEAN Success; + + if (!StringMapper) { + return STATUS_INVALID_PARAMETER_1; + } + + *StringMapper = NULL; + + if (Flags & ~(KEX_RTL_STRING_MAPPER_FLAGS_VALID_MASK)) { + return STATUS_INVALID_PARAMETER_2; + } + + Mapper = SafeAlloc(KEX_RTL_STRING_MAPPER, 1); + if (!Mapper) { + return STATUS_NO_MEMORY; + } + + HashTable = &Mapper->HashTable; + Success = RtlCreateHashTable(&HashTable, 0, 0); + if (!Success) { + // The only way RtlCreateHashTable can fail is by running out of memory. + // (Or an invalid parameter, but that won't happen to us.) + SafeFree(Mapper); + return STATUS_NO_MEMORY; + } + + Mapper->Flags = Flags; + *StringMapper = Mapper; + + return STATUS_SUCCESS; +} + +// +// Delete a string mapper and free its resources. +// +// StringMapper +// Pointer to the opaque string mapper object. +// +KEXAPI NTSTATUS NTAPI KexRtlDeleteStringMapper( + IN PPKEX_RTL_STRING_MAPPER StringMapper) +{ + PKEX_RTL_STRING_MAPPER Mapper; + RTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator; + PRTL_DYNAMIC_HASH_TABLE_ENTRY Entry; + + if (!StringMapper || !*StringMapper) { + return STATUS_INVALID_PARAMETER_1; + } + + Mapper = *StringMapper; + + // + // Enumerate entries in the hash table and free all the memory. + // + + RtlInitEnumerationHashTable(&Mapper->HashTable, &Enumerator); + + do { + Entry = RtlEnumerateEntryHashTable(&Mapper->HashTable, &Enumerator); + RtlFreeHeap(RtlProcessHeap(), 0, Entry); + } until (Entry == NULL); + + RtlEndEnumerationHashTable(&Mapper->HashTable, &Enumerator); + + // + // Free the hash table itself. + // + + RtlDeleteHashTable(&(*StringMapper)->HashTable); + SafeFree(*StringMapper); + + return STATUS_SUCCESS; +} + +// +// Insert a new key-value pair into the string mapper. +// +// The UNICODE_STRING structures themselves are copied into the string +// mapper, but the actual string data that is pointed to by the Buffer +// member is not managed by the mapper - you must ensure that this data +// is not freed before you destroy the string mapper. +// +// StringMapper +// Pointer to a string mapper object +// +// Key +// A string which will be hashed. Do not specify a key which is a +// duplicate of another key you have inserted earlier; this will make +// lookups unreliable (may return any of the values associated with +// the same key). +// +// Value +// Pointer to an uninterpreted UNICODE_STRING which can be retrieved +// if you know the Key, using the KexRtlLookupEntryStringMapper API. +// +KEXAPI NTSTATUS NTAPI KexRtlInsertEntryStringMapper( + IN PKEX_RTL_STRING_MAPPER StringMapper, + IN PCUNICODE_STRING Key, + IN PCUNICODE_STRING Value) +{ + PKEX_RTL_STRING_MAPPER_HASH_TABLE_ENTRY Entry; + ULONG KeySignature; + + if (!StringMapper) { + return STATUS_INVALID_PARAMETER_1; + } + + if (!Key) { + return STATUS_INVALID_PARAMETER_2; + } + + if (!Value) { + return STATUS_INVALID_PARAMETER_3; + } + + Entry = SafeAlloc(KEX_RTL_STRING_MAPPER_HASH_TABLE_ENTRY, 1); + if (!Entry) { + return STATUS_NO_MEMORY; + } + + // + // hash the key and use that as the hash table entry's signature. + // No need to check RtlHashUnicodeString return value because it can't + // fail unless an invalid parameter is supplied, which cannot happen. + // + RtlHashUnicodeString( + Key, + (StringMapper->Flags & KEX_RTL_STRING_MAPPER_CASE_INSENSITIVE_KEYS), + HASH_STRING_ALGORITHM_DEFAULT, + &KeySignature); + + Entry->Key = *Key; + Entry->Value = *Value; + + RtlInsertEntryHashTable( + &StringMapper->HashTable, + &Entry->HashTableEntry, + KeySignature, + NULL); + + return STATUS_SUCCESS; +} + +STATIC NTSTATUS NTAPI KexRtlpLookupRawEntryStringMapper( + IN PKEX_RTL_STRING_MAPPER StringMapper, + IN PCUNICODE_STRING Key, + OUT PPKEX_RTL_STRING_MAPPER_HASH_TABLE_ENTRY EntryOut) +{ + BOOLEAN Success; + BOOLEAN CaseInsensitive; + PKEX_RTL_STRING_MAPPER_HASH_TABLE_ENTRY Entry; + RTL_DYNAMIC_HASH_TABLE_CONTEXT Context; + ULONG KeySignature; + + if (!StringMapper) { + return STATUS_INVALID_PARAMETER_1; + } + + if (!Key) { + return STATUS_INVALID_PARAMETER_2; + } + + if (!EntryOut) { + return STATUS_INTERNAL_ERROR; + } + + CaseInsensitive = (StringMapper->Flags & KEX_RTL_STRING_MAPPER_CASE_INSENSITIVE_KEYS); + + RtlHashUnicodeString( + Key, + CaseInsensitive, + HASH_STRING_ALGORITHM_DEFAULT, + &KeySignature); + + Entry = (PKEX_RTL_STRING_MAPPER_HASH_TABLE_ENTRY) RtlLookupEntryHashTable( + &StringMapper->HashTable, + KeySignature, + &Context); + + while (TRUE) { + if (!Entry || Entry->HashTableEntry.Signature != KeySignature) { + *EntryOut = NULL; + return STATUS_STRING_MAPPER_ENTRY_NOT_FOUND; + } + + Success = RtlEqualUnicodeString( + Key, + &Entry->Key, + CaseInsensitive); + + if (Success) { + break; + } + + // + // If this loop continues more than once, that means there is a hash collision. + // We will handle the situation by checking the rest of the entries in this + // bucket. + // + // With a decent hash function, this code should very rarely be executed. + // + + Entry = (PKEX_RTL_STRING_MAPPER_HASH_TABLE_ENTRY) RtlGetNextEntryHashTable( + &StringMapper->HashTable, + &Context); + } + + *EntryOut = Entry; + + return STATUS_SUCCESS; +} + +// +// Look up a single value by key. +// +// StringMapper +// Pointer to a string mapper object +// +// Key +// Should be the same as what you specified to an earlier insert call. +// If no value with the specified key is found, this function will return +// the STATUS_STRING_MAPPER_ENTRY_NOT_FOUND error code. +// +// Value +// Pointer to a structure which will receive the retrieved value data. +// +KEXAPI NTSTATUS NTAPI KexRtlLookupEntryStringMapper( + IN PKEX_RTL_STRING_MAPPER StringMapper, + IN PCUNICODE_STRING Key, + OUT PUNICODE_STRING Value OPTIONAL) +{ + NTSTATUS Status; + PKEX_RTL_STRING_MAPPER_HASH_TABLE_ENTRY Entry; + + Status = KexRtlpLookupRawEntryStringMapper( + StringMapper, + Key, + &Entry); + + if (!NT_SUCCESS(Status)) { + return Status; + } + + if (Value) { + *Value = Entry->Value; + } + + return Status; +} + +// +// Remove a single value by key. +// +// StringMapper +// Pointer to a string mapper object +// +// Key +// Should be the same as what you specified to an earlier insert call. +// If no value with the specified key is found, this function will return +// the STATUS_STRING_MAPPER_ENTRY_NOT_FOUND error code. +// +KEXAPI NTSTATUS NTAPI KexRtlRemoveEntryStringMapper( + IN PKEX_RTL_STRING_MAPPER StringMapper, + IN PCUNICODE_STRING Key) +{ + NTSTATUS Status; + BOOLEAN Success; + PKEX_RTL_STRING_MAPPER_HASH_TABLE_ENTRY Entry; + + Status = KexRtlpLookupRawEntryStringMapper( + StringMapper, + Key, + &Entry); + + if (!NT_SUCCESS(Status)) { + return Status; + } + + Success = RtlRemoveEntryHashTable( + &StringMapper->HashTable, + &Entry->HashTableEntry, + NULL); + + SafeFree(Entry); + + if (!Success) { + return STATUS_INTERNAL_ERROR; + } + + return STATUS_SUCCESS; +} + +// +// This is a convenience function which takes input and returns output +// from a single UNICODE_STRING structure. It is equivalent to calling +// KexRtlLookupEntryStringMapper with the Key and Value parameters pointing +// to the same UNICODE_STRING. +// +KEXAPI NTSTATUS NTAPI KexRtlApplyStringMapper( + IN PKEX_RTL_STRING_MAPPER StringMapper, + IN OUT PUNICODE_STRING KeyToValue) +{ + return KexRtlLookupEntryStringMapper(StringMapper, KeyToValue, KeyToValue); +} + +// +// This is a convenience function which inserts many entries into the +// mapper with a single call. It is intended to be used with static arrays. +// +KEXAPI NTSTATUS NTAPI KexRtlInsertMultipleEntriesStringMapper( + IN PKEX_RTL_STRING_MAPPER StringMapper, + IN CONST KEX_RTL_STRING_MAPPER_ENTRY Entries[], + IN ULONG EntryCount) +{ + NTSTATUS FailureStatus; + + if (!StringMapper) { + return STATUS_INVALID_PARAMETER_1; + } + + if (!Entries) { + return STATUS_INVALID_PARAMETER_2; + } + + if (!EntryCount) { + return STATUS_INVALID_PARAMETER_3; + } + + FailureStatus = STATUS_SUCCESS; + + do { + NTSTATUS Status; + + Status = KexRtlInsertEntryStringMapper( + StringMapper, + &Entries[EntryCount-1].Key, + &Entries[EntryCount-1].Value); + + if (!NT_SUCCESS(Status)) { + FailureStatus = Status; + } + } while (--EntryCount); + + return FailureStatus; +} + +KEXAPI NTSTATUS NTAPI KexRtlLookupMultipleEntriesStringMapper( + IN PKEX_RTL_STRING_MAPPER StringMapper, + IN OUT KEX_RTL_STRING_MAPPER_ENTRY Entries[], + IN ULONG EntryCount) +{ + NTSTATUS FailureStatus; + + if (!StringMapper) { + return STATUS_INVALID_PARAMETER_1; + } + + if (!Entries) { + return STATUS_INVALID_PARAMETER_2; + } + + if (!EntryCount) { + return STATUS_INVALID_PARAMETER_3; + } + + FailureStatus = STATUS_SUCCESS; + + do { + NTSTATUS Status; + + Status = KexRtlLookupEntryStringMapper( + StringMapper, + &Entries[EntryCount-1].Key, + &Entries[EntryCount-1].Value); + + if (!NT_SUCCESS(Status)) { + FailureStatus = Status; + } + } while (--EntryCount); + + return FailureStatus; +} + +KEXAPI NTSTATUS NTAPI KexRtlBatchApplyStringMapper( + IN PKEX_RTL_STRING_MAPPER StringMapper, + IN OUT UNICODE_STRING KeyToValue[], + IN ULONG KeyToValueCount) +{ + NTSTATUS FailureStatus; + + if (!StringMapper) { + return STATUS_INVALID_PARAMETER_1; + } + + if (!KeyToValue) { + return STATUS_INVALID_PARAMETER_2; + } + + if (!KeyToValueCount) { + return STATUS_INVALID_PARAMETER_3; + } + + FailureStatus = STATUS_SUCCESS; + + do { + NTSTATUS Status; + + Status = KexRtlApplyStringMapper( + StringMapper, + &KeyToValue[KeyToValueCount-1]); + + if (!NT_SUCCESS(Status)) { + FailureStatus = Status; + } + } while (--KeyToValueCount); + + return FailureStatus; +} \ No newline at end of file diff --git a/KexDll/syscal32.c b/KexDll/syscal32.c new file mode 100644 index 0000000..800ed95 --- /dev/null +++ b/KexDll/syscal32.c @@ -0,0 +1,196 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// syscal32.c +// +// Abstract: +// +// 32-bit Unhooked System Call Stubs (native & WOW64). +// TLDR: Tons of macros +// +// Author: +// +// vxiiduu (23-Oct-2022) +// +// Environment: +// +// Early process creation ONLY. For reasons of simplicity these functions +// are not thread safe at all. +// +// Revision History: +// +// vxiiduu 23-Oct-2022 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kexdllp.h" + +#ifdef KEX_ARCH_X86 + +#define KEXNTSYSCALLAPI __declspec(naked) +#pragma warning(disable:4414) // shut the fuck up i dont care + +#define GENERATE_SYSCALL(SyscallName, SyscallNumber32, SyscallNumber64, EcxValue, Retn, ...) \ +KEXNTSYSCALLAPI NTSTATUS NTAPI Kex##SyscallName##(__VA_ARGS__) { asm { \ + asm mov eax, SyscallNumber32 \ + asm mov edx, 0x7FFE0300 \ + asm cmp dword ptr [edx], 0 /* If [0x7ffe0300] is zero, that means we are running as a Wow64 program on a 64 bit OS. */ \ + asm je Kex##SyscallName##_Wow64 \ + asm call [edx] /* Native 32 bit call */ \ + asm ret Retn \ + asm Kex##SyscallName##_Wow64: /* Wow64 call */ \ + asm mov eax, SyscallNumber64 \ + asm mov ecx, EcxValue \ + asm lea edx, [esp+4] \ + asm call fs:0xC0 \ + asm add esp, 4 \ + asm ret Retn \ +}} + +GENERATE_SYSCALL(NtQuerySystemTime, 0x0107, 0x0057, 0x18, 0x04, + OUT PLONGLONG CurrentTime); + +GENERATE_SYSCALL(NtCreateUserProcess, 0x005D, 0x00AA, 0x00, 0x2C, + OUT PHANDLE ProcessHandle, + OUT PHANDLE ThreadHandle, + IN ACCESS_MASK ProcessDesiredAccess, + IN ACCESS_MASK ThreadDesiredAccess, + IN POBJECT_ATTRIBUTES ProcessObjectAttributes OPTIONAL, + IN POBJECT_ATTRIBUTES ThreadObjectAttributes OPTIONAL, + IN ULONG ProcessFlags, + IN ULONG ThreadFlags, + IN PRTL_USER_PROCESS_PARAMETERS ProcessParameters, + IN OUT PPS_CREATE_INFO CreateInfo, + IN PPS_ATTRIBUTE_LIST AttributeList OPTIONAL); + +GENERATE_SYSCALL(NtProtectVirtualMemory, 0x00D7, 0x004D, 0x00, 0x14, + IN HANDLE ProcessHandle, + IN OUT PPVOID BaseAddress, + IN OUT PSIZE_T RegionSize, + IN ULONG NewProtect, + OUT PULONG OldProtect); + +GENERATE_SYSCALL(NtAllocateVirtualMemory, 0x0013, 0x0015, 0x00, 0x18, + IN HANDLE ProcessHandle, + IN OUT PVOID *BaseAddress, + IN ULONG_PTR ZeroBits, + IN OUT PSIZE_T RegionSize, + IN ULONG AllocationType, + IN ULONG Protect); + +GENERATE_SYSCALL(NtQueryVirtualMemory, 0x010B, 0x0020, 0x00, 0x18, + IN HANDLE ProcessHandle, + IN PVOID BaseAddress OPTIONAL, + IN MEMINFOCLASS MemoryInformationClass, + OUT PVOID MemoryInformation, + IN SIZE_T MemoryInformationLength, + OUT PSIZE_T ReturnLength OPTIONAL); + +GENERATE_SYSCALL(NtFreeVirtualMemory, 0x0083, 0x001B, 0x00, 0x10, + IN HANDLE ProcessHandle, + IN OUT PVOID *BaseAddress, + IN OUT PSIZE_T RegionSize, + IN ULONG FreeType); + +GENERATE_SYSCALL(NtOpenKeyEx, 0x00B7, 0x00F2, 0x00, 0x10, + OUT PHANDLE KeyHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN ULONG OpenOptions); + +GENERATE_SYSCALL(NtQueryObject, 0x00F8, 0x000D, 0x00, 0x14, + IN HANDLE ObjectHandle, + IN OBJECT_INFORMATION_CLASS ObjectInformationClass, + OUT PVOID ObjectInformation, + IN ULONG Length, + OUT PULONG ReturnLength OPTIONAL); + +GENERATE_SYSCALL(NtOpenFile, 0x00B3, 0x0030, 0x00, 0x18, + OUT PHANDLE FileHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN ULONG ShareAccess, + IN ULONG OpenOptions); + +GENERATE_SYSCALL(NtWriteFile, 0x018C, 0x0005, 0x1A, 0x24, + IN HANDLE FileHandle, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN PVOID Buffer, + IN ULONG Length, + IN PLONGLONG ByteOffset OPTIONAL, + IN PULONG Key OPTIONAL); + +GENERATE_SYSCALL(NtRaiseHardError, 0x0110, 0x0130, 0x00, 0x18, + IN NTSTATUS ErrorStatus, + IN ULONG NumberOfParameters, + IN ULONG UnicodeStringParameterMask, + IN PULONG_PTR Parameters, + IN ULONG ValidResponseOptions, + OUT PULONG Response); + +GENERATE_SYSCALL(NtQueryInformationThread, 0x00EC, 0x0022, 0x00, 0x14, + IN HANDLE ThreadHandle, + IN THREADINFOCLASS ThreadInformationClass, + OUT PVOID ThreadInformation, + IN ULONG ThreadInformationLength, + OUT PULONG ReturnLength OPTIONAL); + +GENERATE_SYSCALL(NtSetInformationThread, 0x014F, 0x000A, 0x00, 0x10, + IN HANDLE ThreadHandle, + IN THREADINFOCLASS ThreadInformationClass, + IN PVOID ThreadInformation, + IN ULONG ThreadInformationLength); + +GENERATE_SYSCALL(NtNotifyChangeKey, 0x00AC, 0x00EB, 0x00, 0x28, + IN HANDLE KeyHandle, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN ULONG CompletionFilter, + IN BOOLEAN WatchTree, + OUT PVOID Buffer OPTIONAL, + IN ULONG BufferSize, + IN BOOLEAN Asynchronous); + +GENERATE_SYSCALL(NtNotifyChangeMultipleKeys, 0x00AD, 0x00EC, 0x00, 0x30, + IN HANDLE MasterKeyHandle, + IN ULONG Count OPTIONAL, + IN OBJECT_ATTRIBUTES SlaveObjects[] OPTIONAL, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN ULONG CompletionFilter, + IN BOOLEAN WatchTree, + OUT PVOID Buffer OPTIONAL, + IN ULONG BufferSize, + IN BOOLEAN Asynchronous); + +GENERATE_SYSCALL(NtCreateSection, 0x0054, 0x0047, 0x00, 0x1C, + OUT PHANDLE SectionHandle, + IN ULONG DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, + IN PLONGLONG MaximumSize OPTIONAL, + IN ULONG PageAttributes, + IN ULONG SectionAttributes, + IN HANDLE FileHandle OPTIONAL); + +GENERATE_SYSCALL(NtQueryInformationProcess, 0x00EA, 0x0016, 0x00, 0x14, + IN HANDLE ProcessHandle, + IN PROCESSINFOCLASS ProcessInformationClass, + OUT PVOID ProcessInformation, + IN ULONG ProcessInformationLength, + OUT PULONG ReturnLength OPTIONAL); + +GENERATE_SYSCALL(NtAssignProcessToJobObject, 0x002B, 0x0085, 0x08, 0x08, + IN HANDLE JobHandle, + IN HANDLE ProcessHandle); + +#endif \ No newline at end of file diff --git a/KexDll/syscal64.asm b/KexDll/syscal64.asm new file mode 100644 index 0000000..944b179 --- /dev/null +++ b/KexDll/syscal64.asm @@ -0,0 +1,38 @@ +IFDEF RAX + +_TEXT SEGMENT + +GENERATE_SYSCALL MACRO SyscallName, SyscallNumber64 +PUBLIC SyscallName +ALIGN 16 +SyscallName PROC + mov r10, rcx + mov eax, SyscallNumber64 + syscall + ret +SyscallName ENDP +ENDM + +GENERATE_SYSCALL KexNtQuerySystemTime, 0057h +GENERATE_SYSCALL KexNtCreateUserProcess, 00AAh +GENERATE_SYSCALL KexNtProtectVirtualMemory, 004Dh +GENERATE_SYSCALL KexNtAllocateVirtualMemory, 0015h +GENERATE_SYSCALL KexNtQueryVirtualMemory, 0020h +GENERATE_SYSCALL KexNtFreeVirtualMemory, 001Bh +GENERATE_SYSCALL KexNtOpenKeyEx, 00F2h +GENERATE_SYSCALL KexNtQueryObject, 000Dh +GENERATE_SYSCALL KexNtOpenFile, 0030h +GENERATE_SYSCALL KexNtWriteFile, 0005h +GENERATE_SYSCALL KexNtRaiseHardError, 0130h +GENERATE_SYSCALL KexNtQueryInformationThread, 0022h +GENERATE_SYSCALL KexNtSetInformationThread, 000Ah +GENERATE_SYSCALL KexNtNotifyChangeKey, 00EBh +GENERATE_SYSCALL KexNtNotifyChangeMultipleKeys, 00ECh +GENERATE_SYSCALL KexNtCreateSection, 0047h +GENERATE_SYSCALL KexNtQueryInformationProcess, 0016h +GENERATE_SYSCALL KexNtAssignProcessToJobObject, 0085h + +_TEXT ENDS + +ENDIF +END \ No newline at end of file diff --git a/KexDll/verspoof.c b/KexDll/verspoof.c new file mode 100644 index 0000000..b9110fe --- /dev/null +++ b/KexDll/verspoof.c @@ -0,0 +1,356 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// verspoof.c +// +// Abstract: +// +// Contains routines for spoofing Windows version. +// +// Author: +// +// vxiiduu (06-Nov-2022) +// +// Revision History: +// +// vxiiduu 06-Nov-2022 Initial creation. +// vxiiduu 07-Nov-2022 Increase resilience of KexApplyVersionSpoof +// vxiiduu 05-Jan-2023 Convert to user friendly NTSTATUS. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kexdllp.h" + +PCWSTR HumanReadableWinVerSpoof[] = { + L"None", + L"Windows 7 SP1", + L"Windows 8", + L"Windows 8.1", + L"Windows 10", + L"Windows 11" +}; + +UNICODE_STRING CSDVersionUnicodeString; + +STATIC NTSTATUS NTAPI Ext_RtlGetVersion( + OUT PRTL_OSVERSIONINFOEXW Version) +{ + PPEB Peb; + + Peb = NtCurrentPeb(); + + Version->dwMajorVersion = Peb->OSMajorVersion; + Version->dwMinorVersion = Peb->OSMinorVersion; + Version->dwBuildNumber = Peb->OSBuildNumber; + Version->dwPlatformId = Peb->OSPlatformId; + + if (Peb->CSDVersion.Buffer && Peb->CSDVersion.Buffer[0] != '\0') { + StringCchCopy( + Version->szCSDVersion, + ARRAYSIZE(Version->szCSDVersion), + Peb->CSDVersion.Buffer); + } else { + Version->szCSDVersion[0] = '\0'; + } + + if (Version->dwOSVersionInfoSize == sizeof(RTL_OSVERSIONINFOEXW)) { + NT_PRODUCT_TYPE ProductType; + + Version->wServicePackMajor = HIBYTE(Peb->OSCSDVersion); + Version->wServicePackMinor = LOBYTE(Peb->OSCSDVersion); + Version->wSuiteMask = (WORD) SharedUserData->SuiteMask; + Version->wProductType = 0; + + if (RtlGetNtProductType(&ProductType)) { + Version->wProductType = ProductType; + } + + if (ProductType == NtProductWinNt) { + Version->wSuiteMask &= ~VER_SUITE_TERMINAL; + } + } + + if (AshModuleIsWindowsModule(ReturnAddress()) && + !AshModuleBaseNameIs(ReturnAddress(), L"kernelbase.dll") && + !AshModuleBaseNameIs(ReturnAddress(), L"ntdll.dll")) { + + // + // WinInet calls RtlGetVersion at some point in its DllMain and if we + // don't return 6.1 then it will cause problems with connectivity. + // + // We'll return the real Windows version for all Windows DLLs except + // for kernelbase and ntdll, which call RtlGetVersion and can leak the + // real version number to the target application. + // + + Version->dwMajorVersion = 6; + Version->dwMinorVersion = 1; + Version->dwBuildNumber = 7601; + } else if (AshModuleBaseNameIs(ReturnAddress(), L"System.Private.CoreLib.dll")) { + // + // As far as I can tell, System.Private.CoreLib is what tells "managed code" the + // Windows version, so that's all we need to spoof. + // Keep in mind that we need all this code here because the PEB version is not + // spoofed for .NET applications because it will break .NET. + // + + Version->szCSDVersion[0] = '\0'; + + if (Version->dwOSVersionInfoSize == sizeof(RTL_OSVERSIONINFOEXW)) { + Version->wServicePackMajor = 0; + Version->wServicePackMinor = 0; + } + + switch (KexData->IfeoParameters.WinVerSpoof) { + case WinVerSpoofWin7: // SP1 + Version->dwMajorVersion = 6; + Version->dwMinorVersion = 1; + Version->dwBuildNumber = 7601; + + if (Version->dwOSVersionInfoSize == sizeof(RTL_OSVERSIONINFOEXW)) { + Version->wServicePackMajor = 1; + Version->wServicePackMinor = 0; + } + + StringCchCopy( + Version->szCSDVersion, + ARRAYSIZE(Version->szCSDVersion), + L"Service Pack 1"); + + break; + case WinVerSpoofWin8: + Version->dwMajorVersion = 6; + Version->dwMinorVersion = 2; + Version->dwBuildNumber = 9200; + break; + case WinVerSpoofWin8Point1: + Version->dwMajorVersion = 6; + Version->dwMinorVersion = 3; + Version->dwBuildNumber = 9600; + break; + case WinVerSpoofWin10: + Version->dwMajorVersion = 10; + Version->dwMinorVersion = 0; + Version->dwBuildNumber = 19044; + break; + case WinVerSpoofWin11: + default: + Version->dwMajorVersion = 10; + Version->dwMinorVersion = 0; + Version->dwBuildNumber = 22000; + break; + } + } + + return STATUS_SUCCESS; +} + +STATIC VOID NTAPI Ext_RtlGetNtVersionNumbers( + OUT PULONG MajorVersion OPTIONAL, + OUT PULONG MinorVersion OPTIONAL, + OUT PULONG BuildNumber OPTIONAL) +{ + PPEB Peb; + ULONG ReturnMajorVersion; + ULONG ReturnMinorVersion; + ULONG ReturnBuildNumber; + + Peb = NtCurrentPeb(); + ReturnMajorVersion = Peb->OSMajorVersion; + ReturnMinorVersion = Peb->OSMinorVersion; + ReturnBuildNumber = Peb->OSCSDVersion; + + // + // If a call to this function comes from a native Windows DLL, we will + // return the real version numbers. + // + // MSVCRT.DLL checks to see if it's running on the intended OS + // version and will fail in its DllMain if that isn't the case. + // + + if (AshModuleIsWindowsModule(ReturnAddress())) { + ReturnMajorVersion = 6; + ReturnMinorVersion = 1; + ReturnBuildNumber = 7601; + } + + if (MajorVersion) { + *MajorVersion = ReturnMajorVersion; + } + + if (MinorVersion) { + *MinorVersion = ReturnMinorVersion; + } + + if (BuildNumber) { + *BuildNumber = ReturnBuildNumber | 0xF0000000; + } +} + +VOID KexApplyVersionSpoof( + VOID) +{ + PPEB Peb; + ULONG MajorVersion; + ULONG MinorVersion; + USHORT BuildNumber; + USHORT CSDVersion; + + if (KexData->IfeoParameters.WinVerSpoof == WinVerSpoofNone) { + KexLogDebugEvent(L"Not spoofing Windows version since it is not requested."); + return; + } + + KexLogInformationEvent( + L"Applying Windows version spoof: %s", + ARRAY_LOOKUP_BOUNDS_CHECKED(HumanReadableWinVerSpoof, KexData->IfeoParameters.WinVerSpoof)); + + // + // Hook RtlGetVersion specially because its return value needs to be different + // depending on what module is calling it. + // + + KexHkInstallBasicHook(RtlGetVersion, Ext_RtlGetVersion, NULL); + + // + // APPSPECIFICHACK: Spoof version of .NET applications without breaking .NET + // Only leave the RtlGetVersion hook active and leave everything else the same. + // + + unless (KexData->IfeoParameters.DisableAppSpecific) { + if (AshExeBaseNameIs(L"HandBrake.exe") || + AshExeBaseNameIs(L"HandBrake.Worker.exe") || + AshExeBaseNameIs(L"osu!.exe") || + AshExeBaseNameIs(L"paintdotnet.exe") || + AshExeBaseNameIs(L"ChocolateyGui.exe")) { + + return; + } + } + + Peb = NtCurrentPeb(); + + // + // CSDVersion is the service pack number, and therefore should be 0 + // for anything higher than Windows 7 since those OSes don't have any + // service packs. + // + + CSDVersion = 0; + RtlInitConstantUnicodeString(&CSDVersionUnicodeString, L""); + + switch (KexData->IfeoParameters.WinVerSpoof) { + case WinVerSpoofWin7: + // Spoofing Windows 7 on Windows 7 is mainly meant for users of Win7 RTM, + // since there are some programs which require SP1. + MajorVersion = 6; + MinorVersion = 1; + BuildNumber = 7601; + CSDVersion = 0x100; + RtlInitConstantUnicodeString(&CSDVersionUnicodeString, L"Service Pack 1"); + break; + case WinVerSpoofWin8: + MajorVersion = 6; + MinorVersion = 2; + BuildNumber = 9200; + break; + case WinVerSpoofWin8Point1: + MajorVersion = 6; + MinorVersion = 3; + BuildNumber = 9600; + break; + case WinVerSpoofWin10: + MajorVersion = 10; + MinorVersion = 0; + BuildNumber = 19044; // Win10 21H2 + break; + case WinVerSpoofWin11: + default: // default case should always be at the highest win version + MajorVersion = 10; + MinorVersion = 0; + BuildNumber = 22000; // Win11 21H2 + break; + } + + Peb->OSMajorVersion = MajorVersion; + Peb->OSMinorVersion = MinorVersion; + Peb->OSBuildNumber = BuildNumber; + Peb->OSCSDVersion = CSDVersion; + Peb->CSDVersion = CSDVersionUnicodeString; + + // + // RtlGetNtVersionNumbers has hard coded numbers, so we have to hook and + // replace it with a custom function. + // + + KexHkInstallBasicHook(RtlGetNtVersionNumbers, Ext_RtlGetNtVersionNumbers, NULL); + + // + // Strong version spoofing is anything that involves runtime performance + // penalty, or a potential application compatibility penalty to apply. + // For example, spoofing the version number in the registry, in the file + // system, or in SharedUserData. + // + // The StrongVersionSpoof IFEO parameter is a bit field. + // + + if (KexData->IfeoParameters.StrongVersionSpoof & KEX_STRONGSPOOF_SHAREDUSERDATA) { + NTSTATUS Status; + PVOID SharedUserDataPageAddress; + SIZE_T SharedUserDataSize; + ULONG OldProtect; + + // + // SharedUserData spoofing requires additional support from BASE dlls + // and even then, may cause an app compat problem if anything reads + // from it directly. + // + // We are lucky in that it can be made read-write, but any write to it + // will cause the system time fields to stop updating, as the page is + // copy on write. + // + + SharedUserDataPageAddress = SharedUserData; + SharedUserDataSize = sizeof(KUSER_SHARED_DATA); + Status = NtProtectVirtualMemory( + NtCurrentProcess(), + &SharedUserDataPageAddress, + &SharedUserDataSize, + PAGE_READWRITE, + &OldProtect); + + if (NT_SUCCESS(Status)) { + SharedUserData->NtMajorVersion = MajorVersion; + SharedUserData->NtMinorVersion = MinorVersion; + + if (MajorVersion >= 10) { + // win10+ only field, reserved in win7 + SharedUserData->NtBuildNumber = BuildNumber; + } + + // + // Performance counter is queried from SharedUserData directly + // unless bit 1 of TscQpcData (i.e. TscQpcEnabled) is cleared. + // See RtlQueryPerformanceCounter for more information. + // + SharedUserData->TscQpcEnabled = FALSE; + + // + // The NtQuerySystemTime stub actually reads from SharedUserData, + // which is why we need to redirect it to the custom syscall stub. + // + KexHkInstallBasicHook(NtQuerySystemTime, KexNtQuerySystemTime, NULL); + } else { + KexLogWarningEvent( + L"Failed to make SharedUserData read-write.\r\n\r\n" + L"NTSTATUS error code: %s", + KexRtlNtStatusToString(Status)); + } + } + + // + // TODO: Implement registry strong spoofing. + // +} \ No newline at end of file diff --git a/KexDll/vxlopcl.c b/KexDll/vxlopcl.c new file mode 100644 index 0000000..d64192e --- /dev/null +++ b/KexDll/vxlopcl.c @@ -0,0 +1,380 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// opnclose.c +// +// Abstract: +// +// Contains the public routines for opening and closing log files. +// +// Author: +// +// vxiiduu (30-Sep-2022) +// +// Revision History: +// +// vxiiduu 30-Sep-2022 Initial creation. +// vxiiduu 15-Oct-2022 Convert to v2 format. +// vxiiduu 12-Nov-2022 Convert to v3 + native API +// vxiiduu 08-Jan-2023 Set compressed attribute on vxl files +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kexdllp.h" + +STATIC CONST CHAR VXLL_MAGIC[] = {'V','X','L','L'}; + +// +// Open a log file. +// +// LogHandle +// Pointer to a VXLHANDLE that will receive the log handle. +// +// SourceApplication +// String that indicates which application is opening the log file. +// If this string is specified, and the log file is opened for append +// access, then the source application already inside the log file +// will be checked to see if it is the same. If not, the call fails. +// This parameter must be specified if a new log file is created. +// +// ObjectAttributes +// An OBJECT_ATTRIBUTES structure which specifies the file name, its +// root directory, etc. +// +// DesiredAccess +// Must be either GENERIC_READ or GENERIC_WRITE. +// Any other values will cause a failure. +// +// CreateDisposition +// One of the following values: +// +// FILE_SUPERSEDE, FILE_CREATE, FILE_OPEN, FILE_OPEN_IF, +// FILE_OVERWRITE, FILE_OVERWRITE_IF +// +// See the documentation for NtCreateFile to understand what these +// values mean. +// +NTSTATUS NTAPI VxlOpenLog( + OUT PVXLHANDLE LogHandle, + IN PUNICODE_STRING SourceApplication OPTIONAL, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN ACCESS_MASK DesiredAccess, + IN ULONG CreateDisposition) +{ + NTSTATUS Status; + HANDLE SectionHandle; + SIZE_T ViewSize; + IO_STATUS_BLOCK IoStatusBlock; + ULONG ShareAccess; + LONGLONG CreationInitialSize; + PVXLCONTEXT Context; + BOOLEAN NewLogFileCreated; + ULONG SectionDesiredAccess; + ULONG SectionPageProtection; + + if (LogHandle) { + *LogHandle = NULL; + } + + // + // Validate input parameters. + // + + if (!LogHandle || !ObjectAttributes || !DesiredAccess) { + return STATUS_INVALID_PARAMETER; + } + + if (DesiredAccess == GENERIC_READ) { + if (CreateDisposition == FILE_SUPERSEDE || + CreateDisposition == FILE_CREATE || + CreateDisposition == FILE_OVERWRITE || + CreateDisposition == FILE_OVERWRITE_IF) { + + return STATUS_INVALID_PARAMETER; + } + } else if (DesiredAccess != GENERIC_WRITE) { + return STATUS_INVALID_PARAMETER; + } + + Context = NULL; + SectionHandle = NULL; + + try { + // + // Allocate memory for the context structure. + // + + Context = SafeAllocSeh(VXLCONTEXT, 1); + + RtlInitializeSRWLock(&Context->Lock); + + // + // Open the log file itself. + // + + Context->OpenMode = DesiredAccess; + DesiredAccess |= SYNCHRONIZE; + + if (Context->OpenMode == GENERIC_READ) { + ShareAccess = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; + } else { + // Add read permission since we still need to read file headers, + // etc. + DesiredAccess |= GENERIC_READ; + + // Do not allow other apps to write to the log file while we are + // writing it. + ShareAccess = FILE_SHARE_READ | FILE_SHARE_DELETE; + } + + // If we are creating or overwriting a file, then we will allocate enough + // space for the header up front. + CreationInitialSize = sizeof(VXLLOGFILEHEADER); + + Status = NtCreateFile( + &Context->FileHandle, + DesiredAccess, + ObjectAttributes, + &IoStatusBlock, + &CreationInitialSize, + FILE_ATTRIBUTE_NORMAL, + ShareAccess, + CreateDisposition, + FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE, + NULL, + 0); + + if (!NT_SUCCESS(Status)) { + leave; + } + + if (IoStatusBlock.Information == FILE_CREATED || + IoStatusBlock.Information == FILE_SUPERSEDED || + IoStatusBlock.Information == FILE_OVERWRITTEN) { + NewLogFileCreated = TRUE; + } else { + NewLogFileCreated = FALSE; + } + + if (NewLogFileCreated) { + ULONG CompressionType; + + // + // If we created or emptied the file, set the valid data length + // to the size of the log file header so we can map it. Otherwise + // we will get STATUS_MAPPED_FILE_SIZE_ZERO from NtCreateSection. + // + + Status = NtSetInformationFile( + Context->FileHandle, + &IoStatusBlock, + &CreationInitialSize, + sizeof(CreationInitialSize), + FileEndOfFileInformation); + + if (!NT_SUCCESS(Status)) { + leave; + } + + // + // Attempt to set the NTFS compression attribute on the log file. + // Uncompressed log files can quickly accumulate and consume the + // user's disk space, so we want to reduce this impact as much as + // possible. + // + // Of course, this call may fail if the file is on a FAT volume or + // other file system that does not support compression. In this + // case we don't really care - we tried. + // + + CompressionType = COMPRESSION_FORMAT_LZNT1; + + NtFsControlFile( + Context->FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + FSCTL_SET_COMPRESSION, + &CompressionType, + sizeof(CompressionType), + NULL, + 0); + } + + // + // Create a section backed by the entire log file. + // If we are opening for read only, map the entire log file into + // memory. If we are opening read-write, only map the header. + // + + if (Context->OpenMode == GENERIC_READ) { + SectionDesiredAccess = SECTION_MAP_READ; + SectionPageProtection = PAGE_READONLY; + } else { + SectionDesiredAccess = SECTION_MAP_READ | SECTION_MAP_WRITE; + SectionPageProtection = PAGE_READWRITE; + } + + Status = NtCreateSection( + &SectionHandle, + SectionDesiredAccess, + NULL, + NULL, + SectionPageProtection, + SEC_COMMIT, + Context->FileHandle); + + if (!NT_SUCCESS(Status)) { + leave; + } + + if (Context->OpenMode == GENERIC_READ) { + // map entire + ViewSize = 0; + } else { + // only map header + ViewSize = sizeof(VXLLOGFILEHEADER); + } + + Status = NtMapViewOfSection( + SectionHandle, + NtCurrentProcess(), + &Context->MappedSection, + 0, + 0, + NULL, + &ViewSize, + ViewUnmap, + 0, + Context->OpenMode == GENERIC_READ ? PAGE_READONLY : PAGE_READWRITE); + + if (!NT_SUCCESS(Status)) { + leave; + } + + // + // If we are creating a new log file, we must create a new + // log file header. Otherwise, we will validate the existing header. + // + + if (NewLogFileCreated) { + UNICODE_STRING DestinationSourceApplication; + + // + // New empty log file has been created. + // Populate it with a header. + // + + if (!SourceApplication) { + Status = STATUS_INVALID_PARAMETER; + leave; + } + + RtlZeroMemory(Context->Header, sizeof(*Context->Header)); + + RtlInitEmptyUnicodeString( + &DestinationSourceApplication, + Context->Header->SourceApplication, + sizeof(Context->Header->SourceApplication) - sizeof(WCHAR)); + + RtlCopyUnicodeString(&DestinationSourceApplication, SourceApplication); + + Context->Header->Version = VXLL_VERSION; + RtlCopyMemory(Context->Header->Magic, VXLL_MAGIC, sizeof(VXLL_MAGIC)); + } else { + // + // Opening existing log file. Validate the header. + // + + if (!RtlEqualMemory(Context->Header->Magic, VXLL_MAGIC, sizeof(VXLL_MAGIC))) { + Status = STATUS_FILE_INVALID; + leave; + } + + if (Context->Header->Version != VXLL_VERSION) { + Status = STATUS_VERSION_MISMATCH; + leave; + } + + if (Context->OpenMode == GENERIC_WRITE) { + // + // If source application parameter was specified, make sure + // that it is the same as what is in the log file. + // + + if (SourceApplication) { + UNICODE_STRING SourceApplicationFromFile; + + RtlInitUnicodeString( + &SourceApplicationFromFile, + Context->Header->SourceApplication); + + if (!RtlEqualUnicodeString(SourceApplication, &SourceApplicationFromFile, TRUE)) { + Status = STATUS_SOURCE_APPLICATION_MISMATCH; + leave; + } + } + } else { + // + // Opened for reading - build the index. + // + + Status = VxlpBuildIndex(Context); + if (!NT_SUCCESS(Status)) { + leave; + } + } + } + + // + // If opening the file for write access, mark the header as dirty. + // + + if (Context->OpenMode == GENERIC_WRITE) { + Context->Header->Dirty = TRUE; + VxlpFlushLogFileHeader(Context); + } + } except (EXCEPTION_EXECUTE_HANDLER) { + Status = GetExceptionCode(); + } + + SafeClose(SectionHandle); + + if (!NT_SUCCESS(Status)) { + VxlCloseLog(&Context); + } + + *LogHandle = Context; + return Status; +} + +NTSTATUS NTAPI VxlCloseLog( + IN OUT PVXLHANDLE LogHandle) +{ + PVXLCONTEXT Context; + + if (!LogHandle) { + return STATUS_INVALID_PARAMETER; + } + + Context = *LogHandle; + + if (Context) { + if (Context->OpenMode == GENERIC_WRITE && Context->Header != NULL) { + Context->Header->Dirty = FALSE; + } + + if (Context->MappedSection) { + NtUnmapViewOfSection(NtCurrentProcess(), Context->MappedSection); + } + + SafeClose(Context->FileHandle); + SafeFree(Context->EntryIndexToFileOffset); + SafeFree(*LogHandle); + } + + return STATUS_SUCCESS; +} \ No newline at end of file diff --git a/KexDll/vxlpriv.c b/KexDll/vxlpriv.c new file mode 100644 index 0000000..29c778d --- /dev/null +++ b/KexDll/vxlpriv.c @@ -0,0 +1,231 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// vxlpriv.c +// +// Abstract: +// +// Contains miscellaneous private routines. +// +// Author: +// +// vxiiduu (30-Sep-2022) +// +// Revision History: +// +// vxiiduu 30-Sep-2022 Initial creation. +// vxiiduu 15-Oct-2022 Convert to v2 format. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kexdllp.h" + +#pragma warning(disable:4244) + +NTSTATUS VxlpFlushLogFileHeader( + IN VXLHANDLE LogHandle) +{ + PVOID Base; + SIZE_T Size; + IO_STATUS_BLOCK IoStatusBlock; + + ASSERT (LogHandle != NULL); + ASSERT (LogHandle->Header != NULL); + ASSERT (LogHandle->OpenMode == GENERIC_WRITE); + + Base = LogHandle->Header; + Size = sizeof(*LogHandle->Header); + + return NtFlushVirtualMemory( + NtCurrentProcess(), + &Base, + &Size, + &IoStatusBlock); +} + +ULONG VxlpGetTotalLogEntryCount( + IN VXLHANDLE LogHandle) +{ + ULONG Index; + ULONG Total; + + ASSERT (LogHandle != NULL); + ASSERT (LogHandle->Header != NULL); + + Total = 0; + + ForEachArrayItem (LogHandle->Header->EventSeverityTypeCount, Index) { + Total += LogHandle->Header->EventSeverityTypeCount[Index]; + } + + return Total; +} + +ULONG VxlpSizeOfLogFileEntry( + IN PVXLLOGFILEENTRY Entry) +{ + ULONG Size; + + ASSERT (Entry != NULL); + + Size = sizeof(VXLLOGFILEENTRY); + Size += Entry->TextHeaderCch * sizeof(WCHAR); + Size += Entry->TextCch * sizeof(WCHAR); + + return Size; +} + +NTSTATUS VxlpBuildIndex( + IN VXLHANDLE LogHandle) +{ + PVXLLOGFILEENTRY Entry; + ULONG TotalLogEntryCount; + ULONG Index; + ULONG SeverityIndex[LogSeverityMaximumValue]; + + ASSERT (LogHandle != NULL); + ASSERT (LogHandle->OpenMode == GENERIC_READ); + ASSERT (LogHandle->EntryIndexToFileOffset == NULL); + + TotalLogEntryCount = VxlpGetTotalLogEntryCount(LogHandle); + + if (!TotalLogEntryCount) { + return STATUS_NO_MORE_ENTRIES; + } + + // + // Allocate memory for the index. + // + + LogHandle->EntryIndexToFileOffset = SafeAllocSeh(ULONG, TotalLogEntryCount); + + Entry = (PVXLLOGFILEENTRY) (LogHandle->MappedFile + sizeof(VXLLOGFILEHEADER)); + RtlZeroMemory(SeverityIndex, sizeof(SeverityIndex)); + + for (Index = 0; TotalLogEntryCount--; ++Index) { + // + // record file offset of the Index'th entry into the index, + // for fast seeking to any particular log entry + // + + LogHandle->EntryIndexToFileOffset[Index] = (ULONG) VA_TO_RVA(LogHandle->MappedFile, Entry); + + // + // skip ahead to next entry + // + + Entry = (PVXLLOGFILEENTRY) RVA_TO_VA(Entry, VxlpSizeOfLogFileEntry(Entry)); + } + + return STATUS_SUCCESS; +} + +NTSTATUS VxlpFindOrCreateSourceComponentIndex( + IN VXLHANDLE LogHandle, + IN PCWSTR SourceComponent, + OUT PUCHAR SourceComponentIndex) +{ + ULONG Index; + + ASSERT (LogHandle != NULL); + ASSERT (SourceComponent != NULL); + ASSERT (SourceComponentIndex != NULL); + ASSERT (wcslen(SourceComponent) < ARRAYSIZE(LogHandle->Header->SourceComponents[0])); + + for (Index = 0; Index < ARRAYSIZE(LogHandle->Header->SourceComponents); ++Index) { + if (StringEqual(LogHandle->Header->SourceComponents[Index], SourceComponent)) { + *SourceComponentIndex = Index; + return STATUS_SUCCESS; + } else if (LogHandle->Header->SourceComponents[Index][0] == '\0') { + HRESULT Result; + + Result = StringCchCopy( + LogHandle->Header->SourceComponents[Index], + ARRAYSIZE(LogHandle->Header->SourceComponents[Index]), + SourceComponent); + + if (FAILED(Result)) { + return STATUS_BUFFER_TOO_SMALL; + } + + *SourceComponentIndex = Index; + return STATUS_SUCCESS; + } + } + + return STATUS_TOO_MANY_INDICES; +} + +NTSTATUS VxlpFindOrCreateSourceFileIndex( + IN VXLHANDLE LogHandle, + IN PCWSTR SourceFile, + OUT PUCHAR SourceFileIndex) +{ + ULONG Index; + + ASSERT (LogHandle != NULL); + ASSERT (SourceFile != NULL); + ASSERT (SourceFileIndex != NULL); + ASSERT (wcslen(SourceFile) < ARRAYSIZE(LogHandle->Header->SourceFiles[0])); + + for (Index = 0; Index < ARRAYSIZE(LogHandle->Header->SourceFiles); ++Index) { + if (StringEqual(LogHandle->Header->SourceFiles[Index], SourceFile)) { + *SourceFileIndex = Index; + return STATUS_SUCCESS; + } else if (LogHandle->Header->SourceFiles[Index][0] == '\0') { + HRESULT Result; + + Result = StringCchCopy( + LogHandle->Header->SourceFiles[Index], + ARRAYSIZE(LogHandle->Header->SourceFiles[Index]), + SourceFile); + + if (FAILED(Result)) { + return STATUS_BUFFER_TOO_SMALL; + } + + *SourceFileIndex = Index; + return STATUS_SUCCESS; + } + } + + return STATUS_TOO_MANY_INDICES; +} + +NTSTATUS VxlpFindOrCreateSourceFunctionIndex( + IN VXLHANDLE LogHandle, + IN PCWSTR SourceFunction, + OUT PUCHAR SourceFunctionIndex) +{ + ULONG Index; + + ASSERT (LogHandle != NULL); + ASSERT (SourceFunction != NULL); + ASSERT (SourceFunctionIndex != NULL); + ASSERT (wcslen(SourceFunction) < ARRAYSIZE(LogHandle->Header->SourceFunctions[0])); + + for (Index = 0; Index < ARRAYSIZE(LogHandle->Header->SourceFunctions); ++Index) { + if (StringEqual(LogHandle->Header->SourceFunctions[Index], SourceFunction)) { + *SourceFunctionIndex = Index; + return STATUS_SUCCESS; + } else if (LogHandle->Header->SourceFunctions[Index][0] == '\0') { + HRESULT Result; + + Result = StringCchCopy( + LogHandle->Header->SourceFunctions[Index], + ARRAYSIZE(LogHandle->Header->SourceFunctions[Index]), + SourceFunction); + + if (FAILED(Result)) { + return STATUS_BUFFER_TOO_SMALL; + } + + *SourceFunctionIndex = Index; + return STATUS_SUCCESS; + } + } + + return STATUS_TOO_MANY_INDICES; +} \ No newline at end of file diff --git a/KexDll/vxlquery.c b/KexDll/vxlquery.c new file mode 100644 index 0000000..0c1f4e0 --- /dev/null +++ b/KexDll/vxlquery.c @@ -0,0 +1,107 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// vxlquery.c +// +// Abstract: +// +// Contains the public routines for querying log file information. +// +// Author: +// +// vxiiduu (30-Sep-2022) +// +// Revision History: +// +// vxiiduu 30-Sep-2022 Initial creation. +// vxiiduu 12-Nov-2022 Convert to v3 + native API +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kexdllp.h" + +#pragma warning(disable:4267) + +NTSTATUS NTAPI VxlQueryInformationLog( + IN VXLHANDLE LogHandle, + IN VXLLOGINFOCLASS LogInformationClass, + OUT PVOID Buffer OPTIONAL, + IN OUT PULONG BufferSize) +{ + ULONG RequiredBufferSize; + + if (!LogHandle || !BufferSize) { + return STATUS_INVALID_PARAMETER; + } + + if (!Buffer && *BufferSize != 0) { + return STATUS_INVALID_PARAMETER_MIX; + } + + switch (LogInformationClass) { + case LogLibraryVersion: + if (*BufferSize <= sizeof(ULONG)) { + RequiredBufferSize = sizeof(ULONG); + break; + } else { + *(PULONG) Buffer = VXLL_VERSION; + return STATUS_SUCCESS; + } + case LogNumberOfCriticalEvents: + case LogNumberOfErrorEvents: + case LogNumberOfWarningEvents: + case LogNumberOfInformationEvents: + case LogNumberOfDetailEvents: + case LogNumberOfDebugEvents: + case LogTotalNumberOfEvents: + RequiredBufferSize = sizeof(ULONG); + break; + case LogSourceApplication: + // we will figure this out later + RequiredBufferSize = 0; + break; + default: + return STATUS_INVALID_INFO_CLASS; + } + + if (*BufferSize < RequiredBufferSize) { + *BufferSize = RequiredBufferSize; + return STATUS_BUFFER_TOO_SMALL; + } + + try { + RtlAcquireSRWLockShared(&LogHandle->Lock); + + switch (LogInformationClass) { + case LogNumberOfCriticalEvents: + case LogNumberOfErrorEvents: + case LogNumberOfWarningEvents: + case LogNumberOfInformationEvents: + case LogNumberOfDetailEvents: + case LogNumberOfDebugEvents: + *(PULONG) Buffer = LogHandle->Header->EventSeverityTypeCount[LogInformationClass - 1]; + break; + case LogTotalNumberOfEvents: + *(PULONG) Buffer = VxlpGetTotalLogEntryCount(LogHandle); + break; + case LogSourceApplication: + RequiredBufferSize = wcslen(LogHandle->Header->SourceApplication) * sizeof(WCHAR); + + if (*BufferSize < RequiredBufferSize) { + *BufferSize = RequiredBufferSize; + return STATUS_BUFFER_TOO_SMALL; + } + + RtlCopyMemory(Buffer, LogHandle->Header->SourceApplication, RequiredBufferSize); + break; + default: + NOT_REACHED; + } + } finally { + RtlReleaseSRWLockShared(&LogHandle->Lock); + } + + return STATUS_SUCCESS; +} \ No newline at end of file diff --git a/KexDll/vxlread.c b/KexDll/vxlread.c new file mode 100644 index 0000000..e28412d --- /dev/null +++ b/KexDll/vxlread.c @@ -0,0 +1,186 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// vxlread.c +// +// Abstract: +// +// Contains the public routines for reading entries from a log file. +// +// Author: +// +// vxiiduu (19-Nov-2022) +// +// Revision History: +// +// vxiiduu 19-Nov-2022 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kexdllp.h" + +STATIC FORCEINLINE NTSTATUS VxlpReadLogInternal( + IN VXLHANDLE LogHandle, + IN ULONG LogEntryIndex, + OUT PVXLLOGENTRY Entry) +{ + PVXLLOGFILEENTRY FileEntry; + TIME_FIELDS TimeFields; + LONGLONG LocalTime; + + ASSERT (Entry != NULL); + ASSERT (LogHandle != NULL); + ASSERT (LogHandle->MappedFile != NULL); + ASSERT (LogHandle->EntryIndexToFileOffset != NULL); + ASSERT (LogHandle->EntryIndexToFileOffset[LogEntryIndex] != 0); + + // + // Use the index to look up the file offset for this log entry, and then + // convert it into a pointer to the log entry. + // + + FileEntry = (PVXLLOGFILEENTRY) RVA_TO_VA( + LogHandle->MappedFile, + LogHandle->EntryIndexToFileOffset[LogEntryIndex]); + + // + // Fill out the caller's provided VXLLOGENTRY structure. + // + + RtlZeroMemory(Entry, sizeof(*Entry)); + + if (FileEntry->TextHeaderCch != 0) { + Entry->TextHeader.Length = (FileEntry->TextHeaderCch - 1) * sizeof(WCHAR); + Entry->TextHeader.MaximumLength = Entry->TextHeader.Length + sizeof(WCHAR); + Entry->TextHeader.Buffer = FileEntry->Text; + } + + if (FileEntry->TextCch != 0) { + Entry->Text.Length = (FileEntry->TextCch - 1) * sizeof(WCHAR); + Entry->Text.MaximumLength = Entry->Text.Length + sizeof(WCHAR); + Entry->Text.Buffer = FileEntry->Text + FileEntry->TextHeaderCch; + } + + Entry->SourceComponentIndex = FileEntry->SourceComponentIndex; + Entry->SourceFileIndex = FileEntry->SourceFileIndex; + Entry->SourceFunctionIndex = FileEntry->SourceFunctionIndex; + Entry->SourceLine = FileEntry->SourceLine; + + Entry->ClientId.UniqueProcess = (HANDLE) FileEntry->ProcessId; + Entry->ClientId.UniqueThread = (HANDLE) FileEntry->ThreadId; + + Entry->Severity = FileEntry->Severity; + + // + // Fill out the SYSTEMTIME structure in the VXLLOGENTRY structure. + // First, convert the 64-bit timestamp in the VXLLOGFILEENTRY from UTC + // to local time. + // + + do { + LocalTime = FileEntry->Time64 - *(PLONGLONG) &SharedUserData->TimeZoneBias; + } until (SharedUserData->TimeZoneBias.High1Time == SharedUserData->TimeZoneBias.High2Time); + + // + // Now convert the local time into a SYSTEMTIME. + // + + RtlTimeToTimeFields(&LocalTime, &TimeFields); + Entry->Time.wYear = TimeFields.Year; + Entry->Time.wMonth = TimeFields.Month; + Entry->Time.wDay = TimeFields.Day; + Entry->Time.wDayOfWeek = TimeFields.Weekday; + Entry->Time.wHour = TimeFields.Hour; + Entry->Time.wMinute = TimeFields.Minute; + Entry->Time.wSecond = TimeFields.Second; + Entry->Time.wMilliseconds = TimeFields.Milliseconds; + + return STATUS_SUCCESS; +} + +NTSTATUS NTAPI VxlReadLog( + IN VXLHANDLE LogHandle, + IN ULONG LogEntryIndex, + OUT PVXLLOGENTRY Entry) +{ + ULONG MaximumIndex; + + // + // Parameter validation + // + + if (!LogHandle || !Entry) { + return STATUS_INVALID_PARAMETER; + } + + if (LogHandle->OpenMode != GENERIC_READ) { + return STATUS_INVALID_OPEN_MODE; + } + + MaximumIndex = VxlpGetTotalLogEntryCount(LogHandle); + + if (MaximumIndex == -1) { + return STATUS_NO_MORE_ENTRIES; + } + + if (LogEntryIndex > MaximumIndex) { + return STATUS_NO_MORE_ENTRIES; + } + + return VxlpReadLogInternal(LogHandle, LogEntryIndex, Entry); +} + +NTSTATUS NTAPI VxlReadMultipleEntriesLog( + IN VXLHANDLE LogHandle, + IN ULONG LogEntryIndexStart, + IN ULONG LogEntryIndexEnd, + OUT PVXLLOGENTRY Entry[]) +{ + NTSTATUS Status; + ULONG Index; + ULONG MaximumIndex; + + // + // Parameter validation + // + + if (!LogHandle || !Entry) { + return STATUS_INVALID_PARAMETER; + } + + if (LogEntryIndexEnd < LogEntryIndexStart) { + return STATUS_INVALID_PARAMETER_MIX; + } + + MaximumIndex = VxlpGetTotalLogEntryCount(LogHandle) - 1; + + if (MaximumIndex == -1) { + return STATUS_NO_MORE_ENTRIES; + } + + if (LogEntryIndexStart > MaximumIndex) { + return STATUS_NO_MORE_ENTRIES; + } + + if (LogEntryIndexEnd > MaximumIndex) { + LogEntryIndexEnd = MaximumIndex; + } + + // + // Fetch the requested log entries. + // + + for (Index = LogEntryIndexStart; Index < LogEntryIndexEnd; ++Index) { + Status = VxlpReadLogInternal(LogHandle, Index, Entry[Index - LogEntryIndexStart]); + + if (!NT_SUCCESS(Status)) { + return Status; + } + + ++Index; + } + + return Status; +} \ No newline at end of file diff --git a/KexDll/vxlsever.c b/KexDll/vxlsever.c new file mode 100644 index 0000000..98a0582 --- /dev/null +++ b/KexDll/vxlsever.c @@ -0,0 +1,46 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// vxlsever.c +// +// Abstract: +// +// Contains a routine to convert a VXLSEVERITY enumeration value into a +// human-readable string. +// +// Author: +// +// vxiiduu (30-Sep-2022) +// +// Revision History: +// +// vxiiduu 30-Sep-2022 Initial creation. +// vxiiduu 12-Nov-2022 Move into KexDll +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kexdllp.h" + +static PCWSTR SeverityLookupTable[][2] = { + {L"Critical", L"The application encountered a critical error and cannot continue"}, + {L"Error", L"The application encountered a non-critical error which affected its function"}, + {L"Warning", L"An event occurred which should be investigated but does not affect the immediate functioning of the application"}, + {L"Information", L"An informational message which is not a cause for concern"}, + {L"Detail", L"An informational message, generated in large quantities, which is not a cause for concern"}, + {L"Debug", L"Information useful only to the developer of the application"}, + {L"Unknown", L"An invalid or unknown severity value"} +}; + +// +// Convert a VXLSEVERITY enumeration value into a human-readable string. +// You can obtain a long description by passing TRUE for the LongDescription +// parameter. +// +KEXAPI PCWSTR NTAPI VxlSeverityToText( + IN VXLSEVERITY Severity, + IN BOOLEAN LongDescription) +{ + return SeverityLookupTable[min((ULONG) Severity, LogSeverityMaximumValue)][!!LongDescription]; +} \ No newline at end of file diff --git a/KexDll/vxlwrite.c b/KexDll/vxlwrite.c new file mode 100644 index 0000000..eb68905 --- /dev/null +++ b/KexDll/vxlwrite.c @@ -0,0 +1,261 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// vxlwrite.c +// +// Abstract: +// +// Contains the function that is used to write an entry to a log file. +// +// Author: +// +// vxiiduu +// +// Revision History: +// +// vxiiduu 08-Jan-2023 Move from critical section to SRW lock +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "kexdllp.h" + +#pragma warning(disable:4244) // conversion from ULONG to USHORT +#pragma warning(disable:4018) // signed/unsigned mismatch + +NTSTATUS CDECL VxlWriteLogEx( + IN VXLHANDLE LogHandle OPTIONAL, + IN PCWSTR SourceComponent OPTIONAL, + IN PCWSTR SourceFile OPTIONAL, + IN ULONG SourceLine, + IN PCWSTR SourceFunction OPTIONAL, + IN VXLSEVERITY Severity, + IN PCWSTR Format, + IN ...) +{ + NTSTATUS Status; + ARGLIST ArgList; + PVXLLOGFILEENTRY FileEntry; + ULONG FileEntryCb; + PTEB Teb; + IO_STATUS_BLOCK IoStatusBlock; + LONGLONG EndOfFileOffset; + + // + // param validation + // + + if (KexIsReleaseBuild && LogHandle == NULL) { + return STATUS_INVALID_HANDLE; + } + + if (!Format) { + return STATUS_INVALID_PARAMETER; + } + + if (Severity < 0 || Severity > LogSeverityMaximumValue) { + return STATUS_INVALID_PARAMETER; + } + + // + // assign default values to optional parameters + // + + if (!SourceComponent) { + SourceComponent = L""; + } + + if (!SourceFile) { + SourceFile = L""; + } + + if (!SourceFunction) { + SourceFunction = L""; + } + + Status = STATUS_SUCCESS; + FileEntryCb = sizeof(VXLLOGFILEENTRY); + Teb = NtCurrentTeb(); + + va_start(ArgList, Format); + + try { + HRESULT Result; + SIZE_T TextCchSizeT; + ULONG TextCch; + PWSTR DoubleNewLine; + + // + // find out how many text characters in the log entry + // + + Result = StringCchVPrintfBufferLength(&TextCchSizeT, Format, ArgList); + if (FAILED(Result)) { + // must be because of an invalid format string + Status = STATUS_INVALID_PARAMETER; + leave; + } + + TextCch = (ULONG) TextCchSizeT; + + // + // allocate memory for log entry and format text into the buffer + // + + FileEntryCb += TextCch * sizeof(WCHAR); + + if (FileEntryCb > 0xFFFF) { + Status = STATUS_BUFFER_TOO_SMALL; + leave; + } + + // It's important that we avoid performing any heap allocations, directly + // or indirectly, in VxlWriteLog. This is because we want VxlWriteLog to + // always function, even in cases of no system memory. + FileEntry = (PVXLLOGFILEENTRY) StackAlloc(BYTE, FileEntryCb); + RtlZeroMemory(FileEntry, FileEntryCb); + + Result = StringCchVPrintf(FileEntry->Text, TextCch, Format, ArgList); + if (FAILED(Result)) { + Status = STATUS_INTERNAL_ERROR; + leave; + } + + // + // If a debugger is attached, write the formatted log message to the + // debugging console. + // + + if (NtCurrentPeb()->BeingDebugged) { + DbgPrint("VXL (%ws): %ws\r\n", SourceComponent, FileEntry->Text); + } + + // + // At this point, if the passed-in Log Handle is invalid, we'll just + // exit here. We've already printed the log message to the debugger. + // + + if (!LogHandle) { + Status = STATUS_INVALID_HANDLE; + leave; + } + + // + // Check for a double newline (\r\n\r\n) and replace the first \r\n + // out of the two \r\n's with a single null character (\0), unless + // the double newline occurs at the end of the string. + // + + DoubleNewLine = (PWSTR) StringFind(FileEntry->Text, L"\r\n\r\n"); + + if (DoubleNewLine && DoubleNewLine[4]) { + *DoubleNewLine = '\0'; + + RtlMoveMemory( + DoubleNewLine + 1, + DoubleNewLine + 4, + (TextCch - (DoubleNewLine + 4 - FileEntry->Text)) * sizeof(WCHAR)); + + TextCch -= 3; + FileEntry->TextHeaderCch = DoubleNewLine - FileEntry->Text + 1; + FileEntry->TextCch = TextCch - FileEntry->TextHeaderCch; + + ASSERT (wcslen(FileEntry->Text + FileEntry->TextHeaderCch) == FileEntry->TextCch - 1); + + // recalculate new size of log file entry, since we reduced its + // size by 3 characters + FileEntryCb -= 3 * sizeof(WCHAR); + } else { + FileEntry->TextHeaderCch = TextCch; + // FileEntry->TextCch remains 0 since it was zeroed at allocation + } + + ASSERT (wcslen(FileEntry->Text) == FileEntry->TextHeaderCch - 1); + ASSERT (FileEntry->TextCch + FileEntry->TextHeaderCch <= TextCch); + + // + // Fill out remaining fields in the log file entry that do not require + // interacting with the log file header. + // + + KexNtQuerySystemTime((PLONGLONG) &FileEntry->Time64); + FileEntry->ProcessId = (ULONG) Teb->ClientId.UniqueProcess; + FileEntry->ThreadId = (ULONG) Teb->ClientId.UniqueThread; + FileEntry->Severity = Severity; + FileEntry->SourceLine = SourceLine; + + Status = STATUS_SUCCESS; + } except (EXCEPTION_EXECUTE_HANDLER) { + Status = GetExceptionCode(); + } + + if (Status != STATUS_SUCCESS) { + return Status; + } + + ASSERT (LogHandle != NULL); + RtlAcquireSRWLockExclusive(&LogHandle->Lock); + + try { + // + // fill out source component, file, and function indices + // + + Status = VxlpFindOrCreateSourceComponentIndex( + LogHandle, + SourceComponent, + &FileEntry->SourceComponentIndex); + + if (!NT_SUCCESS(Status)) { + leave; + } + + Status = VxlpFindOrCreateSourceFileIndex( + LogHandle, + SourceFile, + &FileEntry->SourceFileIndex); + + if (!NT_SUCCESS(Status)) { + leave; + } + + Status = VxlpFindOrCreateSourceFunctionIndex( + LogHandle, + SourceFunction, + &FileEntry->SourceFunctionIndex); + + if (!NT_SUCCESS(Status)) { + leave; + } + + // + // update severity count + // + + ++LogHandle->Header->EventSeverityTypeCount[Severity]; + + // + // write the actual log entry to the file + // + + // Passing -1 causes the write to occur at the end of the file. + EndOfFileOffset = -1; + + Status = KexNtWriteFile( + LogHandle->FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + FileEntry, + FileEntryCb, + &EndOfFileOffset, + NULL); + } except (EXCEPTION_EXECUTE_HANDLER) { + Status = GetExceptionCode(); + } + + RtlReleaseSRWLockExclusive(&LogHandle->Lock); + return Status; +} \ No newline at end of file diff --git a/KexGui/KexGui.vcxproj b/KexGui/KexGui.vcxproj new file mode 100644 index 0000000..6f9dd4c --- /dev/null +++ b/KexGui/KexGui.vcxproj @@ -0,0 +1,273 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {F7DCFF24-19CD-4FE6-BDDF-6029670E77D6} + Win32Proj + KexGui + + + + StaticLibrary + true + Unicode + + + StaticLibrary + true + Unicode + + + StaticLibrary + false + true + Unicode + + + StaticLibrary + false + true + Unicode + + + + + + + + + + + + + + + + + + + false + + + false + + + false + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;KEXGUI_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + true + false + true + false + false + Default + ProgramDatabase + StdCall + CompileAsC + + + Windows + true + $(SolutionDir)\00-Import Libraries;$(TargetDir) + + + KexGui.def + false + true + + + $(SolutionDir)\00-Common Headers + + + + + + + true + $(SolutionDir)\00-Import Libraries + MachineX86 + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;KEXGUI_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + true + false + true + false + false + Default + ProgramDatabase + StdCall + CompileAsC + + + Windows + true + $(SolutionDir)\00-Import Libraries;$(TargetDir) + + + KexGui.def + false + true + + + $(SolutionDir)\00-Common Headers + + + + + + + true + $(SolutionDir)\00-Import Libraries + MachineX64 + + + + + Level3 + + + MinSpace + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;KEXGUI_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + true + false + true + false + false + Default + ProgramDatabase + OnlyExplicitInline + Size + true + StdCall + CompileAsC + + + Windows + true + true + true + $(SolutionDir)\00-Import Libraries;$(TargetDir) + + + KexGui.def + false + true + + + $(SolutionDir)\00-Common Headers + + + + + + + true + $(SolutionDir)\00-Import Libraries + MachineX86 + + + + + Level3 + + + MinSpace + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;KEXGUI_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + true + false + true + false + false + Default + ProgramDatabase + OnlyExplicitInline + Size + true + StdCall + CompileAsC + + + Windows + true + true + true + $(SolutionDir)\00-Import Libraries;$(TargetDir) + + + KexGui.def + false + true + + + $(SolutionDir)\00-Common Headers + + + + + + + true + $(SolutionDir)\00-Import Libraries + MachineX64 + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/KexGui/KexGui.vcxproj.filters b/KexGui/KexGui.vcxproj.filters new file mode 100644 index 0000000..3f16554 --- /dev/null +++ b/KexGui/KexGui.vcxproj.filters @@ -0,0 +1,54 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/KexGui/buildcfg.h b/KexGui/buildcfg.h new file mode 100644 index 0000000..bc37896 --- /dev/null +++ b/KexGui/buildcfg.h @@ -0,0 +1,24 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN +#define NOKEYSTATES +#define NOSYSCOMMANDS +#define NORASTEROPS +#define NOATOM +#define NOMEMMGR +#define NOOPENFILE +#define NOCOMM +#define NOKANJI +#define NOHELP +#define NOPROFILER +#define NOMCX +#define NOCRYPT +#define NOMETAFILE +#define NOSERVICE +#define NOSOUND + +#define KEXGDECLSPEC + +#define KEX_COMPONENT L"KexGui" +#define KEX_ENV_WIN32 +#define KEX_TARGET_TYPE_LIB diff --git a/KexGui/ctlsx.c b/KexGui/ctlsx.c new file mode 100644 index 0000000..aa99445 --- /dev/null +++ b/KexGui/ctlsx.c @@ -0,0 +1,86 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// ctlsx.c +// +// Abstract: +// +// Convenience functions for interacting with Windows controls. +// +// Author: +// +// vxiiduu (01-Oct-2022) +// +// Environment: +// +// Win32 +// +// Revision History: +// +// vxiiduu 01-Oct-2022 Initial creation. +// vxiiduu 05-Feb-2024 Add Button_SetShield() +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include +#include + +KEXGDECLSPEC EXTERN_C VOID KEXGAPI StatusBar_SetTextF( + IN HWND Window, + IN INT Index, + IN PCWSTR Format, + IN ...) +{ + HRESULT Result; + SIZE_T BufferCch; + PWSTR Buffer; + ARGLIST ArgList; + + ASSERT (Window != NULL); + ASSERT (Format != NULL); + + va_start(ArgList, Format); + + Result = StringCchVPrintfBufferLength(&BufferCch, Format, ArgList); + ASSERT (SUCCEEDED(Result)); + + if (FAILED(Result)) { + return; + } + + Buffer = StackAlloc(WCHAR, BufferCch); + Result = StringCchVPrintf(Buffer, BufferCch, Format, ArgList); + ASSERT (SUCCEEDED(Result)); + + if (FAILED(Result)) { + return; + } + + StatusBar_SetText(Window, Index, Buffer); +} + +KEXGDECLSPEC EXTERN_C VOID KEXGAPI ListView_SetCheckedStateAll( + IN HWND Window, + IN BOOLEAN Checked) +{ + ULONG Index; + ULONG NumberOfComponents; + + ASSERT (Window != NULL); + + NumberOfComponents = ListView_GetItemCount(Window); + + for (Index = 0; Index < NumberOfComponents; Index++) { + ListView_SetCheckState(Window, Index, Checked); + } +} + +KEXGDECLSPEC EXTERN_C VOID KEXGAPI Button_SetShield( + IN HWND Window, + IN BOOLEAN HasShield) +{ + ASSERT (IsWindow(Window)); + SendMessage(Window, BCM_SETSHIELD, 0, HasShield); +} \ No newline at end of file diff --git a/KexGui/dpi.c b/KexGui/dpi.c new file mode 100644 index 0000000..88fecfb --- /dev/null +++ b/KexGui/dpi.c @@ -0,0 +1,40 @@ +#include "buildcfg.h" +#include +#include + +STATIC BOOLEAN AlreadyInitialized = FALSE; +STATIC INT DpiX = USER_DEFAULT_SCREEN_DPI; +STATIC INT DpiY = USER_DEFAULT_SCREEN_DPI; + +STATIC VOID DpiInitialize( + VOID) +{ + HDC DeviceContext; + + DeviceContext = GetDC(NULL); + DpiX = GetDeviceCaps(DeviceContext, LOGPIXELSX); + DpiY = GetDeviceCaps(DeviceContext, LOGPIXELSY); + ReleaseDC(NULL, DeviceContext); + + AlreadyInitialized = TRUE; +} + +KEXGDECLSPEC INT KEXGAPI DpiScaleX( + IN INT PixelsX) +{ + if (!AlreadyInitialized) { + DpiInitialize(); + } + + return MulDiv(PixelsX, DpiX, USER_DEFAULT_SCREEN_DPI); +} + +KEXGDECLSPEC INT KEXGAPI DpiScaleY( + IN INT PixelsY) +{ + if (!AlreadyInitialized) { + DpiInitialize(); + } + + return MulDiv(PixelsY, DpiY, USER_DEFAULT_SCREEN_DPI); +} \ No newline at end of file diff --git a/KexGui/fldrpkr.c b/KexGui/fldrpkr.c new file mode 100644 index 0000000..bbbcc22 --- /dev/null +++ b/KexGui/fldrpkr.c @@ -0,0 +1,58 @@ +#include "buildcfg.h" +#include +#include +#include + +KEXGDECLSPEC EXTERN_C BOOLEAN KEXGAPI PickFolder( + IN HWND OwnerWindow OPTIONAL, + IN PCWSTR DefaultValue OPTIONAL, + IN ULONG AdditionalFlags OPTIONAL, // FOS_* + IN PWSTR DirectoryPath, + IN ULONG DirectoryPathCch) +{ + HRESULT Result; + IFileDialog *FileDialog; + IShellItem *ShellItem; + PWSTR ShellName; + ULONG Flags; + + ASSERT (DirectoryPath != NULL); + ASSERT (DirectoryPathCch != 0); + + FileDialog = NULL; + ShellItem = NULL; + + Result = CoCreateInstance( + &CLSID_FileOpenDialog, + NULL, + CLSCTX_INPROC_SERVER, + &IID_IFileOpenDialog, + (PPVOID) &FileDialog); + + if (!DefaultValue) { + DefaultValue = L""; + } + + if (FAILED(Result)) { + StringCchCopy(DirectoryPath, DirectoryPathCch, DefaultValue); + return FALSE; + } + + IFileDialog_GetOptions(FileDialog, &Flags); + IFileDialog_SetOptions(FileDialog, Flags | FOS_PICKFOLDERS | FOS_FORCEFILESYSTEM | AdditionalFlags); + IFileDialog_Show(FileDialog, OwnerWindow); + IFileDialog_GetResult(FileDialog, &ShellItem); + IFileDialog_Release(FileDialog); + + if (!ShellItem) { + StringCchCopy(DirectoryPath, DirectoryPathCch, DefaultValue); + return FALSE; + } + + IShellItem_GetDisplayName(ShellItem, SIGDN_FILESYSPATH, &ShellName); + StringCchCopy(DirectoryPath, DirectoryPathCch, ShellName); + CoTaskMemFree(ShellName); + IShellItem_Release(ShellItem); + + return TRUE; +} \ No newline at end of file diff --git a/KexGui/kexgui.c b/KexGui/kexgui.c new file mode 100644 index 0000000..010a800 --- /dev/null +++ b/KexGui/kexgui.c @@ -0,0 +1,24 @@ +#include "buildcfg.h" +#include + +#ifdef _DEBUG +KEXGDECLSPEC PCWSTR KexgApplicationFriendlyName = L"YOU MUST SET AN APPLICATION FRIENDLY NAME"; +#else +KEXGDECLSPEC PCWSTR KexgApplicationFriendlyName = L""; +#endif + +KEXGDECLSPEC HWND KexgApplicationMainWindow = NULL; + +#ifdef KEX_TARGET_TYPE_DLL +BOOL WINAPI DllMain( + IN HMODULE DllBase, + IN ULONG Reason, + IN PCONTEXT Context) +{ + if (Reason == DLL_PROCESS_ATTACH) { + DisableThreadLibraryCalls(DllBase); + } + + return TRUE; +} +#endif \ No newline at end of file diff --git a/KexGui/locale.c b/KexGui/locale.c new file mode 100644 index 0000000..1accd72 --- /dev/null +++ b/KexGui/locale.c @@ -0,0 +1,80 @@ +#include "buildcfg.h" +#include +#include +#include + +KEXGDECLSPEC LANGID KEXGAPI GetVxKexUserInterfaceLanguage( + VOID) +{ + HKEY VxKexUserKeyHandle; + STATIC LANGID CachedLangId = LANG_NEUTRAL; + LANGID LangId; + + if (CachedLangId != LANG_NEUTRAL) { + // Already figured out the language. + return CachedLangId; + } + + // + // First of all, check if user has overridden the language in the + // HKCU registry settings. The language override exists for two purposes: + // + // 1. User's language setting on the computer is equivalent to neither + // of the VxKex supported languages, but the user understands one + // of the supported languages better than English. + // + // 2. For developers to test in other languages without changing the + // global system language. + // + + VxKexUserKeyHandle = KxCfgOpenVxKexRegistryKey(TRUE, KEY_READ, NULL); + if (VxKexUserKeyHandle) { + ULONG ErrorCode; + ULONG RegistryLangId; + + ErrorCode = RegReadI32(VxKexUserKeyHandle, NULL, L"LanguageId", &RegistryLangId); + ASSERT (ErrorCode == ERROR_SUCCESS || ErrorCode == ERROR_FILE_NOT_FOUND); + + SafeClose(VxKexUserKeyHandle); + + if (ErrorCode != ERROR_SUCCESS || RegistryLangId == LANG_NEUTRAL) { + goto NoRegistryLanguageFound; + } + + if (RegistryLangId & ~0x3FF) { + // invalid + goto NoRegistryLanguageFound; + } + + LangId = PRIMARYLANGID((WORD) RegistryLangId); + } else { +NoRegistryLanguageFound: + + // + // No language override. Use user or system default. + // + + LangId = PRIMARYLANGID(GetUserDefaultUILanguage()); + + if (LangId == LANG_NEUTRAL) { + LangId = PRIMARYLANGID(GetSystemDefaultUILanguage()); + } + } + + ASSERT (LangId != LANG_NEUTRAL); + ASSERT ((LangId & ~0x3FF) == 0); + + switch (LangId) { + case LANG_ENGLISH: + case LANG_RUSSIAN: + // languages with primary support + return LangId; + case LANG_UKRAINIAN: + case LANG_BELARUSIAN: + // mutually intelligible - most ukrainians and belarusians understand + // russian better than english + return LANG_RUSSIAN; + default: + return LANG_ENGLISH; + } +} \ No newline at end of file diff --git a/KexGui/msgbox.c b/KexGui/msgbox.c new file mode 100644 index 0000000..8362a8d --- /dev/null +++ b/KexGui/msgbox.c @@ -0,0 +1,283 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// msgbox.c +// +// Abstract: +// +// Message box variadic functions. +// +// Author: +// +// vxiiduu (01-Oct-2022) +// +// Environment: +// +// Win32 +// +// Revision History: +// +// vxiiduu 01-Oct-2022 Initial creation. +// vxiiduu 03-Oct-2022 Convert message boxes to task dialogs +// vxiiduu 22-Feb-2024 Delete stub ReportAssertionFailure +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include +#include + +KEXGDECLSPEC EXTERN_C INT KEXGAPI MessageBoxV( + IN ULONG Buttons OPTIONAL, + IN PCWSTR Icon OPTIONAL, + IN PCWSTR WindowTitle OPTIONAL, + IN PCWSTR MessageTitle OPTIONAL, + IN PCWSTR Format, + IN va_list ArgList) +{ + INT ButtonPressed; + HRESULT Result; + SIZE_T BufferCch; + PWSTR Buffer; + TASKDIALOGCONFIG TaskDialogConfig; + + ASSERT (Format != NULL); + + Result = StringCchVPrintfBufferLength(&BufferCch, Format, ArgList); + ASSERT (SUCCEEDED(Result)); + + if (FAILED(Result)) { + return 0; + } + + Buffer = StackAlloc(WCHAR, BufferCch); + + Result = StringCchVPrintf(Buffer, BufferCch, Format, ArgList); + ASSERT (SUCCEEDED(Result)); + + if (FAILED(Result)) { + return 0; + } + + RtlZeroMemory(&TaskDialogConfig, sizeof(TaskDialogConfig)); + + TaskDialogConfig.cbSize = sizeof(TaskDialogConfig); + TaskDialogConfig.dwFlags = TDF_POSITION_RELATIVE_TO_WINDOW | TDF_ALLOW_DIALOG_CANCELLATION; + TaskDialogConfig.hwndParent = KexgApplicationMainWindow; + TaskDialogConfig.pszWindowTitle = WindowTitle; + TaskDialogConfig.pszMainInstruction = MessageTitle; + TaskDialogConfig.pszContent = Buffer; + TaskDialogConfig.dwCommonButtons = Buttons; + TaskDialogConfig.pszMainIcon = Icon; + + Result = TaskDialogIndirect( + &TaskDialogConfig, + &ButtonPressed, + NULL, + NULL); + + ASSERT (SUCCEEDED(Result)); + + return ButtonPressed; +} + +KEXGDECLSPEC EXTERN_C INT KEXGAPI MessageBoxF( + IN ULONG Buttons OPTIONAL, + IN PCWSTR Icon OPTIONAL, + IN PCWSTR WindowTitle OPTIONAL, + IN PCWSTR MessageTitle OPTIONAL, + IN PCWSTR Format, + IN ...) +{ + ARGLIST ArgList; + + va_start(ArgList, Format); + return MessageBoxV(Buttons, Icon, WindowTitle, MessageTitle, Format, ArgList); +} + +KEXGDECLSPEC NORETURN EXTERN_C VOID KEXGAPI CriticalErrorBoxF( + IN PCWSTR Format, + IN ...) +{ + ARGLIST ArgList; + va_start(ArgList, Format); + MessageBoxV(0, TD_ERROR_ICON, KexgApplicationFriendlyName, NULL, Format, ArgList); + ExitProcess(0); +} + +KEXGDECLSPEC EXTERN_C VOID KEXGAPI ErrorBoxF( + IN PCWSTR Format, + IN ...) +{ + ARGLIST ArgList; + va_start(ArgList, Format); + MessageBoxV(0, TD_ERROR_ICON, KexgApplicationFriendlyName, NULL, Format, ArgList); +} + +KEXGDECLSPEC EXTERN_C VOID KEXGAPI WarningBoxF( + IN PCWSTR Format, + IN ...) +{ + ARGLIST ArgList; + va_start(ArgList, Format); + MessageBoxV(0, TD_WARNING_ICON, KexgApplicationFriendlyName, NULL, Format, ArgList); +} + +KEXGDECLSPEC EXTERN_C VOID KEXGAPI InfoBoxF( + IN PCWSTR Format, + IN ...) +{ + ARGLIST ArgList; + va_start(ArgList, Format); + MessageBoxV(0, TD_INFORMATION_ICON, KexgApplicationFriendlyName, NULL, Format, ArgList); +} + +#ifdef ASSERTS_ENABLED +// +// Report TRUE if the caller should cause an exception, +// or FALSE otherwise. +// +KEXGDECLSPEC EXTERN_C BOOLEAN KEXGAPI ReportAssertionFailure( + IN PCWSTR SourceFile, + IN ULONG SourceLine, + IN PCWSTR SourceFunction, + IN PCWSTR AssertCondition) +{ + BOOLEAN Success; + HRESULT Result; + SIZE_T ExtraInfoBufferSize; + PWSTR ExtraInfoText; + HMODULE OriginatingModuleHandle; + WCHAR ModuleNameBuffer[MAX_PATH]; + ULONG ModuleNameLength; + TASKDIALOGCONFIG TaskDialogConfig; + TASKDIALOG_BUTTON ButtonArray[3]; + INT UserSelectedButton; + + PCWSTR ExtraInfoFormat = L"The condition '%s' failed at the following location:\r\n\r\n" + L"%s!%s (%s, line %lu)"; + + // + // No assertions to check the input of this function. + // It would be very ironic to enter an infinite loop with them. + // + + // + // Prepare the module base name to format. + // + + Success = GetModuleHandleEx( + GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | + GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + (PCWSTR) _ReturnAddress(), + &OriginatingModuleHandle); + + if (!Success) { + goto CannotGetModuleName; + } + + ModuleNameLength = GetModuleFileName( + OriginatingModuleHandle, + ModuleNameBuffer, + ARRAYSIZE(ModuleNameBuffer)); + + if (ModuleNameLength > 0) { + PathStripPath(ModuleNameBuffer); + PathRemoveExtension(ModuleNameBuffer); + PathMakePretty(ModuleNameBuffer); + goto GotModuleName; + } + +CannotGetModuleName: + StringCchCopy(ModuleNameBuffer, ARRAYSIZE(ModuleNameBuffer), L""); + +GotModuleName: + + // + // Format the text to be displayed to the user. + // This is displayed in the footer. + // + + Result = StringCchPrintfBufferLength( + &ExtraInfoBufferSize, + ExtraInfoFormat, + AssertCondition, + ModuleNameBuffer, + SourceFunction, + SourceFile, + SourceLine); + + if (FAILED(Result)) { + goto CannotFormatExtraInfoText; + } + + ExtraInfoText = StackAlloc(WCHAR, ExtraInfoBufferSize); + + Result = StringCchPrintf( + ExtraInfoText, + ExtraInfoBufferSize, + ExtraInfoFormat, + AssertCondition, + ModuleNameBuffer, + SourceFunction, + SourceFile, + SourceLine); + + if (SUCCEEDED(Result)) { + goto FormattedExtraInfoText; + } + +CannotFormatExtraInfoText: + ExtraInfoText = L"A secondary error occurred while processing this error."; + +FormattedExtraInfoText: + + // + // Display task dialog to the user and gather his response. + // + + ButtonArray[0].nButtonID = IDYES; + ButtonArray[1].nButtonID = IDRETRY; + ButtonArray[2].nButtonID = IDCLOSE; + ButtonArray[0].pszButtonText = L"&Break"; + ButtonArray[1].pszButtonText = L"&Continue"; + ButtonArray[2].pszButtonText = L"&Quit"; + + ZeroMemory(&TaskDialogConfig, sizeof(TaskDialogConfig)); + TaskDialogConfig.cbSize = sizeof(TaskDialogConfig); + TaskDialogConfig.hwndParent = KexgApplicationMainWindow; + TaskDialogConfig.dwFlags = TDF_EXPAND_FOOTER_AREA | + TDF_POSITION_RELATIVE_TO_WINDOW; + TaskDialogConfig.pszWindowTitle = KexgApplicationFriendlyName; + TaskDialogConfig.pszMainIcon = TD_ERROR_ICON; + TaskDialogConfig.pszMainInstruction = L"Assertion failure"; + TaskDialogConfig.pszContent = L"Select Break to enter the debugger, " + L"Continue to ignore the error, " + L"or Quit to exit the program."; + TaskDialogConfig.cButtons = ARRAYSIZE(ButtonArray); + TaskDialogConfig.pButtons = ButtonArray; + TaskDialogConfig.nDefaultButton = IDYES; + TaskDialogConfig.pszExpandedInformation = ExtraInfoText; + + Result = TaskDialogIndirect( + &TaskDialogConfig, + &UserSelectedButton, + NULL, + NULL); + + if (SUCCEEDED(Result)) { + if (UserSelectedButton == IDCLOSE) { + ExitProcess(0); + } else if (UserSelectedButton == IDYES) { + return TRUE; + } else if (UserSelectedButton == IDRETRY) { + return FALSE; + } + } + + // cause exception HERE if there was a problem + __debugbreak(); + return FALSE; +} +#endif // ifdef ASSERTS_ENABLED \ No newline at end of file diff --git a/KexGui/shprops.c b/KexGui/shprops.c new file mode 100644 index 0000000..fdec836 --- /dev/null +++ b/KexGui/shprops.c @@ -0,0 +1,44 @@ +#include "buildcfg.h" +#include +#include +#include +#include + +KEXGDECLSPEC BOOLEAN KEXGAPI ShowPropertiesDialog( + IN PCWSTR FilePath, + IN INT ShowControl) +{ + SHELLEXECUTEINFO ShellExecuteInfo; + + RtlZeroMemory(&ShellExecuteInfo, sizeof(ShellExecuteInfo)); + ShellExecuteInfo.cbSize = sizeof(ShellExecuteInfo); + ShellExecuteInfo.fMask = SEE_MASK_INVOKEIDLIST | SEE_MASK_NOASYNC | SEE_MASK_UNICODE; + ShellExecuteInfo.hwnd = KexgApplicationMainWindow; + ShellExecuteInfo.lpVerb = L"properties"; + ShellExecuteInfo.lpFile = FilePath; + ShellExecuteInfo.nShow = ShowControl; + + return ShellExecuteEx(&ShellExecuteInfo); +} + +KEXGDECLSPEC HRESULT KEXGAPI OpenFileLocation( + IN PCWSTR FilePath, + IN ULONG Flags) +{ + HRESULT Result; + PIDLIST_ABSOLUTE IDList; + ULONG SfgaoFlags; + + Result = SHParseDisplayName(FilePath, NULL, &IDList, 0, &SfgaoFlags); + if (FAILED(Result)) { + return Result; + } + + CoInitialize(NULL); + + Result = SHOpenFolderAndSelectItems(IDList, 0, NULL, Flags); + + CoUninitialize(); + + return Result; +} \ No newline at end of file diff --git a/KexGui/window.c b/KexGui/window.c new file mode 100644 index 0000000..b8b59d7 --- /dev/null +++ b/KexGui/window.c @@ -0,0 +1,177 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// window.c +// +// Abstract: +// +// Convenience functions for dealing with windows. +// +// Author: +// +// vxiiduu (01-Oct-2022) +// +// Environment: +// +// Win32 +// +// Revision History: +// +// vxiiduu 01-Oct-2022 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include +#include + +KEXGDECLSPEC EXTERN_C BOOLEAN KEXGAPI SetWindowTextF( + IN HWND Window, + IN PCWSTR Format, + IN ...) +{ + HRESULT Result; + SIZE_T BufferCch; + PWSTR Buffer; + ARGLIST ArgList; + + ASSERT (Window != NULL); + ASSERT (Format != NULL); + + va_start(ArgList, Format); + + Result = StringCchVPrintfBufferLength(&BufferCch, Format, ArgList); + ASSERT (SUCCEEDED(Result)); + + if (FAILED(Result)) { + return FALSE; + } + + Buffer = StackAlloc(WCHAR, BufferCch); + Result = StringCchVPrintf(Buffer, BufferCch, Format, ArgList); + ASSERT (SUCCEEDED(Result)); + + if (FAILED(Result)) { + return FALSE; + } + + return SetWindowText(Window, Buffer); +} + +KEXGDECLSPEC EXTERN_C BOOLEAN KEXGAPI SetDlgItemTextF( + IN HWND Window, + IN USHORT ItemId, + IN PCWSTR Format, + IN ...) +{ + HRESULT Result; + SIZE_T BufferCch; + PWSTR Buffer; + ARGLIST ArgList; + + ASSERT (Window != NULL); + ASSERT (Format != NULL); + + va_start(ArgList, Format); + + Result = StringCchVPrintfBufferLength(&BufferCch, Format, ArgList); + ASSERT (SUCCEEDED(Result)); + + if (FAILED(Result)) { + return FALSE; + } + + Buffer = StackAlloc(WCHAR, BufferCch); + Result = StringCchVPrintf(Buffer, BufferCch, Format, ArgList); + ASSERT (SUCCEEDED(Result)); + + if (FAILED(Result)) { + return FALSE; + } + + return SetDlgItemText(Window, ItemId, Buffer); +} + +KEXGDECLSPEC EXTERN_C VOID KEXGAPI SetWindowIcon( + IN HWND Window, + IN USHORT IconId) +{ + HMODULE CurrentModule; + HICON Icon; + + ASSERT (Window != NULL); + + CurrentModule = GetModuleHandle(NULL); + + Icon = (HICON) LoadImage( + CurrentModule, + MAKEINTRESOURCE(IconId), + IMAGE_ICON, + GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), + 0); + SendMessage(Window, WM_SETICON, ICON_SMALL, (LPARAM) Icon); + + Icon = (HICON) LoadImage( + CurrentModule, + MAKEINTRESOURCE(IconId), + IMAGE_ICON, + GetSystemMetrics(SM_CXICON), + GetSystemMetrics(SM_CYICON), + 0); + SendMessage(Window, WM_SETICON, ICON_BIG, (LPARAM) Icon); +} + +// +// Make Window centered on ParentWindow, or centered on the screen if +// ParentWindow is NULL. +// +KEXGDECLSPEC EXTERN_C VOID KEXGAPI CenterWindow( + IN HWND Window, + IN HWND ParentWindow OPTIONAL) +{ + RECT Rect; + RECT ParentRect; + RECT TemporaryRect; + + ASSERT (Window != NULL); + + if (!ParentWindow) { + ParentWindow = GetDesktopWindow(); + } + + GetWindowRect(ParentWindow, &ParentRect); + GetWindowRect(Window, &Rect); + CopyRect(&TemporaryRect, &ParentRect); + + OffsetRect(&Rect, -Rect.left, -Rect.top); + OffsetRect(&TemporaryRect, -TemporaryRect.left, -TemporaryRect.top); + OffsetRect(&TemporaryRect, -Rect.right, -Rect.bottom); + + SetWindowPos( + Window, + HWND_TOP, + ParentRect.left + (TemporaryRect.right / 2), + ParentRect.top + (TemporaryRect.bottom / 2), + 0, 0, + SWP_NOSIZE); +} + +KEXGDECLSPEC EXTERN_C VOID KEXGAPI BanishWindow( + IN HWND Window) +{ + ASSERT (Window != NULL); + + EnableWindow(Window, FALSE); + ShowWindow(Window, SW_HIDE); +} + +KEXGDECLSPEC EXTERN_C VOID KEXGAPI SummonWindow( + IN HWND Window) +{ + ASSERT (Window != NULL); + + ShowWindow(Window, SW_NORMAL); + EnableWindow(Window, TRUE); +} \ No newline at end of file diff --git a/KexGui/wndx.c b/KexGui/wndx.c new file mode 100644 index 0000000..16d7976 --- /dev/null +++ b/KexGui/wndx.c @@ -0,0 +1,167 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// wndx.c +// +// Abstract: +// +// Various miscellaneous convenience functions involving the creation +// of tooltips, menus, etc. +// +// Author: +// +// vxiiduu (01-Oct-2022) +// +// Environment: +// +// Win32 +// +// Revision History: +// +// vxiiduu 01-Oct-2022 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include +#include + +// +// Create a context menu at the specified screen coordinates. +// +// Returns the menu item identifier (resource ID) of the menu item which the +// user clicked. If the user got rid of the menu without clicking any items, +// the return value is 0. +// +// The DefaultMenuItem specifies a menu item ID which is bolded. Specify -1 if +// you do not want a bolded menu item. +// +KEXGDECLSPEC EXTERN_C ULONG KEXGAPI ContextMenuEx( + IN HWND Window, + IN USHORT MenuId, + IN PPOINT ClickPoint, + IN INT DefaultMenuItem) +{ + BOOLEAN MenuDropRightAligned; + HMENU Menu; + HMENU SubMenu; + ULONG Selection; + LONG MenuX; + LONG MenuY; + + if (ClickPoint->x >= 0 && ClickPoint->y >= 0) { + MenuX = ClickPoint->x; + MenuY = ClickPoint->y; + } else { // can happen if user uses menu key, or shift+f10 + RECT WindowRect; + + GetWindowRect(Window, &WindowRect); + MenuX = WindowRect.left; + MenuY = WindowRect.top; + } + + MenuDropRightAligned = GetSystemMetrics(SM_MENUDROPALIGNMENT); + Menu = LoadMenu(NULL, MAKEINTRESOURCE(MenuId)); + SubMenu = GetSubMenu(Menu, 0); + SetMenuDefaultItem(SubMenu, DefaultMenuItem, FALSE); + + Selection = TrackPopupMenu( + SubMenu, + TPM_NONOTIFY | TPM_RETURNCMD | (MenuDropRightAligned ? TPM_RIGHTALIGN | TPM_HORNEGANIMATION + : TPM_LEFTALIGN | TPM_HORPOSANIMATION), + MenuX, MenuY, + 0, + Window, + NULL); + + DestroyMenu(Menu); + return Selection; +} + +KEXGDECLSPEC EXTERN_C ULONG KEXGAPI ContextMenu( + IN HWND Window, + IN USHORT MenuId, + IN PPOINT ClickPoint) +{ + return ContextMenuEx(Window, MenuId, ClickPoint, -1); +} + +KEXGDECLSPEC EXTERN_C HWND KEXGAPI ToolTip( + IN HWND DialogWindow, + IN INT ToolId, + IN PWSTR Format, + IN ...) +{ + TOOLINFO ToolInfo; + HWND ToolWindow; + STATIC HWND ToolTipWindow = NULL; + + HRESULT Result; + SIZE_T BufferCch; + PWSTR Buffer; + ARGLIST ArgList; + + ASSERT (DialogWindow != NULL); + ASSERT (Format != NULL); + + ToolWindow = GetDlgItem(DialogWindow, ToolId); + ASSERT (ToolWindow != NULL); + + if (!ToolWindow) { + return NULL; + } + + // Create the tooltip if: + // 1. we haven't been called before + // 2. our old tooltip window was destroyed because + // the parent dialog window was closed + if (!ToolTipWindow || !IsWindow(ToolTipWindow)) { + ToolTipWindow = CreateWindowEx( + 0, TOOLTIPS_CLASS, NULL, + WS_POPUP | TTS_ALWAYSTIP, + CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, CW_USEDEFAULT, + DialogWindow, NULL, + NULL, NULL); + + if (!ToolTipWindow) { + return NULL; + } + + SendMessage(ToolTipWindow, TTM_SETMAXTIPWIDTH, 0, (LPARAM) 300); + SendMessage(ToolTipWindow, TTM_SETDELAYTIME, TTDT_AUTOPOP, 10000); + } + + // + // Format the message we are going to use for this tool-tip. + // + va_start(ArgList, Format); + Result = StringCchVPrintfBufferLength(&BufferCch, Format, ArgList); + + ASSERT (SUCCEEDED(Result)); + if (SUCCEEDED(Result)) { + Buffer = StackAlloc(WCHAR, BufferCch); + Result = StringCchVPrintf(Buffer, BufferCch, Format, ArgList); + + if (FAILED(Result)) { + // hopefully this is ok, better than no tooltip. + Buffer = Format; + } + } else { + Buffer = Format; + } + + // + // Associate the tooltip with the tool. + // + ZeroMemory(&ToolInfo, sizeof(ToolInfo)); + ToolInfo.cbSize = TTTOOLINFOW_V1_SIZE; // Win2k compat + ToolInfo.hwnd = DialogWindow; + ToolInfo.uFlags = TTF_IDISHWND | TTF_SUBCLASS; + ToolInfo.uId = (UINT_PTR) ToolWindow; + ToolInfo.lpszText = Buffer; + SendMessage(ToolTipWindow, TTM_ADDTOOL, 0, (LPARAM) &ToolInfo); + + return ToolTipWindow; +} \ No newline at end of file diff --git a/KexKMSD/KexKMSD.rc b/KexKMSD/KexKMSD.rc new file mode 100644 index 0000000..7ce7825 --- /dev/null +++ b/KexKMSD/KexKMSD.rc @@ -0,0 +1,32 @@ +#include "buildcfg.h" +#include +#include + +1 VERSIONINFO + FILEVERSION KEX_VERSION_FV + FILEOS VOS_NT +#if defined(KEX_TARGET_TYPE_EXE) + FILETYPE VFT_APP +#elif defined(KEX_TARGET_TYPE_DLL) + FILETYPE VFT_DLL +#elif defined(KEX_TARGET_TYPE_SYS) + FILETYPE VFT_DRV +#endif +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904B0" + BEGIN + VALUE "LegalCopyright", KEX_WEB_STR + VALUE "FileDescription", "VxKex Kernel-Mode Support Driver" + VALUE "FileVersion", KEX_VERSION_STR + VALUE "InternalName", KEX_COMPONENT + VALUE "OriginalFilename", "KEXKMSD.SYS" + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409 0x04B0 + END +END \ No newline at end of file diff --git a/KexKMSD/KexKMSD.vcxproj b/KexKMSD/KexKMSD.vcxproj new file mode 100644 index 0000000..2d09993 --- /dev/null +++ b/KexKMSD/KexKMSD.vcxproj @@ -0,0 +1,257 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {9F42E7FC-954C-4473-A9FC-F354CEC77393} + Win32Proj + KexKMSD + + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + + + + + + + + + + + + + + + + + false + .sys + false + + + false + .sys + false + + + false + .sys + false + + + false + .sys + false + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + Disabled + Size + false + false + false + Default + false + StdCall + CompileAsC + + + Native + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + Driver + + + true + + + + + + + $(SolutionDir)\00-Common Headers + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + Disabled + Size + false + false + false + Default + false + StdCall + CompileAsC + + + Native + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + Driver + + + true + + + + + + + $(SolutionDir)\00-Common Headers + + + + + Level3 + NotUsing + MinSpace + true + true + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + OnlyExplicitInline + Size + true + false + false + Default + false + StdCall + CompileAsC + + + Native + true + true + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + Driver + + + true + + + + + + + $(SolutionDir)\00-Common Headers + + + + + Level3 + NotUsing + MinSpace + true + true + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + OnlyExplicitInline + Size + true + false + false + Default + false + StdCall + CompileAsC + + + Native + true + true + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + Driver + + + true + + + + + + + $(SolutionDir)\00-Common Headers + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/KexKMSD/KexKMSD.vcxproj.filters b/KexKMSD/KexKMSD.vcxproj.filters new file mode 100644 index 0000000..5e89918 --- /dev/null +++ b/KexKMSD/KexKMSD.vcxproj.filters @@ -0,0 +1,32 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + Header Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/KexKMSD/buildcfg.h b/KexKMSD/buildcfg.h new file mode 100644 index 0000000..155abb6 --- /dev/null +++ b/KexKMSD/buildcfg.h @@ -0,0 +1,5 @@ +#pragma once + +#define KEX_COMPONENT L"KexKMSD" +#define KEX_TARGET_TYPE_SYS +#define KEX_ENV_NATIVE diff --git a/KexKMSD/drventry.c b/KexKMSD/drventry.c new file mode 100644 index 0000000..4691706 --- /dev/null +++ b/KexKMSD/drventry.c @@ -0,0 +1,23 @@ +#include "buildcfg.h" +#include + +VOID NTAPI DriverUnload( + IN PDRIVER_OBJECT DriverObject) +{ + ASSERT (DriverObject != NULL); + return; +} + +NTSTATUS NTAPI DriverEntry( + IN OUT PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath) +{ + ASSERT (DriverObject != NULL); + ASSERT (RegistryPath != NULL); + + KdPrint("DriverEntry called\r\n"); + + DriverObject->DriverUnload = DriverUnload; + + return STATUS_SUCCESS; +} \ No newline at end of file diff --git a/KexPathCch/KexPathCch.vcxproj b/KexPathCch/KexPathCch.vcxproj new file mode 100644 index 0000000..418e7e5 --- /dev/null +++ b/KexPathCch/KexPathCch.vcxproj @@ -0,0 +1,182 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + + + + + + + + {0B434F56-68C4-4627-BE2F-BE20A5E97F2D} + Win32Proj + KexPathCch + + + + StaticLibrary + true + Unicode + + + StaticLibrary + true + Unicode + + + StaticLibrary + false + true + Unicode + + + StaticLibrary + false + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + false + false + Default + false + StdCall + CompileAsC + + + Windows + true + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + false + false + Default + false + StdCall + CompileAsC + + + Windows + true + + + + + Level3 + + + MinSpace + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + false + false + Default + false + StdCall + CompileAsC + OnlyExplicitInline + Size + true + + + Windows + true + true + true + + + + + Level3 + + + MinSpace + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + false + false + Default + false + StdCall + CompileAsC + OnlyExplicitInline + Size + true + + + Windows + true + true + true + + + + + + \ No newline at end of file diff --git a/KexPathCch/KexPathCch.vcxproj.filters b/KexPathCch/KexPathCch.vcxproj.filters new file mode 100644 index 0000000..221b62e --- /dev/null +++ b/KexPathCch/KexPathCch.vcxproj.filters @@ -0,0 +1,30 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/KexPathCch/buildcfg.h b/KexPathCch/buildcfg.h new file mode 100644 index 0000000..845bdfe --- /dev/null +++ b/KexPathCch/buildcfg.h @@ -0,0 +1,3 @@ +#define WINPATHCCHAPI +#define KEX_TARGET_TYPE_LIB +#define KEX_COMPONENT L"KexPathCch" diff --git a/KexPathCch/pathcch.c b/KexPathCch/pathcch.c new file mode 100644 index 0000000..aae351c --- /dev/null +++ b/KexPathCch/pathcch.c @@ -0,0 +1,1186 @@ +#include "buildcfg.h" +#include +#include + +#define HRCHECKED(x) hr = (x); if (FAILED(hr)) goto Error + +// check if path begins with \\?\ prefix and has a drive letter and colon after it +STATIC BOOL IsExtendedLengthDosDevicePath( + IN PCWSTR lpszPath) +{ + if (StringBeginsWith(lpszPath, L"\\\\?\\") && isalpha(lpszPath[4]) && lpszPath[5] == ':') { + return TRUE; + } else { + return FALSE; + } +} + +STATIC BOOL IsDosDevicePath( + IN PCWSTR lpszPath) +{ + if (isalpha(lpszPath[0]) && lpszPath[1] == ':' && (lpszPath[2] == '\\' || lpszPath[2] == '\0')) { + return TRUE; + } else { + return FALSE; + } +} + +STATIC BOOL IsVolumeGuidPath( + IN PCWSTR lpszPath) +{ + if (StringBeginsWithI(lpszPath, L"\\\\?\\Volume{") && wcslen(&lpszPath[10]) >= 38) { + return TRUE; + } else { + return FALSE; + } +} + +STATIC BOOL IsPrefixedPath( + IN PCWSTR lpszPath) +{ + return StringBeginsWith(lpszPath, L"\\\\?\\"); +} + +STATIC BOOL IsPrefixedUncPath( + IN PCWSTR lpszPath) +{ + return StringBeginsWithI(lpszPath, L"\\\\?\\UNC\\"); +} + +STATIC BOOL IsFullyQualifiedPath( + IN PCWSTR lpszPath) +{ + return IsDosDevicePath(lpszPath) || StringBeginsWith(lpszPath, L"\\\\"); +} + +WINPATHCCHAPI HRESULT WINAPI PathAllocCanonicalize( + IN PCWSTR lpszPathIn, + IN DWORD dwFlags, + OUT PWSTR *ppszPathOut) +{ + PWSTR lpszPathOut = NULL; + SIZE_T cchPathIn; + SIZE_T cchAlloc; + BOOL bAllowLongPaths = dwFlags & PATHCCH_ALLOW_LONG_PATHS; + HRESULT hr; + + if (!ppszPathOut) { + return E_INVALIDARG; + } + + *ppszPathOut = NULL; + cchPathIn = wcslen(lpszPathIn); + + if (cchPathIn > PATHCCH_MAX_CCH) { + return PATHCCH_E_FILENAME_TOO_LONG; + } + + if (cchPathIn > 0) { + cchAlloc = cchPathIn + 1; + } else { + cchAlloc = 2; + } + + if (cchAlloc > MAX_PATH && bAllowLongPaths) { + // add space for \\?\ prefix + cchAlloc += 6; + } + + // limit maximum path length + if (cchAlloc > (bAllowLongPaths ? PATHCCH_MAX_CCH : MAX_PATH)) { + cchAlloc = (bAllowLongPaths ? PATHCCH_MAX_CCH : MAX_PATH); + } + + lpszPathOut = (PWSTR) LocalAlloc(LMEM_ZEROINIT, cchAlloc * sizeof(WCHAR)); + + if (!lpszPathOut) { + return E_OUTOFMEMORY; + } + + hr = PathCchCanonicalizeEx(lpszPathOut, cchAlloc, lpszPathIn, dwFlags); + + if (FAILED(hr)) { + LocalFree(lpszPathOut); + return hr; + } + + *ppszPathOut = lpszPathOut; + return S_OK; +} + +WINPATHCCHAPI HRESULT WINAPI PathAllocCombine( + IN PCWSTR lpszPathIn OPTIONAL, + IN PCWSTR lpszMore OPTIONAL, + IN DWORD dwFlags, + OUT PWSTR *ppszPathOut) +{ + SIZE_T cchPathIn = 0; + SIZE_T cchMore = 0; + SIZE_T cchPathOut; + PWSTR lpszPathOut; + BOOL bAllowLongPaths = dwFlags & PATHCCH_ALLOW_LONG_PATHS; + HRESULT hr; + + if (!ppszPathOut) { + return E_INVALIDARG; + } + + *ppszPathOut = NULL; + + if (lpszPathIn == NULL && lpszMore == NULL) { + return E_INVALIDARG; + } + + if (lpszPathIn) { + cchPathIn = wcslen(lpszPathIn); + + if (cchPathIn > 0) { + cchPathIn++; // add space for '\0' + } + + if (cchPathIn >= PATHCCH_MAX_CCH) { + return PATHCCH_E_FILENAME_TOO_LONG; + } + } + + if (lpszMore) { + cchMore = wcslen(lpszMore); + + if (cchMore > 0) { + cchMore++; + } + + if (cchMore >= PATHCCH_MAX_CCH) { + return PATHCCH_E_FILENAME_TOO_LONG; + } + } + + cchPathOut = cchMore + cchPathIn; + + if (cchPathOut == 0) { + cchPathOut = 2; // for backslash and null terminator + } else if (cchPathOut > (bAllowLongPaths ? PATHCCH_MAX_CCH : MAX_PATH)) { + cchPathOut = bAllowLongPaths ? PATHCCH_MAX_CCH : MAX_PATH; + } + + if (cchPathOut > MAX_PATH && bAllowLongPaths) { + cchPathOut += 6; // for \\?\ or \\?\UNC\ + } + + lpszPathOut = (PWSTR) LocalAlloc(LMEM_ZEROINIT, cchPathOut * sizeof(WCHAR)); + + if (!lpszPathOut) { + return E_OUTOFMEMORY; + } + + hr = PathCchCombineEx(lpszPathOut, cchPathOut, lpszPathIn, lpszMore, dwFlags); + + if (FAILED(hr)) { + LocalFree(lpszPathOut); + return hr; + } + + *ppszPathOut = lpszPathOut; + return S_OK; +} + +// ALL TESTS PASSED, DO NOT MODIFY +// +WINPATHCCHAPI HRESULT WINAPI PathCchAddBackslash( + IN OUT PWSTR lpszPath, + IN SIZE_T cchPath) +{ + return PathCchAddBackslashEx(lpszPath, cchPath, NULL, NULL); +} + +// ALL TESTS PASSED, DO NOT MODIFY +// +WINPATHCCHAPI HRESULT WINAPI PathCchAddBackslashEx( + IN OUT PWSTR lpszPath, + IN SIZE_T cchPath, + OUT PWSTR *ppszEnd OPTIONAL, + OUT PSIZE_T pcchRemaining OPTIONAL) +{ + PWSTR lpszEnd; + SIZE_T cchRemaining; + SIZE_T cchPathLength; + HRESULT hr; + + if (ppszEnd) { + *ppszEnd = NULL; + } + + if (pcchRemaining) { + *pcchRemaining = 0; + } + + hr = StringCchLength(lpszPath, cchPath, &cchPathLength); + + if (FAILED(hr)) { + return STRSAFE_E_INSUFFICIENT_BUFFER; + } + + cchRemaining = cchPath - cchPathLength; + lpszEnd = &lpszPath[cchPathLength]; + + if (cchPathLength != 0 && lpszEnd[-1] != '\\') { + hr = StringCchCopyEx(lpszEnd, cchRemaining, L"\\", &lpszEnd, &cchRemaining, STRSAFE_NO_TRUNCATION); + } else { + hr = S_FALSE; + } + + if (SUCCEEDED(hr)) { + if (ppszEnd) { + *ppszEnd = lpszEnd; + } + + if (pcchRemaining) { + *pcchRemaining = cchRemaining; + } + } + + return hr; +} + +// ALL TESTS PASSED, DO NOT MODIFY +// +WINPATHCCHAPI HRESULT WINAPI PathCchAddExtension( + IN OUT PWSTR lpszPath, + IN SIZE_T cchPath, + IN PCWSTR lpszExt) +{ + HRESULT hr; + PCWSTR lpszExistingExt; + BOOL bExtHasDot = FALSE; + SIZE_T cchExt; + + if (!lpszPath || !cchPath || !lpszExt || cchPath > PATHCCH_MAX_CCH) { + return E_INVALIDARG; + } + + // gather information about lpszExt + for (cchExt = 0; lpszExt[cchExt] != '\0'; cchExt++) { + switch (lpszExt[cchExt]) { + case '.': + if (cchExt == 0) { + bExtHasDot = TRUE; + continue; + } // if the dot isn't at the beginning, it's invalid - fall through + case ' ': + case '\\': + return E_INVALIDARG; + } + } + + // If lpszExt is empty, or has only a dot, return S_OK + if (cchExt == 0 || (cchExt == 1 && bExtHasDot)) { + return S_OK; + } + + hr = PathCchFindExtension(lpszPath, cchPath, &lpszExistingExt); + + if (FAILED(hr)) { + return hr; + } + + if (*lpszExistingExt != '\0') { + // there is already an extension + return S_FALSE; + } + + if (!bExtHasDot) { + hr = StringCchCatEx(lpszPath, cchPath, L".", &lpszPath, &cchPath, STRSAFE_NO_TRUNCATION); + + if (FAILED(hr)) { + return hr; + } + } + + return StringCchCatEx(lpszPath, cchPath, lpszExt, NULL, NULL, STRSAFE_NO_TRUNCATION); +} + +WINPATHCCHAPI HRESULT WINAPI PathCchAppend( + IN OUT PWSTR lpszPath, + IN SIZE_T cchPath, + IN PCWSTR lpszMore) +{ + return PathCchAppendEx(lpszPath, cchPath, lpszMore, 0); +} + +WINPATHCCHAPI HRESULT WINAPI PathCchAppendEx( + IN OUT PWSTR lpszPath, + IN SIZE_T cchPath, + IN PCWSTR lpszMore OPTIONAL, + IN DWORD dwFlags) +{ + HRESULT hr; + SIZE_T cchPathCopy; + PWSTR lpszPathCopy; + + if (!lpszPath) { + return E_INVALIDARG; + } + + if (lpszMore && !PathIsUNCEx(lpszMore, NULL) && !StringBeginsWith(lpszMore, L"\\\\?\\")) { + until (*lpszMore != '\\') { + lpszMore++; + } + } + + cchPathCopy = wcslen(lpszPath) + 1; + lpszPathCopy = StackAlloc(WCHAR, cchPathCopy); + + RtlCopyMemory(lpszPathCopy, lpszPath, cchPathCopy * sizeof(WCHAR)); + hr = PathCchCombineEx(lpszPath, cchPath, lpszPathCopy, lpszMore, dwFlags); + + return hr; +} + +WINPATHCCHAPI HRESULT WINAPI PathCchCanonicalize( + OUT PWSTR lpszPathOut, + IN SIZE_T cchPathOut, + IN PCWSTR lpszPathIn) +{ + return PathCchCanonicalizeEx(lpszPathOut, cchPathOut, lpszPathIn, PATHCCH_NONE); +} + +// Test results: +// NULL -> Access violation +// -> \ +// ..C\a\b -> ..C\a\b +// C -> C +// C\.. -> \ +// C\..\D:\a\b -> \D:\a\b (Failed) +// C: -> C:\ +// C:D -> C:D +// C:\ -> C:\ +// C:\\ -> C:\\ +// C:\\. -> C:\ +// C:\a\\.. -> C:\a\ +// C:\a\\.\ -> C:\a\\ +// C:\a\b\c\..\d -> C:\a\b\d +// \\?\ -> \\?\ +// \\?\C -> \\?\C +// \\?\C\..\D -> \\?\D +// \\?\C\..\D:\a\b -> \\?\D:\a\b +// \\?\C: -> C:\ +// \\?\C:\Windows\..\Program Files -> C:\Program Files +// \\?\Volume{00000000-0000-0000-0000-000000000000} -> \\?\Volume{00000000-0000-0000-0000-000000000000} +// \\?\Volume{00000000-0000-0000-0000-000000000000}\ -> \\?\Volume{00000000-0000-0000-0000-000000000000}\ +// \\?\Volume{00000000-0000-0000-0000-000000000000}\..\ -> \\?\Volume{00000000-0000-0000-0000-000000000000}\ +// \\?\Volume{Invalid0-0000-0000-0000-000000000000}\..\ -> \\?\ +// \\?\Volume{Invalid0-0000-0000-0000-000000000000}\.\ -> \\?\Volume{Invalid0-0000-0000-0000-000000000000}\ +// \\a\b\c\d\e\f -> \\a\b\c\d\e\f +// \\a\..\b\c\d\e\f -> \\b\c\d\e\f +// \\..\a\..\b\c\d\e\f -> \\b\c\d\e\f +// \\?\UNC\a\b\c\d -> \\a\b\c\d +// \\?\UNC\a\b\c\d\ -> \\a\b\c\d\ +// \\?\UNC\a\b\c\d\. -> \\a\b\c\d +// \\?\UNC\a\b\c\d\.\ -> \\a\b\c\d\ +// \\?\UNC\a\..\b\c\d -> \\b\c\d +WINPATHCCHAPI HRESULT WINAPI PathCchCanonicalizeEx( + OUT PWSTR lpszPathOut, + IN SIZE_T cchPathOut, + IN PCWSTR lpszPathIn, + IN DWORD dwFlags) +{ + PCWSTR lpszServer; + PWSTR lpszOriginalPathOut = lpszPathOut; + SIZE_T cchOriginalPathOut = cchPathOut; + SIZE_T cchPathIn; + BOOL bLongPathAllowed = (dwFlags & (PATHCCH_ALLOW_LONG_PATHS | PATHCCH_ENSURE_IS_EXTENDED_LENGTH_PATH)); + HRESULT hr; + + if (lpszPathOut == lpszPathIn) { + return E_INVALIDARG; + } + + HRCHECKED(StringCchCopy(lpszOriginalPathOut, cchOriginalPathOut, L"")); + + if (cchPathOut > PATHCCH_MAX_CCH) { + return E_INVALIDARG; + } + + cchPathIn = wcslen(lpszPathIn) + 1; + + if (cchPathIn > MAX_PATH) { + if (cchPathIn > PATHCCH_MAX_CCH || !bLongPathAllowed) { + return PATHCCH_E_FILENAME_TOO_LONG; + } + } + + if (!bLongPathAllowed && cchPathOut > MAX_PATH) { + // limit the number of written characters, if long paths aren't permitted + cchPathOut = MAX_PATH; + } + + // Basically there are 6 formatting cases that we handle: + // 1. Plain DOS-device path: C:\a\b\c (incl. stub such as "C:") + // 2. Extended DOS-device path: \\?\C:\a\b\c (incl. stub such as "\\?\C:") + // 3. Volume GUID path: \\?\Volume{guid}\a\b\c + // 4. Plain UNC path: \\server\share\a\b\c + // 5. Extended UNC path: \\?\UNC\server\share\a\b\c + // 6. None of the above + // In all cases except 5, we will strip away a beginning portion of the path as follows, + // to produce a "stripped path". (Not the same as what PathCchSkipRoot does): + // 1. Remove drive letter, colon and first backslash (if present) -> a\b\c + // 2. Remove \\?\ prefix and treat as (1) -> a\b\c + // 3. Remove volume GUID prefix and first backslash (if present) -> a\b\c + // 4. Remove \\ prefix -> server\share\a\b\c + // 5. Remove \\?\UNC prefix and first backslash (if present) -> server\share\a\b\c + + if (PathIsUNCEx(lpszPathIn, &lpszServer)) { + // This branch handles both plain and extended UNC paths. + lpszPathIn = lpszServer; + + if (bLongPathAllowed) { + HRCHECKED(StringCchCopyEx(lpszPathOut, cchPathOut, L"\\\\?\\UNC\\", &lpszPathOut, &cchPathOut, 0)); + } else { + HRCHECKED(StringCchCopyEx(lpszPathOut, cchPathOut, L"\\\\", &lpszPathOut, &cchPathOut, 0)); + } + } else if (IsVolumeGuidPath(lpszPathIn)) { + // Handles volume GUID paths. + HRCHECKED(StringCchCopyNEx(lpszPathOut, cchPathOut, lpszPathIn, 49, &lpszPathOut, &cchPathOut, 0)); + lpszPathIn += 48; + + if (*lpszPathIn != '\0') { + lpszPathIn++; + } + } else if (IsExtendedLengthDosDevicePath(lpszPathIn)) { + // Handles extended DOS-device paths. + lpszPathIn += 4; // skip past \\?\ prefix since we will decide whether to add it separately + goto HandleDosDevicePath; + } else if (IsDosDevicePath(lpszPathIn)) { + // Handles plain DOS-device paths. + WCHAR wcDriveLetter; + +HandleDosDevicePath: + wcDriveLetter = lpszPathIn[0]; + lpszPathIn += 2; + + if (*lpszPathIn != '\0') { + lpszPathIn++; + } + + if (bLongPathAllowed) { + HRCHECKED(StringCchPrintfEx(lpszPathOut, cchPathOut, &lpszPathOut, &cchPathOut, 0, L"\\\\?\\%wc:\\", wcDriveLetter)); + } else { + HRCHECKED(StringCchPrintfEx(lpszPathOut, cchPathOut, &lpszPathOut, &cchPathOut, 0, L"%wc:\\", wcDriveLetter)); + } + } + + // Handle the "stripped path". + while (*lpszPathIn != '\0') { + PCWSTR lpszNextSegment = wcschr(lpszPathIn, '\\'); + + if (!lpszNextSegment) { + // This means we are already at the last path segment. Fast forward until + // lpszSectionEnd points to the terminating null. + lpszNextSegment = lpszPathIn; + + until (*lpszNextSegment == '\0') { + lpszNextSegment++; + } + } else { + lpszNextSegment++; + } + + // if the current path segment is a . or .. then skip it + if (lpszPathIn[0] == '.') { + if (lpszPathIn[1] == '.') { + if (lpszPathIn[2] == '\\' || lpszPathIn[2] == '\0') { + lpszPathIn = lpszNextSegment; + continue; + } + } else { + if (lpszPathIn[1] == '\\' || lpszPathIn[1] == '\0') { + lpszPathIn = lpszNextSegment; + continue; + } + } + } + + // if the next path segment is a .. then skip the current one and the next one + if (lpszNextSegment[0] == '.') { + if (lpszNextSegment[1] == '.') { + if (lpszNextSegment[2] == '\\') { + lpszPathIn = lpszNextSegment + 3; + continue; + } else if (lpszNextSegment[2] == '\0') { + // remove the backslash from the output + if (lpszPathOut > lpszOriginalPathOut && lpszPathOut[-1] == '\\') { + lpszPathOut[-1] = '\0'; + } + + break; + } + } else if (lpszNextSegment[1] == '\0') { + // don't append backslash if next segment is \. and the path ends there + StringCchCopyNEx(lpszPathOut, cchPathOut, lpszPathIn, lpszNextSegment - lpszPathIn - 1, &lpszPathOut, &cchPathOut, 0); + break; + } + } + + // otherwise copy the current segment to output + StringCchCopyNEx(lpszPathOut, cchPathOut, lpszPathIn, lpszNextSegment - lpszPathIn, &lpszPathOut, &cchPathOut, 0); + lpszPathIn = lpszNextSegment; + } + + // Remove all trailing periods, unless preceded by a '*' character. + // In this case, retain 1 trailing period. + lpszPathOut--; + + if (lpszPathOut > lpszOriginalPathOut) { + until (*lpszPathOut != '.') { + lpszPathOut--; + } + + if (*lpszPathOut == '*') { + lpszPathOut += 2; + } else { + lpszPathOut += 1; + } + + *lpszPathOut = '\0'; + } + + // If output path is a root (e.g. "C:"), or if the caller specifies it, ensure it has a backslash at the end. + if ((lpszOriginalPathOut[0] && lpszOriginalPathOut[1] == ':' && lpszOriginalPathOut[2] == '\0') + || (dwFlags & PATHCCH_ENSURE_TRAILING_SLASH)) { + HRCHECKED(PathCchAddBackslash(lpszOriginalPathOut, cchOriginalPathOut)); + } else if (*lpszOriginalPathOut == '\0') { + // If the output path is empty, replace it with "\" + HRCHECKED(StringCchCopy(lpszOriginalPathOut, cchOriginalPathOut, L"\\")); + } + + return S_OK; + +Error: + StringCchCopy(lpszOriginalPathOut, cchOriginalPathOut, L""); + return hr; +} + +WINPATHCCHAPI HRESULT WINAPI PathCchCombine( + OUT PWSTR lpszPathOut, + IN SIZE_T cchPathOut, + IN PCWSTR lpszPathIn OPTIONAL, + IN PCWSTR lpszMore OPTIONAL) +{ + return PathCchCombineEx(lpszPathOut, cchPathOut, lpszPathIn, lpszMore, 0); +} + +WINPATHCCHAPI HRESULT WINAPI PathCchCombineEx( + OUT PWSTR lpszPathOut, + IN SIZE_T cchPathOut, + IN PCWSTR lpszPathIn OPTIONAL, + IN PCWSTR lpszMore OPTIONAL, + IN DWORD dwFlags) +{ + SIZE_T cchBuf = cchPathOut; + PWSTR lpszBuf = NULL; + HRESULT hr; + + if (!lpszPathOut || !cchPathOut || cchPathOut > PATHCCH_MAX_CCH) { + return E_INVALIDARG; + } + + if (!lpszPathIn && !lpszMore) { + HRCHECKED(E_INVALIDARG); + } + + if (lpszPathIn && wcslen(lpszPathIn) >= PATHCCH_MAX_CCH) { + HRCHECKED(PATHCCH_E_FILENAME_TOO_LONG); + } + + if (lpszMore && wcslen(lpszMore) >= PATHCCH_MAX_CCH) { + HRCHECKED(PATHCCH_E_FILENAME_TOO_LONG); + } + + // If lpszPathIn is a blank string or NULL, or if lpszMore is fully qualified, + // it is canonicalized directly to the output buffer without being combined. + if (!lpszPathIn || *lpszPathIn == '\0' || (lpszMore && IsFullyQualifiedPath(lpszMore))) { + if (lpszMore) { + return PathCchCanonicalizeEx(lpszPathOut, cchPathOut, lpszMore, dwFlags); + } + } + + // If lpszMore is a blank string or NULL, canonicalize lpszPathIn directly to the + // output buffer. + if (!lpszMore || *lpszMore == '\0') { + if (lpszPathIn) { + return PathCchCanonicalizeEx(lpszPathOut, cchPathOut, lpszPathIn, dwFlags); + } + } + + // If lpszMore begins with a backslash: + // - copy the root of lpszPathIn to temporary buffer + // - append lpszMore to temporary buffer + // - canonicalize temporary buffer to lpszPathOut + if (*lpszMore == '\\') { + PWSTR lpszPathInRootEnd; + HRCHECKED(PathCchSkipRoot(lpszPathIn, &lpszPathInRootEnd)); + + if (lpszPathInRootEnd > lpszPathIn) { + // lpszPathIn contains a root + + if (lpszPathInRootEnd[-1] == '\\') { + // ensure no backslash - since we know lpszMore already starts with one + lpszPathInRootEnd--; + } + + lpszBuf = (PWSTR) StackAlloc(WCHAR, cchBuf); + + HRCHECKED(StringCchCopyN(lpszBuf, cchBuf, lpszPathIn, lpszPathInRootEnd - lpszPathIn)); + HRCHECKED(StringCchCat(lpszBuf, cchBuf, lpszMore)); + HRCHECKED(PathCchCanonicalizeEx(lpszPathOut, cchPathOut, lpszBuf, dwFlags)); + + return S_OK; + } else { + // lpszPathIn does not contain a root + return PathCchCanonicalizeEx(lpszPathOut, cchPathOut, lpszMore, dwFlags); + } + } + + // Otherwise: + // - copy lpszPathIn to temporary buffer + // - add backslash (if not already present) + // - append lpszMore + // - canonicalize temporary buffer to lpszPathOut + { + lpszBuf = (PWSTR) StackAlloc(WCHAR, cchBuf); + + HRCHECKED(StringCchCopy(lpszBuf, cchBuf, lpszPathIn)); + HRCHECKED(PathCchAddBackslash(lpszBuf, cchBuf)); + HRCHECKED(StringCchCat(lpszBuf, cchBuf, lpszMore)); + HRCHECKED(PathCchCanonicalizeEx(lpszPathOut, cchPathOut, lpszBuf, dwFlags)); + } + + return S_OK; + +Error: + StringCchCopy(lpszPathOut, cchPathOut, L""); + return hr; +} + +// ALL TESTS PASSED, DO NOT MODIFY +// +WINPATHCCHAPI HRESULT WINAPI PathCchFindExtension( + IN PCWSTR lpszPath, + IN SIZE_T cchPath, + OUT PCWSTR *ppszExt) +{ + PCWSTR lpszEnd; + PCWSTR lpszTempExt; + + *ppszExt = NULL; + + if (!lpszPath || cchPath > PATHCCH_MAX_CCH) { + return E_INVALIDARG; + } + + lpszEnd = &lpszPath[cchPath]; + lpszTempExt = NULL; + + if (lpszPath >= lpszEnd) { + return E_INVALIDARG; + } + + do { + if (*lpszPath == '\0') { + break; + } + + if (*lpszPath == '.') { + lpszTempExt = lpszPath; + } else if (*lpszPath == '\\' || *lpszPath == ' ') { + lpszTempExt = NULL; + } + + lpszPath++; + } while (lpszPath < lpszEnd); + + if (lpszPath >= lpszEnd) { + return E_INVALIDARG; + } + + if (!lpszTempExt) { + // point the extension to the null-terminator at the end of the path + lpszTempExt = lpszPath; + } + + *ppszExt = lpszTempExt; + return S_OK; +} + +// ALL TESTS PASSED, DO NOT MODIFY +// +WINPATHCCHAPI BOOL WINAPI PathCchIsRoot( + IN PCWSTR lpszPath) +{ + PCWSTR lpszServer; + + if (!lpszPath || *lpszPath == '\0') { + return FALSE; + } + + if (lpszPath[0] == '\\' && lpszPath[1] == '\0') { + return TRUE; + } + + if (IsVolumeGuidPath(lpszPath)) { + if (lpszPath[48] == '\\' && lpszPath[49] == '\0') { + return TRUE; + } else { + return FALSE; + } + } + + if (IsExtendedLengthDosDevicePath(lpszPath)) { + lpszPath = &lpszPath[4]; + goto ProcessDosPath; + } + + if (PathIsUNCEx(lpszPath, &lpszServer)) { + // fast forward to either a) end of string, or b) a backslash + while (*lpszServer && *lpszServer != '\\') lpszServer++; + + if (lpszServer[0] == '\0') { + return TRUE; + } + + if (lpszServer[0] == '\\' && lpszServer[1] != '\0') { + while (*++lpszServer) { + if (*lpszServer == '\\') { + return FALSE; + } + } + + return TRUE; + } + } else { +ProcessDosPath: + if (isalpha(lpszPath[0]) && lpszPath[1] == ':' && lpszPath[2] == '\\' && lpszPath[3] == '\0') { + return TRUE; + } + } + + return FALSE; +} + +// ALL TESTS PASSED, DO NOT MODIFY +// +WINPATHCCHAPI HRESULT WINAPI PathCchRemoveBackslash( + IN OUT PWSTR lpszPath, + IN SIZE_T cchPath) +{ + return PathCchRemoveBackslashEx(lpszPath, cchPath, NULL, NULL); +} + +// ALL TESTS PASSED, DO NOT MODIFY +// +WINPATHCCHAPI HRESULT WINAPI PathCchRemoveBackslashEx( + IN OUT PWSTR lpszPath, + IN SIZE_T cchPath, + OUT PWSTR *ppszEnd OPTIONAL, + OUT PSIZE_T pcchRemaining OPTIONAL) +{ + HRESULT hr; + SIZE_T cch; + + hr = StringCchLength(lpszPath, cchPath, &cch); + + if (FAILED(hr)) { + goto Error; + } + + if (*lpszPath == '\0') { + if (ppszEnd) { + *ppszEnd = lpszPath; + } + + if (pcchRemaining) { + *pcchRemaining = cchPath; + } + + return S_FALSE; + } + + if (PathCchIsRoot(lpszPath)) { + if (lpszPath[cch - 1] != '\\') { + goto NoBackslash; + } + + if (ppszEnd) { + *ppszEnd = &lpszPath[cch - 1]; + } + + if (pcchRemaining) { + *pcchRemaining = cchPath - cch + 1; + } + + return S_FALSE; + } + + if (lpszPath[cch - 1] == '\\') { + lpszPath[cch - 1] = '\0'; + + if (ppszEnd) { + *ppszEnd = &lpszPath[cch - 1]; + } + + if (pcchRemaining) { + *pcchRemaining = cchPath - cch + 1; + } + + return S_OK; + } else { +NoBackslash: + if (ppszEnd) { + *ppszEnd = &lpszPath[cch]; + } + + if (pcchRemaining) { + *pcchRemaining = cchPath - cch; + } + + return S_FALSE; + } + +Error: + if (ppszEnd) { + *ppszEnd = NULL; + } + + if (pcchRemaining) { + *pcchRemaining = 0; + } + + return E_INVALIDARG; +} + +// ALL TESTS PASSED, DO NOT MODIFY +// +WINPATHCCHAPI HRESULT WINAPI PathCchRemoveExtension( + IN OUT PWSTR lpszPath, + IN SIZE_T cchPath) +{ + HRESULT hr; + PWSTR lpszExt; + + if (!lpszPath || cchPath > PATHCCH_MAX_CCH) { + return E_INVALIDARG; + } + + // Limit non-\\?\ paths to a maximum length of MAX_PATH + if (wcsncmp(lpszPath, L"\\\\?\\", 4) && cchPath > MAX_PATH) { + cchPath = MAX_PATH; + } + + hr = PathCchFindExtension(lpszPath, cchPath, &lpszExt); + + if (FAILED(hr)) { + return hr; + } + + if (*lpszExt != '\0') { + // extension was removed + *lpszExt = '\0'; + return S_OK; + } else { + // extension was not found and not removed + return S_FALSE; + } +} + +// ALL TESTS PASSED, DO NOT MODIFY +// +WINPATHCCHAPI HRESULT WINAPI PathCchRemoveFileSpec( + IN OUT PWSTR lpszPath, + IN SIZE_T cchPath) +{ + PCWSTR lpszPathBufEnd; + PWSTR lpszPtr; + PWSTR lpszBackslash; + PWSTR lpszRootEnd; + PWSTR lpszPathOriginal = lpszPath; + HRESULT hr; + + if (!lpszPath || cchPath > PATHCCH_MAX_CCH) { + return E_INVALIDARG; + } + + hr = PathCchSkipRoot(lpszPath, &lpszRootEnd); + + // if path has a root, skip past it + if (SUCCEEDED(hr)) { + lpszPath = lpszRootEnd; + } + + lpszPathBufEnd = &lpszPath[cchPath]; + + if (lpszPath >= lpszPathBufEnd) { + return E_INVALIDARG; + } + + for (lpszPtr = lpszPath;; lpszPtr = lpszBackslash + 1) { + lpszBackslash = wcschr(lpszPtr, '\\'); + + if (!lpszBackslash) { + break; + } + + lpszPath = lpszBackslash; + + if (lpszBackslash >= lpszPathBufEnd) { + return E_INVALIDARG; + } + } + + if (*lpszPath != '\0') { + *lpszPath = '\0'; + hr = PathCchRemoveBackslash(lpszPathOriginal, cchPath); + + if (FAILED(hr)) { + return hr; + } + + return S_OK; + } else { + return PathCchRemoveBackslash(lpszPathOriginal, cchPath); + } +} + +// ALL TESTS PASSED, DO NOT MODIFY +// +WINPATHCCHAPI HRESULT WINAPI PathCchRenameExtension( + IN OUT PWSTR lpszPath, + IN SIZE_T cchPath, + IN PCWSTR lpszExt) +{ + HRESULT hr; + + hr = PathCchRemoveExtension(lpszPath, cchPath); + if (FAILED(hr)) return hr; + + hr = PathCchAddExtension(lpszPath, cchPath, lpszExt); + if (FAILED(hr)) return hr; + + return S_OK; +} + +// ALL TESTS PASSED, DO NOT MODIFY +// +// Examples: +// C:\Windows -> S_OK, Windows +// C:\ -> S_OK, +// C: -> S_OK, +// C -> E_INVALIDARG, NULL +// -> E_INVALIDARG, NULL +// \ -> S_OK, +// \whatever -> S_OK, whatever +// \\whatever -> S_OK, +// \\\whatever -> S_OK, +// \\\s1\s2\s3 -> S_OK, s2\s3 +// \\server\share -> S_OK, +// \\server\share\1\2\3 -> S_OK, 1\2\3 +// \\?\C:\Windows -> S_OK, Windows +// \\?\C -> E_INVALIDARG, NULL +// \\?\UNC -> E_INVALIDARG, NULL +// \\?\UNC\ -> S_OK, +// \\?\UNC\server\share -> S_OK, +// \\?\UNC\server\share\1\2 -> S_OK, 1\2 +// \\garbage\C:\Windows -> S_OK, Windows +// \\s1\s2\C:\Windows -> S_OK, C:\Windows +// \\s1\s2\s3\C:\Windows -> S_OK, s3\C:\Windows +// +WINPATHCCHAPI HRESULT WINAPI PathCchSkipRoot( + IN PCWSTR lpszPath, + OUT PCWSTR *ppszRootEnd) +{ + if (!lpszPath || !ppszRootEnd) { + return E_INVALIDARG; + } + + if (lpszPath[0] == '\\') { + if (lpszPath[1] == '\\') { + if (lpszPath[2] == '?') { + if (lpszPath[3] == '\\') { + // there are three possibilities here + // either the following characters are "UNC\" (in which case we will process + // the remaining string as a \\server\share\... path) + // or the following characters are "Volume{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}" + // or we will simply process the string after \\?\ as a normal DOS-style path + if (StringBeginsWithI(&lpszPath[4], L"UNC\\")) { + lpszPath = &lpszPath[8]; + goto ProcessServerSharePath; + } else if (StringBeginsWithI(&lpszPath[4], L"Volume{") && wcslen(&lpszPath[10]) >= 38) { + if (lpszPath[48] == '\\') { + *ppszRootEnd = &lpszPath[49]; + } else { + *ppszRootEnd = &lpszPath[48]; + } + + return S_OK; + } else { + lpszPath = &lpszPath[4]; + goto ProcessDosPath; + } + } + } else { + // consume up to two more backslashes and then return the string after that + SIZE_T i; + INT nBackslashes; + lpszPath += 2; + +ProcessServerSharePath: + i = 0; + nBackslashes = 0; + + while (lpszPath[i] != '\0') { + if (lpszPath[i++] == '\\') { + if (++nBackslashes == 2) { + break; + } + + if (nBackslashes == 1 && lpszPath[i] == '\\') { + // Apparently we're not supposed to skip over the "share" part of the + // UNC path if it's empty. Dunno why but Windows 10 does it. + break; + } + } + } + + *ppszRootEnd = &lpszPath[i]; + return S_OK; + } + } else { + // simply return the string after the first backslash + *ppszRootEnd = &lpszPath[1]; + return S_OK; + } + } else { +ProcessDosPath: + // the path must begin with a single [a-zA-Z] char, immediately followed by a colon ':' + if (isalpha(lpszPath[0]) && lpszPath[1] == ':') { + if (lpszPath[2] == '\\') { + // if there is a backslash immediately after the colon, + // return the string directly after it. + // Note: this rule does not apply to forward slashes, since + // it isn't like that in Win10. Maybe it's a bug. + *ppszRootEnd = &lpszPath[3]; + } else { + // otherwise, return the string directly after the colon + *ppszRootEnd = &lpszPath[2]; + } + + return S_OK; + } + } + + *ppszRootEnd = NULL; + return E_INVALIDARG; +} + +// ALL TESTS PASSED, DO NOT MODIFY +// +WINPATHCCHAPI HRESULT WINAPI PathCchStripPrefix( + IN OUT PWSTR lpszPath, + IN SIZE_T cchPath) +{ + HRESULT hr; + + if (!lpszPath || !cchPath || cchPath > PATHCCH_MAX_CCH) { + return E_INVALIDARG; + } + + if (IsExtendedLengthDosDevicePath(lpszPath)) { + hr = StringCchCopyW(lpszPath, cchPath, &lpszPath[4]); + } else if (IsPrefixedUncPath(lpszPath)) { + hr = StringCchCopyW(&lpszPath[2], cchPath - 2, &lpszPath[8]); + } else { + return S_FALSE; + } + + if (SUCCEEDED(hr)) { + return S_OK; + } else { + return E_INVALIDARG; + } +} + +// ALL TESTS PASSED, DO NOT MODIFY +// +WINPATHCCHAPI HRESULT WINAPI PathCchStripToRoot( + IN OUT PWSTR lpszPath, + IN SIZE_T cchPath) +{ + PWSTR lpszAfterRoot; + PWSTR lpszServerPart; + HRESULT hr; + + if (!lpszPath || !cchPath || cchPath > PATHCCH_MAX_CCH) { + return E_INVALIDARG; + } + + hr = PathCchSkipRoot(lpszPath, &lpszAfterRoot); + + if (FAILED(hr)) { + return hr; + } + + if (lpszAfterRoot >= &lpszPath[cchPath]) { + return E_INVALIDARG; + } + + if (PathIsUNCEx(lpszPath, &lpszServerPart) && *lpszServerPart && lpszAfterRoot[-1] == '\\') { + lpszAfterRoot[-1] = '\0'; + } else if (lpszAfterRoot[0] != '\0') { + lpszAfterRoot[0] = '\0'; + } else { + return S_FALSE; + } + + return S_OK; +} + +// ALL TESTS PASSED, DO NOT MODIFY +// +// Examples taken from testing on a Windows 10 system: +// C:\Windows -> FALSE, NULL +// \\server\share\whatever -> TRUE, server\share\whatever +// \\?\C:\Users -> FALSE, NULL +// \\?\UNC -> FALSE, NULL +// \\?\UNC\ -> FALSE, +// \\?\UNC\Whatever -> TRUE, Whatever +// \\.\UNC\Whatever -> TRUE, .\UNC\Whatever +WINPATHCCHAPI BOOL WINAPI PathIsUNCEx( + IN PCWSTR lpszPath, + OUT PCWSTR *ppszServer OPTIONAL) +{ + // Windows 10 does not check whether lpszPath is NULL. + // If it is, we will simply AV. "Not my problem" + + if (lpszPath[0] == '\\' && lpszPath[1] == '\\') { + if (lpszPath[2] == '?') { + if (StringBeginsWithI(&lpszPath[3], L"\\UNC\\")) { + if (ppszServer) { + *ppszServer = &lpszPath[8]; + } + + return TRUE; + } + } else { + if (ppszServer) { + *ppszServer = &lpszPath[2]; + } + + return TRUE; + } + } + + if (ppszServer) { + *ppszServer = NULL; + } + + return FALSE; +} \ No newline at end of file diff --git a/KexSetup/KexSetup.ico b/KexSetup/KexSetup.ico new file mode 100644 index 0000000..632518d Binary files /dev/null and b/KexSetup/KexSetup.ico differ diff --git a/KexSetup/KexSetup.manifest b/KexSetup/KexSetup.manifest new file mode 100644 index 0000000..751cc1c --- /dev/null +++ b/KexSetup/KexSetup.manifest @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/KexSetup/KexSetup.rc b/KexSetup/KexSetup.rc new file mode 100644 index 0000000..c24ebe3 Binary files /dev/null and b/KexSetup/KexSetup.rc differ diff --git a/KexSetup/KexSetup.vcxproj b/KexSetup/KexSetup.vcxproj new file mode 100644 index 0000000..ef573f6 --- /dev/null +++ b/KexSetup/KexSetup.vcxproj @@ -0,0 +1,191 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {F435A5D6-D589-41FA-8430-90C37401DE17} + Win32Proj + KexSetup + + + + Application + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + false + Build + false + false + + + false + Build + false + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + true + true + false + false + Default + false + StdCall + CompileAsC + ProgramDatabase + + + Windows + true + EntryPoint + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + + + $(SolutionDir)\00-Common Headers;$(SolutionDir) + _DEBUG;_UNICODE;UNICODE;%(PreprocessorDefinitions) + + + "$(SolutionDir)\01-Development Utilities\7zSfx\makesfx.bat" /$(Configuration) + Building Self-Extracting Executable (SFX) + $(SolutionDir)\KexSetup_$(Configuration).exe + "$(SolutionDir)\01-Development Utilities\7zSfx\makesfx.bat";$(SolutionDir)\00-Documentation\Changelog.txt + + + + + + + + + + + + + + + + + true + KexSetup.manifest + + + + + Level3 + + + MinSpace + true + true + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + true + true + false + false + Default + false + StdCall + CompileAsC + ProgramDatabase + OnlyExplicitInline + Size + true + + + Windows + true + true + true + EntryPoint + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + + + $(SolutionDir)\00-Common Headers;$(SolutionDir) + _UNICODE;UNICODE;%(PreprocessorDefinitions) + + + "$(SolutionDir)\01-Development Utilities\7zSfx\makesfx.bat" /$(Configuration) + Building Self-Extracting Executable (SFX) + $(SolutionDir)\KexSetup_$(Configuration).exe + "$(SolutionDir)\01-Development Utilities\7zSfx\makesfx.bat" + + + + + + + + + + + + + + + + + true + KexSetup.manifest + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/KexSetup/KexSetup.vcxproj.filters b/KexSetup/KexSetup.vcxproj.filters new file mode 100644 index 0000000..cb09142 --- /dev/null +++ b/KexSetup/KexSetup.vcxproj.filters @@ -0,0 +1,56 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/KexSetup/buildcfg.h b/KexSetup/buildcfg.h new file mode 100644 index 0000000..6e993df --- /dev/null +++ b/KexSetup/buildcfg.h @@ -0,0 +1,6 @@ +#pragma once + +#define FRIENDLYAPPNAME L"VxKex Installer" +#define KEX_COMPONENT L"KexSetup" +#define KEX_ENV_WIN32 +#define KEX_TARGET_TYPE_EXE diff --git a/KexSetup/cmdline.c b/KexSetup/cmdline.c new file mode 100644 index 0000000..b5bfb66 --- /dev/null +++ b/KexSetup/cmdline.c @@ -0,0 +1,221 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// cmdline.c +// +// Abstract: +// +// Contains functions related to parsing the command-line arguments of the +// installer program. +// +// Author: +// +// vxiiduu (01-Feb-2024) +// +// Environment: +// +// Win32, without any vxkex support components +// +// Revision History: +// +// vxiiduu 01-Feb-2024 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "kexsetup.h" + +VOID DisplayHelpMessage( + VOID) +{ + MessageBox( + NULL, + L"KexSetup takes the following command-line parameters:\r\n" + L"\r\n" + L"/HELP or /? - Display this help message\r\n" + L"/UNINSTALL - Start the setup application in uninstall mode\r\n" + L"/PRESERVECONFIG - Keep your settings when uninstalling\r\n" + L"/SILENTUNATTEND - Enable silent unattended mode\r\n" + L"\r\n" + L"Silent unattended mode does not display a GUI and does not prompt for user input. " + L"In this mode, the setup application will immediately perform the requested action. " + L"If /UNINSTALL is not specified then the default action is to install the software. " + L"The following flag may be useful in silent unattend mode:\r\n\r\n" + L"/KEXDIR:\"\" - Specifies the path to which VxKex will be installed. " + L"You must use quotes around the directory path if it contains space characters.", + FRIENDLYAPPNAME, + MB_OK); +} + +VOID ProcessCommandLineOptions( + VOID) +{ + PWSTR CommandLine; + PWSTR CommandLineBuffer; + PCWSTR ParentProcessHwnd; + ULONG CommandLineBufferCch; + ULONG Index; + + // + // Make a copy of the process command line. We will modify it in this function, + // and we don't want to clobber the original since we may need to use it again + // later on. + // + + CommandLine = GetCommandLineWithoutImageName(); + CommandLineBufferCch = wcslen(CommandLine) + 1; + CommandLineBuffer = StackAlloc(WCHAR, CommandLineBufferCch); + CopyMemory(CommandLineBuffer, CommandLine, CommandLineBufferCch * sizeof(WCHAR)); + CommandLine = CommandLineBuffer; + + if (StringSearchI(CommandLine, L"/HELP") || StringSearch(CommandLine, L"/?")) { + DisplayHelpMessage(); + ExitProcess(0); + } + + if (StringSearchI(CommandLine, L"/SILENTUNATTEND")) { + SilentUnattended = TRUE; + } else { + SilentUnattended = FALSE; + } + + if (StringSearchI(CommandLine, L"/PRESERVECONFIG")) { + PreserveConfig = TRUE; + } else { + PreserveConfig = FALSE; + } + + ParentProcessHwnd = StringFindI(CommandLine, L"/HWND:"); + + if (ParentProcessHwnd) { + HWND Window; + + if (!SilentUnattended) { + ErrorBoxF(L"/HWND cannot be used without /SILENTUNATTEND."); + ExitProcess(STATUS_INVALID_PARAMETER_MIX); + } + + ParentProcessHwnd += StringLiteralLength(L"/HWND:"); + Window = NULL; + swscanf_s(ParentProcessHwnd, L"%u", &Window); + + if (IsWindow(Window)) { + MainWindow = Window; + KexgApplicationMainWindow = MainWindow; + } else { + ErrorBoxF(L"Invalid window handle passed to /HWND."); + ExitProcess(STATUS_INVALID_PARAMETER); + } + } + + if (StringSearchI(CommandLine, L"/UNINSTALL")) { + if (ExistingVxKexVersion > InstallerVxKexVersion) { + InfoBoxF( + L"A version of VxKex is installed on your computer that is " + L"newer than the version inside this installer. If you would like " + L"to uninstall, use a newer version of the setup application."); + ExitProcess(STATUS_VERSION_MISMATCH); + } + + OperationMode = OperationModeUninstall; + } else { + if (PreserveConfig) { + ErrorBoxF(L"/PRESERVECONFIG cannot be used without /UNINSTALL."); + ExitProcess(STATUS_INVALID_PARAMETER_MIX); + } + + if (ExistingVxKexVersion == 0) { + OperationMode = OperationModeInstall; + } else if (InstallerVxKexVersion > ExistingVxKexVersion) { + OperationMode = OperationModeUpgrade; + } else if (InstallerVxKexVersion == ExistingVxKexVersion) { + InfoBoxF(L"VxKex is already installed. To uninstall, use the Add/Remove Programs control panel."); + ExitProcess(STATUS_ALREADY_REGISTERED); + } else if (ExistingVxKexVersion > InstallerVxKexVersion) { + InfoBoxF( + L"A version of VxKex is installed on your computer that is " + L"newer than the version inside this installer. If you would " + L"like to downgrade, please uninstall the existing version first."); + ExitProcess(STATUS_VERSION_MISMATCH); + } else { + NOT_REACHED; + } + } + + if (OperationMode == OperationModeInstall) { + PWSTR RequestedInstallationPath; + WCHAR RequestedInstallationPathExpandedEnvironmentStrings[MAX_PATH]; + + RequestedInstallationPath = (PWSTR) StringFindI(CommandLine, L"/KEXDIR:"); + + if (RequestedInstallationPath) { + Index = 0; + RequestedInstallationPath += StringLiteralLength(L"/KEXDIR:"); + + if (RequestedInstallationPath[0] == '"') { + // + // We have a quoted path. Scan ahead until the closing quote. + // + + ++RequestedInstallationPath; + + until (RequestedInstallationPath[Index] == '"' || + RequestedInstallationPath[Index] == '\0') { + ++Index; + } + + if (RequestedInstallationPath[Index] == '"') { + RequestedInstallationPath[Index] = '\0'; + } else { + ErrorBoxF(L"Invalid quoted path argument to /KEXDIR."); + ExitProcess(STATUS_INVALID_PARAMETER); + } + } else { + // + // Unquoted path. Scan ahead until the next space character, + // quote character, or the end of the command line arguments. + // + + until (RequestedInstallationPath[Index] == ' ' || + RequestedInstallationPath[Index] == '"' || + RequestedInstallationPath[Index] == '\0') { + ++Index; + } + + RequestedInstallationPath[Index] = '\0'; + } + + // + // Perform some validation and processing on the requested installation location + // before copying it into the KexDir global variable. + // + + if (PathIsRelative(RequestedInstallationPath)) { + ErrorBoxF(L"The argument to /KEXDIR must be an absolute path."); + ExitProcess(STATUS_INVALID_PARAMETER); + } + + ExpandEnvironmentStrings( + RequestedInstallationPath, + RequestedInstallationPathExpandedEnvironmentStrings, + ARRAYSIZE(RequestedInstallationPathExpandedEnvironmentStrings)); + + RequestedInstallationPath = RequestedInstallationPathExpandedEnvironmentStrings; + PathCchRemoveBackslash(RequestedInstallationPath, ARRAYSIZE(RequestedInstallationPath)); + PathRemoveBlanks(RequestedInstallationPath); + PathCchCanonicalize(KexDir, ARRAYSIZE(KexDir), RequestedInstallationPath); + } + } else { + if (StringSearchI(CommandLine, L"/KEXDIR")) { + if (OperationMode == OperationModeUpgrade) { + ErrorBoxF(L"/KEXDIR cannot be used because VxKex is already installed."); + ExitProcess(STATUS_ALREADY_REGISTERED); + } else if (OperationMode == OperationModeUninstall) { + ErrorBoxF(L"/KEXDIR cannot be combined with /UNINSTALL."); + ExitProcess(STATUS_INVALID_PARAMETER_MIX); + } else { + NOT_REACHED; + } + } + } +} \ No newline at end of file diff --git a/KexSetup/gui.c b/KexSetup/gui.c new file mode 100644 index 0000000..3bc1bb9 --- /dev/null +++ b/KexSetup/gui.c @@ -0,0 +1,615 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// gui.c +// +// Abstract: +// +// This file contains functions which deal with the user interface (i.e. +// gathering information interactively from the user). +// +// Author: +// +// vxiiduu (02-Feb-2024) +// +// Environment: +// +// Win32, without any vxkex support components +// +// Revision History: +// +// vxiiduu 02-Feb-2024 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "kexsetup.h" +#include + +HWND MainWindow = NULL; +ULONG CurrentScene; +HANDLE ElevatedProcess = NULL; + +#define SCENE_SELECT_INSTALLATION_DIR 1 +#define SCENE_INSTALLING 2 +#define SCENE_INSTALLATION_COMPLETE 3 + +#define SCENE_UNINSTALL_CONFIRM 4 +#define SCENE_UNINSTALLING 5 +#define SCENE_UNINSTALLATION_COMPLETE 6 + +#define SCENE_UPDATE_CHANGELOG 7 +#define SCENE_UPDATING 8 +#define SCENE_UPDATE_COMPLETE 9 + +BOOLEAN HideAndDisableControl( + IN USHORT ControlId) +{ + HWND Window; + + ASSERT (IsWindow(MainWindow)); + + Window = GetDlgItem(MainWindow, ControlId); + + if (!Window) { + return FALSE; + } + + ShowWindow(Window, SW_HIDE); + EnableWindow(Window, FALSE); + return TRUE; +} + +BOOLEAN ShowAndEnableControl( + IN USHORT ControlId) +{ + HWND Window; + + ASSERT (IsWindow(MainWindow)); + + Window = GetDlgItem(MainWindow, ControlId); + + if (!Window) { + return FALSE; + } + + ShowWindow(Window, SW_NORMAL); + EnableWindow(Window, TRUE); + return TRUE; +} + +VOID UpdateDiskFreeSpace( + VOID) +{ + HWND StaticControlWindow; + WCHAR InstallationDir[MAX_PATH]; + WCHAR InstallationVolume[MAX_PATH]; + WCHAR FormattedSize[16]; + WCHAR LabelText[22 + ARRAYSIZE(FormattedSize)] = L"Disk space available: "; + ULARGE_INTEGER uliFreeSpace; + + StaticControlWindow = GetDlgItem(MainWindow, IDS1SPACEAVAIL); + GetDlgItemText(MainWindow, IDS1DIRPATH, InstallationDir, ARRAYSIZE(InstallationDir)); + GetVolumePathName(InstallationDir, InstallationVolume, ARRAYSIZE(InstallationVolume)); + + if (GetDiskFreeSpaceEx(InstallationVolume, &uliFreeSpace, NULL, NULL)) { + if (StrFormatByteSize(uliFreeSpace.QuadPart, FormattedSize, ARRAYSIZE(FormattedSize))) { + StringCchCat(LabelText, ARRAYSIZE(LabelText), FormattedSize); + SetDlgItemText(MainWindow, IDS1SPACEAVAIL, LabelText); + return; + } + } + + // dont display anything if the directory is invalid + SetDlgItemText(MainWindow, IDS1SPACEAVAIL, L""); +} + +// +// This function is pretty craptacular and only works well for small stuff +// because it doesn't handle errors or large files effectively. +// Hence why it's only used here and not put into KexW32ML. +// Also probably chews a shitload of stack - not so great. +// +ULONG GetDirectorySize( + IN PCWSTR DirectoryPath) +{ + ULONG DirectorySize; + PWSTR FindSpec; + ULONG FindSpecCch; + HANDLE FindHandle; + WIN32_FIND_DATA FindData; + + ASSERT (DirectoryPath != NULL); + ASSERT (DirectoryPath[0] != '\0'); + + DirectorySize = 0; + FindSpec = StackAlloc(WCHAR, wcslen(DirectoryPath) + 2 + 1); + FindSpecCch = (ULONG) wcslen(DirectoryPath) + 2 + 1; + StringCchPrintf(FindSpec, FindSpecCch, L"%s\\*", DirectoryPath); + + FindHandle = FindFirstFileEx( + FindSpec, + FindExInfoBasic, + &FindData, + FindExSearchNameMatch, + NULL, + FIND_FIRST_EX_LARGE_FETCH); + + if (FindHandle == INVALID_HANDLE_VALUE) { + return -1; + } + + do { + // skip . and .. + if (FindData.cFileName[0] == '.') { + if (FindData.cFileName[1] == '.' && FindData.cFileName[2] == '\0') { + continue; + } + + if (FindData.cFileName[1] == '\0') { + continue; + } + } + + if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + WCHAR SubDirPath[MAX_PATH]; + + // recurse + StringCchCopy(SubDirPath, ARRAYSIZE(SubDirPath), DirectoryPath); + PathCchAppend(SubDirPath, ARRAYSIZE(SubDirPath), FindData.cFileName); + DirectorySize += GetDirectorySize(SubDirPath); + + continue; + } + + DirectorySize += FindData.nFileSizeLow; + } until (!FindNextFile(FindHandle, &FindData) && GetLastError() == ERROR_NO_MORE_FILES); + + return DirectorySize; +} + +ULONG GetRequiredSpaceInBytes( + VOID) +{ + WCHAR ExeDir[MAX_PATH]; + + GetModuleFileName(NULL, ExeDir, ARRAYSIZE(ExeDir)); + PathCchRemoveFileSpec(ExeDir, ARRAYSIZE(ExeDir)); + return GetDirectorySize(ExeDir); +} + +// +// Look in resource.h and you will notice that the control IDs are numerically +// grouped by the scene they belong in. +// +VOID SetScene( + IN ULONG SceneNumber) +{ + BOOLEAN Success; + USHORT ControlId; + USHORT MaxControlId; + + PCWSTR HeaderTexts[][2] = { + {L"Choose Install Location", L"Choose where you want VxKex to install files."}, + {L"Installing...", L"Installation is now in progress."}, + {L"Installation Complete", L"VxKex is now ready for use."}, + {L"Uninstall VxKex", L"Review the information below, and then click Uninstall."}, + {L"Uninstalling...", L"Uninstallation is now in progress."}, + {L"Uninstallation Complete", L"VxKex has been removed from your computer."}, + {L"Update VxKex", L"Review the information below, and then click Update."}, + {L"Updating...", L"Update is now in progress."}, + {L"Update Complete", L"VxKex is now ready for use."} + }; + + ASSERT (SceneNumber >= 1); + ASSERT (SceneNumber <= 9); + + if (CurrentScene == 0) { + // when CurrentScene is zero, that means everything is shown. + // we have to hide everything first. + ControlId = 110; + MaxControlId = 199; + } else { + if (SceneNumber == CurrentScene) { + return; + } + + ControlId = 100 + ((USHORT) CurrentScene * 10); + MaxControlId = ControlId + 9; + } + + while (ControlId <= MaxControlId) { + HideAndDisableControl(ControlId++); + } + + ControlId = 100 + ((USHORT) SceneNumber * 10); + MaxControlId = ControlId + 9; + + while (ControlId <= MaxControlId) { + Success = ShowAndEnableControl(ControlId++); + + if (!Success) { + break; + } + } + + // Set the header text that appears in the white banner at the top of the window. + SetDlgItemText(MainWindow, IDHDRTEXT, HeaderTexts[SceneNumber - 1][0]); + SetDlgItemText(MainWindow, IDHDRSUBTEXT, HeaderTexts[SceneNumber - 1][1]); + + if (SceneNumber == SCENE_SELECT_INSTALLATION_DIR) { + WCHAR FormattedSpaceString[16]; + WCHAR RequiredSpaceString[64] = L"Disk space required: up to "; + + ASSERT (OperationMode == OperationModeInstall); + SetDlgItemText(MainWindow, IDNEXT, L"&Install"); + Button_SetShield(GetDlgItem(MainWindow, IDNEXT), TRUE); + + // populate the installation location edit control with KexDir + SetDlgItemText(MainWindow, IDS1DIRPATH, KexDir); + + StrFormatByteSize( + GetRequiredSpaceInBytes(), + FormattedSpaceString, + ARRAYSIZE(FormattedSpaceString)); + + StringCchCat( + RequiredSpaceString, + ARRAYSIZE(RequiredSpaceString), + FormattedSpaceString); + + SetDlgItemText(MainWindow, IDS1SPACEREQ, RequiredSpaceString); + } else if (SceneNumber == SCENE_UNINSTALL_CONFIRM) { + ASSERT (OperationMode == OperationModeUninstall); + SetDlgItemText(MainWindow, IDNEXT, L"&Uninstall"); + Button_SetShield(GetDlgItem(MainWindow, IDNEXT), TRUE); + } else if (SceneNumber == SCENE_UPDATE_CHANGELOG) { + HWND EditWindow; + HANDLE ChangelogFileHandle; + WCHAR ChangelogPath[MAX_PATH]; + PWSTR Changelog; + ULONG ChangelogCch; + ULONG Discard; + BOOLEAN CannotDisplay; + + CannotDisplay = FALSE; + + ASSERT (OperationMode == OperationModeUpgrade); + SetDlgItemText(MainWindow, IDNEXT, L"&Update"); + Button_SetShield(GetDlgItem(MainWindow, IDNEXT), TRUE); + + GetModuleFileName(NULL, ChangelogPath, ARRAYSIZE(ChangelogPath)); + PathCchRemoveFileSpec(ChangelogPath, ARRAYSIZE(ChangelogPath)); + PathCchAppend(ChangelogPath, ARRAYSIZE(ChangelogPath), L"Core\\Changelog.txt"); + + ChangelogFileHandle = CreateFile( + ChangelogPath, + GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if (ChangelogFileHandle == INVALID_HANDLE_VALUE) { + CannotDisplay = TRUE; + goto CannotDisplayChangelog; + } + + // + // The Changelog must be encoded in Unicode. + // + + ChangelogCch = (GetFileSize(ChangelogFileHandle, NULL) / sizeof(WCHAR)) + 1; + Changelog = StackAlloc(WCHAR, ChangelogCch); + + CannotDisplay = !ReadFile( + ChangelogFileHandle, + Changelog, + ChangelogCch * sizeof(WCHAR), + &Discard, + NULL); + + CloseHandle(ChangelogFileHandle); + + if (CannotDisplay) { + goto CannotDisplayChangelog; + } + + // check for Unicode BOM + if (Changelog[0] != 0xFEFF) { + CannotDisplay = TRUE; + goto CannotDisplayChangelog; + } + + // null terminate + Changelog[ChangelogCch - 1] = '\0'; + ++Changelog; + +CannotDisplayChangelog: + if (CannotDisplay) { + ASSERT (FALSE); + + Changelog = L"The changelog cannot be displayed.\r\n" + L"Visit the website to read it:\r\n" + _L(KEX_WEB_STR); + } + + EditWindow = GetDlgItem(MainWindow, IDS7CHANGELOG); + Edit_ReplaceSel(EditWindow, Changelog); + PostMessage(EditWindow, EM_SETSEL, 0, 0); + } else { + HWND NextButton; + + NextButton = GetDlgItem(MainWindow, IDNEXT); + SetWindowText(NextButton, L"&Finish"); + Button_SetShield(NextButton, FALSE); + + switch (SceneNumber) { + case SCENE_INSTALLING: + case SCENE_UNINSTALLING: + case SCENE_UPDATING: + ShowAndEnableControl(IDPROGRESS); + SendDlgItemMessage(MainWindow, IDPROGRESS, PBM_SETMARQUEE, TRUE, 0); + EnableWindow(NextButton, FALSE); + break; + default: + SendDlgItemMessage(MainWindow, IDPROGRESS, PBM_SETMARQUEE, FALSE, 0); + HideAndDisableControl(IDPROGRESS); + HideAndDisableControl(IDCANCEL2); + EnableWindow(NextButton, TRUE); + break; + } + } + + CurrentScene = SceneNumber; +} + +HGDIOBJ SetStaticControlBackground( + IN HWND DialogWindow, + IN HWND ControlWindow, + IN HDC DeviceContext) +{ + static HFONT BoldFont = NULL; + + if (!BoldFont) { + BoldFont = CreateFont( + -MulDiv(8, GetDeviceCaps(DeviceContext, LOGPIXELSY), 72), + 0, 0, 0, FW_BOLD, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, + CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, DEFAULT_PITCH | FF_DONTCARE, + L"MS Shell Dlg 2"); + } + + switch (GetWindowLongPtr(ControlWindow, GWLP_ID)) { + case IDHDRTEXT: + SelectObject(DeviceContext, BoldFont); + // fall through + case IDHDRSUBTEXT: + // Note: don't use hollow brush, that causes glitches when you change the text + // in a text control. + // We want this color to match the SS_WHITERECT background. That color would + // be COLOR_3DHILIGHT. The documentation for SS_WHITERECT says that it uses + // the "color used to fill the window background", which sounds like it should + // be COLOR_WINDOW, but the documentation is a total fucking piece of shit + // which was probably written by some monkey fucking retard who never looked + // at the very simple source code for the control he was supposed to be + // "documenting". + SetBkColor(DeviceContext, GetSysColor(COLOR_3DHILIGHT)); + return GetSysColorBrush(COLOR_3DHILIGHT); + case IDS7CHANGELOG: + SetTextColor(DeviceContext, GetSysColor(COLOR_WINDOWTEXT)); + SetBkColor(DeviceContext, GetSysColor(COLOR_WINDOW)); + return GetSysColorBrush(COLOR_WINDOW); + } + + return FALSE; +} + +DWORD WINAPI WaitForElevatedProcessEnd( + IN PVOID Parameter) +{ + NTSTATUS ExitCode; + ULONG WaitResult; + + ASSERT (ElevatedProcess != NULL); + + if (KexIsDebugBuild) { + // No timeout for debug build because the elevated process might need to + // be debugged. Annoying to have the GUI close for no reason during + // debugging. + WaitResult = WaitForSingleObject(ElevatedProcess, INFINITE); + } else { + WaitResult = WaitForSingleObject(ElevatedProcess, 60000); // 1 minute max + } + + GetExitCodeProcess(ElevatedProcess, (PULONG) &ExitCode); + + if (WaitResult == WAIT_TIMEOUT) { + ErrorBoxF(L"The elevated setup process appears to have stopped responding.", ExitCode); + SendMessage(MainWindow, WM_USER + 3, 0, 0); + } else if (!NT_SUCCESS(ExitCode)) { + ErrorBoxF(L"The elevated setup process exited with an error code: 0x%08lx", ExitCode); + SendMessage(MainWindow, WM_USER + 3, 0, 0); + } else { + // Instead of calling SetScene directly, we need to ask the main thread + // to do it. Calling SetScene directly works but subtly breaks the + // Finish button. + SendMessage(MainWindow, WM_USER + 2, 0, 0); + } + + return 0; +} + +INT_PTR CALLBACK DialogProc( + IN HWND Window, + IN UINT Message, + IN WPARAM WParam, + IN LPARAM LParam) +{ + if (Message == WM_INITDIALOG) { + MainWindow = Window; + KexgApplicationMainWindow = MainWindow; + CurrentScene = 0; + + SetScene((OperationMode * 3) + 1); + + if (OperationMode == OperationModeInstall) { + HRESULT Result; + Result = SHAutoComplete(GetDlgItem(Window, IDS1DIRPATH), SHACF_FILESYS_DIRS | SHACF_USETAB); + ASSERT (SUCCEEDED(Result)); + } else if (OperationMode == OperationModeUninstall) { + CheckDlgButton(Window, IDS4PRESERVECONFIG, PreserveConfig ? BST_CHECKED : BST_UNCHECKED); + + ToolTip(Window, IDS4PRESERVECONFIG, + L"Preserve the application compatibility settings (such as Windows version spoofing) " + L"for applications. VxKex will still be disabled for these applications and you will " + L"need to re-enable VxKex if you decide to reinstall."); + } + } else if (Message == WM_CLOSE) { + DialogProc(Window, WM_COMMAND, IDCANCEL2, 0); + } else if (Message == WM_COMMAND) { + USHORT ControlId; + + ControlId = LOWORD(WParam); + + if (ControlId == IDCANCEL2) { + if (CurrentScene == SCENE_INSTALLING || + CurrentScene == SCENE_UPDATING || + CurrentScene == SCENE_UNINSTALLING) { + + INT UserResponse; + + UserResponse = MessageBox( + Window, + L"Do you want to cancel Setup?", + FRIENDLYAPPNAME, + MB_ICONQUESTION | MB_YESNO); + + if (UserResponse == IDYES) { + EndDialog(Window, 0); + } + } else { + EndDialog(Window, 0); + } + } else if (ControlId == IDS1DIRPATH) { + UpdateDiskFreeSpace(); + } else if (ControlId == IDS1BROWSE) { + BOOLEAN UserPickedAFolder; + WCHAR DirectoryPath[MAX_PATH]; + + GetDlgItemText(Window, IDS1DIRPATH, DirectoryPath, ARRAYSIZE(DirectoryPath)); + + UserPickedAFolder = PickFolder( + Window, + DirectoryPath, + FOS_NOREADONLYRETURN, + DirectoryPath, + ARRAYSIZE(DirectoryPath)); + + if (UserPickedAFolder) { + PathCchAppend(DirectoryPath, ARRAYSIZE(DirectoryPath), L"VxKex"); + } + + SetDlgItemText(Window, IDS1DIRPATH, DirectoryPath); + StringCchCopy(KexDir, ARRAYSIZE(KexDir), DirectoryPath); + } else if (ControlId == IDNEXT) { + if (CurrentScene == SCENE_INSTALLATION_COMPLETE || + CurrentScene == SCENE_UNINSTALLATION_COMPLETE || + CurrentScene == SCENE_UPDATE_COMPLETE) { + + if (IsDlgButtonChecked(Window, IDS3KEXCFG)) { + WCHAR KexCfgFullPath[MAX_PATH]; + + // "Open global configuration" checkbox is checked. + StringCchPrintf( + KexCfgFullPath, + ARRAYSIZE(KexCfgFullPath), + L"%s\\KexCfg.exe", + KexDir); + + ShellExecute(Window, L"open", KexCfgFullPath, NULL, NULL, SW_SHOW); + } + + // under these conditions the Next button turns into a Finish button + EndDialog(Window, 0); + } else { + WCHAR ExeFullPath[MAX_PATH]; + PWSTR CommandLineArgs; + ULONG ShellExecuteResult; + + GetModuleFileName(NULL, ExeFullPath, ARRAYSIZE(ExeFullPath)); + + StringAllocPrintf( + &CommandLineArgs, + NULL, + L"/SILENTUNATTEND /HWND:%u %s %s %s%s%s", + Window, + PreserveConfig ? L"/PRESERVECONFIG" : L"", + OperationMode == OperationModeUninstall ? L"/UNINSTALL" : L"", + OperationMode == OperationModeInstall ? L"/KEXDIR:\"" : L"", + OperationMode == OperationModeInstall ? KexDir : L"", + OperationMode == OperationModeInstall ? L"\"" : L""); + + ShellExecuteResult = (ULONG) ShellExecute( + MainWindow, + L"runas", + ExeFullPath, + CommandLineArgs, + NULL, + SW_SHOWNORMAL); + + SafeFree(CommandLineArgs); + + // SE_ERR_ACCESSDENIED happens when user clicks No on the + // elevation prompt, so it's not an error for us. + if (ShellExecuteResult <= 32 && ShellExecuteResult != SE_ERR_ACCESSDENIED) { + ErrorBoxF( + L"ShellExecute failed with error code %d. Setup cannot continue.", + ShellExecuteResult); + ExitProcess(STATUS_UNSUCCESSFUL); + } + } + } else if (ControlId == IDS4PRESERVECONFIG) { + PreserveConfig = IsDlgButtonChecked(Window, ControlId); + } else { + return FALSE; + } + } else if (Message == WM_CTLCOLORSTATIC) { + return (INT_PTR) SetStaticControlBackground(Window, (HWND) LParam, (HDC) WParam); + } else if (Message == WM_USER + 1) { + // LPARAM indicates a process handle sent by the elevated process. + ASSERT (LParam != 0); + ASSERT (ElevatedProcess == NULL); + + ElevatedProcess = (HANDLE) LParam; + SetScene(CurrentScene + 1); + + CreateThread( + NULL, + 0, + WaitForElevatedProcessEnd, + NULL, + 0, + NULL); + } else if (Message == WM_USER + 2) { + SetScene(CurrentScene + 1); + } else if (Message == WM_USER + 3) { + // sent after displaying a fatal error dialog to the user + EndDialog(Window, 0); + } else { + return FALSE; + } + + return TRUE; +} + +VOID DisplayInstallerGUI( + VOID) +{ + unless (OperationMode == OperationModeUninstall) { + KexSetupCheckForPrerequisites(); + } + + CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); + DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_MAINWINDOW), NULL, DialogProc); +} \ No newline at end of file diff --git a/KexSetup/kexsetup.h b/KexSetup/kexsetup.h new file mode 100644 index 0000000..bcf11ca --- /dev/null +++ b/KexSetup/kexsetup.h @@ -0,0 +1,160 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// kexsetup.h +// +// Abstract: +// +// Main header file for KexSetup +// +// Author: +// +// vxiiduu (01-Feb-2024) +// +// Environment: +// +// Win32, without any vxkex support components +// +// Revision History: +// +// vxiiduu 01-Feb-2024 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "buildcfg.h" +#include "resource.h" +#include + +typedef enum { + OperationModeInstall, + OperationModeUninstall, + OperationModeUpgrade +} TYPEDEF_TYPE_NAME(KEXSETUP_OPERATION_MODE); + +// +// main.c +// + +EXTERN BOOLEAN Is64BitOS; +EXTERN KEXSETUP_OPERATION_MODE OperationMode; +EXTERN BOOLEAN SilentUnattended; +EXTERN BOOLEAN PreserveConfig; +EXTERN WCHAR KexDir[MAX_PATH]; +EXTERN ULONG ExistingVxKexVersion; +EXTERN ULONG InstallerVxKexVersion; + +// +// cmdline.c +// + +VOID ProcessCommandLineOptions( + VOID); + +// +// gui.c +// + +EXTERN HWND MainWindow; +EXTERN ULONG CurrentScene; + +VOID DisplayInstallerGUI( + VOID); + +INT_PTR CALLBACK DialogProc( + IN HWND Window, + IN UINT Message, + IN WPARAM WParam, + IN LPARAM LParam); + +VOID SetScene( + IN ULONG SceneNumber); + +ULONG GetRequiredSpaceInBytes( + VOID); + +// +// perform.c +// + +EXTERN HANDLE KexSetupTransactionHandle; + +VOID KexSetupPerformActions( + VOID); + +// +// prereq.c +// + +VOID KexSetupCheckForPrerequisites( + VOID); + +// +// util.c +// + +VOID GetDefaultInstallationLocation( + IN PWSTR InstallationPath); + +BOOLEAN IsWow64( + VOID); + +VOID KexSetupCreateKey( + IN HKEY KeyHandle, + IN PCWSTR SubKey, + IN REGSAM DesiredAccess, + OUT PHKEY KeyHandleOut); + +VOID KexSetupDeleteKey( + IN HKEY KeyHandle, + IN PCWSTR Subkey OPTIONAL); + +VOID KexSetupRegWriteI32( + IN HKEY KeyHandle, + IN PCWSTR ValueName, + IN ULONG Data); + +VOID KexSetupRegWriteString( + IN HKEY KeyHandle, + IN PCWSTR ValueName, + IN PCWSTR Data); + +VOID KexSetupRegReadString( + IN HKEY KeyHandle, + IN PCWSTR ValueName, + OUT PWSTR Buffer, + IN ULONG BufferCch); + +VOID KexSetupSupersedeFile( + IN PCWSTR SourceFile, + IN PCWSTR TargetFile); + +VOID KexSetupFormatPath( + OUT PWSTR Buffer, + IN PCWSTR Format, + IN ...); + +VOID KexSetupMoveFileSpecToDirectory( + IN PCWSTR FileSpec, + IN PCWSTR TargetDirectoryPath); + +VOID KexSetupCreateDirectory( + IN PCWSTR DirectoryPath); + +BOOLEAN KexSetupDeleteFile( + IN PCWSTR FilePath); + +BOOLEAN KexSetupRemoveDirectoryRecursive( + IN PCWSTR DirectoryPath); + +BOOLEAN KexSetupDeleteFilesBySpec( + IN PCWSTR FileSpec); + +// +// version.c +// + +ULONG KexSetupGetInstalledVersion( + VOID); \ No newline at end of file diff --git a/KexSetup/main.c b/KexSetup/main.c new file mode 100644 index 0000000..9c05d10 --- /dev/null +++ b/KexSetup/main.c @@ -0,0 +1,54 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// main.c +// +// Abstract: +// +// KexSetup, the VxKex installer (and uninstaller) program. +// +// Author: +// +// vxiiduu (31-Jan-2024) +// +// Environment: +// +// Win32, without any vxkex support components +// +// Revision History: +// +// vxiiduu 31-Jan-2024 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#define NEED_VERSION_DEFS +#include "kexsetup.h" + +BOOLEAN Is64BitOS; +KEXSETUP_OPERATION_MODE OperationMode; +BOOLEAN SilentUnattended; +BOOLEAN PreserveConfig; +WCHAR KexDir[MAX_PATH]; +ULONG ExistingVxKexVersion; +ULONG InstallerVxKexVersion; + +VOID EntryPoint( + VOID) +{ + KexgApplicationFriendlyName = FRIENDLYAPPNAME; + ExistingVxKexVersion = KexSetupGetInstalledVersion(); + InstallerVxKexVersion = KEX_VERSION_DW; + + Is64BitOS = IsWow64(); + GetDefaultInstallationLocation(KexDir); + ProcessCommandLineOptions(); + + if (SilentUnattended) { + KexSetupPerformActions(); + } else { + DisplayInstallerGUI(); + } + + ExitProcess(STATUS_SUCCESS); +} \ No newline at end of file diff --git a/KexSetup/perform.c b/KexSetup/perform.c new file mode 100644 index 0000000..87d1fb2 --- /dev/null +++ b/KexSetup/perform.c @@ -0,0 +1,1408 @@ +#define NEED_VERSION_DEFS +#include "kexsetup.h" +#include +#include + +HANDLE KexSetupTransactionHandle = NULL; +BOOLEAN KexSetupOkToCommitTransaction = FALSE; +ULONG InstalledSize; + +VOID KexSetupWriteUninstallEntry( + VOID) +{ + HKEY KeyHandle; + WCHAR FormattedDate[9]; // YYYYMMDD\0 + WCHAR UninstallString[MAX_PATH + 11]; // +11 for " /UNINSTALL" + + try { + KexSetupCreateKey( + HKEY_LOCAL_MACHINE, + L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\VxKex", + KEY_READ | KEY_WRITE, + &KeyHandle); + + ASSERT (KeyHandle != NULL); + ASSERT (KeyHandle != INVALID_HANDLE_VALUE); + + GetDateFormat(LOCALE_INVARIANT, 0, NULL, L"yyyyMMdd", FormattedDate, ARRAYSIZE(FormattedDate)); + StringCchPrintf(UninstallString, ARRAYSIZE(UninstallString), L"%s\\KexSetup.exe /UNINSTALL", KexDir); + + KexSetupRegWriteString(KeyHandle, L"DisplayName", L"VxKex API Extensions for Windows® 7"); + KexSetupRegWriteString(KeyHandle, L"DisplayVersion", _L(KEX_VERSION_STR)); + KexSetupRegWriteString(KeyHandle, L"Publisher", L"vxiiduu"); + KexSetupRegWriteString(KeyHandle, L"InstallDate", FormattedDate); + KexSetupRegWriteString(KeyHandle, L"InstallLocation", KexDir); + KexSetupRegWriteString(KeyHandle, L"UninstallString", UninstallString); + KexSetupRegWriteString(KeyHandle, L"HelpLink", _L(KEX_WEB_STR)); + KexSetupRegWriteI32 (KeyHandle, L"EstimatedSize", InstalledSize / 1024); + KexSetupRegWriteI32 (KeyHandle, L"NoRepair", TRUE); + KexSetupRegWriteI32 (KeyHandle, L"NoModify", TRUE); + } finally { + RegCloseKey(KeyHandle); + } +} + +// +// This function installs the KexCfg elevation scheduled task. +// +// Note: Errors in this function aren't critical. +// If the scheduled task can't be added, it's not a big deal: there's a fallback +// method for what it's supposed to achieve within the KxCfgHlp library. +// +VOID KexSetupAddKexCfgScheduledTask( + VOID) +{ + HRESULT Result; + VARIANT VariantNull; + WCHAR TaskXml[4096]; + + ITaskService *TaskService; + ITaskFolder *TaskFolder; + IRegisteredTask *KexCfgTask; + + ZeroMemory(&VariantNull, sizeof(VariantNull)); + TaskService = NULL; + TaskFolder = NULL; + KexCfgTask = NULL; + + Result = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + if (FAILED(Result)) { + ASSERT (SUCCEEDED(Result)); + return; + } + + try { + Result = CoCreateInstance( + &CLSID_TaskScheduler, + NULL, + CLSCTX_INPROC_SERVER, + &IID_ITaskService, + (PPVOID) &TaskService); + + if (FAILED(Result)) { + ASSERT (SUCCEEDED(Result)); + return; + } + + // + // Connect to the Task Scheduler service. + // + + Result = ITaskService_Connect( + TaskService, + VariantNull, + VariantNull, + VariantNull, + VariantNull); + + if (FAILED(Result)) { + ASSERT (SUCCEEDED(Result)); + return; + } + + // + // Get the root Task Scheduler folder interface so we can use it to + // register a task. + // + + Result = ITaskService_GetFolder( + TaskService, + L"\\", + &TaskFolder); + + if (FAILED(Result)) { + ASSERT (SUCCEEDED(Result)); + return; + } + + // + // Format the XML string that we'll use to register the task. + // + + Result = StringCchPrintf( + TaskXml, + ARRAYSIZE(TaskXml), + L"\r\n" + L"\r\n" + L" \r\n" + L" vxiiduu\r\n" + L" VxKex\r\n" + L" \r\n" + L"This scheduled task is run on-demand by VxKex components and utilities (for example, " + L"the shell extension). It allows VxKex to be enabled, disabled, or configured for a program " + L"without requiring you to interact with a User Account Control prompt. " + L"You may safely disable or remove this scheduled task if you want. However, keep in mind that " + L"if you do this, and you have User Account Control enabled, you may get a consent prompt every " + L"time you configure VxKex for a program." + L" \r\n" + L" \r\n" + L" \r\n" + L" \r\n" + L" \r\n" + L" S-1-5-18\r\n" + L" HighestAvailable\r\n" + L" \r\n" + L" \r\n" + L" \r\n" + L" Parallel\r\n" + L" false\r\n" + L" false\r\n" + L" true\r\n" + L" false\r\n" + L" false\r\n" + L" \r\n" + L" false\r\n" + L" false\r\n" + L" \r\n" + L" true\r\n" + L" true\r\n" + L" false\r\n" + L" false\r\n" + L" false\r\n" + L" false\r\n" + L" false\r\n" + L" PT1H\r\n" + L" 7\r\n" + L" \r\n" + L" \r\n" + L" \r\n" + L" %s\\KexCfg.exe\r\n" + L" /SCHTASK $(Arg0)\r\n" + L" %s\r\n" + L" \r\n" + L" \r\n" + L"", + KexDir, + KexDir); + + if (FAILED(Result)) { + ASSERT (SUCCEEDED(Result)); + return; + } + + // + // Register the task. + // + + Result = ITaskFolder_RegisterTask( + TaskFolder, + KXCFG_ELEVATION_SCHTASK_NAME, + TaskXml, + TASK_CREATE_OR_UPDATE, + VariantNull, + VariantNull, + TASK_LOGON_GROUP, + VariantNull, + &KexCfgTask); + + if (FAILED(Result)) { + ASSERT (SUCCEEDED(Result)); + return; + } + + // + // Set the security descriptor on the task so that every user on the system + // can run the task. This step is necessary to ensure that non-administrator + // users can also use VxKex. + // + // Later on, if there is demand, we can also add a setting somewhere (perhaps + // through the KexCfg global settings interface) to disable this so that non + // admins can't access the settings. + // + // Owner: Builtin Administrator + // Group: Builtin Administrator + // Local System has full access. + // Administrators have full access. + // Users can read and execute. + // + + Result = IRegisteredTask_SetSecurityDescriptor( + KexCfgTask, + L"O:BAG:BAD:AI(A;;GA;;;SY)(A;;GA;;;BA)(A;;GRGX;;;BU)", + 0); + + ASSERT (SUCCEEDED(Result)); + + } finally { + if (TaskService) { + ITaskService_Release(TaskService); + TaskService = NULL; + } + + if (TaskFolder) { + ITaskFolder_Release(TaskFolder); + TaskFolder = NULL; + } + + if (KexCfgTask) { + IRegisteredTask_Release(KexCfgTask); + KexCfgTask = NULL; + } + + CoUninitialize(); + } +} + +// +// This function deletes the KexCfg elevation scheduled task. +// +// As with KexSetupAddKexCfgScheduledTask, errors in this function +// aren't critical. Even though we call it a "scheduled" task, it only +// ever runs on-demand, so if it never gets deleted because we can't +// delete it... well, besides a few kb's of cruft left on the computer, +// there's no harm. +// +VOID KexSetupRemoveKexCfgScheduledTask( + VOID) +{ + HRESULT Result; + VARIANT VariantNull; + + ITaskService *TaskService; + ITaskFolder *TaskFolder; + + ZeroMemory(&VariantNull, sizeof(VariantNull)); + TaskService = NULL; + TaskFolder = NULL; + + Result = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + + try { + Result = CoCreateInstance( + &CLSID_TaskScheduler, + NULL, + CLSCTX_INPROC_SERVER, + &IID_ITaskService, + (PPVOID) &TaskService); + + if (FAILED(Result)) { + ASSERT (SUCCEEDED(Result)); + return; + } + + // + // Connect to Task Scheduler service. + // + + Result = ITaskService_Connect( + TaskService, + VariantNull, + VariantNull, + VariantNull, + VariantNull); + + if (FAILED(Result)) { + ASSERT (SUCCEEDED(Result)); + return; + } + + // + // Get the ITaskFolder interface so we can use it to delete the task + // + + Result = ITaskService_GetFolder( + TaskService, + L"\\", + &TaskFolder); + + if (FAILED(Result)) { + ASSERT (SUCCEEDED(Result)); + return; + } + + // + // Delete the KexCfg scheduled task. + // + + Result = ITaskFolder_DeleteTask( + TaskFolder, + KXCFG_ELEVATION_SCHTASK_NAME, + 0); + + if (FAILED(Result)) { + ASSERT (SUCCEEDED(Result)); + } + + } finally { + if (TaskService) { + ITaskService_Release(TaskService); + TaskService = NULL; + } + + if (TaskFolder) { + ITaskFolder_Release(TaskFolder); + TaskFolder = NULL; + } + + CoUninitialize(); + } +} + +VOID KexSetupInstallFiles( + VOID) +{ + WCHAR TargetPath[MAX_PATH]; + + // + // Install bitness agnostic data to KexDir. + // This includes everything in Core\, as well as the current program + // (kexsetup.exe). + // + + KexSetupMoveFileSpecToDirectory(L".\\KexSetup.*", KexDir); + KexSetupMoveFileSpecToDirectory(L".\\Core\\*", KexDir); + + // + // Install KexDll to system32, and to syswow64 if 64bit OS. + // The purpose of the wildcard KexDll.* is to include the pdb as well. + // + + if (Is64BitOS) { + GetWindowsDirectory(TargetPath, ARRAYSIZE(TargetPath)); + PathCchAppend(TargetPath, ARRAYSIZE(TargetPath), L"sysnative"); + KexSetupMoveFileSpecToDirectory(L".\\Core64\\KexDll.*", TargetPath); + + PathCchAppend(TargetPath, ARRAYSIZE(TargetPath), L"KexDll.*.old_*"); + KexSetupDeleteFilesBySpec(TargetPath); + + if (KexIsReleaseBuild) { + PathCchRemoveFileSpec(TargetPath, ARRAYSIZE(TargetPath)); + PathCchAppend(TargetPath, ARRAYSIZE(TargetPath), L"KexDll.pdb"); + KexSetupDeleteFile(TargetPath); + } + } + + GetWindowsDirectory(TargetPath, ARRAYSIZE(TargetPath)); + PathCchAppend(TargetPath, ARRAYSIZE(TargetPath), L"system32"); // On 64-bit OS, this actually goes to syswow64 + KexSetupMoveFileSpecToDirectory(L".\\Core32\\KexDll.*", TargetPath); + + // Delete any lingering old files. + PathCchAppend(TargetPath, ARRAYSIZE(TargetPath), L"KexDll.*.old_*"); + KexSetupDeleteFilesBySpec(TargetPath); + + // If a release build, delete PDB now (it is no longer the correct one + // anyway). + if (KexIsReleaseBuild) { + PathCchRemoveFileSpec(TargetPath, ARRAYSIZE(TargetPath)); + PathCchAppend(TargetPath, ARRAYSIZE(TargetPath), L"KexDll.pdb"); + KexSetupDeleteFile(TargetPath); + } + + // + // Install native core files to KexDir, plus KexShl32 & CpiwBp32 if 64bit OS + // + + if (Is64BitOS) { + KexSetupMoveFileSpecToDirectory(L".\\Core64\\*", KexDir); + + KexSetupFormatPath(TargetPath, L"%s\\KexShl32.dll", KexDir); + KexSetupSupersedeFile(L".\\Core32\\KexShlEx.dll", TargetPath); + + KexSetupFormatPath(TargetPath, L"%s\\CpiwBp32.dll", KexDir); + KexSetupSupersedeFile(L".\\Core32\\CpiwBypa.dll", TargetPath); + + if (KexIsDebugBuild) { + // Move the pdbs as well + KexSetupFormatPath(TargetPath, L"%s\\KexShl32.pdb", KexDir); + KexSetupSupersedeFile(L".\\Core32\\KexShlEx.pdb", TargetPath); + + KexSetupFormatPath(TargetPath, L"%s\\CpiwBp32.pdb", KexDir); + KexSetupSupersedeFile(L".\\Core32\\CpiwBypa.pdb", TargetPath); + } + } else { + KexSetupMoveFileSpecToDirectory(L".\\Core32\\*", KexDir); + } + + KexSetupFormatPath(TargetPath, L"%s\\*.old_*", KexDir); + KexSetupDeleteFilesBySpec(TargetPath); + + if (KexIsReleaseBuild) { + // Remove outdated PDB files + KexSetupFormatPath(TargetPath, L"%s\\*.pdb", KexDir); + KexSetupDeleteFilesBySpec(TargetPath); + } + + // + // Install extension DLLs to KexDir\Kex32 (and KexDir\Kex64 if 64bit OS) + // + + // remove old PDBs + KexSetupFormatPath(TargetPath, L"%s\\Kex32\\*.pdb", KexDir); + KexSetupDeleteFilesBySpec(TargetPath); + + KexSetupFormatPath(TargetPath, L"%s\\Kex32", KexDir); + KexSetupMoveFileSpecToDirectory(L".\\Kex32\\*", TargetPath); + + PathCchAppend(TargetPath, ARRAYSIZE(TargetPath), L"*.old_*"); + KexSetupDeleteFilesBySpec(TargetPath); + + // remove dnsw8, which is no longer included + KexSetupFormatPath(TargetPath, L"%s\\Kex32\\dnsw8.dll", KexDir); + KexSetupDeleteFile(TargetPath); + + // remove msvw10, which is no longer included + KexSetupFormatPath(TargetPath, L"%s\\Kex32\\msvw10.dll", KexDir); + KexSetupDeleteFile(TargetPath); + + if (Is64BitOS) { + // remove old PDBs + KexSetupFormatPath(TargetPath, L"%s\\Kex64\\*.pdb", KexDir); + KexSetupDeleteFilesBySpec(TargetPath); + + KexSetupFormatPath(TargetPath, L"%s\\Kex64", KexDir); + KexSetupMoveFileSpecToDirectory(L".\\Kex64\\*", TargetPath); + + PathCchAppend(TargetPath, ARRAYSIZE(TargetPath), L"*.old_*"); + KexSetupDeleteFilesBySpec(TargetPath); + + // remove dnsw8 + KexSetupFormatPath(TargetPath, L"%s\\Kex64\\dnsw8.dll", KexDir); + KexSetupDeleteFile(TargetPath); + + // remove msvw10 + KexSetupFormatPath(TargetPath, L"%s\\Kex64\\msvw10.dll", KexDir); + KexSetupDeleteFile(TargetPath); + } +} + +// +// This function is called (indirectly) by KexSetupUninstall to delete +// or disable VxKex for every program the user configured it for. +// +// It's important that we do this, because it could cause those programs +// to stop working altogether until the user does some manual work to +// fix the problem if we fail to remove the configuration. +// +BOOLEAN CALLBACK KexSetupConfigurationEnumerationCallback( + IN PCWSTR ExeFullPathOrBaseName, + IN BOOLEAN IsLegacyConfiguration, + IN PVOID ExtraParameter) +{ + BOOLEAN Success; + + // always delete pre-rewrite configuration. + if (IsLegacyConfiguration) { + Success = KxCfgDeleteLegacyConfiguration( + ExeFullPathOrBaseName, + KexSetupTransactionHandle); + + if (!Success) { + ErrorBoxF( + L"Setup was unable to delete VxKex legacy configuration for \"%s\". %s", + ExeFullPathOrBaseName, GetLastErrorAsString()); + + RtlRaiseStatus(STATUS_KEXSETUP_FAILURE); + } + + return TRUE; + } + + ASSERT (!PathIsRelative(ExeFullPathOrBaseName)); + + if (PreserveConfig) { + KXCFG_PROGRAM_CONFIGURATION Configuration; + + Success = KxCfgGetConfiguration(ExeFullPathOrBaseName, &Configuration); + if (!Success) { + RtlRaiseStatus(STATUS_KEXSETUP_FAILURE); + } + + if (Configuration.Enabled) { + Configuration.Enabled = FALSE; + + Success = KxCfgSetConfiguration( + ExeFullPathOrBaseName, + &Configuration, + KexSetupTransactionHandle); + + if (!Success) { + ErrorBoxF( + L"Setup was unable to disable VxKex for \"%s\". %s", + ExeFullPathOrBaseName, GetLastErrorAsString()); + + RtlRaiseStatus(STATUS_KEXSETUP_FAILURE); + } + } + } else { + Success = KxCfgDeleteConfiguration( + ExeFullPathOrBaseName, + KexSetupTransactionHandle); + + if (!Success) { + ErrorBoxF( + L"Setup was unable to delete VxKex configuration for \"%s\". %s", + ExeFullPathOrBaseName, GetLastErrorAsString()); + + RtlRaiseStatus(STATUS_KEXSETUP_FAILURE); + } + } + + return TRUE; +} + +VOID KexSetupUninstall( + VOID) +{ + BOOLEAN Success; + WCHAR PathBuffer[MAX_PATH]; + + // + // If the installer is running from KexDir, we will move it out of KexDir to a + // temporary location. Otherwise, we won't be able to fully remove KexDir. + // + + GetModuleFileName(NULL, PathBuffer, ARRAYSIZE(PathBuffer)); + + if (PathIsPrefix(KexDir, PathBuffer)) { + WCHAR NewKexSetupLocation[MAX_PATH]; + WCHAR RandomIdentifier[24]; + + GetTempPath(ARRAYSIZE(PathBuffer), NewKexSetupLocation); + + StringCchPrintf( + RandomIdentifier, + ARRAYSIZE(RandomIdentifier), + L"KexSetup-%08x", + GetTickCount()); + + PathCchAppend(NewKexSetupLocation, ARRAYSIZE(NewKexSetupLocation), RandomIdentifier); + KexSetupCreateDirectory(NewKexSetupLocation); + PathCchAppend(NewKexSetupLocation, ARRAYSIZE(NewKexSetupLocation), L"KexSetup.exe"); + KexSetupSupersedeFile(PathBuffer, NewKexSetupLocation); + + // + // Schedule the temporary file and directory to be deleted later. + // We have to temporarily set the transaction to NULL, since the + // MoveFileTransacted API doesn't like it when you already have a + // transaction handle in the TEB. + // + + RtlSetCurrentTransaction(NULL); + + MoveFileTransacted( + NewKexSetupLocation, + NULL, + NULL, + NULL, + MOVEFILE_DELAY_UNTIL_REBOOT, + KexSetupTransactionHandle); + + PathCchRemoveFileSpec(NewKexSetupLocation, ARRAYSIZE(NewKexSetupLocation)); + + MoveFileTransacted( + NewKexSetupLocation, + NULL, + NULL, + NULL, + MOVEFILE_DELAY_UNTIL_REBOOT, + KexSetupTransactionHandle); + + RtlSetCurrentTransaction(KexSetupTransactionHandle); + } + + // + // Delete the rest of KexDir and remove KexDll from system32 and syswow64. + // + + KexSetupRemoveDirectoryRecursive(KexDir); + + GetWindowsDirectory(PathBuffer, ARRAYSIZE(PathBuffer)); + PathCchAppend(PathBuffer, ARRAYSIZE(PathBuffer), L"system32\\KexDll.*"); + KexSetupDeleteFilesBySpec(PathBuffer); + + if (Is64BitOS) { + GetWindowsDirectory(PathBuffer, ARRAYSIZE(PathBuffer)); + PathCchAppend(PathBuffer, ARRAYSIZE(PathBuffer), L"sysnative\\KexDll.*"); + KexSetupDeleteFilesBySpec(PathBuffer); + } + + // + // Delete system and user LogDir. + // + + if (ExistingVxKexVersion >= 0x80000000) { + HKEY VxKexKeyHandle; + + try { + VxKexKeyHandle = KxCfgOpenVxKexRegistryKey( + FALSE, + KEY_READ, + KexSetupTransactionHandle); + + if (VxKexKeyHandle == NULL) { + leave; + } + + KexSetupRegReadString(VxKexKeyHandle, L"LogDir", PathBuffer, ARRAYSIZE(PathBuffer)); + PathCchAppend(PathBuffer, ARRAYSIZE(PathBuffer), L"*.vxl"); + KexSetupDeleteFilesBySpec(PathBuffer); + PathCchRemoveFileSpec(PathBuffer, ARRAYSIZE(PathBuffer)); + RemoveDirectory(PathBuffer); + SafeClose(VxKexKeyHandle); + + VxKexKeyHandle = KxCfgOpenVxKexRegistryKey( + TRUE, + KEY_READ, + KexSetupTransactionHandle); + + if (VxKexKeyHandle == NULL) { + leave; + } + + KexSetupRegReadString(VxKexKeyHandle, L"LogDir", PathBuffer, ARRAYSIZE(PathBuffer)); + PathCchAppend(PathBuffer, ARRAYSIZE(PathBuffer), L"*.vxl"); + KexSetupDeleteFilesBySpec(PathBuffer); + PathCchRemoveFileSpec(PathBuffer, ARRAYSIZE(PathBuffer)); + RemoveDirectory(PathBuffer); + } except (GetExceptionCode() == STATUS_KEXSETUP_FAILURE) { + // ignore error - not critical + } + + SafeClose(VxKexKeyHandle); + } + + // + // Delete propagation virtual key. + // + + if (ExistingVxKexVersion >= 0x80000000) { + KexSetupDeleteKey( + HKEY_LOCAL_MACHINE, + L"Software\\Microsoft\\Windows NT\\CurrentVersion\\" + L"Image File Execution Options\\{VxKexPropagationVirtualKey}"); + } + + // + // Delete VxKex registry key. + // + + if (ExistingVxKexVersion < 0x80000000) { + KexSetupDeleteKey(HKEY_LOCAL_MACHINE, L"Software\\VXsoft\\VxKexLdr"); + } else { + KexSetupDeleteKey(HKEY_LOCAL_MACHINE, L"Software\\VXsoft\\VxKex"); + } + + // + // Delete VxKex user registry key. + // + + if (ExistingVxKexVersion < 0x80000000) { + KexSetupDeleteKey(HKEY_CURRENT_USER, L"Software\\VXsoft\\VxKexLdr"); + } else { + KexSetupDeleteKey(HKEY_CURRENT_USER, L"Software\\VXsoft\\VxKex"); + } + + // + // If PreserveConfig is TRUE, disable VxKex for all programs. + // Otherwise, delete all VxKex program configuration. + // + + KxCfgEnumerateConfiguration( + KexSetupConfigurationEnumerationCallback, + NULL); + + // + // Unregister shell extension and .vxl file extension handler. + // + + try { + KexSetupDeleteKey(HKEY_CLASSES_ROOT, L".vxl"); + KexSetupDeleteKey(HKEY_CLASSES_ROOT, L"vxlfile"); + KexSetupDeleteKey(HKEY_CLASSES_ROOT, L"CLSID\\" CLSID_STRING_KEXSHLEX); + + if (Is64BitOS) { + KexSetupDeleteKey(HKEY_CLASSES_ROOT, L"Wow6432Node\\CLSID\\" CLSID_STRING_KEXSHLEX); + } + + KexSetupDeleteKey(HKEY_CLASSES_ROOT, L"exefile\\shellex\\PropertySheetHandlers\\KexShlEx Property Page"); + KexSetupDeleteKey(HKEY_CLASSES_ROOT, L"lnkfile\\shellex\\PropertySheetHandlers\\KexShlEx Property Page"); + KexSetupDeleteKey(HKEY_CLASSES_ROOT, L"Msi.Package\\shellex\\PropertySheetHandlers\\KexShlEx Property Page"); + } except (GetExceptionCode() == STATUS_KEXSETUP_FAILURE) { + // Ignore the error. Failure to delete these values isn't critical. + ASSERT ((FALSE, "Failed to unregister shell extension and .vxl file handler")); + } + + // + // Remove .vxl disk cleanup handler. + // + + Success = KxCfgRemoveDiskCleanupHandler(KexSetupTransactionHandle); + ASSERT (Success); + + // + // Unregister CpiwBypa BHO + // + + Success = KxCfgEnableExplorerCpiwBypass( + FALSE, + KexSetupTransactionHandle); + + ASSERT (Success); + + try { + KexSetupDeleteKey(HKEY_CLASSES_ROOT, L"CLSID\\{7EF224FC-1840-433C-9BCB-2951DE71DDBD}"); + + if (Is64BitOS) { + KexSetupDeleteKey(HKEY_CLASSES_ROOT, L"Wow6432Node\\CLSID\\{7EF224FC-1840-433C-9BCB-2951DE71DDBD}"); + } + } except (GetExceptionCode() == STATUS_KEXSETUP_FAILURE) { + ASSERT ((FALSE, "Failed to unregister CpiwBypa browser helper object")); + } + + // + // Remove VxKex context menu entry + // + + Success = KxCfgConfigureShellContextMenuEntries( + FALSE, + FALSE, + KexSetupTransactionHandle); + + ASSERT (Success); + + // + // Delete uninstall entry. + // + + KexSetupDeleteKey(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\VxKex"); + + // + // Delete the KexCfg elevation scheduled task. + // We do this last because it's not transacted (it can't be). + // + + KexSetupRemoveKexCfgScheduledTask(); +} + +VOID KexSetupInstall( + VOID) +{ + BOOLEAN Success; + ULONG ErrorCode; + HKEY KeyHandle; + WCHAR TargetPath[MAX_PATH]; + WCHAR UserLogDir[MAX_PATH]; + + // + // Get the installed size (required when adding the uninstall entry) + // right now before we start moving files out of the installer dir. + // + + InstalledSize = GetRequiredSpaceInBytes(); + + // + // Create KexDir, and KexDir\Kex32 (and KexDir\Kex64 if 64bit OS). + // + + KexSetupCreateDirectory(KexDir); + + KexSetupFormatPath(TargetPath, L"%s\\Kex32", KexDir); + KexSetupCreateDirectory(TargetPath); + + if (Is64BitOS) { + KexSetupFormatPath(TargetPath, L"%s\\Kex64", KexDir); + KexSetupCreateDirectory(TargetPath); + } + + // + // Create and populate the VxKex registry key. + // + + KexSetupCreateKey( + HKEY_LOCAL_MACHINE, + L"Software\\VXsoft\\VxKex", + KEY_READ | KEY_WRITE, + &KeyHandle); + + ASSERT (KeyHandle != NULL); + ASSERT (KeyHandle != INVALID_HANDLE_VALUE); + ASSERT (InstallerVxKexVersion & 0x80000000); + + try { + KexSetupRegWriteI32(KeyHandle, L"InstalledVersion", InstallerVxKexVersion); + KexSetupRegWriteString(KeyHandle, L"KexDir", KexDir); + KexSetupRegWriteString(KeyHandle, L"LogDir", L"C:\\ProgramData\\VxKex\\Logs"); + } finally { + RegCloseKey(KeyHandle); + } + + // + // Create and populate VxKex HKCU registry key. + // + + KexSetupCreateKey( + HKEY_CURRENT_USER, + L"Software\\VXsoft\\VxKex", + KEY_READ | KEY_WRITE, + &KeyHandle); + + try { + ASSERT (KeyHandle != NULL); + ASSERT (KeyHandle != INVALID_HANDLE_VALUE); + + // + // Since the HKCU LogDir value is non-critical, we won't bother informing the + // user of errors in ExpandEnvironmentStrings. + // + + ErrorCode = ExpandEnvironmentStrings( + L"%LOCALAPPDATA%\\VxKex\\Logs", + UserLogDir, + ARRAYSIZE(UserLogDir)); + + ASSERT (ErrorCode != 0); + ASSERT (ErrorCode <= ARRAYSIZE(UserLogDir)); + + unless (ErrorCode == 0 || ErrorCode > ARRAYSIZE(UserLogDir)) { + KexSetupRegWriteString( + KeyHandle, + L"LogDir", + UserLogDir); + } + } finally { + RegCloseKey(KeyHandle); + KeyHandle = NULL; + } + + // + // Create and populate Propagation Virtual Key + // + + KexSetupCreateKey( + HKEY_LOCAL_MACHINE, + L"Software\\Microsoft\\Windows NT\\CurrentVersion\\" + L"Image File Execution Options\\{VxKexPropagationVirtualKey}", + KEY_READ | KEY_WRITE, + &KeyHandle); + + try { + KexSetupRegWriteI32(KeyHandle, L"GlobalFlag", FLG_APPLICATION_VERIFIER); + KexSetupRegWriteI32(KeyHandle, L"VerifierFlags", 0x80000000); + KexSetupRegWriteString(KeyHandle, L"VerifierDlls", L"KexDll.dll"); + } finally { + RegCloseKey(KeyHandle); + KeyHandle = NULL; + } + + // + // Enable VxKex for MSIEXEC. + // This step is not critical, so we do not fail if it doesn't succeed. + // + + KxCfgEnableVxKexForMsiexec(TRUE, KexSetupTransactionHandle); + + // + // Call subroutine to install VxKex files. + // + + KexSetupInstallFiles(); + + // + // Add uninstall entry. + // + + KexSetupWriteUninstallEntry(); + + // + // Register the .vxl file extension for VxlView.exe. + // + // HKEY_CLASSES_ROOT + // .vxl + // (Default) = REG_SZ "vxlfile" + // vxlfile + // shell + // open + // command + // (Default) = REG_SZ ""\VxlView.exe" "%1"" + // DefaultIcon + // (Default) = REG_SZ "\VxlView.exe,1" + // + + KexSetupCreateKey( + HKEY_CLASSES_ROOT, + L".vxl", + KEY_READ | KEY_WRITE, + &KeyHandle); + + try { + KexSetupRegWriteString( + KeyHandle, + NULL, + L"vxlfile"); + } finally { + RegCloseKey(KeyHandle); + KeyHandle = NULL; + } + + KexSetupCreateKey( + HKEY_CLASSES_ROOT, + L"vxlfile", + KEY_READ | KEY_WRITE, + &KeyHandle); + + try { + KexSetupRegWriteString( + KeyHandle, + NULL, + L"VxLog File"); + } finally { + RegCloseKey(KeyHandle); + KeyHandle = NULL; + } + + KexSetupCreateKey( + HKEY_CLASSES_ROOT, + L"vxlfile\\shell\\open\\command", + KEY_READ | KEY_WRITE, + &KeyHandle); + + try { + KexSetupFormatPath(TargetPath, L"\"%s\\VxlView.exe\" \"%%1\"", KexDir); + + KexSetupRegWriteString( + KeyHandle, + NULL, + TargetPath); + } finally { + RegCloseKey(KeyHandle); + KeyHandle = NULL; + } + + KexSetupCreateKey( + HKEY_CLASSES_ROOT, + L"vxlfile\\DefaultIcon", + KEY_READ | KEY_WRITE, + &KeyHandle); + + try { + // Note: Don't add extra quotes to this. It will make it stop working. + KexSetupFormatPath(TargetPath, L"%s\\VxlView.exe,1", KexDir); + + KexSetupRegWriteString( + KeyHandle, + NULL, + TargetPath); + } finally { + RegCloseKey(KeyHandle); + KeyHandle = NULL; + } + + // + // Register disk cleanup handler for .vxl files + // + + Success = KxCfgInstallDiskCleanupHandler( + KexDir, + UserLogDir, + KexSetupTransactionHandle); + + ASSERT (Success); + + // + // Register the shell extension, KexShlEx (and KexShl32 if 64bit OS). + // + // HKEY_CLASSES_ROOT + // CLSID + // {9AACA888-A5F5-4C01-852E-8A2005C1D45F} (*) + // InProcServer32 + // (Default) = REG_SZ "\KexShlEx.dll" + // ThreadingModel = REG_SZ "Apartment" + // exefile + // shellex + // PropertySheetHandlers + // KexShlEx Property Page (*) + // (Default) = REG_SZ "{9AACA888-A5F5-4C01-852E-8A2005C1D45F}" + // lnkfile + // shellex + // PropertySheetHandlers + // KexShlEx Property Page (*) + // (Default) = REG_SZ "{9AACA888-A5F5-4C01-852E-8A2005C1D45F}" + // Msi.Package + // shellex + // PropertySheetHandlers + // KexShlEx Property Page (*) + // (Default) = REG_SZ "{9AACA888-A5F5-4C01-852E-8A2005C1D45F}" + // + + KexSetupCreateKey( + HKEY_CLASSES_ROOT, + L"CLSID\\" CLSID_STRING_KEXSHLEX L"\\InProcServer32", + KEY_READ | KEY_WRITE, + &KeyHandle); + + try { + KexSetupFormatPath(TargetPath, L"%s\\KexShlEx.dll", KexDir); + KexSetupRegWriteString(KeyHandle, NULL, TargetPath); + KexSetupRegWriteString(KeyHandle, L"ThreadingModel", L"Apartment"); + } finally { + RegCloseKey(KeyHandle); + KeyHandle = NULL; + } + + if (Is64BitOS) { + // Register KexShl32.dll as a 32 bit shell extension. + + KexSetupCreateKey( + HKEY_CLASSES_ROOT, + L"Wow6432Node\\CLSID\\" CLSID_STRING_KEXSHLEX L"\\InProcServer32", + KEY_READ | KEY_WRITE, + &KeyHandle); + + try { + KexSetupFormatPath(TargetPath, L"%s\\KexShl32.dll", KexDir); + KexSetupRegWriteString(KeyHandle, NULL, TargetPath); + KexSetupRegWriteString(KeyHandle, L"ThreadingModel", L"Apartment"); + } finally { + RegCloseKey(KeyHandle); + KeyHandle = NULL; + } + } + + KexSetupCreateKey( + HKEY_CLASSES_ROOT, + L"exefile\\shellex\\PropertySheetHandlers\\KexShlEx Property Page", + KEY_READ | KEY_WRITE, + &KeyHandle); + + try { + KexSetupRegWriteString(KeyHandle, NULL, CLSID_STRING_KEXSHLEX); + } finally { + RegCloseKey(KeyHandle); + KeyHandle = NULL; + } + + KexSetupCreateKey( + HKEY_CLASSES_ROOT, + L"lnkfile\\shellex\\PropertySheetHandlers\\KexShlEx Property Page", + KEY_READ | KEY_WRITE, + &KeyHandle); + + try { + KexSetupRegWriteString(KeyHandle, NULL, CLSID_STRING_KEXSHLEX); + } finally { + RegCloseKey(KeyHandle); + KeyHandle = NULL; + } + + KexSetupCreateKey( + HKEY_CLASSES_ROOT, + L"Msi.Package\\shellex\\PropertySheetHandlers\\KexShlEx Property Page", + KEY_READ | KEY_WRITE, + &KeyHandle); + + try { + KexSetupRegWriteString(KeyHandle, NULL, CLSID_STRING_KEXSHLEX); + } finally { + RegCloseKey(KeyHandle); + KeyHandle = NULL; + } + + // + // Register Brower Helper Object for the Explorer CPIW bypass. + // This can be configured by the user using KexCfg. + // + // HKEY_CLASSES_ROOT + // CLSID + // {7EF224FC-1840-433C-9BCB-2951DE71DDBD} (*) + // InProcServer32 + // (Default) = REG_SZ "\CpiwBypa.dll" + // ThreadingModel = REG_SZ "Apartment" + // HKEY_LOCAL_MACHINE + // Software + // Microsoft + // Windows + // CurrentVersion + // Explorer + // Browser Helper Objects + // {7EF224FC-1840-433C-9BCB-2951DE71DDBD} (*) + // (Default) = REG_SZ "VxKex CPIW Version Check Bypass" + // + + KexSetupCreateKey( + HKEY_CLASSES_ROOT, + L"CLSID\\{7EF224FC-1840-433C-9BCB-2951DE71DDBD}\\InProcServer32", + KEY_READ | KEY_WRITE, + &KeyHandle); + + try { + KexSetupFormatPath(TargetPath, L"%s\\CpiwBypa.dll", KexDir); + KexSetupRegWriteString(KeyHandle, NULL, TargetPath); + KexSetupRegWriteString(KeyHandle, L"ThreadingModel", L"Apartment"); + } finally { + RegCloseKey(KeyHandle); + KeyHandle = NULL; + } + + if (Is64BitOS) { + KexSetupCreateKey( + HKEY_CLASSES_ROOT, + L"Wow6432Node\\CLSID\\{7EF224FC-1840-433C-9BCB-2951DE71DDBD}\\InProcServer32", + KEY_READ | KEY_WRITE, + &KeyHandle); + + try { + KexSetupFormatPath(TargetPath, L"%s\\CpiwBp32.dll", KexDir); + KexSetupRegWriteString(KeyHandle, NULL, TargetPath); + KexSetupRegWriteString(KeyHandle, L"ThreadingModel", L"Apartment"); + } finally { + RegCloseKey(KeyHandle); + KeyHandle = NULL; + } + } + + // This call will create the subkey in the Browser Helper Objects key. + Success = KxCfgEnableExplorerCpiwBypass( + TRUE, + KexSetupTransactionHandle); + + ASSERT (Success); + + // + // Add scheduled task for UAC-free configuration. + // We do this last because it can't be transacted. + // (well, it can, but not with the official task scheduler API). + // + + KexSetupAddKexCfgScheduledTask(); +} + +VOID KexSetupUpgrade( + VOID) +{ + HKEY VxKexKeyHandle; + + // + // 1. Uninstall Pre-Rewrite Version if present + // 2. Update VxKex Registry Key + // 3. Call Subroutine To Install VxKex Files + // 4. Update Uninstall Entry + // + + // + // If pre-rewrite version is present, we will do a full uninstall and reinstall. + // + + if (ExistingVxKexVersion < 0x80000000) { + KexSetupUninstall(); + KexSetupInstall(); + return; + } + + // + // Update the InstalledVersion in Vxkex HKLM key. + // Delete the DllRewrite key which was present in older versions + // but is no longer used. + // + + VxKexKeyHandle = KxCfgOpenVxKexRegistryKey( + FALSE, + KEY_READ | KEY_WRITE, + KexSetupTransactionHandle); + + if (!VxKexKeyHandle) { + ErrorBoxF(L"Setup was unable to open the VxKex HKLM registry key. %s", GetLastErrorAsString()); + RtlRaiseStatus(STATUS_KEXSETUP_FAILURE); + } + + try { + KexSetupRegWriteI32(VxKexKeyHandle, L"InstalledVersion", InstallerVxKexVersion); + + // + // Delete the DllRewrite key which was present in older versions, but is + // no longer wanted. + // + + KexSetupDeleteKey(VxKexKeyHandle, L"DllRewrite"); + } finally { + RegCloseKey(VxKexKeyHandle); + } + + // + // Call subroutine to install updated VxKex files. + // + + KexSetupInstallFiles(); + + // + // Update the uninstall entry. + // + + KexSetupWriteUninstallEntry(); +} + +// +// Call this function when all data has been gathered from the user and we +// are ready to do the install/upgrade/uninstall. +// +VOID KexSetupPerformActions( + VOID) +{ + NTSTATUS Status; + BOOLEAN Success; + + // this will happen if we are passed /HWND from being started elevated + // by a potentially non-elevated parent process + if (IsWindow(MainWindow)) { + HANDLE ParentProcess; + HANDLE ElevatedProcess; + ULONG ParentProcessId; + + // + // Give the parent process a handle to ourself so that he knows when + // we have exited (and can query the exit code). + // + // The OpenProcess call that we use to get a handle to our parent process + // will fail when a standard (non-administrator) account runs the + // installer and uses an admin password to start the installation. + // + // In order to work around this problem, we will try and enable the + // SeDebugPrivilege privilege. I'm not sure whether this is the best + // solution, but it works. + // + + { + HANDLE TokenHandle; + TOKEN_PRIVILEGES Privileges; + LUID Luid; + + Success = LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &Luid); + ASSERT (Success); + + if (!Success) { + goto FailDebugPrivilege; + } + + Success = OpenProcessToken( + GetCurrentProcess(), + TOKEN_ADJUST_PRIVILEGES, + &TokenHandle); + + ASSERT (Success); + + if (!Success) { + goto FailDebugPrivilege; + } + + Privileges.PrivilegeCount = 1; + Privileges.Privileges[0].Luid = Luid; + Privileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + + Success = AdjustTokenPrivileges( + TokenHandle, + FALSE, + &Privileges, + sizeof(Privileges), + NULL, + NULL); + + ASSERT (Success); + + CloseHandle(TokenHandle); + } + +FailDebugPrivilege: + + GetWindowThreadProcessId(MainWindow, &ParentProcessId); + + ParentProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, ParentProcessId); + ASSERT (ParentProcess != NULL); + + DuplicateHandle( + GetCurrentProcess(), + GetCurrentProcess(), + ParentProcess, + &ElevatedProcess, + SYNCHRONIZE | PROCESS_QUERY_LIMITED_INFORMATION, + FALSE, + 0); + + CloseHandle(ParentProcess); + + ASSERT (ElevatedProcess != NULL); + SendMessage(MainWindow, WM_USER + 1, 0, (LPARAM) ElevatedProcess); + } + + // + // If VxKex is already installed, we will get the existing KexDir. + // + + if (ExistingVxKexVersion) { + Success = KxCfgGetKexDir(KexDir, ARRAYSIZE(KexDir)); + + if (!Success) { + ErrorBoxF( + L"Setup was unable to determine the location of the existing VxKex installation. %s", + GetLastErrorAsString()); + + ExitProcess(STATUS_UNSUCCESSFUL); + } + } + + PathCchRemoveBackslash(KexDir, ARRAYSIZE(KexDir)); + + // + // Create a transaction for whatever action we are performing to ensure + // it is atomic. + // + + KexSetupTransactionHandle = CreateSimpleTransaction(L"KexSetup Transaction"); + + if (KexSetupTransactionHandle == INVALID_HANDLE_VALUE) { + ErrorBoxF( + L"Setup was unable to create a transaction for this operation. %s", + GetLastErrorAsString()); + ExitProcess(STATUS_UNSUCCESSFUL); + } + + RtlSetCurrentTransaction(KexSetupTransactionHandle); + + // + // Call a subroutine to perform the requested action. + // + + try { + switch (OperationMode) { + case OperationModeInstall: + KexSetupInstall(); + break; + case OperationModeUpgrade: + KexSetupUpgrade(); + break; + case OperationModeUninstall: + KexSetupUninstall(); + break; + default: + NOT_REACHED; + } + + // Accidentally calling a *Transacted file API will cause the + // transaction handle in the TEB to be set to NULL, so we will + // check for that situation here. + ASSERT (RtlGetCurrentTransaction() == KexSetupTransactionHandle); + KexSetupOkToCommitTransaction = TRUE; + } except (GetExceptionCode() == STATUS_KEXSETUP_FAILURE) { + KexSetupOkToCommitTransaction = FALSE; + } + + if (KexSetupOkToCommitTransaction) { + Status = NtCommitTransaction(KexSetupTransactionHandle, TRUE); + Success = NT_SUCCESS(Status); + + if (!Success) { + ErrorBoxF(L"Setup failed to commit the transaction. %s", NtStatusAsString(Status)); + } + } else { + Success = FALSE; + Status = NtRollbackTransaction(KexSetupTransactionHandle, TRUE); + } + + ASSERT (NT_SUCCESS(Status)); + SafeClose(KexSetupTransactionHandle); + RtlSetCurrentTransaction(NULL); + + if (Success) { + ExitProcess(STATUS_SUCCESS); + } else { + ExitProcess(STATUS_UNSUCCESSFUL); + } +} \ No newline at end of file diff --git a/KexSetup/prereq.c b/KexSetup/prereq.c new file mode 100644 index 0000000..a8f20ad --- /dev/null +++ b/KexSetup/prereq.c @@ -0,0 +1,225 @@ +#include "buildcfg.h" +#include "kexsetup.h" +#include + +DEFINE_GUID(IID_IDXGIFactory2, 0x50C83A1C, 0xE072, 0x4C48, 0x87, 0xB0, 0x36, 0x30, 0xFA, 0x36, 0xA6, 0xD0); + +// +// Check for the presence of the following three APIs inside kernel32.dll: +// +// - AddDllDirectory +// - RemoveDllDirectory +// - SetDefaultDllDirectories +// +STATIC BOOLEAN IsDllDirectoriesUpdatePresent( + VOID) +{ + HMODULE Kernel32; + ULONG Index; + PCSTR ApiNames[] = { + "AddDllDirectory", + "RemoveDllDirectory", + "SetDefaultDllDirectories" + }; + + Kernel32 = GetModuleHandle(L"kernel32.dll"); + ASSERT (Kernel32 != NULL); + + if (!Kernel32) { + return FALSE; + } + + for (Index = 0; Index < ARRAYSIZE(ApiNames); ++Index) { + if (GetProcAddress(Kernel32, ApiNames[Index]) == NULL) { + return FALSE; + } + } + + return TRUE; +} + +// +// Check for the ability of CreateDXGIFactory1 to support the IDXGIFactory2 +// interface. +// +STATIC BOOLEAN IsPlatformUpdatePresent( + VOID) +{ + HRESULT Result; + HMODULE Dxgi; + HRESULT (WINAPI *pCreateDXGIFactory1) (REFIID, IUnknown **); + IUnknown *DXGIFactory2; + + DXGIFactory2 = NULL; + + Dxgi = LoadLibrary(L"dxgi.dll"); + ASSERT (Dxgi != NULL); + + if (!Dxgi) { + return FALSE; + } + + pCreateDXGIFactory1 = (HRESULT (WINAPI *) (REFIID, IUnknown **)) GetProcAddress( + Dxgi, + "CreateDXGIFactory1"); + + ASSERT (pCreateDXGIFactory1 != NULL); + + if (!pCreateDXGIFactory1) { + FreeLibrary(Dxgi); + return FALSE; + } + + Result = pCreateDXGIFactory1(&IID_IDXGIFactory2, &DXGIFactory2); + if (FAILED(Result) || !DXGIFactory2) { + FreeLibrary(Dxgi); + return FALSE; + } + + SafeRelease(DXGIFactory2); + return TRUE; +} + +BOOLEAN IsServicePack1Present( + VOID) +{ + return (NtCurrentPeb()->OSBuildNumber > 7600); +} + +VOID KexSetupCheckForPrerequisites( + VOID) +{ + ULONG ErrorCode; + BOOLEAN ServicePack1Present; + BOOLEAN DllDirectoriesUpdatePresent; + BOOLEAN PlatformUpdatePresent; + BOOL DontShowAgain; + ULONG DataCb; + + ServicePack1Present = FALSE; + DllDirectoriesUpdatePresent = FALSE; + PlatformUpdatePresent = FALSE; + + // + // If the user has previously indicated that he doesn't want to see this + // warning, then don't check anything. + // + + DataCb = sizeof(DontShowAgain); + + ErrorCode = RegGetValue( + HKEY_CURRENT_USER, + L"Software\\VXsoft\\VxKex", + L"SetupPrerequisitesDontShowAgain", + RRF_RT_REG_DWORD, + NULL, + &DontShowAgain, + &DataCb); + + if (ErrorCode == ERROR_SUCCESS && DontShowAgain) { + return; + } + + // + // Check for Service Pack 1. + // + + ServicePack1Present = IsServicePack1Present(); + + // + // Check for KB2533623 (DllDirectories update) and KB2670838 + // (Platform Update). + // + + DllDirectoriesUpdatePresent = IsDllDirectoriesUpdatePresent(); + PlatformUpdatePresent = IsPlatformUpdatePresent(); + + // + // If any of the prerequisites were not found, inform the user and ask + // him whether he wants to cancel setup. + // + + unless (ServicePack1Present && DllDirectoriesUpdatePresent && PlatformUpdatePresent) { + HRESULT Result; + WCHAR MainText[1024]; + TASKDIALOGCONFIG TaskDialogConfig; + TASKDIALOG_BUTTON Buttons[] = { + {IDCANCEL, L"Cancel installation"}, + {IDOK, L"Continue installation anyway\n" + L"Without the prerequisites listed above, be aware that some " + L"applications will not work, even with VxKex."}, + }; + + INT UserSelection; + + StringCchCopy( + MainText, + ARRAYSIZE(MainText), + L"Setup has detected that the following prerequisites were not installed on " + L"your computer:\r\n"); + + if (!ServicePack1Present) { + StringCchCat( + MainText, + ARRAYSIZE(MainText), + L"\r\n • Service Pack 1 (SP1) for Windows® 7"); + } + + if (!DllDirectoriesUpdatePresent) { + StringCchCat( + MainText, + ARRAYSIZE(MainText), + L"\r\n • Update KB2533623 (DllDirectories update)"); + } + + if (!PlatformUpdatePresent) { + StringCchCat( + MainText, + ARRAYSIZE(MainText), + L"\r\n • Update KB2670838 (Platform Update)"); + } + + RtlZeroMemory(&TaskDialogConfig, sizeof(TaskDialogConfig)); + TaskDialogConfig.cbSize = sizeof(TaskDialogConfig); + TaskDialogConfig.dwFlags = TDF_ALLOW_DIALOG_CANCELLATION | + TDF_USE_COMMAND_LINKS | + TDF_POSITION_RELATIVE_TO_WINDOW; + TaskDialogConfig.pszWindowTitle = FRIENDLYAPPNAME; + TaskDialogConfig.pszMainIcon = TD_WARNING_ICON; + TaskDialogConfig.pszMainInstruction = L"System requirements not met"; + TaskDialogConfig.pszContent = MainText; + TaskDialogConfig.cButtons = ARRAYSIZE(Buttons); + TaskDialogConfig.pButtons = Buttons; + TaskDialogConfig.nDefaultButton = IDOK; + TaskDialogConfig.pszVerificationText= L"Don't show this warning again"; + + Result = TaskDialogIndirect( + &TaskDialogConfig, + &UserSelection, + NULL, + &DontShowAgain); + + ASSERT (SUCCEEDED(Result)); + + if (FAILED(Result)) { + return; + } + + if (UserSelection == IDCANCEL) { + // User cancelled the installation. + ExitProcess(0); + } + + if (DontShowAgain) { + ErrorCode = RegSetKeyValue( + HKEY_CURRENT_USER, + L"Software\\VXsoft\\VxKex", + L"SetupPrerequisitesDontShowAgain", + REG_DWORD, + &DontShowAgain, + sizeof(DontShowAgain)); + + ASSERT (ErrorCode == ERROR_SUCCESS); + } + } +} \ No newline at end of file diff --git a/KexSetup/resource.h b/KexSetup/resource.h new file mode 100644 index 0000000..49afe03 --- /dev/null +++ b/KexSetup/resource.h @@ -0,0 +1,45 @@ +#define MAIN_WINDOW_WIDTH 333 +#define MAIN_WINDOW_HEIGHT 222 + +#define IDSTATIC -1 + +#define IDI_APPICON 100 + +#define IDD_MAINWINDOW 101 + +#define IDBACK 102 +#define IDNEXT 103 +#define IDCANCEL2 104 +#define IDHDRTEXT 105 +#define IDHDRSUBTEXT 106 +#define IDPROGRESS 107 + +#define IDS1GUIDETEXT 110 +#define IDS1DIRPATH 111 +#define IDS1BROWSE 112 +#define IDS1SPACEREQ 113 +#define IDS1SPACEAVAIL 114 +#define IDS1PDBNOTICE 115 + +#define IDS2GUIDETEXT 120 + +#define IDS3GUIDETEXT 130 +#define IDS3KEXCFG 131 +#define IDS3OPENGUIDE 132 + +#define IDS4GUIDETEXT 140 +#define IDS4GUIDETEXT2 141 +#define IDS4PRESERVECONFIG 142 + +#define IDS5GUIDETEXT 150 + +#define IDS6GUIDETEXT 160 +#define IDS6GUIDETEXT2 161 + +#define IDS7GUIDETEXT 170 +#define IDS7GUIDETEXT2 171 +#define IDS7CHANGELOG 172 + +#define IDS8GUIDETEXT 180 + +#define IDS9GUIDETEXT 190 diff --git a/KexSetup/util.c b/KexSetup/util.c new file mode 100644 index 0000000..d8cb44d --- /dev/null +++ b/KexSetup/util.c @@ -0,0 +1,566 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// util.c +// +// Abstract: +// +// This file contains miscellaneous utility functions for VxKex. +// +// Author: +// +// vxiiduu (02-Feb-2024) +// +// Environment: +// +// Win32, without any vxkex support components +// +// Revision History: +// +// vxiiduu 02-Feb-2024 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "kexsetup.h" +#include + +BOOLEAN IsWow64( + VOID) +{ + if (KexIs64BitBuild) { + return FALSE; + } else { + BOOLEAN Success; + BOOL CurrentProcessIsWow64Process; + + Success = IsWow64Process(GetCurrentProcess(), &CurrentProcessIsWow64Process); + + if (Success) { + return CurrentProcessIsWow64Process; + } else { + return FALSE; + } + } +} + +// InstallationPath must be a pointer to a buffer of size MAX_PATH characters. +VOID GetDefaultInstallationLocation( + IN PWSTR InstallationPath) +{ + PCWSTR FailsafeDefault = L"C:\\Program Files\\VxKex"; + DWORD EnvironmentStringLength; + + EnvironmentStringLength = ExpandEnvironmentStrings(L"%ProgramW6432%", InstallationPath, MAX_PATH); + if (EnvironmentStringLength == 0) { + EnvironmentStringLength = ExpandEnvironmentStrings(L"%ProgramFiles%", InstallationPath, MAX_PATH); + + if (EnvironmentStringLength == 0) { + goto FailSafe; + } + } + + if (PathIsRelative(InstallationPath)) { + goto FailSafe; + } + + PathCchAppend(InstallationPath, MAX_PATH, L"VxKex"); + return; + +FailSafe: + StringCchCopy(InstallationPath, MAX_PATH, FailsafeDefault); + return; +} + +VOID KexSetupCreateKey( + IN HKEY KeyHandle, + IN PCWSTR SubKey, + IN REGSAM DesiredAccess, + OUT PHKEY KeyHandleOut) +{ + ULONG ErrorCode; + + ASSERT (KexSetupTransactionHandle != NULL); + ASSERT (KexSetupTransactionHandle != INVALID_HANDLE_VALUE); + ASSERT (KeyHandle != NULL); + ASSERT (KeyHandle != INVALID_HANDLE_VALUE); + ASSERT (SubKey != NULL); + ASSERT (DesiredAccess != 0); + ASSERT (KeyHandleOut != NULL); + + ErrorCode = RegCreateKeyTransacted( + KeyHandle, + SubKey, + 0, + NULL, + 0, + DesiredAccess | KEY_WOW64_64KEY, + NULL, + KeyHandleOut, + NULL, + KexSetupTransactionHandle, + NULL); + + if (ErrorCode != ERROR_SUCCESS) { + PCWSTR BaseKeyName; + + switch ((ULONG_PTR) KeyHandle) { + case HKEY_LOCAL_MACHINE: + BaseKeyName = L"HKEY_LOCAL_MACHINE"; + break; + case HKEY_CURRENT_USER: + BaseKeyName = L"HKEY_CURRENT_USER"; + break; + default: + BaseKeyName = L"UNKNOWN"; + break; + } + + ErrorBoxF( + L"Failed to create or open registry key \"%s\\%s\". %s", + BaseKeyName, + SubKey, + Win32ErrorAsString(ErrorCode)); + + RtlRaiseStatus(STATUS_KEXSETUP_FAILURE); + } +} + +VOID KexSetupDeleteKey( + IN HKEY KeyHandle, + IN PCWSTR Subkey OPTIONAL) +{ + HKEY NewKeyHandle; + NTSTATUS Status; + ULONG ErrorCode; + + ASSERT (KeyHandle != NULL); + ASSERT (KeyHandle != INVALID_HANDLE_VALUE); + + ErrorCode = RegOpenKeyTransacted( + KeyHandle, + Subkey, + 0, + KEY_READ | KEY_WRITE | DELETE | KEY_WOW64_64KEY, + &NewKeyHandle, + KexSetupTransactionHandle, + NULL); + + if (ErrorCode == ERROR_FILE_NOT_FOUND) { + // No problem - key is already gone. + return; + } + + if (ErrorCode != ERROR_SUCCESS) { + ErrorBoxF(L"Failed to open registry key for deletion. %s", Win32ErrorAsString(ErrorCode)); + RtlRaiseStatus(STATUS_KEXSETUP_FAILURE); + } + + ErrorCode = RegDeleteTree(NewKeyHandle, NULL); + if (ErrorCode != ERROR_SUCCESS) { + RegCloseKey(NewKeyHandle); + ErrorBoxF(L"Failed to delete keys and subkeys. %s", Win32ErrorAsString(ErrorCode)); + RtlRaiseStatus(STATUS_KEXSETUP_FAILURE); + } + + Status = NtDeleteKey(NewKeyHandle); + ErrorCode = RtlNtStatusToDosError(Status); + + SafeClose(NewKeyHandle); + + if (ErrorCode != ERROR_SUCCESS) { + ErrorBoxF(L"Failed to delete key. %s", Win32ErrorAsString(ErrorCode)); + RtlRaiseStatus(STATUS_KEXSETUP_FAILURE); + } +} + +VOID KexSetupRegWriteI32( + IN HKEY KeyHandle, + IN PCWSTR ValueName, + IN ULONG Data) +{ + ULONG ErrorCode; + + ErrorCode = RegWriteI32(KeyHandle, NULL, ValueName, Data); + + if (ErrorCode != ERROR_SUCCESS) { + ErrorBoxF( + L"Setup was unable to write to the registry value %s. %s", + ValueName, Win32ErrorAsString(ErrorCode)); + + RtlRaiseStatus(STATUS_KEXSETUP_FAILURE); + } +} + +VOID KexSetupRegWriteString( + IN HKEY KeyHandle, + IN PCWSTR ValueName, + IN PCWSTR Data) +{ + ULONG ErrorCode; + + ErrorCode = RegWriteString(KeyHandle, NULL, ValueName, Data); + + if (ErrorCode != ERROR_SUCCESS) { + ErrorBoxF( + L"Setup was unable to write to the registry value %s. %s", + ValueName, Win32ErrorAsString(ErrorCode)); + + RtlRaiseStatus(STATUS_KEXSETUP_FAILURE); + } +} + +VOID KexSetupRegReadString( + IN HKEY KeyHandle, + IN PCWSTR ValueName, + OUT PWSTR Buffer, + IN ULONG BufferCch) +{ + ULONG ErrorCode; + + ErrorCode = RegReadString(KeyHandle, NULL, ValueName, Buffer, BufferCch); + + if (ErrorCode != ERROR_SUCCESS) { + ErrorBoxF( + L"Setup was unable to read the registry value %s. %s", + ValueName, Win32ErrorAsString(ErrorCode)); + + RtlRaiseStatus(STATUS_KEXSETUP_FAILURE); + } +} + +// This function applies the ACL from KexDir to the specified file. +VOID KexSetupApplyAclToFile( + IN PCWSTR FilePath) +{ + ULONG ErrorCode; + STATIC BOOLEAN AlreadyInitialized = FALSE; + STATIC PSECURITY_DESCRIPTOR KexDirSecurity = NULL; + STATIC PACL KexDirDacl = NULL; + + if (!AlreadyInitialized) { + ErrorCode = GetNamedSecurityInfo( + KexDir, + SE_FILE_OBJECT, + DACL_SECURITY_INFORMATION, + NULL, + NULL, + &KexDirDacl, + NULL, + &KexDirSecurity); + + ASSERT (ErrorCode == ERROR_SUCCESS); + + if (ErrorCode == ERROR_SUCCESS) { + AlreadyInitialized = TRUE; + } else { + return; + } + } + + ErrorCode = SetNamedSecurityInfo( + (PWSTR) FilePath, + SE_FILE_OBJECT, + DACL_SECURITY_INFORMATION, + NULL, + NULL, + KexDirDacl, + NULL); + + ASSERT (ErrorCode == ERROR_SUCCESS); +} + +VOID KexSetupSupersedeFile( + IN PCWSTR SourceFile, + IN PCWSTR TargetFile) +{ + BOOLEAN Success; + + Success = SupersedeFile(SourceFile, TargetFile, KexSetupTransactionHandle); + + if (!Success) { + ErrorBoxF( + L"Failed to move \"%s\" to \"%s\". %s", + SourceFile, + TargetFile, + GetLastErrorAsString()); + + RtlRaiseStatus(STATUS_KEXSETUP_FAILURE); + } + + // + // Apply ACLs from the target directory to the target file. + // + + KexSetupApplyAclToFile(TargetFile); +} + +// Buffer must have a size of at least MAX_PATH characters. +VOID KexSetupFormatPath( + OUT PWSTR Buffer, + IN PCWSTR Format, + IN ...) +{ + HRESULT Result; + ARGLIST ArgList; + + va_start(ArgList, Format); + + Result = StringCchVPrintf( + Buffer, + MAX_PATH, + Format, + ArgList); + + va_end(ArgList); + + if (FAILED(Result)) { + ErrorBoxF( + L"A path is too long. Ensure the folder you have chosen to install VxKex into " + L"is not nested too deeply."); + + RtlRaiseStatus(STATUS_KEXSETUP_FAILURE); + } +} + +VOID KexSetupMoveFileSpecToDirectory( + IN PCWSTR FileSpec, + IN PCWSTR TargetDirectoryPath) +{ + HANDLE FindHandle; + WIN32_FIND_DATA FindData; + WCHAR SourceDirectoryPath[MAX_PATH]; + WCHAR SourcePath[MAX_PATH]; + WCHAR TargetPath[MAX_PATH]; + + ASSERT (FileSpec != NULL); + ASSERT (TargetDirectoryPath != NULL); + + StringCchCopy(SourceDirectoryPath, ARRAYSIZE(SourceDirectoryPath), FileSpec); + PathCchRemoveFileSpec(SourceDirectoryPath, ARRAYSIZE(SourceDirectoryPath)); + + FindHandle = FindFirstFileEx( + FileSpec, + FindExInfoBasic, + &FindData, + FindExSearchNameMatch, + NULL, + 0); + + if (FindHandle == INVALID_HANDLE_VALUE) { + ErrorBoxF(L"VxKex setup files could not be found. %s", GetLastErrorAsString()); + RtlRaiseStatus(STATUS_KEXSETUP_FAILURE); + } + + SetLastError(ERROR_SUCCESS); + + do { + // Check if the FindNextFile at the end of the loop reported some kind of error. + if (GetLastError() != ERROR_SUCCESS) { + ErrorBoxF(L"Failed to move VxKex files. %s", GetLastErrorAsString()); + RtlRaiseStatus(STATUS_KEXSETUP_FAILURE); + } + + if (FindData.cFileName[0] == '.') { + if (FindData.cFileName[1] == '\0') { + continue; + } else if (FindData.cFileName[1] == '.') { + if (FindData.cFileName[2] == '\0') { + continue; + } + } + } + + KexSetupFormatPath(SourcePath, L"%s\\%s", SourceDirectoryPath, FindData.cFileName); + KexSetupFormatPath(TargetPath, L"%s\\%s", TargetDirectoryPath, FindData.cFileName); + KexSetupSupersedeFile(SourcePath, TargetPath); + + SetLastError(ERROR_SUCCESS); + } until (!FindNextFile(FindHandle, &FindData) && GetLastError() == ERROR_NO_MORE_FILES); +} + +VOID KexSetupCreateDirectory( + IN PCWSTR DirectoryPath) +{ + BOOLEAN Success; + + ASSERT (DirectoryPath != NULL); + + Success = CreateDirectory(DirectoryPath, NULL); + if (!Success) { + if (GetLastError() == ERROR_ALREADY_EXISTS) { + return; + } + + ErrorBoxF(L"Failed to create directory: \"%s\". %s", DirectoryPath, GetLastErrorAsString()); + RtlRaiseStatus(STATUS_KEXSETUP_FAILURE); + } +} + +BOOLEAN KexSetupDeleteFile( + IN PCWSTR FilePath) +{ + BOOLEAN Success; + + Success = DeleteFile(FilePath); + + if (!Success) { + ULONG RandomIdentifier; + WCHAR NewFileName[MAX_PATH]; + + // + // Failed to delete the file. + // Try to rename the file to something else and then schedule its deletion. + // + + RandomIdentifier = GetTickCount(); + + StringCchPrintf( + NewFileName, + ARRAYSIZE(NewFileName), + L"%s.old_%04u", FilePath, RandomIdentifier); + + Success = MoveFile(FilePath, NewFileName); + if (Success) { + FilePath = NewFileName; + } + + RtlSetCurrentTransaction(NULL); + + Success = MoveFileTransacted( + FilePath, + NULL, + NULL, + NULL, + MOVEFILE_DELAY_UNTIL_REBOOT, + KexSetupTransactionHandle); + + RtlSetCurrentTransaction(KexSetupTransactionHandle); + + if (!Success) { + return FALSE; + } + } + + return TRUE; +} + +BOOLEAN KexSetupRemoveDirectoryRecursive( + IN PCWSTR DirectoryPath) +{ + ULONG DirectoryPathCch; + ULONG DirectoryPathSpecCch; + PWSTR DirectoryPathSpec; + + HANDLE FindHandle; + WIN32_FIND_DATA FindData; + + DirectoryPathCch = (ULONG) wcslen(DirectoryPath) + 1; + DirectoryPathSpecCch = DirectoryPathCch + 2; + DirectoryPathSpec = StackAlloc(WCHAR, DirectoryPathSpecCch); + StringCchCopy(DirectoryPathSpec, DirectoryPathSpecCch, DirectoryPath); + PathCchAppend(DirectoryPathSpec, DirectoryPathSpecCch, L"*"); + + FindHandle = FindFirstFileEx( + DirectoryPathSpec, + FindExInfoBasic, + &FindData, + FindExSearchNameMatch, + NULL, + FIND_FIRST_EX_LARGE_FETCH); + + if (FindHandle == INVALID_HANDLE_VALUE) { + return FALSE; + } + + do { + WCHAR FileFullPath[MAX_PATH]; + + // skip . and .. directories + if (FindData.cFileName[0] == '.') { + if (FindData.cFileName[1] == '.') { + if (FindData.cFileName[2] == '\0') { + continue; + } + } else if (FindData.cFileName[1] == '\0') { + continue; + } + } + + if (FindData.dwFileAttributes == FILE_ATTRIBUTE_SYSTEM) { + // Better not delete this. + continue; + } + + StringCchCopy(FileFullPath, ARRAYSIZE(FileFullPath), DirectoryPath); + PathCchAppend(FileFullPath, ARRAYSIZE(FileFullPath), FindData.cFileName); + + if (FindData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY) { + // Recurse into directory. + KexSetupRemoveDirectoryRecursive(FileFullPath); + continue; + } + + // Normal file - delete it + KexSetupDeleteFile(FileFullPath); + } until (!FindNextFile(FindHandle, &FindData) && GetLastError() == ERROR_NO_MORE_FILES); + + // Remove the directory itself, which should now hopefully be empty. + return RemoveDirectory(DirectoryPath); +} + +BOOLEAN KexSetupDeleteFilesBySpec( + IN PCWSTR FileSpec) +{ + HANDLE FindHandle; + WIN32_FIND_DATA FindData; + BOOLEAN Success; + + FindHandle = FindFirstFileEx( + FileSpec, + FindExInfoBasic, + &FindData, + FindExSearchNameMatch, + NULL, + FIND_FIRST_EX_LARGE_FETCH); + + if (FindHandle == INVALID_HANDLE_VALUE) { + return FALSE; + } + + Success = 0xff; + + do { + WCHAR FileFullPath[MAX_PATH]; + + // skip . and .. directories + if (FindData.cFileName[0] == '.') { + if (FindData.cFileName[1] == '.') { + if (FindData.cFileName[2] == '\0') { + continue; + } + } else if (FindData.cFileName[1] == '\0') { + continue; + } + } + + if (FindData.dwFileAttributes == FILE_ATTRIBUTE_SYSTEM) { + // Better not delete this. + Success = FALSE; + continue; + } + + StringCchCopy(FileFullPath, ARRAYSIZE(FileFullPath), FileSpec); + PathCchRemoveFileSpec(FileFullPath, ARRAYSIZE(FileFullPath)); + PathCchAppend(FileFullPath, ARRAYSIZE(FileFullPath), FindData.cFileName); + + if (FindData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY) { + continue; + } + + // Normal file - delete it + Success &= KexSetupDeleteFile(FileFullPath); + } until (!FindNextFile(FindHandle, &FindData) && GetLastError() == ERROR_NO_MORE_FILES); + + return Success; +} \ No newline at end of file diff --git a/KexSetup/version.c b/KexSetup/version.c new file mode 100644 index 0000000..1e1cdca --- /dev/null +++ b/KexSetup/version.c @@ -0,0 +1,47 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// version.c +// +// Abstract: +// +// This file contains functions which query the currently installed version +// of VxKex. +// +// Author: +// +// vxiiduu (02-Feb-2024) +// +// Environment: +// +// Win32, without any vxkex support components +// +// Revision History: +// +// vxiiduu 02-Feb-2024 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "kexsetup.h" + +// Returns 0 for not installed. +ULONG KexSetupGetInstalledVersion( + VOID) +{ + HKEY KeyHandle; + ULONG InstalledVersion; + + KeyHandle = KxCfgOpenVxKexRegistryKey(FALSE, KEY_READ, NULL); + if (!KeyHandle) { + KeyHandle = KxCfgOpenLegacyVxKexRegistryKey(FALSE, KEY_READ, NULL); + if (!KeyHandle) { + return 0; + } + } + + RegReadI32(KeyHandle, NULL, L"InstalledVersion", &InstalledVersion); + SafeClose(KeyHandle); + + return InstalledVersion; +} \ No newline at end of file diff --git a/KexShlEx/KexShlEx.def b/KexShlEx/KexShlEx.def new file mode 100644 index 0000000..5fe838b --- /dev/null +++ b/KexShlEx/KexShlEx.def @@ -0,0 +1,7 @@ +LIBRARY KexShlEx.dll +EXPORTS + DllCanUnloadNow PRIVATE + DllGetClassObject PRIVATE + DllRegisterServer PRIVATE + DllUnregisterServer PRIVATE + DllInstall PRIVATE \ No newline at end of file diff --git a/KexShlEx/KexShlEx.h b/KexShlEx/KexShlEx.h new file mode 100644 index 0000000..7f40c18 --- /dev/null +++ b/KexShlEx/KexShlEx.h @@ -0,0 +1,129 @@ +#pragma once + +#include +#include +#include + +#include + +typedef struct { + IShellExtInitVtbl *ShellExtInitVtbl; + IShellPropSheetExtVtbl *ShellPropSheetExtVtbl; + + LONG RefCount; + WCHAR ExeFullPath[MAX_PATH]; +} IKexShlEx; + +typedef struct { + PCWSTR ExeFullPath; + BOOLEAN SettingsChanged; +} TYPEDEF_TYPE_NAME(KEXSHLEX_PROPSHEET_DATA); + +// +// lnkfile.c +// + +HRESULT GetTargetFromLnkfile( + IN OUT PWSTR FileName); + +// +// ckxshlex.c +// + +HRESULT STDMETHODCALLTYPE CKexShlEx_QueryInterface( + IN IKexShlEx *This, + IN REFIID RefIID, + OUT PPVOID ObjectOut); + +HRESULT STDMETHODCALLTYPE CKexShlEx_QueryInterface_thunk0( + IN IShellExtInit *This, + IN REFIID RefIID, + OUT PPVOID ObjectOut); + +HRESULT STDMETHODCALLTYPE CKexShlEx_QueryInterface_thunk1( + IN IShellPropSheetExt *This, + IN REFIID RefIID, + OUT PPVOID ObjectOut); + +ULONG STDMETHODCALLTYPE CKexShlEx_AddRef( + IN IKexShlEx *This); + +ULONG STDMETHODCALLTYPE CKexShlEx_AddRef_thunk0( + IN IShellExtInit *This); + +ULONG STDMETHODCALLTYPE CKexShlEx_AddRef_thunk1( + IN IShellPropSheetExt *This); + +ULONG STDMETHODCALLTYPE CKexShlEx_Release( + IN IKexShlEx *This); + +ULONG STDMETHODCALLTYPE CKexShlEx_Release_thunk0( + IN IShellExtInit *This); + +ULONG STDMETHODCALLTYPE CKexShlEx_Release_thunk1( + IN IShellPropSheetExt *This); + +HRESULT STDMETHODCALLTYPE CKexShlEx_Initialize( + IN IKexShlEx *This, + IN LPCITEMIDLIST FolderIdList OPTIONAL, + IN LPDATAOBJECT DataObject, + IN HKEY ProgIdKey); + +HRESULT STDMETHODCALLTYPE CKexShlEx_AddPages( + IN IKexShlEx *This, + IN LPFNADDPROPSHEETPAGE AddPage, + IN LPARAM LParam); + +HRESULT STDMETHODCALLTYPE CKexShlEx_ReplacePage( + IN IKexShlEx *This, + IN UINT PageId, + IN LPFNADDPROPSHEETPAGE ReplacePage, + IN LPARAM LParam); + +// +// clsfctry.c +// + +HRESULT STDMETHODCALLTYPE CClassFactory_QueryInterface( + IN IClassFactory *This, + IN REFIID RefIID, + OUT PPVOID ObjectOut); + +ULONG STDMETHODCALLTYPE CClassFactory_AddRef( + IN IClassFactory *This); + +ULONG STDMETHODCALLTYPE CClassFactory_Release( + IN IClassFactory *This); + +HRESULT STDMETHODCALLTYPE CClassFactory_CreateInstance( + IN IClassFactory *This, + IN IUnknown *OuterIUnknown OPTIONAL, + IN REFIID RefIID, + OUT PPVOID ObjectOut); + +HRESULT STDMETHODCALLTYPE CClassFactory_LockServer( + IN IClassFactory *This, + IN BOOL Lock); + +// +// dllmain.c +// + +EXTERN HMODULE DllHandle; +EXTERN LONG DllReferenceCount; +EXTERN CONST IKexShlEx IKexShlExTemplate; + +// +// gui.c +// + +INT_PTR CALLBACK DialogProc( + IN HWND Window, + IN UINT Message, + IN WPARAM WParam, + IN LPARAM LParam); + +UINT WINAPI PropSheetCallbackProc( + IN HWND Window, + IN UINT Message, + IN OUT LPPROPSHEETPAGE PropSheetPage); \ No newline at end of file diff --git a/KexShlEx/KexShlEx.rc b/KexShlEx/KexShlEx.rc new file mode 100644 index 0000000..c9ff8d3 Binary files /dev/null and b/KexShlEx/KexShlEx.rc differ diff --git a/KexShlEx/KexShlEx.vcxproj b/KexShlEx/KexShlEx.vcxproj new file mode 100644 index 0000000..45eb5c8 --- /dev/null +++ b/KexShlEx/KexShlEx.vcxproj @@ -0,0 +1,244 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {0C454599-73FB-4F57-B8C9-0BE68AF3110E} + Win32Proj + KexShlEx + + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + + + + + + + + + + + + + + + + + false + false + + + false + false + + + false + false + + + false + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + true + false + false + Default + false + MultiThreadedDebug + true + ProgramDatabase + StdCall + CompileAsC + + + Windows + true + + + KexShlEx.def + $(SolutionDir)\00-Import Libraries;$(TargetDir) + true + + + $(SolutionDir)\00-Common Headers + + + + + + + Level3 + Disabled + WIN32;_WIN64;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + true + false + false + Default + false + MultiThreadedDebug + true + ProgramDatabase + StdCall + CompileAsC + + + Windows + true + + + KexShlEx.def + $(SolutionDir)\00-Import Libraries;$(TargetDir) + true + + + $(SolutionDir)\00-Common Headers + + + + + Level3 + + + MinSpace + true + true + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + true + false + false + Default + false + MultiThreaded + true + ProgramDatabase + StdCall + CompileAsC + OnlyExplicitInline + Size + true + + + Windows + true + true + true + + + KexShlEx.def + $(SolutionDir)\00-Import Libraries;$(TargetDir) + true + + + $(SolutionDir)\00-Common Headers + + + + + Level3 + + + MinSpace + true + true + WIN32;_WIN64;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + true + false + false + Default + false + MultiThreaded + true + ProgramDatabase + StdCall + CompileAsC + OnlyExplicitInline + Size + true + + + Windows + true + true + true + + + KexShlEx.def + $(SolutionDir)\00-Import Libraries;$(TargetDir) + true + + + $(SolutionDir)\00-Common Headers + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/KexShlEx/KexShlEx.vcxproj.filters b/KexShlEx/KexShlEx.vcxproj.filters new file mode 100644 index 0000000..071a916 --- /dev/null +++ b/KexShlEx/KexShlEx.vcxproj.filters @@ -0,0 +1,55 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + Resource Files + + + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/KexShlEx/buildcfg.h b/KexShlEx/buildcfg.h new file mode 100644 index 0000000..3a1a003 --- /dev/null +++ b/KexShlEx/buildcfg.h @@ -0,0 +1,6 @@ +#pragma once + +#define FRIENDLYAPPNAME L"VxKex Configuration Properties" +#define KEX_TARGET_TYPE_DLL +#define KEX_COMPONENT L"KexShlEx" +#define KEX_ENV_WIN32 diff --git a/KexShlEx/ckxshlex.c b/KexShlEx/ckxshlex.c new file mode 100644 index 0000000..6edbea6 --- /dev/null +++ b/KexShlEx/ckxshlex.c @@ -0,0 +1,289 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// ckxshlex.c +// +// Abstract: +// +// Implements the IKexShlEx (i.e. IShellExtInit and IShellPropSheetExt) +// interfaces. +// +// Ignore the standard COM crap at the top of the file, the functions of +// interest are: +// +// CKexShlEx_Initialize +// CKexShlEx_AddPages +// +// Author: +// +// vxiiduu (08-Feb-2024) +// +// Environment: +// +// Inside explorer.exe +// +// Revision History: +// +// vxiiduu 08-Feb-2024 Initial creation. +// vxiiduu 14-Mar-2024 Fix a multiselect-related bug. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "KexShlEx.h" +#include "resource.h" + +HRESULT STDMETHODCALLTYPE CKexShlEx_QueryInterface( + IN IKexShlEx *This, + IN REFIID RefIID, + OUT PPVOID ObjectOut) +{ + ASSERT (This != NULL); + ASSERT (RefIID != NULL); + ASSERT (ObjectOut != NULL); + + if (IsEqualIID(RefIID, &IID_IUnknown)) { + *ObjectOut = This; + } else if (IsEqualIID(RefIID, &IID_IShellExtInit)) { + *ObjectOut = &This->ShellExtInitVtbl; + } else if (IsEqualIID(RefIID, &IID_IShellPropSheetExt)) { + *ObjectOut = &This->ShellPropSheetExtVtbl; + } else { + *ObjectOut = NULL; + return E_NOINTERFACE; + } + + InterlockedIncrement(&This->RefCount); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CKexShlEx_QueryInterface_thunk0( + IN IShellExtInit *This, + IN REFIID RefIID, + OUT PPVOID ObjectOut) +{ + return CKexShlEx_QueryInterface((IKexShlEx *) This, RefIID, ObjectOut); +} + +HRESULT STDMETHODCALLTYPE CKexShlEx_QueryInterface_thunk1( + IN IShellPropSheetExt *This, + IN REFIID RefIID, + OUT PPVOID ObjectOut) +{ + return CKexShlEx_QueryInterface((IKexShlEx *) (((ULONG_PTR) This) - sizeof(PVOID)), RefIID, ObjectOut); +} + +ULONG STDMETHODCALLTYPE CKexShlEx_AddRef( + IN IKexShlEx *This) +{ + return InterlockedIncrement(&This->RefCount); +} + +ULONG STDMETHODCALLTYPE CKexShlEx_AddRef_thunk0( + IN IShellExtInit *This) +{ + return CKexShlEx_AddRef((IKexShlEx *) This); +} + +ULONG STDMETHODCALLTYPE CKexShlEx_AddRef_thunk1( + IN IShellPropSheetExt *This) +{ + return CKexShlEx_AddRef((IKexShlEx *) (((ULONG_PTR) This) - sizeof(PVOID))); +} + +ULONG STDMETHODCALLTYPE CKexShlEx_Release( + IN IKexShlEx *This) +{ + LONG NewRefCount; + + NewRefCount = InterlockedDecrement(&NewRefCount); + + if (NewRefCount == 0) { + InterlockedDecrement(&DllReferenceCount); + SafeFree(This); + return 0; + } + + return This->RefCount; +} + +ULONG STDMETHODCALLTYPE CKexShlEx_Release_thunk0( + IN IShellExtInit *This) +{ + return CKexShlEx_Release((IKexShlEx *) This); +} + +ULONG STDMETHODCALLTYPE CKexShlEx_Release_thunk1( + IN IShellPropSheetExt *This) +{ + return CKexShlEx_Release((IKexShlEx *) (((ULONG_PTR) This) - sizeof(PVOID))); +} + +HRESULT STDMETHODCALLTYPE CKexShlEx_Initialize( + IN IKexShlEx *This, + IN LPCITEMIDLIST FolderIdList OPTIONAL, + IN LPDATAOBJECT DataObject, + IN HKEY ProgIdKey) +{ + HRESULT Result; + ULONG NumberOfFilesSelected; + FORMATETC Format; + STGMEDIUM StorageMedium; + HDROP Drop; + PCWSTR FileExtension; + + ASSERT (This != NULL); + ASSERT (FolderIdList == NULL); + ASSERT (DataObject != NULL); + + Format.cfFormat = CF_HDROP; + Format.ptd = NULL; + Format.dwAspect = DVASPECT_CONTENT; + Format.lindex = -1; + Format.tymed = TYMED_HGLOBAL; + + Result = DataObject->lpVtbl->GetData( + DataObject, + &Format, + &StorageMedium); + + if (FAILED(Result)) { + return Result; + } + + Drop = (HDROP) StorageMedium.hGlobal; + NumberOfFilesSelected = DragQueryFile(Drop, -1, NULL, 0); + + if (NumberOfFilesSelected != 1) { + // If the user selects multiple files before opening properties, + // we don't want to display any property sheet page. + ReleaseStgMedium(&StorageMedium); + return E_FAIL; + } + + DragQueryFile(Drop, 0, This->ExeFullPath, ARRAYSIZE(This->ExeFullPath)); + ReleaseStgMedium(&StorageMedium); + + // + // The full path to the target file is now stored in This->ExeFullPath. + // + + Result = PathCchFindExtension( + This->ExeFullPath, + ARRAYSIZE(This->ExeFullPath), + &FileExtension); + + if (FAILED(Result)) { + return Result; + } + + if (StringEqualI(FileExtension, L".LNK")) { + // + // Get the path to the file that the .LNK points to. + // + + Result = GetTargetFromLnkfile(This->ExeFullPath); + if (FAILED(Result)) { + return Result; + } + + // + // Determine the file extension for the new target file. + // + + Result = PathCchFindExtension( + This->ExeFullPath, + ARRAYSIZE(This->ExeFullPath), + &FileExtension); + + if (FAILED(Result)) { + return Result; + } + + // + // If it's not .EXE or .MSI, we won't display a property page. + // + + if (!StringEqualI(FileExtension, L".EXE") && + !StringEqualI(FileExtension, L".MSI")) { + + return E_NOTIMPL; + } + } + + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CKexShlEx_AddPages( + IN IKexShlEx *This, + IN LPFNADDPROPSHEETPAGE AddPage, + IN LPARAM LParam) +{ + BOOLEAN Success; + PROPSHEETPAGE Page; + HPROPSHEETPAGE PageHandle; + WCHAR WinDir[MAX_PATH]; + WCHAR KexDir[MAX_PATH]; + + ASSERT (This != NULL); + ASSERT (AddPage != NULL); + + // adjustor + This = (IKexShlEx *) (((ULONG_PTR) This) - sizeof(PVOID)); + + ASSERT (This != NULL); + ASSERT (This->ExeFullPath[0] != '\0'); + + GetWindowsDirectory(WinDir, ARRAYSIZE(WinDir)); + Success = KxCfgGetKexDir(KexDir, ARRAYSIZE(KexDir)); + ASSERT (Success); + + if (!Success) { + return E_FAIL; + } + + // + // If the executable is inside the Windows directory, or if it is inside + // KexDir, then we will not allow the user to change any VxKex settings + // for it. Windows executables or VxKex executables do not benefit from + // enabling VxKex and doing so could cause serious problems. + // + + if (PathIsPrefix(WinDir, This->ExeFullPath) || PathIsPrefix(KexDir, This->ExeFullPath)) { + return E_FAIL; + } + + ZeroMemory(&Page, sizeof(Page)); + Page.dwSize = sizeof(Page); + Page.dwFlags = PSP_USEREFPARENT | PSP_USETITLE | PSP_USECALLBACK; + Page.hInstance = DllHandle; + Page.pszTemplate = MAKEINTRESOURCE(IDD_VXKEXPROPSHEETPAGE); + Page.pszTitle = L"VxKex"; + Page.pfnDlgProc = DialogProc; + Page.pfnCallback = PropSheetCallbackProc; + Page.pcRefParent = (PUINT) &DllReferenceCount; + Page.lParam = (LPARAM) This; + + PageHandle = CreatePropertySheetPage(&Page); + if (!PageHandle) { + return E_OUTOFMEMORY; + } + + Success = AddPage(PageHandle, LParam); + if (!Success) { + DestroyPropertySheetPage(PageHandle); + return E_FAIL; + } + + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CKexShlEx_ReplacePage( + IN IKexShlEx *This, + IN UINT PageId, + IN LPFNADDPROPSHEETPAGE ReplacePage, + IN LPARAM LParam) +{ + return E_NOTIMPL; +} \ No newline at end of file diff --git a/KexShlEx/clsfctry.c b/KexShlEx/clsfctry.c new file mode 100644 index 0000000..d2896c0 --- /dev/null +++ b/KexShlEx/clsfctry.c @@ -0,0 +1,93 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// clsfctry.c +// +// Abstract: +// +// Implements the IClassFactory interface. +// All just COM boilerplate crap, nothing to see here. +// +// Author: +// +// vxiiduu (08-Feb-2024) +// +// Environment: +// +// Inside explorer.exe +// +// Revision History: +// +// vxiiduu 08-Feb-2024 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "KexShlEx.h" + +HRESULT STDMETHODCALLTYPE CClassFactory_QueryInterface( + IN IClassFactory *This, + IN REFIID RefIID, + OUT PPVOID ObjectOut) +{ + ASSERT (This != NULL); + ASSERT (RefIID != NULL); + ASSERT (ObjectOut != NULL); + + if (IsEqualIID(RefIID, &IID_IUnknown)) { + *ObjectOut = This; + } else if (IsEqualIID(RefIID, &IID_IClassFactory)) { + *ObjectOut = This; + } else { + *ObjectOut = NULL; + return E_NOINTERFACE; + } + + return S_OK; +} + +ULONG STDMETHODCALLTYPE CClassFactory_AddRef( + IN IClassFactory *This) +{ + return 1; +} + +ULONG STDMETHODCALLTYPE CClassFactory_Release( + IN IClassFactory *This) +{ + return 1; +} + +HRESULT STDMETHODCALLTYPE CClassFactory_CreateInstance( + IN IClassFactory *This, + IN IUnknown *OuterIUnknown OPTIONAL, + IN REFIID RefIID, + OUT PPVOID ObjectOut) +{ + IKexShlEx *CKexShlEx; + + ASSERT (This != NULL); + ASSERT (RefIID != NULL); + ASSERT (ObjectOut != NULL); + + if (OuterIUnknown) { + return CLASS_E_NOAGGREGATION; + } + + CKexShlEx = SafeAlloc(IKexShlEx, 1); + if (!CKexShlEx) { + return E_OUTOFMEMORY; + } + + InterlockedIncrement(&DllReferenceCount); + CopyMemory(CKexShlEx, &IKexShlExTemplate, sizeof(IKexShlExTemplate)); + return CKexShlEx_QueryInterface(CKexShlEx, RefIID, ObjectOut); +} + +HRESULT STDMETHODCALLTYPE CClassFactory_LockServer( + IN IClassFactory *This, + IN BOOL Lock) +{ + return E_NOTIMPL; +} \ No newline at end of file diff --git a/KexShlEx/dllmain.c b/KexShlEx/dllmain.c new file mode 100644 index 0000000..0a5da42 --- /dev/null +++ b/KexShlEx/dllmain.c @@ -0,0 +1,151 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// dllmain.c +// +// Abstract: +// +// Main file for the shell extension. +// +// To be honest, this file is mostly just full of COM boilerplate slop, +// and you don't need to look in here unless there's a bug. The other files +// in this project might contain more interesting code. +// +// Author: +// +// vxiiduu (08-Feb-2024) +// +// Environment: +// +// Inside explorer.exe +// +// Revision History: +// +// vxiiduu 08-Feb-2024 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "KexShlEx.h" +#include "resource.h" + +#include +// {9AACA888-A5F5-4C01-852E-8A2005C1D45F} +DEFINE_GUID(CLSID_KexShlEx, 0x9aaca888, 0xa5f5, 0x4c01, 0x85, 0x2e, 0x8a, 0x20, 0x5, 0xc1, 0xd4, 0x5f); + +HMODULE DllHandle = NULL; +LONG DllReferenceCount = 0; + +// +// CKexShlEx +// + +IShellExtInitVtbl CShellExtInitVtbl = { + CKexShlEx_QueryInterface_thunk0, + CKexShlEx_AddRef_thunk0, + CKexShlEx_Release_thunk0, + (HRESULT (STDMETHODCALLTYPE *) (IShellExtInit *, LPCITEMIDLIST, LPDATAOBJECT, HKEY)) CKexShlEx_Initialize +}; + +IShellPropSheetExtVtbl CShellPropSheetExtVtbl = { + CKexShlEx_QueryInterface_thunk1, + CKexShlEx_AddRef_thunk1, + CKexShlEx_Release_thunk1, + (HRESULT (STDMETHODCALLTYPE *) (IShellPropSheetExt *, LPFNADDPROPSHEETPAGE, LPARAM)) CKexShlEx_AddPages, + (HRESULT (STDMETHODCALLTYPE *) (IShellPropSheetExt *, UINT, LPFNADDPROPSHEETPAGE, LPARAM)) CKexShlEx_ReplacePage +}; + +CONST IKexShlEx IKexShlExTemplate = { + &CShellExtInitVtbl, + &CShellPropSheetExtVtbl, + FALSE, + 0, + {0} +}; + +// +// CClassFactory +// + +IClassFactoryVtbl CClassFactoryVtbl = { + CClassFactory_QueryInterface, + CClassFactory_AddRef, + CClassFactory_Release, + CClassFactory_CreateInstance, + CClassFactory_LockServer +}; + +IClassFactory CClassFactory = { + &CClassFactoryVtbl +}; + +// +// DLL exports +// + +BOOL WINAPI DllMain( + IN HMODULE InstanceHandle, + IN ULONG Reason, + IN PVOID Reserved) +{ + if (Reason == DLL_PROCESS_ATTACH) { + DllHandle = InstanceHandle; + DisableThreadLibraryCalls(DllHandle); + KexgApplicationFriendlyName = FRIENDLYAPPNAME; + } + + return TRUE; +} + +STDAPI DllGetClassObject( + IN REFCLSID RefCLSID, + IN REFIID RefIID, + IN PPVOID ClassObjectOut) +{ + ASSERT (RefCLSID != NULL); + ASSERT (RefIID != NULL); + ASSERT (ClassObjectOut != NULL); + + *ClassObjectOut = NULL; + + if (IsEqualIID(RefCLSID, &CLSID_KexShlEx)) { + return CClassFactory.lpVtbl->QueryInterface(&CClassFactory, RefIID, ClassObjectOut); + } + + return CLASS_E_CLASSNOTAVAILABLE; +} + +STDAPI DllCanUnloadNow( + VOID) +{ + if (DllReferenceCount == 0) { + return S_OK; + } else { + return S_FALSE; + } +} + +// +// The functionality usually assigned to DllRegisterServer, DllUnregisterServer +// and DllInstall has been moved to KexSetup as part of the rewrite. +// + +STDAPI DllUnregisterServer( + VOID) +{ + return E_NOTIMPL; +} + +STDAPI DllRegisterServer( + VOID) +{ + return E_NOTIMPL; +} + +STDAPI DllInstall( + IN BOOL Install, + IN PCWSTR CommandLine OPTIONAL) +{ + return E_NOTIMPL; +} \ No newline at end of file diff --git a/KexShlEx/gui.c b/KexShlEx/gui.c new file mode 100644 index 0000000..1da3540 --- /dev/null +++ b/KexShlEx/gui.c @@ -0,0 +1,230 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// gui.c +// +// Abstract: +// +// Implements the user interface logic of the shell extension. +// +// Author: +// +// vxiiduu (08-Feb-2024) +// +// Environment: +// +// Inside explorer.exe +// +// Revision History: +// +// vxiiduu 08-Feb-2024 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "KexShlEx.h" +#include "resource.h" + +INT_PTR CALLBACK DialogProc( + IN HWND Window, + IN UINT Message, + IN WPARAM WParam, + IN LPARAM LParam) +{ + PKEXSHLEX_PROPSHEET_DATA PropSheetData; + + PropSheetData = (PKEXSHLEX_PROPSHEET_DATA) GetWindowLongPtr(Window, GWLP_USERDATA); + + if (Message == WM_INITDIALOG) { + BOOLEAN Success; + IKexShlEx *CKexShlEx; + LPPROPSHEETPAGE PropSheetPage; + PCWSTR ExeFullPath; + HWND WinVerComboBox; + KXCFG_PROGRAM_CONFIGURATION ProgramConfiguration; + ULONG Index; + + ASSERT (PropSheetData == NULL); + PropSheetPage = (LPPROPSHEETPAGE) LParam; + ASSERT (PropSheetPage != NULL); + CKexShlEx = (IKexShlEx *) PropSheetPage->lParam; + ASSERT (CKexShlEx != NULL); + ExeFullPath = CKexShlEx->ExeFullPath; + + // + // Allocate a structure for us to store the path to the executable + // as well as record whether any of the settings have changed. + // + + PropSheetData = SafeAlloc(KEXSHLEX_PROPSHEET_DATA, 1); + if (!PropSheetData) { + for (Index = 110; Index < 130; ++Index) { + EnableWindow(GetDlgItem(Window, Index), FALSE); + } + } + + if (PropSheetData) { + PropSheetData->ExeFullPath = ExeFullPath; + PropSheetData->SettingsChanged = FALSE; + } + + // + // Associate the data structure with the property sheet. + // + + SetWindowLongPtr(Window, GWLP_USERDATA, (LONG_PTR) PropSheetData); + + // + // Populate the Windows version combo box. + // + + WinVerComboBox = GetDlgItem(Window, IDWINVERCOMBOBOX); + + ComboBox_AddString(WinVerComboBox, L"Windows 7 Service Pack 1"); + ComboBox_AddString(WinVerComboBox, L"Windows 8"); + ComboBox_AddString(WinVerComboBox, L"Windows 8.1"); + ComboBox_AddString(WinVerComboBox, L"Windows 10"); + ComboBox_AddString(WinVerComboBox, L"Windows 11"); + + // Set default selection to Windows 10. + ComboBox_SetCurSel(WinVerComboBox, 3); + + // + // Query the VxKex configuration for the current program. + // + + Success = KxCfgGetConfiguration( + ExeFullPath, + &ProgramConfiguration); + + if (Success) { + CheckDlgButton(Window, IDUSEVXKEX, !!ProgramConfiguration.Enabled); + + if (ProgramConfiguration.WinVerSpoof != WinVerSpoofNone) { + EnableWindow(WinVerComboBox, TRUE); + EnableWindow(GetDlgItem(Window, IDSTRONGSPOOF), TRUE); + CheckDlgButton(Window, IDSPOOFVERSIONCHECK, BST_CHECKED); + ComboBox_SetCurSel(WinVerComboBox, ProgramConfiguration.WinVerSpoof - 1); + } + + CheckDlgButton(Window, IDSTRONGSPOOF, !!ProgramConfiguration.StrongSpoofOptions); + CheckDlgButton(Window, IDDISABLEFORCHILD, !!ProgramConfiguration.DisableForChild); + CheckDlgButton(Window, IDDISABLEAPPSPECIFIC, !!ProgramConfiguration.DisableAppSpecificHacks); + } + + // + // Add tooltips to all the settings. + // + + ToolTip(Window, IDUSEVXKEX, + L"Enable or disable the main VxKex compatibility layer."); + ToolTip(Window, IDSPOOFVERSIONCHECK, + L"Some applications check the Windows version and refuse to run if it is too low. " + L"This option can help these applications to run correctly.\r\n\r\n" + L"Generally, you should not use a higher Windows version than required to run the " + L"application, because this can degrade application compatibility."); + ToolTip(Window, IDSTRONGSPOOF, + L"Some applications check the Windows version using uncommon methods. This option " + L"can help trick them into working. Do not enable this setting unless you are having " + L"a problem with version detection."); + ToolTip(Window, IDDISABLEFORCHILD, + L"By default, all other programs that are started by this program run with VxKex " + L"enabled. This option disables that behavior."); + ToolTip(Window, IDDISABLEAPPSPECIFIC, + L"For some applications, VxKex may use application-specific workarounds or patches. " + L"This option disables that behavior. Using this option may degrade application " + L"compatibility."); + ToolTip(Window, IDREPORTBUG, _L(KEX_BUGREPORT_STR)); + + SetFocus(GetDlgItem(Window, IDUSEVXKEX)); + return FALSE; + } else if (Message == WM_COMMAND) { + if (LOWORD(WParam) == IDSPOOFVERSIONCHECK) { + BOOLEAN VersionSpoofEnabled; + + VersionSpoofEnabled = !!IsDlgButtonChecked(Window, IDSPOOFVERSIONCHECK); + + // enable the win ver combo box when the user enables version spoof + EnableWindow(GetDlgItem(Window, IDWINVERCOMBOBOX), VersionSpoofEnabled); + + // enable the strong spoof checkbox when user enables version spoof + EnableWindow(GetDlgItem(Window, IDSTRONGSPOOF), VersionSpoofEnabled); + } + + // this causes the "Apply" button to be enabled + PropSheet_Changed(GetParent(Window), Window); + + // Record the change to the settings. + if (PropSheetData) { + PropSheetData->SettingsChanged = TRUE; + } + } else if (Message == WM_NOTIFY && ((LPNMHDR) LParam)->code == PSN_APPLY && + PropSheetData && PropSheetData->SettingsChanged) { + + // + // The OK or Apply button was clicked and we need to apply new settings. + // + + KXCFG_PROGRAM_CONFIGURATION ProgramConfiguration; + + ZeroMemory(&ProgramConfiguration, sizeof(ProgramConfiguration)); + + ProgramConfiguration.Enabled = IsDlgButtonChecked(Window, IDUSEVXKEX); + + if (IsDlgButtonChecked(Window, IDSPOOFVERSIONCHECK)) { + ProgramConfiguration.WinVerSpoof = (KEX_WIN_VER_SPOOF) (ComboBox_GetCurSel(GetDlgItem(Window, IDWINVERCOMBOBOX)) + 1); + } else { + ProgramConfiguration.WinVerSpoof = WinVerSpoofNone; + } + + ProgramConfiguration.StrongSpoofOptions = IsDlgButtonChecked(Window, IDSTRONGSPOOF) ? KEX_STRONGSPOOF_VALID_MASK : 0; + ProgramConfiguration.DisableForChild = IsDlgButtonChecked(Window, IDDISABLEFORCHILD); + ProgramConfiguration.DisableAppSpecificHacks = IsDlgButtonChecked(Window, IDDISABLEAPPSPECIFIC); + + // + // All the configuration is inside the ProgramConfiguration structure. + // Call a helper function to carry out the steps necessary to write it + // to the registry. + // + + if (PropSheetData) { + KxCfgSetConfiguration(PropSheetData->ExeFullPath, &ProgramConfiguration, NULL); + PropSheetData->SettingsChanged = FALSE; + } + } else if (Message == WM_NOTIFY && WParam == IDREPORTBUG) { + ULONG NotificationCode; + + NotificationCode = ((LPNMHDR) LParam)->code; + + if (NotificationCode == NM_CLICK || NotificationCode == NM_RETURN) { + // user clicked the report bug button - open in his default browser + ShellExecute(Window, L"open", _L(KEX_BUGREPORT_STR), NULL, NULL, SW_NORMAL); + } + } else { + return FALSE; + } + + return TRUE; +} + +UINT WINAPI PropSheetCallbackProc( + IN HWND Window, + IN UINT Message, + IN OUT LPPROPSHEETPAGE PropSheetPage) +{ + IKexShlEx *CKexShlEx; + + ASSERT (PropSheetPage != NULL); + + CKexShlEx = (IKexShlEx *) PropSheetPage->lParam; + ASSERT (CKexShlEx != NULL); + + if (Message == PSPCB_ADDREF) { + CKexShlEx_AddRef(CKexShlEx); + } else if (Message == PSPCB_RELEASE) { + CKexShlEx_Release(CKexShlEx); + } + + return TRUE; +} \ No newline at end of file diff --git a/KexShlEx/lnkfile.c b/KexShlEx/lnkfile.c new file mode 100644 index 0000000..f982517 --- /dev/null +++ b/KexShlEx/lnkfile.c @@ -0,0 +1,87 @@ +#include "buildcfg.h" +#include "KexShlEx.h" +#include + +// +// FileName must be MAX_PATH characters in size. +// +HRESULT GetTargetFromLnkfile( + IN OUT PWSTR FileName) +{ + HRESULT Result; + WCHAR LnkTarget[MAX_PATH]; + IShellLink *ShellLink; + IPersistFile *PersistFile; + + ShellLink = NULL; + PersistFile = NULL; + + ASSERT (FileName != NULL); + + Result = CoCreateInstance( + &CLSID_ShellLink, + NULL, + CLSCTX_INPROC_SERVER, + &IID_IShellLink, + (PPVOID) &ShellLink); + + ASSERT (SUCCEEDED(Result)); + ASSERT (ShellLink != NULL); + + if (FAILED(Result)) { + return Result; + } + + try { + Result = IShellLinkW_QueryInterface( + ShellLink, + &IID_IPersistFile, + (PPVOID) &PersistFile); + + ASSERT (SUCCEEDED(Result)); + ASSERT (PersistFile != NULL); + + if (FAILED(Result)) { + leave; + } + + Result = IPersistFile_Load(PersistFile, FileName, STGM_READ); + ASSERT (SUCCEEDED(Result)); + + if (FAILED(Result)) { + leave; + } + + Result = IShellLinkW_Resolve( + ShellLink, + NULL, + SLR_NOTRACK | SLR_NOSEARCH | SLR_NO_UI | SLR_NOUPDATE); + + if (FAILED(Result)) { + leave; + } + + Result = IShellLinkW_GetPath( + ShellLink, + LnkTarget, + ARRAYSIZE(LnkTarget), + NULL, + SLGP_UNCPRIORITY); + + if (FAILED(Result)) { + leave; + } + } finally { + SafeRelease(ShellLink); + SafeRelease(PersistFile); + } + + if (SUCCEEDED(Result)) { + Result = StringCchCopy(FileName, MAX_PATH, LnkTarget); + ASSERT (SUCCEEDED(Result)); + } else { + FileName[0] = '\0'; + } + + return Result; +} \ No newline at end of file diff --git a/KexShlEx/resource.h b/KexShlEx/resource.h new file mode 100644 index 0000000..d374f7b --- /dev/null +++ b/KexShlEx/resource.h @@ -0,0 +1,49 @@ +#include + +#define IDSTATIC -1 +#define IDD_VXKEXPROPSHEETPAGE 101 + +#define IDUSEVXKEX 110 +#define IDSPOOFVERSIONCHECK 111 +#define IDWINVERCOMBOBOX 112 +#define IDSTRONGSPOOF 114 +#define IDDISABLEFORCHILD 115 +#define IDDISABLEAPPSPECIFIC 116 + +#define IDREPORTBUG 130 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/KexW32ML/KexW32ML.vcxproj b/KexW32ML/KexW32ML.vcxproj new file mode 100644 index 0000000..fd2551a --- /dev/null +++ b/KexW32ML/KexW32ML.vcxproj @@ -0,0 +1,236 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {1AEF4F9B-7227-4B51-9ADE-CDED9427C0B5} + Win32Proj + KexW32ML + + + + StaticLibrary + true + Unicode + + + StaticLibrary + true + Unicode + + + StaticLibrary + false + true + Unicode + + + StaticLibrary + false + true + Unicode + + + + + + + + + + + + + + + + + + + false + + + false + + + false + + + false + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;KEXW32ML_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + true + false + StdCall + true + false + false + Default + ProgramDatabase + + + Windows + true + $(SolutionDir)\00-Import Libraries;$(TargetDir) + + + kexw32ml.def + false + true + + + + + $(SolutionDir)\00-Import Libraries + true + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;KEXW32ML_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + true + false + StdCall + true + false + false + Default + ProgramDatabase + + + Windows + true + $(SolutionDir)\00-Import Libraries;$(TargetDir) + + + kexw32ml.def + false + true + + + $(SolutionDir)\00-Import Libraries + + + true + + + + + Level3 + NotUsing + MinSpace + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;KEXW32ML_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + true + false + StdCall + true + false + false + Default + ProgramDatabase + OnlyExplicitInline + Size + true + + + Windows + true + true + true + $(SolutionDir)\00-Import Libraries;$(TargetDir) + + + kexw32ml.def + false + true + + + $(SolutionDir)\00-Import Libraries + + + true + + + + + Level3 + NotUsing + MinSpace + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;KEXW32ML_EXPORTS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + true + false + StdCall + true + false + false + Default + ProgramDatabase + OnlyExplicitInline + Size + true + + + Windows + true + true + true + $(SolutionDir)\00-Import Libraries;$(TargetDir) + + + kexw32ml.def + false + true + + + $(SolutionDir)\00-Import Libraries + + + true + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/KexW32ML/KexW32ML.vcxproj.filters b/KexW32ML/KexW32ML.vcxproj.filters new file mode 100644 index 0000000..8d3a116 --- /dev/null +++ b/KexW32ML/KexW32ML.vcxproj.filters @@ -0,0 +1,39 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/KexW32ML/buildcfg.h b/KexW32ML/buildcfg.h new file mode 100644 index 0000000..cfc1539 --- /dev/null +++ b/KexW32ML/buildcfg.h @@ -0,0 +1,42 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN +#define NOGDICAPMASKS +#define NOVIRTUALKEYCODES +#define NOWINMESSAGES +#define NOWINSTYLES +#define NOSYSMETRICS +#define NOMENUS +#define NOICONS +#define NOKEYSTATES +#define NOSYSCOMMANDS +#define NORASTEROPS +#define NOSHOWWINDOW +#define NOATOM +#define NOCLIPBOARD +#define NOCOLOR +#define NOCTLMGR +#define NODRAWTEXT +#define NOGDI +#define NOMB +#define NOMEMMGR +#define NOOPENFILE +#define NOSCROLL +#define NOTEXTMETRIC +#define NOWH +#define NOWINOFFSETS +#define NOCOMM +#define NOKANJI +#define NOHELP +#define NOPROFILER +#define NODEFERWINDOWPOS +#define NOMCX +#define NOCRYPT +#define NOMETAFILE +#define NOSERVICE +#define NOSOUND + +#pragma comment(lib, "advapi32") + +#define KW32MLDECLSPEC +#define KEX_TARGET_TYPE_LIB diff --git a/KexW32ML/file.c b/KexW32ML/file.c new file mode 100644 index 0000000..01dcea3 --- /dev/null +++ b/KexW32ML/file.c @@ -0,0 +1,99 @@ +#include "buildcfg.h" +#include +#include + +KW32MLDECLSPEC EXTERN_C BOOLEAN KW32MLAPI SupersedeFile( + IN PCWSTR SourceFile, + IN PCWSTR TargetFile, + IN HANDLE TransactionHandle OPTIONAL) +{ + BOOLEAN Success; + HANDLE ExistingTransaction; + + ExistingTransaction = RtlGetCurrentTransaction(); + + if (ExistingTransaction) { + RtlSetCurrentTransaction(NULL); + } + + if (TransactionHandle) { + Success = MoveFileTransacted( + SourceFile, + TargetFile, + NULL, + NULL, + MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED, + TransactionHandle); + } else { + Success = MoveFileEx( + SourceFile, + TargetFile, + MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED); + } + + if (!Success) { + ULONG RandomIdentifier; + WCHAR ExistingTargetNewName[MAX_PATH]; + + // try to rename the old file to .old_xxxx + RandomIdentifier = GetTickCount(); + + StringCchPrintf( + ExistingTargetNewName, + ARRAYSIZE(ExistingTargetNewName), + L"%s.old_%04u", TargetFile, RandomIdentifier); + + if (TransactionHandle) { + Success = MoveFileTransacted( + TargetFile, + ExistingTargetNewName, + NULL, + NULL, + 0, + TransactionHandle); + } else { + Success = MoveFile(TargetFile, ExistingTargetNewName); + } + + if (Success) { + // schedule the old file to be deleted later + + if (TransactionHandle) { + MoveFileTransacted( + ExistingTargetNewName, + NULL, + NULL, + NULL, + MOVEFILE_DELAY_UNTIL_REBOOT, + TransactionHandle); + } else { + MoveFileEx( + ExistingTargetNewName, + NULL, + MOVEFILE_DELAY_UNTIL_REBOOT); + } + + // move the new file into the old position + if (TransactionHandle) { + Success = MoveFileTransacted( + SourceFile, + TargetFile, + NULL, + NULL, + MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED, + TransactionHandle); + } else { + Success = MoveFileEx( + SourceFile, + TargetFile, + MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED); + } + } + } + + if (ExistingTransaction) { + RtlSetCurrentTransaction(ExistingTransaction); + } + + return Success; +} \ No newline at end of file diff --git a/KexW32ML/kexw32ml.c b/KexW32ML/kexw32ml.c new file mode 100644 index 0000000..ad83511 --- /dev/null +++ b/KexW32ML/kexw32ml.c @@ -0,0 +1,147 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// kexw32ml.c +// +// Abstract: +// +// VxKex Win32-mode General Library +// +// Author: +// +// vxiiduu (01-Oct-2022) +// +// Environment: +// +// Win32 +// +// Revision History: +// +// vxiiduu 01-Oct-2022 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include +#include + +// +// The return value is in milliseconds. +// The return value is positive if FileTime2 is later than FileTime1. +// The return value is negative if FileTime2 is earlier than FileTime1. +// +KW32MLDECLSPEC EXTERN_C LONGLONG KW32MLAPI CompareFileTimes( + IN FILETIME FileTime1, + IN FILETIME FileTime2) +{ + LONGLONG FileTime1AsInt64; + LONGLONG FileTime2AsInt64; + + FileTime1AsInt64 = *((PLONGLONG) &FileTime1); + FileTime2AsInt64 = *((PLONGLONG) &FileTime2); + + return (FileTime2AsInt64 - FileTime1AsInt64) / 10000; +} + +KW32MLDECLSPEC EXTERN_C PWSTR KW32MLAPI GetCommandLineWithoutImageName( + VOID) +{ + BOOLEAN DoubleQuoted; + PWSTR RawCommandLine; + + DoubleQuoted = FALSE; + RawCommandLine = NtCurrentPeb()->ProcessParameters->CommandLine.Buffer; + + while (*RawCommandLine > ' ' || (*RawCommandLine && DoubleQuoted)) { + if (*RawCommandLine == '"') { + DoubleQuoted = !DoubleQuoted; + } + + RawCommandLine++; + } + + while (*RawCommandLine && *RawCommandLine <= ' ') { + RawCommandLine++; + } + + return RawCommandLine; +} + +KW32MLDECLSPEC EXTERN_C BOOLEAN KW32MLAPI PathReplaceIllegalCharacters( + IN PWSTR Path, + IN WCHAR ReplacementCharacter, + IN BOOLEAN AllowPathSeparators) +{ + BOOLEAN AtLeastOneCharacterWasReplaced; + + ASSERT (Path != NULL); + + if (!Path) { + return FALSE; + } + + AtLeastOneCharacterWasReplaced = FALSE; + + while (*Path != '\0') { + switch (*Path) { + case '<': + case '>': + case ':': + case '"': + case '|': + case '?': + case '*': + *Path = ReplacementCharacter; + AtLeastOneCharacterWasReplaced = TRUE; + break; + case '/': + case '\\': + unless (AllowPathSeparators) { + *Path = ReplacementCharacter; + AtLeastOneCharacterWasReplaced = TRUE; + } + break; + } + + Path++; + } + + return AtLeastOneCharacterWasReplaced; +} + +KW32MLDECLSPEC PCWSTR KW32MLAPI Win32ErrorAsString( + IN ULONG Win32ErrorCode) +{ + ULONG NumberOfCharacters; + STATIC WCHAR StaticBuffer[256]; + + NumberOfCharacters = FormatMessage( + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + Win32ErrorCode, + 0, + StaticBuffer, + ARRAYSIZE(StaticBuffer), + NULL); + + if (NumberOfCharacters == 0) { + StaticBuffer[0] = '\0'; + } + + return StaticBuffer; +} + +#ifdef KEX_TARGET_TYPE_DLL +ULONG WINAPI DllMain( + IN HMODULE DllBase, + IN ULONG Reason, + IN PCONTEXT Context) +{ + if (Reason == DLL_PROCESS_ATTACH) { + DisableThreadLibraryCalls(DllBase); + } + + return TRUE; +} +#endif \ No newline at end of file diff --git a/KexW32ML/registry.c b/KexW32ML/registry.c new file mode 100644 index 0000000..3e37bc0 --- /dev/null +++ b/KexW32ML/registry.c @@ -0,0 +1,169 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// registry.c +// +// Abstract: +// +// Registry convenience functions +// +// Author: +// +// vxiiduu (02-Oct-2022) +// +// Environment: +// +// Win32 +// +// Revision History: +// +// vxiiduu 02-Oct-2022 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include +#include + +KW32MLDECLSPEC EXTERN_C ULONG KW32MLAPI RegReadI32( + IN HKEY Key, + IN PCWSTR SubKey OPTIONAL, + IN PCWSTR ValueName OPTIONAL, + OUT PULONG Data) +{ + ULONG ErrorCode; + DWORD Discard; + + ASSERT (Key != NULL); + ASSERT (Key != INVALID_HANDLE_VALUE); + ASSERT (Data != NULL); + + Discard = sizeof(*Data); + + ErrorCode = RegGetValue( + Key, + SubKey, + ValueName, + RRF_RT_DWORD, + NULL, + Data, + &Discard); + + if (ErrorCode != ERROR_SUCCESS) { + *Data = 0; + } + + return ErrorCode; +} + +KW32MLDECLSPEC EXTERN_C ULONG KW32MLAPI RegWriteI32( + IN HKEY Key, + IN PCWSTR SubKey OPTIONAL, + IN PCWSTR ValueName OPTIONAL, + IN ULONG Data) +{ + ASSERT (Key != NULL); + ASSERT (Key != INVALID_HANDLE_VALUE); + + return RegSetKeyValue( + Key, + SubKey, + ValueName, + REG_DWORD, + &Data, + sizeof(Data)); +} + +KW32MLDECLSPEC EXTERN_C ULONG KW32MLAPI RegReadString( + IN HKEY Key, + IN PCWSTR SubKey OPTIONAL, + IN PCWSTR ValueName OPTIONAL, + OUT PWSTR Buffer, + IN ULONG BufferCch) +{ + ULONG BufferCb; + + BufferCb = BufferCch * sizeof(WCHAR); + + if (Buffer && BufferCch) { + *Buffer = '\0'; + } + + return RegGetValue( + Key, + SubKey, + ValueName, + RRF_RT_REG_SZ, + NULL, + Buffer, + &BufferCb); +} + +KW32MLDECLSPEC EXTERN_C ULONG KW32MLAPI RegWriteString( + IN HKEY Key, + IN PCWSTR SubKey OPTIONAL, + IN PCWSTR ValueName OPTIONAL, + IN PCWSTR Data) +{ + ULONG DataCb; + + ASSERT (Key != NULL); + ASSERT (Key != INVALID_HANDLE_VALUE); + ASSERT (Data != NULL); + + DataCb = (ULONG) (wcslen(Data) + 1) * sizeof(WCHAR); + + return RegSetKeyValue( + Key, + SubKey, + ValueName, + REG_SZ, + Data, + DataCb); +} + +// Used for reopening a specific key with different permissions. +// This function closes the existing key. +// Upon failure, this function returns FALSE and does not modify +// the existing key. Call GetLastError for more information. +KW32MLDECLSPEC EXTERN_C BOOLEAN KW32MLAPI RegReOpenKey( + IN OUT PHKEY KeyHandle, + IN ACCESS_MASK NewAccessMask, + IN HANDLE TransactionHandle OPTIONAL) +{ + NTSTATUS Status; + UNICODE_STRING ObjectName; + OBJECT_ATTRIBUTES ObjectAttributes; + HKEY NewKeyHandle; + + ASSERT (KeyHandle != NULL); + ASSERT (*KeyHandle != NULL); + ASSERT (*KeyHandle != INVALID_HANDLE_VALUE); + + RtlInitConstantUnicodeString(&ObjectName, L""); + InitializeObjectAttributes(&ObjectAttributes, &ObjectName, 0, (HANDLE) *KeyHandle, NULL); + + if (TransactionHandle) { + Status = NtOpenKeyTransacted( + (PHANDLE) &NewKeyHandle, + NewAccessMask, + &ObjectAttributes, + TransactionHandle); + } else { + Status = NtOpenKey( + (PHANDLE) &NewKeyHandle, + NewAccessMask, + &ObjectAttributes); + } + + SetLastError(RtlNtStatusToDosError(Status)); + + if (NT_SUCCESS(Status)) { + NtClose(*KeyHandle); + *KeyHandle = NewKeyHandle; + return TRUE; + } else { + return FALSE; + } +} \ No newline at end of file diff --git a/KexW32ML/txapi.c b/KexW32ML/txapi.c new file mode 100644 index 0000000..fa7f86c --- /dev/null +++ b/KexW32ML/txapi.c @@ -0,0 +1,43 @@ +#include "buildcfg.h" +#include +#include + +KW32MLDECLSPEC HANDLE KW32MLAPI CreateSimpleTransaction( + IN PCWSTR Description OPTIONAL) +{ + NTSTATUS Status; + HANDLE TransactionHandle; + UNICODE_STRING DescriptionUS; + + if (Description) { + Status = RtlInitUnicodeStringEx(&DescriptionUS, Description); + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + SetLastError(RtlNtStatusToDosError(Status)); + return NULL; + } + } + + Status = NtCreateTransaction( + &TransactionHandle, + TRANSACTION_ALL_ACCESS, + NULL, + NULL, + NULL, + 0, + 0, + 0, + NULL, + Description ? &DescriptionUS : NULL); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + SetLastError(RtlNtStatusToDosError(Status)); + return NULL; + } + + ASSERT (TransactionHandle != NULL); + return TransactionHandle; +} \ No newline at end of file diff --git a/KxCfgHlp/KxCfgHlp.vcxproj b/KxCfgHlp/KxCfgHlp.vcxproj new file mode 100644 index 0000000..1fddbf1 --- /dev/null +++ b/KxCfgHlp/KxCfgHlp.vcxproj @@ -0,0 +1,217 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + + {66231B4E-059F-42B5-8B6D-0B22AD6DFC64} + Win32Proj + KxCfgHlp + + + + StaticLibrary + true + Unicode + + + StaticLibrary + true + Unicode + + + StaticLibrary + false + true + Unicode + + + StaticLibrary + false + true + Unicode + + + + + + + + + + + + + + + + + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + false + false + Default + false + StdCall + CompileAsC + + + Windows + true + + + + + + + true + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + false + false + Default + false + StdCall + CompileAsC + + + Windows + true + + + + + + + true + + + + + Level3 + NotUsing + MinSpace + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + false + false + Default + false + StdCall + CompileAsC + OnlyExplicitInline + Size + true + + + Windows + true + true + true + + + + + + + true + + + + + Level3 + NotUsing + MinSpace + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + false + false + Default + false + StdCall + CompileAsC + OnlyExplicitInline + Size + true + + + Windows + true + true + true + + + + + + + true + + + + + + \ No newline at end of file diff --git a/KxCfgHlp/KxCfgHlp.vcxproj.filters b/KxCfgHlp/KxCfgHlp.vcxproj.filters new file mode 100644 index 0000000..ea05073 --- /dev/null +++ b/KxCfgHlp/KxCfgHlp.vcxproj.filters @@ -0,0 +1,63 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/KxCfgHlp/buildcfg.h b/KxCfgHlp/buildcfg.h new file mode 100644 index 0000000..056bc23 --- /dev/null +++ b/KxCfgHlp/buildcfg.h @@ -0,0 +1,10 @@ +#pragma once + +#pragma comment(lib, "advapi32.lib") +#pragma comment(lib, "oleaut32.lib") +#pragma comment(lib, "taskschd.lib") + +#define KEX_COMPONENT L"KxCfgHlp" +#define KEX_ENV_WIN32 +#define KEX_TARGET_TYPE_LIB +#define KXCFGDECLSPEC diff --git a/KxCfgHlp/cpiwbypa.c b/KxCfgHlp/cpiwbypa.c new file mode 100644 index 0000000..69e902a --- /dev/null +++ b/KxCfgHlp/cpiwbypa.c @@ -0,0 +1,147 @@ +#include "buildcfg.h" +#include +#include + +// returns TRUE if cpiwbypa.dll BHO is registered +KXCFGDECLSPEC BOOLEAN KXCFGAPI KxCfgQueryExplorerCpiwBypass( + VOID) +{ + HKEY KeyHandle; + ULONG ErrorCode; + + ErrorCode = RegOpenKeyEx( + HKEY_LOCAL_MACHINE, + L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\" + L"Browser Helper Objects\\{7EF224FC-1840-433C-9BCB-2951DE71DDBD}", + 0, + STANDARD_RIGHTS_READ, + &KeyHandle); + + ASSERT (ErrorCode == ERROR_SUCCESS || ErrorCode == ERROR_FILE_NOT_FOUND); + + if (ErrorCode == ERROR_SUCCESS) { + SafeClose(KeyHandle); + return TRUE; + } else { + return FALSE; + } +} + +KXCFGDECLSPEC BOOLEAN KXCFGAPI KxCfgEnableExplorerCpiwBypass( + IN BOOLEAN Enable, + IN HANDLE TransactionHandle OPTIONAL) +{ + ULONG ErrorCode; + + if (Enable) { + HKEY KeyHandle; + + KeyHandle = KxCfgpCreateKey( + HKEY_LOCAL_MACHINE, + L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\" + L"Browser Helper Objects\\{7EF224FC-1840-433C-9BCB-2951DE71DDBD}", + KEY_READ | KEY_WRITE, + TransactionHandle); + + if (!KeyHandle) { + return FALSE; + } + + RegWriteString(KeyHandle, NULL, NULL, L"VxKex CPIW Version Check Bypass"); + SafeClose(KeyHandle); + + if (KexRtlOperatingSystemBitness() == 64) { + // Also create Wow64 registry keys/values + + KeyHandle = KxCfgpCreateKey( + HKEY_LOCAL_MACHINE, + L"Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Explorer\\" + L"Browser Helper Objects\\{7EF224FC-1840-433C-9BCB-2951DE71DDBD}", + KEY_READ | KEY_WRITE, + TransactionHandle); + + if (!KeyHandle) { + return FALSE; + } + + ErrorCode = RegWriteString(KeyHandle, NULL, NULL, L"VxKex CPIW Version Check Bypass"); + if (ErrorCode != ERROR_SUCCESS) { + SetLastError(ErrorCode); + return FALSE; + } + + SafeClose(KeyHandle); + } + + // + // Pre-disable the BHO in Internet Explorer to prevent annoying pop up. + // "The add-on blah from an unknown publisher is ready to use." + // + + KeyHandle = KxCfgpCreateKey( + HKEY_CURRENT_USER, + L"Software\\Microsoft\\Windows\\CurrentVersion\\Ext\\" + L"Settings\\{7EF224FC-1840-433C-9BCB-2951DE71DDBD}", + KEY_READ | KEY_WRITE, + TransactionHandle); + + ASSERT (KeyHandle != NULL); + + RegWriteI32(KeyHandle, NULL, L"Flags", 0x40); + SafeClose(KeyHandle); + } else { + // + // We are disabling the CpiwBypa BHO. + // + + ErrorCode = KxCfgpDeleteKey( + NULL, + L"\\Registry\\Machine\\Software\\Microsoft\\Windows\\CurrentVersion\\" + L"Explorer\\Browser Helper Objects\\{7EF224FC-1840-433C-9BCB-2951DE71DDBD}", + TransactionHandle); + + if (ErrorCode != ERROR_SUCCESS && ErrorCode != ERROR_FILE_NOT_FOUND) { + SetLastError(ErrorCode); + return FALSE; + } + + if (KexRtlOperatingSystemBitness() == 64) { + // delete the wow64 key as well + + ErrorCode = KxCfgpDeleteKey( + NULL, + L"\\Registry\\Machine\\Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\" + L"Explorer\\Browser Helper Objects\\{7EF224FC-1840-433C-9BCB-2951DE71DDBD}", + TransactionHandle); + + if (ErrorCode != ERROR_SUCCESS && ErrorCode != ERROR_FILE_NOT_FOUND) { + SetLastError(ErrorCode); + return FALSE; + } + } + + // + // Get rid of cached Internet Explorer BHO settings as well. + // HKCU\Software is not redirected on WOW64, so no need to do all the + // dancing around with Wow6432Node and whatever. + // + + { + HKEY CurrentUserKeyHandle; + + RtlOpenCurrentUser(KEY_READ, (PHANDLE) &CurrentUserKeyHandle); + + ErrorCode = KxCfgpDeleteKey( + CurrentUserKeyHandle, + L"Software\\Microsoft\\Windows\\CurrentVersion\\Ext\\" + L"Settings\\{7EF224FC-1840-433C-9BCB-2951DE71DDBD}", + TransactionHandle); + + SafeClose(CurrentUserKeyHandle); + } + + ASSERT (ErrorCode == ERROR_SUCCESS || ErrorCode == ERROR_FILE_NOT_FOUND); + } + + return TRUE; +} \ No newline at end of file diff --git a/KxCfgHlp/ctxmenu.c b/KxCfgHlp/ctxmenu.c new file mode 100644 index 0000000..8c8710f --- /dev/null +++ b/KxCfgHlp/ctxmenu.c @@ -0,0 +1,216 @@ +#include "buildcfg.h" +#include + +KXCFGDECLSPEC BOOLEAN KXCFGAPI KxCfgQueryShellContextMenuEntries( + OUT PBOOLEAN ExtendedMenu OPTIONAL) +{ + HKEY KeyHandle; + ULONG ErrorCode; + + ErrorCode = RegOpenKeyEx( + HKEY_CLASSES_ROOT, + L"exefile\\shell\\open_vxkex", + 0, + KEY_READ, + &KeyHandle); + + ASSERT (ErrorCode == ERROR_SUCCESS || ErrorCode == ERROR_FILE_NOT_FOUND); + + if (ErrorCode == ERROR_SUCCESS) { + if (ExtendedMenu) { + WCHAR DummyBuffer[4]; + + ErrorCode = RegReadString(KeyHandle, NULL, L"Extended", DummyBuffer, ARRAYSIZE(DummyBuffer)); + ASSERT (ErrorCode == ERROR_SUCCESS || ErrorCode == ERROR_FILE_NOT_FOUND); + + if (ErrorCode == ERROR_SUCCESS) { + *ExtendedMenu = TRUE; + } else { + *ExtendedMenu = FALSE; + } + } + + SafeClose(KeyHandle); + return TRUE; + } else { + return FALSE; + } +} + +KXCFGDECLSPEC BOOLEAN KXCFGAPI KxCfgConfigureShellContextMenuEntries( + IN BOOLEAN Enable, + IN BOOLEAN ExtendedMenu, + IN HANDLE TransactionHandle OPTIONAL) +{ + ULONG ErrorCode; + + if (Enable) { + BOOLEAN Success; + HKEY KeyHandle; + HKEY CommandKeyHandle; + WCHAR KexDir[MAX_PATH]; + WCHAR Command[MAX_PATH + 16]; + PCWSTR KeyName; + BOOLEAN AlreadyEnabledForMsi; + BOOLEAN AlreadyEnabled; + BOOLEAN AlreadyExtended; + + // + // See if already enabled + // + + AlreadyEnabled = KxCfgQueryShellContextMenuEntries(&AlreadyExtended); + + if (AlreadyEnabled) { + if (AlreadyExtended != ExtendedMenu) { + // we're changing which menu, so disable and re-enable + KxCfgConfigureShellContextMenuEntries(FALSE, FALSE, TransactionHandle); + } else { + // configuration is already as requested + return TRUE; + } + } + + // + // We are enabling the VxKex context menu entries. + // Assemble the command line for direct invocation of a VxKex-enabled program. + // + + Success = KxCfgGetKexDir(KexDir, ARRAYSIZE(KexDir)); + ASSERT (Success); + if (!Success) { + return FALSE; + } + + StringCchPrintf( + Command, + ARRAYSIZE(Command), + L"\"%s\\VxKexLdr.exe\" \"%%1\"", + KexDir); + + KeyName = L"exefile\\shell\\open_vxkex"; + AlreadyEnabledForMsi = FALSE; + KeyHandle = NULL; + CommandKeyHandle = NULL; + + // + // Write settings to registry. + // + +DoAgain: + try { + KeyHandle = KxCfgpCreateKey( + HKEY_CLASSES_ROOT, + KeyName, + KEY_READ | KEY_WRITE, + TransactionHandle); + + ASSERT (KeyHandle != NULL); + + if (!KeyHandle) { + return FALSE; + } + + CommandKeyHandle = KxCfgpCreateKey( + KeyHandle, + L"command", + KEY_READ | KEY_WRITE, + TransactionHandle); + + ASSERT (CommandKeyHandle != NULL); + + if (!CommandKeyHandle) { + return FALSE; + } + + ErrorCode = RegWriteString(KeyHandle, NULL, NULL, L"Run with VxKex enabled"); + ASSERT (ErrorCode == ERROR_SUCCESS); + + if (ErrorCode != ERROR_SUCCESS) { + SetLastError(ErrorCode); + return FALSE; + } + + ErrorCode = RegWriteString(CommandKeyHandle, NULL, NULL, Command); + ASSERT (ErrorCode == ERROR_SUCCESS); + + if (ErrorCode != ERROR_SUCCESS) { + SetLastError(ErrorCode); + return FALSE; + } + + if (ExtendedMenu) { + ErrorCode = RegWriteString(KeyHandle, NULL, L"Extended", L""); + ASSERT (ErrorCode == ERROR_SUCCESS); + + if (ErrorCode != ERROR_SUCCESS) { + SetLastError(ErrorCode); + return FALSE; + } + } + } finally { + SafeClose(KeyHandle); + SafeClose(CommandKeyHandle); + } + + if (!AlreadyEnabledForMsi) { + KeyName = L"Msi.Package\\shell\\open_vxkex"; + AlreadyEnabledForMsi = TRUE; + goto DoAgain; + } + } else { + // + // We are disabling the extended context menu. + // + + ErrorCode = KxCfgpDeleteKey( + NULL, + L"\\Registry\\Machine\\Software\\Classes\\exefile\\shell\\open_vxkex\\command", + TransactionHandle); + + ASSERT (ErrorCode == ERROR_SUCCESS || ErrorCode == ERROR_FILE_NOT_FOUND); + + if (ErrorCode != ERROR_SUCCESS && ErrorCode != ERROR_FILE_NOT_FOUND) { + SetLastError(ErrorCode); + return FALSE; + } + + ErrorCode = KxCfgpDeleteKey( + NULL, + L"\\Registry\\Machine\\Software\\Classes\\exefile\\shell\\open_vxkex", + TransactionHandle); + + ASSERT (ErrorCode == ERROR_SUCCESS || ErrorCode == ERROR_FILE_NOT_FOUND); + + if (ErrorCode != ERROR_SUCCESS && ErrorCode != ERROR_FILE_NOT_FOUND) { + SetLastError(ErrorCode); + return FALSE; + } + + ErrorCode = KxCfgpDeleteKey( + NULL, + L"\\Registry\\Machine\\Software\\Classes\\Msi.Package\\shell\\open_vxkex\\command", + TransactionHandle); + + ASSERT (ErrorCode == ERROR_SUCCESS || ErrorCode == ERROR_FILE_NOT_FOUND); + + if (ErrorCode != ERROR_SUCCESS && ErrorCode != ERROR_FILE_NOT_FOUND) { + SetLastError(ErrorCode); + return FALSE; + } + + ErrorCode = KxCfgpDeleteKey( + NULL, + L"\\Registry\\Machine\\Software\\Classes\\Msi.Package\\shell\\open_vxkex", + TransactionHandle); + + ASSERT (ErrorCode == ERROR_SUCCESS || ErrorCode == ERROR_FILE_NOT_FOUND); + + if (ErrorCode != ERROR_SUCCESS && ErrorCode != ERROR_FILE_NOT_FOUND) { + SetLastError(ErrorCode); + return FALSE; + } + } + + return TRUE; +} \ No newline at end of file diff --git a/KxCfgHlp/delcfg.c b/KxCfgHlp/delcfg.c new file mode 100644 index 0000000..3d509f5 --- /dev/null +++ b/KxCfgHlp/delcfg.c @@ -0,0 +1,505 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// delcfg.c +// +// Abstract: +// +// Contains functions for deleting VxKex configuration for a program. +// +// Author: +// +// vxiiduu (02-Feb-2024) +// +// Environment: +// +// Win32 mode. This code must be able to run without KexDll, as it is used +// in KexSetup. This code must function properly when run under WOW64. +// +// Revision History: +// +// vxiiduu 02-Feb-2024 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include +#include +#include + +// +// Delete VxKex configuration for a particular program. +// Returns TRUE on success and FALSE on failure. Call GetLastError() to obtain +// more information. +// Note: This function only handles post-rewrite VxKex configuration and not +// legacy configuration. There's a separate function to handle legacy +// configuration. +// +KXCFGDECLSPEC BOOLEAN KxCfgDeleteConfiguration( + IN PCWSTR ExeFullPath, + IN HANDLE TransactionHandle OPTIONAL) +{ + NTSTATUS Status; + ULONG ErrorCode; + BOOLEAN Success; + HKEY IfeoKeyHandle; + ULONG Index; + UNICODE_STRING ExeFullPathUS; + WCHAR VerifierDlls[256]; + BOOLEAN KexDllWasRemoved; + ULONG NumberOfValues; + ULONG NumberOfSubkeys; + + if (KxCfgpElevationRequired()) { + ASSERT (TransactionHandle == NULL); + return KxCfgpElevatedDeleteConfiguration(ExeFullPath); + } + + // + // 1. Open the IFEO key for the program. If there is no IFEO key for this + // program, then return TRUE, because there is already no VxKex config + // for this program. + // + // 2. Unconditionally delete all VxKex-specific values (KEX_*). + // + // 3. Unconditionally remove KexDll.dll from VerifierDlls (if + // VerifierDlls is present). If KexDll.dll was the only entry in + // VerifierDlls, then delete VerifierDlls. + // + // 4. If KexDll.dll was the only entry in VerifierDlls, turn off + // FLG_APPLICATION_VERIFIER in GlobalFlag. If GlobalFlag is now + // zero, delete GlobalFlag. + // + // 5. If FLG_APPLICATION_VERIFIER was removed from GlobalFlag, then + // delete VerifierFlags. + // + // 6. If there are no more values in the IFEO key for the program (besides + // FilterFullPath), delete the IFEO key for the program. + // + // 7. If there are no more subkeys under the IFEO EXE key (the key that + // has UseFilter in it), delete the IFEO EXE key. + // + + // + // Step 1. Open the IFEO key for the program. + // + + RtlInitUnicodeString(&ExeFullPathUS, ExeFullPath); + + Status = LdrOpenImageFileOptionsKey( + &ExeFullPathUS, + FALSE, + (PHANDLE) &IfeoKeyHandle); + + if (Status == STATUS_OBJECT_NAME_NOT_FOUND) { + return TRUE; + } else { + if (!NT_SUCCESS(Status)) { + SetLastError(RtlNtStatusToDosError(Status)); + return FALSE; + } + } + + // Note that the LdrOpenImageFileOptionsKey opens the key read-only. + // We will have to reopen it read-write. + Success = RegReOpenKey( + &IfeoKeyHandle, + KEY_READ | KEY_WRITE | DELETE, + TransactionHandle); + + if (!Success) { + return FALSE; + } + + try { + // + // Step 2. Unconditionally delete all VxKex-specific values. + // In order to reduce the maintenance requirements for this code, we will + // enumerate the values of the key and simply delete everything that has + // a name starting with "KEX_" (rather than hard-coding the names that we + // want to delete). + // + + Index = 0; + + while (TRUE) { + WCHAR ValueName[128]; + ULONG ValueNameCch; + + ValueNameCch = ARRAYSIZE(ValueName); + + ErrorCode = RegEnumValue( + IfeoKeyHandle, + Index++, + ValueName, + &ValueNameCch, + NULL, + NULL, + NULL, + NULL); + + if (ErrorCode == ERROR_NO_MORE_ITEMS) { + break; + } + + if (ErrorCode != ERROR_SUCCESS) { + continue; + } + + // remember, registry key and value names are case insensitive + if (StringBeginsWithI(ValueName, L"KEX_")) { + ErrorCode = RegDeleteValue(IfeoKeyHandle, ValueName); + ASSERT (ErrorCode == ERROR_SUCCESS); + + // + // This is required so that RegEnumValue doesn't skip certain values. + // It's a bit of a hack. The documentation for RegEnumValue says: + // + // While using RegEnumValue, an application should not call any + // registry functions that might change the key being queried. + // + // The quick and dirty solution which follows the documentation is to + // simply restart the enumeration from 0, but I've found that simply + // decrementing the index (remember, we incremented it after the call + // to RegEnumValue) works just as well. + // + + --Index; + } + } + + // + // Step 3. Unconditionally remove KexDll.dll from VerifierDlls. + // If there's a key called VerifierDlls under the IfeoKeyHandle, we will call + // a helper function to remove KexDll.dll from the list. + // + + ErrorCode = RegReadString( + IfeoKeyHandle, + NULL, + L"VerifierDlls", + VerifierDlls, + ARRAYSIZE(VerifierDlls)); + + if (ErrorCode == ERROR_FILE_NOT_FOUND) { + // VxKex isn't enabled. + return TRUE; + } else if (ErrorCode != ERROR_SUCCESS) { + SetLastError(ErrorCode); + return FALSE; + } + + KexDllWasRemoved = KxCfgpRemoveKexDllFromVerifierDlls(VerifierDlls); + + if (KexDllWasRemoved) { + if (VerifierDlls[0] == '\0') { + // VerifierDlls is now empty because we removed KexDll.dll from it. + // Because of that we will now delete the VerifierDlls value. + ErrorCode = RegDeleteValue(IfeoKeyHandle, L"VerifierDlls"); + } else { + // VerifierDlls was modified but it's not empty. We will write it + // back to the registry. + + ErrorCode = RegWriteString( + IfeoKeyHandle, + NULL, + L"VerifierDlls", + VerifierDlls); + } + + if (ErrorCode != ERROR_SUCCESS) { + SetLastError(ErrorCode); + return FALSE; + } + } + + // + // Step 4. If VerifierDlls is now empty, we will also remove FLG_APPLICATION_VERIFIER + // from the global flags. We will also remove FLG_SHOW_LDR_SNAPS since it is a flag + // that, at this point, we can infer only VxKex would have set. + // + + if (KexDllWasRemoved && VerifierDlls[0] == '\0') { + ULONG GlobalFlag; + + ErrorCode = RegReadI32(IfeoKeyHandle, NULL, L"GlobalFlag", &GlobalFlag); + + if (ErrorCode == ERROR_FILE_NOT_FOUND) { + return TRUE; + } else if (ErrorCode != ERROR_SUCCESS) { + SetLastError(ErrorCode); + return FALSE; + } + + if (GlobalFlag & (FLG_APPLICATION_VERIFIER | FLG_SHOW_LDR_SNAPS)) { + + GlobalFlag &= ~(FLG_APPLICATION_VERIFIER | FLG_SHOW_LDR_SNAPS); + + if (GlobalFlag == 0) { + // GlobalFlag is now empty, so delete it. + ErrorCode = RegDeleteValue(IfeoKeyHandle, L"GlobalFlag"); + } else { + // GlobalFlag still contains stuff. Write it back to registry. + ErrorCode = RegWriteI32(IfeoKeyHandle, NULL, L"GlobalFlag", GlobalFlag); + } + + if (ErrorCode != ERROR_SUCCESS) { + SetLastError(ErrorCode); + return FALSE; + } + + // + // Step 5. If FLG_APPLICATION_VERIFIER was removed from GlobalFlag, then + // delete VerifierFlags. + // + + RegDeleteValue(IfeoKeyHandle, L"VerifierFlags"); + } + } + + // + // Step 6. If there are no more values in the IFEO key for the program (besides + // FilterFullPath), delete the IFEO key for the program. + // + + ErrorCode = RegQueryInfoKey( + IfeoKeyHandle, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + &NumberOfValues, + NULL, + NULL, + NULL, + NULL); + + if (ErrorCode == ERROR_SUCCESS) { + if (NumberOfValues == 1) { + // One value under this key - check if its name is FilterFullPath. + // If so, set number of values to 0 (ignore the presence of FilterFullPath). + + ErrorCode = RegGetValue( + IfeoKeyHandle, + NULL, + L"FilterFullPath", + RRF_RT_ANY, + NULL, + NULL, + NULL); + + if (ErrorCode == ERROR_SUCCESS) { + NumberOfValues = 0; + } + } + + if (NumberOfValues == 0) { + // No values we care about here, so delete the key. + RegDeleteTree(IfeoKeyHandle, NULL); + NtDeleteKey(IfeoKeyHandle); + RegCloseKey(IfeoKeyHandle); + IfeoKeyHandle = NULL; + + // + // Step 7. If there are no more subkeys under the IFEO EXE key (the key that + // has UseFilter in it), delete the IFEO EXE key. + // + + { + PCWSTR ExeBaseName; + + ExeBaseName = PathFindFileName(ExeFullPath); + + Status = LdrOpenImageFileOptionsKey( + NULL, + FALSE, + (PHANDLE) &IfeoKeyHandle); + + ASSERT (NT_SUCCESS(Status)); + + IfeoKeyHandle = KxCfgpOpenKey( + IfeoKeyHandle, + ExeBaseName, + KEY_READ | KEY_WRITE | DELETE, + TransactionHandle); + + ASSERT (IfeoKeyHandle != NULL); + + if (!IfeoKeyHandle) { + // ignore the error, it's not critical + return TRUE; + } + } + + ErrorCode = RegQueryInfoKey( + IfeoKeyHandle, + NULL, + NULL, + NULL, + &NumberOfSubkeys, + NULL, + NULL, + &NumberOfValues, + NULL, + NULL, + NULL, + NULL); + + ASSERT (ErrorCode == ERROR_SUCCESS); + + if (ErrorCode != ERROR_SUCCESS) { + return TRUE; + } + + if (NumberOfSubkeys == 0 && NumberOfValues == 1) { + // Check if the value is UseFilter. If so, ignore it. + ErrorCode = RegGetValue( + IfeoKeyHandle, + NULL, + L"UseFilter", + RRF_RT_ANY, + NULL, + NULL, + NULL); + + if (ErrorCode == ERROR_SUCCESS) { + NumberOfValues = 0; + } + } + + if (NumberOfSubkeys == 0 && NumberOfValues == 0) { + RegDeleteTree(IfeoKeyHandle, NULL); + NtDeleteKey(IfeoKeyHandle); + } + } + } + } finally { + RegCloseKey(IfeoKeyHandle); + } + + return TRUE; +} + +// +// Check if a particular program has configuration for VxKex versions equal to +// or older than 0.0.0.3, and if so, delete it. +// Returns TRUE if legacy configuration was deleted, or FALSE if not. +// +// Legacy versions of VxKex do not use the Win7+ IFEO filter mechanism. +// Therefore, all we need to do is see if the IFEO base key has a subkey +// matching the EXE base name, and if so, check to see if it has a Debugger +// string value that contains "VxKexLdr.exe" somewhere in it. If so, delete +// the Debugger value. +// +// Legacy versions stored all auxiliary configuration such as WinVerSpoof etc. +// within the old "VxKexLdr" *HKCU* key, which we won't bother to touch. +// +KXCFGDECLSPEC BOOLEAN KXCFGAPI KxCfgDeleteLegacyConfiguration( + IN PCWSTR ExeFullPath, + IN HANDLE TransactionHandle OPTIONAL) +{ + NTSTATUS Status; + ULONG ErrorCode; + HKEY IfeoKey; + PCWSTR ExeBaseName; + WCHAR Debugger[MAX_PATH]; + ULONG NumberOfValues; + ULONG NumberOfSubkeys; + + ASSERT (ExeFullPath != NULL); + ASSERT (ExeFullPath[0] != '\0'); + + ExeBaseName = PathFindFileName(ExeFullPath); + if (!ExeBaseName) { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + Status = LdrOpenImageFileOptionsKey( + NULL, + FALSE, + (PHANDLE) &IfeoKey); + + if (!NT_SUCCESS(Status)) { + SetLastError(RtlNtStatusToDosError(Status)); + return FALSE; + } + + IfeoKey = KxCfgpOpenKey( + IfeoKey, + ExeBaseName, + KEY_READ | KEY_WRITE | DELETE, + TransactionHandle); + + if (!IfeoKey) { + ErrorCode = GetLastError(); + + if (ErrorCode == ERROR_FILE_NOT_FOUND) { + // no legacy config to delete + return TRUE; + } else { + SetLastError(ErrorCode); + return FALSE; + } + } + + try { + ErrorCode = RegReadString( + IfeoKey, + NULL, + L"Debugger", + Debugger, + ARRAYSIZE(Debugger)); + + if (ErrorCode == ERROR_FILE_NOT_FOUND) { + // No legacy configuration to delete. + return TRUE; + } else if (ErrorCode != ERROR_SUCCESS) { + SetLastError(ErrorCode); + return FALSE; + } + + if (StringSearchI(Debugger, L"VxKexLdr.exe")) { + // We have legacy configuration. Delete the Debugger value. + ErrorCode = RegDeleteValue(IfeoKey, L"Debugger"); + + if (ErrorCode != ERROR_SUCCESS) { + SetLastError(ErrorCode); + return FALSE; + } + } + + // + // If there are no more values or subkeys inside the IFEO EXE key, + // then delete the IFEO EXE key. + // + + ErrorCode = RegQueryInfoKey( + IfeoKey, + NULL, + NULL, + NULL, + &NumberOfSubkeys, + NULL, + NULL, + &NumberOfValues, + NULL, + NULL, + NULL, + NULL); + + if (ErrorCode == ERROR_SUCCESS) { + if (NumberOfSubkeys == 0 && NumberOfValues == 0) { + RegDeleteTree(IfeoKey, NULL); + NtDeleteKey(IfeoKey); + } + } + } finally { + RegCloseKey(IfeoKey); + } + + return TRUE; +} \ No newline at end of file diff --git a/KxCfgHlp/dskclnup.c b/KxCfgHlp/dskclnup.c new file mode 100644 index 0000000..2c4ac16 --- /dev/null +++ b/KxCfgHlp/dskclnup.c @@ -0,0 +1,109 @@ +#include "buildcfg.h" +#include +#include + +#define DDEVCF_DOSUBDIRS 0x00000001 // recursively search/remove +#define DDEVCF_REMOVEAFTERCLEAN 0x00000002 // remove from the registry after run once +#define DDEVCF_REMOVEREADONLY 0x00000004 // remove file even if it is read-only +#define DDEVCF_REMOVESYSTEM 0x00000008 // remove file even if it is system +#define DDEVCF_REMOVEHIDDEN 0x00000010 // remove file even if it is hidden +#define DDEVCF_DONTSHOWIFZERO 0x00000020 // don't show this cleaner if it has nothing to clean +#define DDEVCF_REMOVEDIRS 0x00000040 // Match filelist against directories and remove everything under them. +#define DDEVCF_RUNIFOUTOFDISKSPACE 0x00000080 // Only run if machine is out of disk space. +#define DDEVCF_REMOVEPARENTDIR 0x00000100 // remove the parent directory once done. +#define DDEVCF_PRIVATE_LASTACCESS 0x10000000 // use LastAccessTime + +// +// This file contains routines which install or uninstall the Disk Cleanup +// handler for the .vxl files in the log directory. +// +// The KexDir and LogDir parameters are intended only for use from the +// installer. Specify NULL if not running from the installer. +// + +KXCFGDECLSPEC BOOLEAN KXCFGAPI KxCfgInstallDiskCleanupHandler( + IN PCWSTR KexDir OPTIONAL, + IN PCWSTR LogDir OPTIONAL, + IN HANDLE TransactionHandle OPTIONAL) +{ + HKEY KeyHandle; + WCHAR IconPath[MAX_PATH]; + WCHAR LogDirBuffer[MAX_PATH]; + + // + // HKLM\Software\Microsoft\Windows\CurrentVersion\Explorer\ + // VolumeCaches (key) + // VxKex Log Files (*) (key) + // (Default) = REG_SZ "{C0E13E61-0CC6-11d1-BBB6-0060978B2AE6}" + // Description = REG_SZ "VxKex may create log files each time you launch an application, " + // "which consume disk space. Log files older than 3 days can safely " + // "be deleted." + // Display = REG_SZ "VxKex Log Files" + // FileList = REG_SZ "*.vxl" + // Flags = REG_DWORD (DDEVCF_DONTSHOWIFZERO) + // Folder = REG_SZ "" + // IconPath = REG_SZ "\VxlView.exe,1" + // LastAccess = REG_DWORD 0x00000003 + // + + KeyHandle = KxCfgpCreateKey( + HKEY_LOCAL_MACHINE, + L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\" + L"VolumeCaches\\VxKex Log Files", + KEY_READ | KEY_WRITE, + TransactionHandle); + + ASSERT (KeyHandle != NULL); + + if (!KeyHandle) { + return FALSE; + } + + if (KexDir) { + StringCchPrintf(IconPath, ARRAYSIZE(IconPath), L"%s\\VxlView.exe,1", KexDir); + } else { + KxCfgGetKexDir(IconPath, ARRAYSIZE(IconPath)); + PathCchAppend(IconPath, ARRAYSIZE(IconPath), L"VxlView.exe,1"); + } + + if (!LogDir) { + KxCfgQueryLoggingSettings(NULL, LogDirBuffer, ARRAYSIZE(LogDirBuffer)); + LogDir = LogDirBuffer; + } + + RegWriteString(KeyHandle, NULL, NULL, L"{C0E13E61-0CC6-11d1-BBB6-0060978B2AE6}"); + RegWriteString(KeyHandle, NULL, L"Display", L"VxKex Log Files"); + RegWriteString(KeyHandle, NULL, L"Description", + L"VxKex may create log files each time you launch an application, " + L"which consumes disk space. Log files older than 3 days can safely " + L"be deleted."); + RegWriteString(KeyHandle, NULL, L"Folder", LogDir); + RegWriteString(KeyHandle, NULL, L"FileList", L"*.vxl"); + RegWriteString(KeyHandle, NULL, L"IconPath", IconPath); + RegWriteI32(KeyHandle, NULL, L"LastAccess", 3); + RegWriteI32(KeyHandle, NULL, L"Flags", DDEVCF_DONTSHOWIFZERO); + + SafeClose(KeyHandle); + return TRUE; +} + +KXCFGDECLSPEC BOOLEAN KXCFGAPI KxCfgRemoveDiskCleanupHandler( + IN HANDLE TransactionHandle OPTIONAL) +{ + ULONG ErrorCode; + + ErrorCode = KxCfgpDeleteKey( + NULL, + L"\\Registry\\Machine\\Software\\Microsoft\\Windows\\CurrentVersion\\" + L"Explorer\\VolumeCaches\\VxKex Log Files", + TransactionHandle); + + ASSERT (ErrorCode == ERROR_SUCCESS || ErrorCode == ERROR_FILE_NOT_FOUND); + + if (ErrorCode != ERROR_SUCCESS && ErrorCode != ERROR_FILE_NOT_FOUND) { + SetLastError(ErrorCode); + return FALSE; + } + + return TRUE; +} \ No newline at end of file diff --git a/KxCfgHlp/elevate.c b/KxCfgHlp/elevate.c new file mode 100644 index 0000000..c11e797 --- /dev/null +++ b/KxCfgHlp/elevate.c @@ -0,0 +1,379 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// elevate.c +// +// Abstract: +// +// Functions related to elevation of privileges necessary to set VxKex +// settings as a non-elevated user. +// +// We want users to be able to change VxKex configuration without accepting +// a UAC prompt every time. However, normal users and non-elevated admins +// cannot write to the IFEO key, which we need to do. +// +// The solution we have chosen is to set up a scheduled task which runs +// as the local SYSTEM account. This scheduled task starts a helper +// process, KexCfg.exe, with command-line arguments which indicate which +// program to change VxKex configuration for and the configuration itself. +// +// Author: +// +// vxiiduu (03-Feb-2024) +// +// Environment: +// +// Win32 mode. This code must be able to run under the LOCAL SYSTEM +// account. +// +// Revision History: +// +// vxiiduu 03-Feb-2024 Initial creation. +// vxiiduu 22-Feb-2024 Use SafeRelease instead of if statement. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include +#include +#include + +// +// This function checks whether we need to elevate privileges in order to +// write to IFEO. The way we do this is simply by trying to open the key, +// and if we get STATUS_ACCESS_DENIED, then we can conclude we need to +// elevate. Simple. +// +BOOLEAN KxCfgpElevationRequired( + VOID) +{ + NTSTATUS Status; + HANDLE KeyHandle; + UNICODE_STRING KeyName; + OBJECT_ATTRIBUTES ObjectAttributes; + + RtlInitConstantUnicodeString( + &KeyName, + L"\\Registry\\Machine\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options"); + + InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE, NULL, NULL); + + Status = NtOpenKey( + &KeyHandle, + KEY_READ | KEY_WRITE, + &ObjectAttributes); + + if (Status == STATUS_ACCESS_DENIED) { + return TRUE; + } else { + NtClose(KeyHandle); + return FALSE; + } +} + +// +// This function is called when we are a NON elevated process which wants +// to set VxKex configuration for a program. +// +// In this function we will try to run the "VxKex Configuration Elevation Task" +// scheduled task. If that fails (for example: Task scheduler service not +// running, or the user deleted the scheduled task for some reason), we'll +// fall back to using ShellExecute and the UAC dialog might appear. +// +// The return value of this function is not a hard guarantee. If it returns +// FALSE, it definitely means the configuration was not applied. But if it +// returns TRUE that just means all the API calls succeeded. There is no +// verification to check whether the configuration was ACTUALLY applied in +// the registry. +// +// The KexCfg.exe helper program uses transactions to apply configuration, +// so we do have a guarantee that configuration won't be partially applied. +// +BOOLEAN KxCfgpElevatedSetConfiguration( + IN PCWSTR ExeFullPath, + IN PKXCFG_PROGRAM_CONFIGURATION Configuration) +{ + BOOLEAN Success; + + ASSERT (ExeFullPath != NULL); + ASSERT (Configuration != NULL); + ASSERT (!PathIsRelative(ExeFullPath)); + + // make sure this function doesn't get called by accident + ASSERT (KxCfgpElevationRequired() == TRUE); + + Success = KxCfgpElevatedSetConfigurationTaskScheduler(ExeFullPath, Configuration); + + if (!Success) { + // fallback + Success = KxCfgpElevatedSetConfigurationShellExecute(ExeFullPath, Configuration); + } + + return Success; +} + +BOOLEAN KxCfgpElevatedDeleteConfiguration( + IN PCWSTR ExeFullPath) +{ + KXCFG_PROGRAM_CONFIGURATION NullConfiguration; + RtlZeroMemory(&NullConfiguration, sizeof(NullConfiguration)); + return KxCfgpElevatedSetConfiguration(ExeFullPath, &NullConfiguration); +} + +BOOLEAN KxCfgpElevatedSetConfigurationTaskScheduler( + IN PCWSTR ExeFullPath, + IN PKXCFG_PROGRAM_CONFIGURATION Configuration) +{ + BOOLEAN Success; + HRESULT Result; + VARIANT VariantNull; + VARIANT VariantArgs; + LPSAFEARRAY ArgsArray; + SAFEARRAYBOUND ArgsArrayBounds; + WCHAR Args[512]; + LONG Zero; + + ITaskService *TaskService; + ITaskFolder *TaskFolder; + IRegisteredTask *KexCfgTask; + + ASSERT (ExeFullPath != NULL); + ASSERT (Configuration != NULL); + ASSERT (!PathIsRelative(ExeFullPath)); + + ZeroMemory(&VariantNull, sizeof(VariantNull)); + ArgsArray = NULL; + Zero = 0; + TaskService = NULL; + TaskFolder = NULL; + KexCfgTask = NULL; + + Result = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + if (FAILED(Result)) { + return FALSE; + } + + try { + Result = CoCreateInstance( + &CLSID_TaskScheduler, + NULL, + CLSCTX_INPROC_SERVER, + &IID_ITaskService, + (PPVOID) &TaskService); + + if (FAILED(Result)) { + return FALSE; + } + + ASSERT (TaskService != NULL); + + // + // Connect to the Task Scheduler service on the local machine. + // + + Result = ITaskService_Connect( + TaskService, + VariantNull, + VariantNull, + VariantNull, + VariantNull); + + if (FAILED(Result)) { + return FALSE; + } + + // + // Get an ITaskFolder interface for the root Task Scheduler folder. + // (i.e. %SystemRoot%\system32\Tasks) + // + + Result = ITaskService_GetFolder( + TaskService, + L"\\", + &TaskFolder); + + if (FAILED(Result)) { + return FALSE; + } + + ASSERT (TaskFolder != NULL); + + // + // Get an IRegisteredTask interface for the KexCfg elevation task. + // + + Result = ITaskFolder_GetTask( + TaskFolder, + KXCFG_ELEVATION_SCHTASK_NAME, + &KexCfgTask); + + if (FAILED(Result)) { + return FALSE; + } + + // + // Assemble the command line to pass to KexCfg. + // Note that /SCHTASK is automatically passed before these args because + // it was included in the task definition XML. + // + + Success = KxCfgpAssembleKexCfgCommandLine( + Args, + ARRAYSIZE(Args), + ExeFullPath, + Configuration); + + if (!Success) { + ASSERT (Success); + return FALSE; + } + + // + // Prepare a SAFEARRAY variant to pass to IRegisteredTask_Run(). + // I found through a lot of experimentation that this is required to + // make the variable arguments feature of Task Scheduler actually work, + // even though the documentation implies that you can just pass a BSTR + // variant (and this in fact does not create an error code at all). + // + // This entire SAFEARRAY thing, like all the rest of COM "technology", + // is an overcomplicated, obtuse piece of shit. + // + + ArgsArrayBounds.cElements = 1; + ArgsArrayBounds.lLbound = 0; + + ArgsArray = SafeArrayCreate(VT_BSTR, 1, &ArgsArrayBounds); + if (!ArgsArray) { + return FALSE; + } + + // The string allocated by SysAllocString is automatically freed by the + // SafeArrayDestroy function, which is called in the SEH finally block. + Result = SafeArrayPutElement( + ArgsArray, + &Zero, + SysAllocString(Args)); + + if (FAILED(Result)) { + return FALSE; + } + + VariantArgs.vt = VT_ARRAY | VT_BSTR; + VariantArgs.parray = ArgsArray; + + // + // Call the IRegisteredTask_Run method to finally call our task. + // + + Result = IRegisteredTask_Run( + KexCfgTask, + VariantArgs, + NULL); + + if (FAILED(Result)) { + return FALSE; + } + + } finally { + SafeRelease(TaskService); + SafeRelease(TaskFolder); + SafeRelease(KexCfgTask); + + if (ArgsArray) { + SafeArrayDestroy(ArgsArray); + ArgsArray = NULL; + } + + CoUninitialize(); + } + + return TRUE; +} + +BOOLEAN KxCfgpElevatedSetConfigurationShellExecute( + IN PCWSTR ExeFullPath, + IN PKXCFG_PROGRAM_CONFIGURATION Configuration) +{ + BOOLEAN Success; + WCHAR KexCfgFullPath[MAX_PATH]; + WCHAR Args[512]; + HINSTANCE ShellExecuteError; + + // + // get full path to KexCfg.exe + // + + Success = KxCfgGetKexDir( + KexCfgFullPath, + ARRAYSIZE(KexCfgFullPath)); + + if (!Success) { + return FALSE; + } + + PathCchAppend(KexCfgFullPath, ARRAYSIZE(KexCfgFullPath), L"KexCfg.exe"); + + // + // assemble command line for KexCfg + // + + Success = KxCfgpAssembleKexCfgCommandLine( + Args, + ARRAYSIZE(Args), + ExeFullPath, + Configuration); + + if (!Success) { + return FALSE; + } + + // + // call KexCfg elevated using ShellExecute + // + + ShellExecuteError = ShellExecute( + NULL, + L"runas", + KexCfgFullPath, + Args, + NULL, + SW_SHOWNORMAL); + + if ((ULONG) ShellExecuteError <= 32) { + return FALSE; + } + + return TRUE; +} + +BOOLEAN KxCfgpAssembleKexCfgCommandLine( + OUT PWSTR Buffer, + IN ULONG BufferCch, + IN PCWSTR ExeFullPath, + IN PKXCFG_PROGRAM_CONFIGURATION Configuration) +{ + HRESULT Result; + + ASSERT (Buffer != NULL); + ASSERT (BufferCch != 0); + ASSERT (ExeFullPath != NULL); + ASSERT (!PathIsRelative(ExeFullPath)); + ASSERT (Configuration != NULL); + + Result = StringCchPrintf( + Buffer, + BufferCch, + L"/EXE:\"%s\" /ENABLE:%lu /DISABLEFORCHILD:%lu " + L"/DISABLEAPPSPECIFIC:%lu /WINVERSPOOF:%lu /STRONGSPOOF:%08x", + ExeFullPath, + Configuration->Enabled, + Configuration->DisableForChild, + Configuration->DisableAppSpecificHacks, + Configuration->WinVerSpoof, + Configuration->StrongSpoofOptions); + + ASSERT (SUCCEEDED(Result)); + + return SUCCEEDED(Result); +} \ No newline at end of file diff --git a/KxCfgHlp/getcfg.c b/KxCfgHlp/getcfg.c new file mode 100644 index 0000000..df79419 --- /dev/null +++ b/KxCfgHlp/getcfg.c @@ -0,0 +1,304 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// getcfg.c +// +// Abstract: +// +// Contains functions for querying and enumerating VxKex configuration. +// +// Author: +// +// vxiiduu (02-Feb-2024) +// +// Environment: +// +// Win32 mode. This code must be able to run without KexDll, as it is used +// in KexSetup. This code must function properly when run under WOW64. +// +// Revision History: +// +// vxiiduu 02-Feb-2024 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include +#include +#include + +// +// Retrieve VxKex configuration for a particular program. +// Returns TRUE on success and FALSE on failure. Call GetLastError() to obtain +// more information. +// +KXCFGDECLSPEC BOOLEAN KXCFGAPI KxCfgGetConfiguration( + IN PCWSTR ExeFullPath, + OUT PKXCFG_PROGRAM_CONFIGURATION Configuration) +{ + NTSTATUS Status; + ULONG ErrorCode; + HKEY KeyHandle; + UNICODE_STRING ExeFullPathUS; + + WCHAR VerifierDlls[256]; + ULONG GlobalFlag; + ULONG KEX_DisableForChild; + ULONG KEX_DisableAppSpecific; + ULONG KEX_WinVerSpoof; + ULONG KEX_StrongVersionSpoof; + + ASSERT (ExeFullPath != NULL); + ASSERT (ExeFullPath[0] != '\0'); + ASSERT (Configuration != NULL); + + RtlZeroMemory(Configuration, sizeof(*Configuration)); + + // + // Open the IFEO key for this program. + // + + RtlInitUnicodeString(&ExeFullPathUS, ExeFullPath); + + Status = LdrOpenImageFileOptionsKey( + &ExeFullPathUS, + FALSE, + (PHANDLE) &KeyHandle); + + if (!NT_SUCCESS(Status)) { + SetLastError(RtlNtStatusToDosError(Status)); + return FALSE; + } + + // + // Read the values of IFEO registry keys relevant to configuration. + // + + ErrorCode = RegReadString( + KeyHandle, + NULL, + L"VerifierDlls", + VerifierDlls, + ARRAYSIZE(VerifierDlls)); + + if (ErrorCode != ERROR_SUCCESS) { + VerifierDlls[0] = '\0'; + } + + RegReadI32(KeyHandle, NULL, L"GlobalFlag", &GlobalFlag); + RegReadI32(KeyHandle, NULL, L"KEX_DisableForChild", &KEX_DisableForChild); + RegReadI32(KeyHandle, NULL, L"KEX_DisableAppSpecific", &KEX_DisableAppSpecific); + RegReadI32(KeyHandle, NULL, L"KEX_WinVerSpoof", &KEX_WinVerSpoof); + RegReadI32(KeyHandle, NULL, L"KEX_StrongVersionSpoof", &KEX_StrongVersionSpoof); + + RegCloseKey(KeyHandle); + + // + // Parse GlobalFlag and VerifierDlls to determine whether VxKex is enabled. + // + + if (GlobalFlag & FLG_APPLICATION_VERIFIER) { + if (StringSearchI(VerifierDlls, L"KexDll.dll")) { + Configuration->Enabled = TRUE; + } + } + + // + // Fill out the remaining members of the structure. + // + + Configuration->DisableForChild = !!KEX_DisableForChild; + Configuration->DisableAppSpecificHacks = !!KEX_DisableAppSpecific; + Configuration->WinVerSpoof = (KEX_WIN_VER_SPOOF) KEX_WinVerSpoof; + Configuration->StrongSpoofOptions = KEX_StrongVersionSpoof; + + return TRUE; +} + +// +// Enumerate all programs with VxKex enabled and call a function for each one. +// This function works for legacy configuration as well. +// +KXCFGDECLSPEC BOOLEAN KXCFGAPI KxCfgEnumerateConfiguration( + IN PKXCFG_ENUMERATE_CONFIGURATION_CALLBACK ConfigurationCallback, + IN PVOID CallbackExtraParameter) +{ + NTSTATUS Status; + HKEY IfeoBaseKey; + ULONG Index; + ULONG ErrorCode; + + ASSERT (ConfigurationCallback != NULL); + + // + // Open the IFEO base key. + // Note that we should not close this key. + // + + Status = LdrOpenImageFileOptionsKey( + NULL, + FALSE, + (PHANDLE) &IfeoBaseKey); + + if (!NT_SUCCESS(Status)) { + SetLastError(RtlNtStatusToDosError(Status)); + return FALSE; + } + + // + // Enumerate all the EXE keys. + // + + Index = 0; + + while (TRUE) { + BOOLEAN ContinueEnumeration; + HKEY IfeoExeKey; + WCHAR ExeBaseName[MAX_PATH]; + ULONG ExeBaseNameCch; + ULONG UseFilter; + WCHAR Debugger[MAX_PATH]; + ULONG SubkeyIndex; + + ExeBaseNameCch = ARRAYSIZE(ExeBaseName); + ErrorCode = RegEnumKeyEx( + IfeoBaseKey, + Index++, + ExeBaseName, + &ExeBaseNameCch, + NULL, + NULL, + NULL, + NULL); + + if (ErrorCode == ERROR_NO_MORE_ITEMS) { + break; + } + + if (ErrorCode != ERROR_SUCCESS) { + continue; + } + + // + // If not present, we Look for "Debugger" value and scan for "VxKexLdr.exe" + // to check for legacy configuration. + // + + ErrorCode = RegReadString( + IfeoBaseKey, + ExeBaseName, + L"Debugger", + Debugger, + ARRAYSIZE(Debugger)); + + if (ErrorCode != ERROR_SUCCESS) { + goto NoLegacyConfigurationFound; + } + + if (!StringSearchI(Debugger, L"VxKexLdr.exe")) { + goto NoLegacyConfigurationFound; + } + + // Legacy configuration has been found - call the callback + ContinueEnumeration = ConfigurationCallback(ExeBaseName, TRUE, CallbackExtraParameter); + if (!ContinueEnumeration) { + SetLastError(ERROR_SUCCESS); + return FALSE; + } + +NoLegacyConfigurationFound: + // + // Check for "UseFilter" value. If so, we will need to enum subkeys. + // + + ErrorCode = RegReadI32(IfeoBaseKey, ExeBaseName, L"UseFilter", &UseFilter); + if (ErrorCode != ERROR_SUCCESS || UseFilter == 0) { + continue; + } + + ErrorCode = RegOpenKeyEx( + IfeoBaseKey, + ExeBaseName, + 0, + KEY_READ, + &IfeoExeKey); + + if (ErrorCode != ERROR_SUCCESS) { + continue; + } + + SubkeyIndex = 0; + + while (TRUE) { + WCHAR SubkeyName[32]; + ULONG SubkeyNameCch; + WCHAR FilterFullPath[MAX_PATH]; + WCHAR VerifierDlls[256]; + ULONG GlobalFlag; + + SubkeyNameCch = ARRAYSIZE(SubkeyName); + ErrorCode = RegEnumKeyEx( + IfeoExeKey, + SubkeyIndex++, + SubkeyName, + &SubkeyNameCch, + NULL, + NULL, + NULL, + NULL); + + if (ErrorCode == ERROR_NO_MORE_ITEMS) { + break; + } + + if (ErrorCode != ERROR_SUCCESS) { + continue; + } + + RegReadI32(IfeoExeKey, SubkeyName, L"GlobalFlag", &GlobalFlag); + + if ((GlobalFlag & FLG_APPLICATION_VERIFIER) == 0) { + continue; + } + + RegReadString( + IfeoExeKey, + SubkeyName, + L"FilterFullPath", + FilterFullPath, + ARRAYSIZE(FilterFullPath)); + + if (FilterFullPath[0] == '\0') { + continue; + } + + RegReadString( + IfeoExeKey, + SubkeyName, + L"VerifierDlls", + VerifierDlls, + ARRAYSIZE(VerifierDlls)); + + if (!StringSearchI(VerifierDlls, L"KexDll.dll")) { + continue; + } + + // + // VxKex configuration has been found, call the callback. + // + + ContinueEnumeration = ConfigurationCallback(FilterFullPath, FALSE, CallbackExtraParameter); + + if (!ContinueEnumeration) { + RegCloseKey(IfeoExeKey); + SetLastError(ERROR_SUCCESS); + return FALSE; + } + } + + RegCloseKey(IfeoExeKey); + } + + return TRUE; +} \ No newline at end of file diff --git a/KxCfgHlp/kexdir.c b/KxCfgHlp/kexdir.c new file mode 100644 index 0000000..1410ff6 --- /dev/null +++ b/KxCfgHlp/kexdir.c @@ -0,0 +1,74 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// kexdir.c +// +// Abstract: +// +// Contains functions for querying KexDir. +// +// Author: +// +// vxiiduu (02-Feb-2024) +// +// Environment: +// +// Win32 mode. This code must be able to run without KexDll, as it is used +// in KexSetup. This code must function properly when run under WOW64. +// +// Revision History: +// +// vxiiduu 02-Feb-2024 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include +#include +#include + +KXCFGDECLSPEC BOOLEAN KXCFGAPI KxCfgGetKexDir( + OUT PWSTR Buffer, + IN ULONG BufferCch) +{ + HKEY VxKexKeyHandle; + ULONG ErrorCode; + + ASSERT (Buffer != NULL); + ASSERT (BufferCch != 0); + + Buffer[0] = '\0'; + + VxKexKeyHandle = KxCfgOpenVxKexRegistryKey( + FALSE, + KEY_READ, + NULL); + + if (!VxKexKeyHandle) { + VxKexKeyHandle = KxCfgOpenLegacyVxKexRegistryKey( + FALSE, + KEY_READ, + NULL); + + if (!VxKexKeyHandle) { + return FALSE; + } + } + + ErrorCode = RegReadString(VxKexKeyHandle, NULL, L"KexDir", Buffer, BufferCch); + RegCloseKey(VxKexKeyHandle); + + if (ErrorCode != ERROR_SUCCESS) { + SetLastError(ErrorCode); + return FALSE; + } + + ASSERT (!PathIsRelative(Buffer)); + if (PathIsRelative(Buffer)) { + SetLastError(ERROR_INVALID_DATA); + return FALSE; + } + + return TRUE; +} \ No newline at end of file diff --git a/KxCfgHlp/kxcfgp.c b/KxCfgHlp/kxcfgp.c new file mode 100644 index 0000000..fae2d45 --- /dev/null +++ b/KxCfgHlp/kxcfgp.c @@ -0,0 +1,419 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// kxcfgp.c +// +// Abstract: +// +// Utility functions for KxCfgHlp. +// +// Author: +// +// vxiiduu (03-Feb-2024) +// +// Environment: +// +// Win32 mode. This code must be able to run without KexDll, as it is used +// in KexSetup. This code must function properly when run under WOW64. +// +// Revision History: +// +// vxiiduu 03-Feb-2024 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include +#include + +// +// This function removes KexDll.dll from a space-separated list (same format as +// you'd find in the IFEO VerifierDlls value). +// +// Returns TRUE if KexDll.dll was removed, FALSE if it was not found. +// If KexDll.dll was the only verifier DLL in the list, then this function will +// cause VerifierDlls to be an empty string. +// +// As a side effect, VerifierDlls will be lowercased. This does not affect the +// normal operation of Application Verifier, since their verifier DLLs are all +// lower case anyway. +// +// For reference: The function within NTDLL that parses the VerifierDlls list is +// called AVrfpParseVerifierDllsString. It is tolerant of double-spacing. +// +BOOLEAN KxCfgpRemoveKexDllFromVerifierDlls( + IN PWSTR VerifierDlls) +{ + ULONG Index; + PWSTR KexDll; + PCWSTR AfterKexDll; + BOOLEAN NonSeparatorCharacterFound; + + ASSERT (VerifierDlls != NULL); + + KexDll = (PWSTR) StringFindI(VerifierDlls, L"kexdll.dll"); + + if (!KexDll) { + // KexDll.dll was not found in the verifier DLLs list. + return FALSE; + } + + // + // Shift backwards the contents of the string in order to remove the + // "kexdll.dll" entry. + // + + AfterKexDll = KexDll + StringLiteralLength(L"kexdll.dll"); + Index = 0; + + do { + KexDll[Index] = AfterKexDll[Index]; + } until (AfterKexDll[Index++] == '\0'); + + // + // Check to see if the VerifierDlls string consists of only separators. + // (note: AVrfpParseVerifierDllsString considers ' ' and '\t' to be separators) + // + + Index = 0; + NonSeparatorCharacterFound = FALSE; + + until (VerifierDlls[Index] == '\0') { + if (VerifierDlls[Index] != ' ' && VerifierDlls[Index] != '\t') { + NonSeparatorCharacterFound = TRUE; + break; + } + + ++Index; + } + + if (NonSeparatorCharacterFound == FALSE) { + // The whole thing is just whitespace. + // Overwrite it so that it becomes an empty string. + VerifierDlls[0] = '\0'; + } + + return TRUE; +} + +BOOLEAN KxCfgpCreateIfeoKeyForProgram( + IN PCWSTR ExeFullPath, + OUT PHKEY KeyHandle, + IN HANDLE TransactionHandle OPTIONAL) +{ + NTSTATUS Status; + ULONG ErrorCode; + WCHAR IfeoSubkeyPath[MAX_PATH]; + PCWSTR ExeBaseName; + HKEY IfeoBaseKey; + HKEY IfeoExeKey; + HKEY IfeoSubkey; + + LARGE_INTEGER RandomSeed; + ULONG RandomIdentifier; + ULONG RandomIdentifier2; + + ASSERT (ExeFullPath != NULL); + ASSERT (ExeFullPath[0] != '\0'); + ASSERT (KeyHandle != NULL); + + *KeyHandle = NULL; + + IfeoBaseKey = NULL; + IfeoExeKey = NULL; + IfeoSubkey = NULL; + + // + // Open the IFEO base key. + // + + // Note: Since we are opening the base key handle, we do not need to, + // and in fact should not close it after we are done using it. + // See ntdll!RtlOpenImageFileOptionsKey for more information. + Status = LdrOpenImageFileOptionsKey( + NULL, + FALSE, + (PHANDLE) &IfeoBaseKey); + + ASSERT (NT_SUCCESS(Status)); + + // + // Generate a random identifier to name the subkey inside the EXE key. + // + + // this "algorithm" is not cryptographically secure or anything but it + // should prevent time-based collisions + QueryPerformanceCounter(&RandomSeed); + RandomSeed.LowPart += (ULONG) (NtCurrentTeb()->ClientId.UniqueProcess); + RandomSeed.HighPart -= (ULONG) (NtCurrentTeb()->ClientId.UniqueThread); + RandomIdentifier = RtlRandomEx(&RandomSeed.LowPart); + RandomIdentifier2 = RtlRandomEx((PULONG) &RandomSeed.HighPart); + + ExeBaseName = PathFindFileName(ExeFullPath); + if (ExeBaseName == NULL) { + // caller must have passed some garbage path... + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + StringCchPrintf( + IfeoSubkeyPath, + ARRAYSIZE(IfeoSubkeyPath), + L"%s\\VxKex_%08I32X%08I32X", + PathFindFileName(ExeFullPath), + RandomIdentifier, + RandomIdentifier2); + + // + // Create the EXE key and the IFEO key for the program. + // + + if (TransactionHandle) { + ErrorCode = RegCreateKeyTransacted( + IfeoBaseKey, + IfeoSubkeyPath, + 0, + NULL, + 0, + KEY_READ | KEY_WRITE, + NULL, + &IfeoSubkey, + NULL, + TransactionHandle, + NULL); + + if (ErrorCode == ERROR_SUCCESS) { + ErrorCode = RegOpenKeyTransacted( + IfeoBaseKey, + PathFindFileName(ExeFullPath), + 0, + KEY_READ | KEY_WRITE, + &IfeoExeKey, + TransactionHandle, + NULL); + } + } else { + ErrorCode = RegCreateKeyEx( + IfeoBaseKey, + IfeoSubkeyPath, + 0, + NULL, + 0, + KEY_READ | KEY_WRITE, + NULL, + &IfeoSubkey, + NULL); + + if (ErrorCode == ERROR_SUCCESS) { + ErrorCode = RegOpenKeyEx( + IfeoBaseKey, + PathFindFileName(ExeFullPath), + 0, + KEY_READ | KEY_WRITE, + &IfeoExeKey); + } + } + + if (ErrorCode != ERROR_SUCCESS) { + if (IfeoSubkey) { + RegCloseKey(IfeoSubkey); + } + + SetLastError(ErrorCode); + return FALSE; + } + + ErrorCode = RegWriteI32(IfeoExeKey, NULL, L"UseFilter", 1); + RegCloseKey(IfeoExeKey); + + if (ErrorCode != ERROR_SUCCESS) { + RegCloseKey(IfeoSubkey); + SetLastError(ErrorCode); + return FALSE; + } + + ErrorCode = RegWriteString( + IfeoSubkey, + NULL, + L"FilterFullPath", + ExeFullPath); + + if (ErrorCode != ERROR_SUCCESS) { + RegCloseKey(IfeoSubkey); + SetLastError(ErrorCode); + return FALSE; + } + + *KeyHandle = IfeoSubkey; + return TRUE; +} + +HKEY KxCfgpCreateKey( + IN HKEY RootDirectory, + IN PCWSTR KeyPath, + IN ACCESS_MASK DesiredAccess, + IN HANDLE TransactionHandle OPTIONAL) +{ + HKEY KeyHandle; + ULONG ErrorCode; + + // 64-bit key is the default, no need to specify. + ASSERT (!(DesiredAccess & KEY_WOW64_64KEY)); + + unless (DesiredAccess & KEY_WOW64_32KEY) { + DesiredAccess |= KEY_WOW64_64KEY; + } + + if (TransactionHandle) { + ErrorCode = RegCreateKeyTransacted( + RootDirectory, + KeyPath, + 0, + NULL, + 0, + DesiredAccess, + NULL, + &KeyHandle, + NULL, + TransactionHandle, + NULL); + } else { + ErrorCode = RegCreateKeyEx( + RootDirectory, + KeyPath, + 0, + NULL, + 0, + DesiredAccess, + NULL, + &KeyHandle, + NULL); + } + + if (ErrorCode != ERROR_SUCCESS) { + SetLastError(ErrorCode); + return NULL; + } + + return KeyHandle; +} + +HKEY KxCfgpOpenKey( + IN HKEY RootDirectory, + IN PCWSTR KeyPath, + IN ACCESS_MASK DesiredAccess, + IN HANDLE TransactionHandle OPTIONAL) +{ + HKEY KeyHandle; + ULONG ErrorCode; + + // 64-bit key is the default, no need to specify. + ASSERT (!(DesiredAccess & KEY_WOW64_64KEY)); + + unless (DesiredAccess & KEY_WOW64_32KEY) { + DesiredAccess |= KEY_WOW64_64KEY; + } + + if (TransactionHandle) { + ErrorCode = RegOpenKeyTransacted( + RootDirectory, + KeyPath, + 0, + DesiredAccess, + &KeyHandle, + TransactionHandle, + NULL); + } else { + ErrorCode = RegOpenKeyEx( + RootDirectory, + KeyPath, + 0, + DesiredAccess, + &KeyHandle); + } + + if (ErrorCode != ERROR_SUCCESS) { + SetLastError(ErrorCode); + return NULL; + } + + return KeyHandle; +} + +// +// WARNING: This API is unlike the others since it takes a NT style registry path +// and doesn't accept predefined handles. Instead of HKEY_LOCAL_MACHINE, prefix KeyPath +// with \Registry\Machine. Instead of HKEY_CURRENT_USER, use RtlOpenCurrentUser. +// + +ULONG KxCfgpDeleteKey( + IN HKEY KeyHandle OPTIONAL, + IN PCWSTR KeyPath OPTIONAL, + IN HANDLE TransactionHandle OPTIONAL) +{ + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING KeyPathUS; + + if (KeyPath || TransactionHandle) { + // + // We need to either re-open the root key transacted or open the key path + // so that we can delete it with NtDeleteKey. + // + + if (KeyPath) { + Status = RtlInitUnicodeStringEx(&KeyPathUS, KeyPath); + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + return RtlNtStatusToDosError(Status); + } + + InitializeObjectAttributes( + &ObjectAttributes, + &KeyPathUS, + OBJ_CASE_INSENSITIVE, + KeyHandle, + NULL); + } else { + InitializeObjectAttributes( + &ObjectAttributes, + NULL, + 0, + KeyHandle, + NULL); + } + + if (TransactionHandle) { + Status = NtOpenKeyTransacted( + (PHANDLE) &KeyHandle, + DELETE | KEY_WOW64_64KEY, + &ObjectAttributes, + TransactionHandle); + } else { + Status = NtOpenKey( + (PHANDLE) &KeyHandle, + DELETE | KEY_WOW64_64KEY, + &ObjectAttributes); + } + + if (Status == STATUS_OBJECT_NAME_NOT_FOUND) { + return ERROR_SUCCESS; + } + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + return RtlNtStatusToDosError(Status); + } + + Status = NtDeleteKey(KeyHandle); + SafeClose(KeyHandle); + } else { + Status = NtDeleteKey(KeyHandle); + } + + ASSERT (NT_SUCCESS(Status)); + return RtlNtStatusToDosError(Status); +} \ No newline at end of file diff --git a/KxCfgHlp/logging.c b/KxCfgHlp/logging.c new file mode 100644 index 0000000..98491f6 --- /dev/null +++ b/KxCfgHlp/logging.c @@ -0,0 +1,120 @@ +#include "buildcfg.h" +#include +#include + +KXCFGDECLSPEC BOOLEAN KXCFGAPI KxCfgQueryLoggingSettings( + OUT PBOOLEAN IsEnabled OPTIONAL, + OUT PWSTR LogDir OPTIONAL, + IN ULONG LogDirCch) +{ + HKEY VxKexUserKeyHandle; + ULONG ErrorCode; + + ASSERT (!!LogDir == !!LogDirCch); + + if (IsEnabled != NULL) { + *IsEnabled = TRUE; + } + + if (LogDir != NULL) { + LogDir[0] = '\0'; + } + + VxKexUserKeyHandle = KxCfgOpenVxKexRegistryKey( + TRUE, + KEY_READ, + NULL); + + ASSERT (VxKexUserKeyHandle != NULL); + + if (!VxKexUserKeyHandle) { + return FALSE; + } + + if (IsEnabled != NULL) { + ULONG DisableLogging; + + ErrorCode = RegReadI32(VxKexUserKeyHandle, NULL, L"DisableLogging", &DisableLogging); + ASSERT (ErrorCode == ERROR_SUCCESS || ErrorCode == ERROR_FILE_NOT_FOUND); + + *IsEnabled = !DisableLogging; + } + + if (LogDir != NULL) { + ErrorCode = RegReadString(VxKexUserKeyHandle, NULL, L"LogDir", LogDir, LogDirCch); + ASSERT (ErrorCode == ERROR_SUCCESS || ErrorCode == ERROR_FILE_NOT_FOUND); + } + + SafeClose(VxKexUserKeyHandle); + return TRUE; +} + +// +// If LogDir is NULL, it will be set to "%localappdata%\vxkex\logs". +// Environment variables are expanded in LogDir. +// +KXCFGDECLSPEC BOOLEAN KXCFGAPI KxCfgConfigureLoggingSettings( + IN BOOLEAN Enabled, + IN PCWSTR LogDir OPTIONAL, + IN HANDLE TransactionHandle OPTIONAL) +{ + HKEY VxKexUserKeyHandle; + ULONG LogDirExpandedCch; + WCHAR LogDirExpanded[MAX_PATH]; + ULONG ErrorCode; + + if (!LogDir || LogDir[0] == '\0') { + LogDir = L"%%LOCALAPPDATA%%\\VxKex\\Logs"; + } + + LogDirExpandedCch = ExpandEnvironmentStrings( + LogDir, + LogDirExpanded, + ARRAYSIZE(LogDirExpanded)); + + ASSERT (LogDirExpandedCch != 0); + + if (LogDirExpandedCch == 0) { + return FALSE; + } + + VxKexUserKeyHandle = KxCfgOpenVxKexRegistryKey( + TRUE, + KEY_READ | KEY_WRITE, + TransactionHandle); + + ASSERT (VxKexUserKeyHandle != NULL); + + if (!VxKexUserKeyHandle) { + return FALSE; + } + + try { + ErrorCode = RegWriteI32(VxKexUserKeyHandle, NULL, L"DisableLogging", !Enabled); + ASSERT (ErrorCode == ERROR_SUCCESS); + + if (ErrorCode != ERROR_SUCCESS) { + SetLastError(ErrorCode); + return FALSE; + } + + ErrorCode = RegWriteString(VxKexUserKeyHandle, NULL, L"LogDir", LogDirExpanded); + ASSERT (ErrorCode == ERROR_SUCCESS); + + if (ErrorCode != ERROR_SUCCESS) { + SetLastError(ErrorCode); + return FALSE; + } + } finally { + SafeClose(VxKexUserKeyHandle); + } + + // + // Refresh the disk cleanup handler, since it depends on the location of + // the log directory. + // + + KxCfgInstallDiskCleanupHandler(NULL, NULL, TransactionHandle); + + return TRUE; +} \ No newline at end of file diff --git a/KxCfgHlp/msisup.c b/KxCfgHlp/msisup.c new file mode 100644 index 0000000..650fce1 --- /dev/null +++ b/KxCfgHlp/msisup.c @@ -0,0 +1,42 @@ +#include "buildcfg.h" +#include + +KXCFGDECLSPEC BOOLEAN WINAPI KxCfgEnableVxKexForMsiexec( + IN BOOLEAN Enable, + IN HANDLE TransactionHandle OPTIONAL) +{ + WCHAR MsiexecPath[MAX_PATH]; + + GetSystemDirectory(MsiexecPath, ARRAYSIZE(MsiexecPath)); + PathCchAppend(MsiexecPath, ARRAYSIZE(MsiexecPath), L"msiexec.exe"); + + if (Enable) { + KXCFG_PROGRAM_CONFIGURATION MsiexecConfiguration; + + RtlZeroMemory(&MsiexecConfiguration, sizeof(MsiexecConfiguration)); + MsiexecConfiguration.Enabled = TRUE; + + return KxCfgSetConfiguration(MsiexecPath, &MsiexecConfiguration, TransactionHandle); + } else { + return KxCfgDeleteConfiguration(MsiexecPath, TransactionHandle); + } +} + +KXCFGDECLSPEC BOOLEAN WINAPI KxCfgQueryVxKexEnabledForMsiexec( + VOID) +{ + BOOLEAN Success; + WCHAR MsiexecPath[MAX_PATH]; + KXCFG_PROGRAM_CONFIGURATION MsiexecConfiguration; + + GetSystemDirectory(MsiexecPath, ARRAYSIZE(MsiexecPath)); + PathCchAppend(MsiexecPath, ARRAYSIZE(MsiexecPath), L"msiexec.exe"); + + Success = KxCfgGetConfiguration(MsiexecPath, &MsiexecConfiguration); + + if (!Success || !MsiexecConfiguration.Enabled) { + return FALSE; + } + + return TRUE; +} \ No newline at end of file diff --git a/KxCfgHlp/openkey.c b/KxCfgHlp/openkey.c new file mode 100644 index 0000000..8dd9ae8 --- /dev/null +++ b/KxCfgHlp/openkey.c @@ -0,0 +1,62 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// openkey.c +// +// Abstract: +// +// Contains functions for opening the VxKex HKLM/HKCU key. +// +// Author: +// +// vxiiduu (02-Feb-2024) +// +// Environment: +// +// Win32 mode. This code must be able to run without KexDll, as it is used +// in KexSetup. This code must function properly when run under WOW64. +// +// Revision History: +// +// vxiiduu 02-Feb-2024 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include +#include + +// +// Open the HKLM or HKCU VxKex key. +// This function does not allow WOW64 redirection. +// Returns NULL on failure. Call GetLastError for more information. +// +KXCFGDECLSPEC HKEY KXCFGAPI KxCfgOpenVxKexRegistryKey( + IN BOOLEAN PerUserKey, + IN ACCESS_MASK DesiredAccess, + IN HANDLE TransactionHandle OPTIONAL) +{ + return KxCfgpOpenKey( + PerUserKey ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, + L"Software\\VXsoft\\VxKex", + DesiredAccess, + TransactionHandle); +} + +// +// Open the legacy, pre-rewrite VxKex key. +// This function does not allow WOW64 redirection. +// Returns NULL on failure. Call GetLastError for more information. +// +KXCFGDECLSPEC HKEY KXCFGAPI KxCfgOpenLegacyVxKexRegistryKey( + IN BOOLEAN PerUserKey, + IN ACCESS_MASK DesiredAccess, + IN HANDLE TransactionHandle OPTIONAL) +{ + return KxCfgpOpenKey( + PerUserKey ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, + L"Software\\VXsoft\\VxKexLdr", + DesiredAccess, + TransactionHandle); +} \ No newline at end of file diff --git a/KxCfgHlp/setcfg.c b/KxCfgHlp/setcfg.c new file mode 100644 index 0000000..a3148a8 --- /dev/null +++ b/KxCfgHlp/setcfg.c @@ -0,0 +1,249 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// setcfg.c +// +// Abstract: +// +// Contains functions for setting VxKex configuration. +// +// Author: +// +// vxiiduu (02-Feb-2024) +// +// Environment: +// +// Win32 mode. This code must be able to run without KexDll, as it is used +// in KexSetup. This code must function properly when run under WOW64. +// +// Revision History: +// +// vxiiduu 02-Feb-2024 Initial creation. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include +#include +#include + +// +// Configure VxKex for a particular program according to the configuration data +// structure. +// Returns TRUE on success and FALSE on failure. Call GetLastError() to obtain +// more information. +// +KXCFGDECLSPEC BOOLEAN KXCFGAPI KxCfgSetConfiguration( + IN PCWSTR ExeFullPath, + IN PKXCFG_PROGRAM_CONFIGURATION Configuration, + IN HANDLE TransactionHandle OPTIONAL) +{ + NTSTATUS Status; + ULONG ErrorCode; + BOOLEAN Success; + HKEY KeyHandle; + UNICODE_STRING ExeFullPathUS; + + WCHAR VerifierDlls[256]; + ULONG GlobalFlag; + ULONG VerifierFlags; + ULONG KEX_DisableForChild; + ULONG KEX_DisableAppSpecific; + ULONG KEX_WinVerSpoof; + ULONG KEX_StrongVersionSpoof; + + ASSERT (ExeFullPath != NULL); + ASSERT (ExeFullPath[0] != '\0'); + ASSERT (Configuration != NULL); + + if (KxCfgpElevationRequired()) { + // Transactions cannot be applied cross-process. (Well, they can, but + // we don't implement that kind of functionality because it's a huge pain + // to get the transaction handles duplicated into elevated processes. + // Plus, we don't need to do it.) + ASSERT (TransactionHandle == NULL); + + return KxCfgpElevatedSetConfiguration(ExeFullPath, Configuration); + } + + VerifierDlls[0] = '\0'; + + // + // The first thing to do is see whether we are doing the special case of + // removing all the configuration values. A Configuration structure consisting + // of all zeroes means deleting the VxKex configuration for a program. + // + + if (Configuration->Enabled == FALSE && + Configuration->DisableForChild == FALSE && + Configuration->DisableAppSpecificHacks == FALSE && + Configuration->WinVerSpoof == WinVerSpoofNone && + Configuration->StrongSpoofOptions == 0) { + + return KxCfgDeleteConfiguration(ExeFullPath, TransactionHandle); + } + + // + // Step 1. Open or create the IFEO key for this program. + // + + RtlInitUnicodeString(&ExeFullPathUS, ExeFullPath); + + Status = LdrOpenImageFileOptionsKey( + &ExeFullPathUS, + FALSE, + (PHANDLE) &KeyHandle); + + if (!NT_SUCCESS(Status)) { + // Probably there is simply no IFEO key for this program. + // So we will call a helper function that creates one for us. + Success = KxCfgpCreateIfeoKeyForProgram( + ExeFullPath, + &KeyHandle, + TransactionHandle); + + if (!Success) { + return FALSE; + } + } else { + // + // The key returned directly from LdrOpenImageFileOptionsKey might be + // one that doesn't use FilterFullPath. In this case, we will still have + // to call the helper function to create a proper one for us. + // + + // Check whether that's the case by querying the existence of FilterFullPath + // key under the IFEO subkey for the program. + ErrorCode = RegGetValue( + KeyHandle, + NULL, + L"FilterFullPath", + RRF_RT_REG_SZ, + NULL, + NULL, + NULL); + + if (ErrorCode == ERROR_SUCCESS) { + // All good. + // The key is opened read only by LdrOpenImageFileOptionsKey, and is + // not transacted. Reopen read-write. + + Success = RegReOpenKey(&KeyHandle, KEY_READ | KEY_WRITE, TransactionHandle); + if (!Success) { + RegCloseKey(KeyHandle); + return FALSE; + } + } else { + // We need to create a proper IFEO subkey that uses a filter. + // Do this by calling a helper function: + RegCloseKey(KeyHandle); + + Success = KxCfgpCreateIfeoKeyForProgram( + ExeFullPath, + &KeyHandle, + TransactionHandle); + + if (!Success) { + return FALSE; + } + } + } + + // + // Step 2. Set registry values. + // + + RegReadI32(KeyHandle, NULL, L"GlobalFlag", &GlobalFlag); + RegReadI32(KeyHandle, NULL, L"VerifierFlags", &VerifierFlags); + + RegReadString( + KeyHandle, + NULL, + L"VerifierDlls", + VerifierDlls, + ARRAYSIZE(VerifierDlls)); + + if (Configuration->Enabled == FALSE) { + BOOLEAN KexDllRemovedFromVerifierDlls; + + // + // 1. Remove KexDll from the list of VerifierDlls. + // 2. If there are no more VerifierDlls, turn off Application Verifier. + // + + KexDllRemovedFromVerifierDlls = KxCfgpRemoveKexDllFromVerifierDlls(VerifierDlls); + + if (KexDllRemovedFromVerifierDlls && VerifierDlls[0] == '\0') { + GlobalFlag &= ~FLG_APPLICATION_VERIFIER; + VerifierFlags = 0; + } + } else { + // + // 1. Add KexDll to the list of VerifierDlls. + // 2. Turn on Application Verifier and set VerifierFlags to 0x80000000. + // + + if (!StringSearchI(VerifierDlls, L"kexdll.dll")) { + StringCchCat( + VerifierDlls, + ARRAYSIZE(VerifierDlls), + VerifierDlls[0] == '\0' ? L"kexdll.dll" : L" kexdll.dll"); + } + + GlobalFlag |= FLG_APPLICATION_VERIFIER; + VerifierFlags = 0x80000000; + } + + KEX_DisableForChild = Configuration->DisableForChild; + KEX_DisableAppSpecific = Configuration->DisableAppSpecificHacks; + KEX_WinVerSpoof = Configuration->WinVerSpoof; + KEX_StrongVersionSpoof = Configuration->StrongSpoofOptions; + + try { + ErrorCode = RegWriteI32(KeyHandle, NULL, L"KEX_DisableForChild", KEX_DisableForChild); + if (ErrorCode) { + return FALSE; + } + + ErrorCode = RegWriteI32(KeyHandle, NULL, L"KEX_DisableAppSpecific", KEX_DisableAppSpecific); + if (ErrorCode) { + return FALSE; + } + + ErrorCode = RegWriteI32(KeyHandle, NULL, L"KEX_WinVerSpoof", KEX_WinVerSpoof); + if (ErrorCode) { + return FALSE; + } + + ErrorCode = RegWriteI32(KeyHandle, NULL, L"KEX_StrongVersionSpoof", KEX_StrongVersionSpoof); + if (ErrorCode) { + return FALSE; + } + + ErrorCode = RegWriteI32(KeyHandle, NULL, L"GlobalFlag", GlobalFlag); + if (ErrorCode) { + return FALSE; + } + + ErrorCode = RegWriteI32(KeyHandle, NULL, L"VerifierFlags", VerifierFlags); + if (ErrorCode) { + return FALSE; + } + + ErrorCode = RegWriteString( + KeyHandle, + NULL, + L"VerifierDlls", + VerifierDlls); + + if (ErrorCode) { + return FALSE; + } + } finally { + SetLastError(ErrorCode); + RegCloseKey(KeyHandle); + } + + return TRUE; +} \ No newline at end of file diff --git a/README.md b/README.md index 43f5959..64d23b7 100644 --- a/README.md +++ b/README.md @@ -32,27 +32,44 @@ success. I hope to address this shortcoming in a future release. **A:** The list of compatible applications includes, but is not limited to: - Bespoke Synth - Blender -- Calibre (limited functionality) +- Calibre +- Chromium (including Ungoogled Chromium) +- Citra - Commander Wars +- Cygwin +- Dasel +- ElectronMail +- Firefox +- GIMP (2.99.18) +- GitHub Desktop - HandBrake - Kodi - MKVToolNix - MongoDB +- MPC-Qt - MPV +- MPV.NET +- Opera +- osu!lazer - Python - qBittorrent - QMMP - Qt Creator - Rufus - Steel Bank Common Lisp +- Spotify - Steinberg SpectraLayers - TeamTalk +- WinDbg (classic from Windows 11 SDK, and preview) - Yuzu (gameplay was not tested) - Zig See the **Application Compatibility List.docx** file, which is installed together with VxKex, for more information. +The majority of Qt6 applications will work, and many Electron applications will +work as well. + **Q: Does VxKex modify system files? Will it make my system unstable?** **A:** VxKex does not modify any system files. Its effect on the whole system is @@ -65,8 +82,8 @@ will remain as stable as it always is. **A:** VxKex is only designed to work with Service Pack 1 installed. Users of Windows 7 RTM can try to use it, but I don't know if it will install or work. -Many programs require the KB2533623 security update to run, so it is a good -idea to install that one. The Windows 7 platform update also helps. +Many programs require KB2533623 and KB2670838 in order to run. It is a good +idea to install those two updates. **Q: If I have ESUs (Extended Security Updates) installed, can I use VxKex?** @@ -95,3 +112,10 @@ API extension is accomplished by editing the program's DLL import table so that instead of importing from Windows 8/8.1/10 DLLs, it imports to VxKex DLLs instead. These VxKex DLLs contain implementations of Windows API functions which were introduced in newer versions of Windows. + +Donations +========= + +If you would like to support development, consider making a donation. + +- https://paypal.me/vxiiduu diff --git a/VxKex.sln b/VxKex.sln new file mode 100644 index 0000000..251c28f --- /dev/null +++ b/VxKex.sln @@ -0,0 +1,413 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Common Headers", "Common Headers", "{14941210-9C7B-4C81-8BE8-9B0AEDEE42C3}" + ProjectSection(SolutionItems) = preProject + 00-Common Headers\KexAssert.h = 00-Common Headers\KexAssert.h + 00-Common Headers\KexComm.h = 00-Common Headers\KexComm.h + 00-Common Headers\KexComp.h = 00-Common Headers\KexComp.h + 00-Common Headers\KexCpu.h = 00-Common Headers\KexCpu.h + 00-Common Headers\KexDll.h = 00-Common Headers\KexDll.h + 00-Common Headers\KexGui.h = 00-Common Headers\KexGui.h + 00-Common Headers\KexLnk.h = 00-Common Headers\KexLnk.h + 00-Common Headers\KexPathCch.h = 00-Common Headers\KexPathCch.h + 00-Common Headers\KexStrSafe.h = 00-Common Headers\KexStrSafe.h + 00-Common Headers\KexTypes.h = 00-Common Headers\KexTypes.h + 00-Common Headers\KexVer.h = 00-Common Headers\KexVer.h + 00-Common Headers\KexW32ML.h = 00-Common Headers\KexW32ML.h + 00-Common Headers\KseGuid.h = 00-Common Headers\KseGuid.h + 00-Common Headers\KxBase.h = 00-Common Headers\KxBase.h + 00-Common Headers\KxCfgHlp.h = 00-Common Headers\KxCfgHlp.h + 00-Common Headers\KxCom.h = 00-Common Headers\KxCom.h + 00-Common Headers\KxDx.h = 00-Common Headers\KxDx.h + 00-Common Headers\KxMi.h = 00-Common Headers\KxMi.h + 00-Common Headers\KxUser.h = 00-Common Headers\KxUser.h + 00-Common Headers\NtDll.h = 00-Common Headers\NtDll.h + 00-Common Headers\NtKrnl.h = 00-Common Headers\NtKrnl.h + 00-Common Headers\NtStrSafe.h = 00-Common Headers\NtStrSafe.h + 00-Common Headers\SafeAlloc.h = 00-Common Headers\SafeAlloc.h + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Documentation", "Documentation", "{2684E7C2-7A0E-4086-ABAB-75C37A620CFB}" + ProjectSection(SolutionItems) = preProject + 00-Documentation\Changelog.txt = 00-Documentation\Changelog.txt + 00-Documentation\Debugging KexDll.txt = 00-Documentation\Debugging KexDll.txt + 00-Documentation\KexSetup responsibilities.txt = 00-Documentation\KexSetup responsibilities.txt + 00-Documentation\Notes on IFEO.txt = 00-Documentation\Notes on IFEO.txt + 00-Documentation\Source File Header.txt = 00-Documentation\Source File Header.txt + 00-Documentation\VxKex Registry Keys (Legacy).txt = 00-Documentation\VxKex Registry Keys (Legacy).txt + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Development Utilities", "Development Utilities", "{086A9AB4-23AC-41C8-A422-A7CF714413CF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VxlView", "VxlView\VxlView.vcxproj", "{9875FF3B-A8F4-4221-B27A-0D092F5CF816}" + ProjectSection(ProjectDependencies) = postProject + {F7DCFF24-19CD-4FE6-BDDF-6029670E77D6} = {F7DCFF24-19CD-4FE6-BDDF-6029670E77D6} + {7656FF69-D1A3-4FA1-AB04-7C0089777CA7} = {7656FF69-D1A3-4FA1-AB04-7C0089777CA7} + {1AEF4F9B-7227-4B51-9ADE-CDED9427C0B5} = {1AEF4F9B-7227-4B51-9ADE-CDED9427C0B5} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KexGui", "KexGui\KexGui.vcxproj", "{F7DCFF24-19CD-4FE6-BDDF-6029670E77D6}" + ProjectSection(ProjectDependencies) = postProject + {66231B4E-059F-42B5-8B6D-0B22AD6DFC64} = {66231B4E-059F-42B5-8B6D-0B22AD6DFC64} + {1AEF4F9B-7227-4B51-9ADE-CDED9427C0B5} = {1AEF4F9B-7227-4B51-9ADE-CDED9427C0B5} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KexW32ML", "KexW32ML\KexW32ML.vcxproj", "{1AEF4F9B-7227-4B51-9ADE-CDED9427C0B5}" + ProjectSection(ProjectDependencies) = postProject + {0B434F56-68C4-4627-BE2F-BE20A5E97F2D} = {0B434F56-68C4-4627-BE2F-BE20A5E97F2D} + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{BCB55952-3128-454B-B060-C53A3C1CCA14}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KexDll", "KexDll\KexDll.vcxproj", "{7656FF69-D1A3-4FA1-AB04-7C0089777CA7}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extended DLLs", "Extended DLLs", "{C38F02E0-99EB-4B94-8134-5F777118B1A8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KexExprt", "01-Development Utilities\KexExprt\KexExprt.vcxproj", "{FEC92998-8D28-42CE-886D-21D17A263D24}" + ProjectSection(ProjectDependencies) = postProject + {F7DCFF24-19CD-4FE6-BDDF-6029670E77D6} = {F7DCFF24-19CD-4FE6-BDDF-6029670E77D6} + {7656FF69-D1A3-4FA1-AB04-7C0089777CA7} = {7656FF69-D1A3-4FA1-AB04-7C0089777CA7} + {1AEF4F9B-7227-4B51-9ADE-CDED9427C0B5} = {1AEF4F9B-7227-4B51-9ADE-CDED9427C0B5} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "loggingtest", "01-Tests\loggingtest\loggingtest.vcxproj", "{8EEB6A31-BBE4-450C-AEF6-E4F81F63EF46}" + ProjectSection(ProjectDependencies) = postProject + {F7DCFF24-19CD-4FE6-BDDF-6029670E77D6} = {F7DCFF24-19CD-4FE6-BDDF-6029670E77D6} + {7656FF69-D1A3-4FA1-AB04-7C0089777CA7} = {7656FF69-D1A3-4FA1-AB04-7C0089777CA7} + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "VxKex Components", "VxKex Components", "{55923E6A-021C-40AF-9977-C9E3072B697B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KexShlEx", "KexShlEx\KexShlEx.vcxproj", "{0C454599-73FB-4F57-B8C9-0BE68AF3110E}" + ProjectSection(ProjectDependencies) = postProject + {F7DCFF24-19CD-4FE6-BDDF-6029670E77D6} = {F7DCFF24-19CD-4FE6-BDDF-6029670E77D6} + {66231B4E-059F-42B5-8B6D-0B22AD6DFC64} = {66231B4E-059F-42B5-8B6D-0B22AD6DFC64} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KexSetup", "KexSetup\KexSetup.vcxproj", "{F435A5D6-D589-41FA-8430-90C37401DE17}" + ProjectSection(ProjectDependencies) = postProject + {BB5B3C11-F77A-4C46-AE5A-76153DD0CA79} = {BB5B3C11-F77A-4C46-AE5A-76153DD0CA79} + {4168C61E-16EF-4196-9E3D-D21F18234CAF} = {4168C61E-16EF-4196-9E3D-D21F18234CAF} + {F7DCFF24-19CD-4FE6-BDDF-6029670E77D6} = {F7DCFF24-19CD-4FE6-BDDF-6029670E77D6} + {9875FF3B-A8F4-4221-B27A-0D092F5CF816} = {9875FF3B-A8F4-4221-B27A-0D092F5CF816} + {66231B4E-059F-42B5-8B6D-0B22AD6DFC64} = {66231B4E-059F-42B5-8B6D-0B22AD6DFC64} + {0B434F56-68C4-4627-BE2F-BE20A5E97F2D} = {0B434F56-68C4-4627-BE2F-BE20A5E97F2D} + {4E267C5E-6A43-4E20-A2B9-8C9526F97215} = {4E267C5E-6A43-4E20-A2B9-8C9526F97215} + {7656FF69-D1A3-4FA1-AB04-7C0089777CA7} = {7656FF69-D1A3-4FA1-AB04-7C0089777CA7} + {A5627E7A-6C18-4D04-A7DE-5445F39E1CAB} = {A5627E7A-6C18-4D04-A7DE-5445F39E1CAB} + {36F79680-796A-465E-9C87-0E76034AF16B} = {36F79680-796A-465E-9C87-0E76034AF16B} + {0C454599-73FB-4F57-B8C9-0BE68AF3110E} = {0C454599-73FB-4F57-B8C9-0BE68AF3110E} + {1AEF4F9B-7227-4B51-9ADE-CDED9427C0B5} = {1AEF4F9B-7227-4B51-9ADE-CDED9427C0B5} + {8C66849E-892F-41DD-AF5D-11DC22FCA013} = {8C66849E-892F-41DD-AF5D-11DC22FCA013} + {7B17BE9E-D4A6-4652-BDE8-80FDE0DDC7D4} = {7B17BE9E-D4A6-4652-BDE8-80FDE0DDC7D4} + {0AF7A2B2-BB6A-49EF-99BF-886525F51821} = {0AF7A2B2-BB6A-49EF-99BF-886525F51821} + {FED853B7-B02A-49FC-9FA9-DFCF8479841A} = {FED853B7-B02A-49FC-9FA9-DFCF8479841A} + {FA376FCE-E31C-4601-B4A7-3B976911E777} = {FA376FCE-E31C-4601-B4A7-3B976911E777} + {F6B2D0CE-1772-4A76-BB46-FEB7C179370A} = {F6B2D0CE-1772-4A76-BB46-FEB7C179370A} + {64D4ABD4-4C7D-47AC-A7E2-BCB6D1F1CF81} = {64D4ABD4-4C7D-47AC-A7E2-BCB6D1F1CF81} + {155D1AED-B54E-4C90-8152-246E0C01EC84} = {155D1AED-B54E-4C90-8152-246E0C01EC84} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KxCfgHlp", "KxCfgHlp\KxCfgHlp.vcxproj", "{66231B4E-059F-42B5-8B6D-0B22AD6DFC64}" + ProjectSection(ProjectDependencies) = postProject + {0B434F56-68C4-4627-BE2F-BE20A5E97F2D} = {0B434F56-68C4-4627-BE2F-BE20A5E97F2D} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KexCfg", "KexCfg\KexCfg.vcxproj", "{F6B2D0CE-1772-4A76-BB46-FEB7C179370A}" + ProjectSection(ProjectDependencies) = postProject + {F7DCFF24-19CD-4FE6-BDDF-6029670E77D6} = {F7DCFF24-19CD-4FE6-BDDF-6029670E77D6} + {66231B4E-059F-42B5-8B6D-0B22AD6DFC64} = {66231B4E-059F-42B5-8B6D-0B22AD6DFC64} + {0B434F56-68C4-4627-BE2F-BE20A5E97F2D} = {0B434F56-68C4-4627-BE2F-BE20A5E97F2D} + {1AEF4F9B-7227-4B51-9ADE-CDED9427C0B5} = {1AEF4F9B-7227-4B51-9ADE-CDED9427C0B5} + {FED853B7-B02A-49FC-9FA9-DFCF8479841A} = {FED853B7-B02A-49FC-9FA9-DFCF8479841A} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KxBase", "01-Extended DLLs\KxBase\kxbase.vcxproj", "{0AF7A2B2-BB6A-49EF-99BF-886525F51821}" + ProjectSection(ProjectDependencies) = postProject + {7656FF69-D1A3-4FA1-AB04-7C0089777CA7} = {7656FF69-D1A3-4FA1-AB04-7C0089777CA7} + {7B17BE9E-D4A6-4652-BDE8-80FDE0DDC7D4} = {7B17BE9E-D4A6-4652-BDE8-80FDE0DDC7D4} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KexPathCch", "KexPathCch\KexPathCch.vcxproj", "{0B434F56-68C4-4627-BE2F-BE20A5E97F2D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KxCom", "01-Extended DLLs\KxCom\KxCom.vcxproj", "{A5627E7A-6C18-4D04-A7DE-5445F39E1CAB}" + ProjectSection(ProjectDependencies) = postProject + {7656FF69-D1A3-4FA1-AB04-7C0089777CA7} = {7656FF69-D1A3-4FA1-AB04-7C0089777CA7} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KxDx", "01-Extended DLLs\KxDx\KxDx.vcxproj", "{8C66849E-892F-41DD-AF5D-11DC22FCA013}" + ProjectSection(ProjectDependencies) = postProject + {7656FF69-D1A3-4FA1-AB04-7C0089777CA7} = {7656FF69-D1A3-4FA1-AB04-7C0089777CA7} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KxNt", "01-Extended DLLs\KxNt\KxNt.vcxproj", "{7B17BE9E-D4A6-4652-BDE8-80FDE0DDC7D4}" + ProjectSection(ProjectDependencies) = postProject + {7656FF69-D1A3-4FA1-AB04-7C0089777CA7} = {7656FF69-D1A3-4FA1-AB04-7C0089777CA7} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KxUser", "01-Extended DLLs\KxUser\KxUser.vcxproj", "{BB5B3C11-F77A-4C46-AE5A-76153DD0CA79}" + ProjectSection(ProjectDependencies) = postProject + {7656FF69-D1A3-4FA1-AB04-7C0089777CA7} = {7656FF69-D1A3-4FA1-AB04-7C0089777CA7} + {0AF7A2B2-BB6A-49EF-99BF-886525F51821} = {0AF7A2B2-BB6A-49EF-99BF-886525F51821} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CpiwBypa", "CpiwBypa\CpiwBypa.vcxproj", "{FED853B7-B02A-49FC-9FA9-DFCF8479841A}" + ProjectSection(ProjectDependencies) = postProject + {0B434F56-68C4-4627-BE2F-BE20A5E97F2D} = {0B434F56-68C4-4627-BE2F-BE20A5E97F2D} + {7656FF69-D1A3-4FA1-AB04-7C0089777CA7} = {7656FF69-D1A3-4FA1-AB04-7C0089777CA7} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VxKexLdr", "VxKexLdr\VxKexLdr.vcxproj", "{155D1AED-B54E-4C90-8152-246E0C01EC84}" + ProjectSection(ProjectDependencies) = postProject + {F7DCFF24-19CD-4FE6-BDDF-6029670E77D6} = {F7DCFF24-19CD-4FE6-BDDF-6029670E77D6} + {7656FF69-D1A3-4FA1-AB04-7C0089777CA7} = {7656FF69-D1A3-4FA1-AB04-7C0089777CA7} + {1AEF4F9B-7227-4B51-9ADE-CDED9427C0B5} = {1AEF4F9B-7227-4B51-9ADE-CDED9427C0B5} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KexKMSD", "KexKMSD\KexKMSD.vcxproj", "{9F42E7FC-954C-4473-A9FC-F354CEC77393}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KxCrt", "01-Extended DLLs\KxCrt\KxCrt.vcxproj", "{64D4ABD4-4C7D-47AC-A7E2-BCB6D1F1CF81}" + ProjectSection(ProjectDependencies) = postProject + {7656FF69-D1A3-4FA1-AB04-7C0089777CA7} = {7656FF69-D1A3-4FA1-AB04-7C0089777CA7} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KxAdvapi", "01-Extended DLLs\KxAdvapi\KxAdvapi.vcxproj", "{4E267C5E-6A43-4E20-A2B9-8C9526F97215}" + ProjectSection(ProjectDependencies) = postProject + {7656FF69-D1A3-4FA1-AB04-7C0089777CA7} = {7656FF69-D1A3-4FA1-AB04-7C0089777CA7} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KxNet", "01-Extended DLLs\KxNet\KxNet.vcxproj", "{36F79680-796A-465E-9C87-0E76034AF16B}" + ProjectSection(ProjectDependencies) = postProject + {7656FF69-D1A3-4FA1-AB04-7C0089777CA7} = {7656FF69-D1A3-4FA1-AB04-7C0089777CA7} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KxCryp", "01-Extended DLLs\KxCryp\KxCryp.vcxproj", "{FA376FCE-E31C-4601-B4A7-3B976911E777}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KxMi", "01-Extended DLLs\KxMi\KxMi.vcxproj", "{4168C61E-16EF-4196-9E3D-D21F18234CAF}" + ProjectSection(ProjectDependencies) = postProject + {7656FF69-D1A3-4FA1-AB04-7C0089777CA7} = {7656FF69-D1A3-4FA1-AB04-7C0089777CA7} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9875FF3B-A8F4-4221-B27A-0D092F5CF816}.Debug|Win32.ActiveCfg = Debug|Win32 + {9875FF3B-A8F4-4221-B27A-0D092F5CF816}.Debug|Win32.Build.0 = Debug|Win32 + {9875FF3B-A8F4-4221-B27A-0D092F5CF816}.Debug|x64.ActiveCfg = Debug|x64 + {9875FF3B-A8F4-4221-B27A-0D092F5CF816}.Debug|x64.Build.0 = Debug|x64 + {9875FF3B-A8F4-4221-B27A-0D092F5CF816}.Release|Win32.ActiveCfg = Release|Win32 + {9875FF3B-A8F4-4221-B27A-0D092F5CF816}.Release|Win32.Build.0 = Release|Win32 + {9875FF3B-A8F4-4221-B27A-0D092F5CF816}.Release|x64.ActiveCfg = Release|x64 + {9875FF3B-A8F4-4221-B27A-0D092F5CF816}.Release|x64.Build.0 = Release|x64 + {F7DCFF24-19CD-4FE6-BDDF-6029670E77D6}.Debug|Win32.ActiveCfg = Debug|Win32 + {F7DCFF24-19CD-4FE6-BDDF-6029670E77D6}.Debug|Win32.Build.0 = Debug|Win32 + {F7DCFF24-19CD-4FE6-BDDF-6029670E77D6}.Debug|x64.ActiveCfg = Debug|x64 + {F7DCFF24-19CD-4FE6-BDDF-6029670E77D6}.Debug|x64.Build.0 = Debug|x64 + {F7DCFF24-19CD-4FE6-BDDF-6029670E77D6}.Release|Win32.ActiveCfg = Release|Win32 + {F7DCFF24-19CD-4FE6-BDDF-6029670E77D6}.Release|Win32.Build.0 = Release|Win32 + {F7DCFF24-19CD-4FE6-BDDF-6029670E77D6}.Release|x64.ActiveCfg = Release|x64 + {F7DCFF24-19CD-4FE6-BDDF-6029670E77D6}.Release|x64.Build.0 = Release|x64 + {1AEF4F9B-7227-4B51-9ADE-CDED9427C0B5}.Debug|Win32.ActiveCfg = Debug|Win32 + {1AEF4F9B-7227-4B51-9ADE-CDED9427C0B5}.Debug|Win32.Build.0 = Debug|Win32 + {1AEF4F9B-7227-4B51-9ADE-CDED9427C0B5}.Debug|x64.ActiveCfg = Debug|x64 + {1AEF4F9B-7227-4B51-9ADE-CDED9427C0B5}.Debug|x64.Build.0 = Debug|x64 + {1AEF4F9B-7227-4B51-9ADE-CDED9427C0B5}.Release|Win32.ActiveCfg = Release|Win32 + {1AEF4F9B-7227-4B51-9ADE-CDED9427C0B5}.Release|Win32.Build.0 = Release|Win32 + {1AEF4F9B-7227-4B51-9ADE-CDED9427C0B5}.Release|x64.ActiveCfg = Release|x64 + {1AEF4F9B-7227-4B51-9ADE-CDED9427C0B5}.Release|x64.Build.0 = Release|x64 + {7656FF69-D1A3-4FA1-AB04-7C0089777CA7}.Debug|Win32.ActiveCfg = Debug|Win32 + {7656FF69-D1A3-4FA1-AB04-7C0089777CA7}.Debug|Win32.Build.0 = Debug|Win32 + {7656FF69-D1A3-4FA1-AB04-7C0089777CA7}.Debug|x64.ActiveCfg = Debug|x64 + {7656FF69-D1A3-4FA1-AB04-7C0089777CA7}.Debug|x64.Build.0 = Debug|x64 + {7656FF69-D1A3-4FA1-AB04-7C0089777CA7}.Release|Win32.ActiveCfg = Release|Win32 + {7656FF69-D1A3-4FA1-AB04-7C0089777CA7}.Release|Win32.Build.0 = Release|Win32 + {7656FF69-D1A3-4FA1-AB04-7C0089777CA7}.Release|x64.ActiveCfg = Release|x64 + {7656FF69-D1A3-4FA1-AB04-7C0089777CA7}.Release|x64.Build.0 = Release|x64 + {FEC92998-8D28-42CE-886D-21D17A263D24}.Debug|Win32.ActiveCfg = Debug|Win32 + {FEC92998-8D28-42CE-886D-21D17A263D24}.Debug|x64.ActiveCfg = Debug|x64 + {FEC92998-8D28-42CE-886D-21D17A263D24}.Release|Win32.ActiveCfg = Debug|x64 + {FEC92998-8D28-42CE-886D-21D17A263D24}.Release|x64.ActiveCfg = Debug|x64 + {FEC92998-8D28-42CE-886D-21D17A263D24}.Release|x64.Build.0 = Debug|x64 + {8EEB6A31-BBE4-450C-AEF6-E4F81F63EF46}.Debug|Win32.ActiveCfg = Debug|Win32 + {8EEB6A31-BBE4-450C-AEF6-E4F81F63EF46}.Debug|x64.ActiveCfg = Debug|x64 + {8EEB6A31-BBE4-450C-AEF6-E4F81F63EF46}.Release|Win32.ActiveCfg = Release|Win32 + {8EEB6A31-BBE4-450C-AEF6-E4F81F63EF46}.Release|x64.ActiveCfg = Release|x64 + {0C454599-73FB-4F57-B8C9-0BE68AF3110E}.Debug|Win32.ActiveCfg = Debug|Win32 + {0C454599-73FB-4F57-B8C9-0BE68AF3110E}.Debug|Win32.Build.0 = Debug|Win32 + {0C454599-73FB-4F57-B8C9-0BE68AF3110E}.Debug|x64.ActiveCfg = Debug|x64 + {0C454599-73FB-4F57-B8C9-0BE68AF3110E}.Debug|x64.Build.0 = Debug|x64 + {0C454599-73FB-4F57-B8C9-0BE68AF3110E}.Release|Win32.ActiveCfg = Release|Win32 + {0C454599-73FB-4F57-B8C9-0BE68AF3110E}.Release|Win32.Build.0 = Release|Win32 + {0C454599-73FB-4F57-B8C9-0BE68AF3110E}.Release|x64.ActiveCfg = Release|x64 + {0C454599-73FB-4F57-B8C9-0BE68AF3110E}.Release|x64.Build.0 = Release|x64 + {F435A5D6-D589-41FA-8430-90C37401DE17}.Debug|Win32.ActiveCfg = Debug|Win32 + {F435A5D6-D589-41FA-8430-90C37401DE17}.Debug|Win32.Build.0 = Debug|Win32 + {F435A5D6-D589-41FA-8430-90C37401DE17}.Debug|x64.ActiveCfg = Debug|Win32 + {F435A5D6-D589-41FA-8430-90C37401DE17}.Release|Win32.ActiveCfg = Release|Win32 + {F435A5D6-D589-41FA-8430-90C37401DE17}.Release|Win32.Build.0 = Release|Win32 + {F435A5D6-D589-41FA-8430-90C37401DE17}.Release|x64.ActiveCfg = Release|Win32 + {F435A5D6-D589-41FA-8430-90C37401DE17}.Release|x64.Build.0 = Release|Win32 + {66231B4E-059F-42B5-8B6D-0B22AD6DFC64}.Debug|Win32.ActiveCfg = Debug|Win32 + {66231B4E-059F-42B5-8B6D-0B22AD6DFC64}.Debug|Win32.Build.0 = Debug|Win32 + {66231B4E-059F-42B5-8B6D-0B22AD6DFC64}.Debug|x64.ActiveCfg = Debug|x64 + {66231B4E-059F-42B5-8B6D-0B22AD6DFC64}.Debug|x64.Build.0 = Debug|x64 + {66231B4E-059F-42B5-8B6D-0B22AD6DFC64}.Release|Win32.ActiveCfg = Release|Win32 + {66231B4E-059F-42B5-8B6D-0B22AD6DFC64}.Release|Win32.Build.0 = Release|Win32 + {66231B4E-059F-42B5-8B6D-0B22AD6DFC64}.Release|x64.ActiveCfg = Release|x64 + {66231B4E-059F-42B5-8B6D-0B22AD6DFC64}.Release|x64.Build.0 = Release|x64 + {F6B2D0CE-1772-4A76-BB46-FEB7C179370A}.Debug|Win32.ActiveCfg = Debug|Win32 + {F6B2D0CE-1772-4A76-BB46-FEB7C179370A}.Debug|Win32.Build.0 = Debug|Win32 + {F6B2D0CE-1772-4A76-BB46-FEB7C179370A}.Debug|x64.ActiveCfg = Debug|x64 + {F6B2D0CE-1772-4A76-BB46-FEB7C179370A}.Debug|x64.Build.0 = Debug|x64 + {F6B2D0CE-1772-4A76-BB46-FEB7C179370A}.Release|Win32.ActiveCfg = Release|Win32 + {F6B2D0CE-1772-4A76-BB46-FEB7C179370A}.Release|Win32.Build.0 = Release|Win32 + {F6B2D0CE-1772-4A76-BB46-FEB7C179370A}.Release|x64.ActiveCfg = Release|x64 + {F6B2D0CE-1772-4A76-BB46-FEB7C179370A}.Release|x64.Build.0 = Release|x64 + {0AF7A2B2-BB6A-49EF-99BF-886525F51821}.Debug|Win32.ActiveCfg = Debug|Win32 + {0AF7A2B2-BB6A-49EF-99BF-886525F51821}.Debug|Win32.Build.0 = Debug|Win32 + {0AF7A2B2-BB6A-49EF-99BF-886525F51821}.Debug|x64.ActiveCfg = Debug|x64 + {0AF7A2B2-BB6A-49EF-99BF-886525F51821}.Debug|x64.Build.0 = Debug|x64 + {0AF7A2B2-BB6A-49EF-99BF-886525F51821}.Release|Win32.ActiveCfg = Release|Win32 + {0AF7A2B2-BB6A-49EF-99BF-886525F51821}.Release|Win32.Build.0 = Release|Win32 + {0AF7A2B2-BB6A-49EF-99BF-886525F51821}.Release|x64.ActiveCfg = Release|x64 + {0AF7A2B2-BB6A-49EF-99BF-886525F51821}.Release|x64.Build.0 = Release|x64 + {0B434F56-68C4-4627-BE2F-BE20A5E97F2D}.Debug|Win32.ActiveCfg = Debug|Win32 + {0B434F56-68C4-4627-BE2F-BE20A5E97F2D}.Debug|Win32.Build.0 = Debug|Win32 + {0B434F56-68C4-4627-BE2F-BE20A5E97F2D}.Debug|x64.ActiveCfg = Debug|x64 + {0B434F56-68C4-4627-BE2F-BE20A5E97F2D}.Debug|x64.Build.0 = Debug|x64 + {0B434F56-68C4-4627-BE2F-BE20A5E97F2D}.Release|Win32.ActiveCfg = Release|Win32 + {0B434F56-68C4-4627-BE2F-BE20A5E97F2D}.Release|Win32.Build.0 = Release|Win32 + {0B434F56-68C4-4627-BE2F-BE20A5E97F2D}.Release|x64.ActiveCfg = Release|x64 + {0B434F56-68C4-4627-BE2F-BE20A5E97F2D}.Release|x64.Build.0 = Release|x64 + {A5627E7A-6C18-4D04-A7DE-5445F39E1CAB}.Debug|Win32.ActiveCfg = Debug|Win32 + {A5627E7A-6C18-4D04-A7DE-5445F39E1CAB}.Debug|Win32.Build.0 = Debug|Win32 + {A5627E7A-6C18-4D04-A7DE-5445F39E1CAB}.Debug|x64.ActiveCfg = Debug|x64 + {A5627E7A-6C18-4D04-A7DE-5445F39E1CAB}.Debug|x64.Build.0 = Debug|x64 + {A5627E7A-6C18-4D04-A7DE-5445F39E1CAB}.Release|Win32.ActiveCfg = Release|Win32 + {A5627E7A-6C18-4D04-A7DE-5445F39E1CAB}.Release|Win32.Build.0 = Release|Win32 + {A5627E7A-6C18-4D04-A7DE-5445F39E1CAB}.Release|x64.ActiveCfg = Release|x64 + {A5627E7A-6C18-4D04-A7DE-5445F39E1CAB}.Release|x64.Build.0 = Release|x64 + {8C66849E-892F-41DD-AF5D-11DC22FCA013}.Debug|Win32.ActiveCfg = Debug|Win32 + {8C66849E-892F-41DD-AF5D-11DC22FCA013}.Debug|Win32.Build.0 = Debug|Win32 + {8C66849E-892F-41DD-AF5D-11DC22FCA013}.Debug|x64.ActiveCfg = Debug|x64 + {8C66849E-892F-41DD-AF5D-11DC22FCA013}.Debug|x64.Build.0 = Debug|x64 + {8C66849E-892F-41DD-AF5D-11DC22FCA013}.Release|Win32.ActiveCfg = Release|Win32 + {8C66849E-892F-41DD-AF5D-11DC22FCA013}.Release|Win32.Build.0 = Release|Win32 + {8C66849E-892F-41DD-AF5D-11DC22FCA013}.Release|x64.ActiveCfg = Release|x64 + {8C66849E-892F-41DD-AF5D-11DC22FCA013}.Release|x64.Build.0 = Release|x64 + {7B17BE9E-D4A6-4652-BDE8-80FDE0DDC7D4}.Debug|Win32.ActiveCfg = Debug|Win32 + {7B17BE9E-D4A6-4652-BDE8-80FDE0DDC7D4}.Debug|Win32.Build.0 = Debug|Win32 + {7B17BE9E-D4A6-4652-BDE8-80FDE0DDC7D4}.Debug|x64.ActiveCfg = Debug|x64 + {7B17BE9E-D4A6-4652-BDE8-80FDE0DDC7D4}.Debug|x64.Build.0 = Debug|x64 + {7B17BE9E-D4A6-4652-BDE8-80FDE0DDC7D4}.Release|Win32.ActiveCfg = Release|Win32 + {7B17BE9E-D4A6-4652-BDE8-80FDE0DDC7D4}.Release|Win32.Build.0 = Release|Win32 + {7B17BE9E-D4A6-4652-BDE8-80FDE0DDC7D4}.Release|x64.ActiveCfg = Release|x64 + {7B17BE9E-D4A6-4652-BDE8-80FDE0DDC7D4}.Release|x64.Build.0 = Release|x64 + {BB5B3C11-F77A-4C46-AE5A-76153DD0CA79}.Debug|Win32.ActiveCfg = Debug|Win32 + {BB5B3C11-F77A-4C46-AE5A-76153DD0CA79}.Debug|Win32.Build.0 = Debug|Win32 + {BB5B3C11-F77A-4C46-AE5A-76153DD0CA79}.Debug|x64.ActiveCfg = Debug|x64 + {BB5B3C11-F77A-4C46-AE5A-76153DD0CA79}.Debug|x64.Build.0 = Debug|x64 + {BB5B3C11-F77A-4C46-AE5A-76153DD0CA79}.Release|Win32.ActiveCfg = Release|Win32 + {BB5B3C11-F77A-4C46-AE5A-76153DD0CA79}.Release|Win32.Build.0 = Release|Win32 + {BB5B3C11-F77A-4C46-AE5A-76153DD0CA79}.Release|x64.ActiveCfg = Release|x64 + {BB5B3C11-F77A-4C46-AE5A-76153DD0CA79}.Release|x64.Build.0 = Release|x64 + {FED853B7-B02A-49FC-9FA9-DFCF8479841A}.Debug|Win32.ActiveCfg = Debug|Win32 + {FED853B7-B02A-49FC-9FA9-DFCF8479841A}.Debug|Win32.Build.0 = Debug|Win32 + {FED853B7-B02A-49FC-9FA9-DFCF8479841A}.Debug|x64.ActiveCfg = Debug|x64 + {FED853B7-B02A-49FC-9FA9-DFCF8479841A}.Debug|x64.Build.0 = Debug|x64 + {FED853B7-B02A-49FC-9FA9-DFCF8479841A}.Release|Win32.ActiveCfg = Release|Win32 + {FED853B7-B02A-49FC-9FA9-DFCF8479841A}.Release|Win32.Build.0 = Release|Win32 + {FED853B7-B02A-49FC-9FA9-DFCF8479841A}.Release|x64.ActiveCfg = Release|x64 + {FED853B7-B02A-49FC-9FA9-DFCF8479841A}.Release|x64.Build.0 = Release|x64 + {155D1AED-B54E-4C90-8152-246E0C01EC84}.Debug|Win32.ActiveCfg = Debug|Win32 + {155D1AED-B54E-4C90-8152-246E0C01EC84}.Debug|Win32.Build.0 = Debug|Win32 + {155D1AED-B54E-4C90-8152-246E0C01EC84}.Debug|x64.ActiveCfg = Debug|x64 + {155D1AED-B54E-4C90-8152-246E0C01EC84}.Debug|x64.Build.0 = Debug|x64 + {155D1AED-B54E-4C90-8152-246E0C01EC84}.Release|Win32.ActiveCfg = Release|Win32 + {155D1AED-B54E-4C90-8152-246E0C01EC84}.Release|Win32.Build.0 = Release|Win32 + {155D1AED-B54E-4C90-8152-246E0C01EC84}.Release|x64.ActiveCfg = Release|x64 + {155D1AED-B54E-4C90-8152-246E0C01EC84}.Release|x64.Build.0 = Release|x64 + {9F42E7FC-954C-4473-A9FC-F354CEC77393}.Debug|Win32.ActiveCfg = Debug|Win32 + {9F42E7FC-954C-4473-A9FC-F354CEC77393}.Debug|x64.ActiveCfg = Debug|x64 + {9F42E7FC-954C-4473-A9FC-F354CEC77393}.Debug|x64.Build.0 = Debug|x64 + {9F42E7FC-954C-4473-A9FC-F354CEC77393}.Release|Win32.ActiveCfg = Release|Win32 + {9F42E7FC-954C-4473-A9FC-F354CEC77393}.Release|x64.ActiveCfg = Release|x64 + {9F42E7FC-954C-4473-A9FC-F354CEC77393}.Release|x64.Build.0 = Release|x64 + {64D4ABD4-4C7D-47AC-A7E2-BCB6D1F1CF81}.Debug|Win32.ActiveCfg = Debug|Win32 + {64D4ABD4-4C7D-47AC-A7E2-BCB6D1F1CF81}.Debug|Win32.Build.0 = Debug|Win32 + {64D4ABD4-4C7D-47AC-A7E2-BCB6D1F1CF81}.Debug|x64.ActiveCfg = Debug|x64 + {64D4ABD4-4C7D-47AC-A7E2-BCB6D1F1CF81}.Debug|x64.Build.0 = Debug|x64 + {64D4ABD4-4C7D-47AC-A7E2-BCB6D1F1CF81}.Release|Win32.ActiveCfg = Release|Win32 + {64D4ABD4-4C7D-47AC-A7E2-BCB6D1F1CF81}.Release|Win32.Build.0 = Release|Win32 + {64D4ABD4-4C7D-47AC-A7E2-BCB6D1F1CF81}.Release|x64.ActiveCfg = Release|x64 + {64D4ABD4-4C7D-47AC-A7E2-BCB6D1F1CF81}.Release|x64.Build.0 = Release|x64 + {4E267C5E-6A43-4E20-A2B9-8C9526F97215}.Debug|Win32.ActiveCfg = Debug|Win32 + {4E267C5E-6A43-4E20-A2B9-8C9526F97215}.Debug|Win32.Build.0 = Debug|Win32 + {4E267C5E-6A43-4E20-A2B9-8C9526F97215}.Debug|x64.ActiveCfg = Debug|x64 + {4E267C5E-6A43-4E20-A2B9-8C9526F97215}.Debug|x64.Build.0 = Debug|x64 + {4E267C5E-6A43-4E20-A2B9-8C9526F97215}.Release|Win32.ActiveCfg = Release|Win32 + {4E267C5E-6A43-4E20-A2B9-8C9526F97215}.Release|Win32.Build.0 = Release|Win32 + {4E267C5E-6A43-4E20-A2B9-8C9526F97215}.Release|x64.ActiveCfg = Release|x64 + {4E267C5E-6A43-4E20-A2B9-8C9526F97215}.Release|x64.Build.0 = Release|x64 + {36F79680-796A-465E-9C87-0E76034AF16B}.Debug|Win32.ActiveCfg = Debug|Win32 + {36F79680-796A-465E-9C87-0E76034AF16B}.Debug|Win32.Build.0 = Debug|Win32 + {36F79680-796A-465E-9C87-0E76034AF16B}.Debug|x64.ActiveCfg = Debug|x64 + {36F79680-796A-465E-9C87-0E76034AF16B}.Debug|x64.Build.0 = Debug|x64 + {36F79680-796A-465E-9C87-0E76034AF16B}.Release|Win32.ActiveCfg = Release|Win32 + {36F79680-796A-465E-9C87-0E76034AF16B}.Release|Win32.Build.0 = Release|Win32 + {36F79680-796A-465E-9C87-0E76034AF16B}.Release|x64.ActiveCfg = Release|x64 + {36F79680-796A-465E-9C87-0E76034AF16B}.Release|x64.Build.0 = Release|x64 + {FA376FCE-E31C-4601-B4A7-3B976911E777}.Debug|Win32.ActiveCfg = Debug|Win32 + {FA376FCE-E31C-4601-B4A7-3B976911E777}.Debug|Win32.Build.0 = Debug|Win32 + {FA376FCE-E31C-4601-B4A7-3B976911E777}.Debug|x64.ActiveCfg = Debug|x64 + {FA376FCE-E31C-4601-B4A7-3B976911E777}.Debug|x64.Build.0 = Debug|x64 + {FA376FCE-E31C-4601-B4A7-3B976911E777}.Release|Win32.ActiveCfg = Release|Win32 + {FA376FCE-E31C-4601-B4A7-3B976911E777}.Release|Win32.Build.0 = Release|Win32 + {FA376FCE-E31C-4601-B4A7-3B976911E777}.Release|x64.ActiveCfg = Release|x64 + {FA376FCE-E31C-4601-B4A7-3B976911E777}.Release|x64.Build.0 = Release|x64 + {4168C61E-16EF-4196-9E3D-D21F18234CAF}.Debug|Win32.ActiveCfg = Debug|Win32 + {4168C61E-16EF-4196-9E3D-D21F18234CAF}.Debug|Win32.Build.0 = Debug|Win32 + {4168C61E-16EF-4196-9E3D-D21F18234CAF}.Debug|x64.ActiveCfg = Debug|x64 + {4168C61E-16EF-4196-9E3D-D21F18234CAF}.Debug|x64.Build.0 = Debug|x64 + {4168C61E-16EF-4196-9E3D-D21F18234CAF}.Release|Win32.ActiveCfg = Release|Win32 + {4168C61E-16EF-4196-9E3D-D21F18234CAF}.Release|Win32.Build.0 = Release|Win32 + {4168C61E-16EF-4196-9E3D-D21F18234CAF}.Release|x64.ActiveCfg = Release|x64 + {4168C61E-16EF-4196-9E3D-D21F18234CAF}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {BCB55952-3128-454B-B060-C53A3C1CCA14} = {086A9AB4-23AC-41C8-A422-A7CF714413CF} + {FEC92998-8D28-42CE-886D-21D17A263D24} = {086A9AB4-23AC-41C8-A422-A7CF714413CF} + {F7DCFF24-19CD-4FE6-BDDF-6029670E77D6} = {55923E6A-021C-40AF-9977-C9E3072B697B} + {1AEF4F9B-7227-4B51-9ADE-CDED9427C0B5} = {55923E6A-021C-40AF-9977-C9E3072B697B} + {7656FF69-D1A3-4FA1-AB04-7C0089777CA7} = {55923E6A-021C-40AF-9977-C9E3072B697B} + {9875FF3B-A8F4-4221-B27A-0D092F5CF816} = {55923E6A-021C-40AF-9977-C9E3072B697B} + {0C454599-73FB-4F57-B8C9-0BE68AF3110E} = {55923E6A-021C-40AF-9977-C9E3072B697B} + {F435A5D6-D589-41FA-8430-90C37401DE17} = {55923E6A-021C-40AF-9977-C9E3072B697B} + {66231B4E-059F-42B5-8B6D-0B22AD6DFC64} = {55923E6A-021C-40AF-9977-C9E3072B697B} + {F6B2D0CE-1772-4A76-BB46-FEB7C179370A} = {55923E6A-021C-40AF-9977-C9E3072B697B} + {0B434F56-68C4-4627-BE2F-BE20A5E97F2D} = {55923E6A-021C-40AF-9977-C9E3072B697B} + {FED853B7-B02A-49FC-9FA9-DFCF8479841A} = {55923E6A-021C-40AF-9977-C9E3072B697B} + {155D1AED-B54E-4C90-8152-246E0C01EC84} = {55923E6A-021C-40AF-9977-C9E3072B697B} + {9F42E7FC-954C-4473-A9FC-F354CEC77393} = {55923E6A-021C-40AF-9977-C9E3072B697B} + {8EEB6A31-BBE4-450C-AEF6-E4F81F63EF46} = {BCB55952-3128-454B-B060-C53A3C1CCA14} + {0AF7A2B2-BB6A-49EF-99BF-886525F51821} = {C38F02E0-99EB-4B94-8134-5F777118B1A8} + {A5627E7A-6C18-4D04-A7DE-5445F39E1CAB} = {C38F02E0-99EB-4B94-8134-5F777118B1A8} + {8C66849E-892F-41DD-AF5D-11DC22FCA013} = {C38F02E0-99EB-4B94-8134-5F777118B1A8} + {7B17BE9E-D4A6-4652-BDE8-80FDE0DDC7D4} = {C38F02E0-99EB-4B94-8134-5F777118B1A8} + {BB5B3C11-F77A-4C46-AE5A-76153DD0CA79} = {C38F02E0-99EB-4B94-8134-5F777118B1A8} + {64D4ABD4-4C7D-47AC-A7E2-BCB6D1F1CF81} = {C38F02E0-99EB-4B94-8134-5F777118B1A8} + {4E267C5E-6A43-4E20-A2B9-8C9526F97215} = {C38F02E0-99EB-4B94-8134-5F777118B1A8} + {36F79680-796A-465E-9C87-0E76034AF16B} = {C38F02E0-99EB-4B94-8134-5F777118B1A8} + {FA376FCE-E31C-4601-B4A7-3B976911E777} = {C38F02E0-99EB-4B94-8134-5F777118B1A8} + {4168C61E-16EF-4196-9E3D-D21F18234CAF} = {C38F02E0-99EB-4B94-8134-5F777118B1A8} + EndGlobalSection +EndGlobal diff --git a/VxKex.suo b/VxKex.suo new file mode 100644 index 0000000..1c2ea05 Binary files /dev/null and b/VxKex.suo differ diff --git a/VxKexLdr.opensdf b/VxKexLdr.opensdf new file mode 100644 index 0000000..c3f3517 Binary files /dev/null and b/VxKexLdr.opensdf differ diff --git a/VxKexLdr/VxKexLdr.rc b/VxKexLdr/VxKexLdr.rc new file mode 100644 index 0000000..0d88755 Binary files /dev/null and b/VxKexLdr/VxKexLdr.rc differ diff --git a/VxKexLdr/VxKexLdr.vcxproj b/VxKexLdr/VxKexLdr.vcxproj new file mode 100644 index 0000000..852244d --- /dev/null +++ b/VxKexLdr/VxKexLdr.vcxproj @@ -0,0 +1,241 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {155D1AED-B54E-4C90-8152-246E0C01EC84} + Win32Proj + VxKexLdr + + + + Application + true + Unicode + + + Application + true + Unicode + + + Application + false + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + + + + + + + false + + + false + + + false + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + false + Default + false + StdCall + CompileAsC + false + + + Windows + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + true + ole32.dll;comdlg32.dll;user32.dll;shell32.dll;comctl32.dll;gdi32.dll + + + $(SolutionDir)\00-Common Headers + + + true + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + false + Default + false + StdCall + CompileAsC + false + + + Windows + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + true + ole32.dll;comdlg32.dll;user32.dll;shell32.dll;comctl32.dll;gdi32.dll + + + $(SolutionDir)\00-Common Headers + + + true + + + + + Level3 + + + MinSpace + true + true + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + false + Default + false + StdCall + CompileAsC + Size + true + false + + + Windows + true + true + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + true + ole32.dll;comdlg32.dll;user32.dll;shell32.dll;comctl32.dll;gdi32.dll + + + $(SolutionDir)\00-Common Headers + + + true + + + + + Level3 + + + MinSpace + true + true + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + ProgramDatabase + true + true + false + Default + false + StdCall + CompileAsC + Size + true + false + + + Windows + true + true + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + true + ole32.dll;comdlg32.dll;user32.dll;shell32.dll;comctl32.dll;gdi32.dll + + + $(SolutionDir)\00-Common Headers + + + true + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VxKexLdr/VxKexLdr.vcxproj.filters b/VxKexLdr/VxKexLdr.vcxproj.filters new file mode 100644 index 0000000..68d2eab --- /dev/null +++ b/VxKexLdr/VxKexLdr.vcxproj.filters @@ -0,0 +1,44 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + + + Resource Files + + + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/VxKexLdr/buildcfg.h b/VxKexLdr/buildcfg.h new file mode 100644 index 0000000..29ecb93 --- /dev/null +++ b/VxKexLdr/buildcfg.h @@ -0,0 +1,6 @@ +#pragma once + +#define FRIENDLYAPPNAME L"VxKex Loader" +#define KEX_TARGET_TYPE_EXE +#define KEX_ENV_WIN32 +#define KEX_COMPONENT L"VxKexLdr" diff --git a/VxKexLdr/creaproc.c b/VxKexLdr/creaproc.c new file mode 100644 index 0000000..458329b --- /dev/null +++ b/VxKexLdr/creaproc.c @@ -0,0 +1,260 @@ +#include "buildcfg.h" +#include "vxkexldr.h" + +BOOLEAN VklCreateProcess( + IN PCWSTR Path, + IN PCWSTR Arguments OPTIONAL) +{ + BOOLEAN Success; + HINSTANCE ShellExecuteError; + + ASSERT (Path != NULL); + + if (Arguments != NULL && Arguments[0] == '\0') { + Arguments = NULL; + } + + if (!PathIsRelative(Path) && StringEqualI(PathFindExtension(Path), L".exe")) { + NTSTATUS Status; + ULONG ErrorCode; + ULONG ProcessCreationFlags; + STARTUPINFOEX StartupInfo; + PROCESS_INFORMATION ProcessInformation; + SIZE_T ProcThreadAttributeListCb; + PROCESS_BASIC_INFORMATION BasicInformation; + OBJECT_ATTRIBUTES ObjectAttributes; + CLIENT_ID ParentProcessClientId; + HANDLE ParentProcessHandle; + PWSTR ArgumentsWithExeName; + + // + // We are opening an EXE. Use CreateProcess to do this. + // + + ParentProcessHandle = NULL; + ProcessCreationFlags = 0; + + // + // Deal with the StartupInfo and proc/thread attribute stuff. + // First of all we need to get a handle to our parent process (which is + // very likely to be Explorer). + // + + Status = NtQueryInformationProcess( + NtCurrentProcess(), + ProcessBasicInformation, + &BasicInformation, + sizeof(BasicInformation), + NULL); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + goto NoExtendedStartupInfo; + } + + ParentProcessClientId.UniqueProcess = (HANDLE) BasicInformation.InheritedFromUniqueProcessId; + ParentProcessClientId.UniqueThread = NULL; + + InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL); + + Status = NtOpenProcess( + &ParentProcessHandle, + PROCESS_CREATE_PROCESS, + &ObjectAttributes, + &ParentProcessClientId); + + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + // + // The NtOpenProcess call can fail if the parent process has exited. + // + + goto NoExtendedStartupInfo; + } + + // + // Now we need to find the size, allocate, and initialize a buffer for + // the process/thread attribute list. + // + // Note: We don't bother calling DeleteProcThreadAttributeList. That + // function does absolutely nothing on Windows 7. + // + // Note: InitializeProcThreadAttributeList and UpdateProcThreadAttribute + // cannot fail unless passed invalid parameters. That is why we don't bother + // checking their return values. + // + // The magic number 48 is the number of bytes required for one proc/thread + // attribute. The formula for calculating the number of bytes required + // for any particular number of proc/thread attributes is: + // + // (n + 1) * 24 + // + + ProcThreadAttributeListCb = 48; + + StartupInfo.lpAttributeList = + (PPROC_THREAD_ATTRIBUTE_LIST) StackAlloc(BYTE, ProcThreadAttributeListCb); + + InitializeProcThreadAttributeList( + StartupInfo.lpAttributeList, + 1, + 0, + &ProcThreadAttributeListCb); + + UpdateProcThreadAttribute( + StartupInfo.lpAttributeList, + 0, + PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, + &ParentProcessHandle, + sizeof(ParentProcessHandle), + NULL, + NULL); + + ProcessCreationFlags |= EXTENDED_STARTUPINFO_PRESENT; + +NoExtendedStartupInfo: + + GetStartupInfo(&StartupInfo.StartupInfo); + StartupInfo.StartupInfo.wShowWindow = SW_SHOW; + + if (ProcessCreationFlags & EXTENDED_STARTUPINFO_PRESENT) { + StartupInfo.StartupInfo.cb = sizeof(StartupInfo); + } + + // + // If we have a command line specified, we need to prepend the executable + // name to it (quoted). + // + + if (Arguments) { + HRESULT Result; + SIZE_T Cch; + + Cch = 1 + // open quote + wcslen(Path) + + 1 + // close quote + 1 + // space + wcslen(Arguments) + + 1; // null terminator + + ArgumentsWithExeName = StackAlloc(WCHAR, Cch); + + Result = StringCchPrintf( + ArgumentsWithExeName, + Cch, + L"\"%s\" %s", + Path, + Arguments); + + ASSERT (SUCCEEDED(Result)); + } else { + ArgumentsWithExeName = NULL; + } + + // + // Actually create our child process. + // + + Success = CreateProcess( + Path, + ArgumentsWithExeName, + NULL, + NULL, + FALSE, + ProcessCreationFlags, + NULL, + NULL, + &StartupInfo.StartupInfo, + &ProcessInformation); + + ErrorCode = GetLastError(); + SafeClose(ParentProcessHandle); + + if (Success) { + SafeClose(ProcessInformation.hProcess); + SafeClose(ProcessInformation.hThread); + return TRUE; + } else { + if (ErrorCode == ERROR_INVALID_PARAMETER) { + // Misleading error code. Change it so the user can get + // a better error message. + ErrorCode = ERROR_FILE_NOT_FOUND; + } + + if (ErrorCode == ERROR_ELEVATION_REQUIRED) { + // Fall through to the ShellExecute code. + NOTHING; + } else { + ErrorBoxF(L"CreateProcess failed: %s", Win32ErrorAsString(ErrorCode)); + return FALSE; + } + } + } + + // + // We are either opening a non-EXE file (such as a MSI), or we are opening + // an EXE file that requires UAC elevation, or the user did not specify + // a full path to an EXE file (including extension). In this case we will + // fall back to ShellExecute, which is slower and less flexible but will + // deal with any conditions you can think of. + // + + ShellExecuteError = ShellExecute( + KexgApplicationMainWindow, + L"open", + Path, + Arguments, + NULL, + SW_SHOW); + + if ((ULONG) ShellExecuteError <= 32) { + PCWSTR ErrorMessage; + + switch ((ULONG) ShellExecuteError) { + case 0: + case SE_ERR_OOM: + ErrorMessage = L"Insufficient resources."; + break; + case ERROR_FILE_NOT_FOUND: + case ERROR_PATH_NOT_FOUND: + case ERROR_BAD_FORMAT: + ErrorMessage = Win32ErrorAsString((ULONG) ShellExecuteError); + break; + case SE_ERR_ACCESSDENIED: + ErrorMessage = L"Access was denied."; + break; + case SE_ERR_DLLNOTFOUND: + ErrorMessage = L"A DLL was not found."; + break; + case SE_ERR_SHARE: + ErrorMessage = L"A sharing violation occurred."; + break; + case SE_ERR_ASSOCINCOMPLETE: + ErrorMessage = L"SE_ERR_ASSOCINCOMPLETE."; + break; + case SE_ERR_DDEBUSY: + ErrorMessage = L"SE_ERR_DDEBUSY."; + break; + case SE_ERR_DDEFAIL: + ErrorMessage = L"SE_ERR_DDEFAIL."; + break; + case SE_ERR_DDETIMEOUT: + ErrorMessage = L"SE_ERR_DDETIMEOUT."; + break; + case SE_ERR_NOASSOC: + ErrorMessage = L"SE_ERR_NOASSOC."; + break; + default: + ASSERT (FALSE); + ErrorMessage = L"Unknown error."; + break; + } + + ErrorBoxF(L"ShellExecute failed: %s", ErrorMessage); + return FALSE; + } + + return TRUE; +} \ No newline at end of file diff --git a/VxKexLdr/gui.c b/VxKexLdr/gui.c new file mode 100644 index 0000000..978c360 --- /dev/null +++ b/VxKexLdr/gui.c @@ -0,0 +1,230 @@ +#include "buildcfg.h" +#include "vxkexldr.h" + +STATIC PKEX_PROCESS_DATA KexData = NULL; + +STATIC INT_PTR CALLBACK MoreOptionsDlgProc( + IN HWND Window, + IN UINT Message, + IN WPARAM WParam, + IN LPARAM LParam) +{ + ASSERT (KexData != NULL); + + if (Message == WM_INITDIALOG) { + HWND ComboBoxWindow; + + ComboBoxWindow = GetDlgItem(Window, IDC_WINVER); + ComboBox_AddString(ComboBoxWindow, L"Windows 7 Service Pack 1"); + ComboBox_AddString(ComboBoxWindow, L"Windows 8"); + ComboBox_AddString(ComboBoxWindow, L"Windows 8.1"); + ComboBox_AddString(ComboBoxWindow, L"Windows 10"); + ComboBox_AddString(ComboBoxWindow, L"Windows 11"); + ComboBox_SetCurSel(ComboBoxWindow, 3); + } else if (Message == WM_COMMAND) { + HWND ControlWindow; + ULONG ControlId; + ULONG NotificationCode; + + ControlWindow = (HWND) LParam; + ControlId = LOWORD(WParam); + NotificationCode = HIWORD(WParam); + + if (ControlId == IDC_ENABLESPOOF) { + if (Button_GetCheck(ControlWindow) == BST_CHECKED) { + EnableWindow(GetDlgItem(Window, IDC_WINVER), TRUE); + EnableWindow(GetDlgItem(Window, IDC_STRONGSPOOF), TRUE); + + KexData->IfeoParameters.WinVerSpoof = + (KEX_WIN_VER_SPOOF) (ComboBox_GetCurSel(GetDlgItem(Window, IDC_WINVER)) + 1); + } else { + EnableWindow(GetDlgItem(Window, IDC_WINVER), FALSE); + EnableWindow(GetDlgItem(Window, IDC_STRONGSPOOF), FALSE); + + KexData->IfeoParameters.WinVerSpoof = WinVerSpoofNone; + } + } else if (ControlId == IDC_WINVER && NotificationCode == CBN_SELCHANGE) { + KexData->IfeoParameters.WinVerSpoof = + (KEX_WIN_VER_SPOOF) (ComboBox_GetCurSel(GetDlgItem(Window, IDC_WINVER)) + 1); + } else if (ControlId == IDC_STRONGSPOOF) { + KexData->IfeoParameters.StrongVersionSpoof = + !!Button_GetCheck(ControlWindow) ? KEX_STRONGSPOOF_VALID_MASK : 0; + } else if (ControlId == IDC_DISABLEFORCHILD) { + KexData->IfeoParameters.DisableAppSpecific = !!Button_GetCheck(ControlWindow); + } else if (ControlId == IDC_DISABLEASH) { + KexData->IfeoParameters.DisableAppSpecific = !!Button_GetCheck(ControlWindow); + } else { + return FALSE; + } + } else { + return FALSE; + } + + return TRUE; +} + +INT_PTR CALLBACK VklDialogProc( + IN HWND Window, + IN UINT Message, + IN WPARAM WParam, + IN LPARAM LParam) +{ + if (Message == WM_INITDIALOG) { + KexgApplicationMainWindow = Window; + SetWindowIcon(Window, IDI_APPICON); + + KexDataInitialize(&KexData); + + // + // Allow files to be dragged and dropped onto the main window when + // running as admin. + // + + ChangeWindowMessageFilterEx(Window, WM_DROPFILES, MSGFLT_ALLOW, NULL); + ChangeWindowMessageFilterEx(Window, WM_COPYDATA, MSGFLT_ALLOW, NULL); + ChangeWindowMessageFilterEx(Window, WM_COPYGLOBALDATA, MSGFLT_ALLOW, NULL); + + // + // Enable shell autocompletion on edit controls. + // For the arguments edit control we are only enabling autocompletion to take + // advantage of the Ctrl+Backspace feature, so autosuggestions are disabled. + // + + SHAutoComplete(GetDlgItem(Window, IDC_FILEPATH), SHACF_FILESYS_ONLY | SHACF_USETAB); + SHAutoComplete(GetDlgItem(Window, IDC_ARGUMENTS), SHACF_AUTOSUGGEST_FORCE_OFF | SHACF_AUTOAPPEND_FORCE_OFF); + + // + // Limit the maximum length of text that can be typed into edit controls. + // + + Edit_LimitText(GetDlgItem(Window, IDC_FILEPATH), MAX_PATH - 1); + Edit_LimitText(GetDlgItem(Window, IDC_ARGUMENTS), 32767 - MAX_PATH); + + // + // Create the extra options child dialog. This is beyond the window boundaries + // and is invisible until the user clicks the More options button. + // + + CreateDialog(NULL, MAKEINTRESOURCE(IDD_MOREOPTIONS), Window, MoreOptionsDlgProc); + } else if (Message == WM_COMMAND) { + HWND ControlWindow; + ULONG ControlId; + ULONG NotificationCode; + + ControlWindow = (HWND) LParam; + ControlId = LOWORD(WParam); + NotificationCode = HIWORD(WParam); + + if (ControlId == IDCANCEL) { + EndDialog(Window, 0); + } else if (ControlId == IDOK) { + WCHAR FilePath[MAX_PATH]; + WCHAR Arguments[MAX_PATH]; + BOOLEAN Success; + + GetDlgItemText(Window, IDC_FILEPATH, FilePath, ARRAYSIZE(FilePath)); + GetDlgItemText(Window, IDC_ARGUMENTS, Arguments, ARRAYSIZE(Arguments)); + + Success = VklCreateProcess(FilePath, Arguments); + + if (Success) { + EndDialog(Window, 0); + } + } else if (ControlId == IDC_BROWSE) { + OPENFILENAME OpenFileInfo; + WCHAR FilePath[MAX_PATH]; + + GetDlgItemText(Window, IDC_FILEPATH, FilePath, ARRAYSIZE(FilePath)); + + RtlZeroMemory(&OpenFileInfo, sizeof(OpenFileInfo)); + OpenFileInfo.lStructSize = sizeof(OpenFileInfo); + OpenFileInfo.hwndOwner = Window; + OpenFileInfo.lpstrFilter = L"Programs (*.exe, *.msi)\0*.exe;*.msi\0All Files (*.*)\0*.*\0"; + OpenFileInfo.lpstrFile = FilePath; + OpenFileInfo.nMaxFile = ARRAYSIZE(FilePath); + OpenFileInfo.lpstrTitle = L"Select Program"; + OpenFileInfo.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; + OpenFileInfo.lpstrDefExt = L"exe"; + + if (GetOpenFileName(&OpenFileInfo) == FALSE) { + ASSERT (CommDlgExtendedError() == 0); + } else { + ASSERT (FilePath[0] != '\0'); + SetDlgItemText(Window, IDC_FILEPATH, FilePath); + } + } else if (ControlId == IDC_FILEPATH && NotificationCode == EN_CHANGE) { + // enable/disable Run button based on whether there is text in the + // edit control + EnableWindow( + GetDlgItem(Window, IDOK), + (GetWindowTextLength(ControlWindow) != 0)); + } else if (ControlId == IDC_MOREOPTIONS) { + STATIC BOOL MoreOptionsDisplayed = FALSE; + STATIC ULONG CollapsedWindowHeight = 0; + STATIC ULONG ExpandedWindowHeight; + STATIC ULONG WindowWidth; + + if (CollapsedWindowHeight == 0) { + RECT WindowRect; + + GetWindowRect(Window, &WindowRect); + WindowWidth = WindowRect.right - WindowRect.left; + CollapsedWindowHeight = WindowRect.bottom - WindowRect.top; + ExpandedWindowHeight = CollapsedWindowHeight + DpiScaleY(95); + } + + // + // More Options button was clicked. + // + + if (MoreOptionsDisplayed) { + // + // The extra options are currently displayed and we need to + // hide them. + // + + SetWindowPos( + Window, + NULL, + 0, 0, + WindowWidth, CollapsedWindowHeight, + SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOREDRAW | + SWP_NOSENDCHANGING | SWP_NOZORDER); + + SetDlgItemText(Window, IDC_MOREOPTIONS, L"▼ More &options"); + } else { + // + // The extra options are currently not displayed and we need + // to display them. + // + + SetWindowPos( + Window, + NULL, + 0, 0, + WindowWidth, ExpandedWindowHeight, + SWP_NOACTIVATE | SWP_NOMOVE | + SWP_NOSENDCHANGING | SWP_NOZORDER); + + SetDlgItemText(Window, IDC_MOREOPTIONS, L"▲ Hide &options"); + } + + MoreOptionsDisplayed = !MoreOptionsDisplayed; + } else { + return FALSE; + } + } else if (Message == WM_DROPFILES) { + HDROP DroppedItem; + WCHAR DroppedFilePath[MAX_PATH]; + + DroppedItem = (HDROP) WParam; + + DragQueryFile(DroppedItem, 0, DroppedFilePath, ARRAYSIZE(DroppedFilePath)); + SetDlgItemText(Window, IDC_FILEPATH, DroppedFilePath); + DragFinish(DroppedItem); + } else { + return FALSE; + } + + return TRUE; +} \ No newline at end of file diff --git a/VxKexLdr/main.c b/VxKexLdr/main.c new file mode 100644 index 0000000..6660591 --- /dev/null +++ b/VxKexLdr/main.c @@ -0,0 +1,146 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Module Name: +// +// main.c +// +// Abstract: +// +// For the rewrite we're bringing back this classic VxKex component that +// used to be the core of VxKex. But this time, it's serving a purpose which +// is very different, yet very similar. +// +// This loader application is invoked mainly by Windows Explorer when the +// user clicks on VxKex options in either the normal context menu or the +// extended context menu. But there is a GUI as well, for if users disable +// VxKex integration into the context menus. +// +// Author: +// +// vxiiduu (29-Feb-2024) +// +// Environment: +// +// Win32 +// +// Revision History: +// +// vxiiduu 29-Feb-2024 Initial creation. +// vxiiduu 19-Mar-2024 Patch CPIW version check as well. +// +/////////////////////////////////////////////////////////////////////////////// + +#include "buildcfg.h" +#include "vxkexldr.h" + +VOID EntryPoint( + VOID) +{ + NTSTATUS Status; + PWSTR CommandLine; + + KexgApplicationFriendlyName = FRIENDLYAPPNAME; + + // + // Initialize the propagation system. This can be done independently from the + // rest of KexDll initialization. The propagation system is what lets us run + // specific programs under VxKex even if they weren't configured in IFEO. + // + + Status = KexInitializePropagation(); + ASSERT (NT_SUCCESS(Status)); + + if (!NT_SUCCESS(Status)) { + CriticalErrorBoxF( + L"Propagation could not be initialized.\r\n" + L"NTSTATUS error code: %s", + KexRtlNtStatusToString(Status)); + + NOT_REACHED; + } + + // + // Patch the CreateProcessInternalW subsystem version check. + // Failure here is non-critical. + // + + Status = KexPatchCpiwSubsystemVersionCheck(); + ASSERT (NT_SUCCESS(Status)); + + // + // Parse command line. + // + + CommandLine = GetCommandLineWithoutImageName(); + + if (CommandLine[0] != '\0') { + BOOLEAN IsQuotedPath; + PCWSTR FilePath; + PCWSTR Arguments; + + // + // Extract the file path. + // + + FilePath = NULL; + Arguments = NULL; + + if (*CommandLine == '"') { + IsQuotedPath = TRUE; + + // Quoted path. Next closing quote or end of string marks + // end of file name or path. + ++CommandLine; + FilePath = CommandLine; + + until (*CommandLine == '"' || *CommandLine == '\0') { + ++CommandLine; + } + } else { + IsQuotedPath = FALSE; + FilePath = CommandLine; + + // Non quoted path. First space or end of string marks end of + // file name or path. + until (*CommandLine == ' ' || *CommandLine == '\0') { + ++CommandLine; + } + } + + if (IsQuotedPath) { + if (*CommandLine != '"') { + // Expected matching quote, but reached end of string. + // Malformed command line without an end quote. + CriticalErrorBoxF(L"Malformed command line. A closing quote must be supplied."); + NOT_REACHED; + } + } + + if (*CommandLine != '\0') { + // Quoted path, or non quoted path that may have arguments. + // Separate the path from the arguments by adding a terminator. + *CommandLine = '\0'; + + // Go past whitespace. + do { + ++CommandLine; + } until (*CommandLine != ' '); + } + + if (*CommandLine != '\0') { + // There are arguments. + Arguments = CommandLine; + } + + VklCreateProcess(FilePath, Arguments); + } else { + // + // No command line parameters. Launch the GUI. + // + + CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); + DialogBox(NULL, MAKEINTRESOURCE(IDD_MAINWINDOW), NULL, VklDialogProc); + } + + ExitProcess(0); +} \ No newline at end of file diff --git a/VxKexLdr/resource.h b/VxKexLdr/resource.h new file mode 100644 index 0000000..7ea7919 --- /dev/null +++ b/VxKexLdr/resource.h @@ -0,0 +1,18 @@ +#pragma once + +#define IDSTATIC -1 + +#define IDI_APPICON 501 + +#define IDD_MAINWINDOW 100 +#define IDC_FILEPATH 101 +#define IDC_BROWSE 102 +#define IDC_ARGUMENTS 103 +#define IDC_MOREOPTIONS 104 + +#define IDD_MOREOPTIONS 200 +#define IDC_ENABLESPOOF 201 +#define IDC_WINVER 202 +#define IDC_STRONGSPOOF 203 +#define IDC_DISABLEASH 204 +#define IDC_DISABLEFORCHILD 205 diff --git a/VxKexLdr/vxkexldr.h b/VxKexLdr/vxkexldr.h new file mode 100644 index 0000000..0237cd3 --- /dev/null +++ b/VxKexLdr/vxkexldr.h @@ -0,0 +1,14 @@ +#pragma once + +#include +#include "resource.h" + +BOOLEAN VklCreateProcess( + IN PCWSTR Path, + IN PCWSTR Arguments OPTIONAL); + +INT_PTR CALLBACK VklDialogProc( + IN HWND Window, + IN UINT Message, + IN WPARAM WParam, + IN LPARAM LParam); \ No newline at end of file diff --git a/VxKexLdr/vxkexldr.ico b/VxKexLdr/vxkexldr.ico new file mode 100644 index 0000000..3effc4f Binary files /dev/null and b/VxKexLdr/vxkexldr.ico differ diff --git a/VxlView/VxlView.rc b/VxlView/VxlView.rc new file mode 100644 index 0000000..0f9400b Binary files /dev/null and b/VxlView/VxlView.rc differ diff --git a/VxlView/VxlView.vcxproj b/VxlView/VxlView.vcxproj new file mode 100644 index 0000000..2b8af80 --- /dev/null +++ b/VxlView/VxlView.vcxproj @@ -0,0 +1,262 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {9875FF3B-A8F4-4221-B27A-0D092F5CF816} + Win32Proj + VxlView + + + + Application + true + Unicode + + + Application + true + Unicode + + + Application + false + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + + + + + + + false + + + false + + + false + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + true + false + true + false + false + Default + ProgramDatabase + + + Windows + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + false + true + comdlg32.dll + + + + + $(SolutionDir)\00-Common Headers + _DEBUG;_UNICODE;UNICODE;%(PreprocessorDefinitions) + + + true + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + true + false + true + false + false + Default + ProgramDatabase + + + Windows + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + false + true + comdlg32.dll + + + + + $(SolutionDir)\00-Common Headers + _DEBUG;_UNICODE;UNICODE;%(PreprocessorDefinitions) + + + true + + + + + Level3 + + + MinSpace + true + true + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + true + false + true + false + false + Default + ProgramDatabase + OnlyExplicitInline + Size + true + + + Windows + true + true + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + false + true + comdlg32.dll + + + + + $(SolutionDir)\00-Common Headers + + + true + + + + + Level3 + + + MinSpace + true + true + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + $(SolutionDir)\00-Common Headers + true + false + true + false + false + Default + ProgramDatabase + OnlyExplicitInline + Size + true + + + Windows + true + true + true + $(TargetDir);$(SolutionDir)\00-Import Libraries + + + false + true + comdlg32.dll + + + + + $(SolutionDir)\00-Common Headers + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/VxlView/VxlView.vcxproj.filters b/VxlView/VxlView.vcxproj.filters new file mode 100644 index 0000000..b0caff0 --- /dev/null +++ b/VxlView/VxlView.vcxproj.filters @@ -0,0 +1,79 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + Resource Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/VxlView/backend.c b/VxlView/backend.c new file mode 100644 index 0000000..320b9b5 --- /dev/null +++ b/VxlView/backend.c @@ -0,0 +1,464 @@ +#include "vxlview.h" +#include "resource.h" +#include "backendp.h" + +// +// This file contains functions to interact with VXLL, maintain a cache +// of log entries, and filter/sort the log entries. +// + +PBACKENDSTATE State = NULL; + +// +// This function must be called before any other function in this file is used. +// Otherwise, the application will crash. +// +VOID InitializeBackend( + VOID) +{ + STATIC BACKENDSTATE StateInternal; + ZeroMemory(&StateInternal, sizeof(StateInternal)); + State = &StateInternal; +} + +// +// Prepare for application exit. Call before quitting the application. +// +VOID CleanupBackend( + VOID) +{ + if (State) { + // + // The only thing we do is close the log file, because it is necessary for + // the smooth operation of future applications that handle the log file. + // All allocated memory will be released by the operating system so there is + // no reason to waste time trying to clean it. + // + VxlCloseLog(&State->LogHandle); + } +} + +// +// Return TRUE if a log file is currently opened, or FALSE otherwise. +// +BOOLEAN IsLogFileOpened( + VOID) +{ + if (State->LogHandle) { + return TRUE; + } else { + return FALSE; + } +} + +// +// Open a log file. +// +BOOLEAN OpenLogFile( + IN PCWSTR LogFileNameWin32) +{ + NTSTATUS Status; + VXLHANDLE NewLogHandle; + UNICODE_STRING LogFileNameNt; + OBJECT_ATTRIBUTES ObjectAttributes; + PPLOGENTRYCACHEENTRY NewLogEntryCache; + ULONG NewNumberOfLogEntries; + ULONG SizeOfNewNumberOfLogEntries; + ULONG Index; + + NewLogHandle = NULL; + NewLogEntryCache = NULL; + + SetWindowText(StatusBarWindow, L"Opening file, please wait..."); + + // + // Convert Win32 file name to NT + // + + Status = RtlDosPathNameToNtPathName_U_WithStatus( + LogFileNameWin32, + &LogFileNameNt, + NULL, + NULL); + + if (!NT_SUCCESS(Status)) { + ErrorBoxF(L"%s failed to convert \"%s\" to a NT filename (%s)", + FRIENDLYAPPNAME, LogFileNameWin32, KexRtlNtStatusToString(Status)); + goto OpenFailure; + } + + InitializeObjectAttributes( + &ObjectAttributes, + &LogFileNameNt, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + // + // Open the log file + // + + Status = VxlOpenLog( + &NewLogHandle, + NULL, + &ObjectAttributes, + GENERIC_READ, + FILE_OPEN); + + RtlFreeUnicodeString(&LogFileNameNt); + + if (!NT_SUCCESS(Status)) { + ErrorBoxF(L"%s failed to open %s (%s)", + FRIENDLYAPPNAME, LogFileNameWin32, KexRtlNtStatusToString(Status)); + goto OpenFailure; + } + + // + // Find how many log entries there are in the file and allocate memory for + // the log-entry cache. + // + SizeOfNewNumberOfLogEntries = sizeof(NewNumberOfLogEntries); + Status = VxlQueryInformationLog( + NewLogHandle, + LogTotalNumberOfEvents, + &NewNumberOfLogEntries, + &SizeOfNewNumberOfLogEntries); + + if (!NT_SUCCESS(Status)) { + ErrorBoxF(L"%s failed to query information about %s. %s.", + FRIENDLYAPPNAME, LogFileNameWin32, KexRtlNtStatusToString(Status)); + goto OpenFailure; + } + + if (NewNumberOfLogEntries == 0) { + MessageBoxF(0, TD_INFORMATION_ICON, NULL, NULL, + L"There are no entries in the log file you selected.\r\n" + L"Please select a log file which is not empty."); + goto OpenFailure; + } + + NewLogEntryCache = SafeAlloc(PLOGENTRYCACHEENTRY, NewNumberOfLogEntries); + if (!NewLogEntryCache) { + ErrorBoxF(L"%s failed to allocate memory to store the log entry cache. " + L"Try closing other applications or browser tabs before trying again.", + FRIENDLYAPPNAME); + goto OpenFailure; + } + + RtlZeroMemory(NewLogEntryCache, NewNumberOfLogEntries * sizeof(PLOGENTRYCACHEENTRY)); + + // + // copy values of all New* variables into the global ones + // + + if (State->LogHandle) { + VxlCloseLog(&State->LogHandle); + } + + SafeFree(State->FilteredLookupCache); + + for (Index = 0; Index < State->NumberOfLogEntries; ++Index) { + SafeFree(State->LogEntryCache[Index]); + } + + SafeFree(State->LogEntryCache); + + RtlZeroMemory(State, sizeof(*State)); + State->NumberOfLogEntries = NewNumberOfLogEntries; + State->LogHandle = NewLogHandle; + State->LogEntryCache = NewLogEntryCache; + + // + // perform other misc. actions such as updating the UI text and whatever + // + + UpdateMainMenu(); + SetWindowText(StatusBarWindow, L"Finished."); + StatusBar_SetTextF(StatusBarWindow, 1, L"%lu entr%s in file", + State->NumberOfLogEntries, + State->NumberOfLogEntries == 1 ? L"y" : L"ies"); + SetWindowTextF(MainWindow, L"%s - %s", FRIENDLYAPPNAME, LogFileNameWin32); + + PopulateSourceComponents(State->LogHandle); + ResetFilterControls(); + + return TRUE; + +OpenFailure: + if (NewLogHandle) { + VxlCloseLog(&NewLogHandle); + } + + SetWindowText(StatusBarWindow, L"Couldn't open the log file."); + return FALSE; +} + +// +// Open a dialog to ask the user for a log file, and then open it. +// +BOOLEAN OpenLogFileWithPrompt( + VOID) +{ + BOOLEAN Success; + OPENFILENAME OpenDialogInfo; + WCHAR OpenFileName[MAX_PATH]; + + ZeroMemory(&OpenDialogInfo, sizeof(OpenDialogInfo)); + OpenFileName[0] = '\0'; + OpenDialogInfo.lStructSize = sizeof(OpenDialogInfo); + OpenDialogInfo.hwndOwner = MainWindow; + OpenDialogInfo.lpstrFilter = L"VXLog Files (*.vxl)\0*.vxl\0All Files (*.*)\0*.*\0"; + OpenDialogInfo.nMaxFile = ARRAYSIZE(OpenFileName); + OpenDialogInfo.lpstrFile = OpenFileName; + OpenDialogInfo.lpstrTitle = L"Select a log file..."; + OpenDialogInfo.Flags = OFN_PATHMUSTEXIST; + OpenDialogInfo.lpstrDefExt = L"vxl"; + + Success = GetOpenFileName(&OpenDialogInfo); + + if (Success) { + Success = OpenLogFile(OpenFileName); + } + + return Success; +} + +// Free the UNICODE_STRING by calling RtlFreeUnicodeString after you're done with it +NTSTATUS ConvertCacheEntryToText( + IN PLOGENTRYCACHEENTRY CacheEntry, + OUT PUNICODE_STRING ExportedText, + IN BOOLEAN LongForm) +{ + HRESULT Result; + PVXLLOGENTRY LogEntry; + SIZE_T RemainingBytes; + + ASSERT (CacheEntry != NULL); + ASSERT (ExportedText != NULL); + + LogEntry = &CacheEntry->LogEntry; + + ExportedText->Length = 0; + ExportedText->MaximumLength = LogEntry->Text.Length + LogEntry->TextHeader.Length + (256 * sizeof(WCHAR)); + ExportedText->Buffer = (PWCHAR) SafeAlloc(BYTE, ExportedText->MaximumLength); + + if (LongForm) { + Result = StringCbPrintfEx( + ExportedText->Buffer, + ExportedText->MaximumLength, + NULL, + &RemainingBytes, + 0, + L"Date/Time: %s\r\n" + L"Source: PID %lu, TID %lu, %s\\%s:%s (in function %s)\r\n" + L"%wZ%s%wZ\r\n", + CacheEntry->ShortDateTimeAsString, + (ULONG) LogEntry->ClientId.UniqueProcess, + (ULONG) LogEntry->ClientId.UniqueThread, + State->LogHandle->Header->SourceComponents[LogEntry->SourceComponentIndex], + State->LogHandle->Header->SourceFiles[LogEntry->SourceFileIndex], + CacheEntry->SourceLineAsString, + State->LogHandle->Header->SourceFunctions[LogEntry->SourceFunctionIndex], + &LogEntry->TextHeader, + LogEntry->Text.Length != 0 ? L"\r\n\r\n" : L"", + &LogEntry->Text); + } else { + Result = StringCbPrintfEx( + ExportedText->Buffer, + ExportedText->MaximumLength, + NULL, + &RemainingBytes, + 0, + L"[%s %04lx:%04lx %s\\%s:%s (%s)] %wZ%s%s\r\n", + CacheEntry->ShortDateTimeAsString, + (ULONG) LogEntry->ClientId.UniqueProcess, + (ULONG) LogEntry->ClientId.UniqueThread, + State->LogHandle->Header->SourceComponents[LogEntry->SourceComponentIndex], + State->LogHandle->Header->SourceFiles[LogEntry->SourceFileIndex], + CacheEntry->SourceLineAsString, + State->LogHandle->Header->SourceFunctions[LogEntry->SourceFunctionIndex], + &LogEntry->TextHeader, + LogEntry->Text.Length != 0 ? L" // " : L"", + LogEntry->Text.Buffer != NULL ? LogEntry->Text.Buffer : L""); + } + + if (Result == STRSAFE_E_INSUFFICIENT_BUFFER) { + ExportedText->Length = ExportedText->MaximumLength - sizeof(WCHAR); + return STATUS_BUFFER_OVERFLOW; + } else if (FAILED(Result)) { + ExportedText->Length = 0; + return STATUS_DATA_ERROR; + } + + ExportedText->Length = ExportedText->MaximumLength - (USHORT) RemainingBytes; + return STATUS_SUCCESS; +} + +// +// Export the currently opened log to a text file. +// +VOID ExportLog( + IN PCWSTR TextFileName) +{ + RtlCreateUserThread( + NtCurrentProcess(), + NULL, + FALSE, + 0, + 0, + 0, + ExportLogThreadProc, + (PVOID) TextFileName, + NULL, + NULL); +} + +// +// Open a dialog to ask the user for a save file location, and then +// export the currently opened log. +// +BOOLEAN ExportLogWithPrompt( + VOID) +{ + BOOLEAN Success; + HRESULT Result; + OPENFILENAME SaveDialogInfo; + STATIC WCHAR SaveFileName[MAX_PATH]; + PCWSTR FileNameFormat = L"Exported log from %s.txt"; + + ZeroMemory(&SaveDialogInfo, sizeof(SaveDialogInfo)); + + // + // Set a default file name for the exported .txt file. + // + + Result = StringCchPrintf( + SaveFileName, + ARRAYSIZE(SaveFileName), + FileNameFormat, + State->LogHandle->Header->SourceApplication); + if (FAILED(Result)) { + StringCchCopy(SaveFileName, ARRAYSIZE(SaveFileName), L"Exported Log.txt"); + } + + PathReplaceIllegalCharacters(SaveFileName, '_', FALSE); + + SaveDialogInfo.lStructSize = sizeof(SaveDialogInfo); + SaveDialogInfo.hwndOwner = MainWindow; + SaveDialogInfo.lpstrFilter = L"Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0"; + SaveDialogInfo.nMaxFile = ARRAYSIZE(SaveFileName); + SaveDialogInfo.lpstrFile = SaveFileName; + SaveDialogInfo.Flags = OFN_OVERWRITEPROMPT; + SaveDialogInfo.lpstrDefExt = L"txt"; + + Success = GetSaveFileName(&SaveDialogInfo); + + if (Success) { + ExportLog(SaveFileName); + } + + return Success; +} + +VOID SetBackendFilters( + IN PBACKENDFILTERS Filters) +{ + CopyMemory(&State->Filters, Filters, sizeof(*Filters)); + RebuildFilterCache(); + ListView_SetItemCount(ListViewWindow, State->EstimatedNumberOfFilteredLogEntries); +} + +ULONG GetLogEntryRawIndex( + IN ULONG EntryIndex) +{ + ULONG DisplayIndex; + ULONG RawIndex; + + // + // if we already cached this, we don't need to evaluate filters + // + if (State->FilteredLookupCache[EntryIndex] != ((ULONG) -1)) { + return State->FilteredLookupCache[EntryIndex]; + } + + for (DisplayIndex = 0; + DisplayIndex < State->EstimatedNumberOfFilteredLogEntries && DisplayIndex <= EntryIndex; + DisplayIndex++) { + + // + // Run every entry against the filters up to the requested display index, + // if it hasn't been filtered already. + // + if (State->FilteredLookupCache[DisplayIndex] != -1) { + continue; + } + + if (DisplayIndex != 0) { + RawIndex = State->FilteredLookupCache[DisplayIndex - 1] + 1; + } else { + RawIndex = 0; + } + + for (; RawIndex < State->NumberOfLogEntries; RawIndex++) { + PLOGENTRYCACHEENTRY CacheEntry; + + CacheEntry = GetLogEntryRaw(RawIndex); + + if (!CacheEntry) { + continue; + } + + if (LogEntryMatchesFilters(CacheEntry)) { + State->FilteredLookupCache[DisplayIndex] = RawIndex; + break; + } + + if (RawIndex == (State->NumberOfLogEntries - 1)) { + // we have reached the end, there are no more filtered entries + ListView_SetItemCountEx(ListViewWindow, DisplayIndex, LVSICF_NOINVALIDATEALL); + } + } + } + + return State->FilteredLookupCache[EntryIndex]; +} + +// This function is rather inefficient as it was hacked in after the core backend +// was already designed. It's used for the Ctrl+G "go to raw entry" functionality. +ULONG GetLogEntryIndexFromRawIndex( + IN ULONG RawIndex) +{ + ULONG RawIndexOfItem; + ULONG Index; + + Index = 0; + + do { + RawIndexOfItem = GetLogEntryRawIndex(Index); + + if (RawIndexOfItem == RawIndex) { + return Index; + } + + ++Index; + } until (RawIndexOfItem == RawIndex || RawIndexOfItem == -1); + + return (ULONG) -1; +} + +// +// Get a log entry, respecting the current filters. +// +PLOGENTRYCACHEENTRY GetLogEntry( + IN ULONG EntryIndex) +{ + ULONG RawIndex; + + RawIndex = GetLogEntryRawIndex(EntryIndex); + + if (RawIndex == -1) { + return NULL; + } + + return GetLogEntryRaw(RawIndex); +} \ No newline at end of file diff --git a/VxlView/backendp.c b/VxlView/backendp.c new file mode 100644 index 0000000..7f89343 --- /dev/null +++ b/VxlView/backendp.c @@ -0,0 +1,401 @@ +#include "vxlview.h" +#include +#include "resource.h" +#include "backendp.h" + +// +// This file contains private functions of the backend. +// + +NTSTATUS NTAPI ExportLogThreadProc( + IN PVOID Parameter) +{ + NTSTATUS Status; + HANDLE FileHandle; + UNICODE_STRING TextFileNameNt; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + PCWSTR TextFileNameWin32; + ULONG EntryIndex; + ULONG MaxEntryIndex; + ULONG SizeofMaxEntryIndex; + ULONG CompletedPercentage; + ULONG PreviousCompletedPercentage; + + SetClassLongPtr(MainWindow, GCLP_HCURSOR, (LONG_PTR) LoadCursor(NULL, IDC_WAIT)); + EnableWindow(MainWindow, FALSE); + + TextFileNameWin32 = (PCWSTR) Parameter; + EntryIndex = 0; + SizeofMaxEntryIndex = sizeof(MaxEntryIndex); + CompletedPercentage = 0; + PreviousCompletedPercentage = 0; + + // + // find out total number of log entries, for calculating percentage + // + + Status = VxlQueryInformationLog( + State->LogHandle, + LogTotalNumberOfEvents, + &MaxEntryIndex, + &SizeofMaxEntryIndex); + + if (!NT_SUCCESS(Status)) { + goto Finished; + } + + // safe to do this because we refuse to open log files with no entries + --MaxEntryIndex; + + // + // Convert win32 name to NT name and open the destination file + // + + Status = RtlDosPathNameToNtPathName_U_WithStatus( + TextFileNameWin32, + &TextFileNameNt, + NULL, + NULL); + + if (!NT_SUCCESS(Status)) { + goto Finished; + } + + InitializeObjectAttributes(&ObjectAttributes, &TextFileNameNt, OBJ_CASE_INSENSITIVE, NULL, NULL); + + Status = NtCreateFile( + &FileHandle, + GENERIC_WRITE | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_READ, + FILE_OVERWRITE_IF, + FILE_NON_DIRECTORY_FILE, + NULL, + 0); + + RtlFreeUnicodeString(&TextFileNameNt); + + if (!NT_SUCCESS(Status)) { + goto Finished; + } + + // + // loop over every log entry, convert to text and write out to the file + // + + while (EntryIndex <= MaxEntryIndex) { + PLOGENTRYCACHEENTRY CacheEntry; + UNICODE_STRING ExportedText; + LONGLONG ByteOffset; + + CacheEntry = GetLogEntryRaw(EntryIndex++); + ConvertCacheEntryToText(CacheEntry, &ExportedText, FALSE); + + // + // Write out the text to the file. + // + + ByteOffset = -1; // write at end of file + + // wait for previous write to complete before starting a new one + Status = NtWaitForSingleObject(FileHandle, FALSE, NULL); + ASSERT (Status == STATUS_SUCCESS); + + Status = NtWriteFile( + FileHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + ExportedText.Buffer, + ExportedText.Length, + &ByteOffset, + NULL); + + RtlFreeUnicodeString(&ExportedText); + ASSERT (NT_SUCCESS(Status)); + + // + // Calculate percentage completed, for UI update + // + + CompletedPercentage = (EntryIndex + 1) * 100 / (MaxEntryIndex + 1); + ASSERT (CompletedPercentage <= 100); + ASSERT (PreviousCompletedPercentage <= 100); + + // + // Avoid expensive UI update if the percentage hasn't changed + // + + if (CompletedPercentage != PreviousCompletedPercentage) { + SetWindowTextF(StatusBarWindow, L"Exporting log entries. Please wait... (%ld%%)", CompletedPercentage); + PreviousCompletedPercentage = CompletedPercentage; + } + } + + NtClose(FileHandle); + +Finished: + EnableWindow(MainWindow, TRUE); + SetClassLongPtr(MainWindow, GCLP_HCURSOR, (LONG_PTR) LoadCursor(NULL, IDC_ARROW)); + SetWindowText(StatusBarWindow, L"Finished."); + + if (NT_SUCCESS(Status)) { + InfoBoxF(L"Export complete."); + } else { + ErrorBoxF(L"Failed to export the log (%s)", KexRtlNtStatusToString(Status)); + } + + return Status; +} + +VOID PopulateSourceComponents( + IN VXLHANDLE LogHandle) +{ + HWND SourceComponentListViewWindow; + ULONG Index; + + SourceComponentListViewWindow = GetDlgItem(FilterWindow, IDC_COMPONENTLIST); + ListView_DeleteAllItems(SourceComponentListViewWindow); + + for (Index = 0; Index < ARRAYSIZE(LogHandle->Header->SourceComponents) && + LogHandle->Header->SourceComponents[Index][0] != '\0'; ++Index) { + LVITEM Item; + + Item.mask = LVIF_TEXT; + Item.iItem = Index; + Item.iSubItem = 0; + Item.pszText = LogHandle->Header->SourceComponents[Index]; + + ListView_InsertItem(SourceComponentListViewWindow, &Item); + ListView_SetCheckState(SourceComponentListViewWindow, Index, TRUE); + } +} + +PLOGENTRYCACHEENTRY AddLogEntryToCache( + IN ULONG EntryIndex, + IN PVXLLOGENTRY LogEntry) +{ + PLOGENTRYCACHEENTRY CacheEntry; + WCHAR DateFormat[32]; + WCHAR TimeFormat[32]; + + CacheEntry = SafeAlloc(LOGENTRYCACHEENTRY, 1); + if (!CacheEntry) { + return NULL; + } + + RtlZeroMemory(CacheEntry, sizeof(*CacheEntry)); + CacheEntry->LogEntry = *LogEntry; + + // + // pre-calc some strings + // + + GetDateFormatEx( + LOCALE_NAME_USER_DEFAULT, + DATE_AUTOLAYOUT | DATE_SHORTDATE, + &LogEntry->Time, + NULL, + DateFormat, + ARRAYSIZE(DateFormat), + NULL); + + GetTimeFormatEx( + LOCALE_NAME_USER_DEFAULT, + TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT, + &LogEntry->Time, + NULL, + TimeFormat, + ARRAYSIZE(CacheEntry->ShortDateTimeAsString)); + + StringCchPrintf( + CacheEntry->ShortDateTimeAsString, + ARRAYSIZE(CacheEntry->ShortDateTimeAsString), + L"%s %s", DateFormat, TimeFormat); + + StringCchPrintf( + CacheEntry->SourceLineAsString, + ARRAYSIZE(CacheEntry->SourceLineAsString), + L"%lu", LogEntry->SourceLine); + + State->LogEntryCache[EntryIndex] = CacheEntry; + return CacheEntry; +} + +// +// Retrieve a log entry from the cache or from the log file. +// This function does not apply any filters. +// +PLOGENTRYCACHEENTRY GetLogEntryRaw( + IN ULONG EntryIndex) +{ + NTSTATUS Status; + PLOGENTRYCACHEENTRY CacheEntry; + + CacheEntry = State->LogEntryCache[EntryIndex]; + + if (!CacheEntry) { + VXLLOGENTRY LogEntry; + + Status = VxlReadLog(State->LogHandle, EntryIndex, &LogEntry); + if (!NT_SUCCESS(Status)) { + return NULL; + } + + CacheEntry = AddLogEntryToCache(EntryIndex, &LogEntry); + } + + return CacheEntry; +} + +BOOLEAN LogEntryMatchesFilters( + IN PLOGENTRYCACHEENTRY CacheEntry) +{ + BOOLEAN LogEntryMatchesTextFilter; + + // + // The idea with this function is to apply the easiest/cheapest (in terms of + // computation power) filters first. So that means, anything which requires + // string comparisons and regex matching comes last. + // + // This function is one of the most critical when it comes to user experience, + // since it is called potentially hundreds of thousands of times when the user + // wants to search for text. + // + + // 1. Does the log entry match the severity filter? If not, then we don't display + // this log entry. + if (State->Filters.SeverityFilters[CacheEntry->LogEntry.Severity] == FALSE) { + return FALSE; + } + + // 2. Does this log entry match the source component filter? If not, then we don't + // display this log entry. + if (State->Filters.ComponentFilters[CacheEntry->LogEntry.SourceComponentIndex] == FALSE) { + return FALSE; + } + + // 3. Does this log entry match the text filter? Note: empty filter always matches. + LogEntryMatchesTextFilter = FALSE; + + if (State->Filters.TextFilter.Length == 0) { + // empty filter + LogEntryMatchesTextFilter = TRUE; + } else { + PUNICODE_STRING TextToSearch; + + TextToSearch = &CacheEntry->LogEntry.TextHeader; + +SearchAgain: + if (State->Filters.TextFilterWildcardMatch) { + LogEntryMatchesTextFilter = RtlIsNameInExpression( + &State->Filters.TextFilter, + TextToSearch, + !State->Filters.TextFilterCaseSensitive, + NULL); + } else { + if (State->Filters.TextFilterCaseSensitive) { + if (State->Filters.TextFilterExact) { + if (StringEqual(TextToSearch->Buffer, State->Filters.TextFilter.Buffer)) { + LogEntryMatchesTextFilter = TRUE; + } + } else { + if (StringSearch(TextToSearch->Buffer, State->Filters.TextFilter.Buffer)) { + LogEntryMatchesTextFilter = TRUE; + } + } + } else { + if (State->Filters.TextFilterExact) { + if (StringEqualI(TextToSearch->Buffer, State->Filters.TextFilter.Buffer)) { + LogEntryMatchesTextFilter = TRUE; + } + } else { + if (StringSearchI(TextToSearch->Buffer, State->Filters.TextFilter.Buffer)) { + LogEntryMatchesTextFilter = TRUE; + } + } + } + } + + if (State->Filters.TextFilterWhole && TextToSearch == &CacheEntry->LogEntry.TextHeader) { + if (CacheEntry->LogEntry.Text.Buffer != NULL) { + TextToSearch = &CacheEntry->LogEntry.Text; + goto SearchAgain; + } + } + } + + if (State->Filters.TextFilterInverted) { + LogEntryMatchesTextFilter = !LogEntryMatchesTextFilter; + } + + return LogEntryMatchesTextFilter; +} + +// +// Returns an ESTIMATE of the number of log entries that will be displayed +// by those filters. This estimate is not accurate for log files with many +// entries, because creating an accurate value for the number of log entries +// for any given filter requires evaluating the filter on all of the log +// entries. +// The estimate will always be equal to or greater than the actual number of +// log entries that match the filters. +// +ULONG EstimateNumberOfFilteredLogEntries( + VOID) +{ + ULONG NumberOfFilteredLogEntries; + ULONG Index; + + NumberOfFilteredLogEntries = 0; + + if (State->NumberOfLogEntries < 2000000) { + // + // do an accurate estimate - evaluate all the entries + // + for (Index = 0; Index < State->NumberOfLogEntries; Index++) { + PLOGENTRYCACHEENTRY CacheEntry; + + CacheEntry = GetLogEntryRaw(Index); + + if (LogEntryMatchesFilters(CacheEntry)) { + NumberOfFilteredLogEntries++; + } + } + } else { + // + // inaccurate estimate - just wing it + // + for (Index = 0; Index < LogSeverityMaximumValue; Index++) { + if (State->Filters.SeverityFilters[Index]) { + NumberOfFilteredLogEntries += State->LogHandle->Header->EventSeverityTypeCount[Index]; + } + } + } + + return NumberOfFilteredLogEntries; +} + +VOID RebuildFilterCache( + VOID) +{ + ULONG EstimatedNumberOfFilteredLogEntries; + + // + // clear the filtered entries lookup table + // + SafeFree(State->FilteredLookupCache); + + // + // reallocate and initialize the lookup table + // + EstimatedNumberOfFilteredLogEntries = EstimateNumberOfFilteredLogEntries(); + State->EstimatedNumberOfFilteredLogEntries = EstimatedNumberOfFilteredLogEntries; + State->FilteredLookupCache = SafeAlloc(ULONG, EstimatedNumberOfFilteredLogEntries); + FillMemory(State->FilteredLookupCache, EstimatedNumberOfFilteredLogEntries * sizeof(ULONG), 0xFF); +} \ No newline at end of file diff --git a/VxlView/backendp.h b/VxlView/backendp.h new file mode 100644 index 0000000..725ac49 --- /dev/null +++ b/VxlView/backendp.h @@ -0,0 +1,42 @@ +#pragma once + +// +// Private header file for the backend. +// + +typedef struct { + VXLHANDLE LogHandle; + PPLOGENTRYCACHEENTRY LogEntryCache; // Array of pointers to LOGENTRYCACHEENTRY structures. Some of the + // pointers may be NULL. The following condition holds: + // if (LogEntryCache) { + // DefHeapSize(LogEntryCache) / sizeof(PLOGENTRYCACHEENTRY) == NumberOfLogEntries; + // } + BACKENDFILTERS Filters; + ULONG EstimatedNumberOfFilteredLogEntries; + PULONG FilteredLookupCache; // display entry -> cache entry lookup table + + ULONG NumberOfLogEntries; // number of log entries in the file + ULONG FilteredNumberOfLogEntries; // number of log entries that are displayed by the user's filter selection +} BACKENDSTATE, *PBACKENDSTATE, **PPBACKENDSTATE, *CONST PCBACKENDSTATE, **CONST PPCBACKENDSTATE; + +// +// Global variables, defined in backend.c +// +extern PBACKENDSTATE State; + +// +// Private functions, defined in backendp.c +// +NTSTATUS NTAPI ExportLogThreadProc( + IN PVOID Parameter); +VOID PopulateSourceComponents( + IN VXLHANDLE LogHandle); +PLOGENTRYCACHEENTRY GetLogEntryRaw( + IN ULONG EntryIndex); +PLOGENTRYCACHEENTRY AddLogEntryToCache( + IN ULONG EntryIndex, + IN PVXLLOGENTRY LogEntry); +VOID RebuildFilterCache( + VOID); +BOOLEAN LogEntryMatchesFilters( + IN PLOGENTRYCACHEENTRY CacheEntry); \ No newline at end of file diff --git a/VxlView/buildcfg.h b/VxlView/buildcfg.h new file mode 100644 index 0000000..c0617c7 --- /dev/null +++ b/VxlView/buildcfg.h @@ -0,0 +1,39 @@ +#pragma once + +#define NOGDICAPMASKS +#define NOVIRTUALKEYCODES +#define NOKEYSTATES +#define NOSYSCOMMANDS +#define NORASTEROPS +#define NOATOM +#define NODRAWTEXT +#define NOMB +#define NOMEMMGR +#define NOOPENFILE +#define NOSCROLL +#define NOTEXTMETRIC +#define NOWH +#define NOCOMM +#define NOKANJI +#define NOHELP +#define NOPROFILER +#define NODEFERWINDOWPOS +#define NOMCX +#define NOCRYPT +#define NOMETAFILE +#define NOSERVICE +#define NOSOUND + +// +// Set to TRUE if you want VxlView to immediately prompt for a file if started +// with no command-line arguments. +// +#define PROMPT_FOR_FILE_ON_STARTUP TRUE + +#pragma comment(lib, "shell32.lib") +#pragma comment(lib, "uxtheme.lib") + +#define KEX_COMPONENT L"VxlView" +#define KEX_TARGET_TYPE_EXE +#define KEX_ENV_WIN32 +#define FRIENDLYAPPNAME L"Log Viewer" diff --git a/VxlView/config.c b/VxlView/config.c new file mode 100644 index 0000000..4e988e9 --- /dev/null +++ b/VxlView/config.c @@ -0,0 +1,116 @@ +#include "vxlview.h" + +// +// Functions to load and save configuration information from the registry, +// such as the size and position of the main window. +// + +STATIC PCWSTR APP_REG_KEY = L"SOFTWARE\\VXsoft\\VxlView"; + +VOID SaveWindowPlacement( + VOID) +{ + WINDOWPLACEMENT WindowPlacement; + + GetWindowPlacement(MainWindow, &WindowPlacement); + + RegWriteI32(HKEY_CURRENT_USER, APP_REG_KEY, L"WndLeft", WindowPlacement.rcNormalPosition.left); + RegWriteI32(HKEY_CURRENT_USER, APP_REG_KEY, L"WndTop", WindowPlacement.rcNormalPosition.top); + RegWriteI32(HKEY_CURRENT_USER, APP_REG_KEY, L"WndRight", WindowPlacement.rcNormalPosition.right); + RegWriteI32(HKEY_CURRENT_USER, APP_REG_KEY, L"WndBottom", WindowPlacement.rcNormalPosition.bottom); +} + +VOID RestoreWindowPlacement( + VOID) +{ + ULONG Error; + WINDOWPLACEMENT WindowPlacement; + + // required for first startup + SetWindowPos(MainWindow, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER); + + GetWindowPlacement(MainWindow, &WindowPlacement); + + Error = 0; + Error += RegReadI32(HKEY_CURRENT_USER, APP_REG_KEY, L"WndLeft", (PULONG) &WindowPlacement.rcNormalPosition.left); + Error += RegReadI32(HKEY_CURRENT_USER, APP_REG_KEY, L"WndTop", (PULONG) &WindowPlacement.rcNormalPosition.top); + Error += RegReadI32(HKEY_CURRENT_USER, APP_REG_KEY, L"WndRight", (PULONG) &WindowPlacement.rcNormalPosition.right); + Error += RegReadI32(HKEY_CURRENT_USER, APP_REG_KEY, L"WndBottom", (PULONG) &WindowPlacement.rcNormalPosition.bottom); + + SetWindowPlacement(MainWindow, &WindowPlacement); + + if (Error) { + // typically occurs on first startup + CenterWindow(MainWindow, HWND_DESKTOP); + } +} + +VOID SaveListViewColumns( + VOID) +{ + USHORT ColumnWidths[ColumnMaxValue]; + INT ColumnOrder[ColumnMaxValue]; + ULONG Index; + + ListView_GetColumnOrderArray(ListViewWindow, ARRAYSIZE(ColumnOrder), ColumnOrder); + + for (Index = 0; Index < ColumnMaxValue; Index++) { + ColumnWidths[Index] = ListView_GetColumnWidth(ListViewWindow, Index); + } + + RegSetKeyValue( + HKEY_CURRENT_USER, + APP_REG_KEY, + L"ColumnWidths", + REG_BINARY, + ColumnWidths, + sizeof(ColumnWidths)); + + RegSetKeyValue( + HKEY_CURRENT_USER, + APP_REG_KEY, + L"ColumnOrder", + REG_BINARY, + ColumnOrder, + sizeof(ColumnOrder)); +} + +VOID RestoreListViewColumns( + VOID) +{ + USHORT ColumnWidths[ColumnMaxValue]; + INT ColumnOrder[ColumnMaxValue]; + ULONG DataSize; + ULONG Index; + LSTATUS LStatus; + + DataSize = sizeof(ColumnOrder); + LStatus = RegGetValue( + HKEY_CURRENT_USER, + APP_REG_KEY, + L"ColumnOrder", + RRF_RT_REG_BINARY, + NULL, + ColumnOrder, + &DataSize); + + if (LStatus == ERROR_SUCCESS && DataSize == sizeof(ColumnOrder)) { + ListView_SetColumnOrderArray(ListViewWindow, ARRAYSIZE(ColumnOrder), ColumnOrder); + } + + DataSize = sizeof(ColumnWidths); + LStatus = RegGetValue( + HKEY_CURRENT_USER, + APP_REG_KEY, + L"ColumnWidths", + RRF_RT_REG_BINARY, + NULL, + ColumnWidths, + &DataSize); + + if (LStatus == ERROR_SUCCESS && DataSize == sizeof(ColumnWidths)) { + for (Index = 0; Index < ARRAYSIZE(ColumnWidths); Index++) { + ListView_SetColumnWidth(ListViewWindow, Index, ColumnWidths[Index]); + } + } +} \ No newline at end of file diff --git a/VxlView/details.c b/VxlView/details.c new file mode 100644 index 0000000..630403c --- /dev/null +++ b/VxlView/details.c @@ -0,0 +1,191 @@ +#include "vxlview.h" +#include "resource.h" +#include "backendp.h" + +VOID InitializeDetailsWindow( + VOID) +{ + HWND EditControlWindow; + HDC EditControlDeviceContext; + HFONT EditControlFont; + UINT TabStops; + + CreateDialog(NULL, MAKEINTRESOURCE(IDD_DETAILS), MainWindow, DetailsWndProc); + + // + // Make the edit control use a monospace font. + // + EditControlWindow = GetDlgItem(DetailsWindow, IDC_DETAILSMESSAGETEXT); + EditControlDeviceContext = GetDC(EditControlWindow); + EditControlFont = CreateFont( + -MulDiv(8, GetDeviceCaps(EditControlDeviceContext, LOGPIXELSY), 72), + 0, 0, 0, FW_NORMAL, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, + CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, DEFAULT_PITCH | FF_DONTCARE, + L"Lucida Console"); + + ReleaseDC(EditControlWindow, EditControlDeviceContext); + + TabStops = 16; // 4-space tabs + SendMessage(EditControlWindow, WM_SETFONT, (WPARAM) EditControlFont, MAKELPARAM(TRUE, 0)); + Edit_SetTabStops(EditControlWindow, 1, &TabStops); + Edit_SetReadOnly(EditControlWindow, TRUE); + + ResetDetailsWindow(); +} + +VOID ResetDetailsWindow( + VOID) +{ + SetDlgItemText(DetailsWindow, IDC_DETAILSSEVERITYTEXT, L""); + SetDlgItemText(DetailsWindow, IDC_DETAILSDATETIMETEXT, L""); + SetDlgItemText(DetailsWindow, IDC_DETAILSSOURCETEXT, L""); + SetDlgItemText(DetailsWindow, IDC_DETAILSMESSAGETEXT, L"(No log entry selected.)"); +} + +VOID ResizeDetailsWindow( + VOID) +{ + RECT MainWindowClientRect; + RECT FilterWindowRect; + RECT DetailsWindowClientRect; + + GetClientRect(DetailsWindow, &DetailsWindowClientRect); + GetClientRect(MainWindow, &MainWindowClientRect); + GetWindowRect(FilterWindow, &FilterWindowRect); + MapWindowRect(HWND_DESKTOP, MainWindow, &FilterWindowRect); + + SetWindowPos( + DetailsWindow, + NULL, + FilterWindowRect.right, + FilterWindowRect.top, + MainWindowClientRect.right - FilterWindowRect.right - DpiScaleX(5), + FilterWindowRect.bottom - FilterWindowRect.top, + SWP_NOZORDER); +} + +VOID PopulateDetailsWindow( + IN ULONG EntryIndex) +{ + WCHAR DateFormat[64]; + WCHAR TimeFormat[32]; + PLOGENTRYCACHEENTRY CacheEntry; + HWND DetailsMessageTextWindow; + + CacheEntry = GetLogEntry(EntryIndex); + if (!CacheEntry) { + return; + } + + GetDateFormatEx( + LOCALE_NAME_USER_DEFAULT, + DATE_AUTOLAYOUT | DATE_LONGDATE, + &CacheEntry->LogEntry.Time, + NULL, + DateFormat, + ARRAYSIZE(DateFormat), + NULL); + + GetTimeFormatEx( + LOCALE_NAME_USER_DEFAULT, + 0, + &CacheEntry->LogEntry.Time, + NULL, + TimeFormat, + ARRAYSIZE(TimeFormat)); + + SetDlgItemTextF(DetailsWindow, IDC_DETAILSSEVERITYTEXT, L"%s (%s.)", + VxlSeverityToText(CacheEntry->LogEntry.Severity, FALSE), + VxlSeverityToText(CacheEntry->LogEntry.Severity, TRUE)); + + SetDlgItemTextF(DetailsWindow, IDC_DETAILSDATETIMETEXT, L"%s at %s", DateFormat, TimeFormat); + + SetDlgItemTextF(DetailsWindow, IDC_DETAILSSOURCETEXT, L"[%04lx:%04lx], %s (%s, line %lu, in function %s)", + (ULONG) CacheEntry->LogEntry.ClientId.UniqueProcess, + (ULONG) CacheEntry->LogEntry.ClientId.UniqueThread, + State->LogHandle->Header->SourceComponents[CacheEntry->LogEntry.SourceComponentIndex], + State->LogHandle->Header->SourceFiles[CacheEntry->LogEntry.SourceFileIndex], + CacheEntry->LogEntry.SourceLine, + State->LogHandle->Header->SourceFunctions[CacheEntry->LogEntry.SourceFunctionIndex]); + + DetailsMessageTextWindow = GetDlgItem(DetailsWindow, IDC_DETAILSMESSAGETEXT); + SetWindowText(DetailsMessageTextWindow, CacheEntry->LogEntry.TextHeader.Buffer); + + if (CacheEntry->LogEntry.Text.Length != 0) { + // append the rest of the log entry text + Edit_SetSel(DetailsMessageTextWindow, INT_MAX, INT_MAX); + Edit_ReplaceSel(DetailsMessageTextWindow, L"\r\n\r\n"); + Edit_SetSel(DetailsMessageTextWindow, INT_MAX, INT_MAX); + Edit_ReplaceSel(DetailsMessageTextWindow, CacheEntry->LogEntry.Text.Buffer); + } +} + +INT_PTR CALLBACK DetailsWndProc( + IN HWND _DetailsWindow, + IN UINT Message, + IN WPARAM WParam, + IN LPARAM LParam) +{ + if (Message == WM_INITDIALOG) { + UNCONST (HWND) DetailsWindow = _DetailsWindow; + } else if (Message == WM_CTLCOLORSTATIC) { + HDC DeviceContext; + HWND Window; + + Window = (HWND) LParam; + DeviceContext = (HDC) WParam; + + if (Window == GetDlgItem(DetailsWindow, IDC_DETAILSMESSAGETEXT)) { + SetTextColor(DeviceContext, GetSysColor(COLOR_WINDOWTEXT)); + SetBkColor(DeviceContext, GetSysColor(COLOR_WINDOW)); + return (INT_PTR) GetSysColorBrush(COLOR_WINDOW); + } else { + return FALSE; + } + } else if (Message == WM_SIZE) { + ULONG Index; + USHORT NewWidth; + USHORT NewHeight; + + NewWidth = LOWORD(LParam); + NewHeight = HIWORD(LParam); + + // resize the border to match the window size + SetWindowPos( + GetDlgItem(DetailsWindow, IDC_GBDETAILSBORDER), + HWND_TOP, + 0, 0, + NewWidth, NewHeight, + 0); + + // resize the edit control + SetWindowPos( + GetDlgItem(DetailsWindow, IDC_DETAILSMESSAGETEXT), + HWND_TOP, + DpiScaleX(80), DpiScaleY(75), + NewWidth - DpiScaleX(90), NewHeight - DpiScaleY(85), + 0); + + // resize the severity, date/time and source text boxes + for (Index = IDC_DETAILSSEVERITYTEXT; Index <= IDC_DETAILSSOURCETEXT; Index++) { + HWND Window; + RECT ClientRect; + + Window = GetDlgItem(DetailsWindow, Index); + GetClientRect(Window, &ClientRect); + + ClientRect.right = NewWidth - DpiScaleX(90); + + SetWindowPos( + Window, + HWND_TOP, + 0, 0, + ClientRect.right, ClientRect.bottom, + SWP_NOMOVE); + } + } else { + return FALSE; + } + + return TRUE; +} \ No newline at end of file diff --git a/VxlView/filters.c b/VxlView/filters.c new file mode 100644 index 0000000..af6c4af --- /dev/null +++ b/VxlView/filters.c @@ -0,0 +1,266 @@ +#include "vxlview.h" +#include "resource.h" + +STATIC CONST USHORT FilterControlIds[] = { + IDC_GBFILTERSEVERITY, + IDC_CBFILTERCRITICAL, + IDC_CBFILTERERROR, + IDC_CBFILTERWARNING, + IDC_CBFILTERINFORMATION, + IDC_CBFILTERDETAIL, + IDC_CBFILTERDEBUG +}; + +VOID InitializeFilterControls( + VOID) +{ + ULONG Index; + HRESULT Result; + WCHAR ToolTipText[256]; + + CreateDialog(NULL, MAKEINTRESOURCE(IDD_FILTERS), MainWindow, FilterWndProc); + + // add tool-tips to the checkboxes + for (Index = IDC_CBFILTERCRITICAL; Index < (IDC_CBFILTERCRITICAL + LogSeverityMaximumValue); Index++) { + Result = StringCchPrintf( + ToolTipText, + ARRAYSIZE(ToolTipText), + L"Display %s events.", + VxlSeverityToText((VXLSEVERITY) (Index - IDC_CBFILTERCRITICAL), FALSE)); + + if (SUCCEEDED(Result) && Index == IDC_CBFILTERDEBUG) { + Result = StringCchCat( + ToolTipText, + ARRAYSIZE(ToolTipText), + L"\r\nDebug events are only generated by debug builds of VxKex."); + } + + if (SUCCEEDED(Result)) { + ToolTip(FilterWindow, Index, ToolTipText); + } + } + + // set cue text in the search box and add a tool-tip to relevant items + Edit_SetCueBannerText(GetDlgItem(FilterWindow, IDC_SEARCHBOX), L"Enter search term..."); + + ToolTip(FilterWindow, IDC_SEARCHBOX, L"Search log entry message text."); + + ToolTip(FilterWindow, IDC_CBCASESENSITIVE, L"When checked, consider text with different capitalization to be different.\r\n\r\n" + L"For example, the search term \"Carrot\" would not match a log entry which contains \"CARROT\"."); + + ToolTip(FilterWindow, IDC_CBWILDCARD, L"When checked, allow wild-card matching with * (match any sequence) and ? (match any character).\r\n\r\n" + L"For example, the search term \"?o?ato\" would match log entries containing both \"potato\" and \"tomato\"."); + + ToolTip(FilterWindow, IDC_CBINVERTSEARCH, L"When checked, only show results that do NOT match the search criteria."); + + ToolTip(FilterWindow, IDC_CBEXACTMATCH, L"When checked, do not show results with leading and trailing text.\r\n\r\n" + L"For example, the search term \"Application started\" would not match a log entry which has the text \"Application started!\" due to the extra exclamation mark."); + + ToolTip(FilterWindow, IDC_CBSEARCHWHOLE, L"When checked, search the entire log text (including details), not just " + L"what is displayed in the list view."); + + // initialize component selection list view + ListView_SetExtendedListViewStyle( + GetDlgItem(FilterWindow, IDC_COMPONENTLIST), + LVS_EX_CHECKBOXES | LVS_EX_DOUBLEBUFFER); + + ResetFilterControls(); +} + +VOID ResetFilterControls( + VOID) +{ + ULONG Index; + + for (Index = IDC_CBFILTERCRITICAL; Index < (IDC_CBFILTERCRITICAL + LogSeverityMaximumValue); Index++) { + CheckDlgButton(FilterWindow, Index, TRUE); + } + + for (Index = IDC_CBCASESENSITIVE; Index <= IDC_CBEXACTMATCH; Index++) { + CheckDlgButton(FilterWindow, Index, FALSE); + } + + SetDlgItemText(FilterWindow, IDC_SEARCHBOX, L""); + ListView_SetCheckedStateAll(GetDlgItem(FilterWindow, IDC_COMPONENTLIST), TRUE); +} + +VOID ResizeFilterControls( + VOID) +{ + RECT StatusBarWindowRect; + RECT FilterWindowClientRect; + + GetClientRect(FilterWindow, &FilterWindowClientRect); + GetWindowRect(GetDlgItem(MainWindow, IDC_STATUSBAR), &StatusBarWindowRect); + MapWindowRect(HWND_DESKTOP, MainWindow, &StatusBarWindowRect); + + // + // Put the bottom of the filter window 10px above the top of the status bar. + // + SetWindowPos( + FilterWindow, + NULL, + 15, StatusBarWindowRect.top - FilterWindowClientRect.bottom - 10, + 0, 0, + SWP_NOSIZE | SWP_NOZORDER); +} + +VOID BuildBackendFilters( + OUT PBACKENDFILTERS Filters) +{ + ULONG Index; + ULONG NumberOfComponents; + ULONG TextFilterBufCch; + BOOLEAN NeedToAddTwoStars; + HWND ComponentListWindow; + STATIC PWSTR TextFilter = NULL; + + SafeFree(TextFilter); + + TextFilterBufCch = GetWindowTextLength(GetDlgItem(FilterWindow, IDC_SEARCHBOX)) + 1; + + if (!IsDlgButtonChecked(FilterWindow, IDC_CBEXACTMATCH) && + IsDlgButtonChecked(FilterWindow, IDC_CBWILDCARD)) { + + // add two '*' characters to beginning and end to implement non-exact match + TextFilterBufCch += 2; + NeedToAddTwoStars = TRUE; + } else { + NeedToAddTwoStars = FALSE; + } + + Filters->TextFilterCaseSensitive = IsDlgButtonChecked(FilterWindow, IDC_CBCASESENSITIVE); + Filters->TextFilterWildcardMatch = IsDlgButtonChecked(FilterWindow, IDC_CBWILDCARD); + Filters->TextFilterInverted = IsDlgButtonChecked(FilterWindow, IDC_CBINVERTSEARCH); + Filters->TextFilterExact = IsDlgButtonChecked(FilterWindow, IDC_CBEXACTMATCH); + Filters->TextFilterWhole = IsDlgButtonChecked(FilterWindow, IDC_CBSEARCHWHOLE); + + TextFilter = SafeAlloc(WCHAR, TextFilterBufCch); + if (TextFilter) { + GetDlgItemText( + FilterWindow, + IDC_SEARCHBOX, + TextFilter + NeedToAddTwoStars, + TextFilterBufCch - (NeedToAddTwoStars * 2)); + + if (NeedToAddTwoStars) { + TextFilter[0] = '*'; + TextFilter[TextFilterBufCch - 2] = '*'; + TextFilter[TextFilterBufCch - 1] = '\0'; + } + + RtlInitUnicodeString(&Filters->TextFilter, TextFilter); + + if (Filters->TextFilterWildcardMatch && !Filters->TextFilterCaseSensitive) { + // needed for RtlIsNameInExpression + RtlUpcaseUnicodeString(&Filters->TextFilter, &Filters->TextFilter, FALSE); + } + } + + for (Index = IDC_CBFILTERCRITICAL; Index <= IDC_CBFILTERDEBUG; Index++) { + VXLSEVERITY Severity; + + Severity = (VXLSEVERITY) (Index - IDC_CBFILTERCRITICAL); + Filters->SeverityFilters[Severity] = IsDlgButtonChecked(FilterWindow, Index); + } + + ComponentListWindow = GetDlgItem(FilterWindow, IDC_COMPONENTLIST); + NumberOfComponents = ListView_GetItemCount(ComponentListWindow); + + for (Index = 0; Index < NumberOfComponents; ++Index) { + Filters->ComponentFilters[Index] = ListView_GetCheckState( + ComponentListWindow, + ListView_MapIDToIndex(ComponentListWindow, Index)); + } +} + +VOID UpdateFilters( + VOID) +{ + BACKENDFILTERS Filters; + + if (!IsLogFileOpened()) { + return; + } + + BuildBackendFilters(&Filters); + SetBackendFilters(&Filters); +} + +INT_PTR CALLBACK FilterWndProc( + IN HWND _FilterWindow, + IN UINT Message, + IN WPARAM WParam, + IN LPARAM LParam) +{ + STATIC BOOLEAN FirstTime; + + if (Message == WM_INITDIALOG) { + UNCONST (HWND) FilterWindow = _FilterWindow; + FirstTime = TRUE; + } else if (Message == WM_CONTEXTMENU) { + HWND Window; + POINT ClickPoint; + + Window = (HWND) WParam; + ClickPoint.x = GET_X_LPARAM(LParam); + ClickPoint.y = GET_Y_LPARAM(LParam); + + if (Window == GetDlgItem(FilterWindow, IDC_COMPONENTLIST)) { + ULONG Selection; + + // + // display the "select all/select none" menu on the components + // list view + // + Selection = ContextMenu(Window, IDM_COMPONENTLISTMENU, &ClickPoint); + + if (Selection == M_SELECTALL || Selection == M_SELECTNONE) { + ListView_SetCheckedStateAll(Window, (Selection == M_SELECTALL)); + } + } + } else if (Message == WM_COMMAND) { + USHORT NotificationId; + WCHAR ClassName[32]; + + GetClassName((HWND) LParam, ClassName, ARRAYSIZE(ClassName)); + NotificationId = HIWORD(WParam); + + if (StringEqual(ClassName, L"Edit") && NotificationId != EN_CHANGE) { + // don't care about any other edit notifications besides + // EN_CHANGE + return FALSE; + } + + UpdateFilters(); + } else if (Message == WM_NOTIFY) { + LPNMHDR Notification; + + Notification = (LPNMHDR) LParam; + + if (Notification->idFrom == IDC_COMPONENTLIST) { + if (Notification->code == LVN_ITEMCHANGED) { + LPNMLISTVIEW ChangedItemInfo; + + ChangedItemInfo = (LPNMLISTVIEW) LParam; + + if (ChangedItemInfo->uNewState & 0x3000) { + if (FirstTime) { + FirstTime = FALSE; + } else { + // An source component was either checked or unchecked + UpdateFilters(); + } + } + } else { + return FALSE; + } + } else { + return FALSE; + } + } else { + return FALSE; + } + + return TRUE; +} \ No newline at end of file diff --git a/VxlView/globals.c b/VxlView/globals.c new file mode 100644 index 0000000..9d2b2c8 --- /dev/null +++ b/VxlView/globals.c @@ -0,0 +1,13 @@ +#include "buildcfg.h" +#include + +// +// These are defined normally here but in the header file they are externed +// as CONST. This is to prevent them from being edited by random code by +// accident. +// +HWND MainWindow = NULL; +HWND ListViewWindow = NULL; +HWND StatusBarWindow = NULL; +HWND DetailsWindow = NULL; +HWND FilterWindow = NULL; \ No newline at end of file diff --git a/VxlView/goto.c b/VxlView/goto.c new file mode 100644 index 0000000..eddb40c --- /dev/null +++ b/VxlView/goto.c @@ -0,0 +1,61 @@ +#include "buildcfg.h" +#include "vxlview.h" + +INT_PTR CALLBACK GotoRawDlgProc( + IN HWND Window, + IN UINT Message, + IN WPARAM WParam, + IN LPARAM LParam) +{ + if (Message == WM_INITDIALOG) { + CenterWindow(Window, MainWindow); + SendMessage(GetDlgItem(Window, scr1), UDM_SETRANGE32, 1, INT_MAX); + Edit_LimitText(GetDlgItem(Window, edt1), 10); + SetDlgItemInt(Window, edt1, 1, FALSE); + } else if (Message == WM_COMMAND) { + ULONG ControlId; + + ControlId = GET_WM_COMMAND_ID(WParam, LParam); + + if (ControlId == IDOK) { + BOOL SuccessfulConversion; + ULONG RawItemIndex; + ULONG ItemIndex; + + ItemIndex = (ULONG) -1; + RawItemIndex = GetDlgItemInt(Window, edt1, &SuccessfulConversion, FALSE); + + if (RawItemIndex > 0) { + --RawItemIndex; + } + + if (SuccessfulConversion) { + ItemIndex = GetLogEntryIndexFromRawIndex(RawItemIndex); + } + + if (ItemIndex == (ULONG) -1) { + EDITBALLOONTIP BalloonTip; + + BalloonTip.cbStruct = sizeof(BalloonTip); + BalloonTip.pszTitle = L"Invalid Item Number"; + BalloonTip.pszText = L"The item number you entered was either out of range " + L"or not displayed by the current set of filters you have " + L"selected."; + BalloonTip.ttiIcon = TTI_NONE; + + Edit_ShowBalloonTip(GetDlgItem(Window, edt1), &BalloonTip); + } else { + SelectListViewItemByIndex(ItemIndex); + EndDialog(Window, IDOK); + } + } else if (ControlId == IDCANCEL) { + PostMessage(Window, WM_CLOSE, 0, 0); + } + } else if (Message == WM_CLOSE) { + EndDialog(Window, IDCANCEL); + } else { + return FALSE; + } + + return TRUE; +} \ No newline at end of file diff --git a/VxlView/helpabout.c b/VxlView/helpabout.c new file mode 100644 index 0000000..63f17b7 --- /dev/null +++ b/VxlView/helpabout.c @@ -0,0 +1,25 @@ +#include "vxlview.h" +#include "resource.h" + +INT_PTR CALLBACK AboutWndProc( + IN HWND AboutWindow, + IN UINT Message, + IN WPARAM WParam, + IN LPARAM LParam) +{ + if (Message == WM_INITDIALOG) { + CenterWindow(AboutWindow, MainWindow); + } else if (Message == WM_CLOSE || Message == WM_COMMAND) { + EndDialog(AboutWindow, 0); + } else if (Message == WM_NOTIFY) { + LPNMHDR Notification = (LPNMHDR) LParam; + + if (Notification->idFrom == IDC_WEBSITELINK && Notification->code == NM_CLICK || Notification->code == NM_RETURN) { + ShellExecute(AboutWindow, L"open", L"https://github.com/vxiiduu/VxKex", NULL, NULL, SW_SHOWNORMAL); + } + } else { + return FALSE; + } + + return TRUE; +} \ No newline at end of file diff --git a/VxlView/listview.c b/VxlView/listview.c new file mode 100644 index 0000000..3a49708 --- /dev/null +++ b/VxlView/listview.c @@ -0,0 +1,270 @@ +#include "vxlview.h" +#include "resource.h" +#include "backendp.h" + +// +// This file contains functions for dealing with the list-view control in +// the main window. +// + +// +// If you change any of the column stuff, also make sure to change +// the LOGENTRYCOLUMNS enumeration in VxlView.h! +// +STATIC PWSTR ColumnNames[] = { + L"Severity", + L"Date/Time", + L"Component", + L"File", + L"Line", + L"Function", + L"Message" +}; + +STATIC CONST USHORT ColumnDefaultWidths[] = { + 90, 130, 80, 80, 40, 130, 500 +}; + +STATIC CONST USHORT SeverityIcons[] = { + 1027, // Critical + 98, // Error + 84, // Warning + 81, // Information + 177, // Detail + 15, // Debug +}; + +VOID InitializeListView( + VOID) +{ + ULONG Index; + LVCOLUMN ColumnInformation; + HIMAGELIST ImageList; + HMODULE ImageRes; + ULONG SmallIconWidth; + ULONG SmallIconHeight; + + UNCONST (HWND) ListViewWindow = GetDlgItem(MainWindow, IDC_LISTVIEW); + + // This is responsible for that nice looking blue (or whatever color + // you have configured) selection highlights. + SetWindowTheme(ListViewWindow, L"Explorer", NULL); + + ListView_SetExtendedListViewStyle( + ListViewWindow, + LVS_EX_FULLROWSELECT | // select full row instead of only part of the label + LVS_EX_HEADERDRAGDROP | // allow user to rearrange the columns to his liking + LVS_EX_LABELTIP | // allow user to see hidden text caused by narrow columns + LVS_EX_DOUBLEBUFFER); // eliminate flickering and artifacts + + // + // Insert each column into the list-view. + // + ColumnInformation.mask = LVCF_FMT | LVCF_ORDER | LVCF_TEXT | LVCF_WIDTH | LVCF_MINWIDTH; + for (Index = 0; Index <= ColumnMaxValue - 1; Index++) { + ColumnInformation.fmt = (Index == ColumnSourceLine) ? LVCFMT_RIGHT : LVCFMT_LEFT; + ColumnInformation.iOrder = Index; + ColumnInformation.pszText = ColumnNames[Index]; + ColumnInformation.cx = DpiScaleX(ColumnDefaultWidths[Index]); + ColumnInformation.cxMin = DpiScaleX(ColumnDefaultWidths[Index] / 2); + ListView_InsertColumn(ListViewWindow, Index, &ColumnInformation); + } + + // + // Create and associate the image list containing icons representing + // the various log-entry severity levels. + // + ImageRes = LoadLibraryEx(L"imageres.dll", NULL, LOAD_LIBRARY_AS_DATAFILE); + SmallIconWidth = GetSystemMetrics(SM_CXSMICON); + SmallIconHeight = GetSystemMetrics(SM_CYSMICON); + + ImageList = ImageList_Create( + SmallIconWidth, + SmallIconHeight, + ILC_MASK | ILC_COLOR32, + 1, 1); + + for (Index = 0; Index < LogSeverityMaximumValue; Index++) { + HICON Icon; + + Icon = (HICON) LoadImage( + ImageRes, + MAKEINTRESOURCE(SeverityIcons[Index]), + IMAGE_ICON, + SmallIconWidth, + SmallIconHeight, + 0); + + ImageList_AddIcon(ImageList, Icon); + } + + ListView_SetImageList(ListViewWindow, ImageList, LVSIL_SMALL); + FreeLibrary(ImageRes); +} + +VOID ResizeListView( + IN USHORT MainWindowWidth) +{ + RECT FilterWindowRect; + + // + // Put the bottom of the list view 10px above the top of the filter window. + // + + GetWindowRect(FilterWindow, &FilterWindowRect); + MapWindowRect(HWND_DESKTOP, MainWindow, &FilterWindowRect); + + SetWindowPos( + ListViewWindow, + NULL, + 0, 0, + MainWindowWidth, FilterWindowRect.top - DpiScaleY(10), + SWP_NOZORDER); + + // + // Make the log text column in the list-view take up all remaining space. + // + ListView_SetColumnWidth(ListViewWindow, ColumnText, LVSCW_AUTOSIZE_USEHEADER); +} + +VOID ResetListView( + VOID) +{ + // + // Make sure that the list view doesn't think there should be any entries + // in it. + // + ListView_SetItemCountEx(ListViewWindow, 0, LVSICF_NOINVALIDATEALL); +} + +// +// Called by MainWndProc when the list-view control wants data. +// +VOID PopulateListViewItem( + IN OUT LPLVITEM Item) +{ + PLOGENTRYCACHEENTRY CacheEntry; + + CacheEntry = GetLogEntry(Item->iItem); + if (!CacheEntry) { + return; + } + + switch (Item->iSubItem) { + case ColumnSeverity: + Item->iImage = CacheEntry->LogEntry.Severity; + Item->pszText = (PWSTR) VxlSeverityToText(CacheEntry->LogEntry.Severity, FALSE); + break; + case ColumnDateTime: + Item->pszText = CacheEntry->ShortDateTimeAsString; + break; + case ColumnSourceComponent: + Item->pszText = State->LogHandle->Header->SourceComponents[CacheEntry->LogEntry.SourceComponentIndex]; + break; + case ColumnSourceFile: + Item->pszText = State->LogHandle->Header->SourceFiles[CacheEntry->LogEntry.SourceFileIndex]; + break; + case ColumnSourceLine: + Item->pszText = CacheEntry->SourceLineAsString; + break; + case ColumnSourceFunction: + Item->pszText = State->LogHandle->Header->SourceFunctions[CacheEntry->LogEntry.SourceFunctionIndex]; + break; + case ColumnText: + Item->pszText = CacheEntry->LogEntry.TextHeader.Buffer; + break; + default: + ASSUME (FALSE); + } +} + +VOID HandleListViewContextMenu( + IN PPOINT ClickPoint) +{ + HWND ListViewHeaderWindow; + RECT ListViewHeaderWindowRect; + LVHITTESTINFO HitTestInfo; + ULONG EntryIndex; + + NTSTATUS Status; + HGLOBAL CopiedText; + UNICODE_STRING LogEntryText; + PWCHAR TextBuffer; + PLOGENTRYCACHEENTRY CacheEntry; + ULONG MenuSelection; + + ListViewHeaderWindow = ListView_GetHeader(ListViewWindow); + GetWindowRect(ListViewHeaderWindow, &ListViewHeaderWindowRect); + + if (PtInRect(&ListViewHeaderWindowRect, *ClickPoint)) { + // user right clicked on the column headers + return; + } + + HitTestInfo.pt = *ClickPoint; + ScreenToClient(ListViewWindow, &HitTestInfo.pt); + EntryIndex = ListView_HitTest(ListViewWindow, &HitTestInfo); + + if (EntryIndex == -1) { + // user right clicked on a blank space in the list view + return; + } + + MenuSelection = ContextMenu(ListViewWindow, IDM_LISTVIEWMENU, ClickPoint); + if (!MenuSelection) { + // context menu was cancelled without selecting a menu item + return; + } + + CacheEntry = GetLogEntry(EntryIndex); + if (!CacheEntry) { + return; + } + + Status = ConvertCacheEntryToText( + CacheEntry, + &LogEntryText, + MenuSelection == M_COPYLONG ? TRUE : FALSE); + + if (!NT_SUCCESS(Status)) { + return; + } + + CopiedText = GlobalAlloc(GMEM_MOVEABLE, LogEntryText.Length + sizeof(WCHAR)); + if (!CopiedText) { + return; + } + + TextBuffer = (PWCHAR) GlobalLock(CopiedText); + RtlCopyMemory(TextBuffer, LogEntryText.Buffer, LogEntryText.Length + sizeof(WCHAR)); + ASSERT (wcslen(TextBuffer) == LogEntryText.Length / sizeof(WCHAR)); + RtlFreeUnicodeString(&LogEntryText); + GlobalUnlock(CopiedText); + + if (!NT_SUCCESS(Status)) { + GlobalFree(CopiedText); + return; + } + + if (OpenClipboard(MainWindow)) { + EmptyClipboard(); + SetClipboardData(CF_UNICODETEXT, CopiedText); + CloseClipboard(); + SetWindowText(StatusBarWindow, L"Text copied to clipboard."); + } +} + +VOID SelectListViewItemByIndex( + IN ULONG Index) +{ + ListView_SetItemState( + ListViewWindow, + Index, + LVNI_SELECTED | LVNI_FOCUSED, + LVNI_SELECTED | LVNI_FOCUSED); + + ListView_EnsureVisible( + ListViewWindow, + Index, + FALSE); +} \ No newline at end of file diff --git a/VxlView/resource.h b/VxlView/resource.h new file mode 100644 index 0000000..4faab7a --- /dev/null +++ b/VxlView/resource.h @@ -0,0 +1,57 @@ +#define IDD_MAINWND 101 +#define IDC_LISTVIEW 102 +#define IDC_STATUSBAR 103 + +#define IDD_FILTERS 108 +#define IDC_GBFILTERSEVERITY 109 +#define IDC_CBFILTERCRITICAL 110 +#define IDC_CBFILTERERROR 111 +#define IDC_CBFILTERWARNING 112 +#define IDC_CBFILTERINFORMATION 113 +#define IDC_CBFILTERDETAIL 114 +#define IDC_CBFILTERDEBUG 115 + +#define IDC_GBFILTERTEXT 120 +#define IDC_SEARCHBOX 121 +#define IDC_CBCASESENSITIVE 122 +#define IDC_CBWILDCARD 123 +#define IDC_CBINVERTSEARCH 124 +#define IDC_CBEXACTMATCH 125 +#define IDC_CBSEARCHWHOLE 126 + +#define IDC_GBFILTERCOMPONENT 130 +#define IDC_COMPONENTLIST 131 + +#define IDD_DETAILS 150 +#define IDC_GBDETAILSBORDER 151 +#define IDC_DETAILSMESSAGETEXT 152 +#define IDC_DETAILSSEVERITYTEXT 153 +#define IDC_DETAILSDATETIMETEXT 154 +#define IDC_DETAILSSOURCETEXT 155 + +#define IDD_ABOUT 160 +#define IDC_WEBSITELINK 161 + +#define IDD_GOTORAW 170 + +#define IDM_MAINMENU 201 +#define M_OPEN 202 +#define M_EXPORT 203 +#define M_EXIT 204 +#define M_COLUMNS 211 +#define M_ABOUT 221 +#define M_FIND 230 +#define M_GOTORAW 231 + +#define IDM_COMPONENTLISTMENU 250 +#define M_SELECTALL 251 +#define M_SELECTNONE 252 + +#define IDM_LISTVIEWMENU 260 +#define M_COPY 261 +#define M_COPYLONG 262 + +#define IDA_ACCELERATORS 300 + +#define IDI_APPICON 501 +#define IDI_FILEICON 502 diff --git a/VxlView/statusbar.c b/VxlView/statusbar.c new file mode 100644 index 0000000..3690b4b --- /dev/null +++ b/VxlView/statusbar.c @@ -0,0 +1,16 @@ +#include "vxlview.h" +#include "resource.h" + +VOID ResizeStatusBar( + IN ULONG MainWindowNewWidth) +{ + INT StatusBarPartWidths[2]; + + // tell the status bar window to correctly size itself + SendMessage(StatusBarWindow, WM_SIZE, 0, 0); + + // resize statusbar parts + StatusBarPartWidths[0] = (MainWindowNewWidth * 70) / 100; // 70% + StatusBarPartWidths[1] = -1; + SendMessage(StatusBarWindow, SB_SETPARTS, ARRAYSIZE(StatusBarPartWidths), (LPARAM) StatusBarPartWidths); +} \ No newline at end of file diff --git a/VxlView/vxlfile.ico b/VxlView/vxlfile.ico new file mode 100644 index 0000000..45a777a Binary files /dev/null and b/VxlView/vxlfile.ico differ diff --git a/VxlView/vxlview.c b/VxlView/vxlview.c new file mode 100644 index 0000000..33f0762 --- /dev/null +++ b/VxlView/vxlview.c @@ -0,0 +1,210 @@ +#include "vxlview.h" +#include "resource.h" + +NTSTATUS NTAPI EntryPoint( + IN PVOID Parameter) +{ + HACCEL Accelerators; + MSG Message; + INITCOMMONCONTROLSEX InitComctl; + + InitComctl.dwSize = sizeof(InitComctl); + InitComctl.dwICC = ICC_BAR_CLASSES | ICC_LISTVIEW_CLASSES; + InitCommonControlsEx(&InitComctl); + + KexgApplicationFriendlyName = FRIENDLYAPPNAME; + + Accelerators = LoadAccelerators(NULL, MAKEINTRESOURCE(IDA_ACCELERATORS)); + CreateDialog(NULL, MAKEINTRESOURCE(IDD_MAINWND), NULL, MainWndProc); + + while (GetMessage(&Message, NULL, 0, 0)) { + if (TranslateAccelerator(MainWindow, Accelerators, &Message)) { + continue; + } + + if (!IsDialogMessage(MainWindow, &Message)) { + TranslateMessage(&Message); + DispatchMessage(&Message); + } + } + + LdrShutdownProcess(); + return NtTerminateProcess(NtCurrentProcess(), STATUS_SUCCESS); +} + +INT_PTR CALLBACK MainWndProc( + IN HWND _MainWindow, + IN UINT Message, + IN WPARAM WParam, + IN LPARAM LParam) +{ + if (Message == WM_INITDIALOG) { + BOOLEAN Success; + PWSTR CommandLine; + + UNCONST (HWND) MainWindow = _MainWindow; + UNCONST (HWND) StatusBarWindow = GetDlgItem(MainWindow, IDC_STATUSBAR); + + KexgApplicationMainWindow = MainWindow; + SetWindowIcon(MainWindow, IDI_APPICON); + + InitializeBackend(); + InitializeListView(); + InitializeFilterControls(); + InitializeDetailsWindow(); + + UpdateMainMenu(); + RestoreWindowPlacement(); + RestoreListViewColumns(); + + CommandLine = GetCommandLineWithoutImageName(); + if (CommandLine[0] == '\0') { + if (PROMPT_FOR_FILE_ON_STARTUP) { + Success = OpenLogFileWithPrompt(); + } else { + Success = TRUE; + } + } else { + if (CommandLine[0] == '"') { + PathUnquoteSpaces(CommandLine); + } + + Success = OpenLogFile(CommandLine); + } + + if (!Success) { + ExitProcess(0); + } + } else if (Message == WM_CLOSE) { + SaveListViewColumns(); + SaveWindowPlacement(); + CleanupBackend(); + ExitProcess(0); + } else if (Message == WM_SIZE && (WParam == SIZENORMAL || WParam == SIZEFULLSCREEN)) { + USHORT MainWndNewWidth = LOWORD(LParam); + + // DON'T change the order of the resize commands. They depend on each other. + ResizeStatusBar(MainWndNewWidth); + ResizeFilterControls(); + ResizeDetailsWindow(); + ResizeListView(MainWndNewWidth); + } else if (Message == WM_GETMINMAXINFO) { + PMINMAXINFO MinMaxInfo = (PMINMAXINFO) LParam; + + // Don't allow user to shrink the window too much. + MinMaxInfo->ptMinTrackSize.x = DpiScaleX(800); + MinMaxInfo->ptMinTrackSize.y = DpiScaleY(600); + } else if (Message == WM_SETCURSOR) { + HCURSOR Cursor; + + Cursor = (HCURSOR) GetClassLongPtr(MainWindow, GCLP_HCURSOR); + + // if the cursor is default, keep the default behavior - otherwise, + // override the cursor. (intended for busy cursor) + if (Cursor != LoadCursor(NULL, IDC_ARROW)) { + SetCursor((HCURSOR) GetClassLongPtr(MainWindow, GCLP_HCURSOR)); + SetWindowLongPtr(MainWindow, DWLP_MSGRESULT, TRUE); + } else { + return FALSE; + } + } else if (Message == WM_COMMAND) { + USHORT MessageSource; + HWND FocusedWindow; + WCHAR ClassName[32]; + + MessageSource = LOWORD(WParam); + + switch (MessageSource) { + case M_EXIT: + PostMessage(MainWindow, WM_CLOSE, 0, 0); + break; + case M_OPEN: + OpenLogFileWithPrompt(); + break; + case M_EXPORT: + ExportLogWithPrompt(); + break; + case M_FIND: + FocusedWindow = GetDlgItem(FilterWindow, IDC_SEARCHBOX); + Edit_SetSel(FocusedWindow, 0, INT_MAX); + SetFocus(FocusedWindow); + break; + case M_GOTORAW: + DialogBox(NULL, MAKEINTRESOURCE(IDD_GOTORAW), MainWindow, GotoRawDlgProc); + break; + case M_SELECTALL: + FocusedWindow = GetFocus(); + GetClassName(FocusedWindow, ClassName, ARRAYSIZE(ClassName)); + + if (StringEqual(ClassName, L"Edit")) { + Edit_SetSel(FocusedWindow, 0, INT_MAX); + } + + break; + case M_ABOUT: + DialogBox(NULL, MAKEINTRESOURCE(IDD_ABOUT), MainWindow, AboutWndProc); + break; + default: + return FALSE; + } + } else if (Message == WM_NOTIFY) { + LPNMHDR Notification; + + Notification = (LPNMHDR) LParam; + + if (Notification->idFrom == IDC_LISTVIEW) { + if (Notification->code == LVN_GETDISPINFO) { + LPLVITEM Item; + + Item = &((NMLVDISPINFO *) LParam)->item; + PopulateListViewItem(Item); + } else if (Notification->code == LVN_ITEMCHANGED) { + LPNMLISTVIEW ChangedItemInfo; + + ChangedItemInfo = (LPNMLISTVIEW) LParam; + if (ChangedItemInfo->uNewState & LVIS_FOCUSED) { + SetWindowTextF(StatusBarWindow, L"Entry #%d selected.", + GetLogEntryRawIndex(ChangedItemInfo->iItem) + 1); + PopulateDetailsWindow(ChangedItemInfo->iItem); + } + } else { + return FALSE; + } + } else { + return FALSE; + } + } else if (Message == WM_CONTEXTMENU) { + HWND Window; + POINT ClickPoint; + + Window = (HWND) WParam; + ClickPoint.x = GET_X_LPARAM(LParam); + ClickPoint.y = GET_Y_LPARAM(LParam); + + if (Window == ListViewWindow) { + HandleListViewContextMenu(&ClickPoint); + } + } else { + // message not handled + return FALSE; + } + + return TRUE; +} + +// +// Enable or disable menu items as necessary. +// +VOID UpdateMainMenu( + VOID) +{ + HMENU MainMenu; + + MainMenu = GetMenu(MainWindow); + + if (IsLogFileOpened()) { + EnableMenuItem(MainMenu, M_EXPORT, MF_ENABLED); + } else { + EnableMenuItem(MainMenu, M_EXPORT, MF_GRAYED); + } +} \ No newline at end of file diff --git a/VxlView/vxlview.h b/VxlView/vxlview.h new file mode 100644 index 0000000..b7cb279 --- /dev/null +++ b/VxlView/vxlview.h @@ -0,0 +1,160 @@ +#pragma once +#include "buildcfg.h" +#include +#include + +#define FRIENDLYAPPNAME L"Log Viewer" + +#define UNCONST(Type) *(Type*)& + +typedef enum { + ColumnSeverity, + ColumnDateTime, + ColumnSourceComponent, + ColumnSourceFile, + ColumnSourceLine, + ColumnSourceFunction, + ColumnText, + ColumnMaxValue +} LOGENTRYCOLUMNS; + +typedef struct { + VXLLOGENTRY LogEntry; + WCHAR SourceLineAsString[11]; + WCHAR ShortDateTimeAsString[32]; +} LOGENTRYCACHEENTRY, *PLOGENTRYCACHEENTRY, **PPLOGENTRYCACHEENTRY, *CONST PCLOGENTRYCACHEENTRY, **CONST PPCLOGENTRYCACHEENTRY; + +typedef struct { + UNICODE_STRING TextFilter; // same as what user typed in search box + BOOLEAN TextFilterCaseSensitive; + BOOLEAN TextFilterWildcardMatch; + BOOLEAN TextFilterInverted; + BOOLEAN TextFilterExact; + BOOLEAN TextFilterWhole; + BOOLEAN SeverityFilters[LogSeverityMaximumValue]; + BOOLEAN ComponentFilters[64]; +} BACKENDFILTERS, *PBACKENDFILTERS, **PPBACKENDFILTERS, *CONST PCBACKENDFILTERS, **CONST PPCBACKENDFILTERS; + +// backend.c + +VOID InitializeBackend( + VOID); +VOID CleanupBackend( + VOID); +BOOLEAN IsLogFileOpened( + VOID); +BOOLEAN OpenLogFile( + IN PCWSTR LogFileName); +BOOLEAN OpenLogFileWithPrompt( + VOID); +VOID ExportLog( + IN PCWSTR TextFileName); +BOOLEAN ExportLogWithPrompt( + VOID); +ULONG GetLogEntryRawIndex( + IN ULONG EntryIndex); +ULONG GetLogEntryIndexFromRawIndex( + IN ULONG RawIndex); +PLOGENTRYCACHEENTRY GetLogEntry( + IN ULONG EntryIndex); +VOID SetBackendFilters( + IN PBACKENDFILTERS Filters); +NTSTATUS ConvertCacheEntryToText( + IN PLOGENTRYCACHEENTRY CacheEntry, + OUT PUNICODE_STRING ExportedText, + IN BOOLEAN LongForm); + +// config.c + +VOID SaveWindowPlacement( + VOID); +VOID RestoreWindowPlacement( + VOID); +VOID SaveListViewColumns( + VOID); +VOID RestoreListViewColumns( + VOID); + +// details.c + +VOID InitializeDetailsWindow( + VOID); +VOID ResetDetailsWindow( + VOID); +VOID ResizeDetailsWindow( + VOID); +VOID PopulateDetailsWindow( + IN ULONG EntryIndex); +INT_PTR CALLBACK DetailsWndProc( + IN HWND _DetailsWindow, + IN UINT Message, + IN WPARAM WParam, + IN LPARAM LParam); + +// filters.c + +VOID InitializeFilterControls( + VOID); +VOID ResetFilterControls( + VOID); +VOID ResizeFilterControls( + VOID); +INT_PTR CALLBACK FilterWndProc( + IN HWND _FilterWindow, + IN UINT Message, + IN WPARAM WParam, + IN LPARAM LParam); + +// globals.c + +extern CONST HWND MainWindow; +extern CONST HWND ListViewWindow; +extern CONST HWND StatusBarWindow; +extern CONST HWND DetailsWindow; +extern CONST HWND FilterWindow; + +// goto.c + +INT_PTR CALLBACK GotoRawDlgProc( + IN HWND Window, + IN UINT Message, + IN WPARAM WParam, + IN LPARAM LParam); + +// helpabout.c + +INT_PTR CALLBACK AboutWndProc( + IN HWND AboutWindow, + IN UINT Message, + IN WPARAM WParam, + IN LPARAM LParam); + +// listview.c + +VOID InitializeListView( + VOID); +VOID ResizeListView( + IN USHORT MainWindowWidth); +VOID ResetListView( + VOID); +VOID PopulateListViewItem( + IN LPLVITEM Item); +VOID HandleListViewContextMenu( + IN PPOINT ClickPoint); +VOID SelectListViewItemByIndex( + IN ULONG Index); + +// statusbar.c + +VOID ResizeStatusBar( + IN ULONG MainWindowNewWidth); + +// vxlview.c + +INT_PTR CALLBACK MainWndProc( + IN HWND _MainWindow, + IN UINT Message, + IN WPARAM WParam, + IN LPARAM LParam); +VOID UpdateMainMenu( + VOID); \ No newline at end of file diff --git a/VxlView/vxlview.ico b/VxlView/vxlview.ico new file mode 100644 index 0000000..42e1e72 Binary files /dev/null and b/VxlView/vxlview.ico differ