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