Index: trunk/include/VBox/GuestHost/SharedClipboard-uri.h
===================================================================
--- trunk/include/VBox/GuestHost/SharedClipboard-uri.h	(revision 79345)
+++ trunk/include/VBox/GuestHost/SharedClipboard-uri.h	(revision 79347)
@@ -61,79 +61,4 @@
 #define SHAREDCLIPBOARDAREA_OPEN_FLAGS_VALID_MASK         0x1
 
-/**
- * Class for maintaining a Shared Clipboard area
- * on the host or guest. This will contain all received files & directories
- * for a single Shared Clipboard operation.
- *
- * In case of a failed Shared Clipboard operation this class can also
- * perform a gentle rollback if required.
- */
-class SharedClipboardArea
-{
-public:
-
-    SharedClipboardArea(void);
-    SharedClipboardArea(const char *pszPath, SHAREDCLIPBOARDAREAID uID = NIL_SHAREDCLIPBOARDAREAID,
-                        SHAREDCLIPBOARDAREAOPENFLAGS fFlags = SHAREDCLIPBOARDAREA_OPEN_FLAGS_NONE);
-    virtual ~SharedClipboardArea(void);
-
-public:
-
-    uint32_t AddRef(void);
-    uint32_t Release(void);
-
-    int Lock(void);
-    int Unlock(void);
-
-    int AddFile(const char *pszFile);
-    int AddDir(const char *pszDir);
-    int Close(void);
-    bool IsOpen(void) const;
-    int OpenEx(const char *pszPath, SHAREDCLIPBOARDAREAID uID = NIL_SHAREDCLIPBOARDAREAID,
-               SHAREDCLIPBOARDAREAOPENFLAGS fFlags = SHAREDCLIPBOARDAREA_OPEN_FLAGS_NONE);
-    int OpenTemp(SHAREDCLIPBOARDAREAID uID = NIL_SHAREDCLIPBOARDAREAID,
-                 SHAREDCLIPBOARDAREAOPENFLAGS fFlags = SHAREDCLIPBOARDAREA_OPEN_FLAGS_NONE);
-    SHAREDCLIPBOARDAREAID GetID(void) const;
-    const char *GetDirAbs(void) const;
-    uint32_t GetRefCount(void);
-    int Reopen(void);
-    int Reset(bool fDeleteContent);
-    int Rollback(void);
-
-public:
-
-    static int PathConstruct(const char *pszBase, SHAREDCLIPBOARDAREAID uID, char *pszPath, size_t cbPath);
-
-protected:
-
-    int initInternal(void);
-    int destroyInternal(void);
-    int closeInternal(void);
-
-protected:
-
-    /** Creation timestamp (in ms). */
-    uint64_t                     m_tsCreatedMs;
-    /** Number of references to this instance. */
-    volatile uint32_t            m_cRefs;
-    /** Critical section for serializing access. */
-    RTCRITSECT                   m_CritSect;
-    /** Open flags. */
-    uint32_t                     m_fOpen;
-    /** Directory handle for drop directory. */
-    RTDIR                        m_hDir;
-    /** Absolute path to drop directory. */
-    RTCString                    m_strPathAbs;
-    /** List for holding created directories in the case of a rollback. */
-    RTCList<RTCString>           m_lstDirs;
-    /** List for holding created files in the case of a rollback. */
-    RTCList<RTCString>           m_lstFiles;
-    /** Associated clipboard area ID. */
-    SHAREDCLIPBOARDAREAID        m_uID;
-};
-
-int SharedClipboardPathSanitizeFilename(char *pszPath, size_t cbPath);
-int SharedClipboardPathSanitize(char *pszPath, size_t cbPath);
-
 /** SharedClipboardURIObject flags. */
 typedef uint32_t SHAREDCLIPBOARDURIOBJECTFLAGS;
@@ -166,4 +91,13 @@
         /** The usual 32-bit hack. */
         Type_32Bit_Hack = 0x7fffffff
+    };
+
+    enum Storage
+    {
+        Storage_Unknown = 0,
+        Storage_Local,
+        Storage_Temporary,
+        /** The usual 32-bit hack. */
+        Storage_32Bit_Hack = 0x7fffffff
     };
 
@@ -269,4 +203,6 @@
     /** The object's view. */
     View      m_enmView;
+    /** Where the object is being stored to. */
+    Storage   m_enmStorage;
     /** Absolute path (base) for the source. */
     RTCString m_strSrcPathAbs;
@@ -309,4 +245,115 @@
 };
 
