Author: weiden
Date: Wed Aug  1 20:20:16 2007
New Revision: 28074
URL: 
http://svn.reactos.org/svn/reactos?rev=28074&view=rev
Log:
Simplify and fix code by using GetFullPathName and GetVolumePathName instead of
re-inventing the wheel once again.
See issue #2041 for more details.
Modified:
    trunk/reactos/base/shell/cmd/dir.c
Modified: trunk/reactos/base/shell/cmd/dir.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/dir.c?rev=2…
==============================================================================
--- trunk/reactos/base/shell/cmd/dir.c (original)
+++ trunk/reactos/base/shell/cmd/dir.c Wed Aug  1 20:20:16 2007
@@ -622,189 +622,6 @@
 /*
- * 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
  *
  * print the header for the dir command
@@ -813,58 +630,30 @@
 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;
+      ErrorMessage(GetLastError(), _T("Failed to build full directory path"));
+      return FALSE;
     }
-  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);
-    }
+
+  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 @@
 {
        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 @@
  */
 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 @@
        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 @@
        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 @@
        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 @@
        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 @@
                                    (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 @@
        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 @@
        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,20 +1820,22 @@
        /* 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]);
        /* <Debug :>
           Uncomment this to show the final state of switch flags*/
@@ -2045,26 +1862,27 @@
        #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,