VirtualBox

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

Last change on this file since 74430 was 69500, checked in by vboxsync, 7 years ago

*: scm --update-copyright-year

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