VirtualBox

source: vbox/trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibAdditions.cpp@ 76422

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

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