VirtualBox

Changeset 29858 in vbox for trunk


Ignore:
Timestamp:
May 28, 2010 12:54:03 PM (15 years ago)
Author:
vboxsync
Message:

VBoxService/win: Cleaned up + fixed logged on user detection, make "NoLoggedInUsers" work with property cache, moved Windows parts of VM info to VBoxServiceVMInfo-win.cpp.

Location:
trunk/src/VBox/Additions/common/VBoxService
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h

    r29817 r29858  
    102102/** The following constant may be defined by including NtStatus.h. */
    103103# define STATUS_SUCCESS             ((NTSTATUS)0x00000000L)
    104 
    105 /** @todo Move these Windows stuff into VBoxServiceVMInfo-win.cpp and hide all
    106  *        the windows details using behind function calls!
    107  * @{  */
    108 /** Structure for storing the looked up user information. */
    109 typedef struct
    110 {
    111     WCHAR wszUser[_MAX_PATH];
    112     WCHAR wszAuthenticationPackage[_MAX_PATH];
    113     WCHAR wszLogonDomain[_MAX_PATH];
    114 } VBOXSERVICEVMINFOUSER, *PVBOXSERVICEVMINFOUSER;
    115 /** Structure for the file information lookup. */
    116 typedef struct
    117 {
    118     char *pszFilePath;
    119     char *pszFileName;
    120 } VBOXSERVICEVMINFOFILE, *PVBOXSERVICEVMINFOFILE;
    121 /** Structure for process information lookup. */
    122 typedef struct
    123 {
    124     DWORD id;
    125     LUID luid;
    126 } VBOXSERVICEVMINFOPROC, *PVBOXSERVICEVMINFOPROC;
    127 /** Function prototypes for dynamic loading. */
    128 typedef DWORD (WINAPI *PFNWTSGETACTIVECONSOLESESSIONID)(void);
    129 /** @} */
    130104
    131105#endif /* RT_OS_WINDOWS */
     
    290264
    291265#ifdef RT_OS_WINDOWS
    292 extern PFNWTSGETACTIVECONSOLESESSIONID g_pfnWTSGetActiveConsoleSessionId; /* VBoxServiceVMInfo-win.cpp */
    293266# ifdef VBOX_WITH_GUEST_PROPS
    294 extern bool VBoxServiceVMInfoWinSessionHasProcesses(PLUID pSession, VBOXSERVICEVMINFOPROC const *paProcs, DWORD cProcs);
    295 extern bool VBoxServiceVMInfoWinIsLoggedIn(PVBOXSERVICEVMINFOUSER a_pUserInfo, PLUID a_pSession);
    296 extern int  VBoxServiceVMInfoWinProcessesEnumerate(PVBOXSERVICEVMINFOPROC *ppProc, DWORD *pdwCount);
    297 extern void VBoxServiceVMInfoWinProcessesFree(PVBOXSERVICEVMINFOPROC paProcs);
    298 extern int  VBoxServiceWinGetComponentVersions(uint32_t uiClientID);
     267extern int VBoxServiceVMInfoWinWriteUsers(char **ppszUserList, uint32_t *pcUsersInList);
     268extern int VBoxServiceWinGetComponentVersions(uint32_t uiClientID);
    299269# endif /* VBOX_WITH_GUEST_PROPS */
    300270#endif /* RT_OS_WINDOWS */
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo-win.cpp

    r28800 r29858  
    3737
    3838
     39/** Structure for storing the looked up user information. */
     40typedef struct
     41{
     42    WCHAR wszUser[_MAX_PATH];
     43    WCHAR wszAuthenticationPackage[_MAX_PATH];
     44    WCHAR wszLogonDomain[_MAX_PATH];
     45} VBOXSERVICEVMINFOUSER, *PVBOXSERVICEVMINFOUSER;
     46/** Structure for the file information lookup. */
     47typedef struct
     48{
     49    char *pszFilePath;
     50    char *pszFileName;
     51} VBOXSERVICEVMINFOFILE, *PVBOXSERVICEVMINFOFILE;
     52/** Structure for process information lookup. */
     53typedef struct
     54{
     55    DWORD id;
     56    LUID luid;
     57} VBOXSERVICEVMINFOPROC, *PVBOXSERVICEVMINFOPROC;
     58
     59
     60/*******************************************************************************
     61*   Prototypes
     62*******************************************************************************/
     63bool VBoxServiceVMInfoWinSessionHasProcesses(PLUID pSession, VBOXSERVICEVMINFOPROC const *paProcs, DWORD cProcs);
     64bool VBoxServiceVMInfoWinIsLoggedIn(PVBOXSERVICEVMINFOUSER a_pUserInfo, PLUID a_pSession);
     65int  VBoxServiceVMInfoWinProcessesEnumerate(PVBOXSERVICEVMINFOPROC *ppProc, DWORD *pdwCount);
     66void VBoxServiceVMInfoWinProcessesFree(PVBOXSERVICEVMINFOPROC paProcs);
     67
     68
    3969/*******************************************************************************
    4070*   Global Variables                                                           *
    4171*******************************************************************************/
    42 /** Function prototypes for dynamic loading. */
    43 PFNWTSGETACTIVECONSOLESESSIONID g_pfnWTSGetActiveConsoleSessionId = NULL;
    4472
    4573
     
    288316
    289317/**
    290  * Detects whether a user is logged on based on the enumerated processes.
     318 * Detects whether a user is logged on.
    291319 *
    292320 * @returns true if logged in, false if not (or error).
     
    296324bool VBoxServiceVMInfoWinIsLoggedIn(PVBOXSERVICEVMINFOUSER a_pUserInfo, PLUID a_pSession)
    297325{
     326    AssertPtr(a_pUserInfo);
    298327    if (!a_pSession)
    299328        return false;
     
    303332    if (rcNt != STATUS_SUCCESS)
    304333    {
    305         VBoxServiceError("LsaGetLogonSessionData failed, LSA error %#x\n", LsaNtStatusToWinError(rcNt));
     334        VBoxServiceError("VMInfo/Users: LsaGetLogonSessionData failed, LSA error %#x\n", LsaNtStatusToWinError(rcNt));
    306335        if (pSessionData)
    307336            LsaFreeReturnBuffer(pSessionData);
     
    310339    if (!pSessionData)
    311340    {
    312         VBoxServiceError("Invalid logon session data.\n");
     341        VBoxServiceError("VMInfo/Users: Invalid logon session data!\n");
    313342        return false;
    314343    }
    315     VBoxServiceVerbose(3, "Users: Session data: Name = %ls, Len = %d, SID = %s, LogonID = %d,%d\n",
    316                        pSessionData->UserName.Buffer,
    317                        pSessionData->UserName.Length,
    318                        pSessionData->Sid != NULL ? "1" : "0",
    319                        pSessionData->LogonId.HighPart, pSessionData->LogonId.LowPart);
    320 
     344
     345    /*
     346     * Only handle users which can login interactively or logged in
     347     * remotely over native RDP.
     348     */
    321349    bool fFoundUser = false;
    322     if (   pSessionData->UserName.Buffer != NULL
    323         && pSessionData->Sid != NULL
    324         && pSessionData->LogonId.LowPart != 0)
    325     {
     350    DWORD dwErr = NO_ERROR;
     351    if (   IsValidSid(pSessionData->Sid)
     352        && (   (SECURITY_LOGON_TYPE)pSessionData->LogonType == Interactive
     353            || (SECURITY_LOGON_TYPE)pSessionData->LogonType == RemoteInteractive
     354            || (SECURITY_LOGON_TYPE)pSessionData->LogonType == CachedInteractive
     355            || (SECURITY_LOGON_TYPE)pSessionData->LogonType == CachedRemoteInteractive))
     356    {
     357        VBoxServiceVerbose(3, "VMInfo/Users: Session data: Name=%ls, Len=%d, SID=%s, LogonID=%ld,%ld\n",
     358                           pSessionData->UserName.Buffer,
     359                           pSessionData->UserName.Length,
     360                           pSessionData->Sid != NULL ? "1" : "0",
     361                           pSessionData->LogonId.HighPart, pSessionData->LogonId.LowPart);
     362
    326363        /*
    327          * Copy out the data.
     364         * Copy out relevant data.
    328365         */
    329366        VBoxServiceVMInfoWinSafeCopy(a_pUserInfo->wszUser, sizeof(a_pUserInfo->wszUser),
     
    334371                                     &pSessionData->LogonDomain, "Logon domain name");
    335372
    336 
    337         /*
    338          * Only handle users which can login interactively or logged in
    339          * remotely over native RDP.
    340          */
    341         /** @todo r=bird: Whey don't we check this before copying the data? */
    342         if (   (   (SECURITY_LOGON_TYPE)pSessionData->LogonType == Interactive
    343                 || (SECURITY_LOGON_TYPE)pSessionData->LogonType == RemoteInteractive)
    344             &&  pSessionData->Sid != NULL)
    345         {
    346             TCHAR           szOwnerName[_MAX_PATH]  = { 0 };
    347             DWORD           dwOwnerNameSize         = sizeof(szOwnerName);
    348             TCHAR           szDomainName[_MAX_PATH] = { 0 };
    349             DWORD           dwDomainNameSize        = sizeof(szDomainName);
    350             SID_NAME_USE    enmOwnerType            = SidTypeInvalid;
    351             if (LookupAccountSid(NULL,
    352                                  pSessionData->Sid,
    353                                  szOwnerName,
    354                                  &dwOwnerNameSize,
    355                                  szDomainName,
    356                                  &dwDomainNameSize,
    357                                  &enmOwnerType))
     373        TCHAR           szOwnerName[_MAX_PATH]  = { 0 };
     374        DWORD           dwOwnerNameSize         = sizeof(szOwnerName);
     375        TCHAR           szDomainName[_MAX_PATH] = { 0 };
     376        DWORD           dwDomainNameSize        = sizeof(szDomainName);
     377        SID_NAME_USE    enmOwnerType            = SidTypeInvalid;
     378        if (!LookupAccountSid(NULL,
     379                              pSessionData->Sid,
     380                              szOwnerName,
     381                              &dwOwnerNameSize,
     382                              szDomainName,
     383                              &dwDomainNameSize,
     384                              &enmOwnerType))
     385        {
     386            VBoxServiceError("VMInfo/Users: Failed looking up account info for user '%ls': %ld!\n",
     387                             a_pUserInfo->wszUser, GetLastError());
     388        }
     389        else
     390        {
     391            if (enmOwnerType == SidTypeUser) /* Only recognize users; we don't care about the rest! */
    358392            {
    359                 VBoxServiceVerbose(3, "Account User=%ls, Session=%ld, LUID=%ld,%ld, AuthPkg=%ls, Domain=%ls\n",
     393                VBoxServiceVerbose(3, "VMInfo/Users: Account User=%ls, Session=%ld, LUID=%ld,%ld, AuthPkg=%ls, Domain=%ls\n",
    360394                                   a_pUserInfo->wszUser, pSessionData->Session, pSessionData->LogonId.HighPart,
    361395                                   pSessionData->LogonId.LowPart, a_pUserInfo->wszAuthenticationPackage,
    362396                                   a_pUserInfo->wszLogonDomain);
    363397
    364 #if 1 /** @todo If we don't use this, drop it? */
    365                 /* The session ID increments/decrements on Vista often! So don't compare
    366                    the session data SID with the current SID here. */
    367                 DWORD dwActiveSession = 0;
    368                 if (g_pfnWTSGetActiveConsoleSessionId != NULL)            /* Check terminal session ID. */
    369                     dwActiveSession = g_pfnWTSGetActiveConsoleSessionId();
    370                 /*VBoxServiceVerbose(3, ("Users: Current active session ID: %ld\n", dwActiveSession));*/
    371 #endif
    372 
    373                 if (enmOwnerType == SidTypeUser)
     398                /* Detect RDP sessions as well. */
     399                LPTSTR  pBuffer = NULL;
     400                DWORD   cbRet   = 0;
     401                int     iState  = 0;
     402                if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE,
     403                                               pSessionData->Session,
     404                                               WTSConnectState,
     405                                               &pBuffer,
     406                                               &cbRet))
    374407                {
    375                     /* Detect RDP sessions as well. */
    376                     LPTSTR  pBuffer = NULL;
    377                     DWORD   cbRet   = 0;
    378                     int     iState  = 0;
    379                     if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE,
    380                                                    WTS_CURRENT_SESSION,
    381                                                    WTSConnectState,
    382                                                    &pBuffer,
    383                                                    &cbRet))
     408                    if(cbRet)
     409                        iState = *pBuffer;
     410                    VBoxServiceVerbose(3, "VMInfo/Users:  Account User=%ls, WTSConnectState=%d\n",
     411                                       a_pUserInfo->wszUser, iState);
     412                    if (    iState == WTSActive           /* User logged on to WinStation. */
     413                         || iState == WTSShadow           /* Shadowing another WinStation. */
     414                         || iState == WTSDisconnected)    /* WinStation logged on without client. */
    384415                    {
    385                         /*VBoxServiceVerbose(3, ("Users: WTSQuerySessionInformation returned %ld bytes, p=%p, state=%d\n", cbRet, pBuffer, pBuffer != NULL ? (INT)*pBuffer : -1));*/
    386                         if(cbRet)
    387                             iState = *pBuffer;
    388 
    389                         if (    iState == WTSActive           /* User logged on to WinStation. */
    390                              || iState == WTSShadow           /* Shadowing another WinStation. */
    391                              || iState == WTSDisconnected)    /* WinStation logged on without client. */
    392                         {
    393                             /** @todo On Vista and W2K, always "old" user name are still
    394                              *        there. Filter out the old one! */
    395                             VBoxServiceVerbose(3, "Users: Account User=%ls is logged in via TCS/RDP. State=%d\n",
    396                                                a_pUserInfo->wszUser, iState);
    397                             fFoundUser = true;
    398                         }
    399 
    400                         if (pBuffer)
    401                             WTSFreeMemory(pBuffer);
    402                     }
    403                     else
    404                     {
    405                         /*
    406                          * Terminal services don't run (for example in W2K,
    407                          * nothing to worry about ...).  ... or is on the Vista
    408                          * fast user switching page!
    409                          */
     416                        /** @todo On Vista and W2K, always "old" user name are still
     417                         *        there. Filter out the old one! */
     418                        VBoxServiceVerbose(3, "VMInfo/Users: Account User=%ls is logged in via TCS/RDP. State=%d\n",
     419                                           a_pUserInfo->wszUser, iState);
    410420                        fFoundUser = true;
    411421                    }
     422                    if (pBuffer)
     423                        WTSFreeMemory(pBuffer);
     424                }
     425                else
     426                {
     427                    VBoxServiceVerbose(3, "VMInfo/Users:  Account User=%ls, WTSConnectState returnd %ld\n",
     428                                       a_pUserInfo->wszUser, GetLastError());
     429
     430                    /*
     431                     * Terminal services don't run (for example in W2K,
     432                     * nothing to worry about ...).  ... or is on the Vista
     433                     * fast user switching page!
     434                     */
     435                    fFoundUser = true;
    412436                }
    413437            }
    414438        }
    415     }
     439    }   
    416440
    417441    LsaFreeReturnBuffer(pSessionData);
    418442    return fFoundUser;
     443}
     444
     445
     446/**
     447 * Retrieves the currently logged in users and stores their names along with the
     448 * user count.
     449 *
     450 * @returns VBox status code.
     451 * @param   ppszUserList    Where to store the user list (separated by commas).  Must be
     452 *                          freed with RTStrFree().
     453 * @param   pcUsersInList   Where to store the number of users in the list.
     454 */
     455int VBoxServiceVMInfoWinWriteUsers(char **ppszUserList, uint32_t *pcUsersInList)
     456{
     457    PLUID       paSessions = NULL;
     458    ULONG       cSession = 0;
     459    NTSTATUS    r = 0;
     460
     461    /* This function can report stale or orphaned interactive logon sessions
     462       of already logged off users (especially in Windows 2000). */
     463    r = LsaEnumerateLogonSessions(&cSession, &paSessions);
     464    VBoxServiceVerbose(3, "VMInfo/Users: Found %ld users\n", cSession);
     465    if (r != STATUS_SUCCESS)
     466    {
     467        VBoxServiceError("VMInfo/Users: LsaEnumerate failed with %lu\n", LsaNtStatusToWinError(r));
     468        return RTErrConvertFromWin32(LsaNtStatusToWinError(r));
     469    }
     470
     471    PVBOXSERVICEVMINFOPROC  paProcs;
     472    DWORD                   cProcs;
     473    int rc = VBoxServiceVMInfoWinProcessesEnumerate(&paProcs, &cProcs);
     474    if (RT_SUCCESS(rc))
     475    {
     476        *pcUsersInList = 0;
     477        for (ULONG i = 0; i < cSession; i++)
     478        {
     479            VBOXSERVICEVMINFOUSER UserInfo;
     480            if (   VBoxServiceVMInfoWinIsLoggedIn(&UserInfo, &paSessions[i])
     481                && VBoxServiceVMInfoWinSessionHasProcesses(&paSessions[i], paProcs, cProcs))
     482            {
     483                if (*pcUsersInList > 0)
     484                {
     485                    rc = RTStrAAppend(ppszUserList, ",");
     486                    AssertRCReturn(rc, rc);
     487                }
     488
     489                *pcUsersInList += 1;
     490
     491                char *pszTemp;
     492                int rc2 = RTUtf16ToUtf8(UserInfo.wszUser, &pszTemp);
     493                if (RT_SUCCESS(rc2))
     494                {
     495                    rc = RTStrAAppend(ppszUserList, pszTemp);
     496                    RTMemFree(pszTemp);
     497                    AssertRCReturn(rc, rc);
     498                }
     499                else
     500                    RTStrAAppend(ppszUserList, "<string-convertion-error>");
     501            }
     502        }
     503        VBoxServiceVMInfoWinProcessesFree(paProcs);
     504    }
     505    LsaFreeReturnBuffer(paSessions);
    419506}
    420507
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp

    r29852 r29858  
    113113    AssertRCReturn(rc, rc);
    114114
    115 #ifdef RT_OS_WINDOWS
    116     /** @todo r=bird: call a windows specific init function and move
    117      *        g_pfnWTSGetActiveConsoleSessionId out of the global scope.  */
    118     /* Get function pointers. */
    119     HMODULE hKernel32 = LoadLibrary("kernel32");
    120     if (hKernel32 != NULL)
    121     {
    122         g_pfnWTSGetActiveConsoleSessionId = (PFNWTSGETACTIVECONSOLESESSIONID)GetProcAddress(hKernel32, "WTSGetActiveConsoleSessionId");
    123         FreeLibrary(hKernel32);
    124     }
    125 #endif
    126 
    127115    rc = VbglR3GuestPropConnect(&g_uVMInfoGuestPropSvcClientID);
    128116    if (RT_SUCCESS(rc))
     
    228216{
    229217    int rc;
    230     char szUserList[4096] = {0};
     218    char *pszUserList = NULL;
    231219    uint32_t cUsersInList = 0;
    232220
    233221#ifdef RT_OS_WINDOWS
    234222# ifndef TARGET_NT4
    235     PLUID       paSessions = NULL;
    236     ULONG       cSession = 0;
    237     NTSTATUS    r = 0;
    238 
    239     /* This function can report stale or orphaned interactive logon sessions
    240        of already logged off users (especially in Windows 2000). */
    241     r = ::LsaEnumerateLogonSessions(&cSession, &paSessions);
    242     VBoxServiceVerbose(3, "Users: Found %ld users.\n", cSession);
    243     if (r != STATUS_SUCCESS)
    244     {
    245         VBoxServiceError("VMInfo/Users: LsaEnumerate failed %lu\n", LsaNtStatusToWinError(r));
    246         return RTErrConvertFromWin32(LsaNtStatusToWinError(r));
    247     }
    248 
    249     PVBOXSERVICEVMINFOPROC  paProcs;
    250     DWORD                   cProcs;
    251     rc = VBoxServiceVMInfoWinProcessesEnumerate(&paProcs, &cProcs);
    252     if (RT_SUCCESS(rc))
    253     {
    254         for (ULONG i = 0; i < cSession; i++)
    255         {
    256             VBOXSERVICEVMINFOUSER UserInfo;
    257             if (   VBoxServiceVMInfoWinIsLoggedIn(&UserInfo, &paSessions[i])
    258                 && VBoxServiceVMInfoWinSessionHasProcesses(&paSessions[i], paProcs, cProcs))
    259             {
    260                 if (cUsersInList > 0)
    261                     strcat(szUserList, ",");
    262 
    263                 cUsersInList++;
    264 
    265                 char *pszTemp;
    266                 int rc2 = RTUtf16ToUtf8(UserInfo.wszUser, &pszTemp);
    267                 if (RT_SUCCESS(rc2))
    268                 {
    269                     strcat(szUserList, pszTemp);
    270                     RTMemFree(pszTemp);
    271                 }
    272                 else
    273                     strcat(szUserList, "<string-convertion-error>");
    274             }
    275         }
    276         VBoxServiceVMInfoWinProcessesFree(paProcs);
    277     }
    278 
    279     ::LsaFreeReturnBuffer(paSessions);
     223    rc = VBoxServiceVMInfoWinWriteUsers(&pszUserList, &cUsersInList);
    280224# endif /* TARGET_NT4 */
    281225#elif defined(RT_OS_FREEBSD)
     
    298242    {
    299243        /* Make sure we don't add user names which are not
    300          * part of type USER_PROCESS and don't add same users twice. */
    301         if (   ut_user->ut_type == USER_PROCESS
    302             && strstr(szUserList, ut_user->ut_user) == NULL)
    303         {
    304             /** @todo Do we really want to filter out double user names? (Same user logged in twice)
    305              *  bird: If we do, then we must add checks for buffer overflows here!  */
    306             /** @todo r=bird: strstr will filtering out users with similar names. For
    307              *        example: smith, smithson, joesmith and bobsmith */
     244         * part of type USER_PROCESS. */
     245
     246        /** @todo Do we want to filter out user names? What if a user is logged in twice? */
     247        if (ut_user->ut_type == USER_PROCESS)
     248        {
    308249            if (cUsersInList > 0)
    309                 strcat(szUserList, ",");
    310             strcat(szUserList, ut_user->ut_user);
     250            {
     251                rc = RTStrAAppend(pszUserList, ",");
     252                AssertRCReturn(rc, rc);
     253            }
     254            rc = RTStrAAppend(pszUserList, ut_user->ut_user);
     255            AssertRCReturn(rc, rc);
    311256            cUsersInList++;
    312257        }
     
    315260#endif /* !RT_OS_WINDOWS */
    316261
    317     if (cUsersInList > 0)
    318         VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsersList", "%s", szUserList);
     262    if (pszUserList && cUsersInList > 0)
     263        VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsersList", "%s", pszUserList);
    319264    else
    320265        VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsersList", NULL);
    321266    VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/LoggedInUsers", "%u", cUsersInList);
    322     if (   g_cVMInfoLoggedInUsers != cUsersInList
    323         || g_cVMInfoLoggedInUsers == UINT32_MAX)
    324     {
    325         /*
    326          * Update this property ONLY if there is a real change from no users to
    327          * users or vice versa. The only exception is that the initialization
    328          * forces an update, but only once. This ensures consistent property
    329          * settings even if the VM aborted previously.
    330          */
    331         if (cUsersInList == 0)
    332             VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/NoLoggedInUsers", "true");
    333         else if (g_cVMInfoLoggedInUsers == 0)
    334             VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/NoLoggedInUsers", "false");
    335     }
    336     g_cVMInfoLoggedInUsers = cUsersInList;
    337 
     267    if (g_cVMInfoLoggedInUsers != cUsersInList)
     268    {
     269        VBoxServicePropCacheUpdate(&g_VMInfoPropCache, "/VirtualBox/GuestInfo/OS/NoLoggedInUsers", cUsersInList == 0 ? "true" : "false");
     270        g_cVMInfoLoggedInUsers = cUsersInList;
     271    }   
     272    if (pszUserList)
     273        RTStrFree(pszUserList);
    338274    return VINF_SUCCESS;
    339275}
     
    655591    WSADATA wsaData;
    656592    if (WSAStartup(MAKEWORD(2, 2), &wsaData))
    657         VBoxServiceError("VMInfo: WSAStartup failed! Error: %Rrc\n", RTErrConvertFromWin32(WSAGetLastError()));
     593        VBoxServiceError("VMInfo/Users: WSAStartup failed! Error: %Rrc\n", RTErrConvertFromWin32(WSAGetLastError()));
    658594#endif /* RT_OS_WINDOWS */
    659595
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