VirtualBox

source: vbox/trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibAdditions.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:keyword set to Id
  • Property svn:keywords set to Id Revision
File size: 10.5 KB
Line 
1/* $Id: VBoxGuestR3LibAdditions.cpp 76409 2018-12-23 18:27:21Z vboxsync $ */
2/** @file
3 * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, Additions Info.
4 */
5
6/*
7 * Copyright (C) 2007-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#include <iprt/mem.h>
32#include <iprt/path.h>
33#include <iprt/string.h>
34#ifdef RT_OS_WINDOWS
35# include <iprt/utf16.h>
36#endif
37#include <VBox/log.h>
38#include <VBox/version.h>
39#include "VBoxGuestR3LibInternal.h"
40
41
42
43#ifdef RT_OS_WINDOWS
44
45/**
46 * Opens the "VirtualBox Guest Additions" registry key.
47 *
48 * @returns IPRT status code
49 * @param phKey Receives key handle on success. The returned handle must
50 * be closed by calling vbglR3WinCloseRegKey.
51 */
52static int vbglR3WinOpenAdditionRegisterKey(PHKEY phKey)
53{
54 /*
55 * Current vendor first. We keep the older ones just for the case that
56 * the caller isn't actually installed yet (no real use case AFAIK).
57 */
58 static PCRTUTF16 s_apwszKeys[] =
59 {
60 L"SOFTWARE\\" RT_LSTR(VBOX_VENDOR_SHORT) L"\\VirtualBox Guest Additions",
61#ifdef RT_ARCH_AMD64
62 L"SOFTWARE\\Wow6432Node\\" RT_LSTR(VBOX_VENDOR_SHORT) L"\\VirtualBox Guest Additions",
63#endif
64 L"SOFTWARE\\Sun\\VirtualBox Guest Additions",
65#ifdef RT_ARCH_AMD64
66 L"SOFTWARE\\Wow6432Node\\Sun\\VirtualBox Guest Additions",
67#endif
68 L"SOFTWARE\\Sun\\xVM VirtualBox Guest Additions",
69#ifdef RT_ARCH_AMD64
70 L"SOFTWARE\\Wow6432Node\\Sun\\xVM VirtualBox Guest Additions",
71#endif
72 };
73 int rc = VERR_NOT_FOUND;
74 for (uint32_t i = 0; i < RT_ELEMENTS(s_apwszKeys); i++)
75 {
76 LSTATUS lrc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, s_apwszKeys[i], 0 /* ulOptions*/, KEY_READ, phKey);
77 if (lrc == ERROR_SUCCESS)
78 return VINF_SUCCESS;
79 if (i == 0)
80 rc = RTErrConvertFromWin32(lrc);
81 }
82 return rc;
83}
84
85
86/**
87 * Closes the registry handle returned by vbglR3WinOpenAdditionRegisterKey().
88 *
89 * @returns @a rc or IPRT failure status.
90 * @param hKey Handle to close.
91 * @param rc The current IPRT status of the operation. Error
92 * condition takes precedence over errors from this call.
93 */
94static int vbglR3WinCloseRegKey(HKEY hKey, int rc)
95{
96 LSTATUS lrc = RegCloseKey(hKey);
97 if ( lrc == ERROR_SUCCESS
98 || RT_FAILURE(rc))
99 return rc;
100 return RTErrConvertFromWin32(lrc);
101}
102
103
104/**
105 * Queries a string value from a specified registry key.
106 *
107 * @return IPRT status code.
108 * @param hKey Handle of registry key to use.
109 * @param pwszValueName The name of the value to query.
110 * @param cbHint Size hint.
111 * @param ppszValue Where to return value string on success. Free
112 * with RTStrFree.
113 */
114static int vbglR3QueryRegistryString(HKEY hKey, PCRTUTF16 pwszValueName, uint32_t cbHint, char **ppszValue)
115{
116 AssertPtr(pwszValueName);
117 AssertPtrReturn(ppszValue, VERR_INVALID_POINTER);
118
119 /*
120 * First try.
121 */
122 int rc;
123 DWORD dwType;
124 DWORD cbTmp = cbHint;
125 PRTUTF16 pwszTmp = (PRTUTF16)RTMemTmpAllocZ(cbTmp + sizeof(RTUTF16));
126 if (pwszTmp)
127 {
128 LSTATUS lrc = RegQueryValueExW(hKey, pwszValueName, NULL, &dwType, (BYTE *)pwszTmp, &cbTmp);
129 if (lrc == ERROR_MORE_DATA)
130 {
131 /*
132 * Allocate larger buffer and try again.
133 */
134 RTMemTmpFree(pwszTmp);
135 cbTmp += 16;
136 pwszTmp = (PRTUTF16)RTMemTmpAllocZ(cbTmp + sizeof(RTUTF16));
137 if (!pwszTmp)
138 {
139 *ppszValue = NULL;
140 return VERR_NO_TMP_MEMORY;
141 }
142 lrc = RegQueryValueExW(hKey, pwszValueName, NULL, &dwType, (BYTE *)pwszTmp, &cbTmp);
143 }
144 if (lrc == ERROR_SUCCESS)
145 {
146 /*
147 * Check the type and convert to UTF-8.
148 */
149 if (dwType == REG_SZ)
150 rc = RTUtf16ToUtf8(pwszTmp, ppszValue);
151 else
152 rc = VERR_WRONG_TYPE;
153 }
154 else
155 rc = RTErrConvertFromWin32(lrc);
156 RTMemTmpFree(pwszTmp);
157 }
158 else
159 rc = VERR_NO_TMP_MEMORY;
160 if (RT_SUCCESS(rc))
161 return rc;
162 *ppszValue = NULL;
163 return rc;
164}
165
166#endif /* RT_OS_WINDOWS */
167
168
169/**
170 * Fallback for VbglR3GetAdditionsVersion.
171 *
172 * @copydoc VbglR3GetAdditionsVersion
173 */
174static int vbglR3GetAdditionsCompileTimeVersion(char **ppszVer, char **ppszVerExt, char **ppszRev)
175{
176 int rc = VINF_SUCCESS;
177 if (ppszVer)
178 rc = RTStrDupEx(ppszVer, VBOX_VERSION_STRING_RAW);
179 if (RT_SUCCESS(rc))
180 {
181 if (ppszVerExt)
182 rc = RTStrDupEx(ppszVerExt, VBOX_VERSION_STRING);
183 if (RT_SUCCESS(rc))
184 {
185 if (ppszRev)
186 rc = RTStrDupEx(ppszRev, RT_XSTR(VBOX_SVN_REV));
187 if (RT_SUCCESS(rc))
188 return VINF_SUCCESS;
189
190 /* bail out: */
191 }
192 if (ppszVerExt)
193 {
194 RTStrFree(*ppszVerExt);
195 *ppszVerExt = NULL;
196 }
197 }
198 if (ppszVer)
199 {
200 RTStrFree(*ppszVer);
201 *ppszVer = NULL;
202 }
203 return rc;
204}
205
206
207/**
208 * Retrieves the installed Guest Additions version and/or revision.
209 *
210 * @returns IPRT status code
211 * @param ppszVer Receives pointer of allocated raw version string
212 * (major.minor.build). NULL is accepted. The returned
213 * pointer must be freed using RTStrFree().
214 * @param ppszVerExt Receives pointer of allocated full version string
215 * (raw version + vendor suffix(es)). NULL is
216 * accepted. The returned pointer must be freed using
217 * RTStrFree().
218 * @param ppszRev Receives pointer of allocated revision string. NULL is
219 * accepted. The returned pointer must be freed using
220 * RTStrFree().
221 */
222VBGLR3DECL(int) VbglR3GetAdditionsVersion(char **ppszVer, char **ppszVerExt, char **ppszRev)
223{
224 /*
225 * Zap the return value up front.
226 */
227 if (ppszVer)
228 *ppszVer = NULL;
229 if (ppszVerExt)
230 *ppszVerExt = NULL;
231 if (ppszRev)
232 *ppszRev = NULL;
233
234#ifdef RT_OS_WINDOWS
235 HKEY hKey;
236 int rc = vbglR3WinOpenAdditionRegisterKey(&hKey);
237 if (RT_SUCCESS(rc))
238 {
239 /*
240 * Version.
241 */
242 if (ppszVer)
243 rc = vbglR3QueryRegistryString(hKey, L"Version", 64, ppszVer);
244
245 if ( RT_SUCCESS(rc)
246 && ppszVerExt)
247 rc = vbglR3QueryRegistryString(hKey, L"VersionExt", 128, ppszVerExt);
248
249 /*
250 * Revision.
251 */
252 if ( RT_SUCCESS(rc)
253 && ppszRev)
254 rc = vbglR3QueryRegistryString(hKey, L"Revision", 64, ppszRev);
255
256 rc = vbglR3WinCloseRegKey(hKey, rc);
257
258 /* Clean up allocated strings on error. */
259 if (RT_FAILURE(rc))
260 {
261 if (ppszVer)
262 {
263 RTStrFree(*ppszVer);
264 *ppszVer = NULL;
265 }
266 if (ppszVerExt)
267 {
268 RTStrFree(*ppszVerExt);
269 *ppszVerExt = NULL;
270 }
271 if (ppszRev)
272 {
273 RTStrFree(*ppszRev);
274 *ppszRev = NULL;
275 }
276 }
277 }
278 /*
279 * No registry entries found, return the version string compiled into this binary.
280 */
281 else
282 rc = vbglR3GetAdditionsCompileTimeVersion(ppszVer, ppszVerExt, ppszRev);
283 return rc;
284
285#else /* !RT_OS_WINDOWS */
286 /*
287 * On non-Windows platforms just return the compile-time version string.
288 */
289 return vbglR3GetAdditionsCompileTimeVersion(ppszVer, ppszVerExt, ppszRev);
290#endif /* !RT_OS_WINDOWS */
291}
292
293
294/**
295 * Retrieves the installation path of Guest Additions.
296 *
297 * @returns IPRT status code
298 * @param ppszPath Receives pointer of allocated installation path string.
299 * The returned pointer must be freed using
300 * RTStrFree().
301 */
302VBGLR3DECL(int) VbglR3GetAdditionsInstallationPath(char **ppszPath)
303{
304 int rc;
305
306#ifdef RT_OS_WINDOWS
307 /*
308 * Get it from the registry.
309 */
310 HKEY hKey;
311 rc = vbglR3WinOpenAdditionRegisterKey(&hKey);
312 if (RT_SUCCESS(rc))
313 {
314 rc = vbglR3QueryRegistryString(hKey, L"InstallDir", _MAX_PATH * sizeof(RTUTF16), ppszPath);
315 if (RT_SUCCESS(rc))
316 RTPathChangeToUnixSlashes(*ppszPath, true /*fForce*/);
317 rc = vbglR3WinCloseRegKey(hKey, rc);
318 }
319#else
320 /** @todo implement me */
321 rc = VERR_NOT_IMPLEMENTED;
322 RT_NOREF1(ppszPath);
323#endif
324 return rc;
325}
326
327
328/**
329 * Reports the Guest Additions status of a certain facility to the host.
330 *
331 * @returns IPRT status code
332 * @param enmFacility The facility to report the status on.
333 * @param enmStatus The new status of the facility.
334 * @param fReserved Flags reserved for future hacks.
335 */
336VBGLR3DECL(int) VbglR3ReportAdditionsStatus(VBoxGuestFacilityType enmFacility, VBoxGuestFacilityStatus enmStatus,
337 uint32_t fReserved)
338{
339 VMMDevReportGuestStatus Report;
340 RT_ZERO(Report);
341 int rc = vmmdevInitRequest(&Report.header, VMMDevReq_ReportGuestStatus);
342 if (RT_SUCCESS(rc))
343 {
344 Report.guestStatus.facility = enmFacility;
345 Report.guestStatus.status = enmStatus;
346 Report.guestStatus.flags = fReserved;
347
348 rc = vbglR3GRPerform(&Report.header);
349 }
350 return rc;
351}
352
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