VirtualBox

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

Last change on this file since 80318 was 80318, checked in by vboxsync, 5 years ago

Shared Clipboard/URI: More work on context IDs and entry list handling.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.3 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 <vector>
39
40# include <iprt/cpp/ministring.h> /* For RTCString. */
41# include <iprt/win/shlobj.h> /* For DROPFILES and friends. */
42# include <VBox/com/string.h> /* For Utf8Str. */
43# include <oleidl.h>
44
45# include <VBox/GuestHost/SharedClipboard-uri.h>
46
47using namespace com;
48# endif /* VBOX_WITH_SHARED_CLIPBOARD_URI_LIST */
49
50#ifndef WM_CLIPBOARDUPDATE
51# define WM_CLIPBOARDUPDATE 0x031D
52#endif
53
54#define VBOX_CLIPBOARD_WNDCLASS_NAME "VBoxSharedClipboardClass"
55
56/** See: https://docs.microsoft.com/en-us/windows/desktop/dataxchg/html-clipboard-format
57 * Do *not* change the name, as this will break compatbility with other (legacy) applications! */
58#define VBOX_CLIPBOARD_WIN_REGFMT_HTML "HTML Format"
59
60/** Default timeout (in ms) for passing down messages down the clipboard chain. */
61#define VBOX_CLIPBOARD_CBCHAIN_TIMEOUT_MS 5000
62
63/** Sets announced clipboard formats from the host. */
64#define VBOX_CLIPBOARD_WM_SET_FORMATS WM_USER
65/** Reads data from the clipboard and sends it to the host. */
66#define VBOX_CLIPBOARD_WM_READ_DATA WM_USER + 1
67#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
68/** Starts a reading transfer from the guest. */
69# define VBOX_CLIPBOARD_WM_URI_START_READ WM_USER + 2
70/** Starts a writing transfer to the guest. */
71# define VBOX_CLIPBOARD_WM_URI_START_WRITE WM_USER + 3
72#endif
73
74/* Dynamically load clipboard functions from User32.dll. */
75typedef BOOL WINAPI FNADDCLIPBOARDFORMATLISTENER(HWND);
76typedef FNADDCLIPBOARDFORMATLISTENER *PFNADDCLIPBOARDFORMATLISTENER;
77
78typedef BOOL WINAPI FNREMOVECLIPBOARDFORMATLISTENER(HWND);
79typedef FNREMOVECLIPBOARDFORMATLISTENER *PFNREMOVECLIPBOARDFORMATLISTENER;
80
81/**
82 * Structure for keeping function pointers for the new clipboard API.
83 * If the new API is not available, those function pointer are NULL.
84 */
85typedef struct _VBOXCLIPBOARDWINAPINEW
86{
87 PFNADDCLIPBOARDFORMATLISTENER pfnAddClipboardFormatListener;
88 PFNREMOVECLIPBOARDFORMATLISTENER pfnRemoveClipboardFormatListener;
89} VBOXCLIPBOARDWINAPINEW, *PVBOXCLIPBOARDWINAPINEW;
90
91/**
92 * Structure for keeping variables which are needed to drive the old clipboard API.
93 */
94typedef struct _VBOXCLIPBOARDWINAPIOLD
95{
96 /** Timer ID for the refresh timer. */
97 UINT timerRefresh;
98 /** Whether "pinging" the clipboard chain currently is in progress or not. */
99 bool fCBChainPingInProcess;
100} VBOXCLIPBOARDWINAPIOLD, *PVBOXCLIPBOARDWINAPIOLD;
101
102/**
103 * Structure for maintaining a Shared Clipboard context on Windows platforms.
104 */
105typedef struct _VBOXCLIPBOARDWINCTX
106{
107 /** Window handle of our (invisible) clipbaord window. */
108 HWND hWnd;
109 /** Window handle which is next to us in the clipboard chain. */
110 HWND hWndNextInChain;
111 /** Window handle of the clipboard owner *if* we are the owner. */
112 HWND hWndClipboardOwnerUs;
113 /** Structure for maintaining the new clipboard API. */
114 VBOXCLIPBOARDWINAPINEW newAPI;
115 /** Structure for maintaining the old clipboard API. */
116 VBOXCLIPBOARDWINAPIOLD oldAPI;
117} VBOXCLIPBOARDWINCTX, *PVBOXCLIPBOARDWINCTX;
118
119int VBoxClipboardWinOpen(HWND hWnd);
120int VBoxClipboardWinClose(void);
121int VBoxClipboardWinClear(void);
122
123int VBoxClipboardWinCheckAndInitNewAPI(PVBOXCLIPBOARDWINAPINEW pAPI);
124bool VBoxClipboardWinIsNewAPI(PVBOXCLIPBOARDWINAPINEW pAPI);
125
126int VBoxClipboardWinChainAdd(PVBOXCLIPBOARDWINCTX pCtx);
127int VBoxClipboardWinChainRemove(PVBOXCLIPBOARDWINCTX pCtx);
128VOID CALLBACK VBoxClipboardWinChainPingProc(HWND hWnd, UINT uMsg, ULONG_PTR dwData, LRESULT lResult);
129LRESULT VBoxClipboardWinChainPassToNext(PVBOXCLIPBOARDWINCTX pWinCtx, UINT msg, WPARAM wParam, LPARAM lParam);
130
131VBOXCLIPBOARDFORMAT VBoxClipboardWinClipboardFormatToVBox(UINT uFormat);
132int VBoxClipboardWinGetFormats(PVBOXCLIPBOARDWINCTX pCtx, PVBOXCLIPBOARDFORMAT pfFormats);
133
134#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
135int VBoxClipboardWinDropFilesToStringList(DROPFILES *pDropFiles, char **papszList, uint32_t *pcbList);
136#endif
137
138int VBoxClipboardWinGetCFHTMLHeaderValue(const char *pszSrc, const char *pszOption, uint32_t *puValue);
139bool VBoxClipboardWinIsCFHTML(const char *pszSource);
140int VBoxClipboardWinConvertCFHTMLToMIME(const char *pszSource, const uint32_t cch, char **ppszOutput, uint32_t *pcbOutput);
141int VBoxClipboardWinConvertMIMEToCFHTML(const char *pszSource, size_t cb, char **ppszOutput, uint32_t *pcbOutput);
142
143LRESULT VBoxClipboardWinHandleWMChangeCBChain(PVBOXCLIPBOARDWINCTX pWinCtx, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
144int VBoxClipboardWinHandleWMDestroy(PVBOXCLIPBOARDWINCTX pWinCtx);
145int VBoxClipboardWinHandleWMRenderAllFormats(PVBOXCLIPBOARDWINCTX pWinCtx, HWND hWnd);
146int VBoxClipboardWinHandleWMTimer(PVBOXCLIPBOARDWINCTX pWinCtx);
147
148int VBoxClipboardWinAnnounceFormats(PVBOXCLIPBOARDWINCTX pWinCtx, VBOXCLIPBOARDFORMATS fFormats);
149#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
150int VBoxClipboardWinURITransferCreate(PVBOXCLIPBOARDWINCTX pWinCtx, PSHAREDCLIPBOARDURITRANSFER pTransfer);
151void VBoxClipboardWinURITransferDestroy(PVBOXCLIPBOARDWINCTX pWinCtx, PSHAREDCLIPBOARDURITRANSFER pTransfer);
152#endif
153
154# ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
155class SharedClipboardURIList;
156# ifndef FILEGROUPDESCRIPTOR
157class FILEGROUPDESCRIPTOR;
158# endif
159
160class VBoxClipboardWinDataObject : public IDataObject //, public IDataObjectAsyncCapability
161{
162public:
163
164 enum Status
165 {
166 Uninitialized = 0,
167 Initialized
168 };
169
170public:
171
172 VBoxClipboardWinDataObject(PSHAREDCLIPBOARDURITRANSFER pTransfer,
173 LPFORMATETC pFormatEtc = NULL, LPSTGMEDIUM pStgMed = NULL, ULONG cFormats = 0);
174 virtual ~VBoxClipboardWinDataObject(void);
175
176public: /* IUnknown methods. */
177
178 STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject);
179 STDMETHOD_(ULONG, AddRef)(void);
180 STDMETHOD_(ULONG, Release)(void);
181
182public: /* IDataObject methods. */
183
184 STDMETHOD(GetData)(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium);
185 STDMETHOD(GetDataHere)(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium);
186 STDMETHOD(QueryGetData)(LPFORMATETC pFormatEtc);
187 STDMETHOD(GetCanonicalFormatEtc)(LPFORMATETC pFormatEct, LPFORMATETC pFormatEtcOut);
188 STDMETHOD(SetData)(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium, BOOL fRelease);
189 STDMETHOD(EnumFormatEtc)(DWORD dwDirection, IEnumFORMATETC **ppEnumFormatEtc);
190 STDMETHOD(DAdvise)(LPFORMATETC pFormatEtc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection);
191 STDMETHOD(DUnadvise)(DWORD dwConnection);
192 STDMETHOD(EnumDAdvise)(IEnumSTATDATA **ppEnumAdvise);
193
194#ifdef VBOX_WITH_SHARED_CLIPBOARD_WIN_ASYNC
195public: /* IDataObjectAsyncCapability methods. */
196
197 STDMETHOD(EndOperation)(HRESULT hResult, IBindCtx* pbcReserved, DWORD dwEffects);
198 STDMETHOD(GetAsyncMode)(BOOL* pfIsOpAsync);
199 STDMETHOD(InOperation)(BOOL* pfInAsyncOp);
200 STDMETHOD(SetAsyncMode)(BOOL fDoOpAsync);
201 STDMETHOD(StartOperation)(IBindCtx* pbcReserved);
202#endif /* VBOX_WITH_SHARED_CLIPBOARD_WIN_ASYNC */
203
204public:
205
206 int Init(void);
207 void OnTransferComplete(int rc = VINF_SUCCESS);
208 void OnTransferCanceled();
209
210public:
211
212 static DECLCALLBACK(int) readThread(RTTHREAD ThreadSelf, void *pvUser);
213
214 static const char* ClipboardFormatToString(CLIPFORMAT fmt);
215
216protected:
217
218 static int Thread(RTTHREAD hThread, void *pvUser);
219
220 int readDir(PSHAREDCLIPBOARDURITRANSFER pTransfer, const Utf8Str &strPath);
221
222 int copyToHGlobal(const void *pvData, size_t cbData, UINT fFlags, HGLOBAL *phGlobal);
223 int createFileGroupDescriptorFromTransfer(PSHAREDCLIPBOARDURITRANSFER pTransfer,
224 bool fUnicode, HGLOBAL *phGlobal);
225
226 bool lookupFormatEtc(LPFORMATETC pFormatEtc, ULONG *puIndex);
227 void registerFormat(LPFORMATETC pFormatEtc, CLIPFORMAT clipFormat, TYMED tyMed = TYMED_HGLOBAL,
228 LONG lindex = -1, DWORD dwAspect = DVASPECT_CONTENT, DVTARGETDEVICE *pTargetDevice = NULL);
229protected:
230
231 /**
232 * Structure for keeping a single file system object entry.
233 */
234 struct FSOBJENTRY
235 {
236 /** Relative path of the object. */
237 Utf8Str strPath;
238 /** Related (cached) object information. */
239 SHAREDCLIPBOARDFSOBJINFO objInfo;
240 };
241
242 /** Vector containing file system objects with its (cached) objection information. */
243 typedef std::vector<FSOBJENTRY> FsObjEntryList;
244
245 Status m_enmStatus;
246 LONG m_lRefCount;
247 ULONG m_cFormats;
248 LPFORMATETC m_pFormatEtc;
249 LPSTGMEDIUM m_pStgMedium;
250 PSHAREDCLIPBOARDURITRANSFER m_pTransfer;
251 IStream *m_pStream;
252 ULONG m_uObjIdx;
253 /** List of (cached) file system objects. */
254 FsObjEntryList m_lstEntries;
255 /** Event being triggered when reading the transfer list been completed. */
256 RTSEMEVENT m_EventListComplete;
257 /** Event being triggered when the transfer has been completed. */
258 RTSEMEVENT m_EventTransferComplete;
259 UINT m_cfFileDescriptorA;
260 UINT m_cfFileDescriptorW;
261 UINT m_cfFileContents;
262};
263
264class VBoxClipboardWinEnumFormatEtc : public IEnumFORMATETC
265{
266public:
267
268 VBoxClipboardWinEnumFormatEtc(LPFORMATETC pFormatEtc, ULONG cFormats);
269 virtual ~VBoxClipboardWinEnumFormatEtc(void);
270
271public: /* IUnknown methods. */
272
273 STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject);
274 STDMETHOD_(ULONG, AddRef)(void);
275 STDMETHOD_(ULONG, Release)(void);
276
277public: /* IEnumFORMATETC methods. */
278
279 STDMETHOD(Next)(ULONG cFormats, LPFORMATETC pFormatEtc, ULONG *pcFetched);
280 STDMETHOD(Skip)(ULONG cFormats);
281 STDMETHOD(Reset)(void);
282 STDMETHOD(Clone)(IEnumFORMATETC **ppEnumFormatEtc);
283
284public:
285
286 static void CopyFormat(LPFORMATETC pFormatDest, LPFORMATETC pFormatSource);
287 static HRESULT CreateEnumFormatEtc(UINT cFormats, LPFORMATETC pFormatEtc, IEnumFORMATETC **ppEnumFormatEtc);
288
289private:
290
291 LONG m_lRefCount;
292 ULONG m_nIndex;
293 ULONG m_nNumFormats;
294 LPFORMATETC m_pFormatEtc;
295};
296
297/**
298 * Own IStream implementation to implement file-based clipboard operations
299 * through HGCM. Needed on Windows hosts and guests.
300 */
301class VBoxClipboardWinStreamImpl : public IStream
302{
303public:
304
305 VBoxClipboardWinStreamImpl(VBoxClipboardWinDataObject *pParent, PSHAREDCLIPBOARDURITRANSFER pTransfer,
306 const Utf8Str &strPath, PSHAREDCLIPBOARDFSOBJINFO pObjInfo);
307 virtual ~VBoxClipboardWinStreamImpl(void);
308
309public: /* IUnknown methods. */
310
311 STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject);
312 STDMETHOD_(ULONG, AddRef)(void);
313 STDMETHOD_(ULONG, Release)(void);
314
315public: /* IStream methods. */
316
317 STDMETHOD(Clone)(IStream** ppStream);
318 STDMETHOD(Commit)(DWORD dwFrags);
319 STDMETHOD(CopyTo)(IStream* pDestStream, ULARGE_INTEGER nBytesToCopy, ULARGE_INTEGER* nBytesRead, ULARGE_INTEGER* nBytesWritten);
320 STDMETHOD(LockRegion)(ULARGE_INTEGER nStart, ULARGE_INTEGER nBytes,DWORD dwFlags);
321 STDMETHOD(Read)(void* pvBuffer, ULONG nBytesToRead, ULONG* nBytesRead);
322 STDMETHOD(Revert)(void);
323 STDMETHOD(Seek)(LARGE_INTEGER nMove, DWORD dwOrigin, ULARGE_INTEGER* nNewPos);
324 STDMETHOD(SetSize)(ULARGE_INTEGER nNewSize);
325 STDMETHOD(Stat)(STATSTG* statstg, DWORD dwFlags);
326 STDMETHOD(UnlockRegion)(ULARGE_INTEGER nStart, ULARGE_INTEGER nBytes, DWORD dwFlags);
327 STDMETHOD(Write)(const void* pvBuffer, ULONG nBytesToRead, ULONG* nBytesRead);
328
329public: /* Own methods. */
330
331 static HRESULT Create(VBoxClipboardWinDataObject *pParent, PSHAREDCLIPBOARDURITRANSFER pTransfer, const Utf8Str &strPath,
332 PSHAREDCLIPBOARDFSOBJINFO pObjInfo, IStream **ppStream);
333private:
334
335 /** Pointer to the parent data object. */
336 VBoxClipboardWinDataObject *m_pParent;
337 /** The stream object's current reference count. */
338 LONG m_lRefCount;
339 /** Pointer to the associated URI transfer. */
340 PSHAREDCLIPBOARDURITRANSFER m_pURITransfer;
341 /** The object handle to use. */
342 SHAREDCLIPBOARDOBJHANDLE m_hObj;
343 /** Object path. */
344 Utf8Str m_strPath;
345 /** (Cached) object information. */
346 SHAREDCLIPBOARDFSOBJINFO m_objInfo;
347 /** Number of bytes already processed. */
348 uint64_t m_cbProcessed;
349 /** Whether we already notified the parent of completion or not. */
350 bool m_fNotifiedComplete;
351};
352
353/**
354 * Class for Windows-specifics for maintaining a single URI transfer.
355 * Set as pvUser / cbUser in SHAREDCLIPBOARDURICTX.
356 */
357class SharedClipboardWinURITransferCtx
358{
359public:
360 SharedClipboardWinURITransferCtx()
361 : pDataObj(NULL) { }
362
363 virtual ~SharedClipboardWinURITransferCtx()
364 {
365 if (pDataObj)
366 delete pDataObj;
367 }
368
369 /** Pointer to data object to use for this transfer.
370 * Can be NULL if not being used. */
371 VBoxClipboardWinDataObject *pDataObj;
372};
373# endif /* VBOX_WITH_SHARED_CLIPBOARD_URI_LIST */
374#endif /* !VBOX_INCLUDED_GuestHost_SharedClipboard_win_h */
375
Note: See TracBrowser for help on using the repository browser.

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