From d2dcef69f33ae65bfebba4ea203c3dbc13a8aaa2 Mon Sep 17 00:00:00 2001 From: mingkuang Date: Thu, 1 Jun 2023 02:26:19 +0800 Subject: [PATCH] =?UTF-8?q?Bug=20#49,=20msvcrt=E6=A8=A1=E5=BC=8F=5Fbeginth?= =?UTF-8?q?read=E5=88=9B=E5=BB=BA=E7=9A=84=E7=BA=BF=E7=A8=8B=E6=97=A0?= =?UTF-8?q?=E6=B3=95=E8=8E=B7=E5=8F=96ptd?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/Build&Test.yml | 10 ++-- Build.proj | 7 ++- Sources/ucrt/inc/corecrt_internal.h | 67 ++++++++++++++++++++++---- UnitTest/UnitTest.vcxproj | 71 ++++++++++++++------------- UnitTest/UnitTest.vcxproj.filters | 3 ++ UnitTest/ptdTest.cpp | 74 +++++++++++++++++++++++++++++ YY.Windows.CRT.sln | 72 ++++++++++++++-------------- 7 files changed, 219 insertions(+), 85 deletions(-) create mode 100644 UnitTest/ptdTest.cpp diff --git a/.github/workflows/Build&Test.yml b/.github/workflows/Build&Test.yml index 522ec02..2d6f3b9 100644 --- a/.github/workflows/Build&Test.yml +++ b/.github/workflows/Build&Test.yml @@ -139,7 +139,7 @@ jobs: $Env:PROCDUMP_PATH="$Env:GITHUB_WORKSPACE\Tools" # 编译单元测试项目 - &msbuild UnitTest\UnitTest.vcxproj "-p:Configuration=Dynamic;Platform=Win32;SolutionDir=$Env:GITHUB_WORKSPACE\\" + &msbuild UnitTest\UnitTest.vcxproj "-p:Configuration=Static;Platform=Win32;SolutionDir=$Env:GITHUB_WORKSPACE\\" if($lastexitcode -ne 0) { throw "单元测试编译失败!退出代码:$lastexitcode" @@ -147,7 +147,7 @@ jobs: $RunFaild = 0 - &vstest.console Dynamic\UnitTest.dll "/logger:trx;LogFileName=UnitTest.trx" --Parallel "/Blame:CollectDump;CollectAlways=false;DumpType=full" + &vstest.console Static\UnitTest.dll "/logger:trx;LogFileName=UnitTest.trx" --Parallel "/Blame:CollectDump;CollectAlways=false;DumpType=full" if($lastexitcode -ne 0) { $RunFaild = 1 @@ -217,9 +217,9 @@ jobs: path: | TestResults/**/*.dmp TestResults/**/Sequence_*.xml - Dynamic\UnitTest.dll - Dynamic\UnitTest.pdb - Dynamic\*.log + Static\UnitTest.dll + Static\UnitTest.pdb + Static\*.log UnitTest/SymbolBuildTest/.test/**/Build.log *.7z diff --git a/Build.proj b/Build.proj index fb8784c..a98fad7 100644 --- a/Build.proj +++ b/Build.proj @@ -39,13 +39,16 @@ - - + + + + + diff --git a/Sources/ucrt/inc/corecrt_internal.h b/Sources/ucrt/inc/corecrt_internal.h index c2c63be..27094ad 100644 --- a/Sources/ucrt/inc/corecrt_internal.h +++ b/Sources/ucrt/inc/corecrt_internal.h @@ -1489,23 +1489,70 @@ __declspec(dllimport) void __cdecl _amsg_exit( __acrt_ptd* __cdecl __acrt_getptd_head(void); #ifdef __BuildWithMSVCRT -__forceinline __acrt_ptd* __cdecl __acrt_getptd_noexit(void) +__declspec(noinline) __inline __acrt_ptd* __cdecl __acrt_getptd_noexit(void) { - __acrt_ptd* ptd = (__acrt_ptd*)(((unsigned char*)_errno()) - FIELD_OFFSET(__acrt_ptd, _terrno)); - - /* - 当 _thandle = -1,这表明此线程的ptd通过msvcrt.dll begin_thread 或者 __getptd_noexit 创建。 - 当 _thandle = 0,这表明此线程的ptd通过msvcrt.dll的DllMain创建。 - 当 _thandle = 其他,这表明msvcrt.dll内部内存已经申请失败。 - */ - return (ptd->_thandle == (uintptr_t)-1/*Current Thread Handle*/ || ptd->_thandle == 0) ? ptd : (__acrt_ptd*)NULL; + // ptd->_thandle 一共有3中情况: + // 当 _thandle = -1,这表明此线程的ptd通过msvcrt.dll _beginthreadex 或者 __getptd_noexit 创建。 + // 当 _thandle = 0,这表明此线程的ptd通过msvcrt.dll的DllMain创建。 + // 当 _thandle = 其他,这可能是通过_beginthread启动的线程,它是实际有效的线程句柄。但是也有可能是内存申请失败了。 + + // 我们不要再根据 ptd->_thandle 判断__getptd_noexit 内存是否申请失,因为我们必须考虑 _beginthread 创建的线程。 + // 这时必须借助GetThreadId,可是它开销是惊人的,不容易做到快速判断。 + // 结合总总情况,我们现在通过判断 _errno() 返回地址是否在msvcrt模块范围来判断 __getptd_noexit 是否发生内存申请失败。 + // 具体Bug请参考:https://github.com/Chuyu-Team/VC-LTL5/issues/49 + typedef struct _DllAddressInfo + { + uintptr_t uBaseAddress; + uintptr_t uEndAddress; + } DllAddressInfo; + + static DllAddressInfo s_DllAddressCache; + + if (s_DllAddressCache.uBaseAddress == 0) + { + DllAddressInfo _DllAddressInfo = { (uintptr_t)-1, (uintptr_t)-1}; + MEMORY_BASIC_INFORMATION _BaseInfo; + if (VirtualQuery(&_amsg_exit, &_BaseInfo, sizeof(_BaseInfo))) + { + _DllAddressInfo.uBaseAddress = (uintptr_t)_BaseInfo.AllocationBase; + _DllAddressInfo.uEndAddress = (uintptr_t)_BaseInfo.BaseAddress + _BaseInfo.RegionSize; + + for (; VirtualQuery((void*)(_DllAddressInfo.uEndAddress + 1), &_BaseInfo, sizeof(_BaseInfo));) + { + if (_DllAddressInfo.uBaseAddress != (uintptr_t)_BaseInfo.AllocationBase) + break; + + _DllAddressInfo.uEndAddress = (uintptr_t)_BaseInfo.BaseAddress + _BaseInfo.RegionSize; + } + } + +#if defined(_X86_) || defined(_ARM_) + static_assert(sizeof(s_DllAddressCache) == sizeof(LONGLONG), ""); + InterlockedCompareExchange64((volatile LONGLONG*)&s_DllAddressCache, *(LONGLONG*)&_DllAddressInfo, 0); +#elif defined(_IA64_) || defined(_AMD64_) || defined(_ARM64_) + // AMD 早期不支持 InterlockedCompareExchange128,所以不用…… + InterlockedCompareExchange64((volatile LONGLONG*)&s_DllAddressCache.uEndAddress, _DllAddressInfo.uEndAddress, 0); + InterlockedCompareExchange64((volatile LONGLONG*)&s_DllAddressCache.uBaseAddress, _DllAddressInfo.uBaseAddress, 0); +#else +#error unsrpport! +#endif + } + + uintptr_t _p_errno_value = (uintptr_t)_errno(); + if (_p_errno_value == 0 || (s_DllAddressCache.uBaseAddress <= _p_errno_value && _p_errno_value < s_DllAddressCache.uEndAddress)) + { + return NULL; + } + + __acrt_ptd* ptd = (__acrt_ptd*)(((unsigned char*)_p_errno_value) - FIELD_OFFSET(__acrt_ptd, _terrno)); + return ptd; } #else __acrt_ptd* __cdecl __acrt_getptd_noexit(void); #endif #ifdef __BuildWithMSVCRT -__forceinline __acrt_ptd* __cdecl __acrt_getptd(void) +__declspec(noinline) __inline __acrt_ptd* __cdecl __acrt_getptd(void) { __acrt_ptd* ptd = __acrt_getptd_noexit(); diff --git a/UnitTest/UnitTest.vcxproj b/UnitTest/UnitTest.vcxproj index 5ace89e..cef979e 100644 --- a/UnitTest/UnitTest.vcxproj +++ b/UnitTest/UnitTest.vcxproj @@ -1,20 +1,20 @@ - - DDynamic + + DStatic Win32 - - Dynamic + + Static Win32 - - DDynamic + + DStatic x64 - - Dynamic + + Static x64 @@ -27,14 +27,15 @@ NativeUnitTestProject - + DynamicLibrary true $(DefaultPlatformToolset) Unicode false + 5.1.2600.0 - + DynamicLibrary false $(DefaultPlatformToolset) @@ -42,14 +43,15 @@ Unicode false - + DynamicLibrary true $(DefaultPlatformToolset) Unicode false + 5.1.2600.0 - + DynamicLibrary false $(DefaultPlatformToolset) @@ -62,32 +64,32 @@ - - + + - - + + - - + + - - + + - + true - + true - + false - + false - + Use Level3 @@ -95,13 +97,14 @@ SymbolBuildTestPath=LR"($(ProjectDir)SymbolBuildTest\)";MSBuildBinPath=LR"($(MSBuildBinPath)\)";VC_LTL_ROOT=LR"($(ProjectDir)..\)";VCToolsInstallDir=LR"($(VCToolsInstallDir))";CurrentUniversalCRTSdkDir=LR"($(UniversalCRTSdkDir)Lib\$(WindowsTargetPlatformVersion)\)";WIN32;_DEBUG;%(PreprocessorDefinitions) true pch.h + MultiThreadedDebug Windows $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) - + Use Level3 @@ -109,13 +112,14 @@ SymbolBuildTestPath=LR"($(ProjectDir)SymbolBuildTest\)";MSBuildBinPath=LR"($(MSBuildBinPath)\)";VC_LTL_ROOT=LR"($(ProjectDir)..\)";VCToolsInstallDir=LR"($(VCToolsInstallDir))";CurrentUniversalCRTSdkDir=LR"($(UniversalCRTSdkDir)Lib\$(WindowsTargetPlatformVersion)\)";_DEBUG;%(PreprocessorDefinitions) true pch.h + MultiThreadedDebug Windows $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) - + Use Level3 @@ -125,6 +129,7 @@ SymbolBuildTestPath=LR"($(ProjectDir)SymbolBuildTest\)";MSBuildBinPath=LR"($(MSBuildBinPath)\)";VC_LTL_ROOT=LR"($(ProjectDir)..\)";VCToolsInstallDir=LR"($(VCToolsInstallDir))";CurrentUniversalCRTSdkDir=LR"($(UniversalCRTSdkDir)Lib\$(WindowsTargetPlatformVersion)\)";WIN32;NDEBUG;%(PreprocessorDefinitions) true pch.h + MultiThreaded Windows @@ -133,7 +138,7 @@ $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) - + Use Level3 @@ -143,6 +148,7 @@ SymbolBuildTestPath=LR"($(ProjectDir)SymbolBuildTest\)";MSBuildBinPath=LR"($(MSBuildBinPath)\)";VC_LTL_ROOT=LR"($(ProjectDir)..\)";VCToolsInstallDir=LR"($(VCToolsInstallDir))";CurrentUniversalCRTSdkDir=LR"($(UniversalCRTSdkDir)Lib\$(WindowsTargetPlatformVersion)\)";NDEBUG;%(PreprocessorDefinitions) true pch.h + MultiThreaded Windows @@ -154,11 +160,12 @@ - Create - Create - Create - Create + Create + Create + Create + Create + diff --git a/UnitTest/UnitTest.vcxproj.filters b/UnitTest/UnitTest.vcxproj.filters index 27c93b3..17263c7 100644 --- a/UnitTest/UnitTest.vcxproj.filters +++ b/UnitTest/UnitTest.vcxproj.filters @@ -27,6 +27,9 @@ 源文件 + + 源文件 + diff --git a/UnitTest/ptdTest.cpp b/UnitTest/ptdTest.cpp new file mode 100644 index 0000000..02f957e --- /dev/null +++ b/UnitTest/ptdTest.cpp @@ -0,0 +1,74 @@ +#include "pch.h" +#include "CppUnitTest.h" + + +using namespace Microsoft::VisualStudio::CppUnitTestFramework; + +namespace UnitTest +{ + extern "C" void* __cdecl __acrt_getptd_noexit(); + + TEST_CLASS(PTD测试) + { + public: + TEST_METHOD(主线程PTD测试) + { + Assert::IsNotNull(__acrt_getptd_noexit()); + } + + TEST_METHOD(_beginthread_PTD测试) + { + HANDLE _hEvent = CreateEventW(nullptr, TRUE, FALSE, nullptr); + + _beginthread( + [](void* _hEvent) + { + Assert::IsNotNull(__acrt_getptd_noexit()); + + SetEvent(_hEvent); + + }, 0, _hEvent); + + + Assert::AreEqual(WaitForSingleObject(_hEvent, 5 * 1000), (DWORD)WAIT_OBJECT_0); + + CloseHandle(_hEvent); + } + + TEST_METHOD(_beginthreadex_PTD测试) + { + auto _hThread = (HANDLE)_beginthreadex( + 0, + 0, + [](void*) -> unsigned + { + Assert::IsNotNull(__acrt_getptd_noexit()); + return 0; + }, 0, 0, nullptr); + + Assert::IsNotNull(_hThread); + + Assert::AreEqual(WaitForSingleObject(_hThread, 5 * 1000), (DWORD)WAIT_OBJECT_0); + + CloseHandle(_hThread); + } + + TEST_METHOD(CreateThread_PTD测试) + { + auto _hThread = (HANDLE)CreateThread( + 0, + 0, + [](void*) -> DWORD + { + Assert::IsNotNull(__acrt_getptd_noexit()); + return 0; + }, 0, 0, nullptr); + + Assert::IsNotNull(_hThread); + + Assert::AreEqual(WaitForSingleObject(_hThread, 5 * 1000), (DWORD)WAIT_OBJECT_0); + + CloseHandle(_hThread); + } + }; +} diff --git a/YY.Windows.CRT.sln b/YY.Windows.CRT.sln index 929eeeb..53d2f88 100644 --- a/YY.Windows.CRT.sln +++ b/YY.Windows.CRT.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.31515.178 +# Visual Studio Version 17 +VisualStudioVersion = 17.6.33712.159 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vcruntime.msvcrt", "vcruntime.msvcrt\vcruntime.msvcrt.vcxproj", "{2D2789F9-1A04-4E94-8386-E5B2C8C93354}" EndProject @@ -77,8 +77,8 @@ Global {089D1C58-7669-4916-B1A2-7BBF6EA236B4}.DDynamic|ARM64.Build.0 = Static|x64 {089D1C58-7669-4916-B1A2-7BBF6EA236B4}.DDynamic|x64.ActiveCfg = Dynamic|x64 {089D1C58-7669-4916-B1A2-7BBF6EA236B4}.DDynamic|x64.Build.0 = Dynamic|x64 - {089D1C58-7669-4916-B1A2-7BBF6EA236B4}.DDynamic|x86.ActiveCfg = DDynamic|Win32 - {089D1C58-7669-4916-B1A2-7BBF6EA236B4}.DDynamic|x86.Build.0 = DDynamic|Win32 + {089D1C58-7669-4916-B1A2-7BBF6EA236B4}.DDynamic|x86.ActiveCfg = DStatic|Win32 + {089D1C58-7669-4916-B1A2-7BBF6EA236B4}.DDynamic|x86.Build.0 = DStatic|Win32 {089D1C58-7669-4916-B1A2-7BBF6EA236B4}.DStatic|ARM.ActiveCfg = Static|ARM {089D1C58-7669-4916-B1A2-7BBF6EA236B4}.DStatic|ARM.Build.0 = Static|ARM {089D1C58-7669-4916-B1A2-7BBF6EA236B4}.DStatic|ARM64.ActiveCfg = Static|ARM @@ -133,38 +133,38 @@ Global {81CACACB-0A7B-4392-BAA7-B1C18B71A80C}.Static|x64.Build.0 = Dynamic|x64 {81CACACB-0A7B-4392-BAA7-B1C18B71A80C}.Static|x86.ActiveCfg = Dynamic|Win32 {81CACACB-0A7B-4392-BAA7-B1C18B71A80C}.Static|x86.Build.0 = Dynamic|Win32 - {A772FE5B-F91F-405F-A54C-BB12334A3C94}.DDynamic|ARM.ActiveCfg = Dynamic|x64 - {A772FE5B-F91F-405F-A54C-BB12334A3C94}.DDynamic|ARM.Build.0 = Dynamic|x64 - {A772FE5B-F91F-405F-A54C-BB12334A3C94}.DDynamic|ARM64.ActiveCfg = Dynamic|x64 - {A772FE5B-F91F-405F-A54C-BB12334A3C94}.DDynamic|ARM64.Build.0 = Dynamic|x64 - {A772FE5B-F91F-405F-A54C-BB12334A3C94}.DDynamic|x64.ActiveCfg = Dynamic|x64 - {A772FE5B-F91F-405F-A54C-BB12334A3C94}.DDynamic|x64.Build.0 = Dynamic|x64 - {A772FE5B-F91F-405F-A54C-BB12334A3C94}.DDynamic|x86.ActiveCfg = DDynamic|Win32 - {A772FE5B-F91F-405F-A54C-BB12334A3C94}.DDynamic|x86.Build.0 = DDynamic|Win32 - {A772FE5B-F91F-405F-A54C-BB12334A3C94}.DStatic|ARM.ActiveCfg = Dynamic|Win32 - {A772FE5B-F91F-405F-A54C-BB12334A3C94}.DStatic|ARM.Build.0 = Dynamic|Win32 - {A772FE5B-F91F-405F-A54C-BB12334A3C94}.DStatic|ARM64.ActiveCfg = Dynamic|Win32 - {A772FE5B-F91F-405F-A54C-BB12334A3C94}.DStatic|ARM64.Build.0 = Dynamic|Win32 - {A772FE5B-F91F-405F-A54C-BB12334A3C94}.DStatic|x64.ActiveCfg = DDynamic|x64 - {A772FE5B-F91F-405F-A54C-BB12334A3C94}.DStatic|x64.Build.0 = DDynamic|x64 - {A772FE5B-F91F-405F-A54C-BB12334A3C94}.DStatic|x86.ActiveCfg = DDynamic|Win32 - {A772FE5B-F91F-405F-A54C-BB12334A3C94}.DStatic|x86.Build.0 = DDynamic|Win32 - {A772FE5B-F91F-405F-A54C-BB12334A3C94}.Dynamic|ARM.ActiveCfg = DDynamic|Win32 - {A772FE5B-F91F-405F-A54C-BB12334A3C94}.Dynamic|ARM.Build.0 = DDynamic|Win32 - {A772FE5B-F91F-405F-A54C-BB12334A3C94}.Dynamic|ARM64.ActiveCfg = DDynamic|Win32 - {A772FE5B-F91F-405F-A54C-BB12334A3C94}.Dynamic|ARM64.Build.0 = DDynamic|Win32 - {A772FE5B-F91F-405F-A54C-BB12334A3C94}.Dynamic|x64.ActiveCfg = DDynamic|x64 - {A772FE5B-F91F-405F-A54C-BB12334A3C94}.Dynamic|x64.Build.0 = DDynamic|x64 - {A772FE5B-F91F-405F-A54C-BB12334A3C94}.Dynamic|x86.ActiveCfg = DDynamic|Win32 - {A772FE5B-F91F-405F-A54C-BB12334A3C94}.Dynamic|x86.Build.0 = DDynamic|Win32 - {A772FE5B-F91F-405F-A54C-BB12334A3C94}.Static|ARM.ActiveCfg = DDynamic|Win32 - {A772FE5B-F91F-405F-A54C-BB12334A3C94}.Static|ARM.Build.0 = DDynamic|Win32 - {A772FE5B-F91F-405F-A54C-BB12334A3C94}.Static|ARM64.ActiveCfg = DDynamic|Win32 - {A772FE5B-F91F-405F-A54C-BB12334A3C94}.Static|ARM64.Build.0 = DDynamic|Win32 - {A772FE5B-F91F-405F-A54C-BB12334A3C94}.Static|x64.ActiveCfg = DDynamic|x64 - {A772FE5B-F91F-405F-A54C-BB12334A3C94}.Static|x64.Build.0 = DDynamic|x64 - {A772FE5B-F91F-405F-A54C-BB12334A3C94}.Static|x86.ActiveCfg = DDynamic|Win32 - {A772FE5B-F91F-405F-A54C-BB12334A3C94}.Static|x86.Build.0 = DDynamic|Win32 + {A772FE5B-F91F-405F-A54C-BB12334A3C94}.DDynamic|ARM.ActiveCfg = Static|x64 + {A772FE5B-F91F-405F-A54C-BB12334A3C94}.DDynamic|ARM.Build.0 = Static|x64 + {A772FE5B-F91F-405F-A54C-BB12334A3C94}.DDynamic|ARM64.ActiveCfg = Static|x64 + {A772FE5B-F91F-405F-A54C-BB12334A3C94}.DDynamic|ARM64.Build.0 = Static|x64 + {A772FE5B-F91F-405F-A54C-BB12334A3C94}.DDynamic|x64.ActiveCfg = Static|x64 + {A772FE5B-F91F-405F-A54C-BB12334A3C94}.DDynamic|x64.Build.0 = Static|x64 + {A772FE5B-F91F-405F-A54C-BB12334A3C94}.DDynamic|x86.ActiveCfg = Static|Win32 + {A772FE5B-F91F-405F-A54C-BB12334A3C94}.DDynamic|x86.Build.0 = Static|Win32 + {A772FE5B-F91F-405F-A54C-BB12334A3C94}.DStatic|ARM.ActiveCfg = Static|Win32 + {A772FE5B-F91F-405F-A54C-BB12334A3C94}.DStatic|ARM.Build.0 = Static|Win32 + {A772FE5B-F91F-405F-A54C-BB12334A3C94}.DStatic|ARM64.ActiveCfg = Static|Win32 + {A772FE5B-F91F-405F-A54C-BB12334A3C94}.DStatic|ARM64.Build.0 = Static|Win32 + {A772FE5B-F91F-405F-A54C-BB12334A3C94}.DStatic|x64.ActiveCfg = DStatic|x64 + {A772FE5B-F91F-405F-A54C-BB12334A3C94}.DStatic|x64.Build.0 = DStatic|x64 + {A772FE5B-F91F-405F-A54C-BB12334A3C94}.DStatic|x86.ActiveCfg = DStatic|Win32 + {A772FE5B-F91F-405F-A54C-BB12334A3C94}.DStatic|x86.Build.0 = DStatic|Win32 + {A772FE5B-F91F-405F-A54C-BB12334A3C94}.Dynamic|ARM.ActiveCfg = DStatic|Win32 + {A772FE5B-F91F-405F-A54C-BB12334A3C94}.Dynamic|ARM.Build.0 = DStatic|Win32 + {A772FE5B-F91F-405F-A54C-BB12334A3C94}.Dynamic|ARM64.ActiveCfg = DStatic|Win32 + {A772FE5B-F91F-405F-A54C-BB12334A3C94}.Dynamic|ARM64.Build.0 = DStatic|Win32 + {A772FE5B-F91F-405F-A54C-BB12334A3C94}.Dynamic|x64.ActiveCfg = DStatic|x64 + {A772FE5B-F91F-405F-A54C-BB12334A3C94}.Dynamic|x64.Build.0 = DStatic|x64 + {A772FE5B-F91F-405F-A54C-BB12334A3C94}.Dynamic|x86.ActiveCfg = DStatic|Win32 + {A772FE5B-F91F-405F-A54C-BB12334A3C94}.Dynamic|x86.Build.0 = DStatic|Win32 + {A772FE5B-F91F-405F-A54C-BB12334A3C94}.Static|ARM.ActiveCfg = Static|Win32 + {A772FE5B-F91F-405F-A54C-BB12334A3C94}.Static|ARM.Build.0 = Static|Win32 + {A772FE5B-F91F-405F-A54C-BB12334A3C94}.Static|ARM64.ActiveCfg = Static|Win32 + {A772FE5B-F91F-405F-A54C-BB12334A3C94}.Static|ARM64.Build.0 = Static|Win32 + {A772FE5B-F91F-405F-A54C-BB12334A3C94}.Static|x64.ActiveCfg = Static|x64 + {A772FE5B-F91F-405F-A54C-BB12334A3C94}.Static|x64.Build.0 = Static|x64 + {A772FE5B-F91F-405F-A54C-BB12334A3C94}.Static|x86.ActiveCfg = Static|Win32 + {A772FE5B-F91F-405F-A54C-BB12334A3C94}.Static|x86.Build.0 = Static|Win32 {2A7AF6B9-03FD-4586-AC60-F9EDDF05DB4E}.DDynamic|ARM.ActiveCfg = Dynamic|ARM {2A7AF6B9-03FD-4586-AC60-F9EDDF05DB4E}.DDynamic|ARM.Build.0 = Dynamic|ARM {2A7AF6B9-03FD-4586-AC60-F9EDDF05DB4E}.DDynamic|ARM64.ActiveCfg = DDynamic|ARM64