Index: /trunk/include/VBox/GuestHost/SharedClipboard-win.h
===================================================================
--- /trunk/include/VBox/GuestHost/SharedClipboard-win.h	(revision 78151)
+++ /trunk/include/VBox/GuestHost/SharedClipboard-win.h	(revision 78151)
@@ -0,0 +1,99 @@
+/** @file
+ * Shared Clipboard - Common Guest and Host Code, for Windows OSes.
+ */
+
+/*
+ * Copyright (C) 2006-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef VBOX_INCLUDED_GuestHost_SharedClipboard_win_h
+#define VBOX_INCLUDED_GuestHost_SharedClipboard_win_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <iprt/win/windows.h>
+
+#ifndef WM_CLIPBOARDUPDATE
+# define WM_CLIPBOARDUPDATE 0x031D
+#endif
+
+#define VBOX_CLIPBOARD_WNDCLASS_NAME        "VBoxSharedClipboardClass"
+
+/** Default timeout (in ms) for passing down messages down the clipboard chain. */
+#define VBOX_CLIPBOARD_CBCHAIN_TIMEOUT_MS   5000
+
+/** Sets announced clipboard formats from the host. */
+#define VBOX_CLIPBOARD_WM_SET_FORMATS       WM_USER
+/** Reads data from the clipboard and sends it to the host. */
+#define VBOX_CLIPBOARD_WM_READ_DATA         WM_USER + 1
+
+/* Dynamically load clipboard functions from User32.dll. */
+typedef BOOL WINAPI FNADDCLIPBOARDFORMATLISTENER(HWND);
+typedef FNADDCLIPBOARDFORMATLISTENER *PFNADDCLIPBOARDFORMATLISTENER;
+
+typedef BOOL WINAPI FNREMOVECLIPBOARDFORMATLISTENER(HWND);
+typedef FNREMOVECLIPBOARDFORMATLISTENER *PFNREMOVECLIPBOARDFORMATLISTENER;
+
+/**
+ * Structure for keeping function pointers for the new clipboard API.
+ * If the new API is not available, those function pointer are NULL.
+ */
+typedef struct VBOXCLIPBOARDWINAPINEW
+{
+    PFNADDCLIPBOARDFORMATLISTENER    pfnAddClipboardFormatListener;
+    PFNREMOVECLIPBOARDFORMATLISTENER pfnRemoveClipboardFormatListener;
+} VBOXCLIPBOARDWINAPINEW, *PVBOXCLIPBOARDWINAPINEW;
+
+/**
+ * Structure for keeping variables which are needed to drive the old clipboard API.
+ */
+typedef struct VBOXCLIPBOARDWINAPIOLD
+{
+    /** Timer ID for the refresh timer. */
+    UINT                   timerRefresh;
+    /** Whether "pinging" the clipboard chain currently is in progress or not. */
+    bool                   fCBChainPingInProcess;
+} VBOXCLIPBOARDWINAPIOLD, *PVBOXCLIPBOARDWINAPIOLD;
+
+typedef struct VBOXCLIPBOARDWINCTX
+{
+    /** Window handle of our (invisible) clipbaord window. */
+    HWND                   hWnd;
+    /** Window handle which is next to us in the clipboard chain. */
+    HWND                   hWndNextInChain;
+    /** Structure for maintaining the new clipboard API. */
+    VBOXCLIPBOARDWINAPINEW newAPI;
+    /** Structure for maintaining the old clipboard API. */
+    VBOXCLIPBOARDWINAPIOLD oldAPI;
+} VBOXCLIPBOARDWINCTX, *PVBOXCLIPBOARDWINCTX;
+
+int VBoxClipboardWinOpen(HWND hWnd);
+int VBoxClipboardWinClose(void);
+int VBoxClipboardWinClear(void);
+int VBoxClipboardWinCheckAndInitNewAPI(PVBOXCLIPBOARDWINAPINEW pAPI);
+bool VBoxClipboardWinIsNewAPI(PVBOXCLIPBOARDWINAPINEW pAPI);
+int VBoxClipboardWinAddToCBChain(PVBOXCLIPBOARDWINCTX pCtx);
+int VBoxClipboardWinRemoveFromCBChain(PVBOXCLIPBOARDWINCTX pCtx);
+VOID CALLBACK VBoxClipboardWinChainPingProc(HWND hWnd, UINT uMsg, ULONG_PTR dwData, LRESULT lResult);
+int VBoxClipboardWinGetFormats(PVBOXCLIPBOARDWINCTX pCtx, uint32_t *puFormats);
+
+#endif /* !VBOX_INCLUDED_GuestHost_SharedClipboard_win_h */
+
Index: /trunk/include/VBox/GuestHost/SharedClipboard.h
===================================================================
--- /trunk/include/VBox/GuestHost/SharedClipboard.h	(revision 78150)
+++ /trunk/include/VBox/GuestHost/SharedClipboard.h	(revision 78151)
@@ -33,4 +33,21 @@
 #include <iprt/types.h>
 