+/**
+ * Enumeration for specifying a clipboard area object type.
+ */
+typedef enum _SHAREDCLIPBOARDAREAOBJTYPE
+{
+    /** Unknown object type; do not use. */
+    SHAREDCLIPBOARDAREAOBJTYPE_UNKNOWN = 0,
+    /** Object is a directory. */
+    SHAREDCLIPBOARDAREAOBJTYPE_DIR,
+    /** Object is a file. */
+    SHAREDCLIPBOARDAREAOBJTYPE_FILE,
+    /** The usual 32-bit hack. */
+    SHAREDCLIPBOARDAREAOBJTYPE__32Bit_Hack = 0x7fffffff
+} SHAREDCLIPBOARDAREAOBJTYPE;
+
+/** Defines a clipboard area object state. */
+typedef uint32_t SHAREDCLIPBOARDAREAOBJSTATE;
+
+/** No object state set. */
+#define SHAREDCLIPBOARDAREAOBJSTATE_NONE                0
+/** The object is considered as being complete (e.g. serialized). */
+#define SHAREDCLIPBOARDAREAOBJSTATE_COMPLETE            RT_BIT(0)
+
+/**
+ * Lightweight structure to keep a clipboard area object's state.
+ *
+ * Note: We don't want to use the ClipboardURIObject class here, as this
+ *       is too heavy for this purpose.
+ */
+typedef struct _SHAREDCLIPBOARDAREAOBJ
+{
+    SHAREDCLIPBOARDAREAOBJTYPE  enmType;
+    SHAREDCLIPBOARDAREAOBJSTATE fState;
+} SHAREDCLIPBOARDAREAOBJ, *PSHAREDCLIPBOARDAREAOBJ;
+
+/**
+ * Class for maintaining a Shared Clipboard area
+ * on the host or guest. This will contain all received files & directories
+ * for a single Shared Clipboard operation.
+ *
+ * In case of a failed Shared Clipboard operation this class can also
+ * perform a gentle rollback if required.
+ */
+class SharedClipboardArea
+{
+public:
+
+    SharedClipboardArea(void);
+    SharedClipboardArea(const char *pszPath, SHAREDCLIPBOARDAREAID uID = NIL_SHAREDCLIPBOARDAREAID,
+                        SHAREDCLIPBOARDAREAOPENFLAGS fFlags = SHAREDCLIPBOARDAREA_OPEN_FLAGS_NONE);
+    virtual ~SharedClipboardArea(void);
+
+public:
+
+    uint32_t AddRef(void);
+    uint32_t Release(void);
+
+    int Lock(void);
+    int Unlock(void);
+
+    int AddObject(const char *pszPath, const SHAREDCLIPBOARDAREAOBJ &Obj);
+    int GetObject(const char *pszPath, PSHAREDCLIPBOARDAREAOBJ pObj);
+
+    int Close(void);
+    bool IsOpen(void) const;
+    int OpenEx(const char *pszPath, SHAREDCLIPBOARDAREAID uID = NIL_SHAREDCLIPBOARDAREAID,
+               SHAREDCLIPBOARDAREAOPENFLAGS fFlags = SHAREDCLIPBOARDAREA_OPEN_FLAGS_NONE);
+    int OpenTemp(SHAREDCLIPBOARDAREAID uID = NIL_SHAREDCLIPBOARDAREAID,
+                 SHAREDCLIPBOARDAREAOPENFLAGS fFlags = SHAREDCLIPBOARDAREA_OPEN_FLAGS_NONE);
+    SHAREDCLIPBOARDAREAID GetID(void) const;
+    const char *GetDirAbs(void) const;
+    uint32_t GetRefCount(void);
+    int Reopen(void);
+    int Reset(bool fDeleteContent);
+    int Rollback(void);
+
+public:
+
+    static int PathConstruct(const char *pszBase, SHAREDCLIPBOARDAREAID uID, char *pszPath, size_t cbPath);
+
+protected:
+
+    int initInternal(void);
+    int destroyInternal(void);
+    int closeInternal(void);
+
+protected:
+
+    typedef std::map<RTCString, SHAREDCLIPBOARDAREAOBJ> SharedClipboardAreaFsObjMap;
+
+    /** Creation timestamp (in ms). */
+    uint64_t                     m_tsCreatedMs;
+    /** Number of references to this instance. */
+    volatile uint32_t            m_cRefs;
+    /** Critical section for serializing access. */
+    RTCRITSECT                   m_CritSect;
+    /** Open flags. */
+    uint32_t                     m_fOpen;
+    /** Directory handle for root clipboard directory. */
+    RTDIR                        m_hDir;
+    /** Absolute path to root clipboard directory. */
+    RTCString                    m_strPathAbs;
+    /** List for holding created directories in the case of a rollback. */
+    SharedClipboardAreaFsObjMap  m_mapObj;
+    /** Associated clipboard area ID. */
+    SHAREDCLIPBOARDAREAID        m_uID;
+};
+
+int SharedClipboardPathSanitizeFilename(char *pszPath, size_t cbPath);
+int SharedClipboardPathSanitize(char *pszPath, size_t cbPath);
+
 /** SharedClipboardURIList flags. */
 typedef uint32_t SHAREDCLIPBOARDURILISTFLAGS;
@@ -408,4 +455,5 @@
 int SharedClipboardURIFileHdrInit(PVBOXCLIPBOARDFILEHDR pFileHdr);
 void SharedClipboardURIFileHdrDestroy(PVBOXCLIPBOARDFILEHDR pFileHdr);
+void SharedClipboardURIFileHdrFree(PVBOXCLIPBOARDFILEHDR pFileHdr);
 PVBOXCLIPBOARDFILEHDR SharedClipboardURIFileHdrDup(PVBOXCLIPBOARDFILEHDR pFileHdr);
 bool SharedClipboardURIFileHdrIsValid(PVBOXCLIPBOARDFILEHDR pFileHdr, PVBOXCLIPBOARDDATAHDR pDataHdr);
@@ -457,11 +505,15 @@
     /** How many bytes are being used in the meta data block. */
     uint32_t                    cbUsed;
+    /** Current reading offset (in bytes). */
+    uint32_t                    cbOffRead;
 } SHAREDCLIPBOARDMETADATA, *PSHAREDCLIPBOARDMETADATA;
 
 int SharedClipboardMetaDataInit(PSHAREDCLIPBOARDMETADATA pMeta, SHAREDCLIPBOARDMETADATAFMT enmFmt);
 void SharedClipboardMetaDataDestroy(PSHAREDCLIPBOARDMETADATA pMeta);
+void SharedClipboardMetaDataFree(PSHAREDCLIPBOARDMETADATA pMeta);
 int SharedClipboardMetaDataAdd(PSHAREDCLIPBOARDMETADATA pMeta, const void *pvDataAdd, uint32_t cbDataAdd);
 int SharedClipboardMetaDataConvertToFormat(const void *pvData, size_t cbData, SHAREDCLIPBOARDMETADATAFMT enmFmt,
                                            void **ppvData, uint32_t *pcbData);
