VirtualBox

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

Last change on this file since 3841 was 3338, checked in by vboxsync, 18 years ago

Export HostServices

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