1*48a54d36SAndroid Build Coastguard Worker /* -*- Mode: C; tab-width: 4 -*-
2*48a54d36SAndroid Build Coastguard Worker *
3*48a54d36SAndroid Build Coastguard Worker * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
4*48a54d36SAndroid Build Coastguard Worker *
5*48a54d36SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
6*48a54d36SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
7*48a54d36SAndroid Build Coastguard Worker * You may obtain a copy of the License at
8*48a54d36SAndroid Build Coastguard Worker *
9*48a54d36SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
10*48a54d36SAndroid Build Coastguard Worker *
11*48a54d36SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
12*48a54d36SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
13*48a54d36SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*48a54d36SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
15*48a54d36SAndroid Build Coastguard Worker * limitations under the License.
16*48a54d36SAndroid Build Coastguard Worker */
17*48a54d36SAndroid Build Coastguard Worker
18*48a54d36SAndroid Build Coastguard Worker #define _WIN32_DCOM
19*48a54d36SAndroid Build Coastguard Worker #include "VPCDetect.h"
20*48a54d36SAndroid Build Coastguard Worker #include "DebugServices.h"
21*48a54d36SAndroid Build Coastguard Worker #include <comdef.h>
22*48a54d36SAndroid Build Coastguard Worker #include <Wbemidl.h>
23*48a54d36SAndroid Build Coastguard Worker
24*48a54d36SAndroid Build Coastguard Worker # pragma comment(lib, "wbemuuid.lib")
25*48a54d36SAndroid Build Coastguard Worker
26*48a54d36SAndroid Build Coastguard Worker static BOOL g_doneCheck = FALSE;
27*48a54d36SAndroid Build Coastguard Worker static BOOL g_isVPC = FALSE;
28*48a54d36SAndroid Build Coastguard Worker
29*48a54d36SAndroid Build Coastguard Worker
30*48a54d36SAndroid Build Coastguard Worker mStatus
IsVPCRunning(BOOL * inVirtualPC)31*48a54d36SAndroid Build Coastguard Worker IsVPCRunning( BOOL * inVirtualPC )
32*48a54d36SAndroid Build Coastguard Worker {
33*48a54d36SAndroid Build Coastguard Worker IWbemLocator * pLoc = 0;
34*48a54d36SAndroid Build Coastguard Worker IWbemServices * pSvc = 0;
35*48a54d36SAndroid Build Coastguard Worker IEnumWbemClassObject * pEnumerator = NULL;
36*48a54d36SAndroid Build Coastguard Worker bool coInit = false;
37*48a54d36SAndroid Build Coastguard Worker HRESULT hres;
38*48a54d36SAndroid Build Coastguard Worker SC_HANDLE scm = NULL;
39*48a54d36SAndroid Build Coastguard Worker SC_HANDLE service = NULL;
40*48a54d36SAndroid Build Coastguard Worker SERVICE_STATUS status;
41*48a54d36SAndroid Build Coastguard Worker mStatus err;
42*48a54d36SAndroid Build Coastguard Worker BOOL ok = TRUE;
43*48a54d36SAndroid Build Coastguard Worker
44*48a54d36SAndroid Build Coastguard Worker // Initialize flag
45*48a54d36SAndroid Build Coastguard Worker
46*48a54d36SAndroid Build Coastguard Worker *inVirtualPC = FALSE;
47*48a54d36SAndroid Build Coastguard Worker
48*48a54d36SAndroid Build Coastguard Worker // Find out if WMI is running
49*48a54d36SAndroid Build Coastguard Worker
50*48a54d36SAndroid Build Coastguard Worker scm = OpenSCManager( 0, 0, SC_MANAGER_CONNECT );
51*48a54d36SAndroid Build Coastguard Worker err = translate_errno( scm, (OSStatus) GetLastError(), kOpenErr );
52*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
53*48a54d36SAndroid Build Coastguard Worker
54*48a54d36SAndroid Build Coastguard Worker service = OpenService( scm, TEXT( "winmgmt" ), SERVICE_QUERY_STATUS );
55*48a54d36SAndroid Build Coastguard Worker err = translate_errno( service, (OSStatus) GetLastError(), kNotFoundErr );
56*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
57*48a54d36SAndroid Build Coastguard Worker
58*48a54d36SAndroid Build Coastguard Worker ok = QueryServiceStatus( service, &status );
59*48a54d36SAndroid Build Coastguard Worker err = translate_errno( ok, (OSStatus) GetLastError(), kAuthenticationErr );
60*48a54d36SAndroid Build Coastguard Worker require_noerr( err, exit );
61*48a54d36SAndroid Build Coastguard Worker require_action( status.dwCurrentState == SERVICE_RUNNING, exit, err = kUnknownErr );
62*48a54d36SAndroid Build Coastguard Worker
63*48a54d36SAndroid Build Coastguard Worker // Initialize COM.
64*48a54d36SAndroid Build Coastguard Worker
65*48a54d36SAndroid Build Coastguard Worker hres = CoInitializeEx(0, COINIT_MULTITHREADED);
66*48a54d36SAndroid Build Coastguard Worker require_action( SUCCEEDED( hres ), exit, err = kUnknownErr );
67*48a54d36SAndroid Build Coastguard Worker coInit = true;
68*48a54d36SAndroid Build Coastguard Worker
69*48a54d36SAndroid Build Coastguard Worker // Initialize Security
70*48a54d36SAndroid Build Coastguard Worker
71*48a54d36SAndroid Build Coastguard Worker hres = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL );
72*48a54d36SAndroid Build Coastguard Worker require_action( SUCCEEDED( hres ), exit, err = kUnknownErr );
73*48a54d36SAndroid Build Coastguard Worker
74*48a54d36SAndroid Build Coastguard Worker
75*48a54d36SAndroid Build Coastguard Worker // Obtain the initial locator to Windows Management on a particular host computer.
76*48a54d36SAndroid Build Coastguard Worker
77*48a54d36SAndroid Build Coastguard Worker hres = CoCreateInstance( CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLoc );
78*48a54d36SAndroid Build Coastguard Worker require_action( SUCCEEDED( hres ), exit, err = kUnknownErr );
79*48a54d36SAndroid Build Coastguard Worker
80*48a54d36SAndroid Build Coastguard Worker // Connect to the root\cimv2 namespace with the
81*48a54d36SAndroid Build Coastguard Worker // current user and obtain pointer pSvc
82*48a54d36SAndroid Build Coastguard Worker // to make IWbemServices calls.
83*48a54d36SAndroid Build Coastguard Worker
84*48a54d36SAndroid Build Coastguard Worker hres = pLoc->ConnectServer( _bstr_t(L"ROOT\\CIMV2"), NULL, NULL, 0, WBEM_FLAG_CONNECT_USE_MAX_WAIT, 0, 0, &pSvc );
85*48a54d36SAndroid Build Coastguard Worker require_action( SUCCEEDED( hres ), exit, err = kUnknownErr );
86*48a54d36SAndroid Build Coastguard Worker
87*48a54d36SAndroid Build Coastguard Worker // Set the IWbemServices proxy so that impersonation
88*48a54d36SAndroid Build Coastguard Worker // of the user (client) occurs.
89*48a54d36SAndroid Build Coastguard Worker
90*48a54d36SAndroid Build Coastguard Worker 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 );
91*48a54d36SAndroid Build Coastguard Worker require_action( SUCCEEDED( hres ), exit, err = kUnknownErr );
92*48a54d36SAndroid Build Coastguard Worker
93*48a54d36SAndroid Build Coastguard Worker // Use the IWbemServices pointer to make requests of WMI.
94*48a54d36SAndroid Build Coastguard Worker // Make requests here:
95*48a54d36SAndroid Build Coastguard Worker
96*48a54d36SAndroid Build Coastguard Worker hres = pSvc->ExecQuery( bstr_t("WQL"), bstr_t("SELECT * from Win32_BaseBoard"), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);
97*48a54d36SAndroid Build Coastguard Worker
98*48a54d36SAndroid Build Coastguard Worker require_action( SUCCEEDED( hres ), exit, err = kUnknownErr );
99*48a54d36SAndroid Build Coastguard Worker
100*48a54d36SAndroid Build Coastguard Worker do
101*48a54d36SAndroid Build Coastguard Worker {
102*48a54d36SAndroid Build Coastguard Worker IWbemClassObject* pInstance = NULL;
103*48a54d36SAndroid Build Coastguard Worker ULONG dwCount = NULL;
104*48a54d36SAndroid Build Coastguard Worker
105*48a54d36SAndroid Build Coastguard Worker hres = pEnumerator->Next( WBEM_INFINITE, 1, &pInstance, &dwCount);
106*48a54d36SAndroid Build Coastguard Worker
107*48a54d36SAndroid Build Coastguard Worker if ( pInstance )
108*48a54d36SAndroid Build Coastguard Worker {
109*48a54d36SAndroid Build Coastguard Worker VARIANT v;
110*48a54d36SAndroid Build Coastguard Worker BSTR strClassProp = SysAllocString(L"Manufacturer");
111*48a54d36SAndroid Build Coastguard Worker HRESULT hr;
112*48a54d36SAndroid Build Coastguard Worker
113*48a54d36SAndroid Build Coastguard Worker hr = pInstance->Get(strClassProp, 0, &v, 0, 0);
114*48a54d36SAndroid Build Coastguard Worker SysFreeString(strClassProp);
115*48a54d36SAndroid Build Coastguard Worker
116*48a54d36SAndroid Build Coastguard Worker // check the HRESULT to see if the action succeeded.
117*48a54d36SAndroid Build Coastguard Worker
118*48a54d36SAndroid Build Coastguard Worker if (SUCCEEDED(hr) && (V_VT(&v) == VT_BSTR))
119*48a54d36SAndroid Build Coastguard Worker {
120*48a54d36SAndroid Build Coastguard Worker wchar_t * wstring = wcslwr( V_BSTR( &v ) );
121*48a54d36SAndroid Build Coastguard Worker
122*48a54d36SAndroid Build Coastguard Worker if (wcscmp( wstring, L"microsoft corporation" ) == 0 )
123*48a54d36SAndroid Build Coastguard Worker {
124*48a54d36SAndroid Build Coastguard Worker *inVirtualPC = TRUE;
125*48a54d36SAndroid Build Coastguard Worker }
126*48a54d36SAndroid Build Coastguard Worker }
127*48a54d36SAndroid Build Coastguard Worker
128*48a54d36SAndroid Build Coastguard Worker VariantClear(&v);
129*48a54d36SAndroid Build Coastguard Worker }
130*48a54d36SAndroid Build Coastguard Worker } while (hres == WBEM_S_NO_ERROR);
131*48a54d36SAndroid Build Coastguard Worker
132*48a54d36SAndroid Build Coastguard Worker exit:
133*48a54d36SAndroid Build Coastguard Worker
134*48a54d36SAndroid Build Coastguard Worker if ( pSvc != NULL )
135*48a54d36SAndroid Build Coastguard Worker {
136*48a54d36SAndroid Build Coastguard Worker pSvc->Release();
137*48a54d36SAndroid Build Coastguard Worker }
138*48a54d36SAndroid Build Coastguard Worker
139*48a54d36SAndroid Build Coastguard Worker if ( pLoc != NULL )
140*48a54d36SAndroid Build Coastguard Worker {
141*48a54d36SAndroid Build Coastguard Worker pLoc->Release();
142*48a54d36SAndroid Build Coastguard Worker }
143*48a54d36SAndroid Build Coastguard Worker
144*48a54d36SAndroid Build Coastguard Worker if ( coInit )
145*48a54d36SAndroid Build Coastguard Worker {
146*48a54d36SAndroid Build Coastguard Worker CoUninitialize();
147*48a54d36SAndroid Build Coastguard Worker }
148*48a54d36SAndroid Build Coastguard Worker
149*48a54d36SAndroid Build Coastguard Worker if ( service )
150*48a54d36SAndroid Build Coastguard Worker {
151*48a54d36SAndroid Build Coastguard Worker CloseServiceHandle( service );
152*48a54d36SAndroid Build Coastguard Worker }
153*48a54d36SAndroid Build Coastguard Worker
154*48a54d36SAndroid Build Coastguard Worker if ( scm )
155*48a54d36SAndroid Build Coastguard Worker {
156*48a54d36SAndroid Build Coastguard Worker CloseServiceHandle( scm );
157*48a54d36SAndroid Build Coastguard Worker }
158*48a54d36SAndroid Build Coastguard Worker
159*48a54d36SAndroid Build Coastguard Worker if ( *inVirtualPC )
160*48a54d36SAndroid Build Coastguard Worker {
161*48a54d36SAndroid Build Coastguard Worker dlog( kDebugLevelTrace, "Virtual PC detected" );
162*48a54d36SAndroid Build Coastguard Worker }
163*48a54d36SAndroid Build Coastguard Worker
164*48a54d36SAndroid Build Coastguard Worker return err;
165*48a54d36SAndroid Build Coastguard Worker }
166