VirtualBox

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

Last change on this file since 51442 was 38737, checked in by vboxsync, 13 years ago

One more Log redef gone.

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