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,