From 208f6f7a9971527de419ed4b862181989176280c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E5=8F=8C=E5=B3=BB?= Date: Tue, 28 May 2024 10:55:34 +0800 Subject: [PATCH] =?UTF-8?q?Fea=20#85,=20QT6.5=E5=92=8Clibcef109=E5=9C=A8?= =?UTF-8?q?=E9=80=82=E9=85=8DXP=E6=97=B6=E4=B8=80=E4=BA=9B=E7=BC=BA?= =?UTF-8?q?=E5=A4=B1=E7=9A=84API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 7 +- ThunksList.md | 106 +- src/Build.cmd | 23 +- src/Thunks/UIAutomationCore.hpp | 76 + src/Thunks/YY_Thunks.cpp | 2 + src/Thunks/api-ms-win-core-processthreads.hpp | 1737 +++++++++-------- .../api-ms-win-core-windowserrorreporting.hpp | 51 + src/Thunks/api-ms-win-core-wow64.hpp | 297 +-- src/Thunks/dwmapi.hpp | 24 + src/Thunks/dxgi.hpp | 28 +- src/Thunks/esent.hpp | 379 ++++ src/Thunks/shell32.hpp | 81 +- src/Thunks/wevtapi.hpp | 140 ++ .../YY-Thunks.UnitTest.vcxproj | 5 + .../YY-Thunks.UnitTest.vcxproj.filters | 24 + src/def/x64/esent.def | 74 + src/def/x86/esent.def | 74 + 17 files changed, 2119 insertions(+), 1009 deletions(-) create mode 100644 src/Thunks/api-ms-win-core-windowserrorreporting.hpp create mode 100644 src/Thunks/esent.hpp create mode 100644 src/Thunks/wevtapi.hpp create mode 100644 src/def/x64/esent.def create mode 100644 src/def/x86/esent.def diff --git a/.gitignore b/.gitignore index db4abc0..b1b0416 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -## Ignore Visual Studio temporary files, build results, and +## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. ## ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore @@ -21,8 +21,8 @@ mono_crash.* [Dd]ebugPublic/ [Rr]elease/ [Rr]eleases/ -x64/ -x86/ +# x64/ +# x86/ [Aa][Rr][Mm]/ [Aa][Rr][Mm]64/ bld/ @@ -353,3 +353,4 @@ MigrationBackup/ /src/Windows2000 /src/Thunks/Thunks /src/Thunks/YY_Thunks_List.hpp +/objs diff --git a/ThunksList.md b/ThunksList.md index 9d23f43..c9dc11e 100644 --- a/ThunksList.md +++ b/ThunksList.md @@ -193,6 +193,7 @@ | DwmGetWindowAttribute | 不存在时,返回 `DWM_E_COMPOSITIONDISABLED`(表示DWM已禁用)。 | DwmSetWindowAttribute | 不存在时,返回 `DWM_E_COMPOSITIONDISABLED`(表示DWM已禁用)。 | DwmFlush | 不存在时,返回 `S_OK_`。 +| DwmGetCompositionTimingInfo | 不存在时,返回 `DWM_E_COMPOSITIONDISABLED`(表示DWM已禁用)。 ## dwrite.dll | 函数 | Fallback @@ -202,13 +203,98 @@ ## dxgi.dll | 函数 | Fallback | ---- | ----------- -| CreateDXGIFactory1 | 不存在时,返回 `E_NOINTERFACE`。 +| CreateDXGIFactory1 | 不存在时,返回 `DXGI_ERROR_UNSUPPORTED`。 +| CreateDXGIFactory | 不存在时,返回 `DXGI_ERROR_UNSUPPORTED`。 ## dxva2.dll | 函数 | Fallback | ---- | ----------- | DXVA2CreateVideoService | 不存在时,返回 `E_NOINTERFACE`。 +## esent.dll +| 函数 | Fallback +| ---- | ----------- +| JetAddColumnA | 调用JetAddColumn。 +| JetAddColumnA | 调用JetAddColumn。 +| JetAttachDatabaseA | 调用JetAttachDatabase。 +| JetAttachDatabase2A | 调用JetAttachDatabase2。 +| JetAttachDatabaseWithStreamingA | 调用JetAttachDatabaseWithStreaming。 +| JetBackupA | 调用JetBackup。 +| JetBackupInstanceA | 调用JetBackupInstance。 +| JetBeginDatabaseIncrementalReseedA | 调用JetBeginDatabaseIncrementalReseed。 +| JetBeginSessionA | 调用JetBeginSession。 +| JetCompactA | 调用JetCompact。 +| JetConvertDDLA | 调用JetConvertDDL。 +| JetCreateDatabaseA | 调用JetCreateDatabase。 +| JetCreateDatabase2A | 调用JetCreateDatabase2。 +| JetCreateDatabaseWithStreamingA | 调用JetCreateDatabaseWithStreaming。 +| JetCreateIndexA | 调用JetCreateIndex。 +| JetCreateIndex2A | 调用JetCreateIndex2。 +| JetCreateInstanceA | 调用JetCreateInstance。 +| JetCreateInstance2A | 调用JetCreateInstance2。 +| JetCreateTableA | 调用JetCreateTable。 +| JetCreateTableColumnIndexA | 调用JetCreateTableColumnIndex。 +| JetCreateTableColumnIndex2A | 调用JetCreateTableColumnIndex2。 +| JetDBUtilitiesA | 调用JetDBUtilities。 +| JetDefragmentA | 调用JetDefragment。 +| JetDefragment2A | 调用JetDefragment2。 +| JetDeleteColumnA | 调用JetDeleteColumn。 +| JetDeleteColumn2A | 调用JetDeleteColumn2。 +| JetDeleteIndexA | 调用JetDeleteIndex。 +| JetDeleteTableA | 调用JetDeleteTable。 +| JetDetachDatabaseA | 调用JetDetachDatabase。 +| JetDetachDatabase2A | 调用JetDetachDatabase2。 +| JetEnableMultiInstanceA | 调用JetEnableMultiInstance。 +| JetExternalRestoreA | 调用JetExternalRestore。 +| JetExternalRestore2A | 调用JetExternalRestore2。 +| JetGetAttachInfoA | 调用JetGetAttachInfo。 +| JetGetAttachInfoInstanceA | 调用JetGetAttachInfoInstance。 +| JetGetColumnInfoA | 调用JetGetColumnInfo。 +| JetGetCurrentIndexA | 调用JetGetCurrentIndex。 +| JetGetDatabaseFileInfoA | 调用JetGetDatabaseFileInfo。 +| JetGetDatabaseInfoA | 调用JetGetDatabaseInfo。 +| JetGetIndexInfoA | 调用JetGetIndexInfo。 +| JetGetInstanceInfoA | 调用JetGetInstanceInfo。 +| JetGetLogInfoA | 调用JetGetLogInfo。 +| JetGetLogInfoInstanceA | 调用JetGetLogInfoInstance。 +| JetGetLogInfoInstance2A | 调用JetGetLogInfoInstance2。 +| JetGetObjectInfoA | 调用JetGetObjectInfo。 +| JetGetSystemParameterA | 调用JetGetSystemParameter。 +| JetGetTableColumnInfoA | 调用JetGetTableColumnInfo。 +| JetGetTableIndexInfoA | 调用JetGetTableIndexInfo。 +| JetGetTableInfoA | 调用JetGetTableInfo。 +| JetGetTruncateLogInfoInstanceA | 调用JetGetTruncateLogInfoInstance。 +| JetInit3A | 调用JetInit3。 +| JetInit4A | 调用JetInit4。 +| JetOpenDatabaseA | 调用JetOpenDatabase。 +| JetOpenFileA | 调用JetOpenFile。 +| JetOpenFileInstanceA | 调用JetOpenFileInstance。 +| JetOpenFileSectionInstanceA | 调用JetOpenFileSectionInstance。 +| JetOpenTableA | 调用JetOpenTable。 +| JetOSSnapshotFreezeA | 调用JetOSSnapshotFreeze。 +| JetRenameColumnA | 调用JetRenameColumn。 +| JetRenameTableA | 调用JetRenameTable。 +| JetRestoreA | 调用JetRestore。 +| JetRestore2A | 调用JetRestore2。 +| JetRestoreInstanceA | 调用JetRestoreInstance。 +| JetSetColumnDefaultValueA | 调用JetSetColumnDefaultValue。 +| JetSetCurrentIndexA | 调用JetSetCurrentIndex。 +| JetSetCurrentIndex2A | 调用JetSetCurrentIndex2。 +| JetSetCurrentIndex3A | 调用JetSetCurrentIndex3。 +| JetSetCurrentIndex4A | 调用JetSetCurrentIndex4。 +| JetSetDatabaseSizeA | 调用JetSetDatabaseSize。 +| JetSetSystemParameterA | 调用JetSetSystemParameter。 +| JetSnapshotStartA | 调用JetSnapshotStart。 +| JetUpgradeDatabaseA | 调用JetUpgradeDatabase。 +| JetAttachDatabase2W | 不存在时,调用JetAttachDatabase2A。 +| JetBeginSessionW | 不存在时,调用JetBeginSessionA。 +| JetCreateInstanceW | 不存在时,调用JetCreateInstanceA。 +| JetGetTableColumnInfoW | 不存在时,调用JetGetTableColumnInfoA。 +| JetOpenDatabaseW | 不存在时,调用JetOpenDatabaseA。 +| JetOpenTableW | 不存在时,调用JetOpenTableA。 +| JetSetSystemParameterW | 不存在时,调用JetSetSystemParameterA。 +| JetGetSystemParameterW | 不存在时,调用JetGetSystemParameterA。 + ## iphlpapi.dll | 函数 | Fallback | ---- | ----------- @@ -427,6 +513,10 @@ | SetProcessDEPPolicy | 不存在时,调用NtSetInformationProcess。 | GetSystemDEPPolicy | 不存在时,返回总是关闭。 | DisableThreadLibraryCalls | 不存在时,始终返回成功。 +| CreateRemoteThreadEx | 不存在时,调用CreateRemoteThread。 +| WerRegisterRuntimeExceptionModule | 不存在时,返回S_OK。 +| WerUnregisterRuntimeExceptionModule | 不存在时,返回S_OK。 +| Wow64GetThreadContext | 不存在时,返回ERROR_INVALID_PARAMETER。 ## mfplat.dll | 函数 | Fallback @@ -506,6 +596,8 @@ | SHCreateItemFromParsingName | 不存在时,调用SHParseDisplayName。 | Shell_NotifyIconGetRect | 不存在时,调用SendMessageW(可能不适用于Vista系统)。 | SHGetStockIconInfo | 不存在时,调用LoadImageW。 +| SHGetPropertyStoreForWindow | 不存在时,报告错误 E_NOTIMPL。 +| SHOpenWithDialog | 不存在时,报告错误 E_NOTIMPL。 ## shlwapi.dll | 函数 | Fallback @@ -520,6 +612,9 @@ | UiaRaiseAutomationEvent | 存在时,报告错误 E_NOTIMPL。 | UiaRaiseAutomationPropertyChangedEvent | 存在时,报告错误 E_NOTIMPL。 | UiaReturnRawElementProvider | 存在时,报告错误 E_NOTIMPL。 +| UiaGetReservedMixedAttributeValue | 存在时,报告错误 E_NOTIMPL。 +| UiaGetReservedNotSupportedValue | 存在时,报告错误 E_NOTIMPL。 +| UiaRaiseStructureChangedEvent | 存在时,报告错误 E_NOTIMPL。 ## user32.dll | 函数 | Fallback @@ -575,6 +670,15 @@ | GetFileVersionInfoExW(A) | 不存在时,调用GetFileVersionInfoW(A)。 | GetFileVersionInfoSizeExW(A) | 不存在时,调用GetFileVersionInfoSizeW(A)。 +## wevtapi.dll +| 函数 | Fallback +| ---- | ----------- +| EvtClose | 不存在时,返回TRUE。 +| EvtCreateRenderContext | 不存在时,报告ERROR_NOT_SUPPORTED。 +| EvtNext | 不存在时,报告ERROR_NOT_SUPPORTED。 +| EvtQuery | 不存在时,报告ERROR_NOT_SUPPORTED。 +| EvtRender | 不存在时,报告ERROR_NOT_SUPPORTED。 + ## WinHttp.dll | 函数 | Fallback | ---- | ----------- diff --git a/src/Build.cmd b/src/Build.cmd index 724119f..e7e81ad 100644 --- a/src/Build.cmd +++ b/src/Build.cmd @@ -22,31 +22,36 @@ popd goto:eof -:: BuildObj YY_Thunks_for_Vista.obj NTDDI_WIN6 +:: BuildObj YY_Thunks_for_Vista.obj NTDDI_WIN6 1.def+2.def :BuildObj cl /O1 /Os /Oi /GS- /std:c++17 /arch:IA32 /Z7 /MT /Fo"objs\\%Platform%\\%1" /Zl /c /D "NDEBUG" /D "YY_Thunks_Support_Version=%2" "%~dp0Thunks\YY_Thunks.cpp" -::кƽ __imp__%s_%u -> __imp__%s@%u +::weakţһЩDZŰΪweakԱʧ LibMaker.exe FixObj "%~dp0..\\objs\\%Platform%\\%1" /WeakExternFix:__security_cookie=%PointType% /WeakExternFix:__YY_Thunks_Process_Terminating=4 /WeakExternFix:__acrt_atexit_table=%PointType% /WeakExternFix:__pfnDllMainCRTStartupForYY_Thunks=%PointType% +if "%3"=="" goto:eof +set DEF_FILES=%3 +:AppendWeak +for /f "tokens=1* delims=+" %%a in ("%DEF_FILES%") do ( + echo "AppendWeak %~dp0def\\%Platform%\\%%a" + LibMaker.exe AppendWeak /MACHINE:%Platform% /DEF:"%~dp0def\\%Platform%\\%%a" /OUT:"%~dp0..\\objs\\%Platform%\\%1" + set DEF_FILES=%%b +) -LibMaker.exe AppendWeak /MACHINE:%Platform% /DEF:"%~dp0def\\%Platform%\\PSAPI2Kernel32.def" /OUT:"%~dp0..\\objs\\%Platform%\\%1" - +if defined DEF_FILES goto :AppendWeak goto:eof :Buildx86 set PointType=4 -call:BuildObj YY_Thunks_for_Win2K.obj NTDDI_WIN2K -call:BuildObj YY_Thunks_for_WinXP.obj NTDDI_WINXP +call:BuildObj YY_Thunks_for_Win2K.obj NTDDI_WIN2K PSAPI2Kernel32.def+esent.def +call:BuildObj YY_Thunks_for_WinXP.obj NTDDI_WINXP PSAPI2Kernel32.def+esent.def call:BuildObj YY_Thunks_for_Vista.obj NTDDI_WIN6 - - goto:eof :Buildx64 set PointType=8 -call:BuildObj YY_Thunks_for_WinXP.obj NTDDI_WS03SP1 +call:BuildObj YY_Thunks_for_WinXP.obj NTDDI_WS03SP1 PSAPI2Kernel32.def+esent.def call:BuildObj YY_Thunks_for_Vista.obj NTDDI_WIN6 goto:eof diff --git a/src/Thunks/UIAutomationCore.hpp b/src/Thunks/UIAutomationCore.hpp index fc4e8b3..c3d9e63 100644 --- a/src/Thunks/UIAutomationCore.hpp +++ b/src/Thunks/UIAutomationCore.hpp @@ -125,4 +125,80 @@ namespace YY::Thunks return E_NOTIMPL; } #endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + // 最低受支持的客户端 Windows XP [桌面应用 | UWP 应用](需要安装 .NET) + // 最低受支持的服务器 Windows Server 2003[桌面应用 | UWP 应用] + __DEFINE_THUNK( + uiautomationcore, + 4, + HRESULT, + WINAPI, + UiaGetReservedMixedAttributeValue, + _Outptr_ IUnknown** punkMixedAttributeValue + ) + { + if (auto const _pfnUiaGetReservedMixedAttributeValue = try_get_UiaGetReservedMixedAttributeValue()) + { + return _pfnUiaGetReservedMixedAttributeValue(punkMixedAttributeValue); + } + + if (punkMixedAttributeValue) + *punkMixedAttributeValue = nullptr; + + return E_NOTIMPL; + } +#endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + // 最低受支持的客户端 Windows XP [桌面应用 | UWP 应用](需要安装 .NET) + // 最低受支持的服务器 Windows Server 2003[桌面应用 | UWP 应用] + __DEFINE_THUNK( + uiautomationcore, + 4, + HRESULT, + WINAPI, + UiaGetReservedNotSupportedValue, + _Outptr_ IUnknown** punkNotSupportedValue + ) + { + if (auto const _pfnUiaGetReservedNotSupportedValue = try_get_UiaGetReservedNotSupportedValue()) + { + return _pfnUiaGetReservedNotSupportedValue(punkNotSupportedValue); + } + if (punkNotSupportedValue) + *punkNotSupportedValue = nullptr; + return E_NOTIMPL; + } +#endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + // 最低受支持的客户端 Windows XP [桌面应用 | UWP 应用](需要安装 .NET) + // 最低受支持的服务器 Windows Server 2003[桌面应用 | UWP 应用] + __DEFINE_THUNK( + uiautomationcore, + 16, + HRESULT, + WINAPI, + UiaRaiseStructureChangedEvent, + IRawElementProviderSimple* pProvider, + enum StructureChangeType structureChangeType, + int* pRuntimeId, + int cRuntimeIdLen + ) + { + if (auto const _pfnUiaRaiseStructureChangedEvent = try_get_UiaRaiseStructureChangedEvent()) + { + return _pfnUiaRaiseStructureChangedEvent(pProvider, structureChangeType, pRuntimeId, cRuntimeIdLen); + } + + return E_NOTIMPL; + } +#endif } diff --git a/src/Thunks/YY_Thunks.cpp b/src/Thunks/YY_Thunks.cpp index 8618d6c..ee64273 100644 --- a/src/Thunks/YY_Thunks.cpp +++ b/src/Thunks/YY_Thunks.cpp @@ -13,6 +13,7 @@ _APPLY(dxgi, "dxgi" , 0 ) \ _APPLY(dwrite, "dwrite" , 0 ) \ _APPLY(dxva2, "dxva2" , 0 ) \ + _APPLY(esent, "esent" , 0 ) \ _APPLY(uxtheme, "uxtheme" , 0 ) \ _APPLY(uiautomationcore, "uiautomationcore" , 0 ) \ _APPLY(psapi, "psapi" , 0 ) \ @@ -34,6 +35,7 @@ _APPLY(bluetoothapis, "bluetoothapis" , 0 ) \ _APPLY(netapi32, "netapi32" , 0 ) \ _APPLY(powrprof, "powrprof" , 0 ) \ + _APPLY(wevtapi, "wevtapi" , 0 ) \ _APPLY(winhttp, "winhttp" , 0 ) \ _APPLY(zipfldr, "zipfldr" , LOAD_AS_DATA_FILE ) \ _APPLY(api_ms_win_core_realtime_l1_1_1, "api-ms-win-core-realtime-l1-1-1" , 0 ) \ diff --git a/src/Thunks/api-ms-win-core-processthreads.hpp b/src/Thunks/api-ms-win-core-processthreads.hpp index ee7f231..c895b89 100644 --- a/src/Thunks/api-ms-win-core-processthreads.hpp +++ b/src/Thunks/api-ms-win-core-processthreads.hpp @@ -28,881 +28,788 @@ typedef struct _PROC_THREAD_ATTRIBUTE_LIST #endif -namespace YY +namespace YY::Thunks::Fallback { - namespace Thunks - { #if defined(YY_Thunks_Implemented) && (YY_Thunks_Support_Version < NTDDI_WIN6) - namespace Fallback - { - static void __cdecl UninitPageVirtualProtect(); + namespace + { + static void __cdecl UninitPageVirtualProtect(); - static char* volatile *GetPageVirtualProtect() - { - //注册 m_pPageVirtualProtect 的反初始化工作 - __declspec(allocate(".YYThr$AAB")) static void* RunUninitPageVirtualProtect = reinterpret_cast(&Fallback::UninitPageVirtualProtect); + static char* volatile* GetPageVirtualProtect() + { + //注册 m_pPageVirtualProtect 的反初始化工作 + __declspec(allocate(".YYThr$AAB")) static void* RunUninitPageVirtualProtect = reinterpret_cast(&Fallback::UninitPageVirtualProtect); - __foreinclude(RunUninitPageVirtualProtect); + __foreinclude(RunUninitPageVirtualProtect); - static char* volatile m_pPageVirtualProtect = nullptr; + static char* volatile m_pPageVirtualProtect = nullptr; - return &m_pPageVirtualProtect; - } + return &m_pPageVirtualProtect; + } - static void __cdecl UninitPageVirtualProtect() - { - auto pOrgPageVirtualProtect = (char*)InterlockedExchangePointer((PVOID volatile*)GetPageVirtualProtect(), INVALID_HANDLE_VALUE); + static void __cdecl UninitPageVirtualProtect() + { + auto pOrgPageVirtualProtect = (char*)InterlockedExchangePointer((PVOID volatile*)GetPageVirtualProtect(), INVALID_HANDLE_VALUE); - if (pOrgPageVirtualProtect != nullptr && pOrgPageVirtualProtect != (char*)INVALID_HANDLE_VALUE) - { - VirtualFree(pOrgPageVirtualProtect, 0, MEM_RELEASE); - } - } - } - + if (pOrgPageVirtualProtect != nullptr && pOrgPageVirtualProtect != (char*)INVALID_HANDLE_VALUE) + { + VirtualFree(pOrgPageVirtualProtect, 0, MEM_RELEASE); + } + } + } #endif +} - +namespace YY ::Thunks +{ #if (YY_Thunks_Support_Version < NTDDI_WS03) - //Windows Vista, Windows Server 2003 - __DEFINE_THUNK( - kernel32, - 0, - DWORD, - WINAPI, - GetCurrentProcessorNumber, - VOID - ) + //Windows Vista, Windows Server 2003 + __DEFINE_THUNK( + kernel32, + 0, + DWORD, + WINAPI, + GetCurrentProcessorNumber, + VOID + ) + { + if (const auto _pfnGetCurrentProcessorNumber = try_get_GetCurrentProcessorNumber()) { - if (const auto _pfnGetCurrentProcessorNumber = try_get_GetCurrentProcessorNumber()) - { - return _pfnGetCurrentProcessorNumber(); - } - else - { - // Reference: https://www.cs.tcd.ie/Jeremy.Jones/GetCurrentProcessorNumberXP.htm - // - // The GetCurrentProcessorNumber() function is not available in XP. - // Here is a VC++ version of the function that works with Windows XP on Intel x86 single, hyperthreaded, multicore - // and multi-socket systems. It makes use of the APIC ID returned by the CPUID instruction. - // This is in the range 0 .. N-1, where N is the number of logical CPUs. - - __asm - { - mov eax, 1 - cpuid - shr ebx, 24 - // eax 返回值 - mov eax, ebx - } - } + return _pfnGetCurrentProcessorNumber(); } + else + { + // Reference: https://www.cs.tcd.ie/Jeremy.Jones/GetCurrentProcessorNumberXP.htm + // + // The GetCurrentProcessorNumber() function is not available in XP. + // Here is a VC++ version of the function that works with Windows XP on Intel x86 single, hyperthreaded, multicore + // and multi-socket systems. It makes use of the APIC ID returned by the CPUID instruction. + // This is in the range 0 .. N-1, where N is the number of logical CPUs. + + __asm + { + mov eax, 1 + cpuid + shr ebx, 24 + // eax 返回值 + mov eax, ebx + } + } + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN7) - //Windows 7, Windows Server 2008 R2 - __DEFINE_THUNK( - kernel32, - 4, - VOID, - WINAPI, - GetCurrentProcessorNumberEx, - _Out_ PPROCESSOR_NUMBER ProcNumber - ) + //Windows 7, Windows Server 2008 R2 + __DEFINE_THUNK( + kernel32, + 4, + VOID, + WINAPI, + GetCurrentProcessorNumberEx, + _Out_ PPROCESSOR_NUMBER ProcNumber + ) + { + if (auto pGetCurrentProcessorNumberEx = try_get_GetCurrentProcessorNumberEx()) { - if (auto pGetCurrentProcessorNumberEx = try_get_GetCurrentProcessorNumberEx()) - { - pGetCurrentProcessorNumberEx(ProcNumber); - } - else - { - //不支持GetCurrentProcessorNumberEx时假定用户只有一组CPU - ProcNumber->Group = 0; - ProcNumber->Number = static_cast(GetCurrentProcessorNumber()); - ProcNumber->Reserved = 0; - } + pGetCurrentProcessorNumberEx(ProcNumber); + } + else + { + //不支持GetCurrentProcessorNumberEx时假定用户只有一组CPU + ProcNumber->Group = 0; + ProcNumber->Number = static_cast(GetCurrentProcessorNumber()); + ProcNumber->Reserved = 0; } + } #endif #if (YY_Thunks_Support_Version < NTDDI_WS03) - //Windows Vista [desktop apps | UWP apps] - //Windows Server 2003 [desktop apps | UWP apps] - //感谢 过客 提供 - __DEFINE_THUNK( - kernel32, - 4, - DWORD, - WINAPI, - GetThreadId, - _In_ HANDLE Thread - ) + //Windows Vista [desktop apps | UWP apps] + //Windows Server 2003 [desktop apps | UWP apps] + //感谢 过客 提供 + __DEFINE_THUNK( + kernel32, + 4, + DWORD, + WINAPI, + GetThreadId, + _In_ HANDLE Thread + ) + { + if (auto pGetThreadId = try_get_GetThreadId()) { - if (auto pGetThreadId = try_get_GetThreadId()) - { - return pGetThreadId(Thread); - } - else if (auto pNtQueryInformationThread = try_get_NtQueryInformationThread()) - { - THREAD_BASIC_INFORMATION ThreadBasicInfo; + return pGetThreadId(Thread); + } + else if (auto pNtQueryInformationThread = try_get_NtQueryInformationThread()) + { + THREAD_BASIC_INFORMATION ThreadBasicInfo; - auto Status = pNtQueryInformationThread(Thread, ThreadBasicInformation, &ThreadBasicInfo, sizeof(ThreadBasicInfo), nullptr); + auto Status = pNtQueryInformationThread(Thread, ThreadBasicInformation, &ThreadBasicInfo, sizeof(ThreadBasicInfo), nullptr); - if (Status < 0) - { - internal::BaseSetLastNTError(Status); - return 0; - } - else - { - return (DWORD)ThreadBasicInfo.ClientId.UniqueThread; - } + if (Status < 0) + { + internal::BaseSetLastNTError(Status); + return 0; } else { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + return (DWORD)ThreadBasicInfo.ClientId.UniqueThread; } } + else + { + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; + } + } #endif #if (YY_Thunks_Support_Version < NTDDI_WS03) - //Windows Vista [desktop apps | UWP apps] - //Windows Server 2003 [desktop apps | UWP apps] - __DEFINE_THUNK( - kernel32, - 4, - DWORD, - WINAPI, - GetProcessIdOfThread, - _In_ HANDLE Thread - ) + //Windows Vista [desktop apps | UWP apps] + //Windows Server 2003 [desktop apps | UWP apps] + __DEFINE_THUNK( + kernel32, + 4, + DWORD, + WINAPI, + GetProcessIdOfThread, + _In_ HANDLE Thread + ) + { + if (auto pGetProcessIdOfThread = try_get_GetProcessIdOfThread()) { - if (auto pGetProcessIdOfThread = try_get_GetProcessIdOfThread()) - { - return pGetProcessIdOfThread(Thread); - } - else if (auto pNtQueryInformationThread = try_get_NtQueryInformationThread()) - { - THREAD_BASIC_INFORMATION ThreadBasicInfo; + return pGetProcessIdOfThread(Thread); + } + else if (auto pNtQueryInformationThread = try_get_NtQueryInformationThread()) + { + THREAD_BASIC_INFORMATION ThreadBasicInfo; - auto Status = pNtQueryInformationThread(Thread, ThreadBasicInformation, &ThreadBasicInfo, sizeof(ThreadBasicInfo), nullptr); + auto Status = pNtQueryInformationThread(Thread, ThreadBasicInformation, &ThreadBasicInfo, sizeof(ThreadBasicInfo), nullptr); - if (Status < 0) - { - internal::BaseSetLastNTError(Status); - return 0; - } - else - { - return (DWORD)ThreadBasicInfo.ClientId.UniqueProcess; - } + if (Status < 0) + { + internal::BaseSetLastNTError(Status); + return 0; } else { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + return (DWORD)ThreadBasicInfo.ClientId.UniqueProcess; } } + else + { + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; + } + } #endif #if (YY_Thunks_Support_Version < NTDDI_WINXPSP1) - //Windows Vista, Windows XP with SP1 [desktop apps | UWP apps] - //Windows Server 2003 [desktop apps | UWP apps] - __DEFINE_THUNK( - kernel32, - 4, - DWORD, - WINAPI, - GetProcessId, - _In_ HANDLE Process - ) + //Windows Vista, Windows XP with SP1 [desktop apps | UWP apps] + //Windows Server 2003 [desktop apps | UWP apps] + __DEFINE_THUNK( + kernel32, + 4, + DWORD, + WINAPI, + GetProcessId, + _In_ HANDLE Process + ) + { + if (auto pGetProcessId = try_get_GetProcessId()) { - if (auto pGetProcessId = try_get_GetProcessId()) - { - return pGetProcessId(Process); - } - else if (auto pNtQueryInformationProcess = try_get_NtQueryInformationProcess()) - { - PROCESS_BASIC_INFORMATION ProcessBasicInfo; + return pGetProcessId(Process); + } + else if (auto pNtQueryInformationProcess = try_get_NtQueryInformationProcess()) + { + PROCESS_BASIC_INFORMATION ProcessBasicInfo; - auto Status = pNtQueryInformationProcess(Process, ProcessBasicInformation, &ProcessBasicInfo, sizeof(ProcessBasicInfo), nullptr); + auto Status = pNtQueryInformationProcess(Process, ProcessBasicInformation, &ProcessBasicInfo, sizeof(ProcessBasicInfo), nullptr); - if (Status < 0) - { - internal::BaseSetLastNTError(Status); - return 0; - } - else - { - return (DWORD)ProcessBasicInfo.UniqueProcessId; - } + if (Status < 0) + { + internal::BaseSetLastNTError(Status); + return 0; } else { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + return (DWORD)ProcessBasicInfo.UniqueProcessId; } } + else + { + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; + } + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN6) - //Minimum supported client Windows Vista [desktop apps | UWP apps] - //Minimum supported server Windows Server 2008 [desktop apps | UWP apps] - __DEFINE_THUNK( - kernel32, - 0, - VOID, - WINAPI, - FlushProcessWriteBuffers, - VOID - ) + //Minimum supported client Windows Vista [desktop apps | UWP apps] + //Minimum supported server Windows Server 2008 [desktop apps | UWP apps] + __DEFINE_THUNK( + kernel32, + 0, + VOID, + WINAPI, + FlushProcessWriteBuffers, + VOID + ) + { + if (auto pFlushProcessWriteBuffers = try_get_FlushProcessWriteBuffers()) { - if (auto pFlushProcessWriteBuffers = try_get_FlushProcessWriteBuffers()) - { - return pFlushProcessWriteBuffers(); - } + return pFlushProcessWriteBuffers(); + } - /* - * 参考了 14.29.30037 crt\src\concrt\ResourceManager.cpp 实现 + /* + * 参考了 14.29.30037 crt\src\concrt\ResourceManager.cpp 实现 - */ + */ - for (;;) + for (;;) + { + auto pOrgPageVirtualProtect = (char*)InterlockedCompareExchangePointer((PVOID volatile*)Fallback::GetPageVirtualProtect(), nullptr, nullptr); + + + //内存存在异常,我们什么也不做。 + if (pOrgPageVirtualProtect == (char*)INVALID_HANDLE_VALUE) { - auto pOrgPageVirtualProtect = (char*)InterlockedCompareExchangePointer((PVOID volatile*)Fallback::GetPageVirtualProtect(), nullptr, nullptr); + break; + } + else if (pOrgPageVirtualProtect == nullptr) + { + //我们需要开辟一段内存 + auto pPageVirtualProtectTmp = (char*)VirtualAlloc(NULL, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); - //内存存在异常,我们什么也不做。 - if (pOrgPageVirtualProtect == (char*)INVALID_HANDLE_VALUE) + if (pPageVirtualProtectTmp == nullptr) { + //内存申请失败,直接设置为 -1,并且什么也不做 + InterlockedCompareExchangePointer((PVOID volatile*)Fallback::GetPageVirtualProtect(), INVALID_HANDLE_VALUE, nullptr); break; } - else if (pOrgPageVirtualProtect == nullptr) - { - //我们需要开辟一段内存 - - auto pPageVirtualProtectTmp = (char*)VirtualAlloc(NULL, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); - - if (pPageVirtualProtectTmp == nullptr) - { - //内存申请失败,直接设置为 -1,并且什么也不做 - InterlockedCompareExchangePointer((PVOID volatile*)Fallback::GetPageVirtualProtect(), INVALID_HANDLE_VALUE, nullptr); - break; - } - - *pPageVirtualProtectTmp = 1; - - pOrgPageVirtualProtect = (char*)InterlockedCompareExchangePointer((PVOID volatile*)Fallback::GetPageVirtualProtect(), pPageVirtualProtectTmp, nullptr); - - if (pOrgPageVirtualProtect != nullptr) - { - //说明另外一个线程已经设置,我们释放这次申请的内存 - VirtualFree(pPageVirtualProtectTmp, 0, MEM_RELEASE); - } - else - { - pOrgPageVirtualProtect = pPageVirtualProtectTmp; - } - } + *pPageVirtualProtectTmp = 1; + + pOrgPageVirtualProtect = (char*)InterlockedCompareExchangePointer((PVOID volatile*)Fallback::GetPageVirtualProtect(), pPageVirtualProtectTmp, nullptr); - // Note that the read of *m_pPageVirtualProtect is very important, as it makes it extremely likely that this memory will - // be in the working set when we call VirtualProtect (see comments below). - if (*pOrgPageVirtualProtect == 1) + if (pOrgPageVirtualProtect != nullptr) + { + //说明另外一个线程已经设置,我们释放这次申请的内存 + VirtualFree(pPageVirtualProtectTmp, 0, MEM_RELEASE); + } + else { - // - // VirtualProtect simulates FlushProcessWriteBuffers because it happens to send an inter-processor interrupt to all CPUs, - // and inter-processor interrupts happen to cause the CPU's store buffers to be flushed. - // - // Unfortunately, VirtualProtect only does this if the page whose status is being changed is in the process' working set - // (otherwise there's no need to tell the other CPUs that anything has changed). - // - // One way to do this is to lock the page into the process' working set. Unfortunately, it can fail if there are already too many - // locked pages. - // - // We could increase the process' working set limit, using SetProcessWorkingSet, but that would be a) intrusive (the process may - // have its own idea of what the limit should be), and b) race-prone (another thread may be trying to adjust the limit, to a - // different value, at the same time). - // - // We could stop using *m_pPageVirtualProtect as the page we fiddle with, and instead use a page we know is already locked into - // the working set. There's no way to enumerate such pages, so it'd have to be a well-known fixed location that we know is always - // locked, and that can have its protection fiddled with without consequence. We know of no such location, and if we did it would - // undoubtedly be some internal Windows data structure that would be subject to changes in the way its memory is handled at any time. - // - // The VirtualProtect trick has worked for many years in the CLR, without the call to VirtualLock, without apparent problems. - // Part of the reason is because of the equivalent of the check of *m_pPageVirtualProtect above. - // - DWORD oldProtect; - - // We have it on good authority from the kernel team that, although VirtualProtect is repeatedly called with the - // same protection (PAGE_READONLY), the OS will not optimize out the flush buffers as a result. - VirtualProtect(pOrgPageVirtualProtect, sizeof(BYTE), PAGE_READONLY, &oldProtect); + pOrgPageVirtualProtect = pPageVirtualProtectTmp; } + } - break; + + // Note that the read of *m_pPageVirtualProtect is very important, as it makes it extremely likely that this memory will + // be in the working set when we call VirtualProtect (see comments below). + if (*pOrgPageVirtualProtect == 1) + { + // + // VirtualProtect simulates FlushProcessWriteBuffers because it happens to send an inter-processor interrupt to all CPUs, + // and inter-processor interrupts happen to cause the CPU's store buffers to be flushed. + // + // Unfortunately, VirtualProtect only does this if the page whose status is being changed is in the process' working set + // (otherwise there's no need to tell the other CPUs that anything has changed). + // + // One way to do this is to lock the page into the process' working set. Unfortunately, it can fail if there are already too many + // locked pages. + // + // We could increase the process' working set limit, using SetProcessWorkingSet, but that would be a) intrusive (the process may + // have its own idea of what the limit should be), and b) race-prone (another thread may be trying to adjust the limit, to a + // different value, at the same time). + // + // We could stop using *m_pPageVirtualProtect as the page we fiddle with, and instead use a page we know is already locked into + // the working set. There's no way to enumerate such pages, so it'd have to be a well-known fixed location that we know is always + // locked, and that can have its protection fiddled with without consequence. We know of no such location, and if we did it would + // undoubtedly be some internal Windows data structure that would be subject to changes in the way its memory is handled at any time. + // + // The VirtualProtect trick has worked for many years in the CLR, without the call to VirtualLock, without apparent problems. + // Part of the reason is because of the equivalent of the check of *m_pPageVirtualProtect above. + // + DWORD oldProtect; + + // We have it on good authority from the kernel team that, although VirtualProtect is repeatedly called with the + // same protection (PAGE_READONLY), the OS will not optimize out the flush buffers as a result. + VirtualProtect(pOrgPageVirtualProtect, sizeof(BYTE), PAGE_READONLY, &oldProtect); } + + break; } + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN6) - //Minimum supported client Windows Vista [desktop apps only] - //Minimum supported server Windows Server 2008 [desktop apps only] - __DEFINE_THUNK( - kernel32, - 16, - _Success_(return != FALSE) - BOOL, - WINAPI, - InitializeProcThreadAttributeList, - _Out_writes_bytes_to_opt_(*lpSize,*lpSize) LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList, - _In_ DWORD dwAttributeCount, - _Reserved_ DWORD dwFlags, - _When_(lpAttributeList == nullptr,_Out_) _When_(lpAttributeList != nullptr,_Inout_) PSIZE_T lpSize - ) + //Minimum supported client Windows Vista [desktop apps only] + //Minimum supported server Windows Server 2008 [desktop apps only] + __DEFINE_THUNK( + kernel32, + 16, + _Success_(return != FALSE) + BOOL, + WINAPI, + InitializeProcThreadAttributeList, + _Out_writes_bytes_to_opt_(*lpSize,*lpSize) LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList, + _In_ DWORD dwAttributeCount, + _Reserved_ DWORD dwFlags, + _When_(lpAttributeList == nullptr,_Out_) _When_(lpAttributeList != nullptr,_Inout_) PSIZE_T lpSize + ) + { + if (const auto pInitializeProcThreadAttributeList = try_get_InitializeProcThreadAttributeList()) { - if (const auto pInitializeProcThreadAttributeList = try_get_InitializeProcThreadAttributeList()) - { - return pInitializeProcThreadAttributeList(lpAttributeList, dwAttributeCount, dwFlags, lpSize); - } + return pInitializeProcThreadAttributeList(lpAttributeList, dwAttributeCount, dwFlags, lpSize); + } - LSTATUS lStatus = ERROR_SUCCESS; + LSTATUS lStatus = ERROR_SUCCESS; - do + do + { + //参数验证 + if (dwFlags) { - //参数验证 - if (dwFlags) - { - lStatus = ERROR_INVALID_PARAMETER; - break; - } + lStatus = ERROR_INVALID_PARAMETER; + break; + } - //Vista只支持 3个 Type,所以只有三个 - if (dwAttributeCount > 3) - { - lStatus = ERROR_INVALID_PARAMETER; - break; - } + //Vista只支持 3个 Type,所以只有三个 + if (dwAttributeCount > 3) + { + lStatus = ERROR_INVALID_PARAMETER; + break; + } - const auto cbSize = *lpSize; - const auto cbSizeNeed = sizeof(PROC_THREAD_ATTRIBUTE_LIST) + dwAttributeCount * sizeof(PROC_THREAD_ATTRIBUTE_ENTRY); - *lpSize = cbSizeNeed; + const auto cbSize = *lpSize; + const auto cbSizeNeed = sizeof(PROC_THREAD_ATTRIBUTE_LIST) + dwAttributeCount * sizeof(PROC_THREAD_ATTRIBUTE_ENTRY); + *lpSize = cbSizeNeed; - if (lpAttributeList == nullptr || cbSize < cbSizeNeed) - { - lStatus = ERROR_INSUFFICIENT_BUFFER; - break; - } + if (lpAttributeList == nullptr || cbSize < cbSizeNeed) + { + lStatus = ERROR_INSUFFICIENT_BUFFER; + break; + } - lpAttributeList->dwFlags = 0; - lpAttributeList->lpExtendedFlags = nullptr; - lpAttributeList->Size = dwAttributeCount; - lpAttributeList->Count = 0; + lpAttributeList->dwFlags = 0; + lpAttributeList->lpExtendedFlags = nullptr; + lpAttributeList->Size = dwAttributeCount; + lpAttributeList->Count = 0; - return TRUE; + return TRUE; - } while (false); + } while (false); - SetLastError(lStatus); - return FALSE; - } + SetLastError(lStatus); + return FALSE; + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN6) - //Minimum supported client Windows Vista [desktop apps only] - //Minimum supported server Windows Server 2008 [desktop apps only] - __DEFINE_THUNK( - kernel32, - 4, - VOID, - WINAPI, - DeleteProcThreadAttributeList, - _Inout_ LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList - ) + //Minimum supported client Windows Vista [desktop apps only] + //Minimum supported server Windows Server 2008 [desktop apps only] + __DEFINE_THUNK( + kernel32, + 4, + VOID, + WINAPI, + DeleteProcThreadAttributeList, + _Inout_ LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList + ) + { + if (const auto pDeleteProcThreadAttributeList = try_get_DeleteProcThreadAttributeList()) { - if (const auto pDeleteProcThreadAttributeList = try_get_DeleteProcThreadAttributeList()) - { - return pDeleteProcThreadAttributeList(lpAttributeList); - } + return pDeleteProcThreadAttributeList(lpAttributeList); + } - //Vista原版什么也没有做…… - } + //Vista原版什么也没有做…… + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN6) - //Minimum supported client Windows Vista [desktop apps only] - //Minimum supported server Windows Server 2008 [desktop apps only] - __DEFINE_THUNK( - kernel32, - 28, - BOOL, - WINAPI, - UpdateProcThreadAttribute, - _Inout_ LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList, - _In_ DWORD dwFlags, - _In_ DWORD_PTR Attribute, - _In_reads_bytes_opt_(cbSize) PVOID lpValue, - _In_ SIZE_T cbSize, - _Out_writes_bytes_opt_(cbSize) PVOID lpPreviousValue, - _In_opt_ PSIZE_T lpReturnSize - ) + //Minimum supported client Windows Vista [desktop apps only] + //Minimum supported server Windows Server 2008 [desktop apps only] + __DEFINE_THUNK( + kernel32, + 28, + BOOL, + WINAPI, + UpdateProcThreadAttribute, + _Inout_ LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList, + _In_ DWORD dwFlags, + _In_ DWORD_PTR Attribute, + _In_reads_bytes_opt_(cbSize) PVOID lpValue, + _In_ SIZE_T cbSize, + _Out_writes_bytes_opt_(cbSize) PVOID lpPreviousValue, + _In_opt_ PSIZE_T lpReturnSize + ) + { + if (const auto pUpdateProcThreadAttribute = try_get_UpdateProcThreadAttribute()) { - if (const auto pUpdateProcThreadAttribute = try_get_UpdateProcThreadAttribute()) - { - return pUpdateProcThreadAttribute(lpAttributeList, dwFlags, Attribute, lpValue, cbSize, lpPreviousValue, lpReturnSize); - } + return pUpdateProcThreadAttribute(lpAttributeList, dwFlags, Attribute, lpValue, cbSize, lpPreviousValue, lpReturnSize); + } - LSTATUS lStatus = ERROR_SUCCESS; + LSTATUS lStatus = ERROR_SUCCESS; + + do + { + auto AttributeMark = 1ul << Attribute; - do + ///////////////////////////////////////////////////// + // + // 参数检查 + // + + if (dwFlags & (~PROC_THREAD_ATTRIBUTE_REPLACE_VALUE)) { - auto AttributeMark = 1ul << Attribute; + lStatus = ERROR_INVALID_PARAMETER; + break; + } - ///////////////////////////////////////////////////// - // - // 参数检查 - // - if (dwFlags & (~PROC_THREAD_ATTRIBUTE_REPLACE_VALUE)) + if ((Attribute & PROC_THREAD_ATTRIBUTE_ADDITIVE) == 0) + { + if (lpAttributeList->Count == lpAttributeList->Size) { - lStatus = ERROR_INVALID_PARAMETER; + //internal::BaseSetLastNTError(0xC0000001); + lStatus = ERROR_GEN_FAILURE; break; } - - - if ((Attribute & PROC_THREAD_ATTRIBUTE_ADDITIVE) == 0) + else if (AttributeMark & lpAttributeList->dwFlags) { - if (lpAttributeList->Count == lpAttributeList->Size) - { - //internal::BaseSetLastNTError(0xC0000001); - lStatus = ERROR_GEN_FAILURE; - break; - } - else if (AttributeMark & lpAttributeList->dwFlags) - { - //internal::BaseSetLastNTError(0x40000000); - lStatus = ERROR_OBJECT_NAME_EXISTS; - break; - } - else if (lpPreviousValue) - { - //internal::BaseSetLastNTError(0xC00000F4); - lStatus = ERROR_INVALID_PARAMETER; - break; - } - else if (dwFlags & PROC_THREAD_ATTRIBUTE_REPLACE_VALUE) - { - //internal::BaseSetLastNTError(0xC00000F0); - lStatus = ERROR_INVALID_PARAMETER; - break; - } + //internal::BaseSetLastNTError(0x40000000); + lStatus = ERROR_OBJECT_NAME_EXISTS; + break; } - - - if ((PROC_THREAD_ATTRIBUTE_INPUT & Attribute) && lpReturnSize) + else if (lpPreviousValue) { - //internal::BaseSetLastNTError(0xC00000F5); + //internal::BaseSetLastNTError(0xC00000F4); lStatus = ERROR_INVALID_PARAMETER; break; } + else if (dwFlags & PROC_THREAD_ATTRIBUTE_REPLACE_VALUE) + { + //internal::BaseSetLastNTError(0xC00000F0); + lStatus = ERROR_INVALID_PARAMETER; + break; + } + } - // - // - //////////////////////////////////////////////////// + if ((PROC_THREAD_ATTRIBUTE_INPUT & Attribute) && lpReturnSize) + { + //internal::BaseSetLastNTError(0xC00000F5); + lStatus = ERROR_INVALID_PARAMETER; + break; + } + + // + // + //////////////////////////////////////////////////// - auto pAttribute = &lpAttributeList->Entries[lpAttributeList->Count]; - constexpr auto ProcThreadAttributeExtendedFlags = 1; - //0x60001,文档没有公开 - constexpr auto PROC_THREAD_ATTRIBUTE_EXTENDED_FLAGS = ProcThreadAttributeValue(ProcThreadAttributeExtendedFlags, FALSE, TRUE, TRUE); + auto pAttribute = &lpAttributeList->Entries[lpAttributeList->Count]; + constexpr auto ProcThreadAttributeExtendedFlags = 1; + //0x60001,文档没有公开 + constexpr auto PROC_THREAD_ATTRIBUTE_EXTENDED_FLAGS = ProcThreadAttributeValue(ProcThreadAttributeExtendedFlags, FALSE, TRUE, TRUE); - if (Attribute == PROC_THREAD_ATTRIBUTE_PARENT_PROCESS) //0x20000 + + if (Attribute == PROC_THREAD_ATTRIBUTE_PARENT_PROCESS) //0x20000 + { + //WinXP不支持 UAC,没实现似乎也没什么的。 + + if (cbSize != sizeof(HANDLE)) { - //WinXP不支持 UAC,没实现似乎也没什么的。 - - if (cbSize != sizeof(HANDLE)) - { - //internal::BaseSetLastNTError(0xC0000004); - lStatus = ERROR_INVALID_PARAMETER; - break; - } + //internal::BaseSetLastNTError(0xC0000004); + lStatus = ERROR_INVALID_PARAMETER; + break; } - else if (Attribute == PROC_THREAD_ATTRIBUTE_EXTENDED_FLAGS) //0x60001 + } + else if (Attribute == PROC_THREAD_ATTRIBUTE_EXTENDED_FLAGS) //0x60001 + { + //系统没有公开这个含义,暂时让他允许通过把…… + + if (cbSize != sizeof(DWORD)) { - //系统没有公开这个含义,暂时让他允许通过把…… - - if (cbSize != sizeof(DWORD)) - { - //internal::BaseSetLastNTError(0xC0000004); - lStatus = ERROR_INVALID_PARAMETER; - break; - } - - DWORD dwOrgFlags; - - if (lpAttributeList->lpExtendedFlags) - { - pAttribute = lpAttributeList->lpExtendedFlags; - dwOrgFlags = (DWORD)lpAttributeList->lpExtendedFlags->lpValue; - AttributeMark = 0; - } - else - { - lpAttributeList->lpExtendedFlags = pAttribute; - dwOrgFlags = 0; - } - - - auto dwNewFlags = *(DWORD*)lpValue; - - if (dwNewFlags & ~0x00000003ul) - { - //internal::BaseSetLastNTError(0xC000000D); - lStatus = ERROR_BAD_LENGTH; - break; - } - - if ((dwFlags & PROC_THREAD_ATTRIBUTE_REPLACE_VALUE) == 0 && dwOrgFlags) - { - dwNewFlags |= dwOrgFlags; - } - - if (lpPreviousValue) - *(DWORD*)lpPreviousValue = dwOrgFlags; - - lpValue = (PVOID)dwNewFlags; + //internal::BaseSetLastNTError(0xC0000004); + lStatus = ERROR_INVALID_PARAMETER; + break; } - else if (Attribute == PROC_THREAD_ATTRIBUTE_HANDLE_LIST) //0x20002 + + DWORD dwOrgFlags; + + if (lpAttributeList->lpExtendedFlags) { - //WinXP也不支持指定句柄继承,他会直接继承所有可继承的句柄,所以没实现好像也没什么大不了的。 - - if (cbSize == 0 || cbSize % sizeof(HANDLE) != 0) - { - //internal::BaseSetLastNTError(0xC0000004); - lStatus = ERROR_INVALID_PARAMETER; - break; - } + pAttribute = lpAttributeList->lpExtendedFlags; + dwOrgFlags = (DWORD)lpAttributeList->lpExtendedFlags->lpValue; + AttributeMark = 0; } else { - //internal::BaseSetLastNTError(0xC00000BB); - lStatus = ERROR_NOT_SUPPORTED; + lpAttributeList->lpExtendedFlags = pAttribute; + dwOrgFlags = 0; + } + + + auto dwNewFlags = *(DWORD*)lpValue; + + if (dwNewFlags & ~0x00000003ul) + { + //internal::BaseSetLastNTError(0xC000000D); + lStatus = ERROR_BAD_LENGTH; break; } - //LABEL_17 - pAttribute->lpValue = lpValue; + if ((dwFlags & PROC_THREAD_ATTRIBUTE_REPLACE_VALUE) == 0 && dwOrgFlags) + { + dwNewFlags |= dwOrgFlags; + } + + if (lpPreviousValue) + *(DWORD*)lpPreviousValue = dwOrgFlags; + + lpValue = (PVOID)dwNewFlags; + } + else if (Attribute == PROC_THREAD_ATTRIBUTE_HANDLE_LIST) //0x20002 + { + //WinXP也不支持指定句柄继承,他会直接继承所有可继承的句柄,所以没实现好像也没什么大不了的。 - if (AttributeMark) + if (cbSize == 0 || cbSize % sizeof(HANDLE) != 0) { - pAttribute->Attribute = Attribute; - pAttribute->cbSize = cbSize; - ++lpAttributeList->Count; - lpAttributeList->dwFlags |= AttributeMark; + //internal::BaseSetLastNTError(0xC0000004); + lStatus = ERROR_INVALID_PARAMETER; + break; } + } + else + { + //internal::BaseSetLastNTError(0xC00000BB); + lStatus = ERROR_NOT_SUPPORTED; + break; + } - return TRUE; + //LABEL_17 + pAttribute->lpValue = lpValue; - } while (false); + if (AttributeMark) + { + pAttribute->Attribute = Attribute; + pAttribute->cbSize = cbSize; + ++lpAttributeList->Count; + lpAttributeList->dwFlags |= AttributeMark; + } + + return TRUE; - SetLastError(lStatus); + } while (false); + + SetLastError(lStatus); - return FALSE; - } + return FALSE; + } #endif #if (YY_Thunks_Support_Version < NTDDI_WS03) - //Windows Vista, Windows XP Professional x64 Edition [desktop apps only] - //Windows Server 2008, Windows Server 2003 with SP1 [desktop apps only] - __DEFINE_THUNK( - kernel32, - 4, - BOOL, - WINAPI, - SetThreadStackGuarantee, - _Inout_ ULONG *StackSizeInBytes - ) + //Windows Vista, Windows XP Professional x64 Edition [desktop apps only] + //Windows Server 2008, Windows Server 2003 with SP1 [desktop apps only] + __DEFINE_THUNK( + kernel32, + 4, + BOOL, + WINAPI, + SetThreadStackGuarantee, + _Inout_ ULONG *StackSizeInBytes + ) + { + if (const auto pSetThreadStackGuarantee = try_get_SetThreadStackGuarantee()) { - if (const auto pSetThreadStackGuarantee = try_get_SetThreadStackGuarantee()) - { - return pSetThreadStackGuarantee(StackSizeInBytes); - } - - // 以下内容来自:ucrt\misc\resetstk.cpp + return pSetThreadStackGuarantee(StackSizeInBytes); + } + // 以下内容来自:ucrt\misc\resetstk.cpp - // 因为只面向 Windows XP以及之前的系统,我们可以硬编码的确定,页大小只可能是 4K。 - // 减少 GetSystemInfo 调用。 - constexpr auto PageSize = 4096u; - constexpr auto MinStackRequest = 2u; - auto pStack = (LPBYTE)_alloca(1); + // 因为只面向 Windows XP以及之前的系统,我们可以硬编码的确定,页大小只可能是 4K。 + // 减少 GetSystemInfo 调用。 + constexpr auto PageSize = 4096u; + constexpr auto MinStackRequest = 2u; - auto RegionSize = *StackSizeInBytes; + auto pStack = (LPBYTE)_alloca(1); - // TEB没有 GuaranteedStackBytes,没法知道上一次的结果,我们仅仅返回一个假的数值。 - *StackSizeInBytes = PageSize; + auto RegionSize = *StackSizeInBytes; - // 长度为 0 时,不需要额外申请 - if (RegionSize == 0) - return TRUE; + // TEB没有 GuaranteedStackBytes,没法知道上一次的结果,我们仅仅返回一个假的数值。 + *StackSizeInBytes = PageSize; - // 我们需要额外一块 PAGE_GUARD 来进行边界防御。 - RegionSize = (RegionSize + PageSize + (PageSize - 1)) & ~(PageSize - 1); - RegionSize = max(RegionSize, PageSize * MinStackRequest); + // 长度为 0 时,不需要额外申请 + if (RegionSize == 0) + return TRUE; - MEMORY_BASIC_INFORMATION mbi; - if (VirtualQuery(pStack, &mbi, sizeof mbi) == 0) - return FALSE; + // 我们需要额外一块 PAGE_GUARD 来进行边界防御。 + RegionSize = (RegionSize + PageSize + (PageSize - 1)) & ~(PageSize - 1); + RegionSize = max(RegionSize, PageSize * MinStackRequest); - auto pStackBase = (LPBYTE)mbi.AllocationBase; + MEMORY_BASIC_INFORMATION mbi; + if (VirtualQuery(pStack, &mbi, sizeof mbi) == 0) + return FALSE; - // - // Find the page(s) just below where the stack pointer currently points. - // This is the highest potential guard page. - auto pMaxGuard = (LPBYTE)(((DWORD_PTR)pStack & ~(DWORD_PTR)(PageSize - 1)) - RegionSize); + auto pStackBase = (LPBYTE)mbi.AllocationBase; - // - // If the potential guard page is too close to the start of the stack - // region, abandon the reset effort for lack of space. Win9x has a - // larger reserved stack requirement. - auto pMinGuard = pStackBase + PageSize; + // + // Find the page(s) just below where the stack pointer currently points. + // This is the highest potential guard page. + auto pMaxGuard = (LPBYTE)(((DWORD_PTR)pStack & ~(DWORD_PTR)(PageSize - 1)) - RegionSize); - if (pMaxGuard < pMinGuard) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } + // + // If the potential guard page is too close to the start of the stack + // region, abandon the reset effort for lack of space. Win9x has a + // larger reserved stack requirement. + auto pMinGuard = pStackBase + PageSize; - // Set the new guard page just below the current stack page. - DWORD flOldProtect; - if (VirtualAlloc(pMaxGuard, RegionSize, MEM_COMMIT, PAGE_READWRITE) == nullptr - || VirtualProtect(pMaxGuard, RegionSize, PAGE_READWRITE | PAGE_GUARD, &flOldProtect) == 0) - { - return FALSE; - } + if (pMaxGuard < pMinGuard) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } - return TRUE; + // Set the new guard page just below the current stack page. + DWORD flOldProtect; + if (VirtualAlloc(pMaxGuard, RegionSize, MEM_COMMIT, PAGE_READWRITE) == nullptr + || VirtualProtect(pMaxGuard, RegionSize, PAGE_READWRITE | PAGE_GUARD, &flOldProtect) == 0) + { + return FALSE; } + + return TRUE; + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN8) - // 最低受支持的客户端 Windows 8 [桌面应用|UWP 应用] - // 最低受支持的服务器 Windows Server 2012[桌面应用 | UWP 应用] - __DEFINE_THUNK( - kernel32, - 16, - BOOL, - WINAPI, - GetProcessMitigationPolicy, - _In_ HANDLE _hProcess, - _In_ PROCESS_MITIGATION_POLICY _eMitigationPolicy, - _Out_writes_bytes_(_cbLength) PVOID _pBuffer, - _In_ SIZE_T _cbLength - ) + // 最低受支持的客户端 Windows 8 [桌面应用|UWP 应用] + // 最低受支持的服务器 Windows Server 2012[桌面应用 | UWP 应用] + __DEFINE_THUNK( + kernel32, + 16, + BOOL, + WINAPI, + GetProcessMitigationPolicy, + _In_ HANDLE _hProcess, + _In_ PROCESS_MITIGATION_POLICY _eMitigationPolicy, + _Out_writes_bytes_(_cbLength) PVOID _pBuffer, + _In_ SIZE_T _cbLength + ) + { + if (const auto _pfnGetProcessMitigationPolicy = try_get_GetProcessMitigationPolicy()) { - if (const auto _pfnGetProcessMitigationPolicy = try_get_GetProcessMitigationPolicy()) - { - return _pfnGetProcessMitigationPolicy(_hProcess, _eMitigationPolicy, _pBuffer, _cbLength); - } + return _pfnGetProcessMitigationPolicy(_hProcess, _eMitigationPolicy, _pBuffer, _cbLength); + } - if (!_pBuffer) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } + if (!_pBuffer) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + if ((DWORD)_eMitigationPolicy >= (DWORD)MaxProcessMitigationPolicy) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + const auto _pfnNtQueryInformationProcess = try_get_NtQueryInformationProcess(); + if (!_pfnNtQueryInformationProcess) + { + SetLastError(ERROR_NOT_SUPPORTED); + return FALSE; + } - if ((DWORD)_eMitigationPolicy >= (DWORD)MaxProcessMitigationPolicy) + if (_eMitigationPolicy == ProcessDEPPolicy) + { + if (_cbLength != sizeof(PROCESS_MITIGATION_DEP_POLICY)) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } - const auto _pfnNtQueryInformationProcess = try_get_NtQueryInformationProcess(); - if (!_pfnNtQueryInformationProcess) - { - SetLastError(ERROR_NOT_SUPPORTED); - return FALSE; - } - - if (_eMitigationPolicy == ProcessDEPPolicy) + KEXECUTE_OPTIONS _DepOptions = {}; + NTSTATUS _Status = _pfnNtQueryInformationProcess(_hProcess, ProcessExecuteFlags, &_DepOptions, sizeof(_DepOptions), nullptr); + if (_Status >= 0) { - if (_cbLength != sizeof(PROCESS_MITIGATION_DEP_POLICY)) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - KEXECUTE_OPTIONS _DepOptions = {}; - NTSTATUS _Status = _pfnNtQueryInformationProcess(_hProcess, ProcessExecuteFlags, &_DepOptions, sizeof(_DepOptions), nullptr); - if (_Status >= 0) - { - auto _pDepPolicy = (PROCESS_MITIGATION_DEP_POLICY*)_pBuffer; - _pDepPolicy->Enable = _DepOptions.ExecuteEnable ? 0 : 1; - _pDepPolicy->DisableAtlThunkEmulation = _DepOptions.DisableThunkEmulation; - _pDepPolicy->ReservedFlags = 0; - _pDepPolicy->Permanent = _DepOptions.Permanent; - return TRUE; - } - else if (STATUS_INVALID_INFO_CLASS == _Status || STATUS_NOT_SUPPORTED == _Status) - { - *(DWORD*)_pBuffer = 0; - return TRUE; - } - else - { - internal::BaseSetLastNTError(_Status); - return FALSE; - } + auto _pDepPolicy = (PROCESS_MITIGATION_DEP_POLICY*)_pBuffer; + _pDepPolicy->Enable = _DepOptions.ExecuteEnable ? 0 : 1; + _pDepPolicy->DisableAtlThunkEmulation = _DepOptions.DisableThunkEmulation; + _pDepPolicy->ReservedFlags = 0; + _pDepPolicy->Permanent = _DepOptions.Permanent; + return TRUE; } - else if (_eMitigationPolicy == ProcessMitigationOptionsMask) + else if (STATUS_INVALID_INFO_CLASS == _Status || STATUS_NOT_SUPPORTED == _Status) { - if (_cbLength < sizeof(UINT64)) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - - memset(_pBuffer, 0, _cbLength); + *(DWORD*)_pBuffer = 0; return TRUE; } else { - if (_cbLength != sizeof(DWORD)) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - - YY_ProcessPolicyInfo _Info = { static_cast(_eMitigationPolicy) }; - NTSTATUS _Status = _pfnNtQueryInformationProcess(_hProcess, YY_ProcessPolicy, &_Info, sizeof(_Info), nullptr); - if (_Status >= 0) - { - *(DWORD*)_pBuffer = _Info.Flags; - return TRUE; - } - else if (STATUS_INVALID_INFO_CLASS == _Status || STATUS_NOT_SUPPORTED == _Status) - { - // 如果没有这个特性,那么统一设置为0,表示内部所有环境方案都处于关闭状态 - *(DWORD*)_pBuffer = 0; - return TRUE; - } - else - { - internal::BaseSetLastNTError(_Status); - return FALSE; - } + internal::BaseSetLastNTError(_Status); + return FALSE; } - - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; } -#endif - -#if (YY_Thunks_Support_Version < NTDDI_WIN8) - - // 最低受支持的客户端 Windows 8 [桌面应用|UWP 应用] - // 最低受支持的服务器 Windows Server 2012[桌面应用 | UWP 应用] - __DEFINE_THUNK( - kernel32, - 12, - BOOL, - WINAPI, - SetProcessMitigationPolicy, - _In_ PROCESS_MITIGATION_POLICY _eMitigationPolicy, - _In_reads_bytes_(_cbLength) PVOID _pBuffer, - _In_ SIZE_T _cbLength - ) + else if (_eMitigationPolicy == ProcessMitigationOptionsMask) { - if (const auto _pfnSetProcessMitigationPolicy = try_get_SetProcessMitigationPolicy()) - { - return _pfnSetProcessMitigationPolicy(_eMitigationPolicy, _pBuffer, _cbLength); - } - - if (!_pBuffer) + if (_cbLength < sizeof(UINT64)) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } - if ((DWORD)_eMitigationPolicy >= (DWORD)MaxProcessMitigationPolicy || _eMitigationPolicy == ProcessMitigationOptionsMask) + memset(_pBuffer, 0, _cbLength); + return TRUE; + } + else + { + if (_cbLength != sizeof(DWORD)) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } - const auto _pfnNtSetInformationProcess = try_get_NtSetInformationProcess(); - if (!_pfnNtSetInformationProcess) - { - SetLastError(ERROR_NOT_SUPPORTED); - return FALSE; - } - - NTSTATUS _Status; - if (_eMitigationPolicy == ProcessDEPPolicy) - { - if (_cbLength != sizeof(PROCESS_MITIGATION_DEP_POLICY)) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - - auto& _DepPolicy = *(PROCESS_MITIGATION_DEP_POLICY*)_pBuffer; - - KEXECUTE_OPTIONS _DepOptions = {}; - if (_DepPolicy.Enable) - { - _DepOptions.ExecuteDisable = 1; - } - else - { - _DepOptions.ExecuteEnable = 1; - } - _DepOptions.DisableThunkEmulation = _DepPolicy.DisableAtlThunkEmulation; - _DepOptions.Permanent = _DepPolicy.Permanent; - _Status = _pfnNtSetInformationProcess(NtCurrentProcess(), YY_ProcessPolicy, &_DepOptions, sizeof(_DepOptions)); - - } - else + YY_ProcessPolicyInfo _Info = { static_cast(_eMitigationPolicy) }; + NTSTATUS _Status = _pfnNtQueryInformationProcess(_hProcess, YY_ProcessPolicy, &_Info, sizeof(_Info), nullptr); + if (_Status >= 0) { - if (_cbLength != sizeof(DWORD)) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - - YY_ProcessPolicyInfo _Info = { static_cast(_eMitigationPolicy), *(DWORD*)_pBuffer }; - _Status = _pfnNtSetInformationProcess(NtCurrentProcess(), YY_ProcessPolicy, &_Info, sizeof(_Info)); + *(DWORD*)_pBuffer = _Info.Flags; + return TRUE; } - - if (_Status >= 0) + else if (STATUS_INVALID_INFO_CLASS == _Status || STATUS_NOT_SUPPORTED == _Status) { + // 如果没有这个特性,那么统一设置为0,表示内部所有环境方案都处于关闭状态 + *(DWORD*)_pBuffer = 0; return TRUE; } else @@ -911,264 +818,384 @@ namespace YY return FALSE; } } + + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } #endif - + #if (YY_Thunks_Support_Version < NTDDI_WIN8) - // 最低受支持的客户端 Windows 8 [桌面应用|UWP 应用] - // 最低受支持的服务器 Windows Server 2012[桌面应用 | UWP 应用] - __DEFINE_THUNK( - kernel32, - 16, - BOOL, - WINAPI, - SetProcessInformation, - _In_ HANDLE _hProcess, - _In_ PROCESS_INFORMATION_CLASS _eProcessInformationClass, - _In_reads_bytes_(_cbProcessInformationSize) LPVOID _pProcessInformation, - _In_ DWORD _cbProcessInformationSize - ) + // 最低受支持的客户端 Windows 8 [桌面应用|UWP 应用] + // 最低受支持的服务器 Windows Server 2012[桌面应用 | UWP 应用] + __DEFINE_THUNK( + kernel32, + 12, + BOOL, + WINAPI, + SetProcessMitigationPolicy, + _In_ PROCESS_MITIGATION_POLICY _eMitigationPolicy, + _In_reads_bytes_(_cbLength) PVOID _pBuffer, + _In_ SIZE_T _cbLength + ) + { + if (const auto _pfnSetProcessMitigationPolicy = try_get_SetProcessMitigationPolicy()) { - if (const auto _pfnSetProcessInformation = try_get_SetProcessInformation()) - { - return _pfnSetProcessInformation(_hProcess, _eProcessInformationClass, _pProcessInformation, _cbProcessInformationSize); - } + return _pfnSetProcessMitigationPolicy(_eMitigationPolicy, _pBuffer, _cbLength); + } - if (_pProcessInformation == nullptr || (DWORD)_eProcessInformationClass >= (DWORD)ProcessInformationClassMax) + if (!_pBuffer) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + if ((DWORD)_eMitigationPolicy >= (DWORD)MaxProcessMitigationPolicy || _eMitigationPolicy == ProcessMitigationOptionsMask) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + const auto _pfnNtSetInformationProcess = try_get_NtSetInformationProcess(); + if (!_pfnNtSetInformationProcess) + { + SetLastError(ERROR_NOT_SUPPORTED); + return FALSE; + } + + NTSTATUS _Status; + if (_eMitigationPolicy == ProcessDEPPolicy) + { + if (_cbLength != sizeof(PROCESS_MITIGATION_DEP_POLICY)) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } - const auto _pfnNtSetInformationProcess = try_get_NtSetInformationProcess(); - if (!_pfnNtSetInformationProcess) - { - SetLastError(ERROR_NOT_SUPPORTED); - return FALSE; - } + auto& _DepPolicy = *(PROCESS_MITIGATION_DEP_POLICY*)_pBuffer; - NTSTATUS _Status; - if (_eProcessInformationClass == ProcessMemoryPriority) + KEXECUTE_OPTIONS _DepOptions = {}; + if (_DepPolicy.Enable) { - if (_cbProcessInformationSize != sizeof(MEMORY_PRIORITY_INFORMATION)) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - // PAGE_PRIORITY_INFORMATION - _Status = _pfnNtSetInformationProcess(_hProcess, ProcessPagePriority, _pProcessInformation, sizeof(DWORD)); + _DepOptions.ExecuteDisable = 1; } else { - SetLastError(ERROR_NOT_SUPPORTED); + _DepOptions.ExecuteEnable = 1; + } + _DepOptions.DisableThunkEmulation = _DepPolicy.DisableAtlThunkEmulation; + _DepOptions.Permanent = _DepPolicy.Permanent; + + _Status = _pfnNtSetInformationProcess(NtCurrentProcess(), YY_ProcessPolicy, &_DepOptions, sizeof(_DepOptions)); + + } + else + { + if (_cbLength != sizeof(DWORD)) + { + SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } - if (_Status >= 0) - return TRUE; + YY_ProcessPolicyInfo _Info = { static_cast(_eMitigationPolicy), *(DWORD*)_pBuffer }; + _Status = _pfnNtSetInformationProcess(NtCurrentProcess(), YY_ProcessPolicy, &_Info, sizeof(_Info)); + } + if (_Status >= 0) + { + return TRUE; + } + else + { internal::BaseSetLastNTError(_Status); return FALSE; } + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN8) - // 最低受支持的客户端 Windows 8 [桌面应用|UWP 应用] - // 最低受支持的服务器 Windows Server 2012[桌面应用 | UWP 应用] - __DEFINE_THUNK( - kernel32, - 16, - BOOL, - WINAPI, - SetThreadInformation, - _In_ HANDLE _hThread, - _In_ THREAD_INFORMATION_CLASS _eThreadInformationClass, - _In_reads_bytes_(_cbThreadInformationSize) LPVOID _pThreadInformation, - _In_ DWORD _cbThreadInformationSize - ) + // 最低受支持的客户端 Windows 8 [桌面应用|UWP 应用] + // 最低受支持的服务器 Windows Server 2012[桌面应用 | UWP 应用] + __DEFINE_THUNK( + kernel32, + 16, + BOOL, + WINAPI, + SetProcessInformation, + _In_ HANDLE _hProcess, + _In_ PROCESS_INFORMATION_CLASS _eProcessInformationClass, + _In_reads_bytes_(_cbProcessInformationSize) LPVOID _pProcessInformation, + _In_ DWORD _cbProcessInformationSize + ) + { + if (const auto _pfnSetProcessInformation = try_get_SetProcessInformation()) { - if (const auto _pfnSetThreadInformation = try_get_SetThreadInformation()) - { - return _pfnSetThreadInformation(_hThread, _eThreadInformationClass, _pThreadInformation, _cbThreadInformationSize); - } + return _pfnSetProcessInformation(_hProcess, _eProcessInformationClass, _pProcessInformation, _cbProcessInformationSize); + } + + if (_pProcessInformation == nullptr || (DWORD)_eProcessInformationClass >= (DWORD)ProcessInformationClassMax) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + const auto _pfnNtSetInformationProcess = try_get_NtSetInformationProcess(); + if (!_pfnNtSetInformationProcess) + { + SetLastError(ERROR_NOT_SUPPORTED); + return FALSE; + } - if (_pThreadInformation == nullptr || (DWORD)_eThreadInformationClass >= (DWORD)ThreadInformationClassMax) + NTSTATUS _Status; + if (_eProcessInformationClass == ProcessMemoryPriority) + { + if (_cbProcessInformationSize != sizeof(MEMORY_PRIORITY_INFORMATION)) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } + // PAGE_PRIORITY_INFORMATION + _Status = _pfnNtSetInformationProcess(_hProcess, ProcessPagePriority, _pProcessInformation, sizeof(DWORD)); + } + else + { + SetLastError(ERROR_NOT_SUPPORTED); + return FALSE; + } - const auto _pfnNtSetInformationThread = try_get_NtSetInformationThread(); - if (!_pfnNtSetInformationThread) - { - SetLastError(ERROR_NOT_SUPPORTED); - return FALSE; - } + if (_Status >= 0) + return TRUE; - NTSTATUS _Status; - if (_eThreadInformationClass == ThreadMemoryPriority) - { - if (_cbThreadInformationSize != sizeof(MEMORY_PRIORITY_INFORMATION)) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - _Status = _pfnNtSetInformationThread(_hThread, ThreadPagePriority, _pThreadInformation, sizeof(DWORD)); - } - else if (_eThreadInformationClass == ThreadAbsoluteCpuPriority) + internal::BaseSetLastNTError(_Status); + return FALSE; + } +#endif + +#if (YY_Thunks_Support_Version < NTDDI_WIN8) + + // 最低受支持的客户端 Windows 8 [桌面应用|UWP 应用] + // 最低受支持的服务器 Windows Server 2012[桌面应用 | UWP 应用] + __DEFINE_THUNK( + kernel32, + 16, + BOOL, + WINAPI, + SetThreadInformation, + _In_ HANDLE _hThread, + _In_ THREAD_INFORMATION_CLASS _eThreadInformationClass, + _In_reads_bytes_(_cbThreadInformationSize) LPVOID _pThreadInformation, + _In_ DWORD _cbThreadInformationSize + ) + { + if (const auto _pfnSetThreadInformation = try_get_SetThreadInformation()) + { + return _pfnSetThreadInformation(_hThread, _eThreadInformationClass, _pThreadInformation, _cbThreadInformationSize); + } + + if (_pThreadInformation == nullptr || (DWORD)_eThreadInformationClass >= (DWORD)ThreadInformationClassMax) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + const auto _pfnNtSetInformationThread = try_get_NtSetInformationThread(); + if (!_pfnNtSetInformationThread) + { + SetLastError(ERROR_NOT_SUPPORTED); + return FALSE; + } + + NTSTATUS _Status; + if (_eThreadInformationClass == ThreadMemoryPriority) + { + if (_cbThreadInformationSize != sizeof(MEMORY_PRIORITY_INFORMATION)) { - if (_cbThreadInformationSize != sizeof(DWORD)) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - _Status = _pfnNtSetInformationThread(_hThread, ThreadActualBasePriority, _pThreadInformation, sizeof(DWORD)); + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; } - else + _Status = _pfnNtSetInformationThread(_hThread, ThreadPagePriority, _pThreadInformation, sizeof(DWORD)); + } + else if (_eThreadInformationClass == ThreadAbsoluteCpuPriority) + { + if (_cbThreadInformationSize != sizeof(DWORD)) { - SetLastError(ERROR_NOT_SUPPORTED); + SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } - - if (_Status >= 0) - return TRUE; - - internal::BaseSetLastNTError(_Status); + _Status = _pfnNtSetInformationThread(_hThread, ThreadActualBasePriority, _pThreadInformation, sizeof(DWORD)); + } + else + { + SetLastError(ERROR_NOT_SUPPORTED); return FALSE; } + + if (_Status >= 0) + return TRUE; + + internal::BaseSetLastNTError(_Status); + return FALSE; + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN8) - // 最低受支持的客户端 Windows 8 [桌面应用|UWP 应用] - // 最低受支持的服务器 Windows Server 2012[桌面应用 | UWP 应用] - __DEFINE_THUNK( - kernel32, - 16, - BOOL, - WINAPI, - GetThreadInformation, - _In_ HANDLE _hThread, - _In_ THREAD_INFORMATION_CLASS _eThreadInformationClass, - _Out_writes_bytes_(_cbThreadInformationSize) LPVOID _pThreadInformation, - _In_ DWORD _cbThreadInformationSize - ) + // 最低受支持的客户端 Windows 8 [桌面应用|UWP 应用] + // 最低受支持的服务器 Windows Server 2012[桌面应用 | UWP 应用] + __DEFINE_THUNK( + kernel32, + 16, + BOOL, + WINAPI, + GetThreadInformation, + _In_ HANDLE _hThread, + _In_ THREAD_INFORMATION_CLASS _eThreadInformationClass, + _Out_writes_bytes_(_cbThreadInformationSize) LPVOID _pThreadInformation, + _In_ DWORD _cbThreadInformationSize + ) + { + if (const auto _pfnGetThreadInformation = try_get_GetThreadInformation()) { - if (const auto _pfnGetThreadInformation = try_get_GetThreadInformation()) - { - return _pfnGetThreadInformation(_hThread, _eThreadInformationClass, _pThreadInformation, _cbThreadInformationSize); - } - - const auto _pfnNtQueryInformationThread = try_get_NtQueryInformationThread(); - if (!_pfnNtQueryInformationThread) - { - SetLastError(ERROR_NOT_SUPPORTED); - return FALSE; - } + return _pfnGetThreadInformation(_hThread, _eThreadInformationClass, _pThreadInformation, _cbThreadInformationSize); + } - long _Status; - if (_eThreadInformationClass == ThreadMemoryPriority) - { - _Status = _pfnNtQueryInformationThread(_hThread, ThreadPagePriority, _pThreadInformation, _cbThreadInformationSize, nullptr); - } - else if (_eThreadInformationClass == ThreadAbsoluteCpuPriority) - { - _Status = _pfnNtQueryInformationThread(_hThread, ThreadActualBasePriority, _pThreadInformation, _cbThreadInformationSize, nullptr); - } - else - { - _Status = STATUS_INVALID_PARAMETER; - } + const auto _pfnNtQueryInformationThread = try_get_NtQueryInformationThread(); + if (!_pfnNtQueryInformationThread) + { + SetLastError(ERROR_NOT_SUPPORTED); + return FALSE; + } - if (_Status < 0) - { - internal::BaseSetLastNTError(_Status); - return FALSE; - } + long _Status; + if (_eThreadInformationClass == ThreadMemoryPriority) + { + _Status = _pfnNtQueryInformationThread(_hThread, ThreadPagePriority, _pThreadInformation, _cbThreadInformationSize, nullptr); + } + else if (_eThreadInformationClass == ThreadAbsoluteCpuPriority) + { + _Status = _pfnNtQueryInformationThread(_hThread, ThreadActualBasePriority, _pThreadInformation, _cbThreadInformationSize, nullptr); + } + else + { + _Status = STATUS_INVALID_PARAMETER; + } - return TRUE; + if (_Status < 0) + { + internal::BaseSetLastNTError(_Status); + return FALSE; } + + return TRUE; + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN7) - // 最低受支持的客户端 Windows 7 [桌面应用 |UWP 应用] - // 最低受支持的服务器 Windows Server 2008 R2[桌面应用 | UWP 应用] - __DEFINE_THUNK( - kernel32, - 12, - BOOL, - WINAPI, - SetThreadIdealProcessorEx, - _In_ HANDLE _hThread, - _In_ PPROCESSOR_NUMBER _pIdealProcessor, - _Out_opt_ PPROCESSOR_NUMBER _pPreviousIdealProcessor - ) + // 最低受支持的客户端 Windows 7 [桌面应用 |UWP 应用] + // 最低受支持的服务器 Windows Server 2008 R2[桌面应用 | UWP 应用] + __DEFINE_THUNK( + kernel32, + 12, + BOOL, + WINAPI, + SetThreadIdealProcessorEx, + _In_ HANDLE _hThread, + _In_ PPROCESSOR_NUMBER _pIdealProcessor, + _Out_opt_ PPROCESSOR_NUMBER _pPreviousIdealProcessor + ) + { + if (const auto _pfnSetThreadIdealProcessorEx = try_get_SetThreadIdealProcessorEx()) { - if (const auto _pfnSetThreadIdealProcessorEx = try_get_SetThreadIdealProcessorEx()) - { - return _pfnSetThreadIdealProcessorEx(_hThread, _pIdealProcessor, _pPreviousIdealProcessor); - } + return _pfnSetThreadIdealProcessorEx(_hThread, _pIdealProcessor, _pPreviousIdealProcessor); + } - // 不支持的平台统一认为只有一组处理器 - // 微软这里就没有检查 _pIdealProcessor - if (_pIdealProcessor->Group != 0 || _pIdealProcessor->Number >= MAXIMUM_PROCESSORS) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } + // 不支持的平台统一认为只有一组处理器 + // 微软这里就没有检查 _pIdealProcessor + if (_pIdealProcessor->Group != 0 || _pIdealProcessor->Number >= MAXIMUM_PROCESSORS) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } - const auto _uPreviousIdealProcessor = SetThreadIdealProcessor(_hThread, _pIdealProcessor->Number); - if (_uPreviousIdealProcessor == static_cast(-1)) - { - return FALSE; - } + const auto _uPreviousIdealProcessor = SetThreadIdealProcessor(_hThread, _pIdealProcessor->Number); + if (_uPreviousIdealProcessor == static_cast(-1)) + { + return FALSE; + } - if (_pPreviousIdealProcessor) - { - _pPreviousIdealProcessor->Group = 0; - _pPreviousIdealProcessor->Number = static_cast(_uPreviousIdealProcessor); - _pPreviousIdealProcessor->Reserved = 0; - } - return TRUE; + if (_pPreviousIdealProcessor) + { + _pPreviousIdealProcessor->Group = 0; + _pPreviousIdealProcessor->Number = static_cast(_uPreviousIdealProcessor); + _pPreviousIdealProcessor->Reserved = 0; } + return TRUE; + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN7) - // 最低受支持的客户端 Windows 7 [桌面应用 |UWP 应用] - // 最低受支持的服务器 Windows Server 2008 R2[桌面应用 | UWP 应用] - __DEFINE_THUNK( - kernel32, - 8, - BOOL, - WINAPI, - GetThreadIdealProcessorEx, - _In_ HANDLE _hThread, - _Out_ PPROCESSOR_NUMBER _pIdealProcessor - ) + // 最低受支持的客户端 Windows 7 [桌面应用 |UWP 应用] + // 最低受支持的服务器 Windows Server 2008 R2[桌面应用 | UWP 应用] + __DEFINE_THUNK( + kernel32, + 8, + BOOL, + WINAPI, + GetThreadIdealProcessorEx, + _In_ HANDLE _hThread, + _Out_ PPROCESSOR_NUMBER _pIdealProcessor + ) + { + if (const auto _pfnGetThreadIdealProcessorEx = try_get_GetThreadIdealProcessorEx()) { - if (const auto _pfnGetThreadIdealProcessorEx = try_get_GetThreadIdealProcessorEx()) - { - return _pfnGetThreadIdealProcessorEx(_hThread, _pIdealProcessor); - } + return _pfnGetThreadIdealProcessorEx(_hThread, _pIdealProcessor); + } - // 不支持的平台统一认为只有一组处理器 - const auto _uPreviousIdealProcessor = SetThreadIdealProcessor(_hThread, MAXIMUM_PROCESSORS); - if (_uPreviousIdealProcessor == static_cast(-1)) - { - return FALSE; - } - - _pIdealProcessor->Group = 0; - _pIdealProcessor->Number = static_cast(_uPreviousIdealProcessor); - _pIdealProcessor->Reserved = 0; - return TRUE; + // 不支持的平台统一认为只有一组处理器 + const auto _uPreviousIdealProcessor = SetThreadIdealProcessor(_hThread, MAXIMUM_PROCESSORS); + if (_uPreviousIdealProcessor == static_cast(-1)) + { + return FALSE; } + + _pIdealProcessor->Group = 0; + _pIdealProcessor->Number = static_cast(_uPreviousIdealProcessor); + _pIdealProcessor->Reserved = 0; + return TRUE; + } #endif - }//namespace Thunks -} //namespace YY + +#if (YY_Thunks_Support_Version < NTDDI_WIN7) + + // 最低受支持的客户端 Windows 7 [仅限桌面应用] + // 最低受支持的服务器 Windows Server 2008 R2[仅限桌面应用] + __DEFINE_THUNK( + kernel32, + 32, + HANDLE, + WINAPI, + CreateRemoteThreadEx, + _In_ HANDLE _hProcess, + _In_ LPSECURITY_ATTRIBUTES _pThreadAttributes, + _In_ SIZE_T _uStackSize, + _In_ LPTHREAD_START_ROUTINE _pStartAddress, + _In_ LPVOID _pParameter, + _In_ DWORD _fCreationFlags, + _In_ LPPROC_THREAD_ATTRIBUTE_LIST _pAttributeList, + _Out_ LPDWORD _pThreadId + ) + { + if (const auto _pfnCreateRemoteThreadEx = try_get_CreateRemoteThreadEx()) + { + return _pfnCreateRemoteThreadEx(_hProcess, _pThreadAttributes, _uStackSize, _pStartAddress, _pParameter, _fCreationFlags, _pAttributeList, _pThreadId); + } + + return CreateRemoteThread(_hProcess, _pThreadAttributes, _uStackSize, _pStartAddress, _pParameter, _fCreationFlags, _pThreadId); + } +#endif +} //namespace YY::Thunks diff --git a/src/Thunks/api-ms-win-core-windowserrorreporting.hpp b/src/Thunks/api-ms-win-core-windowserrorreporting.hpp new file mode 100644 index 0000000..8206be9 --- /dev/null +++ b/src/Thunks/api-ms-win-core-windowserrorreporting.hpp @@ -0,0 +1,51 @@ +#include + +namespace YY::Thunks +{ +#if (YY_Thunks_Support_Version < NTDDI_WIN7) + + // 最低受支持的客户端 Windows 7 [仅限桌面应用] + // 最低受支持的服务器 Windows Server 2008 R2[仅限桌面应用] + __DEFINE_THUNK( + kernel32, + 8, + HRESULT, + WINAPI, + WerRegisterRuntimeExceptionModule, + _In_ PCWSTR _szOutOfProcessCallbackDll, + _In_ PVOID _pContext + ) + { + if (const auto _pfnWerRegisterRuntimeExceptionModule = try_get_WerRegisterRuntimeExceptionModule()) + { + return _pfnWerRegisterRuntimeExceptionModule(_szOutOfProcessCallbackDll, _pContext); + } + + return S_OK; + } +#endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN7) + + // 最低受支持的客户端 Windows 7 [仅限桌面应用] + // 最低受支持的服务器 Windows Server 2008 R2[仅限桌面应用] + __DEFINE_THUNK( + kernel32, + 8, + HRESULT, + WINAPI, + WerUnregisterRuntimeExceptionModule, + _In_ PCWSTR _szOutOfProcessCallbackDll, + _In_ PVOID _pContext + ) + { + if (const auto _pfnWerUnregisterRuntimeExceptionModule = try_get_WerUnregisterRuntimeExceptionModule()) + { + return _pfnWerUnregisterRuntimeExceptionModule(_szOutOfProcessCallbackDll, _pContext); + } + + return S_OK; + } +#endif +} diff --git a/src/Thunks/api-ms-win-core-wow64.hpp b/src/Thunks/api-ms-win-core-wow64.hpp index 87bfa6e..b26064d 100644 --- a/src/Thunks/api-ms-win-core-wow64.hpp +++ b/src/Thunks/api-ms-win-core-wow64.hpp @@ -1,208 +1,227 @@  -namespace YY +namespace YY::Thunks { - namespace Thunks - { - #if (YY_Thunks_Support_Version < NTDDI_WS03) - //Windows XP Professional x64 Edition, Windows Server 2003 - __DEFINE_THUNK( - kernel32, - 4, - BOOL, - WINAPI, - Wow64DisableWow64FsRedirection, - _Out_ PVOID* OldValue - ) + //Windows XP Professional x64 Edition, Windows Server 2003 + __DEFINE_THUNK( + kernel32, + 4, + BOOL, + WINAPI, + Wow64DisableWow64FsRedirection, + _Out_ PVOID* OldValue + ) + { + if (auto const pWow64DisableWow64FsRedirection = try_get_Wow64DisableWow64FsRedirection()) { - if (auto const pWow64DisableWow64FsRedirection = try_get_Wow64DisableWow64FsRedirection()) - { - return pWow64DisableWow64FsRedirection(OldValue); - } + return pWow64DisableWow64FsRedirection(OldValue); + } - SetLastError(ERROR_INVALID_FUNCTION); + SetLastError(ERROR_INVALID_FUNCTION); - return FALSE; - } + return FALSE; + } #endif #if (YY_Thunks_Support_Version < NTDDI_WS03) - //Windows XP Professional x64 Edition, Windows Server 2003 - __DEFINE_THUNK( - kernel32, - 4, - BOOL, - WINAPI, - Wow64RevertWow64FsRedirection, - _In_ PVOID OlValue - ) + //Windows XP Professional x64 Edition, Windows Server 2003 + __DEFINE_THUNK( + kernel32, + 4, + BOOL, + WINAPI, + Wow64RevertWow64FsRedirection, + _In_ PVOID OlValue + ) + { + if (auto const pWow64RevertWow64FsRedirection = try_get_Wow64RevertWow64FsRedirection()) { - if (auto const pWow64RevertWow64FsRedirection = try_get_Wow64RevertWow64FsRedirection()) - { - return pWow64RevertWow64FsRedirection(OlValue); - } + return pWow64RevertWow64FsRedirection(OlValue); + } - SetLastError(ERROR_INVALID_FUNCTION); + SetLastError(ERROR_INVALID_FUNCTION); - return FALSE; - } + return FALSE; + } #endif #if (YY_Thunks_Support_Version < NTDDI_WS03) - //Windows XP Professional x64 Edition, Windows Server 2003 - __DEFINE_THUNK( - kernel32, - 4, - BOOLEAN, - WINAPI, - Wow64EnableWow64FsRedirection, - _In_ BOOLEAN Wow64FsEnableRedirection - ) + //Windows XP Professional x64 Edition, Windows Server 2003 + __DEFINE_THUNK( + kernel32, + 4, + BOOLEAN, + WINAPI, + Wow64EnableWow64FsRedirection, + _In_ BOOLEAN Wow64FsEnableRedirection + ) + { + if (auto const pWow64EnableWow64FsRedirection = try_get_Wow64EnableWow64FsRedirection()) { - if (auto const pWow64EnableWow64FsRedirection = try_get_Wow64EnableWow64FsRedirection()) - { - return pWow64EnableWow64FsRedirection(Wow64FsEnableRedirection); - } + return pWow64EnableWow64FsRedirection(Wow64FsEnableRedirection); + } - SetLastError(ERROR_INVALID_FUNCTION); + SetLastError(ERROR_INVALID_FUNCTION); - return FALSE; + return FALSE; - } + } #endif #if (YY_Thunks_Support_Version < NTDDI_WS03SP1) - //Windows XP with SP2, Windows Server 2003 with SP1 - __DEFINE_THUNK( - kernel32, - 8, - BOOL, - WINAPI, - IsWow64Process, - _In_ HANDLE hProcess, - _Out_ PBOOL Wow64Process - ) + //Windows XP with SP2, Windows Server 2003 with SP1 + __DEFINE_THUNK( + kernel32, + 8, + BOOL, + WINAPI, + IsWow64Process, + _In_ HANDLE hProcess, + _Out_ PBOOL Wow64Process + ) + { + if (auto const pIsWow64Process = try_get_IsWow64Process()) { - if (auto const pIsWow64Process = try_get_IsWow64Process()) - { - return pIsWow64Process(hProcess, Wow64Process); - } + return pIsWow64Process(hProcess, Wow64Process); + } - *Wow64Process = FALSE; + *Wow64Process = FALSE; - return TRUE; - } + return TRUE; + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN10_RS3) && (defined _X86_ || defined _AMD64_) - //Windows 10, Version 1511 - //微软文档有点问题,实际x86以及amd64系统中,16299(RS3)才开始有此API。 - __DEFINE_THUNK( - kernel32, - 12, - _Success_(return) - BOOL, - WINAPI, - IsWow64Process2, - _In_ HANDLE hProcess, - _Out_ USHORT* pProcessMachine, - _Out_opt_ USHORT* pNativeMachine - ) + //Windows 10, Version 1511 + //微软文档有点问题,实际x86以及amd64系统中,16299(RS3)才开始有此API。 + __DEFINE_THUNK( + kernel32, + 12, + _Success_(return) + BOOL, + WINAPI, + IsWow64Process2, + _In_ HANDLE hProcess, + _Out_ USHORT* pProcessMachine, + _Out_opt_ USHORT* pNativeMachine + ) + { + if (auto const pIsWow64Process2 = try_get_IsWow64Process2()) { - if (auto const pIsWow64Process2 = try_get_IsWow64Process2()) - { - return pIsWow64Process2(hProcess, pProcessMachine, pNativeMachine); - } + return pIsWow64Process2(hProcess, pProcessMachine, pNativeMachine); + } - //判断是否运行在Wow6432虚拟机 - BOOL bWow64Process; - auto bRet = IsWow64Process(hProcess, &bWow64Process); + //判断是否运行在Wow6432虚拟机 + BOOL bWow64Process; + auto bRet = IsWow64Process(hProcess, &bWow64Process); - if (bRet) + if (bRet) + { + if (bWow64Process) { - if (bWow64Process) - { - *pProcessMachine = IMAGE_FILE_MACHINE_I386; - - //IA64已经哭晕在厕所 - if (pNativeMachine) - *pNativeMachine = IMAGE_FILE_MACHINE_AMD64; - } - else - { - *pProcessMachine = IMAGE_FILE_MACHINE_UNKNOWN; + *pProcessMachine = IMAGE_FILE_MACHINE_I386; + + //IA64已经哭晕在厕所 + if (pNativeMachine) + *pNativeMachine = IMAGE_FILE_MACHINE_AMD64; + } + else + { + *pProcessMachine = IMAGE_FILE_MACHINE_UNKNOWN; #if defined _X86_ - if (pNativeMachine) - *pNativeMachine = IMAGE_FILE_MACHINE_I386; + if (pNativeMachine) + *pNativeMachine = IMAGE_FILE_MACHINE_I386; #elif defined _AMD64_ - if (pNativeMachine) - *pNativeMachine = IMAGE_FILE_MACHINE_AMD64; + if (pNativeMachine) + *pNativeMachine = IMAGE_FILE_MACHINE_AMD64; #else - #error 不支持此体系 + #error 不支持此体系 #endif - } } - - return bRet; } + + return bRet; + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN10_RS3) && (defined _X86_ || defined _AMD64_) - //Windows 10, version 1709 - __DEFINE_THUNK( - kernel32, - 8, - _Must_inspect_result_ - HRESULT, - WINAPI, - IsWow64GuestMachineSupported, - _In_ USHORT WowGuestMachine, - _Out_ BOOL* MachineIsSupported - ) + //Windows 10, version 1709 + __DEFINE_THUNK( + kernel32, + 8, + _Must_inspect_result_ + HRESULT, + WINAPI, + IsWow64GuestMachineSupported, + _In_ USHORT WowGuestMachine, + _Out_ BOOL* MachineIsSupported + ) + { + if (auto const pIsWow64GuestMachineSupported = try_get_IsWow64GuestMachineSupported()) { - if (auto const pIsWow64GuestMachineSupported = try_get_IsWow64GuestMachineSupported()) - { - return pIsWow64GuestMachineSupported(WowGuestMachine, MachineIsSupported); - } + return pIsWow64GuestMachineSupported(WowGuestMachine, MachineIsSupported); + } - if (IMAGE_FILE_MACHINE_I386 == WowGuestMachine) - { + if (IMAGE_FILE_MACHINE_I386 == WowGuestMachine) + { #ifdef _AMD64_ - *MachineIsSupported = TRUE; + *MachineIsSupported = TRUE; #else - SYSTEM_INFO SystemInfo; - GetNativeSystemInfo(&SystemInfo); + SYSTEM_INFO SystemInfo; + GetNativeSystemInfo(&SystemInfo); - *MachineIsSupported = SystemInfo.wProcessorArchitecture != PROCESSOR_ARCHITECTURE_INTEL; + *MachineIsSupported = SystemInfo.wProcessorArchitecture != PROCESSOR_ARCHITECTURE_INTEL; #endif - } - else - { - *MachineIsSupported = FALSE; - } - - return S_OK; } + else + { + *MachineIsSupported = FALSE; + } + + return S_OK; + } #endif - }//namespace Thunks -} //namespace YY \ No newline at end of file + +#if (YY_Thunks_Support_Version < NTDDI_WS03) + + // 实际看到Vista就有,推测这个接口是x64系统时代添加的。 + __DEFINE_THUNK( + kernel32, + 8, + BOOL, + WINAPI, + Wow64GetThreadContext, + _In_ HANDLE _hThread, + _Out_ PWOW64_CONTEXT _pContext + ) + { + if (const auto _pfnWow64GetThreadContext = try_get_Wow64GetThreadContext()) + { + return _pfnWow64GetThreadContext(_hThread, _pContext); + } + + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } +#endif +} //namespace YY::Thunks diff --git a/src/Thunks/dwmapi.hpp b/src/Thunks/dwmapi.hpp index 36b4855..1c70ae1 100644 --- a/src/Thunks/dwmapi.hpp +++ b/src/Thunks/dwmapi.hpp @@ -260,5 +260,29 @@ namespace YY return S_OK; } #endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + // Minimum supported client Windows Vista + // Minimum supported server Windows Server 2008 + __DEFINE_THUNK( + dwmapi, + 8, + HRESULT, + STDAPICALLTYPE, + DwmGetCompositionTimingInfo, + _In_ HWND _hWnd, + _Out_ DWM_TIMING_INFO* _pTimingInfo + ) + { + if (auto const _pfnDwmGetCompositionTimingInfo = try_get_DwmGetCompositionTimingInfo()) + { + return _pfnDwmGetCompositionTimingInfo(_hWnd, _pTimingInfo); + } + + return DWM_E_COMPOSITIONDISABLED; + } +#endif } // namespace Thunks } // namespace YY diff --git a/src/Thunks/dxgi.hpp b/src/Thunks/dxgi.hpp index 95802c6..0ddafea 100644 --- a/src/Thunks/dxgi.hpp +++ b/src/Thunks/dxgi.hpp @@ -21,7 +21,33 @@ namespace YY::Thunks if (_ppFactory) *_ppFactory = nullptr; - return E_NOINTERFACE; + return DXGI_ERROR_UNSUPPORTED; + } +#endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + // Minimum supported client Windows Vista + // Minimum supported server Windows Server 2008 + __DEFINE_THUNK( + dxgi, + 8, + HRESULT, + STDAPICALLTYPE, + CreateDXGIFactory, + REFIID riid, + _COM_Outptr_ void** _ppFactory + ) + { + if (auto const _pfnCreateDXGIFactory = try_get_CreateDXGIFactory()) + { + return _pfnCreateDXGIFactory(riid, _ppFactory); + } + + if (_ppFactory) + *_ppFactory = nullptr; + return DXGI_ERROR_UNSUPPORTED; } #endif } diff --git a/src/Thunks/esent.hpp b/src/Thunks/esent.hpp new file mode 100644 index 0000000..6bfc572 --- /dev/null +++ b/src/Thunks/esent.hpp @@ -0,0 +1,379 @@ +#include + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) +#pragma comment(lib, "esent.lib") +#endif + +namespace YY::Thunks +{ +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + // Minimum supported client Windows Vista + // Minimum supported server Windows Server 2008 + __DEFINE_THUNK( + esent, + 16, + JET_ERR, + JET_API, + JetAttachDatabase2W, + _In_ JET_SESID sesid, + _In_ JET_PCWSTR szFilename, + _In_ const unsigned long cpgDatabaseSizeMax, + _In_ JET_GRBIT grbit + ) + { + if (auto const _pfnJetAttachDatabase2W = try_get_JetAttachDatabase2W()) + { + return _pfnJetAttachDatabase2W(sesid, szFilename, cpgDatabaseSizeMax, grbit); + } + + // 路径的话理论上MAX_PATH就足够了 + char szFilenameBufferA[512] = {}; + if (szFilename && *szFilename) + { + auto _iResult = WideCharToMultiByte(CP_ACP, 0, szFilename, -1, szFilenameBufferA, _countof(szFilenameBufferA), nullptr, nullptr); + if (_iResult <= 0) + { + return JET_errFileNotFound; + } + } + + return JetAttachDatabase2A(sesid, szFilename ? szFilenameBufferA : nullptr, cpgDatabaseSizeMax, grbit); + } +#endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + // Minimum supported client Windows Vista + // Minimum supported server Windows Server 2008 + __DEFINE_THUNK( + esent, + 16, + JET_ERR, + JET_API, + JetBeginSessionW, + _In_ JET_INSTANCE instance, + _Out_ JET_SESID* psesid, + _In_opt_ JET_PCWSTR szUserName, + _In_opt_ JET_PCWSTR szPassword + ) + { + if (auto const _pfnJetBeginSessionW = try_get_JetBeginSessionW()) + { + return _pfnJetBeginSessionW(instance, psesid, szUserName, szPassword); + } + + internal::StringBuffer _szUserNameBuffer; + if (szUserName || *szUserName) + { + auto _lStatus = internal::Convert(szUserName, -1, &_szUserNameBuffer); + if (_lStatus) + { + return JET_errcatMemory; + } + } + + internal::StringBuffer _szPasswordBuffer; + if (szPassword && *szPassword) + { + auto _lStatus = internal::Convert(szPassword, -1, &_szPasswordBuffer); + if (_lStatus) + { + return JET_errcatMemory; + } + } + return JetBeginSessionA(instance, psesid, szUserName ? _szUserNameBuffer.GetC_String() : nullptr, szPassword ? _szPasswordBuffer.GetC_String() : nullptr); + } +#endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + //Minimum supported client Windows Vista + //Minimum supported server Windows Server 2008 + __DEFINE_THUNK( + esent, + 8, + JET_ERR, + JET_API, + JetCreateInstanceW, + _Out_ JET_INSTANCE* pinstance, + _In_opt_ JET_PCWSTR szInstanceName + ) + { + if (auto const _pfnJetCreateInstanceW = try_get_JetCreateInstanceW()) + { + return _pfnJetCreateInstanceW(pinstance, szInstanceName); + } + internal::StringBuffer _szInstanceNameBuffer; + if (szInstanceName && *szInstanceName) + { + auto _lStatus = internal::Convert(szInstanceName, -1, &_szInstanceNameBuffer); + if (_lStatus) + { + return JET_errcatMemory; + } + } + return JetCreateInstanceA(pinstance, szInstanceName ? _szInstanceNameBuffer.GetC_String() : nullptr);; + } +#endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + // Minimum supported client Windows Vista + // Minimum supported server Windows Server 2008 + __DEFINE_THUNK( + esent, + 24, + JET_ERR, + JET_API, + JetGetTableColumnInfoW, + _In_ JET_SESID sesid, + _In_ JET_TABLEID tableid, + _In_opt_ JET_PCWSTR szColumnName, + _Out_writes_bytes_(cbMax) void* pvResult, + _In_ unsigned long cbMax, + _In_ unsigned long InfoLevel + ) + { + if (auto const _pfnJetGetTableColumnInfoW = try_get_JetGetTableColumnInfoW()) + { + return _pfnJetGetTableColumnInfoW(sesid, tableid, szColumnName, pvResult, cbMax, InfoLevel); + } + internal::StringBuffer _szColumnNameBuffer; + if (szColumnName && *szColumnName) + { + auto _lStatus = internal::Convert(szColumnName, -1, &_szColumnNameBuffer); + if (_lStatus) + { + return JET_errcatMemory; + } + } + return JetGetTableColumnInfoA(sesid, tableid, szColumnName ? _szColumnNameBuffer.GetC_String() : nullptr, pvResult, cbMax, InfoLevel); + } +#endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + // Minimum supported client Windows Vista + // Minimum supported server Windows Server 2008 + __DEFINE_THUNK( + esent, + 20, + JET_ERR, + JET_API, + JetOpenDatabaseW, + _In_ JET_SESID sesid, + _In_ JET_PCWSTR szFilename, + _In_opt_ JET_PCWSTR szConnect, + _Out_ JET_DBID* pdbid, + _In_ JET_GRBIT grbit + ) + { + if (auto const _pfnJetOpenDatabaseW = try_get_JetOpenDatabaseW()) + { + return _pfnJetOpenDatabaseW(sesid, szFilename, szConnect, pdbid, grbit); + } + + char szFileNameBuffer[512] = {}; + if (szFilename && *szFilename) + { + if (WideCharToMultiByte(CP_ACP, 0, szFilename, 01, szFileNameBuffer, _countof(szFileNameBuffer), nullptr, nullptr) <= 0) + { + return JET_errcatMemory; + } + } + + internal::StringBuffer _szConnectBuffer; + if (szConnect && *szConnect) + { + auto _lStatus = internal::Convert(szConnect, -1, &_szConnectBuffer); + if (_lStatus) + { + return JET_errFileNotFound; + } + } + + return JetOpenDatabaseA(sesid, szFilename ? szFileNameBuffer : nullptr, szConnect ? _szConnectBuffer.GetC_String() : nullptr, pdbid, grbit); + } +#endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + // Minimum supported client Windows Vista + // Minimum supported server Windows Server 2008 + __DEFINE_THUNK( + esent, + 28, + JET_ERR, + JET_API, + JetOpenTableW, + _In_ JET_SESID sesid, + _In_ JET_DBID dbid, + _In_ JET_PCWSTR szTableName, + _In_reads_bytes_opt_(cbParameters) const void* pvParameters, + _In_ unsigned long cbParameters, + _In_ JET_GRBIT grbit, + _Out_ JET_TABLEID* ptableid + ) + { + if (auto const _pfnJetOpenTableW = try_get_JetOpenTableW()) + { + return _pfnJetOpenTableW(sesid, dbid, szTableName, pvParameters, cbParameters, grbit, ptableid); + } + + internal::StringBuffer _szTableNameBuffer; + if (szTableName && *szTableName) + { + auto _lStatus = internal::Convert(szTableName, -1, &_szTableNameBuffer); + if (_lStatus) + { + return JET_errcatMemory; + } + } + + return JetOpenTableA(sesid, dbid, szTableName ? _szTableNameBuffer.GetC_String() : nullptr, pvParameters, cbParameters, grbit, ptableid); + } +#endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + //Minimum supported client Windows Vista + //Minimum supported server Windows Server 2008 + __DEFINE_THUNK( + esent, + 20, + JET_ERR, + JET_API, + JetSetSystemParameterW, + _Inout_opt_ JET_INSTANCE* pinstance, + _In_opt_ JET_SESID sesid, + _In_ unsigned long paramid, + _In_opt_ JET_API_PTR lParam, + _In_opt_ JET_PCWSTR szParam + ) + { + if (auto const _pfnJetSetSystemParameterW = try_get_JetSetSystemParameterW()) + { + return _pfnJetSetSystemParameterW(pinstance, sesid, paramid, lParam, szParam); + } + + internal::StringBuffer _szParamBuffer; + if (szParam && *szParam) + { + auto _lStatus = internal::Convert(szParam, -1, &_szParamBuffer); + if (_lStatus) + { + return JET_errcatMemory; + } + } + + return JetSetSystemParameterA(pinstance, sesid, paramid, lParam, szParam ? _szParamBuffer.GetC_String() : nullptr); + } +#endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + //Minimum supported client Windows Vista + //Minimum supported server Windows Server 2008 + __DEFINE_THUNK( + esent, + 24, + JET_ERR, + JET_API, + JetGetSystemParameterW, + _In_ JET_INSTANCE instance, + _In_opt_ JET_SESID sesid, + _In_ unsigned long paramid, + _Out_opt_ JET_API_PTR* plParam, + _Out_writes_bytes_opt_(cbMax) JET_PWSTR szParam, + _In_ unsigned long cbMax + ) + { + if (auto const _pfnJetGetSystemParameterW = try_get_JetGetSystemParameterW()) + { + return _pfnJetGetSystemParameterW(instance, sesid, paramid, plParam, szParam, cbMax); + } + + if (!szParam) + { + return JetGetSystemParameterA(instance, sesid, paramid, plParam, nullptr, cbMax); + } + + internal::StringBuffer _szParamBuffer; + auto _pBuffer = _szParamBuffer.GetBuffer(max(cbMax, 512)); + if (!_pBuffer) + { + return JET_errcatMemory; + } + memset(_pBuffer, 0, _szParamBuffer.uBufferLength); + + const auto _cchMax = cbMax / sizeof(szParam[0]); + + const auto _Error = JetGetSystemParameterA(instance, sesid, paramid, plParam, _pBuffer, _szParamBuffer.uBufferLength); + if (_Error == JET_errSuccess) + { + if (_pBuffer[_szParamBuffer.uBufferLength - 2]) + { + if (_cchMax) + { + const auto _iResult = MultiByteToWideChar(CP_ACP, 0, _pBuffer, _szParamBuffer.uBufferLength, szParam, _cchMax); + if (_iResult <= 0) + { + return JET_errInstanceUnavailable; + } + + szParam[min(_iResult, _cchMax - 1)] = L'\0'; + return JET_wrnBufferTruncated; + } + return JET_errBufferTooSmall; + } + else if (_pBuffer[0]) + { + if (_cchMax) + { + const auto _iResult = MultiByteToWideChar(CP_ACP, 0, _pBuffer, -1, szParam, _cchMax); + if (_iResult <= 0) + { + return JET_errInstanceUnavailable; + } + + if (_iResult < _cchMax) + { + szParam[_iResult] = L'\0'; + return JET_errSuccess; + } + else + { + szParam[_cchMax - 1] = L'\0'; + return JET_wrnBufferTruncated; + } + } + return JET_errBufferTooSmall; + } + } + else if (_Error == JET_wrnBufferTruncated) + { + if (_cchMax) + { + const auto _iResult = MultiByteToWideChar(CP_ACP, 0, _pBuffer, _szParamBuffer.uBufferLength, szParam, _cchMax); + if (_iResult <= 0) + { + return JET_errInstanceUnavailable; + } + + szParam[min(_iResult, _cchMax - 1)] = L'\0'; + return JET_wrnBufferTruncated; + } + return JET_errBufferTooSmall; + } + return _Error; + } +#endif +} //namespace YY::Thunks diff --git a/src/Thunks/shell32.hpp b/src/Thunks/shell32.hpp index 0f12957..6e00b81 100644 --- a/src/Thunks/shell32.hpp +++ b/src/Thunks/shell32.hpp @@ -1124,4 +1124,83 @@ namespace YY::Thunks return _hr; } #endif -} //namespace YY + + +#if (YY_Thunks_Support_Version < NTDDI_WIN7) + + // 最低受支持的客户端 Windows 7 [仅限桌面应用] + // 最低受支持的服务器 Windows Server 2008 R2[仅限桌面应用] + __DEFINE_THUNK( + shell32, + 12, + HRESULT, + STDAPICALLTYPE, + SHGetPropertyStoreForWindow, + _In_ HWND hwnd, + _In_ REFIID riid, + _Inout_ void** ppv + ) + { + if (auto const _pfnSHGetPropertyStoreForWindow = try_get_SHGetPropertyStoreForWindow()) + { + return _pfnSHGetPropertyStoreForWindow(hwnd, riid, ppv); + } + + if (ppv) + *ppv = nullptr; + + return E_NOTIMPL; + } +#endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + // 最低受支持的客户端 Windows Vista [仅限桌面应用] + // 最低受支持的服务器 Windows Server 2008[仅限桌面应用] + __DEFINE_THUNK( + shell32, + 8, + HRESULT, + STDAPICALLTYPE, + SHOpenWithDialog, + _In_ HWND hwndParent, + _In_ const OPENASINFO* poainfo + ) + { + if (auto const _pfnSHOpenWithDialog = try_get_SHOpenWithDialog()) + { + return _pfnSHOpenWithDialog(hwndParent, poainfo); + } + + return E_NOTIMPL; + } +#endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + // 最低受支持的客户端 Windows Vista [仅限桌面应用] + // 最低受支持的服务器 Windows Server 2008[仅限桌面应用] + __DEFINE_THUNK( + shell32, + 4, + HRESULT, + STDAPICALLTYPE, + SHQueryUserNotificationState, + _Out_ QUERY_USER_NOTIFICATION_STATE* pquns + ) + { + if (auto const _pfnSHQueryUserNotificationState = try_get_SHQueryUserNotificationState()) + { + return _pfnSHQueryUserNotificationState(pquns); + } + + if (!pquns) + return E_INVALIDARG; + + *pquns = QUNS_QUIET_TIME; + return S_OK; + } +#endif +} //namespace YY::Thunks diff --git a/src/Thunks/wevtapi.hpp b/src/Thunks/wevtapi.hpp new file mode 100644 index 0000000..3b79bb9 --- /dev/null +++ b/src/Thunks/wevtapi.hpp @@ -0,0 +1,140 @@ +#include + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) +#pragma comment(lib, "wevtapi.lib") +#endif + +namespace YY::Thunks +{ +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + // Minimum supported client Windows Vista [desktop apps only] + // Minimum supported server Windows Server 2008[desktop apps only] + __DEFINE_THUNK( + wevtapi, + 4, + BOOL, + WINAPI, + EvtClose, + _In_ _Post_invalid_ EVT_HANDLE Object + ) + { + if (auto const _pfnEvtClose = try_get_EvtClose()) + { + return _pfnEvtClose(Object); + } + + return TRUE; + } +#endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + // Minimum supported client Windows Vista [desktop apps only] + // Minimum supported server Windows Server 2008[desktop apps only] + __DEFINE_THUNK( + wevtapi, + 12, + EVT_HANDLE, + WINAPI, + EvtCreateRenderContext, + DWORD ValuePathsCount, + _In_reads_opt_(ValuePathsCount) LPCWSTR* ValuePaths, + DWORD Flags + ) + { + if (auto const _pfnEvtCreateRenderContext = try_get_EvtCreateRenderContext()) + { + return _pfnEvtCreateRenderContext(ValuePathsCount, ValuePaths, Flags); + } + + SetLastError(ERROR_NOT_SUPPORTED); + return NULL; + } +#endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + // Minimum supported client Windows Vista [desktop apps only] + // Minimum supported server Windows Server 2008[desktop apps only] + __DEFINE_THUNK( + wevtapi, + 24, + BOOL, + WINAPI, + EvtNext, + _In_ EVT_HANDLE ResultSet, + DWORD EventsSize, + _Out_writes_to_(EventsSize, *Returned) PEVT_HANDLE Events, + DWORD Timeout, + DWORD Flags, + _Out_range_(0, EventsSize) PDWORD Returned + ) + { + if (auto const _pfnEvtNext = try_get_EvtNext()) + { + return _pfnEvtNext(ResultSet, EventsSize, Events, Timeout, Flags, Returned); + } + + SetLastError(ERROR_NOT_SUPPORTED); + return FALSE; + } +#endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + // Minimum supported client Windows Vista [desktop apps only] + // Minimum supported server Windows Server 2008[desktop apps only] + __DEFINE_THUNK( + wevtapi, + 16, + EVT_HANDLE, + WINAPI, + EvtQuery, + _In_opt_ EVT_HANDLE Session, + _In_opt_z_ LPCWSTR Path, + _In_opt_z_ LPCWSTR Query, + DWORD Flags + ) + { + if (auto const _pfnEvtQuery = try_get_EvtQuery()) + { + return _pfnEvtQuery(Session, Path, Query, Flags); + } + SetLastError(ERROR_NOT_SUPPORTED); + return NULL; + } +#endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + // Minimum supported client Windows Vista [desktop apps only] + // Minimum supported server Windows Server 2008[desktop apps only] + __DEFINE_THUNK( + wevtapi, + 28, + BOOL, + WINAPI, + EvtRender, + _In_opt_ EVT_HANDLE Context, + _In_ EVT_HANDLE Fragment, + DWORD Flags, + DWORD BufferSize, + _Out_writes_bytes_to_opt_(BufferSize, *BufferUsed) PVOID Buffer, + _Out_ PDWORD BufferUsed, + _Out_ PDWORD PropertyCount + ) + { + if (auto const _pfnEvtRender = try_get_EvtRender()) + { + return _pfnEvtRender(Context, Fragment, Flags, BufferSize, Buffer, BufferUsed, PropertyCount); + } + SetLastError(ERROR_NOT_SUPPORTED); + return FALSE; + } +#endif +} //namespace YY::Thunks diff --git a/src/YY-Thunks.UnitTest/YY-Thunks.UnitTest.vcxproj b/src/YY-Thunks.UnitTest/YY-Thunks.UnitTest.vcxproj index 20e2e59..ad4a6fb 100644 --- a/src/YY-Thunks.UnitTest/YY-Thunks.UnitTest.vcxproj +++ b/src/YY-Thunks.UnitTest/YY-Thunks.UnitTest.vcxproj @@ -216,6 +216,7 @@ + @@ -231,6 +232,7 @@ + @@ -247,6 +249,7 @@ + @@ -287,7 +290,9 @@ + + diff --git a/src/YY-Thunks.UnitTest/YY-Thunks.UnitTest.vcxproj.filters b/src/YY-Thunks.UnitTest/YY-Thunks.UnitTest.vcxproj.filters index 05e8fe4..3a0d727 100644 --- a/src/YY-Thunks.UnitTest/YY-Thunks.UnitTest.vcxproj.filters +++ b/src/YY-Thunks.UnitTest/YY-Thunks.UnitTest.vcxproj.filters @@ -314,6 +314,24 @@ Thunks + + Thunks + + + Thunks + + + Thunks + + + Thunks + + + Thunks + + + Thunks + @@ -325,5 +343,11 @@ 资源文件 + + 源文件\def\x86 + + + 源文件\def\x64 + \ No newline at end of file diff --git a/src/def/x64/esent.def b/src/def/x64/esent.def new file mode 100644 index 0000000..a58db4e --- /dev/null +++ b/src/def/x64/esent.def @@ -0,0 +1,74 @@ +Windows Vista开始,新增了A后缀来代替统一表示ANSI版函数 + +[Symbols] +JetAddColumnA=JetAddColumn +JetAttachDatabaseA=JetAttachDatabase +JetAttachDatabase2A=JetAttachDatabase2 +JetAttachDatabaseWithStreamingA=JetAttachDatabaseWithStreaming +JetBackupA=JetBackup +JetBackupInstanceA=JetBackupInstance +JetBeginDatabaseIncrementalReseedA=JetBeginDatabaseIncrementalReseed +JetBeginSessionA=JetBeginSession +JetCompactA=JetCompact +JetConvertDDLA=JetConvertDDL +JetCreateDatabaseA=JetCreateDatabase +JetCreateDatabase2A=JetCreateDatabase2 +JetCreateDatabaseWithStreamingA=JetCreateDatabaseWithStreaming +JetCreateIndexA=JetCreateIndex +JetCreateIndex2A=JetCreateIndex2 +JetCreateInstanceA=JetCreateInstance +JetCreateInstance2A=JetCreateInstance2 +JetCreateTableA=JetCreateTable +JetCreateTableColumnIndexA=JetCreateTableColumnIndex +JetCreateTableColumnIndex2A=JetCreateTableColumnIndex2 +JetDBUtilitiesA=JetDBUtilities +JetDefragmentA=JetDefragment +JetDefragment2A=JetDefragment2 +JetDeleteColumnA=JetDeleteColumn +JetDeleteColumn2A=JetDeleteColumn2 +JetDeleteIndexA=JetDeleteIndex +JetDeleteTableA=JetDeleteTable +JetDetachDatabaseA=JetDetachDatabase +JetDetachDatabase2A=JetDetachDatabase2 +JetEnableMultiInstanceA=JetEnableMultiInstance +JetExternalRestoreA=JetExternalRestore +JetExternalRestore2A=JetExternalRestore2 +JetGetAttachInfoA=JetGetAttachInfo +JetGetAttachInfoInstanceA=JetGetAttachInfoInstance +JetGetColumnInfoA=JetGetColumnInfo +JetGetCurrentIndexA=JetGetCurrentIndex +JetGetDatabaseFileInfoA=JetGetDatabaseFileInfo +JetGetDatabaseInfoA=JetGetDatabaseInfo +JetGetIndexInfoA=JetGetIndexInfo +JetGetInstanceInfoA=JetGetInstanceInfo +JetGetLogInfoA=JetGetLogInfo +JetGetLogInfoInstanceA=JetGetLogInfoInstance +JetGetLogInfoInstance2A=JetGetLogInfoInstance2 +JetGetObjectInfoA=JetGetObjectInfo +JetGetSystemParameterA=JetGetSystemParameter +JetGetTableColumnInfoA=JetGetTableColumnInfo +JetGetTableIndexInfoA=JetGetTableIndexInfo +JetGetTableInfoA=JetGetTableInfo +JetGetTruncateLogInfoInstanceA=JetGetTruncateLogInfoInstance +JetInit3A=JetInit3 +JetInit4A=JetInit4 +JetOpenDatabaseA=JetOpenDatabase +JetOpenFileA=JetOpenFile +JetOpenFileInstanceA=JetOpenFileInstance +JetOpenFileSectionInstanceA=JetOpenFileSectionInstance +JetOpenTableA=JetOpenTable +JetOSSnapshotFreezeA=JetOSSnapshotFreeze +JetRenameColumnA=JetRenameColumn +JetRenameTableA=JetRenameTable +JetRestoreA=JetRestore +JetRestore2A=JetRestore2 +JetRestoreInstanceA=JetRestoreInstance +JetSetColumnDefaultValueA=JetSetColumnDefaultValue +JetSetCurrentIndexA=JetSetCurrentIndex +JetSetCurrentIndex2A=JetSetCurrentIndex2 +JetSetCurrentIndex3A=JetSetCurrentIndex3 +JetSetCurrentIndex4A=JetSetCurrentIndex4 +JetSetDatabaseSizeA=JetSetDatabaseSize +JetSetSystemParameterA=JetSetSystemParameter +JetSnapshotStartA=JetSnapshotStart +JetUpgradeDatabaseA=JetUpgradeDatabase diff --git a/src/def/x86/esent.def b/src/def/x86/esent.def new file mode 100644 index 0000000..8afb588 --- /dev/null +++ b/src/def/x86/esent.def @@ -0,0 +1,74 @@ +Windows Vista开始,新增了A后缀来代替统一表示ANSI版函数 + +[Symbols] +JetAddColumnA@28=JetAddColumn@28 +JetAttachDatabaseA@12=JetAttachDatabase@12 +JetAttachDatabase2A@16=JetAttachDatabase2@16 +JetAttachDatabaseWithStreamingA@24=JetAttachDatabaseWithStreaming@24 +JetBackupA@12=JetBackup@12 +JetBackupInstanceA@16=JetBackupInstance@16 +JetBeginDatabaseIncrementalReseedA@16=JetBeginDatabaseIncrementalReseed@16 +JetBeginSessionA@16=JetBeginSession@16 +JetCompactA@24=JetCompact@24 +JetConvertDDLA@20=JetConvertDDL@20 +JetCreateDatabaseA@20=JetCreateDatabase@20 +JetCreateDatabase2A@20=JetCreateDatabase2@20 +JetCreateDatabaseWithStreamingA@28=JetCreateDatabaseWithStreaming@28 +JetCreateIndexA@28=JetCreateIndex@28 +JetCreateIndex2A@16=JetCreateIndex2@16 +JetCreateInstanceA@8=JetCreateInstance@8 +JetCreateInstance2A@16=JetCreateInstance2@16 +JetCreateTableA@24=JetCreateTable@24 +JetCreateTableColumnIndexA@12=JetCreateTableColumnIndex@12 +JetCreateTableColumnIndex2A@12=JetCreateTableColumnIndex2@12 +JetDBUtilitiesA@4=JetDBUtilities@4 +JetDefragmentA@24=JetDefragment@24 +JetDefragment2A@28=JetDefragment2@28 +JetDeleteColumnA@12=JetDeleteColumn@12 +JetDeleteColumn2A@16=JetDeleteColumn2@16 +JetDeleteIndexA@12=JetDeleteIndex@12 +JetDeleteTableA@12=JetDeleteTable@12 +JetDetachDatabaseA@8=JetDetachDatabase@8 +JetDetachDatabase2A@12=JetDetachDatabase2@12 +JetEnableMultiInstanceA@12=JetEnableMultiInstance@12 +JetExternalRestoreA@32=JetExternalRestore@32 +JetExternalRestore2A@40=JetExternalRestore2@40 +JetGetAttachInfoA@12=JetGetAttachInfo@12 +JetGetAttachInfoInstanceA@16=JetGetAttachInfoInstance@16 +JetGetColumnInfoA@28=JetGetColumnInfo@28 +JetGetCurrentIndexA@16=JetGetCurrentIndex@16 +JetGetDatabaseFileInfoA@16=JetGetDatabaseFileInfo@16 +JetGetDatabaseInfoA@20=JetGetDatabaseInfo@20 +JetGetIndexInfoA@28=JetGetIndexInfo@28 +JetGetInstanceInfoA@8=JetGetInstanceInfo@8 +JetGetLogInfoA@12=JetGetLogInfo@12 +JetGetLogInfoInstanceA@16=JetGetLogInfoInstance@16 +JetGetLogInfoInstance2A@20=JetGetLogInfoInstance2@20 +JetGetObjectInfoA@32=JetGetObjectInfo@32 +JetGetSystemParameterA@24=JetGetSystemParameter@24 +JetGetTableColumnInfoA@24=JetGetTableColumnInfo@24 +JetGetTableIndexInfoA@24=JetGetTableIndexInfo@24 +JetGetTableInfoA@20=JetGetTableInfo@20 +JetGetTruncateLogInfoInstanceA@16=JetGetTruncateLogInfoInstance@16 +JetInit3A@12=JetInit3@12 +JetInit4A@12=JetInit4@12 +JetOpenDatabaseA@20=JetOpenDatabase@20 +JetOpenFileA@16=JetOpenFile@16 +JetOpenFileInstanceA@20=JetOpenFileInstance@20 +JetOpenFileSectionInstanceA@36=JetOpenFileSectionInstance@36 +JetOpenTableA@28=JetOpenTable@28 +JetOSSnapshotFreezeA@16=JetOSSnapshotFreeze@16 +JetRenameColumnA@20=JetRenameColumn@20 +JetRenameTableA@16=JetRenameTable@16 +JetRestoreA@8=JetRestore@8 +JetRestore2A@12=JetRestore2@12 +JetRestoreInstanceA@16=JetRestoreInstance@16 +JetSetColumnDefaultValueA@28=JetSetColumnDefaultValue@28 +JetSetCurrentIndexA@12=JetSetCurrentIndex@12 +JetSetCurrentIndex2A@16=JetSetCurrentIndex2@16 +JetSetCurrentIndex3A@20=JetSetCurrentIndex3@20 +JetSetCurrentIndex4A@24=JetSetCurrentIndex4@24 +JetSetDatabaseSizeA@16=JetSetDatabaseSize@16 +JetSetSystemParameterA@20=JetSetSystemParameter@20 +JetSnapshotStartA@12=JetSnapshotStart@12 +JetUpgradeDatabaseA@16=JetUpgradeDatabase@16