]> git.sur5r.net Git - bacula/bacula/commitdiff
ebl Fix patch to handle unicode in external command
authorEric Bollengier <eric@eb.homelinux.org>
Thu, 16 Oct 2008 18:21:12 +0000 (18:21 +0000)
committerEric Bollengier <eric@eb.homelinux.org>
Thu, 16 Oct 2008 18:21:12 +0000 (18:21 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/branches/Branch-2.4@7820 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/patches/2.4.3-win32-runscript-unicode-path.patch [new file with mode: 0644]

diff --git a/bacula/patches/2.4.3-win32-runscript-unicode-path.patch b/bacula/patches/2.4.3-win32-runscript-unicode-path.patch
new file mode 100644 (file)
index 0000000..b4b0674
--- /dev/null
@@ -0,0 +1,289 @@
+
+ This patch fix #1110 about a problem when executing a program with
+ Unicode path.
+
+ It can be applied to 2.4.3 (and previous versions) with:
+
+  cd <bacula-source>
+  patch -p0 <2.4.3-win32-runscript-unicode-path.patch
+  ./configure <your-options>
+  make
+  ...
+  make install
+
+
+Index: src/win32/compat/compat.cpp
+===================================================================
+--- src/win32/compat/compat.cpp        (révision 7772)
++++ src/win32/compat/compat.cpp        (copie de travail)
+@@ -1807,6 +1807,97 @@
+ }
+ /**
++ * 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,44 +1906,30 @@
+ {
+    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)
++      in = GetStdHandle(STD_INPUT_HANDLE);
+-   if (in != INVALID_HANDLE_VALUE)
+-      siStartInfo.hStdInput = in;
+-   else
+-      siStartInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
++   if (out == INVALID_HANDLE_VALUE)
++      out = GetStdHandle(STD_OUTPUT_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 (err == INVALID_HANDLE_VALUE)
++      err = GetStdHandle(STD_ERROR_HANDLE);
+-   // Create the child process.
+-
+    char *exeFile;
+    const char *argStart;
+@@ -1860,43 +1937,32 @@
+       return INVALID_HANDLE_VALUE;
+    }
+-   int cmdLen = strlen(comspec) + 4 + strlen(exeFile) + strlen(argStart) + 1;
++   POOL_MEM cmdLine(PM_FNAME);
++   Mmsg(cmdLine, "%s /c %s%s", comspec, exeFile, argStart);
+-   char *cmdLine = (char *)alloca(cmdLen);
+-
+-   snprintf(cmdLine, cmdLen, "%s /c %s%s", comspec, exeFile, argStart);
+-
+    free(exeFile);
+-   Dmsg2(150, "Calling CreateProcess(%s, %s, ...)\n", comspec, cmdLine);
++   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);
++   }
+-   // 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 (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: src/win32/compat/winapi.c
+===================================================================
+--- src/win32/compat/winapi.c  (révision 7772)
++++ src/win32/compat/winapi.c  (copie de travail)
+@@ -88,6 +88,9 @@
+ t_SHGetFolderPath       p_SHGetFolderPath = NULL;
++t_CreateProcessA        p_CreateProcessA = NULL;
++t_CreateProcessW        p_CreateProcessW = NULL;
++
+ void 
+ InitWinAPIWrapper() 
+ {
+@@ -104,6 +107,12 @@
+    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: src/win32/winapi.h
+===================================================================
+--- src/win32/winapi.h (révision 7772)
++++ src/win32/winapi.h (copie de travail)
+@@ -138,6 +138,32 @@
+ 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;