VirtualBox

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

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

Shared Clipboard/URI: Update.

  • 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 copyToHGlobal(const void *pvData, size_t cbData, UINT fFlags, HGLOBAL *phGlobal);
221 int createFileGroupDescriptorFromTransfer(PSHAREDCLIPBOARDURITRANSFER pTransfer,
222 bool fUnicode, HGLOBAL *phGlobal);
223
224 bool lookupFormatEtc(LPFORMATETC pFormatEtc, ULONG *puIndex);
225 void registerFormat(LPFORMATETC pFormatEtc, CLIPFORMAT clipFormat, TYMED tyMed = TYMED_HGLOBAL,
226 LONG lindex = -1, DWORD dwAspect = DVASPECT_CONTENT, DVTARGETDEVICE *pTargetDevice = NULL);
227protected:
228
229 /**
230 * Structure for keeping a single file system object entry.
231 */
232 struct FSOBJENTRY
233 {
234 /** Relative path of the object. */
235 Utf8Str strPath;
236 /** Related (cached) object information. */
237 SHAREDCLIPBOARDFSOBJINFO objInfo;
238 };
239
240 /** Vector containing file system objects with its (cached) objection information. */
241 typedef std::vector<FSOBJENTRY> FsObjEntryList;
242
243 Status m_enmStatus;
244 LONG m_lRefCount;
245 ULONG m_cFormats;
246 LPFORMATETC m_pFormatEtc;
247 LPSTGMEDIUM m_pStgMedium;
248 PSHAREDCLIPBOARDURITRANSFER m_pTransfer;
249 IStream *m_pStream;
250 ULONG m_uObjIdx;
251 /** List of (cached) file system root objects. */
252 FsObjEntryList m_lstRootEntries;
253 /** Event being triggered when reading the transfer list been completed. */
254 RTSEMEVENT m_EventListComplete;
255 /** Event being triggered when the transfer has been completed. */
256 RTSEMEVENT m_EventTransferComplete;
257 UINT m_cfFileDescriptorA;
258 UINT m_cfFileDescriptorW;
259 UINT m_cfFileContents;
260};
261
262class VBoxClipboardWinEnumFormatEtc : public IEnumFORMATETC
263{
264public:
265
266 VBoxClipboardWinEnumFormatEtc(LPFORMATETC pFormatEtc, ULONG cFormats);
267 virtual ~VBoxClipboardWinEnumFormatEtc(void);
268
269public: /* IUnknown methods. */
270
271 STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject);
272 STDMETHOD_(ULONG, AddRef)(void);
273 STDMETHOD_(ULONG, Release)(void);
274
275public: /* IEnumFORMATETC methods. */
276
277 STDMETHOD(Next)(ULONG cFormats, LPFORMATETC pFormatEtc, ULONG *pcFetched);
278 STDMETHOD(Skip)(ULONG cFormats);
279 STDMETHOD(Reset)(void);
280 STDMETHOD(Clone)(IEnumFORMATETC **ppEnumFormatEtc);
281
282public:
283
284 static void CopyFormat(LPFORMATETC pFormatDest, LPFORMATETC pFormatSource);
285 static HRESULT CreateEnumFormatEtc(UINT cFormats, LPFORMATETC pFormatEtc, IEnumFORMATETC **ppEnumFormatEtc);
286
287private:
288
289 LONG m_lRefCount;
290 ULONG m_nIndex;
291 ULONG m_nNumFormats;
292 LPFORMATETC m_pFormatEtc;
293};
294
295/**
296 * Own IStream implementation to implement file-based clipboard operations
297 * through HGCM. Needed on Windows hosts and guests.
298 */
299class VBoxClipboardWinStreamImpl : public IStream
300{
301public:
302
303 VBoxClipboardWinStreamImpl(VBoxClipboardWinDataObject *pParent, PSHAREDCLIPBOARDURITRANSFER pTransfer,
304 const Utf8Str &strPath, PSHAREDCLIPBOARDFSOBJINFO pObjInfo);
305 virtual ~VBoxClipboardWinStreamImpl(void);
306
307public: /* IUnknown methods. */
308
309 STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject);
310 STDMETHOD_(ULONG, AddRef)(void);
311 STDMETHOD_(ULONG, Release)(void);
312
313public: /* IStream methods. */
314
315 STDMETHOD(Clone)(IStream** ppStream);
316 STDMETHOD(Commit)(DWORD dwFrags);
317 STDMETHOD(CopyTo)(IStream* pDestStream, ULARGE_INTEGER nBytesToCopy, ULARGE_INTEGER* nBytesRead, ULARGE_INTEGER* nBytesWritten);
318 STDMETHOD(LockRegion)(ULARGE_INTEGER nStart, ULARGE_INTEGER nBytes,DWORD dwFlags);
319 STDMETHOD(Read)(void* pvBuffer, ULONG nBytesToRead, ULONG* nBytesRead);
320 STDMETHOD(Revert)(void);
321 STDMETHOD(Seek)(LARGE_INTEGER nMove, DWORD dwOrigin, ULARGE_INTEGER* nNewPos);
322 STDMETHOD(SetSize)(ULARGE_INTEGER nNewSize);
323 STDMETHOD(Stat)(STATSTG* statstg, DWORD dwFlags);
324 STDMETHOD(UnlockRegion)(ULARGE_INTEGER nStart, ULARGE_INTEGER nBytes, DWORD dwFlags);
325 STDMETHOD(Write)(const void* pvBuffer, ULONG nBytesToRead, ULONG* nBytesRead);
326
327public: /* Own methods. */
328
329 static HRESULT Create(VBoxClipboardWinDataObject *pParent, PSHAREDCLIPBOARDURITRANSFER pTransfer, const Utf8Str &strPath,
330 PSHAREDCLIPBOARDFSOBJINFO pObjInfo, IStream **ppStream);
331private:
332
333 /** Pointer to the parent data object. */
334 VBoxClipboardWinDataObject *m_pParent;
335 /** The stream object's current reference count. */
336 LONG m_lRefCount;
337 /** Pointer to the associated URI transfer. */
338 PSHAREDCLIPBOARDURITRANSFER m_pURITransfer;
339 /** The object handle to use. */
340 SHAREDCLIPBOARDOBJHANDLE m_hObj;
341 /** Object path. */
342 Utf8Str m_strPath;
343 /** (Cached) object information. */
344 SHAREDCLIPBOARDFSOBJINFO m_objInfo;
345 /** Number of bytes already processed. */
346 uint64_t m_cbProcessed;
347 /** Whether we already notified the parent of completion or not. */
348 bool m_fNotifiedComplete;
349};
350
351/**
352 * Class for Windows-specifics for maintaining a single URI transfer.
353 * Set as pvUser / cbUser in SHAREDCLIPBOARDURICTX.
354 */
355class SharedClipboardWinURITransferCtx
356{
357public:
358 SharedClipboardWinURITransferCtx()
359 : pDataObj(NULL) { }
360
361 virtual ~SharedClipboardWinURITransferCtx()
362 {
363 if (pDataObj)
364 delete pDataObj;
365 }
366
367 /** Pointer to data object to use for this transfer.
368 * Can be NULL if not being used. */
369 VBoxClipboardWinDataObject *pDataObj;
370};
371# endif /* VBOX_WITH_SHARED_CLIPBOARD_URI_LIST */
372#endif /* !VBOX_INCLUDED_GuestHost_SharedClipboard_win_h */
373
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