From 1948dd0c1a88ab2b785315782a91283442bc9ece Mon Sep 17 00:00:00 2001 From: Jamie Reece Wilson Date: Mon, 24 Jul 2023 07:17:08 +0100 Subject: [PATCH] [*] Further reduce Win32 link-time requirements --- Source/AuProcAddresses.NT.cpp | 20 +++- Source/AuProcAddresses.NT.hpp | 75 +++++++++++++++ .../ConsoleWxWidgets/ConsoleWxWidgets.cpp | 6 +- Source/Extensions/Win32/DarkTheme.cpp | 5 +- Source/HWInfo/AuRamInfo.cpp | 5 +- Source/IO/FS/FileAttrs.NT.cpp | 18 ++-- Source/IO/FS/Resources.cpp | 42 ++++++++- Source/IO/Net/AuIPAddress.cpp | 46 +++++++++- Source/IO/Net/AuNetResolver.NT.cpp | 91 ++++++++++++++----- 9 files changed, 268 insertions(+), 40 deletions(-) diff --git a/Source/AuProcAddresses.NT.cpp b/Source/AuProcAddresses.NT.cpp index fa43f654..4ad2b8b6 100644 --- a/Source/AuProcAddresses.NT.cpp +++ b/Source/AuProcAddresses.NT.cpp @@ -28,6 +28,8 @@ namespace Aurora ADD_LOAD_LIB(WS2); ADD_LOAD_LIB(AdvancedApi); ADD_LOAD_LIB(BCrypt); + ADD_LOAD_LIB(Theme); + ADD_LOAD_LIB(Shell); #define ADD_GET_PROC(name, proc) \ if (h ## name) \ @@ -68,7 +70,8 @@ namespace Aurora ADD_GET_PROC(Nt, NtCreateKeyedEvent) ADD_GET_PROC(Nt, RtlWaitOnAddress) ADD_GET_PROC(Nt, ZwSetTimerResolution) - + ADD_GET_PROC(Nt, NtQueryInformationProcess) + ADD_GET_PROC_BI(Kernel32, KernelBase, VirtualAlloc2) ADD_GET_PROC_BI(Kernel32, KernelBase, MapViewOfFile3) ADD_GET_PROC_BI(Kernel32, KernelBase, UnmapViewOfFile2) @@ -80,21 +83,32 @@ namespace Aurora ADD_GET_PROC(Kernel32, SetThreadSelectedCpuSets) ADD_GET_PROC(Kernel32, PrefetchVirtualMemory) ADD_GET_PROC(Kernel32, SetThreadGroupAffinity) - + ADD_GET_PROC(Kernel32, FindFirstStreamW) + ADD_GET_PROC(Kernel32, FindNextStreamW) + ADD_GET_PROC(Kernel32, FindClose) + ADD_GET_PROC(Sync, WaitOnAddress) ADD_GET_PROC(Sync, WakeByAddressSingle) ADD_GET_PROC(Sync, WakeByAddressAll) + ADD_GET_PROC(WS2, GetAddrInfoExW) ADD_GET_PROC(WS2, GetAddrInfoExCancel) + ADD_GET_PROC(WS2, FreeAddrInfoExW) + ADD_GET_PROC(WS2, getaddrinfo) + ADD_GET_PROC(WS2, freeaddrinfo) ADD_GET_PROC(AdvancedApi, CryptAcquireContextW) ADD_GET_PROC(AdvancedApi, CryptReleaseContext) ADD_GET_PROC(AdvancedApi, CryptGenRandom) ADD_GET_PROC_INTERNAL_MAP(AdvancedApi, RtlGenRandom, SystemFunction036) - + ADD_GET_PROC(BCrypt, BCryptGenRandom) + ADD_GET_PROC(Theme, SetWindowTheme) + + ADD_GET_PROC(Shell, SHGetKnownFolderPath) + #else pWaitOnAddress = WaitOnAddress; pWakeByAddressSingle = WakeByAddressSingle; diff --git a/Source/AuProcAddresses.NT.hpp b/Source/AuProcAddresses.NT.hpp index eaf3137c..eebf221d 100644 --- a/Source/AuProcAddresses.NT.hpp +++ b/Source/AuProcAddresses.NT.hpp @@ -18,6 +18,8 @@ namespace Aurora static const wchar_t *kWS2DllName { L"Ws2_32.dll" }; static const wchar_t *kAdvancedApiDllName { L"Advapi32.dll" }; static const wchar_t *kBCryptDllName { L"bcrypt.dll" }; + static const wchar_t *kThemeDllName { L"UxTheme.dll" }; + static const wchar_t *kShellDllName { L"Shell32.dll" }; struct WIN32_MEMORY_RANGE_ENTRY2 { @@ -165,6 +167,40 @@ namespace Aurora LPHANDLE lpHandle ); + using LPLOOKUPSERVICE_COMPLETION_ROUTINE = void(__stdcall *)( + DWORD dwError, + DWORD dwBytes, + LPWSAOVERLAPPED lpOverlapped + ); + + inline INT(__stdcall *pGetAddrInfoExW)( + PCWSTR pName, + PCWSTR pServiceName, + DWORD dwNameSpace, + LPGUID lpNspId, + const ADDRINFOEXW * hints, + PADDRINFOEXW * ppResult, + struct timeval * timeout, + LPOVERLAPPED lpOverlapped, + LPLOOKUPSERVICE_COMPLETION_ROUTINE lpCompletionRoutine, + LPHANDLE lpHandle + ); + + inline void(__stdcall *pFreeAddrInfoExW)( + PADDRINFOEXW pAddrInfoEx + ); + + inline INT(__stdcall *pgetaddrinfo)( + PCSTR pNodeName, + PCSTR pServiceName, + const ADDRINFOA * pHints, + PADDRINFOA * ppResult + ); + + inline void(__stdcall *pfreeaddrinfo)( + PADDRINFOA pAddrInfo + ); + inline BOOL(__stdcall *pPrefetchVirtualMemory)( HANDLE hProcess, ULONG_PTR NumberOfEntries, @@ -209,6 +245,45 @@ namespace Aurora ULONG RandomBufferLength ); +#if defined(AURORA_PLATFORM_WIN32) + inline NTSTATUS(__stdcall *pNtQueryInformationProcess)( + HANDLE ProcessHandle, + PROCESSINFOCLASS ProcessInformationClass, + PVOID ProcessInformation, + ULONG ProcessInformationLength, + PULONG ReturnLength + ); +#endif + + inline HRESULT(__stdcall *pSetWindowTheme)( + HWND hwnd, + LPCWSTR pszSubAppName, + LPCWSTR pszSubIdList + ); + + inline HANDLE(__stdcall *pFindFirstStreamW)( + LPCWSTR lpFileName, + STREAM_INFO_LEVELS InfoLevel, + LPVOID lpFindStreamData, + DWORD dwFlags + ); + + inline BOOL(__stdcall *pFindNextStreamW)( + HANDLE hFindStream, + LPVOID lpFindStreamData + ); + + inline BOOL(__stdcall *pFindClose)( + HANDLE hFindFile + ); + + inline HRESULT(__stdcall *pSHGetKnownFolderPath)( + const GUID & rfid, + DWORD dwFlags, + HANDLE hToken, + PWSTR * ppszPath + ); + inline bool gUseNativeWaitMutex {}; inline bool gUseNativeWaitCondvar {}; inline bool gUseNativeWaitSemapahore {}; diff --git a/Source/Console/ConsoleWxWidgets/ConsoleWxWidgets.cpp b/Source/Console/ConsoleWxWidgets/ConsoleWxWidgets.cpp index e9f24110..cb26aa41 100644 --- a/Source/Console/ConsoleWxWidgets/ConsoleWxWidgets.cpp +++ b/Source/Console/ConsoleWxWidgets/ConsoleWxWidgets.cpp @@ -577,7 +577,11 @@ ConsoleFrame::ConsoleFrame(const wxString &title, const wxPoint &pos, const wxSi if (Aurora::Extensions::Win32::_FlushMenuThemes) Aurora::Extensions::Win32::_FlushMenuThemes(); - SetWindowTheme(handle, L"DarkMode_Explorer", NULL); + if (pSetWindowTheme) + { + pSetWindowTheme(handle, L"DarkMode_Explorer", NULL); + } + SendMessageW(handle, WM_THEMECHANGED, 0, 0); Aurora::Extensions::Win32::RefreshTitleBarThemeColor(handle); diff --git a/Source/Extensions/Win32/DarkTheme.cpp b/Source/Extensions/Win32/DarkTheme.cpp index b6a75013..10b2ee97 100644 --- a/Source/Extensions/Win32/DarkTheme.cpp +++ b/Source/Extensions/Win32/DarkTheme.cpp @@ -86,7 +86,10 @@ namespace Aurora::Extensions::Win32 void MakeWindowBordersDark(HWND window) { if (!g_darkModeSupported) return; - SetWindowTheme(window, L"DarkMode_Explorer", NULL); + if (pSetWindowTheme) + { + pSetWindowTheme(window, L"DarkMode_Explorer", NULL); + } AllowDarkModeForWindow(window, true); RefreshTitleBarThemeColor(window); } diff --git a/Source/HWInfo/AuRamInfo.cpp b/Source/HWInfo/AuRamInfo.cpp index b877b1ab..9d3b62f3 100644 --- a/Source/HWInfo/AuRamInfo.cpp +++ b/Source/HWInfo/AuRamInfo.cpp @@ -69,7 +69,8 @@ namespace Aurora::HWInfo auto max = GetMemStatSystem().value_or(RamStat {}).qwAvailable; #if defined(AURORA_PLATFORM_WIN32) - if (AuSwInfo::IsWindows10OrGreater()) + if (pNtQueryInformationProcess && + AuSwInfo::IsWindows10OrGreater()) { struct VM_COUNTERS_EX { @@ -97,7 +98,7 @@ namespace Aurora::HWInfo static const PROCESSINFOCLASS kProcessVmCounters = static_cast(3); - if (NtQueryInformationProcess(GetCurrentProcess(), kProcessVmCounters, &vm, sizeof(vm), 0)) + if (pNtQueryInformationProcess(GetCurrentProcess(), kProcessVmCounters, &vm, sizeof(vm), 0)) { // I WILL NOT USE A BLOATED OS THAT LIES TO US // I WILL NOT USE A BLOATED OS THAT LIES TO US diff --git a/Source/IO/FS/FileAttrs.NT.cpp b/Source/IO/FS/FileAttrs.NT.cpp index 1a136b7c..63eb3e68 100644 --- a/Source/IO/FS/FileAttrs.NT.cpp +++ b/Source/IO/FS/FileAttrs.NT.cpp @@ -28,10 +28,16 @@ namespace Aurora::IO::FS return {}; } - auto hIterationHandle = ::FindFirstStreamW(win32Path.c_str(), - FindStreamInfoStandard, - &data, - 0); + if (!pFindFirstStreamW) + { + SysPushErrorUnavailableError(); + return {}; + } + + auto hIterationHandle = pFindFirstStreamW(win32Path.c_str(), + FindStreamInfoStandard, + &data, + 0); if (hIterationHandle == INVALID_HANDLE_VALUE) { if (!AuFS::FileExists(pathex)) @@ -86,8 +92,8 @@ namespace Aurora::IO::FS names.push_back(currentName); } - while (::FindNextStreamW(hIterationHandle, &data)); - ::FindClose(hIterationHandle); + while (pFindNextStreamW(hIterationHandle, &data)); + pFindClose(hIterationHandle); return names; } diff --git a/Source/IO/FS/Resources.cpp b/Source/IO/FS/Resources.cpp index b27d4f55..ce6f2b9e 100644 --- a/Source/IO/FS/Resources.cpp +++ b/Source/IO/FS/Resources.cpp @@ -115,10 +115,50 @@ namespace Aurora::IO::FS #if defined(AURORA_PLATFORM_WIN32) + static AuOptional GUIDTOCISL(REFKNOWNFOLDERID rfid) + { + if (rfid == FOLDERID_RoamingAppData) + { + return CSIDL_APPDATA; + } + + if (rfid == FOLDERID_ProgramData) + { + return CSIDL_COMMON_APPDATA; + } + + if (rfid == FOLDERID_System) + { + return CSIDL_SYSTEM; + } + + if (rfid == FOLDERID_Profile) + { + return CSIDL_PROFILE; + } + + return {}; + } + static AuString GetSpecialDir(REFKNOWNFOLDERID rfid) { PWSTR directory; - if (SHGetKnownFolderPath(rfid, KF_FLAG_DEFAULT, NULL, &directory) != S_OK) + + if (!pSHGetKnownFolderPath) + { + if (auto opt = GUIDTOCISL(rfid)) + { + AuString temp(MAX_PATH, '\x00'); + if (SHGetFolderPathA(0, *opt, 0, 0, temp.data()) == S_OK) + { + return temp; + } + } + + return ""; + } + + if (pSHGetKnownFolderPath(rfid, KF_FLAG_DEFAULT, NULL, &directory) != S_OK) { SysPanic("Couldn't get known special directory path of [MS:{}-{}-{}-{}{}{}{}{}{}{}{}] with a NULL access token", rfid.Data1, rfid.Data2, rfid.Data3, rfid.Data4[0], rfid.Data4[1], rfid.Data4[2], rfid.Data4[3], rfid.Data4[4], rfid.Data4[5], rfid.Data4[6], rfid.Data4[7]); diff --git a/Source/IO/Net/AuIPAddress.cpp b/Source/IO/Net/AuIPAddress.cpp index 1a67ad3b..05649b12 100644 --- a/Source/IO/Net/AuIPAddress.cpp +++ b/Source/IO/Net/AuIPAddress.cpp @@ -16,6 +16,47 @@ namespace Aurora::IO::Net this->ip = EIPProtocol::eEnumInvalid; } +#if defined(AURORA_PLATFORM_WIN32) + int inet_pton_2(int af, const char *src, void *dst) + { + sockaddr_storage sastor {}; + + int size = sizeof(sastor); + + if (::WSAStringToAddressA(AuString(src).data(), + af, + NULL, + (struct sockaddr *)&sastor, + &size)) + { + return 0; + } + + switch (af) + { + case AF_INET: + { + *(in_addr *)dst = ((sockaddr_in *)&sastor)->sin_addr; + return 1; + } + #if defined(AF_INET6) + case AF_INET6: + { + *(in6_addr *)dst = ((sockaddr_in6 *)&sastor)->sin6_addr; + return 1; + } + #endif + } + + return 0; + } +#else + int inet_pton_2(int af, const char *src, void *dst) + { + return ::inet_pton(af, src, dst); + } +#endif + IPAddress::IPAddress(const AuString &parse) { char buf[64]; @@ -30,8 +71,9 @@ namespace Aurora::IO::Net isIPV4 = parse[1] == '.' || parse[2] == '.' || parse[3] == '.'; } - // Requires Windows 8.1 or greater to link... - if (::inet_pton(isIPV4 ? AF_INET : AF_INET6, parse.c_str(), buf) != 1) + if (inet_pton_2(isIPV4 ? AF_INET : AF_INET6, + parse.c_str(), + buf) != 1) { return; } diff --git a/Source/IO/Net/AuNetResolver.NT.cpp b/Source/IO/Net/AuNetResolver.NT.cpp index a9002070..7556daf9 100644 --- a/Source/IO/Net/AuNetResolver.NT.cpp +++ b/Source/IO/Net/AuNetResolver.NT.cpp @@ -31,7 +31,7 @@ namespace Aurora::IO::Net bool NetResolver::Start() { - ADDRINFOEXW infoEx { 0 }; + ADDRINFOEXW infoEx {}; int iInfoEx { 0 }; if (this->bA && this->bAAAA) @@ -56,33 +56,76 @@ namespace Aurora::IO::Net int iRet {}; HANDLE hHandle = NULL; - if (pGetAddrInfoExCancel) + if (pGetAddrInfoExW) { - iRet = GetAddrInfoExW(AuLocale::ConvertFromUTF8(this->hostname).data(), - nullptr, - NS_DNS, - nullptr, - &infoEx, - &this->resultHandle_, - nullptr, - &this->overlapped, - NULL, - &hHandle); + if (pGetAddrInfoExCancel) + { + iRet = pGetAddrInfoExW(AuLocale::ConvertFromUTF8(this->hostname).data(), + nullptr, + NS_DNS, + nullptr, + &infoEx, + &this->resultHandle_, + nullptr, + &this->overlapped, + NULL, + &hHandle); + } + else + { + iRet = pGetAddrInfoExW(AuLocale::ConvertFromUTF8(this->hostname).data(), + nullptr, + NS_DNS, + nullptr, + &infoEx, + &this->resultHandle_, + nullptr, + nullptr, + nullptr, + nullptr); + } + } + else if (pgetaddrinfo) + { + ADDRINFOA infoA { 0 }; + PADDRINFOA pInfoRet {}; + infoA.ai_family = infoEx.ai_family; + + iRet = pgetaddrinfo(this->hostname.c_str(), + nullptr, + &infoA, + &pInfoRet); + + if (iRet == 0) + { + auto pCurrent = pInfoRet; + + while (pCurrent) + { + NetEndpoint endpoint; + AuMemcpy(endpoint.hint, pCurrent->ai_addr, pCurrent->ai_addrlen); + DeoptimizeEndpoint(endpoint); + + if (!AuTryInsert(this->processedIps_, endpoint.ip)) + { + return false; + } + + pCurrent = pCurrent->ai_next; + } + } + + if (pInfoRet && pfreeaddrinfo) + { + pfreeaddrinfo(pInfoRet); + } } else { - iRet = GetAddrInfoExW(AuLocale::ConvertFromUTF8(this->hostname).data(), - nullptr, - NS_DNS, - nullptr, - &infoEx, - &this->resultHandle_, - nullptr, - nullptr, - nullptr, - nullptr); + return false; } + this->hName_ = hHandle; return this->FinishOperationEx(AuSharedFromThis(), this->pWorker_, @@ -195,9 +238,9 @@ namespace Aurora::IO::Net pCurrent = pCurrent->ai_next; } - if (this->resultHandle_) + if (this->resultHandle_ && pFreeAddrInfoExW) { - ::FreeAddrInfoExW(this->resultHandle_); + pFreeAddrInfoExW(this->resultHandle_); } return true;