From e876d321a6fec3587956eeef55d7d44b7ff49353 Mon Sep 17 00:00:00 2001 From: mingkuang Date: Mon, 6 May 2024 12:36:06 +0800 Subject: [PATCH] =?UTF-8?q?*=20Fea=20#66,=20=E8=AE=A9.NET=208/9=20?= =?UTF-8?q?=E6=94=AF=E6=8C=81=20Windows=20XP=20RTM=EF=BC=88=E9=83=A8?= =?UTF-8?q?=E5=88=86=EF=BC=89=20=20=20-=20=E6=B7=BB=E5=8A=A0=20CopyContext?= =?UTF-8?q?=20=20=20-=20=E6=B7=BB=E5=8A=A0=20SetThreadIdealProcessorEx=20?= =?UTF-8?q?=20=20-=20=E6=B7=BB=E5=8A=A0=20GetThreadIdealProcessorEx=20=20?= =?UTF-8?q?=20-=20=E6=B7=BB=E5=8A=A0=20EventActivityIdControl=20=20=20-=20?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20EventRegister=20=20=20-=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=20EventUnregister=20=20=20-=20=E6=B7=BB=E5=8A=A0=20En?= =?UTF-8?q?umerateTraceGuidsEx=20=20=20-=20=E6=B7=BB=E5=8A=A0=20EventEnabl?= =?UTF-8?q?ed=20=20=20-=20=E6=B7=BB=E5=8A=A0=20EventWrite=20=20=20-=20?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20EventWriteTransfer=20=20=20-=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=20EventWriteEx=20=20=20-=20=E6=B7=BB=E5=8A=A0=20Conve?= =?UTF-8?q?rtInterfaceIndexToLuid=20=20=20-=20=E6=B7=BB=E5=8A=A0=20Convert?= =?UTF-8?q?InterfaceLuidToNameW(A)=20=20=20-=20=E6=B7=BB=E5=8A=A0=20Conver?= =?UTF-8?q?tInterfaceNameToLuidW(A)=20=20=20-=20=E6=B7=BB=E5=8A=A0=20if=5F?= =?UTF-8?q?nametoindex=20=20=20-=20=E6=B7=BB=E5=8A=A0=20if=5Findextoname?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ThunksList.md | 27 +- src/Thunks/Iphlpapi.hpp | 391 +++++++++++++++++- src/Thunks/YY_Thunks.cpp | 184 +++++++++ src/Thunks/api-ms-win-core-processthreads.hpp | 80 +++- src/Thunks/api-ms-win-core-xstate.hpp | 143 +++++++ src/Thunks/api-ms-win-eventing-provider.hpp | 218 +++++++++- src/YY-Thunks.UnitTest/Iphlpapi.UnitTest.cpp | 227 ++++++++++ 7 files changed, 1259 insertions(+), 11 deletions(-) diff --git a/ThunksList.md b/ThunksList.md index da91614..bdd2d8a 100644 --- a/ThunksList.md +++ b/ThunksList.md @@ -72,6 +72,14 @@ | RegGetValueW(A) | 不存在时,调用RegQueryValueExW(A)。 | RegCopyTreeW(A) | 不存在时,调用SHCopyKeyW(A)。 | EventSetInformation | 不存在时,返回ERROR_NOT_SUPPORTED。 +| EventActivityIdControl | 不存在时,返回ERROR_NOT_SUPPORTED。 +| EventRegister | 不存在时,返回ERROR_NOT_SUPPORTED。 +| EventUnregister | 不存在时,返回ERROR_NOT_SUPPORTED。 +| EnumerateTraceGuidsEx | 不存在时,返回ERROR_NOT_SUPPORTED。 +| EventEnabled | 不存在时,返回ERROR_NOT_SUPPORTED。 +| EventWrite | 不存在时,返回ERROR_NOT_SUPPORTED。 +| EventWriteTransfer | 不存在时,返回ERROR_NOT_SUPPORTED。 +| EventWriteEx | 不存在时,调用EventWriteTransfer。 ## bcrypt.dll | 函数 | Fallback @@ -112,11 +120,16 @@ ## iphlpapi.dll | 函数 | Fallback | ---- | ----------- -| GetIfTable2 | 不存在时调用,GetIfTable,并使用HeapAlloc申请内存。 -| GetIfTable2Ex | 不存在时调用,GetIfTable,并使用HeapAlloc申请内存。 -| GetIfEntry2 | 不存在时调用,GetIfEntry。 -| GetIfEntry2Ex | 不存在时调用,GetIfEntry2。 -| FreeMibTable | 不存在时调用,HeapFree。 +| GetIfTable2 | 不存在时,调用GetIfTable,并使用HeapAlloc申请内存。 +| GetIfTable2Ex | 不存在时,调用GetIfTable,并使用HeapAlloc申请内存。 +| GetIfEntry2 | 不存在时,调用GetIfEntry。 +| GetIfEntry2Ex | 不存在时,调用GetIfEntry2。 +| FreeMibTable | 不存在时,调用HeapFree。 +| ConvertInterfaceIndexToLuid | 不存在时,调用GetIfEntry。 +| ConvertInterfaceLuidToNameW(A) | 不存在时,内部实现。 +| ConvertInterfaceNameToLuidW(A) | 不存在时,内部实现。 +| if_nametoindex | 不存在时,调用GetIfEntry。 +| if_indextoname | 不存在时,调用ConvertInterfaceIndexToLuid、ConvertInterfaceLuidToNameA。 ## kernel32.dll | 函数 | Fallback @@ -176,6 +189,7 @@ | K32GetPerformanceInfo | 调用GetPerformanceInfo。 | K32EnumPageFilesW(A) | 调用EnumPageFilesW(A)。 | K32GetProcessImageFileNameW(A) | 调用GetProcessImageFileNameW(A)。 +| K32GetProcessMemoryInfo | 调用GetProcessMemoryInfo。 | QueryFullProcessImageNameW(A) | 不存在时,调用GetProcessImageFileNameW(A) 或者 GetModuleFileNameExW(A)。 | CreateFile2 | 不存在时,调用CreateFileW。 | CreateEventExW(A) | 不存在时,调用CreateEventW(A)。 @@ -319,6 +333,9 @@ | InitializeContext | 不存在时,内部实现。 | InitializeContext2 | 不存在时,调用InitializeContext。 | LocateXStateFeature | 不存在时,内部实现。 +| CopyContext | 不存在时,内部实现。 +| SetThreadIdealProcessorEx | 不存在时,调用SetThreadIdealProcessor。 +| GetThreadIdealProcessorEx | 不存在时,调用SetThreadIdealProcessor。 ## mfplat.dll | 函数 | Fallback diff --git a/src/Thunks/Iphlpapi.hpp b/src/Thunks/Iphlpapi.hpp index 1b9bd14..80e0156 100644 --- a/src/Thunks/Iphlpapi.hpp +++ b/src/Thunks/Iphlpapi.hpp @@ -143,6 +143,55 @@ namespace YY return _lStatus; } + struct IfTypeToNameItem + { + IFTYPE uType; + const char* szName; + }; + + static const IfTypeToNameItem(&GetIfTypeMapItems(void))[9] + { + static const IfTypeToNameItem s_Map[] = + { + {IF_TYPE_OTHER, "other"}, + {IF_TYPE_ETHERNET_CSMACD, "ethernet"}, + {IF_TYPE_ISO88025_TOKENRING, "tokenring"}, + {IF_TYPE_PPP, "ppp"}, + {IF_TYPE_SOFTWARE_LOOPBACK, "loopback"}, + {IF_TYPE_ATM, "atm"}, + {IF_TYPE_IEEE80211, "wireless"}, + {IF_TYPE_TUNNEL, "tunnel"}, + {IF_TYPE_IEEE1394, "ieee1394"}, + }; + + return s_Map; + } + + static const char* __fastcall GetAnsiNameFormeIndex(IFTYPE _uType) + { + auto& _Map = GetIfTypeMapItems(); + + int bottom = 0; + int top = _countof(_Map) - 1; + + while (bottom <= top) + { + int middle = (bottom + top) / 2; + int testIndex = _uType - _Map[middle].uType; + + if (testIndex == 0) + { + return _Map[middle].szName; + } + + if (testIndex < 0) + top = middle - 1; + else + bottom = middle + 1; + } + + return "other"; + } #endif // (YY_Thunks_Support_Version < NTDDI_WIN6) #endif // !YY_Thunks_Implemented @@ -245,7 +294,7 @@ namespace YY // 忽略Level,理论上说 多取了 Statistics信息也没有太大影响。 UNREFERENCED_PARAMETER(_eLevel); - return GetIfEntry2(_pRow); + return ::GetIfEntry2(_pRow); } #endif @@ -274,5 +323,345 @@ namespace YY } } #endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + // 最低受支持的客户端 Windows Vista [桌面应用|UWP 应用] + // 最低受支持的服务器 Windows Server 2008[桌面应用 | UWP 应用] + __DEFINE_THUNK( + iphlpapi, + 8, + DWORD, + NETIOAPI_API_, + ConvertInterfaceIndexToLuid, + _In_ NET_IFINDEX InterfaceIndex, + _Out_ PNET_LUID InterfaceLuid + ) + { + if (const auto _pfnConvertInterfaceIndexToLuid = try_get_ConvertInterfaceIndexToLuid()) + { + return _pfnConvertInterfaceIndexToLuid(InterfaceIndex, InterfaceLuid); + } + + MIB_IFROW _IfRow; + _IfRow.dwIndex = InterfaceIndex; + auto _lStatus = GetIfEntry(&_IfRow); + if (_lStatus != ERROR_SUCCESS) + { + return _lStatus; + } + + // 使用 InterfaceIndex 假冒 LuidIndex + InterfaceLuid->Info.IfType = _IfRow.dwType; + InterfaceLuid->Info.NetLuidIndex = InterfaceIndex; + InterfaceLuid->Info.Reserved = 0; + return ERROR_SUCCESS; + } +#endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + // 最低受支持的客户端 Windows Vista [仅限桌面应用] + // 最低受支持的服务器 Windows Server 2008[仅限桌面应用] + __DEFINE_THUNK( + iphlpapi, + 12, + DWORD, + NETIOAPI_API_, + ConvertInterfaceLuidToNameA, + _In_ CONST NET_LUID* InterfaceLuid, + _Out_writes_(Length) PSTR InterfaceName, + _In_ SIZE_T Length + ) + { + if (const auto _pfnConvertInterfaceLuidToNameA = try_get_ConvertInterfaceLuidToNameA()) + { + return _pfnConvertInterfaceLuidToNameA(InterfaceLuid, InterfaceName, Length); + } + + internal::StringBuffer _StringBuffer(InterfaceName, Length); + if (!_StringBuffer.AppendString(GetAnsiNameFormeIndex(InterfaceLuid->Info.IfType))) + { + return ERROR_NOT_ENOUGH_MEMORY; + } + + if (!_StringBuffer.AppendChar('_')) + { + return ERROR_NOT_ENOUGH_MEMORY; + } + + if (!_StringBuffer.AppendUint32(InterfaceLuid->Info.NetLuidIndex)) + { + return ERROR_NOT_ENOUGH_MEMORY; + } + return ERROR_SUCCESS; + } +#endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + // 最低受支持的客户端 Windows Vista [仅限桌面应用] + // 最低受支持的服务器 Windows Server 2008[仅限桌面应用] + __DEFINE_THUNK( + iphlpapi, + 12, + DWORD, + NETIOAPI_API_, + ConvertInterfaceLuidToNameW, + _In_ CONST NET_LUID* InterfaceLuid, + _Out_writes_(Length) PWSTR InterfaceName, + _In_ SIZE_T Length + ) + { + if (const auto _pfnConvertInterfaceLuidToNameW = try_get_ConvertInterfaceLuidToNameW()) + { + return _pfnConvertInterfaceLuidToNameW(InterfaceLuid, InterfaceName, Length); + } + + internal::StringBuffer _StringBuffer(InterfaceName, Length); + if (!_StringBuffer.AppendString(GetAnsiNameFormeIndex(InterfaceLuid->Info.IfType))) + { + return ERROR_NOT_ENOUGH_MEMORY; + } + + if (!_StringBuffer.AppendChar('_')) + { + return ERROR_NOT_ENOUGH_MEMORY; + } + + if (!_StringBuffer.AppendUint32(InterfaceLuid->Info.NetLuidIndex)) + { + return ERROR_NOT_ENOUGH_MEMORY; + } + return ERROR_SUCCESS; + } +#endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + // 最低受支持的客户端 Windows Vista [仅限桌面应用] + // 最低受支持的服务器 Windows Server 2008[仅限桌面应用] + __DEFINE_THUNK( + iphlpapi, + 8, + DWORD, + NETIOAPI_API_, + ConvertInterfaceNameToLuidA, + _In_z_ CONST CHAR* InterfaceName, + _Out_ NET_LUID* InterfaceLuid + ) + { + if (const auto _pfnConvertInterfaceNameToLuidA = try_get_ConvertInterfaceNameToLuidA()) + { + return _pfnConvertInterfaceNameToLuidA(InterfaceName, InterfaceLuid); + } + + auto& _Map = GetIfTypeMapItems(); + + IFTYPE _uType = 0; + DWORD _uIfIndex; + + for (auto& _Item : _Map) + { + const char* _szEnd; + if (internal::StringStartsWithI(InterfaceName, _Item.szName, &_szEnd)) + { + if (*_szEnd == '_') + { + ++_szEnd; + if (internal::StringToUint32(_szEnd, &_uIfIndex, &_szEnd) && *_szEnd == '\0') + { + _uType = _Item.uType; + } + break; + } + } + } + + if (_uType == 0) + { + return ERROR_INVALID_PARAMETER; + } + + InterfaceLuid->Info.IfType = _uType; + InterfaceLuid->Info.NetLuidIndex = _uIfIndex; + InterfaceLuid->Info.Reserved = 0; + return ERROR_SUCCESS; + } +#endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + // 最低受支持的客户端 Windows Vista [仅限桌面应用] + // 最低受支持的服务器 Windows Server 2008[仅限桌面应用] + __DEFINE_THUNK( + iphlpapi, + 8, + DWORD, + NETIOAPI_API_, + ConvertInterfaceNameToLuidW, + _In_z_ CONST WCHAR* InterfaceName, + _Out_ NET_LUID* InterfaceLuid + ) + { + if (const auto _pfnConvertInterfaceNameToLuidW = try_get_ConvertInterfaceNameToLuidW()) + { + return _pfnConvertInterfaceNameToLuidW(InterfaceName, InterfaceLuid); + } + + auto& _Map = GetIfTypeMapItems(); + + IFTYPE _uType = 0; + DWORD _uIfIndex; + + for (auto& _Item : _Map) + { + const WCHAR* _szEnd; + if (internal::StringStartsWithI(InterfaceName, _Item.szName, &_szEnd)) + { + if (*_szEnd == '_') + { + ++_szEnd; + if (internal::StringToUint32(_szEnd, &_uIfIndex, &_szEnd) && *_szEnd == '\0') + { + _uType = _Item.uType; + } + break; + } + } + } + + if (_uType == 0) + { + return ERROR_INVALID_PARAMETER; + } + + InterfaceLuid->Info.IfType = _uType; + InterfaceLuid->Info.NetLuidIndex = _uIfIndex; + InterfaceLuid->Info.Reserved = 0; + return ERROR_SUCCESS; + } +#endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + // 最低受支持的客户端 Windows Vista [桌面应用|UWP 应用] + // 最低受支持的服务器 Windows Server 2008[桌面应用 | UWP 应用] + __DEFINE_THUNK( + iphlpapi, + 4, + NET_IFINDEX, + NETIOAPI_API_, + if_nametoindex, + _In_ PCSTR _szInterfaceName + ) + { + if (const auto _pfnif_nametoindex = try_get_if_nametoindex()) + { + return _pfnif_nametoindex(_szInterfaceName); + } + + auto& _Map = GetIfTypeMapItems(); + + IFTYPE _uType = 0; + MIB_IFROW _IfRow; + + for (auto& _Item : _Map) + { + const char* _szEnd; + if (internal::StringStartsWithI(_szInterfaceName, _Item.szName, &_szEnd)) + { + if (*_szEnd == '_') + { + ++_szEnd; + if (internal::StringToUint32(_szEnd, &_IfRow.dwIndex, &_szEnd) && *_szEnd == '\0') + { + _uType = _Item.uType; + } + break; + } + } + } + + if (_uType == 0) + { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + + auto _lStatus = GetIfEntry(&_IfRow); + if (_lStatus != ERROR_SUCCESS) + { + SetLastError(_lStatus); + return 0; + } + + if (_IfRow.dwType == _uType) + { + return _IfRow.dwIndex; + } + else if (_uType == IF_TYPE_OTHER) + { + for (auto& _Item : _Map) + { + if (_Item.uType == _IfRow.dwType) + { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + } + + return _IfRow.dwIndex; + } + + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } +#endif + + + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + // 最低受支持的客户端 Windows Vista [桌面应用|UWP 应用] + // 最低受支持的服务器 Windows Server 2008[桌面应用 | UWP 应用] + __DEFINE_THUNK( + iphlpapi, + 8, + PCHAR, + NETIOAPI_API_, + if_indextoname, + _In_ NET_IFINDEX InterfaceIndex, + _Out_writes_(IF_NAMESIZE) PCHAR InterfaceName + ) + { + if (const auto _pfnif_indextoname = try_get_if_indextoname()) + { + return _pfnif_indextoname(InterfaceIndex, InterfaceName); + } + + InterfaceName[0] = '\0'; + NET_LUID InterfaceLuid; + auto _lStatus = ::ConvertInterfaceIndexToLuid(InterfaceIndex, &InterfaceLuid); + if (_lStatus != ERROR_SUCCESS) + { + SetLastError(_lStatus); + return nullptr; + } + + _lStatus = ::ConvertInterfaceLuidToNameA(&InterfaceLuid, InterfaceName, IF_NAMESIZE); + if (_lStatus != ERROR_SUCCESS) + { + SetLastError(_lStatus); + return nullptr; + } + return InterfaceName; + } +#endif } } diff --git a/src/Thunks/YY_Thunks.cpp b/src/Thunks/YY_Thunks.cpp index d257f8e..e97b600 100644 --- a/src/Thunks/YY_Thunks.cpp +++ b/src/Thunks/YY_Thunks.cpp @@ -359,6 +359,190 @@ namespace YY _pId->Data4[7] = (CharToHex(_szInput[34]) << 4) | (CharToHex(_szInput[35]) << 0); return TRUE; } + + template + static bool __fastcall StringStartsWithI(_In_z_ const Char1* _szStr, _In_z_ const Char2* _szStartsWith, _Outptr_opt_result_z_ const Char1** _szEnd = nullptr) + { + if (_szEnd) + *_szEnd = _szStr; + + if (_szStr == (Char1*)_szStartsWith) + return true; + + if (_szStr == nullptr) + return false; + if (_szStartsWith == nullptr) + return false; + + for (; *_szStartsWith;++_szStr, ++_szStartsWith) + { + if (*_szStr == *_szStartsWith) + { + continue; + } + else if (__ascii_tolower(*_szStr) == __ascii_tolower(*_szStartsWith)) + { + continue; + } + + return false; + } + if (_szEnd) + *_szEnd = _szStr; + return true; + } + + template + static bool __fastcall StringToUint32(_In_z_ const Char* _szStr, _Out_ DWORD* _puResult, _Outptr_opt_result_z_ Char const** _pszEnd = nullptr) + { + auto _szEnd = _szStr; + + if (_pszEnd) + *_pszEnd = _szEnd; + + *_puResult = 0; + + DWORD64 _uResult64 = 0; + for (;;++_szEnd) + { + if (*_szEnd <= '9' && *_szEnd >= '0') + { + _uResult64 *= 10; + _uResult64 += *_szEnd - '0'; + + // 溢出 + if (_uResult64 > 0xFFFFFFFFull) + { + return false; + } + } + else + { + break; + } + } + + if (_szStr == _szEnd) + return false; + + *_puResult = static_cast(_uResult64); + if (_pszEnd) + *_pszEnd = _szEnd; + return true; + } + + + template + class StringBuffer + { + public: + Char* szBuffer; + size_t uLength; + size_t uBufferLength; + + StringBuffer() + : szBuffer(nullptr) + , uLength(0) + , uBufferLength(0) + { + } + + StringBuffer(Char* _szBuffer, size_t _uBufferLength) + : szBuffer(_szBuffer) + , uLength(0) + , uBufferLength(_uBufferLength) + { + if (uBufferLength) + { + *szBuffer = '\0'; + } + } + + StringBuffer(const StringBuffer&) = delete; + + template + bool __fastcall AppendString(_In_z_ const Char2* _szSrc) + { + if (_szSrc == nullptr || *_szSrc == '\0') + return true; + + if (uLength == uBufferLength) + return false; + + for (auto _uLengthNew = uLength; _uLengthNew != uBufferLength; ++_uLengthNew, ++_szSrc) + { + szBuffer[_uLengthNew] = *_szSrc; + if (*_szSrc == '\0') + { + uLength = _uLengthNew; + return true; + } + } + + szBuffer[uLength] = '\0'; + return false; + } + + template + bool __fastcall AppendChar(_In_z_ Char2 _Ch) + { + if (_Ch == '\0') + return true; + + const auto _uNew = uLength + 1; + if (_uNew >= uBufferLength) + return false; + szBuffer[uLength] = _Ch; + szBuffer[_uNew] = '\0'; + uLength = _uNew; + return true; + } + + bool __fastcall AppendUint32(_In_ DWORD _uAppdendData) + { + if (uLength == uBufferLength) + return false; + + auto _uLengthNew = uLength; + for(; _uLengthNew != uBufferLength;) + { + const auto _uData = _uAppdendData % 10; + _uAppdendData /= 10; + + szBuffer[_uLengthNew] = static_cast('0' + _uData); + ++_uLengthNew; + if (_uAppdendData == 0) + { + if (_uLengthNew == uBufferLength) + { + break; + } + szBuffer[_uLengthNew] = '\0'; + auto _szStart = szBuffer + uLength; + auto _szLast = szBuffer + _uLengthNew; + + for (; _szStart < _szLast;) + { + --_szLast; + const auto _ch = *_szLast; + *_szLast = *_szStart; + *_szStart = _ch; + + ++_szStart; + } + uLength = _uLengthNew; + return true; + } + } + + *szBuffer = '\0'; + return false; + } + }; + + + + } }//namespace Thunks diff --git a/src/Thunks/api-ms-win-core-processthreads.hpp b/src/Thunks/api-ms-win-core-processthreads.hpp index a74e9e1..84aff14 100644 --- a/src/Thunks/api-ms-win-core-processthreads.hpp +++ b/src/Thunks/api-ms-win-core-processthreads.hpp @@ -1078,6 +1078,84 @@ namespace YY return TRUE; } #endif + +#if (YY_Thunks_Support_Version < NTDDI_WIN7) + + // 最低受支持的客户端 Windows 7 [桌面应用 |UWP 应用] + // 最低受支持的服务器 Windows Server 2008 R2[桌面应用 | UWP 应用] + __DEFINE_THUNK( + kernel32, + 12, + BOOL, + WINAPI, + SetThreadIdealProcessorEx, + _In_ HANDLE _hThread, + _In_ PPROCESSOR_NUMBER _pIdealProcessor, + _Out_opt_ PPROCESSOR_NUMBER _pPreviousIdealProcessor + ) + { + if (const auto _pfnSetThreadIdealProcessorEx = try_get_SetThreadIdealProcessorEx()) + { + return _pfnSetThreadIdealProcessorEx(_hThread, _pIdealProcessor, _pPreviousIdealProcessor); + } + + // 不支持的平台统一认为只有一组处理器 + // 微软这里就没有检查 _pIdealProcessor + if (_pIdealProcessor->Group != 0 || _pIdealProcessor->Number >= MAXIMUM_PROCESSORS) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + const auto _uPreviousIdealProcessor = SetThreadIdealProcessor(_hThread, _pIdealProcessor->Number); + if (_uPreviousIdealProcessor == static_cast(-1)) + { + return FALSE; + } + + if (_pPreviousIdealProcessor) + { + _pPreviousIdealProcessor->Group = 0; + _pPreviousIdealProcessor->Number = _uPreviousIdealProcessor; + _pPreviousIdealProcessor->Reserved = 0; + } + return TRUE; + } +#endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN7) + + // 最低受支持的客户端 Windows 7 [桌面应用 |UWP 应用] + // 最低受支持的服务器 Windows Server 2008 R2[桌面应用 | UWP 应用] + __DEFINE_THUNK( + kernel32, + 8, + BOOL, + WINAPI, + GetThreadIdealProcessorEx, + _In_ HANDLE _hThread, + _Out_ PPROCESSOR_NUMBER _pIdealProcessor + ) + { + if (const auto _pfnGetThreadIdealProcessorEx = try_get_GetThreadIdealProcessorEx()) + { + return _pfnGetThreadIdealProcessorEx(_hThread, _pIdealProcessor); + } + + // 不支持的平台统一认为只有一组处理器 + const auto _uPreviousIdealProcessor = SetThreadIdealProcessor(_hThread, MAXIMUM_PROCESSORS); + if (_uPreviousIdealProcessor == static_cast(-1)) + { + return FALSE; + } + + _pIdealProcessor->Group = 0; + _pIdealProcessor->Number = _uPreviousIdealProcessor; + _pIdealProcessor->Reserved = 0; + return TRUE; + } +#endif }//namespace Thunks -} //namespace YY \ No newline at end of file +} //namespace YY diff --git a/src/Thunks/api-ms-win-core-xstate.hpp b/src/Thunks/api-ms-win-core-xstate.hpp index c519b8c..00f0299 100644 --- a/src/Thunks/api-ms-win-core-xstate.hpp +++ b/src/Thunks/api-ms-win-core-xstate.hpp @@ -200,5 +200,148 @@ return InitializeContext(Buffer, ContextFlags, Context, ContextLength); } #endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN6SP1) + + // 最低受支持的客户端 Windows 7 SP1 [仅限桌面应用] + // 最低受支持的服务器 Windows Server 2008 R2 SP1[仅限桌面应用] + __DEFINE_THUNK( + kernel32, + 12, + BOOL, + WINAPI, + CopyContext, + _Inout_ PCONTEXT _pDestination, + _In_ DWORD _uContextFlags, + _In_ PCONTEXT _pSource + ) + { + if (auto const _pfnCopyContext = try_get_CopyContext()) + { + return _pfnCopyContext(_pDestination, _uContextFlags, _pSource); + } + +#if defined(_X86_) + constexpr auto kThreadContext = CONTEXT_i386; + +#elif defined(_AMD64_) + constexpr auto kThreadContext = CONTEXT_AMD64; +#else +#error unknow OS. +#endif + if ((_uContextFlags & kThreadContext) == 0) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + if ((CONTEXT_XSTATE & _uContextFlags) == CONTEXT_XSTATE) + { + // internal::BaseSetLastNTError(0xC00000BB); + SetLastError(ERROR_NOT_SUPPORTED); + return FALSE; + } + + if ((_pSource->ContextFlags & kThreadContext) == 0 || (_pDestination->ContextFlags & kThreadContext) == 0) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + if ((CONTEXT_DEBUG_REGISTERS & _uContextFlags) == CONTEXT_DEBUG_REGISTERS && (CONTEXT_DEBUG_REGISTERS & _pSource->ContextFlags) == CONTEXT_DEBUG_REGISTERS) + { + _pDestination->ContextFlags |= CONTEXT_DEBUG_REGISTERS; + _pDestination->Dr0 = _pSource->Dr0; + _pDestination->Dr1 = _pSource->Dr1; + _pDestination->Dr2 = _pSource->Dr2; + _pDestination->Dr3 = _pSource->Dr3; + _pDestination->Dr6 = _pSource->Dr6; + _pDestination->Dr7 = _pSource->Dr7; +#if defined(_AMD64_) + _pDestination->LastBranchToRip = _pSource->LastBranchToRip; + _pDestination->LastBranchFromRip = _pSource->LastBranchFromRip; + _pDestination->LastExceptionToRip = _pSource->LastExceptionToRip; + _pDestination->LastExceptionFromRip = _pSource->LastExceptionFromRip; +#endif + } + + if ((CONTEXT_FLOATING_POINT & _uContextFlags) == CONTEXT_FLOATING_POINT && (CONTEXT_FLOATING_POINT & _pSource->ContextFlags) == CONTEXT_FLOATING_POINT) + { + _pDestination->ContextFlags |= CONTEXT_FLOATING_POINT; +#if defined(_X86_) + memcpy(&_pDestination->FloatSave, &_pSource->FloatSave, sizeof(_pSource->FloatSave)); +#elif defined(_AMD64_) + _pDestination->MxCsr = _pSource->MxCsr; + memcpy(&_pDestination->FltSave, &_pSource->FltSave, sizeof(_pSource->FltSave)); +#else +#error unknow OS. +#endif + } + + if ((CONTEXT_SEGMENTS & _uContextFlags) == CONTEXT_SEGMENTS && (CONTEXT_SEGMENTS & _pSource->ContextFlags) == CONTEXT_SEGMENTS) + { + _pDestination->ContextFlags |= CONTEXT_SEGMENTS; + _pDestination->SegGs = _pSource->SegGs; + _pDestination->SegFs = _pSource->SegFs; + _pDestination->SegEs = _pSource->SegEs; + _pDestination->SegDs = _pSource->SegDs; + } + + if ((CONTEXT_INTEGER & _uContextFlags) == CONTEXT_INTEGER && (CONTEXT_INTEGER & _pSource->ContextFlags) == CONTEXT_INTEGER) + { + _pDestination->ContextFlags |= CONTEXT_INTEGER; +#if defined(_X86_) + _pDestination->Edi = _pSource->Edi; + _pDestination->Esi = _pSource->Esi; + _pDestination->Ebx = _pSource->Ebx; + _pDestination->Edx = _pSource->Edx; + _pDestination->Ecx = _pSource->Ecx; + _pDestination->Eax = _pSource->Eax; +#elif defined(_AMD64_) + _pDestination->Rax = _pSource->Rax; + _pDestination->Rcx = _pSource->Rcx; + _pDestination->Rdx = _pSource->Rdx; + _pDestination->Rbx = _pSource->Rbx; + _pDestination->Rbp = _pSource->Rbp; + _pDestination->Rsi = _pSource->Rsi; + _pDestination->Rdi = _pSource->Rdi; + _pDestination->R8 = _pSource->R8; + _pDestination->R9 = _pSource->R9; + _pDestination->R10 = _pSource->R10; + _pDestination->R11 = _pSource->R11; + _pDestination->R12 = _pSource->R12; + _pDestination->R13 = _pSource->R13; + _pDestination->R14 = _pSource->R14; + _pDestination->R15 = _pSource->R15; +#else +#error unknow OS. +#endif + } + + if ((CONTEXT_CONTROL & _uContextFlags) == CONTEXT_CONTROL && (CONTEXT_CONTROL & _pSource->ContextFlags) == CONTEXT_CONTROL) + { + _pDestination->ContextFlags |= CONTEXT_CONTROL; +#if defined(_X86_) + _pDestination->Ebp = _pSource->Ebp; + _pDestination->Eip = _pSource->Eip; + _pDestination->SegCs = _pSource->SegCs; + _pDestination->EFlags = _pSource->EFlags; + _pDestination->Esp = _pSource->Esp; + _pDestination->SegSs = _pSource->SegSs; +#elif defined(_AMD64_) + _pDestination->SegCs = _pSource->SegCs; + _pDestination->SegSs = _pSource->SegSs; + _pDestination->EFlags = _pSource->EFlags; + _pDestination->Rsp = _pSource->Rsp; + _pDestination->Rip = _pSource->Rip; +#else +#error unknow OS. +#endif + } + + return TRUE; + } +#endif } } diff --git a/src/Thunks/api-ms-win-eventing-provider.hpp b/src/Thunks/api-ms-win-eventing-provider.hpp index ba98ff1..e632b99 100644 --- a/src/Thunks/api-ms-win-eventing-provider.hpp +++ b/src/Thunks/api-ms-win-eventing-provider.hpp @@ -1,16 +1,19 @@ -#if (YY_Thunks_Support_Version < NTDDI_WIN8) +#if (YY_Thunks_Support_Version < NTDDI_WIN8) #include #endif +#if (YY_Thunks_Support_Version < NTDDI_WIN6) +#include +#endif + namespace YY { namespace Thunks { - #if (YY_Thunks_Support_Version < NTDDI_WIN8) - // ֵ֧Ŀͻ Windows 8 [Ӧ|UWP Ӧ] - // ֵ֧ķ Windows Server 2012[Ӧ | UWP Ӧ] + // 最低受支持的客户端 Windows 8 [桌面应用|UWP 应用] + // 最低受支持的服务器 Windows Server 2012[桌面应用 | UWP 应用] __DEFINE_THUNK( advapi32, 20, @@ -31,5 +34,212 @@ namespace YY return ERROR_NOT_SUPPORTED; } #endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + // Minimum supported client Windows Vista [desktop apps | UWP apps] + // Minimum supported server Windows Server 2008[desktop apps | UWP apps] + __DEFINE_THUNK( + advapi32, + 8, + ULONG, + WINAPI, + EventActivityIdControl, + _In_ ULONG _uControlCode, + _Inout_ LPGUID _pActivityId + ) + { + if (auto const _pfnEventActivityIdControl = try_get_EventActivityIdControl()) + { + return _pfnEventActivityIdControl(_uControlCode, _pActivityId); + } + + return ERROR_NOT_SUPPORTED; + } +#endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + // Minimum supported client Windows Vista [desktop apps | UWP apps] + // Minimum supported server Windows Server 2008[desktop apps | UWP apps] + __DEFINE_THUNK( + advapi32, + 16, + ULONG, + WINAPI, + EventRegister, + _In_ LPCGUID _pProviderId, + _In_opt_ PENABLECALLBACK _pfnEnableCallback, + _In_opt_ PVOID _pCallbackContext, + _Out_ PREGHANDLE _phRegHandle + ) + { + if (auto const _pfnEventRegister = try_get_EventRegister()) + { + return _pfnEventRegister(_pProviderId, _pfnEnableCallback, _pCallbackContext, _phRegHandle); + } + + return ERROR_NOT_SUPPORTED; + } +#endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + // Minimum supported client Windows Vista [desktop apps | UWP apps] + // Minimum supported server Windows Server 2008[desktop apps | UWP apps] + __DEFINE_THUNK( + advapi32, + 8, + ULONG, + WINAPI, + EventUnregister, + _In_ REGHANDLE _hRegHandle + ) + { + if (auto const _pfnEventUnregister = try_get_EventUnregister()) + { + return _pfnEventUnregister(_hRegHandle); + } + return ERROR_NOT_SUPPORTED; + } +#endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + // Minimum supported client Windows Vista [desktop apps | UWP apps] + // Minimum supported server Windows Server 2008[desktop apps | UWP apps] + __DEFINE_THUNK( + advapi32, + 24, + ULONG, + WINAPI, + EnumerateTraceGuidsEx, + _In_ TRACE_QUERY_INFO_CLASS TraceQueryInfoClass, + _In_reads_bytes_opt_(InBufferSize) PVOID InBuffer, + _In_ ULONG InBufferSize, + _Out_writes_bytes_opt_(OutBufferSize) PVOID OutBuffer, + _In_ ULONG OutBufferSize, + _Out_ PULONG ReturnLength + ) + { + if (auto const _pfnEnumerateTraceGuidsEx = try_get_EnumerateTraceGuidsEx()) + { + return _pfnEnumerateTraceGuidsEx(TraceQueryInfoClass, InBuffer, InBufferSize, OutBuffer, OutBufferSize, ReturnLength); + } + return ERROR_NOT_SUPPORTED; + } +#endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + // Minimum supported client Windows Vista [desktop apps | UWP apps] + // Minimum supported server Windows Server 2008[desktop apps | UWP apps] + __DEFINE_THUNK( + advapi32, + 28, + ULONG, + WINAPI, + EventWriteTransfer, + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR EventDescriptor, + _In_opt_ LPCGUID ActivityId, + _In_opt_ LPCGUID RelatedActivityId, + _In_range_(0, MAX_EVENT_DATA_DESCRIPTORS) ULONG UserDataCount, + _In_reads_opt_(UserDataCount) PEVENT_DATA_DESCRIPTOR UserData + ) + { + if (auto const _pfnEventWriteTransfer = try_get_EventWriteTransfer()) + { + return _pfnEventWriteTransfer(RegHandle, EventDescriptor, ActivityId, RelatedActivityId, UserDataCount, UserData); + } + + return ERROR_NOT_SUPPORTED; + } +#endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + // 最低受支持的客户端 Windows Vista [仅限桌面应用] + // 最低受支持的服务器 Windows Server 2008[仅限桌面应用] + __DEFINE_THUNK( + advapi32, + 12, + BOOLEAN, + WINAPI, + EventEnabled, + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR EventDescriptor + ) + { + if (auto const _pfnEventEnabled = try_get_EventEnabled()) + { + return _pfnEventEnabled(RegHandle, EventDescriptor); + } + + return FALSE; + } +#endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN6) + + // 最低受支持的客户端 Windows Vista [桌面应用 | UWP 应用] + // 最低受支持的服务器 Windows Server 2008[桌面应用 | UWP 应用] + __DEFINE_THUNK( + advapi32, + 20, + ULONG, + WINAPI, + EventWrite, + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR EventDescriptor, + _In_range_(0, MAX_EVENT_DATA_DESCRIPTORS) ULONG UserDataCount, + _In_reads_opt_(UserDataCount) PEVENT_DATA_DESCRIPTOR UserData + ) + { + if (auto const _pfnEventWrite = try_get_EventWrite()) + { + return _pfnEventWrite(RegHandle, EventDescriptor, UserDataCount, UserData); + } + + return ERROR_NOT_SUPPORTED; + } +#endif + + +#if (YY_Thunks_Support_Version < NTDDI_WIN7) + + // 最低受支持的客户端 Windows 7 [桌面应用 |UWP 应用] + // 最低受支持的服务器 Windows Server 2008 R2[桌面应用 | UWP 应用] + __DEFINE_THUNK( + advapi32, + 40, + ULONG, + WINAPI, + EventWriteEx, + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR EventDescriptor, + _In_ ULONG64 Filter, + _In_ ULONG Flags, + _In_opt_ LPCGUID ActivityId, + _In_opt_ LPCGUID RelatedActivityId, + _In_range_(0, MAX_EVENT_DATA_DESCRIPTORS) ULONG UserDataCount, + _In_reads_opt_(UserDataCount) PEVENT_DATA_DESCRIPTOR UserData + ) + { + if (auto const _pfnEventWriteEx = try_get_EventWriteEx()) + { + return _pfnEventWriteEx(RegHandle, EventDescriptor, Filter, Flags, ActivityId, RelatedActivityId, UserDataCount, UserData); + } + + return ::EventWriteTransfer(RegHandle, EventDescriptor, ActivityId, RelatedActivityId, UserDataCount, UserData); + } +#endif } } diff --git a/src/YY-Thunks.UnitTest/Iphlpapi.UnitTest.cpp b/src/YY-Thunks.UnitTest/Iphlpapi.UnitTest.cpp index 4bdecb5..8cbea5b 100644 --- a/src/YY-Thunks.UnitTest/Iphlpapi.UnitTest.cpp +++ b/src/YY-Thunks.UnitTest/Iphlpapi.UnitTest.cpp @@ -39,4 +39,231 @@ namespace Iphlpapi ::FreeMibTable(_pTable2_YY); } }; + + TEST_CLASS(ConvertInterfaceNameToLuid) + { + struct Input + { + const char* szInterfaceName; + ULONG64 IfType; + ULONG64 NetLuidIndex; + }; + + public: + ConvertInterfaceNameToLuid() + { + YY::Thunks::aways_null_try_get_ConvertInterfaceNameToLuidA = true; + YY::Thunks::aways_null_try_get_ConvertInterfaceNameToLuidW = true; + } + + ~ConvertInterfaceNameToLuid() + { + YY::Thunks::aways_null_try_get_ConvertInterfaceNameToLuidA = false; + YY::Thunks::aways_null_try_get_ConvertInterfaceNameToLuidW = false; + } + + TEST_METHOD(输入验证) + { + static const Input s_Input[] = + { + {"other_1", IF_TYPE_OTHER, 1}, + {"ethernet_12", IF_TYPE_ETHERNET_CSMACD, 12}, + {"tokenring_123", IF_TYPE_ISO88025_TOKENRING, 123}, + {"ppp_4567", IF_TYPE_PPP, 4567}, + {"loopback_4567", IF_TYPE_SOFTWARE_LOOPBACK, 4567}, + {"atm_4567", IF_TYPE_ATM, 4567}, + {"wireless_4567", IF_TYPE_IEEE80211, 4567}, + {"tunnel_4567", IF_TYPE_TUNNEL, 4567}, + {"ieee1394_4567", IF_TYPE_IEEE1394, 4567}, + }; + + for (auto& _Item : s_Input) + { + NET_LUID InterfaceLuid; + auto _lStatus = ::ConvertInterfaceNameToLuidA(_Item.szInterfaceName, &InterfaceLuid); + + Assert::AreEqual(_lStatus, (DWORD)ERROR_SUCCESS); + Assert::AreEqual(InterfaceLuid.Info.IfType, _Item.IfType); + Assert::AreEqual(InterfaceLuid.Info.NetLuidIndex, _Item.NetLuidIndex); + } + + for (auto& _Item : s_Input) + { + NET_LUID InterfaceLuid; + auto _lStatus = ::ConvertInterfaceNameToLuidW(CStringW(_Item.szInterfaceName), &InterfaceLuid); + + Assert::AreEqual(_lStatus, (DWORD)ERROR_SUCCESS); + Assert::AreEqual(InterfaceLuid.Info.IfType, _Item.IfType); + Assert::AreEqual(InterfaceLuid.Info.NetLuidIndex, _Item.NetLuidIndex); + } + } + + TEST_METHOD(大小写验证) + { + static const Input s_Input[] = + { + {"Other_1", IF_TYPE_OTHER, 1}, + {"OtheR_1", IF_TYPE_OTHER, 1}, + {"OTHER_1", IF_TYPE_OTHER, 1}, + }; + + for (auto& _Item : s_Input) + { + NET_LUID InterfaceLuid; + auto _lStatus = ::ConvertInterfaceNameToLuidA(_Item.szInterfaceName, &InterfaceLuid); + + Assert::AreEqual(_lStatus, (DWORD)ERROR_SUCCESS); + Assert::AreEqual(InterfaceLuid.Info.IfType, _Item.IfType); + Assert::AreEqual(InterfaceLuid.Info.NetLuidIndex, _Item.NetLuidIndex); + } + + for (auto& _Item : s_Input) + { + NET_LUID InterfaceLuid; + auto _lStatus = ::ConvertInterfaceNameToLuidW(CStringW(_Item.szInterfaceName), &InterfaceLuid); + + Assert::AreEqual(_lStatus, (DWORD)ERROR_SUCCESS); + Assert::AreEqual(InterfaceLuid.Info.IfType, _Item.IfType); + Assert::AreEqual(InterfaceLuid.Info.NetLuidIndex, _Item.NetLuidIndex); + } + } + + TEST_METHOD(畸形输入写验证) + { + static const char* s_Input[] = + { + "other", + "other_", + "otherwww_" + "otherqq_1" + }; + + for (auto& _Item : s_Input) + { + NET_LUID InterfaceLuid; + auto _lStatus = ::ConvertInterfaceNameToLuidA(_Item, &InterfaceLuid); + Assert::AreNotEqual(_lStatus, (DWORD)ERROR_SUCCESS); + } + + for (auto& _Item : s_Input) + { + NET_LUID InterfaceLuid; + auto _lStatus = ::ConvertInterfaceNameToLuidW(CStringW(_Item), &InterfaceLuid); + Assert::AreNotEqual(_lStatus, (DWORD)ERROR_SUCCESS); + } + } + }; + + TEST_CLASS(ConvertInterfaceLuidToName) + { + struct Input + { + const char* szInterfaceName; + ULONG64 IfType; + ULONG64 NetLuidIndex; + }; + + public: + ConvertInterfaceLuidToName() + { + YY::Thunks::aways_null_try_get_ConvertInterfaceLuidToNameA = true; + YY::Thunks::aways_null_try_get_ConvertInterfaceLuidToNameW = true; + } + + ~ConvertInterfaceLuidToName() + { + YY::Thunks::aways_null_try_get_ConvertInterfaceLuidToNameA = false; + YY::Thunks::aways_null_try_get_ConvertInterfaceLuidToNameW = false; + } + + TEST_METHOD(输入验证) + { + static const Input s_Input[] = + { + {"other_1", IF_TYPE_OTHER, 1}, + {"other_1", IF_TYPE_RFC877_X25, 1}, + {"ethernet_12", IF_TYPE_ETHERNET_CSMACD, 12}, + {"tokenring_123", IF_TYPE_ISO88025_TOKENRING, 123}, + {"ppp_4567", IF_TYPE_PPP, 4567}, + {"loopback_4567", IF_TYPE_SOFTWARE_LOOPBACK, 4567}, + {"atm_4567", IF_TYPE_ATM, 4567}, + {"wireless_4567", IF_TYPE_IEEE80211, 4567}, + {"tunnel_4567", IF_TYPE_TUNNEL, 4567}, + {"ieee1394_4567", IF_TYPE_IEEE1394, 4567}, + }; + + for (auto& _Item : s_Input) + { + NET_LUID InterfaceLuid; + InterfaceLuid.Info.IfType = _Item.IfType; + InterfaceLuid.Info.NetLuidIndex = _Item.NetLuidIndex; + char _szNameBuffer[256]; + auto _lStatus = ::ConvertInterfaceLuidToNameA(&InterfaceLuid, _szNameBuffer, std::size(_szNameBuffer)); + + Assert::AreEqual(_lStatus, (DWORD)ERROR_SUCCESS); + Assert::AreEqual(std::string(_Item.szInterfaceName), std::string(_szNameBuffer)); + } + + for (auto& _Item : s_Input) + { + NET_LUID InterfaceLuid; + InterfaceLuid.Info.IfType = _Item.IfType; + InterfaceLuid.Info.NetLuidIndex = _Item.NetLuidIndex; + wchar_t _szNameBuffer[256]; + auto _lStatus = ::ConvertInterfaceLuidToNameW(&InterfaceLuid, _szNameBuffer, std::size(_szNameBuffer)); + + Assert::AreEqual(_lStatus, (DWORD)ERROR_SUCCESS); + Assert::AreEqual(std::wstring(CStringW(_Item.szInterfaceName)), std::wstring(_szNameBuffer)); + } + } + + + TEST_METHOD(畸形输入验证) + { + NET_LUID InterfaceLuid; + InterfaceLuid.Info.IfType = IF_TYPE_ETHERNET_CSMACD; + InterfaceLuid.Info.NetLuidIndex = 999; + { + char _szNameBuffer[256]; + auto _lStatus = ::ConvertInterfaceLuidToNameA(&InterfaceLuid, _szNameBuffer, 3); + Assert::AreEqual(_lStatus, (DWORD)ERROR_NOT_ENOUGH_MEMORY); + } + + { + wchar_t _szNameBuffer[256]; + auto _lStatus = ::ConvertInterfaceLuidToNameW(&InterfaceLuid, _szNameBuffer, 3); + Assert::AreEqual(_lStatus, (DWORD)ERROR_NOT_ENOUGH_MEMORY); + } + } + }; + + TEST_CLASS(if_nametoindex与if_indextoname) + { + public: + if_nametoindex与if_indextoname() + { + YY::Thunks::aways_null_try_get_if_nametoindex = true; + YY::Thunks::aways_null_try_get_if_indextoname = true; + YY::Thunks::aways_null_try_get_ConvertInterfaceIndexToLuid = true; + YY::Thunks::aways_null_try_get_ConvertInterfaceLuidToNameA = true; + } + + ~if_nametoindex与if_indextoname() + { + YY::Thunks::aways_null_try_get_if_nametoindex = false; + YY::Thunks::aways_null_try_get_if_indextoname = false; + YY::Thunks::aways_null_try_get_ConvertInterfaceIndexToLuid = false; + YY::Thunks::aways_null_try_get_ConvertInterfaceLuidToNameA = false; + } + + TEST_METHOD(交叉验证) + { + char _szNameBuffer[256]; + auto _szResult = ::if_indextoname(1, _szNameBuffer); + Assert::IsNotNull(_szResult); + + auto _uResultIndex = if_nametoindex(_szNameBuffer); + Assert::AreEqual(_uResultIndex, NET_IFINDEX(1)); + } + }; }