VirtualBox

Changeset 99483 in vbox


Ignore:
Timestamp:
Apr 20, 2023 10:16:10 AM (20 months ago)
Author:
vboxsync
Message:

IPRT/RTProcCreateEx: More fixes for the initial patch supplied; also tweaked the testcases a little. bugref:8053

Location:
trunk/src/VBox/Runtime
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/posix/process-creation-posix.cpp

    r99109 r99483  
    17131713        return VERR_PROC_DETACH_NOT_SUPPORTED;
    17141714#endif
    1715     AssertReturn(pvExtraData == NULL || (fFlags & (RTPROC_FLAGS_DESIRED_SESSION_ID | RTPROC_FLAGS_CWD)),
    1716                  VERR_INVALID_PARAMETER);
    1717     AssertReturn((fFlags & (RTPROC_FLAGS_DESIRED_SESSION_ID | RTPROC_FLAGS_CWD)) != (RTPROC_FLAGS_DESIRED_SESSION_ID | RTPROC_FLAGS_CWD),
    1718                  VERR_INVALID_PARAMETER);
     1715
     1716    /* Extra data: */
     1717    if (fFlags & RTPROC_FLAGS_CWD)
     1718    {
     1719        AssertPtrReturn(pvExtraData, VERR_INVALID_POINTER);
     1720    }
     1721    else
     1722        AssertReturn(pvExtraData == NULL, VERR_INVALID_PARAMETER);
     1723    /* Note: Windows-specific flags will be quietly ignored. */
    17191724
    17201725    /*
  • trunk/src/VBox/Runtime/r3/win/process-win.cpp

    r99109 r99483  
    22622262                               const char *pszPassword, void *pvExtraData, PRTPROCESS phProcess)
    22632263{
    2264     int rc;
    2265 
    22662264    /*
    22672265     * Input validation
     
    22792277
    22802278    /* Extra data: */
     2279    AssertReturn(   pvExtraData == NULL
     2280                 || (fFlags & (   RTPROC_FLAGS_DESIRED_SESSION_ID
     2281                               | RTPROC_FLAGS_TOKEN_SUPPLIED
     2282                               | RTPROC_FLAGS_CWD)),
     2283                 VERR_INVALID_PARAMETER);
     2284
    22812285    uint32_t idDesiredSession = UINT32_MAX;
    22822286    if (   (fFlags & (RTPROC_FLAGS_DESIRED_SESSION_ID | RTPROC_FLAGS_SERVICE))
    22832287        ==           (RTPROC_FLAGS_DESIRED_SESSION_ID | RTPROC_FLAGS_SERVICE))
    22842288    {
    2285         AssertReturn(!(fFlags & RTPROC_FLAGS_CWD), VERR_INVALID_PARAMETER);
     2289        AssertReturn(!(fFlags & (  RTPROC_FLAGS_TOKEN_SUPPLIED
     2290                                 | RTPROC_FLAGS_CWD)),
     2291                     VERR_INVALID_PARAMETER);
    22862292        AssertPtrReturn(pvExtraData, VERR_INVALID_POINTER);
    22872293        idDesiredSession = *(uint32_t *)pvExtraData;
     
    22892295    else
    22902296        AssertReturn(!(fFlags & RTPROC_FLAGS_DESIRED_SESSION_ID), VERR_INVALID_FLAGS);
     2297
     2298    if (fFlags & RTPROC_FLAGS_CWD)
     2299    {
     2300        AssertReturn(!(fFlags & (  RTPROC_FLAGS_DESIRED_SESSION_ID
     2301                                 | RTPROC_FLAGS_TOKEN_SUPPLIED)),
     2302                     VERR_INVALID_PARAMETER);
     2303        AssertPtrReturn(pvExtraData, VERR_INVALID_POINTER);
     2304    }
    22912305
    22922306    HANDLE hUserToken = NULL;
     
    22972311     * Initialize the globals.
    22982312     */
    2299     rc = RTOnce(&g_rtProcWinInitOnce, rtProcWinInitOnce, NULL);
     2313    int rc = RTOnce(&g_rtProcWinInitOnce, rtProcWinInitOnce, NULL);
    23002314    AssertRCReturn(rc, rc);
    23012315    if (   pszAsUser
     
    24362450                                       !(fFlags & RTPROC_FLAGS_UNQUOTED_ARGS)
    24372451                                       ? RTGETOPTARGV_CNV_QUOTE_MS_CRT : RTGETOPTARGV_CNV_UNQUOTED);
    2438     PRTUTF16 pwszExec = NULL;
    24392452    if (RT_SUCCESS(rc))
     2453    {
     2454        PRTUTF16 pwszExec = NULL;
    24402455        rc = RTPathWinFromUtf8(&pwszExec, pszExec, 0 /*fFlags*/);
    2441     PRTUTF16 pwszCwd = NULL;
    2442     if (RT_SUCCESS(rc) && (fFlags & RTPROC_FLAGS_CWD))
    2443         rc = RTPathWinFromUtf8(&pwszCwd, (const char *)pvExtraData, 0);
    2444     if (RT_SUCCESS(rc))
    2445     {
    2446             /*
    2447              * Get going...
    2448              */
    2449             PROCESS_INFORMATION ProcInfo;
    2450             RT_ZERO(ProcInfo);
    2451             DWORD dwCreationFlags = CREATE_UNICODE_ENVIRONMENT;
    2452             if (fFlags & RTPROC_FLAGS_DETACHED)
    2453                 dwCreationFlags |= DETACHED_PROCESS;
    2454             if (fFlags & RTPROC_FLAGS_NO_WINDOW)
    2455                 dwCreationFlags |= CREATE_NO_WINDOW;
    2456 
    2457             /*
    2458              * Only use the normal CreateProcess stuff if we have no user name
    2459              * and we are not running from a (Windows) service. Otherwise use
    2460              * the more advanced version in rtProcWinCreateAsUser().
    2461              */
    2462             if (   pszAsUser == NULL
    2463                 && !(fFlags & (RTPROC_FLAGS_SERVICE | RTPROC_FLAGS_AS_IMPERSONATED_TOKEN | RTPROC_FLAGS_TOKEN_SUPPLIED)))
     2456        if (RT_SUCCESS(rc))
     2457        {
     2458            PRTUTF16 pwszCwd = NULL;
     2459            if (fFlags & RTPROC_FLAGS_CWD)
     2460                rc = RTPathWinFromUtf8(&pwszCwd, (const char *)pvExtraData, 0);
     2461            if (RT_SUCCESS(rc))
    24642462            {
    2465                 /* Create the environment block first. */
    2466                 PRTUTF16 pwszzBlock;
    2467                 rc = rtProcWinCreateEnvBlockAndFindExe(fFlags, hEnv, pszExec, &pwszzBlock, &pwszExec);
     2463                /*
     2464                 * Get going...
     2465                 */
     2466                PROCESS_INFORMATION ProcInfo;
     2467                RT_ZERO(ProcInfo);
     2468                DWORD dwCreationFlags = CREATE_UNICODE_ENVIRONMENT;
     2469                if (fFlags & RTPROC_FLAGS_DETACHED)
     2470                    dwCreationFlags |= DETACHED_PROCESS;
     2471                if (fFlags & RTPROC_FLAGS_NO_WINDOW)
     2472                    dwCreationFlags |= CREATE_NO_WINDOW;
     2473
     2474                /*
     2475                 * Only use the normal CreateProcess stuff if we have no user name
     2476                 * and we are not running from a (Windows) service. Otherwise use
     2477                 * the more advanced version in rtProcWinCreateAsUser().
     2478                 */
     2479                if (   pszAsUser == NULL
     2480                    && !(fFlags & (RTPROC_FLAGS_SERVICE | RTPROC_FLAGS_AS_IMPERSONATED_TOKEN | RTPROC_FLAGS_TOKEN_SUPPLIED)))
     2481                {
     2482                    /* Create the environment block first. */
     2483                    PRTUTF16 pwszzBlock;
     2484                    rc = rtProcWinCreateEnvBlockAndFindExe(fFlags, hEnv, pszExec, &pwszzBlock, &pwszExec);
     2485                    if (RT_SUCCESS(rc))
     2486                    {
     2487                        if (CreateProcessW(pwszExec,
     2488                                           pwszCmdLine,
     2489                                           NULL,         /* pProcessAttributes */
     2490                                           NULL,         /* pThreadAttributes */
     2491                                           TRUE,         /* fInheritHandles */
     2492                                           dwCreationFlags,
     2493                                           pwszzBlock,
     2494                                           pwszCwd,       /* pCurrentDirectory */
     2495                                           &StartupInfo,
     2496                                           &ProcInfo))
     2497                            rc = VINF_SUCCESS;
     2498                        else
     2499                            rc = RTErrConvertFromWin32(GetLastError());
     2500                        RTEnvFreeUtf16Block(pwszzBlock);
     2501                    }
     2502                }
     2503                else
     2504                {
     2505                    /*
     2506                     * Convert the additional parameters and use a helper
     2507                     * function to do the actual work.
     2508                     */
     2509                    PRTUTF16 pwszUser = NULL;
     2510                    if (pszAsUser)
     2511                        rc = RTStrToUtf16(pszAsUser, &pwszUser);
     2512                    if (RT_SUCCESS(rc))
     2513                    {
     2514                        PRTUTF16 pwszPassword;
     2515                        rc = RTStrToUtf16(pszPassword ? pszPassword : "", &pwszPassword);
     2516                        if (RT_SUCCESS(rc))
     2517                        {
     2518                            rc = rtProcWinCreateAsUser(pwszUser, pwszPassword, &pwszExec, pwszCmdLine, hEnv, dwCreationFlags,
     2519                                                       &StartupInfo, &ProcInfo, fFlags, pszExec, idDesiredSession,
     2520                                                       hUserToken, pwszCwd);
     2521
     2522                            if (pwszPassword && *pwszPassword)
     2523                                RTMemWipeThoroughly(pwszPassword, RTUtf16Len(pwszPassword), 5);
     2524                            RTUtf16Free(pwszPassword);
     2525                        }
     2526                        RTUtf16Free(pwszUser);
     2527                    }
     2528                }
    24682529                if (RT_SUCCESS(rc))
    24692530                {
    2470                     if (CreateProcessW(pwszExec,
    2471                                        pwszCmdLine,
    2472                                        NULL,         /* pProcessAttributes */
    2473                                        NULL,         /* pThreadAttributes */
    2474                                        TRUE,         /* fInheritHandles */
    2475                                        dwCreationFlags,
    2476                                        pwszzBlock,
    2477                                        pwszCwd,       /* pCurrentDirectory */
    2478                                        &StartupInfo,
    2479                                        &ProcInfo))
    2480                         rc = VINF_SUCCESS;
    2481                     else
    2482                         rc = RTErrConvertFromWin32(GetLastError());
    2483                     RTEnvFreeUtf16Block(pwszzBlock);
    2484                 }
    2485             }
    2486             else
    2487             {
    2488                 /*
    2489                  * Convert the additional parameters and use a helper
    2490                  * function to do the actual work.
    2491                  */
    2492                 PRTUTF16 pwszUser = NULL;
    2493                 if (pszAsUser)
    2494                     rc = RTStrToUtf16(pszAsUser, &pwszUser);
    2495                 if (RT_SUCCESS(rc))
    2496                 {
    2497                     PRTUTF16 pwszPassword;
    2498                     rc = RTStrToUtf16(pszPassword ? pszPassword : "", &pwszPassword);
    2499                     if (RT_SUCCESS(rc))
     2531                    CloseHandle(ProcInfo.hThread);
     2532                    if (phProcess)
    25002533                    {
    2501                         rc = rtProcWinCreateAsUser(pwszUser, pwszPassword, &pwszExec, pwszCmdLine, hEnv, dwCreationFlags,
    2502                                                    &StartupInfo, &ProcInfo, fFlags, pszExec, idDesiredSession,
    2503                                                    hUserToken, pwszCwd);
    2504 
    2505                         if (pwszPassword && *pwszPassword)
    2506                             RTMemWipeThoroughly(pwszPassword, RTUtf16Len(pwszPassword), 5);
    2507                         RTUtf16Free(pwszPassword);
     2534                        /*
     2535                         * Add the process to the child process list so RTProcWait can reuse and close
     2536                         * the process handle, unless, of course, the caller has no intention waiting.
     2537                         */
     2538                        if (!(fFlags & RTPROC_FLAGS_NO_WAIT))
     2539                            rtProcWinAddPid(ProcInfo.dwProcessId, ProcInfo.hProcess);
     2540                        else
     2541                            CloseHandle(ProcInfo.hProcess);
     2542                        *phProcess = ProcInfo.dwProcessId;
    25082543                    }
    2509                     RTUtf16Free(pwszUser);
    2510                 }
    2511             }
    2512             if (RT_SUCCESS(rc))
    2513             {
    2514                 CloseHandle(ProcInfo.hThread);
    2515                 if (phProcess)
    2516                 {
    2517                     /*
    2518                      * Add the process to the child process list so RTProcWait can reuse and close
    2519                      * the process handle, unless, of course, the caller has no intention waiting.
    2520                      */
    2521                     if (!(fFlags & RTPROC_FLAGS_NO_WAIT))
    2522                         rtProcWinAddPid(ProcInfo.dwProcessId, ProcInfo.hProcess);
    25232544                    else
    25242545                        CloseHandle(ProcInfo.hProcess);
    2525                     *phProcess = ProcInfo.dwProcessId;
     2546                    rc = VINF_SUCCESS;
    25262547                }
    2527                 else
    2528                     CloseHandle(ProcInfo.hProcess);
    2529                 rc = VINF_SUCCESS;
     2548
     2549                RTPathWinFree(pwszCwd);
    25302550            }
    2531     }
    2532     RTPathWinFree(pwszExec);
    2533     RTPathWinFree(pwszCwd);
    2534     RTUtf16Free(pwszCmdLine);
     2551            RTPathWinFree(pwszExec);
     2552        }
     2553        RTUtf16Free(pwszCmdLine);
     2554    }
    25352555
    25362556    if (g_pfnSetHandleInformation)
  • trunk/src/VBox/Runtime/testcase/tstRTProcCreateEx.cpp

    r99151 r99483  
    107107    const char *pszCWD = argv[2];
    108108
     109    RTStrmPrintf(g_pStdOut, "childcwd: Called with CWD '%s'\n", pszCWD);
     110
     111    if (!RTStrICmp(pszCWD, "<cwd-not-specified>")) /* Bail out early if no CWD has been explicitly specified. */
     112        return RTEXITCODE_SUCCESS;
     113
    109114    /* Validate if we really are in the CWD the parent told us. */
    110115    char szCWD[RTPATH_MAX];
     
    155160        g_szExecName,
    156161        "--testcase-child-cwd",
    157         "<invalid-cwd>",
     162        "<cwd-not-specified>",
    158163        pszAsUser,
    159164        NULL
     
    171176                          VERR_INVALID_PARAMETER);
    172177
     178    /* Invalid flag combinations. Windows flags ignored elsewhere. */
     179#ifdef RT_OS_WINDOWS
     180    int rc = VERR_INVALID_PARAMETER;
     181#else
     182    int rc = VERR_INVALID_POINTER; /* Due to missing pvExtraData. */
     183#endif
     184    fFlags = RTPROC_FLAGS_CWD | RTPROC_FLAGS_DESIRED_SESSION_ID | RTPROC_FLAGS_SERVICE;
     185    RTTESTI_CHECK_RC_RETV(RTProcCreateEx(g_szExecName, apszArgs, RTENV_DEFAULT, fFlags,
     186                                         NULL, NULL, NULL, pszAsUser, pszPassword,
     187                                         NULL, &hProc), rc);
     188
     189    /* Windows-only flags. Ignored elsewhere. */
     190#ifdef RT_OS_WINDOWS
     191    rc = VERR_INVALID_POINTER;
     192#else
     193    rc = VINF_SUCCESS;
     194#endif
     195    fFlags = RTPROC_FLAGS_DESIRED_SESSION_ID | RTPROC_FLAGS_SERVICE;
     196    RTTESTI_CHECK_RC_RETV(RTProcCreateEx(g_szExecName, apszArgs, RTENV_DEFAULT, fFlags,
     197                                         NULL, NULL, NULL, pszAsUser, pszPassword,
     198                                         NULL, &hProc), rc);
     199
    173200    /* RTPROC_FLAGS_CWD set, but CWD missing as pvExtradata. */
    174201    fFlags = RTPROC_FLAGS_CWD;
     
    176203                                         NULL, NULL, NULL, pszAsUser, pszPassword,
    177204                                         NULL, &hProc),
    178                           VINF_SUCCESS);
    179 
    180     /* CWD is "<invalid-cwd>" from above, should fail. */
    181     RTPROCSTATUS ProcStatus = { -1, RTPROCEXITREASON_ABEND };
    182     RTTESTI_CHECK_RC(RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &ProcStatus), VINF_SUCCESS);
     205                          VERR_INVALID_POINTER);
    183206
    184207    char szCWD[RTPATH_MAX];
     
    193216                                         (void *)szCWD /* pvExtraData (CWD) */, &hProc),
    194217                          VINF_SUCCESS);
     218    RTPROCSTATUS ProcStatus = { -1, RTPROCEXITREASON_ABEND };
    195219    RTTESTI_CHECK_RC(RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &ProcStatus), VINF_SUCCESS);
    196220    if (ProcStatus.enmReason != RTPROCEXITREASON_NORMAL || ProcStatus.iStatus != 0)
Note: See TracChangeset for help on using the changeset viewer.

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