Changeset 99483 in vbox
- Timestamp:
- Apr 20, 2023 10:16:10 AM (20 months ago)
- Location:
- trunk/src/VBox/Runtime
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/posix/process-creation-posix.cpp
r99109 r99483 1713 1713 return VERR_PROC_DETACH_NOT_SUPPORTED; 1714 1714 #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. */ 1719 1724 1720 1725 /* -
trunk/src/VBox/Runtime/r3/win/process-win.cpp
r99109 r99483 2262 2262 const char *pszPassword, void *pvExtraData, PRTPROCESS phProcess) 2263 2263 { 2264 int rc;2265 2266 2264 /* 2267 2265 * Input validation … … 2279 2277 2280 2278 /* 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 2281 2285 uint32_t idDesiredSession = UINT32_MAX; 2282 2286 if ( (fFlags & (RTPROC_FLAGS_DESIRED_SESSION_ID | RTPROC_FLAGS_SERVICE)) 2283 2287 == (RTPROC_FLAGS_DESIRED_SESSION_ID | RTPROC_FLAGS_SERVICE)) 2284 2288 { 2285 AssertReturn(!(fFlags & RTPROC_FLAGS_CWD), VERR_INVALID_PARAMETER); 2289 AssertReturn(!(fFlags & ( RTPROC_FLAGS_TOKEN_SUPPLIED 2290 | RTPROC_FLAGS_CWD)), 2291 VERR_INVALID_PARAMETER); 2286 2292 AssertPtrReturn(pvExtraData, VERR_INVALID_POINTER); 2287 2293 idDesiredSession = *(uint32_t *)pvExtraData; … … 2289 2295 else 2290 2296 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 } 2291 2305 2292 2306 HANDLE hUserToken = NULL; … … 2297 2311 * Initialize the globals. 2298 2312 */ 2299 rc = RTOnce(&g_rtProcWinInitOnce, rtProcWinInitOnce, NULL);2313 int rc = RTOnce(&g_rtProcWinInitOnce, rtProcWinInitOnce, NULL); 2300 2314 AssertRCReturn(rc, rc); 2301 2315 if ( pszAsUser … … 2436 2450 !(fFlags & RTPROC_FLAGS_UNQUOTED_ARGS) 2437 2451 ? RTGETOPTARGV_CNV_QUOTE_MS_CRT : RTGETOPTARGV_CNV_UNQUOTED); 2438 PRTUTF16 pwszExec = NULL;2439 2452 if (RT_SUCCESS(rc)) 2453 { 2454 PRTUTF16 pwszExec = NULL; 2440 2455 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)) 2464 2462 { 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 } 2468 2529 if (RT_SUCCESS(rc)) 2469 2530 { 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) 2500 2533 { 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; 2508 2543 } 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 close2519 * 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);2523 2544 else 2524 2545 CloseHandle(ProcInfo.hProcess); 2525 *phProcess = ProcInfo.dwProcessId;2546 rc = VINF_SUCCESS; 2526 2547 } 2527 else 2528 CloseHandle(ProcInfo.hProcess); 2529 rc = VINF_SUCCESS; 2548 2549 RTPathWinFree(pwszCwd); 2530 2550 } 2531 }2532 RTPathWinFree(pwszExec);2533 RTPathWinFree(pwszCwd);2534 RTUtf16Free(pwszCmdLine);2551 RTPathWinFree(pwszExec); 2552 } 2553 RTUtf16Free(pwszCmdLine); 2554 } 2535 2555 2536 2556 if (g_pfnSetHandleInformation) -
trunk/src/VBox/Runtime/testcase/tstRTProcCreateEx.cpp
r99151 r99483 107 107 const char *pszCWD = argv[2]; 108 108 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 109 114 /* Validate if we really are in the CWD the parent told us. */ 110 115 char szCWD[RTPATH_MAX]; … … 155 160 g_szExecName, 156 161 "--testcase-child-cwd", 157 "< invalid-cwd>",162 "<cwd-not-specified>", 158 163 pszAsUser, 159 164 NULL … … 171 176 VERR_INVALID_PARAMETER); 172 177 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 173 200 /* RTPROC_FLAGS_CWD set, but CWD missing as pvExtradata. */ 174 201 fFlags = RTPROC_FLAGS_CWD; … … 176 203 NULL, NULL, NULL, pszAsUser, pszPassword, 177 204 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); 183 206 184 207 char szCWD[RTPATH_MAX]; … … 193 216 (void *)szCWD /* pvExtraData (CWD) */, &hProc), 194 217 VINF_SUCCESS); 218 RTPROCSTATUS ProcStatus = { -1, RTPROCEXITREASON_ABEND }; 195 219 RTTESTI_CHECK_RC(RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &ProcStatus), VINF_SUCCESS); 196 220 if (ProcStatus.enmReason != RTPROCEXITREASON_NORMAL || ProcStatus.iStatus != 0)
Note:
See TracChangeset
for help on using the changeset viewer.