VirtualBox

Ignore:
Timestamp:
Jul 11, 2019 7:34:05 PM (5 years ago)
Author:
vboxsync
Message:

Shared Clipboard/URI: Update.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/GuestHost/SharedClipboard/ClipboardDataObjectImpl-win.cpp

    r79672 r79702  
    4343#include <VBox/log.h>
    4444
    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
    4748
    4849VBoxClipboardWinDataObject::VBoxClipboardWinDataObject(PSHAREDCLIPBOARDURITRANSFER pTransfer,
    4950                                                       LPFORMATETC pFormatEtc, LPSTGMEDIUM pStgMed, ULONG cFormats)
    5051    : m_enmStatus(Uninitialized)
    51     , m_lRefCount(1)
     52    , m_lRefCount(0)
    5253    , m_cFormats(0)
    5354    , m_pTransfer(pTransfer)
     
    7778         * Register fixed formats.
    7879         */
     80        unsigned uIdx = 0;
    7981
    8082        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);
    8385#ifdef VBOX_CLIPBOARD_WITH_UNICODE_SUPPORT
    8486        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);
    8789#endif
     90
    8891        /* IStream interface, implemented in ClipboardStreamImpl-win.cpp. */
    8992        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 */);
    9395
    9496        /*
     
    296298
    297299                                    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? */
    298303                                }
    299304                                else
     
    362367    const size_t cbFileDescriptor = fUnicode ? sizeof(FILEDESCRIPTORW) : sizeof(FILEDESCRIPTORA);
    363368
    364     const UINT   cItems = (UINT)0; /** @todo UINT vs. uint64_t */
     369    const UINT   cItems = (UINT)m_lstRootEntries.size(); /** UINT vs. size_t. */
    365370    if (!cItems)
    366371        return VERR_NOT_FOUND;
     372          UINT   curIdx = 0; /* Current index of the handled file group descriptor (FGD). */
    367373
    368374    const size_t cbFGD  = cbFileGroupDescriptor + (cbFileDescriptor * (cItems - 1));
     
    371377
    372378    /* FILEGROUPDESCRIPTORA / FILEGROUPDESCRIPTOR matches except the cFileName member (TCHAR vs. WCHAR). */
    373     FILEGROUPDESCRIPTOR *pFGD = (FILEGROUPDESCRIPTOR *)RTMemAlloc(cbFGD);
     379    FILEGROUPDESCRIPTOR *pFGD = (FILEGROUPDESCRIPTOR *)RTMemAllocZ(cbFGD);
    374380    if (!pFGD)
    375381        return VERR_NO_MEMORY;
     
    380386
    381387    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];
    386393        RT_BZERO(pFD, cbFileDescriptor);
    387394
    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();
    391396        AssertPtr(pszFile);
    392397
     
    403408                                   pwszFileSpec, RTUtf16Len(pwszFileSpec));
    404409                RTUtf16Free(pwszFileSpec);
     410
     411                LogFlowFunc(("pFD->cFileNameW=%ls\n", pFD->cFileName));
    405412            }
    406413        }
    407414        else
     415        {
    408416            rc = RTStrCopy(pFD->cFileName, sizeof(pFD->cFileName), pszFileSpec);
     417            LogFlowFunc(("pFD->cFileNameA=%s\n", pFD->cFileName));
     418        }
    409419
    410420        RTStrFree(pszFileSpec);
     
    419429        pFD->dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
    420430
    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;
    448452        pFD->dwFileAttributes =
    449453        pFD->ftCreationTime   =
     
    451455        pFD->ftLastWriteTime  =
    452456#endif
    453     }
    454 #endif
     457        ++curIdx;
     458        ++itRoot;
     459    }
    455460
    456461    if (pszFileSpec)
     
    458463
    459464    if (RT_SUCCESS(rc))
    460     {
    461465        rc = copyToHGlobal(pFGD, cbFGD, GMEM_MOVEABLE, phGlobal);
    462     }
    463     else
    464     {
    465         RTMemFree(pFGD);
    466     }
     466
     467    RTMemFree(pFGD);
    467468
    468469    LogFlowFuncLeaveRC(rc);
     
    486487    LogFlowFuncEnter();
    487488
    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));
    507490
    508491    /*
    509492     * Initialize default values.
    510493     */
    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
    517499#ifdef VBOX_CLIPBOARD_WITH_UNICODE_SUPPORT
    518             RT_FALL_THROUGH();
    519         case FormatIndex_FileDescriptorW: /* Unicode */
     500        || pFormatEtc->cfFormat == m_cfFileDescriptorW
    520501#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))
    530515            {
    531                 rc = SharedClipboardURITransferPrepare(m_pTransfer);
     516                /* Start the transfer asynchronously in a separate thread. */
     517                rc = SharedClipboardURITransferRun(m_pTransfer, &VBoxClipboardWinDataObject::readThread, this);
    532518                if (RT_SUCCESS(rc))
    533519                {
    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 */);
    536523                    if (RT_SUCCESS(rc))
    537524                    {
    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
    556528                    }
    557529                }
    558530            }
    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
    570560            LogFlowFunc(("FormatIndex_FileContents: m_uObjIdx=%u\n", m_uObjIdx));
    571561
    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()));
    573565
    574566            /* 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);
    576570            if (SUCCEEDED(hr))
    577571            {
     
    579573                pMedium->tymed = TYMED_ISTREAM;
    580574                pMedium->pstm  = m_pStream;
    581 
    582                 /* Handle next object. */
    583                 m_uObjIdx++;
    584575            }
    585             break;
    586         }
    587 
    588         default:
    589             break;
     576        }
    590577    }
    591578
     
    595582        LogFunc(("Failed; copying medium ...\n"));
    596583
    597         pMedium->tymed          = pThisFormat->tymed;
    598         pMedium->pUnkForRelease = NULL;
     584        //pMedium->tymed          = pThisFormat->tymed;
     585        //pMedium->pUnkForRelease = NULL;
    599586    }
    600587
     
    734721    RT_NOREF(rc);
    735722
     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
    736732    LogFlowFuncLeaveRC(rc);
    737733}
     
    739735void VBoxClipboardWinDataObject::OnTransferCanceled(void)
    740736{
     737    LogFlowFuncEnter();
     738
     739    int rc2 = RTSemEventSignal(m_EventTransferComplete);
     740    AssertRC(rc2);
     741
    741742    LogFlowFuncLeave();
    742743}
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette