VirtualBox

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

Last change on this file since 60337 was 58181, checked in by vboxsync, 9 years ago

VBoxGuestLib: Removed misunderstood common/VBoxGuestLib/VBoxGuestR0LibCrOgl.h moving the function prototypes into VBoxGuestLib.h where they belong, after correcting the prefix. Did some more positive thinking excercises.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.0 KB
Line 
1/* $Id: HGCM.cpp 58181 2015-10-12 12:54:23Z 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_ASSERT_MSG 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_ASSERT_MSG(RT_SUCCESS(rc), ("Failed to request handle heap mutex, rc = %Rrc\n", rc));
69
70 return rc;
71}
72
73DECLINLINE(void) vbglHandleHeapLeave(void)
74{
75 RTSemFastMutexRelease(g_vbgldata.mutexHGCMHandle);
76}
77
78struct VBGLHGCMHANDLEDATA *vbglHGCMHandleAlloc(void)
79{
80 struct VBGLHGCMHANDLEDATA *p = NULL;
81 int rc = vbglHandleHeapEnter();
82 if (RT_SUCCESS(rc))
83 {
84 uint32_t i;
85
86 /* Simple linear search in array. This will be called not so often, only connect/disconnect. */
87 /** @todo bitmap for faster search and other obvious optimizations. */
88 for (i = 0; i < RT_ELEMENTS(g_vbgldata.aHGCMHandleData); i++)
89 {
90 if (!g_vbgldata.aHGCMHandleData[i].fAllocated)
91 {
92 p = &g_vbgldata.aHGCMHandleData[i];
93 p->fAllocated = 1;
94 break;
95 }
96 }
97
98 vbglHandleHeapLeave();
99
100 VBGL_HGCM_ASSERT_MSG(p != NULL, ("Not enough HGCM handles.\n"));
101 }
102 return p;
103}
104
105void vbglHGCMHandleFree(struct VBGLHGCMHANDLEDATA *pHandle)
106{
107 if (pHandle)
108 {
109 int rc = vbglHandleHeapEnter();
110 if (RT_SUCCESS(rc))
111 {
112 VBGL_HGCM_ASSERT_MSG(pHandle->fAllocated, ("Freeing not allocated handle.\n"));
113
114 RT_ZERO(*pHandle);
115 vbglHandleHeapLeave();
116 }
117 }
118}
119
120DECLVBGL(int) VbglHGCMConnect(VBGLHGCMHANDLE *pHandle, VBoxGuestHGCMConnectInfo *pData)
121{
122 int rc;
123 if (pHandle && pData)
124 {
125 struct VBGLHGCMHANDLEDATA *pHandleData = vbglHGCMHandleAlloc();
126 if (pHandleData)
127 {
128 rc = vbglDriverOpen(&pHandleData->driver);
129 if (RT_SUCCESS(rc))
130 {
131 rc = vbglDriverIOCtl(&pHandleData->driver, VBOXGUEST_IOCTL_HGCM_CONNECT, pData, sizeof(*pData));
132 if (RT_SUCCESS(rc))
133 rc = pData->result;
134 if (RT_SUCCESS(rc))
135 {
136 *pHandle = pHandleData;
137 return rc;
138 }
139
140 vbglDriverClose(&pHandleData->driver);
141 }
142
143 vbglHGCMHandleFree(pHandleData);
144 }
145 else
146 rc = VERR_NO_MEMORY;
147 }
148 else
149 rc = VERR_INVALID_PARAMETER;
150 return rc;
151}
152
153DECLVBGL(int) VbglHGCMDisconnect(VBGLHGCMHANDLE handle, VBoxGuestHGCMDisconnectInfo *pData)
154{
155 int rc = vbglDriverIOCtl(&handle->driver, VBOXGUEST_IOCTL_HGCM_DISCONNECT, pData, sizeof(*pData));
156
157 vbglDriverClose(&handle->driver);
158
159 vbglHGCMHandleFree(handle);
160
161 return rc;
162}
163
164DECLVBGL(int) VbglHGCMCall(VBGLHGCMHANDLE handle, VBoxGuestHGCMCallInfo *pData, uint32_t cbData)
165{
166 VBGL_HGCM_ASSERT_MSG(cbData >= sizeof(VBoxGuestHGCMCallInfo) + pData->cParms * sizeof(HGCMFunctionParameter),
167 ("cbData = %d, cParms = %d (calculated size %d)\n", cbData, pData->cParms,
168 sizeof(VBoxGuestHGCMCallInfo) + pData->cParms * sizeof(VBoxGuestHGCMCallInfo)));
169
170 return vbglDriverIOCtl(&handle->driver, VBOXGUEST_IOCTL_HGCM_CALL(cbData), pData, cbData);
171}
172
173DECLVBGL(int) VbglHGCMCallUserData (VBGLHGCMHANDLE handle, VBoxGuestHGCMCallInfo *pData, uint32_t cbData)
174{
175 VBGL_HGCM_ASSERT_MSG(cbData >= sizeof(VBoxGuestHGCMCallInfo) + pData->cParms * sizeof(HGCMFunctionParameter),
176 ("cbData = %d, cParms = %d (calculated size %d)\n", cbData, pData->cParms,
177 sizeof(VBoxGuestHGCMCallInfo) + pData->cParms * sizeof(VBoxGuestHGCMCallInfo)));
178
179 return vbglDriverIOCtl(&handle->driver, VBOXGUEST_IOCTL_HGCM_CALL_USERDATA(cbData), pData, cbData);
180}
181
182
183DECLVBGL(int) VbglHGCMCallTimed(VBGLHGCMHANDLE handle, VBoxGuestHGCMCallInfoTimed *pData, uint32_t cbData)
184{
185 uint32_t cbExpected = sizeof(VBoxGuestHGCMCallInfoTimed)
186 + pData->info.cParms * sizeof(HGCMFunctionParameter);
187 VBGL_HGCM_ASSERT_MSG(cbData >= cbExpected,
188 ("cbData = %d, cParms = %d (calculated size %d)\n", cbData, pData->info.cParms, cbExpected));
189 NOREF(cbExpected);
190
191 return vbglDriverIOCtl(&handle->driver, VBOXGUEST_IOCTL_HGCM_CALL_TIMED(cbData), pData, cbData);
192}
193
194#endif /* !VBGL_VBOXGUEST */
195
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