+int SharedClipboardMetaDataRead(PSHAREDCLIPBOARDMETADATA pMeta, void *pvBuf, uint32_t cbBuf, uint32_t *pcbRead);
 int SharedClipboardMetaDataResize(PSHAREDCLIPBOARDMETADATA pMeta, uint32_t cbNewSize);
 size_t SharedClipboardMetaDataGetFree(PSHAREDCLIPBOARDMETADATA pMeta);
@@ -486,4 +538,45 @@
 } SHAREDCLIPBOARDURITRANSFERDIR;
 
+struct _SHAREDCLIPBOARDURITRANSFER;
+typedef struct _SHAREDCLIPBOARDURITRANSFER SHAREDCLIPBOARDURITRANSFER;
+
+/**
+ * Structure for handling a single URI object context.
+ */
+typedef struct _SHAREDCLIPBOARDCLIENTURIOBJCTX
+{
+    SHAREDCLIPBOARDURITRANSFER    *pTransfer;
+    /** Pointer to current object being processed. */
+    SharedClipboardURIObject      *pObj;
+} SHAREDCLIPBOARDCLIENTURIOBJCTX, *PSHAREDCLIPBOARDCLIENTURIOBJCTX;
+
+/**
+ * Enumeration specifying an URI transfer status.
+ */
+typedef enum SHAREDCLIPBOARDURITRANSFERSTATUS
+{
+    /** No status set. */
+    SHAREDCLIPBOARDURITRANSFERSTATUS_NONE = 0,
+    /** The transfer has been announced but is not running yet. */
+    SHAREDCLIPBOARDURITRANSFERSTATUS_ANNOUNCED,
+    /** The transfer is active and running. */
+    SHAREDCLIPBOARDURITRANSFERSTATUS_RUNNING
+};
+
+/**
+ * Enumeration to specify the Shared Clipboard URI source type.
+ */
+typedef enum SHAREDCLIPBOARDSOURCE
+{
+    /** Invalid source type. */
+    SHAREDCLIPBOARDSOURCE_INVALID = 0,
+    /** Source is local. */
+    SHAREDCLIPBOARDSOURCE_LOCAL,
+    /** Source is remote. */
+    SHAREDCLIPBOARDSOURCE_REMOTE,
+    /** The usual 32-bit hack. */
+    SHAREDCLIPBOARDSOURCE_32Bit_Hack = 0x7fffffff
+} SHAREDCLIPBOARDSOURCE;
+
 /**
  * Structure for maintaining an URI transfer state.
@@ -492,58 +585,73 @@
 typedef struct _SHAREDCLIPBOARDURITRANSFERSTATE
 {
+    /** The transfer's current status. */
+    SHAREDCLIPBOARDURITRANSFERSTATUS    enmStatus;
     /** The transfer's direction. */
-    SHAREDCLIPBOARDURITRANSFERDIR enmDir;
+    SHAREDCLIPBOARDURITRANSFERDIR       enmDir;
+    /** The transfer's source. */
+    SHAREDCLIPBOARDSOURCE               enmSource;
+    bool                                fHostMsgSendHeader;
     /** The transfer's cached data header.
      *  Can be NULL if no header has been received yet. */
-    PVBOXCLIPBOARDDATAHDR         pHeader;
+    PVBOXCLIPBOARDDATAHDR               pHeader;
+    bool                                fHostMsgSendMetaDataHdr;
+    bool                                fHostMsgSendMetaDataChunk;
     /** The transfer's cached meta data.
      *  Can be NULL if no meta data has been received yet. */
-    PSHAREDCLIPBOARDMETADATA      pMeta;
+    PSHAREDCLIPBOARDMETADATA            pMeta;
+    /** Context of current object being handled. */
+    SHAREDCLIPBOARDCLIENTURIOBJCTX      ObjCtx;
 } SHAREDCLIPBOARDURITRANSFERSTATE, *PSHAREDCLIPBOARDURITRANSFERSTATE;
 
-/**
- * Enumeration to specify the Shared Clipboard URI provider source type.
- */
-typedef enum SHAREDCLIPBOARDURIPROVIDERSOURCE
-{
-    /** Invalid source type. */
-    SHAREDCLIPBOARDURIPROVIDERSOURCE_INVALID = 0,
-    /** Source is VbglR3. */
-    SHAREDCLIPBOARDURIPROVIDERSOURCE_VBGLR3,
-    /** Source is the host service. */
-    SHAREDCLIPBOARDURIPROVIDERSOURCE_HOSTSERVICE
-} SHAREDCLIPBOARDURIPROVIDERSOURCE;
-
-class SharedClipboardProvider;
-
-/**
- * Structure for storing clipboard provider callback data.
- */
-typedef struct _SHAREDCLIPBOARDPROVIDERCALLBACKDATA
-{
-    /** Pointer to related clipboard provider ("this"). */
-    SharedClipboardProvider    *pProvider;
-    /** Saved user pointer. */
+struct _SHAREDCLIPBOARDURITRANSFER;
+typedef struct _SHAREDCLIPBOARDURITRANSFER *PSHAREDCLIPBOARDURITRANSFER;
+
+typedef struct _SHAREDCLIPBOARDPROVIDERCTX
+{
+    PSHAREDCLIPBOARDURITRANSFER pTransfer;
     void                       *pvUser;
-} SHAREDCLIPBOARDPROVIDERCALLBACKDATA, *PSHAREDCLIPBOARDPROVIDERCALLBACKDATA;
-
-/** Callback functopn for the Shared Clipboard provider. */
-typedef DECLCALLBACK(int) FNSSHAREDCLIPBOARDPROVIDERCALLBACK(PSHAREDCLIPBOARDPROVIDERCALLBACKDATA pData);
-/** Pointer to a FNSSHAREDCLIPBOARDPROVIDERCALLBACK function. */
-typedef FNSSHAREDCLIPBOARDPROVIDERCALLBACK *PFNSSHAREDCLIPBOARDPROVIDERCALLBACK;
-
-/**
- * Structure acting as a function callback table for clipboard providers.
- * All callbacks are optional and therefore can be NULL.
- */
-typedef struct _SHAREDCLIPBOARDPROVIDERCALLBACKS
-{
-    /** Saved user pointer. Will be passed to the callback (if needed). */
-    void                                    *pvUser;
-    /** Function pointer, called when reading the (meta) data header. */
-    PFNSSHAREDCLIPBOARDPROVIDERCALLBACK      pfnReadDataHdr;
-    /** Function pointer, called when reading a (meta) data chunk. */
-    PFNSSHAREDCLIPBOARDPROVIDERCALLBACK      pfnReadDataChunk;
-} SHAREDCLIPBOARDPROVIDERCALLBACKS, *PSHAREDCLIPBOARDPROVIDERCALLBACKS;
+} SHAREDCLIPBOARDPROVIDERCTX, *PSHAREDCLIPBOARDPROVIDERCTX;
+
+#define SHAREDCLIPBOARDPROVIDERFUNCDECL(a_Name, ...) \
+    typedef DECLCALLBACK(int) RT_CONCAT(FNSHAREDCLIPBOARDPROVIDER, a_Name)(PSHAREDCLIPBOARDPROVIDERCTX, __VA_ARGS__); \
+    typedef RT_CONCAT(FNSHAREDCLIPBOARDPROVIDER, a_Name) RT_CONCAT(*PFNSHAREDCLIPBOARDPROVIDER, a_Name);
+
+#define SHAREDCLIPBOARDPROVIDERFUNCDECLVOID(a_Name) \
+    typedef DECLCALLBACK(int) RT_CONCAT(FNSHAREDCLIPBOARDPROVIDER, a_Name)(PSHAREDCLIPBOARDPROVIDERCTX); \
+    typedef RT_CONCAT(FNSHAREDCLIPBOARDPROVIDER, a_Name) RT_CONCAT(*PFNSHAREDCLIPBOARDPROVIDER, a_Name);
+
+#define SHAREDCLIPBOARDPROVIDERFUNCMEMBER(a_Name, a_Member) \
+    RT_CONCAT(PFNSHAREDCLIPBOARDPROVIDER, a_Name) a_Member;
+
+SHAREDCLIPBOARDPROVIDERFUNCDECLVOID(PREPARE)
+SHAREDCLIPBOARDPROVIDERFUNCDECL(READDATAHDR, PVBOXCLIPBOARDDATAHDR *ppDataHdr)
+SHAREDCLIPBOARDPROVIDERFUNCDECL(WRITEDATAHDR, const PVBOXCLIPBOARDDATAHDR pDataHdr)
+SHAREDCLIPBOARDPROVIDERFUNCDECL(READDATACHUNK, const PVBOXCLIPBOARDDATAHDR pDataHdr, void *pvChunk, uint32_t cbChunk, uint32_t fFlags, uint32_t *pcbRead)
+SHAREDCLIPBOARDPROVIDERFUNCDECL(WRITEDATACHUNK, const PVBOXCLIPBOARDDATAHDR pDataHdr, const void *pvChunk, uint32_t cbChunk, uint32_t fFlags, uint32_t *pcbWritten)
+SHAREDCLIPBOARDPROVIDERFUNCDECL(READOBJHDR, PVBOXCLIPBOARDOBJHDR *ppObjHdr)
+SHAREDCLIPBOARDPROVIDERFUNCDECL(READDIRECTORY, PVBOXCLIPBOARDDIRDATA *ppDirData)
+SHAREDCLIPBOARDPROVIDERFUNCDECL(WRITEDIRECTORY, const PVBOXCLIPBOARDDIRDATA pDirData)
+SHAREDCLIPBOARDPROVIDERFUNCDECL(READFILEHDR, PVBOXCLIPBOARDFILEHDR *ppFileHdr);
+SHAREDCLIPBOARDPROVIDERFUNCDECL(WRITEFILEHDR, const PVBOXCLIPBOARDFILEHDR pFileHdr);
+SHAREDCLIPBOARDPROVIDERFUNCDECL(READFILEDATA, void *pvData, uint32_t cbData, uint32_t fFlags, uint32_t *pcbRead)
+SHAREDCLIPBOARDPROVIDERFUNCDECL(WRITEFILEDATA, void *pvData, uint32_t cbData, uint32_t fFlags, uint32_t *pcbWritten)
+SHAREDCLIPBOARDPROVIDERFUNCDECLVOID(RESET)
+
+typedef struct _SHAREDCLIPBOARDPROVIDERINTERFACE
+{
+    SHAREDCLIPBOARDPROVIDERFUNCMEMBER(PREPARE, pfnPrepare);
+    SHAREDCLIPBOARDPROVIDERFUNCMEMBER(READDATAHDR, pfnReadDataHdr);
+    SHAREDCLIPBOARDPROVIDERFUNCMEMBER(WRITEDATAHDR, pfnWriteDataHdr);
+    SHAREDCLIPBOARDPROVIDERFUNCMEMBER(WRITEDATACHUNK, pfnWriteDataChunk);
+    SHAREDCLIPBOARDPROVIDERFUNCMEMBER(READDATACHUNK, pfnReadDataChunk);
+    SHAREDCLIPBOARDPROVIDERFUNCMEMBER(READOBJHDR, pfnReadObjHdr);
+    SHAREDCLIPBOARDPROVIDERFUNCMEMBER(READDIRECTORY, pfnReadDirectory);
+    SHAREDCLIPBOARDPROVIDERFUNCMEMBER(WRITEDIRECTORY, pfnWriteDirectory);
+    SHAREDCLIPBOARDPROVIDERFUNCMEMBER(READFILEHDR, pfnReadFileHdr);
+    SHAREDCLIPBOARDPROVIDERFUNCMEMBER(WRITEFILEHDR, pfnWriteFileHdr);
+    SHAREDCLIPBOARDPROVIDERFUNCMEMBER(READFILEDATA, pfnReadFileData);
+    SHAREDCLIPBOARDPROVIDERFUNCMEMBER(WRITEFILEDATA, pfnWriteFileData);
+    SHAREDCLIPBOARDPROVIDERFUNCMEMBER(RESET, pfnReset);
+} SHAREDCLIPBOARDPROVIDERINTERFACE, *PSHAREDCLIPBOARDPROVIDERINTERFACE;
 
 /**
@@ -553,9 +661,7 @@
 {
     /** Specifies what the source of the provider is. */
