VirtualBox

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

Last change on this file since 34562 was 33595, checked in by vboxsync, 14 years ago

src/*: more spelling fixes (logging), thanks Timeless!

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 11.1 KB
Line 
1/** @file
2 *
3 * Testcase for shared folder case conversion
4 */
5
6/*
7 * Copyright (C) 2006-2007 Oracle Corporation
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, size_t *pcbDirEntry, RTFSOBJATTRADD enmAdditionalAttribs, uint32_t fFlags)
125{
126 NOREF(fFlags);
127 switch(iDirList)
128 {
129 case 1:
130 if (iDirFile == RT_ELEMENTS(pszDirListC))
131 return VERR_NO_MORE_FILES;
132 pDirEntry->cbName = (uint16_t)strlen(pszDirListC[iDirFile]);
133 strcpy(pDirEntry->szName, pszDirListC[iDirFile++]);
134 break;
135 case 2:
136 if (iDirFile == RT_ELEMENTS(pszDirListTestdir))
137 return VERR_NO_MORE_FILES;
138 pDirEntry->cbName = (uint16_t)strlen(pszDirListTestdir[iDirFile]);
139 strcpy(pDirEntry->szName, pszDirListTestdir[iDirFile++]);
140 break;
141 case 3:
142 if (iDirFile == RT_ELEMENTS(pszDirListSUBDIR))
143 return VERR_NO_MORE_FILES;
144 pDirEntry->cbName = (uint16_t)strlen(pszDirListSUBDIR[iDirFile]);
145 strcpy(pDirEntry->szName, pszDirListSUBDIR[iDirFile++]);
146 break;
147 }
148 return VINF_SUCCESS;
149}
150
151int rtPathQueryInfo(const char *pszPath, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAdditionalAttribs)
152{
153 int cMax;
154 const char **ppszDirList;
155
156 /* first try pszDirList */
157 for (unsigned int i=0;i<RT_ELEMENTS(pszDirList);i++)
158 {
159 if(!strcmp(pszPath, pszDirList[i]))
160 return VINF_SUCCESS;
161 }
162
163 switch(iDirList)
164 {
165 case 1:
166 cMax = RT_ELEMENTS(pszDirListC);
167 ppszDirList = pszDirListC;
168 break;
169 case 2:
170 cMax = RT_ELEMENTS(pszDirListTestdir);
171 ppszDirList = pszDirListTestdir;
172 break;
173 case 3:
174 cMax = RT_ELEMENTS(pszDirListSUBDIR);
175 ppszDirList = pszDirListSUBDIR;
176 break;
177 default:
178 return VERR_FILE_NOT_FOUND;
179 }
180 for (int i=0;i<cMax;i++)
181 {
182 if(!strcmp(pszPath, ppszDirList[i]))
183 return VINF_SUCCESS;
184 }
185 return VERR_FILE_NOT_FOUND;
186}
187
188static int vbsfCorrectCasing(char *pszFullPath, char *pszStartComponent)
189{
190 PRTDIRENTRYEX pDirEntry = NULL;
191 uint32_t cbDirEntry;
192 size_t cbComponent;
193 int rc = VERR_FILE_NOT_FOUND;
194 PRTDIR hSearch = 0;
195 char szWildCard[4];
196
197 Log2(("vbsfCorrectCasing: %s %s\n", pszFullPath, pszStartComponent));
198
199 cbComponent = strlen(pszStartComponent);
200
201 cbDirEntry = 4096;
202 pDirEntry = (PRTDIRENTRYEX)RTMemAlloc(cbDirEntry);
203 if (pDirEntry == 0)
204 {
205 AssertFailed();
206 return VERR_NO_MEMORY;
207 }
208
209 /** @todo this is quite inefficient, especially for directories with many files */
210 Assert(pszFullPath < pszStartComponent-1);
211 Assert(*(pszStartComponent-1) == RTPATH_DELIMITER);
212 *(pszStartComponent-1) = 0;
213 strcpy(pDirEntry->szName, pszFullPath);
214 szWildCard[0] = RTPATH_DELIMITER;
215 szWildCard[1] = '*';
216 szWildCard[2] = 0;
217 strcat(pDirEntry->szName, szWildCard);
218
219 rc = RTDirOpenFiltered (&hSearch, pDirEntry->szName, RTDIRFILTER_WINNT);
220 *(pszStartComponent-1) = RTPATH_DELIMITER;
221 if (RT_FAILURE(rc))
222 goto end;
223
224 for(;;)
225 {
226 size_t cbDirEntrySize = cbDirEntry;
227
228 rc = RTDirReadEx(hSearch, pDirEntry, &cbDirEntrySize, RTFSOBJATTRADD_NOTHING, RTPATH_F_FOLLOW_LINK);
229 if (rc == VERR_NO_MORE_FILES)
230 break;
231
232 if (VINF_SUCCESS != rc && rc != VWRN_NO_DIRENT_INFO)
233 {
234 AssertFailed();
235 if (rc != VERR_NO_TRANSLATION)
236 break;
237 else
238 continue;
239 }
240
241 Log2(("vbsfCorrectCasing: found %s\n", &pDirEntry->szName[0]));
242 if ( pDirEntry->cbName == cbComponent
243 && !RTStrICmp(pszStartComponent, &pDirEntry->szName[0]))
244 {
245 Log(("Found original name %s (%s)\n", &pDirEntry->szName[0], pszStartComponent));
246 strcpy(pszStartComponent, &pDirEntry->szName[0]);
247 rc = VINF_SUCCESS;
248 break;
249 }
250 }
251 if (RT_FAILURE(rc))
252 Log(("vbsfCorrectCasing %s failed with %d\n", pszStartComponent, rc));
253
254end:
255 if (pDirEntry)
256 RTMemFree(pDirEntry);
257
258 if (hSearch)
259 RTDirClose(hSearch);
260 return rc;
261}
262
263
264
265int testCase(char *pszFullPath, bool fWildCard = false)
266{
267 int rc;
268 RTFSOBJINFO info;
269 char *pszWildCardComponent = NULL;
270
271 if (fWildCard)
272 {
273 /* strip off the last path component, that contains the wildcard(s) */
274 size_t len = strlen(pszFullPath);
275 char *src = pszFullPath + len - 1;
276
277 while(src > pszFullPath)
278 {
279 if (*src == RTPATH_DELIMITER)
280 break;
281 src--;
282 }
283 if (*src == RTPATH_DELIMITER)
284 {
285 bool fHaveWildcards = false;
286 char *temp = src;
287
288 while(*temp)
289 {
290 char uc = *temp;
291 /** @todo should depend on the guest OS */
292 if (uc == '*' || uc == '?' || uc == '>' || uc == '<' || uc == '"')
293 {
294 fHaveWildcards = true;
295 break;
296 }
297 temp++;
298 }
299
300 if (fHaveWildcards)
301 {
302 pszWildCardComponent = src;
303 *pszWildCardComponent = 0;
304 }
305 }
306 }
307
308 rc = RTPathQueryInfo(pszFullPath, &info, RTFSOBJATTRADD_NOTHING);
309 if (rc == VERR_FILE_NOT_FOUND || rc == VERR_PATH_NOT_FOUND)
310 {
311 size_t len = strlen(pszFullPath);
312 char *src = pszFullPath + len - 1;
313
314 Log(("Handle case insensitive guest fs on top of host case sensitive fs for %s\n", pszFullPath));
315
316 /* Find partial path that's valid */
317 while(src > pszFullPath)
318 {
319 if (*src == RTPATH_DELIMITER)
320 {
321 *src = 0;
322 rc = RTPathQueryInfo (pszFullPath, &info, RTFSOBJATTRADD_NOTHING);
323 *src = RTPATH_DELIMITER;
324 if (rc == VINF_SUCCESS)
325 {
326#ifdef DEBUG
327 *src = 0;
328 Log(("Found valid partial path %s\n", pszFullPath));
329 *src = RTPATH_DELIMITER;
330#endif
331 break;
332 }
333 }
334
335 src--;
336 }
337 Assert(*src == RTPATH_DELIMITER && RT_SUCCESS(rc));
338 if ( *src == RTPATH_DELIMITER
339 && RT_SUCCESS(rc))
340 {
341 src++;
342 for(;;)
343 {
344 char *end = src;
345 bool fEndOfString = true;
346
347 while(*end)
348 {
349 if (*end == RTPATH_DELIMITER)
350 break;
351 end++;
352 }
353
354 if (*end == RTPATH_DELIMITER)
355 {
356 fEndOfString = false;
357 *end = 0;
358 rc = RTPathQueryInfo(src, &info, RTFSOBJATTRADD_NOTHING);
359 Assert(rc == VINF_SUCCESS || rc == VERR_FILE_NOT_FOUND || rc == VERR_PATH_NOT_FOUND);
360 }
361 else
362 if (end == src)
363 rc = VINF_SUCCESS; /* trailing delimiter */
364 else
365 rc = VERR_FILE_NOT_FOUND;
366
367 if (rc == VERR_FILE_NOT_FOUND || rc == VERR_PATH_NOT_FOUND)
368 {
369 /* path component is invalid; try to correct the casing */
370 rc = vbsfCorrectCasing(pszFullPath, src);
371 if (RT_FAILURE(rc))
372 {
373 if (!fEndOfString)
374 *end = RTPATH_DELIMITER;
375 break;
376 }
377 }
378
379 if (fEndOfString)
380 break;
381
382 *end = RTPATH_DELIMITER;
383 src = end + 1;
384 }
385 if (RT_FAILURE(rc))
386 Log(("Unable to find suitable component rc=%d\n", rc));
387 }
388 else
389 rc = VERR_FILE_NOT_FOUND;
390
391 }
392 if (pszWildCardComponent)
393 *pszWildCardComponent = RTPATH_DELIMITER;
394
395 if (RT_SUCCESS(rc))
396 Log(("New valid path %s\n", pszFullPath));
397 else
398 Log(("Old invalid path %s\n", pszFullPath));
399 return rc;
400}
401
402
403int main(int argc, char **argv)
404{
405 char szTest[128];
406
407 strcpy(szTest, "c:\\test Dir\\z.bAt");
408 testCase(szTest);
409 strcpy(szTest, "c:\\test dir\\z.bAt");
410 testCase(szTest);
411 strcpy(szTest, "c:\\test dir\\SUBDIR\\z.bAt");
412 testCase(szTest);
413 strcpy(szTest, "c:\\test dir\\SUBDiR\\atestje.bat");
414 testCase(szTest);
415 strcpy(szTest, "c:\\TEST dir\\subDiR\\aTestje.baT");
416 testCase(szTest);
417 strcpy(szTest, "c:\\TEST dir\\subDiR\\*");
418 testCase(szTest, true);
419 strcpy(szTest, "c:\\TEST dir\\subDiR\\");
420 testCase(szTest ,true);
421 strcpy(szTest, "c:\\test dir\\SUBDIR\\");
422 testCase(szTest);
423 strcpy(szTest, "c:\\test dir\\invalid\\SUBDIR\\test.bat");
424 testCase(szTest);
425 return 0;
426}
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