ref: e806e6a6497d2e282ff66f78e68cc3a6214a7921
parent: 8777a9672ecaf308d974a9c36f6edab6ee65bf4b
author: Simon Howard <fraggle@gmail.com>
date: Tue Jul 7 15:38:00 EDT 2009
Fix launching of the game from the setup tool in Windows CE. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 1608
--- a/setup/execute.c
+++ b/setup/execute.c
@@ -29,11 +29,13 @@
#include <sys/types.h>
#if defined(_WIN32_WCE)
-
#include "libc_wince.h"
+#endif
-#elif defined(_WIN32)
+#ifdef _WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
#include <process.h>
#else
@@ -79,7 +81,6 @@
char *tempdir;
#ifdef _WIN32
-
// Check the TEMP environment variable to find the location.
tempdir = getenv("TEMP");
@@ -147,28 +148,131 @@
fprintf(context->stream, "\n");
}
-#if defined(_WIN32_WCE)
+#if defined(_WIN32)
-static int ExecuteCommand(const char **argv)
+// Wait for the specified process to exit. Returns the exit code.
+
+static unsigned int WaitForProcessExit(HANDLE subprocess)
{
- // Windows CE version.
- // TODO
- return 0;
+ DWORD exit_code;
+
+ for (;;)
+ {
+ WaitForSingleObject(subprocess, INFINITE);
+
+ if (!GetExitCodeProcess(subprocess, &exit_code))
+ {
+ return -1;
+ }
+
+ if (exit_code != STILL_ACTIVE)
+ {
+ return exit_code;
+ }
+ }
}
-#elif defined(_WIN32)
+static wchar_t *GetFullExePath(const char *program)
+{
+ wchar_t *result;
+ unsigned int path_len;
+ char *sep;
-static int ExecuteCommand(const char **argv)
+ // Find the full path to the EXE to execute, by taking the path
+ // to this program and concatenating the EXE name:
+
+ sep = strrchr(myargv[0], DIR_SEPARATOR);
+
+ if (sep == NULL)
+ {
+ path_len = 0;
+ result = calloc(strlen(program) + 1, sizeof(wchar_t));
+ }
+ else
+ {
+ path_len = sep - myargv[0] + 1;
+
+ result = calloc(path_len + strlen(program) + 1,
+ sizeof(wchar_t));
+ MultiByteToWideChar(CP_OEMCP, 0,
+ myargv[0], path_len,
+ result, path_len);
+ }
+
+ MultiByteToWideChar(CP_OEMCP, 0,
+ program, strlen(program) + 1,
+ result + path_len, strlen(program) + 1);
+
+ return result;
+}
+
+// Convert command line argument to wchar_t string and add surrounding
+// "" quotes:
+
+static wchar_t *GetPaddedWideArg(const char *arg)
{
- return _spawnv(_P_WAIT, argv[0], argv);
+ wchar_t *result;
+ unsigned int len = strlen(arg);
+
+ // Convert the command line arg to a wide char string:
+
+ result = calloc(len + 3, sizeof(wchar_t));
+ MultiByteToWideChar(CP_OEMCP, 0,
+ arg, len + 1,
+ result + 1, len + 1);
+
+ // Surrounding quotes:
+
+ result[0] = '"';
+ result[len + 1] = '"';
+ result[len + 2] = 0;
+
+ return result;
}
+static int ExecuteCommand(const char *program, const char *arg)
+{
+ PROCESS_INFORMATION proc_info;
+ wchar_t *exe_path;
+ wchar_t *warg;
+ int result = 0;
+
+ exe_path = GetFullExePath(program);
+ warg = GetPaddedWideArg(arg);
+
+ // Invoke the program:
+
+ memset(&proc_info, 0, sizeof(proc_info));
+
+ if (!CreateProcessW(exe_path, warg,
+ NULL, NULL, FALSE, 0, NULL, NULL, NULL,
+ &proc_info))
+ {
+ result = -1;
+ }
+ else
+ {
+ // Wait for the process to finish, and save the exit code.
+
+ result = WaitForProcessExit(proc_info.hProcess);
+
+ CloseHandle(proc_info.hProcess);
+ CloseHandle(proc_info.hThread);
+ }
+
+ free(exe_path);
+ free(warg);
+
+ return result;
+}
+
#else
-static int ExecuteCommand(const char **argv)
+static int ExecuteCommand(const char *program, const char *arg)
{
pid_t childpid;
int result;
+ const char *argv[] = { program, arg, NULL };
childpid = fork();
@@ -202,7 +306,6 @@
int ExecuteDoom(execute_context_t *context)
{
- const char *argv[3];
char *response_file_arg;
int result;
@@ -213,17 +316,13 @@
response_file_arg = malloc(strlen(context->response_file) + 2);
sprintf(response_file_arg, "@%s", context->response_file);
- argv[0] = DOOM_BINARY;
- argv[1] = response_file_arg;
- argv[2] = NULL;
-
// Run Doom
- result = ExecuteCommand(argv);
+ result = ExecuteCommand(DOOM_BINARY, response_file_arg);
free(response_file_arg);
-
- // Destroy context
+
+ // Destroy context
remove(context->response_file);
free(context->response_file);
free(context);
@@ -259,8 +358,8 @@
exec = NewExecuteContext();
AddCmdLineParameter(exec, "-testcontrols");
- AddCmdLineParameter(exec, "-config %s", main_cfg);
- AddCmdLineParameter(exec, "-extraconfig %s", extra_cfg);
+ AddCmdLineParameter(exec, "-config \"%s\"", main_cfg);
+ AddCmdLineParameter(exec, "-extraconfig \"%s\"", extra_cfg);
ExecuteDoom(exec);
TXT_CloseWindow(testwindow);