VirtualBox

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

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

SharedFolders: Track mappings made by a client session so we can unmap when the session closes, and more importantly when the VM resets.

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