VirtualBox

Ignore:
Timestamp:
Mar 5, 2010 1:05:51 PM (15 years ago)
Author:
vboxsync
Message:

VBoxGuestLib: split up VBoxGuestR3LibMisc.cpp.

File:
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibEvent.cpp

    r27080 r27083  
    11/* $Id$ */
    22/** @file
    3  * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, Misc.
     3 * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, Events.
    44 */
    55
    66/*
    7  * Copyright (C) 2007 Sun Microsystems, Inc.
     7 * Copyright (C) 2007-2010 Sun Microsystems, Inc.
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3333*   Header Files                                                               *
    3434*******************************************************************************/
    35 #include <iprt/mem.h>
    36 #include <iprt/string.h>
    3735#include <VBox/log.h>
    38 #include <VBox/version.h>
    3936#include "VBGLR3Internal.h"
    4037
    41 /** @todo Split this file up so we can drop most of the VBOX_VBGLR3_XFREE86
    42  *        #ifdef'ing. */
    4338
    4439/**
     
    10499}
    105100
    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 at
    117  *          one time. It should probably be rewritten to use pass a pointer
    118  *          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_WINDOWS
    132     /*
    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 #else
    149     /*
    150      * *BSD does not accept more than 4KB per ioctl request, while
    151      * Linux can't express sizes above 8KB, so, split it up into 2KB chunks.
    152      */
    153 # define STEP 2048
    154     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 STEP
    161     return rc;
    162 #endif
    163 }
    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     else
    203         LogRel(("Failed to change guest capabilities: or mask 0x%x, not mask 0x%x.  rc=%Rrc.\n", fOr, fNot, rc));
    204 #endif
    205     return rc;
    206 }
    207 
    208 #ifndef VBOX_VBGLR3_XFREE86
    209 
    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_WINDOWS
    317 /**
    318  * Looks up the storage path handle (registry).
    319  *
    320  * @returns IPRT status value
    321  * @param   hKey        Receives pointer of allocated version string. NULL is
    322  *                      accepted. The returned pointer must be closed by
    323  *                      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_AMD64
    335     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 # endif
    341 
    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_AMD64
    347         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 # endif
    353     }
    354     return RTErrConvertFromWin32(r);
    355 }
    356 
    357 
    358 /**
    359  * Closes the storage path handle (registry).
    360  *
    361  * @returns IPRT status value
    362  * @param   hKey        Handle to close, retrieved by
    363  *                      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 value
    376  * @param   ppszVer     Receives pointer of allocated version string. NULL is
    377  *                      accepted. The returned pointer must be freed using
    378  *                      RTStrFree().
    379  * @param   ppszRev     Receives pointer of allocated revision string. NULL is
    380  *                      accepted. The returned pointer must be freed using
    381  *                      RTStrFree().
    382  */
    383 VBGLR3DECL(int) VbglR3GetAdditionsVersion(char **ppszVer, char **ppszRev)
    384 {
    385 #ifdef RT_OS_WINDOWS
    386     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                     else
    406                         rc = VERR_INVALID_PARAMETER;
    407                 }
    408                 else
    409                 {
    410                     rc = RTErrConvertFromWin32(l);
    411                 }
    412                 RTMemFree(pszTmp);
    413             }
    414             else
    415                 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                     else
    430                         rc = VERR_INVALID_PARAMETER;
    431                 }
    432                 else
    433                 {
    434                     rc = RTErrConvertFromWin32(l);
    435                 }
    436                 RTMemFree(pszTmp);
    437             }
    438             else
    439                 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     else
    450     {
    451         /*
    452          * No registry entries found, return the version string compiled
    453          * 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 value
    472  * @param   ppszPath    Receives pointer of allocated installation path string.
    473  *                      The returned pointer must be freed using
    474  *                      RTStrFree().
    475  */
    476 VBGLR3DECL(int) VbglR3GetAdditionsInstallationPath(char **ppszPath)
    477 {
    478     int rc;
    479 #ifdef RT_OS_WINDOWS
    480     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             else
    496             {
    497                 if (dwType == REG_SZ)
    498                     rc = RTStrDupEx(ppszPath, pszTmp);
    499                 else
    500                     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         else
    512             rc = VERR_NO_MEMORY;
    513         rc = vbglR3CloseAdditionsWinStoragePath(hKey);
    514     }
    515 #else
    516     /** @todo implement me */
    517     rc = VERR_NOT_IMPLEMENTED;
    518 #endif
    519     return rc;
    520 }
    521 
    522 #endif /* !VBOX_VBGLR3_XFREE86 */
    523 
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette