VirtualBox

source: vbox/trunk/src/VBox/Additions/common/VBoxGuestLib/HGCM.cpp@ 68102

Last change on this file since 68102 was 68102, checked in by vboxsync, 7 years ago

R0 guest library: move HGCM globals out of global library structure.

bugref:8524: Additions/linux: play nicely with distribution-installed Additions
As part of elimitating dependencies of the HGCM R0 guest library code on the
rest of the library, move its global variables (handles and mutex) out of the
global library structure and into HGCM.cpp. The aim is to reduce the number
of library files included in the Linux shared folder driver.

Signed-off-by: Hans de Goede <hdegoede@…>
Reworked by Oracle.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.1 KB
Line 
1/* $Id: HGCM.cpp 68102 2017-07-25 09:36:25Z vboxsync $ */
2/** @file
3 * VBoxGuestLib - Host-Guest Communication Manager.
4 *
5 * These public functions can be only used by other drivers. They all
6 * do an IOCTL to VBoxGuest via IDC.
7 */
8
9/*
10 * Copyright (C) 2006-2016 Oracle Corporation
11 *
12 * This file is part of VirtualBox Open Source Edition (OSE), as
13 * available from http://www.virtualbox.org. This file is free software;
14 * you can redistribute it and/or modify it under the terms of the GNU
15 * General Public License (GPL) as published by the Free Software
16 * Foundation, in version 2 as it comes in the "COPYING" file of the
17 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
18 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
19 *
20 * The contents of this file may alternatively be used under the terms
21 * of the Common Development and Distribution License Version 1.0
22 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
23 * VirtualBox OSE distribution, in which case the provisions of the
24 * CDDL are applicable instead of those of the GPL.
25 *
26 * You may elect to license modified versions of this file under the
27 * terms and conditions of either the GPL or the CDDL or both.
28 */
29
30/* Entire file is ifdef'ed with !VBGL_VBOXGUEST */
31#ifndef VBGL_VBOXGUEST
32
33#include "VBGLInternal.h"
34
35#include <iprt/assert.h>
36#include <iprt/semaphore.h>
37#include <iprt/string.h>
38
39#define VBGL_HGCM_ASSERT_MSG AssertReleaseMsg
40
41/**
42 * Fast heap for HGCM handles data.
43 * @{
44 */
45
46static RTSEMFASTMUTEX mutexHGCMHandle;
47
48static struct VBGLHGCMHANDLEDATA aHGCMHandleData[64];
49
50/** @} */
51
52/**
53 * Initializes the HGCM VBGL bits.
54 *
55 * @return VBox status code.
56 */
57int vbglR0HGCMInit(void)
58{
59 AssertReturn(mutexHGCMHandle == NIL_RTSEMFASTMUTEX, VINF_ALREADY_INITIALIZED);
60 return RTSemFastMutexCreate(&mutexHGCMHandle);
61}
62
63/**
64 * Initializes the HGCM VBGL bits.
65 *
66 * @return VBox status code.
67 */
68int vbglR0HGCMTerminate(void)
69{
70 RTSemFastMutexDestroy(mutexHGCMHandle);
71 mutexHGCMHandle = NIL_RTSEMFASTMUTEX;
72
73 return VINF_SUCCESS;
74}
75
76DECLINLINE(int) vbglHandleHeapEnter(void)
77{
78 int rc = RTSemFastMutexRequest(mutexHGCMHandle);
79
80 VBGL_HGCM_ASSERT_MSG(RT_SUCCESS(rc), ("Failed to request handle heap mutex, rc = %Rrc\n", rc));
81
82 return rc;
83}
84
85DECLINLINE(void) vbglHandleHeapLeave(void)
86{
87 RTSemFastMutexRelease(mutexHGCMHandle);
88}
89
90struct VBGLHGCMHANDLEDATA *vbglHGCMHandleAlloc(void)
91{
92 struct VBGLHGCMHANDLEDATA *p = NULL;
93 int rc = vbglHandleHeapEnter();
94 if (RT_SUCCESS(rc))
95 {
96 uint32_t i;
97
98 /* Simple linear search in array. This will be called not so often, only connect/disconnect. */
99 /** @todo bitmap for faster search and other obvious optimizations. */
100 for (i = 0; i < RT_ELEMENTS(aHGCMHandleData); i++)
101 {
102 if (!aHGCMHandleData[i].fAllocated)
103 {
104 p = &aHGCMHandleData[i];
105 p->fAllocated = 1;
106 break;
107 }
108 }
109
110 vbglHandleHeapLeave();
111
112 VBGL_HGCM_ASSERT_MSG(p != NULL, ("Not enough HGCM handles.\n"));
113 }
114 return p;
115}
116
117void vbglHGCMHandleFree(struct VBGLHGCMHANDLEDATA *pHandle)
118{
119 if (pHandle)
120 {
121 int rc = vbglHandleHeapEnter();
122 if (RT_SUCCESS(rc))
123 {
124 VBGL_HGCM_ASSERT_MSG(pHandle->fAllocated, ("Freeing not allocated handle.\n"));
125
126 RT_ZERO(*pHandle);
127 vbglHandleHeapLeave();
128 }
129 }
130}
131
132DECLVBGL(int) VbglHGCMConnect(VBGLHGCMHANDLE *pHandle, VBoxGuestHGCMConnectInfo *pData)
133{
134 int rc;
135 if (pHandle && pData)
136 {
137 struct VBGLHGCMHANDLEDATA *pHandleData = vbglHGCMHandleAlloc();
138 if (pHandleData)
139 {
140 rc = vbglDriverOpen(&pHandleData->driver);
141 if (RT_SUCCESS(rc))
142 {
143 rc = vbglDriverIOCtl(&pHandleData->driver, VBOXGUEST_IOCTL_HGCM_CONNECT, pData, sizeof(*pData));
144 if (RT_SUCCESS(rc))
145 rc = pData->result;
146 if (RT_SUCCESS(rc))
147 {
148 *pHandle = pHandleData;
149 return rc;
150 }
151
152 vbglDriverClose(&pHandleData->driver);
153 }
154
155 vbglHGCMHandleFree(pHandleData);
156 }
157 else
158 rc = VERR_NO_MEMORY;
159 }
160 else
161 rc = VERR_INVALID_PARAMETER;
162 return rc;
163}
164
165DECLVBGL(int) VbglHGCMDisconnect(VBGLHGCMHANDLE handle, VBoxGuestHGCMDisconnectInfo *pData)
166{
167 int rc = vbglDriverIOCtl(&handle->driver, VBOXGUEST_IOCTL_HGCM_DISCONNECT, pData, sizeof(*pData));
168
169 vbglDriverClose(&handle->driver);
170
171 vbglHGCMHandleFree(handle);
172
173 return rc;
174}
175
176DECLVBGL(int) VbglHGCMCall(VBGLHGCMHANDLE handle, VBoxGuestHGCMCallInfo *pData, uint32_t cbData)
177{
178 VBGL_HGCM_ASSERT_MSG(cbData >= sizeof(VBoxGuestHGCMCallInfo) + pData->cParms * sizeof(HGCMFunctionParameter),
179 ("cbData = %d, cParms = %d (calculated size %d)\n", cbData, pData->cParms,
180 sizeof(VBoxGuestHGCMCallInfo) + pData->cParms * sizeof(VBoxGuestHGCMCallInfo)));
181
182 return vbglDriverIOCtl(&handle->driver, VBOXGUEST_IOCTL_HGCM_CALL(cbData), pData, cbData);
183}
184
185DECLVBGL(int) VbglHGCMCallUserData (VBGLHGCMHANDLE handle, VBoxGuestHGCMCallInfo *pData, uint32_t cbData)
186{
187 VBGL_HGCM_ASSERT_MSG(cbData >= sizeof(VBoxGuestHGCMCallInfo) + pData->cParms * sizeof(HGCMFunctionParameter),
188 ("cbData = %d, cParms = %d (calculated size %d)\n", cbData, pData->cParms,
189 sizeof(VBoxGuestHGCMCallInfo) + pData->cParms * sizeof(VBoxGuestHGCMCallInfo)));
190
191 return vbglDriverIOCtl(&handle->driver, VBOXGUEST_IOCTL_HGCM_CALL_USERDATA(cbData), pData, cbData);
192}
193
194
195DECLVBGL(int) VbglHGCMCallTimed(VBGLHGCMHANDLE handle, VBoxGuestHGCMCallInfoTimed *pData, uint32_t cbData)
196{
197 uint32_t cbExpected = sizeof(VBoxGuestHGCMCallInfoTimed)
198 + pData->info.cParms * sizeof(HGCMFunctionParameter);
199 VBGL_HGCM_ASSERT_MSG(cbData >= cbExpected,
200 ("cbData = %d, cParms = %d (calculated size %d)\n", cbData, pData->info.cParms, cbExpected));
201 NOREF(cbExpected);
202
203 return vbglDriverIOCtl(&handle->driver, VBOXGUEST_IOCTL_HGCM_CALL_TIMED(cbData), pData, cbData);
204}
205
206#endif /* !VBGL_VBOXGUEST */
207
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette