VirtualBox

Ignore:
Timestamp:
Nov 14, 2008 1:25:15 PM (16 years ago)
Author:
vboxsync
Message:

Additions/Guest Library: add an HGCM call with timeout

File:
1 edited

Legend:

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

    r13355 r14207  
    253253 * @retval  VERR_NOT_FOUND if the key wasn't found.
    254254 *
    255  * @param   u32ClientId     The client id returned by VbglR3ClipboardConnect().
     255 * @param   u32ClientId     The client id returned by VbglR3GuestPropConnect().
    256256 * @param   pszName         The value to read.  Utf8
    257257 * @param   pvBuf           A scratch buffer to store the data retrieved into.
     
    349349 *          property value.
    350350 *
    351  * @param   u32ClientId     The client id returned by VbglR3ClipboardConnect().
     351 * @param   u32ClientId     The client id returned by VbglR3GuestPropConnect().
    352352 * @param   pszName         The value to read. Must be valid UTF-8.
    353353 * @param   ppszValue       Where to store the pointer to the value returned.
     
    431431 *          needed to hold the value and the value being updated.
    432432 *
    433  * @param   u32ClientId     The client id returned by VbglR3ClipboardConnect().
     433 * @param   u32ClientId     The client id returned by VbglR3GuestPropConnect().
    434434 * @param   pszName         The value to read.  Utf8
    435435 * @param   pszValue        Where to store the value retrieved.
     
    785785}
    786786
     787
     788/**
     789 * Wait for notification of changes to a guest property.  If this is called in
     790 * a loop, the timestamp of the last notification seen can be passed as a
     791 * parameter to be sure that no notifications are missed.
     792 *
     793 * @returns VBox status code.
     794 * @retval  VINF_SUCCESS on success, @a ppszName, @a ppszValue,
     795 *          @a pu64Timestamp and @a ppszFlags containing valid data.
     796 * @retval  VINF_NOT_FOUND if no previous notification could be found with the
     797 *          timestamp supplied.  This will normally mean that a large number
     798 *          of notifications occurred in between.
     799 * @retval  VERR_BUFFER_OVERFLOW if the scratch buffer @a pvBuf is not large
     800 *          enough.  In this case the size needed will be placed in
     801 *          @a pcbBufActual if it is not NULL.
     802 * @retval  VERR_TIMEOUT if a timeout occurred before a notification was seen.
     803 *
     804 * @param   u32ClientId     The client id returned by VbglR3GuestPropConnect().
     805 * @param   pszPatterns     The patterns that the property names must matchfor
     806 *                          the change to be reported.
     807 * @param   pvBuf           A scratch buffer to store the data retrieved into.
     808 *                          The returned data is only valid for it's lifetime.
     809 *                          @a ppszValue will point to the start of this buffer.
     810 * @param   cbBuf           The size of @a pvBuf
     811 * @param   u64Timestamp    The timestamp of the last event seen.  Pass zero
     812 *                          to wait for the next event.
     813 * @param   u32Timeout      Timeout in milliseconds.  Use RT_INDEFINITE_WAIT
     814 *                          to wait indefinitely.
     815 * @param   ppszName        Where to store the pointer to the name retrieved.
     816 *                          Optional.
     817 * @param   ppszValue       Where to store the pointer to the value retrieved.
     818 *                          Optional.
     819 * @param   pu64Timestamp   Where to store the timestamp.  Optional.
     820 * @param   ppszFlags       Where to store the pointer to the flags.  Optional.
     821 * @param   pcbBufActual    If @a pcBuf is not large enough, the size needed.
     822 *                          Optional.
     823 */
     824VBGLR3DECL(int) VbglR3GuestPropWait(uint32_t u32ClientId,
     825                                    const char *pszPatterns,
     826                                    void *pvBuf, uint32_t cbBuf,
     827                                    uint64_t u64Timestamp, uint32_t u32Timeout,
     828                                    char ** ppszName, char **ppszValue,
     829                                    uint64_t *pu64Timestamp, char **ppszFlags,
     830                                    uint32_t *pcbBufActual)
     831{
     832    /*
     833     * Create the GET_NOTIFICATION message and call the host.
     834     */
     835    GetNotification Msg;
     836
     837    Msg.hdr.u32Timeout = u32Timeout;
     838    Msg.hdr.info.result = (uint32_t)VERR_WRONG_ORDER;  /** @todo drop the cast when the result type has been fixed! */
     839    Msg.hdr.info.u32ClientID = u32ClientId;
     840    Msg.hdr.info.u32Function = GET_NOTIFICATION;
     841    Msg.hdr.info.cParms = 4;
     842    Msg.patterns.SetPtr(const_cast<char *>(pszPatterns),
     843                        strlen(pszPatterns) + 1);
     844    Msg.buffer.SetPtr(pvBuf, cbBuf);
     845    Msg.timestamp.SetUInt64(u64Timestamp);
     846    Msg.size.SetUInt32(0);
     847
     848    int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL_TIMEOUT(sizeof(Msg)), &Msg, sizeof(Msg));
     849    if (RT_SUCCESS(rc))
     850        rc = Msg.hdr.info.result;
     851
     852    /*
     853     * The cbBufActual parameter is also returned on overflow so the caller can
     854     * adjust their buffer.
     855     */
     856    if (    rc == VERR_BUFFER_OVERFLOW
     857        ||  pcbBufActual != NULL)
     858    {
     859        int rc2 = Msg.size.GetUInt32(pcbBufActual);
     860        AssertRCReturn(rc2, RT_FAILURE(rc) ? rc : rc2);
     861    }
     862    if (RT_FAILURE(rc))
     863        return rc;
     864
     865    /*
     866     * Buffer layout: Name\0Value\0Flags\0.
     867     *
     868     * If the caller cares about any of these strings, make sure things are
     869     * propertly terminated (paranoia).
     870     */
     871    if (    RT_SUCCESS(rc)
     872        &&  (ppszName != NULL || ppszValue != NULL || ppszFlags != NULL))
     873    {
     874        /* Validate / skip 'Name'. */
     875        char *pszValue = (char *)memchr(pvBuf, '\0', cbBuf) + 1;
     876        AssertPtrReturn(pszValue, VERR_TOO_MUCH_DATA);
     877        if (ppszName)
     878            *ppszName = (char *)pvBuf;
     879
     880        /* Validate / skip 'Value'. */
     881        char *pszFlags = (char *)memchr(pszValue, '\0',
     882                                        cbBuf - (pszValue - (char *)pvBuf)) + 1;
     883        AssertPtrReturn(pszFlags, VERR_TOO_MUCH_DATA);
     884        if (ppszValue)
     885            *ppszValue = pszValue;
     886
     887        if (ppszFlags)
     888        {
     889            /* Validate 'Flags'. */
     890            void *pvEos = memchr(pszFlags, '\0', cbBuf - (pszFlags - (char *)pvBuf));
     891            AssertPtrReturn(pvEos, VERR_TOO_MUCH_DATA);
     892            *ppszFlags = pszFlags;
     893        }
     894    }
     895
     896    /* And the timestamp, if requested. */
     897    if (pu64Timestamp != NULL)
     898    {
     899        rc = Msg.timestamp.GetUInt64(pu64Timestamp);
     900        AssertRCReturn(rc, rc);
     901    }
     902
     903    return VINF_SUCCESS;
     904}
     905
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