VirtualBox

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

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

shared folders: several fixes, cleanup

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