VirtualBox

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

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

some cleanup

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