/* -*- Mode: C; tab-width: 4 -*-
*
* Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#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;
mStatus
IsVPCRunning( BOOL * inVirtualPC )
{
IWbemLocator * pLoc = 0;
IWbemServices * pSvc = 0;
IEnumWbemClassObject * pEnumerator = NULL;
bool coInit = false;
HRESULT hres;
SC_HANDLE scm = NULL;
SC_HANDLE service = NULL;
SERVICE_STATUS status;
mStatus err;
BOOL ok = TRUE;
// Initialize flag
*inVirtualPC = FALSE;
// Find out if WMI is running
scm = OpenSCManager( 0, 0, SC_MANAGER_CONNECT );
err = translate_errno( scm, (OSStatus) GetLastError(), kOpenErr );
require_noerr( err, exit );
service = OpenService( scm, TEXT( "winmgmt" ), SERVICE_QUERY_STATUS );
err = translate_errno( service, (OSStatus) GetLastError(), kNotFoundErr );
require_noerr( err, exit );
ok = QueryServiceStatus( service, &status );
err = translate_errno( ok, (OSStatus) GetLastError(), kAuthenticationErr );
require_noerr( err, exit );
require_action( status.dwCurrentState == SERVICE_RUNNING, exit, err = kUnknownErr );
// Initialize COM.
hres = CoInitializeEx(0, COINIT_MULTITHREADED);
require_action( SUCCEEDED( hres ), exit, err = kUnknownErr );
coInit = true;
// Initialize Security
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, err = kUnknownErr );
// Obtain the initial locator to Windows Management on a particular host computer.
hres = CoCreateInstance( CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLoc );
require_action( SUCCEEDED( hres ), exit, err = kUnknownErr );
// Connect to the root\cimv2 namespace with the
// current user and obtain pointer pSvc
// to make IWbemServices calls.
hres = pLoc->ConnectServer( _bstr_t(L"ROOT\\CIMV2"), NULL, NULL, 0, WBEM_FLAG_CONNECT_USE_MAX_WAIT, 0, 0, &pSvc );
require_action( SUCCEEDED( hres ), exit, err = kUnknownErr );
// Set the IWbemServices proxy so that impersonation
// of the user (client) occurs.
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, err = kUnknownErr );
// Use the IWbemServices pointer to make requests of WMI.
// Make requests here:
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, err = kUnknownErr );
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);
// check the HRESULT to see if the action succeeded.
if (SUCCEEDED(hr) && (V_VT(&v) == VT_BSTR))
{
wchar_t * wstring = wcslwr( V_BSTR( &v ) );
if (wcscmp( wstring, L"microsoft corporation" ) == 0 )
{
*inVirtualPC = TRUE;
}
}
VariantClear(&v);
}
} while (hres == WBEM_S_NO_ERROR);
exit:
if ( pSvc != NULL )
{
pSvc->Release();
}
if ( pLoc != NULL )
{
pLoc->Release();
}
if ( coInit )
{
CoUninitialize();
}
if ( service )
{
CloseServiceHandle( service );
}
if ( scm )
{
CloseServiceHandle( scm );
}
if ( *inVirtualPC )
{
dlog( kDebugLevelTrace, "Virtual PC detected" );
}
return err;
}