VirtualBox

Changeset 52163 in vbox


Ignore:
Timestamp:
Jul 24, 2014 11:35:26 AM (11 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
95205
Message:

SUP: Make the middle respawn process wait on both parent and child. Cleanups.

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/nt/nt.h

    r52139 r52163  
    11171117typedef FILE_FS_ATTRIBUTE_INFORMATION *PFILE_FS_ATTRIBUTE_INFORMATION;
    11181118
     1119NTSYSAPI NTSTATUS NTAPI NtOpenProcess(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PCLIENT_ID);
    11191120NTSYSAPI NTSTATUS NTAPI NtOpenProcessToken(HANDLE, ACCESS_MASK, PHANDLE);
     1121NTSYSAPI NTSTATUS NTAPI NtOpenThread(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PCLIENT_ID);
    11201122NTSYSAPI NTSTATUS NTAPI NtOpenThreadToken(HANDLE, ACCESS_MASK, BOOLEAN, PHANDLE);
    11211123
     
    16411643typedef RTNT_SYSTEM_PROCESS_INFORMATION *PRTNT_SYSTEM_PROCESS_INFORMATION;
    16421644#ifndef IPRT_NT_USE_WINTERNL
    1643 typedef RTNT_SYSTEM_PROCESS_INFORMATION SYSTEM_PROCESS_INFORMATION ;
     1645typedef RTNT_SYSTEM_PROCESS_INFORMATION SYSTEM_PROCESS_INFORMATION;
    16441646typedef SYSTEM_PROCESS_INFORMATION *PSYSTEM_PROCESS_INFORMATION;
    16451647#endif
     
    17041706NTSYSAPI NTSTATUS NTAPI NtYieldExecution(void);
    17051707#ifndef IPRT_NT_USE_WINTERNL
    1706 NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(HANDLE, BOOLEAN PLARGE_INTERGER);
    1707 #endif
     1708NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(HANDLE, BOOLEAN PLARGE_INTEGER);
     1709#endif
     1710typedef enum _OBJECT_WAIT_TYPE { WaitAllObjects = 0, WaitAnyObject = 1, ObjectWaitTypeHack = 0x7fffffff } OBJECT_WAIT_TYPE;
     1711NTSYSAPI NTSTATUS NTAPI NtWaitForMultipleObjects(ULONG, PHANDLE, OBJECT_WAIT_TYPE, BOOLEAN, PLARGE_INTEGER);
    17081712
    17091713
  • trunk/src/VBox/HostDrivers/Support/SUPR3HardenedMain.cpp

    r52160 r52163  
    3838
    3939#elif RT_OS_WINDOWS
    40 # include <Windows.h>
     40# include <iprt/nt/nt-and-windows.h>
    4141
    4242#else /* UNIXes */
     
    230230{
    231231#ifdef RT_OS_WINDOWS
    232     DWORD cbWrittenIgn;
    233     WriteFile(GetStdHandle(STD_ERROR_HANDLE), pch, (DWORD)cch, &cbWrittenIgn, NULL);
     232    HANDLE hStdOut = NtCurrentPeb()->ProcessParameters->StandardOutput;
     233    if (hStdOut != NULL)
     234    {
     235        IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;
     236        NtWriteFile(hStdOut, NULL /*Event*/, NULL /*ApcRoutine*/, NULL /*ApcContext*/,
     237                    &Ios, (PVOID)pch, cch, NULL /*ByteOffset*/, NULL /*Key*/);
     238    }
    234239#else
    235240    (void)write(2, pch, cch);
  • trunk/src/VBox/HostDrivers/Support/SUPR3HardenedVerify.cpp

    r52160 r52163  
    4040
    4141#elif defined(RT_OS_WINDOWS)
    42 # include <Windows.h>
     42# include <iprt/nt/nt-and-windows.h>
    4343# ifndef IN_SUP_HARDENED_R3
    4444#  include <stdio.h>
     
    781781#if defined(RT_OS_WINDOWS)
    782782        LPSTR pszIgnored;
    783         char szName2[RTPATH_MAX];
     783        char szName2[RTPATH_MAX]; /** @todo Must use UTF-16 here! Code is mixing UTF-8 and native. */
    784784        if (    GetFullPathName(szName, RT_ELEMENTS(szName2), &szName2[0], &pszIgnored)
    785785            &&  GetFullPathName(pszFilename, RT_ELEMENTS(szName), &szName[0], &pszIgnored))
     
    17131713            rc = RTErrInfoSetF(pErrInfo, rc, "Error converting '%s' to UTF-16: %Rrc", pszFilename, rc);
    17141714    }
    1715     else if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)hNativeFile, GetCurrentProcess(), &hVerify,
    1716                               GENERIC_READ, false /*bInheritHandle*/, 0 /*dwOptions*/))
    1717         hVerify = INVALID_HANDLE_VALUE;
     1715    else
     1716    {
     1717        NTSTATUS rcNt = NtDuplicateObject(NtCurrentProcess(), (HANDLE)hNativeFile, NtCurrentProcess(), &hVerify,
     1718                                          GENERIC_READ, 0 /*HandleAttributes*/, 0 /*Options*/);
     1719        if (!NT_SUCCESS(rcNt))
     1720            hVerify = INVALID_HANDLE_VALUE;
     1721    }
    17181722    if (hVerify != INVALID_HANDLE_VALUE)
    17191723    {
  • trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp

    r52160 r52163  
    964964     * notifications from ending up in the debugger.
    965965     */
    966     rcNt = NtSetInformationThread(GetCurrentThread(), ThreadHideFromDebugger, NULL, 0);
     966    rcNt = NtSetInformationThread(NtCurrentThread(), ThreadHideFromDebugger, NULL, 0);
    967967    if (!NT_SUCCESS(rcNt))
    968968        supR3HardenedFatalMsg("supR3HardenedWinInstallHooks", kSupInitOp_Misc, VERR_GENERAL_FAILURE,
     
    10641064
    10651065        DWORD dwOldProt;
    1066         SUPR3HARDENED_ASSERT_WIN32_SUCCESS(VirtualProtectEx(GetCurrentProcess(), pbNtCreateSection, 16,
     1066        SUPR3HARDENED_ASSERT_WIN32_SUCCESS(VirtualProtectEx(NtCurrentProcess(), pbNtCreateSection, 16,
    10671067                                                            PAGE_EXECUTE_READWRITE, &dwOldProt));
    10681068        pbNtCreateSection[0] = 0xff;
     
    10701070        *(uint32_t *)&pbNtCreateSection[2] = (uint32_t)((uintptr_t)puJmpTab - (uintptr_t)&pbNtCreateSection[2+4]);
    10711071
    1072         SUPR3HARDENED_ASSERT_WIN32_SUCCESS(VirtualProtectEx(GetCurrentProcess(), pbNtCreateSection, 16,
     1072        SUPR3HARDENED_ASSERT_WIN32_SUCCESS(VirtualProtectEx(NtCurrentProcess(), pbNtCreateSection, 16,
    10731073                                                            PAGE_EXECUTE_READ, &dwOldProt));
    10741074        return;
     
    11421142
    11431143        DWORD dwOldProt;
    1144         SUPR3HARDENED_ASSERT_WIN32_SUCCESS(VirtualProtectEx(GetCurrentProcess(), pbNtCreateSection, 16,
     1144        SUPR3HARDENED_ASSERT_WIN32_SUCCESS(VirtualProtectEx(NtCurrentProcess(), pbNtCreateSection, 16,
    11451145                                                            PAGE_EXECUTE_READWRITE, &dwOldProt));
    11461146        pbNtCreateSection[0] = 0xe9;
     
    11481148                                           - (uintptr_t)&pbNtCreateSection[1+4];
    11491149
    1150         SUPR3HARDENED_ASSERT_WIN32_SUCCESS(VirtualProtectEx(GetCurrentProcess(), pbNtCreateSection, 16,
     1150        SUPR3HARDENED_ASSERT_WIN32_SUCCESS(VirtualProtectEx(NtCurrentProcess(), pbNtCreateSection, 16,
    11511151                                                            PAGE_EXECUTE_READ, &dwOldProt));
    11521152        return;
     
    11731173{
    11741174    RTErrInfoInitStatic(&g_ErrInfoStatic);
    1175     int rc = supHardenedWinVerifyProcess(GetCurrentProcess(), GetCurrentThread(), &g_ErrInfoStatic.Core);
     1175    int rc = supHardenedWinVerifyProcess(NtCurrentProcess(), NtCurrentThread(), &g_ErrInfoStatic.Core);
    11761176    if (RT_FAILURE(rc))
    11771177        supR3HardenedFatalMsg("supR3HardenedWinVerifyProcess", kSupInitOp_Integrity, rc,
     
    11921192{
    11931193    HANDLE hToken;
    1194     SUPR3HARDENED_ASSERT_NT_SUCCESS(NtOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken));
     1194    SUPR3HARDENED_ASSERT_NT_SUCCESS(NtOpenProcessToken(NtCurrentProcess(), TOKEN_QUERY, &hToken));
    11951195    union
    11961196    {
     
    13591359
    13601360/**
    1361  * Construct the new command line.  Since argc/argv are both derived from
    1362  * GetCommandLineW (see suplibHardenedWindowsMain), we skip the argument
    1363  * by argument UTF-8 -> UTF-16 conversion and quoting by going to the
    1364  * original source.
     1361 * Construct the new command line.
     1362 *
     1363 * Since argc/argv are both derived from GetCommandLineW (see
     1364 * suplibHardenedWindowsMain), we skip the argument by argument UTF-8 -> UTF-16
     1365 * conversion and quoting by going to the original source.
    13651366 *
    13661367 * The executable name, though, is replaced in case it's not a fullly
     
    13841385     * Get the command line and skip the executable name.
    13851386     */
    1386     PCRTUTF16 pwszArgs = GetCommandLineW();
     1387    PUNICODE_STRING pCmdLineStr = &NtCurrentPeb()->ProcessParameters->CommandLine;
     1388    PCRTUTF16 pawcArgs = pCmdLineStr->Buffer;
     1389    uint32_t  cwcArgs  = pCmdLineStr->Length / sizeof(WCHAR);
    13871390
    13881391    /* Skip leading space (shouldn't be any, but whatever). */
    1389     while (suplibCommandLineIsArgSeparator(*pwszArgs))
    1390         pwszArgs++;
    1391     SUPR3HARDENED_ASSERT(*pwszArgs != '\0');
     1392    while (cwcArgs > 0 && suplibCommandLineIsArgSeparator(*pawcArgs) )
     1393        cwcArgs--, pawcArgs++;
     1394    SUPR3HARDENED_ASSERT(cwcArgs > 0 && *pawcArgs != '\0');
    13921395
    13931396    /* Walk to the end of it. */
     
    13951398    do
    13961399    {
    1397         if (*pwszArgs == '"')
     1400        if (*pawcArgs == '"')
    13981401        {
    13991402            fQuoted = !fQuoted;
    1400             pwszArgs++;
     1403            cwcArgs--; pawcArgs++;
    14011404        }
    1402         else if (*pwszArgs != '\\' || (pwszArgs[1] != '\\' && pwszArgs[1] != '"'))
    1403             pwszArgs++;
     1405        else if (*pawcArgs != '\\' || (pawcArgs[1] != '\\' && pawcArgs[1] != '"'))
     1406            cwcArgs--, pawcArgs++;
    14041407        else
    14051408        {
    14061409            unsigned cSlashes = 0;
    14071410            do
     1411            {
    14081412                cSlashes++;
    1409             while (*++pwszArgs == '\\');
    1410             if (*pwszArgs == '"' && (cSlashes & 1))
    1411                 pwszArgs++; /* odd number of slashes == escaped quote */
     1413                cwcArgs--;
     1414                pawcArgs++;
     1415            }
     1416            while (cwcArgs > 0 && *pawcArgs == '\\');
     1417            if (cwcArgs > 0 && *pawcArgs == '"' && (cSlashes & 1))
     1418                cwcArgs--, pawcArgs++; /* odd number of slashes == escaped quote */
    14121419        }
    1413     } while (*pwszArgs && (fQuoted || !suplibCommandLineIsArgSeparator(*pwszArgs)));
     1420    } while (cwcArgs > 0 && (fQuoted || !suplibCommandLineIsArgSeparator(*pawcArgs)));
    14141421
    14151422    /* Skip trailing spaces. */
    1416     while (suplibCommandLineIsArgSeparator(*pwszArgs))
    1417         pwszArgs++;
     1423    while (cwcArgs > 0 && suplibCommandLineIsArgSeparator(*pawcArgs))
     1424        cwcArgs--, pawcArgs++;
    14181425
    14191426    /*
     
    14211428     */
    14221429    AssertCompile(sizeof(SUPR3_RESPAWN_1_ARG0) == sizeof(SUPR3_RESPAWN_2_ARG0));
    1423     size_t cwcArgs    = suplibHardenedWStrLen(pwszArgs);
    14241430    size_t cwcCmdLine = (sizeof(SUPR3_RESPAWN_1_ARG0) - 1) / sizeof(SUPR3_RESPAWN_1_ARG0[0]) /* Respawn exe name. */
    14251431                      + !!cwcArgs + cwcArgs; /* if arguments present, add space + arguments. */
     
    14411447    {
    14421448        *pwszDst++ = ' ';
    1443         suplibHardenedMemCopy(pwszDst, pwszArgs, cwcArgs * sizeof(RTUTF16));
     1449        suplibHardenedMemCopy(pwszDst, pawcArgs, cwcArgs * sizeof(RTUTF16));
    14441450        pwszDst += cwcArgs;
    14451451    }
     
    21152121 * Does the actually respawning.
    21162122 *
    2117  * @returns Exit code (if we get that far).
     2123 * @returns Never, will call exit or raise fatal error.
     2124 * @param   iWhich              Which respawn we're to check for, 1 being the
     2125 *                              first one, and 2 the second and final.
     2126 *
     2127 * @todo    Split up this function.
    21182128 */
    21192129static int supR3HardenedWinDoReSpawn(int iWhich)
    21202130{
     2131    NTSTATUS                        rcNt;
     2132    PPEB                            pPeb              = NtCurrentPeb();
     2133    PRTL_USER_PROCESS_PARAMETERS    pParentProcParams = pPeb->ProcessParameters;
     2134
    21212135    SUPR3HARDENED_ASSERT(g_cSuplibHardenedWindowsMainCalls == 1);
    21222136
     
    21502164
    21512165    SiEx.StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
    2152     SiEx.StartupInfo.hStdInput  = GetStdHandle(STD_INPUT_HANDLE);
    2153     SiEx.StartupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
    2154     SiEx.StartupInfo.hStdError  = GetStdHandle(STD_ERROR_HANDLE);
     2166    SiEx.StartupInfo.hStdInput  = pParentProcParams->StandardInput;
     2167    SiEx.StartupInfo.hStdOutput = pParentProcParams->StandardOutput;
     2168    SiEx.StartupInfo.hStdError  = pParentProcParams->StandardError;
    21552169
    21562170    /*
     
    22052219
    22062220    /** @todo this doesn't work. :-( */
    2207     PPEB                            pPeb              = NtCurrentPeb();
    2208     PRTL_USER_PROCESS_PARAMETERS    pParentProcParams = pPeb->ProcessParameters;
    22092221    pProcParams->ConsoleHandle  = pParentProcParams->ConsoleHandle;
    22102222    pProcParams->ConsoleFlags   = pParentProcParams->ConsoleFlags;
     
    22142226
    22152227    RTL_USER_PROCESS_INFORMATION ProcessInfoNt = { sizeof(ProcessInfoNt) };
    2216     NTSTATUS rcNt = RtlCreateUserProcess(&g_SupLibHardenedExeNtPath.UniStr,
    2217                                          OBJ_INHERIT | OBJ_CASE_INSENSITIVE /*Attributes*/,
    2218                                          pProcParams,
    2219                                          NULL, //&ProcessSecAttrs,
    2220                                          NULL, //&ThreadSecAttrs,
    2221                                          NtCurrentProcess() /* ParentProcess */,
    2222                                          FALSE /*fInheritHandles*/,
    2223                                          NULL /* DebugPort */,
    2224                                          NULL /* ExceptionPort */,
    2225                                          &ProcessInfoNt);
     2228    rcNt = RtlCreateUserProcess(&g_SupLibHardenedExeNtPath.UniStr,
     2229                                OBJ_INHERIT | OBJ_CASE_INSENSITIVE /*Attributes*/,
     2230                                pProcParams,
     2231                                NULL, //&ProcessSecAttrs,
     2232                                NULL, //&ThreadSecAttrs,
     2233                                NtCurrentProcess() /* ParentProcess */,
     2234                                FALSE /*fInheritHandles*/,
     2235                                NULL /* DebugPort */,
     2236                                NULL /* ExceptionPort */,
     2237                                &ProcessInfoNt);
    22262238    if (!NT_SUCCESS(rcNt))
    22272239        supR3HardenedFatalMsg("supR3HardenedWinReSpawn", kSupInitOp_Misc, VERR_INVALID_NAME,
     
    22592271    SUPR3HARDENED_ASSERT_NT_SUCCESS(NtClose(hThread));
    22602272
     2273    PROCESS_BASIC_INFORMATION BasicInfo;
    22612274    HANDLE hProcWait;
    2262     DWORD dwRights = SYNCHRONIZE;
     2275    ULONG fRights = SYNCHRONIZE;
    22632276    if (g_uNtVerCombined >= SUP_MAKE_NT_VER_SIMPLE(6, 0)) /* Introduced in Vista. */
    2264         dwRights |= PROCESS_QUERY_LIMITED_INFORMATION;
     2277        fRights |= PROCESS_QUERY_LIMITED_INFORMATION;
    22652278    else
    2266         dwRights |= PROCESS_QUERY_INFORMATION;
    2267     if (!DuplicateHandle(GetCurrentProcess(),
    2268                          hProcess,
    2269                          GetCurrentProcess(),
    2270                          &hProcWait,
    2271                          SYNCHRONIZE,
    2272                          FALSE /*fInheritHandle*/,
    2273                          0))
    2274     {
    2275         /* This is unacceptable, kill the process. */
     2279        fRights |= PROCESS_QUERY_INFORMATION;
     2280    rcNt = NtDuplicateObject(NtCurrentProcess(), hProcess,
     2281                             NtCurrentProcess(), &hProcWait,
     2282                             fRights, 0 /*HandleAttributes*/, 0);
     2283    if (rcNt == STATUS_ACCESS_DENIED)
     2284        rcNt = NtDuplicateObject(NtCurrentProcess(), hProcess,
     2285                                 NtCurrentProcess(), &hProcWait,
     2286                                 SYNCHRONIZE, 0 /*HandleAttributes*/, 0);
     2287    if (!NT_SUCCESS(rcNt))
     2288    {
     2289        /* Failure is unacceptable, kill the process. */
    22762290        DWORD dwErr = GetLastError();
    22772291        NtTerminateProcess(hProcess, RTEXITCODE_FAILURE);
    2278         supR3HardenedError(dwErr, false /*fFatal*/, "DuplicateHandle failed on child process handle: %u\n", dwErr);
    2279 
    2280         DWORD dwExit;
    2281         BOOL fExitOk = GetExitCodeProcess(hProcess, &dwExit)
    2282                     && dwExit != STILL_ACTIVE;
     2292        supR3HardenedError(dwErr, false /*fFatal*/, "NtDuplicateObject failed on child process handle: %u\n", dwErr);
     2293
     2294        NTSTATUS rcNtExit = NtQueryInformationProcess(hProcess, ProcessBasicInformation, &BasicInfo, sizeof(BasicInfo), NULL);
     2295        bool fExitOk = NT_SUCCESS(rcNtExit) && BasicInfo.ExitStatus != STATUS_PENDING;
    22832296        if (!fExitOk)
    22842297        {
     2298            NTSTATUS rcNtWait;
    22852299            DWORD dwStartTick = GetTickCount();
    2286             DWORD dwWait;
    22872300            do
    22882301            {
    22892302                NtTerminateProcess(hProcess, DBG_TERMINATE_PROCESS);
    2290                 dwWait  = WaitForSingleObject(hProcess, 1000);
    2291                 fExitOk = GetExitCodeProcess(hProcess, &dwExit)
    2292                        && dwExit != STILL_ACTIVE;
     2303
     2304                LARGE_INTEGER Timeout;
     2305                Timeout.QuadPart = -20000000; /* 2 second */
     2306                rcNtWait = NtWaitForSingleObject(hProcess, TRUE /*Alertable*/, &Timeout);
     2307
     2308                rcNtExit = NtQueryInformationProcess(hProcess, ProcessBasicInformation, &BasicInfo, sizeof(BasicInfo), NULL);
     2309                fExitOk = NT_SUCCESS(rcNtExit) && BasicInfo.ExitStatus != STATUS_PENDING;
    22932310            } while (   !fExitOk
    2294                      && (dwWait == WAIT_TIMEOUT || dwWait == WAIT_IO_COMPLETION)
     2311                     && (   rcNtWait == STATUS_TIMEOUT
     2312                         || rcNtWait == STATUS_USER_APC
     2313                         || rcNtWait == STATUS_ALERTED)
    22952314                     && GetTickCount() - dwStartTick < 60 * 1000);
    22962315            if (fExitOk)
    22972316                supR3HardenedError(dwErr, false /*fFatal*/,
    2298                                    "DuplicateHandle failed and we failed to kill child: dwErr=%u dwWait=%u err=%u hProcess=%p\n",
    2299                                    dwErr, dwWait, GetLastError(), hProcess);
     2317                                   "NtDuplicateObject failed and we failed to kill child: rcNt=%u rcNtWait=%u hProcess=%p\n",
     2318                                   rcNt, rcNtWait, hProcess);
    23002319        }
    23012320        supR3HardenedFatalMsg("supR3HardenedWinReSpawn", kSupInitOp_Misc, VERR_INVALID_NAME,
    2302                               "DuplicateHandle failed on child process handle: %u\n", dwErr);
     2321                              "NtDuplicateObject failed on child process handle: %#x\n", rcNt);
    23032322    }
    23042323
     
    23072326
    23082327    /*
    2309      * Wait for the process to terminate and proxy the termination code.
    2310      */
    2311     for (;;)
    2312     {
    2313         SetLastError(NO_ERROR);
    2314         DWORD dwWait = WaitForSingleObject(hProcWait, INFINITE);
    2315         if (   dwWait == WAIT_OBJECT_0
    2316             || dwWait == WAIT_ABANDONED_0)
    2317             break;
    2318         if (   dwWait != WAIT_TIMEOUT
    2319             && dwWait != WAIT_IO_COMPLETION)
    2320             supR3HardenedFatal("WaitForSingleObject returned %#x (last error %#x)\n", dwWait, GetLastError());
    2321     }
    2322 
    2323     DWORD dwExit;
    2324     if (   !GetExitCodeProcess(hProcWait, &dwExit)
    2325         || dwExit == STILL_ACTIVE)
    2326         dwExit = RTEXITCODE_FAILURE;
     2328     * If this is the middle process, wait for both parent and child to quit.
     2329     */
     2330    HANDLE hParent = NULL;
     2331    if (iWhich > 1)
     2332    {
     2333        rcNt = NtQueryInformationProcess(NtCurrentProcess(), ProcessBasicInformation, &BasicInfo, sizeof(BasicInfo), NULL);
     2334        if (NT_SUCCESS(rcNt))
     2335        {
     2336            OBJECT_ATTRIBUTES ObjAttr;
     2337            InitializeObjectAttributes(&ObjAttr, NULL, 0, NULL /*hRootDir*/, NULL /*pSecDesc*/);
     2338
     2339            CLIENT_ID ClientId;
     2340            ClientId.UniqueProcess = (HANDLE)BasicInfo.InheritedFromUniqueProcessId;
     2341            ClientId.UniqueThread  = NULL;
     2342
     2343            rcNt = NtOpenProcess(&hParent, SYNCHRONIZE | PROCESS_QUERY_INFORMATION, &ObjAttr, &ClientId);
     2344        }
     2345#ifdef DEBUG
     2346        SUPR3HARDENED_ASSERT_NT_SUCCESS(rcNt);
     2347#endif
     2348    }
     2349
     2350    if (hParent != NULL)
     2351    {
     2352        for (;;)
     2353        {
     2354            HANDLE ahHandles[2] = { hProcWait, hParent };
     2355            rcNt = NtWaitForMultipleObjects(2, &ahHandles[0], WaitAnyObject, TRUE /*Alertable*/, NULL /*pTimeout*/);
     2356            if (   rcNt == STATUS_WAIT_0
     2357                || rcNt == STATUS_WAIT_0 + 1
     2358                || rcNt == STATUS_ABANDONED_WAIT_0
     2359                || rcNt == STATUS_ABANDONED_WAIT_0 + 1)
     2360                break;
     2361            if (   rcNt != STATUS_TIMEOUT
     2362                && rcNt != STATUS_USER_APC
     2363                && rcNt != STATUS_ALERTED)
     2364                supR3HardenedFatal("NtWaitForMultipleObjects returned %#x\n", rcNt);
     2365        }
     2366        NtClose(hParent);
     2367    }
     2368    else
     2369    {
     2370        /*
     2371         * Wait for the process to terminate.
     2372         */
     2373        for (;;)
     2374        {
     2375            rcNt = NtWaitForSingleObject(hProcWait, TRUE /*Alertable*/, NULL /*pTimeout*/);
     2376            if (   rcNt == STATUS_WAIT_0
     2377                || rcNt == STATUS_ABANDONED_WAIT_0)
     2378                break;
     2379            if (   rcNt != STATUS_TIMEOUT
     2380                && rcNt != STATUS_USER_APC
     2381                && rcNt != STATUS_ALERTED)
     2382                supR3HardenedFatal("NtWaitForSingleObject returned %#x\n", rcNt);
     2383        }
     2384    }
     2385
     2386    /*
     2387     * Proxy the termination code of the child, if it exited already.
     2388     */
     2389    rcNt = NtQueryInformationProcess(hProcWait, ProcessBasicInformation, &BasicInfo, sizeof(BasicInfo), NULL);
     2390    if (   !NT_SUCCESS(rcNt)
     2391        || BasicInfo.ExitStatus == STATUS_PENDING)
     2392        BasicInfo.ExitStatus = RTEXITCODE_FAILURE;
    23272393
    23282394    NtClose(hProcWait);
    2329     suplibHardenedExit((RTEXITCODE)dwExit);
     2395    suplibHardenedExit((RTEXITCODE)BasicInfo.ExitStatus);
    23302396}
    23312397
     
    25872653 *
    25882654 * @returns Pointer to the argument array.
    2589  * @param   pwszCmdLine         The UTF-16 windows command line to parse.
     2655 * @param   pawcCmdLine         The UTF-16 windows command line to parse.
     2656 * @param   cwcCmdLine          The length of the command line.
    25902657 * @param   pcArgs              Where to return the number of arguments.
    25912658 */
    2592 static char **suplibCommandLineToArgvWStub(PCRTUTF16 pwszCmdLine, int *pcArgs)
     2659static char **suplibCommandLineToArgvWStub(PCRTUTF16 pawcCmdLine, size_t cwcCmdLine, int *pcArgs)
    25932660{
    25942661    /*
    25952662     * Convert the command line string to UTF-8.
    25962663     */
    2597     char *pszCmdLine;
    2598     SUPR3HARDENED_ASSERT(RT_SUCCESS(RTUtf16ToUtf8(pwszCmdLine, &pszCmdLine)));
     2664    char *pszCmdLine = NULL;
     2665    SUPR3HARDENED_ASSERT(RT_SUCCESS(RTUtf16ToUtf8Ex(pawcCmdLine, cwcCmdLine, &pszCmdLine, 0, NULL)));
    25992666
    26002667    /*
     
    27252792     * Convert the arguments to UTF-8 and call the C/C++ main function.
    27262793     */
    2727     int    cArgs;
    2728     char **papszArgs = suplibCommandLineToArgvWStub(GetCommandLineW(), &cArgs);
     2794    PUNICODE_STRING pCmdLineStr = &NtCurrentPeb()->ProcessParameters->CommandLine;
     2795    int             cArgs;
     2796    char **papszArgs = suplibCommandLineToArgvWStub(pCmdLineStr->Buffer, pCmdLineStr->Length / sizeof(WCHAR), &cArgs);
    27292797
    27302798    rcExit = (RTEXITCODE)main(cArgs, papszArgs, NULL);
  • trunk/src/VBox/Runtime/r3/win/ntdll-mini-implib.def

    r52139 r52163  
    4545    NtOpenProcess                         ;;= _NtOpenProcess@16
    4646    NtOpenProcessToken                    ;;= _NtOpenProcessToken@12
     47    NtOpenThread                          ;;= _NtOpenThread@16
    4748    NtOpenThreadToken                     ;;= _NtOpenThreadToken@16
    4849    NtProtectVirtualMemory                ;;= _NtProtectVirtualMemory@20
     
    7374    NtUnmapViewOfSection                  ;;= _NtUnmapViewOfSection@8
    7475    NtWaitForSingleObject                 ;;= _NtWaitForSingleObject@12
     76    NtWaitForMultipleObjects              ;;= _NtWaitForMultipleObjects@20
    7577    NtWriteFile                           ;;= _NtWriteFile@36
    7678    NtWriteVirtualMemory                  ;;= _NtWriteVirtualMemory@20
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette