VirtualBox

source: vbox/trunk/src/VBox/Additions/common/VBoxGuestLib/HGCMInternal.cpp@ 1959

Last change on this file since 1959 was 1554, checked in by vboxsync, 18 years ago

Logging update

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.9 KB
Line 
1/** @file
2 *
3 * VBoxGuestLib - A support library for VirtualBox guest additions:
4 * Host-Guest Communication Manager internal functions, implemented by VBoxGuest
5 */
6
7/*
8 * Copyright (C) 2006 InnoTek Systemberatung 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 * If you received this file as part of a commercial VirtualBox
19 * distribution, then only the terms of your commercial VirtualBox
20 * license agreement apply instead of the previous paragraph.
21 */
22
23/* Entire file is ifdef'ed with VBGL_VBOXGUEST */
24#ifdef VBGL_VBOXGUEST
25
26/** @todo r=bird: These two issues with string.h and bool are handled by
27 * iprt/string.h and iprt/types.h respectivly. Please change after the release. */
28#if defined(__LINUX__) && defined(__KERNEL__)
29#ifndef bool /* Linux 2.6.19 C++ nightmare */
30#define bool bool_type
31#define true true_type
32#define false false_type
33#define _Bool int
34#define bool_HGCMInternal_cpp
35#endif
36#include <linux/string.h>
37#ifdef bool_HGCMInternal_cpp
38#undef bool
39#undef true
40#undef false
41#undef _Bool
42#undef bool_HGCMInternal_cpp
43#endif
44#else
45#include <string.h>
46#endif
47#include <VBox/VBoxGuestLib.h>
48#include "VBGLInternal.h"
49#include <iprt/assert.h>
50
51/* These functions can be only used by VBoxGuest. */
52
53DECLVBGL(int) VbglHGCMConnect (VBoxGuestHGCMConnectInfo *pConnectInfo,
54 VBGLHGCMCALLBACK *pAsyncCallback, void *pvAsyncData,
55 uint32_t u32AsyncData)
56{
57 VMMDevHGCMConnect *pHGCMConnect;
58 int rc;
59
60 if (!pConnectInfo || !pAsyncCallback)
61 {
62 return VERR_INVALID_PARAMETER;
63 }
64
65 pHGCMConnect = NULL;
66
67 /* Allocate request */
68 rc = VbglGRAlloc ((VMMDevRequestHeader **)&pHGCMConnect, sizeof (VMMDevHGCMConnect), VMMDevReq_HGCMConnect);
69
70 if (VBOX_SUCCESS(rc))
71 {
72 /* Initialize request memory */
73 pHGCMConnect->header.fu32Flags = 0;
74
75 memcpy (&pHGCMConnect->loc, &pConnectInfo->Loc, sizeof (HGCMServiceLocation));
76 pHGCMConnect->u32ClientID = 0;
77
78 /* Issue request */
79 rc = VbglGRPerform (&pHGCMConnect->header.header);
80
81 if (VBOX_SUCCESS(rc))
82 {
83 /* Check if host decides to process the request asynchronously. */
84 if (rc == VINF_HGCM_ASYNC_EXECUTE)
85 {
86 /* Wait for request completion interrupt notification from host */
87 pAsyncCallback (&pHGCMConnect->header, pvAsyncData, u32AsyncData);
88 }
89
90 pConnectInfo->result = pHGCMConnect->header.result;
91
92 if (VBOX_SUCCESS (pConnectInfo->result))
93 {
94 pConnectInfo->u32ClientID = pHGCMConnect->u32ClientID;
95 }
96 }
97
98 VbglGRFree (&pHGCMConnect->header.header);
99 }
100
101 return rc;
102}
103
104
105DECLVBGL(int) VbglHGCMDisconnect (VBoxGuestHGCMDisconnectInfo *pDisconnectInfo,
106 VBGLHGCMCALLBACK *pAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData)
107{
108 VMMDevHGCMDisconnect *pHGCMDisconnect;
109 int rc;
110
111 if (!pDisconnectInfo || !pAsyncCallback)
112 {
113 return VERR_INVALID_PARAMETER;
114 }
115
116 pHGCMDisconnect = NULL;
117
118 /* Allocate request */
119 rc = VbglGRAlloc ((VMMDevRequestHeader **)&pHGCMDisconnect, sizeof (VMMDevHGCMDisconnect), VMMDevReq_HGCMDisconnect);
120
121 if (VBOX_SUCCESS(rc))
122 {
123 /* Initialize request memory */
124 pHGCMDisconnect->header.fu32Flags = 0;
125
126 pHGCMDisconnect->u32ClientID = pDisconnectInfo->u32ClientID;
127
128 /* Issue request */
129 rc = VbglGRPerform (&pHGCMDisconnect->header.header);
130
131 if (VBOX_SUCCESS(rc))
132 {
133 /* Check if host decides to process the request asynchronously. */
134 if (rc == VINF_HGCM_ASYNC_EXECUTE)
135 {
136 /* Wait for request completion interrupt notification from host */
137 pAsyncCallback (&pHGCMDisconnect->header, pvAsyncData, u32AsyncData);
138 }
139
140 pDisconnectInfo->result = pHGCMDisconnect->header.result;
141 }
142
143 VbglGRFree (&pHGCMDisconnect->header.header);
144 }
145
146 return rc;
147}
148
149
150DECLVBGL(int) VbglHGCMCall (VBoxGuestHGCMCallInfo *pCallInfo,
151 VBGLHGCMCALLBACK *pAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData)
152{
153 VMMDevHGCMCall *pHGCMCall;
154 uint32_t cbParms;
155 int rc;
156
157 if (!pCallInfo || !pAsyncCallback)
158 {
159 return VERR_INVALID_PARAMETER;
160 }
161
162 dprintf (("VbglHGCMCall: pCallInfo->cParms = %d, pHGCMCall->u32Function = %d\n", pCallInfo->cParms, pCallInfo->u32Function));
163
164 pHGCMCall = NULL;
165
166 cbParms = pCallInfo->cParms * sizeof (HGCMFunctionParameter);
167
168 /* Allocate request */
169 rc = VbglGRAlloc ((VMMDevRequestHeader **)&pHGCMCall, sizeof (VMMDevHGCMCall) + cbParms, VMMDevReq_HGCMCall);
170
171 dprintf (("VbglHGCMCall Allocated gr %p, rc = %Vrc, cbParms = %d\n", pHGCMCall, rc, cbParms));
172
173 if (VBOX_SUCCESS(rc))
174 {
175 /* Initialize request memory */
176 pHGCMCall->header.fu32Flags = 0;
177 pHGCMCall->header.result = VINF_SUCCESS;
178
179 pHGCMCall->u32ClientID = pCallInfo->u32ClientID;
180 pHGCMCall->u32Function = pCallInfo->u32Function;
181 pHGCMCall->cParms = pCallInfo->cParms;
182
183 if (cbParms)
184 {
185 memcpy (VMMDEV_HGCM_CALL_PARMS(pHGCMCall), VBOXGUEST_HGCM_CALL_PARMS(pCallInfo), cbParms);
186 }
187
188 dprintf (("calling VbglGRPerform\n"));
189
190 /* Issue request */
191 rc = VbglGRPerform (&pHGCMCall->header.header);
192
193 dprintf (("VbglGRPerform rc = %Vrc (header rc=%d)\n", rc, pHGCMCall->header.result));
194
195 /** If the call failed, but as a result of the request itself, then pretend success
196 * Upper layers will interpret the result code in the packet.
197 */
198 if (VBOX_FAILURE(rc) && rc == pHGCMCall->header.result)
199 {
200 Assert(pHGCMCall->header.fu32Flags & VBOX_HGCM_REQ_DONE);
201 rc = VINF_SUCCESS;
202 }
203
204 if (VBOX_SUCCESS(rc))
205 {
206 /* Check if host decides to process the request asynchronously. */
207 if (rc == VINF_HGCM_ASYNC_EXECUTE)
208 {
209 /* Wait for request completion interrupt notification from host */
210 pAsyncCallback (&pHGCMCall->header, pvAsyncData, u32AsyncData);
211 }
212
213 if (pHGCMCall->header.fu32Flags & VBOX_HGCM_REQ_DONE)
214 {
215 if (cbParms)
216 {
217 memcpy (VBOXGUEST_HGCM_CALL_PARMS(pCallInfo), VMMDEV_HGCM_CALL_PARMS(pHGCMCall), cbParms);
218 }
219 pCallInfo->result = pHGCMCall->header.result;
220 }
221 else
222 {
223 /* The callback returns without completing the request,
224 * that means the wait was interrrupted. That can happen
225 * if system reboots or the VBoxService ended abnormally.
226 * In both cases it is OK to just leave the allocated memory
227 * in the physical heap. The memory leak does not affect normal
228 * operations.
229 * @todo VbglGRCancel (&pHGCMCall->header.header) need to be implemented.
230 * The host will not write to the cancelled memory.
231 */
232 pHGCMCall->header.fu32Flags |= VBOX_HGCM_REQ_CANCELLED;
233 }
234 }
235
236 if ((pHGCMCall->header.fu32Flags & VBOX_HGCM_REQ_CANCELLED) == 0)
237 {
238 VbglGRFree (&pHGCMCall->header.header);
239 }
240 else
241 {
242 rc = VERR_INTERRUPTED;
243 }
244 }
245
246 return rc;
247}
248
249
250#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