VBoxGuestR3LibGuestProp.cpp revision e7e60b177e688900656c04404c5123f1dfa1d02c
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/* $Id$ */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/** @file
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * guest properties.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/*
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Copyright (C) 2007 Sun Microsystems, Inc.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * available from http://www.virtualbox.org. This file is free software;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * you can redistribute it and/or modify it under the terms of the GNU
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * General Public License (GPL) as published by the Free Software
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * additional information or have any questions.
8608612b77e4d9bccdd4ff30a40ce7cc68966570vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/*******************************************************************************
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync* Header Files *
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync*******************************************************************************/
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include <iprt/string.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include <iprt/mem.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include <iprt/assert.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include <VBox/log.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include <VBox/HostServices/GuestPropertySvc.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "VBGLR3Internal.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncusing namespace guestProp;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/**
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Connects to the guest property service.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * @returns VBox status code
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * @param pu32ClientId Where to put the client id on success. The client id
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * must be passed to all the other calls to the service.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncVBGLR3DECL(int) VbglR3GuestPropConnect(uint32_t *pu32ClientId)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync VBoxGuestHGCMConnectInfo Info;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync Info.result = (uint32_t)VERR_WRONG_ORDER; /** @todo drop the cast when the result type has been fixed! */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync Info.Loc.type = VMMDevHGCMLoc_LocalHost_Existing;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync memset(&Info.Loc.u, 0, sizeof(Info.Loc.u));
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync strcpy(Info.Loc.u.host.achName, "VBoxGuestPropSvc");
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync Info.u32ClientID = UINT32_MAX; /* try make valgrid shut up. */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CONNECT, &Info, sizeof(Info));
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (RT_SUCCESS(rc))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = Info.result;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (RT_SUCCESS(rc))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *pu32ClientId = Info.u32ClientID;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return rc;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/**
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Disconnect from the guest property service.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * @returns VBox status code.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * @param u32ClientId The client id returned by VbglR3InfoSvcConnect().
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncVBGLR3DECL(int) VbglR3GuestPropDisconnect(uint32_t u32ClientId)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync VBoxGuestHGCMDisconnectInfo Info;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync Info.result = (uint32_t)VERR_WRONG_ORDER; /** @todo drop the cast when the result type has been fixed! */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync Info.u32ClientID = u32ClientId;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_DISCONNECT, &Info, sizeof(Info));
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (RT_SUCCESS(rc))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = Info.result;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return rc;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/**
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Write a property value.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * @returns VBox status code.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * @param u32ClientId The client id returned by VbglR3InvsSvcConnect().
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * @param pszName The property to save to. Utf8
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * @param pszValue The value to store. Utf8. If this is NULL then
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * the property will be removed.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * @param pszFlags The flags for the property
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncVBGLR3DECL(int) VbglR3GuestPropWrite(uint32_t u32ClientId, const char *pszName, const char *pszValue, const char *pszFlags)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int rc;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (pszValue != NULL)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync SetProperty Msg;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync Msg.hdr.result = (uint32_t)VERR_WRONG_ORDER; /** @todo drop the cast when the result type has been fixed! */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync Msg.hdr.u32ClientID = u32ClientId;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync Msg.hdr.u32Function = SET_PROP_VALUE;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync Msg.hdr.cParms = 2;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync VbglHGCMParmPtrSet(&Msg.name, const_cast<char *>(pszName), strlen(pszName) + 1);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync VbglHGCMParmPtrSet(&Msg.value, const_cast<char *>(pszValue), strlen(pszValue) + 1);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync VbglHGCMParmPtrSet(&Msg.flags, const_cast<char *>(pszFlags), strlen(pszFlags) + 1);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (RT_SUCCESS(rc))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = Msg.hdr.result;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync DelProperty Msg;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync Msg.hdr.result = (uint32_t)VERR_WRONG_ORDER; /** @todo drop the cast when the result type has been fixed! */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync Msg.hdr.u32ClientID = u32ClientId;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync Msg.hdr.u32Function = DEL_PROP;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync Msg.hdr.cParms = 1;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync VbglHGCMParmPtrSet(&Msg.name, const_cast<char *>(pszName), strlen(pszName) + 1);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (RT_SUCCESS(rc))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = Msg.hdr.result;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return rc;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/**
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Write a property value.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * @returns VBox status code.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * @param u32ClientId The client id returned by VbglR3InvsSvcConnect().
4d10b27f3115f8fcd58864142163726d6214a752vboxsync * @param pszName The property to save to. Utf8
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * @param pszValue The value to store. Utf8. If this is NULL then
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * the property will be removed.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * @note if the property already exists and pszValue is not NULL then the
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * property's flags field will be left unchanged
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncVBGLR3DECL(int) VbglR3GuestPropWriteValue(uint32_t u32ClientId, const char *pszName, const char *pszValue)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int rc;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (pszValue != NULL)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync SetPropertyValue Msg;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync Msg.hdr.result = (uint32_t)VERR_WRONG_ORDER; /** @todo drop the cast when the result type has been fixed! */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync Msg.hdr.u32ClientID = u32ClientId;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync Msg.hdr.u32Function = SET_PROP_VALUE;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync Msg.hdr.cParms = 2;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync VbglHGCMParmPtrSet(&Msg.name, const_cast<char *>(pszName), strlen(pszName) + 1);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync VbglHGCMParmPtrSet(&Msg.value, const_cast<char *>(pszValue), strlen(pszValue) + 1);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (RT_SUCCESS(rc))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = Msg.hdr.result;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync DelProperty Msg;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync Msg.hdr.result = (uint32_t)VERR_WRONG_ORDER; /** @todo drop the cast when the result type has been fixed! */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync Msg.hdr.u32ClientID = u32ClientId;
c18725c5feb3fb06870ff1b6fd3d424d3033bd11vboxsync Msg.hdr.u32Function = DEL_PROP;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync Msg.hdr.cParms = 1;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync VbglHGCMParmPtrSet(&Msg.name, const_cast<char *>(pszName), strlen(pszName) + 1);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (RT_SUCCESS(rc))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rc = Msg.hdr.result;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return rc;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/**
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Retrieve a property.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * @returns VBox status code.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * @retval VINF_SUCCESS on success, pszValue, pu64Timestamp and pszFlags
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * containing valid data.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * @retval VERR_BUFFER_OVERFLOW if the scratch buffer @a pcBuf is not large
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * enough. In this case the size needed will be placed in
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * @a pcbBufActual if it is not NULL.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * @retval VERR_NOT_FOUND if the key wasn't found.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *
f22cba796fd7499bf85058671a1af7cbe491c622vboxsync * @param u32ClientId The client id returned by VbglR3ClipboardConnect().
f22cba796fd7499bf85058671a1af7cbe491c622vboxsync * @param pszName The value to read. Utf8
f22cba796fd7499bf85058671a1af7cbe491c622vboxsync * @param pcBuf A scratch buffer to store the data retrieved into.
f22cba796fd7499bf85058671a1af7cbe491c622vboxsync * The returned data is only valid for it's lifetime.
f22cba796fd7499bf85058671a1af7cbe491c622vboxsync * @param cbBuf The size of @a pcBuf
f22cba796fd7499bf85058671a1af7cbe491c622vboxsync * @param pszValue Where to store the pointer to the value retrieved.
f22cba796fd7499bf85058671a1af7cbe491c622vboxsync * @param pu64Timestamp Where to store the timestamp. Optional.
f22cba796fd7499bf85058671a1af7cbe491c622vboxsync * @param pszFlags Where to store the pointer to the flags. Optional.
7e032664d31552364e83b411950d6e7c96b0b880vboxsync * @param pcbBufActual If @a pcBuf is not large enough, the size needed.
7e032664d31552364e83b411950d6e7c96b0b880vboxsync * Optional.
ca551aca153d6df494985b5281c573ba2e3eb474vboxsync */
ca551aca153d6df494985b5281c573ba2e3eb474vboxsyncVBGLR3DECL(int) VbglR3GuestPropRead(uint32_t u32ClientId, const char *pszName,
ca551aca153d6df494985b5281c573ba2e3eb474vboxsync void *pvBuf, uint32_t cbBuf,
ca551aca153d6df494985b5281c573ba2e3eb474vboxsync char **ppszValue, uint64_t *pu64Timestamp,
ca551aca153d6df494985b5281c573ba2e3eb474vboxsync char **ppszFlags,
56ab2984caa8d0c6b6f97ca142d54285de8a0e43vboxsync uint32_t *pcbBufActual)
bd810d58866067df322ea7f4a4627d9bdebb70d3vboxsync{
bd810d58866067df322ea7f4a4627d9bdebb70d3vboxsync GetProperty Msg;
bd810d58866067df322ea7f4a4627d9bdebb70d3vboxsync
bd810d58866067df322ea7f4a4627d9bdebb70d3vboxsync Msg.hdr.result = (uint32_t)VERR_WRONG_ORDER; /** @todo drop the cast when the result type has been fixed! */
bd810d58866067df322ea7f4a4627d9bdebb70d3vboxsync Msg.hdr.u32ClientID = u32ClientId;
bd810d58866067df322ea7f4a4627d9bdebb70d3vboxsync Msg.hdr.u32Function = GET_PROP;
6e7c344fc7cdb580356704e8201207b394d367bbvboxsync Msg.hdr.cParms = 4;
6e7c344fc7cdb580356704e8201207b394d367bbvboxsync VbglHGCMParmPtrSet(&Msg.name, const_cast<char *>(pszName),
6e7c344fc7cdb580356704e8201207b394d367bbvboxsync strlen(pszName) + 1);
6e7c344fc7cdb580356704e8201207b394d367bbvboxsync VbglHGCMParmPtrSet(&Msg.buffer, pvBuf, cbBuf);
6e7c344fc7cdb580356704e8201207b394d367bbvboxsync VbglHGCMParmUInt64Set(&Msg.timestamp, 0);
6e7c344fc7cdb580356704e8201207b394d367bbvboxsync VbglHGCMParmUInt32Set(&Msg.size, 0);
6e7c344fc7cdb580356704e8201207b394d367bbvboxsync
6e7c344fc7cdb580356704e8201207b394d367bbvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
6e7c344fc7cdb580356704e8201207b394d367bbvboxsync if (RT_SUCCESS(rc))
6e7c344fc7cdb580356704e8201207b394d367bbvboxsync rc = Msg.hdr.result;
6e7c344fc7cdb580356704e8201207b394d367bbvboxsync if ((VERR_BUFFER_OVERFLOW == rc) && (pcbBufActual != NULL))
6e7c344fc7cdb580356704e8201207b394d367bbvboxsync {
6e7c344fc7cdb580356704e8201207b394d367bbvboxsync int rc2 = VbglHGCMParmUInt32Get(&Msg.size, pcbBufActual);
6e7c344fc7cdb580356704e8201207b394d367bbvboxsync if (!RT_SUCCESS(rc2))
6e7c344fc7cdb580356704e8201207b394d367bbvboxsync rc = rc2;
13f76705071cb6db2cd84c495ccb53e0daebd308vboxsync }
716eca86fb214d6bf59f8837d35f5e812729940avboxsync if (RT_SUCCESS(rc) && (pu64Timestamp != NULL))
af8d59d05d72f134aeea62712f1286b369807d52vboxsync rc = VbglHGCMParmUInt64Get(&Msg.timestamp, pu64Timestamp);
81b3101ea5e60964f67c97185bbd43dbf75c5ab5vboxsync if (RT_SUCCESS(rc))
81b3101ea5e60964f67c97185bbd43dbf75c5ab5vboxsync *ppszValue = reinterpret_cast<char *>(pvBuf);
a399af7c964fd519318bb906a1274e720943a4c1vboxsync if (RT_SUCCESS(rc) && (ppszFlags != NULL))
a399af7c964fd519318bb906a1274e720943a4c1vboxsync {
a399af7c964fd519318bb906a1274e720943a4c1vboxsync char *pszEos = reinterpret_cast<char *>(memchr(pvBuf, '\0', cbBuf));
a399af7c964fd519318bb906a1274e720943a4c1vboxsync if (pszEos)
a399af7c964fd519318bb906a1274e720943a4c1vboxsync *ppszFlags = pszEos + 1;
a399af7c964fd519318bb906a1274e720943a4c1vboxsync else
a399af7c964fd519318bb906a1274e720943a4c1vboxsync rc = VERR_TOO_MUCH_DATA;
a399af7c964fd519318bb906a1274e720943a4c1vboxsync }
a399af7c964fd519318bb906a1274e720943a4c1vboxsync return rc;
a399af7c964fd519318bb906a1274e720943a4c1vboxsync}
a399af7c964fd519318bb906a1274e720943a4c1vboxsync
a399af7c964fd519318bb906a1274e720943a4c1vboxsync
c62d2520ac91e12cf4665c936f490dd2064152d3vboxsync/**
c62d2520ac91e12cf4665c936f490dd2064152d3vboxsync * Retrieve a property value, allocating space for it.
c62d2520ac91e12cf4665c936f490dd2064152d3vboxsync *
c62d2520ac91e12cf4665c936f490dd2064152d3vboxsync * @returns VBox status code.
c62d2520ac91e12cf4665c936f490dd2064152d3vboxsync * @retval VINF_SUCCESS on success, *ppszValue containing valid data.
c62d2520ac91e12cf4665c936f490dd2064152d3vboxsync * @retval VERR_NOT_FOUND if the key wasn't found and *ppszValue set to NULL.
c62d2520ac91e12cf4665c936f490dd2064152d3vboxsync * @retval VERR_TOO_MUCH_DATA if we were unable to determine the right size
88c504b1c053e580e42d5fc90ef2ccedc50c65bdvboxsync * to allocate for the buffer. This can happen as the result of a
bf4db0318f6b76f524b27b87528918fd40aeaae6vboxsync * race between our allocating space and the host changing the
bf4db0318f6b76f524b27b87528918fd40aeaae6vboxsync * property value.
d7b582240fd84655df03ad70cf59ac764bf7cce7vboxsync *
c6ccc50e63b794d6ef52f52de638eeb08c61417evboxsync * @param u32ClientId The client id returned by VbglR3ClipboardConnect().
1923b15bec4fe14f2049678525e5ae739a884dd0vboxsync * @param pszName The value to read. Utf8
1923b15bec4fe14f2049678525e5ae739a884dd0vboxsync * @param ppszValue Where to store the pointer to the value returned.
2f4c1bacd54af5063c3185cc8eab03e4e8ef9b90vboxsync */
c18725c5feb3fb06870ff1b6fd3d424d3033bd11vboxsyncVBGLR3DECL(int) VbglR3GuestPropReadValueAlloc(uint32_t u32ClientId,
3298fbeb9910ae6044bee8c3383ef26e4470ad6dvboxsync const char *pszName,
3298fbeb9910ae6044bee8c3383ef26e4470ad6dvboxsync char **ppszValue)
f350d4fb2d12fd22c0905fe9c7a121499da7b52dvboxsync{
f350d4fb2d12fd22c0905fe9c7a121499da7b52dvboxsync int rc = VINF_SUCCESS;
f350d4fb2d12fd22c0905fe9c7a121499da7b52dvboxsync uint32_t cchBuf = 1024;
f350d4fb2d12fd22c0905fe9c7a121499da7b52dvboxsync void *pvBuf = RTMemAlloc(cchBuf);
f350d4fb2d12fd22c0905fe9c7a121499da7b52dvboxsync char *pszValue = NULL;
f350d4fb2d12fd22c0905fe9c7a121499da7b52dvboxsync *ppszValue = NULL;
f350d4fb2d12fd22c0905fe9c7a121499da7b52dvboxsync if (NULL == pvBuf)
f350d4fb2d12fd22c0905fe9c7a121499da7b52dvboxsync rc = VERR_NO_MEMORY;
f350d4fb2d12fd22c0905fe9c7a121499da7b52dvboxsync if (RT_SUCCESS(rc))
f350d4fb2d12fd22c0905fe9c7a121499da7b52dvboxsync {
/* There is a race here between our reading the property size and the
* host changing the value before we read it. Try up to ten times and
* report the problem if that fails. */
bool finish = false;
for (unsigned i = 0; (i < 10) && !finish; ++i)
{
rc = VbglR3GuestPropRead(u32ClientId, pszName, pvBuf, cchBuf,
&pszValue, NULL, NULL, &cchBuf);
if (VERR_BUFFER_OVERFLOW == rc)
{
pvBuf = RTMemRealloc(pvBuf, cchBuf);
if (NULL == pvBuf)
rc = VERR_NO_MEMORY;
}
if (rc != VERR_BUFFER_OVERFLOW)
finish = true;
}
if (VERR_BUFFER_OVERFLOW == rc)
/* VERR_BUFFER_OVERFLOW has a different meaning here as a
* return code, but we need to report the race. */
rc = VERR_TOO_MUCH_DATA;
}
if (RT_SUCCESS(rc))
*ppszValue = pszValue;
return rc;
}
/**
* Free the memory used by VbglR3GuestPropReadValueAlloc for returning a
* value.
*
* @param pszValue the memory to be freed. NULL pointers will be ignored.
*/
VBGLR3DECL(void) VbglR3GuestPropReadValueFree(char *pszValue)
{
RTMemFree(pszValue);
}
/**
* Retrieve a property value, using a user-provided buffer to store it.
*
* @returns VBox status code.
* @retval VINF_SUCCESS on success, pszValue containing valid data.
* @retval VERR_BUFFER_OVERFLOW and the size needed in pcchValueActual if the
* buffer provided was too small
* @retval VERR_NOT_FOUND if the key wasn't found.
*
* @note There is a race here between obtaining the size of the buffer
* needed to hold the value and the value being updated.
*
* @param u32ClientId The client id returned by VbglR3ClipboardConnect().
* @param pszName The value to read. Utf8
* @param pszValue Where to store the value retrieved.
* @param cchValue The size of the buffer pointed to by @a pszValue
* @param pcchValueActual Where to store the size of the buffer needed if
* the buffer supplied is too small. Optional.
*/
VBGLR3DECL(int) VbglR3GuestPropReadValue(uint32_t u32ClientId, const char *pszName,
char *pszValue, uint32_t cchValue,
uint32_t *pcchValueActual)
{
char *pcBuf = NULL;
int rc = VbglR3GuestPropReadValueAlloc(u32ClientId, pszName, &pcBuf);
if (RT_SUCCESS(rc))
{
uint32_t cchValueActual = strlen(pcBuf) + 1;
if (cchValueActual > cchValue)
{
if (pcchValueActual != NULL)
*pcchValueActual = cchValueActual;
rc = VERR_BUFFER_OVERFLOW;
}
if (RT_SUCCESS(rc))
strcpy(pszValue, pcBuf);
}
VbglR3GuestPropReadValueFree(pcBuf);
return rc;
}