]> git.sur5r.net Git - bacula/bacula/commitdiff
ebl Apply 2.4.3-win32-runscript-unicode-path.patch for #1110
authorEric Bollengier <eric@eb.homelinux.org>
Thu, 20 Nov 2008 09:49:54 +0000 (09:49 +0000)
committerEric Bollengier <eric@eb.homelinux.org>
Thu, 20 Nov 2008 09:49:54 +0000 (09:49 +0000)
     about a problem when executing a program with Unicode path.

git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/branches/Branch-2.4@8068 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/Patchnotes-2.4
bacula/src/win32/compat/compat.cpp
bacula/src/win32/compat/winapi.c
bacula/src/win32/winapi.h
bacula/technotes-2.4

index aefda16a414d05f92fff57a30f0548625d3c141d..ce26d190598eda75d5324b8f6972266804a69dbe 100644 (file)
@@ -7,6 +7,7 @@ Patches Released to Source Forge:
 Patches Committed:
 20Nov08
 2.4.3-unique-inchanger.patch
+2.4.3-win32-runscript-unicode-path.patch
 18Nov08
 2.4.3-purge-bug.patch
 2.4.3-getmsg.patch
@@ -60,7 +61,3 @@ kes  This patch should fix the bug reported on the bacula-users list where
 ebl  This patch corrects a problem when removing a volume from
      an autochanger and the slot is still empty when running
      update slots command. #1175
-
-2.4.3-win32-runscript-unicode-path.patch
-ebl  This patch fix #1110 about a problem when executing a program with
-     Unicode path.
index a3171c3c308d404c3478d01da0217b70ca6bd1fd..c31e8465ab6a1fca6a9c4f7f060b086c7353968b 100644 (file)
@@ -1806,6 +1806,97 @@ GetApplicationName(const char *cmdline, char **pexe, const char **pargs)
    return true;
 }
 
+/**
+ * Create the process with UTF8 API
+ */
+static BOOL
+CreateChildProcessW(const char *comspec, const char *cmdLine,
+                    PROCESS_INFORMATION *hProcInfo,
+                    HANDLE in, HANDLE out, HANDLE err)
+{
+   STARTUPINFOW siStartInfo;
+   BOOL bFuncRetn = FALSE;
+
+   // Set up members of the STARTUPINFO structure.
+   ZeroMemory( &siStartInfo, sizeof(siStartInfo) );
+   siStartInfo.cb = sizeof(siStartInfo);
+   // setup new process to use supplied handles for stdin,stdout,stderr
+
+   siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
+   siStartInfo.wShowWindow = SW_SHOWMINNOACTIVE;
+
+   siStartInfo.hStdInput = in;
+   siStartInfo.hStdOutput = out;
+   siStartInfo.hStdError = err;
+   
+   // Convert argument to WCHAR
+   POOLMEM *cmdLine_wchar = get_pool_memory(PM_FNAME);
+   POOLMEM *comspec_wchar = get_pool_memory(PM_FNAME);
+
+   UTF8_2_wchar(&cmdLine_wchar, cmdLine);
+   UTF8_2_wchar(&comspec_wchar, comspec);
+
+   // Create the child process.
+   Dmsg2(150, "Calling CreateProcess(%s, %s, ...)\n", comspec_wchar, cmdLine_wchar);
+
+   // try to execute program
+   bFuncRetn = p_CreateProcessW((WCHAR*)comspec_wchar,
+                                (WCHAR*)cmdLine_wchar,// command line
+                                NULL,      // process security attributes
+                                NULL,      // primary thread security attributes
+                                TRUE,      // handles are inherited
+                                0,         // creation flags
+                                NULL,      // use parent's environment
+                                NULL,      // use parent's current directory
+                                &siStartInfo,  // STARTUPINFO pointer
+                                hProcInfo);   // receives PROCESS_INFORMATION
+
+   free_pool_memory(cmdLine_wchar);
+   free_pool_memory(comspec_wchar);
+
+   return bFuncRetn;
+}
+
+
+/**
+ * Create the process with ANSI API
+ */
+static BOOL
+CreateChildProcessA(const char *comspec, char *cmdLine,
+                    PROCESS_INFORMATION *hProcInfo,
+                    HANDLE in, HANDLE out, HANDLE err)
+{
+   STARTUPINFOA siStartInfo;
+   BOOL bFuncRetn = FALSE;
+
+   // Set up members of the STARTUPINFO structure.
+   ZeroMemory( &siStartInfo, sizeof(siStartInfo) );
+   siStartInfo.cb = sizeof(siStartInfo);
+   // setup new process to use supplied handles for stdin,stdout,stderr
+   siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
+   siStartInfo.wShowWindow = SW_SHOWMINNOACTIVE;
+
+   siStartInfo.hStdInput = in;
+   siStartInfo.hStdOutput = out;
+   siStartInfo.hStdError = err;
+
+   // Create the child process.
+   Dmsg2(150, "Calling CreateProcess(%s, %s, ...)\n", comspec, cmdLine);
+
+   // try to execute program
+   bFuncRetn = p_CreateProcessA(comspec,
+                                cmdLine,  // command line
+                                NULL,     // process security attributes
+                                NULL,     // primary thread security attributes
+                                TRUE,     // handles are inherited
+                                0,        // creation flags
+                                NULL,     // use parent's environment
+                                NULL,     // use parent's current directory
+                                &siStartInfo,// STARTUPINFO pointer
+                                hProcInfo);// receives PROCESS_INFORMATION
+   return bFuncRetn;
+}
+
 /**
  * OK, so it would seem CreateProcess only handles true executables:
  * .com or .exe files.  So grab $COMSPEC value and pass command line to it.
@@ -1815,43 +1906,29 @@ CreateChildProcess(const char *cmdline, HANDLE in, HANDLE out, HANDLE err)
 {
    static const char *comspec = NULL;
    PROCESS_INFORMATION piProcInfo;
-   STARTUPINFOA siStartInfo;
    BOOL bFuncRetn = FALSE;
 
-   if (comspec == NULL) {
+   if (!p_CreateProcessA || !p_CreateProcessW)
+      return INVALID_HANDLE_VALUE;
+
+   if (comspec == NULL) 
       comspec = getenv("COMSPEC");
-   }
    if (comspec == NULL) // should never happen
       return INVALID_HANDLE_VALUE;
 
    // Set up members of the PROCESS_INFORMATION structure.
    ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
 
-   // Set up members of the STARTUPINFO structure.
-
-   ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
-   siStartInfo.cb = sizeof(STARTUPINFO);
-   // setup new process to use supplied handles for stdin,stdout,stderr
    // if supplied handles are not used the send a copy of our STD_HANDLE
    // as appropriate
-   siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
-   siStartInfo.wShowWindow = SW_SHOWMINNOACTIVE;
-
-   if (in != INVALID_HANDLE_VALUE)
-      siStartInfo.hStdInput = in;
-   else
-      siStartInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
+   if (in == INVALID_HANDLE_VALUE)
+      in = GetStdHandle(STD_INPUT_HANDLE);
 
-   if (out != INVALID_HANDLE_VALUE)
-      siStartInfo.hStdOutput = out;
-   else
-      siStartInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
-   if (err != INVALID_HANDLE_VALUE)
-      siStartInfo.hStdError = err;
-   else
-      siStartInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
+   if (out == INVALID_HANDLE_VALUE)
+      out = GetStdHandle(STD_OUTPUT_HANDLE);
 
-   // Create the child process.
+   if (err == INVALID_HANDLE_VALUE)
+      err = GetStdHandle(STD_ERROR_HANDLE);
 
    char *exeFile;
    const char *argStart;
@@ -1860,43 +1937,32 @@ CreateChildProcess(const char *cmdline, HANDLE in, HANDLE out, HANDLE err)
       return INVALID_HANDLE_VALUE;
    }
 
-   int cmdLen = strlen(comspec) + 4 + strlen(exeFile) + strlen(argStart) + 1;
-
-   char *cmdLine = (char *)alloca(cmdLen);
-
-   snprintf(cmdLine, cmdLen, "%s /c %s%s", comspec, exeFile, argStart);
+   POOL_MEM cmdLine(PM_FNAME);
+   Mmsg(cmdLine, "%s /c %s%s", comspec, exeFile, argStart);
 
    free(exeFile);
 
-   Dmsg2(150, "Calling CreateProcess(%s, %s, ...)\n", comspec, cmdLine);
-
-   // try to execute program
-   bFuncRetn = CreateProcessA(comspec,
-                              cmdLine,       // command line
-                              NULL,          // process security attributes
-                              NULL,          // primary thread security attributes
-                              TRUE,          // handles are inherited
-                              0,             // creation flags
-                              NULL,          // use parent's environment
-                              NULL,          // use parent's current directory
-                              &siStartInfo,  // STARTUPINFO pointer
-                              &piProcInfo);  // receives PROCESS_INFORMATION
+   if (p_CreateProcessW && p_MultiByteToWideChar) {
+      bFuncRetn = CreateChildProcessW(comspec, cmdLine.c_str(), &piProcInfo,
+                                      in, out, err);
+   } else {
+      bFuncRetn = CreateChildProcessA(comspec, cmdLine.c_str(), &piProcInfo,
+                                      in, out, err);
+   }
 
    if (bFuncRetn == 0) {
       ErrorExit("CreateProcess failed\n");
       const char *err = errorString();
-      Dmsg3(99, "CreateProcess(%s, %s, ...)=%s\n", comspec, cmdLine, err);
+      Dmsg3(99, "CreateProcess(%s, %s, ...)=%s\n",comspec,cmdLine.c_str(),err);
       LocalFree((void *)err);
       return INVALID_HANDLE_VALUE;
    }
    // we don't need a handle on the process primary thread so we close
    // this now.
    CloseHandle(piProcInfo.hThread);
-
    return piProcInfo.hProcess;
 }
 
-
 void
 ErrorExit (LPCSTR lpszMessage)
 {
index ed7548338808591d6a84aa9f964c6e135320f7cd..ce56e3f185ec0cfad6bac767350136bb631b0771 100644 (file)
@@ -88,6 +88,9 @@ t_GetVolumeNameForVolumeMountPointW p_GetVolumeNameForVolumeMountPointW = NULL;
 
 t_SHGetFolderPath       p_SHGetFolderPath = NULL;
 
+t_CreateProcessA        p_CreateProcessA = NULL;
+t_CreateProcessW        p_CreateProcessW = NULL;
+
 void 
 InitWinAPIWrapper() 
 {
@@ -104,6 +107,12 @@ InitWinAPIWrapper()
 
    HMODULE hLib = LoadLibraryA("KERNEL32.DLL");
    if (hLib) {
+      /* create process calls */
+      p_CreateProcessA = (t_CreateProcessA)
+         GetProcAddress(hLib, "CreateProcessA");
+      p_CreateProcessW = (t_CreateProcessW)
+         GetProcAddress(hLib, "CreateProcessW");
+
       /* create file calls */
       p_CreateFileA = (t_CreateFileA)
           GetProcAddress(hLib, "CreateFileA");
index 07b46e738b25dc4c5a1fc5bd66b14d56b886c64c..847d2c0a1329c537fccb33e5d10a989f93aa4ed3 100644 (file)
@@ -138,6 +138,32 @@ typedef BOOL (WINAPI * t_GetVolumeNameForVolumeMountPointW) (LPCWSTR, LPWSTR, DW
 
 typedef BOOL (WINAPI * t_AttachConsole) (DWORD);
 
+typedef BOOL (WINAPI *t_CreateProcessA) (
+   LPCSTR,
+   LPSTR,
+   LPSECURITY_ATTRIBUTES,
+   LPSECURITY_ATTRIBUTES,
+   BOOL,
+   DWORD,
+   PVOID,
+   LPCSTR,
+   LPSTARTUPINFOA,
+   LPPROCESS_INFORMATION);
+typedef BOOL (WINAPI *t_CreateProcessW) (
+   LPCWSTR,
+   LPWSTR,
+   LPSECURITY_ATTRIBUTES,
+   LPSECURITY_ATTRIBUTES,
+   BOOL,
+   DWORD,
+   PVOID,
+   LPCWSTR,
+   LPSTARTUPINFOW,
+   LPPROCESS_INFORMATION);
+
+extern t_CreateProcessA DLL_IMP_EXP p_CreateProcessA;
+extern t_CreateProcessW DLL_IMP_EXP p_CreateProcessW;
+
 extern t_GetFileAttributesA   DLL_IMP_EXP p_GetFileAttributesA;
 extern t_GetFileAttributesW   DLL_IMP_EXP p_GetFileAttributesW;
 
index 102b2dbb90fadb840c895691d1c27a8ec0babadb..4730371a347e47c15f0916416cfbc96f67943042 100644 (file)
@@ -2,6 +2,8 @@
 
 General:
 20Nov08
+ebl  Apply 2.4.3-win32-runscript-unicode-path.patch for #1110 
+     about a problem when executing a program with Unicode path.
 ebl  Apply 2.4.3-unique-inchanger.patch fix for #1175 about bad slot
      number if the volume is not in autochanger.
 18Nov08