VirtualBox

source: vbox/trunk/src/VBox/GuestHost/SharedClipboard/ClipboardEnumFormatEtcImpl-win.cpp@ 81269

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

Shared Clipboard/Transfers: Implemented transfer cancellation support for the Windows shell.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.1 KB
Line 
1/* $Id: ClipboardEnumFormatEtcImpl-win.cpp 81269 2019-10-14 18:28:34Z vboxsync $ */
2/** @file
3 * ClipboardEnumFormatEtcImpl-win.cpp - Shared Clipboard IEnumFORMATETC ("Format et cetera") implementation.
4 */
5
6/*
7 * Copyright (C) 2013-2019 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#include <new> /* For bad_alloc. */
23
24#define LOG_GROUP LOG_GROUP_SHARED_CLIPBOARD
25#include <VBox/GuestHost/SharedClipboard-win.h>
26
27#include <iprt/win/windows.h>
28
29#include <VBox/log.h>
30
31
32
33SharedClipboardWinEnumFormatEtc::SharedClipboardWinEnumFormatEtc(LPFORMATETC pFormatEtc, ULONG cFormats)
34 : m_lRefCount(1),
35 m_nIndex(0)
36{
37 HRESULT hr;
38
39 try
40 {
41 LogFlowFunc(("pFormatEtc=%p, cFormats=%RU32\n", pFormatEtc, cFormats));
42 m_pFormatEtc = new FORMATETC[cFormats];
43
44 for (ULONG i = 0; i < cFormats; i++)
45 {
46 LogFlowFunc(("Format %RU32: cfFormat=%RI16, tyMed=%RU32, dwAspect=%RU32\n",
47 i, pFormatEtc[i].cfFormat, pFormatEtc[i].tymed, pFormatEtc[i].dwAspect));
48
49 SharedClipboardWinDataObject::logFormat(pFormatEtc[i].cfFormat);
50
51 SharedClipboardWinEnumFormatEtc::CopyFormat(&m_pFormatEtc[i], &pFormatEtc[i]);
52 }
53
54 m_nNumFormats = cFormats;
55 hr = S_OK;
56 }
57 catch (std::bad_alloc &)
58 {
59 hr = E_OUTOFMEMORY;
60 }
61
62 LogFlowFunc(("hr=%Rhrc\n", hr));
63}
64
65SharedClipboardWinEnumFormatEtc::~SharedClipboardWinEnumFormatEtc(void)
66{
67 if (m_pFormatEtc)
68 {
69 for (ULONG i = 0; i < m_nNumFormats; i++)
70 {
71 if(m_pFormatEtc[i].ptd)
72 CoTaskMemFree(m_pFormatEtc[i].ptd);
73 }
74
75 delete[] m_pFormatEtc;
76 m_pFormatEtc = NULL;
77 }
78
79 LogFlowFunc(("m_lRefCount=%RI32\n", m_lRefCount));
80}
81
82/*
83 * IUnknown methods.
84 */
85
86STDMETHODIMP_(ULONG) SharedClipboardWinEnumFormatEtc::AddRef(void)
87{
88 return InterlockedIncrement(&m_lRefCount);
89}
90
91STDMETHODIMP_(ULONG) SharedClipboardWinEnumFormatEtc::Release(void)
92{
93 LONG lCount = InterlockedDecrement(&m_lRefCount);
94 if (lCount == 0)
95 {
96 LogFlowFunc(("Delete\n"));
97 delete this;
98 return 0;
99 }
100
101 return lCount;
102}
103
104STDMETHODIMP SharedClipboardWinEnumFormatEtc::QueryInterface(REFIID iid, void **ppvObject)
105{
106 if ( iid == IID_IEnumFORMATETC
107 || iid == IID_IUnknown)
108 {
109 AddRef();
110 *ppvObject = this;
111 return S_OK;
112 }
113
114 *ppvObject = 0;
115 return E_NOINTERFACE;
116}
117
118STDMETHODIMP SharedClipboardWinEnumFormatEtc::Next(ULONG cFormats, LPFORMATETC pFormatEtc, ULONG *pcFetched)
119{
120 ULONG ulCopied = 0;
121
122 if(cFormats == 0 || pFormatEtc == 0)
123 return E_INVALIDARG;
124
125 while ( m_nIndex < m_nNumFormats
126 && ulCopied < cFormats)
127 {
128 SharedClipboardWinEnumFormatEtc::CopyFormat(&pFormatEtc[ulCopied], &m_pFormatEtc[m_nIndex]);
129 ulCopied++;
130 m_nIndex++;
131 }
132
133 if (pcFetched)
134 *pcFetched = ulCopied;
135
136 return (ulCopied == cFormats) ? S_OK : S_FALSE;
137}
138
139STDMETHODIMP SharedClipboardWinEnumFormatEtc::Skip(ULONG cFormats)
140{
141 m_nIndex += cFormats;
142 return (m_nIndex <= m_nNumFormats) ? S_OK : S_FALSE;
143}
144
145STDMETHODIMP SharedClipboardWinEnumFormatEtc::Reset(void)
146{
147 m_nIndex = 0;
148 return S_OK;
149}
150
151STDMETHODIMP SharedClipboardWinEnumFormatEtc::Clone(IEnumFORMATETC **ppEnumFormatEtc)
152{
153 HRESULT hResult = CreateEnumFormatEtc(m_nNumFormats, m_pFormatEtc, ppEnumFormatEtc);
154 if (hResult == S_OK)
155 ((SharedClipboardWinEnumFormatEtc *) *ppEnumFormatEtc)->m_nIndex = m_nIndex;
156
157 return hResult;
158}
159
160/* static */
161void SharedClipboardWinEnumFormatEtc::CopyFormat(LPFORMATETC pDest, LPFORMATETC pSource)
162{
163 AssertPtrReturnVoid(pDest);
164 AssertPtrReturnVoid(pSource);
165
166 *pDest = *pSource;
167
168 if (pSource->ptd)
169 {
170 pDest->ptd = (DVTARGETDEVICE*)CoTaskMemAlloc(sizeof(DVTARGETDEVICE));
171 *(pDest->ptd) = *(pSource->ptd);
172 }
173}
174
175/* static */
176HRESULT SharedClipboardWinEnumFormatEtc::CreateEnumFormatEtc(UINT nNumFormats, LPFORMATETC pFormatEtc, IEnumFORMATETC **ppEnumFormatEtc)
177{
178 AssertReturn(nNumFormats, E_INVALIDARG);
179 AssertPtrReturn(pFormatEtc, E_INVALIDARG);
180 AssertPtrReturn(ppEnumFormatEtc, E_INVALIDARG);
181
182 HRESULT hr;
183 try
184 {
185 *ppEnumFormatEtc = new SharedClipboardWinEnumFormatEtc(pFormatEtc, nNumFormats);
186 hr = S_OK;
187 }
188 catch(std::bad_alloc &)
189 {
190 hr = E_OUTOFMEMORY;
191 }
192
193 return hr;
194}
195
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