VirtualBox

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

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

Override path delimiter for linux hosts

File size: 9.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
44#define RTPathQueryInfo rtPathQueryInfo
45
46static int iDirList = 0;
47static int iDirFile = 0;
48
49static char *pszDirList[] =
50{
51"c:",
52"c:\\test dir",
53"c:\\test dir\\SUBDIR",
54};
55
56static char *pszDirListC[] =
57{
58".",
59"..",
60"test dir"
61};
62
63static char *pszDirListTestdir[] =
64{
65".",
66"..",
67"SUBDIR",
68"a.bat",
69"aTestJe.bat",
70"aTestje.bat",
71"b.bat",
72"c.bat",
73"d.bat",
74"e.bat",
75"f.bat",
76"g.bat",
77"h.bat",
78"x.bat",
79"z.bat",
80};
81
82static char *pszDirListSUBDIR[] =
83{
84".",
85"..",
86"a.bat",
87"aTestJe.bat",
88"aTestje.bat",
89"b.bat",
90"c.bat",
91"d.bat",
92"e.bat",
93"f.bat",
94"g.bat",
95"h.bat",
96"x.bat",
97"z.bat",
98};
99
100int rtDirOpenFiltered(PRTDIR *ppDir, const char *pszPath, RTDIRFILTER enmFilter)
101{
102 if (!strcmp(pszPath, "c:\\*"))
103 iDirList = 1;
104 else
105 if (!strcmp(pszPath, "c:\\test dir\\*"))
106 iDirList = 2;
107 else
108 if (!strcmp(pszPath, "c:\\test dir\\SUBDIR\\*"))
109 iDirList = 3;
110 else
111 AssertFailed();
112
113 return VINF_SUCCESS;
114}
115
116int rtDirClose(PRTDIR pDir)
117{
118 iDirFile = 0;
119 return VINF_SUCCESS;
120}
121
122int rtDirReadEx(PRTDIR pDir, PRTDIRENTRYEX pDirEntry, unsigned *pcbDirEntry, RTFSOBJATTRADD enmAdditionalAttribs)
123{
124 switch(iDirList)
125 {
126 case 1:
127 if (iDirFile == RT_ELEMENTS(pszDirListC))
128 return VERR_NO_MORE_FILES;
129 pDirEntry->cbName = strlen(pszDirListC[iDirFile]);
130 strcpy(pDirEntry->szName, pszDirListC[iDirFile++]);
131 break;
132 case 2:
133 if (iDirFile == RT_ELEMENTS(pszDirListTestdir))
134 return VERR_NO_MORE_FILES;
135 pDirEntry->cbName = strlen(pszDirListTestdir[iDirFile]);
136 strcpy(pDirEntry->szName, pszDirListTestdir[iDirFile++]);
137 break;
138 case 3:
139 if (iDirFile == RT_ELEMENTS(pszDirListSUBDIR))
140 return VERR_NO_MORE_FILES;
141 pDirEntry->cbName = strlen(pszDirListSUBDIR[iDirFile]);
142 strcpy(pDirEntry->szName, pszDirListSUBDIR[iDirFile++]);
143 break;
144 }
145 return VINF_SUCCESS;
146}
147
148int rtPathQueryInfo(const char *pszPath, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAdditionalAttribs)
149{
150 int cMax;
151 char **ppszDirList;
152
153 /* first try pszDirList */
154 for (int i=0;i<RT_ELEMENTS(pszDirList);i++)
155 {
156 if(!strcmp(pszPath, pszDirList[i]))
157 return VINF_SUCCESS;
158 }
159
160 switch(iDirList)
161 {
162 case 1:
163 cMax = RT_ELEMENTS(pszDirListC);
164 ppszDirList = pszDirListC;
165 break;
166 case 2:
167 cMax = RT_ELEMENTS(pszDirListTestdir);
168 ppszDirList = pszDirListTestdir;
169 break;
170 case 3:
171 cMax = RT_ELEMENTS(pszDirListSUBDIR);
172 ppszDirList = pszDirListSUBDIR;
173 break;
174 default:
175 return VERR_FILE_NOT_FOUND;
176 }
177 for (int i=0;i<cMax;i++)
178 {
179 if(!strcmp(pszPath, ppszDirList[i]))
180 return VINF_SUCCESS;
181 }
182 return VERR_FILE_NOT_FOUND;
183}
184
185static int vbsfCorrectCasing(char *pszFullPath, char *pszStartComponent)
186{
187 PRTDIRENTRYEX pDirEntry = NULL;
188 uint32_t cbDirEntry, cbComponent;
189 int rc = VERR_FILE_NOT_FOUND;
190 PRTDIR hSearch;
191
192 cbComponent = strlen(pszStartComponent);
193
194 cbDirEntry = 4096;
195 pDirEntry = (PRTDIRENTRYEX)RTMemAlloc(cbDirEntry);
196 if (pDirEntry == 0)
197 {
198 AssertFailed();
199 return VERR_NO_MEMORY;
200 }
201
202 /** @todo this is quite inefficient, especially for directories with many files */
203 Assert(pszFullPath < pszStartComponent-1);
204 Assert(*(pszStartComponent-1) == RTPATH_DELIMITER);
205 *(pszStartComponent-1) = 0;
206 strcpy(pDirEntry->szName, pszFullPath);
207 strcat(pDirEntry->szName, "\\*");
208 rc = RTDirOpenFiltered (&hSearch, pDirEntry->szName, RTDIRFILTER_WINNT);
209 *(pszStartComponent-1) = RTPATH_DELIMITER;
210 if (VBOX_FAILURE(rc))
211 goto end;
212
213 for(;;)
214 {
215 uint32_t cbDirEntrySize = cbDirEntry;
216
217 rc = RTDirReadEx(hSearch, pDirEntry, &cbDirEntrySize, RTFSOBJATTRADD_NOTHING);
218 if (rc == VERR_NO_MORE_FILES)
219 break;
220
221 if (VINF_SUCCESS != rc && rc != VWRN_NO_DIRENT_INFO)
222 {
223 AssertFailed();
224 if (rc != VERR_NO_TRANSLATION)
225 break;
226 else
227 continue;
228 }
229 if ( pDirEntry->cbName == cbComponent
230 && !RTStrICmp(pszStartComponent, &pDirEntry->szName[0]))
231 {
232 Log(("Found original name %s (%s)\n", &pDirEntry->szName[0], pszStartComponent));
233 strcpy(pszStartComponent, &pDirEntry->szName[0]);
234 rc = VINF_SUCCESS;
235 break;
236 }
237 }
238 Assert(VBOX_SUCCESS(rc));
239
240end:
241 if (pDirEntry)
242 RTMemFree(pDirEntry);
243
244 RTDirClose(hSearch);
245 return rc;
246}
247
248
249
250int testCase(char *pszFullPath)
251{
252 int rc;
253 RTFSOBJINFO info;
254 rc = RTPathQueryInfo(pszFullPath, &info, RTFSOBJATTRADD_NOTHING);
255 if (rc == VERR_FILE_NOT_FOUND || rc == VERR_PATH_NOT_FOUND)
256 {
257 uint32_t len = strlen(pszFullPath);
258 char *src = pszFullPath + len - 1;
259
260 Log(("Handle case insenstive guest fs on top of host case sensitive fs for %s\n", pszFullPath));
261
262 /* Find partial path that's valid */
263 while(src > pszFullPath)
264 {
265 if (*src == RTPATH_DELIMITER)
266 {
267 *src = 0;
268 rc = RTPathQueryInfo (pszFullPath, &info, RTFSOBJATTRADD_NOTHING);
269 *src = RTPATH_DELIMITER;
270 if (rc == VINF_SUCCESS)
271 {
272#ifdef DEBUG
273 *src = 0;
274 Log(("Found valid partial path %s\n", pszFullPath));
275 *src = RTPATH_DELIMITER;
276#endif
277 break;
278 }
279 }
280
281 src--;
282 }
283 Assert(*src == RTPATH_DELIMITER && VBOX_SUCCESS(rc));
284 if ( *src == RTPATH_DELIMITER
285 && VBOX_SUCCESS(rc))
286 {
287 src++;
288 for(;;)
289 {
290 char *end = src;
291 bool fEndOfString = true;
292
293 while(*end)
294 {
295 if (*end == RTPATH_DELIMITER)
296 break;
297 end++;
298 }
299
300 if (*end == RTPATH_DELIMITER)
301 {
302 fEndOfString = false;
303 *end = 0;
304 rc = RTPathQueryInfo(src, &info, RTFSOBJATTRADD_NOTHING);
305 Assert(rc == VINF_SUCCESS || rc == VERR_FILE_NOT_FOUND || rc == VERR_PATH_NOT_FOUND);
306 }
307 else
308 rc = VERR_FILE_NOT_FOUND;
309
310 if (rc == VERR_FILE_NOT_FOUND || rc == VERR_PATH_NOT_FOUND)
311 {
312 /* path component is invalid; try to correct the casing */
313 rc = vbsfCorrectCasing(pszFullPath, src);
314 if (VBOX_FAILURE(rc))
315 break;
316 }
317
318 if (fEndOfString)
319 break;
320
321 *end = RTPATH_DELIMITER;
322 src = end + 1;
323 }
324 Assert(rc == VINF_SUCCESS);
325 }
326 else
327 rc = VERR_FILE_NOT_FOUND;
328
329 }
330
331 if (VBOX_SUCCESS(rc))
332 Log(("New valid path %s\n", pszFullPath));
333 return rc;
334}
335
336
337int main(int argc, char **argv)
338{
339 char szTest[128];
340
341 strcpy(szTest, "c:\\test Dir\\z.bAt");
342 testCase(szTest);
343 strcpy(szTest, "c:\\test dir\\z.bAt");
344 testCase(szTest);
345 strcpy(szTest, "c:\\test dir\\SUBDIR\\z.bAt");
346 testCase(szTest);
347 strcpy(szTest, "c:\\test dir\\SUBDiR\\atestje.bat");
348 testCase(szTest);
349 strcpy(szTest, "c:\\TEST dir\\subDiR\\aTestje.baT");
350 testCase(szTest);
351 return 0;
352}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette