VirtualBox

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

Last change on this file since 34575 was 33892, checked in by vboxsync, 14 years ago

Shared folders: drop the #if defined-all-oses around SET_SYMLINKS.

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