- Timestamp:
- Feb 4, 2013 4:15:22 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo-win.cpp
r44528 r44530 57 57 /** Number of assigned user processes. */ 58 58 ULONG ulNumProcs; 59 /** Last (highest) session number. This59 /** Last (highest) session ID. This 60 60 * is needed for distinguishing old session 61 61 * process counts from new (current) session 62 62 * ones. */ 63 ULONG ul Session;63 ULONG ulLastSession; 64 64 } VBOXSERVICEVMINFOUSER, *PVBOXSERVICEVMINFOUSER; 65 65 … … 76 76 /** The PID. */ 77 77 DWORD id; 78 /** The SID. */ 79 PSID pSid; 78 80 /** The LUID. */ 79 81 LUID luid; … … 89 91 bool VBoxServiceVMInfoWinIsLoggedIn(PVBOXSERVICEVMINFOUSER a_pUserInfo, PLUID a_pSession); 90 92 int VBoxServiceVMInfoWinProcessesEnumerate(PVBOXSERVICEVMINFOPROC *ppProc, DWORD *pdwCount); 91 void VBoxServiceVMInfoWinProcessesFree( PVBOXSERVICEVMINFOPROC paProcs);93 void VBoxServiceVMInfoWinProcessesFree(DWORD cProcs, PVBOXSERVICEVMINFOPROC paProcs); 92 94 93 95 typedef BOOL WINAPI FNQUERYFULLPROCESSIMAGENAME(HANDLE, DWORD, LPTSTR, PDWORD); … … 238 240 case TokenGroups: 239 241 dwTokenInfoSize = 0; 240 /* Allocati ngwill follow in a second step. */242 /* Allocation will follow in a second step. */ 241 243 break; 242 244 243 /** @todo Implement more token classes here. */ 245 case TokenUser: 246 dwTokenInfoSize = 0; 247 /* Allocation will follow in a second step. */ 248 break; 244 249 245 250 default: … … 269 274 break; 270 275 276 case TokenUser: 277 pvTokenInfo = (PTOKEN_USER)HeapAlloc(GetProcessHeap(), 278 HEAP_ZERO_MEMORY, dwRetLength); 279 if (!pvTokenInfo) 280 dwErr = GetLastError(); 281 dwTokenInfoSize = dwRetLength; 282 break; 283 271 284 default: 272 285 AssertMsgFailed(("Re-allocating of token information for token class not implemented\n")); … … 291 304 { 292 305 PTOKEN_STATISTICS pStats = (PTOKEN_STATISTICS)pvTokenInfo; 306 AssertPtr(pStats); 293 307 memcpy(&pProc->luid, &pStats->AuthenticationId, sizeof(LUID)); 294 308 /** @todo Add more information of TOKEN_STATISTICS as needed. */ … … 336 350 } 337 351 352 case TokenUser: 353 { 354 PTOKEN_USER pUser = (PTOKEN_USER)pvTokenInfo; 355 AssertPtr(pUser); 356 357 DWORD dwLength = GetLengthSid(pUser->User.Sid); 358 Assert(dwLength); 359 if (dwLength) 360 { 361 pProc->pSid = (PSID)RTMemAlloc(dwLength); 362 AssertPtr(pProc->pSid); 363 if (CopySid(dwLength, pProc->pSid, pUser->User.Sid)) 364 { 365 if (!IsValidSid(pProc->pSid)) 366 dwErr = ERROR_INVALID_NAME; 367 } 368 else 369 dwErr = GetLastError(); 370 } 371 else 372 dwErr = ERROR_NO_DATA; 373 374 if (dwErr != ERROR_SUCCESS) 375 VBoxServiceError("Error retrieving SID of process PID=%ld: %ld\n", 376 pProc->id, dwErr); 377 break; 378 } 379 338 380 default: 339 381 AssertMsgFailed(("Unhandled token information class\n")); … … 423 465 { 424 466 paProcs[i].id = paPID[i]; 425 rc = VBoxServiceVMInfoWinProcessesGetTokenInfo(&paProcs[i], TokenGroups); 426 if (RT_FAILURE(rc)) 427 { 428 /* Because some processes cannot be opened/parsed on 429 Windows, we should not consider to be this an error here. */ 430 rc = VINF_SUCCESS; 431 } 432 else 433 { 434 rc = VBoxServiceVMInfoWinProcessesGetTokenInfo(&paProcs[i], TokenStatistics); 435 if (RT_FAILURE(rc)) 436 { 437 /* Because some processes cannot be opened/parsed on 438 Windows, we should not consider to be this an error here. */ 439 rc = VINF_SUCCESS; 440 } 441 } 467 paProcs[i].pSid = NULL; 468 469 int rc2 = VBoxServiceVMInfoWinProcessesGetTokenInfo(&paProcs[i], TokenUser); 470 if (RT_FAILURE(rc2) && g_cVerbosity) 471 VBoxServiceError("Get token class \"user\" for process %ld failed, rc=%Rrc\n", 472 paProcs[i].id, rc2); 473 474 rc2 = VBoxServiceVMInfoWinProcessesGetTokenInfo(&paProcs[i], TokenGroups); 475 if (RT_FAILURE(rc2) && g_cVerbosity) 476 VBoxServiceError("Get token class \"groups\" for process %ld failed, rc=%Rrc\n", 477 paProcs[i].id, rc2); 478 479 rc2 = VBoxServiceVMInfoWinProcessesGetTokenInfo(&paProcs[i], TokenStatistics); 480 if (RT_FAILURE(rc2) && g_cVerbosity) 481 VBoxServiceError("Get token class \"statistics\" for process %ld failed, rc=%Rrc\n", 482 paProcs[i].id, rc2); 442 483 } 443 484 … … 465 506 * @param paProcs What 466 507 */ 467 void VBoxServiceVMInfoWinProcessesFree(PVBOXSERVICEVMINFOPROC paProcs) 468 { 508 void VBoxServiceVMInfoWinProcessesFree(DWORD cProcs, PVBOXSERVICEVMINFOPROC paProcs) 509 { 510 for (DWORD i = 0; i < cProcs; i++) 511 { 512 if (paProcs[i].pSid) 513 RTMemFree(paProcs[i].pSid); 514 } 469 515 RTMemFree(paProcs); 470 516 } … … 474 520 * 475 521 * @returns Number of processes found for a specified session. 476 * @param pSession The session.522 * @param pSession The current user's SID. 477 523 * @param paProcs The process snapshot. 478 524 * @param cProcs The number of processes in the snaphot. … … 493 539 if (rcNt != STATUS_SUCCESS) 494 540 { 495 VBoxServiceError("Could not get logon session data! rcNt=%#x ", rcNt);541 VBoxServiceError("Could not get logon session data! rcNt=%#x\n", rcNt); 496 542 return 0; 497 543 } 544 545 if (!IsValidSid(pSessionData->Sid)) 546 { 547 VBoxServiceError("User SID=%p is not valid\n", pSessionData->Sid); 548 return 0; 549 } 550 551 int rc = VINF_SUCCESS; 498 552 499 553 /* … … 505 559 for (DWORD i = 0; i < cProcs; i++) 506 560 { 507 VBoxServiceVerbose(4, "PID=%ld: (Interactive: %RTbool) %ld:%ld <-> %ld:%ld\n",508 paProcs[i].id, paProcs[i].fInteractive,509 paProcs[i].luid.HighPart, paProcs[i].luid.LowPart,510 pSessionData->LogonId.HighPart, pSessionData->LogonId.LowPart);511 561 if (g_cVerbosity) 512 562 { 513 563 TCHAR szModule[_1K]; 514 int rc2= VBoxServiceVMInfoWinProcessesGetModuleName(&paProcs[i], szModule, sizeof(szModule));515 if (RT_SUCCESS(rc 2))564 rc = VBoxServiceVMInfoWinProcessesGetModuleName(&paProcs[i], szModule, sizeof(szModule)); 565 if (RT_SUCCESS(rc)) 516 566 VBoxServiceVerbose(4, "PID=%ld: %s\n", 517 567 paProcs[i].id, szModule); 518 568 } 519 569 520 if ( paProcs[i].fInteractive521 && ( paProcs[i].luid.HighPart == pSessionData->LogonId.HighPart522 && paProcs[i].luid.LowPart == pSessionData->LogonId.LowPart))523 {524 cNumProcs++;525 if ( !g_cVerbosity) /* We want a bit more info on higher verbosity. */526 break;527 }528 }529 530 if (g_cVerbosity)531 VBoxServiceVerbose(3, "Session has %u processes total\n", cNumProcs);532 else533 VBoxServiceVerbose(3, "Session has at least one process\n");570 PSID pProcSID = paProcs[i].pSid; 571 if ( RT_SUCCESS(rc) 572 && pProcSID 573 && IsValidSid(pProcSID)) 574 { 575 if ( EqualSid(pSessionData->Sid, paProcs[i].pSid) 576 && paProcs[i].fInteractive) 577 { 578 cNumProcs++; 579 if (!g_cVerbosity) /* We want a bit more info on higher verbosity. */ 580 break; 581 } 582 } 583 } 534 584 535 585 if (puTerminalSession) … … 537 587 538 588 LsaFreeReturnBuffer(pSessionData); 589 539 590 return cNumProcs; 540 591 } … … 611 662 } 612 663 613 VBoxServiceVerbose(3, "Session data: Name=%ls, Session =%u, LogonID=%ld,%ld, LogonType=%ld\n",664 VBoxServiceVerbose(3, "Session data: Name=%ls, SessionID=%RU32, LogonID=%ld,%ld, LogonType=%ld\n", 614 665 pSessionData->UserName.Buffer, 615 666 pSessionData->Session, … … 749 800 } 750 801 802 if (fFoundUser) 803 pUserInfo->ulLastSession = pSessionData->Session; 804 751 805 LsaFreeReturnBuffer(pSessionData); 752 806 return fFoundUser; … … 823 877 { 824 878 ULONG cUniqueUsers = 0; 879 880 /** 881 * Note: The cSessions loop variable does *not* correlate with 882 * the Windows session ID! 883 */ 825 884 for (ULONG i = 0; i < cSessions; i++) 826 885 { 827 VBoxServiceVerbose(3, "Handling session % u\n", i);828 829 VBOXSERVICEVMINFOUSER UserInfo;830 if (VBoxServiceVMInfoWinIsLoggedIn(& UserInfo, &paSessions[i]))886 VBoxServiceVerbose(3, "Handling session %RU32 (of %RU32)\n", i + 1, cSessions); 887 888 VBOXSERVICEVMINFOUSER userSession; 889 if (VBoxServiceVMInfoWinIsLoggedIn(&userSession, &paSessions[i])) 831 890 { 832 VBoxServiceVerbose(4, "Handling user=%ls, domain=%ls, package=%ls\n", 833 UserInfo.wszUser, UserInfo.wszLogonDomain, UserInfo.wszAuthenticationPackage); 891 VBoxServiceVerbose(4, "Handling user=%ls, domain=%ls, package=%ls, session=%RU32\n", 892 userSession.wszUser, userSession.wszLogonDomain, userSession.wszAuthenticationPackage, 893 userSession.ulLastSession); 834 894 835 895 /* Retrieve assigned processes of current session. */ 836 uint32_t c SessionProcs = VBoxServiceVMInfoWinSessionHasProcesses(&paSessions[i], paProcs, cProcs,837 NULL /* Terminal session ID */);896 uint32_t cCurSessionProcs = VBoxServiceVMInfoWinSessionHasProcesses(&paSessions[i], paProcs, cProcs, 897 NULL /* Terminal session ID */); 838 898 /* Don't return here when current session does not have assigned processes 839 899 * anymore -- in that case we have to search through the unique users list below 840 900 * and see if got a stale user/session entry. */ 841 901 842 #ifdef DEBUG 843 char szDebugUserPath[255]; RTStrPrintf(szDebugUserPath, sizeof(szDebugUserPath), "/VirtualBox/GuestInfo/Debug/LSA/Session/%RU32", i); 844 VBoxServiceWritePropF(s_uGuestPropClientID, szDebugUserPath, 845 "%RU32: cSessionProcs=%RU32 (%RU32 total)", s_uIter, cSessionProcs, cProcs); 846 #endif 902 if (g_cVerbosity > 3) 903 { 904 char szDebugSessionPath[255]; RTStrPrintf(szDebugSessionPath, sizeof(szDebugSessionPath), "/VirtualBox/GuestInfo/Debug/LSA/Session/%RU32", 905 userSession.ulLastSession); 906 VBoxServiceWritePropF(s_uGuestPropClientID, szDebugSessionPath, 907 "#%RU32: cSessionProcs=%RU32 (of %RU32 procs total)", s_uIter, cCurSessionProcs, cProcs); 908 } 909 847 910 bool fFoundUser = false; 848 911 for (ULONG a = 0; a < cUniqueUsers; a++) … … 851 914 AssertPtr(pCurUser); 852 915 853 if ( !wcscmp( UserInfo.wszUser, pCurUser->wszUser)854 && !wcscmp( UserInfo.wszLogonDomain, pCurUser->wszLogonDomain)855 && !wcscmp( UserInfo.wszAuthenticationPackage, pCurUser->wszAuthenticationPackage))916 if ( !wcscmp(userSession.wszUser, pCurUser->wszUser) 917 && !wcscmp(userSession.wszLogonDomain, pCurUser->wszLogonDomain) 918 && !wcscmp(userSession.wszAuthenticationPackage, pCurUser->wszAuthenticationPackage)) 856 919 { 857 920 /* 858 921 * Only respect the highest session for the current user. 859 922 */ 860 if ( i > pCurUser->ulSession)923 if (userSession.ulLastSession > pCurUser->ulLastSession) 861 924 { 862 VBoxServiceVerbose(4, "Updating user=%ls to %u processes (last session=%RU32)\n",863 pCurUser->wszUser, c SessionProcs, i);864 865 if (!c SessionProcs)866 VBoxServiceVerbose(3, "Stale session for user=%ls detected! Proc s %RU32->%RU32, Session RU%32->RU32\n",925 VBoxServiceVerbose(4, "Updating user=%ls to %u processes (last used session: %RU32)\n", 926 pCurUser->wszUser, cCurSessionProcs, userSession.ulLastSession); 927 928 if (!cCurSessionProcs) 929 VBoxServiceVerbose(3, "Stale session for user=%ls detected! Processes: %RU32 -> %RU32, Session: %RU32 -> %RU32\n", 867 930 pCurUser->wszUser, 868 pCurUser->ulNumProcs, c SessionProcs,869 pCurUser->ul Session, i);870 871 pCurUser->ulNumProcs = c SessionProcs;872 pCurUser->ul Session = i;931 pCurUser->ulNumProcs, cCurSessionProcs, 932 pCurUser->ulLastSession, userSession.ulLastSession); 933 934 pCurUser->ulNumProcs = cCurSessionProcs; 935 pCurUser->ulLastSession = userSession.ulLastSession; 873 936 } 874 937 /* There can be multiple session objects using the same session ID for the 875 938 * current user -- so when we got the same session again just add the found 876 939 * processes to it. */ 877 else if ( pCurUser->ulSession == i 878 && cSessionProcs) 940 else if (pCurUser->ulLastSession == userSession.ulLastSession) 879 941 { 880 VBoxServiceVerbose(4, " Adding %u processes to user=%ls (session=%RU32)\n",881 cSessionProcs, pCurUser->wszUser, i);882 883 pCurUser->ulNumProcs += cSessionProcs;942 VBoxServiceVerbose(4, "Updating processes for user=%ls (old procs=%RU32, new procs=%RU32, session=%RU32)\n", 943 pCurUser->wszUser, pCurUser->ulNumProcs, cCurSessionProcs, pCurUser->ulLastSession); 944 945 pCurUser->ulNumProcs = cCurSessionProcs; 884 946 } 885 947 … … 891 953 if (!fFoundUser) 892 954 { 893 VBoxServiceVerbose(4, "Adding new user=%ls (session=%RU32) with %u processes\n", 894 UserInfo.wszUser, i, cSessionProcs); 895 896 memcpy(&pUserInfo[cUniqueUsers], &UserInfo, sizeof(VBOXSERVICEVMINFOUSER)); 897 pUserInfo[cUniqueUsers].ulNumProcs = cSessionProcs; 898 pUserInfo[cUniqueUsers].ulSession = i; 955 VBoxServiceVerbose(4, "Adding new user=%ls (session=%RU32) with %RU32 processes\n", 956 userSession.wszUser, userSession.ulLastSession, cCurSessionProcs); 957 958 memcpy(&pUserInfo[cUniqueUsers], &userSession, sizeof(VBOXSERVICEVMINFOUSER)); 959 pUserInfo[cUniqueUsers].ulNumProcs = cCurSessionProcs; 899 960 cUniqueUsers++; 900 961 Assert(cUniqueUsers <= cSessions); … … 903 964 } 904 965 905 #ifdef DEBUG 906 VBoxServiceWritePropF(s_uGuestPropClientID, "/VirtualBox/GuestInfo/Debug/LSA",907 "%RU32: cSessions=%RU32, cProcs=%RU32, cUniqueUsers=%RU32",908 s_uIter, cSessions, cProcs, cUniqueUsers);909 #endif 966 if (g_cVerbosity > 3) 967 VBoxServiceWritePropF(s_uGuestPropClientID, "/VirtualBox/GuestInfo/Debug/LSA", 968 "#%RU32: cSessions=%RU32, cProcs=%RU32, cUniqueUsers=%RU32", 969 s_uIter, cSessions, cProcs, cUniqueUsers); 970 910 971 VBoxServiceVerbose(3, "Found %u unique logged-in user(s)\n", 911 972 cUniqueUsers); … … 914 975 for (ULONG i = 0; i < cUniqueUsers; i++) 915 976 { 916 #ifdef DEBUG 917 char szDebugUserPath[255]; RTStrPrintf(szDebugUserPath, sizeof(szDebugUserPath), "/VirtualBox/GuestInfo/Debug/LSA/User/%RU32", i); 918 VBoxServiceWritePropF(s_uGuestPropClientID, szDebugUserPath, 919 "%RU32: szName=%ls, sessionID=%RU32, cProcs=%RU32", 920 s_uIter, pUserInfo[i].wszUser, pUserInfo[i].ulSession, pUserInfo[i].ulNumProcs); 921 #endif 977 if (g_cVerbosity > 3) 978 { 979 char szDebugUserPath[255]; RTStrPrintf(szDebugUserPath, sizeof(szDebugUserPath), "/VirtualBox/GuestInfo/Debug/LSA/User/%RU32", i); 980 VBoxServiceWritePropF(s_uGuestPropClientID, szDebugUserPath, 981 "#%RU32: szName=%ls, sessionID=%RU32, cProcs=%RU32", 982 s_uIter, pUserInfo[i].wszUser, pUserInfo[i].ulLastSession, pUserInfo[i].ulNumProcs); 983 } 984 922 985 bool fAddUser = false; 923 986 if (pUserInfo[i].ulNumProcs) … … 926 989 if (fAddUser) 927 990 { 928 VBoxServiceVerbose(3, "User %ls has %ld interactive processes (session %u)\n",929 pUserInfo[i].wszUser, pUserInfo[i].ulNumProcs, pUserInfo[i].ul Session);991 VBoxServiceVerbose(3, "User \"%ls\" has %RU32 interactive processes (session=%RU32)\n", 992 pUserInfo[i].wszUser, pUserInfo[i].ulNumProcs, pUserInfo[i].ulLastSession); 930 993 931 994 if (*pcUsersInList > 0) … … 952 1015 RTMemFree(pUserInfo); 953 1016 } 954 VBoxServiceVMInfoWinProcessesFree( paProcs);1017 VBoxServiceVMInfoWinProcessesFree(cProcs, paProcs); 955 1018 } 956 1019 LsaFreeReturnBuffer(paSessions);
Note:
See TracChangeset
for help on using the changeset viewer.