/*** Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: AuProcAddresses.NT.cpp Date: 2023-2-16 Author: Reece ***/ #include #if defined(AURORA_PLATFORM_WIN32) #define _WIN32_WINNT 0x0602 #endif #include #include "Source/Threading/Primitives/AuConditionMutex.NT.hpp" #define AURORA_HAS_LOAD_PGKD #define AURORA_HAS_GET_PROC_NONWIN32 #if !defined(AURORA_RUNITIME_NO_PROFILE_SYMBOL) extern "C" { // As much as I despise third-party drivers matching module names and pattern matching, // we may as well provide some hint for: // * Windows emulators // * Future first party win32 compatibility layers // * Drivers checking for the vintage // * Non-standard PE linkers (Aurora::AddBlockedDLL(...) is valid) AUKN_SYM int NT_APPLICATION_COMPAT_AURORA_RUNTIME_ALPHA; AUKN_SYM int NT_APPLICATION_COMPAT_AURORA_RUNTIME; } #endif namespace Aurora::Memory { AuUInt32 RoundPageUp(AuUInt32 value); } namespace Aurora { static bool gShouldResPathDoNothing {}; #if !defined(AURORA_PLATFORM_WIN32) HMODULE UWPLibraryW(LPCWSTR lpLibFileName); FARPROC UWPProcAddress(HMODULE hModule, LPCSTR lpProcName); HANDLE __stdcall UWPCreateFileMappingA(HANDLE hFile, LPSECURITY_ATTRIBUTES lpFileMappingAttributes, DWORD flProtect, DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeLow, LPCSTR lpName); HANDLE __stdcall UWPOpenFileMappingA(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName); LPVOID __stdcall UWPMapViewOfFile(HANDLE hFileMappingObject, DWORD dwDesiredAccess, DWORD dwFileOffsetHigh, DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap); #endif #if !defined(AURORA_DLL_BLACKLIST) static AuUInt32 gBlockedDLLTable[128] {}; #else static AuUInt32 gBlockedDLLTable[128] { AURORA_DLL_BLACKLIST }; #endif AUKN_SYM bool AddBlockedDLL(const char *pString) { if (!pString) { return false; } auto uHash = AuFnv1a32Runtime(pString, strlen(pString)); for (AU_ITERATE_N(i, AuArraySize(gBlockedDLLTable))) { if (gBlockedDLLTable[i]) { continue; } gBlockedDLLTable[i] = uHash; return true; } return false; } static bool IsBlocked(const char *pString) { auto uHash = AuFnv1a32Runtime(pString, strlen(pString)); for (AU_ITERATE_N(i, AuArraySize(gBlockedDLLTable))) { auto uCurrent = gBlockedDLLTable[i]; if (uCurrent == uHash) { return true; } else if (uCurrent == 0) { return false; } } return false; } void InitNTAddressesForClock() { #if defined(AURORA_PLATFORM_WIN32) // We just need a partial AuSwInfo pass to work in order to setup the clocks at TLS callback-time // Why? rng isnt ready either. We need the fallback clock to work. pLoadLibraryW = LoadLibraryW; pGetProcAddress = GetProcAddress; #define ADD_LOAD_LIB(name) \ HMODULE h ## name {}; \ h ## name = GetModuleHandleW(k## name ## DllName); \ if (!h ## name) \ { \ h ## name = pLoadLibraryW(k## name ## DllName); \ } \ #define ADD_GET_PROC(name, proc) \ if (h ## name) \ { \ p ## proc = AuReinterpretCast(pGetProcAddress(h ## name, #proc)); \ } \ ADD_LOAD_LIB(Kernel32); #if 0 ADD_LOAD_LIB(AdvancedApi); #endif ADD_GET_PROC(Kernel32, VerifyVersionInfoW) ADD_GET_PROC(Kernel32, VerSetConditionMask) ADD_GET_PROC(Kernel32, QueryPerformanceCounter) ADD_GET_PROC(Kernel32, QueryPerformanceFrequency) #if 0 ADD_GET_PROC(AdvancedApi, RegSetValueExW) ADD_GET_PROC(AdvancedApi, RegCloseKey) ADD_GET_PROC(AdvancedApi, RegOpenKeyExW) ADD_GET_PROC(AdvancedApi, RegQueryValueExW) #endif #undef ADD_GET_PROC #undef ADD_LOAD_LIB #else InitNTAddresses(); #endif } void InitNTAddresses() { #if defined(AURORA_PLATFORM_WIN32) pLoadLibraryW = LoadLibraryW; pGetProcAddress = GetProcAddress; #define ADD_LOAD_LIB(name) \ \ HMODULE h ## name {}; \ if (!IsBlocked(#name)) \ { \ h ## name = GetModuleHandleW(k## name ## DllName); \ if (!h ## name) \ { \ h ## name = pLoadLibraryW(k## name ## DllName); \ } \ } ADD_LOAD_LIB(Kernel32); ADD_LOAD_LIB(Nt); ADD_LOAD_LIB(KernelBase); ADD_LOAD_LIB(Sync); ADD_LOAD_LIB(WS2); ADD_LOAD_LIB(AdvancedApi); ADD_LOAD_LIB(BCrypt); ADD_LOAD_LIB(Theme); ADD_LOAD_LIB(Shell); ADD_LOAD_LIB(PSAPILegacy); ADD_LOAD_LIB(DbgHelper); ADD_LOAD_LIB(WinTrust); ADD_LOAD_LIB(IPHelper); ADD_LOAD_LIB(COM); ADD_LOAD_LIB(User32); ADD_LOAD_LIB(SetupAPI); ADD_LOAD_LIB(Router); ADD_LOAD_LIB(CredUI); #define ADD_GET_PROC(name, proc) \ if (!IsBlocked(#proc)) \ { \ if (h ## name) \ { \ p ## proc = AuReinterpretCast(pGetProcAddress(h ## name, #proc)); \ } \ } #define ADD_GET_PROC_BI(name, name2, proc) \ if (!IsBlocked(#proc)) \ { \ p ## proc = nullptr; \ if (h ## name) \ { \ p ## proc = AuReinterpretCast(pGetProcAddress(h ## name, #proc)); \ } \ if (!p ## proc) \ { \ if (h ## name2) \ { \ p ## proc = AuReinterpretCast(pGetProcAddress(h ## name2, #proc));\ } \ } \ } #define ADD_GET_PROC_BI2(name, name2, proc, proc2) \ if (!IsBlocked(#proc)) \ { \ p ## proc2 = nullptr; \ if (h ## name) \ { \ p ## proc2 = AuReinterpretCast(pGetProcAddress(h ## name, #proc)); \ } \ if (!p ## proc2) \ { \ if (h ## name2) \ { \ p ## proc2 = AuReinterpretCast(pGetProcAddress(h ## name2, #proc2)); \ } \ } \ } #define ADD_GET_PROC_INTERNAL_MAP(name, proc, symbol) \ if (!IsBlocked(#proc)) \ { \ if (h ## name) \ { \ p ## proc = AuReinterpretCast(pGetProcAddress(h ## name, #symbol)); \ } \ } if (pRtlGetVersion) { return; } ADD_GET_PROC(Nt, RtlGetVersion) ADD_GET_PROC(Nt, NtDelayExecution) ADD_GET_PROC(Nt, NtWaitForKeyedEvent) ADD_GET_PROC(Nt, NtReleaseKeyedEvent) ADD_GET_PROC(Nt, NtOpenKeyedEvent) ADD_GET_PROC(Nt, NtCreateKeyedEvent) ADD_GET_PROC(Nt, RtlWaitOnAddress) ADD_GET_PROC(Nt, RtlWakeByAddressAll) ADD_GET_PROC(Nt, RtlWakeAddressSingle) ADD_GET_PROC(Nt, ZwSetTimerResolution) ADD_GET_PROC(Nt, NtQueryInformationProcess) ADD_GET_PROC(Nt, NtNotifyChangeDirectoryFile) ADD_GET_PROC(Nt, NtTerminateProcess) ADD_GET_PROC(Nt, NtQuerySymbolicLinkObject) ADD_GET_PROC(Nt, NtOpenSymbolicLinkObject) ADD_GET_PROC(Nt, NtWaitForMultipleObjects) ADD_GET_PROC(Nt, NtQuerySystemInformation) ADD_GET_PROC_BI(Kernel32, KernelBase, VirtualAlloc2) ADD_GET_PROC_BI(Kernel32, KernelBase, MapViewOfFile) ADD_GET_PROC_BI(Kernel32, KernelBase, MapViewOfFile3) ADD_GET_PROC_BI(Kernel32, KernelBase, UnmapViewOfFile2) ADD_GET_PROC_BI(Kernel32, KernelBase, CreateFileW) ADD_GET_PROC_BI(Kernel32, KernelBase, CreateFile2W) ADD_GET_PROC_BI(Kernel32, KernelBase, GetTempPathW) ADD_GET_PROC_BI(Kernel32, KernelBase, CreateFileMappingA) ADD_GET_PROC_BI(Kernel32, KernelBase, OpenFileMappingA) ADD_GET_PROC(Kernel32, GetSystemCpuSetInformation) ADD_GET_PROC(Kernel32, GetLogicalProcessorInformation) ADD_GET_PROC(Kernel32, SetThreadDescription) ADD_GET_PROC(Kernel32, SetThreadInformation) 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(Kernel32, CancelIoEx) ADD_GET_PROC(Kernel32, CancelSynchronousIo) ADD_GET_PROC(Kernel32, SetFileInformationByHandle) ADD_GET_PROC(Kernel32, GetLocaleInfoEx) ADD_GET_PROC(Kernel32, LCIDToLocaleName) ADD_GET_PROC(Kernel32, GetLocaleInfoW) ADD_GET_PROC(Kernel32, GetThreadId) ADD_GET_PROC(Kernel32, VerifyVersionInfoW) ADD_GET_PROC(Kernel32, VerSetConditionMask) ADD_GET_PROC(Kernel32, QueryPerformanceCounter) ADD_GET_PROC(Kernel32, QueryPerformanceFrequency) ADD_GET_PROC(Kernel32, RemoveDllDirectory) ADD_GET_PROC(Kernel32, AddDllDirectory) ADD_GET_PROC(Kernel32, SetProcessInformation) ADD_GET_PROC(Kernel32, GetNamedPipeClientProcessId) ADD_GET_PROC(Kernel32, Module32FirstW) ADD_GET_PROC(Kernel32, Module32NextW) ADD_GET_PROC(Kernel32, CreateJobObjectW) ADD_GET_PROC(Kernel32, GetConsoleScreenBufferInfo) ADD_GET_PROC(Kernel32, SetConsoleScreenBufferSize) ADD_GET_PROC(Kernel32, SetConsoleWindowInfo) ADD_GET_PROC(Kernel32, CreateConsoleScreenBuffer) ADD_GET_PROC(Kernel32, SetConsoleCursorPosition) ADD_GET_PROC(Kernel32, FillConsoleOutputCharacterW) ADD_GET_PROC(Kernel32, FillConsoleOutputAttribute) ADD_GET_PROC(Kernel32, SetConsoleTextAttribute) ADD_GET_PROC(Kernel32, SetConsoleActiveScreenBuffer) ADD_GET_PROC(Kernel32, ScrollConsoleScreenBufferW) ADD_GET_PROC(Kernel32, WriteConsoleInputW) ADD_GET_PROC(Kernel32, WriteConsoleW) ADD_GET_PROC(Kernel32, ReadConsoleInputW) ADD_GET_PROC(Kernel32, GetNumberOfConsoleInputEvents) ADD_GET_PROC_BI2(Kernel32, PSAPILegacy, K32GetProcessMemoryInfo, GetProcessMemoryInfo) ADD_GET_PROC(Sync, WaitOnAddress) ADD_GET_PROC(Sync, WakeByAddressSingle) ADD_GET_PROC(Sync, WakeByAddressAll) ADD_GET_PROC(DbgHelper, UnDecorateSymbolName) ADD_GET_PROC(DbgHelper, MiniDumpWriteDump) ADD_GET_PROC(DbgHelper, SymInitialize) ADD_GET_PROC(DbgHelper, SymGetModuleBase64) ADD_GET_PROC(DbgHelper, SymGetLineFromAddr64) ADD_GET_PROC(DbgHelper, SymFunctionTableAccess64) ADD_GET_PROC(DbgHelper, StackWalk64) 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(WS2, listen) ADD_GET_PROC(WS2, bind) ADD_GET_PROC(WS2, closesocket) ADD_GET_PROC(WS2, shutdown) ADD_GET_PROC(WS2, getpeername) ADD_GET_PROC(WS2, getsockname) ADD_GET_PROC(WS2, ioctlsocket) ADD_GET_PROC(WS2, setsockopt) ADD_GET_PROC(WS2, WSAStartup) ADD_GET_PROC(WS2, WSAIoctl) ADD_GET_PROC(WS2, WSAGetLastError) ADD_GET_PROC(WS2, WSASocketW) ADD_GET_PROC(WS2, WSARecvFrom) ADD_GET_PROC(WS2, WSARecv) ADD_GET_PROC(WS2, WSASendTo) ADD_GET_PROC(WS2, WSASend) ADD_GET_PROC(WS2, WSAStringToAddressA) ADD_GET_PROC(WinTrust, WinVerifyTrust) ADD_GET_PROC(IPHelper, GetAdaptersAddresses) ADD_GET_PROC(IPHelper, GetAdaptersInfo) ADD_GET_PROC(AdvancedApi, CryptAcquireContextW) ADD_GET_PROC(AdvancedApi, CryptReleaseContext) ADD_GET_PROC(AdvancedApi, CryptGenRandom) ADD_GET_PROC(AdvancedApi, RegSetValueExW) ADD_GET_PROC(AdvancedApi, RegCloseKey) ADD_GET_PROC(AdvancedApi, RegOpenKeyExW) ADD_GET_PROC(AdvancedApi, RegQueryValueExW) ADD_GET_PROC(AdvancedApi, DeregisterEventSource) ADD_GET_PROC(AdvancedApi, RegisterEventSourceW) ADD_GET_PROC(AdvancedApi, ReportEventW) ADD_GET_PROC(AdvancedApi, SetEntriesInAclA) ADD_GET_PROC(AdvancedApi, AllocateAndInitializeSid) ADD_GET_PROC(AdvancedApi, SetNamedSecurityInfoW) ADD_GET_PROC(AdvancedApi, FreeSid) // privilege escalation ADD_GET_PROC(AdvancedApi, CreateProcessWithLogonW); ADD_GET_PROC(AdvancedApi, CreateProcessAsUserW); ADD_GET_PROC(AdvancedApi, AdjustTokenPrivileges); ADD_GET_PROC(AdvancedApi, RevertToSelf); ADD_GET_PROC(AdvancedApi, SetTokenInformation); ADD_GET_PROC(AdvancedApi, GetSidSubAuthorityCount); ADD_GET_PROC(AdvancedApi, GetSidSubAuthority); ADD_GET_PROC(AdvancedApi, LogonUserW); ADD_GET_PROC(AdvancedApi, OpenProcessToken); ADD_GET_PROC(AdvancedApi, SetThreadToken); ADD_GET_PROC(AdvancedApi, SetSecurityInfo); ADD_GET_PROC(AdvancedApi, GetUserNameW); ADD_GET_PROC(AdvancedApi, DuplicateTokenEx); ADD_GET_PROC(AdvancedApi, LookupAccountSidW); ADD_GET_PROC(AdvancedApi, GetTokenInformation); ADD_GET_PROC(AdvancedApi, SetSecurityDescriptorDacl); ADD_GET_PROC(AdvancedApi, InitializeSecurityDescriptor); ADD_GET_PROC(AdvancedApi, LookupAccountNameW); ADD_GET_PROC(AdvancedApi, LookupPrivilegeValueA); ADD_GET_PROC(AdvancedApi, LsaOpenPolicy); ADD_GET_PROC(AdvancedApi, LsaClose); ADD_GET_PROC(AdvancedApi, LsaAddAccountRights); ADD_GET_PROC_INTERNAL_MAP(AdvancedApi, RtlGenRandom, SystemFunction036) ADD_GET_PROC(BCrypt, BCryptGenRandom) ADD_GET_PROC(Theme, SetWindowTheme) ADD_GET_PROC(COM, CoInitializeEx) ADD_GET_PROC(COM, CoUninitialize) ADD_GET_PROC(COM, CoTaskMemFree) ADD_GET_PROC(Shell, SHGetKnownFolderPath) ADD_GET_PROC(Shell, SHGetFolderPathA) ADD_GET_PROC(Shell, CommandLineToArgvW) ADD_GET_PROC(Shell, ShellExecuteW) ADD_GET_PROC(User32, GetClipboardData); ADD_GET_PROC(User32, MapVirtualKeyA); ADD_GET_PROC(User32, CloseClipboard); ADD_GET_PROC(User32, GetWindowThreadProcessId); ADD_GET_PROC(User32, SendMessageA); ADD_GET_PROC(User32, EnumThreadWindows); ADD_GET_PROC(User32, DispatchMessageW); ADD_GET_PROC(User32, TranslateMessage); ADD_GET_PROC(User32, MsgWaitForMultipleObjectsEx); ADD_GET_PROC(User32, MsgWaitForMultipleObjects); ADD_GET_PROC(User32, PeekMessageW); ADD_GET_PROC(User32, SetPropW); ADD_GET_PROC(User32, OpenClipboard); ADD_GET_PROC(SetupAPI, SetupDiEnumDeviceInterfaces); ADD_GET_PROC(SetupAPI, SetupDiDestroyDeviceInfoList); ADD_GET_PROC(SetupAPI, SetupDiGetClassDevsW); ADD_GET_PROC(SetupAPI, SetupDiGetDeviceRegistryPropertyA); ADD_GET_PROC(SetupAPI, SetupDiGetDeviceInterfaceDetailW); ADD_GET_PROC(Router, WNetCloseEnum); ADD_GET_PROC(Router, WNetEnumResourceW); ADD_GET_PROC(Router, WNetOpenEnumW); ADD_GET_PROC(Router, WNetGetUniversalNameW); ADD_GET_PROC(CredUI, CredUIPromptForWindowsCredentialsW); ADD_GET_PROC(CredUI, CredUnPackAuthenticationBufferW); if (pNtCreateKeyedEvent && Threading::Primitives::gKeyedEventHandle == INVALID_HANDLE_VALUE) { if (!gUseNativeWaitCondvar) { SysAssert(pNtCreateKeyedEvent); pNtCreateKeyedEvent(&Threading::Primitives::gKeyedEventHandle, -1, NULL, 0); } } #else pLoadLibraryW = UWPLibraryW; pGetProcAddress = UWPProcAddress; pCreateFile2W = CreateFile2FromAppW; pCreateFileMappingFromApp = CreateFileMappingFromApp; pOpenFileMappingFromApp = OpenFileMappingFromApp; pMapViewOfFileFromApp = MapViewOfFileFromApp; pCreateFileMappingA = UWPCreateFileMappingA; pOpenFileMappingA = UWPOpenFileMappingA; pMapViewOfFile = UWPMapViewOfFile; pWaitOnAddress = WaitOnAddress; pWakeByAddressSingle = WakeByAddressSingle; pWakeByAddressAll = WakeByAddressAll; pVirtualAlloc2 = VirtualAlloc2FromApp; pMapViewOfFile3 = MapViewOfFile3FromApp; pCancelIoEx = CancelIoEx; pCancelSynchronousIo = CancelSynchronousIo; pGetLocaleInfoEx = GetLocaleInfoEx; pLCIDToLocaleName = LCIDToLocaleName; pSetFileInformationByHandle = SetFileInformationByHandle; pFindClose = FindClose; pGetTempPathW = GetTempPath2W; pGetSystemCpuSetInformation = GetSystemCpuSetInformation; pGetLogicalProcessorInformation = GetLogicalProcessorInformation; pSetThreadInformation = SetThreadInformation; pSetThreadDescription = SetThreadDescription; pSetThreadSelectedCpuSets = SetThreadSelectedCpuSets; pGetAddrInfoExCancel = GetAddrInfoExCancel; pPrefetchVirtualMemory = PrefetchVirtualMemory; pQueryPerformanceCounter = decltype(pQueryPerformanceCounter)(QueryPerformanceCounter); pQueryPerformanceFrequency = decltype(pQueryPerformanceFrequency)(QueryPerformanceFrequency); // https://github.com/LWJGL/lwjgl3/blob/master/modules/lwjgl/remotery/src/main/c/Remotery.c#L1188 // Xbox main SDK has a better API we should use // So... // TODO: Xbox One and later: https://github.com/microsoft/Xbox-ATG-Samples/blob/main/XDKSamples/Graphics/AdvancedESRAM12/PageAllocator.cpp#L193-L206 // Require AuProcess for that given target pUnmapViewOfFile2 = UnmapViewOfFile2; // < isn't portable but // "This topic lists the Win32 APIs that are part of the Universal Windows Platform (UWP) and that are implemented by all Windows 10 devices." // UnmapViewOfFile2 -> Introduced into api-ms-win-core-memory-l1-1-5.dll in 10.0.17134. pNtDelayExecution = nullptr /* ... (you dont need it, but it'll help a ton for SleepNs) */; pGetAddrInfoExW = GetAddrInfoExW; pGetAddrInfoExCancel = GetAddrInfoExCancel; pFreeAddrInfoExW = FreeAddrInfoExW; pgetaddrinfo = getaddrinfo; pfreeaddrinfo = freeaddrinfo; plisten = listen; pbind = bind; pclosesocket = closesocket; pshutdown = shutdown; pgetpeername = getpeername; pgetsockname = getsockname; pioctlsocket = ioctlsocket; psetsockopt = setsockopt; pWSAStartup = WSAStartup; pWSAIoctl = WSAIoctl; pWSAGetLastError = WSAGetLastError; pWSASocketW = WSASocketW; pWSARecvFrom = WSARecvFrom; pWSARecv = WSARecv; pWSASendTo = WSASendTo; pWSASend = WSASend; pWSAStringToAddressA = WSAStringToAddressA; #endif gUseNativeWaitMutex = (pWaitOnAddress && !gRuntimeConfig.threadingConfig.bPreferNt51XpMutexesOver8 && (pRtlWaitOnAddress || AuBuild::kCurrentPlatform != AuBuild::EPlatform::ePlatformWin32)) || !pNtWaitForKeyedEvent; gUseNativeWaitCondvar = (pWaitOnAddress && !gRuntimeConfig.threadingConfig.bPreferNt51XpCondvarsOver8 && (pRtlWaitOnAddress || AuBuild::kCurrentPlatform != AuBuild::EPlatform::ePlatformWin32)) || !pNtWaitForKeyedEvent; gUseNativeWaitSemapahore = bool(pWaitOnAddress); } static bool IsNetbookXpOrWin7Laptop() { return bool(GetEnvironmentVariableW(L"AURORA_IS_NETBOOK", nullptr, 0)); } void Win32DropInit() { gShouldResPathDoNothing = (AuBuild::kCurrentPlatform != AuBuild::EPlatform::ePlatformWin32) || (!gRuntimeConfig.threadingConfig.bEnableAggressiveScheduling && AuSwInfo::IsWindows10OrGreater()) || IsNetbookXpOrWin7Laptop(); gUseFastFail = AuSwInfo::IsWindows8Point1OrGreater() #if defined(PF_FASTFAIL_AVAILABLE) && ::IsProcessorFeaturePresent(PF_FASTFAIL_AVAILABLE) #endif ; if (gShouldResPathDoNothing) { return; } #if defined(PROCESS_POWER_THROTTLING_CURRENT_VERSION) if (pSetProcessInformation && AuSwInfo::IsWindows10OrGreater()) { static AuInitOnceSmall gInitOnce; if (AuThreading::InitOnceLocker::TryLock(&gInitOnce)) { PROCESS_POWER_THROTTLING_STATE powerThrottling {}; powerThrottling.Version = PROCESS_POWER_THROTTLING_CURRENT_VERSION; powerThrottling.ControlMask = PROCESS_POWER_THROTTLING_EXECUTION_SPEED; powerThrottling.StateMask = 0; gShouldResPathDoNothing = bool(pSetProcessInformation(GetCurrentProcess(), ProcessPowerThrottling, &powerThrottling, sizeof(powerThrottling))); powerThrottling.ControlMask = PROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTION; powerThrottling.StateMask = 0; gShouldResPathDoNothing &= bool(pSetProcessInformation(GetCurrentProcess(), ProcessPowerThrottling, &powerThrottling, sizeof(powerThrottling))); AuThreading::InitOnceLocker::Finish(&gInitOnce); } /* else no-wait. intentionally nop*/ } #endif } void Win32DropSchedulerResolution() { ULONG ullActualResolution {}; if (gShouldResPathDoNothing) { return; } if (gRuntimeConfig.threadingConfig.bEnableAgrSchedulingRatelimit) { static Aurora::Utility::RateLimiter limiter; if (!limiter.nsTimeStep) { limiter.SetNextStep(AuMSToNS(gRuntimeConfig.threadingConfig.bWinXpThrough7BlazeOptimizerPower)); } else if (!limiter.CheckExchangePass()) { return; } } if (pZwSetTimerResolution) { auto uRet = pZwSetTimerResolution(1, true, &ullActualResolution); if (uRet == 0) { return; } else if (uRet == 0xC0000245) { if ((uRet = pZwSetTimerResolution(5'000, true, &ullActualResolution)) == 0) { return; } } } } HANDLE UWPCreateFileMappingA(HANDLE hFile, LPSECURITY_ATTRIBUTES lpFileMappingAttributes, DWORD flProtect, DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeLow, LPCSTR lpName) { auto uSize = AuUInt64(AuUInt64(dwMaximumSizeHigh) << 32ull) | AuUInt64(dwMaximumSizeLow); if (!uSize && SysHandleIsNonZero(AuUInt(hFile))) { uSize = SysGetFileLength(AuUInt(hFile)); } if (!pCreateFileMappingFromApp) { return NULL; } return pCreateFileMappingFromApp(hFile, lpFileMappingAttributes, flProtect, uSize, lpName ? AuLocale::ConvertFromUTF8(lpName).c_str() : nullptr); } HANDLE UWPOpenFileMappingA(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName) { if (!pOpenFileMappingFromApp) { return NULL; } return pOpenFileMappingFromApp(dwDesiredAccess, bInheritHandle, lpName ? AuLocale::ConvertFromUTF8(lpName).c_str() : nullptr); } LPVOID UWPMapViewOfFile(HANDLE hFileMappingObject, DWORD dwDesiredAccess, DWORD dwFileOffsetHigh, DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap) { if (!pMapViewOfFileFromApp) { return NULL; } return pMapViewOfFileFromApp(hFileMappingObject, dwDesiredAccess, AuUInt64(AuUInt64(dwFileOffsetHigh) << 32ull) | AuUInt64(dwFileOffsetLow), dwNumberOfBytesToMap); } void Win32Terminate() { if (gUseFastFail) { __fastfail('fokd'); } else { if (pNtTerminateProcess) { pNtTerminateProcess((HANDLE)-1, 0x0); } ::TerminateProcess(::GetCurrentProcess(), 0); } } HANDLE Win32Open(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, bool bInherit, DWORD dwCreationDisposition, DWORD dwFlags, DWORD dwAttributes ) { SECURITY_ATTRIBUTES attrs {}; attrs.nLength = sizeof(attrs); attrs.bInheritHandle = bInherit ? TRUE : FALSE; bool bSpecialFlags = (dwFlags & 0x4ffff7); bool bSpecialAttrs = (dwAttributes & 0xFFB00008); if (!pCreateFile2W) { if (bSpecialFlags) { SysPushErrorFeatureMissing("Do not use Windows8+ attributes/flags under Win32Open"); return INVALID_HANDLE_VALUE; } if (bSpecialAttrs) { SysPushErrorFeatureMissing("Do not use Windows8+ attributes/flags under Win32Open"); return INVALID_HANDLE_VALUE; } } if (!dwAttributes) { dwAttributes = FILE_ATTRIBUTE_NORMAL; } if (pCreateFileW && !bSpecialFlags && !bSpecialAttrs) { return pCreateFileW(lpFileName, dwDesiredAccess, dwShareMode, &attrs, dwCreationDisposition, dwFlags | dwAttributes, NULL); } if (pCreateFile2W) { _CREATEFILE2_EXTENDED_PARAMETERS params {}; bool bRead {}; HANDLE hHandle {}; params.dwSize = sizeof(_CREATEFILE2_EXTENDED_PARAMETERS); params.dwFileFlags = dwFlags; params.dwFileAttributes = dwAttributes; params.lpSecurityAttributes = &attrs; if ((bRead = (::wcscmp(lpFileName, L"CONIN$") == 0)) || (::wcscmp(lpFileName, L"CONOUT$") == 0) || (::wcscmp(lpFileName, L"CONERR$") == 0)) { if (!bRead) { dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; } else { dwDesiredAccess = GENERIC_READ; } if ((hHandle = pCreateFile2W(lpFileName, dwDesiredAccess, dwShareMode, dwCreationDisposition, ¶ms)) != INVALID_HANDLE_VALUE) { return hHandle; } lpFileName = L"CON"; } return pCreateFile2W(lpFileName, dwDesiredAccess, dwShareMode, dwCreationDisposition, ¶ms); } return INVALID_HANDLE_VALUE; } HANDLE Win32Open2(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlags, DWORD dwAttributes) { bool bSpecialFlags = (dwFlags & 0x4ffff7); bool bSpecialAttrs = (dwAttributes & 0xFFB00008); if (!pCreateFile2W) { if (bSpecialFlags) { SysPushErrorFeatureMissing("Do not use Windows8+ attributes/flags under Win32Open"); return INVALID_HANDLE_VALUE; } if (bSpecialAttrs) { SysPushErrorFeatureMissing("Do not use Windows8+ attributes/flags under Win32Open"); return INVALID_HANDLE_VALUE; } } if (!dwAttributes) { dwAttributes = FILE_ATTRIBUTE_NORMAL; } if (pCreateFileW && !bSpecialFlags && !bSpecialAttrs) { return pCreateFileW(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlags | dwAttributes, NULL); } if (pCreateFile2W) { _CREATEFILE2_EXTENDED_PARAMETERS params {}; bool bRead {}; HANDLE hHandle {}; params.dwSize = sizeof(_CREATEFILE2_EXTENDED_PARAMETERS); params.dwFileFlags = dwFlags; params.dwFileAttributes = dwAttributes; params.lpSecurityAttributes = lpSecurityAttributes; if ((bRead = (::wcscmp(lpFileName, L"CONIN$") == 0)) || (::wcscmp(lpFileName, L"CONOUT$") == 0) || (::wcscmp(lpFileName, L"CONERR$") == 0)) { if (!bRead) { dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; } else { dwDesiredAccess = GENERIC_READ; } if ((hHandle = pCreateFile2W(lpFileName, dwDesiredAccess, dwShareMode, dwCreationDisposition, ¶ms)) != INVALID_HANDLE_VALUE) { return hHandle; } lpFileName = L"CON"; } return pCreateFile2W(lpFileName, dwDesiredAccess, dwShareMode, dwCreationDisposition, ¶ms); } return INVALID_HANDLE_VALUE; } #if !defined(AURORA_PLATFORM_WIN32) HMODULE UWPLibraryW(LPCWSTR lpLibFileName) { auto pos = std::basic_string_view(lpLibFileName).find_last_of('/'); if (pos == std::basic_string_view::npos) { pos = std::basic_string_view(lpLibFileName).find_last_of('\\'); } if (pos == std::basic_string_view::npos) { #if defined(AURORA_HAS_LOAD_PGKD) return (HMODULE)::LoadPackagedLibrary(lpLibFileName, 0); #else return (HMODULE)lpLibFileName; #endif } else { auto pString = &lpLibFileName[pos + 1]; #if defined(AURORA_HAS_LOAD_PGKD) return (HMODULE)::LoadPackagedLibrary(pString, 0); #else return (HMODULE)pString; #endif } } FARPROC UWPProcAddress(HMODULE hModule, LPCSTR lpProcName) { if (!hModule) { return nullptr; } #if defined(AURORA_HAS_GET_PROC_NONWIN32) return GetProcAddress(hModule, lpProcName); #endif return nullptr; } #endif bool SysNativeWaitOnAddressFutexSupported() { return bool(pWaitOnAddress) || bool(pRtlWaitOnAddress); } bool SysWaitOnAddressTimed(const void *pTargetAddress, const void *pCompareAddress, AuUInt8 uWordSize, AuUInt64 uAbsTimeSteadyClock, AuUInt64 uRelativeNanoseconds, AuOptional uAbsTimeAltClock, bool bSpun) { // Wont move out of AuWakeOnAddress.cpp because it's so long and bloated in order to force nanosecond-scale yields on UWP. SysUnreachable(); } void NTWriteEoS(HANDLE hHandle) { SetEndOfFile(hHandle); } void SysWriteEoS(AuUInt uOSHandle) { NTWriteEoS((HANDLE)uOSHandle); } void SysCloseHandle(AuUInt uOSHandle) { auto pHandle = (void *)uOSHandle; AuWin32CloseHandle(pHandle); } bool SysHandleIsNonZero(AuUInt uOSHandle) { return uOSHandle && (void *)uOSHandle != INVALID_HANDLE_VALUE; } void SysFlushHandle(AuUInt uOSHandle) { auto pHandle = (void *)uOSHandle; FlushFileBuffers(pHandle); } AuUInt64 SysGetFileLength(AuUInt uOSHandle) { LARGE_INTEGER length; if (!::GetFileSizeEx((HANDLE)uOSHandle, &length)) { SysPushErrorIO(); return 0; } return length.QuadPart; } void *SysAllocateLarge(AuUInt uLength) { uLength = AuMemory::RoundPageUp(uLength); return VirtualAlloc(nullptr, uLength, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); } void SysAllocateFree(void *pBuffer, AuUInt uLength) { VirtualFree(pBuffer, 0, MEM_RELEASE); } bool SysMemoryLockPages(const void *pVoid, AuUInt uLength) { return VirtualLock((void *)pVoid, uLength); } bool SysMemoryUnlockPages(const void *pVoid, AuUInt uLength) { return VirtualUnlock((void *)pVoid, uLength); } }