/** @file * * Testcase for shared folder case conversion */ /* * Copyright (C) 2006-2007 innotek GmbH * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; * you can redistribute it and/or modify it under the terms of the GNU * General Public License as published by the Free Software Foundation, * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE * distribution. VirtualBox OSE is distributed in the hope that it will * be useful, but WITHOUT ANY WARRANTY of any kind. * * If you received this file as part of a commercial VirtualBox * distribution, then only the terms of your commercial VirtualBox * license agreement apply instead of the previous paragraph. */ /******************************************************************************* * Header Files * *******************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #undef Log #define Log(a) printf a #define RTPathQueryInfo rtPathQueryInfo static int iDirList = 0; static int iDirFile = 0; static char *pszDirList[] = { "c:", "c:\\test dir", "c:\\test dir\\SUBDIR", }; static char *pszDirListC[] = { ".", "..", "test dir" }; static char *pszDirListTestdir[] = { ".", "..", "SUBDIR", "a.bat", "aTestJe.bat", "aTestje.bat", "b.bat", "c.bat", "d.bat", "e.bat", "f.bat", "g.bat", "h.bat", "x.bat", "z.bat", }; static char *pszDirListSUBDIR[] = { ".", "..", "a.bat", "aTestJe.bat", "aTestje.bat", "b.bat", "c.bat", "d.bat", "e.bat", "f.bat", "g.bat", "h.bat", "x.bat", "z.bat", }; int rtDirOpenFiltered(PRTDIR *ppDir, const char *pszPath, RTDIRFILTER enmFilter) { if (!strcmp(pszPath, "c:\\*")) iDirList = 1; else if (!strcmp(pszPath, "c:\\test dir\\*")) iDirList = 2; else if (!strcmp(pszPath, "c:\\test dir\\SUBDIR\\*")) iDirList = 3; else AssertFailed(); return VINF_SUCCESS; } int rtDirClose(PRTDIR pDir) { iDirFile = 0; return VINF_SUCCESS; } int rtDirReadEx(PRTDIR pDir, PRTDIRENTRYEX pDirEntry, unsigned *pcbDirEntry, RTFSOBJATTRADD enmAdditionalAttribs) { switch(iDirList) { case 1: if (iDirFile == RT_ELEMENTS(pszDirListC)) return VERR_NO_MORE_FILES; pDirEntry->cbName = strlen(pszDirListC[iDirFile]); strcpy(pDirEntry->szName, pszDirListC[iDirFile++]); break; case 2: if (iDirFile == RT_ELEMENTS(pszDirListTestdir)) return VERR_NO_MORE_FILES; pDirEntry->cbName = strlen(pszDirListTestdir[iDirFile]); strcpy(pDirEntry->szName, pszDirListTestdir[iDirFile++]); break; case 3: if (iDirFile == RT_ELEMENTS(pszDirListSUBDIR)) return VERR_NO_MORE_FILES; pDirEntry->cbName = strlen(pszDirListSUBDIR[iDirFile]); strcpy(pDirEntry->szName, pszDirListSUBDIR[iDirFile++]); break; } return VINF_SUCCESS; } int rtPathQueryInfo(const char *pszPath, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAdditionalAttribs) { int cMax; char **ppszDirList; /* first try pszDirList */ for (int i=0;iszName, pszFullPath); strcat(pDirEntry->szName, "\\*"); rc = rtDirOpenFiltered (&hSearch, pDirEntry->szName, RTDIRFILTER_WINNT); *(pszStartComponent-1) = RTPATH_DELIMITER; if (VBOX_FAILURE(rc)) goto end; for(;;) { uint32_t cbDirEntrySize = cbDirEntry; rc = rtDirReadEx(hSearch, pDirEntry, &cbDirEntrySize, RTFSOBJATTRADD_NOTHING); if (rc == VERR_NO_MORE_FILES) break; if (VINF_SUCCESS != rc && rc != VWRN_NO_DIRENT_INFO) { AssertFailed(); if (rc != VERR_NO_TRANSLATION) break; else continue; } if ( pDirEntry->cbName == cbComponent && !RTStrICmp(pszStartComponent, &pDirEntry->szName[0])) { Log(("Found original name %s (%s)\n", &pDirEntry->szName[0], pszStartComponent)); strcpy(pszStartComponent, &pDirEntry->szName[0]); rc = VINF_SUCCESS; break; } } Assert(VBOX_SUCCESS(rc)); end: if (pDirEntry) RTMemFree(pDirEntry); rtDirClose(hSearch); return rc; } int testCase(char *pszFullPath) { int rc; RTFSOBJINFO info; rc = RTPathQueryInfo(pszFullPath, &info, RTFSOBJATTRADD_NOTHING); if (rc == VERR_FILE_NOT_FOUND || rc == VERR_PATH_NOT_FOUND) { uint32_t len = strlen(pszFullPath); char *src = pszFullPath + len - 1; Log(("Handle case insenstive guest fs on top of host case sensitive fs for %s\n", pszFullPath)); /* Find partial path that's valid */ while(src > pszFullPath) { if (*src == RTPATH_DELIMITER) { *src = 0; rc = RTPathQueryInfo (pszFullPath, &info, RTFSOBJATTRADD_NOTHING); *src = RTPATH_DELIMITER; if (rc == VINF_SUCCESS) { #ifdef DEBUG *src = 0; Log(("Found valid partial path %s\n", pszFullPath)); *src = RTPATH_DELIMITER; #endif break; } } src--; } Assert(*src == RTPATH_DELIMITER && VBOX_SUCCESS(rc)); if ( *src == RTPATH_DELIMITER && VBOX_SUCCESS(rc)) { src++; for(;;) { char *end = src; bool fEndOfString = true; while(*end) { if (*end == RTPATH_DELIMITER) break; end++; } if (*end == RTPATH_DELIMITER) { fEndOfString = false; *end = 0; rc = RTPathQueryInfo(src, &info, RTFSOBJATTRADD_NOTHING); Assert(rc == VINF_SUCCESS || rc == VERR_FILE_NOT_FOUND || rc == VERR_PATH_NOT_FOUND); } else rc = VERR_FILE_NOT_FOUND; if (rc == VERR_FILE_NOT_FOUND || rc == VERR_PATH_NOT_FOUND) { /* path component is invalid; try to correct the casing */ rc = vbsfCorrectCasing(pszFullPath, src); if (VBOX_FAILURE(rc)) break; } if (fEndOfString) break; *end = RTPATH_DELIMITER; src = end + 1; } Assert(rc == VINF_SUCCESS); } else rc = VERR_FILE_NOT_FOUND; } if (VBOX_SUCCESS(rc)) Log(("New valid path %s\n", pszFullPath)); return rc; } int main(int argc, char **argv) { char szTest[128]; strcpy(szTest, "c:\\test Dir\\z.bAt"); testCase(szTest); strcpy(szTest, "c:\\test dir\\z.bAt"); testCase(szTest); strcpy(szTest, "c:\\test dir\\SUBDIR\\z.bAt"); testCase(szTest); strcpy(szTest, "c:\\test dir\\SUBDiR\\atestje.bat"); testCase(szTest); strcpy(szTest, "c:\\TEST dir\\subDiR\\aTestje.baT"); testCase(szTest); return 0; }