VirtualBox

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

Last change on this file since 8256 was 8155, checked in by vboxsync, 17 years ago

The Big Sun Rebranding Header Change

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