2 * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
23 Change History (most recent first):
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
32 #include "VPCDetect.h"
33 #include "DebugServices.h"
37 # pragma comment(lib, "wbemuuid.lib")
39 static BOOL g_doneCheck
= FALSE
;
40 static BOOL g_isVPC
= FALSE
;
46 IWbemLocator
* pLoc
= 0;
47 IWbemServices
* pSvc
= 0;
48 IEnumWbemClassObject
* pEnumerator
= NULL
;
52 // Short circuit if we've already done this
54 require_action_quiet( !g_doneCheck
, exit
, g_doneCheck
= TRUE
);
58 hres
= CoInitializeEx(0, COINIT_MULTITHREADED
);
59 require_action( SUCCEEDED( hres
), exit
, g_isVPC
= false );
62 // Initialize Security
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 );
68 // Obtain the initial locator to Windows Management on a particular host computer.
70 hres
= CoCreateInstance( CLSID_WbemLocator
, 0, CLSCTX_INPROC_SERVER
, IID_IWbemLocator
, (LPVOID
*) &pLoc
);
71 require_action( SUCCEEDED( hres
), exit
, g_isVPC
= false );
73 // Connect to the root\cimv2 namespace with the
74 // current user and obtain pointer pSvc
75 // to make IWbemServices calls.
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 );
80 // Set the IWbemServices proxy so that impersonation
81 // of the user (client) occurs.
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 );
86 // Use the IWbemServices pointer to make requests of WMI.
87 // Make requests here:
89 hres
= pSvc
->ExecQuery( bstr_t("WQL"), bstr_t("SELECT * from Win32_BaseBoard"), WBEM_FLAG_FORWARD_ONLY
| WBEM_FLAG_RETURN_IMMEDIATELY
, NULL
, &pEnumerator
);
91 require_action( SUCCEEDED( hres
), exit
, g_isVPC
= false );
95 IWbemClassObject
* pInstance
= NULL
;
98 hres
= pEnumerator
->Next( WBEM_INFINITE
, 1, &pInstance
, &dwCount
);
103 BSTR strClassProp
= SysAllocString(L
"Manufacturer");
106 hr
= pInstance
->Get(strClassProp
, 0, &v
, 0, 0);
107 SysFreeString(strClassProp
);
109 // check the HRESULT to see if the action succeeded.
111 if (SUCCEEDED(hr
) && (V_VT(&v
) == VT_BSTR
))
113 wchar_t * wstring
= wcslwr( V_BSTR( &v
) );
115 if (wcscmp( wstring
, L
"microsoft corporation" ) == 0 )
123 } while (hres
== WBEM_S_NO_ERROR
);
148 dlog( kDebugLevelTrace
, "Virtual PC detected" );