| 1317 | */ |
| 1318 | |
| 1319 | static void reportWindowsError( char const * const apiName, int32_t slot ) |
| 1320 | { |
| 1321 | char * errorMessage; |
| 1322 | char buf[24]; |
| 1323 | string * err_buf; |
| 1324 | timing_info time; |
| 1325 | DWORD const errorCode = GetLastError(); |
| 1326 | DWORD apiResult = FormatMessageA( |
| 1327 | FORMAT_MESSAGE_ALLOCATE_BUFFER | /* __in DWORD dwFlags */ |
| 1328 | FORMAT_MESSAGE_FROM_SYSTEM | |
| 1329 | FORMAT_MESSAGE_IGNORE_INSERTS, |
| 1330 | NULL, /* __in_opt LPCVOID lpSource */ |
| 1331 | errorCode, /* __in DWORD dwMessageId */ |
| 1332 | 0, /* __in DWORD dwLanguageId */ |
| 1333 | (LPSTR)&errorMessage, /* __out LPTSTR lpBuffer */ |
| 1334 | 0, /* __in DWORD nSize */ |
| 1335 | 0 ); /* __in_opt va_list * Arguments */ |
| 1336 | |
| 1337 | /* Build a message as if the process had written to stderr. */ |
| 1338 | if ( globs.pipe_action ) |
| 1339 | err_buf = cmdtab[ slot ].buffer_err; |
| 1340 | else |
| 1341 | err_buf = cmdtab[ slot ].buffer_out; |
| 1342 | string_append( err_buf, apiName ); |
| 1343 | string_append( err_buf, "() Windows API failed: " ); |
| 1344 | sprintf( buf, "%lu", errorCode ); |
| 1345 | string_append( err_buf, buf ); |
| 1346 | |
| 1347 | if ( !apiResult ) |
| 1348 | string_append( err_buf, ".\n" ); |
| 1349 | else |
| 1350 | { |
| 1351 | string_append( err_buf, " - " ); |
| 1352 | string_append( err_buf, errorMessage ); |
| 1353 | /* Make sure that the buffer is terminated with a newline */ |
| 1354 | if( err_buf->value[ err_buf->size - 1 ] != '\n' ) |
| 1355 | string_push_back( err_buf, '\n' ); |
| 1356 | LocalFree( errorMessage ); |
| 1357 | } |
| 1358 | |
| 1359 | /* Since the process didn't actually start, use a blank timing_info. */ |
| 1360 | time.system = 0; |
| 1361 | time.user = 0; |
| 1362 | timestamp_current( &time.start ); |
| 1363 | timestamp_current( &time.end ); |
| 1364 | |
| 1365 | /* Invoke the callback with a failure status. */ |
| 1366 | (*cmdtab[ slot ].func)( cmdtab[ slot ].closure, EXEC_CMD_FAIL, &time, |
| 1367 | cmdtab[ slot ].buffer_out->value, cmdtab[ slot ].buffer_err->value, |
| 1368 | EXIT_OK ); |
| 1369 | |
| 1370 | /* Clean up any handles that were opened. */ |
| 1371 | closeWinHandle( &cmdtab[ slot ].pi.hProcess ); |
| 1372 | closeWinHandle( &cmdtab[ slot ].pi.hThread ); |
| 1373 | closeWinHandle( &cmdtab[ slot ].pipe_out[ EXECCMD_PIPE_READ ] ); |
| 1374 | closeWinHandle( &cmdtab[ slot ].pipe_out[ EXECCMD_PIPE_WRITE ] ); |
| 1375 | closeWinHandle( &cmdtab[ slot ].pipe_err[ EXECCMD_PIPE_READ ] ); |
| 1376 | closeWinHandle( &cmdtab[ slot ].pipe_err[ EXECCMD_PIPE_WRITE ] ); |
no test coverage detected