VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedOpenGL/service.cpp@ 4388

Last change on this file since 4388 was 4071, checked in by vboxsync, 17 years ago

Biggest check-in ever. New source code headers for all (C) innotek files.

File size: 11.8 KB
Line 
1/** @file
2 * VBox OpenGL: Host service entry points.
3 */
4
5/*
6 * Copyright (C) 2006-2007 innotek GmbH
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License as published by the Free Software Foundation,
12 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
13 * distribution. VirtualBox OSE is distributed in the hope that it will
14 * be useful, but WITHOUT ANY WARRANTY of any kind.
15 */
16
17#include <iprt/alloc.h>
18#include <iprt/string.h>
19#include <iprt/assert.h>
20#include <VBox/ssm.h>
21#define LOG_GROUP LOG_GROUP_SHARED_OPENGL
22#include <VBox/log.h>
23
24#include "vboxgl.h"
25#include "gldrv.h"
26
27
28PVBOXHGCMSVCHELPERS g_pHelpers;
29
30
31static DECLCALLBACK(int) svcUnload (void)
32{
33 int rc = VINF_SUCCESS;
34
35 Log(("svcUnload\n"));
36
37 vboxglGlobalUnload();
38 return rc;
39}
40
41static DECLCALLBACK(int) svcConnect (uint32_t u32ClientID, void *pvClient)
42{
43 int rc = VINF_SUCCESS;
44
45 NOREF(u32ClientID);
46 NOREF(pvClient);
47
48 Log(("svcConnect: u32ClientID = %d\n", u32ClientID));
49
50 vboxglConnect((PVBOXOGLCTX)pvClient);
51 return rc;
52}
53
54static DECLCALLBACK(int) svcDisconnect (uint32_t u32ClientID, void *pvClient)
55{
56 int rc = VINF_SUCCESS;
57 VBOXOGLCTX *pClient = (VBOXOGLCTX *)pvClient;
58
59 NOREF(pClient);
60
61 Log(("svcDisconnect: u32ClientID = %d\n", u32ClientID));
62 vboxglDisconnect((PVBOXOGLCTX)pvClient);
63 return rc;
64}
65
66/**
67 * We can't save the OpenGL state, so there's not much to do. Perhaps we should invalidate the client id?
68 */
69static DECLCALLBACK(int) svcSaveState(uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM)
70{
71 VBOXOGLCTX *pClient = (VBOXOGLCTX *)pvClient;
72
73 NOREF(pClient);
74 NOREF(pSSM);
75
76 Log(("svcSaveState: u32ClientID = %d\n", u32ClientID));
77
78 return VINF_SUCCESS;
79}
80
81static DECLCALLBACK(int) svcLoadState(uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM)
82{
83 VBOXOGLCTX *pClient = (VBOXOGLCTX *)pvClient;
84
85 NOREF(pClient);
86 NOREF(pSSM);
87
88 Log(("svcLoadState: u32ClientID = %d\n", u32ClientID));
89
90 return VINF_SUCCESS;
91}
92
93static DECLCALLBACK(void) svcCall (VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID, void *pvClient, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
94{
95 int rc = VINF_SUCCESS;
96
97 Log(("svcCall: u32ClientID = %d, fn = %d, cParms = %d, pparms = %d\n", u32ClientID, u32Function, cParms, paParms));
98
99 VBOXOGLCTX *pClient = (VBOXOGLCTX *)pvClient;
100
101#ifdef DEBUG
102 uint32_t i;
103
104 for (i = 0; i < cParms; i++)
105 {
106 /** @todo parameters other than 32 bit */
107 Log((" pparms[%d]: type %d value %d\n", i, paParms[i].type, paParms[i].u.uint32));
108 }
109#endif
110
111 switch (u32Function)
112 {
113 case VBOXOGL_FN_GLGETSTRING:
114 {
115 Log(("svcCall: VBOXOGL_FN_GLGETSTRING\n"));
116
117 /* Verify parameter count and types. */
118 if (cParms != VBOXOGL_CPARMS_GLGETSTRING)
119 {
120 rc = VERR_INVALID_PARAMETER;
121 }
122 else
123 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* name */
124 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR /* string */
125 )
126 {
127 rc = VERR_INVALID_PARAMETER;
128 }
129 else
130 {
131 /* Fetch parameters. */
132 uint32_t name = paParms[0].u.uint32;
133 char *pString = (char *)paParms[1].u.pointer.addr;
134 uint32_t cbString = paParms[1].u.pointer.size;
135
136 /* Verify parameters values. */
137 if ( (cbString < 32)
138 )
139 {
140 rc = VERR_INVALID_PARAMETER;
141 }
142 else
143 {
144 /* Execute the function. */
145 rc = vboxglGetString(pClient, name, pString, &cbString);
146
147 if (VBOX_SUCCESS(rc))
148 {
149 /* Update parameters.*/
150 paParms[1].u.pointer.size = cbString;
151 }
152 }
153 }
154 break;
155 }
156
157 case VBOXOGL_FN_GLFLUSH:
158 {
159 Log(("svcCall: VBOXOGL_FN_GLFLUSH\n"));
160
161 /* Verify parameter count and types. */
162 if (cParms != VBOXOGL_CPARMS_GLFLUSH)
163 {
164 rc = VERR_INVALID_PARAMETER;
165 }
166 else
167 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pCmdBuffer */
168 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* cCommands */
169 || paParms[2].type != VBOX_HGCM_SVC_PARM_64BIT /* retval */
170 || paParms[3].type != VBOX_HGCM_SVC_PARM_32BIT /* lasterror */
171 )
172 {
173 rc = VERR_INVALID_PARAMETER;
174 }
175 else
176 {
177 /* Fetch parameters. */
178 uint8_t *pCmdBuffer = (uint8_t *)paParms[0].u.pointer.addr;
179 uint32_t cbCmdBuffer = paParms[0].u.pointer.size;
180 uint32_t cCommands = paParms[1].u.uint32;
181 GLenum lasterror;
182 uint64_t lastretval;
183
184 /* Execute the function. */
185 rc = vboxglFlushBuffer(pClient, pCmdBuffer, cbCmdBuffer, cCommands, &lasterror, &lastretval);
186
187 if (VBOX_SUCCESS(rc))
188 {
189 /* Update parameters.*/
190 paParms[2].u.uint64 = lastretval;
191 paParms[3].u.uint32 = lasterror;
192 }
193 }
194 break;
195 }
196
197 case VBOXOGL_FN_GLFLUSHPTR:
198 {
199 Log(("svcCall: VBOXOGL_FN_GLFLUSHPTR\n"));
200
201 /* Verify parameter count and types. */
202 if (cParms != VBOXOGL_CPARMS_GLFLUSHPTR)
203 {
204 rc = VERR_INVALID_PARAMETER;
205 }
206 else
207 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pCmdBuffer */
208 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* cCommands */
209 || ( paParms[2].type != VBOX_HGCM_SVC_PARM_PTR /* pLastParam */
210 && paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT) /* pLastParam if NULL */
211 || paParms[3].type != VBOX_HGCM_SVC_PARM_64BIT /* retval */
212 || paParms[4].type != VBOX_HGCM_SVC_PARM_32BIT /* lasterror */
213 )
214 {
215 rc = VERR_INVALID_PARAMETER;
216 }
217 else
218 {
219 /* Fetch parameters. */
220 uint8_t *pCmdBuffer = (uint8_t *)paParms[0].u.pointer.addr;
221 uint32_t cbCmdBuffer = paParms[0].u.pointer.size;
222 uint32_t cCommands = paParms[1].u.uint32;
223 GLenum lasterror;
224 uint64_t lastretval;
225
226 /* Save the last parameter of the last command in the client structure so the macro can pick it up there */
227 if (paParms[2].type == VBOX_HGCM_SVC_PARM_32BIT)
228 {
229 /* HGCM doesn't like NULL pointers. */
230 pClient->pLastParam = NULL;
231 pClient->cbLastParam = 0;
232 }
233 else
234 {
235 pClient->pLastParam = (uint8_t *)paParms[2].u.pointer.addr;
236 pClient->cbLastParam = paParms[2].u.pointer.size;
237 }
238
239 /* Execute the function. */
240 rc = vboxglFlushBuffer(pClient, pCmdBuffer, cbCmdBuffer, cCommands, &lasterror, &lastretval);
241
242 /* Clear last parameter info again */
243 pClient->pLastParam = 0;
244 pClient->cbLastParam = 0;
245
246 if (VBOX_SUCCESS(rc))
247 {
248 /* Update parameters.*/
249 paParms[3].u.uint64 = lastretval;
250 paParms[4].u.uint32 = lasterror;
251 }
252 }
253 break;
254 }
255
256 case VBOXOGL_FN_GLCHECKEXT:
257 {
258 Log(("svcCall: VBOXOGL_FN_GLCHECKEXT\n"));
259
260 /* Verify parameter count and types. */
261 if (cParms != VBOXOGL_CPARMS_GLCHECKEXT)
262 {
263 rc = VERR_INVALID_PARAMETER;
264 }
265 else
266 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pszExtFnName */
267 )
268 {
269 rc = VERR_INVALID_PARAMETER;
270 }
271 else
272 {
273 /* Fetch parameters. */
274 char *pszExtFnName = (char *)paParms[0].u.pointer.addr;
275 uint32_t cbExtFnName = paParms[0].u.pointer.size; /* size including null terminator */
276
277 /* sanity checks */
278 if ( cbExtFnName > 256
279 || pszExtFnName[cbExtFnName-1] != 0
280 )
281 {
282 rc = VERR_INVALID_PARAMETER;
283 }
284 else
285 {
286#ifdef RT_OS_WINDOWS
287 /* Execute the function. */
288 if (vboxwglGetProcAddress(pszExtFnName))
289 rc = VINF_SUCCESS;
290 else
291 rc = VERR_FILE_NOT_FOUND;
292#else
293 rc = VERR_FILE_NOT_FOUND;
294#endif
295 if (VBOX_SUCCESS(rc))
296 {
297 /* Update parameters.*/
298 }
299 }
300 }
301 break;
302 }
303
304 default:
305 {
306 rc = VERR_NOT_IMPLEMENTED;
307 }
308 }
309
310 LogFlow(("svcCall: rc = %Vrc\n", rc));
311
312 g_pHelpers->pfnCallComplete (callHandle, rc);
313}
314
315/*
316 * We differentiate between a function handler for the guest and one for the host. The guest is not allowed to add or remove mappings for obvious security reasons.
317 */
318static DECLCALLBACK(int) svcHostCall (uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
319{
320 int rc = VINF_SUCCESS;
321
322 Log(("svcHostCall: fn = %d, cParms = %d, pparms = %d\n", u32Function, cParms, paParms));
323
324#ifdef DEBUG
325 uint32_t i;
326
327 for (i = 0; i < cParms; i++)
328 {
329 /** @todo parameters other than 32 bit */
330 Log((" pparms[%d]: type %d value %d\n", i, paParms[i].type, paParms[i].u.uint32));
331 }
332#endif
333
334 switch (u32Function)
335 {
336 default:
337 rc = VERR_NOT_IMPLEMENTED;
338 break;
339 }
340
341 LogFlow(("svcHostCall: rc = %Vrc\n", rc));
342 return rc;
343}
344
345extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad (VBOXHGCMSVCFNTABLE *ptable)
346{
347 int rc = VINF_SUCCESS;
348
349 Log(("VBoxHGCMSvcLoad: ptable = %p\n", ptable));
350
351 if (!ptable)
352 {
353 rc = VERR_INVALID_PARAMETER;
354 }
355 else
356 {
357 Log(("VBoxHGCMSvcLoad: ptable->cbSize = %d, ptable->u32Version = 0x%08X\n", ptable->cbSize, ptable->u32Version));
358
359 if ( ptable->cbSize != sizeof (VBOXHGCMSVCFNTABLE)
360 || ptable->u32Version != VBOX_HGCM_SVC_VERSION)
361 {
362 rc = VERR_INVALID_PARAMETER;
363 }
364 else
365 {
366 g_pHelpers = ptable->pHelpers;
367
368 ptable->cbClient = sizeof (VBOXOGLCTX);
369
370 ptable->pfnUnload = svcUnload;
371 ptable->pfnConnect = svcConnect;
372 ptable->pfnDisconnect = svcDisconnect;
373 ptable->pfnCall = svcCall;
374 ptable->pfnHostCall = svcHostCall;
375 ptable->pfnSaveState = svcSaveState;
376 ptable->pfnLoadState = svcLoadState;
377
378 vboxglGlobalInit();
379 }
380 }
381
382 return rc;
383}
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