-    SHAREDCLIPBOARDURIPROVIDERSOURCE  enmSource;
-    /** Specifies whether the provider will read or write data. */
-    SHAREDCLIPBOARDURITRANSFERDIR     enmDir;
-    /** Optional callback table; can be NULL if not needed. */
-    PSHAREDCLIPBOARDPROVIDERCALLBACKS pCallbacks;
+    SHAREDCLIPBOARDSOURCE             enmSource;
+    SHAREDCLIPBOARDPROVIDERINTERFACE  Interface;
+    void                             *pvUser;
     union
     {
@@ -601,4 +707,5 @@
 } SHAREDCLIPBOARDPROVIDERWRITEPARMS, *PSHAREDCLIPBOARDPROVIDERWRITEPARMS;
 
+#if 0
 /**
  * Interface class acting as a lightweight proxy for abstracting reading / writing clipboard data.
@@ -800,4 +907,5 @@
 };
 #endif /* VBOX_WITH_SHARED_CLIPBOARD_HOST */
+#endif
 
 struct _SHAREDCLIPBOARDURITRANSFER;
@@ -815,27 +923,22 @@
 } SHAREDCLIPBOARDURITRANSFERCALLBACKDATA, *PSHAREDCLIPBOARDURITRANSFERCALLBACKDATA;
 
-typedef DECLCALLBACK(void) FNSHAREDCLIPBOARDURITRANSFERSTARTED(PSHAREDCLIPBOARDURITRANSFERCALLBACKDATA pData);
-/** Pointer to a FNSHAREDCLIPBOARDURITRANSFERSTARTED function. */
-typedef FNSHAREDCLIPBOARDURITRANSFERSTARTED *PFNSHAREDCLIPBOARDURITRANSFERSTARTED;
-
-typedef DECLCALLBACK(void) FNSHAREDCLIPBOARDURITRANSFERPREPARE(PSHAREDCLIPBOARDURITRANSFERCALLBACKDATA pData);
-/** Pointer to a FNSHAREDCLIPBOARDURITRANSFERPREPARE function. */
-typedef FNSHAREDCLIPBOARDURITRANSFERPREPARE *PFNSHAREDCLIPBOARDURITRANSFERPREPARE;
-
-typedef DECLCALLBACK(void) FNSHAREDCLIPBOARDURIMETADATACOMPLETE(PSHAREDCLIPBOARDURITRANSFERCALLBACKDATA pData);
-/** Pointer to a FNSHAREDCLIPBOARDURIMETADATACOMPLETE function. */
-typedef FNSHAREDCLIPBOARDURIMETADATACOMPLETE *PFNSHAREDCLIPBOARDURIMETADATACOMPLETE;
-
-typedef DECLCALLBACK(void) FNSHAREDCLIPBOARDURITRANSFERCANCELED(PSHAREDCLIPBOARDURITRANSFERCALLBACKDATA pData);
-/** Pointer to a FNSHAREDCLIPBOARDURITRANSFERCANCELED function. */
-typedef FNSHAREDCLIPBOARDURITRANSFERCANCELED *PFNSHAREDCLIPBOARDURITRANSFERCANCELED;
-
-typedef DECLCALLBACK(void) FNSHAREDCLIPBOARDURITRANSFERCOMPLETE(PSHAREDCLIPBOARDURITRANSFERCALLBACKDATA pData, int rc);
-/** Pointer to a FNSHAREDCLIPBOARDURITRANSFERCOMPLETE function. */
-typedef FNSHAREDCLIPBOARDURITRANSFERCOMPLETE *PFNSHAREDCLIPBOARDURITRANSFERCOMPLETE;
-
-typedef DECLCALLBACK(void) FNSHAREDCLIPBOARDURITRANSFERERROR(PSHAREDCLIPBOARDURITRANSFERCALLBACKDATA pData, int rc);
-/** Pointer to a FNSHAREDCLIPBOARDURITRANSFERERROR function. */
-typedef FNSHAREDCLIPBOARDURITRANSFERERROR *PFNSHAREDCLIPBOARDURITRANSFERERROR;
+#define SHAREDCLIPBOARDTRANSFERCALLBACKDECLVOID(a_Name) \
+    typedef DECLCALLBACK(void) RT_CONCAT(FNSHAREDCLIPBOARDCALLBACK, a_Name)(PSHAREDCLIPBOARDURITRANSFERCALLBACKDATA pData); \
+    typedef RT_CONCAT(FNSHAREDCLIPBOARDCALLBACK, a_Name) RT_CONCAT(*PFNSHAREDCLIPBOARDCALLBACK, a_Name);
+
+#define SHAREDCLIPBOARDTRANSFERCALLBACKDECL(a_Name, ...) \
+    typedef DECLCALLBACK(void) RT_CONCAT(FNSHAREDCLIPBOARDCALLBACK, a_Name)(PSHAREDCLIPBOARDURITRANSFERCALLBACKDATA pData, __VA_ARGS__); \
+    typedef RT_CONCAT(FNSHAREDCLIPBOARDCALLBACK, a_Name) RT_CONCAT(*PFNSHAREDCLIPBOARDCALLBACK, a_Name);
+
+#define SHAREDCLIPBOARDTRANSFERCALLBACKMEMBER(a_Name, a_Member) \
+    RT_CONCAT(PFNSHAREDCLIPBOARDCALLBACK, a_Name) a_Member;
+
+SHAREDCLIPBOARDTRANSFERCALLBACKDECLVOID(TRANSFERPREPARE)
+SHAREDCLIPBOARDTRANSFERCALLBACKDECLVOID(TRANSFERSTARTED)
+SHAREDCLIPBOARDTRANSFERCALLBACKDECLVOID(DATAHDRCOMPLETE)
+SHAREDCLIPBOARDTRANSFERCALLBACKDECLVOID(DATACHUNKCOMPLETE)
+SHAREDCLIPBOARDTRANSFERCALLBACKDECLVOID(TRANSFERCANCELED)
+SHAREDCLIPBOARDTRANSFERCALLBACKDECL    (TRANSFERCOMPLETE, int rc)
+SHAREDCLIPBOARDTRANSFERCALLBACKDECL    (TRANSFERERROR, int rc)
 
 /**
@@ -846,17 +949,19 @@
 {
     /** Saved user pointer. */
