| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 |
- /* See LICENSE.txt for the full license governing this code. */
- /**
- * \file windows_process.c
- *
- * Source file for the process API on windows.
- */
- #include <SDL.h>
- #include <SDL_test.h>
- #include <string.h>
- #include <stdlib.h>
- #include "SDL_visualtest_process.h"
- #if defined(__WIN32__)
- void
- LogLastError(const char* str)
- {
- LPVOID buffer;
- DWORD dw = GetLastError();
- FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|
- FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&buffer,
- 0, NULL);
- SDLTest_LogError("%s: %s", str, (char*)buffer);
- LocalFree(buffer);
- }
- int
- SDL_LaunchProcess(char* file, char* args, SDL_ProcessInfo* pinfo)
- {
- BOOL success;
- char* working_directory;
- char* command_line;
- int path_length, args_length;
- STARTUPINFO sui = {0};
- sui.cb = sizeof(sui);
- if(!file)
- {
- SDLTest_LogError("Path to executable to launched cannot be NULL.");
- return 0;
- }
- if(!pinfo)
- {
- SDLTest_LogError("pinfo cannot be NULL.");
- return 0;
- }
- /* get the working directory of the process being launched, so that
- the process can load any resources it has in it's working directory */
- path_length = SDL_strlen(file);
- if(path_length == 0)
- {
- SDLTest_LogError("Length of the file parameter is zero.");
- return 0;
- }
- working_directory = (char*)SDL_malloc(path_length + 1);
- if(!working_directory)
- {
- SDLTest_LogError("Could not allocate working_directory - SDL_malloc() failed.");
- return 0;
- }
- SDL_memcpy(working_directory, file, path_length + 1);
- PathRemoveFileSpec(working_directory);
- if(SDL_strlen(working_directory) == 0)
- {
- SDL_free(working_directory);
- working_directory = NULL;
- }
- /* join the file path and the args string together */
- if(!args)
- args = "";
- args_length = SDL_strlen(args);
- command_line = (char*)SDL_malloc(path_length + args_length + 2);
- if(!command_line)
- {
- SDLTest_LogError("Could not allocate command_line - SDL_malloc() failed.");
- return 0;
- }
- SDL_memcpy(command_line, file, path_length);
- command_line[path_length] = ' ';
- SDL_memcpy(command_line + path_length + 1, args, args_length + 1);
- /* create the process */
- success = CreateProcess(NULL, command_line, NULL, NULL, FALSE,
- NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW,
- NULL, working_directory, &sui, &pinfo->pi);
- if(working_directory)
- {
- SDL_free(working_directory);
- working_directory = NULL;
- }
- SDL_free(command_line);
- if(!success)
- {
- LogLastError("CreateProcess() failed");
- return 0;
- }
- return 1;
- }
- int
- SDL_GetProcessExitStatus(SDL_ProcessInfo* pinfo, SDL_ProcessExitStatus* ps)
- {
- DWORD exit_status;
- BOOL success;
- if(!pinfo)
- {
- SDLTest_LogError("pinfo cannot be NULL");
- return 0;
- }
- if(!ps)
- {
- SDLTest_LogError("ps cannot be NULL");
- return 0;
- }
- /* get the exit code */
- success = GetExitCodeProcess(pinfo->pi.hProcess, &exit_status);
- if(!success)
- {
- LogLastError("GetExitCodeProcess() failed");
- return 0;
- }
- if(exit_status == STILL_ACTIVE)
- ps->exit_status = -1;
- else
- ps->exit_status = exit_status;
- ps->exit_success = 1;
- return 1;
- }
- int
- SDL_IsProcessRunning(SDL_ProcessInfo* pinfo)
- {
- DWORD exit_status;
- BOOL success;
- if(!pinfo)
- {
- SDLTest_LogError("pinfo cannot be NULL");
- return -1;
- }
- success = GetExitCodeProcess(pinfo->pi.hProcess, &exit_status);
- if(!success)
- {
- LogLastError("GetExitCodeProcess() failed");
- return -1;
- }
-
- if(exit_status == STILL_ACTIVE)
- return 1;
- return 0;
- }
- static BOOL CALLBACK
- CloseWindowCallback(HWND hwnd, LPARAM lparam)
- {
- DWORD pid;
- SDL_ProcessInfo* pinfo;
- pinfo = (SDL_ProcessInfo*)lparam;
- GetWindowThreadProcessId(hwnd, &pid);
- if(pid == pinfo->pi.dwProcessId)
- {
- DWORD_PTR result;
- if(!SendMessageTimeout(hwnd, WM_CLOSE, 0, 0, SMTO_BLOCK,
- 1000, &result))
- {
- if(GetLastError() != ERROR_TIMEOUT)
- {
- LogLastError("SendMessageTimeout() failed");
- return FALSE;
- }
- }
- }
- return TRUE;
- }
- int
- SDL_QuitProcess(SDL_ProcessInfo* pinfo, SDL_ProcessExitStatus* ps)
- {
- DWORD wait_result;
- if(!pinfo)
- {
- SDLTest_LogError("pinfo argument cannot be NULL");
- return 0;
- }
- if(!ps)
- {
- SDLTest_LogError("ps argument cannot be NULL");
- return 0;
- }
- /* enumerate through all the windows, trying to close each one */
- if(!EnumWindows(CloseWindowCallback, (LPARAM)pinfo))
- {
- SDLTest_LogError("EnumWindows() failed");
- return 0;
- }
- /* wait until the process terminates */
- wait_result = WaitForSingleObject(pinfo->pi.hProcess, 1000);
- if(wait_result == WAIT_FAILED)
- {
- LogLastError("WaitForSingleObject() failed");
- return 0;
- }
- if(wait_result != WAIT_OBJECT_0)
- {
- SDLTest_LogError("Process did not quit.");
- return 0;
- }
- /* get the exit code */
- if(!SDL_GetProcessExitStatus(pinfo, ps))
- {
- SDLTest_LogError("SDL_GetProcessExitStatus() failed");
- return 0;
- }
- return 1;
- }
- int
- SDL_KillProcess(SDL_ProcessInfo* pinfo, SDL_ProcessExitStatus* ps)
- {
- BOOL success;
- DWORD exit_status, wait_result;
- if(!pinfo)
- {
- SDLTest_LogError("pinfo argument cannot be NULL");
- return 0;
- }
- if(!ps)
- {
- SDLTest_LogError("ps argument cannot be NULL");
- return 0;
- }
- /* initiate termination of the process */
- success = TerminateProcess(pinfo->pi.hProcess, 0);
- if(!success)
- {
- LogLastError("TerminateProcess() failed");
- return 0;
- }
- /* wait until the process terminates */
- wait_result = WaitForSingleObject(pinfo->pi.hProcess, INFINITE);
- if(wait_result == WAIT_FAILED)
- {
- LogLastError("WaitForSingleObject() failed");
- return 0;
- }
- /* get the exit code */
- success = GetExitCodeProcess(pinfo->pi.hProcess, &exit_status);
- if(!success)
- {
- LogLastError("GetExitCodeProcess() failed");
- return 0;
- }
- ps->exit_status = exit_status;
- ps->exit_success = 1;
- return 1;
- }
- #endif
|