Changeset 100367 in vbox
- Timestamp:
- Jul 4, 2023 4:23:18 PM (20 months ago)
- svn:sync-xref-src-repo-rev:
- 158104
- Location:
- trunk
- Files:
-
- 24 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/GuestHost/SharedClipboard-transfers.h
r100290 r100367 90 90 /** No status set. */ 91 91 SHCLTRANSFERSTATUS_NONE = 0, 92 /** The transfer has been initialized but is not running yet. */ 93 SHCLTRANSFERSTATUS_INITIALIZED, 92 /** Requests a transfer to be initialized by the host. Only used for H->G transfers. 93 * Needed as only the host creates new transfer IDs. */ 94 SHCLTRANSFERSTATUS_REQUESTED = 8, 95 /** The transfer has been initialized and is ready to go, but is not running yet. 96 * At this stage the other party can start reading the root list and other stuff. */ 97 SHCLTRANSFERSTATUS_INITIALIZED = 1, 94 98 /** The transfer has been uninitialized and is not usable anymore. */ 95 SHCLTRANSFERSTATUS_UNINITIALIZED ,99 SHCLTRANSFERSTATUS_UNINITIALIZED = 2, 96 100 /** The transfer is active and running. */ 97 SHCLTRANSFERSTATUS_STARTED ,101 SHCLTRANSFERSTATUS_STARTED = 3, 98 102 /** The transfer has been stopped. */ 99 SHCLTRANSFERSTATUS_STOPPED ,103 SHCLTRANSFERSTATUS_STOPPED = 4, 100 104 /** The transfer has been canceled. */ 101 SHCLTRANSFERSTATUS_CANCELED ,105 SHCLTRANSFERSTATUS_CANCELED = 5, 102 106 /** The transfer has been killed. */ 103 SHCLTRANSFERSTATUS_KILLED ,107 SHCLTRANSFERSTATUS_KILLED = 6, 104 108 /** The transfer ran into an unrecoverable error. 105 109 * This results in completely aborting the operation. */ 106 SHCLTRANSFERSTATUS_ERROR ,110 SHCLTRANSFERSTATUS_ERROR = 7, 107 111 /** The usual 32-bit hack. */ 108 112 SHCLTRANSFERSTATUS_32BIT_SIZE_HACK = 0x7fffffff … … 361 365 typedef struct _SHCLREPLY 362 366 { 363 /** Message type (of type VBOX_SHCL_ REPLYMSGTYPE_TRANSFER_XXX). */367 /** Message type (of type VBOX_SHCL_TX_REPLYMSGTYPE_TRANSFER_XXX). */ 364 368 uint32_t uType; 365 369 /** IPRT result of overall operation. Note: int vs. uint32! */ … … 367 371 union 368 372 { 369 /** For VBOX_SHCL_ REPLYMSGTYPE_TRANSFER_STATUS. */373 /** For VBOX_SHCL_TX_REPLYMSGTYPE_TRANSFER_STATUS. */ 370 374 struct 371 375 { 372 376 SHCLTRANSFERSTATUS uStatus; 373 377 } TransferStatus; 374 /** For VBOX_SHCL_ REPLYMSGTYPE_LIST_OPEN. */378 /** For VBOX_SHCL_TX_REPLYMSGTYPE_LIST_OPEN. */ 375 379 struct 376 380 { 377 381 SHCLLISTHANDLE uHandle; 378 382 } ListOpen; 379 /** For VBOX_SHCL_ REPLYMSGTYPE_LIST_CLOSE. */383 /** For VBOX_SHCL_TX_REPLYMSGTYPE_LIST_CLOSE. */ 380 384 struct 381 385 { 382 386 SHCLLISTHANDLE uHandle; 383 387 } ListClose; 384 /** For VBOX_SHCL_ REPLYMSGTYPE_OBJ_OPEN. */388 /** For VBOX_SHCL_TX_REPLYMSGTYPE_OBJ_OPEN. */ 385 389 struct 386 390 { 387 391 SHCLOBJHANDLE uHandle; 388 392 } ObjOpen; 389 /** For VBOX_SHCL_ REPLYMSGTYPE_OBJ_CLOSE. */393 /** For VBOX_SHCL_TX_REPLYMSGTYPE_OBJ_CLOSE. */ 390 394 struct 391 395 { … … 647 651 typedef SHCLTXPROVIDERCTX *PSHCLTXPROVIDERCTX; 648 652 649 struct SHCLTRANSFERCTX;650 typedef struct SHCLTRANSFERCTX *PSHCLTRANSFERCTX;653 struct _SHCLTRANSFERCTX; 654 typedef struct _SHCLTRANSFERCTX *PSHCLTRANSFERCTX; 651 655 652 656 /** … … 907 911 /** The node member for using this struct in a RTList. */ 908 912 RTLISTNODE Node; 913 /** Critical section for serializing access. */ 914 RTCRITSECT CritSect; 909 915 /** Number of references to this transfer. */ 910 916 uint32_t cRefs; … … 917 923 /** Maximum data chunk size (in bytes) to transfer. Default is 64K. */ 918 924 uint32_t cbMaxChunkSize; 925 /** Status change event. */ 926 RTSEMEVENT StatusChangeEvent; 919 927 /** The transfer's own event source. */ 920 928 SHCLEVENTSOURCE Events; … … 951 959 /** Contains thread-related attributes. */ 952 960 SHCLTRANSFERTHREAD Thread; 953 /** Critical section for serializing access. */954 RTCRITSECT CritSect;955 961 } SHCLTRANSFER; 956 962 /** Pointer to a Shared Clipboard transfer. */ … … 976 982 * Enumeration for HTTP server status changes. 977 983 * 978 * Keep those as flags, so that we can wait for multiple statuses, if needed.984 * Keep those as flags, so that we can wait for multiple statuses, if ever needed. 979 985 */ 980 986 typedef enum _SHCLHTTPSERVERSTATUS … … 1041 1047 1042 1048 /** 1049 * Structure for keeping a single transfer context event. 1050 */ 1051 typedef struct _SHCLTRANSFERCTXEVENT 1052 { 1053 /** Transfer bound to this event. 1054 * Can be NULL if not being used. */ 1055 PSHCLTRANSFER pTransfer; 1056 /** Whether a transfer was registered or not. */ 1057 bool fRegistered; 1058 } SHCLTRANSFERCTXEVENT; 1059 /** Pointer to Shared Clipboard transfer context event. */ 1060 typedef SHCLTRANSFERCTXEVENT *PSHCLTRANSFERCTXEVENT; 1061 1062 /** 1043 1063 * Structure for keeping Shared Clipboard transfer context around. 1044 1064 * 1045 1065 * A transfer context contains a list of (grouped) transfers for book keeping. 1046 1066 */ 1047 structSHCLTRANSFERCTX1067 typedef struct _SHCLTRANSFERCTX 1048 1068 { 1049 1069 /** Critical section for serializing access. */ 1050 1070 RTCRITSECT CritSect; 1071 /** Event used for waiting. for transfer context changes. */ 1072 RTSEMEVENT ChangedEvent; 1073 /** Event data for \a ChangedEvent. */ 1074 SHCLTRANSFERCTXEVENT ChangedEventData; 1051 1075 /** List of transfers. */ 1052 1076 RTLISTANCHOR List; … … 1059 1083 /** Number of total transfers (in list). */ 1060 1084 uint16_t cTransfers; 1061 }; 1085 } SHCLTRANSFERCTX; 1086 /** Pointer to Shared Clipboard transfer context. */ 1087 typedef SHCLTRANSFERCTX *PSHCLTRANSFERCTX; 1062 1088 1063 1089 /** @name Shared Clipboard transfer interface providers. 1064 1090 * @{ 1065 1091 */ 1066 PSHCLTXPROVIDERIFACE VBClTransferProviderLocalQueryInterface(PSHCLTXPROVIDER pProvider);1092 PSHCLTXPROVIDERIFACE ShClTransferProviderLocalQueryInterface(PSHCLTXPROVIDER pProvider); 1067 1093 /** @} */ 1068 1094 … … 1096 1122 * @{ 1097 1123 */ 1098 int ShClTransferCreateEx( uint32_t cbMaxChunkSize, uint32_t cMaxListHandles, uint32_t cMaxObjHandles, PSHCLTRANSFER *ppTransfer);1099 int ShClTransferCreate( PSHCLTRANSFER *ppTransfer);1100 int ShClTransferInit(PSHCLTRANSFER pTransfer , SHCLTRANSFERDIR enmDir, SHCLSOURCE enmSource);1124 int ShClTransferCreateEx(SHCLTRANSFERDIR enmDir, SHCLSOURCE enmSource, uint32_t cbMaxChunkSize, uint32_t cMaxListHandles, uint32_t cMaxObjHandles, PSHCLTRANSFER *ppTransfer); 1125 int ShClTransferCreate(SHCLTRANSFERDIR enmDir, SHCLSOURCE enmSource, PSHCLTRANSFER *ppTransfer); 1126 int ShClTransferInit(PSHCLTRANSFER pTransfer); 1101 1127 int ShClTransferDestroy(PSHCLTRANSFER pTransfer); 1102 1128 void ShClTransferReset(PSHCLTRANSFER pTransfer); … … 1113 1139 SHCLSOURCE ShClTransferGetSource(PSHCLTRANSFER pTransfer); 1114 1140 SHCLTRANSFERSTATUS ShClTransferGetStatus(PSHCLTRANSFER pTransfer); 1141 int ShClTransferWaitForStatus(PSHCLTRANSFER pTransfer, RTMSINTERVAL msTimeout, SHCLTRANSFERSTATUS enmStatus); 1142 int ShClTransferWaitForStatusChange(PSHCLTRANSFER pTransfer, RTMSINTERVAL msTimeout, SHCLTRANSFERSTATUS *penmStatus); 1115 1143 1116 1144 int ShClTransferListOpen(PSHCLTRANSFER pTransfer, PSHCLLISTOPENPARMS pOpenParms, PSHCLLISTHANDLE phList); … … 1159 1187 1160 1188 int ShClTransferRootsInitFromStringList(PSHCLTRANSFER pTransfer, const char *pszRoots, size_t cbRoots); 1189 int ShClTransferRootsInitFromStringListUnicode(PSHCLTRANSFER pTransfer, PRTUTF16 pwszRoots, size_t cbRoots); 1161 1190 int ShClTransferRootsInitFromFile(PSHCLTRANSFER pTransfer, const char *pszFile); 1162 1191 uint64_t ShClTransferRootsCount(PSHCLTRANSFER pTransfer); … … 1173 1202 PSHCLTRANSFER ShClTransferCtxGetTransferById(PSHCLTRANSFERCTX pTransferCtx, uint32_t uID); 1174 1203 PSHCLTRANSFER ShClTransferCtxGetTransferByIndex(PSHCLTRANSFERCTX pTransferCtx, uint32_t uIdx); 1204 PSHCLTRANSFER ShClTransferCtxGetTransferLast(PSHCLTRANSFERCTX pTransferCtx); 1175 1205 uint32_t ShClTransferCtxGetRunningTransfers(PSHCLTRANSFERCTX pTransferCtx); 1176 1206 uint32_t ShClTransferCtxGetTotalTransfers(PSHCLTRANSFERCTX pTransferCtx); 1177 1207 void ShClTransferCtxCleanup(PSHCLTRANSFERCTX pTransferCtx); 1178 bool ShClTransferCtxTransfersMaximumReached(PSHCLTRANSFERCTX pTransferCtx); 1179 int ShClTransferCtxTransferRegister(PSHCLTRANSFERCTX pTransferCtx, PSHCLTRANSFER pTransfer, SHCLTRANSFERID *pidTransfer); 1180 int ShClTransferCtxTransferRegisterById(PSHCLTRANSFERCTX pTransferCtx, PSHCLTRANSFER pTransfer, SHCLTRANSFERID idTransfer); 1181 int ShClTransferCtxTransferUnregisterById(PSHCLTRANSFERCTX pTransferCtx, SHCLTRANSFERID idTransfer); 1208 bool ShClTransferCtxIsMaximumReached(PSHCLTRANSFERCTX pTransferCtx); 1209 int ShClTransferCtxCreateId(PSHCLTRANSFERCTX pTransferCtx, PSHCLTRANSFERID pidTransfer); 1210 int ShClTransferCtxRegister(PSHCLTRANSFERCTX pTransferCtx, PSHCLTRANSFER pTransfer, PSHCLTRANSFERID pidTransfer); 1211 int ShClTransferCtxRegisterById(PSHCLTRANSFERCTX pTransferCtx, PSHCLTRANSFER pTransfer, SHCLTRANSFERID idTransfer); 1212 int ShClTransferCtxUnregisterById(PSHCLTRANSFERCTX pTransferCtx, SHCLTRANSFERID idTransfer); 1213 int ShClTransferCtxWait(PSHCLTRANSFERCTX pTransferCtx, RTMSINTERVAL msTimeout, bool fRegister, SHCLTRANSFERID idTransfer, PSHCLTRANSFER *ppTransfer); 1182 1214 /** @} */ 1183 1215 … … 1210 1242 char *ShClTransferHttpServerGetAddressA(PSHCLHTTPSERVER pSrv); 1211 1243 char *ShClTransferHttpServerGetUrlA(PSHCLHTTPSERVER pSrv, SHCLTRANSFERID idTransfer); 1244 bool ShClTransferHttpServerIsInitialized(PSHCLHTTPSERVER pSrv); 1212 1245 bool ShClTransferHttpServerIsRunning(PSHCLHTTPSERVER pSrv); 1213 1246 int ShClTransferHttpServerWaitForStatusChange(PSHCLHTTPSERVER pSrv, SHCLHTTPSERVERSTATUS fStatus, RTMSINTERVAL msTimeout); … … 1222 1255 const char *ShClTransferStatusToStr(SHCLTRANSFERSTATUS enmStatus); 1223 1256 int ShClTransferValidatePath(const char *pcszPath, bool fMustExist); 1224 int ShClFsObjInfoQuery (const char *pszPath, PSHCLFSOBJINFO pObjInfo);1257 int ShClFsObjInfoQueryLocal(const char *pszPath, PSHCLFSOBJINFO pObjInfo); 1225 1258 int ShClFsObjInfoFromIPRT(PSHCLFSOBJINFO pDst, PCRTFSOBJINFO pSrc); 1226 1259 /** @} */ -
trunk/include/VBox/GuestHost/SharedClipboard-win.h
r100206 r100367 231 231 void Destroy(void); 232 232 233 void SetCallbacks(PSHCLCALLBACKS pCallbacks);234 235 233 public: /* IUnknown methods. */ 236 234 … … 263 261 public: 264 262 265 int Set AndStartTransfer(PSHCLTRANSFER pTransfer);266 int SetStatus(Status enmStatus, int rc = VINF_SUCCESS);263 int SetTransfer(PSHCLTRANSFER pTransfer); 264 int SetStatus(Status enmStatus, int rcSts = VINF_SUCCESS); 267 265 268 266 public: -
trunk/include/VBox/GuestHost/SharedClipboard-x11.h
r100255 r100367 144 144 /** What kind of formats does VBox have to offer? */ 145 145 SHCLFORMATS vboxFormats; 146 /** Cache of the last unicode data that we received. */ 147 void *pvUnicodeCache; 148 /** Size of the unicode data in the cache. */ 149 uint32_t cbUnicodeCache; 146 /** Internval cache of VBox clipboard formats. */ 147 SHCLCACHE Cache; 150 148 /** When we wish the clipboard to exit, we have to wake up the event 151 149 * loop. We do this by writing into a pipe. This end of the pipe is -
trunk/include/VBox/HostServices/VBoxClipboardSvc.h
r100234 r100367 330 330 * @retval VERR_WRONG_PARAMETER_COUNT 331 331 * @retval VERR_WRONG_PARAMETER_TYPE 332 * @since 6.1.0332 * @since 7.1.0 333 333 */ 334 334 #define VBOX_SHCL_GUEST_FN_REPORT_FEATURES 6 … … 343 343 * @retval VERR_WRONG_PARAMETER_COUNT 344 344 * @retval VERR_WRONG_PARAMETER_TYPE 345 * @since 6.1.0345 * @since 7.1.0 346 346 */ 347 347 #define VBOX_SHCL_GUEST_FN_QUERY_FEATURES 7 … … 365 365 * @retval VERR_WRONG_PARAMETER_COUNT 366 366 * @retval VERR_WRONG_PARAMETER_TYPE 367 * @since 6.1.0367 * @since 7.1.0 368 368 */ 369 369 #define VBOX_SHCL_GUEST_FN_MSG_PEEK_NOWAIT 8 … … 393 393 * @retval VERR_WRONG_PARAMETER_TYPE 394 394 * @note This replaces VBOX_SHCL_GUEST_FN_MSG_OLD_GET_WAIT. 395 * @since 6.1.0395 * @since 7.1.0 396 396 */ 397 397 #define VBOX_SHCL_GUEST_FN_MSG_PEEK_WAIT 9 … … 440 440 * @since 6.1.x 441 441 */ 442 #define VBOX_SHCL_GUEST_FN_REPLY 443 /** Gets the root list header from the host.444 * 445 * @retval VINF_SUCCESS on success. 446 * @retval VERR_INVALID_CLIENT_ID 447 * @retval VERR_WRONG_PARAMETER_COUNT 448 * @retval VERR_WRONG_PARAMETER_TYPE 449 * @since 6.1.x450 */ 451 #define VBOX_SHCL_GUEST_FN_ROOT_LIST_HDR_READ 452 /** Sends the root list header to the host.453 * 454 * @retval VINF_SUCCESS on success. 455 * @retval VERR_INVALID_CLIENT_ID 456 * @retval VERR_WRONG_PARAMETER_COUNT 457 * @retval VERR_WRONG_PARAMETER_TYPE 458 * @since 7.1.x 459 */ 460 #define VBOX_SHCL_GUEST_FN_ROOT_LIST_HDR_WRITE 461 /** Gets a root list root entry from the host.462 * 463 * @retval VINF_SUCCESS on success. 464 * @retval VERR_INVALID_CLIENT_ID 465 * @retval VERR_WRONG_PARAMETER_COUNT 466 * @retval VERR_WRONG_PARAMETER_TYPE 467 * @since 7.1.x 468 */ 469 #define VBOX_SHCL_GUEST_FN_ROOT_LIST_ENTRY_READ 470 /** Sends a root list root entry to the host.471 * 472 * @retval VINF_SUCCESS on success. 473 * @retval VERR_INVALID_CLIENT_ID 474 * @retval VERR_WRONG_PARAMETER_COUNT 475 * @retval VERR_WRONG_PARAMETER_TYPE 476 * @since 7.1.x 477 */ 478 #define VBOX_SHCL_GUEST_FN_ROOT_LIST_ENTRY_WRITE 479 /** Opens / gets a list handle from the host.480 * 481 * @retval VINF_SUCCESS on success. 482 * @retval VERR_INVALID_CLIENT_ID 483 * @retval VERR_WRONG_PARAMETER_COUNT 484 * @retval VERR_WRONG_PARAMETER_TYPE 485 * @since 7.1.x 486 */ 487 #define VBOX_SHCL_GUEST_FN_LIST_OPEN 488 /** Closes a list handle from the host.489 * 490 * @retval VINF_SUCCESS on success. 491 * @retval VERR_INVALID_CLIENT_ID 492 * @retval VERR_WRONG_PARAMETER_COUNT 493 * @retval VERR_WRONG_PARAMETER_TYPE 494 * @since 7.1.x 495 */ 496 #define VBOX_SHCL_GUEST_FN_LIST_CLOSE 497 /** Reads a list header from the host.498 * 499 * @retval VINF_SUCCESS on success. 500 * @retval VERR_INVALID_CLIENT_ID 501 * @retval VERR_WRONG_PARAMETER_COUNT 502 * @retval VERR_WRONG_PARAMETER_TYPE 503 * @since 7.1.x 504 */ 505 #define VBOX_SHCL_GUEST_FN_LIST_HDR_READ 506 /** Writes a list header to the host.507 * 508 * @retval VINF_SUCCESS on success. 509 * @retval VERR_INVALID_CLIENT_ID 510 * @retval VERR_WRONG_PARAMETER_COUNT 511 * @retval VERR_WRONG_PARAMETER_TYPE 512 * @since 7.1.x 513 */ 514 #define VBOX_SHCL_GUEST_FN_LIST_HDR_WRITE 515 /** Reads a list entry from the host.516 * 517 * @retval VINF_SUCCESS on success. 518 * @retval VERR_INVALID_CLIENT_ID 519 * @retval VERR_WRONG_PARAMETER_COUNT 520 * @retval VERR_WRONG_PARAMETER_TYPE 521 * @since 7.1.x 522 */ 523 #define VBOX_SHCL_GUEST_FN_LIST_ENTRY_READ 524 /** Sends a list entry to the host.525 * 526 * @retval VINF_SUCCESS on success. 527 * @retval VERR_INVALID_CLIENT_ID 528 * @retval VERR_WRONG_PARAMETER_COUNT 529 * @retval VERR_WRONG_PARAMETER_TYPE 530 * @since 7.1.x 531 */ 532 #define VBOX_SHCL_GUEST_FN_LIST_ENTRY_WRITE 533 /** Opens a nobject on the host.534 * 535 * @retval VINF_SUCCESS on success. 536 * @retval VERR_INVALID_CLIENT_ID 537 * @retval VERR_WRONG_PARAMETER_COUNT 538 * @retval VERR_WRONG_PARAMETER_TYPE 539 * @since 7.1.x 540 */ 541 #define VBOX_SHCL_GUEST_FN_OBJ_OPEN 542 /** Closes a nobject on the host.543 * 544 * @retval VINF_SUCCESS on success. 545 * @retval VERR_INVALID_CLIENT_ID 546 * @retval VERR_WRONG_PARAMETER_COUNT 547 * @retval VERR_WRONG_PARAMETER_TYPE 548 * @since 7.1.x 549 */ 550 #define VBOX_SHCL_GUEST_FN_OBJ_CLOSE 551 /** Reads from a nobject on the host.552 * 553 * @retval VINF_SUCCESS on success. 554 * @retval VERR_INVALID_CLIENT_ID 555 * @retval VERR_WRONG_PARAMETER_COUNT 556 * @retval VERR_WRONG_PARAMETER_TYPE 557 * @since 7.1.x 558 */ 559 #define VBOX_SHCL_GUEST_FN_OBJ_READ 560 /** Writes to a nobject on the host.561 * 562 * @retval VINF_SUCCESS on success. 563 * @retval VERR_INVALID_CLIENT_ID 564 * @retval VERR_WRONG_PARAMETER_COUNT 565 * @retval VERR_WRONG_PARAMETER_TYPE 566 * @since 7.1.x 567 */ 568 #define VBOX_SHCL_GUEST_FN_OBJ_WRITE 569 /** Reports a nerror to the host.442 #define VBOX_SHCL_GUEST_FN_REPLY 11 443 /** Gets the transfer root list header from the host. 444 * 445 * @retval VINF_SUCCESS on success. 446 * @retval VERR_INVALID_CLIENT_ID 447 * @retval VERR_WRONG_PARAMETER_COUNT 448 * @retval VERR_WRONG_PARAMETER_TYPE 449 * @since 7.1.x 450 */ 451 #define VBOX_SHCL_GUEST_FN_ROOT_LIST_HDR_READ 12 452 /** Sends the transfer root list header to the host. 453 * 454 * @retval VINF_SUCCESS on success. 455 * @retval VERR_INVALID_CLIENT_ID 456 * @retval VERR_WRONG_PARAMETER_COUNT 457 * @retval VERR_WRONG_PARAMETER_TYPE 458 * @since 7.1.x 459 */ 460 #define VBOX_SHCL_GUEST_FN_ROOT_LIST_HDR_WRITE 13 461 /** Gets a transfer root list root entry from the host. 462 * 463 * @retval VINF_SUCCESS on success. 464 * @retval VERR_INVALID_CLIENT_ID 465 * @retval VERR_WRONG_PARAMETER_COUNT 466 * @retval VERR_WRONG_PARAMETER_TYPE 467 * @since 7.1.x 468 */ 469 #define VBOX_SHCL_GUEST_FN_ROOT_LIST_ENTRY_READ 14 470 /** Sends a transfer root list root entry to the host. 471 * 472 * @retval VINF_SUCCESS on success. 473 * @retval VERR_INVALID_CLIENT_ID 474 * @retval VERR_WRONG_PARAMETER_COUNT 475 * @retval VERR_WRONG_PARAMETER_TYPE 476 * @since 7.1.x 477 */ 478 #define VBOX_SHCL_GUEST_FN_ROOT_LIST_ENTRY_WRITE 15 479 /** Opens / gets a transfer list handle from the host. 480 * 481 * @retval VINF_SUCCESS on success. 482 * @retval VERR_INVALID_CLIENT_ID 483 * @retval VERR_WRONG_PARAMETER_COUNT 484 * @retval VERR_WRONG_PARAMETER_TYPE 485 * @since 7.1.x 486 */ 487 #define VBOX_SHCL_GUEST_FN_LIST_OPEN 16 488 /** Closes a transfer list handle from the host. 489 * 490 * @retval VINF_SUCCESS on success. 491 * @retval VERR_INVALID_CLIENT_ID 492 * @retval VERR_WRONG_PARAMETER_COUNT 493 * @retval VERR_WRONG_PARAMETER_TYPE 494 * @since 7.1.x 495 */ 496 #define VBOX_SHCL_GUEST_FN_LIST_CLOSE 17 497 /** Reads a transfer list header from the host. 498 * 499 * @retval VINF_SUCCESS on success. 500 * @retval VERR_INVALID_CLIENT_ID 501 * @retval VERR_WRONG_PARAMETER_COUNT 502 * @retval VERR_WRONG_PARAMETER_TYPE 503 * @since 7.1.x 504 */ 505 #define VBOX_SHCL_GUEST_FN_LIST_HDR_READ 18 506 /** Writes a transfer list header to the host. 507 * 508 * @retval VINF_SUCCESS on success. 509 * @retval VERR_INVALID_CLIENT_ID 510 * @retval VERR_WRONG_PARAMETER_COUNT 511 * @retval VERR_WRONG_PARAMETER_TYPE 512 * @since 7.1.x 513 */ 514 #define VBOX_SHCL_GUEST_FN_LIST_HDR_WRITE 19 515 /** Reads a transfer list entry from the host. 516 * 517 * @retval VINF_SUCCESS on success. 518 * @retval VERR_INVALID_CLIENT_ID 519 * @retval VERR_WRONG_PARAMETER_COUNT 520 * @retval VERR_WRONG_PARAMETER_TYPE 521 * @since 7.1.x 522 */ 523 #define VBOX_SHCL_GUEST_FN_LIST_ENTRY_READ 20 524 /** Sends a transfer list entry to the host. 525 * 526 * @retval VINF_SUCCESS on success. 527 * @retval VERR_INVALID_CLIENT_ID 528 * @retval VERR_WRONG_PARAMETER_COUNT 529 * @retval VERR_WRONG_PARAMETER_TYPE 530 * @since 7.1.x 531 */ 532 #define VBOX_SHCL_GUEST_FN_LIST_ENTRY_WRITE 21 533 /** Opens a transfer object on the host. 534 * 535 * @retval VINF_SUCCESS on success. 536 * @retval VERR_INVALID_CLIENT_ID 537 * @retval VERR_WRONG_PARAMETER_COUNT 538 * @retval VERR_WRONG_PARAMETER_TYPE 539 * @since 7.1.x 540 */ 541 #define VBOX_SHCL_GUEST_FN_OBJ_OPEN 22 542 /** Closes a transfer object on the host. 543 * 544 * @retval VINF_SUCCESS on success. 545 * @retval VERR_INVALID_CLIENT_ID 546 * @retval VERR_WRONG_PARAMETER_COUNT 547 * @retval VERR_WRONG_PARAMETER_TYPE 548 * @since 7.1.x 549 */ 550 #define VBOX_SHCL_GUEST_FN_OBJ_CLOSE 23 551 /** Reads from a transfer object on the host. 552 * 553 * @retval VINF_SUCCESS on success. 554 * @retval VERR_INVALID_CLIENT_ID 555 * @retval VERR_WRONG_PARAMETER_COUNT 556 * @retval VERR_WRONG_PARAMETER_TYPE 557 * @since 7.1.x 558 */ 559 #define VBOX_SHCL_GUEST_FN_OBJ_READ 24 560 /** Writes to a transfer object on the host. 561 * 562 * @retval VINF_SUCCESS on success. 563 * @retval VERR_INVALID_CLIENT_ID 564 * @retval VERR_WRONG_PARAMETER_COUNT 565 * @retval VERR_WRONG_PARAMETER_TYPE 566 * @since 7.1.x 567 */ 568 #define VBOX_SHCL_GUEST_FN_OBJ_WRITE 25 569 /** Reports a transfer error to the host. 570 570 * 571 571 * @todo r=bird: Smells like GUEST_MSG_SKIP … … 577 577 * @since 6.1 578 578 */ 579 #define VBOX_SHCL_GUEST_FN_ERROR 579 #define VBOX_SHCL_GUEST_FN_ERROR 27 580 580 581 581 /** For negotiating a chunk size between the guest and host. … … 593 593 * @retval VERR_INVALID_PARAMETER if the 2nd parameter is larger than the 594 594 * first one 595 * @since 6.1595 * @since 7.1 596 596 */ 597 597 #define VBOX_SHCL_GUEST_FN_NEGOTIATE_CHUNK_SIZE 28 … … 836 836 837 837 /** Invalid message type, do not use. */ 838 #define VBOX_SHCL_ REPLYMSGTYPE_INVALID 0838 #define VBOX_SHCL_TX_REPLYMSGTYPE_INVALID 0 839 839 /** Replies a transfer status. */ 840 #define VBOX_SHCL_ REPLYMSGTYPE_TRANSFER_STATUS 1840 #define VBOX_SHCL_TX_REPLYMSGTYPE_TRANSFER_STATUS 1 841 841 /** Replies a list open status. */ 842 #define VBOX_SHCL_ REPLYMSGTYPE_LIST_OPEN 2842 #define VBOX_SHCL_TX_REPLYMSGTYPE_LIST_OPEN 2 843 843 /** Replies a list close status. */ 844 #define VBOX_SHCL_ REPLYMSGTYPE_LIST_CLOSE 3844 #define VBOX_SHCL_TX_REPLYMSGTYPE_LIST_CLOSE 3 845 845 /** Replies an object open status. */ 846 #define VBOX_SHCL_ REPLYMSGTYPE_OBJ_OPEN 4846 #define VBOX_SHCL_TX_REPLYMSGTYPE_OBJ_OPEN 4 847 847 /** Replies an object close status. */ 848 #define VBOX_SHCL_ REPLYMSGTYPE_OBJ_CLOSE 5848 #define VBOX_SHCL_TX_REPLYMSGTYPE_OBJ_CLOSE 5 849 849 850 850 /** … … 857 857 /** uint64_t, out: Context ID. */ 858 858 HGCMFunctionParameter uContext; 859 /** uint32_t, out: Message type of type VBOX_SHCL_ REPLYMSGTYPE_XXX. */859 /** uint32_t, out: Message type of type VBOX_SHCL_TX_REPLYMSGTYPE_XXX. */ 860 860 HGCMFunctionParameter enmType; 861 861 /** uint32_t, out: IPRT result of overall operation. */ -
trunk/include/VBox/VBoxGuestLib.h
r100362 r100367 637 637 /** The context ID - input or/and output depending on the operation. */ 638 638 uint64_t idContext; 639 /** OUT: Number of parameters retrieved.640 * This is set by ??. */641 uint32_t cParmsRecived;642 639 # ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 643 640 /** Data related to Shared Clipboard file transfers. */ … … 726 723 727 724 # ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 725 VBGLR3DECL(int) VbglR3ClipboardTransferRequest(PVBGLR3SHCLCMDCTX pCmdCtx); 728 726 VBGLR3DECL(void) VbglR3ClipboardTransferSetCallbacks(PSHCLTRANSFERCALLBACKS pCallbacks); 729 727 VBGLR3DECL(int) VbglR3ClipboardEventGetNextEx(uint32_t idMsg, uint32_t cParms, PVBGLR3SHCLCMDCTX pCtx, PSHCLTRANSFERCTX pTransferCtx, PVBGLR3CLIPBOARDEVENT pEvent); … … 731 729 VBGLR3DECL(int) VbglR3ClipboardTransferStatusReply(PVBGLR3SHCLCMDCTX pCtx, PSHCLTRANSFER pTransfer, SHCLTRANSFERSTATUS uStatus); 732 730 733 VBGLR3DECL(int) VbglR3Clipboard RootListRead(PVBGLR3SHCLCMDCTX pCtx, PSHCLLIST *ppRootList);734 735 VBGLR3DECL(int) VbglR3Clipboard RootListHdrReadReq(PVBGLR3SHCLCMDCTX pCtx, uint32_t *pfRoots);736 VBGLR3DECL(int) VbglR3Clipboard RootListHdrReadReply(PVBGLR3SHCLCMDCTX pCtx, PSHCLLIST pRootList);731 VBGLR3DECL(int) VbglR3ClipboardTransferRootListRead(PVBGLR3SHCLCMDCTX pCtx, PSHCLLIST *ppRootList); 732 733 VBGLR3DECL(int) VbglR3ClipboardTransferRootListHdrReadReq(PVBGLR3SHCLCMDCTX pCtx, uint32_t *pfRoots); 734 VBGLR3DECL(int) VbglR3ClipboardTransferRootListHdrReadReply(PVBGLR3SHCLCMDCTX pCtx, PSHCLLIST pRootList); 737 735 VBGLR3DECL(int) VbglR3ClipboardRootsWrite(PVBGLR3SHCLCMDCTX pCtx, PSHCLLISTHDR pRoots); 738 736 739 VBGLR3DECL(int) VbglR3Clipboard ListOpenSend(PVBGLR3SHCLCMDCTX pCtx, PSHCLLISTOPENPARMS pOpenParms, PSHCLLISTHANDLE phList);740 VBGLR3DECL(int) VbglR3Clipboard ListOpenRecv(PVBGLR3SHCLCMDCTX pCtx, PSHCLLISTOPENPARMS pOpenParms);741 VBGLR3DECL(int) VbglR3Clipboard ListOpenReply(PVBGLR3SHCLCMDCTX pCtx, int rcReply, SHCLLISTHANDLE hList);742 743 VBGLR3DECL(int) VbglR3Clipboard ListCloseSend(PVBGLR3SHCLCMDCTX pCtx, SHCLLISTHANDLE hList);737 VBGLR3DECL(int) VbglR3ClipboardTransferListOpenSend(PVBGLR3SHCLCMDCTX pCtx, PSHCLLISTOPENPARMS pOpenParms, PSHCLLISTHANDLE phList); 738 VBGLR3DECL(int) VbglR3ClipboardTransferListOpenRecv(PVBGLR3SHCLCMDCTX pCtx, PSHCLLISTOPENPARMS pOpenParms); 739 VBGLR3DECL(int) VbglR3ClipboardTransferListOpenReply(PVBGLR3SHCLCMDCTX pCtx, int rcReply, SHCLLISTHANDLE hList); 740 741 VBGLR3DECL(int) VbglR3ClipboardTransferListCloseSend(PVBGLR3SHCLCMDCTX pCtx, SHCLLISTHANDLE hList); 744 742 VBGLR3DECL(int) VbglR3ClipboardListCloseRecv(PVBGLR3SHCLCMDCTX pCtx, PSHCLLISTHANDLE phList); 745 743 746 VBGLR3DECL(int) VbglR3Clipboard ListHdrWrite(PVBGLR3SHCLCMDCTX pCtx, SHCLLISTHANDLE hList, PSHCLLISTHDR pListHdr);747 VBGLR3DECL(int) VbglR3Clipboard ListEntryWrite(PVBGLR3SHCLCMDCTX pCtx, SHCLLISTHANDLE hList, PSHCLLISTENTRY pListEntry);748 749 VBGLR3DECL(int) VbglR3Clipboard ObjOpenRecv(PVBGLR3SHCLCMDCTX pCtx, PSHCLOBJOPENCREATEPARMS pCreateParms);750 VBGLR3DECL(int) VbglR3Clipboard ObjOpenReply(PVBGLR3SHCLCMDCTX pCtx, int rcReply, SHCLOBJHANDLE hObj);751 VBGLR3DECL(int) VbglR3Clipboard ObjOpenSend(PVBGLR3SHCLCMDCTX pCtx, PSHCLOBJOPENCREATEPARMS pCreateParms,744 VBGLR3DECL(int) VbglR3ClipboardTransferListHdrWrite(PVBGLR3SHCLCMDCTX pCtx, SHCLLISTHANDLE hList, PSHCLLISTHDR pListHdr); 745 VBGLR3DECL(int) VbglR3ClipboardTransferListEntryWrite(PVBGLR3SHCLCMDCTX pCtx, SHCLLISTHANDLE hList, PSHCLLISTENTRY pListEntry); 746 747 VBGLR3DECL(int) VbglR3ClipboardTransferObjOpenRecv(PVBGLR3SHCLCMDCTX pCtx, PSHCLOBJOPENCREATEPARMS pCreateParms); 748 VBGLR3DECL(int) VbglR3ClipboardTransferObjOpenReply(PVBGLR3SHCLCMDCTX pCtx, int rcReply, SHCLOBJHANDLE hObj); 749 VBGLR3DECL(int) VbglR3ClipboardTransferObjOpenSend(PVBGLR3SHCLCMDCTX pCtx, PSHCLOBJOPENCREATEPARMS pCreateParms, 752 750 PSHCLOBJHANDLE phObj); 753 751 754 VBGLR3DECL(int) VbglR3Clipboard ObjCloseRecv(PVBGLR3SHCLCMDCTX pCtx, PSHCLOBJHANDLE phObj);755 VBGLR3DECL(int) VbglR3Clipboard ObjCloseReply(PVBGLR3SHCLCMDCTX pCtx, int rcReply, SHCLOBJHANDLE hObj);756 VBGLR3DECL(int) VbglR3Clipboard ObjCloseSend(PVBGLR3SHCLCMDCTX pCtx, SHCLOBJHANDLE hObj);757 758 VBGLR3DECL(int) VbglR3Clipboard ObjReadRecv(PVBGLR3SHCLCMDCTX pCtx, PSHCLOBJHANDLE phObj, uint32_t pcbToRead,752 VBGLR3DECL(int) VbglR3ClipboardTransferObjCloseRecv(PVBGLR3SHCLCMDCTX pCtx, PSHCLOBJHANDLE phObj); 753 VBGLR3DECL(int) VbglR3ClipboardTransferObjCloseReply(PVBGLR3SHCLCMDCTX pCtx, int rcReply, SHCLOBJHANDLE hObj); 754 VBGLR3DECL(int) VbglR3ClipboardTransferObjCloseSend(PVBGLR3SHCLCMDCTX pCtx, SHCLOBJHANDLE hObj); 755 756 VBGLR3DECL(int) VbglR3ClipboardTransferObjReadRecv(PVBGLR3SHCLCMDCTX pCtx, PSHCLOBJHANDLE phObj, uint32_t pcbToRead, 759 757 uint32_t *pfFlags); 760 VBGLR3DECL(int) VbglR3Clipboard ObjReadSend(PVBGLR3SHCLCMDCTX pCtx, SHCLOBJHANDLE hObj, void *pvBuf, uint32_t cbBuf,758 VBGLR3DECL(int) VbglR3ClipboardTransferObjReadSend(PVBGLR3SHCLCMDCTX pCtx, SHCLOBJHANDLE hObj, void *pvBuf, uint32_t cbBuf, 761 759 uint32_t *pcbRead); 762 VBGLR3DECL(int) VbglR3Clipboard ObjWriteSend(PVBGLR3SHCLCMDCTX pCtx, SHCLOBJHANDLE hObj, void *pvBuf, uint32_t cbBuf,760 VBGLR3DECL(int) VbglR3ClipboardTransferObjWriteSend(PVBGLR3SHCLCMDCTX pCtx, SHCLOBJHANDLE hObj, void *pvBuf, uint32_t cbBuf, 763 761 uint32_t *pcbWritten); 764 762 # endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */ -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxClipboard.cpp
r100205 r100367 120 120 } 121 121 122 int rc2 = ShClTransferCtx TransferUnregister(pTransferCtx, pTransfer->State.uID);122 int rc2 = ShClTransferCtxUnregisterById(pTransferCtx, pTransfer->State.uID); 123 123 AssertRC(rc2); 124 124 … … 251 251 SharedClipboardWinDataObject *pObj = pCtx->Win.pDataObjInFlight; 252 252 AssertPtrReturnVoid(pObj); 253 rc = pObj->Set AndStartTransfer(pTransfer);253 rc = pObj->SetTransfer(pTransfer); 254 254 255 255 pCtx->Win.pDataObjInFlight = NULL; /* Hand off to Windows. */ -
trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibClipboard.cpp
r100291 r100367 118 118 pCtx->fHostFeatures = 0; 119 119 pCtx->fUseLegacyProtocol = true; 120 pCtx->cParmsRecived = 0;121 120 pCtx->idContext = 0; 122 121 … … 687 686 688 687 /** 689 * Reads a root list header from the host.688 * Reads a transfer root list header from the host. 690 689 * 691 690 * @returns VBox status code. … … 693 692 * @param pRootListHdr Where to store the received root list header. 694 693 */ 695 static int vbglR3Clipboard RootListHdrRead(PVBGLR3SHCLCMDCTX pCtx, PSHCLLISTHDR pRootListHdr)694 static int vbglR3ClipboardTransferRootListHdrRead(PVBGLR3SHCLCMDCTX pCtx, PSHCLLISTHDR pRootListHdr) 696 695 { 697 696 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); … … 720 719 } 721 720 } 722 723 LogFlowFuncLeaveRC(rc); 724 return rc; 725 } 726 727 /** 728 * Reads a root list entry from the host. 721 else 722 LogRel(("Shared Clipboard: Reading root list header failed: %Rrc\n", rc)); 723 724 LogFlowFuncLeaveRC(rc); 725 return rc; 726 } 727 728 /** 729 * Reads a transfer root list entry from the host. 729 730 * 730 731 * @returns VBox status code. … … 733 734 * @param pRootListEntry Where to store the root list entry read from the host. 734 735 */ 735 static int vbglR3Clipboard RootListEntryRead(PVBGLR3SHCLCMDCTX pCtx, uint64_t uIndex, PSHCLLISTENTRY pRootListEntry)736 static int vbglR3ClipboardTransferRootListEntryRead(PVBGLR3SHCLCMDCTX pCtx, uint64_t uIndex, PSHCLLISTENTRY pRootListEntry) 736 737 { 737 738 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); … … 794 795 } 795 796 } 797 else 798 LogRel(("Shared Clipboard: Reading root list entry failed: %Rrc\n", rc)); 796 799 } 797 800 … … 803 806 804 807 /** 805 * Reads the root list from the host.806 * 807 * @returns VBox status code. 808 * @param pCtx Shared Clipboard command context to use for the connection. 809 * @param p RootList Where to store the read root list.810 * 811 */ 812 VBGLR3DECL(int) VbglR3Clipboard RootListRead(PVBGLR3SHCLCMDCTX pCtx, PSHCLTRANSFER pTransfer)808 * Reads the transfer root list from the host. 809 * 810 * @returns VBox status code. 811 * @param pCtx Shared Clipboard command context to use for the connection. 812 * @param pTransfer Transfer to read root list for. 813 * Must be in INITIALIZED state. 814 */ 815 VBGLR3DECL(int) VbglR3ClipboardTransferRootListRead(PVBGLR3SHCLCMDCTX pCtx, PSHCLTRANSFER pTransfer) 813 816 { 814 817 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); 815 818 AssertPtrReturn(pTransfer, VERR_INVALID_POINTER); 816 819 820 AssertMsgReturn(ShClTransferGetStatus(pTransfer) == SHCLTRANSFERSTATUS_INITIALIZED, 821 ("Can't read root list -- wrong transfer status\n"), VERR_WRONG_ORDER); 822 817 823 SHCLLISTHDR Hdr; 818 int rc = vbglR3Clipboard RootListHdrRead(pCtx, &Hdr);824 int rc = vbglR3ClipboardTransferRootListHdrRead(pCtx, &Hdr); 819 825 if (RT_SUCCESS(rc)) 820 826 { 821 827 LogFlowFunc(("cEntries=%RU64, cTotalSize=%RU64\n", Hdr.cEntries, Hdr.cbTotalSize)); 828 829 if (!Hdr.cEntries) /* Should never happen (tm). */ 830 { 831 #ifdef DEBUG_andy 832 AssertFailed(); 833 #endif 834 LogRel(("Shared Clipboard: Warning: Transfer %RU32 has no entries\n", ShClTransferGetID(pTransfer))); 835 } 822 836 823 837 for (uint64_t i = 0; i < Hdr.cEntries; i++) … … 827 841 if (RT_SUCCESS(rc)) 828 842 { 829 rc = vbglR3Clipboard RootListEntryRead(pCtx, i, pEntry);843 rc = vbglR3ClipboardTransferRootListEntryRead(pCtx, i, pEntry); 830 844 if (RT_SUCCESS(rc)) 831 845 rc = ShClTransferListAddEntry(&pTransfer->lstRoots, pEntry, true /* fAppend */); … … 839 853 } 840 854 } 855 else 856 LogRel(("Shared Clipboard: Reading root list for transfer %RU32 failed: %Rrc\n", ShClTransferGetID(pTransfer), rc)); 841 857 842 858 LogFlowFuncLeaveRC(rc); … … 900 916 901 917 /** 918 * Replies to a transfer report from the host, extended version. 919 * 920 * @returns VBox status code. 921 * @param pCtx Shared Clipboard command context to use for the connection. 922 * @param uCID Context ID to use. 923 * The transfer ID is part of this. 924 * @param uStatus Tranfer status to reply. 925 * @param rcTransfer Result code (rc) to reply. 926 */ 927 static int vbglR3ClipboardTransferStatusReplyEx(PVBGLR3SHCLCMDCTX pCtx, uint64_t uCID, 928 SHCLTRANSFERSTATUS uStatus, int rcTransfer) 929 { 930 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); 931 932 VBoxShClReplyMsg Msg; 933 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->idClient, 934 VBOX_SHCL_GUEST_FN_REPLY, VBOX_SHCL_CPARMS_REPLY_MIN + 1); 935 936 Msg.uContext.SetUInt64(uCID); 937 Msg.enmType.SetUInt32(VBOX_SHCL_TX_REPLYMSGTYPE_TRANSFER_STATUS); 938 Msg.rc.SetUInt32((uint32_t )rcTransfer); /* int vs. uint32_t */ 939 Msg.pvPayload.SetPtr(NULL, 0); 940 941 Msg.u.TransferStatus.enmStatus.SetUInt32((uint32_t)uStatus); 942 943 LogFlowFunc(("%s\n", ShClTransferStatusToStr(uStatus))); 944 945 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg)); 946 947 LogFlowFuncLeaveRC(rc); 948 return rc; 949 } 950 951 /** 902 952 * Replies to a transfer report from the host. 903 953 * … … 914 964 AssertPtrReturn(pTransfer, VERR_INVALID_POINTER); 915 965 916 RT_NOREF(pTransfer); 917 918 VBoxShClReplyMsg Msg; 919 VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->idClient, 920 VBOX_SHCL_GUEST_FN_REPLY, VBOX_SHCL_CPARMS_REPLY_MIN + 1); 921 922 Msg.uContext.SetUInt64(pCtx->idContext); 923 Msg.enmType.SetUInt32(VBOX_SHCL_REPLYMSGTYPE_TRANSFER_STATUS); 924 Msg.rc.SetUInt32((uint32_t )rcTransfer); /* int vs. uint32_t */ 925 Msg.pvPayload.SetPtr(NULL, 0); 926 927 Msg.u.TransferStatus.enmStatus.SetUInt32((uint32_t)uStatus); 928 929 LogFlowFunc(("%s\n", ShClTransferStatusToStr(uStatus))); 930 931 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg)); 932 933 LogFlowFuncLeaveRC(rc); 934 return rc; 935 } 936 937 /** 938 * Receives a host request to read a root list header from the guest. 966 int rc = vbglR3ClipboardTransferStatusReplyEx(pCtx, pCtx->idContext, uStatus, rcTransfer); 967 968 LogFlowFuncLeaveRC(rc); 969 return rc; 970 } 971 972 /** 973 * Receives a host request to read a transfer root list header from the guest. 939 974 * 940 975 * @returns VBox status code. … … 942 977 * @param pfRoots Where to store the root list header flags to use, requested by the host. 943 978 */ 944 VBGLR3DECL(int) VbglR3Clipboard RootListHdrReadReq(PVBGLR3SHCLCMDCTX pCtx, uint32_t *pfRoots)979 VBGLR3DECL(int) VbglR3ClipboardTransferRootListHdrReadReq(PVBGLR3SHCLCMDCTX pCtx, uint32_t *pfRoots) 945 980 { 946 981 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); … … 970 1005 971 1006 /** 972 * Replies to a root list header request.1007 * Replies to a transfer root list header request. 973 1008 * 974 1009 * @returns VBox status code. … … 976 1011 * @param pRootListHdr Root lsit header to reply to the host. 977 1012 */ 978 VBGLR3DECL(int) VbglR3Clipboard RootListHdrReadReply(PVBGLR3SHCLCMDCTX pCtx, PSHCLLISTHDR pRootListHdr)1013 VBGLR3DECL(int) VbglR3ClipboardTransferRootListHdrReadReply(PVBGLR3SHCLCMDCTX pCtx, PSHCLLISTHDR pRootListHdr) 979 1014 { 980 1015 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); … … 997 1032 998 1033 /** 999 * Receives a host request to read a root list entry from the guest.1034 * Receives a host request to read a transfer root list entry from the guest. 1000 1035 * 1001 1036 * @returns VBox status code. … … 1004 1039 * @param pfInfo Where to return the read flags the host wants to use. 1005 1040 */ 1006 VBGLR3DECL(int) VbglR3Clipboard RootListEntryReadReq(PVBGLR3SHCLCMDCTX pCtx, uint32_t *puIndex, uint32_t *pfInfo)1041 VBGLR3DECL(int) VbglR3ClipboardTransferRootListEntryReadReq(PVBGLR3SHCLCMDCTX pCtx, uint64_t *puIndex, uint32_t *pfInfo) 1007 1042 { 1008 1043 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); … … 1016 1051 Msg.Parms.uContext.SetUInt64(VBOX_SHCL_HOST_MSG_TRANSFER_ROOT_LIST_ENTRY_READ); 1017 1052 Msg.Parms.fInfo.SetUInt32(0); 1018 Msg.Parms.uIndex.SetUInt 32(0);1053 Msg.Parms.uIndex.SetUInt64(0); 1019 1054 1020 1055 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg)); … … 1029 1064 if (RT_SUCCESS(rc)) 1030 1065 { 1031 rc = Msg.Parms.uIndex.GetUInt 32(puIndex);1066 rc = Msg.Parms.uIndex.GetUInt64(puIndex); 1032 1067 AssertRC(rc); 1033 1068 } … … 1039 1074 1040 1075 /** 1041 * Replies to a root list entry read request from the host.1076 * Replies to a transfer root list entry read request from the host. 1042 1077 * 1043 1078 * @returns VBox status code. … … 1046 1081 * @param pEntry Actual root list entry to reply. 1047 1082 */ 1048 VBGLR3DECL(int) VbglR3Clipboard RootListEntryReadReply(PVBGLR3SHCLCMDCTX pCtx, uint32_t uIndex, PSHCLLISTENTRY pEntry)1083 VBGLR3DECL(int) VbglR3ClipboardTransferRootListEntryReadReply(PVBGLR3SHCLCMDCTX pCtx, uint32_t uIndex, PSHCLLISTENTRY pEntry) 1049 1084 { 1050 1085 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); … … 1056 1091 1057 1092 Msg.Parms.uContext.SetUInt64(pCtx->idContext); 1058 Msg.Parms.fInfo.SetUInt32( 0);1059 Msg.Parms.uIndex.SetUInt 32(uIndex);1093 Msg.Parms.fInfo.SetUInt32(pEntry->fInfo); 1094 Msg.Parms.uIndex.SetUInt64(uIndex); 1060 1095 1061 1096 Msg.szName.SetPtr(pEntry->pszName, pEntry->cbName); … … 1070 1105 1071 1106 /** 1072 * Sends a request to open a list handle to the host.1107 * Sends a request to open a transfer list handle to the host. 1073 1108 * 1074 1109 * @returns VBox status code. … … 1077 1112 * @param phList Where to return the list handle received from the host. 1078 1113 */ 1079 VBGLR3DECL(int) VbglR3Clipboard ListOpenSend(PVBGLR3SHCLCMDCTX pCtx, PSHCLLISTOPENPARMS pOpenParms,1080 PSHCLLISTHANDLE phList)1114 VBGLR3DECL(int) VbglR3ClipboardTransferListOpenSend(PVBGLR3SHCLCMDCTX pCtx, PSHCLLISTOPENPARMS pOpenParms, 1115 PSHCLLISTHANDLE phList) 1081 1116 { 1082 1117 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); … … 1105 1140 1106 1141 /** 1107 * Receives a host request to open a list handle on the guest.1142 * Receives a host request to open a transfer list handle on the guest. 1108 1143 * 1109 1144 * @returns VBox status code. … … 1111 1146 * @param pOpenParms Where to store the open parameters the host wants to use for opening the list handle. 1112 1147 */ 1113 VBGLR3DECL(int) VbglR3Clipboard ListOpenRecv(PVBGLR3SHCLCMDCTX pCtx, PSHCLLISTOPENPARMS pOpenParms)1148 VBGLR3DECL(int) VbglR3ClipboardTransferListOpenRecv(PVBGLR3SHCLCMDCTX pCtx, PSHCLLISTOPENPARMS pOpenParms) 1114 1149 { 1115 1150 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); … … 1139 1174 1140 1175 /** 1141 * Replies to a list open request from the host.1176 * Replies to a transfer list open request from the host. 1142 1177 * 1143 1178 * @returns VBox status code. … … 1146 1181 * @param hList List handle of (guest) list to reply to the host. 1147 1182 */ 1148 VBGLR3DECL(int) VbglR3Clipboard ListOpenReply(PVBGLR3SHCLCMDCTX pCtx, int rcReply, SHCLLISTHANDLE hList)1183 VBGLR3DECL(int) VbglR3ClipboardTransferListOpenReply(PVBGLR3SHCLCMDCTX pCtx, int rcReply, SHCLLISTHANDLE hList) 1149 1184 { 1150 1185 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); … … 1155 1190 1156 1191 Msg.uContext.SetUInt64(pCtx->idContext); 1157 Msg.enmType.SetUInt32(VBOX_SHCL_ REPLYMSGTYPE_LIST_OPEN);1192 Msg.enmType.SetUInt32(VBOX_SHCL_TX_REPLYMSGTYPE_LIST_OPEN); 1158 1193 Msg.rc.SetUInt32((uint32_t)rcReply); /** int vs. uint32_t */ 1159 1194 Msg.pvPayload.SetPtr(NULL, 0); … … 1174 1209 * @param phList Where to store the list handle to close, received from the host. 1175 1210 */ 1176 VBGLR3DECL(int) VbglR3Clipboard ListCloseRecv(PVBGLR3SHCLCMDCTX pCtx, PSHCLLISTHANDLE phList)1211 VBGLR3DECL(int) VbglR3ClipboardTransferListCloseRecv(PVBGLR3SHCLCMDCTX pCtx, PSHCLLISTHANDLE phList) 1177 1212 { 1178 1213 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); … … 1202 1237 1203 1238 /** 1204 * Replies to a list handle close request from the host.1239 * Replies to a transfer list handle close request from the host. 1205 1240 * 1206 1241 * @returns VBox status code. … … 1209 1244 * @param hList List handle the send the close reply for. 1210 1245 */ 1211 VBGLR3DECL(int) VbglR3Clipboard ListCloseReply(PVBGLR3SHCLCMDCTX pCtx, int rcReply, SHCLLISTHANDLE hList)1246 VBGLR3DECL(int) VbglR3ClipboardTransferListCloseReply(PVBGLR3SHCLCMDCTX pCtx, int rcReply, SHCLLISTHANDLE hList) 1212 1247 { 1213 1248 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); … … 1218 1253 1219 1254 Msg.uContext.SetUInt64(pCtx->idContext); 1220 Msg.enmType.SetUInt32(VBOX_SHCL_ REPLYMSGTYPE_LIST_CLOSE);1255 Msg.enmType.SetUInt32(VBOX_SHCL_TX_REPLYMSGTYPE_LIST_CLOSE); 1221 1256 Msg.rc.SetUInt32((uint32_t)rcReply); /** int vs. uint32_t */ 1222 1257 Msg.pvPayload.SetPtr(NULL, 0); … … 1231 1266 1232 1267 /** 1233 * Sends a request to close a list handle to the host.1268 * Sends a request to close a transfer list handle to the host. 1234 1269 * 1235 1270 * @returns VBox status code. … … 1237 1272 * @param hList List handle to request for closing on the host. 1238 1273 */ 1239 VBGLR3DECL(int) VbglR3Clipboard ListCloseSend(PVBGLR3SHCLCMDCTX pCtx, SHCLLISTHANDLE hList)1274 VBGLR3DECL(int) VbglR3ClipboardTransferListCloseSend(PVBGLR3SHCLCMDCTX pCtx, SHCLLISTHANDLE hList) 1240 1275 { 1241 1276 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); … … 1255 1290 1256 1291 /** 1257 * Sends a request to read a list header to the host.1292 * Sends a request to read a transfer list header to the host. 1258 1293 * 1259 1294 * @returns VBox status code. … … 1263 1298 * @param pListHdr Where to return the list header received from the host. 1264 1299 */ 1265 VBGLR3DECL(int) VbglR3Clipboard ListHdrRead(PVBGLR3SHCLCMDCTX pCtx, SHCLLISTHANDLE hList, uint32_t fFlags,1266 PSHCLLISTHDR pListHdr)1300 VBGLR3DECL(int) VbglR3ClipboardTransferListHdrRead(PVBGLR3SHCLCMDCTX pCtx, SHCLLISTHANDLE hList, uint32_t fFlags, 1301 PSHCLLISTHDR pListHdr) 1267 1302 { 1268 1303 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); … … 1297 1332 1298 1333 /** 1299 * Receives a host request to read a list header on the guest.1334 * Receives a host request to read a transfer list header on the guest. 1300 1335 * 1301 1336 * @returns VBox status code. … … 1304 1339 * @param pfFlags Where to return the List header read flags to use. 1305 1340 */ 1306 VBGLR3DECL(int) VbglR3Clipboard ListHdrReadRecvReq(PVBGLR3SHCLCMDCTX pCtx, PSHCLLISTHANDLE phList, uint32_t *pfFlags)1341 VBGLR3DECL(int) VbglR3ClipboardTransferListHdrReadRecvReq(PVBGLR3SHCLCMDCTX pCtx, PSHCLLISTHANDLE phList, uint32_t *pfFlags) 1307 1342 { 1308 1343 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); … … 1333 1368 1334 1369 /** 1335 * Sends (writes) a list header to the host.1370 * Sends (writes) a transfer list header to the host. 1336 1371 * 1337 1372 * @returns VBox status code. … … 1340 1375 * @param pListHdr List header to write. 1341 1376 */ 1342 VBGLR3DECL(int) VbglR3Clipboard ListHdrWrite(PVBGLR3SHCLCMDCTX pCtx, SHCLLISTHANDLE hList,1343 PSHCLLISTHDR pListHdr)1377 VBGLR3DECL(int) VbglR3ClipboardTransferListHdrWrite(PVBGLR3SHCLCMDCTX pCtx, SHCLLISTHANDLE hList, 1378 PSHCLLISTHDR pListHdr) 1344 1379 { 1345 1380 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); … … 1366 1401 1367 1402 /** 1368 * Sends a request to read a list entry from the host.1403 * Sends a request to read a transfer list entry from the host. 1369 1404 * 1370 1405 * @returns VBox status code. … … 1373 1408 * @param pListEntry Where to return the list entry read from the host. 1374 1409 */ 1375 VBGLR3DECL(int) VbglR3Clipboard ListEntryRead(PVBGLR3SHCLCMDCTX pCtx, SHCLLISTHANDLE hList,1376 PSHCLLISTENTRY pListEntry)1410 VBGLR3DECL(int) VbglR3ClipboardTransferListEntryRead(PVBGLR3SHCLCMDCTX pCtx, SHCLLISTHANDLE hList, 1411 PSHCLLISTENTRY pListEntry) 1377 1412 { 1378 1413 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); … … 1402 1437 1403 1438 /** 1404 * Receives a host request to read a list entry from the guest.1439 * Receives a host request to read a transfer list entry from the guest. 1405 1440 * 1406 1441 * @returns VBox status code. … … 1409 1444 * @param pfInfo Where to return the list read flags. 1410 1445 */ 1411 VBGLR3DECL(int) VbglR3Clipboard ListEntryReadRecvReq(PVBGLR3SHCLCMDCTX pCtx, PSHCLLISTHANDLE phList, uint32_t *pfInfo)1446 VBGLR3DECL(int) VbglR3ClipboardTransferListEntryReadRecvReq(PVBGLR3SHCLCMDCTX pCtx, PSHCLLISTHANDLE phList, uint32_t *pfInfo) 1412 1447 { 1413 1448 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); … … 1444 1479 1445 1480 /** 1446 * Sends (writes) a list entry to the host.1481 * Sends (writes) a transfer list entry to the host. 1447 1482 * 1448 1483 * @returns VBox status code. … … 1451 1486 * @param pListEntry List entry to write. 1452 1487 */ 1453 VBGLR3DECL(int) VbglR3Clipboard ListEntryWrite(PVBGLR3SHCLCMDCTX pCtx, SHCLLISTHANDLE hList,1454 PSHCLLISTENTRY pListEntry)1488 VBGLR3DECL(int) VbglR3ClipboardTransferListEntryWrite(PVBGLR3SHCLCMDCTX pCtx, SHCLLISTHANDLE hList, 1489 PSHCLLISTENTRY pListEntry) 1455 1490 { 1456 1491 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); … … 1476 1511 1477 1512 /** 1478 * Receives a host request to open a nobject on the guest.1513 * Receives a host request to open a transfer object on the guest. 1479 1514 * 1480 1515 * @returns VBox status code. … … 1482 1517 * @param pCreateParms Where to store the object open/create parameters received from the host. 1483 1518 */ 1484 VBGLR3DECL(int) VbglR3Clipboard ObjOpenRecv(PVBGLR3SHCLCMDCTX pCtx, PSHCLOBJOPENCREATEPARMS pCreateParms)1519 VBGLR3DECL(int) VbglR3ClipboardTransferObjOpenRecv(PVBGLR3SHCLCMDCTX pCtx, PSHCLOBJOPENCREATEPARMS pCreateParms) 1485 1520 { 1486 1521 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); … … 1509 1544 1510 1545 /** 1511 * Replies a host request to open a nobject.1546 * Replies a host request to open a transfer object. 1512 1547 * 1513 1548 * @returns VBox status code. … … 1516 1551 * @param hObj Object handle of opened object to reply to the host. 1517 1552 */ 1518 VBGLR3DECL(int) VbglR3Clipboard ObjOpenReply(PVBGLR3SHCLCMDCTX pCtx, int rcReply, SHCLOBJHANDLE hObj)1553 VBGLR3DECL(int) VbglR3ClipboardTransferObjOpenReply(PVBGLR3SHCLCMDCTX pCtx, int rcReply, SHCLOBJHANDLE hObj) 1519 1554 { 1520 1555 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); … … 1525 1560 1526 1561 Msg.uContext.SetUInt64(pCtx->idContext); 1527 Msg.enmType.SetUInt32(VBOX_SHCL_ REPLYMSGTYPE_OBJ_OPEN);1562 Msg.enmType.SetUInt32(VBOX_SHCL_TX_REPLYMSGTYPE_OBJ_OPEN); 1528 1563 Msg.rc.SetUInt32((uint32_t)rcReply); /** int vs. uint32_t */ 1529 1564 Msg.pvPayload.SetPtr(NULL, 0); … … 1538 1573 1539 1574 /** 1540 * Sends a nobject open request to the host.1575 * Sends a transfer object open request to the host. 1541 1576 * 1542 1577 * @returns VBox status code. … … 1545 1580 * @param phObj Where to return the object handle from the host. 1546 1581 */ 1547 VBGLR3DECL(int) VbglR3Clipboard ObjOpenSend(PVBGLR3SHCLCMDCTX pCtx, PSHCLOBJOPENCREATEPARMS pCreateParms,1548 PSHCLOBJHANDLE phObj)1582 VBGLR3DECL(int) VbglR3ClipboardTransferObjOpenSend(PVBGLR3SHCLCMDCTX pCtx, PSHCLOBJOPENCREATEPARMS pCreateParms, 1583 PSHCLOBJHANDLE phObj) 1549 1584 { 1550 1585 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); … … 1572 1607 1573 1608 /** 1574 * Receives a host request to close a nobject on the guest.1609 * Receives a host request to close a transfer object on the guest. 1575 1610 * 1576 1611 * @returns VBox status code. … … 1578 1613 * @param phObj Where to return the object handle to close from the host. 1579 1614 */ 1580 VBGLR3DECL(int) VbglR3Clipboard ObjCloseRecv(PVBGLR3SHCLCMDCTX pCtx, PSHCLOBJHANDLE phObj)1615 VBGLR3DECL(int) VbglR3ClipboardTransferObjCloseRecv(PVBGLR3SHCLCMDCTX pCtx, PSHCLOBJHANDLE phObj) 1581 1616 { 1582 1617 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); … … 1603 1638 1604 1639 /** 1605 * Replies to a nobject open request from the host.1640 * Replies to a transfer object open request from the host. 1606 1641 * 1607 1642 * @returns VBox status code. … … 1610 1645 * @param hObj Object handle to reply to the host. 1611 1646 */ 1612 VBGLR3DECL(int) VbglR3Clipboard ObjCloseReply(PVBGLR3SHCLCMDCTX pCtx, int rcReply, SHCLOBJHANDLE hObj)1647 VBGLR3DECL(int) VbglR3ClipboardTransferObjCloseReply(PVBGLR3SHCLCMDCTX pCtx, int rcReply, SHCLOBJHANDLE hObj) 1613 1648 { 1614 1649 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); … … 1619 1654 1620 1655 Msg.uContext.SetUInt64(pCtx->idContext); 1621 Msg.enmType.SetUInt32(VBOX_SHCL_ REPLYMSGTYPE_OBJ_CLOSE);1656 Msg.enmType.SetUInt32(VBOX_SHCL_TX_REPLYMSGTYPE_OBJ_CLOSE); 1622 1657 Msg.rc.SetUInt32((uint32_t)rcReply); /** int vs. uint32_t */ 1623 1658 Msg.pvPayload.SetPtr(NULL, 0); … … 1632 1667 1633 1668 /** 1634 * Sends a request to close a nobject to the host.1669 * Sends a request to close a transfer object to the host. 1635 1670 * 1636 1671 * @returns VBox status code. … … 1638 1673 * @param hObj Object handle to close on the host. 1639 1674 */ 1640 VBGLR3DECL(int) VbglR3Clipboard ObjCloseSend(PVBGLR3SHCLCMDCTX pCtx, SHCLOBJHANDLE hObj)1675 VBGLR3DECL(int) VbglR3ClipboardTransferObjCloseSend(PVBGLR3SHCLCMDCTX pCtx, SHCLOBJHANDLE hObj) 1641 1676 { 1642 1677 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); … … 1656 1691 1657 1692 /** 1658 * Receives a host request to read from a nobject on the guest.1693 * Receives a host request to read from a transfer object on the guest. 1659 1694 * 1660 1695 * @returns VBox status code. … … 1664 1699 * @param pfFlags Where to return the read flags. 1665 1700 */ 1666 VBGLR3DECL(int) VbglR3Clipboard ObjReadRecv(PVBGLR3SHCLCMDCTX pCtx, PSHCLOBJHANDLE phObj, uint32_t *pcbToRead,1667 uint32_t *pfFlags)1701 VBGLR3DECL(int) VbglR3ClipboardTransferObjReadRecv(PVBGLR3SHCLCMDCTX pCtx, PSHCLOBJHANDLE phObj, uint32_t *pcbToRead, 1702 uint32_t *pfFlags) 1668 1703 { 1669 1704 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); … … 1698 1733 1699 1734 /** 1700 * Sends a request to read from a nobject to the host.1735 * Sends a request to read from a transfer object to the host. 1701 1736 * 1702 1737 * @returns VBox status code. … … 1707 1742 * @param pcbRead Where to store the amount (in bytes) read from the object. 1708 1743 */ 1709 VBGLR3DECL(int) VbglR3Clipboard ObjReadSend(PVBGLR3SHCLCMDCTX pCtx, SHCLOBJHANDLE hObj,1710 void *pvData, uint32_t cbData, uint32_t *pcbRead)1744 VBGLR3DECL(int) VbglR3ClipboardTransferObjReadSend(PVBGLR3SHCLCMDCTX pCtx, SHCLOBJHANDLE hObj, 1745 void *pvData, uint32_t cbData, uint32_t *pcbRead) 1711 1746 { 1712 1747 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); … … 1743 1778 1744 1779 /** 1745 * Sends a request to write to a nobject to the host.1780 * Sends a request to write to a transfer object to the host. 1746 1781 * 1747 1782 * @returns VBox status code. … … 1752 1787 * @param pcbWritten Where to store the amount (in bytes) written to the object. 1753 1788 */ 1754 VBGLR3DECL(int) VbglR3Clipboard ObjWriteSend(PVBGLR3SHCLCMDCTX pCtx, SHCLOBJHANDLE hObj,1755 void *pvData, uint32_t cbData, uint32_t *pcbWritten)1789 VBGLR3DECL(int) VbglR3ClipboardTransferObjWriteSend(PVBGLR3SHCLCMDCTX pCtx, SHCLOBJHANDLE hObj, 1790 void *pvData, uint32_t cbData, uint32_t *pcbWritten) 1756 1791 { 1757 1792 AssertPtrReturn(pCtx, VERR_INVALID_POINTER); … … 1797 1832 AssertPtr(pCmdCtx); 1798 1833 1799 int rc = VbglR3Clipboard RootListRead(pCmdCtx, pCtx->pTransfer);1834 int rc = VbglR3ClipboardTransferRootListRead(pCmdCtx, pCtx->pTransfer); 1800 1835 1801 1836 LogFlowFuncLeaveRC(rc); … … 1812 1847 AssertPtr(pCmdCtx); 1813 1848 1814 int rc = VbglR3Clipboard ListOpenSend(pCmdCtx, pOpenParms, phList);1849 int rc = VbglR3ClipboardTransferListOpenSend(pCmdCtx, pOpenParms, phList); 1815 1850 1816 1851 LogFlowFuncLeaveRC(rc); … … 1826 1861 AssertPtr(pCmdCtx); 1827 1862 1828 int rc = VbglR3Clipboard ListCloseSend(pCmdCtx, hList);1863 int rc = VbglR3ClipboardTransferListCloseSend(pCmdCtx, hList); 1829 1864 1830 1865 LogFlowFuncLeaveRC(rc); … … 1846 1881 if (RT_SUCCESS(rc)) 1847 1882 { 1848 rc = VbglR3Clipboard ListHdrRead(pCmdCtx, hList, 0 /* fFlags */, pListHdr);1883 rc = VbglR3ClipboardTransferListHdrRead(pCmdCtx, hList, 0 /* fFlags */, pListHdr); 1849 1884 } 1850 1885 else … … 1865 1900 AssertPtr(pCmdCtx); 1866 1901 1867 int rc = VbglR3Clipboard ListEntryRead(pCmdCtx, hList, pListEntry);1902 int rc = VbglR3ClipboardTransferListEntryRead(pCmdCtx, hList, pListEntry); 1868 1903 1869 1904 LogFlowFuncLeaveRC(rc); … … 1880 1915 AssertPtr(pCmdCtx); 1881 1916 1882 int rc = VbglR3Clipboard ObjOpenSend(pCmdCtx, pCreateParms, phObj);1917 int rc = VbglR3ClipboardTransferObjOpenSend(pCmdCtx, pCreateParms, phObj); 1883 1918 1884 1919 LogFlowFuncLeaveRC(rc); … … 1894 1929 AssertPtr(pCmdCtx); 1895 1930 1896 int rc = VbglR3Clipboard ObjCloseSend(pCmdCtx, hObj);1931 int rc = VbglR3ClipboardTransferObjCloseSend(pCmdCtx, hObj); 1897 1932 1898 1933 LogFlowFuncLeaveRC(rc); … … 1912 1947 RT_NOREF(fFlags); /* Not used yet. */ 1913 1948 1914 int rc = VbglR3Clipboard ObjReadSend(pCmdCtx, hObj, pvData, cbData, pcbRead);1915 1916 LogFlowFuncLeaveRC(rc); 1917 return rc; 1918 } 1919 1920 /** 1921 * Initializesa transfer on the guest side.1949 int rc = VbglR3ClipboardTransferObjReadSend(pCmdCtx, hObj, pvData, cbData, pcbRead); 1950 1951 LogFlowFuncLeaveRC(rc); 1952 return rc; 1953 } 1954 1955 /** 1956 * Creates (and registers) a transfer on the guest side. 1922 1957 * 1923 1958 * @returns VBox status code. 1924 1959 * @param pCmdCtx Command context to use. 1925 1960 * @param pTransferCtx Transfer context to init transfer for. 1926 * @param uTransferID ID to use for transfer to init.1927 * @param enm Dir Direction of transfer to init.1928 * @param enmSource Source of transfer to init.1961 * @param enmDir Specifies the transfer direction of this transfer. 1962 * @param enmSource Specifies the data source of the transfer. 1963 * @param idTransfer ID of transfer to create. 1929 1964 * @param ppTransfer Where to return the transfer object on success. Optional. 1930 1965 */ 1931 static int vbglR3ClipboardTransferInit(PVBGLR3SHCLCMDCTX pCmdCtx, PSHCLTRANSFERCTX pTransferCtx, 1932 SHCLTRANSFERID uTransferID, SHCLTRANSFERDIR enmDir, SHCLSOURCE enmSource, 1933 PSHCLTRANSFER *ppTransfer) 1934 { 1935 LogFlowFuncEnter(); 1966 static int vbglR3ClipboardTransferCreate(PVBGLR3SHCLCMDCTX pCmdCtx, PSHCLTRANSFERCTX pTransferCtx, 1967 SHCLTRANSFERDIR enmDir, SHCLSOURCE enmSource, SHCLTRANSFERID idTransfer, 1968 PSHCLTRANSFER *ppTransfer) 1969 { 1970 AssertReturn(idTransfer != NIL_SHCLTRANSFERID, VERR_WRONG_ORDER); 1971 1972 RT_NOREF(pCmdCtx); 1936 1973 1937 1974 PSHCLTRANSFER pTransfer; 1938 int rc = ShClTransferCreate( &pTransfer);1975 int rc = ShClTransferCreate(enmDir, enmSource, &pTransfer); 1939 1976 if (RT_SUCCESS(rc)) 1940 1977 { … … 1942 1979 ShClTransferSetCallbacks(pTransfer, &pCmdCtx->Transfers.Callbacks); 1943 1980 1944 rc = ShClTransferInit(pTransfer, enmDir, enmSource); 1945 if (RT_SUCCESS(rc)) 1946 { 1947 SHCLTXPROVIDER Provider; 1948 RT_ZERO(Provider); 1949 1950 /* Assign local provider first and overwrite interface methods below if needed. */ 1951 VBClTransferProviderLocalQueryInterface(&Provider); 1952 1953 /* If this is a read transfer (reading data from host), set the interface to use 1954 * our VbglR3 routines here. */ 1955 if (enmDir == SHCLTRANSFERDIR_FROM_REMOTE) /* Host -> Guest */ 1956 { 1957 Provider.Interface.pfnRootListRead = vbglR3ClipboardTransferIfaceRootListRead; 1958 1959 Provider.Interface.pfnListOpen = vbglR3ClipboardTransferIfaceListOpen; 1960 Provider.Interface.pfnListClose = vbglR3ClipboardTransferIfaceListClose; 1961 Provider.Interface.pfnListHdrRead = vbglR3ClipboardTransferIfaceListHdrRead; 1962 Provider.Interface.pfnListEntryRead = vbglR3ClipboardTransferIfaceListEntryRead; 1963 1964 Provider.Interface.pfnObjOpen = vbglR3ClipboardTransferIfaceObjOpen; 1965 Provider.Interface.pfnObjClose = vbglR3ClipboardTransferIfaceObjClose; 1966 Provider.Interface.pfnObjRead = vbglR3ClipboardTransferIfaceObjRead; 1967 } 1968 1969 Provider.pvUser = pCmdCtx; 1970 1971 rc = ShClTransferSetProvider(pTransfer, &Provider); 1972 1973 /* As a last step, register the transfer with our transfer context. */ 1974 if (RT_SUCCESS(rc)) 1975 rc = ShClTransferCtxTransferRegisterById(pTransferCtx, pTransfer, uTransferID); 1976 1977 if (RT_FAILURE(rc)) 1978 ShClTransferCtxTransferUnregisterById(pTransferCtx, uTransferID); 1979 } 1980 } 1981 1982 if (RT_SUCCESS(rc)) 1983 { 1984 if (ppTransfer) 1981 rc = ShClTransferCtxRegisterById(pTransferCtx, pTransfer, idTransfer); 1982 if ( RT_SUCCESS(rc) 1983 && ppTransfer) 1985 1984 *ppTransfer = pTransfer; 1986 1985 } 1986 1987 if (RT_SUCCESS(rc)) 1988 LogRel(("Shared Clipboard: Transfer %RU32 successfully created\n", idTransfer)); 1989 else 1990 LogRel(("Shared Clipboard: Error creating transfer %RU32, rc=%Rrc\n", idTransfer, rc)); 1991 1992 LogFlowFuncLeaveRC(rc); 1993 return rc; 1994 } 1995 1996 /** 1997 * Initializes a transfer on the guest side. 1998 * 1999 * @returns VBox status code. 2000 * @param pCmdCtx Command context to use. 2001 * @param pTransfer Transfer to init. 2002 */ 2003 static int vbglR3ClipboardTransferInit(PVBGLR3SHCLCMDCTX pCmdCtx, PSHCLTRANSFER pTransfer) 2004 { 2005 LogFlowFuncEnter(); 2006 2007 SHCLTRANSFERDIR const enmDir = ShClTransferGetDir(pTransfer); 2008 2009 SHCLTXPROVIDER Provider; 2010 RT_ZERO(Provider); 2011 2012 /* Assign local provider first and overwrite interface methods below if needed. */ 2013 ShClTransferProviderLocalQueryInterface(&Provider); 2014 2015 /* If this is a read transfer (reading data from host), set the interface to use 2016 * our VbglR3 routines here. */ 2017 if (enmDir == SHCLTRANSFERDIR_FROM_REMOTE) /* Host -> Guest */ 2018 { 2019 Provider.Interface.pfnRootListRead = vbglR3ClipboardTransferIfaceRootListRead; 2020 2021 Provider.Interface.pfnListOpen = vbglR3ClipboardTransferIfaceListOpen; 2022 Provider.Interface.pfnListClose = vbglR3ClipboardTransferIfaceListClose; 2023 Provider.Interface.pfnListHdrRead = vbglR3ClipboardTransferIfaceListHdrRead; 2024 Provider.Interface.pfnListEntryRead = vbglR3ClipboardTransferIfaceListEntryRead; 2025 2026 Provider.Interface.pfnObjOpen = vbglR3ClipboardTransferIfaceObjOpen; 2027 Provider.Interface.pfnObjClose = vbglR3ClipboardTransferIfaceObjClose; 2028 Provider.Interface.pfnObjRead = vbglR3ClipboardTransferIfaceObjRead; 2029 } 2030 else if (enmDir == SHCLTRANSFERDIR_TO_REMOTE) /* Guest -> Host */ 2031 { 2032 /* Uses the local provider assigned above. */ 2033 } 2034 else 2035 AssertFailed(); 2036 2037 Provider.pvUser = pCmdCtx; 2038 2039 /* Set the provider first before calling ShClTransferInit(), as the init callback might utilize some of the 2040 * provider functions. */ 2041 int rc = ShClTransferSetProvider(pTransfer, &Provider); 2042 if (RT_SUCCESS(rc)) 2043 { 2044 rc = ShClTransferInit(pTransfer); 2045 if (RT_SUCCESS(rc)) 2046 { 2047 /* As soon as we report the INITIALIZED state to the host, the host can start reading stuff from the transfer. 2048 * So make sure that we really are ready here. */ 2049 if (enmDir == SHCLTRANSFERDIR_TO_REMOTE) 2050 AssertMsgStmt(ShClTransferRootsCount(pTransfer), ("No root entries set yet!\n" 2051 "Those have to be present as soon we report the transfer as being INITIALIZED to the host\n"), 2052 rc = VERR_WRONG_ORDER); 2053 } 2054 } 2055 2056 SHCLTRANSFERID const idTransfer = ShClTransferGetID(pTransfer); 2057 2058 if (RT_SUCCESS(rc)) 2059 { 1987 2060 LogRel(("Shared Clipboard: Transfer %RU32 (%s) successfully initialized\n", 1988 uTransferID, 1989 enmDir == SHCLTRANSFERDIR_FROM_REMOTE ? "host -> guest" : "guest -> host")); 2061 idTransfer, enmDir == SHCLTRANSFERDIR_FROM_REMOTE ? "host -> guest" : "guest -> host")); 1990 2062 } 1991 2063 else 1992 LogRel(("Shared Clipboard: Unable to initialize transfer %RU32, rc=%Rrc\n", uTransferID, rc)); 1993 1994 /* Send a reply in any case. */ 1995 int rc2 = VbglR3ClipboardTransferStatusReply(pCmdCtx, pTransfer, 1996 RT_SUCCESS(rc) 1997 ? SHCLTRANSFERSTATUS_INITIALIZED : SHCLTRANSFERSTATUS_ERROR, rc); 1998 if (RT_SUCCESS(rc)) 1999 rc = rc2; 2000 2001 if (RT_FAILURE(rc)) 2002 { 2003 ShClTransferDestroy(pTransfer); 2004 pTransfer = NULL; 2005 } 2006 2007 LogFlowFuncLeaveRC(rc); 2008 return rc; 2009 } 2010 2011 /** 2012 * Uninitializes a transfer on the guest side. 2064 LogRel(("Shared Clipboard: Unable to initialize transfer %RU32, rc=%Rrc\n", idTransfer, rc)); 2065 2066 LogFlowFuncLeaveRC(rc); 2067 return rc; 2068 } 2069 2070 /** 2071 * Destroys a transfer on the guest side. 2013 2072 * 2014 2073 * @returns VBox status code. 2015 2074 * @param pCmdCtx Command context to use. 2016 2075 * @param pTransferCtx Transfer context to uninit transfer for. 2017 * @param uTransferID ID to use for transfer to uninit.2018 */ 2019 static int vbglR3ClipboardTransfer Uninit(PVBGLR3SHCLCMDCTX pCmdCtx, PSHCLTRANSFERCTX pTransferCtx, SHCLTRANSFERID uTransferID)2076 * @param idTransfer ID of transfer to initialize. 2077 */ 2078 static int vbglR3ClipboardTransferDestroy(PVBGLR3SHCLCMDCTX pCmdCtx, PSHCLTRANSFERCTX pTransferCtx, SHCLTRANSFERID idTransfer) 2020 2079 { 2021 2080 RT_NOREF(pCmdCtx); … … 2025 2084 int rc; 2026 2085 2027 PSHCLTRANSFER pTransfer = ShClTransferCtxGetTransferById(pTransferCtx, uTransferID);2086 PSHCLTRANSFER pTransfer = ShClTransferCtxGetTransferById(pTransferCtx, idTransfer); 2028 2087 if (pTransfer) 2029 2088 { 2030 rc = ShClTransferCtx TransferUnregisterById(pTransferCtx, uTransferID);2089 rc = ShClTransferCtxUnregisterById(pTransferCtx, idTransfer); 2031 2090 if (RT_SUCCESS(rc)) 2032 2091 rc = ShClTransferDestroy(pTransfer); … … 2034 2093 if (RT_SUCCESS(rc)) 2035 2094 { 2036 LogRel(("Shared Clipboard: Transfer %RU32 successfully uninitialized\n", uTransferID));2095 LogRel(("Shared Clipboard: Transfer %RU32 successfully uninitialized\n", idTransfer)); 2037 2096 } 2038 2097 else 2039 LogRel(("Shared Clipboard: Unable to uninitialized transfer %RU32, rc=%Rrc\n", uTransferID, rc));2098 LogRel(("Shared Clipboard: Unable to uninitialized transfer %RU32, rc=%Rrc\n", idTransfer, rc)); 2040 2099 } 2041 2100 else … … 2059 2118 2060 2119 /** 2120 * Requests a new transfer from the host. 2121 * 2122 * On success this will issue an INITIALIZED status reply from the host with a transfer ID set. 2123 * This ID will be used to initialize the transfer on the guest side then. 2124 * 2125 * @returns VBox status code. 2126 * @param pCmdCtx Command context to use. 2127 */ 2128 VBGLR3DECL(int) VbglR3ClipboardTransferRequest(PVBGLR3SHCLCMDCTX pCmdCtx) 2129 { 2130 LogFlowFuncEnter(); 2131 2132 LogRel2(("Shared Clipboard: Requesting new host -> guest transfer from host\n")); 2133 2134 int rc = vbglR3ClipboardTransferStatusReplyEx(pCmdCtx, 0 /* Context ID not needed */, 2135 SHCLTRANSFERSTATUS_REQUESTED, VINF_SUCCESS); 2136 LogFlowFuncLeaveRC(rc); 2137 return rc; 2138 } 2139 2140 /** 2061 2141 * Starts a transfer on the guest side. 2062 2142 * … … 2118 2198 if (pTransfer) 2119 2199 { 2120 rc = ShClTransferCtx TransferUnregisterById(pTransferCtx, uTransferID);2200 rc = ShClTransferCtxUnregisterById(pTransferCtx, uTransferID); 2121 2201 if (RT_SUCCESS(rc)) 2122 2202 { … … 2178 2258 if (RT_SUCCESS(rc)) 2179 2259 { 2180 const SHCLTRANSFERID uTransferID= VBOX_SHCL_CONTEXTID_GET_TRANSFER(pCmdCtx->idContext);2260 const SHCLTRANSFERID idTransfer = VBOX_SHCL_CONTEXTID_GET_TRANSFER(pCmdCtx->idContext); 2181 2261 2182 2262 LogRel(("Shared Clipboard: Received status %s (%Rrc) for transfer %RU32\n", 2183 ShClTransferStatusToStr(transferReport.uStatus), transferReport.rc, uTransferID)); 2263 ShClTransferStatusToStr(transferReport.uStatus), transferReport.rc, idTransfer)); 2264 2265 SHCLSOURCE enmSource = SHCLSOURCE_INVALID; 2184 2266 2185 2267 switch (transferReport.uStatus) 2186 2268 { 2187 case SHCLTRANSFERSTATUS_NONE: 2188 AssertFailed(); /* Should never happen. */ 2269 case SHCLTRANSFERSTATUS_REQUESTED: /* Only used for H->G transfers. */ 2270 { 2271 enmDir = SHCLTRANSFERDIR_FROM_REMOTE; 2272 enmSource = SHCLSOURCE_REMOTE; 2273 2274 /* The host acknowledged our request to create a new transfer. 2275 * So create a new transfer here with the transfer ID we just got from the host. 2276 * 2277 * Actual initialization will be done as soon as the host sends use the INITIALIZED status for it. 2278 */ 2279 PSHCLTRANSFER pTransfer; 2280 rc = vbglR3ClipboardTransferCreate(pCmdCtx, pTransferCtx, enmDir, enmSource, idTransfer, &pTransfer); 2281 2282 /* As soon as we've created our transfer locally, report back INITIALIZED to the host. 2283 * This will initialize the transfer on the host, so that in turn reports INITIALIZED 2284 * back to us (see case down below).*/ 2285 int rc2 = VbglR3ClipboardTransferStatusReply(pCmdCtx, pTransfer, 2286 RT_SUCCESS(rc) 2287 ? SHCLTRANSFERSTATUS_INITIALIZED : SHCLTRANSFERSTATUS_ERROR, rc); 2288 if (RT_SUCCESS(rc)) 2289 rc = rc2; 2189 2290 break; 2291 } 2190 2292 2191 2293 case SHCLTRANSFERSTATUS_INITIALIZED: 2192 2294 { 2193 SHCLSOURCE enmSource = SHCLSOURCE_INVALID;2194 2195 2295 /* The host announces the transfer direction from its point of view, so inverse the direction here. */ 2196 if (enmDir == SHCLTRANSFERDIR_TO_REMOTE) /* H ost -> Guest*/2296 if (enmDir == SHCLTRANSFERDIR_TO_REMOTE) /* H -> G */ 2197 2297 { 2198 enmDir = SHCLTRANSFERDIR_FROM_REMOTE;2298 enmDir = SHCLTRANSFERDIR_FROM_REMOTE; 2199 2299 enmSource = SHCLSOURCE_REMOTE; 2200 2201 rc = vbglR3ClipboardTransferInit(pCmdCtx, pTransferCtx, uTransferID,2202 enmDir, enmSource, NULL /* ppTransfer */);2203 2300 } 2204 else if (enmDir == SHCLTRANSFERDIR_FROM_REMOTE) /* G uest -> Host*/2301 else if (enmDir == SHCLTRANSFERDIR_FROM_REMOTE) /* G -> H */ 2205 2302 { 2206 /* Already initialized when remote (host) was reading the URI data. */ 2207 enmDir = SHCLTRANSFERDIR_TO_REMOTE; 2303 enmDir = SHCLTRANSFERDIR_TO_REMOTE; 2208 2304 enmSource = SHCLSOURCE_LOCAL; 2209 2210 rc = vbglR3ClipboardTransferInit(pCmdCtx, pTransferCtx, uTransferID,2211 enmDir, enmSource, NULL /* ppTransfer */);2212 2305 } 2213 2306 else 2214 2307 AssertFailedBreakStmt(rc = VERR_INVALID_PARAMETER); 2215 2308 2309 if (enmDir == SHCLTRANSFERDIR_FROM_REMOTE) /* H->G */ 2310 { 2311 /* The host reported INITIALIZED for the transfer. 2312 * So init our local transfer as well now. */ 2313 PSHCLTRANSFER pTransfer = ShClTransferCtxGetTransferById(pTransferCtx, idTransfer); 2314 if (pTransfer) 2315 { 2316 rc = vbglR3ClipboardTransferInit(pCmdCtx, pTransfer); 2317 2318 /* Only send back a reply on error -- we already reported INITIALIZED 2319 * in the case SHCLTRANSFERSTATUS_REQUESTED above. */ 2320 if (RT_FAILURE(rc)) 2321 { 2322 int rc2 = VbglR3ClipboardTransferStatusReply(pCmdCtx, pTransfer, 2323 SHCLTRANSFERSTATUS_ERROR, rc); 2324 AssertRC(rc2); 2325 } 2326 } 2327 else 2328 rc = VERR_SHCLPB_TRANSFER_ID_NOT_FOUND; 2329 } 2330 else if (enmDir == SHCLTRANSFERDIR_TO_REMOTE) /* G->H */ 2331 { 2332 /* The host reported the INITIALIZED status together with the transfer ID. 2333 * So create a local transfer here with that ID. */ 2334 PSHCLTRANSFER pTransfer; 2335 rc = vbglR3ClipboardTransferCreate(pCmdCtx, pTransferCtx, enmDir, enmSource, idTransfer, &pTransfer); 2336 if (RT_SUCCESS(rc)) 2337 rc = vbglR3ClipboardTransferInit(pCmdCtx, pTransfer); 2338 2339 /* Send a reply in any case. */ 2340 int rc2 = VbglR3ClipboardTransferStatusReply(pCmdCtx, pTransfer, 2341 RT_SUCCESS(rc) 2342 ? SHCLTRANSFERSTATUS_INITIALIZED : SHCLTRANSFERSTATUS_ERROR, rc); 2343 if (RT_SUCCESS(rc)) 2344 rc = rc2; 2345 } 2346 else 2347 AssertFailedBreakStmt(rc = VERR_INVALID_PARAMETER); 2348 2216 2349 break; 2217 2350 } … … 2219 2352 case SHCLTRANSFERSTATUS_UNINITIALIZED: 2220 2353 { 2221 rc = vbglR3ClipboardTransfer Uninit(pCmdCtx, pTransferCtx, uTransferID);2354 rc = vbglR3ClipboardTransferDestroy(pCmdCtx, pTransferCtx, idTransfer); 2222 2355 break; 2223 2356 } … … 2225 2358 case SHCLTRANSFERSTATUS_STARTED: 2226 2359 { 2227 rc = vbglR3ClipboardTransferStart(pCmdCtx, pTransferCtx, uTransferID);2360 rc = vbglR3ClipboardTransferStart(pCmdCtx, pTransferCtx, idTransfer); 2228 2361 break; 2229 2362 } … … 2237 2370 case SHCLTRANSFERSTATUS_ERROR: 2238 2371 { 2239 rc = vbglR3ClipboardTransferStop(pCmdCtx, pTransferCtx, 2240 VBOX_SHCL_CONTEXTID_GET_TRANSFER(pCmdCtx->idContext)); 2372 rc = vbglR3ClipboardTransferStop(pCmdCtx, pTransferCtx, idTransfer); 2241 2373 break; 2242 2374 } … … 2244 2376 default: 2245 2377 LogRel(("Shared Clipboard: Received unknown status %#x (%Rrc) for transfer %RU32\n", 2246 pEvent->u.TransferStatus.Report. uStatus, pEvent->u.TransferStatus.Report.rc,2378 pEvent->u.TransferStatus.Report.rc, 2247 2379 pEvent->u.TransferStatus.uID)); 2248 2380 rc = VERR_NOT_SUPPORTED; … … 2265 2397 { 2266 2398 uint32_t fRoots; 2267 rc = VbglR3Clipboard RootListHdrReadReq(pCmdCtx, &fRoots);2399 rc = VbglR3ClipboardTransferRootListHdrReadReq(pCmdCtx, &fRoots); 2268 2400 2269 2401 /** @todo Validate / handle fRoots. */ … … 2282 2414 LogFlowFunc(("cRoots=%RU32\n", rootListHdr.cEntries)); 2283 2415 2284 rc = VbglR3Clipboard RootListHdrReadReply(pCmdCtx, &rootListHdr);2416 rc = VbglR3ClipboardTransferRootListHdrReadReply(pCmdCtx, &rootListHdr); 2285 2417 } 2286 2418 break; … … 2289 2421 case VBOX_SHCL_HOST_MSG_TRANSFER_ROOT_LIST_ENTRY_READ: 2290 2422 { 2291 uint 32_t uIndex;2423 uint64_t uIndex; 2292 2424 uint32_t fInfo; 2293 rc = VbglR3Clipboard RootListEntryReadReq(pCmdCtx, &uIndex, &fInfo);2425 rc = VbglR3ClipboardTransferRootListEntryReadReq(pCmdCtx, &uIndex, &fInfo); 2294 2426 if (RT_SUCCESS(rc)) 2295 2427 { … … 2301 2433 if (pEntry) 2302 2434 { 2303 rc = VbglR3Clipboard RootListEntryReadReply(pCmdCtx, uIndex, pEntry);2435 rc = VbglR3ClipboardTransferRootListEntryReadReply(pCmdCtx, uIndex, pEntry); 2304 2436 } 2305 2437 else … … 2315 2447 if (RT_SUCCESS(rc)) 2316 2448 { 2317 rc = VbglR3Clipboard ListOpenRecv(pCmdCtx, &openParmsList);2449 rc = VbglR3ClipboardTransferListOpenRecv(pCmdCtx, &openParmsList); 2318 2450 if (RT_SUCCESS(rc)) 2319 2451 { … … 2328 2460 2329 2461 /* Reply in any case. */ 2330 int rc2 = VbglR3Clipboard ListOpenReply(pCmdCtx, rc, hList);2462 int rc2 = VbglR3ClipboardTransferListOpenReply(pCmdCtx, rc, hList); 2331 2463 AssertRC(rc2); 2332 2464 } … … 2341 2473 { 2342 2474 SHCLLISTHANDLE hList; 2343 rc = VbglR3Clipboard ListCloseRecv(pCmdCtx, &hList);2475 rc = VbglR3ClipboardTransferListCloseRecv(pCmdCtx, &hList); 2344 2476 if (RT_SUCCESS(rc)) 2345 2477 { … … 2351 2483 2352 2484 /* Reply in any case. */ 2353 int rc2 = VbglR3Clipboard ListCloseReply(pCmdCtx, rc, hList);2485 int rc2 = VbglR3ClipboardTransferListCloseReply(pCmdCtx, rc, hList); 2354 2486 AssertRC(rc2); 2355 2487 } … … 2364 2496 SHCLLISTHANDLE hList = NIL_SHCLLISTHANDLE; 2365 2497 uint32_t fFlags = 0; 2366 rc = VbglR3Clipboard ListHdrReadRecvReq(pCmdCtx, &hList, &fFlags);2498 rc = VbglR3ClipboardTransferListHdrReadRecvReq(pCmdCtx, &hList, &fFlags); 2367 2499 if (RT_SUCCESS(rc)) 2368 2500 { … … 2375 2507 if (RT_SUCCESS(rc)) 2376 2508 { 2377 rc = VbglR3Clipboard ListHdrWrite(pCmdCtx, hList, &hdrList);2509 rc = VbglR3ClipboardTransferListHdrWrite(pCmdCtx, hList, &hdrList); 2378 2510 2379 2511 ShClTransferListHdrDestroy(&hdrList); … … 2394 2526 SHCLLISTHANDLE hList; 2395 2527 uint32_t fInfo; 2396 rc = VbglR3Clipboard ListEntryReadRecvReq(pCmdCtx, &hList, &fInfo);2528 rc = VbglR3ClipboardTransferListEntryReadRecvReq(pCmdCtx, &hList, &fInfo); 2397 2529 if (RT_SUCCESS(rc)) 2398 2530 { … … 2411 2543 LogFlowFunc(("\t%s (%RU64 bytes)\n", entryList.pszName, pObjInfo->cbObject)); 2412 2544 2413 rc = VbglR3Clipboard ListEntryWrite(pCmdCtx, hList, &entryList);2545 rc = VbglR3ClipboardTransferListEntryWrite(pCmdCtx, hList, &entryList); 2414 2546 } 2415 2547 } … … 2427 2559 if (RT_SUCCESS(rc)) 2428 2560 { 2429 rc = VbglR3Clipboard ObjOpenRecv(pCmdCtx, &openParms);2561 rc = VbglR3ClipboardTransferObjOpenRecv(pCmdCtx, &openParms); 2430 2562 if (RT_SUCCESS(rc)) 2431 2563 { … … 2438 2570 2439 2571 /* Reply in any case. */ 2440 int rc2 = VbglR3Clipboard ObjOpenReply(pCmdCtx, rc, hObj);2572 int rc2 = VbglR3ClipboardTransferObjOpenReply(pCmdCtx, rc, hObj); 2441 2573 AssertRC(rc2); 2442 2574 } … … 2451 2583 { 2452 2584 SHCLOBJHANDLE hObj; 2453 rc = VbglR3Clipboard ObjCloseRecv(pCmdCtx, &hObj);2585 rc = VbglR3ClipboardTransferObjCloseRecv(pCmdCtx, &hObj); 2454 2586 if (RT_SUCCESS(rc)) 2455 2587 { … … 2461 2593 2462 2594 /* Reply in any case. */ 2463 int rc2 = VbglR3Clipboard ObjCloseReply(pCmdCtx, rc, hObj);2595 int rc2 = VbglR3ClipboardTransferObjCloseReply(pCmdCtx, rc, hObj); 2464 2596 AssertRC(rc2); 2465 2597 } … … 2473 2605 uint32_t cbBuf; 2474 2606 uint32_t fFlags; 2475 rc = VbglR3Clipboard ObjReadRecv(pCmdCtx, &hObj, &cbBuf, &fFlags);2607 rc = VbglR3ClipboardTransferObjReadRecv(pCmdCtx, &hObj, &cbBuf, &fFlags); 2476 2608 if (RT_SUCCESS(rc)) 2477 2609 { … … 2493 2625 rc = ShClTransferObjRead(pTransfer, hObj, pvBuf, cbToRead, fFlags, &cbRead); 2494 2626 if (RT_SUCCESS(rc)) 2495 rc = VbglR3Clipboard ObjWriteSend(pCmdCtx, hObj, pvBuf, cbRead, NULL /* pcbWritten */);2627 rc = VbglR3ClipboardTransferObjWriteSend(pCmdCtx, hObj, pvBuf, cbRead, NULL /* pcbWritten */); 2496 2628 2497 2629 RTMemFree(pvBuf); -
trunk/src/VBox/Additions/x11/VBoxClient/clipboard-x11.cpp
r100286 r100367 57 57 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS_HTTP 58 58 /** 59 * Worker for waiting for a transfer status change. 60 */ 61 static DECLCALLBACK(int) vbclX11TransferWaitForStatusWorker(PSHCLCONTEXT pCtx, PSHCLTRANSFER pTransfer, SHCLTRANSFERSTATUS enmSts, 62 RTMSINTERVAL msTimeout) 63 { 64 RT_NOREF(pCtx); 65 66 LogFlowFuncEnter(); 67 68 int rc = VERR_TIMEOUT; 69 70 ShClTransferAcquire(pTransfer); 71 72 uint64_t const tsStartMs = RTTimeMilliTS(); 73 74 while (RTTimeMilliTS() - tsStartMs <= msTimeout) 75 { 76 if (ShClTransferGetStatus(pTransfer) == enmSts) /* Currently we only have busy waiting here. */ 77 { 78 rc = VINF_SUCCESS; 79 break; 80 } 81 RTThreadSleep(100); 82 } 83 84 ShClTransferRelease(pTransfer); 85 86 return rc; 87 } 88 89 /** 90 * @copydoc SHCLTRANSFERCALLBACKS::pfnOnRegistered 91 * 92 * This starts the HTTP server if not done yet and registers the transfer with it. 59 * @copydoc SHCLTRANSFERCALLBACKS::pfnOnInitialized 93 60 * 94 61 * @thread Clipboard main thread. 95 62 */ 96 static DECLCALLBACK(void) vbclX11OnHttpTransferRegisteredCallback(PSHCLTRANSFERCALLBACKCTX pCbCtx, PSHCLTRANSFERCTX pTransferCtx) 97 { 98 RT_NOREF(pTransferCtx); 99 63 static DECLCALLBACK(void) vbclX11OnTransferInitializedCallback(PSHCLTRANSFERCALLBACKCTX pCbCtx) 64 { 100 65 LogFlowFuncEnter(); 101 66 … … 106 71 AssertPtr(pTransfer); 107 72 108 ShClTransferAcquire(pTransfer); 73 int rc = VINF_SUCCESS; 74 75 /* If this is a G->H transfer, we need to set the root list entries here, as the host 76 * will start reading those as soon as we report the INITIALIZED status. */ 77 switch (ShClTransferGetDir(pTransfer)) 78 { 79 case SHCLTRANSFERDIR_TO_REMOTE: /* G->H */ 80 { 81 PSHCLEVENT pEvent; 82 rc = ShClEventSourceGenerateAndRegisterEvent(&pCtx->EventSrc, &pEvent); 83 if (RT_SUCCESS(rc)) 84 { 85 rc = ShClX11ReadDataFromX11Async(&g_Ctx.X11, VBOX_SHCL_FMT_URI_LIST, UINT32_MAX, pEvent); 86 if (RT_SUCCESS(rc)) 87 { 88 PSHCLEVENTPAYLOAD pPayload; 89 rc = ShClEventWait(pEvent, SHCL_TIMEOUT_DEFAULT_MS, &pPayload); 90 if (RT_SUCCESS(rc)) 91 { 92 if (pPayload) 93 { 94 Assert(pPayload->cbData == sizeof(SHCLX11RESPONSE)); 95 PSHCLX11RESPONSE pResp = (PSHCLX11RESPONSE)pPayload->pvData; 96 97 rc = ShClTransferRootsInitFromStringList(pTransfer, (const char *)pResp->Read.pvData, pResp->Read.cbData); 98 99 RTMemFree(pResp->Read.pvData); 100 pResp->Read.cbData = 0; 101 102 ShClPayloadFree(pPayload); 103 } 104 } 105 } 106 } 107 break; 108 } 109 110 case SHCLTRANSFERDIR_FROM_REMOTE: /* H->G */ 111 { 112 /* Retrieve the root entries as a first action, so that the transfer is ready to go 113 * once it gets registered to HTTP server. */ 114 int rc2 = ShClTransferRootListRead(pTransfer); 115 if ( RT_SUCCESS(rc2) 116 /* As soon as we register the transfer with the HTTP server, the transfer needs to have its roots set. */ 117 && ShClTransferRootsCount(pTransfer)) 118 { 119 rc2 = ShClTransferHttpServerRegisterTransfer(&pCtx->X11.HttpCtx.HttpServer, pTransfer); 120 } 121 break; 122 } 123 124 default: 125 break; 126 } 127 128 LogFlowFuncLeaveRC(rc); 129 } 130 131 /** 132 * @copydoc SHCLTRANSFERCALLBACKS::pfnOnRegistered 133 * 134 * This starts the HTTP server if not done yet and registers the transfer with it. 135 * 136 * @thread Clipboard main thread. 137 */ 138 static DECLCALLBACK(void) vbclX11OnTransferRegisteredCallback(PSHCLTRANSFERCALLBACKCTX pCbCtx, PSHCLTRANSFERCTX pTransferCtx) 139 { 140 RT_NOREF(pTransferCtx); 141 142 LogFlowFuncEnter(); 143 144 PSHCLCONTEXT pCtx = (PSHCLCONTEXT)pCbCtx->pvUser; 145 AssertPtr(pCtx); 146 147 PSHCLTRANSFER pTransfer = pCbCtx->pTransfer; 148 AssertPtr(pTransfer); 109 149 110 150 /* We only need to start the HTTP server when we actually receive data from the remote (host). */ 111 if (ShClTransferGetDir(pTransfer) == SHCLTRANSFERDIR_FROM_REMOTE) 112 { 113 /* Retrieve the root entries as a first action, so that the transfer is ready to go 114 * once it gets registered to HTTP server below. */ 115 int rc2 = ShClTransferRootListRead(pTransfer); 116 if (RT_SUCCESS(rc2)) 117 { 118 ShClTransferHttpServerMaybeStart(&pCtx->X11.HttpCtx); 119 rc2 = ShClTransferHttpServerRegisterTransfer(&pCtx->X11.HttpCtx.HttpServer, pTransfer); 120 } 121 151 if (ShClTransferGetDir(pTransfer) == SHCLTRANSFERDIR_FROM_REMOTE) /* H->G */ 152 { 153 int rc2 = ShClTransferHttpServerMaybeStart(&pCtx->X11.HttpCtx); 122 154 if (RT_FAILURE(rc2)) 123 155 LogRel(("Shared Clipboard: Registering HTTP transfer failed: %Rrc\n", rc2)); … … 137 169 * @thread Clipboard main thread. 138 170 */ 139 static void vbclX11 HttpTransferUnregister(PSHCLCONTEXT pCtx, PSHCLTRANSFER pTransfer)171 static void vbclX11TransferUnregister(PSHCLCONTEXT pCtx, PSHCLTRANSFER pTransfer) 140 172 { 141 173 if (ShClTransferGetDir(pTransfer) == SHCLTRANSFERDIR_FROM_REMOTE) 142 174 { 143 ShClTransferHttpServerUnregisterTransfer(&pCtx->X11.HttpCtx.HttpServer, pTransfer); 144 ShClTransferHttpServerMaybeStop(&pCtx->X11.HttpCtx); 145 } 146 147 ShClTransferRelease(pTransfer); 175 if (ShClTransferHttpServerIsInitialized(&pCtx->X11.HttpCtx.HttpServer)) 176 { 177 ShClTransferHttpServerUnregisterTransfer(&pCtx->X11.HttpCtx.HttpServer, pTransfer); 178 ShClTransferHttpServerMaybeStop(&pCtx->X11.HttpCtx); 179 } 180 } 148 181 } 149 182 … … 155 188 * @thread Clipboard main thread. 156 189 */ 157 static DECLCALLBACK(void) vbclX11On HttpTransferUnregisteredCallback(PSHCLTRANSFERCALLBACKCTX pCbCtx, PSHCLTRANSFERCTX pTransferCtx)190 static DECLCALLBACK(void) vbclX11OnTransferUnregisteredCallback(PSHCLTRANSFERCALLBACKCTX pCbCtx, PSHCLTRANSFERCTX pTransferCtx) 158 191 { 159 192 RT_NOREF(pTransferCtx); 160 vbclX11 HttpTransferUnregister((PSHCLCONTEXT)pCbCtx->pvUser, pCbCtx->pTransfer);193 vbclX11TransferUnregister((PSHCLCONTEXT)pCbCtx->pvUser, pCbCtx->pTransfer); 161 194 } 162 195 … … 168 201 * @thread Clipboard main thread. 169 202 */ 170 static DECLCALLBACK(void) vbclX11On HttpTransferCompletedCallback(PSHCLTRANSFERCALLBACKCTX pCbCtx, int rc)203 static DECLCALLBACK(void) vbclX11OnTransferCompletedCallback(PSHCLTRANSFERCALLBACKCTX pCbCtx, int rc) 171 204 { 172 205 RT_NOREF(rc); 173 vbclX11 HttpTransferUnregister((PSHCLCONTEXT)pCbCtx->pvUser, pCbCtx->pTransfer);206 vbclX11TransferUnregister((PSHCLCONTEXT)pCbCtx->pvUser, pCbCtx->pTransfer); 174 207 } 175 208 … … 180 213 * @thread Clipboard main thread. 181 214 */ 182 static DECLCALLBACK(void) vbclX11On HttpTransferErrorCallback(PSHCLTRANSFERCALLBACKCTX pCtx, int rc)183 { 184 return vbclX11On HttpTransferCompletedCallback(pCtx, rc);215 static DECLCALLBACK(void) vbclX11OnTransferErrorCallback(PSHCLTRANSFERCALLBACKCTX pCtx, int rc) 216 { 217 return vbclX11OnTransferCompletedCallback(pCtx, rc); 185 218 } 186 219 #endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS_HTTP */ … … 257 290 * @copydoc SHCLCALLBACKS::pfnOnRequestDataFromSource 258 291 * 259 * Requests URI data from the host. 260 * This initiates a transfer on the host. Most of the handling will be done VbglR3 then. 292 * Requests data from the host. 293 * 294 * For transfers: This requests a transfer from the host. Most of the handling will be done VbglR3 then. 261 295 * 262 296 * @thread X11 event thread. … … 274 308 if (uFmt == VBOX_SHCL_FMT_URI_LIST) 275 309 { 276 PSHCLHTTPSERVER pSrv = &pCtx->X11.HttpCtx.HttpServer;277 278 310 rc = vbclX11ReadDataWorker(pCtx, uFmt, ppv, pcb, pvUser); 279 311 if (RT_SUCCESS(rc)) 280 rc = ShClTransferHttpServerWaitForStatusChange(pSrv, SHCLHTTPSERVERSTATUS_TRANSFER_REGISTERED, 5000 /* SHCL_TIMEOUT_DEFAULT_MS */); 281 if (RT_SUCCESS(rc)) 282 { 283 PSHCLTRANSFER pTransfer = ShClTransferHttpServerGetTransferLast(pSrv); 284 if (pTransfer) 312 { 313 /* Request a new H->G transfer from the host. 314 * This is needed in order to get a transfer ID from the host we can initialize our own local transfer with. 315 * Transfer creation and set up will be done in VbglR3. */ 316 rc = VbglR3ClipboardTransferRequest(&pCtx->CmdCtx); 317 if (RT_SUCCESS(rc)) 285 318 { 286 rc = vbclX11TransferWaitForStatusWorker(pCtx, pTransfer, SHCLTRANSFERSTATUS_STARTED, SHCL_TIMEOUT_DEFAULT_MS); 319 PSHCLHTTPSERVER pSrv = &pCtx->X11.HttpCtx.HttpServer; 320 321 /* Wait until the HTTP server got the transfer registered, so that we have something to work with. */ 322 rc = ShClTransferHttpServerWaitForStatusChange(pSrv, SHCLHTTPSERVERSTATUS_TRANSFER_REGISTERED, SHCL_TIMEOUT_DEFAULT_MS); 287 323 if (RT_SUCCESS(rc)) 288 324 { 289 char *pszURL = ShClTransferHttpServerGetUrlA(pSrv, pTransfer->State.uID); 290 char *pszData = NULL; 291 RTStrAPrintf(&pszData, "copy\n%s", pszURL); 292 293 *ppv = pszData; 294 *pcb = strlen(pszData) + 1 /* Include terminator */; 295 296 LogFlowFunc(("pszURL=%s\n", pszURL)); 297 298 RTStrFree(pszURL); 299 300 rc = VINF_SUCCESS; 301 } 325 PSHCLTRANSFER pTransfer = ShClTransferHttpServerGetTransferLast(pSrv); 326 if (pTransfer) 327 { 328 rc = ShClTransferWaitForStatus(pTransfer, SHCL_TIMEOUT_DEFAULT_MS, SHCLTRANSFERSTATUS_INITIALIZED); 329 if (RT_SUCCESS(rc)) 330 { 331 char *pszURL = ShClTransferHttpServerGetUrlA(pSrv, pTransfer->State.uID); 332 if (pszURL) 333 { 334 *ppv = pszURL; 335 *pcb = strlen(pszURL) + 1 /* Include terminator */; 336 337 LogFlowFunc(("URL is '%s'\n", pszURL)); 338 339 /* ppv has ownership of pszURL. */ 340 } 341 else 342 rc = VERR_NO_MEMORY; 343 } 344 } 345 else 346 AssertMsgFailed(("No registered transfer found for HTTP server\n")); 347 } 348 else 349 LogRel(("Shared Clipboard: Could not start transfer, as no new HTTP transfer was registered in time\n")); 302 350 } 303 else 304 AssertMsgFailed(("No registered transfer found for HTTP server\n")); 305 } 306 else 307 LogRel(("Shared Clipboard: Could not start transfer, as the HTTP server is not running\n")); 351 } 308 352 } 309 353 else /* Anything else */ … … 314 358 315 359 if (RT_FAILURE(rc)) 316 LogRel((" Requesting data in format %#x from host failed with %Rrc\n", uFmt, rc));360 LogRel(("Shared Clipboard: Requesting data in format %#x from host failed with %Rrc\n", uFmt, rc)); 317 361 318 362 LogFlowFuncLeaveRC(rc); … … 418 462 pCtx->CmdCtx.Transfers.Callbacks.cbUser = sizeof(SHCLCONTEXT); 419 463 420 pCtx->CmdCtx.Transfers.Callbacks.pfnOnRegistered = vbclX11OnHttpTransferRegisteredCallback; 421 pCtx->CmdCtx.Transfers.Callbacks.pfnOnUnregistered = vbclX11OnHttpTransferUnregisteredCallback; 422 pCtx->CmdCtx.Transfers.Callbacks.pfnOnCompleted = vbclX11OnHttpTransferCompletedCallback; 423 pCtx->CmdCtx.Transfers.Callbacks.pfnOnError = vbclX11OnHttpTransferErrorCallback; 464 pCtx->CmdCtx.Transfers.Callbacks.pfnOnInitialized = vbclX11OnTransferInitializedCallback; 465 pCtx->CmdCtx.Transfers.Callbacks.pfnOnRegistered = vbclX11OnTransferRegisteredCallback; 466 pCtx->CmdCtx.Transfers.Callbacks.pfnOnUnregistered = vbclX11OnTransferUnregisteredCallback; 467 pCtx->CmdCtx.Transfers.Callbacks.pfnOnCompleted = vbclX11OnTransferCompletedCallback; 468 pCtx->CmdCtx.Transfers.Callbacks.pfnOnError = vbclX11OnTransferErrorCallback; 424 469 # endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS_HTTP */ 425 470 #endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */ -
trunk/src/VBox/GuestHost/SharedClipboard/ClipboardDataObjectImpl-win.cpp
r100205 r100367 224 224 m_fThreadRunning = false; 225 225 m_pTransfer = NULL; 226 }227 228 /**229 * Sets the callbacks for this object.230 *231 * @param pCallbacks Pointer to callbacks table to use.232 */233 void SharedClipboardWinDataObject::SetCallbacks(PSHCLCALLBACKS pCallbacks)234 {235 AssertPtrReturnVoid(pCallbacks);236 237 RT_ZERO(m_Callbacks);238 239 m_Callbacks.pfnOnRequestDataFromSource = pCallbacks->pfnOnRequestDataFromSource;240 226 } 241 227 … … 708 694 /* Request the transfer from the source. 709 695 * This will generate a transfer status message which we're waiting for here. */ 696 #if 0 // CLEAN 710 697 AssertPtr(m_Callbacks.pfnOnRequestDataFromSource); 711 698 rc = m_Callbacks.pfnOnRequestDataFromSource(m_pCtx, … … 713 700 this /* pvUser */); 714 701 AssertRCBreak(rc); 702 #else 703 rc = ShClTransferStart(m_pTransfer); 704 AssertRCBreak(rc); 705 #endif 715 706 716 707 LogRel2(("Shared Clipboard: Waiting for IDataObject started status ...\n")); … … 1014 1005 1015 1006 /** 1016 * Assigns a transfer object and starts the transferfor the data object.1007 * Assigns a transfer object for the data object. 1017 1008 * 1018 1009 * @returns VBox status code. 1019 1010 * @param pTransfer Transfer to assign. 1020 */ 1021 int SharedClipboardWinDataObject::SetAndStartTransfer(PSHCLTRANSFER pTransfer) 1011 * Must be in started state. 1012 */ 1013 int SharedClipboardWinDataObject::SetTransfer(PSHCLTRANSFER pTransfer) 1022 1014 { 1023 1015 AssertReturn(m_pTransfer == NULL, VERR_WRONG_ORDER); /* Transfer already set? */ … … 1028 1020 if (m_enmStatus == Initialized) 1029 1021 { 1022 AssertMsgReturn(ShClTransferGetStatus(pTransfer) == SHCLTRANSFERSTATUS_STARTED, 1023 ("Cannot set a non-started transfer\n"), VERR_WRONG_ORDER); 1024 1030 1025 m_pTransfer = pTransfer; 1031 1026 1032 1027 ShClTransferAcquire(pTransfer); 1033 1034 rc = setStatusLocked(Running);1035 1028 } 1036 1029 else … … 1048 1041 * @returns VBox status code. 1049 1042 * @param enmStatus New status to signal. 1050 * @param rc 1043 * @param rcSts Result code. Optional. 1051 1044 * 1052 1045 * @note Called by the main clipboard thread + SharedClipboardWinStreamImpl. 1053 1046 */ 1054 int SharedClipboardWinDataObject::SetStatus(Status enmStatus, int rc /* = VINF_SUCCESS */)1055 { 1056 int rc 2= RTCritSectEnter(&m_CritSect);1057 if (RT_SUCCESS(rc 2))1058 { 1059 setStatusLocked(enmStatus, rc);1047 int SharedClipboardWinDataObject::SetStatus(Status enmStatus, int rcSts /* = VINF_SUCCESS */) 1048 { 1049 int rc = RTCritSectEnter(&m_CritSect); 1050 if (RT_SUCCESS(rc)) 1051 { 1052 rc = setStatusLocked(enmStatus, rcSts); 1060 1053 1061 1054 RTCritSectLeave(&m_CritSect); 1062 1055 } 1063 1056 1064 return rc 2;1057 return rc; 1065 1058 } 1066 1059 -
trunk/src/VBox/GuestHost/SharedClipboard/clipboard-transfers-http.cpp
r100288 r100367 68 68 *********************************************************************************************************************************/ 69 69 70 #ifdef DEBUG_andy 71 /** When enabled, this lets the HTTP server run at a predictable URL and port for debugging: 72 * URL: http://localhost:49200/transfer<ID> */ 73 # define VBOX_SHCL_DEBUG_HTTPSERVER 74 #endif 75 70 76 typedef struct _SHCLHTTPSERVERTRANSFER 71 77 { … … 97 103 98 104 /********************************************************************************************************************************* 105 * Static assets * 106 *********************************************************************************************************************************/ 107 108 static char s_shClHttpServerPage404[] = " \ 109 <!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \ 110 \"http://www.w3.org/TR/html4/strict.dtd\"> \ 111 <html> \ 112 <head> \ 113 <meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\"> \ 114 <title>VirtualBox Shared Clipboard</title> \ 115 </head> \ 116 <body> \ 117 <h1>VirtualBox Shared Clipboard</h1> \ 118 <p>Error: 404</p> \ 119 <p>Message: Entry not found.</p> \ 120 </body> \ 121 </html>"; 122 123 124 /********************************************************************************************************************************* 99 125 * Internal Shared Clipboard HTTP transfer functions * 100 126 *********************************************************************************************************************************/ … … 240 266 if (pSrvTx) 241 267 { 242 shClHttpTransferLock(pSrvTx);243 268 pReq->pvUser = pSrvTx; 244 269 } … … 258 283 if (pSrvTx) 259 284 { 260 shClHttpTransferUnlock(pSrvTx);261 285 pReq->pvUser = NULL; 262 286 } … … 298 322 { 299 323 RT_NOREF(pData); 324 325 if (pvHandle == NULL) /* Serve a 404 page if we got an invalid handle. */ 326 { 327 Assert(cbBuf >= sizeof(s_shClHttpServerPage404)); /* Keep it simple for now. */ 328 memcpy(pvBuf, &s_shClHttpServerPage404, RT_MIN(cbBuf, sizeof(s_shClHttpServerPage404))); 329 *pcbRead = sizeof(s_shClHttpServerPage404); 330 return VINF_SUCCESS; 331 } 300 332 301 333 int rc; … … 385 417 AssertPtr(pTx); 386 418 387 /* For now we only serve single files, hence index 0 below. */419 /** @todo For now we only serve single files, hence index 0 below. */ 388 420 PCSHCLLISTENTRY pEntry = ShClTransferRootsEntryGet(pTx, 0 /* First file */); 389 421 if (pEntry) 390 422 { 423 LogRel2(("Shared Clipboard: Querying HTTP transfer information for '%s' ...\n", pEntry->pszName)); 424 391 425 rc = RTStrCopy(openParms.pszPath, openParms.cbPath, pEntry->pszName); 392 426 if (RT_SUCCESS(rc)) … … 402 436 PCSHCLFSOBJINFO pSrcObjInfo = (PSHCLFSOBJINFO)pEntry->pvInfo; 403 437 404 LogFlowFunc(("pszName=%s, cbInfo=%RU32, fMode= 0x%x (type %#x)\n",438 LogFlowFunc(("pszName=%s, cbInfo=%RU32, fMode=%#x (type %#x)\n", 405 439 pEntry->pszName, pEntry->cbInfo, pSrcObjInfo->Attr.fMode, (pSrcObjInfo->Attr.fMode & RTFS_TYPE_MASK))); 406 440 … … 411 445 } 412 446 } 447 else 448 LogRel2(("Shared Clipboard: Supplied entry information for '%s' not supported (fInfo=%#x, cbInfo=%RU32\n", 449 pEntry->pszName, pEntry->fInfo, pEntry->cbInfo)); 413 450 } 414 451 } … … 449 486 LogFlowFuncEnter(); 450 487 451 ASMAtomicXchgBool(&pSrv->fInitialized, false); 488 pSrv->fInitialized = false; 489 pSrv->fRunning = false; 452 490 453 491 int rc = VINF_SUCCESS; … … 596 634 597 635 /** 636 * Translates a Shared Clipboard HTTP server status to a string. 637 * 638 * @returns Status as a string. 639 * @param uMsg Status to translate. 640 */ 641 static const char *shClTransferHttpServerStatusToStr(SHCLHTTPSERVERSTATUS enmStatus) 642 { 643 switch (enmStatus) 644 { 645 RT_CASE_RET_STR(SHCLHTTPSERVERSTATUS_NONE); 646 RT_CASE_RET_STR(SHCLHTTPSERVERSTATUS_STARTED); 647 RT_CASE_RET_STR(SHCLHTTPSERVERSTATUS_STOPPED); 648 RT_CASE_RET_STR(SHCLHTTPSERVERSTATUS_TRANSFER_REGISTERED); 649 RT_CASE_RET_STR(SHCLHTTPSERVERSTATUS_TRANSFER_UNREGISTERED); 650 } 651 652 AssertFailedReturn("Unknown"); 653 } 654 655 /** 598 656 * Starts the Shared Clipboard HTTP server instance using a random port (>= 49152). 599 657 * … … 613 671 /* puPort is optional. */ 614 672 673 int rc; 674 #ifdef VBOX_SHCL_DEBUG_HTTPSERVER 675 uint16_t uDebugPort = 49200; 676 rc = ShClTransferHttpServerStartEx(pSrv, (uint32_t)uDebugPort); 677 if (RT_SUCCESS(rc)) 678 { 679 if (puPort) 680 *puPort = uDebugPort; 681 } 682 return rc; 683 #endif 684 615 685 RTRAND hRand; 616 intrc = RTRandAdvCreateSystemFaster(&hRand); /* Should be good enough for this task. */686 rc = RTRandAdvCreateSystemFaster(&hRand); /* Should be good enough for this task. */ 617 687 if (RT_SUCCESS(rc)) 618 688 { … … 662 732 int rc = VINF_SUCCESS; 663 733 664 if ( ASMAtomicReadBool(&pSrv->fRunning))734 if (pSrv->fRunning) 665 735 { 666 736 Assert(pSrv->hHTTPServer != NIL_RTHTTPSERVER); … … 740 810 static int shClTransferHttpServerDestroyTransfer(PSHCLHTTPSERVER pSrv, PSHCLHTTPSERVERTRANSFER pSrvTx) 741 811 { 812 Assert(RTCritSectIsOwner(&pSrv->CritSect)); 813 742 814 RTListNodeRemove(&pSrvTx->Node); 743 815 … … 751 823 pSrvTx->pTransfer->State.uID, pSrv->cTransfers)); 752 824 753 int rc = RTCritSectDelete(&pSrvTx->CritSect); 754 AssertRCReturn(rc, rc); 825 if (RTCritSectIsInitialized(&pSrvTx->CritSect)) 826 { 827 int rc = RTCritSectDelete(&pSrvTx->CritSect); 828 AssertRCReturn(rc, rc); 829 } 755 830 756 831 RTMemFree(pSrvTx); 757 832 pSrvTx = NULL; 758 833 759 return rc;834 return VINF_SUCCESS; 760 835 } 761 836 … … 799 874 { 800 875 rc = RTCritSectInit(&pSrvTx->CritSect); 801 AssertRC (rc);876 AssertRCReturn(rc, rc); 802 877 803 878 PCSHCLLISTENTRY pEntry = ShClTransferRootsEntryGet(pTransfer, 0 /* First file */); … … 806 881 /* Create the virtual HTTP path for the transfer. 807 882 * Every transfer has a dedicated HTTP path (but live in the same URL namespace). */ 883 #ifdef VBOX_SHCL_DEBUG_HTTPSERVER 884 # ifdef DEBUG_andy /** Too lazy to specify a different transfer ID for debugging. */ 885 ssize_t cch = RTStrPrintf2(pSrvTx->szPathVirtual, sizeof(pSrvTx->szPathVirtual), "/transfer"); 886 # else 887 ssize_t cch = RTStrPrintf2(pSrvTx->szPathVirtual, sizeof(pSrvTx->szPathVirtual), "/transfer%RU16", 888 pTransfer->State.uID); 889 # endif 890 #else 808 891 ssize_t cch = RTStrPrintf2(pSrvTx->szPathVirtual, sizeof(pSrvTx->szPathVirtual), "/%s/%s/%s", 809 892 SHCL_HTTPT_URL_NAMESPACE, szUuid, pEntry->pszName); 893 #endif 810 894 AssertReturn(cch, VERR_BUFFER_OVERFLOW); 811 895 … … 1044 1128 1045 1129 /** 1130 * Returns whether a given HTTP server instance is initialized or not. 1131 * 1132 * @returns \c true if running, or \c false if not. 1133 * @param pSrv HTTP server instance to check initialized state for. 1134 */ 1135 bool ShClTransferHttpServerIsInitialized(PSHCLHTTPSERVER pSrv) 1136 { 1137 AssertPtrReturn(pSrv, false); 1138 1139 return ASMAtomicReadBool(&pSrv->fInitialized); 1140 } 1141 1142 /** 1046 1143 * Returns whether a given HTTP server instance is running or not. 1047 1144 * … … 1060 1157 * 1061 1158 * @returns VBox status code. 1062 * @retval VERR_STATE_CHANGED if the HTTP server status has changed (not running anymore).1159 * @retval VERR_STATE_CHANGED if the HTTP server was uninitialized. 1063 1160 * @param pSrv HTTP server instance to wait for. 1064 1161 * @param fStatus Status to wait for. … … 1077 1174 int rc = VERR_TIMEOUT; 1078 1175 1079 LogFlowFunc(("fStatus=%#x, msTimeout=%RU32 \n", fStatus, msTimeout));1176 LogFlowFunc(("fStatus=%#x, msTimeout=%RU32 -- current is %#x\n", fStatus, msTimeout, pSrv->enmStatus)); 1080 1177 1081 1178 while (RTTimeMilliTS() - tsStartMs <= msTimeout) 1082 1179 { 1083 if ( !pSrv->fInitialized 1084 || !pSrv->fRunning) 1180 if (!pSrv->fInitialized) 1085 1181 { 1086 1182 rc = VERR_STATE_CHANGED; … … 1098 1194 1099 1195 LogFlowFunc(("Current status now is: %#x\n", pSrv->enmStatus)); 1196 LogRel2(("Shared Clipboard: HTTP server entered status '%s'\n", shClTransferHttpServerStatusToStr(pSrv->enmStatus))); 1100 1197 1101 1198 if (pSrv->enmStatus & fStatus) … … 1133 1230 rc = ShClTransferHttpServerStart(&pCtx->HttpServer, 32 /* cMaxAttempts */, NULL /* puPort */); 1134 1231 1232 LogFlowFuncLeaveRC(rc); 1135 1233 return rc; 1136 1234 } … … 1155 1253 } 1156 1254 1157 return rc; 1158 } 1159 1255 LogFlowFuncLeaveRC(rc); 1256 return rc; 1257 } 1258 -
trunk/src/VBox/GuestHost/SharedClipboard/clipboard-transfers-provider-local.cpp
r100265 r100367 904 904 * @param pProvider Provider to assign interface to. 905 905 */ 906 PSHCLTXPROVIDERIFACE VBClTransferProviderLocalQueryInterface(PSHCLTXPROVIDER pProvider)906 PSHCLTXPROVIDERIFACE ShClTransferProviderLocalQueryInterface(PSHCLTXPROVIDER pProvider) 907 907 { 908 908 pProvider->Interface.pfnRootListRead = shclTransferIfaceLocalRootListRead; -
trunk/src/VBox/GuestHost/SharedClipboard/clipboard-transfers.cpp
r100290 r100367 36 36 #include <iprt/semaphore.h> 37 37 #include <iprt/uri.h> 38 #include <iprt/utf16.h> 38 39 39 40 #include <VBox/err.h> 40 41 #include <VBox/HostServices/VBoxClipboardSvc.h> 42 #include <VBox/GuestHost/clipboard-helper.h> 41 43 #include <VBox/GuestHost/SharedClipboard-transfers.h> 42 44 43 45 46 DECLINLINE(void) shClTransferLock(PSHCLTRANSFER pTransfer); 47 DECLINLINE(void) shClTransferUnlock(PSHCLTRANSFER pTransfer); 48 static int shClTransferSetStatus(PSHCLTRANSFER pTransfer, SHCLTRANSFERSTATUS enmStatus); 44 49 static int shClTransferThreadCreate(PSHCLTRANSFER pTransfer, PFNRTTHREAD pfnThreadFunc, void *pvUser); 45 50 static int shClTransferThreadDestroy(PSHCLTRANSFER pTransfer, RTMSINTERVAL uTimeoutMs); 46 51 47 52 static void shclTransferCtxTransferRemoveAndUnregister(PSHCLTRANSFERCTX pTransferCtx, PSHCLTRANSFER pTransfer); 48 static PSHCLTRANSFER shClTransferCtxGetTransferByIdInternal(PSHCLTRANSFERCTX pTransferCtx, uint32_tuId);53 static PSHCLTRANSFER shClTransferCtxGetTransferByIdInternal(PSHCLTRANSFERCTX pTransferCtx, SHCLTRANSFERID uId); 49 54 static PSHCLTRANSFER shClTransferCtxGetTransferByIndexInternal(PSHCLTRANSFERCTX pTransferCtx, uint32_t uIdx); 50 55 … … 1045 1050 * 1046 1051 * @returns VBox status code. 1052 * @param enmDir Specifies the transfer direction of this transfer. 1053 * @param enmSource Specifies the data source of the transfer. 1047 1054 * @param cbMaxChunkSize Maximum transfer chunk size (in bytes) to use. 1048 1055 * @param cMaxListHandles Maximum list entries the transfer can have. … … 1051 1058 * Must be destroyed by ShClTransferDestroy(). 1052 1059 */ 1053 int ShClTransferCreateEx( uint32_t cbMaxChunkSize, uint32_t cMaxListHandles, uint32_t cMaxObjHandles,1054 PSHCLTRANSFER *ppTransfer)1060 int ShClTransferCreateEx(SHCLTRANSFERDIR enmDir, SHCLSOURCE enmSource, 1061 uint32_t cbMaxChunkSize, uint32_t cMaxListHandles, uint32_t cMaxObjHandles, PSHCLTRANSFER *ppTransfer) 1055 1062 { 1056 1063 … … 1063 1070 AssertPtrReturn(pTransfer, VERR_NO_MEMORY); 1064 1071 1065 pTransfer->State.uID = 0;1072 pTransfer->State.uID = NIL_SHCLTRANSFERID; 1066 1073 pTransfer->State.enmStatus = SHCLTRANSFERSTATUS_NONE; 1067 pTransfer->State.enmDir = SHCLTRANSFERDIR_UNKNOWN;1068 pTransfer->State.enmSource = SHCLSOURCE_INVALID;1074 pTransfer->State.enmDir = enmDir; 1075 pTransfer->State.enmSource = enmSource; 1069 1076 1070 1077 pTransfer->Thread.hThread = NIL_RTTHREAD; … … 1092 1099 ShClTransferListInit(&pTransfer->lstRoots); 1093 1100 1094 int rc = ShClEventSourceCreate(&pTransfer->Events, 0 /* uID */); 1101 int rc = RTCritSectInit(&pTransfer->CritSect); 1102 AssertRCReturn(rc, rc); 1103 1104 rc = RTSemEventCreate(&pTransfer->StatusChangeEvent); 1105 AssertRCReturn(rc, rc); 1106 1107 rc = ShClEventSourceCreate(&pTransfer->Events, 0 /* uID */); 1095 1108 if (RT_SUCCESS(rc)) 1096 1109 { … … 1114 1127 * 1115 1128 * @returns VBox status code. 1129 * @param enmDir Specifies the transfer direction of this transfer. 1130 * @param enmSource Specifies the data source of the transfer. 1116 1131 * @param ppTransfer Where to return the created clipboard transfer struct. 1117 1132 * Must be destroyed by ShClTransferDestroy(). 1118 1133 */ 1119 int ShClTransferCreate(PSHCLTRANSFER *ppTransfer) 1120 { 1121 return ShClTransferCreateEx(SHCL_TRANSFER_DEFAULT_MAX_CHUNK_SIZE, 1134 int ShClTransferCreate(SHCLTRANSFERDIR enmDir, SHCLSOURCE enmSource, PSHCLTRANSFER *ppTransfer) 1135 { 1136 return ShClTransferCreateEx(enmDir, enmSource, 1137 SHCL_TRANSFER_DEFAULT_MAX_CHUNK_SIZE, 1122 1138 SHCL_TRANSFER_DEFAULT_MAX_LIST_HANDLES, 1123 1139 SHCL_TRANSFER_DEFAULT_MAX_OBJ_HANDLES, … … 1140 1156 pTransfer->Callbacks.pfnOnDestroy(&pTransfer->CallbackCtx); 1141 1157 1142 AssertMsgReturn(pTransfer->cRefs == 0, ("Number of references > 0 (%RU32)\n", pTransfer->cRefs), VERR_WRONG_ORDER); 1158 AssertMsgReturn(ASMAtomicReadU32(&pTransfer->cRefs) == 0, 1159 ("Number of references > 0 (%RU32)\n", pTransfer->cRefs), VERR_WRONG_ORDER); 1143 1160 1144 1161 LogFlowFuncEnter(); 1145 1162 1146 int rc = shClTransferThreadDestroy(pTransfer, RT_MS_30SEC /* Timeout in ms */);1163 int rc = shClTransferThreadDestroy(pTransfer, SHCL_TIMEOUT_DEFAULT_MS); 1147 1164 if (RT_FAILURE(rc)) 1148 1165 return rc; … … 1153 1170 RTCritSectDelete(&pTransfer->CritSect); 1154 1171 1172 rc = RTSemEventDestroy(pTransfer->StatusChangeEvent); 1173 AssertRCReturn(rc, rc); 1174 pTransfer->StatusChangeEvent = NIL_RTSEMEVENT; 1175 1155 1176 ShClEventSourceDestroy(&pTransfer->Events); 1156 1177 … … 1164 1185 * @returns VBox status code. 1165 1186 * @param pTransfer Transfer to initialize. 1166 * @param enmDir Specifies the transfer direction of this transfer.1167 * @param enmSource Specifies the data source of the transfer. 1168 */ 1169 int ShClTransferInit(PSHCLTRANSFER pTransfer, SHCLTRANSFERDIR enmDir, SHCLSOURCE enmSource) 1170 { 1171 AssertMsgReturn (pTransfer->State.enmStatus < SHCLTRANSFERSTATUS_INITIALIZED,1172 ("Wrong status (currently is %s)\n", ShClTransferStatusToStr(pTransfer->State.enmStatus)),1173 VERR_WRONG_ORDER);1187 */ 1188 int ShClTransferInit(PSHCLTRANSFER pTransfer) 1189 { 1190 shClTransferLock(pTransfer); 1191 1192 AssertMsgReturnStmt(pTransfer->State.enmStatus < SHCLTRANSFERSTATUS_INITIALIZED, 1193 ("Wrong status (currently is %s)\n", ShClTransferStatusToStr(pTransfer->State.enmStatus)), 1194 shClTransferUnlock(pTransfer), VERR_WRONG_ORDER); 1174 1195 1175 1196 pTransfer->cRefs = 0; 1176 1177 pTransfer->State.enmDir = enmDir;1178 pTransfer->State.enmSource = enmSource;1179 1197 1180 1198 LogFlowFunc(("uID=%RU32, enmDir=%RU32, enmSource=%RU32\n", … … 1187 1205 pTransfer->uObjHandleNext = 1; 1188 1206 1189 /* Make sure that the callback context has all values set according to the callback table. 1190 * This only needs to be done once, so do this here. */ 1191 pTransfer->CallbackCtx.pTransfer = pTransfer; 1192 pTransfer->CallbackCtx.pvUser = pTransfer->Callbacks.pvUser; 1193 pTransfer->CallbackCtx.cbUser = pTransfer->Callbacks.cbUser; 1194 1195 int rc = RTCritSectInit(&pTransfer->CritSect); 1196 AssertRCReturn(rc, rc); 1197 1198 if (pTransfer->Callbacks.pfnOnInitialized) 1199 pTransfer->Callbacks.pfnOnInitialized(&pTransfer->CallbackCtx); 1207 int rc = shClTransferSetStatus(pTransfer, SHCLTRANSFERSTATUS_INITIALIZED); 1208 1209 shClTransferUnlock(pTransfer); 1200 1210 1201 1211 if (RT_SUCCESS(rc)) 1202 1212 { 1203 pTransfer->State.enmStatus = SHCLTRANSFERSTATUS_INITIALIZED; /* Now we're ready to run. */ 1213 if (pTransfer->Callbacks.pfnOnInitialized) 1214 pTransfer->Callbacks.pfnOnInitialized(&pTransfer->CallbackCtx); 1204 1215 } 1205 1216 … … 1249 1260 uint32_t ShClTransferRelease(PSHCLTRANSFER pTransfer) 1250 1261 { 1251 return ASMAtomicDecU32(&pTransfer->cRefs); 1262 const uint32_t cRefs = ASMAtomicDecU32(&pTransfer->cRefs); 1263 Assert(pTransfer->cRefs <= VBOX_SHCL_MAX_TRANSFERS); /* Not perfect, but better than nothing. */ 1264 return cRefs; 1252 1265 } 1253 1266 … … 1498 1511 1499 1512 ShClTransferCopyCallbacks(&pTransfer->Callbacks, pCallbacks); 1513 1514 /* Make sure that the callback context has all values set according to the callback table. 1515 * This only needs to be done once, so do this here. */ 1516 pTransfer->CallbackCtx.pTransfer = pTransfer; 1517 pTransfer->CallbackCtx.pvUser = pTransfer->Callbacks.pvUser; 1518 pTransfer->CallbackCtx.cbUser = pTransfer->Callbacks.cbUser; 1500 1519 } 1501 1520 … … 1528 1547 1529 1548 /** 1549 * Sets the current status. 1550 * 1551 * @returns VBox status code. 1552 * @param pTransfer Clipboard transfer to set status for. 1553 * @param enmStatus Status to set. 1554 * 1555 * @note Caller needs to take critical section. 1556 */ 1557 static int shClTransferSetStatus(PSHCLTRANSFER pTransfer, SHCLTRANSFERSTATUS enmStatus) 1558 { 1559 Assert(RTCritSectIsOwner(&pTransfer->CritSect)); 1560 #if 0 1561 AssertMsgReturn(pTransfer->State.enmStatus != enmStatus, 1562 ("Setting the same status twice in a row (%#x), please report this!\n", enmStatus), VERR_WRONG_ORDER); 1563 #endif 1564 pTransfer->State.enmStatus = enmStatus; 1565 1566 LogFlowFunc(("enmStatus=%s\n", ShClTransferStatusToStr(pTransfer->State.enmStatus))); 1567 1568 return RTSemEventSignal(pTransfer->StatusChangeEvent); 1569 } 1570 1571 /** 1530 1572 * Returns the number of transfer root list entries. 1531 1573 * … … 1638 1680 * @returns VBox status code. 1639 1681 * @param pTransfer Clipboard transfer to read root list for. 1682 * Must be in STARTED state. 1640 1683 */ 1641 1684 int ShClTransferRootListRead(PSHCLTRANSFER pTransfer) … … 1644 1687 1645 1688 LogFlowFuncEnter(); 1689 1690 #ifdef DEBUG 1691 shClTransferLock(pTransfer); 1692 AssertMsgReturn(pTransfer->State.enmStatus == SHCLTRANSFERSTATUS_INITIALIZED, 1693 ("Cannot read root list in status %s\n", ShClTransferStatusToStr(pTransfer->State.enmStatus)), 1694 VERR_WRONG_ORDER); 1695 shClTransferUnlock(pTransfer); 1696 #endif 1646 1697 1647 1698 int rc; … … 1684 1735 AssertReturn(cbRoots, VERR_INVALID_PARAMETER); 1685 1736 1686 LogFlowFunc Enter();1737 LogFlowFunc(("\n%.*Rhxd\n", cbRoots, pszRoots)); 1687 1738 1688 1739 if (!RTStrIsValidEncoding(pszRoots)) … … 1698 1749 char *pszPathRootAbs = NULL; 1699 1750 1700 RTCList<RTCString> lstRootEntries = RTCString(pszRoots, cbRoots - 1).split(SHCL_TRANSFER_URI_LIST_SEP_STR);1751 RTCList<RTCString> lstRootEntries = RTCString(pszRoots, cbRoots).split(SHCL_TRANSFER_URI_LIST_SEP_STR); 1701 1752 if (!lstRootEntries.size()) 1702 1753 { … … 1725 1776 LogFlowFunc(("pszPathCur=%s\n", pszPathCur)); 1726 1777 1727 rc = ShClTransferValidatePath(pszPathCur, false );1778 rc = ShClTransferValidatePath(pszPathCur, false /* fMustExist */); 1728 1779 if (RT_FAILURE(rc)) 1729 1780 { … … 1760 1811 if (RT_SUCCESS(rc)) 1761 1812 { 1762 PSHCLFSOBJINFO pFsObjInfo = (PSHCLFSOBJINFO )RTMemAlloc (sizeof(SHCLFSOBJINFO));1813 PSHCLFSOBJINFO pFsObjInfo = (PSHCLFSOBJINFO )RTMemAllocZ(sizeof(SHCLFSOBJINFO)); 1763 1814 if (pFsObjInfo) 1764 1815 { 1765 rc = ShClFsObjInfoQuery(pszPathCur, pFsObjInfo); 1816 if (pTransfer->State.enmDir == SHCLTRANSFERDIR_TO_REMOTE) 1817 rc = ShClFsObjInfoQueryLocal(pszPathCur, pFsObjInfo); 1766 1818 if (RT_SUCCESS(rc)) 1767 1819 { … … 1831 1883 1832 1884 /** 1885 * Initializes the root list entries for a given clipboard transfer, UTF-16 (Unicode) version. 1886 * 1887 * @returns VBox status code. 1888 * @param pTransfer Transfer to set transfer list entries for. 1889 * @param pwszRoots Unicode string list (separated by CRLF) of root entries to set. 1890 * All entries must have the same root path. 1891 * @param cbRoots Size (in bytes) of string list. Includes zero terminator. 1892 * 1893 * @note Accepts local paths or URI string lists (absolute only). 1894 */ 1895 int ShClTransferRootsInitFromStringListUnicode(PSHCLTRANSFER pTransfer, PRTUTF16 pwszRoots, size_t cbRoots) 1896 { 1897 AssertPtrReturn(pwszRoots, VERR_INVALID_POINTER); 1898 AssertReturn(cbRoots, VERR_INVALID_PARAMETER); 1899 AssertReturn(cbRoots % sizeof(RTUTF16) == 0, VERR_INVALID_PARAMETER); 1900 1901 size_t cwcRoots = cbRoots / sizeof(RTUTF16); 1902 1903 /* This may slightly overestimate the space needed. */ 1904 size_t chDst = 0; 1905 int rc = ShClUtf16LenUtf8(pwszRoots, cwcRoots, &chDst); 1906 if (RT_SUCCESS(rc)) 1907 { 1908 chDst++; /* Add space for terminator. */ 1909 1910 char *pszDst = (char *)RTStrAlloc(chDst); 1911 if (pszDst) 1912 { 1913 size_t cbActual = 0; 1914 rc = ShClConvUtf16CRLFToUtf8LF(pwszRoots, cwcRoots, pszDst, chDst, &cbActual); 1915 if (RT_SUCCESS(rc)) 1916 rc = ShClTransferRootsInitFromStringList(pTransfer, pszDst, cbActual + 1 /* Include terminator */); 1917 1918 RTStrFree(pszDst); 1919 } 1920 else 1921 rc = VERR_NO_MEMORY; 1922 } 1923 1924 return rc; 1925 } 1926 1927 /** 1833 1928 * Initializes a single file as a transfer root. 1834 1929 * … … 2013 2108 2014 2109 /* Ready to start? */ 2015 AssertMsgReturn(pTransfer->ProviderIface.pfnRootListRead != NULL, 2016 ("No provider interface set (yet)\n"), 2017 VERR_WRONG_ORDER); 2018 AssertMsgReturn(pTransfer->State.enmStatus == SHCLTRANSFERSTATUS_INITIALIZED, 2019 ("Wrong status (currently is %s)\n", ShClTransferStatusToStr(pTransfer->State.enmStatus)), 2020 VERR_WRONG_ORDER); 2021 2022 int rc = VINF_SUCCESS; 2023 2024 pTransfer->State.enmStatus = SHCLTRANSFERSTATUS_STARTED; 2110 AssertMsgReturnStmt(pTransfer->ProviderIface.pfnRootListRead != NULL, 2111 ("No provider interface set (yet)\n"), 2112 shClTransferUnlock(pTransfer), VERR_WRONG_ORDER); 2113 AssertMsgReturnStmt(pTransfer->State.enmStatus == SHCLTRANSFERSTATUS_INITIALIZED, 2114 ("Wrong status (currently is %s)\n", ShClTransferStatusToStr(pTransfer->State.enmStatus)), 2115 shClTransferUnlock(pTransfer), VERR_WRONG_ORDER); 2116 2117 int rc = shClTransferSetStatus(pTransfer, SHCLTRANSFERSTATUS_STARTED); 2025 2118 2026 2119 shClTransferUnlock(pTransfer); … … 2063 2156 shClTransferUnlock(pTransfer); /* Leave lock while waiting. */ 2064 2157 2065 int rc2 = RTThreadUserWait(pTransfer->Thread.hThread, RT_MS_30SEC /* Timeout in ms */);2158 int rc2 = RTThreadUserWait(pTransfer->Thread.hThread, SHCL_TIMEOUT_DEFAULT_MS); 2066 2159 AssertRC(rc2); 2067 2160 … … 2116 2209 } 2117 2210 2211 /** 2212 * Waits for the transfer status to change, internal version. 2213 * 2214 * @returns VBox status code. 2215 * @param pTransfer Clipboard transfer to wait for. 2216 * @param msTimeout Timeout (in ms) to wait. 2217 * @param penmStatus Where to return the new (current) transfer status on success. 2218 * Optional and can be NULL. 2219 */ 2220 static int shClTransferWaitForStatusChangeInternal(PSHCLTRANSFER pTransfer, RTMSINTERVAL msTimeout, SHCLTRANSFERSTATUS *penmStatus) 2221 { 2222 LogFlowFunc(("Waiting for status change (%RU32 timeout) ...\n", msTimeout)); 2223 2224 int rc = RTSemEventWait(pTransfer->StatusChangeEvent, msTimeout); 2225 if (RT_SUCCESS(rc)) 2226 { 2227 if (penmStatus) 2228 { 2229 shClTransferLock(pTransfer); 2230 2231 *penmStatus = pTransfer->State.enmStatus; 2232 2233 shClTransferUnlock(pTransfer); 2234 } 2235 } 2236 2237 return rc; 2238 } 2239 2240 /** 2241 * Waits for the transfer status to change. 2242 * 2243 * @returns VBox status code. 2244 * @param pTransfer Clipboard transfer to wait for. 2245 * @param msTimeout Timeout (in ms) to wait. 2246 * @param penmStatus Where to return the new (current) transfer status on success. 2247 * Optional and can be NULL. 2248 */ 2249 int ShClTransferWaitForStatusChange(PSHCLTRANSFER pTransfer, RTMSINTERVAL msTimeout, SHCLTRANSFERSTATUS *penmStatus) 2250 { 2251 AssertPtrReturn(pTransfer, VERR_INVALID_POINTER); 2252 2253 int rc = shClTransferWaitForStatusChangeInternal(pTransfer, msTimeout, penmStatus); 2254 2255 LogFlowFuncLeaveRC(rc); 2256 return rc; 2257 } 2258 2259 /** 2260 * Waits for a specific transfer status. 2261 * 2262 * @returns VBox status code. 2263 * @param pTransfer Clipboard transfer to wait for. 2264 * @param msTimeout Timeout (in ms) to wait. 2265 * @param enmStatus Transfer status to wait for. 2266 */ 2267 int ShClTransferWaitForStatus(PSHCLTRANSFER pTransfer, RTMSINTERVAL msTimeout, SHCLTRANSFERSTATUS enmStatus) 2268 { 2269 AssertPtrReturn(pTransfer, VERR_INVALID_POINTER); 2270 2271 int rc = VINF_SUCCESS; 2272 2273 uint64_t const tsStartMs = RTTimeMilliTS(); 2274 uint64_t msLeft = msTimeout; 2275 for (;;) 2276 { 2277 SHCLTRANSFERSTATUS enmCurStatus; 2278 rc = shClTransferWaitForStatusChangeInternal(pTransfer, msLeft, &enmCurStatus); 2279 if (RT_FAILURE(rc)) 2280 break; 2281 2282 if (enmCurStatus == enmStatus) 2283 break; 2284 2285 msLeft -= RT_MIN(msLeft, RTTimeMilliTS() - tsStartMs); 2286 if (msLeft == 0) 2287 { 2288 rc = VERR_TIMEOUT; 2289 break; 2290 } 2291 } 2292 2293 LogFlowFuncLeaveRC(rc); 2294 return rc; 2295 } 2296 2118 2297 2119 2298 /********************************************************************************************************************************* … … 2158 2337 if (RT_SUCCESS(rc)) 2159 2338 { 2160 RTListInit(&pTransferCtx->List); 2161 2162 pTransferCtx->cTransfers = 0; 2163 pTransferCtx->cRunning = 0; 2164 pTransferCtx->cMaxRunning = 64; /** @todo Make this configurable? */ 2165 2166 RT_ZERO(pTransferCtx->bmTransferIds); 2167 2168 ShClTransferCtxReset(pTransferCtx); 2339 rc = RTSemEventCreate(&pTransferCtx->ChangedEvent); 2340 if (RT_SUCCESS(rc)) 2341 { 2342 RT_ZERO(pTransferCtx->ChangedEventData); 2343 2344 RTListInit(&pTransferCtx->List); 2345 2346 pTransferCtx->cTransfers = 0; 2347 pTransferCtx->cRunning = 0; 2348 pTransferCtx->cMaxRunning = 64; /** @todo Make this configurable? */ 2349 2350 RT_ZERO(pTransferCtx->bmTransferIds); 2351 2352 ShClTransferCtxReset(pTransferCtx); 2353 } 2169 2354 } 2170 2355 … … 2201 2386 2202 2387 shClTransferCtxUnlock(pTransferCtx); 2388 2389 RTSemEventDestroy(pTransferCtx->ChangedEvent); 2390 pTransferCtx->ChangedEvent = NIL_RTSEMEVENT; 2203 2391 2204 2392 if (RTCritSectIsInitialized(&pTransferCtx->CritSect)) … … 2231 2419 2232 2420 /** 2421 * Signals a change event. 2422 * 2423 * @returns VBox status code. 2424 * @param pTransferCtx Transfer context to return transfer for. 2425 * @param fRegistered Whether a transfer got registered or unregistered. 2426 * @param pTransfer Transfer bound to the event. 2427 */ 2428 static int shClTransferCtxSignal(PSHCLTRANSFERCTX pTransferCtx, bool fRegistered, PSHCLTRANSFER pTransfer) 2429 { 2430 Assert(RTCritSectIsOwner(&pTransferCtx->CritSect)); 2431 2432 LogFlowFunc(("fRegistered=%RTbool, pTransfer=%p\n", fRegistered, pTransfer)); 2433 2434 pTransferCtx->ChangedEventData.fRegistered = fRegistered; 2435 pTransferCtx->ChangedEventData.pTransfer = pTransfer; 2436 2437 return RTSemEventSignal(pTransferCtx->ChangedEvent); 2438 } 2439 2440 /** 2233 2441 * Returns a specific clipboard transfer, internal version. 2442 * 2443 * @returns Clipboard transfer found, or NULL if not found. 2444 * @param pTransferCtx Transfer context to return transfer for. 2445 * @param idTransfer ID of the transfer to return. 2446 * 2447 * @note Caller needs to take critical section. 2448 */ 2449 static PSHCLTRANSFER shClTransferCtxGetTransferByIdInternal(PSHCLTRANSFERCTX pTransferCtx, SHCLTRANSFERID idTransfer) 2450 { 2451 Assert(RTCritSectIsOwner(&pTransferCtx->CritSect)); 2452 2453 PSHCLTRANSFER pTransfer; 2454 RTListForEach(&pTransferCtx->List, pTransfer, SHCLTRANSFER, Node) /** @todo Slow, but works for now. */ 2455 { 2456 if (pTransfer->State.uID == idTransfer) 2457 return pTransfer; 2458 } 2459 2460 return NULL; 2461 } 2462 2463 /** 2464 * Returns a specific clipboard transfer by index, internal version. 2465 * 2466 * @returns Clipboard transfer found, or NULL if not found. 2467 * @param pTransferCtx Transfer context to return transfer for. 2468 * @param uIdx Index of the transfer to return. 2469 * 2470 * @note Caller needs to take critical section. 2471 */ 2472 static PSHCLTRANSFER shClTransferCtxGetTransferByIndexInternal(PSHCLTRANSFERCTX pTransferCtx, uint32_t uIdx) 2473 { 2474 Assert(RTCritSectIsOwner(&pTransferCtx->CritSect)); 2475 2476 uint32_t idx = 0; 2477 2478 PSHCLTRANSFER pTransfer; 2479 RTListForEach(&pTransferCtx->List, pTransfer, SHCLTRANSFER, Node) /** @todo Slow, but works for now. */ 2480 { 2481 if (uIdx == idx) 2482 return pTransfer; 2483 idx++; 2484 } 2485 2486 return NULL; 2487 } 2488 2489 /** 2490 * Returns a clipboard transfer for a specific transfer ID. 2234 2491 * 2235 2492 * @returns Clipboard transfer found, or NULL if not found. 2236 2493 * @param pTransferCtx Transfer context to return transfer for. 2237 2494 * @param uID ID of the transfer to return. 2238 *2239 * @note Caller needs to take critical section.2240 */2241 static PSHCLTRANSFER shClTransferCtxGetTransferByIdInternal(PSHCLTRANSFERCTX pTransferCtx, uint32_t uID)2242 {2243 Assert(RTCritSectIsOwner(&pTransferCtx->CritSect));2244 2245 PSHCLTRANSFER pTransfer;2246 RTListForEach(&pTransferCtx->List, pTransfer, SHCLTRANSFER, Node) /** @todo Slow, but works for now. */2247 {2248 if (pTransfer->State.uID == uID)2249 return pTransfer;2250 }2251 2252 return NULL;2253 }2254 2255 /**2256 * Returns a specific clipboard transfer by index, internal version.2257 *2258 * @returns Clipboard transfer found, or NULL if not found.2259 * @param pTransferCtx Transfer context to return transfer for.2260 * @param uIdx Index of the transfer to return.2261 *2262 * @note Caller needs to take critical section.2263 */2264 static PSHCLTRANSFER shClTransferCtxGetTransferByIndexInternal(PSHCLTRANSFERCTX pTransferCtx, uint32_t uIdx)2265 {2266 Assert(RTCritSectIsOwner(&pTransferCtx->CritSect));2267 2268 uint32_t idx = 0;2269 2270 PSHCLTRANSFER pTransfer;2271 RTListForEach(&pTransferCtx->List, pTransfer, SHCLTRANSFER, Node) /** @todo Slow, but works for now. */2272 {2273 if (uIdx == idx)2274 return pTransfer;2275 idx++;2276 }2277 2278 return NULL;2279 }2280 2281 /**2282 * Returns a clipboard transfer for a specific transfer ID.2283 *2284 * @returns Clipboard transfer found, or NULL if not found.2285 * @param pTransferCtx Transfer context to return transfer for.2286 * @param uID ID of the transfer to return.2287 2495 */ 2288 2496 PSHCLTRANSFER ShClTransferCtxGetTransferById(PSHCLTRANSFERCTX pTransferCtx, uint32_t uID) … … 2315 2523 } 2316 2524 2525 2526 /** 2527 * Returns the last clipboard transfer registered. 2528 * 2529 * @returns Clipboard transfer found, or NULL if not found. 2530 * @param pTransferCtx Transfer context to return transfer for. 2531 */ 2532 PSHCLTRANSFER ShClTransferCtxGetTransferLast(PSHCLTRANSFERCTX pTransferCtx) 2533 { 2534 shClTransferCtxLock(pTransferCtx); 2535 2536 PSHCLTRANSFER const pTransfer = RTListGetLast(&pTransferCtx->List, SHCLTRANSFER, Node); 2537 2538 shClTransferCtxUnlock(pTransferCtx); 2539 2540 return pTransfer; 2541 } 2542 2317 2543 /** 2318 2544 * Returns the number of running clipboard transfers for a given transfer context. … … 2353 2579 } 2354 2580 2355 /** 2356 * Registers a clipboard transfer with a transfer context, i.e. allocates a transfer ID. 2357 * 2358 * @return VBox status code. 2359 * @retval VERR_SHCLPB_MAX_TRANSFERS_REACHED if the maximum of concurrent transfers 2360 * is reached. 2361 * @param pTransferCtx Transfer context to register transfer to. 2362 * @param pTransfer Transfer to register. The context takes ownership of the transfer on success. 2363 * @param pidTransfer Where to return the transfer ID on success. Optional. 2364 */ 2365 int ShClTransferCtxTransferRegister(PSHCLTRANSFERCTX pTransferCtx, PSHCLTRANSFER pTransfer, SHCLTRANSFERID *pidTransfer) 2366 { 2367 AssertPtrReturn(pTransferCtx, VERR_INVALID_POINTER); 2368 AssertPtrReturn(pTransfer, VERR_INVALID_POINTER); 2369 /* pidTransfer is optional. */ 2370 2371 shClTransferCtxLock(pTransferCtx); 2372 2581 static int shClTransferCreateIDInternal(PSHCLTRANSFERCTX pTransferCtx, SHCLTRANSFERID *pidTransfer) 2582 { 2373 2583 /* 2374 2584 * Pick a random bit as starting point. If it's in use, search forward … … 2393 2603 { 2394 2604 LogFunc(("Maximum number of transfers reached (%RU16 transfers)\n", pTransferCtx->cTransfers)); 2395 shClTransferCtxUnlock(pTransferCtx);2396 2605 return VERR_SHCLPB_MAX_TRANSFERS_REACHED; 2397 2606 } 2607 2608 *pidTransfer = idTransfer; 2609 2610 return VINF_SUCCESS; 2611 } 2612 2613 /** 2614 * Creates a new transfer ID for a given transfer context. 2615 * 2616 * @returns VBox status code. 2617 * @retval VERR_SHCLPB_MAX_TRANSFERS_REACHED if the maximum of concurrent transfers is reached. 2618 * @param pTransferCtx Transfer context to create transfer ID for. 2619 * @param pidTransfer Where to return the transfer ID on success. 2620 */ 2621 int ShClTransferCtxCreateId(PSHCLTRANSFERCTX pTransferCtx, PSHCLTRANSFERID pidTransfer) 2622 { 2623 AssertPtrReturn(pTransferCtx, VERR_INVALID_POINTER); 2624 AssertPtrReturn(pidTransfer, VERR_INVALID_POINTER); 2625 2626 shClTransferCtxLock(pTransferCtx); 2627 2628 int rc = shClTransferCreateIDInternal(pTransferCtx, pidTransfer); 2629 2630 shClTransferCtxUnlock(pTransferCtx); 2631 2632 return rc; 2633 } 2634 2635 /** 2636 * Registers a clipboard transfer with a new transfer ID. 2637 * 2638 * @return VBox status code. 2639 * @retval VERR_SHCLPB_MAX_TRANSFERS_REACHED if the maximum of concurrent transfers is reached. 2640 * @param pTransferCtx Transfer context to register transfer to. 2641 * @param pTransfer Transfer to register. The context takes ownership of the transfer on success. 2642 * @param idTransfer Transfer ID to use for registering the given transfer. 2643 */ 2644 static int shClTransferCtxTransferRegisterExInternal(PSHCLTRANSFERCTX pTransferCtx, PSHCLTRANSFER pTransfer, SHCLTRANSFERID idTransfer) 2645 { 2646 AssertPtrReturn(pTransferCtx, VERR_INVALID_POINTER); 2647 AssertPtrReturn(pTransfer, VERR_INVALID_POINTER); 2648 Assert(idTransfer != NIL_SHCLTRANSFERID); 2649 2650 shClTransferCtxLock(pTransferCtx); 2398 2651 2399 2652 pTransfer->State.uID = idTransfer; … … 2410 2663 pTransfer->Callbacks.pfnOnRegistered(&pTransfer->CallbackCtx, pTransferCtx); 2411 2664 2412 if (pidTransfer)2413 *pidTransfer = idTransfer;2414 2415 2665 LogFlowFuncLeaveRC(VINF_SUCCESS); 2416 2666 return VINF_SUCCESS; 2667 } 2668 2669 /** 2670 * Registers a clipboard transfer with a transfer context, i.e. allocates a transfer ID. 2671 * 2672 * @return VBox status code. 2673 * @retval VERR_SHCLPB_MAX_TRANSFERS_REACHED if the maximum of concurrent transfers for this context has been reached. 2674 * @param pTransferCtx Transfer context to register transfer to. 2675 * @param pTransfer Transfer to register. The context takes ownership of the transfer on success. 2676 * @param pidTransfer Where to return the transfer ID on success. Optional. 2677 */ 2678 int ShClTransferCtxRegister(PSHCLTRANSFERCTX pTransferCtx, PSHCLTRANSFER pTransfer, PSHCLTRANSFERID pidTransfer) 2679 { 2680 AssertPtrReturn(pTransferCtx, VERR_INVALID_POINTER); 2681 AssertPtrReturn(pTransfer, VERR_INVALID_POINTER); 2682 2683 shClTransferCtxLock(pTransferCtx); 2684 2685 SHCLTRANSFERID idTransfer; 2686 int rc = shClTransferCreateIDInternal(pTransferCtx, &idTransfer); 2687 if (RT_SUCCESS(rc)) 2688 { 2689 rc = shClTransferCtxTransferRegisterExInternal(pTransferCtx, pTransfer, idTransfer); 2690 if (RT_SUCCESS(rc)) 2691 { 2692 if (pidTransfer) 2693 *pidTransfer = idTransfer; 2694 } 2695 } 2696 2697 shClTransferCtxUnlock(pTransferCtx); 2698 2699 return rc; 2417 2700 } 2418 2701 … … 2423 2706 * @retval VERR_ALREADY_EXISTS if a transfer with the given ID already exists. 2424 2707 * @retval VERR_SHCLPB_MAX_TRANSFERS_REACHED if the maximum of concurrent transfers for this context has been reached. 2425 * @param pTransferCtx 2708 * @param pTransferCtx Transfer context to register transfer to. 2426 2709 * @param pTransfer Transfer to register. 2427 2710 * @param idTransfer Transfer ID to use for registration. 2428 */ 2429 int ShClTransferCtxTransferRegisterById(PSHCLTRANSFERCTX pTransferCtx, PSHCLTRANSFER pTransfer, SHCLTRANSFERID idTransfer) 2711 * 2712 * @note This function ASSUMES you have created \a idTransfer with ShClTransferCtxCreateId(). 2713 */ 2714 int ShClTransferCtxRegisterById(PSHCLTRANSFERCTX pTransferCtx, PSHCLTRANSFER pTransfer, SHCLTRANSFERID idTransfer) 2430 2715 { 2431 2716 shClTransferCtxLock(pTransferCtx); … … 2433 2718 if (pTransferCtx->cTransfers < VBOX_SHCL_MAX_TRANSFERS - 2 /* First and last are not used */) 2434 2719 { 2435 if (!ASMBitTestAndSet(&pTransferCtx->bmTransferIds[0], idTransfer)) 2436 { 2437 RTListAppend(&pTransferCtx->List, &pTransfer->Node); 2438 2439 pTransfer->State.uID = idTransfer; 2440 2441 shClTransferCtxUnlock(pTransferCtx); 2442 2443 if (pTransfer->Callbacks.pfnOnRegistered) 2444 pTransfer->Callbacks.pfnOnRegistered(&pTransfer->CallbackCtx, pTransferCtx); 2445 2446 shClTransferCtxLock(pTransferCtx); 2447 2448 pTransferCtx->cTransfers++; 2449 2450 LogFunc(("Registered transfer ID %RU16 -- now %RU16 transfers total\n", idTransfer, pTransferCtx->cTransfers)); 2451 2452 shClTransferCtxUnlock(pTransferCtx); 2453 return VINF_SUCCESS; 2454 } 2455 2456 return VERR_ALREADY_EXISTS; 2720 RTListAppend(&pTransferCtx->List, &pTransfer->Node); 2721 2722 shClTransferLock(pTransfer); 2723 2724 pTransfer->State.uID = idTransfer; 2725 2726 shClTransferUnlock(pTransfer); 2727 2728 int rc = shClTransferCtxSignal(pTransferCtx, true /* fRegistered */, pTransfer); 2729 2730 pTransferCtx->cTransfers++; 2731 2732 LogFunc(("Registered transfer ID %RU16 -- now %RU16 transfers total\n", idTransfer, pTransferCtx->cTransfers)); 2733 2734 shClTransferCtxUnlock(pTransferCtx); 2735 2736 if (pTransfer->Callbacks.pfnOnRegistered) 2737 pTransfer->Callbacks.pfnOnRegistered(&pTransfer->CallbackCtx, pTransferCtx); 2738 2739 return rc; 2457 2740 } 2458 2741 … … 2501 2784 * @param idTransfer Transfer ID to unregister. 2502 2785 */ 2503 int ShClTransferCtx TransferUnregisterById(PSHCLTRANSFERCTX pTransferCtx, SHCLTRANSFERID idTransfer)2786 int ShClTransferCtxUnregisterById(PSHCLTRANSFERCTX pTransferCtx, SHCLTRANSFERID idTransfer) 2504 2787 { 2505 2788 AssertPtrReturn(pTransferCtx, VERR_INVALID_POINTER); … … 2509 2792 2510 2793 int rc = VINF_SUCCESS; 2511 AssertMsgStmt(ASMBitTestAndClear(&pTransferCtx->bmTransferIds, idTransfer), ("idTransfer=%#x\n", idTransfer), rc = VERR_NOT_FOUND);2512 2794 2513 2795 LogFlowFunc(("idTransfer=%RU32\n", idTransfer)); 2514 2796 2515 if ( RT_SUCCESS(rc))2797 if (ASMBitTestAndClear(&pTransferCtx->bmTransferIds, idTransfer), ("idTransfer=%#x\n", idTransfer)) 2516 2798 { 2517 2799 PSHCLTRANSFER pTransfer = shClTransferCtxGetTransferByIdInternal(pTransferCtx, idTransfer); 2800 AssertPtr(pTransfer); 2518 2801 if (pTransfer) 2519 2802 { 2520 2803 shclTransferCtxTransferRemoveAndUnregister(pTransferCtx, pTransfer); 2804 2805 rc = shClTransferCtxSignal(pTransferCtx, false /* fRegistered */, pTransfer); 2521 2806 } 2522 else2523 rc = VERR_NOT_FOUND;2524 }2807 } 2808 else 2809 rc = VERR_NOT_FOUND; 2525 2810 2526 2811 shClTransferCtxUnlock(pTransferCtx); 2812 2813 LogFlowFuncLeaveRC(rc); 2814 return rc; 2815 } 2816 2817 /** 2818 * Waits for a transfer context event. 2819 * 2820 * @returns VBox status code. 2821 * @param pTransferCtx Transfer context to wait for. 2822 * @param msTimeout Timeout (in ms) to wait. 2823 * @param pEvent Where to return the event data on success. 2824 */ 2825 static int shClTransferCtxWaitInternal(PSHCLTRANSFERCTX pTransferCtx, RTMSINTERVAL msTimeout, PSHCLTRANSFERCTXEVENT pEvent) 2826 { 2827 LogFlowFunc(("Waiting for transfer context change (%RU32 timeout) ...\n", msTimeout)); 2828 2829 int rc = RTSemEventWait(pTransferCtx->ChangedEvent, msTimeout); 2830 if (RT_SUCCESS(rc)) 2831 { 2832 shClTransferCtxLock(pTransferCtx); 2833 2834 memcpy(pEvent, &pTransferCtx->ChangedEventData, sizeof(SHCLTRANSFERCTXEVENT)); 2835 2836 shClTransferCtxUnlock(pTransferCtx); 2837 } 2838 2839 LogFlowFuncLeaveRC(rc); 2840 return rc; 2841 } 2842 2843 /** 2844 * Waits for transfer to be (un-)registered. 2845 * 2846 * @returns VBox status code. 2847 * @param pTransferCtx Transfer context to wait for. 2848 * @param msTimeout Timeout (in ms) to wait. 2849 * @param fRegister Pass \c true for registering, or \c false for unregistering a transfer. 2850 * @param idTransfer Transfer ID to wait for. 2851 * Pass NIL_SHCLTRANSFERID for any transfer. 2852 * @param ppTransfer Where to return the transfer being (un-)registered. Optional and can be NULL. 2853 */ 2854 int ShClTransferCtxWait(PSHCLTRANSFERCTX pTransferCtx, RTMSINTERVAL msTimeout, bool fRegister, SHCLTRANSFERID idTransfer, 2855 PSHCLTRANSFER *ppTransfer) 2856 { 2857 AssertPtrReturn(pTransferCtx, VERR_INVALID_POINTER); 2858 2859 int rc = VERR_TIMEOUT; 2860 2861 uint64_t const tsStartMs = RTTimeMilliTS(); 2862 uint64_t msLeft = msTimeout; 2863 for (;;) 2864 { 2865 SHCLTRANSFERCTXEVENT Event; 2866 rc = shClTransferCtxWaitInternal(pTransferCtx, msLeft, &Event); 2867 if (RT_FAILURE(rc)) 2868 break; 2869 2870 shClTransferCtxLock(pTransferCtx); 2871 2872 if (Event.fRegistered == fRegister) 2873 { 2874 if ( idTransfer != NIL_SHCLTRANSFERID 2875 && Event.pTransfer 2876 && ShClTransferGetID(Event.pTransfer) == idTransfer) 2877 { 2878 if (ppTransfer) 2879 *ppTransfer = Event.pTransfer; 2880 rc = VINF_SUCCESS; 2881 } 2882 } 2883 2884 shClTransferCtxUnlock(pTransferCtx); 2885 2886 if (RT_SUCCESS(rc)) 2887 break; 2888 2889 msLeft -= RT_MIN(msLeft, RTTimeMilliTS() - tsStartMs); 2890 if (msLeft == 0) 2891 break; 2892 } 2527 2893 2528 2894 LogFlowFuncLeaveRC(rc); … … 2584 2950 * @param pTransferCtx Transfer context to determine value for. 2585 2951 */ 2586 bool ShClTransferCtx TransfersMaximumReached(PSHCLTRANSFERCTX pTransferCtx)2952 bool ShClTransferCtxIsMaximumReached(PSHCLTRANSFERCTX pTransferCtx) 2587 2953 { 2588 2954 AssertPtrReturn(pTransferCtx, true); … … 2652 3018 2653 3019 /** 2654 * Queries Shared Clipboardfile system information from a given path.3020 * Queries local file system information from a given path. 2655 3021 * 2656 3022 * @returns VBox status code. … … 2658 3024 * @param pObjInfo Where to return the queried file system information on success. 2659 3025 */ 2660 int ShClFsObjInfoQuery (const char *pszPath, PSHCLFSOBJINFO pObjInfo)3026 int ShClFsObjInfoQueryLocal(const char *pszPath, PSHCLFSOBJINFO pObjInfo) 2661 3027 { 2662 3028 RTFSOBJINFO objInfo; … … 2685 3051 { 2686 3052 RT_CASE_RET_STR(SHCLTRANSFERSTATUS_NONE); 3053 RT_CASE_RET_STR(SHCLTRANSFERSTATUS_REQUESTED); 2687 3054 RT_CASE_RET_STR(SHCLTRANSFERSTATUS_INITIALIZED); 2688 3055 RT_CASE_RET_STR(SHCLTRANSFERSTATUS_UNINITIALIZED); … … 2753 3120 return rc; 2754 3121 } 3122 -
trunk/src/VBox/GuestHost/SharedClipboard/clipboard-win.cpp
r100206 r100367 1070 1070 { 1071 1071 if (RT_SUCCESS(rc)) 1072 pObj->SetCallbacks(pCallbacks);1073 1074 if (RT_SUCCESS(rc))1075 1072 pWinCtx->pDataObjInFlight = pObj; 1076 1073 } -
trunk/src/VBox/GuestHost/SharedClipboard/clipboard-x11.cpp
r100256 r100367 440 440 pCtx->idxFmtHTML, g_aFormats[pCtx->idxFmtHTML].pcszAtom)); 441 441 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 442 Log FlowFunc((", idxFmtURI=%u ('%s')", pCtx->idxFmtURI, g_aFormats[pCtx->idxFmtURI].pcszAtom));443 #endif 444 Log Flow((" -> vboxFmt=%#x\n", vboxFmt));442 Log((", idxFmtURI=%u ('%s')", pCtx->idxFmtURI, g_aFormats[pCtx->idxFmtURI].pcszAtom)); 443 #endif 444 Log((" -> vboxFmt=%#x\n", vboxFmt)); 445 445 446 446 #ifdef LOG_ENABLED … … 1210 1210 } 1211 1211 1212 /* Init clipboard cache. */ 1213 ShClCacheInit(&pCtx->Cache); 1214 1212 1215 /* Install given callbacks. */ 1213 1216 shClX11SetCallbacksInternal(pCtx, pCallbacks); … … 1250 1253 1251 1254 LogFlowFunc(("pCtx=%p\n", pCtx)); 1255 1256 /* Destroy clipboard cache. */ 1257 ShClCacheDestroy(&pCtx->Cache); 1252 1258 1253 1259 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS_HTTP … … 1502 1508 #endif 1503 1509 1504 LogFlowFunc(("pCtx=%p, uFmt=%#x\n", pCtx, uFmt));1505 1506 1510 int rc = VINF_SUCCESS; 1507 1511 … … 1509 1513 uint32_t cb = 0; 1510 1514 1511 if (uFmt == VBOX_SHCL_FMT_UNICODETEXT) 1512 { 1513 if (pCtx->pvUnicodeCache == NULL) /** @todo r=andy Using string cache here? */ 1514 rc = pCtx->Callbacks.pfnOnRequestDataFromSource(pCtx->pFrontend, uFmt, &pCtx->pvUnicodeCache, &pCtx->cbUnicodeCache, 1515 NULL /* pvUser */); 1516 if ( RT_SUCCESS(rc) 1517 /* Catch misbehaving callbacks. */ 1518 && pCtx->pvUnicodeCache 1519 && pCtx->cbUnicodeCache) 1520 { 1521 pv = RTMemDup(pCtx->pvUnicodeCache, pCtx->cbUnicodeCache); 1515 PSHCLCACHEENTRY pCacheEntry = ShClCacheGet(&pCtx->Cache, uFmt); 1516 if (!pCacheEntry) /* Cache miss */ 1517 { 1518 rc = pCtx->Callbacks.pfnOnRequestDataFromSource(pCtx->pFrontend, uFmt, &pv, &cb, 1519 NULL /* pvUser */); 1520 if (RT_SUCCESS(rc)) 1521 rc = ShClCacheSet(&pCtx->Cache, uFmt, pv, cb); 1522 } 1523 else /* Cache hit */ 1524 { 1525 void *pvCache = NULL; 1526 size_t cbCache = 0; 1527 ShClCacheEntryGet(pCacheEntry, &pvCache, &cbCache); 1528 if ( pvCache 1529 && cbCache) 1530 { 1531 pv = RTMemDup(pvCache, cbCache); 1522 1532 if (pv) 1523 cb = pCtx->cbUnicodeCache; 1533 { 1534 cb = cbCache; 1535 } 1524 1536 else 1525 1526 } 1527 } 1528 else 1529 rc = pCtx->Callbacks.pfnOnRequestDataFromSource(pCtx->pFrontend, uFmt, &pv, &cb, NULL /* pvUser */);1530 1531 /* Safey net in case the callbacks above misbehave1537 rc = VERR_NO_MEMORY; 1538 } 1539 } 1540 1541 LogFlowFunc(("pCtx=%p, uFmt=%#x -> Cache %s\n", pCtx, uFmt, pCacheEntry ? "HIT" : "MISS")); 1542 1543 /* Safey net in case the stuff above misbehaves 1532 1544 * (must return VERR_NO_DATA if no data available). */ 1533 1545 if ( RT_SUCCESS(rc) … … 1774 1786 } 1775 1787 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 1776 else if (fmtX11 == SHCLX11FMT_URI_LIST) 1788 else if ( fmtX11 == SHCLX11FMT_URI_LIST 1789 || fmtX11 == SHCLX11FMT_URI_LIST_GNOME_COPIED_FILES 1790 /** @todo BUGBUG Not sure about the following ones; test those. */ 1791 || fmtX11 == SHCLX11FMT_URI_LIST_MATE_COPIED_FILES 1792 || fmtX11 == SHCLX11FMT_URI_LIST_NAUTILUS_CLIPBOARD 1793 || fmtX11 == SHCLX11FMT_URI_LIST_KDE_CUTSELECTION) 1777 1794 { 1778 1795 if (pCtx->vboxFormats & VBOX_SHCL_FMT_URI_LIST) … … 1781 1798 if (RT_SUCCESS(rc)) 1782 1799 { 1800 if ( fmtX11 == SHCLX11FMT_URI_LIST_GNOME_COPIED_FILES 1801 /** @todo BUGBUG Ditto, see above. */ 1802 || fmtX11 == SHCLX11FMT_URI_LIST_MATE_COPIED_FILES 1803 || fmtX11 == SHCLX11FMT_URI_LIST_NAUTILUS_CLIPBOARD 1804 || fmtX11 == SHCLX11FMT_URI_LIST_KDE_CUTSELECTION) 1805 { 1806 /* Note: There must be *no* final new line ('\n') at the end, otherwise Nautilus will crash! */ 1807 char *pszData = NULL; 1808 1809 RTStrAPrintf(&pszData, "copy\n%s", (const char *)pv); 1810 1811 cb = strlen(pszData); 1812 pv = pszData; 1813 } 1814 else /* SHCLX11FMT_URI_LIST -> String only, w/o any special formatting. */ 1815 { 1816 char *pszData = NULL; 1817 RTStrAPrintf(&pszData, "%s\n", (const char *)pv); 1818 1819 cb = strlen(pszData) + 1; 1820 pv = pszData; 1821 } 1822 1823 LogFlowFunc(("Data:\n%.*RhXd\n", cb, pv)); 1824 1783 1825 void *pvDst = (void *)XtMalloc(cb); 1784 1826 if (pvDst) … … 1794 1836 rc = VERR_NO_MEMORY; 1795 1837 } 1838 1839 RTMemFree(pv); 1840 pv = NULL; 1796 1841 } 1797 1842 /* else not supported yet. */ … … 1876 1921 1877 1922 /** 1878 * Invalidates the local c ache of the data in the VBox clipboard.1923 * Invalidates the local clipboard cache. 1879 1924 * 1880 1925 * @param pCtx The X11 clipboard context to use. … … 1882 1927 static void clipInvalidateClipboardCache(PSHCLX11CTX pCtx) 1883 1928 { 1884 if (pCtx->pvUnicodeCache != NULL) 1885 { 1886 RTMemFree(pCtx->pvUnicodeCache); 1887 pCtx->pvUnicodeCache = NULL; 1888 } 1929 LogFlowFuncEnter(); 1930 1931 ShClCacheInvalidate(&pCtx->Cache); 1889 1932 } 1890 1933 … … 2032 2075 *pcbList = 0; 2033 2076 2077 LogFlowFunc(("Data:\n%.*RhXd\n", cbData, pvData)); 2078 2034 2079 char **papszStrings; 2035 2080 size_t cStrings; … … 2040 2085 { 2041 2086 const char *pszString = papszStrings[i]; 2087 LogRel2(("Shared Clipboard: Received entry #%zu from X11: '%s'\n", i, pszString)); 2042 2088 rc = RTStrAAppend(ppszList, pszString); 2043 2089 if (RT_FAILURE(rc)) … … 2236 2282 { 2237 2283 case SHCLX11FMT_URI_LIST: 2284 RT_FALL_THROUGH(); 2285 case SHCLX11FMT_URI_LIST_GNOME_COPIED_FILES: 2286 RT_FALL_THROUGH(); 2287 case SHCLX11FMT_URI_LIST_MATE_COPIED_FILES: 2288 RT_FALL_THROUGH(); 2289 case SHCLX11FMT_URI_LIST_NAUTILUS_CLIPBOARD: 2290 RT_FALL_THROUGH(); 2291 case SHCLX11FMT_URI_LIST_KDE_CUTSELECTION: 2238 2292 { 2239 RTCList<RTCString> lstRootEntries;2240 2293 rc = ShClX11TransferConvertDataToStringList((const char *)pvSrc, cbSrc, (char **)&pvDst, &cbDst); 2241 if (RT_SUCCESS(rc))2242 {2243 #if 02244 for (size_t i = 0; i < lstRootEntries.size(); ++i)2245 {2246 char *pszEntry = RTUriFilePath(lstRootEntries.at(i).c_str())2247 AssertPtrBreakStmt(pszEntry, VERR_INVALID_PARAMETER);2248 2249 LogFlowFunc(("Entry '%s' -> ", (char *)pszEntry));2250 2251 rc = RTStrAAppend((char **)&pvDst, "http://localhost");2252 AssertRCBreakStmt(rc, VERR_NO_MEMORY);2253 cbDst += (uint32_t)strlen(pszEntry);2254 2255 2256 2257 /** @todo BUGBUG Fix port! */2258 /** @todo Add port + UUID (virtual path). */2259 2260 rc = RTStrAAppend((char **)&pvDst, pszEntry);2261 AssertRCBreakStmt(rc, VERR_NO_MEMORY);2262 cbDst += (uint32_t)strlen(pszEntry);2263 2264 LogFlowFunc(("'%s'\n", (char *)pvDst));2265 2266 rc = RTStrAAppend((char **)&pvDst, SHCL_TRANSFER_URI_LIST_SEP_STR);2267 AssertRCBreakStmt(rc, VERR_NO_MEMORY);2268 cbDst += (uint32_t)strlen(SHCL_TRANSFER_URI_LIST_SEP_STR);2269 2270 RTStrFree(pszEntry);2271 }2272 2273 if (cbDst)2274 cbDst++; /* Include final (zero) termination. */2275 #endif2276 2277 2278 }2279 2294 break; 2280 2295 } … … 2282 2297 default: 2283 2298 { 2284 rc = VERR_INVALID_PARAMETER;2299 AssertFailedStmt(rc = VERR_NOT_SUPPORTED); /* Missing code? */ 2285 2300 break; 2286 2301 } -
trunk/src/VBox/GuestHost/SharedClipboard/testcase/tstClipboardHttpServer.cpp
r100242 r100367 198 198 /* Query the local transfer provider. */ 199 199 SHCLTXPROVIDER Provider; 200 RTTESTI_CHECK( VBClTransferProviderLocalQueryInterface(&Provider) != NULL);200 RTTESTI_CHECK(ShClTransferProviderLocalQueryInterface(&Provider) != NULL); 201 201 202 202 /* Parse options again, but this time we only fetch all files we want to serve. … … 212 212 { 213 213 PSHCLTRANSFER pTx; 214 RTTEST_CHECK_RC_OK(hTest, ShClTransferCreate( &pTx));214 RTTEST_CHECK_RC_OK(hTest, ShClTransferCreate(SHCLTRANSFERDIR_TO_REMOTE, SHCLSOURCE_LOCAL, &pTx)); 215 215 RTTEST_CHECK_RC_OK(hTest, ShClTransferSetProvider(pTx, &Provider)); 216 RTTEST_CHECK_RC_OK(hTest, ShClTransferInit(pTx , SHCLTRANSFERDIR_TO_REMOTE, SHCLSOURCE_LOCAL));216 RTTEST_CHECK_RC_OK(hTest, ShClTransferInit(pTx)); 217 217 RTTEST_CHECK_RC_OK(hTest, ShClTransferRootsInitFromFile(pTx, ValueUnion.psz)); 218 RTTEST_CHECK_RC_OK(hTest, ShClTransferCtx TransferRegister(&TxCtx, pTx, NULL));218 RTTEST_CHECK_RC_OK(hTest, ShClTransferCtxRegister(&TxCtx, pTx, NULL)); 219 219 RTTEST_CHECK_RC_OK(hTest, ShClTransferHttpServerRegisterTransfer(&HttpSrv, pTx)); 220 220 break; -
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-internal.h
r100205 r100367 282 282 extern SHCLEXTSTATE g_ExtState; 283 283 284 int shClSvcSetSource(PSHCLCLIENT pClient, SHCLSOURCE enmSource);285 286 284 void shClSvcMsgQueueReset(PSHCLCLIENT pClient); 287 285 PSHCLCLIENTMSG shClSvcMsgAlloc(PSHCLCLIENT pClient, uint32_t uMsg, uint32_t cParms); … … 302 300 int shClSvcClientWakeup(PSHCLCLIENT pClient); 303 301 304 # ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS305 int shClSvcTransferModeSet(uint32_t fMode);306 int shClSvcTransferInit(PSHCLCLIENT pClient, SHCLTRANSFERDIR enmDir, SHCLSOURCE enmSource, PSHCLTRANSFER *ppTransfer);307 int shClSvcTransferStart(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer);308 int shClSvcTransferStop(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer, bool fWaitForGuest);309 bool shClSvcTransferMsgIsAllowed(uint32_t uMode, uint32_t uMsg);310 void shClSvcClientTransfersReset(PSHCLCLIENT pClient);311 #endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */312 313 302 /** @name Service functions, accessible by the backends. 314 303 * Locking is between the (host) service thread and the platform-dependent (window) thread. … … 316 305 */ 317 306 int ShClSvcReadDataFromGuestAsync(PSHCLCLIENT pClient, SHCLFORMATS fFormats, PSHCLEVENT *ppEvent); 307 int ShClSvcReadDataFromGuest(PSHCLCLIENT pClient, SHCLFORMAT uFmt, void **ppv, uint32_t *pcb); 318 308 int ShClSvcGuestDataSignal(PSHCLCLIENT pClient, PSHCLCLIENTCMDCTX pCmdCtx, SHCLFORMAT uFormat, void *pvData, uint32_t cbData); 319 309 int ShClSvcHostReportFormats(PSHCLCLIENT pClient, SHCLFORMATS fFormats); … … 451 441 */ 452 442 /** 453 * Called after a transfer got created.443 * Called before a transfer gets destroyed. 454 444 * 455 445 * @returns VBox status code. 456 446 * @param pBackend Shared Clipboard backend to use. 457 447 * @param pClient Shared Clipboard client context. 458 * @param pTransfer Shared Clipboard transfer created.459 */ 460 int ShClBackendTransfer Create(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer);461 /** 462 * Called before a transfer gets destroyed.448 * @param pTransfer Shared Clipboard transfer to destroy. 449 */ 450 int ShClBackendTransferDestroy(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer); 451 /** 452 * Called after a transfer status got processed. 463 453 * 464 454 * @returns VBox status code. 465 455 * @param pBackend Shared Clipboard backend to use. 466 456 * @param pClient Shared Clipboard client context. 467 * @param pTransfer Shared Clipboard transfer to destroy. 468 */ 469 int ShClBackendTransferDestroy(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer); 470 /** 471 * Called when getting (determining) the transfer roots on the host side. 457 * @param pTransfer Shared Clipboard transfer to process status for. 458 * @param enmSource Transfer source which issues the reply. 459 * @param enmStatus Transfer status. 460 * @param rcStatus Status code (IPRT-style). Depends on \a enmStatus set. 461 */ 462 int ShClBackendTransferHandleStatusReply(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer, SHCLSOURCE enmSource, SHCLTRANSFERSTATUS enmStatus, int rcStatus); 463 /** 464 * Called when the guest wants to read the transfer roots. 472 465 * 473 466 * @returns VBox status code. … … 476 469 * @param pTransfer Shared Clipboard transfer to get roots for. 477 470 */ 478 int ShClBackendTransfer GetRoots(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer);471 int ShClBackendTransferHGRootListRead(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer); 479 472 /** @} */ 480 473 #endif … … 497 490 498 491 int shClSvcTransferIfaceRootsGet(PSHCLTXPROVIDERCTX pCtx, PSHCLLIST pRootList); 499 int shClSvcTransferIface ListOpen(PSHCLTXPROVIDERCTX pCtx, PSHCLLISTOPENPARMS pOpenParms, PSHCLLISTHANDLE phList);500 int shClSvcTransferIface ListClose(PSHCLTXPROVIDERCTX pCtx, SHCLLISTHANDLE hList);501 int shClSvcTransferIface ListHdrRead(PSHCLTXPROVIDERCTX pCtx, SHCLLISTHANDLE hList, PSHCLLISTHDR pListHdr);502 int shClSvcTransferIface ListHdrWrite(PSHCLTXPROVIDERCTX pCtx, SHCLLISTHANDLE hList, PSHCLLISTHDR pListHdr);503 int shClSvcTransferIface ListEntryRead(PSHCLTXPROVIDERCTX pCtx, SHCLLISTHANDLE hList, PSHCLLISTENTRY pListEntry);504 int shClSvcTransferIface ListEntryWrite(PSHCLTXPROVIDERCTX pCtx, SHCLLISTHANDLE hList, PSHCLLISTENTRY pListEntry);505 506 int shClSvcTransferIface ObjOpen(PSHCLTXPROVIDERCTX pCtx, PSHCLOBJOPENCREATEPARMS pCreateParms,492 int shClSvcTransferIfaceGHListOpen(PSHCLTXPROVIDERCTX pCtx, PSHCLLISTOPENPARMS pOpenParms, PSHCLLISTHANDLE phList); 493 int shClSvcTransferIfaceGHListClose(PSHCLTXPROVIDERCTX pCtx, SHCLLISTHANDLE hList); 494 int shClSvcTransferIfaceGHListHdrRead(PSHCLTXPROVIDERCTX pCtx, SHCLLISTHANDLE hList, PSHCLLISTHDR pListHdr); 495 int shClSvcTransferIfaceHGListHdrWrite(PSHCLTXPROVIDERCTX pCtx, SHCLLISTHANDLE hList, PSHCLLISTHDR pListHdr); 496 int shClSvcTransferIfaceGHListEntryRead(PSHCLTXPROVIDERCTX pCtx, SHCLLISTHANDLE hList, PSHCLLISTENTRY pListEntry); 497 int shClSvcTransferIfaceHGListEntryWrite(PSHCLTXPROVIDERCTX pCtx, SHCLLISTHANDLE hList, PSHCLLISTENTRY pListEntry); 498 499 int shClSvcTransferIfaceGHObjOpen(PSHCLTXPROVIDERCTX pCtx, PSHCLOBJOPENCREATEPARMS pCreateParms, 507 500 PSHCLOBJHANDLE phObj); 508 int shClSvcTransferIface ObjClose(PSHCLTXPROVIDERCTX pCtx, SHCLOBJHANDLE hObj);509 int shClSvcTransferIface ObjRead(PSHCLTXPROVIDERCTX pCtx, SHCLOBJHANDLE hObj,501 int shClSvcTransferIfaceGHObjClose(PSHCLTXPROVIDERCTX pCtx, SHCLOBJHANDLE hObj); 502 int shClSvcTransferIfaceGHObjRead(PSHCLTXPROVIDERCTX pCtx, SHCLOBJHANDLE hObj, 510 503 void *pvData, uint32_t cbData, uint32_t fFlags, uint32_t *pcbRead); 511 int shClSvcTransferIface ObjWrite(PSHCLTXPROVIDERCTX pCtx, SHCLOBJHANDLE hObj,504 int shClSvcTransferIfaceHGObjWrite(PSHCLTXPROVIDERCTX pCtx, SHCLOBJHANDLE hObj, 512 505 void *pvData, uint32_t cbData, uint32_t fFlags, uint32_t *pcbWritten); 513 506 /** @} */ -
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-transfers.cpp
r100291 r100367 61 61 * Prototypes * 62 62 *********************************************************************************************************************************/ 63 static int shClSvcTransferSetListOpen(uint32_t cParms, VBOXHGCMSVCPARM aParms[], 64 uint64_t idCtx, PSHCLLISTOPENPARMS pOpenParms); 65 static int shClSvcTransferSetListClose(uint32_t cParms, VBOXHGCMSVCPARM aParms[], 66 uint64_t idCtx, SHCLLISTHANDLE hList); 67 68 69 /********************************************************************************************************************************* 70 * Provider implementation * 71 *********************************************************************************************************************************/ 72 73 /** 74 * Resets all transfers of a Shared Clipboard client. 75 * 76 * @param pClient Client to reset transfers for. 77 */ 78 void shClSvcClientTransfersReset(PSHCLCLIENT pClient) 63 static int shClSvcTransferSendStatusAsyncInternal(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer, SHCLTRANSFERSTATUS uStatus, int rcTransfer, PSHCLEVENT *ppEvent); 64 static int shClSvcTransferSetListOpen(uint32_t cParms, VBOXHGCMSVCPARM aParms[], uint64_t idCtx, PSHCLLISTOPENPARMS pOpenParms); 65 static int shClSvcTransferSetListClose(uint32_t cParms, VBOXHGCMSVCPARM aParms[], uint64_t idCtx, SHCLLISTHANDLE hList); 66 67 68 /** 69 * Destroys all transfers of a Shared Clipboard client. 70 * 71 * @param pClient Client to destroy transfers for. 72 */ 73 void shClSvcTransferDestroyAll(PSHCLCLIENT pClient) 79 74 { 80 75 if (!pClient) … … 83 78 LogFlowFuncEnter(); 84 79 85 /* Make sure to let the backend know that all transfers are getting destroyed. */ 80 /* Unregister and destroy all transfers. 81 * Also make sure to let the backend know that all transfers are getting destroyed. */ 86 82 uint32_t uIdx = 0; 87 83 PSHCLTRANSFER pTransfer; 88 84 while ((pTransfer = ShClTransferCtxGetTransferByIndex(&pClient->Transfers.Ctx, uIdx++))) 89 ShClBackendTransferDestroy(pClient->pBackend, pClient, pTransfer); 90 91 ShClTransferCtxDestroy(&pClient->Transfers.Ctx); 85 ShClSvcTransferDestroy(pClient, pTransfer); 86 } 87 88 /** 89 * Reads a root list header from the guest, asynchronous version. 90 * 91 * @returns VBox status code. 92 * @param pClient Client to read from. 93 * @param idTransfer Transfer ID to read root list header for. 94 * @param ppEvent Where to return the event to wait for. 95 * Must be released by the caller with ShClEventRelease(). 96 */ 97 int ShClSvcTransferGHRootListReadHdrAsync(PSHCLCLIENT pClient, SHCLTRANSFERID idTransfer, PSHCLEVENT *ppEvent) 98 { 99 LogFlowFuncEnter(); 100 101 int rc; 102 103 PSHCLCLIENTMSG pMsgHdr = shClSvcMsgAlloc(pClient, VBOX_SHCL_HOST_MSG_TRANSFER_ROOT_LIST_HDR_READ, 104 VBOX_SHCL_CPARMS_ROOT_LIST_HDR_READ_REQ); 105 if (pMsgHdr) 106 { 107 PSHCLEVENT pEvent; 108 rc = ShClEventSourceGenerateAndRegisterEvent(&pClient->EventSrc, &pEvent); 109 if (RT_SUCCESS(rc)) 110 { 111 HGCMSvcSetU64(&pMsgHdr->aParms[0], VBOX_SHCL_CONTEXTID_MAKE(pClient->State.uSessionID, 112 idTransfer, pEvent->idEvent)); 113 HGCMSvcSetU32(&pMsgHdr->aParms[1], 0 /* fRoots */); 114 115 shClSvcClientLock(pClient); 116 117 shClSvcMsgAdd(pClient, pMsgHdr, true /* fAppend */); 118 rc = shClSvcClientWakeup(pClient); 119 120 shClSvcClientUnlock(pClient); 121 122 /* Remove event from list if caller did not request event handle or in case 123 * of failure (in this case caller should not release event). */ 124 if ( RT_FAILURE(rc) 125 || !ppEvent) 126 { 127 ShClEventRelease(pEvent); 128 pEvent = NULL; 129 } 130 else if (ppEvent) 131 *ppEvent = pEvent; 132 } 133 else 134 { 135 shClSvcMsgFree(pClient, pMsgHdr); 136 rc = VERR_SHCLPB_MAX_EVENTS_REACHED; 137 } 138 } 139 else 140 rc = VERR_NO_MEMORY; 141 142 LogFlowFuncLeaveRC(rc); 143 return rc; 144 } 145 146 /** 147 * Reads a root list header from the guest. 148 * 149 * @returns VBox status code. 150 * @param pClient Client to read from. 151 * @param idTransfer Transfer ID to read root list header for. 152 * @param pHdr Where to store the root list header on succeess. 153 */ 154 int ShClSvcTransferGHRootListReadHdr(PSHCLCLIENT pClient, SHCLTRANSFERID idTransfer, PSHCLLISTHDR pHdr) 155 { 156 PSHCLEVENT pEvent; 157 int rc = ShClSvcTransferGHRootListReadHdrAsync(pClient, idTransfer, &pEvent); 158 if (RT_SUCCESS(rc)) 159 { 160 PSHCLEVENTPAYLOAD pPayload; 161 rc = ShClEventWait(pEvent, SHCL_TIMEOUT_DEFAULT_MS, &pPayload); 162 if (RT_SUCCESS(rc)) 163 { 164 Assert(pPayload->cbData == sizeof(SHCLLISTHDR)); 165 166 memcpy(pHdr, (PSHCLLISTHDR)pPayload->pvData, sizeof(SHCLLISTHDR)); 167 168 LogFlowFunc(("cRoots=%RU32, fFeatures=0x%x\n", pHdr->cEntries, pHdr->fFeatures)); 169 170 ShClPayloadFree(pPayload); 171 } 172 173 ShClEventRelease(pEvent); 174 pEvent = NULL; 175 } 176 177 LogFlowFuncLeaveRC(rc); 178 return rc; 179 } 180 181 /** 182 * Reads a root list entry from the guest, asynchronous version. 183 * 184 * @returns VBox status code. 185 * @param pClient Client to read from. 186 * @param idTransfer Transfer ID to read root list header for. 187 * @param idxEntry Index of entry to read. 188 * @param ppEvent Where to return the event to wait for. 189 * Must be released by the caller with ShClEventRelease(). 190 */ 191 int ShClSvcTransferGHRootListReadEntryAsync(PSHCLCLIENT pClient, SHCLTRANSFERID idTransfer, uint64_t idxEntry, 192 PSHCLEVENT *ppEvent) 193 { 194 LogFlowFuncEnter(); 195 196 PSHCLCLIENTMSG pMsgEntry = shClSvcMsgAlloc(pClient, VBOX_SHCL_HOST_MSG_TRANSFER_ROOT_LIST_ENTRY_READ, 197 VBOX_SHCL_CPARMS_ROOT_LIST_ENTRY_READ_REQ); 198 199 PSHCLEVENT pEvent; 200 int rc = ShClEventSourceGenerateAndRegisterEvent(&pClient->EventSrc, &pEvent); 201 if (RT_SUCCESS(rc)) 202 { 203 HGCMSvcSetU64(&pMsgEntry->aParms[0], 204 VBOX_SHCL_CONTEXTID_MAKE(pClient->State.uClientID, idTransfer, pEvent->idEvent)); 205 HGCMSvcSetU32(&pMsgEntry->aParms[1], 0 /* fFeatures */); 206 HGCMSvcSetU64(&pMsgEntry->aParms[2], idxEntry /* uIndex */); 207 208 shClSvcClientLock(pClient); 209 210 shClSvcMsgAdd(pClient, pMsgEntry, true /* fAppend */); 211 rc = shClSvcClientWakeup(pClient); 212 213 shClSvcClientUnlock(pClient); 214 215 /* Remove event from list if caller did not request event handle or in case 216 * of failure (in this case caller should not release event). */ 217 if ( RT_FAILURE(rc) 218 || !ppEvent) 219 { 220 ShClEventRelease(pEvent); 221 pEvent = NULL; 222 } 223 else if (ppEvent) 224 *ppEvent = pEvent; 225 } 226 else 227 rc = VERR_NO_MEMORY; 228 229 LogFlowFuncLeave(); 230 return rc; 231 } 232 233 /** 234 * Reads a root list entry from the guest. 235 * 236 * @returns VBox status code. 237 * @param pClient Client to read from. 238 * @param idTransfer Transfer ID to read root list header for. 239 * @param idxEntry Index of entry to read. 240 * @param ppListEntry Where to return the allocated root list entry. 241 */ 242 int ShClSvcTransferGHRootListReadEntry(PSHCLCLIENT pClient, SHCLTRANSFERID idTransfer, uint64_t idxEntry, 243 PSHCLLISTENTRY *ppListEntry) 244 { 245 AssertPtrReturn(ppListEntry, VERR_INVALID_POINTER); 246 247 PSHCLEVENT pEvent; 248 int rc = ShClSvcTransferGHRootListReadEntryAsync(pClient, idTransfer, idxEntry, &pEvent); 249 if (RT_SUCCESS(rc)) 250 { 251 PSHCLEVENTPAYLOAD pPayload; 252 rc = ShClEventWait(pEvent, SHCL_TIMEOUT_DEFAULT_MS, &pPayload); 253 if (RT_SUCCESS(rc)) 254 { 255 *ppListEntry = (PSHCLLISTENTRY)pPayload->pvData; /* ppLisEntry own pPayload-pvData now. */ 256 257 } 258 259 ShClEventRelease(pEvent); 260 pEvent = NULL; 261 } 262 263 LogFlowFuncLeaveRC(rc); 264 return rc; 92 265 } 93 266 … … 98 271 99 272 /** @copydoc SHCLTXPROVIDERIFACE::pfnRootListRead */ 100 DECLCALLBACK(int) shClSvcTransferIface RootListRead(PSHCLTXPROVIDERCTX pCtx)273 DECLCALLBACK(int) shClSvcTransferIfaceGHRootListRead(PSHCLTXPROVIDERCTX pCtx) 101 274 { 102 275 LogFlowFuncEnter(); … … 105 278 AssertPtr(pClient); 106 279 107 int rc; 108 109 PSHCLCLIENTMSG pMsgHdr = shClSvcMsgAlloc(pClient, VBOX_SHCL_HOST_MSG_TRANSFER_ROOT_LIST_HDR_READ, 110 VBOX_SHCL_CPARMS_ROOT_LIST_HDR_READ_REQ); 111 if (pMsgHdr) 112 { 113 PSHCLEVENT pEvent; 114 rc = ShClEventSourceGenerateAndRegisterEvent(&pClient->EventSrc, &pEvent); 115 if (RT_SUCCESS(rc)) 116 { 117 HGCMSvcSetU64(&pMsgHdr->aParms[0], VBOX_SHCL_CONTEXTID_MAKE(pClient->State.uSessionID, 118 pCtx->pTransfer->State.uID, pEvent->idEvent)); 119 HGCMSvcSetU32(&pMsgHdr->aParms[1], 0 /* fRoots */); 120 121 shClSvcClientLock(pClient); 122 123 shClSvcMsgAdd(pClient, pMsgHdr, true /* fAppend */); 124 rc = shClSvcClientWakeup(pClient); 125 126 shClSvcClientUnlock(pClient); 127 280 SHCLTRANSFERID const idTransfer = ShClTransferGetID(pCtx->pTransfer); 281 282 SHCLLISTHDR Hdr; 283 int rc = ShClSvcTransferGHRootListReadHdr(pClient, idTransfer, &Hdr); 284 if (RT_SUCCESS(rc)) 285 { 286 for (uint64_t i = 0; i < Hdr.cEntries; i++) 287 { 288 PSHCLLISTENTRY pEntry; 289 rc = ShClSvcTransferGHRootListReadEntry(pClient, idTransfer, i, &pEntry); 128 290 if (RT_SUCCESS(rc)) 129 { 130 PSHCLEVENTPAYLOAD pPayloadHdr; 131 rc = ShClEventWait(pEvent, pCtx->pTransfer->uTimeoutMs, &pPayloadHdr); 132 if (RT_SUCCESS(rc)) 133 { 134 PSHCLLISTHDR pRootListHdr = (PSHCLLISTHDR)pPayloadHdr->pvData; 135 Assert(pPayloadHdr->cbData == sizeof(SHCLLISTHDR)); 136 137 LogFlowFunc(("cRoots=%RU32, fFeatures=0x%x\n", pRootListHdr->cEntries, pRootListHdr->fFeatures)); 138 139 for (uint32_t i = 0; i < pRootListHdr->cEntries; i++) 140 { 141 PSHCLCLIENTMSG pMsgEntry = shClSvcMsgAlloc(pClient, VBOX_SHCL_HOST_MSG_TRANSFER_ROOT_LIST_ENTRY_READ, 142 VBOX_SHCL_CPARMS_ROOT_LIST_ENTRY_READ_REQ); 143 144 PSHCLEVENT pEventRootEntry; 145 rc = ShClEventSourceGenerateAndRegisterEvent(&pClient->EventSrc, &pEventRootEntry); 146 if (RT_SUCCESS(rc)) 147 { 148 HGCMSvcSetU64(&pMsgEntry->aParms[0], 149 VBOX_SHCL_CONTEXTID_MAKE(pClient->State.uClientID, 150 pCtx->pTransfer->State.uID, pEventRootEntry->idEvent)); 151 HGCMSvcSetU32(&pMsgEntry->aParms[1], 0 /* fFeatures */); 152 HGCMSvcSetU32(&pMsgEntry->aParms[2], i /* uIndex */); 153 154 shClSvcClientLock(pClient); 155 shClSvcMsgAdd(pClient, pMsgEntry, true /* fAppend */); 156 shClSvcClientUnlock(pClient); 157 158 PSHCLEVENTPAYLOAD pPayloadEntry; 159 rc = ShClEventWait(pEventRootEntry, pCtx->pTransfer->uTimeoutMs, &pPayloadEntry); 160 if (RT_FAILURE(rc)) 161 break; 162 163 PSHCLLISTENTRY pRootListEntry = (PSHCLLISTENTRY)pPayloadEntry->pvData; 164 Assert(pPayloadEntry->cbData == sizeof(SHCLLISTENTRY)); 165 166 rc = ShClTransferListAddEntry(&pCtx->pTransfer->lstRoots, pRootListEntry, true /* fAppend */); 167 if (RT_FAILURE(rc)) 168 ShClPayloadFree(pPayloadEntry); 169 /* else don't call ShClPayloadFree() here, as pRootList own the data now. */ 170 pPayloadEntry = NULL; 171 172 ShClEventRelease(pEventRootEntry); 173 pEventRootEntry = NULL; 174 } 175 else 176 { 177 shClSvcMsgFree(pClient, pMsgEntry); 178 rc = VERR_SHCLPB_MAX_EVENTS_REACHED; 179 } 180 181 if (RT_FAILURE(rc)) 182 break; 183 } 184 185 ShClPayloadFree(pPayloadHdr); 186 } 187 } 188 189 ShClEventRelease(pEvent); 190 } 191 else 192 { 193 shClSvcMsgFree(pClient, pMsgHdr); 194 rc = VERR_SHCLPB_MAX_EVENTS_REACHED; 195 } 196 } 197 else 198 rc = VERR_NO_MEMORY; 291 rc = ShClTransferListAddEntry(&pCtx->pTransfer->lstRoots, pEntry, true /* fAppend */); 292 293 if (RT_FAILURE(rc)) 294 break; 295 } 296 } 199 297 200 298 LogFlowFuncLeave(); … … 203 301 204 302 /** @copydoc SHCLTXPROVIDERIFACE::pfnListOpen */ 205 DECLCALLBACK(int) shClSvcTransferIface ListOpen(PSHCLTXPROVIDERCTX pCtx,206 PSHCLLISTOPENPARMS pOpenParms, PSHCLLISTHANDLE phList)303 DECLCALLBACK(int) shClSvcTransferIfaceGHListOpen(PSHCLTXPROVIDERCTX pCtx, 304 PSHCLLISTOPENPARMS pOpenParms, PSHCLLISTHANDLE phList) 207 305 { 208 306 LogFlowFuncEnter(); … … 245 343 AssertPtr(pReply); 246 344 247 Assert(pReply->uType == VBOX_SHCL_ REPLYMSGTYPE_LIST_OPEN);345 Assert(pReply->uType == VBOX_SHCL_TX_REPLYMSGTYPE_LIST_OPEN); 248 346 249 347 LogFlowFunc(("hList=%RU64\n", pReply->u.ListOpen.uHandle)); … … 272 370 273 371 /** @copydoc SHCLTXPROVIDERIFACE::pfnListClose */ 274 DECLCALLBACK(int) shClSvcTransferIface ListClose(PSHCLTXPROVIDERCTX pCtx, SHCLLISTHANDLE hList)372 DECLCALLBACK(int) shClSvcTransferIfaceGHListClose(PSHCLTXPROVIDERCTX pCtx, SHCLLISTHANDLE hList) 275 373 { 276 374 LogFlowFuncEnter(); … … 327 425 328 426 /** @copydoc SHCLTXPROVIDERIFACE::pfnListHdrRead */ 329 DECLCALLBACK(int) shClSvcTransferIface ListHdrRead(PSHCLTXPROVIDERCTX pCtx,330 SHCLLISTHANDLE hList, PSHCLLISTHDR pListHdr)427 DECLCALLBACK(int) shClSvcTransferIfaceGHListHdrRead(PSHCLTXPROVIDERCTX pCtx, 428 SHCLLISTHANDLE hList, PSHCLLISTHDR pListHdr) 331 429 { 332 430 LogFlowFuncEnter(); … … 387 485 388 486 /** @copydoc SHCLTXPROVIDERIFACE::pfnListHdrWrite */ 389 DECLCALLBACK(int) shClSvcTransferIface ListHdrWrite(PSHCLTXPROVIDERCTX pCtx,390 SHCLLISTHANDLE hList, PSHCLLISTHDR pListHdr)487 DECLCALLBACK(int) shClSvcTransferIfaceHGListHdrWrite(PSHCLTXPROVIDERCTX pCtx, 488 SHCLLISTHANDLE hList, PSHCLLISTHDR pListHdr) 391 489 { 392 490 RT_NOREF(pCtx, hList, pListHdr); … … 398 496 399 497 /** @copydoc SHCLTXPROVIDERIFACE::pfnListEntryRead */ 400 DECLCALLBACK(int) shClSvcTransferIface ListEntryRead(PSHCLTXPROVIDERCTX pCtx,401 SHCLLISTHANDLE hList, PSHCLLISTENTRY pListEntry)498 DECLCALLBACK(int) shClSvcTransferIfaceGHListEntryRead(PSHCLTXPROVIDERCTX pCtx, 499 SHCLLISTHANDLE hList, PSHCLLISTENTRY pListEntry) 402 500 { 403 501 LogFlowFuncEnter(); … … 458 556 459 557 /** @copydoc SHCLTXPROVIDERIFACE::pfnListEntryWrite */ 460 DECLCALLBACK(int) shClSvcTransferIface ListEntryWrite(PSHCLTXPROVIDERCTX pCtx,461 SHCLLISTHANDLE hList, PSHCLLISTENTRY pListEntry)558 DECLCALLBACK(int) shClSvcTransferIfaceHGListEntryWrite(PSHCLTXPROVIDERCTX pCtx, 559 SHCLLISTHANDLE hList, PSHCLLISTENTRY pListEntry) 462 560 { 463 561 RT_NOREF(pCtx, hList, pListEntry); … … 469 567 470 568 /** @copydoc SHCLTXPROVIDERIFACE::pfnObjOpen */ 471 DECLCALLBACK(int) shClSvcTransferIface ObjOpen(PSHCLTXPROVIDERCTX pCtx, PSHCLOBJOPENCREATEPARMS pCreateParms, PSHCLOBJHANDLE phObj)569 DECLCALLBACK(int) shClSvcTransferIfaceGHObjOpen(PSHCLTXPROVIDERCTX pCtx, PSHCLOBJOPENCREATEPARMS pCreateParms, PSHCLOBJHANDLE phObj) 472 570 { 473 571 LogFlowFuncEnter(); … … 514 612 AssertPtr(pReply); 515 613 516 Assert(pReply->uType == VBOX_SHCL_ REPLYMSGTYPE_OBJ_OPEN);614 Assert(pReply->uType == VBOX_SHCL_TX_REPLYMSGTYPE_OBJ_OPEN); 517 615 518 616 LogFlowFunc(("hObj=%RU64\n", pReply->u.ObjOpen.uHandle)); … … 540 638 541 639 /** @copydoc SHCLTXPROVIDERIFACE::pfnObjClose */ 542 DECLCALLBACK(int) shClSvcTransferIface ObjClose(PSHCLTXPROVIDERCTX pCtx, SHCLOBJHANDLE hObj)640 DECLCALLBACK(int) shClSvcTransferIfaceGHObjClose(PSHCLTXPROVIDERCTX pCtx, SHCLOBJHANDLE hObj) 543 641 { 544 642 LogFlowFuncEnter(); … … 579 677 AssertPtr(pReply); 580 678 581 Assert(pReply->uType == VBOX_SHCL_ REPLYMSGTYPE_OBJ_CLOSE);679 Assert(pReply->uType == VBOX_SHCL_TX_REPLYMSGTYPE_OBJ_CLOSE); 582 680 583 681 LogFlowFunc(("hObj=%RU64\n", pReply->u.ObjClose.uHandle)); … … 603 701 604 702 /** @copydoc SHCLTXPROVIDERIFACE::pfnObjRead */ 605 DECLCALLBACK(int) shClSvcTransferIface ObjRead(PSHCLTXPROVIDERCTX pCtx, SHCLOBJHANDLE hObj,606 void *pvData, uint32_t cbData, uint32_t fFlags, uint32_t *pcbRead)703 DECLCALLBACK(int) shClSvcTransferIfaceGHObjRead(PSHCLTXPROVIDERCTX pCtx, SHCLOBJHANDLE hObj, 704 void *pvData, uint32_t cbData, uint32_t fFlags, uint32_t *pcbRead) 607 705 { 608 706 LogFlowFuncEnter(); … … 672 770 673 771 /** @copydoc SHCLTXPROVIDERIFACE::pfnObjWrite */ 674 DECLCALLBACK(int) shClSvcTransferIface ObjWrite(PSHCLTXPROVIDERCTX pCtx, SHCLOBJHANDLE hObj,675 void *pvData, uint32_t cbData, uint32_t fFlags, uint32_t *pcbWritten)772 DECLCALLBACK(int) shClSvcTransferIfaceHGObjWrite(PSHCLTXPROVIDERCTX pCtx, SHCLOBJHANDLE hObj, 773 void *pvData, uint32_t cbData, uint32_t fFlags, uint32_t *pcbWritten) 676 774 { 677 775 LogFlowFuncEnter(); … … 851 949 switch (pReply->uType) 852 950 { 853 case VBOX_SHCL_ REPLYMSGTYPE_TRANSFER_STATUS:951 case VBOX_SHCL_TX_REPLYMSGTYPE_TRANSFER_STATUS: 854 952 { 855 953 if (cParms > idxParm) … … 860 958 } 861 959 862 case VBOX_SHCL_ REPLYMSGTYPE_LIST_OPEN:960 case VBOX_SHCL_TX_REPLYMSGTYPE_LIST_OPEN: 863 961 { 864 962 if (cParms > idxParm) … … 869 967 } 870 968 871 case VBOX_SHCL_ REPLYMSGTYPE_LIST_CLOSE:969 case VBOX_SHCL_TX_REPLYMSGTYPE_LIST_CLOSE: 872 970 { 873 971 if (cParms > idxParm) … … 878 976 } 879 977 880 case VBOX_SHCL_ REPLYMSGTYPE_OBJ_OPEN:978 case VBOX_SHCL_TX_REPLYMSGTYPE_OBJ_OPEN: 881 979 { 882 980 if (cParms > idxParm) … … 887 985 } 888 986 889 case VBOX_SHCL_ REPLYMSGTYPE_OBJ_CLOSE:987 case VBOX_SHCL_TX_REPLYMSGTYPE_OBJ_CLOSE: 890 988 { 891 989 if (cParms > idxParm) … … 1249 1347 * @returns VBox status code. 1250 1348 * @param pClient Pointer to associated client. 1251 * @param pTransfer Pointer to transfer to handle guest reply for.1349 * @param idTransfer Transfer ID supplied from the guest. 1252 1350 * @param cParms Number of function parameters supplied. 1253 1351 * @param aParms Array function parameters supplied. 1254 1352 */ 1255 static int shClSvcTransferHandleReply(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer, 1256 uint32_t cParms, VBOXHGCMSVCPARM aParms[]) 1257 { 1258 RT_NOREF(pClient, pTransfer); 1259 1353 static int shClSvcTransferHandleReply(PSHCLCLIENT pClient, SHCLTRANSFERID idTransfer, uint32_t cParms, VBOXHGCMSVCPARM aParms[]) 1354 { 1260 1355 int rc; 1356 1357 PSHCLTRANSFER pTransfer = NULL; 1261 1358 1262 1359 uint32_t cbReply = sizeof(SHCLREPLY); … … 1267 1364 if (RT_SUCCESS(rc)) 1268 1365 { 1366 if ( pReply->uType == VBOX_SHCL_TX_REPLYMSGTYPE_TRANSFER_STATUS 1367 && pReply->u.TransferStatus.uStatus == SHCLTRANSFERSTATUS_REQUESTED) 1368 { 1369 /* SHCLTRANSFERSTATUS_REQUESTED is special, as it doesn't provide a transfer ID. */ 1370 } 1371 else /* Everything else needs a valid transfer ID. */ 1372 { 1373 pTransfer = ShClTransferCtxGetTransferById(&pClient->Transfers.Ctx, idTransfer); 1374 if (!pTransfer) 1375 { 1376 LogRel2(("Shared Clipboard: Transfer with ID %RU16 not found\n", idTransfer)); 1377 rc = VERR_SHCLPB_TRANSFER_ID_NOT_FOUND; 1378 } 1379 } 1380 1381 if (RT_FAILURE(rc)) 1382 { 1383 RTMemFree(pReply); 1384 pReply = NULL; 1385 1386 return rc; 1387 } 1388 1269 1389 PSHCLEVENTPAYLOAD pPayload 1270 1390 = (PSHCLEVENTPAYLOAD)RTMemAlloc(sizeof(SHCLEVENTPAYLOAD)); … … 1276 1396 switch (pReply->uType) 1277 1397 { 1278 case VBOX_SHCL_ REPLYMSGTYPE_TRANSFER_STATUS:1398 case VBOX_SHCL_TX_REPLYMSGTYPE_TRANSFER_STATUS: 1279 1399 { 1280 LogRel(("Shared Clipboard: Guest reported status %s for transfer %RU32\n", 1281 ShClTransferStatusToStr(pReply->u.TransferStatus.uStatus), pTransfer->State.uID)); 1400 /* SHCLTRANSFERSTATUS_REQUESTED is special, as it doesn't provide a transfer ID. */ 1401 if (SHCLTRANSFERSTATUS_REQUESTED == pReply->u.TransferStatus.uStatus) 1402 { 1403 LogRel2(("Shared Clipboard: Guest requested a new host -> guest transfer\n")); 1404 } 1405 else 1406 LogRel2(("Shared Clipboard: Guest reported status %s for transfer %RU32\n", 1407 ShClTransferStatusToStr(pReply->u.TransferStatus.uStatus), idTransfer)); 1282 1408 1283 1409 switch (pReply->u.TransferStatus.uStatus) 1284 1410 { 1285 case SHCLTRANSFERSTATUS_INITIALIZED: /* Initialized -> Started */ 1286 rc = shClSvcTransferStart(pClient, pTransfer); 1411 case SHCLTRANSFERSTATUS_REQUESTED: /* Guest requests a H->G transfer. */ 1412 { 1413 uint32_t const uMode = ShClSvcGetMode(); 1414 if ( uMode == VBOX_SHCL_MODE_HOST_TO_GUEST 1415 || uMode == VBOX_SHCL_MODE_BIDIRECTIONAL) 1416 { 1417 /* We only create (but not initialize) the transfer here. This is the most lightweight form of 1418 * having a pending transfer around. Report back the new transfer ID to the guest then. */ 1419 if (pTransfer == NULL) /* Must not exist yet. */ 1420 { 1421 rc = ShClSvcTransferCreate(pClient, SHCLTRANSFERDIR_TO_REMOTE, SHCLSOURCE_LOCAL, 1422 NIL_SHCLTRANSFERID /* Creates a new transfer ID */, 1423 &pTransfer); 1424 if (RT_SUCCESS(rc)) 1425 { 1426 shClSvcClientLock(pClient); 1427 1428 rc = shClSvcTransferSendStatusAsyncInternal(pClient, pTransfer, 1429 SHCLTRANSFERSTATUS_REQUESTED, VINF_SUCCESS, 1430 NULL); 1431 shClSvcClientUnlock(pClient); 1432 } 1433 } 1434 else 1435 rc = VERR_WRONG_ORDER; 1436 } 1437 else 1438 rc = VERR_INVALID_PARAMETER; 1439 1287 1440 break; 1288 1289 case SHCLTRANSFERSTATUS_STARTED: 1441 } 1442 1443 case SHCLTRANSFERSTATUS_INITIALIZED: /* Guest reports the transfer as being initialized. */ 1444 { 1445 switch (ShClTransferGetDir(pTransfer)) 1446 { 1447 case SHCLTRANSFERDIR_FROM_REMOTE: /* G->H */ 1448 /* Already done locally when creating the transfer. */ 1449 break; 1450 1451 case SHCLTRANSFERDIR_TO_REMOTE: /* H->G */ 1452 { 1453 /* Initialize the transfer on the host side. */ 1454 rc = ShClSvcTransferInit(pClient, pTransfer); 1455 break; 1456 } 1457 1458 default: 1459 AssertFailed(); 1460 break; 1461 } 1462 1290 1463 break; 1464 } 1465 case SHCLTRANSFERSTATUS_STARTED: /* Guest has started the transfer on its side. */ 1466 { 1467 /* We only need to start for H->G transfers here. 1468 * For G->H transfers we start this as soon as the host clipboard requests data. */ 1469 if (ShClTransferGetDir(pTransfer) == SHCLTRANSFERDIR_TO_REMOTE) 1470 { 1471 /* Start the transfer on the host side. */ 1472 rc = ShClSvcTransferStart(pClient, pTransfer); 1473 } 1474 break; 1475 } 1476 1477 case SHCLTRANSFERSTATUS_CANCELED: 1478 RT_FALL_THROUGH(); 1479 case SHCLTRANSFERSTATUS_KILLED: 1480 { 1481 LogRel(("Shared Clipboard: Guest has %s transfer %RU32\n", 1482 pReply->uType == SHCLTRANSFERSTATUS_CANCELED ? "canceled" : "killed", pTransfer->State.uID)); 1483 1484 rc = ShClSvcTransferStop(pClient, pTransfer, false /* fWaitForGuest */); 1485 1486 /* Regardless of whether the guest was able to report back and/or stop the transfer, remove the transfer on the host 1487 * so that we don't risk of having stale transfers here. */ 1488 ShClSvcTransferDestroy(pClient, pTransfer); 1489 pTransfer = NULL; 1490 break; 1491 } 1492 1493 case SHCLTRANSFERSTATUS_STOPPED: 1494 { 1495 LogRel(("Shared Clipboard: Guest has stopped transfer %RU32\n", pTransfer->State.uID)); 1496 1497 rc = ShClSvcTransferStop(pClient, pTransfer, false /* fWaitForGuest */); 1498 break; 1499 } 1291 1500 1292 1501 case SHCLTRANSFERSTATUS_ERROR: … … 1294 1503 LogRel(("Shared Clipboard: Guest reported error %Rrc for transfer %RU32\n", 1295 1504 pReply->rc, pTransfer->State.uID)); 1296 1297 rc = shClSvcTransferStop(pClient, pTransfer, false /* fWaitForGuest */); 1505 RT_FALL_THROUGH(); 1506 } 1507 default: 1508 { 1509 /* Regardless of whether the guest was able to report back and/or stop the transfer, remove the transfer on the host 1510 * so that we don't risk of having stale transfers here. */ 1511 ShClSvcTransferDestroy(pClient, pTransfer); 1512 pTransfer = NULL; 1298 1513 break; 1299 1514 } 1300 1301 default:1302 rc = shClSvcTransferStop(pClient, pTransfer, true /* fWaitForGuest */);1303 break;1304 1515 } 1516 1517 /* Tell the backend. */ 1518 int rc2 = ShClBackendTransferHandleStatusReply(pClient->pBackend, pClient, pTransfer, 1519 SHCLSOURCE_REMOTE, pReply->u.TransferStatus.uStatus, 1520 pReply->rc); 1521 if (RT_SUCCESS(rc)) 1522 rc = rc2; 1305 1523 1306 1524 RT_FALL_THROUGH(); 1307 1525 } 1308 case VBOX_SHCL_ REPLYMSGTYPE_LIST_OPEN:1526 case VBOX_SHCL_TX_REPLYMSGTYPE_LIST_OPEN: 1309 1527 RT_FALL_THROUGH(); 1310 case VBOX_SHCL_ REPLYMSGTYPE_LIST_CLOSE:1528 case VBOX_SHCL_TX_REPLYMSGTYPE_LIST_CLOSE: 1311 1529 RT_FALL_THROUGH(); 1312 case VBOX_SHCL_ REPLYMSGTYPE_OBJ_OPEN:1530 case VBOX_SHCL_TX_REPLYMSGTYPE_OBJ_OPEN: 1313 1531 RT_FALL_THROUGH(); 1314 case VBOX_SHCL_ REPLYMSGTYPE_OBJ_CLOSE:1532 case VBOX_SHCL_TX_REPLYMSGTYPE_OBJ_CLOSE: 1315 1533 { 1316 1534 uint64_t uCID; … … 1391 1609 int rc = VERR_INVALID_PARAMETER; /* Play safe by default. */ 1392 1610 1611 if (cParms < 1) 1612 return rc; 1613 ASSERT_GUEST_RETURN(aParms[0].type == VBOX_HGCM_SVC_PARM_64BIT, VERR_WRONG_PARAMETER_TYPE); 1614 1615 uint64_t uCID = 0; /* Context ID */ 1616 rc = HGCMSvcGetU64(&aParms[0], &uCID); 1617 if (RT_FAILURE(rc)) 1618 return rc; 1619 1620 const SHCLTRANSFERID idTransfer = VBOX_SHCL_CONTEXTID_GET_TRANSFER(uCID); 1621 1393 1622 /* 1394 1623 * Pre-check: For certain messages we need to make sure that a (right) transfer is present. 1395 1624 */ 1396 uint64_t uCID = 0; /* Context ID */1397 1625 PSHCLTRANSFER pTransfer = NULL; 1398 1399 shClSvcClientLock(pClient);1400 ASSERT_GUEST_MSG_RETURN(pClient->Pending.uType == 0, ("Already pending! (idClient=%RU32)\n",1401 pClient->State.uClientID), VERR_RESOURCE_BUSY);1402 shClSvcClientUnlock(pClient);1403 1404 1626 switch (u32Function) 1405 1627 { 1628 case VBOX_SHCL_GUEST_FN_REPLY: 1629 /* Function does its own lookup. */ 1630 break; 1631 1406 1632 default: 1407 1633 { 1408 if (!ShClTransferCtxGetTotalTransfers(&pClient->Transfers.Ctx)) 1409 { 1410 LogFunc(("No transfers found\n")); 1411 rc = VERR_SHCLPB_TRANSFER_ID_NOT_FOUND; 1412 break; 1413 } 1414 1415 if (cParms < 1) 1416 break; 1417 1418 ASSERT_GUEST_RETURN(aParms[0].type == VBOX_HGCM_SVC_PARM_64BIT, VERR_WRONG_PARAMETER_TYPE); 1419 1420 rc = HGCMSvcGetU64(&aParms[0], &uCID); 1421 if (RT_FAILURE(rc)) 1422 break; 1423 1424 const SHCLTRANSFERID uTransferID = VBOX_SHCL_CONTEXTID_GET_TRANSFER(uCID); 1425 1426 pTransfer = ShClTransferCtxGetTransferById(&pClient->Transfers.Ctx, uTransferID); 1634 pTransfer = ShClTransferCtxGetTransferById(&pClient->Transfers.Ctx, idTransfer); 1427 1635 if (!pTransfer) 1428 1636 { 1429 Log Func(("Transfer with ID %RU16 not found\n", uTransferID));1637 LogRel(("Shared Clipboard: Transfer with ID %RU16 not found\n", idTransfer)); 1430 1638 rc = VERR_SHCLPB_TRANSFER_ID_NOT_FOUND; 1431 1639 } … … 1443 1651 case VBOX_SHCL_GUEST_FN_REPLY: 1444 1652 { 1445 rc = shClSvcTransferHandleReply(pClient, pTransfer, cParms, aParms);1653 rc = shClSvcTransferHandleReply(pClient, idTransfer, cParms, aParms); 1446 1654 break; 1447 1655 } … … 1458 1666 && ShClTransferGetDir(pTransfer) == SHCLTRANSFERDIR_TO_REMOTE) 1459 1667 { 1460 /* Get roots if this is a local write transfer (host -> guest). */ 1461 rc = ShClBackendTransferGetRoots(pClient->pBackend, pClient, pTransfer); 1668 rc = ShClBackendTransferHGRootListRead(pClient->pBackend, pClient, pTransfer); 1669 if (RT_FAILURE(rc)) 1670 break; 1462 1671 } 1463 1672 else … … 1473 1682 HGCMSvcSetU32(&aParms[1], rootListHdr.fFeatures); 1474 1683 HGCMSvcSetU64(&aParms[2], rootListHdr.cEntries); 1475 1476 rc = VINF_SUCCESS;1477 1684 break; 1478 1685 } … … 1830 2037 } 1831 2038 2039 /* If anything wrong has happened, make sure to unregister the transfer again (if not done already) and tell the guest. */ 2040 if ( RT_FAILURE(rc) 2041 && pTransfer) 2042 { 2043 shClSvcClientLock(pClient); 2044 2045 /* Let the guest know. */ 2046 int rc2 = shClSvcTransferSendStatusAsyncInternal(pClient, pTransfer, 2047 SHCLTRANSFERSTATUS_ERROR, rc, NULL /* ppEvent */); 2048 AssertRC(rc2); 2049 2050 ShClSvcTransferDestroy(pClient, pTransfer); 2051 2052 shClSvcClientUnlock(pClient); 2053 } 2054 1832 2055 LogFlowFunc(("[Client %RU32] Returning rc=%Rrc\n", pClient->State.uClientID, rc)); 1833 2056 return rc; … … 1879 2102 break; 1880 2103 } 2104 2105 LogFlowFuncLeaveRC(rc); 2106 return rc; 2107 } 2108 2109 /** 2110 * Reports a transfer status to the guest. 2111 * 2112 * @returns VBox status code. 2113 * @param pClient Client that owns the transfer. 2114 * @param idTransfer Transfer ID to report status for. 2115 * @param enmDir Transfer direction to report status for. 2116 * @param uStatus Status to report. 2117 * @param rcTransfer Result code to report. Optional and depending on status. 2118 * @param ppEvent Where to return the wait event on success. Optional. 2119 * Must be released by the caller with ShClEventRelease(). 2120 * 2121 * @note Caller must enter the client's critical section. 2122 */ 2123 static int shClSvcTransferSendStatusExAsync(PSHCLCLIENT pClient, SHCLTRANSFERID idTransfer, SHCLTRANSFERDIR enmDir, SHCLTRANSFERSTATUS uStatus, 2124 int rcTransfer, PSHCLEVENT *ppEvent) 2125 { 2126 AssertPtrReturn(pClient, VERR_INVALID_POINTER); 2127 AssertReturn(idTransfer != NIL_SHCLTRANSFERID, VERR_INVALID_PARAMETER); 2128 /* ppEvent is optional. */ 2129 2130 PSHCLCLIENTMSG pMsgReadData = shClSvcMsgAlloc(pClient, VBOX_SHCL_HOST_MSG_TRANSFER_STATUS, 2131 VBOX_SHCL_CPARMS_TRANSFER_STATUS); 2132 if (!pMsgReadData) 2133 return VERR_NO_MEMORY; 2134 2135 PSHCLEVENT pEvent; 2136 int rc = ShClEventSourceGenerateAndRegisterEvent(&pClient->EventSrc, &pEvent); 2137 if (RT_SUCCESS(rc)) 2138 { 2139 HGCMSvcSetU64(&pMsgReadData->aParms[0], VBOX_SHCL_CONTEXTID_MAKE(pClient->State.uSessionID, idTransfer, pEvent->idEvent)); 2140 HGCMSvcSetU32(&pMsgReadData->aParms[1], enmDir); 2141 HGCMSvcSetU32(&pMsgReadData->aParms[2], uStatus); 2142 HGCMSvcSetU32(&pMsgReadData->aParms[3], (uint32_t)rcTransfer); /** @todo uint32_t vs. int. */ 2143 HGCMSvcSetU32(&pMsgReadData->aParms[4], 0 /* fFlags, unused */); 2144 2145 shClSvcMsgAdd(pClient, pMsgReadData, true /* fAppend */); 2146 2147 rc = shClSvcClientWakeup(pClient); 2148 if (RT_SUCCESS(rc)) 2149 { 2150 LogRel2(("Shared Clipboard: Reported status %s (rc=%Rrc) of transfer %RU32 to guest\n", 2151 ShClTransferStatusToStr(uStatus), rcTransfer, idTransfer)); 2152 2153 if (ppEvent) 2154 { 2155 *ppEvent = pEvent; /* Takes ownership. */ 2156 } 2157 else /* If event is not consumed by the caller, release the event again. */ 2158 ShClEventRelease(pEvent); 2159 } 2160 else 2161 ShClEventRelease(pEvent); 2162 } 2163 else 2164 rc = VERR_SHCLPB_MAX_EVENTS_REACHED; 2165 2166 if (RT_FAILURE(rc)) 2167 LogRel(("Shared Clipboard: Reporting status %s (%Rrc) for transfer %RU32 to guest failed with %Rrc\n", 2168 ShClTransferStatusToStr(uStatus), rcTransfer, idTransfer, rc)); 1881 2169 1882 2170 LogFlowFuncLeaveRC(rc); … … 1895 2183 * Must be released by the caller with ShClEventRelease(). 1896 2184 * 1897 * @note Caller must enter critical section.1898 */ 1899 int shClSvcTransferSendStatus(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer, SHCLTRANSFERSTATUS uStatus,1900 int rcTransfer, PSHCLEVENT *ppEvent)2185 * @note Caller must enter the client's critical section. 2186 */ 2187 static int shClSvcTransferSendStatusAsyncInternal(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer, SHCLTRANSFERSTATUS uStatus, 2188 int rcTransfer, PSHCLEVENT *ppEvent) 1901 2189 { 1902 2190 AssertPtrReturn(pClient, VERR_INVALID_POINTER); … … 1904 2192 /* ppEvent is optional. */ 1905 2193 1906 PSHCLCLIENTMSG pMsgReadData = shClSvcMsgAlloc(pClient, VBOX_SHCL_HOST_MSG_TRANSFER_STATUS, 1907 VBOX_SHCL_CPARMS_TRANSFER_STATUS); 1908 if (!pMsgReadData) 1909 return VERR_NO_MEMORY; 1910 1911 PSHCLEVENT pEvent; 1912 int rc = ShClEventSourceGenerateAndRegisterEvent(&pClient->EventSrc, &pEvent); 1913 if (RT_SUCCESS(rc)) 1914 { 1915 HGCMSvcSetU64(&pMsgReadData->aParms[0], VBOX_SHCL_CONTEXTID_MAKE(pClient->State.uSessionID, 1916 pTransfer->State.uID, pEvent->idEvent)); 1917 HGCMSvcSetU32(&pMsgReadData->aParms[1], pTransfer->State.enmDir); 1918 HGCMSvcSetU32(&pMsgReadData->aParms[2], uStatus); 1919 HGCMSvcSetU32(&pMsgReadData->aParms[3], (uint32_t)rcTransfer); /** @todo uint32_t vs. int. */ 1920 HGCMSvcSetU32(&pMsgReadData->aParms[4], 0 /* fFlags, unused */); 1921 1922 shClSvcMsgAdd(pClient, pMsgReadData, true /* fAppend */); 1923 1924 rc = shClSvcClientWakeup(pClient); 1925 if (RT_SUCCESS(rc)) 1926 { 1927 LogRel2(("Shared Clipboard: Reported status %s (rc=%Rrc) of transfer %RU32 to guest\n", 1928 ShClTransferStatusToStr(uStatus), rcTransfer, pTransfer->State.uID)); 1929 1930 if (ppEvent) 1931 { 1932 *ppEvent = pEvent; /* Takes ownership. */ 1933 } 1934 else /* If event is not consumed by the caller, release the event again. */ 1935 ShClEventRelease(pEvent); 1936 } 1937 else 1938 ShClEventRelease(pEvent); 1939 } 1940 else 1941 rc = VERR_SHCLPB_MAX_EVENTS_REACHED; 1942 1943 if (RT_FAILURE(rc)) 1944 LogRel(("Shared Clipboard: Reporting status %s (%Rrc) for transfer %RU32 to guest failed with %Rrc\n", 1945 ShClTransferStatusToStr(uStatus), rcTransfer, pTransfer->State.uID, rc)); 1946 1947 LogFlowFuncLeaveRC(rc); 1948 return rc; 1949 } 1950 1951 /** 1952 * Cleans up (unregisters and destroys) all transfers not in the 'started' state (anymore). 2194 return shClSvcTransferSendStatusExAsync(pClient, ShClTransferGetID(pTransfer), ShClTransferGetDir(pTransfer), 2195 uStatus, rcTransfer, ppEvent); 2196 } 2197 2198 int ShClSvcTransferSendStatusAsync(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer, SHCLTRANSFERSTATUS uStatus, 2199 int rcTransfer, PSHCLEVENT *ppEvent) 2200 { 2201 shClSvcClientLock(pClient); 2202 2203 int rc = shClSvcTransferSendStatusAsyncInternal(pClient, pTransfer, uStatus, rcTransfer, ppEvent); 2204 2205 shClSvcClientUnlock(pClient); 2206 2207 return rc; 2208 } 2209 2210 /** 2211 * Cleans up (unregisters and destroys) all transfers not in started state (anymore). 1953 2212 * 1954 2213 * @param pClient Client to clean up transfers for. … … 1956 2215 * @note Caller needs to take the critical section. 1957 2216 */ 1958 void shClSvcTransferCleanupAllUnused(PSHCLCLIENT pClient) 1959 { 2217 static void shClSvcTransferCleanupAllUnused(PSHCLCLIENT pClient) 2218 { 2219 Assert(RTCritSectIsOwner(&pClient->CritSect)); 2220 1960 2221 LogFlowFuncEnter(); 1961 2222 1962 2223 PSHCLTRANSFERCTX pTxCtx = &pClient->Transfers.Ctx; 1963 2224 1964 /* Remove all transfers which are not in a running state (e.g. only announced). */1965 2225 PSHCLTRANSFER pTransfer, pTransferNext; 1966 2226 RTListForEachSafe(&pTxCtx->List, pTransfer, pTransferNext, SHCLTRANSFER, Node) 1967 2227 { 1968 if (ShClTransferGetStatus(pTransfer) != SHCLTRANSFERSTATUS_STARTED) 2228 SHCLTRANSFERSTATUS const enmSts = ShClTransferGetStatus(pTransfer); 2229 if (enmSts != SHCLTRANSFERSTATUS_STARTED) 1969 2230 { 1970 2231 /* Let the guest know. */ 1971 int rc2 = shClSvcTransferSendStatus (pClient, pTransfer,1972 SHCLTRANSFERSTATUS_UNINITIALIZED, VINF_SUCCESS, NULL /* ppEvent */);2232 int rc2 = shClSvcTransferSendStatusAsyncInternal(pClient, pTransfer, 2233 SHCLTRANSFERSTATUS_UNINITIALIZED, VINF_SUCCESS, NULL /* ppEvent */); 1973 2234 AssertRC(rc2); 1974 2235 1975 ShClTransferCtx TransferUnregisterById(pTxCtx, pTransfer->State.uID);2236 ShClTransferCtxUnregisterById(pTxCtx, pTransfer->State.uID); 1976 2237 1977 2238 ShClTransferDestroy(pTransfer); … … 1984 2245 1985 2246 /** 1986 * Initializes a new transfer and sends the status to the guest. 1987 * 1988 * @note Assumes that the client's critical section is taken. 2247 * Creates a new transfer on the host. 1989 2248 * 1990 2249 * @returns VBox status code. 1991 2250 * @param pClient Client that owns the transfer. 1992 * @param enmDir Transfer direction to start. 1993 * @param enmSource Transfer source to start. 1994 * @param ppTransfer Where to return the created transfer on success. Optional. 1995 */ 1996 int shClSvcTransferInit(PSHCLCLIENT pClient, 1997 SHCLTRANSFERDIR enmDir, SHCLSOURCE enmSource, 1998 PSHCLTRANSFER *ppTransfer) 1999 { 2000 Assert(RTCritSectIsOwner(&pClient->CritSect)); 2001 2251 * @param enmDir Transfer direction to create. 2252 * @param enmSource Transfer source to create. 2253 * @param idTransfer Transfer ID to use for creation. 2254 * If set to NIL_SHCLTRANSFERID, a new transfer ID will be created. 2255 * @param ppTransfer Where to return the created transfer on success. Optional and can be NULL. 2256 */ 2257 int ShClSvcTransferCreate(PSHCLCLIENT pClient, SHCLTRANSFERDIR enmDir, SHCLSOURCE enmSource, SHCLTRANSFERID idTransfer, PSHCLTRANSFER *ppTransfer) 2258 { 2002 2259 AssertPtrReturn(pClient, VERR_INVALID_POINTER); 2003 2260 /* ppTransfer is optional. */ … … 2005 2262 LogFlowFuncEnter(); 2006 2263 2264 shClSvcClientLock(pClient); 2265 2266 /* When creating a new transfer, this is a good time to clean up old stuff we don't need anymore. */ 2007 2267 shClSvcTransferCleanupAllUnused(pClient); 2008 2268 2269 PSHCLTRANSFER pTransfer; 2270 int rc = ShClTransferCreate(enmDir, enmSource, &pTransfer); 2271 if (RT_SUCCESS(rc)) 2272 { 2273 if (idTransfer == NIL_SHCLTRANSFERID) 2274 rc = ShClTransferCtxRegister(&pClient->Transfers.Ctx, pTransfer, &idTransfer); 2275 else 2276 rc = ShClTransferCtxRegisterById(&pClient->Transfers.Ctx, pTransfer, idTransfer); 2277 if (RT_SUCCESS(rc)) 2278 { 2279 if (ppTransfer) 2280 *ppTransfer = pTransfer; 2281 } 2282 } 2283 2284 shClSvcClientUnlock(pClient); 2285 2286 if (RT_FAILURE(rc)) 2287 { 2288 ShClTransferDestroy(pTransfer); 2289 2290 RTMemFree(pTransfer); 2291 pTransfer = NULL; 2292 } 2293 2294 if (RT_FAILURE(rc)) 2295 LogRel(("Shared Clipboard: Creating transfer failed with %Rrc\n", rc)); 2296 2297 LogFlowFuncLeaveRC(rc); 2298 return rc; 2299 } 2300 2301 /** 2302 * Destroys a transfer on the host. 2303 * 2304 * @param pClient Client to destroy transfer for. 2305 * @param pTransfer Transfer to destroy. 2306 * The pointer will be invalid after return. 2307 */ 2308 void ShClSvcTransferDestroy(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer) 2309 { 2310 if (!pTransfer) 2311 return; 2312 2313 LogFlowFuncEnter(); 2314 2009 2315 PSHCLTRANSFERCTX pTxCtx = &pClient->Transfers.Ctx; 2010 2316 2317 ShClTransferCtxUnregisterById(pTxCtx, pTransfer->State.uID); 2318 2319 ShClTransferDestroy(pTransfer); 2320 2321 RTMemFree(pTransfer); 2322 pTransfer = NULL; 2323 2324 LogFlowFuncLeave(); 2325 } 2326 2327 /** 2328 * Initializes a (created) transfer on the host. 2329 * 2330 * @returns VBox status code. 2331 * @param pClient Client that owns the transfer. 2332 * @param pTransfer Transfer to initialize. 2333 */ 2334 int ShClSvcTransferInit(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer) 2335 { 2336 AssertPtrReturn(pClient, VERR_INVALID_POINTER); 2337 2338 LogFlowFuncEnter(); 2339 2340 shClSvcClientLock(pClient); 2341 2342 Assert(ShClTransferGetStatus(pTransfer) == SHCLTRANSFERSTATUS_NONE); 2343 2344 PSHCLTRANSFERCTX pTxCtx = &pClient->Transfers.Ctx; 2345 2011 2346 int rc; 2012 2347 2013 if (!ShClTransferCtxTransfersMaximumReached(pTxCtx)) 2014 { 2348 if (!ShClTransferCtxIsMaximumReached(pTxCtx)) 2349 { 2350 SHCLTRANSFERDIR const enmDir = ShClTransferGetDir(pTransfer); 2351 2015 2352 LogRel2(("Shared Clipboard: Initializing %s transfer ...\n", 2016 2353 enmDir == SHCLTRANSFERDIR_FROM_REMOTE ? "guest -> host" : "host -> guest")); 2017 2354 2018 PSHCLTRANSFER pTransfer; 2019 rc = ShClTransferCreate(&pTransfer); 2020 if (RT_SUCCESS(rc)) 2021 { 2022 SHCLTXPROVIDER Provider; 2023 RT_ZERO(Provider); 2024 2025 /* Assign local provider first and overwrite interface methods below if needed. */ 2026 VBClTransferProviderLocalQueryInterface(&Provider); 2027 2028 if (enmDir == SHCLTRANSFERDIR_FROM_REMOTE) /* Guest -> Host. */ 2029 { 2030 Provider.Interface.pfnRootListRead = shClSvcTransferIfaceRootListRead; 2031 2032 Provider.Interface.pfnListOpen = shClSvcTransferIfaceListOpen; 2033 Provider.Interface.pfnListClose = shClSvcTransferIfaceListClose; 2034 Provider.Interface.pfnListHdrRead = shClSvcTransferIfaceListHdrRead; 2035 Provider.Interface.pfnListEntryRead = shClSvcTransferIfaceListEntryRead; 2036 2037 Provider.Interface.pfnObjOpen = shClSvcTransferIfaceObjOpen; 2038 Provider.Interface.pfnObjClose = shClSvcTransferIfaceObjClose; 2039 Provider.Interface.pfnObjRead = shClSvcTransferIfaceObjRead; 2040 } 2041 else if (enmDir == SHCLTRANSFERDIR_TO_REMOTE) /* Host -> Guest. */ 2042 { 2043 Provider.Interface.pfnListHdrWrite = shClSvcTransferIfaceListHdrWrite; 2044 Provider.Interface.pfnListEntryWrite = shClSvcTransferIfaceListEntryWrite; 2045 Provider.Interface.pfnObjWrite = shClSvcTransferIfaceObjWrite; 2046 } 2047 else 2048 AssertFailed(); 2049 2050 Provider.enmSource = pClient->State.enmSource; 2051 Provider.pvUser = pClient; 2052 2053 rc = ShClTransferSetProvider(pTransfer, &Provider); 2355 SHCLTXPROVIDER Provider; 2356 RT_ZERO(Provider); 2357 2358 /* Assign local provider first and overwrite interface methods below if needed. */ 2359 ShClTransferProviderLocalQueryInterface(&Provider); 2360 2361 if (enmDir == SHCLTRANSFERDIR_FROM_REMOTE) /* Guest -> Host. */ 2362 { 2363 Provider.Interface.pfnRootListRead = shClSvcTransferIfaceGHRootListRead; 2364 2365 Provider.Interface.pfnListOpen = shClSvcTransferIfaceGHListOpen; 2366 Provider.Interface.pfnListClose = shClSvcTransferIfaceGHListClose; 2367 Provider.Interface.pfnListHdrRead = shClSvcTransferIfaceGHListHdrRead; 2368 Provider.Interface.pfnListEntryRead = shClSvcTransferIfaceGHListEntryRead; 2369 2370 Provider.Interface.pfnObjOpen = shClSvcTransferIfaceGHObjOpen; 2371 Provider.Interface.pfnObjClose = shClSvcTransferIfaceGHObjClose; 2372 Provider.Interface.pfnObjRead = shClSvcTransferIfaceGHObjRead; 2373 } 2374 else if (enmDir == SHCLTRANSFERDIR_TO_REMOTE) /* Host -> Guest. */ 2375 { 2376 Provider.Interface.pfnListHdrWrite = shClSvcTransferIfaceHGListHdrWrite; 2377 Provider.Interface.pfnListEntryWrite = shClSvcTransferIfaceHGListEntryWrite; 2378 Provider.Interface.pfnObjWrite = shClSvcTransferIfaceHGObjWrite; 2379 } 2380 else 2381 AssertFailed(); 2382 2383 Provider.enmSource = pClient->State.enmSource; 2384 Provider.pvUser = pClient; 2385 2386 rc = ShClTransferSetProvider(pTransfer, &Provider); 2387 if (RT_SUCCESS(rc)) 2388 { 2389 ShClTransferSetCallbacks(pTransfer, &pClient->Transfers.Callbacks); 2390 2391 rc = ShClTransferInit(pTransfer); 2054 2392 if (RT_SUCCESS(rc)) 2055 2393 { 2056 ShClTransferSetCallbacks(pTransfer, &pClient->Transfers.Callbacks); 2057 2058 rc = ShClTransferInit(pTransfer, enmDir, enmSource); 2059 if (RT_SUCCESS(rc)) 2060 { 2061 SHCLTRANSFERID uTransferID = 0; 2062 rc = ShClTransferCtxTransferRegister(pTxCtx, pTransfer, &uTransferID); 2063 if (RT_SUCCESS(rc)) 2064 { 2065 rc = ShClBackendTransferCreate(pClient->pBackend, pClient, pTransfer); 2066 if (RT_SUCCESS(rc)) 2067 { 2068 /* Tell the guest that we've initialized the transfer locally. */ 2069 rc = shClSvcTransferSendStatus(pClient, pTransfer, 2070 SHCLTRANSFERSTATUS_INITIALIZED, VINF_SUCCESS, NULL /* ppEvent */); 2071 } 2072 } 2073 2074 if (RT_FAILURE(rc)) 2075 ShClTransferCtxTransferUnregisterById(pTxCtx, uTransferID); 2076 } 2077 } 2078 2079 if (RT_FAILURE(rc)) 2080 { 2081 ShClBackendTransferDestroy(pClient->pBackend, pClient, pTransfer); 2082 ShClTransferDestroy(pTransfer); 2083 2084 RTMemFree(pTransfer); 2085 pTransfer = NULL; 2086 } 2087 else 2088 { 2089 if (ppTransfer) 2090 *ppTransfer = pTransfer; 2091 } 2092 } 2093 2094 if (RT_FAILURE(rc)) 2095 LogRel(("Shared Clipboard: Starting transfer failed with %Rrc\n", rc)); 2394 /* Sanity: Make sure that the transfer we're gonna report as INITIALIZED to the guest 2395 * actually has some root entries set, as the guest can query for those at any time then. */ 2396 if (enmDir == SHCLTRANSFERDIR_TO_REMOTE) 2397 AssertMsgStmt(ShClTransferRootsCount(pTransfer), ("Transfer has no root entries set\n"), rc = VERR_WRONG_ORDER); 2398 } 2399 } 2096 2400 } 2097 2401 else 2098 2402 rc = VERR_SHCLPB_MAX_TRANSFERS_REACHED; 2099 2403 2404 /* Tell the guest the outcome. */ 2405 int rc2 = shClSvcTransferSendStatusAsyncInternal(pClient, pTransfer, 2406 RT_SUCCESS(rc) 2407 ? SHCLTRANSFERSTATUS_INITIALIZED : SHCLTRANSFERSTATUS_ERROR, rc, 2408 NULL /* ppEvent */); 2409 if (RT_SUCCESS(rc)) 2410 rc2 = rc; 2411 2412 if (RT_FAILURE(rc)) 2413 LogRel(("Shared Clipboard: Initializing transfer failed with %Rrc\n", rc)); 2414 2415 shClSvcClientUnlock(pClient); 2416 2100 2417 LogFlowFuncLeaveRC(rc); 2101 2418 return rc; … … 2107 2424 * @returns VBox status code. 2108 2425 * @param pClient Client that owns the transfer. 2109 * @param pTransfer Transfer to st op.2110 */ 2111 int shClSvcTransferStart(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer)2426 * @param pTransfer Transfer to start. 2427 */ 2428 int ShClSvcTransferStart(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer) 2112 2429 { 2113 2430 LogRel2(("Shared Clipboard: Starting transfer %RU32 ...\n", pTransfer->State.uID)); … … 2119 2436 /* Let the guest know in any case 2120 2437 * (so that it can tear down the transfer on error as well). */ 2121 int rc2 = shClSvcTransferSendStatus(pClient, pTransfer, 2122 RT_SUCCESS(rc) ? SHCLTRANSFERSTATUS_STARTED : SHCLTRANSFERSTATUS_ERROR, rc, NULL /* ppEvent */); 2438 int rc2 = shClSvcTransferSendStatusAsyncInternal(pClient, pTransfer, 2439 RT_SUCCESS(rc) ? SHCLTRANSFERSTATUS_STARTED : SHCLTRANSFERSTATUS_ERROR, rc, 2440 NULL /* ppEvent */); 2123 2441 if (RT_SUCCESS(rc)) 2124 2442 rc = rc2; … … 2136 2454 * @param fWaitForGuest Set to \c true to wait for acknowledgement from guest, or \c false to skip waiting. 2137 2455 */ 2138 int shClSvcTransferStop(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer, bool fWaitForGuest)2456 int ShClSvcTransferStop(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer, bool fWaitForGuest) 2139 2457 { 2140 2458 LogRel2(("Shared Clipboard: Stopping transfer %RU32 ...\n", pTransfer->State.uID)); … … 2143 2461 2144 2462 PSHCLEVENT pEvent; 2145 int rc = shClSvcTransferSendStatus (pClient, pTransfer,2146 SHCLTRANSFERSTATUS_STOPPED, VINF_SUCCESS, &pEvent);2463 int rc = shClSvcTransferSendStatusAsyncInternal(pClient, pTransfer, 2464 SHCLTRANSFERSTATUS_STOPPED, VINF_SUCCESS, &pEvent); 2147 2465 if ( RT_SUCCESS(rc) 2148 2466 && fWaitForGuest) … … 2165 2483 pTransfer->State.uID, rc)); 2166 2484 2167 /* Regardless of whether the guest was able to report back and/or stop the transfer, remove the transfer on the host2168 * so that we don't risk of having stale transfers here. */2169 int rc2 = ShClTransferCtxTransferUnregisterById(&pClient->Transfers.Ctx, ShClTransferGetID(pTransfer));2170 if (RT_SUCCESS(rc2))2171 {2172 ShClBackendTransferDestroy(pClient->pBackend, pClient, pTransfer);2173 ShClTransferDestroy(pTransfer);2174 pTransfer = NULL;2175 }2176 2177 if (RT_SUCCESS(rc))2178 rc = rc2;2179 2180 if (RT_FAILURE(rc))2181 LogRel(("Shared Clipboard: Stopping transfer %RU32 failed with rc=%Rrc\n",2182 pTransfer->State.uID, rc));2183 2184 2485 shClSvcClientUnlock(pClient); 2185 2486 … … 2213 2514 AssertPtr(pClient); 2214 2515 2215 shClSvc ClientTransfersReset(pClient);2516 shClSvcTransferDestroyAll(pClient); 2216 2517 2217 2518 ++itClient; -
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-transfers.h
r98103 r100367 32 32 #endif 33 33 34 int shClSvcTransferModeSet(uint32_t fMode); 35 int ShClSvcTransferCreate(PSHCLCLIENT pClient, SHCLTRANSFERDIR enmDir, SHCLSOURCE enmSource, SHCLTRANSFERID idTransfer, PSHCLTRANSFER *ppTransfer); 36 void ShClSvcTransferDestroy(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer); 37 int ShClSvcTransferInit(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer); 38 int ShClSvcTransferStart(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer); 39 int ShClSvcTransferStop(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer, bool fWaitForGuest); 40 int ShClSvcTransferSendStatusAsync(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer, SHCLTRANSFERSTATUS uStatus, int rcTransfer, PSHCLEVENT *ppEvent); 41 int ShClSvcTransferRootListReadFromGuest(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer); 42 bool shClSvcTransferMsgIsAllowed(uint32_t uMode, uint32_t uMsg); 43 void shClSvcTransferDestroyAll(PSHCLCLIENT pClient); 44 34 45 #endif /* !VBOX_INCLUDED_SRC_SharedClipboard_VBoxSharedClipboardSvc_transfers_h */ 35 46 -
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-win.cpp
r100205 r100367 166 166 LogFlowFunc(("uFmt=%#x\n", uFmt)); 167 167 168 int rc; 169 170 PSHCLEVENT pEvent; 171 rc = ShClSvcReadDataFromGuestAsync(pCtx->pClient, uFmt, &pEvent); 172 if (RT_SUCCESS(rc)) 173 { 174 PSHCLEVENTPAYLOAD pPayload; 175 rc = ShClEventWait(pEvent, SHCL_TIMEOUT_DEFAULT_MS, &pPayload); 176 if (RT_SUCCESS(rc)) 177 { 178 if (ppvData) 179 *ppvData = pPayload ? pPayload->pvData : NULL; 180 if (pcbData) 181 *pcbData = pPayload ? pPayload->cbData : 0; 182 } 183 184 ShClEventRelease(pEvent); 185 } 186 168 int rc = ShClSvcReadDataFromGuest(pCtx->pClient, uFmt, &pEvent); 187 169 if (RT_FAILURE(rc)) 188 170 LogRel(("Shared Clipboard: Reading guest clipboard data for Windows host failed with %Rrc\n", rc)); … … 231 213 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 232 214 /** 233 * @copydoc SHCLTRANSFERCALLBACKS::pfnOn Start234 * 235 * Called on transfer start to notify the "in-flight" IDataObject about a startedtransfer.215 * @copydoc SHCLTRANSFERCALLBACKS::pfnOnInitialized 216 * 217 * Called on transfer intialization to notify the "in-flight" IDataObject about a data transfer. 236 218 * 237 219 * @thread Service main thread. 238 220 */ 239 static DECLCALLBACK(void) vboxClipboardSvcWinTransfer StartedCallback(PSHCLTRANSFERCALLBACKCTX pCbCtx)221 static DECLCALLBACK(void) vboxClipboardSvcWinTransferInitializedCallback(PSHCLTRANSFERCALLBACKCTX pCbCtx) 240 222 { 241 223 PSHCLCONTEXT pCtx = (PSHCLCONTEXT)pCbCtx->pvUser; … … 259 241 SharedClipboardWinDataObject *pObj = pCtx->Win.pDataObjInFlight; 260 242 AssertPtrReturnVoid(pObj); 261 rc = pObj->Set AndStartTransfer(pTransfer);243 rc = pObj->SetTransfer(pTransfer); 262 244 263 245 pCtx->Win.pDataObjInFlight = NULL; /* Hand off to Windows. */ … … 272 254 273 255 LogFlowFunc(("LEAVE: idTransfer=%RU32, rc=%Rrc\n", ShClTransferGetID(pTransfer), rc)); 256 } 257 258 /** 259 * @copydoc SHCLTRANSFERCALLBACKS::pfnOnDestroy 260 * 261 * @thread Service main thread. 262 */ 263 static DECLCALLBACK(void) vboxClipboardSvcWinTransferDestroyCallback(PSHCLTRANSFERCALLBACKCTX pCbCtx) 264 { 265 PSHCLCONTEXT pCtx = (PSHCLCONTEXT)pCbCtx->pvUser; 266 AssertPtr(pCtx); 267 268 PSHCLTRANSFER pTransfer = pCbCtx->pTransfer; 269 AssertPtr(pTransfer); 270 271 SharedClipboardWinTransferDestroy(&pCtx->Win, pTransfer); 272 } 273 274 /** 275 * @copydoc SHCLTRANSFERCALLBACKS::pfnOnStarted 276 * 277 * @thread Service main thread. 278 */ 279 static DECLCALLBACK(void) vboxClipboardSvcWinTransferStartedCallback(PSHCLTRANSFERCALLBACKCTX pCbCtx) 280 { 281 PSHCLCONTEXT pCtx = (PSHCLCONTEXT)pCbCtx->pvUser; 282 AssertPtr(pCtx); 283 284 PSHCLTRANSFER pTransfer = pCbCtx->pTransfer; 285 AssertPtr(pTransfer); 286 287 if (ShClTransferGetDir(pTransfer) == SHCLTRANSFERDIR_FROM_REMOTE) /* G->H */ 288 { 289 /* Report to the guest that we now entered the STARTED state. */ 290 ShClSvcTransferStart(pCtx->pClient, pTransfer); 291 } 274 292 } 275 293 #endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */ … … 385 403 void *pvData = NULL; 386 404 uint32_t cbData = 0; 387 int rc = vboxClipboardSvcWinReadDataFromGuest(pCtx, uFormat, &pvData, &cbData);405 int rc = ShClSvcReadDataFromGuest(pCtx->pClient, uFormat, &pvData, &cbData); 388 406 if ( RT_SUCCESS(rc) 389 407 && pvData … … 440 458 441 459 int rc = SharedClipboardWinClearAndAnnounceFormats(pWinCtx, fFormats, hWnd); 442 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS443 if ( RT_SUCCESS(rc)444 && fFormats & VBOX_SHCL_FMT_URI_LIST)445 {446 /*447 * The host requested data from the guest as URI list.448 *449 * This means on Windows we450 * - need to first create an own IDataObject and push it on the clipboard451 * - register a transfer locally so that we have a valid ID for it452 *453 * That way Windows will recognize that there is a data transfer "in flight".454 *455 * As soon as the user requests to "paste" the data (transfer), the IDataObject will try to read data via456 * the pfnOnRequestDataFromSource callback.457 */458 SHCLCALLBACKS Callbacks;459 RT_ZERO(Callbacks);460 Callbacks.pfnOnRequestDataFromSource = vboxClipboardSvcWinRequestDataFromSourceCallback;461 462 rc = SharedClipboardWinTransferCreateAndSetDataObject(pWinCtx, pCtx, &Callbacks);463 }464 #endif465 460 if (RT_FAILURE(rc)) 466 461 LogRel(("Shared Clipboard: Reporting clipboard formats %#x to Windows host failed with %Rrc\n", fFormats, rc)); … … 739 734 */ 740 735 RT_ZERO(pClient->Transfers.Callbacks); 741 pClient->Transfers.Callbacks.pfnOnStarted = vboxClipboardSvcWinTransferStartedCallback; 736 pClient->Transfers.Callbacks.pfnOnInitialized = vboxClipboardSvcWinTransferInitializedCallback; 737 pClient->Transfers.Callbacks.pfnOnStarted = vboxClipboardSvcWinTransferStartedCallback; 738 pClient->Transfers.Callbacks.pfnOnDestroy = vboxClipboardSvcWinTransferDestroyCallback; 742 739 743 740 pClient->Transfers.Callbacks.pvUser = pCtx; /* Assign context as user-provided callback data. */ … … 973 970 974 971 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 975 int ShClBackendTransferCreate(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer) 976 { 977 RT_NOREF(pBackend, pClient, pTransfer); 978 979 LogFlowFuncEnter(); 980 981 return VINF_SUCCESS; 982 } 983 984 int ShClBackendTransferDestroy(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer) 985 { 986 RT_NOREF(pBackend); 987 988 LogFlowFuncEnter(); 989 990 SharedClipboardWinTransferDestroy(&pClient->State.pCtx->Win, pTransfer); 991 992 return VINF_SUCCESS; 993 } 994 995 int ShClBackendTransferGetRoots(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer) 972 int ShClBackendTransferHGRootListRead(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer) 996 973 { 997 974 RT_NOREF(pBackend); -
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-x11.cpp
r100237 r100367 44 44 #include <iprt/errcore.h> 45 45 46 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS _HTTP46 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 47 47 # include <VBox/GuestHost/SharedClipboard-transfers.h> 48 # ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS_HTTP 49 # include <VBox/GuestHost/SharedClipboard-transfers.h> 50 # endif 48 51 #endif 49 52 50 53 #include "VBoxSharedClipboardSvc-internal.h" 54 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 55 # include "VBoxSharedClipboardSvc-transfers.h" 56 #endif 51 57 52 58 /* Number of currently extablished connections. */ … … 81 87 static DECLCALLBACK(int) shClSvcX11RequestDataFromSourceCallback(PSHCLCONTEXT pCtx, SHCLFORMAT uFmt, void **ppv, uint32_t *pcb, void *pvUser); 82 88 89 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 90 static DECLCALLBACK(void) shClSvcX11OnTransferInitCallback(PSHCLTRANSFERCALLBACKCTX pCbCtx); 91 static DECLCALLBACK(void) shClSvcX11OnTransferDestroyCallback(PSHCLTRANSFERCALLBACKCTX pCbCtx); 92 static DECLCALLBACK(void) shClSvcX11OnTransferUnregisteredCallback(PSHCLTRANSFERCALLBACKCTX pCbCtx, PSHCLTRANSFERCTX pTransferCtx); 93 #endif 94 83 95 84 96 int ShClBackendInit(PSHCLBACKEND pBackend, VBOXHGCMSVCFNTABLE *pTable) … … 146 158 pClient->State.pCtx = pCtx; 147 159 pCtx->pClient = pClient; 160 161 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 162 /* 163 * Set callbacks. 164 * Those will be registered within ShClSvcTransferInit() when a new transfer gets initialized. 165 * 166 * Used for starting / stopping the HTTP server. 167 */ 168 RT_ZERO(pClient->Transfers.Callbacks); 169 170 pClient->Transfers.Callbacks.pvUser = pCtx; /* Assign context as user-provided callback data. */ 171 pClient->Transfers.Callbacks.cbUser = sizeof(SHCLCONTEXT); 172 173 pClient->Transfers.Callbacks.pfnOnInitialized = shClSvcX11OnTransferInitCallback; 174 pClient->Transfers.Callbacks.pfnOnDestroy = shClSvcX11OnTransferDestroyCallback; 175 pClient->Transfers.Callbacks.pfnOnUnregistered = shClSvcX11OnTransferUnregisteredCallback; 176 #endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */ 148 177 149 178 rc = ShClX11ThreadStart(&pCtx->X11, true /* grab shared clipboard */); … … 352 381 } 353 382 383 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 384 /** 385 * @copydoc SHCLTRANSFERCALLBACKS::pfnOnInitialized 386 * 387 * This starts the HTTP server if not done yet and registers the transfer with it. 388 * 389 * @thread Service main thread. 390 */ 391 static DECLCALLBACK(void) shClSvcX11OnTransferInitCallback(PSHCLTRANSFERCALLBACKCTX pCbCtx) 392 { 393 RT_NOREF(pCbCtx); 394 395 #if 1 396 LogFlowFuncEnter(); 397 398 PSHCLCONTEXT pCtx = (PSHCLCONTEXT)pCbCtx->pvUser; 399 AssertPtr(pCtx); 400 401 PSHCLTRANSFER pTransfer = pCbCtx->pTransfer; 402 AssertPtr(pTransfer); 403 404 switch (ShClTransferGetDir(pTransfer)) 405 { 406 case SHCLTRANSFERDIR_FROM_REMOTE: /* G->H */ 407 { 408 # ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS_HTTP 409 /* We only need to start the HTTP server when we actually receive data from the remote (host). */ 410 ShClTransferHttpServerMaybeStart(&pCtx->X11.HttpCtx); 411 # endif 412 break; 413 } 414 415 case SHCLTRANSFERDIR_TO_REMOTE: /* H->G */ 416 { 417 PSHCLEVENT pEvent; 418 int rc = ShClEventSourceGenerateAndRegisterEvent(&pCtx->pClient->EventSrc, &pEvent); 419 if (RT_SUCCESS(rc)) 420 { 421 rc = ShClX11ReadDataFromX11Async(&pCtx->X11, VBOX_SHCL_FMT_URI_LIST, UINT32_MAX, pEvent); 422 if (RT_SUCCESS(rc)) 423 { 424 /* X supplies the data asynchronously, so we need to wait for data to arrive first. */ 425 PSHCLEVENTPAYLOAD pPayload; 426 rc = ShClEventWait(pEvent, SHCL_TIMEOUT_DEFAULT_MS, &pPayload); 427 if (RT_SUCCESS(rc)) 428 { 429 if (pPayload) 430 { 431 Assert(pPayload->cbData == sizeof(SHCLX11RESPONSE)); 432 AssertPtr(pPayload->pvData); 433 PSHCLX11RESPONSE pResp = (PSHCLX11RESPONSE)pPayload->pvData; 434 435 rc = ShClTransferRootsInitFromStringList(pTransfer, 436 (char *)pResp->Read.pvData, pResp->Read.cbData + 1 /* Include zero terminator */); 437 //if (RT_SUCCESS(rc)) 438 // rc = ShClTransferRootListRead(pTransfer); 439 440 if (RT_SUCCESS(rc)) 441 LogRel2(("Shared Clipboard: Host reported %RU64 X11 root entries for transfer to guest\n", ShClTransferRootsCount(pTransfer))); 442 443 RTMemFree(pResp->Read.pvData); 444 pResp->Read.cbData = 0; 445 446 ShClPayloadFree(pPayload); 447 pPayload = NULL; 448 } 449 else 450 rc = VERR_NO_DATA; /* No payload. */ 451 } 452 } 453 454 ShClEventRelease(pEvent); 455 } 456 else 457 rc = VERR_SHCLPB_MAX_EVENTS_REACHED; 458 break; 459 } 460 461 default: 462 break; 463 } 464 465 LogFlowFuncLeave(); 466 } 467 468 /** 469 * @copydoc SHCLTRANSFERCALLBACKS::pfnOnDestroy 470 * 471 * This stops the HTTP server if not done yet. 472 * 473 * @thread Service main thread. 474 */ 475 static DECLCALLBACK(void) shClSvcX11OnTransferDestroyCallback(PSHCLTRANSFERCALLBACKCTX pCbCtx) 476 { 477 LogFlowFuncEnter(); 478 479 # ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS_HTTP 480 PSHCLCONTEXT pCtx = (PSHCLCONTEXT)pCbCtx->pvUser; 481 AssertPtr(pCtx); 482 483 PSHCLTRANSFER pTransfer = pCbCtx->pTransfer; 484 AssertPtr(pTransfer); 485 486 if (ShClTransferGetDir(pTransfer) == SHCLTRANSFERDIR_FROM_REMOTE) 487 ShClTransferHttpServerMaybeStop(&pCtx->X11.HttpCtx); 488 # else 489 RT_NOREF(pCbCtx); 490 # endif 491 492 LogFlowFuncLeave(); 493 } 494 495 /** 496 * Unregisters a transfer from a HTTP server. 497 * 498 * This also stops the HTTP server if no active transfers are found anymore. 499 * 500 * @param pCtx Shared clipboard context to unregister transfer for. 501 * @param pTransfer Transfer to unregister. 502 * 503 * @thread Clipboard main thread. 504 */ 505 static void shClSvcX11HttpTransferUnregister(PSHCLCONTEXT pCtx, PSHCLTRANSFER pTransfer) 506 { 507 if (ShClTransferGetDir(pTransfer) == SHCLTRANSFERDIR_FROM_REMOTE) 508 { 509 # ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS_HTTP 510 if (ShClTransferHttpServerIsInitialized(&pCtx->X11.HttpCtx.HttpServer)) 511 { 512 ShClTransferHttpServerUnregisterTransfer(&pCtx->X11.HttpCtx.HttpServer, pTransfer); 513 ShClTransferHttpServerMaybeStop(&pCtx->X11.HttpCtx); 514 } 515 # else 516 RT_NOREF(pCtx); 517 # endif 518 } 519 520 //ShClTransferRelease(pTransfer); 521 } 522 523 /** 524 * @copydoc SHCLTRANSFERCALLBACKS::pfnOnUnregistered 525 * 526 * Unregisters a (now) unregistered transfer from the HTTP server. 527 * 528 * @thread Clipboard main thread. 529 */ 530 static DECLCALLBACK(void) shClSvcX11OnTransferUnregisteredCallback(PSHCLTRANSFERCALLBACKCTX pCbCtx, PSHCLTRANSFERCTX pTransferCtx) 531 { 532 RT_NOREF(pTransferCtx); 533 shClSvcX11HttpTransferUnregister((PSHCLCONTEXT)pCbCtx->pvUser, pCbCtx->pTransfer); 534 } 535 #endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */ 536 354 537 /** 355 538 * @copydoc SHCLCALLBACKS::pfnOnRequestDataFromSource … … 373 556 } 374 557 375 int rc = VINF_SUCCESS; 376 377 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS_HTTP 558 PSHCLCLIENT const pClient = pCtx->pClient; 559 int rc = ShClSvcReadDataFromGuest(pClient, uFmt, ppv, pcb); 560 if (RT_FAILURE(rc)) 561 return rc; 562 378 563 /* 379 * Note: We always return a generic URI list here.564 * Note: We always return a generic URI list (as HTTP links) here. 380 565 * As we don't know which Atom target format was requested by the caller, the X11 clipboard codes needs 381 566 * to decide & transform the list into the actual clipboard Atom target format the caller wanted. 382 567 */ 568 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 383 569 if (uFmt == VBOX_SHCL_FMT_URI_LIST) 384 570 { 385 PSHCLTRANSFER pTransfer = ShClTransferHttpServerGetTransferFirst(&pCtx->X11.HttpCtx.HttpServer); 386 if (pTransfer) 387 { 388 if (RT_SUCCESS(rc)) 389 rc = ShClTransferRootListRead(pTransfer); 390 } 391 392 /** @todo BUGBUG IMPLEMENT THIS! */ 393 394 *ppv = NULL; 395 *pcb = 0; 396 397 rc = VERR_NO_DATA; 398 } 399 #endif 400 401 if (RT_SUCCESS(rc)) 402 { 403 /* Request data from the guest and for data to arrive. */ 404 PSHCLEVENT pEvent; 405 rc = ShClSvcReadDataFromGuestAsync(pCtx->pClient, uFmt, &pEvent); 571 PSHCLTRANSFER pTransfer; 572 rc = ShClSvcTransferCreate(pClient, SHCLTRANSFERDIR_FROM_REMOTE, SHCLSOURCE_REMOTE, 573 NIL_SHCLTRANSFERID /* Creates a new transfer ID */, &pTransfer); 406 574 if (RT_SUCCESS(rc)) 407 575 { 408 PSHCLEVENTPAYLOAD pPayload; 409 rc = ShClEventWait(pEvent, SHCL_TIMEOUT_DEFAULT_MS, &pPayload); 576 /* Initialize the transfer on the host side. */ 577 rc = ShClSvcTransferInit(pClient, pTransfer); 578 if (RT_FAILURE(rc)) 579 ShClSvcTransferDestroy(pClient, pTransfer); 580 } 581 582 if (RT_SUCCESS(rc)) 583 { 584 /* We have to wait for the guest reporting the transfer as being initialized. 585 * Only then we can start reading stuff. */ 586 rc = ShClTransferWaitForStatus(pTransfer, SHCL_TIMEOUT_DEFAULT_MS, SHCLTRANSFERSTATUS_INITIALIZED); 410 587 if (RT_SUCCESS(rc)) 411 588 { 412 if ( !pPayload413 || !pPayload->cbData)589 rc = ShClTransferRootListRead(pTransfer); 590 if (RT_SUCCESS(rc)) 414 591 { 415 rc = VERR_NO_DATA; 416 } 417 else 418 { 419 *ppv = pPayload->pvData; 420 *pcb = pPayload->cbData; 592 # ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS_HTTP 593 /* As soon as we register the transfer with the HTTP server, the transfer needs to have its roots set. */ 594 PSHCLHTTPSERVER const pHttpSrv = &pCtx->X11.HttpCtx.HttpServer; 595 rc = ShClTransferHttpServerRegisterTransfer(pHttpSrv, pTransfer); 596 if (RT_SUCCESS(rc)) 597 { 598 char *pszURL = ShClTransferHttpServerGetUrlA(pHttpSrv, pTransfer->State.uID); 599 if (pszURL) 600 { 601 *ppv = pszURL; 602 *pcb = strlen(pszURL) + 1 /* Include terminator */; 603 604 LogFlowFunc(("URL is '%s'\n", pszURL)); 605 606 /* ppv has ownership of pszURL. */ 607 608 rc = VINF_SUCCESS; 609 } 610 else 611 rc = VERR_NO_MEMORY; 612 } 613 # else 614 rc = VERR_NOT_SUPPORTED; 615 # endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS_HTTP */ 421 616 } 422 617 } 423 424 ShClEventRelease(pEvent); 425 } 426 } 618 } 619 } 620 #endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */ 427 621 428 622 if (RT_FAILURE(rc)) 429 LogRel(("Shared Clipboard: Requesting data in format %#x for X11 host failed with %Rrc\n", uFmt, rc));623 LogRel(("Shared Clipboard: Requesting X11 data in format %#x from guest failed with %Rrc\n", uFmt, rc)); 430 624 431 625 LogFlowFuncLeaveRC(rc); … … 434 628 435 629 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 436 437 int ShClBackendTransferCreate(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer) 630 /** 631 * Handles transfer status replies from the guest. 632 */ 633 int ShClBackendTransferHandleStatusReply(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer, SHCLSOURCE enmSource, SHCLTRANSFERSTATUS enmStatus, int rcStatus) 634 { 635 RT_NOREF(pBackend, pClient, enmSource, rcStatus); 636 637 PSHCLCONTEXT pCtx = pClient->State.pCtx; RT_NOREF(pCtx); 638 639 if (ShClTransferGetDir(pTransfer) == SHCLTRANSFERDIR_FROM_REMOTE) /* Guest -> Host */ 640 { 641 switch (enmStatus) 642 { 643 case SHCLTRANSFERSTATUS_INITIALIZED: 644 { 645 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS_HTTP 646 int rc2 = ShClTransferHttpServerMaybeStart(&pCtx->X11.HttpCtx); 647 if (RT_SUCCESS(rc2)) 648 { 649 650 } 651 652 if (RT_FAILURE(rc2)) 653 LogRel(("Shared Clipboard: Registering HTTP transfer failed: %Rrc\n", rc2)); 654 #endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS_HTTP */ 655 break; 656 } 657 658 default: 659 break; 660 } 661 } 662 663 return VINF_SUCCESS; 664 } 665 666 int ShClBackendTransferHGRootListRead(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer) 438 667 { 439 668 RT_NOREF(pBackend); 440 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS_HTTP 441 /* We only need to start the HTTP server (and register the transfer to it) when we actually receive data from the guest. */ 442 if (ShClTransferGetDir(pTransfer) == SHCLTRANSFERDIR_FROM_REMOTE)443 return ShClTransferHttpServerMaybeStart(&pClient->State.pCtx->X11.HttpCtx);669 670 #if 1 671 RT_NOREF(pClient, pTransfer); 672 int rc = 0; 444 673 #else 445 RT_NOREF(pClient, pTransfer);446 #endif447 return VINF_SUCCESS;448 }449 450 int ShClBackendTransferDestroy(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer)451 {452 RT_NOREF(pBackend);453 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS_HTTP454 /* See comment in ShClBackendTransferCreate(). */455 if (ShClTransferGetDir(pTransfer) == SHCLTRANSFERDIR_FROM_REMOTE)456 return ShClTransferHttpServerMaybeStop(&pClient->State.pCtx->X11.HttpCtx);457 #else458 RT_NOREF(pClient, pTransfer);459 #endif460 return VINF_SUCCESS;461 }462 463 int ShClBackendTransferGetRoots(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer)464 {465 RT_NOREF(pBackend);466 467 674 LogFlowFuncEnter(); 468 675 … … 508 715 else 509 716 rc = VERR_SHCLPB_MAX_EVENTS_REACHED; 717 #endif 510 718 511 719 LogFlowFuncLeaveRC(rc); -
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc.cpp
r100204 r100367 614 614 615 615 /* Make sure to send a quit message to the guest so that it can terminate gracefully. */ 616 RTCritSectEnter(&pClient->CritSect); 616 shClSvcClientLock(pClient); 617 617 618 if (pClient->Pending.uType) 618 619 { … … 627 628 pClient->Pending.paParms = NULL; 628 629 } 629 RTCritSectLeave(&pClient->CritSect); 630 631 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 632 shClSvcTransferDestroyAll(pClient); 633 ShClTransferCtxDestroy(&pClient->Transfers.Ctx); 634 #endif 630 635 631 636 ShClEventSourceDestroy(&pClient->EventSrc); 637 638 shClSvcClientUnlock(pClient); 632 639 633 640 shClSvcClientStateDestroy(&pClient->State); … … 635 642 PSHCLCLIENTLEGACYCID pCidIter, pCidIterNext; 636 643 RTListForEachSafe(&pClient->Legacy.lstCID, pCidIter, pCidIterNext, SHCLCLIENTLEGACYCID, Node) 637 {638 644 RTMemFree(pCidIter); 639 }640 645 641 646 int rc2 = RTCritSectDelete(&pClient->CritSect); … … 686 691 687 692 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 688 shClSvc ClientTransfersReset(pClient);693 shClSvcTransferDestroyAll(pClient); 689 694 #endif 690 695 … … 1220 1225 1221 1226 /** 1222 * Re quests to read clipboard data from the guest.1227 * Reads clipboard data from the guest, asynchronous version. 1223 1228 * 1224 1229 * @returns VBox status code. … … 1330 1335 } 1331 1336 1332 #if def VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS1337 #if 0 /* ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */ 1333 1338 /* 1334 1339 * When the host wants to read URI data from the guest: 1335 1340 * - Initialize a transfer locally. 1336 1341 * - Request URI data from the guest; this tells the guest to initialize a transfer on the guest side. 1337 * - Start the transfer locally once we receive the transfer STARTED status from the guest via VBOX_SHCL_GUEST_FN_REPLY. 1342 * - Start the transfer locally once we receive the transfer INITIALIZED status from the guest via VBOX_SHCL_GUEST_FN_REPLY. 1343 * 1344 * When this function returns, the X11 clipboard will try reading the data, so we need to make sure that 1345 * - the local HTTP server is up and running (will be done in ShClBackendTransferCreate() on X11) 1346 * - the right (HTTP) URL data is filled into the clipboard 1347 * by then. 1338 1348 */ 1339 1349 if ( RT_SUCCESS(rc) 1340 && fFormat == VBOX_SHCL_FMT_URI_LIST)1350 && (fFormat & VBOX_SHCL_FMT_URI_LIST)) 1341 1351 { 1342 rc = shClSvcTransferInit(pClient, SHCLTRANSFERDIR_FROM_REMOTE, SHCLSOURCE_REMOTE,1343 NULL /* pTransfer */);1352 PSHCLTRANSFER pTransfer; 1353 rc = ShClSvcTransferInit(pClient, SHCLTRANSFERDIR_FROM_REMOTE, SHCLSOURCE_REMOTE, &pTransfer); 1344 1354 if (RT_SUCCESS(rc)) 1345 1355 rc = shClSvcSetSource(pClient, SHCLSOURCE_REMOTE); … … 1381 1391 1382 1392 /** 1393 * Reads clipboard data from the guest. 1394 * 1395 * @returns VBox status code. 1396 * @param pClient Client to request to read data form. 1397 * @param fFormats The formats being requested, OR'ed together (VBOX_SHCL_FMT_XXX). 1398 * @param ppv Where to return the allocated data read. 1399 * Must be free'd by the caller. 1400 * @param pcb Where to return number of bytes read. 1401 */ 1402 int ShClSvcReadDataFromGuest(PSHCLCLIENT pClient, SHCLFORMAT fFormats, void **ppv, uint32_t *pcb) 1403 { 1404 LogFlowFuncEnter(); 1405 1406 /* Request data from the guest and wait for data to arrive. */ 1407 PSHCLEVENT pEvent; 1408 int rc = ShClSvcReadDataFromGuestAsync(pClient, fFormats, &pEvent); 1409 if (RT_SUCCESS(rc)) 1410 { 1411 PSHCLEVENTPAYLOAD pPayload; 1412 rc = ShClEventWait(pEvent, SHCL_TIMEOUT_DEFAULT_MS, &pPayload); 1413 if (RT_SUCCESS(rc)) 1414 { 1415 if ( !pPayload 1416 || !pPayload->cbData) 1417 { 1418 rc = VERR_NO_DATA; 1419 } 1420 else 1421 { 1422 *ppv = pPayload->pvData; 1423 *pcb = pPayload->cbData; 1424 } 1425 } 1426 1427 ShClEventRelease(pEvent); 1428 } 1429 1430 if (RT_FAILURE(rc)) 1431 LogRel(("Shared Clipboard: Reading data from guest failed with %Rrc\n", rc)); 1432 1433 LogFlowFuncLeaveRC(rc); 1434 return rc; 1435 } 1436 1437 /** 1383 1438 * Signals the host that clipboard data from the guest has been received. 1384 1439 * … … 1575 1630 */ 1576 1631 int rc; 1577 if (!fFormats && pClient->State.enmSource != SHCLSOURCE_REMOTE)1632 if (!fFormats) 1578 1633 rc = VINF_SUCCESS; 1579 1634 else 1580 1635 { 1581 rc = shClSvcSetSource(pClient, SHCLSOURCE_REMOTE);1636 rc = RTCritSectEnter(&g_CritSect); 1582 1637 if (RT_SUCCESS(rc)) 1583 1638 { 1584 rc = RTCritSectEnter(&g_CritSect); 1585 if (RT_SUCCESS(rc)) 1639 if (g_ExtState.pfnExtension) 1586 1640 { 1587 if (g_ExtState.pfnExtension) 1588 { 1589 SHCLEXTPARMS parms; 1590 RT_ZERO(parms); 1591 parms.uFormat = fFormats; 1592 1593 g_ExtState.pfnExtension(g_ExtState.pvExtension, VBOX_CLIPBOARD_EXT_FN_FORMAT_ANNOUNCE, &parms, sizeof(parms)); 1594 } 1595 else 1596 { 1597 #ifdef LOG_ENABLED 1598 char *pszFmts = ShClFormatsToStrA(fFormats); 1599 if (pszFmts) 1600 { 1601 LogRel2(("Shared Clipboard: Guest reported formats '%s' to host\n", pszFmts)); 1602 RTStrFree(pszFmts); 1603 } 1604 #endif 1605 rc = ShClBackendReportFormats(&g_ShClBackend, pClient, fFormats); 1606 if (RT_FAILURE(rc)) 1607 LogRel(("Shared Clipboard: Reporting guest clipboard formats to the host failed with %Rrc\n", rc)); 1608 } 1609 1610 RTCritSectLeave(&g_CritSect); 1641 SHCLEXTPARMS parms; 1642 RT_ZERO(parms); 1643 parms.uFormat = fFormats; 1644 1645 g_ExtState.pfnExtension(g_ExtState.pvExtension, VBOX_CLIPBOARD_EXT_FN_FORMAT_ANNOUNCE, &parms, sizeof(parms)); 1611 1646 } 1612 1647 else 1613 LogRel2(("Shared Clipboard: Unable to take internal lock while receiving guest clipboard announcement: %Rrc\n", rc)); 1614 } 1648 { 1649 #ifdef LOG_ENABLED 1650 char *pszFmts = ShClFormatsToStrA(fFormats); 1651 if (pszFmts) 1652 { 1653 LogRel2(("Shared Clipboard: Guest reported formats '%s' to host\n", pszFmts)); 1654 RTStrFree(pszFmts); 1655 } 1656 #endif 1657 rc = ShClBackendReportFormats(&g_ShClBackend, pClient, fFormats); 1658 if (RT_FAILURE(rc)) 1659 LogRel(("Shared Clipboard: Reporting guest clipboard formats to the host failed with %Rrc\n", rc)); 1660 } 1661 1662 RTCritSectLeave(&g_CritSect); 1663 } 1664 else 1665 LogRel2(("Shared Clipboard: Unable to take internal lock while receiving guest clipboard announcement: %Rrc\n", rc)); 1615 1666 } 1616 1667 … … 1762 1813 else 1763 1814 LogRel(("Shared Clipboard: Reading host clipboard data failed with %Rrc\n", rc)); 1764 1765 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS1766 /*1767 * When we receive a read request for URI data:1768 * - Initialize a transfer locally.1769 * - Tell the guest to initialize a transfer on the guest side.1770 * - Start the transfer locally once we receive the transfer STARTED status from the guest via VBOX_SHCL_GUEST_FN_REPLY.1771 */1772 if (uFormat == VBOX_SHCL_FMT_URI_LIST) /* Only init a transfer if we supply an URI list. */1773 {1774 shClSvcClientLock(pClient);1775 1776 rc = shClSvcTransferInit(pClient, SHCLTRANSFERDIR_TO_REMOTE, SHCLSOURCE_LOCAL,1777 NULL /* pTransfer */);1778 if (RT_SUCCESS(rc))1779 rc = shClSvcSetSource(pClient, SHCLSOURCE_LOCAL);1780 1781 if (RT_FAILURE(rc))1782 LogRel(("Shared Clipboard: Initializing host -> guest transfer failed with %Rrc\n", rc));1783 1784 shClSvcClientUnlock(pClient);1785 }1786 #endif1787 1815 } 1788 1816 … … 1998 2026 } 1999 2027 2000 /**2001 * Sets the transfer source type of a Shared Clipboard client.2002 *2003 * @returns VBox status code.2004 * @param pClient Client to set transfer source type for.2005 * @param enmSource Source type to set.2006 */2007 int shClSvcSetSource(PSHCLCLIENT pClient, SHCLSOURCE enmSource)2008 {2009 if (!pClient) /* If no client connected (anymore), bail out. */2010 return VINF_SUCCESS;2011 2012 int rc = VINF_SUCCESS;2013 2014 pClient->State.enmSource = enmSource;2015 2016 LogFlowFunc(("Source of client %RU32 is now %RU32\n", pClient->State.uClientID, pClient->State.enmSource));2017 2018 LogFlowFuncLeaveRC(rc);2019 return rc;2020 }2021 2022 2028 static int svcInit(VBOXHGCMSVCFNTABLE *pTable) 2023 2029 { … … 2069 2075 g_ExtState.uClientID = 0; 2070 2076 } 2071 2072 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS2073 shClSvcClientTransfersReset(pClient);2074 #endif2075 2077 2076 2078 ShClBackendDisconnect(&g_ShClBackend, pClient); … … 2250 2252 2251 2253 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 2252 shClSvcClientTransfersReset(pClient); 2254 /* Reset transfer state. */ 2255 shClSvcTransferDestroyAll(pClient); 2253 2256 #endif 2254 2257 shClSvcClientUnlock(pClient); -
trunk/src/VBox/HostServices/SharedClipboard/testcase/tstClipboardServiceHost.cpp
r100204 r100367 330 330 331 331 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS 332 int ShClBackendTransferCreate(PSHCLBACKEND, PSHCLCLIENT, PSHCLTRANSFER) { return VINF_SUCCESS; } 333 int ShClBackendTransferDestroy(PSHCLBACKEND, PSHCLCLIENT, PSHCLTRANSFER) { return VINF_SUCCESS; } 334 int ShClBackendTransferGetRoots(PSHCLBACKEND, PSHCLCLIENT, PSHCLTRANSFER) { return VINF_SUCCESS; } 332 int ShClBackendTransferHandleStatusReply(PSHCLBACKEND, PSHCLCLIENT, PSHCLTRANSFER, SHCLSOURCE, SHCLTRANSFERSTATUS, int) { return VINF_SUCCESS; } 333 int ShClBackendTransferHGRootListRead(PSHCLBACKEND, PSHCLCLIENT, PSHCLTRANSFER) { return VINF_SUCCESS; } 335 334 #endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */ 336 335 -
trunk/src/VBox/HostServices/SharedClipboard/testcase/tstClipboardTransfers.cpp
r100204 r100367 212 212 { 213 213 PSHCLTRANSFER pTransfer; 214 int rc = ShClTransferCreate( &pTransfer);214 int rc = ShClTransferCreate(SHCLTRANSFERDIR_TO_REMOTE, SHCLSOURCE_LOCAL, &pTransfer); 215 215 RTTESTI_CHECK_RC_OK(rc); 216 216 217 217 SHCLTXPROVIDER Provider; 218 RTTESTI_CHECK( VBClTransferProviderLocalQueryInterface(&Provider) != NULL);218 RTTESTI_CHECK(ShClTransferProviderLocalQueryInterface(&Provider) != NULL); 219 219 RTTESTI_CHECK_RC_OK(ShClTransferSetProvider(pTransfer, &Provider)); 220 220 … … 246 246 247 247 PSHCLTRANSFER pTransfer; 248 int rc = ShClTransferCreate( &pTransfer);248 int rc = ShClTransferCreate(SHCLTRANSFERDIR_TO_REMOTE, SHCLSOURCE_LOCAL, &pTransfer); 249 249 RTTESTI_CHECK_RC_OK(rc); 250 250 251 251 SHCLTXPROVIDER Provider; 252 VBClTransferProviderLocalQueryInterface(&Provider);252 ShClTransferProviderLocalQueryInterface(&Provider); 253 253 254 254 rc = ShClTransferSetProvider(pTransfer, &Provider); 255 255 RTTESTI_CHECK_RC_OK(rc); 256 256 257 rc = ShClTransferInit(pTransfer , SHCLTRANSFERDIR_FROM_REMOTE, SHCLSOURCE_LOCAL);257 rc = ShClTransferInit(pTransfer); 258 258 RTTESTI_CHECK_RC_OK(rc); 259 259 … … 309 309 RTTESTI_CHECK_RC_OK(rc); 310 310 PSHCLTRANSFER pTransfer; 311 rc = ShClTransferCreate( &pTransfer);311 rc = ShClTransferCreate(SHCLTRANSFERDIR_TO_REMOTE, SHCLSOURCE_LOCAL, &pTransfer); 312 312 RTTESTI_CHECK_RC_OK(rc); 313 313 rc = ShClTransferDestroy(pTransfer); … … 318 318 PSHCLLIST pList = ShClTransferListAlloc(); 319 319 RTTESTI_CHECK(pList != NULL); 320 rc = ShClTransferCreate( &pTransfer);320 rc = ShClTransferCreate(SHCLTRANSFERDIR_TO_REMOTE, SHCLSOURCE_LOCAL, &pTransfer); 321 321 RTTESTI_CHECK_RC_OK(rc); 322 322 ShClTransferListFree(pList); -
trunk/src/VBox/Runtime/r3/http-server.cpp
r100250 r100367 689 689 case VERR_IS_A_DIRECTORY: return RTHTTPSTATUS_FORBIDDEN; 690 690 case VERR_NOT_FOUND: return RTHTTPSTATUS_NOTFOUND; 691 case VERR_INTERNAL_ERROR: return RTHTTPSTATUS_INTERNALSERVERERROR; 691 692 default: 692 693 break; … … 713 714 LogFlowFuncEnter(); 714 715 715 int rc = VINF_SUCCESS;716 717 716 /* If a low-level GET request handler is defined, call it and return. */ 718 717 RTHTTPSERVER_HANDLE_CALLBACK_VA_RET(pfnOnGetRequest, pReq); … … 723 722 char *pszMIMEHint = NULL; 724 723 724 RTHTTPSTATUS enmStsResponse = RTHTTPSTATUS_OK; 725 726 int rc; 727 725 728 RTHTTPSERVER_HANDLE_CALLBACK_VA(pfnQueryInfo, pReq, &fsObj, &pszMIMEHint); 726 729 if (RT_FAILURE(rc)) 727 return rc;730 enmStsResponse = rtHttpServerRcToStatus(rc); 728 731 729 732 void *pvHandle = NULL; 730 RTHTTPSERVER_HANDLE_CALLBACK_VA(pfnOpen, pReq, &pvHandle); 731 732 if (RT_SUCCESS(rc)) 733 { 734 size_t cbBuf = _64K; 735 void *pvBuf = RTMemAlloc(cbBuf); 736 AssertPtrReturn(pvBuf, VERR_NO_MEMORY); 737 738 for (;;) 739 { 740 RTHTTPHEADERLIST HdrLst; 741 rc = RTHttpHeaderListInit(&HdrLst); 733 if (RT_SUCCESS(rc)) /* Only call open if querying information above succeeded. */ 734 RTHTTPSERVER_HANDLE_CALLBACK_VA(pfnOpen, pReq, &pvHandle); 735 736 size_t cbBuf = _64K; 737 void *pvBuf = RTMemAlloc(cbBuf); 738 AssertPtrReturn(pvBuf, VERR_NO_MEMORY); 739 740 for (;;) 741 { 742 RTHTTPHEADERLIST HdrLst; 743 rc = RTHttpHeaderListInit(&HdrLst); 744 AssertRCReturn(rc, rc); 745 746 char szVal[16]; 747 748 /* Note: For directories fsObj.cbObject contains the actual size (in bytes) 749 * of the body data for the directory listing. */ 750 751 ssize_t cch = RTStrPrintf2(szVal, sizeof(szVal), "%RU64", fsObj.cbObject); 752 AssertBreakStmt(cch, VERR_BUFFER_OVERFLOW); 753 rc = RTHttpHeaderListAdd(HdrLst, "Content-Length", szVal, strlen(szVal), RTHTTPHEADERLISTADD_F_BACK); 754 AssertRCBreak(rc); 755 756 cch = RTStrPrintf2(szVal, sizeof(szVal), "identity"); 757 AssertBreakStmt(cch, VERR_BUFFER_OVERFLOW); 758 rc = RTHttpHeaderListAdd(HdrLst, "Content-Encoding", szVal, strlen(szVal), RTHTTPHEADERLISTADD_F_BACK); 759 AssertRCBreak(rc); 760 761 if (pszMIMEHint == NULL) 762 { 763 const char *pszMIME = rtHttpServerGuessMIMEType(RTPathSuffix(pReq->pszUrl)); 764 rc = RTHttpHeaderListAdd(HdrLst, "Content-Type", pszMIME, strlen(pszMIME), RTHTTPHEADERLISTADD_F_BACK); 765 } 766 else 767 { 768 rc = RTHttpHeaderListAdd(HdrLst, "Content-Type", pszMIMEHint, strlen(pszMIMEHint), RTHTTPHEADERLISTADD_F_BACK); 769 RTStrFree(pszMIMEHint); 770 pszMIMEHint = NULL; 771 } 772 AssertRCBreak(rc); 773 774 if (pClient->State.msKeepAlive) 775 { 776 /* If the client requested to keep alive the connection, 777 * always override this with 30s and report this back to the client. */ 778 pClient->State.msKeepAlive = RT_MS_30SEC; /** @todo Make this configurable. */ 779 #ifdef DEBUG_andy 780 pClient->State.msKeepAlive = 5000; 781 #endif 782 cch = RTStrPrintf2(szVal, sizeof(szVal), "timeout=%RU64", pClient->State.msKeepAlive / RT_MS_1SEC); /** @todo No pipelining support here yet. */ 783 AssertBreakStmt(cch, VERR_BUFFER_OVERFLOW); 784 rc = RTHttpHeaderListAdd(HdrLst, "Keep-Alive", szVal, strlen(szVal), RTHTTPHEADERLISTADD_F_BACK); 742 785 AssertRCReturn(rc, rc); 743 744 char szVal[16]; 745 746 /* Note: For directories fsObj.cbObject contains the actual size (in bytes) 747 * of the body data for the directory listing. */ 748 749 ssize_t cch = RTStrPrintf2(szVal, sizeof(szVal), "%RU64", fsObj.cbObject); 750 AssertBreakStmt(cch, VERR_BUFFER_OVERFLOW); 751 rc = RTHttpHeaderListAdd(HdrLst, "Content-Length", szVal, strlen(szVal), RTHTTPHEADERLISTADD_F_BACK); 752 AssertRCBreak(rc); 753 754 cch = RTStrPrintf2(szVal, sizeof(szVal), "identity"); 755 AssertBreakStmt(cch, VERR_BUFFER_OVERFLOW); 756 rc = RTHttpHeaderListAdd(HdrLst, "Content-Encoding", szVal, strlen(szVal), RTHTTPHEADERLISTADD_F_BACK); 757 AssertRCBreak(rc); 758 759 if (pszMIMEHint == NULL) 786 } 787 788 rc = rtHttpServerSendResponseEx(pClient, enmStsResponse, &HdrLst); 789 790 RTHttpHeaderListDestroy(HdrLst); 791 792 if (rc == VERR_BROKEN_PIPE) /* Could happen on fast reloads. */ 793 break; 794 AssertRCReturn(rc, rc); 795 796 size_t cbToRead = fsObj.cbObject; 797 size_t cbRead = 0; /* Shut up GCC. */ 798 size_t cbWritten = 0; /* Ditto. */ 799 while (cbToRead) 800 { 801 RTHTTPSERVER_HANDLE_CALLBACK_VA(pfnRead, pReq, pvHandle, pvBuf, RT_MIN(cbBuf, cbToRead), &cbRead); 802 if (RT_FAILURE(rc)) 803 break; 804 rc = rtHttpServerSendResponseBody(pClient, pvBuf, cbRead, &cbWritten); 805 AssertBreak(cbToRead >= cbWritten); 806 cbToRead -= cbWritten; 807 if (rc == VERR_NET_CONNECTION_RESET_BY_PEER) /* Clients often apruptly abort the connection when done. */ 760 808 { 761 const char *pszMIME = rtHttpServerGuessMIMEType(RTPathSuffix(pReq->pszUrl)); 762 rc = RTHttpHeaderListAdd(HdrLst, "Content-Type", pszMIME, strlen(pszMIME), RTHTTPHEADERLISTADD_F_BACK); 763 } 764 else 765 { 766 rc = RTHttpHeaderListAdd(HdrLst, "Content-Type", pszMIMEHint, strlen(pszMIMEHint), RTHTTPHEADERLISTADD_F_BACK); 767 RTStrFree(pszMIMEHint); 768 pszMIMEHint = NULL; 809 rc = VINF_SUCCESS; 810 break; 769 811 } 770 812 AssertRCBreak(rc); 771 772 if (pClient->State.msKeepAlive) 773 { 774 /* If the client requested to keep alive the connection, 775 * always override this with 30s and report this back to the client. */ 776 pClient->State.msKeepAlive = RT_MS_30SEC; /** @todo Make this configurable. */ 777 #ifdef DEBUG_andy 778 pClient->State.msKeepAlive = 5000; 779 #endif 780 cch = RTStrPrintf2(szVal, sizeof(szVal), "timeout=%RU64", pClient->State.msKeepAlive / RT_MS_1SEC); /** @todo No pipelining support here yet. */ 781 AssertBreakStmt(cch, VERR_BUFFER_OVERFLOW); 782 rc = RTHttpHeaderListAdd(HdrLst, "Keep-Alive", szVal, strlen(szVal), RTHTTPHEADERLISTADD_F_BACK); 783 AssertRCReturn(rc, rc); 784 } 785 786 rc = rtHttpServerSendResponseEx(pClient, RTHTTPSTATUS_OK, &HdrLst); 787 788 RTHttpHeaderListDestroy(HdrLst); 789 790 if (rc == VERR_BROKEN_PIPE) /* Could happen on fast reloads. */ 791 break; 792 AssertRCReturn(rc, rc); 793 794 size_t cbToRead = fsObj.cbObject; 795 size_t cbRead = 0; /* Shut up GCC. */ 796 size_t cbWritten = 0; /* Ditto. */ 797 while (cbToRead) 798 { 799 RTHTTPSERVER_HANDLE_CALLBACK_VA(pfnRead, pReq, pvHandle, pvBuf, RT_MIN(cbBuf, cbToRead), &cbRead); 800 if (RT_FAILURE(rc)) 801 break; 802 rc = rtHttpServerSendResponseBody(pClient, pvBuf, cbRead, &cbWritten); 803 AssertBreak(cbToRead >= cbWritten); 804 cbToRead -= cbWritten; 805 if (rc == VERR_NET_CONNECTION_RESET_BY_PEER) /* Clients often apruptly abort the connection when done. */ 806 { 807 rc = VINF_SUCCESS; 808 break; 809 } 810 AssertRCBreak(rc); 811 } 812 813 break; 814 } /* for (;;) */ 815 816 RTMemFree(pvBuf); 817 818 int rc2 = rc; /* Save rc. */ 819 813 } 814 815 break; 816 } /* for (;;) */ 817 818 RTMemFree(pvBuf); 819 820 int rc2 = rc; /* Save rc. */ 821 822 if (pvHandle) 820 823 RTHTTPSERVER_HANDLE_CALLBACK_VA(pfnClose, pReq, pvHandle); 821 824 822 if (RT_FAILURE(rc2)) /* Restore original rc on failure. */ 823 rc = rc2; 824 } 825 if (RT_FAILURE(rc2)) /* Restore original rc on failure. */ 826 rc = rc2; 825 827 826 828 LogFlowFuncLeaveRC(rc); … … 1224 1226 if (RT_FAILURE(rcMethod)) 1225 1227 LogFunc(("Request %s %s failed with %Rrc\n", RTHttpMethodToStr(pReq->enmMethod), pReq->pszUrl, rcMethod)); 1226 1227 enmSts = rtHttpServerRcToStatus(rcMethod);1228 1228 break; 1229 1229 } … … 1242 1242 /* Make sure to return at least *something* to the client, to prevent hangs. */ 1243 1243 if (enmSts == RTHTTPSTATUS_INTERNAL_NOT_SET) 1244 enmSts = RTHTTPSTATUS_INTERNALSERVERERROR;1244 enmSts = rtHttpServerRcToStatus(VERR_INTERNAL_ERROR); 1245 1245 1246 1246 int rc2 = rtHttpServerSendResponseSimple(pClient, enmSts); … … 1257 1257 * @returns VBox status code. 1258 1258 * @param pClient Client to process requests for. 1259 */ 1260 static int rtHttpServerClientMain(PRTHTTPSERVERCLIENT pClient) 1259 * @param msTimeout Timeout to wait for reading data. 1260 * Gets renewed for a each reading round. 1261 */ 1262 static int rtHttpServerClientMain(PRTHTTPSERVERCLIENT pClient, RTMSINTERVAL msTimeout) 1261 1263 { 1262 1264 int rc; … … 1269 1271 pClient->State.msKeepAlive = 0; 1270 1272 1271 RTMSINTERVAL cWaitMs = RT_INDEFINITE_WAIT; /* The first wait always waits indefinitely. */1273 RTMSINTERVAL cWaitMs = msTimeout; 1272 1274 uint64_t tsLastReadMs = 0; 1273 1275 1274 for (;;) 1276 for (;;) /* For keep-alive handling. */ 1275 1277 { 1276 1278 rc = RTTcpSelectOne(pClient->hSocket, cWaitMs); … … 1349 1351 rc = rtHttpServerProcessRequest(pClient, szReq, cbReadTotal); 1350 1352 } 1351 else 1352 1353 1354 break; 1353 1355 1354 1356 } /* for */ … … 1395 1397 Client.hSocket = hSocket; 1396 1398 1397 return rtHttpServerClientMain(&Client );1399 return rtHttpServerClientMain(&Client, RT_MS_30SEC /* Timeout */); 1398 1400 } 1399 1401
Note:
See TracChangeset
for help on using the changeset viewer.