VirtualBox

source: vbox/trunk/src/VBox/GuestHost/SharedClipboard/clipboard-uri.cpp@ 79630

Last change on this file since 79630 was 79630, checked in by vboxsync, 5 years ago

Shared Clipboard/URI: Update.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 57.2 KB
Line 
1/* $Id: clipboard-uri.cpp 79630 2019-07-09 08:14:01Z vboxsync $ */
2/** @file
3 * Shared Clipboard: Common URI transfer handling code.
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#define LOG_GROUP LOG_GROUP_SHARED_CLIPBOARD
19#include <VBox/log.h>
20
21#include <iprt/dir.h>
22#include <iprt/file.h>
23#include <iprt/path.h>
24#include <iprt/semaphore.h>
25
26#include <VBox/err.h>
27#include <VBox/HostServices/VBoxClipboardSvc.h>
28#include <VBox/GuestHost/SharedClipboard-uri.h>
29
30
31#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
32static int sharedClipboardURITransferThreadCreate(PSHAREDCLIPBOARDURITRANSFER pTransfer, PFNRTTHREAD pfnThreadFunc, void *pvUser);
33static int sharedClipboardURITransferThreadDestroy(PSHAREDCLIPBOARDURITRANSFER pTransfer, RTMSINTERVAL uTimeoutMs);
34static int sharedClipboardURITransferWriteThread(RTTHREAD hThread, void *pvUser);
35static PSHAREDCLIPBOARDURITRANSFER sharedClipboardURICtxGetTransferInternal(PSHAREDCLIPBOARDURICTX pURI, uint32_t uIdx);
36#endif
37
38
39/**
40 * Allocates a VBOXCLIPBOARDListHdr structure.
41 *
42 * @returns VBox status code.
43 * @param ppListEntry Where to store the allocated VBOXCLIPBOARDListHdr structure on success.
44 */
45int SharedClipboardURIListHdrAlloc(PVBOXCLIPBOARDLISTHDR *ppListHdr)
46{
47 int rc;
48
49 PVBOXCLIPBOARDLISTHDR pListHdr = (PVBOXCLIPBOARDLISTHDR)RTMemAllocZ(sizeof(VBOXCLIPBOARDLISTHDR));
50 if (pListHdr)
51 {
52 *ppListHdr = pListHdr;
53 rc = VINF_SUCCESS;
54 }
55 else
56 rc = VERR_NO_MEMORY;
57
58 LogFlowFuncLeaveRC(rc);
59 return rc;
60}
61
62/**
63 * Frees a VBOXCLIPBOARDListHdr structure.
64 *
65 * @param pListEntry VBOXCLIPBOARDListHdr structure to free.
66 */
67void SharedClipboardURIListHdrFree(PVBOXCLIPBOARDLISTHDR pListHdr)
68{
69 if (!pListHdr)
70 return;
71
72 LogFlowFuncEnter();
73
74 SharedClipboardURIListHdrDestroy(pListHdr);
75
76 RTMemFree(pListHdr);
77 pListHdr = NULL;
78}
79
80/**
81 * Duplicates (allocates) a VBOXCLIPBOARDListHdr structure.
82 *
83 * @returns Duplicated VBOXCLIPBOARDListHdr structure on success.
84 * @param pListHdr VBOXCLIPBOARDListHdr to duplicate.
85 */
86PVBOXCLIPBOARDLISTHDR SharedClipboardURIListHdrDup(PVBOXCLIPBOARDLISTHDR pListHdr)
87{
88 AssertPtrReturn(pListHdr, NULL);
89
90 PVBOXCLIPBOARDLISTHDR pListHdrDup = (PVBOXCLIPBOARDLISTHDR)RTMemAlloc(sizeof(VBOXCLIPBOARDLISTHDR));
91 if (pListHdrDup)
92 {
93 *pListHdrDup = *pListHdr;
94 }
95
96 return pListHdrDup;
97}
98
99/**
100 * Initializes an URI data header struct.
101 *
102 * @returns VBox status code.
103 * @param pListHdr Data header struct to initialize.
104 */
105int SharedClipboardURIListHdrInit(PVBOXCLIPBOARDLISTHDR pListHdr)
106{
107 AssertPtrReturn(pListHdr, VERR_INVALID_POINTER);
108
109 LogFlowFuncEnter();
110
111 SharedClipboardURIListHdrReset(pListHdr);
112
113 return VINF_SUCCESS;
114}
115
116/**
117 * Destroys an URI data header struct.
118 *
119 * @param pListHdr Data header struct to destroy.
120 */
121void SharedClipboardURIListHdrDestroy(PVBOXCLIPBOARDLISTHDR pListHdr)
122{
123 if (!pListHdr)
124 return;
125
126 LogFlowFuncEnter();
127}
128
129/**
130 * Resets a VBOXCLIPBOARDListHdr structture.
131 *
132 * @returns VBox status code.
133 * @param pListHdr VBOXCLIPBOARDListHdr structture to reset.
134 */
135void SharedClipboardURIListHdrReset(PVBOXCLIPBOARDLISTHDR pListHdr)
136{
137 AssertPtrReturnVoid(pListHdr);
138
139 LogFlowFuncEnter();
140
141 RT_BZERO(pListHdr, sizeof(VBOXCLIPBOARDLISTHDR));
142}
143
144/**
145 * Returns whether a given clipboard data header is valid or not.
146 *
147 * @returns \c true if valid, \c false if not.
148 * @param pListHdr Clipboard data header to validate.
149 */
150bool SharedClipboardURIListHdrIsValid(PVBOXCLIPBOARDLISTHDR pListHdr)
151{
152 RT_NOREF(pListHdr);
153 return true; /** @todo Implement this. */
154}
155
156int SharedClipboardURIListOpenParmsCopy(PVBOXCLIPBOARDLISTOPENPARMS pDst, PVBOXCLIPBOARDLISTOPENPARMS pSrc)
157{
158 AssertPtrReturn(pDst, VERR_INVALID_POINTER);
159 AssertPtrReturn(pSrc, VERR_INVALID_POINTER);
160
161 int rc = VINF_SUCCESS;
162
163 if (pSrc->pszFilter)
164 {
165 pDst->pszFilter = RTStrDup(pSrc->pszFilter);
166 if (!pDst->pszFilter)
167 rc = VERR_NO_MEMORY;
168 }
169
170 if ( RT_SUCCESS(rc)
171 && pSrc->pszPath)
172 {
173 pDst->pszPath = RTStrDup(pSrc->pszPath);
174 if (!pDst->pszPath)
175 rc = VERR_NO_MEMORY;
176 }
177
178 if (RT_SUCCESS(rc))
179 {
180 pDst->fList = pDst->fList;
181 pDst->cbFilter = pSrc->cbFilter;
182 pDst->cbPath = pSrc->cbPath;
183 }
184
185 return rc;
186}
187
188PVBOXCLIPBOARDLISTOPENPARMS SharedClipboardURIListOpenParmsDup(PVBOXCLIPBOARDLISTOPENPARMS pParms)
189{
190 AssertPtrReturn(pParms, NULL);
191
192 PVBOXCLIPBOARDLISTOPENPARMS pParmsDup = (PVBOXCLIPBOARDLISTOPENPARMS)RTMemAllocZ(sizeof(VBOXCLIPBOARDLISTOPENPARMS));
193 if (!pParmsDup)
194 return NULL;
195
196 int rc = SharedClipboardURIListOpenParmsCopy(pParmsDup, pParms);
197 if (RT_FAILURE(rc))
198 {
199 SharedClipboardURIListOpenParmsDestroy(pParmsDup);
200
201 RTMemFree(pParmsDup);
202 pParmsDup = NULL;
203 }
204
205 return pParmsDup;
206}
207
208int SharedClipboardURIListOpenParmsInit(PVBOXCLIPBOARDLISTOPENPARMS pParms)
209{
210 AssertPtrReturn(pParms, VERR_INVALID_POINTER);
211
212 RT_BZERO(pParms, sizeof(VBOXCLIPBOARDLISTOPENPARMS));
213
214 pParms->cbFilter = 64;
215 pParms->pszFilter = RTStrAlloc(pParms->cbFilter);
216
217 pParms->cbPath = RTPATH_MAX;
218 pParms->pszPath = RTStrAlloc(pParms->cbPath);
219
220 LogFlowFuncLeave();
221 return VINF_SUCCESS;
222}
223
224void SharedClipboardURIListOpenParmsDestroy(PVBOXCLIPBOARDLISTOPENPARMS pParms)
225{
226 if (!pParms)
227 return;
228
229 if (pParms->pszFilter)
230 {
231 RTStrFree(pParms->pszFilter);
232 pParms->pszFilter = NULL;
233 }
234
235 if (pParms->pszPath)
236 {
237 RTStrFree(pParms->pszPath);
238 pParms->pszPath = NULL;
239 }
240}
241
242/**
243 * Creates (allocates) and initializes a clipboard list entry structure.
244 *
245 * @param ppDirData Where to return the created clipboard list entry structure on success.
246 */
247int SharedClipboardURIListEntryAlloc(PVBOXCLIPBOARDLISTENTRY *ppListEntry)
248{
249 PVBOXCLIPBOARDLISTENTRY pListEntry = (PVBOXCLIPBOARDLISTENTRY)RTMemAlloc(sizeof(VBOXCLIPBOARDLISTENTRY));
250 if (!pListEntry)
251 return VERR_NO_MEMORY;
252
253 int rc = SharedClipboardURIListEntryInit(pListEntry);
254 if (RT_SUCCESS(rc))
255 *ppListEntry = pListEntry;
256
257 return rc;
258}
259
260/**
261 * Frees a clipboard list entry structure.
262 *
263 * @param pListEntry Clipboard list entry structure to free.
264 */
265void SharedClipboardURIListEntryFree(PVBOXCLIPBOARDLISTENTRY pListEntry)
266{
267 if (!pListEntry)
268 return;
269
270 SharedClipboardURIListEntryDestroy(pListEntry);
271 RTMemFree(pListEntry);
272}
273
274/**
275 * (Deep) Copies a clipboard list entry structure.
276 *
277 * @returns VBox status code.
278 * @param pListEntry Clipboard list entry to copy.
279 */
280int SharedClipboardURIListEntryCopy(PVBOXCLIPBOARDLISTENTRY pDst, PVBOXCLIPBOARDLISTENTRY pSrc)
281{
282 AssertPtrReturn(pDst, VERR_INVALID_POINTER);
283 AssertPtrReturn(pSrc, VERR_INVALID_POINTER);
284
285 int rc = VINF_SUCCESS;
286
287 *pDst = *pSrc;
288
289 if (pSrc->pvInfo)
290 {
291 pDst->pvInfo = RTMemDup(pSrc->pvInfo, pSrc->cbInfo);
292 if (pDst->pvInfo)
293 {
294 pDst->cbInfo = pSrc->cbInfo;
295 }
296 else
297 rc = VERR_NO_MEMORY;
298 }
299
300 if (RT_FAILURE(rc))
301 {
302 if (pDst->pvInfo)
303 {
304 RTMemFree(pDst->pvInfo);
305 pDst->pvInfo = NULL;
306 pDst->cbInfo = 0;
307 }
308 }
309
310 return rc;
311}
312
313/**
314 * Duplicates (allocates) a clipboard list entry structure.
315 *
316 * @returns Duplicated clipboard list entry structure on success.
317 * @param pListEntry Clipboard list entry to duplicate.
318 */
319PVBOXCLIPBOARDLISTENTRY SharedClipboardURIListEntryDup(PVBOXCLIPBOARDLISTENTRY pListEntry)
320{
321 AssertPtrReturn(pListEntry, NULL);
322
323 int rc = VINF_SUCCESS;
324
325 PVBOXCLIPBOARDLISTENTRY pListEntryDup = (PVBOXCLIPBOARDLISTENTRY)RTMemAllocZ(sizeof(VBOXCLIPBOARDLISTENTRY));
326 if (pListEntryDup)
327 rc = SharedClipboardURIListEntryCopy(pListEntryDup, pListEntry);
328
329 if (RT_FAILURE(rc))
330 {
331 SharedClipboardURIListEntryDestroy(pListEntryDup);
332
333 RTMemFree(pListEntryDup);
334 pListEntryDup = NULL;
335 }
336
337 return pListEntryDup;
338}
339
340/**
341 * Initializes a clipboard list entry structure.
342 *
343 * @param pListEntry clipboard list entry structure to initialize.
344 */
345int SharedClipboardURIListEntryInit(PVBOXCLIPBOARDLISTENTRY pListEntry)
346{
347 RT_BZERO(pListEntry, sizeof(VBOXCLIPBOARDLISTENTRY));
348
349 return VINF_SUCCESS;
350}
351
352/**
353 * Initializes a clipboard list entry structure.
354 *
355 * @param pListEntry clipboard list entry structure to destroy.
356 */
357void SharedClipboardURIListEntryDestroy(PVBOXCLIPBOARDLISTENTRY pListEntry)
358{
359 if (!pListEntry)
360 return;
361
362 if (pListEntry->pvInfo)
363 {
364 RTMemFree(pListEntry->pvInfo);
365 pListEntry->pvInfo = NULL;
366 pListEntry->cbInfo = 0;
367 }
368}
369
370/**
371 * Returns whether a given clipboard data chunk is valid or not.
372 *
373 * @returns \c true if valid, \c false if not.
374 * @param pListEntry Clipboard data chunk to validate.
375 */
376bool SharedClipboardURIListEntryIsValid(PVBOXCLIPBOARDLISTENTRY pListEntry)
377{
378 RT_NOREF(pListEntry);
379
380 /** @todo Verify checksum. */
381
382 return true; /** @todo Implement this. */
383}
384
385#if 0
386/**
387 * Creates (allocates) and initializes a VBOXCLIPBOARDDIRDATA structure.
388 *
389 * @param ppDirData Where to return the created VBOXCLIPBOARDDIRDATA structure on success.
390 */
391int SharedClipboardURIDirDataAlloc(PVBOXCLIPBOARDDIRDATA *ppDirData)
392{
393 PVBOXCLIPBOARDDIRDATA pDirData = (PVBOXCLIPBOARDDIRDATA)RTMemAlloc(sizeof(VBOXCLIPBOARDDIRDATA));
394 if (!pDirData)
395 return VERR_NO_MEMORY;
396
397 int rc = SharedClipboardURIDirDataInit(pDirData);
398 if (RT_SUCCESS(rc))
399 *ppDirData = pDirData;
400
401 return rc;
402}
403
404/**
405 * Frees a VBOXCLIPBOARDDIRDATA structure.
406 *
407 * @param pDirData Where to return the created VBOXCLIPBOARDDIRDATA structure on success.
408 */
409void SharedClipboardURIDirDataFree(PVBOXCLIPBOARDDIRDATA pDirData)
410{
411 if (!pDirData)
412 return;
413
414 SharedClipboardURIDirDataDestroy(pDirData);
415 RTMemFree(pDirData);
416}
417
418/**
419 * Initializes a VBOXCLIPBOARDDIRDATA structure.
420 *
421 * @param pDirData VBOXCLIPBOARDDIRDATA structure to initialize.
422 */
423int SharedClipboardURIDirDataInit(PVBOXCLIPBOARDDIRDATA pDirData)
424{
425 RT_BZERO(pDirData, sizeof(VBOXCLIPBOARDDIRDATA));
426
427 return VINF_SUCCESS;
428}
429
430/**
431 * Destroys a VBOXCLIPBOARDDIRDATA structure.
432 *
433 * @param pDirData VBOXCLIPBOARDDIRDATA structure to destroy.
434 */
435void SharedClipboardURIDirDataDestroy(PVBOXCLIPBOARDDIRDATA pDirData)
436{
437 if (!pDirData)
438 return;
439
440 if (pDirData->pszPath)
441 {
442 Assert(pDirData->cbPath);
443 RTStrFree(pDirData->pszPath);
444 pDirData->pszPath = NULL;
445 }
446}
447
448/**
449 * Duplicates (allocates) a VBOXCLIPBOARDDIRDATA structure.
450 *
451 * @returns Duplicated VBOXCLIPBOARDDIRDATA structure on success.
452 * @param pDirData VBOXCLIPBOARDDIRDATA to duplicate.
453 */
454PVBOXCLIPBOARDDIRDATA SharedClipboardURIDirDataDup(PVBOXCLIPBOARDDIRDATA pDirData)
455{
456 AssertPtrReturn(pDirData, NULL);
457
458 PVBOXCLIPBOARDDIRDATA pDirDataDup = (PVBOXCLIPBOARDDIRDATA)RTMemAllocZ(sizeof(VBOXCLIPBOARDDIRDATA));
459 if (pDirDataDup)
460 {
461 *pDirDataDup = *pDirData;
462
463 if (pDirData->pszPath)
464 {
465 pDirDataDup->pszPath = RTStrDup(pDirData->pszPath);
466 if (pDirDataDup->pszPath)
467 pDirDataDup->cbPath = pDirData->cbPath;
468 }
469 }
470
471 return pDirDataDup;
472}
473
474/**
475 * Returns whether given clipboard directory data is valid or not.
476 *
477 * @returns \c true if valid, \c false if not.
478 * @param pDirData Clipboard directory data to validate.
479 */
480bool SharedClipboardURIDirDataIsValid(PVBOXCLIPBOARDDIRDATA pDirData)
481{
482 if ( !pDirData->cbPath
483 || pDirData->cbPath > RTPATH_MAX)
484 return false;
485
486 if (!RTStrIsValidEncoding(pDirData->pszPath))
487 return false;
488
489 return true;
490}
491
492/**
493 * Initializes a VBOXCLIPBOARDFILEHDR structure.
494 *
495 * @param pDirData VBOXCLIPBOARDFILEHDR structure to initialize.
496 */
497int SharedClipboardURIFileHdrInit(PVBOXCLIPBOARDFILEHDR pFileHdr)
498{
499 RT_BZERO(pFileHdr, sizeof(VBOXCLIPBOARDFILEHDR));
500
501 return VINF_SUCCESS;
502}
503
504/**
505 * Destroys a VBOXCLIPBOARDFILEHDR structure.
506 *
507 * @param pFileHdr VBOXCLIPBOARDFILEHDR structure to destroy.
508 */
509void SharedClipboardURIFileHdrDestroy(PVBOXCLIPBOARDFILEHDR pFileHdr)
510{
511 if (!pFileHdr)
512 return;
513
514 if (pFileHdr->pszFilePath)
515 {
516 Assert(pFileHdr->pszFilePath);
517 RTStrFree(pFileHdr->pszFilePath);
518 pFileHdr->pszFilePath = NULL;
519 }
520}
521
522/**
523 * Frees a VBOXCLIPBOARDFILEHDR structure.
524 *
525 * @param pFileHdr VBOXCLIPBOARDFILEHDR structure to free.
526 */
527void SharedClipboardURIFileHdrFree(PVBOXCLIPBOARDFILEHDR pFileHdr)
528{
529 if (!pFileHdr)
530 return;
531
532 SharedClipboardURIFileHdrDestroy(pFileHdr);
533
534 RTMemFree(pFileHdr);
535 pFileHdr = NULL;
536}
537
538/**
539 * Duplicates (allocates) a VBOXCLIPBOARDFILEHDR structure.
540 *
541 * @returns Duplicated VBOXCLIPBOARDFILEHDR structure on success.
542 * @param pFileHdr VBOXCLIPBOARDFILEHDR to duplicate.
543 */
544PVBOXCLIPBOARDFILEHDR SharedClipboardURIFileHdrDup(PVBOXCLIPBOARDFILEHDR pFileHdr)
545{
546 AssertPtrReturn(pFileHdr, NULL);
547
548 PVBOXCLIPBOARDFILEHDR pFileHdrDup = (PVBOXCLIPBOARDFILEHDR)RTMemAllocZ(sizeof(VBOXCLIPBOARDFILEHDR));
549 if (pFileHdrDup)
550 {
551 *pFileHdrDup = *pFileHdr;
552
553 if (pFileHdr->pszFilePath)
554 {
555 pFileHdrDup->pszFilePath = RTStrDup(pFileHdr->pszFilePath);
556 if (pFileHdrDup->pszFilePath)
557 pFileHdrDup->cbFilePath = pFileHdrDup->cbFilePath;
558 }
559 }
560
561 return pFileHdrDup;
562}
563
564/**
565 * Returns whether a given clipboard file header is valid or not.
566 *
567 * @returns \c true if valid, \c false if not.
568 * @param pFileHdr Clipboard file header to validate.
569 * @param pListHdr Data header to use for validation.
570 */
571bool SharedClipboardURIFileHdrIsValid(PVBOXCLIPBOARDFILEHDR pFileHdr, PVBOXCLIPBOARDLISTHDR pListHdr)
572{
573 if ( !pFileHdr->cbFilePath
574 || pFileHdr->cbFilePath > RTPATH_MAX)
575 return false;
576
577 if (!RTStrIsValidEncoding(pFileHdr->pszFilePath))
578 return false;
579
580 if (pFileHdr->cbSize > pListHdr->cbTotalSize)
581 return false;
582
583 return true;
584}
585
586/**
587 * Destroys a VBOXCLIPBOARDFILEDATA structure.
588 *
589 * @param pFileData VBOXCLIPBOARDFILEDATA structure to destroy.
590 */
591void SharedClipboardURIFileDataDestroy(PVBOXCLIPBOARDFILEDATA pFileData)
592{
593 if (!pFileData)
594 return;
595
596 if (pFileData->pvData)
597 {
598 Assert(pFileData->cbData);
599 RTMemFree(pFileData->pvData);
600 pFileData->pvData = NULL;
601 }
602}
603
604/**
605 * Duplicates (allocates) a VBOXCLIPBOARDFILEDATA structure.
606 *
607 * @returns Duplicated VBOXCLIPBOARDFILEDATA structure on success.
608 * @param pFileData VBOXCLIPBOARDFILEDATA to duplicate.
609 */
610PVBOXCLIPBOARDFILEDATA SharedClipboardURIFileDataDup(PVBOXCLIPBOARDFILEDATA pFileData)
611{
612 AssertPtrReturn(pFileData, NULL);
613
614 PVBOXCLIPBOARDFILEDATA pFileDataDup = (PVBOXCLIPBOARDFILEDATA)RTMemAllocZ(sizeof(VBOXCLIPBOARDFILEDATA));
615 if (pFileDataDup)
616 {
617 *pFileDataDup = *pFileData;
618
619 if (pFileData->pvData)
620 {
621 pFileDataDup->pvData = RTMemDup(pFileData->pvData, pFileData->cbData);
622 if (pFileDataDup->pvData)
623 pFileDataDup->cbData = pFileDataDup->cbData;
624 }
625
626 if (pFileData->pvChecksum)
627 {
628 pFileDataDup->pvChecksum = RTMemDup(pFileData->pvChecksum, pFileData->cbChecksum);
629 if (pFileDataDup->pvChecksum)
630 pFileDataDup->cbChecksum = pFileData->cbChecksum;
631 }
632 }
633
634 return pFileDataDup;
635}
636
637/**
638 * Returns whether given clipboard file data is valid or not.
639 *
640 * @returns \c true if valid, \c false if not.
641 * @param pFileData Clipboard file data to validate.
642 * @param pListHdr Data header to use for validation.
643 */
644bool SharedClipboardURIFileDataIsValid(PVBOXCLIPBOARDFILEDATA pFileData, PVBOXCLIPBOARDLISTHDR pListHdr)
645{
646 RT_NOREF(pFileData, pListHdr);
647 return true;
648}
649#endif
650
651/**
652 * Initializes an URI object context.
653 *
654 * @returns VBox status code.
655 * @param pObjCtx URI object context to initialize.
656 */
657int SharedClipboardURIObjCtxInit(PSHAREDCLIPBOARDCLIENTURIOBJCTX pObjCtx)
658{
659 AssertPtrReturn(pObjCtx, VERR_INVALID_POINTER);
660
661 LogFlowFuncEnter();
662
663 pObjCtx->uHandle = SHAREDCLIPBOARDOBJHANDLE_INVALID;
664
665 return VINF_SUCCESS;
666}
667
668/**
669 * Destroys an URI object context.
670 *
671 * @param pObjCtx URI object context to destroy.
672 */
673void SharedClipboardURIObjCtxDestroy(PSHAREDCLIPBOARDCLIENTURIOBJCTX pObjCtx)
674{
675 AssertPtrReturnVoid(pObjCtx);
676
677 LogFlowFuncEnter();
678}
679
680/**
681 * Returns if an URI object context is valid or not.
682 *
683 * @returns \c true if valid, \c false if not.
684 * @param pObjCtx URI object context to check.
685 */
686bool SharedClipboardURIObjCtxIsValid(PSHAREDCLIPBOARDCLIENTURIOBJCTX pObjCtx)
687{
688 return ( pObjCtx
689 && pObjCtx->uHandle != SHAREDCLIPBOARDOBJHANDLE_INVALID);
690}
691
692/**
693 * Initializes an URI clipboard transfer struct.
694 *
695 * @returns VBox status code.
696 * @param enmDir Specifies the transfer direction of this transfer.
697 * @param enmSource Specifies the data source of the transfer.
698 * @param ppTransfer Where to return the created URI transfer struct.
699 * Must be destroyed by SharedClipboardURITransferDestroy().
700 */
701int SharedClipboardURITransferCreate(SHAREDCLIPBOARDURITRANSFERDIR enmDir, SHAREDCLIPBOARDSOURCE enmSource,
702 PSHAREDCLIPBOARDURITRANSFER *ppTransfer)
703{
704 AssertPtrReturn(ppTransfer, VERR_INVALID_POINTER);
705
706 LogFlowFuncEnter();
707
708 PSHAREDCLIPBOARDURITRANSFER pTransfer = (PSHAREDCLIPBOARDURITRANSFER)RTMemAlloc(sizeof(SHAREDCLIPBOARDURITRANSFER));
709 if (!pTransfer)
710 return VERR_NO_MEMORY;
711
712 int rc = VINF_SUCCESS;
713
714 pTransfer->State.enmStatus = SHAREDCLIPBOARDURITRANSFERSTATUS_NONE;
715 pTransfer->State.enmDir = enmDir;
716 pTransfer->State.enmSource = enmSource;
717
718 LogFlowFunc(("enmDir=%RU32, enmSource=%RU32\n", pTransfer->State.enmDir, pTransfer->State.enmSource));
719
720 pTransfer->pArea = NULL; /* Will be created later if needed. */
721
722 pTransfer->Thread.hThread = NIL_RTTHREAD;
723 pTransfer->Thread.fCancelled = false;
724 pTransfer->Thread.fStarted = false;
725 pTransfer->Thread.fStop = false;
726
727 pTransfer->pvUser = NULL;
728 pTransfer->cbUser = 0;
729
730 RT_ZERO(pTransfer->Callbacks);
731
732 pTransfer->pMapEvents = new SharedClipboardURITransferEventMap();
733 if (pTransfer->pMapEvents)
734 {
735 pTransfer->pMapLists = new SharedClipboardURIListMap();
736 if (pTransfer->pMapLists)
737 {
738 *ppTransfer = pTransfer;
739 }
740 }
741 else
742 rc = VERR_NO_MEMORY;
743
744 if (RT_FAILURE(rc))
745 {
746 RTMemFree(pTransfer);
747 }
748
749 LogFlowFuncLeaveRC(rc);
750 return rc;
751}
752
753/**
754 * Destroys an URI clipboard transfer context struct.
755 *
756 * @returns VBox status code.
757 * @param pURI URI clipboard transfer to destroy.
758 */
759int SharedClipboardURITransferDestroy(PSHAREDCLIPBOARDURITRANSFER pTransfer)
760{
761 if (!pTransfer)
762 return VINF_SUCCESS;
763
764 LogFlowFuncEnter();
765
766 int rc = sharedClipboardURITransferThreadDestroy(pTransfer, 30 * 1000 /* Timeout in ms */);
767 if (RT_FAILURE(rc))
768 return rc;
769
770 if (pTransfer->pMapEvents)
771 {
772 delete pTransfer->pMapEvents;
773 pTransfer->pMapEvents = NULL;
774 }
775
776 if (pTransfer->pMapLists)
777 {
778 delete pTransfer->pMapLists;
779 pTransfer->pMapLists = NULL;
780 }
781
782 LogFlowFuncLeave();
783 return VINF_SUCCESS;
784}
785
786int SharedClipboardURITransferOpen(PSHAREDCLIPBOARDURITRANSFER pTransfer)
787{
788 int rc = VINF_SUCCESS;
789
790 if (pTransfer->ProviderIface.pfnTransferOpen)
791 rc = pTransfer->ProviderIface.pfnTransferOpen(&pTransfer->ProviderCtx);
792
793 LogFlowFuncLeaveRC(rc);
794 return rc;
795}
796
797int SharedClipboardURITransferClose(PSHAREDCLIPBOARDURITRANSFER pTransfer)
798{
799 int rc = VINF_SUCCESS;
800
801 if (pTransfer->ProviderIface.pfnTransferClose)
802 rc = pTransfer->ProviderIface.pfnTransferClose(&pTransfer->ProviderCtx);
803
804 LogFlowFuncLeaveRC(rc);
805 return rc;
806}
807
808static SHAREDCLIPBOARDLISTHANDLE sharedClipboardURITransferListHandleNew(PSHAREDCLIPBOARDURITRANSFER pTransfer)
809{
810 RT_NOREF(pTransfer);
811
812 return 42; /** @todo FIX !!!!! */
813}
814
815int SharedClipboardURITransferListOpen(PSHAREDCLIPBOARDURITRANSFER pTransfer, PVBOXCLIPBOARDLISTOPENPARMS pOpenParms,
816 PSHAREDCLIPBOARDLISTHANDLE phList)
817{
818 AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
819 AssertPtrReturn(pOpenParms, VERR_INVALID_POINTER);
820 AssertPtrReturn(phList, VERR_INVALID_POINTER);
821
822 int rc;
823
824 SHAREDCLIPBOARDLISTHANDLE hList = SHAREDCLIPBOARDLISTHANDLE_INVALID;
825
826 if (pTransfer->State.enmSource == SHAREDCLIPBOARDSOURCE_LOCAL)
827 {
828 PSHAREDCLIPBOARDURILISTHANDLEINFO pInfo
829 = (PSHAREDCLIPBOARDURILISTHANDLEINFO)RTMemAlloc(sizeof(SHAREDCLIPBOARDURILISTHANDLEINFO));
830 if (pInfo)
831 {
832 if ( !pOpenParms->pszPath
833 || !strlen(pOpenParms->pszPath))
834 RTStrAPrintf(&pOpenParms->pszPath, "C:\\Temp"); /** @todo FIX !!!! */
835
836 RTFSOBJINFO objInfo;
837 rc = RTPathQueryInfo(pOpenParms->pszPath, &objInfo, RTFSOBJATTRADD_NOTHING);
838 if (RTFS_IS_DIRECTORY(objInfo.Attr.fMode))
839 {
840 rc = RTDirOpen(&pInfo->u.Local.hDirRoot, pOpenParms->pszPath);
841 }
842 else if (RTFS_IS_FILE(objInfo.Attr.fMode))
843 {
844 rc = RTFileOpen(&pInfo->u.Local.hFile, pOpenParms->pszPath, RTFILE_O_READ | RTFILE_O_DENY_WRITE);
845 }
846 else if (RTFS_IS_SYMLINK(objInfo.Attr.fMode))
847 {
848 rc = VERR_NOT_IMPLEMENTED; /** @todo */
849 }
850 else
851 AssertFailedStmt(rc = VERR_NOT_SUPPORTED);
852
853 if (RT_SUCCESS(rc))
854 rc = SharedClipboardURIListOpenParmsCopy(&pInfo->OpenParms, pOpenParms);
855
856 if (RT_SUCCESS(rc))
857 {
858 pInfo->fMode = objInfo.Attr.fMode;
859
860 hList = sharedClipboardURITransferListHandleNew(pTransfer);
861
862 pTransfer->pMapLists->insert(
863 std::pair<SHAREDCLIPBOARDLISTHANDLE, PSHAREDCLIPBOARDURILISTHANDLEINFO>(hList, pInfo));
864 }
865 else
866 {
867 if (RTFS_IS_DIRECTORY(objInfo.Attr.fMode))
868 {
869 if (RTDirIsValid(pInfo->u.Local.hDirRoot))
870 RTDirClose(pInfo->u.Local.hDirRoot);
871 }
872 else if (RTFS_IS_FILE(objInfo.Attr.fMode))
873 {
874 if (RTFileIsValid(pInfo->u.Local.hFile))
875 RTFileClose(pInfo->u.Local.hFile);
876 }
877
878 RTMemFree(pInfo);
879 pInfo = NULL;
880 }
881 }
882 else
883 rc = VERR_NO_MEMORY;
884 }
885 else if (pTransfer->State.enmSource == SHAREDCLIPBOARDSOURCE_REMOTE)
886 {
887 if (pTransfer->ProviderIface.pfnListOpen)
888 {
889 rc = pTransfer->ProviderIface.pfnListOpen(&pTransfer->ProviderCtx, pOpenParms, &hList);
890 }
891 else
892 rc = VERR_NOT_SUPPORTED;
893 }
894 else
895 AssertFailedStmt(rc = VERR_NOT_IMPLEMENTED);
896
897 if (RT_SUCCESS(rc))
898 *phList = hList;
899
900 LogFlowFuncLeaveRC(rc);
901 return rc;
902}
903
904int SharedClipboardURITransferListClose(PSHAREDCLIPBOARDURITRANSFER pTransfer, SHAREDCLIPBOARDLISTHANDLE hList)
905{
906 AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
907
908 if (hList == SHAREDCLIPBOARDLISTHANDLE_INVALID)
909 return VINF_SUCCESS;
910
911 int rc = VINF_SUCCESS;
912
913 if (pTransfer->State.enmSource == SHAREDCLIPBOARDSOURCE_LOCAL)
914 {
915 SharedClipboardURIListMap::iterator itList = pTransfer->pMapLists->find(hList);
916 if (itList != pTransfer->pMapLists->end())
917 {
918 PSHAREDCLIPBOARDURILISTHANDLEINFO pInfo = itList->second;
919 AssertPtr(pInfo);
920
921 if (RTDirIsValid(pInfo->u.Local.hDirRoot))
922 RTDirClose(pInfo->u.Local.hDirRoot);
923
924 RTMemFree(pInfo);
925
926 pTransfer->pMapLists->erase(itList);
927 }
928 else
929 rc = VERR_NOT_FOUND;
930 }
931 else if (pTransfer->State.enmSource == SHAREDCLIPBOARDSOURCE_REMOTE)
932 {
933 if (pTransfer->ProviderIface.pfnListClose)
934 {
935 rc = pTransfer->ProviderIface.pfnListClose(&pTransfer->ProviderCtx, hList);
936 }
937 else
938 rc = VERR_NOT_SUPPORTED;
939 }
940
941 LogFlowFuncLeaveRC(rc);
942 return rc;
943}
944
945static int sharedClipboardURITransferListHdrAddFile(PVBOXCLIPBOARDLISTHDR pHdr, const char *pszPath)
946{
947 uint64_t cbSize = 0;
948 int rc = RTFileQuerySize(pszPath, &cbSize);
949 if (RT_SUCCESS(rc))
950 {
951 pHdr->cbTotalSize += cbSize;
952 pHdr->cTotalObjects++;
953 }
954
955 LogFlowFuncLeaveRC(rc);
956 return rc;
957}
958
959static int sharedClipboardURITransferListHdrFromDir(PVBOXCLIPBOARDLISTHDR pHdr,
960 const char *pcszSrcPath, const char *pcszDstPath,
961 const char *pcszDstBase, size_t cchDstBase)
962{
963 AssertPtrReturn(pcszSrcPath, VERR_INVALID_POINTER);
964 AssertPtrReturn(pcszDstBase, VERR_INVALID_POINTER);
965 AssertPtrReturn(pcszDstPath, VERR_INVALID_POINTER);
966
967 LogFlowFunc(("pcszSrcPath=%s, pcszDstPath=%s, pcszDstBase=%s, cchDstBase=%zu\n",
968 pcszSrcPath, pcszDstPath, pcszDstBase, cchDstBase));
969
970 RTFSOBJINFO objInfo;
971 int rc = RTPathQueryInfo(pcszSrcPath, &objInfo, RTFSOBJATTRADD_NOTHING);
972 if (RT_SUCCESS(rc))
973 {
974 if (RTFS_IS_DIRECTORY(objInfo.Attr.fMode))
975 {
976 pHdr->cTotalObjects++; /* Add directory itself. */
977
978 if (RT_SUCCESS(rc))
979 {
980 RTDIR hDir;
981 rc = RTDirOpen(&hDir, pcszSrcPath);
982 if (RT_SUCCESS(rc))
983 {
984 size_t cbDirEntry = 0;
985 PRTDIRENTRYEX pDirEntry = NULL;
986 do
987 {
988 /* Retrieve the next directory entry. */
989 rc = RTDirReadExA(hDir, &pDirEntry, &cbDirEntry, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK);
990 if (RT_FAILURE(rc))
991 {
992 if (rc == VERR_NO_MORE_FILES)
993 rc = VINF_SUCCESS;
994 break;
995 }
996
997 switch (pDirEntry->Info.Attr.fMode & RTFS_TYPE_MASK)
998 {
999 case RTFS_TYPE_DIRECTORY:
1000 {
1001 /* Skip "." and ".." entries. */
1002 if (RTDirEntryExIsStdDotLink(pDirEntry))
1003 break;
1004
1005 char *pszSrc = RTPathJoinA(pcszSrcPath, pDirEntry->szName);
1006 if (pszSrc)
1007 {
1008 char *pszDst = RTPathJoinA(pcszDstPath, pDirEntry->szName);
1009 if (pszDst)
1010 {
1011 rc = sharedClipboardURITransferListHdrFromDir(pHdr, pszSrc, pszDst,
1012 pcszDstBase, cchDstBase);
1013 RTStrFree(pszDst);
1014 }
1015 else
1016 rc = VERR_NO_MEMORY;
1017
1018 RTStrFree(pszSrc);
1019 }
1020 else
1021 rc = VERR_NO_MEMORY;
1022 break;
1023 }
1024
1025 case RTFS_TYPE_FILE:
1026 {
1027 char *pszSrc = RTPathJoinA(pcszSrcPath, pDirEntry->szName);
1028 if (pszSrc)
1029 {
1030 rc = sharedClipboardURITransferListHdrAddFile(pHdr, pszSrc);
1031 RTStrFree(pszSrc);
1032 }
1033 else
1034 rc = VERR_NO_MEMORY;
1035 break;
1036 }
1037 case RTFS_TYPE_SYMLINK:
1038 {
1039 /** @todo Not implemented yet. */
1040 }
1041
1042 default:
1043 break;
1044 }
1045
1046 } while (RT_SUCCESS(rc));
1047
1048 RTDirReadExAFree(&pDirEntry, &cbDirEntry);
1049 RTDirClose(hDir);
1050 }
1051 }
1052 }
1053 else if (RTFS_IS_FILE(objInfo.Attr.fMode))
1054 {
1055 rc = sharedClipboardURITransferListHdrAddFile(pHdr, pcszSrcPath);
1056 }
1057 else if (RTFS_IS_SYMLINK(objInfo.Attr.fMode))
1058 {
1059 /** @todo Not implemented yet. */
1060 }
1061 else
1062 rc = VERR_NOT_SUPPORTED;
1063 }
1064
1065 LogFlowFuncLeaveRC(rc);
1066 return rc;
1067}
1068
1069int SharedClipboardURITransferListGetHeader(PSHAREDCLIPBOARDURITRANSFER pTransfer, SHAREDCLIPBOARDLISTHANDLE hList,
1070 PVBOXCLIPBOARDLISTHDR pHdr)
1071{
1072 AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
1073 AssertPtrReturn(pHdr, VERR_INVALID_POINTER);
1074
1075 int rc;
1076
1077 LogFlowFunc(("hList=%RU64\n", hList));
1078
1079 if (pTransfer->State.enmSource == SHAREDCLIPBOARDSOURCE_LOCAL)
1080 {
1081 SharedClipboardURIListMap::iterator itList = pTransfer->pMapLists->find(hList);
1082 if (itList != pTransfer->pMapLists->end())
1083 {
1084 rc = SharedClipboardURIListHdrInit(pHdr);
1085 if (RT_SUCCESS(rc))
1086 {
1087 PSHAREDCLIPBOARDURILISTHANDLEINFO pInfo = itList->second;
1088 AssertPtr(pInfo);
1089
1090 if (RTFS_IS_DIRECTORY(pInfo->fMode))
1091 {
1092 char *pszSrcPath = RTStrDup(pInfo->OpenParms.pszPath);
1093 if (pszSrcPath)
1094 {
1095 size_t cbSrcPathLen = RTPathStripTrailingSlash(pszSrcPath);
1096 if (cbSrcPathLen)
1097 {
1098 char *pszFileName = RTPathFilename(pszSrcPath);
1099 if (pszFileName)
1100 {
1101 Assert(pszFileName >= pszSrcPath);
1102 size_t cchDstBase = pszFileName - pszSrcPath;
1103 char *pszDstPath = &pszSrcPath[cchDstBase];
1104
1105 LogFlowFunc(("pszSrcPath=%s, pszFileName=%s, pszDstPath=%s\n", pszSrcPath, pszFileName, pszDstPath));
1106 rc = sharedClipboardURITransferListHdrFromDir(pHdr,
1107 pszSrcPath, pszSrcPath, pszSrcPath, cchDstBase);
1108 }
1109 else
1110 rc = VERR_PATH_NOT_FOUND;
1111 }
1112 else
1113 rc = VERR_INVALID_PARAMETER;
1114
1115 RTStrFree(pszSrcPath);
1116 }
1117 else
1118 rc = VERR_NO_MEMORY;
1119 }
1120 else if (RTFS_IS_FILE(pInfo->fMode))
1121 {
1122 pHdr->cTotalObjects = 1;
1123
1124 RTFSOBJINFO objInfo;
1125 rc = RTFileQueryInfo(pInfo->u.Local.hFile, &objInfo, RTFSOBJATTRADD_NOTHING);
1126 if (RT_SUCCESS(rc))
1127 {
1128 pHdr->cbTotalSize = objInfo.cbObject;
1129 }
1130 }
1131 else if (RTFS_IS_SYMLINK(pInfo->fMode))
1132 {
1133 rc = VERR_NOT_IMPLEMENTED; /** @todo */
1134 }
1135 else
1136 AssertFailedStmt(rc = VERR_NOT_SUPPORTED);
1137 }
1138 }
1139 else
1140 rc = VERR_NOT_FOUND;
1141 }
1142 else if (pTransfer->State.enmSource == SHAREDCLIPBOARDSOURCE_REMOTE)
1143 {
1144 if (pTransfer->ProviderIface.pfnListHdrRead)
1145 {
1146 rc = pTransfer->ProviderIface.pfnListHdrRead(&pTransfer->ProviderCtx, hList, pHdr);
1147 }
1148 else
1149 rc = VERR_NOT_SUPPORTED;
1150 }
1151 else
1152 AssertFailedStmt(rc = VERR_NOT_IMPLEMENTED);
1153
1154 LogFlowFuncLeaveRC(rc);
1155 return rc;
1156}
1157
1158/**
1159 * Returns the current URI object for a clipboard URI transfer list.
1160 *
1161 * @returns Pointer to URI object.
1162 * @param pTransfer URI clipboard transfer to return URI object for.
1163 */
1164PSHAREDCLIPBOARDURITRANSFEROBJ SharedClipboardURITransferListGetObj(PSHAREDCLIPBOARDURITRANSFER pTransfer,
1165 SHAREDCLIPBOARDLISTHANDLE hList, uint64_t uIdx)
1166{
1167 AssertPtrReturn(pTransfer, NULL);
1168
1169 RT_NOREF(hList, uIdx);
1170
1171 LogFlowFunc(("hList=%RU64\n", hList));
1172
1173 return NULL;
1174}
1175
1176int SharedClipboardURITransferListRead(PSHAREDCLIPBOARDURITRANSFER pTransfer, SHAREDCLIPBOARDLISTHANDLE hList,
1177 PVBOXCLIPBOARDLISTENTRY pEntry)
1178{
1179 AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
1180 AssertPtrReturn(pEntry, VERR_INVALID_POINTER);
1181
1182 int rc = VINF_SUCCESS;
1183
1184 LogFlowFunc(("hList=%RU64\n", hList));
1185
1186 if (pTransfer->State.enmSource == SHAREDCLIPBOARDSOURCE_LOCAL)
1187 {
1188 SharedClipboardURIListMap::iterator itList = pTransfer->pMapLists->find(hList);
1189 if (itList != pTransfer->pMapLists->end())
1190 {
1191 PSHAREDCLIPBOARDURILISTHANDLEINFO pInfo = itList->second;
1192 AssertPtr(pInfo);
1193
1194 if (RTFS_IS_DIRECTORY(pInfo->fMode))
1195 {
1196 size_t cbDirEntry = 0;
1197 PRTDIRENTRYEX pDirEntry = NULL;
1198 rc = RTDirReadExA(pInfo->u.Local.hDirRoot, &pDirEntry, &cbDirEntry, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK);
1199 if (RT_SUCCESS(rc))
1200 {
1201 switch (pDirEntry->Info.Attr.fMode & RTFS_TYPE_MASK)
1202 {
1203 case RTFS_TYPE_DIRECTORY:
1204 {
1205 /* Skip "." and ".." entries. */
1206 if (RTDirEntryExIsStdDotLink(pDirEntry))
1207 break;
1208
1209 RT_FALL_THROUGH();
1210 }
1211
1212 case RTFS_TYPE_FILE:
1213 {
1214 pEntry->pvInfo = (PSHAREDCLIPBOARDFSOBJINFO)RTMemAlloc(sizeof(SHAREDCLIPBOARDFSOBJINFO));
1215 if (pEntry->pvInfo)
1216 {
1217 SharedClipboardFsObjFromIPRT(PSHAREDCLIPBOARDFSOBJINFO(pEntry->pvInfo), &pDirEntry->Info);
1218
1219 pEntry->cbInfo = sizeof(SHAREDCLIPBOARDFSOBJINFO);
1220 pEntry->fInfo = 0; /** @todo Implement. */
1221 }
1222 else
1223 rc = VERR_NO_MEMORY;
1224 break;
1225 }
1226
1227 case RTFS_TYPE_SYMLINK:
1228 {
1229 /** @todo Not implemented yet. */
1230 break;
1231 }
1232
1233 default:
1234 break;
1235 }
1236
1237 RTDirReadExAFree(&pDirEntry, &cbDirEntry);
1238 }
1239 }
1240 else if (RTFS_IS_FILE(pInfo->fMode))
1241 {
1242 RTFSOBJINFO objInfo;
1243 rc = RTFileQueryInfo(pInfo->u.Local.hFile, &objInfo, RTFSOBJATTRADD_NOTHING);
1244 if (RT_SUCCESS(rc))
1245 {
1246 pEntry->pvInfo = (PSHAREDCLIPBOARDFSOBJINFO)RTMemAlloc(sizeof(SHAREDCLIPBOARDFSOBJINFO));
1247 if (pEntry->pvInfo)
1248 {
1249 SharedClipboardFsObjFromIPRT(PSHAREDCLIPBOARDFSOBJINFO(pEntry->pvInfo), &objInfo);
1250
1251 pEntry->cbInfo = sizeof(SHAREDCLIPBOARDFSOBJINFO);
1252 pEntry->fInfo = 0; /** @todo Implement. */
1253 }
1254 else
1255 rc = VERR_NO_MEMORY;
1256 }
1257 }
1258 else if (RTFS_IS_SYMLINK(pInfo->fMode))
1259 {
1260 rc = VERR_NOT_IMPLEMENTED;
1261 }
1262 else
1263 AssertFailedStmt(rc = VERR_NOT_SUPPORTED);
1264 }
1265 else
1266 rc = VERR_NOT_FOUND;
1267 }
1268 else if (pTransfer->State.enmSource == SHAREDCLIPBOARDSOURCE_REMOTE)
1269 {
1270 if (pTransfer->ProviderIface.pfnListEntryRead)
1271 rc = pTransfer->ProviderIface.pfnListEntryRead(&pTransfer->ProviderCtx, hList, pEntry);
1272 else
1273 rc = VERR_NOT_SUPPORTED;
1274 }
1275
1276 LogFlowFuncLeaveRC(rc);
1277 return rc;
1278}
1279
1280int SharedClipboardURITransferListWrite(PSHAREDCLIPBOARDURITRANSFER pTransfer, SHAREDCLIPBOARDLISTHANDLE hList,
1281 PVBOXCLIPBOARDLISTENTRY pEntry)
1282{
1283 RT_NOREF(pTransfer, hList, pEntry);
1284
1285 int rc = VINF_SUCCESS;
1286
1287#if 0
1288 if (pTransfer->ProviderIface.pfnListEntryWrite)
1289 rc = pTransfer->ProviderIface.pfnListEntryWrite(&pTransfer->ProviderCtx, hList, pEntry);
1290#endif
1291
1292 LogFlowFuncLeaveRC(rc);
1293 return rc;
1294}
1295
1296bool SharedClipboardURITransferListHandleIsValid(PSHAREDCLIPBOARDURITRANSFER pTransfer, SHAREDCLIPBOARDLISTHANDLE hList)
1297{
1298 bool fIsValid = false;
1299
1300 if (pTransfer->State.enmSource == SHAREDCLIPBOARDSOURCE_LOCAL)
1301 {
1302 SharedClipboardURIListMap::iterator itList = pTransfer->pMapLists->find(hList);
1303 fIsValid = itList != pTransfer->pMapLists->end();
1304 }
1305 else if (pTransfer->State.enmSource == SHAREDCLIPBOARDSOURCE_REMOTE)
1306 {
1307 AssertFailed(); /** @todo Implement. */
1308 }
1309
1310 return fIsValid;
1311}
1312
1313/**
1314 * Prepares everything needed for a read / write transfer to begin.
1315 *
1316 * @returns VBox status code.
1317 * @param pTransfer URI clipboard transfer to prepare.
1318 */
1319int SharedClipboardURITransferPrepare(PSHAREDCLIPBOARDURITRANSFER pTransfer)
1320{
1321 AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
1322
1323 LogFlowFuncEnter();
1324
1325 int rc = VINF_SUCCESS;
1326
1327 AssertMsgReturn(pTransfer->State.enmStatus == SHAREDCLIPBOARDURITRANSFERSTATUS_NONE,
1328 ("Transfer has wrong state (%RU32)\n", pTransfer->State.enmStatus), VERR_WRONG_ORDER);
1329
1330 LogFlowFunc(("pTransfer=%p, enmDir=%RU32\n", pTransfer, pTransfer->State.enmDir));
1331
1332 if (pTransfer->Callbacks.pfnTransferPrepare)
1333 {
1334 SHAREDCLIPBOARDURITRANSFERCALLBACKDATA callbackData = { pTransfer, pTransfer->Callbacks.pvUser };
1335 pTransfer->Callbacks.pfnTransferPrepare(&callbackData);
1336 }
1337
1338 if (RT_SUCCESS(rc))
1339 {
1340 pTransfer->State.enmStatus = SHAREDCLIPBOARDURITRANSFERSTATUS_READY;
1341
1342 /** @todo Add checksum support. */
1343 }
1344
1345 LogFlowFuncLeaveRC(rc);
1346 return rc;
1347}
1348
1349/**
1350 * Sets the URI provider interface for a given transfer.
1351 *
1352 * @returns VBox status code.
1353 * @param pTransfer Transfer to create URI provider for.
1354 * @param pCreationCtx Provider creation context to use for provider creation.
1355 */
1356int SharedClipboardURITransferSetInterface(PSHAREDCLIPBOARDURITRANSFER pTransfer,
1357 PSHAREDCLIPBOARDPROVIDERCREATIONCTX pCreationCtx)
1358{
1359 AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
1360 AssertPtrReturn(pCreationCtx, VERR_INVALID_POINTER);
1361
1362 LogFlowFuncEnter();
1363
1364 int rc = VINF_SUCCESS;
1365
1366 pTransfer->ProviderIface = pCreationCtx->Interface;
1367
1368 pTransfer->ProviderCtx.pTransfer = pTransfer;
1369 pTransfer->ProviderCtx.pvUser = pCreationCtx->pvUser;
1370
1371 LogFlowFuncLeaveRC(rc);
1372 return rc;
1373}
1374
1375/**
1376 * Resets an clipboard URI transfer.
1377 *
1378 * @param pTransfer URI clipboard transfer to reset.
1379 */
1380void SharedClipboardURITransferReset(PSHAREDCLIPBOARDURITRANSFER pTransfer)
1381{
1382 AssertPtrReturnVoid(pTransfer);
1383
1384 LogFlowFuncEnter();
1385
1386 /** @todo Anything else to do here? */
1387}
1388
1389/**
1390 * Returns the clipboard area for a clipboard URI transfer.
1391 *
1392 * @returns Current clipboard area, or NULL if none.
1393 * @param pTransfer URI clipboard transfer to return clipboard area for.
1394 */
1395SharedClipboardArea *SharedClipboardURITransferGetArea(PSHAREDCLIPBOARDURITRANSFER pTransfer)
1396{
1397 AssertPtrReturn(pTransfer, NULL);
1398
1399 return pTransfer->pArea;
1400}
1401
1402SHAREDCLIPBOARDSOURCE SharedClipboardURITransferGetSource(PSHAREDCLIPBOARDURITRANSFER pTransfer)
1403{
1404 AssertPtrReturn(pTransfer, SHAREDCLIPBOARDSOURCE_INVALID);
1405
1406 return pTransfer->State.enmSource;
1407}
1408
1409/**
1410 * Returns the current transfer status.
1411 *
1412 * @returns Current transfer status.
1413 * @param pTransfer URI clipboard transfer to return status for.
1414 */
1415SHAREDCLIPBOARDURITRANSFERSTATUS SharedClipboardURITransferGetStatus(PSHAREDCLIPBOARDURITRANSFER pTransfer)
1416{
1417 AssertPtrReturn(pTransfer, SHAREDCLIPBOARDURITRANSFERSTATUS_NONE);
1418
1419 return pTransfer->State.enmStatus;
1420}
1421
1422/**
1423 * Runs (starts) an URI transfer thread.
1424 *
1425 * @returns VBox status code.
1426 * @param pTransfer URI clipboard transfer to run.
1427 * @param pfnThreadFunc Pointer to thread function to use.
1428 * @param pvUser Pointer to user-provided data.
1429 */
1430int SharedClipboardURITransferRun(PSHAREDCLIPBOARDURITRANSFER pTransfer, PFNRTTHREAD pfnThreadFunc, void *pvUser)
1431{
1432 AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
1433
1434 AssertMsgReturn(pTransfer->State.enmStatus == SHAREDCLIPBOARDURITRANSFERSTATUS_READY,
1435 ("Wrong status (currently is %RU32)\n", pTransfer->State.enmStatus), VERR_WRONG_ORDER);
1436
1437 int rc = sharedClipboardURITransferThreadCreate(pTransfer, pfnThreadFunc, pvUser);
1438
1439 LogFlowFuncLeaveRC(rc);
1440 return rc;
1441}
1442
1443/**
1444 * Sets or unsets the callback table to be used for a clipboard URI transfer.
1445 *
1446 * @returns VBox status code.
1447 * @param pTransfer URI clipboard transfer to set callbacks for.
1448 * @param pCallbacks Pointer to callback table to set.
1449 */
1450void SharedClipboardURITransferSetCallbacks(PSHAREDCLIPBOARDURITRANSFER pTransfer,
1451 PSHAREDCLIPBOARDURITRANSFERCALLBACKS pCallbacks)
1452{
1453 AssertPtrReturnVoid(pTransfer);
1454 AssertPtrReturnVoid(pCallbacks);
1455
1456 LogFlowFunc(("pCallbacks=%p\n", pCallbacks));
1457
1458#define SET_CALLBACK(a_pfnCallback) \
1459 if (pCallbacks->a_pfnCallback) \
1460 pTransfer->Callbacks.a_pfnCallback = pCallbacks->a_pfnCallback
1461
1462 SET_CALLBACK(pfnTransferPrepare);
1463 SET_CALLBACK(pfnTransferStarted);
1464 SET_CALLBACK(pfnListHeaderComplete);
1465 SET_CALLBACK(pfnListEntryComplete);
1466 SET_CALLBACK(pfnTransferCanceled);
1467 SET_CALLBACK(pfnTransferError);
1468 SET_CALLBACK(pfnTransferStarted);
1469
1470#undef SET_CALLBACK
1471
1472 pTransfer->Callbacks.pvUser = pCallbacks->pvUser;
1473}
1474
1475int SharedClipboardURITransferPayloadAlloc(uint32_t uID, const void *pvData, uint32_t cbData,
1476 PSHAREDCLIPBOARDURITRANSFERPAYLOAD *ppPayload)
1477{
1478 PSHAREDCLIPBOARDURITRANSFERPAYLOAD pPayload =
1479 (PSHAREDCLIPBOARDURITRANSFERPAYLOAD)RTMemAlloc(sizeof(SHAREDCLIPBOARDURITRANSFERPAYLOAD));
1480 if (!pPayload)
1481 return VERR_NO_MEMORY;
1482
1483 pPayload->pvData = RTMemAlloc(cbData);
1484 if (pPayload->pvData)
1485 {
1486 memcpy(pPayload->pvData, pvData, cbData);
1487
1488 pPayload->cbData = cbData;
1489 pPayload->uID = uID;
1490
1491 *ppPayload = pPayload;
1492
1493 return VINF_SUCCESS;
1494 }
1495
1496 RTMemFree(pPayload);
1497 return VERR_NO_MEMORY;
1498}
1499
1500void SharedClipboardURITransferPayloadFree(PSHAREDCLIPBOARDURITRANSFERPAYLOAD pPayload)
1501{
1502 if (!pPayload)
1503 return;
1504
1505 if (pPayload->pvData)
1506 {
1507 Assert(pPayload->cbData);
1508 RTMemFree(pPayload->pvData);
1509 pPayload->pvData = NULL;
1510 }
1511
1512 pPayload->cbData = 0;
1513
1514 RTMemFree(pPayload);
1515 pPayload = NULL;
1516}
1517
1518int SharedClipboardURITransferEventRegister(PSHAREDCLIPBOARDURITRANSFER pTransfer, uint32_t uID)
1519{
1520 int rc;
1521
1522 SharedClipboardURITransferEventMap::iterator itEvent = pTransfer->pMapEvents->find(uID);
1523 if (itEvent == pTransfer->pMapEvents->end())
1524 {
1525 PSHAREDCLIPBOARDURITRANSFEREVENT pEvent
1526 = (PSHAREDCLIPBOARDURITRANSFEREVENT)RTMemAllocZ(sizeof(SHAREDCLIPBOARDURITRANSFEREVENT));
1527 if (pEvent)
1528 {
1529 rc = RTSemEventCreate(&pEvent->hEventSem);
1530 if (RT_SUCCESS(rc))
1531 {
1532 pTransfer->pMapEvents->insert(std::pair<uint32_t, PSHAREDCLIPBOARDURITRANSFEREVENT>(uID, pEvent)); /** @todo Can this throw? */
1533 }
1534 }
1535 else
1536 rc = VERR_NO_MEMORY;
1537 }
1538 else
1539 rc = VERR_ALREADY_EXISTS;
1540
1541 LogFlowFuncLeaveRC(rc);
1542 return rc;
1543}
1544
1545int SharedClipboardURITransferEventUnregister(PSHAREDCLIPBOARDURITRANSFER pTransfer, uint32_t uID)
1546{
1547 int rc;
1548
1549 SharedClipboardURITransferEventMap::const_iterator itEvent = pTransfer->pMapEvents->find(uID);
1550 if (itEvent != pTransfer->pMapEvents->end())
1551 {
1552 SharedClipboardURITransferPayloadFree(itEvent->second->pPayload);
1553
1554 RTSemEventDestroy(itEvent->second->hEventSem);
1555
1556 RTMemFree(itEvent->second);
1557
1558 pTransfer->pMapEvents->erase(itEvent);
1559
1560 rc = VINF_SUCCESS;
1561 }
1562 else
1563 rc = VERR_NOT_FOUND;
1564
1565 LogFlowFuncLeaveRC(rc);
1566 return rc;
1567}
1568
1569int SharedClipboardURITransferEventWait(PSHAREDCLIPBOARDURITRANSFER pTransfer, uint32_t uID, RTMSINTERVAL uTimeoutMs,
1570 PSHAREDCLIPBOARDURITRANSFERPAYLOAD *ppPayload)
1571{
1572 LogFlowFuncEnter();
1573
1574 int rc;
1575
1576 SharedClipboardURITransferEventMap::const_iterator itEvent = pTransfer->pMapEvents->find(uID);
1577 if (itEvent != pTransfer->pMapEvents->end())
1578 {
1579 rc = RTSemEventWait(itEvent->second->hEventSem, uTimeoutMs);
1580 if (RT_SUCCESS(rc))
1581 {
1582 *ppPayload = itEvent->second->pPayload;
1583
1584 itEvent->second->pPayload = NULL;
1585 }
1586 }
1587 else
1588 rc = VERR_NOT_FOUND;
1589
1590 LogFlowFuncLeaveRC(rc);
1591 return rc;
1592}
1593
1594int SharedClipboardURITransferEventSignal(PSHAREDCLIPBOARDURITRANSFER pTransfer, uint32_t uID,
1595 PSHAREDCLIPBOARDURITRANSFERPAYLOAD pPayload)
1596{
1597 int rc;
1598
1599 SharedClipboardURITransferEventMap::const_iterator itEvent = pTransfer->pMapEvents->find(uID);
1600 if (itEvent != pTransfer->pMapEvents->end())
1601 {
1602 Assert(itEvent->second->pPayload == NULL);
1603
1604 itEvent->second->pPayload = pPayload;
1605
1606 rc = RTSemEventSignal(itEvent->second->hEventSem);
1607 }
1608 else
1609 rc = VERR_NOT_FOUND;
1610
1611 LogFlowFuncLeaveRC(rc);
1612 return rc;
1613}
1614
1615/**
1616 * Creates a thread for a clipboard URI transfer.
1617 *
1618 * @returns VBox status code.
1619 * @param pTransfer URI clipboard transfer to create thread for.
1620 * @param pfnThreadFunc Thread function to use for this transfer.
1621 * @param pvUser Pointer to user-provided data.
1622 */
1623static int sharedClipboardURITransferThreadCreate(PSHAREDCLIPBOARDURITRANSFER pTransfer, PFNRTTHREAD pfnThreadFunc, void *pvUser)
1624
1625{
1626 AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
1627
1628 /* Spawn a worker thread, so that we don't block the window thread for too long. */
1629 int rc = RTThreadCreate(&pTransfer->Thread.hThread, pfnThreadFunc,
1630 pvUser, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE,
1631 "shclp");
1632 if (RT_SUCCESS(rc))
1633 {
1634 int rc2 = RTThreadUserWait(pTransfer->Thread.hThread, 30 * 1000 /* Timeout in ms */);
1635 AssertRC(rc2);
1636
1637 if (pTransfer->Thread.fStarted) /* Did the thread indicate that it started correctly? */
1638 {
1639 pTransfer->State.enmStatus = SHAREDCLIPBOARDURITRANSFERSTATUS_RUNNING;
1640 }
1641 else
1642 rc = VERR_GENERAL_FAILURE; /** @todo Find a better rc. */
1643 }
1644
1645 LogFlowFuncLeaveRC(rc);
1646 return rc;
1647}
1648
1649/**
1650 * Destroys a thread of a clipboard URI transfer.
1651 *
1652 * @returns VBox status code.
1653 * @param pTransfer URI clipboard transfer to destroy thread for.
1654 * @param uTimeoutMs Timeout (in ms) to wait for thread creation.
1655 */
1656static int sharedClipboardURITransferThreadDestroy(PSHAREDCLIPBOARDURITRANSFER pTransfer, RTMSINTERVAL uTimeoutMs)
1657{
1658 AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
1659
1660 if (pTransfer->Thread.hThread == NIL_RTTHREAD)
1661 return VINF_SUCCESS;
1662
1663 LogFlowFuncEnter();
1664
1665 /* Set stop indicator. */
1666 pTransfer->Thread.fStop = true;
1667
1668 int rcThread = VERR_WRONG_ORDER;
1669 int rc = RTThreadWait(pTransfer->Thread.hThread, uTimeoutMs, &rcThread);
1670
1671 LogFlowFunc(("Waiting for thread resulted in %Rrc (thread exited with %Rrc)\n", rc, rcThread));
1672
1673 return rc;
1674}
1675
1676/**
1677 * Initializes a clipboard URI transfer.
1678 *
1679 * @returns VBox status code.
1680 * @param pURI URI clipboard context to initialize.
1681 */
1682int SharedClipboardURICtxInit(PSHAREDCLIPBOARDURICTX pURI)
1683{
1684 AssertPtrReturn(pURI, VERR_INVALID_POINTER);
1685
1686 LogFlowFunc(("%p\n", pURI));
1687
1688 int rc = RTCritSectInit(&pURI->CritSect);
1689 if (RT_SUCCESS(rc))
1690 {
1691 RTListInit(&pURI->List);
1692
1693 pURI->cRunning = 0;
1694 pURI->cMaxRunning = 1; /* For now we only support one transfer per client at a time. */
1695
1696#ifdef DEBUG_andy
1697 pURI->cMaxRunning = UINT32_MAX;
1698#endif
1699 SharedClipboardURICtxReset(pURI);
1700 }
1701
1702 return VINF_SUCCESS;
1703}
1704
1705/**
1706 * Destroys an URI clipboard information context struct.
1707 *
1708 * @param pURI URI clipboard context to destroy.
1709 */
1710void SharedClipboardURICtxDestroy(PSHAREDCLIPBOARDURICTX pURI)
1711{
1712 AssertPtrReturnVoid(pURI);
1713
1714 LogFlowFunc(("%p\n", pURI));
1715
1716 RTCritSectDelete(&pURI->CritSect);
1717
1718 PSHAREDCLIPBOARDURITRANSFER pTransfer, pTransferNext;
1719 RTListForEachSafe(&pURI->List, pTransfer, pTransferNext, SHAREDCLIPBOARDURITRANSFER, Node)
1720 {
1721 SharedClipboardURITransferDestroy(pTransfer);
1722
1723 RTListNodeRemove(&pTransfer->Node);
1724
1725 RTMemFree(pTransfer);
1726 pTransfer = NULL;
1727 }
1728
1729 pURI->cRunning = 0;
1730 pURI->cTransfers = 0;
1731}
1732
1733/**
1734 * Resets an clipboard URI transfer.
1735 *
1736 * @param pURI URI clipboard context to reset.
1737 */
1738void SharedClipboardURICtxReset(PSHAREDCLIPBOARDURICTX pURI)
1739{
1740 AssertPtrReturnVoid(pURI);
1741
1742 LogFlowFuncEnter();
1743
1744 PSHAREDCLIPBOARDURITRANSFER pTransfer;
1745 RTListForEach(&pURI->List, pTransfer, SHAREDCLIPBOARDURITRANSFER, Node)
1746 SharedClipboardURITransferReset(pTransfer);
1747}
1748
1749/**
1750 * Adds a new URI transfer to an clipboard URI transfer.
1751 *
1752 * @returns VBox status code.
1753 * @param pURI URI clipboard context to add transfer to.
1754 * @param pTransfer Pointer to URI clipboard transfer to add.
1755 */
1756int SharedClipboardURICtxTransferAdd(PSHAREDCLIPBOARDURICTX pURI, PSHAREDCLIPBOARDURITRANSFER pTransfer)
1757{
1758 AssertPtrReturn(pURI, VERR_INVALID_POINTER);
1759 AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
1760
1761 LogFlowFuncEnter();
1762
1763 if (pURI->cRunning == pURI->cMaxRunning)
1764 return VERR_SHCLPB_MAX_TRANSFERS_REACHED;
1765
1766 RTListAppend(&pURI->List, &pTransfer->Node);
1767
1768 pURI->cTransfers++;
1769 LogFlowFunc(("cTransfers=%RU32, cRunning=%RU32\n", pURI->cTransfers, pURI->cRunning));
1770
1771 return VINF_SUCCESS;
1772}
1773
1774/**
1775 * Removes an URI transfer from a clipboard URI transfer.
1776 *
1777 * @returns VBox status code.
1778 * @param pURI URI clipboard context to remove transfer from.
1779 * @param pTransfer Pointer to URI clipboard transfer to remove.
1780 */
1781int SharedClipboardURICtxTransferRemove(PSHAREDCLIPBOARDURICTX pURI, PSHAREDCLIPBOARDURITRANSFER pTransfer)
1782{
1783 AssertPtrReturn(pURI, VERR_INVALID_POINTER);
1784 AssertPtrReturn(pTransfer, VERR_INVALID_POINTER);
1785
1786 LogFlowFuncEnter();
1787
1788
1789 int rc = SharedClipboardURITransferDestroy(pTransfer);
1790 if (RT_SUCCESS(rc))
1791 {
1792 RTListNodeRemove(&pTransfer->Node);
1793
1794 RTMemFree(pTransfer);
1795 pTransfer = NULL;
1796 }
1797
1798 LogFlowFuncLeaveRC(rc);
1799 return rc;
1800}
1801
1802/**
1803 * Returns a specific URI transfer, internal version.
1804 *
1805 * @returns URI transfer, or NULL if not found.
1806 * @param pURI URI clipboard context to return transfer for.
1807 * @param uIdx Index of the transfer to return.
1808 */
1809static PSHAREDCLIPBOARDURITRANSFER sharedClipboardURICtxGetTransferInternal(PSHAREDCLIPBOARDURICTX pURI, uint32_t uIdx)
1810{
1811 AssertReturn(uIdx == 0, NULL); /* Only one transfer allowed at the moment. */
1812 return RTListGetFirst(&pURI->List, SHAREDCLIPBOARDURITRANSFER, Node);
1813}
1814
1815/**
1816 * Returns a specific URI transfer.
1817 *
1818 * @returns URI transfer, or NULL if not found.
1819 * @param pURI URI clipboard context to return transfer for.
1820 * @param uIdx Index of the transfer to return.
1821 */
1822PSHAREDCLIPBOARDURITRANSFER SharedClipboardURICtxGetTransfer(PSHAREDCLIPBOARDURICTX pURI, uint32_t uIdx)
1823{
1824 return sharedClipboardURICtxGetTransferInternal(pURI, uIdx);
1825}
1826
1827/**
1828 * Returns the number of running URI transfers.
1829 *
1830 * @returns Number of running transfers.
1831 * @param pURI URI clipboard context to return number for.
1832 */
1833uint32_t SharedClipboardURICtxGetRunningTransfers(PSHAREDCLIPBOARDURICTX pURI)
1834{
1835 AssertPtrReturn(pURI, 0);
1836 return pURI->cRunning;
1837}
1838
1839/**
1840 * Returns the number of total URI transfers.
1841 *
1842 * @returns Number of total transfers.
1843 * @param pURI URI clipboard context to return number for.
1844 */
1845uint32_t SharedClipboardURICtxGetTotalTransfers(PSHAREDCLIPBOARDURICTX pURI)
1846{
1847 AssertPtrReturn(pURI, 0);
1848 return pURI->cTransfers;
1849}
1850
1851/**
1852 * Cleans up all associated transfers which are not needed (anymore).
1853 * This can be due to transfers which only have been announced but not / never being run.
1854 *
1855 * @param pURI URI clipboard context to cleanup transfers for.
1856 */
1857void SharedClipboardURICtxTransfersCleanup(PSHAREDCLIPBOARDURICTX pURI)
1858{
1859 AssertPtrReturnVoid(pURI);
1860
1861 LogFlowFunc(("cRunning=%RU32\n", pURI->cRunning));
1862
1863 /* Remove all transfers which are not in a running state (e.g. only announced). */
1864 PSHAREDCLIPBOARDURITRANSFER pTransfer, pTransferNext;
1865 RTListForEachSafe(&pURI->List, pTransfer, pTransferNext, SHAREDCLIPBOARDURITRANSFER, Node)
1866 {
1867 if (SharedClipboardURITransferGetStatus(pTransfer) != SHAREDCLIPBOARDURITRANSFERSTATUS_RUNNING)
1868 {
1869 SharedClipboardURITransferDestroy(pTransfer);
1870 RTListNodeRemove(&pTransfer->Node);
1871
1872 RTMemFree(pTransfer);
1873 pTransfer = NULL;
1874
1875 Assert(pURI->cTransfers);
1876 pURI->cTransfers--;
1877
1878 LogFlowFunc(("cTransfers=%RU32\n", pURI->cTransfers));
1879 }
1880 }
1881}
1882
1883/**
1884 * Returns whether the maximum of concurrent transfers of a specific URI context has been reached or not.
1885 *
1886 * @returns \c if maximum has been reached, \c false if not.
1887 * @param pURI URI clipboard context to determine value for.
1888 */
1889bool SharedClipboardURICtxTransfersMaximumReached(PSHAREDCLIPBOARDURICTX pURI)
1890{
1891 AssertPtrReturn(pURI, true);
1892
1893 LogFlowFunc(("cRunning=%RU32, cMaxRunning=%RU32\n", pURI->cRunning, pURI->cMaxRunning));
1894
1895 Assert(pURI->cRunning <= pURI->cMaxRunning);
1896 return pURI->cRunning == pURI->cMaxRunning;
1897}
1898
1899/**
1900 * Copies file system objinfo from IPRT to Shared Clipboard format.
1901 *
1902 * @param pDst The Shared Clipboard structure to convert data to.
1903 * @param pSrc The IPRT structure to convert data from.
1904 */
1905void SharedClipboardFsObjFromIPRT(PSHAREDCLIPBOARDFSOBJINFO pDst, PCRTFSOBJINFO pSrc)
1906{
1907 pDst->cbObject = pSrc->cbObject;
1908 pDst->cbAllocated = pSrc->cbAllocated;
1909 pDst->AccessTime = pSrc->AccessTime;
1910 pDst->ModificationTime = pSrc->ModificationTime;
1911 pDst->ChangeTime = pSrc->ChangeTime;
1912 pDst->BirthTime = pSrc->BirthTime;
1913 pDst->Attr.fMode = pSrc->Attr.fMode;
1914 /* Clear bits which we don't pass through for security reasons. */
1915 pDst->Attr.fMode &= ~(RTFS_UNIX_ISUID | RTFS_UNIX_ISGID | RTFS_UNIX_ISTXT);
1916 RT_ZERO(pDst->Attr.u);
1917 switch (pSrc->Attr.enmAdditional)
1918 {
1919 default:
1920 case RTFSOBJATTRADD_NOTHING:
1921 pDst->Attr.enmAdditional = SHAREDCLIPBOARDFSOBJATTRADD_NOTHING;
1922 break;
1923
1924 case RTFSOBJATTRADD_UNIX:
1925 pDst->Attr.enmAdditional = SHAREDCLIPBOARDFSOBJATTRADD_UNIX;
1926 pDst->Attr.u.Unix.uid = pSrc->Attr.u.Unix.uid;
1927 pDst->Attr.u.Unix.gid = pSrc->Attr.u.Unix.gid;
1928 pDst->Attr.u.Unix.cHardlinks = pSrc->Attr.u.Unix.cHardlinks;
1929 pDst->Attr.u.Unix.INodeIdDevice = pSrc->Attr.u.Unix.INodeIdDevice;
1930 pDst->Attr.u.Unix.INodeId = pSrc->Attr.u.Unix.INodeId;
1931 pDst->Attr.u.Unix.fFlags = pSrc->Attr.u.Unix.fFlags;
1932 pDst->Attr.u.Unix.GenerationId = pSrc->Attr.u.Unix.GenerationId;
1933 pDst->Attr.u.Unix.Device = pSrc->Attr.u.Unix.Device;
1934 break;
1935
1936 case RTFSOBJATTRADD_EASIZE:
1937 pDst->Attr.enmAdditional = SHAREDCLIPBOARDFSOBJATTRADD_EASIZE;
1938 pDst->Attr.u.EASize.cb = pSrc->Attr.u.EASize.cb;
1939 break;
1940 }
1941}
1942
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