Changeset 100374 in vbox for trunk/src/VBox/HostServices
- Timestamp:
- Jul 5, 2023 8:36:57 AM (17 months ago)
- Location:
- trunk/src/VBox/HostServices/SharedClipboard
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-internal.h
r100370 r100374 186 186 /** Transfer context. */ 187 187 SHCLTRANSFERCTX Ctx; 188 /** Transfers callbacks to use. */188 /** Backends-specific transfers callbacks to use. */ 189 189 SHCLTRANSFERCALLBACKS Callbacks; 190 /** Backends-specific transfers provider to use. */ 191 SHCLTXPROVIDER Provider; 190 192 } SHCLIENTTRANSFERS, *PSHCLIENTTRANSFERS; 191 193 #endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */ … … 473 475 /** @} */ 474 476 475 /** @name Shared Clipboard transfer interface implementations for the host service. 476 * @{ 477 */ 478 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS_HTTP 479 480 #endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS_HTTP */ 481 482 int shClSvcTransferIfaceRootsGet(PSHCLTXPROVIDERCTX pCtx, PSHCLLIST pRootList); 483 int shClSvcTransferIfaceGHListOpen(PSHCLTXPROVIDERCTX pCtx, PSHCLLISTOPENPARMS pOpenParms, PSHCLLISTHANDLE phList); 484 int shClSvcTransferIfaceGHListClose(PSHCLTXPROVIDERCTX pCtx, SHCLLISTHANDLE hList); 485 int shClSvcTransferIfaceGHListHdrRead(PSHCLTXPROVIDERCTX pCtx, SHCLLISTHANDLE hList, PSHCLLISTHDR pListHdr); 486 int shClSvcTransferIfaceHGListHdrWrite(PSHCLTXPROVIDERCTX pCtx, SHCLLISTHANDLE hList, PSHCLLISTHDR pListHdr); 487 int shClSvcTransferIfaceGHListEntryRead(PSHCLTXPROVIDERCTX pCtx, SHCLLISTHANDLE hList, PSHCLLISTENTRY pListEntry); 488 int shClSvcTransferIfaceHGListEntryWrite(PSHCLTXPROVIDERCTX pCtx, SHCLLISTHANDLE hList, PSHCLLISTENTRY pListEntry); 489 490 int shClSvcTransferIfaceGHObjOpen(PSHCLTXPROVIDERCTX pCtx, PSHCLOBJOPENCREATEPARMS pCreateParms, 491 PSHCLOBJHANDLE phObj); 492 int shClSvcTransferIfaceGHObjClose(PSHCLTXPROVIDERCTX pCtx, SHCLOBJHANDLE hObj); 493 int shClSvcTransferIfaceGHObjRead(PSHCLTXPROVIDERCTX pCtx, SHCLOBJHANDLE hObj, 494 void *pvData, uint32_t cbData, uint32_t fFlags, uint32_t *pcbRead); 495 int shClSvcTransferIfaceHGObjWrite(PSHCLTXPROVIDERCTX pCtx, SHCLOBJHANDLE hObj, 496 void *pvData, uint32_t cbData, uint32_t fFlags, uint32_t *pcbWritten); 477 /** @name Shared Clipboard transfer interface implementations for guest -> host transfers. 478 * @{ 479 */ 480 DECLCALLBACK(int) shClSvcTransferIfaceGHRootListRead(PSHCLTXPROVIDERCTX pCtx); 481 DECLCALLBACK(int) shClSvcTransferIfaceGHListOpen(PSHCLTXPROVIDERCTX pCtx, PSHCLLISTOPENPARMS pOpenParms, PSHCLLISTHANDLE phList); 482 DECLCALLBACK(int) shClSvcTransferIfaceGHListClose(PSHCLTXPROVIDERCTX pCtx, SHCLLISTHANDLE hList); 483 DECLCALLBACK(int) shClSvcTransferIfaceGHListHdrRead(PSHCLTXPROVIDERCTX pCtx, SHCLLISTHANDLE hList, PSHCLLISTHDR pListHdr); 484 DECLCALLBACK(int) shClSvcTransferIfaceGHListEntryRead(PSHCLTXPROVIDERCTX pCtx, SHCLLISTHANDLE hList, PSHCLLISTENTRY pListEntry); 485 DECLCALLBACK(int) shClSvcTransferIfaceGHObjOpen(PSHCLTXPROVIDERCTX pCtx, PSHCLOBJOPENCREATEPARMS pCreateParms, PSHCLOBJHANDLE phObj); 486 DECLCALLBACK(int) shClSvcTransferIfaceGHObjClose(PSHCLTXPROVIDERCTX pCtx, SHCLOBJHANDLE hObj); 487 DECLCALLBACK(int) shClSvcTransferIfaceGHObjRead(PSHCLTXPROVIDERCTX pCtx, SHCLOBJHANDLE hObj, void *pvData, uint32_t cbData, uint32_t fFlags, uint32_t *pcbRead); 488 /** @} */ 489 490 /** @name Shared Clipboard transfer interface implementations for host -> guest transfers. 491 * @{ 492 */ 493 DECLCALLBACK(int) shClSvcTransferIfaceHGListHdrWrite(PSHCLTXPROVIDERCTX pCtx, SHCLLISTHANDLE hList, PSHCLLISTHDR pListHdr); 494 DECLCALLBACK(int) shClSvcTransferIfaceHGListEntryWrite(PSHCLTXPROVIDERCTX pCtx, SHCLLISTHANDLE hList, PSHCLLISTENTRY pListEntry); 495 DECLCALLBACK(int) shClSvcTransferIfaceHGObjWrite(PSHCLTXPROVIDERCTX pCtx, SHCLOBJHANDLE hObj, void *pvData, uint32_t cbData, uint32_t fFlags, uint32_t *pcbWritten); 497 496 /** @} */ 498 497 -
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-transfers.cpp
r100370 r100374 2343 2343 enmDir == SHCLTRANSFERDIR_FROM_REMOTE ? "guest -> host" : "host -> guest")); 2344 2344 2345 SHCLTXPROVIDER Provider; 2346 RT_ZERO(Provider); 2347 2348 /* Assign local provider first and overwrite interface methods below if needed. */ 2349 ShClTransferProviderLocalQueryInterface(&Provider); 2350 2351 if (enmDir == SHCLTRANSFERDIR_FROM_REMOTE) /* Guest -> Host. */ 2352 { 2353 Provider.Interface.pfnRootListRead = shClSvcTransferIfaceGHRootListRead; 2354 2355 Provider.Interface.pfnListOpen = shClSvcTransferIfaceGHListOpen; 2356 Provider.Interface.pfnListClose = shClSvcTransferIfaceGHListClose; 2357 Provider.Interface.pfnListHdrRead = shClSvcTransferIfaceGHListHdrRead; 2358 Provider.Interface.pfnListEntryRead = shClSvcTransferIfaceGHListEntryRead; 2359 2360 Provider.Interface.pfnObjOpen = shClSvcTransferIfaceGHObjOpen; 2361 Provider.Interface.pfnObjClose = shClSvcTransferIfaceGHObjClose; 2362 Provider.Interface.pfnObjRead = shClSvcTransferIfaceGHObjRead; 2363 } 2364 else if (enmDir == SHCLTRANSFERDIR_TO_REMOTE) /* Host -> Guest. */ 2365 { 2366 Provider.Interface.pfnListHdrWrite = shClSvcTransferIfaceHGListHdrWrite; 2367 Provider.Interface.pfnListEntryWrite = shClSvcTransferIfaceHGListEntryWrite; 2368 Provider.Interface.pfnObjWrite = shClSvcTransferIfaceHGObjWrite; 2369 } 2370 else 2371 AssertFailed(); 2372 2373 Provider.enmSource = pClient->State.enmSource; 2374 Provider.pvUser = pClient; 2375 2376 rc = ShClTransferSetProvider(pTransfer, &Provider); 2377 if (RT_SUCCESS(rc)) 2378 { 2379 ShClTransferSetCallbacks(pTransfer, &pClient->Transfers.Callbacks); 2380 2381 rc = ShClTransferInit(pTransfer); 2382 if (RT_SUCCESS(rc)) 2383 { 2384 /* Sanity: Make sure that the transfer we're gonna report as INITIALIZED to the guest 2385 * actually has some root entries set, as the guest can query for those at any time then. */ 2386 if (enmDir == SHCLTRANSFERDIR_TO_REMOTE) 2387 AssertMsgStmt(ShClTransferRootsCount(pTransfer), ("Transfer has no root entries set\n"), rc = VERR_WRONG_ORDER); 2388 } 2345 ShClTransferSetCallbacks(pTransfer, &pClient->Transfers.Callbacks); 2346 2347 pClient->Transfers.Provider.enmSource = pClient->State.enmSource; 2348 pClient->Transfers.Provider.pvUser = pClient; 2349 2350 rc = ShClTransferInit(pTransfer); 2351 if (RT_SUCCESS(rc)) 2352 { 2353 /* Sanity: Make sure that the transfer we're gonna report as INITIALIZED to the guest 2354 * actually has some root entries set, as the guest can query for those at any time then. */ 2355 if (enmDir == SHCLTRANSFERDIR_TO_REMOTE) 2356 AssertMsgStmt(ShClTransferRootsCount(pTransfer), ("Transfer has no root entries set\n"), rc = VERR_WRONG_ORDER); 2389 2357 } 2390 2358 } -
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-win.cpp
r100370 r100374 212 212 213 213 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 214 /** 215 * @copydoc SHCLTRANSFERCALLBACKS::pfnOnCreated 216 * 217 * @thread Service main thread. 218 */ 219 static DECLCALLBACK(void) shClSvcWinTransferOnCreatedCallback(PSHCLTRANSFERCALLBACKCTX pCbCtx) 220 { 221 LogFlowFuncEnter(); 222 223 PSHCLCONTEXT pCtx = (PSHCLCONTEXT)pCbCtx->pvUser; 224 AssertPtr(pCtx); 225 226 PSHCLTRANSFER pTransfer = pCbCtx->pTransfer; 227 AssertPtr(pTransfer); 228 229 PSHCLCLIENT const pClient = pCtx->pClient; 230 AssertPtr(pClient); 231 232 /* 233 * Set transfer provider. 234 * Those will be registered within ShClSvcTransferInit() when a new transfer gets initialized. 235 */ 236 237 /* Set the interface to the local provider by default first. */ 238 RT_ZERO(pClient->Transfers.Provider); 239 ShClTransferProviderLocalQueryInterface(&pClient->Transfers.Provider); 240 241 PSHCLTXPROVIDERIFACE pIface = &pClient->Transfers.Provider.Interface; 242 243 switch (ShClTransferGetDir(pTransfer)) 244 { 245 case SHCLTRANSFERDIR_FROM_REMOTE: /* Guest -> Host. */ 246 { 247 /** @todo BUGBUG */ 248 break; 249 } 250 251 case SHCLTRANSFERDIR_TO_REMOTE: /* Host -> Guest. */ 252 { 253 /** @todo BUGBUG */ 254 break; 255 } 256 257 default: 258 AssertFailed(); 259 } 260 261 int rc = ShClTransferSetProvider(pTransfer, &pClient->Transfers.Provider); 262 263 LogFlowFuncLeaveRC(rc); 264 } 265 214 266 /** 215 267 * @copydoc SHCLTRANSFERCALLBACKS::pfnOnInitialized -
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-x11.cpp
r100370 r100374 88 88 89 89 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 90 static DECLCALLBACK(void) shClSvcX11OnTransferCreatedCallback(PSHCLTRANSFERCALLBACKCTX pCbCtx); 90 91 static DECLCALLBACK(void) shClSvcX11OnTransferInitCallback(PSHCLTRANSFERCALLBACKCTX pCbCtx); 91 92 static DECLCALLBACK(void) shClSvcX11OnTransferDestroyCallback(PSHCLTRANSFERCALLBACKCTX pCbCtx); 92 93 static DECLCALLBACK(void) shClSvcX11OnTransferUnregisteredCallback(PSHCLTRANSFERCALLBACKCTX pCbCtx, PSHCLTRANSFERCTX pTransferCtx); 94 95 static DECLCALLBACK(int) shClSvcX11TransferIfaceHGRootListRead(PSHCLTXPROVIDERCTX pCtx); 93 96 #endif 94 97 … … 171 174 pClient->Transfers.Callbacks.cbUser = sizeof(SHCLCONTEXT); 172 175 176 pClient->Transfers.Callbacks.pfnOnCreated = shClSvcX11OnTransferCreatedCallback; 173 177 pClient->Transfers.Callbacks.pfnOnInitialized = shClSvcX11OnTransferInitCallback; 174 178 pClient->Transfers.Callbacks.pfnOnDestroy = shClSvcX11OnTransferDestroyCallback; … … 383 387 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 384 388 /** 385 * @copydoc SHCLTRANSFERCALLBACKS::pfnOnInitialized 386 * 387 * This starts the HTTP server if not done yet and registers the transfer with it. 389 * @copydoc SHCLTRANSFERCALLBACKS::pfnOnCreated 388 390 * 389 391 * @thread Service main thread. 390 392 */ 391 static DECLCALLBACK(void) shClSvcX11OnTransferInitCallback(PSHCLTRANSFERCALLBACKCTX pCbCtx) 392 { 393 RT_NOREF(pCbCtx); 394 393 static DECLCALLBACK(void) shClSvcX11OnTransferCreatedCallback(PSHCLTRANSFERCALLBACKCTX pCbCtx) 394 { 395 395 LogFlowFuncEnter(); 396 396 … … 401 401 AssertPtr(pTransfer); 402 402 403 PSHCLCLIENT const pClient = pCtx->pClient; 404 AssertPtr(pClient); 405 406 /* 407 * Set transfer provider. 408 * Those will be registered within ShClSvcTransferInit() when a new transfer gets initialized. 409 */ 410 411 /* Set the interface to the local provider by default first. */ 412 RT_ZERO(pClient->Transfers.Provider); 413 ShClTransferProviderLocalQueryInterface(&pClient->Transfers.Provider); 414 415 PSHCLTXPROVIDERIFACE pIface = &pClient->Transfers.Provider.Interface; 416 417 switch (ShClTransferGetDir(pTransfer)) 418 { 419 case SHCLTRANSFERDIR_FROM_REMOTE: /* Guest -> Host. */ 420 { 421 pIface->pfnRootListRead = shClSvcTransferIfaceGHRootListRead; 422 423 pIface->pfnListOpen = shClSvcTransferIfaceGHListOpen; 424 pIface->pfnListClose = shClSvcTransferIfaceGHListClose; 425 pIface->pfnListHdrRead = shClSvcTransferIfaceGHListHdrRead; 426 pIface->pfnListEntryRead = shClSvcTransferIfaceGHListEntryRead; 427 428 pIface->pfnObjOpen = shClSvcTransferIfaceGHObjOpen; 429 pIface->pfnObjClose = shClSvcTransferIfaceGHObjClose; 430 pIface->pfnObjRead = shClSvcTransferIfaceGHObjRead; 431 break; 432 } 433 434 case SHCLTRANSFERDIR_TO_REMOTE: /* Host -> Guest. */ 435 { 436 pIface->pfnRootListRead = shClSvcX11TransferIfaceHGRootListRead; 437 break; 438 } 439 440 default: 441 AssertFailed(); 442 } 443 444 int rc = ShClTransferSetProvider(pTransfer, &pClient->Transfers.Provider); 445 446 LogFlowFuncLeaveRC(rc); 447 } 448 449 /** 450 * @copydoc SHCLTRANSFERCALLBACKS::pfnOnInitialized 451 * 452 * This starts the HTTP server if not done yet and registers the transfer with it. 453 * 454 * @thread Service main thread. 455 */ 456 static DECLCALLBACK(void) shClSvcX11OnTransferInitCallback(PSHCLTRANSFERCALLBACKCTX pCbCtx) 457 { 458 LogFlowFuncEnter(); 459 460 PSHCLCONTEXT pCtx = (PSHCLCONTEXT)pCbCtx->pvUser; 461 AssertPtr(pCtx); 462 463 PSHCLTRANSFER pTransfer = pCbCtx->pTransfer; 464 AssertPtr(pTransfer); 465 466 int rc; 467 403 468 switch (ShClTransferGetDir(pTransfer)) 404 469 { … … 407 472 # ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS_HTTP 408 473 /* We only need to start the HTTP server when we actually receive data from the remote (host). */ 409 ShClTransferHttpServerMaybeStart(&pCtx->X11.HttpCtx);474 rc = ShClTransferHttpServerMaybeStart(&pCtx->X11.HttpCtx); 410 475 # endif 411 476 break; … … 414 479 case SHCLTRANSFERDIR_TO_REMOTE: /* H->G */ 415 480 { 416 PSHCLEVENT pEvent; 417 int rc = ShClEventSourceGenerateAndRegisterEvent(&pCtx->pClient->EventSrc, &pEvent); 418 if (RT_SUCCESS(rc)) 419 { 420 rc = ShClX11ReadDataFromX11Async(&pCtx->X11, VBOX_SHCL_FMT_URI_LIST, UINT32_MAX, pEvent); 421 if (RT_SUCCESS(rc)) 422 { 423 /* X supplies the data asynchronously, so we need to wait for data to arrive first. */ 424 PSHCLEVENTPAYLOAD pPayload; 425 rc = ShClEventWait(pEvent, SHCL_TIMEOUT_DEFAULT_MS, &pPayload); 426 if (RT_SUCCESS(rc)) 427 { 428 if (pPayload) 429 { 430 Assert(pPayload->cbData == sizeof(SHCLX11RESPONSE)); 431 AssertPtr(pPayload->pvData); 432 PSHCLX11RESPONSE pResp = (PSHCLX11RESPONSE)pPayload->pvData; 433 434 rc = ShClTransferRootsInitFromStringList(pTransfer, 435 (char *)pResp->Read.pvData, pResp->Read.cbData + 1 /* Include zero terminator */); 436 if (RT_SUCCESS(rc)) 437 LogRel2(("Shared Clipboard: Host reported %RU64 X11 root entries for transfer to guest\n", ShClTransferRootsCount(pTransfer))); 438 439 RTMemFree(pResp->Read.pvData); 440 pResp->Read.cbData = 0; 441 442 ShClPayloadFree(pPayload); 443 pPayload = NULL; 444 } 445 else 446 rc = VERR_NO_DATA; /* No payload. */ 447 } 448 } 449 450 ShClEventRelease(pEvent); 451 } 452 else 453 rc = VERR_SHCLPB_MAX_EVENTS_REACHED; 481 rc = ShClTransferRootListRead(pTransfer); /* Calls shClSvcTransferIfaceHGRootListRead(). */ 454 482 break; 455 483 } 456 484 457 485 default: 486 rc = VERR_NOT_IMPLEMENTED; 458 487 break; 459 488 } 460 489 461 LogFlowFuncLeave ();490 LogFlowFuncLeaveRC(rc); 462 491 } 463 492 … … 659 688 return VINF_SUCCESS; 660 689 } 690 691 692 /********************************************************************************************************************************* 693 * Provider interface implementation * 694 *********************************************************************************************************************************/ 695 696 /** @copydoc SHCLTXPROVIDERIFACE::pfnRootListRead */ 697 static DECLCALLBACK(int) shClSvcX11TransferIfaceHGRootListRead(PSHCLTXPROVIDERCTX pCtx) 698 { 699 LogFlowFuncEnter(); 700 701 PSHCLCLIENT pClient = (PSHCLCLIENT)pCtx->pvUser; 702 AssertPtr(pClient); 703 704 AssertPtr(pClient->State.pCtx); 705 PSHCLX11CTX pX11 = &pClient->State.pCtx->X11; 706 707 PSHCLEVENT pEvent; 708 int rc = ShClEventSourceGenerateAndRegisterEvent(&pClient->EventSrc, &pEvent); 709 if (RT_SUCCESS(rc)) 710 { 711 rc = ShClX11ReadDataFromX11Async(pX11, VBOX_SHCL_FMT_URI_LIST, UINT32_MAX, pEvent); 712 if (RT_SUCCESS(rc)) 713 { 714 /* X supplies the data asynchronously, so we need to wait for data to arrive first. */ 715 PSHCLEVENTPAYLOAD pPayload; 716 rc = ShClEventWait(pEvent, SHCL_TIMEOUT_DEFAULT_MS, &pPayload); 717 if (RT_SUCCESS(rc)) 718 { 719 if (pPayload) 720 { 721 Assert(pPayload->cbData == sizeof(SHCLX11RESPONSE)); 722 AssertPtr(pPayload->pvData); 723 PSHCLX11RESPONSE pResp = (PSHCLX11RESPONSE)pPayload->pvData; 724 725 rc = ShClTransferRootsInitFromStringList(pCtx->pTransfer, 726 (char *)pResp->Read.pvData, pResp->Read.cbData + 1 /* Include zero terminator */); 727 if (RT_SUCCESS(rc)) 728 LogRel2(("Shared Clipboard: Host reported %RU64 X11 root entries for transfer to guest\n", 729 ShClTransferRootsCount(pCtx->pTransfer))); 730 731 RTMemFree(pResp->Read.pvData); 732 pResp->Read.cbData = 0; 733 734 ShClPayloadFree(pPayload); 735 pPayload = NULL; 736 } 737 else 738 rc = VERR_NO_DATA; /* No payload. */ 739 } 740 } 741 742 ShClEventRelease(pEvent); 743 } 744 else 745 rc = VERR_SHCLPB_MAX_EVENTS_REACHED; 746 747 LogFlowFuncLeaveRC(rc); 748 return rc; 749 } 661 750 #endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */ 662 751
Note:
See TracChangeset
for help on using the changeset viewer.