VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedFolders/service.cpp@ 39606

Last change on this file since 39606 was 39540, checked in by vboxsync, 13 years ago

HostServices/SharedFolders: starter unit test.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 51.2 KB
Line 
1/** @file
2 * Shared Folders: Host service entry points.
3 */
4
5/*
6 * Copyright (C) 2006-2010 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 */
16
17#include <VBox/shflsvc.h>
18
19
20#include "shfl.h"
21#include "mappings.h"
22#include "shflhandle.h"
23#include "vbsf.h"
24#include <iprt/alloc.h>
25#include <iprt/string.h>
26#include <iprt/assert.h>
27#include <VBox/vmm/ssm.h>
28#include <VBox/vmm/pdmifs.h>
29
30#define SHFL_SSM_VERSION 2
31
32
33/* Shared Folders Host Service.
34 *
35 * Shared Folders map a host file system to guest logical filesystem.
36 * A mapping represents 'host name'<->'guest name' translation and a root
37 * identifier to be used to access this mapping.
38 * Examples: "C:\WINNT"<->"F:", "C:\WINNT\System32"<->"/mnt/host/system32".
39 *
40 * Therefore, host name and guest name are strings interpreted
41 * only by host service and guest client respectively. Host name is
42 * passed to guest only for informational purpose. Guest may for example
43 * display the string or construct volume label out of the string.
44 *
45 * Root identifiers are unique for whole guest life,
46 * that is until next guest reset/fresh start.
47 * 32 bit value incremented for each new mapping is used.
48 *
49 * Mapping strings are taken from VM XML configuration on VM startup.
50 * The service DLL takes mappings during initialization. There is
51 * also API for changing mappings at runtime.
52 *
53 * Current mappings and root identifiers are saved when VM is saved.
54 *
55 * Guest may use any of these mappings. Full path information
56 * about an object on a mapping consists of the root identifier and
57 * a full path of object.
58 *
59 * Guest IFS connects to the service and calls SHFL_FN_QUERY_MAP
60 * function which returns current mappings. For guest convenience,
61 * removed mappings also returned with REMOVED flag and new mappings
62 * are marked with NEW flag.
63 *
64 * To access host file system guest just forwards file system calls
65 * to the service, and specifies full paths or handles for objects.
66 *
67 *
68 */
69
70
71PVBOXHGCMSVCHELPERS g_pHelpers;
72static PPDMLED pStatusLed = NULL;
73
74static DECLCALLBACK(int) svcUnload (void *)
75{
76 int rc = VINF_SUCCESS;
77
78 Log(("svcUnload\n"));
79
80 return rc;
81}
82
83static DECLCALLBACK(int) svcConnect (void *, uint32_t u32ClientID, void *pvClient)
84{
85 int rc = VINF_SUCCESS;
86
87 NOREF(u32ClientID);
88 NOREF(pvClient);
89
90 Log(("SharedFolders host service: connected, u32ClientID = %u\n", u32ClientID));
91
92 return rc;
93}
94
95static DECLCALLBACK(int) svcDisconnect (void *, uint32_t u32ClientID, void *pvClient)
96{
97 int rc = VINF_SUCCESS;
98 SHFLCLIENTDATA *pClient = (SHFLCLIENTDATA *)pvClient;
99
100 Log(("SharedFolders host service: disconnected, u32ClientID = %u\n", u32ClientID));
101
102 vbsfDisconnect(pClient);
103 return rc;
104}
105
106/** @note We only save as much state as required to access the shared folder again after restore.
107 * All I/O requests pending at the time of saving will never be completed or result in errors.
108 * (file handles no longer valid etc)
109 * This works as designed at the moment. A full state save would be difficult and not always possible
110 * as the contents of a shared folder might change in between save and restore.
111 */
112static DECLCALLBACK(int) svcSaveState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM)
113{
114#ifndef UNITTEST /* Read this as not yet tested */
115 SHFLCLIENTDATA *pClient = (SHFLCLIENTDATA *)pvClient;
116
117 Log(("SharedFolders host service: saving state, u32ClientID = %u\n", u32ClientID));
118
119 int rc = SSMR3PutU32(pSSM, SHFL_SSM_VERSION);
120 AssertRCReturn(rc, rc);
121
122 rc = SSMR3PutU32(pSSM, SHFL_MAX_MAPPINGS);
123 AssertRCReturn(rc, rc);
124
125 /* Save client structure length & contents */
126 rc = SSMR3PutU32(pSSM, sizeof(*pClient));
127 AssertRCReturn(rc, rc);
128
129 rc = SSMR3PutMem(pSSM, pClient, sizeof(*pClient));
130 AssertRCReturn(rc, rc);
131
132 /* Save all the active mappings. */
133 for (int i=0;i<SHFL_MAX_MAPPINGS;i++)
134 {
135 /* Mapping are saved in the order of increasing root handle values. */
136 MAPPING *pFolderMapping = vbsfMappingGetByRoot(i);
137
138 rc = SSMR3PutU32(pSSM, pFolderMapping? pFolderMapping->cMappings: 0);
139 AssertRCReturn(rc, rc);
140
141 rc = SSMR3PutBool(pSSM, pFolderMapping? pFolderMapping->fValid: false);
142 AssertRCReturn(rc, rc);
143
144 if (pFolderMapping && pFolderMapping->fValid)
145 {
146 uint32_t len;
147
148 len = ShflStringSizeOfBuffer(pFolderMapping->pFolderName);
149 rc = SSMR3PutU32(pSSM, len);
150 AssertRCReturn(rc, rc);
151
152 rc = SSMR3PutMem(pSSM, pFolderMapping->pFolderName, len);
153 AssertRCReturn(rc, rc);
154
155 len = ShflStringSizeOfBuffer(pFolderMapping->pMapName);
156 rc = SSMR3PutU32(pSSM, len);
157 AssertRCReturn(rc, rc);
158
159 rc = SSMR3PutMem(pSSM, pFolderMapping->pMapName, len);
160 AssertRCReturn(rc, rc);
161
162 rc = SSMR3PutBool(pSSM, pFolderMapping->fHostCaseSensitive);
163 AssertRCReturn(rc, rc);
164
165 rc = SSMR3PutBool(pSSM, pFolderMapping->fGuestCaseSensitive);
166 AssertRCReturn(rc, rc);
167 }
168 }
169
170#endif
171 return VINF_SUCCESS;
172}
173
174static DECLCALLBACK(int) svcLoadState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM)
175{
176#ifndef UNITTEST /* Read this as not yet tested */
177 uint32_t nrMappings;
178 SHFLCLIENTDATA *pClient = (SHFLCLIENTDATA *)pvClient;
179 uint32_t len, version;
180
181 Log(("SharedFolders host service: loading state, u32ClientID = %u\n", u32ClientID));
182
183 int rc = SSMR3GetU32(pSSM, &version);
184 AssertRCReturn(rc, rc);
185
186 if (version != SHFL_SSM_VERSION)
187 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
188
189 rc = SSMR3GetU32(pSSM, &nrMappings);
190 AssertRCReturn(rc, rc);
191 if (nrMappings != SHFL_MAX_MAPPINGS)
192 return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
193
194 /* Restore the client data (flags + path delimiter at the moment) */
195 rc = SSMR3GetU32(pSSM, &len);
196 AssertRCReturn(rc, rc);
197
198 if (len != sizeof(*pClient))
199 return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
200
201 rc = SSMR3GetMem(pSSM, pClient, sizeof(*pClient));
202 AssertRCReturn(rc, rc);
203
204 /* We don't actually (fully) restore the state; we simply check if the current state is as we it expect it to be. */
205 for (int i=0;i<SHFL_MAX_MAPPINGS;i++)
206 {
207 /* Load the saved mapping description and try to find it in the mappings. */
208 MAPPING mapping;
209 memset (&mapping, 0, sizeof (mapping));
210
211 /* restore the folder mapping counter. */
212 rc = SSMR3GetU32(pSSM, &mapping.cMappings);
213 AssertRCReturn(rc, rc);
214
215 rc = SSMR3GetBool(pSSM, &mapping.fValid);
216 AssertRCReturn(rc, rc);
217
218 if (mapping.fValid)
219 {
220 uint32_t cbFolderName;
221 PSHFLSTRING pFolderName;
222
223 uint32_t cbMapName;
224 PSHFLSTRING pMapName;
225
226 /* Load the host path name. */
227 rc = SSMR3GetU32(pSSM, &cbFolderName);
228 AssertRCReturn(rc, rc);
229
230 pFolderName = (PSHFLSTRING)RTMemAlloc(cbFolderName);
231 AssertReturn(pFolderName != NULL, VERR_NO_MEMORY);
232
233 rc = SSMR3GetMem(pSSM, pFolderName, cbFolderName);
234 AssertRCReturn(rc, rc);
235
236 /* Load the map name. */
237 rc = SSMR3GetU32(pSSM, &cbMapName);
238 AssertRCReturn(rc, rc);
239
240 pMapName = (PSHFLSTRING)RTMemAlloc(cbMapName);
241 AssertReturn(pMapName != NULL, VERR_NO_MEMORY);
242
243 rc = SSMR3GetMem(pSSM, pMapName, cbMapName);
244 AssertRCReturn(rc, rc);
245
246 rc = SSMR3GetBool(pSSM, &mapping.fHostCaseSensitive);
247 AssertRCReturn(rc, rc);
248
249 rc = SSMR3GetBool(pSSM, &mapping.fGuestCaseSensitive);
250 AssertRCReturn(rc, rc);
251
252 mapping.pFolderName = pFolderName;
253 mapping.pMapName = pMapName;
254
255 /* 'i' is the root handle of the saved mapping. */
256 rc = vbsfMappingLoaded (&mapping, i);
257
258 RTMemFree(pMapName);
259 RTMemFree(pFolderName);
260
261 AssertRCReturn(rc, rc);
262 }
263 }
264 Log(("SharedFolders host service: successfully loaded state\n"));
265#endif
266 return VINF_SUCCESS;
267}
268
269static DECLCALLBACK(void) svcCall (void *, VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID, void *pvClient, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
270{
271 int rc = VINF_SUCCESS;
272
273 Log(("SharedFolders host service: svcCall: u32ClientID = %u, fn = %u, cParms = %u, pparms = %p\n", u32ClientID, u32Function, cParms, paParms));
274
275 SHFLCLIENTDATA *pClient = (SHFLCLIENTDATA *)pvClient;
276
277 bool fAsynchronousProcessing = false;
278
279#ifdef DEBUG
280 uint32_t i;
281
282 for (i = 0; i < cParms; i++)
283 {
284 /** @todo parameters other than 32 bit */
285 Log((" pparms[%d]: type %u, value %u\n", i, paParms[i].type, paParms[i].u.uint32));
286 }
287#endif
288
289 switch (u32Function)
290 {
291 case SHFL_FN_QUERY_MAPPINGS:
292 {
293 Log(("SharedFolders host service: svcCall: SHFL_FN_QUERY_MAPPINGS\n"));
294
295 /* Verify parameter count and types. */
296 if (cParms != SHFL_CPARMS_QUERY_MAPPINGS)
297 {
298 rc = VERR_INVALID_PARAMETER;
299 }
300 else if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* flags */
301 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* numberOfMappings */
302 || paParms[2].type != VBOX_HGCM_SVC_PARM_PTR /* mappings */
303 )
304 {
305 rc = VERR_INVALID_PARAMETER;
306 }
307 else
308 {
309 /* Fetch parameters. */
310 uint32_t fu32Flags = paParms[0].u.uint32;
311 uint32_t cMappings = paParms[1].u.uint32;
312 SHFLMAPPING *pMappings = (SHFLMAPPING *)paParms[2].u.pointer.addr;
313 uint32_t cbMappings = paParms[2].u.pointer.size;
314
315 /* Verify parameters values. */
316 if ( (fu32Flags & ~SHFL_MF_MASK) != 0
317 || cbMappings / sizeof (SHFLMAPPING) != cMappings
318 )
319 {
320 rc = VERR_INVALID_PARAMETER;
321 }
322 else
323 {
324 /* Execute the function. */
325 if (fu32Flags & SHFL_MF_UTF8)
326 pClient->fu32Flags |= SHFL_CF_UTF8;
327 if (fu32Flags & SHFL_MF_AUTOMOUNT)
328 pClient->fu32Flags |= SHFL_MF_AUTOMOUNT;
329
330 rc = vbsfMappingsQuery(pClient, pMappings, &cMappings);
331 if (RT_SUCCESS(rc))
332 {
333 /* Report that there are more mappings to get if
334 * handed in buffer is too small. */
335 if (paParms[1].u.uint32 < cMappings)
336 rc = VINF_BUFFER_OVERFLOW;
337
338 /* Update parameters. */
339 paParms[1].u.uint32 = cMappings;
340 }
341 }
342 }
343
344
345 } break;
346
347 case SHFL_FN_QUERY_MAP_NAME:
348 {
349 Log(("SharedFolders host service: svcCall: SHFL_FN_QUERY_MAP_NAME\n"));
350
351 /* Verify parameter count and types. */
352 if (cParms != SHFL_CPARMS_QUERY_MAP_NAME)
353 {
354 rc = VERR_INVALID_PARAMETER;
355 }
356 else if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* Root. */
357 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR /* Name. */
358 )
359 {
360 rc = VERR_INVALID_PARAMETER;
361 }
362 else
363 {
364 /* Fetch parameters. */
365 SHFLROOT root = (SHFLROOT)paParms[0].u.uint32;
366 SHFLSTRING *pString = (SHFLSTRING *)paParms[1].u.pointer.addr;
367
368 /* Verify parameters values. */
369 if (!ShflStringIsValid(pString, paParms[1].u.pointer.size))
370 {
371 rc = VERR_INVALID_PARAMETER;
372 }
373 else
374 {
375 /* Execute the function. */
376 rc = vbsfMappingsQueryName(pClient, root, pString);
377
378 if (RT_SUCCESS(rc))
379 {
380 /* Update parameters.*/
381 ; /* None. */
382 }
383 }
384 }
385
386 } break;
387
388 case SHFL_FN_CREATE:
389 {
390 Log(("SharedFolders host service: svcCall: SHFL_FN_CREATE\n"));
391
392 /* Verify parameter count and types. */
393 if (cParms != SHFL_CPARMS_CREATE)
394 {
395 rc = VERR_INVALID_PARAMETER;
396 }
397 else if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* root */
398 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR /* path */
399 || paParms[2].type != VBOX_HGCM_SVC_PARM_PTR /* parms */
400 )
401 {
402 Log(("SharedFolders host service: Invalid parameters types\n"));
403 rc = VERR_INVALID_PARAMETER;
404 }
405 else
406 {
407 /* Fetch parameters. */
408 SHFLROOT root = (SHFLROOT)paParms[0].u.uint32;
409 SHFLSTRING *pPath = (SHFLSTRING *)paParms[1].u.pointer.addr;
410 uint32_t cbPath = paParms[1].u.pointer.size;
411 SHFLCREATEPARMS *pParms = (SHFLCREATEPARMS *)paParms[2].u.pointer.addr;
412 uint32_t cbParms = paParms[2].u.pointer.size;
413
414 /* Verify parameters values. */
415 if ( !ShflStringIsValid(pPath, cbPath)
416 || (cbParms != sizeof (SHFLCREATEPARMS))
417 )
418 {
419 AssertMsgFailed (("Invalid parameters cbPath or cbParms (%x, %x - expected >=%x, %x)\n",
420 cbPath, cbParms, sizeof(SHFLSTRING), sizeof (SHFLCREATEPARMS)));
421 rc = VERR_INVALID_PARAMETER;
422 }
423 else
424 {
425 /* Execute the function. */
426
427 rc = vbsfCreate (pClient, root, pPath, cbPath, pParms);
428
429 if (RT_SUCCESS(rc))
430 {
431 /* Update parameters.*/
432 ; /* none */
433 }
434 }
435 }
436 break;
437 }
438
439 case SHFL_FN_CLOSE:
440 {
441 Log(("SharedFolders host service: svcCall: SHFL_FN_CLOSE\n"));
442
443 /* Verify parameter count and types. */
444 if (cParms != SHFL_CPARMS_CLOSE)
445 {
446 rc = VERR_INVALID_PARAMETER;
447 }
448 else if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* root */
449 || paParms[1].type != VBOX_HGCM_SVC_PARM_64BIT /* handle */
450 )
451 {
452 rc = VERR_INVALID_PARAMETER;
453 }
454 else
455 {
456 /* Fetch parameters. */
457 SHFLROOT root = (SHFLROOT)paParms[0].u.uint32;
458 SHFLHANDLE Handle = paParms[1].u.uint64;
459
460 /* Verify parameters values. */
461 if (Handle == SHFL_HANDLE_ROOT)
462 {
463 rc = VERR_INVALID_PARAMETER;
464 }
465 else
466 if (Handle == SHFL_HANDLE_NIL)
467 {
468 AssertMsgFailed(("Invalid handle!\n"));
469 rc = VERR_INVALID_HANDLE;
470 }
471 else
472 {
473 /* Execute the function. */
474
475 rc = vbsfClose (pClient, root, Handle);
476
477 if (RT_SUCCESS(rc))
478 {
479 /* Update parameters.*/
480 ; /* none */
481 }
482 }
483 }
484 break;
485
486 }
487
488 /** Read object content. */
489 case SHFL_FN_READ:
490 Log(("SharedFolders host service: svcCall: SHFL_FN_READ\n"));
491
492 /* Verify parameter count and types. */
493 if (cParms != SHFL_CPARMS_READ)
494 {
495 rc = VERR_INVALID_PARAMETER;
496 }
497 else
498 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* root */
499 || paParms[1].type != VBOX_HGCM_SVC_PARM_64BIT /* handle */
500 || paParms[2].type != VBOX_HGCM_SVC_PARM_64BIT /* offset */
501 || paParms[3].type != VBOX_HGCM_SVC_PARM_32BIT /* count */
502 || paParms[4].type != VBOX_HGCM_SVC_PARM_PTR /* buffer */
503 )
504 {
505 rc = VERR_INVALID_PARAMETER;
506 }
507 else
508 {
509 /* Fetch parameters. */
510 SHFLROOT root = (SHFLROOT)paParms[0].u.uint32;
511 SHFLHANDLE Handle = paParms[1].u.uint64;
512 uint64_t offset = paParms[2].u.uint64;
513 uint32_t count = paParms[3].u.uint32;
514 uint8_t *pBuffer = (uint8_t *)paParms[4].u.pointer.addr;
515
516 /* Verify parameters values. */
517 if ( Handle == SHFL_HANDLE_ROOT
518 || count > paParms[4].u.pointer.size
519 )
520 {
521 rc = VERR_INVALID_PARAMETER;
522 }
523 else
524 if (Handle == SHFL_HANDLE_NIL)
525 {
526 AssertMsgFailed(("Invalid handle!\n"));
527 rc = VERR_INVALID_HANDLE;
528 }
529 else
530 {
531 /* Execute the function. */
532 if (pStatusLed)
533 {
534 Assert(pStatusLed->u32Magic == PDMLED_MAGIC);
535 pStatusLed->Asserted.s.fReading = pStatusLed->Actual.s.fReading = 1;
536 }
537
538 rc = vbsfRead (pClient, root, Handle, offset, &count, pBuffer);
539 if (pStatusLed)
540 pStatusLed->Actual.s.fReading = 0;
541
542 if (RT_SUCCESS(rc))
543 {
544 /* Update parameters.*/
545 paParms[3].u.uint32 = count;
546 }
547 else
548 {
549 paParms[3].u.uint32 = 0; /* nothing read */
550 }
551 }
552 }
553 break;
554
555 /** Write new object content. */
556 case SHFL_FN_WRITE:
557 Log(("SharedFolders host service: svcCall: SHFL_FN_WRITE\n"));
558
559 /* Verify parameter count and types. */
560 if (cParms != SHFL_CPARMS_WRITE)
561 {
562 rc = VERR_INVALID_PARAMETER;
563 }
564 else
565 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* root */
566 || paParms[1].type != VBOX_HGCM_SVC_PARM_64BIT /* handle */
567 || paParms[2].type != VBOX_HGCM_SVC_PARM_64BIT /* offset */
568 || paParms[3].type != VBOX_HGCM_SVC_PARM_32BIT /* count */
569 || paParms[4].type != VBOX_HGCM_SVC_PARM_PTR /* buffer */
570 )
571 {
572 rc = VERR_INVALID_PARAMETER;
573 }
574 else
575 {
576 /* Fetch parameters. */
577 SHFLROOT root = (SHFLROOT)paParms[0].u.uint32;
578 SHFLHANDLE Handle = paParms[1].u.uint64;
579 uint64_t offset = paParms[2].u.uint64;
580 uint32_t count = paParms[3].u.uint32;
581 uint8_t *pBuffer = (uint8_t *)paParms[4].u.pointer.addr;
582
583 /* Verify parameters values. */
584 if ( Handle == SHFL_HANDLE_ROOT
585 || count > paParms[4].u.pointer.size
586 )
587 {
588 rc = VERR_INVALID_PARAMETER;
589 }
590 else
591 if (Handle == SHFL_HANDLE_NIL)
592 {
593 AssertMsgFailed(("Invalid handle!\n"));
594 rc = VERR_INVALID_HANDLE;
595 }
596 else
597 {
598 /* Execute the function. */
599 if (pStatusLed)
600 {
601 Assert(pStatusLed->u32Magic == PDMLED_MAGIC);
602 pStatusLed->Asserted.s.fWriting = pStatusLed->Actual.s.fWriting = 1;
603 }
604
605 rc = vbsfWrite (pClient, root, Handle, offset, &count, pBuffer);
606 if (pStatusLed)
607 pStatusLed->Actual.s.fWriting = 0;
608
609 if (RT_SUCCESS(rc))
610 {
611 /* Update parameters.*/
612 paParms[3].u.uint32 = count;
613 }
614 else
615 {
616 paParms[3].u.uint32 = 0; /* nothing read */
617 }
618 }
619 }
620 break;
621
622 /** Lock/unlock a range in the object. */
623 case SHFL_FN_LOCK:
624 Log(("SharedFolders host service: svcCall: SHFL_FN_LOCK\n"));
625
626 /* Verify parameter count and types. */
627 if (cParms != SHFL_CPARMS_LOCK)
628 {
629 rc = VERR_INVALID_PARAMETER;
630 }
631 else
632 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* root */
633 || paParms[1].type != VBOX_HGCM_SVC_PARM_64BIT /* handle */
634 || paParms[2].type != VBOX_HGCM_SVC_PARM_64BIT /* offset */
635 || paParms[3].type != VBOX_HGCM_SVC_PARM_64BIT /* length */
636 || paParms[4].type != VBOX_HGCM_SVC_PARM_32BIT /* flags */
637 )
638 {
639 rc = VERR_INVALID_PARAMETER;
640 }
641 else
642 {
643 /* Fetch parameters. */
644 SHFLROOT root = (SHFLROOT)paParms[0].u.uint32;
645 SHFLHANDLE Handle = paParms[1].u.uint64;
646 uint64_t offset = paParms[2].u.uint64;
647 uint64_t length = paParms[3].u.uint64;
648 uint32_t flags = paParms[4].u.uint32;
649
650 /* Verify parameters values. */
651 if (Handle == SHFL_HANDLE_ROOT)
652 {
653 rc = VERR_INVALID_PARAMETER;
654 }
655 else
656 if (Handle == SHFL_HANDLE_NIL)
657 {
658 AssertMsgFailed(("Invalid handle!\n"));
659 rc = VERR_INVALID_HANDLE;
660 }
661 else if (flags & SHFL_LOCK_WAIT)
662 {
663 /* @todo This should be properly implemented by the shared folders service.
664 * The service thread must never block. If an operation requires
665 * blocking, it must be processed by another thread and when it is
666 * completed, the another thread must call
667 *
668 * g_pHelpers->pfnCallComplete (callHandle, rc);
669 *
670 * The operation is async.
671 * fAsynchronousProcessing = true;
672 */
673
674 /* Here the operation must be posted to another thread. At the moment it is not implemented.
675 * Until it is implemented, try to perform the operation without waiting.
676 */
677 flags &= ~SHFL_LOCK_WAIT;
678
679 /* Execute the function. */
680 if ((flags & SHFL_LOCK_MODE_MASK) == SHFL_LOCK_CANCEL)
681 rc = vbsfUnlock(pClient, root, Handle, offset, length, flags);
682 else
683 rc = vbsfLock(pClient, root, Handle, offset, length, flags);
684
685 if (RT_SUCCESS(rc))
686 {
687 /* Update parameters.*/
688 /* none */
689 }
690 }
691 else
692 {
693 /* Execute the function. */
694 if ((flags & SHFL_LOCK_MODE_MASK) == SHFL_LOCK_CANCEL)
695 rc = vbsfUnlock(pClient, root, Handle, offset, length, flags);
696 else
697 rc = vbsfLock(pClient, root, Handle, offset, length, flags);
698
699 if (RT_SUCCESS(rc))
700 {
701 /* Update parameters.*/
702 /* none */
703 }
704 }
705 }
706 break;
707
708 /** List object content. */
709 case SHFL_FN_LIST:
710 {
711 Log(("SharedFolders host service: svcCall: SHFL_FN_LIST\n"));
712
713 /* Verify parameter count and types. */
714 if (cParms != SHFL_CPARMS_LIST)
715 {
716 rc = VERR_INVALID_PARAMETER;
717 }
718 else
719 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* root */
720 || paParms[1].type != VBOX_HGCM_SVC_PARM_64BIT /* handle */
721 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* flags */
722 || paParms[3].type != VBOX_HGCM_SVC_PARM_32BIT /* cb */
723 || paParms[4].type != VBOX_HGCM_SVC_PARM_PTR /* pPath */
724 || paParms[5].type != VBOX_HGCM_SVC_PARM_PTR /* buffer */
725 || paParms[6].type != VBOX_HGCM_SVC_PARM_32BIT /* resumePoint */
726 || paParms[7].type != VBOX_HGCM_SVC_PARM_32BIT /* cFiles (out) */
727 )
728 {
729 rc = VERR_INVALID_PARAMETER;
730 }
731 else
732 {
733 /* Fetch parameters. */
734 SHFLROOT root = (SHFLROOT)paParms[0].u.uint32;
735 SHFLHANDLE Handle = paParms[1].u.uint64;
736 uint32_t flags = paParms[2].u.uint32;
737 uint32_t length = paParms[3].u.uint32;
738 SHFLSTRING *pPath = (paParms[4].u.pointer.size == 0) ? 0 : (SHFLSTRING *)paParms[4].u.pointer.addr;
739 uint8_t *pBuffer = (uint8_t *)paParms[5].u.pointer.addr;
740 uint32_t resumePoint = paParms[6].u.uint32;
741 uint32_t cFiles = 0;
742
743 /* Verify parameters values. */
744 if ( (length < sizeof (SHFLDIRINFO))
745 || length > paParms[5].u.pointer.size
746 || !ShflStringIsValidOrNull(pPath, paParms[4].u.pointer.size)
747 )
748 {
749 rc = VERR_INVALID_PARAMETER;
750 }
751 else
752 {
753 if (pStatusLed)
754 {
755 Assert(pStatusLed->u32Magic == PDMLED_MAGIC);
756 pStatusLed->Asserted.s.fReading = pStatusLed->Actual.s.fReading = 1;
757 }
758
759 /* Execute the function. */
760 rc = vbsfDirList (pClient, root, Handle, pPath, flags, &length, pBuffer, &resumePoint, &cFiles);
761
762 if (pStatusLed)
763 pStatusLed->Actual.s.fReading = 0;
764
765 if (rc == VERR_NO_MORE_FILES && cFiles != 0)
766 rc = VINF_SUCCESS; /* Successfully return these files. */
767
768 if (RT_SUCCESS(rc))
769 {
770 /* Update parameters.*/
771 paParms[3].u.uint32 = length;
772 paParms[6].u.uint32 = resumePoint;
773 paParms[7].u.uint32 = cFiles;
774 }
775 else
776 {
777 paParms[3].u.uint32 = 0; /* nothing read */
778 paParms[6].u.uint32 = 0;
779 paParms[7].u.uint32 = cFiles;
780 }
781 }
782 }
783 break;
784 }
785
786 /* Read symlink destination */
787 case SHFL_FN_READLINK:
788 {
789 Log(("SharedFolders host service: svcCall: SHFL_FN_READLINK\n"));
790
791 /* Verify parameter count and types. */
792 if (cParms != SHFL_CPARMS_READLINK)
793 {
794 rc = VERR_INVALID_PARAMETER;
795 }
796 else
797 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* root */
798 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR /* path */
799 || paParms[2].type != VBOX_HGCM_SVC_PARM_PTR /* buffer */
800 )
801 {
802 rc = VERR_INVALID_PARAMETER;
803 }
804 else
805 {
806 /* Fetch parameters. */
807 SHFLROOT root = (SHFLROOT)paParms[0].u.uint32;
808 SHFLSTRING *pPath = (SHFLSTRING *)paParms[1].u.pointer.addr;
809 uint32_t cbPath = paParms[1].u.pointer.size;
810 uint8_t *pBuffer = (uint8_t *)paParms[2].u.pointer.addr;
811 uint32_t cbBuffer = paParms[2].u.pointer.size;
812
813 /* Verify parameters values. */
814 if (!ShflStringIsValidOrNull(pPath, paParms[1].u.pointer.size))
815 {
816 rc = VERR_INVALID_PARAMETER;
817 }
818 else
819 {
820 /* Execute the function. */
821 rc = vbsfReadLink (pClient, root, pPath, cbPath, pBuffer, cbBuffer);
822
823 if (RT_SUCCESS(rc))
824 {
825 /* Update parameters.*/
826 ; /* none */
827 }
828 }
829 }
830
831 break;
832 }
833
834 /* Legacy interface */
835 case SHFL_FN_MAP_FOLDER_OLD:
836 {
837 Log(("SharedFolders host service: svcCall: SHFL_FN_MAP_FOLDER_OLD\n"));
838
839 /* Verify parameter count and types. */
840 if (cParms != SHFL_CPARMS_MAP_FOLDER_OLD)
841 {
842 rc = VERR_INVALID_PARAMETER;
843 }
844 else if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* path */
845 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* root */
846 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* delimiter */
847 )
848 {
849 rc = VERR_INVALID_PARAMETER;
850 }
851 else
852 {
853 /* Fetch parameters. */
854 PSHFLSTRING pszMapName = (PSHFLSTRING)paParms[0].u.pointer.addr;
855 SHFLROOT root = (SHFLROOT)paParms[1].u.uint32;
856 RTUTF16 delimiter = (RTUTF16)paParms[2].u.uint32;
857
858 /* Verify parameters values. */
859 if (!ShflStringIsValid(pszMapName, paParms[0].u.pointer.size))
860 {
861 rc = VERR_INVALID_PARAMETER;
862 }
863 else
864 {
865 /* Execute the function. */
866 rc = vbsfMapFolder (pClient, pszMapName, delimiter, false, &root);
867
868 if (RT_SUCCESS(rc))
869 {
870 /* Update parameters.*/
871 paParms[1].u.uint32 = root;
872 }
873 }
874 }
875 break;
876 }
877
878 case SHFL_FN_MAP_FOLDER:
879 {
880 Log(("SharedFolders host service: svcCall: SHFL_FN_MAP_FOLDER\n"));
881 if (BIT_FLAG(pClient->fu32Flags, SHFL_CF_UTF8))
882 Log(("SharedFolders host service: request to map folder '%s'\n",
883 ((PSHFLSTRING)paParms[0].u.pointer.addr)->String.utf8));
884 else
885 Log(("SharedFolders host service: request to map folder '%ls'\n",
886 ((PSHFLSTRING)paParms[0].u.pointer.addr)->String.ucs2));
887
888 /* Verify parameter count and types. */
889 if (cParms != SHFL_CPARMS_MAP_FOLDER)
890 {
891 rc = VERR_INVALID_PARAMETER;
892 }
893 else if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* path */
894 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* root */
895 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* delimiter */
896 || paParms[3].type != VBOX_HGCM_SVC_PARM_32BIT /* fCaseSensitive */
897 )
898 {
899 rc = VERR_INVALID_PARAMETER;
900 }
901 else
902 {
903 /* Fetch parameters. */
904 PSHFLSTRING pszMapName = (PSHFLSTRING)paParms[0].u.pointer.addr;
905 SHFLROOT root = (SHFLROOT)paParms[1].u.uint32;
906 RTUTF16 delimiter = (RTUTF16)paParms[2].u.uint32;
907 bool fCaseSensitive = !!paParms[3].u.uint32;
908
909 /* Verify parameters values. */
910 if (!ShflStringIsValid(pszMapName, paParms[0].u.pointer.size))
911 {
912 rc = VERR_INVALID_PARAMETER;
913 }
914 else
915 {
916
917 /* Execute the function. */
918 rc = vbsfMapFolder (pClient, pszMapName, delimiter, fCaseSensitive, &root);
919
920 if (RT_SUCCESS(rc))
921 {
922 /* Update parameters.*/
923 paParms[1].u.uint32 = root;
924 }
925 }
926 }
927 Log(("SharedFolders host service: map operation result %Rrc\n", rc));
928 if (RT_SUCCESS(rc))
929 Log(("SharedFolders host service: mapped to handle %d\n", paParms[1].u.uint32));
930 break;
931 }
932
933 case SHFL_FN_UNMAP_FOLDER:
934 {
935 Log(("SharedFolders host service: svcCall: SHFL_FN_UNMAP_FOLDER\n"));
936 Log(("SharedFolders host service: request to unmap folder handle %u\n",
937 paParms[0].u.uint32));
938
939 /* Verify parameter count and types. */
940 if (cParms != SHFL_CPARMS_UNMAP_FOLDER)
941 {
942 rc = VERR_INVALID_PARAMETER;
943 }
944 else if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* root */
945 )
946 {
947 rc = VERR_INVALID_PARAMETER;
948 }
949 else
950 {
951 /* Fetch parameters. */
952 SHFLROOT root = (SHFLROOT)paParms[0].u.uint32;
953
954 /* Execute the function. */
955 rc = vbsfUnmapFolder (pClient, root);
956
957 if (RT_SUCCESS(rc))
958 {
959 /* Update parameters.*/
960 /* nothing */
961 }
962 }
963 Log(("SharedFolders host service: unmap operation result %Rrc\n", rc));
964 break;
965 }
966
967 /** Query/set object information. */
968 case SHFL_FN_INFORMATION:
969 {
970 Log(("SharedFolders host service: svcCall: SHFL_FN_INFORMATION\n"));
971
972 /* Verify parameter count and types. */
973 if (cParms != SHFL_CPARMS_INFORMATION)
974 {
975 rc = VERR_INVALID_PARAMETER;
976 }
977 else
978 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* root */
979 || paParms[1].type != VBOX_HGCM_SVC_PARM_64BIT /* handle */
980 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* flags */
981 || paParms[3].type != VBOX_HGCM_SVC_PARM_32BIT /* cb */
982 || paParms[4].type != VBOX_HGCM_SVC_PARM_PTR /* buffer */
983 )
984 {
985 rc = VERR_INVALID_PARAMETER;
986 }
987 else
988 {
989 /* Fetch parameters. */
990 SHFLROOT root = (SHFLROOT)paParms[0].u.uint32;
991 SHFLHANDLE Handle = paParms[1].u.uint64;
992 uint32_t flags = paParms[2].u.uint32;
993 uint32_t length = paParms[3].u.uint32;
994 uint8_t *pBuffer = (uint8_t *)paParms[4].u.pointer.addr;
995
996 /* Verify parameters values. */
997 if (length > paParms[4].u.pointer.size)
998 {
999 rc = VERR_INVALID_PARAMETER;
1000 }
1001 else
1002 {
1003 /* Execute the function. */
1004 if (flags & SHFL_INFO_SET)
1005 rc = vbsfSetFSInfo (pClient, root, Handle, flags, &length, pBuffer);
1006 else /* SHFL_INFO_GET */
1007 rc = vbsfQueryFSInfo (pClient, root, Handle, flags, &length, pBuffer);
1008
1009 if (RT_SUCCESS(rc))
1010 {
1011 /* Update parameters.*/
1012 paParms[3].u.uint32 = length;
1013 }
1014 else
1015 {
1016 paParms[3].u.uint32 = 0; /* nothing read */
1017 }
1018 }
1019 }
1020 break;
1021 }
1022
1023 /** Remove or rename object */
1024 case SHFL_FN_REMOVE:
1025 {
1026 Log(("SharedFolders host service: svcCall: SHFL_FN_REMOVE\n"));
1027
1028 /* Verify parameter count and types. */
1029 if (cParms != SHFL_CPARMS_REMOVE)
1030 {
1031 rc = VERR_INVALID_PARAMETER;
1032 }
1033 else if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* root */
1034 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR /* path */
1035 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* flags */
1036 )
1037 {
1038 rc = VERR_INVALID_PARAMETER;
1039 }
1040 else
1041 {
1042 /* Fetch parameters. */
1043 SHFLROOT root = (SHFLROOT)paParms[0].u.uint32;
1044 SHFLSTRING *pPath = (SHFLSTRING *)paParms[1].u.pointer.addr;
1045 uint32_t cbPath = paParms[1].u.pointer.size;
1046 uint32_t flags = paParms[2].u.uint32;
1047
1048 /* Verify parameters values. */
1049 if (!ShflStringIsValid(pPath, cbPath))
1050 {
1051 rc = VERR_INVALID_PARAMETER;
1052 }
1053 else
1054 {
1055 /* Execute the function. */
1056 rc = vbsfRemove (pClient, root, pPath, cbPath, flags);
1057 if (RT_SUCCESS(rc))
1058 {
1059 /* Update parameters.*/
1060 ; /* none */
1061 }
1062 }
1063 }
1064 break;
1065 }
1066
1067 case SHFL_FN_RENAME:
1068 {
1069 Log(("SharedFolders host service: svcCall: SHFL_FN_RENAME\n"));
1070
1071 /* Verify parameter count and types. */
1072 if (cParms != SHFL_CPARMS_RENAME)
1073 {
1074 rc = VERR_INVALID_PARAMETER;
1075 }
1076 else if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* root */
1077 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR /* src */
1078 || paParms[2].type != VBOX_HGCM_SVC_PARM_PTR /* dest */
1079 || paParms[3].type != VBOX_HGCM_SVC_PARM_32BIT /* flags */
1080 )
1081 {
1082 rc = VERR_INVALID_PARAMETER;
1083 }
1084 else
1085 {
1086 /* Fetch parameters. */
1087 SHFLROOT root = (SHFLROOT)paParms[0].u.uint32;
1088 SHFLSTRING *pSrc = (SHFLSTRING *)paParms[1].u.pointer.addr;
1089 SHFLSTRING *pDest = (SHFLSTRING *)paParms[2].u.pointer.addr;
1090 uint32_t flags = paParms[3].u.uint32;
1091
1092 /* Verify parameters values. */
1093 if ( !ShflStringIsValid(pSrc, paParms[1].u.pointer.size)
1094 || !ShflStringIsValid(pDest, paParms[2].u.pointer.size)
1095 )
1096 {
1097 rc = VERR_INVALID_PARAMETER;
1098 }
1099 else
1100 {
1101 /* Execute the function. */
1102 rc = vbsfRename (pClient, root, pSrc, pDest, flags);
1103 if (RT_SUCCESS(rc))
1104 {
1105 /* Update parameters.*/
1106 ; /* none */
1107 }
1108 }
1109 }
1110 break;
1111 }
1112
1113 case SHFL_FN_FLUSH:
1114 {
1115 Log(("SharedFolders host service: svcCall: SHFL_FN_FLUSH\n"));
1116
1117 /* Verify parameter count and types. */
1118 if (cParms != SHFL_CPARMS_FLUSH)
1119 {
1120 rc = VERR_INVALID_PARAMETER;
1121 }
1122 else
1123 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* root */
1124 || paParms[1].type != VBOX_HGCM_SVC_PARM_64BIT /* handle */
1125 )
1126 {
1127 rc = VERR_INVALID_PARAMETER;
1128 }
1129 else
1130 {
1131 /* Fetch parameters. */
1132 SHFLROOT root = (SHFLROOT)paParms[0].u.uint32;
1133 SHFLHANDLE Handle = paParms[1].u.uint64;
1134
1135 /* Verify parameters values. */
1136 if (Handle == SHFL_HANDLE_ROOT)
1137 {
1138 rc = VERR_INVALID_PARAMETER;
1139 }
1140 else
1141 if (Handle == SHFL_HANDLE_NIL)
1142 {
1143 AssertMsgFailed(("Invalid handle!\n"));
1144 rc = VERR_INVALID_HANDLE;
1145 }
1146 else
1147 {
1148 /* Execute the function. */
1149
1150 rc = vbsfFlush (pClient, root, Handle);
1151
1152 if (RT_SUCCESS(rc))
1153 {
1154 /* Nothing to do */
1155 }
1156 }
1157 }
1158 } break;
1159
1160 case SHFL_FN_SET_UTF8:
1161 {
1162 pClient->fu32Flags |= SHFL_CF_UTF8;
1163 rc = VINF_SUCCESS;
1164 break;
1165 }
1166
1167 case SHFL_FN_SYMLINK:
1168 {
1169 Log(("SharedFolders host service: svnCall: SHFL_FN_SYMLINK\n"));
1170 /* Verify parameter count and types. */
1171 if (cParms != SHFL_CPARMS_SYMLINK)
1172 {
1173 rc = VERR_INVALID_PARAMETER;
1174 }
1175 else if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* root */
1176 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR /* newPath */
1177 || paParms[2].type != VBOX_HGCM_SVC_PARM_PTR /* oldPath */
1178 || paParms[3].type != VBOX_HGCM_SVC_PARM_PTR /* info */
1179 )
1180 {
1181 rc = VERR_INVALID_PARAMETER;
1182 }
1183 else
1184 {
1185 /* Fetch parameters. */
1186 SHFLROOT root = (SHFLROOT)paParms[0].u.uint32;
1187 SHFLSTRING *pNewPath = (SHFLSTRING *)paParms[1].u.pointer.addr;
1188 SHFLSTRING *pOldPath = (SHFLSTRING *)paParms[2].u.pointer.addr;
1189 SHFLFSOBJINFO *pInfo = (SHFLFSOBJINFO *)paParms[3].u.pointer.addr;
1190 uint32_t cbInfo = paParms[3].u.pointer.size;
1191
1192 /* Verify parameters values. */
1193 if ( !ShflStringIsValid(pNewPath, paParms[1].u.pointer.size)
1194 || !ShflStringIsValid(pOldPath, paParms[2].u.pointer.size)
1195 || (cbInfo != sizeof(SHFLFSOBJINFO))
1196 )
1197 {
1198 rc = VERR_INVALID_PARAMETER;
1199 }
1200 else
1201 {
1202 /* Execute the function. */
1203 rc = vbsfSymlink (pClient, root, pNewPath, pOldPath, pInfo);
1204 if (RT_SUCCESS(rc))
1205 {
1206 /* Update parameters.*/
1207 ; /* none */
1208 }
1209 }
1210 }
1211 }
1212 break;
1213
1214 case SHFL_FN_SET_SYMLINKS:
1215 {
1216 pClient->fu32Flags |= SHFL_CF_SYMLINKS;
1217 rc = VINF_SUCCESS;
1218 break;
1219 }
1220
1221 default:
1222 {
1223 rc = VERR_NOT_IMPLEMENTED;
1224 break;
1225 }
1226 }
1227
1228 LogFlow(("SharedFolders host service: svcCall: rc=%Rrc\n", rc));
1229
1230 if ( !fAsynchronousProcessing
1231 || RT_FAILURE (rc))
1232 {
1233 /* Complete the operation if it was unsuccessful or
1234 * it was processed synchronously.
1235 */
1236 g_pHelpers->pfnCallComplete (callHandle, rc);
1237 }
1238
1239 LogFlow(("\n")); /* Add a new line to differentiate between calls more easily. */
1240}
1241
1242/*
1243 * We differentiate between a function handler for the guest and one for the host. The guest is not allowed to add or remove mappings for obvious security reasons.
1244 */
1245static DECLCALLBACK(int) svcHostCall (void *, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
1246{
1247 int rc = VINF_SUCCESS;
1248
1249 Log(("svcHostCall: fn = %d, cParms = %d, pparms = %d\n", u32Function, cParms, paParms));
1250
1251#ifdef DEBUG
1252 uint32_t i;
1253
1254 for (i = 0; i < cParms; i++)
1255 {
1256 /** @todo parameters other than 32 bit */
1257 Log((" pparms[%d]: type %d value %d\n", i, paParms[i].type, paParms[i].u.uint32));
1258 }
1259#endif
1260
1261 switch (u32Function)
1262 {
1263 case SHFL_FN_ADD_MAPPING:
1264 {
1265 Log(("SharedFolders host service: svcCall: SHFL_FN_ADD_MAPPING\n"));
1266 LogRel(("SharedFolders host service: adding host mapping\n"));
1267 LogRel((" Host path '%ls', map name '%ls', %s\n",
1268 ((SHFLSTRING *)paParms[0].u.pointer.addr)->String.ucs2,
1269 ((SHFLSTRING *)paParms[1].u.pointer.addr)->String.ucs2,
1270 paParms[2].u.uint32 ? "writable" : "read-only"));
1271
1272 /* Verify parameter count and types. */
1273 if ( (cParms != SHFL_CPARMS_ADD_MAPPING)
1274 && (cParms != SHFL_CPARMS_ADD_MAPPING2) /* With auto-mount flag. */
1275 )
1276 {
1277 rc = VERR_INVALID_PARAMETER;
1278 }
1279 else if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* host folder name */
1280 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR /* guest map name */
1281 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* fWritable */
1282 /* With auto-mount flag? */
1283 || ( cParms == SHFL_CPARMS_ADD_MAPPING2
1284 && paParms[3].type != VBOX_HGCM_SVC_PARM_32BIT))
1285 {
1286 rc = VERR_INVALID_PARAMETER;
1287 }
1288 else
1289 {
1290 /* Fetch parameters. */
1291 SHFLSTRING *pFolderName = (SHFLSTRING *)paParms[0].u.pointer.addr;
1292 SHFLSTRING *pMapName = (SHFLSTRING *)paParms[1].u.pointer.addr;
1293 uint32_t fWritable = paParms[2].u.uint32;
1294 uint32_t fAutoMount = 0; /* Disabled by default. */
1295
1296 /* Handle auto-mount flag if present. */
1297 if (cParms == SHFL_CPARMS_ADD_MAPPING2)
1298 fAutoMount = paParms[3].u.uint32;
1299
1300 /* Verify parameters values. */
1301 if ( !ShflStringIsValid(pFolderName, paParms[0].u.pointer.size)
1302 || !ShflStringIsValid(pMapName, paParms[1].u.pointer.size)
1303 )
1304 {
1305 rc = VERR_INVALID_PARAMETER;
1306 }
1307 else
1308 {
1309 /* Execute the function. */
1310 rc = vbsfMappingsAdd(pFolderName, pMapName, fWritable, fAutoMount);
1311 if (RT_SUCCESS(rc))
1312 {
1313 /* Update parameters.*/
1314 ; /* none */
1315 }
1316 }
1317 }
1318 if (RT_FAILURE(rc))
1319 LogRel(("SharedFolders host service: adding host mapping failed with rc=%Rrc\n", rc));
1320 break;
1321 }
1322
1323 case SHFL_FN_REMOVE_MAPPING:
1324 {
1325 Log(("SharedFolders host service: svcCall: SHFL_FN_REMOVE_MAPPING\n"));
1326 LogRel(("SharedFolders host service: removing host mapping '%ls'\n",
1327 ((SHFLSTRING *)paParms[0].u.pointer.addr)->String.ucs2));
1328
1329 /* Verify parameter count and types. */
1330 if (cParms != SHFL_CPARMS_REMOVE_MAPPING)
1331 {
1332 rc = VERR_INVALID_PARAMETER;
1333 }
1334 else if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* folder name */
1335 )
1336 {
1337 rc = VERR_INVALID_PARAMETER;
1338 }
1339 else
1340 {
1341 /* Fetch parameters. */
1342 SHFLSTRING *pString = (SHFLSTRING *)paParms[0].u.pointer.addr;
1343
1344 /* Verify parameters values. */
1345 if (!ShflStringIsValid(pString, paParms[0].u.pointer.size))
1346 {
1347 rc = VERR_INVALID_PARAMETER;
1348 }
1349 else
1350 {
1351 /* Execute the function. */
1352 rc = vbsfMappingsRemove (pString);
1353
1354 if (RT_SUCCESS(rc))
1355 {
1356 /* Update parameters.*/
1357 ; /* none */
1358 }
1359 }
1360 }
1361 if (RT_FAILURE(rc))
1362 LogRel(("SharedFolders host service: removing host mapping failed with rc=%Rrc\n", rc));
1363 break;
1364 }
1365
1366 case SHFL_FN_SET_STATUS_LED:
1367 {
1368 Log(("SharedFolders host service: svcCall: SHFL_FN_SET_STATUS_LED\n"));
1369
1370 /* Verify parameter count and types. */
1371 if (cParms != SHFL_CPARMS_SET_STATUS_LED)
1372 {
1373 rc = VERR_INVALID_PARAMETER;
1374 }
1375 else if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* folder name */
1376 )
1377 {
1378 rc = VERR_INVALID_PARAMETER;
1379 }
1380 else
1381 {
1382 /* Fetch parameters. */
1383 PPDMLED pLed = (PPDMLED)paParms[0].u.pointer.addr;
1384 uint32_t cbLed = paParms[0].u.pointer.size;
1385
1386 /* Verify parameters values. */
1387 if ( (cbLed != sizeof (PDMLED))
1388 )
1389 {
1390 rc = VERR_INVALID_PARAMETER;
1391 }
1392 else
1393 {
1394 /* Execute the function. */
1395 pStatusLed = pLed;
1396 rc = VINF_SUCCESS;
1397 }
1398 }
1399 break;
1400 }
1401
1402 default:
1403 rc = VERR_NOT_IMPLEMENTED;
1404 break;
1405 }
1406
1407 LogFlow(("SharedFolders host service: svcHostCall ended with rc=%Rrc\n", rc));
1408 return rc;
1409}
1410
1411extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad (VBOXHGCMSVCFNTABLE *ptable)
1412{
1413 int rc = VINF_SUCCESS;
1414
1415 Log(("SharedFolders host service: VBoxHGCMSvcLoad: ptable = %p\n", ptable));
1416
1417 if (!VALID_PTR(ptable))
1418 {
1419 LogRelFunc(("SharedFolders host service: bad value of ptable (%p)\n", ptable));
1420 rc = VERR_INVALID_PARAMETER;
1421 }
1422 else
1423 {
1424 Log(("SharedFolders host service: VBoxHGCMSvcLoad: ptable->cbSize = %u, ptable->u32Version = 0x%08X\n",
1425 ptable->cbSize, ptable->u32Version));
1426
1427 if ( ptable->cbSize != sizeof (VBOXHGCMSVCFNTABLE)
1428 || ptable->u32Version != VBOX_HGCM_SVC_VERSION)
1429 {
1430 LogRelFunc(("SharedFolders host service: version mismatch while loading: ptable->cbSize = %u (should be %u), ptable->u32Version = 0x%08X (should be 0x%08X)\n",
1431 ptable->cbSize, sizeof (VBOXHGCMSVCFNTABLE), ptable->u32Version, VBOX_HGCM_SVC_VERSION));
1432 rc = VERR_VERSION_MISMATCH;
1433 }
1434 else
1435 {
1436 g_pHelpers = ptable->pHelpers;
1437
1438 ptable->cbClient = sizeof (SHFLCLIENTDATA);
1439
1440 ptable->pfnUnload = svcUnload;
1441 ptable->pfnConnect = svcConnect;
1442 ptable->pfnDisconnect = svcDisconnect;
1443 ptable->pfnCall = svcCall;
1444 ptable->pfnHostCall = svcHostCall;
1445 ptable->pfnSaveState = svcSaveState;
1446 ptable->pfnLoadState = svcLoadState;
1447 ptable->pvService = NULL;
1448 }
1449
1450 /* Init handle table */
1451 rc = vbsfInitHandleTable();
1452 AssertRC(rc);
1453
1454 vbsfMappingInit();
1455 }
1456
1457 return rc;
1458}
1459
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette