VirtualBox

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

Last change on this file since 63561 was 62787, checked in by vboxsync, 8 years ago

HostServices: warnings

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