/* -*- 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;
}
