Bug 455381 - WinCE XPCOM Explicit Unicode API Calls, Wide Char CheckVersion Function nsCommonProcess changes. relanding after backout. r=bsmedberg
authorBrad Lassey <blassey@mozilla.com>
Thu, 11 Dec 2008 11:50:24 -0800
changeset 22692 fd31061170dc0e597dcf67a92fedd2d1ac06efbd
parent 22691 8e6fb32f0da96feb6f6852b67b6c390fb1156749
child 22693 9e5b08f9e9d96d15872c7b8c60312bb579be4115
push idunknown
push userunknown
push dateunknown
reviewersbsmedberg
bugs455381
milestone1.9.2a1pre
Bug 455381 - WinCE XPCOM Explicit Unicode API Calls, Wide Char CheckVersion Function nsCommonProcess changes. relanding after backout. r=bsmedberg
xpcom/threads/nsProcessCommon.cpp
--- 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 `wideCmdLine` must be PR_Freed by the 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 ) {