Index: trunk/include/VBox/GuestHost/SharedClipboard-uri.h
===================================================================
--- trunk/include/VBox/GuestHost/SharedClipboard-uri.h	(revision 79173)
+++ trunk/include/VBox/GuestHost/SharedClipboard-uri.h	(revision 79174)
@@ -31,8 +31,4 @@
 #endif
 
-#ifdef VBOX_WITH_SHARED_CLIPBOARD_HOST
-#include <map> /* Needed for host provider. */
-#endif
-
 #include <iprt/assert.h>
 #include <iprt/critsect.h>
@@ -45,4 +41,8 @@
 #include <VBox/HostServices/VBoxClipboardSvc.h>
 
+#ifdef VBOX_WITH_SHARED_CLIPBOARD_HOST
+#include <map> /* Needed for host provider. */
+#endif
+
 /** Clipboard area ID. A valid area is >= 1.
  *  If 0 is specified, the last (most recent) area is meant.
@@ -56,8 +56,10 @@
 typedef uint32_t SHAREDCLIPBOARDAREAOPENFLAGS;
 
-/** No open flags specified. */
+/** No clipboard area open flags specified. */
 #define SHAREDCLIPBOARDAREA_OPEN_FLAGS_NONE               0
 /** The clipboard area must not exist yet. */
 #define SHAREDCLIPBOARDAREA_OPEN_FLAGS_MUST_NOT_EXIST     RT_BIT(0)
