Return-Path: Delivered-To: apmail-commons-commits-archive@minotaur.apache.org Received: (qmail 29648 invoked from network); 26 Jan 2010 16:23:39 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 26 Jan 2010 16:23:39 -0000 Received: (qmail 29832 invoked by uid 500); 26 Jan 2010 16:23:39 -0000 Delivered-To: apmail-commons-commits-archive@commons.apache.org Received: (qmail 29765 invoked by uid 500); 26 Jan 2010 16:23:39 -0000 Mailing-List: contact commits-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@commons.apache.org Delivered-To: mailing list commits@commons.apache.org Received: (qmail 29756 invoked by uid 99); 26 Jan 2010 16:23:39 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 26 Jan 2010 16:23:39 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 26 Jan 2010 16:23:35 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id B227623889DA; Tue, 26 Jan 2010 16:23:13 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r903304 - /commons/sandbox/runtime/trunk/src/main/native/support/win32/wsuexec.c Date: Tue, 26 Jan 2010 16:23:13 -0000 To: commits@commons.apache.org From: mturk@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20100126162313.B227623889DA@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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; } +