Changeset 58176 in vbox for trunk/src/VBox/Additions
- Timestamp:
- Oct 12, 2015 11:10:47 AM (9 years ago)
- svn:sync-xref-src-repo-rev:
- 103288
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibAdditions.cpp
r57358 r58176 30 30 *********************************************************************************************************************************/ 31 31 #include <iprt/mem.h> 32 #include <iprt/path.h> 32 33 #include <iprt/string.h> 33 34 #include <VBox/log.h> … … 36 37 37 38 39 40 #ifdef RT_OS_WINDOWS 41 42 # define WIDE_STR_2(a) L##a 43 # define WIDE_STR(a) WIDE_STR_2(a) 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 */ 52 static 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\\" WIDE_STR(VBOX_VENDOR_SHORT) L"\\VirtualBox Guest Additions", 61 #ifdef RT_ARCH_AMD64 62 L"SOFTWARE\\Wow6432Node\\" WIDE_STR(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 */ 94 static 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 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 */ 114 static 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 38 169 /** 39 170 * Fallback for VbglR3GetAdditionsVersion. 171 * 172 * @copydoc VbglR3GetAdditionsVersion 40 173 */ 41 174 static int vbglR3GetAdditionsCompileTimeVersion(char **ppszVer, char **ppszVerEx, char **ppszRev) … … 51 184 { 52 185 if (ppszRev) 53 {54 #if 055 char szRev[64];56 RTStrPrintf(szRev, sizeof(szRev), "%d", VBOX_SVN_REV);57 rc = RTStrDupEx(ppszRev, szRev);58 #else59 186 rc = RTStrDupEx(ppszRev, RT_XSTR(VBOX_SVN_REV)); 60 #endif61 }62 187 if (RT_SUCCESS(rc)) 63 188 return VINF_SUCCESS; … … 79 204 } 80 205 81 #ifdef RT_OS_WINDOWS82 83 /**84 * Looks up the storage path handle (registry).85 *86 * @returns IPRT status value87 * @param hKey Receives storage path handle on success.88 * The returned handle must be closed by vbglR3CloseAdditionsWinStoragePath().89 */90 static 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_AMD64102 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 # endif109 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_AMD64115 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 # endif121 }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_AMD64128 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 # endif134 }135 return RTErrConvertFromWin32(r);136 }137 138 139 /**140 * Closes the storage path handle (registry).141 *142 * @returns IPRT status value143 * @param hKey Handle to close, retrieved by144 * vbglR3QueryAdditionsWinStoragePath().145 */146 static 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 value157 * @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 */161 VBGLR3DECL(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_WINDOWS180 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 */190 static 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 else203 rc = RTErrConvertFromWin32(lRet);204 return rc;205 }206 207 #endif /* RT_OS_WINDOWS */208 206 209 207 /** 210 208 * Retrieves the installed Guest Additions version and/or revision. 211 209 * 212 * @returns IPRT status value210 * @returns IPRT status code 213 211 * @param ppszVer Receives pointer of allocated raw version string 214 212 * (major.minor.build). NULL is accepted. The returned 215 * pointer must be freed using RTStrFree(). *213 * pointer must be freed using RTStrFree(). 216 214 * @param ppszVerExt Receives pointer of allocated full version string 217 215 * (raw version + vendor suffix(es)). NULL is … … 236 234 #ifdef RT_OS_WINDOWS 237 235 HKEY hKey; 238 int rc = vbglR3 QueryAdditionsWinStoragePath(&hKey);236 int rc = vbglR3WinOpenAdditionRegisterKey(&hKey); 239 237 if (RT_SUCCESS(rc)) 240 238 { … … 242 240 * Version. 243 241 */ 244 char szTemp[32];245 242 if (ppszVer) 246 { 247 rc = vbglR3QueryRegistryString(hKey, "Version", szTemp, sizeof(szTemp)); 248 if (RT_SUCCESS(rc)) 249 rc = RTStrDupEx(ppszVer, szTemp); 250 } 243 rc = vbglR3QueryRegistryString(hKey, L"Version", 64, ppszVer); 251 244 252 245 if ( RT_SUCCESS(rc) 253 246 && ppszVerExt) 254 { 255 rc = vbglR3QueryRegistryString(hKey, "VersionExt", szTemp, sizeof(szTemp)); 256 if (RT_SUCCESS(rc)) 257 rc = RTStrDupEx(ppszVerExt, szTemp); 258 } 247 rc = vbglR3QueryRegistryString(hKey, L"VersionExt", 128, ppszVerExt); 259 248 260 249 /* … … 263 252 if ( RT_SUCCESS(rc) 264 253 && 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; 254 rc = vbglR3QueryRegistryString(hKey, L"Revision", 64, ppszRev); 255 256 rc = vbglR3WinCloseRegKey(hKey, rc); 274 257 275 258 /* Clean up allocated strings on error. */ … … 277 260 { 278 261 if (ppszVer) 262 { 279 263 RTStrFree(*ppszVer); 264 *ppszVer = NULL; 265 } 280 266 if (ppszVerExt) 267 { 281 268 RTStrFree(*ppszVerExt); 269 *ppszVerExt = NULL; 270 } 282 271 if (ppszRev) 272 { 283 273 RTStrFree(*ppszRev); 284 } 285 } 274 *ppszRev = NULL; 275 } 276 } 277 } 278 /* 279 * No registry entries found, return the version string compiled into this binary. 280 */ 286 281 else 287 {288 /*289 * No registry entries found, return the version string compiled290 * into this binary.291 */292 282 rc = vbglR3GetAdditionsCompileTimeVersion(ppszVer, ppszVerExt, ppszRev); 293 }294 283 return rc; 295 284 … … 306 295 * Retrieves the installation path of Guest Additions. 307 296 * 308 * @returns IPRT status value297 * @returns IPRT status code 309 298 * @param ppszPath Receives pointer of allocated installation path string. 310 299 * The returned pointer must be freed using … … 314 303 { 315 304 int rc; 305 316 306 #ifdef RT_OS_WINDOWS 307 /* 308 * Get it from the registry. 309 */ 317 310 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); 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); 351 318 } 352 319 #else … … 357 324 } 358 325 326 327 /** 328 * Reports the Guest Additions status of a certain facility to the host. 329 * 330 * @returns IPRT status code 331 * @param enmFacility The facility to report the status on. 332 * @param enmStatus The new status of the facility. 333 * @param fReserved Flags reserved for future hacks. 334 */ 335 VBGLR3DECL(int) VbglR3ReportAdditionsStatus(VBoxGuestFacilityType enmFacility, 336 VBoxGuestFacilityStatus enmStatusCurrent, 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 = enmStatusCurrent; 346 Report.guestStatus.flags = fReserved; 347 348 rc = vbglR3GRPerform(&Report.header); 349 } 350 return rc; 351 } 352
Note:
See TracChangeset
for help on using the changeset viewer.