#define _WIN32_DCOM
#include "VPCDetect.h"
#include "DebugServices.h"
#include <comdef.h>
#include <Wbemidl.h>
# pragma comment(lib, "wbemuuid.lib")
static BOOL g_doneCheck = FALSE;
static BOOL g_isVPC = FALSE;
BOOL
IsVPCRunning()
{
IWbemLocator * pLoc = 0;
IWbemServices * pSvc = 0;
IEnumWbemClassObject * pEnumerator = NULL;
bool coInit = false;
HRESULT hres;
require_action_quiet( !g_doneCheck, exit, g_doneCheck = TRUE );
hres = CoInitializeEx(0, COINIT_MULTITHREADED);
require_action( SUCCEEDED( hres ), exit, g_isVPC = false );
coInit = true;
hres = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL );
require_action( SUCCEEDED( hres ), exit, g_isVPC = false );
hres = CoCreateInstance( CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLoc );
require_action( SUCCEEDED( hres ), exit, g_isVPC = false );
hres = pLoc->ConnectServer( _bstr_t(L"ROOT\\CIMV2"), NULL, NULL, 0, NULL, 0, 0, &pSvc );
require_action( SUCCEEDED( hres ), exit, g_isVPC = false );
hres = CoSetProxyBlanket( pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE );
require_action( SUCCEEDED( hres ), exit, g_isVPC = false );
hres = pSvc->ExecQuery( bstr_t("WQL"), bstr_t("SELECT * from Win32_BaseBoard"), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);
require_action( SUCCEEDED( hres ), exit, g_isVPC = false );
do
{
IWbemClassObject* pInstance = NULL;
ULONG dwCount = NULL;
hres = pEnumerator->Next( WBEM_INFINITE, 1, &pInstance, &dwCount);
if ( pInstance )
{
VARIANT v;
BSTR strClassProp = SysAllocString(L"Manufacturer");
HRESULT hr;
hr = pInstance->Get(strClassProp, 0, &v, 0, 0);
SysFreeString(strClassProp);
if (SUCCEEDED(hr) && (V_VT(&v) == VT_BSTR))
{
wchar_t * wstring = wcslwr( V_BSTR( &v ) );
if (wcscmp( wstring, L"microsoft corporation" ) == 0 )
{
g_isVPC = true;
}
}
VariantClear(&v);
}
} while (hres == WBEM_S_NO_ERROR);
exit:
if ( pSvc != NULL )
{
pSvc->Release();
}
if ( pLoc != NULL )
{
pLoc->Release();
}
if ( coInit )
{
CoUninitialize();
}
if ( !g_doneCheck )
{
g_doneCheck = TRUE;
if ( g_isVPC )
{
dlog( kDebugLevelTrace, "Virtual PC detected" );
}
}
return g_isVPC;
}