Changeset 40158 in vbox for trunk/src/VBox/Additions/common
- Timestamp:
- Feb 16, 2012 5:06:35 PM (13 years ago)
- svn:sync-xref-src-repo-rev:
- 76311
- Location:
- trunk/src/VBox/Additions/common/VBoxService
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxService/VBoxService-win.cpp
r36338 r40158 136 136 ss.dwCurrentState = dwStatus; 137 137 ss.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; 138 #ifndef TARGET_NT4 139 ss.dwControlsAccepted |= SERVICE_ACCEPT_SESSIONCHANGE; 140 #endif 138 141 ss.dwWin32ExitCode = NO_ERROR; 139 142 ss.dwServiceSpecificExitCode = 0; /* Not used */ … … 379 382 380 383 384 #ifndef TARGET_NT4 385 static const char* vboxServiceWTSStateToString(DWORD dwEvent) 386 { 387 switch (dwEvent) 388 { 389 case WTS_CONSOLE_CONNECT: 390 return "A session was connected to the console terminal"; 391 392 case WTS_CONSOLE_DISCONNECT: 393 return "A session was disconnected from the console terminal"; 394 395 case WTS_REMOTE_CONNECT: 396 return "A session connected to the remote terminal"; 397 398 case WTS_REMOTE_DISCONNECT: 399 return "A session was disconnected from the remote terminal"; 400 401 case WTS_SESSION_LOGON: 402 return "A user has logged on to a session"; 403 404 case WTS_SESSION_LOGOFF: 405 return "A user has logged off the session"; 406 407 case WTS_SESSION_LOCK: 408 return "A session has been locked"; 409 410 case WTS_SESSION_UNLOCK: 411 return "A session has been unlocked"; 412 413 case WTS_SESSION_REMOTE_CONTROL: 414 return "A session has changed its remote controlled status"; 415 #if 0 416 case WTS_SESSION_CREATE: 417 return "A session has been created"; 418 419 case WTS_SESSION_TERMINATE: 420 return "The session has been terminated"; 421 #endif 422 default: 423 break; 424 } 425 426 return "Uknonwn state"; 427 } 428 #endif /* !TARGET_NT4 */ 429 430 381 431 #ifdef TARGET_NT4 382 432 static VOID WINAPI vboxServiceWinCtrlHandler(DWORD dwControl) … … 417 467 } 418 468 419 case SERVICE_CONTROL_SESSIONCHANGE: /* Only Win XP and up. */ 420 #ifndef TARGET_NT4 421 # if 0 422 switch (dwEventType) 423 { 424 case WTS_SESSION_LOGON: 425 VBoxServiceVerbose(2, "A user has logged on to the session.\n"); 426 break; 427 428 case WTS_SESSION_LOGOFF: 429 VBoxServiceVerbose(2, "A user has logged off from the session.\n"); 430 break; 431 default: 432 break; 433 } 434 # endif 435 #endif /* !TARGET_NT4 */ 469 # ifndef TARGET_NT4 470 case SERVICE_CONTROL_SESSIONCHANGE: /* Only Windows 2000 and up. */ 471 { 472 AssertPtr(lpEventData); 473 PWTSSESSION_NOTIFICATION pNotify = (PWTSSESSION_NOTIFICATION)lpEventData; 474 Assert(pNotify->cbSize == sizeof(WTSSESSION_NOTIFICATION)); 475 476 VBoxServiceVerbose(1, "Control handler: %s (Session=%ld, Event=%#x)\n", 477 vboxServiceWTSStateToString(dwEventType), 478 pNotify->dwSessionId, dwEventType); 479 480 /* Handle all events, regardless of dwEventType. */ 481 int rc2 = VBoxServiceVMInfoSignal(); 482 AssertRC(rc2); 436 483 break; 484 } 485 # endif /* !TARGET_NT4 */ 437 486 438 487 default: 439 VBoxServiceVerbose(1, " Service control function not implemented: %#x\n", dwControl);488 VBoxServiceVerbose(1, "Control handler: Function not implemented: %#x\n", dwControl); 440 489 rcRet = ERROR_CALL_NOT_IMPLEMENTED; 441 490 break; -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h
r39906 r40158 411 411 412 412 #ifdef VBOXSERVICE_MANAGEMENT 413 extern uint32_t VBoxServiceBalloonQueryPages(uint32_t cbPage);413 extern uint32_t VBoxServiceBalloonQueryPages(uint32_t cbPage); 414 414 #endif 415 415 #if defined(VBOX_WITH_PAGE_SHARING) && defined(RT_OS_WINDOWS) 416 extern RTEXITCODE VBoxServicePageSharingInitFork(void); 417 #endif 416 extern RTEXITCODE VBoxServicePageSharingInitFork(void); 417 #endif 418 extern int VBoxServiceVMInfoSignal(void); 418 419 419 420 RT_C_DECLS_END -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo-win.cpp
r39760 r40158 53 53 /** Number of assigned user processes. */ 54 54 ULONG ulNumProcs; 55 /** Last (highest) session number. This 56 * is needed for distinguishing old session 57 * process counts from new (current) session 58 * ones. */ 59 ULONG ulSession; 55 60 } VBOXSERVICEVMINFOUSER, *PVBOXSERVICEVMINFOUSER; 56 61 … … 65 70 typedef struct 66 71 { 72 /** The PID. */ 67 73 DWORD id; 74 /** The LUID. */ 68 75 LUID luid; 76 /** Interactive process. */ 77 bool fInteractive; 69 78 } VBOXSERVICEVMINFOPROC, *PVBOXSERVICEVMINFOPROC; 70 79 … … 120 129 DWORD dwErr = GetLastError(); 121 130 if (g_cVerbosity) 122 VBoxServiceError(" VMInfo/Users: Unable to open process with PID=%ld, error=%ld",131 VBoxServiceError("Unable to open process with PID=%ld, error=%ld\n", 123 132 pProc->id, dwErr); 124 133 rc = RTErrConvertFromWin32(dwErr); … … 142 151 if (RT_SUCCESS(rc)) 143 152 { 144 DWORD dwLen = sizeof(pszName);153 DWORD dwLen = cbName / sizeof(TCHAR); 145 154 if (!pfnQueryFullProcessImageName(h, 0 /*PROCESS_NAME_NATIVE*/, pszName, &dwLen)) 146 155 rc = VERR_ACCESS_DENIED; … … 154 163 if (!GetModuleFileNameEx(h, NULL /* Get main executable */, pszName, cbName / sizeof(TCHAR))) 155 164 rc = VERR_ACCESS_DENIED; 156 }157 158 if (VERR_ACCESS_DENIED == rc)159 {160 DWORD dwErr = GetLastError();161 if (g_cVerbosity)162 VBoxServiceError("VMInfo/Users: Unable to retrieve module name for PID=%ld, error=%ld",163 pProc->id, dwErr);164 rc = RTErrConvertFromWin32(dwErr);165 165 } 166 166 … … 183 183 { 184 184 AssertPtrReturn(pProc, VERR_INVALID_POINTER); 185 186 DWORD dwErr = ERROR_SUCCESS; 185 187 HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pProc->id); 186 188 if (h == NULL) 187 189 { 188 DWORDdwErr = GetLastError();189 if (g_cVerbosity )190 VBoxServiceError(" VMInfo/Users: Unable to open process with PID=%ld, error=%ld",190 dwErr = GetLastError(); 191 if (g_cVerbosity > 4) 192 VBoxServiceError("Unable to open process with PID=%ld, error=%ld\n", 191 193 pProc->id, dwErr); 192 194 return RTErrConvertFromWin32(dwErr); 193 195 } 194 196 195 int rc = VERR_NO_MEMORY; 196 HANDLE hToken; 197 if (OpenProcessToken(h, TOKEN_QUERY, &hToken)) 198 { 199 void *pvTokenInfo = NULL; 200 DWORD dwTokenInfoSize; 201 switch (tkClass) 202 { 203 case TokenStatistics: 204 dwTokenInfoSize = sizeof(TOKEN_STATISTICS); 205 pvTokenInfo = RTMemAlloc(dwTokenInfoSize); 206 break; 207 208 /** @todo Implement more token classes here. */ 209 210 default: 211 VBoxServiceError("Token class not implemented: %ld", tkClass); 212 rc = VERR_NOT_IMPLEMENTED; 213 break; 214 } 215 216 if (pvTokenInfo) 217 { 218 DWORD dwRetLength; 219 if (GetTokenInformation(hToken, tkClass, pvTokenInfo, dwTokenInfoSize, &dwRetLength)) 220 { 221 switch (tkClass) 222 { 223 case TokenStatistics: 224 { 225 TOKEN_STATISTICS *pStats = (TOKEN_STATISTICS*)pvTokenInfo; 226 pProc->luid = pStats->AuthenticationId; 227 /** @todo Add more information of TOKEN_STATISTICS as needed. */ 228 break; 229 } 230 231 default: 232 /* Should never get here! */ 233 break; 234 } 235 rc = VINF_SUCCESS; 236 } 237 else 238 rc = RTErrConvertFromWin32(GetLastError()); 239 RTMemFree(pvTokenInfo); 240 } 241 CloseHandle(hToken); 197 int rc = VINF_SUCCESS; 198 HANDLE hToken; 199 if (OpenProcessToken(h, TOKEN_QUERY, &hToken)) 200 { 201 void *pvTokenInfo = NULL; 202 DWORD dwTokenInfoSize; 203 switch (tkClass) 204 { 205 case TokenStatistics: 206 dwTokenInfoSize = sizeof(TOKEN_STATISTICS); 207 pvTokenInfo = HeapAlloc(GetProcessHeap(), 208 HEAP_ZERO_MEMORY, dwTokenInfoSize); 209 AssertPtr(pvTokenInfo); 210 break; 211 212 case TokenGroups: 213 dwTokenInfoSize = 0; 214 /* Allocating will follow in a second step. */ 215 break; 216 217 /** @todo Implement more token classes here. */ 218 219 default: 220 VBoxServiceError("Token class not implemented: %ld", tkClass); 221 rc = VERR_NOT_IMPLEMENTED; 222 break; 223 } 224 225 if (RT_SUCCESS(rc)) 226 { 227 DWORD dwRetLength; 228 if (!GetTokenInformation(hToken, tkClass, pvTokenInfo, dwTokenInfoSize, &dwRetLength)) 229 { 230 dwErr = GetLastError(); 231 if (dwErr == ERROR_INSUFFICIENT_BUFFER) 232 { 233 dwErr = ERROR_SUCCESS; 234 235 switch (tkClass) 236 { 237 case TokenGroups: 238 pvTokenInfo = (PTOKEN_GROUPS)HeapAlloc(GetProcessHeap(), 239 HEAP_ZERO_MEMORY, dwRetLength); 240 if (!pvTokenInfo) 241 dwErr = GetLastError(); 242 dwTokenInfoSize = dwRetLength; 243 break; 244 245 default: 246 AssertMsgFailed(("Re-allocating of token information for token class not implemented\n")); 247 break; 248 } 249 250 if (dwErr == ERROR_SUCCESS) 251 { 252 if (!GetTokenInformation(hToken, tkClass, pvTokenInfo, dwTokenInfoSize, &dwRetLength)) 253 dwErr = GetLastError(); 254 } 255 } 256 } 257 258 if (dwErr == ERROR_SUCCESS) 259 { 260 rc = VINF_SUCCESS; 261 262 switch (tkClass) 263 { 264 case TokenStatistics: 265 { 266 PTOKEN_STATISTICS pStats = (PTOKEN_STATISTICS)pvTokenInfo; 267 memcpy(&pProc->luid, &pStats->AuthenticationId, sizeof(LUID)); 268 /** @todo Add more information of TOKEN_STATISTICS as needed. */ 269 break; 270 } 271 272 case TokenGroups: 273 { 274 pProc->fInteractive = false; 275 276 SID_IDENTIFIER_AUTHORITY sidAuthNT = SECURITY_NT_AUTHORITY; 277 PSID pSidInteractive = NULL; /* S-1-5-4 */ 278 if (!AllocateAndInitializeSid(&sidAuthNT, 1, 4, 0, 0, 0, 0, 0, 0, 0, &pSidInteractive)) 279 dwErr = GetLastError(); 280 281 PSID pSidLocal = NULL; /* S-1-2-0 */ 282 if (dwErr == ERROR_SUCCESS) 283 { 284 SID_IDENTIFIER_AUTHORITY sidAuthLocal = SECURITY_LOCAL_SID_AUTHORITY; 285 if (!AllocateAndInitializeSid(&sidAuthLocal, 1, 0, 0, 0, 0, 0, 0, 0, 0, &pSidLocal)) 286 dwErr = GetLastError(); 287 } 288 289 if (dwErr == ERROR_SUCCESS) 290 { 291 PTOKEN_GROUPS pGroups = (PTOKEN_GROUPS)pvTokenInfo; 292 AssertPtr(pGroups); 293 for (DWORD i = 0; i < pGroups->GroupCount; i++) 294 { 295 if ( EqualSid(pGroups->Groups[i].Sid, pSidInteractive) 296 || EqualSid(pGroups->Groups[i].Sid, pSidLocal) 297 || pGroups->Groups[i].Attributes & SE_GROUP_LOGON_ID) 298 { 299 pProc->fInteractive = true; 300 break; 301 } 302 } 303 } 304 305 if (pSidInteractive) 306 FreeSid(pSidInteractive); 307 if (pSidLocal) 308 FreeSid(pSidLocal); 309 break; 310 } 311 312 default: 313 AssertMsgFailed(("Unhandled token information class\n")); 314 break; 315 } 316 } 317 318 if (pvTokenInfo) 319 HeapFree(GetProcessHeap(), 0 /* Flags */, pvTokenInfo); 320 } 321 CloseHandle(hToken); 242 322 } 243 323 else 244 { 245 DWORD dwErr = GetLastError(); 324 dwErr = GetLastError(); 325 326 if (dwErr != ERROR_SUCCESS) 327 { 246 328 if (g_cVerbosity) 247 VBoxServiceError(" VMInfo/Users: Unable to query process token for PID=%ld, error=%ld\n",329 VBoxServiceError("Unable to query token information for PID=%ld, error=%ld\n", 248 330 pProc->id, dwErr); 249 331 rc = RTErrConvertFromWin32(dwErr); 250 332 } 333 251 334 CloseHandle(h); 252 335 return rc; … … 314 397 { 315 398 paProcs[i].id = paPID[i]; 316 rc = VBoxServiceVMInfoWinProcessesGetTokenInfo(&paProcs[i], Token Statistics);399 rc = VBoxServiceVMInfoWinProcessesGetTokenInfo(&paProcs[i], TokenGroups); 317 400 if (RT_FAILURE(rc)) 318 401 { 319 402 /* Because some processes cannot be opened/parsed on 320 Windows, we should not consider to be this an error here. */403 Windows, we should not consider to be this an error here. */ 321 404 rc = VINF_SUCCESS; 405 } 406 else 407 { 408 rc = VBoxServiceVMInfoWinProcessesGetTokenInfo(&paProcs[i], TokenStatistics); 409 if (RT_FAILURE(rc)) 410 { 411 /* Because some processes cannot be opened/parsed on 412 Windows, we should not consider to be this an error here. */ 413 rc = VINF_SUCCESS; 414 } 322 415 } 323 416 } … … 358 451 * @param paProcs The process snapshot. 359 452 * @param cProcs The number of processes in the snaphot. 453 * @param puSession Looked up session number. Optional. 360 454 */ 361 uint32_t VBoxServiceVMInfoWinSessionHasProcesses(PLUID pSession, PVBOXSERVICEVMINFOPROC const paProcs, DWORD cProcs) 455 uint32_t VBoxServiceVMInfoWinSessionHasProcesses(PLUID pSession, 456 PVBOXSERVICEVMINFOPROC const paProcs, DWORD cProcs, 457 PULONG puSession) 362 458 { 363 459 if (!pSession) 364 460 { 365 VBoxServiceVerbose(1, " VMInfo/Users:Session became invalid while enumerating!\n");461 VBoxServiceVerbose(1, "Session became invalid while enumerating!\n"); 366 462 return 0; 367 463 } … … 371 467 if (rcNt != STATUS_SUCCESS) 372 468 { 373 VBoxServiceError(" VMInfo/Users:Could not get logon session data! rcNt=%#x", rcNt);469 VBoxServiceError("Could not get logon session data! rcNt=%#x", rcNt); 374 470 return 0; 375 471 } … … 383 479 for (DWORD i = 0; i < cProcs; i++) 384 480 { 385 /*VBoxServiceVerbose(3, "%ld:%ld <-> %ld:%ld\n", 386 paProcs[i].luid.HighPart, paProcs[i].luid.LowPart, 387 pSessionData->LogonId.HighPart, pSessionData->LogonId.LowPart);*/ 388 if ( paProcs[i].luid.HighPart == pSessionData->LogonId.HighPart 389 && paProcs[i].luid.LowPart == pSessionData->LogonId.LowPart) 481 VBoxServiceVerbose(4, "PID=%ld: (Interactive: %RTbool) %ld:%ld <-> %ld:%ld\n", 482 paProcs[i].id, paProcs[i].fInteractive, 483 paProcs[i].luid.HighPart, paProcs[i].luid.LowPart, 484 pSessionData->LogonId.HighPart, pSessionData->LogonId.LowPart); 485 if (g_cVerbosity) 486 { 487 TCHAR szModule[_1K]; 488 int rc2 = VBoxServiceVMInfoWinProcessesGetModuleName(&paProcs[i], szModule, sizeof(szModule)); 489 if (RT_SUCCESS(rc2)) 490 VBoxServiceVerbose(4, "PID=%ld: %s\n", 491 paProcs[i].id, szModule); 492 } 493 494 if ( paProcs[i].fInteractive 495 && ( paProcs[i].luid.HighPart == pSessionData->LogonId.HighPart 496 && paProcs[i].luid.LowPart == pSessionData->LogonId.LowPart)) 390 497 { 391 498 cNumProcs++; 392 499 if (!g_cVerbosity) /* We want a bit more info on higher verbosity. */ 393 500 break; 394 395 TCHAR szModule[_1K];396 int rc2 = VBoxServiceVMInfoWinProcessesGetModuleName(&paProcs[i], szModule, sizeof(szModule));397 if (RT_SUCCESS(rc2))398 VBoxServiceVerbose(4, "VMInfo/Users: PID=%ld: %s\n",399 paProcs[i].id, szModule);400 501 } 401 502 } 402 503 403 504 if (g_cVerbosity) 404 VBoxServiceVerbose(3, " VMInfo/Users: Session %u has %u processes\n",505 VBoxServiceVerbose(3, "Session %u has %u processes total\n", 405 506 pSessionData->Session, cNumProcs); 406 507 else 407 VBoxServiceVerbose(3, " VMInfo/Users:Session %u has at least one process\n",508 VBoxServiceVerbose(3, "Session %u has at least one process\n", 408 509 pSessionData->Session); 510 511 if (puSession) 512 *puSession = pSessionData->Session; 409 513 410 514 LsaFreeReturnBuffer(pSessionData); … … 447 551 bool VBoxServiceVMInfoWinIsLoggedIn(PVBOXSERVICEVMINFOUSER pUserInfo, PLUID pSession) 448 552 { 449 AssertPtr (pUserInfo);553 AssertPtrReturn(pUserInfo, false); 450 554 if (!pSession) 451 555 return false; … … 461 565 /* If we don't have enough memory it's hard to judge whether the specified user 462 566 * is logged in or not, so just assume he/she's not. */ 463 VBoxServiceVerbose(3, " VMInfo/Users:Not enough memory to retrieve logon session data!\n");567 VBoxServiceVerbose(3, "Not enough memory to retrieve logon session data!\n"); 464 568 break; 465 569 … … 470 574 471 575 default: 472 VBoxServiceError(" VMInfo/Users: LsaGetLogonSessionData failed with error %ul\n", ulError);576 VBoxServiceError("LsaGetLogonSessionData failed with error %u\n", ulError); 473 577 break; 474 578 } … … 479 583 if (!pSessionData) 480 584 { 481 VBoxServiceError(" VMInfo/Users:Invalid logon session data!\n");585 VBoxServiceError("Invalid logon session data!\n"); 482 586 return false; 483 587 } … … 491 595 if ( IsValidSid(pSessionData->Sid) 492 596 && ( (SECURITY_LOGON_TYPE)pSessionData->LogonType == Interactive 493 || (SECURITY_LOGON_TYPE)pSessionData->LogonType == RemoteInteractive 494 || (SECURITY_LOGON_TYPE)pSessionData->LogonType == CachedInteractive 495 || (SECURITY_LOGON_TYPE)pSessionData->LogonType == CachedRemoteInteractive)) 496 { 497 VBoxServiceVerbose(3, "VMInfo/Users: Session data: Name=%ls, Len=%d, SID=%s, LogonID=%ld,%ld, LogonType=%ld\n", 597 || (SECURITY_LOGON_TYPE)pSessionData->LogonType == RemoteInteractive)) 598 { 599 VBoxServiceVerbose(3, "Session data: Name=%ls, Session=%u, LogonID=%ld,%ld, LogonType=%ld\n", 498 600 pSessionData->UserName.Buffer, 499 pSessionData->UserName.Length, 500 pSessionData->Sid != NULL ? "1" : "0", 601 pSessionData->Session, 501 602 pSessionData->LogonId.HighPart, pSessionData->LogonId.LowPart, 502 603 pSessionData->LogonType); … … 533 634 */ 534 635 if (dwErr != ERROR_NONE_MAPPED) 535 VBoxServiceError(" VMInfo/Users:Failed looking up account info for user=%ls, error=$ld!\n",636 VBoxServiceError("Failed looking up account info for user=%ls, error=$ld!\n", 536 637 pUserInfo->wszUser, dwErr); 537 638 } … … 540 641 if (enmOwnerType == SidTypeUser) /* Only recognize users; we don't care about the rest! */ 541 642 { 542 VBoxServiceVerbose(3, " VMInfo/Users: Account User=%ls, Session=%ld, LUID=%ld,%ld, AuthPkg=%ls, Domain=%ls\n",643 VBoxServiceVerbose(3, "Account User=%ls, Session=%ld, LogonID=%ld,%ld, AuthPkg=%ls, Domain=%ls\n", 543 644 pUserInfo->wszUser, pSessionData->Session, pSessionData->LogonId.HighPart, 544 645 pSessionData->LogonId.LowPart, pUserInfo->wszAuthenticationPackage, … … 548 649 LPTSTR pBuffer = NULL; 549 650 DWORD cbRet = 0; 550 int iState = 0;651 int iState = -1; 551 652 if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, 552 653 pSessionData->Session, … … 557 658 if (cbRet) 558 659 iState = *pBuffer; 559 VBoxServiceVerbose(3, " VMInfo/Users: Account User=%ls, WTSConnectState=%d\n",560 pUserInfo->wszUser, iState );660 VBoxServiceVerbose(3, "Account User=%ls, WTSConnectState=%d (%ld)\n", 661 pUserInfo->wszUser, iState, cbRet); 561 662 if ( iState == WTSActive /* User logged on to WinStation. */ 562 663 || iState == WTSShadow /* Shadowing another WinStation. */ … … 565 666 /** @todo On Vista and W2K, always "old" user name are still 566 667 * there. Filter out the old one! */ 567 VBoxServiceVerbose(3, " VMInfo/Users: Account User=%ls using TCS/RDP, state=%d\n",668 VBoxServiceVerbose(3, "Account User=%ls using TCS/RDP, state=%d \n", 568 669 pUserInfo->wszUser, iState); 569 670 fFoundUser = true; … … 583 684 */ 584 685 case ERROR_CTX_WINSTATION_NOT_FOUND: 585 VBoxServiceVerbose(3, " VMInfo/Users: Account User=%ls, no WinSta found\n",686 VBoxServiceVerbose(3, "No WinStation found for user=%ls\n", 586 687 pUserInfo->wszUser); 587 688 break; 588 689 589 690 default: 590 VBoxServiceVerbose(3, " VMInfo/Users: Account User=%ls, error=%ld\n",691 VBoxServiceVerbose(3, "Cannot query WTS connection state for user=%ls, error=%ld\n", 591 692 pUserInfo->wszUser, dwLastErr); 592 693 break; … … 598 699 } 599 700 600 VBoxServiceVerbose(3, " VMInfo/Users:Account User=%ls %s logged in\n",701 VBoxServiceVerbose(3, "Account User=%ls %s logged in\n", 601 702 pUserInfo->wszUser, fFoundUser ? "is" : "is not"); 602 703 } … … 630 731 { 631 732 case ERROR_NOT_ENOUGH_MEMORY: 632 VBoxServiceError(" VMInfo/Users:Not enough memory to enumerate logon sessions!\n");733 VBoxServiceError("Not enough memory to enumerate logon sessions!\n"); 633 734 break; 634 735 … … 636 737 /* If we're about to shutdown when we were in the middle of enumerating the logon 637 738 * sessions, skip the error to not confuse the user with an unnecessary log message. */ 638 VBoxServiceVerbose(3, " VMInfo/Users:Shutdown in progress ...\n");739 VBoxServiceVerbose(3, "Shutdown in progress ...\n"); 639 740 ulError = ERROR_SUCCESS; 640 741 break; 641 742 642 743 default: 643 VBoxServiceError(" VMInfo/Users: LsaEnumerate failed with error %ul\n", ulError);744 VBoxServiceError("LsaEnumerate failed with error %u\n", ulError); 644 745 break; 645 746 } … … 647 748 return RTErrConvertFromWin32(ulError); 648 749 } 649 VBoxServiceVerbose(3, " VMInfo/Users:Found %ld sessions\n", cSessions);750 VBoxServiceVerbose(3, "Found %ld sessions\n", cSessions); 650 751 651 752 PVBOXSERVICEVMINFOPROC paProcs; … … 655 756 { 656 757 if (rc == VERR_NO_MEMORY) 657 VBoxServiceError(" VMInfo/Users: Not enough memory to enumerate processes for a session!\n");758 VBoxServiceError("Not enough memory to enumerate processes\n"); 658 759 else 659 VBoxServiceError(" VMInfo/Users: Failed to enumerate processes for a session, rc=%Rrc\n", rc);760 VBoxServiceError("Failed to enumerate processes, rc=%Rrc\n", rc); 660 761 } 661 762 else … … 664 765 pUserInfo = (PVBOXSERVICEVMINFOUSER)RTMemAllocZ(cSessions * sizeof(VBOXSERVICEVMINFOUSER) + 1); 665 766 if (!pUserInfo) 666 VBoxServiceError(" VMInfo/Users:Not enough memory to store enumerated users!\n");767 VBoxServiceError("Not enough memory to store enumerated users!\n"); 667 768 else 668 769 { … … 673 774 if (VBoxServiceVMInfoWinIsLoggedIn(&UserInfo, &paSessions[i])) 674 775 { 675 VBoxServiceVerbose(4, " VMInfo/Users:Handling user=%ls, domain=%ls, package=%ls\n",676 pUserInfo[i].wszUser, pUserInfo[i].wszLogonDomain, pUserInfo[i].wszAuthenticationPackage);776 VBoxServiceVerbose(4, "Handling user=%ls, domain=%ls, package=%ls\n", 777 UserInfo.wszUser, UserInfo.wszLogonDomain, UserInfo.wszAuthenticationPackage); 677 778 678 779 /* Retrieve assigned processes of current session. */ 679 uint32_t cSessionProcs = VBoxServiceVMInfoWinSessionHasProcesses(&paSessions[i], paProcs, cProcs); 780 ULONG ulSession; 781 uint32_t cSessionProcs = VBoxServiceVMInfoWinSessionHasProcesses(&paSessions[i], paProcs, cProcs, &ulSession); 680 782 /* Don't return here when current session does not have assigned processes 681 783 * anymore -- in that case we have to search through the unique users list below … … 687 789 if ( !wcscmp(UserInfo.wszUser, pUserInfo[i].wszUser) 688 790 && !wcscmp(UserInfo.wszLogonDomain, pUserInfo[i].wszLogonDomain) 689 && !wcscmp(UserInfo.wszAuthenticationPackage, pUserInfo[i].wszAuthenticationPackage)) 791 && !wcscmp(UserInfo.wszAuthenticationPackage, pUserInfo[i].wszAuthenticationPackage) 792 && cSessionProcs) 690 793 { 691 /* If the process-per-user count was higher than 0 before but another session was 692 * was detected which also belongs to this user but has no assigned processes anymore, 693 * we detected a stale session. */ 694 if ( pUserInfo[i].ulNumProcs > 0 695 && !cSessionProcs) 794 /* 795 * Only respect the highest session for the current user. 796 */ 797 if (ulSession > pUserInfo[i].ulSession) 696 798 { 697 VBoxServiceVerbose(3, "VMInfo/Users: Stale session for user=%ls detected! Old processes: %u, new: %u\n", 698 pUserInfo[i].wszUser, pUserInfo[i].ulNumProcs, cSessionProcs); 799 VBoxServiceVerbose(4, "Updating user=%ls to %u processes (last session: %u)\n", 800 UserInfo.wszUser, cSessionProcs, ulSession); 801 802 pUserInfo[i].ulNumProcs = cSessionProcs; 803 pUserInfo[i].ulSession = ulSession; 804 805 if (!cSessionProcs) 806 VBoxServiceVerbose(3, "Stale session for user=%ls detected! Old processes: %u, new: %u\n", 807 pUserInfo[i].wszUser, pUserInfo[i].ulNumProcs, cSessionProcs); 699 808 } 700 701 VBoxServiceVerbose(4, "VMInfo/Users: Updating user=%ls to %u processes\n", 702 UserInfo.wszUser, cSessionProcs); 703 704 pUserInfo[i].ulNumProcs = cSessionProcs; 809 /* There can be multiple session objects using the same session ID for the 810 * current user -- so when we got the same session again just add the found 811 * processes to it. */ 812 else if (pUserInfo[i].ulSession == ulSession) 813 { 814 VBoxServiceVerbose(4, "Adding %u processes to user=%ls (session %u)\n", 815 cSessionProcs, UserInfo.wszUser, ulSession); 816 817 pUserInfo[i].ulNumProcs += cSessionProcs; 818 pUserInfo[i].ulSession = ulSession; 819 } 820 705 821 fFoundUser = true; 706 822 break; … … 710 826 if (!fFoundUser) 711 827 { 712 VBoxServiceVerbose(4, " VMInfo/Users: Adding new user=%lswith %u processes\n",713 UserInfo.wszUser, cSessionProcs);828 VBoxServiceVerbose(4, "Adding new user=%ls (session %u) with %u processes\n", 829 UserInfo.wszUser, ulSession, cSessionProcs); 714 830 715 831 memcpy(&pUserInfo[cUniqueUsers], &UserInfo, sizeof(VBOXSERVICEVMINFOUSER)); 716 pUserInfo[cUniqueUsers++].ulNumProcs = cSessionProcs; 832 pUserInfo[cUniqueUsers].ulNumProcs = cSessionProcs; 833 pUserInfo[cUniqueUsers].ulSession = ulSession; 834 cUniqueUsers++; 717 835 Assert(cUniqueUsers <= cSessions); 718 836 } … … 720 838 } 721 839 722 VBoxServiceVerbose(3, " VMInfo/Users:Found %u unique logged-in user(s)\n",840 VBoxServiceVerbose(3, "Found %u unique logged-in user(s)\n", 723 841 cUniqueUsers); 724 842 … … 728 846 if (pUserInfo[i].ulNumProcs) 729 847 { 848 VBoxServiceVerbose(3, "User %ls has %ld processes (session %u)\n", 849 pUserInfo[i].wszUser, pUserInfo[i].ulNumProcs, pUserInfo[i].ulSession); 850 730 851 if (*pcUsersInList > 0) 731 852 { -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp
r39129 r40158 83 83 84 84 85 #ifdef RT_OS_WINDOWS 86 static BOOL WINAPI VBoxServiceVMInfoConsoleControlHandler(DWORD dwCtrlType) 87 { 88 int rc = VINF_SUCCESS; 89 bool fEventHandled = FALSE; 90 switch (dwCtrlType) 91 { 92 case CTRL_LOGOFF_EVENT: 93 VBoxServiceVerbose(2, "VMInfo: Received logged-off event\n"); 94 /* Trigger a re-enumeration of all logged-in users by unblocking 95 * the multi event semaphore of the VMInfo thread. */ 96 if (g_hVMInfoEvent) 97 rc = RTSemEventMultiSignal(g_hVMInfoEvent); 98 fEventHandled = TRUE; 99 break; 100 default: 101 break; 102 /** @todo Add other events here. */ 103 } 104 105 if (RT_FAILURE(rc)) 106 VBoxServiceError("VMInfo: Event %ld handled with error rc=%Rrc\n", 107 dwCtrlType, rc); 108 return fEventHandled; 85 86 /** 87 * Signals the event so that a re-enumeration of VM-specific 88 * information (like logged in users) can happen. 89 * 90 * @return IPRT status code. 91 */ 92 int VBoxServiceVMInfoSignal(void) 93 { 94 /* Trigger a re-enumeration of all logged-in users by unblocking 95 * the multi event semaphore of the VMInfo thread. */ 96 if (g_hVMInfoEvent) 97 return RTSemEventMultiSignal(g_hVMInfoEvent); 98 99 return VINF_SUCCESS; 109 100 } 110 #endif /* RT_OS_WINDOWS */111 101 112 102 … … 182 172 VBoxServicePropCacheUpdateEntry(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/Net/Count", 183 173 VBOXSERVICEPROPCACHEFLAG_TEMPORARY | VBOXSERVICEPROPCACHEFLAG_ALWAYS_UPDATE, NULL /* Delete on exit */); 184 185 #ifdef RT_OS_WINDOWS186 # ifndef RT_OS_NT4187 /* Install console control handler. */188 if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)VBoxServiceVMInfoConsoleControlHandler, TRUE /* Add handler */))189 {190 VBoxServiceError("VMInfo: Unable to add console control handler, error=%ld\n", GetLastError());191 /* Just skip this error, not critical. */192 }193 # endif /* !RT_OS_NT4 */194 #endif /* RT_OS_WINDOWS */195 174 } 196 175 return rc; … … 301 280 && RT_SUCCESS(rc)) 302 281 { 303 VBoxServiceVerbose(4, " VMInfo/Users:Found logged in user \"%s\"\n",282 VBoxServiceVerbose(4, "Found logged in user \"%s\"\n", 304 283 ut_user->ut_user); 305 284 if (cUsersInList > cListSize) … … 369 348 static int s_iVMInfoBitchedOOM = 0; 370 349 if (s_iVMInfoBitchedOOM++ < 3) 371 VBoxServiceVerbose(0, " VMInfo/Users:Warning: Not enough memory available to enumerate users! Keeping old value (%u)\n",350 VBoxServiceVerbose(0, "Warning: Not enough memory available to enumerate users! Keeping old value (%u)\n", 372 351 g_cVMInfoLoggedInUsers); 373 352 cUsersInList = g_cVMInfoLoggedInUsers; … … 377 356 } 378 357 379 VBoxServiceVerbose(4, " VMInfo/Users:cUsersInList: %u, pszUserList: %s, rc=%Rrc\n",358 VBoxServiceVerbose(4, "cUsersInList: %u, pszUserList: %s, rc=%Rrc\n", 380 359 cUsersInList, pszUserList ? pszUserList : "<NULL>", rc); 381 360 … … 878 857 static DECLCALLBACK(void) VBoxServiceVMInfoTerm(void) 879 858 { 880 int rc;881 882 #ifdef RT_OS_WINDOWS883 # ifndef RT_OS_NT4884 /* Uninstall console control handler. */885 if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)NULL, FALSE /* Remove handler */))886 {887 VBoxServiceError("VMInfo: Unable to remove console control handler, error=%ld\n", GetLastError());888 /* Just skip this error, not critical. */889 }890 # endif /* !RT_OS_NT4 */891 #endif892 893 859 if (g_hVMInfoEvent != NIL_RTSEMEVENTMULTI) 894 860 { … … 906 872 /* Delete the "../Net" branch. */ 907 873 const char *apszPat[1] = { "/VirtualBox/GuestInfo/Net/*" }; 908 rc = VbglR3GuestPropDelSet(g_uVMInfoGuestPropSvcClientID, &apszPat[0], RT_ELEMENTS(apszPat));874 int rc = VbglR3GuestPropDelSet(g_uVMInfoGuestPropSvcClientID, &apszPat[0], RT_ELEMENTS(apszPat)); 909 875 910 876 /* Destroy property cache. */
Note:
See TracChangeset
for help on using the changeset viewer.