]> git.saurik.com Git - apple/mdnsresponder.git/blob - mDNSWindows/VPCDetect.cpp
mDNSResponder-108.4.tar.gz
[apple/mdnsresponder.git] / mDNSWindows / VPCDetect.cpp
1 /*
2 * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22
23 Change History (most recent first):
24
25 $Log: VPCDetect.cpp,v $
26 Revision 1.1 2005/11/27 20:21:16 herscher
27 <rdar://problem/4210580> Workaround Virtual PC bug that incorrectly modifies incoming mDNS packets
28
29 */
30
31 #define _WIN32_DCOM
32 #include "VPCDetect.h"
33 #include "DebugServices.h"
34 #include <comdef.h>
35 #include <Wbemidl.h>
36
37 # pragma comment(lib, "wbemuuid.lib")
38
39 static BOOL g_doneCheck = FALSE;
40 static BOOL g_isVPC = FALSE;
41
42
43 BOOL
44 IsVPCRunning()
45 {
46 IWbemLocator * pLoc = 0;
47 IWbemServices * pSvc = 0;
48 IEnumWbemClassObject * pEnumerator = NULL;
49 bool coInit = false;
50 HRESULT hres;
51
52 // Short circuit if we've already done this
53
54 require_action_quiet( !g_doneCheck, exit, g_doneCheck = TRUE );
55
56 // Initialize COM.
57
58 hres = CoInitializeEx(0, COINIT_MULTITHREADED);
59 require_action( SUCCEEDED( hres ), exit, g_isVPC = false );
60 coInit = true;
61
62 // Initialize Security
63
64 hres = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL );
65 require_action( SUCCEEDED( hres ), exit, g_isVPC = false );
66
67
68 // Obtain the initial locator to Windows Management on a particular host computer.
69
70 hres = CoCreateInstance( CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLoc );
71 require_action( SUCCEEDED( hres ), exit, g_isVPC = false );
72
73 // Connect to the root\cimv2 namespace with the
74 // current user and obtain pointer pSvc
75 // to make IWbemServices calls.
76
77 hres = pLoc->ConnectServer( _bstr_t(L"ROOT\\CIMV2"), NULL, NULL, 0, NULL, 0, 0, &pSvc );
78 require_action( SUCCEEDED( hres ), exit, g_isVPC = false );
79
80 // Set the IWbemServices proxy so that impersonation
81 // of the user (client) occurs.
82
83 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 );
84 require_action( SUCCEEDED( hres ), exit, g_isVPC = false );
85
86 // Use the IWbemServices pointer to make requests of WMI.
87 // Make requests here:
88
89 hres = pSvc->ExecQuery( bstr_t("WQL"), bstr_t("SELECT * from Win32_BaseBoard"), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);
90
91 require_action( SUCCEEDED( hres ), exit, g_isVPC = false );
92
93 do
94 {
95 IWbemClassObject* pInstance = NULL;
96 ULONG dwCount = NULL;
97
98 hres = pEnumerator->Next( WBEM_INFINITE, 1, &pInstance, &dwCount);
99
100 if ( pInstance )
101 {
102 VARIANT v;
103 BSTR strClassProp = SysAllocString(L"Manufacturer");
104 HRESULT hr;
105
106 hr = pInstance->Get(strClassProp, 0, &v, 0, 0);
107 SysFreeString(strClassProp);
108
109 // check the HRESULT to see if the action succeeded.
110
111 if (SUCCEEDED(hr) && (V_VT(&v) == VT_BSTR))
112 {
113 wchar_t * wstring = wcslwr( V_BSTR( &v ) );
114
115 if (wcscmp( wstring, L"microsoft corporation" ) == 0 )
116 {
117 g_isVPC = true;
118 }
119 }
120
121 VariantClear(&v);
122 }
123 } while (hres == WBEM_S_NO_ERROR);
124
125 exit:
126
127 if ( pSvc != NULL )
128 {
129 pSvc->Release();
130 }
131
132 if ( pLoc != NULL )
133 {
134 pLoc->Release();
135 }
136
137 if ( coInit )
138 {
139 CoUninitialize();
140 }
141
142 if ( !g_doneCheck )
143 {
144 g_doneCheck = TRUE;
145
146 if ( g_isVPC )
147 {
148 dlog( kDebugLevelTrace, "Virtual PC detected" );
149 }
150 }
151
152 return g_isVPC;
153 }