VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnDEnumFormat.cpp

Last change on this file was 98103, checked in by vboxsync, 16 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.1 KB
RevLine 
[49947]1/* $Id: VBoxDnDEnumFormat.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * VBoxDnDEnumFormat.cpp - IEnumFORMATETC ("Format et cetera") implementation.
4 */
5
6/*
[98103]7 * Copyright (C) 2013-2023 Oracle and/or its affiliates.
[49947]8 *
[96407]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
[49947]26 */
[69361]27
[95960]28
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
[95961]32#define LOG_GROUP LOG_GROUP_GUEST_DND
33#include <VBox/log.h>
34
[62679]35#include <iprt/win/windows.h>
[49947]36#include <new> /* For bad_alloc. */
37
38#include "VBoxTray.h"
39#include "VBoxHelpers.h"
40#include "VBoxDnD.h"
41
42
[95836]43VBoxDnDEnumFormatEtc::VBoxDnDEnumFormatEtc(LPFORMATETC pFormatEtc, ULONG uIdx, ULONG cToCopy, ULONG cTotal)
[95734]44 : m_cRefs(1)
45 , m_uIdxCur(0)
46 , m_cFormats(0)
47 , m_paFormatEtc(NULL)
48
[49947]49{
[95836]50 int rc2 = Init(pFormatEtc, uIdx, cToCopy, cTotal);
51 AssertRC(rc2);
[49947]52}
53
54VBoxDnDEnumFormatEtc::~VBoxDnDEnumFormatEtc(void)
55{
[85694]56 if (m_paFormatEtc)
[49947]57 {
[85694]58 for (ULONG i = 0; i < m_cFormats; i++)
[95734]59 if (m_paFormatEtc[i].ptd)
60 {
[85694]61 CoTaskMemFree(m_paFormatEtc[i].ptd);
[95734]62 m_paFormatEtc[i].ptd = NULL;
63 }
[49947]64
[95734]65 RTMemFree(m_paFormatEtc);
[85694]66 m_paFormatEtc = NULL;
[49947]67 }
68
[85694]69 LogFlowFunc(("m_lRefCount=%RI32\n", m_cRefs));
[49947]70}
71
[95836]72/**
73 * Initializes the class by copying the required formats.
74 *
75 * @returns VBox status code.
76 * @param pFormatEtc Format Etc to use for initialization.
77 * @param uIdx Index (zero-based) of format
78 * @param cToCopy Number of formats \a pFormatEtc to copy, starting from \a uIdx.
79 * @param cTotal Number of total formats \a pFormatEtc holds.
80 */
81int VBoxDnDEnumFormatEtc::Init(LPFORMATETC pFormatEtc, ULONG uIdx, ULONG cToCopy, ULONG cTotal)
82{
83 AssertPtrReturn(pFormatEtc, VERR_INVALID_POINTER);
84 AssertReturn(uIdx <= cTotal, VERR_INVALID_PARAMETER);
85 AssertReturn(uIdx + cToCopy <= cTotal, VERR_INVALID_PARAMETER);
86 /* cFormats can be 0. */
87
88 if (!cToCopy)
89 return VINF_SUCCESS;
90
91 AssertReturn(m_paFormatEtc == NULL && m_cFormats == 0, VERR_WRONG_ORDER);
92
93 int rc = VINF_SUCCESS;
94
95 m_paFormatEtc = (LPFORMATETC)RTMemAllocZ(sizeof(FORMATETC) * cToCopy);
96 if (m_paFormatEtc)
97 {
98 for (ULONG i = 0; i < cToCopy; i++)
99 {
100 LPFORMATETC const pFormatCur = &pFormatEtc[uIdx + i];
101
102 LogFlowFunc(("Format %RU32 (index %RU32): cfFormat=%RI16, sFormat=%s, tyMed=%RU32, dwAspect=%RU32\n",
103 i, uIdx + i, pFormatCur->cfFormat, VBoxDnDDataObject::ClipboardFormatToString(pFormatCur->cfFormat),
104 pFormatCur->tymed, pFormatCur->dwAspect));
105 VBoxDnDEnumFormatEtc::CopyFormat(&m_paFormatEtc[i], pFormatCur);
106 }
107
108 m_cFormats = cToCopy;
109 }
110 else
111 rc = VERR_NO_MEMORY;
112 return rc;
113}
114
[49947]115/*
116 * IUnknown methods.
117 */
118
119STDMETHODIMP_(ULONG) VBoxDnDEnumFormatEtc::AddRef(void)
120{
[85694]121 return InterlockedIncrement(&m_cRefs);
[49947]122}
123
124STDMETHODIMP_(ULONG) VBoxDnDEnumFormatEtc::Release(void)
125{
[85694]126 LONG lCount = InterlockedDecrement(&m_cRefs);
[49947]127 if (lCount == 0)
128 {
129 delete this;
130 return 0;
131 }
132
133 return lCount;
134}
135
136STDMETHODIMP VBoxDnDEnumFormatEtc::QueryInterface(REFIID iid, void **ppvObject)
137{
138 if ( iid == IID_IEnumFORMATETC
139 || iid == IID_IUnknown)
140 {
141 AddRef();
142 *ppvObject = this;
143 return S_OK;
144 }
145
146 *ppvObject = 0;
147 return E_NOINTERFACE;
148}
149
[56661]150STDMETHODIMP VBoxDnDEnumFormatEtc::Next(ULONG cFormats, LPFORMATETC pFormatEtc, ULONG *pcFetched)
[49947]151{
152 ULONG ulCopied = 0;
153
154 if(cFormats == 0 || pFormatEtc == 0)
155 return E_INVALIDARG;
156
[85694]157 while ( m_uIdxCur < m_cFormats
[49947]158 && ulCopied < cFormats)
159 {
160 VBoxDnDEnumFormatEtc::CopyFormat(&pFormatEtc[ulCopied],
[85694]161 &m_paFormatEtc[m_uIdxCur]);
[49947]162 ulCopied++;
[85694]163 m_uIdxCur++;
[49947]164 }
165
166 if (pcFetched)
167 *pcFetched = ulCopied;
168
169 return (ulCopied == cFormats) ? S_OK : S_FALSE;
170}
171
172STDMETHODIMP VBoxDnDEnumFormatEtc::Skip(ULONG cFormats)
173{
[85694]174 m_uIdxCur += cFormats;
175 return (m_uIdxCur <= m_cFormats) ? S_OK : S_FALSE;
[49947]176}
177
178STDMETHODIMP VBoxDnDEnumFormatEtc::Reset(void)
179{
[85694]180 m_uIdxCur = 0;
[49947]181 return S_OK;
182}
183
184STDMETHODIMP VBoxDnDEnumFormatEtc::Clone(IEnumFORMATETC **ppEnumFormatEtc)
185{
[95734]186 HRESULT hrc = CreateEnumFormatEtc(m_cFormats, m_paFormatEtc, ppEnumFormatEtc);
[49947]187
[95734]188 if (hrc == S_OK)
[85694]189 ((VBoxDnDEnumFormatEtc *) *ppEnumFormatEtc)->m_uIdxCur = m_uIdxCur;
[49947]190
[95734]191 return hrc;
[49947]192}
193
[95836]194/**
195 * Copies a format etc from \a pSource to \a aDest (deep copy).
196 *
197 * @returns VBox status code.
198 * @param pDest Where to copy \a pSource to.
199 * @param pSource Source to copy.
200 */
[49947]201/* static */
[95836]202int VBoxDnDEnumFormatEtc::CopyFormat(LPFORMATETC pDest, LPFORMATETC pSource)
[49947]203{
[95836]204 AssertPtrReturn(pDest , VERR_INVALID_POINTER);
205 AssertPtrReturn(pSource, VERR_INVALID_POINTER);
[49947]206
207 *pDest = *pSource;
208
209 if (pSource->ptd)
210 {
211 pDest->ptd = (DVTARGETDEVICE*)CoTaskMemAlloc(sizeof(DVTARGETDEVICE));
[95836]212 AssertPtrReturn(pDest->ptd, VERR_NO_MEMORY);
[49947]213 *(pDest->ptd) = *(pSource->ptd);
214 }
[95836]215
216 return VINF_SUCCESS;
[49947]217}
218
[95836]219/**
220 * Creates an IEnumFormatEtc interface from a given format etc structure.
221 *
222 * @returns HRESULT
223 * @param nNumFormats Number of formats to copy from \a pFormatEtc.
224 * @param pFormatEtc Format etc to use for creation.
225 * @param ppEnumFormatEtc Where to return the created IEnumFormatEtc interface on success.
226 */
[49947]227/* static */
[56661]228HRESULT VBoxDnDEnumFormatEtc::CreateEnumFormatEtc(UINT nNumFormats, LPFORMATETC pFormatEtc, IEnumFORMATETC **ppEnumFormatEtc)
[49947]229{
[95836]230 /* cNumFormats can be 0. */
[49947]231 AssertPtrReturn(pFormatEtc, E_INVALIDARG);
232 AssertPtrReturn(ppEnumFormatEtc, E_INVALIDARG);
233
[95734]234#ifdef RT_EXCEPTIONS_ENABLED
[95836]235 try { *ppEnumFormatEtc = new VBoxDnDEnumFormatEtc(pFormatEtc,
236 0 /* uIdx */, nNumFormats /* cToCopy */, nNumFormats /* cTotal */); }
[95734]237 catch (std::bad_alloc &)
238#else
[95836]239 *ppEnumFormatEtc = new VBoxDnDEnumFormatEtc(pFormatEtc,
240 0 /* uIdx */, nNumFormats /* cToCopy */, nNumFormats /* cTotal */);
[95734]241 if (!*ppEnumFormatEtc)
242#endif
[49947]243 {
[95734]244 return E_OUTOFMEMORY;
[49947]245 }
246
[95734]247 return S_OK;
[49947]248}
249
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use