+/** Mask of all valid clipboard area open flags.  */
+#define SHAREDCLIPBOARDAREA_OPEN_FLAGS_VALID_MASK         0x1
 
 /**
@@ -382,14 +384,33 @@
 };
 
+uint32_t SharedClipboardURIDataHdrGetMetaDataSize(PVBOXCLIPBOARDDATAHDR pDataHdr);
 int SharedClipboardURIDataHdrInit(PVBOXCLIPBOARDDATAHDR pDataHdr);
 void SharedClipboardURIDataHdrDestroy(PVBOXCLIPBOARDDATAHDR pDataHdr);
+void SharedClipboardURIDataHdrReset(PVBOXCLIPBOARDDATAHDR pDataHdr);
 bool SharedClipboardURIDataHdrIsValid(PVBOXCLIPBOARDDATAHDR pDataHdr);
+
 bool SharedClipboardURIDataChunkIsValid(PVBOXCLIPBOARDDATACHUNK pDataChunk);
+
 void SharedClipboardURIDirDataDestroy(PVBOXCLIPBOARDDIRDATA pDirData);
 bool SharedClipboardURIDirDataIsValid(PVBOXCLIPBOARDDIRDATA pDirData);
+
 void SharedClipboardURIFileHdrDestroy(PVBOXCLIPBOARDFILEHDR pFileHdr);
 bool SharedClipboardURIFileHdrIsValid(PVBOXCLIPBOARDFILEHDR pFileHdr, PVBOXCLIPBOARDDATAHDR pDataHdr);
+
 void SharedClipboardURIFileDataDestroy(PVBOXCLIPBOARDFILEDATA pFileData);
 bool SharedClipboardURIFileDataIsValid(PVBOXCLIPBOARDFILEDATA pFileData, PVBOXCLIPBOARDDATAHDR pDataHdr);
+
+/**
+ * Structure for maintaining a meta data format.
+ */
+typedef struct _SHAREDCLIPBOARDMETADATAFMT
+{
+    /** Meta data format version. */
+    uint32_t uVer;
+    /** Actual meta data format data. */
+    void    *pvFmt;
+    /** Size of meta data format data (in bytes). */
+    uint32_t cbFmt;
+} SHAREDCLIPBOARDMETADATAFMT, *PSHAREDCLIPBOARDMETADATAFMT;
 
 /**
@@ -419,13 +440,31 @@
 
 /**
- * Structure for maintaining an URI transfer cache.
- */
-typedef struct _SHAREDCLIPBOARDURITRANSFERCACHE
-{
+ * Enumeration specifying an URI transfer direction.
+ */
+typedef enum _SHAREDCLIPBOARDURITRANSFERDIR
+{
+    /** Unknown transfer directory. */
+    SHAREDCLIPBOARDURITRANSFERDIR_UNKNOWN = 0,
+    /** Read transfer (from source). */
+    SHAREDCLIPBOARDURITRANSFERDIR_READ,
+    /** Write transfer (to target). */
+    SHAREDCLIPBOARDURITRANSFERDIR_WRITE,
+    /** The usual 32-bit hack. */
+    SHAREDCLIPBOARDURITRANSFERDIR__32BIT_HACK = 0x7fffffff
+} SHAREDCLIPBOARDURITRANSFERDIR;
+
+/**
+ * Structure for maintaining an URI transfer state.
+ * Everything in here will be part of a saved state (later).
+ */
+typedef struct _SHAREDCLIPBOARDURITRANSFERSTATE
+{
+    /** The transfer's direction. */
+    SHAREDCLIPBOARDURITRANSFERDIR enmDir;
     /** The transfer's cached data header. */
-    VBOXCLIPBOARDDATAHDR        Header;
+    VBOXCLIPBOARDDATAHDR          Header;
     /** The transfer's cached meta data. */
-    SHAREDCLIPBOARDMETADATA     Meta;
-} SHAREDCLIPBOARDURITRANSFERCACHE, *PSHAREDCLIPBOARDURITRANSFERCACHE;
+    SHAREDCLIPBOARDMETADATA       Meta;
+} SHAREDCLIPBOARDURITRANSFERSTATE, *PSHAREDCLIPBOARDURITRANSFERSTATE;
 
 /**
@@ -442,4 +481,33 @@
 } SHAREDCLIPBOARDPROVIDERSOURCE;
 
+class SharedClipboardProvider;
+
+/**
+ * Structure for storing clipboard provider callback data.
+ */
+typedef struct _SHAREDCLIPBOARDPROVIDERCALLBACKDATA
+{
+    /** Pointer to related clipboard provider ("this"). */
+    SharedClipboardProvider    *pProvider;
+    /** Saved user pointer. */
+    void                       *pvUser;
+} SHAREDCLIPBOARDPROVIDERCALLBACKDATA, *PSHAREDCLIPBOARDPROVIDERCALLBACKDATA;
+
+typedef DECLCALLBACK(int) FNSSHAREDCLIPBOARDPROVIDERREADDATAHDR(PSHAREDCLIPBOARDPROVIDERCALLBACKDATA pData);
+/** Pointer to a FNSSHAREDCLIPBOARDPROVIDERREADDATAHDR function. */
+typedef FNSSHAREDCLIPBOARDPROVIDERREADDATAHDR *PFNSSHAREDCLIPBOARDPROVIDERREADDATAHDR;
+
+/**
+ * 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 the transfer has been started. */
+    PFNSSHAREDCLIPBOARDPROVIDERREADDATAHDR  pfnReadDataHdr;
+} SHAREDCLIPBOARDPROVIDERCALLBACKS, *PSHAREDCLIPBOARDPROVIDERCALLBACKS;
+
 /**
  * Structure for the Shared Clipboard provider creation context.
@@ -447,5 +515,8 @@
 typedef struct _SHAREDCLIPBOARDPROVIDERCREATIONCTX
 {
-    SHAREDCLIPBOARDPROVIDERSOURCE enmSource;
+    /** Specifies what the source of the provider is. */
+    SHAREDCLIPBOARDPROVIDERSOURCE     enmSource;
+    /** Optional callback table; can be NULL if not needed. */
+    PSHAREDCLIPBOARDPROVIDERCALLBACKS pCallbacks;
     union
     {
@@ -454,5 +525,8 @@
             /** HGCM client ID to use. */
             uint32_t uClientID;
-        } VBGLR3;
+        } VbglR3;
+        struct
+        {
+        } HostService;
     } u;
 } SHAREDCLIPBOARDPROVIDERCREATIONCTX, *PSHAREDCLIPBOARDPROVIDERCREATIONCTX;
