Changeset 27083 in vbox for trunk/src/VBox/Additions/common/VBoxGuestLib
- Timestamp:
- Mar 5, 2010 1:05:51 PM (15 years ago)
- Location:
- trunk/src/VBox/Additions/common/VBoxGuestLib
- Files:
-
- 3 edited
- 5 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxGuestLib/Makefile.kmk
r27014 r27083 94 94 VBoxGuestR3Lib_SOURCES = \ 95 95 VBoxGuestR3Lib.cpp \ 96 VBoxGuestR3LibAdditions.cpp \ 97 VBoxGuestR3LibBalloon.cpp \ 96 98 VBoxGuestR3LibClipboard.cpp \ 99 VBoxGuestR3LibCpuHotPlug.cpp \ 97 100 VBoxGuestR3LibCredentials.cpp \ 101 VBoxGuestR3LibEvent.cpp \ 98 102 VBoxGuestR3LibGR.cpp \ 99 VBoxGuestR3Lib Time.cpp \103 VBoxGuestR3LibLog.cpp \ 100 104 VBoxGuestR3LibMisc.cpp \ 101 VBoxGuestR3LibCpuHotPlug.cpp 105 VBoxGuestR3LibStat.cpp \ 106 VBoxGuestR3LibTime.cpp 102 107 ifneq ($(KBUILD_TARGET),win) ## @todo get rid of this hack (as soon as it's all implemented / #defined). 103 108 VBoxGuestR3Lib_SOURCES += \ … … 117 122 endif 118 123 119 VBoxGuestR3LibMisc.cpp_DEFS = VBOX_SVN_REV=$(VBOX_SVN_REV) 120 VBoxGuestR3LibMisc.cpp_DEPS = $(VBOX_SVN_REV_KMK) 124 VBoxGuestR3LibAdditions.cpp_DEFS = VBOX_SVN_REV=$(VBOX_SVN_REV) 121 125 122 126 # -
trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibAdditions.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, Additions Info. 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 … … 39 39 #include "VBGLR3Internal.h" 40 40 41 /** @todo Split this file up so we can drop most of the VBOX_VBGLR3_XFREE8642 * #ifdef'ing. */43 44 /**45 * Wait for the host to signal one or more events and return which.46 *47 * The events will only be delivered by the host if they have been enabled48 * previously using @a VbglR3CtlFilterMask. If one or several of the events49 * have already been signalled but not yet waited for, this function will return50 * immediately and return those events.51 *52 * @returns IPRT status code.53 *54 * @param fMask The events we want to wait for, or-ed together.55 * @param cMillies How long to wait before giving up and returning56 * (VERR_TIMEOUT). Use RT_INDEFINITE_WAIT to wait until we57 * are interrupted or one of the events is signalled.58 * @param pfEvents Where to store the events signalled. Optional.59 */60 VBGLR3DECL(int) VbglR3WaitEvent(uint32_t fMask, uint32_t cMillies, uint32_t *pfEvents)61 {62 #ifndef VBOX_VBGLR3_XFREE8663 LogFlow(("VbglR3WaitEvent: fMask=0x%x, cMillies=%u, pfEvents=%p\n",64 fMask, cMillies, pfEvents));65 AssertReturn((fMask & ~VMMDEV_EVENT_VALID_EVENT_MASK) == 0, VERR_INVALID_PARAMETER);66 AssertPtrNullReturn(pfEvents, VERR_INVALID_POINTER);67 #endif68 69 VBoxGuestWaitEventInfo waitEvent;70 waitEvent.u32TimeoutIn = cMillies;71 waitEvent.u32EventMaskIn = fMask;72 waitEvent.u32Result = VBOXGUEST_WAITEVENT_ERROR;73 waitEvent.u32EventFlagsOut = 0;74 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_WAITEVENT, &waitEvent, sizeof(waitEvent));75 if (RT_SUCCESS(rc))76 {77 #if !defined(VBOX_VBGLR3_XFREE86) && !defined(RT_OS_WINDOWS)78 AssertMsg(waitEvent.u32Result == VBOXGUEST_WAITEVENT_OK, ("%d rc=%Rrc\n", waitEvent.u32Result, rc));79 #endif80 if (pfEvents)81 *pfEvents = waitEvent.u32EventFlagsOut;82 }83 84 #ifndef VBOX_VBGLR3_XFREE8685 LogFlow(("VbglR3WaitEvent: rc=%Rrc, u32EventFlagsOut=0x%x. u32Result=%d\n",86 rc, waitEvent.u32EventFlagsOut, waitEvent.u32Result));87 #endif88 return rc;89 }90 91 92 /**93 * Cause any pending WaitEvent calls (VBOXGUEST_IOCTL_WAITEVENT) to return94 * with a VERR_INTERRUPTED status.95 *96 * Can be used in combination with a termination flag variable for interrupting97 * event loops. Avoiding race conditions is the responsibility of the caller.98 *99 * @returns IPRT status code.100 */101 VBGLR3DECL(int) VbglR3InterruptEventWaits(void)102 {103 return vbglR3DoIOCtl(VBOXGUEST_IOCTL_CANCEL_ALL_WAITEVENTS, 0, 0);104 }105 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 41 285 42 /** … … 520 277 } 521 278 522 #endif /* !VBOX_VBGLR3_XFREE86 */523 -
trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibBalloon.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, Ballooning. 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 #include <VBox/log.h>38 #include <VBox/version.h>39 35 #include "VBGLR3Internal.h" 40 41 /** @todo Split this file up so we can drop most of the VBOX_VBGLR3_XFREE8642 * #ifdef'ing. */43 44 /**45 * Wait for the host to signal one or more events and return which.46 *47 * The events will only be delivered by the host if they have been enabled48 * previously using @a VbglR3CtlFilterMask. If one or several of the events49 * have already been signalled but not yet waited for, this function will return50 * immediately and return those events.51 *52 * @returns IPRT status code.53 *54 * @param fMask The events we want to wait for, or-ed together.55 * @param cMillies How long to wait before giving up and returning56 * (VERR_TIMEOUT). Use RT_INDEFINITE_WAIT to wait until we57 * are interrupted or one of the events is signalled.58 * @param pfEvents Where to store the events signalled. Optional.59 */60 VBGLR3DECL(int) VbglR3WaitEvent(uint32_t fMask, uint32_t cMillies, uint32_t *pfEvents)61 {62 #ifndef VBOX_VBGLR3_XFREE8663 LogFlow(("VbglR3WaitEvent: fMask=0x%x, cMillies=%u, pfEvents=%p\n",64 fMask, cMillies, pfEvents));65 AssertReturn((fMask & ~VMMDEV_EVENT_VALID_EVENT_MASK) == 0, VERR_INVALID_PARAMETER);66 AssertPtrNullReturn(pfEvents, VERR_INVALID_POINTER);67 #endif68 69 VBoxGuestWaitEventInfo waitEvent;70 waitEvent.u32TimeoutIn = cMillies;71 waitEvent.u32EventMaskIn = fMask;72 waitEvent.u32Result = VBOXGUEST_WAITEVENT_ERROR;73 waitEvent.u32EventFlagsOut = 0;74 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_WAITEVENT, &waitEvent, sizeof(waitEvent));75 if (RT_SUCCESS(rc))76 {77 #if !defined(VBOX_VBGLR3_XFREE86) && !defined(RT_OS_WINDOWS)78 AssertMsg(waitEvent.u32Result == VBOXGUEST_WAITEVENT_OK, ("%d rc=%Rrc\n", waitEvent.u32Result, rc));79 #endif80 if (pfEvents)81 *pfEvents = waitEvent.u32EventFlagsOut;82 }83 84 #ifndef VBOX_VBGLR3_XFREE8685 LogFlow(("VbglR3WaitEvent: rc=%Rrc, u32EventFlagsOut=0x%x. u32Result=%d\n",86 rc, waitEvent.u32EventFlagsOut, waitEvent.u32Result));87 #endif88 return rc;89 }90 91 92 /**93 * Cause any pending WaitEvent calls (VBOXGUEST_IOCTL_WAITEVENT) to return94 * with a VERR_INTERRUPTED status.95 *96 * Can be used in combination with a termination flag variable for interrupting97 * event loops. Avoiding race conditions is the responsibility of the caller.98 *99 * @returns IPRT status code.100 */101 VBGLR3DECL(int) VbglR3InterruptEventWaits(void)102 {103 return vbglR3DoIOCtl(VBOXGUEST_IOCTL_CANCEL_ALL_WAITEVENTS, 0, 0);104 }105 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 36 246 37 … … 282 73 } 283 74 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 -
trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibCpuHotPlug.cpp
r26425 r27083 1 1 /* $Id$ */ 2 2 /** @file 3 * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, CPU hotplug.3 * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, CPU Hot Plugging. 4 4 */ 5 5 -
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 -
trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibLog.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, Logging. 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 … … 34 34 *******************************************************************************/ 35 35 #include <iprt/mem.h> 36 #include <iprt/string.h>37 #include <VBox/log.h>38 #include <VBox/version.h>39 36 #include "VBGLR3Internal.h" 40 41 /** @todo Split this file up so we can drop most of the VBOX_VBGLR3_XFREE8642 * #ifdef'ing. */43 44 /**45 * Wait for the host to signal one or more events and return which.46 *47 * The events will only be delivered by the host if they have been enabled48 * previously using @a VbglR3CtlFilterMask. If one or several of the events49 * have already been signalled but not yet waited for, this function will return50 * immediately and return those events.51 *52 * @returns IPRT status code.53 *54 * @param fMask The events we want to wait for, or-ed together.55 * @param cMillies How long to wait before giving up and returning56 * (VERR_TIMEOUT). Use RT_INDEFINITE_WAIT to wait until we57 * are interrupted or one of the events is signalled.58 * @param pfEvents Where to store the events signalled. Optional.59 */60 VBGLR3DECL(int) VbglR3WaitEvent(uint32_t fMask, uint32_t cMillies, uint32_t *pfEvents)61 {62 #ifndef VBOX_VBGLR3_XFREE8663 LogFlow(("VbglR3WaitEvent: fMask=0x%x, cMillies=%u, pfEvents=%p\n",64 fMask, cMillies, pfEvents));65 AssertReturn((fMask & ~VMMDEV_EVENT_VALID_EVENT_MASK) == 0, VERR_INVALID_PARAMETER);66 AssertPtrNullReturn(pfEvents, VERR_INVALID_POINTER);67 #endif68 69 VBoxGuestWaitEventInfo waitEvent;70 waitEvent.u32TimeoutIn = cMillies;71 waitEvent.u32EventMaskIn = fMask;72 waitEvent.u32Result = VBOXGUEST_WAITEVENT_ERROR;73 waitEvent.u32EventFlagsOut = 0;74 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_WAITEVENT, &waitEvent, sizeof(waitEvent));75 if (RT_SUCCESS(rc))76 {77 #if !defined(VBOX_VBGLR3_XFREE86) && !defined(RT_OS_WINDOWS)78 AssertMsg(waitEvent.u32Result == VBOXGUEST_WAITEVENT_OK, ("%d rc=%Rrc\n", waitEvent.u32Result, rc));79 #endif80 if (pfEvents)81 *pfEvents = waitEvent.u32EventFlagsOut;82 }83 84 #ifndef VBOX_VBGLR3_XFREE8685 LogFlow(("VbglR3WaitEvent: rc=%Rrc, u32EventFlagsOut=0x%x. u32Result=%d\n",86 rc, waitEvent.u32EventFlagsOut, waitEvent.u32Result));87 #endif88 return rc;89 }90 91 92 /**93 * Cause any pending WaitEvent calls (VBOXGUEST_IOCTL_WAITEVENT) to return94 * with a VERR_INTERRUPTED status.95 *96 * Can be used in combination with a termination flag variable for interrupting97 * event loops. Avoiding race conditions is the responsibility of the caller.98 *99 * @returns IPRT status code.100 */101 VBGLR3DECL(int) VbglR3InterruptEventWaits(void)102 {103 return vbglR3DoIOCtl(VBOXGUEST_IOCTL_CANCEL_ALL_WAITEVENTS, 0, 0);104 }105 37 106 38 … … 111 43 * 112 44 * @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. 45 * @param cch The number of chars (bytes) to log. 115 46 * 116 47 * @remarks This currently does not accept more than 255 bytes of data at … … 118 49 * in the IOCtl. 119 50 */ 120 VBGLR3DECL(int) VbglR3WriteLog(const char *pch, size_t c b)51 VBGLR3DECL(int) VbglR3WriteLog(const char *pch, size_t cch) 121 52 { 122 53 /* … … 124 55 * (Happens in the RTLogBackdoorPrintf case.) 125 56 */ 126 if (!c b)57 if (!cch) 127 58 return VINF_SUCCESS; 128 59 if (!VALID_PTR(pch)) … … 133 64 * Duplicate the string as it may be read only (a C string). 134 65 */ 135 void *pvTmp = RTMemDup(pch, c b);66 void *pvTmp = RTMemDup(pch, cch); 136 67 if (!pvTmp) 137 68 return VERR_NO_MEMORY; 138 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_LOG(c b), pvTmp, cb);69 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_LOG(cch), pvTmp, cch); 139 70 RTMemFree(pvTmp); 140 71 return rc; … … 144 75 * Handle the entire request in one go. 145 76 */ 146 return vbglR3DoIOCtl(VBOXGUEST_IOCTL_LOG(c b), pvTmp, cb);77 return vbglR3DoIOCtl(VBOXGUEST_IOCTL_LOG(cch), pvTmp, cch); 147 78 148 79 #else … … 153 84 # define STEP 2048 154 85 int rc = VINF_SUCCESS; 155 for (size_t off = 0; off < c b&& RT_SUCCESS(rc); off += STEP)86 for (size_t off = 0; off < cch && RT_SUCCESS(rc); off += STEP) 156 87 { 157 size_t cbStep = RT_MIN(c b- off, STEP);88 size_t cbStep = RT_MIN(cch - off, STEP); 158 89 rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_LOG(cbStep), (char *)pch + off, cbStep); 159 90 } … … 163 94 } 164 95 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 -
trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibMisc.cpp
r27080 r27083 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 41 /** @todo Split this file up so we can drop most of the VBOX_VBGLR3_XFREE8642 * #ifdef'ing. */43 44 /**45 * Wait for the host to signal one or more events and return which.46 *47 * The events will only be delivered by the host if they have been enabled48 * previously using @a VbglR3CtlFilterMask. If one or several of the events49 * have already been signalled but not yet waited for, this function will return50 * immediately and return those events.51 *52 * @returns IPRT status code.53 *54 * @param fMask The events we want to wait for, or-ed together.55 * @param cMillies How long to wait before giving up and returning56 * (VERR_TIMEOUT). Use RT_INDEFINITE_WAIT to wait until we57 * are interrupted or one of the events is signalled.58 * @param pfEvents Where to store the events signalled. Optional.59 */60 VBGLR3DECL(int) VbglR3WaitEvent(uint32_t fMask, uint32_t cMillies, uint32_t *pfEvents)61 {62 #ifndef VBOX_VBGLR3_XFREE8663 LogFlow(("VbglR3WaitEvent: fMask=0x%x, cMillies=%u, pfEvents=%p\n",64 fMask, cMillies, pfEvents));65 AssertReturn((fMask & ~VMMDEV_EVENT_VALID_EVENT_MASK) == 0, VERR_INVALID_PARAMETER);66 AssertPtrNullReturn(pfEvents, VERR_INVALID_POINTER);67 #endif68 69 VBoxGuestWaitEventInfo waitEvent;70 waitEvent.u32TimeoutIn = cMillies;71 waitEvent.u32EventMaskIn = fMask;72 waitEvent.u32Result = VBOXGUEST_WAITEVENT_ERROR;73 waitEvent.u32EventFlagsOut = 0;74 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_WAITEVENT, &waitEvent, sizeof(waitEvent));75 if (RT_SUCCESS(rc))76 {77 #if !defined(VBOX_VBGLR3_XFREE86) && !defined(RT_OS_WINDOWS)78 AssertMsg(waitEvent.u32Result == VBOXGUEST_WAITEVENT_OK, ("%d rc=%Rrc\n", waitEvent.u32Result, rc));79 #endif80 if (pfEvents)81 *pfEvents = waitEvent.u32EventFlagsOut;82 }83 84 #ifndef VBOX_VBGLR3_XFREE8685 LogFlow(("VbglR3WaitEvent: rc=%Rrc, u32EventFlagsOut=0x%x. u32Result=%d\n",86 rc, waitEvent.u32EventFlagsOut, waitEvent.u32Result));87 #endif88 return rc;89 }90 91 92 /**93 * Cause any pending WaitEvent calls (VBOXGUEST_IOCTL_WAITEVENT) to return94 * with a VERR_INTERRUPTED status.95 *96 * Can be used in combination with a termination flag variable for interrupting97 * event loops. Avoiding race conditions is the responsibility of the caller.98 *99 * @returns IPRT status code.100 */101 VBGLR3DECL(int) VbglR3InterruptEventWaits(void)102 {103 return vbglR3DoIOCtl(VBOXGUEST_IOCTL_CANCEL_ALL_WAITEVENTS, 0, 0);104 }105 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 37 165 38 … … 206 79 } 207 80 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 -
trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibStat.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, Statistics. 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 #include <VBox/log.h>38 #include <VBox/version.h>39 35 #include "VBGLR3Internal.h" 40 36 41 /** @todo Split this file up so we can drop most of the VBOX_VBGLR3_XFREE8642 * #ifdef'ing. */43 44 /**45 * Wait for the host to signal one or more events and return which.46 *47 * The events will only be delivered by the host if they have been enabled48 * previously using @a VbglR3CtlFilterMask. If one or several of the events49 * have already been signalled but not yet waited for, this function will return50 * immediately and return those events.51 *52 * @returns IPRT status code.53 *54 * @param fMask The events we want to wait for, or-ed together.55 * @param cMillies How long to wait before giving up and returning56 * (VERR_TIMEOUT). Use RT_INDEFINITE_WAIT to wait until we57 * are interrupted or one of the events is signalled.58 * @param pfEvents Where to store the events signalled. Optional.59 */60 VBGLR3DECL(int) VbglR3WaitEvent(uint32_t fMask, uint32_t cMillies, uint32_t *pfEvents)61 {62 #ifndef VBOX_VBGLR3_XFREE8663 LogFlow(("VbglR3WaitEvent: fMask=0x%x, cMillies=%u, pfEvents=%p\n",64 fMask, cMillies, pfEvents));65 AssertReturn((fMask & ~VMMDEV_EVENT_VALID_EVENT_MASK) == 0, VERR_INVALID_PARAMETER);66 AssertPtrNullReturn(pfEvents, VERR_INVALID_POINTER);67 #endif68 69 VBoxGuestWaitEventInfo waitEvent;70 waitEvent.u32TimeoutIn = cMillies;71 waitEvent.u32EventMaskIn = fMask;72 waitEvent.u32Result = VBOXGUEST_WAITEVENT_ERROR;73 waitEvent.u32EventFlagsOut = 0;74 int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_WAITEVENT, &waitEvent, sizeof(waitEvent));75 if (RT_SUCCESS(rc))76 {77 #if !defined(VBOX_VBGLR3_XFREE86) && !defined(RT_OS_WINDOWS)78 AssertMsg(waitEvent.u32Result == VBOXGUEST_WAITEVENT_OK, ("%d rc=%Rrc\n", waitEvent.u32Result, rc));79 #endif80 if (pfEvents)81 *pfEvents = waitEvent.u32EventFlagsOut;82 }83 84 #ifndef VBOX_VBGLR3_XFREE8685 LogFlow(("VbglR3WaitEvent: rc=%Rrc, u32EventFlagsOut=0x%x. u32Result=%d\n",86 rc, waitEvent.u32EventFlagsOut, waitEvent.u32Result));87 #endif88 return rc;89 }90 91 92 /**93 * Cause any pending WaitEvent calls (VBOXGUEST_IOCTL_WAITEVENT) to return94 * with a VERR_INTERRUPTED status.95 *96 * Can be used in combination with a termination flag variable for interrupting97 * event loops. Avoiding race conditions is the responsibility of the caller.98 *99 * @returns IPRT status code.100 */101 VBGLR3DECL(int) VbglR3InterruptEventWaits(void)102 {103 return vbglR3DoIOCtl(VBOXGUEST_IOCTL_CANCEL_ALL_WAITEVENTS, 0, 0);104 }105 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 37 210 38 /** … … 244 72 } 245 73 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.