VirtualBox

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

Last change on this file since 93115 was 93115, checked in by vboxsync, 3 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.4 KB
Line 
1/* $Id: VBoxGuestR0LibHGCM.cpp 93115 2022-01-01 11:31:46Z vboxsync $ */
2/** @file
3 * VBoxGuestLib - Host-Guest Communication Manager, ring-0 client drivers.
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-2022 Oracle Corporation
11 *
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:
20 *
21 * The above copyright notice and this permission notice shall be
22 * included in all copies or substantial portions of the Software.
23 *
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.
32 */
33
34
35/*********************************************************************************************************************************
36* Header Files *
37*********************************************************************************************************************************/
38#include "VBoxGuestR0LibInternal.h"
39
40#include <iprt/assert.h>
41#include <iprt/semaphore.h>
42#include <iprt/string.h>
43#include <VBox/err.h>
44
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*********************************************************************************************************************************/
53#define VBGL_HGCM_ASSERT_MSG AssertReleaseMsg
54
55
56/*********************************************************************************************************************************
57* Global Variables *
58*********************************************************************************************************************************/
59/**
60 * Fast heap for HGCM handles data.
61 * @{
62 */
63static RTSEMFASTMUTEX g_hMtxHGCMHandleData;
64static struct VBGLHGCMHANDLEDATA g_aHGCMHandleData[64];
65/** @} */
66
67
68/**
69 * Initializes the HGCM VBGL bits.
70 *
71 * @return VBox status code.
72 */
73DECLR0VBGL(int) VbglR0HGCMInit(void)
74{
75 AssertReturn(g_hMtxHGCMHandleData == NIL_RTSEMFASTMUTEX, VINF_ALREADY_INITIALIZED);
76 return RTSemFastMutexCreate(&g_hMtxHGCMHandleData);
77}
78
79/**
80 * Initializes the HGCM VBGL bits.
81 *
82 * @return VBox status code.
83 */
84DECLR0VBGL(int) VbglR0HGCMTerminate(void)
85{
86 RTSemFastMutexDestroy(g_hMtxHGCMHandleData);
87 g_hMtxHGCMHandleData = NIL_RTSEMFASTMUTEX;
88
89 return VINF_SUCCESS;
90}
91
92DECLINLINE(int) vbglR0HandleHeapEnter(void)
93{
94 int rc = RTSemFastMutexRequest(g_hMtxHGCMHandleData);
95
96 VBGL_HGCM_ASSERT_MSG(RT_SUCCESS(rc), ("Failed to request handle heap mutex, rc = %Rrc\n", rc));
97
98 return rc;
99}
100
101DECLINLINE(void) vbglR0HandleHeapLeave(void)
102{
103 RTSemFastMutexRelease(g_hMtxHGCMHandleData);
104}
105
106struct VBGLHGCMHANDLEDATA *vbglR0HGCMHandleAlloc(void)
107{
108 struct VBGLHGCMHANDLEDATA *p = NULL;
109 int rc = vbglR0HandleHeapEnter();
110 if (RT_SUCCESS(rc))
111 {
112 uint32_t i;
113
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. */
116 for (i = 0; i < RT_ELEMENTS(g_aHGCMHandleData); i++)
117 {
118 if (!g_aHGCMHandleData[i].fAllocated)
119 {
120 p = &g_aHGCMHandleData[i];
121 p->fAllocated = 1;
122 break;
123 }
124 }
125
126 vbglR0HandleHeapLeave();
127
128 VBGL_HGCM_ASSERT_MSG(p != NULL, ("Not enough HGCM handles.\n"));
129 }
130 return p;
131}
132
133void vbglR0HGCMHandleFree(struct VBGLHGCMHANDLEDATA *pHandle)
134{
135 if (pHandle)
136 {
137 int rc = vbglR0HandleHeapEnter();
138 if (RT_SUCCESS(rc))
139 {
140 VBGL_HGCM_ASSERT_MSG(pHandle->fAllocated, ("Freeing not allocated handle.\n"));
141
142 RT_ZERO(*pHandle);
143 vbglR0HandleHeapLeave();
144 }
145 }
146}
147
148DECLR0VBGL(int) VbglR0HGCMConnect(VBGLHGCMHANDLE *pHandle, const char *pszServiceName, HGCMCLIENTID *pidClient)
149{
150 int rc;
151 if (pHandle && pszServiceName && pidClient)
152 {
153 struct VBGLHGCMHANDLEDATA *pHandleData = vbglR0HGCMHandleAlloc();
154 if (pHandleData)
155 {
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*/);
160 if (RT_SUCCESS(rc))
161 {
162 VBGLIOCHGCMCONNECT Info;
163 RT_ZERO(Info);
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);
167 if (RT_SUCCESS(rc))
168 {
169 rc = VbglR0IdcCall(&pHandleData->IdcHandle, VBGL_IOCTL_HGCM_CONNECT, &Info.Hdr, sizeof(Info));
170 if (RT_SUCCESS(rc))
171 {
172 *pidClient = Info.u.Out.idClient;
173 *pHandle = pHandleData;
174 return rc;
175 }
176 }
177
178 VbglR0IdcClose(&pHandleData->IdcHandle);
179 }
180
181 vbglR0HGCMHandleFree(pHandleData);
182 }
183 else
184 rc = VERR_NO_MEMORY;
185 }
186 else
187 rc = VERR_INVALID_PARAMETER;
188 return rc;
189}
190
191DECLR0VBGL(int) VbglR0HGCMDisconnect(VBGLHGCMHANDLE handle, HGCMCLIENTID idClient)
192{
193 int rc;
194 VBGLIOCHGCMDISCONNECT Info;
195
196 RT_ZERO(Info);
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));
200
201 VbglR0IdcClose(&handle->IdcHandle);
202
203 vbglR0HGCMHandleFree(handle);
204
205 return rc;
206}
207
208DECLR0VBGL(int) VbglR0HGCMCallRaw(VBGLHGCMHANDLE handle, PVBGLIOCHGCMCALL pData, uint32_t cbData)
209{
210 VBGL_HGCM_ASSERT_MSG(cbData >= sizeof(VBGLIOCHGCMCALL) + pData->cParms * sizeof(HGCMFunctionParameter),
211 ("cbData = %d, cParms = %d (calculated size %d)\n", cbData, pData->cParms,
212 sizeof(VBGLIOCHGCMCALL) + pData->cParms * sizeof(VBGLIOCHGCMCALL)));
213
214 return VbglR0IdcCallRaw(&handle->IdcHandle, VBGL_IOCTL_HGCM_CALL(cbData), &pData->Hdr, cbData);
215}
216
217DECLR0VBGL(int) VbglR0HGCMCall(VBGLHGCMHANDLE handle, PVBGLIOCHGCMCALL pData, uint32_t cbData)
218{
219 int rc = VbglR0HGCMCallRaw(handle, pData, cbData);
220 if (RT_SUCCESS(rc))
221 rc = pData->Hdr.rc;
222 return rc;
223}
224
225DECLR0VBGL(int) VbglR0HGCMCallUserDataRaw(VBGLHGCMHANDLE handle, PVBGLIOCHGCMCALL pData, uint32_t cbData)
226{
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)));
230
231 return VbglR0IdcCallRaw(&handle->IdcHandle, VBGL_IOCTL_HGCM_CALL_WITH_USER_DATA(cbData), &pData->Hdr, cbData);
232}
233
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.

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