VirtualBox

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

Last change on this file since 79107 was 79036, 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.1 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 /** Structure for maintaining the new clipboard API. */
101 VBOXCLIPBOARDWINAPINEW newAPI;
102 /** Structure for maintaining the old clipboard API. */
103 VBOXCLIPBOARDWINAPIOLD oldAPI;
104} VBOXCLIPBOARDWINCTX, *PVBOXCLIPBOARDWINCTX;
105
106int VBoxClipboardWinOpen(HWND hWnd);
107int VBoxClipboardWinClose(void);
108int VBoxClipboardWinClear(void);
109int VBoxClipboardWinCheckAndInitNewAPI(PVBOXCLIPBOARDWINAPINEW pAPI);
110bool VBoxClipboardWinIsNewAPI(PVBOXCLIPBOARDWINAPINEW pAPI);
111int VBoxClipboardWinAddToCBChain(PVBOXCLIPBOARDWINCTX pCtx);
112int VBoxClipboardWinRemoveFromCBChain(PVBOXCLIPBOARDWINCTX pCtx);
113VOID CALLBACK VBoxClipboardWinChainPingProc(HWND hWnd, UINT uMsg, ULONG_PTR dwData, LRESULT lResult);
114
115VBOXCLIPBOARDFORMAT VBoxClipboardWinClipboardFormatToVBox(UINT uFormat);
116int VBoxClipboardWinGetFormats(PVBOXCLIPBOARDWINCTX pCtx, PVBOXCLIPBOARDFORMAT pfFormats);
117
118#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
119int VBoxClipboardWinDropFilesToStringList(DROPFILES *pDropFiles, char **ppszData, size_t *pcbData);
120#endif
121
122int VBoxClipboardWinGetCFHTMLHeaderValue(const char *pszSrc, const char *pszOption, uint32_t *puValue);
123bool VBoxClipboardWinIsCFHTML(const char *pszSource);
124int VBoxClipboardWinConvertCFHTMLToMIME(const char *pszSource, const uint32_t cch, char **ppszOutput, uint32_t *pcbOutput);
125int VBoxClipboardWinConvertMIMEToCFHTML(const char *pszSource, size_t cb, char **ppszOutput, uint32_t *pcbOutput);
126
127int VBoxClipboardWinHandleWMSetFormats(const PVBOXCLIPBOARDWINCTX pCtx, VBOXCLIPBOARDFORMATS fFormats);
128#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
129int VBoxClipboardWinURIHandleWMSetFormats(const PVBOXCLIPBOARDWINCTX pCtx, PSHAREDCLIPBOARDURICTX pURICtx,
130 PSHAREDCLIPBOARDPROVIDERCREATIONCTX pProviderCtx, VBOXCLIPBOARDFORMATS fFormats);
131#endif
132
133# ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
134class SharedClipboardURIList;
135# ifndef FILEGROUPDESCRIPTOR
136class FILEGROUPDESCRIPTOR;
137# endif
138
139class VBoxClipboardWinDataObject : public IDataObject //, public IDataObjectAsyncCapability
140{
141public:
142
143 enum Status
144 {
145 Uninitialized = 0,
146 Initialized
147 };
148
149 enum FormatIndex
150 {
151 /** File descriptor, ANSI version. */
152 FormatIndex_FileDescriptorA = 0,
153 /** File descriptor, Unicode version. */
154 FormatIndex_FileDescriptorW,
155 /** File contents. */
156 FormatIndex_FileContents
157 };
158
159public:
160
161 VBoxClipboardWinDataObject(PSHAREDCLIPBOARDURITRANSFER pTransfer,
162 LPFORMATETC pFormatEtc = NULL, LPSTGMEDIUM pStgMed = NULL, ULONG cFormats = 0);
163 virtual ~VBoxClipboardWinDataObject(void);
164
165public: /* IUnknown methods. */
166
167 STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject);
168 STDMETHOD_(ULONG, AddRef)(void);
169 STDMETHOD_(ULONG, Release)(void);
170
171public: /* IDataObject methods. */
172
173 STDMETHOD(GetData)(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium);
174 STDMETHOD(GetDataHere)(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium);
175 STDMETHOD(QueryGetData)(LPFORMATETC pFormatEtc);
176 STDMETHOD(GetCanonicalFormatEtc)(LPFORMATETC pFormatEct, LPFORMATETC pFormatEtcOut);
177 STDMETHOD(SetData)(LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium, BOOL fRelease);
178 STDMETHOD(EnumFormatEtc)(DWORD dwDirection, IEnumFORMATETC **ppEnumFormatEtc);
179 STDMETHOD(DAdvise)(LPFORMATETC pFormatEtc, DWORD advf, IAdviseSink *pAdvSink, DWORD *pdwConnection);
180 STDMETHOD(DUnadvise)(DWORD dwConnection);
181 STDMETHOD(EnumDAdvise)(IEnumSTATDATA **ppEnumAdvise);
182
183#ifdef VBOX_WITH_SHARED_CLIPBOARD_WIN_ASYNC
184public: /* IDataObjectAsyncCapability methods. */
185
186 STDMETHOD(EndOperation)(HRESULT hResult, IBindCtx* pbcReserved, DWORD dwEffects);
187 STDMETHOD(GetAsyncMode)(BOOL* pfIsOpAsync);
188 STDMETHOD(InOperation)(BOOL* pfInAsyncOp);
189 STDMETHOD(SetAsyncMode)(BOOL fDoOpAsync);
190 STDMETHOD(StartOperation)(IBindCtx* pbcReserved);
191#endif /* VBOX_WITH_SHARED_CLIPBOARD_WIN_ASYNC */
192
193public:
194
195 int Init(void);
196 void OnTransferComplete(int rc = VINF_SUCCESS);
197 void OnTransferCanceled();
198
199public:
200
201 static const char* ClipboardFormatToString(CLIPFORMAT fmt);
202
203protected:
204
205 static int Thread(RTTHREAD hThread, void *pvUser);
206
207 int copyToHGlobal(const void *pvData, size_t cbData, UINT fFlags, HGLOBAL *phGlobal);
208 int createFileGroupDescriptorFromURIList(const SharedClipboardURIList &URIList, bool fUnicode, HGLOBAL *phGlobal);
209
210 bool lookupFormatEtc(LPFORMATETC pFormatEtc, ULONG *puIndex);
211 void registerFormat(LPFORMATETC pFormatEtc, CLIPFORMAT clipFormat, TYMED tyMed = TYMED_HGLOBAL,
212 LONG lindex = -1, DWORD dwAspect = DVASPECT_CONTENT, DVTARGETDEVICE *pTargetDevice = NULL);
213
214protected:
215
216 Status m_enmStatus;
217 LONG m_lRefCount;
218 ULONG m_cFormats;
219 LPFORMATETC m_pFormatEtc;
220 LPSTGMEDIUM m_pStgMedium;
221 PSHAREDCLIPBOARDURITRANSFER m_pTransfer;
222 IStream *m_pStream;
223 ULONG m_uObjIdx;
224};
225
226class VBoxClipboardWinEnumFormatEtc : public IEnumFORMATETC
227{
228public:
229
230 VBoxClipboardWinEnumFormatEtc(LPFORMATETC pFormatEtc, ULONG cFormats);
231 virtual ~VBoxClipboardWinEnumFormatEtc(void);
232
233public: /* IUnknown methods. */
234
235 STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject);
236 STDMETHOD_(ULONG, AddRef)(void);
237 STDMETHOD_(ULONG, Release)(void);
238
239public: /* IEnumFORMATETC methods. */
240
241 STDMETHOD(Next)(ULONG cFormats, LPFORMATETC pFormatEtc, ULONG *pcFetched);
242 STDMETHOD(Skip)(ULONG cFormats);
243 STDMETHOD(Reset)(void);
244 STDMETHOD(Clone)(IEnumFORMATETC **ppEnumFormatEtc);
245
246public:
247
248 static void CopyFormat(LPFORMATETC pFormatDest, LPFORMATETC pFormatSource);
249 static HRESULT CreateEnumFormatEtc(UINT cFormats, LPFORMATETC pFormatEtc, IEnumFORMATETC **ppEnumFormatEtc);
250
251private:
252
253 LONG m_lRefCount;
254 ULONG m_nIndex;
255 ULONG m_nNumFormats;
256 LPFORMATETC m_pFormatEtc;
257};
258
259/**
260 * Own IStream implementation to implement file-based clipboard operations
261 * through HGCM. Needed on Windows hosts and guests.
262 */
263class VBoxClipboardWinStreamImpl : public IStream
264{
265public:
266
267 VBoxClipboardWinStreamImpl(VBoxClipboardWinDataObject *pParent,
268 PSHAREDCLIPBOARDURITRANSFER pTransfer, uint64_t uObjIdx);
269 virtual ~VBoxClipboardWinStreamImpl(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: /* IStream methods. */
278
279 STDMETHOD(Clone)(IStream** ppStream);
280 STDMETHOD(Commit)(DWORD dwFrags);
281 STDMETHOD(CopyTo)(IStream* pDestStream, ULARGE_INTEGER nBytesToCopy, ULARGE_INTEGER* nBytesRead, ULARGE_INTEGER* nBytesWritten);
282 STDMETHOD(LockRegion)(ULARGE_INTEGER nStart, ULARGE_INTEGER nBytes,DWORD dwFlags);
283 STDMETHOD(Read)(void* pvBuffer, ULONG nBytesToRead, ULONG* nBytesRead);
284 STDMETHOD(Revert)(void);
285 STDMETHOD(Seek)(LARGE_INTEGER nMove, DWORD dwOrigin, ULARGE_INTEGER* nNewPos);
286 STDMETHOD(SetSize)(ULARGE_INTEGER nNewSize);
287 STDMETHOD(Stat)(STATSTG* statstg, DWORD dwFlags);
288 STDMETHOD(UnlockRegion)(ULARGE_INTEGER nStart, ULARGE_INTEGER nBytes, DWORD dwFlags);
289 STDMETHOD(Write)(const void* pvBuffer, ULONG nBytesToRead, ULONG* nBytesRead);
290
291public: /* Own methods. */
292
293 static HRESULT Create(VBoxClipboardWinDataObject *pParent,
294 PSHAREDCLIPBOARDURITRANSFER pTransfer, uint64_t uObjIdx, IStream **ppStream);
295
296private:
297
298 /** Pointer to the parent data object. */
299 VBoxClipboardWinDataObject *m_pParent;
300 /** The stream object's current reference count. */
301 LONG m_lRefCount;
302 /** Pointer to the associated URI transfer object. */
303 PSHAREDCLIPBOARDURITRANSFER m_pURITransfer;
304 /** Index of the object to handle within the associated URI transfer object. */
305 uint64_t m_uObjIdx;
306};
307
308/**
309 * Class for Windows-specifics for maintaining a single URI transfer.
310 * Set as pvUser / cbUser in SHAREDCLIPBOARDURICTX.
311 */
312class SharedClipboardWinURITransferCtx
313{
314public:
315 SharedClipboardWinURITransferCtx()
316 : pDataObj(NULL) { }
317
318 virtual ~SharedClipboardWinURITransferCtx()
319 {
320 if (pDataObj)
321 delete pDataObj;
322 }
323
324 /** Pointer to data object to use for this transfer.
325 * Can be NULL if not being used. */
326 VBoxClipboardWinDataObject *pDataObj;
327};
328# endif /* VBOX_WITH_SHARED_CLIPBOARD_URI_LIST */
329#endif /* !VBOX_INCLUDED_GuestHost_SharedClipboard_win_h */
330
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