+/**
+ * Supported data formats for Shared Clipboard. Bit mask.
+ */
+/** Shared Clipboard format is an Unicode text. */
+#define VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT   UINT32_C(0x01)
+/** Shared Clipboard format is bitmap (BMP / DIB). */
+#define VBOX_SHARED_CLIPBOARD_FMT_BITMAP        UINT32_C(0x02)
+/** Shared Clipboard format is HTML. */
+#define VBOX_SHARED_CLIPBOARD_FMT_HTML          UINT32_C(0x04)
+
+/**
+ * The host messages for the guest.
+ */
+#define VBOX_SHARED_CLIPBOARD_HOST_MSG_QUIT        1
+#define VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA   2
+#define VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS     3
+
 enum
 {
@@ -46,4 +63,5 @@
 struct _VBOXCLIPBOARDCONTEXT;
 typedef struct _VBOXCLIPBOARDCONTEXT VBOXCLIPBOARDCONTEXT;
+typedef struct _VBOXCLIPBOARDCONTEXT *PVBOXCLIPBOARDCONTEXT;
 
 /** Opaque data structure for the X11/VBox backend code. */
Index: /trunk/include/VBox/HostServices/VBoxClipboardSvc.h
===================================================================
--- /trunk/include/VBox/HostServices/VBoxClipboardSvc.h	(revision 78150)
+++ /trunk/include/VBox/HostServices/VBoxClipboardSvc.h	(revision 78151)
@@ -43,11 +43,4 @@
 
 /*
- * Supported data formats. Bit mask.
- */
-#define VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT   UINT32_C(0x01)
-#define VBOX_SHARED_CLIPBOARD_FMT_BITMAP        UINT32_C(0x02)
-#define VBOX_SHARED_CLIPBOARD_FMT_HTML          UINT32_C(0x04)
-
-/*
  * The service functions which are callable by host.
  */
@@ -67,11 +60,4 @@
 /* Send data in requested format to host. */
 #define VBOX_SHARED_CLIPBOARD_FN_WRITE_DATA        4
-
-/*
- * The host messages for the guest.
- */
-#define VBOX_SHARED_CLIPBOARD_HOST_MSG_QUIT        1
-#define VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA   2
-#define VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS     3
 
 /*
Index: /trunk/src/VBox/Additions/WINNT/VBoxTray/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Additions/WINNT/VBoxTray/Makefile.kmk	(revision 78150)
+++ /trunk/src/VBox/Additions/WINNT/VBoxTray/Makefile.kmk	(revision 78151)
@@ -37,5 +37,4 @@
 	VBoxDispIf.cpp \
 	VBoxSeamless.cpp \
-	VBoxClipboard.cpp \
 	VBoxDisplay.cpp \
 	VBoxVRDP.cpp \
@@ -46,4 +45,11 @@
 VBoxTray_VBOX_IMPORT_CHECKER.win.x86 = nt4 #nt350
 VBoxTray_VBOX_IMPORT_CHECKER.win.amd64 = xp64
+ifdef VBOX_WITH_SHARED_CLIPBOARD
+ VBoxTray_DEFS     += \
+	VBOX_WITH_SHARED_CLIPBOARD
+ VBoxTray_SOURCES  += \
+	VBoxClipboard.cpp \
+	$(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/clipboard-win.cpp
+endif
 ifdef VBOX_WITH_DRAG_AND_DROP
  VBoxTray_DEFS     += \
Index: /trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxClipboard.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxClipboard.cpp	(revision 78150)
+++ /trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxClipboard.cpp	(revision 78151)
@@ -27,5 +27,6 @@
 #include <iprt/ldr.h>
 
-#include <VBox/HostServices/VBoxClipboardSvc.h>
+#include <VBox/GuestHost/SharedClipboard.h>
+#include <VBox/GuestHost/SharedClipboard-win.h>
 #include <strsafe.h>
 
@@ -36,222 +37,29 @@
 *   Structures and Typedefs                                                                                                      *
 *********************************************************************************************************************************/
-/* Dynamically load clipboard functions from User32.dll. */
-typedef BOOL WINAPI FNADDCLIPBOARDFORMATLISTENER(HWND);
-typedef FNADDCLIPBOARDFORMATLISTENER *PFNADDCLIPBOARDFORMATLISTENER;
-
-typedef BOOL WINAPI FNREMOVECLIPBOARDFORMATLISTENER(HWND);
-typedef FNREMOVECLIPBOARDFORMATLISTENER *PFNREMOVECLIPBOARDFORMATLISTENER;
-
-#ifndef WM_CLIPBOARDUPDATE
-#define WM_CLIPBOARDUPDATE 0x031D
-#endif
-
-/** Sets announced clipboard formats from the host. */
-#define VBOX_WM_SHCLPB_SET_FORMATS      WM_USER
-/** Reads data from the clipboard and sends it to the host. */
-#define VBOX_WM_SHCLPB_READ_DATA        WM_USER + 1
-
-typedef struct _VBOXCLIPBOARDCONTEXT
-{
-    const VBOXSERVICEENV *pEnv;
-    uint32_t              u32ClientID;
-    ATOM                  wndClass;
-    HWND                  hwnd;
-    HWND                  hwndNextInChain;
-    UINT                  timerRefresh;
-    bool                  fCBChainPingInProcess;
-    PFNADDCLIPBOARDFORMATLISTENER pfnAddClipboardFormatListener;
-    PFNREMOVECLIPBOARDFORMATLISTENER pfnRemoveClipboardFormatListener;
-} VBOXCLIPBOARDCONTEXT, *PVBOXCLIPBOARDCONTEXT;
-
-enum { CBCHAIN_TIMEOUT = 5000 /* ms */ };
-
+
+struct _VBOXCLIPBOARDCONTEXT
+{
+    /** Pointer to the VBoxClient service environment. */
+    const VBOXSERVICEENV    *pEnv;
+    /** Client ID the service is connected to the HGCM service with. */
+    uint32_t                 u32ClientID;
+    /** Windows-specific context data. */
+    VBOXCLIPBOARDWINCTX      Win;
+};
 
 /*********************************************************************************************************************************
-*   Header Files                                                                                                                 *
+*   Static variables                                                                                                             *
 *********************************************************************************************************************************/
-/** Static since it is the single instance. Directly used in the windows proc. */
+/** Static clipboard context (since it is the single instance). Directly used in the windows proc. */
 static VBOXCLIPBOARDCONTEXT g_Ctx = { NULL };
-
-static char s_szClipWndClassName[] = "VBoxSharedClipboardClass";
-
-
-static void vboxClipboardInitNewAPI(VBOXCLIPBOARDCONTEXT *pCtx)
-{
-    RTLDRMOD hUser32 = NIL_RTLDRMOD;
-    int rc = RTLdrLoadSystem("User32.dll", /* fNoUnload = */ true, &hUser32);
-    if (RT_SUCCESS(rc))
-    {
-        rc = RTLdrGetSymbol(hUser32, "AddClipboardFormatListener", (void**)&pCtx->pfnAddClipboardFormatListener);
-        if (RT_SUCCESS(rc))
-        {
-            rc = RTLdrGetSymbol(hUser32, "RemoveClipboardFormatListener", (void**)&pCtx->pfnRemoveClipboardFormatListener);
-        }
-
-        RTLdrClose(hUser32);
-    }
-
-    if (RT_SUCCESS(rc))
-    {
-        Log(("New Clipboard API is enabled\n"));
-    }
-    else
-    {
-        pCtx->pfnAddClipboardFormatListener = NULL;
-        pCtx->pfnRemoveClipboardFormatListener = NULL;
-        Log(("New Clipboard API is not available. rc = %Rrc\n", rc));
-    }
-}
-
-static bool vboxClipboardIsNewAPI(VBOXCLIPBOARDCONTEXT *pCtx)
-{
-    return pCtx->pfnAddClipboardFormatListener != NULL;
-}
-
-
-static int vboxOpenClipboard(HWND hWnd)
-{
-    /* "OpenClipboard fails if another window has the clipboard open."
-     * So try a few times and wait up to 1 second.
-     */
-    BOOL fOpened = FALSE;
-
-    LogFlowFunc(("hWnd=%p\n", hWnd));
-
-    int i = 0;
-    for (;;)
-    {
-        if (OpenClipboard(hWnd))
-        {
-            fOpened = TRUE;
-            break;
-        }
-
-        if (i >= 10) /* sleep interval = [1..512] ms */
-            break;
-
-        RTThreadSleep(1 << i);
-        ++i;
-    }
-
-#ifdef LOG_ENABLED
-    if (i > 0)
-        LogFlowFunc(("%d times tried to open clipboard\n", i + 1));
-#endif
-
-    int rc;
-    if (fOpened)
-        rc = VINF_SUCCESS;
-    else
-    {
-        const DWORD dwLastErr = GetLastError();
-        rc = RTErrConvertFromWin32(dwLastErr);
-        LogRel(("Clipboard: Failed to open clipboard! Error=%ld (%Rrc)\n", dwLastErr, rc));
-    }
-
-    return rc;
-}
-
-
-static int vboxClipboardChanged(PVBOXCLIPBOARDCONTEXT pCtx)
+/** Static window class name. */
+static char s_szClipWndClassName[] = VBOX_CLIPBOARD_WNDCLASS_NAME;
+
+
+static LRESULT vboxClipboardProcessMsg(PVBOXCLIPBOARDCONTEXT pCtx, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
     AssertPtr(pCtx);
 
-    /* Query list of available formats and report to host. */
-    int rc = vboxOpenClipboard(pCtx->hwnd);
-    if (RT_SUCCESS(rc))
-    {
-        uint32_t u32Formats = 0;
-        UINT format = 0;
-
-        while ((format = EnumClipboardFormats(format)) != 0)
-        {
-            LogFlowFunc(("vboxClipboardChanged: format = 0x%08X\n", format));
-            switch (format)
-            {
-                case CF_UNICODETEXT:
-                case CF_TEXT:
-                    u32Formats |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT;
-                    break;
-
-                case CF_DIB:
-                case CF_BITMAP:
-                    u32Formats |= VBOX_SHARED_CLIPBOARD_FMT_BITMAP;
-                    break;
-
-                default:
-                {
-                    if (format >= 0xC000)
-                    {
-                        TCHAR szFormatName[256];
-
-                        int cActual = GetClipboardFormatName(format, szFormatName, sizeof(szFormatName)/sizeof (TCHAR));
-                        if (cActual)
-                        {
-                            if (strcmp (szFormatName, "HTML Format") == 0)
-                            {
-                                u32Formats |= VBOX_SHARED_CLIPBOARD_FMT_HTML;
-                            }
-                        }
-                    }
-                    break;
-                }
-            }
-        }
-
-        CloseClipboard();
-        rc = VbglR3ClipboardReportFormats(pCtx->u32ClientID, u32Formats);
-    }
-    return rc;
-}
-
-/* Add ourselves into the chain of cliboard listeners */
-static void vboxClipboardAddToCBChain(PVBOXCLIPBOARDCONTEXT pCtx)
-{
-    AssertPtrReturnVoid(pCtx);
-    if (vboxClipboardIsNewAPI(pCtx))
-        pCtx->pfnAddClipboardFormatListener(pCtx->hwnd);
-    else
-        pCtx->hwndNextInChain = SetClipboardViewer(pCtx->hwnd);
-    /** @todo r=andy Return code?? */
-}
-
-/* Remove ourselves from the chain of cliboard listeners */
-static void vboxClipboardRemoveFromCBChain(PVBOXCLIPBOARDCONTEXT pCtx)
-{
-    AssertPtrReturnVoid(pCtx);
-
-    if (vboxClipboardIsNewAPI(pCtx))
-    {
-        pCtx->pfnRemoveClipboardFormatListener(pCtx->hwnd);
-    }
-    else
-    {
-        ChangeClipboardChain(pCtx->hwnd, pCtx->hwndNextInChain);
-        pCtx->hwndNextInChain = NULL;
-    }
-    /** @todo r=andy Return code?? */
-}
-
-/* Callback which is invoked when we have successfully pinged ourselves down the
- * clipboard chain.  We simply unset a boolean flag to say that we are responding.
- * There is a race if a ping returns after the next one is initiated, but nothing
- * very bad is likely to happen. */
-VOID CALLBACK vboxClipboardChainPingProc(HWND hWnd, UINT uMsg, ULONG_PTR dwData, LRESULT lResult)
-{
-    NOREF(hWnd);
-    NOREF(uMsg);
-    NOREF(lResult);
-
-    /** @todo r=andy Why not using SetWindowLongPtr for keeping the context? */
-    PVBOXCLIPBOARDCONTEXT pCtx = (PVBOXCLIPBOARDCONTEXT)dwData;
-    AssertPtr(pCtx);
-
-    pCtx->fCBChainPingInProcess = FALSE;
-}
-
-static LRESULT vboxClipboardProcessMsg(PVBOXCLIPBOARDCONTEXT pCtx, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
-    AssertPtr(pCtx);
+    const PVBOXCLIPBOARDWINCTX pWinCtx = &pCtx->Win;
 
     LRESULT rc = 0;
@@ -266,5 +74,8 @@
             {
                 /* Clipboard was updated by another application. */
-                vboxClipboardChanged(pCtx);
+                uint32_t uFormats;
+                int vboxrc = VBoxClipboardWinGetFormats(&pCtx->Win, &uFormats);
+                if (RT_SUCCESS(vboxrc))
+                    vboxrc = VbglR3ClipboardReportFormats(pCtx->u32ClientID, uFormats);
             }
         } break;
@@ -272,5 +83,5 @@
         case WM_CHANGECBCHAIN:
         {
-            if (vboxClipboardIsNewAPI(pCtx))
+            if (VBoxClipboardWinIsNewAPI(&pWinCtx->newAPI))
             {
                 rc = DefWindowProc(hwnd, msg, wParam, lParam);
@@ -278,22 +89,23 @@
             }
 
-            HWND hwndRemoved = (HWND)wParam;
-            HWND hwndNext    = (HWND)lParam;
-
-            LogFlowFunc(("WM_CHANGECBCHAIN: hwndRemoved %p, hwndNext %p, hwnd %p\n", hwndRemoved, hwndNext, pCtx->hwnd));
-
-            if (hwndRemoved == pCtx->hwndNextInChain)
+            HWND hWndRemoved = (HWND)wParam;
+            HWND hWndNext    = (HWND)lParam;
+
+            LogFlowFunc(("WM_CHANGECBCHAIN: hWndRemoved=%p, hWndNext=%p, hWnd=%p\n", hWndRemoved, hWndNext, pWinCtx->hWnd));
+
+            if (hWndRemoved == pWinCtx->hWndNextInChain)
             {
                 /* The window that was next to our in the chain is being removed.
                  * Relink to the new next window. */
-                pCtx->hwndNextInChain = hwndNext;
+                pWinCtx->hWndNextInChain = hWndNext;
             }
             else
             {
-                if (pCtx->hwndNextInChain)
+                if (pWinCtx->hWndNextInChain)
                 {
                     /* Pass the message further. */
                     DWORD_PTR dwResult;
-                    rc = SendMessageTimeout(pCtx->hwndNextInChain, WM_CHANGECBCHAIN, wParam, lParam, 0, CBCHAIN_TIMEOUT, &dwResult);
+                    rc = SendMessageTimeout(pWinCtx->hWndNextInChain, WM_CHANGECBCHAIN, wParam, lParam, 0,
+                                            VBOX_CLIPBOARD_CBCHAIN_TIMEOUT_MS, &dwResult);
                     if (!rc)
                         rc = (LRESULT) dwResult;
@@ -304,5 +116,5 @@
         case WM_DRAWCLIPBOARD:
         {
-            LogFlowFunc(("WM_DRAWCLIPBOARD, hwnd %p\n", pCtx->hwnd));
+            LogFlowFunc(("WM_DRAWCLIPBOARD, hwnd %p\n", pWinCtx->hWnd));
 
             if (GetClipboardOwner() != hwnd)
@@ -310,13 +122,14 @@
                 /* Clipboard was updated by another application. */
                 /* WM_DRAWCLIPBOARD always expects a return code of 0, so don't change "rc" here. */
-                int vboxrc = vboxClipboardChanged(pCtx);
-                if (RT_FAILURE(vboxrc))
-                    LogFlowFunc(("vboxClipboardChanged failed, rc = %Rrc\n", vboxrc));
-            }
-
-            if (pCtx->hwndNextInChain)
+                uint32_t uFormats;
+                int vboxrc = VBoxClipboardWinGetFormats(pWinCtx, &uFormats);
+                if (RT_SUCCESS(vboxrc))
+                    vboxrc = VbglR3ClipboardReportFormats(pCtx->u32ClientID, uFormats);
+            }
+
+            if (pWinCtx->hWndNextInChain)
             {
                 /* Pass the message to next windows in the clipboard chain. */
-                SendMessageTimeout(pCtx->hwndNextInChain, msg, wParam, lParam, 0, CBCHAIN_TIMEOUT, NULL);
+                SendMessageTimeout(pWinCtx->hWndNextInChain, msg, wParam, lParam, 0, VBOX_CLIPBOARD_CBCHAIN_TIMEOUT_MS, NULL);
             }
         } break;
@@ -324,5 +137,5 @@
         case WM_TIMER:
         {
-            if (vboxClipboardIsNewAPI(pCtx))
+            if (VBoxClipboardWinIsNewAPI(&pWinCtx->newAPI))
                 break;
 
@@ -331,15 +144,18 @@
             /* Re-register ourselves in the clipboard chain if our last ping
              * timed out or there seems to be no valid chain. */
-            if (!hViewer || pCtx->fCBChainPingInProcess)
-            {
-                vboxClipboardRemoveFromCBChain(pCtx);
-                vboxClipboardAddToCBChain(pCtx);
-            }
+            if (!hViewer || pWinCtx->oldAPI.fCBChainPingInProcess)
+            {
+                VBoxClipboardWinRemoveFromCBChain(pWinCtx);
+                VBoxClipboardWinAddToCBChain(pWinCtx);
+            }
+
             /* Start a new ping by passing a dummy WM_CHANGECBCHAIN to be
              * processed by ourselves to the chain. */
-            pCtx->fCBChainPingInProcess = TRUE;
+            pWinCtx->oldAPI.fCBChainPingInProcess = TRUE;
+
             hViewer = GetClipboardViewer();
             if (hViewer)
-                SendMessageCallback(hViewer, WM_CHANGECBCHAIN, (WPARAM)pCtx->hwndNextInChain, (LPARAM)pCtx->hwndNextInChain, vboxClipboardChainPingProc, (ULONG_PTR)pCtx);
+                SendMessageCallback(hViewer, WM_CHANGECBCHAIN, (WPARAM)pWinCtx->hWndNextInChain, (LPARAM)pWinCtx->hWndNextInChain,
+                                    VBoxClipboardWinChainPingProc, (ULONG_PTR)pWinCtx);
         } break;
 
@@ -387,5 +203,5 @@
                 /* Unsupported clipboard format is requested. */
                 LogFlowFunc(("Unsupported clipboard format requested: %ld\n", u32Format));
-                EmptyClipboard();
+                VBoxClipboardWinClear();
             }
             else
@@ -518,5 +334,5 @@
 
                 /* Something went wrong. */
-                EmptyClipboard();
+                VBoxClipboardWinClear();
             }
         } break;
