foxygit / doom Log in
commit f9c922149717242958f065c8718e7e7586c165a5
Author:     Simon Howard <fraggle@gmail.com>
AuthorDate: Sat Nov 21 00:24:59 2009 +0000
Commit:     Simon Howard <fraggle@gmail.com>
CommitDate: Sat Nov 21 00:24:59 2009 +0000

    Fix crash with chocolate-setup under Windows (thanks Janizdreg).

    Subversion-branch: /trunk/chocolate-doom
    Subversion-revision: 1731
---
 setup/execute.c | 80 ++++++++++++++++++++++++---------------------------------
 1 file changed, 33 insertions(+), 47 deletions(-)

diff --git a/setup/execute.c b/setup/execute.c
index 9672a334..fb9885fa 100644
--- a/setup/execute.c
+++ b/setup/execute.c
@@ -172,60 +172,47 @@ static unsigned int WaitForProcessExit(HANDLE subprocess)
     }
 }

-static wchar_t *GetFullExePath(const char *program)
+static void ConcatWCString(wchar_t *buf, const char *value)
+{
+    MultiByteToWideChar(CP_OEMCP, 0,
+                        value, strlen(value) + 1,
+                        buf + wcslen(buf), strlen(value) + 1);
+}
+
+// Build the command line string, a wide character string of the form:
+//
+// "program" "arg"
+
+static wchar_t *BuildCommandLine(const char *program, const char *arg)
 {
     wchar_t *result;
-    unsigned int path_len;
     char *sep;

-    // Find the full path to the EXE to execute, by taking the path
-    // to this program and concatenating the EXE name:
+    result = calloc(strlen(myargv[0]) + strlen(program) + strlen(arg) + 6,
+                    sizeof(wchar_t));
+
+    wcscpy(result, L"\"");

     sep = strrchr(myargv[0], DIR_SEPARATOR);

-    if (sep == NULL)
-    {
-        path_len = 0;
-        result = calloc(strlen(program) + 1, sizeof(wchar_t));
-    }
-    else
+    if (sep != NULL)
     {
-        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;
-}
+        ConcatWCString(result, myargv[0]);

-// Convert command line argument to wchar_t string and add surrounding
-// "" quotes:
+        // Cut off the string after the last directory separator,
+        // before appending the actual program.

-static wchar_t *GetPaddedWideArg(const char *arg)
-{
-    wchar_t *result;
-    unsigned int len = strlen(arg);
+        result[sep - myargv[0] + 2] = '\0';
+
+    }

-    // Convert the command line arg to a wide char string:
+    ConcatWCString(result, program);

-    result = calloc(len + 3, sizeof(wchar_t));
-    MultiByteToWideChar(CP_OEMCP, 0,
-                        arg, len + 1,
-                        result + 1, len + 1);
+    wcscat(result, L"\" \"");

-    // Surrounding quotes:
+    ConcatWCString(result, arg);

-    result[0] = '"';
-    result[len + 1] = '"';
-    result[len + 2] = 0;
+    wcscat(result, L"\"");

     return result;
 }
@@ -234,18 +221,18 @@ static int ExecuteCommand(const char *program, const char *arg)
 {
     STARTUPINFOW startup_info;
     PROCESS_INFORMATION proc_info;
-    wchar_t *exe_path;
-    wchar_t *warg;
+    wchar_t *command;
     int result = 0;

-    exe_path = GetFullExePath(program);
-    warg = GetPaddedWideArg(arg);
+    command = BuildCommandLine(program, arg);

     // Invoke the program:

     memset(&proc_info, 0, sizeof(proc_info));
+    memset(&startup_info, 0, sizeof(startup_info));
+    startup_info.cb = sizeof(startup_info);

-    if (!CreateProcessW(exe_path, warg,
+    if (!CreateProcessW(NULL, command,
                         NULL, NULL, FALSE, 0, NULL, NULL,
                         &startup_info, &proc_info))
     {
@@ -261,8 +248,7 @@ static int ExecuteCommand(const char *program, const char *arg)
         CloseHandle(proc_info.hThread);
     }

-    free(exe_path);
-    free(warg);
+    free(command);

     return result;
 }