VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedFolders/testcase/tstShflCase.cpp@ 11938

Last change on this file since 11938 was 8155, checked in by vboxsync, 17 years ago

The Big Sun Rebranding Header Change

  • Property svn:eol-style set to native
File size: 11.2 KB
Line 
1/** @file
2 *
3 * Testcase for shared folder case conversion
4 */
5
6/*
7 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22/*******************************************************************************
23* Header Files *
24*******************************************************************************/
25#include <VBox/shflsvc.h>
26#include <iprt/stream.h>
27#include <iprt/alloc.h>
28#include <iprt/assert.h>
29#include <iprt/fs.h>
30#include <iprt/dir.h>
31#include <iprt/file.h>
32#include <iprt/path.h>
33#include <iprt/string.h>
34#include <iprt/uni.h>
35#include <stdio.h>
36
37/* override for linux host */
38#undef RTPATH_DELIMITER
39#define RTPATH_DELIMITER '\\'
40
41#undef Log
42#define Log(a) printf a
43#undef Log2
44#define Log2 Log
45
46#define RTPathQueryInfo rtPathQueryInfo
47#define RTDirOpenFiltered rtDirOpenFiltered
48#define RTDirClose rtDirClose
49#define RTDirReadEx rtDirReadEx
50
51static int iDirList = 0;
52static int iDirFile = 0;
53
54static const char *pszDirList[] =
55{
56"c:",
57"c:\\test dir",
58"c:\\test dir\\SUBDIR",
59};
60
61static const char *pszDirListC[] =
62{
63".",
64"..",
65"test dir"
66};
67
68static const char *pszDirListTestdir[] =
69{
70".",
71"..",
72"SUBDIR",
73"a.bat",
74"aTestJe.bat",
75"aTestje.bat",
76"b.bat",
77"c.bat",
78"d.bat",
79"e.bat",
80"f.bat",
81"g.bat",
82"h.bat",
83"x.bat",
84"z.bat",
85};
86
87static const char *pszDirListSUBDIR[] =
88{
89".",
90"..",
91"a.bat",
92"aTestJe.bat",
93"aTestje.bat",
94"b.bat",
95"c.bat",
96"d.bat",
97"e.bat",
98"f.bat",
99"g.bat",
100"h.bat",
101"x.bat",
102"z.bat",
103};
104
105int rtDirOpenFiltered(PRTDIR *ppDir, const char *pszPath, RTDIRFILTER enmFilter)
106{
107 if (!strcmp(pszPath, "c:\\*"))
108 iDirList = 1;
109 else
110 if (!strcmp(pszPath, "c:\\test dir\\*"))
111 iDirList = 2;
112 else
113 if (!strcmp(pszPath, "c:\\test dir\\SUBDIR\\*"))
114 iDirList = 3;
115 else
116 AssertFailed();
117
118 *ppDir = (PRTDIR)1;
119 return VINF_SUCCESS;
120}
121
122int rtDirClose(PRTDIR pDir)
123{
124 iDirFile = 0;
125 return VINF_SUCCESS;
126}
127
128int rtDirReadEx(PRTDIR pDir, PRTDIRENTRYEX pDirEntry, unsigned *pcbDirEntry, RTFSOBJATTRADD enmAdditionalAttribs)
129{
130 switch(iDirList)
131 {
132 case 1:
133 if (iDirFile == RT_ELEMENTS(pszDirListC))
134 return VERR_NO_MORE_FILES;
135 pDirEntry->cbName = strlen(pszDirListC[iDirFile]);
136 strcpy(pDirEntry->szName, pszDirListC[iDirFile++]);
137 break;
138 case 2:
139 if (iDirFile == RT_ELEMENTS(pszDirListTestdir))
140 return VERR_NO_MORE_FILES;
141 pDirEntry->cbName = strlen(pszDirListTestdir[iDirFile]);
142 strcpy(pDirEntry->szName, pszDirListTestdir[iDirFile++]);
143 break;
144 case 3:
145 if (iDirFile == RT_ELEMENTS(pszDirListSUBDIR))
146 return VERR_NO_MORE_FILES;
147 pDirEntry->cbName = strlen(pszDirListSUBDIR[iDirFile]);
148 strcpy(pDirEntry->szName, pszDirListSUBDIR[iDirFile++]);
149 break;
150 }
151 return VINF_SUCCESS;
152}
153
154int rtPathQueryInfo(const char *pszPath, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAdditionalAttribs)
155{
156 int cMax;
157 const char **ppszDirList;
158
159 /* first try pszDirList */
160 for (unsigned int i=0;i<RT_ELEMENTS(pszDirList);i++)
161 {
162 if(!strcmp(pszPath, pszDirList[i]))
163 return VINF_SUCCESS;
164 }
165
166 switch(iDirList)
167 {
168 case 1:
169 cMax = RT_ELEMENTS(pszDirListC);
170 ppszDirList = pszDirListC;
171 break;
172 case 2:
173 cMax = RT_ELEMENTS(pszDirListTestdir);
174 ppszDirList = pszDirListTestdir;
175 break;
176 case 3:
177 cMax = RT_ELEMENTS(pszDirListSUBDIR);
178 ppszDirList = pszDirListSUBDIR;
179 break;
180 default:
181 return VERR_FILE_NOT_FOUND;
182 }
183 for (int i=0;i<cMax;i++)
184 {
185 if(!strcmp(pszPath, ppszDirList[i]))
186 return VINF_SUCCESS;
187 }
188 return VERR_FILE_NOT_FOUND;
189}
190
191static int vbsfCorrectCasing(char *pszFullPath, char *pszStartComponent)
192{
193 PRTDIRENTRYEX pDirEntry = NULL;
194 uint32_t cbDirEntry, cbComponent;
195 int rc = VERR_FILE_NOT_FOUND;
196 PRTDIR hSearch = 0;
197 char szWildCard[4];
198
199 Log2(("vbsfCorrectCasing: %s %s\n", pszFullPath, pszStartComponent));
200
201 cbComponent = strlen(pszStartComponent);
202
203 cbDirEntry = 4096;
204 pDirEntry = (PRTDIRENTRYEX)RTMemAlloc(cbDirEntry);
205 if (pDirEntry == 0)
206 {
207 AssertFailed();
208 return VERR_NO_MEMORY;
209 }
210
211 /** @todo this is quite inefficient, especially for directories with many files */
212 Assert(pszFullPath < pszStartComponent-1);
213 Assert(*(pszStartComponent-1) == RTPATH_DELIMITER);
214 *(pszStartComponent-1) = 0;
215 strcpy(pDirEntry->szName, pszFullPath);
216 szWildCard[0] = RTPATH_DELIMITER;
217 szWildCard[1] = '*';
218 szWildCard[2] = 0;
219 strcat(pDirEntry->szName, szWildCard);
220
221 rc = RTDirOpenFiltered (&hSearch, pDirEntry->szName, RTDIRFILTER_WINNT);
222 *(pszStartComponent-1) = RTPATH_DELIMITER;
223 if (VBOX_FAILURE(rc))
224 goto end;
225
226 for(;;)
227 {
228 uint32_t cbDirEntrySize = cbDirEntry;
229
230 rc = RTDirReadEx(hSearch, pDirEntry, &cbDirEntrySize, RTFSOBJATTRADD_NOTHING);
231 if (rc == VERR_NO_MORE_FILES)
232 break;
233
234 if (VINF_SUCCESS != rc && rc != VWRN_NO_DIRENT_INFO)
235 {
236 AssertFailed();
237 if (rc != VERR_NO_TRANSLATION)
238 break;
239 else
240 continue;
241 }
242
243 Log2(("vbsfCorrectCasing: found %s\n", &pDirEntry->szName[0]));
244 if ( pDirEntry->cbName == cbComponent
245 && !RTStrICmp(pszStartComponent, &pDirEntry->szName[0]))
246 {
247 Log(("Found original name %s (%s)\n", &pDirEntry->szName[0], pszStartComponent));
248 strcpy(pszStartComponent, &pDirEntry->szName[0]);
249 rc = VINF_SUCCESS;
250 break;
251 }
252 }
253 if (VBOX_FAILURE(rc))
254 Log(("vbsfCorrectCasing %s failed with %d\n", pszStartComponent, rc));
255
256end:
257 if (pDirEntry)
258 RTMemFree(pDirEntry);
259
260 if (hSearch)
261 RTDirClose(hSearch);
262 return rc;
263}
264
265
266
267int testCase(char *pszFullPath, bool fWildCard = false)
268{
269 int rc;
270 RTFSOBJINFO info;
271 char *pszWildCardComponent = NULL;
272
273 if (fWildCard)
274 {
275 /* strip off the last path component, that contains the wildcard(s) */
276 uint32_t len = strlen(pszFullPath);
277 char *src = pszFullPath + len - 1;
278
279 while(src > pszFullPath)
280 {
281 if (*src == RTPATH_DELIMITER)
282 break;
283 src--;
284 }
285 if (*src == RTPATH_DELIMITER)
286 {
287 bool fHaveWildcards = false;
288 char *temp = src;
289
290 while(*temp)
291 {
292 char uc = *temp;
293 /** @todo should depend on the guest OS */
294 if (uc == '*' || uc == '?' || uc == '>' || uc == '<' || uc == '"')
295 {
296 fHaveWildcards = true;
297 break;
298 }
299 temp++;
300 }
301
302 if (fHaveWildcards)
303 {
304 pszWildCardComponent = src;
305 *pszWildCardComponent = 0;
306 }
307 }
308 }
309
310 rc = RTPathQueryInfo(pszFullPath, &info, RTFSOBJATTRADD_NOTHING);
311 if (rc == VERR_FILE_NOT_FOUND || rc == VERR_PATH_NOT_FOUND)
312 {
313 uint32_t len = strlen(pszFullPath);
314 char *src = pszFullPath + len - 1;
315
316 Log(("Handle case insenstive guest fs on top of host case sensitive fs for %s\n", pszFullPath));
317
318 /* Find partial path that's valid */
319 while(src > pszFullPath)
320 {
321 if (*src == RTPATH_DELIMITER)
322 {
323 *src = 0;
324 rc = RTPathQueryInfo (pszFullPath, &info, RTFSOBJATTRADD_NOTHING);
325 *src = RTPATH_DELIMITER;
326 if (rc == VINF_SUCCESS)
327 {
328#ifdef DEBUG
329 *src = 0;
330 Log(("Found valid partial path %s\n", pszFullPath));
331 *src = RTPATH_DELIMITER;
332#endif
333 break;
334 }
335 }
336
337 src--;
338 }
339 Assert(*src == RTPATH_DELIMITER && VBOX_SUCCESS(rc));
340 if ( *src == RTPATH_DELIMITER
341 && VBOX_SUCCESS(rc))
342 {
343 src++;
344 for(;;)
345 {
346 char *end = src;
347 bool fEndOfString = true;
348
349 while(*end)
350 {
351 if (*end == RTPATH_DELIMITER)
352 break;
353 end++;
354 }
355
356 if (*end == RTPATH_DELIMITER)
357 {
358 fEndOfString = false;
359 *end = 0;
360 rc = RTPathQueryInfo(src, &info, RTFSOBJATTRADD_NOTHING);
361 Assert(rc == VINF_SUCCESS || rc == VERR_FILE_NOT_FOUND || rc == VERR_PATH_NOT_FOUND);
362 }
363 else
364 if (end == src)
365 rc = VINF_SUCCESS; /* trailing delimiter */
366 else
367 rc = VERR_FILE_NOT_FOUND;
368
369 if (rc == VERR_FILE_NOT_FOUND || rc == VERR_PATH_NOT_FOUND)
370 {
371 /* path component is invalid; try to correct the casing */
372 rc = vbsfCorrectCasing(pszFullPath, src);
373 if (VBOX_FAILURE(rc))
374 {
375 if (!fEndOfString)
376 *end = RTPATH_DELIMITER;
377 break;
378 }
379 }
380
381 if (fEndOfString)
382 break;
383
384 *end = RTPATH_DELIMITER;
385 src = end + 1;
386 }
387 if (VBOX_FAILURE(rc))
388 Log(("Unable to find suitable component rc=%d\n", rc));
389 }
390 else
391 rc = VERR_FILE_NOT_FOUND;
392
393 }
394 if (pszWildCardComponent)
395 *pszWildCardComponent = RTPATH_DELIMITER;
396
397 if (VBOX_SUCCESS(rc))
398 Log(("New valid path %s\n", pszFullPath));
399 else
400 Log(("Old invalid path %s\n", pszFullPath));
401 return rc;
402}
403
404
405int main(int argc, char **argv)
406{
407 char szTest[128];
408
409 strcpy(szTest, "c:\\test Dir\\z.bAt");
410 testCase(szTest);
411 strcpy(szTest, "c:\\test dir\\z.bAt");
412 testCase(szTest);
413 strcpy(szTest, "c:\\test dir\\SUBDIR\\z.bAt");
414 testCase(szTest);
415 strcpy(szTest, "c:\\test dir\\SUBDiR\\atestje.bat");
416 testCase(szTest);
417 strcpy(szTest, "c:\\TEST dir\\subDiR\\aTestje.baT");
418 testCase(szTest);
419 strcpy(szTest, "c:\\TEST dir\\subDiR\\*");
420 testCase(szTest, true);
421 strcpy(szTest, "c:\\TEST dir\\subDiR\\");
422 testCase(szTest ,true);
423 strcpy(szTest, "c:\\test dir\\SUBDIR\\");
424 testCase(szTest);
425 strcpy(szTest, "c:\\test dir\\invalid\\SUBDIR\\test.bat");
426 testCase(szTest);
427 return 0;
428}
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