@@ -527,13 +343,13 @@
              * windows is to be destroyed and therefore the guest side becomes inactive.
              */
-            int vboxrc = vboxOpenClipboard(hwnd);
+            int vboxrc = VBoxClipboardWinOpen(hwnd);
             if (RT_SUCCESS(vboxrc))
             {
-                EmptyClipboard();
-                CloseClipboard();
-            }
-        } break;
-
-        case VBOX_WM_SHCLPB_SET_FORMATS:
+                VBoxClipboardWinClear();
+                VBoxClipboardWinClose();
+            }
+        } break;
+
+        case VBOX_CLIPBOARD_WM_SET_FORMATS:
         {
             /* Announce available formats. Do not insert data, they will be inserted in WM_RENDER*. */
@@ -542,8 +358,8 @@
             LogFlowFunc(("VBOX_WM_SHCLPB_SET_FORMATS: u32Formats=0x%x\n", u32Formats));
 
-            int vboxrc = vboxOpenClipboard(hwnd);
+            int vboxrc = VBoxClipboardWinOpen(hwnd);
             if (RT_SUCCESS(vboxrc))
             {
-                EmptyClipboard();
+                VBoxClipboardWinClear();
 
                 HANDLE hClip = NULL;
@@ -562,5 +378,5 @@
                 }
 
-                CloseClipboard();
+                VBoxClipboardWinClose();
 
                 LogFlowFunc(("VBOX_WM_SHCLPB_SET_FORMATS: hClip=%p, lastErr=%ld\n", hClip, GetLastError()));
@@ -568,5 +384,5 @@
         } break;
 
-        case VBOX_WM_SHCLPB_READ_DATA:
+        case VBOX_CLIPBOARD_WM_READ_DATA:
         {
             /* Send data in the specified format to the host. */
@@ -576,5 +392,5 @@
             LogFlowFunc(("VBOX_WM_SHCLPB_READ_DATA: u32Formats=0x%x\n", u32Formats));
 
-            int vboxrc = vboxOpenClipboard(hwnd);
+            int vboxrc = VBoxClipboardWinOpen(hwnd);
             if (RT_SUCCESS(vboxrc))
             {
@@ -642,5 +458,5 @@
                 }
 
-                CloseClipboard();
+                VBoxClipboardWinClose();
             }
 
@@ -654,7 +470,7 @@
         case WM_DESTROY:
         {
-            vboxClipboardRemoveFromCBChain(pCtx);
-            if (pCtx->timerRefresh)
-                KillTimer(pCtx->hwnd, 0);
+            VBoxClipboardWinRemoveFromCBChain(pWinCtx);
+            if (pWinCtx->oldAPI.timerRefresh)
+                KillTimer(pWinCtx->hWnd, 0);
             /*
              * don't need to call PostQuitMessage cause
@@ -699,6 +515,6 @@
         wc.lpszClassName = s_szClipWndClassName;
 
-        pCtx->wndClass = RegisterClassEx(&wc);
-        if (pCtx->wndClass == 0)
+        ATOM wndClass = RegisterClassEx(&wc);
+        if (wndClass == 0)
             rc = RTErrConvertFromWin32(GetLastError());
     }
@@ -706,10 +522,12 @@
     if (RT_SUCCESS(rc))
     {
+        const PVBOXCLIPBOARDWINCTX pWinCtx = &pCtx->Win;
+
         /* Create the window. */
-        pCtx->hwnd = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_TOPMOST,
-                                    s_szClipWndClassName, s_szClipWndClassName,
-                                    WS_POPUPWINDOW,
-                                    -200, -200, 100, 100, NULL, NULL, hInstance, NULL);
-        if (pCtx->hwnd == NULL)
+        pWinCtx->hWnd = CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_TOPMOST,
+                                       s_szClipWndClassName, s_szClipWndClassName,
+                                       WS_POPUPWINDOW,
+                                       -200, -200, 100, 100, NULL, NULL, hInstance, NULL);
+        if (pWinCtx->hWnd == NULL)
         {
             rc = VERR_NOT_SUPPORTED;
@@ -717,10 +535,10 @@
         else
         {
-            SetWindowPos(pCtx->hwnd, HWND_TOPMOST, -200, -200, 0, 0,
+            SetWindowPos(pWinCtx->hWnd, HWND_TOPMOST, -200, -200, 0, 0,
                          SWP_NOACTIVATE | SWP_HIDEWINDOW | SWP_NOCOPYBITS | SWP_NOREDRAW | SWP_NOSIZE);
 
-            vboxClipboardAddToCBChain(pCtx);
-            if (!vboxClipboardIsNewAPI(pCtx))
-                pCtx->timerRefresh = SetTimer(pCtx->hwnd, 0, 10 * 1000, NULL);
+            VBoxClipboardWinAddToCBChain(pWinCtx);
+            if (!VBoxClipboardWinIsNewAPI(&pWinCtx->newAPI))
+                pWinCtx->oldAPI.timerRefresh = SetTimer(pWinCtx->hWnd, 0, 10 * 1000 /* 10s */, NULL);
         }
     }
@@ -734,15 +552,13 @@
     AssertPtrReturnVoid(pCtx);
 
-    if (pCtx->hwnd)
+    const PVBOXCLIPBOARDWINCTX pWinCtx = &pCtx->Win;
+
+    if (pWinCtx->hWnd)
     {
-        DestroyWindow(pCtx->hwnd);
-        pCtx->hwnd = NULL;
+        DestroyWindow(pWinCtx->hWnd);
+        pWinCtx->hWnd = NULL;
     }
 
-    if (pCtx->wndClass != 0)
-    {
-        UnregisterClass(s_szClipWndClassName, pCtx->pEnv->hInstance);
-        pCtx->wndClass = 0;
-    }
+    UnregisterClass(s_szClipWndClassName, pCtx->pEnv->hInstance);
 }
 
