VBoxClipboard.cpp revision e62cb87bae732e9968199a3ad153cc94004b7182
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync/** @file
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync *
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync * VBoxClipboard - Shared clipboard
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync *
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync/*
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync *
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync * available from http://www.virtualbox.org. This file is free software;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync * you can redistribute it and/or modify it under the terms of the GNU
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync * General Public License (GPL) as published by the Free Software
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync *
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync * additional information or have any questions.
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync#include "VBoxTray.h"
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync#include <VBox/HostServices/VBoxClipboardSvc.h>
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync#include "helpers.h"
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync#include <iprt/asm.h>
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsynctypedef struct _VBOXCLIPBOARDCONTEXT
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync{
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync const VBOXSERVICEENV *pEnv;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync uint32_t u32ClientID;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync ATOM atomWindowClass;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync HWND hwnd;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync HWND hwndNextInChain;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync// bool fOperational;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync// uint32_t u32LastSentFormat;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync// uint64_t u64LastSentCRC64;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync} VBOXCLIPBOARDCONTEXT;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsyncstatic char gachWindowClassName[] = "VBoxSharedClipboardClass";
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync#define VBOX_INIT_CALL(__a, __b, __c) do { \
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync (__a)->hdr.result = VINF_SUCCESS; \
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync (__a)->hdr.u32ClientID = (__c)->u32ClientID; \
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync (__a)->hdr.u32Function = (__b); \
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync (__a)->hdr.cParms = (sizeof (*(__a)) - sizeof ((__a)->hdr)) / sizeof (HGCMFunctionParameter); \
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync} while (0)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync//static bool vboxClipboardIsSameAsLastSent (VBOXCLIPBOARDCONTEXT *pCtx, uint32_t u32Format,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync// void *pv, uint32_t cb)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync//{
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync// uint64_t u64CRC = RTCrc64 (pv, cb);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync//
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync// if ( pCtx->u32LastSentFormat == u32Format
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync// && pCtx->u64LastSentCRC64 == u64CRC)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync// {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync// return true;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync// }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync//
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync// pCtx->u64LastSentCRC64 = u64CRC;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync// pCtx->u32LastSentFormat = u32Format;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync//
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync// return false;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync//}
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsyncstatic int vboxClipboardConnect (VBOXCLIPBOARDCONTEXT *pCtx)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync{
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync VBoxGuestHGCMConnectInfo info;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync memset (&info, 0, sizeof (info));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync info.Loc.type = VMMDevHGCMLoc_LocalHost_Existing;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync strcpy (info.Loc.u.host.achName, "VBoxSharedClipboard");
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync DWORD cbReturned;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (DeviceIoControl (pCtx->pEnv->hDriver,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync IOCTL_VBOXGUEST_HGCM_CONNECT,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync &info, sizeof (info),
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync &info, sizeof (info),
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync &cbReturned,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync NULL))
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (info.result == VINF_SUCCESS)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync pCtx->u32ClientID = info.u32ClientID;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync else
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync info.result = VERR_NOT_SUPPORTED;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync return info.result;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync}
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsyncstatic void vboxClipboardDisconnect (VBOXCLIPBOARDCONTEXT *pCtx)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync{
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (pCtx->u32ClientID == 0)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync return;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync VBoxGuestHGCMDisconnectInfo info;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync memset (&info, 0, sizeof (info));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync info.u32ClientID = pCtx->u32ClientID;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync DWORD cbReturned;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync DeviceIoControl (pCtx->pEnv->hDriver,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync IOCTL_VBOXGUEST_HGCM_DISCONNECT,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync &info, sizeof (info),
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync &info, sizeof (info),
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync &cbReturned,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync NULL);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync return;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync}
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsyncstatic void VBoxHGCMParmUInt32Set (HGCMFunctionParameter *pParm, uint32_t u32)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync{
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync pParm->type = VMMDevHGCMParmType_32bit;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync pParm->u.value32 = u32;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync}
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsyncstatic int VBoxHGCMParmUInt32Get (HGCMFunctionParameter *pParm, uint32_t *pu32)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync{
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (pParm->type == VMMDevHGCMParmType_32bit)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync *pu32 = pParm->u.value32;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync return VINF_SUCCESS;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync return VERR_INVALID_PARAMETER;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync}
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsyncstatic void VBoxHGCMParmPtrSet (HGCMFunctionParameter *pParm, void *pv, uint32_t cb)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync{
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync pParm->type = VMMDevHGCMParmType_LinAddr;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync pParm->u.Pointer.size = cb;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync pParm->u.Pointer.u.linearAddr = (RTGCPTR)pv;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync}
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsyncstatic int vboxCall (HANDLE hDriver, void *pvData, unsigned cbData)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync{
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync DWORD cbReturned;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (DeviceIoControl (hDriver,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync IOCTL_VBOXGUEST_HGCM_CALL,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync pvData, cbData,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync pvData, cbData,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync &cbReturned,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync NULL))
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync return VINF_SUCCESS;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync return VERR_NOT_SUPPORTED;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync}
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsyncstatic int vboxClipboardReportFormats (VBOXCLIPBOARDCONTEXT *pCtx, uint32_t u32Formats)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync{
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync VBoxClipboardFormats parms;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync VBOX_INIT_CALL(&parms, VBOX_SHARED_CLIPBOARD_FN_FORMATS, pCtx);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync VBoxHGCMParmUInt32Set (&parms.formats, u32Formats);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync int rc = vboxCall (pCtx->pEnv->hDriver, &parms, sizeof (parms));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (VBOX_SUCCESS (rc))
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync rc = parms.hdr.result;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync return rc;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync}
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsyncstatic int vboxClipboardReadData (VBOXCLIPBOARDCONTEXT *pCtx, uint32_t u32Format, void *pv, uint32_t cb, uint32_t *pcbActual)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync{
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync VBoxClipboardReadData parms;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync VBOX_INIT_CALL(&parms, VBOX_SHARED_CLIPBOARD_FN_READ_DATA, pCtx);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync VBoxHGCMParmUInt32Set (&parms.format, u32Format);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync VBoxHGCMParmPtrSet (&parms.ptr, pv, cb);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync VBoxHGCMParmUInt32Set (&parms.size, 0);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync int rc = vboxCall (pCtx->pEnv->hDriver, &parms, sizeof (parms));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (VBOX_SUCCESS (rc))
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync rc = parms.hdr.result;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (VBOX_SUCCESS (rc))
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync uint32_t u32Size;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync rc = VBoxHGCMParmUInt32Get (&parms.size, &u32Size);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync dprintf (("vboxClipboardReadData: actual size = %d, rc = %d\n", u32Size, rc));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (VBOX_SUCCESS (rc))
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (pcbActual)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync *pcbActual = u32Size;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync return rc;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync}
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsyncstatic int vboxClipboardWriteData (VBOXCLIPBOARDCONTEXT *pCtx, uint32_t u32Format,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync void *pv, uint32_t cb)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync{
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync// if (vboxClipboardIsSameAsLastSent (pCtx, u32Format, pv, cb))
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync// {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync// dprintf (("vboxClipboardWriteData: The data to be sent are the same as the last sent.\n"));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync// return VINF_SUCCESS;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync// }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync VBoxClipboardWriteData parms;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync VBOX_INIT_CALL(&parms, VBOX_SHARED_CLIPBOARD_FN_WRITE_DATA, pCtx);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync VBoxHGCMParmUInt32Set (&parms.format, u32Format);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync VBoxHGCMParmPtrSet (&parms.ptr, pv, cb);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync int rc = vboxCall (pCtx->pEnv->hDriver, &parms, sizeof (parms));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (VBOX_SUCCESS (rc))
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync rc = parms.hdr.result;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync return rc;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync}
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsyncstatic void vboxClipboardChanged (VBOXCLIPBOARDCONTEXT *pCtx)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync{
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* Query list of available formats and report to host. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (OpenClipboard (pCtx->hwnd))
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync uint32_t u32Formats = 0;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync UINT format = 0;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync while ((format = EnumClipboardFormats (format)) != 0)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync dprintf (("vboxClipboardChanged: format 0x%08X\n", format));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync switch (format)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync case CF_UNICODETEXT:
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync case CF_TEXT:
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync u32Formats |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync case CF_DIB:
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync case CF_BITMAP:
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync u32Formats |= VBOX_SHARED_CLIPBOARD_FMT_BITMAP;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync default:
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (format >= 0xC000)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync TCHAR szFormatName[256];
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync int cActual = GetClipboardFormatName(format, szFormatName, sizeof(szFormatName)/sizeof (TCHAR));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (cActual)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (strcmp (szFormatName, "HTML Format") == 0)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync u32Formats |= VBOX_SHARED_CLIPBOARD_FMT_HTML;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync CloseClipboard ();
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync vboxClipboardReportFormats (pCtx, u32Formats);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync}
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsyncstatic LRESULT vboxClipboardProcessMsg(VBOXCLIPBOARDCONTEXT *pCtx, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync{
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync LRESULT rc = 0;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync switch (msg)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync case WM_CHANGECBCHAIN:
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync HWND hwndRemoved = (HWND)wParam;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync HWND hwndNext = (HWND)lParam;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync dprintf (("vboxClipboardProcessMsg: WM_CHANGECBCHAIN: hwndRemoved %p, hwndNext %p, hwnd %p\n", hwndRemoved, hwndNext, pCtx->hwnd));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (hwndRemoved == pCtx->hwndNextInChain)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* The window that was next to our in the chain is being removed.
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync * Relink to the new next window.
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync pCtx->hwndNextInChain = hwndNext;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync else
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (pCtx->hwndNextInChain)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* Pass the message further. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync rc = SendMessage (pCtx->hwndNextInChain, WM_CHANGECBCHAIN, wParam, lParam);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync } break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync case WM_DRAWCLIPBOARD:
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync dprintf (("vboxClipboardProcessMsg: WM_DRAWCLIPBOARD, hwnd %p\n", pCtx->hwnd));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (GetClipboardOwner () != hwnd)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* Clipboard was updated by another application. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync vboxClipboardChanged (pCtx);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* Pass the message to next windows in the clipboard chain. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync rc = SendMessage (pCtx->hwndNextInChain, msg, wParam, lParam);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync } break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync case WM_CLOSE:
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* Do nothing. Ignore the message. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync } break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync case WM_RENDERFORMAT:
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* Insert the requested clipboard format data into the clipboard. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync uint32_t u32Format = 0;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync UINT format = (UINT)wParam;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync dprintf (("vboxClipboardProcessMsg: WM_RENDERFORMAT, format %x\n", format));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync switch (format)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync case CF_UNICODETEXT:
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync u32Format |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync case CF_DIB:
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync u32Format |= VBOX_SHARED_CLIPBOARD_FMT_BITMAP;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync default:
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (format >= 0xC000)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync TCHAR szFormatName[256];
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync int cActual = GetClipboardFormatName(format, szFormatName, sizeof(szFormatName)/sizeof (TCHAR));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (cActual)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (strcmp (szFormatName, "HTML Format") == 0)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync u32Format |= VBOX_SHARED_CLIPBOARD_FMT_HTML;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (u32Format == 0)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* Unsupported clipboard format is requested. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync EmptyClipboard ();
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync else
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync const uint32_t cbPrealloc = 4096;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync uint32_t cb = 0;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* Preallocate a buffer, most of small text transfers will fit into it. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync HANDLE hMem = GlobalAlloc (GMEM_DDESHARE | GMEM_MOVEABLE, cbPrealloc);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync dprintf(("hMem %p\n", hMem));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (hMem)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync void *pMem = GlobalLock (hMem);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync dprintf(("pMem %p, GlobalSize %d\n", pMem, GlobalSize (hMem)));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (pMem)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* Read the host data to the preallocated buffer. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync int vboxrc = vboxClipboardReadData (pCtx, u32Format, pMem, cbPrealloc, &cb);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync dprintf(("vboxClipboardReadData vboxrc %d\n", vboxrc));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (VBOX_SUCCESS (rc))
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (cb > cbPrealloc)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync GlobalUnlock (hMem);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* The preallocated buffer is too small, adjust the size. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync hMem = GlobalReAlloc (hMem, cb, 0);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync dprintf(("hMem %p\n", hMem));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (hMem)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync pMem = GlobalLock (hMem);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync dprintf(("pMem %p, GlobalSize %d\n", pMem, GlobalSize (hMem)));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (pMem)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* Read the host data to the preallocated buffer. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync uint32_t cbNew = 0;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync vboxrc = vboxClipboardReadData (pCtx, u32Format, pMem, cb, &cbNew);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync dprintf(("vboxClipboardReadData vboxrc %d, cb = %d, cbNew = %d\n", vboxrc, cb, cbNew));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (VBOX_SUCCESS (vboxrc) && cbNew <= cb)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync cb = cbNew;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync else
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync GlobalUnlock (pMem);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync GlobalFree (hMem);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync hMem = NULL;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync else
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync GlobalFree (hMem);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync hMem = NULL;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (hMem)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* pMem is the address of the data. cb is the size of returned data. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* Verify the size of returned text. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (u32Format == VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync cb = (lstrlenW((LPWSTR)pMem) + 1) * 2;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync GlobalUnlock (hMem);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync hMem = GlobalReAlloc (hMem, cb, 0);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync dprintf(("hMem %p\n", hMem));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (hMem)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* 'hMem' contains the host clipboard data.
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync * size is 'cb' and format is 'format'.
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync HANDLE hClip = SetClipboardData (format, hMem);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync dprintf(("WM_RENDERFORMAT hClip %p\n", hClip));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (hClip)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* The hMem ownership has gone to the system. Finish the processing. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* Cleanup follows. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (hMem)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync GlobalUnlock (hMem);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (hMem)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync GlobalFree (hMem);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* Something went wrong. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync EmptyClipboard ();
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync } break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync case WM_RENDERALLFORMATS:
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* Do nothing. The clipboard formats will be unavailable now, because the
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync * windows is to be destroyed and therefore the guest side becomes inactive.
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (OpenClipboard (hwnd))
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync EmptyClipboard();
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync CloseClipboard();
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync } break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync case WM_USER:
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* Announce available formats. Do not insert data, they will be inserted in WM_RENDER*. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync uint32_t u32Formats = (uint32_t)lParam;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (OpenClipboard (hwnd))
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync EmptyClipboard();
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync HANDLE hClip = NULL;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync dprintf(("window proc WM_USER: VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT\n"));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync hClip = SetClipboardData (CF_UNICODETEXT, NULL);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync dprintf(("window proc WM_USER: VBOX_SHARED_CLIPBOARD_FMT_BITMAP\n"));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync hClip = SetClipboardData (CF_DIB, NULL);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_HTML)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync UINT format = RegisterClipboardFormat ("HTML Format");
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync dprintf(("window proc WM_USER: VBOX_SHARED_CLIPBOARD_FMT_HTML 0x%04X\n", format));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (format != 0)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync hClip = SetClipboardData (format, NULL);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync CloseClipboard();
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync dprintf(("window proc WM_USER: hClip %p, err %d\n", hClip, GetLastError ()));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync else
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync dprintf(("window proc WM_USER: failed to open clipboard\n"));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync } break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync case WM_USER + 1:
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* Send data in the specified format to the host. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync uint32_t u32Formats = (uint32_t)lParam;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync HANDLE hClip = NULL;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (OpenClipboard (hwnd))
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync hClip = GetClipboardData (CF_DIB);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (hClip != NULL)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync LPVOID lp = GlobalLock (hClip);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (lp != NULL)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync dprintf(("CF_DIB\n"));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync vboxClipboardWriteData (pCtx, VBOX_SHARED_CLIPBOARD_FMT_BITMAP,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync lp, GlobalSize (hClip));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync GlobalUnlock(hClip);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync else
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync hClip = NULL;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync hClip = GetClipboardData(CF_UNICODETEXT);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (hClip != NULL)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync LPWSTR uniString = (LPWSTR)GlobalLock (hClip);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (uniString != NULL)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync dprintf(("CF_UNICODETEXT\n"));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync vboxClipboardWriteData (pCtx, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync uniString, (lstrlenW (uniString) + 1) * 2);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync GlobalUnlock(hClip);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync else
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync hClip = NULL;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_HTML)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync UINT format = RegisterClipboardFormat ("HTML Format");
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (format != 0)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync hClip = GetClipboardData (format);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (hClip != NULL)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync LPVOID lp = GlobalLock (hClip);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (lp != NULL)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync dprintf(("CF_HTML\n"));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync vboxClipboardWriteData (pCtx, VBOX_SHARED_CLIPBOARD_FMT_HTML,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync lp, GlobalSize (hClip));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync GlobalUnlock(hClip);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync else
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync hClip = NULL;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync CloseClipboard ();
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (hClip == NULL)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* Requested clipboard format is not available, send empty data. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync vboxClipboardWriteData (pCtx, 0, NULL, 0);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync } break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync default:
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync rc = DefWindowProc (hwnd, msg, wParam, lParam);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync return rc;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync}
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsyncstatic LRESULT CALLBACK vboxClipboardWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsyncstatic int vboxClipboardInit (VBOXCLIPBOARDCONTEXT *pCtx)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync{
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync int rc = VINF_SUCCESS;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* Register the Window Class. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync WNDCLASS wc;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync wc.style = CS_NOCLOSE;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync wc.lpfnWndProc = vboxClipboardWndProc;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync wc.cbClsExtra = 0;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync wc.cbWndExtra = 0;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync wc.hInstance = pCtx->pEnv->hInstance;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync wc.hIcon = NULL;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync wc.hCursor = NULL;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync wc.lpszMenuName = NULL;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync wc.lpszClassName = gachWindowClassName;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync pCtx->atomWindowClass = RegisterClass (&wc);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (pCtx->atomWindowClass == 0)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync rc = VERR_NOT_SUPPORTED;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync else
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* Create the window. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync pCtx->hwnd = CreateWindowEx (WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_TOPMOST,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync gachWindowClassName, gachWindowClassName,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync WS_POPUPWINDOW,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync -200, -200, 100, 100, NULL, NULL, pCtx->pEnv->hInstance, NULL);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (pCtx->hwnd == NULL)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync rc = VERR_NOT_SUPPORTED;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync else
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync SetWindowPos(pCtx->hwnd, HWND_TOPMOST, -200, -200, 0, 0,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync SWP_NOACTIVATE | SWP_HIDEWINDOW | SWP_NOCOPYBITS | SWP_NOREDRAW | SWP_NOSIZE);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync pCtx->hwndNextInChain = SetClipboardViewer (pCtx->hwnd);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync return rc;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync}
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsyncstatic void vboxClipboardDestroy (VBOXCLIPBOARDCONTEXT *pCtx)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync{
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (pCtx->hwnd)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync ChangeClipboardChain (pCtx->hwnd, pCtx->hwndNextInChain);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync pCtx->hwndNextInChain = NULL;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync DestroyWindow (pCtx->hwnd);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync pCtx->hwnd = NULL;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (pCtx->atomWindowClass != 0)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync UnregisterClass(gachWindowClassName, pCtx->pEnv->hInstance);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync pCtx->atomWindowClass = 0;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync}
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync/* Static since it is the single instance. Directly used in the windows proc. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsyncstatic VBOXCLIPBOARDCONTEXT gCtx = { NULL };
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsyncstatic LRESULT CALLBACK vboxClipboardWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync{
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* Forward with proper context. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync return vboxClipboardProcessMsg (&gCtx, hwnd, msg, wParam, lParam);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync}
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsyncint VBoxClipboardInit (const VBOXSERVICEENV *pEnv, void **ppInstance, bool *pfStartThread)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync{
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync int rc = VINF_SUCCESS;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync dprintf (("VboxClipboardInit\n"));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (gCtx.pEnv)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* Clipboard was already initialized. 2 or more instances are not supported. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync return VERR_NOT_SUPPORTED;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync memset (&gCtx, 0, sizeof (gCtx));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync gCtx.pEnv = pEnv;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync rc = vboxClipboardConnect (&gCtx);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (VBOX_SUCCESS (rc))
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync rc = vboxClipboardInit (&gCtx);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync dprintf (("vboxClipboardInit: rc = %d\n", rc));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (VBOX_SUCCESS (rc))
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* Always start the thread for host messages. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync *pfStartThread = true;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (VBOX_SUCCESS (rc))
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync *ppInstance = &gCtx;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync else
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync vboxClipboardDisconnect (&gCtx);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync return rc;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync}
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsyncunsigned __stdcall VBoxClipboardThread (void *pInstance)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync{
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync VBOXCLIPBOARDCONTEXT *pCtx = (VBOXCLIPBOARDCONTEXT *)pInstance;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync dprintf(("VBoxClipboardThread\n"));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* Open the new driver instance to not interfere with other callers. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync HANDLE hDriver = CreateFile(VBOXGUEST_DEVICE_NAME,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync GENERIC_READ | GENERIC_WRITE,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync FILE_SHARE_READ | FILE_SHARE_WRITE,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync NULL,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync OPEN_EXISTING,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync FILE_ATTRIBUTE_NORMAL,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync NULL);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* The thread waits for incoming messages from the host. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync for (;;)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync VBoxClipboardGetHostMsg parms;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync VBOX_INIT_CALL(&parms, VBOX_SHARED_CLIPBOARD_FN_GET_HOST_MSG, pCtx);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync VBoxHGCMParmUInt32Set (&parms.msg, 0);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync VBoxHGCMParmUInt32Set (&parms.formats, 0);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync DWORD cbReturned;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (!DeviceIoControl (hDriver,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync IOCTL_VBOXGUEST_HGCM_CALL,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync &parms, sizeof (parms),
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync &parms, sizeof (parms),
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync &cbReturned,
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync NULL))
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync dprintf(("Failed to call the driver for host message.\n"));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* Wait a bit before retrying. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 1000) == WAIT_OBJECT_0)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync continue;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync int rc = parms.hdr.result;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (VBOX_SUCCESS (rc))
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync uint32_t u32Msg;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync uint32_t u32Formats;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync rc = VBoxHGCMParmUInt32Get (&parms.msg, &u32Msg);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (VBOX_SUCCESS (rc))
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync rc = VBoxHGCMParmUInt32Get (&parms.formats, &u32Formats);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (VBOX_SUCCESS (rc))
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync dprintf(("vboxClipboardHostEvent u32Msg %d, u32Formats %d\n", u32Msg, u32Formats));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync switch (u32Msg)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync case VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS:
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* The host has announced available clipboard formats.
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync * Forward the information to the window, so it can later
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync * respond to WM_RENDERFORMAT message.
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync ::PostMessage (pCtx->hwnd, WM_USER, 0, u32Formats);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync } break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync case VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA:
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* The host needs data in the specified format.
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync ::PostMessage (pCtx->hwnd, WM_USER + 1, 0, u32Formats);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync } break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync case VBOX_SHARED_CLIPBOARD_HOST_MSG_QUIT:
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* The host is terminating.
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync rc = VERR_INTERRUPTED;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync } break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync default:
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync dprintf(("Unsupported message from host!!!"));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (rc == VERR_INTERRUPTED)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* Wait for termination event. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync WaitForSingleObject(pCtx->pEnv->hStopEvent, INFINITE);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (VBOX_FAILURE (rc))
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync /* Wait a bit before retrying. */
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 1000) == WAIT_OBJECT_0)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync break;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync continue;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync dprintf(("processed host event rc = %d\n", rc));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync CloseHandle (hDriver);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync return 0;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync}
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsyncvoid VBoxClipboardDestroy (const VBOXSERVICEENV *pEnv, void *pInstance)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync{
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync VBOXCLIPBOARDCONTEXT *pCtx = (VBOXCLIPBOARDCONTEXT *)pInstance;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync if (pCtx != &gCtx)
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync {
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync dprintf(("VBoxClipboardDestroy: invalid instance %p (our %p)!!!\n", pCtx, &gCtx));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync pCtx = &gCtx;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync }
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync vboxClipboardDestroy (pCtx);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync vboxClipboardDisconnect (pCtx);
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync memset (pCtx, 0, sizeof (*pCtx));
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync return;
e62cb87bae732e9968199a3ad153cc94004b7182vboxsync}