-    void                                 *pvUser;
+    void                                  *pvUser;
     /** Function pointer, called when the transfer is going to be prepared. */
-    PFNSHAREDCLIPBOARDURITRANSFERPREPARE  pfnTransferPrepare;
+    SHAREDCLIPBOARDTRANSFERCALLBACKMEMBER(TRANSFERPREPARE, pfnTransferPrepare);
     /** Function pointer, called when the transfer has been started. */
-    PFNSHAREDCLIPBOARDURITRANSFERSTARTED  pfnTransferStarted;
-    /** Function pointer, called when reading / writing meta data is complete. */
-    PFNSHAREDCLIPBOARDURIMETADATACOMPLETE pfnMetaDataComplete;
+    SHAREDCLIPBOARDTRANSFERCALLBACKMEMBER(TRANSFERSTARTED, pfnTransferStarted);
+    /** Function pointer, called when reading / writing the meta data header is complete. */
+    SHAREDCLIPBOARDTRANSFERCALLBACKMEMBER(DATAHDRCOMPLETE, pfnDataHeaderComplete);
+    /** Function pointer, called when reading / writing the meta data is complete. */
+    SHAREDCLIPBOARDTRANSFERCALLBACKMEMBER(DATACHUNKCOMPLETE, pfnDataComplete);
     /** Function pointer, called when the transfer is complete. */
-    PFNSHAREDCLIPBOARDURITRANSFERCOMPLETE pfnTransferComplete;
+    SHAREDCLIPBOARDTRANSFERCALLBACKMEMBER(TRANSFERCOMPLETE, pfnTransferComplete);
     /** Function pointer, called when the transfer has been canceled. */
-    PFNSHAREDCLIPBOARDURITRANSFERCANCELED pfnTransferCanceled;
+    SHAREDCLIPBOARDTRANSFERCALLBACKMEMBER(TRANSFERCANCELED, pfnTransferCanceled);
     /** Function pointer, called when transfer resulted in an unrecoverable error. */
-    PFNSHAREDCLIPBOARDURITRANSFERERROR    pfnTransferError;
+    SHAREDCLIPBOARDTRANSFERCALLBACKMEMBER(TRANSFERERROR, pfnTransferError);
 } SHAREDCLIPBOARDURITRANSFERCALLBACKS, *PSHAREDCLIPBOARDURITRANSFERCALLBACKS;
 
@@ -874,13 +979,4 @@
     volatile bool               fCancelled;
 } SHAREDCLIPBOARDURITRANSFERTHREAD, *PSHAREDCLIPBOARDURITRANSFERTHREAD;
-
-/**
- * Structure for handling a single URI object context.
- */
-typedef struct _SHAREDCLIPBOARDCLIENTURIOBJCTX
-{
-    /** Pointer to current object being processed. */
-    SharedClipboardURIObject      *pObj;
-} SHAREDCLIPBOARDCLIENTURIOBJCTX, *PSHAREDCLIPBOARDCLIENTURIOBJCTX;
 
 /**
@@ -903,8 +999,9 @@
     /** The URI list for this transfer. */
     SharedClipboardURIList             *pURIList;
-    /** Context of current object being handled. */
-    SHAREDCLIPBOARDCLIENTURIOBJCTX      ObjCtx;
-    /** The Shared Clipboard provider in charge for this transfer. */
-    SharedClipboardProvider            *pProvider;
+    SHAREDCLIPBOARDPROVIDERCTX          ProviderCtx;
+    /** The transfer's provider interface. */
+    SHAREDCLIPBOARDPROVIDERINTERFACE    ProviderIface;
+    /** The transfer's (optional) callback table. */
+    SHAREDCLIPBOARDURITRANSFERCALLBACKS Callbacks;
     /** Opaque pointer to implementation-specific parameters. */
     void                               *pvUser;
@@ -913,6 +1010,4 @@
     /** Contains thread-related attributes. */
     SHAREDCLIPBOARDURITRANSFERTHREAD    Thread;
-    /** (Optional) callbacks related to this transfer. */
-    SHAREDCLIPBOARDURITRANSFERCALLBACKS Callbacks;
 } SHAREDCLIPBOARDURITRANSFER, *PSHAREDCLIPBOARDURITRANSFER;
 
@@ -927,10 +1022,13 @@
      *  Use a list or something lateron. */
     RTLISTANCHOR                List;
-    /** Number of concurrent transfers.
+    /** Number of running (concurrent) transfers.
      *  At the moment we only support only one transfer per client at a time. */
-    uint32_t                    cTransfers;
-    /** Maximum Number of concurrent transfers.
+    uint32_t                    cRunning;
+    /** Maximum Number of running (concurrent) transfers.
      *  At the moment we only support only one transfer per client at a time. */
