VirtualBox

source: vbox/trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR0LibHGCM.cpp

Last change on this file was 98103, checked in by vboxsync, 17 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.4 KB
RevLine 
[55401]1/* $Id: VBoxGuestR0LibHGCM.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
[1]2/** @file
[68476]3 * VBoxGuestLib - Host-Guest Communication Manager, ring-0 client drivers.
[1]4 *
[21211]5 * These public functions can be only used by other drivers. They all
6 * do an IOCTL to VBoxGuest via IDC.
[1]7 */
8
9/*
[98103]10 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
[1]11 *
[72627]12 * Permission is hereby granted, free of charge, to any person
13 * obtaining a copy of this software and associated documentation
14 * files (the "Software"), to deal in the Software without
15 * restriction, including without limitation the rights to use,
16 * copy, modify, merge, publish, distribute, sublicense, and/or sell
17 * copies of the Software, and to permit persons to whom the
18 * Software is furnished to do so, subject to the following
19 * conditions:
[8155]20 *
[72627]21 * The above copyright notice and this permission notice shall be
22 * included in all copies or substantial portions of the Software.
[26425]23 *
[72627]24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
26 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
28 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
29 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
30 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
31 * OTHER DEALINGS IN THE SOFTWARE.
[1]32 */
33
[69308]34
[68476]35/*********************************************************************************************************************************
36* Header Files *
37*********************************************************************************************************************************/
[68645]38#include "VBoxGuestR0LibInternal.h"
[1]39
40#include <iprt/assert.h>
41#include <iprt/semaphore.h>
[2194]42#include <iprt/string.h>
[76419]43#include <VBox/err.h>
[1]44
[68653]45#ifdef VBGL_VBOXGUEST
46# error "This file shouldn't be part of the VBoxGuestR0LibBase library that is linked into VBoxGuest. It's client code."
47#endif
48
49
50/*********************************************************************************************************************************
51* Defined Constants And Macros *
52*********************************************************************************************************************************/
[58181]53#define VBGL_HGCM_ASSERT_MSG AssertReleaseMsg
[1]54
[69308]55
[68476]56/*********************************************************************************************************************************
57* Global Variables *
58*********************************************************************************************************************************/
[21461]59/**
[68102]60 * Fast heap for HGCM handles data.
61 * @{
62 */
[68476]63static RTSEMFASTMUTEX g_hMtxHGCMHandleData;
64static struct VBGLHGCMHANDLEDATA g_aHGCMHandleData[64];
65/** @} */
[68102]66
67
68/**
[21461]69 * Initializes the HGCM VBGL bits.
70 *
71 * @return VBox status code.
72 */
[68654]73DECLR0VBGL(int) VbglR0HGCMInit(void)
[1]74{
[68476]75 AssertReturn(g_hMtxHGCMHandleData == NIL_RTSEMFASTMUTEX, VINF_ALREADY_INITIALIZED);
76 return RTSemFastMutexCreate(&g_hMtxHGCMHandleData);
[1]77}
78
[21461]79/**
80 * Initializes the HGCM VBGL bits.
81 *
82 * @return VBox status code.
83 */
[68654]84DECLR0VBGL(int) VbglR0HGCMTerminate(void)
[1]85{
[68476]86 RTSemFastMutexDestroy(g_hMtxHGCMHandleData);
87 g_hMtxHGCMHandleData = NIL_RTSEMFASTMUTEX;
[1]88
89 return VINF_SUCCESS;
90}
91
[68476]92DECLINLINE(int) vbglR0HandleHeapEnter(void)
[1]93{
[68476]94 int rc = RTSemFastMutexRequest(g_hMtxHGCMHandleData);
[1]95
[58181]96 VBGL_HGCM_ASSERT_MSG(RT_SUCCESS(rc), ("Failed to request handle heap mutex, rc = %Rrc\n", rc));
[1]97
98 return rc;
99}
100
[68476]101DECLINLINE(void) vbglR0HandleHeapLeave(void)
[1]102{
[68476]103 RTSemFastMutexRelease(g_hMtxHGCMHandleData);
[1]104}
105
[68476]106struct VBGLHGCMHANDLEDATA *vbglR0HGCMHandleAlloc(void)
[1]107{
[58181]108 struct VBGLHGCMHANDLEDATA *p = NULL;
[68476]109 int rc = vbglR0HandleHeapEnter();
[58181]110 if (RT_SUCCESS(rc))
111 {
112 uint32_t i;
[1]113
[58181]114 /* Simple linear search in array. This will be called not so often, only connect/disconnect. */
115 /** @todo bitmap for faster search and other obvious optimizations. */
[68476]116 for (i = 0; i < RT_ELEMENTS(g_aHGCMHandleData); i++)
[1]117 {
[68476]118 if (!g_aHGCMHandleData[i].fAllocated)
[58181]119 {
[68476]120 p = &g_aHGCMHandleData[i];
[58181]121 p->fAllocated = 1;
122 break;
123 }
[1]124 }
125
[68476]126 vbglR0HandleHeapLeave();
[1]127
[58181]128 VBGL_HGCM_ASSERT_MSG(p != NULL, ("Not enough HGCM handles.\n"));
129 }
[1]130 return p;
131}
132
[68476]133void vbglR0HGCMHandleFree(struct VBGLHGCMHANDLEDATA *pHandle)
[1]134{
[58181]135 if (pHandle)
136 {
[68476]137 int rc = vbglR0HandleHeapEnter();
[58181]138 if (RT_SUCCESS(rc))
139 {
140 VBGL_HGCM_ASSERT_MSG(pHandle->fAllocated, ("Freeing not allocated handle.\n"));
[719]141
[58181]142 RT_ZERO(*pHandle);
[68476]143 vbglR0HandleHeapLeave();
[58181]144 }
145 }
[1]146}
147
[68654]148DECLR0VBGL(int) VbglR0HGCMConnect(VBGLHGCMHANDLE *pHandle, const char *pszServiceName, HGCMCLIENTID *pidClient)
[1]149{
[719]150 int rc;
[68476]151 if (pHandle && pszServiceName && pidClient)
[1]152 {
[68476]153 struct VBGLHGCMHANDLEDATA *pHandleData = vbglR0HGCMHandleAlloc();
[58181]154 if (pHandleData)
[1]155 {
[68550]156 rc = VbglR0IdcOpen(&pHandleData->IdcHandle,
157 VBGL_IOC_VERSION /*uReqVersion*/,
158 VBGL_IOC_VERSION & UINT32_C(0xffff0000) /*uMinVersion*/,
159 NULL /*puSessionVersion*/, NULL /*puDriverVersion*/, NULL /*uDriverRevision*/);
[50838]160 if (RT_SUCCESS(rc))
[1]161 {
[68550]162 VBGLIOCHGCMCONNECT Info;
[68476]163 RT_ZERO(Info);
[68550]164 VBGLREQHDR_INIT(&Info.Hdr, HGCM_CONNECT);
165 Info.u.In.Loc.type = VMMDevHGCMLoc_LocalHost_Existing;
166 rc = RTStrCopy(Info.u.In.Loc.u.host.achName, sizeof(Info.u.In.Loc.u.host.achName), pszServiceName);
[58181]167 if (RT_SUCCESS(rc))
168 {
[68550]169 rc = VbglR0IdcCall(&pHandleData->IdcHandle, VBGL_IOCTL_HGCM_CONNECT, &Info.Hdr, sizeof(Info));
[68476]170 if (RT_SUCCESS(rc))
171 {
[68550]172 *pidClient = Info.u.Out.idClient;
[68476]173 *pHandle = pHandleData;
174 return rc;
175 }
[58181]176 }
177
[68550]178 VbglR0IdcClose(&pHandleData->IdcHandle);
[1]179 }
[50838]180
[68476]181 vbglR0HGCMHandleFree(pHandleData);
[1]182 }
[58181]183 else
184 rc = VERR_NO_MEMORY;
[1]185 }
[58181]186 else
187 rc = VERR_INVALID_PARAMETER;
[1]188 return rc;
189}
190
[68654]191DECLR0VBGL(int) VbglR0HGCMDisconnect(VBGLHGCMHANDLE handle, HGCMCLIENTID idClient)
[1]192{
[68476]193 int rc;
[68550]194 VBGLIOCHGCMDISCONNECT Info;
[1]195
[68476]196 RT_ZERO(Info);
[68550]197 VBGLREQHDR_INIT(&Info.Hdr, HGCM_DISCONNECT);
198 Info.u.In.idClient = idClient;
199 rc = VbglR0IdcCall(&handle->IdcHandle, VBGL_IOCTL_HGCM_DISCONNECT, &Info.Hdr, sizeof(Info));
[68476]200
[68550]201 VbglR0IdcClose(&handle->IdcHandle);
[1]202
[68476]203 vbglR0HGCMHandleFree(handle);
[1]204
205 return rc;
206}
207
[68654]208DECLR0VBGL(int) VbglR0HGCMCallRaw(VBGLHGCMHANDLE handle, PVBGLIOCHGCMCALL pData, uint32_t cbData)
[1]209{
[68550]210 VBGL_HGCM_ASSERT_MSG(cbData >= sizeof(VBGLIOCHGCMCALL) + pData->cParms * sizeof(HGCMFunctionParameter),
[58181]211 ("cbData = %d, cParms = %d (calculated size %d)\n", cbData, pData->cParms,
[68550]212 sizeof(VBGLIOCHGCMCALL) + pData->cParms * sizeof(VBGLIOCHGCMCALL)));
[1]213
[68550]214 return VbglR0IdcCallRaw(&handle->IdcHandle, VBGL_IOCTL_HGCM_CALL(cbData), &pData->Hdr, cbData);
[1]215}
216
[68654]217DECLR0VBGL(int) VbglR0HGCMCall(VBGLHGCMHANDLE handle, PVBGLIOCHGCMCALL pData, uint32_t cbData)
[40483]218{
[68550]219 int rc = VbglR0HGCMCallRaw(handle, pData, cbData);
220 if (RT_SUCCESS(rc))
221 rc = pData->Hdr.rc;
222 return rc;
[40483]223}
224
[68654]225DECLR0VBGL(int) VbglR0HGCMCallUserDataRaw(VBGLHGCMHANDLE handle, PVBGLIOCHGCMCALL pData, uint32_t cbData)
[14207]226{
[68550]227 VBGL_HGCM_ASSERT_MSG(cbData >= sizeof(VBGLIOCHGCMCALL) + pData->cParms * sizeof(HGCMFunctionParameter),
228 ("cbData = %d, cParms = %d (calculated size %d)\n", cbData, pData->cParms,
229 sizeof(VBGLIOCHGCMCALL) + pData->cParms * sizeof(VBGLIOCHGCMCALL)));
[14207]230
[68550]231 return VbglR0IdcCallRaw(&handle->IdcHandle, VBGL_IOCTL_HGCM_CALL_WITH_USER_DATA(cbData), &pData->Hdr, cbData);
[14207]232}
233
[75547]234
235DECLR0VBGL(int) VbglR0HGCMFastCall(VBGLHGCMHANDLE hHandle, PVBGLIOCIDCHGCMFASTCALL pCallReq, uint32_t cbCallReq)
236{
237 /* pCallReq->Hdr.rc and pCallReq->HgcmCallReq.header.header.rc; are not used by this IDC. */
238 return VbglR0IdcCallRaw(&hHandle->IdcHandle, VBGL_IOCTL_IDC_HGCM_FAST_CALL, &pCallReq->Hdr, cbCallReq);
239}
240
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use