VirtualBox

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

Last change on this file since 4968 was 4071, checked in by vboxsync, 17 years ago

Biggest check-in ever. New source code headers for all (C) innotek files.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.4 KB
Line 
1/** @file
2 *
3 * VBoxGuestLib - A support library for VirtualBox guest additions:
4 * Host-Guest Communication Manager
5 */
6
7/*
8 * Copyright (C) 2006-2007 innotek GmbH
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License as published by the Free Software Foundation,
14 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
15 * distribution. VirtualBox OSE is distributed in the hope that it will
16 * be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19/* These public functions can be only used by other drivers.
20 * They all do an IOCTL to VBoxGuest.
21 */
22
23/* Entire file is ifdef'ed with !VBGL_VBOXGUEST */
24#ifndef VBGL_VBOXGUEST
25
26#include <VBox/VBoxGuestLib.h>
27#include "VBGLInternal.h"
28
29#include <iprt/assert.h>
30#include <iprt/semaphore.h>
31#include <iprt/string.h>
32
33#define VBGL_HGCM_ASSERTMsg AssertReleaseMsg
34
35int vbglHGCMInit (void)
36{
37 RTSemFastMutexCreate(&g_vbgldata.mutexHGCMHandle);
38
39 return VINF_SUCCESS;
40}
41
42int vbglHGCMTerminate (void)
43{
44 RTSemFastMutexDestroy(g_vbgldata.mutexHGCMHandle);
45
46 return VINF_SUCCESS;
47}
48
49DECLINLINE(int) vbglHandleHeapEnter (void)
50{
51 int rc = RTSemFastMutexRequest(g_vbgldata.mutexHGCMHandle);
52
53 VBGL_HGCM_ASSERTMsg(VBOX_SUCCESS(rc),
54 ("Failed to request handle heap mutex, rc = %Vrc\n", rc));
55
56 return rc;
57}
58
59DECLINLINE(void) vbglHandleHeapLeave (void)
60{
61 RTSemFastMutexRelease(g_vbgldata.mutexHGCMHandle);
62}
63
64struct VBGLHGCMHANDLEDATA *vbglHGCMHandleAlloc (void)
65{
66 struct VBGLHGCMHANDLEDATA *p;
67 int rc = vbglHandleHeapEnter ();
68 uint32_t i;
69
70 if (VBOX_FAILURE (rc))
71 return NULL;
72
73 p = NULL;
74
75 /** Simple linear search in array. This will be called not so often, only connect/disconnect.
76 * @todo bitmap for faster search and other obvious optimizations.
77 */
78
79 for (i = 0; i < ELEMENTS(g_vbgldata.aHGCMHandleData); i++)
80 {
81 if (!g_vbgldata.aHGCMHandleData[i].fAllocated)
82 {
83 p = &g_vbgldata.aHGCMHandleData[i];
84 p->fAllocated = 1;
85 break;
86 }
87 }
88
89 vbglHandleHeapLeave ();
90
91 VBGL_HGCM_ASSERTMsg(p != NULL,
92 ("Not enough HGCM handles.\n"));
93
94 return p;
95}
96
97void vbglHGCMHandleFree (struct VBGLHGCMHANDLEDATA *pHandle)
98{
99 int rc;
100
101 if (!pHandle)
102 return;
103
104 rc = vbglHandleHeapEnter ();
105
106 if (VBOX_FAILURE (rc))
107 return;
108
109 VBGL_HGCM_ASSERTMsg(pHandle->fAllocated,
110 ("Freeing not allocated handle.\n"));
111
112 memset(pHandle, 0, sizeof (struct VBGLHGCMHANDLEDATA));
113 vbglHandleHeapLeave ();
114 return;
115}
116
117DECLVBGL(int) VbglHGCMConnect (VBGLHGCMHANDLE *pHandle, VBoxGuestHGCMConnectInfo *pData)
118{
119 int rc;
120 struct VBGLHGCMHANDLEDATA *pHandleData;
121
122 if (!pHandle || !pData)
123 return VERR_INVALID_PARAMETER;
124
125 pHandleData = vbglHGCMHandleAlloc ();
126
127 rc = VINF_SUCCESS;
128
129 if (!pHandleData)
130 {
131 rc = VERR_NO_MEMORY;
132 }
133 else
134 {
135 rc = vbglDriverOpen (&pHandleData->driver);
136
137 if (VBOX_SUCCESS(rc))
138 {
139 rc = vbglDriverIOCtl (&pHandleData->driver, IOCTL_VBOXGUEST_HGCM_CONNECT, pData, sizeof (*pData));
140
141 if (VBOX_SUCCESS(rc))
142 {
143 *pHandle = pHandleData;
144 }
145 else
146 {
147 vbglDriverClose (&pHandleData->driver);
148 }
149 }
150
151 if (VBOX_FAILURE(rc))
152 {
153 vbglHGCMHandleFree (pHandleData);
154 }
155 }
156
157 return rc;
158}
159
160DECLVBGL(int) VbglHGCMDisconnect (VBGLHGCMHANDLE handle, VBoxGuestHGCMDisconnectInfo *pData)
161{
162 int rc = VINF_SUCCESS;
163
164 rc = vbglDriverIOCtl (&handle->driver, IOCTL_VBOXGUEST_HGCM_DISCONNECT, pData, sizeof (*pData));
165
166 vbglDriverClose (&handle->driver);
167
168 vbglHGCMHandleFree (handle);
169
170 return rc;
171}
172
173DECLVBGL(int) VbglHGCMCall (VBGLHGCMHANDLE handle, VBoxGuestHGCMCallInfo *pData, uint32_t cbData)
174{
175 int rc = VINF_SUCCESS;
176
177 VBGL_HGCM_ASSERTMsg(cbData >= sizeof (VBoxGuestHGCMCallInfo) + pData->cParms * sizeof (HGCMFunctionParameter),
178 ("cbData = %d, cParms = %d (calculated size %d)\n", cbData, pData->cParms, sizeof (VBoxGuestHGCMCallInfo) + pData->cParms * sizeof (VBoxGuestHGCMCallInfo)));
179
180 rc = vbglDriverIOCtl (&handle->driver, IOCTL_VBOXGUEST_HGCM_CALL, pData, cbData);
181
182 return rc;
183}
184
185#endif /* VBGL_VBOXGUEST */
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