VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-uri.cpp@ 78683

Last change on this file since 78683 was 78683, 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: 24.7 KB
Line 
1/* $Id: VBoxSharedClipboardSvc-uri.cpp 78683 2019-05-23 10:07:21Z vboxsync $ */
2/** @file
3 * Shared Clipboard Service - Internal code for URI (list) handling.
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/HostServices/VBoxClipboardSvc.h>
24#include <VBox/HostServices/VBoxClipboardExt.h>
25
26#include <iprt/dir.h>
27#include <iprt/file.h>
28#include <iprt/path.h>
29
30#include "VBoxSharedClipboardSvc-internal.h"
31#include "VBoxSharedClipboardSvc-uri.h"
32
33
34/*********************************************************************************************************************************
35* Externals *
36*********************************************************************************************************************************/
37extern PFNHGCMSVCEXT g_pfnExtension;
38extern void *g_pvExtension;
39
40
41/**
42 * Initializes an URI object context.
43 *
44 * @returns VBox status code.
45 * @param pObjCtx URI object context to initialize.
46 */
47int vboxClipboardSvcURIObjCtxInit(PVBOXCLIPBOARDCLIENTURIOBJCTX pObjCtx)
48{
49 AssertPtrReturn(pObjCtx, VERR_INVALID_POINTER);
50
51 LogFlowFuncEnter();
52
53 pObjCtx->pObj = NULL;
54
55 return VINF_SUCCESS;
56}
57
58/**
59 * Uninitializes an URI object context.
60 *
61 * @param pObjCtx URI object context to uninitialize.
62 */
63void vboxClipboardSvcURIObjCtxUninit(PVBOXCLIPBOARDCLIENTURIOBJCTX pObjCtx)
64{
65 AssertPtrReturnVoid(pObjCtx);
66
67 LogFlowFuncEnter();
68
69 if (pObjCtx->pObj)
70 {
71 pObjCtx->pObj->Close();
72 delete pObjCtx->pObj;
73 }
74
75 pObjCtx->pObj = NULL;
76}
77
78/**
79 * Returns the URI object context's URI object.
80 *
81 * @returns Pointer to the URI object context's URI object.
82 * @param pObjCtx URI object context to return the URI object for.
83 */
84SharedClipboardURIObject *vboxClipboardSvcURIObjCtxGetObj(PVBOXCLIPBOARDCLIENTURIOBJCTX pObjCtx)
85{
86 AssertPtrReturn(pObjCtx, NULL);
87 return pObjCtx->pObj;
88}
89
90/**
91 * Returns if an URI object context is valid or not.
92 *
93 * @returns \c true if valid, \c false if not.
94 * @param pObjCtx URI object context to check.
95 */
96bool vboxClipboardSvcURIObjCtxIsValid(PVBOXCLIPBOARDCLIENTURIOBJCTX pObjCtx)
97{
98 return ( pObjCtx
99 && pObjCtx->pObj
100 && pObjCtx->pObj->IsComplete() == false
101 && pObjCtx->pObj->IsOpen());
102}
103
104/**
105 * Creates a URI transfer object.
106 *
107 * @returns VBox status code.
108 * @param pTransfer Transfer object to destroy.
109 * @param uClientID Client ID to assign to the transfer object.
110 */
111int vboxClipboardSvcURITransferCreate(PVBOXCLIPBOARDCLIENTURITRANSFER pTransfer, uint32_t uClientID)
112{
113 AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
114 RT_NOREF(uClientID);
115
116 int rc = pTransfer->Cache.OpenTemp(SHAREDCLIPBOARDCACHE_FLAGS_NONE);
117 if (RT_SUCCESS(rc))
118 {
119 rc = SharedClipboardMetaDataInit(&pTransfer->Meta);
120 if (RT_SUCCESS(rc))
121 vboxClipboardSvcURIObjCtxInit(&pTransfer->ObjCtx);
122 }
123
124 return rc;
125}
126
127/**
128 * Destroys a URI transfer object.
129 *
130 * @param pTransfer Transfer object to destroy.
131 */
132void vboxClipboardSvcURITransferDestroy(PVBOXCLIPBOARDCLIENTURITRANSFER pTransfer)
133{
134 AssertPtrReturnVoid(pTransfer);
135
136 LogFlowFuncEnter();
137
138 vboxClipboardSvcURITransferReset(pTransfer);
139}
140
141/**
142 * Resets a URI transfer object.
143 *
144 * @param pTransfer Transfer object to reset.
145 */
146void vboxClipboardSvcURITransferReset(PVBOXCLIPBOARDCLIENTURITRANSFER pTransfer)
147{
148 AssertPtrReturnVoid(pTransfer);
149
150 LogFlowFuncEnter();
151
152 vboxClipboardSvcURIObjCtxUninit(&pTransfer->ObjCtx);
153
154 int rc2;
155
156 /* Do we need to detach from a previously attached clipboard area? */
157 const SHAREDCLIPBOARDAREAID uAreaID = pTransfer->Cache.GetAreaID();
158 if (uAreaID != NIL_SHAREDCLIPBOARDAREAID)
159 {
160 VBOXCLIPBOARDEXTAREAPARMS parms;
161 RT_ZERO(parms);
162 parms.uID = uAreaID;
163
164 rc2 = g_pfnExtension(g_pvExtension, VBOX_CLIPBOARD_EXT_FN_AREA_DETACH, &parms, sizeof(parms));
165 AssertRC(rc2);
166 }
167
168 rc2 = pTransfer->Cache.Rollback();
169 AssertRC(rc2);
170
171 rc2 = pTransfer->Cache.Close();
172 AssertRC(rc2);
173
174 SharedClipboardMetaDataDestroy(&pTransfer->Meta);
175}
176
177/**
178 * URI client (guest) handler for the Shared Clipboard host service.
179 *
180 * @returns VBox status code.
181 * @param u32ClientID Client ID of the client which called this handler.
182 * @param pvClient Pointer to client-specific data block.
183 * @param u32Function Function number being called.
184 * @param cParms Number of function parameters supplied.
185 * @param paParms Array function parameters supplied.
186 * @param tsArrival Timestamp of arrival.
187 * @param pfAsync Returns \c true if the response needs to be being asynchronous or \c false if not,
188 */
189int vboxClipboardSvcURIHandler(uint32_t u32ClientID,
190 void *pvClient,
191 uint32_t u32Function,
192 uint32_t cParms,
193 VBOXHGCMSVCPARM paParms[],
194 uint64_t tsArrival,
195 bool *pfAsync)
196{
197 RT_NOREF(u32ClientID, paParms, tsArrival, pfAsync);
198
199 const PVBOXCLIPBOARDCLIENTDATA pClientData = (PVBOXCLIPBOARDCLIENTDATA)pvClient;
200
201 /* Check if we've the right mode set. */
202 int rc = VERR_ACCESS_DENIED; /* Play safe. */
203
204 switch (u32Function)
205 {
206 case VBOX_SHARED_CLIPBOARD_FN_READ_DATA_HDR:
207 RT_FALL_THROUGH();
208 case VBOX_SHARED_CLIPBOARD_FN_READ_DIR:
209 RT_FALL_THROUGH();
210 case VBOX_SHARED_CLIPBOARD_FN_READ_FILE_HDR:
211 RT_FALL_THROUGH();
212 case VBOX_SHARED_CLIPBOARD_FN_READ_FILE_DATA:
213 {
214 if ( vboxSvcClipboardGetMode() == VBOX_SHARED_CLIPBOARD_MODE_GUEST_TO_HOST
215 || vboxSvcClipboardGetMode() == VBOX_SHARED_CLIPBOARD_MODE_BIDIRECTIONAL)
216 {
217 rc = VINF_SUCCESS;
218 }
219
220 if (RT_FAILURE(rc))
221 LogFunc(("Guest -> Host Shared Clipboard mode disabled, ignoring request\n"));
222 break;
223 }
224
225 case VBOX_SHARED_CLIPBOARD_FN_WRITE_DATA_HDR:
226 RT_FALL_THROUGH();
227 case VBOX_SHARED_CLIPBOARD_FN_WRITE_FILE_HDR:
228 RT_FALL_THROUGH();
229 case VBOX_SHARED_CLIPBOARD_FN_WRITE_FILE_DATA:
230 RT_FALL_THROUGH();
231 case VBOX_SHARED_CLIPBOARD_FN_WRITE_CANCEL:
232 RT_FALL_THROUGH();
233 case VBOX_SHARED_CLIPBOARD_FN_WRITE_ERROR:
234 {
235 if ( vboxSvcClipboardGetMode() == VBOX_SHARED_CLIPBOARD_MODE_HOST_TO_GUEST
236 || vboxSvcClipboardGetMode() == VBOX_SHARED_CLIPBOARD_MODE_BIDIRECTIONAL)
237 {
238 rc = VINF_SUCCESS;
239 }
240
241 if (RT_FAILURE(rc))
242 LogFunc(("Clipboard: Host -> Guest Shared Clipboard mode disabled, ignoring request\n"));
243 break;
244 }
245
246 default:
247 break;
248 }
249
250 if (RT_FAILURE(rc))
251 return rc;
252
253 const PVBOXCLIPBOARDCLIENTURITRANSFER pTransfer = &pClientData->Transfer;
254
255 rc = VERR_INVALID_PARAMETER; /* Play safe. */
256
257 switch (u32Function)
258 {
259 case VBOX_SHARED_CLIPBOARD_FN_READ_DATA_HDR:
260 {
261 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_FN_READ_DATA_HDR\n"));
262 if (cParms == VBOX_SHARED_CLIPBOARD_CPARMS_READ_DATA_HDR)
263 {
264 if ( RT_SUCCESS(rc)
265 && g_pfnExtension)
266 {
267 VBOXCLIPBOARDEXTAREAPARMS parms;
268 RT_ZERO(parms);
269
270 parms.uID = 0; /* 0 means most recent clipboard area. */
271
272 /* The client now needs to attach to the most recent clipboard area
273 * to keep a reference to it. The host does the actual book keeping / cleanup then. */
274 rc = g_pfnExtension(g_pvExtension, VBOX_CLIPBOARD_EXT_FN_AREA_ATTACH, &parms, sizeof(parms));
275 if (RT_SUCCESS(rc))
276 {
277
278 }
279
280 /* Do we need to detach again because we're done? */
281 if ( RT_SUCCESS(rc))
282 {
283 RT_ZERO(parms);
284 parms.uID = pTransfer->Cache.GetAreaID();
285
286 rc = g_pfnExtension(g_pvExtension, VBOX_CLIPBOARD_EXT_FN_AREA_DETACH, &parms, sizeof(parms));
287 }
288 }
289 }
290 break;
291 }
292
293 case VBOX_SHARED_CLIPBOARD_FN_WRITE_DATA_HDR:
294 {
295 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_FN_WRITE_DATA_HDR\n"));
296 if (cParms == VBOX_SHARED_CLIPBOARD_CPARMS_WRITE_DATA_HDR)
297 {
298 if (pClientData->cTransfers == 0) /* At the moment we only support on transfer per client at a time. */
299 {
300 RT_ZERO(pTransfer->Hdr);
301 /* Note: Context ID (paParms[0]) not used yet. */
302 rc = HGCMSvcGetU32(&paParms[1], &pTransfer->Hdr.uFlags);
303 if (RT_SUCCESS(rc))
304 rc = HGCMSvcGetU32(&paParms[2], &pTransfer->Hdr.uScreenId);
305 if (RT_SUCCESS(rc))
306 rc = HGCMSvcGetU64(&paParms[3], &pTransfer->Hdr.cbTotal);
307 if (RT_SUCCESS(rc))
308 rc = HGCMSvcGetU32(&paParms[4], &pTransfer->Hdr.cbMeta);
309 if (RT_SUCCESS(rc))
310 rc = HGCMSvcGetPv(&paParms[5], &pTransfer->Hdr.pvMetaFmt, &pTransfer->Hdr.cbMetaFmt);
311 if (RT_SUCCESS(rc))
312 rc = HGCMSvcGetU32(&paParms[6], &pTransfer->Hdr.cbMetaFmt);
313 if (RT_SUCCESS(rc))
314 rc = HGCMSvcGetU64(&paParms[7], &pTransfer->Hdr.cObjects);
315 if (RT_SUCCESS(rc))
316 rc = HGCMSvcGetU32(&paParms[8], &pTransfer->Hdr.enmCompression);
317 if (RT_SUCCESS(rc))
318 rc = HGCMSvcGetU32(&paParms[9], (uint32_t *)&pTransfer->Hdr.enmChecksumType);
319 if (RT_SUCCESS(rc))
320 rc = HGCMSvcGetPv(&paParms[10], &pTransfer->Hdr.pvChecksum, &pTransfer->Hdr.cbChecksum);
321 if (RT_SUCCESS(rc))
322 rc = HGCMSvcGetU32(&paParms[11], &pTransfer->Hdr.cbChecksum);
323
324 LogFlowFunc(("fFlags=0x%x, cbTotalSize=%RU64, cObj=%RU64\n",
325 pTransfer->Hdr.uFlags, pTransfer->Hdr.cbTotal, pTransfer->Hdr.cObjects));
326
327 if (RT_SUCCESS(rc))
328 {
329 /** @todo Validate pvMetaFmt + cbMetaFmt. */
330 /** @todo Validate checksum. */
331 rc = SharedClipboardMetaDataResize(&pTransfer->Meta, pTransfer->Hdr.cbMeta);
332 if (RT_SUCCESS(rc))
333 pClientData->cTransfers++;
334 }
335 }
336 else
337 LogFunc(("Another transfer in progress, cTransfers=%RU32\n", pClientData->cTransfers));
338 }
339
340 break;
341 }
342
343 case VBOX_SHARED_CLIPBOARD_FN_WRITE_DATA_CHUNK:
344 {
345 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_FN_WRITE_DATA_CHUNK\n"));
346 if ( cParms == VBOX_SHARED_CLIPBOARD_CPARMS_WRITE_DATA_CHUNK
347 && pClientData->cTransfers) /* Some transfer in-flight? */
348 {
349 VBOXCLIPBOARDDATACHUNK data;
350 RT_ZERO(data);
351 /* Note: Context ID (paParms[0]) not used yet. */
352 rc = HGCMSvcGetPv(&paParms[1], (void**)&data.pvData, &data.cbData);
353 if (RT_SUCCESS(rc))
354 rc = HGCMSvcGetU32(&paParms[2], &data.cbData);
355 if (RT_SUCCESS(rc))
356 rc = HGCMSvcGetPv(&paParms[3], (void**)&data.pvChecksum, &data.cbChecksum);
357 if (RT_SUCCESS(rc))
358 rc = HGCMSvcGetU32(&paParms[4], &data.cbChecksum);
359
360 if (RT_SUCCESS(rc))
361 {
362 if (!VBoxSvcClipboardDataChunkIsValid(&data))
363 rc = VERR_INVALID_PARAMETER;
364 }
365
366 if (RT_SUCCESS(rc))
367 {
368 /** @todo Validate checksum. */
369 rc = SharedClipboardMetaDataAdd(&pTransfer->Meta, data.pvData, data.cbData);
370 if ( RT_SUCCESS(rc)
371 && SharedClipboardMetaDataGetUsed(&pTransfer->Meta) == pTransfer->Hdr.cbMeta) /* Meta data transfer complete? */
372 {
373 void *pvMeta = SharedClipboardMetaDataMutableRaw(&pTransfer->Meta);
374 const size_t cbMeta = SharedClipboardMetaDataGetSize(&pTransfer->Meta);
375
376 rc = pTransfer->List.SetFromURIData(pvMeta, cbMeta, SHAREDCLIPBOARDURILIST_FLAGS_NONE);
377
378 if ( RT_SUCCESS(rc)
379 && g_pfnExtension)
380 {
381 VBOXCLIPBOARDEXTAREAPARMS parms;
382 RT_ZERO(parms);
383
384 parms.u.fn_register.pvData = pvMeta;
385 parms.u.fn_register.cbData = cbMeta;
386
387 /* As the meta data is now complete, register a new clipboard on the host side. */
388 rc = g_pfnExtension(g_pvExtension, VBOX_CLIPBOARD_EXT_FN_AREA_REGISTER, &parms, sizeof(parms));
389 }
390
391 /* We're done processing the meta data, so just destroy it. */
392 SharedClipboardMetaDataDestroy(&pTransfer->Meta);
393 }
394 }
395 }
396 break;
397 }
398
399 case VBOX_SHARED_CLIPBOARD_FN_READ_DIR:
400 {
401 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_FN_READ_DIR\n"));
402 AssertFailedStmt(rc = VERR_NOT_IMPLEMENTED);
403 break;
404 }
405
406 case VBOX_SHARED_CLIPBOARD_FN_WRITE_DIR:
407 {
408 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_FN_WRITE_DIR\n"));
409 if ( cParms == VBOX_SHARED_CLIPBOARD_CPARMS_WRITE_DIR
410 && pClientData->cTransfers) /* Some transfer in-flight? */
411 {
412 VBOXCLIPBOARDDIRDATA data;
413 RT_ZERO(data);
414 /* Note: Context ID (paParms[0]) not used yet. */
415 rc = HGCMSvcGetPv(&paParms[1], (void**)&data.pszPath, &data.cbPath);
416 if (RT_SUCCESS(rc))
417 rc = HGCMSvcGetU32(&paParms[2], &data.cbPath);
418 if (RT_SUCCESS(rc))
419 rc = HGCMSvcGetU32(&paParms[3], &data.fMode);
420
421 LogFlowFunc(("pszPath=%s, cbPath=%RU32, fMode=0x%x\n", data.pszPath, data.cbPath, data.fMode));
422
423 if (RT_SUCCESS(rc))
424 {
425 if (!VBoxSvcClipboardDirDataIsValid(&data))
426 rc = VERR_INVALID_PARAMETER;
427 }
428
429 if (RT_SUCCESS(rc))
430 {
431 const char *pszCacheDir = pTransfer->Cache.GetDirAbs();
432 char *pszDir = RTPathJoinA(pszCacheDir, data.pszPath);
433 if (pszDir)
434 {
435 rc = RTDirCreateFullPath(pszDir, data.fMode);
436 if (RT_SUCCESS(rc))
437 {
438 /* Add for having a proper rollback. */
439 int rc2 = pTransfer->Cache.AddDir(pszDir);
440 AssertRC(rc2);
441 }
442 }
443 else
444 rc = VERR_NO_MEMORY;
445 }
446 }
447 break;
448 }
449
450 case VBOX_SHARED_CLIPBOARD_FN_READ_FILE_HDR:
451 {
452 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_FN_READ_FILE_HDR\n"));
453 AssertFailedStmt(rc = VERR_NOT_IMPLEMENTED);
454 break;
455 }
456
457 case VBOX_SHARED_CLIPBOARD_FN_WRITE_FILE_HDR:
458 {
459 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_FN_WRITE_FILE_HDR\n"));
460 if ( cParms == VBOX_SHARED_CLIPBOARD_CPARMS_WRITE_FILE_HDR
461 && pClientData->cTransfers) /* Some transfer in-flight? */
462 {
463 VBOXCLIPBOARDFILEHDR data;
464 RT_ZERO(data);
465 /* Note: Context ID (paParms[0]) not used yet. */
466 rc = HGCMSvcGetPv(&paParms[1], (void**)&data.pszFilePath, &data.cbFilePath);
467 if (RT_SUCCESS(rc))
468 rc = HGCMSvcGetU32(&paParms[2], &data.cbFilePath);
469 if (RT_SUCCESS(rc))
470 rc = HGCMSvcGetU32(&paParms[3], &data.fFlags);
471 if (RT_SUCCESS(rc))
472 rc = HGCMSvcGetU32(&paParms[4], &data.fMode);
473 if (RT_SUCCESS(rc))
474 rc = HGCMSvcGetU64(&paParms[5], &data.cbSize);
475
476 LogFlowFunc(("pszPath=%s, cbPath=%RU32, fMode=0x%x, cbSize=%RU64\n",
477 data.pszFilePath, data.cbFilePath, data.fMode, data.cbSize));
478
479 if (RT_SUCCESS(rc))
480 {
481 if (!VBoxSvcClipboardFileHdrIsValid(&data, &pTransfer->Hdr))
482 rc = VERR_INVALID_PARAMETER;
483
484 if (pTransfer->ObjCtx.pObj == NULL)
485 {
486 pTransfer->ObjCtx.pObj = new SharedClipboardURIObject(SharedClipboardURIObject::Type_File);
487 if (!pTransfer->ObjCtx.pObj) /** @todo Can this throw? */
488 rc = VERR_NO_MEMORY;
489 }
490 else /* There still is another object being processed? */
491 rc = VERR_WRONG_ORDER;
492 }
493
494 if (RT_SUCCESS(rc))
495 {
496 const char *pszCacheDir = pTransfer->Cache.GetDirAbs();
497
498 char pszPathAbs[RTPATH_MAX];
499 rc = RTPathJoin(pszPathAbs, sizeof(pszPathAbs), pszCacheDir, data.pszFilePath);
500 if (RT_SUCCESS(rc))
501 {
502 rc = SharedClipboardPathSanitize(pszPathAbs, sizeof(pszPathAbs));
503 if (RT_SUCCESS(rc))
504 {
505 SharedClipboardURIObject *pObj = vboxClipboardSvcURIObjCtxGetObj(&pTransfer->ObjCtx);
506
507 /** @todo Add sparse file support based on fFlags? (Use Open(..., fFlags | SPARSE). */
508 rc = pObj->OpenEx(pszPathAbs, SharedClipboardURIObject::View_Target,
509 RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_DENY_WRITE,
510 (data.fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRUSR | RTFS_UNIX_IWUSR);
511 if (RT_SUCCESS(rc))
512 {
513 rc = pObj->SetSize(data.cbSize);
514
515 /** @todo Unescape path before printing. */
516 LogRel2(("Clipboard: Transferring guest file '%s' to host (%RU64 bytes, mode 0x%x)\n",
517 pObj->GetDestPathAbs().c_str(), pObj->GetSize(), pObj->GetMode()));
518
519 if (pObj->IsComplete()) /* 0-byte file? We're done already. */
520 {
521 /** @todo Sanitize path. */
522 LogRel2(("Clipboard: Transferring guest file '%s' (0 bytes) to host complete\n",
523 pObj->GetDestPathAbs().c_str()));
524
525 vboxClipboardSvcURIObjCtxUninit(&pTransfer->ObjCtx);
526 }
527
528 /* Add for having a proper rollback. */
529 int rc2 = pTransfer->Cache.AddFile(pszPathAbs);
530 AssertRC(rc2);
531 }
532 else
533 LogRel(("Clipboard: Error opening/creating guest file '%s' on host, rc=%Rrc\n", pszPathAbs, rc));
534 }
535 }
536 }
537 }
538 break;
539 }
540
541 case VBOX_SHARED_CLIPBOARD_FN_READ_FILE_DATA:
542 {
543 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_FN_READ_FILE_DATA\n"));
544 AssertFailedStmt(rc = VERR_NOT_IMPLEMENTED);
545 break;
546 }
547
548 case VBOX_SHARED_CLIPBOARD_FN_WRITE_FILE_DATA:
549 {
550 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_FN_WRITE_FILE_DATA\n"));
551 if ( cParms == VBOX_SHARED_CLIPBOARD_CPARMS_WRITE_FILE_DATA
552 && pClientData->cTransfers) /* Some transfer in-flight? */
553 {
554 VBOXCLIPBOARDFILEDATA data;
555 RT_ZERO(data);
556 /* Note: Context ID (paParms[0]) not used yet. */
557 rc = HGCMSvcGetPv(&paParms[1], (void**)&data.pvData, &data.cbData);
558 if (RT_SUCCESS(rc))
559 rc = HGCMSvcGetU32(&paParms[2], &data.cbData);
560 if (RT_SUCCESS(rc))
561 rc = HGCMSvcGetPv(&paParms[3], (void**)&data.pvChecksum, &data.cbChecksum);
562 if (RT_SUCCESS(rc))
563 rc = HGCMSvcGetU32(&paParms[4], &data.cbChecksum);
564
565 LogFlowFunc(("pvData=0x%p, cbData=%RU32\n", data.pvData, data.cbData));
566
567 if (RT_SUCCESS(rc))
568 {
569 if (!VBoxSvcClipboardFileDataIsValid(&data, &pTransfer->Hdr))
570 rc = VERR_INVALID_PARAMETER;
571
572 if (!vboxClipboardSvcURIObjCtxIsValid(&pTransfer->ObjCtx))
573 rc = VERR_WRONG_ORDER;
574 }
575
576 if (RT_SUCCESS(rc))
577 {
578 SharedClipboardURIObject *pObj = vboxClipboardSvcURIObjCtxGetObj(&pTransfer->ObjCtx);
579
580 uint32_t cbWritten;
581 rc = pObj->Write(data.pvData, data.cbData, &cbWritten);
582 if (RT_SUCCESS(rc))
583 {
584 Assert(cbWritten <= data.cbData);
585 if (cbWritten < data.cbData)
586 {
587 /** @todo What to do when the host's disk is full? */
588 rc = VERR_DISK_FULL;
589 }
590
591 if ( pObj->IsComplete()
592 || RT_FAILURE(rc))
593 vboxClipboardSvcURIObjCtxUninit(&pTransfer->ObjCtx);
594 }
595 else
596 LogRel(("Clipboard: Error writing guest file data for '%s', rc=%Rrc\n", pObj->GetDestPathAbs().c_str(), rc));
597 }
598 }
599 break;
600 }
601
602 case VBOX_SHARED_CLIPBOARD_FN_WRITE_CANCEL:
603 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_FN_WRITE_CANCEL\n"));
604 AssertFailedStmt(rc = VERR_NOT_IMPLEMENTED);
605 break;
606
607 case VBOX_SHARED_CLIPBOARD_FN_WRITE_ERROR:
608 LogFlowFunc(("VBOX_SHARED_CLIPBOARD_FN_WRITE_ERROR\n"));
609 AssertFailedStmt(rc = VERR_NOT_IMPLEMENTED);
610 break;
611
612 default:
613 AssertMsgFailed(("Not implemented\n"));
614 break;
615 }
616
617#ifdef DEBUG_andy
618 AssertRC(rc);
619#endif
620 return rc;
621}
622
623/**
624 * URI host handler for the Shared Clipboard host service.
625 *
626 * @returns VBox status code.
627 * @param u32Function Function number being called.
628 * @param cParms Number of function parameters supplied.
629 * @param paParms Array function parameters supplied.
630 */
631int vboxClipboardSvcURIHostHandler(uint32_t u32Function,
632 uint32_t cParms,
633 VBOXHGCMSVCPARM paParms[])
634{
635 RT_NOREF(cParms, paParms);
636
637 int rc = VERR_INVALID_PARAMETER; /* Play safe. */
638
639 switch (u32Function)
640 {
641 case VBOX_SHARED_CLIPBOARD_HOST_FN_CANCEL:
642 break;
643
644 case VBOX_SHARED_CLIPBOARD_HOST_FN_ERROR:
645 break;
646
647 default:
648 AssertMsgFailed(("Not implemented\n"));
649 break;
650
651 }
652
653 return rc;
654}
655
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