VirtualBox

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

Last change on this file since 75380 was 75380, checked in by vboxsync, 6 years ago

Main,VBoxManage,FE/Qt: Extended the createSharedFolder and ISharedFolder methods with a mount poit parameter/attribute for use when auto-mounting. This is especially useful for Windows and OS/2 guests which operates with drive letters. The change has not yet trickled down to the guest interface and VBoxService.

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