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.
{
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;
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)
{