Index: trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-internal.h
===================================================================
--- trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-internal.h	(revision 80560)
+++ trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-internal.h	(revision 80562)
@@ -231,4 +231,6 @@
 int vboxSvcClipboardOldCompleteReadData(PVBOXCLIPBOARDCLIENT pClient, int rc, uint32_t cbActual);
 int vboxSvcClipboardOldReportMsg(PVBOXCLIPBOARDCLIENT pClient, uint32_t uMsg, uint32_t uFormats);
+void vboxSvcClipboardOldClientStateResetData(PVBOXCLIPBOARDCLIENTSTATE pClientState);
+void vboxSvcClipboardOldClientStateReset(PVBOXCLIPBOARDCLIENTSTATE pClientState);
 
 uint32_t vboxSvcClipboardGetMode(void);
@@ -246,4 +248,7 @@
 
 # ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
+int vboxSvcClipboardURITransferStart(PVBOXCLIPBOARDCLIENT pClient,
+                                     SHAREDCLIPBOARDURITRANSFERDIR enmDir, SHAREDCLIPBOARDSOURCE enmSource,
+                                     PSHAREDCLIPBOARDURITRANSFER *ppTransfer);
 bool vboxSvcClipboardURIMsgIsAllowed(uint32_t uMode, uint32_t uMsg);
 # endif /* VBOX_WITH_SHARED_CLIPBOARD_URI_LIST */
@@ -258,4 +263,5 @@
 int VBoxClipboardSvcImplDisconnect(PVBOXCLIPBOARDCLIENT pClient);
 int VBoxClipboardSvcImplFormatAnnounce(PVBOXCLIPBOARDCLIENT pClient, PVBOXCLIPBOARDCLIENTCMDCTX pCmdCtx, PSHAREDCLIPBOARDFORMATDATA pFormats);
+/** @todo Document: Can return VINF_HGCM_ASYNC_EXECUTE to defer returning read data.*/
 int VBoxClipboardSvcImplReadData(PVBOXCLIPBOARDCLIENT pClient, PVBOXCLIPBOARDCLIENTCMDCTX pCmdCtx, PSHAREDCLIPBOARDDATABLOCK pData, uint32_t *pcbActual);
 int VBoxClipboardSvcImplWriteData(PVBOXCLIPBOARDCLIENT pClient, PVBOXCLIPBOARDCLIENTCMDCTX pCmdCtx, PSHAREDCLIPBOARDDATABLOCK pData);
@@ -268,8 +274,10 @@
 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
 int vboxSvcClipboardURITransferOpen(PSHAREDCLIPBOARDPROVIDERCTX pCtx);
-int vboxSvcClipboardURITransferClose(PSHAREDCLIPBOARDPROVIDERCTX pCtx);
+DECLCALLBACK(int) vboxSvcClipboardURITransferClose(PSHAREDCLIPBOARDPROVIDERCTX pCtx);
+
+int vboxSvcClipboardURIGetRoots(PSHAREDCLIPBOARDPROVIDERCTX pCtx, PVBOXCLIPBOARDROOTLIST *ppRootList);
 
 int vboxSvcClipboardURIListOpen(PSHAREDCLIPBOARDPROVIDERCTX pCtx,
-                                PVBOXCLIPBOARDLISTHDR pListHdr, PSHAREDCLIPBOARDLISTHANDLE phList);
+                                PVBOXCLIPBOARDLISTOPENPARMS pOpenParms, PSHAREDCLIPBOARDLISTHANDLE phList);
 int vboxSvcClipboardURIListClose(PSHAREDCLIPBOARDPROVIDERCTX pCtx, SHAREDCLIPBOARDLISTHANDLE hList);
 int vboxSvcClipboardURIListHdrRead(PSHAREDCLIPBOARDPROVIDERCTX pCtx, SHAREDCLIPBOARDLISTHANDLE hList,
Index: trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-win.cpp
===================================================================
--- trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-win.cpp	(revision 80560)
+++ trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-win.cpp	(revision 80562)
@@ -216,21 +216,10 @@
                                                 pCtx->pClient->State.Old.data.pv, pCtx->pClient->State.Old.data.cb);
 
