VirtualBox

source: vbox/trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibClipboard.cpp@ 79672

Last change on this file since 79672 was 79672, checked in by vboxsync, 6 years ago

Shared Clipboard/URI: More code for root entries handling.

  • Property svn:eol-style set to native
  • Property svn:keyword set to Id
  • Property svn:keywords set to Author Date Id Revision
File size: 39.4 KB
Line 
1/* $Id: VBoxGuestR3LibClipboard.cpp 79672 2019-07-10 13:02:50Z vboxsync $ */
2/** @file
3 * VBoxGuestR3Lib - Ring-3 Support Library for VirtualBox guest additions, Shared Clipboard.
4 */
5
6/*
7 * Copyright (C) 2007-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 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include <VBox/GuestHost/SharedClipboard.h>
32#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
33# include <VBox/GuestHost/SharedClipboard-uri.h>
34#endif
35#include <VBox/HostServices/VBoxClipboardSvc.h>
36#include <VBox/err.h>
37#include <iprt/assert.h>
38#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
39# include <iprt/dir.h>
40# include <iprt/file.h>
41# include <iprt/path.h>
42#endif
43#include <iprt/string.h>
44#include <iprt/cpp/ministring.h>
45
46#include "VBoxGuestR3LibInternal.h"
47
48
49/*********************************************************************************************************************************
50* Prototypes *
51*********************************************************************************************************************************/
52
53
54/**
55 * Connects to the clipboard service.
56 *
57 * @returns VBox status code
58 * @param pidClient Where to put the client id on success. The client id
59 * must be passed to all the other clipboard calls.
60 */
61VBGLR3DECL(int) VbglR3ClipboardConnect(HGCMCLIENTID *pidClient)
62{
63 int rc = VbglR3HGCMConnect("VBoxSharedClipboard", pidClient);
64 if (rc == VERR_HGCM_SERVICE_NOT_FOUND)
65 rc = VINF_PERMISSION_DENIED;
66
67 LogFlowFuncLeaveRC(rc);
68 return rc;
69}
70
71
72/**
73 * Disconnect from the clipboard service.
74 *
75 * @returns VBox status code.
76 * @param idClient The client id returned by VbglR3ClipboardConnect().
77 */
78VBGLR3DECL(int) VbglR3ClipboardDisconnect(HGCMCLIENTID idClient)
79{
80 return VbglR3HGCMDisconnect(idClient);
81}
82
83
84/**
85 * Get a host message, old version.
86 *
87 * Note: This is the old message which still is being used for the non-URI Shared Clipboard transfers,
88 * to not break compatibility with older additions / VBox versions.
89 *
90 * This will block until a message becomes available.
91 *
92 * @returns VBox status code.
93 * @param idClient The client id returned by VbglR3ClipboardConnect().
94 * @param pidMsg Where to store the message id.
95 * @param pfFormats Where to store the format(s) the message applies to.
96 */
97VBGLR3DECL(int) VbglR3ClipboardGetHostMsgOld(HGCMCLIENTID idClient, uint32_t *pidMsg, uint32_t *pfFormats)
98{
99 VBoxClipboardGetHostMsgOld Msg;
100
101 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
102 VBOX_SHARED_CLIPBOARD_GUEST_FN_GET_HOST_MSG_OLD, VBOX_SHARED_CLIPBOARD_CPARMS_GET_HOST_MSG_OLD);
103
104 VbglHGCMParmUInt32Set(&Msg.msg, 0);
105 VbglHGCMParmUInt32Set(&Msg.formats, 0);
106
107 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
108 if (RT_SUCCESS(rc))
109 {
110 int rc2 = VbglHGCMParmUInt32Get(&Msg.msg, pidMsg);
111 if (RT_SUCCESS(rc))
112 {
113 rc2 = VbglHGCMParmUInt32Get(&Msg.formats, pfFormats);
114 if (RT_SUCCESS(rc2))
115 return rc;
116 }
117 rc = rc2;
118 }
119 *pidMsg = UINT32_MAX - 1;
120 *pfFormats = UINT32_MAX;
121 return rc;
122}
123
124
125/**
126 * Reads data from the host clipboard.
127 *
128 * @returns VBox status code.
129 * @retval VINF_BUFFER_OVERFLOW If there is more data available than the caller provided buffer space for.
130 *
131 * @param idClient The client id returned by VbglR3ClipboardConnect().
132 * @param fFormat The format we're requesting the data in.
133 * @param pv Where to store the data.
134 * @param cb The size of the buffer pointed to by pv.
135 * @param pcb The actual size of the host clipboard data. May be larger than cb.
136 */
137VBGLR3DECL(int) VbglR3ClipboardReadData(HGCMCLIENTID idClient, uint32_t fFormat, void *pv, uint32_t cb, uint32_t *pcb)
138{
139 VBoxClipboardReadDataMsg Msg;
140
141 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_GUEST_FN_READ_DATA, VBOX_SHARED_CLIPBOARD_CPARMS_READ_DATA);
142 VbglHGCMParmUInt32Set(&Msg.format, fFormat);
143 VbglHGCMParmPtrSet(&Msg.ptr, pv, cb);
144 VbglHGCMParmUInt32Set(&Msg.size, 0);
145
146 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
147 if (RT_SUCCESS(rc))
148 {
149 uint32_t cbActual;
150 int rc2 = VbglHGCMParmUInt32Get(&Msg.size, &cbActual);
151 if (RT_SUCCESS(rc2))
152 {
153 *pcb = cbActual;
154 if (cbActual > cb)
155 return VINF_BUFFER_OVERFLOW;
156 return rc;
157 }
158 rc = rc2;
159 }
160 return rc;
161}
162
163#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
164#if 0
165static int vbglR3ClipboardPeekMsg(HGCMCLIENTID idClient, uint32_t *puMsg, uint32_t *pcParms, bool fWait)
166{
167 AssertPtrReturn(puMsg, VERR_INVALID_POINTER);
168 AssertPtrReturn(pcParms, VERR_INVALID_POINTER);
169
170 VBoxClipboardPeekMsg Msg;
171 RT_ZERO(Msg);
172
173 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
174 VBOX_SHARED_CLIPBOARD_GUEST_FN_GET_HOST_MSG, VBOX_SHARED_CLIPBOARD_CPARMS_GET_HOST_MSG);
175
176 Msg.uMsg.SetUInt32(0);
177 Msg.cParms.SetUInt32(0);
178 Msg.fBlock.SetUInt32(fWait ? 1 : 0);
179
180 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
181 if (RT_SUCCESS(rc))
182 {
183 rc = Msg.uMsg.GetUInt32(puMsg);
184 if (RT_SUCCESS(rc))
185 rc = Msg.cParms.GetUInt32(pcParms);
186 }
187
188 LogFlowFuncLeaveRC(rc);
189 return rc;
190}
191#else
192/**
193 * Peeks at the next host message, waiting for one to turn up.
194 *
195 * @returns VBox status code.
196 * @retval VERR_INTERRUPTED if interrupted. Does the necessary cleanup, so
197 * caller just have to repeat this call.
198 * @retval VERR_VM_RESTORED if the VM has been restored (idRestoreCheck).
199 *
200 * @param idClient The client ID returned by VbglR3GuestCtrlConnect().
201 * @param pidMsg Where to store the message id.
202 * @param pcParameters Where to store the number of parameters which will
203 * be received in a second call to the host.
204 * @param pidRestoreCheck Pointer to the VbglR3GetSessionId() variable to use
205 * for the VM restore check. Optional.
206 *
207 * @note Restore check is only performed optimally with a 6.0 host.
208 */
209static int vbglR3ClipboardMsgPeekWait(uint32_t idClient, uint32_t *pidMsg, uint32_t *pcParameters, uint64_t *pidRestoreCheck)
210{
211 AssertPtrReturn(pidMsg, VERR_INVALID_POINTER);
212 AssertPtrReturn(pcParameters, VERR_INVALID_POINTER);
213
214 int rc;
215
216 struct
217 {
218 VBGLIOCHGCMCALL Hdr;
219 HGCMFunctionParameter idMsg; /* Doubles as restore check on input. */
220 HGCMFunctionParameter cParameters;
221 } Msg;
222 VBGL_HGCM_HDR_INIT(&Msg.Hdr, idClient, VBOX_SHARED_CLIPBOARD_GUEST_FN_MSG_PEEK_WAIT, 2);
223 VbglHGCMParmUInt64Set(&Msg.idMsg, pidRestoreCheck ? *pidRestoreCheck : 0);
224 VbglHGCMParmUInt32Set(&Msg.cParameters, 0);
225 rc = VbglR3HGCMCall(&Msg.Hdr, sizeof(Msg));
226 LogRel2(("VbglR3GuestCtrlMsgPeekWait -> %Rrc\n", rc));
227 if (RT_SUCCESS(rc))
228 {
229 AssertMsgReturn( Msg.idMsg.type == VMMDevHGCMParmType_64bit
230 && Msg.cParameters.type == VMMDevHGCMParmType_32bit,
231 ("msg.type=%d num_parms.type=%d\n", Msg.idMsg.type, Msg.cParameters.type),
232 VERR_INTERNAL_ERROR_3);
233
234 *pidMsg = (uint32_t)Msg.idMsg.u.value64;
235 *pcParameters = Msg.cParameters.u.value32;
236 return rc;
237 }
238
239 /*
240 * If interrupted we must cancel the call so it doesn't prevent us from making another one.
241 */
242 if (rc == VERR_INTERRUPTED)
243 {
244 VBGL_HGCM_HDR_INIT(&Msg.Hdr, idClient, VBOX_SHARED_CLIPBOARD_GUEST_FN_CANCEL, 0);
245 int rc2 = VbglR3HGCMCall(&Msg.Hdr, sizeof(Msg.Hdr));
246 AssertRC(rc2);
247 }
248
249 /*
250 * If restored, update pidRestoreCheck.
251 */
252 if (rc == VERR_VM_RESTORED && pidRestoreCheck)
253 *pidRestoreCheck = Msg.idMsg.u.value64;
254
255 *pidMsg = UINT32_MAX - 1;
256 *pcParameters = UINT32_MAX - 2;
257 return rc;
258}
259#endif
260
261VBGLR3DECL(int) VbglR3ClipboardTransferSendStatus(HGCMCLIENTID idClient, SHAREDCLIPBOARDURITRANSFERSTATUS uStatus)
262{
263 VBoxClipboardStatusMsg Msg;
264 RT_ZERO(Msg);
265
266 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
267 VBOX_SHARED_CLIPBOARD_GUEST_FN_STATUS, VBOX_SHARED_CLIPBOARD_CPARMS_STATUS);
268
269 Msg.uContext.SetUInt32(0); /** @todo Context ID not used yet. */
270 Msg.uStatus.SetUInt32(uStatus);
271 Msg.cbPayload.SetUInt32(0);
272 Msg.pvPayload.SetPtr(NULL, 0);
273
274 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
275
276 LogFlowFuncLeaveRC(rc);
277 return rc;
278}
279
280VBGLR3DECL(int) VbglR3ClipboardRootsRecv(HGCMCLIENTID idClient, PVBOXCLIPBOARDROOTS pRoots)
281{
282 AssertPtrReturn(pRoots, VERR_INVALID_POINTER);
283
284 VBoxClipboardRootsMsg Msg;
285 RT_ZERO(Msg);
286
287 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
288 VBOX_SHARED_CLIPBOARD_GUEST_FN_MSG_GET, VBOX_SHARED_CLIPBOARD_CPARMS_ROOTS);
289
290 Msg.uContext.SetUInt32(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_ROOTS);
291 Msg.fRoots.SetUInt32(0);
292 Msg.fMore.SetUInt32(0);
293 Msg.cRoots.SetUInt32(0);
294 Msg.cbRoots.SetUInt32(pRoots->cbRoots);
295 Msg.pvRoots.SetPtr((void *)pRoots->pszRoots, pRoots->cbRoots);
296
297 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
298 if (RT_SUCCESS(rc))
299 {
300 uint32_t fMore;
301 rc = Msg.fMore.GetUInt32(&fMore); AssertRC(rc);
302 if (RT_SUCCESS(rc))
303 {
304 pRoots->fMore = RT_BOOL(fMore);
305 }
306 if (RT_SUCCESS(rc))
307 rc = Msg.fRoots.GetUInt32(&pRoots->fRoots); AssertRC(rc);
308 if (RT_SUCCESS(rc))
309 rc = Msg.cRoots.GetUInt32(&pRoots->cRoots); AssertRC(rc);
310 if (RT_SUCCESS(rc))
311 rc = Msg.cbRoots.GetUInt32(&pRoots->cbRoots); AssertRC(rc);
312 }
313
314 LogFlowFuncLeaveRC(rc);
315 return rc;
316}
317
318VBGLR3DECL(int) VbglR3ClipboardRootsWrite(HGCMCLIENTID idClient, uint32_t cRoots, char *papszList, uint32_t cbList)
319{
320 AssertPtrReturn(papszList, VERR_INVALID_POINTER);
321 AssertReturn(cbList, VERR_INVALID_PARAMETER);
322
323 VBoxClipboardRootsMsg Msg;
324 RT_ZERO(Msg);
325
326 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
327 VBOX_SHARED_CLIPBOARD_GUEST_FN_ROOTS, VBOX_SHARED_CLIPBOARD_CPARMS_ROOTS);
328
329 Msg.uContext.SetUInt32(0); /** @todo Context ID not used yet. */
330 Msg.fRoots.SetUInt32(0);
331 Msg.fMore.SetUInt32(0);
332 Msg.cRoots.SetUInt32(cRoots);
333 Msg.cbRoots.SetUInt32(cbList);
334 Msg.pvRoots.SetPtr(papszList, cbList);
335
336 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
337
338 LogFlowFuncLeaveRC(rc);
339 return rc;
340}
341
342VBGLR3DECL(int) VbglR3ClipboardListOpenSend(HGCMCLIENTID idClient, PVBOXCLIPBOARDLISTOPENPARMS pOpenParms,
343 PSHAREDCLIPBOARDLISTHANDLE phList)
344{
345 AssertPtrReturn(pOpenParms, VERR_INVALID_POINTER);
346 AssertPtrReturn(phList, VERR_INVALID_POINTER);
347
348 VBoxClipboardListOpenMsg Msg;
349 RT_ZERO(Msg);
350
351 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
352 VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_OPEN, VBOX_SHARED_CLIPBOARD_CPARMS_LIST_OPEN);
353
354 Msg.uContext.SetUInt32(0); /** @todo Context ID not used yet. */
355 Msg.fList.SetUInt32(0);
356 Msg.cbFilter.SetUInt32(pOpenParms->cbFilter);
357 Msg.pvFilter.SetPtr(pOpenParms->pszFilter, pOpenParms->cbFilter);
358 Msg.cbPath.SetUInt32(pOpenParms->cbPath);
359 Msg.pvFilter.SetPtr(pOpenParms->pszPath, pOpenParms->cbPath);
360
361 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
362 if (RT_SUCCESS(rc))
363 {
364 rc = Msg.uHandle.GetUInt64(phList); AssertRC(rc);
365 }
366
367 LogFlowFuncLeaveRC(rc);
368 return rc;
369}
370
371VBGLR3DECL(int) VbglR3ClipboardListOpenRecv(HGCMCLIENTID idClient, PVBOXCLIPBOARDLISTOPENPARMS pOpenParms)
372{
373 AssertPtrReturn(pOpenParms, VERR_INVALID_POINTER);
374
375 VBoxClipboardListOpenMsg Msg;
376 RT_ZERO(Msg);
377
378 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
379 VBOX_SHARED_CLIPBOARD_GUEST_FN_MSG_GET, VBOX_SHARED_CLIPBOARD_CPARMS_LIST_OPEN);
380
381 Msg.uContext.SetUInt32(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_OPEN);
382 Msg.fList.SetUInt32(0);
383 Msg.cbPath.SetUInt32(pOpenParms->cbPath);
384 Msg.pvPath.SetPtr(pOpenParms->pszPath, pOpenParms->cbPath);
385 Msg.cbFilter.SetUInt32(pOpenParms->cbFilter);
386 Msg.pvFilter.SetPtr(pOpenParms->pszFilter, pOpenParms->cbFilter);
387 Msg.uHandle.SetUInt64(0);
388
389 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
390 if (RT_SUCCESS(rc))
391 {
392 rc = Msg.fList.GetUInt32(&pOpenParms->fList);
393 if (RT_SUCCESS(rc))
394 rc = Msg.cbFilter.GetUInt32(&pOpenParms->cbFilter);
395 if (RT_SUCCESS(rc))
396 rc = Msg.cbPath.GetUInt32(&pOpenParms->cbPath);
397 }
398
399 LogFlowFuncLeaveRC(rc);
400 return rc;
401}
402
403VBGLR3DECL(int) VbglR3ClipboardListOpenReply(HGCMCLIENTID idClient, int rcReply, SHAREDCLIPBOARDLISTHANDLE hList)
404{
405 VBoxClipboardReplyMsg Msg;
406 RT_ZERO(Msg);
407
408 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
409 VBOX_SHARED_CLIPBOARD_GUEST_FN_REPLY, 6);
410
411 Msg.uContext.SetUInt32(0); /** @todo Context ID not used yet. */
412 Msg.enmType.SetUInt32(VBOX_SHAREDCLIPBOARD_REPLYMSGTYPE_LIST_OPEN);
413 Msg.rc.SetUInt32((uint32_t)rcReply); /** int vs. uint32_t */
414 Msg.cbPayload.SetUInt32(0);
415 Msg.pvPayload.SetPtr(0, NULL);
416
417 Msg.u.ListOpen.uHandle.SetUInt64(hList);
418
419 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
420
421 LogFlowFuncLeaveRC(rc);
422 return rc;
423}
424
425VBGLR3DECL(int) VbglR3ClipboardListCloseSend(HGCMCLIENTID idClient, SHAREDCLIPBOARDLISTHANDLE hList)
426{
427 VBoxClipboardListCloseMsg Msg;
428 RT_ZERO(Msg);
429
430 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
431 VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_CLOSE, VBOX_SHARED_CLIPBOARD_CPARMS_LIST_CLOSE);
432
433 Msg.uContext.SetUInt32(0); /** @todo Context ID not used yet. */
434 Msg.uHandle.SetUInt64(hList);
435
436 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
437
438 LogFlowFuncLeaveRC(rc);
439 return rc;
440}
441
442VBGLR3DECL(int) VbglR3ClipboardListCloseRecv(HGCMCLIENTID idClient, PSHAREDCLIPBOARDLISTHANDLE phList)
443{
444 AssertPtrReturn(phList, VERR_INVALID_POINTER);
445
446 VBoxClipboardListCloseMsg Msg;
447 RT_ZERO(Msg);
448
449 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
450 VBOX_SHARED_CLIPBOARD_GUEST_FN_MSG_GET, VBOX_SHARED_CLIPBOARD_CPARMS_LIST_CLOSE);
451
452 Msg.uContext.SetUInt32(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_CLOSE);
453 Msg.uHandle.SetUInt64(0);
454
455 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
456 if (RT_SUCCESS(rc))
457 {
458 rc = Msg.uHandle.GetUInt64(phList); AssertRC(rc);
459 }
460
461 LogFlowFuncLeaveRC(rc);
462 return rc;
463}
464
465VBGLR3DECL(int) VbglR3ClipboardListHdrRead(HGCMCLIENTID idClient, SHAREDCLIPBOARDLISTHANDLE hList, uint32_t fFlags,
466 PVBOXCLIPBOARDLISTHDR pListHdr)
467{
468 AssertPtrReturn(pListHdr, VERR_INVALID_POINTER);
469
470 VBoxClipboardListHdrMsg Msg;
471 RT_ZERO(Msg);
472
473 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
474 VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_HDR_READ, VBOX_SHARED_CLIPBOARD_CPARMS_LIST_HDR);
475
476 Msg.ReqParms.uContext.SetUInt32(0); /** @todo Context ID not used yet. */
477 Msg.ReqParms.uHandle.SetUInt64(hList);
478 Msg.ReqParms.fFlags.SetUInt32(fFlags);
479
480 Msg.fFeatures.SetUInt32(0);
481 Msg.cbTotalSize.SetUInt32(0);
482 Msg.cTotalObjects.SetUInt64(0);
483 Msg.cbTotalSize.SetUInt64(0);
484 Msg.enmCompression.SetUInt32(0);
485 Msg.enmChecksumType.SetUInt32(0);
486
487 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
488 if (RT_SUCCESS(rc))
489 {
490 rc = Msg.fFeatures.GetUInt32(&pListHdr->fFeatures);
491 if (RT_SUCCESS(rc))
492 rc = Msg.cTotalObjects.GetUInt64(&pListHdr->cTotalObjects);
493 if (RT_SUCCESS(rc))
494 rc = Msg.cbTotalSize.GetUInt64(&pListHdr->cbTotalSize);
495 if (RT_SUCCESS(rc))
496 rc = Msg.enmCompression.GetUInt32(&pListHdr->enmCompression);
497 if (RT_SUCCESS(rc))
498 rc = Msg.enmChecksumType.GetUInt32(&pListHdr->enmChecksumType);
499 }
500
501 LogFlowFuncLeaveRC(rc);
502 return rc;
503}
504
505VBGLR3DECL(int) VbglR3ClipboardListHdrReadRecvReq(HGCMCLIENTID idClient, PSHAREDCLIPBOARDLISTHANDLE phList, uint32_t *pfFlags)
506{
507 AssertPtrReturn(phList, VERR_INVALID_POINTER);
508 AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
509
510 VBoxClipboardListHdrReadReqMsg Msg;
511 RT_ZERO(Msg);
512
513 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
514 VBOX_SHARED_CLIPBOARD_GUEST_FN_MSG_GET, VBOX_SHARED_CLIPBOARD_CPARMS_LIST_HDR_READ_REQ);
515
516 Msg.ReqParms.uContext.SetUInt32(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_HDR_READ);
517 Msg.ReqParms.uHandle.SetUInt64(0);
518 Msg.ReqParms.fFlags.SetUInt32(0);
519
520 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
521 if (RT_SUCCESS(rc))
522 {
523 if (RT_SUCCESS(rc))
524 rc = Msg.ReqParms.uHandle.GetUInt64(phList);
525 if (RT_SUCCESS(rc))
526 rc = Msg.ReqParms.fFlags.GetUInt32(pfFlags);
527 }
528
529 LogFlowFuncLeaveRC(rc);
530 return rc;
531}
532
533VBGLR3DECL(int) VbglR3ClipboardListHdrWrite(HGCMCLIENTID idClient, SHAREDCLIPBOARDLISTHANDLE hList,
534 PVBOXCLIPBOARDLISTHDR pListHdr)
535{
536 AssertPtrReturn(pListHdr, VERR_INVALID_POINTER);
537
538 VBoxClipboardListHdrMsg Msg;
539 RT_ZERO(Msg);
540
541 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
542 VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_HDR_WRITE, VBOX_SHARED_CLIPBOARD_CPARMS_LIST_HDR);
543
544 Msg.ReqParms.uContext.SetUInt32(0);
545 Msg.ReqParms.uHandle.SetUInt64(hList);
546 Msg.ReqParms.fFlags.SetUInt32(0);
547
548 Msg.fFeatures.SetUInt32(0);
549 Msg.cbTotalSize.SetUInt32(pListHdr->fFeatures);
550 Msg.cTotalObjects.SetUInt64(pListHdr->cTotalObjects);
551 Msg.cbTotalSize.SetUInt64(pListHdr->cbTotalSize);
552 Msg.enmCompression.SetUInt32(pListHdr->enmCompression);
553 Msg.enmChecksumType.SetUInt32(pListHdr->enmChecksumType);
554
555 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
556
557 LogFlowFuncLeaveRC(rc);
558 return rc;
559}
560
561VBGLR3DECL(int) VbglR3ClipboardListEntryRead(HGCMCLIENTID idClient, SHAREDCLIPBOARDLISTHANDLE hList,
562 PVBOXCLIPBOARDLISTENTRY pListEntry)
563{
564 AssertPtrReturn(pListEntry, VERR_INVALID_POINTER);
565
566 VBoxClipboardListEntryMsg Msg;
567 RT_ZERO(Msg);
568
569 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
570 VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_ENTRY_READ, VBOX_SHARED_CLIPBOARD_CPARMS_LIST_ENTRY);
571
572 Msg.ReqParms.uContext.SetUInt32(0); /** @todo Context ID not used yet. */
573 Msg.ReqParms.uHandle.SetUInt64(hList);
574 Msg.ReqParms.fInfo.SetUInt32(0);
575
576 Msg.szName.SetPtr(pListEntry->pszName, pListEntry->cbName);
577 Msg.cbInfo.SetUInt32(0);
578 Msg.pvInfo.SetPtr(pListEntry->pvInfo, pListEntry->cbInfo);
579
580 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
581 if (RT_SUCCESS(rc))
582 {
583 rc = Msg.cbInfo.GetUInt32(&pListEntry->cbInfo); AssertRC(rc);
584 }
585
586 LogFlowFuncLeaveRC(rc);
587 return rc;
588}
589
590VBGLR3DECL(int) VbglR3ClipboardListEntryReadRecvReq(HGCMCLIENTID idClient, PSHAREDCLIPBOARDLISTHANDLE phList, uint32_t *pfInfo)
591{
592 AssertPtrReturn(phList, VERR_INVALID_POINTER);
593 AssertPtrReturn(pfInfo, VERR_INVALID_POINTER);
594
595 VBoxClipboardListEntryReadReqMsg Msg;
596 RT_ZERO(Msg);
597
598 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
599 VBOX_SHARED_CLIPBOARD_GUEST_FN_MSG_GET, VBOX_SHARED_CLIPBOARD_CPARMS_LIST_ENTRY_READ_REQ);
600
601 Msg.ReqParms.uContext.SetUInt32(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_ENTRY_READ);
602 Msg.ReqParms.uHandle.SetUInt64(0);
603 Msg.ReqParms.fInfo.SetUInt32(0);
604
605 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
606 if (RT_SUCCESS(rc))
607 {
608 rc = Msg.ReqParms.uHandle.GetUInt64(phList); AssertRC(rc);
609 if (RT_SUCCESS(rc))
610 rc = Msg.ReqParms.fInfo.GetUInt32(pfInfo); AssertRC(rc);
611 }
612
613 LogFlowFuncLeaveRC(rc);
614 return rc;
615}
616
617VBGLR3DECL(int) VbglR3ClipboardListEntryWrite(HGCMCLIENTID idClient, SHAREDCLIPBOARDLISTHANDLE hList,
618 PVBOXCLIPBOARDLISTENTRY pListEntry)
619{
620 AssertPtrReturn(pListEntry, VERR_INVALID_POINTER);
621
622 VBoxClipboardListEntryMsg Msg;
623 RT_ZERO(Msg);
624
625 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
626 VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_ENTRY_WRITE, VBOX_SHARED_CLIPBOARD_CPARMS_LIST_ENTRY);
627
628 Msg.ReqParms.uContext.SetUInt32(0); /** @todo Context ID not used yet. */
629 Msg.ReqParms.uHandle.SetUInt64(hList);
630 Msg.ReqParms.fInfo.SetUInt32(pListEntry->fInfo);
631
632 Msg.szName.SetPtr(pListEntry->pszName, pListEntry->cbName);
633 Msg.cbInfo.SetUInt32(pListEntry->cbInfo);
634 Msg.pvInfo.SetPtr(pListEntry->pvInfo, pListEntry->cbInfo);
635
636 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
637
638 LogFlowFuncLeaveRC(rc);
639 return rc;
640}
641
642VBGLR3DECL(int) VbglR3ClipboardEventGetNext(HGCMCLIENTID idClient, PSHAREDCLIPBOARDURITRANSFER pTransfer,
643 PVBGLR3CLIPBOARDEVENT *ppEvent)
644{
645 AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
646 AssertPtrReturn(ppEvent, VERR_INVALID_POINTER);
647
648 PVBGLR3CLIPBOARDEVENT pEvent = (PVBGLR3CLIPBOARDEVENT)RTMemAllocZ(sizeof(VBGLR3CLIPBOARDEVENT));
649 if (!pEvent)
650 return VERR_NO_MEMORY;
651
652 uint32_t uMsg = 0;
653 uint32_t cParms = 0;
654 int rc = vbglR3ClipboardMsgPeekWait(idClient, &uMsg, &cParms, NULL /* pidRestoreCheck */);
655 if (RT_SUCCESS(rc))
656 {
657 LogFunc(("Handling uMsg=%RU32\n", uMsg));
658
659 switch (uMsg)
660 {
661#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
662 case VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_ROOTS:
663 {
664 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_ROOTS\n"));
665
666 VBOXCLIPBOARDROOTS Roots;
667 rc = SharedClipboardURIRootsInit(&Roots);
668 if (RT_SUCCESS(rc))
669 {
670 rc = VbglR3ClipboardRootsRecv(idClient, &Roots);
671 if (RT_SUCCESS(rc))
672 {
673 /** @todo Handle fFlags. */
674
675 char *pszRoots = NULL;
676 uint32_t cRoots = 0;
677 rc = SharedClipboardURILTransferGetRoots(pTransfer, &pszRoots, &cRoots);
678 if (RT_SUCCESS(rc))
679 {
680 /** @todo Split up transfers in _64K each. */
681
682 rc = VbglR3ClipboardRootsWrite(idClient, cRoots,
683 pszRoots, pszRoots ? (uint32_t)strlen(pszRoots) : NULL);
684 }
685 }
686 }
687
688 break;
689 }
690
691 case VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_OPEN:
692 {
693 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_OPEN\n"));
694
695 VBOXCLIPBOARDLISTOPENPARMS openParmsList;
696 rc = SharedClipboardURIListOpenParmsInit(&openParmsList);
697 if (RT_SUCCESS(rc))
698 {
699 rc = VbglR3ClipboardListOpenRecv(idClient, &openParmsList);
700 if (RT_SUCCESS(rc))
701 {
702 LogFlowFunc(("pszPath=%s\n", openParmsList.pszPath));
703
704 SHAREDCLIPBOARDLISTHANDLE hList = SHAREDCLIPBOARDLISTHANDLE_INVALID;
705 rc = SharedClipboardURITransferListOpen(pTransfer, &openParmsList, &hList);
706
707 /* Reply in any case. */
708 int rc2 = VbglR3ClipboardListOpenReply(idClient, rc, hList);
709 AssertRC(rc2);
710
711 SharedClipboardURIListOpenParmsDestroy(&openParmsList);
712 }
713 }
714
715 break;
716 }
717
718 case VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_CLOSE:
719 {
720 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_CLOSE\n"));
721
722 SHAREDCLIPBOARDLISTHANDLE hList;
723 rc = VbglR3ClipboardListCloseRecv(idClient, &hList);
724 if (RT_SUCCESS(rc))
725 {
726 rc = SharedClipboardURITransferListClose(pTransfer, hList);
727 }
728
729 break;
730 }
731
732 case VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_HDR_READ:
733 {
734 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_HDR_READ\n"));
735
736 /** @todo Handle filter + list features. */
737
738 SHAREDCLIPBOARDLISTHANDLE hList = SHAREDCLIPBOARDLISTHANDLE_INVALID;
739 uint32_t fFlags = 0;
740 rc = VbglR3ClipboardListHdrReadRecvReq(idClient, &hList, &fFlags);
741 if (RT_SUCCESS(rc))
742 {
743 VBOXCLIPBOARDLISTHDR hdrList;
744 rc = SharedClipboardURITransferListGetHeader(pTransfer, hList, &hdrList);
745 if (RT_SUCCESS(rc))
746 {
747 rc = VbglR3ClipboardListHdrWrite(idClient, hList, &hdrList);
748 SharedClipboardURIListHdrDestroy(&hdrList);
749 }
750 }
751
752 break;
753 }
754
755 #if 0
756 case VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_HDR_WRITE:
757 {
758 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_HDR_WRITE\n"));
759
760 VBOXCLIPBOARDLISTHDR hdrList;
761 rc = SharedClipboardURIListHdrInit(&hdrList);
762 if (RT_SUCCESS(rc))
763 {
764 rc = VBglR3ClipboardListHdrRecv(idClient, )
765 }
766 break;
767 }
768 #endif
769
770 case VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_ENTRY_READ:
771 {
772 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_ENTRY_READ\n"));
773
774 VBOXCLIPBOARDLISTENTRY entryList;
775 rc = SharedClipboardURIListEntryInit(&entryList);
776 if (RT_SUCCESS(rc))
777 {
778 SHAREDCLIPBOARDLISTHANDLE hList;
779 uint32_t fInfo;
780 rc = VbglR3ClipboardListEntryReadRecvReq(idClient, &hList, &fInfo);
781 if (RT_SUCCESS(rc))
782 {
783 rc = SharedClipboardURITransferListRead(pTransfer, hList, &entryList);
784 if (RT_SUCCESS(rc))
785 {
786 PSHAREDCLIPBOARDFSOBJINFO pObjInfo = (PSHAREDCLIPBOARDFSOBJINFO)entryList.pvInfo;
787 Assert(entryList.cbInfo == sizeof(SHAREDCLIPBOARDFSOBJINFO));
788
789 LogFlowFunc(("\t%s (%RU64 bytes)\n", entryList.pszName, pObjInfo->cbObject));
790
791 rc = VbglR3ClipboardListEntryWrite(idClient, hList, &entryList);
792 }
793 }
794
795 SharedClipboardURIListEntryDestroy(&entryList);
796 }
797
798 break;
799 }
800
801 #if 0
802 case VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_ENTRY_WRITE:
803 {
804 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_ENTRY_WRITE\n"));
805 pEvent->enmType = VBGLR3CLIPBOARDEVENTTYPE_URI_LIST_ENTRY_WRITE;
806 break;
807 }
808 #endif
809
810 case VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_OBJ_OPEN:
811 {
812 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_OBJ_OPEN\n"));
813 pEvent->enmType = VBGLR3CLIPBOARDEVENTTYPE_URI_OBJ_OPEN;
814 break;
815 }
816
817 case VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_OBJ_CLOSE:
818 {
819 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_OBJ_CLOSE\n"));
820 pEvent->enmType = VBGLR3CLIPBOARDEVENTTYPE_URI_OBJ_CLOSE;
821 break;
822 }
823
824 case VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_OBJ_READ:
825 {
826 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_OBJ_READ\n"));
827 pEvent->enmType = VBGLR3CLIPBOARDEVENTTYPE_URI_OBJ_READ;
828 break;
829 }
830
831 #if 0
832 case VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_OBJ_WRITE:
833 {
834 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_OBJ_WRITE\n"));
835 pEvent->enmType = VBGLR3CLIPBOARDEVENTTYPE_URI_OBJ_WRITE;
836 break;
837 }
838 #endif
839#endif /* VBOX_WITH_SHARED_CLIPBOARD_URI_LIST */
840
841 default:
842 rc = VERR_NOT_SUPPORTED;
843 break;
844 }
845 }
846
847 if (RT_SUCCESS(rc))
848 {
849 if (pEvent->enmType != VBGLR3CLIPBOARDEVENTTYPE_INVALID)
850 {
851 *ppEvent = pEvent;
852 }
853 else
854 VbglR3ClipboardEventFree(pEvent);
855 }
856 else
857 {
858 /* Report error back to the host. */
859 //VbglR3ClipboardWriteError(idClient, rc);
860
861 VbglR3ClipboardEventFree(pEvent);
862 }
863
864 LogFlowFuncLeaveRC(rc);
865 return rc;
866}
867
868/**
869 * Frees (destroys) a formerly allocated Shared Clipboard event.
870 *
871 * @returns IPRT status code.
872 * @param pEvent Event to free (destroy).
873 */
874VBGLR3DECL(void) VbglR3ClipboardEventFree(PVBGLR3CLIPBOARDEVENT pEvent)
875{
876 if (!pEvent)
877 return;
878
879 /* Some messages require additional cleanup. */
880 switch (pEvent->enmType)
881 {
882 default:
883 break;
884 }
885
886 RTMemFree(pEvent);
887 pEvent = NULL;
888}
889
890#if 0
891VBGLR3DECL(int) VbglR3ClipboardListHdrReadRecv(HGCMCLIENTID idClient, PVBOXCLIPBOARDLISTHANDLE phList)
892{
893 AssertPtrReturn(phList, VERR_INVALID_POINTER);
894
895 VBoxClipboardListHdrReadMsg Msg;
896 RT_ZERO(Msg);
897
898 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
899 VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_HDR_READ, VBOX_SHARED_CLIPBOARD_CPARMS_LIST_HDR_READ);
900
901 Msg.uContext.SetUInt32(0); /** @todo Not used yet. */
902 Msg.uHandle.SetUInt64(0);
903
904 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
905 if (RT_SUCCESS(rc))
906 {
907 Msg.uHandle.GetUInt32(phList);
908 }
909
910 LogFlowFuncLeaveRC(rc);
911 return rc;
912}
913
914/**
915 * Sends a list header to the host.
916 *
917 * @returns VBox status code.
918 * @param idClient The client id returned by VbglR3ClipboardConnect().
919 * @param hList List handle to send header for.
920 * @param pListHdr List header to send.
921 */
922VBGLR3DECL(int) VbglR3ClipboardListHdrSend(HGCMCLIENTID idClient,
923 VBOXCLIPBOARDLISTHANDLE hList, PVBOXCLIPBOARDLISTHDR pListHdr)
924{
925 AssertPtrReturn(pListHdr, VERR_INVALID_POINTER);
926
927 VBoxClipboardListHdrMsg Msg;
928 RT_ZERO(Msg);
929
930 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
931 VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_HDR_WRITE, VBOX_SHARED_CLIPBOARD_CPARMS_LIST_HDR);
932
933 Msg.uContext.SetUInt32(0); /** @todo Not used yet. */
934 Msg.fFeatures.SetUInt32(pListHdr->fFeatures);
935 Msg.cTotalObjects.SetUInt64(pListHdr->cTotalObjects);
936 Msg.cbTotalSize.SetUInt64(pListHdr->cbTotalSize);
937 Msg.enmCompression.SetUInt32(pListHdr->enmCompression);
938 Msg.enmChecksumType.SetUInt32(RTDIGESTTYPE_INVALID);
939
940 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
941
942 LogFlowFuncLeaveRC(rc);
943 return rc;
944}
945
946/**
947 * Sends a list entry to the host.
948 *
949 * @returns IPRT status code.
950 * @param idClient The client id returned by VbglR3ClipboardConnect()
951 * @param hList List handle to send entry for.
952 * @param pListEntry List entry to send.
953 */
954VBGLR3DECL(int) VbglR3ClipboardSendListEntryWrite(HGCMCLIENTID idClient,
955 VBOXCLIPBOARDLISTHANDLE hList, PVBOXCLIPBOARDLISTENTRY pListEntry)
956{
957 AssertPtrReturn(pListEntry, VERR_INVALID_POINTER);
958
959 VBoxClipboardListEntryWriteMsg Msg;
960 RT_ZERO(Msg);
961
962 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
963 VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_ENTRY_WRITE, VBOX_SHARED_CLIPBOARD_CPARMS_LIST_ENTRY_WRITE);
964
965 Msg.uContext.SetUInt32(0); /** @todo Not used yet. */
966 Msg.uHandle.SetUInt64(hList);
967 Msg.fInfo.SetUInt32(pListEntry->fInfo);
968 Msg.cbInfo.SetUInt32(pListEntry->cbInfo);
969 Msg.pvInfo.SetPtr(pListEntry->pvInfo, pListEntry->cbInfo);
970
971 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
972
973 LogFlowFuncLeaveRC(rc);
974 return rc;
975}
976#endif
977
978VBGLR3DECL(int) VbglR3ClipboardObjOpen(HGCMCLIENTID idClient,
979 const char *pszPath, PVBOXCLIPBOARDCREATEPARMS pCreateParms,
980 PSHAREDCLIPBOARDOBJHANDLE phObj)
981{
982 AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
983 AssertPtrReturn(pCreateParms, VERR_INVALID_POINTER);
984 AssertPtrReturn(phObj, VERR_INVALID_POINTER);
985
986 VBoxClipboardObjOpenMsg Msg;
987 RT_ZERO(Msg);
988
989 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
990 VBOX_SHARED_CLIPBOARD_GUEST_FN_OBJ_OPEN, VBOX_SHARED_CLIPBOARD_CPARMS_OBJ_OPEN);
991
992 int rc;
993
994 char *pszPathTmp = RTStrDup(pszPath);
995 if (pszPathTmp)
996 {
997 Msg.szPath.SetPtr((void *)pszPathTmp, (uint32_t)strlen(pszPathTmp) + 1 /* Include terminating zero */);
998 Msg.parms.SetPtr(pCreateParms, sizeof(VBOXCLIPBOARDCREATEPARMS));
999
1000 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1001 if (RT_SUCCESS(rc))
1002 {
1003 *phObj = pCreateParms->uHandle;
1004 }
1005
1006 RTStrFree(pszPathTmp);
1007 }
1008 else
1009 rc = VERR_NO_MEMORY;
1010
1011 LogFlowFuncLeaveRC(rc);
1012 return rc;
1013}
1014
1015VBGLR3DECL(int) VbglR3ClipboardObjClose(HGCMCLIENTID idClient, SHAREDCLIPBOARDOBJHANDLE hObj)
1016{
1017 VBoxClipboardObjCloseMsg Msg;
1018 RT_ZERO(Msg);
1019
1020 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
1021 VBOX_SHARED_CLIPBOARD_GUEST_FN_OBJ_CLOSE, VBOX_SHARED_CLIPBOARD_CPARMS_OBJ_CLOSE);
1022
1023 Msg.uHandle.SetUInt64(hObj);
1024
1025 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1026
1027 LogFlowFuncLeaveRC(rc);
1028 return rc;
1029}
1030
1031VBGLR3DECL(int) VbglR3ClipboardObjRead(HGCMCLIENTID idClient, SHAREDCLIPBOARDOBJHANDLE hObj,
1032 void *pvData, uint32_t cbData, uint32_t *pcbRead)
1033{
1034 AssertPtrReturn(pvData, VERR_INVALID_POINTER);
1035 AssertReturn(cbData, VERR_INVALID_PARAMETER);
1036 /* pcbRead is optional. */
1037
1038 VBoxClipboardObjReadWriteMsg Msg;
1039 RT_ZERO(Msg);
1040
1041 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_GUEST_FN_OBJ_READ, VBOX_SHARED_CLIPBOARD_CPARMS_OBJ_READ);
1042
1043 Msg.uContext.SetUInt32(0);
1044 Msg.uHandle.SetUInt64(hObj);
1045 Msg.pvData.SetPtr(pvData, cbData);
1046 Msg.cbData.SetUInt32(0);
1047 Msg.pvChecksum.SetPtr(NULL, 0);
1048 Msg.cbChecksum.SetUInt32(0);
1049
1050 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1051 if (RT_SUCCESS(rc))
1052 {
1053 /** @todo Context ID not used yet. */
1054 /** @todo Add checksum support. */
1055
1056 if (pcbRead)
1057 {
1058 rc = Msg.cbData.GetUInt32(pcbRead); AssertRC(rc);
1059 AssertReturn(cbData >= *pcbRead, VERR_TOO_MUCH_DATA);
1060 }
1061 }
1062
1063 LogFlowFuncLeaveRC(rc);
1064 return rc;
1065}
1066
1067VBGLR3DECL(int) VbglR3ClipboardObjWrite(HGCMCLIENTID idClient,
1068 SHAREDCLIPBOARDOBJHANDLE hObj,
1069 void *pvData, uint32_t cbData, uint32_t *pcbWritten)
1070{
1071 AssertPtrReturn(pvData, VERR_INVALID_POINTER);
1072 AssertReturn(cbData, VERR_INVALID_PARAMETER);
1073 /* pcbWritten is optional. */
1074
1075 VBoxClipboardObjReadWriteMsg Msg;
1076 RT_ZERO(Msg);
1077
1078 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_GUEST_FN_OBJ_WRITE, VBOX_SHARED_CLIPBOARD_CPARMS_OBJ_WRITE);
1079
1080 Msg.uContext.SetUInt32(0);
1081 Msg.uHandle.SetUInt64(hObj);
1082 Msg.pvData.SetPtr(pvData, cbData);
1083 Msg.cbData.SetUInt32(cbData);
1084 Msg.pvChecksum.SetPtr(NULL, 0); /** @todo Implement this. */
1085 Msg.cbChecksum.SetUInt32(0); /** @todo Implement this. */
1086
1087 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1088 if (RT_SUCCESS(rc))
1089 {
1090 if (pcbWritten)
1091 *pcbWritten = cbData;
1092 }
1093
1094 LogFlowFuncLeaveRC(rc);
1095 return rc;
1096}
1097#endif /* VBOX_WITH_SHARED_CLIPBOARD_URI_LIST */
1098
1099/**
1100 * Reports (advertises) guest clipboard formats to the host.
1101 *
1102 * @returns VBox status code.
1103 * @param idClient The client id returned by VbglR3ClipboardConnect().
1104 * @param fFormats The formats to advertise.
1105 */
1106VBGLR3DECL(int) VbglR3ClipboardReportFormats(HGCMCLIENTID idClient, uint32_t fFormats)
1107{
1108 VBoxClipboardReportFormatsMsg Msg;
1109
1110 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_GUEST_FN_REPORT_FORMATS, VBOX_SHARED_CLIPBOARD_CPARMS_REPORT_FORMATS);
1111 VbglHGCMParmUInt32Set(&Msg.formats, fFormats);
1112
1113 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1114}
1115
1116/**
1117 * Sends guest clipboard data to the host.
1118 *
1119 * This is usually called in reply to a VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA message
1120 * from the host.
1121 *
1122 * @returns VBox status code.
1123 * @param idClient The client id returned by VbglR3ClipboardConnect().
1124 * @param fFormat The format of the data.
1125 * @param pv The data.
1126 * @param cb The size of the data.
1127 */
1128static int vbglR3ClipboardWriteDataRaw(HGCMCLIENTID idClient, uint32_t fFormat, void *pv, uint32_t cb)
1129{
1130 VBoxClipboardWriteDataMsg Msg;
1131 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_DATA, VBOX_SHARED_CLIPBOARD_CPARMS_WRITE_DATA);
1132 VbglHGCMParmUInt32Set(&Msg.format, fFormat);
1133 VbglHGCMParmPtrSet(&Msg.ptr, pv, cb);
1134
1135 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1136}
1137
1138/**
1139 * Send guest clipboard data to the host.
1140 *
1141 * This is usually called in reply to a VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA message
1142 * from the host.
1143 *
1144 * @returns VBox status code.
1145 * @param idClient The client id returned by VbglR3ClipboardConnect().
1146 * @param fFormat The format of the data.
1147 * @param pv The data.
1148 * @param cb The size of the data.
1149 */
1150VBGLR3DECL(int) VbglR3ClipboardWriteData(HGCMCLIENTID idClient, uint32_t fFormat, void *pv, uint32_t cb)
1151{
1152 int rc = vbglR3ClipboardWriteDataRaw(idClient, fFormat, pv, cb);
1153
1154 return rc;
1155}
1156
1157#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
1158/**
1159 * Writes an error to the host.
1160 *
1161 * @returns IPRT status code.
1162 * @param idClient The client id returned by VbglR3ClipboardConnect().
1163 * @param rcErr Error (IPRT-style) to send.
1164 */
1165VBGLR3DECL(int) VbglR3ClipboardWriteError(HGCMCLIENTID idClient, int rcErr)
1166{
1167 VBoxClipboardWriteErrorMsg Msg;
1168 RT_ZERO(Msg);
1169
1170 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_GUEST_FN_ERROR, VBOX_SHARED_CLIPBOARD_CPARMS_ERROR);
1171
1172 /** @todo Context ID not used yet. */
1173 Msg.uContext.SetUInt32(0);
1174 Msg.rc.SetUInt32((uint32_t)rcErr); /* uint32_t vs. int. */
1175
1176 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1177
1178 if (RT_FAILURE(rc))
1179 LogFlowFunc(("Sending error %Rrc failed with rc=%Rrc\n", rcErr, rc));
1180 if (rc == VERR_NOT_SUPPORTED)
1181 rc = VINF_SUCCESS;
1182
1183 if (RT_FAILURE(rc))
1184 LogRel(("Shared Clipboard: Reporting error %Rrc to the host failed with %Rrc\n", rcErr, rc));
1185
1186 LogFlowFuncLeaveRC(rc);
1187 return rc;
1188}
1189#endif /* VBOX_WITH_SHARED_CLIPBOARD_URI_LIST */
1190
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