@@ -777,8 +593,9 @@
 
     RT_BZERO(pCtx, sizeof(VBOXCLIPBOARDCONTEXT));
+
     pCtx->pEnv = pEnv;
 
     /* Check that new Clipboard API is available */
-    vboxClipboardInitNewAPI(pCtx);
+    VBoxClipboardWinCheckAndInitNewAPI(&pCtx->Win.newAPI);
 
     int rc = VbglR3ClipboardConnect(&pCtx->u32ClientID);
@@ -811,6 +628,8 @@
     RTThreadUserSignal(RTThreadSelf());
 
-    PVBOXCLIPBOARDCONTEXT pCtx = (PVBOXCLIPBOARDCONTEXT)pInstance;
+    const PVBOXCLIPBOARDCONTEXT pCtx = (PVBOXCLIPBOARDCONTEXT)pInstance;
     AssertPtr(pCtx);
+
+    const PVBOXCLIPBOARDWINCTX pWinCtx = &pCtx->Win;
 
     int rc;
@@ -846,5 +665,5 @@
                      * Forward the information to the window, so it can later
                      * respond to WM_RENDERFORMAT message. */
-                    ::PostMessage(pCtx->hwnd, VBOX_WM_SHCLPB_SET_FORMATS, 0, u32Formats);
+                    ::PostMessage(pWinCtx->hWnd, VBOX_CLIPBOARD_WM_SET_FORMATS, 0, u32Formats);
                 } break;
 
@@ -852,5 +671,5 @@
                 {
                     /* The host needs data in the specified format. */
-                    ::PostMessage(pCtx->hwnd, VBOX_WM_SHCLPB_READ_DATA, 0, u32Formats);
+                    ::PostMessage(pWinCtx->hWnd, VBOX_CLIPBOARD_WM_READ_DATA, 0, u32Formats);
                 } break;
 
@@ -927,2 +746,3 @@
     VBoxClipboardDestroy
 };
+
Index: /trunk/src/VBox/GuestHost/SharedClipboard/clipboard-win.cpp
===================================================================
--- /trunk/src/VBox/GuestHost/SharedClipboard/clipboard-win.cpp	(revision 78151)
+++ /trunk/src/VBox/GuestHost/SharedClipboard/clipboard-win.cpp	(revision 78151)
@@ -0,0 +1,337 @@
+/* $Id$ */
+/** @file
+ * Shared Clipboard: Windows-specific functions for clipboard handling.
+ */
+
+/*
+ * Copyright (C) 2006-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <iprt/alloc.h>
+#include <iprt/assert.h>
+#include <iprt/errcore.h>
+#include <iprt/ldr.h>
+#include <iprt/thread.h>
+
+#include <VBox/log.h>
+#include <VBox/GuestHost/SharedClipboard.h>
+#include <VBox/GuestHost/SharedClipboard-win.h>
+#include <VBox/GuestHost/clipboard-helper.h>
+
+/**
+ * Opens the clipboard of a specific window.
+ *
+ * @returns VBox status code.
+ * @param   hWnd                Handle of window to open clipboard for.
+ */
+int VBoxClipboardWinOpen(HWND hWnd)
+{
+    /* "OpenClipboard fails if another window has the clipboard open."
+     * So try a few times and wait up to 1 second.
+     */
+    BOOL fOpened = FALSE;
+
+    LogFlowFunc(("hWnd=%p\n", hWnd));
+
+    int i = 0;
+    for (;;)
+    {
+        if (OpenClipboard(hWnd))
+        {
+            fOpened = TRUE;
+            break;
+        }
+
+        if (i >= 10) /* sleep interval = [1..512] ms */
+            break;
+
+        RTThreadSleep(1 << i);
+        ++i;
+    }
+
+#ifdef LOG_ENABLED
+    if (i > 0)
+        LogFlowFunc(("%d times tried to open clipboard\n", i + 1));
+#endif
+
+    int rc;
+    if (fOpened)
+        rc = VINF_SUCCESS;
+    else
+    {
+        const DWORD dwLastErr = GetLastError();
+        rc = RTErrConvertFromWin32(dwLastErr);
+        LogFunc(("Failed to open clipboard, rc=%Rrc (0x%x)\n", rc, dwLastErr));
+    }
+
+    return rc;
+}
+
+/**
+ * Closes the clipboard for the current thread.
+ *
+ * @returns VBox status code.
+ */
+int VBoxClipboardWinClose(void)
+{
+    int rc;
+
+    const BOOL fRc = CloseClipboard();
+    if (RT_UNLIKELY(fRc))
+    {
+        const DWORD dwLastErr = GetLastError();
+        rc = RTErrConvertFromWin32(dwLastErr);
+        LogFunc(("Failed with %Rrc (0x%x)\n", rc, dwLastErr));
+    }
+    else
+        rc = VINF_SUCCESS;
+
+    return rc;
+}
+
+/**
+ * Clears the clipboard for the current thread.
+ *
+ * @returns VBox status code.
+ */
+int VBoxClipboardWinClear(void)
+{
+    int rc;
+
+    const BOOL fRc = EmptyClipboard();
+    if (RT_UNLIKELY(fRc))
+    {
+        const DWORD dwLastErr = GetLastError();
+        rc = RTErrConvertFromWin32(dwLastErr);
+        LogFunc(("Failed with %Rrc (0x%x)\n", rc, dwLastErr));
+    }
+    else
+        rc = VINF_SUCCESS;
+
+    return rc;
+}
+
+/**
+ * Checks and initializes function pointer which are required for using
+ * the new clipboard API.
+ *
+ * @returns VBox status code.
+ * @param   pAPI                Where to store the retrieved function pointers.
+ *                              Will be set to NULL if the new API is not available.
+ */
+int VBoxClipboardWinCheckAndInitNewAPI(PVBOXCLIPBOARDWINAPINEW pAPI)
+{
+    RTLDRMOD hUser32 = NIL_RTLDRMOD;
+    int rc = RTLdrLoadSystem("User32.dll", /* fNoUnload = */ true, &hUser32);
+    if (RT_SUCCESS(rc))
+    {
+        rc = RTLdrGetSymbol(hUser32, "AddClipboardFormatListener", (void**)&pAPI->pfnAddClipboardFormatListener);
+        if (RT_SUCCESS(rc))
+        {
+            rc = RTLdrGetSymbol(hUser32, "RemoveClipboardFormatListener", (void**)&pAPI->pfnRemoveClipboardFormatListener);
+        }
+
+        RTLdrClose(hUser32);
+    }
+
+    if (RT_SUCCESS(rc))
+    {
+        LogFunc(("New Clipboard API enabled\n"));
+    }
+    else
+    {
+        RT_BZERO(pAPI, sizeof(VBOXCLIPBOARDWINAPINEW));
+        LogFunc(("New Clipboard API not available; rc=%Rrc\n", rc));
+    }
+
+    return rc;
+}
+
+/**
+ * Returns if the new clipboard API is available or not.
+ *
+ * @returns @c true if the new API is available, or @c false if not.
+ * @param   pAPI                Structure used for checking if the new clipboard API is available or not.
+ */
+bool VBoxClipboardWinIsNewAPI(PVBOXCLIPBOARDWINAPINEW pAPI)
+{
+    if (!pAPI)
+        return false;
+    return pAPI->pfnAddClipboardFormatListener != NULL;
+}
+
+/**
+ * Adds ourselves into the chain of cliboard listeners.
+ *
+ * @returns VBox status code.
+ * @param   pCtx                Windows clipboard context to use to add ourselves.
+ */
+int VBoxClipboardWinAddToCBChain(PVBOXCLIPBOARDWINCTX pCtx)
+{
+    const PVBOXCLIPBOARDWINAPINEW pAPI = &pCtx->newAPI;
+
+    BOOL fRc;
+    if (VBoxClipboardWinIsNewAPI(pAPI))
+    {
+        fRc = pAPI->pfnAddClipboardFormatListener(pCtx->hWnd);
+    }
+    else
+    {
+        pCtx->hWndNextInChain = SetClipboardViewer(pCtx->hWnd);
+        fRc = pCtx->hWndNextInChain != NULL;
+    }
+
+    int rc = VINF_SUCCESS;
+
+    if (!fRc)
+    {
+        const DWORD dwLastErr = GetLastError();
+        rc = RTErrConvertFromWin32(dwLastErr);
+        LogFunc(("Failed with %Rrc (0x%x)\n", rc, dwLastErr));
+    }
+
+    return rc;
+}
+
+/**
+ * Remove ourselves from the chain of cliboard listeners
+ *
+ * @returns VBox status code.
+ * @param   pCtx                Windows clipboard context to use to remove ourselves.
+ */
+int VBoxClipboardWinRemoveFromCBChain(PVBOXCLIPBOARDWINCTX pCtx)
+{
+    if (!pCtx->hWnd)
+        return VINF_SUCCESS;
+
+    const PVBOXCLIPBOARDWINAPINEW pAPI = &pCtx->newAPI;
+
+    BOOL fRc;
+    if (VBoxClipboardWinIsNewAPI(pAPI))
+    {
+        fRc = pAPI->pfnRemoveClipboardFormatListener(pCtx->hWnd);
+    }
+    else
+    {
+        fRc = ChangeClipboardChain(pCtx->hWnd, pCtx->hWndNextInChain);
+        if (fRc)
+            pCtx->hWndNextInChain = NULL;
+    }
+
+    int rc = VINF_SUCCESS;
+
+    if (!fRc)
+    {
+        const DWORD dwLastErr = GetLastError();
+        rc = RTErrConvertFromWin32(dwLastErr);
+        LogFunc(("Failed with %Rrc (0x%x)\n", rc, dwLastErr));
+    }
+
+    return rc;
+}
+
+/**
+ * Callback which is invoked when we have successfully pinged ourselves down the
+ * clipboard chain.  We simply unset a boolean flag to say that we are responding.
+ * There is a race if a ping returns after the next one is initiated, but nothing
+ * very bad is likely to happen.
+ *
+ * @param   hWnd                Window handle to use for this callback. Not used currently.
+ * @param   uMsg                Message to handle. Not used currently.
+ * @param   dwData              Pointer to user-provided data. Contains our Windows clipboard context.
+ * @param   lResult             Additional data to pass. Not used currently.
+ */
+VOID CALLBACK VBoxClipboardWinChainPingProc(HWND hWnd, UINT uMsg, ULONG_PTR dwData, LRESULT lResult)
+{
+    RT_NOREF(hWnd);
+    RT_NOREF(uMsg);
+    RT_NOREF(lResult);
+
+    /** @todo r=andy Why not using SetWindowLongPtr for keeping the context? */
+    PVBOXCLIPBOARDWINCTX pCtx = (PVBOXCLIPBOARDWINCTX)dwData;
+    AssertPtrReturnVoid(pCtx);
+
+    pCtx->oldAPI.fCBChainPingInProcess = FALSE;
+}
+
+/**
+ * Retrieves all supported clipboard formats of a specific clipboard.
+ *
+ * @returns VBox status code.
+ * @param   pCtx                Windows clipboard context to retrieve formats for.
+ * @param   puFormats           Where to store the retrieved formats of type VBOX_SHARED_CLIPBOARD_FMT_ (bitmask).
+ */
+int VBoxClipboardWinGetFormats(PVBOXCLIPBOARDWINCTX pCtx, uint32_t *puFormats)
+{
+    AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
+    AssertPtrReturn(puFormats, VERR_INVALID_POINTER);
+
+    if (!pCtx)
+    {
+        *puFormats = 0;
+        return VINF_SUCCESS;
+    }
+
+    uint32_t uFormats = 0;
+
+    /* Query list of available formats and report to host. */
+    int rc = VBoxClipboardWinOpen(pCtx->hWnd);
+    if (RT_SUCCESS(rc))
+    {
+        UINT uCurFormat = 0;
+        while ((uCurFormat = EnumClipboardFormats(uCurFormat)) != 0)
+        {
+            LogFlowFunc(("uFormat = 0x%08X\n", uCurFormat));
+            switch (uCurFormat)
+            {
+                case CF_UNICODETEXT:
+                case CF_TEXT:
+                    uFormats |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT;
+                    break;
+
+                case CF_DIB:
+                case CF_BITMAP:
+                    uFormats |= VBOX_SHARED_CLIPBOARD_FMT_BITMAP;
+                    break;
+
+                default:
+                {
+                    if (uCurFormat >= 0xC000) /** @todo r=andy Find a define for this. */
+                    {
+                        TCHAR szFormatName[256]; /** @todo r=andy Is this enough? */
+                        int cActual = GetClipboardFormatName(uCurFormat, szFormatName, sizeof(szFormatName)/sizeof (TCHAR));
+                        if (cActual)
+                        {
+                            if (strcmp (szFormatName, "HTML Format") == 0)
+                            {
+                                uFormats |= VBOX_SHARED_CLIPBOARD_FMT_HTML;
+                            }
+                        }
+                    }
+                    break;
+                }
+            }
+        }
+
+        int rc2 = VBoxClipboardWinClose();
+        AssertRC(rc2);
+    }
+
+    if (RT_FAILURE(rc))
+    {
+        LogFunc(("Failed with rc=%Rrc\n", rc));
+    }
+    else
+        *puFormats = uFormats;
+
+    return rc;
+}
+
Index: /trunk/src/VBox/HostServices/SharedClipboard/Makefile.kmk
===================================================================
--- /trunk/src/VBox/HostServices/SharedClipboard/Makefile.kmk	(revision 78150)
+++ /trunk/src/VBox/HostServices/SharedClipboard/Makefile.kmk	(revision 78151)
@@ -35,4 +35,5 @@
 VBoxSharedClipboard_SOURCES.win = \
 	VBoxClipboard-win.cpp \
