VirtualBox

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

Last change on this file since 76409 was 76409, checked in by vboxsync, 6 years ago

iprt/string.h: Dropped including utf16.h and let those who need it include it themselves. bugref:9344

  • 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 76409 2018-12-23 18:27:21Z 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#include <iprt/utf16.h>
42
43
44/**
45 * Initialize COM.
46 *
47 * @returns COM status code.
48 */
49static HRESULT rtSystemDmiWinInitialize(void)
50{
51 HRESULT hrc = CoInitializeEx(0, COINIT_MULTITHREADED);
52 if (SUCCEEDED(hrc))
53 {
54 hrc = CoInitializeSecurity(NULL,
55 -1, /* COM authentication. */
56 NULL, /* Which authentication services. */
57 NULL, /* Reserved. */
58 RPC_C_AUTHN_LEVEL_DEFAULT, /* Default authentication. */
59 RPC_C_IMP_LEVEL_IMPERSONATE, /* Default impersonation. */
60 NULL, /* Authentication info. */
61 EOAC_NONE, /* Additional capabilities. */
62 NULL); /* Reserved. */
63 if (hrc == RPC_E_TOO_LATE)
64 hrc = S_OK;
65 else if (FAILED(hrc))
66 CoUninitialize();
67 }
68 return hrc;
69}
70
71
72/**
73 * Undo what rtSystemDmiWinInitialize did.
74 */
75static void rtSystemDmiWinTerminate(void)
76{
77 CoUninitialize();
78}
79
80
81/**
82 * Convert a UTF-8 string to a BSTR.
83 *
84 * @returns BSTR pointer.
85 * @param psz The UTF-8 string.
86 */
87static BSTR rtSystemWinBstrFromUtf8(const char *psz)
88{
89 PRTUTF16 pwsz = NULL;
90 int rc = RTStrToUtf16(psz, &pwsz);
91 if (RT_FAILURE(rc))
92 return NULL;
93 BSTR pBStr = SysAllocString((const OLECHAR *)pwsz);
94 RTUtf16Free(pwsz);
95 return pBStr;
96}
97
98
99/**
100 * Connect to the DMI server.
101 *
102 * @returns COM status code.
103 * @param pLocator The locator.
104 * @param pszServer The server name.
105 * @param ppServices Where to return the services interface.
106 */
107static HRESULT rtSystemDmiWinConnectToServer(IWbemLocator *pLocator, const char *pszServer, IWbemServices **ppServices)
108{
109 AssertPtr(pLocator);
110 AssertPtrNull(pszServer);
111 AssertPtr(ppServices);
112
113 BSTR pBStrServer = rtSystemWinBstrFromUtf8(pszServer);
114 if (!pBStrServer)
115 return E_OUTOFMEMORY;
116
117 HRESULT hrc = pLocator->ConnectServer(pBStrServer,
118 NULL,
119 NULL,
120 0,
121 NULL,
122 0,
123 0,
124 ppServices);
125 if (SUCCEEDED(hrc))
126 {
127 hrc = CoSetProxyBlanket(*ppServices,
128 RPC_C_AUTHN_WINNT,
129 RPC_C_AUTHZ_NONE,
130 NULL,
131 RPC_C_AUTHN_LEVEL_CALL,
132 RPC_C_IMP_LEVEL_IMPERSONATE,
133 NULL,
134 EOAC_NONE);
135 if (FAILED(hrc))
136 (*ppServices)->Release();
137 }
138 SysFreeString(pBStrServer);
139 return hrc;
140}
141
142
143RTDECL(int) RTSystemQueryDmiString(RTSYSDMISTR enmString, char *pszBuf, size_t cbBuf)
144{
145 AssertPtrReturn(pszBuf, VERR_INVALID_POINTER);
146 AssertReturn(cbBuf > 0, VERR_INVALID_PARAMETER);
147 *pszBuf = '\0';
148 AssertReturn(enmString > RTSYSDMISTR_INVALID && enmString < RTSYSDMISTR_END, VERR_INVALID_PARAMETER);
149
150 /*
151 * Figure the property name before we start.
152 */
153 const char *pszPropName;
154 switch (enmString)
155 {
156 case RTSYSDMISTR_PRODUCT_NAME: pszPropName = "Name"; break;
157 case RTSYSDMISTR_PRODUCT_VERSION: pszPropName = "Version"; break;
158 case RTSYSDMISTR_PRODUCT_UUID: pszPropName = "UUID"; break;
159 case RTSYSDMISTR_PRODUCT_SERIAL: pszPropName = "IdentifyingNumber"; break;
160 case RTSYSDMISTR_MANUFACTURER: pszPropName = "Vendor"; break;
161
162 default:
163 return VERR_NOT_SUPPORTED;
164 }
165
166 /*
167 * Before we do anything with COM, we have to initialize it.
168 */
169 bool fUninit = true;
170 HRESULT hrc = rtSystemDmiWinInitialize();
171 if (hrc == RPC_E_CHANGED_MODE)
172 fUninit = false; /* don't fail if already initialized */
173 else if (FAILED(hrc))
174 return VERR_NOT_SUPPORTED;
175
176 int rc = VERR_NOT_SUPPORTED;
177 BSTR pBstrPropName = rtSystemWinBstrFromUtf8(pszPropName);
178 if (pBstrPropName)
179 {
180 /*
181 * Instantiate the IWbemLocator, whatever that is and connect to the
182 * DMI serve.
183 */
184 IWbemLocator *pLoc;
185 hrc = CoCreateInstance(CLSID_WbemLocator,
186 0,
187 CLSCTX_INPROC_SERVER,
188 IID_IWbemLocator,
189 (LPVOID *)&pLoc);
190 if (SUCCEEDED(hrc))
191 {
192 IWbemServices *pServices;
193 hrc = rtSystemDmiWinConnectToServer(pLoc, "ROOT\\CIMV2", &pServices);
194 if (SUCCEEDED(hrc))
195 {
196 /*
197 * Enumerate whatever it is we're looking at and try get
198 * the desired property.
199 */
200 BSTR pBstrFilter = rtSystemWinBstrFromUtf8("Win32_ComputerSystemProduct");
201 if (pBstrFilter)
202 {
203 IEnumWbemClassObject *pEnum;
204 hrc = pServices->CreateInstanceEnum(pBstrFilter, 0, NULL, &pEnum);
205 if (SUCCEEDED(hrc))
206 {
207 do
208 {
209 IWbemClassObject *pObj;
210 ULONG cObjRet;
211 hrc = pEnum->Next(WBEM_INFINITE, 1, &pObj, &cObjRet);
212 if ( SUCCEEDED(hrc)
213 && cObjRet >= 1)
214 {
215 VARIANT Var;
216 VariantInit(&Var);
217 hrc = pObj->Get(pBstrPropName, 0, &Var, 0, 0);
218 if ( SUCCEEDED(hrc)
219 && V_VT(&Var) == VT_BSTR)
220 {
221 /*
222 * Convert the BSTR to UTF-8 and copy it
223 * into the return buffer.
224 */
225 char *pszValue;
226 rc = RTUtf16ToUtf8(Var.bstrVal, &pszValue);
227 if (RT_SUCCESS(rc))
228 {
229 rc = RTStrCopy(pszBuf, cbBuf, pszValue);
230 RTStrFree(pszValue);
231 hrc = WBEM_S_FALSE;
232 }
233 }
234 VariantClear(&Var);
235 pObj->Release();
236 }
237 } while (hrc != WBEM_S_FALSE);
238
239 pEnum->Release();
240 }
241 SysFreeString(pBstrFilter);
242 }
243 else
244 hrc = E_OUTOFMEMORY;
245 pServices->Release();
246 }
247 pLoc->Release();
248 }
249 SysFreeString(pBstrPropName);
250 }
251 else
252 hrc = E_OUTOFMEMORY;
253 if (fUninit)
254 rtSystemDmiWinTerminate();
255 if (FAILED(hrc) && rc == VERR_NOT_SUPPORTED)
256 rc = VERR_NOT_SUPPORTED;
257 return rc;
258}
259
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