service.cpp revision c7210c2150d85e23412b7c1d887e7f38c6ab2d25
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync * Shared Clipboard:
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync * Host service entry points.
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync * available from http://www.virtualbox.org. This file is free software;
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync * you can redistribute it and/or modify it under the terms of the GNU
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync * General Public License (GPL) as published by the Free Software
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync * additional information or have any questions.
e2a73964f463b9e91f6f096f9e15974a3edcc416vboxsyncstatic void VBoxHGCMParmUInt32Set (VBOXHGCMSVCPARM *pParm, uint32_t u32)
39c2eccedfdb7455c52225543c355e33a65f0c81vboxsyncstatic int VBoxHGCMParmUInt32Get (VBOXHGCMSVCPARM *pParm, uint32_t *pu32)
e2a73964f463b9e91f6f096f9e15974a3edcc416vboxsyncstatic void VBoxHGCMParmPtrSet (VBOXHGCMSVCPARM *pParm, void *pv, uint32_t cb)
e2a73964f463b9e91f6f096f9e15974a3edcc416vboxsyncstatic int VBoxHGCMParmPtrGet (VBOXHGCMSVCPARM *pParm, void **ppv, uint32_t *pcb)
39c2eccedfdb7455c52225543c355e33a65f0c81vboxsync/* Serialization of data reading and format announcements from the RDP client. */
39c2eccedfdb7455c52225543c355e33a65f0c81vboxsyncstatic bool g_fReadingData = false;
39c2eccedfdb7455c52225543c355e33a65f0c81vboxsyncstatic bool g_fDelayedAnnouncement = false;
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsyncstatic void vboxSvcClipboardModeSet (uint32_t u32Mode)
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync/* Set the HGCM parameters according to pending messages.
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync * Executed under the clipboard lock.
d1c36fd86d36726777e3d6f9d040573e0aaf30devboxsyncstatic bool vboxSvcClipboardReturnMsg (VBOXCLIPBOARDCLIENTDATA *pClient, VBOXHGCMSVCPARM paParms[])
d1c36fd86d36726777e3d6f9d040573e0aaf30devboxsync /* Message priority is taken into account. */
d1c36fd86d36726777e3d6f9d040573e0aaf30devboxsync VBoxHGCMParmUInt32Set (&paParms[0], VBOX_SHARED_CLIPBOARD_HOST_MSG_QUIT);
d1c36fd86d36726777e3d6f9d040573e0aaf30devboxsync LogFlow(("vboxSvcClipboardReturnMsg: ReadData %02X\n", pClient->u32RequestedFormat));
d1c36fd86d36726777e3d6f9d040573e0aaf30devboxsync VBoxHGCMParmUInt32Set (&paParms[0], VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA);
d1c36fd86d36726777e3d6f9d040573e0aaf30devboxsync VBoxHGCMParmUInt32Set (&paParms[1], pClient->u32RequestedFormat);
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync LogFlow(("vboxSvcClipboardReturnMsg: Formats %02X\n", pClient->u32AvailableFormats));
e2a73964f463b9e91f6f096f9e15974a3edcc416vboxsync VBoxHGCMParmUInt32Set (&paParms[0], VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS);
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync VBoxHGCMParmUInt32Set (&paParms[1], pClient->u32AvailableFormats);
d1c36fd86d36726777e3d6f9d040573e0aaf30devboxsync /* No pending messages. */
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync LogFlow(("vboxSvcClipboardReturnMsg: no message\n"));
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync return false;
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync /* Message information assigned. */
d1c36fd86d36726777e3d6f9d040573e0aaf30devboxsync return true;
d1c36fd86d36726777e3d6f9d040573e0aaf30devboxsyncvoid vboxSvcClipboardReportMsg (VBOXCLIPBOARDCLIENTDATA *pClient, uint32_t u32Msg, uint32_t u32Formats)
d1c36fd86d36726777e3d6f9d040573e0aaf30devboxsync if ( vboxSvcClipboardMode () != VBOX_SHARED_CLIPBOARD_MODE_GUEST_TO_HOST
d1c36fd86d36726777e3d6f9d040573e0aaf30devboxsync && vboxSvcClipboardMode () != VBOX_SHARED_CLIPBOARD_MODE_BIDIRECTIONAL)
d1c36fd86d36726777e3d6f9d040573e0aaf30devboxsync /* Skip the message. */
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync LogFlow(("vboxSvcClipboardReportMsg: ReadData %02X\n", u32Formats));
e2a73964f463b9e91f6f096f9e15974a3edcc416vboxsync if ( vboxSvcClipboardMode () != VBOX_SHARED_CLIPBOARD_MODE_HOST_TO_GUEST
e2a73964f463b9e91f6f096f9e15974a3edcc416vboxsync && vboxSvcClipboardMode () != VBOX_SHARED_CLIPBOARD_MODE_BIDIRECTIONAL)
e2a73964f463b9e91f6f096f9e15974a3edcc416vboxsync /* Skip the message. */
e2a73964f463b9e91f6f096f9e15974a3edcc416vboxsync LogFlow(("vboxSvcClipboardReportMsg: Formats %02X\n", u32Formats));
0612e2adbcc146b9eb7748983c720e35e38d0dc9vboxsync /* Invalid message. */
0612e2adbcc146b9eb7748983c720e35e38d0dc9vboxsync LogFlow(("vboxSvcClipboardReportMsg: invalid message %d\n", u32Msg));
0612e2adbcc146b9eb7748983c720e35e38d0dc9vboxsync /* The client waits for a responce. */
0612e2adbcc146b9eb7748983c720e35e38d0dc9vboxsync bool fMessageReturned = vboxSvcClipboardReturnMsg (pClient, pClient->async.paParms);
e2a73964f463b9e91f6f096f9e15974a3edcc416vboxsync /* Make a copy of the handle. */
e2a73964f463b9e91f6f096f9e15974a3edcc416vboxsync VBOXHGCMCALLHANDLE callHandle = pClient->async.callHandle;
e2a73964f463b9e91f6f096f9e15974a3edcc416vboxsync /* There is a responce. */
0612e2adbcc146b9eb7748983c720e35e38d0dc9vboxsync LogFlow(("vboxSvcClipboardReportMsg: CallComplete\n"));
0612e2adbcc146b9eb7748983c720e35e38d0dc9vboxsync g_pHelpers->pfnCallComplete (callHandle, VINF_SUCCESS);
39c2eccedfdb7455c52225543c355e33a65f0c81vboxsyncstatic int svcInit (void)
d8dee9a7ef33d4c705d5fd087d5af9c7cb071f85vboxsync vboxSvcClipboardModeSet (VBOX_SHARED_CLIPBOARD_MODE_OFF);
39c2eccedfdb7455c52225543c355e33a65f0c81vboxsync /* Clean up on failure, because 'svnUnload' will not be called
39c2eccedfdb7455c52225543c355e33a65f0c81vboxsync * if the 'svcInit' returns an error.
d8dee9a7ef33d4c705d5fd087d5af9c7cb071f85vboxsync * Disconnect the host side of the shared clipboard and send a "host disconnected" message
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync * to the guest side.
d8dee9a7ef33d4c705d5fd087d5af9c7cb071f85vboxsyncstatic DECLCALLBACK(int) svcDisconnect (void *, uint32_t u32ClientID, void *pvClient)
d8dee9a7ef33d4c705d5fd087d5af9c7cb071f85vboxsync VBOXCLIPBOARDCLIENTDATA *pClient = (VBOXCLIPBOARDCLIENTDATA *)pvClient;
d8dee9a7ef33d4c705d5fd087d5af9c7cb071f85vboxsync vboxSvcClipboardReportMsg (pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_QUIT, 0);
d8dee9a7ef33d4c705d5fd087d5af9c7cb071f85vboxsyncstatic DECLCALLBACK(int) svcConnect (void *, uint32_t u32ClientID, void *pvClient)
d8dee9a7ef33d4c705d5fd087d5af9c7cb071f85vboxsync VBOXCLIPBOARDCLIENTDATA *pClient = (VBOXCLIPBOARDCLIENTDATA *)pvClient;
84f746c9015f34e9ab096b87e063d0d6ab7fc7aevboxsync /* If there is already a client connected then we want to release it first. */
return rc;
void *pvClient,
bool fAsynchronousProcessing = false;
#ifdef DEBUG
uint32_t i;
for (i = 0; i < cParms; i++)
switch (u32Function)
if (vboxSvcClipboardLock ())
if (fMessageReturned)
fAsynchronousProcessing = true;
if (g_pfnExtension)
void *pv;
if (g_pfnExtension)
g_fReadingData = true;
LogFlow(("DATA: g_fDelayedAnnouncement = %d, g_u32DelayedFormats = 0x%x\n", g_fDelayedAnnouncement, g_u32DelayedFormats));
g_fDelayedAnnouncement = false;
g_u32DelayedFormats = 0;
g_fReadingData = false;
void *pv;
if (g_pfnExtension)
if (!fAsynchronousProcessing)
switch (u32Function)
return rc;
static DECLCALLBACK(int) svcSaveState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM)
g_pHelpers->pfnCallComplete (pClient->async.callHandle, VINF_SUCCESS /* error code is not important here. */);
return VINF_SUCCESS;
static DECLCALLBACK(int) svcLoadState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM)
return VINF_SUCCESS;
static DECLCALLBACK(int) extCallback (uint32_t u32Function, uint32_t u32Format, void *pvData, uint32_t cbData)
switch (u32Function)
if (g_fReadingData)
g_fDelayedAnnouncement = true;
return VERR_NOT_SUPPORTED;
return VINF_SUCCESS;
static DECLCALLBACK(int) svcRegisterExtension(void *, PFNHGCMSVCEXT pfnExtension, void *pvExtension)
if (pfnExtension)
if (g_pfnExtension)
return VINF_SUCCESS;
if (!ptable)
Log(("VBoxHGCMSvcLoad: ptable->cbSize = %d, ptable->u32Version = 0x%08X\n", ptable->cbSize, ptable->u32Version));
return rc;