VirtualBox

Ignore:
Timestamp:
Jul 22, 2008 8:12:42 AM (16 years ago)
Author:
vboxsync
Message:

Guest properties: initial commit of new interface

File:
1 moved

Legend:

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

    r10683 r10797  
    11/* $Id$ */
    22/** @file
    3  * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, information service.
     3 * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions,
     4 * guest properties.
    45 */
    56
     
    2829#include <iprt/assert.h>
    2930#include <VBox/log.h>
    30 #include <VBox/HostServices/VBoxInfoSvc.h>  /* For Save and RetrieveVideoMode */
     31#include <VBox/HostServices/GuestPropertySvc.h>
    3132
    3233#include "VBGLR3Internal.h"
    3334
    34 using namespace svcInfo;
    35 
    36 /**
    37  * Connects to the information service.
     35using namespace guestProp;
     36
     37/**
     38 * Connects to the guest property service.
    3839 *
    3940 * @returns VBox status code
     
    4142 *                          must be passed to all the other calls to the service.
    4243 */
    43 VBGLR3DECL(int) VbglR3InfoSvcConnect(uint32_t *pu32ClientId)
     44VBGLR3DECL(int) VbglR3GuestPropConnect(uint32_t *pu32ClientId)
    4445{
    4546    VBoxGuestHGCMConnectInfo Info;
     
    4748    Info.Loc.type = VMMDevHGCMLoc_LocalHost_Existing;
    4849    memset(&Info.Loc.u, 0, sizeof(Info.Loc.u));
    49     strcpy(Info.Loc.u.host.achName, "VBoxSharedInfoSvc");
     50    strcpy(Info.Loc.u.host.achName, "VBoxGuestPropSvc");
    5051    Info.u32ClientID = UINT32_MAX;  /* try make valgrid shut up. */
    5152
     
    6263
    6364/**
    64  * Disconnect from the information service.
     65 * Disconnect from the guest property service.
    6566 *
    6667 * @returns VBox status code.
    6768 * @param   u32ClientId     The client id returned by VbglR3InfoSvcConnect().
    6869 */
    69 VBGLR3DECL(int) VbglR3InfoSvcDisconnect(uint32_t u32ClientId)
     70VBGLR3DECL(int) VbglR3GuestPropDisconnect(uint32_t u32ClientId)
    7071{
    7172    VBoxGuestHGCMDisconnectInfo Info;
     
    8182
    8283/**
    83  * Write a key value.
     84 * Write a property value.
    8485 *
    8586 * @returns VBox status code.
    8687 * @param   u32ClientId     The client id returned by VbglR3InvsSvcConnect().
    87  * @param   pszKey          The key to save to.  Utf8
     88 * @param   pszName         The property to save to.  Utf8
    8889 * @param   pszValue        The value to store.  Utf8.  If this is NULL then
    89  *                          the key will be removed.
    90  */
    91 VBGLR3DECL(int) VbglR3InfoSvcWriteKey(uint32_t u32ClientId, char *pszKey, char *pszValue)
     90 *                          the property will be removed.
     91 * @param   pszFlags        The flags for the property
     92 */
     93VBGLR3DECL(int) VbglR3GuestPropWrite(uint32_t u32ClientId, char *pszName, char *pszValue, char *pszFlags)
    9294{
    9395    int rc;
     
    9597    if (pszValue != NULL)
    9698    {
    97         SetConfigKey Msg;
     99        SetProperty Msg;
    98100
    99101        Msg.hdr.result = (uint32_t)VERR_WRONG_ORDER;  /** @todo drop the cast when the result type has been fixed! */
    100102        Msg.hdr.u32ClientID = u32ClientId;
    101         Msg.hdr.u32Function = SET_CONFIG_KEY;
     103        Msg.hdr.u32Function = SET_PROP_VALUE;
    102104        Msg.hdr.cParms = 2;
    103         VbglHGCMParmPtrSet(&Msg.key, pszKey, strlen(pszKey) + 1);
     105        VbglHGCMParmPtrSet(&Msg.name, pszName, strlen(pszName) + 1);
     106        VbglHGCMParmPtrSet(&Msg.value, pszValue, strlen(pszValue) + 1);
     107        VbglHGCMParmPtrSet(&Msg.flags, pszFlags, strlen(pszFlags) + 1);
     108        rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
     109        if (RT_SUCCESS(rc))
     110            rc = Msg.hdr.result;
     111    }
     112    else
     113    {
     114        DelProperty Msg;
     115
     116        Msg.hdr.result = (uint32_t)VERR_WRONG_ORDER;  /** @todo drop the cast when the result type has been fixed! */
     117        Msg.hdr.u32ClientID = u32ClientId;
     118        Msg.hdr.u32Function = DEL_PROP;
     119        Msg.hdr.cParms = 1;
     120        VbglHGCMParmPtrSet(&Msg.name, pszName, strlen(pszName) + 1);
     121        rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
     122        if (RT_SUCCESS(rc))
     123            rc = Msg.hdr.result;
     124    }
     125    return rc;
     126}
     127
     128
     129/**
     130 * Write a property value.
     131 *
     132 * @returns VBox status code.
     133 * @param   u32ClientId     The client id returned by VbglR3InvsSvcConnect().
     134 * @param   pszName         The property to save to.  Utf8
     135 * @param   pszValue        The value to store.  Utf8.  If this is NULL then
     136 *                          the property will be removed.
     137 * @note  if the property already exists and pszValue is not NULL then the
     138 *        property's flags field will be left unchanged
     139 */
     140VBGLR3DECL(int) VbglR3GuestPropWriteValue(uint32_t u32ClientId, char *pszName, char *pszValue)
     141{
     142    int rc;
     143
     144    if (pszValue != NULL)
     145    {
     146        SetPropertyValue Msg;
     147
     148        Msg.hdr.result = (uint32_t)VERR_WRONG_ORDER;  /** @todo drop the cast when the result type has been fixed! */
     149        Msg.hdr.u32ClientID = u32ClientId;
     150        Msg.hdr.u32Function = SET_PROP_VALUE;
     151        Msg.hdr.cParms = 2;
     152        VbglHGCMParmPtrSet(&Msg.name, pszName, strlen(pszName) + 1);
    104153        VbglHGCMParmPtrSet(&Msg.value, pszValue, strlen(pszValue) + 1);
    105154        rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
     
    109158    else
    110159    {
    111         DelConfigKey Msg;
     160        DelProperty Msg;
    112161
    113162        Msg.hdr.result = (uint32_t)VERR_WRONG_ORDER;  /** @todo drop the cast when the result type has been fixed! */
    114163        Msg.hdr.u32ClientID = u32ClientId;
    115         Msg.hdr.u32Function = DEL_CONFIG_KEY;
     164        Msg.hdr.u32Function = DEL_PROP;
    116165        Msg.hdr.cParms = 1;
    117         VbglHGCMParmPtrSet(&Msg.key, pszKey, strlen(pszKey) + 1);
     166        VbglHGCMParmPtrSet(&Msg.name, pszName, strlen(pszName) + 1);
    118167        rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
    119168        if (RT_SUCCESS(rc))
     
    125174
    126175/**
    127  * Retrieve a key value.
    128  *
    129  * @returns VBox status code.
    130  * @retval  VINF_SUCCESS on success, pszValue and pcbActual containing valid data.
    131  * @retval  VERR_BUFFER_OVERFLOW if the buffer is too small, pcbActual will contain
    132  *          the require buffer size. Note race condition here when retrying wrt
    133  *          someone updating it.
     176 * Retrieve a property.
     177 *
     178 * @returns VBox status code.
     179 * @retval  VINF_SUCCESS on success, pszValue, pu64Timestamp and pszFlags
     180 *          containing valid data.
     181 * @retval  VERR_BUFFER_OVERFLOW if the scratch buffer @a pcBuf is not large
     182 *          enough.  In this case the size needed will be placed in
     183 *          @a pcbBufActual if it is not NULL.
    134184 * @retval  VERR_NOT_FOUND if the key wasn't found.
    135185 *
    136186 * @param   u32ClientId     The client id returned by VbglR3ClipboardConnect().
    137  * @param   pszKey          The key to read.  Utf8
    138  * @param   pszValue        Where to store the value retrieved.  Utf8.
    139  * @param   cbValue         The size of the buffer pszValue points to.
    140  * @param   pcbActual       Where to store the required buffer size if cbValue
    141  *                          is too small.  On success this contains the
    142  *                          actual size of the value retrieved.  Optional.
    143  */
    144 VBGLR3DECL(int) VbglR3InfoSvcReadKey(uint32_t u32ClientId, char *pszKey,
    145                                      char *pszValue, uint32_t cbValue, uint32_t *pcbActual)
    146 {
    147     GetConfigKey Msg;
     187 * @param   pszName         The value to read.  Utf8
     188 * @param   pcBuf           A scratch buffer to store the data retrieved into.
     189 *                          The returned data is only valid for it's lifetime.
     190 * @param   cbBuf           The size of @a pcBuf
     191 * @param   pszValue        Where to store the pointer to the value retrieved.
     192 * @param   pu64Timestamp   Where to store the timestamp.  Optional.
     193 * @param   pszFlags        Where to store the pointer to the flags.  Optional.
     194 * @param   pcbBufActual    If @a pcBuf is not large enough, the size needed.
     195 *                          Optional.
     196 */
     197VBGLR3DECL(int) VbglR3GuestPropRead(uint32_t u32ClientId, const char *pszName,
     198                                    void *pvBuf, uint32_t cbBuf,
     199                                    char **ppszValue, uint64_t *pu64Timestamp,
     200                                    char **ppszFlags,
     201                                    uint32_t *pcbBufActual)
     202{
     203    GetProperty Msg;
    148204
    149205    Msg.hdr.result = (uint32_t)VERR_WRONG_ORDER;  /** @todo drop the cast when the result type has been fixed! */
    150206    Msg.hdr.u32ClientID = u32ClientId;
    151     Msg.hdr.u32Function = GET_CONFIG_KEY;
    152     Msg.hdr.cParms = 3;
    153     VbglHGCMParmPtrSet(&Msg.key, pszKey, strlen(pszKey) + 1);
    154     VbglHGCMParmPtrSet(&Msg.value, pszValue, cbValue);
     207    Msg.hdr.u32Function = GET_PROP;
     208    Msg.hdr.cParms = 4;
     209    VbglHGCMParmPtrSet(&Msg.name, const_cast<char *>(pszName),
     210                       strlen(pszName) + 1);
     211    VbglHGCMParmPtrSet(&Msg.buffer, pvBuf, cbBuf);
     212    VbglHGCMParmUInt64Set(&Msg.timestamp, 0);
    155213    VbglHGCMParmUInt32Set(&Msg.size, 0);
    156214
     
    158216    if (RT_SUCCESS(rc))
    159217        rc = Msg.hdr.result;
    160     uint32_t cbActual;
    161     if (RT_SUCCESS(rc) || (VERR_BUFFER_OVERFLOW == rc))
    162     {
    163         int rc2 = VbglHGCMParmUInt32Get(&Msg.size, &cbActual);
    164         if (RT_SUCCESS(rc2))
     218    if ((VERR_BUFFER_OVERFLOW == rc) && (pcbBufActual != NULL))
     219    {
     220        int rc2 = VbglHGCMParmUInt32Get(&Msg.size, pcbBufActual);
     221        if (!RT_SUCCESS(rc2))
     222            rc = rc2;
     223    }
     224    if (RT_SUCCESS(rc) && (pu64Timestamp != NULL))
     225        rc = VbglHGCMParmUInt64Get(&Msg.timestamp, pu64Timestamp);
     226    if (RT_SUCCESS(rc))
     227        *ppszValue = reinterpret_cast<char *>(pvBuf);
     228    if (RT_SUCCESS(rc) && (ppszFlags != NULL))
     229    {
     230        bool found = false;
     231        size_t i = 0;
     232        char *pcBuf = reinterpret_cast<char *>(pvBuf);
     233        for (; i < cbBuf && !found; ++i)
     234            if (0 == pcBuf[i])
     235                found = true;
     236        if (!found)
     237            /* To my mind this is an internal error, but whatever */
     238            rc = VERR_TOO_MUCH_DATA;
     239        else
     240            *ppszFlags = pcBuf + i;
     241    }
     242    return rc;
     243}
     244
     245
     246/**
     247 * Retrieve a property value, allocating space for it.
     248 *
     249 * @returns VBox status code.
     250 * @retval  VINF_SUCCESS on success, pszValue containing valid data.
     251 * @retval  VERR_NOT_FOUND if the key wasn't found.
     252 *
     253 * @param   u32ClientId     The client id returned by VbglR3ClipboardConnect().
     254 * @param   pszName         The value to read.  Utf8
     255 * @param   ppszValue       Where to store the pointer to the value returned.
     256 */
     257VBGLR3DECL(int) VbglR3GuestPropReadValueAlloc(uint32_t u32ClientId,
     258                                              const char *pszName,
     259                                              char **ppszValue)
     260{
     261    int rc = VINF_SUCCESS;
     262    uint32_t cchBuf = 1024;
     263    void *pvBuf = RTMemAlloc(cchBuf);
     264    char *pszValue = NULL;
     265    if (NULL == pvBuf)
     266        rc = VERR_NO_MEMORY;
     267    if (RT_SUCCESS(rc))
     268    {
     269        rc = VbglR3GuestPropRead(u32ClientId, pszName, pvBuf, cchBuf,
     270                                 &pszValue, NULL, NULL, &cchBuf);
     271        if (VERR_BUFFER_OVERFLOW == rc)
    165272        {
    166             if (pcbActual != NULL)
    167                 *pcbActual = cbActual;
     273            /** @todo how should we handle the race condition here? */
     274            pvBuf = RTMemRealloc(pvBuf, cchBuf);
     275            if (pvBuf != NULL)
     276                rc = VbglR3GuestPropRead(u32ClientId, pszName, pvBuf, cchBuf,
     277                                         &pszValue, NULL, NULL, NULL);
     278            else
     279                rc = VERR_NO_MEMORY;
     280            if (VERR_BUFFER_OVERFLOW == rc)
     281                /* VERR_BUFFER_OVERFLOW has a different meaning here as a
     282                 * return code */
     283                rc = VERR_TOO_MUCH_DATA;
    168284        }
    169         else
    170             rc = rc2;
    171     }
    172     return rc;
    173 }
     285    }
     286    if (RT_SUCCESS(rc))
     287        *ppszValue = pszValue;
     288    return rc;
     289}
     290
     291/**
     292 * Free the memory used by VbglR3GuestPropReadValueAlloc for returning a
     293 * value.
     294 *
     295 * @param pszValue   the memory to be freed.  NULL pointers will be ignored.
     296 */
     297VBGLR3DECL(void) VbglR3GuestPropReadValueFree(char *pszValue)
     298{
     299    RTMemFree(pszValue);
     300}
     301
     302
     303/**
     304 * Retrieve a property value, using a user-provided buffer to store it.
     305 *
     306 * @returns VBox status code.
     307 * @retval  VINF_SUCCESS on success, pszValue containing valid data.
     308 * @retval  VERR_BUFFER_OVERFLOW and the size needed in pcchValueActual if the
     309 *          buffer provided was too small
     310 * @retval  VERR_NOT_FOUND if the key wasn't found.
     311 *
     312 * @note    There is a race here between obtaining the size of the buffer
     313 *          needed to hold the value and the value being updated.
     314 *
     315 * @param   u32ClientId     The client id returned by VbglR3ClipboardConnect().
     316 * @param   pszName         The value to read.  Utf8
     317 * @param   pszValue        Where to store the value retrieved.
     318 * @param   cchValue        The size of the buffer pointed to by @a pszValue
     319 * @param   pcchValueActual Where to store the size of the buffer needed if
     320 *                          the buffer supplied is too small.  Optional.
     321 */
     322VBGLR3DECL(int) VbglR3GuestPropReadValue(uint32_t u32ClientId, const char *pszName,
     323                                         char *pszValue, uint32_t cchValue,
     324                                         uint32_t *pcchValueActual)
     325{
     326    char *pcBuf = NULL;
     327    int rc = VbglR3GuestPropReadValueAlloc(u32ClientId, pszName, &pcBuf);
     328    if (RT_SUCCESS(rc))
     329    {
     330        uint32_t cchValueActual = strlen(pcBuf) + 1;
     331        if (cchValueActual > cchValue)
     332        {
     333            if (pcchValueActual != NULL)
     334                *pcchValueActual = cchValueActual;
     335            rc = VERR_BUFFER_OVERFLOW;
     336        }
     337        if (RT_SUCCESS(rc))
     338            strcpy(pszValue, pcBuf);
     339    }
     340    VbglR3GuestPropReadValueFree(pcBuf);
     341    return rc;
     342}
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