VirtualBox

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

Last change on this file since 21459 was 21261, checked in by vboxsync, 15 years ago

oops.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.2 KB
Line 
1/* $Revision: 21261 $ */
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-2007 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
21 * Clara, CA 95054 USA or visit http://www.sun.com if you need
22 * additional information or have any questions.
23 */
24
25/* Entire file is ifdef'ed with !VBGL_VBOXGUEST */
26#ifndef VBGL_VBOXGUEST
27
28#include "VBGLInternal.h"
29
30#include <iprt/assert.h>
31#include <iprt/semaphore.h>
32#include <iprt/string.h>
33
34#define VBGL_HGCM_ASSERTMsg AssertReleaseMsg
35
36int vbglHGCMInit (void)
37{
38 RTSemFastMutexCreate(&g_vbgldata.mutexHGCMHandle);
39
40 return VINF_SUCCESS;
41}
42
43int vbglHGCMTerminate (void)
44{
45 RTSemFastMutexDestroy(g_vbgldata.mutexHGCMHandle);
46
47 return VINF_SUCCESS;
48}
49
50DECLINLINE(int) vbglHandleHeapEnter (void)
51{
52 int rc = RTSemFastMutexRequest(g_vbgldata.mutexHGCMHandle);
53
54 VBGL_HGCM_ASSERTMsg(RT_SUCCESS(rc),
55 ("Failed to request handle heap mutex, rc = %Rrc\n", rc));
56
57 return rc;
58}
59
60DECLINLINE(void) vbglHandleHeapLeave (void)
61{
62 RTSemFastMutexRelease(g_vbgldata.mutexHGCMHandle);
63}
64
65struct VBGLHGCMHANDLEDATA *vbglHGCMHandleAlloc (void)
66{
67 struct VBGLHGCMHANDLEDATA *p;
68 int rc = vbglHandleHeapEnter ();
69 uint32_t i;
70
71 if (RT_FAILURE (rc))
72 return NULL;
73
74 p = NULL;
75
76 /** Simple linear search in array. This will be called not so often, only connect/disconnect.
77 * @todo bitmap for faster search and other obvious optimizations.
78 */
79
80 for (i = 0; i < RT_ELEMENTS(g_vbgldata.aHGCMHandleData); i++)
81 {
82 if (!g_vbgldata.aHGCMHandleData[i].fAllocated)
83 {
84 p = &g_vbgldata.aHGCMHandleData[i];
85 p->fAllocated = 1;
86 break;
87 }
88 }
89
90 vbglHandleHeapLeave ();
91
92 VBGL_HGCM_ASSERTMsg(p != NULL,
93 ("Not enough HGCM handles.\n"));
94
95 return p;
96}
97
98void vbglHGCMHandleFree (struct VBGLHGCMHANDLEDATA *pHandle)
99{
100 int rc;
101
102 if (!pHandle)
103 return;
104
105 rc = vbglHandleHeapEnter ();
106
107 if (RT_FAILURE (rc))
108 return;
109
110 VBGL_HGCM_ASSERTMsg(pHandle->fAllocated,
111 ("Freeing not allocated handle.\n"));
112
113 memset(pHandle, 0, sizeof (struct VBGLHGCMHANDLEDATA));
114 vbglHandleHeapLeave ();
115 return;
116}
117
118DECLVBGL(int) VbglHGCMConnect (VBGLHGCMHANDLE *pHandle, VBoxGuestHGCMConnectInfo *pData)
119{
120 int rc;
121 struct VBGLHGCMHANDLEDATA *pHandleData;
122
123 if (!pHandle || !pData)
124 return VERR_INVALID_PARAMETER;
125
126 pHandleData = vbglHGCMHandleAlloc ();
127
128 rc = VINF_SUCCESS;
129
130 if (!pHandleData)
131 {
132 rc = VERR_NO_MEMORY;
133 }
134 else
135 {
136 rc = vbglDriverOpen (&pHandleData->driver);
137
138 if (RT_SUCCESS(rc))
139 {
140 rc = vbglDriverIOCtl (&pHandleData->driver, VBOXGUEST_IOCTL_HGCM_CONNECT, pData, sizeof (*pData));
141
142 if (RT_SUCCESS(rc))
143 {
144 *pHandle = pHandleData;
145 }
146 else
147 {
148 vbglDriverClose (&pHandleData->driver);
149 }
150 }
151
152 if (RT_FAILURE(rc))
153 {
154 vbglHGCMHandleFree (pHandleData);
155 }
156 }
157
158 return rc;
159}
160
161DECLVBGL(int) VbglHGCMDisconnect (VBGLHGCMHANDLE handle, VBoxGuestHGCMDisconnectInfo *pData)
162{
163 int rc = VINF_SUCCESS;
164
165 rc = vbglDriverIOCtl (&handle->driver, VBOXGUEST_IOCTL_HGCM_DISCONNECT, pData, sizeof (*pData));
166
167 vbglDriverClose (&handle->driver);
168
169 vbglHGCMHandleFree (handle);
170
171 return rc;
172}
173
174DECLVBGL(int) VbglHGCMCall (VBGLHGCMHANDLE handle, VBoxGuestHGCMCallInfo *pData, uint32_t cbData)
175{
176 int rc = VINF_SUCCESS;
177
178 VBGL_HGCM_ASSERTMsg(cbData >= sizeof (VBoxGuestHGCMCallInfo) + pData->cParms * sizeof (HGCMFunctionParameter),
179 ("cbData = %d, cParms = %d (calculated size %d)\n", cbData, pData->cParms, sizeof (VBoxGuestHGCMCallInfo) + pData->cParms * sizeof (VBoxGuestHGCMCallInfo)));
180
181 rc = vbglDriverIOCtl (&handle->driver, VBOXGUEST_IOCTL_HGCM_CALL(cbData), pData, cbData);
182
183 return rc;
184}
185
186DECLVBGL(int) VbglHGCMCallTimed (VBGLHGCMHANDLE handle,
187 VBoxGuestHGCMCallInfoTimed *pData, uint32_t cbData)
188{
189 int rc = VINF_SUCCESS;
190
191 uint32_t cbExpected = sizeof (VBoxGuestHGCMCallInfoTimed)
192 + pData->info.cParms * sizeof (HGCMFunctionParameter);
193 VBGL_HGCM_ASSERTMsg(cbData >= cbExpected,
194 ("cbData = %d, cParms = %d (calculated size %d)\n",
195 cbData, pData->info.cParms, cbExpected));
196
197 rc = vbglDriverIOCtl (&handle->driver, VBOXGUEST_IOCTL_HGCM_CALL_TIMED(cbData),
198 pData, cbData);
199
200 return rc;
201}
202
203#endif /* !VBGL_VBOXGUEST */
204
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