@@ -467,5 +541,4 @@
         struct
         {
-
         } HostService;
     } u;
@@ -508,4 +581,8 @@
     uint32_t Release(void);
 
+public:
+
+    void SetCallbacks(PSHAREDCLIPBOARDPROVIDERCALLBACKS pCallbacks);
+
 public: /* Interface to be implemented. */
 
@@ -543,5 +620,7 @@
 
     /** Number of references to this instance. */
-    volatile uint32_t      m_cRefs;
+    volatile uint32_t                m_cRefs;
+    /** The provider's callback table. */
+    SHAREDCLIPBOARDPROVIDERCALLBACKS m_Callbacks;
 };
 
@@ -644,5 +723,7 @@
         /** The event's own event semaphore. */
         RTSEMEVENT  mEvent;
+        /** User-provided data buffer associated to this event. Optional. */
         void       *mpvData;
+        /** Size (in bytes) of user-provided data buffer associated to this event. */
         uint32_t    mcbData;
     };
@@ -658,8 +739,8 @@
 protected:
 
+    /** Default timeout (in ms) for waiting for events. */
     RTMSINTERVAL                    m_uTimeoutMs;
-    SHAREDCLIPBOARDURITRANSFERCACHE m_Cache;
+    /** Map of (internal) events to provide asynchronous reads / writes. */
     EventMap                        m_mapEvents;
-
 };
 #endif /* VBOX_WITH_SHARED_CLIPBOARD_HOST */
@@ -728,19 +809,4 @@
 
 /**
- * Enumeration specifying an URI transfer direction.
- */
-typedef enum _SHAREDCLIPBOARDURITRANSFERDIR
-{
-    /** Unknown transfer directory. */
-    SHAREDCLIPBOARDURITRANSFERDIR_UNKNOWN = 0,
-    /** Read transfer (from source). */
-    SHAREDCLIPBOARDURITRANSFERDIR_READ,
-    /** Write transfer (to target). */
-    SHAREDCLIPBOARDURITRANSFERDIR_WRITE,
-    /** The usual 32-bit hack. */
-    SHAREDCLIPBOARDURITRANSFERDIR__32BIT_HACK = 0x7fffffff
-} SHAREDCLIPBOARDURITRANSFERDIR;
-
-/**
  * Structure for handling a single URI object context.
  */
@@ -762,8 +828,6 @@
     /** Critical section for serializing access. */
     RTCRITSECT                          CritSect;
-    /** The transfer's direction. */
-    SHAREDCLIPBOARDURITRANSFERDIR       enmDir;
-    /** The transfer's cache. */
-    SHAREDCLIPBOARDURITRANSFERCACHE     Cache;
+    /** The transfer's state (for SSM, later). */
+    SHAREDCLIPBOARDURITRANSFERSTATE     State;
     /** The transfer's own (local) area, if any (can be NULL if not needed).
      *  The area itself has a clipboard area ID assigned.
@@ -797,8 +861,8 @@
     RTLISTANCHOR                List;
     /** Number of concurrent transfers.
-     *  At the moment we only support only one transfer at a time. */
+     *  At the moment we only support only one transfer per client at a time. */
     uint32_t                    cTransfers;
     /** Maximum Number of concurrent transfers.
-     *  At the moment we only support one transfer at a time (per client). */
+     *  At the moment we only support only one transfer per client at a time. */
     uint32_t                    cMaxTransfers;
 } SHAREDCLIPBOARDURICTX, *PSHAREDCLIPBOARDURICTX;
@@ -822,4 +886,5 @@
 
 int SharedClipboardURITransferMetaDataAdd(PSHAREDCLIPBOARDURITRANSFER pTransfer, const void *pvMeta, uint32_t cbMeta);
