Service.h revision 1264d7bb16bd361221f6e7b6e1642a520d9f72cb
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync/** @file
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync * Base class for an host-guest service.
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync */
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync/*
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync * Copyright (C) 2011 Oracle Corporation
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync *
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync * available from http://www.virtualbox.org. This file is free software;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync * you can redistribute it and/or modify it under the terms of the GNU
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync * General Public License (GPL) as published by the Free Software
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync *
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync * The contents of this file may alternatively be used under the terms
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync * of the Common Development and Distribution License Version 1.0
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync * VirtualBox OSE distribution, in which case the provisions of the
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync * CDDL are applicable instead of those of the GPL.
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync *
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync * You may elect to license modified versions of this file under the
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync * terms and conditions of either the GPL or the CDDL or both.
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync */
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync#ifndef ___VBox_HostService_Service_h
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync#define ___VBox_HostService_Service_h
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync#include <VBox/log.h>
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync#include <VBox/hgcmsvc.h>
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync#include <iprt/assert.h>
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync#include <iprt/alloc.h>
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync#include <iprt/cpp/utils.h>
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync#include <memory> /* for auto_ptr */
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync#include <iprt/stream.h> /* remove */
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsyncnamespace HGCM
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync{
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsyncclass Message
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync{
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsyncpublic:
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync Message(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM aParms[])
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync : m_uMsg(0)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync , m_cParms(0)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync , m_paParms(0)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync setData(uMsg, cParms, aParms);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync ~Message()
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync cleanup();
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync uint32_t message() const { return m_uMsg; }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync uint32_t paramsCount() const { return m_cParms; }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync int getData(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM aParms[]) const
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync if (m_uMsg != uMsg)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync LogFlowFunc(("Message type does not match (%u (buffer), %u (guest))\n",
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync m_uMsg, uMsg));
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync RTPrintf("Message type does not match (%u (buffer), %u (guest))\n",
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync m_uMsg, uMsg);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync return VERR_INVALID_PARAMETER;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync if (m_cParms != cParms)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync LogFlowFunc(("Parameter count does not match (%u (buffer), %u (guest))\n",
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync m_cParms, cParms));
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync RTPrintf("Parameter count does not match (%u (buffer), %u (guest))\n",
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync m_cParms, cParms);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync return VERR_INVALID_PARAMETER;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync int rc = copyParms(cParms, m_paParms, &aParms[0], false /* fCreatePtrs */);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync// if (RT_FAILURE(rc))
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync// cleanup(aParms);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync return rc;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync int setData(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM aParms[])
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync AssertReturn(cParms < 256, VERR_INVALID_PARAMETER);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync AssertPtrNullReturn(aParms, VERR_INVALID_PARAMETER);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync /* Cleanup old messages. */
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync cleanup();
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync m_uMsg = uMsg;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync m_cParms = cParms;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync if (cParms > 0)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync m_paParms = (VBOXHGCMSVCPARM*)RTMemAllocZ(sizeof(VBOXHGCMSVCPARM) * m_cParms);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync if (!m_paParms)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync return VERR_NO_MEMORY;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync int rc = copyParms(cParms, &aParms[0], m_paParms, true /* fCreatePtrs */);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync if (RT_FAILURE(rc))
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync cleanup();
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync return rc;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync int getParmU32Info(uint32_t iParm, uint32_t *pu32Info) const
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync AssertPtrNullReturn(pu32Info, VERR_INVALID_PARAMETER);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync AssertReturn(iParm < m_cParms, VERR_INVALID_PARAMETER);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync AssertReturn(m_paParms[iParm].type == VBOX_HGCM_SVC_PARM_32BIT, VERR_INVALID_PARAMETER);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync *pu32Info = m_paParms[iParm].u.uint32;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync return VINF_SUCCESS;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync int getParmU64Info(uint32_t iParm, uint64_t *pu64Info) const
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync AssertPtrNullReturn(pu64Info, VERR_INVALID_PARAMETER);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync AssertReturn(iParm < m_cParms, VERR_INVALID_PARAMETER);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync AssertReturn(m_paParms[iParm].type == VBOX_HGCM_SVC_PARM_64BIT, VERR_INVALID_PARAMETER);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync *pu64Info = m_paParms[iParm].u.uint64;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync return VINF_SUCCESS;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync int getParmPtrInfo(uint32_t iParm, void **ppvAddr, uint32_t *pcSize) const
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync AssertPtrNullReturn(ppvAddr, VERR_INVALID_PARAMETER);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync AssertPtrNullReturn(pcSize, VERR_INVALID_PARAMETER);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync AssertReturn(iParm < m_cParms, VERR_INVALID_PARAMETER);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync AssertReturn(m_paParms[iParm].type == VBOX_HGCM_SVC_PARM_PTR, VERR_INVALID_PARAMETER);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync *ppvAddr = m_paParms[iParm].u.pointer.addr;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync *pcSize = m_paParms[iParm].u.pointer.size;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync return VINF_SUCCESS;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync int copyParms(uint32_t cParms, PVBOXHGCMSVCPARM paParmsSrc, PVBOXHGCMSVCPARM paParmsDst, bool fCreatePtrs) const
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync int rc = VINF_SUCCESS;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync for (uint32_t i = 0; i < cParms; ++i)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync paParmsDst[i].type = paParmsSrc[i].type;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync switch (paParmsSrc[i].type)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync case VBOX_HGCM_SVC_PARM_32BIT:
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync paParmsDst[i].u.uint32 = paParmsSrc[i].u.uint32;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync break;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync case VBOX_HGCM_SVC_PARM_64BIT:
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync paParmsDst[i].u.uint64 = paParmsSrc[i].u.uint64;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync break;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync case VBOX_HGCM_SVC_PARM_PTR:
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync /* Do we have to recreate the memory? */
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync if (fCreatePtrs)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync /* Yes, do so. */
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync paParmsDst[i].u.pointer.size = paParmsSrc[i].u.pointer.size;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync if (paParmsDst[i].u.pointer.size > 0)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync paParmsDst[i].u.pointer.addr = RTMemAlloc(paParmsDst[i].u.pointer.size);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync if (!paParmsDst[i].u.pointer.addr)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync rc = VERR_NO_MEMORY;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync break;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync else
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync /* No, but we have to check if there is enough room. */
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync if (paParmsDst[i].u.pointer.size < paParmsSrc[i].u.pointer.size)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync rc = VERR_BUFFER_OVERFLOW;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync if ( paParmsDst[i].u.pointer.addr
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync && paParmsSrc[i].u.pointer.size > 0
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync && paParmsDst[i].u.pointer.size > 0)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync memcpy(paParmsDst[i].u.pointer.addr,
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync paParmsSrc[i].u.pointer.addr,
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync RT_MIN(paParmsDst[i].u.pointer.size, paParmsSrc[i].u.pointer.size));
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync break;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync default:
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync AssertMsgFailed(("Unknown HGCM type %u\n", paParmsSrc[i].type));
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync rc = VERR_INVALID_PARAMETER;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync break;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync if (RT_FAILURE(rc))
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync break;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync return rc;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync void cleanup()
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync if (m_paParms)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync for (uint32_t i = 0; i < m_cParms; ++i)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync switch (m_paParms[i].type)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync case VBOX_HGCM_SVC_PARM_PTR:
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync if (m_paParms[i].u.pointer.size)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync RTMemFree(m_paParms[i].u.pointer.addr);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync break;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync RTMemFree(m_paParms);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync m_paParms = 0;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync m_cParms = 0;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync m_uMsg = 0;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsyncprotected:
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync uint32_t m_uMsg;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync uint32_t m_cParms;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync PVBOXHGCMSVCPARM m_paParms;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync};
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsyncclass Client
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync{
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsyncpublic:
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync Client(uint32_t uClientId, VBOXHGCMCALLHANDLE hHandle, uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM aParms[])
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync : m_uClientId(uClientId)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync , m_hHandle(hHandle)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync , m_uMsg(uMsg)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync , m_cParms(cParms)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync , m_paParms(aParms) {}
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync VBOXHGCMCALLHANDLE handle() const { return m_hHandle; }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync uint32_t message() const { return m_uMsg; }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync uint32_t clientId() const { return m_uClientId; }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync int addMessageInfo(uint32_t uMsg, uint32_t cParms)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync if (m_cParms != 3)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync return VERR_INVALID_PARAMETER;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync m_paParms[0].setUInt32(uMsg);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync m_paParms[1].setUInt32(cParms);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync return VINF_SUCCESS;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync int addMessageInfo(const Message *pMessage)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync if (m_cParms != 3)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync return VERR_INVALID_PARAMETER;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync m_paParms[0].setUInt32(pMessage->message());
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync m_paParms[1].setUInt32(pMessage->paramsCount());
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync return VINF_SUCCESS;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync int addMessage(const Message *pMessage)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync return pMessage->getData(m_uMsg, m_cParms, m_paParms);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsyncprivate:
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync uint32_t m_uClientId;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync VBOXHGCMCALLHANDLE m_hHandle;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync uint32_t m_uMsg;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync uint32_t m_cParms;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync PVBOXHGCMSVCPARM m_paParms;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync};
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsynctemplate <class T>
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsyncclass AbstractService: public RTCNonCopyable
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync{
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsyncpublic:
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync /**
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync * @copydoc VBOXHGCMSVCLOAD
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync */
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync static DECLCALLBACK(int) svcLoad(VBOXHGCMSVCFNTABLE *pTable)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync LogFlowFunc(("ptable = %p\n", pTable));
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync int rc = VINF_SUCCESS;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync if (!VALID_PTR(pTable))
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync rc = VERR_INVALID_PARAMETER;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync else
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync LogFlowFunc(("ptable->cbSize = %d, ptable->u32Version = 0x%08X\n", pTable->cbSize, pTable->u32Version));
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync if ( pTable->cbSize != sizeof (VBOXHGCMSVCFNTABLE)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync || pTable->u32Version != VBOX_HGCM_SVC_VERSION)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync rc = VERR_VERSION_MISMATCH;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync else
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync std::auto_ptr<AbstractService> apService;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync /* No exceptions may propagate outside. */
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync try
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync apService = std::auto_ptr<AbstractService>(new T(pTable->pHelpers));
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync } catch (int rcThrown)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync rc = rcThrown;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync } catch (...)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync rc = VERR_UNRESOLVED_ERROR;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync if (RT_SUCCESS(rc))
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync /*
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync * We don't need an additional client data area on the host,
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync * because we're a class which can have members for that :-).
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync */
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync pTable->cbClient = 0;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync /* These functions are mandatory */
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync pTable->pfnUnload = svcUnload;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync pTable->pfnConnect = svcConnect;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync pTable->pfnDisconnect = svcDisconnect;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync pTable->pfnCall = svcCall;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync /* Clear obligatory functions. */
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync pTable->pfnHostCall = NULL;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync pTable->pfnSaveState = NULL;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync pTable->pfnLoadState = NULL;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync pTable->pfnRegisterExtension = NULL;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync /* Let the service itself initialize. */
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync rc = apService->init(pTable);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync /* Only on success stop the auto release of the auto_ptr. */
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync if (RT_SUCCESS(rc))
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync pTable->pvService = apService.release();
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync LogFlowFunc(("returning %Rrc\n", rc));
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync return rc;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync virtual ~AbstractService() {};
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsyncprotected:
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync explicit AbstractService(PVBOXHGCMSVCHELPERS pHelpers)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync : m_pHelpers(pHelpers)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync , m_pfnHostCallback(NULL)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync , m_pvHostData(NULL)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {}
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync virtual int init(VBOXHGCMSVCFNTABLE *ptable) { return VINF_SUCCESS; }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync virtual int uninit() { return VINF_SUCCESS; }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync virtual int clientConnect(uint32_t u32ClientID, void *pvClient) = 0;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync virtual int clientDisconnect(uint32_t u32ClientID, void *pvClient) = 0;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync virtual void guestCall(VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID, void *pvClient, uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) = 0;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync virtual int hostCall(uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) { return VINF_SUCCESS; }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync /** Type definition for use in callback functions. */
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync typedef AbstractService SELF;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync /** HGCM helper functions. */
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync PVBOXHGCMSVCHELPERS m_pHelpers;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync /*
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync * Callback function supplied by the host for notification of updates
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync * to properties.
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync */
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync PFNHGCMSVCEXT m_pfnHostCallback;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync /** User data pointer to be supplied to the host callback function. */
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync void *m_pvHostData;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync /**
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync * @copydoc VBOXHGCMSVCHELPERS::pfnUnload
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync * Simply deletes the service object
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync */
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync static DECLCALLBACK(int) svcUnload(void *pvService)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync AssertLogRelReturn(VALID_PTR(pvService), VERR_INVALID_PARAMETER);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync SELF *pSelf = reinterpret_cast<SELF *>(pvService);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync int rc = pSelf->uninit();
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync AssertRC(rc);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync if (RT_SUCCESS(rc))
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync delete pSelf;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync return rc;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync /**
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync * @copydoc VBOXHGCMSVCHELPERS::pfnConnect
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync * Stub implementation of pfnConnect and pfnDisconnect.
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync */
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync static DECLCALLBACK(int) svcConnect(void *pvService,
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync uint32_t u32ClientID,
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync void *pvClient)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync AssertLogRelReturn(VALID_PTR(pvService), VERR_INVALID_PARAMETER);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync LogFlowFunc(("pvService=%p, u32ClientID=%u, pvClient=%p\n", pvService, u32ClientID, pvClient));
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync SELF *pSelf = reinterpret_cast<SELF *>(pvService);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync int rc = pSelf->clientConnect(u32ClientID, pvClient);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync LogFlowFunc(("rc=%Rrc\n", rc));
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync return rc;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync /**
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync * @copydoc VBOXHGCMSVCHELPERS::pfnConnect
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync * Stub implementation of pfnConnect and pfnDisconnect.
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync */
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync static DECLCALLBACK(int) svcDisconnect(void *pvService,
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync uint32_t u32ClientID,
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync void *pvClient)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync AssertLogRelReturn(VALID_PTR(pvService), VERR_INVALID_PARAMETER);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync LogFlowFunc(("pvService=%p, u32ClientID=%u, pvClient=%p\n", pvService, u32ClientID, pvClient));
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync SELF *pSelf = reinterpret_cast<SELF *>(pvService);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync int rc = pSelf->clientDisconnect(u32ClientID, pvClient);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync LogFlowFunc(("rc=%Rrc\n", rc));
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync return rc;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync /**
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync * @copydoc VBOXHGCMSVCHELPERS::pfnCall
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync * Wraps to the call member function
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync */
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync static DECLCALLBACK(void) svcCall(void * pvService,
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync VBOXHGCMCALLHANDLE callHandle,
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync uint32_t u32ClientID,
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync void *pvClient,
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync uint32_t u32Function,
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync uint32_t cParms,
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync VBOXHGCMSVCPARM paParms[])
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync AssertLogRelReturnVoid(VALID_PTR(pvService));
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync LogFlowFunc(("pvService=%p, callHandle=%p, u32ClientID=%u, pvClient=%p, u32Function=%u, cParms=%u, paParms=%p\n", pvService, callHandle, u32ClientID, pvClient, u32Function, cParms, paParms));
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync SELF *pSelf = reinterpret_cast<SELF *>(pvService);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync pSelf->guestCall(callHandle, u32ClientID, pvClient, u32Function, cParms, paParms);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync LogFlowFunc(("returning\n"));
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync /**
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync * @copydoc VBOXHGCMSVCHELPERS::pfnHostCall
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync * Wraps to the hostCall member function
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync */
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync static DECLCALLBACK(int) svcHostCall(void *pvService,
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync uint32_t u32Function,
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync uint32_t cParms,
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync VBOXHGCMSVCPARM paParms[])
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync AssertLogRelReturn(VALID_PTR(pvService), VERR_INVALID_PARAMETER);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync LogFlowFunc(("pvService=%p, u32Function=%u, cParms=%u, paParms=%p\n", pvService, u32Function, cParms, paParms));
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync SELF *pSelf = reinterpret_cast<SELF *>(pvService);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync int rc = pSelf->hostCall(u32Function, cParms, paParms);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync LogFlowFunc(("rc=%Rrc\n", rc));
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync return rc;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync /**
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync * @copydoc VBOXHGCMSVCHELPERS::pfnRegisterExtension
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync * Installs a host callback for notifications of property changes.
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync */
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync static DECLCALLBACK(int) svcRegisterExtension(void *pvService,
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync PFNHGCMSVCEXT pfnExtension,
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync void *pvExtension)
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync {
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync AssertLogRelReturn(VALID_PTR(pvService), VERR_INVALID_PARAMETER);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync LogFlowFunc(("pvService=%p, pfnExtension=%p, pvExtention=%p\n", pvService, pfnExtension, pvExtension));
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync SELF *pSelf = reinterpret_cast<SELF *>(pvService);
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync pSelf->m_pfnHostCallback = pfnExtension;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync pSelf->m_pvHostData = pvExtension;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync return VINF_SUCCESS;
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync }
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync};
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync}
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync#endif /* !___VBox_HostService_Service_h */
1264d7bb16bd361221f6e7b6e1642a520d9f72cbvboxsync