ReactOS 0.4.15-dev-5672-gf73ac17
dir.c File Reference
#include "precomp.h"
Include dependency graph for dir.c:

Go to the source code of this file.

Classes

struct  _DirSwitchesFlags
 
struct  _DIRFINDSTREAMNODE
 
struct  _DIRFINDINFO
 
struct  _DIRFINDLISTNODE
 

Typedefs

typedef struct _DirSwitchesFlags DIRSWITCHFLAGS
 
typedef struct _DirSwitchesFlagsLPDIRSWITCHFLAGS
 
typedef struct _DIRFINDSTREAMNODE DIRFINDSTREAMNODE
 
typedef struct _DIRFINDSTREAMNODEPDIRFINDSTREAMNODE
 
typedef struct _DIRFINDINFO DIRFINDINFO
 
typedef struct _DIRFINDINFOPDIRFINDINFO
 
typedef struct _DIRFINDLISTNODE DIRFINDLISTNODE
 
typedef struct _DIRFINDLISTNODEPDIRFINDLISTNODE
 
typedef BOOL(WINAPIPGETFREEDISKSPACEEX) (LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER)
 

Enumerations

enum  ETimeField { TF_CREATIONDATE = 0 , TF_MODIFIEDDATE = 1 , TF_LASTACCESSEDDATE = 2 }
 
enum  EOrderBy {
  ORDER_NAME = 0 , ORDER_SIZE = 1 , ORDER_DIRECTORY = 2 , ORDER_EXTENSION = 3 ,
  ORDER_TIME = 4
}
 

Functions

static VOID DirHelp (VOID)
 
FORCEINLINE BOOL IsDotDirectory (IN LPCTSTR pszPath)
 
FORCEINLINE BOOL IsDotDirectoryN (IN const TCHAR *pPath, IN SIZE_T Length)
 
static BOOL DirReadParam (LPTSTR Line, LPTSTR **params, LPINT entries, LPDIRSWITCHFLAGS lpFlags)
 
static BOOL DirPrintf (LPDIRSWITCHFLAGS lpFlags, LPTSTR szFormat,...)
 
static BOOL PrintDirectoryHeader (LPCTSTR szPath, LPDIRSWITCHFLAGS lpFlags)
 
static VOID DirPrintFileDateTime (TCHAR *lpDate, TCHAR *lpTime, LPWIN32_FIND_DATA lpFile, LPDIRSWITCHFLAGS lpFlags)
 
INT FormatDate (TCHAR *lpDate, LPSYSTEMTIME dt, BOOL b4Digit)
 
INT FormatTime (TCHAR *lpTime, LPSYSTEMTIME dt)
 
static VOID GetUserDiskFreeSpace (LPCTSTR lpRoot, PULARGE_INTEGER lpFreeSpace)
 
static INT PrintSummary (LPCTSTR szPath, ULONG ulFiles, ULONG ulDirs, ULONGLONG u64Bytes, LPDIRSWITCHFLAGS lpFlags, BOOL TotalSummary)
 
TCHARgetExt (const TCHAR *file)
 
static LPTSTR getName (const TCHAR *file, TCHAR *dest)
 
static VOID DirPrintNewList (PDIRFINDINFO ptrFiles[], DWORD dwCount, LPCTSTR szCurPath, LPDIRSWITCHFLAGS lpFlags)
 
static VOID DirPrintWideList (PDIRFINDINFO ptrFiles[], DWORD dwCount, LPCTSTR szCurPath, LPDIRSWITCHFLAGS lpFlags)
 
static VOID DirPrintOldList (PDIRFINDINFO ptrFiles[], DWORD dwCount, LPCTSTR szCurPath, LPDIRSWITCHFLAGS lpFlags)
 
static VOID DirPrintBareList (PDIRFINDINFO ptrFiles[], DWORD dwCount, LPCTSTR szCurPath, LPDIRSWITCHFLAGS lpFlags)
 
static VOID DirPrintFiles (PDIRFINDINFO ptrFiles[], DWORD dwCount, LPCTSTR szCurPath, LPDIRSWITCHFLAGS lpFlags)
 
static BOOL CompareFiles (PDIRFINDINFO lpFile1, PDIRFINDINFO lpFile2, LPDIRSWITCHFLAGS lpFlags)
 
static VOID QsortFiles (PDIRFINDINFO ptrArray[], int i, int j, LPDIRSWITCHFLAGS lpFlags)
 
static VOID DirNodeCleanup (PDIRFINDLISTNODE ptrStartNode, PDWORD pdwCount)
 
static INT DirList (IN OUT LPTSTR szFullPath, IN LPTSTR pszFilePart, LPDIRSWITCHFLAGS lpFlags)
 
static VOID ResolvePattern (IN LPTSTR pszPattern, IN DWORD nBufferLength, OUT LPTSTR pszFullPath, OUT LPTSTR *ppszPatternPart OPTIONAL)
 
INT CommandDir (LPTSTR rest)
 

Variables

static ULONG recurse_dir_cnt
 
static ULONG recurse_file_cnt
 
static ULONGLONG recurse_bytes
 

Typedef Documentation

◆ DIRFINDINFO

◆ DIRFINDLISTNODE

◆ DIRFINDSTREAMNODE

◆ DIRSWITCHFLAGS

◆ LPDIRSWITCHFLAGS

◆ PDIRFINDINFO

◆ PDIRFINDLISTNODE

◆ PDIRFINDSTREAMNODE

◆ PGETFREEDISKSPACEEX

typedef BOOL(WINAPI * PGETFREEDISKSPACEEX) (LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER)

Definition at line 215 of file dir.c.

Enumeration Type Documentation

◆ EOrderBy

Enumerator
ORDER_NAME 
ORDER_SIZE 
ORDER_DIRECTORY 
ORDER_EXTENSION 
ORDER_TIME 

Definition at line 156 of file dir.c.

157{
158 ORDER_NAME = 0,
159 ORDER_SIZE = 1,
160 ORDER_DIRECTORY = 2,
161 ORDER_EXTENSION = 3,
162 ORDER_TIME = 4
163};
@ ORDER_DIRECTORY
Definition: dir.c:160
@ ORDER_EXTENSION
Definition: dir.c:161
@ ORDER_TIME
Definition: dir.c:162
@ ORDER_SIZE
Definition: dir.c:159
@ ORDER_NAME
Definition: dir.c:158

◆ ETimeField

Enumerator
TF_CREATIONDATE 
TF_MODIFIEDDATE 
TF_LASTACCESSEDDATE 

Definition at line 148 of file dir.c.

149{
150 TF_CREATIONDATE = 0,
151 TF_MODIFIEDDATE = 1,
153};
@ TF_CREATIONDATE
Definition: dir.c:150
@ TF_MODIFIEDDATE
Definition: dir.c:151
@ TF_LASTACCESSEDDATE
Definition: dir.c:152

Function Documentation

◆ CommandDir()

INT CommandDir ( LPTSTR  rest)

Definition at line 1835 of file dir.c.