+int SharedClipboardURITransferMetaDataComplete(PSHAREDCLIPBOARDURITRANSFER pTransfer);
 int SharedClipboardURITransferMetaGet(PSHAREDCLIPBOARDURITRANSFER pTransfer, const void *pvMeta, uint32_t cbMeta);
 int SharedClipboardURITransferMetaDataRead(PSHAREDCLIPBOARDURITRANSFER pTransfer, uint32_t *pcbRead);
Index: trunk/include/VBox/GuestHost/SharedClipboard-win.h
===================================================================
--- trunk/include/VBox/GuestHost/SharedClipboard-win.h	(revision 79173)
+++ trunk/include/VBox/GuestHost/SharedClipboard-win.h	(revision 79174)
@@ -98,4 +98,6 @@
     /** Window handle which is next to us in the clipboard chain. */
     HWND                        hWndNextInChain;
+    /** Window handle of the clipboard owner *if* we are the owner. */
+    HWND                        hWndClipboardOwnerUs;
     /** Structure for maintaining the new clipboard API. */
     VBOXCLIPBOARDWINAPINEW      newAPI;
@@ -107,9 +109,12 @@
 int VBoxClipboardWinClose(void);
 int VBoxClipboardWinClear(void);
+
 int VBoxClipboardWinCheckAndInitNewAPI(PVBOXCLIPBOARDWINAPINEW pAPI);
 bool VBoxClipboardWinIsNewAPI(PVBOXCLIPBOARDWINAPINEW pAPI);
-int VBoxClipboardWinAddToCBChain(PVBOXCLIPBOARDWINCTX pCtx);
-int VBoxClipboardWinRemoveFromCBChain(PVBOXCLIPBOARDWINCTX pCtx);
+
+int VBoxClipboardWinChainAdd(PVBOXCLIPBOARDWINCTX pCtx);
+int VBoxClipboardWinChainRemove(PVBOXCLIPBOARDWINCTX pCtx);
 VOID CALLBACK VBoxClipboardWinChainPingProc(HWND hWnd, UINT uMsg, ULONG_PTR dwData, LRESULT lResult);
+LRESULT VBoxClipboardWinChainPassToNext(PVBOXCLIPBOARDWINCTX pWinCtx, UINT msg, WPARAM wParam, LPARAM lParam);
 
 VBOXCLIPBOARDFORMAT VBoxClipboardWinClipboardFormatToVBox(UINT uFormat);
@@ -125,8 +130,17 @@
 int VBoxClipboardWinConvertMIMEToCFHTML(const char *pszSource, size_t cb, char **ppszOutput, uint32_t *pcbOutput);
 
