VirtualBox

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

Last change on this file since 74714 was 69500, checked in by vboxsync, 7 years ago

*: scm --update-copyright-year

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