| 161 | } |
| 162 | |
| 163 | bool OnLoad(HINSTANCE hInstDLL) { |
| 164 | gSelfInstance = hInstDLL; |
| 165 | hNtdll = GetModuleHandleW(L"ntdll.dll"); |
| 166 | if (hNtdll == nullptr) { |
| 167 | return false; |
| 168 | } |
| 169 | checkEnableDebugConsole(); |
| 170 | hWsaClient = GetModuleHandleW(L"WsaClient.exe"); |
| 171 | if (kDebug) { |
| 172 | if (AllocConsole()) { |
| 173 | gConsoleIsAllocated = true; |
| 174 | } |
| 175 | gConsoleOutput = CreateFileW(L"CONOUT$", GENERIC_WRITE, FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr); |
| 176 | if (gConsoleOutput != INVALID_HANDLE_VALUE) { |
| 177 | Log::setLogHandler(&defaultLogHandler); |
| 178 | } else { |
| 179 | std::wstring msg = std::wstring(L"Error CreateFileW CONOUT$, GetLastError=") + std::to_wstring(GetLastError()); |
| 180 | MessageBoxW(nullptr, msg.c_str(), L"wsapatch.dll", MB_OK | MB_ICONERROR); |
| 181 | } |
| 182 | } |
| 183 | LOGD(L"OnLoad, hInstDLL=%p, hNtdll=%p, hWsaClient=%p", hInstDLL, hNtdll, hWsaClient); |
| 184 | if (hWsaClient == nullptr) { |
| 185 | // check if we are loaded into the correct process |
| 186 | WCHAR filename[MAX_PATH]; |
| 187 | GetModuleFileNameW(nullptr, filename, MAX_PATH); |
| 188 | // get lower case filename |
| 189 | for (int i = 0; filename[i] != 0; i++) { |
| 190 | filename[i] = towlower(filename[i]); |
| 191 | } |
| 192 | if (wcsstr(filename, L"\\wsaclinent.exe") == nullptr) { |
| 193 | WCHAR buf[1024] = {}; |
| 194 | StringCbPrintfW(buf, 1024, L"GetModuleHandleW(L\"WsaClient.exe\") is NULL.\nIs wsapatch.dll loaded into wrong process?\n%s", filename); |
| 195 | MessageBoxW(nullptr, buf, L"wsapatch.dll", MB_OK | MB_ICONERROR); |
| 196 | return false; |
| 197 | } |
| 198 | return false; |
| 199 | } |
| 200 | LOGD(L"ntdll.dll = %p", hNtdll); |
| 201 | LOGD(L"WsaClient.dll = %p", hWsaClient); |
| 202 | FuncRtlGetVersion funcRtlGetVersion = reinterpret_cast<FuncRtlGetVersion>(GetProcAddress(hNtdll, "RtlGetVersion")); |
| 203 | if (funcRtlGetVersion == nullptr) { |
| 204 | LOGE(L"GetProcAddress(NTDLL.DLL, \"RtlGetVersion\") failed, GetLastError=%d", GetLastError()); |
| 205 | return false; |
| 206 | } |
| 207 | gOsVersionInfo.dwOSVersionInfoSize = sizeof(gOsVersionInfo); |
| 208 | NTSTATUS status = funcRtlGetVersion(reinterpret_cast<PRTL_OSVERSIONINFOW>(&gOsVersionInfo)); |
| 209 | if (!NT_SUCCESS(status)) { |
| 210 | LOGE(L"funcRtlGetVersion(&osVersionInfo) failed, status=%d", status); |
| 211 | return false; |
| 212 | } |
| 213 | LOGD(L"RtlGetVersion: dwMajorVersion=%d, dwMinorVersion=%d, dwBuildNumber=%d, dwPlatformId=%d", |
| 214 | gOsVersionInfo.dwMajorVersion, gOsVersionInfo.dwMinorVersion, gOsVersionInfo.dwBuildNumber, gOsVersionInfo.dwPlatformId); |
| 215 | bool isWin11 = gOsVersionInfo.dwMajorVersion >= 10 && gOsVersionInfo.dwMinorVersion >= 0 && gOsVersionInfo.dwBuildNumber >= 22000; |
| 216 | gIsPatchVersionNumber = !isWin11; |
| 217 | gIsPatchProductType = (gOsVersionInfo.wProductType != VER_NT_WORKSTATION); |
| 218 | if (!gIsPatchVersionNumber && !gIsPatchProductType) { |
| 219 | LOGW(L"Windows 11 workstation detected, no need to patch"); |
| 220 | return true; |
no test coverage detected