1836{
1837 TCHAR dircmd[MAX_PATH]; /* A variable to store the DIRCMD environment variable */
1838 TCHAR prev_volume[MAX_PATH];
1839 TCHAR szFullPath[MAX_PATH];
1840 LPTSTR* params = NULL;
1841 LPTSTR pszFilePart;
1842 TCHAR cPathSep;
1843 INT entries = 0;
1844 UINT loop = 0;
1845 DIRSWITCHFLAGS stFlags;
1846 INT ret = 1;
1847 BOOL ChangedVolume;
1848
1849 /* Initialize Switch Flags < Default switches are set here! > */
1850 stFlags.b4Digit = TRUE;
1851 stFlags.bBareFormat = FALSE;
1852 stFlags.bDataStreams = FALSE;
1853 stFlags.bLowerCase = FALSE;
1854 stFlags.bNewLongList = TRUE;
1855 stFlags.bPause = FALSE;
1856 stFlags.bRecursive = FALSE;
1857 stFlags.bShortName = FALSE;
1858 stFlags.bTSeparator = TRUE;
1859 stFlags.bUser = FALSE;
1860 stFlags.bWideList = FALSE;
1861 stFlags.bWideListColSort = FALSE;
1862 stFlags.stTimeField.eTimeField = TF_MODIFIEDDATE;
1863 stFlags.stAttribs.dwAttribMask = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
1864 stFlags.stAttribs.dwAttribVal = 0L;
1865 stFlags.stOrderBy.sCriteriaCount = 0;
1866
1867 nErrorLevel = 0;
1868
1869 /* Read the parameters from the DIRCMD environment variable */
1870 if (GetEnvironmentVariable (_T("DIRCMD"), dircmd, ARRAYSIZE(dircmd)))
1871 {
1872 if (!DirReadParam(dircmd, &params, &entries, &stFlags))
1873 {
1874 nErrorLevel = 1;
1875 goto cleanup;
1876 }
1877 }
1878
1879 /* Read the parameters */
1880 if (!DirReadParam(rest, &params, &entries, &stFlags) || CheckCtrlBreak(BREAK_INPUT))
1881 {
1882 nErrorLevel = 1;
1883 goto cleanup;
1884 }
1885
1886 /* Default to current directory */
1887 if (entries == 0)
1888 {
1889 if (!add_entry(&entries, &params, _T("*")))
1890 {
1891 nErrorLevel = 1;
1892 goto cleanup;
1893 }
1894 }
1895
1896 prev_volume[0] = _T('\0');
1897
1898 /* Reset paging state */
1899 if (stFlags.bPause)
1901
1902 for (loop = 0; loop < (UINT)entries; loop++)
1903 {
1905 {
1906 nErrorLevel = 1;
1907 goto cleanup;
1908 }
1909
1910 recurse_dir_cnt = 0L;
1912 recurse_bytes = 0;
1913
1914 /* <Debug :>
1915 Uncomment this to show the final state of switch flags*/
1916 {
1917 int i;
1918 TRACE("Attributes mask/value %x/%x\n",stFlags.stAttribs.dwAttribMask,stFlags.stAttribs.dwAttribVal);
1919 TRACE("(B) Bare format : %i\n", stFlags.bBareFormat);
1920 TRACE("(C) Thousand : %i\n", stFlags.bTSeparator);
1921 TRACE("(W) Wide list : %i\n", stFlags.bWideList);
1922 TRACE("(D) Wide list sort by column : %i\n", stFlags.bWideListColSort);
1923 TRACE("(L) Lowercase : %i\n", stFlags.bLowerCase);
1924 TRACE("(N) New : %i\n", stFlags.bNewLongList);
1925 TRACE("(O) Order : %i\n", stFlags.stOrderBy.sCriteriaCount);
1926 for (i =0;i<stFlags.stOrderBy.sCriteriaCount;i++)
1927 TRACE(" Order Criteria [%i]: %i (Reversed: %i)\n",i, stFlags.stOrderBy.eCriteria[i], stFlags.stOrderBy.bCriteriaRev[i]);
1928 TRACE("(P) Pause : %i\n", stFlags.bPause);
1929 TRACE("(Q) Owner : %i\n", stFlags.bUser);
1930 TRACE("(R) Data stream : %i\n", stFlags.bDataStreams);
1931 TRACE("(S) Recursive : %i\n", stFlags.bRecursive);
1932 TRACE("(T) Time field : %i\n", stFlags.stTimeField.eTimeField);
1933 TRACE("(X) Short names : %i\n", stFlags.bShortName);
1934 TRACE("Parameter : %s\n", debugstr_aw(params[loop]));
1935 }
1936
1937 /* Print the drive header if the volume changed */
1938 ChangedVolume = TRUE;
1939
1940 if (!stFlags.bBareFormat &&
1941 GetVolumePathName(params[loop], szFullPath, ARRAYSIZE(szFullPath)))
1942 {
1943 if (!_tcscmp(szFullPath, prev_volume))
1944 ChangedVolume = FALSE;
1945 else
1946 _tcscpy(prev_volume, szFullPath);
1947 }
1948
1949 /* Resolve the pattern */
1950 ResolvePattern(params[loop], ARRAYSIZE(szFullPath), szFullPath, &pszFilePart);
1951
1952 /* Print the header */
1953 cPathSep = pszFilePart[-1];
1954 pszFilePart[-1] = _T('\0'); /* Truncate to directory name only */
1955 if (ChangedVolume && !stFlags.bBareFormat &&
1956 !PrintDirectoryHeader(szFullPath, &stFlags))
1957 {
1958 nErrorLevel = 1;
1959 goto cleanup;
1960 }
1961 pszFilePart[-1] = cPathSep;
1962
1963 /* Perform the actual directory listing */
1964 if (DirList(szFullPath, pszFilePart, &stFlags) != 0)
1965 {
1966 nErrorLevel = 1;
1967 goto cleanup;
1968 }
1969
1970 /* Print the footer */
1971 pszFilePart[-1] = _T('\0'); /* Truncate to directory name only */
1972 PrintSummary(szFullPath,
1976 &stFlags,
1977 TRUE);
1978 }
1979
1980 ret = 0;
1981
1982cleanup:
1983 freep(params);
1984
1985 return ret;
1986}
INT nErrorLevel
Definition: cmd.c:158
BOOL CheckCtrlBreak(INT)
Definition: misc.c:132
#define BREAK_INPUT
Definition: cmd.h:36
BOOL __cdecl ConOutPrintfPaging(BOOL StartPaging, LPTSTR szFormat,...)
Definition: console.c:171
static INT PrintSummary(LPCTSTR szPath, ULONG ulFiles, ULONG ulDirs, ULONGLONG u64Bytes, LPDIRSWITCHFLAGS lpFlags, BOOL TotalSummary)
Definition: dir.c:770
static ULONG recurse_dir_cnt
Definition: dir.c:220
static INT DirList(IN OUT LPTSTR szFullPath, IN LPTSTR pszFilePart, LPDIRSWITCHFLAGS lpFlags)
Definition: dir.c:1357
static ULONGLONG recurse_bytes
Definition: dir.c:222
static BOOL DirReadParam(LPTSTR Line, LPTSTR **params, LPINT entries, LPDIRSWITCHFLAGS lpFlags)
Definition: dir.c:264
static VOID ResolvePattern(IN LPTSTR pszPattern, IN DWORD nBufferLength, OUT LPTSTR pszFullPath, OUT LPTSTR *ppszPatternPart OPTIONAL)
Definition: dir.c:1610
static BOOL PrintDirectoryHeader(LPCTSTR szPath, LPDIRSWITCHFLAGS lpFlags)
Definition: dir.c:597
static ULONG recurse_file_cnt
Definition: dir.c:221
#define debugstr_aw
Definition: precomp.h:43
static VOID freep(LPSTR *p)
Definition: cmdcons.c:98
BOOL add_entry(LPINT ac, LPSTR **arg, LPCSTR entry)
Definition: cmdcons.c:132
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define MAX_PATH
Definition: compat.h:34
static void cleanup(void)
Definition: main.c:1335
unsigned int BOOL
Definition: ntddk_ex.h:94
GLenum const GLfloat * params
Definition: glext.h:5645
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define _tcscmp
Definition: tchar.h:1424
#define _tcscpy
Definition: tchar.h:623
unsigned int UINT
Definition: ndis.h:50
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
#define FILE_ATTRIBUTE_SYSTEM
Definition: nt_native.h:704
#define L(x)
Definition: ntvdm.h:50
#define TRACE(s)
Definition: solgame.cpp:4
BOOL bDataStreams
Definition: dir.c:179
BOOL bRecursive
Definition: dir.c:176
BOOL bNewLongList
Definition: dir.c:173
struct _DirSwitchesFlags::@62 stOrderBy
BOOL bWideListColSort
Definition: dir.c:171
BOOL bBareFormat
Definition: dir.c:168
BOOL bWideList
Definition: dir.c:170
BOOL b4Digit
Definition: dir.c:178
BOOL bLowerCase
Definition: dir.c:172
struct _DirSwitchesFlags::@63 stTimeField
struct _DirSwitchesFlags::@61 stAttribs
BOOL bShortName
Definition: dir.c:177
BOOL bPause
Definition: dir.c:174
BOOL bUser
Definition: dir.c:175
BOOL bTSeparator
Definition: dir.c:169
int32_t INT
Definition: typedefs.h:58
#define _T(x)
Definition: vfdio.h:22
int ret
#define GetEnvironmentVariable
Definition: winbase.h:3685
#define GetVolumePathName
Definition: winbase.h:3726
char TCHAR
Definition: xmlstorage.h:189
CHAR * LPTSTR
Definition: xmlstorage.h:192

◆ CompareFiles()

static BOOL CompareFiles ( PDIRFINDINFO  lpFile1,
PDIRFINDINFO  lpFile2,
LPDIRSWITCHFLAGS  lpFlags 
)
static

Definition at line 1192 of file dir.c.

1195{
1196 ULARGE_INTEGER u64File1;
1197 ULARGE_INTEGER u64File2;
1198 int i;
1199 long iComp = 0; /* The comparison result */
1200
1201 /* Calculate criteria by order given from user */
1202 for (i = 0; i < lpFlags->stOrderBy.sCriteriaCount; i++)
1203 {
1204
1205 /* Calculate criteria */
1206 switch (lpFlags->stOrderBy.eCriteria[i])
1207 {
1208 case ORDER_SIZE: /* Order by size /o:s */
1209 /* concat the 32bit integers to a 64bit */
1210 u64File1.LowPart = lpFile1->stFindInfo.nFileSizeLow;
1211 u64File1.HighPart = lpFile1->stFindInfo.nFileSizeHigh;
1212 u64File2.LowPart = lpFile2->stFindInfo.nFileSizeLow;
1213 u64File2.HighPart = lpFile2->stFindInfo.nFileSizeHigh;
1214
1215 /* In case that difference is too big for a long */
1216 if (u64File1.QuadPart < u64File2.QuadPart)
1217 iComp = -1;
1218 else if (u64File1.QuadPart > u64File2.QuadPart)
1219 iComp = 1;
1220 else
1221 iComp = 0;
1222 break;
1223
1224 case ORDER_DIRECTORY: /* Order by directory attribute /o:g */
1225 iComp = ((lpFile2->stFindInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)-
1226 (lpFile1->stFindInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY));
1227 break;
1228
1229 case ORDER_EXTENSION: /* Order by extension name /o:e */
1230 iComp = _tcsicmp(getExt(lpFile1->stFindInfo.cFileName),getExt(lpFile2->stFindInfo.cFileName));
1231 break;
1232
1233 case ORDER_NAME: /* Order by filename /o:n */
1234 iComp = _tcsicmp(lpFile1->stFindInfo.cFileName, lpFile2->stFindInfo.cFileName);
1235 break;
1236
1237 case ORDER_TIME: /* Order by file's time /o:t */
1238 /* We compare files based on the time field selected by /t */
1239 switch (lpFlags->stTimeField.eTimeField)
1240 {
1241 case TF_CREATIONDATE:
1242 /* concat the 32bit integers to a 64bit */
1243 u64File1.LowPart = lpFile1->stFindInfo.ftCreationTime.dwLowDateTime;
1244 u64File1.HighPart = lpFile1->stFindInfo.ftCreationTime.dwHighDateTime ;
1245 u64File2.LowPart = lpFile2->stFindInfo.ftCreationTime.dwLowDateTime;
1246 u64File2.HighPart = lpFile2->stFindInfo.ftCreationTime.dwHighDateTime ;
1247 break;
1248 case TF_LASTACCESSEDDATE :
1249 /* concat the 32bit integers to a 64bit */
1250 u64File1.LowPart = lpFile1->stFindInfo.ftLastAccessTime.dwLowDateTime;
1251 u64File1.HighPart = lpFile1->stFindInfo.ftLastAccessTime.dwHighDateTime ;
1252 u64File2.LowPart = lpFile2->stFindInfo.ftLastAccessTime.dwLowDateTime;
1253 u64File2.HighPart = lpFile2->stFindInfo.ftLastAccessTime.dwHighDateTime ;
1254 break;
1255 case TF_MODIFIEDDATE:
1256 /* concat the 32bit integers to a 64bit */
1257 u64File1.LowPart = lpFile1->stFindInfo.ftLastWriteTime.dwLowDateTime;
1258 u64File1.HighPart = lpFile1->stFindInfo.ftLastWriteTime.dwHighDateTime ;
1259 u64File2.LowPart = lpFile2->stFindInfo.ftLastWriteTime.dwLowDateTime;
1260 u64File2.HighPart = lpFile2->stFindInfo.ftLastWriteTime.dwHighDateTime ;
1261 break;
1262 }
1263
1264 /* In case that difference is too big for a long */
1265 if (u64File1.QuadPart < u64File2.QuadPart)
1266 iComp = -1;
1267 else if (u64File1.QuadPart > u64File2.QuadPart)
1268 iComp = 1;
1269 else
1270 iComp = 0;
1271 break;
1272 }
1273
1274 /* Reverse if desired */
1275 if (lpFlags->stOrderBy.bCriteriaRev[i])
1276 iComp *= -1;
1277
1278 /* If that criteria was enough for distinguishing
1279 the files/dirs,there is no need to calculate the others*/
1280 if (iComp != 0) break;
1281 }
1282
1283 /* Translate the value of iComp to boolean */
1284 return iComp > 0;
1285}
TCHAR * getExt(const TCHAR *file)
Definition: dir.c:829
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
WIN32_FIND_DATA stFindInfo
Definition: dir.c:205
$ULONG LowPart
Definition: ntbasedef.h:569
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
$ULONG HighPart
Definition: ntbasedef.h:570
#define _tcsicmp
Definition: xmlstorage.h:205

Referenced by QsortFiles().

◆ DirHelp()

static VOID DirHelp ( VOID  )
static

Definition at line 231 of file dir.c.

232{
234}
VOID ConOutResPaging(BOOL StartPaging, UINT resID)
Definition: console.c:182
#define STRING_DIR_HELP1
Definition: resource.h:106

Referenced by DirReadParam().

◆ DirList()

static INT DirList ( IN OUT LPTSTR  szFullPath,
IN LPTSTR  pszFilePart,
LPDIRSWITCHFLAGS  lpFlags 
)
static

Definition at line 1357 of file dir.c.

