VirtualBox

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

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

Changed the Linux Additions to compile everything from source (no more binaries linked in) and cleaned up those files to compile as plain C.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.3 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
50/* These functions can be only used by VBoxGuest. */
51
52DECLVBGL(int) VbglHGCMConnect (VBoxGuestHGCMConnectInfo *pConnectInfo,
53 VBGLHGCMCALLBACK *pAsyncCallback, void *pvAsyncData,
54 uint32_t u32AsyncData)
55{
56 VMMDevHGCMConnect *pHGCMConnect;
57 if (!pConnectInfo || !pAsyncCallback)
58 {
59 return VERR_INVALID_PARAMETER;
60 }
61
62 pHGCMConnect = NULL;
63
64 /* Allocate request */
65 int rc = VbglGRAlloc ((VMMDevRequestHeader **)&pHGCMConnect, sizeof (VMMDevHGCMConnect), VMMDevReq_HGCMConnect);
66
67 if (VBOX_SUCCESS(rc))
68 {
69 /* Initialize request memory */
70 pHGCMConnect->header.fu32Flags = 0;
71
72 memcpy (&pHGCMConnect->loc, &pConnectInfo->Loc, sizeof (HGCMServiceLocation));
73 pHGCMConnect->u32ClientID = 0;
74
75 /* Issue request */
76 rc = VbglGRPerform (&pHGCMConnect->header.header);
77
78 if (VBOX_SUCCESS(rc))
79 {
80 /* Check if host decides to process the request asynchronously. */
81 if (rc == VINF_HGCM_ASYNC_EXECUTE)
82 {
83 /* Wait for request completion interrupt notification from host */
84 pAsyncCallback (&pHGCMConnect->header, pvAsyncData, u32AsyncData);
85 }
86
87 pConnectInfo->result = pHGCMConnect->header.result;
88
89 if (VBOX_SUCCESS (pConnectInfo->result))
90 {
91 pConnectInfo->u32ClientID = pHGCMConnect->u32ClientID;
92 }
93 }
94
95 VbglGRFree (&pHGCMConnect->header.header);
96 }
97
98 return rc;
99}
100
101
102DECLVBGL(int) VbglHGCMDisconnect (VBoxGuestHGCMDisconnectInfo *pDisconnectInfo,
103 VBGLHGCMCALLBACK *pAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData)
104{
105 VMMDevHGCMDisconnect *pHGCMDisconnect;
106 if (!pDisconnectInfo || !pAsyncCallback)
107 {
108 return VERR_INVALID_PARAMETER;
109 }
110
111 pHGCMDisconnect = NULL;
112
113 /* Allocate request */
114 int rc = VbglGRAlloc ((VMMDevRequestHeader **)&pHGCMDisconnect, sizeof (VMMDevHGCMDisconnect), VMMDevReq_HGCMDisconnect);
115
116 if (VBOX_SUCCESS(rc))
117 {
118 /* Initialize request memory */
119 pHGCMDisconnect->header.fu32Flags = 0;
120
121 pHGCMDisconnect->u32ClientID = pDisconnectInfo->u32ClientID;
122
123 /* Issue request */
124 rc = VbglGRPerform (&pHGCMDisconnect->header.header);
125
126 if (VBOX_SUCCESS(rc))
127 {
128 /* Check if host decides to process the request asynchronously. */
129 if (rc == VINF_HGCM_ASYNC_EXECUTE)
130 {
131 /* Wait for request completion interrupt notification from host */
132 pAsyncCallback (&pHGCMDisconnect->header, pvAsyncData, u32AsyncData);
133 }
134
135 pDisconnectInfo->result = pHGCMDisconnect->header.result;
136 }
137
138 VbglGRFree (&pHGCMDisconnect->header.header);
139 }
140
141 return rc;
142}
143
144
145DECLVBGL(int) VbglHGCMCall (VBoxGuestHGCMCallInfo *pCallInfo,
146 VBGLHGCMCALLBACK *pAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData)
147{
148 VMMDevHGCMCall *pHGCMCall;
149 if (!pCallInfo || !pAsyncCallback)
150 {
151 return VERR_INVALID_PARAMETER;
152 }
153
154 dprintf (("VbglHGCMCall: pCallInfo->cParms = %d, pHGCMCall->u32Function = %d\n", pCallInfo->cParms, pCallInfo->u32Function));
155
156 pHGCMCall = NULL;
157
158 uint32_t cbParms = pCallInfo->cParms * sizeof (HGCMFunctionParameter);
159
160 /* Allocate request */
161 int rc = VbglGRAlloc ((VMMDevRequestHeader **)&pHGCMCall, sizeof (VMMDevHGCMCall) + cbParms, VMMDevReq_HGCMCall);
162
163 dprintf (("VbglHGCMCall Allocated gr %p, rc = %Vrc, cbParms = %d\n", pHGCMCall, rc, cbParms));
164
165 if (VBOX_SUCCESS(rc))
166 {
167 /* Initialize request memory */
168 pHGCMCall->header.fu32Flags = 0;
169
170 pHGCMCall->u32ClientID = pCallInfo->u32ClientID;
171 pHGCMCall->u32Function = pCallInfo->u32Function;
172 pHGCMCall->cParms = pCallInfo->cParms;
173
174 if (cbParms)
175 {
176 memcpy (VMMDEV_HGCM_CALL_PARMS(pHGCMCall), VBOXGUEST_HGCM_CALL_PARMS(pCallInfo), cbParms);
177 }
178
179 dprintf (("calling VbglGRPerform\n"));
180
181 /* Issue request */
182 rc = VbglGRPerform (&pHGCMCall->header.header);
183
184 dprintf (("VbglGRPerform rc = %Vrc\n", rc));
185
186 if (VBOX_SUCCESS(rc))
187 {
188 /* Check if host decides to process the request asynchronously. */
189 if (rc == VINF_HGCM_ASYNC_EXECUTE)
190 {
191 /* Wait for request completion interrupt notification from host */
192 pAsyncCallback (&pHGCMCall->header, pvAsyncData, u32AsyncData);
193 }
194
195 if (pHGCMCall->header.fu32Flags & VBOX_HGCM_REQ_DONE)
196 {
197 if (cbParms)
198 {
199 memcpy (VBOXGUEST_HGCM_CALL_PARMS(pCallInfo), VMMDEV_HGCM_CALL_PARMS(pHGCMCall), cbParms);
200 }
201 pCallInfo->result = pHGCMCall->header.result;
202 }
203 else
204 {
205 /* The callback returns without completing the request,
206 * that means the wait was interrrupted. That can happen
207 * if system reboots or the VBoxService ended abnormally.
208 * In both cases it is OK to just leave the allocated memory
209 * in the physical heap. The memory leak does not affect normal
210 * operations.
211 * @todo VbglGRCancel (&pHGCMCall->header.header) need to be implemented.
212 * The host will not write to the cancelled memory.
213 */
214 pHGCMCall->header.fu32Flags |= VBOX_HGCM_REQ_CANCELLED;
215 }
216 }
217
218 if ((pHGCMCall->header.fu32Flags & VBOX_HGCM_REQ_CANCELLED) == 0)
219 {
220 VbglGRFree (&pHGCMCall->header.header);
221 }
222 else
223 {
224 rc = VERR_INTERRUPTED;
225 }
226 }
227
228 return rc;
229}
230
231
232#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