VirtualBox

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

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

*: spelling fixes, thanks Timeless!

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 28.7 KB
Line 
1/* $Id: crservice.cpp 33540 2010-10-28 09:27:05Z 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#ifdef VBOX_WITH_CRHGSMI
56#include <VBox/VBoxVideo.h>
57#endif
58
59#include <VBox/com/errorprint.h>
60
61PVBOXHGCMSVCHELPERS g_pHelpers;
62static IConsole* g_pConsole = NULL;
63static PVM g_pVM = NULL;
64#ifdef VBOX_WITH_CRHGSMI
65static uint8_t* g_pvVRamBase;
66#endif
67
68#ifndef RT_OS_WINDOWS
69#define DWORD int
70#define WINAPI
71#endif
72
73static const char* gszVBoxOGLSSMMagic = "***OpenGL state data***";
74
75static DECLCALLBACK(int) svcUnload (void *)
76{
77 int rc = VINF_SUCCESS;
78
79 Log(("SHARED_CROPENGL svcUnload\n"));
80
81 crVBoxServerTearDown();
82
83 return rc;
84}
85
86static DECLCALLBACK(int) svcConnect (void *, uint32_t u32ClientID, void *pvClient)
87{
88 int rc = VINF_SUCCESS;
89
90 NOREF(pvClient);
91
92 Log(("SHARED_CROPENGL svcConnect: u32ClientID = %d\n", u32ClientID));
93
94 rc = crVBoxServerAddClient(u32ClientID);
95
96 return rc;
97}
98
99static DECLCALLBACK(int) svcDisconnect (void *, uint32_t u32ClientID, void *pvClient)
100{
101 int rc = VINF_SUCCESS;
102
103 NOREF(pvClient);
104
105 Log(("SHARED_CROPENGL svcDisconnect: u32ClientID = %d\n", u32ClientID));
106
107 crVBoxServerRemoveClient(u32ClientID);
108
109 return rc;
110}
111
112static DECLCALLBACK(int) svcSaveState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM)
113{
114 int rc = VINF_SUCCESS;
115
116 NOREF(pvClient);
117
118 Log(("SHARED_CROPENGL svcSaveState: u32ClientID = %d\n", u32ClientID));
119
120 /* Start*/
121 rc = SSMR3PutStrZ(pSSM, gszVBoxOGLSSMMagic);
122 AssertRCReturn(rc, rc);
123
124 /* Version */
125 rc = SSMR3PutU32(pSSM, (uint32_t) SHCROGL_SSM_VERSION);
126 AssertRCReturn(rc, rc);
127
128 /* The state itself */
129 rc = crVBoxServerSaveState(pSSM);
130 AssertRCReturn(rc, rc);
131
132 /* End */
133 rc = SSMR3PutStrZ(pSSM, gszVBoxOGLSSMMagic);
134 AssertRCReturn(rc, rc);
135
136 return VINF_SUCCESS;
137}
138
139static DECLCALLBACK(int) svcLoadState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM)
140{
141 int rc = VINF_SUCCESS;
142
143 NOREF(pvClient);
144
145 Log(("SHARED_CROPENGL svcLoadState: u32ClientID = %d\n", u32ClientID));
146
147 char psz[2000];
148 uint32_t ui32;
149
150 /* Start of data */
151 rc = SSMR3GetStrZEx(pSSM, psz, 2000, NULL);
152 AssertRCReturn(rc, rc);
153 if (strcmp(gszVBoxOGLSSMMagic, psz))
154 return VERR_SSM_UNEXPECTED_DATA;
155
156 /* Version */
157 rc = SSMR3GetU32(pSSM, &ui32);
158 AssertRCReturn(rc, rc);
159
160 /* The state itself */
161 rc = crVBoxServerLoadState(pSSM, ui32);
162
163 if (rc==VERR_SSM_DATA_UNIT_FORMAT_CHANGED && ui32!=SHCROGL_SSM_VERSION)
164 {
165 LogRel(("SHARED_CROPENGL svcLoadState: unsupported save state version %d\n", ui32));
166
167 /*@todo ugly hack, as we don't know size of stored opengl data try to read untill end of opengl data marker*/
168 /*VboxSharedCrOpenGL isn't last hgcm service now, so can't use SSMR3SkipToEndOfUnit*/
169 {
170 const char *pMatch = &gszVBoxOGLSSMMagic[0];
171 char current;
172
173 while (*pMatch)
174 {
175 rc = SSMR3GetS8(pSSM, (int8_t*)&current);
176 AssertRCReturn(rc, rc);
177
178 if (current==*pMatch)
179 {
180 pMatch++;
181 }
182 else
183 {
184 pMatch = &gszVBoxOGLSSMMagic[0];
185 }
186 }
187 }
188
189 return VINF_SUCCESS;
190 }
191 AssertRCReturn(rc, rc);
192
193 /* End of data */
194 rc = SSMR3GetStrZEx(pSSM, psz, 2000, NULL);
195 AssertRCReturn(rc, rc);
196 if (strcmp(gszVBoxOGLSSMMagic, psz))
197 return VERR_SSM_UNEXPECTED_DATA;
198
199 return VINF_SUCCESS;
200}
201
202static void svcClientVersionUnsupported(uint32_t minor, uint32_t major)
203{
204 LogRel(("SHARED_CROPENGL: unsupported client version %d.%d\n", minor, major));
205
206 /*MS's opengl32 tries to load our ICD around 30 times on failure...this is to prevent unnecessary spam*/
207 static int shown = 0;
208
209 if (g_pVM && !shown)
210 {
211 VMSetRuntimeError(g_pVM, VMSETRTERR_FLAGS_NO_WAIT, "3DSupportIncompatibleAdditions",
212 "An attempt by the virtual machine to use hardware 3D acceleration failed. "
213 "The version of the Guest Additions installed in the virtual machine does not match the "
214 "version of VirtualBox on the host. Please install appropriate Guest Additions to fix this issue");
215 shown = 1;
216 }
217}
218
219static DECLCALLBACK(void) svcPresentFBO(void *data, int32_t screenId, int32_t x, int32_t y, uint32_t w, uint32_t h)
220{
221#if 0
222 ComPtr<IDisplay> pDisplay;
223 BYTE *data;
224 int i,j;
225 CHECK_ERROR(g_pConsole, COMGETTER(Display)(pDisplay.asOutParam()));
226
227 data = (BYTE*) RTMemTmpAllocZ(100*100*4);
228
229 for (i=0; i<100; i+=2)
230 {
231 for (j=0; j<100; ++j)
232 {
233 *(data+i*100*4+j*4+0) = 0xFF;
234 *(data+i*100*4+j*4+1) = 0xFF;
235 *(data+i*100*4+j*4+2) = 0xFF;
236 *(data+i*100*4+j*4+3) = 0xFF;
237 }
238 }
239
240 CHECK_ERROR(pDisplay, DrawToScreen(screenId, data, 0, 0, 100, 100));
241
242 RTMemTmpFree(data);
243#endif
244 HRESULT rc;
245 ComPtr<IDisplay> pDisplay;
246
247 CHECK_ERROR(g_pConsole, COMGETTER(Display)(pDisplay.asOutParam()));
248 CHECK_ERROR(pDisplay, DrawToScreen(screenId, (BYTE*)data, x, y, w, h));
249}
250
251static DECLCALLBACK(void) svcCall (void *, VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID, void *pvClient, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
252{
253 int rc = VINF_SUCCESS;
254
255 NOREF(pvClient);
256
257 Log(("SHARED_CROPENGL svcCall: u32ClientID = %d, fn = %d, cParms = %d, pparms = %d\n", u32ClientID, u32Function, cParms, paParms));
258
259#ifdef DEBUG
260 uint32_t i;
261
262 for (i = 0; i < cParms; i++)
263 {
264 /** @todo parameters other than 32 bit */
265 Log((" pparms[%d]: type %d value %d\n", i, paParms[i].type, paParms[i].u.uint32));
266 }
267#endif
268
269 switch (u32Function)
270 {
271 case SHCRGL_GUEST_FN_WRITE:
272 {
273 Log(("svcCall: SHCRGL_GUEST_FN_WRITE\n"));
274
275 /* Verify parameter count and types. */
276 if (cParms != SHCRGL_CPARMS_WRITE)
277 {
278 rc = VERR_INVALID_PARAMETER;
279 }
280 else
281 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pBuffer */
282 )
283 {
284 rc = VERR_INVALID_PARAMETER;
285 }
286 else
287 {
288 /* Fetch parameters. */
289 uint8_t *pBuffer = (uint8_t *)paParms[0].u.pointer.addr;
290 uint32_t cbBuffer = paParms[0].u.pointer.size;
291
292 /* Execute the function. */
293 rc = crVBoxServerClientWrite(u32ClientID, pBuffer, cbBuffer);
294 if (!RT_SUCCESS(rc))
295 {
296 Assert(VERR_NOT_SUPPORTED==rc);
297 svcClientVersionUnsupported(0, 0);
298 }
299
300 }
301 break;
302 }
303
304 case SHCRGL_GUEST_FN_INJECT:
305 {
306 Log(("svcCall: SHCRGL_GUEST_FN_INJECT\n"));
307
308 /* Verify parameter count and types. */
309 if (cParms != SHCRGL_CPARMS_INJECT)
310 {
311 rc = VERR_INVALID_PARAMETER;
312 }
313 else
314 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* u32ClientID */
315 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR /* pBuffer */
316 )
317 {
318 rc = VERR_INVALID_PARAMETER;
319 }
320 else
321 {
322 /* Fetch parameters. */
323 uint32_t u32InjectClientID = paParms[0].u.uint32;
324 uint8_t *pBuffer = (uint8_t *)paParms[1].u.pointer.addr;
325 uint32_t cbBuffer = paParms[1].u.pointer.size;
326
327 /* Execute the function. */
328 rc = crVBoxServerClientWrite(u32InjectClientID, pBuffer, cbBuffer);
329 if (!RT_SUCCESS(rc))
330 {
331 if (VERR_NOT_SUPPORTED==rc)
332 {
333 svcClientVersionUnsupported(0, 0);
334 }
335 else
336 {
337 crWarning("SHCRGL_GUEST_FN_INJECT failed to inject for %i from %i", u32InjectClientID, u32ClientID);
338 }
339 }
340 }
341 break;
342 }
343
344 case SHCRGL_GUEST_FN_READ:
345 {
346 Log(("svcCall: SHCRGL_GUEST_FN_READ\n"));
347
348 /* Verify parameter count and types. */
349 if (cParms != SHCRGL_CPARMS_READ)
350 {
351 rc = VERR_INVALID_PARAMETER;
352 }
353 else
354 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pBuffer */
355 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* cbBuffer */
356 )
357 {
358 rc = VERR_INVALID_PARAMETER;
359 }
360
361 /* Fetch parameters. */
362 uint8_t *pBuffer = (uint8_t *)paParms[0].u.pointer.addr;
363 uint32_t cbBuffer = paParms[0].u.pointer.size;
364
365 /* Execute the function. */
366 rc = crVBoxServerClientRead(u32ClientID, pBuffer, &cbBuffer);
367
368 if (RT_SUCCESS(rc))
369 {
370 /* Update parameters.*/
371 paParms[0].u.pointer.size = cbBuffer; //@todo guest doesn't see this change somehow?
372 } else if (VERR_NOT_SUPPORTED==rc)
373 {
374 svcClientVersionUnsupported(0, 0);
375 }
376
377 /* Return the required buffer size always */
378 paParms[1].u.uint32 = cbBuffer;
379
380 break;
381 }
382
383 case SHCRGL_GUEST_FN_WRITE_READ:
384 {
385 Log(("svcCall: SHCRGL_GUEST_FN_WRITE_READ\n"));
386
387 /* Verify parameter count and types. */
388 if (cParms != SHCRGL_CPARMS_WRITE_READ)
389 {
390 rc = VERR_INVALID_PARAMETER;
391 }
392 else
393 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pBuffer */
394 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR /* pWriteback */
395 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* cbWriteback */
396 )
397 {
398 rc = VERR_INVALID_PARAMETER;
399 }
400 else
401 {
402 /* Fetch parameters. */
403 uint8_t *pBuffer = (uint8_t *)paParms[0].u.pointer.addr;
404 uint32_t cbBuffer = paParms[0].u.pointer.size;
405
406 uint8_t *pWriteback = (uint8_t *)paParms[1].u.pointer.addr;
407 uint32_t cbWriteback = paParms[1].u.pointer.size;
408
409 /* Execute the function. */
410 rc = crVBoxServerClientWrite(u32ClientID, pBuffer, cbBuffer);
411 if (!RT_SUCCESS(rc))
412 {
413 Assert(VERR_NOT_SUPPORTED==rc);
414 svcClientVersionUnsupported(0, 0);
415 }
416
417 rc = crVBoxServerClientRead(u32ClientID, pWriteback, &cbWriteback);
418
419 if (RT_SUCCESS(rc))
420 {
421 /* Update parameters.*/
422 paParms[1].u.pointer.size = cbWriteback;
423 }
424 /* Return the required buffer size always */
425 paParms[2].u.uint32 = cbWriteback;
426 }
427
428 break;
429 }
430
431 case SHCRGL_GUEST_FN_SET_VERSION:
432 {
433 Log(("svcCall: SHCRGL_GUEST_FN_SET_VERSION\n"));
434
435 /* Verify parameter count and types. */
436 if (cParms != SHCRGL_CPARMS_SET_VERSION)
437 {
438 rc = VERR_INVALID_PARAMETER;
439 }
440 else
441 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* vMajor */
442 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* vMinor */
443 )
444 {
445 rc = VERR_INVALID_PARAMETER;
446 }
447 else
448 {
449 /* Fetch parameters. */
450 uint32_t vMajor = paParms[0].u.uint32;
451 uint32_t vMinor = paParms[1].u.uint32;
452
453 /* Execute the function. */
454 rc = crVBoxServerClientSetVersion(u32ClientID, vMajor, vMinor);
455
456 if (!RT_SUCCESS(rc))
457 {
458 svcClientVersionUnsupported(vMajor, vMinor);
459 }
460 }
461
462 break;
463 }
464
465 default:
466 {
467 rc = VERR_NOT_IMPLEMENTED;
468 }
469 }
470
471
472 LogFlow(("svcCall: rc = %Rrc\n", rc));
473
474 g_pHelpers->pfnCallComplete (callHandle, rc);
475}
476
477#ifdef VBOX_WITH_CRHGSMI
478static int vboxCrHgsmiCtl(PVBOXVDMACMD_CHROMIUM_CTL pCtl)
479{
480 int rc;
481
482 switch (pCtl->enmType)
483 {
484 case VBOXVDMACMD_CHROMIUM_CTL_TYPE_CRHGSMI_SETUP:
485 {
486 PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP pSetup = (PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP)pCtl;
487 g_pvVRamBase = (uint8_t*)pSetup->pvRamBase;
488 rc = VINF_SUCCESS;
489 } break;
490 default:
491 Assert(0);
492 rc = VERR_INVALID_PARAMETER;
493 }
494
495 return rc;
496}
497
498#define VBOXCRHGSMI_PTR(_off, _t) ((_t*)(g_pvVRamBase + (_off)))
499static int vboxCrHgsmiCmd(PVBOXVDMACMD_CHROMIUM_CMD pCmd)
500{
501 int rc;
502 uint32_t cBuffers = pCmd->cBuffers;
503 uint32_t cParams;
504
505 if (!g_pvVRamBase)
506 {
507 Assert(0);
508 return VERR_INVALID_STATE;
509 }
510
511 if (!cBuffers)
512 {
513 Assert(0);
514 return VERR_INVALID_PARAMETER;
515 }
516
517 cParams = cBuffers-1;
518
519 CRVBOXHGSMIHDR *pHdr = VBOXCRHGSMI_PTR(pCmd->aBuffers[0].offBuffer, CRVBOXHGSMIHDR);
520 uint32_t u32Function = pHdr->u32Function;
521 uint32_t u32ClientID = pHdr->u32ClientID;
522 /* now we compile HGCM params out of HGSMI
523 * @todo: can we avoid this ? */
524 switch (u32Function)
525 {
526
527 case SHCRGL_GUEST_FN_WRITE:
528 {
529 Log(("svcCall: SHCRGL_GUEST_FN_WRITE\n"));
530
531 CRVBOXHGSMIWRITE* pFnCmd = (CRVBOXHGSMIWRITE*)pHdr;
532
533 /* @todo: Verify */
534 if (cParams == 1)
535 {
536 VBOXVDMACMD_CHROMIUM_BUFFER *pBuf = &pCmd->aBuffers[1];
537 /* Fetch parameters. */
538 uint8_t *pBuffer = VBOXCRHGSMI_PTR(pBuf->offBuffer, uint8_t);
539 uint32_t cbBuffer = pBuf->cbBuffer;
540
541 /* Execute the function. */
542 rc = crVBoxServerClientWrite(u32ClientID, pBuffer, cbBuffer);
543 if (!RT_SUCCESS(rc))
544 {
545 Assert(VERR_NOT_SUPPORTED==rc);
546 svcClientVersionUnsupported(0, 0);
547 }
548 }
549 else
550 {
551 Assert(0);
552 rc = VERR_INVALID_PARAMETER;
553 }
554 break;
555 }
556
557 case SHCRGL_GUEST_FN_INJECT:
558 {
559 Log(("svcCall: SHCRGL_GUEST_FN_INJECT\n"));
560
561 CRVBOXHGSMIINJECT *pFnCmd = (CRVBOXHGSMIINJECT*)pHdr;
562
563 /* @todo: Verify */
564 if (cParams == 1)
565 {
566 /* Fetch parameters. */
567 uint32_t u32InjectClientID = pFnCmd->u32ClientID;
568 VBOXVDMACMD_CHROMIUM_BUFFER *pBuf = &pCmd->aBuffers[1];
569 uint8_t *pBuffer = VBOXCRHGSMI_PTR(pBuf->offBuffer, uint8_t);
570 uint32_t cbBuffer = pBuf->cbBuffer;
571
572 /* Execute the function. */
573 rc = crVBoxServerClientWrite(u32InjectClientID, pBuffer, cbBuffer);
574 if (!RT_SUCCESS(rc))
575 {
576 if (VERR_NOT_SUPPORTED==rc)
577 {
578 svcClientVersionUnsupported(0, 0);
579 }
580 else
581 {
582 crWarning("SHCRGL_GUEST_FN_INJECT failed to inject for %i from %i", u32InjectClientID, u32ClientID);
583 }
584 }
585 }
586 else
587 {
588 Assert(0);
589 rc = VERR_INVALID_PARAMETER;
590 }
591 break;
592 }
593
594 case SHCRGL_GUEST_FN_READ:
595 {
596 Log(("svcCall: SHCRGL_GUEST_FN_READ\n"));
597
598 /* @todo: Verify */
599 if (cParams == 1)
600 {
601 CRVBOXHGSMIREAD *pFnCmd = (CRVBOXHGSMIREAD*)pHdr;
602 VBOXVDMACMD_CHROMIUM_BUFFER *pBuf = &pCmd->aBuffers[1];
603 /* Fetch parameters. */
604 uint8_t *pBuffer = VBOXCRHGSMI_PTR(pBuf->offBuffer, uint8_t);
605 uint32_t cbBuffer = pBuf->cbBuffer;
606
607 /* Execute the function. */
608 rc = crVBoxServerClientRead(u32ClientID, pBuffer, &cbBuffer);
609
610 if (RT_SUCCESS(rc))
611 {
612 /* Update parameters.*/
613// paParms[0].u.pointer.size = cbBuffer; //@todo guest doesn't see this change somehow?
614 } else if (VERR_NOT_SUPPORTED==rc)
615 {
616 svcClientVersionUnsupported(0, 0);
617 }
618
619 /* Return the required buffer size always */
620 pFnCmd->cbBuffer = cbBuffer;
621 }
622 else
623 {
624 Assert(0);
625 rc = VERR_INVALID_PARAMETER;
626 }
627
628 break;
629 }
630
631 case SHCRGL_GUEST_FN_WRITE_READ:
632 {
633 Log(("svcCall: SHCRGL_GUEST_FN_WRITE_READ\n"));
634
635 /* @todo: Verify */
636 if (cParams == 2)
637 {
638 CRVBOXHGSMIWRITEREAD *pFnCmd = (CRVBOXHGSMIWRITEREAD*)pHdr;
639 VBOXVDMACMD_CHROMIUM_BUFFER *pBuf = &pCmd->aBuffers[1];
640 VBOXVDMACMD_CHROMIUM_BUFFER *pWbBuf = &pCmd->aBuffers[2];
641
642 /* Fetch parameters. */
643 uint8_t *pBuffer = VBOXCRHGSMI_PTR(pBuf->offBuffer, uint8_t);
644 uint32_t cbBuffer = pBuf->cbBuffer;
645
646 uint8_t *pWriteback = VBOXCRHGSMI_PTR(pWbBuf->offBuffer, uint8_t);
647 uint32_t cbWriteback = pWbBuf->cbBuffer;
648
649 /* Execute the function. */
650 rc = crVBoxServerClientWrite(u32ClientID, pBuffer, cbBuffer);
651 if (!RT_SUCCESS(rc))
652 {
653 Assert(VERR_NOT_SUPPORTED==rc);
654 svcClientVersionUnsupported(0, 0);
655 }
656
657 rc = crVBoxServerClientRead(u32ClientID, pWriteback, &cbWriteback);
658
659// if (RT_SUCCESS(rc))
660// {
661// /* Update parameters.*/
662// paParms[1].u.pointer.size = cbWriteback;
663// }
664 /* Return the required buffer size always */
665 pFnCmd->cbWriteback = cbWriteback;
666 }
667 else
668 {
669 Assert(0);
670 rc = VERR_INVALID_PARAMETER;
671 }
672
673 break;
674 }
675
676 case SHCRGL_GUEST_FN_SET_VERSION:
677 {
678 Assert(0);
679 rc = VERR_NOT_IMPLEMENTED;
680 break;
681 }
682
683 default:
684 {
685 Assert(0);
686 rc = VERR_NOT_IMPLEMENTED;
687 }
688
689 }
690
691 pHdr->result = rc;
692
693 return VINF_SUCCESS;
694}
695#endif
696
697/*
698 * We differentiate between a function handler for the guest and one for the host.
699 */
700static DECLCALLBACK(int) svcHostCall (void *, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
701{
702 int rc = VINF_SUCCESS;
703
704 Log(("SHARED_CROPENGL svcHostCall: fn = %d, cParms = %d, pparms = %d\n", u32Function, cParms, paParms));
705
706#ifdef DEBUG
707 uint32_t i;
708
709 for (i = 0; i < cParms; i++)
710 {
711 /** @todo parameters other than 32 bit */
712 Log((" pparms[%d]: type %d value %d\n", i, paParms[i].type, paParms[i].u.uint32));
713 }
714#endif
715
716 switch (u32Function)
717 {
718#ifdef VBOX_WITH_CRHGSMI
719 case SHCRGL_HOST_FN_CRHGSMI_CMD:
720 {
721 Assert(cParms == 1 && paParms[0].type == VBOX_HGCM_SVC_PARM_PTR);
722 if (cParms == 1 && paParms[0].type == VBOX_HGCM_SVC_PARM_PTR)
723 rc = vboxCrHgsmiCmd((PVBOXVDMACMD_CHROMIUM_CMD)paParms[0].u.pointer.addr);
724 else
725 rc = VERR_INVALID_PARAMETER;
726 } break;
727 case SHCRGL_HOST_FN_CRHGSMI_CTL:
728 {
729 Assert(cParms == 1 && paParms[0].type == VBOX_HGCM_SVC_PARM_PTR);
730 if (cParms == 1 && paParms[0].type == VBOX_HGCM_SVC_PARM_PTR)
731 rc = vboxCrHgsmiCtl((PVBOXVDMACMD_CHROMIUM_CTL)paParms[0].u.pointer.addr);
732 else
733 rc = VERR_INVALID_PARAMETER;
734 } break;
735#endif
736 case SHCRGL_HOST_FN_SET_CONSOLE:
737 {
738 Log(("svcCall: SHCRGL_HOST_FN_SET_DISPLAY\n"));
739
740 /* Verify parameter count and types. */
741 if (cParms != SHCRGL_CPARMS_SET_CONSOLE)
742 {
743 rc = VERR_INVALID_PARAMETER;
744 }
745 else if (paParms[0].type != VBOX_HGCM_SVC_PARM_PTR)
746 {
747 rc = VERR_INVALID_PARAMETER;
748 }
749 else
750 {
751 /* Fetch parameters. */
752 IConsole* pConsole = (IConsole*)paParms[0].u.pointer.addr;
753 uint32_t cbData = paParms[0].u.pointer.size;
754
755 /* Verify parameters values. */
756 if (cbData != sizeof (IConsole*))
757 {
758 rc = VERR_INVALID_PARAMETER;
759 }
760 else if (!pConsole)
761 {
762 rc = VERR_INVALID_PARAMETER;
763 }
764 else /* Execute the function. */
765 {
766 ComPtr<IMachine> pMachine;
767 ComPtr<IDisplay> pDisplay;
768 ComPtr<IFramebuffer> pFramebuffer;
769 LONG xo, yo;
770 LONG64 winId = 0;
771 ULONG monitorCount, i, w, h;
772
773 CHECK_ERROR_BREAK(pConsole, COMGETTER(Machine)(pMachine.asOutParam()));
774 CHECK_ERROR_BREAK(pMachine, COMGETTER(MonitorCount)(&monitorCount));
775 CHECK_ERROR_BREAK(pConsole, COMGETTER(Display)(pDisplay.asOutParam()));
776
777 rc = crVBoxServerSetScreenCount(monitorCount);
778 AssertRCReturn(rc, rc);
779
780 for (i=0; i<monitorCount; ++i)
781 {
782 CHECK_ERROR_RET(pDisplay, GetFramebuffer(i, pFramebuffer.asOutParam(), &xo, &yo), rc);
783
784 if (!pDisplay)
785 {
786 rc = crVBoxServerUnmapScreen(i);
787 AssertRCReturn(rc, rc);
788 }
789 else
790 {
791 CHECK_ERROR_RET(pFramebuffer, COMGETTER(WinId)(&winId), rc);
792 CHECK_ERROR_RET(pFramebuffer, COMGETTER(Width)(&w), rc);
793 CHECK_ERROR_RET(pFramebuffer, COMGETTER(Height)(&h), rc);
794
795 rc = crVBoxServerMapScreen(i, xo, yo, w, h, winId);
796 AssertRCReturn(rc, rc);
797 }
798 }
799
800 g_pConsole = pConsole;
801 rc = VINF_SUCCESS;
802 }
803 }
804 break;
805 }
806 case SHCRGL_HOST_FN_SET_VM:
807 {
808 Log(("svcCall: SHCRGL_HOST_FN_SET_VM\n"));
809
810 /* Verify parameter count and types. */
811 if (cParms != SHCRGL_CPARMS_SET_VM)
812 {
813 rc = VERR_INVALID_PARAMETER;
814 }
815 else if (paParms[0].type != VBOX_HGCM_SVC_PARM_PTR)
816 {
817 rc = VERR_INVALID_PARAMETER;
818 }
819 else
820 {
821 /* Fetch parameters. */
822 PVM pVM = (PVM)paParms[0].u.pointer.addr;
823 uint32_t cbData = paParms[0].u.pointer.size;
824
825 /* Verify parameters values. */
826 if (cbData != sizeof (PVM))
827 {
828 rc = VERR_INVALID_PARAMETER;
829 }
830 else
831 {
832 /* Execute the function. */
833 g_pVM = pVM;
834 rc = VINF_SUCCESS;
835 }
836 }
837 break;
838 }
839 case SHCRGL_HOST_FN_SET_VISIBLE_REGION:
840 {
841 Log(("svcCall: SHCRGL_HOST_FN_SET_VISIBLE_REGION\n"));
842
843 if (cParms != SHCRGL_CPARMS_SET_VISIBLE_REGION)
844 {
845 rc = VERR_INVALID_PARAMETER;
846 break;
847 }
848
849 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* pRects */
850 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* cRects */
851 )
852 {
853 rc = VERR_INVALID_PARAMETER;
854 break;
855 }
856
857 Assert(sizeof(RTRECT)==4*sizeof(GLint));
858
859 rc = crVBoxServerSetRootVisibleRegion(paParms[1].u.uint32, (GLint*)paParms[0].u.pointer.addr);
860 break;
861 }
862 case SHCRGL_HOST_FN_SCREEN_CHANGED:
863 {
864 Log(("svcCall: SHCRGL_HOST_FN_SCREEN_CHANGED\n"));
865
866 /* Verify parameter count and types. */
867 if (cParms != SHCRGL_CPARMS_SCREEN_CHANGED)
868 {
869 rc = VERR_INVALID_PARAMETER;
870 }
871 else if (paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT)
872 {
873 rc = VERR_INVALID_PARAMETER;
874 }
875 else
876 {
877 /* Fetch parameters. */
878 uint32_t screenId = paParms[0].u.uint32;
879
880 /* Execute the function. */
881 ComPtr<IDisplay> pDisplay;
882 ComPtr<IFramebuffer> pFramebuffer;
883 LONG xo, yo;
884 LONG64 winId = 0;
885 ULONG w, h;
886
887 Assert(g_pConsole);
888 CHECK_ERROR_RET(g_pConsole, COMGETTER(Display)(pDisplay.asOutParam()), rc);
889 CHECK_ERROR_RET(pDisplay, GetFramebuffer(screenId, pFramebuffer.asOutParam(), &xo, &yo), rc);
890
891 if (!pFramebuffer)
892 {
893 rc = crVBoxServerUnmapScreen(screenId);
894 AssertRCReturn(rc, rc);
895 }
896 else
897 {
898 CHECK_ERROR_RET(pFramebuffer, COMGETTER(WinId)(&winId), rc);
899 CHECK_ERROR_RET(pFramebuffer, COMGETTER(Width)(&w), rc);
900 CHECK_ERROR_RET(pFramebuffer, COMGETTER(Height)(&h), rc);
901
902 rc = crVBoxServerMapScreen(screenId, xo, yo, w, h, winId);
903 AssertRCReturn(rc, rc);
904 }
905
906 rc = VINF_SUCCESS;
907 }
908 break;
909 }
910 default:
911 rc = VERR_NOT_IMPLEMENTED;
912 break;
913 }
914
915 LogFlow(("svcHostCall: rc = %Rrc\n", rc));
916 return rc;
917}
918
919extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad (VBOXHGCMSVCFNTABLE *ptable)
920{
921 int rc = VINF_SUCCESS;
922
923 Log(("SHARED_CROPENGL VBoxHGCMSvcLoad: ptable = %p\n", ptable));
924
925 if (!ptable)
926 {
927 rc = VERR_INVALID_PARAMETER;
928 }
929 else
930 {
931 Log(("VBoxHGCMSvcLoad: ptable->cbSize = %d, ptable->u32Version = 0x%08X\n", ptable->cbSize, ptable->u32Version));
932
933 if ( ptable->cbSize != sizeof (VBOXHGCMSVCFNTABLE)
934 || ptable->u32Version != VBOX_HGCM_SVC_VERSION)
935 {
936 rc = VERR_INVALID_PARAMETER;
937 }
938 else
939 {
940 g_pHelpers = ptable->pHelpers;
941
942 ptable->cbClient = sizeof (void*);
943
944 ptable->pfnUnload = svcUnload;
945 ptable->pfnConnect = svcConnect;
946 ptable->pfnDisconnect = svcDisconnect;
947 ptable->pfnCall = svcCall;
948 ptable->pfnHostCall = svcHostCall;
949 ptable->pfnSaveState = svcSaveState;
950 ptable->pfnLoadState = svcLoadState;
951 ptable->pvService = NULL;
952
953 if (!crVBoxServerInit())
954 return VERR_NOT_SUPPORTED;
955
956 crVBoxServerSetPresentFBOCB(svcPresentFBO);
957 }
958 }
959
960 return rc;
961}
962
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette