Changeset 27618 in vbox for trunk/src/VBox/Runtime/r3
- Timestamp:
- Mar 23, 2010 4:39:41 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/win/RTSystemQueryDmiString-win.cpp
r27129 r27618 33 33 * Header Files * 34 34 *******************************************************************************/ 35 #define _WIN32_DCOM 36 #include <Windows.h> 37 #include <WbemCli.h> 38 35 39 #include <iprt/system.h> 36 40 #include "internal/iprt.h" … … 40 44 #include <iprt/string.h> 41 45 42 #define _WIN32_DCOM 43 #include <comdef.h> 44 #include <Wbemidl.h> 45 46 47 HRESULT rtSystemInitializeDmiLookup() 48 { 49 HRESULT hr = CoInitializeEx(0, COINIT_MULTITHREADED); 50 if (SUCCEEDED(hr)) 51 { 52 hr = CoInitializeSecurity(NULL, 53 -1, /* COM authentication. */ 54 NULL, /* Which authentication services. */ 55 NULL, /* Reserved. */ 56 RPC_C_AUTHN_LEVEL_DEFAULT, /* Default authentication. */ 57 RPC_C_IMP_LEVEL_IMPERSONATE, /* Default impersonation. */ 58 NULL, /* Authentication info. */ 59 EOAC_NONE, /* Additional capabilities. */ 60 NULL); /* Reserved. */ 61 } 62 return hr; 63 } 64 65 66 void rtSystemShutdownDmiLookup() 46 47 /** 48 * Initialize COM. 49 * 50 * @returns COM status code. 51 */ 52 static HRESULT rtSystemDmiWinInitialize(void) 53 { 54 HRESULT hrc = CoInitializeEx(0, COINIT_MULTITHREADED); 55 if (SUCCEEDED(hrc)) 56 { 57 hrc = CoInitializeSecurity(NULL, 58 -1, /* COM authentication. */ 59 NULL, /* Which authentication services. */ 60 NULL, /* Reserved. */ 61 RPC_C_AUTHN_LEVEL_DEFAULT, /* Default authentication. */ 62 RPC_C_IMP_LEVEL_IMPERSONATE, /* Default impersonation. */ 63 NULL, /* Authentication info. */ 64 EOAC_NONE, /* Additional capabilities. */ 65 NULL); /* Reserved. */ 66 } 67 return hrc; 68 } 69 70 71 /** 72 * Undo what rtSystemDmiWinInitialize did. 73 */ 74 static void rtSystemDmiWinTerminate(void) 67 75 { 68 76 CoUninitialize(); … … 70 78 71 79 72 HRESULT rtSystemConnectToDmiServer(IWbemLocator *pLocator, const char *pszServer, IWbemServices **ppServices) 80 /** 81 * Convert a UTF-8 string to a BSTR. 82 * 83 * @returns BSTR pointer. 84 * @param psz The UTF-8 string. 85 */ 86 static BSTR rtSystemWinBstrFromUtf8(const char *psz) 87 { 88 PRTUTF16 pwsz = NULL; 89 int rc = RTStrToUtf16(psz, &pwsz); 90 if (RT_FAILURE(rc)) 91 return NULL; 92 BSTR pBStr = SysAllocString((const OLECHAR *)pwsz); 93 RTUtf16Free(pwsz); 94 return pBStr; 95 } 96 97 98 /** 99 * Connect to the DMI server. 100 * 101 * @returns COM status code. 102 * @param pLocator The locator. 103 * @param pszServer The server name. 104 * @param ppServices Where to return the services interface. 105 */ 106 static HRESULT rtSystemDmiWinConnectToServer(IWbemLocator *pLocator, const char *pszServer, IWbemServices **ppServices) 73 107 { 74 108 AssertPtr(pLocator); … … 76 110 AssertPtr(ppServices); 77 111 78 HRESULT hr = pLocator->ConnectServer(_bstr_t(TEXT(pszServer)), 79 NULL, 80 NULL, 81 0, 82 NULL, 83 0, 84 0, 85 ppServices); 86 if (SUCCEEDED(hr)) 87 { 88 hr = CoSetProxyBlanket(*ppServices, 89 RPC_C_AUTHN_WINNT, 90 RPC_C_AUTHZ_NONE, 91 NULL, 92 RPC_C_AUTHN_LEVEL_CALL, 93 RPC_C_IMP_LEVEL_IMPERSONATE, 94 NULL, 95 EOAC_NONE); 96 } 97 return hr; 112 BSTR pBStrServer = rtSystemWinBstrFromUtf8(pszServer); 113 if (!pBStrServer) 114 return E_OUTOFMEMORY; 115 116 HRESULT hrc = pLocator->ConnectServer(pBStrServer, 117 NULL, 118 NULL, 119 0, 120 NULL, 121 0, 122 0, 123 ppServices); 124 if (SUCCEEDED(hrc)) 125 { 126 hrc = CoSetProxyBlanket(*ppServices, 127 RPC_C_AUTHN_WINNT, 128 RPC_C_AUTHZ_NONE, 129 NULL, 130 RPC_C_AUTHN_LEVEL_CALL, 131 RPC_C_IMP_LEVEL_IMPERSONATE, 132 NULL, 133 EOAC_NONE); 134 if (FAILED(hrc)) 135 (*ppServices)->Release(); 136 } 137 SysFreeString(pBStrServer); 138 return hrc; 98 139 } 99 140 … … 106 147 AssertReturn(enmString > RTSYSDMISTR_INVALID && enmString < RTSYSDMISTR_END, VERR_INVALID_PARAMETER); 107 148 108 HRESULT hr = rtSystemInitializeDmiLookup(); 109 if (FAILED(hr)) 149 /* 150 * Figure the property name before we start. 151 */ 152 const char *pszPropName; 153 switch (enmString) 154 { 155 case RTSYSDMISTR_PRODUCT_NAME: pszPropName = "Name"; break; 156 case RTSYSDMISTR_PRODUCT_VERSION: pszPropName = "Version"; break; 157 case RTSYSDMISTR_PRODUCT_UUID: pszPropName = "UUID"; break; 158 case RTSYSDMISTR_PRODUCT_SERIAL: pszPropName = "IdentifyingNumber"; break; 159 default: 160 return VERR_NOT_SUPPORTED; 161 } 162 163 /* 164 * Before we do anything with COM, we have to initalize it. 165 */ 166 HRESULT hrc = rtSystemDmiWinInitialize(); 167 if (FAILED(hrc)) 110 168 return VERR_NOT_SUPPORTED; 111 169 112 IWbemLocator *pLoc; 113 hr = CoCreateInstance(CLSID_WbemLocator, 114 0, 115 CLSCTX_INPROC_SERVER, 116 IID_IWbemLocator, (LPVOID *)&pLoc); 117 int rc = VINF_SUCCESS; 118 if (SUCCEEDED(hr)) 119 { 120 IWbemServices *pServices; 121 hr = rtSystemConnectToDmiServer(pLoc, "ROOT\\CIMV2", &pServices); 122 if (SUCCEEDED(hr)) 170 int rc = VERR_NOT_SUPPORTED; 171 BSTR pBstrPropName = rtSystemWinBstrFromUtf8(pszPropName); 172 if (pBstrPropName) 173 { 174 /* 175 * Instantiate the IWbemLocator, whatever that is and connect to the 176 * DMI serve. 177 */ 178 IWbemLocator *pLoc; 179 hrc = CoCreateInstance(CLSID_WbemLocator, 180 0, 181 CLSCTX_INPROC_SERVER, 182 IID_IWbemLocator, 183 (LPVOID *)&pLoc); 184 if (SUCCEEDED(hrc)) 123 185 { 124 I EnumWbemClassObject *pEnum;125 hr = pServices->CreateInstanceEnum(L"Win32_ComputerSystemProduct", 0, NULL, &pEnum);126 if (SUCCEEDED(hr ))186 IWbemServices *pServices; 187 hrc = rtSystemDmiWinConnectToServer(pLoc, "ROOT\\CIMV2", &pServices); 188 if (SUCCEEDED(hrc)) 127 189 { 128 IWbemClassObject *pObj; 129 ULONG uCount; 130 131 do 190 /* 191 * Enumerate whatever it is we're looking at and try get 192 * the desired property. 193 */ 194 BSTR pBstrFilter = rtSystemWinBstrFromUtf8("Win32_ComputerSystemProduct"); 195 if (pBstrFilter) 132 196 { 133 hr = pEnum->Next(WBEM_INFINITE, 134 1, 135 &pObj, 136 &uCount); 137 if ( SUCCEEDED(hr) 138 && uCount > 0) 197 IEnumWbemClassObject *pEnum; 198 hrc = pServices->CreateInstanceEnum(pBstrFilter, 0, NULL, &pEnum); 199 if (SUCCEEDED(hrc)) 139 200 { 140 const char *pszPropName; 141 switch (enmString) 201 do 142 202 { 143 case RTSYSDMISTR_PRODUCT_NAME: pszPropName = "Name"; break; 144 case RTSYSDMISTR_PRODUCT_VERSION: pszPropName = "Version"; break; 145 case RTSYSDMISTR_PRODUCT_UUID: pszPropName = "UUID"; break; 146 case RTSYSDMISTR_PRODUCT_SERIAL: pszPropName = "IdentifyingNumber"; break; 147 default: 148 rc = VERR_NOT_SUPPORTED; 149 } 150 151 if (RT_SUCCESS(rc)) 152 { 153 _variant_t v; 154 hr = pObj->Get(_bstr_t(TEXT(pszPropName)), 0, &v, 0, 0); 155 if ( SUCCEEDED(hr) 156 && V_VT(&v) == VT_BSTR) 203 IWbemClassObject *pObj; 204 ULONG cObjRet; 205 hrc = pEnum->Next(WBEM_INFINITE, 1, &pObj, &cObjRet); 206 if ( SUCCEEDED(hrc) 207 && cObjRet >= 1) 157 208 { 158 RTStrPrintf(pszBuf, cbBuf, "%s", (char*)_bstr_t(v.bstrVal)); 159 VariantClear(&v); 209 VARIANT Var; 210 VariantInit(&Var); 211 hrc = pObj->Get(pBstrPropName, 0, &Var, 0, 0); 212 if ( SUCCEEDED(hrc) 213 && V_VT(&Var) == VT_BSTR) 214 { 215 /* 216 * Convert the BSTR to UTF-8 and copy it 217 * into the return buffer. 218 */ 219 char *pszValue; 220 rc = RTUtf16ToUtf8(Var.bstrVal, &pszValue); 221 if (RT_SUCCESS(rc)) 222 { 223 rc = RTStrCopy(pszBuf, cbBuf, pszValue); 224 RTStrFree(pszValue); 225 hrc = WBEM_S_FALSE; 226 } 227 } 228 VariantClear(&Var); 229 pObj->Release(); 160 230 } 161 } 162 pObj->Release(); 231 } while (hrc != WBEM_S_FALSE); 232 233 pEnum->Release(); 163 234 } 164 } while(hr != WBEM_S_FALSE); 165 pEnum->Release(); 235 SysFreeString(pBstrFilter); 236 } 237 else 238 hrc = E_OUTOFMEMORY; 239 pServices->Release(); 166 240 } 167 p Services->Release();241 pLoc->Release(); 168 242 } 169 pLoc->Release(); 170 } 171 172 rtSystemShutdownDmiLookup(); 173 if (FAILED(hr)) 174 rc = VERR_NOT_FOUND; /** @todo Find a better error, since neither of the RTErrConvert* can do the conversion here. */ 243 SysFreeString(pBstrPropName); 244 } 245 else 246 hrc = E_OUTOFMEMORY; 247 rtSystemDmiWinTerminate(); 248 if (FAILED(hrc) && rc == VERR_NOT_SUPPORTED) 249 rc = VERR_NOT_SUPPORTED; 175 250 return rc; 176 251 } 177 RT_EXPORT_SYMBOL(RTSystemQueryDmiString); 178 252
Note:
See TracChangeset
for help on using the changeset viewer.