VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedFolders/VBoxSharedFoldersSvc.cpp@ 77807

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

tstSharedFolderService.cpp: Need to catch RTFileWriteAt and RTFileReadAt too now. bugref:9172

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