VirtualBox

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

Last change on this file since 7729 was 5999, checked in by vboxsync, 17 years ago

The Giant CDDL Dual-License Header Change.

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