VirtualBox

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

Last change on this file since 58029 was 56294, checked in by vboxsync, 10 years ago

Additions/common,Additions/os2: Updated (C) year.

  • 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 56294 2015-06-09 14:26:20Z 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-2015 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_ASSERTMsg AssertReleaseMsg
40
41/**
42 * Initializes the HGCM VBGL bits.
43 *
44 * @return VBox status code.
45 */
46int vbglR0HGCMInit (void)
47{
48 return RTSemFastMutexCreate(&g_vbgldata.mutexHGCMHandle);
49}
50
51/**
52 * Initializes the HGCM VBGL bits.
53 *
54 * @return VBox status code.
55 */
56int vbglR0HGCMTerminate (void)
57{
58 RTSemFastMutexDestroy(g_vbgldata.mutexHGCMHandle);
59 g_vbgldata.mutexHGCMHandle = NIL_RTSEMFASTMUTEX;
60
61 return VINF_SUCCESS;
62}
63
64DECLINLINE(int) vbglHandleHeapEnter (void)
65{
66 int rc = RTSemFastMutexRequest(g_vbgldata.mutexHGCMHandle);
67
68 VBGL_HGCM_ASSERTMsg(RT_SUCCESS(rc),
69 ("Failed to request handle heap mutex, rc = %Rrc\n", rc));
70
71 return rc;
72}
73
74DECLINLINE(void) vbglHandleHeapLeave (void)
75{
76 RTSemFastMutexRelease(g_vbgldata.mutexHGCMHandle);
77}
78
79struct VBGLHGCMHANDLEDATA *vbglHGCMHandleAlloc (void)
80{
81 struct VBGLHGCMHANDLEDATA *p;
82 int rc = vbglHandleHeapEnter ();
83 uint32_t i;
84
85 if (RT_FAILURE (rc))
86 return NULL;
87
88 p = NULL;
89
90 /** Simple linear search in array. This will be called not so often, only connect/disconnect.
91 * @todo bitmap for faster search and other obvious optimizations.
92 */
93
94 for (i = 0; i < RT_ELEMENTS(g_vbgldata.aHGCMHandleData); i++)
95 {
96 if (!g_vbgldata.aHGCMHandleData[i].fAllocated)
97 {
98 p = &g_vbgldata.aHGCMHandleData[i];
99 p->fAllocated = 1;
100 break;
101 }
102 }
103
104 vbglHandleHeapLeave ();
105
106 VBGL_HGCM_ASSERTMsg(p != NULL,
107 ("Not enough HGCM handles.\n"));
108
109 return p;
110}
111
112void vbglHGCMHandleFree (struct VBGLHGCMHANDLEDATA *pHandle)
113{
114 int rc;
115
116 if (!pHandle)
117 return;
118
119 rc = vbglHandleHeapEnter ();
120
121 if (RT_FAILURE (rc))
122 return;
123
124 VBGL_HGCM_ASSERTMsg(pHandle->fAllocated,
125 ("Freeing not allocated handle.\n"));
126
127 memset(pHandle, 0, sizeof (struct VBGLHGCMHANDLEDATA));
128 vbglHandleHeapLeave ();
129 return;
130}
131
132DECLVBGL(int) VbglHGCMConnect (VBGLHGCMHANDLE *pHandle, VBoxGuestHGCMConnectInfo *pData)
133{
134 int rc;
135 struct VBGLHGCMHANDLEDATA *pHandleData;
136
137 if (!pHandle || !pData)
138 return VERR_INVALID_PARAMETER;
139
140 pHandleData = vbglHGCMHandleAlloc();
141 if (!pHandleData)
142 rc = VERR_NO_MEMORY;
143 else
144 {
145 rc = vbglDriverOpen (&pHandleData->driver);
146 if (RT_SUCCESS(rc))
147 {
148 rc = vbglDriverIOCtl (&pHandleData->driver, VBOXGUEST_IOCTL_HGCM_CONNECT, pData, sizeof (*pData));
149 if (RT_SUCCESS(rc))
150 rc = pData->result;
151 if (RT_SUCCESS(rc))
152 {
153 *pHandle = pHandleData;
154 return rc;
155 }
156
157 vbglDriverClose (&pHandleData->driver);
158 }
159
160 vbglHGCMHandleFree (pHandleData);
161 }
162
163 return rc;
164}
165
166DECLVBGL(int) VbglHGCMDisconnect (VBGLHGCMHANDLE handle, VBoxGuestHGCMDisconnectInfo *pData)
167{
168 int rc = VINF_SUCCESS;
169
170 rc = vbglDriverIOCtl (&handle->driver, VBOXGUEST_IOCTL_HGCM_DISCONNECT, pData, sizeof (*pData));
171
172 vbglDriverClose (&handle->driver);
173
174 vbglHGCMHandleFree (handle);
175
176 return rc;
177}
178
179DECLVBGL(int) VbglHGCMCall (VBGLHGCMHANDLE handle, VBoxGuestHGCMCallInfo *pData, uint32_t cbData)
180{
181 int rc = VINF_SUCCESS;
182
183 VBGL_HGCM_ASSERTMsg(cbData >= sizeof (VBoxGuestHGCMCallInfo) + pData->cParms * sizeof (HGCMFunctionParameter),
184 ("cbData = %d, cParms = %d (calculated size %d)\n", cbData, pData->cParms, sizeof (VBoxGuestHGCMCallInfo) + pData->cParms * sizeof (VBoxGuestHGCMCallInfo)));
185
186 rc = vbglDriverIOCtl (&handle->driver, VBOXGUEST_IOCTL_HGCM_CALL(cbData), pData, cbData);
187
188 return rc;
189}
190
191DECLVBGL(int) VbglHGCMCallUserData (VBGLHGCMHANDLE handle, VBoxGuestHGCMCallInfo *pData, uint32_t cbData)
192{
193 int rc = VINF_SUCCESS;
194
195 VBGL_HGCM_ASSERTMsg(cbData >= sizeof (VBoxGuestHGCMCallInfo) + pData->cParms * sizeof (HGCMFunctionParameter),
196 ("cbData = %d, cParms = %d (calculated size %d)\n", cbData, pData->cParms, sizeof (VBoxGuestHGCMCallInfo) + pData->cParms * sizeof (VBoxGuestHGCMCallInfo)));
197
198 rc = vbglDriverIOCtl (&handle->driver, VBOXGUEST_IOCTL_HGCM_CALL_USERDATA(cbData), pData, cbData);
199
200 return rc;
201}
202
203
204DECLVBGL(int) VbglHGCMCallTimed (VBGLHGCMHANDLE handle,
205 VBoxGuestHGCMCallInfoTimed *pData, uint32_t cbData)
206{
207 int rc = VINF_SUCCESS;
208
209 uint32_t cbExpected = sizeof (VBoxGuestHGCMCallInfoTimed)
210 + pData->info.cParms * sizeof (HGCMFunctionParameter);
211 VBGL_HGCM_ASSERTMsg(cbData >= cbExpected,
212 ("cbData = %d, cParms = %d (calculated size %d)\n",
213 cbData, pData->info.cParms, cbExpected));
214
215 rc = vbglDriverIOCtl (&handle->driver, VBOXGUEST_IOCTL_HGCM_CALL_TIMED(cbData),
216 pData, cbData);
217
218 return rc;
219}
220
221#endif /* !VBGL_VBOXGUEST */
222
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