- Timestamp:
- Apr 27, 2007 9:59:46 AM (18 years ago)
- Location:
- trunk
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/hgcmsvc.h
r1711 r2386 46 46 * 2.1->2.2 Because pfnSaveState and pfnLoadState were added 47 47 * 2.2->3.1 Because pfnHostCall is now synchronous, returns rc, and parameters were changed 48 * 3.1->3.2 Because pfnRegisterExtension was added 48 49 */ 49 #define VBOX_HGCM_SVC_VERSION_MINOR (0x0001)50 50 #define VBOX_HGCM_SVC_VERSION_MAJOR (0x0003) 51 #define VBOX_HGCM_SVC_VERSION_MINOR (0x0002) 51 52 #define VBOX_HGCM_SVC_VERSION ((VBOX_HGCM_SVC_VERSION_MAJOR << 16) + VBOX_HGCM_SVC_VERSION_MINOR) 52 53 … … 92 93 typedef VBOXHGCMSVCPARM *PVBOXHGCMSVCPARM; 93 94 95 /** Service specific extension callback. 96 * This callback is called by the service to perform service specific operation. 97 * 98 * @param pvExtension The extension pointer. 99 * @param u32Function What the callback is supposed to do. 100 * @param pvParm The function parameters. 101 * @param cbParm The size of the function parameters. 102 */ 103 typedef DECLCALLBACK(int) FNHGCMSVCEXT(void *pvExtension, uint32_t u32Function, void *pvParm, uint32_t cbParms); 104 typedef FNHGCMSVCEXT *PFNHGCMSVCEXT; 105 94 106 /** The Service DLL entry points. 95 107 * … … 118 130 uint32_t cbClient; 119 131 #if ARCH_BITS == 64 120 /** Ensure that the following pointers are properly aligned on 64-bit system. 121 * To counter harm done by the paranoid #pragma pack(1). */ 122 uint32_t u32Alignment0; 132 /** Ensure that the following pointers are properly aligned on 64-bit system. */ 133 uint32_t u32Alignment0; 123 134 #endif 124 135 … … 148 159 DECLCALLBACKMEMBER(int, pfnLoadState) (uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM); 149 160 161 /** Manage the service extension. */ 162 DECLCALLBACKMEMBER(int, pfnRegisterExtension) (PFNHGCMSVCEXT pfnExtension, void *pvExtension); 163 150 164 } VBOXHGCMSVCFNTABLE; 151 165 #pragma pack() -
trunk/include/VBox/vrdpapi.h
r517 r2386 542 542 543 543 544 #define VRDP_CLIPBOARD_FORMAT_INVALID (0xFFFFFFFF) 545 #define VRDP_CLIPBOARD_FORMAT_UNICODE_TEXT (0) 546 #define VRDP_CLIPBOARD_FORMAT_BITMAP (1) 547 548 VRDPR3DECL(void) VRDPSendClipboardData (HVRDPSERVER hserver, uint32_t u32Format, void *pvData, uint32_t cbData); 544 #define VRDP_CLIPBOARD_FORMAT_NULL (0x0) 545 #define VRDP_CLIPBOARD_FORMAT_UNICODE_TEXT (0x1) 546 #define VRDP_CLIPBOARD_FORMAT_BITMAP (0x2) 547 548 #define VRDP_CLIPBOARD_FUNCTION_FORMAT_ANNOUNCE (0) 549 #define VRDP_CLIPBOARD_FUNCTION_DATA_READ (1) 550 #define VRDP_CLIPBOARD_FUNCTION_DATA_WRITE (2) 551 552 /** 553 * Called by the host when (VRDP_CLIPBOARD_FUNCTION_*): 554 * - (0) guest announces available clipboard formats; 555 * - (1) guest requests clipboard data; 556 * - (2) host responds to the client's request for clipboard data. 557 * 558 * @param hserver The VRDP server handle. 559 * @param u32Function The cause of the call. 560 * @param u32Format Bitmask of announced formats or the format of data. 561 * @param pvData Points to data from the host, as reply to (2). 562 * @param cbData Size of the data in bytes. 563 * 564 */ 565 VRDPR3DECL(void) VRDPClipboard (HVRDPSERVER hserver, 566 uint32_t u32Function, 567 uint32_t u32Format, 568 const void *pvData, 569 uint32_t cbData); 549 570 550 571 #ifdef VRDP_MC … … 586 607 587 608 /** 588 * Called by the server when a clipboard data is received from a client. 609 * Called by the server when (VRDP_CLIPBOARD_FUNCTION_*): 610 * - (0) client announces available clipboard formats; 611 * - (1) client requests clipboard data; 612 * - (2) client responds to the guest's request for clipboard data. 613 * 614 * - client announces available clipboard formats; 615 * - clipboard data is received from the client. 589 616 * 590 617 * @param pvCallback Callback specific value returned by VRDPSERVERCALLBACK::pfnInterceptClipboard. 591 * @param u32ClientId Identifies the client that sent the reply. 592 * @param u32Format The format of data. 618 * @param u32ClientId Identifies the RDP client that sent the reply. 619 * @param u32Function The cause if the callback. 620 * @param u32Format Bitmask of reported formats or the format of received data. 593 621 * @param pvData Points to data received from the client. 594 622 * @param cbData Size of the data in bytes. … … 598 626 typedef DECLCALLBACK(int) FNVRDPCLIPBOARDCALLBACK (void *pvCallback, 599 627 uint32_t u32ClientId, 628 uint32_t u32Function, 600 629 uint32_t u32Format, 601 630 const void *pvData, -
trunk/src/VBox/Additions/WINNT/VBoxService/VBoxClipboard.cpp
r1305 r2386 24 24 // #include <iprt/crc64.h> 25 25 26 #define LOG_ENABLED26 // #define LOG_ENABLED 27 27 28 28 #ifdef LOG_ENABLED … … 320 320 while ((format = EnumClipboardFormats (format)) != 0) 321 321 { 322 dprintf (("vboxClipboardChanged: format 0x%08X\n", format)); 322 323 switch (format) 323 324 { -
trunk/src/VBox/Main/ConsoleImpl.cpp
r2382 r2386 666 666 console->mConsoleVRDPServer->USBBackendDelete (u32ClientId); 667 667 } 668 669 if (fu32Intercepted & VRDP_CLIENT_INTERCEPT_CLIPBOARD) 670 { 671 console->mConsoleVRDPServer->ClipboardDelete (u32ClientId); 672 } 668 673 #else 669 674 console->mConsoleVRDPServer->DeleteUSBBackend (); … … 788 793 } 789 794 795 #ifdef VRDP_MC 796 DECLCALLBACK(void) Console::vrdp_InterceptClipboard (void *pvUser, 797 uint32_t u32ClientId, 798 PFNVRDPCLIPBOARDCALLBACK *ppfn, 799 void **ppv) 800 { 801 LogFlowFuncEnter(); 802 803 Console *console = static_cast <Console *> (pvUser); 804 AssertReturnVoid (console); 805 806 AutoCaller autoCaller (console); 807 AssertComRCReturnVoid (autoCaller.rc()); 808 809 AssertReturnVoid (console->mConsoleVRDPServer); 810 811 console->mConsoleVRDPServer->ClipboardCreate (u32ClientId, ppfn, ppv); 812 813 LogFlowFuncLeave(); 814 return; 815 } 816 #else 817 DECLCALLBACK(void) Console::vrdp_InterceptClipboard (void *pvUser, 818 PFNVRDPCLIPBOARDCALLBACK *ppfn, 819 void **ppv) 820 { 821 /* Obsolete. */ 822 return; 823 } 824 #endif /* VRDP_MC */ 825 826 790 827 // static 791 828 VRDPSERVERCALLBACK Console::sVrdpServerCallback = … … 795 832 vrdp_ClientDisconnect, 796 833 vrdp_InterceptAudio, 797 vrdp_InterceptUSB 834 vrdp_InterceptUSB, 835 vrdp_InterceptClipboard 798 836 }; 799 837 -
trunk/src/VBox/Main/ConsoleVRDPServer.cpp
r2333 r2386 26 26 #include "Logging.h" 27 27 28 #include <iprt/asm.h> 28 29 #include <iprt/ldr.h> 29 30 … … 33 34 // ConsoleVRDPServer 34 35 //////////////////////////////////////////////////////////////////////////////// 36 37 #define VBOX_CLIPBOARD_NO_DATA 0 38 #define VBOX_CLIPBOARD_DATA_WAITING 1 39 #define VBOX_CLIPBOARD_DATA_ARRIVED 2 35 40 36 41 #ifdef VBOX_VRDP … … 51 56 void (VBOXCALL *ConsoleVRDPServer::mpfnVRDPSendUpdate) (HVRDPSERVER hServer, void *pvUpdate, uint32_t cbUpdate); 52 57 void (VBOXCALL *ConsoleVRDPServer::mpfnVRDPQueryInfo) (HVRDPSERVER hserver, uint32_t index, void *pvBuffer, uint32_t cbBuffer, uint32_t *pcbOut); 58 void (VBOXCALL *ConsoleVRDPServer::mpfnVRDPClipboard) (HVRDPSERVER hserver, uint32_t u32Function, uint32_t u32Format, const void *pvData, uint32_t cbData); 53 59 #endif 54 60 … … 60 66 int rc = RTCritSectInit (&mCritSect); 61 67 AssertRC (rc); 62 68 69 mcClipboardRefs = 0; 70 mpfnClipboardCallback = NULL; 71 72 rc = RTSemEventMultiCreate(&mEventClipboardData); 73 AssertRC (rc); 74 mpvClipboardData = NULL; 75 mcbClipboardData = 0; 76 mfu32ClipboardWaitData = VBOX_CLIPBOARD_NO_DATA; 77 63 78 #ifdef VBOX_WITH_USB 64 79 mUSBBackends.pHead = NULL; … … 86 101 #ifdef VRDP_MC 87 102 Stop (); 103 104 RTSemEventMultiDestroy (mEventClipboardData); 88 105 89 106 if (RTCritSectIsInitialized (&mCritSect)) … … 417 434 } 418 435 436 DECLCALLBACK(int) ConsoleVRDPServer::ClipboardCallback (void *pvCallback, 437 uint32_t u32ClientId, 438 uint32_t u32Function, 439 uint32_t u32Format, 440 const void *pvData, 441 uint32_t cbData) 442 { 443 LogFlowFunc(("pvCallback = %p, u32ClientId = %d, u32Function = %d, u32Format = 0x%08X, pvData = %p, cbData = %d\n", 444 pvCallback, u32ClientId, u32Function, u32Format, pvData, cbData)); 445 446 int rc = VINF_SUCCESS; 447 448 ConsoleVRDPServer *pServer = static_cast <ConsoleVRDPServer *>(pvCallback); 449 450 NOREF(u32ClientId); 451 452 switch (u32Function) 453 { 454 case VRDP_CLIPBOARD_FUNCTION_FORMAT_ANNOUNCE: 455 { 456 if (pServer->mpfnClipboardCallback) 457 { 458 pServer->mpfnClipboardCallback (VBOX_CLIPBOARD_EXT_FN_FORMAT_ANNOUNCE, 459 u32Format, 460 (void *)pvData, 461 cbData); 462 } 463 464 /* Discard current data. */ 465 ASMAtomicCmpXchgU32(&pServer->mfu32ClipboardWaitData, VBOX_CLIPBOARD_NO_DATA, VBOX_CLIPBOARD_DATA_ARRIVED); 466 } break; 467 468 case VRDP_CLIPBOARD_FUNCTION_DATA_READ: 469 { 470 if (pServer->mpfnClipboardCallback) 471 { 472 pServer->mpfnClipboardCallback (VBOX_CLIPBOARD_EXT_FN_DATA_READ, 473 u32Format, 474 (void *)pvData, 475 cbData); 476 } 477 } break; 478 479 case VRDP_CLIPBOARD_FUNCTION_DATA_WRITE: 480 { 481 if (ASMAtomicCmpXchgU32(&pServer->mfu32ClipboardWaitData, VBOX_CLIPBOARD_DATA_ARRIVED, VBOX_CLIPBOARD_DATA_WAITING)) 482 { 483 LogFlowFunc(("Got clipboard data\n")); 484 485 if (pServer->mpvClipboardData) 486 { 487 RTMemFree (pServer->mpvClipboardData); 488 pServer->mpvClipboardData = NULL; 489 } 490 491 if (cbData) 492 { 493 void *pv = RTMemAlloc (cbData); 494 495 memcpy (pv, pvData, cbData); 496 497 pServer->mpvClipboardData = pv; 498 pServer->mcbClipboardData = cbData; 499 } 500 else 501 { 502 pServer->mpvClipboardData = NULL; 503 pServer->mcbClipboardData = 0; 504 } 505 506 RTSemEventMultiSignal (pServer->mEventClipboardData); 507 } 508 } break; 509 510 default: 511 rc = VERR_NOT_SUPPORTED; 512 } 513 514 return rc; 515 } 516 517 DECLCALLBACK(int) ConsoleVRDPServer::ClipboardServiceExtension (void *pvExtension, 518 uint32_t u32Function, 519 void *pvParms, 520 uint32_t cbParms) 521 { 522 LogFlowFunc(("pvExtension = %p, u32Function = %d, pvParms = %p, cbParms = %d\n", 523 pvExtension, u32Function, pvParms, cbParms)); 524 525 int rc = VINF_SUCCESS; 526 527 ConsoleVRDPServer *pServer = static_cast <ConsoleVRDPServer *>(pvExtension); 528 529 VBOXCLIPBOARDEXTPARMS *pParms = (VBOXCLIPBOARDEXTPARMS *)pvParms; 530 531 switch (u32Function) 532 { 533 case VBOX_CLIPBOARD_EXT_FN_SET_CALLBACK: 534 { 535 pServer->mpfnClipboardCallback = (PFNVRDPCLIPBOARDEXTCALLBACK)pParms->pvData; 536 } break; 537 538 case VBOX_CLIPBOARD_EXT_FN_FORMAT_ANNOUNCE: 539 { 540 if (mpfnVRDPClipboard) 541 { 542 mpfnVRDPClipboard (pServer->mhServer, 543 VRDP_CLIPBOARD_FUNCTION_FORMAT_ANNOUNCE, 544 pParms->u32Format, 545 NULL, 546 0); 547 } 548 } break; 549 550 case VBOX_CLIPBOARD_EXT_FN_DATA_READ: 551 { 552 if (mpfnVRDPClipboard) 553 { 554 if (ASMAtomicCmpXchgU32(&pServer->mfu32ClipboardWaitData, VBOX_CLIPBOARD_DATA_WAITING, VBOX_CLIPBOARD_NO_DATA)) 555 { 556 LogFlowFunc(("Wait for clipboard data\n")); 557 RTSemEventMultiReset(pServer->mEventClipboardData); 558 559 mpfnVRDPClipboard (pServer->mhServer, 560 VRDP_CLIPBOARD_FUNCTION_DATA_READ, 561 pParms->u32Format, 562 NULL, 563 0); 564 565 /* Wait for the client. 10 seconds should be enough. */ 566 int rc = RTSemEventMultiWait(pServer->mEventClipboardData, 10*1000); 567 LogFlowFunc (("Wait completed rc = %d.\n", rc)); NOREF(rc); 568 } 569 570 if (pServer->mfu32ClipboardWaitData == VBOX_CLIPBOARD_DATA_ARRIVED) 571 { 572 LogFlowFunc(("Return clipboard data: pParms->cbData = %d, mcbClipboardData = %d\n", pParms->cbData, pServer->mcbClipboardData)); 573 if (pParms->cbData >= pServer->mcbClipboardData) 574 { 575 if (pServer->mcbClipboardData) 576 { 577 memcpy (pParms->pvData, pServer->mpvClipboardData, pServer->mcbClipboardData); 578 } 579 580 RTMemFree (pServer->mpvClipboardData); 581 pServer->mpvClipboardData = NULL; 582 583 pServer->mfu32ClipboardWaitData = VBOX_CLIPBOARD_NO_DATA; 584 } 585 586 pParms->cbData = pServer->mcbClipboardData; 587 } 588 else 589 { 590 pParms->pvData = NULL; 591 pParms->cbData = 0; 592 } 593 } 594 } break; 595 596 case VBOX_CLIPBOARD_EXT_FN_DATA_WRITE: 597 { 598 if (mpfnVRDPClipboard) 599 { 600 mpfnVRDPClipboard (pServer->mhServer, 601 VRDP_CLIPBOARD_FUNCTION_DATA_WRITE, 602 pParms->u32Format, 603 pParms->pvData, 604 pParms->cbData); 605 } 606 } break; 607 608 default: 609 rc = VERR_NOT_SUPPORTED; 610 } 611 612 return rc; 613 } 614 615 void ConsoleVRDPServer::ClipboardCreate (uint32_t u32ClientId, PFNVRDPCLIPBOARDCALLBACK *ppfn, void **ppv) 616 { 617 int rc = lockConsoleVRDPServer (); 618 619 if (VBOX_SUCCESS (rc)) 620 { 621 if (mcClipboardRefs == 0) 622 { 623 rc = HGCMHostRegisterServiceExtension (&mhClipboard, "VBoxSharedClipboard", ClipboardServiceExtension, this); 624 625 if (VBOX_SUCCESS (rc)) 626 { 627 mcClipboardRefs++; 628 } 629 } 630 631 if (VBOX_SUCCESS (rc)) 632 { 633 *ppfn = ClipboardCallback; 634 *ppv = this; 635 } 636 637 unlockConsoleVRDPServer (); 638 } 639 } 640 641 void ConsoleVRDPServer::ClipboardDelete (uint32_t u32ClientId) 642 { 643 int rc = lockConsoleVRDPServer (); 644 645 if (VBOX_SUCCESS (rc)) 646 { 647 mcClipboardRefs--; 648 649 if (mcClipboardRefs == 0) 650 { 651 HGCMHostUnregisterServiceExtension (mhClipboard); 652 } 653 654 unlockConsoleVRDPServer (); 655 } 656 } 657 419 658 /* That is called on INPUT thread of the VRDP server. 420 659 * The ConsoleVRDPServer keeps a list of created backend instances. … … 825 1064 DEFSYMENTRY(VRDPSendUSBRequest), 826 1065 DEFSYMENTRY(VRDPQueryInfo), 1066 DEFSYMENTRY(VRDPClipboard) 827 1067 }; 828 1068 -
trunk/src/VBox/Main/hgcm/HGCM.cpp
r2072 r2386 66 66 #define VBOX_HGCM_SVC_NAME_MAX_BYTES 1024 67 67 68 struct _HGCMSVCEXTHANDLEDATA 69 { 70 char *pszServiceName; 71 /* The service name follows. */ 72 }; 73 68 74 /** Internal helper service object. HGCM code would use it to 69 75 * hold information about services and communicate with services. … … 103 109 104 110 uint32_t *m_paClientIds; 111 112 HGCMSVCEXTHANDLE m_hExtension; 105 113 106 114 int loadServiceDLL (void); … … 127 135 */ 128 136 static int LoadService (const char *pszServiceLibrary, const char *pszServiceName); 129 void UnloadService ( );137 void UnloadService (void); 130 138 131 139 static void UnloadAll (void); … … 146 154 147 155 uint32_t SizeOfClient (void) { return m_fntable.cbClient; }; 156 157 int RegisterExtension (HGCMSVCEXTHANDLE handle, PFNHGCMSVCEXT pfnExtension, void *pvExtension); 158 void UnregisterExtension (HGCMSVCEXTHANDLE handle); 148 159 149 160 /* … … 213 224 m_cClients (0), 214 225 m_cClientsAllocated (0), 215 m_paClientIds (NULL) 226 m_paClientIds (NULL), 227 m_hExtension (NULL) 216 228 { 217 229 memset (&m_fntable, 0, sizeof (m_fntable)); … … 230 242 int HGCMService::loadServiceDLL (void) 231 243 { 232 LogFlow (("HGCMService::loadServiceDLL:m_pszSvcLibrary = %s\n", m_pszSvcLibrary));244 LogFlowFunc(("m_pszSvcLibrary = %s\n", m_pszSvcLibrary)); 233 245 234 246 if (m_pszSvcLibrary == NULL) … … 243 255 if (VBOX_SUCCESS(rc)) 244 256 { 245 LogFlow (("HGCMService::loadServiceDLL:successfully loaded the library.\n"));257 LogFlowFunc(("successfully loaded the library.\n")); 246 258 247 259 m_pfnLoad = NULL; … … 270 282 rc = m_pfnLoad (&m_fntable); 271 283 272 LogFlow (("HGCMService::loadServiceDLL:m_pfnLoad rc = %Vrc\n", rc));284 LogFlowFunc(("m_pfnLoad rc = %Vrc\n", rc)); 273 285 274 286 if (VBOX_SUCCESS (rc)) … … 294 306 else 295 307 { 296 LogFlow (("HGCMService::loadServiceDLL:failed to load service library. The service is not available %Vrc\n", rc));308 LogFlowFunc(("failed to load service library. The service is not available %Vrc\n", rc)); 297 309 m_hLdrMod = NIL_RTLDRMOD; 298 310 } … … 335 347 #define SVC_MSG_SAVESTATE (7) /* pfnSaveState. */ 336 348 #define SVC_MSG_QUIT (8) /* Terminate the thread. */ 349 #define SVC_MSG_REGEXT (9) /* pfnRegisterExtension */ 350 #define SVC_MSG_UNREGEXT (10) /* pfnRegisterExtension */ 337 351 338 352 class HGCMMsgSvcLoad: public HGCMMsgCore … … 403 417 404 418 VBOXHGCMSVCPARM *paParms; 419 }; 420 421 class HGCMMsgSvcRegisterExtension: public HGCMMsgCore 422 { 423 public: 424 /* Handle of the extension to be registered. */ 425 HGCMSVCEXTHANDLE handle; 426 /* The extension entry point. */ 427 PFNHGCMSVCEXT pfnExtension; 428 /* The extension pointer. */ 429 void *pvExtension; 430 }; 431 432 class HGCMMsgSvcUnregisterExtension: public HGCMMsgCore 433 { 434 public: 435 /* Handle of the registered extension. */ 436 HGCMSVCEXTHANDLE handle; 405 437 }; 406 438 … … 417 449 case SVC_MSG_LOADSTATE: 418 450 case SVC_MSG_SAVESTATE: return new HGCMMsgLoadSaveStateClient (); 451 case SVC_MSG_REGEXT: return new HGCMMsgSvcRegisterExtension (); 452 case SVC_MSG_UNREGEXT: return new HGCMMsgSvcUnregisterExtension (); 419 453 default: 420 454 AssertReleaseMsgFailed(("Msg id = %08X\n", u32MsgId)); … … 581 615 { 582 616 rc = VERR_HGCM_INVALID_CLIENT_ID; 617 } 618 } break; 619 620 case SVC_MSG_REGEXT: 621 { 622 HGCMMsgSvcRegisterExtension *pMsg = (HGCMMsgSvcRegisterExtension *)pMsgCore; 623 624 LogFlowFunc(("SVC_MSG_REGEXT handle = %p, pfn = %p\n", pMsg->handle, pMsg->pfnExtension)); 625 626 if (pSvc->m_hExtension) 627 { 628 rc = VERR_NOT_SUPPORTED; 629 } 630 else 631 { 632 if (pSvc->m_fntable.pfnRegisterExtension) 633 { 634 rc = pSvc->m_fntable.pfnRegisterExtension (pMsg->pfnExtension, pMsg->pvExtension); 635 } 636 else 637 { 638 rc = VERR_NOT_SUPPORTED; 639 } 640 641 if (VBOX_SUCCESS (rc)) 642 { 643 pSvc->m_hExtension = pMsg->handle; 644 } 645 } 646 } break; 647 648 case SVC_MSG_UNREGEXT: 649 { 650 HGCMMsgSvcUnregisterExtension *pMsg = (HGCMMsgSvcUnregisterExtension *)pMsgCore; 651 652 LogFlowFunc(("SVC_MSG_UNREGEXT handle = %p\n", pMsg->handle)); 653 654 if (pSvc->m_hExtension != pMsg->handle) 655 { 656 rc = VERR_NOT_SUPPORTED; 657 } 658 else 659 { 660 if (pSvc->m_fntable.pfnRegisterExtension) 661 { 662 rc = pSvc->m_fntable.pfnRegisterExtension (NULL, NULL); 663 } 664 else 665 { 666 rc = VERR_NOT_SUPPORTED; 667 } 668 669 pSvc->m_hExtension = NULL; 583 670 } 584 671 } break; … … 1278 1365 } 1279 1366 1280 /* Perform a host call the service. 1367 int HGCMService::RegisterExtension (HGCMSVCEXTHANDLE handle, 1368 PFNHGCMSVCEXT pfnExtension, 1369 void *pvExtension) 1370 { 1371 LogFlowFunc(("%s\n", handle->pszServiceName)); 1372 1373 /* Forward the message to the service thread. */ 1374 HGCMMSGHANDLE hMsg = 0; 1375 int rc = hgcmMsgAlloc (m_thread, &hMsg, SVC_MSG_REGEXT, hgcmMessageAllocSvc); 1376 1377 if (VBOX_SUCCESS(rc)) 1378 { 1379 HGCMMsgSvcRegisterExtension *pMsg = (HGCMMsgSvcRegisterExtension *)hgcmObjReference (hMsg, HGCMOBJ_MSG); 1380 AssertRelease(pMsg); 1381 1382 pMsg->handle = handle; 1383 pMsg->pfnExtension = pfnExtension; 1384 pMsg->pvExtension = pvExtension; 1385 1386 hgcmObjDereference (pMsg); 1387 1388 rc = hgcmMsgSend (hMsg); 1389 } 1390 1391 LogFlowFunc(("rc = %Vrc\n", rc)); 1392 return rc; 1393 } 1394 1395 void HGCMService::UnregisterExtension (HGCMSVCEXTHANDLE handle) 1396 { 1397 /* Forward the message to the service thread. */ 1398 HGCMMSGHANDLE hMsg = 0; 1399 int rc = hgcmMsgAlloc (m_thread, &hMsg, SVC_MSG_UNREGEXT, hgcmMessageAllocSvc); 1400 1401 if (VBOX_SUCCESS(rc)) 1402 { 1403 HGCMMsgSvcUnregisterExtension *pMsg = (HGCMMsgSvcUnregisterExtension *)hgcmObjReference (hMsg, HGCMOBJ_MSG); 1404 AssertRelease(pMsg); 1405 1406 pMsg->handle = handle; 1407 1408 hgcmObjDereference (pMsg); 1409 1410 rc = hgcmMsgSend (hMsg); 1411 } 1412 1413 LogFlowFunc(("rc = %Vrc\n", rc)); 1414 } 1415 1416 /* Perform a guest call to the service. 1281 1417 * 1282 1418 * @param pHGCMPort The port to be used for completion confirmation. … … 1319 1455 } 1320 1456 1457 LogFlowFunc(("rc = %Vrc\n", rc)); 1321 1458 return rc; 1322 1459 } … … 1369 1506 #define HGCM_MSG_RESET (16) /* Disconnect all clients from the specified service. */ 1370 1507 #define HGCM_MSG_QUIT (17) /* Unload all services and terminate the thread. */ 1508 #define HGCM_MSG_REGEXT (18) /* Register a service extension. */ 1509 #define HGCM_MSG_UNREGEXT (19) /* Unregister a service extension. */ 1371 1510 1372 1511 class HGCMMsgMainConnect: public HGCMMsgHeader … … 1423 1562 }; 1424 1563 1564 class HGCMMsgMainRegisterExtension: public HGCMMsgCore 1565 { 1566 public: 1567 /* Returned handle to be used in HGCMMsgMainUnregisterExtension. */ 1568 HGCMSVCEXTHANDLE *pHandle; 1569 /* Name of the service. */ 1570 const char *pszServiceName; 1571 /* The extension entry point. */ 1572 PFNHGCMSVCEXT pfnExtension; 1573 /* The extension pointer. */ 1574 void *pvExtension; 1575 }; 1576 1577 class HGCMMsgMainUnregisterExtension: public HGCMMsgCore 1578 { 1579 public: 1580 /* Handle of the registered extension. */ 1581 HGCMSVCEXTHANDLE handle; 1582 }; 1583 1425 1584 static HGCMMsgCore *hgcmMainMessageAlloc (uint32_t u32MsgId) 1426 1585 { … … 1435 1594 case HGCM_MSG_RESET: return new HGCMMsgMainReset (); 1436 1595 case HGCM_MSG_QUIT: return new HGCMMsgMainQuit (); 1596 case HGCM_MSG_REGEXT: return new HGCMMsgMainRegisterExtension (); 1597 case HGCM_MSG_UNREGEXT: return new HGCMMsgMainUnregisterExtension (); 1437 1598 default: 1438 1599 AssertReleaseMsgFailed(("Msg id = %08X\n", u32MsgId)); … … 1578 1739 } break; 1579 1740 1741 case HGCM_MSG_REGEXT: 1742 { 1743 HGCMMsgMainRegisterExtension *pMsg = (HGCMMsgMainRegisterExtension *)pMsgCore; 1744 1745 LogFlowFunc(("HGCM_MSG_REGEXT\n")); 1746 1747 /* Allocate the handle data. */ 1748 HGCMSVCEXTHANDLE handle = (HGCMSVCEXTHANDLE)RTMemAllocZ (sizeof (struct _HGCMSVCEXTHANDLEDATA) 1749 + strlen (pMsg->pszServiceName) 1750 + sizeof (char)); 1751 1752 if (handle == NULL) 1753 { 1754 rc = VERR_NO_MEMORY; 1755 } 1756 else 1757 { 1758 handle->pszServiceName = (char *)((uint8_t *)handle + sizeof (struct _HGCMSVCEXTHANDLEDATA)); 1759 strcpy (handle->pszServiceName, pMsg->pszServiceName); 1760 1761 HGCMService *pService; 1762 rc = HGCMService::ResolveService (&pService, handle->pszServiceName); 1763 1764 if (VBOX_SUCCESS (rc)) 1765 { 1766 pService->RegisterExtension (handle, pMsg->pfnExtension, pMsg->pvExtension); 1767 1768 pService->ReleaseService (); 1769 } 1770 1771 if (VBOX_FAILURE (rc)) 1772 { 1773 RTMemFree (handle); 1774 } 1775 else 1776 { 1777 *pMsg->pHandle = handle; 1778 } 1779 } 1780 } break; 1781 1782 case HGCM_MSG_UNREGEXT: 1783 { 1784 HGCMMsgMainUnregisterExtension *pMsg = (HGCMMsgMainUnregisterExtension *)pMsgCore; 1785 1786 LogFlowFunc(("HGCM_MSG_UNREGEXT\n")); 1787 1788 HGCMService *pService; 1789 rc = HGCMService::ResolveService (&pService, pMsg->handle->pszServiceName); 1790 1791 if (VBOX_SUCCESS (rc)) 1792 { 1793 pService->UnregisterExtension (pMsg->handle); 1794 1795 pService->ReleaseService (); 1796 } 1797 1798 RTMemFree (pMsg->handle); 1799 } break; 1800 1580 1801 default: 1581 1802 { … … 1647 1868 } 1648 1869 1870 /* Register a HGCM service extension. 1871 * 1872 * @param pHandle Returned handle for the registered extension. 1873 * @param pszServiceName The name of the service. 1874 * @param pfnExtension The extension callback. 1875 * @return VBox rc. 1876 */ 1877 int HGCMHostRegisterServiceExtension (HGCMSVCEXTHANDLE *pHandle, 1878 const char *pszServiceName, 1879 PFNHGCMSVCEXT pfnExtension, 1880 void *pvExtension) 1881 { 1882 LogFlowFunc(("pHandle = %p, name = %s, pfn = %p, rv = %p\n", pHandle, pszServiceName, pfnExtension, pvExtension)); 1883 1884 if (!pHandle || !pszServiceName || !pfnExtension) 1885 { 1886 return VERR_INVALID_PARAMETER; 1887 } 1888 1889 /* Forward the request to the main hgcm thread. */ 1890 HGCMMSGHANDLE hMsg = 0; 1891 1892 int rc = hgcmMsgAlloc (g_hgcmThread, &hMsg, HGCM_MSG_REGEXT, hgcmMainMessageAlloc); 1893 1894 if (VBOX_SUCCESS(rc)) 1895 { 1896 /* Initialize the message. Since the message is synchronous, use the supplied pointers. */ 1897 HGCMMsgMainRegisterExtension *pMsg = (HGCMMsgMainRegisterExtension *)hgcmObjReference (hMsg, HGCMOBJ_MSG); 1898 AssertRelease(pMsg); 1899 1900 pMsg->pHandle = pHandle; 1901 pMsg->pszServiceName = pszServiceName; 1902 pMsg->pfnExtension = pfnExtension; 1903 pMsg->pvExtension = pvExtension; 1904 1905 hgcmObjDereference (pMsg); 1906 1907 rc = hgcmMsgSend (hMsg); 1908 } 1909 1910 LogFlowFunc(("*pHandle = %p, rc = %Vrc\n", *pHandle, rc)); 1911 return rc; 1912 } 1913 1914 void HGCMHostUnregisterServiceExtension (HGCMSVCEXTHANDLE handle) 1915 { 1916 LogFlowFunc(("handle = %p\n", handle)); 1917 1918 /* Forward the request to the main hgcm thread. */ 1919 HGCMMSGHANDLE hMsg = 0; 1920 1921 int rc = hgcmMsgAlloc (g_hgcmThread, &hMsg, HGCM_MSG_UNREGEXT, hgcmMainMessageAlloc); 1922 1923 if (VBOX_SUCCESS(rc)) 1924 { 1925 /* Initialize the message. */ 1926 HGCMMsgMainUnregisterExtension *pMsg = (HGCMMsgMainUnregisterExtension *)hgcmObjReference (hMsg, HGCMOBJ_MSG); 1927 AssertRelease(pMsg); 1928 1929 pMsg->handle = handle; 1930 1931 hgcmObjDereference (pMsg); 1932 1933 rc = hgcmMsgSend (hMsg); 1934 } 1935 1936 LogFlowFunc(("rc = %Vrc\n", rc)); 1937 return; 1938 } 1649 1939 1650 1940 /* Find a service and inform it about a client connection, create a client handle. -
trunk/src/VBox/Main/hgcm/HGCMThread.cpp
r1788 r2386 200 200 pThread->m_fu32ThreadFlags |= HGCMMSG_TF_TERMINATED; 201 201 202 pThread->m_thread = NIL_RTTHREAD; 203 202 204 hgcmObjDeleteHandle (pThread->Handle ()); 203 204 pThread->m_thread = NIL_RTTHREAD;205 205 206 206 LogFlow(("MAIN::hgcmWorkerThreadFunc: completed HGCM thread %p\n", pThread)); -
trunk/src/VBox/Main/include/ConsoleImpl.h
r2382 r2386 410 410 static DECLCALLBACK(void) vrdp_InterceptAudio (void *pvUser, uint32_t u32ClientId); 411 411 static DECLCALLBACK(void) vrdp_InterceptUSB (void *pvUser, uint32_t u32ClientId, PFNVRDPUSBCALLBACK *ppfn, void **ppv); 412 static DECLCALLBACK(void) vrdp_InterceptClipboard (void *pvUser, uint32_t u32ClientId, PFNVRDPCLIPBOARDCALLBACK *ppfn, void **ppv); 412 413 #else 413 414 static DECLCALLBACK(int) vrdp_ClientLogon (void *pvUser, const char *pszUser, const char *pszPassword, const char *pszDomain); … … 416 417 static DECLCALLBACK(void) vrdp_InterceptAudio (void *pvUser, bool keepHostAudio); 417 418 static DECLCALLBACK(void) vrdp_InterceptUSB (void *pvUser, PFNVRDPUSBCALLBACK *ppfn, void **ppv); 419 static DECLCALLBACK(void) vrdp_InterceptClipboard (void *pvUser, PFNVRDPCLIPBOARDCALLBACK *ppfn, void **ppv); 418 420 #endif /* VRDP_MC */ 419 421 -
trunk/src/VBox/Main/include/ConsoleVRDPServer.h
r300 r2386 24 24 25 25 #include "RemoteUSBBackend.h" 26 #include "hgcm/hgcm.h" 26 27 27 28 #include <VBox/VRDPAuth.h> 29 30 #include <VBox/HostServices/VBoxClipboardExt.h> 28 31 29 32 // ConsoleVRDPServer … … 61 64 void waitRemoteUSBThreadEvent (unsigned cMillies); 62 65 66 void ClipboardCreate (uint32_t u32ClientId, PFNVRDPCLIPBOARDCALLBACK *ppfn, void **ppv); 67 void ClipboardDelete (uint32_t u32ClientId); 63 68 #else 64 69 void CreateUSBBackend (PFNVRDPUSBCALLBACK *ppfn, void **ppv); … … 116 121 static void (VBOXCALL *mpfnVRDPSendUpdate) (HVRDPSERVER hServer, void *pvUpdate, uint32_t cbUpdate); 117 122 static void (VBOXCALL *mpfnVRDPQueryInfo) (HVRDPSERVER hserver, uint32_t index, void *pvBuffer, uint32_t cbBuffer, uint32_t *pcbOut); 123 static void (VBOXCALL *mpfnVRDPClipboard) (HVRDPSERVER hserver, uint32_t u32Function, uint32_t u32Format, const void *pvData, uint32_t cbData); 118 124 #endif 119 125 … … 123 129 int lockConsoleVRDPServer (void); 124 130 void unlockConsoleVRDPServer (void); 125 131 132 int mcClipboardRefs; 133 HGCMSVCEXTHANDLE mhClipboard; 134 PFNVRDPCLIPBOARDEXTCALLBACK mpfnClipboardCallback; 135 136 RTSEMEVENTMULTI mEventClipboardData; 137 void *mpvClipboardData; 138 uint32_t mcbClipboardData; 139 volatile uint32_t mfu32ClipboardWaitData; 140 141 static DECLCALLBACK(int) ClipboardCallback (void *pvCallback, uint32_t u32ClientId, uint32_t u32Function, uint32_t u32Format, const void *pvData, uint32_t cbData); 142 static DECLCALLBACK(int) ClipboardServiceExtension (void *pvExtension, uint32_t u32Function, void *pvParm, uint32_t cbParms); 143 126 144 #ifdef VBOX_WITH_USB 127 145 RemoteUSBBackend *usbBackendFindByUUID (const Guid *pGuid); -
trunk/src/VBox/Main/include/hgcm/HGCM.h
r1711 r2386 33 33 #define HGCM_SSM_VERSION 2 34 34 35 /* Handle of a HGCM service extension. */ 36 struct _HGCMSVCEXTHANDLEDATA; 37 typedef struct _HGCMSVCEXTHANDLEDATA *HGCMSVCEXTHANDLE; 38 35 39 __BEGIN_DECLS 36 40 int HGCMHostInit (void); … … 40 44 41 45 int HGCMHostLoad (const char *pszServiceName, const char *pszServiceLibrary); 46 47 int HGCMHostRegisterServiceExtension (HGCMSVCEXTHANDLE *pHandle, const char *pszServiceName, PFNHGCMSVCEXT pfnExtension, void *pvExtension); 48 void HGCMHostUnregisterServiceExtension (HGCMSVCEXTHANDLE handle); 42 49 43 50 int HGCMGuestConnect (PPDMIHGCMPORT pHGCMPort, PVBOXHGCMCMD pCmdPtr, const char *pszServiceName, uint32_t *pClientID);
Note:
See TracChangeset
for help on using the changeset viewer.