VirtualBox

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

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

fixed includes

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette