VirtualBox

source: vbox/trunk/src/VBox/GuestHost/SharedClipboard/ClipboardProvider-HostService.cpp@ 79260

Last change on this file since 79260 was 79174, 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: 10.6 KB
Line 
1/* $Id: ClipboardProvider-HostService.cpp 79174 2019-06-17 10:30:49Z vboxsync $ */
2/** @file
3 * Shared Clipboard - Provider implementation for host service (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-uri.h>
24
25#include <iprt/asm.h>
26#include <iprt/assert.h>
27#include <iprt/dir.h>
28#include <iprt/errcore.h>
29#include <iprt/semaphore.h>
30#include <iprt/file.h>
31#include <iprt/path.h>
32#include <iprt/string.h>
33
34#include <VBox/log.h>
35
36
37
38SharedClipboardProviderHostService::Event::Event(uint32_t uMsg)
39 : mMsg(uMsg)
40 , mpvData(NULL)
41 , mcbData(0)
42{
43 int rc2 = RTSemEventCreate(&mEvent);
44 AssertRC(rc2);
45}
46
47SharedClipboardProviderHostService::Event::~Event()
48{
49 if (mpvData)
50 {
51 Assert(mcbData);
52
53 RTMemFree(mpvData);
54 mpvData = NULL;
55 }
56
57 int rc2 = RTSemEventDestroy(mEvent);
58 AssertRC(rc2);
59}
60
61/**
62 * Sets user data associated to an event.
63 *
64 * @returns VBox status code.
65 * @param pvData Pointer to user data to set.
66 * @param cbData Size (in bytes) of user data to set.
67 */
68int SharedClipboardProviderHostService::Event::SetData(const void *pvData, uint32_t cbData)
69{
70 Assert(mpvData == NULL);
71 Assert(mcbData == 0);
72
73 if (!cbData)
74 return VINF_SUCCESS;
75
76 mpvData = RTMemDup(pvData, cbData);
77 if (!mpvData)
78 return VERR_NO_MEMORY;
79
80 mcbData = cbData;
81
82 return VINF_SUCCESS;
83}
84
85/**
86 * Waits for an event to get signalled.
87 * Will return VERR_NOT_FOUND if no event has been found.
88 *
89 * @returns VBox status code.
90 * @param uTimeoutMs Timeout (in ms) to wait.
91 */
92int SharedClipboardProviderHostService::Event::Wait(RTMSINTERVAL uTimeoutMs)
93{
94 LogFlowFuncEnter();
95
96 int rc = RTSemEventWait(mEvent, uTimeoutMs);
97
98 LogFlowFuncLeaveRC(rc);
99 return rc;
100}
101
102/**
103 * Returns the event's (raw) data (mutable).
104 *
105 * @returns Pointer to the event's raw data.
106 */
107void *SharedClipboardProviderHostService::Event::DataRaw()
108{
109 return mpvData;
110}
111
112/**
113 * Returns the event's data size (in bytes).
114 *
115 * @returns Data size (in bytes).
116 */
117uint32_t SharedClipboardProviderHostService::Event::DataSize()
118{
119 return mcbData;
120}
121
122SharedClipboardProviderHostService::SharedClipboardProviderHostService(void)
123 : m_uTimeoutMs(30 * 1000 /* 30s timeout by default */)
124{
125 LogFlowFuncEnter();
126}
127
128SharedClipboardProviderHostService::~SharedClipboardProviderHostService(void)
129{
130 Reset();
131}
132
133int SharedClipboardProviderHostService::ReadDataHdr(PVBOXCLIPBOARDDATAHDR pDataHdr)
134{
135 int rc;
136
137 if (m_Callbacks.pfnReadDataHdr)
138 {
139 SHAREDCLIPBOARDPROVIDERCALLBACKDATA data = { this, m_Callbacks.pvUser };
140 rc = m_Callbacks.pfnReadDataHdr(&data);
141 }
142 else
143 rc = VERR_NOT_SUPPORTED;
144
145 if (RT_SUCCESS(rc))
146 {
147 Event *pEvent = eventGet(VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_DATA_HDR);
148 if (pEvent)
149 {
150 rc = pEvent->Wait(m_uTimeoutMs);
151 if (RT_SUCCESS(rc))
152 memcpy(pDataHdr, pEvent->DataRaw(), pEvent->DataSize());
153 }
154 else
155 rc = VERR_NOT_FOUND;
156 }
157
158 LogFlowFuncLeaveRC(rc);
159 return rc;
160}
161
162int SharedClipboardProviderHostService::WriteDataHdr(const PVBOXCLIPBOARDDATAHDR pDataHdr)
163{
164 RT_NOREF(pDataHdr);
165 return VERR_NOT_IMPLEMENTED;
166}
167
168int SharedClipboardProviderHostService::ReaaDataChunk(const PVBOXCLIPBOARDDATAHDR pDataHdr, void *pvChunk, uint32_t cbChunk,
169 uint32_t *pcbRead, uint32_t fFlags /* = 0 */)
170{
171 RT_NOREF(pDataHdr, pvChunk, cbChunk, pcbRead, fFlags);
172 return VERR_NOT_IMPLEMENTED;
173}
174
175int SharedClipboardProviderHostService::WriteDataChunk(const PVBOXCLIPBOARDDATAHDR pDataHdr, const void *pvMeta, uint32_t cbMeta,
176 uint32_t *pcbWritten, uint32_t fFlags /* = 0 */)
177{
178 RT_NOREF(pDataHdr, pvMeta, cbMeta, pcbWritten, fFlags);
179 return VERR_NOT_IMPLEMENTED;
180}
181
182int SharedClipboardProviderHostService::ReadDirectory(PVBOXCLIPBOARDDIRDATA pDirData)
183{
184 RT_NOREF(pDirData);
185
186 LogFlowFuncEnter();
187
188 int rc = VERR_NOT_IMPLEMENTED;
189
190 LogFlowFuncLeaveRC(rc);
191 return rc;
192}
193
194int SharedClipboardProviderHostService::WriteDirectory(const PVBOXCLIPBOARDDIRDATA pDirData)
195{
196 RT_NOREF(pDirData);
197
198 LogFlowFuncEnter();
199
200 int rc = VERR_NOT_IMPLEMENTED;
201
202 LogFlowFuncLeaveRC(rc);
203 return rc;
204}
205
206int SharedClipboardProviderHostService::ReadFileHdr(PVBOXCLIPBOARDFILEHDR pFileHdr)
207{
208 RT_NOREF(pFileHdr);
209
210 LogFlowFuncEnter();
211
212 int rc = VERR_NOT_IMPLEMENTED;
213
214 LogFlowFuncLeaveRC(rc);
215 return rc;
216}
217
218int SharedClipboardProviderHostService::WriteFileHdr(const PVBOXCLIPBOARDFILEHDR pFileHdr)
219{
220 RT_NOREF(pFileHdr);
221
222 LogFlowFuncEnter();
223
224 int rc = VERR_NOT_IMPLEMENTED;
225
226 LogFlowFuncLeaveRC(rc);
227 return rc;
228}
229
230int SharedClipboardProviderHostService::ReadFileData(PVBOXCLIPBOARDFILEDATA pFileData, uint32_t *pcbRead)
231{
232 RT_NOREF(pFileData, pcbRead);
233
234 LogFlowFuncEnter();
235
236 int rc = VERR_NOT_IMPLEMENTED;
237
238 LogFlowFuncLeaveRC(rc);
239 return rc;
240}
241
242int SharedClipboardProviderHostService::WriteFileData(const PVBOXCLIPBOARDFILEDATA pFileData, uint32_t *pcbWritten)
243{
244 RT_NOREF(pFileData, pcbWritten);
245
246 LogFlowFuncEnter();
247
248 int rc = VERR_NOT_IMPLEMENTED;
249
250 LogFlowFuncLeaveRC(rc);
251 return rc;
252}
253
254void SharedClipboardProviderHostService::Reset(void)
255{
256 LogFlowFuncEnter();
257
258 EventMap::const_iterator itEvent = m_mapEvents.begin();
259 while (itEvent != m_mapEvents.end())
260 {
261 delete itEvent->second;
262 m_mapEvents.erase(itEvent);
263
264 itEvent = m_mapEvents.begin();
265 }
266
267 int rc2 = eventRegister(VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_DATA_HDR);
268 AssertRC(rc2);
269}
270
271int SharedClipboardProviderHostService::OnRead(PSHAREDCLIPBOARDPROVIDERREADPARMS pParms)
272{
273 RT_NOREF(pParms);
274
275 LogFlowFuncEnter();
276
277 int rc = VERR_NOT_IMPLEMENTED;
278
279 LogFlowFuncLeaveRC(rc);
280 return rc;
281}
282
283int SharedClipboardProviderHostService::OnWrite(PSHAREDCLIPBOARDPROVIDERWRITEPARMS pParms)
284{
285 LogFlowFuncEnter();
286
287 int rc = VINF_SUCCESS;
288
289 switch (pParms->u.HostService.uMsg)
290 {
291 case VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_DATA_HDR:
292 {
293 VBOXCLIPBOARDDATAHDR dataHdr;
294 rc = VBoxSvcClipboardURIReadDataHdr(pParms->u.HostService.cParms, pParms->u.HostService.paParms,
295 &dataHdr);
296 if (RT_SUCCESS(rc))
297 {
298 Event *pEvent = eventGet(pParms->u.HostService.uMsg);
299 if (pEvent)
300 rc = pEvent->SetData(&dataHdr, sizeof(dataHdr));
301 }
302 break;
303 }
304 case VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_DATA_CHUNK:
305 {
306 break;
307 }
308 case VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_DIR:
309 RT_FALL_THROUGH();
310 case VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_FILE_HDR:
311 RT_FALL_THROUGH();
312 case VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_FILE_DATA:
313 RT_FALL_THROUGH();
314 case VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_CANCEL:
315 RT_FALL_THROUGH();
316 case VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_ERROR:
317 {
318
319 }
320
321 default:
322 rc = VERR_NOT_IMPLEMENTED;
323 break;
324 }
325
326 if (RT_SUCCESS(rc))
327 {
328 rc = eventSignal(pParms->u.HostService.uMsg);
329 if (rc == VERR_NOT_FOUND) /* Having an event is optional, so don't fail here. */
330 rc = VINF_SUCCESS;
331 }
332
333 LogFlowFuncLeaveRC(rc);
334 return rc;
335}
336
337/**
338 * Registers a new event.
339 * Will fail if an event with the same message ID already exists.
340 *
341 * @returns VBox status code.
342 * @param uMsg Message ID to register event for.
343 */
344int SharedClipboardProviderHostService::eventRegister(uint32_t uMsg)
345{
346 LogFlowFuncEnter();
347
348 int rc;
349
350 EventMap::const_iterator itEvent = m_mapEvents.find(uMsg);
351 if (itEvent == m_mapEvents.end())
352 {
353 SharedClipboardProviderHostService::Event *pEvent = new SharedClipboardProviderHostService::Event(uMsg);
354 if (pEvent) /** @todo Can this throw? */
355 {
356 rc = VINF_SUCCESS;
357 }
358 else
359 rc = VERR_NO_MEMORY;
360 }
361 else
362 rc = VERR_ALREADY_EXISTS;
363
364 LogFlowFuncLeaveRC(rc);
365 return rc;
366}
367
368/**
369 * Unregisters an existing event.
370 * Will return VERR_NOT_FOUND if no event has been found.
371 *
372 * @returns VBox status code.
373 * @param uMsg Message ID to unregister event for.
374 */
375int SharedClipboardProviderHostService::eventUnregister(uint32_t uMsg)
376{
377 LogFlowFuncEnter();
378
379 int rc;
380
381 EventMap::const_iterator itEvent = m_mapEvents.find(uMsg);
382 if (itEvent != m_mapEvents.end())
383 {
384 delete itEvent->second;
385 m_mapEvents.erase(itEvent);
386
387 rc = VINF_SUCCESS;
388 }
389 else
390 rc = VERR_NOT_FOUND;
391
392 LogFlowFuncLeaveRC(rc);
393 return rc;
394}
395
396/**
397 * Signals an event.
398 * Will return VERR_NOT_FOUND if no event has been found.
399 *
400 * @returns VBox status code.
401 * @param uMsg Message ID of event to signal.
402 */
403int SharedClipboardProviderHostService::eventSignal(uint32_t uMsg)
404{
405 LogFlowFuncEnter();
406
407 int rc;
408
409 EventMap::const_iterator itEvent = m_mapEvents.find(uMsg);
410 if (itEvent != m_mapEvents.end())
411 {
412 rc = RTSemEventSignal(itEvent->second->mEvent);
413 }
414 else
415 rc = VERR_NOT_FOUND;
416
417 LogFlowFuncLeaveRC(rc);
418 return rc;
419}
420
421/**
422 * Returns the event for a specific message ID.
423 *
424 * @returns Pointer to event if found, or NULL if no event has been found
425 * @param uMsg Messagae ID to return event for.
426 */
427SharedClipboardProviderHostService::Event *SharedClipboardProviderHostService::eventGet(uint32_t uMsg)
428{
429 LogFlowFuncEnter();
430
431 EventMap::const_iterator itEvent = m_mapEvents.find(uMsg);
432 if (itEvent != m_mapEvents.end())
433 return itEvent->second;
434
435 return NULL;
436}
437
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