Index: /trunk/include/VBox/GuestHost/SharedClipboard-transfers.h
===================================================================
--- /trunk/include/VBox/GuestHost/SharedClipboard-transfers.h	(revision 81228)
+++ /trunk/include/VBox/GuestHost/SharedClipboard-transfers.h	(revision 81229)
@@ -397,4 +397,8 @@
             SHCLLISTHANDLE uHandle;
         } ListOpen;
+        struct
+        {
+            SHCLLISTHANDLE uHandle;
+        } ListClose;
         struct
         {
Index: /trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibClipboard.cpp
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibClipboard.cpp	(revision 81228)
+++ /trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibClipboard.cpp	(revision 81229)
@@ -1953,5 +1953,5 @@
 
             SHCLLISTHANDLE hList  = SHCLLISTHANDLE_INVALID;
-            uint32_t                  fFlags = 0;
+            uint32_t       fFlags = 0;
             rc = VbglR3ClipboardListHdrReadRecvReq(pCmdCtx, &hList, &fFlags);
             if (RT_SUCCESS(rc))
@@ -1983,5 +1983,5 @@
             {
                 SHCLLISTHANDLE hList;
-                uint32_t                  fInfo;
+                uint32_t       fInfo;
                 rc = VbglR3ClipboardListEntryReadRecvReq(pCmdCtx, &hList, &fInfo);
                 if (RT_SUCCESS(rc))
@@ -2061,6 +2061,6 @@
         {
             SHCLOBJHANDLE hObj;
-            uint32_t cbBuf;
-            uint32_t fFlags;
+            uint32_t      cbBuf;
+            uint32_t      fFlags;
             rc = VbglR3ClipboardObjReadRecv(pCmdCtx, &hObj, &cbBuf, &fFlags);
             if (RT_SUCCESS(rc))
Index: /trunk/src/VBox/GuestHost/SharedClipboard/clipboard-transfers.cpp
===================================================================
--- /trunk/src/VBox/GuestHost/SharedClipboard/clipboard-transfers.cpp	(revision 81228)
+++ /trunk/src/VBox/GuestHost/SharedClipboard/clipboard-transfers.cpp	(revision 81229)
@@ -268,8 +268,8 @@
 
 /**
- * Initializes a transfer data  header struct.
- *
- * @returns VBox status code.
- * @param   pListHdr            Data header struct to initialize.
+ * Initializes a transfer list header structure.
+ *
+ * @returns VBox status code.
+ * @param   pListHdr            Transfer list header struct to initialize.
  */
 int ShClTransferListHdrInit(PSHCLLISTHDR pListHdr)
@@ -285,7 +285,7 @@
 
 /**
- * Destroys a transfer data  header struct.
- *
- * @param   pListHdr            Data header struct to destroy.
+ * Destroys a transfer list header structure.
+ *
+ * @param   pListHdr            Transfer list header struct to destroy.
  */
 void ShClTransferListHdrDestroy(PSHCLLISTHDR pListHdr)
@@ -298,8 +298,8 @@
 
 /**
- * Resets a SHCLListHdr structture.
- *
- * @returns VBox status code.
- * @param   pListHdr            SHCLListHdr structture to reset.
+ * Resets a transfer list header structure.
+ *
+ * @returns VBox status code.
+ * @param   pListHdr            Transfer list header struct to reset.
  */
 void ShClTransferListHdrReset(PSHCLLISTHDR pListHdr)
@@ -313,8 +313,8 @@
 
 /**
- * Returns whether a given clipboard data header is valid or not.
+ * Returns whether a given transfer list header is valid or not.
  *
  * @returns \c true if valid, \c false if not.
- * @param   pListHdr            Clipboard data header to validate.
+ * @param   pListHdr            Transfer list header to validate.
  */
 bool ShClTransferListHdrIsValid(PSHCLLISTHDR pListHdr)
@@ -880,5 +880,11 @@
                     rc = RTDirClose(pInfo->u.Local.hDir);
                     if (RT_SUCCESS(rc))
+                    {
                         pInfo->u.Local.hDir = NIL_RTDIR;
+
+                        LogRel2(("Shared Clipboard: Closed directory '%s'\n", pInfo->pszPathLocalAbs));
+                    }
+                    else
+                        LogRel(("Shared Clipboard: Closing directory '%s' failed with %Rrc\n", pInfo->pszPathLocalAbs, rc));
                     break;
                 }
@@ -888,5 +894,11 @@
                     rc = RTFileClose(pInfo->u.Local.hFile);
                     if (RT_SUCCESS(rc))
+                    {
                         pInfo->u.Local.hFile = NIL_RTFILE;
+
+                        LogRel2(("Shared Clipboard: Closed file '%s'\n", pInfo->pszPathLocalAbs));
+                    }
+                    else
+                        LogRel(("Shared Clipboard: Closing file '%s' failed with %Rrc\n", pInfo->pszPathLocalAbs, rc));
                     break;
                 }
@@ -1285,5 +1297,5 @@
 {
     PSHCLLISTHANDLEINFO pIt;
-    RTListForEach(&pTransfer->lstList, pIt, SHCLLISTHANDLEINFO, Node)
+    RTListForEach(&pTransfer->lstList, pIt, SHCLLISTHANDLEINFO, Node) /** @todo Sloooow ... improve this. */
     {
         if (pIt->hList == hList)
@@ -1303,4 +1315,48 @@
 {
     return pTransfer->uListHandleNext++; /** @todo Good enough for now. Improve this later. */
+}
+
+/**
+ * Resolves a relative path of a specific transfer to its absolute path.
+ *
+ * @returns VBox status code.
+ * @param   pTransfer           Clipboard transfer to resolve path for.
+ * @param   pszPath             Path to resolve.
+ * @param   fFlags              Resolve flags. Currently not used and must be 0.
+ * @param   ppszResolved        Where to store the allocated resolved path. Must be free'd by the called using RTStrFree().
+ */
+static int shClTransferResolvePathAbs(PSHCLTRANSFER pTransfer, const char *pszPath, uint32_t fFlags,
+                                      char **ppszResolved)
+{
+    AssertPtrReturn(pTransfer,   VERR_INVALID_POINTER);
+    AssertPtrReturn(pszPath,     VERR_INVALID_POINTER);
+    AssertReturn   (fFlags == 0, VERR_INVALID_PARAMETER);
+
+    /* Paranoia. */
+    if (   !strlen(pTransfer->pszPathRootAbs)
+        || !RTStrIsValidEncoding(pTransfer->pszPathRootAbs)
+        || !RTStrCmp(pTransfer->pszPathRootAbs, ".")
+        || !RTStrCmp(pTransfer->pszPathRootAbs, "..")
+        || !RTPathStartsWithRoot(pTransfer->pszPathRootAbs))
+    {
+        return VERR_INVALID_PARAMETER;
+    }
+
+    int rc;
+
+    char *pszResolved = RTPathJoinA(pTransfer->pszPathRootAbs, pszPath);
+    if (pszResolved)
+    {
+        LogFlowFunc(("pszPathRootAbs=%s, pszPath=%s -> %s\n", pTransfer->pszPathRootAbs, pszPath, pszResolved));
+
+        *ppszResolved = pszResolved;
+
+        rc = VINF_SUCCESS;
+    }
+    else
+        rc = VERR_NO_MEMORY;
+
+    LogFlowFuncLeaveRC(rc);
+    return rc;
 }
 
@@ -1322,71 +1378,97 @@
     int rc;
 
-    SHCLLISTHANDLE hList = SHCLLISTHANDLE_INVALID;
-
     if (pTransfer->State.enmSource == SHCLSOURCE_LOCAL)
     {
         LogFlowFunc(("pszPath=%s\n", pOpenParms->pszPath));
 
-        PSHCLLISTHANDLEINFO pInfo
-            = (PSHCLLISTHANDLEINFO)RTMemAlloc(sizeof(SHCLLISTHANDLEINFO));
-        if (pInfo)
-        {
-            rc = ShClTransferListHandleInfoInit(pInfo);
-            if (RT_SUCCESS(rc))
+        char *pszPathAbs;
+        rc = shClTransferResolvePathAbs(pTransfer, pOpenParms->pszPath, 0 /* fFlags */, &pszPathAbs);
+        if (RT_SUCCESS(rc))
+        {
+            PSHCLLISTHANDLEINFO pInfo
+                = (PSHCLLISTHANDLEINFO)RTMemAlloc(sizeof(SHCLLISTHANDLEINFO));
+            if (pInfo)
             {
-                RTFSOBJINFO objInfo;
-                rc = RTPathQueryInfo(pOpenParms->pszPath, &objInfo, RTFSOBJATTRADD_NOTHING);
+                rc = ShClTransferListHandleInfoInit(pInfo);
                 if (RT_SUCCESS(rc))
                 {
-                    if (RTFS_IS_DIRECTORY(objInfo.Attr.fMode))
-                    {
-                        rc = RTDirOpen(&pInfo->u.Local.hDir, pOpenParms->pszPath);
-                        if (RT_SUCCESS(rc))
-                            pInfo->enmType = SHCLOBJTYPE_DIRECTORY;
-
-                    }
-                    else if (RTFS_IS_FILE(objInfo.Attr.fMode))
-                    {
-                        rc = RTFileOpen(&pInfo->u.Local.hFile, pOpenParms->pszPath,
-                                        RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE);
-                        if (RT_SUCCESS(rc))
-                            pInfo->enmType = SHCLOBJTYPE_FILE;
-                    }
-                    else
-                        rc = VERR_NOT_SUPPORTED;
-
+                    RTFSOBJINFO objInfo;
+                    rc = RTPathQueryInfo(pOpenParms->pszPath, &objInfo, RTFSOBJATTRADD_NOTHING);
                     if (RT_SUCCESS(rc))
-                    {
-                        pInfo->hList = sharedClipboardTransferListHandleNew(pTransfer);
-
-                        RTListAppend(&pTransfer->lstList, &pInfo->Node);
-                    }
-                    else
                     {
                         if (RTFS_IS_DIRECTORY(objInfo.Attr.fMode))
                         {
-                            if (RTDirIsValid(pInfo->u.Local.hDir))
-                                RTDirClose(pInfo->u.Local.hDir);
+                            rc = RTDirOpen(&pInfo->u.Local.hDir, pszPathAbs);
+                            if (RT_SUCCESS(rc))
+                            {
+                                pInfo->enmType = SHCLOBJTYPE_DIRECTORY;
+
+                                LogRel2(("Shared Clipboard: Opening directory '%s'\n", pszPathAbs));
+                            }
+                            else
+                                LogRel(("Shared Clipboard: Opening directory '%s' failed with %Rrc\n", pInfo->pszPathLocalAbs, rc));
+
                         }
                         else if (RTFS_IS_FILE(objInfo.Attr.fMode))
                         {
-                            if (RTFileIsValid(pInfo->u.Local.hFile))
-                                RTFileClose(pInfo->u.Local.hFile);
+                            rc = RTFileOpen(&pInfo->u.Local.hFile, pszPathAbs,
+                                            RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE);
+                            if (RT_SUCCESS(rc))
+                            {
+                                pInfo->enmType = SHCLOBJTYPE_FILE;
+
+                                LogRel2(("Shared Clipboard: Opening file '%s'\n", pszPathAbs));
+                            }
+                            else
+                                LogRel(("Shared Clipboard: Opening file '%s' failed with %Rrc\n", pInfo->pszPathLocalAbs, rc));
+                        }
+                        else
+                            rc = VERR_NOT_SUPPORTED;
+
+                        if (RT_SUCCESS(rc))
+                        {
+                            pInfo->hList           = sharedClipboardTransferListHandleNew(pTransfer);
+                            pInfo->pszPathLocalAbs = RTStrDup(pszPathAbs);
+                            if (pInfo->pszPathLocalAbs)
+                            {
+                                RTListAppend(&pTransfer->lstList, &pInfo->Node);
+
+                                LogFlowFunc(("pszPathLocalAbs=%s, hList=%RU64\n", pInfo->pszPathLocalAbs, pInfo->hList));
+
+                                *phList = pInfo->hList;
+                            }
+                            else
+                                rc = VERR_NO_MEMORY;
+                        }
+                        else
+                        {
+                            if (RTFS_IS_DIRECTORY(objInfo.Attr.fMode))
+                            {
+                                if (RTDirIsValid(pInfo->u.Local.hDir))
+                                    RTDirClose(pInfo->u.Local.hDir);
+                            }
+                            else if (RTFS_IS_FILE(objInfo.Attr.fMode))
+                            {
+                                if (RTFileIsValid(pInfo->u.Local.hFile))
+                                    RTFileClose(pInfo->u.Local.hFile);
+                            }
                         }
                     }
+
+                    if (RT_FAILURE(rc))
+                        ShClTransferListHandleInfoDestroy(pInfo);
                 }
 
                 if (RT_FAILURE(rc))
-                    ShClTransferListHandleInfoDestroy(pInfo);
+                {
+                    RTMemFree(pInfo);
+                    pInfo = NULL;
+                }
             }
-
-            if (RT_FAILURE(rc))
-            {
-                RTMemFree(pInfo);
-                pInfo = NULL;
-            }
-        }
-        else
-            rc = VERR_NO_MEMORY;
+            else
+                rc = VERR_NO_MEMORY;
+
+            RTStrFree(pszPathAbs);
+        }
     }
     else if (pTransfer->State.enmSource == SHCLSOURCE_REMOTE)
@@ -1394,5 +1476,5 @@
         if (pTransfer->ProviderIface.pfnListOpen)
         {
-            rc = pTransfer->ProviderIface.pfnListOpen(&pTransfer->ProviderCtx, pOpenParms, &hList);
+            rc = pTransfer->ProviderIface.pfnListOpen(&pTransfer->ProviderCtx, pOpenParms, phList);
         }
         else
@@ -1401,7 +1483,4 @@
     else
         AssertFailedStmt(rc = VERR_NOT_IMPLEMENTED);
-
-    if (RT_SUCCESS(rc))
-        *phList = hList;
 
     LogFlowFuncLeaveRC(rc);
@@ -1499,25 +1578,18 @@
  * @param   cchDstBase          Number of charaters of destination base path.
  */
-static int sharedClipboardTransferListHdrFromDir(PSHCLLISTHDR pHdr,
-                                                 const char *pcszSrcPath, const char *pcszDstPath,
-                                                 const char *pcszDstBase)
-{
-    AssertPtrReturn(pcszSrcPath, VERR_INVALID_POINTER);
-    AssertPtrReturn(pcszDstBase, VERR_INVALID_POINTER);
-    AssertPtrReturn(pcszDstPath, VERR_INVALID_POINTER);
-
-    LogFlowFunc(("pcszSrcPath=%s, pcszDstPath=%s, pcszDstBase=%s\n",
-                 pcszSrcPath, pcszDstPath, pcszDstBase));
+static int sharedClipboardTransferListHdrFromDir(PSHCLLISTHDR pHdr, const char *pcszPathAbs)
+{
+    AssertPtrReturn(pcszPathAbs, VERR_INVALID_POINTER);
+
+    LogFlowFunc(("pcszPathAbs=%s\n", pcszPathAbs));
 
     RTFSOBJINFO objInfo;
-    int rc = RTPathQueryInfo(pcszSrcPath, &objInfo, RTFSOBJATTRADD_NOTHING);
+    int rc = RTPathQueryInfo(pcszPathAbs, &objInfo, RTFSOBJATTRADD_NOTHING);
     if (RT_SUCCESS(rc))
     {
         if (RTFS_IS_DIRECTORY(objInfo.Attr.fMode))
         {
-            pHdr->cTotalObjects++;
-
             RTDIR hDir;
-            rc = RTDirOpen(&hDir, pcszSrcPath);
+            rc = RTDirOpen(&hDir, pcszPathAbs);
             if (RT_SUCCESS(rc))
             {
@@ -1537,5 +1609,4 @@
                     switch (pDirEntry->Info.Attr.fMode & RTFS_TYPE_MASK)
                     {
-                #if 0 /* No recursion here (yet). */
                         case RTFS_TYPE_DIRECTORY:
                         {
@@ -1544,27 +1615,10 @@
                                 break;
 
-                            char *pszSrc = RTPathJoinA(pcszSrcPath, pDirEntry->szName);
-                            if (pszSrc)
-                            {
-                                char *pszDst = RTPathJoinA(pcszDstPath, pDirEntry->szName);
-                                if (pszDst)
-                                {
-                                    rc = sharedClipboardTransferListHdrFromDir(pHdr, pszSrc, pszDst,
-                                                                                  pcszDstBase, cchDstBase);
-                                    RTStrFree(pszDst);
-                                }
-                                else
-                                    rc = VERR_NO_MEMORY;
-
-                                RTStrFree(pszSrc);
-                            }
-                            else
-                                rc = VERR_NO_MEMORY;
+                            pHdr->cTotalObjects++;
                             break;
                         }
-                #endif
                         case RTFS_TYPE_FILE:
                         {
-                            char *pszSrc = RTPathJoinA(pcszSrcPath, pDirEntry->szName);
+                            char *pszSrc = RTPathJoinA(pcszPathAbs, pDirEntry->szName);
                             if (pszSrc)
                             {
@@ -1593,5 +1647,5 @@
         else if (RTFS_IS_FILE(objInfo.Attr.fMode))
         {
-            rc = sharedClipboardTransferListHdrAddFile(pHdr, pcszSrcPath);
+            rc = sharedClipboardTransferListHdrAddFile(pHdr, pcszPathAbs);
         }
         else if (RTFS_IS_SYMLINK(objInfo.Attr.fMode))
@@ -1616,4 +1670,8 @@
 static char *sharedClipboardPathTranslate(const char *pszPath)
 {
+    AssertPtrReturn(pszPath, NULL);
+
+    LogFlowFunc(("pszPath=%s\n", pszPath));
+
     char *pszPathTranslated = NULL;
 
@@ -1673,13 +1731,7 @@
                     case SHCLOBJTYPE_DIRECTORY:
                     {
-                        char *pszPathRel = sharedClipboardPathTranslate(pInfo->pszPathLocalAbs);
-                        if (pszPathRel)
-                        {
-                            rc = sharedClipboardTransferListHdrFromDir(pHdr,
-                                                                       pszPathRel, pszPathRel, pszPathRel);
-                            RTStrFree(pszPathRel);
-                        }
-                        else
-                            rc = VERR_NO_MEMORY;
+                        LogFlowFunc(("DirAbs: %s\n", pInfo->pszPathLocalAbs));
+
+                        rc = sharedClipboardTransferListHdrFromDir(pHdr, pInfo->pszPathLocalAbs);
                         break;
                     }
@@ -1687,4 +1739,6 @@
                     case SHCLOBJTYPE_FILE:
                     {
+                        LogFlowFunc(("FileAbs: %s\n", pInfo->pszPathLocalAbs));
+
                         pHdr->cTotalObjects = 1;
 
@@ -2513,5 +2567,6 @@
     LogFlowFunc(("pTransferCtx=%p\n", pTransferCtx));
 
-    RTCritSectDelete(&pTransferCtx->CritSect);
+    if (RTCritSectIsInitialized(&pTransferCtx->CritSect))
+        RTCritSectDelete(&pTransferCtx->CritSect);
 
     PSHCLTRANSFER pTransfer, pTransferNext;
Index: /trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-internal.h
===================================================================
--- /trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-internal.h	(revision 81228)
+++ /trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-internal.h	(revision 81229)
@@ -200,4 +200,5 @@
 int shclSvcTransferStop(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer);
 bool shclSvcTransferMsgIsAllowed(uint32_t uMode, uint32_t uMsg);
+void shclSvcClientTransfersReset(PSHCLCLIENT pClient);
 #endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */
 
Index: /trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-transfers.cpp
===================================================================
--- /trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-transfers.cpp	(revision 81228)
+++ /trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-transfers.cpp	(revision 81229)
@@ -58,4 +58,32 @@
 *********************************************************************************************************************************/
 
+/**
+ * Resets all transfers of a Shared Clipboard client.
+ *
+ * @param   pClient             Client to reset transfers for.
+ */
+void shclSvcClientTransfersReset(PSHCLCLIENT pClient)
+{
+    if (!pClient)
+        return;
+
+    LogFlowFuncEnter();
+
+    const uint32_t cTransfers = ShClTransferCtxGetTotalTransfers(&pClient->TransferCtx);
+    for (uint32_t i = 0; i < cTransfers; i++)
+    {
+        PSHCLTRANSFER pTransfer = ShClTransferCtxGetTransfer(&pClient->TransferCtx, i);
+        if (pTransfer)
+            shclSvcTransferAreaDetach(&pClient->State, pTransfer);
+    }
+
+    ShClTransferCtxDestroy(&pClient->TransferCtx);
+}
+
+
+/*********************************************************************************************************************************
+*   Provider implementation                                                                                                      *
+*********************************************************************************************************************************/
+
 DECLCALLBACK(int) shclSvcTransferIfaceOpen(PSHCLPROVIDERCTX pCtx)
 {
@@ -208,5 +236,5 @@
         const SHCLEVENTID uEvent = ShClEventIDGenerate(&pCtx->pTransfer->Events);
 
-        pMsg->Ctx.uContextID = VBOX_SHCL_CONTEXTID_MAKE(pClient->State.uSessionID,  pCtx->pTransfer->State.uID,
+        pMsg->Ctx.uContextID = VBOX_SHCL_CONTEXTID_MAKE(pClient->State.uSessionID, pCtx->pTransfer->State.uID,
                                                         uEvent);
 
@@ -233,4 +261,6 @@
 
                         Assert(pReply->uType == VBOX_SHCL_REPLYMSGTYPE_LIST_OPEN);
+
+                        LogFlowFunc(("hList=%RU64\n", pReply->u.ListOpen.uHandle));
 
                         *phList = pReply->u.ListOpen.uHandle;
@@ -466,4 +496,6 @@
                     Assert(pReply->uType == VBOX_SHCL_REPLYMSGTYPE_OBJ_OPEN);
 
+                    LogFlowFunc(("hObj=%RU64\n", pReply->u.ObjOpen.uHandle));
+
                     *phObj = pReply->u.ObjOpen.uHandle;
 
@@ -519,4 +551,6 @@
 
                     Assert(pReply->uType == VBOX_SHCL_REPLYMSGTYPE_OBJ_CLOSE);
+
+                    LogFlowFunc(("hObj=%RU64\n", pReply->u.ObjClose.uHandle));
 #endif
 
@@ -765,4 +799,6 @@
                     if (cParms >= 6)
                         rc = HGCMSvcGetU32(&paParms[5], &pReply->u.TransferStatus.uStatus);
+
+                    LogFlowFunc(("uTransferStatus=%RU32\n", pReply->u.TransferStatus.uStatus));
                     break;
                 }
@@ -772,4 +808,15 @@
                     if (cParms >= 6)
                         rc = HGCMSvcGetU64(&paParms[5], &pReply->u.ListOpen.uHandle);
+
+                    LogFlowFunc(("hListOpen=%RU64\n", pReply->u.ListOpen.uHandle));
+                    break;
+                }
+
+                case VBOX_SHCL_REPLYMSGTYPE_LIST_CLOSE:
+                {
+                    if (cParms >= 6)
+                        rc = HGCMSvcGetU64(&paParms[5], &pReply->u.ListClose.uHandle);
+
+                    LogFlowFunc(("hListClose=%RU64\n", pReply->u.ListClose.uHandle));
                     break;
                 }
@@ -779,4 +826,6 @@
                     if (cParms >= 6)
                         rc = HGCMSvcGetU64(&paParms[5], &pReply->u.ObjOpen.uHandle);
+
+                    LogFlowFunc(("hObjOpen=%RU64\n", pReply->u.ObjOpen.uHandle));
                     break;
                 }
@@ -786,4 +835,6 @@
                     if (cParms >= 6)
                         rc = HGCMSvcGetU64(&paParms[5], &pReply->u.ObjClose.uHandle);
+
+                    LogFlowFunc(("hObjClose=%RU64\n", pReply->u.ObjClose.uHandle));
                     break;
                 }
@@ -1152,30 +1203,4 @@
             }
         }
-    }
-    else
-        rc = VERR_INVALID_PARAMETER;
-
-    LogFlowFuncLeaveRC(rc);
-    return rc;
-}
-
-/**
- * Gets a transfer error from HGCM service parameters.
- *
- * @returns VBox status code.
- * @param   cParms              Number of HGCM parameters supplied in \a paParms.
- * @param   paParms             Array of HGCM parameters.
- * @param   pRc                 Where to store the received error code.
- */
-static int shclSvcTransferGetError(uint32_t cParms, VBOXHGCMSVCPARM paParms[], int *pRc)
-{
-    AssertPtrReturn(paParms, VERR_INVALID_PARAMETER);
-    AssertPtrReturn(pRc,     VERR_INVALID_PARAMETER);
-
-    int rc;
-
-    if (cParms == VBOX_SHCL_CPARMS_ERROR)
-    {
-        rc = HGCMSvcGetU32(&paParms[1], (uint32_t *)pRc); /** @todo int vs. uint32_t !!! */
     }
     else
@@ -1848,19 +1873,4 @@
         }
 #endif
-        case VBOX_SHCL_GUEST_FN_CANCEL:
-        {
-            LogRel2(("Shared Clipboard: Transfer canceled\n"));
-            break;
-        }
-
-        case VBOX_SHCL_GUEST_FN_ERROR:
-        {
-            int rcGuest;
-            rc = shclSvcTransferGetError(cParms,paParms, &rcGuest);
-            if (RT_SUCCESS(rc))
-                LogRel(("Shared Clipboard: Transfer error from guest: %Rrc\n", rcGuest));
-            break;
-        }
-
         default:
             LogFunc(("Not implemented\n"));
Index: /trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc.cpp
===================================================================
--- /trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc.cpp	(revision 81228)
+++ /trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc.cpp	(revision 81229)
@@ -1060,4 +1060,30 @@
 }
 
+/**
+ * Gets an error from HGCM service parameters.
+ *
+ * @returns VBox status code.
+ * @param   cParms              Number of HGCM parameters supplied in \a paParms.
+ * @param   paParms             Array of HGCM parameters.
+ * @param   pRc                 Where to store the received error code.
+ */
+static int shclSvcGetError(uint32_t cParms, VBOXHGCMSVCPARM paParms[], int *pRc)
+{
+    AssertPtrReturn(paParms, VERR_INVALID_PARAMETER);
+    AssertPtrReturn(pRc,     VERR_INVALID_PARAMETER);
+
+    int rc;
+
+    if (cParms == VBOX_SHCL_CPARMS_ERROR)
+    {
+        rc = HGCMSvcGetU32(&paParms[1], (uint32_t *)pRc); /** @todo int vs. uint32_t !!! */
+    }
+    else
+        rc = VERR_INVALID_PARAMETER;
+
+    LogFlowFuncLeaveRC(rc);
+    return rc;
+}
+
 int shclSvcSetSource(PSHCLCLIENT pClient, SHCLSOURCE enmSource)
 {
@@ -1121,9 +1147,5 @@
 
 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
-    PSHCLTRANSFER pTransfer = ShClTransferCtxGetTransfer(&pClient->TransferCtx, 0 /* Index*/);
-    if (pTransfer)
-        shclSvcTransferAreaDetach(&pClient->State, pTransfer);
-
-    ShClTransferCtxDestroy(&pClient->TransferCtx);
+    shclSvcClientTransfersReset(pClient);
 #endif
 
@@ -1487,4 +1509,29 @@
         }
 
+        case VBOX_SHCL_GUEST_FN_CANCEL:
+        {
+            LogRel2(("Shared Clipboard: Operation canceled by guest side\n"));
+
+            /** @todo Do we need to do anything here? */
+            break;
+        }
+
+        case VBOX_SHCL_GUEST_FN_ERROR:
+        {
+            int rcGuest;
+            rc = shclSvcGetError(cParms,paParms, &rcGuest);
+            if (RT_SUCCESS(rc))
+            {
+                LogRel(("Shared Clipboard: Error from guest side: %Rrc\n", rcGuest));
+
+                /* Reset client state and start over. */
+                shclSvcClientStateReset(&pClient->State);
+#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
+                shclSvcClientTransfersReset(pClient);
+#endif
+            }
+            break;
+        }
+
         default:
         {