1360{
1361 HANDLE hSearch; /* The handle of the search */
1362 HANDLE hRecSearch; /* The handle for searching recursively */
1363 HANDLE hStreams; /* The handle for alternate streams */
1364 WIN32_FIND_DATA wfdFileInfo; /* The info of file that found */
1365 PDIRFINDINFO * ptrFileArray; /* An array of pointers with all the files */
1366 PDIRFINDLISTNODE ptrStartNode; /* The pointer to the first node */
1367 PDIRFINDLISTNODE ptrNextNode; /* A pointer used for relatives references */
1368 TCHAR szSubPath[MAX_PATH]; /* The full path used for the recursive search */
1369 LPTSTR pszSubFilePart;
1370 TCHAR cPathSep;
1371 DWORD dwCount; /* A counter of files found in directory */
1372 DWORD dwCountFiles; /* Counter for files */
1373 DWORD dwCountDirs; /* Counter for directories */
1374 ULONGLONG u64CountBytes; /* Counter for bytes */
1375 ULARGE_INTEGER u64Temp; /* A temporary counter */
1376 WIN32_FIND_STREAM_DATA wfsdStreamInfo;
1377 PDIRFINDSTREAMNODE * ptrCurNode; /* The pointer to the first stream */
1378 static HANDLE (WINAPI *pFindFirstStreamW)(LPCWSTR, STREAM_INFO_LEVELS, LPVOID, DWORD);
1379 static BOOL (WINAPI *pFindNextStreamW)(HANDLE, LPVOID);
1380
1381 /* Initialize variables */
1382 ptrStartNode = NULL;
1383 ptrNextNode = NULL;
1384 dwCount = 0;
1385 dwCountFiles = 0;
1386 dwCountDirs = 0;
1387 u64CountBytes = 0;
1388
1389 /* Prepare the linked list, first node is allocated */
1390 ptrStartNode = cmd_alloc(sizeof(DIRFINDLISTNODE));
1391 if (ptrStartNode == NULL)
1392 {
1393 WARN("Cannot allocate memory for ptrStartNode!\n");
1394 return 1; /* Error cannot allocate memory for 1st object */
1395 }
1396 ptrStartNode->stInfo.ptrHead = NULL;
1397 ptrNextNode = ptrStartNode;
1398
1399 /* Collect the results for the current directory */
1400 hSearch = FindFirstFile(szFullPath, &wfdFileInfo);
1401 if (hSearch != INVALID_HANDLE_VALUE)
1402 {
1403 do
1404 {
1405 if ((wfdFileInfo.dwFileAttributes & lpFlags->stAttribs.dwAttribMask) ==
1406 (lpFlags->stAttribs.dwAttribMask & lpFlags->stAttribs.dwAttribVal))
1407 {
1408 ptrNextNode->ptrNext = cmd_alloc(sizeof(DIRFINDLISTNODE));
1409 if (ptrNextNode->ptrNext == NULL)
1410 {
1411 WARN("Cannot allocate memory for ptrNextNode->ptrNext!\n");
1412 DirNodeCleanup(ptrStartNode, &dwCount);
1413 FindClose(hSearch);
1414 return 1;
1415 }
1416
1417 /* Copy the info of search at linked list */
1418 memcpy(&ptrNextNode->ptrNext->stInfo.stFindInfo,
1419 &wfdFileInfo,
1420 sizeof(WIN32_FIND_DATA));
1421
1422 /* If lower case is selected do it here */
1423 if (lpFlags->bLowerCase)
1424 {
1425 _tcslwr(ptrNextNode->ptrNext->stInfo.stFindInfo.cAlternateFileName);
1426 _tcslwr(ptrNextNode->ptrNext->stInfo.stFindInfo.cFileName);
1427 }
1428
1429 /* No streams (yet?) */
1430 ptrNextNode->ptrNext->stInfo.ptrHead = NULL;
1431
1432 /* Alternate streams are only displayed with new long list */
1433 if (lpFlags->bNewLongList && lpFlags->bDataStreams)
1434 {
1435 if (!pFindFirstStreamW)
1436 {
1437 pFindFirstStreamW = (PVOID)GetProcAddress(GetModuleHandle(_T("kernel32")), "FindFirstStreamW");
1438 pFindNextStreamW = (PVOID)GetProcAddress(GetModuleHandle(_T("kernel32")), "FindNextStreamW");
1439 }
1440
1441 /* Try to get stream information */
1442 if (pFindFirstStreamW && pFindNextStreamW)
1443 {
1444 hStreams = pFindFirstStreamW(wfdFileInfo.cFileName, FindStreamInfoStandard, &wfsdStreamInfo, 0);
1445 }
1446 else
1447 {
1448 hStreams = INVALID_HANDLE_VALUE;
1449 ERR("FindFirstStreamW not supported!\n");
1450 }
1451
1452 if (hStreams != INVALID_HANDLE_VALUE)
1453 {
1454 /* We totally ignore first stream. It contains data about ::$DATA */
1455 ptrCurNode = &ptrNextNode->ptrNext->stInfo.ptrHead;
1456 while (pFindNextStreamW(hStreams, &wfsdStreamInfo))
1457 {
1458 *ptrCurNode = cmd_alloc(sizeof(DIRFINDSTREAMNODE));
1459 if (*ptrCurNode == NULL)
1460 {
1461 WARN("Cannot allocate memory for *ptrCurNode!\n");
1462 DirNodeCleanup(ptrStartNode, &dwCount);
1463 FindClose(hStreams);
1464 FindClose(hSearch);
1465 return 1;
1466 }
1467
1468 memcpy(&(*ptrCurNode)->stStreamInfo, &wfsdStreamInfo,
1469 sizeof(WIN32_FIND_STREAM_DATA));
1470
1471 /* If lower case is selected do it here */
1472 if (lpFlags->bLowerCase)
1473 {
1474 _tcslwr((*ptrCurNode)->stStreamInfo.cStreamName);
1475 }
1476
1477 ptrCurNode = &(*ptrCurNode)->ptrNext;
1478 }
1479
1480 FindClose(hStreams);
1481 *ptrCurNode = NULL;
1482 }
1483 }
1484
1485 /* Continue at next node at linked list */
1486 ptrNextNode = ptrNextNode->ptrNext;
1487 dwCount++;
1488
1489 /* Grab statistics */
1490 if (wfdFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1491 {
1492 /* Directory */
1493 dwCountDirs++;
1494 }
1495 else
1496 {
1497 /* File */
1498 dwCountFiles++;
1499 u64Temp.HighPart = wfdFileInfo.nFileSizeHigh;
1500 u64Temp.LowPart = wfdFileInfo.nFileSizeLow;
1501 u64CountBytes += u64Temp.QuadPart;
1502 }
1503 }
1504 } while (FindNextFile(hSearch, &wfdFileInfo));
1505 FindClose(hSearch);
1506 }
1507
1508 /* Terminate list */
1509 ptrNextNode->ptrNext = NULL;
1510
1511 /* Calculate and allocate space need for making an array of pointers */
1512 ptrFileArray = cmd_alloc(sizeof(PDIRFINDINFO) * dwCount);
1513 if (ptrFileArray == NULL)
1514 {
1515 WARN("Cannot allocate memory for ptrFileArray!\n");
1516 DirNodeCleanup(ptrStartNode, &dwCount);
1517 return 1;
1518 }
1519
1520 /*
1521 * Create an array of pointers from the linked list
1522 * this will be used to sort and print data, rather than the list
1523 */
1524 ptrNextNode = ptrStartNode;
1525 dwCount = 0;
1526 while (ptrNextNode->ptrNext)
1527 {
1528 ptrFileArray[dwCount] = &ptrNextNode->ptrNext->stInfo;
1529 ptrNextNode = ptrNextNode->ptrNext;
1530 dwCount++;
1531 }
1532
1533 /* Sort Data if requested */
1534 if (lpFlags->stOrderBy.sCriteriaCount > 0)
1535 QsortFiles(ptrFileArray, 0, dwCount-1, lpFlags);
1536
1537 /* Print Data */
1538 cPathSep = pszFilePart[-1];
1539 pszFilePart[-1] = _T('\0'); /* Truncate to directory name only */
1540 DirPrintFiles(ptrFileArray, dwCount, szFullPath, lpFlags);
1541
1542 if (lpFlags->bRecursive)
1543 {
1544 PrintSummary(szFullPath,
1545 dwCountFiles,
1546 dwCountDirs,
1547 u64CountBytes,
1548 lpFlags,
1549 FALSE);
1550 }
1551 pszFilePart[-1] = cPathSep;
1552
1553 /* Free array */
1554 cmd_free(ptrFileArray);
1555
1556 /* Free linked list */
1557 DirNodeCleanup(ptrStartNode, &dwCount);
1558
1560 return 1;
1561
1562 /* Add statistics to recursive statistics */
1563 recurse_dir_cnt += dwCountDirs;
1564 recurse_file_cnt += dwCountFiles;
1565 recurse_bytes += u64CountBytes;
1566
1567 /*
1568 * Do the recursive job if requested.
1569 * The recursion is done on ALL (independent of their attributes)
1570 * directories of the current one.
1571 */
1572 if (lpFlags->bRecursive)
1573 {
1574 /* The new search is involving any *.* file */
1575 memcpy(szSubPath, szFullPath, (pszFilePart - szFullPath) * sizeof(TCHAR));
1576 _tcscpy(&szSubPath[pszFilePart - szFullPath], _T("*.*"));
1577
1578 hRecSearch = FindFirstFile(szSubPath, &wfdFileInfo);
1579 if (hRecSearch != INVALID_HANDLE_VALUE)
1580 {
1581 do
1582 {
1583 /* We search for directories other than "." and ".." */
1584 if (!IsDotDirectory(wfdFileInfo.cFileName) &&
1585 (wfdFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
1586 {
1587 /* Concat the path and the directory to do recursive */
1588 memcpy(szSubPath, szFullPath, (pszFilePart - szFullPath) * sizeof(TCHAR));
1589 _tcscpy(&szSubPath[pszFilePart - szFullPath], wfdFileInfo.cFileName);
1590 _tcscat(szSubPath, _T("\\"));
1591 pszSubFilePart = &szSubPath[_tcslen(szSubPath)];
1592 _tcscat(pszSubFilePart, pszFilePart);
1593
1594 /* We do the same for the directory */
1595 if (DirList(szSubPath, pszSubFilePart, lpFlags) != 0)
1596 {
1597 FindClose(hRecSearch);
1598 return 1;
1599 }
1600 }
1601 } while (FindNextFile(hRecSearch, &wfdFileInfo));
1602 }
1603 FindClose(hRecSearch);
1604 }
1605
1606 return 0;
1607}
static VOID DirNodeCleanup(PDIRFINDLISTNODE ptrStartNode, PDWORD pdwCount)
Definition: dir.c:1331
FORCEINLINE BOOL IsDotDirectory(IN LPCTSTR pszPath)
Definition: dir.c:239
static VOID QsortFiles(PDIRFINDINFO ptrArray[], int i, int j, LPDIRSWITCHFLAGS lpFlags)
Definition: dir.c:1293
static VOID DirPrintFiles(PDIRFINDINFO ptrFiles[], DWORD dwCount, LPCTSTR szCurPath, LPDIRSWITCHFLAGS lpFlags)
Definition: dir.c:1136
#define WARN(fmt,...)
Definition: debug.h:112
#define ERR(fmt,...)
Definition: debug.h:110
#define cmd_free(ptr)
Definition: cmddbg.h:31
#define cmd_alloc(size)
Definition: cmddbg.h:29
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502
unsigned long DWORD
Definition: ntddk_ex.h:95
#define _tcscat
Definition: tchar.h:622
#define _tcslwr
Definition: tchar.h:1465
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define BOOL
Definition: nt_native.h:43
#define DWORD
Definition: nt_native.h:44
#define LPVOID
Definition: nt_native.h:45
PDIRFINDSTREAMNODE ptrHead
Definition: dir.c:206
DIRFINDINFO stInfo
Definition: dir.c:211
struct _DIRFINDLISTNODE * ptrNext
Definition: dir.c:212
struct _DIRFINDSTREAMNODE * ptrNext
Definition: dir.c:200
void * PVOID
Definition: typedefs.h:50
PVOID HANDLE
Definition: typedefs.h:73
uint64_t ULONGLONG
Definition: typedefs.h:67
#define GetModuleHandle
Definition: winbase.h:3698
#define FindNextFile
Definition: winbase.h:3659
#define FindFirstFile
Definition: winbase.h:3653
#define WINAPI
Definition: msvc.h:6
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define _tcslen
Definition: xmlstorage.h:198

Referenced by CommandDir(), and DirList().

◆ DirNodeCleanup()

static VOID DirNodeCleanup ( PDIRFINDLISTNODE  ptrStartNode,
PDWORD  pdwCount 
)
static

Definition at line 1331 of file dir.c.

1333{
1334 PDIRFINDLISTNODE ptrNextNode;
1335 PDIRFINDSTREAMNODE ptrFreeNode;
1336 while (ptrStartNode)
1337 {
1338 ptrNextNode = ptrStartNode->ptrNext;
1339 while (ptrStartNode->stInfo.ptrHead)
1340 {
1341 ptrFreeNode = ptrStartNode->stInfo.ptrHead;
1342 ptrStartNode->stInfo.ptrHead = ptrFreeNode->ptrNext;
1343 cmd_free(ptrFreeNode);
1344 }
1345 cmd_free(ptrStartNode);
1346 ptrStartNode = ptrNextNode;
1347 --(*pdwCount);
1348 }
1349}

Referenced by DirList().

◆ DirPrintBareList()

static VOID DirPrintBareList ( PDIRFINDINFO  ptrFiles[],
DWORD  dwCount,
LPCTSTR  szCurPath,
LPDIRSWITCHFLAGS  lpFlags 
)
static

Definition at line 1102 of file dir.c.

1106{
1107 DWORD i;
1108
1109 for (i = 0; i < dwCount && !CheckCtrlBreak(BREAK_INPUT); i++)
1110 {
1111 if (IsDotDirectory(ptrFiles[i]->stFindInfo.cFileName))
1112 {
1113 /* At bare format we don't print the dot-directories "." and ".." */
1114 continue;
1115 }
1116 if (lpFlags->bRecursive)
1117 {
1118 /* At recursive mode we print full path of file */
1119 DirPrintf(lpFlags, _T("%s\\%s\n"), szCurPath, ptrFiles[i]->stFindInfo.cFileName);
1120 }
1121 else
1122 {
1123 /* If we are not in recursive mode we print the file names */
1124 DirPrintf(lpFlags, _T("%s\n"), ptrFiles[i]->stFindInfo.cFileName);
1125 }
1126 }
1127}
static BOOL DirPrintf(LPDIRSWITCHFLAGS lpFlags, LPTSTR szFormat,...)
Definition: dir.c:577

Referenced by DirPrintFiles().

◆ DirPrintf()

static BOOL DirPrintf ( LPDIRSWITCHFLAGS  lpFlags,
LPTSTR  szFormat,
  ... 
)
static

Definition at line 577 of file dir.c.

578{
579 BOOL Done = TRUE;
580 va_list arg_ptr;
581 va_start(arg_ptr, szFormat);
582 if (lpFlags->bPause)
583 Done = ConPrintfVPaging(&StdOutPager, FALSE, szFormat, arg_ptr);
584 else
585 ConPrintfV(StdOut, szFormat, arg_ptr);
586 va_end(arg_ptr);
587 return Done;
588}
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
#define StdOut
Definition: fc.c:14
CON_PAGER StdOutPager
Definition: console.c:30
BOOL ConPrintfVPaging(PCON_PAGER Pager, BOOL StartPaging, LPTSTR szFormat, va_list arg_ptr)
Definition: console.c:155
INT ConPrintfV(IN PCON_STREAM Stream, IN PCWSTR szStr, IN va_list args)
Definition: outstream.c:466

Referenced by DirPrintBareList(), DirPrintFiles(), DirPrintNewList(), DirPrintOldList(), DirPrintWideList(), PrintDirectoryHeader(), and PrintSummary().

◆ DirPrintFileDateTime()

static VOID DirPrintFileDateTime ( TCHAR lpDate,
TCHAR lpTime,
LPWIN32_FIND_DATA  lpFile,
LPDIRSWITCHFLAGS  lpFlags 
)
static

Definition at line 639 of file dir.c.

643{
644 FILETIME ft;
645 SYSTEMTIME dt;
646
647 /* Select the right time field */
648 switch (lpFlags->stTimeField.eTimeField)
649 {
650 case TF_CREATIONDATE:
651 if (!FileTimeToLocalFileTime(&lpFile->ftCreationTime, &ft))
652 return;
653 FileTimeToSystemTime(&ft, &dt);
654 break;
655
657 if (!FileTimeToLocalFileTime(&lpFile->ftLastAccessTime, &ft))
658 return;
659 FileTimeToSystemTime(&ft, &dt);
660 break;
661
662 case TF_MODIFIEDDATE:
663 if (!FileTimeToLocalFileTime(&lpFile->ftLastWriteTime, &ft))
664 return;
665 FileTimeToSystemTime(&ft, &dt);
666 break;
667 }
668
669 FormatDate(lpDate, &dt, lpFlags->b4Digit);
670 FormatTime(lpTime, &dt);
671}
INT FormatTime(TCHAR *lpTime, LPSYSTEMTIME dt)
Definition: dir.c:703
INT FormatDate(TCHAR *lpDate, LPSYSTEMTIME dt, BOOL b4Digit)
Definition: dir.c:674
BOOL WINAPI FileTimeToSystemTime(IN CONST FILETIME *lpFileTime, OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:188
BOOL WINAPI FileTimeToLocalFileTime(IN CONST FILETIME *lpFileTime, OUT LPFILETIME lpLocalFileTime)
Definition: time.c:221

Referenced by DirPrintNewList(), and DirPrintOldList().

◆ DirPrintFiles()

static VOID DirPrintFiles ( PDIRFINDINFO  ptrFiles[],
DWORD  dwCount,
LPCTSTR  szCurPath,
LPDIRSWITCHFLAGS  lpFlags 
)
static

Definition at line 1136 of file dir.c.

1140{
1142 TCHAR szTemp[MAX_PATH]; /* A buffer to format the directory header */
1143
1144 /* Print trailing backslash for root directory of drive */
1145 _tcscpy(szTemp, szCurPath);
1146 if (_tcslen(szTemp) == 2 && szTemp[1] == _T(':'))
1147 _tcscat(szTemp, _T("\\"));
1148
1149 /* Condition to print header:
1150 We are not printing in bare format
1151 and if we are in recursive mode... we must have results */
1152 if (!lpFlags->bBareFormat && !(lpFlags->bRecursive && (dwCount <= 0)))
1153 {
1155 if (!DirPrintf(lpFlags, szMsg, szTemp))
1156 return;
1157 }
1158
1159 if (lpFlags->bBareFormat)
1160 {
1161 /* Bare format */
1162 DirPrintBareList(ptrFiles, dwCount, szCurPath, lpFlags);
1163 }
1164 else if (lpFlags->bShortName)
1165 {
1166 /* New list style / Short names */
1167 DirPrintNewList(ptrFiles, dwCount, szCurPath, lpFlags);
1168 }
1169 else if (lpFlags->bWideListColSort || lpFlags->bWideList)
1170 {
1171 /* Wide list */
1172 DirPrintWideList(ptrFiles, dwCount, szCurPath, lpFlags);
1173 }
1174 else if (lpFlags->bNewLongList )
1175 {
1176 /* New list style*/
1177 DirPrintNewList(ptrFiles, dwCount, szCurPath, lpFlags);
1178 }
1179 else
1180 {
1181 /* If nothing is selected old list is the default */
1182 DirPrintOldList(ptrFiles, dwCount, szCurPath, lpFlags);
1183 }
1184}
#define RC_STRING_MAX_SIZE
Definition: resource.h:3
HANDLE CMD_ModuleHandle
Definition: cmd.c:165
static VOID DirPrintNewList(PDIRFINDINFO ptrFiles[], DWORD dwCount, LPCTSTR szCurPath, LPDIRSWITCHFLAGS lpFlags)
Definition: dir.c:873
static VOID DirPrintOldList(PDIRFINDINFO ptrFiles[], DWORD dwCount, LPCTSTR szCurPath, LPDIRSWITCHFLAGS lpFlags)
Definition: dir.c:1037
static VOID DirPrintWideList(PDIRFINDINFO ptrFiles[], DWORD dwCount, LPCTSTR szCurPath, LPDIRSWITCHFLAGS lpFlags)
Definition: dir.c:955
static VOID DirPrintBareList(PDIRFINDINFO ptrFiles[], DWORD dwCount, LPCTSTR szCurPath, LPDIRSWITCHFLAGS lpFlags)
Definition: dir.c:1102
#define STRING_DIR_HELP7
Definition: resource.h:112
#define LoadString
Definition: winuser.h:5809

Referenced by DirList().

◆ DirPrintNewList()

static VOID DirPrintNewList ( PDIRFINDINFO  ptrFiles[],
DWORD  dwCount,
LPCTSTR  szCurPath,
LPDIRSWITCHFLAGS  lpFlags 
)
static

Definition at line 873 of file dir.c.

877{
878 DWORD i;
879 TCHAR szSize[30];
880 TCHAR szShortName[15];
881 TCHAR szDate[20];
882 TCHAR szTime[20];
883 INT iSizeFormat;
884 ULARGE_INTEGER u64FileSize;
885 PDIRFINDSTREAMNODE ptrCurStream;
886
887 for (i = 0; i < dwCount && !CheckCtrlBreak(BREAK_INPUT); i++)
888 {
889 /* Calculate size */
890 if (ptrFiles[i]->stFindInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
891 {
892 /* Junction */
893 iSizeFormat = -14;
894 _tcscpy(szSize, _T("<JUNCTION>"));
895 }
896 else if (ptrFiles[i]->stFindInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
897 {
898 /* Directory */
899 iSizeFormat = -14;
900 _tcscpy(szSize, _T("<DIR>"));
901 }
902 else
903 {
904 /* File */
905 iSizeFormat = 14;
906 u64FileSize.HighPart = ptrFiles[i]->stFindInfo.nFileSizeHigh;
907 u64FileSize.LowPart = ptrFiles[i]->stFindInfo.nFileSizeLow;
908 ConvertULargeInteger(u64FileSize.QuadPart, szSize, 20, lpFlags->bTSeparator);
909 }
910
911 /* Calculate short name */
912 szShortName[0] = _T('\0');
913 if (lpFlags->bShortName)
914 _stprintf(szShortName, _T(" %-12s"), ptrFiles[i]->stFindInfo.cAlternateFileName);
915
916 /* Format date and time */
917 DirPrintFileDateTime(szDate, szTime, &ptrFiles[i]->stFindInfo, lpFlags);
918
919 /* Print the line */
920 DirPrintf(lpFlags, _T("%10s %-6s %*s%s %s\n"),
921 szDate,
922 szTime,
923 iSizeFormat,
924 szSize,
925 szShortName,
926 ptrFiles[i]->stFindInfo.cFileName);
927
928 /* Now, loop on the streams */
929 ptrCurStream = ptrFiles[i]->ptrHead;
930 while (ptrCurStream)
931 {
932 ConvertULargeInteger(ptrCurStream->stStreamInfo.StreamSize.QuadPart, szSize, 20, lpFlags->bTSeparator);
933
934 /* Print the line */
935 DirPrintf(lpFlags, _T("%10s %-6s %*s%s %s%s\n"),
936 L"",
937 L"",
938 16,
939 szSize,
940 L"",
941 ptrFiles[i]->stFindInfo.cFileName,
942 ptrCurStream->stStreamInfo.cStreamName);
943 ptrCurStream = ptrCurStream->ptrNext;
944 }
945 }
946}
INT ConvertULargeInteger(ULONGLONG num, LPTSTR des, UINT len, BOOL bPutSeparator)
Definition: cmd.c:189
static VOID DirPrintFileDateTime(TCHAR *lpDate, TCHAR *lpTime, LPWIN32_FIND_DATA lpFile, LPDIRSWITCHFLAGS lpFlags)
Definition: dir.c:639
#define _stprintf
Definition: utility.h:124
#define FILE_ATTRIBUTE_REPARSE_POINT
Definition: ntifs_ex.h:381
TCHAR szTime[64]
Definition: solitaire.cpp:19
WIN32_FIND_STREAM_DATA stStreamInfo
Definition: dir.c:199

Referenced by DirPrintFiles().

◆ DirPrintOldList()

static VOID DirPrintOldList ( PDIRFINDINFO  ptrFiles[],
DWORD  dwCount,
LPCTSTR  szCurPath,
LPDIRSWITCHFLAGS  lpFlags 
)
static

Definition at line 1037 of file dir.c.

1041{
1042 DWORD i; /* An indexer for "for"s */
1043 TCHAR szName[10]; /* The name of file */
1044 TCHAR szExt[5]; /* The extension of file */
1045 TCHAR szDate[30],szTime[30]; /* Used to format time and date */
1046 TCHAR szSize[30]; /* The size of file */
1047 int iSizeFormat; /* The format of size field */
1048 ULARGE_INTEGER u64FileSize; /* The file size */
1049
1050 for (i = 0; i < dwCount && !CheckCtrlBreak(BREAK_INPUT); i++)
1051 {
1052 /* Broke 8.3 format */
1053 if (*ptrFiles[i]->stFindInfo.cAlternateFileName )
1054 {
1055 /* If the file is long named then we read the alter name */
1056 getName( ptrFiles[i]->stFindInfo.cAlternateFileName, szName);
1057 _tcscpy(szExt, getExt( ptrFiles[i]->stFindInfo.cAlternateFileName));
1058 }
1059 else
1060 {
1061 /* If the file is not long name we read its original name */
1062 getName( ptrFiles[i]->stFindInfo.cFileName, szName);
1063 _tcscpy(szExt, getExt( ptrFiles[i]->stFindInfo.cFileName));
1064 }
1065
1066 /* Calculate size */
1067 if (ptrFiles[i]->stFindInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1068 {
1069 /* Directory, no size it's a directory */
1070 iSizeFormat = -17;
1071 _tcscpy(szSize, _T("<DIR>"));
1072 }
1073 else
1074 {
1075 /* File */
1076 iSizeFormat = 17;
1077 u64FileSize.HighPart = ptrFiles[i]->stFindInfo.nFileSizeHigh;
1078 u64FileSize.LowPart = ptrFiles[i]->stFindInfo.nFileSizeLow;
1079 ConvertULargeInteger(u64FileSize.QuadPart, szSize, 20, lpFlags->bTSeparator);
1080 }
1081
1082 /* Format date and time */
1083 DirPrintFileDateTime(szDate,szTime,&ptrFiles[i]->stFindInfo,lpFlags);
1084
1085 /* Print the line */
1086 DirPrintf(lpFlags, _T("%-8s %-3s %*s %s %s\n"),
1087 szName, /* The file's 8.3 name */
1088 szExt, /* The file's 8.3 extension */
1089 iSizeFormat, /* print format for size column */
1090 szSize, /* The size of file or "<DIR>" for dirs */
1091 szDate, /* The date of file/dir */
1092 szTime); /* The time of file/dir */
1093 }
1094}
static LPTSTR getName(const TCHAR *file, TCHAR *dest)
Definition: dir.c:842
static const WCHAR szName[]
Definition: powrprof.c:45

Referenced by DirPrintFiles().

◆ DirPrintWideList()

static VOID DirPrintWideList ( PDIRFINDINFO  ptrFiles[],
DWORD  dwCount,
LPCTSTR  szCurPath,
LPDIRSWITCHFLAGS  lpFlags 
)
static

Definition at line 955 of file dir.c.

959{
960 SHORT iScreenWidth;
961 USHORT iColumns;
962 USHORT iLines;
963 UINT_PTR iLongestName;
964 TCHAR szTempFname[MAX_PATH];
965 DWORD i;
966 DWORD j;
967 DWORD temp;
968
969 /* Calculate longest name */
970 iLongestName = 1;
971 for (i = 0; i < dwCount; i++)
972 {
973 if (ptrFiles[i]->stFindInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
974 {
975 /* Directories need 2 additional characters for brackets */
976 if ((_tcslen(ptrFiles[i]->stFindInfo.cFileName) + 2) > iLongestName)
977 iLongestName = _tcslen(ptrFiles[i]->stFindInfo.cFileName) + 2;
978 }
979 else
980 {
981 if (_tcslen(ptrFiles[i]->stFindInfo.cFileName) > iLongestName)
982 iLongestName = _tcslen(ptrFiles[i]->stFindInfo.cFileName);
983 }
984 }
985
986 /* Count the highest number of columns */
987 GetScreenSize(&iScreenWidth, NULL);
988 iColumns = (USHORT)(iScreenWidth / iLongestName);
989
990 /* Check if there is enough space for spaces between names */
991 if (((iLongestName * iColumns) + iColumns) >= (UINT)iScreenWidth)
992 iColumns --;
993
994 /* A last check at iColumns to avoid division by zero */
995 if (!iColumns) iColumns = 1;
996
997 /* Calculate the lines that will be printed */
998 iLines = (USHORT)((dwCount + iColumns - 1) / iColumns);
999
1000 for (i = 0; i < iLines && !CheckCtrlBreak(BREAK_INPUT); i++)
1001 {
1002 for (j = 0; j < iColumns; j++)
1003 {
1004 if (lpFlags->bWideListColSort)
1005 {
1006 /* Print Column sorted */
1007 temp = (j * iLines) + i;
1008 }
1009 else
1010 {
1011 /* Print Line sorted */
1012 temp = (i * iColumns) + j;
1013 }
1014
1015 if (temp >= dwCount) break;
1016
1017 if (ptrFiles[temp]->stFindInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1018 _stprintf(szTempFname, _T("[%s]"), ptrFiles[temp]->stFindInfo.cFileName);
1019 else
1020 _stprintf(szTempFname, _T("%s"), ptrFiles[temp]->stFindInfo.cFileName);
1021
1022 DirPrintf(lpFlags, _T("%-*s"), iLongestName + 1, szTempFname);
1023 }
1024
1025 /* Add a new line after the last item in the column */
1026 DirPrintf(lpFlags, _T("\n"));
1027 }
1028}
VOID GetScreenSize(PSHORT maxx, PSHORT maxy)
Definition: console.c:236
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
short SHORT
Definition: pedump.c:59
unsigned short USHORT
Definition: pedump.c:61
static calc_node_t temp
Definition: rpn_ieee.c:38

Referenced by DirPrintFiles().

◆ DirReadParam()

static BOOL DirReadParam ( LPTSTR  Line,
LPTSTR **  params,
LPINT  entries,
LPDIRSWITCHFLAGS  lpFlags 
)
static

Definition at line 264 of file dir.c.

268{
269 TCHAR cCurSwitch; /* The current switch */
270 TCHAR cCurChar; /* Current examined character */
271 TCHAR cCurUChar; /* Current upper examined character */
272 BOOL bNegative; /* Negative switch */
273 BOOL bPNegative; /* Negative switch parameter */
274 BOOL bIntoQuotes; /* A flag showing if we are in quotes (") */
275 LPTSTR ptrStart; /* A pointer to the first character of a parameter */
276 LPTSTR ptrEnd; /* A pointer to the last character of a parameter */
277 BOOL bOrderByNoPar; /* A flag to indicate /O with no switch parameter */
278 LPTSTR temp;
279
280 /* Initialize parameter array */
281 *params = NULL;
282 *entries = 0;
283
284 /* Initialize variables; */
285 cCurSwitch = _T(' ');
286 bNegative = FALSE;
287 bPNegative = FALSE;
288
289 /* We suppose that switch parameters
290 were given to avoid setting them to default
291 if the switch was not given */
292 bOrderByNoPar = FALSE;
293
294 /* Main Loop (see README_DIR.txt) */
295 /* scan the command line char per char, and we process its char */
296 while (*Line)
297 {
298 /* we save current character as it is and its upper case */
299 cCurChar = *Line;
300 cCurUChar = _totupper(*Line);
301
302 /* 1st section (see README_DIR.txt) */
303 /* When a switch is expecting */
304 if (cCurSwitch == _T('/'))
305 {
306 while (_istspace(*Line))
307 Line++;
308
309 bNegative = (*Line == _T('-'));
310 Line += bNegative;
311
312 cCurChar = *Line;
313 cCurUChar = _totupper(*Line);
314
315 if ((cCurUChar == _T('A')) ||(cCurUChar == _T('T')) || (cCurUChar == _T('O')))
316 {
317 /* If positive, prepare for parameters... if negative, reset to defaults */
318 switch (cCurUChar)
319 {
320 case _T('A'):
321 lpFlags->stAttribs.dwAttribVal = 0L;
322 lpFlags->stAttribs.dwAttribMask = 0L;
323 if (bNegative)
324 lpFlags->stAttribs.dwAttribMask = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
325 break;
326 case _T('T'):
327 if (bNegative)
328 lpFlags->stTimeField.eTimeField = TF_MODIFIEDDATE;
329 break;
330 case _T('O'):
331 bOrderByNoPar = !bNegative;
332 lpFlags->stOrderBy.sCriteriaCount = 0;
333 break;
334 }
335
336 if (!bNegative)
337 {
338 /* Positive switch, so it can take parameters. */
339 cCurSwitch = cCurUChar;
340 Line++;
341 /* Skip optional leading colon */
342 if (*Line == _T(':'))
343 Line++;
344 continue;
345 }
346 }
347 else if (cCurUChar == _T('L'))
348 lpFlags->bLowerCase = ! bNegative;
349 else if (cCurUChar == _T('B'))
350 lpFlags->bBareFormat = ! bNegative;
351 else if (cCurUChar == _T('C'))
352 lpFlags->bTSeparator = ! bNegative;
353 else if (cCurUChar == _T('W'))
354 lpFlags->bWideList = ! bNegative;
355 else if (cCurUChar == _T('D'))
356 lpFlags->bWideListColSort = ! bNegative;
357 else if (cCurUChar == _T('N'))
358 lpFlags->bNewLongList = ! bNegative;
359 else if (cCurUChar == _T('P'))
360 lpFlags->bPause = ! bNegative;
361 else if (cCurUChar == _T('Q'))
362 lpFlags->bUser = ! bNegative;
363 else if (cCurUChar == _T('S'))
364 lpFlags->bRecursive = ! bNegative;
365 else if (cCurUChar == _T('X'))
366 lpFlags->bShortName = ! bNegative;
367 else if (cCurUChar == _T('R'))
368 lpFlags->bDataStreams = ! bNegative;
369 else if (cCurChar == _T('4'))
370 lpFlags->b4Digit = ! bNegative;
371 else if (cCurChar == _T('?'))
372 {
373 DirHelp();
374 return FALSE;
375 }
376 else
377 {
379 return FALSE;
380 }
381
382 /* Make sure there's no extra characters at the end of the switch */
383 if (Line[1] && Line[1] != _T('/') && !_istspace(Line[1]))
384 {
386 return FALSE;
387 }
388
389 cCurSwitch = _T(' ');
390 }
391 else if (cCurSwitch == _T(' '))
392 {
393 /* 2nd section (see README_DIR.txt) */
394 /* We are expecting parameter or the unknown */
395
396 if (cCurChar == _T('/'))
397 cCurSwitch = _T('/');
398 else if (_istspace(cCurChar))
399 /* do nothing */;
400 else
401 {
402 /* This is a file/directory name parameter. Find its end */
403 ptrStart = Line;
404 bIntoQuotes = FALSE;
405 while (*Line)
406 {
407 if (!bIntoQuotes && (*Line == _T('/') || _istspace(*Line)))
408 break;
409 bIntoQuotes ^= (*Line == _T('"'));
410 Line++;
411 }
412 ptrEnd = Line;
413
414 /* Copy it to the entries list */
415 temp = cmd_alloc((ptrEnd - ptrStart + 1) * sizeof(TCHAR));
416 if (!temp)
417 return FALSE;
418 memcpy(temp, ptrStart, (ptrEnd - ptrStart) * sizeof(TCHAR));
419 temp[ptrEnd - ptrStart] = _T('\0');
421 if (!add_entry(entries, params, temp))
422 {
423 cmd_free(temp);
424 freep(*params);
425 return FALSE;
426 }
427
428 cmd_free(temp);
429 continue;
430 }
431 }
432 else
433 {
434 /* 3rd section (see README_DIR.txt) */
435 /* We are waiting for switch parameters */
436
437 /* Check if there are no more switch parameters */
438 if ((cCurChar == _T('/')) || _istspace(cCurChar))
439 {
440 /* Wrong decision path, reprocess current character */
441 cCurSwitch = _T(' ');
442 continue;
443 }
444 /* Process parameter switch */
445 switch (cCurSwitch)
446 {
447 case _T('A'): /* Switch parameters for /A (attributes filter) */
448 if (cCurChar == _T('-'))
449 bPNegative = TRUE;
450 else if (cCurUChar == _T('D'))
451 {
452 lpFlags->stAttribs.dwAttribMask |= FILE_ATTRIBUTE_DIRECTORY;
453 if (bPNegative)
454 lpFlags->stAttribs.dwAttribVal &= ~FILE_ATTRIBUTE_DIRECTORY;
455 else
456 lpFlags->stAttribs.dwAttribVal |= FILE_ATTRIBUTE_DIRECTORY;
457 }
458 else if (cCurUChar == _T('R'))
459 {
460 lpFlags->stAttribs.dwAttribMask |= FILE_ATTRIBUTE_READONLY;
461 if (bPNegative)
462 lpFlags->stAttribs.dwAttribVal &= ~FILE_ATTRIBUTE_READONLY;
463 else
464 lpFlags->stAttribs.dwAttribVal |= FILE_ATTRIBUTE_READONLY;
465 }
466 else if (cCurUChar == _T('H'))
467 {
468 lpFlags->stAttribs.dwAttribMask |= FILE_ATTRIBUTE_HIDDEN;
469 if (bPNegative)
470 lpFlags->stAttribs.dwAttribVal &= ~FILE_ATTRIBUTE_HIDDEN;
471 else
472 lpFlags->stAttribs.dwAttribVal |= FILE_ATTRIBUTE_HIDDEN;
473 }
474 else if (cCurUChar == _T('A'))
475 {
476 lpFlags->stAttribs.dwAttribMask |= FILE_ATTRIBUTE_ARCHIVE;
477 if (bPNegative)
478 lpFlags->stAttribs.dwAttribVal &= ~FILE_ATTRIBUTE_ARCHIVE;
479 else
480 lpFlags->stAttribs.dwAttribVal |= FILE_ATTRIBUTE_ARCHIVE;
481 }
482 else if (cCurUChar == _T('S'))
483 {
484 lpFlags->stAttribs.dwAttribMask |= FILE_ATTRIBUTE_SYSTEM;
485 if (bPNegative)
486 lpFlags->stAttribs.dwAttribVal &= ~FILE_ATTRIBUTE_SYSTEM;
487 else
488 lpFlags->stAttribs.dwAttribVal |= FILE_ATTRIBUTE_SYSTEM;
489 }
490 else
491 {
493 return FALSE;
494 }
495 break;
496 case _T('T'): /* Switch parameters for /T (time field) */
497 if (cCurUChar == _T('C'))
498 lpFlags->stTimeField.eTimeField= TF_CREATIONDATE ;
499 else if (cCurUChar == _T('A'))
500 lpFlags->stTimeField.eTimeField= TF_LASTACCESSEDDATE ;
501 else if (cCurUChar == _T('W'))
502 lpFlags->stTimeField.eTimeField= TF_MODIFIEDDATE ;
503 else
504 {
506 return FALSE;
507 }
508 break;
509 case _T('O'): /* Switch parameters for /O (order) */
510 /* Ok a switch parameter was given */
511 bOrderByNoPar = FALSE;
512
513 if (cCurChar == _T('-'))
514 bPNegative = TRUE;
515 else if (cCurUChar == _T('N'))
516 {
517 if (lpFlags->stOrderBy.sCriteriaCount < 3) lpFlags->stOrderBy.sCriteriaCount++;
518 lpFlags->stOrderBy.bCriteriaRev[lpFlags->stOrderBy.sCriteriaCount - 1] = bPNegative;
519 lpFlags->stOrderBy.eCriteria[lpFlags->stOrderBy.sCriteriaCount - 1] = ORDER_NAME;
520 }
521 else if (cCurUChar == _T('S'))
522 {
523 if (lpFlags->stOrderBy.sCriteriaCount < 3) lpFlags->stOrderBy.sCriteriaCount++;
524 lpFlags->stOrderBy.bCriteriaRev[lpFlags->stOrderBy.sCriteriaCount - 1] = bPNegative;
525 lpFlags->stOrderBy.eCriteria[lpFlags->stOrderBy.sCriteriaCount - 1] = ORDER_SIZE;
526 }
527 else if (cCurUChar == _T('G'))
528 {
529 if (lpFlags->stOrderBy.sCriteriaCount < 3) lpFlags->stOrderBy.sCriteriaCount++;
530 lpFlags->stOrderBy.bCriteriaRev[lpFlags->stOrderBy.sCriteriaCount - 1] = bPNegative;
531 lpFlags->stOrderBy.eCriteria[lpFlags->stOrderBy.sCriteriaCount - 1] = ORDER_DIRECTORY;
532 }
533 else if (cCurUChar == _T('E'))
534 {
535 if (lpFlags->stOrderBy.sCriteriaCount < 3) lpFlags->stOrderBy.sCriteriaCount++;
536 lpFlags->stOrderBy.bCriteriaRev[lpFlags->stOrderBy.sCriteriaCount - 1] = bPNegative;
537 lpFlags->stOrderBy.eCriteria[lpFlags->stOrderBy.sCriteriaCount - 1] = ORDER_EXTENSION;
538 }
539 else if (cCurUChar == _T('D'))
540 {
541 if (lpFlags->stOrderBy.sCriteriaCount < 3) lpFlags->stOrderBy.sCriteriaCount++;
542 lpFlags->stOrderBy.bCriteriaRev[lpFlags->stOrderBy.sCriteriaCount - 1] = bPNegative;
543 lpFlags->stOrderBy.eCriteria[lpFlags->stOrderBy.sCriteriaCount - 1] = ORDER_TIME;
544 }
545
546 else
547 {
549 return FALSE;
550 }
551
552
553 }
554 /* We check if we calculated the negative value and release the flag */
555 if ((cCurChar != _T('-')) && bPNegative)
556 bPNegative = FALSE;
557 }
558
559 Line++;
560 }
561
562 /* /O with no switch parameters acts like /O:GN */
563 if (bOrderByNoPar)
564 {
565 lpFlags->stOrderBy.sCriteriaCount = 2;
566 lpFlags->stOrderBy.eCriteria[0] = ORDER_DIRECTORY;
567 lpFlags->stOrderBy.bCriteriaRev[0] = FALSE;
568 lpFlags->stOrderBy.eCriteria[1] = ORDER_NAME;
569 lpFlags->stOrderBy.bCriteriaRev[1] = FALSE;
570 }
571
572 return TRUE;
573}
VOID error_parameter_format(TCHAR ch)
Definition: error.c:65
VOID error_invalid_switch(TCHAR ch)
Definition: error.c:72
static VOID DirHelp(VOID)
Definition: dir.c:231
static VOID StripQuotes(LPSTR in)
Definition: cmdcons.c:116
#define _istspace
Definition: tchar.h:1504
#define _totupper
Definition: tchar.h:1509
if(dx< 0)
Definition: linetemp.h:194
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define FILE_ATTRIBUTE_ARCHIVE
Definition: nt_native.h:706
Definition: ncftp.h:79

Referenced by CommandDir().

◆ FormatDate()

INT FormatDate ( TCHAR lpDate,
LPSYSTEMTIME  dt,
BOOL  b4Digit 
)

Definition at line 674 of file dir.c.

675{
676 /* Format date */
677 WORD wYear = b4Digit ? dt->wYear : dt->wYear%100;
678 switch (nDateFormat)
679 {
680 case 0: /* mmddyy */
681 default:
682 return _stprintf(lpDate, _T("%02d%c%02d%c%0*d"),
684 dt->wDay, cDateSeparator,
685 b4Digit?4:2, wYear);
686 break;
687
688 case 1: /* ddmmyy */
689 return _stprintf(lpDate, _T("%02d%c%02d%c%0*d"),
690 dt->wDay, cDateSeparator, dt->wMonth,
691 cDateSeparator, b4Digit?4:2, wYear);
692 break;
693
694 case 2: /* yymmdd */
695 return _stprintf(lpDate, _T("%0*d%c%02d%c%02d"),
696 b4Digit?4:2, wYear, cDateSeparator,
697 dt->wMonth, cDateSeparator, dt->wDay);
698 break;
699 }
700}
TCHAR cDateSeparator
Definition: locale.c:16
INT nDateFormat
Definition: locale.c:20
unsigned short WORD
Definition: ntddk_ex.h:93
WORD wYear
Definition: winbase.h:905
WORD wMonth
Definition: winbase.h:906
WORD wDay
Definition: winbase.h:908

Referenced by DirPrintFileDateTime(), GetDateString(), and GetEnhancedVar().

◆ FormatTime()

INT FormatTime ( TCHAR lpTime,
LPSYSTEMTIME  dt 
)

Definition at line 703 of file dir.c.

704{
705 /* Format Time */
706 switch (nTimeFormat)
707 {
708 case 0: /* 12 hour format */
709 default:
710 return _stprintf(lpTime,_T("%02d%c%02u %cM"),
711 (dt->wHour == 0 ? 12 : (dt->wHour <= 12 ? dt->wHour : dt->wHour - 12)),
713 dt->wMinute, (dt->wHour <= 11 ? _T('A') : _T('P')));
714 break;
715
716 case 1: /* 24 hour format */
717 return _stprintf(lpTime, _T("%02d%c%02u"),
718 dt->wHour, cTimeSeparator, dt->wMinute);
719 break;
720 }
721}
INT nTimeFormat
Definition: locale.c:21
TCHAR cTimeSeparator
Definition: locale.c:17
WORD wHour
Definition: winbase.h:909
WORD wMinute
Definition: winbase.h:910

Referenced by cmd_time(), DirPrintFileDateTime(), and GetEnhancedVar().

◆ getExt()

TCHAR * getExt ( const TCHAR file)

Definition at line 829 of file dir.c.

830{
831 static TCHAR *NoExt = _T("");
832 TCHAR* lastdot = _tcsrchr(file, _T('.'));
833 return (lastdot != NULL ? lastdot + 1 : NoExt);
834}
#define _tcsrchr
Definition: utility.h:116
Definition: fci.c:127

Referenced by CompareFiles(), and DirPrintOldList().

◆ getName()

static LPTSTR getName ( const TCHAR file,
TCHAR dest 
)
static

Definition at line 842 of file dir.c.

843{
844 INT_PTR iLen;
845 LPTSTR end;
846
847 /* Check for dot-directories "." and ".." */
848 if (IsDotDirectory(file))
849 {
850 _tcscpy(dest, file);
851 return dest;
852 }
853
854 end = _tcsrchr(file, _T('.'));
855 if (!end)
856 iLen = _tcslen(file);
857 else
858 iLen = (end - file);
859
860 _tcsncpy(dest, file, iLen);
861 *(dest + iLen) = _T('\0');
862
863 return dest;
864}
GLuint GLuint end
Definition: gl.h:1545
#define _tcsncpy
Definition: tchar.h:1410
static char * dest
Definition: rtl.c:135
int32_t INT_PTR
Definition: typedefs.h:64

Referenced by DirPrintOldList().

◆ GetUserDiskFreeSpace()

static VOID GetUserDiskFreeSpace ( LPCTSTR  lpRoot,
PULARGE_INTEGER  lpFreeSpace 
)
static

Definition at line 725 of file dir.c.

727{
728 PGETFREEDISKSPACEEX pGetFreeDiskSpaceEx;
730 DWORD dwSecPerCl;
731 DWORD dwBytPerSec;
732 DWORD dwFreeCl;
733 DWORD dwTotCl;
734 ULARGE_INTEGER TotalNumberOfBytes, TotalNumberOfFreeBytes;
735
736 lpFreeSpace->QuadPart = 0;
737
738 hInstance = GetModuleHandle(_T("KERNEL32"));
739 if (hInstance != NULL)
740 {
741 pGetFreeDiskSpaceEx = (PGETFREEDISKSPACEEX)GetProcAddress(hInstance,
742#ifdef _UNICODE
743 "GetDiskFreeSpaceExW");
744#else
745 "GetDiskFreeSpaceExA");
746#endif
747 if (pGetFreeDiskSpaceEx != NULL)
748 {
749 if (pGetFreeDiskSpaceEx(lpRoot, lpFreeSpace, &TotalNumberOfBytes, &TotalNumberOfFreeBytes) != FALSE)
750 return;
751 }
752 }
753
754 GetDiskFreeSpace(lpRoot,
755 &dwSecPerCl,
756 &dwBytPerSec,
757 &dwFreeCl,
758 &dwTotCl);
759
760 lpFreeSpace->QuadPart = dwSecPerCl * dwBytPerSec * dwFreeCl;
761}
BOOL(WINAPI * PGETFREEDISKSPACEEX)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER)
Definition: dir.c:216
HINSTANCE hInstance
Definition: charmap.c:19
#define _UNICODE
Definition: textw.c:5
#define GetDiskFreeSpace
Definition: winbase.h:3678

Referenced by PrintSummary().

◆ IsDotDirectory()

FORCEINLINE BOOL IsDotDirectory ( IN LPCTSTR  pszPath)

Definition at line 239 of file dir.c.

241{
242 return ( pszPath[0] == _T('.') &&
243 ( pszPath[1] == 0 || /* pszPath[1] == _T('\\') || */
244 (pszPath[1] == _T('.') && (pszPath[2] == 0 /* || pszPath[2] == _T('\\') */))
245 ) );
246}

Referenced by DirList(), DirPrintBareList(), getName(), and ResolvePattern().

◆ IsDotDirectoryN()

FORCEINLINE BOOL IsDotDirectoryN ( IN const TCHAR pPath,
IN SIZE_T  Length 
)

Definition at line 250 of file dir.c.

253{
254 return ((Length == 1 && pPath[0] == _T('.')) ||
255 (Length == 2 && pPath[0] == _T('.') && pPath[1] == _T('.')));
256}
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102

Referenced by ResolvePattern().

◆ PrintDirectoryHeader()

static BOOL PrintDirectoryHeader ( LPCTSTR  szPath,
LPDIRSWITCHFLAGS  lpFlags 
)
static

Definition at line 597 of file dir.c.

598{
600 LPCTSTR szFullDir;
601 TCHAR szRootName[MAX_PATH];
602 TCHAR szVolName[80];
603 DWORD dwSerialNr;
604
605 if (lpFlags->bBareFormat)
606 return TRUE;
607
608 szFullDir = szPath;
609
610 /* Get the media ID of the drive */
611 if (!GetVolumePathName(szFullDir, szRootName, ARRAYSIZE(szRootName)) ||
612 !GetVolumeInformation(szRootName, szVolName, ARRAYSIZE(szVolName),
613 &dwSerialNr, NULL, NULL, NULL, 0))
614 {
615 return TRUE;
616 }
617
618 /* Print drive info */
619 if (szVolName[0] != _T('\0'))
620 {
622 DirPrintf(lpFlags, szMsg, _totupper(szRootName[0]), szVolName);
623 }
624 else
625 {
627 DirPrintf(lpFlags, szMsg, _totupper(szRootName[0]));
628 }
629
630 /* Print the volume serial number if the return was successful */
632 DirPrintf(lpFlags, szMsg, HIWORD(dwSerialNr), LOWORD(dwSerialNr));
633
634 return TRUE;
635}
#define STRING_DIR_HELP4
Definition: resource.h:109
#define STRING_DIR_HELP3
Definition: resource.h:108
#define STRING_DIR_HELP2
Definition: resource.h:107
LPCWSTR szPath
Definition: env.c:37
#define LOWORD(l)
Definition: pedump.c:82
#define HIWORD(l)
Definition: typedefs.h:247
#define GetVolumeInformation
Definition: winbase.h:3724
const CHAR * LPCTSTR
Definition: xmlstorage.h:193

Referenced by CommandDir().

◆ PrintSummary()

static INT PrintSummary ( LPCTSTR  szPath,
ULONG  ulFiles,
ULONG  ulDirs,
ULONGLONG  u64Bytes,
LPDIRSWITCHFLAGS  lpFlags,
BOOL  TotalSummary 
)
static

Definition at line 770 of file dir.c.

776{
778 TCHAR szBuffer[64];
779 ULARGE_INTEGER uliFree;
780
781 /* Here we check if we didn't find anything */
782 if (!(ulFiles + ulDirs))
783 {
784 if (!lpFlags->bRecursive || (TotalSummary && lpFlags->bRecursive))
786 return 1;
787 }
788
789 /* In bare format we don't print results */
790 if (lpFlags->bBareFormat)
791 return 0;
792
793 /* Print recursive specific results */
794
795 /* Take this code offline to fix /S does not print double info */
796 if (TotalSummary && lpFlags->bRecursive)
797 {
798 ConvertULargeInteger(u64Bytes, szBuffer, ARRAYSIZE(szBuffer), lpFlags->bTSeparator);
800 DirPrintf(lpFlags, szMsg, ulFiles, szBuffer);
801 }
802 else
803 {
804 /* Print File Summary */
805 /* Condition to print summary is:
806 If we are not in bare format and if we have results! */
807 ConvertULargeInteger(u64Bytes, szBuffer, ARRAYSIZE(szBuffer), lpFlags->bTSeparator);
809 DirPrintf(lpFlags, szMsg, ulFiles, szBuffer);
810 }
811
812 /* Print total directories and free space */
813 if (!lpFlags->bRecursive || TotalSummary)
814 {
815 GetUserDiskFreeSpace(szPath, &uliFree);
816 ConvertULargeInteger(uliFree.QuadPart, szBuffer, ARRAYSIZE(szBuffer), lpFlags->bTSeparator);
818 DirPrintf(lpFlags, szMsg, ulDirs, szBuffer);
819 }
820
821 return 0;
822}
VOID error_file_not_found(VOID)
Definition: error.c:93
static VOID GetUserDiskFreeSpace(LPCTSTR lpRoot, PULARGE_INTEGER lpFreeSpace)
Definition: dir.c:725
#define STRING_DIR_HELP8
Definition: resource.h:113
#define STRING_DIR_HELP6
Definition: resource.h:111
#define STRING_DIR_HELP5
Definition: resource.h:110

Referenced by CommandDir(), and DirList().

◆ QsortFiles()

static VOID QsortFiles ( PDIRFINDINFO  ptrArray[],
int  i,
int  j,
LPDIRSWITCHFLAGS  lpFlags 
)
static

Definition at line 1293 of file dir.c.

1297{
1298 PDIRFINDINFO lpTemp; /* A temporary pointer */
1299 BOOL Way;
1300
1301 if (i < j)
1302 {
1303 int First = i, Last = j, Temp;
1304 Way = TRUE;
1305 while (i != j)
1306 {
1307 if (Way == CompareFiles(ptrArray[i], ptrArray[j], lpFlags))
1308 {
1309 /* Swap the pointers of the array */
1310 lpTemp = ptrArray[i];
1311 ptrArray[i]= ptrArray[j];
1312 ptrArray[j] = lpTemp;
1313
1314 /* Swap the indexes for inverting sorting */
1315 Temp = i;
1316 i = j;
1317 j =Temp;
1318
1319 Way = !Way;
1320 }
1321
1322 j += (!Way - Way);
1323 }
1324
1325 QsortFiles(ptrArray,First, i-1, lpFlags);
1326 QsortFiles(ptrArray,i+1,Last, lpFlags);
1327 }
1328}
WCHAR First[]
Definition: FormatMessage.c:11
static BOOL CompareFiles(PDIRFINDINFO lpFile1, PDIRFINDINFO lpFile2, LPDIRSWITCHFLAGS lpFlags)
Definition: dir.c:1192

Referenced by DirList(), and QsortFiles().

◆ ResolvePattern()

static VOID ResolvePattern ( IN LPTSTR  pszPattern,
IN DWORD  nBufferLength,
OUT LPTSTR  pszFullPath,
OUT LPTSTR *ppszPatternPart  OPTIONAL 
)
static

Definition at line 1610 of file dir.c.

1615{
1616 LPTSTR pCurDir, pNextDir, ptr;
1617 LPTSTR pszPatternPart;
1618 TCHAR szNewPattern[MAX_PATH];
1619
1620 /*
1621 * We are going to use GetFullPathName() to properly determine the actual
1622 * full path from the pattern. However, due to the fact GetFullPathName()
1623 * strips parts of the file name component in case the pattern contains
1624 * path specification with trailing dots, it is required to perform a
1625 * pre-treatment on the pattern and a post-treatment on the obtained path.
1626 * This is mandatory in order to use the correct file search criterion.
1627 *
1628 * One particular case is when the pattern specifies a dots-only directory
1629 * followed by either the "." or ".." special directories. In this case the
1630 * GetFullPathName() function may completely miss the dots-only directory.
1631 * An example is given by the pattern (C-string notation) "\\...\\." .
1632 * To cope with this problem we need to partially canonicalize the pattern
1633 * by collapsing any "." or ".." special directory that immediately follows
1634 * a dots-only directory. We collapse in addition consecutive backslashes.
1635 *
1636 * Finally, trailing dots are skipped by GetFullPathName(). Therefore
1637 * a pattern that matches files with no extension, for example: "*." ,
1638 * or: "dir\\noextfile." , are reduced to simply "*" or "dir\\noextfile",
1639 * that match files with extensions. Or, a pattern specifying a trailing
1640 * dots-only directory: "dir\\..." gets completely ignored and only the
1641 * full path to "dir" is returned.
1642 * To fix this second problem we need to restore the last part of the path
1643 * pattern using the pattern that has been first partially canonicalized.
1644 *
1645 * Note however that the "." or ".." special directories are always
1646 * interpreted correctly by GetFullPathName().
1647 */
1648
1649 /* Make a copy of the path pattern */
1650 ASSERT(_tcslen(pszPattern) < ARRAYSIZE(szNewPattern));
1651 _tcscpy(szNewPattern, pszPattern);
1652 pszPattern = szNewPattern;
1653
1654 TRACE("Original pszPattern: %S\n", pszPattern);
1655
1656 /* Convert slashes into backslashes */
1657 pNextDir = pszPattern;
1658 while ((pNextDir = _tcschr(pNextDir, _T('/'))))
1659 *pNextDir++ = _T('\\');
1660
1661 /*
1662 * Find any dots-only directory and collapse any "." or ".." special
1663 * directory that immediately follows it.
1664 * Note that we just start looking after the first path separator. Indeed,
1665 * dots-only directories that are not preceded by a path separator, and so
1666 * appear first in the pattern, for example: "...\dir", or: "..." , are
1667 * either correctly handled by GetFullPathName() because they are followed
1668 * by a non-pathological directory, or because they are handled when we
1669 * restore the trailing dots pattern piece in the next step.
1670 */
1671 pNextDir = pszPattern;
1672 while (pNextDir)
1673 {
1674 pCurDir = pNextDir;
1675
1676 /* Find the next path separator in the pattern */
1677 pNextDir = _tcschr(pNextDir, _T('\\'));
1678 if (!pNextDir)
1679 break;
1680
1681 /* Ignore the special "." and ".." directories that are correctly handled */
1682 if ((pNextDir - pCurDir == 0) || IsDotDirectoryN(pCurDir, pNextDir - pCurDir))
1683 {
1684 /* Found such a directory, ignore */
1685 ++pNextDir;
1686 continue;
1687 }
1688
1689 /* Check whether this is a dots-only directory */
1690 for (ptr = pCurDir; ptr < pNextDir; ++ptr)
1691 {
1692 if (*ptr != _T('.'))
1693 break;
1694 }
1695 if (ptr < pNextDir)
1696 {
1697 /* Not a dots-only directory, ignore */
1698 ++pNextDir;
1699 continue;
1700 }
1701
1702 /* Skip any consecutive backslashes */
1703 for (ptr = pNextDir; *ptr == _T('\\'); ++ptr) ;
1704
1705 /* pCurDir is a dots-only directory, perform partial canonicalization */
1706
1707 /* Remove any following "." directory */
1708 if (ptr[0] == _T('.') && (ptr[1] == _T('\\') || ptr[1] == 0))
1709 {
1710 memmove(pNextDir, ptr + 1, (_tcslen(ptr + 1) + 1) * sizeof(TCHAR));
1711 }
1712 /* Remove any following ".." directory */
1713 else if (ptr[0] == _T('.') && ptr[1] == _T('.') && (ptr[2] == _T('\\') || ptr[2] == 0))
1714 {
1715 /* Skip any consecutive backslashes before the next directory */
1716 for (ptr = ptr + 2; *ptr == _T('\\'); ++ptr) ;
1717
1718 memmove(pCurDir, ptr, (_tcslen(ptr) + 1) * sizeof(TCHAR));
1719 pNextDir = pCurDir;
1720 }
1721 else
1722 {
1723 ++pNextDir;
1724
1725 /* Collapse consecutive backslashes */
1726 if (ptr > pNextDir)
1727 memmove(pNextDir, ptr, (_tcslen(ptr) + 1) * sizeof(TCHAR));
1728 }
1729 }
1730
1731 /* An empty pattern means we enumerate all files in the current directory */
1732 if (!*pszPattern)
1733 _tcscpy(pszPattern, _T("*"));
1734
1735 TRACE("New pszPattern: %S\n", pszPattern);
1736
1737 /* Create the full path */
1738 if (GetFullPathName(pszPattern, nBufferLength, pszFullPath, &pszPatternPart) == 0)
1739 {
1740 _tcscpy(pszFullPath, pszPattern);
1741 pszPatternPart = NULL;
1742 }
1743
1744 TRACE("pszFullPath (1): %S\n", pszFullPath);
1745 TRACE("pszPatternPart (1): %S\n", pszPatternPart);
1746
1747 /*
1748 * Restore the correct file name component in case the pattern contained
1749 * trailing dots that have been skipped by GetFullPathName().
1750 */
1751
1752 /* Find the last path separator in the original szPath */
1753 pNextDir = _tcsrchr(pszPattern, _T('\\'));
1754 if (pNextDir)
1755 {
1756 /* Skip past the separator and look at the path */
1757 ++pNextDir;
1758 }
1759 else
1760 {
1761 /* The pattern is the path we need to look at */
1762 pNextDir = pszPattern;
1763 }
1764
1765 /*
1766 * When pszPatternPart == NULL this means that pszFullPath should be a
1767 * directory; however it might have happened that the original pattern
1768 * was specifying a dots-only directory, that has been stripped off by
1769 * GetFullPathName(). In both these cases we need to restore these as
1770 * they are part of the actual directory path; the exception being if
1771 * these are the special "." or ".." directories.
1772 */
1773 if (_istalpha(pNextDir[0]) && pNextDir[1] == _T(':') && pNextDir[2] != _T('\\'))
1774 {
1775 /*
1776 * The syntax "<drive_letter>:" without any trailing backslash actually
1777 * means: "current directory on this drive".
1778 */
1779 }
1780 else if (pszPatternPart == NULL)
1781 {
1782 ASSERT(pszFullPath[_tcslen(pszFullPath)-1] == _T('\\'));
1783
1784 /* Anything NOT being "." or ".." (the special directories) must be fully restored */
1785 if (*pNextDir && !IsDotDirectory(pNextDir))
1786 {
1787 pszPatternPart = &pszFullPath[_tcslen(pszFullPath)];
1788 _tcscpy(pszPatternPart, pNextDir);
1789 pszPatternPart = NULL;
1790 }
1791 }
1792 else if (_tcscmp(pNextDir, pszPatternPart) != 0)
1793 {
1794 /*
1795 * For example, pszPatternPart == "." or ".." and we do not need to
1796 * do anything for these, or pszPatternPart == "dir\\noextfile." and
1797 * we need to restore all the trailing points.
1798 */
1799 TRACE("pszPatternPart: %S is DIFFERENT from file criterion: %S\n", pszPatternPart, pNextDir);
1800
1801 /* Anything NOT being "." or ".." (the special directories) must be fully restored */
1802 if (*pNextDir && !IsDotDirectory(pNextDir))
1803 {
1804 /* Restore the correct file criterion */
1805 _tcscpy(pszPatternPart, pNextDir);
1806 }
1807 }
1808
1809 TRACE("pszFullPath (2): %S\n", pszFullPath);
1810
1811 /*
1812 * If no wildcard or file was specified and this is a directory,
1813 * display all files in it.
1814 */
1815 if (pszPatternPart == NULL || IsExistingDirectory(pszFullPath))
1816 {
1817 pszPatternPart = &pszFullPath[_tcslen(pszFullPath)];
1818 if (pszPatternPart[-1] != _T('\\'))
1819 *pszPatternPart++ = _T('\\');
1820 _tcscpy(pszPatternPart, _T("*"));
1821 }
1822
1823 TRACE("pszPatternPart (2): %S\n", pszPatternPart);
1824
1825 if (ppszPatternPart)
1826 *ppszPatternPart = pszPatternPart;
1827}
BOOL IsExistingDirectory(IN LPCTSTR pszPath)
Definition: misc.c:504
FORCEINLINE BOOL IsDotDirectoryN(IN const TCHAR *pPath, IN SIZE_T Length)
Definition: dir.c:250
#define _istalpha
Definition: tchar.h:1492
#define _tcschr
Definition: tchar.h:1406
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define ASSERT(a)
Definition: mode.c:44
static PVOID ptr
Definition: dispmode.c:27
_In_ LPCSTR _In_opt_ LPCSTR _In_ DWORD nBufferLength
Definition: winbase.h:3060
#define GetFullPathName
Definition: winbase.h:3692

Referenced by CommandDir().

Variable Documentation

◆ recurse_bytes

ULONGLONG recurse_bytes
static

Definition at line 222 of file dir.c.

Referenced by CommandDir(), and DirList().

◆ recurse_dir_cnt

ULONG recurse_dir_cnt
static

Definition at line 220 of file dir.c.

Referenced by CommandDir(), and DirList().

◆ recurse_file_cnt

ULONG recurse_file_cnt
static

Definition at line 221 of file dir.c.

Referenced by CommandDir(), and DirList().