+	$(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/clipboard-win.cpp \
 	VBoxSharedClipboardSvc.rc
 VBoxSharedClipboard_SOURCES.darwin = \
Index: /trunk/src/VBox/HostServices/SharedClipboard/VBoxClipboard-win.cpp
===================================================================
--- /trunk/src/VBox/HostServices/SharedClipboard/VBoxClipboard-win.cpp	(revision 78150)
+++ /trunk/src/VBox/HostServices/SharedClipboard/VBoxClipboard-win.cpp	(revision 78151)
@@ -24,4 +24,5 @@
 
 #include <VBox/HostServices/VBoxClipboardSvc.h>
+#include <VBox/GuestHost/SharedClipboard-win.h>
 
 #include <iprt/alloc.h>
@@ -35,17 +36,6 @@
 #include "VBoxClipboard.h"
 
-#define dprintf Log
-
-static char gachWindowClassName[] = "VBoxSharedClipboardClass";
-
-enum { CBCHAIN_TIMEOUT = 5000 /* ms */ };
-
-/* Dynamically load clipboard functions from User32.dll. */
-typedef BOOL WINAPI FNADDCLIPBOARDFORMATLISTENER(HWND);
-typedef FNADDCLIPBOARDFORMATLISTENER *PFNADDCLIPBOARDFORMATLISTENER;
-
-typedef BOOL WINAPI FNREMOVECLIPBOARDFORMATLISTENER(HWND);
-typedef FNREMOVECLIPBOARDFORMATLISTENER *PFNREMOVECLIPBOARDFORMATLISTENER;
-
+/** Static window class name. */
+static char s_szClipWndClassName[] = VBOX_CLIPBOARD_WNDCLASS_NAME;
 
 /*********************************************************************************************************************************
@@ -55,28 +45,16 @@
 static int ConvertMimeToCFHTML(const char *pszSource, size_t cb, char **ppszOutput, uint32_t *pcbOutput);
 static bool IsWindowsHTML(const char *source);
-
-
-#ifndef WM_CLIPBOARDUPDATE
-#define WM_CLIPBOARDUPDATE 0x031D
-#endif
+static int vboxClipboardSyncInternal(PVBOXCLIPBOARDCONTEXT pCtx);
 
 struct _VBOXCLIPBOARDCONTEXT
 {
-    HWND    hwnd;
-    HWND    hwndNextInChain;
-
-    UINT     timerRefresh;
-
-    bool     fCBChainPingInProcess;
-
-    RTTHREAD thread;
-
-    HANDLE hRenderEvent;
-
-    VBOXCLIPBOARDCLIENTDATA *pClient;
-
-    PFNADDCLIPBOARDFORMATLISTENER    pfnAddClipboardFormatListener;
-    PFNREMOVECLIPBOARDFORMATLISTENER pfnRemoveClipboardFormatListener;
-
+    /** Handle for window message handling thread. */
+    RTTHREAD                 hThread;
+    /** Event which gets triggered if the host clipboard needs to render its data. */
+    HANDLE                   hRenderEvent;
+    /** Structure for keeping and communicating with client data (from the guest). */
+    PVBOXCLIPBOARDCLIENTDATA pClient;
+    /** Windows-specific context data. */
+    VBOXCLIPBOARDWINCTX      Win;
 };
 
@@ -86,22 +64,22 @@
 
 #ifdef LOG_ENABLED
