VBoxVMInfoUser.cpp revision d65680efa46fa49e8bf14e67b29b782510ff934c
/* $Id$ */
/** @file
* VBoxVMInfoUser - User information for the host.
*/
/*
* Copyright (C) 2006-2007 Sun Microsystems, Inc.
*
* Sun Microsystems, Inc. confidential
* All rights reserved
*/
#include "VBoxService.h"
#include "VBoxVMInfo.h"
#include "VBoxVMInfoUser.h"
#include <Ntsecapi.h>
#include <wtsapi32.h> /* For WTS* calls. */
#include <psapi.h> /* EnumProcesses. */
/* Function GetLUIDsFromProcesses() written by Stefan Kuhr. */
{
if (!ppLuid)
{
return 0L;
}
// Call the PSAPI function EnumProcesses to get all of the
// ProcID's currently in the system.
// NOTE: In the documentation, the third parameter of
// EnumProcesses is named cbNeeded, which implies that you
// can call the function once to find out how much space to
// allocate for a buffer and again to fill the buffer.
// This is not the case. The cbNeeded parameter returns
// the number of PIDs returned, so if your buffer size is
// zero cbNeeded returns zero.
// NOTE: The "HeapAlloc" loop here ensures that we
// actually allocate a buffer large enough for all the
// PIDs in the system.
do
{
if( lpdwPIDs )
{
dwSize2 *= 2 ;
}
return 0L; // Last error will be that of HeapAlloc
{
return 0L;
}
}
/* At this point we have an array of the PIDs at the
time of the last EnumProcesses invocation. We will
allocate an array of LUIDs passed back via the out
param ppLuid of exactly the number of PIDs. We will
only fill the first n values of this array, with n
being the number of unique LUIDs found in these PIDs. */
// How many ProcIDs did we get?
dwSize2 = 0L; /* Our return value of found luids. */
if (!(*ppLuid))
{
dwLastError = GetLastError();
goto CLEANUP;
}
{
// Open the process (if we can... security does not
// permit every process in the system).
{
{
{
if (!bFound)
}
}
CloseHandle( hProcess ) ;
}
/// we don't really care if OpenProcess or OpenProcessToken fail or succeed, because
/// there are quite a number of system processes we cannot open anyway, not even as SYSTEM.
}
if (lpdwPIDs)
if (ERROR_SUCCESS !=dwLastError)
return dwSize2;
}
{
int usLength = 0;
if (!a_pSession)
return FALSE;
if (ret != STATUS_SUCCESS)
{
if (sessionData)
return FALSE;
}
if (!sessionData)
{
Log(("vboxVMInfoThread: Invalid logon session data.\n"));
return FALSE;
}
{
/* Get the user name. */
if (usLength > 256)
{
}
else
{
/** @todo r=bird: Check this code for buffer overruns. the if check above is wrong as it's making assumptions about _MAX_PATH (which is 260 not 256 as stated). */
/* Only handle users which can login interactively. */
{
if (LookupAccountSid(NULL,
&ownerType))
{
Log(("vboxVMInfoThread: Account User=%ls, Session=%ld, LUID=%ld,%ld, AuthPkg=%ls, Domain=%ls\n",
a_pUserInfo->szUser, sessionData->Session, sessionData->LogonId.HighPart, sessionData->LogonId.LowPart, szAuthPkg, szLogonDomain));
/* The session ID increments/decrements on Vista often! So don't compare
the session data SID with the current SID here. */
DWORD dwActiveSession = 0;
/*Log(("vboxVMInfoThread: Current active session ID: %ld\n", dwActiveSession));*/
if (SidTypeUser == ownerType)
{
DWORD dwBytesRet = 0;
int iState = 0;
if (WTSQuerySessionInformation( /* Detect RDP sessions as well. */
&pBuffer,
&dwBytesRet))
{
/*Log(("vboxVMInfoThread: WTSQuerySessionInformation returned %ld bytes, p=%p, state=%d\n", dwBytesRet, pBuffer, pBuffer != NULL ? (INT)*pBuffer : -1));*/
if(dwBytesRet)
{
/** @todo On Vista and W2K, always "old" user name are still there. Filter out the old! */
Log(("vboxVMInfoThread: Account User=%ls is logged in via TCS/RDP. State=%d\n", a_pUserInfo->szUser, iState));
bFoundUser = TRUE;
}
}
else
{
/* Terminal services don't run (for example in W2K, nothing to worry about ...). */
/* ... or is on Vista fast user switching page! */
bFoundUser = TRUE;
}
if (pBuffer)
{
{
break;
}
}
}
}
}
}
}
return bLoggedIn;
}
{
int iUserCount = 0;
char szUserList[4096] = {0};
/* This function can report stale or orphaned interactive logon sessions of already logged
off users (especially in Windows 2000). */
if (ret != STATUS_SUCCESS)
{
return 1;
}
for (int i = 0; i<(int)ulCount; i++)
{
{
if (iUserCount > 0)
iUserCount++;
}
}
/* Write information to host. */
vboxVMInfoWriteProp(a_pCtx, "GuestInfo/OS/LoggedInUsersList", (iUserCount > 0) ? szUserList : NULL);
return ret;
}