VBoxGuestR3LibGuestProp.cpp revision 3c3a5ab35783f4d31cb5d3a15db9daadeb804daa
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync/* $Id$ */
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync/** @file
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions,
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync * guest properties.
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync */
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync/*
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync * Copyright (C) 2007 Sun Microsystems, Inc.
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync *
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync * available from http://www.virtualbox.org. This file is free software;
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync * you can redistribute it and/or modify it under the terms of the GNU
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync * General Public License (GPL) as published by the Free Software
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync *
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
3aa59619d4b10a8ba3e2f3d3001309b20fa567bavboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
3aa59619d4b10a8ba3e2f3d3001309b20fa567bavboxsync * additional information or have any questions.
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync */
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync/*******************************************************************************
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync* Header Files *
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync*******************************************************************************/
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync#include <iprt/string.h>
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync#include <iprt/mem.h>
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync#include <iprt/assert.h>
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync#include <VBox/log.h>
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync#include <VBox/HostServices/GuestPropertySvc.h>
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync#include "VBGLR3Internal.h"
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsyncusing namespace guestProp;
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync/**
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync * Connects to the guest property service.
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync *
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync * @returns VBox status code
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync * @param pu32ClientId Where to put the client id on success. The client id
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync * must be passed to all the other calls to the service.
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync */
d7d635edfa61196a9ffe24d486ffec1c53b4e6f0vboxsyncVBGLR3DECL(int) VbglR3GuestPropConnect(uint32_t *pu32ClientId)
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync{
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync VBoxGuestHGCMConnectInfo Info;
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync Info.result = (uint32_t)VERR_WRONG_ORDER; /** @todo drop the cast when the result type has been fixed! */
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync Info.Loc.type = VMMDevHGCMLoc_LocalHost_Existing;
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync memset(&Info.Loc.u, 0, sizeof(Info.Loc.u));
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync strcpy(Info.Loc.u.host.achName, "VBoxGuestPropSvc");
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync Info.u32ClientID = UINT32_MAX; /* try make valgrid shut up. */
cd1ce370c056a0c36a34b23281583353b8a51bc4vboxsync
cd1ce370c056a0c36a34b23281583353b8a51bc4vboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CONNECT, &Info, sizeof(Info));
cd1ce370c056a0c36a34b23281583353b8a51bc4vboxsync if (RT_SUCCESS(rc))
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync {
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync rc = Info.result;
cdaeb34871aa28b96c0d80b474f3c8f9805d0388vboxsync if (RT_SUCCESS(rc))
cdaeb34871aa28b96c0d80b474f3c8f9805d0388vboxsync *pu32ClientId = Info.u32ClientID;
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync }
f36543a0783c9fadf211ea3e98ef6578f5736ccdvboxsync return rc;
cdaeb34871aa28b96c0d80b474f3c8f9805d0388vboxsync}
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync/**
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync * Disconnect from the guest property service.
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync *
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync * @returns VBox status code.
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync * @param u32ClientId The client id returned by VbglR3InfoSvcConnect().
cdaeb34871aa28b96c0d80b474f3c8f9805d0388vboxsync */
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsyncVBGLR3DECL(int) VbglR3GuestPropDisconnect(uint32_t u32ClientId)
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync{
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync VBoxGuestHGCMDisconnectInfo Info;
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync Info.result = (uint32_t)VERR_WRONG_ORDER; /** @todo drop the cast when the result type has been fixed! */
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync Info.u32ClientID = u32ClientId;
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_DISCONNECT, &Info, sizeof(Info));
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync if (RT_SUCCESS(rc))
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync rc = Info.result;
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync return rc;
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync}
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync/**
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync * Write a property value.
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync *
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync * @returns VBox status code.
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync * @param u32ClientId The client id returned by VbglR3InvsSvcConnect().
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync * @param pszName The property to save to. Utf8
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync * @param pszValue The value to store. Utf8. If this is NULL then
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync * the property will be removed.
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync * @param pszFlags The flags for the property
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync */
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsyncVBGLR3DECL(int) VbglR3GuestPropWrite(uint32_t u32ClientId, char *pszName, char *pszValue, char *pszFlags)
b7b0555d5885e8472bfeb1a1b9810f14a2a58177vboxsync{
07ddac0955239ed18e474aaea92b0583981ff778vboxsync int rc;
07ddac0955239ed18e474aaea92b0583981ff778vboxsync
07ddac0955239ed18e474aaea92b0583981ff778vboxsync if (pszValue != NULL)
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync {
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync SetProperty Msg;
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync Msg.hdr.result = (uint32_t)VERR_WRONG_ORDER; /** @todo drop the cast when the result type has been fixed! */
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync Msg.hdr.u32ClientID = u32ClientId;
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync Msg.hdr.u32Function = SET_PROP_VALUE;
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync Msg.hdr.cParms = 2;
e8b6c391092b76836d83c32717155d5b323a2683vboxsync VbglHGCMParmPtrSet(&Msg.name, pszName, strlen(pszName) + 1);
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync VbglHGCMParmPtrSet(&Msg.value, pszValue, strlen(pszValue) + 1);
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync VbglHGCMParmPtrSet(&Msg.flags, pszFlags, strlen(pszFlags) + 1);
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync if (RT_SUCCESS(rc))
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync rc = Msg.hdr.result;
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync }
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync else
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync {
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync DelProperty Msg;
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync
07ddac0955239ed18e474aaea92b0583981ff778vboxsync Msg.hdr.result = (uint32_t)VERR_WRONG_ORDER; /** @todo drop the cast when the result type has been fixed! */
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync Msg.hdr.u32ClientID = u32ClientId;
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync Msg.hdr.u32Function = DEL_PROP;
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync Msg.hdr.cParms = 1;
cdaeb34871aa28b96c0d80b474f3c8f9805d0388vboxsync VbglHGCMParmPtrSet(&Msg.name, pszName, strlen(pszName) + 1);
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync if (RT_SUCCESS(rc))
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync rc = Msg.hdr.result;
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync }
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync return rc;
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync}
cdaeb34871aa28b96c0d80b474f3c8f9805d0388vboxsync
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync/**
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync * Write a property value.
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync *
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync * @returns VBox status code.
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync * @param u32ClientId The client id returned by VbglR3InvsSvcConnect().
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync * @param pszName The property to save to. Utf8
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync * @param pszValue The value to store. Utf8. If this is NULL then
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync * the property will be removed.
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync * @note if the property already exists and pszValue is not NULL then the
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync * property's flags field will be left unchanged
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync */
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsyncVBGLR3DECL(int) VbglR3GuestPropWriteValue(uint32_t u32ClientId, char *pszName, char *pszValue)
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync{
cdaeb34871aa28b96c0d80b474f3c8f9805d0388vboxsync int rc;
cdaeb34871aa28b96c0d80b474f3c8f9805d0388vboxsync
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync if (pszValue != NULL)
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync {
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync SetPropertyValue Msg;
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync Msg.hdr.result = (uint32_t)VERR_WRONG_ORDER; /** @todo drop the cast when the result type has been fixed! */
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync Msg.hdr.u32ClientID = u32ClientId;
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync Msg.hdr.u32Function = SET_PROP_VALUE;
d7d635edfa61196a9ffe24d486ffec1c53b4e6f0vboxsync Msg.hdr.cParms = 2;
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync VbglHGCMParmPtrSet(&Msg.name, pszName, strlen(pszName) + 1);
d7d635edfa61196a9ffe24d486ffec1c53b4e6f0vboxsync VbglHGCMParmPtrSet(&Msg.value, pszValue, strlen(pszValue) + 1);
d7d635edfa61196a9ffe24d486ffec1c53b4e6f0vboxsync rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
d7d635edfa61196a9ffe24d486ffec1c53b4e6f0vboxsync if (RT_SUCCESS(rc))
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync rc = Msg.hdr.result;
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync }
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync else
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync {
cdaeb34871aa28b96c0d80b474f3c8f9805d0388vboxsync DelProperty Msg;
cdaeb34871aa28b96c0d80b474f3c8f9805d0388vboxsync
d7d635edfa61196a9ffe24d486ffec1c53b4e6f0vboxsync Msg.hdr.result = (uint32_t)VERR_WRONG_ORDER; /** @todo drop the cast when the result type has been fixed! */
d7d635edfa61196a9ffe24d486ffec1c53b4e6f0vboxsync Msg.hdr.u32ClientID = u32ClientId;
d7d635edfa61196a9ffe24d486ffec1c53b4e6f0vboxsync Msg.hdr.u32Function = DEL_PROP;
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync Msg.hdr.cParms = 1;
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync VbglHGCMParmPtrSet(&Msg.name, pszName, strlen(pszName) + 1);
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync if (RT_SUCCESS(rc))
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync rc = Msg.hdr.result;
d7d635edfa61196a9ffe24d486ffec1c53b4e6f0vboxsync }
d7d635edfa61196a9ffe24d486ffec1c53b4e6f0vboxsync return rc;
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync}
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync
d7d635edfa61196a9ffe24d486ffec1c53b4e6f0vboxsync
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync/**
d7d635edfa61196a9ffe24d486ffec1c53b4e6f0vboxsync * Retrieve a property.
d7d635edfa61196a9ffe24d486ffec1c53b4e6f0vboxsync *
d7d635edfa61196a9ffe24d486ffec1c53b4e6f0vboxsync * @returns VBox status code.
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync * @retval VINF_SUCCESS on success, pszValue, pu64Timestamp and pszFlags
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync * containing valid data.
d7d635edfa61196a9ffe24d486ffec1c53b4e6f0vboxsync * @retval VERR_BUFFER_OVERFLOW if the scratch buffer @a pcBuf is not large
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync * enough. In this case the size needed will be placed in
d7d635edfa61196a9ffe24d486ffec1c53b4e6f0vboxsync * @a pcbBufActual if it is not NULL.
d7d635edfa61196a9ffe24d486ffec1c53b4e6f0vboxsync * @retval VERR_NOT_FOUND if the key wasn't found.
d7d635edfa61196a9ffe24d486ffec1c53b4e6f0vboxsync *
cdaeb34871aa28b96c0d80b474f3c8f9805d0388vboxsync * @param u32ClientId The client id returned by VbglR3ClipboardConnect().
cdaeb34871aa28b96c0d80b474f3c8f9805d0388vboxsync * @param pszName The value to read. Utf8
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync * @param pcBuf A scratch buffer to store the data retrieved into.
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync * The returned data is only valid for it's lifetime.
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync * @param cbBuf The size of @a pcBuf
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync * @param pszValue Where to store the pointer to the value retrieved.
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync * @param pu64Timestamp Where to store the timestamp. Optional.
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync * @param pszFlags Where to store the pointer to the flags. Optional.
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync * @param pcbBufActual If @a pcBuf is not large enough, the size needed.
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync * Optional.
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync */
d7d635edfa61196a9ffe24d486ffec1c53b4e6f0vboxsyncVBGLR3DECL(int) VbglR3GuestPropRead(uint32_t u32ClientId, const char *pszName,
d7d635edfa61196a9ffe24d486ffec1c53b4e6f0vboxsync void *pvBuf, uint32_t cbBuf,
d7d635edfa61196a9ffe24d486ffec1c53b4e6f0vboxsync char **ppszValue, uint64_t *pu64Timestamp,
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync char **ppszFlags,
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync uint32_t *pcbBufActual)
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync{
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync GetProperty Msg;
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync Msg.hdr.result = (uint32_t)VERR_WRONG_ORDER; /** @todo drop the cast when the result type has been fixed! */
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync Msg.hdr.u32ClientID = u32ClientId;
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync Msg.hdr.u32Function = GET_PROP;
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync Msg.hdr.cParms = 4;
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync VbglHGCMParmPtrSet(&Msg.name, const_cast<char *>(pszName),
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync strlen(pszName) + 1);
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync VbglHGCMParmPtrSet(&Msg.buffer, pvBuf, cbBuf);
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync VbglHGCMParmUInt64Set(&Msg.timestamp, 0);
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync VbglHGCMParmUInt32Set(&Msg.size, 0);
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync if (RT_SUCCESS(rc))
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync rc = Msg.hdr.result;
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync if ((VERR_BUFFER_OVERFLOW == rc) && (pcbBufActual != NULL))
cdaeb34871aa28b96c0d80b474f3c8f9805d0388vboxsync {
cdaeb34871aa28b96c0d80b474f3c8f9805d0388vboxsync int rc2 = VbglHGCMParmUInt32Get(&Msg.size, pcbBufActual);
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync if (!RT_SUCCESS(rc2))
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync rc = rc2;
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync }
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync if (RT_SUCCESS(rc) && (pu64Timestamp != NULL))
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync rc = VbglHGCMParmUInt64Get(&Msg.timestamp, pu64Timestamp);
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync if (RT_SUCCESS(rc))
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync *ppszValue = reinterpret_cast<char *>(pvBuf);
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync if (RT_SUCCESS(rc) && (ppszFlags != NULL))
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync {
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync bool found = false;
a191ab87779e39bb47804d5055c3f0f2dde104fevboxsync size_t i = 0;
a191ab87779e39bb47804d5055c3f0f2dde104fevboxsync char *pcBuf = reinterpret_cast<char *>(pvBuf);
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync for (; i < cbBuf && !found; ++i)
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync if (0 == pcBuf[i])
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync found = true;
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync if (!found)
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync /* To my mind this is an internal error, but whatever */
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync rc = VERR_TOO_MUCH_DATA;
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync else
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync *ppszFlags = pcBuf + i;
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync }
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync return rc;
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync}
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync/**
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync * Retrieve a property value, allocating space for it.
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync *
cdaeb34871aa28b96c0d80b474f3c8f9805d0388vboxsync * @returns VBox status code.
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync * @retval VINF_SUCCESS on success, pszValue containing valid data.
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync * @retval VERR_NOT_FOUND if the key wasn't found.
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync *
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync * @param u32ClientId The client id returned by VbglR3ClipboardConnect().
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync * @param pszName The value to read. Utf8
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync * @param ppszValue Where to store the pointer to the value returned.
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync */
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsyncVBGLR3DECL(int) VbglR3GuestPropReadValueAlloc(uint32_t u32ClientId,
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync const char *pszName,
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync char **ppszValue)
a191ab87779e39bb47804d5055c3f0f2dde104fevboxsync{
667a27cac134814da3a83bf2e0a017833066518bvboxsync int rc = VINF_SUCCESS;
667a27cac134814da3a83bf2e0a017833066518bvboxsync uint32_t cchBuf = 1024;
667a27cac134814da3a83bf2e0a017833066518bvboxsync void *pvBuf = RTMemAlloc(cchBuf);
667a27cac134814da3a83bf2e0a017833066518bvboxsync char *pszValue = NULL;
667a27cac134814da3a83bf2e0a017833066518bvboxsync if (NULL == pvBuf)
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync rc = VERR_NO_MEMORY;
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync if (RT_SUCCESS(rc))
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync {
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync rc = VbglR3GuestPropRead(u32ClientId, pszName, pvBuf, cchBuf,
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync &pszValue, NULL, NULL, &cchBuf);
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync if (VERR_BUFFER_OVERFLOW == rc)
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync {
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync /** @todo how should we handle the race condition here? */
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync pvBuf = RTMemRealloc(pvBuf, cchBuf);
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync if (pvBuf != NULL)
4322eab57b88f880a55e6a4ae0cb76b870167f06vboxsync rc = VbglR3GuestPropRead(u32ClientId, pszName, pvBuf, cchBuf,
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync &pszValue, NULL, NULL, NULL);
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync else
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync rc = VERR_NO_MEMORY;
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync if (VERR_BUFFER_OVERFLOW == rc)
7b2222e6c060dfe168591f22543d3a80f96112b4vboxsync /* VERR_BUFFER_OVERFLOW has a different meaning here as a
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync * return code */
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync rc = VERR_TOO_MUCH_DATA;
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync }
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync }
a191ab87779e39bb47804d5055c3f0f2dde104fevboxsync if (RT_SUCCESS(rc))
a191ab87779e39bb47804d5055c3f0f2dde104fevboxsync *ppszValue = pszValue;
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync return rc;
cdaeb34871aa28b96c0d80b474f3c8f9805d0388vboxsync}
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync/**
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync * Free the memory used by VbglR3GuestPropReadValueAlloc for returning a
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync * value.
cdaeb34871aa28b96c0d80b474f3c8f9805d0388vboxsync *
36545c63b2aab948161e4a712913a4f2dce17d2fvboxsync * @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;
}