--- a/xpcom/threads/nsProcessCommon.cpp
+++ b/xpcom/threads/nsProcessCommon.cpp
@@ -101,20 +101,21 @@ nsProcess::Init(nsIFile* executable)
#endif
rv = mExecutable->GetNativePath(mTargetPath);
return rv;
}
#if defined(XP_WIN)
-static int assembleCmdLine(char *const *argv, char **cmdLine)
+// out param must be freed by caller
+static int assembleCmdLine(char *const *argv, PRUnichar **wideCmdLine)
{
char *const *arg;
- char *p, *q;
+ char *p, *q, **cmdLine;
int cmdLineSize;
int numBackslashes;
int i;
int argNeedQuotes;
/*
* Find out how large the command line buffer should be.
*/
@@ -126,17 +127,17 @@ static int assembleCmdLine(char *const *
* may double. If we quote an argument, that needs two ".
* Finally, we need a space between arguments, and
* a null byte at the end of command line.
*/
cmdLineSize += 2 * strlen(*arg) /* \ and " need to be escaped */
+ 2 /* we quote every argument */
+ 1; /* space in between, or final null */
}
- p = *cmdLine = (char *) PR_MALLOC(cmdLineSize);
+ p = *cmdLine = (char *) PR_MALLOC(cmdLineSize*sizeof(char));
if (p == NULL) {
return -1;
}
for (arg = argv; *arg; arg++) {
/* Add a space to separates the arguments */
if (arg != argv) {
*p++ = ' ';
@@ -200,16 +201,20 @@ static int assembleCmdLine(char *const *
}
}
if (argNeedQuotes) {
*p++ = '"';
}
}
*p = '\0';
+ PRInt32 numChars = MultiByteToWideChar(CP_ACP, 0, *cmdLine, -1, NULL, 0);
+ *wideCmdLine = (PRUnichar *) PR_MALLOC(numChars*sizeof(PRUnichar));
+ MultiByteToWideChar(CP_ACP, 0, *cmdLine, -1, *wideCmdLine, numChars);
+ PR_Free(cmdLine);
return 0;
}
#endif
// XXXldb |args| has the wrong const-ness
NS_IMETHODIMP
nsProcess::Run(PRBool blocking, const char **args, PRUint32 count,
PRUint32 *pid)
@@ -232,49 +237,49 @@ nsProcess::Run(PRBool blocking, const ch
my_argv[i+1] = const_cast<char*>(args[i]);
}
// we need to set argv[0] to the program name.
my_argv[0] = mTargetPath.BeginWriting();
// null terminate the array
my_argv[count+1] = NULL;
#if defined(XP_WIN) && !defined (WINCE) /* wince uses nspr */
- STARTUPINFO startupInfo;
+ STARTUPINFOW startupInfo;
PROCESS_INFORMATION procInfo;
BOOL retVal;
- char *cmdLine;
+ PRUnichar *cmdLine;
if (assembleCmdLine(my_argv, &cmdLine) == -1) {
nsMemory::Free(my_argv);
return NS_ERROR_FILE_EXECUTION_FAILED;
}
ZeroMemory(&startupInfo, sizeof(startupInfo));
startupInfo.cb = sizeof(startupInfo);
/* The CREATE_NO_WINDOW flag is important to prevent console
* windows from appearing. This makes behavior the same on all
* platforms. This won't work on win9x, however. The flag will
* not have any effect on non-console applications.
*/
- retVal = CreateProcess(NULL,
- // const_cast<char*>(mTargetPath.get()),
- cmdLine,
- NULL, /* security attributes for the new
- * process */
- NULL, /* security attributes for the primary
- * thread in the new process */
- FALSE, /* inherit handles */
- CREATE_NO_WINDOW, /* creation flags */
- NULL, /* env */
- NULL, /* current drive and directory */
- &startupInfo,
- &procInfo
- );
+ retVal = CreateProcessW(NULL,
+ // const_cast<char*>(mTargetPath.get()),
+ cmdLine,
+ NULL, /* security attributes for the new
+ * process */
+ NULL, /* security attributes for the primary
+ * thread in the new process */
+ FALSE, /* inherit handles */
+ CREATE_NO_WINDOW, /* creation flags */
+ NULL, /* env */
+ NULL, /* current drive and directory */
+ &startupInfo,
+ &procInfo
+ );
PR_Free( cmdLine );
if (blocking) {
// if success, wait for process termination. the early returns and such
// are a bit ugly but preserving the logic of the nspr code I copied to
// minimize our risk abit.
if ( retVal == TRUE ) {