VirtualBox

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

Last change on this file since 3993 was 3993, checked in by vboxsync, 18 years ago

Fixed dir search on linux hosts

File size: 11.2 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 as published by the Free Software Foundation,
13 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
14 * distribution. VirtualBox OSE is distributed in the hope that it will
15 * be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * If you received this file as part of a commercial VirtualBox
18 * distribution, then only the terms of your commercial VirtualBox
19 * license agreement apply instead of the previous paragraph.
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 char *pszDirList[] =
55{
56"c:",
57"c:\\test dir",
58"c:\\test dir\\SUBDIR",
59};
60
61static char *pszDirListC[] =
62{
63".",
64"..",
65"test dir"
66};
67
68static 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 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 return VINF_SUCCESS;
119}
120
121int rtDirClose(PRTDIR pDir)
122{
123 iDirFile = 0;
124 return VINF_SUCCESS;
125}
126
127int rtDirReadEx(PRTDIR pDir, PRTDIRENTRYEX pDirEntry, unsigned *pcbDirEntry, RTFSOBJATTRADD enmAdditionalAttribs)
128{
129 switch(iDirList)
130 {
131 case 1:
132 if (iDirFile == RT_ELEMENTS(pszDirListC))
133 return VERR_NO_MORE_FILES;
134 pDirEntry->cbName = strlen(pszDirListC[iDirFile]);
135 strcpy(pDirEntry->szName, pszDirListC[iDirFile++]);
136 break;
137 case 2:
138 if (iDirFile == RT_ELEMENTS(pszDirListTestdir))
139 return VERR_NO_MORE_FILES;
140 pDirEntry->cbName = strlen(pszDirListTestdir[iDirFile]);
141 strcpy(pDirEntry->szName, pszDirListTestdir[iDirFile++]);
142 break;
143 case 3:
144 if (iDirFile == RT_ELEMENTS(pszDirListSUBDIR))
145 return VERR_NO_MORE_FILES;
146 pDirEntry->cbName = strlen(pszDirListSUBDIR[iDirFile]);
147 strcpy(pDirEntry->szName, pszDirListSUBDIR[iDirFile++]);
148 break;
149 }
150 return VINF_SUCCESS;
151}
152
153int rtPathQueryInfo(const char *pszPath, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAdditionalAttribs)
154{
155 int cMax;
156 char **ppszDirList;
157
158 /* first try pszDirList */
159 for (int i=0;i<RT_ELEMENTS(pszDirList);i++)
160 {
161 if(!strcmp(pszPath, pszDirList[i]))
162 return VINF_SUCCESS;
163 }
164
165 switch(iDirList)
166 {
167 case 1:
168 cMax = RT_ELEMENTS(pszDirListC);
169 ppszDirList = pszDirListC;
170 break;
171 case 2:
172 cMax = RT_ELEMENTS(pszDirListTestdir);
173 ppszDirList = pszDirListTestdir;
174 break;
175 case 3:
176 cMax = RT_ELEMENTS(pszDirListSUBDIR);
177 ppszDirList = pszDirListSUBDIR;
178 break;
179 default:
180 return VERR_FILE_NOT_FOUND;
181 }
182 for (int i=0;i<cMax;i++)
183 {
184 if(!strcmp(pszPath, ppszDirList[i]))
185 return VINF_SUCCESS;
186 }
187 return VERR_FILE_NOT_FOUND;
188}
189
190static int vbsfCorrectCasing(char *pszFullPath, char *pszStartComponent)
191{
192 PRTDIRENTRYEX pDirEntry = NULL;
193 uint32_t cbDirEntry, cbComponent;
194 int rc = VERR_FILE_NOT_FOUND;
195 PRTDIR hSearch;
196 char szWildCard[4];
197
198 Log2(("vbsfCorrectCasing: %s %s\n", pszFullPath, pszStartComponent));
199
200 cbComponent = strlen(pszStartComponent);
201
202 cbDirEntry = 4096;
203 pDirEntry = (PRTDIRENTRYEX)RTMemAlloc(cbDirEntry);
204 if (pDirEntry == 0)
205 {
206 AssertFailed();
207 return VERR_NO_MEMORY;
208 }
209
210 /** @todo this is quite inefficient, especially for directories with many files */
211 Assert(pszFullPath < pszStartComponent-1);
212 Assert(*(pszStartComponent-1) == RTPATH_DELIMITER);
213 *(pszStartComponent-1) = 0;
214 strcpy(pDirEntry->szName, pszFullPath);
215 szWildCard[0] = RTPATH_DELIMITER;
216 szWildCard[1] = '*';
217 szWildCard[2] = 0;
218 strcat(pDirEntry->szName, szWildCard);
219
220 rc = RTDirOpenFiltered (&hSearch, pDirEntry->szName, RTDIRFILTER_WINNT);
221 *(pszStartComponent-1) = RTPATH_DELIMITER;
222 if (VBOX_FAILURE(rc))
223 goto end;
224
225 for(;;)
226 {
227 uint32_t cbDirEntrySize = cbDirEntry;
228
229 rc = RTDirReadEx(hSearch, pDirEntry, &cbDirEntrySize, RTFSOBJATTRADD_NOTHING);
230 if (rc == VERR_NO_MORE_FILES)
231 break;
232
233 if (VINF_SUCCESS != rc && rc != VWRN_NO_DIRENT_INFO)
234 {
235 AssertFailed();
236 if (rc != VERR_NO_TRANSLATION)
237 break;
238 else
239 continue;
240 }
241
242 Log2(("vbsfCorrectCasing: found %s\n", &pDirEntry->szName[0]));
243 if ( pDirEntry->cbName == cbComponent
244 && !RTStrICmp(pszStartComponent, &pDirEntry->szName[0]))
245 {
246 Log(("Found original name %s (%s)\n", &pDirEntry->szName[0], pszStartComponent));
247 strcpy(pszStartComponent, &pDirEntry->szName[0]);
248 rc = VINF_SUCCESS;
249 break;
250 }
251 }
252 if (VBOX_FAILURE(rc))
253 Log(("vbsfCorrectCasing %s failed with %d\n", pszStartComponent, rc));
254
255end:
256 if (pDirEntry)
257 RTMemFree(pDirEntry);
258
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 uint32_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 uint32_t len = strlen(pszFullPath);
312 char *src = pszFullPath + len - 1;
313
314 Log(("Handle case insenstive 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 && VBOX_SUCCESS(rc));
338 if ( *src == RTPATH_DELIMITER
339 && VBOX_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 (VBOX_FAILURE(rc))
372 break;
373 }
374
375 if (fEndOfString)
376 break;
377
378 *end = RTPATH_DELIMITER;
379 src = end + 1;
380 }
381 if (VBOX_FAILURE(rc))
382 Log(("Unable to find suitable component rc=%d\n", rc));
383 }
384 else
385 rc = VERR_FILE_NOT_FOUND;
386
387 }
388 if (pszWildCardComponent)
389 *pszWildCardComponent = RTPATH_DELIMITER;
390
391 if (VBOX_SUCCESS(rc))
392 Log(("New valid path %s\n", pszFullPath));
393 return rc;
394}
395
396
397int main(int argc, char **argv)
398{
399 char szTest[128];
400
401 strcpy(szTest, "c:\\test Dir\\z.bAt");
402 testCase(szTest);
403 strcpy(szTest, "c:\\test dir\\z.bAt");
404 testCase(szTest);
405 strcpy(szTest, "c:\\test dir\\SUBDIR\\z.bAt");
406 testCase(szTest);
407 strcpy(szTest, "c:\\test dir\\SUBDiR\\atestje.bat");
408 testCase(szTest);
409 strcpy(szTest, "c:\\TEST dir\\subDiR\\aTestje.baT");
410 testCase(szTest);
411 strcpy(szTest, "c:\\TEST dir\\subDiR\\*");
412 testCase(szTest, true);
413 strcpy(szTest, "c:\\TEST dir\\subDiR\\");
414 testCase(szTest ,true);
415 strcpy(szTest, "c:\\test dir\\SUBDIR\\");
416 testCase(szTest);
417 return 0;
418}
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