VBoxGuestR3LibGuestProp.cpp revision dd6994667c4e2ebd8f1f01a1d29f5c0491f82603
d6aa6429f99fb7648883eb612f8a52b9aaf3bff4vboxsync * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, guest properties.
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync * Copyright (C) 2007-2013 Oracle Corporation
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * available from http://www.virtualbox.org. This file is free software;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * you can redistribute it and/or modify it under the terms of the GNU
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * General Public License (GPL) as published by the Free Software
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
aba0e602e244ae7c4f11b50fc6d2440f5a762038vboxsync * The contents of this file may alternatively be used under the terms
aba0e602e244ae7c4f11b50fc6d2440f5a762038vboxsync * of the Common Development and Distribution License Version 1.0
aba0e602e244ae7c4f11b50fc6d2440f5a762038vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
aba0e602e244ae7c4f11b50fc6d2440f5a762038vboxsync * VirtualBox OSE distribution, in which case the provisions of the
aba0e602e244ae7c4f11b50fc6d2440f5a762038vboxsync * CDDL are applicable instead of those of the GPL.
aba0e602e244ae7c4f11b50fc6d2440f5a762038vboxsync * You may elect to license modified versions of this file under the
aba0e602e244ae7c4f11b50fc6d2440f5a762038vboxsync * terms and conditions of either the GPL or the CDDL or both.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync/*******************************************************************************
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync* Header Files *
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync*******************************************************************************/
208aaecb51db539a2f7f3d25f38dd2efd0f014a3vboxsync/* Rather than try to resolve all the header file conflicts, I will just
208aaecb51db539a2f7f3d25f38dd2efd0f014a3vboxsync prototype what we need here. */
208aaecb51db539a2f7f3d25f38dd2efd0f014a3vboxsyncextern "C" void* xf86memchr(const void*,int,xf86size_t);
ccaa0be74d0fa1390e58e017737204eeb8980d23vboxsyncextern "C" void* xf86memset(const void*,int,xf86size_t);
a34996f4849a881e4112ba993984dcd2388b8bf2vboxsyncDECLINLINE(char const *) RTStrEnd(char const *pszString, size_t cchMax)
b0f98e7a2b3f68fcd23e6bb8d83ff0333e6dda3evboxsync /* Avoid potential issues with memchr seen in glibc.
b0f98e7a2b3f68fcd23e6bb8d83ff0333e6dda3evboxsync * See sysdeps/x86_64/memchr.S in glibc versions older than 2.11 */
a34996f4849a881e4112ba993984dcd2388b8bf2vboxsync char const *pszRet = (char const *)memchr(pszString, '\0', RTSTR_MEMCHR_MAX);
a34996f4849a881e4112ba993984dcd2388b8bf2vboxsync return (char const *)memchr(pszString, '\0', cchMax);
a34996f4849a881e4112ba993984dcd2388b8bf2vboxsyncDECLINLINE(char *) RTStrEnd(char *pszString, size_t cchMax)
b0f98e7a2b3f68fcd23e6bb8d83ff0333e6dda3evboxsync /* Avoid potential issues with memchr seen in glibc.
b0f98e7a2b3f68fcd23e6bb8d83ff0333e6dda3evboxsync * See sysdeps/x86_64/memchr.S in glibc versions older than 2.11 */
a34996f4849a881e4112ba993984dcd2388b8bf2vboxsync char *pszRet = (char *)memchr(pszString, '\0', RTSTR_MEMCHR_MAX);
208aaecb51db539a2f7f3d25f38dd2efd0f014a3vboxsync#endif /* VBOX_VBGLR3_XFREE86 */
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync/*******************************************************************************
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync* Structures and Typedefs *
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync*******************************************************************************/
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * Structure containing information needed to enumerate through guest
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * properties.
d6aa6429f99fb7648883eb612f8a52b9aaf3bff4vboxsync * @remarks typedef in VBoxGuestLib.h.
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync /** @todo add a magic and validate the handle. */
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync /** The buffer containing the raw enumeration data */
d44cb80e1d772854c10ef9ae03daba8dcf61d389vboxsync /** The end of the buffer */
d44cb80e1d772854c10ef9ae03daba8dcf61d389vboxsync /** Pointer to the next entry to enumerate inside the buffer */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncusing namespace guestProp;
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * Connects to the guest property service.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * @returns VBox status code
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * @param pu32ClientId Where to put the client id on success. The client id
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * must be passed to all the other calls to the service.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncVBGLR3DECL(int) VbglR3GuestPropConnect(uint32_t *pu32ClientId)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync strcpy(Info.Loc.u.host.achName, "VBoxGuestPropSvc");
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync Info.u32ClientID = UINT32_MAX; /* try make valgrind shut up. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CONNECT, &Info, sizeof(Info));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * Disconnect from the guest property service.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * @returns VBox status code.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * @param u32ClientId The client id returned by VbglR3InfoSvcConnect().
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncVBGLR3DECL(int) VbglR3GuestPropDisconnect(uint32_t u32ClientId)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_DISCONNECT, &Info, sizeof(Info));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * Write a property value.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * @returns VBox status code.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * @param u32ClientId The client id returned by VbglR3InvsSvcConnect().
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * @param pszName The property to save to. Utf8
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * @param pszValue The value to store. Utf8. If this is NULL then
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * the property will be removed.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * @param pszFlags The flags for the property
e7e60b177e688900656c04404c5123f1dfa1d02cvboxsyncVBGLR3DECL(int) VbglR3GuestPropWrite(uint32_t u32ClientId, const char *pszName, const char *pszValue, const char *pszFlags)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * Write a property value.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * @returns VBox status code.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * @param u32ClientId The client id returned by VbglR3InvsSvcConnect().
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync * @param pszName The property to save to. Must be valid UTF-8.
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync * @param pszValue The value to store. Must be valid UTF-8.
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync * If this is NULL then the property will be removed.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * @note if the property already exists and pszValue is not NULL then the
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * property's flags field will be left unchanged
e7e60b177e688900656c04404c5123f1dfa1d02cvboxsyncVBGLR3DECL(int) VbglR3GuestPropWriteValue(uint32_t u32ClientId, const char *pszName, const char *pszValue)
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
9f9eff04f209bd905529ee3b76076e55568db917vboxsync * Write a property value where the value is formatted in RTStrPrintfV fashion.
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync * @returns The same as VbglR3GuestPropWriteValue with the addition of VERR_NO_STR_MEMORY.
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync * @param u32ClientId The client ID returned by VbglR3InvsSvcConnect().
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync * @param pszName The property to save to. Must be valid UTF-8.
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync * @param pszValueFormat The value format. This must be valid UTF-8 when fully formatted.
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync * @param va The format arguments.
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsyncVBGLR3DECL(int) VbglR3GuestPropWriteValueV(uint32_t u32ClientId, const char *pszName, const char *pszValueFormat, va_list va)
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync * Format the value and pass it on to the setter.
33f11b53cd8c54c594fb6117dc4413e05bd7a3cdvboxsync if (RTStrAPrintfV(&pszValue, pszValueFormat, va) >= 0)
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync rc = VbglR3GuestPropWriteValue(u32ClientId, pszName, pszValue);
9f9eff04f209bd905529ee3b76076e55568db917vboxsync * Write a property value where the value is formatted in RTStrPrintf fashion.
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync * @returns The same as VbglR3GuestPropWriteValue with the addition of VERR_NO_STR_MEMORY.
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync * @param u32ClientId The client ID returned by VbglR3InvsSvcConnect().
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync * @param pszName The property to save to. Must be valid UTF-8.
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync * @param pszValueFormat The value format. This must be valid UTF-8 when fully formatted.
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync * @param ... The format arguments.
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsyncVBGLR3DECL(int) VbglR3GuestPropWriteValueF(uint32_t u32ClientId, const char *pszName, const char *pszValueFormat, ...)
a2d53f020c57ede4a469a06d8ef8f735c7a46596vboxsync int rc = VbglR3GuestPropWriteValueV(u32ClientId, pszName, pszValueFormat, va);
208aaecb51db539a2f7f3d25f38dd2efd0f014a3vboxsync#endif /* VBOX_VBGLR3_XFREE86 */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * Retrieve a property.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * @returns VBox status code.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * @retval VINF_SUCCESS on success, pszValue, pu64Timestamp and pszFlags
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * containing valid data.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * @retval VERR_BUFFER_OVERFLOW if the scratch buffer @a pcBuf is not large
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * enough. In this case the size needed will be placed in
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * @a pcbBufActual if it is not NULL.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * @retval VERR_NOT_FOUND if the key wasn't found.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * @param u32ClientId The client id returned by VbglR3GuestPropConnect().
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * @param pszName The value to read. Utf8
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * @param pvBuf A scratch buffer to store the data retrieved into.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * The returned data is only valid for it's lifetime.
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * @a ppszValue will point to the start of this buffer.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * @param cbBuf The size of @a pcBuf
397a09203bcbe5348def6093e6c855c43d4ad98fvboxsync * @param ppszValue Where to store the pointer to the value retrieved.
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * Optional.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * @param pu64Timestamp Where to store the timestamp. Optional.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * @param pszFlags Where to store the pointer to the flags. Optional.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * @param pcbBufActual If @a pcBuf is not large enough, the size needed.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * Optional.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncVBGLR3DECL(int) VbglR3GuestPropRead(uint32_t u32ClientId, const char *pszName,
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * Create the GET_PROP message and call the host.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * The cbBufActual parameter is also returned on overflow so the call can
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * adjust his/her buffer.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync int rc2 = VbglHGCMParmUInt32Get(&Msg.size, pcbBufActual);
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * Buffer layout: Value\0Flags\0.
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * If the caller cares about any of these strings, make sure things are
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync * properly terminated (paranoia).
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync /* Validate / skip 'Name'. */
e86538a7bc028e823f16f8982e90f0c7ef5d4ecevboxsync char *pszFlags = RTStrEnd((char *)pvBuf, cbBuf) + 1;
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync /* Validate 'Flags'. */
e86538a7bc028e823f16f8982e90f0c7ef5d4ecevboxsync char *pszEos = RTStrEnd(pszFlags, cbBuf - (pszFlags - (char *)pvBuf));
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync /* And the timestamp, if requested. */
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync rc = VbglHGCMParmUInt64Get(&Msg.timestamp, pu64Timestamp);
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * Retrieve a property value, allocating space for it.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * @returns VBox status code.
e7e60b177e688900656c04404c5123f1dfa1d02cvboxsync * @retval VINF_SUCCESS on success, *ppszValue containing valid data.
243041cd7eae9f34b08e7340533b2a88218ee57evboxsync * @retval VERR_NOT_FOUND if the key wasn't found.
e7e60b177e688900656c04404c5123f1dfa1d02cvboxsync * @retval VERR_TOO_MUCH_DATA if we were unable to determine the right size
e7e60b177e688900656c04404c5123f1dfa1d02cvboxsync * to allocate for the buffer. This can happen as the result of a
e7e60b177e688900656c04404c5123f1dfa1d02cvboxsync * race between our allocating space and the host changing the
e7e60b177e688900656c04404c5123f1dfa1d02cvboxsync * property value.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * @param u32ClientId The client id returned by VbglR3GuestPropConnect().
243041cd7eae9f34b08e7340533b2a88218ee57evboxsync * @param pszName The value to read. Must be valid UTF-8.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * @param ppszValue Where to store the pointer to the value returned.
243041cd7eae9f34b08e7340533b2a88218ee57evboxsync * This is always set to NULL or to the result, even
243041cd7eae9f34b08e7340533b2a88218ee57evboxsync * on failure.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncVBGLR3DECL(int) VbglR3GuestPropReadValueAlloc(uint32_t u32ClientId,
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync const char *pszName,
243041cd7eae9f34b08e7340533b2a88218ee57evboxsync * Quick input validation.
243041cd7eae9f34b08e7340533b2a88218ee57evboxsync * There is a race here between our reading the property size and the
e61cd03db2217b7ec7467065af02d7ea7549149evboxsync * host changing the value before we read it. Try up to ten times and
243041cd7eae9f34b08e7340533b2a88218ee57evboxsync * report the problem if that fails.
243041cd7eae9f34b08e7340533b2a88218ee57evboxsync for (unsigned i = 0; i < 10 && rc == VERR_BUFFER_OVERFLOW; ++i)
243041cd7eae9f34b08e7340533b2a88218ee57evboxsync /* We leave a bit of space here in case the maximum value is raised. */
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync rc = VbglR3GuestPropRead(u32ClientId, pszName, pvBuf, cchBuf,
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync /* VERR_BUFFER_OVERFLOW has a different meaning here as a
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync * return code, but we need to report the race. */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * Free the memory used by VbglR3GuestPropReadValueAlloc for returning a
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * @param pszValue the memory to be freed. NULL pointers will be ignored.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncVBGLR3DECL(void) VbglR3GuestPropReadValueFree(char *pszValue)
208aaecb51db539a2f7f3d25f38dd2efd0f014a3vboxsync#endif /* VBOX_VBGLR3_XFREE86 */
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * Retrieve a property value, using a user-provided buffer to store it.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * @returns VBox status code.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * @retval VINF_SUCCESS on success, pszValue containing valid data.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * @retval VERR_BUFFER_OVERFLOW and the size needed in pcchValueActual if the
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * buffer provided was too small
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * @retval VERR_NOT_FOUND if the key wasn't found.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * @note There is a race here between obtaining the size of the buffer
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * needed to hold the value and the value being updated.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * @param u32ClientId The client id returned by VbglR3GuestPropConnect().
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * @param pszName The value to read. Utf8
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * @param pszValue Where to store the value retrieved.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * @param cchValue The size of the buffer pointed to by @a pszValue
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * @param pcchValueActual Where to store the size of the buffer needed if
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsync * the buffer supplied is too small. Optional.
3c3a5ab35783f4d31cb5d3a15db9daadeb804daavboxsyncVBGLR3DECL(int) VbglR3GuestPropReadValue(uint32_t u32ClientId, const char *pszName,
208aaecb51db539a2f7f3d25f38dd2efd0f014a3vboxsync int rc = VbglR3GuestPropRead(u32ClientId, pszName, pvBuf, cchValue,
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * Raw API for enumerating guest properties which match a given pattern.
0c436e66dac8edc81d43b54cd878ed239a63574bvboxsync * @returns VBox status code.
0c436e66dac8edc81d43b54cd878ed239a63574bvboxsync * @retval VINF_SUCCESS on success and pcBuf points to a packed array
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * of the form <name>, <value>, <timestamp string>, <flags>,
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * terminated by four empty strings. pcbBufActual will contain the
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * total size of the array.
0c436e66dac8edc81d43b54cd878ed239a63574bvboxsync * @retval VERR_BUFFER_OVERFLOW if the buffer provided was too small. In
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * this case pcbBufActual will contain the size of the buffer needed.
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * @returns IPRT error code in other cases, and pchBufActual is undefined.
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * @param u32ClientId The client ID returned by VbglR3GuestPropConnect
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * @param paszPatterns A packed array of zero terminated strings, terminated
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * by an empty string.
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * @param pcBuf The buffer to store the results to.
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * @param cbBuf The size of the buffer
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * @param pcbBufActual Where to store the size of the returned data on
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * success or the buffer size needed if @a pcBuf is too
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsyncVBGLR3DECL(int) VbglR3GuestPropEnumRaw(uint32_t u32ClientId,
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync /* Get the length of the patterns array... */
bf4de0c2965291e927412f708c6c27eeeb5825d4vboxsync for (size_t cchCurrent = strlen(pszzPatterns); cchCurrent != 0;
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync /* ...including the terminator. */
bf4de0c2965291e927412f708c6c27eeeb5825d4vboxsync VbglHGCMParmPtrSet(&Msg.patterns, (char *)pszzPatterns, (uint32_t)cchPatterns);
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync int rc2 = VbglHGCMParmUInt32Get(&Msg.size, pcbBufActual);
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * Start enumerating guest properties which match a given pattern.
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * This function creates a handle which can be used to continue enumerating.
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync * @returns VBox status code.
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync * @retval VINF_SUCCESS on success, *ppHandle points to a handle for continuing
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync * the enumeration and *ppszName, *ppszValue, *pu64Timestamp and
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync * *ppszFlags are set.
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync * @retval VERR_NOT_FOUND if no matching properties were found. In this case
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * the return parameters are not initialised.
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync * @retval VERR_TOO_MUCH_DATA if it was not possible to determine the amount
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * of local space needed to store all the enumeration data. This is
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * due to a race between allocating space and the host adding new
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * data, so retrying may help here. Other parameters are left
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * uninitialised
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync * @param u32ClientId The client id returned by VbglR3InfoSvcConnect().
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync * @param papszPatterns The patterns against which the properties are
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync * matched. Pass NULL if everything should be matched.
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync * @param cPatterns The number of patterns in @a papszPatterns. 0 means
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync * match everything.
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync * @param ppHandle where the handle for continued enumeration is stored
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync * on success. This must be freed with
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync * VbglR3GuestPropEnumFree when it is no longer needed.
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync * @param ppszName Where to store the first property name on success.
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * Should not be freed. Optional.
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync * @param ppszValue Where to store the first property value on success.
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * Should not be freed. Optional.
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync * @param ppszValue Where to store the first timestamp value on success.
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * Optional.
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync * @param ppszFlags Where to store the first flags value on success.
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * Should not be freed. Optional.
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsyncVBGLR3DECL(int) VbglR3GuestPropEnum(uint32_t u32ClientId,
9ee72227058430bcead5831131741b5dc1601f00vboxsync char const * const *papszPatterns,
9ee72227058430bcead5831131741b5dc1601f00vboxsync char const **ppszName,
9ee72227058430bcead5831131741b5dc1601f00vboxsync char const **ppszValue,
9ee72227058430bcead5831131741b5dc1601f00vboxsync char const **ppszFlags)
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync /* Create the handle. */
470122d12fa43f83f993ae8e93ba8e3cf4c674cdvboxsync RTCMemAutoPtr<VBGLR3GUESTPROPENUM, VbglR3GuestPropEnumFree> Handle;
9ee72227058430bcead5831131741b5dc1601f00vboxsync Handle = (PVBGLR3GUESTPROPENUM)RTMemAllocZ(sizeof(VBGLR3GUESTPROPENUM));
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync /* Get the length of the pattern string, including the final terminator. */
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync /* Pack the pattern array */
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync /* Randomly chosen initial size for the buffer to hold the enumeration
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * information. */
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync /* In reading the guest property data we are racing against the host
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * adding more of it, so loop a few times and retry on overflow. */
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync for (int i = 0; i < 10; ++i)
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync rc = VbglR3GuestPropEnumRaw(u32ClientId, Patterns.get(),
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * Transfer ownership of the buffer to the handle structure and
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync * call VbglR3GuestPropEnumNext to retrieve the first entry.
7c930c3ee58f55e1a2cebfa2ad3ae918569a8f44vboxsync rc = VbglR3GuestPropEnumNext(Handle.get(), ppszName, ppszValue,
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync rc = VERR_NOT_FOUND; /* No matching properties found. */
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * Get the next guest property.
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * See @a VbglR3GuestPropEnum.
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync * @returns VBox status code.
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync * @param pHandle Handle obtained from @a VbglR3GuestPropEnum.
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync * @param ppszName Where to store the next property name. This will be
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * set to NULL if there are no more properties to
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * enumerate. This pointer should not be freed. Optional.
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync * @param ppszValue Where to store the next property value. This will be
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * set to NULL if there are no more properties to
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * enumerate. This pointer should not be freed. Optional.
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync * @param pu64Timestamp Where to store the next property timestamp. This
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * will be set to zero if there are no more properties
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * to enumerate. Optional.
1f6b1f68eb26f8af1f9a4b5ffd00df66ad7af1devboxsync * @param ppszFlags Where to store the next property flags. This will be
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * set to NULL if there are no more properties to
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * enumerate. This pointer should not be freed. Optional.
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * @remarks While all output parameters are optional, you need at least one to
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * figure out when to stop.
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsyncVBGLR3DECL(int) VbglR3GuestPropEnumNext(PVBGLR3GUESTPROPENUM pHandle,
9ee72227058430bcead5831131741b5dc1601f00vboxsync char const **ppszName,
9ee72227058430bcead5831131741b5dc1601f00vboxsync char const **ppszValue,
9ee72227058430bcead5831131741b5dc1601f00vboxsync char const **ppszFlags)
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * The VBGLR3GUESTPROPENUM structure contains a buffer containing the raw
d44cb80e1d772854c10ef9ae03daba8dcf61d389vboxsync * properties data and a pointer into the buffer which tracks how far we
d44cb80e1d772854c10ef9ae03daba8dcf61d389vboxsync * have parsed so far. The buffer contains packed strings in groups of
d44cb80e1d772854c10ef9ae03daba8dcf61d389vboxsync * four - name, value, timestamp (as a decimal string) and flags. It is
d44cb80e1d772854c10ef9ae03daba8dcf61d389vboxsync * terminated by four empty strings. We can rely on this layout unless
d44cb80e1d772854c10ef9ae03daba8dcf61d389vboxsync * the caller has been poking about in the structure internals, in which
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * case they must take responsibility for the results.
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * Name\0Value\0Timestamp\0Flags\0
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync char *pchNext = pHandle->pchNext; /* The cursor. */
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync char *pchEnd = pHandle->pchBufEnd; /* End of buffer, for size calculations. */
e86538a7bc028e823f16f8982e90f0c7ef5d4ecevboxsync char *pszValue = pchNext = RTStrEnd(pchNext, pchEnd - pchNext) + 1;
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync AssertPtrReturn(pchNext, VERR_PARSE_ERROR); /* 0x1 is also an invalid pointer :) */
e86538a7bc028e823f16f8982e90f0c7ef5d4ecevboxsync char *pszTimestamp = pchNext = RTStrEnd(pchNext, pchEnd - pchNext) + 1;
e86538a7bc028e823f16f8982e90f0c7ef5d4ecevboxsync char *pszFlags = pchNext = RTStrEnd(pchNext, pchEnd - pchNext) + 1;
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * Don't move the index pointer if we found the terminating "\0\0\0\0" entry.
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * Don't try convert the timestamp either.
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync /* Convert the timestamp string into a number. */
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync int rc = RTStrToUInt64Full(pszTimestamp, 0, &u64Timestamp);
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync AssertMsgReturn(!*pszValue && !*pszTimestamp && !*pszFlags,
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync ("'%s' '%s' '%s'\n", pszValue, pszTimestamp, pszFlags),
70142706c9117b6c1befe7a5be768d25c699ead5vboxsync * Everything is fine, set the return values.
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * Free an enumeration handle returned by @a VbglR3GuestPropEnum.
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsync * @param pHandle the handle to free
3c0e6e6c131cfdaeaeaea598603f6ef6ab10e781vboxsyncVBGLR3DECL(void) VbglR3GuestPropEnumFree(PVBGLR3GUESTPROPENUM pHandle)
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync * Deletes a guest property.
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync * @returns VBox status code.
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync * @param u32ClientId The client id returned by VbglR3InvsSvcConnect().
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync * @param pszName The property to delete. Utf8
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsyncVBGLR3DECL(int) VbglR3GuestPropDelete(uint32_t u32ClientId, const char *pszName)
faf0941c69d5b901d3fa4b67fe6d5d7fb5c28368vboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync * Deletes a set of keys.
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync * The set is specified in the same way as for VbglR3GuestPropEnum.
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync * @returns VBox status code. Stops on first failure.
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync * See also VbglR3GuestPropEnum.
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync * @param u32ClientId The client id returned by VbglR3InfoSvcConnect().
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync * @param papszPatterns The patterns against which the properties are
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync * matched. Pass NULL if everything should be matched.
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync * @param cPatterns The number of patterns in @a papszPatterns. 0 means
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync * match everything.
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsyncVBGLR3DECL(int) VbglR3GuestPropDelSet(uint32_t u32ClientId,
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync const char * const *papszPatterns,
28563f589b9e002e0ca7d7e2567f423fb620b1advboxsync (char **)papszPatterns, /** @todo fix this cast. */
33d90ac36a3ebf89e46a50252fe9542602a6b2bevboxsync rc = VbglR3GuestPropWriteValue(u32ClientId, pszName, NULL);
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * Wait for notification of changes to a guest property. If this is called in
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * a loop, the timestamp of the last notification seen can be passed as a
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * parameter to be sure that no notifications are missed.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * @returns VBox status code.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * @retval VINF_SUCCESS on success, @a ppszName, @a ppszValue,
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * @a pu64Timestamp and @a ppszFlags containing valid data.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * @retval VINF_NOT_FOUND if no previous notification could be found with the
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * timestamp supplied. This will normally mean that a large number
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * of notifications occurred in between.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * @retval VERR_BUFFER_OVERFLOW if the scratch buffer @a pvBuf is not large
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * enough. In this case the size needed will be placed in
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * @a pcbBufActual if it is not NULL.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * @retval VERR_TIMEOUT if a timeout occurred before a notification was seen.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * @param u32ClientId The client id returned by VbglR3GuestPropConnect().
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * @param pszPatterns The patterns that the property names must matchfor
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * the change to be reported.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * @param pvBuf A scratch buffer to store the data retrieved into.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * The returned data is only valid for it's lifetime.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * @a ppszValue will point to the start of this buffer.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * @param cbBuf The size of @a pvBuf
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * @param u64Timestamp The timestamp of the last event seen. Pass zero
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * to wait for the next event.
2e61a24ab78fc4b63349676a08468fbcf1a7a17bvboxsync * @param cMillies Timeout in milliseconds. Use RT_INDEFINITE_WAIT
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * to wait indefinitely.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * @param ppszName Where to store the pointer to the name retrieved.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * Optional.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * @param ppszValue Where to store the pointer to the value retrieved.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * Optional.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * @param pu64Timestamp Where to store the timestamp. Optional.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * @param ppszFlags Where to store the pointer to the flags. Optional.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * @param pcbBufActual If @a pcBuf is not large enough, the size needed.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * Optional.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsyncVBGLR3DECL(int) VbglR3GuestPropWait(uint32_t u32ClientId,
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * Create the GET_NOTIFICATION message and call the host.
bf4de0c2965291e927412f708c6c27eeeb5825d4vboxsync VbglHGCMParmPtrSetString(&Msg.patterns, pszPatterns);
32ad75b4af91dad97e4f6c0b1d9f2fd63d173f19vboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL_TIMED(sizeof(Msg)), &Msg, sizeof(Msg));
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * The cbBufActual parameter is also returned on overflow so the caller can
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * adjust their buffer.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * Buffer layout: Name\0Value\0Flags\0.
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync * If the caller cares about any of these strings, make sure things are
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync * properly terminated (paranoia).
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync && (ppszName != NULL || ppszValue != NULL || ppszFlags != NULL))
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync /* Validate / skip 'Name'. */
e86538a7bc028e823f16f8982e90f0c7ef5d4ecevboxsync char *pszValue = RTStrEnd((char *)pvBuf, cbBuf) + 1;
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync /* Validate / skip 'Value'. */
e86538a7bc028e823f16f8982e90f0c7ef5d4ecevboxsync char *pszFlags = RTStrEnd(pszValue, cbBuf - (pszValue - (char *)pvBuf)) + 1;
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync /* Validate 'Flags'. */
e86538a7bc028e823f16f8982e90f0c7ef5d4ecevboxsync char *pszEos = RTStrEnd(pszFlags, cbBuf - (pszFlags - (char *)pvBuf));
714655059cb50166bd78a8b4fc9fe2d4b29ef4afvboxsync /* And the timestamp, if requested. */
208aaecb51db539a2f7f3d25f38dd2efd0f014a3vboxsync#endif /* VBOX_VBGLR3_XFREE86 */