VirtualBox

source: vbox/trunk/include/VBox/GuestHost/SharedClipboard-win.h@ 79267

Last change on this file since 79267 was 79267, checked in by vboxsync, 6 years ago

Shared Clipboard/URI: Update.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.6 KB
Line 
1/** @file
2 * Shared Clipboard - Common Guest and Host Code, for Windows OSes.
3 */
4
5/*
6 * Copyright (C) 2006-2019 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef VBOX_INCLUDED_GuestHost_SharedClipboard_win_h
27#define VBOX_INCLUDED_GuestHost_SharedClipboard_win_h
28#ifndef RT_WITHOUT_PRAGMA_ONCE
29# pragma once
30#endif
31
32#include <iprt/types.h>
33#include <iprt/win/windows.h>
34
35#include <VBox/GuestHost/SharedClipboard.h>
36
37# ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
38# include <iprt/cpp/ministring.h> /* For RTCString. */
39# include <iprt/win/shlobj.h> /* For DROPFILES and friends. */
40# include <oleidl.h>
41
42# include <VBox/GuestHost/SharedClipboard-uri.h>
43# endif
44
45#ifndef WM_CLIPBOARDUPDATE
46# define WM_CLIPBOARDUPDATE 0x031D
47#endif
48
49#define VBOX_CLIPBOARD_WNDCLASS_NAME "VBoxSharedClipboardClass"
50
51/** See: https://docs.microsoft.com/en-us/windows/desktop/dataxchg/html-clipboard-format
52 * Do *not* change the name, as this will break compatbility with other (legacy) applications! */
53#define VBOX_CLIPBOARD_WIN_REGFMT_HTML "HTML Format"
54
55/** Default timeout (in ms) for passing down messages down the clipboard chain. */
56#define VBOX_CLIPBOARD_CBCHAIN_TIMEOUT_MS 5000
57
58/** Sets announced clipboard formats from the host. */
59#define VBOX_CLIPBOARD_WM_SET_FORMATS WM_USER
60/** Reads data from the clipboard and sends it to the host. */
61#define VBOX_CLIPBOARD_WM_READ_DATA WM_USER + 1
62
63/* Dynamically load clipboard functions from User32.dll. */
64typedef BOOL WINAPI FNADDCLIPBOARDFORMATLISTENER(HWND);
65typedef FNADDCLIPBOARDFORMATLISTENER *PFNADDCLIPBOARDFORMATLISTENER;
66
67typedef BOOL WINAPI FNREMOVECLIPBOARDFORMATLISTENER(HWND);
68typedef FNREMOVECLIPBOARDFORMATLISTENER *PFNREMOVECLIPBOARDFORMATLISTENER;
69
70/**
71 * Structure for keeping function pointers for the new clipboard API.
72 * If the new API is not available, those function pointer are NULL.
73 */
74typedef struct _VBOXCLIPBOARDWINAPINEW
75{
76 PFNADDCLIPBOARDFORMATLISTENER pfnAddClipboardFormatListener;
77 PFNREMOVECLIPBOARDFORMATLISTENER pfnRemoveClipboardFormatListener;
78} VBOXCLIPBOARDWINAPINEW, *PVBOXCLIPBOARDWINAPINEW;
79
80/**
81 * Structure for keeping variables which are needed to drive the old clipboard API.
82 */
83typedef struct _VBOXCLIPBOARDWINAPIOLD
84{
85 /** Timer ID for the refresh timer. */
86 UINT timerRefresh;
87 /** Whether "pinging" the clipboard chain currently is in progress or not. */
88 bool fCBChainPingInProcess;
89} VBOXCLIPBOARDWINAPIOLD, *PVBOXCLIPBOARDWINAPIOLD;
90
91/**
92 * Structure for maintaining a Shared Clipboard context on Windows platforms.
93 */
94typedef struct _VBOXCLIPBOARDWINCTX
95{
96 /** Window handle of our (invisible) clipbaord window. */
97 HWND hWnd;
98 /** Window handle which is next to us in the clipboard chain. */
99 HWND hWndNextInChain;
100 /** Window handle of the clipboard owner *if* we are the owner. */
101 HWND hWndClipboardOwnerUs;
102 /** Structure for maintaining the new clipboard API. */
103 VBOXCLIPBOARDWINAPINEW newAPI;
104 /** Structure for maintaining the old clipboard API. */
105 VBOXCLIPBOARDWINAPIOLD oldAPI;
106} VBOXCLIPBOARDWINCTX, *PVBOXCLIPBOARDWINCTX;
107
108int VBoxClipboardWinOpen(HWND hWnd);
109int VBoxClipboardWinClose(void);
110int VBoxClipboardWinClear(void);
111
112int VBoxClipboardWinCheckAndInitNewAPI(PVBOXCLIPBOARDWINAPINEW pAPI);
113bool VBoxClipboardWinIsNewAPI(PVBOXCLIPBOARDWINAPINEW pAPI);
114
115int VBoxClipboardWinChainAdd(PVBOXCLIPBOARDWINCTX pCtx);
116int VBoxClipboardWinChainRemove(PVBOXCLIPBOARDWINCTX pCtx);
117VOID CALLBACK VBoxClipboardWinChainPingProc(HWND hWnd, UINT uMsg, ULONG_PTR dwData, LRESULT lResult);
118LRESULT VBoxClipboardWinChainPassToNext(PVBOXCLIPBOARDWINCTX pWinCtx, UINT msg, WPARAM wParam, LPARAM lParam);
119
120VBOXCLIPBOARDFORMAT VBoxClipboardWinClipboardFormatToVBox(UINT uFormat);
121int VBoxClipboardWinGetFormats(PVBOXCLIPBOARDWINCTX pCtx, PVBOXCLIPBOARDFORMAT pfFormats);
122
123#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
124int VBoxClipboardWinDropFilesToTransfer(DROPFILES *pDropFiles, PSHAREDCLIPBOARDURITRANSFER pTransfer);
125#endif
126
127int VBoxClipboardWinGetCFHTMLHeaderValue(const char *pszSrc, const char *pszOption, uint32_t *puValue);
128bool VBoxClipboardWinIsCFHTML(const char *pszSource);
129int VBoxClipboardWinConvertCFHTMLToMIME(const char *pszSource, const uint32_t cch, char **ppszOutput, uint32_t *pcbOutput);
130int VBoxClipboardWinConvertMIMEToCFHTML(const char *pszSource, size_t cb, char **ppszOutput, uint32_t *pcbOutput);
131
132LRESULT VBoxClipboardWinHandleWMChangeCBChain(PVBOXCLIPBOARDWINCTX pWinCtx, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
133int VBoxClipboardWinHandleWMDestroy(PVBOXCLIPBOARDWINCTX pWinCtx);
134int VBoxClipboardWinHandleWMRenderAllFormats(PVBOXCLIPBOARDWINCTX pWinCtx, HWND hWnd);
135int VBoxClipboardWinHandleWMTimer(PVBOXCLIPBOARDWINCTX pWinCtx);
136
137int VBoxClipboardWinAnnounceFormats(PVBOXCLIPBOARDWINCTX pWinCtx, VBOXCLIPBOARDFORMATS fFormats);
138#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
139int VBoxClipboardWinURIAnnounce(PVBOXCLIPBOARDWINCTX pWinCtx, PSHAREDCLIPBOARDURICTX pURICtx,
140 PSHAREDCLIPBOARDURITRANSFER pTransfer);
141#endif
142
143# ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
144class SharedClipboardURIList;
145# ifndef FILEGROUPDESCRIPTOR
146class FILEGROUPDESCRIPTOR;
147# endif
148
149class VBoxClipboardWinDataObject : public IDataObject //, public IDataObjectAsyncCapability
150{
151public:
152
153 enum Status
154 {
155 Uninitialized = 0,
156 Initialized
157 };
158
159 enum FormatIndex
160 {
161 /** File descriptor, ANSI version. */
162 FormatIndex_FileDescriptorA = 0,
163 /** File descriptor, Unicode version. */
164 FormatIndex_FileDescriptorW,
165 /** File contents. */
166 FormatIndex_FileContents
167 };
168
169public:
170
171 VBoxClipboardWinDataObject(PSHAREDCLIPBOARDURITRANSFER pTransfer,
172 LPFORMATETC pFormatEtc = NULL, LPSTGMEDIUM pStgMed = NULL, ULONG cFormats = 0);
173 virtual ~VBoxClipboardWinDataObject(void);
174
175public: /* IUnknown methods. */
176
177 STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject);
178 STDMETHOD_(ULONG, AddRef)(void);
179 STDMETHOD_(ULONG, Release)(void);
180
181public: /* IDataObject methods. */
182
183 STDMETHOD(GetData)(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium);
184 STDMETHOD(GetDataHere)(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium);
185 STDMETHOD(QueryGetData)(LPFORMATETC pFormatEtc);
186 STDMETHOD(GetCanonicalFormatEtc)(LPFORMATETC pFormatEct, LPFORMATETC pFormatEtcOut);
187 STDMETHOD(SetData)(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium, BOOL fRelease);
188 STDMETHOD(EnumFormatEtc)(DWORD dwDirection, IEnumFORMATETC **ppEnumFormatEtc);
189 STDMETHOD(DAdvise)(LPFORMATETC pFormatEtc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection);
190 STDMETHOD(DUnadvise)(DWORD dwConnection);
191 STDMETHOD(EnumDAdvise)(IEnumSTATDATA **ppEnumAdvise);
192
193#ifdef VBOX_WITH_SHARED_CLIPBOARD_WIN_ASYNC
194public: /* IDataObjectAsyncCapability methods. */
195
196 STDMETHOD(EndOperation)(HRESULT hResult, IBindCtx* pbcReserved, DWORD dwEffects);
197 STDMETHOD(GetAsyncMode)(BOOL* pfIsOpAsync);
198 STDMETHOD(InOperation)(BOOL* pfInAsyncOp);
199 STDMETHOD(SetAsyncMode)(BOOL fDoOpAsync);
200 STDMETHOD(StartOperation)(IBindCtx* pbcReserved);
201#endif /* VBOX_WITH_SHARED_CLIPBOARD_WIN_ASYNC */
202
203public:
204
205 int Init(void);
206 void OnTransferComplete(int rc = VINF_SUCCESS);
207 void OnTransferCanceled();
208
209public:
210
211 static const char* ClipboardFormatToString(CLIPFORMAT fmt);
212
213protected:
214
215 static int Thread(RTTHREAD hThread, void *pvUser);
216
217 int copyToHGlobal(const void *pvData, size_t cbData, UINT fFlags, HGLOBAL *phGlobal);
218 int createFileGroupDescriptorFromURIList(const SharedClipboardURIList &URIList, bool fUnicode, HGLOBAL *phGlobal);
219
220 bool lookupFormatEtc(LPFORMATETC pFormatEtc, ULONG *puIndex);
221 void registerFormat(LPFORMATETC pFormatEtc, CLIPFORMAT clipFormat, TYMED tyMed = TYMED_HGLOBAL,
222 LONG lindex = -1, DWORD dwAspect = DVASPECT_CONTENT, DVTARGETDEVICE *pTargetDevice = NULL);
223
224protected:
225
226 Status m_enmStatus;
227 LONG m_lRefCount;
228 ULONG m_cFormats;
229 LPFORMATETC m_pFormatEtc;
230 LPSTGMEDIUM m_pStgMedium;
231 PSHAREDCLIPBOARDURITRANSFER m_pTransfer;
232 IStream *m_pStream;
233 ULONG m_uObjIdx;
234};
235
236class VBoxClipboardWinEnumFormatEtc : public IEnumFORMATETC
237{
238public:
239
240 VBoxClipboardWinEnumFormatEtc(LPFORMATETC pFormatEtc, ULONG cFormats);
241 virtual ~VBoxClipboardWinEnumFormatEtc(void);
242
243public: /* IUnknown methods. */
244
245 STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject);
246 STDMETHOD_(ULONG, AddRef)(void);
247 STDMETHOD_(ULONG, Release)(void);
248
249public: /* IEnumFORMATETC methods. */
250
251 STDMETHOD(Next)(ULONG cFormats, LPFORMATETC pFormatEtc, ULONG *pcFetched);
252 STDMETHOD(Skip)(ULONG cFormats);
253 STDMETHOD(Reset)(void);
254 STDMETHOD(Clone)(IEnumFORMATETC **ppEnumFormatEtc);
255
256public:
257
258 static void CopyFormat(LPFORMATETC pFormatDest, LPFORMATETC pFormatSource);
259 static HRESULT CreateEnumFormatEtc(UINT cFormats, LPFORMATETC pFormatEtc, IEnumFORMATETC **ppEnumFormatEtc);
260
261private:
262
263 LONG m_lRefCount;
264 ULONG m_nIndex;
265 ULONG m_nNumFormats;
266 LPFORMATETC m_pFormatEtc;
267};
268
269/**
270 * Own IStream implementation to implement file-based clipboard operations
271 * through HGCM. Needed on Windows hosts and guests.
272 */
273class VBoxClipboardWinStreamImpl : public IStream
274{
275public:
276
277 VBoxClipboardWinStreamImpl(VBoxClipboardWinDataObject *pParent,
278 PSHAREDCLIPBOARDURITRANSFER pTransfer, uint64_t uObjIdx);
279 virtual ~VBoxClipboardWinStreamImpl(void);
280
281public: /* IUnknown methods. */
282
283 STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject);
284 STDMETHOD_(ULONG, AddRef)(void);
285 STDMETHOD_(ULONG, Release)(void);
286
287public: /* IStream methods. */
288
289 STDMETHOD(Clone)(IStream** ppStream);
290 STDMETHOD(Commit)(DWORD dwFrags);
291 STDMETHOD(CopyTo)(IStream* pDestStream, ULARGE_INTEGER nBytesToCopy, ULARGE_INTEGER* nBytesRead, ULARGE_INTEGER* nBytesWritten);
292 STDMETHOD(LockRegion)(ULARGE_INTEGER nStart, ULARGE_INTEGER nBytes,DWORD dwFlags);
293 STDMETHOD(Read)(void* pvBuffer, ULONG nBytesToRead, ULONG* nBytesRead);
294 STDMETHOD(Revert)(void);
295 STDMETHOD(Seek)(LARGE_INTEGER nMove, DWORD dwOrigin, ULARGE_INTEGER* nNewPos);
296 STDMETHOD(SetSize)(ULARGE_INTEGER nNewSize);
297 STDMETHOD(Stat)(STATSTG* statstg, DWORD dwFlags);
298 STDMETHOD(UnlockRegion)(ULARGE_INTEGER nStart, ULARGE_INTEGER nBytes, DWORD dwFlags);
299 STDMETHOD(Write)(const void* pvBuffer, ULONG nBytesToRead, ULONG* nBytesRead);
300
301public: /* Own methods. */
302
303 static HRESULT Create(VBoxClipboardWinDataObject *pParent,
304 PSHAREDCLIPBOARDURITRANSFER pTransfer, uint64_t uObjIdx, IStream **ppStream);
305
306private:
307
308 /** Pointer to the parent data object. */
309 VBoxClipboardWinDataObject *m_pParent;
310 /** The stream object's current reference count. */
311 LONG m_lRefCount;
312 /** Pointer to the associated URI transfer object. */
313 PSHAREDCLIPBOARDURITRANSFER m_pURITransfer;
314 /** Index of the object to handle within the associated URI transfer object. */
315 uint64_t m_uObjIdx;
316};
317
318/**
319 * Class for Windows-specifics for maintaining a single URI transfer.
320 * Set as pvUser / cbUser in SHAREDCLIPBOARDURICTX.
321 */
322class SharedClipboardWinURITransferCtx
323{
324public:
325 SharedClipboardWinURITransferCtx()
326 : pDataObj(NULL) { }
327
328 virtual ~SharedClipboardWinURITransferCtx()
329 {
330 if (pDataObj)
331 delete pDataObj;
332 }
333
334 /** Pointer to data object to use for this transfer.
335 * Can be NULL if not being used. */
336 VBoxClipboardWinDataObject *pDataObj;
337};
338# endif /* VBOX_WITH_SHARED_CLIPBOARD_URI_LIST */
339#endif /* !VBOX_INCLUDED_GuestHost_SharedClipboard_win_h */
340
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette