VirtualBox

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

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

VMMDev,Main,HostServices: More profiling of HGCM guest call processing.

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