-int VBoxClipboardWinHandleWMSetFormats(const PVBOXCLIPBOARDWINCTX pCtx, VBOXCLIPBOARDFORMATS fFormats);
+void VBoxClipboardWinDump(const void *pv, size_t cb, VBOXCLIPBOARDFORMAT u32Format);
+int VBoxClipboardWinOHandleMSetFormats(PVBOXCLIPBOARDWINCTX pWinCtx, PSHAREDCLIPBOARDURICTX pURICtx,
+                                       PSHAREDCLIPBOARDPROVIDERCREATIONCTX pProviderCtx);
+
+LRESULT VBoxClipboardWinHandleWMChangeCBChain(PVBOXCLIPBOARDWINCTX pWinCtx, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
+int VBoxClipboardWinHandleWMDestroy(PVBOXCLIPBOARDWINCTX pWinCtx);
+int VBoxClipboardWinHandleWMRenderAllFormats(PVBOXCLIPBOARDWINCTX pWinCtx, HWND hWnd);
+int VBoxClipboardWinHandleWMTimer(PVBOXCLIPBOARDWINCTX pWinCtx);
+
+int VBoxClipboardWinAnnounceFormats(PVBOXCLIPBOARDWINCTX pWinCtx, VBOXCLIPBOARDFORMATS fFormats);
 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
-int VBoxClipboardWinURIHandleWMSetFormats(const PVBOXCLIPBOARDWINCTX pCtx, PSHAREDCLIPBOARDURICTX pURICtx,
-                                          PSHAREDCLIPBOARDPROVIDERCREATIONCTX pProviderCtx, VBOXCLIPBOARDFORMATS fFormats);
+int VBoxClipboardWinURIReadMain(PVBOXCLIPBOARDWINCTX pWinCtx, PSHAREDCLIPBOARDURICTX pURICtx,
+                                PSHAREDCLIPBOARDPROVIDERCREATIONCTX pProviderCtx, VBOXCLIPBOARDFORMATS fFormats);
 #endif
 
Index: trunk/include/VBox/GuestHost/SharedClipboard.h
===================================================================
--- trunk/include/VBox/GuestHost/SharedClipboard.h	(revision 79173)
+++ trunk/include/VBox/GuestHost/SharedClipboard.h	(revision 79174)
@@ -38,7 +38,7 @@
 typedef VBOXCLIPBOARDFORMAT *PVBOXCLIPBOARDFORMAT;
 
-/** Bit map of Shared Clipboard format. */
+/** Bit map of Shared Clipboard formats. */
 typedef uint32_t VBOXCLIPBOARDFORMATS;
-/** Pointer to a bit map of Shared Clipboard format. */
+/** Pointer to a bit map of Shared Clipboard formats. */
 typedef VBOXCLIPBOARDFORMATS *PVBOXCLIPBOARDFORMATS;
 
Index: trunk/include/VBox/GuestHost/clipboard-helper.h
===================================================================
--- trunk/include/VBox/GuestHost/clipboard-helper.h	(revision 79173)
+++ trunk/include/VBox/GuestHost/clipboard-helper.h	(revision 79174)
@@ -170,4 +170,14 @@
 int vboxClipboardBmpGetDib(const void *pvSrc, size_t cbSrc, const void **ppvDst, size_t *pcbDst);
 
+#ifdef VBOX_STRICT
+/**
+ * Dumps HTML data to the debug log.
+ *
+ * @returns VBox status code.
+ * @param   pszSrc              HTML data to dump.
+ * @param   cb                  Size (in bytes) of HTML data to dump.
+ */
+int vboxClipboardDbgDumpHtml(const char *pszSrc, size_t cbSrc);
+#endif
 
 #endif /* !VBOX_INCLUDED_GuestHost_clipboard_helper_h */
Index: trunk/include/VBox/HostServices/VBoxClipboardSvc.h
===================================================================
--- trunk/include/VBox/HostServices/VBoxClipboardSvc.h	(revision 79173)
+++ trunk/include/VBox/HostServices/VBoxClipboardSvc.h	(revision 79174)
@@ -127,5 +127,5 @@
 #define VBOX_SHARED_CLIPBOARD_CPARMS_GET_HOST_MSG 2
 
-typedef struct _VBoxClipboardWriteFormatsMsg
+typedef struct _VBoxClipboardReportFormatsMsg
 {
     VBGLIOCHGCMCALL hdr;
@@ -133,7 +133,7 @@
     /* VBOX_SHARED_CLIPBOARD_FMT_* */
     HGCMFunctionParameter formats; /* OUT uint32_t */
-} VBoxClipboardWriteFormatsMsg;
-
-#define VBOX_SHARED_CLIPBOARD_CPARMS_FORMATS 1
+} VBoxClipboardReportFormatsMsg;
+
+#define VBOX_SHARED_CLIPBOARD_CPARMS_REPORT_FORMATS 1
 
 typedef struct _VBoxClipboardReadDataMsg
@@ -369,7 +369,9 @@
      *  This size also is part of cbTotal already. */
     uint32_t                    cbMeta;
-    /** Meta format buffer. */
+    /** Meta data format.
+     *  Is SHAREDCLIPBOARDMETADATAFMT. */
     void                       *pvMetaFmt;
-    /** Size (in bytes) of meta format buffer. */
+    /** Size (in bytes) of meta format buffer.
+     *  Is sizeof(SHAREDCLIPBOARDMETADATAFMT). */
     uint32_t                    cbMetaFmt;
     /** Number of objects (files/directories) to transfer. */
