VirtualBox

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

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

Shared Clipboard/URI: Update.

  • Property svn:eol-style set to native
  • Property svn:keyword set to Id
  • Property svn:keywords set to Author Date Id Revision
File size: 40.3 KB
Line 
1/* $Id: VBoxGuestR3LibClipboard.cpp 79702 2019-07-11 19:34:05Z 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) VbglR3ClipboardListCloseReply(HGCMCLIENTID idClient, int rcReply, SHAREDCLIPBOARDLISTHANDLE hList)
426{
427 VBoxClipboardReplyMsg Msg;
428 RT_ZERO(Msg);
429
430 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
431 VBOX_SHARED_CLIPBOARD_GUEST_FN_REPLY, 6);
432
433 Msg.uContext.SetUInt32(0); /** @todo Context ID not used yet. */
434 Msg.enmType.SetUInt32(VBOX_SHAREDCLIPBOARD_REPLYMSGTYPE_LIST_CLOSE);
435 Msg.rc.SetUInt32((uint32_t)rcReply); /** int vs. uint32_t */
436 Msg.cbPayload.SetUInt32(0);
437 Msg.pvPayload.SetPtr(0, NULL);
438
439 Msg.u.ListOpen.uHandle.SetUInt64(hList);
440
441 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
442
443 LogFlowFuncLeaveRC(rc);
444 return rc;
445}
446
447VBGLR3DECL(int) VbglR3ClipboardListCloseSend(HGCMCLIENTID idClient, SHAREDCLIPBOARDLISTHANDLE hList)
448{
449 VBoxClipboardListCloseMsg Msg;
450 RT_ZERO(Msg);
451
452 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
453 VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_CLOSE, VBOX_SHARED_CLIPBOARD_CPARMS_LIST_CLOSE);
454
455 Msg.uContext.SetUInt32(0); /** @todo Context ID not used yet. */
456 Msg.uHandle.SetUInt64(hList);
457
458 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
459
460 LogFlowFuncLeaveRC(rc);
461 return rc;
462}
463
464VBGLR3DECL(int) VbglR3ClipboardListCloseRecv(HGCMCLIENTID idClient, PSHAREDCLIPBOARDLISTHANDLE phList)
465{
466 AssertPtrReturn(phList, VERR_INVALID_POINTER);
467
468 VBoxClipboardListCloseMsg Msg;
469 RT_ZERO(Msg);
470
471 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
472 VBOX_SHARED_CLIPBOARD_GUEST_FN_MSG_GET, VBOX_SHARED_CLIPBOARD_CPARMS_LIST_CLOSE);
473
474 Msg.uContext.SetUInt32(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_CLOSE);
475 Msg.uHandle.SetUInt64(0);
476
477 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
478 if (RT_SUCCESS(rc))
479 {
480 rc = Msg.uHandle.GetUInt64(phList); AssertRC(rc);
481 }
482
483 LogFlowFuncLeaveRC(rc);
484 return rc;
485}
486
487VBGLR3DECL(int) VbglR3ClipboardListHdrRead(HGCMCLIENTID idClient, SHAREDCLIPBOARDLISTHANDLE hList, uint32_t fFlags,
488 PVBOXCLIPBOARDLISTHDR pListHdr)
489{
490 AssertPtrReturn(pListHdr, VERR_INVALID_POINTER);
491
492 VBoxClipboardListHdrMsg Msg;
493 RT_ZERO(Msg);
494
495 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
496 VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_HDR_READ, VBOX_SHARED_CLIPBOARD_CPARMS_LIST_HDR);
497
498 Msg.ReqParms.uContext.SetUInt32(0); /** @todo Context ID not used yet. */
499 Msg.ReqParms.uHandle.SetUInt64(hList);
500 Msg.ReqParms.fFlags.SetUInt32(fFlags);
501
502 Msg.fFeatures.SetUInt32(0);
503 Msg.cbTotalSize.SetUInt32(0);
504 Msg.cTotalObjects.SetUInt64(0);
505 Msg.cbTotalSize.SetUInt64(0);
506 Msg.enmCompression.SetUInt32(0);
507 Msg.enmChecksumType.SetUInt32(0);
508
509 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
510 if (RT_SUCCESS(rc))
511 {
512 rc = Msg.fFeatures.GetUInt32(&pListHdr->fFeatures);
513 if (RT_SUCCESS(rc))
514 rc = Msg.cTotalObjects.GetUInt64(&pListHdr->cTotalObjects);
515 if (RT_SUCCESS(rc))
516 rc = Msg.cbTotalSize.GetUInt64(&pListHdr->cbTotalSize);
517 if (RT_SUCCESS(rc))
518 rc = Msg.enmCompression.GetUInt32(&pListHdr->enmCompression);
519 if (RT_SUCCESS(rc))
520 rc = Msg.enmChecksumType.GetUInt32(&pListHdr->enmChecksumType);
521 }
522
523 LogFlowFuncLeaveRC(rc);
524 return rc;
525}
526
527VBGLR3DECL(int) VbglR3ClipboardListHdrReadRecvReq(HGCMCLIENTID idClient, PSHAREDCLIPBOARDLISTHANDLE phList, uint32_t *pfFlags)
528{
529 AssertPtrReturn(phList, VERR_INVALID_POINTER);
530 AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
531
532 VBoxClipboardListHdrReadReqMsg Msg;
533 RT_ZERO(Msg);
534
535 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
536 VBOX_SHARED_CLIPBOARD_GUEST_FN_MSG_GET, VBOX_SHARED_CLIPBOARD_CPARMS_LIST_HDR_READ_REQ);
537
538 Msg.ReqParms.uContext.SetUInt32(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_HDR_READ);
539 Msg.ReqParms.uHandle.SetUInt64(0);
540 Msg.ReqParms.fFlags.SetUInt32(0);
541
542 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
543 if (RT_SUCCESS(rc))
544 {
545 if (RT_SUCCESS(rc))
546 rc = Msg.ReqParms.uHandle.GetUInt64(phList);
547 if (RT_SUCCESS(rc))
548 rc = Msg.ReqParms.fFlags.GetUInt32(pfFlags);
549 }
550
551 LogFlowFuncLeaveRC(rc);
552 return rc;
553}
554
555VBGLR3DECL(int) VbglR3ClipboardListHdrWrite(HGCMCLIENTID idClient, SHAREDCLIPBOARDLISTHANDLE hList,
556 PVBOXCLIPBOARDLISTHDR pListHdr)
557{
558 AssertPtrReturn(pListHdr, VERR_INVALID_POINTER);
559
560 VBoxClipboardListHdrMsg Msg;
561 RT_ZERO(Msg);
562
563 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
564 VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_HDR_WRITE, VBOX_SHARED_CLIPBOARD_CPARMS_LIST_HDR);
565
566 Msg.ReqParms.uContext.SetUInt32(0);
567 Msg.ReqParms.uHandle.SetUInt64(hList);
568 Msg.ReqParms.fFlags.SetUInt32(0);
569
570 Msg.fFeatures.SetUInt32(0);
571 Msg.cbTotalSize.SetUInt32(pListHdr->fFeatures);
572 Msg.cTotalObjects.SetUInt64(pListHdr->cTotalObjects);
573 Msg.cbTotalSize.SetUInt64(pListHdr->cbTotalSize);
574 Msg.enmCompression.SetUInt32(pListHdr->enmCompression);
575 Msg.enmChecksumType.SetUInt32(pListHdr->enmChecksumType);
576
577 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
578
579 LogFlowFuncLeaveRC(rc);
580 return rc;
581}
582
583VBGLR3DECL(int) VbglR3ClipboardListEntryRead(HGCMCLIENTID idClient, SHAREDCLIPBOARDLISTHANDLE hList,
584 PVBOXCLIPBOARDLISTENTRY pListEntry)
585{
586 AssertPtrReturn(pListEntry, VERR_INVALID_POINTER);
587
588 VBoxClipboardListEntryMsg Msg;
589 RT_ZERO(Msg);
590
591 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
592 VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_ENTRY_READ, VBOX_SHARED_CLIPBOARD_CPARMS_LIST_ENTRY);
593
594 Msg.ReqParms.uContext.SetUInt32(0); /** @todo Context ID not used yet. */
595 Msg.ReqParms.uHandle.SetUInt64(hList);
596 Msg.ReqParms.fInfo.SetUInt32(0);
597
598 Msg.szName.SetPtr(pListEntry->pszName, pListEntry->cbName);
599 Msg.cbInfo.SetUInt32(0);
600 Msg.pvInfo.SetPtr(pListEntry->pvInfo, pListEntry->cbInfo);
601
602 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
603 if (RT_SUCCESS(rc))
604 {
605 rc = Msg.cbInfo.GetUInt32(&pListEntry->cbInfo); AssertRC(rc);
606 }
607
608 LogFlowFuncLeaveRC(rc);
609 return rc;
610}
611
612VBGLR3DECL(int) VbglR3ClipboardListEntryReadRecvReq(HGCMCLIENTID idClient, PSHAREDCLIPBOARDLISTHANDLE phList, uint32_t *pfInfo)
613{
614 AssertPtrReturn(phList, VERR_INVALID_POINTER);
615 AssertPtrReturn(pfInfo, VERR_INVALID_POINTER);
616
617 VBoxClipboardListEntryReadReqMsg Msg;
618 RT_ZERO(Msg);
619
620 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
621 VBOX_SHARED_CLIPBOARD_GUEST_FN_MSG_GET, VBOX_SHARED_CLIPBOARD_CPARMS_LIST_ENTRY_READ_REQ);
622
623 Msg.ReqParms.uContext.SetUInt32(VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_ENTRY_READ);
624 Msg.ReqParms.uHandle.SetUInt64(0);
625 Msg.ReqParms.fInfo.SetUInt32(0);
626
627 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
628 if (RT_SUCCESS(rc))
629 {
630 rc = Msg.ReqParms.uHandle.GetUInt64(phList); AssertRC(rc);
631 if (RT_SUCCESS(rc))
632 rc = Msg.ReqParms.fInfo.GetUInt32(pfInfo); AssertRC(rc);
633 }
634
635 LogFlowFuncLeaveRC(rc);
636 return rc;
637}
638
639VBGLR3DECL(int) VbglR3ClipboardListEntryWrite(HGCMCLIENTID idClient, SHAREDCLIPBOARDLISTHANDLE hList,
640 PVBOXCLIPBOARDLISTENTRY pListEntry)
641{
642 AssertPtrReturn(pListEntry, VERR_INVALID_POINTER);
643
644 VBoxClipboardListEntryMsg Msg;
645 RT_ZERO(Msg);
646
647 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
648 VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_ENTRY_WRITE, VBOX_SHARED_CLIPBOARD_CPARMS_LIST_ENTRY);
649
650 Msg.ReqParms.uContext.SetUInt32(0); /** @todo Context ID not used yet. */
651 Msg.ReqParms.uHandle.SetUInt64(hList);
652 Msg.ReqParms.fInfo.SetUInt32(pListEntry->fInfo);
653
654 Msg.szName.SetPtr(pListEntry->pszName, pListEntry->cbName);
655 Msg.cbInfo.SetUInt32(pListEntry->cbInfo);
656 Msg.pvInfo.SetPtr(pListEntry->pvInfo, pListEntry->cbInfo);
657
658 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
659
660 LogFlowFuncLeaveRC(rc);
661 return rc;
662}
663
664VBGLR3DECL(int) VbglR3ClipboardEventGetNext(HGCMCLIENTID idClient, PSHAREDCLIPBOARDURITRANSFER pTransfer,
665 PVBGLR3CLIPBOARDEVENT *ppEvent)
666{
667 AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
668 AssertPtrReturn(ppEvent, VERR_INVALID_POINTER);
669
670 PVBGLR3CLIPBOARDEVENT pEvent = (PVBGLR3CLIPBOARDEVENT)RTMemAllocZ(sizeof(VBGLR3CLIPBOARDEVENT));
671 if (!pEvent)
672 return VERR_NO_MEMORY;
673
674 uint32_t uMsg = 0;
675 uint32_t cParms = 0;
676 int rc = vbglR3ClipboardMsgPeekWait(idClient, &uMsg, &cParms, NULL /* pidRestoreCheck */);
677 if (RT_SUCCESS(rc))
678 {
679 LogFunc(("Handling uMsg=%RU32\n", uMsg));
680
681 switch (uMsg)
682 {
683#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
684 case VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_ROOTS:
685 {
686 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_ROOTS\n"));
687
688 VBOXCLIPBOARDROOTS Roots;
689 rc = SharedClipboardURIRootsInit(&Roots);
690 if (RT_SUCCESS(rc))
691 {
692 rc = VbglR3ClipboardRootsRecv(idClient, &Roots);
693 if (RT_SUCCESS(rc))
694 {
695 /** @todo Handle Roots.fRoots flags. */
696
697 char *pszRoots = NULL;
698 uint32_t cRoots = 0;
699 rc = SharedClipboardURILTransferGetRoots(pTransfer, &pszRoots, &cRoots);
700 if (RT_SUCCESS(rc))
701 {
702 /** @todo Split up transfers in _64K each. */
703
704 const uint32_t cbRoots = pszRoots
705 ? (uint32_t)strlen(pszRoots) + 1 /* Include termination. */
706 : 0;
707
708 rc = VbglR3ClipboardRootsWrite(idClient, cRoots, pszRoots, cbRoots);
709 }
710 }
711 }
712
713 break;
714 }
715
716 case VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_OPEN:
717 {
718 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_OPEN\n"));
719
720 VBOXCLIPBOARDLISTOPENPARMS openParmsList;
721 rc = SharedClipboardURIListOpenParmsInit(&openParmsList);
722 if (RT_SUCCESS(rc))
723 {
724 rc = VbglR3ClipboardListOpenRecv(idClient, &openParmsList);
725 if (RT_SUCCESS(rc))
726 {
727 LogFlowFunc(("pszPath=%s\n", openParmsList.pszPath));
728
729 SHAREDCLIPBOARDLISTHANDLE hList = SHAREDCLIPBOARDLISTHANDLE_INVALID;
730 rc = SharedClipboardURITransferListOpen(pTransfer, &openParmsList, &hList);
731
732 /* Reply in any case. */
733 int rc2 = VbglR3ClipboardListOpenReply(idClient, rc, hList);
734 AssertRC(rc2);
735
736 SharedClipboardURIListOpenParmsDestroy(&openParmsList);
737 }
738 }
739
740 break;
741 }
742
743 case VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_CLOSE:
744 {
745 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_CLOSE\n"));
746
747 SHAREDCLIPBOARDLISTHANDLE hList;
748 rc = VbglR3ClipboardListCloseRecv(idClient, &hList);
749 if (RT_SUCCESS(rc))
750 {
751 rc = SharedClipboardURITransferListClose(pTransfer, hList);
752
753 /* Reply in any case. */
754 int rc2 = VbglR3ClipboardListCloseReply(idClient, rc, hList);
755 AssertRC(rc2);
756 }
757
758 break;
759 }
760
761 case VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_HDR_READ:
762 {
763 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_HDR_READ\n"));
764
765 /** @todo Handle filter + list features. */
766
767 SHAREDCLIPBOARDLISTHANDLE hList = SHAREDCLIPBOARDLISTHANDLE_INVALID;
768 uint32_t fFlags = 0;
769 rc = VbglR3ClipboardListHdrReadRecvReq(idClient, &hList, &fFlags);
770 if (RT_SUCCESS(rc))
771 {
772 VBOXCLIPBOARDLISTHDR hdrList;
773 rc = SharedClipboardURITransferListGetHeader(pTransfer, hList, &hdrList);
774 if (RT_SUCCESS(rc))
775 {
776 rc = VbglR3ClipboardListHdrWrite(idClient, hList, &hdrList);
777 SharedClipboardURIListHdrDestroy(&hdrList);
778 }
779 }
780
781 break;
782 }
783
784 #if 0
785 case VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_HDR_WRITE:
786 {
787 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_HDR_WRITE\n"));
788
789 VBOXCLIPBOARDLISTHDR hdrList;
790 rc = SharedClipboardURIListHdrInit(&hdrList);
791 if (RT_SUCCESS(rc))
792 {
793 rc = VBglR3ClipboardListHdrRecv(idClient, )
794 }
795 break;
796 }
797 #endif
798
799 case VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_ENTRY_READ:
800 {
801 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_ENTRY_READ\n"));
802
803 VBOXCLIPBOARDLISTENTRY entryList;
804 rc = SharedClipboardURIListEntryInit(&entryList);
805 if (RT_SUCCESS(rc))
806 {
807 SHAREDCLIPBOARDLISTHANDLE hList;
808 uint32_t fInfo;
809 rc = VbglR3ClipboardListEntryReadRecvReq(idClient, &hList, &fInfo);
810 if (RT_SUCCESS(rc))
811 {
812 rc = SharedClipboardURITransferListRead(pTransfer, hList, &entryList);
813 if (RT_SUCCESS(rc))
814 {
815 PSHAREDCLIPBOARDFSOBJINFO pObjInfo = (PSHAREDCLIPBOARDFSOBJINFO)entryList.pvInfo;
816 Assert(entryList.cbInfo == sizeof(SHAREDCLIPBOARDFSOBJINFO));
817
818 LogFlowFunc(("\t%s (%RU64 bytes)\n", entryList.pszName, pObjInfo->cbObject));
819
820 rc = VbglR3ClipboardListEntryWrite(idClient, hList, &entryList);
821 }
822 }
823
824 SharedClipboardURIListEntryDestroy(&entryList);
825 }
826
827 break;
828 }
829
830 #if 0
831 case VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_ENTRY_WRITE:
832 {
833 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_LIST_ENTRY_WRITE\n"));
834 pEvent->enmType = VBGLR3CLIPBOARDEVENTTYPE_URI_LIST_ENTRY_WRITE;
835 break;
836 }
837 #endif
838
839 case VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_OBJ_OPEN:
840 {
841 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_OBJ_OPEN\n"));
842 pEvent->enmType = VBGLR3CLIPBOARDEVENTTYPE_URI_OBJ_OPEN;
843 break;
844 }
845
846 case VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_OBJ_CLOSE:
847 {
848 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_OBJ_CLOSE\n"));
849 pEvent->enmType = VBGLR3CLIPBOARDEVENTTYPE_URI_OBJ_CLOSE;
850 break;
851 }
852
853 case VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_OBJ_READ:
854 {
855 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_OBJ_READ\n"));
856 pEvent->enmType = VBGLR3CLIPBOARDEVENTTYPE_URI_OBJ_READ;
857 break;
858 }
859
860 #if 0
861 case VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_OBJ_WRITE:
862 {
863 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_URI_OBJ_WRITE\n"));
864 pEvent->enmType = VBGLR3CLIPBOARDEVENTTYPE_URI_OBJ_WRITE;
865 break;
866 }
867 #endif
868#endif /* VBOX_WITH_SHARED_CLIPBOARD_URI_LIST */
869
870 default:
871 rc = VERR_NOT_SUPPORTED;
872 break;
873 }
874 }
875
876 if (RT_SUCCESS(rc))
877 {
878 if (pEvent->enmType != VBGLR3CLIPBOARDEVENTTYPE_INVALID)
879 {
880 *ppEvent = pEvent;
881 }
882 else
883 VbglR3ClipboardEventFree(pEvent);
884 }
885 else
886 {
887 /* Report error back to the host. */
888 //VbglR3ClipboardWriteError(idClient, rc);
889
890 VbglR3ClipboardEventFree(pEvent);
891 }
892
893 LogFlowFuncLeaveRC(rc);
894 return rc;
895}
896
897/**
898 * Frees (destroys) a formerly allocated Shared Clipboard event.
899 *
900 * @returns IPRT status code.
901 * @param pEvent Event to free (destroy).
902 */
903VBGLR3DECL(void) VbglR3ClipboardEventFree(PVBGLR3CLIPBOARDEVENT pEvent)
904{
905 if (!pEvent)
906 return;
907
908 /* Some messages require additional cleanup. */
909 switch (pEvent->enmType)
910 {
911 default:
912 break;
913 }
914
915 RTMemFree(pEvent);
916 pEvent = NULL;
917}
918
919#if 0
920VBGLR3DECL(int) VbglR3ClipboardListHdrReadRecv(HGCMCLIENTID idClient, PVBOXCLIPBOARDLISTHANDLE phList)
921{
922 AssertPtrReturn(phList, VERR_INVALID_POINTER);
923
924 VBoxClipboardListHdrReadMsg Msg;
925 RT_ZERO(Msg);
926
927 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
928 VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_HDR_READ, VBOX_SHARED_CLIPBOARD_CPARMS_LIST_HDR_READ);
929
930 Msg.uContext.SetUInt32(0); /** @todo Not used yet. */
931 Msg.uHandle.SetUInt64(0);
932
933 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
934 if (RT_SUCCESS(rc))
935 {
936 Msg.uHandle.GetUInt32(phList);
937 }
938
939 LogFlowFuncLeaveRC(rc);
940 return rc;
941}
942
943/**
944 * Sends a list header to the host.
945 *
946 * @returns VBox status code.
947 * @param idClient The client id returned by VbglR3ClipboardConnect().
948 * @param hList List handle to send header for.
949 * @param pListHdr List header to send.
950 */
951VBGLR3DECL(int) VbglR3ClipboardListHdrSend(HGCMCLIENTID idClient,
952 VBOXCLIPBOARDLISTHANDLE hList, PVBOXCLIPBOARDLISTHDR pListHdr)
953{
954 AssertPtrReturn(pListHdr, VERR_INVALID_POINTER);
955
956 VBoxClipboardListHdrMsg Msg;
957 RT_ZERO(Msg);
958
959 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
960 VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_HDR_WRITE, VBOX_SHARED_CLIPBOARD_CPARMS_LIST_HDR);
961
962 Msg.uContext.SetUInt32(0); /** @todo Not used yet. */
963 Msg.fFeatures.SetUInt32(pListHdr->fFeatures);
964 Msg.cTotalObjects.SetUInt64(pListHdr->cTotalObjects);
965 Msg.cbTotalSize.SetUInt64(pListHdr->cbTotalSize);
966 Msg.enmCompression.SetUInt32(pListHdr->enmCompression);
967 Msg.enmChecksumType.SetUInt32(RTDIGESTTYPE_INVALID);
968
969 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
970
971 LogFlowFuncLeaveRC(rc);
972 return rc;
973}
974
975/**
976 * Sends a list entry to the host.
977 *
978 * @returns IPRT status code.
979 * @param idClient The client id returned by VbglR3ClipboardConnect()
980 * @param hList List handle to send entry for.
981 * @param pListEntry List entry to send.
982 */
983VBGLR3DECL(int) VbglR3ClipboardSendListEntryWrite(HGCMCLIENTID idClient,
984 VBOXCLIPBOARDLISTHANDLE hList, PVBOXCLIPBOARDLISTENTRY pListEntry)
985{
986 AssertPtrReturn(pListEntry, VERR_INVALID_POINTER);
987
988 VBoxClipboardListEntryWriteMsg Msg;
989 RT_ZERO(Msg);
990
991 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
992 VBOX_SHARED_CLIPBOARD_GUEST_FN_LIST_ENTRY_WRITE, VBOX_SHARED_CLIPBOARD_CPARMS_LIST_ENTRY_WRITE);
993
994 Msg.uContext.SetUInt32(0); /** @todo Not used yet. */
995 Msg.uHandle.SetUInt64(hList);
996 Msg.fInfo.SetUInt32(pListEntry->fInfo);
997 Msg.cbInfo.SetUInt32(pListEntry->cbInfo);
998 Msg.pvInfo.SetPtr(pListEntry->pvInfo, pListEntry->cbInfo);
999
1000 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1001
1002 LogFlowFuncLeaveRC(rc);
1003 return rc;
1004}
1005#endif
1006
1007VBGLR3DECL(int) VbglR3ClipboardObjOpen(HGCMCLIENTID idClient,
1008 const char *pszPath, PVBOXCLIPBOARDCREATEPARMS pCreateParms,
1009 PSHAREDCLIPBOARDOBJHANDLE phObj)
1010{
1011 AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
1012 AssertPtrReturn(pCreateParms, VERR_INVALID_POINTER);
1013 AssertPtrReturn(phObj, VERR_INVALID_POINTER);
1014
1015 VBoxClipboardObjOpenMsg Msg;
1016 RT_ZERO(Msg);
1017
1018 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
1019 VBOX_SHARED_CLIPBOARD_GUEST_FN_OBJ_OPEN, VBOX_SHARED_CLIPBOARD_CPARMS_OBJ_OPEN);
1020
1021 int rc;
1022
1023 char *pszPathTmp = RTStrDup(pszPath);
1024 if (pszPathTmp)
1025 {
1026 Msg.szPath.SetPtr((void *)pszPathTmp, (uint32_t)strlen(pszPathTmp) + 1 /* Include terminating zero */);
1027 Msg.parms.SetPtr(pCreateParms, sizeof(VBOXCLIPBOARDCREATEPARMS));
1028
1029 rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1030 if (RT_SUCCESS(rc))
1031 {
1032 *phObj = pCreateParms->uHandle;
1033 }
1034
1035 RTStrFree(pszPathTmp);
1036 }
1037 else
1038 rc = VERR_NO_MEMORY;
1039
1040 LogFlowFuncLeaveRC(rc);
1041 return rc;
1042}
1043
1044VBGLR3DECL(int) VbglR3ClipboardObjClose(HGCMCLIENTID idClient, SHAREDCLIPBOARDOBJHANDLE hObj)
1045{
1046 VBoxClipboardObjCloseMsg Msg;
1047 RT_ZERO(Msg);
1048
1049 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient,
1050 VBOX_SHARED_CLIPBOARD_GUEST_FN_OBJ_CLOSE, VBOX_SHARED_CLIPBOARD_CPARMS_OBJ_CLOSE);
1051
1052 Msg.uHandle.SetUInt64(hObj);
1053
1054 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1055
1056 LogFlowFuncLeaveRC(rc);
1057 return rc;
1058}
1059
1060VBGLR3DECL(int) VbglR3ClipboardObjRead(HGCMCLIENTID idClient, SHAREDCLIPBOARDOBJHANDLE hObj,
1061 void *pvData, uint32_t cbData, uint32_t *pcbRead)
1062{
1063 AssertPtrReturn(pvData, VERR_INVALID_POINTER);
1064 AssertReturn(cbData, VERR_INVALID_PARAMETER);
1065 /* pcbRead is optional. */
1066
1067 VBoxClipboardObjReadWriteMsg Msg;
1068 RT_ZERO(Msg);
1069
1070 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_GUEST_FN_OBJ_READ, VBOX_SHARED_CLIPBOARD_CPARMS_OBJ_READ);
1071
1072 Msg.uContext.SetUInt32(0);
1073 Msg.uHandle.SetUInt64(hObj);
1074 Msg.pvData.SetPtr(pvData, cbData);
1075 Msg.cbData.SetUInt32(0);
1076 Msg.pvChecksum.SetPtr(NULL, 0);
1077 Msg.cbChecksum.SetUInt32(0);
1078
1079 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1080 if (RT_SUCCESS(rc))
1081 {
1082 /** @todo Context ID not used yet. */
1083 /** @todo Add checksum support. */
1084
1085 if (pcbRead)
1086 {
1087 rc = Msg.cbData.GetUInt32(pcbRead); AssertRC(rc);
1088 AssertReturn(cbData >= *pcbRead, VERR_TOO_MUCH_DATA);
1089 }
1090 }
1091
1092 LogFlowFuncLeaveRC(rc);
1093 return rc;
1094}
1095
1096VBGLR3DECL(int) VbglR3ClipboardObjWrite(HGCMCLIENTID idClient,
1097 SHAREDCLIPBOARDOBJHANDLE hObj,
1098 void *pvData, uint32_t cbData, uint32_t *pcbWritten)
1099{
1100 AssertPtrReturn(pvData, VERR_INVALID_POINTER);
1101 AssertReturn(cbData, VERR_INVALID_PARAMETER);
1102 /* pcbWritten is optional. */
1103
1104 VBoxClipboardObjReadWriteMsg Msg;
1105 RT_ZERO(Msg);
1106
1107 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_GUEST_FN_OBJ_WRITE, VBOX_SHARED_CLIPBOARD_CPARMS_OBJ_WRITE);
1108
1109 Msg.uContext.SetUInt32(0);
1110 Msg.uHandle.SetUInt64(hObj);
1111 Msg.pvData.SetPtr(pvData, cbData);
1112 Msg.cbData.SetUInt32(cbData);
1113 Msg.pvChecksum.SetPtr(NULL, 0); /** @todo Implement this. */
1114 Msg.cbChecksum.SetUInt32(0); /** @todo Implement this. */
1115
1116 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1117 if (RT_SUCCESS(rc))
1118 {
1119 if (pcbWritten)
1120 *pcbWritten = cbData;
1121 }
1122
1123 LogFlowFuncLeaveRC(rc);
1124 return rc;
1125}
1126#endif /* VBOX_WITH_SHARED_CLIPBOARD_URI_LIST */
1127
1128/**
1129 * Reports (advertises) guest clipboard formats to the host.
1130 *
1131 * @returns VBox status code.
1132 * @param idClient The client id returned by VbglR3ClipboardConnect().
1133 * @param fFormats The formats to advertise.
1134 */
1135VBGLR3DECL(int) VbglR3ClipboardReportFormats(HGCMCLIENTID idClient, uint32_t fFormats)
1136{
1137 VBoxClipboardReportFormatsMsg Msg;
1138
1139 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_GUEST_FN_REPORT_FORMATS, VBOX_SHARED_CLIPBOARD_CPARMS_REPORT_FORMATS);
1140 VbglHGCMParmUInt32Set(&Msg.formats, fFormats);
1141
1142 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1143}
1144
1145/**
1146 * Sends guest clipboard data to the host.
1147 *
1148 * This is usually called in reply to a VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA message
1149 * from the host.
1150 *
1151 * @returns VBox status code.
1152 * @param idClient The client id returned by VbglR3ClipboardConnect().
1153 * @param fFormat The format of the data.
1154 * @param pv The data.
1155 * @param cb The size of the data.
1156 */
1157static int vbglR3ClipboardWriteDataRaw(HGCMCLIENTID idClient, uint32_t fFormat, void *pv, uint32_t cb)
1158{
1159 VBoxClipboardWriteDataMsg Msg;
1160 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_GUEST_FN_WRITE_DATA, VBOX_SHARED_CLIPBOARD_CPARMS_WRITE_DATA);
1161 VbglHGCMParmUInt32Set(&Msg.format, fFormat);
1162 VbglHGCMParmPtrSet(&Msg.ptr, pv, cb);
1163
1164 return VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1165}
1166
1167/**
1168 * Send guest clipboard data to the host.
1169 *
1170 * This is usually called in reply to a VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA message
1171 * from the host.
1172 *
1173 * @returns VBox status code.
1174 * @param idClient The client id returned by VbglR3ClipboardConnect().
1175 * @param fFormat The format of the data.
1176 * @param pv The data.
1177 * @param cb The size of the data.
1178 */
1179VBGLR3DECL(int) VbglR3ClipboardWriteData(HGCMCLIENTID idClient, uint32_t fFormat, void *pv, uint32_t cb)
1180{
1181 int rc = vbglR3ClipboardWriteDataRaw(idClient, fFormat, pv, cb);
1182
1183 return rc;
1184}
1185
1186#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
1187/**
1188 * Writes an error to the host.
1189 *
1190 * @returns IPRT status code.
1191 * @param idClient The client id returned by VbglR3ClipboardConnect().
1192 * @param rcErr Error (IPRT-style) to send.
1193 */
1194VBGLR3DECL(int) VbglR3ClipboardWriteError(HGCMCLIENTID idClient, int rcErr)
1195{
1196 VBoxClipboardWriteErrorMsg Msg;
1197 RT_ZERO(Msg);
1198
1199 VBGL_HGCM_HDR_INIT(&Msg.hdr, idClient, VBOX_SHARED_CLIPBOARD_GUEST_FN_ERROR, VBOX_SHARED_CLIPBOARD_CPARMS_ERROR);
1200
1201 /** @todo Context ID not used yet. */
1202 Msg.uContext.SetUInt32(0);
1203 Msg.rc.SetUInt32((uint32_t)rcErr); /* uint32_t vs. int. */
1204
1205 int rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
1206
1207 if (RT_FAILURE(rc))
1208 LogFlowFunc(("Sending error %Rrc failed with rc=%Rrc\n", rcErr, rc));
1209 if (rc == VERR_NOT_SUPPORTED)
1210 rc = VINF_SUCCESS;
1211
1212 if (RT_FAILURE(rc))
1213 LogRel(("Shared Clipboard: Reporting error %Rrc to the host failed with %Rrc\n", rcErr, rc));
1214
1215 LogFlowFuncLeaveRC(rc);
1216 return rc;
1217}
1218#endif /* VBOX_WITH_SHARED_CLIPBOARD_URI_LIST */
1219
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