Changeset 95274 in vbox
- Timestamp:
- Jun 14, 2022 10:48:33 AM (2 years ago)
- Location:
- trunk
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Config.kmk
r95270 r95274 779 779 VBOX_WITH_SECURELABEL = 1 780 780 endif 781 # Start VBoxSVC in windows session 0 (services session). 782 VBOX_WITH_VBOXSVC_SESSION_0 = 781 783 # The headless frontend. 782 784 VBOX_WITH_HEADLESS = 1 -
trunk/include/iprt/process.h
r93115 r95274 230 230 /** For use with RTPROC_FLAGS_SERVICE to specify a desired session ID 231 231 * (Windows only, ignored elsewhere). The @a pvExtraData argument points to 232 * a uint32_t containing the session ID, UINT32_MAX means any session. */ 232 * a uint32_t containing the session ID, UINT32_MAX means any session. 233 * Can not be set with RTPROC_FLAGS_TOKEN_SUPPLIED */ 233 234 #define RTPROC_FLAGS_DESIRED_SESSION_ID RT_BIT(11) 234 235 /** This is a modifier to RTPROC_FLAGS_PROFILE on unix systems that makes it … … 238 239 * This is ignored on Windows as it is using UTF-16. */ 239 240 #define RTPROC_FLAGS_UTF8_ARGV RT_BIT_32(13) 241 /** Create process using supplied token. The @a pvExtraData argument points to 242 * a HANDLE containing the token used as user credentials for process creation. 243 * Can not be set with RTPROC_FLAGS_DESIRED_SESSION_ID. 244 * Windows only flag, ignored everywhere else. */ 245 #define RTPROC_FLAGS_TOKEN_SUPPLIED RT_BIT(14) 246 240 247 /** Valid flag mask. */ 241 #define RTPROC_FLAGS_VALID_MASK UINT32_C(0x 3fff)248 #define RTPROC_FLAGS_VALID_MASK UINT32_C(0x7fff) 242 249 /** @} */ 243 250 -
trunk/src/VBox/Main/Makefile.kmk
r94793 r95274 458 458 ifdef VBOX_WITH_QTGUI 459 459 VBoxSDS_DEFS += VBOX_WITH_QTGUI 460 endif 461 ifdef VBOX_WITH_VBOXSVC_SESSION_0 462 VBoxSDS_DEFS += VBOX_WITH_VBOXSVC_SESSION_0 460 463 endif 461 464 VBoxSDS_INCS = \ -
trunk/src/VBox/Main/idl/VirtualBox.xidl
r94981 r95274 29870 29870 29871 29871 <method name="registerVBoxSVC"> 29872 <desc>Registers a VBoxSVC instance with the SDS.</desc> 29872 <desc> 29873 Registers a VBoxSVC instance with VBoxSDS. If the caller is not running 29874 in a Windows 0 session, the method attempts to run VBoxSVC in that 29875 session. 29876 <result name="E_PENDING"> 29877 The caller is not running in a Windows session 0 and no VBoxSVC 29878 is registered. VBoxSVC registration begins in Windows session 0. 29879 You should call this method again later. 29880 </result> 29881 </desc> 29873 29882 <param name="vboxSVC" type="IVBoxSVCRegistration" dir="in"> 29874 29883 <desc>Interface implemented by the VirtualBox class factory.</desc> -
trunk/src/VBox/Main/src-global/win/VirtualBoxSDSImpl.cpp
r93115 r95274 22 22 #define LOG_GROUP LOG_GROUP_MAIN_VIRTUALBOXSDS 23 23 #include <VBox/com/VirtualBox.h> 24 #include <VBox/com/utils.h> 24 25 #include "VirtualBoxSDSImpl.h" 25 26 … … 31 32 #include <iprt/asm.h> 32 33 #include <iprt/critsect.h> 34 #include <iprt/env.h> 35 #include <iprt/err.h> 33 36 #include <iprt/mem.h> 37 #include <iprt/path.h> 34 38 #include <iprt/process.h> 35 39 #include <iprt/system.h> … … 71 75 /** The PID of the chosen one. */ 72 76 RTPROCESS m_pidTheChosenOne; 77 /** The tick count when the process in Windows session 0 started */ 78 uint32_t m_tickTheChosenOne; 73 79 /** The current watcher thread index, UINT32_MAX if not watched. */ 74 80 uint32_t m_iWatcher; … … 89 95 , m_strUsername(a_rStrUsername) 90 96 , m_pidTheChosenOne(NIL_RTPROCESS) 97 , m_tickTheChosenOne(0) 91 98 #ifdef WITH_WATCHER 92 99 , m_iWatcher(UINT32_MAX) … … 146 153 } 147 154 m_pidTheChosenOne = NIL_RTPROCESS; 155 m_tickTheChosenOne = 0; 148 156 } 149 157 … … 250 258 { 251 259 *aExistingVirtualBox = NULL; 252 253 260 /* 254 261 * Get the client user SID and name. … … 263 270 /* 264 271 * If there already is a chosen one, ask it for a IVirtualBox instance 265 * to return to the caller. 272 * to return to the caller. Should it be dead or unresponsive, the caller 266 273 * takes its place. 267 274 */ 268 275 if (pUserData->m_ptrTheChosenOne.isNotNull()) 269 276 { … … 271 278 { 272 279 hrc = pUserData->m_ptrTheChosenOne->GetVirtualBox(aExistingVirtualBox); 280 /* seems the VBoxSVC in windows session 0 is not yet finished object creation. 281 * Give it a time. */ 282 if (FAILED(hrc) && GetTickCount() - pUserData->m_tickTheChosenOne < 60 * 1000) 283 hrc = E_PENDING; 273 284 } 274 285 catch (...) … … 284 295 #endif 285 296 pUserData->i_unchooseTheOne(true /*fIrregular*/); 297 hrc = S_OK; 286 298 } 287 299 } … … 289 301 hrc = S_OK; 290 302 291 /* 292 * No chosen one? Make the caller the new chosen one! 293 */ 294 if (pUserData->m_ptrTheChosenOne.isNull()) 303 /* No chosen one? Make the caller the new chosen one! */ 304 if (SUCCEEDED(hrc) && pUserData->m_ptrTheChosenOne.isNull()) 295 305 { 296 LogRel(("registerVBoxSVC: Making aPid=%u (%#x) the chosen one for user %s (%s)!\n", 297 aPid, aPid, pUserData->m_strUserSid.c_str(), pUserData->m_strUsername.c_str())); 306 #ifdef VBOX_WITH_VBOXSVC_SESSION_0 307 /* Get user token. */ 308 HANDLE hThreadToken = NULL; 309 hrc = CoImpersonateClient(); 310 if (SUCCEEDED(hrc)) 311 { 312 hrc = E_FAIL; 313 if (OpenThreadToken(GetCurrentThread(), 314 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE 315 | TOKEN_ASSIGN_PRIMARY | TOKEN_ADJUST_SESSIONID | TOKEN_READ | TOKEN_WRITE, 316 TRUE /* OpenAsSelf - for impersonation at SecurityIdentification level */, 317 &hThreadToken)) 318 { 319 HANDLE hNewToken; 320 if (DuplicateTokenEx(hThreadToken, MAXIMUM_ALLOWED, NULL /*SecurityAttribs*/, 321 SecurityIdentification, TokenPrimary, &hNewToken)) 322 { 323 CloseHandle(hThreadToken); 324 hThreadToken = hNewToken; 325 hrc = S_OK; 326 } 327 else 328 LogRel(("registerVBoxSVC: DuplicateTokenEx failed: %ld\n", GetLastError())); 329 } 330 else 331 LogRel(("registerVBoxSVC: OpenThreadToken failed: %ld\n", GetLastError())); 332 333 CoRevertToSelf(); 334 } 335 else 336 LogRel(("registerVBoxSVC: CoImpersonateClient failed: %Rhrc\n", hrc)); 337 338 /* check windows session */ 339 DWORD dwSessionId = 0; 340 if (SUCCEEDED(hrc) && hThreadToken != NULL) 341 { 342 hrc = E_FAIL; 343 DWORD cbSessionId = sizeof(DWORD); 344 if (GetTokenInformation(hThreadToken, TokenSessionId, (LPVOID)&dwSessionId, cbSessionId, &cbSessionId)) 345 { 346 if (cbSessionId == sizeof(DWORD)) 347 hrc = S_OK; 348 else 349 LogRel(("registerVBoxSVC: GetTokenInformation return value has invalid size\n")); 350 } 351 else 352 LogRel(("registerVBoxSVC: GetTokenInformation failed: %ld\n", GetLastError())); 353 } 354 if (SUCCEEDED(hrc) && dwSessionId != 0) 355 { 356 /* if VBoxSVC in the Windows session 0 is not started or if it did not 357 * registered during a minute, start new one */ 358 if ( pUserData->m_pidTheChosenOne == NIL_RTPROCESS 359 || GetTickCount() - pUserData->m_tickTheChosenOne > 60 * 1000) 360 { 361 uint32_t uSessionId = 0; 362 if (SetTokenInformation(hThreadToken, TokenSessionId, &uSessionId, sizeof(uint32_t))) 363 { 364 /* start VBoxSVC process */ 365 /* Get the path to the executable directory w/ trailing slash: */ 366 char szPath[RTPATH_MAX]; 367 int vrc = RTPathAppPrivateArch(szPath, sizeof(szPath)); 368 AssertRCReturn(vrc, vrc); 369 size_t cbBufLeft = RTPathEnsureTrailingSeparator(szPath, sizeof(szPath)); 370 AssertReturn(cbBufLeft > 0, VERR_FILENAME_TOO_LONG); 371 char *pszNamePart = &szPath[cbBufLeft]; NOREF(pszNamePart); 372 cbBufLeft = sizeof(szPath) - cbBufLeft; 373 static const char s_szVirtualBox_exe[] = "VBoxSVC.exe"; 374 vrc = RTStrCopy(pszNamePart, cbBufLeft, s_szVirtualBox_exe); 375 AssertRCReturn(vrc, vrc); 376 const char *apszArgs[] = 377 { 378 szPath, 379 "--registervbox", 380 NULL 381 }; 382 383 RTPROCESS pid; 384 vrc = RTProcCreateEx(szPath, 385 apszArgs, 386 RTENV_DEFAULT, 387 RTPROC_FLAGS_TOKEN_SUPPLIED, 388 NULL, NULL, NULL, NULL, NULL, &hThreadToken, &pid); 389 390 if (RT_SUCCESS(vrc)) 391 { 392 pUserData->m_pidTheChosenOne = pid; 393 pUserData->m_tickTheChosenOne = GetTickCount(); 394 hrc = E_PENDING; 395 } 396 else 397 LogRel(("registerVBoxSVC: Create VBoxSVC process failed: %Rrc\n", vrc)); 398 } 399 else 400 { 401 hrc = E_FAIL; 402 LogRel(("registerVBoxSVC: SetTokenInformation failed: %ld\n", GetLastError())); 403 } 404 } 405 else /* the VBoxSVC in Windows session 0 already started */ 406 hrc = E_PENDING; 407 } 408 CloseHandle(hThreadToken); 409 410 if (SUCCEEDED(hrc) && dwSessionId == 0) 411 { 412 #endif 413 LogRel(("registerVBoxSVC: Making aPid=%u (%#x) the chosen one for user %s (%s)!\n", 414 aPid, aPid, pUserData->m_strUserSid.c_str(), pUserData->m_strUsername.c_str())); 298 415 #ifdef WITH_WATCHER 299 /* Open the process so we can watch it. */300 HANDLE hProcess = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION, FALSE /*fInherit*/, aPid);301 if (hProcess == NULL)302 hProcess = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_LIMITED_INFORMATION, FALSE /*fInherit*/, aPid);303 if (hProcess == NULL)304 hProcess = OpenProcess(SYNCHRONIZE, FALSE /*fInherit*/, aPid);305 if (hProcess != NULL)306 {307 if (i_watchIt(pUserData, hProcess, aPid))416 /* Open the process so we can watch it. */ 417 HANDLE hProcess = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION, FALSE /*fInherit*/, aPid); 418 if (hProcess == NULL) 419 hProcess = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_LIMITED_INFORMATION, FALSE /*fInherit*/, aPid); 420 if (hProcess == NULL) 421 hProcess = OpenProcess(SYNCHRONIZE, FALSE /*fInherit*/, aPid); 422 if (hProcess != NULL) 423 { 424 if (i_watchIt(pUserData, hProcess, aPid)) 308 425 #endif 309 { 310 /* Make it official... */ 311 pUserData->m_ptrTheChosenOne = aVBoxSVC; 312 pUserData->m_pidTheChosenOne = aPid; 313 hrc = S_OK; 426 { 427 /* Make it official... */ 428 pUserData->m_ptrTheChosenOne = aVBoxSVC; 429 pUserData->m_pidTheChosenOne = aPid; 430 hrc = S_OK; 431 } 432 #ifdef WITH_WATCHER 433 else 434 { 435 436 LogRel(("registerVBoxSVC: i_watchIt failed!\n")); 437 hrc = RPC_E_OUT_OF_RESOURCES; 438 } 314 439 } 315 #ifdef WITH_WATCHER316 440 else 317 441 { 318 319 LogRel(("registerVBoxSVC: i_watchIt failed!\n")); 320 hrc = RPC_E_OUT_OF_RESOURCES; 442 LogRel(("registerVBoxSVC: OpenProcess() failed: %ld\n", GetLastError())); 443 hrc = E_ACCESSDENIED; 321 444 } 322 } 323 else 324 { 325 LogRel(("registerVBoxSVC: OpenProcess failed: %u\n", GetLastError())); 326 hrc = E_ACCESSDENIED; 445 #endif 446 #ifdef VBOX_WITH_VBOXSVC_SESSION_0 327 447 } 328 448 #endif 329 449 } 330 331 450 pUserData->i_unlock(); 332 451 pUserData->i_release(); … … 474 593 a_pStrUsername->setNull(); 475 594 476 CoInitializeEx(NULL, COINIT_MULTITHREADED); // is this necessary?477 595 HRESULT hrc = CoImpersonateClient(); 478 596 if (SUCCEEDED(hrc)) … … 555 673 else 556 674 LogRel(("i_GetClientUserSID: CoImpersonateClient failed: %Rhrc\n", hrc)); 557 CoUninitialize();558 675 return fRet; 559 676 } -
trunk/src/VBox/Main/src-server/win/svcmain.cpp
r95120 r95274 333 333 if (SUCCEEDED(hrc)) 334 334 { 335 /* 336 * Create VBoxSVCRegistration object and hand that to VBoxSDS. 337 */ 338 m_pVBoxSVC = new VBoxSVCRegistration(this); 339 hrc = m_ptrVirtualBoxSDS->RegisterVBoxSVC(m_pVBoxSVC, GetCurrentProcessId(), ppOtherVirtualBox); 335 /* By default the RPC_C_IMP_LEVEL_IDENTIFY is used for impersonation the client. It allows 336 ACL checking but restricts an access to system objects e.g. files. Call to CoSetProxyBlanket 337 elevates the impersonation level up to RPC_C_IMP_LEVEL_IMPERSONATE allowing the VBoxSDS 338 service to access the files. */ 339 hrc = CoSetProxyBlanket(m_ptrVirtualBoxSDS, 340 RPC_C_AUTHN_DEFAULT, 341 RPC_C_AUTHZ_DEFAULT, 342 COLE_DEFAULT_PRINCIPAL, 343 RPC_C_AUTHN_LEVEL_DEFAULT, 344 RPC_C_IMP_LEVEL_IMPERSONATE, 345 NULL, 346 EOAC_DEFAULT); 340 347 if (SUCCEEDED(hrc)) 341 348 { 342 g_fRegisteredWithVBoxSDS = !*ppOtherVirtualBox; 343 return hrc; 344 } 345 m_pVBoxSVC->Release(); 349 /* 350 * Create VBoxSVCRegistration object and hand that to VBoxSDS. 351 */ 352 m_pVBoxSVC = new VBoxSVCRegistration(this); 353 hrc = E_PENDING; 354 /* we try to register IVirtualBox 10 times */ 355 for (int regTimes = 0; hrc == E_PENDING && regTimes < 10; --regTimes) 356 { 357 hrc = m_ptrVirtualBoxSDS->RegisterVBoxSVC(m_pVBoxSVC, GetCurrentProcessId(), ppOtherVirtualBox); 358 if (SUCCEEDED(hrc)) 359 { 360 g_fRegisteredWithVBoxSDS = !*ppOtherVirtualBox; 361 return hrc; 362 } 363 /* sleep to give a time for windows session 0 registration */ 364 if (hrc == E_PENDING) 365 RTThreadSleep(1000); 366 } 367 m_pVBoxSVC->Release(); 368 } 346 369 } 347 370 m_ptrVirtualBoxSDS.setNull(); … … 687 710 break; 688 711 } 689 690 712 case WM_DESTROY: 691 713 { … … 823 845 { 824 846 /* never called, just need to be here */ 847 } 848 849 850 /* thread for registering the VBoxSVC started in session 0 */ 851 static DWORD WINAPI threadRegisterVirtualBox(LPVOID lpParam) throw() 852 { 853 HANDLE hEvent = (HANDLE)lpParam; 854 HRESULT hrc = CoInitializeEx(NULL, COINIT_MULTITHREADED); 855 if (SUCCEEDED(hrc)) 856 { 857 /* create IVirtualBox instance */ 858 ComPtr<IVirtualBox> pVirtualBox; 859 hrc = CoCreateInstance(CLSID_VirtualBox, NULL, CLSCTX_INPROC_SERVER /*CLSCTX_LOCAL_SERVER */, IID_IVirtualBox, 860 (void **)pVirtualBox.asOutParam()); 861 if (SUCCEEDED(hrc)) 862 { 863 /* wait a minute allowing clients to connect to the instance */ 864 WaitForSingleObject(hEvent, 60 * 1000); 865 /* remove reference. If anybody connected to IVirtualBox it will stay alive. */ 866 pVirtualBox.setNull(); 867 } 868 CoUninitialize(); 869 } 870 return 0L; 825 871 } 826 872 … … 891 937 { "-loginterval", 'I', RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_ICASE }, 892 938 { "/loginterval", 'I', RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_ICASE }, 939 { "--registervbox", 'b', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE }, 940 { "-registervbox", 'b', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE }, 941 { "/registervbox", 'b', RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_ICASE }, 893 942 }; 894 943 … … 901 950 uint32_t uHistoryFileTime = RT_SEC_1DAY; // max 1 day per file 902 951 uint64_t uHistoryFileSize = 100 * _1M; // max 100MB per file 952 bool fRegisterVBox = false; 903 953 904 954 RTGETOPTSTATE GetOptState; … … 981 1031 } 982 1032 1033 case 'b': 1034 fRegisterVBox = true; 1035 break; 1036 983 1037 default: 984 1038 /** @todo this assumes that stderr is visible, which is not … … 1101 1155 Log(("SVCMain: Failed to create main window\n")); 1102 1156 1157 /* create thread to register IVirtualBox in VBoxSDS 1158 * It is used for starting the VBoxSVC in the windows 1159 * session 0. */ 1160 HANDLE hWaitEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 1161 HANDLE hRegisterVBoxThread = NULL; 1162 if (fRegisterVBox) 1163 { 1164 DWORD dwThreadId = 0; 1165 hRegisterVBoxThread = CreateThread(NULL, 0, threadRegisterVirtualBox, (LPVOID)hWaitEvent, 1166 0, &dwThreadId); 1167 } 1168 1103 1169 MSG msg; 1104 1170 while (GetMessage(&msg, 0, 0, 0) > 0) … … 1109 1175 1110 1176 DestroyMainWindow(); 1177 1178 if (fRegisterVBox) 1179 { 1180 SetEvent(hWaitEvent); 1181 WaitForSingleObject(hRegisterVBoxThread, INFINITE); 1182 CloseHandle(hRegisterVBoxThread); 1183 CloseHandle(hWaitEvent); 1184 } 1111 1185 1112 1186 g_pModule->RevokeClassObjects(); -
trunk/src/VBox/Runtime/r3/win/process-win.cpp
r93115 r95274 1612 1612 RTENV hEnv, DWORD dwCreationFlags, 1613 1613 STARTUPINFOW *pStartupInfo, PROCESS_INFORMATION *pProcInfo, 1614 uint32_t fFlags, const char *pszExec, uint32_t idDesiredSession) 1614 uint32_t fFlags, const char *pszExec, uint32_t idDesiredSession, 1615 HANDLE hUserToken) 1615 1616 { 1616 1617 /* … … 1642 1643 DWORD dwErr = NO_ERROR; 1643 1644 HANDLE hTokenLogon = INVALID_HANDLE_VALUE; 1644 int rc; 1645 if (fFlags & RTPROC_FLAGS_AS_IMPERSONATED_TOKEN) 1645 int rc = VINF_SUCCESS; 1646 if (fFlags & RTPROC_FLAGS_TOKEN_SUPPLIED) 1647 hTokenLogon = hUserToken; 1648 else if (fFlags & RTPROC_FLAGS_AS_IMPERSONATED_TOKEN) 1646 1649 rc = rtProcWinGetThreadTokenHandle(GetCurrentThread(), &hTokenLogon); 1647 1650 else if (pwszUser == NULL) … … 1850 1853 if (hTokenUserDesktop != INVALID_HANDLE_VALUE) 1851 1854 CloseHandle(hTokenUserDesktop); 1852 if (hTokenLogon != INVALID_HANDLE_VALUE) 1855 if ( !(fFlags & RTPROC_FLAGS_TOKEN_SUPPLIED) 1856 && hTokenLogon != INVALID_HANDLE_VALUE) 1853 1857 CloseHandle(hTokenLogon); 1854 1858 … … 2088 2092 RTENV hEnv, DWORD dwCreationFlags, 2089 2093 STARTUPINFOW *pStartupInfo, PROCESS_INFORMATION *pProcInfo, 2090 uint32_t fFlags, const char *pszExec, uint32_t idDesiredSession) 2094 uint32_t fFlags, const char *pszExec, uint32_t idDesiredSession, 2095 HANDLE hUserToken) 2091 2096 { 2092 2097 /* … … 2096 2101 * Note! This method is very slow on W2K. 2097 2102 */ 2098 if (!(fFlags & (RTPROC_FLAGS_SERVICE | RTPROC_FLAGS_AS_IMPERSONATED_TOKEN )))2103 if (!(fFlags & (RTPROC_FLAGS_SERVICE | RTPROC_FLAGS_AS_IMPERSONATED_TOKEN | RTPROC_FLAGS_TOKEN_SUPPLIED))) 2099 2104 { 2100 2105 AssertPtr(pwszUser); … … 2104 2109 return rc; 2105 2110 } 2106 return rtProcWinCreateAsUser2(pwszUser, pwszPassword, ppwszExec, pwszCmdLine, 2107 hEnv, dwCreationFlags, pStartupInfo, pProcInfo, fFlags, pszExec, idDesiredSession);2111 return rtProcWinCreateAsUser2(pwszUser, pwszPassword, ppwszExec, pwszCmdLine, hEnv, dwCreationFlags, 2112 pStartupInfo, pProcInfo, fFlags, pszExec, idDesiredSession, hUserToken); 2108 2113 } 2109 2114 … … 2282 2287 AssertReturn(!(fFlags & RTPROC_FLAGS_DESIRED_SESSION_ID), VERR_INVALID_FLAGS); 2283 2288 2289 HANDLE hUserToken = NULL; 2290 if (fFlags & RTPROC_FLAGS_TOKEN_SUPPLIED) 2291 hUserToken = *(HANDLE *)pvExtraData; 2292 2284 2293 /* 2285 2294 * Initialize the globals. … … 2287 2296 int rc = RTOnce(&g_rtProcWinInitOnce, rtProcWinInitOnce, NULL); 2288 2297 AssertRCReturn(rc, rc); 2289 if (pszAsUser || (fFlags & (RTPROC_FLAGS_PROFILE | RTPROC_FLAGS_SERVICE | RTPROC_FLAGS_AS_IMPERSONATED_TOKEN))) 2298 if ( pszAsUser 2299 || (fFlags & (RTPROC_FLAGS_PROFILE | RTPROC_FLAGS_SERVICE | RTPROC_FLAGS_AS_IMPERSONATED_TOKEN 2300 | RTPROC_FLAGS_TOKEN_SUPPLIED))) 2290 2301 { 2291 2302 rc = RTOnce(&g_rtProcWinResolveOnce, rtProcWinResolveOnce, NULL); … … 2445 2456 */ 2446 2457 if ( pszAsUser == NULL 2447 && !(fFlags & (RTPROC_FLAGS_SERVICE | RTPROC_FLAGS_AS_IMPERSONATED_TOKEN )))2458 && !(fFlags & (RTPROC_FLAGS_SERVICE | RTPROC_FLAGS_AS_IMPERSONATED_TOKEN | RTPROC_FLAGS_TOKEN_SUPPLIED))) 2448 2459 { 2449 2460 /* Create the environment block first. */ … … 2483 2494 if (RT_SUCCESS(rc)) 2484 2495 { 2485 rc = rtProcWinCreateAsUser(pwszUser, pwszPassword, 2486 & pwszExec, pwszCmdLine, hEnv, dwCreationFlags,2487 &StartupInfo, &ProcInfo, fFlags, pszExec, idDesiredSession);2496 rc = rtProcWinCreateAsUser(pwszUser, pwszPassword, &pwszExec, pwszCmdLine, hEnv, dwCreationFlags, 2497 &StartupInfo, &ProcInfo, fFlags, pszExec, idDesiredSession, 2498 hUserToken); 2488 2499 2489 2500 if (pwszPassword && *pwszPassword)
Note:
See TracChangeset
for help on using the changeset viewer.