Index: /trunk/include/VBox/vrdpapi.h
===================================================================
--- /trunk/include/VBox/vrdpapi.h	(revision 2521)
+++ /trunk/include/VBox/vrdpapi.h	(revision 2522)
@@ -555,11 +555,13 @@
  *   - (0) guest announces available clipboard formats;
  *   - (1) guest requests clipboard data;
- *   - (2) host responds to the client's request for clipboard data.
+ *   - (2) guest responds to the client's request for clipboard data.
  *
  * @param hserver     The VRDP server handle.
  * @param u32Function The cause of the call.
  * @param u32Format   Bitmask of announced formats or the format of data.
- * @param pvData      Points to data from the host, as reply to (2).
- * @param cbData      Size of the data in bytes.
+ * @param pvData      Points to: (1) buffer to be filled with clients data;
+ *                               (2) data from the host.
+ * @param cbData      Size of 'pvData' buffer in bytes.
+ * @param pcbActualRead Size of the copied data in bytes.
  *
  */
@@ -567,6 +569,7 @@
                                 uint32_t u32Function,
                                 uint32_t u32Format,
-                                const void *pvData,
-                                uint32_t cbData);
+                                void *pvData,
+                                uint32_t cbData,
+                                uint32_t *pcbActualRead);
 
 #ifdef VRDP_MC
@@ -610,16 +613,12 @@
  * Called by the server when (VRDP_CLIPBOARD_FUNCTION_*):
  *   - (0) client announces available clipboard formats;
- *   - (1) client requests clipboard data;
- *   - (2) client responds to the guest's request for clipboard data.
- *
- *   - client announces available clipboard formats;
- *   - clipboard data is received from the client.
+ *   - (1) client requests clipboard data.
  *
  * @param pvCallback  Callback specific value returned by VRDPSERVERCALLBACK::pfnInterceptClipboard.
  * @param u32ClientId Identifies the RDP client that sent the reply.
- * @param u32Function The cause if the callback.
+ * @param u32Function The cause of the callback.
  * @param u32Format   Bitmask of reported formats or the format of received data.
- * @param pvData      Points to data received from the client.
- * @param cbData      Size of the data in bytes.
+ * @param pvData      Reserved.
+ * @param cbData      Reserved.
  *
  * @return VBox error code.
Index: /trunk/src/VBox/Main/ConsoleVRDPServer.cpp
===================================================================
--- /trunk/src/VBox/Main/ConsoleVRDPServer.cpp	(revision 2521)
+++ /trunk/src/VBox/Main/ConsoleVRDPServer.cpp	(revision 2522)
@@ -34,8 +34,4 @@
 // ConsoleVRDPServer
 ////////////////////////////////////////////////////////////////////////////////
-
-#define VBOX_CLIPBOARD_NO_DATA      0
-#define VBOX_CLIPBOARD_DATA_WAITING 1
-#define VBOX_CLIPBOARD_DATA_ARRIVED 2
 
 #ifdef VBOX_VRDP
@@ -56,6 +52,6 @@
 void (VBOXCALL *ConsoleVRDPServer::mpfnVRDPSendUpdate)      (HVRDPSERVER hServer, void *pvUpdate, uint32_t cbUpdate);
 void (VBOXCALL *ConsoleVRDPServer::mpfnVRDPQueryInfo)       (HVRDPSERVER hserver, uint32_t index, void *pvBuffer, uint32_t cbBuffer, uint32_t *pcbOut);
-void (VBOXCALL *ConsoleVRDPServer::mpfnVRDPClipboard)       (HVRDPSERVER hserver, uint32_t u32Function, uint32_t u32Format, const void *pvData, uint32_t cbData);
-#endif
+void (VBOXCALL *ConsoleVRDPServer::mpfnVRDPClipboard)       (HVRDPSERVER hserver, uint32_t u32Function, uint32_t u32Format, const void *pvData, uint32_t cbData, uint32_t *pcbActualRead);
+#endif /* VBOX_VRDP */
 
 ConsoleVRDPServer::ConsoleVRDPServer (Console *console)
@@ -70,10 +66,4 @@
     mpfnClipboardCallback = NULL;
 
-    rc = RTSemEventMultiCreate(&mEventClipboardData);
-    AssertRC (rc);
-    mpvClipboardData = NULL;
-    mcbClipboardData = 0;
-    mfu32ClipboardWaitData = VBOX_CLIPBOARD_NO_DATA;
-    
 #ifdef VBOX_WITH_USB
     mUSBBackends.pHead = NULL;
@@ -101,6 +91,4 @@
 #ifdef VRDP_MC
     Stop ();
-    
-    RTSemEventMultiDestroy (mEventClipboardData);
 
     if (RTCritSectIsInitialized (&mCritSect))
@@ -461,7 +449,4 @@
                                                 cbData);
             }
-            
-            /* Discard current data. */
-            ASMAtomicCmpXchgU32(&pServer->mfu32ClipboardWaitData, VBOX_CLIPBOARD_NO_DATA, VBOX_CLIPBOARD_DATA_ARRIVED);
         } break; 
         
@@ -477,35 +462,4 @@
         } break; 
 
