VirtualBox

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

Last change on this file since 30037 was 28800, checked in by vboxsync, 14 years ago

Automated rebranding to Oracle copyright/license strings via filemuncher

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

© 2023 Oracle
ContactPrivacy policyTerms of Use