VirtualBox

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

Last change on this file since 79497 was 79497, 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.2 KB
Line 
1/* $Id: ClipboardStreamImpl-win.cpp 79497 2019-07-03 13:28: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
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 AssertPtr(m_pURITransfer->State.ObjCtx.pObjInfo);
163
164 const uint64_t cbSize = m_pURITransfer->State.ObjCtx.pObjInfo->cbObject;
165 uint64_t cbProcessed = m_pURITransfer->State.ObjCtx.cbProcessed;
166
167 if (cbProcessed == cbSize)
168 {
169 /* There can be 0-byte files. */
170 AssertMsg(cbSize == 0, ("Object is complete -- can't read from it anymore\n"));
171 if (nBytesRead)
172 *nBytesRead = 0; /** @todo If the file size is 0, already return at least 1 byte, else the whole operation will fail. */
173 return S_OK; /* Don't report any failures back to Windows. */
174 }
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.pfnObjRead(&m_pURITransfer->ProviderCtx, m_pURITransfer->State.ObjCtx.uHandle,
184 pvBuffer, cbToRead, 0 /* fFlags */, &cbRead);
185 if (RT_SUCCESS(rc))
186 {
187 cbProcessed += cbRead;
188 Assert(cbProcessed <= cbSize);
189
190 if (cbProcessed == cbSize)
191 m_pParent->OnTransferComplete();
192
193 m_pURITransfer->State.ObjCtx.cbProcessed = cbProcessed;
194 }
195 }
196
197 if (nBytesRead)
198 *nBytesRead = (ULONG)cbRead;
199
200 LogFlowThisFunc(("rc=%Rrc, cbSize=%RU64, cbProcessed=%RU64 -> cbToRead=%zu, cbRead=%zu\n",
201 rc, cbSize, cbProcessed, cbToRead, cbRead));
202 return RT_SUCCESS(rc) ? S_OK : E_FAIL;
203}
204
205STDMETHODIMP VBoxClipboardWinStreamImpl::Revert(void)
206{
207 LogFlowThisFuncEnter();
208 return STG_E_INVALIDFUNCTION;
209}
210
211STDMETHODIMP VBoxClipboardWinStreamImpl::Seek(LARGE_INTEGER nMove, DWORD dwOrigin, ULARGE_INTEGER* nNewPos)
212{
213 RT_NOREF(nMove, dwOrigin, nNewPos);
214
215 LogFlowThisFuncEnter();
216 return STG_E_INVALIDFUNCTION;
217}
218
219STDMETHODIMP VBoxClipboardWinStreamImpl::SetSize(ULARGE_INTEGER nNewSize)
220{
221 RT_NOREF(nNewSize);
222
223 LogFlowThisFuncEnter();
224 return STG_E_INVALIDFUNCTION;
225}
226
227STDMETHODIMP VBoxClipboardWinStreamImpl::Stat(STATSTG *pStatStg, DWORD dwFlags)
228{
229 HRESULT hr = S_OK;
230
231 if (pStatStg)
232 {
233 const SharedClipboardURIObject *pObj = SharedClipboardURITransferGetObject(m_pURITransfer, m_uObjIdx);
234
235 RT_BZERO(pStatStg, sizeof(STATSTG));
236
237 switch (dwFlags)
238 {
239 case STATFLAG_NONAME:
240 pStatStg->pwcsName = NULL;
241 break;
242
243 case STATFLAG_DEFAULT:
244 {
245 int rc2 = RTStrToUtf16(pObj->GetDestPathAbs().c_str(), &pStatStg->pwcsName);
246 if (RT_FAILURE(rc2))
247 hr = E_FAIL;
248 break;
249 }
250
251 default:
252 hr = STG_E_INVALIDFLAG;
253 break;
254 }
255
256 if (SUCCEEDED(hr))
257 {
258 pStatStg->type = STGTY_STREAM;
259 pStatStg->grfMode = STGM_READ;
260 pStatStg->grfLocksSupported = 0;
261 pStatStg->cbSize.QuadPart = pObj->GetSize();
262 }
263 }
264 else
265 hr = STG_E_INVALIDPOINTER;
266
267 LogFlowThisFunc(("hr=%Rhrc\n", hr));
268 return hr;
269}
270
271STDMETHODIMP VBoxClipboardWinStreamImpl::UnlockRegion(ULARGE_INTEGER nStart, ULARGE_INTEGER nBytes, DWORD dwFlags)
272{
273 RT_NOREF(nStart, nBytes, dwFlags);
274
275 LogFlowThisFuncEnter();
276 return STG_E_INVALIDFUNCTION;
277}
278
279STDMETHODIMP VBoxClipboardWinStreamImpl::Write(const void *pvBuffer, ULONG nBytesToRead, ULONG *nBytesRead)
280{
281 RT_NOREF(pvBuffer, nBytesToRead, nBytesRead);
282
283 LogFlowThisFuncEnter();
284 return E_NOTIMPL;
285}
286
287/*
288 * Own stuff.
289 */
290
291/**
292 * Factory to create our own IStream implementation.
293 *
294 * @returns HRESULT
295 * @param pParent Pointer to the parent data object.
296 * @param pTransfer Pointer to URI transfer object to use.
297 * @param uObjIdx Index of object to handle within the given URI transfer object.
298 * @param ppStream Where to return the created stream object on success.
299 */
300/* static */
301HRESULT VBoxClipboardWinStreamImpl::Create(VBoxClipboardWinDataObject *pParent,
302 PSHAREDCLIPBOARDURITRANSFER pTransfer, uint64_t uObjIdx, IStream **ppStream)
303{
304 AssertPtrReturn(pTransfer, E_POINTER);
305
306 VBoxClipboardWinStreamImpl *pStream = new VBoxClipboardWinStreamImpl(pParent, pTransfer, uObjIdx);
307 if (pStream)
308 {
309 pStream->AddRef();
310
311 *ppStream = pStream;
312 return S_OK;
313 }
314
315 return E_FAIL;
316}
317
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette