VBoxServiceVMInfo-win.cpp revision ad71dcafc4a031487d2715c5470bc95801249005
/* $Id$ */
/** @file
* VBoxVMInfo-win - Virtual machine (guest) information for the host.
*/
/*
* Copyright (C) 2009 Sun Microsystems, Inc.
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
* Clara, CA 95054 USA or visit http://www.sun.com if you need
* additional information or have any questions.
*/
/*******************************************************************************
* Header Files *
*******************************************************************************/
#include <windows.h>
#include <wtsapi32.h> /* For WTS* calls. */
#include <psapi.h> /* EnumProcesses. */
#include <iprt/semaphore.h>
#include <VBox/VBoxGuestLib.h>
#include "VBoxServiceInternal.h"
#include "VBoxServiceUtils.h"
/*******************************************************************************
* Global Variables *
*******************************************************************************/
#ifndef TARGET_NT4
/** Function prototypes for dynamic loading. */
/** The vminfo interval (millseconds). */
#endif
#ifndef TARGET_NT4
{
if (h == NULL)
return RTErrConvertFromWin32(GetLastError());
int rc;
{
}
else
{
void *pvTokenInfo = NULL;
switch (tkClass)
{
case TokenStatistics:
dwTokenInfoSize = sizeof(TOKEN_STATISTICS);
break;
/** @todo Implement more token classes here. */
default:
break;
}
if (pvTokenInfo)
{
{
}
else
{
switch (tkClass)
{
case TokenStatistics:
{
/* @todo Add more information of TOKEN_STATISTICS as needed. */
break;
}
default:
/* Should never get here! */
break;
}
rc = VINF_SUCCESS;
}
}
}
CloseHandle(h);
return rc;
}
{
if (pdwProcIDs == NULL)
return VERR_NO_MEMORY;
int rc;
do
{
{
break;
}
/* Was our array big enough? Or do we need more space? */
{
/* Apparently not, so try next bigger size */
dwNumProcs += 128;
if (pdwProcIDs == NULL)
{
rc = VERR_NO_MEMORY;
break;
}
}
else
{
rc = VINF_SUCCESS;
break;
}
if (RT_SUCCESS(rc))
{
/* Allocate our process structure */
rc = VERR_NO_MEMORY;
if (RT_SUCCESS(rc))
{
/* We now have the PIDs, fill them into the struct and lookup their LUID's */
for (DWORD i=0; i<dwNumProcs; i++)
{
if (RT_FAILURE(rc))
{
be this an error here. */
rc = VINF_SUCCESS;
}
pCur++;
pCurProcID++;
}
/* Save number of processes */
*pdwCount = dwNumProcs;
}
}
if (RT_FAILURE(rc))
return rc;
}
{
{
}
}
{
if (dwProcCount <= 0) /* To be on the safe side. */
return 0;
{
VBoxServiceError("Could not get logon session data! rc=%Rrc", RTErrConvertFromWin32(GetLastError()));
return 0;
}
* So check if we have some processes bound to it by comparing the session <-> process LUIDs. */
for (DWORD i=0; i<dwProcCount; i++)
{
/*VBoxServiceVerbose(3, "%ld:%ld <-> %ld:%ld\n",
pCur->luid.HighPart, pCur->luid.LowPart,
pSessionData->LogonId.HighPart, pSessionData->LogonId.LowPart);*/
{
return 1;
}
pCur++;
}
return 0;
}
{
NTSTATUS r = 0;
int iLength = 0;
if (!a_pSession)
return FALSE;
if (r != STATUS_SUCCESS)
{
if (sessionData)
return FALSE;
}
if (!sessionData)
{
VBoxServiceError("Invalid logon session data.\n");
return FALSE;
}
(sessionData->Sid != NULL) ? "1" : "0", sessionData->LogonId.HighPart, sessionData->LogonId.LowPart);
{
/* Get the user name. */
if (iLength > sizeof(a_pUserInfo->szUser) - sizeof(WCHAR)) /* -sizeof(WCHAR) because we have to add the terminating null char at the end later. */
{
VBoxServiceVerbose(0, "User name too long (%d bytes) for buffer! Name will be truncated.\n", iLength);
}
/* Get authentication package. */
if (iLength > sizeof(a_pUserInfo->szAuthenticationPackage) - sizeof(WCHAR)) /* -sizeof(WCHAR) because we have to add the terminating null char at the end later. */
{
VBoxServiceVerbose(0, "Authentication pkg name too long (%d bytes) for buffer! Name will be truncated.\n", iLength);
}
if (iLength)
/* Get logon domain. */
if (iLength > sizeof(a_pUserInfo->szLogonDomain) - sizeof(WCHAR)) /* -sizeof(WCHAR) because we have to add the terminating null char at the end later. */
{
VBoxServiceVerbose(0, "Logon domain name too long (%d bytes) for buffer! Name will be truncated.\n", iLength);
}
if (iLength)
/* Only handle users which can login interactively or logged in remotely over native RDP. */
{
if (LookupAccountSid(NULL,
&ownerType))
{
a_pUserInfo->szUser, sessionData->Session, sessionData->LogonId.HighPart, sessionData->LogonId.LowPart, a_pUserInfo->szAuthenticationPackage, a_pUserInfo->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;
/*VBoxServiceVerbose(3, ("Users: 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))
{
/*VBoxServiceVerbose(3, ("Users: 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 one! */
VBoxServiceVerbose(3, "Users: 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)
}
}
}
}
return bFoundUser;
}
#endif /* TARGET_NT4 */
{
int rc;
char szPropPath[_MAX_PATH] = {0};
#ifdef RT_ARCH_AMD64
#endif
/* The file information table. */
#ifndef TARGET_NT4
{
{ szSysDir, "VBoxControl.exe", },
{ szSysDir, "VBoxHook.dll", },
{ szSysDir, "VBoxDisp.dll", },
{ szSysDir, "VBoxMRXNP.dll", },
{ szSysDir, "VBoxService.exe", },
{ szSysDir, "VBoxTray.exe", },
{ szSysDir, "VBoxGINA.dll", },
{ szSysDir, "VBoxCredProv.dll", },
/* On 64-bit we don't yet have the OpenGL DLLs in native format.
So just enumerate the 32-bit files in the SYSWOW directory. */
#ifdef RT_ARCH_AMD64
{ szSysWowDir, "VBoxOGLarrayspu.dll", },
{ szSysWowDir, "VBoxOGLcrutil.dll", },
{ szSysWowDir, "VBoxOGLerrorspu.dll", },
{ szSysWowDir, "VBoxOGLpackspu.dll", },
{ szSysWowDir, "VBoxOGLpassthroughspu.dll", },
{ szSysWowDir, "VBoxOGLfeedbackspu.dll", },
{ szSysWowDir, "VBoxOGL.dll", },
#else
{ szSysDir, "VBoxOGLarrayspu.dll", },
{ szSysDir, "VBoxOGLcrutil.dll", },
{ szSysDir, "VBoxOGLerrorspu.dll", },
{ szSysDir, "VBoxOGLpackspu.dll", },
{ szSysDir, "VBoxOGLpassthroughspu.dll", },
{ szSysDir, "VBoxOGLfeedbackspu.dll", },
{ szSysDir, "VBoxOGL.dll", },
#endif
{ szDriversDir, "VBoxGuest.sys", },
{ szDriversDir, "VBoxMouse.sys", },
{ szDriversDir, "VBoxSF.sys", },
{ szDriversDir, "VBoxVideo.sys", },
{
}
};
#else /* File lookup for NT4. */
{
{ szSysDir, "VBoxControl.exe", },
{ szSysDir, "VBoxHook.dll", },
{ szSysDir, "VBoxDisp.dll", },
{ szSysDir, "VBoxService.exe", },
{ szSysDir, "VBoxTray.exe", },
{ szDriversDir, "VBoxGuestNT.sys", },
{ szDriversDir, "VBoxMouseNT.sys", },
{ szDriversDir, "VBoxVideo.sys", },
{
}
};
#endif
while (pTable->pszFileName)
{
rc = VBoxServiceGetFileVersionString(pTable->pszFilePath, pTable->pszFileName, szVer, sizeof(szVer));
RTStrPrintf(szPropPath, sizeof(szPropPath), "/VirtualBox/GuestAdd/Components/%s", pTable->pszFileName);
pTable++;
}
return VINF_SUCCESS;
}