VirtualBox

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

Last change on this file since 28 was 1, checked in by vboxsync, 55 years ago

import

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