]> git.sur5r.net Git - bacula/bacula/commitdiff
ebl Fix #1110 about RunScript that can't execute a script with
authorEric Bollengier <eric@eb.homelinux.org>
Thu, 16 Oct 2008 11:31:13 +0000 (11:31 +0000)
committerEric Bollengier <eric@eb.homelinux.org>
Thu, 16 Oct 2008 11:31:13 +0000 (11:31 +0000)
     Unicode caracters in the path.

git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@7817 91ce42f0-d328-0410-95d8-f526ca767f89

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

index aeeb8fbc61f4ae14b469539b0b447a9ac0fb480b..43334a83c9a43fb08fd207437d2ad51833e3232f 100644 (file)
@@ -1846,6 +1846,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);
+
+   make_win32_path_UTF8_2_wchar(&cmdLine_wchar, cmdLine);
+   make_win32_path_UTF8_2_wchar(&comspec_wchar, comspec);
+
+   // Create the child process.
+   Dmsg2(150, "Calling CreateProcess(%s, %s, ...)\n", comspec, cmdLine);
+
+   // 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.
@@ -1855,43 +1946,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;
@@ -1900,43 +1977,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 b94922fa526348ba9cf1c84f10c3f0090ff18342..b6aef82d9fbc30c3469333e0da64d24655ca82ff 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");
       p_CreateDirectoryA = (t_CreateDirectoryA)GetProcAddress(hLib, "CreateDirectoryA");
index 471e0365d9c18253ce299f63af2bbaec3e49b3f6..ed77b6ec4608568a735eee8badf2807c13a41924 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 96bdcde97b32e6124ceaf3823f3479ba74bf28ab..7bcb0a228993871e0d87a1ed5c0fe1e4d178898e 100644 (file)
@@ -17,6 +17,9 @@ dbdriver
 remove reader/writer in FOPTS????
 
 General:
+16Oct08
+ebl  Fix #1110 about RunScript that can't execute a script with
+     Unicode caracters in the path.
 15Oct08
 kes  Apply tray-monitor patch from Bastian Friedrich to make it
      work with the new FD.