-void vboxClipboardDump(const void *pv, size_t cb, uint32_t u32Format)
+static void vboxClipboardDump(const void *pv, size_t cb, uint32_t u32Format)
 {
     if (u32Format & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
     {
-        Log(("DUMP: VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT:\n"));
+        LogFunc(("VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT:\n"));
         if (pv && cb)
-            Log(("%ls\n", pv));
+            LogFunc(("%ls\n", pv));
         else
-            Log(("%p %d\n", pv, cb));
+            LogFunc(("%p %zu\n", pv, cb));
     }
     else if (u32Format & VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
-        dprintf(("DUMP: VBOX_SHARED_CLIPBOARD_FMT_BITMAP\n"));
+        LogFunc(("VBOX_SHARED_CLIPBOARD_FMT_BITMAP\n"));
     else if (u32Format & VBOX_SHARED_CLIPBOARD_FMT_HTML)
     {
-        Log(("DUMP: VBOX_SHARED_CLIPBOARD_FMT_HTML:\n"));
+        LogFunc(("VBOX_SHARED_CLIPBOARD_FMT_HTML:\n"));
         if (pv && cb)
         {
-            Log(("%s\n", pv));
+            LogFunc(("%s\n", pv));
 
             //size_t cb = RTStrNLen(pv, );
@@ -114,12 +92,12 @@
             }
 
-            Log(("%s\n", pszBuf));
+            LogFunc(("%s\n", pszBuf));
             RTMemFree(pszBuf);
         }
         else
-            Log(("%p %d\n", pv, cb));
+            LogFunc(("%p %zu\n", pv, cb));
     }
     else
-        dprintf(("DUMP: invalid format %02X\n", u32Format));
+        LogFunc(("Invalid format %02X\n", u32Format));
 }
 #else  /* !LOG_ENABLED */
@@ -127,86 +105,8 @@
 #endif /* !LOG_ENABLED */
 
-
-static void vboxClipboardInitNewAPI(VBOXCLIPBOARDCONTEXT *pCtx)
-{
-    RTLDRMOD hUser32 = NIL_RTLDRMOD;
-    int rc = RTLdrLoadSystem("User32.dll", /* fNoUnload = */ true, &hUser32);
-    if (RT_SUCCESS(rc))
-    {
-        rc = RTLdrGetSymbol(hUser32, "AddClipboardFormatListener", (void**)&pCtx->pfnAddClipboardFormatListener);
-        if (RT_SUCCESS(rc))
-        {
-            rc = RTLdrGetSymbol(hUser32, "RemoveClipboardFormatListener", (void**)&pCtx->pfnRemoveClipboardFormatListener);
-        }
-
-        RTLdrClose(hUser32);
-    }
-
-    if (RT_SUCCESS(rc))
-    {
-        Log(("New Clipboard API is enabled\n"));
-    }
-    else
-    {
-        pCtx->pfnAddClipboardFormatListener = NULL;
-        pCtx->pfnRemoveClipboardFormatListener = NULL;
-        Log(("New Clipboard API is not available. rc = %Rrc\n", rc));
-    }
-}
-
-static bool vboxClipboardIsNewAPI(VBOXCLIPBOARDCONTEXT *pCtx)
-{
-    return pCtx->pfnAddClipboardFormatListener != NULL;
-}
-
-
-static int vboxOpenClipboard(HWND hwnd)
-{
-    /* "OpenClipboard fails if another window has the clipboard open."
-     * So try a few times and wait up to 1 second.
-     */
-    BOOL fOpened = FALSE;
-
-    int i = 0;
-    for (;;)
-    {
-        if (OpenClipboard(hwnd))
-        {
-            fOpened = TRUE;
-            break;
-        }
-
-        if (i >= 10) /* sleep interval = [1..512] ms */
-            break;
-
-        RTThreadSleep(1 << i);
-        ++i;
-    }
-
-#ifdef LOG_ENABLED
-    if (i > 0)
-        LogFlowFunc(("%d times tried to open clipboard.\n", i + 1));
-#endif
-
-    int rc;
-    if (fOpened)
-        rc = VINF_SUCCESS;
-    else
-    {
-        const DWORD err = GetLastError();
-        LogFlowFunc(("error %d\n", err));
-        rc = RTErrConvertFromWin32(err);
-    }
-
-    return rc;
-}
-
-
 /** @todo Someone please explain the protocol wrt overflows...  */
 static void vboxClipboardGetData (uint32_t u32Format, const void *pvSrc, uint32_t cbSrc,
                                   void *pvDst, uint32_t cbDst, uint32_t *pcbActualDst)
 {
-    dprintf (("vboxClipboardGetData.\n"));
-
     LogFlow(("vboxClipboardGetData cbSrc = %d, cbDst = %d\n", cbSrc, cbDst));
 
@@ -270,108 +170,9 @@
 }
 
-static void vboxClipboardChanged (VBOXCLIPBOARDCONTEXT *pCtx)
-{
-    LogFlow(("vboxClipboardChanged\n"));
-
-    if (pCtx->pClient == NULL)
-    {
-        return;
-    }
-
-    /* Query list of available formats and report to host. */
-    int rc = vboxOpenClipboard(pCtx->hwnd);
-    if (RT_SUCCESS(rc))
-    {
-        uint32_t u32Formats = 0;
-
-        UINT format = 0;
-
-        while ((format = EnumClipboardFormats (format)) != 0)
-        {
-            LogFlow(("vboxClipboardChanged format %#x\n", format));
-            switch (format)
-            {
-                case CF_UNICODETEXT:
-                case CF_TEXT:
-                    u32Formats |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT;
-                    break;
-
-                case CF_DIB:
-                case CF_BITMAP:
-                    u32Formats |= VBOX_SHARED_CLIPBOARD_FMT_BITMAP;
-                    break;
-
-                default:
-                    if (format >= 0xC000)
-                    {
-                        TCHAR szFormatName[256];
-
-                        int cActual = GetClipboardFormatName(format, szFormatName, sizeof(szFormatName)/sizeof (TCHAR));
-
-                        if (cActual)
-                        {
-                            if (strcmp (szFormatName, "HTML Format") == 0)
-                            {
-                                u32Formats |= VBOX_SHARED_CLIPBOARD_FMT_HTML;
-                            }
-                        }
-                    }
-                    break;
-            }
-        }
-
-        CloseClipboard ();
-
-        LogFlow(("vboxClipboardChanged u32Formats %02X\n", u32Formats));
-
-        vboxSvcClipboardReportMsg (pCtx->pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS, u32Formats);
-    }
-    else
-    {
-        LogFlow(("vboxClipboardChanged: error in open clipboard. hwnd: %x. err: %Rrc\n", pCtx->hwnd, rc));
-    }
-}
-
-/* Add ourselves into the chain of cliboard listeners */
-static void addToCBChain (VBOXCLIPBOARDCONTEXT *pCtx)
-{
-    if (vboxClipboardIsNewAPI(pCtx))
-        pCtx->pfnAddClipboardFormatListener(pCtx->hwnd);
-    else
-        pCtx->hwndNextInChain = SetClipboardViewer(pCtx->hwnd);
-}
-
-/* Remove ourselves from the chain of cliboard listeners */
-static void removeFromCBChain (VBOXCLIPBOARDCONTEXT *pCtx)
-{
-    if (vboxClipboardIsNewAPI(pCtx))
-    {
-        pCtx->pfnRemoveClipboardFormatListener(pCtx->hwnd);
-    }
-    else
-    {
-        ChangeClipboardChain(pCtx->hwnd, pCtx->hwndNextInChain);
-        pCtx->hwndNextInChain = NULL;
-    }
-}
-
-/* Callback which is invoked when we have successfully pinged ourselves down the
- * clipboard chain.  We simply unset a boolean flag to say that we are responding.
- * There is a race if a ping returns after the next one is initiated, but nothing
- * very bad is likely to happen. */
-VOID CALLBACK CBChainPingProc(HWND hwnd, UINT uMsg, ULONG_PTR dwData, LRESULT lResult)
-{
-    (void) hwnd;
-    (void) uMsg;
-    (void) lResult;
-    VBOXCLIPBOARDCONTEXT *pCtx = (VBOXCLIPBOARDCONTEXT *)dwData;
-    pCtx->fCBChainPingInProcess = FALSE;
-}
-
 static LRESULT CALLBACK vboxClipboardWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
     LRESULT rc = 0;
 
-    VBOXCLIPBOARDCONTEXT *pCtx = &g_ctx;
+    PVBOXCLIPBOARDCONTEXT pCtx = &g_ctx;
 
     switch (msg)
@@ -383,6 +184,7 @@
             if (GetClipboardOwner() != hwnd)
             {
-                /* Clipboard was updated by another application. */
-                vboxClipboardChanged(pCtx);
+                /* Clipboard was updated by another application, retrieve formats and report back. */
+                int vboxrc = vboxClipboardSyncInternal(pCtx);
+                AssertRC(vboxrc);
             }
         } break;
@@ -392,5 +194,5 @@
             Log(("WM_CHANGECBCHAIN\n"));
 
