From 1f6dec06f404c92d677c12e94b4dfe60538f891e Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Wed, 1 Aug 2007 16:20:16 +0000 Subject: [PATCH] Simplify and fix code by using GetFullPathName and GetVolumePathName instead of re-inventing the wheel once again. See issue #2041 for more details. svn path=/trunk/; revision=28074 --- reactos/base/shell/cmd/dir.c | 320 ++++++++--------------------------- 1 file changed, 69 insertions(+), 251 deletions(-) diff --git a/reactos/base/shell/cmd/dir.c b/reactos/base/shell/cmd/dir.c index 491d11778a7..c1529beb4b4 100644 --- a/reactos/base/shell/cmd/dir.c +++ b/reactos/base/shell/cmd/dir.c @@ -621,189 +621,6 @@ DirReadParam(LPTSTR Line, /* [IN] The line with the parameters & switches */ } -/* - * ExtendFilespec - * - * extend the filespec, possibly adding wildcards - */ -static VOID -ExtendFilespec (LPTSTR file) -{ - INT len = 0; - - if (!file) - return; - - - /* if no file spec, change to "*.*" */ - if (*file == _T('\0')) - { - _tcscpy (file, _T("*.*")); - return; - } - - // add support for *. - if ((file[0] == _T('*')) && (file[1] == _T('.') )) - { - return; - } - - /* if starts with . add * in front */ - if (*file == _T('.')) - { - memmove (&file[1], &file[0], (_tcslen (file) + 1) * sizeof(TCHAR)); - file[0] = _T('*'); - } - - /* if no . add .* */ - if (!_tcschr (file, _T('.'))) - { - _tcscat (file, _T(".*")); - return; - } - - - - /* if last character is '.' add '*' */ - len = _tcslen (file); - if (file[len - 1] == _T('.')) - { - _tcscat (file, _T("*")); - return; - } -} - - -/* - * dir_parse_pathspec - * - * split the pathspec into drive, directory, and filespec - */ -static INT -DirParsePathspec (LPTSTR szPathspec, LPTSTR szPath, LPTSTR szFilespec) -{ - TCHAR szOrigPath[MAX_PATH]; - LPTSTR start; - LPTSTR tmp; - INT i; - BOOL bWildcards = FALSE; - - GetCurrentDirectory (MAX_PATH, szOrigPath); - - /* get the drive and change to it */ - if (szPathspec[1] == _T(':')) - { - TCHAR szRootPath[] = _T("A:"); - - szRootPath[0] = szPathspec[0]; - start = szPathspec + 2; - if (!SetCurrentDirectory (szRootPath)) - { - ErrorMessage (GetLastError(), NULL); - return 1; - } - } - else - { - start = szPathspec; - } - - - /* check for wildcards */ - for (i = 0; szPathspec[i]; i++) - { - if (szPathspec[i] == _T('*') || szPathspec[i] == _T('?')) - bWildcards = TRUE; - } - - /* check if this spec is a directory */ - if (!bWildcards) - { - if (SetCurrentDirectory (szPathspec)) - { - _tcscpy (szFilespec, _T("*.*")); - - if (!GetCurrentDirectory (MAX_PATH, szPath)) - { - szFilespec[0] = _T('\0'); - SetCurrentDirectory (szOrigPath); - error_out_of_memory(); - return 1; - } - - SetCurrentDirectory (szOrigPath); - return 0; - } - } - - /* find the file spec */ - tmp = _tcsrchr (start, _T('\\')); - - /* if no path is specified */ - if (!tmp) - { - _tcscpy (szFilespec, start); - ExtendFilespec (szFilespec); - if (!GetCurrentDirectory (MAX_PATH, szPath)) - { - szFilespec[0] = _T('\0'); - SetCurrentDirectory (szOrigPath); - error_out_of_memory(); - return 1; - } - - SetCurrentDirectory (szOrigPath); - return 0; - } - - /* get the filename */ - _tcscpy (szFilespec, tmp+1); - ExtendFilespec (szFilespec); - - if (tmp == start) - { - /* change to the root directory */ - if (!SetCurrentDirectory (_T("\\"))) - { - szFilespec[0] = _T('\0'); - SetCurrentDirectory (szOrigPath); - error_path_not_found (); - return 1; - } - } - else - { - *tmp = _T('\0'); - - /* change to this directory */ - if (!SetCurrentDirectory (start)) - { - *tmp = _T('\\'); - szFilespec[0] = _T('\0'); - SetCurrentDirectory (szOrigPath); - error_path_not_found (); - return 1; - } - } - - /* get the full name of the directory */ - if (!GetCurrentDirectory (MAX_PATH, szPath)) - { - *tmp = _T('\\'); - szFilespec[0] = _T('\0'); - SetCurrentDirectory (szOrigPath); - error_out_of_memory (); - return 1; - } - - *tmp = _T('\\'); - - SetCurrentDirectory (szOrigPath); - - return 0; -} - - /* * PrintDirectoryHeader * @@ -813,58 +630,30 @@ static BOOL PrintDirectoryHeader(LPTSTR szPath, LPDIRSWITCHFLAGS lpFlags) { TCHAR szMsg[RC_STRING_MAX_SIZE]; + TCHAR szFullDir[MAX_PATH]; TCHAR szRootName[MAX_PATH]; TCHAR szVolName[80]; + LPTSTR pszFilePart; DWORD dwSerialNr; - LPTSTR p; if (lpFlags->bBareFormat) return TRUE; - /* build usable root path */ - if (szPath[1] == _T(':') && szPath[2] == _T('\\')) + if (GetFullPathName(szPath, sizeof(szFullDir) / sizeof(TCHAR), szFullDir, &pszFilePart) == 0) { - /* normal path */ - szRootName[0] = szPath[0]; - szRootName[1] = _T(':'); - szRootName[2] = _T('\\'); - szRootName[3] = 0; - } - else if (szPath[0] == _T('\\') && szPath[1] == _T('\\')) - { - /* UNC path */ - p = _tcschr(&szPath[2], _T('\\')); - if (p == NULL) - { - error_invalid_drive(); - return(FALSE); - } - p = _tcschr(p+1, _T('\\')); - if (p == NULL) - { - _tcscpy(szRootName, szPath); - _tcscat(szRootName, _T("\\")); - } - else - { - *p = 0; - _tcscpy(szRootName, szPath); - _tcscat(szRootName, _T("\\")); - *p = _T('\\'); - } - } - else - { - error_invalid_drive(); - return(FALSE); + ErrorMessage(GetLastError(), _T("Failed to build full directory path")); + return FALSE; } + if (pszFilePart != NULL) + *pszFilePart = _T('\0'); + /* get the media ID of the drive */ - if (!GetVolumeInformation(szRootName, szVolName, 80, &dwSerialNr, + if (!GetVolumePathName(szFullDir, szRootName, sizeof(szRootName) / sizeof(TCHAR)) || + !GetVolumeInformation(szRootName, szVolName, 80, &dwSerialNr, NULL, NULL, NULL, 0)) { - error_invalid_drive(); - return(FALSE); + return(TRUE); } /* print drive info */ @@ -1522,12 +1311,18 @@ DirPrintFiles(LPWIN32_FIND_DATA ptrFiles[], /* [IN] Files' Info */ { TCHAR szMsg[RC_STRING_MAX_SIZE]; TCHAR szTemp[MAX_PATH]; /* A buffer to format the directory header */ + LPTSTR pszFilePart; SIZE_T len; - /* Print directory header */ - _tcscpy(szTemp, szCurPath); - /* We cut the trailing \ of the full path, unless the path is a drive */ + if (GetFullPathName(szCurPath, sizeof(szTemp) / sizeof(TCHAR), szTemp, &pszFilePart) == 0) + { + pszFilePart = NULL; + _tcscpy(szTemp, szCurPath); + } + else if (pszFilePart != NULL) + *pszFilePart = _T('\0'); + len = _tcslen(szTemp); if ((len != 3 || szTemp[len - 2] != _T(':')) && szTemp[len - 1] == _T('\\')) szTemp[len-1] = _T('\0'); @@ -1736,7 +1531,6 @@ QsortFiles(LPWIN32_FIND_DATA ptrArray[], /* [IN/OUT] The array with file info po */ static INT DirList(LPTSTR szPath, /* [IN] The path that dir starts */ - LPTSTR szFilespec, /* [IN] The type of file that we are looking for */ LPDIRSWITCHFLAGS lpFlags) /* [IN] The flags of the listing */ { HANDLE hSearch; /* The handle of the search */ @@ -1746,7 +1540,8 @@ DirList(LPTSTR szPath, /* [IN] The path that dir starts */ PDIRFINDLISTNODE ptrStartNode; /* The pointer to the first node */ PDIRFINDLISTNODE ptrNextNode; /* A pointer used for relatives refernces */ TCHAR szFullPath[MAX_PATH]; /* The full path that we are listing with trailing \ */ -TCHAR szFullFileSpec[MAX_PATH]; /* The full path with file specs that we ll request\ */ +TCHAR szSubPath[MAX_PATH]; +LPTSTR pszFilePart; DWORD dwCount; /* A counter of files found in directory */ DWORD dwCountFiles; /* Counter for files */ DWORD dwCountDirs; /* Counter for directories */ @@ -1761,12 +1556,14 @@ ULARGE_INTEGER u64Temp; /* A temporary counter */ dwCountDirs = 0; u64CountBytes.QuadPart = 0; - /* Create szFullPath and szFullFileSpec */ - _tcscpy (szFullPath, szPath); - if (szFullPath[_tcslen(szFullPath) - 1] != _T('\\')) - _tcscat (szFullPath, _T("\\")); - _tcscpy (szFullFileSpec, szFullPath); - _tcscat (szFullFileSpec, szFilespec); + /* Create szFullPath */ + if (GetFullPathName(szPath, sizeof(szFullPath) / sizeof(TCHAR), szFullPath, &pszFilePart) == 0) + { + _tcscpy (szFullPath, szPath); + if (szFullPath[_tcslen(szFullPath) - 1] != _T('\\')) + _tcscat (szFullPath, _T("\\")); + pszFilePart = NULL; + } /* Prepare the linked list, first node is allocated */ ptrStartNode = cmd_alloc(sizeof(DIRFINDLISTNODE)); @@ -1780,7 +1577,7 @@ ULARGE_INTEGER u64Temp; /* A temporary counter */ ptrNextNode = ptrStartNode; /* Collect the results for the current folder */ - hSearch = FindFirstFile(szFullFileSpec, &wfdFileInfo); + hSearch = FindFirstFile(szFullPath, &wfdFileInfo); do { if (hSearch != INVALID_HANDLE_VALUE) @@ -1902,9 +1699,17 @@ ULARGE_INTEGER u64Temp; /* A temporary counter */ if (lpFlags->bRecursive) { /* The new search is involving any *.* file */ - _tcscpy(szFullFileSpec, szFullPath); - _tcscat(szFullFileSpec, _T("*.*")); - hRecSearch = FindFirstFile (szFullFileSpec, &wfdFileInfo); + if (pszFilePart != NULL) + { + memcpy(szSubPath, szFullPath, (pszFilePart - szFullPath) * sizeof(TCHAR)); + szSubPath[pszFilePart - szFullPath] = _T('\0'); + } + else + _tcscpy(szSubPath, szFullPath); + + _tcscat(szSubPath, _T("*.*")); + + hRecSearch = FindFirstFile (szSubPath, &wfdFileInfo); do { if (hRecSearch != INVALID_HANDLE_VALUE) @@ -1915,10 +1720,21 @@ ULARGE_INTEGER u64Temp; /* A temporary counter */ (wfdFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { /* Concat the path and the directory to do recursive */ - _tcscpy(szFullFileSpec, szFullPath); - _tcscat(szFullFileSpec, wfdFileInfo.cFileName); - /* We do the same for tha folder */ - if (DirList(szFullFileSpec, szFilespec, lpFlags) != 0) + if (pszFilePart != NULL) + { + memcpy(szSubPath, szFullPath, (pszFilePart - szFullPath) * sizeof(TCHAR)); + szSubPath[pszFilePart - szFullPath] = _T('\0'); + } + else + _tcscpy(szSubPath, szFullPath); + + _tcscat(szSubPath, wfdFileInfo.cFileName); + _tcscat(szSubPath, _T("\\")); + if (pszFilePart != NULL) + _tcscat(szSubPath, pszFilePart); + + /* We do the same for the folder */ + if (DirList(szSubPath, lpFlags) != 0) { return 1; } @@ -1953,7 +1769,6 @@ CommandDir(LPTSTR first, LPTSTR rest) TCHAR dircmd[256]; /* A variable to store the DIRCMD enviroment variable */ TCHAR cDrive; TCHAR szPath[MAX_PATH]; - TCHAR szFilespec[MAX_PATH]; LPTSTR* params = NULL; INT entries = 0; UINT loop = 0; @@ -1987,7 +1802,7 @@ CommandDir(LPTSTR first, LPTSTR rest) stFlags.stOrderBy.bUnSet = FALSE; nErrorLevel = 0; - + /* read the parameters from the DIRCMD environment variable */ if (GetEnvironmentVariable (_T("DIRCMD"), dircmd, 256)) if (!DirReadParam(dircmd, ¶ms, &entries, &stFlags)) @@ -2005,21 +1820,23 @@ CommandDir(LPTSTR first, LPTSTR rest) /* default to current directory */ if(entries == 0) { - if(!add_entry(&entries, ¶ms, _T("."))) { + if(!add_entry(&entries, ¶ms, _T("*"))) { nErrorLevel = 1; goto cleanup; } } + szPath[0] = _T('\0'); for(loop = 0; loop < entries; loop++) { - /* parse the directory info */ - if (DirParsePathspec (params[loop], szPath, szFilespec) || CheckCtrlBreak(BREAK_INPUT)) + if (CheckCtrlBreak(BREAK_INPUT)) { nErrorLevel = 1; goto cleanup; } + _tcscpy(szPath, params[loop]); + /* Uncomment this to show the final state of switch flags*/ #ifdef _DEBUG @@ -2045,26 +1862,27 @@ CommandDir(LPTSTR first, LPTSTR rest) #endif /* Print the drive header if the drive changed */ - if(cDrive != szPath[0] && !stFlags.bBareFormat) { - if (!PrintDirectoryHeader (szPath, &stFlags)) { + if(cDrive != params[loop][0] && !stFlags.bBareFormat) { + if (!PrintDirectoryHeader (params[loop], &stFlags)) { nErrorLevel = 1; goto cleanup; } - cDrive = szPath[0]; + cDrive = params[loop][0]; } /* do the actual dir */ - if (DirList (szPath, szFilespec, &stFlags)) + if (DirList (params[loop], &stFlags)) { nErrorLevel = 1; goto cleanup; } + } /* print the footer */ - PrintSummary(szPath, + PrintSummary(szPath, // FIXME: root of initial dir? recurse_file_cnt, recurse_dir_cnt, recurse_bytes,