!system/!execute: XCopy.exe/ChCp.com (and other tools using ulib.dll?) does not work without a valid StdIn so we provide a empty pipe

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6601 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
anders_k 2015-09-03 11:06:18 +00:00
parent 87ad351f1b
commit 5c6dfdca9a
2 changed files with 17 additions and 10 deletions

View file

@ -10,6 +10,10 @@ Released on ? ?th, 201?
\b RequestExecutionLevel now defaults to \c{admin} \b RequestExecutionLevel now defaults to \c{admin}
\S2{} Minor Changes
\b !system and !execute now provide a empty StdIn pipe to work around bugs in some Windows utilities
\H{v3.0b2} 3.0 Beta 2 \H{v3.0b2} 3.0 Beta 2
Released on August 4th, 2015 Released on August 4th, 2015

View file

@ -859,26 +859,28 @@ int RunChildProcessRedirected(LPCWSTR cmdprefix, LPCWSTR cmdmain)
if (!cmd) return -1; if (!cmd) return -1;
_tcscpy(cmd, cmdprefix); _tcscpy(cmd, cmdprefix);
_tcscat(cmd, cmdmain); _tcscat(cmd, cmdmain);
SECURITY_DESCRIPTOR sd = {1, 0, SE_DACL_PRESENT, NULL, }; SECURITY_DESCRIPTOR sd = { 1, 0, SE_DACL_PRESENT, NULL, };
SECURITY_ATTRIBUTES sa = {sizeof(sa), &sd, true}; SECURITY_ATTRIBUTES sa = { sizeof(sa), &sd, TRUE };
const UINT orgwinconcp = GetConsoleCP(), orgwinconoutcp = GetConsoleOutputCP(); const UINT orgwinconcp = GetConsoleCP(), orgwinconoutcp = GetConsoleOutputCP();
if (orgwinconoutcp == oemcp) cp = oemcp, mbtwcf = 0; // Bug #1092: Batch files not a fan of UTF-8 if (orgwinconoutcp == oemcp) cp = oemcp, mbtwcf = 0; // Bug #1092: Batch files not a fan of UTF-8
HANDLE hPipRd, hPipWr; HANDLE hSIRd, hSIWr, hSORd, hSOWr;
PROCESS_INFORMATION pi; PROCESS_INFORMATION pi;
BOOL ok = CreatePipe(&hPipRd, &hPipWr, &sa, 0); if (!CreatePipe(&hSIRd, &hSIWr, &sa, 0)) // XCopy.exe does not work without a valid StdIn!
hSIRd = hSIWr = INVALID_HANDLE_VALUE;
BOOL ok = CreatePipe(&hSORd, &hSOWr, &sa, 0);
if (!ok) if (!ok)
hPipRd = 0, hPipWr = 0; hSORd = hSOWr = 0;
else else
{ {
STARTUPINFO si = {sizeof(si)}; STARTUPINFO si = {sizeof(si)};
si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW; si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE; si.wShowWindow = SW_HIDE;
si.hStdOutput = si.hStdError = hPipWr; si.hStdOutput = si.hStdError = hSOWr;
si.hStdInput = INVALID_HANDLE_VALUE; si.hStdInput = hSIRd;
errno = ECHILD; errno = ECHILD;
SetConsoleOutputCP(cp); SetConsoleOutputCP(cp);
ok = CreateProcess(0, cmd, 0, 0, TRUE, 0, 0, 0, &si, &pi); ok = CreateProcess(0, cmd, 0, 0, TRUE, 0, 0, 0, &si, &pi);
CloseHandle(hPipWr); // We want ERROR_BROKEN_PIPE when the child is done CloseHandle(hSOWr); // We want ERROR_BROKEN_PIPE when the child is done
} }
free(cmd); free(cmd);
DWORD childec = -1; DWORD childec = -1;
@ -890,7 +892,7 @@ int RunChildProcessRedirected(LPCWSTR cmdprefix, LPCWSTR cmdmain)
WCHAR wbuf[100], wchbuf[2+1]; // A surrogate pair + \0 WCHAR wbuf[100], wchbuf[2+1]; // A surrogate pair + \0
for(;;) for(;;)
{ {
BOOL okr = ReadFile(hPipRd, iobuf+cbOfs, sizeof(iobuf)-cbOfs, &cbRead, 0); BOOL okr = ReadFile(hSORd, iobuf+cbOfs, sizeof(iobuf)-cbOfs, &cbRead, 0);
cbRead += cbOfs, cbOfs = 0; cbRead += cbOfs, cbOfs = 0;
unsigned char cbTrail, cch; unsigned char cbTrail, cch;
for(DWORD i = 0; i < cbRead;) for(DWORD i = 0; i < cbRead;)
@ -951,7 +953,8 @@ switchcp: cp = orgwinconoutcp, mbtwcf = 0, utf8 = false;
CloseHandle(pi.hProcess); CloseHandle(pi.hProcess);
} }
SetConsoleCP(orgwinconcp), SetConsoleOutputCP(orgwinconoutcp); SetConsoleCP(orgwinconcp), SetConsoleOutputCP(orgwinconoutcp);
CloseHandle(hPipRd); CloseHandle(hSIRd), CloseHandle(hSIWr);
CloseHandle(hSORd);
return childec; return childec;
} }
#else #else