-    uint32_t                    cMaxTransfers;
+    uint32_t                    cMaxRunning;
+#ifdef DEBUG
+    uint32_t                    cTransfer;
+#endif
 } SHAREDCLIPBOARDURICTX, *PSHAREDCLIPBOARDURICTX;
 
@@ -940,19 +1038,22 @@
 bool SharedClipboardURIObjCtxIsValid(PSHAREDCLIPBOARDCLIENTURIOBJCTX pObjCtx);
 
-int SharedClipboardURITransferCreate(SHAREDCLIPBOARDURITRANSFERDIR enmDir, PSHAREDCLIPBOARDURITRANSFER *ppTransfer);
+int SharedClipboardURITransferCreate(SHAREDCLIPBOARDURITRANSFERDIR enmDir, SHAREDCLIPBOARDSOURCE enmSource, PSHAREDCLIPBOARDURITRANSFER *ppTransfer);
 int SharedClipboardURITransferDestroy(PSHAREDCLIPBOARDURITRANSFER pTransfer);
 int SharedClipboardURITransferPrepare(PSHAREDCLIPBOARDURITRANSFER pTransfer);
 int SharedClipboardURITransferProviderCreate(PSHAREDCLIPBOARDURITRANSFER pTransfer,
-                                             PSHAREDCLIPBOARDPROVIDERCREATIONCTX pProviderCtx);
+                                             PSHAREDCLIPBOARDPROVIDERCREATIONCTX pCreationCtx);
 void SharedClipboardURITransferReset(PSHAREDCLIPBOARDURITRANSFER pTransfer);
 SharedClipboardArea *SharedClipboardURITransferGetArea(PSHAREDCLIPBOARDURITRANSFER pTransfer);
 PSHAREDCLIPBOARDCLIENTURIOBJCTX SharedClipboardURITransferGetCurrentObjCtx(PSHAREDCLIPBOARDURITRANSFER pTransfer);
 const SharedClipboardURIObject *SharedClipboardURITransferGetCurrentObject(PSHAREDCLIPBOARDURITRANSFER pTransfer);
-SharedClipboardProvider *SharedClipboardURITransferGetProvider(PSHAREDCLIPBOARDURITRANSFER pTransfer);
 SharedClipboardURIList *SharedClipboardURITransferGetList(PSHAREDCLIPBOARDURITRANSFER pTransfer);
 SharedClipboardURIObject *SharedClipboardURITransferGetObject(PSHAREDCLIPBOARDURITRANSFER pTransfer, uint64_t uIdx);
+SHAREDCLIPBOARDSOURCE SharedClipboardURITransferGetSource(PSHAREDCLIPBOARDURITRANSFER pTransfer);
+SHAREDCLIPBOARDURITRANSFERSTATUS SharedClipboardURITransferGetStatus(PSHAREDCLIPBOARDURITRANSFER pTransfer);
 int SharedClipboardURITransferRun(PSHAREDCLIPBOARDURITRANSFER pTransfer, bool fAsync);
 void SharedClipboardURITransferSetCallbacks(PSHAREDCLIPBOARDURITRANSFER pTransfer,
                                             PSHAREDCLIPBOARDURITRANSFERCALLBACKS pCallbacks);
+int SharedClipboardURITransferSetDataHeader(PSHAREDCLIPBOARDURITRANSFER pTransfer, PVBOXCLIPBOARDDATAHDR pDataHdr);
+int SharedClipboardURITransferSetDataChunk(PSHAREDCLIPBOARDURITRANSFER pTransfer, PVBOXCLIPBOARDDATACHUNK pDataChunk);
 
 int SharedClipboardURITransferMetaDataAdd(PSHAREDCLIPBOARDURITRANSFER pTransfer, const void *pvMeta, uint32_t cbMeta);
@@ -971,6 +1072,7 @@
 void SharedClipboardURICtxReset(PSHAREDCLIPBOARDURICTX pURI);
 PSHAREDCLIPBOARDURITRANSFER SharedClipboardURICtxGetTransfer(PSHAREDCLIPBOARDURICTX pURI, uint32_t uIdx);
-uint32_t SharedClipboardURICtxGetActiveTransfers(PSHAREDCLIPBOARDURICTX pURI);
-bool SharedClipboardURICtxMaximumTransfersReached(PSHAREDCLIPBOARDURICTX pURI);
+uint32_t SharedClipboardURICtxGetRunningTransfers(PSHAREDCLIPBOARDURICTX pURI);
+void SharedClipboardURICtxTransfersCleanup(PSHAREDCLIPBOARDURICTX pURI);
+bool SharedClipboardURICtxTransfersMaximumReached(PSHAREDCLIPBOARDURICTX pURI);
 int SharedClipboardURICtxTransferAdd(PSHAREDCLIPBOARDURICTX pURI, PSHAREDCLIPBOARDURITRANSFER pTransfer);
 int SharedClipboardURICtxTransferRemove(PSHAREDCLIPBOARDURICTX pURI, PSHAREDCLIPBOARDURITRANSFER pTransfer);
Index: trunk/include/VBox/GuestHost/SharedClipboard-win.h
===================================================================
--- trunk/include/VBox/GuestHost/SharedClipboard-win.h	(revision 79345)
+++ trunk/include/VBox/GuestHost/SharedClipboard-win.h	(revision 79347)
@@ -137,6 +137,6 @@
 int VBoxClipboardWinAnnounceFormats(PVBOXCLIPBOARDWINCTX pWinCtx, VBOXCLIPBOARDFORMATS fFormats);
 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
