VirtualBox

source: vbox/trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibAdditions.cpp@ 55772

Last change on this file since 55772 was 48938, checked in by vboxsync, 11 years ago

Additions/common: Whitespace and svn:keyword cleanups by scm.

  • Property svn:eol-style set to native
  • Property svn:keyword set to Id
  • Property svn:keywords set to Id Revision
File size: 11.0 KB
Line 
1/* $Id: VBoxGuestR3LibAdditions.cpp 48938 2013-10-07 21:23:57Z vboxsync $ */
2/** @file
3 * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, Additions Info.
4 */
5
6/*
7 * Copyright (C) 2007-2011 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/string.h>
33#include <VBox/log.h>
34#include <VBox/version.h>
35#include "VBGLR3Internal.h"
36
37
38/**
39 * Fallback for VbglR3GetAdditionsVersion.
40 */
41static int vbglR3GetAdditionsCompileTimeVersion(char **ppszVer, char **ppszVerEx, char **ppszRev)
42{
43 int rc = VINF_SUCCESS;
44 if (ppszVer)
45 rc = RTStrDupEx(ppszVer, VBOX_VERSION_STRING_RAW);
46 if (RT_SUCCESS(rc))
47 {
48 if (ppszVerEx)
49 rc = RTStrDupEx(ppszVerEx, VBOX_VERSION_STRING);
50 if (RT_SUCCESS(rc))
51 {
52 if (ppszRev)
53 {
54#if 0
55 char szRev[64];
56 RTStrPrintf(szRev, sizeof(szRev), "%d", VBOX_SVN_REV);
57 rc = RTStrDupEx(ppszRev, szRev);
58#else
59 rc = RTStrDupEx(ppszRev, RT_XSTR(VBOX_SVN_REV));
60#endif
61 }
62 if (RT_SUCCESS(rc))
63 return VINF_SUCCESS;
64
65 /* bail out: */
66 }
67 if (ppszVerEx)
68 {
69 RTStrFree(*ppszVerEx);
70 *ppszVerEx = NULL;
71 }
72 }
73 if (ppszVer)
74 {
75 RTStrFree(*ppszVer);
76 *ppszVer = NULL;
77 }
78 return rc;
79}
80
81#ifdef RT_OS_WINDOWS
82
83/**
84 * Looks up the storage path handle (registry).
85 *
86 * @returns IPRT status value
87 * @param hKey Receives storage path handle on success.
88 * The returned handle must be closed by vbglR3CloseAdditionsWinStoragePath().
89 */
90static int vbglR3QueryAdditionsWinStoragePath(PHKEY phKey)
91{
92 /*
93 * Try get the *installed* version first.
94 */
95 LONG r;
96
97 /* Check the built in vendor path first. */
98 char szPath[255];
99 RTStrPrintf(szPath, sizeof(szPath), "SOFTWARE\\%s\\VirtualBox Guest Additions", VBOX_VENDOR_SHORT);
100 r = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szPath, 0, KEY_READ, phKey);
101# ifdef RT_ARCH_AMD64
102 if (r != ERROR_SUCCESS)
103 {
104 /* Check Wow6432Node. */
105 RTStrPrintf(szPath, sizeof(szPath), "SOFTWARE\\Wow6432Node\\%s\\VirtualBox Guest Additions", VBOX_VENDOR_SHORT);
106 r = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szPath, 0, KEY_READ, phKey);
107 }
108# endif
109
110 /* Check the "Sun" path first. */
111 if (r != ERROR_SUCCESS)
112 {
113 r = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Sun\\VirtualBox Guest Additions", 0, KEY_READ, phKey);
114# ifdef RT_ARCH_AMD64
115 if (r != ERROR_SUCCESS)
116 {
117 /* Check Wow6432Node (for new entries). */
118 r = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wow6432Node\\Sun\\VirtualBox Guest Additions", 0, KEY_READ, phKey);
119 }
120# endif
121 }
122
123 /* Still no luck? Then try the old "Sun xVM" paths ... */
124 if (r != ERROR_SUCCESS)
125 {
126 r = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Sun\\xVM VirtualBox Guest Additions", 0, KEY_READ, phKey);
127# ifdef RT_ARCH_AMD64
128 if (r != ERROR_SUCCESS)
129 {
130 /* Check Wow6432Node (for new entries). */
131 r = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wow6432Node\\Sun\\xVM VirtualBox Guest Additions", 0, KEY_READ, phKey);
132 }
133# endif
134 }
135 return RTErrConvertFromWin32(r);
136}
137
138
139/**
140 * Closes the storage path handle (registry).
141 *
142 * @returns IPRT status value
143 * @param hKey Handle to close, retrieved by
144 * vbglR3QueryAdditionsWinStoragePath().
145 */
146static int vbglR3CloseAdditionsWinStoragePath(HKEY hKey)
147{
148 return RTErrConvertFromWin32(RegCloseKey(hKey));
149}
150
151#endif /* RT_OS_WINDOWS */
152
153/**
154 * Reports the Guest Additions status of a certain facility to the host.
155 *
156 * @returns IPRT status value
157 * @param enmFacility The facility to report the status on.
158 * @param enmStatus The new status of the facility.
159 * @param fReserved Reserved for future use (what?).
160 */
161VBGLR3DECL(int) VbglR3ReportAdditionsStatus(VBoxGuestFacilityType enmFacility,
162 VBoxGuestFacilityStatus enmStatusCurrent,
163 uint32_t fReserved)
164{
165 VMMDevReportGuestStatus Report;
166 RT_ZERO(Report);
167 int rc = vmmdevInitRequest((VMMDevRequestHeader*)&Report, VMMDevReq_ReportGuestStatus);
168 if (RT_SUCCESS(rc))
169 {
170 Report.guestStatus.facility = enmFacility;
171 Report.guestStatus.status = enmStatusCurrent;
172 Report.guestStatus.flags = fReserved;
173
174 rc = vbglR3GRPerform(&Report.header);
175 }
176 return rc;
177}
178
179#ifdef RT_OS_WINDOWS
180
181/**
182 * Queries a string value from a specified registry key.
183 *
184 * @return IPRT status code.
185 * @param hKey Handle of registry key to use.
186 * @param pszValName Value name to query value from.
187 * @param pszBuffer Pointer to buffer which the queried string value gets stored into.
188 * @param cchBuffer Size (in bytes) of buffer.
189 */
190static int vbglR3QueryRegistryString(HKEY hKey, const char *pszValName, char *pszBuffer, size_t cchBuffer)
191{
192 AssertReturn(pszValName, VERR_INVALID_PARAMETER);
193 AssertReturn(pszBuffer, VERR_INVALID_POINTER);
194 AssertReturn(cchBuffer, VERR_INVALID_PARAMETER);
195
196 int rc;
197 DWORD dwType;
198 DWORD dwSize = (DWORD)cchBuffer;
199 LONG lRet = RegQueryValueEx(hKey, pszValName, NULL, &dwType, (BYTE *)pszBuffer, &dwSize);
200 if (lRet == ERROR_SUCCESS)
201 rc = dwType == REG_SZ ? VINF_SUCCESS : VERR_INVALID_PARAMETER;
202 else
203 rc = RTErrConvertFromWin32(lRet);
204 return rc;
205}
206
207#endif /* RT_OS_WINDOWS */
208
209/**
210 * Retrieves the installed Guest Additions version and/or revision.
211 *
212 * @returns IPRT status value
213 * @param ppszVer Receives pointer of allocated raw version string
214 * (major.minor.build). NULL is accepted. The returned
215 * pointer must be freed using RTStrFree().*
216 * @param ppszVerExt Receives pointer of allocated full version string
217 * (raw version + vendor suffix(es)). NULL is
218 * accepted. The returned pointer must be freed using
219 * RTStrFree().
220 * @param ppszRev Receives pointer of allocated revision string. NULL is
221 * accepted. The returned pointer must be freed using
222 * RTStrFree().
223 */
224VBGLR3DECL(int) VbglR3GetAdditionsVersion(char **ppszVer, char **ppszVerExt, char **ppszRev)
225{
226 /*
227 * Zap the return value up front.
228 */
229 if (ppszVer)
230 *ppszVer = NULL;
231 if (ppszVerExt)
232 *ppszVerExt = NULL;
233 if (ppszRev)
234 *ppszRev = NULL;
235
236#ifdef RT_OS_WINDOWS
237 HKEY hKey;
238 int rc = vbglR3QueryAdditionsWinStoragePath(&hKey);
239 if (RT_SUCCESS(rc))
240 {
241 /*
242 * Version.
243 */
244 char szTemp[32];
245 if (ppszVer)
246 {
247 rc = vbglR3QueryRegistryString(hKey, "Version", szTemp, sizeof(szTemp));
248 if (RT_SUCCESS(rc))
249 rc = RTStrDupEx(ppszVer, szTemp);
250 }
251
252 if ( RT_SUCCESS(rc)
253 && ppszVerExt)
254 {
255 rc = vbglR3QueryRegistryString(hKey, "VersionExt", szTemp, sizeof(szTemp));
256 if (RT_SUCCESS(rc))
257 rc = RTStrDupEx(ppszVerExt, szTemp);
258 }
259
260 /*
261 * Revision.
262 */
263 if ( RT_SUCCESS(rc)
264 && ppszRev)
265 {
266 rc = vbglR3QueryRegistryString(hKey, "Revision", szTemp, sizeof(szTemp));
267 if (RT_SUCCESS(rc))
268 rc = RTStrDupEx(ppszRev, szTemp);
269 }
270
271 int rc2 = vbglR3CloseAdditionsWinStoragePath(hKey);
272 if (RT_SUCCESS(rc))
273 rc = rc2;
274
275 /* Clean up allocated strings on error. */
276 if (RT_FAILURE(rc))
277 {
278 if (ppszVer)
279 RTStrFree(*ppszVer);
280 if (ppszVerExt)
281 RTStrFree(*ppszVerExt);
282 if (ppszRev)
283 RTStrFree(*ppszRev);
284 }
285 }
286 else
287 {
288 /*
289 * No registry entries found, return the version string compiled
290 * into this binary.
291 */
292 rc = vbglR3GetAdditionsCompileTimeVersion(ppszVer, ppszVerExt, ppszRev);
293 }
294 return rc;
295
296#else /* !RT_OS_WINDOWS */
297 /*
298 * On non-Windows platforms just return the compile-time version string.
299 */
300 return vbglR3GetAdditionsCompileTimeVersion(ppszVer, ppszVerExt, ppszRev);
301#endif /* !RT_OS_WINDOWS */
302}
303
304
305/**
306 * Retrieves the installation path of Guest Additions.
307 *
308 * @returns IPRT status value
309 * @param ppszPath Receives pointer of allocated installation path string.
310 * The returned pointer must be freed using
311 * RTStrFree().
312 */
313VBGLR3DECL(int) VbglR3GetAdditionsInstallationPath(char **ppszPath)
314{
315 int rc;
316#ifdef RT_OS_WINDOWS
317 HKEY hKey;
318 rc = vbglR3QueryAdditionsWinStoragePath(&hKey);
319 if (RT_SUCCESS(rc))
320 {
321 /* Installation directory. */
322 DWORD dwType;
323 DWORD dwSize = _MAX_PATH * sizeof(char);
324 char *pszTmp = (char*)RTMemAlloc(dwSize + 1);
325 if (pszTmp)
326 {
327 LONG l = RegQueryValueEx(hKey, "InstallDir", NULL, &dwType, (BYTE*)(LPCTSTR)pszTmp, &dwSize);
328 if ((l != ERROR_SUCCESS) && (l != ERROR_FILE_NOT_FOUND))
329 {
330 rc = RTErrConvertFromNtStatus(l);
331 }
332 else
333 {
334 if (dwType == REG_SZ)
335 rc = RTStrDupEx(ppszPath, pszTmp);
336 else
337 rc = VERR_INVALID_PARAMETER;
338 if (RT_SUCCESS(rc))
339 {
340 /* Flip slashes. */
341 for (char *pszTmp2 = ppszPath[0]; *pszTmp2; ++pszTmp2)
342 if (*pszTmp2 == '\\')
343 *pszTmp2 = '/';
344 }
345 }
346 RTMemFree(pszTmp);
347 }
348 else
349 rc = VERR_NO_MEMORY;
350 rc = vbglR3CloseAdditionsWinStoragePath(hKey);
351 }
352#else
353 /** @todo implement me */
354 rc = VERR_NOT_IMPLEMENTED;
355#endif
356 return rc;
357}
358
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