VirtualBox

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

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

crOpenGL: resource sharing between contexts

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 20.7 KB
Line 
1/* $Id: crservice.cpp 31808 2010-08-20 09:40:40Z 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 Assert(VERR_NOT_SUPPORTED==rc);
307 svcClientVersionUnsupported(0, 0);
308 }
309
310 }
311 break;
312 }
313
314 case SHCRGL_GUEST_FN_READ:
315 {
316 Log(("svcCall: SHCRGL_GUEST_FN_READ\n"));
317
318 /* Verify parameter count and types. */
319 if (cParms != SHCRGL_CPARMS_READ)
320 {
321 rc = VERR_INVALID_PARAMETER;
322 }
323 else
324 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pBuffer */
325 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* cbBuffer */
326 )
327 {
328 rc = VERR_INVALID_PARAMETER;
329 }
330
331 /* Fetch parameters. */
332 uint8_t *pBuffer = (uint8_t *)paParms[0].u.pointer.addr;
333 uint32_t cbBuffer = paParms[0].u.pointer.size;
334
335 /* Execute the function. */
336 rc = crVBoxServerClientRead(u32ClientID, pBuffer, &cbBuffer);
337
338 if (RT_SUCCESS(rc))
339 {
340 /* Update parameters.*/
341 paParms[0].u.pointer.size = cbBuffer; //@todo guest doesn't see this change somehow?
342 } else if (VERR_NOT_SUPPORTED==rc)
343 {
344 svcClientVersionUnsupported(0, 0);
345 }
346
347 /* Return the required buffer size always */
348 paParms[1].u.uint32 = cbBuffer;
349
350 break;
351 }
352
353 case SHCRGL_GUEST_FN_WRITE_READ:
354 {
355 Log(("svcCall: SHCRGL_GUEST_FN_WRITE_READ\n"));
356
357 /* Verify parameter count and types. */
358 if (cParms != SHCRGL_CPARMS_WRITE_READ)
359 {
360 rc = VERR_INVALID_PARAMETER;
361 }
362 else
363 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pBuffer */
364 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR /* pWriteback */
365 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* cbWriteback */
366 )
367 {
368 rc = VERR_INVALID_PARAMETER;
369 }
370 else
371 {
372 /* Fetch parameters. */
373 uint8_t *pBuffer = (uint8_t *)paParms[0].u.pointer.addr;
374 uint32_t cbBuffer = paParms[0].u.pointer.size;
375
376 uint8_t *pWriteback = (uint8_t *)paParms[1].u.pointer.addr;
377 uint32_t cbWriteback = paParms[1].u.pointer.size;
378
379 /* Execute the function. */
380 rc = crVBoxServerClientWrite(u32ClientID, pBuffer, cbBuffer);
381 if (!RT_SUCCESS(rc))
382 {
383 Assert(VERR_NOT_SUPPORTED==rc);
384 svcClientVersionUnsupported(0, 0);
385 }
386
387 rc = crVBoxServerClientRead(u32ClientID, pWriteback, &cbWriteback);
388
389 if (RT_SUCCESS(rc))
390 {
391 /* Update parameters.*/
392 paParms[1].u.pointer.size = cbWriteback;
393 }
394 /* Return the required buffer size always */
395 paParms[2].u.uint32 = cbWriteback;
396 }
397
398 break;
399 }
400
401 case SHCRGL_GUEST_FN_SET_VERSION:
402 {
403 Log(("svcCall: SHCRGL_GUEST_FN_SET_VERSION\n"));
404
405 /* Verify parameter count and types. */
406 if (cParms != SHCRGL_CPARMS_SET_VERSION)
407 {
408 rc = VERR_INVALID_PARAMETER;
409 }
410 else
411 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* vMajor */
412 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* vMinor */
413 )
414 {
415 rc = VERR_INVALID_PARAMETER;
416 }
417 else
418 {
419 /* Fetch parameters. */
420 uint32_t vMajor = paParms[0].u.uint32;
421 uint32_t vMinor = paParms[1].u.uint32;
422
423 /* Execute the function. */
424 rc = crVBoxServerClientSetVersion(u32ClientID, vMajor, vMinor);
425
426 if (!RT_SUCCESS(rc))
427 {
428 svcClientVersionUnsupported(vMajor, vMinor);
429 }
430 }
431
432 break;
433 }
434
435 default:
436 {
437 rc = VERR_NOT_IMPLEMENTED;
438 }
439 }
440
441
442 LogFlow(("svcCall: rc = %Rrc\n", rc));
443
444 g_pHelpers->pfnCallComplete (callHandle, rc);
445}
446
447/*
448 * We differentiate between a function handler for the guest and one for the host.
449 */
450static DECLCALLBACK(int) svcHostCall (void *, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
451{
452 int rc = VINF_SUCCESS;
453
454 Log(("SHARED_CROPENGL svcHostCall: fn = %d, cParms = %d, pparms = %d\n", u32Function, cParms, paParms));
455
456#ifdef DEBUG
457 uint32_t i;
458
459 for (i = 0; i < cParms; i++)
460 {
461 /** @todo parameters other than 32 bit */
462 Log((" pparms[%d]: type %d value %d\n", i, paParms[i].type, paParms[i].u.uint32));
463 }
464#endif
465
466 switch (u32Function)
467 {
468 case SHCRGL_HOST_FN_SET_CONSOLE:
469 {
470 Log(("svcCall: SHCRGL_HOST_FN_SET_DISPLAY\n"));
471
472 /* Verify parameter count and types. */
473 if (cParms != SHCRGL_CPARMS_SET_CONSOLE)
474 {
475 rc = VERR_INVALID_PARAMETER;
476 }
477 else if (paParms[0].type != VBOX_HGCM_SVC_PARM_PTR)
478 {
479 rc = VERR_INVALID_PARAMETER;
480 }
481 else
482 {
483 /* Fetch parameters. */
484 IConsole* pConsole = (IConsole*)paParms[0].u.pointer.addr;
485 uint32_t cbData = paParms[0].u.pointer.size;
486
487 /* Verify parameters values. */
488 if (cbData != sizeof (IConsole*))
489 {
490 rc = VERR_INVALID_PARAMETER;
491 }
492 else if (!pConsole)
493 {
494 rc = VERR_INVALID_PARAMETER;
495 }
496 else /* Execute the function. */
497 {
498 ComPtr<IMachine> pMachine;
499 ComPtr<IDisplay> pDisplay;
500 ComPtr<IFramebuffer> pFramebuffer;
501 LONG xo, yo;
502 LONG64 winId = 0;
503 ULONG monitorCount, i, w, h;
504
505 CHECK_ERROR_BREAK(pConsole, COMGETTER(Machine)(pMachine.asOutParam()));
506 CHECK_ERROR_BREAK(pMachine, COMGETTER(MonitorCount)(&monitorCount));
507 CHECK_ERROR_BREAK(pConsole, COMGETTER(Display)(pDisplay.asOutParam()));
508
509 rc = crVBoxServerSetScreenCount(monitorCount);
510 AssertRCReturn(rc, rc);
511
512 for (i=0; i<monitorCount; ++i)
513 {
514 CHECK_ERROR_RET(pDisplay, GetFramebuffer(i, pFramebuffer.asOutParam(), &xo, &yo), rc);
515
516 if (!pDisplay)
517 {
518 rc = crVBoxServerUnmapScreen(i);
519 AssertRCReturn(rc, rc);
520 }
521 else
522 {
523 CHECK_ERROR_RET(pFramebuffer, COMGETTER(WinId)(&winId), rc);
524 CHECK_ERROR_RET(pFramebuffer, COMGETTER(Width)(&w), rc);
525 CHECK_ERROR_RET(pFramebuffer, COMGETTER(Height)(&h), rc);
526
527 rc = crVBoxServerMapScreen(i, xo, yo, w, h, winId);
528 AssertRCReturn(rc, rc);
529 }
530 }
531
532 g_pConsole = pConsole;
533 rc = VINF_SUCCESS;
534 }
535 }
536 break;
537 }
538 case SHCRGL_HOST_FN_SET_VM:
539 {
540 Log(("svcCall: SHCRGL_HOST_FN_SET_VM\n"));
541
542 /* Verify parameter count and types. */
543 if (cParms != SHCRGL_CPARMS_SET_VM)
544 {
545 rc = VERR_INVALID_PARAMETER;
546 }
547 else if (paParms[0].type != VBOX_HGCM_SVC_PARM_PTR)
548 {
549 rc = VERR_INVALID_PARAMETER;
550 }
551 else
552 {
553 /* Fetch parameters. */
554 PVM pVM = (PVM)paParms[0].u.pointer.addr;
555 uint32_t cbData = paParms[0].u.pointer.size;
556
557 /* Verify parameters values. */
558 if (cbData != sizeof (PVM))
559 {
560 rc = VERR_INVALID_PARAMETER;
561 }
562 else
563 {
564 /* Execute the function. */
565 g_pVM = pVM;
566 rc = VINF_SUCCESS;
567 }
568 }
569 break;
570 }
571 case SHCRGL_HOST_FN_SET_VISIBLE_REGION:
572 {
573 Log(("svcCall: SHCRGL_HOST_FN_SET_VISIBLE_REGION\n"));
574
575 if (cParms != SHCRGL_CPARMS_SET_VISIBLE_REGION)
576 {
577 rc = VERR_INVALID_PARAMETER;
578 break;
579 }
580
581 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pRects */
582 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* cRects */
583 )
584 {
585 rc = VERR_INVALID_PARAMETER;
586 break;
587 }
588
589 Assert(sizeof(RTRECT)==4*sizeof(GLint));
590
591 rc = crVBoxServerSetRootVisibleRegion(paParms[1].u.uint32, (GLint*)paParms[0].u.pointer.addr);
592 break;
593 }
594 case SHCRGL_HOST_FN_SCREEN_CHANGED:
595 {
596 Log(("svcCall: SHCRGL_HOST_FN_SCREEN_CHANGED\n"));
597
598 /* Verify parameter count and types. */
599 if (cParms != SHCRGL_CPARMS_SCREEN_CHANGED)
600 {
601 rc = VERR_INVALID_PARAMETER;
602 }
603 else if (paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT)
604 {
605 rc = VERR_INVALID_PARAMETER;
606 }
607 else
608 {
609 /* Fetch parameters. */
610 uint32_t screenId = paParms[0].u.uint32;
611
612 /* Execute the function. */
613 ComPtr<IDisplay> pDisplay;
614 ComPtr<IFramebuffer> pFramebuffer;
615 LONG xo, yo;
616 LONG64 winId = 0;
617 ULONG w, h;
618
619 Assert(g_pConsole);
620 CHECK_ERROR_RET(g_pConsole, COMGETTER(Display)(pDisplay.asOutParam()), rc);
621 CHECK_ERROR_RET(pDisplay, GetFramebuffer(screenId, pFramebuffer.asOutParam(), &xo, &yo), rc);
622
623 if (!pFramebuffer)
624 {
625 rc = crVBoxServerUnmapScreen(screenId);
626 AssertRCReturn(rc, rc);
627 }
628 else
629 {
630 CHECK_ERROR_RET(pFramebuffer, COMGETTER(WinId)(&winId), rc);
631 CHECK_ERROR_RET(pFramebuffer, COMGETTER(Width)(&w), rc);
632 CHECK_ERROR_RET(pFramebuffer, COMGETTER(Height)(&h), rc);
633
634 rc = crVBoxServerMapScreen(screenId, xo, yo, w, h, winId);
635 AssertRCReturn(rc, rc);
636 }
637
638 rc = VINF_SUCCESS;
639 }
640 break;
641 }
642 default:
643 rc = VERR_NOT_IMPLEMENTED;
644 break;
645 }
646
647 LogFlow(("svcHostCall: rc = %Rrc\n", rc));
648 return rc;
649}
650
651extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad (VBOXHGCMSVCFNTABLE *ptable)
652{
653 int rc = VINF_SUCCESS;
654
655 Log(("SHARED_CROPENGL VBoxHGCMSvcLoad: ptable = %p\n", ptable));
656
657 if (!ptable)
658 {
659 rc = VERR_INVALID_PARAMETER;
660 }
661 else
662 {
663 Log(("VBoxHGCMSvcLoad: ptable->cbSize = %d, ptable->u32Version = 0x%08X\n", ptable->cbSize, ptable->u32Version));
664
665 if ( ptable->cbSize != sizeof (VBOXHGCMSVCFNTABLE)
666 || ptable->u32Version != VBOX_HGCM_SVC_VERSION)
667 {
668 rc = VERR_INVALID_PARAMETER;
669 }
670 else
671 {
672 g_pHelpers = ptable->pHelpers;
673
674 ptable->cbClient = sizeof (void*);
675
676 ptable->pfnUnload = svcUnload;
677 ptable->pfnConnect = svcConnect;
678 ptable->pfnDisconnect = svcDisconnect;
679 ptable->pfnCall = svcCall;
680 ptable->pfnHostCall = svcHostCall;
681 ptable->pfnSaveState = svcSaveState;
682 ptable->pfnLoadState = svcLoadState;
683 ptable->pvService = NULL;
684
685 if (!crVBoxServerInit())
686 return VERR_NOT_SUPPORTED;
687
688 crVBoxServerSetPresentFBOCB(svcPresentFBO);
689 }
690 }
691
692 return rc;
693}
694
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