VirtualBox

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

Last change on this file since 94018 was 93444, checked in by vboxsync, 3 years ago

VMM,Main,HostServices: Use a function table for accessing the VBoxVMM.dll/so/dylib functionality, and load it dynamically when the Console object is initialized. Also converted a few drivers in Main to use device helpers to get config values and such. bugref:10074

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