VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp@ 32420

Last change on this file since 32420 was 32420, checked in by vboxsync, 14 years ago

crOpenGL: some mutter/meego related fixes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 20.9 KB
Line 
1/* $Id: crservice.cpp 32420 2010-09-10 16:25:10Z vboxsync $ */
2
3/** @file
4 * VBox crOpenGL: Host service entry points.
5 */
6
7/*
8 * Copyright (C) 2006-2008 Oracle Corporation
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 (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19#define __STDC_CONSTANT_MACROS /* needed for a definition in iprt/string.h */
20
21#ifdef RT_OS_WINDOWS
22#include <iprt/alloc.h>
23#include <iprt/string.h>
24#include <iprt/assert.h>
25#include <iprt/stream.h>
26#include <VBox/ssm.h>
27#include <VBox/hgcmsvc.h>
28#include <VBox/HostServices/VBoxCrOpenGLSvc.h>
29#include "cr_server.h"
30#define LOG_GROUP LOG_GROUP_SHARED_CROPENGL
31#include <VBox/log.h>
32
33#include <VBox/com/com.h>
34#include <VBox/com/string.h>
35#include <VBox/com/array.h>
36#include <VBox/com/Guid.h>
37#include <VBox/com/ErrorInfo.h>
38#include <VBox/com/EventQueue.h>
39#include <VBox/com/VirtualBox.h>
40#include <VBox/com/assert.h>
41
42#else
43#include <VBox/com/VirtualBox.h>
44#include <iprt/assert.h>
45#include <VBox/ssm.h>
46#include <VBox/hgcmsvc.h>
47#include <VBox/HostServices/VBoxCrOpenGLSvc.h>
48
49#include "cr_server.h"
50#define LOG_GROUP LOG_GROUP_SHARED_CROPENGL
51#include <VBox/log.h>
52#include <VBox/com/ErrorInfo.h>
53#endif /* RT_OS_WINDOWS */
54
55#include <VBox/com/errorprint.h>
56
57PVBOXHGCMSVCHELPERS g_pHelpers;
58static IConsole* g_pConsole = NULL;
59static PVM g_pVM = NULL;
60
61#ifndef RT_OS_WINDOWS
62#define DWORD int
63#define WINAPI
64#endif
65
66static const char* gszVBoxOGLSSMMagic = "***OpenGL state data***";
67#define SHCROGL_SSM_VERSION 20
68
69static DECLCALLBACK(int) svcUnload (void *)
70{
71 int rc = VINF_SUCCESS;
72
73 Log(("SHARED_CROPENGL svcUnload\n"));
74
75 crVBoxServerTearDown();
76
77 return rc;
78}
79
80static DECLCALLBACK(int) svcConnect (void *, uint32_t u32ClientID, void *pvClient)
81{
82 int rc = VINF_SUCCESS;
83
84 NOREF(pvClient);
85
86 Log(("SHARED_CROPENGL svcConnect: u32ClientID = %d\n", u32ClientID));
87
88 rc = crVBoxServerAddClient(u32ClientID);
89
90 return rc;
91}
92
93static DECLCALLBACK(int) svcDisconnect (void *, uint32_t u32ClientID, void *pvClient)
94{
95 int rc = VINF_SUCCESS;
96
97 NOREF(pvClient);
98
99 Log(("SHARED_CROPENGL svcDisconnect: u32ClientID = %d\n", u32ClientID));
100
101 crVBoxServerRemoveClient(u32ClientID);
102
103 return rc;
104}
105
106static DECLCALLBACK(int) svcSaveState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM)
107{
108 int rc = VINF_SUCCESS;
109
110 NOREF(pvClient);
111
112 Log(("SHARED_CROPENGL svcSaveState: u32ClientID = %d\n", u32ClientID));
113
114 /* Start*/
115 rc = SSMR3PutStrZ(pSSM, gszVBoxOGLSSMMagic);
116 AssertRCReturn(rc, rc);
117
118 /* Version */
119 rc = SSMR3PutU32(pSSM, (uint32_t) SHCROGL_SSM_VERSION);
120 AssertRCReturn(rc, rc);
121
122 /* The state itself */
123 rc = crVBoxServerSaveState(pSSM);
124 AssertRCReturn(rc, rc);
125
126 /* End */
127 rc = SSMR3PutStrZ(pSSM, gszVBoxOGLSSMMagic);
128 AssertRCReturn(rc, rc);
129
130 return VINF_SUCCESS;
131}
132
133static DECLCALLBACK(int) svcLoadState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM)
134{
135 int rc = VINF_SUCCESS;
136
137 NOREF(pvClient);
138
139 Log(("SHARED_CROPENGL svcLoadState: u32ClientID = %d\n", u32ClientID));
140
141 char psz[2000];
142 uint32_t ui32;
143
144 /* Start of data */
145 rc = SSMR3GetStrZEx(pSSM, psz, 2000, NULL);
146 AssertRCReturn(rc, rc);
147 if (strcmp(gszVBoxOGLSSMMagic, psz))
148 return VERR_SSM_UNEXPECTED_DATA;
149
150 /* Version */
151 rc = SSMR3GetU32(pSSM, &ui32);
152 AssertRCReturn(rc, rc);
153 if ((SHCROGL_SSM_VERSION != ui32)
154 && ((SHCROGL_SSM_VERSION!=4) || (3!=ui32)))
155 {
156 /*@todo: add some warning here*/
157 /*@todo: in many cases saved states would be made without any opengl guest app running.
158 * that means we could safely restore the default context.
159 */
160 rc = SSMR3SkipToEndOfUnit(pSSM);
161 return rc;
162 }
163
164 /* The state itself */
165 rc = crVBoxServerLoadState(pSSM, ui32);
166 AssertRCReturn(rc, rc);
167
168 /* End of data */
169 rc = SSMR3GetStrZEx(pSSM, psz, 2000, NULL);
170 AssertRCReturn(rc, rc);
171 if (strcmp(gszVBoxOGLSSMMagic, psz))
172 return VERR_SSM_UNEXPECTED_DATA;
173
174 return VINF_SUCCESS;
175}
176
177static void svcClientVersionUnsupported(uint32_t minor, uint32_t major)
178{
179 LogRel(("SHARED_CROPENGL: unsupported client version %d.%d\n", minor, major));
180
181 /*MS's opengl32 tryes to load our ICD around 30 times on failure...this is to prevent unnecessary spam*/
182 static int shown = 0;
183
184 if (g_pVM && !shown)
185 {
186 VMSetRuntimeError(g_pVM, VMSETRTERR_FLAGS_NO_WAIT, "3DSupportIncompatibleAdditions",
187 "An attempt by the virtual machine to use hardware 3D acceleration failed. "
188 "The version of the Guest Additions installed in the virtual machine does not match the "
189 "version of VirtualBox on the host. Please install appropriate Guest Additions to fix this issue");
190 shown = 1;
191 }
192}
193
194static DECLCALLBACK(void) svcPresentFBO(void *data, int32_t screenId, int32_t x, int32_t y, uint32_t w, uint32_t h)
195{
196#if 0
197 ComPtr<IDisplay> pDisplay;
198 BYTE *data;
199 int i,j;
200 CHECK_ERROR(g_pConsole, COMGETTER(Display)(pDisplay.asOutParam()));
201
202 data = (BYTE*) RTMemTmpAllocZ(100*100*4);
203
204 for (i=0; i<100; i+=2)
205 {
206 for (j=0; j<100; ++j)
207 {
208 *(data+i*100*4+j*4+0) = 0xFF;
209 *(data+i*100*4+j*4+1) = 0xFF;
210 *(data+i*100*4+j*4+2) = 0xFF;
211 *(data+i*100*4+j*4+3) = 0xFF;
212 }
213 }
214
215 CHECK_ERROR(pDisplay, DrawToScreen(screenId, data, 0, 0, 100, 100));
216
217 RTMemTmpFree(data);
218#endif
219 HRESULT rc;
220 ComPtr<IDisplay> pDisplay;
221
222 CHECK_ERROR(g_pConsole, COMGETTER(Display)(pDisplay.asOutParam()));
223 CHECK_ERROR(pDisplay, DrawToScreen(screenId, (BYTE*)data, x, y, w, h));
224}
225
226static DECLCALLBACK(void) svcCall (void *, VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID, void *pvClient, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
227{
228 int rc = VINF_SUCCESS;
229
230 NOREF(pvClient);
231
232 Log(("SHARED_CROPENGL svcCall: u32ClientID = %d, fn = %d, cParms = %d, pparms = %d\n", u32ClientID, u32Function, cParms, paParms));
233
234#ifdef DEBUG
235 uint32_t i;
236
237 for (i = 0; i < cParms; i++)
238 {
239 /** @todo parameters other than 32 bit */
240 Log((" pparms[%d]: type %d value %d\n", i, paParms[i].type, paParms[i].u.uint32));
241 }
242#endif
243
244 switch (u32Function)
245 {
246 case SHCRGL_GUEST_FN_WRITE:
247 {
248 Log(("svcCall: SHCRGL_GUEST_FN_WRITE\n"));
249
250 /* Verify parameter count and types. */
251 if (cParms != SHCRGL_CPARMS_WRITE)
252 {
253 rc = VERR_INVALID_PARAMETER;
254 }
255 else
256 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pBuffer */
257 )
258 {
259 rc = VERR_INVALID_PARAMETER;
260 }
261 else
262 {
263 /* Fetch parameters. */
264 uint8_t *pBuffer = (uint8_t *)paParms[0].u.pointer.addr;
265 uint32_t cbBuffer = paParms[0].u.pointer.size;
266
267 /* Execute the function. */
268 rc = crVBoxServerClientWrite(u32ClientID, pBuffer, cbBuffer);
269 if (!RT_SUCCESS(rc))
270 {
271 Assert(VERR_NOT_SUPPORTED==rc);
272 svcClientVersionUnsupported(0, 0);
273 }
274
275 }
276 break;
277 }
278
279 case SHCRGL_GUEST_FN_INJECT:
280 {
281 Log(("svcCall: SHCRGL_GUEST_FN_INJECT\n"));
282
283 /* Verify parameter count and types. */
284 if (cParms != SHCRGL_CPARMS_INJECT)
285 {
286 rc = VERR_INVALID_PARAMETER;
287 }
288 else
289 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* u32ClientID */
290 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR /* pBuffer */
291 )
292 {
293 rc = VERR_INVALID_PARAMETER;
294 }
295 else
296 {
297 /* Fetch parameters. */
298 uint32_t u32InjectClientID = paParms[0].u.uint32;
299 uint8_t *pBuffer = (uint8_t *)paParms[1].u.pointer.addr;
300 uint32_t cbBuffer = paParms[1].u.pointer.size;
301
302 /* Execute the function. */
303 rc = crVBoxServerClientWrite(u32InjectClientID, pBuffer, cbBuffer);
304 if (!RT_SUCCESS(rc))
305 {
306 if (VERR_NOT_SUPPORTED==rc)
307 {
308 svcClientVersionUnsupported(0, 0);
309 }
310 else
311 {
312 crWarning("SHCRGL_GUEST_FN_INJECT failed to inject for %i from %i", u32InjectClientID, u32ClientID);
313 }
314 }
315 }
316 break;
317 }
318
319 case SHCRGL_GUEST_FN_READ:
320 {
321 Log(("svcCall: SHCRGL_GUEST_FN_READ\n"));
322
323 /* Verify parameter count and types. */
324 if (cParms != SHCRGL_CPARMS_READ)
325 {
326 rc = VERR_INVALID_PARAMETER;
327 }
328 else
329 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pBuffer */
330 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* cbBuffer */
331 )
332 {
333 rc = VERR_INVALID_PARAMETER;
334 }
335
336 /* Fetch parameters. */
337 uint8_t *pBuffer = (uint8_t *)paParms[0].u.pointer.addr;
338 uint32_t cbBuffer = paParms[0].u.pointer.size;
339
340 /* Execute the function. */
341 rc = crVBoxServerClientRead(u32ClientID, pBuffer, &cbBuffer);
342
343 if (RT_SUCCESS(rc))
344 {
345 /* Update parameters.*/
346 paParms[0].u.pointer.size = cbBuffer; //@todo guest doesn't see this change somehow?
347 } else if (VERR_NOT_SUPPORTED==rc)
348 {
349 svcClientVersionUnsupported(0, 0);
350 }
351
352 /* Return the required buffer size always */
353 paParms[1].u.uint32 = cbBuffer;
354
355 break;
356 }
357
358 case SHCRGL_GUEST_FN_WRITE_READ:
359 {
360 Log(("svcCall: SHCRGL_GUEST_FN_WRITE_READ\n"));
361
362 /* Verify parameter count and types. */
363 if (cParms != SHCRGL_CPARMS_WRITE_READ)
364 {
365 rc = VERR_INVALID_PARAMETER;
366 }
367 else
368 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pBuffer */
369 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR /* pWriteback */
370 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* cbWriteback */
371 )
372 {
373 rc = VERR_INVALID_PARAMETER;
374 }
375 else
376 {
377 /* Fetch parameters. */
378 uint8_t *pBuffer = (uint8_t *)paParms[0].u.pointer.addr;
379 uint32_t cbBuffer = paParms[0].u.pointer.size;
380
381 uint8_t *pWriteback = (uint8_t *)paParms[1].u.pointer.addr;
382 uint32_t cbWriteback = paParms[1].u.pointer.size;
383
384 /* Execute the function. */
385 rc = crVBoxServerClientWrite(u32ClientID, pBuffer, cbBuffer);
386 if (!RT_SUCCESS(rc))
387 {
388 Assert(VERR_NOT_SUPPORTED==rc);
389 svcClientVersionUnsupported(0, 0);
390 }
391
392 rc = crVBoxServerClientRead(u32ClientID, pWriteback, &cbWriteback);
393
394 if (RT_SUCCESS(rc))
395 {
396 /* Update parameters.*/
397 paParms[1].u.pointer.size = cbWriteback;
398 }
399 /* Return the required buffer size always */
400 paParms[2].u.uint32 = cbWriteback;
401 }
402
403 break;
404 }
405
406 case SHCRGL_GUEST_FN_SET_VERSION:
407 {
408 Log(("svcCall: SHCRGL_GUEST_FN_SET_VERSION\n"));
409
410 /* Verify parameter count and types. */
411 if (cParms != SHCRGL_CPARMS_SET_VERSION)
412 {
413 rc = VERR_INVALID_PARAMETER;
414 }
415 else
416 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* vMajor */
417 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* vMinor */
418 )
419 {
420 rc = VERR_INVALID_PARAMETER;
421 }
422 else
423 {
424 /* Fetch parameters. */
425 uint32_t vMajor = paParms[0].u.uint32;
426 uint32_t vMinor = paParms[1].u.uint32;
427
428 /* Execute the function. */
429 rc = crVBoxServerClientSetVersion(u32ClientID, vMajor, vMinor);
430
431 if (!RT_SUCCESS(rc))
432 {
433 svcClientVersionUnsupported(vMajor, vMinor);
434 }
435 }
436
437 break;
438 }
439
440 default:
441 {
442 rc = VERR_NOT_IMPLEMENTED;
443 }
444 }
445
446
447 LogFlow(("svcCall: rc = %Rrc\n", rc));
448
449 g_pHelpers->pfnCallComplete (callHandle, rc);
450}
451
452/*
453 * We differentiate between a function handler for the guest and one for the host.
454 */
455static DECLCALLBACK(int) svcHostCall (void *, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
456{
457 int rc = VINF_SUCCESS;
458
459 Log(("SHARED_CROPENGL svcHostCall: fn = %d, cParms = %d, pparms = %d\n", u32Function, cParms, paParms));
460
461#ifdef DEBUG
462 uint32_t i;
463
464 for (i = 0; i < cParms; i++)
465 {
466 /** @todo parameters other than 32 bit */
467 Log((" pparms[%d]: type %d value %d\n", i, paParms[i].type, paParms[i].u.uint32));
468 }
469#endif
470
471 switch (u32Function)
472 {
473 case SHCRGL_HOST_FN_SET_CONSOLE:
474 {
475 Log(("svcCall: SHCRGL_HOST_FN_SET_DISPLAY\n"));
476
477 /* Verify parameter count and types. */
478 if (cParms != SHCRGL_CPARMS_SET_CONSOLE)
479 {
480 rc = VERR_INVALID_PARAMETER;
481 }
482 else if (paParms[0].type != VBOX_HGCM_SVC_PARM_PTR)
483 {
484 rc = VERR_INVALID_PARAMETER;
485 }
486 else
487 {
488 /* Fetch parameters. */
489 IConsole* pConsole = (IConsole*)paParms[0].u.pointer.addr;
490 uint32_t cbData = paParms[0].u.pointer.size;
491
492 /* Verify parameters values. */
493 if (cbData != sizeof (IConsole*))
494 {
495 rc = VERR_INVALID_PARAMETER;
496 }
497 else if (!pConsole)
498 {
499 rc = VERR_INVALID_PARAMETER;
500 }
501 else /* Execute the function. */
502 {
503 ComPtr<IMachine> pMachine;
504 ComPtr<IDisplay> pDisplay;
505 ComPtr<IFramebuffer> pFramebuffer;
506 LONG xo, yo;
507 LONG64 winId = 0;
508 ULONG monitorCount, i, w, h;
509
510 CHECK_ERROR_BREAK(pConsole, COMGETTER(Machine)(pMachine.asOutParam()));
511 CHECK_ERROR_BREAK(pMachine, COMGETTER(MonitorCount)(&monitorCount));
512 CHECK_ERROR_BREAK(pConsole, COMGETTER(Display)(pDisplay.asOutParam()));
513
514 rc = crVBoxServerSetScreenCount(monitorCount);
515 AssertRCReturn(rc, rc);
516
517 for (i=0; i<monitorCount; ++i)
518 {
519 CHECK_ERROR_RET(pDisplay, GetFramebuffer(i, pFramebuffer.asOutParam(), &xo, &yo), rc);
520
521 if (!pDisplay)
522 {
523 rc = crVBoxServerUnmapScreen(i);
524 AssertRCReturn(rc, rc);
525 }
526 else
527 {
528 CHECK_ERROR_RET(pFramebuffer, COMGETTER(WinId)(&winId), rc);
529 CHECK_ERROR_RET(pFramebuffer, COMGETTER(Width)(&w), rc);
530 CHECK_ERROR_RET(pFramebuffer, COMGETTER(Height)(&h), rc);
531
532 rc = crVBoxServerMapScreen(i, xo, yo, w, h, winId);
533 AssertRCReturn(rc, rc);
534 }
535 }
536
537 g_pConsole = pConsole;
538 rc = VINF_SUCCESS;
539 }
540 }
541 break;
542 }
543 case SHCRGL_HOST_FN_SET_VM:
544 {
545 Log(("svcCall: SHCRGL_HOST_FN_SET_VM\n"));
546
547 /* Verify parameter count and types. */
548 if (cParms != SHCRGL_CPARMS_SET_VM)
549 {
550 rc = VERR_INVALID_PARAMETER;
551 }
552 else if (paParms[0].type != VBOX_HGCM_SVC_PARM_PTR)
553 {
554 rc = VERR_INVALID_PARAMETER;
555 }
556 else
557 {
558 /* Fetch parameters. */
559 PVM pVM = (PVM)paParms[0].u.pointer.addr;
560 uint32_t cbData = paParms[0].u.pointer.size;
561
562 /* Verify parameters values. */
563 if (cbData != sizeof (PVM))
564 {
565 rc = VERR_INVALID_PARAMETER;
566 }
567 else
568 {
569 /* Execute the function. */
570 g_pVM = pVM;
571 rc = VINF_SUCCESS;
572 }
573 }
574 break;
575 }
576 case SHCRGL_HOST_FN_SET_VISIBLE_REGION:
577 {
578 Log(("svcCall: SHCRGL_HOST_FN_SET_VISIBLE_REGION\n"));
579
580 if (cParms != SHCRGL_CPARMS_SET_VISIBLE_REGION)
581 {
582 rc = VERR_INVALID_PARAMETER;
583 break;
584 }
585
586 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pRects */
587 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* cRects */
588 )
589 {
590 rc = VERR_INVALID_PARAMETER;
591 break;
592 }
593
594 Assert(sizeof(RTRECT)==4*sizeof(GLint));
595
596 rc = crVBoxServerSetRootVisibleRegion(paParms[1].u.uint32, (GLint*)paParms[0].u.pointer.addr);
597 break;
598 }
599 case SHCRGL_HOST_FN_SCREEN_CHANGED:
600 {
601 Log(("svcCall: SHCRGL_HOST_FN_SCREEN_CHANGED\n"));
602
603 /* Verify parameter count and types. */
604 if (cParms != SHCRGL_CPARMS_SCREEN_CHANGED)
605 {
606 rc = VERR_INVALID_PARAMETER;
607 }
608 else if (paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT)
609 {
610 rc = VERR_INVALID_PARAMETER;
611 }
612 else
613 {
614 /* Fetch parameters. */
615 uint32_t screenId = paParms[0].u.uint32;
616
617 /* Execute the function. */
618 ComPtr<IDisplay> pDisplay;
619 ComPtr<IFramebuffer> pFramebuffer;
620 LONG xo, yo;
621 LONG64 winId = 0;
622 ULONG w, h;
623
624 Assert(g_pConsole);
625 CHECK_ERROR_RET(g_pConsole, COMGETTER(Display)(pDisplay.asOutParam()), rc);
626 CHECK_ERROR_RET(pDisplay, GetFramebuffer(screenId, pFramebuffer.asOutParam(), &xo, &yo), rc);
627
628 if (!pFramebuffer)
629 {
630 rc = crVBoxServerUnmapScreen(screenId);
631 AssertRCReturn(rc, rc);
632 }
633 else
634 {
635 CHECK_ERROR_RET(pFramebuffer, COMGETTER(WinId)(&winId), rc);
636 CHECK_ERROR_RET(pFramebuffer, COMGETTER(Width)(&w), rc);
637 CHECK_ERROR_RET(pFramebuffer, COMGETTER(Height)(&h), rc);
638
639 rc = crVBoxServerMapScreen(screenId, xo, yo, w, h, winId);
640 AssertRCReturn(rc, rc);
641 }
642
643 rc = VINF_SUCCESS;
644 }
645 break;
646 }
647 default:
648 rc = VERR_NOT_IMPLEMENTED;
649 break;
650 }
651
652 LogFlow(("svcHostCall: rc = %Rrc\n", rc));
653 return rc;
654}
655
656extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad (VBOXHGCMSVCFNTABLE *ptable)
657{
658 int rc = VINF_SUCCESS;
659
660 Log(("SHARED_CROPENGL VBoxHGCMSvcLoad: ptable = %p\n", ptable));
661
662 if (!ptable)
663 {
664 rc = VERR_INVALID_PARAMETER;
665 }
666 else
667 {
668 Log(("VBoxHGCMSvcLoad: ptable->cbSize = %d, ptable->u32Version = 0x%08X\n", ptable->cbSize, ptable->u32Version));
669
670 if ( ptable->cbSize != sizeof (VBOXHGCMSVCFNTABLE)
671 || ptable->u32Version != VBOX_HGCM_SVC_VERSION)
672 {
673 rc = VERR_INVALID_PARAMETER;
674 }
675 else
676 {
677 g_pHelpers = ptable->pHelpers;
678
679 ptable->cbClient = sizeof (void*);
680
681 ptable->pfnUnload = svcUnload;
682 ptable->pfnConnect = svcConnect;
683 ptable->pfnDisconnect = svcDisconnect;
684 ptable->pfnCall = svcCall;
685 ptable->pfnHostCall = svcHostCall;
686 ptable->pfnSaveState = svcSaveState;
687 ptable->pfnLoadState = svcLoadState;
688 ptable->pvService = NULL;
689
690 if (!crVBoxServerInit())
691 return VERR_NOT_SUPPORTED;
692
693 crVBoxServerSetPresentFBOCB(svcPresentFBO);
694 }
695 }
696
697 return rc;
698}
699
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