Changeset 27083 in vbox for trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibEvent.cpp
- Timestamp:
- Mar 5, 2010 1:05:51 PM (15 years ago)
- File:
-
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibEvent.cpp
r27080 r27083 1 1 /* $Id$ */ 2 2 /** @file 3 * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, Misc.3 * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, Events. 4 4 */ 5 5 6 6 /* 7 * Copyright (C) 2007 Sun Microsystems, Inc.7 * Copyright (C) 2007-2010 Sun Microsystems, Inc. 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 33 33 * Header Files * 34 34 *******************************************************************************/ 35 #include <iprt/mem.h>36 #include <iprt/string.h>37 35 #include <VBox/log.h> 38 #include <VBox/version.h>39 36 #include "VBGLR3Internal.h" 40 37 41 /** @todo Split this file up so we can drop most of the VBOX_VBGLR3_XFREE8642 * #ifdef'ing. */43 38 44 39 /** … … 104 99 } 105 100 106 107 /**108 * Write to the backdoor logger from ring 3 guest code.109 *110 * @returns IPRT status code.111 *112 * @param pch The string to log. Does not need to be terminated.113 * @param cb The number of byte to log.114 * @todo cb -> cch.115 *116 * @remarks This currently does not accept more than 255 bytes of data at117 * one time. It should probably be rewritten to use pass a pointer118 * in the IOCtl.119 */120 VBGLR3DECL(int) VbglR3WriteLog(const char *pch, size_t cb)121 {122 /*123 * Quietly skip NULL strings.124 * (Happens in the RTLogBackdoorPrintf case.)125 */126 if (!cb)127 return VINF_SUCCESS;128 if (!VALID_PTR(pch))129 return VERR_INVALID_POINTER;130 131 #ifdef RT_OS_WINDOWS132 /*133 * Duplicate the string as it may be read only (a C string).134 */135 void *pvTmp = RTMemDup(pch, cb);136 if (!pvTmp)137 return VERR_NO_MEMORY;138 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_LOG(cb), pvTmp, cb);139 RTMemFree(pvTmp);140 return rc;141 142 #elif 0 /** @todo Several OSes could take this route (solaris and freebsd for instance). */143 /*144 * Handle the entire request in one go.145 */146 return vbglR3DoIOCtl(VBOXGUEST_IOCTL_LOG(cb), pvTmp, cb);147 148 #else149 /*150 * *BSD does not accept more than 4KB per ioctl request, while151 * Linux can't express sizes above 8KB, so, split it up into 2KB chunks.152 */153 # define STEP 2048154 int rc = VINF_SUCCESS;155 for (size_t off = 0; off < cb && RT_SUCCESS(rc); off += STEP)156 {157 size_t cbStep = RT_MIN(cb - off, STEP);158 rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_LOG(cbStep), (char *)pch + off, cbStep);159 }160 # undef STEP161 return rc;162 #endif163 }164 165 166 /**167 * Change the IRQ filter mask.168 *169 * @returns IPRT status code.170 * @param fOr The OR mask.171 * @param fNo The NOT mask.172 */173 VBGLR3DECL(int) VbglR3CtlFilterMask(uint32_t fOr, uint32_t fNot)174 {175 VBoxGuestFilterMaskInfo Info;176 Info.u32OrMask = fOr;177 Info.u32NotMask = fNot;178 return vbglR3DoIOCtl(VBOXGUEST_IOCTL_CTL_FILTER_MASK, &Info, sizeof(Info));179 }180 181 182 /**183 * Report a change in the capabilities that we support to the host.184 *185 * @returns IPRT status code.186 * @param fOr Capabilities which have been added.187 * @param fNot Capabilities which have been removed.188 *189 * @todo Move to a different file.190 */191 VBGLR3DECL(int) VbglR3SetGuestCaps(uint32_t fOr, uint32_t fNot)192 {193 VMMDevReqGuestCapabilities2 Req;194 195 vmmdevInitRequest(&Req.header, VMMDevReq_SetGuestCapabilities);196 Req.u32OrMask = fOr;197 Req.u32NotMask = fNot;198 int rc = vbglR3GRPerform(&Req.header);199 #if defined(DEBUG) && !defined(VBOX_VBGLR3_XFREE86)200 if (RT_SUCCESS(rc))201 LogRel(("Successfully changed guest capabilities: or mask 0x%x, not mask 0x%x.\n", fOr, fNot));202 else203 LogRel(("Failed to change guest capabilities: or mask 0x%x, not mask 0x%x. rc=%Rrc.\n", fOr, fNot, rc));204 #endif205 return rc;206 }207 208 #ifndef VBOX_VBGLR3_XFREE86209 210 /**211 * Query the current statistics update interval.212 *213 * @returns IPRT status code.214 * @param pcMsInterval Update interval in ms (out).215 */216 VBGLR3DECL(int) VbglR3StatQueryInterval(PRTMSINTERVAL pcMsInterval)217 {218 VMMDevGetStatisticsChangeRequest Req;219 220 vmmdevInitRequest(&Req.header, VMMDevReq_GetStatisticsChangeRequest);221 Req.eventAck = VMMDEV_EVENT_STATISTICS_INTERVAL_CHANGE_REQUEST;222 Req.u32StatInterval = 1;223 int rc = vbglR3GRPerform(&Req.header);224 if (RT_SUCCESS(rc))225 {226 *pcMsInterval = Req.u32StatInterval * 1000;227 if (*pcMsInterval / 1000 != Req.u32StatInterval)228 *pcMsInterval = ~(RTMSINTERVAL)0;229 }230 return rc;231 }232 233 234 /**235 * Report guest statistics.236 *237 * @returns IPRT status code.238 * @param pReq Request packet with statistics.239 */240 VBGLR3DECL(int) VbglR3StatReport(VMMDevReportGuestStats *pReq)241 {242 vmmdevInitRequest(&pReq->header, VMMDevReq_ReportGuestStats);243 return vbglR3GRPerform(&pReq->header);244 }245 246 247 /**248 * Refresh the memory balloon after a change.249 *250 * @returns IPRT status code.251 * @param pcChunks The size of the balloon in chunks of 1MB (out).252 * @param pfHandleInR3 Allocating of memory in R3 required (out).253 */254 VBGLR3DECL(int) VbglR3MemBalloonRefresh(uint32_t *pcChunks, bool *pfHandleInR3)255 {256 VBoxGuestCheckBalloonInfo Info;257 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_CHECK_BALLOON, &Info, sizeof(Info));258 if (RT_SUCCESS(rc))259 {260 *pcChunks = Info.cBalloonChunks;261 Assert(Info.fHandleInR3 == false || Info.fHandleInR3 == true || RT_FAILURE(rc));262 *pfHandleInR3 = Info.fHandleInR3 != false;263 }264 return rc;265 }266 267 268 /**269 * Change the memory by granting/reclaiming memory to/from R0.270 *271 * @returns IPRT status code.272 * @param pv Memory chunk (1MB).273 * @param fInflate true = inflate balloon (grant memory).274 * false = deflate balloon (reclaim memory).275 */276 VBGLR3DECL(int) VbglR3MemBalloonChange(void *pv, bool fInflate)277 {278 VBoxGuestChangeBalloonInfo Info;279 Info.u64ChunkAddr = (uint64_t)((uintptr_t)pv);280 Info.fInflate = fInflate;281 return vbglR3DoIOCtl(VBOXGUEST_IOCTL_CHANGE_BALLOON, &Info, sizeof(Info));282 }283 284 285 /**286 * Fallback for vbglR3GetAdditionsVersion.287 */288 static int vbglR3GetAdditionsCompileTimeVersion(char **ppszVer, char **ppszRev)289 {290 if (ppszVer)291 {292 *ppszVer = RTStrDup(VBOX_VERSION_STRING);293 if (!*ppszVer)294 return VERR_NO_STR_MEMORY;295 }296 297 if (ppszRev)298 {299 char szRev[64];300 RTStrPrintf(szRev, sizeof(szRev), "%d", VBOX_SVN_REV);301 *ppszRev = RTStrDup(szRev);302 if (!*ppszRev)303 {304 if (ppszVer)305 {306 RTStrFree(*ppszVer);307 *ppszVer = NULL;308 }309 return VERR_NO_STR_MEMORY;310 }311 }312 313 return VINF_SUCCESS;314 }315 316 #ifdef RT_OS_WINDOWS317 /**318 * Looks up the storage path handle (registry).319 *320 * @returns IPRT status value321 * @param hKey Receives pointer of allocated version string. NULL is322 * accepted. The returned pointer must be closed by323 * vbglR3CloseAdditionsWinStoragePath().324 */325 static int vbglR3GetAdditionsWinStoragePath(PHKEY phKey)326 {327 /*328 * Try get the *installed* version first.329 */330 LONG r;331 332 /* Check the new path first. */333 r = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Sun\\VirtualBox Guest Additions", 0, KEY_READ, phKey);334 # ifdef RT_ARCH_AMD64335 if (r != ERROR_SUCCESS)336 {337 /* Check Wow6432Node (for new entries). */338 r = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wow6432Node\\Sun\\VirtualBox Guest Additions", 0, KEY_READ, phKey);339 }340 # endif341 342 /* Still no luck? Then try the old xVM paths ... */343 if (r != ERROR_SUCCESS)344 {345 r = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Sun\\xVM VirtualBox Guest Additions", 0, KEY_READ, phKey);346 # ifdef RT_ARCH_AMD64347 if (r != ERROR_SUCCESS)348 {349 /* Check Wow6432Node (for new entries). */350 r = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Wow6432Node\\Sun\\xVM VirtualBox Guest Additions", 0, KEY_READ, phKey);351 }352 # endif353 }354 return RTErrConvertFromWin32(r);355 }356 357 358 /**359 * Closes the storage path handle (registry).360 *361 * @returns IPRT status value362 * @param hKey Handle to close, retrieved by363 * vbglR3GetAdditionsWinStoragePath().364 */365 static int vbglR3CloseAdditionsWinStoragePath(HKEY hKey)366 {367 return RTErrConvertFromWin32(RegCloseKey(hKey));368 }369 370 #endif /* RT_OS_WINDOWS */371 372 /**373 * Retrieves the installed Guest Additions version and/or revision.374 *375 * @returns IPRT status value376 * @param ppszVer Receives pointer of allocated version string. NULL is377 * accepted. The returned pointer must be freed using378 * RTStrFree().379 * @param ppszRev Receives pointer of allocated revision string. NULL is380 * accepted. The returned pointer must be freed using381 * RTStrFree().382 */383 VBGLR3DECL(int) VbglR3GetAdditionsVersion(char **ppszVer, char **ppszRev)384 {385 #ifdef RT_OS_WINDOWS386 HKEY hKey;387 int rc = vbglR3GetAdditionsWinStoragePath(&hKey);388 if (RT_SUCCESS(rc))389 {390 /* Version. */391 LONG l;392 DWORD dwType;393 DWORD dwSize = 32;394 char *pszTmp;395 if (ppszVer)396 {397 pszTmp = (char*)RTMemAlloc(dwSize);398 if (pszTmp)399 {400 l = RegQueryValueEx(hKey, "Version", NULL, &dwType, (BYTE*)(LPCTSTR)pszTmp, &dwSize);401 if (l == ERROR_SUCCESS)402 {403 if (dwType == REG_SZ)404 rc = RTStrDupEx(ppszVer, pszTmp);405 else406 rc = VERR_INVALID_PARAMETER;407 }408 else409 {410 rc = RTErrConvertFromWin32(l);411 }412 RTMemFree(pszTmp);413 }414 else415 rc = VERR_NO_MEMORY;416 }417 /* Revision. */418 if (ppszRev)419 {420 dwSize = 32; /* Reset */421 pszTmp = (char*)RTMemAlloc(dwSize);422 if (pszTmp)423 {424 l = RegQueryValueEx(hKey, "Revision", NULL, &dwType, (BYTE*)(LPCTSTR)pszTmp, &dwSize);425 if (l == ERROR_SUCCESS)426 {427 if (dwType == REG_SZ)428 rc = RTStrDupEx(ppszRev, pszTmp);429 else430 rc = VERR_INVALID_PARAMETER;431 }432 else433 {434 rc = RTErrConvertFromWin32(l);435 }436 RTMemFree(pszTmp);437 }438 else439 rc = VERR_NO_MEMORY;440 441 if (RT_FAILURE(rc) && ppszVer)442 {443 RTStrFree(*ppszVer);444 *ppszVer = NULL;445 }446 }447 rc = vbglR3CloseAdditionsWinStoragePath(hKey);448 }449 else450 {451 /*452 * No registry entries found, return the version string compiled453 * into this binary.454 */455 rc = vbglR3GetAdditionsCompileTimeVersion(ppszVer, ppszRev);456 }457 return rc;458 459 #else /* !RT_OS_WINDOWS */460 /*461 * On non-Windows platforms just return the compile-time version string.462 */463 return vbglR3GetAdditionsCompileTimeVersion(ppszVer, ppszRev);464 #endif /* !RT_OS_WINDOWS */465 }466 467 468 /**469 * Retrieves the installation path of Guest Additions.470 *471 * @returns IPRT status value472 * @param ppszPath Receives pointer of allocated installation path string.473 * The returned pointer must be freed using474 * RTStrFree().475 */476 VBGLR3DECL(int) VbglR3GetAdditionsInstallationPath(char **ppszPath)477 {478 int rc;479 #ifdef RT_OS_WINDOWS480 HKEY hKey;481 rc = vbglR3GetAdditionsWinStoragePath(&hKey);482 if (RT_SUCCESS(rc))483 {484 /* Installation directory. */485 DWORD dwType;486 DWORD dwSize = _MAX_PATH * sizeof(char);487 char *pszTmp = (char*)RTMemAlloc(dwSize + 1);488 if (pszTmp)489 {490 LONG l = RegQueryValueEx(hKey, "InstallDir", NULL, &dwType, (BYTE*)(LPCTSTR)pszTmp, &dwSize);491 if ((l != ERROR_SUCCESS) && (l != ERROR_FILE_NOT_FOUND))492 {493 rc = RTErrConvertFromNtStatus(l);494 }495 else496 {497 if (dwType == REG_SZ)498 rc = RTStrDupEx(ppszPath, pszTmp);499 else500 rc = VERR_INVALID_PARAMETER;501 if (RT_SUCCESS(rc))502 {503 /* Flip slashes. */504 for (char *pszTmp2 = ppszPath[0]; *pszTmp2; ++pszTmp2)505 if (*pszTmp2 == '\\')506 *pszTmp2 = '/';507 }508 }509 RTMemFree(pszTmp);510 }511 else512 rc = VERR_NO_MEMORY;513 rc = vbglR3CloseAdditionsWinStoragePath(hKey);514 }515 #else516 /** @todo implement me */517 rc = VERR_NOT_IMPLEMENTED;518 #endif519 return rc;520 }521 522 #endif /* !VBOX_VBGLR3_XFREE86 */523
Note:
See TracChangeset
for help on using the changeset viewer.