VirtualBox

Changeset 79267 in vbox


Ignore:
Timestamp:
Jun 21, 2019 10:11:59 AM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
131460
Message:

Shared Clipboard/URI: Update.

Location:
trunk
Files:
20 edited

Legend:

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

    r79174 r79267  
    3131#endif
    3232
     33#include <map>
     34
    3335#include <iprt/assert.h>
    3436#include <iprt/critsect.h>
     
    4042
    4143#include <VBox/HostServices/VBoxClipboardSvc.h>
    42 
    43 #ifdef VBOX_WITH_SHARED_CLIPBOARD_HOST
    44 #include <map> /* Needed for host provider. */
    45 #endif
    4644
    4745/** Clipboard area ID. A valid area is >= 1.
     
    384382};
    385383
     384int SharedClipboardURIDataHdrAlloc(PVBOXCLIPBOARDDATAHDR *ppDataHdr);
     385void SharedClipboardURIDataHdrFree(PVBOXCLIPBOARDDATAHDR pDataHdr);
     386PVBOXCLIPBOARDDATAHDR SharedClipboardURIDataHdrDup(PVBOXCLIPBOARDDATAHDR pDataHdr);
    386387uint32_t SharedClipboardURIDataHdrGetMetaDataSize(PVBOXCLIPBOARDDATAHDR pDataHdr);
    387388int SharedClipboardURIDataHdrInit(PVBOXCLIPBOARDDATAHDR pDataHdr);
    388389void SharedClipboardURIDataHdrDestroy(PVBOXCLIPBOARDDATAHDR pDataHdr);
     390void SharedClipboardURIDataHdrFree(PVBOXCLIPBOARDDATAHDR pDataHdr);
    389391void SharedClipboardURIDataHdrReset(PVBOXCLIPBOARDDATAHDR pDataHdr);
    390392bool SharedClipboardURIDataHdrIsValid(PVBOXCLIPBOARDDATAHDR pDataHdr);
    391393
     394int SharedClipboardURIDataChunkAlloc(PVBOXCLIPBOARDDATACHUNK *ppDataChunk);
     395void SharedClipboardURIDataChunkFree(PVBOXCLIPBOARDDATACHUNK pDataChunk);
     396PVBOXCLIPBOARDDATACHUNK SharedClipboardURIDataChunkDup(PVBOXCLIPBOARDDATACHUNK pDataChunk);
     397int SharedClipboardURIDataChunkInit(PVBOXCLIPBOARDDATACHUNK pDataChunk);
     398void SharedClipboardURIDataChunkDestroy(PVBOXCLIPBOARDDATACHUNK pDataChunk);
    392399bool SharedClipboardURIDataChunkIsValid(PVBOXCLIPBOARDDATACHUNK pDataChunk);
    393400
     401int SharedClipboardURIDirDataAlloc(PVBOXCLIPBOARDDIRDATA *ppDirData);
     402void SharedClipboardURIDirDataFree(PVBOXCLIPBOARDDIRDATA pDirData);
     403int SharedClipboardURIDirDataInit(PVBOXCLIPBOARDDIRDATA pDirData);
    394404void SharedClipboardURIDirDataDestroy(PVBOXCLIPBOARDDIRDATA pDirData);
     405PVBOXCLIPBOARDDIRDATA SharedClipboardURIDirDataDup(PVBOXCLIPBOARDDIRDATA pDirData);
    395406bool SharedClipboardURIDirDataIsValid(PVBOXCLIPBOARDDIRDATA pDirData);
    396407
     408int SharedClipboardURIFileHdrInit(PVBOXCLIPBOARDFILEHDR pFileHdr);
    397409void SharedClipboardURIFileHdrDestroy(PVBOXCLIPBOARDFILEHDR pFileHdr);
     410PVBOXCLIPBOARDFILEHDR SharedClipboardURIFileHdrDup(PVBOXCLIPBOARDFILEHDR pFileHdr);
    398411bool SharedClipboardURIFileHdrIsValid(PVBOXCLIPBOARDFILEHDR pFileHdr, PVBOXCLIPBOARDDATAHDR pDataHdr);
    399412
    400413void SharedClipboardURIFileDataDestroy(PVBOXCLIPBOARDFILEDATA pFileData);
     414PVBOXCLIPBOARDFILEDATA SharedClipboardURIFileDataDup(PVBOXCLIPBOARDFILEDATA pFileData);
    401415bool SharedClipboardURIFileDataIsValid(PVBOXCLIPBOARDFILEDATA pFileData, PVBOXCLIPBOARDDATAHDR pDataHdr);
    402416
    403 /**
    404  * Structure for maintaining a meta data format.
    405  */
    406 typedef struct _SHAREDCLIPBOARDMETADATAFMT
     417/** Specifies a meta data format. */
     418typedef uint32_t SHAREDCLIPBOARDMETADATAFMT;
     419
     420/**
     421 * Enumeration of meta data formats.
     422 */
     423typedef enum _SHAREDCLIPBOARDMETADATAFMTENUM
     424{
     425    /** Unknown meta data format; do not use. */
     426    SHAREDCLIPBOARDMETADATAFMT_UNKNOWN  = 0,
     427    /** Meta data is an URI list.
     428     *  UTF-8 format with Unix path separators. Each URI entry is separated by "\r\n". */
     429    SHAREDCLIPBOARDMETADATAFMT_URI_LIST = 1
     430} SHAREDCLIPBOARDMETADATAFMTENUM;
     431
     432/**
     433 * Structure for maintaining meta data format data.
     434 */
     435typedef struct _SHAREDCLIPBOARDMETADATAFMTDATA
    407436{
    408437    /** Meta data format version. */
     
    412441    /** Size of meta data format data (in bytes). */
    413442    uint32_t cbFmt;
    414 } SHAREDCLIPBOARDMETADATAFMT, *PSHAREDCLIPBOARDMETADATAFMT;
     443} SHAREDCLIPBOARDMETADATAFMTDATA, *PSHAREDCLIPBOARDMETADATAFMTDATA;
    415444
    416445/**
    417446 * Structure for keeping Shared Clipboard meta data.
    418  *
    419  * For URI transfers this represents a string list with the file object root entries in it.
     447 * The actual format of the meta data depends on the format set in enmFmt.
    420448 */
    421449typedef struct _SHAREDCLIPBOARDMETADATA
    422450{
     451    /** Format of the data. */
     452    SHAREDCLIPBOARDMETADATAFMT  enmFmt;
    423453    /** Actual meta data block. */
    424     void    *pvMeta;
     454    void                       *pvMeta;
    425455    /** Total size (in bytes) of the allocated meta data block .*/
    426     uint32_t cbMeta;
     456    uint32_t                    cbMeta;
    427457    /** How many bytes are being used in the meta data block. */
    428     uint32_t cbUsed;
     458    uint32_t                    cbUsed;
    429459} SHAREDCLIPBOARDMETADATA, *PSHAREDCLIPBOARDMETADATA;
    430460
    431 int SharedClipboardMetaDataInit(PSHAREDCLIPBOARDMETADATA pMeta);
     461int SharedClipboardMetaDataInit(PSHAREDCLIPBOARDMETADATA pMeta, SHAREDCLIPBOARDMETADATAFMT enmFmt);
    432462void SharedClipboardMetaDataDestroy(PSHAREDCLIPBOARDMETADATA pMeta);
    433463int SharedClipboardMetaDataAdd(PSHAREDCLIPBOARDMETADATA pMeta, const void *pvDataAdd, uint32_t cbDataAdd);
     464int SharedClipboardMetaDataConvertToFormat(const void *pvData, size_t cbData, SHAREDCLIPBOARDMETADATAFMT enmFmt,
     465                                           void **ppvData, uint32_t *pcbData);
    434466int SharedClipboardMetaDataResize(PSHAREDCLIPBOARDMETADATA pMeta, uint32_t cbNewSize);
    435467size_t SharedClipboardMetaDataGetFree(PSHAREDCLIPBOARDMETADATA pMeta);
     
    462494    /** The transfer's direction. */
    463495    SHAREDCLIPBOARDURITRANSFERDIR enmDir;
    464     /** The transfer's cached data header. */
    465     VBOXCLIPBOARDDATAHDR          Header;
    466     /** The transfer's cached meta data. */
    467     SHAREDCLIPBOARDMETADATA       Meta;
     496    /** The transfer's cached data header.
     497     *  Can be NULL if no header has been received yet. */
     498    PVBOXCLIPBOARDDATAHDR         pHeader;
     499    /** The transfer's cached meta data.
     500     *  Can be NULL if no meta data has been received yet. */
     501    PSHAREDCLIPBOARDMETADATA      pMeta;
    468502} SHAREDCLIPBOARDURITRANSFERSTATE, *PSHAREDCLIPBOARDURITRANSFERSTATE;
    469503
     
    494528} SHAREDCLIPBOARDPROVIDERCALLBACKDATA, *PSHAREDCLIPBOARDPROVIDERCALLBACKDATA;
    495529
    496 typedef DECLCALLBACK(int) FNSSHAREDCLIPBOARDPROVIDERREADDATAHDR(PSHAREDCLIPBOARDPROVIDERCALLBACKDATA pData);
    497 /** Pointer to a FNSSHAREDCLIPBOARDPROVIDERREADDATAHDR function. */
    498 typedef FNSSHAREDCLIPBOARDPROVIDERREADDATAHDR *PFNSSHAREDCLIPBOARDPROVIDERREADDATAHDR;
     530/** Callback functopn for the Shared Clipboard provider. */
     531typedef DECLCALLBACK(int) FNSSHAREDCLIPBOARDPROVIDERCALLBACK(PSHAREDCLIPBOARDPROVIDERCALLBACKDATA pData);
     532/** Pointer to a FNSSHAREDCLIPBOARDPROVIDERCALLBACK function. */
     533typedef FNSSHAREDCLIPBOARDPROVIDERCALLBACK *PFNSSHAREDCLIPBOARDPROVIDERCALLBACK;
    499534
    500535/**
     
    505540{
    506541    /** Saved user pointer. Will be passed to the callback (if needed). */
    507     void                                   *pvUser;
    508     /** Function pointer, called when the transfer has been started. */
    509     PFNSSHAREDCLIPBOARDPROVIDERREADDATAHDR  pfnReadDataHdr;
     542    void                                    *pvUser;
     543    /** Function pointer, called when reading the (meta) data header. */
     544    PFNSSHAREDCLIPBOARDPROVIDERCALLBACK      pfnReadDataHdr;
     545    /** Function pointer, called when reading a (meta) data chunk. */
     546    PFNSSHAREDCLIPBOARDPROVIDERCALLBACK      pfnReadDataChunk;
    510547} SHAREDCLIPBOARDPROVIDERCALLBACKS, *PSHAREDCLIPBOARDPROVIDERCALLBACKS;
    511548
     
    528565        struct
    529566        {
     567            SharedClipboardArea *pArea;
    530568        } HostService;
    531569    } u;
     
    587625public: /* Interface to be implemented. */
    588626
    589     virtual int ReadDataHdr(PVBOXCLIPBOARDDATAHDR pDataHdr);
     627    virtual int ReadDataHdr(PVBOXCLIPBOARDDATAHDR *ppDataHdr);
    590628    virtual int WriteDataHdr(const PVBOXCLIPBOARDDATAHDR pDataHdr);
    591629
    592     virtual int ReadDataChunk(const PVBOXCLIPBOARDDATAHDR pDataHdr, void *pvChunk, uint32_t cbChunk, uint32_t *pcbRead,
    593                               uint32_t fFlags = 0);
    594     virtual int WriteDataChunk(const PVBOXCLIPBOARDDATAHDR pDataHdr, const void *pvChunk, uint32_t cbChunk, uint32_t *pcbWritten,
    595                                uint32_t fFlags = 0);
    596 
    597     virtual int ReadDirectory(PVBOXCLIPBOARDDIRDATA pDirData);
     630    virtual int ReadDataChunk(const PVBOXCLIPBOARDDATAHDR pDataHdr, void *pvChunk, uint32_t cbChunk, uint32_t fFlags = 0,
     631                              uint32_t *pcbRead = NULL);
     632    virtual int WriteDataChunk(const PVBOXCLIPBOARDDATAHDR pDataHdr, const void *pvChunk, uint32_t cbChunk, uint32_t fFlags = 0,
     633                               uint32_t *pcbWritten = NULL);
     634
     635    virtual int ReadDirectory(PVBOXCLIPBOARDDIRDATA *ppDirData);
    598636    virtual int WriteDirectory(const PVBOXCLIPBOARDDIRDATA pDirData);
    599637
    600     virtual int ReadFileHdr(PVBOXCLIPBOARDFILEHDR pFileHdr);
     638    virtual int ReadFileHdr(PVBOXCLIPBOARDFILEHDR *ppFileHdr);
    601639    virtual int WriteFileHdr(const PVBOXCLIPBOARDFILEHDR pFileHdr);
    602640
    603     virtual int ReadFileData(PVBOXCLIPBOARDFILEDATA pFileData, uint32_t *pcbRead);
    604     virtual int WriteFileData(const PVBOXCLIPBOARDFILEDATA pFileData, uint32_t *pcbWritten);
     641    virtual int ReadFileData(void *pvData, uint32_t cbData, uint32_t fFlags = 0, uint32_t *pcbRead = NULL);
     642    virtual int WriteFileData(void *pvData, uint32_t cbData, uint32_t fFlags = 0, uint32_t *pcbWritten = NULL);
    605643
    606644    virtual void Reset(void);
     
    618656
    619657protected:
    620 
    621     /** Number of references to this instance. */
    622     volatile uint32_t                m_cRefs;
    623     /** The provider's callback table. */
    624     SHAREDCLIPBOARDPROVIDERCALLBACKS m_Callbacks;
    625 };
    626 
    627 /**
    628  * Shared Clipboard provider implementation for VbglR3 (guest side).
    629  */
    630 class SharedClipboardProviderVbglR3 : protected SharedClipboardProvider
    631 {
    632     friend class SharedClipboardProvider;
    633 
    634 public:
    635 
    636     virtual ~SharedClipboardProviderVbglR3(void);
    637 
    638 public:
    639 
    640     int ReadDataHdr(PVBOXCLIPBOARDDATAHDR pDataHdr);
    641     int WriteDataHdr(const PVBOXCLIPBOARDDATAHDR pDataHdr);
    642 
    643     int ReadDataChunkk(const PVBOXCLIPBOARDDATAHDR pDataHdr, void *pvChunk, uint32_t cbChunk, uint32_t *pcbRead,
    644                        uint32_t fFlags = 0);
    645     int WriteDataChunk(const PVBOXCLIPBOARDDATAHDR pDataHdr, const void *pvChunk, uint32_t cbChunk, uint32_t *pcbWritten,
    646                        uint32_t fFlags = 0);
    647 
    648     int ReadDirectory(PVBOXCLIPBOARDDIRDATA pDirData);
    649     int WriteDirectory(const PVBOXCLIPBOARDDIRDATA pDirData);
    650 
    651     int ReadFileHdr(PVBOXCLIPBOARDFILEHDR pFileHdr);
    652     int WriteFileHdr(const PVBOXCLIPBOARDFILEHDR pFileHdr);
    653 
    654     int ReadFileData(PVBOXCLIPBOARDFILEDATA pFileData, uint32_t *pcbRead);
    655     int WriteFileData(const PVBOXCLIPBOARDFILEDATA pFileData, uint32_t *pcbWritten);
    656 
    657     void Reset(void);
    658 
    659 protected:
    660 
    661     SharedClipboardProviderVbglR3(uint32_t uClientID);
    662 
    663     /** HGCM client ID to use. */
    664     uint32_t m_uClientID;
    665 };
    666 
    667 #ifdef VBOX_WITH_SHARED_CLIPBOARD_HOST
    668 /**
    669  * Shared Clipboard provider implementation for host service (host side).
    670  */
    671 class SharedClipboardProviderHostService : protected SharedClipboardProvider
    672 {
    673     friend class SharedClipboardProvider;
    674 
    675 public:
    676 
    677     virtual ~SharedClipboardProviderHostService(void);
    678 
    679 public:
    680 
    681     int ReadDataHdr(PVBOXCLIPBOARDDATAHDR pDataHdr);
    682     int WriteDataHdr(const PVBOXCLIPBOARDDATAHDR pDataHdr);
    683 
    684     int ReaaDataChunk(const PVBOXCLIPBOARDDATAHDR pDataHdr, void *pvMeta, uint32_t cbMeta, uint32_t *pcbRead, uint32_t fFlags = 0);
    685     int WriteDataChunk(const PVBOXCLIPBOARDDATAHDR pDataHdr, const void *pvMeta, uint32_t cbMeta, uint32_t *pcbWritten,
    686                        uint32_t fFlags = 0);
    687 
    688     int ReadDirectory(PVBOXCLIPBOARDDIRDATA pDirData);
    689     int WriteDirectory(const PVBOXCLIPBOARDDIRDATA pDirData);
    690 
    691     int ReadFileHdr(PVBOXCLIPBOARDFILEHDR pFileHdr);
    692     int WriteFileHdr(const PVBOXCLIPBOARDFILEHDR pFileHdr);
    693 
    694     int ReadFileData(PVBOXCLIPBOARDFILEDATA pFileData, uint32_t *pcbRead);
    695     int WriteFileData(const PVBOXCLIPBOARDFILEDATA pFileData, uint32_t *pcbWritten);
    696 
    697     void Reset(void);
    698 
    699 public:
    700 
    701     int OnRead(PSHAREDCLIPBOARDPROVIDERREADPARMS pParms);
    702     int OnWrite(PSHAREDCLIPBOARDPROVIDERWRITEPARMS pParms);
    703 
    704 protected:
    705 
    706     SharedClipboardProviderHostService(void);
    707658
    708659    /**
     
    714665        virtual ~Event();
    715666
     667        void *DataAdopt(void);
    716668        uint32_t DataSize(void);
    717669        void *DataRaw(void);
     670        void Reset(void);
    718671        int SetData(const void *pvData, uint32_t cbData);
    719672        int Wait(RTMSINTERVAL uTimeoutMs);
     
    734687    int eventRegister(uint32_t uMsg);
    735688    int eventUnregister(uint32_t uMsg);
     689    int eventUnregisterAll(void);
    736690    int eventSignal(uint32_t uMsg);
    737     SharedClipboardProviderHostService::Event *eventGet(uint32_t uMsg);
    738 
    739 protected:
    740 
     691    int eventWait(uint32_t uMsg, PFNSSHAREDCLIPBOARDPROVIDERCALLBACK pfnCallback, RTMSINTERVAL uTimeoutMs,
     692                  void **ppvData, uint32_t *pcbData = NULL);
     693    SharedClipboardProvider::Event *eventGet(uint32_t uMsg);
     694
     695protected:
     696
     697    /** Number of references to this instance. */
     698    volatile uint32_t                m_cRefs;
     699    /** The provider's callback table. */
     700    SHAREDCLIPBOARDPROVIDERCALLBACKS m_Callbacks;
    741701    /** Default timeout (in ms) for waiting for events. */
    742     RTMSINTERVAL                    m_uTimeoutMs;
     702    RTMSINTERVAL                     m_uTimeoutMs;
    743703    /** Map of (internal) events to provide asynchronous reads / writes. */
    744     EventMap                        m_mapEvents;
     704    EventMap                         m_mapEvents;
     705};
     706
     707/**
     708 * Shared Clipboard provider implementation for VbglR3 (guest side).
     709 */
     710class SharedClipboardProviderVbglR3 : protected SharedClipboardProvider
     711{
     712    friend class SharedClipboardProvider;
     713
     714public:
     715
     716    virtual ~SharedClipboardProviderVbglR3(void);
     717
     718public:
     719
     720    int ReadDataHdr(PVBOXCLIPBOARDDATAHDR *ppDataHdr);
     721    int WriteDataHdr(const PVBOXCLIPBOARDDATAHDR pDataHdr);
     722
     723    int ReadDataChunk(const PVBOXCLIPBOARDDATAHDR pDataHdr, void *pvChunk, uint32_t cbChunk, uint32_t fFlags = 0,
     724                      uint32_t *pcbRead = NULL);
     725    int WriteDataChunk(const PVBOXCLIPBOARDDATAHDR pDataHdr, const void *pvChunk, uint32_t cbChunk, uint32_t fFlags = 0,
     726                       uint32_t *pcbWritten = NULL);
     727
     728    int ReadDirectory(PVBOXCLIPBOARDDIRDATA *ppDirData);
     729    int WriteDirectory(const PVBOXCLIPBOARDDIRDATA pDirData);
     730
     731    int ReadFileHdr(PVBOXCLIPBOARDFILEHDR *ppFileHdr);
     732    int WriteFileHdr(const PVBOXCLIPBOARDFILEHDR pFileHdr);
     733
     734    int ReadFileData(void *pvData, uint32_t cbData, uint32_t fFlags = 0, uint32_t *pcbRead = NULL);
     735    int WriteFileData(void *pvData, uint32_t cbData, uint32_t fFlags = 0, uint32_t *pcbWritten = NULL);
     736
     737    void Reset(void);
     738
     739protected:
     740
     741    SharedClipboardProviderVbglR3(uint32_t uClientID);
     742
     743    /** HGCM client ID to use. */
     744    uint32_t m_uClientID;
     745};
     746
     747#ifdef VBOX_WITH_SHARED_CLIPBOARD_HOST
     748/**
     749 * Shared Clipboard provider implementation for host service (host side).
     750 */
     751class SharedClipboardProviderHostService : protected SharedClipboardProvider
     752{
     753    friend class SharedClipboardProvider;
     754
     755public:
     756
     757    virtual ~SharedClipboardProviderHostService();
     758
     759public:
     760
     761    int ReadDataHdr(PVBOXCLIPBOARDDATAHDR *ppDataHdr);
     762    int WriteDataHdr(const PVBOXCLIPBOARDDATAHDR pDataHdr);
     763
     764    int ReadDataChunk(const PVBOXCLIPBOARDDATAHDR pDataHdr, void *pvChunk, uint32_t cbChunk, uint32_t fFlags = 0,
     765                      uint32_t *pcbRead = NULL);
     766    int WriteDataChunk(const PVBOXCLIPBOARDDATAHDR pDataHdr, const void *pvChunk, uint32_t cbChunk, uint32_t fFlags = 0,
     767                       uint32_t *pcbWritten = NULL);
     768
     769    int ReadDirectory(PVBOXCLIPBOARDDIRDATA *ppDirData);
     770    int WriteDirectory(const PVBOXCLIPBOARDDIRDATA pDirData);
     771
     772    int ReadFileHdr(PVBOXCLIPBOARDFILEHDR *ppFileHdr);
     773    int WriteFileHdr(const PVBOXCLIPBOARDFILEHDR pFileHdr);
     774
     775    int ReadFileData(void *pvData, uint32_t cbData, uint32_t fFlags = 0, uint32_t *pcbRead = NULL);
     776    int WriteFileData(void *pvData, uint32_t cbData, uint32_t fFlags = 0, uint32_t *pcbWritten = NULL);
     777
     778    void Reset(void);
     779
     780public:
     781
     782    int OnWrite(PSHAREDCLIPBOARDPROVIDERWRITEPARMS pParms);
     783
     784protected:
     785
     786    SharedClipboardProviderHostService(SharedClipboardArea *pArea);
     787
     788protected:
     789
     790    /** Pointer to associated clipboard area. */
     791    SharedClipboardArea            *m_pArea;
    745792};
    746793#endif /* VBOX_WITH_SHARED_CLIPBOARD_HOST */
     
    835882    SharedClipboardArea                *pArea;
    836883    /** The URI list for this transfer. */
    837     SharedClipboardURIList              URIList;
     884    SharedClipboardURIList             *pURIList;
    838885    /** Context of current object being handled. */
    839886    SHAREDCLIPBOARDCLIENTURIOBJCTX      ObjCtx;
     
    869916
    870917int SharedClipboardURIObjCtxInit(PSHAREDCLIPBOARDCLIENTURIOBJCTX pObjCtx);
    871 void SharedClipboardURIObjCtxUninit(PSHAREDCLIPBOARDCLIENTURIOBJCTX pObjCtx);
     918void SharedClipboardURIObjCtxDestroy(PSHAREDCLIPBOARDCLIENTURIOBJCTX pObjCtx);
    872919SharedClipboardURIObject *SharedClipboardURIObjCtxGetObj(PSHAREDCLIPBOARDCLIENTURIOBJCTX pObjCtx);
    873920bool SharedClipboardURIObjCtxIsValid(PSHAREDCLIPBOARDCLIENTURIOBJCTX pObjCtx);
    874921
    875 int SharedClipboardURITransferCreate(SHAREDCLIPBOARDURITRANSFERDIR enmDir, PSHAREDCLIPBOARDPROVIDERCREATIONCTX pCtx,
    876                                      PSHAREDCLIPBOARDURITRANSFER *ppTransfer);
     922int SharedClipboardURITransferCreate(SHAREDCLIPBOARDURITRANSFERDIR enmDir, PSHAREDCLIPBOARDURITRANSFER *ppTransfer);
    877923int SharedClipboardURITransferDestroy(PSHAREDCLIPBOARDURITRANSFER pTransfer);
     924int SharedClipboardURITransferPrepare(PSHAREDCLIPBOARDURITRANSFER pTransfer);
     925int SharedClipboardURITransferProviderCreate(PSHAREDCLIPBOARDURITRANSFER pTransfer,
     926                                             PSHAREDCLIPBOARDPROVIDERCREATIONCTX pProviderCtx);
    878927void SharedClipboardURITransferReset(PSHAREDCLIPBOARDURITRANSFER pTransfer);
    879928SharedClipboardArea *SharedClipboardURITransferGetArea(PSHAREDCLIPBOARDURITRANSFER pTransfer);
     929PSHAREDCLIPBOARDCLIENTURIOBJCTX SharedClipboardURITransferGetCurrentObjCtx(PSHAREDCLIPBOARDURITRANSFER pTransfer);
    880930const SharedClipboardURIObject *SharedClipboardURITransferGetCurrentObject(PSHAREDCLIPBOARDURITRANSFER pTransfer);
    881931SharedClipboardProvider *SharedClipboardURITransferGetProvider(PSHAREDCLIPBOARDURITRANSFER pTransfer);
     
    886936
    887937int SharedClipboardURITransferMetaDataAdd(PSHAREDCLIPBOARDURITRANSFER pTransfer, const void *pvMeta, uint32_t cbMeta);
    888 int SharedClipboardURITransferMetaDataComplete(PSHAREDCLIPBOARDURITRANSFER pTransfer);
     938bool SharedClipboardURITransferMetaDataIsComplete(PSHAREDCLIPBOARDURITRANSFER pTransfer);
    889939int SharedClipboardURITransferMetaGet(PSHAREDCLIPBOARDURITRANSFER pTransfer, const void *pvMeta, uint32_t cbMeta);
    890940int SharedClipboardURITransferMetaDataRead(PSHAREDCLIPBOARDURITRANSFER pTransfer, uint32_t *pcbRead);
     
    892942
    893943int SharedClipboardURITransferRead(PSHAREDCLIPBOARDURITRANSFER pTransfer);
     944int SharedClipboardURITransferReadObjects(PSHAREDCLIPBOARDURITRANSFER pTransfer);
    894945
    895946int SharedClipboardURITransferWrite(PSHAREDCLIPBOARDURITRANSFER pTransfer);
  • trunk/include/VBox/GuestHost/SharedClipboard-win.h

    r79178 r79267  
    122122
    123123#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
    124 int VBoxClipboardWinDropFilesToStringList(DROPFILES *pDropFiles, char **ppszData, size_t *pcbData);
     124int VBoxClipboardWinDropFilesToTransfer(DROPFILES *pDropFiles, PSHAREDCLIPBOARDURITRANSFER pTransfer);
    125125#endif
    126126
     
    137137int VBoxClipboardWinAnnounceFormats(PVBOXCLIPBOARDWINCTX pWinCtx, VBOXCLIPBOARDFORMATS fFormats);
    138138#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
    139 int VBoxClipboardWinURIReadMain(PVBOXCLIPBOARDWINCTX pWinCtx, PSHAREDCLIPBOARDURICTX pURICtx,
    140                                 PSHAREDCLIPBOARDPROVIDERCREATIONCTX pProviderCtx, VBOXCLIPBOARDFORMATS fFormats);
     139int VBoxClipboardWinURIAnnounce(PVBOXCLIPBOARDWINCTX pWinCtx, PSHAREDCLIPBOARDURICTX pURICtx,
     140                                PSHAREDCLIPBOARDURITRANSFER pTransfer);
    141141#endif
    142142
  • trunk/include/VBox/HostServices/VBoxClipboardSvc.h

    r79174 r79267  
    195195     */
    196196    HGCMFunctionParameter cbMeta;          /* OUT uint64_t */
     197    /** Size (in bytes) of meta data format. */
     198    HGCMFunctionParameter cbMetaFmt;       /* OUT uint32_t */
    197199    /** Meta data format. */
    198200    HGCMFunctionParameter pvMetaFmt;       /* OUT ptr */
    199     /** Size (in bytes) of meta data format. */
    200     HGCMFunctionParameter cbMetaFmt;       /* OUT uint32_t */
    201201    /* Number of objects (files/directories) to transfer. */
    202202    HGCMFunctionParameter cObjects;        /* OUT uint64_t */
     
    205205    /** Checksum type. */
    206206    HGCMFunctionParameter enmChecksumType; /* OUT uint32_t */
     207    /** Size (in bytes) of checksum. */
     208    HGCMFunctionParameter cbChecksum;      /* OUT uint32_t */
    207209    /** Checksum buffer for the entire data to be transferred. */
    208210    HGCMFunctionParameter pvChecksum;      /* OUT ptr */
    209     /** Size (in bytes) of checksum. */
    210     HGCMFunctionParameter cbChecksum;      /* OUT uint32_t */
    211211} VBoxClipboardReadDataHdrMsg, VBoxClipboardWriteDataHdrMsg;
    212212
     
    227227    /** Context ID. Unused at the moment. */
    228228    HGCMFunctionParameter uContext;     /* OUT uint32_t */
     229    /** Size (in bytes) of data block to send. */
     230    HGCMFunctionParameter cbData;       /* OUT uint32_t */
    229231    /** Data block to send. */
    230232    HGCMFunctionParameter pvData;       /* OUT ptr */
    231     /** Size (in bytes) of data block to send. */
    232     HGCMFunctionParameter cbData;       /* OUT uint32_t */
     233    /** Size (in bytes) of checksum. */
     234    HGCMFunctionParameter cbChecksum;   /* OUT uint32_t */
    233235    /** (Rolling) Checksum, based on checksum type in data header. */
    234236    HGCMFunctionParameter pvChecksum;   /* OUT ptr */
    235     /** Size (in bytes) of checksum. */
    236     HGCMFunctionParameter cbChecksum;   /* OUT uint32_t */
    237237} VBoxClipboardReadDataChunkMsg, VBoxClipboardWriteDataChunkMsg;
    238238
     
    253253    /** Context ID. Unused at the moment. */
    254254    HGCMFunctionParameter uContext;     /* OUT uint32_t */
     255    /** Size (in bytes) of directory name. */
     256    HGCMFunctionParameter cbName;       /* OUT uint32_t */
    255257    /** Directory name. */
    256258    HGCMFunctionParameter pvName;       /* OUT ptr */
    257     /** Size (in bytes) of directory name. */
    258     HGCMFunctionParameter cbName;       /* OUT uint32_t */
    259259    /** Directory mode. */
    260260    HGCMFunctionParameter fMode;        /* OUT uint32_t */
     
    277277    /** Context ID. Unused at the moment. */
    278278    HGCMFunctionParameter uContext;     /* OUT uint32_t */
     279    /** Size (in bytes) of file path. */
     280    HGCMFunctionParameter cbName;       /* OUT uint32_t */
    279281    /** File path. */
    280282    HGCMFunctionParameter pvName;       /* OUT ptr */
    281     /** Size (in bytes) of file path. */
    282     HGCMFunctionParameter cbName;       /* OUT uint32_t */
    283283    /** Optional flags; unused at the moment. */
    284284    HGCMFunctionParameter uFlags;       /* OUT uint32_t */
     
    305305    /** Context ID. Unused at the moment. */
    306306    HGCMFunctionParameter uContext;     /* OUT uint32_t */
     307    /** Size (in bytes) of current data chunk. */
     308    HGCMFunctionParameter cbData;       /* OUT uint32_t */
    307309    /** Current data chunk. */
    308310    HGCMFunctionParameter pvData;       /* OUT ptr */
    309     /** Size (in bytes) of current data chunk. */
    310     HGCMFunctionParameter cbData;       /* OUT uint32_t */
     311    /** Size (in bytes) of current data chunk checksum. */
     312    HGCMFunctionParameter cbChecksum;   /* OUT uint32_t */
    311313    /** Checksum of data block, based on the checksum
    312314     *  type in the data header. Optional. */
    313315    HGCMFunctionParameter pvChecksum;   /* OUT ptr */
    314     /** Size (in bytes) of curren data chunk checksum. */
    315     HGCMFunctionParameter cbChecksum;   /* OUT uint32_t */
    316316} VBoxClipboardReadFileDataMsg, VBoxClipboardWriteFileDataMsg;
    317317
     
    369369     *  This size also is part of cbTotal already. */
    370370    uint32_t                    cbMeta;
     371    /** Size (in bytes) of meta format buffer.
     372     *  Is sizeof(SHAREDCLIPBOARDMETADATAFMT). */
     373    uint32_t                    cbMetaFmt;
    371374    /** Meta data format.
    372375     *  Is SHAREDCLIPBOARDMETADATAFMT. */
    373376    void                       *pvMetaFmt;
    374     /** Size (in bytes) of meta format buffer.
    375      *  Is sizeof(SHAREDCLIPBOARDMETADATAFMT). */
    376     uint32_t                    cbMetaFmt;
    377377    /** Number of objects (files/directories) to transfer. */
    378378    uint64_t                    cObjects;
     
    382382    /** Checksum type. Currently unused, so specify RTDIGESTTYPE_INVALID. */
    383383    RTDIGESTTYPE                enmChecksumType;
     384    /** Size (in bytes) of checksum. */
     385    uint32_t                    cbChecksum;
    384386    /** The actual checksum buffer for the entire data to be transferred,
    385387     *  based on enmChksumType. If RTDIGESTTYPE_INVALID is specified,
    386388     *  no checksum is being used and pvChecksum will be NULL. */
    387389    void                       *pvChecksum;
    388     /** Size (in bytes) of checksum. */
    389     uint32_t                    cbChecksum;
    390390} VBOXCLIPBOARDDATAHDR, *PVBOXCLIPBOARDDATAHDR;
    391391
  • trunk/src/VBox

    • Property svn:mergeinfo
      •  

        old new  
        99/branches/VBox-5.1/src/VBox:112367,116543,116550,116568,116573
        1010/branches/VBox-5.2/src/VBox:119536,120083,120099,120213,120221,120239,123597-123598,123600-123601,123755,124263,124273,124277-124279,124284-124286,124288-124290,125768,125779-125780,125812,127158-127159,127162-127167,127180
        11 /branches/VBox-6.0/src/VBox:130474-130475,130477,130479
         11/branches/VBox-6.0/src/VBox:130474-130475,130477,130479,131352
        1212/branches/aeichner/vbox-chromium-cleanup/src/VBox:129818-129851,129853-129861,129871-129872,129876,129880,129882,130013-130015,130094-130095
        1313/branches/andy/draganddrop/src/VBox:90781-91268
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxClipboard.cpp

    r79174 r79267  
    316316       case VBOX_CLIPBOARD_WM_SET_FORMATS:
    317317       {
     318            LogFunc(("VBOX_CLIPBOARD_WM_SET_FORMATS\n"));
     319
    318320            /* Announce available formats. Do not insert data -- will be inserted in WM_RENDERFORMAT. */
    319321            VBOXCLIPBOARDFORMATS fFormats = (uint32_t)lParam;
     
    330332                        LogFunc(("VBOX_SHARED_CLIPBOARD_FMT_URI_LIST\n"));
    331333
    332                         SHAREDCLIPBOARDPROVIDERCREATIONCTX providerCtx;
    333                         RT_ZERO(providerCtx);
    334                         providerCtx.enmSource = SHAREDCLIPBOARDPROVIDERSOURCE_VBGLR3;
    335                         providerCtx.u.VbglR3.uClientID = pCtx->u32ClientID;
    336 
    337                         rc = VBoxClipboardWinURIReadMain(pWinCtx, &pCtx->URI, &providerCtx, fFormats);
    338 
    339                         /* Note: VBoxClipboardWinURIReadMain() takes care of closing the clipboard. */
     334                        PSHAREDCLIPBOARDURITRANSFER pTransfer;
     335                        rc = SharedClipboardURITransferCreate(SHAREDCLIPBOARDURITRANSFERDIR_READ, &pTransfer);
     336                        if (RT_SUCCESS(rc))
     337                        {
     338                            SHAREDCLIPBOARDURITRANSFERCALLBACKS TransferCallbacks;
     339                            RT_ZERO(TransferCallbacks);
     340
     341                            TransferCallbacks.pvUser              = &pCtx->URI;
     342                            TransferCallbacks.pfnTransferComplete = vboxClipboardOnURITransferComplete;
     343                            TransferCallbacks.pfnTransferError    = vboxClipboardOnURITransferError;
     344
     345                            SharedClipboardURITransferSetCallbacks(pTransfer, &TransferCallbacks);
     346
     347                            SHAREDCLIPBOARDPROVIDERCREATIONCTX creationCtx;
     348                            RT_ZERO(creationCtx);
     349                            creationCtx.enmSource = SHAREDCLIPBOARDPROVIDERSOURCE_VBGLR3;
     350                            creationCtx.u.VbglR3.uClientID = pCtx->u32ClientID;
     351
     352                            rc = SharedClipboardURITransferProviderCreate(pTransfer, &creationCtx);
     353                            if (RT_SUCCESS(rc))
     354                            {
     355                                rc = SharedClipboardURICtxTransferAdd(&pCtx->URI, pTransfer);
     356                                if (RT_SUCCESS(rc))
     357                                    rc = VBoxClipboardWinURIAnnounce(pWinCtx, &pCtx->URI, pTransfer);
     358                            }
     359
     360                            /* Note: VBoxClipboardWinURIAnnounce() takes care of closing the clipboard. */
     361
     362                            LogFunc(("VBOX_SHARED_CLIPBOARD_FMT_URI_LIST: rc=%Rrc\n", rc));
     363                        }
    340364                    }
    341365                    else
     
    427451               else if (uFormat == VBOX_SHARED_CLIPBOARD_FMT_URI_LIST)
    428452               {
    429                    const uint32_t cTransfers = SharedClipboardURICtxGetActiveTransfers(&pCtx->URI);
    430 
    431                    LogFunc(("VBOX_SHARED_CLIPBOARD_FMT_URI_LIST cTransfers=%RU32\n", cTransfers));
    432 
    433                    if (cTransfers == 0) /* Only allow one transfer at a time for now. */
    434                    {
    435                        SHAREDCLIPBOARDPROVIDERCREATIONCTX creationCtx;
    436                        RT_ZERO(creationCtx);
    437                        creationCtx.enmSource = SHAREDCLIPBOARDPROVIDERSOURCE_VBGLR3;
    438                        creationCtx.u.VbglR3.uClientID = pCtx->u32ClientID;
    439 
    440                        PSHAREDCLIPBOARDURITRANSFER pTransfer;
    441                        rc = SharedClipboardURITransferCreate(SHAREDCLIPBOARDURITRANSFERDIR_WRITE, &creationCtx, &pTransfer);
    442                        if (RT_SUCCESS(rc))
    443                        {
    444                            SHAREDCLIPBOARDURITRANSFERCALLBACKS TransferCallbacks;
    445                            RT_ZERO(TransferCallbacks);
    446 
    447                            TransferCallbacks.pvUser              = &pCtx->URI;
    448                            TransferCallbacks.pfnTransferComplete = vboxClipboardOnURITransferComplete;
    449                            TransferCallbacks.pfnTransferError    = vboxClipboardOnURITransferError;
    450 
    451                            SharedClipboardURITransferSetCallbacks(pTransfer, &TransferCallbacks);
    452 
    453                            rc = SharedClipboardURICtxTransferAdd(&pCtx->URI, pTransfer);
    454                            if (RT_SUCCESS(rc))
    455                            {
    456                                /* The data data in CF_HDROP format, as the files are locally present and don't need to be
     453                   LogFunc(("VBOX_SHARED_CLIPBOARD_FMT_URI_LIST cTransfers=%RU32\n",
     454                            SharedClipboardURICtxGetActiveTransfers(&pCtx->URI)));
     455
     456                    PSHAREDCLIPBOARDURITRANSFER pTransfer;
     457                    rc = SharedClipboardURITransferCreate(SHAREDCLIPBOARDURITRANSFERDIR_WRITE, &pTransfer);
     458                    if (RT_SUCCESS(rc))
     459                    {
     460                        SHAREDCLIPBOARDURITRANSFERCALLBACKS TransferCallbacks;
     461                        RT_ZERO(TransferCallbacks);
     462
     463                        TransferCallbacks.pvUser              = &pCtx->URI;
     464                        TransferCallbacks.pfnTransferComplete = vboxClipboardOnURITransferComplete;
     465                        TransferCallbacks.pfnTransferError    = vboxClipboardOnURITransferError;
     466
     467                        SharedClipboardURITransferSetCallbacks(pTransfer, &TransferCallbacks);
     468
     469                        SHAREDCLIPBOARDPROVIDERCREATIONCTX creationCtx;
     470                        RT_ZERO(creationCtx);
     471                        creationCtx.enmSource = SHAREDCLIPBOARDPROVIDERSOURCE_VBGLR3;
     472                        creationCtx.u.VbglR3.uClientID = pCtx->u32ClientID;
     473
     474                        rc = SharedClipboardURITransferProviderCreate(pTransfer, &creationCtx);
     475                        if (RT_SUCCESS(rc))
     476                        {
     477                            rc = SharedClipboardURICtxTransferAdd(&pCtx->URI, pTransfer);
     478                            if (RT_SUCCESS(rc))
     479                            {
     480                                /* The data data in CF_HDROP format, as the files are locally present and don't need to be
    457481                                * presented as a IDataObject or IStream. */
    458                                hClip = GetClipboardData(CF_HDROP);
    459                                if (hClip)
    460                                {
    461                                    HDROP hDrop = (HDROP)GlobalLock(hClip);
    462                                    if (hDrop)
    463                                    {
    464                                        char *pszList;
    465                                        size_t cbList;
    466                                        rc = VBoxClipboardWinDropFilesToStringList((DROPFILES *)hDrop, &pszList, &cbList);
    467                                        if (RT_SUCCESS(rc))
    468                                        {
    469                                            rc = SharedClipboardURITransferMetaDataAdd(pTransfer, pszList, (uint32_t)cbList);
    470                                            RTMemFree(pszList);
    471                                        }
    472 
    473                                        GlobalUnlock(hClip);
    474 
    475                                        if (RT_SUCCESS(rc))
    476                                        {
    477                                            rc = SharedClipboardURITransferMetaDataComplete(pTransfer);
    478                                            if (RT_SUCCESS(rc))
    479                                                rc = SharedClipboardURITransferRun(pTransfer, true /* fAsync */);
    480                                        }
    481                                    }
    482                                    else
    483                                    {
    484                                        hClip = NULL;
    485                                    }
    486                                }
    487                            }
    488                        }
    489                    }
    490                    else
    491                    {
    492                        rc = VERR_SHCLPB_MAX_TRANSFERS_REACHED;
    493                        LogRel(("Clipboard: Only one transfer at a time supported (current %RU32 transfer(s) active), skipping\n",
    494                                cTransfers));
     482                                hClip = GetClipboardData(CF_HDROP);
     483                                if (hClip)
     484                                {
     485                                    HDROP hDrop = (HDROP)GlobalLock(hClip);
     486                                    if (hDrop)
     487                                    {
     488                                        rc = VBoxClipboardWinDropFilesToTransfer((DROPFILES *)hDrop, pTransfer);
     489
     490                                        GlobalUnlock(hClip);
     491
     492                                        if (RT_SUCCESS(rc))
     493                                        {
     494                                            rc = SharedClipboardURITransferPrepare(pTransfer);
     495                                            if (RT_SUCCESS(rc))
     496                                                rc = SharedClipboardURITransferRun(pTransfer, true /* fAsync */);
     497                                        }
     498                                    }
     499                                    else
     500                                    {
     501                                        hClip = NULL;
     502                                    }
     503                                }
     504                            }
     505                        }
    495506                   }
    496507
     
    605616    LogFlowFunc(("pData=%p, rc=%Rrc\n", pData, rc));
    606617
    607     LogRel(("Shared Clipboard: Transfer to destination complete"));
     618    LogRel2(("Shared Clipboard: Transfer to destination complete\n"));
    608619
    609620    PSHAREDCLIPBOARDURICTX pCtx = (PSHAREDCLIPBOARDURICTX)pData->pvUser;
  • trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibClipboard.cpp

    r79174 r79267  
    178178    Msg.cbTotal.SetUInt64(0);
    179179    Msg.cbMeta.SetUInt32(0);
     180    Msg.cbMetaFmt.SetUInt32(0);
    180181    Msg.pvMetaFmt.SetPtr(pDataHdr->pvMetaFmt, pDataHdr->cbMetaFmt);
    181     Msg.cbMetaFmt.SetUInt32(0);
    182182    Msg.cObjects.SetUInt64(0);
    183183    Msg.enmCompression.SetUInt32(0);
     
    231231    Msg.cbTotal.SetUInt64(pDataHdr->cbTotal);
    232232    Msg.cbMeta.SetUInt32(pDataHdr->cbMeta);
     233    Msg.cbMetaFmt.SetUInt32(pDataHdr->cbMetaFmt);
    233234    Msg.pvMetaFmt.SetPtr(pDataHdr->pvMetaFmt, pDataHdr->cbMetaFmt);
    234     Msg.cbMetaFmt.SetUInt32(pDataHdr->cbMetaFmt);
    235235    Msg.cObjects.SetUInt64(pDataHdr->cObjects);
    236236    Msg.enmCompression.SetUInt32(pDataHdr->enmCompression);             /** @todo Not used yet. */
    237237    Msg.enmChecksumType.SetUInt32(RTDIGESTTYPE_INVALID);                /** @todo Not used yet. */
     238    Msg.cbChecksum.SetUInt32(0);                                        /** @todo Not used yet. */
    238239    Msg.pvChecksum.SetPtr(NULL, 0);                                     /** @todo Not used yet. */
    239     Msg.cbChecksum.SetUInt32(0);                                        /** @todo Not used yet. */
    240240
    241241    int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
     
    426426    VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
    427427                       VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_DATA_CHUNK, VBOX_SHARED_CLIPBOARD_CPARMS_WRITE_DATA_CHUNK);
     428
     429    Msg.uContext.SetUInt32(0);                                          /** @todo Not used yet. */
     430    Msg.cbData.SetUInt32(cbData);
    428431    Msg.pvData.SetPtr(pvData, cbData);
    429     Msg.cbData.SetUInt32(0);
     432    Msg.cbChecksum.SetUInt32(0);
    430433    Msg.pvChecksum.SetPtr(NULL, 0);
    431     Msg.cbChecksum.SetUInt32(0);
    432434
    433435    int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
     
    444446
    445447/**
    446  * Helper function for writing the actual clipboard (meta) data to the host. Do not call directly.
     448 * Writes the actual meta data to the host, internal version.
    447449 *
    448450 * @returns IPRT status code.
     
    453455 * @param   pcbWritten          How much bytes were written on success. Optional.
    454456 */
    455 static int vbglR3ClipboardWriteMetaDataLoop(HGCMCLIENTID idClient, PVBOXCLIPBOARDDATAHDR pDataHdr,
    456                                             const void *pvMeta, uint32_t cbMeta, uint32_t *pcbWritten)
     457static int vbglR3ClipboardWriteMetaDataInternal(HGCMCLIENTID idClient, PVBOXCLIPBOARDDATAHDR pDataHdr,
     458                                                const void *pvMeta, uint32_t cbMeta, uint32_t *pcbWritten)
    457459{
    458460    AssertPtrReturn(pDataHdr, VERR_INVALID_POINTER);
     
    490492    }
    491493
    492     LogFlowFuncLeaveRC(rc);
    493     return rc;
    494 }
    495 
    496 /**
    497  * Writes the actual meta data to the host, internal version.
    498  *
    499  * @returns IPRT status code.
    500  * @param   idClient            The client id returned by VbglR3ClipboardConnect().
    501  * @param   pDataHdr            Pointer to data header to use.
    502  * @param   pvMeta              Meta data buffer to write.
    503  * @param   cbMeta              Size (in bytes) of meta data buffer.
    504  * @param   pcbWritten          How much bytes were written on success. Optional.
    505  */
    506 static int vbglR3ClipboardWriteMetaDataInternal(HGCMCLIENTID idClient, PVBOXCLIPBOARDDATAHDR pDataHdr,
    507                                                 const void *pvMeta, uint32_t cbMeta, uint32_t *pcbWritten)
    508 {
    509     LogFlowFuncEnter();
    510 
    511     int rc = vbglR3ClipboardWriteMetaDataLoop(idClient, pDataHdr, pvMeta, cbMeta, pcbWritten);
    512 
    513     LogFlowFuncLeaveRC(rc);
     494    LogFlowFunc(("cbWrittenTotal=%RU32, rc=%Rrc\n", cbWrittenTotal, rc));
    514495    return rc;
    515496}
     
    707688    VBGL_HGCM_HDR_INIT(&MsgHdr.hdr, idClient, VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_FILE_HDR, VBOX_SHARED_CLIPBOARD_CPARMS_WRITE_FILE_HDR);
    708689    MsgHdr.uContext.SetUInt32(0);                                                    /* Context ID; unused at the moment. */
     690    MsgHdr.cbName.SetUInt32(cbFileSz);
    709691    MsgHdr.pvName.SetPtr((void *)pszFilename, (uint32_t)(cbFileSz));
    710     MsgHdr.cbName.SetUInt32(cbFileSz);
    711692    MsgHdr.uFlags.SetUInt32(0);                                                      /* Flags; unused at the moment. */
    712693    MsgHdr.fMode.SetUInt32(fMode);                                                   /* File mode */
  • trunk/src/VBox/GuestHost/SharedClipboard/ClipboardDataObjectImpl-win.cpp

    r79107 r79267  
    391391#endif
    392392        {
     393            break;
     394#if 0
    393395            const bool fUnicode = lIndex == FormatIndex_FileDescriptorW;
    394396
     
    414416                }
    415417            }
     418#endif
    416419            break;
    417420        }
  • trunk/src/VBox/GuestHost/SharedClipboard/ClipboardMetaData.cpp

    r79174 r79267  
    2323#include <VBox/GuestHost/SharedClipboard-uri.h>
    2424
     25#include <iprt/path.h>
     26#include <iprt/uri.h>
     27
    2528/**
    2629 * Initializes a clipboard meta data struct.
     
    2831 * @returns VBox status code.
    2932 * @param   pMeta               Meta data struct to initialize.
    30  */
    31 int SharedClipboardMetaDataInit(PSHAREDCLIPBOARDMETADATA pMeta)
     33 * @param   enmFmt              Meta data format to use.
     34 */
     35int SharedClipboardMetaDataInit(PSHAREDCLIPBOARDMETADATA pMeta, SHAREDCLIPBOARDMETADATAFMT enmFmt)
    3236{
    3337    AssertPtrReturn(pMeta, VERR_INVALID_POINTER);
    3438
     39    pMeta->enmFmt = enmFmt;
    3540    pMeta->pvMeta = NULL;
    3641    pMeta->cbMeta = 0;
     
    4752void SharedClipboardMetaDataDestroy(PSHAREDCLIPBOARDMETADATA pMeta)
    4853{
    49     AssertPtrReturnVoid(pMeta);
    50 
    5154    if (!pMeta)
    5255        return;
     
    9497
    9598/**
     99 * Converts data to a specific meta data format.
     100 *
     101 * @returns VBox status code. VERR_NOT_SUPPORTED if the format is unknown.
     102 * @param   pvData              Pointer to data to convert.
     103 * @param   cbData              Size (in bytes) of data to convert.
     104 * @param   enmFmt              Meta data format to convert data to.
     105 * @param   ppvData             Where to store the converted data on success. Caller must free the data accordingly.
     106 * @param   pcbData             Where to store the size (in bytes) of the converted data. Optional.
     107 */
     108int SharedClipboardMetaDataConvertToFormat(const void *pvData, size_t cbData, SHAREDCLIPBOARDMETADATAFMT enmFmt,
     109                                           void **ppvData, uint32_t *pcbData)
     110{
     111    AssertPtrReturn(pvData,  VERR_INVALID_POINTER);
     112    AssertReturn   (cbData,  VERR_INVALID_PARAMETER);
     113    AssertPtrReturn(ppvData, VERR_INVALID_POINTER);
     114
     115    /* pcbData is optional. */
     116
     117    RT_NOREF(cbData);
     118
     119    int rc = VERR_INVALID_PARAMETER;
     120
     121    switch (enmFmt)
     122    {
     123        case SHAREDCLIPBOARDMETADATAFMT_URI_LIST:
     124        {
     125            char *pszTmp = RTStrDup((char *)pvData);
     126            if (!pszTmp)
     127            {
     128                rc = VERR_NO_MEMORY;
     129                break;
     130            }
     131
     132            RTPathChangeToUnixSlashes(pszTmp, true /* fForce */);
     133
     134            char  *pszURI;
     135            rc = RTUriFileCreateEx(pszTmp, RTPATH_STR_F_STYLE_UNIX, &pszURI, 0 /*cbUri*/, NULL /* pcchUri */);
     136            if (RT_SUCCESS(rc))
     137            {
     138                *ppvData = pszURI;
     139                if (pcbData)
     140                    *pcbData = (uint32_t)strlen(pszURI);
     141
     142                rc = VINF_SUCCESS;
     143            }
     144
     145            RTStrFree(pszTmp);
     146            break;
     147        }
     148
     149        default:
     150            rc = VERR_NOT_SUPPORTED;
     151            AssertFailed();
     152            break;
     153    }
     154
     155    LogFlowFuncLeaveRC(rc);
     156    return rc;
     157}
     158
     159/**
    96160 * Resizes the data buffer of a meta data struct.
    97161 * Note: At the moment only supports growing the data buffer.
     
    127191        AssertPtr(pMeta->pvMeta);
    128192        pvTmp = RTMemRealloc(pMeta->pvMeta, cbNewSize);
    129         RT_BZERO(pvTmp, cbNewSize);
    130193    }
    131194
  • trunk/src/VBox/GuestHost/SharedClipboard/ClipboardPath.cpp

    r78501 r79267  
    7474int SharedClipboardPathSanitize(char *pszPath, size_t cbPath)
    7575{
     76    RT_NOREF(pszPath, cbPath);
     77
    7678    /** @todo */
    77     RT_NOREF(pszPath, cbPath);
     79
    7880    return VINF_SUCCESS;
    7981}
  • trunk/src/VBox/GuestHost/SharedClipboard/ClipboardProvider-HostService.cpp

    r79174 r79267  
    2727#include <iprt/dir.h>
    2828#include <iprt/errcore.h>
    29 #include <iprt/semaphore.h>
    3029#include <iprt/file.h>
    3130#include <iprt/path.h>
     
    3635
    3736
    38 SharedClipboardProviderHostService::Event::Event(uint32_t uMsg)
    39     : mMsg(uMsg)
    40     , mpvData(NULL)
    41     , mcbData(0)
    42 {
    43     int rc2 = RTSemEventCreate(&mEvent);
    44     AssertRC(rc2);
    45 }
    46 
    47 SharedClipboardProviderHostService::Event::~Event()
    48 {
    49     if (mpvData)
     37
     38SharedClipboardProviderHostService::SharedClipboardProviderHostService(SharedClipboardArea *pArea)
     39    : m_pArea(pArea)
     40{
     41    LogFlowFuncEnter();
     42
     43    Reset();
     44
     45    m_pArea->AddRef();
     46}
     47
     48SharedClipboardProviderHostService::~SharedClipboardProviderHostService(void)
     49{
     50    m_pArea->Release();
     51}
     52
     53int SharedClipboardProviderHostService::ReadDataHdr(PVBOXCLIPBOARDDATAHDR *ppDataHdr)
     54{
     55    RT_NOREF(ppDataHdr);
     56    /*return eventWait(VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_DATA_HDR, m_Callbacks.pfnReadDataHdr, m_uTimeoutMs,
     57                     (void **)ppDataHdr);*/
     58    return 0;
     59}
     60
     61int SharedClipboardProviderHostService::WriteDataHdr(const PVBOXCLIPBOARDDATAHDR pDataHdr)
     62{
     63    RT_NOREF(pDataHdr);
     64
     65    LogFlowFuncEnter();
     66
     67    return VERR_NOT_IMPLEMENTED;
     68}
     69
     70int SharedClipboardProviderHostService::ReadDataChunk(const PVBOXCLIPBOARDDATAHDR pDataHdr, void *pvChunk, uint32_t cbChunk,
     71                                                      uint32_t fFlags /* = 0 */, uint32_t *pcbRead /* = NULL*/)
     72{
     73    RT_NOREF(pDataHdr, pvChunk, cbChunk, fFlags, pcbRead);
     74
     75    /*return eventWait(VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_DATA_CHUNK, m_Callbacks.pfnReadDataChunk, m_uTimeoutMs,
     76                     (void **)ppDataChunk);*/
     77    return 0;
     78}
     79
     80int SharedClipboardProviderHostService::WriteDataChunk(const PVBOXCLIPBOARDDATAHDR pDataHdr, const void *pvChunk, uint32_t cbChunk,
     81                                                       uint32_t fFlags /* = 0 */, uint32_t *pcbWritten /* = NULL */)
     82{
     83    RT_NOREF(pDataHdr, pvChunk, cbChunk, fFlags, pcbWritten);
     84    return VERR_NOT_IMPLEMENTED;
     85}
     86
     87int SharedClipboardProviderHostService::ReadDirectory(PVBOXCLIPBOARDDIRDATA *ppDirData)
     88{
     89    //return eventWait(VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_DIR, NULL, m_uTimeoutMs, (void **)ppDirData);
     90    RT_NOREF(ppDirData);
     91    return 0;
     92}
     93
     94int SharedClipboardProviderHostService::WriteDirectory(const PVBOXCLIPBOARDDIRDATA pDirData)
     95{
     96    RT_NOREF(pDirData);
     97
     98    LogFlowFuncEnter();
     99
     100    int rc = VERR_NOT_IMPLEMENTED;
     101
     102    LogFlowFuncLeaveRC(rc);
     103    return rc;
     104}
     105
     106int SharedClipboardProviderHostService::ReadFileHdr(PVBOXCLIPBOARDFILEHDR *ppFileHdr)
     107{
     108    RT_NOREF(ppFileHdr);
     109    //return eventWait(VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_FILE_HDR, NULL, m_uTimeoutMs, (void **)ppFileHdr);
     110    return 0;
     111}
     112
     113int SharedClipboardProviderHostService::WriteFileHdr(const PVBOXCLIPBOARDFILEHDR pFileHdr)
     114{
     115    RT_NOREF(pFileHdr);
     116
     117    LogFlowFuncEnter();
     118
     119    int rc = VERR_NOT_IMPLEMENTED;
     120
     121    LogFlowFuncLeaveRC(rc);
     122    return rc;
     123}
     124
     125int SharedClipboardProviderHostService::ReadFileData(void *pvData, uint32_t cbData, uint32_t fFlags /* = 0 */,
     126                                                     uint32_t *pcbRead /* = NULL */)
     127{
     128    RT_NOREF(pvData, cbData, fFlags, pcbRead);
     129    //return eventWait(VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_FILE_DATA, NULL, m_uTimeoutMs, (void **)ppFileData);
     130    return 0;
     131}
     132
     133int SharedClipboardProviderHostService::WriteFileData(void *pvData, uint32_t cbData, uint32_t fFlags /* = 0 */,
     134                                                      uint32_t *pcbWritten /* = NULL */)
     135{
     136    RT_NOREF(pvData, cbData, fFlags, pcbWritten);
     137
     138    LogFlowFuncEnter();
     139
     140    int rc = VERR_NOT_IMPLEMENTED;
     141
     142    LogFlowFuncLeaveRC(rc);
     143    return rc;
     144}
     145void SharedClipboardProviderHostService::Reset(void)
     146{
     147    LogFlowFuncEnter();
     148
     149    eventUnregisterAll();
     150
     151    uint32_t aMsgIDs[] = { VBOX_SHARED_CLIPBOARD_GUEST_FN_READ_DATA_HDR,
     152                           VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_DATA_HDR,
     153                           VBOX_SHARED_CLIPBOARD_GUEST_FN_READ_DATA_CHUNK,
     154                           VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_DATA_CHUNK,
     155                           VBOX_SHARED_CLIPBOARD_GUEST_FN_READ_DIR,
     156                           VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_DIR,
     157                           VBOX_SHARED_CLIPBOARD_GUEST_FN_READ_FILE_HDR,
     158                           VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_FILE_HDR,
     159                           VBOX_SHARED_CLIPBOARD_GUEST_FN_READ_FILE_DATA,
     160                           VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_FILE_DATA };
     161
     162    for (unsigned i = 0; i < RT_ELEMENTS(aMsgIDs); i++)
    50163    {
    51         Assert(mcbData);
    52 
    53         RTMemFree(mpvData);
    54         mpvData = NULL;
     164        int rc2 = eventRegister(aMsgIDs[i]);
     165        AssertRC(rc2);
    55166    }
    56 
    57     int rc2 = RTSemEventDestroy(mEvent);
    58     AssertRC(rc2);
    59 }
    60 
    61 /**
    62  * Sets user data associated to an event.
    63  *
    64  * @returns VBox status code.
    65  * @param   pvData              Pointer to user data to set.
    66  * @param   cbData              Size (in bytes) of user data to set.
    67  */
    68 int SharedClipboardProviderHostService::Event::SetData(const void *pvData, uint32_t cbData)
    69 {
    70     Assert(mpvData == NULL);
    71     Assert(mcbData == 0);
    72 
    73     if (!cbData)
    74         return VINF_SUCCESS;
    75 
    76     mpvData = RTMemDup(pvData, cbData);
    77     if (!mpvData)
    78         return VERR_NO_MEMORY;
    79 
    80     mcbData = cbData;
    81 
    82     return VINF_SUCCESS;
    83 }
    84 
    85 /**
    86  * Waits for an event to get signalled.
    87  * Will return VERR_NOT_FOUND if no event has been found.
    88  *
    89  * @returns VBox status code.
    90  * @param   uTimeoutMs          Timeout (in ms) to wait.
    91  */
    92 int SharedClipboardProviderHostService::Event::Wait(RTMSINTERVAL uTimeoutMs)
    93 {
    94     LogFlowFuncEnter();
    95 
    96     int rc = RTSemEventWait(mEvent, uTimeoutMs);
    97 
    98     LogFlowFuncLeaveRC(rc);
    99     return rc;
    100 }
    101 
    102 /**
    103  * Returns the event's (raw) data (mutable).
    104  *
    105  * @returns Pointer to the event's raw data.
    106  */
    107 void *SharedClipboardProviderHostService::Event::DataRaw()
    108 {
    109     return mpvData;
    110 }
    111 
    112 /**
    113  * Returns the event's data size (in bytes).
    114  *
    115  * @returns Data size (in bytes).
    116  */
    117 uint32_t SharedClipboardProviderHostService::Event::DataSize()
    118 {
    119     return mcbData;
    120 }
    121 
    122 SharedClipboardProviderHostService::SharedClipboardProviderHostService(void)
    123     : m_uTimeoutMs(30 * 1000 /* 30s timeout by default */)
    124 {
    125     LogFlowFuncEnter();
    126 }
    127 
    128 SharedClipboardProviderHostService::~SharedClipboardProviderHostService(void)
    129 {
    130     Reset();
    131 }
    132 
    133 int SharedClipboardProviderHostService::ReadDataHdr(PVBOXCLIPBOARDDATAHDR pDataHdr)
    134 {
    135     int rc;
    136 
    137     if (m_Callbacks.pfnReadDataHdr)
    138     {
    139         SHAREDCLIPBOARDPROVIDERCALLBACKDATA data = { this, m_Callbacks.pvUser };
    140         rc = m_Callbacks.pfnReadDataHdr(&data);
    141     }
    142     else
    143         rc = VERR_NOT_SUPPORTED;
    144 
    145     if (RT_SUCCESS(rc))
    146     {
    147         Event *pEvent = eventGet(VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_DATA_HDR);
    148         if (pEvent)
    149         {
    150             rc = pEvent->Wait(m_uTimeoutMs);
    151             if (RT_SUCCESS(rc))
    152                 memcpy(pDataHdr, pEvent->DataRaw(), pEvent->DataSize());
    153         }
    154         else
    155             rc = VERR_NOT_FOUND;
    156     }
    157 
    158     LogFlowFuncLeaveRC(rc);
    159     return rc;
    160 }
    161 
    162 int SharedClipboardProviderHostService::WriteDataHdr(const PVBOXCLIPBOARDDATAHDR pDataHdr)
    163 {
    164     RT_NOREF(pDataHdr);
    165     return VERR_NOT_IMPLEMENTED;
    166 }
    167 
    168 int SharedClipboardProviderHostService::ReaaDataChunk(const PVBOXCLIPBOARDDATAHDR pDataHdr, void *pvChunk, uint32_t cbChunk,
    169                                                       uint32_t *pcbRead, uint32_t fFlags /* = 0 */)
    170 {
    171     RT_NOREF(pDataHdr, pvChunk, cbChunk, pcbRead, fFlags);
    172     return VERR_NOT_IMPLEMENTED;
    173 }
    174 
    175 int SharedClipboardProviderHostService::WriteDataChunk(const PVBOXCLIPBOARDDATAHDR pDataHdr, const void *pvMeta, uint32_t cbMeta,
    176                                                        uint32_t *pcbWritten, uint32_t fFlags /* = 0 */)
    177 {
    178     RT_NOREF(pDataHdr, pvMeta, cbMeta, pcbWritten, fFlags);
    179     return VERR_NOT_IMPLEMENTED;
    180 }
    181 
    182 int SharedClipboardProviderHostService::ReadDirectory(PVBOXCLIPBOARDDIRDATA pDirData)
    183 {
    184     RT_NOREF(pDirData);
    185 
    186     LogFlowFuncEnter();
    187 
    188     int rc = VERR_NOT_IMPLEMENTED;
    189 
    190     LogFlowFuncLeaveRC(rc);
    191     return rc;
    192 }
    193 
    194 int SharedClipboardProviderHostService::WriteDirectory(const PVBOXCLIPBOARDDIRDATA pDirData)
    195 {
    196     RT_NOREF(pDirData);
    197 
    198     LogFlowFuncEnter();
    199 
    200     int rc = VERR_NOT_IMPLEMENTED;
    201 
    202     LogFlowFuncLeaveRC(rc);
    203     return rc;
    204 }
    205 
    206 int SharedClipboardProviderHostService::ReadFileHdr(PVBOXCLIPBOARDFILEHDR pFileHdr)
    207 {
    208     RT_NOREF(pFileHdr);
    209 
    210     LogFlowFuncEnter();
    211 
    212     int rc = VERR_NOT_IMPLEMENTED;
    213 
    214     LogFlowFuncLeaveRC(rc);
    215     return rc;
    216 }
    217 
    218 int SharedClipboardProviderHostService::WriteFileHdr(const PVBOXCLIPBOARDFILEHDR pFileHdr)
    219 {
    220     RT_NOREF(pFileHdr);
    221 
    222     LogFlowFuncEnter();
    223 
    224     int rc = VERR_NOT_IMPLEMENTED;
    225 
    226     LogFlowFuncLeaveRC(rc);
    227     return rc;
    228 }
    229 
    230 int SharedClipboardProviderHostService::ReadFileData(PVBOXCLIPBOARDFILEDATA pFileData, uint32_t *pcbRead)
    231 {
    232     RT_NOREF(pFileData, pcbRead);
    233 
    234     LogFlowFuncEnter();
    235 
    236     int rc = VERR_NOT_IMPLEMENTED;
    237 
    238     LogFlowFuncLeaveRC(rc);
    239     return rc;
    240 }
    241 
    242 int SharedClipboardProviderHostService::WriteFileData(const PVBOXCLIPBOARDFILEDATA pFileData, uint32_t *pcbWritten)
    243 {
    244     RT_NOREF(pFileData, pcbWritten);
    245 
    246     LogFlowFuncEnter();
    247 
    248     int rc = VERR_NOT_IMPLEMENTED;
    249 
    250     LogFlowFuncLeaveRC(rc);
    251     return rc;
    252 }
    253 
    254 void SharedClipboardProviderHostService::Reset(void)
    255 {
    256     LogFlowFuncEnter();
    257 
    258     EventMap::const_iterator itEvent = m_mapEvents.begin();
    259     while (itEvent != m_mapEvents.end())
    260     {
    261         delete itEvent->second;
    262         m_mapEvents.erase(itEvent);
    263 
    264         itEvent = m_mapEvents.begin();
    265     }
    266 
    267     int rc2 = eventRegister(VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_DATA_HDR);
    268     AssertRC(rc2);
    269 }
    270 
    271 int SharedClipboardProviderHostService::OnRead(PSHAREDCLIPBOARDPROVIDERREADPARMS pParms)
     167}
     168
     169int SharedClipboardProviderHostService::OnWrite(PSHAREDCLIPBOARDPROVIDERWRITEPARMS pParms)
    272170{
    273171    RT_NOREF(pParms);
     
    275173    LogFlowFuncEnter();
    276174
    277     int rc = VERR_NOT_IMPLEMENTED;
    278 
    279     LogFlowFuncLeaveRC(rc);
    280     return rc;
    281 }
    282 
    283 int SharedClipboardProviderHostService::OnWrite(PSHAREDCLIPBOARDPROVIDERWRITEPARMS pParms)
    284 {
    285     LogFlowFuncEnter();
    286 
    287     int rc = VINF_SUCCESS;
    288 
     175    int rc = VERR_NOT_SUPPORTED;
     176
     177#if 0
    289178    switch (pParms->u.HostService.uMsg)
    290179    {
     
    292181        {
    293182            VBOXCLIPBOARDDATAHDR dataHdr;
    294             rc = VBoxSvcClipboardURIReadDataHdr(pParms->u.HostService.cParms, pParms->u.HostService.paParms,
    295                                                 &dataHdr);
    296             if (RT_SUCCESS(rc))
    297             {
    298                 Event *pEvent = eventGet(pParms->u.HostService.uMsg);
    299                 if (pEvent)
    300                     rc = pEvent->SetData(&dataHdr, sizeof(dataHdr));
    301             }
    302             break;
    303         }
     183            rc = VBoxSvcClipboardURIReadDataHdr(pParms->u.HostService.cParms, pParms->u.HostService.paParms, &dataHdr);
     184            if (RT_SUCCESS(rc))
     185            {
     186                /** @todo Handle compression type. */
     187                /** @todo Handle checksum type. */
     188        #if 0
     189                Event *pEvent = eventGet(pParms->u.HostService.uMsg);
     190                if (pEvent)
     191                    rc = pEvent->SetData(SharedClipboardURIDataHdrDup(&dataHdr),
     192                                         sizeof(dataHdr) + dataHdr.cbMetaFmt + dataHdr.cbChecksum);
     193        #endif
     194            }
     195            break;
     196        }
     197
    304198        case VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_DATA_CHUNK:
    305199        {
    306             break;
    307         }
     200            VBOXCLIPBOARDDATACHUNK dataChunk;
     201            rc = VBoxSvcClipboardURIReadDataChunk(pParms->u.HostService.cParms, pParms->u.HostService.paParms, &dataChunk);
     202            if (RT_SUCCESS(rc))
     203            {
     204                Event *pEvent = eventGet(pParms->u.HostService.uMsg);
     205                if (pEvent)
     206                    rc = pEvent->SetData(SharedClipboardURIDataChunkDup(&dataChunk),
     207                                         sizeof(dataChunk) + dataChunk.cbData + dataChunk.cbChecksum);
     208            }
     209            break;
     210        }
     211
    308212        case VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_DIR:
    309             RT_FALL_THROUGH();
     213        {
     214            VBOXCLIPBOARDDIRDATA dirData;
     215            rc = VBoxSvcClipboardURIReadDir(pParms->u.HostService.cParms, pParms->u.HostService.paParms, &dirData);
     216            if (RT_SUCCESS(rc))
     217            {
     218                Event *pEvent = eventGet(pParms->u.HostService.uMsg);
     219                if (pEvent)
     220                    rc = pEvent->SetData(SharedClipboardURIDirDataDup(&dirData),
     221                                         sizeof(dirData) + dirData.cbPath);
     222            }
     223            break;
     224        }
     225
    310226        case VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_FILE_HDR:
    311             RT_FALL_THROUGH();
     227        {
     228            VBOXCLIPBOARDFILEHDR fileHdr;
     229            rc = VBoxSvcClipboardURIReadFileHdr(pParms->u.HostService.cParms, pParms->u.HostService.paParms, &fileHdr);
     230            if (RT_SUCCESS(rc))
     231            {
     232                Event *pEvent = eventGet(pParms->u.HostService.uMsg);
     233                if (pEvent)
     234                    rc = pEvent->SetData(SharedClipboardURIFileHdrDup(&fileHdr),
     235                                         sizeof(fileHdr) + fileHdr.cbFilePath);
     236            }
     237            break;
     238        }
     239
    312240        case VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_FILE_DATA:
    313             RT_FALL_THROUGH();
     241        {
     242            VBOXCLIPBOARDFILEDATA fileData;
     243            rc = VBoxSvcClipboardURIReadFileData(pParms->u.HostService.cParms, pParms->u.HostService.paParms, &fileData);
     244            if (RT_SUCCESS(rc))
     245            {
     246                Event *pEvent = eventGet(pParms->u.HostService.uMsg);
     247                if (pEvent)
     248                    rc = pEvent->SetData(SharedClipboardURIFileDataDup(&fileData),
     249                                         sizeof(fileData) + fileData.cbData + fileData.cbChecksum);
     250            }
     251            break;
     252        }
     253
    314254        case VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_CANCEL:
    315             RT_FALL_THROUGH();
     255        {
     256            AssertFailedStmt(rc = VERR_NOT_IMPLEMENTED);
     257            break;
     258        }
     259
    316260        case VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_ERROR:
    317261        {
    318 
     262            AssertFailedStmt(rc = VERR_NOT_IMPLEMENTED);
     263            break;
    319264        }
    320265
    321266        default:
    322             rc = VERR_NOT_IMPLEMENTED;
    323267            break;
    324268    }
     
    330274            rc = VINF_SUCCESS;
    331275    }
    332 
    333     LogFlowFuncLeaveRC(rc);
    334     return rc;
    335 }
    336 
    337 /**
    338  * Registers a new event.
    339  * Will fail if an event with the same message ID already exists.
    340  *
    341  * @returns VBox status code.
    342  * @param   uMsg                Message ID to register event for.
    343  */
    344 int SharedClipboardProviderHostService::eventRegister(uint32_t uMsg)
    345 {
    346     LogFlowFuncEnter();
    347 
    348     int rc;
    349 
    350     EventMap::const_iterator itEvent = m_mapEvents.find(uMsg);
    351     if (itEvent == m_mapEvents.end())
    352     {
    353         SharedClipboardProviderHostService::Event *pEvent = new SharedClipboardProviderHostService::Event(uMsg);
    354         if (pEvent) /** @todo Can this throw? */
    355         {
    356             rc = VINF_SUCCESS;
    357         }
    358         else
    359             rc = VERR_NO_MEMORY;
    360     }
    361     else
    362         rc = VERR_ALREADY_EXISTS;
    363 
    364     LogFlowFuncLeaveRC(rc);
    365     return rc;
    366 }
    367 
    368 /**
    369  * Unregisters an existing event.
    370  * Will return VERR_NOT_FOUND if no event has been found.
    371  *
    372  * @returns VBox status code.
    373  * @param   uMsg                Message ID to unregister event for.
    374  */
    375 int SharedClipboardProviderHostService::eventUnregister(uint32_t uMsg)
    376 {
    377     LogFlowFuncEnter();
    378 
    379     int rc;
    380 
    381     EventMap::const_iterator itEvent = m_mapEvents.find(uMsg);
    382     if (itEvent != m_mapEvents.end())
    383     {
    384         delete itEvent->second;
    385         m_mapEvents.erase(itEvent);
    386 
    387         rc = VINF_SUCCESS;
    388     }
    389     else
    390         rc = VERR_NOT_FOUND;
    391 
    392     LogFlowFuncLeaveRC(rc);
    393     return rc;
    394 }
    395 
    396 /**
    397  * Signals an event.
    398  * Will return VERR_NOT_FOUND if no event has been found.
    399  *
    400  * @returns VBox status code.
    401  * @param   uMsg                Message ID of event to signal.
    402  */
    403 int SharedClipboardProviderHostService::eventSignal(uint32_t uMsg)
    404 {
    405     LogFlowFuncEnter();
    406 
    407     int rc;
    408 
    409     EventMap::const_iterator itEvent = m_mapEvents.find(uMsg);
    410     if (itEvent != m_mapEvents.end())
    411     {
    412         rc = RTSemEventSignal(itEvent->second->mEvent);
    413     }
    414     else
    415         rc = VERR_NOT_FOUND;
    416 
    417     LogFlowFuncLeaveRC(rc);
    418     return rc;
    419 }
    420 
    421 /**
    422  * Returns the event for a specific message ID.
    423  *
    424  * @returns Pointer to event if found, or NULL if no event has been found
    425  * @param   uMsg                Messagae ID to return event for.
    426  */
    427 SharedClipboardProviderHostService::Event *SharedClipboardProviderHostService::eventGet(uint32_t uMsg)
    428 {
    429     LogFlowFuncEnter();
    430 
    431     EventMap::const_iterator itEvent = m_mapEvents.find(uMsg);
    432     if (itEvent != m_mapEvents.end())
    433         return itEvent->second;
    434 
    435     return NULL;
    436 }
    437 
     276#endif
     277
     278    LogFlowFuncLeaveRC(rc);
     279    return rc;
     280}
     281
  • trunk/src/VBox/GuestHost/SharedClipboard/ClipboardProvider-VbglR3.cpp

    r79120 r79267  
    4545}
    4646
    47 int SharedClipboardProviderVbglR3::ReadDataHdr(PVBOXCLIPBOARDDATAHDR pDataHdr)
    48 {
    49     LogFlowFuncEnter();
    50 
    51     int rc = VbglR3ClipboardReadDataHdr(m_uClientID, pDataHdr);
     47int SharedClipboardProviderVbglR3::ReadDataHdr(PVBOXCLIPBOARDDATAHDR *ppDataHdr)
     48{
     49    LogFlowFuncEnter();
     50
     51    VBOXCLIPBOARDDATAHDR dataHdr;
     52    int rc = VbglR3ClipboardReadDataHdr(m_uClientID, &dataHdr);
     53    if (RT_SUCCESS(rc))
     54    {
     55        *ppDataHdr = SharedClipboardURIDataHdrDup(&dataHdr);
     56    }
    5257
    5358    LogFlowFuncLeaveRC(rc);
     
    6570}
    6671
    67 int SharedClipboardProviderVbglR3::ReadDataChunkk(const PVBOXCLIPBOARDDATAHDR pDataHdr, void *pvChunk, uint32_t cbChunk,
    68                                                   uint32_t *pcbRead, uint32_t fFlags /* = 0 */)
     72int SharedClipboardProviderVbglR3::ReadDataChunk(const PVBOXCLIPBOARDDATAHDR pDataHdr, void *pvChunk, uint32_t cbChunk,
     73                                                 uint32_t fFlags /* = 0 */, uint32_t *pcbRead /* = NULL */)
    6974{
    7075    RT_NOREF(fFlags);
     
    100105
    101106int SharedClipboardProviderVbglR3::WriteDataChunk(const PVBOXCLIPBOARDDATAHDR pDataHdr, const void *pvChunk, uint32_t cbChunk,
    102                                                   uint32_t *pcbWritten, uint32_t fFlags /* = 0 */)
     107                                                  uint32_t fFlags /* = 0 */, uint32_t *pcbWritten /* = NULL */)
    103108{
    104109    RT_NOREF(fFlags);
     
    129134    }
    130135
    131     LogFlowFuncLeaveRC(rc);
    132     return rc;
    133 }
    134 
    135 int SharedClipboardProviderVbglR3::ReadDirectory(PVBOXCLIPBOARDDIRDATA pDirData)
    136 {
    137     LogFlowFuncEnter();
    138 
    139     int rc = VbglR3ClipboardReadDir(m_uClientID, pDirData->pszPath, pDirData->cbPath, &pDirData->cbPath, &pDirData->fMode);
     136    LogFlowFunc(("cbWrittenTotal=%RU32, rc=%Rrc\n", cbWrittenTotal, rc));
     137    return rc;
     138}
     139
     140int SharedClipboardProviderVbglR3::ReadDirectory(PVBOXCLIPBOARDDIRDATA *ppDirData)
     141{
     142    LogFlowFuncEnter();
     143
     144    VBOXCLIPBOARDDIRDATA dirData;
     145    int rc = VbglR3ClipboardReadDir(m_uClientID, dirData.pszPath, dirData.cbPath, &dirData.cbPath, &dirData.fMode);
     146    if (RT_SUCCESS(rc))
     147    {
     148        *ppDirData = SharedClipboardURIDirDataDup(&dirData);
     149    }
    140150
    141151    LogFlowFuncLeaveRC(rc);
     
    153163}
    154164
    155 int SharedClipboardProviderVbglR3::ReadFileHdr(PVBOXCLIPBOARDFILEHDR pFileHdr)
    156 {
    157     LogFlowFuncEnter();
    158 
    159     int rc = VbglR3ClipboardReadFileHdr(m_uClientID, pFileHdr->pszFilePath, pFileHdr->cbFilePath,
    160                                         &pFileHdr->fFlags, &pFileHdr->fMode, &pFileHdr->cbSize);
     165int SharedClipboardProviderVbglR3::ReadFileHdr(PVBOXCLIPBOARDFILEHDR *ppFileHdr)
     166{
     167    LogFlowFuncEnter();
     168
     169    VBOXCLIPBOARDFILEHDR fileHdr;
     170    int rc = VbglR3ClipboardReadFileHdr(m_uClientID, fileHdr.pszFilePath, fileHdr.cbFilePath,
     171                                        &fileHdr.fFlags, &fileHdr.fMode, &fileHdr.cbSize);
     172    if (RT_SUCCESS(rc))
     173    {
     174        *ppFileHdr = SharedClipboardURIFileHdrDup(&fileHdr);
     175    }
     176
    161177    LogFlowFuncLeaveRC(rc);
    162178    return rc;
     
    173189}
    174190
    175 int SharedClipboardProviderVbglR3::ReadFileData(PVBOXCLIPBOARDFILEDATA pFileData, uint32_t *pcbRead)
    176 {
     191int SharedClipboardProviderVbglR3::ReadFileData(void *pvData, uint32_t cbData, uint32_t fFlags /* = 0 */,
     192                                                uint32_t *pcbRead /* = NULL */)
     193{
     194    RT_NOREF(fFlags);
     195
    177196    AssertPtrReturn(pcbRead, VERR_INVALID_POINTER);
    178197
    179198    LogFlowFuncEnter();
    180199
    181     int rc = VbglR3ClipboardReadFileData(m_uClientID, pFileData->pvData, pFileData->cbData, pcbRead);
    182 
    183     LogFlowFuncLeaveRC(rc);
    184     return rc;
    185 }
    186 
    187 int SharedClipboardProviderVbglR3::WriteFileData(const PVBOXCLIPBOARDFILEDATA pFileData, uint32_t *pcbWritten)
    188 {
     200    int rc = VbglR3ClipboardReadFileData(m_uClientID, pvData, cbData, pcbRead);
     201
     202    LogFlowFuncLeaveRC(rc);
     203    return rc;
     204}
     205
     206int SharedClipboardProviderVbglR3::WriteFileData(void *pvData, uint32_t cbData, uint32_t fFlags /* = 0 */,
     207                                                 uint32_t *pcbWritten /* = NULL */)
     208{
     209    RT_NOREF(fFlags);
     210
    189211    AssertPtrReturn(pcbWritten, VERR_INVALID_POINTER);
    190212
    191213    LogFlowFuncEnter();
    192214
    193     int rc = VbglR3ClipboardWriteFileData(m_uClientID, pFileData->pvData, pFileData->cbData, pcbWritten);
     215    int rc = VbglR3ClipboardWriteFileData(m_uClientID, pvData, cbData, pcbWritten);
    194216
    195217    LogFlowFuncLeaveRC(rc);
  • trunk/src/VBox/GuestHost/SharedClipboard/ClipboardProvider.cpp

    r79174 r79267  
    2929#include <iprt/file.h>
    3030#include <iprt/path.h>
     31#include <iprt/semaphore.h>
    3132#include <iprt/string.h>
    3233
    33 
    3434#include <VBox/log.h>
    3535
    3636
     37SharedClipboardProvider::Event::Event(uint32_t uMsg)
     38    : mMsg(uMsg)
     39    , mpvData(NULL)
     40    , mcbData(0)
     41{
     42    int rc2 = RTSemEventCreate(&mEvent);
     43    AssertRC(rc2);
     44}
     45
     46SharedClipboardProvider::Event::~Event()
     47{
     48    Reset();
     49
     50    int rc2 = RTSemEventDestroy(mEvent);
     51    AssertRC(rc2);
     52}
     53
     54/**
     55 * Resets an event by clearing the (allocated) data.
     56 */
     57void SharedClipboardProvider::Event::Reset(void)
     58{
     59    LogFlowFuncEnter();
     60
     61    if (mpvData)
     62    {
     63        Assert(mcbData);
     64
     65        RTMemFree(mpvData);
     66        mpvData = NULL;
     67    }
     68
     69    mcbData = 0;
     70}
     71
     72/**
     73 * Sets user data associated to an event.
     74 *
     75 * @returns VBox status code.
     76 * @param   pvData              Pointer to user data to set.
     77 * @param   cbData              Size (in bytes) of user data to set.
     78 */
     79int SharedClipboardProvider::Event::SetData(const void *pvData, uint32_t cbData)
     80{
     81    Reset();
     82
     83    if (!cbData)
     84        return VINF_SUCCESS;
     85
     86    mpvData = RTMemDup(pvData, cbData);
     87    if (!mpvData)
     88        return VERR_NO_MEMORY;
     89
     90    mcbData = cbData;
     91
     92    return VINF_SUCCESS;
     93}
     94
     95/**
     96 * Waits for an event to get signalled.
     97 * Will return VERR_NOT_FOUND if no event has been found.
     98 *
     99 * @returns VBox status code.
     100 * @param   uTimeoutMs          Timeout (in ms) to wait.
     101 */
     102int SharedClipboardProvider::Event::Wait(RTMSINTERVAL uTimeoutMs)
     103{
     104    LogFlowFunc(("mMsg=%RU32, uTimeoutMs=%RU32\n", mMsg, uTimeoutMs));
     105
     106    int rc = RTSemEventWait(mEvent, uTimeoutMs);
     107
     108    LogFlowFuncLeaveRC(rc);
     109    return rc;
     110}
     111
     112/**
     113 * Lets the caller adopt (transfer ownership) the returned event data.
     114 * The caller is responsible of free'ing the data accordingly.
     115 *
     116 * @returns Pointer to the adopted event's raw data.
     117 */
     118void *SharedClipboardProvider::Event::DataAdopt(void)
     119{
     120    void *pvData = mpvData;
     121
     122    mpvData = NULL;
     123    mcbData = 0;
     124
     125    return pvData;
     126}
     127
     128/**
     129 * Returns the event's (raw) data (mutable).
     130 *
     131 * @returns Pointer to the event's raw data.
     132 */
     133void *SharedClipboardProvider::Event::DataRaw(void)
     134{
     135    return mpvData;
     136}
     137
     138/**
     139 * Returns the event's data size (in bytes).
     140 *
     141 * @returns Data size (in bytes).
     142 */
     143uint32_t SharedClipboardProvider::Event::DataSize(void)
     144{
     145    return mcbData;
     146}
    37147
    38148SharedClipboardProvider::SharedClipboardProvider(void)
    39149    : m_cRefs(0)
     150    , m_uTimeoutMs(30 * 1000 /* 30s timeout by default */)
    40151{
    41152    LogFlowFuncEnter();
     
    45156{
    46157    LogFlowFuncEnter();
     158
    47159    Assert(m_cRefs == 0);
     160
     161    eventUnregisterAll();
    48162}
    49163
     
    71185#ifdef VBOX_WITH_SHARED_CLIPBOARD_HOST
    72186        case SHAREDCLIPBOARDPROVIDERSOURCE_HOSTSERVICE:
    73             pProvider = new SharedClipboardProviderHostService();
     187            pProvider = new SharedClipboardProviderHostService(pCtx->u.HostService.pArea);
    74188            break;
    75189#endif
     
    132246 */
    133247
    134 int SharedClipboardProvider::ReadDataHdr(PVBOXCLIPBOARDDATAHDR pDataHdr)
     248int SharedClipboardProvider::ReadDataHdr(PVBOXCLIPBOARDDATAHDR *ppDataHdr)
     249{
     250    RT_NOREF(ppDataHdr);
     251    return VERR_NOT_IMPLEMENTED;
     252}
     253
     254int SharedClipboardProvider::WriteDataHdr(const PVBOXCLIPBOARDDATAHDR pDataHdr)
    135255{
    136256    RT_NOREF(pDataHdr);
     
    138258}
    139259
    140 int SharedClipboardProvider::WriteDataHdr(const PVBOXCLIPBOARDDATAHDR pDataHdr)
    141 {
    142     RT_NOREF(pDataHdr);
     260int SharedClipboardProvider::ReadDataChunk(const PVBOXCLIPBOARDDATAHDR pDataHdr, void *pvChunk, uint32_t cbChunk,
     261                                           uint32_t fFlags /* = 0 */, uint32_t *pcbRead /* = NULL*/)
     262{
     263    RT_NOREF(pDataHdr, pvChunk, cbChunk, fFlags, pcbRead);
    143264    return VERR_NOT_IMPLEMENTED;
    144265}
    145266
    146 int SharedClipboardProvider::ReadDataChunk(const PVBOXCLIPBOARDDATAHDR pDataHdr, void *pvChunk, uint32_t cbChunk,
    147                                            uint32_t *pcbRead, uint32_t fFlags /* = 0 */)
    148 {
    149     RT_NOREF(pDataHdr, pvChunk, cbChunk, pcbRead, fFlags);
     267int SharedClipboardProvider::WriteDataChunk(const PVBOXCLIPBOARDDATAHDR pDataHdr, const void *pvChunk, uint32_t cbChunk,
     268                                            uint32_t fFlags /* = 0 */, uint32_t *pcbWritten /* = NULL */)
     269{
     270    RT_NOREF(pDataHdr, pvChunk, cbChunk, fFlags, pcbWritten);
    150271    return VERR_NOT_IMPLEMENTED;
    151272}
    152273
    153 int SharedClipboardProvider::WriteDataChunk(const PVBOXCLIPBOARDDATAHDR pDataHdr, const void *pvChunk, uint32_t cbChunk,
    154                                             uint32_t *pcbWritten, uint32_t fFlags /* = 0 */)
    155 {
    156     RT_NOREF(pDataHdr, pvChunk, cbChunk, pcbWritten, fFlags);
    157     return VERR_NOT_IMPLEMENTED;
    158 }
    159 
    160 int SharedClipboardProvider::ReadDirectory(PVBOXCLIPBOARDDIRDATA pDirData)
     274int SharedClipboardProvider::ReadDirectory(PVBOXCLIPBOARDDIRDATA *ppDirData)
     275{
     276    RT_NOREF(ppDirData);
     277
     278    LogFlowFuncEnter();
     279
     280    int rc = VERR_NOT_IMPLEMENTED;
     281
     282    LogFlowFuncLeaveRC(rc);
     283    return rc;
     284}
     285
     286int SharedClipboardProvider::WriteDirectory(const PVBOXCLIPBOARDDIRDATA pDirData)
    161287{
    162288    RT_NOREF(pDirData);
     
    170296}
    171297
    172 int SharedClipboardProvider::WriteDirectory(const PVBOXCLIPBOARDDIRDATA pDirData)
    173 {
    174     RT_NOREF(pDirData);
    175 
    176     LogFlowFuncEnter();
    177 
    178     int rc = VERR_NOT_IMPLEMENTED;
    179 
    180     LogFlowFuncLeaveRC(rc);
    181     return rc;
    182 }
    183 
    184 int SharedClipboardProvider::ReadFileHdr(PVBOXCLIPBOARDFILEHDR pFileHdr)
     298int SharedClipboardProvider::ReadFileHdr(PVBOXCLIPBOARDFILEHDR *ppFileHdr)
     299{
     300    RT_NOREF(ppFileHdr);
     301
     302    LogFlowFuncEnter();
     303
     304    int rc = VERR_NOT_IMPLEMENTED;
     305
     306    LogFlowFuncLeaveRC(rc);
     307    return rc;
     308}
     309
     310int SharedClipboardProvider::WriteFileHdr(const PVBOXCLIPBOARDFILEHDR pFileHdr)
    185311{
    186312    RT_NOREF(pFileHdr);
     
    194320}
    195321
    196 int SharedClipboardProvider::WriteFileHdr(const PVBOXCLIPBOARDFILEHDR pFileHdr)
    197 {
    198     RT_NOREF(pFileHdr);
    199 
    200     LogFlowFuncEnter();
    201 
    202     int rc = VERR_NOT_IMPLEMENTED;
    203 
    204     LogFlowFuncLeaveRC(rc);
    205     return rc;
    206 }
    207 
    208 int SharedClipboardProvider::ReadFileData(PVBOXCLIPBOARDFILEDATA pFileData, uint32_t *pcbRead)
    209 {
    210     RT_NOREF(pFileData, pcbRead);
    211 
    212     LogFlowFuncEnter();
    213 
    214     int rc = VERR_NOT_IMPLEMENTED;
    215 
    216     LogFlowFuncLeaveRC(rc);
    217     return rc;
    218 }
    219 
    220 int SharedClipboardProvider::WriteFileData(const PVBOXCLIPBOARDFILEDATA pFileData, uint32_t *pcbWritten)
    221 {
    222     RT_NOREF(pFileData, pcbWritten);
     322int SharedClipboardProvider::ReadFileData(void *pvData, uint32_t cbData, uint32_t fFlags /* = 0 */,
     323                                          uint32_t *pcbRead /* = NULL */)
     324{
     325    RT_NOREF(pvData, cbData, fFlags, pcbRead);
     326
     327    LogFlowFuncEnter();
     328
     329    int rc = VERR_NOT_IMPLEMENTED;
     330
     331    LogFlowFuncLeaveRC(rc);
     332    return rc;
     333}
     334
     335int SharedClipboardProvider::WriteFileData(void *pvData, uint32_t cbData, uint32_t fFlags /* = 0 */,
     336                                           uint32_t *pcbWritten /* = NULL */)
     337{
     338    RT_NOREF(pvData, cbData, fFlags, pcbWritten);
    223339
    224340    LogFlowFuncEnter();
     
    254370}
    255371
     372/**
     373 * Registers a new event.
     374 * Will fail if an event with the same message ID already exists.
     375 *
     376 * @returns VBox status code.
     377 * @param   uMsg                Message ID to register event for.
     378 */
     379int SharedClipboardProvider::eventRegister(uint32_t uMsg)
     380{
     381    LogFlowFunc(("uMsg=%RU32\n", uMsg));
     382
     383    int rc;
     384
     385    EventMap::const_iterator itEvent = m_mapEvents.find(uMsg);
     386    if (itEvent == m_mapEvents.end())
     387    {
     388        SharedClipboardProvider::Event *pEvent = new SharedClipboardProvider::Event(uMsg);
     389        if (pEvent) /** @todo Can this throw? */
     390        {
     391            m_mapEvents[uMsg] = pEvent; /** @todo Ditto. */
     392
     393            rc = VINF_SUCCESS;
     394        }
     395        else
     396            rc = VERR_NO_MEMORY;
     397    }
     398    else
     399        rc = VERR_ALREADY_EXISTS;
     400
     401    LogFlowFuncLeaveRC(rc);
     402    return rc;
     403}
     404
     405/**
     406 * Unregisters an existing event.
     407 * Will return VERR_NOT_FOUND if no event has been found.
     408 *
     409 * @returns VBox status code.
     410 * @param   uMsg                Message ID to unregister event for.
     411 */
     412int SharedClipboardProvider::eventUnregister(uint32_t uMsg)
     413{
     414    LogFlowFunc(("uMsg=%RU32\n", uMsg));
     415
     416    int rc;
     417
     418    EventMap::const_iterator itEvent = m_mapEvents.find(uMsg);
     419    if (itEvent != m_mapEvents.end())
     420    {
     421        delete itEvent->second;
     422        m_mapEvents.erase(itEvent);
     423
     424        rc = VINF_SUCCESS;
     425    }
     426    else
     427        rc = VERR_NOT_FOUND;
     428
     429    LogFlowFuncLeaveRC(rc);
     430    return rc;
     431}
     432
     433/**
     434 * Unregisters all registered events.
     435 *
     436 * @returns VBox status code.
     437 */
     438int SharedClipboardProvider::eventUnregisterAll(void)
     439{
     440    int rc = VINF_SUCCESS;
     441
     442    LogFlowFuncEnter();
     443
     444    EventMap::const_iterator itEvent = m_mapEvents.begin();
     445    while (itEvent != m_mapEvents.end())
     446    {
     447        delete itEvent->second;
     448        m_mapEvents.erase(itEvent);
     449
     450        itEvent = m_mapEvents.begin();
     451    }
     452
     453    LogFlowFuncLeaveRC(rc);
     454    return rc;
     455}
     456
     457/**
     458 * Signals an event.
     459 * Will return VERR_NOT_FOUND if no event has been found.
     460 *
     461 * @returns VBox status code.
     462 * @param   uMsg                Message ID of event to signal.
     463 */
     464int SharedClipboardProvider::eventSignal(uint32_t uMsg)
     465{
     466    LogFlowFunc(("uMsg=%RU32\n", uMsg));
     467
     468    int rc;
     469
     470    EventMap::const_iterator itEvent = m_mapEvents.find(uMsg);
     471    if (itEvent != m_mapEvents.end())
     472    {
     473        rc = RTSemEventSignal(itEvent->second->mEvent);
     474    }
     475    else
     476        rc = VERR_NOT_FOUND;
     477
     478    LogFlowFuncLeaveRC(rc);
     479    return rc;
     480}
     481
     482/**
     483 * Returns the event for a specific message ID.
     484 *
     485 * @returns Pointer to event if found, or NULL if no event has been found
     486 * @param   uMsg                Messagae ID to return event for.
     487 */
     488SharedClipboardProvider::Event *SharedClipboardProvider::eventGet(uint32_t uMsg)
     489{
     490    LogFlowFuncEnter();
     491
     492    EventMap::const_iterator itEvent = m_mapEvents.find(uMsg);
     493    if (itEvent != m_mapEvents.end())
     494        return itEvent->second;
     495
     496    return NULL;
     497}
     498
     499/**
     500 * Waits for an event to get signalled and optionally returns related event data on success.
     501 *
     502 * @returns VBox status code.
     503 * @param   uMsg                Message ID of event to wait for.
     504 * @param   pfnCallback         Callback to use before waiting for event. Specify NULL if not needed.
     505 * @param   uTimeoutMs          Timeout (in ms) to wait for.
     506 * @param   ppvData             Where to store the related event data. Optioanl.
     507 * @param   pcbData             Where to store the size (in bytes) of the related event data. Optioanl.
     508 */
     509int SharedClipboardProvider::eventWait(uint32_t uMsg, PFNSSHAREDCLIPBOARDPROVIDERCALLBACK pfnCallback,
     510                                       RTMSINTERVAL uTimeoutMs, void **ppvData, uint32_t *pcbData /* = NULL */)
     511{
     512    LogFlowFunc(("uMsg=%RU32, uTimeoutMs=%RU32\n", uMsg, uTimeoutMs));
     513
     514    int rc = VINF_SUCCESS;
     515
     516    if (pfnCallback)
     517    {
     518        SHAREDCLIPBOARDPROVIDERCALLBACKDATA data = { this, m_Callbacks.pvUser };
     519        rc = pfnCallback(&data);
     520    }
     521
     522    if (RT_SUCCESS(rc))
     523    {
     524        Event *pEvent = eventGet(uMsg);
     525        if (pEvent)
     526        {
     527            rc = pEvent->Wait(m_uTimeoutMs);
     528            if (RT_SUCCESS(rc))
     529            {
     530                if (pcbData)
     531                    *pcbData = pEvent->DataSize();
     532
     533                if (ppvData)
     534                    *ppvData = pEvent->DataAdopt();
     535
     536                pEvent->Reset();
     537            }
     538        }
     539        else
     540            rc = VERR_NOT_FOUND;
     541    }
     542
     543    LogFlowFuncLeaveRC(rc);
     544    return rc;
     545}
     546
  • trunk/src/VBox/GuestHost/SharedClipboard/ClipboardStreamImpl-win.cpp

    r79120 r79267  
    188188    if (cbToRead)
    189189    {
    190         VBOXCLIPBOARDFILEDATA FileData;
    191         RT_ZERO(FileData);
    192 
    193         FileData.pvData = pvBuffer;
    194         FileData.cbData = cbToRead;
    195 
    196         rc = m_pURITransfer->pProvider->ReadFileData(&FileData, &cbRead);
     190        rc = m_pURITransfer->pProvider->ReadFileData(pvBuffer, cbToRead, 0 /* fFlags */, &cbRead);
    197191        if (RT_SUCCESS(rc))
    198192        {
  • trunk/src/VBox/GuestHost/SharedClipboard/ClipboardURIList.cpp

    r78942 r79267  
    5050    AssertPtrReturn(pcszSource, VERR_INVALID_POINTER);
    5151    AssertPtrReturn(pcszTarget, VERR_INVALID_POINTER);
     52    AssertReturn(!(fFlags & ~SHAREDCLIPBOARDURILIST_FLAGS_VALID_MASK), VERR_INVALID_FLAGS);
    5253
    5354    LogFlowFunc(("pcszSource=%s, pcszTarget=%s, fFlags=0x%x\n", pcszSource, pcszTarget, fFlags));
     
    292293    AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
    293294
    294     int rc;
    295     char *pszPathNative = RTStrDup(pszPath);
    296     if (pszPathNative)
    297     {
    298         RTPathChangeToUnixSlashes(pszPathNative, true /* fForce */);
    299 
    300         char *pszPathURI = RTUriCreate("file" /* pszScheme */, NULL /* pszAuthority */,
    301                                        pszPathNative, NULL /* pszQuery */, NULL /* pszFragment */);
    302         if (pszPathURI)
    303         {
    304             rc = AppendURIPath(pszPathURI, fFlags);
    305             RTStrFree(pszPathURI);
    306         }
    307         else
    308             rc = VERR_INVALID_PARAMETER;
    309 
    310         RTStrFree(pszPathNative);
    311     }
    312     else
    313         rc = VERR_NO_MEMORY;
     295    char *pszPathURI;
     296    int rc = SharedClipboardMetaDataConvertToFormat(pszPath, strlen(pszPath), SHAREDCLIPBOARDMETADATAFMT_URI_LIST,
     297                                                    (void **)&pszPathURI, NULL /* cbData */);
     298    if (RT_SUCCESS(rc))
     299    {
     300        rc = AppendURIPath(pszPathURI, fFlags);
     301        RTStrFree(pszPathURI);
     302    }
    314303
    315304    return rc;
     
    493482int SharedClipboardURIList::SetFromURIData(const void *pvData, size_t cbData, SHAREDCLIPBOARDURILISTFLAGS fFlags)
    494483{
    495     Assert(fFlags == 0); RT_NOREF1(fFlags);
    496484    AssertPtrReturn(pvData, VERR_INVALID_POINTER);
    497485    AssertReturn(cbData, VERR_INVALID_PARAMETER);
     486    AssertReturn(!(fFlags & ~SHAREDCLIPBOARDURILIST_FLAGS_VALID_MASK), VERR_INVALID_FLAGS);
    498487
    499488    if (!RTStrIsValidEncoding(static_cast<const char *>(pvData)))
     
    534523    }
    535524
     525    LogFlowFuncLeaveRC(rc);
    536526    return rc;
    537527}
  • trunk/src/VBox/GuestHost/SharedClipboard/clipboard-common.cpp

    r79178 r79267  
    3838static int sharedClipboardURITransferWriteThread(RTTHREAD hThread, void *pvUser);
    3939static PSHAREDCLIPBOARDURITRANSFER sharedClipboardURICtxGetTransferInternal(PSHAREDCLIPBOARDURICTX pURI, uint32_t uIdx);
     40
     41static void sharedClipboardURITransferMetaDataDestroyInternal(PSHAREDCLIPBOARDURITRANSFER pTransfer);
    4042#endif
    4143
     
    422424
    423425#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
    424 /**
    425  * Returns the size (in bytes) of the announced meta data.
    426  *
    427  * @returns Announced meta data size in bytes.
    428  * @param   pDataHdr            Data header struct to get announced meta data size for.
    429  */
    430 uint32_t SharedClipboardURIDataHdrGetMetaDataSize(PVBOXCLIPBOARDDATAHDR pDataHdr)
    431 {
    432     AssertPtrReturn(pDataHdr, 0);
    433 
    434     return pDataHdr->cbMeta;
    435 }
    436 
    437 /**
    438  * Initializes an URI data header struct.
    439  *
    440  * @returns VBox status code.
    441  * @param   pDataHdr            Data header struct to initialize.
    442  */
    443 int SharedClipboardURIDataHdrInit(PVBOXCLIPBOARDDATAHDR pDataHdr)
    444 {
    445     AssertPtrReturn(pDataHdr, VERR_INVALID_POINTER);
    446 
    447     SharedClipboardURIDataHdrReset(pDataHdr);
    448 
    449     return VINF_SUCCESS;
    450 }
    451 
    452 /**
    453  * Destroys an URI data header struct.
    454  *
    455  * @param   pDataHdr            Data header struct to destroy.
    456  */
    457 void SharedClipboardURIDataHdrDestroy(PVBOXCLIPBOARDDATAHDR pDataHdr)
    458 {
    459     if (!pDataHdr)
    460         return;
    461 
    462     if (pDataHdr->pvMetaFmt)
    463     {
    464         Assert(pDataHdr->cbMetaFmt);
    465 
    466         PSHAREDCLIPBOARDMETADATAFMT pMetaDatafmt = (PSHAREDCLIPBOARDMETADATAFMT)pDataHdr->pvMetaFmt;
    467         AssertPtr(pMetaDatafmt);
    468         if (pMetaDatafmt->pvFmt)
    469         {
    470             Assert(pMetaDatafmt->cbFmt);
    471             RTMemFree(pMetaDatafmt->pvFmt);
    472         }
    473 
    474         RTMemFree(pDataHdr->pvMetaFmt);
    475         pDataHdr->pvMetaFmt = NULL;
    476         pDataHdr->cbMetaFmt = 0;
    477     }
    478 
    479     if (pDataHdr->pvChecksum)
    480     {
    481         Assert(pDataHdr->cbChecksum);
    482 
    483         RTMemFree(pDataHdr->pvChecksum);
    484         pDataHdr->pvChecksum = NULL;
    485         pDataHdr->cbChecksum = 0;
    486     }
    487 }
    488 
    489 /**
    490  * Resets an URI data header struct.
    491  *
    492  * @returns VBox status code.
    493  * @param   pDataHdr            Data header struct to reset.
    494  */
    495 void SharedClipboardURIDataHdrReset(PVBOXCLIPBOARDDATAHDR pDataHdr)
    496 {
    497     AssertPtrReturnVoid(pDataHdr);
    498 
    499     LogFlowFuncEnter();
    500 
    501     RT_BZERO(pDataHdr, sizeof(VBOXCLIPBOARDDATAHDR));
    502 }
    503 
    504 /**
    505  * Returns whether a given clipboard data header is valid or not.
    506  *
    507  * @returns \c true if valid, \c false if not.
    508  * @param   pDataHdr            Clipboard data header to validate.
    509  */
    510 bool SharedClipboardURIDataHdrIsValid(PVBOXCLIPBOARDDATAHDR pDataHdr)
    511 {
    512     RT_NOREF(pDataHdr);
    513     return true; /** @todo Implement this. */
    514 }
    515 
    516 /**
    517  * Returns whether a given clipboard data chunk is valid or not.
    518  *
    519  * @returns \c true if valid, \c false if not.
    520  * @param   pDataChunk          Clipboard data chunk to validate.
    521  */
    522 bool SharedClipboardURIDataChunkIsValid(PVBOXCLIPBOARDDATACHUNK pDataChunk)
    523 {
    524     RT_NOREF(pDataChunk);
    525     return true; /** @todo Implement this. */
    526 }
    527 
    528 /**
    529  * Returns whether given clipboard directory data is valid or not.
    530  *
    531  * @returns \c true if valid, \c false if not.
    532  * @param   pDirData            Clipboard directory data to validate.
    533  */
    534 bool SharedClipboardURIDirDataIsValid(PVBOXCLIPBOARDDIRDATA pDirData)
    535 {
    536     if (   !pDirData->cbPath
    537         || pDirData->cbPath > RTPATH_MAX)
    538         return false;
    539 
    540     if (!RTStrIsValidEncoding(pDirData->pszPath))
    541         return false;
    542 
    543     return true;
    544 }
    545 
    546 /**
    547  * Returns whether a given clipboard file header is valid or not.
    548  *
    549  * @returns \c true if valid, \c false if not.
    550  * @param   pFileHdr            Clipboard file header to validate.
    551  * @param   pDataHdr            Data header to use for validation.
    552  */
    553 bool SharedClipboardURIFileHdrIsValid(PVBOXCLIPBOARDFILEHDR pFileHdr, PVBOXCLIPBOARDDATAHDR pDataHdr)
    554 {
    555     if (   !pFileHdr->cbFilePath
    556         || pFileHdr->cbFilePath > RTPATH_MAX)
    557         return false;
    558 
    559     if (!RTStrIsValidEncoding(pFileHdr->pszFilePath))
    560         return false;
    561 
    562     if (pFileHdr->cbSize > pDataHdr->cbTotal)
    563         return false;
    564 
    565     return true;
    566 }
    567 
    568 /**
    569  * Returns whether given clipboard file data is valid or not.
    570  *
    571  * @returns \c true if valid, \c false if not.
    572  * @param   pFileData           Clipboard file data to validate.
    573  * @param   pDataHdr            Data header to use for validation.
    574  */
    575 bool SharedClipboardURIFileDataIsValid(PVBOXCLIPBOARDFILEDATA pFileData, PVBOXCLIPBOARDDATAHDR pDataHdr)
    576 {
    577     RT_NOREF(pFileData, pDataHdr);
    578     return true;
    579 }
    580 
    581 /**
    582  * Initializes an URI object context.
    583  *
    584  * @returns VBox status code.
    585  * @param   pObjCtx             URI object context to initialize.
    586  */
    587 int SharedClipboardURIObjCtxInit(PSHAREDCLIPBOARDCLIENTURIOBJCTX pObjCtx)
    588 {
    589     AssertPtrReturn(pObjCtx, VERR_INVALID_POINTER);
    590 
    591     LogFlowFuncEnter();
    592 
    593     pObjCtx->pObj = NULL;
    594 
    595     return VINF_SUCCESS;
    596 }
    597 
    598 /**
    599  * Uninitializes an URI object context.
    600  *
    601  * @param   pObjCtx             URI object context to uninitialize.
    602  */
    603 void SharedClipboardURIObjCtxUninit(PSHAREDCLIPBOARDCLIENTURIOBJCTX pObjCtx)
    604 {
    605     AssertPtrReturnVoid(pObjCtx);
    606 
    607     LogFlowFuncEnter();
    608 
    609     if (pObjCtx->pObj)
    610     {
    611         pObjCtx->pObj->Close();
    612         delete pObjCtx->pObj;
    613     }
    614 
    615     pObjCtx->pObj = NULL;
    616 }
    617 
    618 /**
    619  * Returns the URI object context's URI object.
    620  *
    621  * @returns Pointer to the URI object context's URI object.
    622  * @param   pObjCtx             URI object context to return the URI object for.
    623  */
    624 SharedClipboardURIObject *SharedClipboardURIObjCtxGetObj(PSHAREDCLIPBOARDCLIENTURIOBJCTX pObjCtx)
    625 {
    626     AssertPtrReturn(pObjCtx, NULL);
    627     return pObjCtx->pObj;
    628 }
    629 
    630 /**
    631  * Returns if an URI object context is valid or not.
    632  *
    633  * @returns \c true if valid, \c false if not.
    634  * @param   pObjCtx             URI object context to check.
    635  */
    636 bool SharedClipboardURIObjCtxIsValid(PSHAREDCLIPBOARDCLIENTURIOBJCTX pObjCtx)
    637 {
    638     return (   pObjCtx
    639             && pObjCtx->pObj
    640             && pObjCtx->pObj->IsComplete() == false
    641             && pObjCtx->pObj->IsOpen());
    642 }
    643 
    644 /**
    645  * Initializes an URI clipboard transfer struct.
    646  *
    647  * @returns VBox status code.
    648  * @param   enmDir              Transfer direction.
    649  * @param   pCtx                Shared Clipboard provider creation context to use.
    650  * @param   ppTransfer          Where to return the created URI transfer struct.
    651  *                              Must be destroyed by SharedClipboardURITransferDestroy().
    652  */
    653 int SharedClipboardURITransferCreate(SHAREDCLIPBOARDURITRANSFERDIR enmDir, PSHAREDCLIPBOARDPROVIDERCREATIONCTX pCtx,
    654                                      PSHAREDCLIPBOARDURITRANSFER *ppTransfer)
    655 {
    656     AssertPtrReturn(pCtx,       VERR_INVALID_POINTER);
    657     AssertPtrReturn(ppTransfer, VERR_INVALID_POINTER);
    658 
    659     LogFlowFuncEnter();
    660 
    661     PSHAREDCLIPBOARDURITRANSFER pTransfer = (PSHAREDCLIPBOARDURITRANSFER)RTMemAlloc(sizeof(SHAREDCLIPBOARDURITRANSFER));
    662     if (!pTransfer)
    663         return VERR_NO_MEMORY;
    664 
    665     pTransfer->State.enmDir = enmDir;
    666 
    667     int rc = SharedClipboardURIDataHdrInit(&pTransfer->State.Header);
    668     if (RT_SUCCESS(rc))
    669     {
    670         rc = SharedClipboardMetaDataInit(&pTransfer->State.Meta);
    671         if (RT_SUCCESS(rc))
    672         {
    673             pTransfer->pArea     = NULL; /* Will be created later if needed. */
    674             pTransfer->pProvider = SharedClipboardProvider::Create(pCtx);
    675             if (pTransfer->pProvider)
    676             {
    677                 pTransfer->Thread.hThread    = NIL_RTTHREAD;
    678                 pTransfer->Thread.fCancelled = false;
    679                 pTransfer->Thread.fStarted   = false;
    680 
    681                 pTransfer->pvUser = NULL;
    682                 pTransfer->cbUser = 0;
    683 
    684                 *ppTransfer = pTransfer;
    685             }
    686             else
    687                 rc = VERR_NO_MEMORY;
    688         }
    689     }
    690 
    691     LogFlowFuncLeaveRC(rc);
    692     return rc;
    693 }
    694 
    695 /**
    696  * Destroys an URI clipboard transfer context struct.
    697  *
    698  * @returns VBox status code.
    699  * @param   pURI                URI clipboard transfer to destroy.
    700  */
    701 int SharedClipboardURITransferDestroy(PSHAREDCLIPBOARDURITRANSFER pTransfer)
    702 {
    703     if (!pTransfer)
    704         return VINF_SUCCESS;
    705 
    706     LogFlowFuncEnter();
    707 
    708     int rc = sharedClipboardURITransferThreadDestroy(pTransfer, 30 * 1000 /* Timeout in ms */);
    709     if (RT_FAILURE(rc))
    710         return rc;
    711 
    712     SharedClipboardURIDataHdrDestroy(&pTransfer->State.Header);
    713     SharedClipboardMetaDataDestroy(&pTransfer->State.Meta);
    714 
    715     if (pTransfer->pProvider)
    716     {
    717         delete pTransfer->pProvider;
    718         pTransfer->pProvider = NULL;
    719     }
    720 
    721     RTMemFree(pTransfer);
    722     pTransfer = NULL;
    723 
    724     LogFlowFuncLeave();
    725 
    726     return VINF_SUCCESS;
    727 }
    728 
    729 /**
    730  * Resets an clipboard URI transfer.
    731  *
    732  * @param   pTransfer           URI clipboard transfer to reset.
    733  */
    734 void SharedClipboardURITransferReset(PSHAREDCLIPBOARDURITRANSFER pTransfer)
    735 {
    736     AssertPtrReturnVoid(pTransfer);
    737 
    738     LogFlowFuncEnter();
    739 
    740     /** @todo Anything else to do here? */
    741 
    742     if (pTransfer->pProvider)
    743         pTransfer->pProvider->Reset();
    744 
    745     pTransfer->URIList.Clear();
    746 }
    747 
    748 /**
    749  * Returns the clipboard area for a clipboard URI transfer.
    750  *
    751  * @returns Current clipboard area, or NULL if none.
    752  * @param   pTransfer           URI clipboard transfer to return clipboard area for.
    753  */
    754 SharedClipboardArea *SharedClipboardURITransferGetArea(PSHAREDCLIPBOARDURITRANSFER pTransfer)
    755 {
    756     AssertPtrReturn(pTransfer, NULL);
    757 
    758     return pTransfer->pArea;
    759 }
    760 
    761 /**
    762  * Returns the current URI object for a clipboard URI transfer.
    763  *
    764  * @returns Current URI object, or NULL if none.
    765  * @param   pTransfer           URI clipboard transfer to return current URI object for.
    766  */
    767 const SharedClipboardURIObject *SharedClipboardURITransferGetCurrentObject(PSHAREDCLIPBOARDURITRANSFER pTransfer)
    768 {
    769     AssertPtrReturn(pTransfer, NULL);
    770 
    771     return pTransfer->URIList.First();
    772 }
    773 
    774 /**
    775  * Returns the provider for a clipboard URI transfer.
    776  *
    777  * @returns Current provider, or NULL if none.
    778  * @param   pTransfer           URI clipboard transfer to return provider for.
    779  */
    780 SharedClipboardProvider *SharedClipboardURITransferGetProvider(PSHAREDCLIPBOARDURITRANSFER pTransfer)
    781 {
    782     AssertPtrReturn(pTransfer, NULL);
    783 
    784     return pTransfer->pProvider;
    785 }
    786 
    787 /**
    788  * Returns the URI list for a clipboard URI transfer.
    789  *
    790  * @returns Pointer to URI list.
    791  * @param   pTransfer           URI clipboard transfer to return URI list for.
    792  */
    793 SharedClipboardURIList *SharedClipboardURITransferGetList(PSHAREDCLIPBOARDURITRANSFER pTransfer)
    794 {
    795     return &pTransfer->URIList;
    796 }
    797 
    798 /**
    799  * Returns the current URI object for a clipboard URI transfer.
    800  *
    801  * @returns Pointer to URI object.
    802  * @param   pTransfer           URI clipboard transfer to return URI object for.
    803  */
    804 SharedClipboardURIObject *SharedClipboardURITransferGetObject(PSHAREDCLIPBOARDURITRANSFER pTransfer, uint64_t uIdx)
    805 {
    806     return pTransfer->URIList.At(uIdx);
    807 }
    808 
    809 /**
    810  * Runs (starts) an URI transfer, either in synchronous or asynchronous (threaded) mode.
    811  *
    812  * @returns VBox status code.
    813  * @param   pTransfer           URI clipboard transfer to run.
    814  * @param   fAsync              Whether to run the transfer synchronously or asynchronously.
    815  */
    816 int SharedClipboardURITransferRun(PSHAREDCLIPBOARDURITRANSFER pTransfer, bool fAsync)
    817 {
    818     AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
    819 
     426int SharedClipboardURIDataHdrAlloc(PVBOXCLIPBOARDDATAHDR *ppDataHdr)
     427{
    820428    int rc;
    821429
    822     LogFlowFunc(("fAsync=%RTbool\n", fAsync));
    823 
    824     if (fAsync)
    825     {
    826         rc = sharedClipboardURITransferThreadCreate(pTransfer);
    827     }
    828     else
    829     {
    830         if (pTransfer->State.enmDir == SHAREDCLIPBOARDURITRANSFERDIR_READ)
    831             rc = SharedClipboardURITransferRead(pTransfer);
    832         else if (pTransfer->State.enmDir == SHAREDCLIPBOARDURITRANSFERDIR_WRITE)
    833             rc = SharedClipboardURITransferWrite(pTransfer);
    834         else
    835             rc = VERR_NOT_IMPLEMENTED;
    836     }
    837 
    838     LogFlowFuncLeaveRC(rc);
    839     return rc;
    840 }
    841 
    842 /**
    843  * Sets or unsets the callback table to be used for a clipboard URI transfer.
    844  *
    845  * @returns VBox status code.
    846  * @param   pTransfer           URI clipboard transfer to set callbacks for.
    847  * @param   pCallbacks          Pointer to callback table to set. Specify NULL to unset existing callbacks.
    848  */
    849 void SharedClipboardURITransferSetCallbacks(PSHAREDCLIPBOARDURITRANSFER pTransfer, PSHAREDCLIPBOARDURITRANSFERCALLBACKS pCallbacks)
    850 {
    851     AssertPtrReturnVoid(pTransfer);
    852     /* pCallbacks might be NULL to unset callbacks. */
    853 
    854     LogFlowFunc(("pCallbacks=%p\n", pCallbacks));
    855 
    856     if (pCallbacks)
    857     {
    858         pTransfer->Callbacks = *pCallbacks;
    859     }
    860     else
    861         RT_ZERO(pTransfer->Callbacks);
    862 }
    863 
    864 /**
    865  * Creates a thread for a clipboard URI transfer.
    866  *
    867  * @returns VBox status code.
    868  * @param   pTransfer           URI clipboard transfer to create thread for.
    869  */
    870 static int sharedClipboardURITransferThreadCreate(PSHAREDCLIPBOARDURITRANSFER pTransfer)
    871 {
    872     AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
    873 
    874     PFNRTTHREAD pfnRTThread = NULL;
    875 
    876     if (pTransfer->State.enmDir == SHAREDCLIPBOARDURITRANSFERDIR_READ)
    877         pfnRTThread = sharedClipboardURITransferReadThread;
    878     else if (pTransfer->State.enmDir == SHAREDCLIPBOARDURITRANSFERDIR_WRITE)
    879         pfnRTThread = sharedClipboardURITransferWriteThread;
    880 
    881     AssertPtrReturn(pfnRTThread, VERR_NOT_SUPPORTED);
    882 
    883     /* Spawn a worker thread, so that we don't block the window thread for too long. */
    884     int rc = RTThreadCreate(&pTransfer->Thread.hThread, pfnRTThread,
    885                             pTransfer /* pvUser */, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE,
    886                             "shclp");
    887     if (RT_SUCCESS(rc))
    888     {
    889         int rc2 = RTThreadUserWait(pTransfer->Thread.hThread, 30 * 1000 /* Timeout in ms */);
    890         AssertRC(rc2);
    891 
    892         if (!pTransfer->Thread.fStarted) /* Did the thread fail to start? */
    893             rc = VERR_GENERAL_FAILURE; /** @todo Find a better rc. */
    894     }
    895 
    896     LogFlowFuncLeaveRC(rc);
    897     return rc;
    898 }
    899 
    900 /**
    901  * Destroys a thread of a clipboard URI transfer.
    902  *
    903  * @returns VBox status code.
    904  * @param   pTransfer           URI clipboard transfer to destroy thread for.
    905  * @param   uTimeoutMs          Timeout (in ms) to wait for thread creation.
    906  */
    907 static int sharedClipboardURITransferThreadDestroy(PSHAREDCLIPBOARDURITRANSFER pTransfer, RTMSINTERVAL uTimeoutMs)
    908 {
    909     AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
    910 
    911     if (pTransfer->Thread.hThread == NIL_RTTHREAD)
    912         return VINF_SUCCESS;
    913 
    914     int rcThread = VERR_WRONG_ORDER;
    915     int rc = RTThreadWait(pTransfer->Thread.hThread, uTimeoutMs, &rcThread);
    916 
    917     LogFlowFunc(("Waiting for thread resulted in %Rrc (thread exited with %Rrc)\n", rc, rcThread));
    918 
    919     return rc;
    920 }
    921 
    922 /**
    923  * Reads all URI objects using the connected provider.
    924  *
    925  * @returns VBox status code.
    926  * @param   pTransfer           Transfer to read objects for.
    927  */
    928 int SharedClipboardURITransferRead(PSHAREDCLIPBOARDURITRANSFER pTransfer)
    929 {
    930     AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
    931 
    932     LogFlowFuncEnter();
    933 
    934     int rc = SharedClipboardURITransferMetaDataRead(pTransfer, NULL /* pcbRead */);
    935     if (RT_SUCCESS(rc))
    936     {
    937         rc = SharedClipboardURITransferWriteObjects(pTransfer);
    938         if (RT_SUCCESS(rc))
    939         {
    940             if (pTransfer->Callbacks.pfnTransferComplete)
    941             {
    942                 SHAREDCLIPBOARDURITRANSFERCALLBACKDATA callbackData = { pTransfer, pTransfer->Callbacks.pvUser };
    943                 pTransfer->Callbacks.pfnTransferComplete(&callbackData, rc);
    944             }
    945         }
    946     }
    947 
    948     if (RT_FAILURE(rc))
    949     {
    950         if (pTransfer->Callbacks.pfnTransferError)
    951         {
    952             SHAREDCLIPBOARDURITRANSFERCALLBACKDATA callbackData = { pTransfer, pTransfer->Callbacks.pvUser };
    953             pTransfer->Callbacks.pfnTransferError(&callbackData, rc);
    954         }
    955     }
    956 
    957     LogFlowFuncLeaveRC(rc);
    958     return rc;
    959 }
    960 
    961 /**
    962  * Thread for transferring (reading) URI objects from source to the target.
    963  * For target to source transfers we utilize our own IDataObject / IStream implementations.
    964  *
    965  * @returns VBox status code.
    966  * @param   hThread             Thread handle.
    967  * @param   pvUser              User arguments; is PSHAREDCLIPBOARDURITRANSFER.
    968  */
    969 static int sharedClipboardURITransferReadThread(RTTHREAD hThread, void *pvUser)
    970 {
    971     AssertPtrReturn(pvUser, VERR_INVALID_POINTER);
    972 
    973     LogFlowFuncEnter();
    974 
    975     /* At the moment we only support one transfer at a time. */
    976     PSHAREDCLIPBOARDURITRANSFER pTransfer = (PSHAREDCLIPBOARDURITRANSFER)pvUser;
    977     AssertPtr(pTransfer->pProvider);
    978 
    979     int rc = VINF_SUCCESS;
    980 
    981     if (RT_SUCCESS(rc))
    982         pTransfer->Thread.fStarted = true;
    983 
    984     int rc2 = RTThreadUserSignal(hThread);
    985     const bool fSignalled = RT_SUCCESS(rc2);
    986 
    987     if (RT_SUCCESS(rc))
    988         rc = SharedClipboardURITransferRead(pTransfer);
    989 
    990     if (!fSignalled)
    991     {
    992         rc2 = RTThreadUserSignal(hThread);
    993         AssertRC(rc2);
    994     }
    995 
    996     LogFlowFuncLeaveRC(rc);
    997     return rc;
    998 }
    999 
    1000 /**
    1001  * Adds meta data for a clipboard URI transfer, internal version.
    1002  *
    1003  * @returns VBox status code.
    1004  * @param   pTransfer           URI clipboard transfer to set meta data for.
    1005  * @param   pvMeta              Pointer to meta data buffer.
    1006  * @param   cbMeta              Size (in bytes) of meta data buffer.
    1007  */
    1008 static int sharedClipboardURITransferMetaDataAddInternal(PSHAREDCLIPBOARDURITRANSFER pTransfer,
    1009                                                          const void *pvMeta, uint32_t cbMeta)
    1010 {
    1011     LogFlowFunc(("pvMeta=%p, cbMeta=%RU32\n", pvMeta, cbMeta));
    1012 
    1013     int rc = SharedClipboardMetaDataAdd(&pTransfer->State.Meta, pvMeta, cbMeta);
    1014 
    1015     LogFlowFuncLeaveRC(rc);
    1016     return rc;
    1017 }
    1018 
    1019 /**
    1020  * Adds meta data for a clipboard URI transfer.
    1021  *
    1022  * @returns VBox status code.
    1023  * @param   pTransfer           URI clipboard transfer to set meta data for.
    1024  * @param   pvMeta              Pointer to meta data buffer.
    1025  * @param   cbMeta              Size (in bytes) of meta data buffer.
    1026  */
    1027 int SharedClipboardURITransferMetaDataAdd(PSHAREDCLIPBOARDURITRANSFER pTransfer, const void *pvMeta, uint32_t cbMeta)
    1028 {
    1029     AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
    1030 
    1031     int rc = sharedClipboardURITransferMetaDataAddInternal(pTransfer, pvMeta, cbMeta);
    1032 
    1033     LogFlowFuncLeaveRC(rc);
    1034     return rc;
    1035 }
    1036 
    1037 /**
    1038  * Marks the meta data as being complete and initializes everything needed for the transfer to begin.
    1039  *
    1040  * @returns VBox status code.
    1041  * @param   pTransfer           URI clipboard transfer to mark meta data complete for.
    1042  */
    1043 int SharedClipboardURITransferMetaDataComplete(PSHAREDCLIPBOARDURITRANSFER pTransfer)
    1044 {
    1045     AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
    1046 
    1047     LogFlowFuncEnter();
    1048 
    1049     int rc = pTransfer->URIList.SetFromURIData(SharedClipboardMetaDataRaw(&pTransfer->State.Meta),
    1050                                                SharedClipboardMetaDataGetUsed(&pTransfer->State.Meta),
    1051                                                SHAREDCLIPBOARDURILIST_FLAGS_NONE);
    1052     if (RT_SUCCESS(rc))
    1053     {
    1054         pTransfer->State.Header.cbTotal  = pTransfer->URIList.GetTotalBytes();
    1055         pTransfer->State.Header.cbMeta   = (uint32_t)SharedClipboardMetaDataGetUsed(&pTransfer->State.Meta);
    1056         pTransfer->State.Header.cObjects = pTransfer->URIList.GetTotalCount();
    1057 
    1058         PSHAREDCLIPBOARDMETADATAFMT pMetaDataFmt = (PSHAREDCLIPBOARDMETADATAFMT)RTMemAllocZ(sizeof(SHAREDCLIPBOARDMETADATAFMT));
     430    PVBOXCLIPBOARDDATAHDR pDataHdr = (PVBOXCLIPBOARDDATAHDR)RTMemAllocZ(sizeof(VBOXCLIPBOARDDATAHDR));
     431    if (pDataHdr)
     432    {
     433        PSHAREDCLIPBOARDMETADATAFMTDATA pMetaDataFmt
     434            = (PSHAREDCLIPBOARDMETADATAFMTDATA)RTMemAllocZ(sizeof(SHAREDCLIPBOARDMETADATAFMTDATA));
    1059435        if (pMetaDataFmt)
    1060436        {
     
    1067443                pMetaDataFmt->cbFmt = (uint32_t)strlen(pszFmt) + 1 /* Include terminating zero */;
    1068444
    1069                 pTransfer->State.Header.pvMetaFmt = pMetaDataFmt;
    1070                 pTransfer->State.Header.cbMetaFmt = sizeof(PSHAREDCLIPBOARDMETADATAFMT) + pMetaDataFmt->cbFmt;
     445                pDataHdr->pvMetaFmt = pMetaDataFmt;
     446                pDataHdr->cbMetaFmt = sizeof(SHAREDCLIPBOARDMETADATAFMTDATA) + pMetaDataFmt->cbFmt;
     447
     448                *ppDataHdr = pDataHdr;
    1071449            }
    1072450        }
     
    1074452            rc = VERR_NO_MEMORY;
    1075453
     454        if (RT_FAILURE(rc))
     455        {
     456            RTMemFree(pDataHdr);
     457            pDataHdr = NULL;
     458        }
     459    }
     460    else
     461        rc = VERR_NO_MEMORY;
     462
     463    LogFlowFuncLeaveRC(rc);
     464    return rc;
     465}
     466
     467/**
     468 * Frees a VBOXCLIPBOARDDATAHDR structure.
     469 *
     470 * @param   pDataChunk          VBOXCLIPBOARDDATAHDR structure to free.
     471 */
     472void SharedClipboardURIDataHdrFree(PVBOXCLIPBOARDDATAHDR pDataHdr)
     473{
     474    if (!pDataHdr)
     475        return;
     476
     477    LogFlowFuncEnter();
     478
     479    SharedClipboardURIDataHdrDestroy(pDataHdr);
     480
     481    RTMemFree(pDataHdr);
     482    pDataHdr = NULL;
     483}
     484
     485/**
     486 * Duplicates (allocates) a VBOXCLIPBOARDDATAHDR structure.
     487 *
     488 * @returns Duplicated VBOXCLIPBOARDDATAHDR structure on success.
     489 * @param   pDataHdr            VBOXCLIPBOARDDATAHDR to duplicate.
     490 */
     491PVBOXCLIPBOARDDATAHDR SharedClipboardURIDataHdrDup(PVBOXCLIPBOARDDATAHDR pDataHdr)
     492{
     493    AssertPtrReturn(pDataHdr, NULL);
     494
     495    PVBOXCLIPBOARDDATAHDR pDataHdrDup = (PVBOXCLIPBOARDDATAHDR)RTMemAlloc(sizeof(VBOXCLIPBOARDDATAHDR));
     496    if (pDataHdrDup)
     497    {
     498        *pDataHdrDup = *pDataHdr;
     499
     500        if (pDataHdr->pvMetaFmt)
     501        {
     502            pDataHdrDup->pvMetaFmt = RTMemDup(pDataHdr->pvMetaFmt, pDataHdr->cbMetaFmt);
     503            pDataHdrDup->cbMetaFmt = pDataHdr->cbMetaFmt;
     504        }
     505
     506        if (pDataHdr->pvChecksum)
     507        {
     508            pDataHdrDup->pvChecksum = RTMemDup(pDataHdr->pvChecksum, pDataHdr->cbChecksum);
     509            pDataHdrDup->cbChecksum = pDataHdr->cbChecksum;
     510        }
     511    }
     512
     513    return pDataHdrDup;
     514}
     515
     516/**
     517 * Returns the size (in bytes) of the announced meta data.
     518 *
     519 * @returns Announced meta data size in bytes.
     520 * @param   pDataHdr            Data header struct to get announced meta data size for.
     521 */
     522uint32_t SharedClipboardURIDataHdrGetMetaDataSize(PVBOXCLIPBOARDDATAHDR pDataHdr)
     523{
     524    AssertPtrReturn(pDataHdr, 0);
     525
     526    return pDataHdr->cbMeta;
     527}
     528
     529/**
     530 * Initializes an URI data header struct.
     531 *
     532 * @returns VBox status code.
     533 * @param   pDataHdr            Data header struct to initialize.
     534 */
     535int SharedClipboardURIDataHdrInit(PVBOXCLIPBOARDDATAHDR pDataHdr)
     536{
     537    AssertPtrReturn(pDataHdr, VERR_INVALID_POINTER);
     538
     539    SharedClipboardURIDataHdrReset(pDataHdr);
     540
     541    return VINF_SUCCESS;
     542}
     543
     544/**
     545 * Destroys an URI data header struct.
     546 *
     547 * @param   pDataHdr            Data header struct to destroy.
     548 */
     549void SharedClipboardURIDataHdrDestroy(PVBOXCLIPBOARDDATAHDR pDataHdr)
     550{
     551    if (!pDataHdr)
     552        return;
     553
     554    LogFlowFuncEnter();
     555
     556    if (pDataHdr->pvMetaFmt)
     557    {
     558        Assert(pDataHdr->cbMetaFmt);
     559
     560        RTMemFree(pDataHdr->pvMetaFmt);
     561        pDataHdr->pvMetaFmt = NULL;
     562        pDataHdr->cbMetaFmt = 0;
     563    }
     564
     565    if (pDataHdr->pvChecksum)
     566    {
     567        Assert(pDataHdr->cbChecksum);
     568
     569        RTMemFree(pDataHdr->pvChecksum);
     570        pDataHdr->pvChecksum = NULL;
     571        pDataHdr->cbChecksum = 0;
     572    }
     573}
     574
     575/**
     576 * Resets a VBOXCLIPBOARDDATAHDR structture.
     577 *
     578 * @returns VBox status code.
     579 * @param   pDataHdr            VBOXCLIPBOARDDATAHDR structture to reset.
     580 */
     581void SharedClipboardURIDataHdrReset(PVBOXCLIPBOARDDATAHDR pDataHdr)
     582{
     583    AssertPtrReturnVoid(pDataHdr);
     584
     585    LogFlowFuncEnter();
     586
     587    RT_BZERO(pDataHdr, sizeof(VBOXCLIPBOARDDATAHDR));
     588}
     589
     590/**
     591 * Returns whether a given clipboard data header is valid or not.
     592 *
     593 * @returns \c true if valid, \c false if not.
     594 * @param   pDataHdr            Clipboard data header to validate.
     595 */
     596bool SharedClipboardURIDataHdrIsValid(PVBOXCLIPBOARDDATAHDR pDataHdr)
     597{
     598    RT_NOREF(pDataHdr);
     599    return true; /** @todo Implement this. */
     600}
     601
     602/**
     603 * Creates (allocates) and initializes a VBOXCLIPBOARDDATACHUNK structure.
     604 *
     605 * @param   ppDirData           Where to return the created VBOXCLIPBOARDDATACHUNK structure on success.
     606 */
     607int SharedClipboardURIDataChunkAlloc(PVBOXCLIPBOARDDATACHUNK *ppDataChunk)
     608{
     609    PVBOXCLIPBOARDDATACHUNK pDataChunk = (PVBOXCLIPBOARDDATACHUNK)RTMemAlloc(sizeof(VBOXCLIPBOARDDATACHUNK));
     610    if (!pDataChunk)
     611        return VERR_NO_MEMORY;
     612
     613    int rc = SharedClipboardURIDataChunkInit(pDataChunk);
     614    if (RT_SUCCESS(rc))
     615        *ppDataChunk = pDataChunk;
     616
     617    return rc;
     618}
     619
     620/**
     621 * Frees a VBOXCLIPBOARDDATACHUNK structure.
     622 *
     623 * @param   pDataChunk         VBOXCLIPBOARDDATACHUNK structure to free.
     624 */
     625void SharedClipboardURIDataChunkFree(PVBOXCLIPBOARDDATACHUNK pDataChunk)
     626{
     627    if (!pDataChunk)
     628        return;
     629
     630    SharedClipboardURIDataChunkDestroy(pDataChunk);
     631    RTMemFree(pDataChunk);
     632}
     633
     634/**
     635 * Initializes a VBOXCLIPBOARDDATACHUNK structure.
     636 *
     637 * @param   pDataChunk          VBOXCLIPBOARDDATACHUNK structure to initialize.
     638 */
     639int SharedClipboardURIDataChunkInit(PVBOXCLIPBOARDDATACHUNK pDataChunk)
     640{
     641    RT_BZERO(pDataChunk, sizeof(VBOXCLIPBOARDDATACHUNK));
     642
     643    return VINF_SUCCESS;
     644}
     645
     646/**
     647 * Initializes a VBOXCLIPBOARDDATACHUNK structure.
     648 *
     649 * @param   pDataChunk          VBOXCLIPBOARDDATACHUNK structure to destroy.
     650 */
     651void SharedClipboardURIDataChunkDestroy(PVBOXCLIPBOARDDATACHUNK pDataChunk)
     652{
     653    if (pDataChunk->pvData)
     654    {
     655        RTMemFree(pDataChunk->pvData);
     656        pDataChunk->pvData = NULL;
     657        pDataChunk->cbData = 0;
     658    }
     659
     660    if (pDataChunk->pvChecksum)
     661    {
     662        RTMemFree(pDataChunk->pvChecksum);
     663        pDataChunk->pvChecksum = NULL;
     664        pDataChunk->cbChecksum = 0;
     665    }
     666}
     667
     668/**
     669 * Returns whether a given clipboard data chunk is valid or not.
     670 *
     671 * @returns \c true if valid, \c false if not.
     672 * @param   pDataChunk          Clipboard data chunk to validate.
     673 */
     674bool SharedClipboardURIDataChunkIsValid(PVBOXCLIPBOARDDATACHUNK pDataChunk)
     675{
     676    RT_NOREF(pDataChunk);
     677
     678    /** @todo Verify checksum. */
     679
     680    return true; /** @todo Implement this. */
     681}
     682
     683/**
     684 * Creates (allocates) and initializes a VBOXCLIPBOARDDIRDATA structure.
     685 *
     686 * @param   ppDirData           Where to return the created VBOXCLIPBOARDDIRDATA structure on success.
     687 */
     688int SharedClipboardURIDirDataAlloc(PVBOXCLIPBOARDDIRDATA *ppDirData)
     689{
     690    PVBOXCLIPBOARDDIRDATA pDirData = (PVBOXCLIPBOARDDIRDATA)RTMemAlloc(sizeof(VBOXCLIPBOARDDIRDATA));
     691    if (!pDirData)
     692        return VERR_NO_MEMORY;
     693
     694    int rc = SharedClipboardURIDirDataInit(pDirData);
     695    if (RT_SUCCESS(rc))
     696        *ppDirData = pDirData;
     697
     698    return rc;
     699}
     700
     701/**
     702 * Frees a VBOXCLIPBOARDDIRDATA structure.
     703 *
     704 * @param   pDirData           Where to return the created VBOXCLIPBOARDDIRDATA structure on success.
     705 */
     706void SharedClipboardURIDirDataFree(PVBOXCLIPBOARDDIRDATA pDirData)
     707{
     708    if (!pDirData)
     709        return;
     710
     711    SharedClipboardURIDirDataDestroy(pDirData);
     712    RTMemFree(pDirData);
     713}
     714
     715/**
     716 * Initializes a VBOXCLIPBOARDDIRDATA structure.
     717 *
     718 * @param   pDirData            VBOXCLIPBOARDDIRDATA structure to initialize.
     719 */
     720int SharedClipboardURIDirDataInit(PVBOXCLIPBOARDDIRDATA pDirData)
     721{
     722    RT_BZERO(pDirData, sizeof(VBOXCLIPBOARDDIRDATA));
     723
     724    return VINF_SUCCESS;
     725}
     726
     727/**
     728 * Destroys a VBOXCLIPBOARDDIRDATA structure.
     729 *
     730 * @param   pDirData            VBOXCLIPBOARDDIRDATA structure to destroy.
     731 */
     732void SharedClipboardURIDirDataDestroy(PVBOXCLIPBOARDDIRDATA pDirData)
     733{
     734    if (!pDirData)
     735        return;
     736
     737    if (pDirData->pszPath)
     738    {
     739        Assert(pDirData->cbPath);
     740        RTStrFree(pDirData->pszPath);
     741        pDirData->pszPath = NULL;
     742    }
     743}
     744
     745/**
     746 * Duplicates (allocates) a VBOXCLIPBOARDDIRDATA structure.
     747 *
     748 * @returns Duplicated VBOXCLIPBOARDDIRDATA structure on success.
     749 * @param   pDirData            VBOXCLIPBOARDDIRDATA to duplicate.
     750 */
     751PVBOXCLIPBOARDDIRDATA SharedClipboardURIDirDataDup(PVBOXCLIPBOARDDIRDATA pDirData)
     752{
     753    AssertPtrReturn(pDirData, NULL);
     754
     755    PVBOXCLIPBOARDDIRDATA pDirDataDup = (PVBOXCLIPBOARDDIRDATA)RTMemAllocZ(sizeof(VBOXCLIPBOARDDIRDATA));
     756    if (pDirDataDup)
     757    {
     758        *pDirDataDup = *pDirData;
     759
     760        if (pDirData->pszPath)
     761        {
     762            pDirDataDup->pszPath = RTStrDup(pDirData->pszPath);
     763            if (pDirDataDup->pszPath)
     764                pDirDataDup->cbPath = pDirData->cbPath;
     765        }
     766    }
     767
     768    return pDirDataDup;
     769}
     770
     771/**
     772 * Returns whether given clipboard directory data is valid or not.
     773 *
     774 * @returns \c true if valid, \c false if not.
     775 * @param   pDirData            Clipboard directory data to validate.
     776 */
     777bool SharedClipboardURIDirDataIsValid(PVBOXCLIPBOARDDIRDATA pDirData)
     778{
     779    if (   !pDirData->cbPath
     780        || pDirData->cbPath > RTPATH_MAX)
     781        return false;
     782
     783    if (!RTStrIsValidEncoding(pDirData->pszPath))
     784        return false;
     785
     786    return true;
     787}
     788
     789/**
     790 * Initializes a VBOXCLIPBOARDFILEHDR structure.
     791 *
     792 * @param   pDirData            VBOXCLIPBOARDFILEHDR structure to initialize.
     793 */
     794int SharedClipboardURIFileHdrInit(PVBOXCLIPBOARDFILEHDR pFileHdr)
     795{
     796    RT_BZERO(pFileHdr, sizeof(VBOXCLIPBOARDFILEHDR));
     797
     798    return VINF_SUCCESS;
     799}
     800
     801/**
     802 * Destroys a VBOXCLIPBOARDFILEHDR structure.
     803 *
     804 * @param   pFileHdr            VBOXCLIPBOARDFILEHDR structure to destroy.
     805 */
     806void SharedClipboardURIFileHdrDestroy(PVBOXCLIPBOARDFILEHDR pFileHdr)
     807{
     808    if (!pFileHdr)
     809        return;
     810
     811    if (pFileHdr->pszFilePath)
     812    {
     813        Assert(pFileHdr->pszFilePath);
     814        RTStrFree(pFileHdr->pszFilePath);
     815        pFileHdr->pszFilePath = NULL;
     816    }
     817}
     818
     819/**
     820 * Duplicates (allocates) a VBOXCLIPBOARDFILEHDR structure.
     821 *
     822 * @returns Duplicated VBOXCLIPBOARDFILEHDR structure on success.
     823 * @param   pFileHdr            VBOXCLIPBOARDFILEHDR to duplicate.
     824 */
     825PVBOXCLIPBOARDFILEHDR SharedClipboardURIFileHdrDup(PVBOXCLIPBOARDFILEHDR pFileHdr)
     826{
     827    AssertPtrReturn(pFileHdr, NULL);
     828
     829    PVBOXCLIPBOARDFILEHDR pFileHdrDup = (PVBOXCLIPBOARDFILEHDR)RTMemAllocZ(sizeof(VBOXCLIPBOARDFILEHDR));
     830    if (pFileHdrDup)
     831    {
     832        *pFileHdrDup = *pFileHdr;
     833
     834        if (pFileHdr->pszFilePath)
     835        {
     836            pFileHdrDup->pszFilePath = RTStrDup(pFileHdr->pszFilePath);
     837            if (pFileHdrDup->pszFilePath)
     838                pFileHdrDup->cbFilePath = pFileHdrDup->cbFilePath;
     839        }
     840    }
     841
     842    return pFileHdrDup;
     843}
     844
     845/**
     846 * Returns whether a given clipboard file header is valid or not.
     847 *
     848 * @returns \c true if valid, \c false if not.
     849 * @param   pFileHdr            Clipboard file header to validate.
     850 * @param   pDataHdr            Data header to use for validation.
     851 */
     852bool SharedClipboardURIFileHdrIsValid(PVBOXCLIPBOARDFILEHDR pFileHdr, PVBOXCLIPBOARDDATAHDR pDataHdr)
     853{
     854    if (   !pFileHdr->cbFilePath
     855        || pFileHdr->cbFilePath > RTPATH_MAX)
     856        return false;
     857
     858    if (!RTStrIsValidEncoding(pFileHdr->pszFilePath))
     859        return false;
     860
     861    if (pFileHdr->cbSize > pDataHdr->cbTotal)
     862        return false;
     863
     864    return true;
     865}
     866
     867/**
     868 * Destroys a VBOXCLIPBOARDFILEDATA structure.
     869 *
     870 * @param   pFileData           VBOXCLIPBOARDFILEDATA structure to destroy.
     871 */
     872void SharedClipboardURIFileDataDestroy(PVBOXCLIPBOARDFILEDATA pFileData)
     873{
     874    if (!pFileData)
     875        return;
     876
     877    if (pFileData->pvData)
     878    {
     879        Assert(pFileData->cbData);
     880        RTMemFree(pFileData->pvData);
     881        pFileData->pvData = NULL;
     882    }
     883}
     884
     885/**
     886 * Duplicates (allocates) a VBOXCLIPBOARDFILEDATA structure.
     887 *
     888 * @returns Duplicated VBOXCLIPBOARDFILEDATA structure on success.
     889 * @param   pFileData           VBOXCLIPBOARDFILEDATA to duplicate.
     890 */
     891PVBOXCLIPBOARDFILEDATA SharedClipboardURIFileDataDup(PVBOXCLIPBOARDFILEDATA pFileData)
     892{
     893    AssertPtrReturn(pFileData, NULL);
     894
     895    PVBOXCLIPBOARDFILEDATA pFileDataDup = (PVBOXCLIPBOARDFILEDATA)RTMemAllocZ(sizeof(VBOXCLIPBOARDFILEDATA));
     896    if (pFileDataDup)
     897    {
     898        *pFileDataDup = *pFileData;
     899
     900        if (pFileData->pvData)
     901        {
     902            pFileDataDup->pvData = RTMemDup(pFileData->pvData, pFileData->cbData);
     903            if (pFileDataDup->pvData)
     904                pFileDataDup->cbData = pFileDataDup->cbData;
     905        }
     906
     907        if (pFileData->pvChecksum)
     908        {
     909            pFileDataDup->pvChecksum = RTMemDup(pFileData->pvChecksum, pFileData->cbChecksum);
     910            if (pFileDataDup->pvChecksum)
     911                pFileDataDup->cbChecksum = pFileData->cbChecksum;
     912        }
     913    }
     914
     915    return pFileDataDup;
     916}
     917
     918/**
     919 * Returns whether given clipboard file data is valid or not.
     920 *
     921 * @returns \c true if valid, \c false if not.
     922 * @param   pFileData           Clipboard file data to validate.
     923 * @param   pDataHdr            Data header to use for validation.
     924 */
     925bool SharedClipboardURIFileDataIsValid(PVBOXCLIPBOARDFILEDATA pFileData, PVBOXCLIPBOARDDATAHDR pDataHdr)
     926{
     927    RT_NOREF(pFileData, pDataHdr);
     928    return true;
     929}
     930
     931/**
     932 * Initializes an URI object context.
     933 *
     934 * @returns VBox status code.
     935 * @param   pObjCtx             URI object context to initialize.
     936 */
     937int SharedClipboardURIObjCtxInit(PSHAREDCLIPBOARDCLIENTURIOBJCTX pObjCtx)
     938{
     939    AssertPtrReturn(pObjCtx, VERR_INVALID_POINTER);
     940
     941    LogFlowFuncEnter();
     942
     943    pObjCtx->pObj = NULL;
     944
     945    return VINF_SUCCESS;
     946}
     947
     948/**
     949 * Destroys an URI object context.
     950 *
     951 * @param   pObjCtx             URI object context to destroy.
     952 */
     953void SharedClipboardURIObjCtxDestroy(PSHAREDCLIPBOARDCLIENTURIOBJCTX pObjCtx)
     954{
     955    AssertPtrReturnVoid(pObjCtx);
     956
     957    LogFlowFuncEnter();
     958
     959    if (pObjCtx->pObj)
     960    {
     961        pObjCtx->pObj->Close();
     962        /* Note: Do *not* delete pObj here -- the associated URI list will do this. */
     963    }
     964
     965    pObjCtx->pObj = NULL;
     966}
     967
     968/**
     969 * Returns the URI object context's URI object.
     970 *
     971 * @returns Pointer to the URI object context's URI object.
     972 * @param   pObjCtx             URI object context to return the URI object for.
     973 */
     974SharedClipboardURIObject *SharedClipboardURIObjCtxGetObj(PSHAREDCLIPBOARDCLIENTURIOBJCTX pObjCtx)
     975{
     976    AssertPtrReturn(pObjCtx, NULL);
     977    return pObjCtx->pObj;
     978}
     979
     980/**
     981 * Returns if an URI object context is valid or not.
     982 *
     983 * @returns \c true if valid, \c false if not.
     984 * @param   pObjCtx             URI object context to check.
     985 */
     986bool SharedClipboardURIObjCtxIsValid(PSHAREDCLIPBOARDCLIENTURIOBJCTX pObjCtx)
     987{
     988    return (   pObjCtx
     989            && pObjCtx->pObj
     990            && pObjCtx->pObj->IsComplete() == false
     991            && pObjCtx->pObj->IsOpen());
     992}
     993
     994/**
     995 * Initializes an URI clipboard transfer struct.
     996 *
     997 * @returns VBox status code.
     998 * @param   enmDir              Transfer direction.
     999 * @param   ppTransfer          Where to return the created URI transfer struct.
     1000 *                              Must be destroyed by SharedClipboardURITransferDestroy().
     1001 */
     1002int SharedClipboardURITransferCreate(SHAREDCLIPBOARDURITRANSFERDIR enmDir, PSHAREDCLIPBOARDURITRANSFER *ppTransfer)
     1003{
     1004    AssertPtrReturn(ppTransfer, VERR_INVALID_POINTER);
     1005
     1006    LogFlowFuncEnter();
     1007
     1008    PSHAREDCLIPBOARDURITRANSFER pTransfer = (PSHAREDCLIPBOARDURITRANSFER)RTMemAlloc(sizeof(SHAREDCLIPBOARDURITRANSFER));
     1009    if (!pTransfer)
     1010        return VERR_NO_MEMORY;
     1011
     1012    int rc = VINF_SUCCESS;
     1013
     1014    pTransfer->State.enmDir = enmDir;
     1015
     1016    pTransfer->State.pHeader = NULL;
     1017    pTransfer->State.pMeta   = NULL;
     1018    pTransfer->pArea         = NULL; /* Will be created later if needed. */
     1019
     1020    pTransfer->Thread.hThread    = NIL_RTTHREAD;
     1021    pTransfer->Thread.fCancelled = false;
     1022    pTransfer->Thread.fStarted   = false;
     1023
     1024    pTransfer->pvUser = NULL;
     1025    pTransfer->cbUser = 0;
     1026
     1027    pTransfer->pURIList = new SharedClipboardURIList();
     1028    if (!pTransfer->pURIList)
     1029    {
     1030        RTMemFree(pTransfer);
     1031        return VERR_NO_MEMORY;
     1032    }
     1033
     1034    rc = SharedClipboardURIObjCtxInit(&pTransfer->ObjCtx);
     1035    if (RT_SUCCESS(rc))
     1036    {
     1037        *ppTransfer = pTransfer;
     1038    }
     1039
     1040    LogFlowFuncLeaveRC(rc);
     1041    return rc;
     1042}
     1043
     1044/**
     1045 * Destroys an URI clipboard transfer context struct.
     1046 *
     1047 * @returns VBox status code.
     1048 * @param   pURI                URI clipboard transfer to destroy.
     1049 */
     1050int SharedClipboardURITransferDestroy(PSHAREDCLIPBOARDURITRANSFER pTransfer)
     1051{
     1052    if (!pTransfer)
     1053        return VINF_SUCCESS;
     1054
     1055    LogFlowFuncEnter();
     1056
     1057    int rc = sharedClipboardURITransferThreadDestroy(pTransfer, 30 * 1000 /* Timeout in ms */);
     1058    if (RT_FAILURE(rc))
     1059        return rc;
     1060
     1061    SharedClipboardURIDataHdrDestroy(pTransfer->State.pHeader);
     1062    SharedClipboardMetaDataDestroy(pTransfer->State.pMeta);
     1063
     1064    if (pTransfer->pURIList)
     1065    {
     1066        delete pTransfer->pURIList;
     1067        pTransfer->pURIList = NULL;
     1068    }
     1069
     1070    if (pTransfer->pProvider)
     1071    {
     1072        delete pTransfer->pProvider;
     1073        pTransfer->pProvider = NULL;
     1074    }
     1075
     1076    SharedClipboardURIObjCtxDestroy(&pTransfer->ObjCtx);
     1077
     1078    RTMemFree(pTransfer);
     1079    pTransfer = NULL;
     1080
     1081    LogFlowFuncLeave();
     1082
     1083    return VINF_SUCCESS;
     1084}
     1085
     1086/**
     1087 * Prepares everything needed for a read / write transfer to begin.
     1088 *
     1089 * @returns VBox status code.
     1090 * @param   pTransfer           URI clipboard transfer to prepare.
     1091 */
     1092int SharedClipboardURITransferPrepare(PSHAREDCLIPBOARDURITRANSFER pTransfer)
     1093{
     1094    AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
     1095
     1096    LogFlowFuncEnter();
     1097
     1098    AssertPtrReturn(pTransfer->State.pMeta, VERR_WRONG_ORDER);
     1099    AssertPtrReturn(pTransfer->pURIList,    VERR_WRONG_ORDER);
     1100
     1101    PSHAREDCLIPBOARDMETADATA pMeta = pTransfer->State.pMeta;
     1102    AssertPtrReturn(pMeta, VERR_WRONG_ORDER);
     1103
     1104    int rc;
     1105
     1106    LogFlowFunc(("enmDir=%RU32\n", pTransfer->State.enmDir));
     1107
     1108    if (pTransfer->State.enmDir == SHAREDCLIPBOARDURITRANSFERDIR_READ)
     1109    {
     1110        rc = pTransfer->pURIList->SetFromURIData(SharedClipboardMetaDataRaw(pMeta),
     1111                                                 SharedClipboardMetaDataGetUsed(pMeta),
     1112                                                 SHAREDCLIPBOARDURILIST_FLAGS_NONE);
     1113        /** @todo Verify pvMetaFmt. */
     1114
     1115        sharedClipboardURITransferMetaDataDestroyInternal(pTransfer);
     1116    }
     1117    else if (pTransfer->State.enmDir == SHAREDCLIPBOARDURITRANSFERDIR_WRITE)
     1118    {
     1119        rc = pTransfer->pURIList->AppendURIPathsFromList((char *)SharedClipboardMetaDataRaw(pMeta),
     1120                                                         SharedClipboardMetaDataGetUsed(pMeta),
     1121                                                         SHAREDCLIPBOARDURILIST_FLAGS_KEEP_OPEN);
    10761122        if (RT_SUCCESS(rc))
    10771123        {
    1078             /** @todo Add checksum support. */
    1079 
    1080             if (!SharedClipboardURIDataHdrIsValid(&pTransfer->State.Header))
    1081                 rc = VERR_INVALID_PARAMETER;
    1082         }
     1124            PVBOXCLIPBOARDDATAHDR pHeader;
     1125            rc = SharedClipboardURIDataHdrAlloc(&pHeader);
     1126            if (RT_SUCCESS(rc))
     1127            {
     1128                /* The total size also contains the size of the meta data. */
     1129                uint64_t cbTotal  = pMeta->cbUsed;
     1130                         cbTotal += pTransfer->pURIList->GetTotalBytes();
     1131
     1132                pHeader->cbTotal  = cbTotal;
     1133                pHeader->cbMeta   = (uint32_t)SharedClipboardMetaDataGetUsed(pMeta);
     1134                pHeader->cObjects = pTransfer->pURIList->GetTotalCount();
     1135
     1136                SharedClipboardURIDataHdrDestroy(pTransfer->State.pHeader);
     1137
     1138                if (RT_SUCCESS(rc))
     1139                {
     1140                    LogFlowFunc(("Writing cbTotal=%RU64, cbMeta=%RU32, cObj=%RU64\n",
     1141                                 pHeader->cbTotal, pHeader->cbMeta, pHeader->cObjects));
     1142
     1143                    pTransfer->State.pHeader = pHeader;
     1144                }
     1145                else
     1146                    SharedClipboardURIDataHdrFree(pHeader);
     1147            }
     1148        }
     1149    }
     1150    else
     1151    {
     1152        rc = VERR_NOT_IMPLEMENTED;
     1153        AssertFailed();
     1154    }
     1155
     1156    if (RT_SUCCESS(rc))
     1157    {
     1158        /** @todo Add checksum support. */
    10831159    }
    10841160
    10851161    LogFlowFuncLeaveRC(rc);
    10861162    return rc;
     1163}
     1164
     1165/**
     1166 * Creates an URI provider for a given transfer.
     1167 *
     1168 * @returns VBox status code.
     1169 * @param   pTransfer           Transfer to create URI provider for.
     1170 * @param   pProviderCtx        Provider creation context to use for provider creation.
     1171 */
     1172int SharedClipboardURITransferProviderCreate(PSHAREDCLIPBOARDURITRANSFER pTransfer,
     1173                                             PSHAREDCLIPBOARDPROVIDERCREATIONCTX pProviderCtx)
     1174{
     1175    AssertPtrReturn(pTransfer,    VERR_INVALID_POINTER);
     1176    AssertPtrReturn(pProviderCtx, VERR_INVALID_POINTER);
     1177
     1178    LogFlowFuncEnter();
     1179
     1180    int rc;
     1181
     1182    pTransfer->pProvider = SharedClipboardProvider::Create(pProviderCtx);
     1183    if (pTransfer->pProvider)
     1184    {
     1185        rc = VINF_SUCCESS;
     1186    }
     1187    else
     1188        rc = VERR_NO_MEMORY;
     1189
     1190    LogFlowFuncLeaveRC(rc);
     1191    return rc;
     1192}
     1193
     1194/**
     1195 * Resets an clipboard URI transfer.
     1196 *
     1197 * @param   pTransfer           URI clipboard transfer to reset.
     1198 */
     1199void SharedClipboardURITransferReset(PSHAREDCLIPBOARDURITRANSFER pTransfer)
     1200{
     1201    AssertPtrReturnVoid(pTransfer);
     1202
     1203    LogFlowFuncEnter();
     1204
     1205    /** @todo Anything else to do here? */
     1206
     1207    if (pTransfer->pProvider)
     1208        pTransfer->pProvider->Reset();
     1209
     1210    if (pTransfer->pURIList)
     1211        pTransfer->pURIList->Clear();
     1212
     1213    SharedClipboardURIObjCtxDestroy(&pTransfer->ObjCtx);
     1214}
     1215
     1216/**
     1217 * Returns the clipboard area for a clipboard URI transfer.
     1218 *
     1219 * @returns Current clipboard area, or NULL if none.
     1220 * @param   pTransfer           URI clipboard transfer to return clipboard area for.
     1221 */
     1222SharedClipboardArea *SharedClipboardURITransferGetArea(PSHAREDCLIPBOARDURITRANSFER pTransfer)
     1223{
     1224    AssertPtrReturn(pTransfer, NULL);
     1225
     1226    return pTransfer->pArea;
     1227}
     1228
     1229/**
     1230 * Returns the current object context of a clipboard URI transfer.
     1231 *
     1232 * @returns Current object context, or NULL if none.
     1233 * @param   pTransfer           URI clipboard transfer to return object context for.
     1234 */
     1235PSHAREDCLIPBOARDCLIENTURIOBJCTX SharedClipboardURITransferGetCurrentObjCtx(PSHAREDCLIPBOARDURITRANSFER pTransfer)
     1236{
     1237    /* At the moment we only have one object context per transfer at a time. */
     1238    return &pTransfer->ObjCtx;
     1239}
     1240
     1241/**
     1242 * Returns the current URI object for a clipboard URI transfer.
     1243 *
     1244 * @returns Current URI object, or NULL if none.
     1245 * @param   pTransfer           URI clipboard transfer to return current URI object for.
     1246 */
     1247const SharedClipboardURIObject *SharedClipboardURITransferGetCurrentObject(PSHAREDCLIPBOARDURITRANSFER pTransfer)
     1248{
     1249    AssertPtrReturn(pTransfer, NULL);
     1250
     1251    if (pTransfer->pURIList)
     1252        return pTransfer->pURIList->First();
     1253
     1254    return NULL;
     1255}
     1256
     1257/**
     1258 * Returns the provider for a clipboard URI transfer.
     1259 *
     1260 * @returns Current provider, or NULL if none.
     1261 * @param   pTransfer           URI clipboard transfer to return provider for.
     1262 */
     1263SharedClipboardProvider *SharedClipboardURITransferGetProvider(PSHAREDCLIPBOARDURITRANSFER pTransfer)
     1264{
     1265    AssertPtrReturn(pTransfer, NULL);
     1266
     1267    return pTransfer->pProvider;
     1268}
     1269
     1270/**
     1271 * Returns the URI list for a clipboard URI transfer.
     1272 *
     1273 * @returns Pointer to URI list.
     1274 * @param   pTransfer           URI clipboard transfer to return URI list for.
     1275 */
     1276SharedClipboardURIList *SharedClipboardURITransferGetList(PSHAREDCLIPBOARDURITRANSFER pTransfer)
     1277{
     1278    AssertPtrReturn(pTransfer, NULL);
     1279
     1280    return pTransfer->pURIList;
     1281}
     1282
     1283/**
     1284 * Returns the current URI object for a clipboard URI transfer.
     1285 *
     1286 * @returns Pointer to URI object.
     1287 * @param   pTransfer           URI clipboard transfer to return URI object for.
     1288 */
     1289SharedClipboardURIObject *SharedClipboardURITransferGetObject(PSHAREDCLIPBOARDURITRANSFER pTransfer, uint64_t uIdx)
     1290{
     1291    AssertPtrReturn(pTransfer, NULL);
     1292
     1293    if (!pTransfer->pURIList)
     1294        return NULL;
     1295
     1296    return pTransfer->pURIList->At(uIdx);
     1297}
     1298
     1299/**
     1300 * Runs (starts) an URI transfer, either in synchronous or asynchronous (threaded) mode.
     1301 *
     1302 * @returns VBox status code.
     1303 * @param   pTransfer           URI clipboard transfer to run.
     1304 * @param   fAsync              Whether to run the transfer synchronously or asynchronously.
     1305 */
     1306int SharedClipboardURITransferRun(PSHAREDCLIPBOARDURITRANSFER pTransfer, bool fAsync)
     1307{
     1308    AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
     1309
     1310    int rc;
     1311
     1312    LogFlowFunc(("fAsync=%RTbool\n", fAsync));
     1313
     1314    if (fAsync)
     1315    {
     1316        rc = sharedClipboardURITransferThreadCreate(pTransfer);
     1317    }
     1318    else
     1319    {
     1320        if (pTransfer->State.enmDir == SHAREDCLIPBOARDURITRANSFERDIR_READ)
     1321            rc = SharedClipboardURITransferRead(pTransfer);
     1322        else if (pTransfer->State.enmDir == SHAREDCLIPBOARDURITRANSFERDIR_WRITE)
     1323            rc = SharedClipboardURITransferWrite(pTransfer);
     1324        else
     1325            rc = VERR_NOT_IMPLEMENTED;
     1326    }
     1327
     1328    LogFlowFuncLeaveRC(rc);
     1329    return rc;
     1330}
     1331
     1332/**
     1333 * Sets or unsets the callback table to be used for a clipboard URI transfer.
     1334 *
     1335 * @returns VBox status code.
     1336 * @param   pTransfer           URI clipboard transfer to set callbacks for.
     1337 * @param   pCallbacks          Pointer to callback table to set. Specify NULL to unset existing callbacks.
     1338 */
     1339void SharedClipboardURITransferSetCallbacks(PSHAREDCLIPBOARDURITRANSFER pTransfer, PSHAREDCLIPBOARDURITRANSFERCALLBACKS pCallbacks)
     1340{
     1341    AssertPtrReturnVoid(pTransfer);
     1342    /* pCallbacks might be NULL to unset callbacks. */
     1343
     1344    LogFlowFunc(("pCallbacks=%p\n", pCallbacks));
     1345
     1346    if (pCallbacks)
     1347    {
     1348        pTransfer->Callbacks = *pCallbacks;
     1349    }
     1350    else
     1351        RT_ZERO(pTransfer->Callbacks);
     1352}
     1353
     1354/**
     1355 * Creates a thread for a clipboard URI transfer.
     1356 *
     1357 * @returns VBox status code.
     1358 * @param   pTransfer           URI clipboard transfer to create thread for.
     1359 */
     1360static int sharedClipboardURITransferThreadCreate(PSHAREDCLIPBOARDURITRANSFER pTransfer)
     1361{
     1362    AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
     1363
     1364    PFNRTTHREAD pfnRTThread = NULL;
     1365
     1366    if (pTransfer->State.enmDir == SHAREDCLIPBOARDURITRANSFERDIR_READ)
     1367        pfnRTThread = sharedClipboardURITransferReadThread;
     1368    else if (pTransfer->State.enmDir == SHAREDCLIPBOARDURITRANSFERDIR_WRITE)
     1369        pfnRTThread = sharedClipboardURITransferWriteThread;
     1370
     1371    AssertPtrReturn(pfnRTThread, VERR_NOT_SUPPORTED);
     1372
     1373    /* Spawn a worker thread, so that we don't block the window thread for too long. */
     1374    int rc = RTThreadCreate(&pTransfer->Thread.hThread, pfnRTThread,
     1375                            pTransfer /* pvUser */, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE,
     1376                            "shclp");
     1377    if (RT_SUCCESS(rc))
     1378    {
     1379        int rc2 = RTThreadUserWait(pTransfer->Thread.hThread, 30 * 1000 /* Timeout in ms */);
     1380        AssertRC(rc2);
     1381
     1382        if (!pTransfer->Thread.fStarted) /* Did the thread fail to start? */
     1383            rc = VERR_GENERAL_FAILURE; /** @todo Find a better rc. */
     1384    }
     1385
     1386    LogFlowFuncLeaveRC(rc);
     1387    return rc;
     1388}
     1389
     1390/**
     1391 * Destroys a thread of a clipboard URI transfer.
     1392 *
     1393 * @returns VBox status code.
     1394 * @param   pTransfer           URI clipboard transfer to destroy thread for.
     1395 * @param   uTimeoutMs          Timeout (in ms) to wait for thread creation.
     1396 */
     1397static int sharedClipboardURITransferThreadDestroy(PSHAREDCLIPBOARDURITRANSFER pTransfer, RTMSINTERVAL uTimeoutMs)
     1398{
     1399    AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
     1400
     1401    if (pTransfer->Thread.hThread == NIL_RTTHREAD)
     1402        return VINF_SUCCESS;
     1403
     1404    int rcThread = VERR_WRONG_ORDER;
     1405    int rc = RTThreadWait(pTransfer->Thread.hThread, uTimeoutMs, &rcThread);
     1406
     1407    LogFlowFunc(("Waiting for thread resulted in %Rrc (thread exited with %Rrc)\n", rc, rcThread));
     1408
     1409    return rc;
     1410}
     1411
     1412/**
     1413 * Reads all URI objects using the connected provider.
     1414 *
     1415 * @returns VBox status code.
     1416 * @param   pTransfer           Transfer to read objects for.
     1417 */
     1418int SharedClipboardURITransferRead(PSHAREDCLIPBOARDURITRANSFER pTransfer)
     1419{
     1420    AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
     1421
     1422    LogFlowFuncEnter();
     1423
     1424    int rc = SharedClipboardURITransferMetaDataRead(pTransfer, NULL /* pcbRead */);
     1425    if (RT_SUCCESS(rc))
     1426    {
     1427        rc = SharedClipboardURITransferReadObjects(pTransfer);
     1428        if (RT_SUCCESS(rc))
     1429        {
     1430            if (pTransfer->Callbacks.pfnTransferComplete)
     1431            {
     1432                SHAREDCLIPBOARDURITRANSFERCALLBACKDATA callbackData = { pTransfer, pTransfer->Callbacks.pvUser };
     1433                pTransfer->Callbacks.pfnTransferComplete(&callbackData, rc);
     1434            }
     1435        }
     1436    }
     1437
     1438    if (RT_FAILURE(rc))
     1439    {
     1440        if (pTransfer->Callbacks.pfnTransferError)
     1441        {
     1442            SHAREDCLIPBOARDURITRANSFERCALLBACKDATA callbackData = { pTransfer, pTransfer->Callbacks.pvUser };
     1443            pTransfer->Callbacks.pfnTransferError(&callbackData, rc);
     1444        }
     1445    }
     1446
     1447    LogFlowFuncLeaveRC(rc);
     1448    return rc;
     1449}
     1450
     1451/**
     1452 * Reads all URI objects using the connected provider.
     1453 *
     1454 * @returns VBox status code.
     1455 * @param   pTransfer           Transfer to read objects for.
     1456 */
     1457int SharedClipboardURITransferReadObjects(PSHAREDCLIPBOARDURITRANSFER pTransfer)
     1458{
     1459    AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
     1460
     1461    LogFlowFuncEnter();
     1462
     1463    int rc = VERR_NOT_IMPLEMENTED;
     1464
     1465    LogFlowFuncLeaveRC(rc);
     1466    return rc;
     1467}
     1468
     1469/**
     1470 * Thread for transferring (reading) URI objects from source to the target.
     1471 * For target to source transfers we utilize our own IDataObject / IStream implementations.
     1472 *
     1473 * @returns VBox status code.
     1474 * @param   hThread             Thread handle.
     1475 * @param   pvUser              User arguments; is PSHAREDCLIPBOARDURITRANSFER.
     1476 */
     1477static int sharedClipboardURITransferReadThread(RTTHREAD hThread, void *pvUser)
     1478{
     1479    AssertPtrReturn(pvUser, VERR_INVALID_POINTER);
     1480
     1481    LogFlowFuncEnter();
     1482
     1483    /* At the moment we only support one transfer at a time. */
     1484    PSHAREDCLIPBOARDURITRANSFER pTransfer = (PSHAREDCLIPBOARDURITRANSFER)pvUser;
     1485    AssertPtr(pTransfer->pProvider);
     1486
     1487    int rc = VINF_SUCCESS;
     1488
     1489    if (RT_SUCCESS(rc))
     1490        pTransfer->Thread.fStarted = true;
     1491
     1492    int rc2 = RTThreadUserSignal(hThread);
     1493    const bool fSignalled = RT_SUCCESS(rc2);
     1494
     1495    if (RT_SUCCESS(rc))
     1496        rc = SharedClipboardURITransferRead(pTransfer);
     1497
     1498    if (!fSignalled)
     1499    {
     1500        rc2 = RTThreadUserSignal(hThread);
     1501        AssertRC(rc2);
     1502    }
     1503
     1504    LogFlowFuncLeaveRC(rc);
     1505    return rc;
     1506}
     1507
     1508/**
     1509 * Creates the internal meta data buffer of an URI clipboard transfer.
     1510 *
     1511 * @returns VBox status code.
     1512 * @param   pTransfer           URI clipboard transfer to create internal meta data for.
     1513 * @param   cbSize              Size (in bytes) of meta data buffer to create. An existing meta data buffer
     1514 *                              will be resized accordingly.
     1515 */
     1516static int sharedClipboardURITransferMetaDataCreateInternal(PSHAREDCLIPBOARDURITRANSFER pTransfer, uint32_t cbSize)
     1517{
     1518    int rc;
     1519
     1520    LogFlowFuncEnter();
     1521
     1522    if (pTransfer->State.pMeta == NULL)
     1523    {
     1524        pTransfer->State.pMeta = (PSHAREDCLIPBOARDMETADATA)RTMemAlloc(sizeof(SHAREDCLIPBOARDMETADATA));
     1525        if (pTransfer->State.pMeta)
     1526        {
     1527            /** @todo Make meta data format handling more flexible. */
     1528            rc = SharedClipboardMetaDataInit(pTransfer->State.pMeta, SHAREDCLIPBOARDMETADATAFMT_URI_LIST);
     1529        }
     1530        else
     1531            rc = VERR_NO_MEMORY;
     1532    }
     1533    else
     1534        rc = SharedClipboardMetaDataResize(pTransfer->State.pMeta, cbSize);
     1535
     1536    LogFlowFuncLeaveRC(rc);
     1537    return rc;
     1538}
     1539
     1540/**
     1541 * Destroys a clipboard URI transfer's internal meta data.
     1542 *
     1543 * @param   pTransfer           URI clipboard transfer to destroy internal meta data of.
     1544 */
     1545static void sharedClipboardURITransferMetaDataDestroyInternal(PSHAREDCLIPBOARDURITRANSFER pTransfer)
     1546{
     1547    if (!pTransfer->State.pMeta)
     1548        return;
     1549
     1550    LogFlowFuncEnter();
     1551
     1552    /* We're done processing the meta data, so just destroy it. */
     1553    SharedClipboardMetaDataDestroy(pTransfer->State.pMeta);
     1554
     1555    RTMemFree(pTransfer->State.pMeta);
     1556    pTransfer->State.pMeta = NULL;
     1557}
     1558
     1559/**
     1560 * Adds meta data for a clipboard URI transfer, internal version.
     1561 *
     1562 * @returns VBox status code.
     1563 * @param   pTransfer           URI clipboard transfer to set meta data for.
     1564 * @param   pvMeta              Pointer to meta data buffer.
     1565 * @param   cbMeta              Size (in bytes) of meta data buffer.
     1566 */
     1567static int sharedClipboardURITransferMetaDataAddInternal(PSHAREDCLIPBOARDURITRANSFER pTransfer,
     1568                                                         const void *pvMeta, uint32_t cbMeta)
     1569{
     1570    LogFlowFunc(("pvMeta=%p, cbMeta=%RU32\n", pvMeta, cbMeta));
     1571
     1572    int rc = SharedClipboardMetaDataAdd(pTransfer->State.pMeta, pvMeta, cbMeta);
     1573
     1574    LogFlowFuncLeaveRC(rc);
     1575    return rc;
     1576}
     1577
     1578/**
     1579 * Adds meta data for a clipboard URI transfer.
     1580 *
     1581 * @returns VBox status code.
     1582 * @param   pTransfer           URI clipboard transfer to set meta data for.
     1583 * @param   pvMeta              Pointer to meta data buffer.
     1584 * @param   cbMeta              Size (in bytes) of meta data buffer.
     1585 */
     1586int SharedClipboardURITransferMetaDataAdd(PSHAREDCLIPBOARDURITRANSFER pTransfer, const void *pvMeta, uint32_t cbMeta)
     1587{
     1588    AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
     1589
     1590    LogFlowFuncEnter();
     1591
     1592    int rc = sharedClipboardURITransferMetaDataCreateInternal(pTransfer, cbMeta);
     1593    if (RT_SUCCESS(rc))
     1594        rc = sharedClipboardURITransferMetaDataAddInternal(pTransfer, pvMeta, cbMeta);
     1595
     1596    LogFlowFuncLeaveRC(rc);
     1597    return rc;
     1598}
     1599
     1600/**
     1601 * Returns whether the meta data is in a complete state (e.g. completetely read / written) or not.
     1602 *
     1603 * @returns \c true if meta data is complete, \c false if not.
     1604 * @param   pTransfer           URI clipboard transfer to get completion status of meta data for.
     1605 */
     1606bool SharedClipboardURITransferMetaDataIsComplete(PSHAREDCLIPBOARDURITRANSFER pTransfer)
     1607{
     1608    AssertPtrReturn(pTransfer->State.pHeader, false);
     1609    AssertPtrReturn(pTransfer->State.pMeta,   false);
     1610
     1611    return SharedClipboardMetaDataGetUsed(pTransfer->State.pMeta) == pTransfer->State.pHeader->cbMeta;
    10871612}
    10881613
     
    10981623    AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
    10991624
     1625    LogFlowFuncEnter();
     1626
    11001627    /* Destroy any former meta data. */
    1101     SharedClipboardMetaDataDestroy(&pTransfer->State.Meta);
     1628    SharedClipboardMetaDataDestroy(pTransfer->State.pMeta);
    11021629
    11031630    uint32_t cbReadTotal = 0;
    11041631
    1105     int rc = pTransfer->pProvider->ReadDataHdr(&pTransfer->State.Header);
     1632    int rc = pTransfer->pProvider->ReadDataHdr(&pTransfer->State.pHeader);
    11061633    if (RT_SUCCESS(rc))
    11071634    {
     
    11111638        if (pvMeta)
    11121639        {
    1113             uint32_t cbMetaToRead = pTransfer->State.Header.cbMeta;
     1640            uint32_t cbMetaToRead = pTransfer->State.pHeader->cbMeta;
    11141641            while (cbMetaToRead)
    11151642            {
    11161643                uint32_t cbMetaRead;
    1117                 rc = pTransfer->pProvider->ReadDataChunk(&pTransfer->State.Header, pvMeta, cbMeta, &cbMetaRead);
     1644                rc = pTransfer->pProvider->ReadDataChunk(pTransfer->State.pHeader, pvMeta, cbMeta, 0 /* fFlags */, &cbMetaRead);
    11181645                if (RT_SUCCESS(rc))
    11191646                    rc = sharedClipboardURITransferMetaDataAddInternal(pTransfer, pvMeta, cbMeta);
     
    11571684    AssertPtr(pTransfer->pProvider);
    11581685
     1686    LogFlowFuncEnter();
     1687
     1688    AssertPtrReturn(pTransfer->State.pHeader, VERR_WRONG_ORDER);
     1689    AssertPtrReturn(pTransfer->State.pMeta,   VERR_WRONG_ORDER);
     1690
    11591691    uint32_t cbWrittenTotal = 0;
    11601692
    1161     int rc = pTransfer->pProvider->WriteDataHdr(&pTransfer->State.Header);
     1693    int rc = pTransfer->pProvider->WriteDataHdr(pTransfer->State.pHeader);
    11621694    if (RT_SUCCESS(rc))
    11631695    {
    11641696        /* Sanity. */
    1165         Assert(pTransfer->State.Header.cbMeta == pTransfer->State.Meta.cbUsed);
    1166 
    1167         uint32_t cbMetaToWrite = pTransfer->State.Header.cbMeta;
     1697        Assert(pTransfer->State.pHeader->cbMeta == pTransfer->State.pMeta->cbUsed);
     1698
     1699        uint32_t cbMetaToWrite = pTransfer->State.pHeader->cbMeta;
    11681700        while (cbMetaToWrite)
    11691701        {
    11701702            uint32_t cbMetaWritten;
    1171             rc = pTransfer->pProvider->WriteDataChunk(&pTransfer->State.Header, (uint8_t *)pTransfer->State.Meta.pvMeta + cbWrittenTotal,
    1172                                                       cbMetaToWrite, &cbMetaWritten, 0 /* fFlags */);
    1173             if (RT_SUCCESS(rc))
    1174             {
    1175                 cbWrittenTotal += cbMetaWritten;
    1176                 Assert(cbWrittenTotal <= pTransfer->State.Header.cbMeta);
    1177             }
     1703            rc = pTransfer->pProvider->WriteDataChunk(pTransfer->State.pHeader, (uint8_t *)pTransfer->State.pMeta->pvMeta + cbWrittenTotal,
     1704                                                      cbMetaToWrite, 0 /* fFlags */, &cbMetaWritten);
     1705            if (RT_FAILURE(rc))
     1706                break;
     1707
     1708            Assert(cbMetaToWrite >= cbMetaWritten);
     1709            cbMetaToWrite -= cbMetaWritten;
     1710
     1711            cbWrittenTotal += cbMetaWritten;
     1712            Assert(cbWrittenTotal <= pTransfer->State.pHeader->cbMeta);
    11781713        }
    11791714
     
    12031738    int rc = VINF_SUCCESS;
    12041739
    1205     AssertPtr(pTransfer->pProvider);
    1206 
    1207     while (!pTransfer->URIList.IsEmpty())
    1208     {
    1209         SharedClipboardURIObject *pObj = pTransfer->URIList.First();
     1740    AssertPtrReturn(pTransfer->pURIList,  VERR_WRONG_ORDER);
     1741    AssertPtrReturn(pTransfer->pProvider, VERR_WRONG_ORDER);
     1742
     1743    while (!pTransfer->pURIList->IsEmpty())
     1744    {
     1745        SharedClipboardURIObject *pObj = pTransfer->pURIList->First();
    12101746        AssertPtrBreakStmt(pObj, rc = VERR_INVALID_POINTER);
    12111747
     
    12141750            case SharedClipboardURIObject::Type_Directory:
    12151751            {
     1752                RTCString strPath = pObj->GetDestPathAbs();
     1753                LogFlowFunc(("strDir=%s (%zu), fMode=0x%x\n",
     1754                             strPath.c_str(), strPath.length(), pObj->GetMode()));
     1755
    12161756                VBOXCLIPBOARDDIRDATA dirData;
    1217                 RT_ZERO(dirData);
    1218 
    1219                 dirData.pszPath = RTStrDup(pObj->GetDestPathAbs().c_str());
    1220                 dirData.cbPath  = (uint32_t)strlen(dirData.pszPath);
     1757                SharedClipboardURIDirDataInit(&dirData);
     1758
     1759                dirData.pszPath = RTStrDup(strPath.c_str());
     1760                dirData.cbPath  = (uint32_t)strlen(dirData.pszPath) + 1 /* Include termination */;
    12211761
    12221762                rc = pTransfer->pProvider->WriteDirectory(&dirData);
     1763
     1764                SharedClipboardURIDirDataDestroy(&dirData);
    12231765                break;
    12241766            }
     
    12261768            case SharedClipboardURIObject::Type_File:
    12271769            {
     1770                AssertBreakStmt(pObj->IsOpen(), rc = VERR_INVALID_STATE);
     1771
     1772                RTCString strPath = pObj->GetDestPathAbs();
     1773
     1774                LogFlowFunc(("strFile=%s (%zu), cbSize=%RU64, fMode=0x%x\n", strPath.c_str(), strPath.length(),
     1775                             pObj->GetSize(), pObj->GetMode()));
     1776
    12281777                VBOXCLIPBOARDFILEHDR fileHdr;
    1229                 RT_ZERO(fileHdr);
    1230 
    1231                 fileHdr.pszFilePath = RTStrDup(pObj->GetDestPathAbs().c_str());
    1232                 fileHdr.cbFilePath  = (uint32_t)strlen(fileHdr.pszFilePath);
     1778                SharedClipboardURIFileHdrInit(&fileHdr);
     1779
     1780                fileHdr.pszFilePath = RTStrDup(strPath.c_str());
     1781                fileHdr.cbFilePath  = (uint32_t)strlen(fileHdr.pszFilePath) + 1 /* Include termination */;
    12331782                fileHdr.cbSize      = pObj->GetSize();
    12341783                fileHdr.fFlags      = 0;
     
    12361785
    12371786                rc = pTransfer->pProvider->WriteFileHdr(&fileHdr);
     1787                SharedClipboardURIFileHdrDestroy(&fileHdr);
     1788
    12381789                if (RT_FAILURE(rc))
    12391790                    break;
    12401791
    1241                 uint32_t cbData = _4K; /** @todo Improve. */
     1792                uint32_t cbData = _64K; /** @todo Improve. */
    12421793                void    *pvData = RTMemAlloc(cbData);
     1794
     1795                AssertPtrBreakStmt(pvData, rc = VERR_NO_MEMORY);
    12431796
    12441797                while (!pObj->IsComplete())
    12451798                {
    1246                     VBOXCLIPBOARDFILEDATA fileData;
    1247                     RT_ZERO(fileData);
    1248 
    12491799                    uint32_t cbRead;
    12501800                    rc = pObj->Read(pvData, cbData, &cbRead);
    12511801                    if (RT_SUCCESS(rc))
    12521802                    {
    1253                         fileData.pvData = pvData;
    1254                         fileData.cbData = cbRead;
    1255 
    1256                         uint32_t cbWritten;
    1257                         rc = pTransfer->pProvider->WriteFileData(&fileData, &cbWritten);
     1803                        rc = pTransfer->pProvider->WriteFileData(pvData, cbRead);
    12581804                    }
    12591805
     
    12611807                        break;
    12621808                }
     1809
     1810                RTMemFree(pvData);
     1811                pvData = NULL;
    12631812                break;
    12641813            }
     
    12731822
    12741823        /* Only remove current object on success. */
    1275         pTransfer->URIList.RemoveFirst();
     1824        pTransfer->pURIList->RemoveFirst();
    12761825    }
    12771826
  • trunk/src/VBox/GuestHost/SharedClipboard/clipboard-win.cpp

    r79178 r79267  
    833833#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
    834834/**
    835  * Main entry function for reading an URI transfer from a source.
     835 * Announces URI data (via IDataObject) to Windows.
     836 * This creates the necessary IDataObject + IStream implementations and initiates the actual transfers required for getting
     837 * the meta data. Whether or not the actual (file++) transfer(s) are happening is up to the user (at some point) later then.
    836838 *
    837839 * @returns VBox status code.
    838840 * @param   pWinCtx             Windows context to use.
    839841 * @param   pURICtx             URI context to use.
    840  * @param   pProviderCtx        Provider (creation) context to use.
    841  * @param   fFormats            Format to handle for the transfer.
    842  */
    843 int VBoxClipboardWinURIReadMain(PVBOXCLIPBOARDWINCTX pWinCtx, PSHAREDCLIPBOARDURICTX pURICtx,
    844                                 PSHAREDCLIPBOARDPROVIDERCREATIONCTX pProviderCtx, VBOXCLIPBOARDFORMATS fFormats)
     842 * @param   pTransfer           URI transfer to use.
     843 */
     844int VBoxClipboardWinURIAnnounce(PVBOXCLIPBOARDWINCTX pWinCtx, PSHAREDCLIPBOARDURICTX pURICtx,
     845                                PSHAREDCLIPBOARDURITRANSFER pTransfer)
    845846{
    846847    AssertPtrReturn(pURICtx, VERR_INVALID_POINTER);
    847     AssertPtrReturn(pProviderCtx, VERR_INVALID_POINTER);
    848 
    849     /* Sanity. */
    850     AssertReturn(fFormats & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST, VERR_NOT_SUPPORTED);
    851 
    852     LogFlowFunc(("fFormats=0x%x\n", fFormats));
    853 
    854     if (SharedClipboardURICtxMaximumTransfersReached(pURICtx))
    855     {
    856         LogRel(("Shared Clipboard: Only one transfer at a time supported (current %RU32 transfer(s) active), skipping\n",
    857                 SharedClipboardURICtxGetActiveTransfers(pURICtx)));
    858         return VERR_SHCLPB_MAX_TRANSFERS_REACHED;
    859     }
    860 
    861     /* We want to read from the source. */
    862     PSHAREDCLIPBOARDURITRANSFER pTransfer;
    863     int rc = SharedClipboardURITransferCreate(SHAREDCLIPBOARDURITRANSFERDIR_READ, pProviderCtx, &pTransfer);
    864     if (RT_SUCCESS(rc))
    865     {
    866         rc = SharedClipboardURICtxTransferAdd(pURICtx, pTransfer);
    867         if (RT_SUCCESS(rc))
    868         {
    869             SharedClipboardWinURITransferCtx *pWinURITransferCtx = new SharedClipboardWinURITransferCtx();
    870             if (pWinURITransferCtx)
     848    AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
     849
     850    LogFlowFuncEnter();
     851
     852    int rc;
     853
     854    SharedClipboardWinURITransferCtx *pWinURITransferCtx = new SharedClipboardWinURITransferCtx();
     855    if (pWinURITransferCtx)
     856    {
     857        pTransfer->pvUser = pWinURITransferCtx;
     858        pTransfer->cbUser = sizeof(SharedClipboardWinURITransferCtx);
     859
     860        pWinURITransferCtx->pDataObj = new VBoxClipboardWinDataObject(pTransfer);
     861        if (pWinURITransferCtx->pDataObj)
     862        {
     863            rc = pWinURITransferCtx->pDataObj->Init();
     864            if (RT_SUCCESS(rc))
    871865            {
    872                 pTransfer->pvUser = pWinURITransferCtx;
    873                 pTransfer->cbUser = sizeof(SharedClipboardWinURITransferCtx);
    874 
    875                 pWinURITransferCtx->pDataObj = new VBoxClipboardWinDataObject(pTransfer);
    876                 if (pWinURITransferCtx->pDataObj)
     866                VBoxClipboardWinClose();
     867                /* Note: Clipboard must be closed first before calling OleSetClipboard(). */
     868
     869                /** @todo There is a potential race between VBoxClipboardWinClose() and OleSetClipboard(),
     870                 *        where another application could own the clipboard (open), and thus the call to
     871                 *        OleSetClipboard() will fail. Needs (better) fixing. */
     872                for (unsigned uTries = 0; uTries < 3; uTries++)
    877873                {
    878                     rc = pWinURITransferCtx->pDataObj->Init();
    879                     if (RT_SUCCESS(rc))
     874                    HRESULT hr = OleSetClipboard(pWinURITransferCtx->pDataObj);
     875                    if (SUCCEEDED(hr))
    880876                    {
    881                         VBoxClipboardWinClose();
    882                         /* Note: Clipboard must be closed first before calling OleSetClipboard(). */
    883 
    884                         /** @todo There is a potential race between VBoxClipboardWinClose() and OleSetClipboard(),
    885                          *        where another application could own the clipboard (open), and thus the call to
    886                          *        OleSetClipboard() will fail. Needs (better) fixing. */
    887                         for (unsigned uTries = 0; uTries < 3; uTries++)
    888                         {
    889                             HRESULT hr = OleSetClipboard(pWinURITransferCtx->pDataObj);
    890                             if (SUCCEEDED(hr))
    891                             {
    892                                 /*
    893                                  * Calling OleSetClipboard() changed the clipboard owner, which in turn will let us receive
    894                                  * a WM_CLIPBOARDUPDATE message. To not confuse ourselves with our own clipboard owner changes,
    895                                  * save a new window handle and deal with it in WM_CLIPBOARDUPDATE.
    896                                  */
    897                                 pWinCtx->hWndClipboardOwnerUs = GetClipboardOwner();
    898                                 break;
    899                             }
    900                             else
    901                             {
    902                                 rc = VERR_ACCESS_DENIED; /** @todo Fudge; fix this. */
    903                                 LogRel(("Shared Clipboard: Failed with %Rhrc when setting data object to clipboard\n", hr));
    904                                 RTThreadSleep(100); /* Wait a bit. */
    905                             }
    906                         }
     877                        /*
     878                         * Calling OleSetClipboard() changed the clipboard owner, which in turn will let us receive
     879                         * a WM_CLIPBOARDUPDATE message. To not confuse ourselves with our own clipboard owner changes,
     880                         * save a new window handle and deal with it in WM_CLIPBOARDUPDATE.
     881                         */
     882                        pWinCtx->hWndClipboardOwnerUs = GetClipboardOwner();
     883                        break;
     884                    }
     885                    else
     886                    {
     887                        rc = VERR_ACCESS_DENIED; /** @todo Fudge; fix this. */
     888                        LogRel(("Shared Clipboard: Failed with %Rhrc when setting data object to clipboard\n", hr));
     889                        RTThreadSleep(100); /* Wait a bit. */
    907890                    }
    908891                }
    909                 else
    910                     rc = VERR_NO_MEMORY;
    911892            }
    912             else
    913                 rc = VERR_NO_MEMORY;
    914893        }
    915     }
     894        else
     895            rc = VERR_NO_MEMORY;
     896    }
     897    else
     898        rc = VERR_NO_MEMORY;
    916899
    917900    LogFlowFuncLeaveRC(rc);
     
    925908 * @returns VBox status code.
    926909 * @param   pDropFiles          Pointer to DROPFILES structure to convert.
    927  * @param   ppszData            Where to return the converted (allocated) data on success.
    928  *                              Must be free'd by the caller with RTMemFree().
    929  * @param   pcbData             Size (in bytes) of the allocated data returned.
    930  */
    931 int VBoxClipboardWinDropFilesToStringList(DROPFILES *pDropFiles, char **ppszbData, size_t *pcbData)
     910 * @param   pTransfer           Transfer where to add the string list to.
     911 */
     912int VBoxClipboardWinDropFilesToTransfer(DROPFILES *pDropFiles, PSHAREDCLIPBOARDURITRANSFER pTransfer)
    932913{
    933914    AssertPtrReturn(pDropFiles, VERR_INVALID_POINTER);
    934     AssertPtrReturn(ppszbData,  VERR_INVALID_POINTER);
    935     AssertPtrReturn(pcbData,    VERR_INVALID_POINTER);
     915    AssertPtrReturn(pTransfer,  VERR_INVALID_POINTER);
    936916
    937917    /* Do we need to do Unicode stuff? */
     
    1012992            LogRel(("Shared Clipboard: Adding guest file '%s'\n", pszFileUtf8));
    1013993
    1014             rc = RTStrAAppendExN(&pszFiles, 1 /* cPairs */, pszFileUtf8, cchFileUtf8);
     994            char    *pszFileURI;
     995            uint32_t cchFileURI;
     996            rc = SharedClipboardMetaDataConvertToFormat(pszFileUtf8, strlen(pszFileUtf8), SHAREDCLIPBOARDMETADATAFMT_URI_LIST,
     997                                                        (void **)&pszFileURI, &cchFileURI);
    1015998            if (RT_SUCCESS(rc))
    1016                 cchFiles += cchFileUtf8;
     999            {
     1000                LogFlowFunc(("\tURI is: %s (%RU32)\n", pszFileURI, cchFileURI));
     1001
     1002                rc = RTStrAAppendExN(&pszFiles, 1 /* cPairs */, pszFileURI, cchFileURI);
     1003                if (RT_SUCCESS(rc))
     1004                    cchFiles += cchFileURI;
     1005
     1006                RTStrFree(pszFileURI);
     1007            }
    10171008        }
    1018         else
    1019             LogFunc(("Error handling file entry #%u, rc=%Rrc\n", i, rc));
    10201009
    10211010        if (pszFileUtf8)
     
    10231012
    10241013        if (RT_FAILURE(rc))
     1014        {
     1015            LogFunc(("Error handling file entry #%u, rc=%Rrc\n", i, rc));
    10251016            break;
     1017        }
    10261018
    10271019        /* Add separation between filenames.
     
    10351027    {
    10361028        cchFiles += 1; /* Add string termination. */
    1037         uint32_t cbFiles = cchFiles * sizeof(char);
     1029        uint32_t cbFiles = cchFiles * sizeof(char); /* UTF-8. */
    10381030
    10391031        LogFlowFunc(("cFiles=%u, cchFiles=%RU32, cbFiles=%RU32, pszFiles=0x%p\n",
    10401032                     cFiles, cchFiles, cbFiles, pszFiles));
    10411033
    1042         /* Translate the list into URI elements. */
    1043         SharedClipboardURIList lstURI;
    1044         rc = lstURI.AppendNativePathsFromList(pszFiles, cbFiles,
    1045                                               SHAREDCLIPBOARDURILIST_FLAGS_ABSOLUTE_PATHS);
    1046         if (RT_SUCCESS(rc))
    1047         {
    1048             RTCString strRoot = lstURI.GetRootEntries();
    1049             size_t cbRoot = strRoot.length() + 1; /* Include termination */
    1050 
    1051             void *pvData = RTMemAlloc(cbRoot);
    1052             if (pvData)
    1053             {
    1054                 memcpy(pvData, strRoot.c_str(), cbRoot);
    1055 
    1056                 *ppszbData = (char *)pvData;
    1057                 *pcbData   = cbRoot;
    1058             }
    1059             else
    1060                 rc = VERR_NO_MEMORY;
    1061         }
     1034        rc = SharedClipboardURITransferMetaDataAdd(pTransfer, pszFiles, cbFiles);
    10621035    }
    10631036
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-uri.cpp

    r79176 r79267  
    4444
    4545/**
    46  * Destroys a VBOXCLIPBOARDDIRDATA structure.
    47  *
    48  * @param   pDirData            VBOXCLIPBOARDDIRDATA structure to destroy.
    49  */
    50 void SharedClipboardURIDirDataDestroy(PVBOXCLIPBOARDDIRDATA pDirData)
    51 {
    52     if (!pDirData)
    53         return;
    54 
    55     if (pDirData->pszPath)
    56     {
    57         Assert(pDirData->cbPath);
    58         RTStrFree(pDirData->pszPath);
    59         pDirData->pszPath = NULL;
    60     }
    61 }
    62 
    63 /**
    64  * Destroys a VBOXCLIPBOARDFILEHDR structure.
    65  *
    66  * @param   pFileHdr            VBOXCLIPBOARDFILEHDR structure to destroy.
    67  */
    68 void SharedClipboardURIFileHdrDestroy(PVBOXCLIPBOARDFILEHDR pFileHdr)
    69 {
    70     if (!pFileHdr)
    71         return;
    72 
    73     if (pFileHdr->pszFilePath)
    74     {
    75         Assert(pFileHdr->pszFilePath);
    76         RTStrFree(pFileHdr->pszFilePath);
    77         pFileHdr->pszFilePath = NULL;
    78     }
    79 }
    80 
    81 /**
    82  * Destroys a VBOXCLIPBOARDFILEDATA structure.
    83  *
    84  * @param   pFileData           VBOXCLIPBOARDFILEDATA structure to destroy.
    85  */
    86 void SharedClipboardURIFileDataDestroy(PVBOXCLIPBOARDFILEDATA pFileData)
    87 {
    88     if (!pFileData)
    89         return;
    90 
    91     if (pFileData->pvData)
    92     {
    93         Assert(pFileData->cbData);
    94         RTMemFree(pFileData->pvData);
    95         pFileData->pvData = NULL;
    96     }
    97 }
    98 
    99 /**
    10046 * Reads an URI data header from HGCM service parameters.
    10147 *
     
    10753int VBoxSvcClipboardURIReadDataHdr(uint32_t cParms, VBOXHGCMSVCPARM paParms[], PVBOXCLIPBOARDDATAHDR pDataHdr)
    10854{
    109     if (cParms != VBOX_SHARED_CLIPBOARD_CPARMS_WRITE_DATA_HDR)
    110         return VERR_INVALID_PARAMETER;
    111 
    112     RT_BZERO(pDataHdr, sizeof(VBOXCLIPBOARDDATAHDR));
    113 
    114     /* Note: Context ID (paParms[0]) not used yet. */
    115     int rc = HGCMSvcGetU32(&paParms[1], &pDataHdr->uFlags);
    116     if (RT_SUCCESS(rc))
    117         rc = HGCMSvcGetU32(&paParms[2], &pDataHdr->uScreenId);
    118     if (RT_SUCCESS(rc))
    119         rc = HGCMSvcGetU64(&paParms[3], &pDataHdr->cbTotal);
    120     if (RT_SUCCESS(rc))
    121         rc = HGCMSvcGetU32(&paParms[4], &pDataHdr->cbMeta);
    122     if (RT_SUCCESS(rc))
    123         rc = HGCMSvcGetPv(&paParms[5], &pDataHdr->pvMetaFmt, &pDataHdr->cbMetaFmt);
    124     if (RT_SUCCESS(rc))
    125         rc = HGCMSvcGetU32(&paParms[6], &pDataHdr->cbMetaFmt);
    126     if (RT_SUCCESS(rc))
    127         rc = HGCMSvcGetU64(&paParms[7], &pDataHdr->cObjects);
    128     if (RT_SUCCESS(rc))
    129         rc = HGCMSvcGetU32(&paParms[8], &pDataHdr->enmCompression);
    130     if (RT_SUCCESS(rc))
    131         rc = HGCMSvcGetU32(&paParms[9], (uint32_t *)&pDataHdr->enmChecksumType);
    132     if (RT_SUCCESS(rc))
    133         rc = HGCMSvcGetPv(&paParms[10], &pDataHdr->pvChecksum, &pDataHdr->cbChecksum);
    134     if (RT_SUCCESS(rc))
    135         rc = HGCMSvcGetU32(&paParms[11], &pDataHdr->cbChecksum);
    136 
    137     LogFlowFunc(("fFlags=0x%x, cbMeta=%RU32, cbTotalSize=%RU64, cObj=%RU64\n",
    138                  pDataHdr->uFlags, pDataHdr->cbMeta, pDataHdr->cbTotal, pDataHdr->cObjects));
    139 
    140     if (RT_SUCCESS(rc))
    141     {
    142         /** @todo Validate pvMetaFmt + cbMetaFmt. */
    143         /** @todo Validate header checksum. */
    144     }
     55    int rc;
     56
     57    if (cParms == VBOX_SHARED_CLIPBOARD_CPARMS_WRITE_DATA_HDR)
     58    {
     59        /* Note: Context ID (paParms[0]) not used yet. */
     60        rc = HGCMSvcGetU32(&paParms[1], &pDataHdr->uFlags);
     61        if (RT_SUCCESS(rc))
     62            rc = HGCMSvcGetU32(&paParms[2], &pDataHdr->uScreenId);
     63        if (RT_SUCCESS(rc))
     64            rc = HGCMSvcGetU64(&paParms[3], &pDataHdr->cbTotal);
     65        if (RT_SUCCESS(rc))
     66            rc = HGCMSvcGetU32(&paParms[4], &pDataHdr->cbMeta);
     67        if (RT_SUCCESS(rc))
     68            rc = HGCMSvcGetU32(&paParms[5], &pDataHdr->cbMetaFmt);
     69        if (RT_SUCCESS(rc))
     70            rc = HGCMSvcGetPv(&paParms[6], &pDataHdr->pvMetaFmt, &pDataHdr->cbMetaFmt);
     71        if (RT_SUCCESS(rc))
     72            rc = HGCMSvcGetU64(&paParms[7], &pDataHdr->cObjects);
     73        if (RT_SUCCESS(rc))
     74            rc = HGCMSvcGetU32(&paParms[8], &pDataHdr->enmCompression);
     75        if (RT_SUCCESS(rc))
     76            rc = HGCMSvcGetU32(&paParms[9], (uint32_t *)&pDataHdr->enmChecksumType);
     77        if (RT_SUCCESS(rc))
     78            rc = HGCMSvcGetU32(&paParms[10], &pDataHdr->cbChecksum);
     79        if (RT_SUCCESS(rc))
     80            rc = HGCMSvcGetPv(&paParms[11], &pDataHdr->pvChecksum, &pDataHdr->cbChecksum);
     81
     82        LogFlowFunc(("fFlags=0x%x, cbMeta=%RU32, cbTotalSize=%RU64, cObj=%RU64\n",
     83                     pDataHdr->uFlags, pDataHdr->cbMeta, pDataHdr->cbTotal, pDataHdr->cObjects));
     84
     85        if (RT_SUCCESS(rc))
     86        {
     87            /** @todo Validate pvMetaFmt + cbMetaFmt. */
     88            /** @todo Validate header checksum. */
     89        }
     90    }
     91    else
     92        rc = VERR_INVALID_PARAMETER;
    14593
    14694    LogFlowFuncLeaveRC(rc);
     
    158106int VBoxSvcClipboardURIReadDataChunk(uint32_t cParms, VBOXHGCMSVCPARM paParms[], PVBOXCLIPBOARDDATACHUNK pDataChunk)
    159107{
    160     if (cParms != VBOX_SHARED_CLIPBOARD_CPARMS_WRITE_DATA_CHUNK)
    161         return VERR_INVALID_PARAMETER;
    162 
    163     RT_BZERO(pDataChunk, sizeof(VBOXCLIPBOARDDATACHUNK));
    164 
    165     /* Note: Context ID (paParms[0]) not used yet. */
    166     int rc = HGCMSvcGetPv(&paParms[1], (void**)&pDataChunk->pvData, &pDataChunk->cbData);
    167     if (RT_SUCCESS(rc))
    168         rc = HGCMSvcGetU32(&paParms[2], &pDataChunk->cbData);
    169     if (RT_SUCCESS(rc))
    170         rc = HGCMSvcGetPv(&paParms[3], (void**)&pDataChunk->pvChecksum, &pDataChunk->cbChecksum);
    171     if (RT_SUCCESS(rc))
    172         rc = HGCMSvcGetU32(&paParms[4], &pDataChunk->cbChecksum);
    173 
    174     if (RT_SUCCESS(rc))
    175     {
    176         if (!SharedClipboardURIDataChunkIsValid(pDataChunk))
    177             rc = VERR_INVALID_PARAMETER;
    178     }
     108    int rc;
     109
     110    if (cParms == VBOX_SHARED_CLIPBOARD_CPARMS_WRITE_DATA_CHUNK)
     111    {
     112        /* Note: Context ID (paParms[0]) not used yet. */
     113        rc = HGCMSvcGetU32(&paParms[1], &pDataChunk->cbData);
     114        if (RT_SUCCESS(rc))
     115            rc = HGCMSvcGetPv(&paParms[2], &pDataChunk->pvData, &pDataChunk->cbData);
     116        if (RT_SUCCESS(rc))
     117            rc = HGCMSvcGetU32(&paParms[3], &pDataChunk->cbChecksum);
     118        if (RT_SUCCESS(rc))
     119            rc = HGCMSvcGetPv(&paParms[4], &pDataChunk->pvChecksum, &pDataChunk->cbChecksum);
     120
     121        if (RT_SUCCESS(rc))
     122        {
     123            if (!SharedClipboardURIDataChunkIsValid(pDataChunk))
     124                rc = VERR_INVALID_PARAMETER;
     125        }
     126    }
     127    else
     128        rc = VERR_INVALID_PARAMETER;
    179129
    180130    LogFlowFuncLeaveRC(rc);
     
    192142int VBoxSvcClipboardURIReadDir(uint32_t cParms, VBOXHGCMSVCPARM paParms[], PVBOXCLIPBOARDDIRDATA pDirData)
    193143{
    194     if (cParms != VBOX_SHARED_CLIPBOARD_CPARMS_WRITE_DIR)
    195         return VERR_INVALID_PARAMETER;
    196 
    197     RT_BZERO(pDirData, sizeof(VBOXCLIPBOARDDIRDATA));
    198 
    199     /* Note: Context ID (paParms[0]) not used yet. */
    200     int rc = HGCMSvcGetPv(&paParms[1], (void**)&pDirData->pszPath, &pDirData->cbPath);
    201     if (RT_SUCCESS(rc))
    202         rc = HGCMSvcGetU32(&paParms[2], &pDirData->cbPath);
    203     if (RT_SUCCESS(rc))
    204         rc = HGCMSvcGetU32(&paParms[3], &pDirData->fMode);
    205 
    206     LogFlowFunc(("pszPath=%s, cbPath=%RU32, fMode=0x%x\n", pDirData->pszPath, pDirData->cbPath, pDirData->fMode));
    207 
    208     if (RT_SUCCESS(rc))
    209     {
    210         if (!SharedClipboardURIDirDataIsValid(pDirData))
    211             rc = VERR_INVALID_PARAMETER;
    212     }
     144    int rc;
     145
     146    if (cParms == VBOX_SHARED_CLIPBOARD_CPARMS_WRITE_DIR)
     147    {
     148        /* Note: Context ID (paParms[0]) not used yet. */
     149        rc = HGCMSvcGetU32(&paParms[1], &pDirData->cbPath);
     150        if (RT_SUCCESS(rc))
     151            rc = HGCMSvcGetPv(&paParms[2], (void **)&pDirData->pszPath, &pDirData->cbPath);
     152        if (RT_SUCCESS(rc))
     153            rc = HGCMSvcGetU32(&paParms[3], &pDirData->fMode);
     154
     155        LogFlowFunc(("pszPath=%s, cbPath=%RU32, fMode=0x%x\n", pDirData->pszPath, pDirData->cbPath, pDirData->fMode));
     156
     157        if (RT_SUCCESS(rc))
     158        {
     159            if (!SharedClipboardURIDirDataIsValid(pDirData))
     160                rc = VERR_INVALID_PARAMETER;
     161        }
     162    }
     163    else
     164        rc = VERR_INVALID_PARAMETER;
    213165
    214166    LogFlowFuncLeaveRC(rc);
     
    226178int VBoxSvcClipboardURIReadFileHdr(uint32_t cParms, VBOXHGCMSVCPARM paParms[], PVBOXCLIPBOARDFILEHDR pFileHdr)
    227179{
    228     if (cParms != VBOX_SHARED_CLIPBOARD_CPARMS_WRITE_FILE_HDR)
    229         return VERR_INVALID_PARAMETER;
    230 
    231     RT_BZERO(pFileHdr, sizeof(VBOXCLIPBOARDFILEHDR));
    232 
    233     /* Note: Context ID (paParms[0]) not used yet. */
    234     int rc = HGCMSvcGetPv(&paParms[1], (void**)&pFileHdr->pszFilePath, &pFileHdr->cbFilePath);
    235     if (RT_SUCCESS(rc))
    236         rc = HGCMSvcGetU32(&paParms[2], &pFileHdr->cbFilePath);
    237     if (RT_SUCCESS(rc))
    238         rc = HGCMSvcGetU32(&paParms[3], &pFileHdr->fFlags);
    239     if (RT_SUCCESS(rc))
    240         rc = HGCMSvcGetU32(&paParms[4], &pFileHdr->fMode);
    241     if (RT_SUCCESS(rc))
    242         rc = HGCMSvcGetU64(&paParms[5], &pFileHdr->cbSize);
    243 
    244     LogFlowFunc(("pszPath=%s, cbPath=%RU32, fMode=0x%x, cbSize=%RU64\n",
    245                  pFileHdr->pszFilePath, pFileHdr->cbFilePath, pFileHdr->fMode, pFileHdr->cbSize));
     180    int rc;
     181
     182    if (cParms == VBOX_SHARED_CLIPBOARD_CPARMS_WRITE_FILE_HDR)
     183    {
     184        /* Note: Context ID (paParms[0]) not used yet. */
     185        rc = HGCMSvcGetU32(&paParms[1], &pFileHdr->cbFilePath);
     186        if (RT_SUCCESS(rc))
     187            rc = HGCMSvcGetPv(&paParms[2], (void **)&pFileHdr->pszFilePath, &pFileHdr->cbFilePath);
     188        if (RT_SUCCESS(rc))
     189            rc = HGCMSvcGetU32(&paParms[3], &pFileHdr->fFlags);
     190        if (RT_SUCCESS(rc))
     191            rc = HGCMSvcGetU32(&paParms[4], &pFileHdr->fMode);
     192        if (RT_SUCCESS(rc))
     193            rc = HGCMSvcGetU64(&paParms[5], &pFileHdr->cbSize);
     194
     195        LogFlowFunc(("pszPath=%s, cbPath=%RU32, fMode=0x%x, cbSize=%RU64\n",
     196                     pFileHdr->pszFilePath, pFileHdr->cbFilePath, pFileHdr->fMode, pFileHdr->cbSize));
     197    }
     198    else
     199        rc = VERR_INVALID_PARAMETER;
    246200
    247201    LogFlowFuncLeaveRC(rc);
     
    259213int VBoxSvcClipboardURIReadFileData(uint32_t cParms, VBOXHGCMSVCPARM paParms[], PVBOXCLIPBOARDFILEDATA pFileData)
    260214{
    261     if (cParms != VBOX_SHARED_CLIPBOARD_CPARMS_WRITE_FILE_DATA)
    262         return VERR_INVALID_PARAMETER;
    263 
    264     RT_BZERO(pFileData, sizeof(VBOXCLIPBOARDFILEDATA));
    265 
    266     /* Note: Context ID (paParms[0]) not used yet. */
    267     int rc = HGCMSvcGetPv(&paParms[1], (void**)&pFileData->pvData, &pFileData->cbData);
    268     if (RT_SUCCESS(rc))
    269         rc = HGCMSvcGetU32(&paParms[2], &pFileData->cbData);
    270     if (RT_SUCCESS(rc))
    271         rc = HGCMSvcGetPv(&paParms[3], (void**)&pFileData->pvChecksum, &pFileData->cbChecksum);
    272     if (RT_SUCCESS(rc))
    273         rc = HGCMSvcGetU32(&paParms[4], &pFileData->cbChecksum);
    274 
    275     LogFlowFunc(("pvData=0x%p, cbData=%RU32\n", pFileData->pvData, pFileData->cbData));
     215    int rc;
     216
     217    if (cParms == VBOX_SHARED_CLIPBOARD_CPARMS_WRITE_FILE_DATA)
     218    {
     219        /* Note: Context ID (paParms[0]) not used yet. */
     220        rc = HGCMSvcGetU32(&paParms[1], &pFileData->cbData);
     221        if (RT_SUCCESS(rc))
     222            rc = HGCMSvcGetPv(&paParms[2], &pFileData->pvData, &pFileData->cbData);
     223        if (RT_SUCCESS(rc))
     224            rc = HGCMSvcGetU32(&paParms[3], &pFileData->cbChecksum);
     225        if (RT_SUCCESS(rc))
     226            rc = HGCMSvcGetPv(&paParms[4], &pFileData->pvChecksum, &pFileData->cbChecksum);
     227
     228        LogFlowFunc(("pvData=0x%p, cbData=%RU32\n", pFileData->pvData, pFileData->cbData));
     229    }
     230    else
     231        rc = VERR_INVALID_PARAMETER;
    276232
    277233    LogFlowFuncLeaveRC(rc);
     
    308264
    309265    /* Check if we've the right mode set. */
    310     int rc = VERR_ACCESS_DENIED; /* Play safe. */
    311 
    312266    if (!vboxSvcClipboardURIMsgIsAllowed(vboxSvcClipboardGetMode(), u32Function))
    313         return rc;
     267        return VERR_ACCESS_DENIED;
    314268
    315269    /* A (valid) service extension is needed because VBoxSVC needs to keep track of the
     
    321275#endif
    322276        LogFunc(("Invalid / no service extension set, skipping URI handling\n"));
    323         rc = VERR_NOT_SUPPORTED;
    324     }
    325 
    326     if (RT_FAILURE(rc))
    327         return rc;
    328 
    329     const PSHAREDCLIPBOARDURITRANSFER pTransfer = SharedClipboardURICtxGetTransfer(&pClientData->URI, 0 /* Index */);
    330 
    331     bool fWrite = false;
    332 
    333     rc = VERR_INVALID_PARAMETER; /* Play safe. */
     277        return VERR_NOT_SUPPORTED;
     278    }
     279
     280    if (!SharedClipboardURICtxGetActiveTransfers(&pClientData->URI))
     281    {
     282        LogFunc(("No active transfers found\n"));
     283        return VERR_WRONG_ORDER;
     284    }
     285
     286    const uint32_t uTransferID = 0; /* Only one transfer is supported at the moment. */
     287
     288    const PSHAREDCLIPBOARDURITRANSFER pTransfer = SharedClipboardURICtxGetTransfer(&pClientData->URI, uTransferID);
     289    if (!pTransfer)
     290    {
     291        LogFunc(("Transfer with ID %RU32 not found\n", uTransferID));
     292        return VERR_WRONG_ORDER;
     293    }
     294
     295    bool fDispatchToProvider = false; /* Whether to (also) dispatch the HCGCM data to the transfer provider. */
     296
     297    int rc = VERR_INVALID_PARAMETER; /* Play safe. */
    334298
    335299    switch (u32Function)
     
    337301        case VBOX_SHARED_CLIPBOARD_GUEST_FN_READ_DATA_HDR:
    338302        {
    339             LogFlowFunc(("VBOX_SHARED_CLIPBOARD_FN_READ_DATA_HDR\n"));
    340             if (cParms == VBOX_SHARED_CLIPBOARD_CPARMS_READ_DATA_HDR)
    341             {
    342                 bool fDetach = false;
    343 
    344                 if (RT_SUCCESS(rc))
    345                 {
    346                     // pTransfer->Area. parms.uID
    347 
    348                     /** @todo Detach if header / meta size is 0. */
    349                 }
    350 
    351                 /* Do we need to detach again because we're done? */
    352                 if (fDetach)
    353                     vboxSvcClipboardURIAreaDetach(&pClientData->State, pTransfer);
    354             }
     303            LogFlowFunc(("VBOX_SHARED_CLIPBOARD_GUEST_FN_READ_DATA_HDR\n"));
    355304            break;
    356305        }
     
    358307        case VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_DATA_HDR:
    359308        {
    360 
    361             RT_BREAKPOINT();
    362 
    363             if (   u32Function == VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_DATA_HDR
    364                 && SharedClipboardURICtxMaximumTransfersReached(&pClientData->URI))
    365             {
    366                 rc = VERR_SHCLPB_MAX_TRANSFERS_REACHED;
    367                 break;
    368             }
    369 
    370             fWrite = true;
     309            LogFlowFunc(("VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_DATA_HDR\n"));
     310
     311            VBOXCLIPBOARDDATAHDR dataHdr;
     312            rc = SharedClipboardURIDataHdrInit(&dataHdr);
     313            if (RT_SUCCESS(rc))
     314                rc = VBoxSvcClipboardURIReadDataHdr(cParms, paParms, &dataHdr);
     315            if (RT_SUCCESS(rc))
     316            {
     317                AssertBreakStmt(pTransfer->State.pHeader == NULL, rc = VERR_WRONG_ORDER);
     318                pTransfer->State.pHeader = SharedClipboardURIDataHdrDup(&dataHdr);
     319                if (pTransfer->State.pHeader)
     320                {
     321                    LogFlowFunc(("Meta data size is %RU32\n", pTransfer->State.pHeader->cbMeta));
     322                }
     323                else
     324                    rc = VERR_NO_MEMORY;
     325            }
     326            break;
     327        }
     328
     329        case VBOX_SHARED_CLIPBOARD_GUEST_FN_READ_DATA_CHUNK:
     330        {
     331            LogFlowFunc(("VBOX_SHARED_CLIPBOARD_GUEST_FN_READ_DATA_CHUNK\n"));
    371332            break;
    372333        }
     
    374335        case VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_DATA_CHUNK:
    375336        {
    376             LogFlowFunc(("VBOX_SHARED_CLIPBOARD_FN_WRITE_DATA_CHUNK\n"));
    377 
    378             if (!SharedClipboardURICtxGetActiveTransfers(&pClientData->URI))
    379             {
    380                 rc = VERR_WRONG_ORDER;
    381                 break;
    382             }
    383 
    384            fWrite = true;
    385 #if 0
     337            LogFlowFunc(("VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_DATA_CHUNK\n"));
     338
     339            VBOXCLIPBOARDDATACHUNK dataChunk;
     340            rc = SharedClipboardURIDataChunkInit(&dataChunk);
    386341            if (RT_SUCCESS(rc))
    387             {
    388                 /** @todo Validate checksum. */
    389                 rc = SharedClipboardMetaDataAdd(&pTransfer->Meta, data.pvData, data.cbData);
     342                rc = VBoxSvcClipboardURIReadDataChunk(cParms, paParms, &dataChunk);
     343            if (RT_SUCCESS(rc))
     344            {
     345                AssertPtrBreakStmt(pTransfer->State.pHeader, rc = VERR_WRONG_ORDER);
     346
     347                rc = SharedClipboardURITransferMetaDataAdd(pTransfer, dataChunk.pvData, dataChunk.cbData);
    390348                if (   RT_SUCCESS(rc)
    391                     && SharedClipboardMetaDataGetUsed(&pTransfer->Meta) == pTransfer->Header.cbMeta) /* Meta data transfer complete? */
    392                 {
    393                     if (RT_SUCCESS(rc))
    394                     {
    395 
    396                     }
    397 
    398                     /* We're done processing the meta data, so just destroy it. */
    399                     SharedClipboardMetaDataDestroy(&pTransfer->Meta);
    400                 }
    401             }
    402 #endif
     349                    && SharedClipboardURITransferMetaDataIsComplete(pTransfer)) /* Meta data transfer complete? */
     350                {
     351                    rc = SharedClipboardURITransferPrepare(pTransfer);
     352                }
     353            }
     354
    403355            break;
    404356        }
     
    406358        case VBOX_SHARED_CLIPBOARD_GUEST_FN_READ_DIR:
    407359        {
    408             LogFlowFunc(("VBOX_SHARED_CLIPBOARD_FN_READ_DIR\n"));
     360            LogFlowFunc(("VBOX_SHARED_CLIPBOARD_GUEST_FN_READ_DIR\n"));
    409361            if (cParms == VBOX_SHARED_CLIPBOARD_CPARMS_READ_DIR)
    410362            {
     
    432384        case VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_DIR:
    433385        {
    434             LogFlowFunc(("VBOX_SHARED_CLIPBOARD_FN_WRITE_DIR\n"));
    435 
    436             if (!SharedClipboardURICtxGetActiveTransfers(&pClientData->URI))
    437             {
    438                 rc = VERR_WRONG_ORDER;
    439                 break;
    440             }
    441 
    442 #if 0
     386            LogFlowFunc(("VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_DIR\n"));
     387
     388            VBOXCLIPBOARDDIRDATA dirData;
     389            rc = VBoxSvcClipboardURIReadDir(cParms, paParms, &dirData);
    443390            if (RT_SUCCESS(rc))
    444391            {
     
    447394
    448395                const char *pszCacheDir = pArea->GetDirAbs();
    449                 char *pszDir = RTPathJoinA(pszCacheDir, data.pszPath);
     396                char *pszDir = RTPathJoinA(pszCacheDir, dirData.pszPath);
    450397                if (pszDir)
    451398                {
    452399                    LogFlowFunc(("pszDir=%s\n", pszDir));
    453400
    454                     rc = RTDirCreateFullPath(pszDir, data.fMode);
     401                    rc = RTDirCreateFullPath(pszDir, dirData.fMode);
    455402                    if (RT_SUCCESS(rc))
    456403                    {
     
    465412                    rc = VERR_NO_MEMORY;
    466413            }
    467 #endif
    468414            break;
    469415        }
     
    471417        case VBOX_SHARED_CLIPBOARD_GUEST_FN_READ_FILE_HDR:
    472418        {
    473             LogFlowFunc(("VBOX_SHARED_CLIPBOARD_FN_READ_FILE_HDR\n"));
     419            LogFlowFunc(("VBOX_SHARED_CLIPBOARD_GUEST_FN_READ_FILE_HDR\n"));
    474420            if (cParms == VBOX_SHARED_CLIPBOARD_CPARMS_READ_FILE_HDR)
    475421            {
    476                 if (!SharedClipboardURICtxGetActiveTransfers(&pClientData->URI))
    477                 {
    478                     rc = VERR_WRONG_ORDER;
    479                     break;
    480                 }
    481 
    482422                VBOXCLIPBOARDFILEHDR hdr;
    483423                rc = VBoxClipboardSvcImplURIReadFileHdr(pClientData, &hdr);
     
    499439        case VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_FILE_HDR:
    500440        {
    501             LogFlowFunc(("VBOX_SHARED_CLIPBOARD_FN_WRITE_FILE_HDR\n"));
    502 
    503                 if (!SharedClipboardURICtxGetActiveTransfers(&pClientData->URI))
    504                 {
    505                     rc = VERR_WRONG_ORDER;
    506                     break;
    507                 }
    508 
    509 #if 0
     441            LogFlowFunc(("VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_FILE_HDR\n"));
     442
     443            if (!SharedClipboardURIObjCtxIsValid(SharedClipboardURITransferGetCurrentObjCtx(pTransfer)))
     444            {
     445                pTransfer->ObjCtx.pObj = new SharedClipboardURIObject(SharedClipboardURIObject::Type_File);
     446                if (pTransfer->ObjCtx.pObj) /** @todo Can this throw? */
     447                {
     448                    rc = VINF_SUCCESS;
     449                }
     450                else
     451                    rc = VERR_NO_MEMORY;
     452            }
     453            else /* There still is another object being processed? */
     454                rc = VERR_WRONG_ORDER;
     455
     456            if (RT_FAILURE(rc))
     457                break;
     458
     459            VBOXCLIPBOARDFILEHDR fileHdr;
     460            rc = VBoxSvcClipboardURIReadFileHdr(cParms, paParms, &fileHdr);
     461            if (RT_SUCCESS(rc))
     462            {
     463                SharedClipboardArea *pArea = SharedClipboardURITransferGetArea(pTransfer);
     464                AssertPtrBreakStmt(pArea, rc = VERR_WRONG_ORDER);
     465
     466                const char *pszCacheDir = pArea->GetDirAbs();
     467
     468    RT_BREAKPOINT();
     469
     470                char pszPathAbs[RTPATH_MAX];
     471                rc = RTPathJoin(pszPathAbs, sizeof(pszPathAbs), pszCacheDir, fileHdr.pszFilePath);
    510472                if (RT_SUCCESS(rc))
    511473                {
    512                     if (!vboxSvcClipboardURIFileHdrIsValid(&data, &pTransfer->Header))
    513                     {
    514                         rc = VERR_INVALID_PARAMETER;
    515                     }
    516                     else
    517                     {
    518                         if (pTransfer->ObjCtx.pObj == NULL)
    519                         {
    520                             pTransfer->ObjCtx.pObj = new SharedClipboardURIObject(SharedClipboardURIObject::Type_File);
    521                             if (!pTransfer->ObjCtx.pObj) /** @todo Can this throw? */
    522                                 rc = VERR_NO_MEMORY;
    523                         }
    524                         else /* There still is another object being processed? */
    525                            rc = VERR_WRONG_ORDER;
    526                     }
    527                 }
    528 
    529                 if (RT_SUCCESS(rc))
    530                 {
    531                     SharedClipboardArea *pArea = SharedClipboardURITransferGetArea(pTransfer);
    532                     AssertPtrBreakStmt(pArea, rc = VERR_INVALID_POINTER);
    533 
    534                     const char *pszCacheDir = pArea->GetDirAbs();
    535 
    536                     char pszPathAbs[RTPATH_MAX];
    537                     rc = RTPathJoin(pszPathAbs, sizeof(pszPathAbs), pszCacheDir, data.pszFilePath);
     474                    rc = SharedClipboardPathSanitize(pszPathAbs, sizeof(pszPathAbs));
    538475                    if (RT_SUCCESS(rc))
    539476                    {
    540                         rc = SharedClipboardPathSanitize(pszPathAbs, sizeof(pszPathAbs));
     477                        PSHAREDCLIPBOARDCLIENTURIOBJCTX pObjCtx = SharedClipboardURITransferGetCurrentObjCtx(pTransfer);
     478                        AssertPtrBreakStmt(pObjCtx, VERR_INVALID_POINTER);
     479
     480                        SharedClipboardURIObject *pObj = pObjCtx->pObj;
     481                        AssertPtrBreakStmt(pObj, VERR_INVALID_POINTER);
     482
     483                        LogFlowFunc(("pszFile=%s\n", pszPathAbs));
     484
     485                        /** @todo Add sparse file support based on fFlags? (Use Open(..., fFlags | SPARSE). */
     486                        rc = pObj->OpenFileEx(pszPathAbs, SharedClipboardURIObject::View_Target,
     487                                              RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_DENY_WRITE,
     488                                              (fileHdr.fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRUSR | RTFS_UNIX_IWUSR);
    541489                        if (RT_SUCCESS(rc))
    542490                        {
    543                             SharedClipboardURIObject *pObj = SharedClipboardURITransferGetObject(pTransfer, 0 /* Index */);
    544                             AssertPtrBreakStmt(pObj, VERR_INVALID_POINTER);
    545 
    546                             /** @todo Add sparse file support based on fFlags? (Use Open(..., fFlags | SPARSE). */
    547                             rc = pObj->OpenFileEx(pszPathAbs, SharedClipboardURIObject::View_Target,
    548                                                   RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_DENY_WRITE,
    549                                                   (data.fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRUSR | RTFS_UNIX_IWUSR);
    550                             if (RT_SUCCESS(rc))
     491                            rc = pObj->SetSize(fileHdr.cbSize);
     492
     493                            /** @todo Unescape path before printing. */
     494                            LogRel2(("Clipboard: Transferring guest file '%s' to host (%RU64 bytes, mode 0x%x)\n",
     495                                     pObj->GetDestPathAbs().c_str(), pObj->GetSize(), pObj->GetMode()));
     496
     497                            if (pObj->IsComplete()) /* 0-byte file? We're done already. */
    551498                            {
    552                                 rc = pObj->SetSize(data.cbSize);
    553 
    554                                 /** @todo Unescape path before printing. */
    555                                 LogRel2(("Clipboard: Transferring guest file '%s' to host (%RU64 bytes, mode 0x%x)\n",
    556                                          pObj->GetDestPathAbs().c_str(), pObj->GetSize(), pObj->GetMode()));
    557 
    558                                 if (pObj->IsComplete()) /* 0-byte file? We're done already. */
    559                                 {
    560                                     /** @todo Sanitize path. */
    561                                     LogRel2(("Clipboard: Transferring guest file '%s' (0 bytes) to host complete\n",
    562                                              pObj->GetDestPathAbs().c_str()));
    563 
    564                                     SharedClipboardURIObjCtxUninit(&pTransfer->ObjCtx);
    565                                 }
    566 
    567                                 /* Add for having a proper rollback. */
    568                                 int rc2 = pArea->AddFile(pszPathAbs);
    569                                 AssertRC(rc2);
     499                                /** @todo Sanitize path. */
     500                                LogRel2(("Clipboard: Transferring guest file '%s' (0 bytes) to host complete\n",
     501                                         pObj->GetDestPathAbs().c_str()));
     502
     503                                SharedClipboardURIObjCtxDestroy(&pTransfer->ObjCtx);
    570504                            }
    571                             else
    572                                 LogRel(("Clipboard: Error opening/creating guest file '%s' on host, rc=%Rrc\n", pszPathAbs, rc));
     505
     506                            /* Add for having a proper rollback. */
     507                            int rc2 = pArea->AddFile(pszPathAbs);
     508                            AssertRC(rc2);
    573509                        }
     510                        else
     511                            LogRel(("Clipboard: Error opening/creating guest file '%s' on host, rc=%Rrc\n", pszPathAbs, rc));
    574512                    }
    575             }
    576 #endif
     513                }
     514            }
    577515            break;
    578516        }
     
    609547            LogFlowFunc(("VBOX_SHARED_CLIPBOARD_FN_WRITE_FILE_DATA\n"));
    610548
    611             if (!SharedClipboardURICtxGetActiveTransfers(&pClientData->URI))
     549            if (!SharedClipboardURIObjCtxIsValid(&pTransfer->ObjCtx))
    612550            {
    613551                rc = VERR_WRONG_ORDER;
     
    615553            }
    616554
    617 #if 0
     555            VBOXCLIPBOARDFILEDATA fileData;
     556            rc = VBoxSvcClipboardURIReadFileData(cParms, paParms, &fileData);
    618557            if (RT_SUCCESS(rc))
    619558            {
    620                 if (!vboxSvcClipboardURIFileDataIsValid(&data, &pTransfer->Header))
    621                     rc = VERR_INVALID_PARAMETER;
    622 
    623                 if (!SharedClipboardURIObjCtxIsValid(&pTransfer->ObjCtx))
    624                     rc = VERR_WRONG_ORDER;
    625             }
    626 
    627             if (RT_SUCCESS(rc))
    628             {
    629                 SharedClipboardURIObject *pObj = SharedClipboardURIObjCtxGetObj(&pTransfer->ObjCtx);
     559                PSHAREDCLIPBOARDCLIENTURIOBJCTX pObjCtx = SharedClipboardURITransferGetCurrentObjCtx(pTransfer);
     560                AssertPtrBreakStmt(pObjCtx, VERR_INVALID_POINTER);
     561
     562                SharedClipboardURIObject *pObj = pObjCtx->pObj;
    630563                AssertPtrBreakStmt(pObj, VERR_INVALID_POINTER);
    631564
    632565                uint32_t cbWritten;
    633                 rc = pObj->Write(data.pvData, data.cbData, &cbWritten);
     566                rc = pObj->Write(fileData.pvData, fileData.cbData, &cbWritten);
    634567                if (RT_SUCCESS(rc))
    635568                {
    636                     Assert(cbWritten <= data.cbData);
    637                     if (cbWritten < data.cbData)
     569                    Assert(cbWritten <= fileData.cbData);
     570                    if (cbWritten < fileData.cbData)
    638571                    {
    639572                        /** @todo What to do when the host's disk is full? */
     
    643576                    if (   pObj->IsComplete()
    644577                        || RT_FAILURE(rc))
    645                         SharedClipboardURIObjCtxUninit(&pTransfer->ObjCtx);
     578                        SharedClipboardURIObjCtxDestroy(&pTransfer->ObjCtx);
    646579                }
    647580                else
    648581                    LogRel(("Clipboard: Error writing guest file data for '%s', rc=%Rrc\n", pObj->GetDestPathAbs().c_str(), rc));
    649582            }
    650 #endif
    651583            break;
    652584        }
     
    667599    }
    668600
     601    if (fDispatchToProvider)
     602        rc = VINF_SUCCESS;
     603
    669604    if (RT_SUCCESS(rc))
    670605    {
    671         if (fWrite)
     606        if (fDispatchToProvider)
    672607        {
    673608            SHAREDCLIPBOARDPROVIDERWRITEPARMS writeParms;
     
    740675        return VERR_NO_MEMORY;
    741676
    742     VBOXCLIPBOARDEXTAREAPARMS parms;
    743     RT_ZERO(parms);
    744 
    745     parms.uID                  = NIL_SHAREDCLIPBOARDAREAID;
    746     parms.u.fn_register.pvData = SharedClipboardMetaDataMutableRaw(&pTransfer->State.Meta);
    747     parms.u.fn_register.cbData = (uint32_t)SharedClipboardMetaDataGetUsed(&pTransfer->State.Meta);
    748 
    749     /* As the meta data is now complete, register a new clipboard on the host side. */
    750     int rc = g_pfnExtension(g_pvExtension, VBOX_CLIPBOARD_EXT_FN_AREA_REGISTER, &parms, sizeof(parms));
    751     if (RT_SUCCESS(rc))
    752     {
    753         /* Note: Do *not* specify SHAREDCLIPBOARDAREA_OPEN_FLAGS_MUST_NOT_EXIST as flags here, as VBoxSVC took care of the
    754          *       clipboard area creation already. */
    755         rc = pTransfer->pArea->OpenTemp(parms.uID /* Area ID */,
    756                                         SHAREDCLIPBOARDAREA_OPEN_FLAGS_NONE);
    757     }
    758 
    759     LogFlowFunc(("Registered new clipboard area (%RU32) by client %RU32 with rc=%Rrc\n",
    760                  parms.uID, pClientState->u32ClientID, rc));
     677    int rc;
     678
     679    if (g_pfnExtension)
     680    {
     681        VBOXCLIPBOARDEXTAREAPARMS parms;
     682        RT_ZERO(parms);
     683
     684        parms.uID = NIL_SHAREDCLIPBOARDAREAID;
     685
     686        if (pTransfer->State.pMeta)
     687        {
     688            parms.u.fn_register.pvData = SharedClipboardMetaDataMutableRaw(pTransfer->State.pMeta);
     689            parms.u.fn_register.cbData = (uint32_t)SharedClipboardMetaDataGetUsed(pTransfer->State.pMeta);
     690        }
     691
     692        /* As the meta data is now complete, register a new clipboard on the host side. */
     693        rc = g_pfnExtension(g_pvExtension, VBOX_CLIPBOARD_EXT_FN_AREA_REGISTER, &parms, sizeof(parms));
     694        if (RT_SUCCESS(rc))
     695        {
     696            /* Note: Do *not* specify SHAREDCLIPBOARDAREA_OPEN_FLAGS_MUST_NOT_EXIST as flags here, as VBoxSVC took care of the
     697             *       clipboard area creation already. */
     698            rc = pTransfer->pArea->OpenTemp(parms.uID /* Area ID */,
     699                                            SHAREDCLIPBOARDAREA_OPEN_FLAGS_NONE);
     700        }
     701
     702        LogFlowFunc(("Registered new clipboard area (%RU32) by client %RU32 with rc=%Rrc\n",
     703                     parms.uID, pClientState->u32ClientID, rc));
     704    }
     705    else
     706        rc = VERR_NOT_SUPPORTED;
    761707
    762708    LogFlowFuncLeaveRC(rc);
     
    778724        return VINF_SUCCESS;
    779725
    780     VBOXCLIPBOARDEXTAREAPARMS parms;
    781     RT_ZERO(parms);
    782 
    783     parms.uID = pTransfer->pArea->GetID();
    784 
    785     int rc = g_pfnExtension(g_pvExtension, VBOX_CLIPBOARD_EXT_FN_AREA_UNREGISTER, &parms, sizeof(parms));
    786     if (RT_SUCCESS(rc))
    787     {
    788         rc = pTransfer->pArea->Close();
    789         if (RT_SUCCESS(rc))
    790         {
    791             delete pTransfer->pArea;
    792             pTransfer->pArea = NULL;
    793         }
    794     }
    795 
    796     LogFlowFunc(("Unregistered clipboard area (%RU32) by client %RU32 with rc=%Rrc\n",
    797                  parms.uID, pClientState->u32ClientID, rc));
     726    int rc = VINF_SUCCESS;
     727
     728    if (g_pfnExtension)
     729    {
     730        VBOXCLIPBOARDEXTAREAPARMS parms;
     731        RT_ZERO(parms);
     732
     733        parms.uID = pTransfer->pArea->GetID();
     734
     735        rc = g_pfnExtension(g_pvExtension, VBOX_CLIPBOARD_EXT_FN_AREA_UNREGISTER, &parms, sizeof(parms));
     736        if (RT_SUCCESS(rc))
     737        {
     738            rc = pTransfer->pArea->Close();
     739            if (RT_SUCCESS(rc))
     740            {
     741                delete pTransfer->pArea;
     742                pTransfer->pArea = NULL;
     743            }
     744        }
     745
     746        LogFlowFunc(("Unregistered clipboard area (%RU32) by client %RU32 with rc=%Rrc\n",
     747                     parms.uID, pClientState->u32ClientID, rc));
     748    }
     749
     750    delete pTransfer->pArea;
     751    pTransfer->pArea = NULL;
    798752
    799753    LogFlowFuncLeaveRC(rc);
     
    819773        return VERR_NO_MEMORY;
    820774
    821     VBOXCLIPBOARDEXTAREAPARMS parms;
    822     RT_ZERO(parms);
    823 
    824     parms.uID = 0; /* 0 means most recent clipboard area. */
    825 
    826     /* The client now needs to attach to the most recent clipboard area
    827      * to keep a reference to it. The host does the actual book keeping / cleanup then.
    828      *
    829      * This might fail if the host does not have a most recent clipboard area (yet). */
    830     int rc = g_pfnExtension(g_pvExtension, VBOX_CLIPBOARD_EXT_FN_AREA_ATTACH, &parms, sizeof(parms));
    831     if (RT_SUCCESS(rc))
    832         rc = pTransfer->pArea->OpenTemp(parms.uID /* Area ID */);
    833 
    834     LogFlowFunc(("Attached client %RU32 to clipboard area %RU32 with rc=%Rrc\n",
    835                  pClientState->u32ClientID, parms.uID, rc));
     775    int rc = VINF_SUCCESS;
     776
     777    if (g_pfnExtension)
     778    {
     779        VBOXCLIPBOARDEXTAREAPARMS parms;
     780        RT_ZERO(parms);
     781
     782        parms.uID = 0; /* 0 means most recent clipboard area. */
     783
     784        /* The client now needs to attach to the most recent clipboard area
     785         * to keep a reference to it. The host does the actual book keeping / cleanup then.
     786         *
     787         * This might fail if the host does not have a most recent clipboard area (yet). */
     788        rc = g_pfnExtension(g_pvExtension, VBOX_CLIPBOARD_EXT_FN_AREA_ATTACH, &parms, sizeof(parms));
     789        if (RT_SUCCESS(rc))
     790            rc = pTransfer->pArea->OpenTemp(parms.uID /* Area ID */);
     791
     792        LogFlowFunc(("Attached client %RU32 to clipboard area %RU32 with rc=%Rrc\n",
     793                     pClientState->u32ClientID, parms.uID, rc));
     794    }
     795    else
     796        rc = VERR_NOT_SUPPORTED;
    836797
    837798    LogFlowFuncLeaveRC(rc);
     
    869830    }
    870831
    871     LogFlowFuncLeaveRC(rc);
    872     return rc;
    873 }
    874 
     832    delete pTransfer->pArea;
     833    pTransfer->pArea = NULL;
     834
     835    LogFlowFuncLeaveRC(rc);
     836    return rc;
     837}
     838
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-utils.cpp

    r79175 r79267  
    154154bool vboxSvcClipboardURIReturnMsg(PVBOXCLIPBOARDCLIENTDATA pClientData, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
    155155{
    156     RT_NOREF(cParms);
     156    RT_NOREF(pClientData, cParms, paParms);
    157157
    158158    bool fHandled = false;
    159159
     160#if 0
    160161    PSHAREDCLIPBOARDURITRANSFER pTransfer = SharedClipboardURICtxGetTransfer(&pClientData->URI, 0 /* Index */);
    161162    if (pTransfer)
    162163    {
    163164        if (   !s_fReqHdr
    164             && pTransfer->State.Header.cObjects == 0) /** @todo For now we ASSUME that a header has been received when cObject > 0. */
     165            && !pTransfer->State.pHeader)
    165166        {
    166167            LogFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA\n"));
     
    176177        }
    177178    }
     179#endif
    178180
    179181    LogFlowFunc(("fHandled=%RTbool\n", fHandled));
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-win.cpp

    r79178 r79267  
    6868    /** Windows-specific context data. */
    6969    VBOXCLIPBOARDWINCTX      Win;
    70 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
    71     /** Structure for keeping URI clipboard information around. */
    72     SHAREDCLIPBOARDURICTX    URI;
    73 #endif
    7470};
    7571
     
    127123
    128124/**
    129  * Reads data of a specific format by waiting for its arrival.
     125 * Requests data of a specific format from the guest, optionally waiting for its arrival via VBoxClipboardSvcImplWriteData().
    130126 *
    131127 * @returns VBox status code.
    132128 * @param   pCtx                Clipboard context to use.
    133129 * @param   fFormat             Format to receive data in.
    134  * @param   uTimeoutMs          Timeout in ms.
     130 * @param   uTimeoutMs          Timeout (in ms). Specify 0 if no waiting is required.
    135131 */
    136 static int vboxClipboardWinReadData(PVBOXCLIPBOARDCONTEXT pCtx, VBOXCLIPBOARDFORMAT fFormat,
    137                                     RTMSINTERVAL uTimeoutMs)
     132static int vboxClipboardWinRequestData(PVBOXCLIPBOARDCONTEXT pCtx, VBOXCLIPBOARDFORMAT fFormat,
     133                                       RTMSINTERVAL uTimeoutMs)
    138134{
    139135    Assert(pCtx->pClientData);
     
    144140
    145141    int rc = vboxSvcClipboardReportMsg(pCtx->pClientData, VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA, fFormat);
    146     if (RT_SUCCESS(rc))
     142    if (   RT_SUCCESS(rc)
     143        && uTimeoutMs)
     144    {
    147145        rc = RTSemEventWait(pCtx->hRenderEvent, uTimeoutMs /* Timeout in ms */);
     146    }
    148147
    149148    LogFlowFuncLeaveRC(rc);
     
    221220            else
    222221            {
    223                 int rc = vboxClipboardWinReadData(pCtx, fFormat, 30 * 1000 /* 30s timeout */);
     222                int rc = vboxClipboardWinRequestData(pCtx, fFormat, 30 * 1000 /* 30s timeout */);
    224223
    225224                LogFunc(("vboxClipboardReadDataFromClient rc = %Rrc, pv %p, cb %d, u32Format %d\n",
     
    324323                        LogFunc(("VBOX_SHARED_CLIPBOARD_FMT_URI_LIST\n"));
    325324
    326                         SHAREDCLIPBOARDPROVIDERCREATIONCTX providerCtx;
    327                         RT_ZERO(providerCtx);
    328                         providerCtx.enmSource = SHAREDCLIPBOARDPROVIDERSOURCE_HOSTSERVICE;
    329 
    330                         SHAREDCLIPBOARDPROVIDERCALLBACKS providerCallbacks;
    331                         RT_ZERO(providerCallbacks);
    332                         providerCallbacks.pvUser         = pCtx->pClientData;
    333                         providerCallbacks.pfnReadDataHdr = vboxClipboardSvcReadDataHdrCallback;
    334 
    335                         providerCtx.pCallbacks = &providerCallbacks;
    336 
    337                         rc = VBoxClipboardWinURIReadMain(pWinCtx, &pCtx->URI, &providerCtx, fFormats);
    338 
    339                         /* Note: VBoxClipboardWinURIReadMain() takes care of closing the clipboard. */
     325                        PSHAREDCLIPBOARDURITRANSFER pTransfer = SharedClipboardURICtxGetTransfer(&pCtx->pClientData->URI,
     326                                                                                                 0 /* uIdx */);
     327                        if (pTransfer)
     328                        {
     329                            rc = VBoxClipboardWinURIAnnounce(pWinCtx, &pCtx->pClientData->URI, pTransfer);
     330                            if (RT_SUCCESS(rc))
     331                            {
     332                                rc = vboxClipboardWinRequestData(pCtx, fFormats, 0 /* Waiting not required */); /** FIX !!!!!!!!!!!! NEEDS TO GO INTO IDATAOBJECT GetData() !!!! */
     333                            }
     334                        }
     335                        else
     336                            AssertFailedStmt(rc = VERR_NOT_FOUND);
     337
     338                        /* Note: VBoxClipboardWinURIAnnounce() takes care of closing the clipboard. */
    340339                    }
    341340                    else
     
    349348#endif
    350349                }
     350
     351                if (RT_FAILURE(rc))
     352                    LogFunc(("Failed with rc=%Rrc\n", rc));
    351353            }
    352354            LogFunc(("VBOX_CLIPBOARD_WM_SET_FORMATS: fFormats=0x%x, lastErr=%ld\n", fFormats, GetLastError()));
     
    440442                else
    441443                    LogRel(("Clipboard: Initialized OLE\n"));
    442 
    443                 int rc2 = SharedClipboardURICtxInit(&g_ctx.URI);
    444                 AssertRC(rc2);
    445444            }
    446445#endif
     
    463462            OleSetClipboard(NULL); /* Make sure to flush the clipboard on destruction. */
    464463            OleUninitialize();
    465 
    466             SharedClipboardURICtxDestroy(&g_ctx.URI);
    467464#endif
    468465        }
     
    701698        else if (u32Format & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST)
    702699        {
    703             hClip = GetClipboardData(CF_HDROP);
    704             if (hClip != NULL) /* Do we have data in CF_HDROP format? */
    705             {
    706                 LPVOID lp = GlobalLock(hClip);
    707                 if (lp)
    708                 {
    709                     void *pvTemp;
    710                     size_t cbTemp;
    711                     rc = VBoxClipboardWinDropFilesToStringList((DROPFILES *)lp, (char **)&pvTemp, &cbTemp);
    712                     if (RT_SUCCESS(rc))
    713                     {
    714                         if (cbTemp > cb) /** @todo Add overflow handling! */
    715                         {
    716                             AssertMsgFailed(("More data buffer needed -- fix this\n"));
    717                             cbTemp = cb; /* Never copy more than the available buffer supplies. */
    718                         }
    719 
    720                         memcpy(pv, pvTemp, cbTemp);
    721 
    722                         RTMemFree(pvTemp);
    723 
    724                         *pcbActual = (uint32_t)cbTemp;
    725                     }
    726 
    727                     GlobalUnlock(hClip);
    728                 }
    729             }
     700            AssertFailed(); /* @todo */
    730701        }
    731702#endif /* VBOX_WITH_SHARED_CLIPBOARD_URI_LIST */
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc.cpp

    r79174 r79267  
    570570                            if (!SharedClipboardURICtxMaximumTransfersReached(&pClientData->URI))
    571571                            {
    572                                 SHAREDCLIPBOARDPROVIDERCREATIONCTX creationCtx;
    573                                 RT_ZERO(creationCtx);
    574                                 creationCtx.enmSource = SHAREDCLIPBOARDPROVIDERSOURCE_HOSTSERVICE;
    575 
    576572                                PSHAREDCLIPBOARDURITRANSFER pTransfer;
    577                                 rc = SharedClipboardURITransferCreate(SHAREDCLIPBOARDURITRANSFERDIR_READ,
    578                                                                       &creationCtx, &pTransfer);
     573                                rc = SharedClipboardURITransferCreate(SHAREDCLIPBOARDURITRANSFERDIR_READ, &pTransfer);
    579574                                if (RT_SUCCESS(rc))
    580575                                {
    581                                     rc = SharedClipboardURICtxTransferAdd(&pClientData->URI, pTransfer);
     576                                    rc = vboxSvcClipboardURIAreaRegister(&pClientData->State, pTransfer);
    582577                                    if (RT_SUCCESS(rc))
    583                                         rc = vboxSvcClipboardURIAreaRegister(&pClientData->State, pTransfer);
     578                                    {
     579                                        SHAREDCLIPBOARDPROVIDERCREATIONCTX creationCtx;
     580                                        RT_ZERO(creationCtx);
     581                                        creationCtx.enmSource = SHAREDCLIPBOARDPROVIDERSOURCE_HOSTSERVICE;
     582                                        creationCtx.u.HostService.pArea = pTransfer->pArea;
     583
     584                                        rc = SharedClipboardURITransferProviderCreate(pTransfer, &creationCtx);
     585                                        if (RT_SUCCESS(rc))
     586                                            rc = SharedClipboardURICtxTransferAdd(&pClientData->URI, pTransfer);
     587                                    }
    584588                                }
    585589                            }
     
    727731
    728732                rc = HGCMSvcGetU32(&paParms[0], &u32Format);
    729                 if (RT_SUCCESS (rc))
     733                if (RT_SUCCESS(rc))
    730734                {
    731735                    rc = VBoxHGCMParmPtrGet(&paParms[1], &pv, &cb);
    732 
    733                     if (RT_SUCCESS (rc))
     736                    if (RT_SUCCESS(rc))
    734737                    {
    735738                        if (   vboxSvcClipboardGetMode() != VBOX_SHARED_CLIPBOARD_MODE_GUEST_TO_HOST
Note: See TracChangeset for help on using the changeset viewer.

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