VirtualBox

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

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