| 258 | } |
| 259 | |
| 260 | bool CacheRelFunTBL() { |
| 261 | // Table generator ocmmand line |
| 262 | std::string cmd = "GRS.Backends.DX12.Service.RelFunTBL.exe"; |
| 263 | |
| 264 | // Startup information |
| 265 | STARTUPINFO info{}; |
| 266 | info.cb = sizeof(info); |
| 267 | |
| 268 | // Launch table generator |
| 269 | PROCESS_INFORMATION processInfo; |
| 270 | if (!CreateProcess( |
| 271 | nullptr, |
| 272 | cmd.data(), |
| 273 | nullptr, |
| 274 | nullptr, |
| 275 | false, |
| 276 | 0, |
| 277 | nullptr, |
| 278 | nullptr, |
| 279 | &info, |
| 280 | &processInfo |
| 281 | )) { |
| 282 | return false; |
| 283 | } |
| 284 | |
| 285 | // Wait for process |
| 286 | WaitForSingleObject(processInfo.hProcess, INFINITE); |
| 287 | |
| 288 | // Validate exit code |
| 289 | DWORD exitCode; |
| 290 | if (!GetExitCodeProcess(processInfo.hProcess, &exitCode)) { |
| 291 | exitCode = 1u; |
| 292 | } |
| 293 | |
| 294 | // Cleanup |
| 295 | CloseHandle(processInfo.hProcess); |
| 296 | CloseHandle(processInfo.hThread); |
| 297 | |
| 298 | // Succeeded? |
| 299 | if (exitCode != 0) { |
| 300 | return false; |
| 301 | } |
| 302 | |
| 303 | // Open table data |
| 304 | std::ifstream stream(GetIntermediatePath("Interop") / "X86RelFunTbl.dat", std::ios_base::binary); |
| 305 | if (!stream.good()) { |
| 306 | return false; |
| 307 | } |
| 308 | |
| 309 | // Stream in table |
| 310 | stream.read(reinterpret_cast<char*>(&X86Table), sizeof(X86Table)); |
| 311 | stream.close(); |
| 312 | |
| 313 | // Validate |
| 314 | if (!X86Table.kernel32LoadLibraryA || !X86Table.kernel32FreeLibrary) { |
| 315 | return false; |
| 316 | } |
| 317 |
no test coverage detected