From de52011794fc1b41ac1fab00a863165a375881d0 Mon Sep 17 00:00:00 2001 From: mingkuang Date: Sat, 1 Jun 2024 22:22:56 +0800 Subject: [PATCH] =?UTF-8?q?Fea=20#30,=20=E4=B8=BALLD=E6=B7=BB=E5=8A=A0lib?= =?UTF-8?q?=E4=BE=9D=E8=B5=96=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build&Test.yml | 3 +- src/Build.cmd | 74 +- src/Thunks/YY_Thunks.cpp | 30 +- src/Thunks/YY_Thunks.h | 6 +- src/Thunks/api-ms-win-core-synch.hpp | 3891 ++++++++--------- .../YY.Depends.Analyzer.cpp | 2 +- 6 files changed, 2026 insertions(+), 1980 deletions(-) diff --git a/.github/workflows/Build&Test.yml b/.github/workflows/Build&Test.yml index 7120343..15cd4b4 100644 --- a/.github/workflows/Build&Test.yml +++ b/.github/workflows/Build&Test.yml @@ -19,7 +19,7 @@ jobs: &7z e Bin\Procdump.zip "-o$Env:GITHUB_WORKSPACE\Bin" - Invoke-WebRequest -Uri https://github.com/Chuyu-Team/LibMaker/releases/download/v1.0.2/LibMaker.exe -OutFile Bin\LibMaker.exe + Invoke-WebRequest -Uri https://github.com/Chuyu-Team/LibMaker/releases/download/v1.0.3/LibMaker.exe -OutFile Bin\LibMaker.exe Invoke-WebRequest -Uri https://github.com/Chuyu-Team/YY-Thunks/releases/download/v1.0.2.8/MinimumRequiredVersionHelper.exe -OutFile Bin\MinimumRequiredVersionHelper.exe $ProgramFiles = ${env:ProgramFiles(x86)} @@ -163,6 +163,7 @@ jobs: pushd ".\src\YY.Depends.Analyzer" 7z a -tzip %GITHUB_WORKSPACE%\YY-Thunks-${{env.BuildVersion}}-Binary.zip Config popd + 7z a -tzip %GITHUB_WORKSPACE%\YY-Thunks-${{env.BuildVersion}}-Lib-Binary.zip Lib LICENSE ReadMe.md ThunksList.md ::鎵撳寘Nuget if "${{env.BuildVersion}}" NEQ "" ( diff --git a/src/Build.cmd b/src/Build.cmd index 632d004..7992223 100644 --- a/src/Build.cmd +++ b/src/Build.cmd @@ -41,38 +41,76 @@ if defined DEF_FILES goto :AppendWeak goto:eof +:: BuildObj 6.0.6000.0 NTDDI_WIN6 1.def+2.def +:BuildLib +md "Lib\\%1\\%Platform%" + +cl /O1 /Os /Oi /GS- /std:c++17 /arch:IA32 /Z7 /MT /Fo"Lib\\%1\\%Platform%\\YY_Thunks_for_%1.obj" /Zl /c /D "NDEBUG" /D "YY_Thunks_Support_Version=%2" /D "__FALLBACK_PREFIX=YY_Thunks_" "%~dp0Thunks\YY_Thunks.cpp" + +::生成weak符号,一些非必须符号安排为weak可以避免链接失败 +LibMaker.exe FixObj "%~dp0..\\Lib\\%1\\%Platform%\\YY_Thunks_for_%1.obj" /WeakExternFix:__security_cookie=%PointType% /WeakExternFix:__YY_Thunks_Process_Terminating=4 /WeakExternFix:__acrt_atexit_table=%PointType% /WeakExternFix:__pfnDllMainCRTStartupForYY_Thunks=%PointType% + +if "%3"=="" goto:BuildWeak +set DEF_FILES=%3 +:AppendWeakByLib +for /f "tokens=1* delims=+" %%a in ("%DEF_FILES%") do ( + echo "AppendWeak %~dp0def\\%Platform%\\%%a" + LibMaker.exe /PREFIX:YY_Thunks_ AppendWeak /MACHINE:%Platform% /DEF:"%~dp0def\\%Platform%\\%%a" /OUT:"%~dp0..\\Lib\\%1\\%Platform%\\YY_Thunks_for_%1.obj" + set DEF_FILES=%%b +) + +if defined DEF_FILES goto:AppendWeakByLib +:BuildWeak + +set "SupportApiSet=/SupportApiSet" +:: XP ~ Win7不支持API Set +if "%1"=="5.1.2600.0" (set "SupportApiSet=") +if "%1"=="5.2.3790.0" (set "SupportApiSet=") +if "%1"=="6.0.6000.0" (set "SupportApiSet=") +if "%1"=="6.1.7600.0" (set "SupportApiSet=") + +LibMaker.exe %SupportApiSet% /PREFIX:YY_Thunks_ BuildYY_ThunksLibraries "%~dp0..\\Lib\\%1\\%Platform%\\YY_Thunks_for_%1.obj" "%WindowsSdkDir%\\Lib\\%WindowsSDKLibVersion%\\um\\%Platform%" "%~dp0..\\Lib\\%1\\%Platform%" + +goto:eof + +:: 6.0.6000.0 YY_Thunks_for_Vista.obj NTDDI_WIN6 1.def+2.def +:BuildX +call:BuildObj %2 %3 %4 +call:BuildLib %1 %3 %4 +goto:eof + :Buildx86 set PointType=4 -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 PSAPI2Kernel32.def -call:BuildObj YY_Thunks_for_Win7.obj NTDDI_WIN7 -call:BuildObj YY_Thunks_for_Win8.obj NTDDI_WIN8 -call:BuildObj YY_Thunks_for_Win10.0.10240.obj NTDDI_WIN10 -call:BuildObj YY_Thunks_for_Win10.0.19041.obj NTDDI_WIN10_VB +call:BuildX 5.0.2195.0 YY_Thunks_for_Win2K.obj NTDDI_WIN2K PSAPI2Kernel32.def+esent.def +call:BuildX 5.1.2600.0 YY_Thunks_for_WinXP.obj NTDDI_WINXP PSAPI2Kernel32.def+esent.def +call:BuildX 6.0.6000.0 YY_Thunks_for_Vista.obj NTDDI_WIN6 PSAPI2Kernel32.def +call:BuildX 6.1.7600.0 YY_Thunks_for_Win7.obj NTDDI_WIN7 +call:BuildX 6.2.9200.0 YY_Thunks_for_Win8.obj NTDDI_WIN8 +call:BuildX 10.0.10240.0 YY_Thunks_for_Win10.0.10240.obj NTDDI_WIN10 +call:BuildX 10.0.19041.0 YY_Thunks_for_Win10.0.19041.obj NTDDI_WIN10_VB goto:eof :Buildx64 set PointType=8 -call:BuildObj YY_Thunks_for_WinXP.obj NTDDI_WS03SP1 PSAPI2Kernel32.def+esent.def -call:BuildObj YY_Thunks_for_Vista.obj NTDDI_WIN6 PSAPI2Kernel32.def -call:BuildObj YY_Thunks_for_Win7.obj NTDDI_WIN7 -call:BuildObj YY_Thunks_for_Win8.obj NTDDI_WIN8 -call:BuildObj YY_Thunks_for_Win10.0.10240.obj NTDDI_WIN10 -call:BuildObj YY_Thunks_for_Win10.0.19041.obj NTDDI_WIN10_VB +call:BuildX 5.2.3790.1180 YY_Thunks_for_WinXP.obj NTDDI_WS03SP1 PSAPI2Kernel32.def+esent.def +call:BuildX 6.0.6000.0 YY_Thunks_for_Vista.obj NTDDI_WIN6 PSAPI2Kernel32.def +call:BuildX 6.1.7600.0 YY_Thunks_for_Win7.obj NTDDI_WIN7 +call:BuildX 6.2.9200.0 YY_Thunks_for_Win8.obj NTDDI_WIN8 +call:BuildX 10.0.10240.0 YY_Thunks_for_Win10.0.10240.obj NTDDI_WIN10 +call:BuildX 10.0.19041.0 YY_Thunks_for_Win10.0.19041.obj NTDDI_WIN10_VB goto:eof :Buildarm set PointType=4 -call:BuildObj YY_Thunks_for_Win8.obj NTDDI_WIN8 -call:BuildObj YY_Thunks_for_Win10.0.10240.obj NTDDI_WIN10 -call:BuildObj YY_Thunks_for_Win10.0.19041.obj NTDDI_WIN10_VB +call:BuildX 6.2.9200.0 YY_Thunks_for_Win8.obj NTDDI_WIN8 +call:BuildX 10.0.10240.0 YY_Thunks_for_Win10.0.10240.obj NTDDI_WIN10 +call:BuildX 10.0.19041.0 YY_Thunks_for_Win10.0.19041.obj NTDDI_WIN10_VB goto:eof :Buildarm64 set PointType=8 ; NTDDI_WIN10_RS3 = 16299 -call:BuildObj YY_Thunks_for_Win10.0.10240.obj NTDDI_WIN10_RS3 -call:BuildObj YY_Thunks_for_Win10.0.19041.obj NTDDI_WIN10_VB +call:BuildX 10.0.10240.0 YY_Thunks_for_Win10.0.10240.obj NTDDI_WIN10_RS3 +call:BuildX 10.0.19041.0 YY_Thunks_for_Win10.0.19041.obj NTDDI_WIN10_VB goto:eof diff --git a/src/Thunks/YY_Thunks.cpp b/src/Thunks/YY_Thunks.cpp index 3e19fbf..b44c6d7 100644 --- a/src/Thunks/YY_Thunks.cpp +++ b/src/Thunks/YY_Thunks.cpp @@ -186,13 +186,18 @@ RtlCutoverTimeToSystemTime( #include +#ifndef __FALLBACK_PREFIX +#define __FALLBACK_PREFIX +#endif + //灞曞紑鍑芥暟鐨勬墍鏈夌殑 澹版槑 浠ュ強 try_get_ 鍑芥暟 -#define __DEFINE_THUNK(_MODULE, _SIZE, _RETURN_, _CONVENTION_, _FUNCTION, ...) \ - __APPLY_UNIT_TEST_BOOL(_FUNCTION); \ - EXTERN_C _RETURN_ _CONVENTION_ _FUNCTION(__VA_ARGS__); \ - static decltype(_FUNCTION)* __cdecl _CRT_CONCATENATE(try_get_, _FUNCTION)() noexcept; \ +#define __DEFINE_THUNK_EXTERN_PREFIX(_PREFIX, _MODULE, _SIZE, _RETURN_, _CONVENTION_, _FUNCTION, ...) \ + __APPLY_UNIT_TEST_BOOL(_FUNCTION); \ + EXTERN_C _RETURN_ _CONVENTION_ _CRT_CONCATENATE_(_PREFIX, _FUNCTION)(__VA_ARGS__); \ + static decltype(_CRT_CONCATENATE_(_PREFIX, _FUNCTION))* __cdecl _CRT_CONCATENATE(try_get_, _FUNCTION)() noexcept; \ __if_not_exists(_CRT_CONCATENATE(try_get_, _FUNCTION)) +#define __DEFINE_THUNK(_MODULE, _SIZE, _RETURN_, _CONVENTION_, _FUNCTION, ...) __DEFINE_THUNK_EXTERN_PREFIX(__FALLBACK_PREFIX, _MODULE, _SIZE, _RETURN_, _CONVENTION_, _FUNCTION, __VA_ARGS__) #include "Thunks\YY_Thunks_List.hpp" @@ -781,10 +786,13 @@ namespace YY::Thunks::internal #include "ThreadRunner.h" +#define _DEFINE_IAT_SYMBOL_PREFIX(_PREFIX, _FUNCTION, _SIZE) _LCRT_DEFINE_IAT_SYMBOL(_PREFIX ## _FUNCTION, _SIZE) +#define _YY_THUNKS_DEFINE_RUST_RAW_DYLIB_IAT_SYMBOL_PREFIX(_PREFIX, _FUNCTION, _SIZE) _YY_THUNKS_DEFINE_RUST_RAW_DYLIB_IAT_SYMBOL(_FUNCTION, _SIZE, _PREFIX ## _FUNCTION) + //瀵煎叆瀹為檯鐨勫疄鐜 #define YY_Thunks_Implemented -#define __DEFINE_THUNK(_MODULE, _SIZE, _RETURN_, _CONVENTION_, _FUNCTION, ...) \ - static decltype(_FUNCTION)* __cdecl _CRT_CONCATENATE(try_get_, _FUNCTION)() noexcept \ +#define __DEFINE_THUNK_IMP_PREFIX(_PREFIX, _MODULE, _SIZE, _RETURN_, _CONVENTION_, _FUNCTION, ...) \ + static decltype(_CRT_CONCATENATE_(_PREFIX, _FUNCTION))* __cdecl _CRT_CONCATENATE(try_get_, _FUNCTION)() noexcept \ { \ __CHECK_UNIT_TEST_BOOL(_FUNCTION); \ __declspec(allocate(".YYThr$AAA")) static void* _CRT_CONCATENATE(pInit_ ,_FUNCTION) = \ @@ -801,13 +809,15 @@ __if_exists(YY::Thunks::Fallback::_CRT_CONCATENATE(try_get_, _FUNCTION)) &YY::Thunks::Fallback::_CRT_CONCATENATE(try_get_, _FUNCTION) \ } \ }; \ - return reinterpret_cast(try_get_function( \ + return reinterpret_cast(try_get_function( \ &_CRT_CONCATENATE(pFun_ ,_FUNCTION), \ _ProcInfo)); \ } \ - _LCRT_DEFINE_IAT_SYMBOL(_FUNCTION, _SIZE); \ - _YY_THUNKS_DEFINE_RUST_RAW_DYLIB_IAT_SYMBOL(_FUNCTION, _SIZE); \ - EXTERN_C _RETURN_ _CONVENTION_ _FUNCTION(__VA_ARGS__) + _DEFINE_IAT_SYMBOL_PREFIX(_PREFIX, _FUNCTION, _SIZE); \ + _YY_THUNKS_DEFINE_RUST_RAW_DYLIB_IAT_SYMBOL_PREFIX(_PREFIX, _FUNCTION, _SIZE); \ + EXTERN_C _RETURN_ _CONVENTION_ _CRT_CONCATENATE_(_PREFIX, _FUNCTION)(__VA_ARGS__) + +#define __DEFINE_THUNK(_MODULE, _SIZE, _RETURN_, _CONVENTION_, _FUNCTION, ...) __DEFINE_THUNK_IMP_PREFIX(__FALLBACK_PREFIX, _MODULE, _SIZE, _RETURN_, _CONVENTION_, _FUNCTION, __VA_ARGS__) #include "YY_Thunks_List.hpp" diff --git a/src/Thunks/YY_Thunks.h b/src/Thunks/YY_Thunks.h index fb28672..f4862d1 100644 --- a/src/Thunks/YY_Thunks.h +++ b/src/Thunks/YY_Thunks.h @@ -34,12 +34,12 @@ #if defined(_M_IX86) // 鏍规嵁 https://github.com/Chuyu-Team/YY-Thunks/issues/78 淇涓涓媟ust raw-dylib寮曠敤瑙勫垯 -#define _YY_THUNKS_DEFINE_RUST_RAW_DYLIB_IAT_SYMBOL(_FUNCTION, _SIZE) \ +#define _YY_THUNKS_DEFINE_RUST_RAW_DYLIB_IAT_SYMBOL(_FUNCTION, _SIZE, _FUNCTION_ADDRESS) \ __pragma(warning(suppress:4483)) \ extern "C" __declspec(selectany) void const* const __identifier(_CRT_STRINGIZE_(_imp_ ## _FUNCTION)) \ - = reinterpret_cast(_FUNCTION) + = reinterpret_cast(_FUNCTION_ADDRESS) #else -#define _YY_THUNKS_DEFINE_RUST_RAW_DYLIB_IAT_SYMBOL(_FUNCTION, _SIZE) +#define _YY_THUNKS_DEFINE_RUST_RAW_DYLIB_IAT_SYMBOL(_FUNCTION, _SIZE, _FUNCTION_ADDRESS) #endif #ifdef __YY_Thunks_Unit_Test diff --git a/src/Thunks/api-ms-win-core-synch.hpp b/src/Thunks/api-ms-win-core-synch.hpp index 7c6225f..adf1a42 100644 --- a/src/Thunks/api-ms-win-core-synch.hpp +++ b/src/Thunks/api-ms-win-core-synch.hpp @@ -109,283 +109,312 @@ static_assert(sizeof(SYNCHRONIZATION_BARRIER) >= sizeof(YY_BARRIER), "蹇呴』璺 #endif - -namespace YY +#ifdef YY_Thunks_Implemented +namespace YY::Thunks::internal { - namespace Thunks + namespace { -#ifdef YY_Thunks_Implemented - namespace internal + static HANDLE __fastcall GetGlobalKeyedEventHandle() { - static HANDLE __fastcall GetGlobalKeyedEventHandle() - { #if (YY_Thunks_Support_Version < NTDDI_WIN6) - //Windows XP绛夊钩鍙板垯 浣跨敤绯荤粺鑷韩鐨 CritSecOutOfMemoryEvent锛孷ista鎴栬呮洿楂樺钩鍙 鎴戜滑鐩存帴杩斿洖 nullptr 鍗冲彲銆 - if (NtCurrentTeb()->ProcessEnvironmentBlock->OSMajorVersion < 6) + //Windows XP绛夊钩鍙板垯 浣跨敤绯荤粺鑷韩鐨 CritSecOutOfMemoryEvent锛孷ista鎴栬呮洿楂樺钩鍙 鎴戜滑鐩存帴杩斿洖 nullptr 鍗冲彲銆 + if (NtCurrentTeb()->ProcessEnvironmentBlock->OSMajorVersion < 6) + { + if (_GlobalKeyedEventHandle == nullptr) { - if (_GlobalKeyedEventHandle == nullptr) - { - auto pNtOpenKeyedEvent = try_get_NtOpenKeyedEvent(); + auto pNtOpenKeyedEvent = try_get_NtOpenKeyedEvent(); - if(pNtOpenKeyedEvent == nullptr) - RaiseStatus(STATUS_RESOURCE_NOT_OWNED); + if(pNtOpenKeyedEvent == nullptr) + RaiseStatus(STATUS_RESOURCE_NOT_OWNED); - constexpr const wchar_t Name[] = L"\\KernelObjects\\CritSecOutOfMemoryEvent"; + constexpr const wchar_t Name[] = L"\\KernelObjects\\CritSecOutOfMemoryEvent"; - UNICODE_STRING ObjectName = {sizeof(Name) - sizeof(wchar_t),sizeof(Name) - sizeof(wchar_t) ,(PWSTR)Name }; - OBJECT_ATTRIBUTES attr = { sizeof(attr),nullptr,&ObjectName }; + UNICODE_STRING ObjectName = {sizeof(Name) - sizeof(wchar_t),sizeof(Name) - sizeof(wchar_t) ,(PWSTR)Name }; + OBJECT_ATTRIBUTES attr = { sizeof(attr),nullptr,&ObjectName }; - HANDLE KeyedEventHandle; - - if (pNtOpenKeyedEvent(&KeyedEventHandle, MAXIMUM_ALLOWED, &attr) < 0) - { - RaiseStatus(STATUS_RESOURCE_NOT_OWNED); - } + HANDLE KeyedEventHandle; - if (InterlockedCompareExchange((size_t*)&_GlobalKeyedEventHandle, (size_t)KeyedEventHandle, (size_t)nullptr)) - { - CloseHandle(KeyedEventHandle); - } + if (pNtOpenKeyedEvent(&KeyedEventHandle, MAXIMUM_ALLOWED, &attr) < 0) + { + RaiseStatus(STATUS_RESOURCE_NOT_OWNED); } - return _GlobalKeyedEventHandle; + if (InterlockedCompareExchange((size_t*)&_GlobalKeyedEventHandle, (size_t)KeyedEventHandle, (size_t)nullptr)) + { + CloseHandle(KeyedEventHandle); + } } -#endif - //Vista浠ヤ笂骞冲彴鏀寔缁 KeyedEvent鐩存帴浼 nullptr - return nullptr; + + return _GlobalKeyedEventHandle; } +#endif + //Vista浠ヤ笂骞冲彴鏀寔缁 KeyedEvent鐩存帴浼 nullptr + return nullptr; + } #if (YY_Thunks_Support_Version < NTDDI_WIN6) - static void __fastcall RtlpWakeSRWLock(SRWLOCK* SRWLock, size_t Status) - { - auto GlobalKeyedEventHandle = GetGlobalKeyedEventHandle(); - auto pNtReleaseKeyedEvent = try_get_NtReleaseKeyedEvent(); + static void __fastcall RtlpWakeSRWLock(SRWLOCK* SRWLock, size_t Status) + { + auto GlobalKeyedEventHandle = GetGlobalKeyedEventHandle(); + auto pNtReleaseKeyedEvent = try_get_NtReleaseKeyedEvent(); - if (!pNtReleaseKeyedEvent) - { - RaiseStatus(STATUS_RESOURCE_NOT_OWNED); - } + if (!pNtReleaseKeyedEvent) + { + RaiseStatus(STATUS_RESOURCE_NOT_OWNED); + } - for (;;) + for (;;) + { + if ((Status & YY_SRWLOCK_Locked) == 0) { - if ((Status & YY_SRWLOCK_Locked) == 0) - { - //寰蒋灏变笉鍒ゆ柇涓嬬┖鎸囬拡锛熷姝よ嚜淇★紵 - auto pWatiBlock = YY_SRWLOCK_GET_BLOCK(Status); + //寰蒋灏变笉鍒ゆ柇涓嬬┖鎸囬拡锛熷姝よ嚜淇★紵 + auto pWatiBlock = YY_SRWLOCK_GET_BLOCK(Status); - YY_SRWLOCK_WAIT_BLOCK* notify; + YY_SRWLOCK_WAIT_BLOCK* notify; - for (auto pBlock = pWatiBlock; (notify = pBlock->notify) == nullptr;) - { - auto back = pBlock->back; - back->next = pBlock; + for (auto pBlock = pWatiBlock; (notify = pBlock->notify) == nullptr;) + { + auto back = pBlock->back; + back->next = pBlock; - pBlock = back; - } + pBlock = back; + } - pWatiBlock->notify = notify; + pWatiBlock->notify = notify; - //鍒ゆ柇鏄惁鏄竴涓嫭鍗犻摼 - if (notify->next && (notify->flag & 1)) - { - pWatiBlock->notify = notify->next; - notify->next = nullptr; + //鍒ゆ柇鏄惁鏄竴涓嫭鍗犻摼 + if (notify->next && (notify->flag & 1)) + { + pWatiBlock->notify = notify->next; + notify->next = nullptr; - //SRWLock & (~YY_SRWLOCK_Waking) + //SRWLock & (~YY_SRWLOCK_Waking) #ifdef _WIN64 - _InterlockedAnd64((volatile LONG_PTR *)SRWLock, ~LONG_PTR(YY_SRWLOCK_Waking)); + _InterlockedAnd64((volatile LONG_PTR *)SRWLock, ~LONG_PTR(YY_SRWLOCK_Waking)); #else - _InterlockedAnd((volatile LONG_PTR *)SRWLock, ~LONG_PTR(YY_SRWLOCK_Waking)); + _InterlockedAnd((volatile LONG_PTR *)SRWLock, ~LONG_PTR(YY_SRWLOCK_Waking)); #endif - if (!InterlockedBitTestAndReset((volatile LONG*)¬ify->flag, 1)) - { - //鍧楀浜庣瓑寰呯姸鎬侊紝鎴戜滑杩涜绾跨▼鍞ら啋 + if (!InterlockedBitTestAndReset((volatile LONG*)¬ify->flag, 1)) + { + //鍧楀浜庣瓑寰呯姸鎬侊紝鎴戜滑杩涜绾跨▼鍞ら啋 - //if(!RtlpWaitCouldDeadlock()) + //if(!RtlpWaitCouldDeadlock()) - pNtReleaseKeyedEvent(GlobalKeyedEventHandle, notify, 0, nullptr); - } - - return; + pNtReleaseKeyedEvent(GlobalKeyedEventHandle, notify, 0, nullptr); } - else - { - //绛夊緟鐨勬槸涓涓叡浜攣锛岄偅涔堝敜閱掓墍鏈夌瓑寰呯殑鍏变韩閿併 - auto NewStatus = InterlockedCompareExchange((volatile size_t *)SRWLock, 0, Status); - if (NewStatus == Status) - { - //鏇存柊鎴愬姛锛 - for (; notify;) - { - auto next = notify->next; + return; + } + else + { + //绛夊緟鐨勬槸涓涓叡浜攣锛岄偅涔堝敜閱掓墍鏈夌瓑寰呯殑鍏变韩閿併 + auto NewStatus = InterlockedCompareExchange((volatile size_t *)SRWLock, 0, Status); + if (NewStatus == Status) + { + //鏇存柊鎴愬姛锛 + for (; notify;) + { + auto next = notify->next; - if (!InterlockedBitTestAndReset((volatile LONG*)¬ify->flag, 1)) - { - //鍧楀浜庣瓑寰呯姸鎬侊紝鎴戜滑杩涜绾跨▼鍞ら啋 - //if(!RtlpWaitCouldDeadlock()) + if (!InterlockedBitTestAndReset((volatile LONG*)¬ify->flag, 1)) + { + //鍧楀浜庣瓑寰呯姸鎬侊紝鎴戜滑杩涜绾跨▼鍞ら啋 - pNtReleaseKeyedEvent(GlobalKeyedEventHandle, notify, 0, nullptr); - } + //if(!RtlpWaitCouldDeadlock()) - notify = next; + pNtReleaseKeyedEvent(GlobalKeyedEventHandle, notify, 0, nullptr); } - return; + notify = next; } - Status = NewStatus; - } - - pWatiBlock->notify = notify; - } - else - { - auto NewStatus = InterlockedCompareExchange((volatile size_t*)SRWLock, Status & ~YY_SRWLOCK_Waking, Status); - if (NewStatus == Status) return; + } Status = NewStatus; } + + pWatiBlock->notify = notify; + } + else + { + auto NewStatus = InterlockedCompareExchange((volatile size_t*)SRWLock, Status & ~YY_SRWLOCK_Waking, Status); + if (NewStatus == Status) + return; + + Status = NewStatus; } } + } - static void __fastcall RtlpOptimizeSRWLockList(SRWLOCK* SRWLock, size_t Status) + static void __fastcall RtlpOptimizeSRWLockList(SRWLOCK* SRWLock, size_t Status) + { + for (;;) { - for (;;) + if (Status & YY_SRWLOCK_Locked) { - if (Status & YY_SRWLOCK_Locked) + if (auto WatiBlock = (YY_SRWLOCK_WAIT_BLOCK*)(Status & (~YY_SRWLOCK_MASK))) { - if (auto WatiBlock = (YY_SRWLOCK_WAIT_BLOCK*)(Status & (~YY_SRWLOCK_MASK))) - { - auto pBlock = WatiBlock; - - for (; pBlock->notify == nullptr;) - { - auto back = pBlock->back; - back->next = pBlock; + auto pBlock = WatiBlock; - pBlock = back; - } + for (; pBlock->notify == nullptr;) + { + auto back = pBlock->back; + back->next = pBlock; - WatiBlock->notify = pBlock->notify; + pBlock = back; } - //寰蒋涓轰粈涔堢敤 Status - YY_SRWLOCK_Waking锛岃屼负浠涔堜笉鐢 Status & ~YY_SRWLOCK_Waking 锛 - auto CurrentStatus = InterlockedCompareExchange((volatile size_t *)SRWLock, Status - YY_SRWLOCK_Waking, Status); - if (CurrentStatus == Status) - break; - - Status = CurrentStatus; + WatiBlock->notify = pBlock->notify; } - else - { - RtlpWakeSRWLock(SRWLock, Status); + + //寰蒋涓轰粈涔堢敤 Status - YY_SRWLOCK_Waking锛岃屼负浠涔堜笉鐢 Status & ~YY_SRWLOCK_Waking 锛 + auto CurrentStatus = InterlockedCompareExchange((volatile size_t *)SRWLock, Status - YY_SRWLOCK_Waking, Status); + if (CurrentStatus == Status) break; - } + + Status = CurrentStatus; + } + else + { + RtlpWakeSRWLock(SRWLock, Status); + break; } } + } - //灏嗙瓑寰呭潡鎻掑叆 SRWLock 涓 - static BOOL __fastcall RtlpQueueWaitBlockToSRWLock(YY_CV_WAIT_BLOCK* pBolck, PSRWLOCK SRWLock, DWORD SRWLockMark) + //灏嗙瓑寰呭潡鎻掑叆 SRWLock 涓 + static BOOL __fastcall RtlpQueueWaitBlockToSRWLock(YY_CV_WAIT_BLOCK* pBolck, PSRWLOCK SRWLock, DWORD SRWLockMark) + { + for (;;) { - for (;;) + auto Current = *(volatile size_t*)SRWLock; + + if ((Current & 0x1) == 0) + break; + + + if (SRWLockMark == 0) + { + pBolck->flag |= 0x1; + } + else if ((Current & 0x2) == 0 && YY_SRWLOCK_GET_BLOCK(Current)) { - auto Current = *(volatile size_t*)SRWLock; + return FALSE; + } - if ((Current & 0x1) == 0) - break; + pBolck->next = nullptr; + size_t New; - if (SRWLockMark == 0) - { - pBolck->flag |= 0x1; - } - else if ((Current & 0x2) == 0 && YY_SRWLOCK_GET_BLOCK(Current)) - { - return FALSE; - } + if (Current & 0x2) + { + pBolck->notify = nullptr; + pBolck->shareCount = 0; - pBolck->next = nullptr; + //_YY_CV_WAIT_BLOCK 缁撴瀯浣撹窡 _YY_SRWLOCK_WAIT_BLOCK鍏煎锛屾墍浠ヨ兘杩欐牱寮鸿浆 + pBolck->back = (_YY_CV_WAIT_BLOCK*)YY_SRWLOCK_GET_BLOCK(Current); - size_t New; + New = size_t(pBolck) | (Current & YY_CV_MASK); + } + else + { + auto shareCount = Current >> 4; - if (Current & 0x2) - { - pBolck->notify = nullptr; - pBolck->shareCount = 0; + pBolck->shareCount = shareCount; + pBolck->notify = pBolck; + New = shareCount <= 1 ? (size_t(pBolck) | 0x3) : (size_t(pBolck) | 0xB); + } - //_YY_CV_WAIT_BLOCK 缁撴瀯浣撹窡 _YY_SRWLOCK_WAIT_BLOCK鍏煎锛屾墍浠ヨ兘杩欐牱寮鸿浆 - pBolck->back = (_YY_CV_WAIT_BLOCK*)YY_SRWLOCK_GET_BLOCK(Current); + //娓呮碃 鍙戠幇鐨凚ug锛屾垜浠簲璇ヨ繑鍥 TRUE锛屽噺灏戝繀瑕佺殑鍐呮牳绛夊緟銆 + if (InterlockedCompareExchange((volatile size_t*)SRWLock, New, Current) == Current) + return TRUE; - New = size_t(pBolck) | (Current & YY_CV_MASK); - } - else - { - auto shareCount = Current >> 4; + //RtlBackoff(&v7); + YieldProcessor(); + } - pBolck->shareCount = shareCount; - pBolck->notify = pBolck; - New = shareCount <= 1 ? (size_t(pBolck) | 0x3) : (size_t(pBolck) | 0xB); - } + return FALSE; + } - //娓呮碃 鍙戠幇鐨凚ug锛屾垜浠簲璇ヨ繑鍥 TRUE锛屽噺灏戝繀瑕佺殑鍐呮牳绛夊緟銆 - if (InterlockedCompareExchange((volatile size_t*)SRWLock, New, Current) == Current) - return TRUE; - //RtlBackoff(&v7); - YieldProcessor(); - } + static void __fastcall RtlpWakeConditionVariable(PCONDITION_VARIABLE ConditionVariable, size_t ConditionVariableStatus, size_t WakeCount) + { + auto GlobalKeyedEventHandle = GetGlobalKeyedEventHandle(); + auto pNtReleaseKeyedEvent = try_get_NtReleaseKeyedEvent(); - return FALSE; + if (!pNtReleaseKeyedEvent) + { + RaiseStatus(STATUS_RESOURCE_NOT_OWNED); } - static void __fastcall RtlpWakeConditionVariable(PCONDITION_VARIABLE ConditionVariable, size_t ConditionVariableStatus, size_t WakeCount) + //v16 + YY_CV_WAIT_BLOCK* notify = nullptr; + + YY_CV_WAIT_BLOCK* pWake = nullptr; + YY_CV_WAIT_BLOCK** ppInsert = &pWake; + + size_t Count = 0; + + for (;;) { - auto GlobalKeyedEventHandle = GetGlobalKeyedEventHandle(); - auto pNtReleaseKeyedEvent = try_get_NtReleaseKeyedEvent(); + auto pWaitBlock = YY_CV_GET_BLOCK(ConditionVariableStatus); - if (!pNtReleaseKeyedEvent) + if ((ConditionVariableStatus & 0x7) == 0x7) { - RaiseStatus(STATUS_RESOURCE_NOT_OWNED); + ConditionVariableStatus = InterlockedExchange((volatile size_t*)ConditionVariable, 0); + + *ppInsert = YY_CV_GET_BLOCK(ConditionVariableStatus); + + break; } + const auto MaxWakeCount = WakeCount + (ConditionVariableStatus & 7); - //v16 - YY_CV_WAIT_BLOCK* notify = nullptr; + auto pBlock = pWaitBlock; - YY_CV_WAIT_BLOCK* pWake = nullptr; - YY_CV_WAIT_BLOCK** ppInsert = &pWake; + for (; pBlock->notify == nullptr;) + { + auto tmp = pBlock; + pBlock = pBlock->back; + pBlock->next = tmp; + } - size_t Count = 0; + if (MaxWakeCount <= Count) + { + const auto LastStatus = InterlockedCompareExchange((volatile size_t*)ConditionVariable, size_t(pWaitBlock), ConditionVariableStatus); - for (;;) + if (LastStatus == ConditionVariableStatus) + { + break; + } + + ConditionVariableStatus = LastStatus; + } + else { - auto pWaitBlock = YY_CV_GET_BLOCK(ConditionVariableStatus); + notify = pBlock->notify; - if ((ConditionVariableStatus & 0x7) == 0x7) + for (; MaxWakeCount > Count && notify->next;) { - ConditionVariableStatus = InterlockedExchange((volatile size_t*)ConditionVariable, 0); + ++Count; + *ppInsert = notify; + notify->back = nullptr; - *ppInsert = YY_CV_GET_BLOCK(ConditionVariableStatus); + auto next = notify->next; - break; - } + pWaitBlock->notify = next; + next->back = nullptr; - const auto MaxWakeCount = WakeCount + (ConditionVariableStatus & 7); + ppInsert = ¬ify->back; - auto pBlock = pWaitBlock; + notify = next; - for (; pBlock->notify == nullptr;) - { - auto tmp = pBlock; - pBlock = pBlock->back; - pBlock->next = tmp; } if (MaxWakeCount <= Count) @@ -401,2471 +430,2439 @@ namespace YY } else { - notify = pBlock->notify; - - for (; MaxWakeCount > Count && notify->next;) - { - ++Count; - *ppInsert = notify; - notify->back = nullptr; - - auto next = notify->next; - - pWaitBlock->notify = next; - next->back = nullptr; + const auto LastStatus = InterlockedCompareExchange((volatile size_t*)ConditionVariable, 0, ConditionVariableStatus); - ppInsert = ¬ify->back; - notify = next; - - } - - if (MaxWakeCount <= Count) + if (LastStatus == ConditionVariableStatus) { - const auto LastStatus = InterlockedCompareExchange((volatile size_t*)ConditionVariable, size_t(pWaitBlock), ConditionVariableStatus); - - if (LastStatus == ConditionVariableStatus) - { - break; - } + *ppInsert = notify; + notify->back = 0; - ConditionVariableStatus = LastStatus; + break; } - else - { - const auto LastStatus = InterlockedCompareExchange((volatile size_t*)ConditionVariable, 0, ConditionVariableStatus); - - if (LastStatus == ConditionVariableStatus) - { - *ppInsert = notify; - notify->back = 0; - - break; - } - - ConditionVariableStatus = LastStatus; - } + ConditionVariableStatus = LastStatus; } } + } - for (; pWake;) - { - auto back = pWake->back; + for (; pWake;) + { + auto back = pWake->back; - if (!InterlockedBitTestAndReset((volatile LONG*)&pWake->flag, 1)) + if (!InterlockedBitTestAndReset((volatile LONG*)&pWake->flag, 1)) + { + if (pWake->SRWLock == nullptr || RtlpQueueWaitBlockToSRWLock(pWake, pWake->SRWLock, (pWake->flag >> 2) & 0x1) == FALSE) { - if (pWake->SRWLock == nullptr || RtlpQueueWaitBlockToSRWLock(pWake, pWake->SRWLock, (pWake->flag >> 2) & 0x1) == FALSE) - { - pNtReleaseKeyedEvent(GlobalKeyedEventHandle, pWake, 0, nullptr); - } + pNtReleaseKeyedEvent(GlobalKeyedEventHandle, pWake, 0, nullptr); } - - pWake = back; } - return; + pWake = back; } - static void __fastcall RtlpOptimizeConditionVariableWaitList(PCONDITION_VARIABLE ConditionVariable, size_t ConditionVariableStatus) + return; + } + + static void __fastcall RtlpOptimizeConditionVariableWaitList(PCONDITION_VARIABLE ConditionVariable, size_t ConditionVariableStatus) + { + for (;;) { - for (;;) - { - auto pWaitBlock = YY_CV_GET_BLOCK(ConditionVariableStatus); - auto pItem = pWaitBlock; + auto pWaitBlock = YY_CV_GET_BLOCK(ConditionVariableStatus); + auto pItem = pWaitBlock; - for (; pItem->notify == nullptr;) - { - auto temp = pItem; - pItem = pItem->back; - pItem->next = temp; - } + for (; pItem->notify == nullptr;) + { + auto temp = pItem; + pItem = pItem->back; + pItem->next = temp; + } - pWaitBlock->notify = pItem->notify; + pWaitBlock->notify = pItem->notify; - const auto LastStatus = InterlockedCompareExchange((volatile size_t*)ConditionVariable, size_t(pWaitBlock), ConditionVariableStatus); + const auto LastStatus = InterlockedCompareExchange((volatile size_t*)ConditionVariable, size_t(pWaitBlock), ConditionVariableStatus); - if (LastStatus == ConditionVariableStatus) - break; + if (LastStatus == ConditionVariableStatus) + break; - ConditionVariableStatus = LastStatus; + ConditionVariableStatus = LastStatus; - if (ConditionVariableStatus & 7) - { - RtlpWakeConditionVariable(ConditionVariable, ConditionVariableStatus, 0); - return; - } + if (ConditionVariableStatus & 7) + { + RtlpWakeConditionVariable(ConditionVariable, ConditionVariableStatus, 0); + return; } } + } - static BOOL __fastcall RtlpWakeSingle(PCONDITION_VARIABLE ConditionVariable, YY_CV_WAIT_BLOCK* pBlock) - { - auto Current = *(volatile size_t*)ConditionVariable; + static BOOL __fastcall RtlpWakeSingle(PCONDITION_VARIABLE ConditionVariable, YY_CV_WAIT_BLOCK* pBlock) + { + auto Current = *(volatile size_t*)ConditionVariable; - for (; Current && (Current & 0x7) != 0x7;) + for (; Current && (Current & 0x7) != 0x7;) + { + if (Current & 0x8) { - if (Current & 0x8) - { - const auto Last = InterlockedCompareExchange((volatile size_t*)ConditionVariable, Current | 0x7, Current); + const auto Last = InterlockedCompareExchange((volatile size_t*)ConditionVariable, Current | 0x7, Current); - if (Last == Current) - return FALSE; + if (Last == Current) + return FALSE; - Current = Last; - } - else - { - auto New = Current | 0x8; + Current = Last; + } + else + { + auto New = Current | 0x8; - auto Last = InterlockedCompareExchange((volatile size_t*)ConditionVariable, New, Current); + auto Last = InterlockedCompareExchange((volatile size_t*)ConditionVariable, New, Current); - if (Last == Current) - { - Current = New; + if (Last == Current) + { + Current = New; - YY_CV_WAIT_BLOCK* notify = nullptr; - BOOL bRet = FALSE; + YY_CV_WAIT_BLOCK* notify = nullptr; + BOOL bRet = FALSE; - auto pWaitBlock = YY_CV_GET_BLOCK(Current); - auto pSuccessor = pWaitBlock; + auto pWaitBlock = YY_CV_GET_BLOCK(Current); + auto pSuccessor = pWaitBlock; - if (pWaitBlock) + if (pWaitBlock) + { + for (; pWaitBlock;) { - for (; pWaitBlock;) + if (pWaitBlock == pBlock) { - if (pWaitBlock == pBlock) + if (notify) { - if (notify) - { - pWaitBlock = pWaitBlock->back; - bRet = TRUE; - - notify->back = pWaitBlock; + pWaitBlock = pWaitBlock->back; + bRet = TRUE; - if (!pWaitBlock) - break; + notify->back = pWaitBlock; - pWaitBlock->next = notify; - } - else - { - auto back = size_t(pWaitBlock->back); + if (!pWaitBlock) + break; - New = back == 0 ? back : back ^ ((New ^ back) & 0xF); + pWaitBlock->next = notify; + } + else + { + auto back = size_t(pWaitBlock->back); - Last = InterlockedCompareExchange((volatile size_t*)ConditionVariable, New, Current); + New = back == 0 ? back : back ^ ((New ^ back) & 0xF); - if (Last == Current) - { - Current = New; - if (back == 0) - return TRUE; + Last = InterlockedCompareExchange((volatile size_t*)ConditionVariable, New, Current); - bRet = TRUE; - } - else - { - Current = Last; - } + if (Last == Current) + { + Current = New; + if (back == 0) + return TRUE; - pSuccessor = pWaitBlock = YY_CV_GET_BLOCK(Current); - notify = nullptr; + bRet = TRUE; } - } - else - { - pWaitBlock->next = notify; - notify = pWaitBlock; - pWaitBlock = pWaitBlock->back; + else + { + Current = Last; + } + + pSuccessor = pWaitBlock = YY_CV_GET_BLOCK(Current); + notify = nullptr; } } - - if (pSuccessor) - pSuccessor->notify = notify; + else + { + pWaitBlock->next = notify; + notify = pWaitBlock; + pWaitBlock = pWaitBlock->back; + } } - RtlpWakeConditionVariable(ConditionVariable, Current, 0); - return bRet; + if (pSuccessor) + pSuccessor->notify = notify; } - Current = Last; + RtlpWakeConditionVariable(ConditionVariable, Current, 0); + return bRet; } - } - return FALSE; + Current = Last; + } } + return FALSE; + } - static size_t __fastcall RtlpRunOnceWaitForInit( - size_t Current, - LPINIT_ONCE lpInitOnce - ) - { - auto GlobalKeyedEventHandle = internal::GetGlobalKeyedEventHandle(); - auto pNtWaitForKeyedEvent = try_get_NtWaitForKeyedEvent(); - if (!pNtWaitForKeyedEvent) - internal::RaiseStatus(STATUS_RESOURCE_NOT_OWNED); - do - { - const auto Old = Current; - - Current = Current & ~size_t(RTL_RUN_ONCE_CHECK_ONLY | RTL_RUN_ONCE_ASYNC); + static size_t __fastcall RtlpRunOnceWaitForInit( + size_t Current, + LPINIT_ONCE lpInitOnce + ) + { + auto GlobalKeyedEventHandle = internal::GetGlobalKeyedEventHandle(); + auto pNtWaitForKeyedEvent = try_get_NtWaitForKeyedEvent(); + if (!pNtWaitForKeyedEvent) + internal::RaiseStatus(STATUS_RESOURCE_NOT_OWNED); - const auto New = (size_t(&Current) & ~size_t(RTL_RUN_ONCE_ASYNC)) | RTL_RUN_ONCE_CHECK_ONLY; - const auto Last = InterlockedCompareExchange((volatile size_t*)lpInitOnce, New, Old); - if (Last == Old) - { - //WinXP绛夎佺郴缁熶笉鏀寔绌哄彞鏌勪紶鍏ワ紝姝よ涓轰笉鑳界収鎼琖indows 7 - pNtWaitForKeyedEvent(GlobalKeyedEventHandle, &Current, 0, nullptr); + do + { + const auto Old = Current; - Current = *(volatile size_t*)lpInitOnce; - } - else - { - Current = Last; - } - } while ((Current & (RTL_RUN_ONCE_CHECK_ONLY | RTL_RUN_ONCE_ASYNC)) == RTL_RUN_ONCE_CHECK_ONLY); + Current = Current & ~size_t(RTL_RUN_ONCE_CHECK_ONLY | RTL_RUN_ONCE_ASYNC); - return Current; - } + const auto New = (size_t(&Current) & ~size_t(RTL_RUN_ONCE_ASYNC)) | RTL_RUN_ONCE_CHECK_ONLY; + const auto Last = InterlockedCompareExchange((volatile size_t*)lpInitOnce, New, Old); + if (Last == Old) + { + //WinXP绛夎佺郴缁熶笉鏀寔绌哄彞鏌勪紶鍏ワ紝姝よ涓轰笉鑳界収鎼琖indows 7 + pNtWaitForKeyedEvent(GlobalKeyedEventHandle, &Current, 0, nullptr); - static NTSTATUS __fastcall RtlRunOnceBeginInitialize( - _Inout_ LPINIT_ONCE lpInitOnce, - _In_ DWORD dwFlags, - _Outptr_opt_result_maybenull_ LPVOID* lpContext - ) - { - //鍙傛暟妫鏌 - if ((dwFlags & ~(RTL_RUN_ONCE_CHECK_ONLY | RTL_RUN_ONCE_ASYNC)) || ((dwFlags - 1) & dwFlags)) + Current = *(volatile size_t*)lpInitOnce; + } + else { - return STATUS_INVALID_PARAMETER_2; + Current = Last; } + } while ((Current & (RTL_RUN_ONCE_CHECK_ONLY | RTL_RUN_ONCE_ASYNC)) == RTL_RUN_ONCE_CHECK_ONLY); - auto Current = *(volatile size_t*)lpInitOnce; + return Current; + } - if ((Current & (RTL_RUN_ONCE_CHECK_ONLY | RTL_RUN_ONCE_ASYNC)) == RTL_RUN_ONCE_ASYNC) - { - //娌℃湁鎯虫槑鐧借繖鏍峰仛鐨勬剰鍥撅紝淇敼lpInitOnce鏈韩鏈変粈涔堟剰涔夛紵 nop锛 - InterlockedExchange((volatile size_t *)&lpInitOnce, dwFlags); + static NTSTATUS __fastcall RtlRunOnceBeginInitialize( + _Inout_ LPINIT_ONCE lpInitOnce, + _In_ DWORD dwFlags, + _Outptr_opt_result_maybenull_ LPVOID* lpContext + ) + { + //鍙傛暟妫鏌 + if ((dwFlags & ~(RTL_RUN_ONCE_CHECK_ONLY | RTL_RUN_ONCE_ASYNC)) || ((dwFlags - 1) & dwFlags)) + { + return STATUS_INVALID_PARAMETER_2; + } - if (lpContext) - *lpContext = (LPVOID)(Current & ~size_t(RTL_RUN_ONCE_CHECK_ONLY | RTL_RUN_ONCE_ASYNC)); + auto Current = *(volatile size_t*)lpInitOnce; - return STATUS_SUCCESS; - } + if ((Current & (RTL_RUN_ONCE_CHECK_ONLY | RTL_RUN_ONCE_ASYNC)) == RTL_RUN_ONCE_ASYNC) + { + //娌℃湁鎯虫槑鐧借繖鏍峰仛鐨勬剰鍥撅紝淇敼lpInitOnce鏈韩鏈変粈涔堟剰涔夛紵 nop锛 + InterlockedExchange((volatile size_t *)&lpInitOnce, dwFlags); - if (dwFlags & RTL_RUN_ONCE_CHECK_ONLY) - { - return STATUS_UNSUCCESSFUL; - } + if (lpContext) + *lpContext = (LPVOID)(Current & ~size_t(RTL_RUN_ONCE_CHECK_ONLY | RTL_RUN_ONCE_ASYNC)); + + return STATUS_SUCCESS; + } + + if (dwFlags & RTL_RUN_ONCE_CHECK_ONLY) + { + return STATUS_UNSUCCESSFUL; + } - const auto New = (dwFlags & RTL_RUN_ONCE_ASYNC) | RTL_RUN_ONCE_CHECK_ONLY; + const auto New = (dwFlags & RTL_RUN_ONCE_ASYNC) | RTL_RUN_ONCE_CHECK_ONLY; - for (;;) + for (;;) + { + const auto InitOnceData = Current & 3; + if (InitOnceData == 0) { - const auto InitOnceData = Current & 3; - if (InitOnceData == 0) - { - const auto Last = InterlockedCompareExchange((volatile size_t *)lpInitOnce, New, Current); - if (Last == Current) - return STATUS_PENDING; + const auto Last = InterlockedCompareExchange((volatile size_t *)lpInitOnce, New, Current); + if (Last == Current) + return STATUS_PENDING; - Current = Last; - } - else if (InitOnceData == RTL_RUN_ONCE_CHECK_ONLY) - { - if (dwFlags & RTL_RUN_ONCE_ASYNC) - return STATUS_INVALID_PARAMETER_2; + Current = Last; + } + else if (InitOnceData == RTL_RUN_ONCE_CHECK_ONLY) + { + if (dwFlags & RTL_RUN_ONCE_ASYNC) + return STATUS_INVALID_PARAMETER_2; - Current = RtlpRunOnceWaitForInit(Current, lpInitOnce); - } - else + Current = RtlpRunOnceWaitForInit(Current, lpInitOnce); + } + else + { + //鐤戞儜锛熶负浠涔堝井杞杩欐牱鍒ゆ柇鈥︹ + if (Current != (RTL_RUN_ONCE_CHECK_ONLY | RTL_RUN_ONCE_ASYNC)) { - //鐤戞儜锛熶负浠涔堝井杞杩欐牱鍒ゆ柇鈥︹ - if (Current != (RTL_RUN_ONCE_CHECK_ONLY | RTL_RUN_ONCE_ASYNC)) - { - if (lpContext) - *lpContext = (LPVOID)(Current & ~size_t(RTL_RUN_ONCE_CHECK_ONLY | RTL_RUN_ONCE_ASYNC)); - - return STATUS_SUCCESS; - } + if (lpContext) + *lpContext = (LPVOID)(Current & ~size_t(RTL_RUN_ONCE_CHECK_ONLY | RTL_RUN_ONCE_ASYNC)); - return (dwFlags & RTL_RUN_ONCE_ASYNC) ? STATUS_PENDING : STATUS_INVALID_PARAMETER_2; + return STATUS_SUCCESS; } + + return (dwFlags & RTL_RUN_ONCE_ASYNC) ? STATUS_PENDING : STATUS_INVALID_PARAMETER_2; } } + } - static void __fastcall RtlpRunOnceWakeAll(size_t* pWake) + static void __fastcall RtlpRunOnceWakeAll(size_t* pWake) + { + auto GlobalKeyedEventHandle = internal::GetGlobalKeyedEventHandle(); + auto pNtReleaseKeyedEvent = try_get_NtReleaseKeyedEvent(); + if (!pNtReleaseKeyedEvent) + internal::RaiseStatus(STATUS_RESOURCE_NOT_OWNED); + + for (auto WakeAddress = (LPVOID)(*pWake & ~size_t(RTL_RUN_ONCE_CHECK_ONLY | RTL_RUN_ONCE_ASYNC)); WakeAddress; ) { - auto GlobalKeyedEventHandle = internal::GetGlobalKeyedEventHandle(); - auto pNtReleaseKeyedEvent = try_get_NtReleaseKeyedEvent(); - if (!pNtReleaseKeyedEvent) - internal::RaiseStatus(STATUS_RESOURCE_NOT_OWNED); + //闃叉鍦板潃鏃犳晥锛屾垜浠厛淇濆瓨涓 + auto NextWakeAddress = *(LPVOID*)WakeAddress; - for (auto WakeAddress = (LPVOID)(*pWake & ~size_t(RTL_RUN_ONCE_CHECK_ONLY | RTL_RUN_ONCE_ASYNC)); WakeAddress; ) - { - //闃叉鍦板潃鏃犳晥锛屾垜浠厛淇濆瓨涓 - auto NextWakeAddress = *(LPVOID*)WakeAddress; + //WinXP绛夎佺郴缁熶笉鏀寔绌哄彞鏌勪紶鍏ワ紝姝よ涓轰笉鑳界収鎼琖indows 7 + pNtReleaseKeyedEvent(GlobalKeyedEventHandle, WakeAddress, 0, nullptr); - //WinXP绛夎佺郴缁熶笉鏀寔绌哄彞鏌勪紶鍏ワ紝姝よ涓轰笉鑳界収鎼琖indows 7 - pNtReleaseKeyedEvent(GlobalKeyedEventHandle, WakeAddress, 0, nullptr); + WakeAddress = NextWakeAddress; + } + } - WakeAddress = NextWakeAddress; - } + static LSTATUS __fastcall RtlRunOnceComplete( + _Inout_ LPINIT_ONCE lpInitOnce, + _In_ DWORD dwFlags, + _In_opt_ LPVOID lpContext + ) + { + //鍙傛暟妫鏌ユ棤鏁 鎴栬 鍚屾椂浣跨敤浜嗗涓爣璁颁綅 + if ((dwFlags & ~(RTL_RUN_ONCE_ASYNC | RTL_RUN_ONCE_INIT_FAILED)) || ((dwFlags - 1) & dwFlags)) + { + return STATUS_INVALID_PARAMETER_2; + } + + /* + dwFlags = 0, dwNewFlags = 0x3锛圧TL_RUN_ONCE_CHECK_ONLY | RTL_RUN_ONCE_ASYNC锛 + dwFlags = 0x2, dwNewFlags = 0x2锛圧TL_RUN_ONCE_ASYNC锛 + dwFlags = 0x4, dwNewFlags = 0x5锛圧TL_RUN_ONCE_CHECK_ONLY | RTL_RUN_ONCE_INIT_FAILED锛 + */ + const auto dwNewFlags = (dwFlags ^ ~(dwFlags >> 1)) & 3 ^ dwFlags; + + if (lpContext && ((dwNewFlags & RTL_RUN_ONCE_ASYNC) == 0 || (size_t(lpContext) & (RTL_RUN_ONCE_CHECK_ONLY | RTL_RUN_ONCE_ASYNC)))) + { + return STATUS_INVALID_PARAMETER_3; } - static LSTATUS __fastcall RtlRunOnceComplete( - _Inout_ LPINIT_ONCE lpInitOnce, - _In_ DWORD dwFlags, - _In_opt_ LPVOID lpContext - ) + auto Current = *(volatile size_t*)lpInitOnce; + auto New = (size_t(lpContext) & ~size_t(RTL_RUN_ONCE_CHECK_ONLY | RTL_RUN_ONCE_ASYNC)) | (dwNewFlags & RTL_RUN_ONCE_ASYNC); + + switch (Current & (RTL_RUN_ONCE_CHECK_ONLY | RTL_RUN_ONCE_ASYNC)) { - //鍙傛暟妫鏌ユ棤鏁 鎴栬 鍚屾椂浣跨敤浜嗗涓爣璁颁綅 - if ((dwFlags & ~(RTL_RUN_ONCE_ASYNC | RTL_RUN_ONCE_INIT_FAILED)) || ((dwFlags - 1) & dwFlags)) + case RTL_RUN_ONCE_CHECK_ONLY: + if ((dwNewFlags & RTL_RUN_ONCE_CHECK_ONLY) == 0) { return STATUS_INVALID_PARAMETER_2; } - /* - dwFlags = 0, dwNewFlags = 0x3锛圧TL_RUN_ONCE_CHECK_ONLY | RTL_RUN_ONCE_ASYNC锛 - dwFlags = 0x2, dwNewFlags = 0x2锛圧TL_RUN_ONCE_ASYNC锛 - dwFlags = 0x4, dwNewFlags = 0x5锛圧TL_RUN_ONCE_CHECK_ONLY | RTL_RUN_ONCE_INIT_FAILED锛 - */ - const auto dwNewFlags = (dwFlags ^ ~(dwFlags >> 1)) & 3 ^ dwFlags; - - if (lpContext && ((dwNewFlags & RTL_RUN_ONCE_ASYNC) == 0 || (size_t(lpContext) & (RTL_RUN_ONCE_CHECK_ONLY | RTL_RUN_ONCE_ASYNC)))) + Current = InterlockedExchange((volatile size_t*)lpInitOnce, New); + if ((Current & (RTL_RUN_ONCE_CHECK_ONLY | RTL_RUN_ONCE_ASYNC)) == RTL_RUN_ONCE_CHECK_ONLY) { - return STATUS_INVALID_PARAMETER_3; + RtlpRunOnceWakeAll(&Current); + + return STATUS_SUCCESS; } - auto Current = *(volatile size_t*)lpInitOnce; - auto New = (size_t(lpContext) & ~size_t(RTL_RUN_ONCE_CHECK_ONLY | RTL_RUN_ONCE_ASYNC)) | (dwNewFlags & RTL_RUN_ONCE_ASYNC); + return STATUS_INVALID_OWNER; + break; + case RTL_RUN_ONCE_CHECK_ONLY | RTL_RUN_ONCE_ASYNC: + if (dwNewFlags & RTL_RUN_ONCE_CHECK_ONLY) + { + return STATUS_INVALID_PARAMETER_2; + } - switch (Current & (RTL_RUN_ONCE_CHECK_ONLY | RTL_RUN_ONCE_ASYNC)) + if (InterlockedCompareExchange((volatile size_t*)lpInitOnce, New, Current) == Current) { - case RTL_RUN_ONCE_CHECK_ONLY: - if ((dwNewFlags & RTL_RUN_ONCE_CHECK_ONLY) == 0) - { - return STATUS_INVALID_PARAMETER_2; - } + return STATUS_SUCCESS; + } - Current = InterlockedExchange((volatile size_t*)lpInitOnce, New); - if ((Current & (RTL_RUN_ONCE_CHECK_ONLY | RTL_RUN_ONCE_ASYNC)) == RTL_RUN_ONCE_CHECK_ONLY) - { - RtlpRunOnceWakeAll(&Current); + return STATUS_OBJECT_NAME_COLLISION; - return STATUS_SUCCESS; - } + break; + default: + return STATUS_UNSUCCESSFUL; + break; + } + } - return STATUS_INVALID_OWNER; - break; - case RTL_RUN_ONCE_CHECK_ONLY | RTL_RUN_ONCE_ASYNC: - if (dwNewFlags & RTL_RUN_ONCE_CHECK_ONLY) - { - return STATUS_INVALID_PARAMETER_2; - } +#endif - if (InterlockedCompareExchange((volatile size_t*)lpInitOnce, New, Current) == Current) - { - return STATUS_SUCCESS; - } +#if (YY_Thunks_Support_Version < NTDDI_WIN8) + static auto __fastcall GetBlockByWaitOnAddressHashTable(LPVOID Address) + { + static volatile ULONG_PTR WaitOnAddressHashTable[128]; - return STATUS_OBJECT_NAME_COLLISION; + const auto Index = (size_t(Address) >> 5) & 0x7F; - break; - default: - return STATUS_UNSUCCESSFUL; - break; - } - } + return &WaitOnAddressHashTable[Index]; + } -#endif + static void __fastcall RtlpWaitOnAddressWakeEntireList(YY_ADDRESS_WAIT_BLOCK* pBlock) + { + auto GlobalKeyedEventHandle = GetGlobalKeyedEventHandle(); + auto pNtReleaseKeyedEvent = try_get_NtReleaseKeyedEvent(); + if (!pNtReleaseKeyedEvent) + internal::RaiseStatus(STATUS_NOT_FOUND); -#if (YY_Thunks_Support_Version < NTDDI_WIN8) - static auto __fastcall GetBlockByWaitOnAddressHashTable(LPVOID Address) + for (; pBlock;) { - static volatile ULONG_PTR WaitOnAddressHashTable[128]; + auto Tmp = pBlock->back; + + if (InterlockedExchange(&pBlock->flag, 2) == 0) + { + pNtReleaseKeyedEvent(GlobalKeyedEventHandle, pBlock, 0, nullptr); + } - const auto Index = (size_t(Address) >> 5) & 0x7F; - return &WaitOnAddressHashTable[Index]; + pBlock = Tmp; } + } + + static void __fastcall RtlpOptimizeWaitOnAddressWaitList(volatile ULONG_PTR* ppFirstBlock) + { + auto Current = *ppFirstBlock; - static void __fastcall RtlpWaitOnAddressWakeEntireList(YY_ADDRESS_WAIT_BLOCK* pBlock) + for (;;) { - auto GlobalKeyedEventHandle = GetGlobalKeyedEventHandle(); - auto pNtReleaseKeyedEvent = try_get_NtReleaseKeyedEvent(); - if (!pNtReleaseKeyedEvent) - internal::RaiseStatus(STATUS_NOT_FOUND); + auto pBlock = YY_ADDRESS_GET_BLOCK(Current); - for (; pBlock;) + for (auto pItem = pBlock;;) { - auto Tmp = pBlock->back; - - if (InterlockedExchange(&pBlock->flag, 2) == 0) + if (pItem->next != nullptr) { - pNtReleaseKeyedEvent(GlobalKeyedEventHandle, pBlock, 0, nullptr); + pBlock->next = pItem->next; + break; } - - pBlock = Tmp; + auto Tmp = pItem; + pItem = pItem->back; + pItem->notify = Tmp; } - } - static void __fastcall RtlpOptimizeWaitOnAddressWaitList(volatile ULONG_PTR* ppFirstBlock) - { - auto Current = *ppFirstBlock; + const auto Last = InterlockedCompareExchange(ppFirstBlock, (Current & 1) == 0 ? size_t(pBlock) : 0, Current); - for (;;) + if (Last == Current) { - auto pBlock = YY_ADDRESS_GET_BLOCK(Current); - - for (auto pItem = pBlock;;) + if(Current & 1) { - if (pItem->next != nullptr) - { - pBlock->next = pItem->next; - break; - } - - auto Tmp = pItem; - pItem = pItem->back; - pItem->notify = Tmp; + RtlpWaitOnAddressWakeEntireList(pBlock); } - const auto Last = InterlockedCompareExchange(ppFirstBlock, (Current & 1) == 0 ? size_t(pBlock) : 0, Current); + return; + } - if (Last == Current) - { - if(Current & 1) - { - RtlpWaitOnAddressWakeEntireList(pBlock); - } - return; - } + Current = Last; + } + } - Current = Last; - } - } + static void __fastcall RtlpAddWaitBlockToWaitList(YY_ADDRESS_WAIT_BLOCK* pWaitBlock) + { + auto ppFirstBlock = GetBlockByWaitOnAddressHashTable((LPVOID)pWaitBlock->Address); + auto Current = *ppFirstBlock; - static void __fastcall RtlpAddWaitBlockToWaitList(YY_ADDRESS_WAIT_BLOCK* pWaitBlock) + for (;;) { - auto ppFirstBlock = GetBlockByWaitOnAddressHashTable((LPVOID)pWaitBlock->Address); - - auto Current = *ppFirstBlock; + auto New = size_t(pWaitBlock) | (size_t(Current) & 0x3); - for (;;) + auto back = YY_ADDRESS_GET_BLOCK(Current); + pWaitBlock->back = back; + if (back) { - auto New = size_t(pWaitBlock) | (size_t(Current) & 0x3); - - auto back = YY_ADDRESS_GET_BLOCK(Current); - pWaitBlock->back = back; - if (back) - { - New |= 0x2; + New |= 0x2; - pWaitBlock->next = nullptr; - } - else - { - pWaitBlock->next = pWaitBlock; - } + pWaitBlock->next = nullptr; + } + else + { + pWaitBlock->next = pWaitBlock; + } - const auto Last = InterlockedCompareExchange(ppFirstBlock, New, Current); + const auto Last = InterlockedCompareExchange(ppFirstBlock, New, Current); - if (Last == Current) + if (Last == Current) + { + //0x2鐘舵佸彂鐢熷彉鍖 鎵嶉渶瑕侀噸鏂颁紭鍖栭攣銆 + if ((Current ^ New) & 0x2) { - //0x2鐘舵佸彂鐢熷彉鍖 鎵嶉渶瑕侀噸鏂颁紭鍖栭攣銆 - if ((Current ^ New) & 0x2) - { - RtlpOptimizeWaitOnAddressWaitList(ppFirstBlock); - } - - return; + RtlpOptimizeWaitOnAddressWaitList(ppFirstBlock); } - Current = Last; + return; } + + Current = Last; } + } - static NTSTATUS __fastcall RtlpWaitOnAddressWithTimeout(YY_ADDRESS_WAIT_BLOCK* pWaitBlock, LARGE_INTEGER *TimeOut); + static NTSTATUS __fastcall RtlpWaitOnAddressWithTimeout(YY_ADDRESS_WAIT_BLOCK* pWaitBlock, LARGE_INTEGER *TimeOut); - static void __fastcall RtlpWaitOnAddressRemoveWaitBlock(YY_ADDRESS_WAIT_BLOCK* pWaitBlock) - { - auto GlobalKeyedEventHandle = GetGlobalKeyedEventHandle(); - auto pNtWaitForKeyedEvent = try_get_NtWaitForKeyedEvent(); - if (!pNtWaitForKeyedEvent) - internal::RaiseStatus(STATUS_NOT_FOUND); + static void __fastcall RtlpWaitOnAddressRemoveWaitBlock(YY_ADDRESS_WAIT_BLOCK* pWaitBlock) + { + auto GlobalKeyedEventHandle = GetGlobalKeyedEventHandle(); + auto pNtWaitForKeyedEvent = try_get_NtWaitForKeyedEvent(); + if (!pNtWaitForKeyedEvent) + internal::RaiseStatus(STATUS_NOT_FOUND); - auto ppFirstBlock = GetBlockByWaitOnAddressHashTable((LPVOID)pWaitBlock->Address); + auto ppFirstBlock = GetBlockByWaitOnAddressHashTable((LPVOID)pWaitBlock->Address); - auto Current = *ppFirstBlock; - size_t Last; + auto Current = *ppFirstBlock; + size_t Last; - for (; Current; Current = Last) + for (; Current; Current = Last) + { + if (Current & 2) { - if (Current & 2) - { - Last = InterlockedCompareExchange(ppFirstBlock, Current | 1, Current); + Last = InterlockedCompareExchange(ppFirstBlock, Current | 1, Current); - if (Last == Current) - { - break; - } + if (Last == Current) + { + break; } - else + } + else + { + auto New = Current | 0x2; + Last = InterlockedCompareExchange(ppFirstBlock, New, Current); + + if (Last == Current) { - auto New = Current | 0x2; - Last = InterlockedCompareExchange(ppFirstBlock, New, Current); + Current = New; - if (Last == Current) - { - Current = New; + bool bFind = false; - bool bFind = false; + //鍚屾鎴愬姛锛 + auto pBlock = YY_ADDRESS_GET_BLOCK(New); + auto pItem = pBlock; - //鍚屾鎴愬姛锛 - auto pBlock = YY_ADDRESS_GET_BLOCK(New); - auto pItem = pBlock; + auto pNotify = pBlock->notify; + YY_ADDRESS_WAIT_BLOCK* Tmp; - auto pNotify = pBlock->notify; - YY_ADDRESS_WAIT_BLOCK* Tmp; + do + { + Tmp = pBlock->back; - do + if (pBlock != pWaitBlock) { - Tmp = pBlock->back; - - if (pBlock != pWaitBlock) - { - pBlock->notify = pNotify; - pNotify = pBlock; - + pBlock->notify = pNotify; + pNotify = pBlock; - pBlock = Tmp; - Tmp = pItem; - continue; - } - - bFind = true; + pBlock = Tmp; + Tmp = pItem; + continue; + } - if (pBlock != pItem) - { - pNotify->back = Tmp; - if (Tmp) - Tmp->notify = pNotify; - else - pNotify->next = pNotify; + bFind = true; - pBlock = Tmp; - Tmp = pItem; - continue; - } - New = size_t(pBlock->back); + if (pBlock != pItem) + { + pNotify->back = Tmp; if (Tmp) - { - New = size_t(Tmp) ^ (Current ^ size_t(Tmp)) & 0x3; - } - - Last = InterlockedCompareExchange(ppFirstBlock, New, Current); - - if (Last == Current) - { - if (New == 0) - return; - - Tmp->notify = nullptr; - pBlock = Tmp; - } + Tmp->notify = pNotify; else - { - Current = Last; + pNotify->next = pNotify; - Tmp = pBlock = YY_ADDRESS_GET_BLOCK(Current); - pNotify = pBlock->notify; - } - - - pItem = Tmp; - } while (pBlock); - + pBlock = Tmp; + Tmp = pItem; + continue; + } - if (bFind == false && InterlockedExchange(&pWaitBlock->flag, 0) != 2) + New = size_t(pBlock->back); + if (Tmp) { - pNtWaitForKeyedEvent(GlobalKeyedEventHandle, pWaitBlock, 0, nullptr); + New = size_t(Tmp) ^ (Current ^ size_t(Tmp)) & 0x3; } - Tmp->next = pNotify; + Last = InterlockedCompareExchange(ppFirstBlock, New, Current); - for (;;) + if (Last == Current) { - const auto Last = InterlockedCompareExchange(ppFirstBlock, (Current & 1) == 0 ? size_t(YY_ADDRESS_GET_BLOCK(Current)) : 0, Current); - - if (Last == Current) - break; + if (New == 0) + return; + Tmp->notify = nullptr; + pBlock = Tmp; + } + else + { Current = Last; + + Tmp = pBlock = YY_ADDRESS_GET_BLOCK(Current); + pNotify = pBlock->notify; } - if (Current & 1) - RtlpWaitOnAddressWakeEntireList(YY_ADDRESS_GET_BLOCK(Current)); + pItem = Tmp; + } while (pBlock); + - return; + if (bFind == false && InterlockedExchange(&pWaitBlock->flag, 0) != 2) + { + pNtWaitForKeyedEvent(GlobalKeyedEventHandle, pWaitBlock, 0, nullptr); } - } - } - - if (InterlockedExchange(&pWaitBlock->flag, 1) == 2) - return; - RtlpWaitOnAddressWithTimeout(pWaitBlock, 0); - } + Tmp->next = pNotify; - static NTSTATUS __fastcall RtlpWaitOnAddressWithTimeout(YY_ADDRESS_WAIT_BLOCK* pWaitBlock, LARGE_INTEGER *TimeOut) - { - //鍗曟牳 鎴戜滑鏃犻渶鑷棆锛岀洿鎺ヨ繘鍏ョ瓑寰呰繃绋嬪嵆鍙 - if (NtCurrentTeb()->ProcessEnvironmentBlock->NumberOfProcessors > 1 && RtlpWaitOnAddressSpinCount) - { - for (DWORD SpinCount = 0; SpinCount < RtlpWaitOnAddressSpinCount;++SpinCount) - { - if ((pWaitBlock->flag & 1) == 0) + for (;;) { - //鑷棆杩囩▼涓紝绛夊埌浜嗕俊鍙锋敼鍙 - return STATUS_SUCCESS; - } + const auto Last = InterlockedCompareExchange(ppFirstBlock, (Current & 1) == 0 ? size_t(YY_ADDRESS_GET_BLOCK(Current)) : 0, Current); - YieldProcessor(); - } - } + if (Last == Current) + break; - if (!_interlockedbittestandreset((volatile long *)&pWaitBlock->flag, 0)) - { - //鏈潵鎴戞槸鎷掔粷鐨勶紝浣嗘槸杩愭皵濂斤紝鐘舵佸凡缁忓彂鐢熶簡鍙嶈浆 - return STATUS_SUCCESS; + Current = Last; + } + + if (Current & 1) + RtlpWaitOnAddressWakeEntireList(YY_ADDRESS_GET_BLOCK(Current)); + + + return; + } } + } - auto GlobalKeyedEventHandle = GetGlobalKeyedEventHandle(); - auto pNtWaitForKeyedEvent = try_get_NtWaitForKeyedEvent(); - if (!pNtWaitForKeyedEvent) - internal::RaiseStatus(STATUS_NOT_FOUND); + if (InterlockedExchange(&pWaitBlock->flag, 1) == 2) + return; - auto Status = pNtWaitForKeyedEvent(GlobalKeyedEventHandle, pWaitBlock, 0, TimeOut); + RtlpWaitOnAddressWithTimeout(pWaitBlock, 0); + } - if (Status == STATUS_TIMEOUT) + static NTSTATUS __fastcall RtlpWaitOnAddressWithTimeout(YY_ADDRESS_WAIT_BLOCK* pWaitBlock, LARGE_INTEGER *TimeOut) + { + //鍗曟牳 鎴戜滑鏃犻渶鑷棆锛岀洿鎺ヨ繘鍏ョ瓑寰呰繃绋嬪嵆鍙 + if (NtCurrentTeb()->ProcessEnvironmentBlock->NumberOfProcessors > 1 && RtlpWaitOnAddressSpinCount) + { + for (DWORD SpinCount = 0; SpinCount < RtlpWaitOnAddressSpinCount;++SpinCount) { - if (InterlockedExchange(&pWaitBlock->flag, 4) == 2) - { - Status = pNtWaitForKeyedEvent(GlobalKeyedEventHandle, pWaitBlock, 0, nullptr); - } - else + if ((pWaitBlock->flag & 1) == 0) { - RtlpWaitOnAddressRemoveWaitBlock(pWaitBlock); + //鑷棆杩囩▼涓紝绛夊埌浜嗕俊鍙锋敼鍙 + return STATUS_SUCCESS; } + + YieldProcessor(); } + } + + if (!_interlockedbittestandreset((volatile long *)&pWaitBlock->flag, 0)) + { + //鏈潵鎴戞槸鎷掔粷鐨勶紝浣嗘槸杩愭皵濂斤紝鐘舵佸凡缁忓彂鐢熶簡鍙嶈浆 + return STATUS_SUCCESS; + } + + auto GlobalKeyedEventHandle = GetGlobalKeyedEventHandle(); + auto pNtWaitForKeyedEvent = try_get_NtWaitForKeyedEvent(); + if (!pNtWaitForKeyedEvent) + internal::RaiseStatus(STATUS_NOT_FOUND); - return Status; + auto Status = pNtWaitForKeyedEvent(GlobalKeyedEventHandle, pWaitBlock, 0, TimeOut); + + if (Status == STATUS_TIMEOUT) + { + if (InterlockedExchange(&pWaitBlock->flag, 4) == 2) + { + Status = pNtWaitForKeyedEvent(GlobalKeyedEventHandle, pWaitBlock, 0, nullptr); + } + else + { + RtlpWaitOnAddressRemoveWaitBlock(pWaitBlock); + } } + return Status; + } + #if defined(_X86_) - #define RtlpWakeByAddress(Address, bWakeAll) YY_RtlpWakeByAddress(0, bWakeAll, Address) - static void __fastcall YY_RtlpWakeByAddress(DWORD dwReserved/*鐢ㄤ簬骞宠 鏍堥渶瑕侊紝鍒╀簬缂栬瘧鍣ㄤ紭鍖栨垚jmp*/, BOOL bWakeAll, LPVOID Address) + #define RtlpWakeByAddress(Address, bWakeAll) YY_RtlpWakeByAddress(0, bWakeAll, Address) + static void __fastcall YY_RtlpWakeByAddress(DWORD dwReserved/*鐢ㄤ簬骞宠 鏍堥渶瑕侊紝鍒╀簬缂栬瘧鍣ㄤ紭鍖栨垚jmp*/, BOOL bWakeAll, LPVOID Address) #else - static void __fastcall RtlpWakeByAddress(LPVOID Address, BOOL bWakeAll) + static void __fastcall RtlpWakeByAddress(LPVOID Address, BOOL bWakeAll) #endif - { - auto ppFirstBlock = GetBlockByWaitOnAddressHashTable(Address); - YY_ADDRESS_WAIT_BLOCK* LastWake = nullptr; + { + auto ppFirstBlock = GetBlockByWaitOnAddressHashTable(Address); + YY_ADDRESS_WAIT_BLOCK* LastWake = nullptr; - auto Current = *ppFirstBlock; - size_t Last; - bool bNoRemove = false; + auto Current = *ppFirstBlock; + size_t Last; + bool bNoRemove = false; - for (; Current && (Current & 1) ==0; Current = Last) + for (; Current && (Current & 1) ==0; Current = Last) + { + if (Current & 2) { - if (Current & 2) - { - Last = InterlockedCompareExchange(ppFirstBlock, Current | 1, Current); + Last = InterlockedCompareExchange(ppFirstBlock, Current | 1, Current); - if (Last == Current) - { - return; - } + if (Last == Current) + { + return; } - else + } + else + { + auto New = Current | 0x2; + Last = InterlockedCompareExchange(ppFirstBlock, New, Current); + + if (Last == Current) { - auto New = Current | 0x2; - Last = InterlockedCompareExchange(ppFirstBlock, New, Current); + Current = New; - if (Last == Current) - { - Current = New; + __retry: - __retry: + auto pBlock = YY_ADDRESS_GET_BLOCK(Current); + auto pItem = pBlock; - auto pBlock = YY_ADDRESS_GET_BLOCK(Current); - auto pItem = pBlock; + for (; pItem->next == nullptr;) + { + auto Tmp = pItem; + pItem = pItem->back; + pItem->notify = Tmp; + } - for (; pItem->next == nullptr;) - { - auto Tmp = pItem; - pItem = pItem->back; - pItem->notify = Tmp; - } + pItem = pItem->next; + pBlock->next = pItem; - pItem = pItem->next; - pBlock->next = pItem; + for (; pItem;) + { + auto notify = pItem->notify; - for (; pItem;) + if (pItem->Address == Address) { - auto notify = pItem->notify; - - if (pItem->Address == Address) + auto back = pItem->back; + if (pItem == pBlock) { - auto back = pItem->back; - if (pItem == pBlock) + New = size_t(back); + if (New) { - New = size_t(back); - if (New) - { - New = (Current ^ New) & 3 ^ New; - } + New = (Current ^ New) & 3 ^ New; + } - Last = InterlockedCompareExchange(ppFirstBlock, New, Current); + Last = InterlockedCompareExchange(ppFirstBlock, New, Current); - if (Last != Current) - { - //鎹釜濮垮娍锛屽啀鏉ヤ竴娆 - Current = Last; - goto __retry; - } + if (Last != Current) + { + //鎹釜濮垮娍锛屽啀鏉ヤ竴娆 + Current = Last; + goto __retry; + } - pBlock = YY_ADDRESS_GET_BLOCK(Last); + pBlock = YY_ADDRESS_GET_BLOCK(Last); - bNoRemove = New == 0; - if (back) - { - back->notify = nullptr; - back->next = pItem->next; - } + bNoRemove = New == 0; + if (back) + { + back->notify = nullptr; + back->next = pItem->next; + } + } + else + { + notify->back = back; + back = pItem->back; + auto notify = pItem->notify; + + if (back) + { + back->notify = notify; } else { - notify->back = back; - back = pItem->back; - auto notify = pItem->notify; - - if (back) - { - back->notify = notify; - } - else - { - pBlock->next = notify; - notify->next = notify; - } + pBlock->next = notify; + notify->next = notify; } + } - const auto LastFlag = InterlockedExchange(&pItem->flag, 2); + const auto LastFlag = InterlockedExchange(&pItem->flag, 2); - if (LastFlag != 2) + if (LastFlag != 2) + { + if (LastFlag == 0) { - if (LastFlag == 0) - { - pItem->back = LastWake; - LastWake = pItem; - } - - if (!bWakeAll) - break; + pItem->back = LastWake; + LastWake = pItem; } - } - pItem = notify; + if (!bWakeAll) + break; + } } - auto GlobalKeyedEventHandle = GetGlobalKeyedEventHandle(); - auto pNtReleaseKeyedEvent = try_get_NtReleaseKeyedEvent(); - if (!pNtReleaseKeyedEvent) - internal::RaiseStatus(STATUS_NOT_FOUND); + pItem = notify; + } - for (auto pItem = LastWake; pItem;) - { - //NtReleaseKeyedEvent 璋冪敤鍚 pItem 鍐呭瓨鍧楀彲鑳芥棤鏁堬紝鍥犳蹇呴』鍏堜繚瀛樹竴浠姐 - auto Tmp = pItem->back; + auto GlobalKeyedEventHandle = GetGlobalKeyedEventHandle(); + auto pNtReleaseKeyedEvent = try_get_NtReleaseKeyedEvent(); + if (!pNtReleaseKeyedEvent) + internal::RaiseStatus(STATUS_NOT_FOUND); - //鍞ら啋绛夊緟鐨凨ey - pNtReleaseKeyedEvent(GlobalKeyedEventHandle, pItem, FALSE, nullptr); + for (auto pItem = LastWake; pItem;) + { + //NtReleaseKeyedEvent 璋冪敤鍚 pItem 鍐呭瓨鍧楀彲鑳芥棤鏁堬紝鍥犳蹇呴』鍏堜繚瀛樹竴浠姐 + auto Tmp = pItem->back; - pItem = Tmp; - } + //鍞ら啋绛夊緟鐨凨ey + pNtReleaseKeyedEvent(GlobalKeyedEventHandle, pItem, FALSE, nullptr); - if (!bNoRemove) - { - //鏇存柊鏍囧ご鍧 + pItem = Tmp; + } + if (!bNoRemove) + { + //鏇存柊鏍囧ご鍧 - for (auto Current = *ppFirstBlock;;) - { - const auto Last = InterlockedCompareExchange(ppFirstBlock, (Current & 1) == 0 ? size_t(YY_ADDRESS_GET_BLOCK(Current)) : 0, Current); - if (Last == Current) - { - if(Current & 1) - RtlpWaitOnAddressWakeEntireList(YY_ADDRESS_GET_BLOCK(Current)); + for (auto Current = *ppFirstBlock;;) + { + const auto Last = InterlockedCompareExchange(ppFirstBlock, (Current & 1) == 0 ? size_t(YY_ADDRESS_GET_BLOCK(Current)) : 0, Current); - break; - } + if (Last == Current) + { + if(Current & 1) + RtlpWaitOnAddressWakeEntireList(YY_ADDRESS_GET_BLOCK(Current)); - Current = Last; + break; } - } - return; + Current = Last; + } } + + return; } } - } -#endif + } +#endif + } +} #endif - +namespace YY::Thunks +{ #if (YY_Thunks_Support_Version < NTDDI_WIN6) - //Windows Vista, Windows Server 2008 - __DEFINE_THUNK( - kernel32, - 12, - BOOL, - WINAPI, - InitializeCriticalSectionEx, - _Out_ LPCRITICAL_SECTION lpCriticalSection, - _In_ DWORD dwSpinCount, - _In_ DWORD Flags - ) + //Windows Vista, Windows Server 2008 + __DEFINE_THUNK( + kernel32, + 12, + BOOL, + WINAPI, + InitializeCriticalSectionEx, + _Out_ LPCRITICAL_SECTION lpCriticalSection, + _In_ DWORD dwSpinCount, + _In_ DWORD Flags + ) + { + if (auto const pInitializeCriticalSectionEx = try_get_InitializeCriticalSectionEx()) { - if (auto const pInitializeCriticalSectionEx = try_get_InitializeCriticalSectionEx()) - { - return pInitializeCriticalSectionEx(lpCriticalSection, dwSpinCount, Flags); - } - - return InitializeCriticalSectionAndSpinCount(lpCriticalSection, dwSpinCount); + return pInitializeCriticalSectionEx(lpCriticalSection, dwSpinCount, Flags); } + + return InitializeCriticalSectionAndSpinCount(lpCriticalSection, dwSpinCount); + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN6) - //Windows Vista [desktop apps | UWP apps] - //Windows Server 2008 [desktop apps | UWP apps] - __DEFINE_THUNK( - kernel32, - 4, - VOID, - WINAPI, - InitOnceInitialize, - _Out_ PINIT_ONCE InitOnce - ) - { - *InitOnce = INIT_ONCE_STATIC_INIT; - } + //Windows Vista [desktop apps | UWP apps] + //Windows Server 2008 [desktop apps | UWP apps] + __DEFINE_THUNK( + kernel32, + 4, + VOID, + WINAPI, + InitOnceInitialize, + _Out_ PINIT_ONCE InitOnce + ) + { + *InitOnce = INIT_ONCE_STATIC_INIT; + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN6) - //Windows Vista [desktop apps | UWP apps] - //Windows Server 2008 [desktop apps | UWP apps] - __DEFINE_THUNK( - kernel32, - 16, - _Success_(return) - BOOL, - WINAPI, - InitOnceBeginInitialize, - _Inout_ LPINIT_ONCE lpInitOnce, - _In_ DWORD dwFlags, - _Out_ PBOOL fPending, - _Outptr_opt_result_maybenull_ LPVOID* lpContext - ) + //Windows Vista [desktop apps | UWP apps] + //Windows Server 2008 [desktop apps | UWP apps] + __DEFINE_THUNK( + kernel32, + 16, + _Success_(return) + BOOL, + WINAPI, + InitOnceBeginInitialize, + _Inout_ LPINIT_ONCE lpInitOnce, + _In_ DWORD dwFlags, + _Out_ PBOOL fPending, + _Outptr_opt_result_maybenull_ LPVOID* lpContext + ) + { + if (auto const pInitOnceBeginInitialize = try_get_InitOnceBeginInitialize()) { - if (auto const pInitOnceBeginInitialize = try_get_InitOnceBeginInitialize()) - { - return pInitOnceBeginInitialize(lpInitOnce, dwFlags, fPending, lpContext); - } + return pInitOnceBeginInitialize(lpInitOnce, dwFlags, fPending, lpContext); + } - auto Status = internal::RtlRunOnceBeginInitialize(lpInitOnce, dwFlags, lpContext); + auto Status = internal::RtlRunOnceBeginInitialize(lpInitOnce, dwFlags, lpContext); - if (Status >= STATUS_SUCCESS) - { - *fPending = Status == STATUS_PENDING; - return TRUE; - } - else - { - internal::BaseSetLastNTError(Status); - return FALSE; - } + if (Status >= STATUS_SUCCESS) + { + *fPending = Status == STATUS_PENDING; + return TRUE; + } + else + { + internal::BaseSetLastNTError(Status); + return FALSE; } + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN6) - //Windows Vista [desktop apps | UWP apps] - //Windows Server 2008 [desktop apps | UWP apps] - __DEFINE_THUNK( - kernel32, - 12, - BOOL, - WINAPI, - InitOnceComplete, - _Inout_ LPINIT_ONCE lpInitOnce, - _In_ DWORD dwFlags, - _In_opt_ LPVOID lpContext - ) + //Windows Vista [desktop apps | UWP apps] + //Windows Server 2008 [desktop apps | UWP apps] + __DEFINE_THUNK( + kernel32, + 12, + BOOL, + WINAPI, + InitOnceComplete, + _Inout_ LPINIT_ONCE lpInitOnce, + _In_ DWORD dwFlags, + _In_opt_ LPVOID lpContext + ) + { + if (auto const pInitOnceComplete = try_get_InitOnceComplete()) { - if (auto const pInitOnceComplete = try_get_InitOnceComplete()) - { - return pInitOnceComplete(lpInitOnce, dwFlags, lpContext); - } + return pInitOnceComplete(lpInitOnce, dwFlags, lpContext); + } - auto Status = internal::RtlRunOnceComplete(lpInitOnce, dwFlags, lpContext); + auto Status = internal::RtlRunOnceComplete(lpInitOnce, dwFlags, lpContext); - if (Status >= 0) - { - return TRUE; - } - else - { - internal::BaseSetLastNTError(Status); - return FALSE; - } + if (Status >= 0) + { + return TRUE; } + else + { + internal::BaseSetLastNTError(Status); + return FALSE; + } + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN6) - //Windows Vista [desktop apps | UWP apps] - //Windows Server 2008 [desktop apps | UWP apps] - __DEFINE_THUNK( - kernel32, - 16, - BOOL, - WINAPI, - InitOnceExecuteOnce, - _Inout_ PINIT_ONCE InitOnce, - _In_ __callback PINIT_ONCE_FN InitFn, - _Inout_opt_ PVOID Parameter, - _Outptr_opt_result_maybenull_ LPVOID* Context - ) + //Windows Vista [desktop apps | UWP apps] + //Windows Server 2008 [desktop apps | UWP apps] + __DEFINE_THUNK( + kernel32, + 16, + BOOL, + WINAPI, + InitOnceExecuteOnce, + _Inout_ PINIT_ONCE InitOnce, + _In_ __callback PINIT_ONCE_FN InitFn, + _Inout_opt_ PVOID Parameter, + _Outptr_opt_result_maybenull_ LPVOID* Context + ) + { + if (auto const pInitOnceExecuteOnce = try_get_InitOnceExecuteOnce()) { - if (auto const pInitOnceExecuteOnce = try_get_InitOnceExecuteOnce()) - { - return pInitOnceExecuteOnce(InitOnce, InitFn, Parameter, Context); - } + return pInitOnceExecuteOnce(InitOnce, InitFn, Parameter, Context); + } - auto Status = internal::RtlRunOnceBeginInitialize(InitOnce, 0, Context); + auto Status = internal::RtlRunOnceBeginInitialize(InitOnce, 0, Context); - ULONG_PTR ExceptionArgument; + ULONG_PTR ExceptionArgument; - do + do + { + if (Status < STATUS_SUCCESS) { - if (Status < STATUS_SUCCESS) - { - ExceptionArgument = 0; - } - else if (Status == STATUS_PENDING) + ExceptionArgument = 0; + } + else if (Status == STATUS_PENDING) + { + if (InitFn(InitOnce, Parameter, Context)) { - if (InitFn(InitOnce, Parameter, Context)) - { - auto NewContext = Context; - if (NewContext) - NewContext = (LPVOID*)*NewContext; + auto NewContext = Context; + if (NewContext) + NewContext = (LPVOID*)*NewContext; - Status = internal::RtlRunOnceComplete(InitOnce, 0, NewContext); + Status = internal::RtlRunOnceComplete(InitOnce, 0, NewContext); - if (Status >= STATUS_SUCCESS) - break; + if (Status >= STATUS_SUCCESS) + break; - ExceptionArgument = 1; - } - else - { - Status = internal::RtlRunOnceComplete(InitOnce, RTL_RUN_ONCE_INIT_FAILED, nullptr); - if (Status >= STATUS_SUCCESS) - { - Status = STATUS_UNSUCCESSFUL; - break; - } - ExceptionArgument = 2; - } + ExceptionArgument = 1; } else { - break; + Status = internal::RtlRunOnceComplete(InitOnce, RTL_RUN_ONCE_INIT_FAILED, nullptr); + if (Status >= STATUS_SUCCESS) + { + Status = STATUS_UNSUCCESSFUL; + break; + } + ExceptionArgument = 2; } + } + else + { + break; + } - RaiseException(Status, EXCEPTION_NONCONTINUABLE, 1, &ExceptionArgument); + RaiseException(Status, EXCEPTION_NONCONTINUABLE, 1, &ExceptionArgument); - } while (false); + } while (false); - //鍒棶鎴戜负浠涔堜笉璁剧疆LastError鈥︹︼紝Windows 7鐨勮繖涓嚱鏁颁篃娌¤缃 LastError锛屾棦鐒惰繖鏍凤紝鎴戜滑閮藉伔鎳掍笅鍚э紝琛屼负璺熷井杞繚鎸佷竴鑷淬 - return Status >= STATUS_SUCCESS; - } + //鍒棶鎴戜负浠涔堜笉璁剧疆LastError鈥︹︼紝Windows 7鐨勮繖涓嚱鏁颁篃娌¤缃 LastError锛屾棦鐒惰繖鏍凤紝鎴戜滑閮藉伔鎳掍笅鍚э紝琛屼负璺熷井杞繚鎸佷竴鑷淬 + return Status >= STATUS_SUCCESS; + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN6) - //Windows Vista [desktop apps | UWP apps] - //Windows Server 2008 [desktop apps | UWP apps] - __DEFINE_THUNK( - kernel32, - 16, - HANDLE, - WINAPI, - CreateEventExW, - _In_opt_ LPSECURITY_ATTRIBUTES lpEventAttributes, - _In_opt_ LPCWSTR lpName, - _In_ DWORD dwFlags, - _In_ DWORD dwDesiredAccess - ) + //Windows Vista [desktop apps | UWP apps] + //Windows Server 2008 [desktop apps | UWP apps] + __DEFINE_THUNK( + kernel32, + 16, + HANDLE, + WINAPI, + CreateEventExW, + _In_opt_ LPSECURITY_ATTRIBUTES lpEventAttributes, + _In_opt_ LPCWSTR lpName, + _In_ DWORD dwFlags, + _In_ DWORD dwDesiredAccess + ) + { + if (auto pCreateEventExW = try_get_CreateEventExW()) { - if (auto pCreateEventExW = try_get_CreateEventExW()) - { - return pCreateEventExW(lpEventAttributes, lpName, dwFlags, dwDesiredAccess); - } - - return CreateEventW(lpEventAttributes, dwFlags & CREATE_EVENT_MANUAL_RESET, dwFlags & CREATE_EVENT_INITIAL_SET, lpName); + return pCreateEventExW(lpEventAttributes, lpName, dwFlags, dwDesiredAccess); } + + return CreateEventW(lpEventAttributes, dwFlags & CREATE_EVENT_MANUAL_RESET, dwFlags & CREATE_EVENT_INITIAL_SET, lpName); + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN6) - //Windows Vista [desktop apps | UWP apps] - //Windows Server 2008 [desktop apps | UWP apps] - __DEFINE_THUNK( - kernel32, - 16, - HANDLE, - WINAPI, - CreateEventExA, - _In_opt_ LPSECURITY_ATTRIBUTES lpEventAttributes, - _In_opt_ LPCSTR lpName, - _In_ DWORD dwFlags, - _In_ DWORD dwDesiredAccess - ) + //Windows Vista [desktop apps | UWP apps] + //Windows Server 2008 [desktop apps | UWP apps] + __DEFINE_THUNK( + kernel32, + 16, + HANDLE, + WINAPI, + CreateEventExA, + _In_opt_ LPSECURITY_ATTRIBUTES lpEventAttributes, + _In_opt_ LPCSTR lpName, + _In_ DWORD dwFlags, + _In_ DWORD dwDesiredAccess + ) + { + if (auto pCreateEventExA = try_get_CreateEventExA()) { - if (auto pCreateEventExA = try_get_CreateEventExA()) - { - return pCreateEventExA(lpEventAttributes, lpName, dwFlags, dwDesiredAccess); - } - - return CreateEventA(lpEventAttributes, dwFlags & CREATE_EVENT_MANUAL_RESET, dwFlags & CREATE_EVENT_INITIAL_SET, lpName); + return pCreateEventExA(lpEventAttributes, lpName, dwFlags, dwDesiredAccess); } + + return CreateEventA(lpEventAttributes, dwFlags & CREATE_EVENT_MANUAL_RESET, dwFlags & CREATE_EVENT_INITIAL_SET, lpName); + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN6) - //Windows Vista [desktop apps | UWP apps] - //Windows Server 2008 [desktop apps | UWP apps] - __DEFINE_THUNK( - kernel32, - 16, - HANDLE, - WINAPI, - CreateMutexExW, - _In_opt_ LPSECURITY_ATTRIBUTES lpMutexAttributes, - _In_opt_ LPCWSTR lpName, - _In_ DWORD dwFlags, - _In_ DWORD dwDesiredAccess - ) + //Windows Vista [desktop apps | UWP apps] + //Windows Server 2008 [desktop apps | UWP apps] + __DEFINE_THUNK( + kernel32, + 16, + HANDLE, + WINAPI, + CreateMutexExW, + _In_opt_ LPSECURITY_ATTRIBUTES lpMutexAttributes, + _In_opt_ LPCWSTR lpName, + _In_ DWORD dwFlags, + _In_ DWORD dwDesiredAccess + ) + { + if (auto pCreateMutexExW = try_get_CreateMutexExW()) { - if (auto pCreateMutexExW = try_get_CreateMutexExW()) - { - return pCreateMutexExW(lpMutexAttributes, lpName, dwFlags, dwDesiredAccess); - } - - return CreateMutexW(lpMutexAttributes, dwFlags & CREATE_MUTEX_INITIAL_OWNER, lpName); + return pCreateMutexExW(lpMutexAttributes, lpName, dwFlags, dwDesiredAccess); } + + return CreateMutexW(lpMutexAttributes, dwFlags & CREATE_MUTEX_INITIAL_OWNER, lpName); + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN6) - //Windows Vista [desktop apps | UWP apps] - //Windows Server 2008 [desktop apps | UWP apps] - __DEFINE_THUNK( - kernel32, - 16, - HANDLE, - WINAPI, - CreateMutexExA, - _In_opt_ LPSECURITY_ATTRIBUTES lpMutexAttributes, - _In_opt_ LPCSTR lpName, - _In_ DWORD dwFlags, - _In_ DWORD dwDesiredAccess - ) + //Windows Vista [desktop apps | UWP apps] + //Windows Server 2008 [desktop apps | UWP apps] + __DEFINE_THUNK( + kernel32, + 16, + HANDLE, + WINAPI, + CreateMutexExA, + _In_opt_ LPSECURITY_ATTRIBUTES lpMutexAttributes, + _In_opt_ LPCSTR lpName, + _In_ DWORD dwFlags, + _In_ DWORD dwDesiredAccess + ) + { + if (auto pCreateMutexExA = try_get_CreateMutexExA()) { - if (auto pCreateMutexExA = try_get_CreateMutexExA()) - { - return pCreateMutexExA(lpMutexAttributes, lpName, dwFlags, dwDesiredAccess); - } - - return CreateMutexA(lpMutexAttributes, dwFlags & CREATE_MUTEX_INITIAL_OWNER, lpName); + return pCreateMutexExA(lpMutexAttributes, lpName, dwFlags, dwDesiredAccess); } + + return CreateMutexA(lpMutexAttributes, dwFlags & CREATE_MUTEX_INITIAL_OWNER, lpName); + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN6) - //Windows Vista [desktop apps | UWP apps] - //Windows Server 2008 [desktop apps | UWP apps] - __DEFINE_THUNK( - kernel32, - 24, - HANDLE, - WINAPI, - CreateSemaphoreExW, - _In_opt_ LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, - _In_ LONG lInitialCount, - _In_ LONG lMaximumCount, - _In_opt_ LPCWSTR lpName, - _Reserved_ DWORD dwFlags, - _In_ DWORD dwDesiredAccess - ) + //Windows Vista [desktop apps | UWP apps] + //Windows Server 2008 [desktop apps | UWP apps] + __DEFINE_THUNK( + kernel32, + 24, + HANDLE, + WINAPI, + CreateSemaphoreExW, + _In_opt_ LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, + _In_ LONG lInitialCount, + _In_ LONG lMaximumCount, + _In_opt_ LPCWSTR lpName, + _Reserved_ DWORD dwFlags, + _In_ DWORD dwDesiredAccess + ) + { + if (auto pCreateSemaphoreExW = try_get_CreateSemaphoreExW()) { - if (auto pCreateSemaphoreExW = try_get_CreateSemaphoreExW()) - { - return pCreateSemaphoreExW(lpSemaphoreAttributes, lInitialCount, lMaximumCount, lpName, dwFlags, dwDesiredAccess); - } - - return CreateSemaphoreW(lpSemaphoreAttributes, lInitialCount, lMaximumCount, lpName); + return pCreateSemaphoreExW(lpSemaphoreAttributes, lInitialCount, lMaximumCount, lpName, dwFlags, dwDesiredAccess); } + + return CreateSemaphoreW(lpSemaphoreAttributes, lInitialCount, lMaximumCount, lpName); + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN6) - //Windows Vista [desktop apps | UWP apps] - //Windows Server 2008 [desktop apps | UWP apps] - __DEFINE_THUNK( - kernel32, - 16, - HANDLE, - WINAPI, - CreateWaitableTimerExW, - _In_opt_ LPSECURITY_ATTRIBUTES lpTimerAttributes, - _In_opt_ LPCWSTR lpTimerName, - _In_ DWORD dwFlags, - _In_ DWORD dwDesiredAccess - ) + //Windows Vista [desktop apps | UWP apps] + //Windows Server 2008 [desktop apps | UWP apps] + __DEFINE_THUNK( + kernel32, + 16, + HANDLE, + WINAPI, + CreateWaitableTimerExW, + _In_opt_ LPSECURITY_ATTRIBUTES lpTimerAttributes, + _In_opt_ LPCWSTR lpTimerName, + _In_ DWORD dwFlags, + _In_ DWORD dwDesiredAccess + ) + { + if (auto pCreateWaitableTimerExW = try_get_CreateWaitableTimerExW()) { - if (auto pCreateWaitableTimerExW = try_get_CreateWaitableTimerExW()) - { - return pCreateWaitableTimerExW(lpTimerAttributes, lpTimerName, dwFlags, dwDesiredAccess); - } - - return CreateWaitableTimerW(lpTimerAttributes, dwFlags&CREATE_WAITABLE_TIMER_MANUAL_RESET, lpTimerName); + return pCreateWaitableTimerExW(lpTimerAttributes, lpTimerName, dwFlags, dwDesiredAccess); } + + return CreateWaitableTimerW(lpTimerAttributes, dwFlags&CREATE_WAITABLE_TIMER_MANUAL_RESET, lpTimerName); + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN6) - //Windows Vista [desktop apps | UWP apps] - //Windows Server 2008 [desktop apps | UWP apps] - __DEFINE_THUNK( - kernel32, - 4, - VOID, - WINAPI, - InitializeSRWLock, - _Out_ PSRWLOCK SRWLock - ) - { - *SRWLock = RTL_SRWLOCK_INIT; - } + //Windows Vista [desktop apps | UWP apps] + //Windows Server 2008 [desktop apps | UWP apps] + __DEFINE_THUNK( + kernel32, + 4, + VOID, + WINAPI, + InitializeSRWLock, + _Out_ PSRWLOCK SRWLock + ) + { + *SRWLock = RTL_SRWLOCK_INIT; + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN6) - //Windows Vista [desktop apps | UWP apps] - //Windows Server 2008 [desktop apps | UWP apps] - __DEFINE_THUNK( - kernel32, - 4, - VOID, - WINAPI, - AcquireSRWLockExclusive, - _Inout_ PSRWLOCK SRWLock - ) + //Windows Vista [desktop apps | UWP apps] + //Windows Server 2008 [desktop apps | UWP apps] + __DEFINE_THUNK( + kernel32, + 4, + VOID, + WINAPI, + AcquireSRWLockExclusive, + _Inout_ PSRWLOCK SRWLock + ) + { + if (auto const pAcquireSRWLockExclusive = try_get_AcquireSRWLockExclusive()) { - if (auto const pAcquireSRWLockExclusive = try_get_AcquireSRWLockExclusive()) - { - return pAcquireSRWLockExclusive(SRWLock); - } + return pAcquireSRWLockExclusive(SRWLock); + } - YY_SRWLOCK_WAIT_BLOCK StackWaitBlock; - bool bOptimize; + YY_SRWLOCK_WAIT_BLOCK StackWaitBlock; + bool bOptimize; - //灏濊瘯鍔犻攣涓娆 + //灏濊瘯鍔犻攣涓娆 #if defined(_WIN64) - auto OldBit = InterlockedBitTestAndSet64((volatile LONG_PTR*)SRWLock, YY_SRWLOCK_Locked_BIT); + auto OldBit = InterlockedBitTestAndSet64((volatile LONG_PTR*)SRWLock, YY_SRWLOCK_Locked_BIT); #else - auto OldBit = InterlockedBitTestAndSet((volatile LONG_PTR*)SRWLock, YY_SRWLOCK_Locked_BIT); + auto OldBit = InterlockedBitTestAndSet((volatile LONG_PTR*)SRWLock, YY_SRWLOCK_Locked_BIT); #endif - if(OldBit == false) - { - //鎴愬姛閿佸畾 - return; - } - - for (;;) - { - auto SRWLockOld = *(volatile size_t*)SRWLock; + if(OldBit == false) + { + //鎴愬姛閿佸畾 + return; + } - if (YY_SRWLOCK_Locked & SRWLockOld) - { - /* - if (RtlpWaitCouldDeadlock()) - ZwTerminateProcess((HANDLE)0xFFFFFFFF, 0xC000004B); - */ + for (;;) + { + auto SRWLockOld = *(volatile size_t*)SRWLock; - StackWaitBlock.next = nullptr; - StackWaitBlock.flag = 3; - bOptimize = false; + if (YY_SRWLOCK_Locked & SRWLockOld) + { + /* + if (RtlpWaitCouldDeadlock()) + ZwTerminateProcess((HANDLE)0xFFFFFFFF, 0xC000004B); + */ - size_t SRWLockNew; + StackWaitBlock.next = nullptr; + StackWaitBlock.flag = 3; + bOptimize = false; - if (YY_SRWLOCK_Waiting & SRWLockOld) - { - //鏈変汉姝e湪绛夊緟杩炴帴 - StackWaitBlock.notify = nullptr; - StackWaitBlock.shareCount = 0; - StackWaitBlock.back = (YY_SRWLOCK_WAIT_BLOCK*)(SRWLockOld & (~YY_SRWLOCK_MASK)); + size_t SRWLockNew; - SRWLockNew = (size_t)(&StackWaitBlock) | (SRWLockOld & YY_SRWLOCK_MultipleShared) | YY_SRWLOCK_Waking | YY_SRWLOCK_Waiting | YY_SRWLOCK_Locked; + if (YY_SRWLOCK_Waiting & SRWLockOld) + { + //鏈変汉姝e湪绛夊緟杩炴帴 + StackWaitBlock.notify = nullptr; + StackWaitBlock.shareCount = 0; + StackWaitBlock.back = (YY_SRWLOCK_WAIT_BLOCK*)(SRWLockOld & (~YY_SRWLOCK_MASK)); - if ((YY_SRWLOCK_Waking & SRWLockOld) == 0) - { - bOptimize = true; - } - } - else + SRWLockNew = (size_t)(&StackWaitBlock) | (SRWLockOld & YY_SRWLOCK_MultipleShared) | YY_SRWLOCK_Waking | YY_SRWLOCK_Waiting | YY_SRWLOCK_Locked; + + if ((YY_SRWLOCK_Waking & SRWLockOld) == 0) { - //娌℃湁鍏朵粬浜烘病鏈夌瓑寰咃紝鎵浠ユ垜浠渶瑕佸垱寤轰竴涓 - StackWaitBlock.notify = (YY_SRWLOCK_WAIT_BLOCK*)&StackWaitBlock; - StackWaitBlock.shareCount = (SRWLockOld >> YY_SRWLOCK_BITS); + bOptimize = true; + } + } + else + { + //娌℃湁鍏朵粬浜烘病鏈夌瓑寰咃紝鎵浠ユ垜浠渶瑕佸垱寤轰竴涓 + StackWaitBlock.notify = (YY_SRWLOCK_WAIT_BLOCK*)&StackWaitBlock; + StackWaitBlock.shareCount = (SRWLockOld >> YY_SRWLOCK_BITS); - SRWLockNew = StackWaitBlock.shareCount > 1 ? - (size_t)(&StackWaitBlock) | YY_SRWLOCK_MultipleShared | YY_SRWLOCK_Waiting | YY_SRWLOCK_Locked - : (size_t)(&StackWaitBlock) | YY_SRWLOCK_Waiting | YY_SRWLOCK_Locked; - } + SRWLockNew = StackWaitBlock.shareCount > 1 ? + (size_t)(&StackWaitBlock) | YY_SRWLOCK_MultipleShared | YY_SRWLOCK_Waiting | YY_SRWLOCK_Locked + : (size_t)(&StackWaitBlock) | YY_SRWLOCK_Waiting | YY_SRWLOCK_Locked; + } - if (InterlockedCompareExchange((volatile size_t*)SRWLock, SRWLockNew, SRWLockOld) != SRWLockOld) - { - //鏇存柊閿佺姸鎬佸け璐ワ紝鍏朵粬绾跨▼姝e湪澶勭悊鏀归攣锛岃涓嶅拫浠崲涓Э鍔垮啀鏉 + if (InterlockedCompareExchange((volatile size_t*)SRWLock, SRWLockNew, SRWLockOld) != SRWLockOld) + { + //鏇存柊閿佺姸鎬佸け璐ワ紝鍏朵粬绾跨▼姝e湪澶勭悊鏀归攣锛岃涓嶅拫浠崲涓Э鍔垮啀鏉 - //RtlBackoff灏辨噿寰楀仛浜嗭紝鍙嶆鍙槸绛夊緟涓浼氳屽凡锛岀洿鎺ieldProcessor鍐嶆潵涓娆″惂銆 - //RtlBackoff(&nBackOff) + //RtlBackoff灏辨噿寰楀仛浜嗭紝鍙嶆鍙槸绛夊緟涓浼氳屽凡锛岀洿鎺ieldProcessor鍐嶆潵涓娆″惂銆 + //RtlBackoff(&nBackOff) - YieldProcessor(); - continue; - } + YieldProcessor(); + continue; + } - if (bOptimize) - { - internal::RtlpOptimizeSRWLockList(SRWLock, SRWLockNew); - } + if (bOptimize) + { + internal::RtlpOptimizeSRWLockList(SRWLock, SRWLockNew); + } - auto GlobalKeyedEventHandle = internal::GetGlobalKeyedEventHandle(); - auto pNtWaitForKeyedEvent = try_get_NtWaitForKeyedEvent(); - if (!pNtWaitForKeyedEvent) - { - internal::RaiseStatus(STATUS_RESOURCE_NOT_OWNED); - } + auto GlobalKeyedEventHandle = internal::GetGlobalKeyedEventHandle(); + auto pNtWaitForKeyedEvent = try_get_NtWaitForKeyedEvent(); + if (!pNtWaitForKeyedEvent) + { + internal::RaiseStatus(STATUS_RESOURCE_NOT_OWNED); + } - //鑷棆 - for (DWORD SpinCount = SRWLockSpinCount; SpinCount; --SpinCount) - { - if ((StackWaitBlock.flag & 2) == 0) - break; + //鑷棆 + for (DWORD SpinCount = SRWLockSpinCount; SpinCount; --SpinCount) + { + if ((StackWaitBlock.flag & 2) == 0) + break; - YieldProcessor(); - } + YieldProcessor(); + } - if (InterlockedBitTestAndReset((volatile LONG*)&StackWaitBlock.flag, 1)) - { - pNtWaitForKeyedEvent(GlobalKeyedEventHandle, (PVOID)&StackWaitBlock, 0, nullptr); - } + if (InterlockedBitTestAndReset((volatile LONG*)&StackWaitBlock.flag, 1)) + { + pNtWaitForKeyedEvent(GlobalKeyedEventHandle, (PVOID)&StackWaitBlock, 0, nullptr); } - else + } + else + { + //灏濊瘯鑾峰彇閿佺殑鎵鏈夋潈 + if (InterlockedCompareExchange((volatile size_t*)SRWLock, SRWLockOld | YY_SRWLOCK_Locked, SRWLockOld) == SRWLockOld) { - //灏濊瘯鑾峰彇閿佺殑鎵鏈夋潈 - if (InterlockedCompareExchange((volatile size_t*)SRWLock, SRWLockOld | YY_SRWLOCK_Locked, SRWLockOld) == SRWLockOld) - { - //鎴愬姛鍔犻攣 - return; - } - - //鍙兘澶氱嚎绋嬪苟鍙戣闂紝鎹釜濮垮娍鍐嶆潵涓娆 - YieldProcessor(); + //鎴愬姛鍔犻攣 + return; } + + //鍙兘澶氱嚎绋嬪苟鍙戣闂紝鎹釜濮垮娍鍐嶆潵涓娆 + YieldProcessor(); } } + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN7) - //Windows 7 [desktop apps | UWP apps] - //Windows Server 2008 R2 [desktop apps | UWP apps] - __DEFINE_THUNK( - kernel32, - 4, - BOOLEAN, - WINAPI, - TryAcquireSRWLockExclusive, - _Inout_ PSRWLOCK SRWLock - ) + //Windows 7 [desktop apps | UWP apps] + //Windows Server 2008 R2 [desktop apps | UWP apps] + __DEFINE_THUNK( + kernel32, + 4, + BOOLEAN, + WINAPI, + TryAcquireSRWLockExclusive, + _Inout_ PSRWLOCK SRWLock + ) + { + if (auto const pTryAcquireSRWLockExclusive = try_get_TryAcquireSRWLockExclusive()) { - if (auto const pTryAcquireSRWLockExclusive = try_get_TryAcquireSRWLockExclusive()) - { - return pTryAcquireSRWLockExclusive(SRWLock); - } + return pTryAcquireSRWLockExclusive(SRWLock); + } #if defined(_WIN64) - return InterlockedBitTestAndSet64((volatile LONG_PTR*)SRWLock, YY_SRWLOCK_Locked_BIT) == 0; + return InterlockedBitTestAndSet64((volatile LONG_PTR*)SRWLock, YY_SRWLOCK_Locked_BIT) == 0; #else - return InterlockedBitTestAndSet((volatile LONG_PTR*)SRWLock, YY_SRWLOCK_Locked_BIT) == 0; + return InterlockedBitTestAndSet((volatile LONG_PTR*)SRWLock, YY_SRWLOCK_Locked_BIT) == 0; #endif - } + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN6) - //Windows Vista [desktop apps | UWP apps] - //Windows Server 2008 [desktop apps | UWP apps] - __DEFINE_THUNK( - kernel32, - 4, - VOID, - WINAPI, - ReleaseSRWLockExclusive, - _Inout_ PSRWLOCK SRWLock - ) + //Windows Vista [desktop apps | UWP apps] + //Windows Server 2008 [desktop apps | UWP apps] + __DEFINE_THUNK( + kernel32, + 4, + VOID, + WINAPI, + ReleaseSRWLockExclusive, + _Inout_ PSRWLOCK SRWLock + ) + { + if (auto const pReleaseSRWLockExclusive = try_get_ReleaseSRWLockExclusive()) { - if (auto const pReleaseSRWLockExclusive = try_get_ReleaseSRWLockExclusive()) - { - return pReleaseSRWLockExclusive(SRWLock); - } + return pReleaseSRWLockExclusive(SRWLock); + } - auto OldSRWLock = InterlockedExchangeAdd((volatile size_t *)SRWLock, size_t(-1)); - if ((OldSRWLock & YY_SRWLOCK_Locked) == 0) - { - internal::RaiseStatus(STATUS_RESOURCE_NOT_OWNED); - } + auto OldSRWLock = InterlockedExchangeAdd((volatile size_t *)SRWLock, size_t(-1)); + if ((OldSRWLock & YY_SRWLOCK_Locked) == 0) + { + internal::RaiseStatus(STATUS_RESOURCE_NOT_OWNED); + } - if ((OldSRWLock & YY_SRWLOCK_Waiting) && (OldSRWLock & YY_SRWLOCK_Waking) == 0) - { - OldSRWLock -= YY_SRWLOCK_Locked; + if ((OldSRWLock & YY_SRWLOCK_Waiting) && (OldSRWLock & YY_SRWLOCK_Waking) == 0) + { + OldSRWLock -= YY_SRWLOCK_Locked; - auto NewSRWLock = OldSRWLock | YY_SRWLOCK_Waking; - auto CurrentSRWLock = InterlockedCompareExchange((volatile size_t *)SRWLock, NewSRWLock, OldSRWLock); + auto NewSRWLock = OldSRWLock | YY_SRWLOCK_Waking; + auto CurrentSRWLock = InterlockedCompareExchange((volatile size_t *)SRWLock, NewSRWLock, OldSRWLock); - if (CurrentSRWLock == OldSRWLock) - internal::RtlpWakeSRWLock(SRWLock, NewSRWLock); - } + if (CurrentSRWLock == OldSRWLock) + internal::RtlpWakeSRWLock(SRWLock, NewSRWLock); } + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN6) - //Windows Vista [desktop apps | UWP apps] - //Windows Server 2008 [desktop apps | UWP apps] - __DEFINE_THUNK( - kernel32, - 4, - VOID, - WINAPI, - AcquireSRWLockShared, - _Inout_ PSRWLOCK SRWLock - ) + //Windows Vista [desktop apps | UWP apps] + //Windows Server 2008 [desktop apps | UWP apps] + __DEFINE_THUNK( + kernel32, + 4, + VOID, + WINAPI, + AcquireSRWLockShared, + _Inout_ PSRWLOCK SRWLock + ) + { + if (auto const pAcquireSRWLockShared = try_get_AcquireSRWLockShared()) { - if (auto const pAcquireSRWLockShared = try_get_AcquireSRWLockShared()) - { - return pAcquireSRWLockShared(SRWLock); - } + return pAcquireSRWLockShared(SRWLock); + } - YY_SRWLOCK_WAIT_BLOCK StackWaitBlock; - bool bOptimize; + YY_SRWLOCK_WAIT_BLOCK StackWaitBlock; + bool bOptimize; - //灏濊瘯缁欏叏鏂扮殑閿佸姞閿 - auto OldSRWLock = InterlockedCompareExchange((volatile size_t*)SRWLock, size_t(0x11), 0); + //灏濊瘯缁欏叏鏂扮殑閿佸姞閿 + auto OldSRWLock = InterlockedCompareExchange((volatile size_t*)SRWLock, size_t(0x11), 0); - //鎴愬姛 - if (OldSRWLock == size_t(0)) - { - return; - } + //鎴愬姛 + if (OldSRWLock == size_t(0)) + { + return; + } - size_t NewSRWLock; + size_t NewSRWLock; - for (;; OldSRWLock = *(volatile size_t *)SRWLock) + for (;; OldSRWLock = *(volatile size_t *)SRWLock) + { + if ((OldSRWLock & YY_SRWLOCK_Locked) && ((OldSRWLock & YY_SRWLOCK_Waiting) || YY_SRWLOCK_GET_BLOCK(OldSRWLock) == nullptr)) { - if ((OldSRWLock & YY_SRWLOCK_Locked) && ((OldSRWLock & YY_SRWLOCK_Waiting) || YY_SRWLOCK_GET_BLOCK(OldSRWLock) == nullptr)) - { - //if ( RtlpWaitCouldDeadlock() ) - // ZwTerminateProcess((HANDLE)0xFFFFFFFF, 0xC000004B); + //if ( RtlpWaitCouldDeadlock() ) + // ZwTerminateProcess((HANDLE)0xFFFFFFFF, 0xC000004B); - StackWaitBlock.flag = 2; - StackWaitBlock.shareCount = 0; - StackWaitBlock.next = nullptr; + StackWaitBlock.flag = 2; + StackWaitBlock.shareCount = 0; + StackWaitBlock.next = nullptr; - bOptimize = false; + bOptimize = false; - if (OldSRWLock & YY_SRWLOCK_Waiting) - { - //宸茬粡鏈変汉绛夊緟锛屾垜浠彃鍏ヤ竴涓柊鐨勭瓑寰呭潡 - StackWaitBlock.back = YY_SRWLOCK_GET_BLOCK(OldSRWLock); - StackWaitBlock.notify = nullptr; + if (OldSRWLock & YY_SRWLOCK_Waiting) + { + //宸茬粡鏈変汉绛夊緟锛屾垜浠彃鍏ヤ竴涓柊鐨勭瓑寰呭潡 + StackWaitBlock.back = YY_SRWLOCK_GET_BLOCK(OldSRWLock); + StackWaitBlock.notify = nullptr; - NewSRWLock = size_t(&StackWaitBlock) | (OldSRWLock & YY_SRWLOCK_MultipleShared) | (YY_SRWLOCK_Waking | YY_SRWLOCK_Waiting | YY_SRWLOCK_Locked); + NewSRWLock = size_t(&StackWaitBlock) | (OldSRWLock & YY_SRWLOCK_MultipleShared) | (YY_SRWLOCK_Waking | YY_SRWLOCK_Waiting | YY_SRWLOCK_Locked); - if ((OldSRWLock & YY_SRWLOCK_Waking) == 0) - { - bOptimize = true; - } - } - else + if ((OldSRWLock & YY_SRWLOCK_Waking) == 0) { - StackWaitBlock.notify = &StackWaitBlock; - NewSRWLock = size_t(&StackWaitBlock) | (YY_SRWLOCK_Waiting | YY_SRWLOCK_Locked); + bOptimize = true; } + } + else + { + StackWaitBlock.notify = &StackWaitBlock; + NewSRWLock = size_t(&StackWaitBlock) | (YY_SRWLOCK_Waiting | YY_SRWLOCK_Locked); + } - if (InterlockedCompareExchange((volatile size_t *)SRWLock, NewSRWLock, OldSRWLock) == OldSRWLock) - { - //鏇存柊鎴愬姛锛 - - if (bOptimize) - { - internal::RtlpOptimizeSRWLockList(SRWLock, NewSRWLock); - } + if (InterlockedCompareExchange((volatile size_t *)SRWLock, NewSRWLock, OldSRWLock) == OldSRWLock) + { + //鏇存柊鎴愬姛锛 - auto GlobalKeyedEventHandle = internal::GetGlobalKeyedEventHandle(); - auto pNtWaitForKeyedEvent = try_get_NtWaitForKeyedEvent(); - if (!pNtWaitForKeyedEvent) - { - internal::RaiseStatus(STATUS_RESOURCE_NOT_OWNED); - } + if (bOptimize) + { + internal::RtlpOptimizeSRWLockList(SRWLock, NewSRWLock); + } - //鑷棆 - for (DWORD SpinCount = SRWLockSpinCount; SpinCount; --SpinCount) - { - if ((StackWaitBlock.flag & 2) == 0) - break; + auto GlobalKeyedEventHandle = internal::GetGlobalKeyedEventHandle(); + auto pNtWaitForKeyedEvent = try_get_NtWaitForKeyedEvent(); + if (!pNtWaitForKeyedEvent) + { + internal::RaiseStatus(STATUS_RESOURCE_NOT_OWNED); + } - YieldProcessor(); - } + //鑷棆 + for (DWORD SpinCount = SRWLockSpinCount; SpinCount; --SpinCount) + { + if ((StackWaitBlock.flag & 2) == 0) + break; - if (InterlockedBitTestAndReset((volatile LONG*)&StackWaitBlock.flag, 1)) - { - pNtWaitForKeyedEvent(GlobalKeyedEventHandle, (PVOID)&StackWaitBlock, 0, nullptr); - } + YieldProcessor(); + } - continue; + if (InterlockedBitTestAndReset((volatile LONG*)&StackWaitBlock.flag, 1)) + { + pNtWaitForKeyedEvent(GlobalKeyedEventHandle, (PVOID)&StackWaitBlock, 0, nullptr); } + + continue; + } + } + else + { + if (OldSRWLock & YY_SRWLOCK_Waiting) + { + //鏃㈢劧鏈変汉鍦ㄧ瓑寰呴攣锛岄偅涔圷Y_SRWLOCK_Locked搴旇閲嶆柊鍔犱笂 + NewSRWLock = OldSRWLock | YY_SRWLOCK_Locked; } else { - if (OldSRWLock & YY_SRWLOCK_Waiting) - { - //鏃㈢劧鏈変汉鍦ㄧ瓑寰呴攣锛岄偅涔圷Y_SRWLOCK_Locked搴旇閲嶆柊鍔犱笂 - NewSRWLock = OldSRWLock | YY_SRWLOCK_Locked; - } - else - { - //娌℃湁浜虹瓑寰咃紝閭d箞鍗曠函鍔犱釜 0x10鍗冲彲 - NewSRWLock = (OldSRWLock + 0x10) | YY_SRWLOCK_Locked; - } - - if (InterlockedCompareExchange((volatile size_t *)SRWLock, NewSRWLock, OldSRWLock) == OldSRWLock) - return; + //娌℃湁浜虹瓑寰咃紝閭d箞鍗曠函鍔犱釜 0x10鍗冲彲 + NewSRWLock = (OldSRWLock + 0x10) | YY_SRWLOCK_Locked; } - //鍋锋噿涓嬶紝鐩存帴 YieldProcessor 鍚 - //RtlBackoff(&nBackOff); - YieldProcessor(); + if (InterlockedCompareExchange((volatile size_t *)SRWLock, NewSRWLock, OldSRWLock) == OldSRWLock) + return; } + + //鍋锋噿涓嬶紝鐩存帴 YieldProcessor 鍚 + //RtlBackoff(&nBackOff); + YieldProcessor(); } + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN7) - //Windows 7 [desktop apps | UWP apps] - //Windows Server 2008 R2 [desktop apps | UWP apps] - __DEFINE_THUNK( - kernel32, - 4, - BOOLEAN, - WINAPI, - TryAcquireSRWLockShared, - _Inout_ PSRWLOCK SRWLock - ) + //Windows 7 [desktop apps | UWP apps] + //Windows Server 2008 R2 [desktop apps | UWP apps] + __DEFINE_THUNK( + kernel32, + 4, + BOOLEAN, + WINAPI, + TryAcquireSRWLockShared, + _Inout_ PSRWLOCK SRWLock + ) + { + if (auto const pTryAcquireSRWLockShared = try_get_TryAcquireSRWLockShared()) { - if (auto const pTryAcquireSRWLockShared = try_get_TryAcquireSRWLockShared()) - { - return pTryAcquireSRWLockShared(SRWLock); - } + return pTryAcquireSRWLockShared(SRWLock); + } - //灏濊瘯缁欏叏鏂扮殑閿佸姞閿 - auto OldSRWLock = InterlockedCompareExchange((volatile size_t*)SRWLock, size_t(0x11), 0); + //灏濊瘯缁欏叏鏂扮殑閿佸姞閿 + auto OldSRWLock = InterlockedCompareExchange((volatile size_t*)SRWLock, size_t(0x11), 0); + + //鎴愬姛 + if (OldSRWLock == size_t(0)) + { + return TRUE; + } - //鎴愬姛 - if (OldSRWLock == size_t(0)) + for (;;) + { + if ((OldSRWLock & YY_SRWLOCK_Locked) && ((OldSRWLock & YY_SRWLOCK_Waiting) || YY_SRWLOCK_GET_BLOCK(OldSRWLock) == nullptr)) { - return TRUE; + //姝e湪琚攣瀹氫腑 + return FALSE; } - - for (;;) + else { - if ((OldSRWLock & YY_SRWLOCK_Locked) && ((OldSRWLock & YY_SRWLOCK_Waiting) || YY_SRWLOCK_GET_BLOCK(OldSRWLock) == nullptr)) - { - //姝e湪琚攣瀹氫腑 - return FALSE; - } - else - { - size_t NewSRWLock; + size_t NewSRWLock; - if (OldSRWLock & YY_SRWLOCK_Waiting) - NewSRWLock = OldSRWLock | YY_SRWLOCK_Locked; - else - NewSRWLock = (OldSRWLock + 0x10) | YY_SRWLOCK_Locked; - - if (InterlockedCompareExchange((volatile size_t*)SRWLock, NewSRWLock, OldSRWLock) == OldSRWLock) - { - //閿佸畾瀹屾垚 - return TRUE; - } + if (OldSRWLock & YY_SRWLOCK_Waiting) + NewSRWLock = OldSRWLock | YY_SRWLOCK_Locked; + else + NewSRWLock = (OldSRWLock + 0x10) | YY_SRWLOCK_Locked; - //RtlBackoff((unsigned int *)&v4); - YieldProcessor(); - OldSRWLock = *(volatile size_t*)SRWLock; + if (InterlockedCompareExchange((volatile size_t*)SRWLock, NewSRWLock, OldSRWLock) == OldSRWLock) + { + //閿佸畾瀹屾垚 + return TRUE; } + + //RtlBackoff((unsigned int *)&v4); + YieldProcessor(); + OldSRWLock = *(volatile size_t*)SRWLock; } } + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN6) - //Windows Vista [desktop apps | UWP apps] - //Windows Server 2008 [desktop apps | UWP apps] - __DEFINE_THUNK( - kernel32, - 4, - VOID, - WINAPI, - ReleaseSRWLockShared, - _Inout_ PSRWLOCK SRWLock - ) + //Windows Vista [desktop apps | UWP apps] + //Windows Server 2008 [desktop apps | UWP apps] + __DEFINE_THUNK( + kernel32, + 4, + VOID, + WINAPI, + ReleaseSRWLockShared, + _Inout_ PSRWLOCK SRWLock + ) + { + if (auto const pReleaseSRWLockShared = try_get_ReleaseSRWLockShared()) { - if (auto const pReleaseSRWLockShared = try_get_ReleaseSRWLockShared()) - { - return pReleaseSRWLockShared(SRWLock); - } + return pReleaseSRWLockShared(SRWLock); + } - //灏濊瘯瑙i攣鍙姞涓娆¤閿佺殑鎯呭喌 + //灏濊瘯瑙i攣鍙姞涓娆¤閿佺殑鎯呭喌 - auto OldSRWLock = InterlockedCompareExchange((volatile size_t*)SRWLock, 0, size_t(0x11)); + auto OldSRWLock = InterlockedCompareExchange((volatile size_t*)SRWLock, 0, size_t(0x11)); - //瑙i攣鎴愬姛 - if (OldSRWLock == size_t(0x11)) - { - return; - } + //瑙i攣鎴愬姛 + if (OldSRWLock == size_t(0x11)) + { + return; + } - if ((OldSRWLock & YY_SRWLOCK_Locked) == 0) - { - internal::RaiseStatus(STATUS_RESOURCE_NOT_OWNED); - } + if ((OldSRWLock & YY_SRWLOCK_Locked) == 0) + { + internal::RaiseStatus(STATUS_RESOURCE_NOT_OWNED); + } - for (;;) + for (;;) + { + if (OldSRWLock & YY_SRWLOCK_Waiting) { - if (OldSRWLock & YY_SRWLOCK_Waiting) + if (OldSRWLock & YY_SRWLOCK_MultipleShared) { - if (OldSRWLock & YY_SRWLOCK_MultipleShared) - { - auto pLastNode = YY_SRWLOCK_GET_BLOCK(OldSRWLock); + auto pLastNode = YY_SRWLOCK_GET_BLOCK(OldSRWLock); - for (; pLastNode->notify == nullptr; pLastNode = pLastNode->back); + for (; pLastNode->notify == nullptr; pLastNode = pLastNode->back); - /* - 鏃㈢劧鏄湪閲婃斁鍏变韩閿侊紝璇存槑涓瀹氭湁浜鸿幏鍙栦簡鍏变韩閿 - 濡傛灉鏈変汉鑾峰彇浜嗗叡浜攣锛屽氨涓瀹氭病鏈変汉鑾峰彇鐙埌鍗犻攣 - 鍙渶瑕佹妸鍏变韩娆℃暟鍑1 - 鍙栧嚭notify鑺傜偣鐨勫叡浜鏁板彉閲忕殑鍦板潃, 鍘熷瓙鍑 - */ - if (InterlockedDecrement((volatile size_t *)&(pLastNode->notify->shareCount)) > 0) - { - return; - } + /* + 鏃㈢劧鏄湪閲婃斁鍏变韩閿侊紝璇存槑涓瀹氭湁浜鸿幏鍙栦簡鍏变韩閿 + 濡傛灉鏈変汉鑾峰彇浜嗗叡浜攣锛屽氨涓瀹氭病鏈変汉鑾峰彇鐙埌鍗犻攣 + 鍙渶瑕佹妸鍏变韩娆℃暟鍑1 + 鍙栧嚭notify鑺傜偣鐨勫叡浜鏁板彉閲忕殑鍦板潃, 鍘熷瓙鍑 + */ + if (InterlockedDecrement((volatile size_t *)&(pLastNode->notify->shareCount)) > 0) + { + return; } + } - for (;;) - { - auto NewSRWLock = OldSRWLock & (~(YY_SRWLOCK_MultipleShared | YY_SRWLOCK_Locked)); - size_t LastSRWLock; - - if (OldSRWLock & YY_SRWLOCK_Waking) - { - LastSRWLock = InterlockedCompareExchange((volatile size_t *)SRWLock, NewSRWLock, OldSRWLock); + for (;;) + { + auto NewSRWLock = OldSRWLock & (~(YY_SRWLOCK_MultipleShared | YY_SRWLOCK_Locked)); + size_t LastSRWLock; - if (LastSRWLock == OldSRWLock) - return; - } - else - { - NewSRWLock |= YY_SRWLOCK_Waking; + if (OldSRWLock & YY_SRWLOCK_Waking) + { + LastSRWLock = InterlockedCompareExchange((volatile size_t *)SRWLock, NewSRWLock, OldSRWLock); - LastSRWLock = InterlockedCompareExchange((volatile size_t *)SRWLock, NewSRWLock, OldSRWLock); - if (LastSRWLock == OldSRWLock) - return internal::RtlpWakeSRWLock(SRWLock, NewSRWLock); - } + if (LastSRWLock == OldSRWLock) + return; + } + else + { + NewSRWLock |= YY_SRWLOCK_Waking; - OldSRWLock = LastSRWLock; + LastSRWLock = InterlockedCompareExchange((volatile size_t *)SRWLock, NewSRWLock, OldSRWLock); + if (LastSRWLock == OldSRWLock) + return internal::RtlpWakeSRWLock(SRWLock, NewSRWLock); } - break; + OldSRWLock = LastSRWLock; } - else - { - auto NewSRWLock = size_t(YY_SRWLOCK_GET_BLOCK(OldSRWLock)) <= 0x10 ? 0 : OldSRWLock - 0x10; - auto LastSRWLock = InterlockedCompareExchange((volatile size_t *)SRWLock, NewSRWLock, OldSRWLock); - if (LastSRWLock == OldSRWLock) - break; + break; + } + else + { + auto NewSRWLock = size_t(YY_SRWLOCK_GET_BLOCK(OldSRWLock)) <= 0x10 ? 0 : OldSRWLock - 0x10; - OldSRWLock = LastSRWLock; - } + auto LastSRWLock = InterlockedCompareExchange((volatile size_t *)SRWLock, NewSRWLock, OldSRWLock); + if (LastSRWLock == OldSRWLock) + break; + + OldSRWLock = LastSRWLock; } } + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN6) - //Windows Vista [desktop apps | UWP apps] - //Windows Server 2008 [desktop apps | UWP apps] - __DEFINE_THUNK( - kernel32, - 4, - VOID, - WINAPI, - InitializeConditionVariable, - _Out_ PCONDITION_VARIABLE ConditionVariable - ) - { - *ConditionVariable = CONDITION_VARIABLE_INIT; - } + //Windows Vista [desktop apps | UWP apps] + //Windows Server 2008 [desktop apps | UWP apps] + __DEFINE_THUNK( + kernel32, + 4, + VOID, + WINAPI, + InitializeConditionVariable, + _Out_ PCONDITION_VARIABLE ConditionVariable + ) + { + *ConditionVariable = CONDITION_VARIABLE_INIT; + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN6) - //Windows Vista [desktop apps | UWP apps] - //Windows Server 2008 [desktop apps | UWP apps] - __DEFINE_THUNK( - kernel32, - 12, - BOOL, - WINAPI, - SleepConditionVariableCS, - _Inout_ PCONDITION_VARIABLE ConditionVariable, - _Inout_ PCRITICAL_SECTION CriticalSection, - _In_ DWORD dwMilliseconds - ) + //Windows Vista [desktop apps | UWP apps] + //Windows Server 2008 [desktop apps | UWP apps] + __DEFINE_THUNK( + kernel32, + 12, + BOOL, + WINAPI, + SleepConditionVariableCS, + _Inout_ PCONDITION_VARIABLE ConditionVariable, + _Inout_ PCRITICAL_SECTION CriticalSection, + _In_ DWORD dwMilliseconds + ) + { + if (auto const pSleepConditionVariableCS = try_get_SleepConditionVariableCS()) { - if (auto const pSleepConditionVariableCS = try_get_SleepConditionVariableCS()) - { - return pSleepConditionVariableCS(ConditionVariable, CriticalSection, dwMilliseconds); - } + return pSleepConditionVariableCS(ConditionVariable, CriticalSection, dwMilliseconds); + } - YY_CV_WAIT_BLOCK StackWaitBlock; + YY_CV_WAIT_BLOCK StackWaitBlock; - StackWaitBlock.next = nullptr; - StackWaitBlock.flag = 2; - StackWaitBlock.SRWLock = nullptr; + StackWaitBlock.next = nullptr; + StackWaitBlock.flag = 2; + StackWaitBlock.SRWLock = nullptr; - auto OldConditionVariable = *(size_t*)ConditionVariable; + auto OldConditionVariable = *(size_t*)ConditionVariable; - size_t NewConditionVariable; + size_t NewConditionVariable; - for (;;) - { - NewConditionVariable = size_t(&StackWaitBlock) | (OldConditionVariable & YY_CV_MASK); - StackWaitBlock.back = YY_CV_GET_BLOCK(OldConditionVariable); + for (;;) + { + NewConditionVariable = size_t(&StackWaitBlock) | (OldConditionVariable & YY_CV_MASK); + StackWaitBlock.back = YY_CV_GET_BLOCK(OldConditionVariable); - if (StackWaitBlock.back) - { - StackWaitBlock.notify = nullptr; + if (StackWaitBlock.back) + { + StackWaitBlock.notify = nullptr; - NewConditionVariable |= 0x8; - } - else - { - StackWaitBlock.notify = &StackWaitBlock; - } + NewConditionVariable |= 0x8; + } + else + { + StackWaitBlock.notify = &StackWaitBlock; + } - auto LastConditionVariable = InterlockedCompareExchange((volatile size_t*)ConditionVariable, NewConditionVariable, OldConditionVariable); + auto LastConditionVariable = InterlockedCompareExchange((volatile size_t*)ConditionVariable, NewConditionVariable, OldConditionVariable); - if (LastConditionVariable == OldConditionVariable) - break; + if (LastConditionVariable == OldConditionVariable) + break; - OldConditionVariable = LastConditionVariable; - } + OldConditionVariable = LastConditionVariable; + } - LeaveCriticalSection(CriticalSection); + LeaveCriticalSection(CriticalSection); - //0x8 鏍囪鏂板鏃讹紝鎵嶈繘琛屼紭鍖 ConditionVariableWaitList - if ((OldConditionVariable ^ NewConditionVariable) & 0x8) - { - internal::RtlpOptimizeConditionVariableWaitList(ConditionVariable, NewConditionVariable); - } + //0x8 鏍囪鏂板鏃讹紝鎵嶈繘琛屼紭鍖 ConditionVariableWaitList + if ((OldConditionVariable ^ NewConditionVariable) & 0x8) + { + internal::RtlpOptimizeConditionVariableWaitList(ConditionVariable, NewConditionVariable); + } - auto GlobalKeyedEventHandle = internal::GetGlobalKeyedEventHandle(); - auto pNtWaitForKeyedEvent = try_get_NtWaitForKeyedEvent(); - if (!pNtWaitForKeyedEvent) - { - internal::RaiseStatus(STATUS_RESOURCE_NOT_OWNED); - } + auto GlobalKeyedEventHandle = internal::GetGlobalKeyedEventHandle(); + auto pNtWaitForKeyedEvent = try_get_NtWaitForKeyedEvent(); + if (!pNtWaitForKeyedEvent) + { + internal::RaiseStatus(STATUS_RESOURCE_NOT_OWNED); + } - //鑷棆 - for (auto SpinCount = ConditionVariableSpinCount; SpinCount; --SpinCount) - { - if (!(StackWaitBlock.flag & 2)) - break; + //鑷棆 + for (auto SpinCount = ConditionVariableSpinCount; SpinCount; --SpinCount) + { + if (!(StackWaitBlock.flag & 2)) + break; - YieldProcessor(); - } + YieldProcessor(); + } - NTSTATUS Status = 0; + NTSTATUS Status = 0; - if (InterlockedBitTestAndReset((volatile LONG*)&StackWaitBlock.flag, 1)) - { - LARGE_INTEGER TimeOut; + if (InterlockedBitTestAndReset((volatile LONG*)&StackWaitBlock.flag, 1)) + { + LARGE_INTEGER TimeOut; - Status = pNtWaitForKeyedEvent(GlobalKeyedEventHandle, (PVOID)&StackWaitBlock, 0, internal::BaseFormatTimeOut(&TimeOut, dwMilliseconds)); + Status = pNtWaitForKeyedEvent(GlobalKeyedEventHandle, (PVOID)&StackWaitBlock, 0, internal::BaseFormatTimeOut(&TimeOut, dwMilliseconds)); - if (Status == STATUS_TIMEOUT && internal::RtlpWakeSingle(ConditionVariable, &StackWaitBlock) == FALSE) - { - pNtWaitForKeyedEvent(GlobalKeyedEventHandle, (PVOID)&StackWaitBlock, 0, nullptr); - Status = 0; - } + if (Status == STATUS_TIMEOUT && internal::RtlpWakeSingle(ConditionVariable, &StackWaitBlock) == FALSE) + { + pNtWaitForKeyedEvent(GlobalKeyedEventHandle, (PVOID)&StackWaitBlock, 0, nullptr); + Status = 0; } + } - EnterCriticalSection(CriticalSection); + EnterCriticalSection(CriticalSection); - internal::BaseSetLastNTError(Status); + internal::BaseSetLastNTError(Status); - return Status >= 0 && Status != STATUS_TIMEOUT; - } + return Status >= 0 && Status != STATUS_TIMEOUT; + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN6) - //Windows Vista [desktop apps | UWP apps] - //Windows Server 2008 [desktop apps | UWP apps] - __DEFINE_THUNK( - kernel32, - 16, - BOOL, - WINAPI, - SleepConditionVariableSRW, - _Inout_ PCONDITION_VARIABLE ConditionVariable, - _Inout_ PSRWLOCK SRWLock, - _In_ DWORD dwMilliseconds, - _In_ ULONG Flags - ) + //Windows Vista [desktop apps | UWP apps] + //Windows Server 2008 [desktop apps | UWP apps] + __DEFINE_THUNK( + kernel32, + 16, + BOOL, + WINAPI, + SleepConditionVariableSRW, + _Inout_ PCONDITION_VARIABLE ConditionVariable, + _Inout_ PSRWLOCK SRWLock, + _In_ DWORD dwMilliseconds, + _In_ ULONG Flags + ) + { + if (auto const pSleepConditionVariableSRW = try_get_SleepConditionVariableSRW()) + { + return pSleepConditionVariableSRW(ConditionVariable, SRWLock, dwMilliseconds, Flags); + } + + YY_CV_WAIT_BLOCK StackWaitBlock; + + NTSTATUS Status = 0; + + do { - if (auto const pSleepConditionVariableSRW = try_get_SleepConditionVariableSRW()) + if (Flags & ~CONDITION_VARIABLE_LOCKMODE_SHARED) { - return pSleepConditionVariableSRW(ConditionVariable, SRWLock, dwMilliseconds, Flags); + Status = STATUS_INVALID_PARAMETER_2; + break; } - YY_CV_WAIT_BLOCK StackWaitBlock; + StackWaitBlock.next = nullptr; + StackWaitBlock.flag = 2; + StackWaitBlock.SRWLock = nullptr; + + if (Flags& CONDITION_VARIABLE_LOCKMODE_SHARED) + { + StackWaitBlock.flag |= 0x4; + } - NTSTATUS Status = 0; + size_t Current = *(volatile size_t*)ConditionVariable; + size_t New; - do + for (;;) { - if (Flags & ~CONDITION_VARIABLE_LOCKMODE_SHARED) - { - Status = STATUS_INVALID_PARAMETER_2; - break; - } + New = size_t(&StackWaitBlock) | (Current & YY_CV_MASK); - StackWaitBlock.next = nullptr; - StackWaitBlock.flag = 2; - StackWaitBlock.SRWLock = nullptr; + if (StackWaitBlock.back = YY_CV_GET_BLOCK(Current)) + { + StackWaitBlock.notify = nullptr; - if (Flags& CONDITION_VARIABLE_LOCKMODE_SHARED) + New |= 0x8; + } + else { - StackWaitBlock.flag |= 0x4; + StackWaitBlock.notify = &StackWaitBlock; } - size_t Current = *(volatile size_t*)ConditionVariable; - size_t New; + const auto Last = InterlockedCompareExchange((volatile size_t*)ConditionVariable, New, Current); - for (;;) + if (Last == Current) { - New = size_t(&StackWaitBlock) | (Current & YY_CV_MASK); - - if (StackWaitBlock.back = YY_CV_GET_BLOCK(Current)) - { - StackWaitBlock.notify = nullptr; - - New |= 0x8; - } - else - { - StackWaitBlock.notify = &StackWaitBlock; - } - - const auto Last = InterlockedCompareExchange((volatile size_t*)ConditionVariable, New, Current); - - if (Last == Current) - { - break; - } + break; + } - Current = Last; - } + Current = Last; + } - if (Flags& CONDITION_VARIABLE_LOCKMODE_SHARED) - YY::Thunks::ReleaseSRWLockShared(SRWLock); - else - YY::Thunks::ReleaseSRWLockExclusive(SRWLock); + if (Flags& CONDITION_VARIABLE_LOCKMODE_SHARED) + ReleaseSRWLockShared(SRWLock); + else + ReleaseSRWLockExclusive(SRWLock); - if ((Current ^ New) & 0x8) - { - //鏂板0x8 鏍囪浣嶆墠璋冪敤 RtlpOptimizeConditionVariableWaitList - internal::RtlpOptimizeConditionVariableWaitList(ConditionVariable, New); - } + if ((Current ^ New) & 0x8) + { + //鏂板0x8 鏍囪浣嶆墠璋冪敤 RtlpOptimizeConditionVariableWaitList + internal::RtlpOptimizeConditionVariableWaitList(ConditionVariable, New); + } - auto GlobalKeyedEventHandle = internal::GetGlobalKeyedEventHandle(); - auto pNtWaitForKeyedEvent = try_get_NtWaitForKeyedEvent(); - if (!pNtWaitForKeyedEvent) - { - internal::RaiseStatus(STATUS_RESOURCE_NOT_OWNED); - } + auto GlobalKeyedEventHandle = internal::GetGlobalKeyedEventHandle(); + auto pNtWaitForKeyedEvent = try_get_NtWaitForKeyedEvent(); + if (!pNtWaitForKeyedEvent) + { + internal::RaiseStatus(STATUS_RESOURCE_NOT_OWNED); + } - //鑷棆 - for (auto SpinCount = ConditionVariableSpinCount; SpinCount; --SpinCount) - { - if (!(StackWaitBlock.flag & 2)) - break; + //鑷棆 + for (auto SpinCount = ConditionVariableSpinCount; SpinCount; --SpinCount) + { + if (!(StackWaitBlock.flag & 2)) + break; - YieldProcessor(); - } + YieldProcessor(); + } - if (InterlockedBitTestAndReset((volatile LONG*)&StackWaitBlock.flag, 1)) - { - LARGE_INTEGER TimeOut; + if (InterlockedBitTestAndReset((volatile LONG*)&StackWaitBlock.flag, 1)) + { + LARGE_INTEGER TimeOut; - Status = pNtWaitForKeyedEvent(GlobalKeyedEventHandle, (PVOID)&StackWaitBlock, 0, internal::BaseFormatTimeOut(&TimeOut, dwMilliseconds)); + Status = pNtWaitForKeyedEvent(GlobalKeyedEventHandle, (PVOID)&StackWaitBlock, 0, internal::BaseFormatTimeOut(&TimeOut, dwMilliseconds)); - if (Status == STATUS_TIMEOUT && internal::RtlpWakeSingle(ConditionVariable, &StackWaitBlock) == FALSE) - { - pNtWaitForKeyedEvent(GlobalKeyedEventHandle, (PVOID)&StackWaitBlock, 0, nullptr); - Status = 0; - } + if (Status == STATUS_TIMEOUT && internal::RtlpWakeSingle(ConditionVariable, &StackWaitBlock) == FALSE) + { + pNtWaitForKeyedEvent(GlobalKeyedEventHandle, (PVOID)&StackWaitBlock, 0, nullptr); + Status = 0; } + } - if (Flags& CONDITION_VARIABLE_LOCKMODE_SHARED) - YY::Thunks::AcquireSRWLockShared(SRWLock); - else - YY::Thunks::AcquireSRWLockExclusive(SRWLock); + if (Flags& CONDITION_VARIABLE_LOCKMODE_SHARED) + AcquireSRWLockShared(SRWLock); + else + AcquireSRWLockExclusive(SRWLock); - } while (false); + } while (false); - internal::BaseSetLastNTError(Status); + internal::BaseSetLastNTError(Status); - return Status >= 0 && Status != STATUS_TIMEOUT; + return Status >= 0 && Status != STATUS_TIMEOUT; - } + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN6) - //Windows Vista [desktop apps | UWP apps] - //Windows Server 2008 [desktop apps | UWP apps] - __DEFINE_THUNK( - kernel32, - 4, - VOID, - WINAPI, - WakeConditionVariable, - _Inout_ PCONDITION_VARIABLE ConditionVariable - ) + //Windows Vista [desktop apps | UWP apps] + //Windows Server 2008 [desktop apps | UWP apps] + __DEFINE_THUNK( + kernel32, + 4, + VOID, + WINAPI, + WakeConditionVariable, + _Inout_ PCONDITION_VARIABLE ConditionVariable + ) + { + if (auto const pWakeConditionVariable = try_get_WakeConditionVariable()) { - if (auto const pWakeConditionVariable = try_get_WakeConditionVariable()) - { - return pWakeConditionVariable(ConditionVariable); - } + return pWakeConditionVariable(ConditionVariable); + } - size_t Current = *(volatile size_t*)ConditionVariable; - size_t Last; + size_t Current = *(volatile size_t*)ConditionVariable; + size_t Last; - for (; Current; Current = Last) + for (; Current; Current = Last) + { + if (Current & 0x8) { - if (Current & 0x8) + if ((Current & 0x7) == 0x7) { - if ((Current & 0x7) == 0x7) - { - return; - } - - Last = InterlockedCompareExchange((volatile size_t*)ConditionVariable, Current + 1, Current); - if (Last == Current) - return; + return; } - else + + Last = InterlockedCompareExchange((volatile size_t*)ConditionVariable, Current + 1, Current); + if (Last == Current) + return; + } + else + { + Last = InterlockedCompareExchange((volatile size_t*)ConditionVariable, Current | 0x8, Current); + if (Last == Current) { - Last = InterlockedCompareExchange((volatile size_t*)ConditionVariable, Current | 0x8, Current); - if (Last == Current) - { - internal::RtlpWakeConditionVariable(ConditionVariable, Current + 8, 1); - return; - } + internal::RtlpWakeConditionVariable(ConditionVariable, Current + 8, 1); + return; } } } + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN6) - //Windows Vista [desktop apps | UWP apps] - //Windows Server 2008 [desktop apps | UWP apps] - __DEFINE_THUNK( - kernel32, - 4, - VOID, - WINAPI, - WakeAllConditionVariable, - _Inout_ PCONDITION_VARIABLE ConditionVariable - ) + //Windows Vista [desktop apps | UWP apps] + //Windows Server 2008 [desktop apps | UWP apps] + __DEFINE_THUNK( + kernel32, + 4, + VOID, + WINAPI, + WakeAllConditionVariable, + _Inout_ PCONDITION_VARIABLE ConditionVariable + ) + { + if (auto const pWakeAllConditionVariable = try_get_WakeAllConditionVariable()) { - if (auto const pWakeAllConditionVariable = try_get_WakeAllConditionVariable()) - { - return pWakeAllConditionVariable(ConditionVariable); - } + return pWakeAllConditionVariable(ConditionVariable); + } - size_t Current = *(volatile size_t*)ConditionVariable; - size_t Last; + size_t Current = *(volatile size_t*)ConditionVariable; + size_t Last; - for (; Current && (Current & 0x7) != 0x7; Current = Last) + for (; Current && (Current & 0x7) != 0x7; Current = Last) + { + if (Current & 0x8) { - if (Current & 0x8) - { - Last = InterlockedCompareExchange((volatile size_t*)ConditionVariable, Current | 0x7, Current); - if (Last == Current) - return; - } - else + Last = InterlockedCompareExchange((volatile size_t*)ConditionVariable, Current | 0x7, Current); + if (Last == Current) + return; + } + else + { + Last = InterlockedCompareExchange((volatile size_t*)ConditionVariable, 0, Current); + if (Last == Current) { - Last = InterlockedCompareExchange((volatile size_t*)ConditionVariable, 0, Current); - if (Last == Current) + auto GlobalKeyedEventHandle = internal::GetGlobalKeyedEventHandle(); + auto pNtReleaseKeyedEvent = try_get_NtReleaseKeyedEvent(); + + if (!pNtReleaseKeyedEvent) { - auto GlobalKeyedEventHandle = internal::GetGlobalKeyedEventHandle(); - auto pNtReleaseKeyedEvent = try_get_NtReleaseKeyedEvent(); + internal::RaiseStatus(STATUS_RESOURCE_NOT_OWNED); + } - if (!pNtReleaseKeyedEvent) - { - internal::RaiseStatus(STATUS_RESOURCE_NOT_OWNED); - } + for (auto pBlock = YY_CV_GET_BLOCK(Current); pBlock;) + { + auto Tmp = pBlock->back; - for (auto pBlock = YY_CV_GET_BLOCK(Current); pBlock;) + if (!InterlockedBitTestAndReset((volatile LONG*)&pBlock->flag, 1)) { - auto Tmp = pBlock->back; - - if (!InterlockedBitTestAndReset((volatile LONG*)&pBlock->flag, 1)) - { - pNtReleaseKeyedEvent(GlobalKeyedEventHandle, pBlock, FALSE, nullptr); - } - - pBlock = Tmp; + pNtReleaseKeyedEvent(GlobalKeyedEventHandle, pBlock, FALSE, nullptr); } - return; + pBlock = Tmp; } + + return; } } } + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN8) - //Windows 8 [desktop apps only] - //Windows Server 2012 [desktop apps only] - __DEFINE_THUNK( - kernel32, - 12, - BOOL, - WINAPI, - InitializeSynchronizationBarrier, - _Out_ LPSYNCHRONIZATION_BARRIER lpBarrier, - _In_ LONG lTotalThreads, - _In_ LONG lSpinCount - ) + //Windows 8 [desktop apps only] + //Windows Server 2012 [desktop apps only] + __DEFINE_THUNK( + kernel32, + 12, + BOOL, + WINAPI, + InitializeSynchronizationBarrier, + _Out_ LPSYNCHRONIZATION_BARRIER lpBarrier, + _In_ LONG lTotalThreads, + _In_ LONG lSpinCount + ) + { + if (auto const pEnterSynchronizationBarrier = try_get_InitializeSynchronizationBarrier()) { - if (auto const pEnterSynchronizationBarrier = try_get_InitializeSynchronizationBarrier()) - { - return pEnterSynchronizationBarrier(lpBarrier, lTotalThreads, lSpinCount); - } - - auto pYYBarrier = (YY_BARRIER*)lpBarrier; + return pEnterSynchronizationBarrier(lpBarrier, lTotalThreads, lSpinCount); + } - pYYBarrier->lTotalThreads = lTotalThreads; - pYYBarrier->lRemainderThreads = lTotalThreads; - pYYBarrier->dwNumProcessors = ((TEB*)NtCurrentTeb())->ProcessEnvironmentBlock->NumberOfProcessors; - pYYBarrier->dwSpinCount = lSpinCount == -1 ? 2000 : lSpinCount; + auto pYYBarrier = (YY_BARRIER*)lpBarrier; - if ((pYYBarrier->hEvent[0] = CreateEventW(nullptr, TRUE, FALSE, nullptr)) == nullptr) - return FALSE; + pYYBarrier->lTotalThreads = lTotalThreads; + pYYBarrier->lRemainderThreads = lTotalThreads; + pYYBarrier->dwNumProcessors = ((TEB*)NtCurrentTeb())->ProcessEnvironmentBlock->NumberOfProcessors; + pYYBarrier->dwSpinCount = lSpinCount == -1 ? 2000 : lSpinCount; - if ((pYYBarrier->hEvent[1] = CreateEventW(nullptr, TRUE, FALSE, nullptr)) == nullptr) - { - auto lStatus = GetLastError(); - CloseHandle(pYYBarrier->hEvent[0]); - SetLastError(lStatus); - return FALSE; - } + if ((pYYBarrier->hEvent[0] = CreateEventW(nullptr, TRUE, FALSE, nullptr)) == nullptr) + return FALSE; - return TRUE; + if ((pYYBarrier->hEvent[1] = CreateEventW(nullptr, TRUE, FALSE, nullptr)) == nullptr) + { + auto lStatus = GetLastError(); + CloseHandle(pYYBarrier->hEvent[0]); + SetLastError(lStatus); + return FALSE; } + + return TRUE; + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN8) - //Windows 8 [desktop apps only] - //Windows Server 2012 [desktop apps only] - __DEFINE_THUNK( - kernel32, - 8, - BOOL, - WINAPI, - EnterSynchronizationBarrier, - _Inout_ LPSYNCHRONIZATION_BARRIER lpBarrier, - _In_ DWORD dwFlags - ) + //Windows 8 [desktop apps only] + //Windows Server 2012 [desktop apps only] + __DEFINE_THUNK( + kernel32, + 8, + BOOL, + WINAPI, + EnterSynchronizationBarrier, + _Inout_ LPSYNCHRONIZATION_BARRIER lpBarrier, + _In_ DWORD dwFlags + ) + { + if (auto const pEnterSynchronizationBarrier = try_get_EnterSynchronizationBarrier()) { - if (auto const pEnterSynchronizationBarrier = try_get_EnterSynchronizationBarrier()) - { - return pEnterSynchronizationBarrier(lpBarrier, dwFlags); - } - - if (dwFlags & ~(SYNCHRONIZATION_BARRIER_FLAGS_SPIN_ONLY | SYNCHRONIZATION_BARRIER_FLAGS_BLOCK_ONLY | SYNCHRONIZATION_BARRIER_FLAGS_NO_DELETE)) - { - internal::RaiseStatus(STATUS_INVALID_PARAMETER); - } - - DWORD dwRtlBarrierFlags = dwFlags & (SYNCHRONIZATION_BARRIER_FLAGS_SPIN_ONLY | SYNCHRONIZATION_BARRIER_FLAGS_BLOCK_ONLY); + return pEnterSynchronizationBarrier(lpBarrier, dwFlags); + } - if ((dwFlags & SYNCHRONIZATION_BARRIER_FLAGS_NO_DELETE) == 0) - dwRtlBarrierFlags |= 0x10000; + if (dwFlags & ~(SYNCHRONIZATION_BARRIER_FLAGS_SPIN_ONLY | SYNCHRONIZATION_BARRIER_FLAGS_BLOCK_ONLY | SYNCHRONIZATION_BARRIER_FLAGS_NO_DELETE)) + { + internal::RaiseStatus(STATUS_INVALID_PARAMETER); + } + DWORD dwRtlBarrierFlags = dwFlags & (SYNCHRONIZATION_BARRIER_FLAGS_SPIN_ONLY | SYNCHRONIZATION_BARRIER_FLAGS_BLOCK_ONLY); - auto pYYBarrier = (YY_BARRIER*)lpBarrier; + if ((dwFlags & SYNCHRONIZATION_BARRIER_FLAGS_NO_DELETE) == 0) + dwRtlBarrierFlags |= 0x10000; - auto Current = InterlockedDecrement(&pYYBarrier->lRemainderThreads); + auto pYYBarrier = (YY_BARRIER*)lpBarrier; - const auto GroupStatus = Current & 0x80000000; - const auto EventIndex = Current >= 0 ? 1 : 0; - DWORD dwRemainderThreads = Current & 0x7FFFFFFF; + auto Current = InterlockedDecrement(&pYYBarrier->lRemainderThreads); - if (dwRemainderThreads == 0) - { - //鍓╀綑鏁伴噺宸茬粡鍙樻垚 0 浜嗭紝鎴戜滑闇瑕佸敜閱掍箣鍓嶇瓑寰呯殑绾跨▼锛屽苟涓旂炕杞 EventIndex - const auto NewEventIndex = EventIndex ? 0 : 1; + const auto GroupStatus = Current & 0x80000000; + const auto EventIndex = Current >= 0 ? 1 : 0; + DWORD dwRemainderThreads = Current & 0x7FFFFFFF; - //灏嗕笅娆¢渶瑕佷娇鐢ㄧ殑浜嬩欢璁剧疆涓 鏃犱俊鍙风姸鎬 - auto NewEvent = pYYBarrier->hEvent[NewEventIndex]; - if (size_t(NewEvent) & 0x1) - { - auto hEvent = (HANDLE)(size_t(NewEvent) & ~size_t(0x1)); - pYYBarrier->hEvent[NewEventIndex] = hEvent; + if (dwRemainderThreads == 0) + { + //鍓╀綑鏁伴噺宸茬粡鍙樻垚 0 浜嗭紝鎴戜滑闇瑕佸敜閱掍箣鍓嶇瓑寰呯殑绾跨▼锛屽苟涓旂炕杞 EventIndex + const auto NewEventIndex = EventIndex ? 0 : 1; - ResetEvent(hEvent); - } - //鍚у綋鍓嶇殑 GroupStatus 鐘舵佺疆鍙嶏紝鐒跺悗缁勫悎鎴愭柊鐨 RemainderThreads - auto NewRemainderThreads = pYYBarrier->lTotalThreads | (GroupStatus ^ 0x80000000); + //灏嗕笅娆¢渶瑕佷娇鐢ㄧ殑浜嬩欢璁剧疆涓 鏃犱俊鍙风姸鎬 + auto NewEvent = pYYBarrier->hEvent[NewEventIndex]; + if (size_t(NewEvent) & 0x1) + { + auto hEvent = (HANDLE)(size_t(NewEvent) & ~size_t(0x1)); + pYYBarrier->hEvent[NewEventIndex] = hEvent; - //姝ゆ爣璁板悗灏嗚嚜鍔ㄥ垹闄 Barrier锛屽悗缁篃灏嗘棤娉曞啀娆″埄鐢 Barrier - if (dwRtlBarrierFlags & 0x10000) - { - pYYBarrier->lTotalThreads = 1; - } - pYYBarrier->lRemainderThreads = NewRemainderThreads; + ResetEvent(hEvent); + } - auto Event = pYYBarrier->hEvent[EventIndex]; - if (size_t(Event) & 0x1) - { - SetEvent((HANDLE)(size_t(Event) & ~size_t(0x1))); - } + //鍚у綋鍓嶇殑 GroupStatus 鐘舵佺疆鍙嶏紝鐒跺悗缁勫悎鎴愭柊鐨 RemainderThreads + auto NewRemainderThreads = pYYBarrier->lTotalThreads | (GroupStatus ^ 0x80000000); - return TRUE; + //姝ゆ爣璁板悗灏嗚嚜鍔ㄥ垹闄 Barrier锛屽悗缁篃灏嗘棤娉曞啀娆″埄鐢 Barrier + if (dwRtlBarrierFlags & 0x10000) + { + pYYBarrier->lTotalThreads = 1; } + pYYBarrier->lRemainderThreads = NewRemainderThreads; - if (pYYBarrier->dwSpinCount && ((dwRemainderThreads < pYYBarrier->dwNumProcessors && (dwRtlBarrierFlags & SYNCHRONIZATION_BARRIER_FLAGS_BLOCK_ONLY) == 0) || (dwRtlBarrierFlags & SYNCHRONIZATION_BARRIER_FLAGS_SPIN_ONLY))) + auto Event = pYYBarrier->hEvent[EventIndex]; + if (size_t(Event) & 0x1) { - DWORD CurrentSpinCount = 0; - for (;;) - { - if ((pYYBarrier->lRemainderThreads & 0x80000000) != GroupStatus) - { - //鑷棆绛夊緟鎴愬姛 - auto dwSpinCount = pYYBarrier->dwSpinCount; + SetEvent((HANDLE)(size_t(Event) & ~size_t(0x1))); + } - if (dwSpinCount < 5000) - { - pYYBarrier->dwSpinCount = dwSpinCount + 1; - } + return TRUE; + } - goto __retrun; - } + if (pYYBarrier->dwSpinCount && ((dwRemainderThreads < pYYBarrier->dwNumProcessors && (dwRtlBarrierFlags & SYNCHRONIZATION_BARRIER_FLAGS_BLOCK_ONLY) == 0) || (dwRtlBarrierFlags & SYNCHRONIZATION_BARRIER_FLAGS_SPIN_ONLY))) + { + DWORD CurrentSpinCount = 0; + for (;;) + { + if ((pYYBarrier->lRemainderThreads & 0x80000000) != GroupStatus) + { + //鑷棆绛夊緟鎴愬姛 + auto dwSpinCount = pYYBarrier->dwSpinCount; - //鎸囧畾 SYNCHRONIZATION_BARRIER_FLAGS_SPIN_ONLY 鏍囪瘑鏃朵細濮嬬粓鑷棆锛屾墍浠ユ病鏈夋鏍囪瘑鏃舵垜浠棤闇鏇存柊褰撳墠鑷棆娆℃暟 - if ((dwRtlBarrierFlags & SYNCHRONIZATION_BARRIER_FLAGS_SPIN_ONLY) == 0) + if (dwSpinCount < 5000) { - ++CurrentSpinCount; + pYYBarrier->dwSpinCount = dwSpinCount + 1; } - YieldProcessor(); + goto __retrun; + } - auto dwSpinCount = pYYBarrier->dwSpinCount; + //鎸囧畾 SYNCHRONIZATION_BARRIER_FLAGS_SPIN_ONLY 鏍囪瘑鏃朵細濮嬬粓鑷棆锛屾墍浠ユ病鏈夋鏍囪瘑鏃舵垜浠棤闇鏇存柊褰撳墠鑷棆娆℃暟 + if ((dwRtlBarrierFlags & SYNCHRONIZATION_BARRIER_FLAGS_SPIN_ONLY) == 0) + { + ++CurrentSpinCount; + } - if (CurrentSpinCount >= dwSpinCount) - { - if (dwSpinCount > 50) - { - pYYBarrier->dwSpinCount = dwSpinCount - 1; - } + YieldProcessor(); - break; + auto dwSpinCount = pYYBarrier->dwSpinCount; + + if (CurrentSpinCount >= dwSpinCount) + { + if (dwSpinCount > 50) + { + pYYBarrier->dwSpinCount = dwSpinCount - 1; } + + break; } } + } + { + //濡傛灉娌℃湁 0x1鏍囪鍒欐坊鍔犱竴涓紝鏉ユ寚绀哄凡缁 WaitForSingleObject 浜 + HANDLE hEnvet = pYYBarrier->hEvent[EventIndex]; + if ((size_t(hEnvet) & 0x1) == 0) { - //濡傛灉娌℃湁 0x1鏍囪鍒欐坊鍔犱竴涓紝鏉ユ寚绀哄凡缁 WaitForSingleObject 浜 - HANDLE hEnvet = pYYBarrier->hEvent[EventIndex]; - if ((size_t(hEnvet) & 0x1) == 0) - { - pYYBarrier->hEvent[EventIndex] = HANDLE(size_t(hEnvet) | 0x1); - } - - if ((pYYBarrier->lRemainderThreads & 0x80000000) == GroupStatus) - WaitForSingleObject((HANDLE)(size_t(hEnvet) & ~size_t(0x1)), INFINITE); + pYYBarrier->hEvent[EventIndex] = HANDLE(size_t(hEnvet) | 0x1); } - __retrun: + if ((pYYBarrier->lRemainderThreads & 0x80000000) == GroupStatus) + WaitForSingleObject((HANDLE)(size_t(hEnvet) & ~size_t(0x1)), INFINITE); + } + + __retrun: - if (dwRtlBarrierFlags & 0x10000) - InterlockedIncrement(&pYYBarrier->lTotalThreads); + if (dwRtlBarrierFlags & 0x10000) + InterlockedIncrement(&pYYBarrier->lTotalThreads); - return TRUE; - } + return TRUE; + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN8) - //Windows 8 [desktop apps only] - //Windows Server 2012 [desktop apps only] - __DEFINE_THUNK( - kernel32, - 4, - BOOL, - WINAPI, - DeleteSynchronizationBarrier, - _Inout_ LPSYNCHRONIZATION_BARRIER lpBarrier - ) + //Windows 8 [desktop apps only] + //Windows Server 2012 [desktop apps only] + __DEFINE_THUNK( + kernel32, + 4, + BOOL, + WINAPI, + DeleteSynchronizationBarrier, + _Inout_ LPSYNCHRONIZATION_BARRIER lpBarrier + ) + { + if (auto const pDeleteSynchronizationBarrier = try_get_DeleteSynchronizationBarrier()) { - if (auto const pDeleteSynchronizationBarrier = try_get_DeleteSynchronizationBarrier()) - { - return pDeleteSynchronizationBarrier(lpBarrier); - } + return pDeleteSynchronizationBarrier(lpBarrier); + } - auto pYYBarrier = (YY_BARRIER*)lpBarrier; + auto pYYBarrier = (YY_BARRIER*)lpBarrier; - //鑷棆绛夊緟鎵鏈 EnterSynchronizationBarrier 閮借繘鍏ュ氨缁 - for (; pYYBarrier->lTotalThreads != (pYYBarrier->lRemainderThreads & 0x7FFFFFFF);) - { - //绛夊緟16姣 - Sleep(16); - } + //鑷棆绛夊緟鎵鏈 EnterSynchronizationBarrier 閮借繘鍏ュ氨缁 + for (; pYYBarrier->lTotalThreads != (pYYBarrier->lRemainderThreads & 0x7FFFFFFF);) + { + //绛夊緟16姣 + Sleep(16); + } - BOOL bSuccess = FALSE; - if (auto hEnent = (HANDLE)(size_t(pYYBarrier->hEvent[0]) & ~size_t(0x1))) - CloseHandle(hEnent); + BOOL bSuccess = FALSE; + if (auto hEnent = (HANDLE)(size_t(pYYBarrier->hEvent[0]) & ~size_t(0x1))) + CloseHandle(hEnent); - if (auto hEnent = (HANDLE)(size_t(pYYBarrier->hEvent[1]) & ~size_t(0x1))) - CloseHandle(hEnent); + if (auto hEnent = (HANDLE)(size_t(pYYBarrier->hEvent[1]) & ~size_t(0x1))) + CloseHandle(hEnent); - //寰蒋鏂囨。璇寸殑锛岃繖涓嚱鏁版绘槸杩斿洖 TRUE锛屼絾鏄井杞疻indows 8鐨勫疄鐜扮暐鏈夐棶棰橈紝鐩存帴杞彂浜 RtlDeleteBarrier锛岃繑鍥炲煎苟涓嶆纭 - return TRUE; - } + //寰蒋鏂囨。璇寸殑锛岃繖涓嚱鏁版绘槸杩斿洖 TRUE锛屼絾鏄井杞疻indows 8鐨勫疄鐜扮暐鏈夐棶棰橈紝鐩存帴杞彂浜 RtlDeleteBarrier锛岃繑鍥炲煎苟涓嶆纭 + return TRUE; + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN8) - //Windows 8 [desktop apps | UWP apps] - //Windows Server 2012 [desktop apps | UWP apps] - __DEFINE_THUNK( - api_ms_win_core_synch_l1_2_0, - 16, - BOOL, - WINAPI, - WaitOnAddress, - _In_reads_bytes_(AddressSize) volatile VOID* Address, - _In_reads_bytes_(AddressSize) PVOID CompareAddress, - _In_ SIZE_T AddressSize, - _In_opt_ DWORD dwMilliseconds - ) + //Windows 8 [desktop apps | UWP apps] + //Windows Server 2012 [desktop apps | UWP apps] + __DEFINE_THUNK( + api_ms_win_core_synch_l1_2_0, + 16, + BOOL, + WINAPI, + WaitOnAddress, + _In_reads_bytes_(AddressSize) volatile VOID* Address, + _In_reads_bytes_(AddressSize) PVOID CompareAddress, + _In_ SIZE_T AddressSize, + _In_opt_ DWORD dwMilliseconds + ) + { + if (auto const pWaitOnAddress = try_get_WaitOnAddress()) { - if (auto const pWaitOnAddress = try_get_WaitOnAddress()) - { - return pWaitOnAddress(Address, CompareAddress, AddressSize, dwMilliseconds); - } + return pWaitOnAddress(Address, CompareAddress, AddressSize, dwMilliseconds); + } - //鍙傛暟妫鏌ワ紝AddressSize 鍙兘 涓 1,2,4,8 - if (AddressSize > 8 || AddressSize == 0 || ((AddressSize - 1) & AddressSize) != 0) - { - //STATUS_INVALID_PARAMETER - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } + //鍙傛暟妫鏌ワ紝AddressSize 鍙兘 涓 1,2,4,8 + if (AddressSize > 8 || AddressSize == 0 || ((AddressSize - 1) & AddressSize) != 0) + { + //STATUS_INVALID_PARAMETER + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } - YY_ADDRESS_WAIT_BLOCK WaitBlock; - WaitBlock.Address = Address; - WaitBlock.back = nullptr; - WaitBlock.notify = nullptr; - WaitBlock.next = nullptr; - WaitBlock.flag = 1; + YY_ADDRESS_WAIT_BLOCK WaitBlock; + WaitBlock.Address = Address; + WaitBlock.back = nullptr; + WaitBlock.notify = nullptr; + WaitBlock.next = nullptr; + WaitBlock.flag = 1; - internal::RtlpAddWaitBlockToWaitList(&WaitBlock); + internal::RtlpAddWaitBlockToWaitList(&WaitBlock); - bool bSame; - switch (AddressSize) - { - case 1: - bSame = *(volatile byte*)Address == *(volatile byte*)CompareAddress; - break; - case 2: - bSame = *(volatile WORD*)Address == *(volatile WORD*)CompareAddress; - break; - case 4: - bSame = *(volatile DWORD*)Address == *(volatile DWORD*)CompareAddress; - break; - default: - //case 8: + bool bSame; + switch (AddressSize) + { + case 1: + bSame = *(volatile byte*)Address == *(volatile byte*)CompareAddress; + break; + case 2: + bSame = *(volatile WORD*)Address == *(volatile WORD*)CompareAddress; + break; + case 4: + bSame = *(volatile DWORD*)Address == *(volatile DWORD*)CompareAddress; + break; + default: + //case 8: #if _WIN64 - //64浣嶈嚜韬兘淇濊瘉鎿嶄綔鐨勫師瀛愭 - bSame = *(volatile unsigned long long*)Address == *(volatile unsigned long long*)CompareAddress; + //64浣嶈嚜韬兘淇濊瘉鎿嶄綔鐨勫師瀛愭 + bSame = *(volatile unsigned long long*)Address == *(volatile unsigned long long*)CompareAddress; #else - bSame = InterlockedCompareExchange64((volatile long long*)Address, 0, 0) == *(volatile long long*)CompareAddress; + bSame = InterlockedCompareExchange64((volatile long long*)Address, 0, 0) == *(volatile long long*)CompareAddress; #endif - break; - } - + break; + } - if (!bSame) - { - //缁撴灉涓嶇浉鍚岋紝鎴戜滑浠庣瓑寰呴槦鍒楃Щ闄 - internal::RtlpWaitOnAddressRemoveWaitBlock(&WaitBlock); - return TRUE; - } - LARGE_INTEGER TimeOut; + if (!bSame) + { + //缁撴灉涓嶇浉鍚岋紝鎴戜滑浠庣瓑寰呴槦鍒楃Щ闄 + internal::RtlpWaitOnAddressRemoveWaitBlock(&WaitBlock); + return TRUE; + } - auto Status = internal::RtlpWaitOnAddressWithTimeout(&WaitBlock, internal::BaseFormatTimeOut(&TimeOut, dwMilliseconds)); + LARGE_INTEGER TimeOut; - if (Status) - { - internal::BaseSetLastNTError(Status); - } + auto Status = internal::RtlpWaitOnAddressWithTimeout(&WaitBlock, internal::BaseFormatTimeOut(&TimeOut, dwMilliseconds)); - return Status < 0 || Status == STATUS_TIMEOUT ? FALSE : TRUE; + if (Status) + { + internal::BaseSetLastNTError(Status); } + + return Status < 0 || Status == STATUS_TIMEOUT ? FALSE : TRUE; + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN8) - //Windows 8 [desktop apps | UWP apps] - //Windows Server 2012 [desktop apps | UWP apps] - __DEFINE_THUNK( - api_ms_win_core_synch_l1_2_0, - 4, - VOID, - WINAPI, - WakeByAddressSingle, - _In_ PVOID Address - ) + //Windows 8 [desktop apps | UWP apps] + //Windows Server 2012 [desktop apps | UWP apps] + __DEFINE_THUNK( + api_ms_win_core_synch_l1_2_0, + 4, + VOID, + WINAPI, + WakeByAddressSingle, + _In_ PVOID Address + ) + { + if (auto const pWakeByAddressSingle = try_get_WakeByAddressSingle()) { - if (auto const pWakeByAddressSingle = try_get_WakeByAddressSingle()) - { - return pWakeByAddressSingle(Address); - } - - internal::RtlpWakeByAddress(Address, FALSE); + return pWakeByAddressSingle(Address); } + + internal::RtlpWakeByAddress(Address, FALSE); + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN8) - //Windows 8 [desktop apps | UWP apps] - //Windows Server 2012 [desktop apps | UWP apps] - __DEFINE_THUNK( - api_ms_win_core_synch_l1_2_0, - 4, - VOID, - WINAPI, - WakeByAddressAll, - _In_ PVOID Address - ) + //Windows 8 [desktop apps | UWP apps] + //Windows Server 2012 [desktop apps | UWP apps] + __DEFINE_THUNK( + api_ms_win_core_synch_l1_2_0, + 4, + VOID, + WINAPI, + WakeByAddressAll, + _In_ PVOID Address + ) + { + if (auto const pWakeByAddressAll = try_get_WakeByAddressAll()) { - if (auto const pWakeByAddressAll = try_get_WakeByAddressAll()) - { - return pWakeByAddressAll(Address); - } - - internal::RtlpWakeByAddress(Address, TRUE); + return pWakeByAddressAll(Address); } + + internal::RtlpWakeByAddress(Address, TRUE); + } #endif #if (YY_Thunks_Support_Version < NTDDI_WIN7) - // Minimum supported client Windows 7 [desktop apps | UWP apps] - // Minimum supported server Windows Server 2008 R2 [desktop apps | UWP apps] - __DEFINE_THUNK( - kernel32, - 28, - BOOL, - WINAPI, - SetWaitableTimerEx, - _In_ HANDLE _hTimer, - _In_ const LARGE_INTEGER* _lpDueTime, - _In_ LONG _iPeriod, - _In_opt_ PTIMERAPCROUTINE _pfnCompletionRoutine, - _In_opt_ LPVOID _lpArgToCompletionRoutine, - _In_opt_ PREASON_CONTEXT _pWakeContext, - _In_ ULONG _uTolerableDelay - ) + // Minimum supported client Windows 7 [desktop apps | UWP apps] + // Minimum supported server Windows Server 2008 R2 [desktop apps | UWP apps] + __DEFINE_THUNK( + kernel32, + 28, + BOOL, + WINAPI, + SetWaitableTimerEx, + _In_ HANDLE _hTimer, + _In_ const LARGE_INTEGER* _lpDueTime, + _In_ LONG _iPeriod, + _In_opt_ PTIMERAPCROUTINE _pfnCompletionRoutine, + _In_opt_ LPVOID _lpArgToCompletionRoutine, + _In_opt_ PREASON_CONTEXT _pWakeContext, + _In_ ULONG _uTolerableDelay + ) + { + if (auto const _pfnSetWaitableTimerEx = try_get_SetWaitableTimerEx()) { - if (auto const _pfnSetWaitableTimerEx = try_get_SetWaitableTimerEx()) - { - return _pfnSetWaitableTimerEx(_hTimer, _lpDueTime, _iPeriod, _pfnCompletionRoutine, _lpArgToCompletionRoutine, _pWakeContext, _uTolerableDelay); - } + return _pfnSetWaitableTimerEx(_hTimer, _lpDueTime, _iPeriod, _pfnCompletionRoutine, _lpArgToCompletionRoutine, _pWakeContext, _uTolerableDelay); + } - UNREFERENCED_PARAMETER(_uTolerableDelay); + UNREFERENCED_PARAMETER(_uTolerableDelay); - LSTATUS _lStatus = ERROR_SUCCESS; - // 妫鏌 _pWakeContext 鍙傛暟鏄惁鍚堟硶 - // Version 蹇呴』涓 POWER_REQUEST_CONTEXT_VERSION - // Flags 鏃犳晥鏍囪鍙弬鑰 DIAGNOSTIC_REASON_INVALID_FLAGS锛屾澶 POWER_REQUEST_CONTEXT_DETAILED_STRING锛孭OWER_REQUEST_CONTEXT_SIMPLE_STRING 蹇呴』璁剧疆銆 - // 鏈夌鐗规畩鎯呭喌鏄 DIAGNOSTIC_REASON_NOT_SPECIFIED锛屽畠浼氳鐩存帴鏀捐銆備笉瑕侀棶鎴戔︹﹂嗗悜缁撴灉濡傛锛屽井杞枃妗e苟鏈叕寮銆 - // 寰蒋鏂囨。閾炬帴锛歨ttps://learn.microsoft.com/zh-cn/windows/win32/api/minwinbase/ns-minwinbase-reason_context - do + LSTATUS _lStatus = ERROR_SUCCESS; + // 妫鏌 _pWakeContext 鍙傛暟鏄惁鍚堟硶 + // Version 蹇呴』涓 POWER_REQUEST_CONTEXT_VERSION + // Flags 鏃犳晥鏍囪鍙弬鑰 DIAGNOSTIC_REASON_INVALID_FLAGS锛屾澶 POWER_REQUEST_CONTEXT_DETAILED_STRING锛孭OWER_REQUEST_CONTEXT_SIMPLE_STRING 蹇呴』璁剧疆銆 + // 鏈夌鐗规畩鎯呭喌鏄 DIAGNOSTIC_REASON_NOT_SPECIFIED锛屽畠浼氳鐩存帴鏀捐銆備笉瑕侀棶鎴戔︹﹂嗗悜缁撴灉濡傛锛屽井杞枃妗e苟鏈叕寮銆 + // 寰蒋鏂囨。閾炬帴锛歨ttps://learn.microsoft.com/zh-cn/windows/win32/api/minwinbase/ns-minwinbase-reason_context + do + { + if (!_pWakeContext) + break; + + if (_pWakeContext->Version != POWER_REQUEST_CONTEXT_VERSION) { - if (!_pWakeContext) - break; + _lStatus = ERROR_INVALID_PARAMETER; + break; + } - if (_pWakeContext->Version != POWER_REQUEST_CONTEXT_VERSION) - { - _lStatus = ERROR_INVALID_PARAMETER; - break; - } + const auto _fFlags = _pWakeContext->Flags; - const auto _fFlags = _pWakeContext->Flags; + // 寰蒋鍘熺増灏辨槸濡傛锛屽畾涔 DIAGNOSTIC_REASON_NOT_SPECIFIED 鏃朵細鐩存帴鏀捐鈥︹ + // 鎴戜滑淇濇寔寰蒋鐨勯昏緫锛岃繖鏃朵笉杩涗竴姝ョ殑鍙傛暟楠岃瘉銆 + if (_fFlags & DIAGNOSTIC_REASON_NOT_SPECIFIED) + break; - // 寰蒋鍘熺増灏辨槸濡傛锛屽畾涔 DIAGNOSTIC_REASON_NOT_SPECIFIED 鏃朵細鐩存帴鏀捐鈥︹ - // 鎴戜滑淇濇寔寰蒋鐨勯昏緫锛岃繖鏃朵笉杩涗竴姝ョ殑鍙傛暟楠岃瘉銆 - if (_fFlags & DIAGNOSTIC_REASON_NOT_SPECIFIED) - break; + // 鏃犳晥鐨凢lags缁勫悎 + if ((_fFlags & DIAGNOSTIC_REASON_INVALID_FLAGS) != 0 + || (_fFlags & (POWER_REQUEST_CONTEXT_DETAILED_STRING | POWER_REQUEST_CONTEXT_SIMPLE_STRING)) == 0) + { + _lStatus = ERROR_INVALID_PARAMETER; + break; + } - // 鏃犳晥鐨凢lags缁勫悎 - if ((_fFlags & DIAGNOSTIC_REASON_INVALID_FLAGS) != 0 - || (_fFlags & (POWER_REQUEST_CONTEXT_DETAILED_STRING | POWER_REQUEST_CONTEXT_SIMPLE_STRING)) == 0) + if (_fFlags & POWER_REQUEST_CONTEXT_DETAILED_STRING) + { + if(_pWakeContext->Reason.Detailed.LocalizedReasonId > 0xFFFFu) { _lStatus = ERROR_INVALID_PARAMETER; break; } - - if (_fFlags & POWER_REQUEST_CONTEXT_DETAILED_STRING) - { - if(_pWakeContext->Reason.Detailed.LocalizedReasonId > 0xFFFFu) - { - _lStatus = ERROR_INVALID_PARAMETER; - break; - } - } - } while (false); - - if (_lStatus != ERROR_SUCCESS) - { - SetLastError(_lStatus); - return FALSE; } + } while (false); - return SetWaitableTimer(_hTimer, _lpDueTime, _iPeriod, _pfnCompletionRoutine, _lpArgToCompletionRoutine, _pWakeContext != nullptr); + if (_lStatus != ERROR_SUCCESS) + { + SetLastError(_lStatus); + return FALSE; } -#endif - }//namespace Thunks -} //namespace YY + return SetWaitableTimer(_hTimer, _lpDueTime, _iPeriod, _pfnCompletionRoutine, _lpArgToCompletionRoutine, _pWakeContext != nullptr); + } +#endif +} //namespace YY::Thunks diff --git a/src/YY.Depends.Analyzer/YY.Depends.Analyzer.cpp b/src/YY.Depends.Analyzer/YY.Depends.Analyzer.cpp index ddb6724..d7482cc 100644 --- a/src/YY.Depends.Analyzer/YY.Depends.Analyzer.cpp +++ b/src/YY.Depends.Analyzer/YY.Depends.Analyzer.cpp @@ -1375,7 +1375,7 @@ HRESULT BuildAnalyzer(CStringW _szOutputPath, CStringW _szTarget, std::mapProcNameToModuleNameMap.find(_Proc.second.szProc); if (_iter != _pCache->ProcNameToModuleNameMap.end()) { - _szData += " ( try use"; + _szData += " ( try use "; _szData += _iter->second; _szData += '?'; _szData += '?';