VirtualBox

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

Last change on this file since 103068 was 99802, checked in by vboxsync, 19 months ago

*: Adjustments necessary for dropping -Zc:wchar_t- on windows and instead let the C++ compiler use the native wchar_t type.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 92.1 KB
Line 
1/* $Id: VBoxSharedFoldersSvc.cpp 99802 2023-05-16 00:05:16Z 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 )
1703 {
1704 rc = VERR_INVALID_PARAMETER;
1705 }
1706 else
1707 {
1708 /* Fetch parameters. */
1709 SHFLSTRING *pHostPath = (SHFLSTRING *)paParms[0].u.pointer.addr;
1710 SHFLSTRING *pMapName = (SHFLSTRING *)paParms[1].u.pointer.addr;
1711 uint32_t fFlags = paParms[2].u.uint32;
1712 SHFLSTRING *pAutoMountPoint = (SHFLSTRING *)paParms[3].u.pointer.addr;
1713
1714 /* Verify parameters values. */
1715 if ( !ShflStringIsValidIn(pHostPath, paParms[0].u.pointer.size, false /*fUtf8Not16*/)
1716 || !ShflStringIsValidIn(pMapName, paParms[1].u.pointer.size, false /*fUtf8Not16*/)
1717 || !ShflStringIsValidIn(pAutoMountPoint, paParms[3].u.pointer.size, false /*fUtf8Not16*/)
1718 )
1719 {
1720 rc = VERR_INVALID_PARAMETER;
1721 }
1722 else
1723 {
1724 LogRel((" Host path '%ls', map name '%ls', %s, automount=%s, automntpnt=%ls, create_symlinks=%s, missing=%s\n",
1725 pHostPath->String.utf16, pMapName->String.utf16,
1726 RT_BOOL(fFlags & SHFL_ADD_MAPPING_F_WRITABLE) ? "writable" : "read-only",
1727 RT_BOOL(fFlags & SHFL_ADD_MAPPING_F_AUTOMOUNT) ? "true" : "false",
1728 pAutoMountPoint->String.utf16,
1729 RT_BOOL(fFlags & SHFL_ADD_MAPPING_F_CREATE_SYMLINKS) ? "true" : "false",
1730 RT_BOOL(fFlags & SHFL_ADD_MAPPING_F_MISSING) ? "true" : "false"));
1731
1732 char *pszHostPath;
1733 rc = RTUtf16ToUtf8(pHostPath->String.utf16, &pszHostPath);
1734 if (RT_SUCCESS(rc))
1735 {
1736 /* Execute the function. */
1737 rc = vbsfMappingsAdd(pszHostPath, pMapName,
1738 RT_BOOL(fFlags & SHFL_ADD_MAPPING_F_WRITABLE),
1739 RT_BOOL(fFlags & SHFL_ADD_MAPPING_F_AUTOMOUNT),
1740 pAutoMountPoint,
1741 RT_BOOL(fFlags & SHFL_ADD_MAPPING_F_CREATE_SYMLINKS),
1742 RT_BOOL(fFlags & SHFL_ADD_MAPPING_F_MISSING),
1743 /* fPlaceholder = */ false);
1744 if (RT_SUCCESS(rc))
1745 {
1746 /* Update parameters.*/
1747 ; /* none */
1748 }
1749 RTStrFree(pszHostPath);
1750 }
1751 }
1752 }
1753 if (RT_FAILURE(rc))
1754 LogRel(("SharedFolders host service: Adding host mapping failed with rc=%Rrc\n", rc));
1755 break;
1756 }
1757
1758 case SHFL_FN_REMOVE_MAPPING:
1759 {
1760 Log(("SharedFolders host service: svcCall: SHFL_FN_REMOVE_MAPPING\n"));
1761 LogRel(("SharedFolders host service: Removing host mapping '%ls'\n",
1762 ((SHFLSTRING *)paParms[0].u.pointer.addr)->String.utf16));
1763
1764 /* Verify parameter count and types. */
1765 if (cParms != SHFL_CPARMS_REMOVE_MAPPING)
1766 {
1767 rc = VERR_INVALID_PARAMETER;
1768 }
1769 else if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* folder name */
1770 )
1771 {
1772 rc = VERR_INVALID_PARAMETER;
1773 }
1774 else
1775 {
1776 /* Fetch parameters. */
1777 SHFLSTRING *pString = (SHFLSTRING *)paParms[0].u.pointer.addr;
1778
1779 /* Verify parameters values. */
1780 if (!ShflStringIsValidIn(pString, paParms[0].u.pointer.size, false /*fUtf8Not16*/))
1781 {
1782 rc = VERR_INVALID_PARAMETER;
1783 }
1784 else
1785 {
1786 /* Execute the function. */
1787 rc = vbsfMappingsRemove (pString);
1788
1789 if (RT_SUCCESS(rc))
1790 {
1791 /* Update parameters.*/
1792 ; /* none */
1793 }
1794 }
1795 }
1796 if (RT_FAILURE(rc))
1797 LogRel(("SharedFolders host service: Removing host mapping failed with rc=%Rrc\n", rc));
1798 break;
1799 }
1800
1801 case SHFL_FN_SET_STATUS_LED:
1802 {
1803 Log(("SharedFolders host service: svcCall: SHFL_FN_SET_STATUS_LED\n"));
1804
1805 /* Verify parameter count and types. */
1806 if (cParms != SHFL_CPARMS_SET_STATUS_LED)
1807 {
1808 rc = VERR_INVALID_PARAMETER;
1809 }
1810 else if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* folder name */
1811 )
1812 {
1813 rc = VERR_INVALID_PARAMETER;
1814 }
1815 else
1816 {
1817 /* Fetch parameters. */
1818 PPDMLED pLed = (PPDMLED)paParms[0].u.pointer.addr;
1819 uint32_t cbLed = paParms[0].u.pointer.size;
1820
1821 /* Verify parameters values. */
1822 if ( (cbLed != sizeof (PDMLED))
1823 )
1824 {
1825 rc = VERR_INVALID_PARAMETER;
1826 }
1827 else
1828 {
1829 /* Execute the function. */
1830 g_pStatusLed = pLed;
1831 rc = VINF_SUCCESS;
1832 }
1833 }
1834 break;
1835 }
1836
1837 default:
1838 rc = VERR_NOT_IMPLEMENTED;
1839 break;
1840 }
1841
1842 LogFlow(("SharedFolders host service: svcHostCall ended with rc=%Rrc\n", rc));
1843 return rc;
1844}
1845
1846extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad (VBOXHGCMSVCFNTABLE *ptable)
1847{
1848 int rc = VINF_SUCCESS;
1849
1850 Log(("SharedFolders host service: VBoxHGCMSvcLoad: ptable = %p\n", ptable));
1851
1852 if (!RT_VALID_PTR(ptable))
1853 {
1854 LogRelFunc(("SharedFolders host service: Bad value of ptable (%p)\n", ptable));
1855 rc = VERR_INVALID_PARAMETER;
1856 }
1857 else
1858 {
1859 Log(("SharedFolders host service: VBoxHGCMSvcLoad: ptable->cbSize = %u, ptable->u32Version = 0x%08X\n",
1860 ptable->cbSize, ptable->u32Version));
1861
1862 if ( ptable->cbSize != sizeof (VBOXHGCMSVCFNTABLE)
1863 || ptable->u32Version != VBOX_HGCM_SVC_VERSION)
1864 {
1865 LogRelFunc(("SharedFolders host service: Version mismatch while loading: ptable->cbSize = %u (should be %u), ptable->u32Version = 0x%08X (should be 0x%08X)\n",
1866 ptable->cbSize, sizeof (VBOXHGCMSVCFNTABLE), ptable->u32Version, VBOX_HGCM_SVC_VERSION));
1867 rc = VERR_VERSION_MISMATCH;
1868 }
1869 else
1870 {
1871 g_pHelpers = ptable->pHelpers;
1872
1873 ptable->cbClient = sizeof (SHFLCLIENTDATA);
1874
1875 /* Map legacy clients to the kernel category. */
1876 ptable->idxLegacyClientCategory = HGCM_CLIENT_CATEGORY_KERNEL;
1877
1878 /* Only 64K pending calls per kernel client, root gets 16K and regular users 1K. */
1879 ptable->acMaxCallsPerClient[HGCM_CLIENT_CATEGORY_KERNEL] = _64K;
1880 ptable->acMaxCallsPerClient[HGCM_CLIENT_CATEGORY_ROOT] = _16K;
1881 ptable->acMaxCallsPerClient[HGCM_CLIENT_CATEGORY_USER] = _1K;
1882
1883 /* Reduce the number of clients to SHFL_MAX_MAPPINGS + 2 in each category,
1884 so the increased calls-per-client value causes less trouble.
1885 ((64 + 2) * 3 * 65536 = 12 976 128) */
1886 for (uintptr_t i = 0; i < RT_ELEMENTS(ptable->acMaxClients); i++)
1887 ptable->acMaxClients[i] = SHFL_MAX_MAPPINGS + 2;
1888
1889 ptable->pfnUnload = svcUnload;
1890 ptable->pfnConnect = svcConnect;
1891 ptable->pfnDisconnect = svcDisconnect;
1892 ptable->pfnCall = svcCall;
1893 ptable->pfnHostCall = svcHostCall;
1894 ptable->pfnSaveState = svcSaveState;
1895 ptable->pfnLoadState = svcLoadState;
1896 ptable->pfnNotify = NULL;
1897 ptable->pvService = NULL;
1898 }
1899
1900 /* Init handle table */
1901 rc = vbsfInitHandleTable();
1902 AssertRC(rc);
1903
1904 vbsfMappingInit();
1905
1906 /* Finally, register statistics if everything went well: */
1907 if (RT_SUCCESS(rc))
1908 {
1909 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatQueryMappings, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_QUERY_MAPPINGS successes", "/HGCM/VBoxSharedFolders/FnQueryMappings");
1910 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatQueryMappingsFail, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_QUERY_MAPPINGS failures", "/HGCM/VBoxSharedFolders/FnQueryMappingsFail");
1911 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatQueryMapName, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_QUERY_MAP_NAME", "/HGCM/VBoxSharedFolders/FnQueryMapName");
1912 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatCreate, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_CREATE/CREATE successes", "/HGCM/VBoxSharedFolders/FnCreate");
1913 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatCreateFail, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_CREATE/CREATE failures", "/HGCM/VBoxSharedFolders/FnCreateFail");
1914 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatLookup, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_CREATE/LOOKUP successes", "/HGCM/VBoxSharedFolders/FnLookup");
1915 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatLookupFail, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_CREATE/LOOKUP failures", "/HGCM/VBoxSharedFolders/FnLookupFail");
1916 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatClose, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_CLOSE successes", "/HGCM/VBoxSharedFolders/FnClose");
1917 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatCloseFail, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_CLOSE failures", "/HGCM/VBoxSharedFolders/FnCloseFail");
1918 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatRead, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_READ successes", "/HGCM/VBoxSharedFolders/FnRead");
1919 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatReadFail, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_READ failures", "/HGCM/VBoxSharedFolders/FnReadFail");
1920 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatWrite, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_WRITE successes", "/HGCM/VBoxSharedFolders/FnWrite");
1921 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatWriteFail, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_WRITE failures", "/HGCM/VBoxSharedFolders/FnWriteFail");
1922 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatLock, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_LOCK successes", "/HGCM/VBoxSharedFolders/FnLock");
1923 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatLockFail, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_LOCK failures", "/HGCM/VBoxSharedFolders/FnLockFail");
1924 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatList, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_LIST successes", "/HGCM/VBoxSharedFolders/FnList");
1925 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatListFail, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_LIST failures", "/HGCM/VBoxSharedFolders/FnListFail");
1926 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatReadLink, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_READLINK successes", "/HGCM/VBoxSharedFolders/FnReadLink");
1927 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatReadLinkFail, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_READLINK failures", "/HGCM/VBoxSharedFolders/FnReadLinkFail");
1928 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatMapFolderOld, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_MAP_FOLDER_OLD", "/HGCM/VBoxSharedFolders/FnMapFolderOld");
1929 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatMapFolder, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_MAP_FOLDER successes", "/HGCM/VBoxSharedFolders/FnMapFolder");
1930 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatMapFolderFail, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_MAP_FOLDER failures", "/HGCM/VBoxSharedFolders/FnMapFolderFail");
1931 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatUnmapFolder, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_UNMAP_FOLDER successes", "/HGCM/VBoxSharedFolders/FnUnmapFolder");
1932 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatUnmapFolderFail, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_UNMAP_FOLDER failures", "/HGCM/VBoxSharedFolders/FnUnmapFolderFail");
1933 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatInformationFail, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_INFORMATION early failures", "/HGCM/VBoxSharedFolders/FnInformationFail");
1934 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatInformationSetFile, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_INFORMATION/SET/FILE successes", "/HGCM/VBoxSharedFolders/FnInformationSetFile");
1935 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatInformationSetFileFail, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_INFORMATION/SET/FILE failures", "/HGCM/VBoxSharedFolders/FnInformationSetFileFail");
1936 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatInformationSetSize, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_INFORMATION/SET/SIZE successes", "/HGCM/VBoxSharedFolders/FnInformationSetSize");
1937 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatInformationSetSizeFail, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_INFORMATION/SET/SIZE failures", "/HGCM/VBoxSharedFolders/FnInformationSetSizeFail");
1938 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatInformationGetFile, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_INFORMATION/GET/FILE successes", "/HGCM/VBoxSharedFolders/FnInformationGetFile");
1939 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatInformationGetFileFail, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_INFORMATION/GET/FILE failures", "/HGCM/VBoxSharedFolders/FnInformationGetFileFail");
1940 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatInformationGetVolume, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_INFORMATION/GET/VOLUME successes", "/HGCM/VBoxSharedFolders/FnInformationGetVolume");
1941 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatInformationGetVolumeFail, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_INFORMATION/GET/VOLUME failures", "/HGCM/VBoxSharedFolders/FnInformationGetVolumeFail");
1942 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatRemove, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_REMOVE successes", "/HGCM/VBoxSharedFolders/FnRemove");
1943 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatRemoveFail, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_REMOVE failures", "/HGCM/VBoxSharedFolders/FnRemoveFail");
1944 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatCloseAndRemove, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_CLOSE_AND_REMOVE successes", "/HGCM/VBoxSharedFolders/FnCloseAndRemove");
1945 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatCloseAndRemoveFail, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_CLOSE_AND_REMOVE failures", "/HGCM/VBoxSharedFolders/FnCloseAndRemoveFail");
1946 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatRename, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_RENAME successes", "/HGCM/VBoxSharedFolders/FnRename");
1947 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatRenameFail, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_RENAME failures", "/HGCM/VBoxSharedFolders/FnRenameFail");
1948 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatFlush, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_FLUSH successes", "/HGCM/VBoxSharedFolders/FnFlush");
1949 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatFlushFail, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_FLUSH failures", "/HGCM/VBoxSharedFolders/FnFlushFail");
1950 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatSetErrorStyle, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_SET_ERROR_STYLE", "/HGCM/VBoxSharedFolders/FnSetErrorStyle");
1951 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatSetUtf8, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_SET_UTF8", "/HGCM/VBoxSharedFolders/FnSetUtf8");
1952 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatSymlink, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_SYMLINK successes", "/HGCM/VBoxSharedFolders/FnSymlink");
1953 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatSymlinkFail, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_SYMLINK failures", "/HGCM/VBoxSharedFolders/FnSymlinkFail");
1954 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatSetSymlinks, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_SET_SYMLINKS", "/HGCM/VBoxSharedFolders/FnSetSymlink");
1955 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatQueryMapInfo, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_QUERY_MAP_INFO", "/HGCM/VBoxSharedFolders/FnQueryMapInfo");
1956 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatQueryFeatures, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_QUERY_FEATURES", "/HGCM/VBoxSharedFolders/FnQueryFeatures");
1957 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatCopyFile, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_COPY_FILE successes", "/HGCM/VBoxSharedFolders/FnCopyFile");
1958 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatCopyFileFail, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_COPY_FILE failures", "/HGCM/VBoxSharedFolders/FnCopyFileFail");
1959 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatCopyFilePart, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_COPY_FILE_PART successes", "/HGCM/VBoxSharedFolders/FnCopyFilePart");
1960 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatCopyFilePartFail, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_COPY_FILE_PART failures", "/HGCM/VBoxSharedFolders/FnCopyFilePartFail");
1961 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatWaitForMappingsChanges, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_WAIT_FOR_MAPPINGS_CHANGES successes", "/HGCM/VBoxSharedFolders/FnWaitForMappingsChanges");
1962 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatWaitForMappingsChangesFail,STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_WAIT_FOR_MAPPINGS_CHANGES failures","/HGCM/VBoxSharedFolders/FnWaitForMappingsChangesFail");
1963 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatCancelMappingsChangesWait, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_CANCEL_MAPPINGS_CHANGES_WAITS", "/HGCM/VBoxSharedFolders/FnCancelMappingsChangesWaits");
1964 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatUnknown, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "SHFL_FN_???", "/HGCM/VBoxSharedFolders/FnUnknown");
1965 HGCMSvcHlpStamRegister(g_pHelpers, &g_StatMsgStage1, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Time from VMMDev arrival to worker thread.","/HGCM/VBoxSharedFolders/MsgStage1");
1966 }
1967 }
1968
1969 return rc;
1970}
1971
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