https://git.reactos.org/?p=reactos.git;a=commitdiff;h=092c3710f2b7e94316eb6…
commit 092c3710f2b7e94316eb6459b4dc3a874219b24c
Author: Jared Smudde <computerwhiz02(a)hotmail.com>
AuthorDate: Tue Aug 7 06:22:03 2018 -0500
Commit: Hermès BÉLUSCA - MAÏTO <hermes.belusca-maito(a)reactos.org>
CommitDate: Tue Aug 7 13:22:03 2018 +0200
[BOOTDATA] Change the default open command for HTA files to open in Wine Internet Explorer. (#719)
It's a shortcut from implementing the function in mshtml but it works.
Also add an edit option to the right click menu.
---
boot/bootdata/hivecls.inf | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/boot/bootdata/hivecls.inf b/boot/bootdata/hivecls.inf
index 61d6f4f318..25b6a471ec 100644
--- a/boot/bootdata/hivecls.inf
+++ b/boot/bootdata/hivecls.inf
@@ -220,7 +220,9 @@ HKCR,"chm.file\shell\open\command","",0x00020000,"%SystemRoot%\hh.exe %1"
HKCR,".hta","",0x00000000,"htafile"
HKCR,"htafile","",0x00000000,"HTML Application"
HKCR,"htafile\DefaultIcon","",0x00020000,"%SystemRoot%\system32\mshta.exe,-1"
-HKCR,"htafile\shell\open\command","",0x00020000,"%SystemRoot%\system32\mshta.exe ""%1"" %*"
+; HKCR,"htafile\shell\open\command","",0x00020000,"%SystemRoot%\system32\mshta.exe ""%1"" %*"
+HKCR,"htafile\shell\edit\command","",0x00020000,"%SystemRoot%\system32\notepad.exe %1"
+HKCR,"htafile\shell\open\command","",0x00020000,"""%ProgramFiles%\Internet Explorer\iexplore.exe"" %1"
; set MIME type for .html and .htm because Tiny webserver needs it
HKCR,".htm","",0x00000000,"htmlfile"
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=23b36fc1730022398cbec…
commit 23b36fc1730022398cbec47f100444c9526e73f0
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Mon Aug 6 22:36:14 2018 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Mon Aug 6 22:40:17 2018 +0200
[CMD] Add speed-optimized checks for dot-directories "." and ".." .
Adapted from PR #592 by Katayama Hirofumi MZ.
---
base/shell/cmd/dir.c | 57 ++++++++++++++++++++++++++++++++--------------------
1 file changed, 35 insertions(+), 22 deletions(-)
diff --git a/base/shell/cmd/dir.c b/base/shell/cmd/dir.c
index 17627b9bae..b59bf6c6c6 100644
--- a/base/shell/cmd/dir.c
+++ b/base/shell/cmd/dir.c
@@ -233,6 +233,28 @@ DirHelp(VOID)
ConOutResPaging(TRUE, STRING_DIR_HELP1);
}
+/* Check whether this is a dot-directory "." or "..", speed-optimized */
+FORCEINLINE
+BOOL
+IsDotDirectory(
+ IN LPCTSTR pszPath)
+{
+ return ( pszPath[0] == _T('.') &&
+ ( pszPath[1] == 0 || /* pszPath[1] == _T('\\') || */
+ (pszPath[1] == _T('.') && (pszPath[2] == 0 /* || pszPath[2] == _T('\\') */))
+ ) );
+}
+
+FORCEINLINE
+BOOL
+IsDotDirectoryN(
+ IN const TCHAR* pPath,
+ IN SIZE_T Length)
+{
+ return ((Length == 1 && pPath[0] == _T('.')) ||
+ (Length == 2 && pPath[0] == _T('.') && pPath[1] == _T('.')));
+}
+
/*
* DirReadParameters
*
@@ -822,11 +844,10 @@ getName(const TCHAR* file, TCHAR * dest)
INT_PTR iLen;
LPTSTR end;
- /* Check for "." and ".." folders */
- if ((_tcscmp(file, _T(".")) == 0) ||
- (_tcscmp(file, _T("..")) == 0))
+ /* Check for dot-directories "." and ".." */
+ if (IsDotDirectory(file))
{
- _tcscpy(dest,file);
+ _tcscpy(dest, file);
return dest;
}
@@ -1087,20 +1108,19 @@ DirPrintBareList(PDIRFINDINFO ptrFiles[], /* [IN] Files' Info */
for (i = 0; i < dwCount && !CheckCtrlBreak(BREAK_INPUT); i++)
{
- if ((_tcscmp(ptrFiles[i]->stFindInfo.cFileName, _T(".")) == 0) ||
- (_tcscmp(ptrFiles[i]->stFindInfo.cFileName, _T("..")) == 0))
+ if (IsDotDirectory(ptrFiles[i]->stFindInfo.cFileName))
{
- /* at bare format we don't print "." and ".." folder */
+ /* At bare format we don't print the dot-directories "." and ".." */
continue;
}
if (lpFlags->bRecursive)
{
- /* at recursive mode we print full path of file */
+ /* At recursive mode we print full path of file */
DirPrintf(lpFlags, _T("%s\\%s\n"), szCurPath, ptrFiles[i]->stFindInfo.cFileName);
}
else
{
- /* if we are not in recursive mode we print the file names */
+ /* If we are not in recursive mode we print the file names */
DirPrintf(lpFlags, _T("%s\n"), ptrFiles[i]->stFindInfo.cFileName);
}
}
@@ -1376,7 +1396,7 @@ DirList(IN OUT LPTSTR szFullPath, /* [IN] The full path we are listing with tr
ptrStartNode->stInfo.ptrHead = NULL;
ptrNextNode = ptrStartNode;
- /* Collect the results for the current folder */
+ /* Collect the results for the current directory */
hSearch = FindFirstFile(szFullPath, &wfdFileInfo);
if (hSearch != INVALID_HANDLE_VALUE)
{
@@ -1561,8 +1581,7 @@ DirList(IN OUT LPTSTR szFullPath, /* [IN] The full path we are listing with tr
do
{
/* We search for directories other than "." and ".." */
- if ((_tcsicmp(wfdFileInfo.cFileName, _T(".")) != 0) &&
- (_tcsicmp(wfdFileInfo.cFileName, _T("..")) != 0) &&
+ if (!IsDotDirectory(wfdFileInfo.cFileName) &&
(wfdFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
/* Concat the path and the directory to do recursive */
@@ -1572,7 +1591,7 @@ DirList(IN OUT LPTSTR szFullPath, /* [IN] The full path we are listing with tr
pszSubFilePart = &szSubPath[_tcslen(szSubPath)];
_tcscat(pszSubFilePart, pszFilePart);
- /* We do the same for the folder */
+ /* We do the same for the directory */
if (DirList(szSubPath, pszSubFilePart, lpFlags) != 0)
{
FindClose(hRecSearch);
@@ -1660,9 +1679,7 @@ ResolvePattern(
break;
/* Ignore the special "." and ".." directories that are correctly handled */
- if ((pNextDir - pCurDir == 0) ||
- (pNextDir - pCurDir == 1 && pCurDir[0] == _T('.')) ||
- (pNextDir - pCurDir == 2 && pCurDir[0] == _T('.') && pCurDir[1] == _T('.')))
+ if ((pNextDir - pCurDir == 0) || IsDotDirectoryN(pCurDir, pNextDir - pCurDir))
{
/* Found such a directory, ignore */
++pNextDir;
@@ -1758,9 +1775,7 @@ ResolvePattern(
ASSERT(pszFullPath[_tcslen(pszFullPath)-1] == _T('\\'));
/* Anything NOT being "." or ".." (the special directories) must be fully restored */
- if (*pNextDir &&
- (_tcsicmp(pNextDir, _T(".")) != 0) &&
- (_tcsicmp(pNextDir, _T("..")) != 0))
+ if (*pNextDir && !IsDotDirectory(pNextDir))
{
pszPatternPart = &pszFullPath[_tcslen(pszFullPath)];
_tcscpy(pszPatternPart, pNextDir);
@@ -1777,9 +1792,7 @@ ResolvePattern(
TRACE("pszPatternPart: %S is DIFFERENT from file criterion: %S\n", pszPatternPart, pNextDir);
/* Anything NOT being "." or ".." (the special directories) must be fully restored */
- if (*pNextDir &&
- (_tcsicmp(pNextDir, _T(".")) != 0) &&
- (_tcsicmp(pNextDir, _T("..")) != 0))
+ if (*pNextDir && !IsDotDirectory(pNextDir))
{
/* Restore the correct file criterion */
_tcscpy(pszPatternPart, pNextDir);
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=17ebc8421af13d0fc5709…
commit 17ebc8421af13d0fc57095a16fa0d3440b059303
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Mon Aug 6 21:46:38 2018 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Mon Aug 6 22:40:17 2018 +0200
[CMD] Fix the way the DIR-command pattern is interpreted when it contains paths or filenames with trailing dots.
Particular DIR commands like: "DIR .", "DIR .." now work as expected,
and we also correctly fix the behavior for files without extension,
that r38746 (2b06cfc0) originally tried to fix but broke the previous
examples.
Therefore "DIR *." and "DIR noextfile." work too.
Pathological cases like "DIR \...", "DIR \...\.", "DIR ..\...\.." and
the like (and with more than 3 dots) now work as expected.
Adapted from PR #592 by Katayama Hirofumi MZ, but with extended bugfixing.
CORE-13961
---
base/shell/cmd/dir.c | 321 ++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 254 insertions(+), 67 deletions(-)
diff --git a/base/shell/cmd/dir.c b/base/shell/cmd/dir.c
index 965cf74d6f..17627b9bae 100644
--- a/base/shell/cmd/dir.c
+++ b/base/shell/cmd/dir.c
@@ -121,20 +121,23 @@
*
* 27-Feb-2005 (Konstantinos Paliouras <squarious(a)gmail.com>)
* Implemented all the switches that were missing, and made
- * the ros dir very similar to windows dir. Major part of
+ * the ROS dir very similar to windows dir. Major part of
* the code is rewritten. /p is removed, to be rewritten in
* the main cmd code.
*
* 1-Jul-2004 (Brandon Turner <turnerb7(a)msu.edu>)
* Added /p back in using ConOutPrintfPaging
*
- * 3-feb-2007 (Paolo Devoti devotip at gmail)
+ * 3-Feb-2007 (Paolo Devoti devotip at gmail)
* Removed variables formerly in use to handle pagination
* Pagination belongs to ConOutPrintfPaging
* Removed already commented out code of old pagination
*
* 25-Aug-2015 (Pierre Schweitzer)
* Implemented /R switch
+ *
+ * 6-Aug-2018 (Hermes Belusca-Maito and Katayama Hirofumi MZ)
+ * Fix handling of patterns containing trailing dots.
*/
#include "precomp.h"
@@ -572,23 +575,15 @@ static BOOL
PrintDirectoryHeader(LPCTSTR szPath, LPDIRSWITCHFLAGS lpFlags)
{
TCHAR szMsg[RC_STRING_MAX_SIZE];
- TCHAR szFullDir[MAX_PATH];
+ LPCTSTR szFullDir;
TCHAR szRootName[MAX_PATH];
TCHAR szVolName[80];
- LPTSTR pszFilePart;
DWORD dwSerialNr;
if (lpFlags->bBareFormat)
return TRUE;
- if (GetFullPathName(szPath, ARRAYSIZE(szFullDir), szFullDir, &pszFilePart) == 0)
- {
- ErrorMessage(GetLastError(), _T("Failed to build full directory path"));
- return FALSE;
- }
-
- if (pszFilePart != NULL)
- *pszFilePart = _T('\0');
+ szFullDir = szPath;
/* Get the media ID of the drive */
if (!GetVolumePathName(szFullDir, szRootName, ARRAYSIZE(szRootName)) ||
@@ -1339,10 +1334,10 @@ DirNodeCleanup(PDIRFINDLISTNODE ptrStartNode,
* The function that does everything except for printing results
*/
static INT
-DirList(LPTSTR szPath, /* [IN] The path that dir starts */
+DirList(IN OUT LPTSTR szFullPath, /* [IN] The full path we are listing with trailing '\', where dir starts */
+ IN LPTSTR pszFilePart, /* [IN] Pointer in the szFullPath buffer where the file (pattern) part starts*/
LPDIRSWITCHFLAGS lpFlags) /* [IN] The flags of the listing */
{
- BOOL fPoint; /* If szPath is a file with extension fPoint will be True */
HANDLE hSearch; /* The handle of the search */
HANDLE hRecSearch; /* The handle for searching recursively */
HANDLE hStreams; /* The handle for alternate streams */
@@ -1350,9 +1345,9 @@ DirList(LPTSTR szPath, /* [IN] The path that dir starts */
PDIRFINDINFO * ptrFileArray; /* An array of pointers with all the files */
PDIRFINDLISTNODE ptrStartNode; /* The pointer to the first node */
PDIRFINDLISTNODE ptrNextNode; /* A pointer used for relatives references */
- TCHAR szFullPath[MAX_PATH]; /* The full path that we are listing with trailing '\' */
- TCHAR szSubPath[MAX_PATH];
- LPTSTR pszFilePart;
+ TCHAR szSubPath[MAX_PATH]; /* The full path used for the recursive search */
+ LPTSTR pszSubFilePart;
+ TCHAR cPathSep;
DWORD dwCount; /* A counter of files found in directory */
DWORD dwCountFiles; /* Counter for files */
DWORD dwCountDirs; /* Counter for directories */
@@ -1370,24 +1365,6 @@ DirList(LPTSTR szPath, /* [IN] The path that dir starts */
dwCountFiles = 0;
dwCountDirs = 0;
u64CountBytes = 0;
- fPoint= FALSE;
-
- /* Create szFullPath */
- if (GetFullPathName(szPath, ARRAYSIZE(szFullPath), szFullPath, &pszFilePart) == 0)
- {
- _tcscpy (szFullPath, szPath);
- pszFilePart = NULL;
- }
-
- /* If no wildcard or file was specified and this is a directory, then
- display all files in it */
- if (pszFilePart == NULL || IsExistingDirectory(szFullPath))
- {
- pszFilePart = &szFullPath[_tcslen(szFullPath)];
- if (pszFilePart[-1] != _T('\\'))
- *pszFilePart++ = _T('\\');
- _tcscpy(pszFilePart, _T("*"));
- }
/* Prepare the linked list, first node is allocated */
ptrStartNode = cmd_alloc(sizeof(DIRFINDLISTNODE));
@@ -1399,24 +1376,14 @@ DirList(LPTSTR szPath, /* [IN] The path that dir starts */
ptrStartNode->stInfo.ptrHead = NULL;
ptrNextNode = ptrStartNode;
- /* Checking if szPath is a File with/wout extension */
- if (szPath[_tcslen(szPath) - 1] == _T('.'))
- fPoint= TRUE;
-
/* Collect the results for the current folder */
hSearch = FindFirstFile(szFullPath, &wfdFileInfo);
if (hSearch != INVALID_HANDLE_VALUE)
{
do
{
- /* If retrieved FileName has extension,and szPath doesnt have extension then JUMP the retrieved FileName */
- if (_tcschr(wfdFileInfo.cFileName,_T('.')) && (fPoint != FALSE))
- {
- continue;
- /* Here we filter all the specified attributes */
- }
- else if ((wfdFileInfo.dwFileAttributes & lpFlags->stAttribs.dwAttribMask )
- == (lpFlags->stAttribs.dwAttribMask & lpFlags->stAttribs.dwAttribVal ))
+ if ((wfdFileInfo.dwFileAttributes & lpFlags->stAttribs.dwAttribMask) ==
+ (lpFlags->stAttribs.dwAttribMask & lpFlags->stAttribs.dwAttribVal))
{
ptrNextNode->ptrNext = cmd_alloc(sizeof(DIRFINDLISTNODE));
if (ptrNextNode->ptrNext == NULL)
@@ -1548,9 +1515,9 @@ DirList(LPTSTR szPath, /* [IN] The path that dir starts */
QsortFiles(ptrFileArray, 0, dwCount-1, lpFlags);
/* Print Data */
- pszFilePart[-1] = _T('\0'); /* truncate to directory name only */
+ cPathSep = pszFilePart[-1];
+ pszFilePart[-1] = _T('\0'); /* Truncate to directory name only */
DirPrintFiles(ptrFileArray, dwCount, szFullPath, lpFlags);
- pszFilePart[-1] = _T('\\');
if (lpFlags->bRecursive)
{
@@ -1561,6 +1528,7 @@ DirList(LPTSTR szPath, /* [IN] The path that dir starts */
lpFlags,
FALSE);
}
+ pszFilePart[-1] = cPathSep;
/* Free array */
cmd_free(ptrFileArray);
@@ -1601,10 +1569,11 @@ DirList(LPTSTR szPath, /* [IN] The path that dir starts */
memcpy(szSubPath, szFullPath, (pszFilePart - szFullPath) * sizeof(TCHAR));
_tcscpy(&szSubPath[pszFilePart - szFullPath], wfdFileInfo.cFileName);
_tcscat(szSubPath, _T("\\"));
- _tcscat(szSubPath, pszFilePart);
+ pszSubFilePart = &szSubPath[_tcslen(szSubPath)];
+ _tcscat(pszSubFilePart, pszFilePart);
/* We do the same for the folder */
- if (DirList(szSubPath, lpFlags) != 0)
+ if (DirList(szSubPath, pszSubFilePart, lpFlags) != 0)
{
FindClose(hRecSearch);
return 1;
@@ -1618,6 +1587,225 @@ DirList(LPTSTR szPath, /* [IN] The path that dir starts */
return 0;
}
+static VOID
+ResolvePattern(
+ IN LPTSTR pszPattern,
+ IN DWORD nBufferLength,
+ OUT LPTSTR pszFullPath,
+ OUT LPTSTR* ppszPatternPart OPTIONAL)
+{
+ LPTSTR pCurDir, pNextDir, ptr;
+ LPTSTR pszPatternPart;
+ TCHAR szNewPattern[MAX_PATH];
+
+ /*
+ * We are going to use GetFullPathName() to properly determine the actual
+ * full path from the pattern. However, due to the fact GetFullPathName()
+ * strips parts of the file name component in case the pattern contains
+ * path specification with trailing dots, it is required to perform a
+ * pre-treatment on the pattern and a post-treatment on the obtained path.
+ * This is mandatory in order to use the correct file search criterion.
+ *
+ * One particular case is when the pattern specifies a dots-only directory
+ * followed by either the "." or ".." special directories. In this case the
+ * GetFullPathName() function may completely miss the dots-only directory.
+ * An example is given by the pattern (C-string notation) "\\...\\." .
+ * To cope with this problem we need to partially canonicalize the pattern
+ * by collapsing any "." or ".." special directory that immediately follows
+ * a dots-only directory. We collapse in addition consecutive backslashes.
+ *
+ * Finally, trailing dots are skipped by GetFullPathName(). Therefore
+ * a pattern that matches files with no extension, for example: "*." ,
+ * or: "dir\\noextfile." , are reduced to simply "*" or "dir\\noextfile",
+ * that match files with extensions. Or, a pattern specifying a trailing
+ * dots-only directory: "dir\\..." gets completely ignored and only the
+ * full path to "dir" is returned.
+ * To fix this second problem we need to restore the last part of the path
+ * pattern using the pattern that has been first partially canonicalized.
+ *
+ * Note however that the "." or ".." special directories are always
+ * interpreted correctly by GetFullPathName().
+ */
+
+ /* Make a copy of the path pattern */
+ ASSERT(_tcslen(pszPattern) < ARRAYSIZE(szNewPattern));
+ _tcscpy(szNewPattern, pszPattern);
+ pszPattern = szNewPattern;
+
+ TRACE("Original pszPattern: %S\n", pszPattern);
+
+ /* Convert slashes into backslashes */
+ pNextDir = pszPattern;
+ while ((pNextDir = _tcschr(pNextDir, _T('/'))))
+ *pNextDir++ = _T('\\');
+
+ /*
+ * Find any dots-only directory and collapse any "." or ".." special
+ * directory that immediately follows it.
+ * Note that we just start looking after the first path separator. Indeed,
+ * dots-only directories that are not preceded by a path separator, and so
+ * appear first in the pattern, for example: "...\dir", or: "..." , are
+ * either correctly handled by GetFullPathName() because they are followed
+ * by a non-pathological directory, or because they are handled when we
+ * restore the trailing dots pattern piece in the next step.
+ */
+ pNextDir = pszPattern;
+ while (pNextDir)
+ {
+ pCurDir = pNextDir;
+
+ /* Find the next path separator in the pattern */
+ pNextDir = _tcschr(pNextDir, _T('\\'));
+ if (!pNextDir)
+ break;
+
+ /* Ignore the special "." and ".." directories that are correctly handled */
+ if ((pNextDir - pCurDir == 0) ||
+ (pNextDir - pCurDir == 1 && pCurDir[0] == _T('.')) ||
+ (pNextDir - pCurDir == 2 && pCurDir[0] == _T('.') && pCurDir[1] == _T('.')))
+ {
+ /* Found such a directory, ignore */
+ ++pNextDir;
+ continue;
+ }
+
+ /* Check whether this is a dots-only directory */
+ for (ptr = pCurDir; ptr < pNextDir; ++ptr)
+ {
+ if (*ptr != _T('.'))
+ break;
+ }
+ if (ptr < pNextDir)
+ {
+ /* Not a dots-only directory, ignore */
+ ++pNextDir;
+ continue;
+ }
+
+ /* Skip any consecutive backslashes */
+ for (ptr = pNextDir; *ptr == _T('\\'); ++ptr) ;
+
+ /* pCurDir is a dots-only directory, perform partial canonicalization */
+
+ /* Remove any following "." directory */
+ if (ptr[0] == _T('.') && (ptr[1] == _T('\\') || ptr[1] == 0))
+ {
+ memmove(pNextDir, ptr + 1, (_tcslen(ptr + 1) + 1) * sizeof(TCHAR));
+ }
+ /* Remove any following ".." directory */
+ else if (ptr[0] == _T('.') && ptr[1] == _T('.') && (ptr[2] == _T('\\') || ptr[2] == 0))
+ {
+ /* Skip any consecutive backslashes before the next directory */
+ for (ptr = ptr + 2; *ptr == _T('\\'); ++ptr) ;
+
+ memmove(pCurDir, ptr, (_tcslen(ptr) + 1) * sizeof(TCHAR));
+ pNextDir = pCurDir;
+ }
+ else
+ {
+ ++pNextDir;
+
+ /* Collapse consecutive backslashes */
+ if (ptr > pNextDir)
+ memmove(pNextDir, ptr, (_tcslen(ptr) + 1) * sizeof(TCHAR));
+ }
+ }
+
+ /* An empty pattern means we enumerate all files in the current directory */
+ if (!*pszPattern)
+ _tcscpy(pszPattern, _T("*"));
+
+ TRACE("New pszPattern: %S\n", pszPattern);
+
+ /* Create the full path */
+ if (GetFullPathName(pszPattern, nBufferLength, pszFullPath, &pszPatternPart) == 0)
+ {
+ _tcscpy(pszFullPath, pszPattern);
+ pszPatternPart = NULL;
+ }
+
+ TRACE("pszFullPath (1): %S\n", pszFullPath);
+ TRACE("pszPatternPart (1): %S\n", pszPatternPart);
+
+ /*
+ * Restore the correct file name component in case the pattern contained
+ * trailing dots that have been skipped by GetFullPathName().
+ */
+
+ /* Find the last path separator in the original szPath */
+ pNextDir = _tcsrchr(pszPattern, _T('\\'));
+ if (pNextDir)
+ {
+ /* Skip past the separator and look at the path */
+ ++pNextDir;
+ }
+ else
+ {
+ /* The pattern is the path we need to look at */
+ pNextDir = pszPattern;
+ }
+
+ /*
+ * When pszPatternPart == NULL this means that pszFullPath should be a
+ * directory; however it might have happened that the original pattern
+ * was specifying a dots-only directory, that has been stripped off by
+ * GetFullPathName(). In both these cases we need to restore these as
+ * they are part of the actual directory path; the exception being if
+ * these are the special "." or ".." directories.
+ */
+ if (pszPatternPart == NULL)
+ {
+ ASSERT(pszFullPath[_tcslen(pszFullPath)-1] == _T('\\'));
+
+ /* Anything NOT being "." or ".." (the special directories) must be fully restored */
+ if (*pNextDir &&
+ (_tcsicmp(pNextDir, _T(".")) != 0) &&
+ (_tcsicmp(pNextDir, _T("..")) != 0))
+ {
+ pszPatternPart = &pszFullPath[_tcslen(pszFullPath)];
+ _tcscpy(pszPatternPart, pNextDir);
+ pszPatternPart = NULL;
+ }
+ }
+ else if (_tcscmp(pNextDir, pszPatternPart) != 0)
+ {
+ /*
+ * For example, pszPatternPart == "." or ".." and we do not need to
+ * do anything for these, or pszPatternPart == "dir\\noextfile." and
+ * we need to restore all the trailing points.
+ */
+ TRACE("pszPatternPart: %S is DIFFERENT from file criterion: %S\n", pszPatternPart, pNextDir);
+
+ /* Anything NOT being "." or ".." (the special directories) must be fully restored */
+ if (*pNextDir &&
+ (_tcsicmp(pNextDir, _T(".")) != 0) &&
+ (_tcsicmp(pNextDir, _T("..")) != 0))
+ {
+ /* Restore the correct file criterion */
+ _tcscpy(pszPatternPart, pNextDir);
+ }
+ }
+
+ TRACE("pszFullPath (2): %S\n", pszFullPath);
+
+ /*
+ * If no wildcard or file was specified and this is a directory,
+ * display all files in it.
+ */
+ if (pszPatternPart == NULL || IsExistingDirectory(pszFullPath))
+ {
+ pszPatternPart = &pszFullPath[_tcslen(pszFullPath)];
+ if (pszPatternPart[-1] != _T('\\'))
+ *pszPatternPart++ = _T('\\');
+ _tcscpy(pszPatternPart, _T("*"));
+ }
+
+ TRACE("pszPatternPart (2): %S\n", pszPatternPart);
+
+ if (ppszPatternPart)
+ *ppszPatternPart = pszPatternPart;
+}
+
/*
* dir
*
@@ -1627,10 +1815,11 @@ INT
CommandDir(LPTSTR rest)
{
TCHAR dircmd[MAX_PATH]; /* A variable to store the DIRCMD environment variable */
- TCHAR path[MAX_PATH];
TCHAR prev_volume[MAX_PATH];
+ TCHAR szFullPath[MAX_PATH];
LPTSTR* params = NULL;
LPTSTR pszFilePart;
+ TCHAR cPathSep;
INT entries = 0;
UINT loop = 0;
DIRSWITCHFLAGS stFlags;
@@ -1729,40 +1918,38 @@ CommandDir(LPTSTR rest)
ChangedVolume = TRUE;
if (!stFlags.bBareFormat &&
- GetVolumePathName(params[loop], path, ARRAYSIZE(path)))
+ GetVolumePathName(params[loop], szFullPath, ARRAYSIZE(szFullPath)))
{
- if (!_tcscmp(path, prev_volume))
+ if (!_tcscmp(szFullPath, prev_volume))
ChangedVolume = FALSE;
else
- _tcscpy(prev_volume, path);
- }
- else if (GetFullPathName(params[loop], ARRAYSIZE(path), path, &pszFilePart) != 0)
- {
- if (pszFilePart != NULL)
- *pszFilePart = _T('\0');
- }
- else
- {
- _tcscpy(path, params[loop]);
+ _tcscpy(prev_volume, szFullPath);
}
+ /* Resolve the pattern */
+ ResolvePattern(params[loop], ARRAYSIZE(szFullPath), szFullPath, &pszFilePart);
+
/* Print the header */
+ cPathSep = pszFilePart[-1];
+ pszFilePart[-1] = _T('\0'); /* Truncate to directory name only */
if (ChangedVolume && !stFlags.bBareFormat &&
- !PrintDirectoryHeader(params[loop], &stFlags))
+ !PrintDirectoryHeader(szFullPath, &stFlags))
{
nErrorLevel = 1;
goto cleanup;
}
+ pszFilePart[-1] = cPathSep;
/* Perform the actual directory listing */
- if (DirList(params[loop], &stFlags) != 0)
+ if (DirList(szFullPath, pszFilePart, &stFlags) != 0)
{
nErrorLevel = 1;
goto cleanup;
}
/* Print the footer */
- PrintSummary(path,
+ pszFilePart[-1] = _T('\0'); /* Truncate to directory name only */
+ PrintSummary(szFullPath,
recurse_file_cnt,
recurse_dir_cnt,
recurse_bytes,