-                if (pCtx->pClient->State.Old.data.pv)
-                {
-                    RTMemFree(pCtx->pClient->State.Old.data.pv);
-                    pCtx->pClient->State.Old.data.pv = NULL;
-                }
+                vboxSvcClipboardOldClientStateResetData(&pCtx->pClient->State);
             }
 
             if (RT_FAILURE(rc))
             {
-                if (pCtx->pClient->State.Old.data.pv)
-                {
-                    RTMemFree(pCtx->pClient->State.Old.data.pv);
-                    pCtx->pClient->State.Old.data.pv = NULL;
-                }
-
-                pCtx->pClient->State.Old.data.cb        = 0;
-                pCtx->pClient->State.Old.data.u32Format = 0;
+                vboxSvcClipboardOldClientStateReset(&pCtx->pClient->State);
 
                 /* Something went wrong. */
@@ -438,32 +427,8 @@
                 {
                     VBoxClipboardWinClear();
-#if 0
-                    if (fFormats & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST)
-                    {
-                        LogFunc(("VBOX_SHARED_CLIPBOARD_FMT_URI_LIST\n"));
-
-                        PSHAREDCLIPBOARDURITRANSFER pTransfer = SharedClipboardURICtxGetTransfer(&pCtx->pClient->URI,
-                                                                                                 0 /* uIdx */);
-                        if (pTransfer)
-                        {
-                            rc = VBoxClipboardWinURITransferCreate(pWinCtx, pTransfer);
-
-                            /* Note: The actual requesting + retrieving of data will be done in the IDataObject implementation
-                                     (ClipboardDataObjectImpl::GetData()). */
-                        }
-                        else
-                            AssertFailedStmt(rc = VERR_NOT_FOUND);
-
-                        /* Note: VBoxClipboardWinURITransferCreate() takes care of closing the clipboard. */
-                    }
-                    else
-                    {
-#endif
-                        rc = VBoxClipboardWinAnnounceFormats(pWinCtx, fFormats);
-
-                        VBoxClipboardWinClose();
-#if 0
-                    }
-#endif
+
+                    rc = VBoxClipboardWinAnnounceFormats(pWinCtx, fFormats);
+
+                    VBoxClipboardWinClose();
                 }
 
@@ -806,4 +771,6 @@
     RT_NOREF(pCmdCtx);
 
+    int rc;
+
     PVBOXCLIPBOARDCONTEXT pCtx = pClient->State.pCtx;
     AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
@@ -811,11 +778,37 @@
     LogFlowFunc(("uFormats=0x%x, hWnd=%p\n", pFormats->uFormats, pCtx->Win.hWnd));
 
-    /*
-     * The guest announced formats. Forward to the window thread.
-     */
-    PostMessage(pCtx->Win.hWnd, VBOX_CLIPBOARD_WM_REPORT_FORMATS,
-                0 /* wParam */, pFormats->uFormats /* lParam */);
-
-    return VINF_SUCCESS;
+    if (!(pFormats->uFormats & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST))
+    {
+        /*
+         * The guest announced formats. Forward to the window thread.
+         */
+        PostMessage(pCtx->Win.hWnd, VBOX_CLIPBOARD_WM_REPORT_FORMATS,
+                    0 /* wParam */, pFormats->uFormats /* lParam */);
+
+        rc = VINF_SUCCESS;
+    }
+#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
+    else if (pFormats->uFormats & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST)
+    {
+        PSHAREDCLIPBOARDURITRANSFER pTransfer;
+        rc = vboxSvcClipboardURITransferStart(pClient,
+                                              SHAREDCLIPBOARDURITRANSFERDIR_READ, SHAREDCLIPBOARDSOURCE_REMOTE,
+                                              &pTransfer);
+        if (RT_SUCCESS(rc))
+        {
+            /* Create the IDataObject implementation the host OS needs and assign
+             * the newly created transfer to this object. */
+            rc = VBoxClipboardWinURITransferCreate(&pCtx->Win, pTransfer);
+
+            /*  Note: The actual requesting + retrieving of data will be done in the IDataObject implementation
+                      (ClipboardDataObjectImpl::GetData()). */
+        }
+    }
+#endif /* VBOX_WITH_SHARED_CLIPBOARD_URI_LIST */
+    else
+        rc = VERR_NOT_SUPPORTED;
+
+    LogFlowFuncLeaveRC(rc);
+    return rc;
 }
 
Index: trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc.cpp
===================================================================
--- trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc.cpp	(revision 80560)
+++ trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc.cpp	(revision 80562)
@@ -1019,4 +1019,94 @@
     return rc;
 }