-        case VRDP_CLIPBOARD_FUNCTION_DATA_WRITE:
-        {
-            if (ASMAtomicCmpXchgU32(&pServer->mfu32ClipboardWaitData, VBOX_CLIPBOARD_DATA_ARRIVED, VBOX_CLIPBOARD_DATA_WAITING))
-            {
-                LogFlowFunc(("Got clipboard data\n"));
-                
-                if (pServer->mpvClipboardData)
-                {
-                    RTMemFree (pServer->mpvClipboardData);
-                    pServer->mpvClipboardData = NULL;
-                }
-                
-                if (cbData)
-                {
-                    void *pv = RTMemAlloc (cbData);
-            
-                    memcpy (pv, pvData, cbData);
-            
-                    pServer->mpvClipboardData = pv;
-                    pServer->mcbClipboardData = cbData;
-                }
-                else
-                {
-                    pServer->mpvClipboardData = NULL;
-                    pServer->mcbClipboardData = 0;
-                }
-            
-                RTSemEventMultiSignal (pServer->mEventClipboardData);
-            }
-        } break; 
-
         default: 
             rc = VERR_NOT_SUPPORTED;
@@ -539,4 +493,5 @@
         case VBOX_CLIPBOARD_EXT_FN_FORMAT_ANNOUNCE:
         {
+            /* The guest announces clipboard formats. This must be delivered to all clients. */
             if (mpfnVRDPClipboard)
             {
@@ -545,5 +500,6 @@
                                    pParms->u32Format,
                                    NULL,
-                                   0);
+                                   0,
+                                   NULL);
             }
         } break;
@@ -551,45 +507,16 @@
         case VBOX_CLIPBOARD_EXT_FN_DATA_READ:
         {
+            /* The clipboard service expects that the pvData buffer will be filled
+             * with clipboard data. The server returns the data from the client that
+             * announced the requested format most recently.
+             */
             if (mpfnVRDPClipboard)
             {
-                if (ASMAtomicCmpXchgU32(&pServer->mfu32ClipboardWaitData, VBOX_CLIPBOARD_DATA_WAITING, VBOX_CLIPBOARD_NO_DATA))
-                {
-                    LogFlowFunc(("Wait for clipboard data\n"));
-                    RTSemEventMultiReset(pServer->mEventClipboardData);
-                    
-                    mpfnVRDPClipboard (pServer->mhServer, 
-                                       VRDP_CLIPBOARD_FUNCTION_DATA_READ,
-                                       pParms->u32Format,
-                                       NULL,
-                                       0);
-                    
-                    /* Wait for the client. 10 seconds should be enough. */
-                    int rc = RTSemEventMultiWait(pServer->mEventClipboardData, 10*1000);
-                    LogFlowFunc (("Wait completed rc = %d.\n", rc)); NOREF(rc);
-                }
-                
-                if (pServer->mfu32ClipboardWaitData == VBOX_CLIPBOARD_DATA_ARRIVED)
-                {
-                    LogFlowFunc(("Return clipboard data: pParms->cbData = %d, mcbClipboardData = %d\n", pParms->cbData, pServer->mcbClipboardData));
-                    if (pParms->cbData >= pServer->mcbClipboardData)
-                    {
-                        if (pServer->mcbClipboardData)
-                        {
-                            memcpy (pParms->pvData, pServer->mpvClipboardData, pServer->mcbClipboardData);
-                        }
-                    
-                        RTMemFree (pServer->mpvClipboardData);
-                        pServer->mpvClipboardData = NULL;
-                        
-                        pServer->mfu32ClipboardWaitData = VBOX_CLIPBOARD_NO_DATA;
-                    }
-                
-                    pParms->cbData = pServer->mcbClipboardData;
-                }
-                else
-                {
-                    pParms->pvData = NULL;
-                    pParms->cbData = 0;
-                }
+                mpfnVRDPClipboard (pServer->mhServer, 
+                                   VRDP_CLIPBOARD_FUNCTION_DATA_READ,
+                                   pParms->u32Format,
+                                   pParms->pvData,
+                                   pParms->cbData,
+                                   &pParms->cbData);
             }
         } break;
@@ -603,5 +530,6 @@
                                    pParms->u32Format,
                                    pParms->pvData,
-                                   pParms->cbData);
+                                   pParms->cbData,
+                                   NULL);
             }
         } break;
Index: /trunk/src/VBox/Main/include/ConsoleVRDPServer.h
===================================================================
--- /trunk/src/VBox/Main/include/ConsoleVRDPServer.h	(revision 2521)
+++ /trunk/src/VBox/Main/include/ConsoleVRDPServer.h	(revision 2522)
@@ -121,6 +121,6 @@
     static void (VBOXCALL *mpfnVRDPSendUpdate)      (HVRDPSERVER hServer, void *pvUpdate, uint32_t cbUpdate);
     static void (VBOXCALL *mpfnVRDPQueryInfo)       (HVRDPSERVER hserver, uint32_t index, void *pvBuffer, uint32_t cbBuffer, uint32_t *pcbOut);
-    static void (VBOXCALL *mpfnVRDPClipboard)       (HVRDPSERVER hserver, uint32_t u32Function, uint32_t u32Format, const void *pvData, uint32_t cbData);
-#endif
+    static void (VBOXCALL *mpfnVRDPClipboard)       (HVRDPSERVER hserver, uint32_t u32Function, uint32_t u32Format, const void *pvData, uint32_t cbData, uint32_t *pcbActualRead);
+#endif /* VBOX_VRDP */
 
 #ifdef VRDP_MC
@@ -133,9 +133,4 @@
     HGCMSVCEXTHANDLE mhClipboard;
     PFNVRDPCLIPBOARDEXTCALLBACK mpfnClipboardCallback;
-
-    RTSEMEVENTMULTI   mEventClipboardData;
-    void             *mpvClipboardData;
-    uint32_t          mcbClipboardData;
-    volatile uint32_t mfu32ClipboardWaitData;
 
     static DECLCALLBACK(int) ClipboardCallback (void *pvCallback, uint32_t u32ClientId, uint32_t u32Function, uint32_t u32Format, const void *pvData, uint32_t cbData);
