Changeset 95274 in vbox for trunk/src/VBox/Main/src-global
- Timestamp:
- Jun 14, 2022 10:48:33 AM (3 years ago)
- svn:sync-xref-src-repo-rev:
- 151855
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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 }
Note:
See TracChangeset
for help on using the changeset viewer.