VirtualBox

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

Last change on this file since 100763 was 100665, checked in by vboxsync, 17 months ago

Shared Clipboard: More Windows data object refcount bugfixes. Added VBOX_SHARED_CLIPBOARD_DEBUG_OBJECT_COUNTS for helping tracking down those issues. bugref:9437

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.1 KB
Line 
1/* $Id: ClipboardEnumFormatEtcImpl-win.cpp 100665 2023-07-20 13:20:29Z vboxsync $ */
2/** @file
3 * ClipboardEnumFormatEtcImpl-win.cpp - Shared Clipboard IEnumFORMATETC ("Format et cetera") implementation.
4 */
5
6/*
7 * Copyright (C) 2013-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
32#include <new> /* For bad_alloc. */
33
34#define LOG_GROUP LOG_GROUP_SHARED_CLIPBOARD
35#include <VBox/GuestHost/SharedClipboard-win.h>
36
37#include <iprt/win/windows.h>
38
39#include <VBox/log.h>
40
41
42/*********************************************************************************************************************************
43* Structures and Typedefs *
44*********************************************************************************************************************************/
45
46
47
48/*********************************************************************************************************************************
49* Static variables *
50*********************************************************************************************************************************/
51#ifdef VBOX_SHARED_CLIPBOARD_DEBUG_OBJECT_COUNTS
52 extern int g_cDbgDataObj;
53 extern int g_cDbgStreamObj;
54 extern int g_cDbgEnumFmtObj;
55#endif
56
57
58SharedClipboardWinEnumFormatEtc::SharedClipboardWinEnumFormatEtc(void)
59 : m_lRefCount(1),
60 m_nIndex(0)
61{
62#ifdef VBOX_SHARED_CLIPBOARD_DEBUG_OBJECT_COUNTS
63 g_cDbgEnumFmtObj++;
64 LogFlowFunc(("g_cDataObj=%d, g_cStreamObj=%d, g_cEnumFmtObj=%d\n", g_cDbgDataObj, g_cDbgStreamObj, g_cDbgEnumFmtObj));
65#endif
66}
67
68SharedClipboardWinEnumFormatEtc::~SharedClipboardWinEnumFormatEtc(void)
69{
70 Destroy();
71
72 LogFlowFunc(("m_lRefCount=%RI32\n", m_lRefCount));
73
74#ifdef VBOX_SHARED_CLIPBOARD_DEBUG_OBJECT_COUNTS
75 g_cDbgEnumFmtObj--;
76 LogFlowFunc(("g_cDataObj=%d, g_cStreamObj=%d, g_cEnumFmtObj=%d\n", g_cDbgDataObj, g_cDbgStreamObj, g_cDbgEnumFmtObj));
77#endif
78}
79
80/**
81 * Initializes an IEnumFORMATETC instance.
82 *
83 * @returns VBox status code.
84 * @param pFormatEtc Array of formats to use for initialization.
85 * @param cFormats Number of formats in \a pFormatEtc.
86 */
87int SharedClipboardWinEnumFormatEtc::Init(LPFORMATETC pFormatEtc, ULONG cFormats)
88{
89 LogFlowFunc(("pFormatEtc=%p, cFormats=%RU32\n", pFormatEtc, cFormats));
90 m_pFormatEtc = new FORMATETC[cFormats];
91 AssertPtrReturn(m_pFormatEtc, VERR_NO_MEMORY);
92
93 for (ULONG i = 0; i < cFormats; i++)
94 {
95 LogFlowFunc(("Format %RU32: cfFormat=%RI16, tyMed=%RU32, dwAspect=%RU32\n",
96 i, pFormatEtc[i].cfFormat, pFormatEtc[i].tymed, pFormatEtc[i].dwAspect));
97
98 SharedClipboardWinDataObject::logFormat(pFormatEtc[i].cfFormat);
99
100 SharedClipboardWinEnumFormatEtc::CopyFormat(&m_pFormatEtc[i], &pFormatEtc[i]);
101 }
102
103 m_nNumFormats = cFormats;
104
105 return VINF_SUCCESS;
106}
107
108/**
109 * Destroys an IEnumFORMATETC instance.
110 */
111void SharedClipboardWinEnumFormatEtc::Destroy(void)
112{
113 if (m_pFormatEtc)
114 {
115 for (ULONG i = 0; i < m_nNumFormats; i++)
116 {
117 if(m_pFormatEtc[i].ptd)
118 CoTaskMemFree(m_pFormatEtc[i].ptd);
119 }
120
121 delete[] m_pFormatEtc;
122 m_pFormatEtc = NULL;
123 }
124
125 m_nNumFormats = 0;
126}
127
128/*
129 * IUnknown methods.
130 */
131
132STDMETHODIMP_(ULONG) SharedClipboardWinEnumFormatEtc::AddRef(void)
133{
134 return InterlockedIncrement(&m_lRefCount);
135}
136
137STDMETHODIMP_(ULONG) SharedClipboardWinEnumFormatEtc::Release(void)
138{
139 LONG lCount = InterlockedDecrement(&m_lRefCount);
140 if (lCount == 0)
141 {
142 LogFlowFunc(("Delete\n"));
143 delete this;
144 return 0;
145 }
146
147 return lCount;
148}
149
150STDMETHODIMP SharedClipboardWinEnumFormatEtc::QueryInterface(REFIID iid, void **ppvObject)
151{
152 if ( iid == IID_IEnumFORMATETC
153 || iid == IID_IUnknown)
154 {
155 AddRef();
156 *ppvObject = this;
157 return S_OK;
158 }
159
160 *ppvObject = 0;
161 return E_NOINTERFACE;
162}
163
164STDMETHODIMP SharedClipboardWinEnumFormatEtc::Next(ULONG cFormats, LPFORMATETC pFormatEtc, ULONG *pcFetched)
165{
166 ULONG ulCopied = 0;
167
168 if(cFormats == 0 || pFormatEtc == 0)
169 return E_INVALIDARG;
170
171 while ( m_nIndex < m_nNumFormats
172 && ulCopied < cFormats)
173 {
174 SharedClipboardWinEnumFormatEtc::CopyFormat(&pFormatEtc[ulCopied], &m_pFormatEtc[m_nIndex]);
175 ulCopied++;
176 m_nIndex++;
177 }
178
179 if (pcFetched)
180 *pcFetched = ulCopied;
181
182 return (ulCopied == cFormats) ? S_OK : S_FALSE;
183}
184
185STDMETHODIMP SharedClipboardWinEnumFormatEtc::Skip(ULONG cFormats)
186{
187 m_nIndex += cFormats;
188 return (m_nIndex <= m_nNumFormats) ? S_OK : S_FALSE;
189}
190
191STDMETHODIMP SharedClipboardWinEnumFormatEtc::Reset(void)
192{
193 m_nIndex = 0;
194 return S_OK;
195}
196
197STDMETHODIMP SharedClipboardWinEnumFormatEtc::Clone(IEnumFORMATETC **ppEnumFormatEtc)
198{
199 HRESULT hResult = CreateEnumFormatEtc(m_nNumFormats, m_pFormatEtc, ppEnumFormatEtc);
200 if (hResult == S_OK)
201 ((SharedClipboardWinEnumFormatEtc *) *ppEnumFormatEtc)->m_nIndex = m_nIndex;
202
203 return hResult;
204}
205
206/* static */
207void SharedClipboardWinEnumFormatEtc::CopyFormat(LPFORMATETC pDest, LPFORMATETC pSource)
208{
209 AssertPtrReturnVoid(pDest);
210 AssertPtrReturnVoid(pSource);
211
212 *pDest = *pSource;
213
214 if (pSource->ptd)
215 {
216 pDest->ptd = (DVTARGETDEVICE*)CoTaskMemAlloc(sizeof(DVTARGETDEVICE));
217 *(pDest->ptd) = *(pSource->ptd);
218 }
219}
220
221/* static */
222HRESULT SharedClipboardWinEnumFormatEtc::CreateEnumFormatEtc(UINT nNumFormats, LPFORMATETC pFormatEtc, IEnumFORMATETC **ppEnumFormatEtc)
223{
224 AssertReturn(nNumFormats, E_INVALIDARG);
225 AssertPtrReturn(pFormatEtc, E_INVALIDARG);
226 AssertPtrReturn(ppEnumFormatEtc, E_INVALIDARG);
227
228 HRESULT hr;
229
230 SharedClipboardWinEnumFormatEtc *pEnumFormatEtc = new SharedClipboardWinEnumFormatEtc();
231 if (pEnumFormatEtc)
232 {
233 hr = pEnumFormatEtc->Init(pFormatEtc, nNumFormats);
234 if (SUCCEEDED(hr))
235 *ppEnumFormatEtc = pEnumFormatEtc;
236 }
237 else
238 hr = E_OUTOFMEMORY;
239
240 return hr;
241}
242
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