Search
j0ke.net Open Build Service
>
Projects
>
server:backup
>
bacula
> 2.4.3-win32-runscript-unicode-path.patch
Sign Up
|
Log In
Username
Password
Cancel
Overview
Repositories
Revisions
Requests
Users
Advanced
Attributes
Meta
File 2.4.3-win32-runscript-unicode-path.patch of Package bacula (Revision 2)
Currently displaying revision
2
,
show latest
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;