xref: /aosp_15_r20/external/mdnsresponder/mDNSWindows/VPCDetect.cpp (revision 48a54d368dc4fa860885eef7b70b6c53499e7c25)
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