VirtualBox

source: vbox/trunk/src/VBox/Runtime/r3/win/RTSystemQueryDmiString-win.cpp@ 75879

Last change on this file since 75879 was 69111, checked in by vboxsync, 7 years ago

(C) year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.1 KB
Line 
1/* $Id: RTSystemQueryDmiString-win.cpp 69111 2017-10-17 14:26:02Z vboxsync $ */
2/** @file
3 * IPRT - RTSystemQueryDmiString, windows ring-3.
4 */
5
6/*
7 * Copyright (C) 2010-2017 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#define _WIN32_DCOM
32#include <iprt/win/windows.h>
33#include <WbemCli.h>
34
35#include <iprt/system.h>
36#include "internal/iprt.h"
37
38#include <iprt/err.h>
39#include <iprt/assert.h>
40#include <iprt/string.h>
41
42
43/**
44 * Initialize COM.
45 *
46 * @returns COM status code.
47 */
48static HRESULT rtSystemDmiWinInitialize(void)
49{
50 HRESULT hrc = CoInitializeEx(0, COINIT_MULTITHREADED);
51 if (SUCCEEDED(hrc))
52 {
53 hrc = CoInitializeSecurity(NULL,
54 -1, /* COM authentication. */
55 NULL, /* Which authentication services. */
56 NULL, /* Reserved. */
57 RPC_C_AUTHN_LEVEL_DEFAULT, /* Default authentication. */
58 RPC_C_IMP_LEVEL_IMPERSONATE, /* Default impersonation. */
59 NULL, /* Authentication info. */
60 EOAC_NONE, /* Additional capabilities. */
61 NULL); /* Reserved. */
62 if (hrc == RPC_E_TOO_LATE)
63 hrc = S_OK;
64 else if (FAILED(hrc))
65 CoUninitialize();
66 }
67 return hrc;
68}
69
70
71/**
72 * Undo what rtSystemDmiWinInitialize did.
73 */
74static void rtSystemDmiWinTerminate(void)
75{
76 CoUninitialize();
77}
78
79
80/**
81 * Convert a UTF-8 string to a BSTR.
82 *
83 * @returns BSTR pointer.
84 * @param psz The UTF-8 string.
85 */
86static 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 */
106static HRESULT rtSystemDmiWinConnectToServer(IWbemLocator *pLocator, const char *pszServer, IWbemServices **ppServices)
107{
108 AssertPtr(pLocator);
109 AssertPtrNull(pszServer);
110 AssertPtr(ppServices);
111
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;
139}
140
141
142RTDECL(int) RTSystemQueryDmiString(RTSYSDMISTR enmString, char *pszBuf, size_t cbBuf)
143{
144 AssertPtrReturn(pszBuf, VERR_INVALID_POINTER);
145 AssertReturn(cbBuf > 0, VERR_INVALID_PARAMETER);
146 *pszBuf = '\0';
147 AssertReturn(enmString > RTSYSDMISTR_INVALID && enmString < RTSYSDMISTR_END, VERR_INVALID_PARAMETER);
148
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 case RTSYSDMISTR_MANUFACTURER: pszPropName = "Vendor"; break;
160
161 default:
162 return VERR_NOT_SUPPORTED;
163 }
164
165 /*
166 * Before we do anything with COM, we have to initialize it.
167 */
168 bool fUninit = true;
169 HRESULT hrc = rtSystemDmiWinInitialize();
170 if (hrc == RPC_E_CHANGED_MODE)
171 fUninit = false; /* don't fail if already initialized */
172 else if (FAILED(hrc))
173 return VERR_NOT_SUPPORTED;
174
175 int rc = VERR_NOT_SUPPORTED;
176 BSTR pBstrPropName = rtSystemWinBstrFromUtf8(pszPropName);
177 if (pBstrPropName)
178 {
179 /*
180 * Instantiate the IWbemLocator, whatever that is and connect to the
181 * DMI serve.
182 */
183 IWbemLocator *pLoc;
184 hrc = CoCreateInstance(CLSID_WbemLocator,
185 0,
186 CLSCTX_INPROC_SERVER,
187 IID_IWbemLocator,
188 (LPVOID *)&pLoc);
189 if (SUCCEEDED(hrc))
190 {
191 IWbemServices *pServices;
192 hrc = rtSystemDmiWinConnectToServer(pLoc, "ROOT\\CIMV2", &pServices);
193 if (SUCCEEDED(hrc))
194 {
195 /*
196 * Enumerate whatever it is we're looking at and try get
197 * the desired property.
198 */
199 BSTR pBstrFilter = rtSystemWinBstrFromUtf8("Win32_ComputerSystemProduct");
200 if (pBstrFilter)
201 {
202 IEnumWbemClassObject *pEnum;
203 hrc = pServices->CreateInstanceEnum(pBstrFilter, 0, NULL, &pEnum);
204 if (SUCCEEDED(hrc))
205 {
206 do
207 {
208 IWbemClassObject *pObj;
209 ULONG cObjRet;
210 hrc = pEnum->Next(WBEM_INFINITE, 1, &pObj, &cObjRet);
211 if ( SUCCEEDED(hrc)
212 && cObjRet >= 1)
213 {
214 VARIANT Var;
215 VariantInit(&Var);
216 hrc = pObj->Get(pBstrPropName, 0, &Var, 0, 0);
217 if ( SUCCEEDED(hrc)
218 && V_VT(&Var) == VT_BSTR)
219 {
220 /*
221 * Convert the BSTR to UTF-8 and copy it
222 * into the return buffer.
223 */
224 char *pszValue;
225 rc = RTUtf16ToUtf8(Var.bstrVal, &pszValue);
226 if (RT_SUCCESS(rc))
227 {
228 rc = RTStrCopy(pszBuf, cbBuf, pszValue);
229 RTStrFree(pszValue);
230 hrc = WBEM_S_FALSE;
231 }
232 }
233 VariantClear(&Var);
234 pObj->Release();
235 }
236 } while (hrc != WBEM_S_FALSE);
237
238 pEnum->Release();
239 }
240 SysFreeString(pBstrFilter);
241 }
242 else
243 hrc = E_OUTOFMEMORY;
244 pServices->Release();
245 }
246 pLoc->Release();
247 }
248 SysFreeString(pBstrPropName);
249 }
250 else
251 hrc = E_OUTOFMEMORY;
252 if (fUninit)
253 rtSystemDmiWinTerminate();
254 if (FAILED(hrc) && rc == VERR_NOT_SUPPORTED)
255 rc = VERR_NOT_SUPPORTED;
256 return rc;
257}
258
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette