VirtualBox

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

Last change on this file since 3539 was 3468, checked in by vboxsync, 17 years ago

Extension detection updates

File size: 11.9 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 * If you received this file as part of a commercial VirtualBox
17 * distribution, then only the terms of your commercial VirtualBox
18 * license agreement apply instead of the previous paragraph.
19 */
20
21#include <iprt/alloc.h>
22#include <iprt/string.h>
23#include <iprt/assert.h>
24#include <VBox/ssm.h>
25#define LOG_GROUP LOG_GROUP_SHARED_OPENGL
26#include <VBox/log.h>
27
28#include "vboxgl.h"
29#include "gldrv.h"
30
31
32PVBOXHGCMSVCHELPERS g_pHelpers;
33
34
35static DECLCALLBACK(int) svcUnload (void)
36{
37 int rc = VINF_SUCCESS;
38
39 Log(("svcUnload\n"));
40
41 return rc;
42}
43
44static DECLCALLBACK(int) svcConnect (uint32_t u32ClientID, void *pvClient)
45{
46 int rc = VINF_SUCCESS;
47
48 NOREF(u32ClientID);
49 NOREF(pvClient);
50
51 Log(("svcConnect: u32ClientID = %d\n", u32ClientID));
52
53 vboxglConnect((PVBOXOGLCTX)pvClient);
54 return rc;
55}
56
57static DECLCALLBACK(int) svcDisconnect (uint32_t u32ClientID, void *pvClient)
58{
59 int rc = VINF_SUCCESS;
60 VBOXOGLCTX *pClient = (VBOXOGLCTX *)pvClient;
61
62 NOREF(pClient);
63
64 Log(("svcDisconnect: u32ClientID = %d\n", u32ClientID));
65 vboxglDisconnect((PVBOXOGLCTX)pvClient);
66 return rc;
67}
68
69/**
70 * We can't save the OpenGL state, so there's not much to do. Perhaps we should invalidate the client id?
71 */
72static DECLCALLBACK(int) svcSaveState(uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM)
73{
74 VBOXOGLCTX *pClient = (VBOXOGLCTX *)pvClient;
75
76 NOREF(pClient);
77 NOREF(pSSM);
78
79 Log(("svcSaveState: u32ClientID = %d\n", u32ClientID));
80
81 return VINF_SUCCESS;
82}
83
84static DECLCALLBACK(int) svcLoadState(uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM)
85{
86 VBOXOGLCTX *pClient = (VBOXOGLCTX *)pvClient;
87
88 NOREF(pClient);
89 NOREF(pSSM);
90
91 Log(("svcLoadState: u32ClientID = %d\n", u32ClientID));
92
93 return VINF_SUCCESS;
94}
95
96static DECLCALLBACK(void) svcCall (VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID, void *pvClient, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
97{
98 int rc = VINF_SUCCESS;
99
100 Log(("svcCall: u32ClientID = %d, fn = %d, cParms = %d, pparms = %d\n", u32ClientID, u32Function, cParms, paParms));
101
102 VBOXOGLCTX *pClient = (VBOXOGLCTX *)pvClient;
103
104#ifdef DEBUG
105 uint32_t i;
106
107 for (i = 0; i < cParms; i++)
108 {
109 /** @todo parameters other than 32 bit */
110 Log((" pparms[%d]: type %d value %d\n", i, paParms[i].type, paParms[i].u.uint32));
111 }
112#endif
113
114 switch (u32Function)
115 {
116 case VBOXOGL_FN_GLGETSTRING:
117 {
118 Log(("svcCall: VBOXOGL_FN_GLGETSTRING\n"));
119
120 /* Verify parameter count and types. */
121 if (cParms != VBOXOGL_CPARMS_GLGETSTRING)
122 {
123 rc = VERR_INVALID_PARAMETER;
124 }
125 else
126 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* name */
127 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR /* string */
128 )
129 {
130 rc = VERR_INVALID_PARAMETER;
131 }
132 else
133 {
134 /* Fetch parameters. */
135 uint32_t name = paParms[0].u.uint32;
136 char *pString = (char *)paParms[1].u.pointer.addr;
137 uint32_t cbString = paParms[1].u.pointer.size;
138
139 /* Verify parameters values. */
140 if ( (cbString < 32)
141 )
142 {
143 rc = VERR_INVALID_PARAMETER;
144 }
145 else
146 {
147 /* Execute the function. */
148 rc = vboxglGetString(pClient, name, pString, &cbString);
149
150 if (VBOX_SUCCESS(rc))
151 {
152 /* Update parameters.*/
153 paParms[1].u.pointer.size = cbString;
154 }
155 }
156 }
157 break;
158 }
159
160 case VBOXOGL_FN_GLFLUSH:
161 {
162 Log(("svcCall: VBOXOGL_FN_GLFLUSH\n"));
163
164 /* Verify parameter count and types. */
165 if (cParms != VBOXOGL_CPARMS_GLFLUSH)
166 {
167 rc = VERR_INVALID_PARAMETER;
168 }
169 else
170 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pCmdBuffer */
171 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* cCommands */
172 || paParms[2].type != VBOX_HGCM_SVC_PARM_64BIT /* retval */
173 || paParms[3].type != VBOX_HGCM_SVC_PARM_32BIT /* lasterror */
174 )
175 {
176 rc = VERR_INVALID_PARAMETER;
177 }
178 else
179 {
180 /* Fetch parameters. */
181 uint8_t *pCmdBuffer = (uint8_t *)paParms[0].u.pointer.addr;
182 uint32_t cbCmdBuffer = paParms[0].u.pointer.size;
183 uint32_t cCommands = paParms[1].u.uint32;
184 GLenum lasterror;
185 uint64_t lastretval;
186
187 /* Execute the function. */
188 rc = vboxglFlushBuffer(pClient, pCmdBuffer, cbCmdBuffer, cCommands, &lasterror, &lastretval);
189
190 if (VBOX_SUCCESS(rc))
191 {
192 /* Update parameters.*/
193 paParms[2].u.uint64 = lastretval;
194 paParms[3].u.uint32 = lasterror;
195 }
196 }
197 break;
198 }
199
200 case VBOXOGL_FN_GLFLUSHPTR:
201 {
202 Log(("svcCall: VBOXOGL_FN_GLFLUSHPTR\n"));
203
204 /* Verify parameter count and types. */
205 if (cParms != VBOXOGL_CPARMS_GLFLUSHPTR)
206 {
207 rc = VERR_INVALID_PARAMETER;
208 }
209 else
210 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pCmdBuffer */
211 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* cCommands */
212 || ( paParms[2].type != VBOX_HGCM_SVC_PARM_PTR /* pLastParam */
213 && paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT) /* pLastParam if NULL */
214 || paParms[3].type != VBOX_HGCM_SVC_PARM_64BIT /* retval */
215 || paParms[4].type != VBOX_HGCM_SVC_PARM_32BIT /* lasterror */
216 )
217 {
218 rc = VERR_INVALID_PARAMETER;
219 }
220 else
221 {
222 /* Fetch parameters. */
223 uint8_t *pCmdBuffer = (uint8_t *)paParms[0].u.pointer.addr;
224 uint32_t cbCmdBuffer = paParms[0].u.pointer.size;
225 uint32_t cCommands = paParms[1].u.uint32;
226 GLenum lasterror;
227 uint64_t lastretval;
228
229 /* Save the last parameter of the last command in the client structure so the macro can pick it up there */
230 if (paParms[2].type == VBOX_HGCM_SVC_PARM_32BIT)
231 {
232 /* HGCM doesn't like NULL pointers. */
233 pClient->pLastParam = NULL;
234 pClient->cbLastParam = 0;
235 }
236 else
237 {
238 pClient->pLastParam = (uint8_t *)paParms[2].u.pointer.addr;
239 pClient->cbLastParam = paParms[2].u.pointer.size;
240 }
241
242 /* Execute the function. */
243 rc = vboxglFlushBuffer(pClient, pCmdBuffer, cbCmdBuffer, cCommands, &lasterror, &lastretval);
244
245 /* Clear last parameter info again */
246 pClient->pLastParam = 0;
247 pClient->cbLastParam = 0;
248
249 if (VBOX_SUCCESS(rc))
250 {
251 /* Update parameters.*/
252 paParms[3].u.uint64 = lastretval;
253 paParms[4].u.uint32 = lasterror;
254 }
255 }
256 break;
257 }
258
259 case VBOXOGL_FN_GLCHECKEXT:
260 {
261 Log(("svcCall: VBOXOGL_FN_GLCHECKEXT\n"));
262
263 /* Verify parameter count and types. */
264 if (cParms != VBOXOGL_CPARMS_GLCHECKEXT)
265 {
266 rc = VERR_INVALID_PARAMETER;
267 }
268 else
269 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pszExtFnName */
270 )
271 {
272 rc = VERR_INVALID_PARAMETER;
273 }
274 else
275 {
276 /* Fetch parameters. */
277 char *pszExtFnName = (char *)paParms[0].u.pointer.addr;
278 uint32_t cbExtFnName = paParms[0].u.pointer.size; /* size including null terminator */
279
280 /* sanity checks */
281 if ( cbExtFnName > 256
282 || pszExtFnName[cbExtFnName-1] != 0
283 )
284 {
285 rc = VERR_INVALID_PARAMETER;
286 }
287 else
288 {
289 /* Execute the function. */
290 if (vboxwglGetProcAddress(pszExtFnName))
291 rc = VINF_SUCCESS;
292 else
293 rc = VERR_FILE_NOT_FOUND;
294
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