-int VBoxClipboardWinURIAnnounce(PVBOXCLIPBOARDWINCTX pWinCtx, PSHAREDCLIPBOARDURICTX pURICtx,
-                                PSHAREDCLIPBOARDURITRANSFER pTransfer);
+int VBoxClipboardWinURITransferCreate(PVBOXCLIPBOARDWINCTX pWinCtx, PSHAREDCLIPBOARDURITRANSFER pTransfer);
+void VBoxClipboardWinURITransferDestroy(PVBOXCLIPBOARDWINCTX pWinCtx, PSHAREDCLIPBOARDURITRANSFER pTransfer);
 #endif
 
@@ -204,4 +204,5 @@
 
     int Init(void);
+    void OnMetaDataComplete(PSHAREDCLIPBOARDURITRANSFER pTransfer);
     void OnTransferComplete(int rc = VINF_SUCCESS);
     void OnTransferCanceled();
@@ -222,9 +223,4 @@
     void registerFormat(LPFORMATETC pFormatEtc, CLIPFORMAT clipFormat, TYMED tyMed = TYMED_HGLOBAL,
                         LONG lindex = -1, DWORD dwAspect = DVASPECT_CONTENT, DVTARGETDEVICE *pTargetDevice = NULL);
-
-protected: /* URI transfer callbacks */
-
-    static DECLCALLBACK(void) onMetaDataCompleteCallback(PSHAREDCLIPBOARDURITRANSFERCALLBACKDATA pData);
-
 protected:
 
Index: trunk/include/VBox/HostServices/VBoxClipboardSvc.h
===================================================================
--- trunk/include/VBox/HostServices/VBoxClipboardSvc.h	(revision 79345)
+++ trunk/include/VBox/HostServices/VBoxClipboardSvc.h	(revision 79347)
@@ -402,4 +402,9 @@
 } VBOXCLIPBOARDDATACHUNK, *PVBOXCLIPBOARDDATACHUNK;
 
+typedef struct _VBOXCLIPBOARDOBJHDR
+{
+    uint32_t                    enmType;
+} VBOXCLIPBOARDOBJHDR, *PVBOXCLIPBOARDOBJHDR;
+
 typedef struct _VBOXCLIPBOARDDIRDATA
 {
@@ -448,14 +453,14 @@
 
 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
-int VBoxSvcClipboardURIReadDataHdr(uint32_t cParms, VBOXHGCMSVCPARM paParms[], PVBOXCLIPBOARDDATAHDR pDataHdr);
-int VBoxSvcClipboardURIWriteDataHdr(uint32_t cParms, VBOXHGCMSVCPARM paParms[], PVBOXCLIPBOARDDATAHDR pDataHdr);
-int VBoxSvcClipboardURIReadDataChunk(uint32_t cParms, VBOXHGCMSVCPARM paParms[], PVBOXCLIPBOARDDATACHUNK pDataChunk);
-int VBoxSvcClipboardURIWriteDataChunk(uint32_t cParms, VBOXHGCMSVCPARM paParms[], PVBOXCLIPBOARDDATACHUNK pDataChunk);
-int VBoxSvcClipboardURIReadDir(uint32_t cParms, VBOXHGCMSVCPARM paParms[], PVBOXCLIPBOARDDIRDATA pDirData);
-int VBoxSvcClipboardURIWriteDir(uint32_t cParms, VBOXHGCMSVCPARM paParms[], PVBOXCLIPBOARDDIRDATA pDirData);
-int VBoxSvcClipboardURIReadFileHdr(uint32_t cParms, VBOXHGCMSVCPARM paParms[], PVBOXCLIPBOARDFILEHDR pFileHdr);
-int VBoxSvcClipboardURIWriteFileHdr(uint32_t cParms, VBOXHGCMSVCPARM paParms[], PVBOXCLIPBOARDFILEHDR pFileHdr);
-int VBoxSvcClipboardURIReadFileData(uint32_t cParms, VBOXHGCMSVCPARM paParms[], PVBOXCLIPBOARDFILEDATA pFileData);
-int VBoxSvcClipboardURIWriteFileData(uint32_t cParms, VBOXHGCMSVCPARM paParms[], PVBOXCLIPBOARDFILEDATA pFileData);
+int VBoxSvcClipboardURIGetDataHdr(uint32_t cParms, VBOXHGCMSVCPARM paParms[], PVBOXCLIPBOARDDATAHDR pDataHdr);
+int VBoxSvcClipboardURISetDataHdr(uint32_t cParms, VBOXHGCMSVCPARM paParms[], PVBOXCLIPBOARDDATAHDR pDataHdr);
+int VBoxSvcClipboardURISetDataChunk(uint32_t cParms, VBOXHGCMSVCPARM paParms[], PVBOXCLIPBOARDDATACHUNK pDataChunk);
+int VBoxSvcClipboardURISetDataChunk(uint32_t cParms, VBOXHGCMSVCPARM paParms[], PVBOXCLIPBOARDDATACHUNK pDataChunk);
+int VBoxSvcClipboardURIGetDir(uint32_t cParms, VBOXHGCMSVCPARM paParms[], PVBOXCLIPBOARDDIRDATA pDirData);
+int VBoxSvcClipboardURISetDir(uint32_t cParms, VBOXHGCMSVCPARM paParms[], PVBOXCLIPBOARDDIRDATA pDirData);
+int VBoxSvcClipboardURIGetFileHdr(uint32_t cParms, VBOXHGCMSVCPARM paParms[], PVBOXCLIPBOARDFILEHDR pFileHdr);
+int VBoxSvcClipboardURISetFileHdr(uint32_t cParms, VBOXHGCMSVCPARM paParms[], PVBOXCLIPBOARDFILEHDR pFileHdr);
+int VBoxSvcClipboardURIGetFileData(uint32_t cParms, VBOXHGCMSVCPARM paParms[], PVBOXCLIPBOARDFILEDATA pFileData);
+int VBoxSvcClipboardURISetFileData(uint32_t cParms, VBOXHGCMSVCPARM paParms[], PVBOXCLIPBOARDFILEDATA pFileData);
 #endif
 
