VirtualBox

source: vbox/trunk/src/VBox/GuestHost/SharedClipboard/ClipboardStreamImpl-win.cpp@ 79120

Last change on this file since 79120 was 79120, 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: 9.3 KB
Line 
1/* $Id: ClipboardStreamImpl-win.cpp 79120 2019-06-13 10:08:33Z vboxsync $ */
2/** @file
3 * ClipboardStreamImpl-win.cpp - Shared Clipboard IStream object implementation (guest and host side).
4 */
5
6/*
7 * Copyright (C) 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#define LOG_GROUP LOG_GROUP_SHARED_CLIPBOARD
23#include <VBox/GuestHost/SharedClipboard-win.h>
24
25#include <iprt/asm.h>
26#include <iprt/ldr.h>
27#include <iprt/thread.h>
28
29#include <VBox/GuestHost/SharedClipboard.h>
30#include <VBox/GuestHost/SharedClipboard-win.h>
31#include <strsafe.h>
32
33#include <VBox/log.h>
34
35
36/*********************************************************************************************************************************
37* Structures and Typedefs *
38*********************************************************************************************************************************/
39
40
41
42/*********************************************************************************************************************************
43* Static variables *
44*********************************************************************************************************************************/
45
46
47
48VBoxClipboardWinStreamImpl::VBoxClipboardWinStreamImpl(VBoxClipboardWinDataObject *pParent,
49 PSHAREDCLIPBOARDURITRANSFER pTransfer, uint64_t uObjIdx)
50 : m_pParent(pParent)
51 , m_lRefCount(1)
52 , m_pURITransfer(pTransfer)
53 , m_uObjIdx(uObjIdx)
54{
55 AssertPtr(m_pURITransfer);
56 AssertPtr(m_pURITransfer->pProvider);
57
58 LogFunc(("m_uObjIdx=%RU64\n", uObjIdx));
59
60 m_pURITransfer->pProvider->AddRef();
61}
62
63VBoxClipboardWinStreamImpl::~VBoxClipboardWinStreamImpl(void)
64{
65 LogFlowThisFuncEnter();
66
67 if ( m_pURITransfer
68 && m_pURITransfer->pProvider)
69 m_pURITransfer->pProvider->Release();
70}
71
72/*
73 * IUnknown methods.
74 */
75
76STDMETHODIMP VBoxClipboardWinStreamImpl::QueryInterface(REFIID iid, void **ppvObject)
77{
78 AssertPtrReturn(ppvObject, E_INVALIDARG);
79
80 if (iid == IID_IUnknown)
81 {
82 LogFlowFunc(("IID_IUnknown\n"));
83 *ppvObject = (IUnknown *)(ISequentialStream *)this;
84 }
85 else if (iid == IID_ISequentialStream)
86 {
87 LogFlowFunc(("IID_ISequentialStream\n"));
88 *ppvObject = (ISequentialStream *)this;
89 }
90 else if (iid == IID_IStream)
91 {
92 LogFlowFunc(("IID_IStream\n"));
93 *ppvObject = (IStream *)this;
94 }
95 else
96 {
97 *ppvObject = NULL;
98 return E_NOINTERFACE;
99 }
100
101 AddRef();
102 return S_OK;
103}
104
105STDMETHODIMP_(ULONG) VBoxClipboardWinStreamImpl::AddRef(void)
106{
107 LONG lCount = InterlockedIncrement(&m_lRefCount);
108 LogFlowFunc(("lCount=%RI32\n", lCount));
109 return lCount;
110}
111
112STDMETHODIMP_(ULONG) VBoxClipboardWinStreamImpl::Release(void)
113{
114 LONG lCount = InterlockedDecrement(&m_lRefCount);
115 LogFlowFunc(("lCount=%RI32\n", m_lRefCount));
116 if (lCount == 0)
117 {
118 if (m_pParent)
119 m_pParent->OnTransferComplete();
120
121 delete this;
122 return 0;
123 }
124
125 return lCount;
126}
127
128/*
129 * IStream methods.
130 */
131
132STDMETHODIMP VBoxClipboardWinStreamImpl::Clone(IStream** ppStream)
133{
134 RT_NOREF(ppStream);
135
136 LogFlowFuncEnter();
137 return E_NOTIMPL;
138}
139
140STDMETHODIMP VBoxClipboardWinStreamImpl::Commit(DWORD dwFrags)
141{
142 RT_NOREF(dwFrags);
143
144 LogFlowThisFuncEnter();
145 return E_NOTIMPL;
146}
147
148STDMETHODIMP VBoxClipboardWinStreamImpl::CopyTo(IStream *pDestStream, ULARGE_INTEGER nBytesToCopy, ULARGE_INTEGER *nBytesRead,
149 ULARGE_INTEGER *nBytesWritten)
150{
151 RT_NOREF(pDestStream, nBytesToCopy, nBytesRead, nBytesWritten);
152
153 LogFlowThisFuncEnter();
154 return E_NOTIMPL;
155}
156
157STDMETHODIMP VBoxClipboardWinStreamImpl::LockRegion(ULARGE_INTEGER nStart, ULARGE_INTEGER nBytes,DWORD dwFlags)
158{
159 RT_NOREF(nStart, nBytes, dwFlags);
160
161 LogFlowThisFuncEnter();
162 return STG_E_INVALIDFUNCTION;
163}
164
165STDMETHODIMP VBoxClipboardWinStreamImpl::Read(void *pvBuffer, ULONG nBytesToRead, ULONG *nBytesRead)
166{
167 LogFlowThisFuncEnter();
168
169 const SharedClipboardURIObject *pObj = SharedClipboardURITransferGetObject(m_pURITransfer, m_uObjIdx);
170
171 if (pObj->IsComplete())
172 {
173 /* There can be 0-byte files. */
174 AssertMsg(pObj->GetSize() == 0, ("Object is complete -- can't read from it anymore\n"));
175 if (nBytesRead)
176 *nBytesRead = 0; /** @todo If the file size is 0, already return at least 1 byte, else the whole operation will fail. */
177 return S_OK; /* Don't report any failures back to Windows. */
178 }
179
180 const uint64_t cbSize = pObj->GetSize();
181 const uint64_t cbProcessed = pObj->GetProcessed();
182
183 const uint32_t cbToRead = RT_MIN(cbSize - cbProcessed, nBytesToRead);
184 uint32_t cbRead = 0;
185
186 int rc = VINF_SUCCESS;
187
188 if (cbToRead)
189 {
190 VBOXCLIPBOARDFILEDATA FileData;
191 RT_ZERO(FileData);
192
193 FileData.pvData = pvBuffer;
194 FileData.cbData = cbToRead;
195
196 rc = m_pURITransfer->pProvider->ReadFileData(&FileData, &cbRead);
197 if (RT_SUCCESS(rc))
198 {
199// pObj->AddProcessed(cbRead);
200
201 if (pObj->IsComplete())
202 m_pParent->OnTransferComplete();
203 }
204 }
205
206 if (nBytesRead)
207 *nBytesRead = (ULONG)cbRead;
208
209 LogFlowThisFunc(("rc=%Rrc, cbSize=%RU64, cbProcessed=%RU64 -> cbToRead=%zu, cbRead=%zu\n",
210 rc, cbSize, cbProcessed, cbToRead, cbRead));
211 return RT_SUCCESS(rc) ? S_OK : E_FAIL;
212}
213
214STDMETHODIMP VBoxClipboardWinStreamImpl::Revert(void)
215{
216 LogFlowThisFuncEnter();
217 return STG_E_INVALIDFUNCTION;
218}
219
220STDMETHODIMP VBoxClipboardWinStreamImpl::Seek(LARGE_INTEGER nMove, DWORD dwOrigin, ULARGE_INTEGER* nNewPos)
221{
222 RT_NOREF(nMove, dwOrigin, nNewPos);
223
224 LogFlowThisFuncEnter();
225 return STG_E_INVALIDFUNCTION;
226}
227
228STDMETHODIMP VBoxClipboardWinStreamImpl::SetSize(ULARGE_INTEGER nNewSize)
229{
230 RT_NOREF(nNewSize);
231
232 LogFlowThisFuncEnter();
233 return STG_E_INVALIDFUNCTION;
234}
235
236STDMETHODIMP VBoxClipboardWinStreamImpl::Stat(STATSTG *pStatStg, DWORD dwFlags)
237{
238 HRESULT hr = S_OK;
239
240 if (pStatStg)
241 {
242 const SharedClipboardURIObject *pObj = SharedClipboardURITransferGetObject(m_pURITransfer, m_uObjIdx);
243
244 RT_BZERO(pStatStg, sizeof(STATSTG));
245
246 switch (dwFlags)
247 {
248 case STATFLAG_NONAME:
249 pStatStg->pwcsName = NULL;
250 break;
251
252 case STATFLAG_DEFAULT:
253 {
254 int rc2 = RTStrToUtf16(pObj->GetDestPathAbs().c_str(), &pStatStg->pwcsName);
255 if (RT_FAILURE(rc2))
256 hr = E_FAIL;
257 break;
258 }
259
260 default:
261 hr = STG_E_INVALIDFLAG;
262 break;
263 }
264
265 if (SUCCEEDED(hr))
266 {
267 pStatStg->type = STGTY_STREAM;
268 pStatStg->grfMode = STGM_READ;
269 pStatStg->grfLocksSupported = 0;
270 pStatStg->cbSize.QuadPart = pObj->GetSize();
271 }
272 }
273 else
274 hr = STG_E_INVALIDPOINTER;
275
276 LogFlowThisFunc(("hr=%Rhrc\n", hr));
277 return hr;
278}
279
280STDMETHODIMP VBoxClipboardWinStreamImpl::UnlockRegion(ULARGE_INTEGER nStart, ULARGE_INTEGER nBytes, DWORD dwFlags)
281{
282 RT_NOREF(nStart, nBytes, dwFlags);
283
284 LogFlowThisFuncEnter();
285 return STG_E_INVALIDFUNCTION;
286}
287
288STDMETHODIMP VBoxClipboardWinStreamImpl::Write(const void *pvBuffer, ULONG nBytesToRead, ULONG *nBytesRead)
289{
290 RT_NOREF(pvBuffer, nBytesToRead, nBytesRead);
291
292 LogFlowThisFuncEnter();
293 return E_NOTIMPL;
294}
295
296/*
297 * Own stuff.
298 */
299
300/**
301 * Factory to create our own IStream implementation.
302 *
303 * @returns HRESULT
304 * @param pParent Pointer to the parent data object.
305 * @param pTransfer Pointer to URI transfer object to use.
306 * @param uObjIdx Index of object to handle within the given URI transfer object.
307 * @param ppStream Where to return the created stream object on success.
308 */
309/* static */
310HRESULT VBoxClipboardWinStreamImpl::Create(VBoxClipboardWinDataObject *pParent,
311 PSHAREDCLIPBOARDURITRANSFER pTransfer, uint64_t uObjIdx, IStream **ppStream)
312{
313 AssertPtrReturn(pTransfer, E_POINTER);
314
315 VBoxClipboardWinStreamImpl *pStream = new VBoxClipboardWinStreamImpl(pParent, pTransfer, uObjIdx);
316 if (pStream)
317 {
318 pStream->AddRef();
319
320 *ppStream = pStream;
321 return S_OK;
322 }
323
324 return E_FAIL;
325}
326
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