+
+#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
+int vboxSvcClipboardURITransferStart(PVBOXCLIPBOARDCLIENT pClient,
+                                     SHAREDCLIPBOARDURITRANSFERDIR enmDir, SHAREDCLIPBOARDSOURCE enmSource,
+                                     PSHAREDCLIPBOARDURITRANSFER *ppTransfer)
+{
+    LogFlowFuncEnter();
+
+    SharedClipboardURICtxTransfersCleanup(&pClient->URI);
+
+    int rc;
+
+    if (!SharedClipboardURICtxTransfersMaximumReached(&pClient->URI))
+    {
+        PSHAREDCLIPBOARDURITRANSFER pTransfer;
+        rc = SharedClipboardURITransferCreate(enmDir, enmSource, &pTransfer);
+        if (RT_SUCCESS(rc))
+        {
+            SHAREDCLIPBOARDPROVIDERCREATIONCTX creationCtx;
+            RT_ZERO(creationCtx);
+
+            if (enmDir == SHAREDCLIPBOARDURITRANSFERDIR_READ)
+            {
+                rc = vboxSvcClipboardURIAreaRegister(&pClient->State, pTransfer);
+                if (RT_SUCCESS(rc))
+                {
+                    creationCtx.enmSource = pClient->State.enmSource;
+
+                    creationCtx.Interface.pfnTransferOpen    = vboxSvcClipboardURITransferOpen;
+                    creationCtx.Interface.pfnTransferClose   = vboxSvcClipboardURITransferClose;
+                    creationCtx.Interface.pfnListOpen        = vboxSvcClipboardURIListOpen;
+                    creationCtx.Interface.pfnListClose       = vboxSvcClipboardURIListClose;
+                    creationCtx.Interface.pfnObjOpen         = vboxSvcClipboardURIObjOpen;
+                    creationCtx.Interface.pfnObjClose        = vboxSvcClipboardURIObjClose;
+
+                    creationCtx.Interface.pfnGetRoots        = vboxSvcClipboardURIGetRoots;
+                    creationCtx.Interface.pfnListHdrRead     = vboxSvcClipboardURIListHdrRead;
+                    creationCtx.Interface.pfnListEntryRead   = vboxSvcClipboardURIListEntryRead;
+                    creationCtx.Interface.pfnObjRead         = vboxSvcClipboardURIObjRead;
+
+                    creationCtx.pvUser = pClient;
+                }
+            }
+            else if (enmDir == SHAREDCLIPBOARDURITRANSFERDIR_WRITE)
+            {
+                AssertFailed(); /** @todo Implement this. */
+            }
+
+            /* Register needed callbacks so that we can wait for the meta data to arrive here. */
+            SHAREDCLIPBOARDURITRANSFERCALLBACKS Callbacks;
+            RT_ZERO(Callbacks);
+
+            Callbacks.pvUser                = pClient;
+
+            Callbacks.pfnTransferPrepare    = VBoxSvcClipboardURITransferPrepareCallback;
+            Callbacks.pfnTransferComplete   = VBoxSvcClipboardURITransferCompleteCallback;
+            Callbacks.pfnTransferCanceled   = VBoxSvcClipboardURITransferCanceledCallback;
+            Callbacks.pfnTransferError      = VBoxSvcClipboardURITransferErrorCallback;
+
+            SharedClipboardURITransferSetCallbacks(pTransfer, &Callbacks);
+
+            rc = SharedClipboardURITransferSetInterface(pTransfer, &creationCtx);
+            if (RT_SUCCESS(rc))
+            {
+                rc = SharedClipboardURICtxTransferAdd(&pClient->URI, pTransfer);
+                if (RT_SUCCESS(rc))
+                    rc = VBoxClipboardSvcImplURITransferCreate(pClient, pTransfer);
+
+                if (RT_FAILURE(rc))
+                    VBoxClipboardSvcImplURITransferDestroy(pClient, pTransfer);
+            }
+
+            if (RT_FAILURE(rc))
+            {
+                SharedClipboardURITransferDestroy(pTransfer);
+                pTransfer = NULL;
+            }
+            else
+            {
+                *ppTransfer = pTransfer;
+            }
+        }
+    }
+    else
+        rc = VERR_SHCLPB_MAX_TRANSFERS_REACHED;
+
+    LogFlowFuncLeaveRC(rc);
+    return rc;
+}
+#endif /* VBOX_WITH_SHARED_CLIPBOARD_URI_LIST */
 
 static int svcInit(void)
@@ -1625,4 +1715,23 @@
 
 /**
+ * Resets the Shared Clipboard data reading porition of the old client state.
+ *
+ * Legacy protocol, do not use anymore.
+ *
+ * @param   pClientState        Client state to reset data reading portion for.
+ */
+void vboxSvcClipboardOldClientStateResetData(PVBOXCLIPBOARDCLIENTSTATE pClientState)
+{
+    if (pClientState->Old.data.pv)
+    {
+        RTMemFree(pClientState->Old.data.pv);
+        pClientState->Old.data.pv = NULL;
+    }
+
+    pClientState->Old.data.cb = 0;
+    pClientState->Old.data.u32Format = 0;
+}
+
+/**
  * Resets a Shared Clipboard service's old client state.
  * Legacy protocol, do not use anymore.
@@ -1630,17 +1739,19 @@
  * @param   pClientState        Client state to reset.
  */
-static void vboxSvcClipboardOldClientStateReset(PVBOXCLIPBOARDCLIENTSTATE pClientState)
+void vboxSvcClipboardOldClientStateReset(PVBOXCLIPBOARDCLIENTSTATE pClientState)
 {
     LogFlowFuncEnter();
 
-    pClientState->Old.fAsync                       = false;
-    pClientState->Old.fReadPending                 = false;
-
-    pClientState->Old.fHostMsgQuit                 = false;
-    pClientState->Old.fHostMsgReadData             = false;
-    pClientState->Old.fHostMsgFormats              = false;
+    pClientState->Old.fAsync              = false;
+    pClientState->Old.fReadPending        = false;
+
+    pClientState->Old.fHostMsgQuit        = false;
+    pClientState->Old.fHostMsgReadData    = false;
+    pClientState->Old.fHostMsgFormats     = false;
 
     pClientState->Old.u32AvailableFormats = 0;
     pClientState->Old.u32RequestedFormat  = 0;
+
+    vboxSvcClipboardOldClientStateResetData(pClientState);
 }
 
