VirtualBox

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

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

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 15.3 KB
Line 
1/** @file
2 * Shared Clipboard - Common Guest and Host Code, for Windows OSes.
3 */
4
5/*
6 * Copyright (C) 2006-2020 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/critsect.h>
33#include <iprt/types.h>
34#include <iprt/win/windows.h>
35
36#include <VBox/GuestHost/SharedClipboard.h>
37
38# ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
39# include <vector>
40
41# include <iprt/cpp/ministring.h> /* For RTCString. */
42# include <iprt/win/shlobj.h> /* For DROPFILES and friends. */
43# include <VBox/com/string.h> /* For Utf8Str. */
44# include <oleidl.h>
45
46# include <VBox/GuestHost/SharedClipboard-transfers.h>
47
48using namespace com;
49# endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */
50
51#ifndef WM_CLIPBOARDUPDATE
52# define WM_CLIPBOARDUPDATE 0x031D
53#endif
54
55#define SHCL_WIN_WNDCLASS_NAME "VBoxSharedClipboardClass"
56
57/** See: https://docs.microsoft.com/en-us/windows/desktop/dataxchg/html-clipboard-format
58 * Do *not* change the name, as this will break compatbility with other (legacy) applications! */
59#define SHCL_WIN_REGFMT_HTML "HTML Format"
60
61/** Default timeout (in ms) for passing down messages down the clipboard chain. */
62#define SHCL_WIN_CBCHAIN_TIMEOUT_MS 5000
63
64/** Reports clipboard formats. */
65#define SHCL_WIN_WM_REPORT_FORMATS WM_USER
66/** Reads data from the clipboard and sends it to the destination. */
67#define SHCL_WIN_WM_READ_DATA WM_USER + 1
68#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
69/** Starts a transfer on the guest.
70 * This creates the necessary IDataObject in the matching window thread. */
71# define SHCL_WIN_WM_TRANSFER_START WM_USER + 2
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 _SHCLWINAPINEW
86{
87 PFNADDCLIPBOARDFORMATLISTENER pfnAddClipboardFormatListener;
88 PFNREMOVECLIPBOARDFORMATLISTENER pfnRemoveClipboardFormatListener;
89} SHCLWINAPINEW, *PSHCLWINAPINEW;
90
91/**
92 * Structure for keeping variables which are needed to drive the old clipboard API.
93 */
94typedef struct _SHCLWINAPIOLD
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} SHCLWINAPIOLD, *PSHCLWINAPIOLD;
101
102/**
103 * Structure for maintaining a Shared Clipboard context on Windows platforms.
104 */
105typedef struct _SHCLWINCTX
106{
107 /** Critical section to serialize access. */
108 RTCRITSECT CritSect;
109 /** Window handle of our (invisible) clipbaord window. */
110 HWND hWnd;
111 /** Window handle which is next to us in the clipboard chain. */
112 HWND hWndNextInChain;
113 /** Window handle of the clipboard owner *if* we are the owner. */
114 HWND hWndClipboardOwnerUs;
115 /** Structure for maintaining the new clipboard API. */
116 SHCLWINAPINEW newAPI;
117 /** Structure for maintaining the old clipboard API. */
118 SHCLWINAPIOLD oldAPI;
119} SHCLWINCTX, *PSHCLWINCTX;
120
121int SharedClipboardWinOpen(HWND hWnd);
122int SharedClipboardWinClose(void);
123int SharedClipboardWinClear(void);
124
125int SharedClipboardWinCtxInit(PSHCLWINCTX pWinCtx);
126void SharedClipboardWinCtxDestroy(PSHCLWINCTX pWinCtx);
127
128int SharedClipboardWinCheckAndInitNewAPI(PSHCLWINAPINEW pAPI);
129bool SharedClipboardWinIsNewAPI(PSHCLWINAPINEW pAPI);
130
131int SharedClipboardWinChainAdd(PSHCLWINCTX pCtx);
132int SharedClipboardWinChainRemove(PSHCLWINCTX pCtx);
133VOID CALLBACK SharedClipboardWinChainPingProc(HWND hWnd, UINT uMsg, ULONG_PTR dwData, LRESULT lResult);
134LRESULT SharedClipboardWinChainPassToNext(PSHCLWINCTX pWinCtx, UINT msg, WPARAM wParam, LPARAM lParam);
135
136SHCLFORMAT SharedClipboardWinClipboardFormatToVBox(UINT uFormat);
137int SharedClipboardWinGetFormats(PSHCLWINCTX pCtx, PSHCLFORMATDATA pFormats);
138
139#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
140int SharedClipboardWinGetRoots(PSHCLWINCTX pWinCtx, PSHCLTRANSFER pTransfer);
141int SharedClipboardWinDropFilesToStringList(DROPFILES *pDropFiles, char **papszList, uint32_t *pcbList);
142#endif
143
144int SharedClipboardWinGetCFHTMLHeaderValue(const char *pszSrc, const char *pszOption, uint32_t *puValue);
145bool SharedClipboardWinIsCFHTML(const char *pszSource);
146int SharedClipboardWinConvertCFHTMLToMIME(const char *pszSource, const uint32_t cch, char **ppszOutput, uint32_t *pcbOutput);
147int SharedClipboardWinConvertMIMEToCFHTML(const char *pszSource, size_t cb, char **ppszOutput, uint32_t *pcbOutput);
148
149LRESULT SharedClipboardWinHandleWMChangeCBChain(PSHCLWINCTX pWinCtx, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
150int SharedClipboardWinHandleWMDestroy(PSHCLWINCTX pWinCtx);
151int SharedClipboardWinHandleWMRenderAllFormats(PSHCLWINCTX pWinCtx, HWND hWnd);
152int SharedClipboardWinHandleWMTimer(PSHCLWINCTX pWinCtx);
153
154int SharedClipboardWinAnnounceFormats(PSHCLWINCTX pWinCtx, SHCLFORMATS fFormats);
155#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
156int SharedClipboardWinTransferCreate(PSHCLWINCTX pWinCtx, PSHCLTRANSFER pTransfer);
157void SharedClipboardWinTransferDestroy(PSHCLWINCTX pWinCtx, PSHCLTRANSFER pTransfer);
158#endif
159
160# ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
161class SharedClipboardTransferList;
162# ifndef FILEGROUPDESCRIPTOR
163class FILEGROUPDESCRIPTOR;
164# endif
165
166class SharedClipboardWinDataObject : public IDataObject //, public IDataObjectAsyncCapability
167{
168public:
169
170 enum Status
171 {
172 /** The object is uninitialized (not ready). */
173 Uninitialized = 0,
174 /** The object is initialized and ready to use. */
175 Initialized,
176 /** The operation has been successfully completed. */
177 Completed,
178 /** The operation has been canceled. */
179 Canceled,
180 /** An (unrecoverable) error occurred. */
181 Error
182 };
183
184public:
185
186 SharedClipboardWinDataObject(PSHCLTRANSFER pTransfer,
187 LPFORMATETC pFormatEtc = NULL, LPSTGMEDIUM pStgMed = NULL, ULONG cFormats = 0);
188 virtual ~SharedClipboardWinDataObject(void);
189
190public: /* IUnknown methods. */
191
192 STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject);
193 STDMETHOD_(ULONG, AddRef)(void);
194 STDMETHOD_(ULONG, Release)(void);
195
196public: /* IDataObject methods. */
197
198 STDMETHOD(GetData)(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium);
199 STDMETHOD(GetDataHere)(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium);
200 STDMETHOD(QueryGetData)(LPFORMATETC pFormatEtc);
201 STDMETHOD(GetCanonicalFormatEtc)(LPFORMATETC pFormatEct, LPFORMATETC pFormatEtcOut);
202 STDMETHOD(SetData)(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium, BOOL fRelease);
203 STDMETHOD(EnumFormatEtc)(DWORD dwDirection, IEnumFORMATETC **ppEnumFormatEtc);
204 STDMETHOD(DAdvise)(LPFORMATETC pFormatEtc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection);
205 STDMETHOD(DUnadvise)(DWORD dwConnection);
206 STDMETHOD(EnumDAdvise)(IEnumSTATDATA **ppEnumAdvise);
207
208#ifdef VBOX_WITH_SHARED_CLIPBOARD_WIN_ASYNC
209public: /* IDataObjectAsyncCapability methods. */
210
211 STDMETHOD(EndOperation)(HRESULT hResult, IBindCtx* pbcReserved, DWORD dwEffects);
212 STDMETHOD(GetAsyncMode)(BOOL* pfIsOpAsync);
213 STDMETHOD(InOperation)(BOOL* pfInAsyncOp);
214 STDMETHOD(SetAsyncMode)(BOOL fDoOpAsync);
215 STDMETHOD(StartOperation)(IBindCtx* pbcReserved);
216#endif /* VBOX_WITH_SHARED_CLIPBOARD_WIN_ASYNC */
217
218public:
219
220 int Init(void);
221 void OnTransferComplete(int rc = VINF_SUCCESS);
222 void OnTransferCanceled();
223
224public:
225
226 static DECLCALLBACK(int) readThread(RTTHREAD ThreadSelf, void *pvUser);
227
228 static void logFormat(CLIPFORMAT fmt);
229
230protected:
231
232 static int Thread(RTTHREAD hThread, void *pvUser);
233
234 int readDir(PSHCLTRANSFER pTransfer, const Utf8Str &strPath);
235
236 int copyToHGlobal(const void *pvData, size_t cbData, UINT fFlags, HGLOBAL *phGlobal);
237 int createFileGroupDescriptorFromTransfer(PSHCLTRANSFER pTransfer,
238 bool fUnicode, HGLOBAL *phGlobal);
239
240 bool lookupFormatEtc(LPFORMATETC pFormatEtc, ULONG *puIndex);
241 void registerFormat(LPFORMATETC pFormatEtc, CLIPFORMAT clipFormat, TYMED tyMed = TYMED_HGLOBAL,
242 LONG lindex = -1, DWORD dwAspect = DVASPECT_CONTENT, DVTARGETDEVICE *pTargetDevice = NULL);
243protected:
244
245 /**
246 * Structure for keeping a single file system object entry.
247 */
248 struct FSOBJENTRY
249 {
250 /** Relative path of the object. */
251 Utf8Str strPath;
252 /** Related (cached) object information. */
253 SHCLFSOBJINFO objInfo;
254 };
255
256 /** Vector containing file system objects with its (cached) objection information. */
257 typedef std::vector<FSOBJENTRY> FsObjEntryList;
258
259 /** The object's current status. */
260 Status m_enmStatus;
261 /** The object's current reference count. */
262 LONG m_lRefCount;
263 /** How many formats have been registered. */
264 ULONG m_cFormats;
265 LPFORMATETC m_pFormatEtc;
266 LPSTGMEDIUM m_pStgMedium;
267 /** Pointer to the associated transfer object being handled. */
268 PSHCLTRANSFER m_pTransfer;
269 /** Current stream object being used. */
270 IStream *m_pStream;
271 /** Current object index being handled by the data object.
272 * This is needed to create the next IStream object for e.g. the next upcoming file/dir/++ in the transfer. */
273 ULONG m_uObjIdx;
274 /** List of (cached) file system objects. */
275 FsObjEntryList m_lstEntries;
276 /** Whether the transfer thread is running. */
277 bool m_fRunning;
278 /** Event being triggered when reading the transfer list been completed. */
279 RTSEMEVENT m_EventListComplete;
280 /** Event being triggered when the transfer has been completed. */
281 RTSEMEVENT m_EventTransferComplete;
282 /** Registered format for CFSTR_FILEDESCRIPTORA. */
283 UINT m_cfFileDescriptorA;
284 /** Registered format for CFSTR_FILEDESCRIPTORW. */
285 UINT m_cfFileDescriptorW;
286 /** Registered format for CFSTR_FILECONTENTS. */
287 UINT m_cfFileContents;
288 /** Registered format for CFSTR_PERFORMEDDROPEFFECT. */
289 UINT m_cfPerformedDropEffect;
290};
291
292class SharedClipboardWinEnumFormatEtc : public IEnumFORMATETC
293{
294public:
295
296 SharedClipboardWinEnumFormatEtc(LPFORMATETC pFormatEtc, ULONG cFormats);
297 virtual ~SharedClipboardWinEnumFormatEtc(void);
298
299public: /* IUnknown methods. */
300
301 STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject);
302 STDMETHOD_(ULONG, AddRef)(void);
303 STDMETHOD_(ULONG, Release)(void);
304
305public: /* IEnumFORMATETC methods. */
306
307 STDMETHOD(Next)(ULONG cFormats, LPFORMATETC pFormatEtc, ULONG *pcFetched);
308 STDMETHOD(Skip)(ULONG cFormats);
309 STDMETHOD(Reset)(void);
310 STDMETHOD(Clone)(IEnumFORMATETC **ppEnumFormatEtc);
311
312public:
313
314 static void CopyFormat(LPFORMATETC pFormatDest, LPFORMATETC pFormatSource);
315 static HRESULT CreateEnumFormatEtc(UINT cFormats, LPFORMATETC pFormatEtc, IEnumFORMATETC **ppEnumFormatEtc);
316
317private:
318
319 LONG m_lRefCount;
320 ULONG m_nIndex;
321 ULONG m_nNumFormats;
322 LPFORMATETC m_pFormatEtc;
323};
324
325/**
326 * Own IStream implementation to implement file-based clipboard operations
327 * through HGCM. Needed on Windows hosts and guests.
328 */
329class SharedClipboardWinStreamImpl : public IStream
330{
331public:
332
333 SharedClipboardWinStreamImpl(SharedClipboardWinDataObject *pParent, PSHCLTRANSFER pTransfer,
334 const Utf8Str &strPath, PSHCLFSOBJINFO pObjInfo);
335 virtual ~SharedClipboardWinStreamImpl(void);
336
337public: /* IUnknown methods. */
338
339 STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject);
340 STDMETHOD_(ULONG, AddRef)(void);
341 STDMETHOD_(ULONG, Release)(void);
342
343public: /* IStream methods. */
344
345 STDMETHOD(Clone)(IStream** ppStream);
346 STDMETHOD(Commit)(DWORD dwFrags);
347 STDMETHOD(CopyTo)(IStream* pDestStream, ULARGE_INTEGER nBytesToCopy, ULARGE_INTEGER* nBytesRead, ULARGE_INTEGER* nBytesWritten);
348 STDMETHOD(LockRegion)(ULARGE_INTEGER nStart, ULARGE_INTEGER nBytes,DWORD dwFlags);
349 STDMETHOD(Read)(void* pvBuffer, ULONG nBytesToRead, ULONG* nBytesRead);
350 STDMETHOD(Revert)(void);
351 STDMETHOD(Seek)(LARGE_INTEGER nMove, DWORD dwOrigin, ULARGE_INTEGER* nNewPos);
352 STDMETHOD(SetSize)(ULARGE_INTEGER nNewSize);
353 STDMETHOD(Stat)(STATSTG* statstg, DWORD dwFlags);
354 STDMETHOD(UnlockRegion)(ULARGE_INTEGER nStart, ULARGE_INTEGER nBytes, DWORD dwFlags);
355 STDMETHOD(Write)(const void* pvBuffer, ULONG nBytesToRead, ULONG* nBytesRead);
356
357public: /* Own methods. */
358
359 static HRESULT Create(SharedClipboardWinDataObject *pParent, PSHCLTRANSFER pTransfer, const Utf8Str &strPath,
360 PSHCLFSOBJINFO pObjInfo, IStream **ppStream);
361private:
362
363 /** Pointer to the parent data object. */
364 SharedClipboardWinDataObject *m_pParent;
365 /** The stream object's current reference count. */
366 LONG m_lRefCount;
367 /** Pointer to the associated Shared Clipboard transfer. */
368 PSHCLTRANSFER m_pTransfer;
369 /** The object handle to use. */
370 SHCLOBJHANDLE m_hObj;
371 /** Object path. */
372 Utf8Str m_strPath;
373 /** (Cached) object information. */
374 SHCLFSOBJINFO m_objInfo;
375 /** Number of bytes already processed. */
376 uint64_t m_cbProcessed;
377 /** Whether this object already is in completed state or not. */
378 bool m_fIsComplete;
379};
380
381/**
382 * Class for Windows-specifics for maintaining a single Shared Clipboard transfer.
383 * Set as pvUser / cbUser in SHCLTRANSFERCTX.
384 */
385class SharedClipboardWinTransferCtx
386{
387public:
388 SharedClipboardWinTransferCtx()
389 : pDataObj(NULL) { }
390
391 virtual ~SharedClipboardWinTransferCtx()
392 {
393 if (pDataObj)
394 delete pDataObj;
395 }
396
397 /** Pointer to data object to use for this transfer.
398 * Can be NULL if not being used. */
399 SharedClipboardWinDataObject *pDataObj;
400};
401# endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */
402#endif /* !VBOX_INCLUDED_GuestHost_SharedClipboard_win_h */
403
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