VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedFolders/mappings.cpp@ 28374

Last change on this file since 28374 was 26498, checked in by vboxsync, 15 years ago

lots under src/VBox: whitespace cleanup.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.4 KB
Line 
1/** @file
2 * Shared Folders: Mappings support.
3 */
4
5/*
6 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
17 * Clara, CA 95054 USA or visit http://www.sun.com if you need
18 * additional information or have any questions.
19 */
20
21#include "mappings.h"
22#include <iprt/alloc.h>
23#include <iprt/assert.h>
24#include <iprt/string.h>
25
26/* Shared folders order in the saved state and in the FolderMapping can differ.
27 * So a translation array of root handle is needed.
28 */
29
30static MAPPING FolderMapping[SHFL_MAX_MAPPINGS];
31static SHFLROOT aIndexFromRoot[SHFL_MAX_MAPPINGS];
32
33void vbsfMappingInit(void)
34{
35 unsigned root;
36
37 for (root = 0; root < RT_ELEMENTS(aIndexFromRoot); root++)
38 {
39 aIndexFromRoot[root] = SHFL_ROOT_NIL;
40 }
41}
42
43int vbsfMappingLoaded (const MAPPING *pLoadedMapping, SHFLROOT root)
44{
45 /* Mapping loaded from the saved state with the index. Which means
46 * the guest uses the iMapping as root handle for this folder.
47 * Check whether there is the same mapping in FolderMapping and
48 * update the aIndexFromRoot.
49 *
50 * Also update the mapping properties, which were lost: cMappings.
51 */
52 if (root >= SHFL_MAX_MAPPINGS)
53 {
54 return VERR_INVALID_PARAMETER;
55 }
56
57 SHFLROOT i;
58 for (i = 0; i < RT_ELEMENTS(FolderMapping); i++)
59 {
60 MAPPING *pMapping = &FolderMapping[i];
61
62 /* Equal? */
63 if ( pLoadedMapping->fValid == pMapping->fValid
64 && ShflStringSizeOfBuffer(pLoadedMapping->pMapName) == ShflStringSizeOfBuffer(pMapping->pMapName)
65 && memcmp(pLoadedMapping->pMapName, pMapping->pMapName, ShflStringSizeOfBuffer(pMapping->pMapName)) == 0)
66 {
67 /* Actual index is i. */
68 aIndexFromRoot[root] = i;
69
70 /* Update the mapping properties. */
71 pMapping->cMappings = pLoadedMapping->cMappings;
72
73 return VINF_SUCCESS;
74 }
75 }
76
77 return VERR_INVALID_PARAMETER;
78}
79
80MAPPING *vbsfMappingGetByRoot(SHFLROOT root)
81{
82 if (root < RT_ELEMENTS(aIndexFromRoot))
83 {
84 SHFLROOT iMapping = aIndexFromRoot[root];
85
86 if ( iMapping != SHFL_ROOT_NIL
87 && iMapping < RT_ELEMENTS(FolderMapping))
88 {
89 return &FolderMapping[iMapping];
90 }
91 }
92
93 return NULL;
94}
95
96static SHFLROOT vbsfMappingGetRootFromIndex(SHFLROOT iMapping)
97{
98 unsigned root;
99
100 for (root = 0; root < RT_ELEMENTS(aIndexFromRoot); root++)
101 {
102 if (iMapping == aIndexFromRoot[root])
103 {
104 return root;
105 }
106 }
107
108 return SHFL_ROOT_NIL;
109}
110
111static MAPPING *vbsfMappingGetByName (PRTUTF16 utf16Name, SHFLROOT *pRoot)
112{
113 unsigned i;
114
115 for (i=0; i<SHFL_MAX_MAPPINGS; i++)
116 {
117 if (FolderMapping[i].fValid == true)
118 {
119 if (!RTUtf16LocaleICmp(FolderMapping[i].pMapName->String.ucs2, utf16Name))
120 {
121 SHFLROOT root = vbsfMappingGetRootFromIndex(i);
122
123 if (root != SHFL_ROOT_NIL)
124 {
125 if (pRoot)
126 {
127 *pRoot = root;
128 }
129 return &FolderMapping[i];
130 }
131 else
132 {
133 AssertFailed();
134 }
135 }
136 }
137 }
138
139 return NULL;
140}
141
142static void vbsfRootHandleAdd(SHFLROOT iMapping)
143{
144 unsigned root;
145
146 for (root = 0; root < RT_ELEMENTS(aIndexFromRoot); root++)
147 {
148 if (aIndexFromRoot[root] == SHFL_ROOT_NIL)
149 {
150 aIndexFromRoot[root] = iMapping;
151 return;
152 }
153 }
154
155 AssertFailed();
156}
157
158static void vbsfRootHandleRemove(SHFLROOT iMapping)
159{
160 unsigned root;
161
162 for (root = 0; root < RT_ELEMENTS(aIndexFromRoot); root++)
163 {
164 if (aIndexFromRoot[root] == iMapping)
165 {
166 aIndexFromRoot[root] = SHFL_ROOT_NIL;
167 return;
168 }
169 }
170
171 AssertFailed();
172}
173
174
175
176/*
177 *
178 * We are always executed from one specific HGCM thread. So thread safe.
179 *
180 */
181int vbsfMappingsAdd (PSHFLSTRING pFolderName, PSHFLSTRING pMapName, uint32_t fWritable)
182{
183 unsigned i;
184
185 Assert(pFolderName && pMapName);
186
187 Log(("vbsfMappingsAdd %ls\n", pMapName->String.ucs2));
188
189 /* check for duplicates */
190 for (i=0; i<SHFL_MAX_MAPPINGS; i++)
191 {
192 if (FolderMapping[i].fValid == true)
193 {
194 if (!RTUtf16LocaleICmp(FolderMapping[i].pMapName->String.ucs2, pMapName->String.ucs2))
195 {
196 AssertMsgFailed(("vbsfMappingsAdd: %ls mapping already exists!!\n", pMapName->String.ucs2));
197 return VERR_ALREADY_EXISTS;
198 }
199 }
200 }
201
202 for (i=0; i<SHFL_MAX_MAPPINGS; i++)
203 {
204 if (FolderMapping[i].fValid == false)
205 {
206 FolderMapping[i].pFolderName = (PSHFLSTRING)RTMemAlloc(ShflStringSizeOfBuffer(pFolderName));
207 Assert(FolderMapping[i].pFolderName);
208 if (FolderMapping[i].pFolderName == NULL)
209 return VERR_NO_MEMORY;
210
211 FolderMapping[i].pFolderName->u16Length = pFolderName->u16Length;
212 FolderMapping[i].pFolderName->u16Size = pFolderName->u16Size;
213 memcpy(FolderMapping[i].pFolderName->String.ucs2, pFolderName->String.ucs2, pFolderName->u16Size);
214
215 FolderMapping[i].pMapName = (PSHFLSTRING)RTMemAlloc(ShflStringSizeOfBuffer(pMapName));
216 Assert(FolderMapping[i].pMapName);
217 if (FolderMapping[i].pMapName == NULL)
218 return VERR_NO_MEMORY;
219
220 FolderMapping[i].pMapName->u16Length = pMapName->u16Length;
221 FolderMapping[i].pMapName->u16Size = pMapName->u16Size;
222 memcpy(FolderMapping[i].pMapName->String.ucs2, pMapName->String.ucs2, pMapName->u16Size);
223
224 FolderMapping[i].fValid = true;
225 FolderMapping[i].cMappings = 0;
226 FolderMapping[i].fWritable = !!fWritable;
227
228 /* Check if the host file system is case sensitive */
229 RTFSPROPERTIES prop;
230 char *utf8Root, *asciiroot;
231
232 int rc = RTUtf16ToUtf8(FolderMapping[i].pFolderName->String.ucs2, &utf8Root);
233 AssertRC(rc);
234
235 if (RT_SUCCESS(rc))
236 {
237 rc = RTStrUtf8ToCurrentCP(&asciiroot, utf8Root);
238 if (RT_SUCCESS(rc))
239 {
240 rc = RTFsQueryProperties(asciiroot, &prop);
241 AssertRC(rc);
242 RTStrFree(asciiroot);
243 }
244 RTStrFree(utf8Root);
245 }
246 FolderMapping[i].fHostCaseSensitive = RT_SUCCESS(rc) ? prop.fCaseSensitive : false;
247 vbsfRootHandleAdd(i);
248 break;
249 }
250 }
251 if (i == SHFL_MAX_MAPPINGS)
252 {
253 AssertMsgFailed(("vbsfMappingsAdd: no more room to add mapping %ls to %ls!!\n", pFolderName->String.ucs2, pMapName->String.ucs2));
254 return VERR_TOO_MUCH_DATA;
255 }
256
257 Log(("vbsfMappingsAdd: added mapping %ls to %ls\n", pFolderName->String.ucs2, pMapName->String.ucs2));
258 return VINF_SUCCESS;
259}
260
261int vbsfMappingsRemove (PSHFLSTRING pMapName)
262{
263 unsigned i;
264
265 Assert(pMapName);
266
267 Log(("vbsfMappingsRemove %ls\n", pMapName->String.ucs2));
268 for (i=0; i<SHFL_MAX_MAPPINGS; i++)
269 {
270 if (FolderMapping[i].fValid == true)
271 {
272 if (!RTUtf16LocaleICmp(FolderMapping[i].pMapName->String.ucs2, pMapName->String.ucs2))
273 {
274 if (FolderMapping[i].cMappings != 0)
275 {
276 Log(("vbsfMappingsRemove: trying to remove active share %ls\n", pMapName->String.ucs2));
277 return VERR_PERMISSION_DENIED;
278 }
279
280 RTMemFree(FolderMapping[i].pFolderName);
281 RTMemFree(FolderMapping[i].pMapName);
282 FolderMapping[i].pFolderName = NULL;
283 FolderMapping[i].pMapName = NULL;
284 FolderMapping[i].fValid = false;
285 vbsfRootHandleRemove(i);
286 break;
287 }
288 }
289 }
290
291 if (i == SHFL_MAX_MAPPINGS)
292 {
293 AssertMsgFailed(("vbsfMappingsRemove: mapping %ls not found!!!!\n", pMapName->String.ucs2));
294 return VERR_FILE_NOT_FOUND;
295 }
296 Log(("vbsfMappingsRemove: mapping %ls removed\n", pMapName->String.ucs2));
297 return VINF_SUCCESS;
298}
299
300PCRTUTF16 vbsfMappingsQueryHostRoot (SHFLROOT root, uint32_t *pcbRoot)
301{
302 MAPPING *pFolderMapping = vbsfMappingGetByRoot(root);
303 if (pFolderMapping == NULL)
304 {
305 AssertFailed();
306 return NULL;
307 }
308
309 *pcbRoot = pFolderMapping->pFolderName->u16Size;
310 return &pFolderMapping->pFolderName->String.ucs2[0];
311}
312
313bool vbsfIsGuestMappingCaseSensitive (SHFLROOT root)
314{
315 MAPPING *pFolderMapping = vbsfMappingGetByRoot(root);
316 if (pFolderMapping == NULL)
317 {
318 AssertFailed();
319 return false;
320 }
321
322 return pFolderMapping->fGuestCaseSensitive;
323}
324
325bool vbsfIsHostMappingCaseSensitive (SHFLROOT root)
326{
327 MAPPING *pFolderMapping = vbsfMappingGetByRoot(root);
328 if (pFolderMapping == NULL)
329 {
330 AssertFailed();
331 return false;
332 }
333
334 return pFolderMapping->fHostCaseSensitive;
335}
336
337int vbsfMappingsQuery (SHFLCLIENTDATA *pClient, SHFLMAPPING *pMappings, uint32_t *pcMappings)
338{
339 int rc = VINF_SUCCESS;
340 uint32_t cMaxMappings = RT_MIN(*pcMappings, SHFL_MAX_MAPPINGS);
341
342 LogFlow(("vbsfMappingsQuery: pClient = %p, pMappings = %p, pcMappings = %p, *pcMappings = %d\n",
343 pClient, pMappings, pcMappings, *pcMappings));
344
345 *pcMappings = 0;
346 for (uint32_t i=0;i<cMaxMappings;i++)
347 {
348 MAPPING *pFolderMapping = vbsfMappingGetByRoot(i);
349 if (pFolderMapping != NULL && pFolderMapping->fValid == true)
350 {
351 pMappings[*pcMappings].u32Status = SHFL_MS_NEW;
352 pMappings[*pcMappings].root = i;
353 *pcMappings = *pcMappings + 1;
354 }
355 }
356
357 LogFlow(("vbsfMappingsQuery: return rc = %Rrc\n", rc));
358
359 return rc;
360}
361
362int vbsfMappingsQueryName (SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLSTRING *pString)
363{
364 int rc = VINF_SUCCESS;
365
366 LogFlow(("vbsfMappingsQuery: pClient = %p, root = %d, *pString = %p\n",
367 pClient, root, pString));
368
369 MAPPING *pFolderMapping = vbsfMappingGetByRoot(root);
370 if (pFolderMapping == NULL)
371 {
372 return VERR_INVALID_PARAMETER;
373 }
374
375 if (BIT_FLAG(pClient->fu32Flags, SHFL_CF_UTF8))
376 {
377 /* not implemented */
378 AssertFailed();
379 return VERR_INVALID_PARAMETER;
380 }
381
382 if (pFolderMapping->fValid == true)
383 {
384 pString->u16Length = pFolderMapping->pMapName->u16Length;
385 memcpy(pString->String.ucs2, pFolderMapping->pMapName->String.ucs2, pString->u16Size);
386 }
387 else
388 rc = VERR_FILE_NOT_FOUND;
389
390 LogFlow(("vbsfMappingsQuery:Name return rc = %Rrc\n", rc));
391
392 return rc;
393}
394
395int vbsfMappingsQueryWritable (SHFLCLIENTDATA *pClient, SHFLROOT root, bool *fWritable)
396{
397 int rc = VINF_SUCCESS;
398
399 LogFlow(("vbsfMappingsQueryWritable: pClient = %p, root = %d\n",
400 pClient, root));
401
402 MAPPING *pFolderMapping = vbsfMappingGetByRoot(root);
403 if (pFolderMapping == NULL)
404 {
405 return VERR_INVALID_PARAMETER;
406 }
407
408 if (pFolderMapping->fValid == true)
409 *fWritable = pFolderMapping->fWritable;
410 else
411 rc = VERR_FILE_NOT_FOUND;
412
413 LogFlow(("vbsfMappingsQuery:Writable return rc = %Rrc\n", rc));
414
415 return rc;
416}
417
418int vbsfMapFolder (SHFLCLIENTDATA *pClient, PSHFLSTRING pszMapName, RTUTF16 delimiter, bool fCaseSensitive, SHFLROOT *pRoot)
419{
420 MAPPING *pFolderMapping = NULL;
421
422 if (BIT_FLAG(pClient->fu32Flags, SHFL_CF_UTF8))
423 {
424 Log(("vbsfMapFolder %s\n", pszMapName->String.utf8));
425 }
426 else
427 {
428 Log(("vbsfMapFolder %ls\n", pszMapName->String.ucs2));
429 }
430
431 if (pClient->PathDelimiter == 0)
432 {
433 pClient->PathDelimiter = delimiter;
434 }
435 else
436 {
437 Assert(delimiter == pClient->PathDelimiter);
438 }
439
440 if (BIT_FLAG(pClient->fu32Flags, SHFL_CF_UTF8))
441 {
442 int rc;
443 PRTUTF16 utf16Name;
444
445 rc = RTStrToUtf16 ((const char *) pszMapName->String.utf8, &utf16Name);
446 if (RT_FAILURE (rc))
447 return rc;
448
449 pFolderMapping = vbsfMappingGetByName(utf16Name, pRoot);
450 RTUtf16Free (utf16Name);
451 }
452 else
453 {
454 pFolderMapping = vbsfMappingGetByName(pszMapName->String.ucs2, pRoot);
455 }
456
457 if (!pFolderMapping)
458 {
459 return VERR_FILE_NOT_FOUND;
460 }
461
462 pFolderMapping->cMappings++;
463 Assert(pFolderMapping->cMappings == 1 || pFolderMapping->fGuestCaseSensitive == fCaseSensitive);
464 pFolderMapping->fGuestCaseSensitive = fCaseSensitive;
465 return VINF_SUCCESS;
466}
467
468int vbsfUnmapFolder (SHFLCLIENTDATA *pClient, SHFLROOT root)
469{
470 int rc = VINF_SUCCESS;
471
472 MAPPING *pFolderMapping = vbsfMappingGetByRoot(root);
473 if (pFolderMapping == NULL)
474 {
475 AssertFailed();
476 return VERR_FILE_NOT_FOUND;
477 }
478
479 Assert(pFolderMapping->fValid == true && pFolderMapping->cMappings > 0);
480 if (pFolderMapping->cMappings > 0)
481 pFolderMapping->cMappings--;
482
483 Log(("vbsfUnmapFolder\n"));
484 return rc;
485}
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