- Timestamp:
- Apr 26, 2019 6:41:46 AM (6 years ago)
- Location:
- trunk/src/VBox
- Files:
-
- 12 edited
- 5 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/VBoxTray/Makefile.kmk
r78151 r78307 47 47 ifdef VBOX_WITH_SHARED_CLIPBOARD 48 48 VBoxTray_DEFS += \ 49 VBOX_WITH_SHARED_CLIPBOARD 49 VBOX_WITH_SHARED_CLIPBOARD \ 50 $(if $(VBOX_WITH_SHARED_CLIPBOARD_URI_LIST),VBOX_WITH_SHARED_CLIPBOARD_URI_LIST,) 50 51 VBoxTray_SOURCES += \ 51 52 VBoxClipboard.cpp \ -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxClipboard.cpp
r78172 r78307 78 78 int vboxrc = VBoxClipboardWinGetFormats(&pCtx->Win, &uFormats); 79 79 if (RT_SUCCESS(vboxrc)) 80 vboxrc = VbglR3Clipboard ReportFormats(pCtx->u32ClientID, uFormats);80 vboxrc = VbglR3ClipboardWriteFormats(pCtx->u32ClientID, uFormats); 81 81 } 82 82 } … … 128 128 int vboxrc = VBoxClipboardWinGetFormats(pWinCtx, &uFormats); 129 129 if (RT_SUCCESS(vboxrc)) 130 vboxrc = VbglR3Clipboard ReportFormats(pCtx->u32ClientID, uFormats);130 vboxrc = VbglR3ClipboardWriteFormats(pCtx->u32ClientID, uFormats); 131 131 } 132 132 … … 386 386 } 387 387 388 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST 389 if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST) 390 hClip = SetClipboardData(CF_HDROP, NULL); 391 #endif 388 392 VBoxClipboardWinClose(); 389 393 … … 466 470 } 467 471 } 468 472 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST 473 else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST) 474 { 475 hClip = GetClipboardData(CF_HDROP); 476 if (hClip) 477 { 478 HDROP hDrop = (HDROP)GlobalLock(hClip); 479 if (hDrop) 480 { 481 vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_URI_LIST, 482 ); 483 GlobalUnlock(hClip); 484 } 485 else 486 { 487 hClip = NULL; 488 } 489 } 490 } 491 #endif 469 492 VBoxClipboardWinClose(); 470 493 } -
trunk/src/VBox/Additions/common/VBoxGuest/lib/Makefile.kmk
r76553 r78307 110 110 VBOX_WITH_HGCM \ 111 111 $(if $(VBOX_WITH_GUEST_PROPS),VBOX_WITH_GUEST_PROPS,) \ 112 $(if $(VBOX_WITH_SHARED_CLIPBOARD),VBOX_WITH_SHARED_CLIPBOARD,) \ 112 113 $(if $(VBOX_WITH_SHARED_FOLDERS),VBOX_WITH_SHARED_FOLDERS,) \ 113 114 $(if $(VBOX_WITH_GUEST_CONTROL),VBOX_WITH_GUEST_CONTROL,) … … 160 161 VBoxGuestR3LibDragAndDrop.cpp 161 162 endif 163 ifdef VBOX_WITH_SHARED_CLIPBOARD 164 VBoxGuestR3Lib_DEFS += \ 165 $(if $(VBOX_WITH_SHARED_CLIPBOARD_URI_LIST),VBOX_WITH_SHARED_CLIPBOARD_URI_LIST,) 166 endif 162 167 163 168 VBoxGuestR3LibAdditions.cpp_DEFS = VBOX_SVN_REV=$(VBOX_SVN_REV) … … 202 207 $(if $(VBOX_WITH_GUEST_PROPS),VBOX_WITH_GUEST_PROPS,) \ 203 208 $(if $(VBOX_WITH_DRAG_AND_DROP),VBOX_WITH_DRAG_AND_DROP,) \ 204 $(if $(VBOX_WITH_DRAG_AND_DROP_GH),VBOX_WITH_DRAG_AND_DROP_GH,) 209 $(if $(VBOX_WITH_DRAG_AND_DROP_GH),VBOX_WITH_DRAG_AND_DROP_GH,) \ 210 $(if $(VBOX_WITH_SHARED_CLIPBOARD_URI_LIST),VBOX_WITH_SHARED_CLIPBOARD_URI_LIST,) 205 211 VBoxGuestR3LibXFree86_SOURCES = \ 206 212 VBoxGuestR3Lib.cpp \ … … 229 235 $(if $(VBOX_WITH_GUEST_PROPS),VBOX_WITH_GUEST_PROPS,) \ 230 236 $(if $(VBOX_WITH_DRAG_AND_DROP),VBOX_WITH_DRAG_AND_DROP,) \ 231 $(if $(VBOX_WITH_DRAG_AND_DROP_GH),VBOX_WITH_DRAG_AND_DROP_GH,) 237 $(if $(VBOX_WITH_DRAG_AND_DROP_GH),VBOX_WITH_DRAG_AND_DROP_GH,) \ 238 $(if $(VBOX_WITH_SHARED_CLIPBOARD_URI_LIST),VBOX_WITH_SHARED_CLIPBOARD_URI_LIST,) 232 239 VBoxGuestR3LibXOrg_SOURCES = $(VBoxGuestR3LibXFree86_SOURCES) 233 240 -
trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibClipboard.cpp
r76553 r78307 29 29 * Header Files * 30 30 *********************************************************************************************************************************/ 31 #include <VBox/GuestHost/SharedClipboard.h> 32 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST 33 # include <VBox/GuestHost/SharedClipboard-uri.h> 34 #endif 31 35 #include <VBox/HostServices/VBoxClipboardSvc.h> 32 36 #include <VBox/err.h> 33 37 #include <iprt/assert.h> 34 38 #include <iprt/string.h> 39 #include <iprt/cpp/ministring.h> 35 40 #include "VBoxGuestR3LibInternal.h" 41 42 43 /********************************************************************************************************************************* 44 * Prototypes * 45 *********************************************************************************************************************************/ 46 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST 47 static int vbglR3ClipboardSendErrorInternal(HGCMCLIENTID idClient, int rcErr); 48 static int vbglR3ClipboardSendURIData(HGCMCLIENTID idClient, const void *pvData, size_t cbData); 49 #endif 36 50 37 51 … … 140 154 141 155 /** 142 * Advertisesguest clipboard formats to the host.156 * Writes (advertises) guest clipboard formats to the host. 143 157 * 144 158 * @returns VBox status code. … … 146 160 * @param fFormats The formats to advertise. 147 161 */ 148 VBGLR3DECL(int) VbglR3Clipboard ReportFormats(HGCMCLIENTID idClient, uint32_t fFormats)149 { 150 VBoxClipboard Formats Msg;151 152 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_FN_ FORMATS, 1);162 VBGLR3DECL(int) VbglR3ClipboardWriteFormats(HGCMCLIENTID idClient, uint32_t fFormats) 163 { 164 VBoxClipboardWriteFormats Msg; 165 166 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_FN_WRITE_FORMATS, 1); 153 167 VbglHGCMParmUInt32Set(&Msg.formats, fFormats); 154 168 … … 156 170 } 157 171 158 159 /** 160 * Send guest clipboard data to the host. 172 /** 173 * Sends guest clipboard data to the host. 161 174 * 162 175 * This is usually called in reply to a VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA message … … 169 182 * @param cb The size of the data. 170 183 */ 171 VBGLR3DECL(int) VbglR3ClipboardWriteData(HGCMCLIENTID idClient, uint32_t fFormat, void *pv, uint32_t cb)184 static int vbglR3ClipboardWriteDataRaw(HGCMCLIENTID idClient, uint32_t fFormat, void *pv, uint32_t cb) 172 185 { 173 186 VBoxClipboardWriteData Msg; … … 179 192 } 180 193 194 /** 195 * Send guest clipboard data to the host. 196 * 197 * This is usually called in reply to a VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA message 198 * from the host. 199 * 200 * @returns VBox status code. 201 * @param idClient The client id returned by VbglR3ClipboardConnect(). 202 * @param fFormat The format of the data. 203 * @param pv The data. 204 * @param cb The size of the data. 205 */ 206 VBGLR3DECL(int) VbglR3ClipboardWriteData(HGCMCLIENTID idClient, uint32_t fFormat, void *pv, uint32_t cb) 207 { 208 int rc; 209 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST 210 if (fFormat == VBOX_SHARED_CLIPBOARD_FMT_URI_LIST) 211 { 212 rc = vbglR3ClipboardSendURIData(idClient, pv, cb); 213 } 214 else 215 #else 216 RT_NOREF(fFormat); 217 #endif 218 rc = vbglR3ClipboardWriteDataRaw(idClient, fFormat, pv, cb); 219 220 if (RT_FAILURE(rc)) 221 { 222 int rc2 = vbglR3ClipboardSendErrorInternal(idClient, rc); 223 if (RT_FAILURE(rc2)) 224 LogFlowFunc(("Unable to send error (%Rrc) to host, rc=%Rrc\n", rc, rc2)); 225 } 226 227 return rc; 228 } 229 230 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST 231 /** 232 * Guest -> Host 233 * Utility function to send clipboard data from guest to the host. 234 * 235 * @returns IPRT status code. 236 * @param idClient The client id returned by VbglR3ClipboardConnect(). 237 * @param pvData Data block to send. 238 * @param cbData Size (in bytes) of data block to send. 239 * @param pDataHdr Data header to use -- needed for accounting. 240 */ 241 static int vbglR3ClipboardSendDataInternal(HGCMCLIENTID idClient, 242 void *pvData, uint64_t cbData, PVBOXCLIPBOARDDATAHDR pDataHdr) 243 { 244 AssertPtrReturn(pvData, VERR_INVALID_POINTER); 245 AssertReturn(cbData, VERR_INVALID_PARAMETER); 246 AssertPtrReturn(pDataHdr, VERR_INVALID_POINTER); 247 248 VBoxClipboardWriteDataHdrMsg MsgHdr; 249 RT_ZERO(MsgHdr); 250 251 VBGL_HGCM_HDR_INIT(&MsgHdr.hdr, idClient, VBOX_SHARED_CLIPBOARD_FN_WRITE_DATA_HDR, 12); 252 MsgHdr.uContext.SetUInt32(0); /** @todo Not used yet. */ 253 MsgHdr.uFlags.SetUInt32(0); /** @todo Not used yet. */ 254 MsgHdr.uScreenId.SetUInt32(0); /** @todo Not used for guest->host (yet). */ 255 MsgHdr.cbTotal.SetUInt64(pDataHdr->cbTotal); 256 MsgHdr.cbMeta.SetUInt32(pDataHdr->cbMeta); 257 MsgHdr.pvMetaFmt.SetPtr(pDataHdr->pvMetaFmt, pDataHdr->cbMetaFmt); 258 MsgHdr.cbMetaFmt.SetUInt32(pDataHdr->cbMetaFmt); 259 MsgHdr.cObjects.SetUInt64(pDataHdr->cObjects); 260 MsgHdr.enmCompression.SetUInt32(0); /** @todo Not used yet. */ 261 MsgHdr.enmChecksumType.SetUInt32(RTDIGESTTYPE_INVALID); /** @todo Not used yet. */ 262 MsgHdr.pvChecksum.SetPtr(NULL, 0); /** @todo Not used yet. */ 263 MsgHdr.cbChecksum.SetUInt32(0); /** @todo Not used yet. */ 264 265 int rc = VbglR3HGCMCall(&MsgHdr.hdr, sizeof(MsgHdr)); 266 267 LogFlowFunc(("cbTotal=%RU64, cbMeta=%RU32, cObjects=%RU64, rc=%Rrc\n", 268 pDataHdr->cbTotal, pDataHdr->cbMeta, pDataHdr->cObjects, rc)); 269 270 if (RT_SUCCESS(rc)) 271 { 272 VBoxClipboardWriteDataChunkMsg MsgData; 273 RT_ZERO(MsgData); 274 275 VBGL_HGCM_HDR_INIT(&MsgData.hdr, idClient, VBOX_SHARED_CLIPBOARD_FN_WRITE_DATA_CHUNK, 5); 276 MsgData.uContext.SetUInt32(0); /** @todo Not used yet. */ 277 MsgData.pvChecksum.SetPtr(NULL, 0); /** @todo Not used yet. */ 278 MsgData.cbChecksum.SetUInt32(0); /** @todo Not used yet. */ 279 280 uint32_t cbCurChunk; 281 const uint32_t cbMaxChunk = VBOX_SHARED_CLIPBOARD_MAX_CHUNK_SIZE; 282 uint32_t cbSent = 0; 283 284 HGCMFunctionParameter *pParm = &MsgData.pvData; 285 286 while (cbSent < cbData) 287 { 288 cbCurChunk = RT_MIN(cbData - cbSent, cbMaxChunk); 289 pParm->SetPtr(static_cast<uint8_t *>(pvData) + cbSent, cbCurChunk); 290 291 MsgData.cbData.SetUInt32(cbCurChunk); 292 293 rc = VbglR3HGCMCall(&MsgData.hdr, sizeof(MsgData)); 294 if (RT_FAILURE(rc)) 295 break; 296 297 cbSent += cbCurChunk; 298 } 299 300 LogFlowFunc(("cbMaxChunk=%RU32, cbData=%RU64, cbSent=%RU32, rc=%Rrc\n", 301 cbMaxChunk, cbData, cbSent, rc)); 302 303 if (RT_SUCCESS(rc)) 304 Assert(cbSent == cbData); 305 } 306 307 LogFlowFuncLeaveRC(rc); 308 return rc; 309 } 310 311 /** 312 * Guest -> Host 313 * Utility function to send a guest directory to the host. 314 * 315 * @returns IPRT status code. 316 * @param idClient The client id returned by VbglR3ClipboardConnect(). 317 * @param pObj URI object containing the directory to send. 318 */ 319 static int vbglR3ClipboardSendDir(HGCMCLIENTID idClient, SharedClipboardURIObject *pObj) 320 { 321 AssertPtrReturn(pObj, VERR_INVALID_POINTER); 322 AssertReturn(pObj->GetType() == SharedClipboardURIObject::Type_Directory, VERR_INVALID_PARAMETER); 323 324 RTCString strPath = pObj->GetDestPathAbs(); 325 LogFlowFunc(("strDir=%s (%zu), fMode=0x%x\n", 326 strPath.c_str(), strPath.length(), pObj->GetMode())); 327 328 if (strPath.length() > RTPATH_MAX) 329 return VERR_INVALID_PARAMETER; 330 331 const uint32_t cbPath = (uint32_t)strPath.length() + 1; /* Include termination. */ 332 333 VBoxClipboardWriteDirMsg Msg; 334 RT_ZERO(Msg); 335 336 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_FN_WRITE_DIR, 4); 337 /** @todo Context ID not used yet. */ 338 Msg.pvName.SetPtr((void *)strPath.c_str(), (uint32_t)cbPath); 339 Msg.cbName.SetUInt32((uint32_t)cbPath); 340 Msg.fMode.SetUInt32(pObj->GetMode()); 341 342 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg)); 343 } 344 345 /** 346 * Guest -> Host 347 * Utility function to send a file from the guest to the host. 348 * 349 * @returns IPRT status code. 350 * @param idClient The client id returned by VbglR3ClipboardConnect(). 351 * @param pObj URI object containing the file to send. 352 */ 353 static int vbglR3ClipboardSendFile(HGCMCLIENTID idClient, SharedClipboardURIObject *pObj) 354 { 355 AssertPtrReturn(pObj, VERR_INVALID_POINTER); 356 AssertReturn(pObj->GetType() == SharedClipboardURIObject::Type_File, VERR_INVALID_PARAMETER); 357 AssertReturn(pObj->IsOpen(), VERR_INVALID_STATE); 358 359 uint32_t cbBuf = _64K; /** @todo Make this configurable? */ 360 void *pvBuf = RTMemAlloc(cbBuf); 361 if (!pvBuf) 362 return VERR_NO_MEMORY; 363 364 RTCString strPath = pObj->GetDestPathAbs(); 365 366 LogFlowFunc(("strFile=%s (%zu), cbSize=%RU64, fMode=0x%x\n", strPath.c_str(), strPath.length(), 367 pObj->GetSize(), pObj->GetMode())); 368 369 VBoxClipboardWriteFileHdrMsg MsgHdr; 370 RT_ZERO(MsgHdr); 371 372 VBGL_HGCM_HDR_INIT(&MsgHdr.hdr, idClient, VBOX_SHARED_CLIPBOARD_FN_WRITE_FILE_HDR, 6); 373 MsgHdr.uContext.SetUInt32(0); /* Context ID; unused at the moment. */ 374 MsgHdr.pvName.SetPtr((void *)strPath.c_str(), (uint32_t)(strPath.length() + 1)); 375 MsgHdr.cbName.SetUInt32((uint32_t)(strPath.length() + 1)); 376 MsgHdr.uFlags.SetUInt32(0); /* Flags; unused at the moment. */ 377 MsgHdr.fMode.SetUInt32(pObj->GetMode()); /* File mode */ 378 MsgHdr.cbTotal.SetUInt64(pObj->GetSize()); /* File size (in bytes). */ 379 380 int rc = VbglR3HGCMCall(&MsgHdr.hdr, sizeof(MsgHdr)); 381 382 LogFlowFunc(("Sending file header resulted in %Rrc\n", rc)); 383 384 if (RT_SUCCESS(rc)) 385 { 386 /* 387 * Send the actual file data, chunk by chunk. 388 */ 389 VBoxClipboardWriteFileDataMsg Msg; 390 RT_ZERO(Msg); 391 392 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_FN_WRITE_FILE_DATA, 5); 393 Msg.uContext.SetUInt32(0); 394 Msg.pvChecksum.SetPtr(NULL, 0); 395 Msg.cbChecksum.SetUInt32(0); 396 397 uint64_t cbToReadTotal = pObj->GetSize(); 398 uint64_t cbWrittenTotal = 0; 399 while (cbToReadTotal) 400 { 401 uint32_t cbToRead = RT_MIN(cbToReadTotal, cbBuf); 402 uint32_t cbRead = 0; 403 if (cbToRead) 404 rc = pObj->Read(pvBuf, cbToRead, &cbRead); 405 406 LogFlowFunc(("cbToReadTotal=%RU64, cbToRead=%RU32, cbRead=%RU32, rc=%Rrc\n", 407 cbToReadTotal, cbToRead, cbRead, rc)); 408 409 if ( RT_SUCCESS(rc) 410 && cbRead) 411 { 412 Msg.pvData.SetPtr(pvBuf, cbRead); 413 Msg.cbData.SetUInt32(cbRead); 414 /** @todo Calculate + set checksums. */ 415 416 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg)); 417 } 418 419 if (RT_FAILURE(rc)) 420 { 421 LogFlowFunc(("Reading failed with rc=%Rrc\n", rc)); 422 break; 423 } 424 425 Assert(cbRead <= cbToReadTotal); 426 cbToReadTotal -= cbRead; 427 cbWrittenTotal += cbRead; 428 429 LogFlowFunc(("%RU64/%RU64 -- %RU8%%\n", cbWrittenTotal, pObj->GetSize(), cbWrittenTotal * 100 / pObj->GetSize())); 430 }; 431 } 432 433 RTMemFree(pvBuf); 434 435 LogFlowFuncLeaveRC(rc); 436 return rc; 437 } 438 439 /** 440 * Guest -> Host 441 * Utility function to send an URI object from guest to the host. 442 * 443 * @returns IPRT status code. 444 * @param idClient The client id returned by VbglR3ClipboardConnect(). 445 * @param pObj URI object to send from guest to the host. 446 */ 447 static int vbglR3ClipboardSendURIObject(HGCMCLIENTID idClient, SharedClipboardURIObject *pObj) 448 { 449 AssertPtrReturn(pObj, VERR_INVALID_POINTER); 450 451 int rc; 452 453 switch (pObj->GetType()) 454 { 455 case SharedClipboardURIObject::Type_Directory: 456 rc = vbglR3ClipboardSendDir(idClient, pObj); 457 break; 458 459 case SharedClipboardURIObject::Type_File: 460 rc = vbglR3ClipboardSendFile(idClient, pObj); 461 break; 462 463 default: 464 AssertMsgFailed(("Object type %ld not implemented\n", pObj->GetType())); 465 rc = VERR_NOT_IMPLEMENTED; 466 break; 467 } 468 469 return rc; 470 } 471 472 /** 473 * Guest -> Host 474 * Utility function to send URI data from guest to the host. 475 * 476 * @returns IPRT status code. 477 * @param idClient The client id returned by VbglR3ClipboardConnect(). 478 * @param pvData Block to URI data to send. 479 * @param cbData Size (in bytes) of URI data to send. 480 */ 481 static int vbglR3ClipboardSendURIData(HGCMCLIENTID idClient, const void *pvData, size_t cbData) 482 { 483 AssertPtrReturn(pvData, VERR_INVALID_POINTER); 484 AssertReturn(cbData, VERR_INVALID_PARAMETER); 485 486 RTCList<RTCString> lstPaths = 487 RTCString((const char *)pvData, cbData).split("\r\n"); 488 489 /** @todo Add symlink support (SHAREDCLIPBOARDURILIST_FLAGS_RESOLVE_SYMLINKS) here. */ 490 /** @todo Add lazy loading (SHAREDCLIPBOARDURILIST_FLAGS_LAZY) here. */ 491 uint32_t fFlags = SHAREDCLIPBOARDURILIST_FLAGS_KEEP_OPEN; 492 493 SharedClipboardURIList lstURI; 494 int rc = lstURI.AppendURIPathsFromList(lstPaths, fFlags); 495 if (RT_SUCCESS(rc)) 496 { 497 /* 498 * Send the (meta) data; in case of URIs it's the (non-recursive) file/directory 499 * URI list the host needs to know upfront to set up the drag'n drop operation. 500 */ 501 RTCString strRootDest = lstURI.GetRootEntries(); 502 if (strRootDest.isNotEmpty()) 503 { 504 void *pvURIList = (void *)strRootDest.c_str(); /* URI root list. */ 505 uint32_t cbURLIist = (uint32_t)strRootDest.length() + 1; /* Include string termination. */ 506 507 /* The total size also contains the size of the meta data. */ 508 uint64_t cbTotal = cbURLIist; 509 cbTotal += lstURI.GetTotalBytes(); 510 511 /* We're going to send an URI list in text format. */ 512 const char szMetaFmt[] = "text/uri-list"; 513 const uint32_t cbMetaFmt = (uint32_t)strlen(szMetaFmt) + 1; /* Include termination. */ 514 515 VBOXCLIPBOARDDATAHDR dataHdr; 516 dataHdr.uFlags = 0; /* Flags not used yet. */ 517 dataHdr.cbTotal = cbTotal; 518 dataHdr.cbMeta = cbURLIist; 519 dataHdr.pvMetaFmt = (void *)szMetaFmt; 520 dataHdr.cbMetaFmt = cbMetaFmt; 521 dataHdr.cObjects = lstURI.GetTotalCount(); 522 523 rc = vbglR3ClipboardSendDataInternal(idClient, 524 pvURIList, cbURLIist, &dataHdr); 525 } 526 else 527 rc = VERR_INVALID_PARAMETER; 528 } 529 530 if (RT_SUCCESS(rc)) 531 { 532 while (!lstURI.IsEmpty()) 533 { 534 SharedClipboardURIObject *pNextObj = lstURI.First(); 535 536 rc = vbglR3ClipboardSendURIObject(idClient, pNextObj); 537 if (RT_FAILURE(rc)) 538 break; 539 540 lstURI.RemoveFirst(); 541 } 542 } 543 544 return rc; 545 } 546 547 /** 548 * Guest -> Host 549 * Sends an error back to the host. 550 * 551 * @returns IPRT status code. 552 * @param idClient The client id returned by VbglR3ClipboardConnect(). 553 * @param rcErr Error (IPRT-style) to send. 554 */ 555 static int vbglR3ClipboardSendErrorInternal(HGCMCLIENTID idClient, int rcErr) 556 { 557 VBoxClipboardWriteErrorMsg Msg; 558 RT_ZERO(Msg); 559 560 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_FN_WRITE_ERROR, 2); 561 /** @todo Context ID not used yet. */ 562 Msg.uContext.SetUInt32(0); 563 Msg.rc.SetUInt32((uint32_t)rcErr); /* uint32_t vs. int. */ 564 565 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg)); 566 567 /* 568 * Never return an error if the host did not accept the error at the current 569 * time. This can be due to the host not having any appropriate callbacks 570 * set which would handle that error. 571 * 572 * bird: Looks like VERR_NOT_SUPPORTED is what the host will return if it 573 * doesn't an appropriate callback. The code used to ignore ALL errors 574 * the host would return, also relevant ones. 575 */ 576 if (RT_FAILURE(rc)) 577 LogFlowFunc(("Sending error %Rrc failed with rc=%Rrc\n", rcErr, rc)); 578 if (rc == VERR_NOT_SUPPORTED) 579 rc = VINF_SUCCESS; 580 581 return rc; 582 } 583 584 /** 585 * Guest -> Host 586 * Send an error back to the host. 587 * 588 * @returns IPRT status code. 589 * @param idClient The client id returned by VbglR3ClipboardConnect(). 590 * @param rcErr Error (IPRT-style) to send. 591 */ 592 VBGLR3DECL(int) VbglR3ClipboardSendError(HGCMCLIENTID idClient, int rcErr) 593 { 594 return vbglR3ClipboardSendErrorInternal(idClient, rcErr); 595 } 596 #endif /* VBOX_WITH_SHARED_CLIPBOARD_URI_LIST */ 597 -
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceClipboard-os2.cpp
r78181 r78307 611 611 } 612 612 VGSvcVerbose(4, "clipboard: reporting fFormats=%#x\n", fFormats); 613 VbglR3Clipboard ReportFormats(g_u32ClientId, fFormats);613 VbglR3ClipboardWriteFormats(g_u32ClientId, fFormats); 614 614 } 615 615 … … 658 658 g_fEmptyClipboard = true; 659 659 VGSvcVerbose(3, "Reporting empty clipboard\n"); 660 VbglR3Clipboard ReportFormats(g_u32ClientId, 0);660 VbglR3ClipboardWriteFormats(g_u32ClientId, 0); 661 661 } 662 662 } … … 681 681 g_fEmptyClipboard = true; 682 682 VGSvcVerbose(3, "Reporting empty clipboard\n"); 683 VbglR3Clipboard ReportFormats(g_u32ClientId, 0);683 VbglR3ClipboardWriteFormats(g_u32ClientId, 0); 684 684 685 685 vgsvcClipboardOs2PollViewer(); -
trunk/src/VBox/Additions/haiku/VBoxTray/VBoxClipboard.cpp
r76553 r78307 345 345 be_clipboard->Unlock(); 346 346 347 VbglR3Clipboard ReportFormats(fClientId, formats);347 VbglR3ClipboardWriteFormats(fClientId, formats); 348 348 break; 349 349 } -
trunk/src/VBox/Additions/x11/VBoxClient/Makefile.kmk
r78162 r78307 41 41 check3d.cpp 42 42 43 ifdef VBOX_WITH_SHARED_CLIPBOARD44 VBoxClient_DEFS += \45 VBOX_WITH_SHARED_CLIPBOARD46 VBoxClient_SOURCES += \47 $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/clipboard-common.cpp \48 $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/clipboard-x11.cpp \49 clipboard.cpp50 endif51 52 43 VBoxClient_SOURCES.linux = \ 53 44 chk_stubs.c … … 91 82 VBoxClient_DEFS += VBOX_WITH_GUEST_PROPS 92 83 endif 84 93 85 ifdef VBOX_WITH_DRAG_AND_DROP 94 86 VBoxClient_DEFS += \ … … 100 92 $(VBOX_LIB_VBGL_R3) \ 101 93 $(PATH_STAGE_LIB)/additions/VBoxDnDGuestR3Lib$(VBOX_SUFF_LIB) 94 endif 95 96 ifdef VBOX_WITH_SHARED_CLIPBOARD 97 VBoxClient_DEFS += \ 98 VBOX_WITH_SHARED_CLIPBOARD \ 99 $(if $(VBOX_WITH_SHARED_CLIPBOARD_URI_LIST),VBOX_WITH_SHARED_CLIPBOARD_URI_LIST,) 100 VBoxClient_SOURCES += \ 101 $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/clipboard-common.cpp \ 102 $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/clipboard-x11.cpp \ 103 clipboard.cpp 104 ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST 105 ifdef VBOX_WITH_LIBFUSE 106 VBoxClient_SOURCES += \ 107 clipboard-fuse.cpp 108 VBoxClient_LIBS += \ 109 libfuse 110 endif 111 ifdef VBOX_WITH_LIBGVFS 112 VBoxClient_SOURCES += \ 113 clipboard-gvfs.c 114 VBOX_VBOXCLIENT_GVFS_VER:=1.31.92 115 VBoxClient_INCS += \ 116 gvfs-$(VBOX_VBOXCLIENT_GVFS_VER)/common \ 117 gvfs-$(VBOX_VBOXCLIENT_GVFS_VER)/client \ 118 gvfs-$(VBOX_VBOXCLIENT_GVFS_VER)/daemon \ 119 /usr/lib/x86_64-linux-gnu/glib-2.0/include \ 120 /usr/include/glib-2.0 121 VBoxClient_LIBS += \ 122 libgio-2.0 \ 123 libglib-2.0 124 endif 125 endif 102 126 endif 103 127 -
trunk/src/VBox/Additions/x11/VBoxClient/clipboard.cpp
r76553 r78307 152 152 RT_NOREF1(pCtx); 153 153 LogRelFlowFunc(("u32Formats=%d\n", u32Formats)); 154 int rc = VbglR3Clipboard ReportFormats(g_ctx.client, u32Formats);154 int rc = VbglR3ClipboardWriteFormats(g_ctx.client, u32Formats); 155 155 LogRelFlowFunc(("rc=%Rrc\n", rc)); 156 156 } -
trunk/src/VBox/GuestHost/SharedClipboard/clipboard-win.cpp
r78171 r78307 303 303 break; 304 304 305 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST 306 case CF_HDROP: 307 uFormats |= VBOX_SHARED_CLIPBOARD_FMT_URI_LIST; 308 break; 309 #endif 305 310 default: 306 311 { -
trunk/src/VBox/HostServices/SharedClipboard/Makefile.kmk
r78161 r78307 27 27 DLLS += VBoxSharedClipboard 28 28 VBoxSharedClipboard_TEMPLATE = VBOXR3 29 VBoxSharedClipboard_DEFS = VBOX_WITH_HGCM 29 VBoxSharedClipboard_DEFS = \ 30 VBOX_WITH_HGCM \ 31 $(if $(VBOX_WITH_SHARED_CLIPBOARD_URI_LIST),VBOX_WITH_SHARED_CLIPBOARD_URI_LIST,) 30 32 VBoxSharedClipboard_INCS.win = \ 31 33 $(VBOX_PATH_SDK) -
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-win.cpp
r78171 r78307 32 32 #include <iprt/thread.h> 33 33 #include <iprt/ldr.h> 34 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST 35 # include <iprt/utf16.h> 36 #endif 37 34 38 #include <process.h> 39 #include <shlobj.h> /* Needed for shell objects. */ 35 40 36 41 #include "VBoxClipboard.h" … … 112 117 LogFlow(("vboxClipboardGetData cbSrc = %d, cbDst = %d\n", cbSrc, cbDst)); 113 118 114 if ( u32Format == VBOX_SHARED_CLIPBOARD_FMT_HTML119 if ( u32Format == VBOX_SHARED_CLIPBOARD_FMT_HTML 115 120 && IsWindowsHTML((const char *)pvSrc)) 116 121 { … … 134 139 *pcbActualDst = 0; 135 140 } 141 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST 142 if (u32Format == VBOX_SHARED_CLIPBOARD_FMT_URI_LIST) 143 { 144 /* Convert data to URI list. */ 145 } 146 #endif 136 147 else 137 148 { … … 283 294 UINT format = (UINT)wParam; 284 295 285 Log(("WM_RENDERFORMAT %d\n", format));296 Log(("WM_RENDERFORMAT: Format %u\n", format)); 286 297 287 298 switch (format) … … 298 309 if (format >= 0xC000) 299 310 { 300 TCHAR szFormatName[256]; 301 302 int cActual = GetClipboardFormatName(format, szFormatName, sizeof(szFormatName)/sizeof (TCHAR)); 303 311 TCHAR szFormatName[256]; /** @todo r=andy Unicode, 256 is enough? */ 312 int cActual = GetClipboardFormatName(format, szFormatName, sizeof(szFormatName) / sizeof (TCHAR)); 304 313 if (cActual) 305 314 { 306 if (strcmp (szFormatName, "HTML Format") == 0) 307 { 315 if (RTStrCmp(szFormatName, "HTML Format") == 0) 308 316 u32Format |= VBOX_SHARED_CLIPBOARD_FMT_HTML; 309 } 317 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST 318 if ( RTStrCmp(szFormatName, CFSTR_FILEDESCRIPTOR) == 0 319 || RTStrCmp(szFormatName, CFSTR_FILECONTENTS) == 0) 320 u32Format |= VBOX_SHARED_CLIPBOARD_FMT_URI_LIST; 321 #endif 310 322 } 311 323 } … … 321 333 else 322 334 { 323 int vboxrc = vboxClipboardReadDataFromClient 335 int vboxrc = vboxClipboardReadDataFromClient(pCtx, u32Format); 324 336 325 337 LogFunc(("vboxClipboardReadDataFromClient vboxrc = %d, pv %p, cb %d, u32Format %d\n", … … 331 343 && pCtx->pClient->data.u32Format == u32Format) 332 344 { 333 HANDLE hMem = GlobalAlloc 345 HANDLE hMem = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, pCtx->pClient->data.cb); 334 346 335 347 LogFunc(("hMem %p\n", hMem)); … … 337 349 if (hMem) 338 350 { 339 void *pMem = GlobalLock 340 341 LogFunc(("pMem %p, GlobalSize %d\n", pMem, GlobalSize 351 void *pMem = GlobalLock(hMem); 352 353 LogFunc(("pMem %p, GlobalSize %d\n", pMem, GlobalSize(hMem))); 342 354 343 355 if (pMem) … … 347 359 if (pCtx->pClient->data.pv) 348 360 { 349 memcpy 350 351 RTMemFree 361 memcpy(pMem, pCtx->pClient->data.pv, pCtx->pClient->data.cb); 362 363 RTMemFree(pCtx->pClient->data.pv); 352 364 pCtx->pClient->data.pv = NULL; 353 365 } … … 357 369 358 370 /* The memory must be unlocked before inserting to the Clipboard. */ 359 GlobalUnlock 371 GlobalUnlock(hMem); 360 372 361 373 /* 'hMem' contains the host clipboard data. 362 374 * size is 'cb' and format is 'format'. 363 375 */ 364 HANDLE hClip = SetClipboardData 376 HANDLE hClip = SetClipboardData(format, hMem); 365 377 366 378 LogFunc(("vboxClipboardHostEvent hClip %p\n", hClip)); … … 373 385 } 374 386 375 GlobalFree 387 GlobalFree(hMem); 376 388 } 377 389 } 378 390 379 RTMemFree 391 RTMemFree(pCtx->pClient->data.pv); 380 392 pCtx->pClient->data.pv = NULL; 381 393 pCtx->pClient->data.cb = 0; … … 446 458 } 447 459 460 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST 461 if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST) 462 { 463 UINT format = RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR); 464 if (format) 465 hClip = SetClipboardData(format, NULL); 466 } 467 #endif 448 468 VBoxClipboardWinClose(); 449 469 … … 590 610 g_ctx.hRenderEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 591 611 592 rc = RTThreadCreate(&g_ctx.hThread, VBoxClipboardThread, NULL, 65536,612 rc = RTThreadCreate(&g_ctx.hThread, VBoxClipboardThread, NULL, _64K /* Stack size */, 593 613 RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "SHCLIP"); 594 614 … … 788 808 } 789 809 } 790 810 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST 811 else if (u32Format & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST) 812 { 813 #if 0 814 UINT format = RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR); 815 if (format) 816 { 817 hClip = GetClipboardData(format); 818 if (hClip != NULL) 819 { 820 LPVOID lp = GlobalLock(hClip); 821 822 if (lp != NULL) 823 { 824 LogFunc(("CF_HTML\n")); 825 826 vboxClipboardGetData(VBOX_SHARED_CLIPBOARD_FMT_HTML, lp, GlobalSize(hClip), 827 pv, cb, pcbActual); 828 LogRelFlowFunc(("Raw HTML clipboard data from host :")); 829 DumpHtml((char *)pv, cb); 830 GlobalUnlock(hClip); 831 } 832 else 833 { 834 hClip = NULL; 835 } 836 } 837 } 838 #else 839 /* Convert to a string list, separated by \r\n. */ 840 DROPFILES *pDropFiles = (DROPFILES *)hClip; 841 AssertPtr(pDropFiles); 842 843 /* Do we need to do Unicode stuff? */ 844 const bool fUnicode = RT_BOOL(pDropFiles->fWide); 845 846 /* Get the offset of the file list. */ 847 Assert(pDropFiles->pFiles >= sizeof(DROPFILES)); 848 849 /* Note: This is *not* pDropFiles->pFiles! DragQueryFile only 850 * will work with the plain storage medium pointer! */ 851 HDROP hDrop = (HDROP)(hClip); 852 853 /* First, get the file count. */ 854 /** @todo Does this work on Windows 2000 / NT4? */ 855 char *pszFiles = NULL; 856 uint32_t cchFiles = 0; 857 UINT cFiles = DragQueryFile(hDrop, UINT32_MAX /* iFile */, NULL /* lpszFile */, 0 /* cchFile */); 858 859 LogRel(("DnD: Got %RU16 file(s), fUnicode=%RTbool\n", cFiles, fUnicode)); 860 861 for (UINT i = 0; i < cFiles; i++) 862 { 863 UINT cchFile = DragQueryFile(hDrop, i /* File index */, NULL /* Query size first */, 0 /* cchFile */); 864 Assert(cchFile); 865 866 if (RT_FAILURE(rc)) 867 break; 868 869 char *pszFileUtf8 = NULL; /* UTF-8 version. */ 870 UINT cchFileUtf8 = 0; 871 if (fUnicode) 872 { 873 /* Allocate enough space (including terminator). */ 874 WCHAR *pwszFile = (WCHAR *)RTMemAlloc((cchFile + 1) * sizeof(WCHAR)); 875 if (pwszFile) 876 { 877 const UINT cwcFileUtf16 = DragQueryFileW(hDrop, i /* File index */, 878 pwszFile, cchFile + 1 /* Include terminator */); 879 880 AssertMsg(cwcFileUtf16 == cchFile, ("cchFileUtf16 (%RU16) does not match cchFile (%RU16)\n", 881 cwcFileUtf16, cchFile)); 882 RT_NOREF(cwcFileUtf16); 883 884 rc = RTUtf16ToUtf8(pwszFile, &pszFileUtf8); 885 if (RT_SUCCESS(rc)) 886 { 887 cchFileUtf8 = (UINT)strlen(pszFileUtf8); 888 Assert(cchFileUtf8); 889 } 890 891 RTMemFree(pwszFile); 892 } 893 else 894 rc = VERR_NO_MEMORY; 895 } 896 else /* ANSI */ 897 { 898 /* Allocate enough space (including terminator). */ 899 pszFileUtf8 = (char *)RTMemAlloc((cchFile + 1) * sizeof(char)); 900 if (pszFileUtf8) 901 { 902 cchFileUtf8 = DragQueryFileA(hDrop, i /* File index */, 903 pszFileUtf8, cchFile + 1 /* Include terminator */); 904 905 AssertMsg(cchFileUtf8 == cchFile, ("cchFileUtf8 (%RU16) does not match cchFile (%RU16)\n", 906 cchFileUtf8, cchFile)); 907 } 908 else 909 rc = VERR_NO_MEMORY; 910 } 911 912 if (RT_SUCCESS(rc)) 913 { 914 LogFlowFunc(("\tFile: %s (cchFile=%RU16)\n", pszFileUtf8, cchFileUtf8)); 915 916 LogRel(("DnD: Adding guest file '%s'\n", pszFileUtf8)); 917 918 rc = RTStrAAppendExN(&pszFiles, 1 /* cPairs */, pszFileUtf8, cchFileUtf8); 919 if (RT_SUCCESS(rc)) 920 cchFiles += cchFileUtf8; 921 } 922 else 923 LogRel(("DnD: Error handling file entry #%u, rc=%Rrc\n", i, rc)); 924 925 if (pszFileUtf8) 926 RTStrFree(pszFileUtf8); 927 928 if (RT_FAILURE(rc)) 929 break; 930 931 /* Add separation between filenames. 932 * Note: Also do this for the last element of the list. */ 933 rc = RTStrAAppendExN(&pszFiles, 1 /* cPairs */, "\r\n", 2 /* Bytes */); 934 if (RT_SUCCESS(rc)) 935 cchFiles += 2; /* Include \r\n */ 936 } 937 938 if (RT_SUCCESS(rc)) 939 { 940 cchFiles += 1; /* Add string termination. */ 941 uint32_t cbFiles = cchFiles * sizeof(char); 942 943 LogFlowFunc(("cFiles=%u, cchFiles=%RU32, cbFiles=%RU32, pszFiles=0x%p\n", 944 cFiles, cchFiles, cbFiles, pszFiles)); 945 946 /* Translate the list into URI elements. */ 947 DnDURIList lstURI; 948 rc = lstURI.AppendNativePathsFromList(pszFiles, cbFiles, 949 DNDURILIST_FLAGS_ABSOLUTE_PATHS); 950 if (RT_SUCCESS(rc)) 951 { 952 RTCString strRoot = lstURI.GetRootEntries(); 953 size_t cbRoot = strRoot.length() + 1; /* Include termination */ 954 955 mpvData = RTMemAlloc(cbRoot); 956 if (mpvData) 957 { 958 memcpy(mpvData, strRoot.c_str(), cbRoot); 959 mcbData = cbRoot; 960 } 961 else 962 rc = VERR_NO_MEMORY; 963 } 964 } 965 966 LogFlowFunc(("Building CF_HDROP list rc=%Rrc, pszFiles=0x%p, cFiles=%RU16, cchFiles=%RU32\n", 967 rc, pszFiles, cFiles, cchFiles)); 968 969 if (pszFiles) 970 RTStrFree(pszFiles); 971 break; 972 #endif /* 0 */ 973 } 974 #endif /* VBOX_WITH_SHARED_CLIPBOARD_URI_LIST */ 791 975 VBoxClipboardWinClose(); 792 976 } … … 893 1077 894 1078 895 /* 896 * Converts clipboard data from CF_HTML format to mimie clipboard format1079 /** 1080 * Converts clipboard data from CF_HTML format to MIME clipboard format. 897 1081 * 898 1082 * Returns allocated buffer that contains html converted to text/html mime type -
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc.cpp
r78171 r78307 484 484 } break; 485 485 486 case VBOX_SHARED_CLIPBOARD_FN_ FORMATS:486 case VBOX_SHARED_CLIPBOARD_FN_WRITE_FORMATS: 487 487 { 488 488 /* The guest reports that some formats are available. */
Note:
See TracChangeset
for help on using the changeset viewer.