VirtualBox

Changeset 79027 in vbox


Ignore:
Timestamp:
Jun 6, 2019 2:47:16 PM (6 years ago)
Author:
vboxsync
Message:

Shared Clipboard/URI: Update (more glue code, transfer callbacks).

Location:
trunk
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/GuestHost/SharedClipboard-uri.h

    r78974 r79027  
    386386{
    387387    /** Actual meta data block. */
    388     void  *pvMeta;
     388    void    *pvMeta;
    389389    /** Total size (in bytes) of the allocated meta data block .*/
    390     size_t cbMeta;
     390    uint32_t cbMeta;
    391391    /** How many bytes are being used in the meta data block. */
    392     size_t cbUsed;
     392    uint32_t cbUsed;
    393393} SHAREDCLIPBOARDMETADATA, *PSHAREDCLIPBOARDMETADATA;
    394394
     
    396396void SharedClipboardMetaDataDestroy(PSHAREDCLIPBOARDMETADATA pMeta);
    397397int SharedClipboardMetaDataAdd(PSHAREDCLIPBOARDMETADATA pMeta, const void *pvDataAdd, uint32_t cbDataAdd);
    398 int SharedClipboardMetaDataResize(PSHAREDCLIPBOARDMETADATA pMeta, size_t cbNewSize);
     398int SharedClipboardMetaDataResize(PSHAREDCLIPBOARDMETADATA pMeta, uint32_t cbNewSize);
     399size_t SharedClipboardMetaDataGetFree(PSHAREDCLIPBOARDMETADATA pMeta);
    399400size_t SharedClipboardMetaDataGetUsed(PSHAREDCLIPBOARDMETADATA pMeta);
    400401size_t SharedClipboardMetaDataGetSize(PSHAREDCLIPBOARDMETADATA pMeta);
     
    453454public: /* Interface to be implemented. */
    454455
    455     virtual int ReadMetaData(uint32_t fFlags = 0);
    456     virtual int WriteMetaData(const void *pvBuf, size_t cbBuf, size_t *pcbWritten, uint32_t fFlags = 0);
     456    virtual int ReadDataHdr(PVBOXCLIPBOARDDATAHDR pDataHdr);
     457    virtual int WriteDataHdr(const PVBOXCLIPBOARDDATAHDR pDataHdr);
     458
     459    virtual int ReadMetaData(const PVBOXCLIPBOARDDATAHDR pDataHdr, void *pvMeta, uint32_t cbMeta, uint32_t *pcbRead, uint32_t fFlags = 0);
     460    virtual int WriteMetaData(const PVBOXCLIPBOARDDATAHDR pDataHdr, const void *pvMeta, uint32_t cbMeta, uint32_t *pcbWritten,
     461                              uint32_t fFlags = 0);
    457462
    458463    virtual int ReadDirectory(PVBOXCLIPBOARDDIRDATA pDirData);
    459     virtual int ReadDirectoryObj(SharedClipboardURIObject &Obj);
    460 
    461464    virtual int WriteDirectory(const PVBOXCLIPBOARDDIRDATA pDirData);
    462     virtual int WriteDirectoryObj(const SharedClipboardURIObject &Obj);
    463465
    464466    virtual int ReadFileHdr(PVBOXCLIPBOARDFILEHDR pFileHdr);
    465     virtual int ReadFileHdrObj(SharedClipboardURIObject &Obj);
    466 
    467467    virtual int WriteFileHdr(const PVBOXCLIPBOARDFILEHDR pFileHdr);
    468     virtual int WriteFileHdrObj(const SharedClipboardURIObject &Obj);
    469468
    470469    virtual int ReadFileData(PVBOXCLIPBOARDFILEDATA pFileData, uint32_t *pcbRead);
    471     virtual int ReadFileDataObj(SharedClipboardURIObject &Obj, uint32_t *pcbRead);
    472 
    473470    virtual int WriteFileData(const PVBOXCLIPBOARDFILEDATA pFileData, uint32_t *pcbWritten);
    474     virtual int WriteFileDataObj(const SharedClipboardURIObject &Obj, uint32_t *pcbWritten);
    475471
    476472    virtual void Reset(void);
    477 
    478 public:
    479 
    480           SharedClipboardURIList   &GetURIList(void) { return m_URIList; }
    481     const SharedClipboardURIObject *GetURIObjectCurrent(void) { return m_URIList.First(); }
    482473
    483474protected:
     
    489480    /** Number of references to this instance. */
    490481    volatile uint32_t      m_cRefs;
    491     /** Current URI list. */
    492     SharedClipboardURIList m_URIList;
    493482};
    494483
     
    506495public:
    507496
    508     int ReadMetaData(uint32_t fFlags = 0);
    509     int WriteMetaData(const void *pvBuf, size_t cbBuf, size_t *pcbWritten, uint32_t fFlags = 0);
     497    int ReadDataHdr(PVBOXCLIPBOARDDATAHDR pDataHdr);
     498    int WriteDataHdr(const PVBOXCLIPBOARDDATAHDR pDataHdr);
     499
     500    int ReadMetaData(const PVBOXCLIPBOARDDATAHDR pDataHdr, void *pvMeta, uint32_t cbMeta, uint32_t *pcbRead, uint32_t fFlags = 0);
     501    int WriteMetaData(const PVBOXCLIPBOARDDATAHDR pDataHdr, const void *pvMeta, uint32_t cbMeta, uint32_t *pcbWritten,
     502                      uint32_t fFlags = 0);
    510503
    511504    int ReadDirectory(PVBOXCLIPBOARDDIRDATA pDirData);
     
    514507    int ReadFileHdr(PVBOXCLIPBOARDFILEHDR pFileHdr);
    515508    int WriteFileHdr(const PVBOXCLIPBOARDFILEHDR pFileHdr);
     509
    516510    int ReadFileData(PVBOXCLIPBOARDFILEDATA pFileData, uint32_t *pcbRead);
    517511    int WriteFileData(const PVBOXCLIPBOARDFILEDATA pFileData, uint32_t *pcbWritten);
     
    543537};
    544538
    545 typedef DECLCALLBACK(int) FNSHAREDCLIPBOARDURITRANSFERSTARTED(void *pvUser);
     539struct _SHAREDCLIPBOARDURITRANSFER;
     540typedef _SHAREDCLIPBOARDURITRANSFER *PSHAREDCLIPBOARDURITRANSFER;
     541
     542/**
     543 * Structure for storing URI transfer callback data.
     544 */
     545typedef struct _SHAREDCLIPBOARDURITRANSFERCALLBACKDATA
     546{
     547    /** Pointer to related URI transfer. */
     548    PSHAREDCLIPBOARDURITRANSFER pTransfer;
     549    /** Saved user pointer. */
     550    void                       *pvUser;
     551} SHAREDCLIPBOARDURITRANSFERCALLBACKDATA, *PSHAREDCLIPBOARDURITRANSFERCALLBACKDATA;
     552
     553typedef DECLCALLBACK(void) FNSHAREDCLIPBOARDURITRANSFERSTARTED(PSHAREDCLIPBOARDURITRANSFERCALLBACKDATA pData);
    546554/** Pointer to a FNSHAREDCLIPBOARDURITRANSFERSTARTED function. */
    547555typedef FNSHAREDCLIPBOARDURITRANSFERSTARTED *PFNSHAREDCLIPBOARDURITRANSFERSTARTED;
    548556
    549 typedef DECLCALLBACK(int) FNSHAREDCLIPBOARDURITRANSFERCANCELED(void *pvUser);
     557typedef DECLCALLBACK(void) FNSHAREDCLIPBOARDURITRANSFERCANCELED(PSHAREDCLIPBOARDURITRANSFERCALLBACKDATA pData);
    550558/** Pointer to a FNSHAREDCLIPBOARDURITRANSFERCANCELED function. */
    551559typedef FNSHAREDCLIPBOARDURITRANSFERCANCELED *PFNSHAREDCLIPBOARDURITRANSFERCANCELED;
    552560
    553 typedef DECLCALLBACK(int) FNSHAREDCLIPBOARDURITRANSFERCOMPLETE(void *pvUser, int rc);
     561typedef DECLCALLBACK(void) FNSHAREDCLIPBOARDURITRANSFERCOMPLETE(PSHAREDCLIPBOARDURITRANSFERCALLBACKDATA pData, int rc);
    554562/** Pointer to a FNSHAREDCLIPBOARDURITRANSFERCOMPLETE function. */
    555563typedef FNSHAREDCLIPBOARDURITRANSFERCOMPLETE *PFNSHAREDCLIPBOARDURITRANSFERCOMPLETE;
    556564
    557 typedef DECLCALLBACK(int) FNSHAREDCLIPBOARDURITRANSFERERROR(void *pvUser, int rc);
     565typedef DECLCALLBACK(void) FNSHAREDCLIPBOARDURITRANSFERERROR(PSHAREDCLIPBOARDURITRANSFERCALLBACKDATA pData, int rc);
    558566/** Pointer to a FNSHAREDCLIPBOARDURITRANSFERERROR function. */
    559567typedef FNSHAREDCLIPBOARDURITRANSFERERROR *PFNSHAREDCLIPBOARDURITRANSFERERROR;
     
    565573typedef struct _SHAREDCLIPBOARDURITRANSFERCALLBACKS
    566574{
     575    /** Saved user pointer. */
     576    void                                 *pvUser;
    567577    /** Function pointer, called when the transfer has been started. */
    568578    PFNSHAREDCLIPBOARDURITRANSFERSTARTED  pfnTransferStarted;
     
    590600
    591601/**
     602 * Enumeration specifying an URI transfer direction.
     603 */
     604typedef enum _SHAREDCLIPBOARDURITRANSFERDIR
     605{
     606    /** Unknown transfer directory. */
     607    SHAREDCLIPBOARDURITRANSFERDIR_UNKNOWN = 0,
     608    /** Read transfer (from source). */
     609    SHAREDCLIPBOARDURITRANSFERDIR_READ,
     610    /** Write transfer (to target). */
     611    SHAREDCLIPBOARDURITRANSFERDIR_WRITE,
     612    /** The usual 32-bit hack. */
     613    SHAREDCLIPBOARDURITRANSFERDIR__32BIT_HACK = 0x7fffffff
     614} SHAREDCLIPBOARDURITRANSFERDIR;
     615
     616/**
    592617 * Structure for maintaining a single URI transfer.
     618 *
     619 ** @todo Not yet thread safe.
    593620 */
    594621typedef struct _SHAREDCLIPBOARDURITRANSFER
     
    596623    /** The node member for using this struct in a RTList. */
    597624    RTLISTNODE                          Node;
     625    /** Critical section for serializing access. */
     626    RTCRITSECT                          CritSect;
     627    /** The transfer's direction. */
     628    SHAREDCLIPBOARDURITRANSFERDIR       enmDir;
     629    /** The transfer's meta data cache. */
     630    VBOXCLIPBOARDDATAHDR                Header;
     631    /** The transfer's meta data cache. */
     632    SHAREDCLIPBOARDMETADATA             Meta;
     633    /** The URI list for this transfer. */
     634    SharedClipboardURIList              URIList;
    598635    /** The Shared Clipboard provider in charge for this transfer. */
    599636    SharedClipboardProvider            *pProvider;
     
    604641    /** Contains thread-related attributes. */
    605642    SHAREDCLIPBOARDURITRANSFERTHREAD    Thread;
     643    /** (Optional) callbacks related to this transfer. */
     644    SHAREDCLIPBOARDURITRANSFERCALLBACKS Callbacks;
    606645} SHAREDCLIPBOARDURITRANSFER, *PSHAREDCLIPBOARDURITRANSFER;
    607646
     
    621660} SHAREDCLIPBOARDURICTX, *PSHAREDCLIPBOARDURICTX;
    622661
    623 int SharedClipboardURITransferCreate(PSHAREDCLIPBOARDPROVIDERCREATIONCTX pCtx,
     662int SharedClipboardURITransferCreate(SHAREDCLIPBOARDURITRANSFERDIR enmDir, PSHAREDCLIPBOARDPROVIDERCREATIONCTX pCtx,
    624663                                     PSHAREDCLIPBOARDURITRANSFER *ppTransfer);
    625 void SharedClipboardURITransferDestroy(PSHAREDCLIPBOARDURITRANSFER pTransfer);
     664int SharedClipboardURITransferDestroy(PSHAREDCLIPBOARDURITRANSFER pTransfer);
    626665void SharedClipboardURITransferReset(PSHAREDCLIPBOARDURITRANSFER pTransfer);
     666const SharedClipboardURIObject *SharedClipboardURITransferGetCurrentObject(PSHAREDCLIPBOARDURITRANSFER pTransfer);
     667SharedClipboardProvider *SharedClipboardURITransferGetProvider(PSHAREDCLIPBOARDURITRANSFER pTransfer);
     668const SharedClipboardURIList *SharedClipboardURITransferGetList(PSHAREDCLIPBOARDURITRANSFER pTransfer);
     669const SharedClipboardURIObject *SharedClipboardURITransferGetObject(PSHAREDCLIPBOARDURITRANSFER pTransfer, uint64_t uIdx);
     670void SharedClipboardURITransferSetCallbacks(PSHAREDCLIPBOARDURITRANSFER pTransfer, PSHAREDCLIPBOARDURITRANSFERCALLBACKS pCallbacks);
     671int SharedClipboardURITransferThreadCreate(PSHAREDCLIPBOARDURITRANSFER pTransfer);
     672int SharedClipboardURITransferThreadDestroy(PSHAREDCLIPBOARDURITRANSFER pTransfer, RTMSINTERVAL uTimeoutMs);
     673
     674int SharedClipboardURITransferMetaDataAdd(PSHAREDCLIPBOARDURITRANSFER pTransfer, const void *pvMeta, uint32_t cbMeta);
     675int SharedClipboardURITransferMetaGet(PSHAREDCLIPBOARDURITRANSFER pTransfer, const void *pvMeta, uint32_t cbMeta);
     676int SharedClipboardURITransferMetaDataRead(PSHAREDCLIPBOARDURITRANSFER pTransfer, uint32_t *pcbRead);
     677int SharedClipboardURITransferMetaDataWrite(PSHAREDCLIPBOARDURITRANSFER pTransfer, uint32_t *pcbWritten);
     678
    627679int SharedClipboardURITransferWrite(PSHAREDCLIPBOARDURITRANSFER pTransfer);
    628 int SharedClipboardURITransferWriteThread(RTTHREAD hThread, void *pvUser);
    629 
    630 int SharedClipboardURICtxInit(PSHAREDCLIPBOARDURICTX pURI, PSHAREDCLIPBOARDURITRANSFER pTransfer);
     680int SharedClipboardURITransferWriteObjects(PSHAREDCLIPBOARDURITRANSFER pTransfer);
     681
     682int SharedClipboardURICtxInit(PSHAREDCLIPBOARDURICTX pURI);
    631683void SharedClipboardURICtxDestroy(PSHAREDCLIPBOARDURICTX pURI);
    632684void SharedClipboardURICtxReset(PSHAREDCLIPBOARDURICTX pURI);
     
    634686uint32_t SharedClipboardURICtxGetActiveTransfers(PSHAREDCLIPBOARDURICTX pURI);
    635687int SharedClipboardURICtxTransferAdd(PSHAREDCLIPBOARDURICTX pURI, PSHAREDCLIPBOARDURITRANSFER pTransfer);
     688int SharedClipboardURICtxTransferRemove(PSHAREDCLIPBOARDURICTX pURI, PSHAREDCLIPBOARDURITRANSFER pTransfer);
    636689
    637690bool SharedClipboardMIMEHasFileURLs(const char *pcszFormat, size_t cchFormatMax);
  • trunk/include/VBox/GuestHost/SharedClipboard-win.h

    r78974 r79027  
    260260
    261261    VBoxClipboardWinStreamImpl(VBoxClipboardWinDataObject *pParent,
    262                                PSHAREDCLIPBOARDURITRANSFER pTransfer, SharedClipboardURIObject *pURIObj);
     262                               PSHAREDCLIPBOARDURITRANSFER pTransfer, uint64_t uObjIdx);
    263263    virtual ~VBoxClipboardWinStreamImpl(void);
    264264
     
    286286
    287287    static HRESULT Create(VBoxClipboardWinDataObject *pParent,
    288                           PSHAREDCLIPBOARDURITRANSFER pTransfer, SharedClipboardURIObject *pURIObj, IStream **ppStream);
     288                          PSHAREDCLIPBOARDURITRANSFER pTransfer, uint64_t uObjIdx, IStream **ppStream);
    289289
    290290private:
     
    295295    LONG                        m_lRefCount;
    296296    /** Pointer to the associated URI transfer object. */
    297     PSHAREDCLIPBOARDURITRANSFER m_pTransfer;
    298     /** Pointer to the associated URI object. */
    299     SharedClipboardURIObject   *m_pURIObj;
     297    PSHAREDCLIPBOARDURITRANSFER m_pURITransfer;
     298    /** Index of the object to handle within the associated URI transfer object. */
     299    uint64_t                    m_uObjIdx;
    300300};
    301301
  • trunk/include/VBox/VBoxGuestLib.h

    r78946 r79027  
    602602VBGLR3DECL(int)     VbglR3ClipboardDisconnect(HGCMCLIENTID idClient);
    603603VBGLR3DECL(int)     VbglR3ClipboardGetHostMsg(HGCMCLIENTID idClient, uint32_t *pMsg, uint32_t *pfFormats);
    604 #  ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
    605 VBGLR3DECL(int)     VbglR3ClipboardReadMetaData(HGCMCLIENTID idClient, SharedClipboardURIList &URIList);
    606 VBGLR3DECL(int)     VbglR3ClipboardWriteMetaData(HGCMCLIENTID idClient, const SharedClipboardURIList &URIList);
    607 #  endif /* VBOX_WITH_SHARED_CLIPBOARD_URI_LIST */
    608604VBGLR3DECL(int)     VbglR3ClipboardReadData(HGCMCLIENTID idClient, uint32_t fFormat, void *pv, uint32_t cb, uint32_t *pcb);
    609605VBGLR3DECL(int)     VbglR3ClipboardReportFormats(HGCMCLIENTID idClient, uint32_t fFormats);
    610606VBGLR3DECL(int)     VbglR3ClipboardWriteData(HGCMCLIENTID idClient, uint32_t fFormat, void *pv, uint32_t cb);
     607
    611608#  ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     609VBGLR3DECL(int)     VbglR3ClipboardReadDataHdr(HGCMCLIENTID idClient, PVBOXCLIPBOARDDATAHDR pDataHdr);
     610VBGLR3DECL(int)     VbglR3ClipboardWriteDataHdr(HGCMCLIENTID idClient, const PVBOXCLIPBOARDDATAHDR pDataHdr);
     611VBGLR3DECL(int)     VbglR3ClipboardReadMetaData(HGCMCLIENTID idClient, PVBOXCLIPBOARDDATAHDR pDataHdr,
     612                                                void *pvMeta, uint32_t cbMeta, uint32_t *pcbRead);
     613VBGLR3DECL(int)     VbglR3ClipboardReadMetaDataEx(HGCMCLIENTID idClient, PVBOXCLIPBOARDDATAHDR pDataHdr,
     614                                                  void *pvMeta, uint32_t cbMeta, uint32_t *pcbRead);
     615VBGLR3DECL(int)     VbglR3ClipboardWriteMetaData(HGCMCLIENTID idClient, const void *pvMeta, uint32_t cbMeta, uint32_t *pcbWritten);
     616VBGLR3DECL(int)     VbglR3ClipboardWriteMetaDataEx(HGCMCLIENTID idClient, const void *pvMeta, uint32_t cbMeta, uint32_t *pcbWritten);
    612617VBGLR3DECL(int)     VbglR3ClipboardReadDir(HGCMCLIENTID idClient, char *pszDirname, uint32_t cbDirname, uint32_t *pcbDirnameRecv,
    613618                                           uint32_t *pfMode);
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxClipboard.cpp

    r78974 r79027  
    7373/** Static window class name. */
    7474static char s_szClipWndClassName[] = VBOX_CLIPBOARD_WNDCLASS_NAME;
     75
     76
     77/*********************************************************************************************************************************
     78*   Prototypes                                                                                                                   *
     79*********************************************************************************************************************************/
     80#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     81static DECLCALLBACK(void) vboxClipboardOnURITransferComplete(PSHAREDCLIPBOARDURITRANSFERCALLBACKDATA pData, int rc);
     82#endif
    7583
    7684
     
    523531               {
    524532                   const uint32_t cTransfers = SharedClipboardURICtxGetActiveTransfers(&pCtx->URI);
     533
     534                   LogFunc(("VBOX_SHARED_CLIPBOARD_FMT_URI_LIST cTransfers=%RU32\n", cTransfers));
     535
    525536                   if (cTransfers == 0) /* Only allow one transfer at a time for now. */
    526537                   {
    527                        PSHAREDCLIPBOARDURITRANSFER pTransfer = SharedClipboardURICtxGetTransfer(&pCtx->URI, 0 /* Index */);
    528 
    529                        /* The data data in CF_HDROP format, as the files are locally present and don't need to be
    530                         * presented as a IDataObject or IStream. */
    531                        hClip = GetClipboardData(CF_HDROP);
    532                        if (hClip)
     538                       SHAREDCLIPBOARDPROVIDERCREATIONCTX creationCtx;
     539                       RT_ZERO(creationCtx);
     540                       creationCtx.enmSource = SHAREDCLIPBOARDPROVIDERSOURCE_VBGLR3;
     541                       creationCtx.u.VBGLR3.uClientID = pCtx->u32ClientID;
     542
     543                       PSHAREDCLIPBOARDURITRANSFER pTransfer;
     544                       rc = SharedClipboardURITransferCreate(SHAREDCLIPBOARDURITRANSFERDIR_WRITE, &creationCtx, &pTransfer);
     545                       if (RT_SUCCESS(rc))
    533546                       {
    534                            HDROP hDrop = (HDROP)GlobalLock(hClip);
    535                            if (hDrop)
     547                           SHAREDCLIPBOARDURITRANSFERCALLBACKS TransferCallbacks;
     548                           RT_ZERO(TransferCallbacks);
     549
     550                           TransferCallbacks.pvUser              = &pCtx->URI;
     551                           TransferCallbacks.pfnTransferComplete = vboxClipboardOnURITransferComplete;
     552
     553                           SharedClipboardURITransferSetCallbacks(pTransfer, &TransferCallbacks);
     554
     555                           rc = SharedClipboardURICtxTransferAdd(&pCtx->URI, pTransfer);
     556                           if (RT_SUCCESS(rc))
    536557                           {
    537                                char *pszList;
    538                                size_t cbList;
    539                                rc = VBoxClipboardWinDropFilesToStringList((DROPFILES *)hDrop, &pszList, &cbList);
    540                                if (RT_SUCCESS(rc))
     558                               /* The data data in CF_HDROP format, as the files are locally present and don't need to be
     559                                * presented as a IDataObject or IStream. */
     560                               hClip = GetClipboardData(CF_HDROP);
     561                               if (hClip)
    541562                               {
    542 
    543 
    544                                    size_t cbWrittenIgnored;
    545                                    rc = pTransfer->pProvider->WriteMetaData(pszList, cbList,
    546                                                                             &cbWrittenIgnored, 0 /* fFlags */);
    547                                    if (RT_SUCCESS(rc))
     563                                   HDROP hDrop = (HDROP)GlobalLock(hClip);
     564                                   if (hDrop)
    548565                                   {
    549                                        /* Spawn a worker thread, so that we don't block the window thread for too long. */
    550                                        rc = RTThreadCreate(&pTransfer->Thread.hThread, SharedClipboardURITransferWriteThread,
    551                                                            &pCtx->URI /* pvUser */, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE,
    552                                                            "vbxshclp");
     566                                       char *pszList;
     567                                       size_t cbList;
     568                                       rc = VBoxClipboardWinDropFilesToStringList((DROPFILES *)hDrop, &pszList, &cbList);
    553569                                       if (RT_SUCCESS(rc))
    554                                        {
    555                                            int rc2 = RTThreadUserWait(pTransfer->Thread.hThread, 30 * 1000 /* Timeout in ms */);
    556                                            AssertRC(rc2);
    557 
    558                                            if (!pTransfer->Thread.fStarted) /* Did the thread fail to start? */
    559                                                rc = VERR_GENERAL_FAILURE; /** @todo Find a better rc. */
    560                                        }
     570                                           rc = SharedClipboardURITransferMetaDataAdd(pTransfer, pszList, (uint32_t)cbList);
     571
     572                                       GlobalUnlock(hClip);
     573                                   }
     574                                   else
     575                                   {
     576                                       hClip = NULL;
    561577                                   }
    562578                               }
    563 
    564                                if (RT_FAILURE(rc))
    565                                    LogFunc(("VBOX_SHARED_CLIPBOARD_FMT_URI_LIST failed with rc=%Rrc\n", rc));
    566 
    567                                GlobalUnlock(hClip);
    568                            }
    569                            else
    570                            {
    571                                hClip = NULL;
    572579                           }
    573580                       }
     581
     582                       if (RT_FAILURE(rc))
     583                           LogFunc(("VBOX_SHARED_CLIPBOARD_FMT_URI_LIST failed with rc=%Rrc\n", rc));
    574584                   }
    575                   else
     585                   else
    576586                       LogRel(("Clipboard: Only one transfer at a time supported (current %RU32 transfer(s) active), skipping\n",
    577587                               cTransfers));
     
    673683}
    674684
     685#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     686static DECLCALLBACK(void) vboxClipboardOnURITransferComplete(PSHAREDCLIPBOARDURITRANSFERCALLBACKDATA pData, int rc)
     687{
     688    RT_NOREF(rc);
     689    LogFlowFunc(("rc=%Rrc\n", rc));
     690
     691    PSHAREDCLIPBOARDURICTX pCtx = (PSHAREDCLIPBOARDURICTX)pData->pvUser;
     692    AssertPtr(pCtx);
     693
     694    PSHAREDCLIPBOARDURITRANSFER pTransfer = pData->pTransfer;
     695    AssertPtr(pTransfer);
     696
     697    int rc2 = SharedClipboardURICtxTransferRemove(pCtx, pTransfer);
     698    AssertRC(rc2);
     699}
     700#endif /* VBOX_WITH_SHARED_CLIPBOARD_URI_LIST */
     701
    675702static void vboxClipboardDestroy(PVBOXCLIPBOARDCONTEXT pCtx)
    676703{
     
    744771            {
    745772#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
    746                 SHAREDCLIPBOARDPROVIDERCREATIONCTX creationCtx;
    747                 RT_ZERO(creationCtx);
    748                 creationCtx.enmSource = SHAREDCLIPBOARDPROVIDERSOURCE_VBGLR3;
    749                 creationCtx.u.VBGLR3.uClientID = pCtx->u32ClientID;
    750 
    751                 PSHAREDCLIPBOARDURITRANSFER pTransfer;
    752                 rc = SharedClipboardURITransferCreate(&creationCtx, &pTransfer);
    753                 if (RT_SUCCESS(rc))
    754                     rc = SharedClipboardURICtxInit(&pCtx->URI, pTransfer);
     773                rc = SharedClipboardURICtxInit(&pCtx->URI);
    755774                if (RT_SUCCESS(rc))
    756775#endif
  • trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibClipboard.cpp

    r78946 r79027  
    165165 * @param   pDataHdr            Where to store the read meta data header.
    166166 */
    167 static int vbglR3ClipboardReadDataHdr(HGCMCLIENTID idClient, PVBOXCLIPBOARDDATAHDR pDataHdr)
     167VBGLR3DECL(int) VbglR3ClipboardReadDataHdr(HGCMCLIENTID idClient, PVBOXCLIPBOARDDATAHDR pDataHdr)
    168168{
    169169    AssertPtrReturn(pDataHdr, VERR_INVALID_POINTER);
     
    206206
    207207/**
     208 * Sends a guest clipboard data header to the host.
     209 *
     210 * This is usually called in reply to a VBOX_SHARED_CLIPBOARD_HOST_MSG_WRITE_DATA_HDR message
     211 * from the host.
     212 *
     213 * @returns VBox status code.
     214 * @param   idClient        The client id returned by VbglR3ClipboardConnect().
     215 * @param   pDataHdr        Pointer to data header to send.
     216 */
     217VBGLR3DECL(int) VbglR3ClipboardWriteDataHdr(HGCMCLIENTID idClient, const PVBOXCLIPBOARDDATAHDR pDataHdr)
     218{
     219    VBoxClipboardWriteDataHdrMsg Msg;
     220    VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_FN_WRITE_DATA_HDR, VBOX_SHARED_CLIPBOARD_CPARMS_WRITE_DATA_HDR);
     221
     222    VbglHGCMParmUInt32Set(&Msg.uFlags, pDataHdr->uFlags);                             /** @todo Not used yet. */
     223    VbglHGCMParmUInt32Set(&Msg.uScreenId, pDataHdr->uScreenId);                       /** @todo Not used for guest->host (yet). */
     224    VbglHGCMParmUInt64Set(&Msg.cbTotal, pDataHdr->cbTotal);
     225    VbglHGCMParmUInt32Set(&Msg.cbMeta, pDataHdr->cbMeta);
     226    VbglHGCMParmPtrSet(&Msg.cbMetaFmt, pDataHdr->pvMetaFmt, pDataHdr->cbMetaFmt);
     227    VbglHGCMParmUInt32Set(&Msg.cbMetaFmt, pDataHdr->cbMetaFmt);
     228    VbglHGCMParmUInt64Set(&Msg.cObjects, pDataHdr->cObjects);
     229    VbglHGCMParmUInt32Set(&Msg.enmCompression, pDataHdr->enmCompression);             /** @todo Not used yet. */
     230    VbglHGCMParmUInt32Set(&Msg.enmChecksumType, pDataHdr->enmChecksumType);           /** @todo Not used yet. */
     231    VbglHGCMParmPtrSet(&Msg.cbChecksum, pDataHdr->pvChecksum, pDataHdr->cbChecksum);  /** @todo Not used yet. */
     232    VbglHGCMParmUInt32Set(&Msg.cbChecksum, pDataHdr->cbChecksum);                     /** @todo Not used yet. */
     233
     234    return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
     235}
     236
     237/**
    208238 * Reads a (meta) data chunk from the host.
    209239 *
     
    261291 * @returns IPRT status code.
    262292 * @param   idClient            The client id returned by VbglR3ClipboardConnect().
    263  * @param   pDataHdr            Where to store the data header data.
    264  * @param   pMetaData           Returns the received meta data. Needs to be free'd by the caller.
     293 * @param   pDataHdr            Pointer to data header to use.
     294 * @param   pvMeta              Where to store the received meta data.
     295 * @param   cbMeta              Size (in bytes) of meta data buffer.
     296 * @param   pcbRead             How much bytes were read on success. Optional.
    265297 */
    266298static int vbglR3ClipboardReadMetaDataLoop(HGCMCLIENTID idClient, PVBOXCLIPBOARDDATAHDR pDataHdr,
    267                                            PSHAREDCLIPBOARDMETADATA pMetaData)
    268 {
    269     AssertPtrReturn(pDataHdr,  VERR_INVALID_POINTER);
    270     AssertPtrReturn(pMetaData, VERR_INVALID_POINTER);
    271 
    272     int rc;
    273     uint32_t cbDataRecv;
     299                                           void *pvMeta, uint32_t cbMeta, uint32_t *pcbRead)
     300{
     301    AssertPtrReturn(pDataHdr, VERR_INVALID_POINTER);
     302    AssertPtrReturn(pvMeta,   VERR_INVALID_POINTER);
    274303
    275304    LogFlowFuncEnter();
    276305
    277     rc = vbglR3ClipboardReadDataHdr(idClient, pDataHdr);
    278     if (RT_FAILURE(rc))
    279         return rc;
     306    int rc = VINF_SUCCESS;
     307
     308    uint32_t cbReadTotal = 0;
    280309
    281310    LogFlowFunc(("cbTotal=%RU64, cbMeta=%RU32, cObjects=%RU32\n", pDataHdr->cbTotal, pDataHdr->cbMeta, pDataHdr->cObjects));
    282311    if (pDataHdr->cbMeta)
    283312    {
    284         uint64_t cbDataTmp = 0;
    285         void    *pvDataTmp = RTMemAlloc(pDataHdr->cbMeta);
    286         if (!pvDataTmp)
    287             rc = VERR_NO_MEMORY;
    288 
    289         if (RT_SUCCESS(rc))
     313        uint32_t cbToRead = RT_MIN(cbMeta, pDataHdr->cbMeta);
     314        while (cbToRead)
    290315        {
    291             const uint32_t cbMaxChunkSize = VBOX_SHARED_CLIPBOARD_MAX_CHUNK_SIZE;
    292 
    293             uint8_t *pvDataOff = (uint8_t *)pvDataTmp;
    294             while (cbDataTmp < pDataHdr->cbMeta)
    295             {
    296                 rc = vbglR3ClipboardReadDataChunk(idClient, pDataHdr,
    297                                                   pvDataOff, RT_MIN(pDataHdr->cbMeta - cbDataTmp, cbMaxChunkSize),
    298                                                   &cbDataRecv);
    299                 if (RT_SUCCESS(rc))
    300                 {
    301                     LogFlowFunc(("cbDataRecv=%RU32, cbDataTmp=%RU64\n", cbDataRecv, cbDataTmp));
    302                     Assert(cbDataTmp + cbDataRecv <= pDataHdr->cbMeta);
    303                     cbDataTmp += cbDataRecv;
    304                     pvDataOff += cbDataRecv;
    305                 }
    306                 else
    307                     break;
    308             }
    309 
    310             if (RT_SUCCESS(rc))
    311             {
    312                 Assert(cbDataTmp == pDataHdr->cbMeta);
    313 
    314                 LogFlowFunc(("Received %RU64 bytes of data\n", cbDataTmp));
    315 
    316                 pMetaData->pvMeta = pvDataTmp;
    317                 pMetaData->cbMeta = cbDataTmp;
    318                 pMetaData->cbUsed = cbDataTmp;
    319             }
    320             else
    321                 RTMemFree(pvDataTmp);
     316            uint32_t cbRead;
     317            rc = vbglR3ClipboardReadDataChunk(idClient, pDataHdr,
     318                                              (uint8_t *)pvMeta + cbReadTotal, cbToRead, &cbRead);
     319            if (RT_FAILURE(rc))
     320                break;
     321
     322            Assert(cbToRead >= cbRead);
     323            cbToRead -= cbRead;
     324
     325            cbReadTotal += cbRead;
    322326        }
    323327    }
    324     else
    325         SharedClipboardMetaDataDestroy(pMetaData);
     328
     329    if (RT_SUCCESS(rc))
     330    {
     331        if (pcbRead)
     332            *pcbRead = cbReadTotal;
     333    }
    326334
    327335    LogFlowFuncLeaveRC(rc);
     
    334342 * @returns IPRT status code.
    335343 * @param   idClient            The client id returned by VbglR3ClipboardConnect().
    336  * @param   URIList             Where to store received meta data.
    337  */
    338 static int vbglR3ClipboardReadMetaDataEx(HGCMCLIENTID idClient, SharedClipboardURIList &URIList)
    339 {
    340     /* The rest is optional. */
    341 
    342     VBOXCLIPBOARDDATAHDR dataHdr;
    343     RT_ZERO(dataHdr);
    344 
    345     dataHdr.cbMetaFmt = VBOX_SHARED_CLIPBOARD_MAX_CHUNK_SIZE;
    346     dataHdr.pvMetaFmt = RTMemAlloc(dataHdr.cbMetaFmt);
    347     if (!dataHdr.pvMetaFmt)
    348         return VERR_NO_MEMORY;
    349 
    350     SHAREDCLIPBOARDMETADATA dataMeta;
    351     SharedClipboardMetaDataInit(&dataMeta);
    352 
    353     int rc = vbglR3ClipboardReadMetaDataLoop(idClient, &dataHdr, &dataMeta);
    354     if (RT_SUCCESS(rc))
    355     {
    356         /**
    357          * Check if this is an URI event. If so, let VbglR3 do all the actual
    358          * data transfer + file/directory creation internally without letting
    359          * the caller know.
    360          *
    361          * This keeps the actual (guest OS-)dependent client (like VBoxClient /
    362          * VBoxTray) small by not having too much redundant code.
    363          */
    364         Assert(dataHdr.cbMetaFmt);
    365         AssertPtr(dataHdr.pvMetaFmt);
    366         if (SharedClipboardMIMEHasFileURLs((char *)dataHdr.pvMetaFmt, dataHdr.cbMetaFmt)) /* URI data. */
    367         {
    368             rc = URIList.SetFromURIData(dataMeta.pvMeta, dataMeta.cbMeta, 0 /* fFlags */);
    369 
    370         #if 0
    371             if (RT_SUCCESS(rc))
    372                 rc = vbglR3ClipboardReadURIData(idClient, &dataHdr);
    373 
    374             if (RT_SUCCESS(rc))
    375             {
    376                 if (pvData)
    377                 {
    378                     /* Reuse data buffer to fill in the transformed URI file list. */
    379                     RTMemFree(pvData);
    380                     pvData = NULL;
    381                 }
    382 
    383             #if 0
    384                 RTCString strData = lstURI.GetRootEntries(clipboardCache.GetDirAbs());
    385                 Assert(!strData.isEmpty());
    386 
    387                 cbData = strData.length() + 1;
    388                 LogFlowFunc(("URI list has %zu bytes\n", cbData));
    389 
    390                 pvData = RTMemAlloc(cbData);
    391                 if (pvData)
    392                 {
    393                     memcpy(pvData, strData.c_str(), cbData);
    394                 }
    395                 else
    396                     rc =  VERR_NO_MEMORY;
    397             #endif
    398             }
    399         #endif
    400         }
    401         else /* Raw data. */
    402         {
    403             /** @todo Implement this. */
    404         }
    405 
    406         SharedClipboardMetaDataDestroy(&dataMeta);
    407     }
    408 
    409     if (dataHdr.pvMetaFmt)
    410     {
    411         RTMemFree(dataHdr.pvMetaFmt);
    412         dataHdr.pvMetaFmt = NULL;
    413     }
     344 * @param   pDataHdr            Pointer to data header to use.
     345 * @param   pvMeta              Where to store the received meta data.
     346 * @param   cbMeta              Size (in bytes) of meta data buffer.
     347 * @param   pcbRead             How much bytes were read on success. Optional.
     348 */
     349static int vbglR3ClipboardReadMetaDataInternal(HGCMCLIENTID idClient, PVBOXCLIPBOARDDATAHDR pDataHdr,
     350                                               void *pvMeta, uint32_t cbMeta, uint32_t *pcbRead)
     351{
     352   LogFlowFuncEnter();
     353
     354    int rc = vbglR3ClipboardReadMetaDataLoop(idClient, pDataHdr, pvMeta, cbMeta, pcbRead);
    414355
    415356    LogFlowFuncLeaveRC(rc);
     
    418359
    419360/**
     361 * Reads the actual meta data from the host, extended version.
     362 *
     363 * @returns IPRT status code.
     364 * @param   idClient            The client id returned by VbglR3ClipboardConnect().
     365 * @param   pvMeta              Where to store the received meta data.
     366 * @param   cbMeta              Size (in bytes) of meta data buffer.
     367 * @param   pcbRead             How much bytes were read on success. Optional.
     368 */
     369VBGLR3DECL(int) VbglR3ClipboardReadMetaDataEx(HGCMCLIENTID idClient, PVBOXCLIPBOARDDATAHDR pDataHdr,
     370                                              void *pvMeta, uint32_t cbMeta, uint32_t *pcbRead)
     371{
     372    return vbglR3ClipboardReadMetaDataInternal(idClient, pDataHdr, pvMeta, cbMeta, pcbRead);
     373}
     374
     375/**
    420376 * Reads the actual meta data from the host.
    421377 *
    422378 * @returns IPRT status code.
    423379 * @param   idClient            The client id returned by VbglR3ClipboardConnect().
    424  * @param   URIList             Where to store received meta data.
    425  */
    426 VBGLR3DECL(int) VbglR3ClipboardReadMetaData(HGCMCLIENTID idClient, SharedClipboardURIList &URIList)
    427 {
    428     return vbglR3ClipboardReadMetaDataEx(idClient, URIList);
    429 }
    430 
    431 VBGLR3DECL(int) VbglR3ClipboardWriteMetaData(HGCMCLIENTID idClient, const SharedClipboardURIList &URIList)
    432 {
    433     RT_NOREF(idClient, URIList);
     380 * @param   pvMeta              Where to store the received meta data.
     381 * @param   cbMeta              Size (in bytes) of meta data buffer.
     382 * @param   pcbRead             How much bytes were read on success. Optional.
     383 */
     384VBGLR3DECL(int) VbglR3ClipboardReadMetaData(HGCMCLIENTID idClient, PVBOXCLIPBOARDDATAHDR pDataHdr,
     385                                            void *pvMeta, uint32_t cbMeta, uint32_t *pcbRead)
     386{
     387    return VbglR3ClipboardReadMetaDataEx(idClient, pDataHdr, pvMeta, cbMeta, pcbRead);
     388}
     389
     390/**
     391 * Writes the actual meta data to the host, extended version.
     392 *
     393 * @returns IPRT status code.
     394 * @param   idClient            The client id returned by VbglR3ClipboardConnect().
     395 * @param   pvMeta              Pointer to meta data buffer.
     396 * @param   cbMeta              Size (in bytes) of meta data buffer.
     397 * @param   pcbWritten          How much bytes were written on success. Optional.
     398 */
     399VBGLR3DECL(int) VbglR3ClipboardWriteMetaDataEx(HGCMCLIENTID idClient, const void *pvMeta, uint32_t cbMeta, uint32_t *pcbWritten)
     400{
     401    RT_NOREF(idClient, pvMeta, cbMeta, pcbWritten);
    434402    return 0;
     403}
     404
     405/**
     406 * Writes the actual meta data to the host.
     407 *
     408 * @returns IPRT status code.
     409 * @param   idClient            The client id returned by VbglR3ClipboardConnect().
     410 * @param   pvMeta              Pointer to meta data buffer.
     411 * @param   cbMeta              Size (in bytes) of meta data buffer.
     412 * @param   pcbWritten          How much bytes were written on success. Optional.
     413 */
     414VBGLR3DECL(int) VbglR3ClipboardWriteMetaData(HGCMCLIENTID idClient, const void *pvMeta, uint32_t cbMeta, uint32_t *pcbWritten)
     415{
     416    return VbglR3ClipboardWriteMetaDataEx(idClient, pvMeta, cbMeta, pcbWritten);
    435417}
    436418
     
    688670    VBoxClipboardWriteFormatsMsg Msg;
    689671
    690     VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_FN_REPORT_FORMATS, 1);
     672    VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_FN_REPORT_FORMATS, VBOX_SHARED_CLIPBOARD_CPARMS_FORMATS);
    691673    VbglHGCMParmUInt32Set(&Msg.formats, fFormats);
    692674
     
    709691{
    710692    VBoxClipboardWriteDataMsg Msg;
    711     VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_FN_WRITE_DATA, 2);
     693    VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_FN_WRITE_DATA, VBOX_SHARED_CLIPBOARD_CPARMS_WRITE_DATA);
    712694    VbglHGCMParmUInt32Set(&Msg.format, fFormat);
    713695    VbglHGCMParmPtrSet(&Msg.ptr, pv, cb);
  • trunk/src/VBox/GuestHost/SharedClipboard/ClipboardDataObjectImpl-win.cpp

    r78974 r79027  
    395395            LogFlowFunc(("FormatIndex_FileDescriptor%s\n", fUnicode ? "W" : "A"));
    396396
    397             int rc = m_pTransfer->pProvider->ReadMetaData(); /** @todo Do this asynchronously some time earlier? */
    398             if (   RT_SUCCESS(rc)
    399                 && !m_pTransfer->pProvider->GetURIList().IsEmpty())
     397            int rc = SharedClipboardURITransferMetaDataRead(m_pTransfer, NULL /* cbRead */);
     398            if (RT_SUCCESS(rc))
    400399            {
    401                 HGLOBAL hGlobal;
    402                 rc = createFileGroupDescriptorFromURIList(m_pTransfer->pProvider->GetURIList(), fUnicode, &hGlobal);
    403                 if (RT_SUCCESS(rc))
     400                const SharedClipboardURIList *pURIList = SharedClipboardURITransferGetList(m_pTransfer);
     401                if (    pURIList
     402                    && !pURIList->IsEmpty())
    404403                {
    405                     pMedium->tymed   = TYMED_HGLOBAL;
    406                     pMedium->hGlobal = hGlobal;
    407                     /* Note: hGlobal now is being owned by pMedium / the caller. */
    408 
    409                     hr = S_OK;
     404                    HGLOBAL hGlobal;
     405                    rc = createFileGroupDescriptorFromURIList(*pURIList, fUnicode, &hGlobal);
     406                    if (RT_SUCCESS(rc))
     407                    {
     408                        pMedium->tymed   = TYMED_HGLOBAL;
     409                        pMedium->hGlobal = hGlobal;
     410                        /* Note: hGlobal now is being owned by pMedium / the caller. */
     411
     412                        hr = S_OK;
     413                    }
    410414                }
    411415            }
     
    417421            LogFlowFunc(("FormatIndex_FileContents: m_uObjIdx=%u\n", m_uObjIdx));
    418422
    419             SharedClipboardURIObject *pURIObj = m_pTransfer->pProvider->GetURIList().At(m_uObjIdx);
    420             if (pURIObj)
     423            /* Hand-in the provider so that our IStream implementation can continue working with it. */
     424            hr = VBoxClipboardWinStreamImpl::Create(this /* pParent */, m_pTransfer, m_uObjIdx, &m_pStream);
     425            if (SUCCEEDED(hr))
    421426            {
    422                 /* Hand-in the provider so that our IStream implementation can continue working with it. */
    423                 hr = VBoxClipboardWinStreamImpl::Create(this /* pParent */, m_pTransfer, pURIObj, &m_pStream);
    424                 if (SUCCEEDED(hr))
    425                 {
    426                     /* Hand over the stream to the caller. */
    427                     pMedium->tymed = TYMED_ISTREAM;
    428                     pMedium->pstm  = m_pStream;
    429 
    430                     /* Handle next object. */
    431                     m_uObjIdx++;
    432                 }
     427                /* Hand over the stream to the caller. */
     428                pMedium->tymed = TYMED_ISTREAM;
     429                pMedium->pstm  = m_pStream;
     430
     431                /* Handle next object. */
     432                m_uObjIdx++;
    433433            }
    434             else
    435                 LogFunc(("No object with index %u found, skipping\n", m_uObjIdx));
    436434            break;
    437435        }
     
    540538 */
    541539
    542 STDMETHODIMP VBoxClipboardWinDataObject::EndOperation(HRESULT hResult, IBindCtx* pbcReserved, DWORD dwEffects)
     540STDMETHODIMP VBoxClipboardWinDataObject::EndOperation(HRESULT hResult, IBindCtx *pbcReserved, DWORD dwEffects)
    543541{
    544542     RT_NOREF(hResult, pbcReserved, dwEffects);
     
    546544}
    547545
    548 STDMETHODIMP VBoxClipboardWinDataObject::GetAsyncMode(BOOL* pfIsOpAsync)
     546STDMETHODIMP VBoxClipboardWinDataObject::GetAsyncMode(BOOL *pfIsOpAsync)
    549547{
    550548     RT_NOREF(pfIsOpAsync);
     
    552550}
    553551
    554 STDMETHODIMP VBoxClipboardWinDataObject::InOperation(BOOL* pfInAsyncOp)
     552STDMETHODIMP VBoxClipboardWinDataObject::InOperation(BOOL *pfInAsyncOp)
    555553{
    556554     RT_NOREF(pfInAsyncOp);
     
    564562}
    565563
    566 STDMETHODIMP VBoxClipboardWinDataObject::StartOperation(IBindCtx* pbcReserved)
     564STDMETHODIMP VBoxClipboardWinDataObject::StartOperation(IBindCtx *pbcReserved)
    567565{
    568566     RT_NOREF(pbcReserved);
  • trunk/src/VBox/GuestHost/SharedClipboard/ClipboardMetaData.cpp

    r78897 r79027  
    9999 * @param   cbNewSize           New size (in bytes) to use for resizing.
    100100 */
    101 int SharedClipboardMetaDataResize(PSHAREDCLIPBOARDMETADATA pMeta, size_t cbNewSize)
     101int SharedClipboardMetaDataResize(PSHAREDCLIPBOARDMETADATA pMeta, uint32_t cbNewSize)
    102102{
    103103    AssertPtrReturn(pMeta, VERR_INVALID_POINTER);
     
    136136
    137137    return VERR_NO_MEMORY;
     138}
     139
     140/**
     141 * Returns the actual free bytes of a meta data struct.
     142 *
     143 * @returns Actual free bytes of a meta data struct.
     144 * @param   pMeta               Meta data struct to return free bytes for.
     145 */
     146size_t SharedClipboardMetaDataGetFree(PSHAREDCLIPBOARDMETADATA pMeta)
     147{
     148    AssertPtrReturn(pMeta, 0);
     149    return pMeta->cbMeta - pMeta->cbUsed;
    138150}
    139151
  • trunk/src/VBox/GuestHost/SharedClipboard/ClipboardProvider-VbglR3.cpp

    r78974 r79027  
    4343SharedClipboardProviderVbglR3::~SharedClipboardProviderVbglR3(void)
    4444{
    45     m_URIList.Clear();
    46 }
    47 
    48 int SharedClipboardProviderVbglR3::ReadMetaData(uint32_t fFlags /* = 0 */)
     45}
     46
     47int SharedClipboardProviderVbglR3::ReadDataHdr(PVBOXCLIPBOARDDATAHDR pDataHdr)
     48{
     49    LogFlowFuncEnter();
     50
     51    int rc = VbglR3ClipboardReadDataHdr(m_uClientID, pDataHdr);
     52
     53    LogFlowFuncLeaveRC(rc);
     54    return rc;
     55}
     56
     57int SharedClipboardProviderVbglR3::WriteDataHdr(const PVBOXCLIPBOARDDATAHDR pDataHdr)
     58{
     59    LogFlowFuncEnter();
     60
     61    int rc = VbglR3ClipboardWriteDataHdr(m_uClientID, pDataHdr);
     62
     63    LogFlowFuncLeaveRC(rc);
     64    return rc;
     65}
     66
     67int SharedClipboardProviderVbglR3::ReadMetaData(const PVBOXCLIPBOARDDATAHDR pDataHdr, void *pvMeta, uint32_t cbMeta,
     68                                                uint32_t *pcbRead, uint32_t fFlags /* = 0 */)
    4969{
    5070    RT_NOREF(fFlags);
     
    5272    LogFlowFuncEnter();
    5373
    54     int rc = VbglR3ClipboardReadMetaData(m_uClientID, m_URIList);
    55 
    56 #ifdef DEBUG_andy_disabled
    57     SharedClipboardURIObject *pObj1 = new SharedClipboardURIObject(SharedClipboardURIObject::Type_File, "foobar1.baz");
    58     pObj1->SetSize(_64M);
    59     m_URIList.AppendURIObject(pObj1);
    60 
    61     SharedClipboardURIObject *pObj2 = new SharedClipboardURIObject(SharedClipboardURIObject::Type_File, "foobar2.baz");
    62     pObj2->SetSize(_32M);
    63     m_URIList.AppendURIObject(pObj2);
    64 #endif
    65 
    66     LogFlowFuncLeaveRC(rc);
    67     return rc;
    68 }
    69 
    70 int SharedClipboardProviderVbglR3::WriteMetaData(const void *pvBuf, size_t cbBuf, size_t *pcbWritten, uint32_t fFlags /* = 0 */)
    71 {
    72     RT_NOREF(pcbWritten, fFlags);
    73 
    74     SHAREDCLIPBOARDURILISTFLAGS fURIListFlags = SHAREDCLIPBOARDURILIST_FLAGS_NONE;
    75 
    76     int rc = m_URIList.SetFromURIData(pvBuf, cbBuf, fURIListFlags);
     74    int rc = VINF_SUCCESS;
     75
     76    uint32_t cbReadTotal = 0;
     77    uint32_t cbToRead = RT_MIN(pDataHdr->cbMeta, cbMeta);
     78
     79    while (cbToRead)
     80    {
     81        uint32_t cbRead;
     82        rc = VbglR3ClipboardReadMetaData(m_uClientID, pDataHdr, (uint8_t *)pvMeta + cbReadTotal, cbToRead, &cbRead);
     83        if (RT_FAILURE(rc))
     84            break;
     85
     86        cbReadTotal += cbRead;
     87        Assert(cbToRead >= cbRead);
     88        cbToRead    -= cbRead;
     89    }
     90
    7791    if (RT_SUCCESS(rc))
    78         rc = VbglR3ClipboardWriteMetaData(m_uClientID, m_URIList);
     92    {
     93        if (pcbRead)
     94            *pcbRead = cbReadTotal;
     95    }
     96
     97    LogFlowFuncLeaveRC(rc);
     98    return rc;
     99}
     100
     101int SharedClipboardProviderVbglR3::WriteMetaData(const PVBOXCLIPBOARDDATAHDR pDataHdr, const void *pvMeta, uint32_t cbMeta,
     102                                                 uint32_t *pcbWritten, uint32_t fFlags /* = 0 */)
     103{
     104    RT_NOREF(fFlags);
     105
     106    LogFlowFuncEnter();
     107
     108    int rc = VINF_SUCCESS;
     109
     110    uint32_t cbWrittenTotal = 0;
     111    uint32_t cbToWrite      = RT_MIN(pDataHdr->cbMeta, cbMeta);
     112
     113    while (cbToWrite)
     114    {
     115        uint32_t cbWritten;
     116        rc = VbglR3ClipboardWriteMetaData(m_uClientID, (uint8_t *)pvMeta + cbWrittenTotal, cbToWrite, &cbWritten);
     117        if (RT_FAILURE(rc))
     118            break;
     119
     120        cbWrittenTotal += cbWritten;
     121        Assert(cbToWrite >= cbWritten);
     122        cbToWrite      -= cbWritten;
     123    }
     124
     125    if (RT_SUCCESS(rc))
     126    {
     127        if (pcbWritten)
     128            *pcbWritten = cbWrittenTotal;
     129    }
    79130
    80131    LogFlowFuncLeaveRC(rc);
     
    86137    LogFlowFuncEnter();
    87138
    88     int rc;
    89 
    90     SharedClipboardURIObject *pObj = m_URIList.First();
    91     if (pObj)
    92     {
    93         rc = VbglR3ClipboardReadDir(m_uClientID, pDirData->pszPath, pDirData->cbPath, &pDirData->cbPath, &pDirData->fMode);
    94     }
    95     else
    96         rc = VERR_WRONG_ORDER;
     139    int rc = VbglR3ClipboardReadDir(m_uClientID, pDirData->pszPath, pDirData->cbPath, &pDirData->cbPath, &pDirData->fMode);
    97140
    98141    LogFlowFuncLeaveRC(rc);
     
    104147    LogFlowFuncEnter();
    105148
    106     int rc;
    107 
    108     SharedClipboardURIObject *pObj = m_URIList.First();
    109     if (pObj)
    110     {
    111         rc = VbglR3ClipboardWriteDir(m_uClientID, pDirData->pszPath, pDirData->cbPath, pDirData->fMode);
    112     }
    113     else
    114         rc = VERR_WRONG_ORDER;
     149    int rc = VbglR3ClipboardWriteDir(m_uClientID, pDirData->pszPath, pDirData->cbPath, pDirData->fMode);
    115150
    116151    LogFlowFuncLeaveRC(rc);
     
    122157    LogFlowFuncEnter();
    123158
    124     int rc;
    125 
    126     SharedClipboardURIObject *pObj = m_URIList.First();
    127     if (pObj)
    128     {
    129         rc = VbglR3ClipboardReadFileHdr(m_uClientID, pFileHdr->pszFilePath, pFileHdr->cbFilePath,
     159    int rc = VbglR3ClipboardReadFileHdr(m_uClientID, pFileHdr->pszFilePath, pFileHdr->cbFilePath,
    130160                                        &pFileHdr->fFlags, &pFileHdr->fMode, &pFileHdr->cbSize);
    131         if (RT_SUCCESS(rc))
    132         {
    133             rc = pObj->SetFileData(pFileHdr->pszFilePath, SharedClipboardURIObject::View_Target,
    134                                    RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE, pFileHdr->fMode);
    135             if (RT_SUCCESS(rc))
    136                 rc = pObj->SetSize(pFileHdr->cbSize);
    137         }
    138     }
    139     else
    140         rc = VERR_WRONG_ORDER;
    141 
    142161    LogFlowFuncLeaveRC(rc);
    143162    return rc;
     
    148167    LogFlowFuncEnter();
    149168
    150     int rc;
    151 
    152     SharedClipboardURIObject *pObj = m_URIList.First();
    153     if (pObj)
    154     {
    155         rc = VbglR3ClipboardWriteFileHdr(m_uClientID, pFileHdr->pszFilePath, pFileHdr->cbFilePath,
     169    int rc = VbglR3ClipboardWriteFileHdr(m_uClientID, pFileHdr->pszFilePath, pFileHdr->cbFilePath,
    156170                                         pFileHdr->fFlags, pFileHdr->fMode, pFileHdr->cbSize);
    157     }
    158     else
    159         rc = VERR_WRONG_ORDER;
    160 
    161171    LogFlowFuncLeaveRC(rc);
    162172    return rc;
     
    169179    LogFlowFuncEnter();
    170180
    171     int rc;
    172 
    173     SharedClipboardURIObject *pObj = m_URIList.First();
    174     if (pObj)
    175     {
    176         rc = VbglR3ClipboardReadFileData(m_uClientID, pFileData->pvData, pFileData->cbData, pcbRead);
    177     }
    178     else
    179         rc = VERR_WRONG_ORDER;
     181    int rc = VbglR3ClipboardReadFileData(m_uClientID, pFileData->pvData, pFileData->cbData, pcbRead);
    180182
    181183    LogFlowFuncLeaveRC(rc);
     
    189191    LogFlowFuncEnter();
    190192
    191     int rc;
    192 
    193     SharedClipboardURIObject *pObj = m_URIList.First();
    194     if (pObj)
    195     {
    196         rc = VbglR3ClipboardWriteFileData(m_uClientID, pFileData->pvData, pFileData->cbData, pcbWritten);
    197     }
    198     else
    199         rc = VERR_WRONG_ORDER;
     193    int rc = VbglR3ClipboardWriteFileData(m_uClientID, pFileData->pvData, pFileData->cbData, pcbWritten);
    200194
    201195    LogFlowFuncLeaveRC(rc);
     
    207201    LogFlowFuncEnter();
    208202
    209     m_URIList.Clear();
    210 
    211203    /* Don't clear the refcount here. */
    212204}
  • trunk/src/VBox/GuestHost/SharedClipboard/ClipboardProvider.cpp

    r78974 r79027  
    105105}
    106106
    107 int SharedClipboardProvider::ReadMetaData(uint32_t fFlags /* = 0 */)
    108 {
    109     RT_NOREF(fFlags);
    110     return VERR_NOT_IMPLEMENTED;
    111 }
    112 
    113 int SharedClipboardProvider::WriteMetaData(const void *pvBuf, size_t cbBuf, size_t *pcbWritten, uint32_t fFlags /* = 0 */)
    114 {
    115     RT_NOREF(pvBuf, cbBuf, pcbWritten, fFlags);
     107int SharedClipboardProvider::ReadDataHdr(PVBOXCLIPBOARDDATAHDR pDataHdr)
     108{
     109    RT_NOREF(pDataHdr);
     110    return VERR_NOT_IMPLEMENTED;
     111}
     112
     113int SharedClipboardProvider::WriteDataHdr(const PVBOXCLIPBOARDDATAHDR pDataHdr)
     114{
     115    RT_NOREF(pDataHdr);
     116    return VERR_NOT_IMPLEMENTED;
     117}
     118
     119int SharedClipboardProvider::ReadMetaData(const PVBOXCLIPBOARDDATAHDR pDataHdr, void *pvMeta, uint32_t cbMeta, uint32_t *pcbRead,
     120                                          uint32_t fFlags /* = 0 */)
     121{
     122    RT_NOREF(pDataHdr, pvMeta, cbMeta, pcbRead, fFlags);
     123    return VERR_NOT_IMPLEMENTED;
     124}
     125
     126int SharedClipboardProvider::WriteMetaData(const PVBOXCLIPBOARDDATAHDR pDataHdr, const void *pvMeta, uint32_t cbMeta,
     127                                           uint32_t *pcbWritten, uint32_t fFlags /* = 0 */)
     128{
     129    RT_NOREF(pDataHdr, pvMeta, cbMeta, pcbWritten, fFlags);
    116130    return VERR_NOT_IMPLEMENTED;
    117131}
     
    133147}
    134148
    135 int SharedClipboardProvider::ReadDirectoryObj(SharedClipboardURIObject &Obj)
    136 {
    137     RT_NOREF(Obj);
    138 
    139     LogFlowFuncEnter();
    140 
    141     int rc = VERR_NOT_IMPLEMENTED;
    142 
    143     LogFlowFuncLeaveRC(rc);
    144     return rc;
    145 }
    146 
    147149int SharedClipboardProvider::WriteDirectory(const PVBOXCLIPBOARDDIRDATA pDirData)
    148150{
     
    157159}
    158160
    159 int SharedClipboardProvider::WriteDirectoryObj(const SharedClipboardURIObject &Obj)
    160 {
    161     RT_NOREF(Obj);
    162 
    163     LogFlowFuncEnter();
    164 
    165     int rc = VERR_NOT_IMPLEMENTED;
    166 
    167     LogFlowFuncLeaveRC(rc);
    168     return rc;
    169 }
    170 
    171161int SharedClipboardProvider::ReadFileHdr(PVBOXCLIPBOARDFILEHDR pFileHdr)
    172162{
     
    181171}
    182172
    183 int SharedClipboardProvider::ReadFileHdrObj(SharedClipboardURIObject &Obj)
    184 {
    185     RT_NOREF(Obj);
    186 
    187     LogFlowFuncEnter();
    188 
    189     int rc = VERR_NOT_IMPLEMENTED;
    190 
    191     LogFlowFuncLeaveRC(rc);
    192     return rc;
    193 }
    194 
    195173int SharedClipboardProvider::WriteFileHdr(const PVBOXCLIPBOARDFILEHDR pFileHdr)
    196174{
     
    205183}
    206184
    207 int SharedClipboardProvider::WriteFileHdrObj(const SharedClipboardURIObject &Obj)
    208 {
    209     RT_NOREF(Obj);
    210 
    211     LogFlowFuncEnter();
    212 
    213     int rc = VERR_NOT_IMPLEMENTED;
    214 
    215     LogFlowFuncLeaveRC(rc);
    216     return rc;
    217 }
    218 
    219 int SharedClipboardProvider::ReadFileDataObj(SharedClipboardURIObject &Obj, uint32_t *pcbRead)
    220 {
    221     RT_NOREF(Obj, pcbRead);
    222 
    223     LogFlowFuncEnter();
    224 
    225     int rc = VERR_NOT_IMPLEMENTED;
    226 
    227     LogFlowFuncLeaveRC(rc);
    228     return rc;
    229 }
    230 
    231185int SharedClipboardProvider::ReadFileData(PVBOXCLIPBOARDFILEDATA pFileData, uint32_t *pcbRead)
    232186{
     
    241195}
    242196
    243 int SharedClipboardProvider::WriteFileDataObj(const SharedClipboardURIObject &Obj, uint32_t *pcbWritten)
    244 {
    245     RT_NOREF(Obj, pcbWritten);
    246 
    247     LogFlowFuncEnter();
    248 
    249     int rc = VERR_NOT_IMPLEMENTED;
    250 
    251     LogFlowFuncLeaveRC(rc);
    252     return rc;
    253 }
    254 
    255197int SharedClipboardProvider::WriteFileData(const PVBOXCLIPBOARDFILEDATA pFileData, uint32_t *pcbWritten)
    256198{
  • trunk/src/VBox/GuestHost/SharedClipboard/ClipboardStreamImpl-win.cpp

    r78974 r79027  
    11/* $Id$ */
    22/** @file
    3  * ClipboardStreamImpl-win.cpp - Shared Clipboard IStream object implementation (for CF_HDROP).
     3 * ClipboardStreamImpl-win.cpp - Shared Clipboard IStream object implementation (guest and host side).
    44 */
    55
     
    4747
    4848VBoxClipboardWinStreamImpl::VBoxClipboardWinStreamImpl(VBoxClipboardWinDataObject *pParent,
    49                                                        PSHAREDCLIPBOARDURITRANSFER pTransfer, SharedClipboardURIObject *pURIObj)
     49                                                       PSHAREDCLIPBOARDURITRANSFER pTransfer, uint64_t uObjIdx)
    5050    : m_pParent(pParent)
    5151    , m_lRefCount(1)
    52     , m_pTransfer(pTransfer)
    53     , m_pURIObj(pURIObj)
    54 {
    55     AssertPtr(m_pTransfer);
    56     AssertPtr(m_pTransfer->pProvider);
    57     AssertPtr(m_pURIObj);
    58 
    59     LogFunc(("szSrcPath=%s, cbSize=%RU64\n", m_pURIObj->GetSourcePathAbs().c_str(), m_pURIObj->GetSize()));
    60 
    61     m_pTransfer->pProvider->AddRef();
     52    , m_pURITransfer(pTransfer)
     53    , m_uObjIdx(uObjIdx)
     54{
     55    AssertPtr(m_pURITransfer);
     56    AssertPtr(m_pURITransfer->pProvider);
     57
     58    LogFunc(("m_uObjIdx=%RU64\n", uObjIdx));
     59
     60    m_pURITransfer->pProvider->AddRef();
    6261}
    6362
     
    6665    LogFlowThisFuncEnter();
    6766
    68     if (   m_pTransfer
    69         && m_pTransfer->pProvider)
    70         m_pTransfer->pProvider->Release();
     67    if (   m_pURITransfer
     68        && m_pURITransfer->pProvider)
     69        m_pURITransfer->pProvider->Release();
    7170}
    7271
     
    7574 */
    7675
    77 STDMETHODIMP VBoxClipboardWinStreamImpl::QueryInterface(REFIID iid, void ** ppvObject)
     76STDMETHODIMP VBoxClipboardWinStreamImpl::QueryInterface(REFIID iid, void **ppvObject)
    7877{
    7978    AssertPtrReturn(ppvObject, E_INVALIDARG);
    8079
    81     if (   iid == IID_IStream
    82         || iid == IID_IUnknown)
    83     {
    84         AddRef();
    85         *ppvObject = this;
    86         return S_OK;
    87     }
    88 
    89     *ppvObject = 0;
    90     return E_NOINTERFACE;
     80    if (iid == IID_IUnknown)
     81    {
     82        LogFlowFunc(("IID_IUnknown\n"));
     83        *ppvObject = (IUnknown *)(ISequentialStream *)this;
     84    }
     85    else if (iid == IID_ISequentialStream)
     86    {
     87        LogFlowFunc(("IID_ISequentialStream\n"));
     88        *ppvObject = (ISequentialStream *)this;
     89    }
     90    else if (iid == IID_IStream)
     91    {
     92        LogFlowFunc(("IID_IStream\n"));
     93        *ppvObject = (IStream *)this;
     94    }
     95    else
     96    {
     97        *ppvObject = NULL;
     98        return E_NOINTERFACE;
     99    }
     100
     101    AddRef();
     102    return S_OK;
    91103}
    92104
     
    104116    if (lCount == 0)
    105117    {
     118        if (m_pParent)
     119            m_pParent->OnTransferComplete();
     120
    106121        delete this;
    107122        return 0;
     
    145160
    146161    LogFlowThisFuncEnter();
    147     return E_NOTIMPL;
     162    return STG_E_INVALIDFUNCTION;
    148163}
    149164
    150165STDMETHODIMP VBoxClipboardWinStreamImpl::Read(void *pvBuffer, ULONG nBytesToRead, ULONG *nBytesRead)
    151166{
    152    LogFlowThisFuncEnter();
    153 
    154     AssertPtr(m_pURIObj);
    155     if (m_pURIObj->IsComplete())
     167    LogFlowThisFuncEnter();
     168
     169    const SharedClipboardURIObject *pObj = SharedClipboardURITransferGetObject(m_pURITransfer, m_uObjIdx);
     170
     171    if (pObj->IsComplete())
    156172    {
    157173        /* There can be 0-byte files. */
    158         AssertMsg(m_pURIObj->GetSize() == 0, ("Object is complete -- can't read from it anymore\n"));
     174        AssertMsg(pObj->GetSize() == 0, ("Object is complete -- can't read from it anymore\n"));
    159175        if (nBytesRead)
    160176            *nBytesRead = 0; /** @todo If the file size is 0, already return at least 1 byte, else the whole operation will fail. */
     
    162178    }
    163179
    164     const uint64_t cbSize      = m_pURIObj->GetSize();
    165     const uint64_t cbProcessed = m_pURIObj->GetProcessed();
     180    const uint64_t cbSize      = pObj->GetSize();
     181    const uint64_t cbProcessed = pObj->GetProcessed();
    166182
    167183    const uint32_t cbToRead = RT_MIN(cbSize - cbProcessed, nBytesToRead);
     
    178194        FileData.cbData = cbToRead;
    179195
    180         rc = m_pTransfer->pProvider->ReadFileData(&FileData, &cbRead);
     196        rc = m_pURITransfer->pProvider->ReadFileData(&FileData, &cbRead);
    181197        if (RT_SUCCESS(rc))
    182198        {
    183             if (m_pURIObj->IsComplete())
     199            if (pObj->IsComplete())
    184200                m_pParent->OnTransferComplete();
    185201        }
     
    197213{
    198214    LogFlowThisFuncEnter();
    199     return E_NOTIMPL;
     215    return STG_E_INVALIDFUNCTION;
    200216}
    201217
     
    205221
    206222    LogFlowThisFuncEnter();
    207     return E_NOTIMPL;
     223    return STG_E_INVALIDFUNCTION;
    208224}
    209225
     
    213229
    214230    LogFlowThisFuncEnter();
    215     return E_NOTIMPL;
    216 }
    217 
    218 STDMETHODIMP VBoxClipboardWinStreamImpl::Stat(STATSTG *statstg, DWORD dwFlags)
    219 {
    220     RT_NOREF(statstg, dwFlags);
    221 
    222     LogFlowThisFuncEnter();
    223     return E_NOTIMPL;
     231    return STG_E_INVALIDFUNCTION;
     232}
     233
     234STDMETHODIMP VBoxClipboardWinStreamImpl::Stat(STATSTG *pStatStg, DWORD dwFlags)
     235{
     236    HRESULT hr = S_OK;
     237
     238    if (pStatStg)
     239    {
     240        const SharedClipboardURIObject *pObj = SharedClipboardURITransferGetObject(m_pURITransfer, m_uObjIdx);
     241
     242        RT_BZERO(pStatStg, sizeof(STATSTG));
     243
     244        switch (dwFlags)
     245        {
     246            case STATFLAG_NONAME:
     247                pStatStg->pwcsName = NULL;
     248                break;
     249
     250            case STATFLAG_DEFAULT:
     251            {
     252                int rc2 = RTStrToUtf16(pObj->GetDestPathAbs().c_str(), &pStatStg->pwcsName);
     253                if (RT_FAILURE(rc2))
     254                    hr = E_FAIL;
     255                break;
     256            }
     257
     258            default:
     259                hr = STG_E_INVALIDFLAG;
     260                break;
     261        }
     262
     263        if (SUCCEEDED(hr))
     264        {
     265            pStatStg->type              = STGTY_STREAM;
     266            pStatStg->grfMode           = STGM_READ;
     267            pStatStg->grfLocksSupported = 0;
     268            pStatStg->cbSize.QuadPart   = pObj->GetSize();
     269        }
     270    }
     271    else
     272       hr = STG_E_INVALIDPOINTER;
     273
     274    LogFlowThisFunc(("hr=%Rhrc\n", hr));
     275    return hr;
    224276}
    225277
     
    229281
    230282    LogFlowThisFuncEnter();
    231     return E_NOTIMPL;
     283    return STG_E_INVALIDFUNCTION;
    232284}
    233285
     
    250302 * @param   pParent             Pointer to the parent data object.
    251303 * @param   pTransfer           Pointer to URI transfer object to use.
    252  * @param   pURIObj             Pointer to URI object to handle.
     304 * @param   uObjIdx             Index of object to handle within the given URI transfer object.
    253305 * @param   ppStream            Where to return the created stream object on success.
    254306 */
    255307/* static */
    256308HRESULT VBoxClipboardWinStreamImpl::Create(VBoxClipboardWinDataObject *pParent,
    257                                            PSHAREDCLIPBOARDURITRANSFER pTransfer, SharedClipboardURIObject *pURIObj,
    258                                            IStream **ppStream)
     309                                           PSHAREDCLIPBOARDURITRANSFER pTransfer, uint64_t uObjIdx, IStream **ppStream)
    259310{
    260311    AssertPtrReturn(pTransfer, E_POINTER);
    261312
    262     VBoxClipboardWinStreamImpl *pStream = new VBoxClipboardWinStreamImpl(pParent, pTransfer, pURIObj);
     313    VBoxClipboardWinStreamImpl *pStream = new VBoxClipboardWinStreamImpl(pParent, pTransfer, uObjIdx);
    263314    if (pStream)
    264315    {
  • trunk/src/VBox/GuestHost/SharedClipboard/clipboard-common.cpp

    r78974 r79027  
    2626#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
    2727# include <VBox/GuestHost/SharedClipboard-uri.h>
     28#endif
     29
     30
     31#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     32static int sharedClipboardURITransferReadThread(RTTHREAD hThread, void *pvUser);
     33static int sharedClipboardURITransferWriteThread(RTTHREAD hThread, void *pvUser);
     34static PSHAREDCLIPBOARDURITRANSFER sharedClipboardURICtxGetTransferInternal(PSHAREDCLIPBOARDURICTX pURI, uint32_t uIdx);
    2835#endif
    2936
     
    346353 *
    347354 * @returns VBox status code.
     355 * @param   enmDir              Transfer direction.
    348356 * @param   pCtx                Shared Clipboard provider creation context to use.
    349357 * @param   ppTransfer          Where to return the created URI transfer struct.
    350  *                              Must be free'd by SharedClipboardURITransferDestroy().
    351  */
    352 int SharedClipboardURITransferCreate(PSHAREDCLIPBOARDPROVIDERCREATIONCTX pCtx,
     358 *                              Must be destroyed by SharedClipboardURITransferDestroy().
     359 */
     360int SharedClipboardURITransferCreate(SHAREDCLIPBOARDURITRANSFERDIR enmDir, PSHAREDCLIPBOARDPROVIDERCREATIONCTX pCtx,
    353361                                     PSHAREDCLIPBOARDURITRANSFER *ppTransfer)
    354362{
     
    362370    LogFlowFuncEnter();
    363371
     372    pTransfer->enmDir = enmDir;
     373
     374    SharedClipboardMetaDataInit(&pTransfer->Meta);
     375
    364376    pTransfer->pProvider = SharedClipboardProvider::Create(pCtx);
    365377    if (!pTransfer->pProvider)
    366378        return VERR_NO_MEMORY;
    367379
     380    pTransfer->Thread.hThread    = NIL_RTTHREAD;
    368381    pTransfer->Thread.fCancelled = false;
    369382    pTransfer->Thread.fStarted   = false;
     
    380393 * Destroys an URI clipboard transfer context struct.
    381394 *
     395 * @returns VBox status code.
    382396 * @param   pURI                URI clipboard transfer struct to destroy.
    383397 */
    384 void SharedClipboardURITransferDestroy(PSHAREDCLIPBOARDURITRANSFER pTransfer)
     398int SharedClipboardURITransferDestroy(PSHAREDCLIPBOARDURITRANSFER pTransfer)
    385399{
    386400    if (!pTransfer)
    387         return;
    388 
    389     LogFlowFuncEnter();
     401        return VINF_SUCCESS;
     402
     403    LogFlowFuncEnter();
     404
     405    int rc = SharedClipboardURITransferThreadDestroy(pTransfer, 30 * 1000 /* Timeout in ms */);
     406    if (RT_FAILURE(rc))
     407        return rc;
     408
     409    SharedClipboardMetaDataDestroy(&pTransfer->Meta);
    390410
    391411    if (pTransfer->pProvider)
     
    397417    RTMemFree(pTransfer);
    398418    pTransfer = NULL;
    399 }
    400 
    401 /**
    402  * Resets an URI clipboard context struct.
     419
     420    LogFlowFuncLeave();
     421
     422    return VINF_SUCCESS;
     423}
     424
     425/**
     426 * Resets an clipboard URI transfer.
    403427 *
    404428 * @param   pTransfer           URI clipboard transfer struct to reset.
     
    409433
    410434    LogFlowFuncEnter();
     435
     436    /** @todo Anything else to do here? */
    411437
    412438    if (pTransfer->pProvider)
    413439        pTransfer->pProvider->Reset();
     440
     441    pTransfer->URIList.Clear();
     442}
     443
     444/**
     445 * Returns the current URI object for a clipboard URI transfer.
     446 *
     447 * @returns VBox status code.
     448 * @param   pTransfer           URI clipboard transfer struct to return current URI object for.
     449 */
     450const SharedClipboardURIObject *SharedClipboardURITransferGetCurrentObject(PSHAREDCLIPBOARDURITRANSFER pTransfer)
     451{
     452    AssertPtrReturn(pTransfer, NULL);
     453
     454    return pTransfer->URIList.First();
     455}
     456
     457/**
     458 * Returns the provider for a clipboard URI transfer.
     459 *
     460 * @returns VBox status code.
     461 * @param   pTransfer           URI clipboard transfer struct to return provider for.
     462 */
     463SharedClipboardProvider *SharedClipboardURITransferGetProvider(PSHAREDCLIPBOARDURITRANSFER pTransfer)
     464{
     465    AssertPtrReturn(pTransfer, NULL);
     466
     467    return pTransfer->pProvider;
     468}
     469
     470const SharedClipboardURIList *SharedClipboardURITransferGetList(PSHAREDCLIPBOARDURITRANSFER pTransfer)
     471{
     472    return &pTransfer->URIList;
     473}
     474
     475const SharedClipboardURIObject *SharedClipboardURITransferGetObject(PSHAREDCLIPBOARDURITRANSFER pTransfer, uint64_t uIdx)
     476{
     477    return pTransfer->URIList.At(uIdx);
     478}
     479
     480/**
     481 * Sets or unsets the callback table to be used for a clipboard URI transfer.
     482 *
     483 * @returns VBox status code.
     484 * @param   pTransfer           URI clipboard transfer struct to set callbacks for.
     485 * @param   pCallbacks          Pointer to callback table to set. Specify NULL to unset existing callbacks.
     486 */
     487void SharedClipboardURITransferSetCallbacks(PSHAREDCLIPBOARDURITRANSFER pTransfer, PSHAREDCLIPBOARDURITRANSFERCALLBACKS pCallbacks)
     488{
     489    AssertPtrReturnVoid(pTransfer);
     490    /* pCallbacks might be NULL to unset callbacks. */
     491
     492    LogFlowFunc(("pCallbacks=%p\n", pCallbacks));
     493
     494    if (pCallbacks)
     495    {
     496        pTransfer->Callbacks = *pCallbacks;
     497    }
     498    else
     499        RT_ZERO(pTransfer->Callbacks);
     500}
     501
     502/**
     503 * Creates a thread for a clipboard URI transfer.
     504 *
     505 * @returns VBox status code.
     506 * @param   pTransfer           URI clipboard transfer struct to create thread for.
     507 */
     508int SharedClipboardURITransferThreadCreate(PSHAREDCLIPBOARDURITRANSFER pTransfer)
     509{
     510    AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
     511
     512    PFNRTTHREAD pfnRTThread = NULL;
     513
     514    if (pTransfer->enmDir == SHAREDCLIPBOARDURITRANSFERDIR_READ)
     515        pfnRTThread = sharedClipboardURITransferReadThread;
     516    else if (pTransfer->enmDir == SHAREDCLIPBOARDURITRANSFERDIR_WRITE)
     517        pfnRTThread = sharedClipboardURITransferWriteThread;
     518
     519    AssertPtrReturn(pfnRTThread, VERR_NOT_SUPPORTED);
     520
     521    /* Spawn a worker thread, so that we don't block the window thread for too long. */
     522    int rc = RTThreadCreate(&pTransfer->Thread.hThread, pfnRTThread,
     523                            pTransfer /* pvUser */, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE,
     524                            "vbxshclp");
     525    if (RT_SUCCESS(rc))
     526    {
     527        int rc2 = RTThreadUserWait(pTransfer->Thread.hThread, 30 * 1000 /* Timeout in ms */);
     528        AssertRC(rc2);
     529
     530        if (!pTransfer->Thread.fStarted) /* Did the thread fail to start? */
     531            rc = VERR_GENERAL_FAILURE; /** @todo Find a better rc. */
     532    }
     533
     534    LogFlowFuncLeaveRC(rc);
     535    return rc;
     536}
     537
     538/**
     539 * Destroys a thread of a clipboard URI transfer.
     540 *
     541 * @returns VBox status code.
     542 * @param   pTransfer           URI clipboard transfer struct to destroy thread for.
     543 * @param   uTimeoutMs          Timeout (in ms) to wait for thread creation.
     544 */
     545int SharedClipboardURITransferThreadDestroy(PSHAREDCLIPBOARDURITRANSFER pTransfer, RTMSINTERVAL uTimeoutMs)
     546{
     547    AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
     548
     549    if (pTransfer->Thread.hThread == NIL_RTTHREAD)
     550        return VINF_SUCCESS;
     551
     552    int rcThread = VERR_WRONG_ORDER;
     553    int rc = RTThreadWait(pTransfer->Thread.hThread, uTimeoutMs, &rcThread);
     554
     555    LogFlowFunc(("Waiting for thread resulted in %Rrc (thread exited with %Rrc)\n", rc, rcThread));
     556
     557    return rc;
     558}
     559
     560/**
     561 * Reads all URI objects using the connected provider.
     562 *
     563 * @returns VBox status code.
     564 * @param   pTransfer           Transfer to read objects for.
     565 */
     566int SharedClipboardURITransferRead(PSHAREDCLIPBOARDURITRANSFER pTransfer)
     567{
     568    AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
     569
     570    LogFlowFuncEnter();
     571
     572    int rc = SharedClipboardURITransferMetaDataRead(pTransfer, NULL /* pcbRead */);
     573    if (RT_SUCCESS(rc))
     574        rc = SharedClipboardURITransferWriteObjects(pTransfer);
     575
     576    LogFlowFuncLeaveRC(rc);
     577    return rc;
     578}
     579
     580/**
     581 * Thread for transferring (reading) URI objects from source to the target.
     582 * For target to source transfers we utilize our own IDataObject / IStream implementations.
     583 *
     584 * @returns VBox status code.
     585 * @param   hThread             Thread handle.
     586 * @param   pvUser              User arguments; is PSHAREDCLIPBOARDURITRANSFER.
     587 */
     588static int sharedClipboardURITransferReadThread(RTTHREAD hThread, void *pvUser)
     589{
     590    AssertPtrReturn(pvUser, VERR_INVALID_POINTER);
     591
     592    LogFlowFuncEnter();
     593
     594    /* At the moment we only support one transfer at a time. */
     595    PSHAREDCLIPBOARDURITRANSFER pTransfer = (PSHAREDCLIPBOARDURITRANSFER)pvUser;
     596    AssertPtr(pTransfer->pProvider);
     597
     598    int rc = VINF_SUCCESS;
     599
     600    if (RT_SUCCESS(rc))
     601        pTransfer->Thread.fStarted = true;
     602
     603    int rc2 = RTThreadUserSignal(hThread);
     604    const bool fSignalled = RT_SUCCESS(rc2);
     605
     606    if (RT_SUCCESS(rc))
     607        rc = SharedClipboardURITransferRead(pTransfer);
     608
     609    if (!fSignalled)
     610    {
     611        rc2 = RTThreadUserSignal(hThread);
     612        AssertRC(rc2);
     613    }
     614
     615    LogFlowFuncLeaveRC(rc);
     616    return rc;
     617}
     618
     619int sharedClipboardURITransferMetaDataAddInternal(PSHAREDCLIPBOARDURITRANSFER pTransfer, const void *pvMeta, uint32_t cbMeta)
     620{
     621    LogFlowFuncEnter();
     622
     623    int rc = SharedClipboardMetaDataAdd(&pTransfer->Meta, pvMeta, cbMeta);
     624    if (RT_SUCCESS(rc))
     625    {
     626        /** @todo Accounting? */
     627    }
     628
     629    LogFlowFuncLeaveRC(rc);
     630    return rc;
     631}
     632
     633
     634/**
     635 * Adds meta data for a clipboard URI transfer.
     636 *
     637 * @returns VBox status code.
     638 * @param   pTransfer           URI clipboard transfer struct to set meta data for.
     639 * @param   pvMeta              Pointer to meta data buffer.
     640 * @param   cbMeta              Size (in bytes) of meta data buffer.
     641 */
     642int SharedClipboardURITransferMetaDataAdd(PSHAREDCLIPBOARDURITRANSFER pTransfer, const void *pvMeta, uint32_t cbMeta)
     643{
     644    AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
     645
     646    int rc = sharedClipboardURITransferMetaDataAddInternal(pTransfer, pvMeta, cbMeta);
     647
     648    LogFlowFuncLeaveRC(rc);
     649    return rc;
     650}
     651
     652int SharedClipboardURITransferMetaDataRead(PSHAREDCLIPBOARDURITRANSFER pTransfer, uint32_t *pcbRead)
     653{
     654    AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
     655
     656    /* Destroy any former meta data. */
     657    SharedClipboardMetaDataDestroy(&pTransfer->Meta);
     658
     659    uint32_t cbReadTotal = 0;
     660
     661    int rc = pTransfer->pProvider->ReadDataHdr(&pTransfer->Header);
     662    if (RT_SUCCESS(rc))
     663    {
     664        uint32_t cbMeta = _4K; /** @todo Improve. */
     665        void    *pvMeta = RTMemAlloc(cbMeta);
     666
     667        if (pvMeta)
     668        {
     669            uint32_t cbMetaToRead = pTransfer->Header.cbMeta;
     670            while (cbMetaToRead)
     671            {
     672                uint32_t cbMetaRead;
     673                rc = pTransfer->pProvider->ReadMetaData(&pTransfer->Header, pvMeta, cbMeta, &cbMetaRead);
     674                if (RT_SUCCESS(rc))
     675                    rc = sharedClipboardURITransferMetaDataAddInternal(pTransfer, pvMeta, cbMeta);
     676
     677                if (RT_FAILURE(rc))
     678                    break;
     679
     680                Assert(cbMetaToRead >= cbMetaRead);
     681                cbMetaToRead -= cbMetaRead;
     682
     683                cbReadTotal += cbReadTotal;
     684            }
     685
     686            RTMemFree(pvMeta);
     687
     688            if (RT_SUCCESS(rc))
     689            {
     690                if (pcbRead)
     691                    *pcbRead = cbReadTotal;
     692            }
     693        }
     694        else
     695            rc = VERR_NO_MEMORY;
     696    }
     697
     698    LogFlowFuncLeaveRC(rc);
     699    return rc;
     700}
     701
     702/**
     703 * Writes the actual meta data.
     704 *
     705 * @returns IPRT status code.
     706 * @param   pTransfer           Transfer to write meta data for.
     707 * @param   pcbWritten          How much bytes were written on success. Optional.
     708 */
     709int SharedClipboardURITransferMetaDataWrite(PSHAREDCLIPBOARDURITRANSFER pTransfer, uint32_t *pcbWritten)
     710{
     711    AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
     712
     713    AssertPtr(pTransfer->pProvider);
     714
     715    uint32_t cbWrittenTotal = 0;
     716
     717    int rc = pTransfer->pProvider->WriteDataHdr(&pTransfer->Header);
     718    if (RT_SUCCESS(rc))
     719    {
     720        /* Sanity. */
     721        Assert(pTransfer->Header.cbMeta == pTransfer->Meta.cbUsed);
     722
     723        uint32_t cbMetaToWrite = pTransfer->Header.cbMeta;
     724        while (cbMetaToWrite)
     725        {
     726            uint32_t cbMetaWritten;
     727            rc = pTransfer->pProvider->WriteMetaData(&pTransfer->Header, (uint8_t *)pTransfer->Meta.pvMeta + cbWrittenTotal,
     728                                                     cbMetaToWrite, &cbMetaWritten, 0 /* fFlags */);
     729            if (RT_SUCCESS(rc))
     730            {
     731                cbWrittenTotal += cbMetaWritten;
     732                Assert(cbWrittenTotal <= pTransfer->Header.cbMeta);
     733            }
     734        }
     735
     736        if (RT_SUCCESS(rc))
     737        {
     738            if (pcbWritten)
     739                *pcbWritten = cbWrittenTotal;
     740        }
     741    }
     742
     743    LogFlowFuncLeaveRC(rc);
     744    return rc;
    414745}
    415746
     
    420751 * @param   pTransfer           Transfer to write objects for.
    421752 */
    422 int SharedClipboardURITransferWrite(PSHAREDCLIPBOARDURITRANSFER pTransfer)
     753int SharedClipboardURITransferWriteObjects(PSHAREDCLIPBOARDURITRANSFER pTransfer)
    423754{
    424755    AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
     
    428759    int rc = VINF_SUCCESS;
    429760
    430     SharedClipboardURIList &lstURI = pTransfer->pProvider->GetURIList();
    431 
    432     while (!lstURI.IsEmpty())
    433     {
    434         SharedClipboardURIObject *pObj = lstURI.First();
     761    AssertPtr(pTransfer->pProvider);
     762
     763    while (!pTransfer->URIList.IsEmpty())
     764    {
     765        SharedClipboardURIObject *pObj = pTransfer->URIList.First();
    435766        AssertPtrBreakStmt(pObj, rc = VERR_INVALID_POINTER);
    436767
     
    439770            case SharedClipboardURIObject::Type_Directory:
    440771            {
    441                 rc = pTransfer->pProvider->WriteDirectoryObj(*pObj);
     772                VBOXCLIPBOARDDIRDATA dirData;
     773                RT_ZERO(dirData);
     774
     775                dirData.pszPath = RTStrDup(pObj->GetDestPathAbs().c_str());
     776                dirData.cbPath  = (uint32_t)strlen(dirData.pszPath);
     777
     778                rc = pTransfer->pProvider->WriteDirectory(&dirData);
    442779                break;
    443780            }
     
    445782            case SharedClipboardURIObject::Type_File:
    446783            {
    447                 rc = pTransfer->pProvider->WriteFileHdrObj(*pObj);
     784                VBOXCLIPBOARDFILEHDR fileHdr;
     785                RT_ZERO(fileHdr);
     786
     787                fileHdr.pszFilePath = RTStrDup(pObj->GetDestPathAbs().c_str());
     788                fileHdr.cbFilePath  = (uint32_t)strlen(fileHdr.pszFilePath);
     789                fileHdr.cbSize      = pObj->GetSize();
     790                fileHdr.fFlags      = 0;
     791                fileHdr.fMode       = pObj->GetMode();
     792
     793                rc = pTransfer->pProvider->WriteFileHdr(&fileHdr);
    448794                if (RT_FAILURE(rc))
    449795                    break;
    450796
     797                uint32_t cbData = _4K; /** @todo Improve. */
     798                void    *pvData = RTMemAlloc(cbData);
     799
    451800                while (!pObj->IsComplete())
    452801                {
    453                     uint32_t cbWritten;
    454                     rc = pTransfer->pProvider->WriteFileDataObj(*pObj, &cbWritten);
     802                    VBOXCLIPBOARDFILEDATA fileData;
     803                    RT_ZERO(fileData);
     804
     805                    uint32_t cbRead;
     806                    rc = pObj->Read(pvData, cbData, &cbRead);
     807                    if (RT_SUCCESS(rc))
     808                    {
     809                        fileData.pvData = pvData;
     810                        fileData.cbData = cbRead;
     811
     812                        uint32_t cbWritten;
     813                        rc = pTransfer->pProvider->WriteFileData(&fileData, &cbWritten);
     814                    }
     815
    455816                    if (RT_FAILURE(rc))
    456817                        break;
     
    468829
    469830        /* Only remove current object on success. */
    470         lstURI.RemoveFirst();
     831        pTransfer->URIList.RemoveFirst();
    471832    }
    472833
     
    483844 * @param   pvUser              User arguments; is PSHAREDCLIPBOARDURICTX.
    484845 */
    485 int SharedClipboardURITransferWriteThread(RTTHREAD hThread, void *pvUser)
     846static int sharedClipboardURITransferWriteThread(RTTHREAD hThread, void *pvUser)
    486847{
    487848    AssertPtrReturn(pvUser, VERR_INVALID_POINTER);
     
    489850    LogFlowFuncEnter();
    490851
    491     PSHAREDCLIPBOARDURICTX pURICtx = (PSHAREDCLIPBOARDURICTX)pvUser;
    492     AssertPtr(pURICtx);
    493 
    494852    /* At the moment we only support one transfer at a time. */
    495     PSHAREDCLIPBOARDURITRANSFER pTransfer = SharedClipboardURICtxGetTransfer(pURICtx, 0 /* Index*/);
     853    PSHAREDCLIPBOARDURITRANSFER pTransfer = (PSHAREDCLIPBOARDURITRANSFER)pvUser;
    496854    AssertPtr(pTransfer->pProvider);
    497855
     
    517875}
    518876
    519 /**
    520  * Initializes an URI clipboard context struct.
     877int SharedClipboardURITransferWrite(PSHAREDCLIPBOARDURITRANSFER pTransfer)
     878{
     879    AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
     880
     881    int rc = SharedClipboardURITransferMetaDataWrite(pTransfer, NULL /* pcbWritten */);
     882    if (RT_SUCCESS(rc))
     883        rc = SharedClipboardURITransferWriteObjects(pTransfer);
     884
     885    LogFlowFuncLeaveRC(rc);
     886    return rc;
     887}
     888
     889/**
     890 * Initializes a clipboard URI transfer.
    521891 *
    522892 * @returns VBox status code.
    523893 * @param   pURI                URI clipboard context to initialize.
    524  * @param   pTransfer           Pointer to URI clipboard transfer struct to use.
    525  */
    526 int SharedClipboardURICtxInit(PSHAREDCLIPBOARDURICTX pURI, PSHAREDCLIPBOARDURITRANSFER pTransfer)
    527 {
    528     AssertPtrReturn(pURI,      VERR_INVALID_POINTER);
    529     AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
     894 */
     895int SharedClipboardURICtxInit(PSHAREDCLIPBOARDURICTX pURI)
     896{
     897    AssertPtrReturn(pURI, VERR_INVALID_POINTER);
    530898
    531899    LogFlowFuncEnter();
     
    564932
    565933/**
    566  * Resets an URI clipboard context struct.
     934 * Resets an clipboard URI transfer.
    567935 *
    568936 * @param   pURI                URI clipboard context to reset.
     
    573941
    574942    LogFlowFuncEnter();
    575 
    576     pURI->cTransfers = 0;
    577943
    578944    PSHAREDCLIPBOARDURITRANSFER pTransfer;
     
    582948
    583949/**
    584  * Adds a new transfer to an URI clipboard context struct.
     950 * Adds a new URI transfer to an clipboard URI transfer.
    585951 *
    586952 * @returns VBox status code.
     
    595961    LogFlowFuncEnter();
    596962
     963    if (pURI->cTransfers) /* Only one transfer per URI context allowed at the moment. */
     964        return VERR_ALREADY_EXISTS;
     965
    597966    RTListAppend(&pURI->List, &pTransfer->Node);
     967    pURI->cTransfers++;
    598968
    599969    return VINF_SUCCESS;
     
    601971
    602972/**
    603  * Returns a specific URI transfer.
     973 * Removes an URI transfer from a clipboard URI transfer.
     974 *
     975 * @returns VBox status code.
     976 * @param   pURI                URI clipboard context to remove transfer from.
     977 * @param   pTransfer           Pointer to URI clipboard transfer struct to remove.
     978 */
     979int SharedClipboardURICtxTransferRemove(PSHAREDCLIPBOARDURICTX pURI, PSHAREDCLIPBOARDURITRANSFER pTransfer)
     980{
     981    AssertPtrReturn(pURI,      VERR_INVALID_POINTER);
     982    AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
     983
     984    LogFlowFuncEnter();
     985
     986    /* Sanity. */
     987    AssertReturn(pURI->cTransfers, VERR_WRONG_ORDER);
     988
     989    int rc = SharedClipboardURITransferDestroy(pTransfer);
     990    if (RT_SUCCESS(rc))
     991    {
     992
     993        RTListNodeRemove(&pTransfer->Node);
     994        pURI->cTransfers--;
     995    }
     996
     997    LogFlowFuncLeaveRC(rc);
     998    return rc;
     999}
     1000
     1001/**
     1002 * Returns a specific URI transfer, internal version.
    6041003 *
    6051004 * @returns URI transfer, or NULL if not found.
     
    6071006 * @param   uIdx                Index of the transfer to return.
    6081007 */
    609 PSHAREDCLIPBOARDURITRANSFER SharedClipboardURICtxGetTransfer(PSHAREDCLIPBOARDURICTX pURI, uint32_t uIdx)
     1008static PSHAREDCLIPBOARDURITRANSFER sharedClipboardURICtxGetTransferInternal(PSHAREDCLIPBOARDURICTX pURI, uint32_t uIdx)
    6101009{
    6111010    AssertReturn(uIdx == 0, NULL); /* Only one transfer allowed at the moment. */
     
    6141013
    6151014/**
     1015 * Returns a specific URI transfer.
     1016 *
     1017 * @returns URI transfer, or NULL if not found.
     1018 * @param   pURI                URI clipboard context to return transfer for.
     1019 * @param   uIdx                Index of the transfer to return.
     1020 */
     1021PSHAREDCLIPBOARDURITRANSFER SharedClipboardURICtxGetTransfer(PSHAREDCLIPBOARDURICTX pURI, uint32_t uIdx)
     1022{
     1023    return sharedClipboardURICtxGetTransferInternal(pURI, uIdx);
     1024}
     1025
     1026/**
    6161027 * Returns the number of active URI transfers.
    6171028 *
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