Changeset 79702 in vbox for trunk/src/VBox/GuestHost/SharedClipboard/ClipboardDataObjectImpl-win.cpp
- Timestamp:
- Jul 11, 2019 7:34:05 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/GuestHost/SharedClipboard/ClipboardDataObjectImpl-win.cpp
r79672 r79702 43 43 #include <VBox/log.h> 44 44 45 /** Also handle Unicode entries. */ 46 #define VBOX_CLIPBOARD_WITH_UNICODE_SUPPORT 1 45 /** @todo Also handle Unicode entries. 46 * !!! WARNING: Buggy, doesn't work yet (some memory corruption / garbage in the file name descriptions) !!! */ 47 //#define VBOX_CLIPBOARD_WITH_UNICODE_SUPPORT 0 47 48 48 49 VBoxClipboardWinDataObject::VBoxClipboardWinDataObject(PSHAREDCLIPBOARDURITRANSFER pTransfer, 49 50 LPFORMATETC pFormatEtc, LPSTGMEDIUM pStgMed, ULONG cFormats) 50 51 : m_enmStatus(Uninitialized) 51 , m_lRefCount( 1)52 , m_lRefCount(0) 52 53 , m_cFormats(0) 53 54 , m_pTransfer(pTransfer) … … 77 78 * Register fixed formats. 78 79 */ 80 unsigned uIdx = 0; 79 81 80 82 LogFlowFunc(("Registering CFSTR_FILEDESCRIPTORA ...\n")); 81 registerFormat(&m_pFormatEtc[FormatIndex_FileDescriptorA],82 RegisterClipboardFormat(CFSTR_FILEDESCRIPTORA));83 m_cfFileDescriptorA = RegisterClipboardFormat(CFSTR_FILEDESCRIPTORA); 84 registerFormat(&m_pFormatEtc[uIdx++], m_cfFileDescriptorA); 83 85 #ifdef VBOX_CLIPBOARD_WITH_UNICODE_SUPPORT 84 86 LogFlowFunc(("Registering CFSTR_FILEDESCRIPTORW ...\n")); 85 registerFormat(&m_pFormatEtc[FormatIndex_FileDescriptorW],86 RegisterClipboardFormat(CFSTR_FILEDESCRIPTORW));87 m_cfFileDescriptorW = RegisterClipboardFormat(CFSTR_FILEDESCRIPTORW); 88 registerFormat(&m_pFormatEtc[uIdx++], m_cfFileDescriptorW); 87 89 #endif 90 88 91 /* IStream interface, implemented in ClipboardStreamImpl-win.cpp. */ 89 92 LogFlowFunc(("Registering CFSTR_FILECONTENTS ...\n")); 90 registerFormat(&m_pFormatEtc[FormatIndex_FileContents], 91 RegisterClipboardFormat(CFSTR_FILECONTENTS), 92 TYMED_ISTREAM, 0 /* lIndex */); 93 m_cfFileContents = RegisterClipboardFormat(CFSTR_FILECONTENTS); 94 registerFormat(&m_pFormatEtc[uIdx++], m_cfFileContents, TYMED_ISTREAM, 0 /* lIndex */); 93 95 94 96 /* … … 296 298 297 299 LogFlowFunc(("\t%s (%RU64 bytes)\n", entryList.pszName, pObjInfo->cbObject)); 300 301 FSOBJENTRY objEntry = { entryList.pszName, *pObjInfo }; 302 pThis->m_lstRootEntries.push_back(objEntry); /** @todo Can this throw? */ 298 303 } 299 304 else … … 362 367 const size_t cbFileDescriptor = fUnicode ? sizeof(FILEDESCRIPTORW) : sizeof(FILEDESCRIPTORA); 363 368 364 const UINT cItems = (UINT) 0; /** @todo UINT vs. uint64_t*/369 const UINT cItems = (UINT)m_lstRootEntries.size(); /** UINT vs. size_t. */ 365 370 if (!cItems) 366 371 return VERR_NOT_FOUND; 372 UINT curIdx = 0; /* Current index of the handled file group descriptor (FGD). */ 367 373 368 374 const size_t cbFGD = cbFileGroupDescriptor + (cbFileDescriptor * (cItems - 1)); … … 371 377 372 378 /* FILEGROUPDESCRIPTORA / FILEGROUPDESCRIPTOR matches except the cFileName member (TCHAR vs. WCHAR). */ 373 FILEGROUPDESCRIPTOR *pFGD = (FILEGROUPDESCRIPTOR *)RTMemAlloc (cbFGD);379 FILEGROUPDESCRIPTOR *pFGD = (FILEGROUPDESCRIPTOR *)RTMemAllocZ(cbFGD); 374 380 if (!pFGD) 375 381 return VERR_NO_MEMORY; … … 380 386 381 387 char *pszFileSpec = NULL; 382 #if 0 383 for (UINT i = 0; i < cItems; i++) 384 { 385 FILEDESCRIPTOR *pFD = &pFGD->fgd[i]; 388 389 FsObjEntryList::const_iterator itRoot = m_lstRootEntries.begin(); 390 while (itRoot != m_lstRootEntries.end()) 391 { 392 FILEDESCRIPTOR *pFD = &pFGD->fgd[curIdx]; 386 393 RT_BZERO(pFD, cbFileDescriptor); 387 394 388 const SharedClipboardURIObject *pObj = pURIList->At(i); 389 AssertPtr(pObj); 390 const char *pszFile = pObj->GetSourcePathAbs().c_str(); 395 const char *pszFile = itRoot->strPath.c_str(); 391 396 AssertPtr(pszFile); 392 397 … … 403 408 pwszFileSpec, RTUtf16Len(pwszFileSpec)); 404 409 RTUtf16Free(pwszFileSpec); 410 411 LogFlowFunc(("pFD->cFileNameW=%ls\n", pFD->cFileName)); 405 412 } 406 413 } 407 414 else 415 { 408 416 rc = RTStrCopy(pFD->cFileName, sizeof(pFD->cFileName), pszFileSpec); 417 LogFlowFunc(("pFD->cFileNameA=%s\n", pFD->cFileName)); 418 } 409 419 410 420 RTStrFree(pszFileSpec); … … 419 429 pFD->dwFileAttributes = FILE_ATTRIBUTE_NORMAL; 420 430 421 switch (pObj->GetType()) 422 { 423 case SharedClipboardURIObject::Type_Directory: 424 pFD->dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY; 425 426 LogFunc(("pszDir=%s\n", pszFile)); 427 break; 428 429 case SharedClipboardURIObject::Type_File: 430 { 431 pFD->dwFlags |= FD_FILESIZE; 432 433 const uint64_t cbObjSize = pObj->GetSize(); 434 435 pFD->nFileSizeHigh = RT_HI_U32(cbObjSize); 436 pFD->nFileSizeLow = RT_LO_U32(cbObjSize); 437 438 LogFunc(("pszFile=%s, cbObjSize=%RU64\n", pszFile, cbObjSize)); 439 break; 440 } 441 442 default: 443 AssertFailed(); 444 break; 445 } 446 #if 0 447 pFD->dwFlags = FD_ATTRIBUTES | FD_CREATETIME | FD_ACCESSTIME | FD_WRITESTIME | FD_FILESIZE; /** @todo Implement this. */ 431 const SHAREDCLIPBOARDFSOBJINFO *pObjInfo = &itRoot->objInfo; 432 433 if (RTFS_IS_DIRECTORY(pObjInfo->Attr.fMode)) 434 { 435 pFD->dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY; 436 } 437 else if (RTFS_IS_FILE(pObjInfo->Attr.fMode)) 438 { 439 pFD->dwFlags |= FD_FILESIZE; 440 441 const uint64_t cbObjSize = pObjInfo->cbObject; 442 443 pFD->nFileSizeHigh = RT_HI_U32(cbObjSize); 444 pFD->nFileSizeLow = RT_LO_U32(cbObjSize); 445 } 446 else if (RTFS_IS_SYMLINK(pObjInfo->Attr.fMode)) 447 { 448 /** @todo Implement. */ 449 } 450 #if 0 /** @todo Implement this. */ 451 pFD->dwFlags = FD_ATTRIBUTES | FD_CREATETIME | FD_ACCESSTIME | FD_WRITESTIME | FD_FILESIZE; 448 452 pFD->dwFileAttributes = 449 453 pFD->ftCreationTime = … … 451 455 pFD->ftLastWriteTime = 452 456 #endif 453 } 454 #endif 457 ++curIdx; 458 ++itRoot; 459 } 455 460 456 461 if (pszFileSpec) … … 458 463 459 464 if (RT_SUCCESS(rc)) 460 {461 465 rc = copyToHGlobal(pFGD, cbFGD, GMEM_MOVEABLE, phGlobal); 462 } 463 else 464 { 465 RTMemFree(pFGD); 466 } 466 467 RTMemFree(pFGD); 467 468 468 469 LogFlowFuncLeaveRC(rc); … … 486 487 LogFlowFuncEnter(); 487 488 488 ULONG lIndex; 489 if (!lookupFormatEtc(pFormatEtc, &lIndex)) /* Format supported? */ 490 return DV_E_FORMATETC; 491 if (lIndex >= m_cFormats) /* Paranoia. */ 492 return DV_E_LINDEX; 493 494 LPFORMATETC pThisFormat = &m_pFormatEtc[lIndex]; 495 AssertPtr(pThisFormat); 496 497 LPSTGMEDIUM pThisMedium = &m_pStgMedium[lIndex]; 498 AssertPtr(pThisMedium); 499 500 LogFlowFunc(("Using pThisFormat=%p, pThisMedium=%p\n", pThisFormat, pThisMedium)); 501 502 HRESULT hr = DV_E_FORMATETC; /* Play safe. */ 503 504 LogRel2(("Shared Clipboard: cfFormat=%RI16, sFormat=%s, tyMed=%RU32, dwAspect=%RU32 -> lIndex=%u\n", 505 pThisFormat->cfFormat, VBoxClipboardWinDataObject::ClipboardFormatToString(pFormatEtc->cfFormat), 506 pThisFormat->tymed, pThisFormat->dwAspect, lIndex)); 489 LogFlowFunc(("lIndex=%RI32\n", pFormatEtc->lindex)); 507 490 508 491 /* 509 492 * Initialize default values. 510 493 */ 511 pMedium->tymed = pThisFormat->tymed; 512 pMedium->pUnkForRelease = NULL; /* Caller is responsible for deleting the data. */ 513 514 switch (lIndex) 515 { 516 case FormatIndex_FileDescriptorA: /* ANSI */ 494 RT_BZERO(pMedium, sizeof(STGMEDIUM)); 495 496 HRESULT hr = DV_E_FORMATETC; /* Play safe. */ 497 498 if ( pFormatEtc->cfFormat == m_cfFileDescriptorA 517 499 #ifdef VBOX_CLIPBOARD_WITH_UNICODE_SUPPORT 518 RT_FALL_THROUGH(); 519 case FormatIndex_FileDescriptorW: /* Unicode */ 500 || pFormatEtc->cfFormat == m_cfFileDescriptorW 520 501 #endif 521 { 522 const bool fUnicode = lIndex == FormatIndex_FileDescriptorW; 523 524 LogFlowFunc(("FormatIndex_FileDescriptor%s\n", fUnicode ? "W" : "A")); 525 526 int rc; 527 528 /* The caller can call GetData() several times, so make sure we don't do the same transfer multiple times. */ 529 if (SharedClipboardURITransferGetStatus(m_pTransfer) == SHAREDCLIPBOARDURITRANSFERSTATUS_NONE) 502 ) 503 { 504 const bool fUnicode = pFormatEtc->cfFormat == m_cfFileDescriptorW; 505 506 LogFlowFunc(("FormatIndex_FileDescriptor%s\n", fUnicode ? "W" : "A")); 507 508 int rc; 509 510 /* The caller can call GetData() several times, so make sure we don't do the same transfer multiple times. */ 511 if (SharedClipboardURITransferGetStatus(m_pTransfer) == SHAREDCLIPBOARDURITRANSFERSTATUS_NONE) 512 { 513 rc = SharedClipboardURITransferPrepare(m_pTransfer); 514 if (RT_SUCCESS(rc)) 530 515 { 531 rc = SharedClipboardURITransferPrepare(m_pTransfer); 516 /* Start the transfer asynchronously in a separate thread. */ 517 rc = SharedClipboardURITransferRun(m_pTransfer, &VBoxClipboardWinDataObject::readThread, this); 532 518 if (RT_SUCCESS(rc)) 533 519 { 534 /* Start the transfer asynchronously in a separate thread. */ 535 rc = SharedClipboardURITransferRun(m_pTransfer, &VBoxClipboardWinDataObject::readThread, this); 520 /* Don't block for too long here, as this also will screw other apps running on the OS. */ 521 LogFunc(("Waiting for listing to arrive ...\n")); 522 rc = RTSemEventWait(m_EventListComplete, 10 * 1000 /* 10s timeout */); 536 523 if (RT_SUCCESS(rc)) 537 524 { 538 /* Don't block for too long here, as this also will screw other apps running on the OS. */ 539 LogFunc(("Waiting for listing to arrive ...\n")); 540 rc = RTSemEventWait(m_EventListComplete, 10 * 1000 /* 10s timeout */); 541 if (RT_SUCCESS(rc)) 542 { 543 LogFunc(("Listing complete\n")); 544 545 HGLOBAL hGlobal; 546 rc = createFileGroupDescriptorFromTransfer(m_pTransfer, fUnicode, &hGlobal); 547 if (RT_SUCCESS(rc)) 548 { 549 pMedium->tymed = TYMED_HGLOBAL; 550 pMedium->hGlobal = hGlobal; 551 /* Note: hGlobal now is being owned by pMedium / the caller. */ 552 553 hr = S_OK; 554 } 555 } 525 LogFunc(("Listing complete\n")); 526 527 556 528 } 557 529 } 558 530 } 559 else 560 rc = VERR_ALREADY_EXISTS; 561 562 if (RT_FAILURE(rc)) 563 LogRel(("Shared Clipboard: Data object unable to get data, rc=%Rrc\n", rc)); 564 565 break; 566 } 567 568 case FormatIndex_FileContents: 569 { 531 } 532 else 533 rc = VINF_SUCCESS; 534 535 if (RT_SUCCESS(rc)) 536 { 537 HGLOBAL hGlobal; 538 rc = createFileGroupDescriptorFromTransfer(m_pTransfer, fUnicode, &hGlobal); 539 if (RT_SUCCESS(rc)) 540 { 541 pMedium->tymed = TYMED_HGLOBAL; 542 pMedium->hGlobal = hGlobal; 543 /* Note: hGlobal now is being owned by pMedium / the caller. */ 544 545 hr = S_OK; 546 } 547 } 548 549 if (RT_FAILURE(rc)) 550 LogRel(("Shared Clipboard: Data object unable to get data, rc=%Rrc\n", rc)); 551 } 552 553 if (pFormatEtc->cfFormat == m_cfFileContents) 554 { 555 if ( pFormatEtc->lindex >= 0 556 && pFormatEtc->lindex < m_lstRootEntries.size()) 557 { 558 m_uObjIdx = pFormatEtc->lindex; /* lIndex of FormatEtc contains the actual index to the object being handled. */ 559 570 560 LogFlowFunc(("FormatIndex_FileContents: m_uObjIdx=%u\n", m_uObjIdx)); 571 561 572 SHAREDCLIPBOARDOBJHANDLE hObj = 0; /** @todo */ 562 FSOBJENTRY &fsObjEntry = m_lstRootEntries.at(m_uObjIdx); 563 564 LogRel2(("Shared Clipboard: Receiving file '%s' ...\n", fsObjEntry.strPath.c_str())); 573 565 574 566 /* Hand-in the provider so that our IStream implementation can continue working with it. */ 575 hr = VBoxClipboardWinStreamImpl::Create(this /* pParent */, m_pTransfer, hObj, &m_pStream); 567 hr = VBoxClipboardWinStreamImpl::Create(this /* pParent */, m_pTransfer, 568 fsObjEntry.strPath.c_str()/* File name */, &fsObjEntry.objInfo /* PSHAREDCLIPBOARDFSOBJINFO */, 569 &m_pStream); 576 570 if (SUCCEEDED(hr)) 577 571 { … … 579 573 pMedium->tymed = TYMED_ISTREAM; 580 574 pMedium->pstm = m_pStream; 581 582 /* Handle next object. */583 m_uObjIdx++;584 575 } 585 break; 586 } 587 588 default: 589 break; 576 } 590 577 } 591 578 … … 595 582 LogFunc(("Failed; copying medium ...\n")); 596 583 597 pMedium->tymed = pThisFormat->tymed;598 pMedium->pUnkForRelease = NULL;584 //pMedium->tymed = pThisFormat->tymed; 585 //pMedium->pUnkForRelease = NULL; 599 586 } 600 587 … … 734 721 RT_NOREF(rc); 735 722 723 LogFlowFunc(("m_uObjIdx=%RU32 (total: %zu)\n", m_uObjIdx, m_lstRootEntries.size())); 724 725 const bool fComplete = m_uObjIdx == m_lstRootEntries.size() - 1 /* Object index is zero-based */; 726 if (fComplete) 727 { 728 int rc2 = RTSemEventSignal(m_EventTransferComplete); 729 AssertRC(rc2); 730 } 731 736 732 LogFlowFuncLeaveRC(rc); 737 733 } … … 739 735 void VBoxClipboardWinDataObject::OnTransferCanceled(void) 740 736 { 737 LogFlowFuncEnter(); 738 739 int rc2 = RTSemEventSignal(m_EventTransferComplete); 740 AssertRC(rc2); 741 741 742 LogFlowFuncLeave(); 742 743 }
Note:
See TracChangeset
for help on using the changeset viewer.