VirtualBox

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

Last change on this file since 48798 was 48798, checked in by vboxsync, 11 years ago

crOpenGL: notify VISIBLE_3DDATA event on remap

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 41.8 KB
Line 
1/* $Id: crservice.cpp 48798 2013-10-01 14:54:28Z vboxsync $ */
2
3/** @file
4 * VBox crOpenGL: Host service entry points.
5 */
6
7/*
8 * Copyright (C) 2006-2012 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#define LOG_GROUP LOG_GROUP_SHARED_CROPENGL
22
23#include <iprt/assert.h>
24#include <iprt/asm.h>
25#include <iprt/critsect.h>
26#include <iprt/mem.h>
27#include <iprt/semaphore.h>
28#include <iprt/stream.h>
29#include <iprt/string.h>
30#include <iprt/thread.h>
31
32#include <VBox/hgcmsvc.h>
33#include <VBox/log.h>
34#include <VBox/com/ErrorInfo.h>
35#include <VBox/com/VirtualBox.h>
36#include <VBox/com/errorprint.h>
37#include <VBox/HostServices/VBoxCrOpenGLSvc.h>
38#include <VBox/vmm/ssm.h>
39
40#include "cr_mem.h"
41#include "cr_server.h"
42
43PVBOXHGCMSVCHELPERS g_pHelpers;
44static IConsole* g_pConsole = NULL;
45static PVM g_pVM = NULL;
46
47#ifndef RT_OS_WINDOWS
48# define DWORD int
49# define WINAPI
50#endif
51
52static const char* gszVBoxOGLSSMMagic = "***OpenGL state data***";
53
54/* Used to process guest calls exceeding maximum allowed HGCM call size in a sequence of smaller calls */
55typedef struct _CRVBOXSVCBUFFER_t {
56 uint32_t uiId;
57 uint32_t uiSize;
58 void* pData;
59 _CRVBOXSVCBUFFER_t *pNext, *pPrev;
60} CRVBOXSVCBUFFER_t;
61
62static CRVBOXSVCBUFFER_t *g_pCRVBoxSVCBuffers = NULL;
63static uint32_t g_CRVBoxSVCBufferID = 0;
64
65/* svcPresentFBO related data */
66typedef struct _CRVBOXSVCPRESENTFBOCMD_t {
67 void *pData;
68 int32_t screenId, x, y, w, h;
69 _CRVBOXSVCPRESENTFBOCMD_t *pNext;
70} CRVBOXSVCPRESENTFBOCMD_t, *PCRVBOXSVCPRESENTFBOCMD_t;
71
72typedef struct _CRVBOXSVCPRESENTFBO_t {
73 PCRVBOXSVCPRESENTFBOCMD_t pQueueHead, pQueueTail; /* Head/Tail of FIFO cmds queue */
74 RTCRITSECT hQueueLock; /* Queue lock */
75 RTTHREAD hWorkerThread; /* Worker thread */
76 bool volatile bShutdownWorker; /* Shutdown flag */
77 RTSEMEVENT hEventProcess; /* Signalled when worker thread should process data or exit */
78} CRVBOXSVCPRESENTFBO_t;
79
80static CRVBOXSVCPRESENTFBO_t g_SvcPresentFBO;
81
82/* Schedule a call to a separate worker thread to avoid deadlock on EMT thread when the screen configuration changes
83 and we're processing crServerPresentFBO caused by guest application command.
84 To avoid unnecessary memcpy, worker thread frees the data passed.
85*/
86static DECLCALLBACK(void) svcPresentFBO(void *data, int32_t screenId, int32_t x, int32_t y, uint32_t w, uint32_t h)
87{
88 PCRVBOXSVCPRESENTFBOCMD_t pCmd;
89
90 pCmd = (PCRVBOXSVCPRESENTFBOCMD_t) RTMemAlloc(sizeof(CRVBOXSVCPRESENTFBOCMD_t));
91 if (!pCmd)
92 {
93 LogRel(("SHARED_CROPENGL svcPresentFBO: not enough memory (%d)\n", sizeof(CRVBOXSVCPRESENTFBOCMD_t)));
94 return;
95 }
96 pCmd->pData = data;
97 pCmd->screenId = screenId;
98 pCmd->x = x;
99 pCmd->y = y;
100 pCmd->w = w;
101 pCmd->h = h;
102 pCmd->pNext = NULL;
103
104 RTCritSectEnter(&g_SvcPresentFBO.hQueueLock);
105
106 if (g_SvcPresentFBO.pQueueTail)
107 {
108 g_SvcPresentFBO.pQueueTail->pNext = pCmd;
109 }
110 else
111 {
112 Assert(!g_SvcPresentFBO.pQueueHead);
113 g_SvcPresentFBO.pQueueHead = pCmd;
114 }
115 g_SvcPresentFBO.pQueueTail = pCmd;
116
117 RTCritSectLeave(&g_SvcPresentFBO.hQueueLock);
118
119 RTSemEventSignal(g_SvcPresentFBO.hEventProcess);
120}
121
122static DECLCALLBACK(int) svcPresentFBOWorkerThreadProc(RTTHREAD ThreadSelf, void *pvUser)
123{
124 int rc = VINF_SUCCESS;
125 PCRVBOXSVCPRESENTFBOCMD_t pCmd;
126
127 Log(("SHARED_CROPENGL svcPresentFBOWorkerThreadProc started\n"));
128
129 for (;;)
130 {
131 rc = RTSemEventWait(g_SvcPresentFBO.hEventProcess, RT_INDEFINITE_WAIT);
132 AssertRCReturn(rc, rc);
133
134 if (g_SvcPresentFBO.bShutdownWorker)
135 {
136 break;
137 }
138
139 // @todo use critsect only to fetch the list and update the g_SvcPresentFBO's pQueueHead and pQueueTail.
140 rc = RTCritSectEnter(&g_SvcPresentFBO.hQueueLock);
141 AssertRCReturn(rc, rc);
142
143 pCmd = g_SvcPresentFBO.pQueueHead;
144 while (pCmd)
145 {
146 ComPtr<IDisplay> pDisplay;
147
148 /*remove from queue*/
149 g_SvcPresentFBO.pQueueHead = pCmd->pNext;
150 if (!g_SvcPresentFBO.pQueueHead)
151 {
152 g_SvcPresentFBO.pQueueTail = NULL;
153 }
154
155 CHECK_ERROR_RET(g_pConsole, COMGETTER(Display)(pDisplay.asOutParam()), rc);
156
157 RTCritSectLeave(&g_SvcPresentFBO.hQueueLock);
158
159 CHECK_ERROR_RET(pDisplay, DrawToScreen(pCmd->screenId, (BYTE*)pCmd->pData, pCmd->x, pCmd->y, pCmd->w, pCmd->h), rc);
160
161 crFree(pCmd->pData);
162 RTMemFree(pCmd);
163
164 rc = RTCritSectEnter(&g_SvcPresentFBO.hQueueLock);
165 AssertRCReturn(rc, rc);
166 pCmd = g_SvcPresentFBO.pQueueHead;
167 }
168
169 RTCritSectLeave(&g_SvcPresentFBO.hQueueLock);
170 }
171
172 Log(("SHARED_CROPENGL svcPresentFBOWorkerThreadProc finished\n"));
173
174 return rc;
175}
176
177static int svcPresentFBOInit(void)
178{
179 int rc = VINF_SUCCESS;
180
181 g_SvcPresentFBO.pQueueHead = NULL;
182 g_SvcPresentFBO.pQueueTail = NULL;
183 g_SvcPresentFBO.bShutdownWorker = false;
184
185 rc = RTCritSectInit(&g_SvcPresentFBO.hQueueLock);
186 AssertRCReturn(rc, rc);
187
188 rc = RTSemEventCreate(&g_SvcPresentFBO.hEventProcess);
189 AssertRCReturn(rc, rc);
190
191 rc = RTThreadCreate(&g_SvcPresentFBO.hWorkerThread, svcPresentFBOWorkerThreadProc, NULL, 0,
192 RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "OpenGLWorker");
193 AssertRCReturn(rc, rc);
194
195 crVBoxServerSetPresentFBOCB(svcPresentFBO);
196
197 return rc;
198}
199
200static int svcPresentFBOTearDown(void)
201{
202 int rc = VINF_SUCCESS;
203 PCRVBOXSVCPRESENTFBOCMD_t pQueue, pTmp;
204
205 ASMAtomicWriteBool(&g_SvcPresentFBO.bShutdownWorker, true);
206 RTSemEventSignal(g_SvcPresentFBO.hEventProcess);
207 rc = RTThreadWait(g_SvcPresentFBO.hWorkerThread, 5000, NULL);
208 AssertRCReturn(rc, rc);
209
210 RTCritSectDelete(&g_SvcPresentFBO.hQueueLock);
211 RTSemEventDestroy(g_SvcPresentFBO.hEventProcess);
212
213 pQueue = g_SvcPresentFBO.pQueueHead;
214 while (pQueue)
215 {
216 pTmp = pQueue->pNext;
217 crFree(pQueue->pData);
218 RTMemFree(pQueue);
219 pQueue = pTmp;
220 }
221 g_SvcPresentFBO.pQueueHead = NULL;
222 g_SvcPresentFBO.pQueueTail = NULL;
223
224 return rc;
225}
226
227static DECLCALLBACK(void) svcNotifyEventCB(int32_t screenId, uint32_t uEvent, void*pvData)
228{
229 ComPtr<IDisplay> pDisplay;
230 ComPtr<IFramebuffer> pFramebuffer;
231 LONG xo, yo;
232
233 if (!g_pConsole)
234 {
235 crWarning("Console not defined!");
236 return;
237 }
238
239 CHECK_ERROR2_STMT(g_pConsole, COMGETTER(Display)(pDisplay.asOutParam()), return);
240
241 CHECK_ERROR2_STMT(pDisplay, GetFramebuffer(screenId, pFramebuffer.asOutParam(), &xo, &yo), return);
242
243 if (!pFramebuffer)
244 return;
245
246 CHECK_ERROR2_STMT(pFramebuffer, Notify3DEvent(uEvent, (BYTE*)pvData), return);
247}
248
249
250static DECLCALLBACK(int) svcUnload (void *)
251{
252 int rc = VINF_SUCCESS;
253
254 Log(("SHARED_CROPENGL svcUnload\n"));
255
256 crVBoxServerTearDown();
257
258 svcPresentFBOTearDown();
259
260 return rc;
261}
262
263static DECLCALLBACK(int) svcConnect (void *, uint32_t u32ClientID, void *pvClient)
264{
265 int rc = VINF_SUCCESS;
266
267 NOREF(pvClient);
268
269 Log(("SHARED_CROPENGL svcConnect: u32ClientID = %d\n", u32ClientID));
270
271 rc = crVBoxServerAddClient(u32ClientID);
272
273 return rc;
274}
275
276static DECLCALLBACK(int) svcDisconnect (void *, uint32_t u32ClientID, void *pvClient)
277{
278 int rc = VINF_SUCCESS;
279
280 NOREF(pvClient);
281
282 Log(("SHARED_CROPENGL svcDisconnect: u32ClientID = %d\n", u32ClientID));
283
284 crVBoxServerRemoveClient(u32ClientID);
285
286 return rc;
287}
288
289static DECLCALLBACK(int) svcSaveState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM)
290{
291 int rc = VINF_SUCCESS;
292
293 NOREF(pvClient);
294
295 Log(("SHARED_CROPENGL svcSaveState: u32ClientID = %d\n", u32ClientID));
296
297 /* Start*/
298 rc = SSMR3PutStrZ(pSSM, gszVBoxOGLSSMMagic);
299 AssertRCReturn(rc, rc);
300
301 /* Version */
302 rc = SSMR3PutU32(pSSM, (uint32_t) SHCROGL_SSM_VERSION);
303 AssertRCReturn(rc, rc);
304
305 /* The state itself */
306 rc = crVBoxServerSaveState(pSSM);
307 AssertRCReturn(rc, rc);
308
309 /* Save svc buffers info */
310 {
311 CRVBOXSVCBUFFER_t *pBuffer = g_pCRVBoxSVCBuffers;
312
313 rc = SSMR3PutU32(pSSM, g_CRVBoxSVCBufferID);
314 AssertRCReturn(rc, rc);
315
316 while (pBuffer)
317 {
318 rc = SSMR3PutU32(pSSM, pBuffer->uiId);
319 AssertRCReturn(rc, rc);
320
321 rc = SSMR3PutU32(pSSM, pBuffer->uiSize);
322 AssertRCReturn(rc, rc);
323
324 rc = SSMR3PutMem(pSSM, pBuffer->pData, pBuffer->uiSize);
325 AssertRCReturn(rc, rc);
326
327 pBuffer = pBuffer->pNext;
328 }
329
330 rc = SSMR3PutU32(pSSM, 0);
331 AssertRCReturn(rc, rc);
332 }
333
334 /* End */
335 rc = SSMR3PutStrZ(pSSM, gszVBoxOGLSSMMagic);
336 AssertRCReturn(rc, rc);
337
338 return VINF_SUCCESS;
339}
340
341static DECLCALLBACK(int) svcLoadState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM)
342{
343 int rc = VINF_SUCCESS;
344
345 NOREF(pvClient);
346
347 Log(("SHARED_CROPENGL svcLoadState: u32ClientID = %d\n", u32ClientID));
348
349 char psz[2000];
350 uint32_t ui32;
351
352 /* Start of data */
353 rc = SSMR3GetStrZEx(pSSM, psz, 2000, NULL);
354 AssertRCReturn(rc, rc);
355 if (strcmp(gszVBoxOGLSSMMagic, psz))
356 return VERR_SSM_UNEXPECTED_DATA;
357
358 /* Version */
359 rc = SSMR3GetU32(pSSM, &ui32);
360 AssertRCReturn(rc, rc);
361
362 /* The state itself */
363 rc = crVBoxServerLoadState(pSSM, ui32);
364
365 if (rc==VERR_SSM_DATA_UNIT_FORMAT_CHANGED && ui32!=SHCROGL_SSM_VERSION)
366 {
367 LogRel(("SHARED_CROPENGL svcLoadState: unsupported save state version %d\n", ui32));
368
369 /*@todo ugly hack, as we don't know size of stored opengl data try to read untill end of opengl data marker*/
370 /*VboxSharedCrOpenGL isn't last hgcm service now, so can't use SSMR3SkipToEndOfUnit*/
371 {
372 const char *pMatch = &gszVBoxOGLSSMMagic[0];
373 char current;
374
375 while (*pMatch)
376 {
377 rc = SSMR3GetS8(pSSM, (int8_t*)&current);
378 AssertRCReturn(rc, rc);
379
380 if (current==*pMatch)
381 {
382 pMatch++;
383 }
384 else
385 {
386 pMatch = &gszVBoxOGLSSMMagic[0];
387 }
388 }
389 }
390
391 return VINF_SUCCESS;
392 }
393 AssertRCReturn(rc, rc);
394
395 /* Load svc buffers info */
396 if (ui32>=24)
397 {
398 uint32_t uiId;
399
400 rc = SSMR3GetU32(pSSM, &g_CRVBoxSVCBufferID);
401 AssertRCReturn(rc, rc);
402
403 rc = SSMR3GetU32(pSSM, &uiId);
404 AssertRCReturn(rc, rc);
405
406 while (uiId)
407 {
408 CRVBOXSVCBUFFER_t *pBuffer = (CRVBOXSVCBUFFER_t *) RTMemAlloc(sizeof(CRVBOXSVCBUFFER_t));
409 if (!pBuffer)
410 {
411 return VERR_NO_MEMORY;
412 }
413 pBuffer->uiId = uiId;
414
415 rc = SSMR3GetU32(pSSM, &pBuffer->uiSize);
416 AssertRCReturn(rc, rc);
417
418 pBuffer->pData = RTMemAlloc(pBuffer->uiSize);
419 if (!pBuffer->pData)
420 {
421 RTMemFree(pBuffer);
422 return VERR_NO_MEMORY;
423 }
424
425 rc = SSMR3GetMem(pSSM, pBuffer->pData, pBuffer->uiSize);
426 AssertRCReturn(rc, rc);
427
428 pBuffer->pNext = g_pCRVBoxSVCBuffers;
429 pBuffer->pPrev = NULL;
430 if (g_pCRVBoxSVCBuffers)
431 {
432 g_pCRVBoxSVCBuffers->pPrev = pBuffer;
433 }
434 g_pCRVBoxSVCBuffers = pBuffer;
435
436 rc = SSMR3GetU32(pSSM, &uiId);
437 AssertRCReturn(rc, rc);
438 }
439 }
440
441 /* End of data */
442 rc = SSMR3GetStrZEx(pSSM, psz, 2000, NULL);
443 AssertRCReturn(rc, rc);
444 if (strcmp(gszVBoxOGLSSMMagic, psz))
445 return VERR_SSM_UNEXPECTED_DATA;
446
447 return VINF_SUCCESS;
448}
449
450static void svcClientVersionUnsupported(uint32_t minor, uint32_t major)
451{
452 LogRel(("SHARED_CROPENGL: unsupported client version %d.%d\n", minor, major));
453
454 /*MS's opengl32 tries to load our ICD around 30 times on failure...this is to prevent unnecessary spam*/
455 static int shown = 0;
456
457 if (g_pVM && !shown)
458 {
459 VMSetRuntimeError(g_pVM, VMSETRTERR_FLAGS_NO_WAIT, "3DSupportIncompatibleAdditions",
460 "An attempt by the virtual machine to use hardware 3D acceleration failed. "
461 "The version of the Guest Additions installed in the virtual machine does not match the "
462 "version of VirtualBox on the host. Please install appropriate Guest Additions to fix this issue");
463 shown = 1;
464 }
465}
466
467static CRVBOXSVCBUFFER_t* svcGetBuffer(uint32_t iBuffer, uint32_t cbBufferSize)
468{
469 CRVBOXSVCBUFFER_t* pBuffer;
470
471 if (iBuffer)
472 {
473 pBuffer = g_pCRVBoxSVCBuffers;
474 while (pBuffer)
475 {
476 if (pBuffer->uiId == iBuffer)
477 {
478 if (cbBufferSize && pBuffer->uiSize!=cbBufferSize)
479 {
480 static int shown=0;
481
482 if (shown<20)
483 {
484 shown++;
485 LogRel(("SHARED_CROPENGL svcGetBuffer: invalid buffer(%i) size %i instead of %i\n",
486 iBuffer, pBuffer->uiSize, cbBufferSize));
487 }
488 return NULL;
489 }
490 return pBuffer;
491 }
492 pBuffer = pBuffer->pNext;
493 }
494 return NULL;
495 }
496 else /*allocate new buffer*/
497 {
498 pBuffer = (CRVBOXSVCBUFFER_t*) RTMemAlloc(sizeof(CRVBOXSVCBUFFER_t));
499 if (pBuffer)
500 {
501 pBuffer->pData = RTMemAlloc(cbBufferSize);
502 if (!pBuffer->pData)
503 {
504 LogRel(("SHARED_CROPENGL svcGetBuffer: not enough memory (%d)\n", cbBufferSize));
505 RTMemFree(pBuffer);
506 return NULL;
507 }
508 pBuffer->uiId = ++g_CRVBoxSVCBufferID;
509 if (!pBuffer->uiId)
510 {
511 pBuffer->uiId = ++g_CRVBoxSVCBufferID;
512 }
513 Assert(pBuffer->uiId);
514 pBuffer->uiSize = cbBufferSize;
515 pBuffer->pPrev = NULL;
516 pBuffer->pNext = g_pCRVBoxSVCBuffers;
517 if (g_pCRVBoxSVCBuffers)
518 {
519 g_pCRVBoxSVCBuffers->pPrev = pBuffer;
520 }
521 g_pCRVBoxSVCBuffers = pBuffer;
522 }
523 else
524 {
525 LogRel(("SHARED_CROPENGL svcGetBuffer: not enough memory (%d)\n", sizeof(CRVBOXSVCBUFFER_t)));
526 }
527 return pBuffer;
528 }
529}
530
531static void svcFreeBuffer(CRVBOXSVCBUFFER_t* pBuffer)
532{
533 Assert(pBuffer);
534
535 if (pBuffer->pPrev)
536 {
537 pBuffer->pPrev->pNext = pBuffer->pNext;
538 }
539 else
540 {
541 Assert(pBuffer==g_pCRVBoxSVCBuffers);
542 g_pCRVBoxSVCBuffers = pBuffer->pNext;
543 }
544
545 if (pBuffer->pNext)
546 {
547 pBuffer->pNext->pPrev = pBuffer->pPrev;
548 }
549
550 RTMemFree(pBuffer->pData);
551 RTMemFree(pBuffer);
552}
553
554static DECLCALLBACK(void) svcCall (void *, VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID, void *pvClient, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
555{
556 int rc = VINF_SUCCESS;
557
558 NOREF(pvClient);
559
560 Log(("SHARED_CROPENGL svcCall: u32ClientID = %d, fn = %d, cParms = %d, pparms = %d\n", u32ClientID, u32Function, cParms, paParms));
561
562#ifdef DEBUG
563 uint32_t i;
564
565 for (i = 0; i < cParms; i++)
566 {
567 /** @todo parameters other than 32 bit */
568 Log((" pparms[%d]: type %d value %d\n", i, paParms[i].type, paParms[i].u.uint32));
569 }
570#endif
571
572 switch (u32Function)
573 {
574 case SHCRGL_GUEST_FN_WRITE:
575 {
576 Log(("svcCall: SHCRGL_GUEST_FN_WRITE\n"));
577
578 /* Verify parameter count and types. */
579 if (cParms != SHCRGL_CPARMS_WRITE)
580 {
581 rc = VERR_INVALID_PARAMETER;
582 }
583 else
584 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pBuffer */
585 )
586 {
587 rc = VERR_INVALID_PARAMETER;
588 }
589 else
590 {
591 /* Fetch parameters. */
592 uint8_t *pBuffer = (uint8_t *)paParms[0].u.pointer.addr;
593 uint32_t cbBuffer = paParms[0].u.pointer.size;
594
595 /* Execute the function. */
596 rc = crVBoxServerClientWrite(u32ClientID, pBuffer, cbBuffer);
597 if (!RT_SUCCESS(rc))
598 {
599 Assert(VERR_NOT_SUPPORTED==rc);
600 svcClientVersionUnsupported(0, 0);
601 }
602
603 }
604 break;
605 }
606
607 case SHCRGL_GUEST_FN_INJECT:
608 {
609 Log(("svcCall: SHCRGL_GUEST_FN_INJECT\n"));
610
611 /* Verify parameter count and types. */
612 if (cParms != SHCRGL_CPARMS_INJECT)
613 {
614 rc = VERR_INVALID_PARAMETER;
615 }
616 else
617 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* u32ClientID */
618 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR /* pBuffer */
619 )
620 {
621 rc = VERR_INVALID_PARAMETER;
622 }
623 else
624 {
625 /* Fetch parameters. */
626 uint32_t u32InjectClientID = paParms[0].u.uint32;
627 uint8_t *pBuffer = (uint8_t *)paParms[1].u.pointer.addr;
628 uint32_t cbBuffer = paParms[1].u.pointer.size;
629
630 /* Execute the function. */
631 rc = crVBoxServerClientWrite(u32InjectClientID, pBuffer, cbBuffer);
632 if (!RT_SUCCESS(rc))
633 {
634 if (VERR_NOT_SUPPORTED==rc)
635 {
636 svcClientVersionUnsupported(0, 0);
637 }
638 else
639 {
640 crWarning("SHCRGL_GUEST_FN_INJECT failed to inject for %i from %i", u32InjectClientID, u32ClientID);
641 }
642 }
643 }
644 break;
645 }
646
647 case SHCRGL_GUEST_FN_READ:
648 {
649 Log(("svcCall: SHCRGL_GUEST_FN_READ\n"));
650
651 /* Verify parameter count and types. */
652 if (cParms != SHCRGL_CPARMS_READ)
653 {
654 rc = VERR_INVALID_PARAMETER;
655 }
656 else
657 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pBuffer */
658 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* cbBuffer */
659 )
660 {
661 rc = VERR_INVALID_PARAMETER;
662 }
663
664 /* Fetch parameters. */
665 uint8_t *pBuffer = (uint8_t *)paParms[0].u.pointer.addr;
666 uint32_t cbBuffer = paParms[0].u.pointer.size;
667
668 /* Execute the function. */
669 rc = crVBoxServerClientRead(u32ClientID, pBuffer, &cbBuffer);
670
671 if (RT_SUCCESS(rc))
672 {
673 /* Update parameters.*/
674 paParms[0].u.pointer.size = cbBuffer; //@todo guest doesn't see this change somehow?
675 } else if (VERR_NOT_SUPPORTED==rc)
676 {
677 svcClientVersionUnsupported(0, 0);
678 }
679
680 /* Return the required buffer size always */
681 paParms[1].u.uint32 = cbBuffer;
682
683 break;
684 }
685
686 case SHCRGL_GUEST_FN_WRITE_READ:
687 {
688 Log(("svcCall: SHCRGL_GUEST_FN_WRITE_READ\n"));
689
690 /* Verify parameter count and types. */
691 if (cParms != SHCRGL_CPARMS_WRITE_READ)
692 {
693 rc = VERR_INVALID_PARAMETER;
694 }
695 else
696 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pBuffer */
697 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR /* pWriteback */
698 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* cbWriteback */
699 )
700 {
701 rc = VERR_INVALID_PARAMETER;
702 }
703 else
704 {
705 /* Fetch parameters. */
706 uint8_t *pBuffer = (uint8_t *)paParms[0].u.pointer.addr;
707 uint32_t cbBuffer = paParms[0].u.pointer.size;
708
709 uint8_t *pWriteback = (uint8_t *)paParms[1].u.pointer.addr;
710 uint32_t cbWriteback = paParms[1].u.pointer.size;
711
712 /* Execute the function. */
713 rc = crVBoxServerClientWrite(u32ClientID, pBuffer, cbBuffer);
714 if (!RT_SUCCESS(rc))
715 {
716 Assert(VERR_NOT_SUPPORTED==rc);
717 svcClientVersionUnsupported(0, 0);
718 }
719
720 rc = crVBoxServerClientRead(u32ClientID, pWriteback, &cbWriteback);
721
722 if (RT_SUCCESS(rc))
723 {
724 /* Update parameters.*/
725 paParms[1].u.pointer.size = cbWriteback;
726 }
727 /* Return the required buffer size always */
728 paParms[2].u.uint32 = cbWriteback;
729 }
730
731 break;
732 }
733
734 case SHCRGL_GUEST_FN_SET_VERSION:
735 {
736 Log(("svcCall: SHCRGL_GUEST_FN_SET_VERSION\n"));
737
738 /* Verify parameter count and types. */
739 if (cParms != SHCRGL_CPARMS_SET_VERSION)
740 {
741 rc = VERR_INVALID_PARAMETER;
742 }
743 else
744 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* vMajor */
745 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* vMinor */
746 )
747 {
748 rc = VERR_INVALID_PARAMETER;
749 }
750 else
751 {
752 /* Fetch parameters. */
753 uint32_t vMajor = paParms[0].u.uint32;
754 uint32_t vMinor = paParms[1].u.uint32;
755
756 /* Execute the function. */
757 rc = crVBoxServerClientSetVersion(u32ClientID, vMajor, vMinor);
758
759 if (!RT_SUCCESS(rc))
760 {
761 svcClientVersionUnsupported(vMajor, vMinor);
762 }
763 }
764
765 break;
766 }
767
768 case SHCRGL_GUEST_FN_SET_PID:
769 {
770 Log(("svcCall: SHCRGL_GUEST_FN_SET_PID\n"));
771
772 /* Verify parameter count and types. */
773 if (cParms != SHCRGL_CPARMS_SET_PID)
774 {
775 rc = VERR_INVALID_PARAMETER;
776 }
777 else
778 if (paParms[0].type != VBOX_HGCM_SVC_PARM_64BIT)
779 {
780 rc = VERR_INVALID_PARAMETER;
781 }
782 else
783 {
784 /* Fetch parameters. */
785 uint64_t pid = paParms[0].u.uint64;
786
787 /* Execute the function. */
788 rc = crVBoxServerClientSetPID(u32ClientID, pid);
789 }
790
791 break;
792 }
793
794 case SHCRGL_GUEST_FN_WRITE_BUFFER:
795 {
796 Log(("svcCall: SHCRGL_GUEST_FN_WRITE_BUFFER\n"));
797 /* Verify parameter count and types. */
798 if (cParms != SHCRGL_CPARMS_WRITE_BUFFER)
799 {
800 rc = VERR_INVALID_PARAMETER;
801 }
802 else
803 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /*iBufferID*/
804 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /*cbBufferSize*/
805 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /*ui32Offset*/
806 || paParms[3].type != VBOX_HGCM_SVC_PARM_PTR /*pBuffer*/
807 )
808 {
809 rc = VERR_INVALID_PARAMETER;
810 }
811 else
812 {
813 /* Fetch parameters. */
814 uint32_t iBuffer = paParms[0].u.uint32;
815 uint32_t cbBufferSize = paParms[1].u.uint32;
816 uint32_t ui32Offset = paParms[2].u.uint32;
817 uint8_t *pBuffer = (uint8_t *)paParms[3].u.pointer.addr;
818 uint32_t cbBuffer = paParms[3].u.pointer.size;
819
820 /* Execute the function. */
821 CRVBOXSVCBUFFER_t *pSvcBuffer = svcGetBuffer(iBuffer, cbBufferSize);
822 if (!pSvcBuffer || ((uint64_t)ui32Offset+cbBuffer)>cbBufferSize)
823 {
824 rc = VERR_INVALID_PARAMETER;
825 }
826 else
827 {
828 memcpy((void*)((uintptr_t)pSvcBuffer->pData+ui32Offset), pBuffer, cbBuffer);
829
830 /* Return the buffer id */
831 paParms[0].u.uint32 = pSvcBuffer->uiId;
832 }
833 }
834
835 break;
836 }
837
838 case SHCRGL_GUEST_FN_WRITE_READ_BUFFERED:
839 {
840 Log(("svcCall: SHCRGL_GUEST_FN_WRITE_READ_BUFFERED\n"));
841
842 /* Verify parameter count and types. */
843 if (cParms != SHCRGL_CPARMS_WRITE_READ_BUFFERED)
844 {
845 rc = VERR_INVALID_PARAMETER;
846 }
847 else
848 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* iBufferID */
849 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR /* pWriteback */
850 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* cbWriteback */
851 || !paParms[0].u.uint32 /*iBufferID can't be 0 here*/
852 )
853 {
854 rc = VERR_INVALID_PARAMETER;
855 }
856 else
857 {
858 /* Fetch parameters. */
859 uint32_t iBuffer = paParms[0].u.uint32;
860 uint8_t *pWriteback = (uint8_t *)paParms[1].u.pointer.addr;
861 uint32_t cbWriteback = paParms[1].u.pointer.size;
862
863 CRVBOXSVCBUFFER_t *pSvcBuffer = svcGetBuffer(iBuffer, 0);
864 if (!pSvcBuffer)
865 {
866 LogRel(("SHARED_CROPENGL svcCall(WRITE_READ_BUFFERED): invalid buffer (%d)\n", iBuffer));
867 rc = VERR_INVALID_PARAMETER;
868 break;
869 }
870
871 uint8_t *pBuffer = (uint8_t *)pSvcBuffer->pData;
872 uint32_t cbBuffer = pSvcBuffer->uiSize;
873
874 /* Execute the function. */
875 rc = crVBoxServerClientWrite(u32ClientID, pBuffer, cbBuffer);
876 if (!RT_SUCCESS(rc))
877 {
878 Assert(VERR_NOT_SUPPORTED==rc);
879 svcClientVersionUnsupported(0, 0);
880 }
881
882 rc = crVBoxServerClientRead(u32ClientID, pWriteback, &cbWriteback);
883
884 if (RT_SUCCESS(rc))
885 {
886 /* Update parameters.*/
887 paParms[1].u.pointer.size = cbWriteback;
888 }
889 /* Return the required buffer size always */
890 paParms[2].u.uint32 = cbWriteback;
891
892 svcFreeBuffer(pSvcBuffer);
893 }
894
895 break;
896 }
897
898 case SHCRGL_GUEST_FN_GET_CAPS:
899 {
900 Log(("svcCall: SHCRGL_GUEST_FN_GET_CAPS\n"));
901
902 /* Verify parameter count and types. */
903 if (cParms != SHCRGL_CPARMS_GET_CAPS)
904 {
905 rc = VERR_INVALID_PARAMETER;
906 }
907 else
908 if (paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT)
909 {
910 rc = VERR_INVALID_PARAMETER;
911 }
912 else
913 {
914 /* Execute the function. */
915 rc = crVBoxServerClientGetCaps(u32ClientID, &paParms[0].u.uint32);
916 AssertRC(rc);
917 }
918
919 break;
920 }
921
922 default:
923 {
924 rc = VERR_NOT_IMPLEMENTED;
925 }
926 }
927
928
929 LogFlow(("svcCall: rc = %Rrc\n", rc));
930
931 g_pHelpers->pfnCallComplete (callHandle, rc);
932}
933
934/*
935 * We differentiate between a function handler for the guest and one for the host.
936 */
937static DECLCALLBACK(int) svcHostCall (void *, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
938{
939 int rc = VINF_SUCCESS;
940
941 Log(("SHARED_CROPENGL svcHostCall: fn = %d, cParms = %d, pparms = %d\n", u32Function, cParms, paParms));
942
943#ifdef DEBUG
944 uint32_t i;
945
946 for (i = 0; i < cParms; i++)
947 {
948 /** @todo parameters other than 32 bit */
949 Log((" pparms[%d]: type %d value %d\n", i, paParms[i].type, paParms[i].u.uint32));
950 }
951#endif
952
953 switch (u32Function)
954 {
955#ifdef VBOX_WITH_CRHGSMI
956 case SHCRGL_HOST_FN_CRHGSMI_CMD:
957 {
958 Assert(cParms == 1 && paParms[0].type == VBOX_HGCM_SVC_PARM_PTR);
959 if (cParms == 1 && paParms[0].type == VBOX_HGCM_SVC_PARM_PTR)
960 {
961 rc = crVBoxServerCrHgsmiCmd((PVBOXVDMACMD_CHROMIUM_CMD)paParms[0].u.pointer.addr, paParms[0].u.pointer.size);
962 if (VERR_NOT_SUPPORTED == rc)
963 {
964 svcClientVersionUnsupported(0, 0);
965 }
966 }
967 else
968 rc = VERR_INVALID_PARAMETER;
969 } break;
970 case SHCRGL_HOST_FN_CRHGSMI_CTL:
971 {
972 Assert(cParms == 1 && paParms[0].type == VBOX_HGCM_SVC_PARM_PTR);
973 if (cParms == 1 && paParms[0].type == VBOX_HGCM_SVC_PARM_PTR)
974 rc = crVBoxServerCrHgsmiCtl((PVBOXVDMACMD_CHROMIUM_CTL)paParms[0].u.pointer.addr, paParms[0].u.pointer.size);
975 else
976 rc = VERR_INVALID_PARAMETER;
977 } break;
978#endif
979 case SHCRGL_HOST_FN_SET_CONSOLE:
980 {
981 Log(("svcCall: SHCRGL_HOST_FN_SET_DISPLAY\n"));
982
983 /* Verify parameter count and types. */
984 if (cParms != SHCRGL_CPARMS_SET_CONSOLE)
985 {
986 rc = VERR_INVALID_PARAMETER;
987 }
988 else if (paParms[0].type != VBOX_HGCM_SVC_PARM_PTR)
989 {
990 rc = VERR_INVALID_PARAMETER;
991 }
992 else
993 {
994 /* Fetch parameters. */
995 IConsole* pConsole = (IConsole*)paParms[0].u.pointer.addr;
996 uint32_t cbData = paParms[0].u.pointer.size;
997
998 /* Verify parameters values. */
999 if (cbData != sizeof (IConsole*))
1000 {
1001 rc = VERR_INVALID_PARAMETER;
1002 }
1003 else if (!pConsole)
1004 {
1005 rc = VERR_INVALID_PARAMETER;
1006 }
1007 else /* Execute the function. */
1008 {
1009 ComPtr<IMachine> pMachine;
1010 ComPtr<IDisplay> pDisplay;
1011 ComPtr<IFramebuffer> pFramebuffer;
1012 LONG xo, yo;
1013 LONG64 winId = 0;
1014 ULONG monitorCount, i, w, h;
1015
1016 CHECK_ERROR_BREAK(pConsole, COMGETTER(Machine)(pMachine.asOutParam()));
1017 CHECK_ERROR_BREAK(pMachine, COMGETTER(MonitorCount)(&monitorCount));
1018 CHECK_ERROR_BREAK(pConsole, COMGETTER(Display)(pDisplay.asOutParam()));
1019
1020 crServerVBoxCompositionSetEnableStateGlobal(GL_FALSE);
1021
1022 g_pConsole = pConsole;
1023
1024 rc = crVBoxServerSetScreenCount(monitorCount);
1025 AssertRCReturn(rc, rc);
1026
1027 for (i=0; i<monitorCount; ++i)
1028 {
1029 CHECK_ERROR_RET(pDisplay, GetFramebuffer(i, pFramebuffer.asOutParam(), &xo, &yo), rc);
1030
1031 if (!pFramebuffer)
1032 {
1033 rc = crVBoxServerUnmapScreen(i);
1034 AssertRCReturn(rc, rc);
1035 }
1036 else
1037 {
1038 CHECK_ERROR_RET(pFramebuffer, COMGETTER(WinId)(&winId), rc);
1039 CHECK_ERROR_RET(pFramebuffer, COMGETTER(Width)(&w), rc);
1040 CHECK_ERROR_RET(pFramebuffer, COMGETTER(Height)(&h), rc);
1041
1042 rc = crVBoxServerMapScreen(i, xo, yo, w, h, winId);
1043 AssertRCReturn(rc, rc);
1044 }
1045 }
1046
1047 crServerVBoxCompositionSetEnableStateGlobal(GL_TRUE);
1048
1049 rc = VINF_SUCCESS;
1050 }
1051 }
1052 break;
1053 }
1054 case SHCRGL_HOST_FN_SET_VM:
1055 {
1056 Log(("svcCall: SHCRGL_HOST_FN_SET_VM\n"));
1057
1058 /* Verify parameter count and types. */
1059 if (cParms != SHCRGL_CPARMS_SET_VM)
1060 {
1061 rc = VERR_INVALID_PARAMETER;
1062 }
1063 else if (paParms[0].type != VBOX_HGCM_SVC_PARM_PTR)
1064 {
1065 rc = VERR_INVALID_PARAMETER;
1066 }
1067 else
1068 {
1069 /* Fetch parameters. */
1070 PVM pVM = (PVM)paParms[0].u.pointer.addr;
1071 uint32_t cbData = paParms[0].u.pointer.size;
1072
1073 /* Verify parameters values. */
1074 if (cbData != sizeof (PVM))
1075 {
1076 rc = VERR_INVALID_PARAMETER;
1077 }
1078 else
1079 {
1080 /* Execute the function. */
1081 g_pVM = pVM;
1082 rc = VINF_SUCCESS;
1083 }
1084 }
1085 break;
1086 }
1087 case SHCRGL_HOST_FN_SET_VISIBLE_REGION:
1088 {
1089 Log(("svcCall: SHCRGL_HOST_FN_SET_VISIBLE_REGION\n"));
1090
1091 if (cParms != SHCRGL_CPARMS_SET_VISIBLE_REGION)
1092 {
1093 rc = VERR_INVALID_PARAMETER;
1094 break;
1095 }
1096
1097 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pRects */
1098 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* cRects */
1099 )
1100 {
1101 rc = VERR_INVALID_PARAMETER;
1102 break;
1103 }
1104
1105 Assert(sizeof(RTRECT)==4*sizeof(GLint));
1106
1107 rc = crVBoxServerSetRootVisibleRegion(paParms[1].u.uint32, (const RTRECT*)paParms[0].u.pointer.addr);
1108 break;
1109 }
1110 case SHCRGL_HOST_FN_SCREEN_CHANGED:
1111 {
1112 Log(("svcCall: SHCRGL_HOST_FN_SCREEN_CHANGED\n"));
1113
1114 /* Verify parameter count and types. */
1115 if (cParms != SHCRGL_CPARMS_SCREEN_CHANGED)
1116 {
1117 rc = VERR_INVALID_PARAMETER;
1118 }
1119 else if (paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT)
1120 {
1121 rc = VERR_INVALID_PARAMETER;
1122 }
1123 else
1124 {
1125 /* Fetch parameters. */
1126 uint32_t screenId = paParms[0].u.uint32;
1127
1128 /* Execute the function. */
1129 ComPtr<IDisplay> pDisplay;
1130 ComPtr<IFramebuffer> pFramebuffer;
1131 LONG xo, yo;
1132 LONG64 winId = 0;
1133 ULONG w, h;
1134
1135 Assert(g_pConsole);
1136 CHECK_ERROR_RET(g_pConsole, COMGETTER(Display)(pDisplay.asOutParam()), rc);
1137 CHECK_ERROR_RET(pDisplay, GetFramebuffer(screenId, pFramebuffer.asOutParam(), &xo, &yo), rc);
1138
1139 crServerVBoxCompositionSetEnableStateGlobal(GL_FALSE);
1140
1141 if (!pFramebuffer)
1142 {
1143 rc = crVBoxServerUnmapScreen(screenId);
1144 AssertRCReturn(rc, rc);
1145 }
1146 else
1147 {
1148 CHECK_ERROR_RET(pFramebuffer, COMGETTER(WinId)(&winId), rc);
1149
1150 if (!winId)
1151 {
1152 /* View associated with framebuffer is destroyed, happens with 2d accel enabled */
1153 rc = crVBoxServerUnmapScreen(screenId);
1154 AssertRCReturn(rc, rc);
1155 }
1156 else
1157 {
1158 CHECK_ERROR_RET(pFramebuffer, COMGETTER(Width)(&w), rc);
1159 CHECK_ERROR_RET(pFramebuffer, COMGETTER(Height)(&h), rc);
1160
1161 rc = crVBoxServerMapScreen(screenId, xo, yo, w, h, winId);
1162 AssertRCReturn(rc, rc);
1163 }
1164 }
1165
1166 crServerVBoxCompositionSetEnableStateGlobal(GL_TRUE);
1167
1168 rc = VINF_SUCCESS;
1169 }
1170 break;
1171 }
1172 case SHCRGL_HOST_FN_VIEWPORT_CHANGED:
1173 {
1174 Log(("svcCall: SHCRGL_HOST_FN_VIEWPORT_CHANGED\n"));
1175
1176 /* Verify parameter count and types. */
1177 if (cParms != SHCRGL_CPARMS_VIEWPORT_CHANGED)
1178 {
1179 LogRel(("SHCRGL_HOST_FN_VIEWPORT_CHANGED: cParms invalid - %d", cParms));
1180 rc = VERR_INVALID_PARAMETER;
1181 break;
1182 }
1183
1184 for (int i = 0; i < SHCRGL_CPARMS_VIEWPORT_CHANGED; ++i)
1185 {
1186 if (paParms[i].type != VBOX_HGCM_SVC_PARM_32BIT)
1187 {
1188 LogRel(("SHCRGL_HOST_FN_VIEWPORT_CHANGED: param[%d] type invalid - %d", i, paParms[i].type));
1189 rc = VERR_INVALID_PARAMETER;
1190 break;
1191 }
1192 }
1193
1194 if (!RT_SUCCESS(rc))
1195 {
1196 LogRel(("SHCRGL_HOST_FN_VIEWPORT_CHANGED: param validation failed, returning.."));
1197 break;
1198 }
1199
1200 crServerVBoxCompositionSetEnableStateGlobal(GL_FALSE);
1201
1202 rc = crVBoxServerSetScreenViewport((int)paParms[0].u.uint32,
1203 paParms[1].u.uint32, /* x */
1204 paParms[2].u.uint32, /* y */
1205 paParms[3].u.uint32, /* w */
1206 paParms[4].u.uint32 /* h */);
1207 if (!RT_SUCCESS(rc))
1208 {
1209 LogRel(("SHCRGL_HOST_FN_VIEWPORT_CHANGED: crVBoxServerSetScreenViewport failed, rc %d", rc));
1210 }
1211
1212 crServerVBoxCompositionSetEnableStateGlobal(GL_TRUE);
1213
1214 break;
1215 }
1216 case SHCRGL_HOST_FN_SET_OUTPUT_REDIRECT:
1217 {
1218 /*
1219 * OutputRedirect.
1220 * Note: the service calls OutputRedirect callbacks directly
1221 * and they must not block. If asynchronous processing is needed,
1222 * the callback provider must organize this.
1223 */
1224 Log(("svcCall: SHCRGL_HOST_FN_SET_OUTPUT_REDIRECT\n"));
1225
1226 /* Verify parameter count and types. */
1227 if (cParms != SHCRGL_CPARMS_SET_OUTPUT_REDIRECT)
1228 {
1229 rc = VERR_INVALID_PARAMETER;
1230 }
1231 else if (paParms[0].type != VBOX_HGCM_SVC_PARM_PTR)
1232 {
1233 rc = VERR_INVALID_PARAMETER;
1234 }
1235 else
1236 {
1237 /* Fetch parameters. */
1238 H3DOUTPUTREDIRECT *pOutputRedirect = (H3DOUTPUTREDIRECT *)paParms[0].u.pointer.addr;
1239 uint32_t cbData = paParms[0].u.pointer.size;
1240
1241 /* Verify parameters values. */
1242 if (cbData != sizeof (H3DOUTPUTREDIRECT))
1243 {
1244 rc = VERR_INVALID_PARAMETER;
1245 }
1246 else /* Execute the function. */
1247 {
1248 if (pOutputRedirect->H3DORBegin != NULL)
1249 {
1250 rc = crVBoxServerSetOffscreenRendering(GL_TRUE);
1251
1252 if (RT_SUCCESS(rc))
1253 {
1254 CROutputRedirect outputRedirect;
1255 outputRedirect.pvContext = pOutputRedirect->pvContext;
1256 outputRedirect.CRORBegin = pOutputRedirect->H3DORBegin;
1257 outputRedirect.CRORGeometry = pOutputRedirect->H3DORGeometry;
1258 outputRedirect.CRORVisibleRegion = pOutputRedirect->H3DORVisibleRegion;
1259 outputRedirect.CRORFrame = pOutputRedirect->H3DORFrame;
1260 outputRedirect.CROREnd = pOutputRedirect->H3DOREnd;
1261 outputRedirect.CRORContextProperty = pOutputRedirect->H3DORContextProperty;
1262 rc = crVBoxServerOutputRedirectSet(&outputRedirect);
1263 }
1264 }
1265 else
1266 {
1267 /* Redirection is disabled. */
1268 crVBoxServerSetOffscreenRendering(GL_FALSE);
1269 crVBoxServerOutputRedirectSet(NULL);
1270 }
1271 }
1272 }
1273 break;
1274 }
1275 default:
1276 rc = VERR_NOT_IMPLEMENTED;
1277 break;
1278 }
1279
1280 LogFlow(("svcHostCall: rc = %Rrc\n", rc));
1281 return rc;
1282}
1283
1284extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad (VBOXHGCMSVCFNTABLE *ptable)
1285{
1286 int rc = VINF_SUCCESS;
1287
1288 Log(("SHARED_CROPENGL VBoxHGCMSvcLoad: ptable = %p\n", ptable));
1289
1290 if (!ptable)
1291 {
1292 rc = VERR_INVALID_PARAMETER;
1293 }
1294 else
1295 {
1296 Log(("VBoxHGCMSvcLoad: ptable->cbSize = %d, ptable->u32Version = 0x%08X\n", ptable->cbSize, ptable->u32Version));
1297
1298 if ( ptable->cbSize != sizeof (VBOXHGCMSVCFNTABLE)
1299 || ptable->u32Version != VBOX_HGCM_SVC_VERSION)
1300 {
1301 rc = VERR_INVALID_PARAMETER;
1302 }
1303 else
1304 {
1305 g_pHelpers = ptable->pHelpers;
1306
1307 ptable->cbClient = sizeof (void*);
1308
1309 ptable->pfnUnload = svcUnload;
1310 ptable->pfnConnect = svcConnect;
1311 ptable->pfnDisconnect = svcDisconnect;
1312 ptable->pfnCall = svcCall;
1313 ptable->pfnHostCall = svcHostCall;
1314 ptable->pfnSaveState = svcSaveState;
1315 ptable->pfnLoadState = svcLoadState;
1316 ptable->pvService = NULL;
1317
1318 if (!crVBoxServerInit())
1319 return VERR_NOT_SUPPORTED;
1320
1321 rc = svcPresentFBOInit();
1322
1323 crServerVBoxSetNotifyEventCB(svcNotifyEventCB);
1324 }
1325 }
1326
1327 return rc;
1328}
1329
1330#ifdef RT_OS_WINDOWS
1331#define WIN32_LEAN_AND_MEAN
1332#include <windows.h>
1333BOOL WINAPI DllMain(HINSTANCE hDLLInst, DWORD fdwReason, LPVOID lpvReserved)
1334{
1335 (void) lpvReserved;
1336
1337 switch (fdwReason)
1338 {
1339 case DLL_THREAD_ATTACH:
1340 {
1341 crStateVBoxAttachThread();
1342 break;
1343 }
1344
1345 case DLL_PROCESS_DETACH:
1346 /* do exactly the same thing as for DLL_THREAD_DETACH since
1347 * DLL_THREAD_DETACH is not called for the thread doing DLL_PROCESS_DETACH according to msdn docs */
1348 case DLL_THREAD_DETACH:
1349 {
1350 crStateVBoxDetachThread();
1351 break;
1352 }
1353
1354 case DLL_PROCESS_ATTACH:
1355 default:
1356 break;
1357 }
1358
1359 return TRUE;
1360}
1361#endif
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