VirtualBox

source: vbox/trunk/src/VBox/GuestHost/SharedClipboard/ClipboardProvider-HostService.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: 10.2 KB
Line 
1/* $Id: ClipboardProvider-HostService.cpp 79120 2019-06-13 10:08:33Z 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
102void *SharedClipboardProviderHostService::Event::DataRaw()
103{
104 return mpvData;
105}
106
107uint32_t SharedClipboardProviderHostService::Event::DataSize()
108{
109 return mcbData;
110}
111
112SharedClipboardProviderHostService::SharedClipboardProviderHostService(void)
113 : m_uTimeoutMs(30 * 1000 /* 30s timeout by default */)
114{
115 LogFlowFuncEnter();
116}
117
118SharedClipboardProviderHostService::~SharedClipboardProviderHostService(void)
119{
120 Reset();
121}
122
123int SharedClipboardProviderHostService::ReadDataHdr(PVBOXCLIPBOARDDATAHDR pDataHdr)
124{
125 int rc;
126
127 Event *pEvent = eventGet(VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_DATA_HDR);
128 if (pEvent)
129 {
130 rc = pEvent->Wait(m_uTimeoutMs);
131 if (RT_SUCCESS(rc))
132 memcpy(pDataHdr, pEvent->DataRaw(), pEvent->DataSize());
133 }
134 else
135 rc = VERR_NOT_FOUND;
136
137 LogFlowFuncLeaveRC(rc);
138 return rc;
139}
140
141int SharedClipboardProviderHostService::WriteDataHdr(const PVBOXCLIPBOARDDATAHDR pDataHdr)
142{
143 RT_NOREF(pDataHdr);
144 return VERR_NOT_IMPLEMENTED;
145}
146
147int SharedClipboardProviderHostService::ReaaDataChunk(const PVBOXCLIPBOARDDATAHDR pDataHdr, void *pvChunk, uint32_t cbChunk,
148 uint32_t *pcbRead, uint32_t fFlags /* = 0 */)
149{
150 RT_NOREF(pDataHdr, pvChunk, cbChunk, pcbRead, fFlags);
151 return VERR_NOT_IMPLEMENTED;
152}
153
154int SharedClipboardProviderHostService::WriteDataChunk(const PVBOXCLIPBOARDDATAHDR pDataHdr, const void *pvMeta, uint32_t cbMeta,
155 uint32_t *pcbWritten, uint32_t fFlags /* = 0 */)
156{
157 RT_NOREF(pDataHdr, pvMeta, cbMeta, pcbWritten, fFlags);
158 return VERR_NOT_IMPLEMENTED;
159}
160
161int SharedClipboardProviderHostService::ReadDirectory(PVBOXCLIPBOARDDIRDATA pDirData)
162{
163 RT_NOREF(pDirData);
164
165 LogFlowFuncEnter();
166
167 int rc = VERR_NOT_IMPLEMENTED;
168
169 LogFlowFuncLeaveRC(rc);
170 return rc;
171}
172
173int SharedClipboardProviderHostService::WriteDirectory(const PVBOXCLIPBOARDDIRDATA pDirData)
174{
175 RT_NOREF(pDirData);
176
177 LogFlowFuncEnter();
178
179 int rc = VERR_NOT_IMPLEMENTED;
180
181 LogFlowFuncLeaveRC(rc);
182 return rc;
183}
184
185int SharedClipboardProviderHostService::ReadFileHdr(PVBOXCLIPBOARDFILEHDR pFileHdr)
186{
187 RT_NOREF(pFileHdr);
188
189 LogFlowFuncEnter();
190
191 int rc = VERR_NOT_IMPLEMENTED;
192
193 LogFlowFuncLeaveRC(rc);
194 return rc;
195}
196
197int SharedClipboardProviderHostService::WriteFileHdr(const PVBOXCLIPBOARDFILEHDR pFileHdr)
198{
199 RT_NOREF(pFileHdr);
200
201 LogFlowFuncEnter();
202
203 int rc = VERR_NOT_IMPLEMENTED;
204
205 LogFlowFuncLeaveRC(rc);
206 return rc;
207}
208
209int SharedClipboardProviderHostService::ReadFileData(PVBOXCLIPBOARDFILEDATA pFileData, uint32_t *pcbRead)
210{
211 RT_NOREF(pFileData, pcbRead);
212
213 LogFlowFuncEnter();
214
215 int rc = VERR_NOT_IMPLEMENTED;
216
217 LogFlowFuncLeaveRC(rc);
218 return rc;
219}
220
221int SharedClipboardProviderHostService::WriteFileData(const PVBOXCLIPBOARDFILEDATA pFileData, uint32_t *pcbWritten)
222{
223 RT_NOREF(pFileData, pcbWritten);
224
225 LogFlowFuncEnter();
226
227 int rc = VERR_NOT_IMPLEMENTED;
228
229 LogFlowFuncLeaveRC(rc);
230 return rc;
231}
232
233void SharedClipboardProviderHostService::Reset(void)
234{
235 LogFlowFuncEnter();
236
237 EventMap::const_iterator itEvent = m_mapEvents.begin();
238 while (itEvent != m_mapEvents.end())
239 {
240 delete itEvent->second;
241 m_mapEvents.erase(itEvent);
242
243 itEvent = m_mapEvents.begin();
244 }
245
246 int rc2 = eventRegister(VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_DATA_HDR);
247 AssertRC(rc2);
248}
249
250int SharedClipboardProviderHostService::OnRead(PSHAREDCLIPBOARDPROVIDERREADPARMS pParms)
251{
252 RT_NOREF(pParms);
253
254 LogFlowFuncEnter();
255
256 int rc = VERR_NOT_IMPLEMENTED;
257
258 LogFlowFuncLeaveRC(rc);
259 return rc;
260}
261
262int SharedClipboardProviderHostService::OnWrite(PSHAREDCLIPBOARDPROVIDERWRITEPARMS pParms)
263{
264 LogFlowFuncEnter();
265
266 int rc = VINF_SUCCESS;
267
268 switch (pParms->u.HostService.uMsg)
269 {
270 case VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_DATA_HDR:
271 {
272 VBOXCLIPBOARDDATAHDR dataHdr;
273 rc = VBoxSvcClipboardURIReadDataHdr(pParms->u.HostService.cParms, pParms->u.HostService.paParms,
274 &dataHdr);
275 if (RT_SUCCESS(rc))
276 {
277 Event *pEvent = eventGet(pParms->u.HostService.uMsg);
278 if (pEvent)
279 {
280 rc = pEvent->SetData(&dataHdr, sizeof(dataHdr));
281 }
282 }
283 break;
284 }
285 case VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_DATA_CHUNK:
286 {
287 break;
288 }
289 case VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_DIR:
290 RT_FALL_THROUGH();
291 case VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_FILE_HDR:
292 RT_FALL_THROUGH();
293 case VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_FILE_DATA:
294 RT_FALL_THROUGH();
295 case VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_CANCEL:
296 RT_FALL_THROUGH();
297 case VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_ERROR:
298 {
299
300 }
301
302 default:
303 rc = VERR_NOT_IMPLEMENTED;
304 break;
305 }
306
307 if (RT_SUCCESS(rc))
308 {
309 rc = eventSignal(pParms->u.HostService.uMsg);
310 if (rc == VERR_NOT_FOUND) /* Having an event is optional, so don't fail here. */
311 rc = VINF_SUCCESS;
312 }
313
314 LogFlowFuncLeaveRC(rc);
315 return rc;
316}
317
318/**
319 * Registers a new event.
320 * Will fail if an event with the same message ID already exists.
321 *
322 * @returns VBox status code.
323 * @param uMsg Message ID to register event for.
324 */
325int SharedClipboardProviderHostService::eventRegister(uint32_t uMsg)
326{
327 LogFlowFuncEnter();
328
329 int rc;
330
331 EventMap::const_iterator itEvent = m_mapEvents.find(uMsg);
332 if (itEvent == m_mapEvents.end())
333 {
334 SharedClipboardProviderHostService::Event *pEvent = new SharedClipboardProviderHostService::Event(uMsg);
335 if (pEvent) /** @todo Can this throw? */
336 {
337 rc = VINF_SUCCESS;
338 }
339 else
340 rc = VERR_NO_MEMORY;
341 }
342 else
343 rc = VERR_ALREADY_EXISTS;
344
345 LogFlowFuncLeaveRC(rc);
346 return rc;
347}
348
349/**
350 * Unregisters an existing event.
351 * Will return VERR_NOT_FOUND if no event has been found.
352 *
353 * @returns VBox status code.
354 * @param uMsg Message ID to unregister event for.
355 */
356int SharedClipboardProviderHostService::eventUnregister(uint32_t uMsg)
357{
358 LogFlowFuncEnter();
359
360 int rc;
361
362 EventMap::const_iterator itEvent = m_mapEvents.find(uMsg);
363 if (itEvent != m_mapEvents.end())
364 {
365 delete itEvent->second;
366 m_mapEvents.erase(itEvent);
367
368 rc = VINF_SUCCESS;
369 }
370 else
371 rc = VERR_NOT_FOUND;
372
373 LogFlowFuncLeaveRC(rc);
374 return rc;
375}
376
377/**
378 * Signals an event.
379 * Will return VERR_NOT_FOUND if no event has been found.
380 *
381 * @returns VBox status code.
382 * @param uMsg Message ID of event to signal.
383 */
384int SharedClipboardProviderHostService::eventSignal(uint32_t uMsg)
385{
386 LogFlowFuncEnter();
387
388 int rc;
389
390 EventMap::const_iterator itEvent = m_mapEvents.find(uMsg);
391 if (itEvent != m_mapEvents.end())
392 {
393 rc = RTSemEventSignal(itEvent->second->mEvent);
394 }
395 else
396 rc = VERR_NOT_FOUND;
397
398 LogFlowFuncLeaveRC(rc);
399 return rc;
400}
401
402/**
403 * Returns the event for a specific message ID.
404 *
405 * @returns Pointer to event if found, or NULL if no event has been found
406 * @param uMsg Messagae ID to return event for.
407 */
408SharedClipboardProviderHostService::Event *SharedClipboardProviderHostService::eventGet(uint32_t uMsg)
409{
410 LogFlowFuncEnter();
411
412 EventMap::const_iterator itEvent = m_mapEvents.find(uMsg);
413 if (itEvent != m_mapEvents.end())
414 return itEvent->second;
415
416 return NULL;
417}
418
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