VirtualBox

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

Last change on this file since 31019 was 31002, checked in by vboxsync, 15 years ago

First support for auto-mounted Shared Folders (Windows only yet).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 46.3 KB
Line 
1/** @file
2 * Shared Folders: Host service entry points.
3 */
4
5/*
6 * Copyright (C) 2006-2007 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 */
16
17#include <VBox/shflsvc.h>
18
19
20#include "shfl.h"
21#include "mappings.h"
22#include "shflhandle.h"
23#include "vbsf.h"
24#include <iprt/alloc.h>
25#include <iprt/string.h>
26#include <iprt/assert.h>
27#include <VBox/ssm.h>
28#include <VBox/pdm.h>
29
30#define SHFL_SSM_VERSION 2
31
32
33/* Shared Folders Host Service.
34 *
35 * Shared Folders map a host file system to guest logical filesystem.
36 * A mapping represents 'host name'<->'guest name' translation and a root
37 * identifier to be used to access this mapping.
38 * Examples: "C:\WINNT"<->"F:", "C:\WINNT\System32"<->"/mnt/host/system32".
39 *
40 * Therefore, host name and guest name are strings interpreted
41 * only by host service and guest client respectively. Host name is
42 * passed to guest only for informational purpose. Guest may for example
43 * display the string or construct volume label out of the string.
44 *
45 * Root identifiers are unique for whole guest life,
46 * that is until next guest reset/fresh start.
47 * 32 bit value incremented for each new mapping is used.
48 *
49 * Mapping strings are taken from VM XML configuration on VM startup.
50 * The service DLL takes mappings during initialization. There is
51 * also API for changing mappings at runtime.
52 *
53 * Current mappings and root identifiers are saved when VM is saved.
54 *
55 * Guest may use any of these mappings. Full path information
56 * about an object on a mapping consists of the root indentifier and
57 * a full path of object.
58 *
59 * Guest IFS connects to the service and calls SHFL_FN_QUERY_MAP
60 * function which returns current mappings. For guest convenience,
61 * removed mappings also returned with REMOVED flag and new mappings
62 * are marked with NEW flag.
63 *
64 * To access host file system guest just forwards file system calls
65 * to the service, and specifies full paths or handles for objects.
66 *
67 *
68 */
69
70
71PVBOXHGCMSVCHELPERS g_pHelpers;
72static PPDMLED pStatusLed = NULL;
73
74static DECLCALLBACK(int) svcUnload (void *)
75{
76 int rc = VINF_SUCCESS;
77
78 Log(("svcUnload\n"));
79
80 return rc;
81}
82
83static DECLCALLBACK(int) svcConnect (void *, uint32_t u32ClientID, void *pvClient)
84{
85 int rc = VINF_SUCCESS;
86
87 NOREF(u32ClientID);
88 NOREF(pvClient);
89
90 LogRel(("SharedFolders host service: connected, u32ClientID = %d\n", u32ClientID));
91
92 return rc;
93}
94
95static DECLCALLBACK(int) svcDisconnect (void *, uint32_t u32ClientID, void *pvClient)
96{
97 int rc = VINF_SUCCESS;
98 SHFLCLIENTDATA *pClient = (SHFLCLIENTDATA *)pvClient;
99
100 LogRel(("SharedFolders host service: disconnected, u32ClientID = %d\n", u32ClientID));
101
102 vbsfDisconnect(pClient);
103 return rc;
104}
105
106/** @note We only save as much state as required to access the shared folder again after restore.
107 * All I/O requests pending at the time of saving will never be completed or result in errors.
108 * (file handles no longer valid etc)
109 * This works as designed at the moment. A full state save would be difficult and not always possible
110 * as the contents of a shared folder might change in between save and restore.
111 */
112static DECLCALLBACK(int) svcSaveState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM)
113{
114 SHFLCLIENTDATA *pClient = (SHFLCLIENTDATA *)pvClient;
115
116 LogRel(("SharedFolders host service: saving state, u32ClientID = %d\n", u32ClientID));
117
118 int rc = SSMR3PutU32(pSSM, SHFL_SSM_VERSION);
119 AssertRCReturn(rc, rc);
120
121 rc = SSMR3PutU32(pSSM, SHFL_MAX_MAPPINGS);
122 AssertRCReturn(rc, rc);
123
124 /* Save client structure length & contents */
125 rc = SSMR3PutU32(pSSM, sizeof(*pClient));
126 AssertRCReturn(rc, rc);
127
128 rc = SSMR3PutMem(pSSM, pClient, sizeof(*pClient));
129 AssertRCReturn(rc, rc);
130
131 /* Save all the active mappings. */
132 for (int i=0;i<SHFL_MAX_MAPPINGS;i++)
133 {
134 /* Mapping are saved in the order of increasing root handle values. */
135 MAPPING *pFolderMapping = vbsfMappingGetByRoot(i);
136
137 rc = SSMR3PutU32(pSSM, pFolderMapping? pFolderMapping->cMappings: 0);
138 AssertRCReturn(rc, rc);
139
140 rc = SSMR3PutBool(pSSM, pFolderMapping? pFolderMapping->fValid: false);
141 AssertRCReturn(rc, rc);
142
143 if (pFolderMapping && pFolderMapping->fValid)
144 {
145 uint32_t len;
146
147 len = ShflStringSizeOfBuffer(pFolderMapping->pFolderName);
148 rc = SSMR3PutU32(pSSM, len);
149 AssertRCReturn(rc, rc);
150
151 rc = SSMR3PutMem(pSSM, pFolderMapping->pFolderName, len);
152 AssertRCReturn(rc, rc);
153
154 len = ShflStringSizeOfBuffer(pFolderMapping->pMapName);
155 rc = SSMR3PutU32(pSSM, len);
156 AssertRCReturn(rc, rc);
157
158 rc = SSMR3PutMem(pSSM, pFolderMapping->pMapName, len);
159 AssertRCReturn(rc, rc);
160
161 rc = SSMR3PutBool(pSSM, pFolderMapping->fHostCaseSensitive);
162 AssertRCReturn(rc, rc);
163
164 rc = SSMR3PutBool(pSSM, pFolderMapping->fGuestCaseSensitive);
165 AssertRCReturn(rc, rc);
166 }
167 }
168
169 return VINF_SUCCESS;
170}
171
172static DECLCALLBACK(int) svcLoadState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM)
173{
174 uint32_t nrMappings;
175 SHFLCLIENTDATA *pClient = (SHFLCLIENTDATA *)pvClient;
176 uint32_t len, version;
177
178 LogRel(("SharedFolders host service: loading state, u32ClientID = %d\n", u32ClientID));
179
180 int rc = SSMR3GetU32(pSSM, &version);
181 AssertRCReturn(rc, rc);
182
183 if (version != SHFL_SSM_VERSION)
184 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
185
186 rc = SSMR3GetU32(pSSM, &nrMappings);
187 AssertRCReturn(rc, rc);
188 if (nrMappings != SHFL_MAX_MAPPINGS)
189 return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
190
191 /* Restore the client data (flags + path delimiter at the moment) */
192 rc = SSMR3GetU32(pSSM, &len);
193 AssertRCReturn(rc, rc);
194
195 if (len != sizeof(*pClient))
196 return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;
197
198 rc = SSMR3GetMem(pSSM, pClient, sizeof(*pClient));
199 AssertRCReturn(rc, rc);
200
201 /* We don't actually (fully) restore the state; we simply check if the current state is as we it expect it to be. */
202 for (int i=0;i<SHFL_MAX_MAPPINGS;i++)
203 {
204 /* Load the saved mapping description and try to find it in the mappings. */
205 MAPPING mapping;
206 memset (&mapping, 0, sizeof (mapping));
207
208 /* restore the folder mapping counter. */
209 rc = SSMR3GetU32(pSSM, &mapping.cMappings);
210 AssertRCReturn(rc, rc);
211
212 rc = SSMR3GetBool(pSSM, &mapping.fValid);
213 AssertRCReturn(rc, rc);
214
215 if (mapping.fValid)
216 {
217 uint32_t cbFolderName;
218 PSHFLSTRING pFolderName;
219
220 uint32_t cbMapName;
221 PSHFLSTRING pMapName;
222
223 /* Load the host path name. */
224 rc = SSMR3GetU32(pSSM, &cbFolderName);
225 AssertRCReturn(rc, rc);
226
227 pFolderName = (PSHFLSTRING)RTMemAlloc(cbFolderName);
228 AssertReturn(pFolderName != NULL, VERR_NO_MEMORY);
229
230 rc = SSMR3GetMem(pSSM, pFolderName, cbFolderName);
231 AssertRCReturn(rc, rc);
232
233 /* Load the map name. */
234 rc = SSMR3GetU32(pSSM, &cbMapName);
235 AssertRCReturn(rc, rc);
236
237 pMapName = (PSHFLSTRING)RTMemAlloc(cbMapName);
238 AssertReturn(pMapName != NULL, VERR_NO_MEMORY);
239
240 rc = SSMR3GetMem(pSSM, pMapName, cbMapName);
241 AssertRCReturn(rc, rc);
242
243 rc = SSMR3GetBool(pSSM, &mapping.fHostCaseSensitive);
244 AssertRCReturn(rc, rc);
245
246 rc = SSMR3GetBool(pSSM, &mapping.fGuestCaseSensitive);
247 AssertRCReturn(rc, rc);
248
249 mapping.pFolderName = pFolderName;
250 mapping.pMapName = pMapName;
251
252 /* 'i' is the root handle of the saved mapping. */
253 rc = vbsfMappingLoaded (&mapping, i);
254
255 RTMemFree(pMapName);
256 RTMemFree(pFolderName);
257
258 AssertRCReturn(rc, rc);
259 }
260 }
261 LogRel(("SharedFolders host service: success\n"));
262 return VINF_SUCCESS;
263}
264
265static DECLCALLBACK(void) svcCall (void *, VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID, void *pvClient, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
266{
267 int rc = VINF_SUCCESS;
268
269 Log(("svcCall: u32ClientID = %d, fn = %d, cParms = %d, pparms = %d\n", u32ClientID, u32Function, cParms, paParms));
270
271 SHFLCLIENTDATA *pClient = (SHFLCLIENTDATA *)pvClient;
272
273 bool fAsynchronousProcessing = false;
274
275#ifdef DEBUG
276 uint32_t i;
277
278 for (i = 0; i < cParms; i++)
279 {
280 /** @todo parameters other than 32 bit */
281 Log((" pparms[%d]: type %d value %d\n", i, paParms[i].type, paParms[i].u.uint32));
282 }
283#endif
284
285 switch (u32Function)
286 {
287 case SHFL_FN_QUERY_MAPPINGS:
288 {
289 Log(("svcCall: SHFL_FN_QUERY_MAPPINGS\n"));
290
291 /* Verify parameter count and types. */
292 if (cParms != SHFL_CPARMS_QUERY_MAPPINGS)
293 {
294 rc = VERR_INVALID_PARAMETER;
295 }
296 else if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* flags */
297 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* numberOfMappings */
298 || paParms[2].type != VBOX_HGCM_SVC_PARM_PTR /* mappings */
299 )
300 {
301 rc = VERR_INVALID_PARAMETER;
302 }
303 else
304 {
305 /* Fetch parameters. */
306 uint32_t fu32Flags = paParms[0].u.uint32;
307 uint32_t cMappings = paParms[1].u.uint32;
308 SHFLMAPPING *pMappings = (SHFLMAPPING *)paParms[2].u.pointer.addr;
309 uint32_t cbMappings = paParms[2].u.pointer.size;
310
311 /* Verify parameters values. */
312 if ( (fu32Flags & ~SHFL_MF_MASK) != 0
313 || cbMappings / sizeof (SHFLMAPPING) != cMappings
314 )
315 {
316 rc = VERR_INVALID_PARAMETER;
317 }
318 else
319 {
320 /* Execute the function. */
321 if (fu32Flags & SHFL_MF_UTF8)
322 pClient->fu32Flags |= SHFL_CF_UTF8;
323 if (fu32Flags & SHFL_MF_AUTOMOUNT)
324 pClient->fu32Flags |= SHFL_MF_AUTOMOUNT;
325
326 rc = vbsfMappingsQuery(pClient, pMappings, &cMappings);
327 if (RT_SUCCESS(rc))
328 {
329 /* Update parameters. */
330 paParms[1].u.uint32 = cMappings;
331 }
332 }
333 }
334
335
336 } break;
337
338 case SHFL_FN_QUERY_MAP_NAME:
339 {
340 Log(("svcCall: SHFL_FN_QUERY_MAP_NAME\n"));
341
342 /* Verify parameter count and types. */
343 if (cParms != SHFL_CPARMS_QUERY_MAP_NAME)
344 {
345 rc = VERR_INVALID_PARAMETER;
346 }
347 else if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* Root. */
348 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR /* Name. */
349 )
350 {
351 rc = VERR_INVALID_PARAMETER;
352 }
353 else
354 {
355 /* Fetch parameters. */
356 SHFLROOT root = (SHFLROOT)paParms[0].u.uint32;
357 SHFLSTRING *pString = (SHFLSTRING *)paParms[1].u.pointer.addr;
358
359 /* Verify parameters values. */
360 if (!ShflStringIsValid(pString, paParms[1].u.pointer.size))
361 {
362 rc = VERR_INVALID_PARAMETER;
363 }
364 else
365 {
366 /* Execute the function. */
367 rc = vbsfMappingsQueryName(pClient, root, pString);
368
369 if (RT_SUCCESS(rc))
370 {
371 /* Update parameters.*/
372 ; /* None. */
373 }
374 }
375 }
376
377 } break;
378
379 case SHFL_FN_CREATE:
380 {
381 Log(("svcCall: SHFL_FN_CREATE\n"));
382
383 /* Verify parameter count and types. */
384 if (cParms != SHFL_CPARMS_CREATE)
385 {
386 rc = VERR_INVALID_PARAMETER;
387 }
388 else if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* root */
389 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR /* path */
390 || paParms[2].type != VBOX_HGCM_SVC_PARM_PTR /* parms */
391 )
392 {
393 Log(("Invalid parameters types\n"));
394 rc = VERR_INVALID_PARAMETER;
395 }
396 else
397 {
398 /* Fetch parameters. */
399 SHFLROOT root = (SHFLROOT)paParms[0].u.uint32;
400 SHFLSTRING *pPath = (SHFLSTRING *)paParms[1].u.pointer.addr;
401 uint32_t cbPath = paParms[1].u.pointer.size;
402 SHFLCREATEPARMS *pParms = (SHFLCREATEPARMS *)paParms[2].u.pointer.addr;
403 uint32_t cbParms = paParms[2].u.pointer.size;
404
405 /* Verify parameters values. */
406 if ( !ShflStringIsValid(pPath, cbPath)
407 || (cbParms != sizeof (SHFLCREATEPARMS))
408 )
409 {
410 AssertMsgFailed (("Invalid parameters cbPath or cbParms (%x, %x - expected >=%x, %x)\n",
411 cbPath, cbParms, sizeof(SHFLSTRING), sizeof (SHFLCREATEPARMS)));
412 rc = VERR_INVALID_PARAMETER;
413 }
414 else
415 {
416 /* Execute the function. */
417
418 rc = vbsfCreate (pClient, root, pPath, cbPath, pParms);
419
420 if (RT_SUCCESS(rc))
421 {
422 /* Update parameters.*/
423 ; /* none */
424 }
425 }
426 }
427 break;
428 }
429
430 case SHFL_FN_CLOSE:
431 {
432 Log(("svcCall: SHFL_FN_CLOSE\n"));
433
434 /* Verify parameter count and types. */
435 if (cParms != SHFL_CPARMS_CLOSE)
436 {
437 rc = VERR_INVALID_PARAMETER;
438 }
439 else if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* root */
440 || paParms[1].type != VBOX_HGCM_SVC_PARM_64BIT /* handle */
441 )
442 {
443 rc = VERR_INVALID_PARAMETER;
444 }
445 else
446 {
447 /* Fetch parameters. */
448 SHFLROOT root = (SHFLROOT)paParms[0].u.uint32;
449 SHFLHANDLE Handle = paParms[1].u.uint64;
450
451 /* Verify parameters values. */
452 if (Handle == SHFL_HANDLE_ROOT)
453 {
454 rc = VERR_INVALID_PARAMETER;
455 }
456 else
457 if (Handle == SHFL_HANDLE_NIL)
458 {
459 AssertMsgFailed(("Invalid handle!!!!\n"));
460 rc = VERR_INVALID_HANDLE;
461 }
462 else
463 {
464 /* Execute the function. */
465
466 rc = vbsfClose (pClient, root, Handle);
467
468 if (RT_SUCCESS(rc))
469 {
470 /* Update parameters.*/
471 ; /* none */
472 }
473 }
474 }
475 break;
476
477 }
478
479 /** Read object content. */
480 case SHFL_FN_READ:
481 Log(("svcCall: SHFL_FN_READ\n"));
482
483 /* Verify parameter count and types. */
484 if (cParms != SHFL_CPARMS_READ)
485 {
486 rc = VERR_INVALID_PARAMETER;
487 }
488 else
489 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* root */
490 || paParms[1].type != VBOX_HGCM_SVC_PARM_64BIT /* handle */
491 || paParms[2].type != VBOX_HGCM_SVC_PARM_64BIT /* offset */
492 || paParms[3].type != VBOX_HGCM_SVC_PARM_32BIT /* count */
493 || paParms[4].type != VBOX_HGCM_SVC_PARM_PTR /* buffer */
494 )
495 {
496 rc = VERR_INVALID_PARAMETER;
497 }
498 else
499 {
500 /* Fetch parameters. */
501 SHFLROOT root = (SHFLROOT)paParms[0].u.uint32;
502 SHFLHANDLE Handle = paParms[1].u.uint64;
503 uint64_t offset = paParms[2].u.uint64;
504 uint32_t count = paParms[3].u.uint32;
505 uint8_t *pBuffer = (uint8_t *)paParms[4].u.pointer.addr;
506
507 /* Verify parameters values. */
508 if ( Handle == SHFL_HANDLE_ROOT
509 || count > paParms[4].u.pointer.size
510 )
511 {
512 rc = VERR_INVALID_PARAMETER;
513 }
514 else
515 if (Handle == SHFL_HANDLE_NIL)
516 {
517 AssertMsgFailed(("Invalid handle!!!!\n"));
518 rc = VERR_INVALID_HANDLE;
519 }
520 else
521 {
522 /* Execute the function. */
523 if (pStatusLed)
524 {
525 Assert(pStatusLed->u32Magic == PDMLED_MAGIC);
526 pStatusLed->Asserted.s.fReading = pStatusLed->Actual.s.fReading = 1;
527 }
528
529 rc = vbsfRead (pClient, root, Handle, offset, &count, pBuffer);
530 if (pStatusLed)
531 pStatusLed->Actual.s.fReading = 0;
532
533 if (RT_SUCCESS(rc))
534 {
535 /* Update parameters.*/
536 paParms[3].u.uint32 = count;
537 }
538 else
539 {
540 paParms[3].u.uint32 = 0; /* nothing read */
541 }
542 }
543 }
544 break;
545
546 /** Write new object content. */
547 case SHFL_FN_WRITE:
548 Log(("svcCall: SHFL_FN_WRITE\n"));
549
550 /* Verify parameter count and types. */
551 if (cParms != SHFL_CPARMS_WRITE)
552 {
553 rc = VERR_INVALID_PARAMETER;
554 }
555 else
556 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* root */
557 || paParms[1].type != VBOX_HGCM_SVC_PARM_64BIT /* handle */
558 || paParms[2].type != VBOX_HGCM_SVC_PARM_64BIT /* offset */
559 || paParms[3].type != VBOX_HGCM_SVC_PARM_32BIT /* count */
560 || paParms[4].type != VBOX_HGCM_SVC_PARM_PTR /* buffer */
561 )
562 {
563 rc = VERR_INVALID_PARAMETER;
564 }
565 else
566 {
567 /* Fetch parameters. */
568 SHFLROOT root = (SHFLROOT)paParms[0].u.uint32;
569 SHFLHANDLE Handle = paParms[1].u.uint64;
570 uint64_t offset = paParms[2].u.uint64;
571 uint32_t count = paParms[3].u.uint32;
572 uint8_t *pBuffer = (uint8_t *)paParms[4].u.pointer.addr;
573
574 /* Verify parameters values. */
575 if ( Handle == SHFL_HANDLE_ROOT
576 || count > paParms[4].u.pointer.size
577 )
578 {
579 rc = VERR_INVALID_PARAMETER;
580 }
581 else
582 if (Handle == SHFL_HANDLE_NIL)
583 {
584 AssertMsgFailed(("Invalid handle!!!!\n"));
585 rc = VERR_INVALID_HANDLE;
586 }
587 else
588 {
589 /* Execute the function. */
590 if (pStatusLed)
591 {
592 Assert(pStatusLed->u32Magic == PDMLED_MAGIC);
593 pStatusLed->Asserted.s.fWriting = pStatusLed->Actual.s.fWriting = 1;
594 }
595
596 rc = vbsfWrite (pClient, root, Handle, offset, &count, pBuffer);
597 if (pStatusLed)
598 pStatusLed->Actual.s.fWriting = 0;
599
600 if (RT_SUCCESS(rc))
601 {
602 /* Update parameters.*/
603 paParms[3].u.uint32 = count;
604 }
605 else
606 {
607 paParms[3].u.uint32 = 0; /* nothing read */
608 }
609 }
610 }
611 break;
612
613 /** Lock/unlock a range in the object. */
614 case SHFL_FN_LOCK:
615 Log(("svcCall: SHFL_FN_LOCK\n"));
616
617 /* Verify parameter count and types. */
618 if (cParms != SHFL_CPARMS_LOCK)
619 {
620 rc = VERR_INVALID_PARAMETER;
621 }
622 else
623 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* root */
624 || paParms[1].type != VBOX_HGCM_SVC_PARM_64BIT /* handle */
625 || paParms[2].type != VBOX_HGCM_SVC_PARM_64BIT /* offset */
626 || paParms[3].type != VBOX_HGCM_SVC_PARM_64BIT /* length */
627 || paParms[4].type != VBOX_HGCM_SVC_PARM_32BIT /* flags */
628 )
629 {
630 rc = VERR_INVALID_PARAMETER;
631 }
632 else
633 {
634 /* Fetch parameters. */
635 SHFLROOT root = (SHFLROOT)paParms[0].u.uint32;
636 SHFLHANDLE Handle = paParms[1].u.uint64;
637 uint64_t offset = paParms[2].u.uint64;
638 uint64_t length = paParms[3].u.uint64;
639 uint32_t flags = paParms[4].u.uint32;
640
641 /* Verify parameters values. */
642 if (Handle == SHFL_HANDLE_ROOT)
643 {
644 rc = VERR_INVALID_PARAMETER;
645 }
646 else
647 if (Handle == SHFL_HANDLE_NIL)
648 {
649 AssertMsgFailed(("Invalid handle!!!!\n"));
650 rc = VERR_INVALID_HANDLE;
651 }
652 else if (flags & SHFL_LOCK_WAIT)
653 {
654 /* @todo This should be properly implemented by the shared folders service.
655 * The service thread must never block. If an operation requires
656 * blocking, it must be processed by another thread and when it is
657 * completed, the another thread must call
658 *
659 * g_pHelpers->pfnCallComplete (callHandle, rc);
660 *
661 * The operation is async.
662 * fAsynchronousProcessing = true;
663 */
664
665 /* Here the operation must be posted to another thread. At the moment it is not implemented.
666 * Until it is implemented, try to perform the operation without waiting.
667 */
668 flags &= ~SHFL_LOCK_WAIT;
669
670 /* Execute the function. */
671 if ((flags & SHFL_LOCK_MODE_MASK) == SHFL_LOCK_CANCEL)
672 rc = vbsfUnlock(pClient, root, Handle, offset, length, flags);
673 else
674 rc = vbsfLock(pClient, root, Handle, offset, length, flags);
675
676 if (RT_SUCCESS(rc))
677 {
678 /* Update parameters.*/
679 /* none */
680 }
681 }
682 else
683 {
684 /* Execute the function. */
685 if ((flags & SHFL_LOCK_MODE_MASK) == SHFL_LOCK_CANCEL)
686 rc = vbsfUnlock(pClient, root, Handle, offset, length, flags);
687 else
688 rc = vbsfLock(pClient, root, Handle, offset, length, flags);
689
690 if (RT_SUCCESS(rc))
691 {
692 /* Update parameters.*/
693 /* none */
694 }
695 }
696 }
697 break;
698
699 /** List object content. */
700 case SHFL_FN_LIST:
701 {
702 Log(("svcCall: SHFL_FN_LIST\n"));
703
704 /* Verify parameter count and types. */
705 if (cParms != SHFL_CPARMS_LIST)
706 {
707 rc = VERR_INVALID_PARAMETER;
708 }
709 else
710 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* root */
711 || paParms[1].type != VBOX_HGCM_SVC_PARM_64BIT /* handle */
712 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* flags */
713 || paParms[3].type != VBOX_HGCM_SVC_PARM_32BIT /* cb */
714 || paParms[4].type != VBOX_HGCM_SVC_PARM_PTR /* pPath */
715 || paParms[5].type != VBOX_HGCM_SVC_PARM_PTR /* buffer */
716 || paParms[6].type != VBOX_HGCM_SVC_PARM_32BIT /* resumePoint */
717 || paParms[7].type != VBOX_HGCM_SVC_PARM_32BIT /* cFiles (out) */
718 )
719 {
720 rc = VERR_INVALID_PARAMETER;
721 }
722 else
723 {
724 /* Fetch parameters. */
725 SHFLROOT root = (SHFLROOT)paParms[0].u.uint32;
726 SHFLHANDLE Handle = paParms[1].u.uint64;
727 uint32_t flags = paParms[2].u.uint32;
728 uint32_t length = paParms[3].u.uint32;
729 SHFLSTRING *pPath = (paParms[4].u.pointer.size == 0) ? 0 : (SHFLSTRING *)paParms[4].u.pointer.addr;
730 uint8_t *pBuffer = (uint8_t *)paParms[5].u.pointer.addr;
731 uint32_t resumePoint = paParms[6].u.uint32;
732 uint32_t cFiles = 0;
733
734 /* Verify parameters values. */
735 if ( (length < sizeof (SHFLDIRINFO))
736 || length > paParms[5].u.pointer.size
737 || !ShflStringIsValidOrNull(pPath, paParms[4].u.pointer.size)
738 )
739 {
740 rc = VERR_INVALID_PARAMETER;
741 }
742 else
743 {
744 if (pStatusLed)
745 {
746 Assert(pStatusLed->u32Magic == PDMLED_MAGIC);
747 pStatusLed->Asserted.s.fReading = pStatusLed->Actual.s.fReading = 1;
748 }
749
750 /* Execute the function. */
751 rc = vbsfDirList (pClient, root, Handle, pPath, flags, &length, pBuffer, &resumePoint, &cFiles);
752
753 if (pStatusLed)
754 pStatusLed->Actual.s.fReading = 0;
755
756 if (rc == VERR_NO_MORE_FILES && cFiles != 0)
757 rc = VINF_SUCCESS; /* Successfully return these files. */
758
759 if (RT_SUCCESS(rc))
760 {
761 /* Update parameters.*/
762 paParms[3].u.uint32 = length;
763 paParms[6].u.uint32 = resumePoint;
764 paParms[7].u.uint32 = cFiles;
765 }
766 else
767 {
768 paParms[3].u.uint32 = 0; /* nothing read */
769 paParms[6].u.uint32 = 0;
770 paParms[7].u.uint32 = cFiles;
771 }
772 }
773 }
774 break;
775 }
776
777 /* Legacy interface */
778 case SHFL_FN_MAP_FOLDER_OLD:
779 {
780 Log(("svcCall: SHFL_FN_MAP_FOLDER_OLD\n"));
781
782 /* Verify parameter count and types. */
783 if (cParms != SHFL_CPARMS_MAP_FOLDER_OLD)
784 {
785 rc = VERR_INVALID_PARAMETER;
786 }
787 else if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* path */
788 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* root */
789 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* delimiter */
790 )
791 {
792 rc = VERR_INVALID_PARAMETER;
793 }
794 else
795 {
796 /* Fetch parameters. */
797 PSHFLSTRING pszMapName = (PSHFLSTRING)paParms[0].u.pointer.addr;
798 SHFLROOT root = (SHFLROOT)paParms[1].u.uint32;
799 RTUTF16 delimiter = (RTUTF16)paParms[2].u.uint32;
800
801 /* Verify parameters values. */
802 if (!ShflStringIsValid(pszMapName, paParms[0].u.pointer.size))
803 {
804 rc = VERR_INVALID_PARAMETER;
805 }
806 else
807 {
808 /* Execute the function. */
809 rc = vbsfMapFolder (pClient, pszMapName, delimiter, false, &root);
810
811 if (RT_SUCCESS(rc))
812 {
813 /* Update parameters.*/
814 paParms[1].u.uint32 = root;
815 }
816 }
817 }
818 break;
819 }
820
821 case SHFL_FN_MAP_FOLDER:
822 {
823 Log(("svcCall: SHFL_FN_MAP_FOLDER\n"));
824 if (BIT_FLAG(pClient->fu32Flags, SHFL_CF_UTF8))
825 LogRel(("SharedFolders host service: request to map folder '%S'\n",
826 ((PSHFLSTRING)paParms[0].u.pointer.addr)->String.utf8));
827 else
828 LogRel(("SharedFolders host service: request to map folder '%lS'\n",
829 ((PSHFLSTRING)paParms[0].u.pointer.addr)->String.ucs2));
830
831 /* Verify parameter count and types. */
832 if (cParms != SHFL_CPARMS_MAP_FOLDER)
833 {
834 rc = VERR_INVALID_PARAMETER;
835 }
836 else if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* path */
837 || paParms[1].type != VBOX_HGCM_SVC_PARM_32BIT /* root */
838 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* delimiter */
839 || paParms[3].type != VBOX_HGCM_SVC_PARM_32BIT /* fCaseSensitive */
840 )
841 {
842 rc = VERR_INVALID_PARAMETER;
843 }
844 else
845 {
846 /* Fetch parameters. */
847 PSHFLSTRING pszMapName = (PSHFLSTRING)paParms[0].u.pointer.addr;
848 SHFLROOT root = (SHFLROOT)paParms[1].u.uint32;
849 RTUTF16 delimiter = (RTUTF16)paParms[2].u.uint32;
850 bool fCaseSensitive = !!paParms[3].u.uint32;
851
852 /* Verify parameters values. */
853 if (!ShflStringIsValid(pszMapName, paParms[0].u.pointer.size))
854 {
855 rc = VERR_INVALID_PARAMETER;
856 }
857 else
858 {
859
860 /* Execute the function. */
861 rc = vbsfMapFolder (pClient, pszMapName, delimiter, fCaseSensitive, &root);
862
863 if (RT_SUCCESS(rc))
864 {
865 /* Update parameters.*/
866 paParms[1].u.uint32 = root;
867 }
868 }
869 }
870 LogRel(("SharedFolders host service: map operation result %Rrc.\n", rc));
871 if (RT_SUCCESS(rc))
872 LogRel((" Mapped to handle %d.\n", paParms[1].u.uint32));
873 break;
874 }
875
876 case SHFL_FN_UNMAP_FOLDER:
877 {
878 Log(("svcCall: SHFL_FN_UNMAP_FOLDER\n"));
879 LogRel(("SharedFolders host service: request to unmap folder handle %d\n",
880 paParms[0].u.uint32));
881
882 /* Verify parameter count and types. */
883 if (cParms != SHFL_CPARMS_UNMAP_FOLDER)
884 {
885 rc = VERR_INVALID_PARAMETER;
886 }
887 else if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* root */
888 )
889 {
890 rc = VERR_INVALID_PARAMETER;
891 }
892 else
893 {
894 /* Fetch parameters. */
895 SHFLROOT root = (SHFLROOT)paParms[0].u.uint32;
896
897 /* Execute the function. */
898 rc = vbsfUnmapFolder (pClient, root);
899
900 if (RT_SUCCESS(rc))
901 {
902 /* Update parameters.*/
903 /* nothing */
904 }
905 }
906 LogRel(("SharedFolders host service: unmap operation result %Rrc.\n", rc));
907 break;
908 }
909
910 /** Query/set object information. */
911 case SHFL_FN_INFORMATION:
912 {
913 Log(("svcCall: SHFL_FN_INFORMATION\n"));
914
915 /* Verify parameter count and types. */
916 if (cParms != SHFL_CPARMS_INFORMATION)
917 {
918 rc = VERR_INVALID_PARAMETER;
919 }
920 else
921 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* root */
922 || paParms[1].type != VBOX_HGCM_SVC_PARM_64BIT /* handle */
923 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* flags */
924 || paParms[3].type != VBOX_HGCM_SVC_PARM_32BIT /* cb */
925 || paParms[4].type != VBOX_HGCM_SVC_PARM_PTR /* buffer */
926 )
927 {
928 rc = VERR_INVALID_PARAMETER;
929 }
930 else
931 {
932 /* Fetch parameters. */
933 SHFLROOT root = (SHFLROOT)paParms[0].u.uint32;
934 SHFLHANDLE Handle = paParms[1].u.uint64;
935 uint32_t flags = paParms[2].u.uint32;
936 uint32_t length = paParms[3].u.uint32;
937 uint8_t *pBuffer = (uint8_t *)paParms[4].u.pointer.addr;
938
939 /* Verify parameters values. */
940 if (length > paParms[4].u.pointer.size)
941 {
942 rc = VERR_INVALID_PARAMETER;
943 }
944 else
945 {
946 /* Execute the function. */
947 if (flags & SHFL_INFO_SET)
948 rc = vbsfSetFSInfo (pClient, root, Handle, flags, &length, pBuffer);
949 else /* SHFL_INFO_GET */
950 rc = vbsfQueryFSInfo (pClient, root, Handle, flags, &length, pBuffer);
951
952 if (RT_SUCCESS(rc))
953 {
954 /* Update parameters.*/
955 paParms[3].u.uint32 = length;
956 }
957 else
958 {
959 paParms[3].u.uint32 = 0; /* nothing read */
960 }
961 }
962 }
963 break;
964 }
965
966 /** Remove or rename object */
967 case SHFL_FN_REMOVE:
968 {
969 Log(("svcCall: SHFL_FN_REMOVE\n"));
970
971 /* Verify parameter count and types. */
972 if (cParms != SHFL_CPARMS_REMOVE)
973 {
974 rc = VERR_INVALID_PARAMETER;
975 }
976 else if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* root */
977 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR /* path */
978 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* flags */
979 )
980 {
981 rc = VERR_INVALID_PARAMETER;
982 }
983 else
984 {
985 /* Fetch parameters. */
986 SHFLROOT root = (SHFLROOT)paParms[0].u.uint32;
987 SHFLSTRING *pPath = (SHFLSTRING *)paParms[1].u.pointer.addr;
988 uint32_t cbPath = paParms[1].u.pointer.size;
989 uint32_t flags = paParms[2].u.uint32;
990
991 /* Verify parameters values. */
992 if (!ShflStringIsValid(pPath, cbPath))
993 {
994 rc = VERR_INVALID_PARAMETER;
995 }
996 else
997 {
998 /* Execute the function. */
999
1000 rc = vbsfRemove (pClient, root, pPath, cbPath, flags);
1001 if (RT_SUCCESS(rc))
1002 {
1003 /* Update parameters.*/
1004 ; /* none */
1005 }
1006 }
1007 }
1008 break;
1009 }
1010
1011 case SHFL_FN_RENAME:
1012 {
1013 Log(("svcCall: SHFL_FN_RENAME\n"));
1014
1015 /* Verify parameter count and types. */
1016 if (cParms != SHFL_CPARMS_RENAME)
1017 {
1018 rc = VERR_INVALID_PARAMETER;
1019 }
1020 else if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* root */
1021 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR /* src */
1022 || paParms[2].type != VBOX_HGCM_SVC_PARM_PTR /* dest */
1023 || paParms[3].type != VBOX_HGCM_SVC_PARM_32BIT /* flags */
1024 )
1025 {
1026 rc = VERR_INVALID_PARAMETER;
1027 }
1028 else
1029 {
1030 /* Fetch parameters. */
1031 SHFLROOT root = (SHFLROOT)paParms[0].u.uint32;
1032 SHFLSTRING *pSrc = (SHFLSTRING *)paParms[1].u.pointer.addr;
1033 SHFLSTRING *pDest = (SHFLSTRING *)paParms[2].u.pointer.addr;
1034 uint32_t flags = paParms[3].u.uint32;
1035
1036 /* Verify parameters values. */
1037 if ( !ShflStringIsValid(pSrc, paParms[1].u.pointer.size)
1038 || !ShflStringIsValid(pDest, paParms[2].u.pointer.size)
1039 )
1040 {
1041 rc = VERR_INVALID_PARAMETER;
1042 }
1043 else
1044 {
1045 /* Execute the function. */
1046 rc = vbsfRename (pClient, root, pSrc, pDest, flags);
1047 if (RT_SUCCESS(rc))
1048 {
1049 /* Update parameters.*/
1050 ; /* none */
1051 }
1052 }
1053 }
1054 break;
1055 }
1056
1057 case SHFL_FN_FLUSH:
1058 {
1059 Log(("svcCall: SHFL_FN_FLUSH\n"));
1060
1061 /* Verify parameter count and types. */
1062 if (cParms != SHFL_CPARMS_FLUSH)
1063 {
1064 rc = VERR_INVALID_PARAMETER;
1065 }
1066 else
1067 if ( paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT /* root */
1068 || paParms[1].type != VBOX_HGCM_SVC_PARM_64BIT /* handle */
1069 )
1070 {
1071 rc = VERR_INVALID_PARAMETER;
1072 }
1073 else
1074 {
1075 /* Fetch parameters. */
1076 SHFLROOT root = (SHFLROOT)paParms[0].u.uint32;
1077 SHFLHANDLE Handle = paParms[1].u.uint64;
1078
1079 /* Verify parameters values. */
1080 if (Handle == SHFL_HANDLE_ROOT)
1081 {
1082 rc = VERR_INVALID_PARAMETER;
1083 }
1084 else
1085 if (Handle == SHFL_HANDLE_NIL)
1086 {
1087 AssertMsgFailed(("Invalid handle!!!!\n"));
1088 rc = VERR_INVALID_HANDLE;
1089 }
1090 else
1091 {
1092 /* Execute the function. */
1093
1094 rc = vbsfFlush (pClient, root, Handle);
1095
1096 if (RT_SUCCESS(rc))
1097 {
1098 /* Nothing to do */
1099 }
1100 }
1101 }
1102 } break;
1103
1104 case SHFL_FN_SET_UTF8:
1105 {
1106 pClient->fu32Flags |= SHFL_CF_UTF8;
1107 rc = VINF_SUCCESS;
1108 break;
1109 }
1110
1111 default:
1112 {
1113 rc = VERR_NOT_IMPLEMENTED;
1114 break;
1115 }
1116 }
1117
1118 LogFlow(("svcCall: rc = %Rrc\n", rc));
1119
1120 if ( !fAsynchronousProcessing
1121 || RT_FAILURE (rc))
1122 {
1123 /* Complete the operation if it was unsuccessful or
1124 * it was processed synchronously.
1125 */
1126 g_pHelpers->pfnCallComplete (callHandle, rc);
1127 }
1128
1129 LogFlow(("\n")); /* Add a new line to differentiate between calls more easily. */
1130}
1131
1132/*
1133 * We differentiate between a function handler for the guest and one for the host. The guest is not allowed to add or remove mappings for obvious security reasons.
1134 */
1135static DECLCALLBACK(int) svcHostCall (void *, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
1136{
1137 int rc = VINF_SUCCESS;
1138
1139 Log(("svcHostCall: fn = %d, cParms = %d, pparms = %d\n", u32Function, cParms, paParms));
1140
1141#ifdef DEBUG
1142 uint32_t i;
1143
1144 for (i = 0; i < cParms; i++)
1145 {
1146 /** @todo parameters other than 32 bit */
1147 Log((" pparms[%d]: type %d value %d\n", i, paParms[i].type, paParms[i].u.uint32));
1148 }
1149#endif
1150
1151 switch (u32Function)
1152 {
1153 case SHFL_FN_ADD_MAPPING:
1154 {
1155 Log(("svcCall: SHFL_FN_ADD_MAPPING\n"));
1156 LogRel(("SharedFolders host service: adding host mapping.\n"));
1157 LogRel((" Host path '%lS', map name '%lS', %s\n",
1158 ((SHFLSTRING *)paParms[0].u.pointer.addr)->String.ucs2,
1159 ((SHFLSTRING *)paParms[1].u.pointer.addr)->String.ucs2,
1160 paParms[2].u.uint32 ? "writable" : "read-only"));
1161
1162 /* Verify parameter count and types. */
1163 if ( (cParms != SHFL_CPARMS_ADD_MAPPING)
1164 && (cParms != SHFL_CPARMS_ADD_MAPPING2) /* With auto-mount flag. */
1165 )
1166 {
1167 rc = VERR_INVALID_PARAMETER;
1168 }
1169 else if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* host folder name */
1170 || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR /* guest map name */
1171 || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* fWritable */
1172 /* With auto-mount flag? */
1173 || ( cParms == SHFL_CPARMS_ADD_MAPPING2
1174 && paParms[3].type != VBOX_HGCM_SVC_PARM_32BIT))
1175 {
1176 rc = VERR_INVALID_PARAMETER;
1177 }
1178 else
1179 {
1180 /* Fetch parameters. */
1181 SHFLSTRING *pFolderName = (SHFLSTRING *)paParms[0].u.pointer.addr;
1182 SHFLSTRING *pMapName = (SHFLSTRING *)paParms[1].u.pointer.addr;
1183 uint32_t fWritable = paParms[2].u.uint32;
1184 uint32_t fAutoMount = 0; /* Disabled by default. */
1185
1186 /* Handle auto-mount flag if present. */
1187 if (cParms == SHFL_CPARMS_ADD_MAPPING2)
1188 fAutoMount = paParms[3].u.uint32;
1189
1190 /* Verify parameters values. */
1191 if ( !ShflStringIsValid(pFolderName, paParms[0].u.pointer.size)
1192 || !ShflStringIsValid(pMapName, paParms[1].u.pointer.size)
1193 )
1194 {
1195 rc = VERR_INVALID_PARAMETER;
1196 }
1197 else
1198 {
1199 /* Execute the function. */
1200 rc = vbsfMappingsAdd(pFolderName, pMapName, fWritable, fAutoMount);
1201 if (RT_SUCCESS(rc))
1202 {
1203 /* Update parameters.*/
1204 ; /* none */
1205 }
1206 }
1207 }
1208 LogRel(("SharedFolders host service: add mapping result %Rrc\n", rc));
1209 break;
1210 }
1211
1212 case SHFL_FN_REMOVE_MAPPING:
1213 {
1214 Log(("svcCall: SHFL_FN_REMOVE_MAPPING\n"));
1215 LogRel(("SharedFolders host service: removing host mapping '%lS'\n",
1216 ((SHFLSTRING *)paParms[0].u.pointer.addr)->String.ucs2));
1217
1218 /* Verify parameter count and types. */
1219 if (cParms != SHFL_CPARMS_REMOVE_MAPPING)
1220 {
1221 rc = VERR_INVALID_PARAMETER;
1222 }
1223 else if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* folder name */
1224 )
1225 {
1226 rc = VERR_INVALID_PARAMETER;
1227 }
1228 else
1229 {
1230 /* Fetch parameters. */
1231 SHFLSTRING *pString = (SHFLSTRING *)paParms[0].u.pointer.addr;
1232
1233 /* Verify parameters values. */
1234 if (!ShflStringIsValid(pString, paParms[0].u.pointer.size))
1235 {
1236 rc = VERR_INVALID_PARAMETER;
1237 }
1238 else
1239 {
1240 /* Execute the function. */
1241 rc = vbsfMappingsRemove (pString);
1242
1243 if (RT_SUCCESS(rc))
1244 {
1245 /* Update parameters.*/
1246 ; /* none */
1247 }
1248 }
1249 }
1250 LogRel(("SharedFolders host service: remove mapping result %Rrc\n", rc));
1251 break;
1252 }
1253
1254 case SHFL_FN_SET_STATUS_LED:
1255 {
1256 Log(("svcCall: SHFL_FN_SET_STATUS_LED\n"));
1257
1258 /* Verify parameter count and types. */
1259 if (cParms != SHFL_CPARMS_SET_STATUS_LED)
1260 {
1261 rc = VERR_INVALID_PARAMETER;
1262 }
1263 else if ( paParms[0].type != VBOX_HGCM_SVC_PARM_PTR /* folder name */
1264 )
1265 {
1266 rc = VERR_INVALID_PARAMETER;
1267 }
1268 else
1269 {
1270 /* Fetch parameters. */
1271 PPDMLED pLed = (PPDMLED)paParms[0].u.pointer.addr;
1272 uint32_t cbLed = paParms[0].u.pointer.size;
1273
1274 /* Verify parameters values. */
1275 if ( (cbLed != sizeof (PDMLED))
1276 )
1277 {
1278 rc = VERR_INVALID_PARAMETER;
1279 }
1280 else
1281 {
1282 /* Execute the function. */
1283 pStatusLed = pLed;
1284 rc = VINF_SUCCESS;
1285 }
1286 }
1287 break;
1288 }
1289
1290 default:
1291 rc = VERR_NOT_IMPLEMENTED;
1292 break;
1293 }
1294
1295 LogFlow(("svcHostCall: rc = %Rrc\n", rc));
1296 return rc;
1297}
1298
1299extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad (VBOXHGCMSVCFNTABLE *ptable)
1300{
1301 int rc = VINF_SUCCESS;
1302
1303 Log(("VBoxHGCMSvcLoad: ptable = %p\n", ptable));
1304
1305 if (!VALID_PTR(ptable))
1306 {
1307 LogRelFunc(("Bad value of ptable (%p) in shared folders service\n", ptable));
1308 rc = VERR_INVALID_PARAMETER;
1309 }
1310 else
1311 {
1312 Log(("VBoxHGCMSvcLoad: ptable->cbSize = %d, ptable->u32Version = 0x%08X\n", ptable->cbSize, ptable->u32Version));
1313
1314 if ( ptable->cbSize != sizeof (VBOXHGCMSVCFNTABLE)
1315 || ptable->u32Version != VBOX_HGCM_SVC_VERSION)
1316 {
1317 LogRelFunc(("version mismatch loading shared folders service: ptable->cbSize = %d, should be %d, ptable->u32Version = 0x%08X, should be 0x%08X\n", ptable->cbSize, sizeof (VBOXHGCMSVCFNTABLE), ptable->u32Version, VBOX_HGCM_SVC_VERSION));
1318 rc = VERR_VERSION_MISMATCH;
1319 }
1320 else
1321 {
1322 g_pHelpers = ptable->pHelpers;
1323
1324 ptable->cbClient = sizeof (SHFLCLIENTDATA);
1325
1326 ptable->pfnUnload = svcUnload;
1327 ptable->pfnConnect = svcConnect;
1328 ptable->pfnDisconnect = svcDisconnect;
1329 ptable->pfnCall = svcCall;
1330 ptable->pfnHostCall = svcHostCall;
1331 ptable->pfnSaveState = svcSaveState;
1332 ptable->pfnLoadState = svcLoadState;
1333 ptable->pvService = NULL;
1334 }
1335
1336 /* Init handle table */
1337 rc = vbsfInitHandleTable();
1338 AssertRC(rc);
1339
1340 vbsfMappingInit();
1341 }
1342
1343 return rc;
1344}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette