VirtualBox

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

Last change on this file since 43952 was 43952, checked in by vboxsync, 12 years ago

Shared folders: instead of dropping a shared folder which does not have a mapping on the host, include it but make any operation on it fail. This is necessary to keep SSM consistent.

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