You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mt...@apache.org on 2010/01/26 17:23:13 UTC
svn commit: r903304 -
/commons/sandbox/runtime/trunk/src/main/native/support/win32/wsuexec.c
Author: mturk
Date: Tue Jan 26 16:23:13 2010
New Revision: 903304
URL: http://svn.apache.org/viewvc?rev=903304&view=rev
Log:
Stage 3 of wsuexec
Modified:
commons/sandbox/runtime/trunk/src/main/native/support/win32/wsuexec.c
Modified: commons/sandbox/runtime/trunk/src/main/native/support/win32/wsuexec.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/support/win32/wsuexec.c?rev=903304&r1=903303&r2=903304&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/support/win32/wsuexec.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/support/win32/wsuexec.c Tue Jan 26 16:23:13 2010
@@ -40,11 +40,25 @@
* Begin of argument processing code
* ---------------------------------------------------------------------
*/
-#define ERRFAILED 0xE0000000
-#define ERRSUCESS 0x20000000
+#define ERRFAILED 0x80000000
+#define ERRSUCESS 0x40000000
+#define WIFPIDMASK 0x0FFFFFFF
+#define WIFERRMASK 0x0FFFFFFF
+#define WIFSTATMASK 0xC0000000
+
+#define WIFEXITED(S) (((S) & WIFPIDMASK) == (S))
+#define WIFSIGNALED(S) ((S) & ERRFAILED)
+#define WEXITSTATUS(S) ((((S) & ~WIFERRMASK) << 2) == WIFSTATMASK ? \
+ ((S) | ~WIFERRMASK) : ((((S) & ~WIFERRMASK) << 2) | (S) & WIFERRMASK))
+#define WEXITERROR(S) ((((S) & ~WIFERRMASK) << 2) | ((S) & WIFERRMASK))
+#define WEXITPID(S) ((S) & WIFPIDMASK)
+
+#define RWEXITPID(S) ((S) & WIFPIDMASK)
+#define RWEXITSTATUS(S) ((((S) >> 2) & ~WIFERRMASK) | ((S) & WIFERRMASK) | ERRSUCESS)
+#define RWEXITERROR(S) ((((S) >> 2) & ~WIFERRMASK) | ((S) & WIFERRMASK) | ERRFAILED)
+
+#define GWEXITERROR() RWEXITERROR(GetLastError())
-#define RCERROR(x) ((x) | ERRFAILED)
-#define GETLASTERROR() (GetLastError() | ERRFAILED)
#define RESOURCE_NAME_LEN 64
#define RESOURCE_SSID_LEN 256
#define RESOURCE_USER_LEN 256
@@ -571,7 +585,7 @@
/* To share the objects with other processes, we need a NULL ACL
* Code from MS KB Q106387
*/
-PSECURITY_ATTRIBUTES GetSaWithNullDacl()
+PSECURITY_ATTRIBUTES GetSaWithNullDacl(BOOL bInherit)
{
DWORD rc = 0;
PSECURITY_DESCRIPTOR pSD;
@@ -601,7 +615,7 @@
goto cleanup;
}
pNullSA->lpSecurityDescriptor = pSD;
- pNullSA->bInheritHandle = FALSE;
+ pNullSA->bInheritHandle = bInherit;
SetLastError(0);
return pNullSA;
@@ -749,7 +763,7 @@
*lphToken = INVALID_HANDLE_VALUE;
}
CloseHandle(hProcess);
- if (!DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, GetSaWithNullDacl(),
+ if (!DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, GetSaWithNullDacl(FALSE),
SecurityIdentification, TokenPrimary,
lphToken)) {
CloseHandle(hToken);
@@ -825,7 +839,7 @@
return FALSE;
}
CloseHandle(hProcess);
- rs = DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, GetSaWithNullDacl(),
+ rs = DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, GetSaWithNullDacl(FALSE),
SecurityIdentification, TokenPrimary,
lphToken);
CloseHandle(hToken);
@@ -852,7 +866,7 @@
if (rc != ERROR_SUCCESS)
return FALSE;
}
- if (!DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, GetSaWithNullDacl(),
+ if (!DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, GetSaWithNullDacl(FALSE),
SecurityIdentification, TokenPrimary,
lphToken)) {
CloseHandle(hToken);
@@ -1174,7 +1188,7 @@
return NULL;
}
hShm = CreateFileMappingW(INVALID_HANDLE_VALUE,
- GetSaWithNullDacl(),
+ GetSaWithNullDacl(FALSE),
PAGE_READWRITE,
0,
cbSize,
@@ -1244,7 +1258,7 @@
0,
65536,
1,
- GetSaWithNullDacl());
+ GetSaWithNullDacl(FALSE));
if (IS_INVALID_HANDLE(hRpipe))
return FALSE;
}
@@ -1256,7 +1270,7 @@
hWpipe = CreateFileW(szPipeName,
GENERIC_WRITE,
0,
- GetSaWithNullDacl(),
+ GetSaWithNullDacl(FALSE),
OPEN_EXISTING,
dwOpenMode,
NULL);
@@ -1298,7 +1312,7 @@
hNull = CreateFileW(L"NUL",
dwFlags,
0,
- GetSaWithNullDacl(),
+ GetSaWithNullDacl(FALSE),
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
@@ -1629,14 +1643,14 @@
MEM_COMMIT | MEM_RESERVE,
PAGE_READWRITE | PAGE_NOCACHE);
if (!lpForkData) {
- rc = GETLASTERROR();
+ rc = GWEXITERROR();
DBG_PRINTF((__LINE__, "[ERROR] VirtualAlloc err=%d", GetLastError()));
goto cleanup;
}
lpForkData->cb = sizeof(FORK_DATA);
hCurrentProcess = GetCurrentProcess();
if (!GetCurrentAccessToken(&hToken)) {
- rc = GETLASTERROR();
+ rc = GWEXITERROR();
DBG_PRINTF((__LINE__, "[ERROR] GetCurrentAccessToken err=%d", GetLastError()));
goto cleanup;
}
@@ -1647,7 +1661,7 @@
DBG_PRINTF((__LINE__, "[INFO] Running in Session %d", dwSourceSessionId));
args = CommandLineToArrayW(GetCommandLineW(), &argc);
if (args == NULL) {
- rc = GETLASTERROR();
+ rc = GWEXITERROR();
DBG_PRINTF((__LINE__, "[ERROR] CommandLineToArrayW err=%d", GetLastError()));
goto cleanup;
}
@@ -1690,7 +1704,7 @@
else if (*opt == L't') {
if (!val || !*val) {
/* Invalid timeout argument */
- rc = RCERROR(ERROR_INVALID_PARAMETER);
+ rc = RWEXITERROR(ERROR_INVALID_PARAMETER);
DBG_PRINTF((__LINE__, "[ERROR] Missing Timeout param"));
goto cleanup;
}
@@ -1698,7 +1712,7 @@
lpForkData->dwTimeout = (DWORD)wcstoul(val, &cep, 10);
if (*cep) {
/* Invalid timeout argument */
- rc = RCERROR(ERROR_INVALID_PARAMETER);
+ rc = RWEXITERROR(ERROR_INVALID_PARAMETER);
DBG_PRINTF((__LINE__, "[ERROR] Invalid Timeout param %S", val));
goto cleanup;
}
@@ -1714,7 +1728,7 @@
dwTargetSessionId = (DWORD)wcstoul(val, &cep, 10);
if (*cep) {
/* Invalid parent pid argument */
- rc = RCERROR(ERROR_INVALID_PARAMETER);
+ rc = RWEXITERROR(ERROR_INVALID_PARAMETER);
DBG_PRINTF((__LINE__, "[ERROR] Invalid Session param %S", val));
goto cleanup;
}
@@ -1725,7 +1739,7 @@
if (val)
wcslcpy(lpForkData->szpCryptoSalt, val, RESOURCE_NAME_LEN);
else {
- rc = RCERROR(ERROR_INVALID_PARAMETER);
+ rc = RWEXITERROR(ERROR_INVALID_PARAMETER);
DBG_PRINTF((__LINE__, "[ERROR] Param --h is missing"));
goto cleanup;
}
@@ -1733,7 +1747,7 @@
else if (*opt == L'u' && val) {
DWORD cb = RESOURCE_SSID_LEN;
if (!GetStringSidFromAccountName(val, lpForkData->szUserSsid, &cb)) {
- rc = GETLASTERROR();
+ rc = GWEXITERROR();
DBG_PRINTF((__LINE__, "[ERROR] GetStringSidFromAccountName %S err=%d", val, GetLastError()));
goto cleanup;
}
@@ -1750,7 +1764,7 @@
lpForkData->szpCryptoSalt,
lpForkData->bpEncPassword,
&lpForkData->cbEncPassword)) {
- rc = RCERROR(ERROR_INVALID_PARAMETER);
+ rc = RWEXITERROR(ERROR_INVALID_PARAMETER);
DBG_PRINTF((__LINE__, "[ERROR] EncryptPassword err=%d", GetLastError()));
goto cleanup;
}
@@ -1808,7 +1822,7 @@
}
else {
DBG_PRINTF((__LINE__, "[ERROR] Unknown command option: --%S[=%S]", val, opt));
- rc = RCERROR(ERROR_INVALID_PARAMETER);
+ rc = RWEXITERROR(ERROR_INVALID_PARAMETER);
goto cleanup;
}
}
@@ -1826,7 +1840,7 @@
if (bFork) {
const wchar_t *c[3] = { _wpgmptr, szVmsMem, NULL };
if (!(argv = MergeArrays(c, argv))) {
- rc = GETLASTERROR();
+ rc = GWEXITERROR();
DBG_PRINTF((__LINE__, "[ERROR] MergeArrays err=%d", GetLastError()));
goto cleanup;
}
@@ -1837,19 +1851,19 @@
/* We don't have the valid
* for the supplied parent
*/
- rc = RCERROR(ERROR_INVALID_PARAMETER);
+ rc = RWEXITERROR(ERROR_INVALID_PARAMETER);
DBG_PRINTF((__LINE__, "[ERROR] Missing Memory Pointer for %d", dwParentPid));
goto cleanup;
}
hParent = OpenProcess(PROCESS_VM_READ, FALSE, dwParentPid);
if (IS_INVALID_HANDLE(hParent)) {
- rc = GETLASTERROR();
+ rc = GWEXITERROR();
DBG_PRINTF((__LINE__, "[ERROR] OpenProcess %d err=%d", dwParentPid, GetLastError()));
goto cleanup;
}
if (!ReadProcessMemory(hParent, lpVmsPtr,
lpForkData, sizeof(FORK_DATA), NULL)) {
- rc = GETLASTERROR();
+ rc = GWEXITERROR();
DBG_PRINTF((__LINE__, "[ERROR] ReadProcessMemory err=%d", GetLastError()));
goto cleanup;
}
@@ -1858,12 +1872,12 @@
if (argc < 1) {
/* We need at least one argument.
*/
- rc = RCERROR(ERROR_INVALID_PARAMETER);
+ rc = RWEXITERROR(ERROR_INVALID_PARAMETER);
DBG_PRINTF((__LINE__, "[ERROR] Invalid Nuber of Arguments"));
goto cleanup;
}
if (!(cmdline = ArgvToCommandLineW(argv))) {
- rc = RCERROR(ERROR_NOT_ENOUGH_MEMORY);
+ rc = RWEXITERROR(ERROR_NOT_ENOUGH_MEMORY);
DBG_PRINTF((__LINE__, "[ERROR] ArgvToCommandLineW err=%d", GetLastError()));
goto cleanup;
}
@@ -1889,7 +1903,7 @@
/* Failed to obtain required Session token.
* Probably we are missing privileges
*/
- rc = GETLASTERROR();
+ rc = GWEXITERROR();
DBG_PRINTF((__LINE__, "[ERROR] GetSession0Token err=%d", GetLastError()));
goto cleanup;
}
@@ -1902,7 +1916,7 @@
/* Failed to obtain required Session token.
* Probably we are missing privileges
*/
- rc = GETLASTERROR();
+ rc = GWEXITERROR();
DBG_PRINTF((__LINE__, "[ERROR] GetSessionToken session=%d err=%d", dwTargetSessionId, GetLastError()));
goto cleanup;
}
@@ -1926,7 +1940,7 @@
&si,
&pi);
if (!rs) {
- rc = GETLASTERROR();
+ rc = GWEXITERROR();
DBG_PRINTF((__LINE__, "[ERROR] CreateProcessAsUserW proc=%S err=%d", argv[0], rc));
goto cleanup;
}
@@ -1944,7 +1958,7 @@
* Return the child pid in the exit code
*/
rc = pi.dwProcessId;
- goto finally;
+ goto cleanup;
}
/* Wait until forked child exits. It will report us the
* PID of the grand child in the return value
@@ -1952,24 +1966,23 @@
rc = WaitForSingleObject(pi.hProcess, INFINITE);
if (rc == WAIT_OBJECT_0) {
if (!GetExitCodeProcess(pi.hProcess, &dwChildExitval)) {
- rc = GETLASTERROR();
+ rc = GWEXITERROR();
DBG_PRINTF((__LINE__, "[ERROR] GetExitCodeProcess pid=%d err=%d", pi.dwProcessId, GetLastError()));
- goto cleanup;
}
else {
DBG_PRINTF((__LINE__, "[INFO] GetExitCodeProcess pid=%d exitval=%08X", pi.dwProcessId, dwChildExitval));
- /* Unmask the exit value */
- rc = dwChildExitval & ~ERRSUCESS;
+ rc = dwChildExitval;
+ goto cleanup;
}
}
else {
- DWORD wr = rc;
+ DWORD ws = rc;
/* Something wrong with the wait */
- rc = GETLASTERROR();
+ rc = GWEXITERROR();
DBG_PRINTF((__LINE__, "[ERROR] WaitForSingleObject wait=%d err=%d",
- wr, GetLastError()));
- goto cleanup;
+ ws, GetLastError()));
}
+ goto cleanup;
}
else {
/* We are inside forked child.
@@ -1992,7 +2005,7 @@
NULL,
lpForkData->szStdInpName,
PIPE_FULL_BLOCK)) {
- rc = GETLASTERROR();
+ rc = GWEXITERROR();
DBG_PRINTF((__LINE__, "[ERROR] CreatePipePair pipe=%S err=%d",
lpForkData->szStdInpName, GetLastError()));
goto cleanup;
@@ -2010,7 +2023,7 @@
&hPipes[PIPE_STDINP_WRS],
NULL,
PIPE_READ_BLOCK)) {
- rc = GETLASTERROR();
+ rc = GWEXITERROR();
DBG_PRINTF((__LINE__, "[ERROR] CreatePipePair err=%d",
GetLastError()));
goto cleanup;
@@ -2020,7 +2033,7 @@
if (!lpForkData->szDllEntry[0] &&
!CreateNullPipe(&hPipes[PIPE_STDINP_RDS],
GENERIC_READ)) {
- rc = GETLASTERROR();
+ rc = GWEXITERROR();
DBG_PRINTF((__LINE__, "[ERROR] CreateNullPipe err=%d",
GetLastError()));
goto cleanup;
@@ -2035,7 +2048,7 @@
&hPpipe[PIPE_STDOUT_RPC],
lpForkData->szStdOutName,
PIPE_FULL_BLOCK)) {
- rc = GETLASTERROR();
+ rc = GWEXITERROR();
DBG_PRINTF((__LINE__, "[ERROR] CreatePipePair pipe=%S err=%d",
lpForkData->szStdOutName, GetLastError()));
goto cleanup;
@@ -2047,7 +2060,7 @@
&hPipes[PIPE_STDOUT_WRS],
NULL,
PIPE_WRITE_BLOCK)) {
- rc = GETLASTERROR();
+ rc = GWEXITERROR();
DBG_PRINTF((__LINE__, "[ERROR] CreatePipePair err=%d",
GetLastError()));
goto cleanup;
@@ -2057,7 +2070,7 @@
if (!lpForkData->szDllEntry[0] &&
!CreateNullPipe(&hPipes[PIPE_STDOUT_WRS],
GENERIC_WRITE)) {
- rc = GETLASTERROR();
+ rc = GWEXITERROR();
DBG_PRINTF((__LINE__, "[ERROR] CreateNullPipe err=%d",
GetLastError()));
goto cleanup;
@@ -2072,7 +2085,7 @@
&hPpipe[PIPE_STDERR_RPC],
lpForkData->szStdErrName,
PIPE_FULL_BLOCK)) {
- rc = GETLASTERROR();
+ rc = GWEXITERROR();
DBG_PRINTF((__LINE__, "[ERROR] CreatePipePair pipe=%S err=%d",
lpForkData->szStdErrName, GetLastError()));
goto cleanup;
@@ -2084,7 +2097,7 @@
&hPipes[PIPE_STDERR_WRS],
NULL,
PIPE_WRITE_BLOCK)) {
- rc = GETLASTERROR();
+ rc = GWEXITERROR();
DBG_PRINTF((__LINE__, "[ERROR] CreatePipePair err=%d",
GetLastError()));
goto cleanup;
@@ -2094,7 +2107,7 @@
if (!lpForkData->szDllEntry[0] &&
!CreateNullPipe(&hPipes[PIPE_STDERR_WRS],
GENERIC_WRITE)) {
- rc = GETLASTERROR();
+ rc = GWEXITERROR();
DBG_PRINTF((__LINE__, "[ERROR] CreateNullPipe err=%d",
GetLastError()));
goto cleanup;
@@ -2107,18 +2120,38 @@
hPipes[PIPE_STDERR_WRS] = hPipes[PIPE_STDOUT_WRS];
}
if (lpForkData->szDllEntry[0]) {
-
+ /* Setup std descriptors do we can used them
+ * immediately from DllMain
+ */
+ if (IS_VALID_HANDLE(hPpipe[PIPE_STDINP_RPC])) {
+ int fd = _open_osfhandle((ptrdiff_t)hPpipe[PIPE_STDINP_RPC], _O_RDONLY);
+ if (fd > 0)
+ dup2(fd, 0);
+ hPpipe[PIPE_STDINP_RPC] = NULL;
+ }
+ if (IS_VALID_HANDLE(hPpipe[PIPE_STDOUT_RPC])) {
+ int fd = _open_osfhandle((ptrdiff_t)hPpipe[PIPE_STDOUT_RPC], _O_WRONLY);
+ if (fd > 1)
+ dup2(fd, 1);
+ hPpipe[PIPE_STDOUT_RPC] = NULL;
+ }
+ if (IS_VALID_HANDLE(hPpipe[PIPE_STDERR_RPC])) {
+ int fd = _open_osfhandle((ptrdiff_t)hPpipe[PIPE_STDERR_RPC], _O_WRONLY);
+ if (fd > 2)
+ dup2(fd, 2);
+ hPpipe[PIPE_STDERR_RPC] = NULL;
+ }
DBG_PRINTF((__LINE__, "[INFO] LoadLibrary dll=%S func=%s", argv[0], lpForkData->szDllEntry));
hModule = LoadLibraryW(argv[0]);
if (IS_INVALID_HANDLE(hModule)) {
- rc = GETLASTERROR();
+ rc = GWEXITERROR();
DBG_PRINTF((__LINE__, "[ERROR] LoadLibrary dll=%S err=%d", argv[0], GetLastError()));
goto cleanup;
}
fnDllMain = (lpfnDllMain)GetProcAddress(hModule, lpForkData->szDllEntry);
if (!fnDllMain) {
- rc = GETLASTERROR();
+ rc = GWEXITERROR();
DBG_PRINTF((__LINE__, "[ERROR] GetProcAddress func=%s err=%d", lpForkData->szDllEntry, GetLastError()));
goto cleanup;
}
@@ -2130,7 +2163,7 @@
if (!DecryptPassword(lpForkData->bpEncPassword,
lpForkData->cbEncPassword,
lpForkData->szpCryptoSalt, szPassword)) {
- rc = GETLASTERROR();
+ rc = GWEXITERROR();
DBG_PRINTF((__LINE__, "[ERROR] DecryptPassword err=%d", GetLastError()));
goto cleanup;
}
@@ -2140,7 +2173,7 @@
if (!StoreEncryptedPassword(lpForkData->szUserSsid,
lpForkData->bpEncPassword,
lpForkData->cbEncPassword)) {
- rc = GETLASTERROR();
+ rc = GWEXITERROR();
DBG_PRINTF((__LINE__, "[ERROR] StoreEncryptedPassword err=%d", GetLastError()));
goto cleanup;
}
@@ -2157,7 +2190,7 @@
lpForkData->cbEncPassword,
lpForkData->szpCryptoSalt,
szPassword)) {
- rc = GETLASTERROR();
+ rc = GWEXITERROR();
DBG_PRINTF((__LINE__, "[ERROR] DecryptPassword err=%d", GetLastError()));
goto cleanup;
}
@@ -2181,7 +2214,7 @@
LOGON32_LOGON_NETWORK,
LOGON32_PROVIDER_DEFAULT,
&hUser)) {
- rc = GETLASTERROR();
+ rc = GWEXITERROR();
DBG_PRINTF((__LINE__, "[ERROR] LogonUser user=%S err=%d", lpForkData->szUserName, GetLastError()));
goto cleanup;
@@ -2192,7 +2225,7 @@
if (!DuplicateTokenEx(hUser, MAXIMUM_ALLOWED, NULL,
SecurityImpersonation, TokenPrimary,
&hToken)) {
- rc = GETLASTERROR();
+ rc = GWEXITERROR();
DBG_PRINTF((__LINE__, "[ERROR] DuplicateTokenEx err=%d", GetLastError()));
CloseHandle(hUser);
goto cleanup;
@@ -2204,7 +2237,7 @@
if (!ImpersonateLoggedOnUser(hToken)) {
/* Althugh logged in, we cannot imersonate the user
*/
- rc = GETLASTERROR();
+ rc = GWEXITERROR();
DBG_PRINTF((__LINE__, "[ERROR] ImpersonateLoggedOnUser err=%d", GetLastError()));
goto cleanup;
}
@@ -2213,25 +2246,6 @@
RESOURCE_NAME_LEN * sizeof(WCHAR));
if (fnDllMain) {
- /* Setup std descriptors */
- if (IS_VALID_HANDLE(hPpipe[PIPE_STDINP_RPC])) {
- int fd = _open_osfhandle((intptr_t)hPpipe[PIPE_STDINP_RPC], _O_RDONLY);
- if (fd > 0)
- dup2(fd, 0);
- hPpipe[PIPE_STDINP_RPC] = NULL;
- }
- if (IS_VALID_HANDLE(hPpipe[PIPE_STDOUT_RPC])) {
- int fd = _open_osfhandle((intptr_t)hPpipe[PIPE_STDOUT_RPC], _O_WRONLY);
- if (fd > 1)
- dup2(fd, 1);
- hPpipe[PIPE_STDOUT_RPC] = NULL;
- }
- if (IS_VALID_HANDLE(hPpipe[PIPE_STDERR_RPC])) {
- int fd = _open_osfhandle((intptr_t)hPpipe[PIPE_STDERR_RPC], _O_WRONLY);
- if (fd > 2)
- dup2(fd, 2);
- hPpipe[PIPE_STDERR_RPC] = NULL;
- }
/* Execute the Loaded DLL enty point.
* Note that we call RevertToSelf afterwards meaning
* that we run under the impersonated user account.
@@ -2244,7 +2258,7 @@
DBG_PRINTF((__LINE__, "[INFO] DLL Module rv=%d", rc));
if (lpForkData->szUserName[0])
RevertToSelf();
- rc &= ~ERRFAILED;
+ rc = RWEXITSTATUS(rc);
}
else {
LPWCH lpEnv = NULL;
@@ -2252,14 +2266,14 @@
if (!RevertToSelf()) {
/* If RevertToSelf fails, bail out.
*/
- rc = GETLASTERROR();
+ rc = GWEXITERROR();
DBG_PRINTF((__LINE__, "[ERROR] RevertToSelf err=%d", GetLastError()));
goto cleanup;
}
}
if (lpForkData->bUseCgiEnv) {
if (!(lpEnv = GetSafeEnvironmentBlock(lpForkData->szSafeEnvars))) {
- rc = GETLASTERROR();
+ rc = GWEXITERROR();
DBG_PRINTF((__LINE__, "[ERROR] GetSafeEnvironmentBlock err=%d", GetLastError()));
goto cleanup;
}
@@ -2290,7 +2304,7 @@
&pi);
if (!rs) {
- rc = GETLASTERROR();
+ rc = GWEXITERROR();
DBG_PRINTF((__LINE__, "[ERROR] CreateProcessAsUserW %S err=%d", argv[0], rc));
x_free(lpEnv);
goto cleanup;
@@ -2300,14 +2314,14 @@
SAFE_CLOSE_HANDLE(hPipes[PIPE_STDINP_RDS]);
SAFE_CLOSE_HANDLE(hPipes[PIPE_STDOUT_WRS]);
SAFE_CLOSE_HANDLE(hPipes[PIPE_STDERR_WRS]);
- /* Our exit value will contain the child pid
- */
- rc = pi.dwProcessId;
ResumeThread(pi.hThread);
x_free(lpEnv);
if (lpForkData->dwTimeout == 0) {
- /* Detached process */
- goto finally;
+ /* Detached process.
+ * Our exit value will contain the child pid
+ */
+ rc = RWEXITPID(pi.dwProcessId);
+ goto cleanup;
}
/* Setup wait handles
@@ -2540,25 +2554,32 @@
if (rc != ERROR_NO_MORE_FILES) {
/* Kill the process */
TerminateProcess(pi.hProcess, 9);
+ rc = RWEXITERROR(rc);
+ goto cleanup;
}
- /* XXX: How long should we wait for TerminateProcess ? */
- switch (WaitForSingleObject(pi.hProcess, 1000) {
+ /* Wait for the remaining of the timeout left if any */
+ if ((dwTimeout = GetTimeRunning()) > lpForkData->dwTimeout)
+ dwTimeout = 0;
+ else
+ dwTimeout = lpForkData->dwTimeout - dwTimeout;
+ switch (WaitForSingleObject(pi.hProcess, dwTimeout)) {
case WAIT_OBJECT_0:
- GetExitCodeProcess(pi.hProcess, &rc);
+ GetExitCodeProcess(pi.hProcess, &dwChildExitval);
+ /* Unmask the return value.
+ * This is the only place where we can have problems
+ * reporting the real child exit value.
+ */
+ rc = RWEXITSTATUS(dwChildExitval);
break;
default:
+ DBG_PRINTF((__LINE__, "[INFO] TerminateProcess pid=%d", pi.dwProcessId));
TerminateProcess(pi.hProcess, 9);
- rc = 9;
+ rc = RWEXITERROR(ERROR_TIMEOUT);
break;
}
}
}
-finally:
- /* Mask the value with ERRSUCESS
- */
- rc |= ERRSUCESS;
-
cleanup:
SAFE_CLOSE_HANDLE(hModule);
SAFE_CLOSE_HANDLE(hParent);
@@ -2591,5 +2612,15 @@
* but add Error Severity and Customer code set.
*/
DBG_PRINTF((__LINE__, "[INFO] ExitMain rv=%08X", rc));
+ if (WIFEXITED(rc)) {
+ DBG_PRINTF((__LINE__, "[INFO] Exited pid=%08X", WEXITPID(rc)));
+ }
+ else if (WIFSIGNALED(rc)) {
+ DBG_PRINTF((__LINE__, "[INFO] Exited error=%08X", WEXITERROR(rc)));
+ }
+ else {
+ DBG_PRINTF((__LINE__, "[INFO] Exited status=%08X", WEXITSTATUS(rc)));
+ }
return rc;
}
+