-            if (vboxClipboardIsNewAPI(pCtx))
+            if (VBoxClipboardWinIsNewAPI(&pCtx->Win.newAPI))
             {
                 rc = DefWindowProc(hwnd, msg, wParam, lParam);
@@ -401,18 +203,20 @@
             HWND hwndNext    = (HWND)lParam;
 
-            if (hwndRemoved == pCtx->hwndNextInChain)
+            if (hwndRemoved == pCtx->Win.hWndNextInChain)
             {
                 /* The window that was next to our in the chain is being removed.
                  * Relink to the new next window.
                  */
-                pCtx->hwndNextInChain = hwndNext;
+                pCtx->Win.hWndNextInChain = hwndNext;
             }
             else
             {
-                if (pCtx->hwndNextInChain)
+                if (pCtx->Win.hWndNextInChain)
                 {
                     /* Pass the message further. */
                     DWORD_PTR dwResult;
-                    rc = SendMessageTimeout(pCtx->hwndNextInChain, WM_CHANGECBCHAIN, wParam, lParam, 0, CBCHAIN_TIMEOUT, &dwResult);
+                    rc = SendMessageTimeout(pCtx->Win.hWndNextInChain, WM_CHANGECBCHAIN, wParam, lParam, 0,
+                                            VBOX_CLIPBOARD_CBCHAIN_TIMEOUT_MS,
+                                            &dwResult);
                     if (!rc)
                         rc = (LRESULT)dwResult;
@@ -425,16 +229,18 @@
             Log(("WM_DRAWCLIPBOARD\n"));
 
-            if (GetClipboardOwner () != hwnd)
-            {
-                /* Clipboard was updated by another application. */
-                vboxClipboardChanged (pCtx);
-            }
-
-            if (pCtx->hwndNextInChain)
-            {
-                Log(("WM_DRAWCLIPBOARD next %p\n", pCtx->hwndNextInChain));
+            if (GetClipboardOwner() != hwnd)
+            {
+                /* Clipboard was updated by another application, retrieve formats and report back. */
+                int vboxrc = vboxClipboardSyncInternal(pCtx);
+                AssertRC(vboxrc);
+            }
+
+            if (pCtx->Win.hWndNextInChain)
+            {
+                Log(("WM_DRAWCLIPBOARD next %p\n", pCtx->Win.hWndNextInChain));
                 /* Pass the message to next windows in the clipboard chain. */
                 DWORD_PTR dwResult;
-                rc = SendMessageTimeout(pCtx->hwndNextInChain, msg, wParam, lParam, 0, CBCHAIN_TIMEOUT, &dwResult);
+                rc = SendMessageTimeout(pCtx->Win.hWndNextInChain, msg, wParam, lParam, 0, VBOX_CLIPBOARD_CBCHAIN_TIMEOUT_MS,
+                                        &dwResult);
                 if (!rc)
                     rc = dwResult;
@@ -444,5 +250,5 @@
         case WM_TIMER:
         {
-            if (vboxClipboardIsNewAPI(pCtx))
+            if (VBoxClipboardWinIsNewAPI(&pCtx->Win.newAPI))
                 break;
 
@@ -451,15 +257,19 @@
             /* Re-register ourselves in the clipboard chain if our last ping
              * timed out or there seems to be no valid chain. */
-            if (!hViewer || pCtx->fCBChainPingInProcess)
-            {
-                removeFromCBChain(pCtx);
-                addToCBChain(pCtx);
-            }
+            if (!hViewer || pCtx->Win.oldAPI.fCBChainPingInProcess)
+            {
+                VBoxClipboardWinRemoveFromCBChain(&pCtx->Win);
+                VBoxClipboardWinAddToCBChain(&pCtx->Win);
+            }
+
             /* Start a new ping by passing a dummy WM_CHANGECBCHAIN to be
              * processed by ourselves to the chain. */
-            pCtx->fCBChainPingInProcess = TRUE;
+            pCtx->Win.oldAPI.fCBChainPingInProcess = TRUE;
+
             hViewer = GetClipboardViewer();
             if (hViewer)
-                SendMessageCallback(hViewer, WM_CHANGECBCHAIN, (WPARAM)pCtx->hwndNextInChain, (LPARAM)pCtx->hwndNextInChain, CBChainPingProc, (ULONG_PTR) pCtx);
+                SendMessageCallback(hViewer, WM_CHANGECBCHAIN,
+                                    (WPARAM)pCtx->Win.hWndNextInChain, (LPARAM)pCtx->Win.hWndNextInChain,
+                                    VBoxClipboardWinChainPingProc, (ULONG_PTR)pCtx);
         } break;
 
@@ -511,5 +321,5 @@
                 int vboxrc = vboxClipboardReadDataFromClient (pCtx, u32Format);
 
-                dprintf(("vboxClipboardReadDataFromClient vboxrc = %d, pv %p, cb %d, u32Format %d\n",
+                LogFunc(("vboxClipboardReadDataFromClient vboxrc = %d, pv %p, cb %d, u32Format %d\n",
                           vboxrc, pCtx->pClient->data.pv, pCtx->pClient->data.cb, pCtx->pClient->data.u32Format));
 
@@ -521,5 +331,5 @@
                     HANDLE hMem = GlobalAlloc (GMEM_DDESHARE | GMEM_MOVEABLE, pCtx->pClient->data.cb);
 
-                    dprintf(("hMem %p\n", hMem));
+                    LogFunc(("hMem %p\n", hMem));
 
                     if (hMem)
@@ -527,5 +337,5 @@
                         void *pMem = GlobalLock (hMem);
 
-                        dprintf(("pMem %p, GlobalSize %d\n", pMem, GlobalSize (hMem)));
+                        LogFunc(("pMem %p, GlobalSize %d\n", pMem, GlobalSize (hMem)));
 
                         if (pMem)
@@ -552,5 +362,5 @@
                             HANDLE hClip = SetClipboardData (format, hMem);
 
-                            dprintf(("vboxClipboardHostEvent hClip %p\n", hClip));
+                            LogFunc(("vboxClipboardHostEvent hClip %p\n", hClip));
 
                             if (hClip)
@@ -571,5 +381,5 @@
 
                 /* Something went wrong. */
-                EmptyClipboard ();
+                VBoxClipboardWinClear();
             }
         } break;
@@ -582,10 +392,9 @@
              * windows is to be destroyed and therefore the guest side becomes inactive.
              */
-            int vboxrc = vboxOpenClipboard(hwnd);
+            int vboxrc = VBoxClipboardWinOpen(hwnd);
             if (RT_SUCCESS(vboxrc))
             {
-                EmptyClipboard();
-
-                CloseClipboard();
+                VBoxClipboardWinClear();
+                VBoxClipboardWinClose();
             }
             else
@@ -595,5 +404,5 @@
         } break;
 
-        case WM_USER:
+        case VBOX_CLIPBOARD_WM_SET_FORMATS:
         {
             if (pCtx->pClient == NULL || pCtx->pClient->fMsgFormats)
@@ -602,5 +411,5 @@
                  * because host clipboard has more priority.
                  */
-                Log(("WM_USER ignored\n"));
+                Log(("VBOX_CLIPBOARD_WM_SET_FORMATS ignored\n"));
                 break;
             }
@@ -609,33 +418,24 @@
             uint32_t u32Formats = (uint32_t)lParam;
 
-            Log(("WM_USER u32Formats = %02X\n", u32Formats));
-
-            int vboxrc = vboxOpenClipboard(hwnd);
+            Log(("VBOX_CLIPBOARD_WM_SET_FORMATS: u32Formats=%02X\n", u32Formats));
+
+            int vboxrc = VBoxClipboardWinOpen(hwnd);
             if (RT_SUCCESS(vboxrc))
             {
-                EmptyClipboard();
-
-                Log(("WM_USER emptied clipboard\n"));
+                VBoxClipboardWinClear();
+
+                Log(("VBOX_CLIPBOARD_WM_SET_FORMATS emptied clipboard\n"));
 
                 HANDLE hClip = NULL;
 
                 if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
-                {
-                    dprintf(("window proc WM_USER: VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT\n"));
-
-                    hClip = SetClipboardData (CF_UNICODETEXT, NULL);
-                }
+                    hClip = SetClipboardData(CF_UNICODETEXT, NULL);
 
                 if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
-                {
-                    dprintf(("window proc WM_USER: VBOX_SHARED_CLIPBOARD_FMT_BITMAP\n"));
-
-                    hClip = SetClipboardData (CF_DIB, NULL);
-                }
+                    hClip = SetClipboardData(CF_DIB, NULL);
 
                 if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_HTML)
                 {
                     UINT format = RegisterClipboardFormat ("HTML Format");
-                    dprintf(("window proc WM_USER: VBOX_SHARED_CLIPBOARD_FMT_HTML 0x%04X\n", format));
                     if (format != 0)
                     {
@@ -644,11 +444,7 @@
                 }
 
-                CloseClipboard();
-
-                dprintf(("window proc WM_USER: hClip %p, err %d\n", hClip, GetLastError ()));
-            }
-            else
-            {
-                dprintf(("window proc WM_USER: failed to open clipboard. rc: %Rrc\n", vboxrc));
+                VBoxClipboardWinClose();
+
+                LogFunc(("VBOX_CLIPBOARD_WM_SET_FORMATS: hClip=%p, lastErr=%ld\n", hClip, GetLastError ()));
             }
         } break;
@@ -656,9 +452,11 @@
         case WM_DESTROY:
         {
-            /* MS recommends to remove from Clipboard chain in this callback */
-            Assert(pCtx->hwnd);
-            removeFromCBChain(pCtx);
-            if (pCtx->timerRefresh)
-                KillTimer(pCtx->hwnd, 0);
+            /* MS recommends to remove from Clipboard chain in this callback. */
+            VBoxClipboardWinRemoveFromCBChain(&pCtx->Win);
+            if (pCtx->Win.oldAPI.timerRefresh)
+            {
+                Assert(pCtx->Win.hWnd);
+                KillTimer(pCtx->Win.hWnd, 0);
+            }
             PostQuitMessage(0);
         } break;
@@ -683,5 +481,5 @@
     LogFlow(("VBoxClipboardThread\n"));
 
-    VBOXCLIPBOARDCONTEXT *pCtx = &g_ctx;
+    const PVBOXCLIPBOARDCONTEXT pCtx = &g_ctx;
 
     HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL);
@@ -695,5 +493,5 @@
     wc.hInstance     = hInstance;
     wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
-    wc.lpszClassName = gachWindowClassName;
+    wc.lpszClassName = s_szClipWndClassName;
 
     ATOM atomWindowClass = RegisterClass(&wc);
@@ -707,10 +505,9 @@
     {
         /* Create the window. */
-        pCtx->hwnd = CreateWindowEx (WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_TOPMOST,
-                                     gachWindowClassName, gachWindowClassName,
-                                     WS_POPUPWINDOW,
-                                     -200, -200, 100, 100, NULL, NULL, hInstance, NULL);
-
-        if (pCtx->hwnd == NULL)
+        pCtx->Win.hWnd = CreateWindowEx (WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_TOPMOST,
+                                         s_szClipWndClassName, s_szClipWndClassName,
+                                         WS_POPUPWINDOW,
+                                         -200, -200, 100, 100, NULL, NULL, hInstance, NULL);
+        if (pCtx->Win.hWnd == NULL)
         {
             Log(("Failed to create window\n"));
@@ -719,10 +516,10 @@
         else
         {
-            SetWindowPos(pCtx->hwnd, HWND_TOPMOST, -200, -200, 0, 0,
+            SetWindowPos(pCtx->Win.hWnd, HWND_TOPMOST, -200, -200, 0, 0,
                          SWP_NOACTIVATE | SWP_HIDEWINDOW | SWP_NOCOPYBITS | SWP_NOREDRAW | SWP_NOSIZE);
 
-            addToCBChain(pCtx);
-            if (!vboxClipboardIsNewAPI(pCtx))
-                pCtx->timerRefresh = SetTimer(pCtx->hwnd, 0, 10 * 1000, NULL);
+            VBoxClipboardWinAddToCBChain(&pCtx->Win);
+            if (!VBoxClipboardWinIsNewAPI(&pCtx->Win.newAPI))
+                pCtx->Win.oldAPI.timerRefresh = SetTimer(pCtx->Win.hWnd, 0, 10 * 1000, NULL);
 
             MSG msg;
@@ -743,13 +540,30 @@
     }
 
-    pCtx->hwnd = NULL;
+    pCtx->Win.hWnd = NULL;
 
     if (atomWindowClass != 0)
     {
-        UnregisterClass (gachWindowClassName, hInstance);
+        UnregisterClass (s_szClipWndClassName, hInstance);
         atomWindowClass = 0;
     }
 
     return 0;
+}
+
+/**
+ * Synchronizes the host and the guest clipboard formats by sending all supported host clipboard
+ * formats to the guest.
+ *
+ * @returns VBox status code.
+ * @param   pCtx                Clipboard context to synchronize.
+ */
+static int vboxClipboardSyncInternal(PVBOXCLIPBOARDCONTEXT pCtx)
+{
+    uint32_t uFormats;
+    int rc = VBoxClipboardWinGetFormats(&pCtx->Win, &uFormats);
+    if (RT_SUCCESS(rc))
+        vboxSvcClipboardReportMsg(pCtx->pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS, uFormats);
+
+    return rc;
 }
 
@@ -763,10 +577,10 @@
     RT_ZERO(g_ctx);
 
-    /* Check that new Clipboard API is available */
-    vboxClipboardInitNewAPI(&g_ctx);
+    /* Check that new Clipboard API is available. */
+    VBoxClipboardWinCheckAndInitNewAPI(&g_ctx.Win.newAPI);
 
     g_ctx.hRenderEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
 
-    rc = RTThreadCreate (&g_ctx.thread, VBoxClipboardThread, NULL, 65536,
+    rc = RTThreadCreate (&g_ctx.hThread, VBoxClipboardThread, NULL, 65536,
                          RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "SHCLIP");
 
@@ -783,7 +597,7 @@
     Log(("vboxClipboardDestroy\n"));
 
-    if (g_ctx.hwnd)
-    {
-        PostMessage (g_ctx.hwnd, WM_CLOSE, 0, 0);
+    if (g_ctx.Win.hWnd)
+    {
+        PostMessage (g_ctx.Win.hWnd, WM_CLOSE, 0, 0);
     }
 
@@ -791,7 +605,7 @@
 
     /* Wait for the window thread to terminate. */
-    RTThreadWait (g_ctx.thread, RT_INDEFINITE_WAIT, NULL);
-
-    g_ctx.thread = NIL_RTTHREAD;
+    RTThreadWait (g_ctx.hThread, RT_INDEFINITE_WAIT, NULL);
+
+    g_ctx.hThread = NIL_RTTHREAD;
 }
 
@@ -820,7 +634,5 @@
 {
     /* Sync the host clipboard content with the client. */
-    vboxClipboardChanged (pClient->pCtx);
-
-    return VINF_SUCCESS;
+    return vboxClipboardSyncInternal(pClient->pCtx);
 }
 
@@ -838,5 +650,5 @@
      * The guest announces formats. Forward to the window thread.
      */
-    PostMessage (pClient->pCtx->hwnd, WM_USER, 0, u32Formats);
+    PostMessage (pClient->pCtx->Win.hWnd, WM_USER, 0, u32Formats);
 }
 
@@ -880,8 +692,8 @@
      * The guest wants to read data in the given format.
      */
-    int rc = vboxOpenClipboard(pClient->pCtx->hwnd);
+    int rc = VBoxClipboardWinOpen(pClient->pCtx->Win.hWnd);
     if (RT_SUCCESS(rc))
     {
-        dprintf(("Clipboard opened.\n"));
+        LogFunc(("Clipboard opened.\n"));
 
         if (u32Format & VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
@@ -895,5 +707,5 @@
                 if (lp != NULL)
                 {
-                    dprintf(("CF_DIB\n"));
+                    LogFunc(("CF_DIB\n"));
 
                     vboxClipboardGetData (VBOX_SHARED_CLIPBOARD_FMT_BITMAP, lp, GlobalSize (hClip),
@@ -918,5 +730,5 @@
                 if (uniString != NULL)
                 {
-                    dprintf(("CF_UNICODETEXT\n"));
+                    LogFunc(("CF_UNICODETEXT\n"));
 
                     vboxClipboardGetData (VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT, uniString, (lstrlenW (uniString) + 1) * 2,
@@ -945,5 +757,5 @@
                     if (lp != NULL)
                     {
-                        dprintf(("CF_HTML\n"));
+                        LogFunc(("CF_HTML\n"));
 
                         vboxClipboardGetData (VBOX_SHARED_CLIPBOARD_FMT_HTML, lp, GlobalSize (hClip),
@@ -961,9 +773,9 @@
         }
 
-        CloseClipboard ();
+        VBoxClipboardWinClose();
     }
     else
     {
-        dprintf(("vboxClipboardReadData: failed to open clipboard, rc: %Rrc\n", rc));
+        LogFunc(("vboxClipboardReadData: failed to open clipboard, rc: %Rrc\n", rc));
     }
 
Index: /trunk/src/VBox/HostServices/SharedClipboard/VBoxClipboard.h
===================================================================
--- /trunk/src/VBox/HostServices/SharedClipboard/VBoxClipboard.h	(revision 78150)
+++ /trunk/src/VBox/HostServices/SharedClipboard/VBoxClipboard.h	(revision 78151)
@@ -25,7 +25,5 @@
 #include <VBox/log.h>
 
-struct _VBOXCLIPBOARDCONTEXT;
-typedef struct _VBOXCLIPBOARDCONTEXT VBOXCLIPBOARDCONTEXT;
-
+#include <VBox/GuestHost/SharedClipboard.h>
 
 typedef struct _VBOXCLIPBOARDCLIENTDATA
@@ -64,17 +62,11 @@
     uint32_t u32RequestedFormat;
 
-} VBOXCLIPBOARDCLIENTDATA;
+} VBOXCLIPBOARDCLIENTDATA, *PVBOXCLIPBOARDCLIENTDATA;
 
 /*
  * The service functions. Locking is between the service thread and the platform dependent windows thread.
  */
-bool vboxSvcClipboardLock (void);
-void vboxSvcClipboardUnlock (void);
-
 void vboxSvcClipboardReportMsg (VBOXCLIPBOARDCLIENTDATA *pClient, uint32_t u32Msg, uint32_t u32Formats);
-
 void vboxSvcClipboardCompleteReadData(VBOXCLIPBOARDCLIENTDATA *pClient, int rc, uint32_t cbActual);
-
-bool vboxSvcClipboardGetHeadless(void);
 
 /*
@@ -86,9 +78,6 @@
 int vboxClipboardConnect (VBOXCLIPBOARDCLIENTDATA *pClient, bool fHeadless);
 void vboxClipboardDisconnect (VBOXCLIPBOARDCLIENTDATA *pClient);
-
 void vboxClipboardFormatAnnounce (VBOXCLIPBOARDCLIENTDATA *pClient, uint32_t u32Formats);
-
 int vboxClipboardReadData (VBOXCLIPBOARDCLIENTDATA *pClient, uint32_t u32Format, void *pv, uint32_t cb, uint32_t *pcbActual);
-
 void vboxClipboardWriteData (VBOXCLIPBOARDCLIENTDATA *pClient, void *pv, uint32_t cb, uint32_t u32Format);
 
Index: /trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc.cpp
===================================================================
--- /trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc.cpp	(revision 78150)
+++ /trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc.cpp	(revision 78151)
@@ -109,4 +109,8 @@
 static bool g_fHeadless = false;
 
+static bool vboxSvcClipboardGetHeadless(void);
+static bool vboxSvcClipboardLock(void);
+static void vboxSvcClipboardUnlock(void);
+
 
 static void VBoxHGCMParmUInt32Set (VBOXHGCMSVCPARM *pParm, uint32_t u32)
@@ -163,5 +167,5 @@
 
 /** Getter for headless setting */
-bool vboxSvcClipboardGetHeadless(void)
+static bool vboxSvcClipboardGetHeadless(void)
 {
     return g_fHeadless;
@@ -184,10 +188,10 @@
 }
 
-bool vboxSvcClipboardLock (void)
+static bool vboxSvcClipboardLock (void)
 {
     return RT_SUCCESS(RTCritSectEnter (&critsect));
 }
 
-void vboxSvcClipboardUnlock (void)
+static void vboxSvcClipboardUnlock(void)
 {
     RTCritSectLeave (&critsect);
