VirtualBox

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

Last change on this file since 105745 was 105087, checked in by vboxsync, 5 months ago

doc/manual,include/VBox,Frontends/VBoxManage,HostServices/SharedFolders,
Main/{include,SharedFolder,Console,Machine,VirtualBox.xidl}: Add a
new attribute to ISharedFolder for specifying a symbolic link creation
policy to restrict the source pathname when creating symbolic links
within a guest. The symbolic link policies are represented by a new
enumeration of type SymlinkPolicy_T which includes values for no
restrictions ('any'), symlink sources only within the subtree of the
share ('subtree'), symlink sources as any relative path ('relative'),
and no symlinks allowed ('forbidden'). The symlink policy can only be
applied to permanent shared folders at this stage. bugref:10619

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