VirtualBox

Changeset 48678 in vbox


Ignore:
Timestamp:
Sep 25, 2013 11:11:22 AM (11 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
89300
Message:

Forward ported r89250 + r89298 (VBoxService/VMInfo: Fixed memory leak caused in WTSQuerySessionInformation on Windows OSes without appropriate hotfix, logging typo).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo-win.cpp

    r47977 r48678  
    4444#include "../../WINNT/VBoxTray/VBoxTrayMsg.h" /* For IPC. */
    4545
    46 static uint32_t s_uGuestPropClientID = 0;
    47 static uint32_t s_uIter = 0;
     46static uint32_t s_uDebugGuestPropClientID = 0;
     47static uint32_t s_uDebugIter = 0;
     48/** Whether to skip the logged-in user detection over RDP or not.
     49 *  See notes in this section why we might want to skip this. */
     50static bool s_fSkipRDPDetection = false;
    4851
    4952/*******************************************************************************
     
    138141    AssertReturn(cbName, VERR_INVALID_PARAMETER);
    139142
     143    /** @todo Only do this once. Later. */
    140144    OSVERSIONINFOEX OSInfoEx;
    141145    RT_ZERO(OSInfoEx);
     
    547551    {
    548552       VBoxServiceError("User SID=%p is not valid\n", pSessionData->Sid);
     553       if (pSessionData)
     554           LsaFreeReturnBuffer(pSessionData);
    549555       return 0;
    550556    }
     
    741747                                   pUserInfo->wszLogonDomain);
    742748
    743                 /* Detect RDP sessions as well. */
    744                 LPTSTR  pBuffer = NULL;
    745                 DWORD   cbRet   = 0;
    746                 int     iState  = -1;
    747                 if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE,
    748                                                pSessionData->Session,
    749                                                WTSConnectState,
    750                                                &pBuffer,
    751                                                &cbRet))
     749                /**
     750                 * Note: On certain Windows OSes WTSQuerySessionInformation leaks memory when used
     751                 * under a heavy stress situation. There are hotfixes available from Microsoft.
     752                 *
     753                 * See: http://support.microsoft.com/kb/970910
     754                 */
     755                if (!s_fSkipRDPDetection)
    752756                {
    753                     if (cbRet)
    754                         iState = *pBuffer;
    755                     VBoxServiceVerbose(3, "Account User=%ls, WTSConnectState=%d (%ld)\n",
    756                                        pUserInfo->wszUser, iState, cbRet);
    757                     if (    iState == WTSActive           /* User logged on to WinStation. */
    758                          || iState == WTSShadow           /* Shadowing another WinStation. */
    759                          || iState == WTSDisconnected)    /* WinStation logged on without client. */
    760                     {
    761                         /** @todo On Vista and W2K, always "old" user name are still
    762                          *        there. Filter out the old one! */
    763                         VBoxServiceVerbose(3, "Account User=%ls using TCS/RDP, state=%d \n",
    764                                            pUserInfo->wszUser, iState);
     757                    /** @todo Only do this once. Later. */
     758                    OSVERSIONINFOEX OSInfoEx;
     759                    RT_ZERO(OSInfoEx);
     760                    OSInfoEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
     761
     762                    /* Skip RDP detection on non-NT systems. */
     763                    if (   !GetVersionEx((LPOSVERSIONINFO) &OSInfoEx)
     764                        || OSInfoEx.dwPlatformId != VER_PLATFORM_WIN32_NT)
     765                    {
     766                        s_fSkipRDPDetection = true;
     767                    }
     768                    /* Skip RDP detection on Windows 2000.
     769                     * For Windows 2000 however we don't have any hotfixes, so just skip the
     770                     * RDP detection in any case. */
     771                    if (   OSInfoEx.dwMajorVersion == 5
     772                        && OSInfoEx.dwMinorVersion == 0)
     773                    {
     774                        s_fSkipRDPDetection = true;
     775                    }
     776
     777                    if (s_fSkipRDPDetection)
     778                        VBoxServiceVerbose(0, "Detection of logged-in users via RDP is disabled\n");
     779                }
     780
     781                if (!s_fSkipRDPDetection)
     782                {
     783                    /* Detect RDP sessions as well. */
     784                    LPTSTR  pBuffer = NULL;
     785                    DWORD   cbRet   = 0;
     786                    int     iState  = -1;
     787                    if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE,
     788                                                   pSessionData->Session,
     789                                                   WTSConnectState,
     790                                                   &pBuffer,
     791                                                   &cbRet))
     792                    {
     793                        if (cbRet)
     794                            iState = *pBuffer;
     795                        VBoxServiceVerbose(3, "Account User=%ls, WTSConnectState=%d (%ld)\n",
     796                                           pUserInfo->wszUser, iState, cbRet);
     797                        if (    iState == WTSActive           /* User logged on to WinStation. */
     798                             || iState == WTSShadow           /* Shadowing another WinStation. */
     799                             || iState == WTSDisconnected)    /* WinStation logged on without client. */
     800                        {
     801                            /** @todo On Vista and W2K, always "old" user name are still
     802                             *        there. Filter out the old one! */
     803                            VBoxServiceVerbose(3, "Account User=%ls using TCS/RDP, state=%d \n",
     804                                               pUserInfo->wszUser, iState);
     805                            fFoundUser = true;
     806                        }
     807                        if (pBuffer)
     808                            WTSFreeMemory(pBuffer);
     809                    }
     810                    else
     811                    {
     812                        DWORD dwLastErr = GetLastError();
     813                        switch (dwLastErr)
     814                        {
     815                            /*
     816                             * Terminal services don't run (for example in W2K,
     817                             * nothing to worry about ...).  ... or is on the Vista
     818                             * fast user switching page!
     819                             */
     820                            case ERROR_CTX_WINSTATION_NOT_FOUND:
     821                                VBoxServiceVerbose(3, "No WinStation found for user=%ls\n",
     822                                                   pUserInfo->wszUser);
     823                                break;
     824
     825                            default:
     826                                VBoxServiceVerbose(3, "Cannot query WTS connection state for user=%ls, error=%ld\n",
     827                                                   pUserInfo->wszUser, dwLastErr);
     828                                break;
     829                        }
     830
    765831                        fFoundUser = true;
    766832                    }
    767                     if (pBuffer)
    768                         WTSFreeMemory(pBuffer);
    769                 }
    770                 else
    771                 {
    772                     DWORD dwLastErr = GetLastError();
    773                     switch (dwLastErr)
    774                     {
    775                         /*
    776                          * Terminal services don't run (for example in W2K,
    777                          * nothing to worry about ...).  ... or is on the Vista
    778                          * fast user switching page!
    779                          */
    780                         case ERROR_CTX_WINSTATION_NOT_FOUND:
    781                             VBoxServiceVerbose(3, "No WinStation found for user=%ls\n",
    782                                                pUserInfo->wszUser);
    783                             break;
    784 
    785                         default:
    786                             VBoxServiceVerbose(3, "Cannot query WTS connection state for user=%ls, error=%ld\n",
    787                                                pUserInfo->wszUser, dwLastErr);
    788                             break;
    789                     }
    790 
    791                     fFoundUser = true;
    792833                }
    793834            }
     
    948989    AssertPtrReturn(pcUsersInList, VERR_INVALID_POINTER);
    949990
    950     PLUID       paSessions = NULL;
    951     ULONG       cSessions = 0;
    952 
    953     int rc2 = VbglR3GuestPropConnect(&s_uGuestPropClientID);
     991    int rc2 = VbglR3GuestPropConnect(&s_uDebugGuestPropClientID);
    954992    AssertRC(rc2);
    955993
    956994    /* This function can report stale or orphaned interactive logon sessions
    957995       of already logged off users (especially in Windows 2000). */
     996    PLUID    paSessions = NULL;
     997    ULONG    cSessions = 0;
    958998    NTSTATUS rcNt = LsaEnumerateLogonSessions(&cSessions, &paSessions);
    959999    if (rcNt != STATUS_SUCCESS)
     
    9741014
    9751015            default:
    976                 VBoxServiceError("LsaEnumerate failed with error %u\n", ulError);
     1016                VBoxServiceError("LsaEnumerate failed with error %RU32\n", ulError);
    9771017                break;
    9781018        }
     1019
     1020        if (paSessions)
     1021            LsaFreeReturnBuffer(paSessions);
    9791022
    9801023        return RTErrConvertFromWin32(ulError);
     
    10281071                        char szDebugSessionPath[255]; RTStrPrintf(szDebugSessionPath,  sizeof(szDebugSessionPath), "/VirtualBox/GuestInfo/Debug/LSA/Session/%RU32",
    10291072                                                                  userSession.ulLastSession);
    1030                         VBoxServiceWritePropF(s_uGuestPropClientID, szDebugSessionPath,
    1031                                               "#%RU32: cSessionProcs=%RU32 (of %RU32 procs total)", s_uIter, cCurSessionProcs, cProcs);
     1073                        VBoxServiceWritePropF(s_uDebugGuestPropClientID, szDebugSessionPath,
     1074                                              "#%RU32: cSessionProcs=%RU32 (of %RU32 procs total)", s_uDebugIter, cCurSessionProcs, cProcs);
    10321075                    }
    10331076
     
    10891132
    10901133            if (g_cVerbosity > 3)
    1091                 VBoxServiceWritePropF(s_uGuestPropClientID, "/VirtualBox/GuestInfo/Debug/LSA",
     1134                VBoxServiceWritePropF(s_uDebugGuestPropClientID, "/VirtualBox/GuestInfo/Debug/LSA",
    10921135                                      "#%RU32: cSessions=%RU32, cProcs=%RU32, cUniqueUsers=%RU32",
    1093                                       s_uIter, cSessions, cProcs, cUniqueUsers);
     1136                                      s_uDebugIter, cSessions, cProcs, cUniqueUsers);
    10941137
    10951138            VBoxServiceVerbose(3, "Found %u unique logged-in user(s)\n",
     
    11021145                {
    11031146                    char szDebugUserPath[255]; RTStrPrintf(szDebugUserPath,  sizeof(szDebugUserPath), "/VirtualBox/GuestInfo/Debug/LSA/User/%RU32", i);
    1104                     VBoxServiceWritePropF(s_uGuestPropClientID, szDebugUserPath,
     1147                    VBoxServiceWritePropF(s_uDebugGuestPropClientID, szDebugUserPath,
    11051148                                          "#%RU32: szName=%ls, sessionID=%RU32, cProcs=%RU32",
    1106                                           s_uIter, pUserInfo[i].wszUser, pUserInfo[i].ulLastSession, pUserInfo[i].ulNumProcs);
     1149                                          s_uDebugIter, pUserInfo[i].wszUser, pUserInfo[i].ulLastSession, pUserInfo[i].ulNumProcs);
    11071150                }
    11081151
     
    11531196        VBoxServiceVMInfoWinProcessesFree(cProcs, paProcs);
    11541197    }
    1155     LsaFreeReturnBuffer(paSessions);
    1156 
    1157     s_uIter++;
    1158     VbglR3GuestPropDisconnect(s_uGuestPropClientID);
     1198    if (paSessions)
     1199        LsaFreeReturnBuffer(paSessions);
     1200
     1201    s_uDebugIter++;
     1202    VbglR3GuestPropDisconnect(s_uDebugGuestPropClientID);
    11591203
    11601204    return rc;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette