Changeset 79630 in vbox for trunk/src/VBox/HostServices/SharedClipboard
- Timestamp:
- Jul 9, 2019 8:14:01 AM (6 years ago)
- svn:sync-xref-src-repo-rev:
- 131932
- Location:
- trunk/src/VBox/HostServices/SharedClipboard
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-internal.h
r79503 r79630 150 150 /** Optional protocol version the client uses. Set to 0 by default. */ 151 151 uint32_t uProtocolVer; 152 /** Flag indicating whether this client currently is deferred mode, 153 * meaning that it did not return to the caller yet. */ 154 bool fDeferred; 155 /** Structure for keeping the client's deferred state. 152 /** Structure for keeping the client's pending (deferred return) state. 156 153 * A client is in a deferred state when it asks for the next HGCM message, 157 154 * but the service can't provide it yet. That way a client will block (on the guest side, does not return) … … 161 158 /** The client's HGCM call handle. Needed for completing a deferred call. */ 162 159 VBOXHGCMCALLHANDLE hHandle; 163 /** Message type (function number) to use when completing the deferred call. */ 160 /** Message type (function number) to use when completing the deferred call. 161 * A non-0 value means the client is in pending mode. */ 164 162 uint32_t uType; 165 163 /** Parameter count to use when completing the deferred call. */ … … 167 165 /** Parameters to use when completing the deferred call. */ 168 166 PVBOXHGCMSVCPARM paParms; 169 } Deferred;167 } Pending; 170 168 } VBOXCLIPBOARDCLIENT, *PVBOXCLIPBOARDCLIENT; 171 169 … … 184 182 int vboxSvcClipboardSetSource(PVBOXCLIPBOARDCLIENTDATA pClientData, SHAREDCLIPBOARDSOURCE enmSource); 185 183 186 int vboxSvcClipboardClientDefer(PVBOXCLIPBOARDCLIENT pClient,187 VBOXHGCMCALLHANDLE hHandle, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);188 int vboxSvcClipboardClientComplete(PVBOXCLIPBOARDCLIENT pClient, VBOXHGCMCALLHANDLE hHandle, int rc);189 int vboxSvcClipboardClientDeferredComplete(PVBOXCLIPBOARDCLIENT pClient, int rc);190 int vboxSvcClipboardClientDeferredSetMsgInfo(PVBOXCLIPBOARDCLIENT pClient, uint32_t uMsg, uint32_t cParms);191 192 184 void vboxSvcClipboardMsgQueueReset(PVBOXCLIPBOARDCLIENTDATA pClientData); 193 185 PVBOXCLIPBOARDCLIENTMSG vboxSvcClipboardMsgAlloc(uint32_t uMsg, uint32_t cParms); 194 186 void vboxSvcClipboardMsgFree(PVBOXCLIPBOARDCLIENTMSG pMsg); 187 void vboxSvcClipboardMsgSetPeekReturn(PVBOXCLIPBOARDCLIENTMSG pMsg, PVBOXHGCMSVCPARM paDstParms, uint32_t cDstParms); 195 188 int vboxSvcClipboardMsgAdd(PVBOXCLIPBOARDCLIENTDATA pClientData, PVBOXCLIPBOARDCLIENTMSG pMsg, bool fAppend); 196 int vboxSvcClipboardMsgGetNextInfo(PVBOXCLIPBOARDCLIENTDATA pClientData, uint32_t *puType, uint32_t *pcParms); 197 int vboxSvcClipboardMsgGetNext(PVBOXCLIPBOARDCLIENTDATA pClientData, 198 uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[]); 189 int vboxSvcClipboardMsgPeek(PVBOXCLIPBOARDCLIENT pClient, VBOXHGCMCALLHANDLE hCall, uint32_t cParms, VBOXHGCMSVCPARM paParms[], bool fWait); 190 int vboxSvcClipboardMsgGet(PVBOXCLIPBOARDCLIENT pClient, VBOXHGCMCALLHANDLE hCall, uint32_t cParms, VBOXHGCMSVCPARM paParms[]); 191 192 int vboxSvcClipboardClientWakeup(PVBOXCLIPBOARDCLIENT pClient); 199 193 200 194 # ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST … … 226 220 227 221 int vboxSvcClipboardURIListOpen(PSHAREDCLIPBOARDPROVIDERCTX pCtx, 228 PVBOXCLIPBOARDLISTHDR pListHdr, P VBOXCLIPBOARDLISTHANDLE phList);229 int vboxSvcClipboardURIListClose(PSHAREDCLIPBOARDPROVIDERCTX pCtx, VBOXCLIPBOARDLISTHANDLE hList);230 int vboxSvcClipboardURIListHdrRead(PSHAREDCLIPBOARDPROVIDERCTX pCtx, VBOXCLIPBOARDLISTHANDLE hList,222 PVBOXCLIPBOARDLISTHDR pListHdr, PSHAREDCLIPBOARDLISTHANDLE phList); 223 int vboxSvcClipboardURIListClose(PSHAREDCLIPBOARDPROVIDERCTX pCtx, SHAREDCLIPBOARDLISTHANDLE hList); 224 int vboxSvcClipboardURIListHdrRead(PSHAREDCLIPBOARDPROVIDERCTX pCtx, SHAREDCLIPBOARDLISTHANDLE hList, 231 225 PVBOXCLIPBOARDLISTHDR pListHdr); 232 int vboxSvcClipboardURIListHdrWrite(PSHAREDCLIPBOARDPROVIDERCTX pCtx, VBOXCLIPBOARDLISTHANDLE hList,226 int vboxSvcClipboardURIListHdrWrite(PSHAREDCLIPBOARDPROVIDERCTX pCtx, SHAREDCLIPBOARDLISTHANDLE hList, 233 227 PVBOXCLIPBOARDLISTHDR pListHdr); 234 int vboxSvcClipboardURIListEntryRead(PSHAREDCLIPBOARDPROVIDERCTX pCtx, VBOXCLIPBOARDLISTHANDLE hList,228 int vboxSvcClipboardURIListEntryRead(PSHAREDCLIPBOARDPROVIDERCTX pCtx, SHAREDCLIPBOARDLISTHANDLE hList, 235 229 PVBOXCLIPBOARDLISTENTRY pListEntry); 236 int vboxSvcClipboardURIListEntryWrite(PSHAREDCLIPBOARDPROVIDERCTX pCtx, VBOXCLIPBOARDLISTHANDLE hList,230 int vboxSvcClipboardURIListEntryWrite(PSHAREDCLIPBOARDPROVIDERCTX pCtx, SHAREDCLIPBOARDLISTHANDLE hList, 237 231 PVBOXCLIPBOARDLISTENTRY pListEntry); 238 232 -
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-uri.cpp
r79497 r79630 41 41 extern PFNHGCMSVCEXT g_pfnExtension; 42 42 extern void *g_pvExtension; 43 extern PVBOXHGCMSVCHELPERS g_pHelpers; 43 44 44 45 extern ClipboardClientQueue g_listClientsDeferred; 46 47 48 /********************************************************************************************************************************* 49 * Prototypes * 50 *********************************************************************************************************************************/ 51 int VBoxSvcClipboardURISetListOpen(uint32_t cParms, VBOXHGCMSVCPARM paParms[], 52 PVBOXCLIPBOARDLISTOPENPARMS pOpenParms); 45 53 46 54 … … 66 74 67 75 DECLCALLBACK(int) vboxSvcClipboardURIListOpen(PSHAREDCLIPBOARDPROVIDERCTX pCtx, 68 PVBOXCLIPBOARDLISTHDR pListHdr, PVBOXCLIPBOARDLISTHANDLE phList) 69 { 70 RT_NOREF(pCtx, pListHdr, phList); 71 72 LogFlowFuncEnter(); 73 74 int rc = VINF_SUCCESS; 75 76 LogFlowFuncLeaveRC(rc); 77 return rc; 78 } 79 80 DECLCALLBACK(int) vboxSvcClipboardURIListClose(PSHAREDCLIPBOARDPROVIDERCTX pCtx, VBOXCLIPBOARDLISTHANDLE hList) 81 { 82 RT_NOREF(pCtx, hList); 83 84 LogFlowFuncEnter(); 85 86 int rc = VINF_SUCCESS; 87 88 LogFlowFuncLeaveRC(rc); 89 return rc; 90 } 91 92 DECLCALLBACK(int) vboxSvcClipboardURIListHdrRead(PSHAREDCLIPBOARDPROVIDERCTX pCtx, 93 VBOXCLIPBOARDLISTHANDLE hList, PVBOXCLIPBOARDLISTHDR pListHdr) 94 { 95 RT_NOREF(pCtx, hList, pListHdr); 76 PVBOXCLIPBOARDLISTOPENPARMS pOpenParms, PSHAREDCLIPBOARDLISTHANDLE phList) 77 { 78 RT_NOREF(phList); 96 79 97 80 LogFlowFuncEnter(); … … 102 85 int rc; 103 86 104 PVBOXCLIPBOARDCLIENTMSG pMsg = vboxSvcClipboardMsgAlloc(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_ HDR_READ,105 VBOX_SHARED_CLIPBOARD_CPARMS_LIST_ HDR_READ);87 PVBOXCLIPBOARDCLIENTMSG pMsg = vboxSvcClipboardMsgAlloc(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_OPEN, 88 VBOX_SHARED_CLIPBOARD_CPARMS_LIST_OPEN); 106 89 if (pMsg) 107 90 { 108 rc = vboxSvcClipboardMsgAdd(&pClient->pData->State, pMsg, true /* fAppend */); 109 if (RT_SUCCESS(rc)) 110 rc = vboxSvcClipboardClientDeferredComplete(pClient, VINF_SUCCESS); 91 rc = VBoxSvcClipboardURISetListOpen(pMsg->m_cParms, pMsg->m_paParms, pOpenParms); 92 if (RT_SUCCESS(rc)) 93 { 94 rc = vboxSvcClipboardMsgAdd(pClient->pData, pMsg, true /* fAppend */); 95 if (RT_SUCCESS(rc)) 96 { 97 int rc2 = SharedClipboardURITransferEventRegister(pCtx->pTransfer, SHAREDCLIPBOARDURITRANSFEREVENTTYPE_LIST_OPEN); 98 AssertRC(rc2); 99 100 vboxSvcClipboardClientWakeup(pClient); 101 } 102 } 111 103 } 112 104 else … … 116 108 { 117 109 PSHAREDCLIPBOARDURITRANSFERPAYLOAD pPayload; 118 rc = SharedClipboardURITransferEventWait(pCtx->pTransfer, SHAREDCLIPBOARDURITRANSFEREVENTTYPE_LIST_ HDR_READ,110 rc = SharedClipboardURITransferEventWait(pCtx->pTransfer, SHAREDCLIPBOARDURITRANSFEREVENTTYPE_LIST_OPEN, 119 111 30 * 1000 /* Timeout in ms */, &pPayload); 120 112 if (RT_SUCCESS(rc)) 121 113 { 114 Assert(pPayload->cbData == sizeof(VBOXCLIPBOARDREPLY)); 115 116 PVBOXCLIPBOARDREPLY pReply = (PVBOXCLIPBOARDREPLY)pPayload->pvData; 117 AssertPtr(pReply); 118 119 Assert(pReply->uType == VBOX_SHAREDCLIPBOARD_REPLYMSGTYPE_LIST_OPEN); 120 121 *phList = pReply->u.ListOpen.uHandle; 122 123 SharedClipboardURITransferPayloadFree(pPayload); 124 } 125 } 126 127 LogFlowFuncLeaveRC(rc); 128 return rc; 129 } 130 131 DECLCALLBACK(int) vboxSvcClipboardURIListClose(PSHAREDCLIPBOARDPROVIDERCTX pCtx, SHAREDCLIPBOARDLISTHANDLE hList) 132 { 133 RT_NOREF(pCtx, hList); 134 135 LogFlowFuncEnter(); 136 137 int rc = VINF_SUCCESS; 138 139 LogFlowFuncLeaveRC(rc); 140 return rc; 141 } 142 143 DECLCALLBACK(int) vboxSvcClipboardURIListHdrRead(PSHAREDCLIPBOARDPROVIDERCTX pCtx, 144 SHAREDCLIPBOARDLISTHANDLE hList, PVBOXCLIPBOARDLISTHDR pListHdr) 145 { 146 LogFlowFuncEnter(); 147 148 PVBOXCLIPBOARDCLIENT pClient = (PVBOXCLIPBOARDCLIENT)pCtx->pvUser; 149 AssertPtr(pClient); 150 151 int rc; 152 153 PVBOXCLIPBOARDCLIENTMSG pMsg = vboxSvcClipboardMsgAlloc(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_HDR_READ, 154 VBOX_SHARED_CLIPBOARD_CPARMS_LIST_HDR_READ_REQ); 155 if (pMsg) 156 { 157 HGCMSvcSetU32(&pMsg->m_paParms[0], 0 /* uContextID */); 158 HGCMSvcSetU64(&pMsg->m_paParms[1], hList); 159 HGCMSvcSetU32(&pMsg->m_paParms[2], 0 /* fFlags */); 160 161 rc = vboxSvcClipboardMsgAdd(pClient->pData, pMsg, true /* fAppend */); 162 if (RT_SUCCESS(rc)) 163 { 164 int rc2 = SharedClipboardURITransferEventRegister(pCtx->pTransfer, SHAREDCLIPBOARDURITRANSFEREVENTTYPE_LIST_HDR_WRITE); 165 AssertRC(rc2); 166 167 vboxSvcClipboardClientWakeup(pClient); 168 } 169 } 170 else 171 rc = VERR_NO_MEMORY; 172 173 if (RT_SUCCESS(rc)) 174 { 175 PSHAREDCLIPBOARDURITRANSFERPAYLOAD pPayload; 176 rc = SharedClipboardURITransferEventWait(pCtx->pTransfer, SHAREDCLIPBOARDURITRANSFEREVENTTYPE_LIST_HDR_WRITE, 177 30 * 1000 /* Timeout in ms */, &pPayload); 178 if (RT_SUCCESS(rc)) 179 { 122 180 Assert(pPayload->cbData == sizeof(VBOXCLIPBOARDLISTHDR)); 123 //*ppListHdr = (PVBOXCLIPBOARDLISTHDR)pPayload->pvData; 124 125 RTMemFree(pPayload); 181 182 *pListHdr = *(PVBOXCLIPBOARDLISTHDR)pPayload->pvData; 183 184 SharedClipboardURITransferPayloadFree(pPayload); 126 185 } 127 186 } … … 132 191 133 192 DECLCALLBACK(int) vboxSvcClipboardURIListHdrWrite(PSHAREDCLIPBOARDPROVIDERCTX pCtx, 134 VBOXCLIPBOARDLISTHANDLE hList, PVBOXCLIPBOARDLISTHDR pListHdr)193 SHAREDCLIPBOARDLISTHANDLE hList, PVBOXCLIPBOARDLISTHDR pListHdr) 135 194 { 136 195 RT_NOREF(pCtx, hList, pListHdr); … … 142 201 143 202 DECLCALLBACK(int) vboxSvcClipboardURIListEntryRead(PSHAREDCLIPBOARDPROVIDERCTX pCtx, 144 VBOXCLIPBOARDLISTHANDLE hList, PVBOXCLIPBOARDLISTENTRY pListEntry) 145 { 146 RT_NOREF(pCtx, hList, pListEntry); 147 148 LogFlowFuncEnter(); 149 150 PVBOXCLIPBOARDCLIENTDATA pClientData = (PVBOXCLIPBOARDCLIENTDATA)pCtx->pvUser; 151 AssertPtr(pClientData); 152 153 PSHAREDCLIPBOARDURITRANSFERPAYLOAD pPayload; 154 int rc = SharedClipboardURITransferEventWait(pCtx->pTransfer, SHAREDCLIPBOARDURITRANSFEREVENTTYPE_LIST_ENTRY_READ, 203 SHAREDCLIPBOARDLISTHANDLE hList, PVBOXCLIPBOARDLISTENTRY pListEntry) 204 { 205 LogFlowFuncEnter(); 206 207 PVBOXCLIPBOARDCLIENT pClient = (PVBOXCLIPBOARDCLIENT)pCtx->pvUser; 208 AssertPtr(pClient); 209 210 int rc; 211 212 PVBOXCLIPBOARDCLIENTMSG pMsg = vboxSvcClipboardMsgAlloc(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_ENTRY_READ, 213 VBOX_SHARED_CLIPBOARD_CPARMS_LIST_ENTRY_READ_REQ); 214 if (pMsg) 215 { 216 HGCMSvcSetU32(&pMsg->m_paParms[0], 0 /* uContextID */); 217 HGCMSvcSetU64(&pMsg->m_paParms[1], hList); 218 HGCMSvcSetU32(&pMsg->m_paParms[2], 0 /* fInfo */); 219 220 rc = vboxSvcClipboardMsgAdd(pClient->pData, pMsg, true /* fAppend */); 221 if (RT_SUCCESS(rc)) 222 { 223 int rc2 = SharedClipboardURITransferEventRegister(pCtx->pTransfer, SHAREDCLIPBOARDURITRANSFEREVENTTYPE_LIST_ENTRY_WRITE); 224 if (rc2 == VERR_ALREADY_EXISTS) 225 rc2 = VINF_SUCCESS; 226 AssertRC(rc2); 227 228 vboxSvcClipboardClientWakeup(pClient); 229 } 230 } 231 else 232 rc = VERR_NO_MEMORY; 233 234 if (RT_SUCCESS(rc)) 235 { 236 PSHAREDCLIPBOARDURITRANSFERPAYLOAD pPayload; 237 rc = SharedClipboardURITransferEventWait(pCtx->pTransfer, SHAREDCLIPBOARDURITRANSFEREVENTTYPE_LIST_ENTRY_WRITE, 155 238 30 * 1000 /* Timeout in ms */, &pPayload); 156 if (RT_SUCCESS(rc)) 157 { 158 Assert(pPayload->cbData == sizeof(VBOXCLIPBOARDLISTENTRY)); 159 160 PVBOXCLIPBOARDLISTENTRY pListEntry = (PVBOXCLIPBOARDLISTENTRY)pPayload->pvData; 161 AssertPtr(pListEntry); 162 163 /* const uint32_t cbToRead = RT_MIN(cbChunk, pListEntry->cbData); 164 165 memcpy(pvChunk, pListEntry->pvData, cbToRead);*/ 166 167 SharedClipboardURITransferPayloadFree(pPayload); 168 169 /* if (pcbRead) 170 *pcbRead = cbToRead;*/ 239 if (RT_SUCCESS(rc)) 240 { 241 Assert(pPayload->cbData == sizeof(VBOXCLIPBOARDLISTENTRY)); 242 243 rc = SharedClipboardURIListEntryCopy(pListEntry, (PVBOXCLIPBOARDLISTENTRY)pPayload->pvData); 244 245 SharedClipboardURITransferPayloadFree(pPayload); 246 } 171 247 } 172 248 … … 176 252 177 253 DECLCALLBACK(int) vboxSvcClipboardURIListEntryWrite(PSHAREDCLIPBOARDPROVIDERCTX pCtx, 178 VBOXCLIPBOARDLISTHANDLE hList, PVBOXCLIPBOARDLISTENTRY pListEntry)254 SHAREDCLIPBOARDLISTHANDLE hList, PVBOXCLIPBOARDLISTENTRY pListEntry) 179 255 { 180 256 RT_NOREF(pCtx, hList, pListEntry); … … 237 313 DECLCALLBACK(void) VBoxSvcClipboardURITransferPrepareCallback(PSHAREDCLIPBOARDURITRANSFERCALLBACKDATA pData) 238 314 { 239 LogFlowFuncEnter(); 240 241 AssertPtrReturnVoid(pData); 242 243 PVBOXCLIPBOARDCLIENTDATA pClientData = (PVBOXCLIPBOARDCLIENTDATA)pData->pvUser; 244 AssertPtrReturnVoid(pClientData); 245 246 PSHAREDCLIPBOARDURITRANSFER pTransfer = pData->pTransfer; 247 AssertPtrReturnVoid(pTransfer); 248 249 /* Register needed events. */ 250 int rc2 = SharedClipboardURITransferEventRegister(pData->pTransfer, SHAREDCLIPBOARDURITRANSFEREVENTTYPE_LIST_HDR_READ); 251 AssertRC(rc2); 252 rc2 = SharedClipboardURITransferEventRegister(pData->pTransfer, SHAREDCLIPBOARDURITRANSFEREVENTTYPE_LIST_ENTRY_READ); 253 AssertRC(rc2); 254 255 #if 0 256 /* Tell the guest that it can start sending URI data. */ 257 rc2 = vboxSvcClipboardReportMsg(pClientData, VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_TRANSFER_START, 258 0 /* u32Formats == 0 means reading data */); 259 AssertRC(rc2); 260 #endif 315 RT_NOREF(pData); 316 317 LogFlowFuncEnter(); 261 318 } 262 319 263 320 DECLCALLBACK(void) VBoxSvcClipboardURITransferCompleteCallback(PSHAREDCLIPBOARDURITRANSFERCALLBACKDATA pData, int rc) 264 321 { 265 LogFlowFuncEnter();266 267 322 RT_NOREF(pData, rc); 268 323 324 LogFlowFuncEnter(); 325 269 326 LogRel2(("Shared Clipboard: Transfer complete\n")); 270 327 } … … 286 343 287 344 LogRel(("Shared Clipboard: Transfer failed with %Rrc\n", rc)); 345 } 346 347 /** 348 * Gets an URI message reply from HGCM service parameters. 349 * 350 * @returns VBox status code. 351 * @param cParms Number of HGCM parameters supplied in \a paParms. 352 * @param paParms Array of HGCM parameters. 353 * @param pReply Where to store the reply. 354 */ 355 int VBoxSvcClipboardURIGetReply(uint32_t cParms, VBOXHGCMSVCPARM paParms[], 356 PVBOXCLIPBOARDREPLY pReply) 357 { 358 int rc; 359 360 if (cParms >= VBOX_SHARED_CLIPBOARD_CPARMS_REPLY_MIN) 361 { 362 uint32_t cbPayload = 0; 363 364 /* Note: Context ID (paParms[0]) not used yet. */ 365 rc = HGCMSvcGetU32(&paParms[1], &pReply->uType); 366 if (RT_SUCCESS(rc)) 367 rc = HGCMSvcGetU32(&paParms[2], &pReply->rc); 368 if (RT_SUCCESS(rc)) 369 rc = HGCMSvcGetU32(&paParms[3], &cbPayload); 370 if (RT_SUCCESS(rc)) 371 { 372 rc = HGCMSvcGetPv(&paParms[4], &pReply->pvPayload, &pReply->cbPayload); 373 AssertReturn(cbPayload == pReply->cbPayload, VERR_INVALID_PARAMETER); 374 } 375 376 if (RT_SUCCESS(rc)) 377 { 378 switch (pReply->uType) 379 { 380 case VBOX_SHAREDCLIPBOARD_REPLYMSGTYPE_LIST_OPEN: 381 { 382 if (cParms >= 6) 383 { 384 rc = HGCMSvcGetU64(&paParms[5], &pReply->u.ListOpen.uHandle); 385 } 386 else 387 rc = VERR_INVALID_PARAMETER; 388 break; 389 } 390 391 case VBOX_SHAREDCLIPBOARD_REPLYMSGTYPE_OBJ_OPEN: 392 { 393 if (cParms >= 6) 394 { 395 rc = HGCMSvcGetU64(&paParms[5], &pReply->u.ObjOpen.uHandle); 396 } 397 else 398 rc = VERR_INVALID_PARAMETER; 399 break; 400 } 401 402 default: 403 break; 404 } 405 } 406 } 407 else 408 rc = VERR_INVALID_PARAMETER; 409 410 LogFlowFuncLeaveRC(rc); 411 return rc; 412 } 413 414 /** 415 * Gets an URI list open request from HGCM service parameters. 416 * 417 * @returns VBox status code. 418 * @param cParms Number of HGCM parameters supplied in \a paParms. 419 * @param paParms Array of HGCM parameters. 420 * @param pOpenParms Where to store the open parameters of the request. 421 */ 422 int VBoxSvcClipboardURIGetListOpen(uint32_t cParms, VBOXHGCMSVCPARM paParms[], 423 PVBOXCLIPBOARDLISTOPENPARMS pOpenParms) 424 { 425 int rc; 426 427 if (cParms == VBOX_SHARED_CLIPBOARD_CPARMS_LIST_OPEN) 428 { 429 uint32_t cbPath = 0; 430 uint32_t cbFilter = 0; 431 432 /* Note: Context ID (paParms[0]) not used yet. */ 433 rc = HGCMSvcGetU32(&paParms[1], &pOpenParms->fList); 434 if (RT_SUCCESS(rc)) 435 rc = HGCMSvcGetU32(&paParms[2], &cbPath); 436 if (RT_SUCCESS(rc)) 437 { 438 rc = HGCMSvcGetStr(&paParms[3], &pOpenParms->pszPath, &pOpenParms->cbPath); 439 AssertReturn(cbPath == pOpenParms->cbPath, VERR_INVALID_PARAMETER); 440 } 441 if (RT_SUCCESS(rc)) 442 rc = HGCMSvcGetU32(&paParms[4], &cbFilter); 443 if (RT_SUCCESS(rc)) 444 { 445 rc = HGCMSvcGetStr(&paParms[5], &pOpenParms->pszFilter, &pOpenParms->cbFilter); 446 AssertReturn(cbFilter == pOpenParms->cbFilter, VERR_INVALID_PARAMETER); 447 } 448 449 if (RT_SUCCESS(rc)) 450 { 451 /** @todo Some more validation. */ 452 } 453 } 454 else 455 rc = VERR_INVALID_PARAMETER; 456 457 LogFlowFuncLeaveRC(rc); 458 return rc; 459 } 460 461 int VBoxSvcClipboardURISetListOpen(uint32_t cParms, VBOXHGCMSVCPARM paParms[], 462 PVBOXCLIPBOARDLISTOPENPARMS pOpenParms) 463 { 464 int rc; 465 466 if (cParms == VBOX_SHARED_CLIPBOARD_CPARMS_LIST_OPEN) 467 { 468 HGCMSvcSetU32(&paParms[0], 0 /* uContextID */); 469 HGCMSvcSetU32(&paParms[1], pOpenParms->fList); 470 HGCMSvcSetU32(&paParms[2], pOpenParms->cbFilter); 471 HGCMSvcSetPv (&paParms[3], pOpenParms->pszFilter, pOpenParms->cbFilter); 472 HGCMSvcSetU32(&paParms[4], pOpenParms->cbPath); 473 HGCMSvcSetPv (&paParms[5], pOpenParms->pszPath, pOpenParms->cbPath); 474 HGCMSvcSetU64(&paParms[6], 0); /* OUT: uHandle */ 475 476 rc = VINF_SUCCESS; 477 } 478 else 479 rc = VERR_INVALID_PARAMETER; 480 481 LogFlowFuncLeaveRC(rc); 482 return rc; 288 483 } 289 484 … … 298 493 */ 299 494 int VBoxSvcClipboardURIGetListHdr(uint32_t cParms, VBOXHGCMSVCPARM paParms[], 300 P VBOXCLIPBOARDLISTHANDLE phList, PVBOXCLIPBOARDLISTHDR pListHdr)495 PSHAREDCLIPBOARDLISTHANDLE phList, PVBOXCLIPBOARDLISTHDR pListHdr) 301 496 { 302 497 int rc; 303 498 304 if (cParms == VBOX_SHARED_CLIPBOARD_CPARMS_LIST_HDR _WRITE)499 if (cParms == VBOX_SHARED_CLIPBOARD_CPARMS_LIST_HDR) 305 500 { 306 501 /* Note: Context ID (paParms[0]) not used yet. */ 307 502 rc = HGCMSvcGetU64(&paParms[1], phList); 308 if (RT_SUCCESS(rc)) 309 rc = HGCMSvcGetU64(&paParms[2], &pListHdr->cTotalObjects); 310 if (RT_SUCCESS(rc)) 311 rc = HGCMSvcGetU64(&paParms[3], &pListHdr->cbTotalSize); 312 if (RT_SUCCESS(rc)) 313 rc = HGCMSvcGetU32(&paParms[4], &pListHdr->enmCompression); 314 if (RT_SUCCESS(rc)) 315 rc = HGCMSvcGetU32(&paParms[5], (uint32_t *)&pListHdr->enmChecksumType); 503 /* Note: Flags (paParms[2]) not used here. */ 504 if (RT_SUCCESS(rc)) 505 rc = HGCMSvcGetU32(&paParms[3], &pListHdr->fFeatures); 506 if (RT_SUCCESS(rc)) 507 rc = HGCMSvcGetU64(&paParms[4], &pListHdr->cTotalObjects); 508 if (RT_SUCCESS(rc)) 509 rc = HGCMSvcGetU64(&paParms[5], &pListHdr->cbTotalSize); 510 if (RT_SUCCESS(rc)) 511 rc = HGCMSvcGetU32(&paParms[6], &pListHdr->enmCompression); 512 if (RT_SUCCESS(rc)) 513 rc = HGCMSvcGetU32(&paParms[7], (uint32_t *)&pListHdr->enmChecksumType); 316 514 317 515 if (RT_SUCCESS(rc)) … … 340 538 int rc; 341 539 342 if (cParms == VBOX_SHARED_CLIPBOARD_CPARMS_LIST_HDR_READ) 540 if ( cParms == VBOX_SHARED_CLIPBOARD_CPARMS_LIST_HDR 541 || cParms == VBOX_SHARED_CLIPBOARD_CPARMS_LIST_HDR) 343 542 { 344 543 /** @todo Set pvMetaFmt + cbMetaFmt. */ 345 544 /** @todo Calculate header checksum. */ 346 545 347 /* Note: Context ID (paParms[0]) not used yet. */ 348 HGCMSvcSetU32(&paParms[1], pListHdr->fList); 349 HGCMSvcSetU32(&paParms[2], pListHdr->fFeatures); 350 HGCMSvcSetU32(&paParms[3], pListHdr->cbFilter); 351 HGCMSvcSetPv (&paParms[4], pListHdr->pszFilter, pListHdr->cbFilter); 352 HGCMSvcSetU64(&paParms[5], pListHdr->cTotalObjects); 353 HGCMSvcSetU64(&paParms[6], pListHdr->cbTotalSize); 354 HGCMSvcSetU32(&paParms[7], pListHdr->enmCompression); 355 HGCMSvcSetU32(&paParms[8], (uint32_t)pListHdr->enmChecksumType); 546 HGCMSvcSetU32(&paParms[0], 0 /* uContextID */); 547 HGCMSvcSetU32(&paParms[1], pListHdr->fFeatures); 548 HGCMSvcSetU32(&paParms[2], 0 /* Features, will be returned on success */); 549 HGCMSvcSetU64(&paParms[3], pListHdr->cTotalObjects); 550 HGCMSvcSetU64(&paParms[4], pListHdr->cbTotalSize); 551 HGCMSvcSetU32(&paParms[5], pListHdr->enmCompression); 552 HGCMSvcSetU32(&paParms[6], pListHdr->enmChecksumType); 356 553 357 554 rc = VINF_SUCCESS; … … 374 571 */ 375 572 int VBoxSvcClipboardURIGetListEntry(uint32_t cParms, VBOXHGCMSVCPARM paParms[], 376 P VBOXCLIPBOARDLISTHANDLE phList, PVBOXCLIPBOARDLISTENTRY pListEntry)573 PSHAREDCLIPBOARDLISTHANDLE phList, PVBOXCLIPBOARDLISTENTRY pListEntry) 377 574 { 378 575 int rc; 379 576 380 if (cParms == VBOX_SHARED_CLIPBOARD_CPARMS_LIST_ENTRY _WRITE)577 if (cParms == VBOX_SHARED_CLIPBOARD_CPARMS_LIST_ENTRY) 381 578 { 382 579 /* Note: Context ID (paParms[0]) not used yet. */ … … 414 611 int rc; 415 612 416 if (cParms == VBOX_SHARED_CLIPBOARD_CPARMS_LIST_ENTRY _READ)613 if (cParms == VBOX_SHARED_CLIPBOARD_CPARMS_LIST_ENTRY) 417 614 { 418 615 /** @todo Calculate chunk checksum. */ 419 616 420 /* Note: Context ID (paParms[0]) not used yet. */617 HGCMSvcSetU32(&paParms[0], 0 /* uContextID */); 421 618 HGCMSvcSetU32(&paParms[1], pListEntry->fInfo); 422 619 HGCMSvcSetU32(&paParms[2], pListEntry->cbInfo); … … 432 629 } 433 630 631 /** 632 * Gets an URI error from HGCM service parameters. 633 * 634 * @returns VBox status code. 635 * @param cParms Number of HGCM parameters supplied in \a paParms. 636 * @param paParms Array of HGCM parameters. 637 * @param pRc Where to store the received error code. 638 */ 434 639 int VBoxSvcClipboardURIGetError(uint32_t cParms, VBOXHGCMSVCPARM paParms[], int *pRc) 435 640 { … … 446 651 else 447 652 rc = VERR_INVALID_PARAMETER; 653 654 LogFlowFuncLeaveRC(rc); 655 return rc; 656 } 657 658 int VBoxSvcClipboardURITransferHandleReply(PVBOXCLIPBOARDCLIENT pClient, PSHAREDCLIPBOARDURITRANSFER pTransfer, 659 uint32_t cParms, VBOXHGCMSVCPARM paParms[]) 660 { 661 RT_NOREF(pClient); 662 663 int rc; 664 665 uint32_t cbReply = sizeof(VBOXCLIPBOARDREPLY); 666 PVBOXCLIPBOARDREPLY pReply = (PVBOXCLIPBOARDREPLY)RTMemAlloc(cbReply); 667 if (pReply) 668 { 669 rc = VBoxSvcClipboardURIGetReply(cParms, paParms, pReply); 670 if (RT_SUCCESS(rc)) 671 { 672 PSHAREDCLIPBOARDURITRANSFERPAYLOAD pPayload 673 = (PSHAREDCLIPBOARDURITRANSFERPAYLOAD)RTMemAlloc(sizeof(SHAREDCLIPBOARDURITRANSFERPAYLOAD)); 674 if (pPayload) 675 { 676 pPayload->pvData = pReply; 677 pPayload->cbData = cbReply; 678 679 switch (pReply->uType) 680 { 681 case VBOX_SHAREDCLIPBOARD_REPLYMSGTYPE_LIST_OPEN: 682 { 683 rc = SharedClipboardURITransferEventSignal(pTransfer, 684 SHAREDCLIPBOARDURITRANSFEREVENTTYPE_LIST_OPEN, pPayload); 685 break; 686 } 687 688 default: 689 rc = VERR_NOT_FOUND; 690 break; 691 } 692 693 if (RT_FAILURE(rc)) 694 { 695 if (pPayload) 696 RTMemFree(pPayload); 697 } 698 } 699 else 700 rc = VERR_NO_MEMORY; 701 } 702 } 703 else 704 rc = VERR_NO_MEMORY; 705 706 if (RT_FAILURE(rc)) 707 { 708 if (pReply) 709 RTMemFree(pReply); 710 } 448 711 449 712 LogFlowFuncLeaveRC(rc); … … 471 734 RT_NOREF(paParms, tsArrival); 472 735 473 LogFlowFunc(("uClient=%RU32, u32Function=%RU32 , cParms=%RU32, g_pfnExtension=%p\n",474 pClient->uClientID, u32Function, cParms, g_pfnExtension));736 LogFlowFunc(("uClient=%RU32, u32Function=%RU32 (%s), cParms=%RU32, g_pfnExtension=%p\n", 737 pClient->uClientID, u32Function, VBoxSvcClipboardGuestMsgToStr(u32Function), cParms, g_pfnExtension)); 475 738 476 739 const PVBOXCLIPBOARDCLIENTDATA pClientData = pClient->pData; … … 503 766 switch (u32Function) 504 767 { 505 case VBOX_SHARED_CLIPBOARD_GUEST_FN_ GET_HOST_MSG:768 case VBOX_SHARED_CLIPBOARD_GUEST_FN_MSG_PEEK_NOWAIT: 506 769 RT_FALL_THROUGH(); 507 case VBOX_SHARED_CLIPBOARD_GUEST_FN_TRANSFER_REPORT: 770 case VBOX_SHARED_CLIPBOARD_GUEST_FN_MSG_PEEK_WAIT: 771 RT_FALL_THROUGH(); 772 case VBOX_SHARED_CLIPBOARD_GUEST_FN_MSG_GET: 773 RT_FALL_THROUGH(); 774 case VBOX_SHARED_CLIPBOARD_GUEST_FN_STATUS: 508 775 break; 509 776 default: … … 535 802 switch (u32Function) 536 803 { 537 case VBOX_SHARED_CLIPBOARD_GUEST_FN_TRANSFER_REPORT: 538 { 539 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_GUEST_FN_TRANSFER_REPORT\n")); 540 541 if (!SharedClipboardURICtxTransfersMaximumReached(&pClientData->URI)) 804 case VBOX_SHARED_CLIPBOARD_GUEST_FN_STATUS: 805 { 806 LogFlowFunc(("[Client %RU32] VBOX_SHARED_CLIPBOARD_GUEST_FN_STATUS\n", pClient->uClientID)); 807 808 if (cParms != VBOX_SHARED_CLIPBOARD_CPARMS_STATUS) 809 break; 810 811 SHAREDCLIPBOARDURITRANSFERSTATUS uStatus = SHAREDCLIPBOARDURITRANSFERSTATUS_NONE; 812 rc = HGCMSvcGetU32(&paParms[1], &uStatus); 813 if (RT_FAILURE(rc)) 814 break; 815 816 LogFlowFunc(("uStatus: %RU32\n", uStatus)); 817 818 if ( uStatus == SHAREDCLIPBOARDURITRANSFERSTATUS_RUNNING 819 && !SharedClipboardURICtxTransfersMaximumReached(&pClientData->URI)) 542 820 { 543 821 SharedClipboardURICtxTransfersCleanup(&pClientData->URI); … … 592 870 SharedClipboardURITransferSetCallbacks(pTransfer, &Callbacks); 593 871 594 rc = SharedClipboardURITransfer ProviderCreate(pTransfer, &creationCtx);872 rc = SharedClipboardURITransferSetInterface(pTransfer, &creationCtx); 595 873 if (RT_SUCCESS(rc)) 596 874 rc = SharedClipboardURICtxTransferAdd(&pClientData->URI, pTransfer); … … 614 892 rc = VERR_SHCLPB_MAX_TRANSFERS_REACHED; 615 893 616 LogF unc(("VBOX_SHARED_CLIPBOARD_GUEST_FN_TRANSFER_REPORT: %Rrc\n", rc));894 LogFlowFunc(("[Client %RU32] VBOX_SHARED_CLIPBOARD_GUEST_FN_STATUS: %Rrc\n", pClient->uClientID, rc)); 617 895 618 896 if (RT_FAILURE(rc)) … … 622 900 } 623 901 624 case VBOX_SHARED_CLIPBOARD_GUEST_FN_GET_HOST_MSG: 625 { 626 if (cParms == VBOX_SHARED_CLIPBOARD_CPARMS_GET_HOST_MSG) 627 { 628 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_GUEST_FN_GET_HOST_MSG\n")); 629 rc = vboxSvcClipboardMsgGetNextInfo(&pClientData->State, 630 &paParms[0].u.uint32 /* uMsg */, &paParms[1].u.uint32 /* cParms */); 631 632 /* No (new) messages available or some error occurred? */ 633 if ( rc == VERR_NO_DATA 634 || RT_FAILURE(rc)) 902 case VBOX_SHARED_CLIPBOARD_GUEST_FN_MSG_PEEK_NOWAIT: 903 { 904 rc = vboxSvcClipboardMsgPeek(pClient, callHandle, cParms, paParms, false /*fWait*/); 905 break; 906 } 907 908 case VBOX_SHARED_CLIPBOARD_GUEST_FN_MSG_PEEK_WAIT: 909 { 910 rc = vboxSvcClipboardMsgPeek(pClient, callHandle, cParms, paParms, true /*fWait*/); 911 break; 912 } 913 914 case VBOX_SHARED_CLIPBOARD_GUEST_FN_MSG_GET: 915 { 916 rc = vboxSvcClipboardMsgGet(pClient, callHandle, cParms, paParms); 917 break; 918 } 919 920 case VBOX_SHARED_CLIPBOARD_GUEST_FN_REPLY: 921 { 922 rc = VBoxSvcClipboardURITransferHandleReply(pClient, pTransfer, cParms, paParms); 923 break; 924 } 925 926 case VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_OPEN: 927 { 928 VBOXCLIPBOARDLISTOPENPARMS listOpenParms; 929 rc = VBoxSvcClipboardURIGetListOpen(cParms, paParms, &listOpenParms); 930 if (RT_SUCCESS(rc)) 931 { 932 SHAREDCLIPBOARDLISTHANDLE hList; 933 rc = SharedClipboardURITransferListOpen(pTransfer, &listOpenParms, &hList); 934 if (RT_SUCCESS(rc)) 635 935 { 636 uint32_t fFlags = 0; 637 int rc2 = HGCMSvcGetU32(&paParms[2], &fFlags); 638 if ( RT_SUCCESS(rc2) 639 && fFlags) /* Blocking flag set? */ 640 { 641 /* Defer client returning. */ 642 rc = VINF_HGCM_ASYNC_EXECUTE; 643 } 644 else 645 rc = VERR_INVALID_PARAMETER; 646 647 LogFlowFunc(("Message queue is empty, returning %Rrc to guest\n", rc)); 936 /* Return list handle. */ 937 HGCMSvcSetU32(&paParms[1], hList); 648 938 } 649 939 } … … 651 941 } 652 942 653 case VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_OPEN:654 {655 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_OPEN\n"));656 rc = VINF_SUCCESS;657 break;658 }659 660 943 case VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_CLOSE: 661 944 { 662 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_CLOSE\n")); 663 rc = VINF_SUCCESS; 945 if (cParms != VBOX_SHARED_CLIPBOARD_CPARMS_LIST_CLOSE) 946 break; 947 948 SHAREDCLIPBOARDLISTHANDLE hList; 949 /* Note: Context ID (paParms[0]) not used yet. */ 950 rc = HGCMSvcGetU64(&paParms[1], &hList); 951 if (RT_SUCCESS(rc)) 952 { 953 rc = SharedClipboardURITransferListClose(pTransfer, hList); 954 } 664 955 break; 665 956 } … … 667 958 case VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_HDR_READ: 668 959 { 669 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_GUEST_FN_READ_LIST_HDR\n")); 670 671 VBOXCLIPBOARDLISTHANDLE hList; 672 VBOXCLIPBOARDLISTHDR hdrList; 673 rc = VBoxSvcClipboardURIGetListHdr(cParms, paParms, &hList, &hdrList); 960 if (cParms != VBOX_SHARED_CLIPBOARD_CPARMS_LIST_HDR) 961 break; 962 963 SHAREDCLIPBOARDLISTHANDLE hList; 964 /* Note: Context ID (paParms[0]) not used yet. */ 965 rc = HGCMSvcGetU64(&paParms[1], &hList); /* Get list handle. */ 674 966 if (RT_SUCCESS(rc)) 675 967 { 968 VBOXCLIPBOARDLISTHDR hdrList; 969 rc = SharedClipboardURITransferListGetHeader(pTransfer, hList, &hdrList); 676 970 if (RT_SUCCESS(rc)) 677 971 rc = VBoxSvcClipboardURISetListHdr(cParms, paParms, &hdrList); … … 682 976 case VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_HDR_WRITE: 683 977 { 684 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_LIST_HDR\n"));685 686 978 VBOXCLIPBOARDLISTHDR hdrList; 687 979 rc = SharedClipboardURIListHdrInit(&hdrList); 688 980 if (RT_SUCCESS(rc)) 689 981 { 690 VBOXCLIPBOARDLISTHANDLE hList;982 SHAREDCLIPBOARDLISTHANDLE hList; 691 983 rc = VBoxSvcClipboardURIGetListHdr(cParms, paParms, &hList, &hdrList); 692 984 if (RT_SUCCESS(rc)) … … 696 988 697 989 PSHAREDCLIPBOARDURITRANSFERPAYLOAD pPayload; 698 rc = SharedClipboardURITransferPayloadAlloc(SHAREDCLIPBOARDURITRANSFEREVENTTYPE_LIST_HDR_ READ,990 rc = SharedClipboardURITransferPayloadAlloc(SHAREDCLIPBOARDURITRANSFEREVENTTYPE_LIST_HDR_WRITE, 699 991 pvData, cbData, &pPayload); 700 992 if (RT_SUCCESS(rc)) 701 993 { 702 rc = SharedClipboardURITransferEventSignal(pTransfer, SHAREDCLIPBOARDURITRANSFEREVENTTYPE_LIST_HDR_ READ,994 rc = SharedClipboardURITransferEventSignal(pTransfer, SHAREDCLIPBOARDURITRANSFEREVENTTYPE_LIST_HDR_WRITE, 703 995 pPayload); 704 996 } … … 710 1002 case VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_ENTRY_READ: 711 1003 { 712 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_GUEST_FN_READ_LIST_ENTRY\n")); 1004 if (cParms != VBOX_SHARED_CLIPBOARD_CPARMS_LIST_ENTRY) 1005 break; 1006 1007 SHAREDCLIPBOARDLISTHANDLE hList; 1008 /* Note: Context ID (paParms[0]) not used yet. */ 1009 rc = HGCMSvcGetU64(&paParms[1], &hList); /* Get list handle. */ 1010 if (RT_SUCCESS(rc)) 1011 { 1012 VBOXCLIPBOARDLISTENTRY entryList; 1013 rc = SharedClipboardURITransferListRead(pTransfer, hList, &entryList); 1014 } 713 1015 break; 714 1016 } … … 716 1018 case VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_ENTRY_WRITE: 717 1019 { 718 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_LIST_ENTRY\n"));719 720 1020 VBOXCLIPBOARDLISTENTRY entryList; 721 1021 rc = SharedClipboardURIListEntryInit(&entryList); 722 1022 if (RT_SUCCESS(rc)) 723 1023 { 724 VBOXCLIPBOARDLISTHANDLE hList;1024 SHAREDCLIPBOARDLISTHANDLE hList; 725 1025 rc = VBoxSvcClipboardURIGetListEntry(cParms, paParms, &hList, &entryList); 726 1026 if (RT_SUCCESS(rc)) … … 730 1030 731 1031 PSHAREDCLIPBOARDURITRANSFERPAYLOAD pPayload; 732 rc = SharedClipboardURITransferPayloadAlloc(SHAREDCLIPBOARDURITRANSFEREVENTTYPE_LIST_ENTRY_ READ,1032 rc = SharedClipboardURITransferPayloadAlloc(SHAREDCLIPBOARDURITRANSFEREVENTTYPE_LIST_ENTRY_WRITE, 733 1033 pvData, cbData, &pPayload); 734 1034 if (RT_SUCCESS(rc)) 735 1035 { 736 rc = SharedClipboardURITransferEventSignal(pTransfer, SHAREDCLIPBOARDURITRANSFEREVENTTYPE_LIST_ENTRY_ READ,1036 rc = SharedClipboardURITransferEventSignal(pTransfer, SHAREDCLIPBOARDURITRANSFEREVENTTYPE_LIST_ENTRY_WRITE, 737 1037 pPayload); 738 1038 } … … 742 1042 break; 743 1043 } 744 #if 0 1044 1045 #if 0 745 1046 case VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_DIR: 746 1047 { … … 913 1214 #endif 914 1215 case VBOX_SHARED_CLIPBOARD_GUEST_FN_CANCEL: 915 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_FN_CANCEL\n")); 916 1216 { 917 1217 LogRel2(("Shared Clipboard: Transfer canceled\n")); 918 1218 break; 1219 } 919 1220 920 1221 case VBOX_SHARED_CLIPBOARD_GUEST_FN_ERROR: 921 1222 { 922 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_FN_ERROR\n"));923 924 1223 int rcGuest; 925 1224 rc = VBoxSvcClipboardURIGetError(cParms,paParms, &rcGuest); … … 930 1229 931 1230 default: 932 AssertMsgFailed(("Not implemented\n")); 933 break; 934 } 935 936 if (rc == VINF_HGCM_ASYNC_EXECUTE) 937 { 938 try 939 { 940 vboxSvcClipboardClientDefer(pClient, callHandle, u32Function, cParms, paParms); 941 g_listClientsDeferred.push_back(pClient->uClientID); 942 } 943 catch (std::bad_alloc &) 944 { 945 rc = VERR_NO_MEMORY; 946 /* Don't report to guest. */ 947 } 948 } 949 else if (pClient) 950 { 951 int rc2 = vboxSvcClipboardClientComplete(pClient, callHandle, rc); 952 AssertRC(rc2); 953 } 954 955 LogFlowFunc(("Returning uClient=%RU32, rc=%Rrc\n", pClient->uClientID, rc)); 1231 LogFunc(("Not implemented\n")); 1232 break; 1233 } 1234 1235 if (rc != VINF_HGCM_ASYNC_EXECUTE) 1236 { 1237 /* Tell the client that the call is complete (unblocks waiting). */ 1238 LogFlowFunc(("[Client %RU32] Calling pfnCallComplete w/ rc=%Rrc\n", pClient->uClientID, rc)); 1239 AssertPtr(g_pHelpers); 1240 g_pHelpers->pfnCallComplete(callHandle, rc); 1241 } 1242 1243 LogFlowFunc(("[Client %RU32] Returning rc=%Rrc\n", pClient->uClientID, rc)); 956 1244 return rc; 957 1245 } -
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-utils.cpp
r79497 r79630 68 68 break; 69 69 70 case VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_HDR_WRITE: 71 RT_FALL_THROUGH(); 72 case VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_ENTRY_WRITE: 73 RT_FALL_THROUGH(); 74 case VBOX_SHARED_CLIPBOARD_GUEST_FN_OBJ_WRITE: 75 fAllowed = fGuestToHost; 76 break; 77 78 case VBOX_SHARED_CLIPBOARD_GUEST_FN_TRANSFER_REPORT: 79 RT_FALL_THROUGH(); 80 case VBOX_SHARED_CLIPBOARD_GUEST_FN_GET_HOST_MSG: 70 case VBOX_SHARED_CLIPBOARD_GUEST_FN_MSG_PEEK_WAIT: 71 RT_FALL_THROUGH(); 72 case VBOX_SHARED_CLIPBOARD_GUEST_FN_MSG_PEEK_NOWAIT: 73 RT_FALL_THROUGH(); 74 case VBOX_SHARED_CLIPBOARD_GUEST_FN_MSG_GET: 75 RT_FALL_THROUGH(); 76 case VBOX_SHARED_CLIPBOARD_GUEST_FN_STATUS: 81 77 RT_FALL_THROUGH(); 82 78 case VBOX_SHARED_CLIPBOARD_GUEST_FN_CANCEL: … … 89 85 break; 90 86 } 87 88 fAllowed = true; /** @todo FIX !!!! */ 91 89 92 90 LogFlowFunc(("uMsg=%RU32, uMode=%RU32 -> fAllowed=%RTbool\n", uMsg, uMode, fAllowed)); -
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-win.cpp
r79497 r79630 646 646 { 647 647 if (pCtx->Win.hWnd) 648 PostMessage(pCtx->Win.hWnd, WM_ CLOSE, 0 /* wParam */, 0 /* lParam */);648 PostMessage(pCtx->Win.hWnd, WM_DESTROY, 0 /* wParam */, 0 /* lParam */); 649 649 650 650 rc = RTSemEventDestroy(pCtx->hRenderEvent); -
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc.cpp
r79505 r79630 127 127 * the rest of the code stays the same. 128 128 * 129 * @section sec_uri_protocol URI protocol. 130 * 131 * The host service issues commands which the guest has to respond with an own 132 * message to. The protocol itself is designed so that it has primitives to list 133 * directories and open/close/read/write file system objects. 134 * 135 * The protocol does not rely on the old ReportMsg() / ReturnMsg() mechanism anymore 136 * and uses a (per-client) message queue instead (see VBOX_SHARED_CLIPBOARD_GUEST_FN_GET_HOST_MSG_OLD 137 * vs. VBOX_SHARED_CLIPBOARD_GUEST_FN_GET_HOST_MSG). 138 * 139 * Note that this is different from the DnD approach, as Shared Clipboard transfers 140 * need to be deeper integrated within the host / guest OS (i.e. for progress UI), 141 * and this might require non-monolithic / random access APIs to achieve. 142 * 143 * One transfer always is handled by an own (HGCM) client, so for multiple transfers 144 * at the same time, multiple clients (client IDs) are being used. How this transfer 145 * is implemented on the guest (and / or host) side depends upon the actual implementation, 146 * e.g. via an own thread per transfer. 129 147 */ 130 148 … … 136 154 #include <VBox/log.h> 137 155 156 #include <VBox/AssertGuest.h> 138 157 #include <VBox/HostServices/Service.h> 139 158 #include <VBox/HostServices/VBoxClipboardSvc.h> … … 167 186 * Global Variables * 168 187 *********************************************************************************************************************************/ 169 staticPVBOXHGCMSVCHELPERS g_pHelpers;188 PVBOXHGCMSVCHELPERS g_pHelpers; 170 189 171 190 static RTCRITSECT g_CritSect; … … 183 202 static bool g_fHeadless = false; 184 203 185 /** Map of all connected clients. */204 /** Global map of all connected clients. */ 186 205 ClipboardClientMap g_mapClients; 187 206 188 /** List of all clients which are queued up (deferred return) and ready207 /** Global list of all clients which are queued up (deferred return) and ready 189 208 * to process new commands. The key is the (unique) client ID. */ 190 209 ClipboardClientQueue g_listClientsDeferred; 191 210 192 193 #if 0194 static void VBoxHGCMParmPtrSet (VBOXHGCMSVCPARM *pParm, void *pv, uint32_t cb)195 {196 pParm->type = VBOX_HGCM_SVC_PARM_PTR;197 pParm->u.pointer.size = cb;198 pParm->u.pointer.addr = pv;199 }200 #endif201 211 202 212 static int VBoxHGCMParmPtrGet(VBOXHGCMSVCPARM *pParm, void **ppv, uint32_t *pcb) … … 323 333 324 334 /** 335 * Sets the GUEST_MSG_PEEK_WAIT GUEST_MSG_PEEK_NOWAIT return parameters. 336 * 337 * @param paDstParms The peek parameter vector. 338 * @param cDstParms The number of peek parameters (at least two). 339 * @remarks ASSUMES the parameters has been cleared by clientMsgPeek. 340 */ 341 void vboxSvcClipboardMsgSetPeekReturn(PVBOXCLIPBOARDCLIENTMSG pMsg, PVBOXHGCMSVCPARM paDstParms, uint32_t cDstParms) 342 { 343 Assert(cDstParms >= 2); 344 if (paDstParms[0].type == VBOX_HGCM_SVC_PARM_32BIT) 345 paDstParms[0].u.uint32 = pMsg->m_uMsg; 346 else 347 paDstParms[0].u.uint64 = pMsg->m_uMsg; 348 paDstParms[1].u.uint32 = pMsg->m_cParms; 349 350 uint32_t i = RT_MIN(cDstParms, pMsg->m_cParms + 2); 351 while (i-- > 2) 352 switch (pMsg->m_paParms[i - 2].type) 353 { 354 case VBOX_HGCM_SVC_PARM_32BIT: paDstParms[i].u.uint32 = ~(uint32_t)sizeof(uint32_t); break; 355 case VBOX_HGCM_SVC_PARM_64BIT: paDstParms[i].u.uint32 = ~(uint32_t)sizeof(uint64_t); break; 356 case VBOX_HGCM_SVC_PARM_PTR: paDstParms[i].u.uint32 = pMsg->m_paParms[i - 2].u.pointer.size; break; 357 } 358 } 359 360 /** 325 361 * Adds a new message to a client'S message queue. 326 362 * … … 347 383 348 384 /** 349 * Retrieves information about the next message in the queue. 350 * 351 * @returns IPRT status code. VERR_NO_DATA if no next message is available. 352 * @param pClientData Pointer to the client data structure to get message info for. 353 * @param puType Where to store the message type. 354 * @param pcParms Where to store the message parameter count. 385 * Implements VBOX_SHARED_CLIPBOARD_GUEST_FN_MSG_PEEK_WAIT and VBOX_SHARED_CLIPBOARD_GUEST_FN_MSG_PEEK_NOWAIT. 386 * 387 * @returns VBox status code. 388 * @retval VINF_SUCCESS if a message was pending and is being returned. 389 * @retval VERR_TRY_AGAIN if no message pending and not blocking. 390 * @retval VERR_RESOURCE_BUSY if another read already made a waiting call. 391 * @retval VINF_HGCM_ASYNC_EXECUTE if message wait is pending. 392 * 393 * @param pClient The client state. 394 * @param hCall The client's call handle. 395 * @param cParms Number of parameters. 396 * @param paParms Array of parameters. 397 * @param fWait Set if we should wait for a message, clear if to return 398 * immediately. 355 399 */ 356 int vboxSvcClipboardMsgGetNextInfo(PVBOXCLIPBOARDCLIENTDATA pClientData, uint32_t *puType, uint32_t *pcParms) 357 { 358 AssertPtrReturn(puType, VERR_INVALID_POINTER); 359 AssertPtrReturn(pcParms, VERR_INVALID_POINTER); 360 361 int rc; 362 363 if (pClientData->queueMsg.isEmpty()) 364 { 365 rc = VERR_NO_DATA; 366 } 367 else 368 { 369 PVBOXCLIPBOARDCLIENTMSG pMsg = pClientData->queueMsg.first(); 370 AssertPtr(pMsg); 371 372 *puType = pMsg->m_uMsg; 373 *pcParms = pMsg->m_cParms; 400 int vboxSvcClipboardMsgPeek(PVBOXCLIPBOARDCLIENT pClient, VBOXHGCMCALLHANDLE hCall, uint32_t cParms, VBOXHGCMSVCPARM paParms[], 401 bool fWait) 402 { 403 /* 404 * Validate the request. 405 */ 406 ASSERT_GUEST_MSG_RETURN(cParms >= 2, ("cParms=%u!\n", cParms), VERR_WRONG_PARAMETER_COUNT); 407 408 uint64_t idRestoreCheck = 0; 409 uint32_t i = 0; 410 if (paParms[i].type == VBOX_HGCM_SVC_PARM_64BIT) 411 { 412 idRestoreCheck = paParms[0].u.uint64; 413 paParms[0].u.uint64 = 0; 414 i++; 415 } 416 for (; i < cParms; i++) 417 { 418 ASSERT_GUEST_MSG_RETURN(paParms[i].type == VBOX_HGCM_SVC_PARM_32BIT, ("#%u type=%u\n", i, paParms[i].type), 419 VERR_WRONG_PARAMETER_TYPE); 420 paParms[i].u.uint32 = 0; 421 } 422 423 /* 424 * Check restore session ID. 425 */ 426 if (idRestoreCheck != 0) 427 { 428 uint64_t idRestore = g_pHelpers->pfnGetVMMDevSessionId(g_pHelpers); 429 if (idRestoreCheck != idRestore) 430 { 431 paParms[0].u.uint64 = idRestore; 432 LogFlowFunc(("[Client %RU32] VBOX_SHARED_CLIPBOARD_GUEST_FN_MSG_PEEK_XXX -> VERR_VM_RESTORED (%#RX64 -> %#RX64)\n", 433 pClient->uClientID, idRestoreCheck, idRestore)); 434 return VERR_VM_RESTORED; 435 } 436 Assert(!g_pHelpers->pfnIsCallRestored(hCall)); 437 } 438 439 /* 440 * Return information about the first message if one is pending in the list. 441 */ 442 if (!pClient->pData->queueMsg.isEmpty()) 443 { 444 PVBOXCLIPBOARDCLIENTMSG pFirstMsg = pClient->pData->queueMsg.first(); 445 if (pFirstMsg) 446 { 447 vboxSvcClipboardMsgSetPeekReturn(pFirstMsg, paParms, cParms); 448 LogFlowFunc(("[Client %RU32] VBOX_SHARED_CLIPBOARD_GUEST_FN_MSG_PEEK_XXX -> VINF_SUCCESS (idMsg=%u (%s), cParms=%u)\n", 449 pClient->uClientID, pFirstMsg->m_uMsg, VBoxSvcClipboardHostMsgToStr(pFirstMsg->m_uMsg), 450 pFirstMsg->m_cParms)); 451 return VINF_SUCCESS; 452 } 453 } 454 455 /* 456 * If we cannot wait, fail the call. 457 */ 458 if (!fWait) 459 { 460 LogFlowFunc(("[Client %RU32] GUEST_MSG_PEEK_NOWAIT -> VERR_TRY_AGAIN\n", pClient->uClientID)); 461 return VERR_TRY_AGAIN; 462 } 463 464 /* 465 * Wait for the host to queue a message for this client. 466 */ 467 ASSERT_GUEST_MSG_RETURN(pClient->Pending.uType == 0, ("Already pending! (idClient=%RU32)\n", 468 pClient->uClientID), VERR_RESOURCE_BUSY); 469 pClient->Pending.hHandle = hCall; 470 pClient->Pending.cParms = cParms; 471 pClient->Pending.paParms = paParms; 472 pClient->Pending.uType = VBOX_SHARED_CLIPBOARD_GUEST_FN_MSG_PEEK_WAIT; 473 LogFlowFunc(("[Client %RU32] Is now in pending mode...\n", pClient->uClientID)); 474 return VINF_HGCM_ASYNC_EXECUTE; 475 } 476 477 /** 478 * Implements VBOX_SHARED_CLIPBOARD_GUEST_FN_MSG_GET. 479 * 480 * @returns VBox status code. 481 * @retval VINF_SUCCESS if message retrieved and removed from the pending queue. 482 * @retval VERR_TRY_AGAIN if no message pending. 483 * @retval VERR_BUFFER_OVERFLOW if a parmeter buffer is too small. The buffer 484 * size was updated to reflect the required size, though this isn't yet 485 * forwarded to the guest. (The guest is better of using peek with 486 * parameter count + 2 parameters to get the sizes.) 487 * @retval VERR_MISMATCH if the incoming message ID does not match the pending. 488 * @retval VINF_HGCM_ASYNC_EXECUTE if message was completed already. 489 * 490 * @param pClient The client state. 491 * @param hCall The client's call handle. 492 * @param cParms Number of parameters. 493 * @param paParms Array of parameters. 494 */ 495 int vboxSvcClipboardMsgGet(PVBOXCLIPBOARDCLIENT pClient, VBOXHGCMCALLHANDLE hCall, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) 496 { 497 /* 498 * Validate the request. 499 */ 500 uint32_t const idMsgExpected = cParms > 0 && paParms[0].type == VBOX_HGCM_SVC_PARM_32BIT ? paParms[0].u.uint32 501 : cParms > 0 && paParms[0].type == VBOX_HGCM_SVC_PARM_64BIT ? paParms[0].u.uint64 502 : UINT32_MAX; 503 504 /* 505 * Return information about the first message if one is pending in the list. 506 */ 507 PVBOXCLIPBOARDCLIENTMSG pFirstMsg = pClient->pData->queueMsg.first(); 508 if (pFirstMsg) 509 { 510 LogFlowFunc(("First message is: %RU32 %s (%RU32 parms)\n", 511 pFirstMsg->m_uMsg, VBoxSvcClipboardHostMsgToStr(pFirstMsg->m_uMsg), pFirstMsg->m_cParms)); 512 513 ASSERT_GUEST_MSG_RETURN(pFirstMsg->m_uMsg == idMsgExpected || idMsgExpected == UINT32_MAX, 514 ("idMsg=%u (%s) cParms=%u, caller expected %u (%s) and %u\n", 515 pFirstMsg->m_uMsg, VBoxSvcClipboardHostMsgToStr(pFirstMsg->m_uMsg), pFirstMsg->m_uMsg, 516 idMsgExpected, VBoxSvcClipboardHostMsgToStr(idMsgExpected), cParms), 517 VERR_MISMATCH); 518 ASSERT_GUEST_MSG_RETURN(pFirstMsg->m_cParms == cParms, 519 ("idMsg=%u (%s) cParms=%u, caller expected %u (%s) and %u\n", 520 pFirstMsg->m_uMsg, VBoxSvcClipboardHostMsgToStr(pFirstMsg->m_uMsg), pFirstMsg->m_cParms, 521 idMsgExpected, VBoxSvcClipboardHostMsgToStr(idMsgExpected), cParms), 522 VERR_WRONG_PARAMETER_COUNT); 523 524 /* Check the parameter types. */ 525 for (uint32_t i = 0; i < cParms; i++) 526 ASSERT_GUEST_MSG_RETURN(pFirstMsg->m_paParms[i].type == paParms[i].type, 527 ("param #%u: type %u, caller expected %u (idMsg=%u %s)\n", i, pFirstMsg->m_paParms[i].type, 528 paParms[i].type, pFirstMsg->m_uMsg, VBoxSvcClipboardHostMsgToStr(pFirstMsg->m_uMsg)), 529 VERR_WRONG_PARAMETER_TYPE); 530 /* 531 * Copy out the parameters. 532 * 533 * No assertions on buffer overflows, and keep going till the end so we can 534 * communicate all the required buffer sizes. 535 */ 536 int rc = VINF_SUCCESS; 537 for (uint32_t i = 0; i < cParms; i++) 538 switch (pFirstMsg->m_paParms[i].type) 539 { 540 case VBOX_HGCM_SVC_PARM_32BIT: 541 paParms[i].u.uint32 = pFirstMsg->m_paParms[i].u.uint32; 542 break; 543 544 case VBOX_HGCM_SVC_PARM_64BIT: 545 paParms[i].u.uint64 = pFirstMsg->m_paParms[i].u.uint64; 546 break; 547 548 case VBOX_HGCM_SVC_PARM_PTR: 549 { 550 uint32_t const cbSrc = pFirstMsg->m_paParms[i].u.pointer.size; 551 uint32_t const cbDst = paParms[i].u.pointer.size; 552 paParms[i].u.pointer.size = cbSrc; /** @todo Check if this is safe in other layers... 553 * Update: Safe, yes, but VMMDevHGCM doesn't pass it along. */ 554 if (cbSrc <= cbDst) 555 memcpy(paParms[i].u.pointer.addr, pFirstMsg->m_paParms[i].u.pointer.addr, cbSrc); 556 else 557 rc = VERR_BUFFER_OVERFLOW; 558 break; 559 } 560 561 default: 562 AssertMsgFailed(("#%u: %u\n", i, pFirstMsg->m_paParms[i].type)); 563 rc = VERR_INTERNAL_ERROR; 564 break; 565 } 566 if (RT_SUCCESS(rc)) 567 { 568 /* 569 * Complete the message and remove the pending message unless the 570 * guest raced us and cancelled this call in the meantime. 571 */ 572 AssertPtr(g_pHelpers); 573 rc = g_pHelpers->pfnCallComplete(hCall, rc); 574 575 LogFlowFunc(("[Client %RU32] pfnCallComplete -> %Rrc\n", pClient->uClientID, rc)); 576 577 if (rc != VERR_CANCELLED) 578 { 579 pClient->pData->queueMsg.removeFirst(); 580 vboxSvcClipboardMsgFree(pFirstMsg); 581 } 582 583 return VINF_HGCM_ASYNC_EXECUTE; /* The caller must not complete it. */ 584 } 585 586 LogFlowFunc(("[Client %RU32] Returning %Rrc\n", pClient->uClientID, rc)); 587 return rc; 588 } 589 590 paParms[0].u.uint32 = 0; 591 paParms[1].u.uint32 = 0; 592 LogFlowFunc(("[Client %RU32] -> VERR_TRY_AGAIN\n", pClient->uClientID)); 593 return VERR_TRY_AGAIN; 594 } 595 596 int vboxSvcClipboardClientWakeup(PVBOXCLIPBOARDCLIENT pClient) 597 { 598 int rc = VINF_NO_CHANGE; 599 600 if (pClient->Pending.uType) 601 { 602 LogFlowFunc(("[Client %RU32] Waking up ...\n", pClient->uClientID)); 374 603 375 604 rc = VINF_SUCCESS; 376 } 377 378 LogFlowFunc(("Returning puMsg=%RU32, pcParms=%RU32, rc=%Rrc\n", *puType, *pcParms, rc)); 379 return rc; 380 } 381 382 /** 383 * Retrieves the next queued up message and removes it from the queue on success. 384 * Will return VERR_NO_DATA if no next message is available. 385 * 386 * @returns IPRT status code. 387 * @param pClientData Pointer to the client data structure to get message for. 388 * @param uMsg Message type to retrieve. 389 * @param cParms Number of parameters the \@a paParms array can store. 390 * @param paParms Where to store the message parameters. 391 */ 392 int vboxSvcClipboardMsgGetNext(PVBOXCLIPBOARDCLIENTDATA pClientData, 393 uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) 394 { 395 LogFlowFunc(("uMsg=%RU32, cParms=%RU32\n", uMsg, cParms)); 396 397 /* Check for pending messages in our queue. */ 398 if (pClientData->queueMsg.isEmpty()) 399 return VERR_NO_DATA; 400 401 /* Get the current message. */ 402 PVBOXCLIPBOARDCLIENTMSG pMsg = pClientData->queueMsg.first(); 403 AssertPtr(pMsg); 404 405 int rc = VINF_SUCCESS; 406 407 /* Fetch the current message info. */ 408 if (pMsg->m_uMsg != uMsg) 409 { 410 LogFunc(("Stored message type (%RU32) does not match request (%RU32)\n", pMsg->m_uMsg, uMsg)); 411 rc = VERR_INVALID_PARAMETER; 412 } 413 else if (pMsg->m_cParms > cParms) 414 { 415 LogFunc(("Stored parameter count (%RU32) exceeds request buffer (%RU32)\n", pMsg->m_cParms, cParms)); 416 rc = VERR_INVALID_PARAMETER; 417 } 418 419 if (RT_SUCCESS(rc)) 420 { 421 rc = Message::CopyParms(paParms, cParms, pMsg->m_paParms, pMsg->m_cParms, true /* fDeepCopy */); 422 423 /** @todo Only remove on success? */ 424 pClientData->queueMsg.removeFirst(); /* Remove the current message from the queue. */ 425 } 426 else 427 { 428 vboxSvcClipboardMsgQueueReset(pClientData); 429 /** @todo Cleanup, send notification to guest. */ 430 } 431 432 LogFlowFunc(("Message processed with rc=%Rrc\n", rc)); 433 return rc; 605 606 if (!pClient->pData->queueMsg.isEmpty()) 607 { 608 PVBOXCLIPBOARDCLIENTMSG pFirstMsg = pClient->pData->queueMsg.first(); 609 if (pFirstMsg) 610 { 611 LogFlowFunc(("[Client %RU32] Current host message is %RU32 (cParms=%RU32)\n", 612 pClient->uClientID, pFirstMsg->m_uMsg, pFirstMsg->m_cParms)); 613 614 if (pClient->Pending.uType == VBOX_SHARED_CLIPBOARD_GUEST_FN_MSG_PEEK_WAIT) 615 { 616 vboxSvcClipboardMsgSetPeekReturn(pFirstMsg, pClient->Pending.paParms, pClient->Pending.cParms); 617 rc = g_pHelpers->pfnCallComplete(pClient->Pending.hHandle, VINF_SUCCESS); 618 619 pClient->Pending.hHandle = NULL; 620 pClient->Pending.paParms = NULL; 621 pClient->Pending.cParms = 0; 622 pClient->Pending.uType = false; 623 } 624 } 625 else 626 AssertFailed(); 627 } 628 else 629 AssertMsgFailed(("Waking up client ID=%RU32 with no host message in queue is a bad idea\n", pClient->uClientID)); 630 631 return rc; 632 } 633 634 return VINF_NO_CHANGE; 434 635 } 435 636 … … 919 1120 SharedClipboardURITransferSetCallbacks(pTransfer, &Callbacks); 920 1121 921 rc = SharedClipboardURITransfer ProviderCreate(pTransfer, &creationCtx);1122 rc = SharedClipboardURITransferSetInterface(pTransfer, &creationCtx); 922 1123 if (RT_SUCCESS(rc)) 923 1124 rc = SharedClipboardURICtxTransferAdd(&pClientData->URI, pTransfer); … … 1036 1237 creationCtx.pvUser = pClientData; 1037 1238 1038 rc = SharedClipboardURITransfer ProviderCreate(pTransfer, &creationCtx);1239 rc = SharedClipboardURITransferSetInterface(pTransfer, &creationCtx); 1039 1240 if (RT_SUCCESS(rc)) 1040 1241 rc = SharedClipboardURICtxTransferAdd(&pClientData->URI, pTransfer); … … 1233 1434 1234 1435 /** 1235 * Defers a client from returning back to the caller (guest side).1236 *1237 * @returns VBox status code.1238 * @param pClient Client to defer.1239 * @param hHandle The call handle to defer.1240 * @param u32Function Function ID to save.1241 * @param cParms Number of parameters to save.1242 * @param paParms Parameter arrray to save.1243 */1244 int vboxSvcClipboardClientDefer(PVBOXCLIPBOARDCLIENT pClient,1245 VBOXHGCMCALLHANDLE hHandle, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])1246 {1247 LogFlowFunc(("uClient=%RU32\n", pClient->uClientID));1248 1249 AssertMsgReturn(pClient->fDeferred == false, ("Client already in deferred mode\n"),1250 VERR_WRONG_ORDER);1251 1252 pClient->fDeferred = true;1253 1254 pClient->Deferred.hHandle = hHandle;1255 pClient->Deferred.uType = u32Function;1256 pClient->Deferred.cParms = cParms;1257 pClient->Deferred.paParms = paParms;1258 1259 return false;1260 }1261 1262 /**1263 * Completes a call of a client, which in turn will return the result to the caller on1264 * the guest side.1265 *1266 * @returns VBox status code.1267 * @param pClient Client to complete.1268 * @param hHandle Call handle to complete.1269 * @param rc Return code to set for the client.1270 */1271 int vboxSvcClipboardClientComplete(PVBOXCLIPBOARDCLIENT pClient, VBOXHGCMCALLHANDLE hHandle, int rc)1272 {1273 RT_NOREF(pClient);1274 1275 LogFlowFunc(("uClient=%RU32, rc=%Rrc\n", pClient->uClientID, rc));1276 1277 g_pHelpers->pfnCallComplete(hHandle, rc);1278 1279 return VINF_SUCCESS;1280 }1281 1282 /**1283 * Completes a deferred client.1284 *1285 * @returns VBox status code.1286 * @param pClient Client to complete.1287 * @param rcComplete Return code to set for the client.1288 */1289 int vboxSvcClipboardClientDeferredComplete(PVBOXCLIPBOARDCLIENT pClient, int rcComplete)1290 {1291 LogFlowFunc(("uClient=%RU32, fDeferred=%RTbool\n", pClient->uClientID, pClient->fDeferred));1292 1293 int rc = VINF_SUCCESS;1294 1295 if (pClient->fDeferred) /* Not deferred? Bail out early. */1296 {1297 LogFlowFunc(("Completing call\n"));1298 1299 rc = vboxSvcClipboardClientComplete(pClient, pClient->Deferred.hHandle, rcComplete);1300 1301 pClient->fDeferred = false;1302 RT_ZERO(pClient->Deferred);1303 }1304 1305 return rc;1306 }1307 1308 /**1309 * Sets a deferred client's next message info -- when returning to the client, it then1310 * can retrieve the actual message sent by the host.1311 *1312 * @returns VBox status code.1313 * @param pClient Client to set the next message information for.1314 * @param uMsg Message ID to set.1315 * @param cParms Number of parameters of message required.1316 */1317 int vboxSvcClipboardClientDeferredSetMsgInfo(PVBOXCLIPBOARDCLIENT pClient, uint32_t uMsg, uint32_t cParms)1318 {1319 int rc;1320 1321 LogFlowFunc(("uClient=%RU32\n", pClient->uClientID));1322 1323 if (pClient->fDeferred)1324 {1325 if (pClient->Deferred.cParms >= 2)1326 {1327 AssertPtrReturn(pClient->Deferred.paParms, VERR_BUFFER_OVERFLOW);1328 1329 HGCMSvcSetU32(&pClient->Deferred.paParms[0], uMsg);1330 HGCMSvcSetU32(&pClient->Deferred.paParms[1], cParms);1331 1332 rc = VINF_SUCCESS;1333 }1334 else1335 rc = VERR_INVALID_PARAMETER;1336 }1337 else1338 rc = VERR_INVALID_STATE;1339 1340 LogFlowFuncLeaveRC(rc);1341 return rc;1342 }1343 1344 /**1345 1436 * Initializes a Shared Clipboard service's client state. 1346 1437 *
Note:
See TracChangeset
for help on using the changeset viewer.