VirtualBox

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

Last change on this file since 55180 was 51976, checked in by vboxsync, 10 years ago

SharedFolders: warning, LogRel if folder can not be loaded.

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