ReactOS 0.4.15-dev-7988-g06a3508
dir.c File Reference
#include "precomp.h"
#include <cjkcode.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 216 of file dir.c.

Enumeration Type Documentation

◆ EOrderBy

Enumerator
ORDER_NAME 
ORDER_SIZE 
ORDER_DIRECTORY 
ORDER_EXTENSION 
ORDER_TIME 

Definition at line 157 of file dir.c.

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

◆ ETimeField

Enumerator
TF_CREATIONDATE 
TF_MODIFIEDDATE 
TF_LASTACCESSEDDATE 

Definition at line 149 of file dir.c.

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

Function Documentation

◆ CommandDir()

INT CommandDir ( LPTSTR  rest)

Definition at line 1843 of file dir.c.

1844{
1845 TCHAR dircmd[MAX_PATH]; /* A variable to store the DIRCMD environment variable */
1846 TCHAR prev_volume[MAX_PATH];
1847 TCHAR szFullPath[MAX_PATH];
1848 LPTSTR* params = NULL;
1849 LPTSTR pszFilePart;
1850 TCHAR cPathSep;
1851 INT entries = 0;
1852 UINT loop = 0;
1853 DIRSWITCHFLAGS stFlags;
1854 INT ret = 1;
1855 BOOL ChangedVolume;
1856
1857 /* Initialize Switch Flags < Default switches are set here! > */
1858 stFlags.b4Digit = TRUE;
1859 stFlags.bBareFormat = FALSE;
1860 stFlags.bDataStreams = FALSE;
1861 stFlags.bLowerCase = FALSE;
1862 stFlags.bNewLongList = TRUE;
1863 stFlags.bPause = FALSE;
1864 stFlags.bRecursive = FALSE;
1865 stFlags.bShortName = FALSE;
1866 stFlags.bTSeparator = TRUE;
1867 stFlags.bUser = FALSE;
1868 stFlags.bWideList = FALSE;
1869 stFlags.bWideListColSort = FALSE;
1870 stFlags.stTimeField.eTimeField = TF_MODIFIEDDATE;
1871 stFlags.stAttribs.dwAttribMask = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
1872 stFlags.stAttribs.dwAttribVal = 0L;
1873 stFlags.stOrderBy.sCriteriaCount = 0;
1874
1875 nErrorLevel = 0;
1876
1877 /* Read the parameters from the DIRCMD environment variable */
1878 if (GetEnvironmentVariable (_T("DIRCMD"), dircmd, ARRAYSIZE(dircmd)))
1879 {
1880 if (!DirReadParam(dircmd, &params, &entries, &stFlags))
1881 {
1882 nErrorLevel = 1;
1883 goto cleanup;
1884 }
1885 }
1886
1887 /* Read the parameters */
1888 if (!DirReadParam(rest, &params, &entries, &stFlags) || CheckCtrlBreak(BREAK_INPUT))
1889 {
1890 nErrorLevel = 1;
1891 goto cleanup;
1892 }
1893
1894 /* Default to current directory */
1895 if (entries == 0)
1896 {
1897 if (!add_entry(&entries, &params, _T("*")))
1898 {
1899 nErrorLevel = 1;
1900 goto cleanup;
1901 }
1902 }
1903
1904 prev_volume[0] = _T('\0');
1905
1906 /* Reset paging state */
1907 if (stFlags.bPause)
1909
1910 for (loop = 0; loop < (UINT)entries; loop++)
1911 {
1913 {
1914 nErrorLevel = 1;
1915 goto cleanup;
1916 }
1917
1918 recurse_dir_cnt = 0L;
1920 recurse_bytes = 0;
1921
1922 /* <Debug :>
1923 Uncomment this to show the final state of switch flags*/
1924 {
1925 int i;
1926 TRACE("Attributes mask/value %x/%x\n",stFlags.stAttribs.dwAttribMask,stFlags.stAttribs.dwAttribVal);
1927 TRACE("(B) Bare format : %i\n", stFlags.bBareFormat);
1928 TRACE("(C) Thousand : %i\n", stFlags.bTSeparator);
1929 TRACE("(W) Wide list : %i\n", stFlags.bWideList);
1930 TRACE("(D) Wide list sort by column : %i\n", stFlags.bWideListColSort);
1931 TRACE("(L) Lowercase : %i\n", stFlags.bLowerCase);
1932 TRACE("(N) New : %i\n", stFlags.bNewLongList);
1933 TRACE("(O) Order : %i\n", stFlags.stOrderBy.sCriteriaCount);
1934 for (i =0;i<stFlags.stOrderBy.sCriteriaCount;i++)
1935 TRACE(" Order Criteria [%i]: %i (Reversed: %i)\n",i, stFlags.stOrderBy.eCriteria[i], stFlags.stOrderBy.bCriteriaRev[i]);
1936 TRACE("(P) Pause : %i\n", stFlags.bPause);
1937 TRACE("(Q) Owner : %i\n", stFlags.bUser);
1938 TRACE("(R) Data stream : %i\n", stFlags.bDataStreams);
1939 TRACE("(S) Recursive : %i\n", stFlags.bRecursive);
1940 TRACE("(T) Time field : %i\n", stFlags.stTimeField.eTimeField);
1941 TRACE("(X) Short names : %i\n", stFlags.bShortName);
1942 TRACE("Parameter : %s\n", debugstr_aw(params[loop]));
1943 }
1944
1945 /* Print the drive header if the volume changed */
1946 ChangedVolume = TRUE;
1947
1948 if (!stFlags.bBareFormat &&
1949 GetVolumePathName(params[loop], szFullPath, ARRAYSIZE(szFullPath)))
1950 {
1951 if (!_tcscmp(szFullPath, prev_volume))
1952 ChangedVolume = FALSE;
1953 else
1954 _tcscpy(prev_volume, szFullPath);
1955 }
1956
1957 /* Resolve the pattern */
1958 ResolvePattern(params[loop], ARRAYSIZE(szFullPath), szFullPath, &pszFilePart);
1959
1960 /* Print the header */
1961 cPathSep = pszFilePart[-1];
1962 pszFilePart[-1] = _T('\0'); /* Truncate to directory name only */
1963 if (ChangedVolume && !stFlags.bBareFormat &&
1964 !PrintDirectoryHeader(szFullPath, &stFlags))
1965 {
1966 nErrorLevel = 1;
1967 goto cleanup;
1968 }
1969 pszFilePart[-1] = cPathSep;
1970
1971 /* Perform the actual directory listing */
1972 if (DirList(szFullPath, pszFilePart, &stFlags) != 0)
1973 {
1974 nErrorLevel = 1;
1975 goto cleanup;
1976 }
1977
1978 /* Print the footer */
1979 pszFilePart[-1] = _T('\0'); /* Truncate to directory name only */
1980 PrintSummary(szFullPath,
1984 &stFlags,
1985 TRUE);
1986 }
1987
1988 ret = 0;
1989
1990cleanup:
1991 freep(params);
1992
1993 return ret;
1994}
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:771
static ULONG recurse_dir_cnt
Definition: dir.c:221
static INT DirList(IN OUT LPTSTR szFullPath, IN LPTSTR pszFilePart, LPDIRSWITCHFLAGS lpFlags)
Definition: dir.c:1365
static ULONGLONG recurse_bytes
Definition: dir.c:223
static BOOL DirReadParam(LPTSTR Line, LPTSTR **params, LPINT entries, LPDIRSWITCHFLAGS lpFlags)
Definition: dir.c:265
static VOID ResolvePattern(IN LPTSTR pszPattern, IN DWORD nBufferLength, OUT LPTSTR pszFullPath, OUT LPTSTR *ppszPatternPart OPTIONAL)
Definition: dir.c:1618
static BOOL PrintDirectoryHeader(LPCTSTR szPath, LPDIRSWITCHFLAGS lpFlags)
Definition: dir.c:598
static ULONG recurse_file_cnt
Definition: dir.c:222
#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:180
struct _DirSwitchesFlags::@72 stOrderBy
BOOL bRecursive
Definition: dir.c:177
BOOL bNewLongList
Definition: dir.c:174
BOOL bWideListColSort
Definition: dir.c:172
BOOL bBareFormat
Definition: dir.c:169
BOOL bWideList
Definition: dir.c:171
BOOL b4Digit
Definition: dir.c:179
struct _DirSwitchesFlags::@73 stTimeField
BOOL bLowerCase
Definition: dir.c:173
struct _DirSwitchesFlags::@71 stAttribs
BOOL bShortName
Definition: dir.c:178
BOOL bPause
Definition: dir.c:175
BOOL bUser
Definition: dir.c:176
BOOL bTSeparator
Definition: dir.c:170
int32_t INT
Definition: typedefs.h:58
#define _T(x)
Definition: vfdio.h:22
int ret
#define GetEnvironmentVariable
Definition: winbase.h:3814
#define GetVolumePathName
Definition: winbase.h:3855
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 1200 of file dir.c.

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

233{
235}
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 1365 of file dir.c.

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

1341{
1342 PDIRFINDLISTNODE ptrNextNode;
1343 PDIRFINDSTREAMNODE ptrFreeNode;
1344 while (ptrStartNode)
1345 {
1346 ptrNextNode = ptrStartNode->ptrNext;
1347 while (ptrStartNode->stInfo.ptrHead)
1348 {
1349 ptrFreeNode = ptrStartNode->stInfo.ptrHead;
1350 ptrStartNode->stInfo.ptrHead = ptrFreeNode->ptrNext;
1351 cmd_free(ptrFreeNode);
1352 }
1353 cmd_free(ptrStartNode);
1354 ptrStartNode = ptrNextNode;
1355 --(*pdwCount);
1356 }
1357}

Referenced by DirList().

◆ DirPrintBareList()

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

Definition at line 1110 of file dir.c.

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

Referenced by DirPrintFiles().

◆ DirPrintf()

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

Definition at line 578 of file dir.c.

579{
580 BOOL Done = TRUE;
581 va_list arg_ptr;
582 va_start(arg_ptr, szFormat);
583 if (lpFlags->bPause)
584 Done = ConPrintfVPaging(&StdOutPager, FALSE, szFormat, arg_ptr);
585 else
586 ConPrintfV(StdOut, szFormat, arg_ptr);
587 va_end(arg_ptr);
588 return Done;
589}
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 640 of file dir.c.

644{
645 FILETIME ft;
646 SYSTEMTIME dt;
647
648 /* Select the right time field */
649 switch (lpFlags->stTimeField.eTimeField)
650 {
651 case TF_CREATIONDATE:
652 if (!FileTimeToLocalFileTime(&lpFile->ftCreationTime, &ft))
653 return;
654 FileTimeToSystemTime(&ft, &dt);
655 break;
656
658 if (!FileTimeToLocalFileTime(&lpFile->ftLastAccessTime, &ft))
659 return;
660 FileTimeToSystemTime(&ft, &dt);
661 break;
662
663 case TF_MODIFIEDDATE:
664 if (!FileTimeToLocalFileTime(&lpFile->ftLastWriteTime, &ft))
665 return;
666 FileTimeToSystemTime(&ft, &dt);
667 break;
668 }
669
670 FormatDate(lpDate, &dt, lpFlags->b4Digit);
671 FormatTime(lpTime, &dt);
672}
INT FormatTime(TCHAR *lpTime, LPSYSTEMTIME dt)
Definition: dir.c:704
INT FormatDate(TCHAR *lpDate, LPSYSTEMTIME dt, BOOL b4Digit)
Definition: dir.c:675
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 1144 of file dir.c.

1148{
1150 TCHAR szTemp[MAX_PATH]; /* A buffer to format the directory header */
1151
1152 /* Print trailing backslash for root directory of drive */
1153 _tcscpy(szTemp, szCurPath);
1154 if (_tcslen(szTemp) == 2 && szTemp[1] == _T(':'))
1155 _tcscat(szTemp, _T("\\"));
1156
1157 /* Condition to print header:
1158 We are not printing in bare format
1159 and if we are in recursive mode... we must have results */
1160 if (!lpFlags->bBareFormat && !(lpFlags->bRecursive && (dwCount <= 0)))
1161 {
1163 if (!DirPrintf(lpFlags, szMsg, szTemp))
1164 return;
1165 }
1166
1167 if (lpFlags->bBareFormat)
1168 {
1169 /* Bare format */
1170 DirPrintBareList(ptrFiles, dwCount, szCurPath, lpFlags);
1171 }
1172 else if (lpFlags->bShortName)
1173 {
1174 /* New list style / Short names */
1175 DirPrintNewList(ptrFiles, dwCount, szCurPath, lpFlags);
1176 }
1177 else if (lpFlags->bWideListColSort || lpFlags->bWideList)
1178 {
1179 /* Wide list */
1180 DirPrintWideList(ptrFiles, dwCount, szCurPath, lpFlags);
1181 }
1182 else if (lpFlags->bNewLongList )
1183 {
1184 /* New list style*/
1185 DirPrintNewList(ptrFiles, dwCount, szCurPath, lpFlags);
1186 }
1187 else
1188 {
1189 /* If nothing is selected old list is the default */
1190 DirPrintOldList(ptrFiles, dwCount, szCurPath, lpFlags);
1191 }
1192}
#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:874
static VOID DirPrintOldList(PDIRFINDINFO ptrFiles[], DWORD dwCount, LPCTSTR szCurPath, LPDIRSWITCHFLAGS lpFlags)
Definition: dir.c:1045
static VOID DirPrintWideList(PDIRFINDINFO ptrFiles[], DWORD dwCount, LPCTSTR szCurPath, LPDIRSWITCHFLAGS lpFlags)
Definition: dir.c:956
static VOID DirPrintBareList(PDIRFINDINFO ptrFiles[], DWORD dwCount, LPCTSTR szCurPath, LPDIRSWITCHFLAGS lpFlags)
Definition: dir.c:1110
#define STRING_DIR_HELP7
Definition: resource.h:112
#define LoadString
Definition: winuser.h:5819

Referenced by DirList().

◆ DirPrintNewList()

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

Definition at line 874 of file dir.c.

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

Referenced by DirPrintFiles().

◆ DirPrintOldList()

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

Definition at line 1045 of file dir.c.

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

960{
961 SHORT iScreenWidth;
962 USHORT iColumns;
963 USHORT iLines;
964 UINT_PTR iLongestName;
965 TCHAR szTempFname[MAX_PATH];
966 DWORD i;
967 DWORD j;
968 DWORD temp;
970 SIZE_T cxWidth;
971
972 /* Calculate longest name */
973 iLongestName = 1;
974 for (i = 0; i < dwCount; i++)
975 {
976 cxWidth = ConGetTextWidth(ptrFiles[i]->stFindInfo.cFileName);
977
978 /* Directories need 2 additional characters for brackets */
979 if (ptrFiles[i]->stFindInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
980 cxWidth += 2;
981
982 iLongestName = max(iLongestName, cxWidth);
983 }
984
985 /* Count the highest number of columns */
986 GetScreenSize(&iScreenWidth, NULL);
987 iColumns = (USHORT)(iScreenWidth / iLongestName);
988
989 /* Check if there is enough space for spaces between names */
990 if (((iLongestName * iColumns) + iColumns) >= (UINT)iScreenWidth)
991 iColumns --;
992
993 /* A last check at iColumns to avoid division by zero */
994 if (!iColumns) iColumns = 1;
995
996 /* Calculate the lines that will be printed */
997 iLines = (USHORT)((dwCount + iColumns - 1) / iColumns);
998
999 for (i = 0; i < iLines && !CheckCtrlBreak(BREAK_INPUT); i++)
1000 {
1001 for (j = 0; j < iColumns; j++)
1002 {
1003 if (lpFlags->bWideListColSort)
1004 {
1005 /* Print Column sorted */
1006 temp = (j * iLines) + i;
1007 }
1008 else
1009 {
1010 /* Print Line sorted */
1011 temp = (i * iColumns) + j;
1012 }
1013
1014 if (temp >= dwCount) break;
1015
1016 if (ptrFiles[temp]->stFindInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1017 _stprintf(szTempFname, _T("[%s]"), ptrFiles[temp]->stFindInfo.cFileName);
1018 else
1019 _stprintf(szTempFname, _T("%s"), ptrFiles[temp]->stFindInfo.cFileName);
1020
1021 if (bCJK)
1022 {
1023 cxWidth = ConGetTextWidth(szTempFname);
1024 /* Print string and add space padding */
1025 DirPrintf(lpFlags, _T("%s%*s"), szTempFname, iLongestName + 1 - cxWidth, _T(""));
1026 }
1027 else
1028 {
1029 DirPrintf(lpFlags, _T("%-*s"), iLongestName + 1, szTempFname);
1030 }
1031 }
1032
1033 /* Add a new line after the last item in the column */
1034 DirPrintf(lpFlags, _T("\n"));
1035 }
1036}
UINT OutputCodePage
Definition: console.c:26
VOID GetScreenSize(PSHORT maxx, PSHORT maxy)
Definition: console.c:236
#define ConGetTextWidth
Definition: console.h:105
#define IsCJKCodePage(CodePage)
Definition: cjkcode.h:27
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
#define max(a, b)
Definition: svc.c:63
ULONG_PTR SIZE_T
Definition: typedefs.h:80

Referenced by DirPrintFiles().

◆ DirReadParam()

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

Definition at line 265 of file dir.c.

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

676{
677 /* Format date */
678 WORD wYear = b4Digit ? dt->wYear : dt->wYear%100;
679 switch (nDateFormat)
680 {
681 case 0: /* mmddyy */
682 default:
683 return _stprintf(lpDate, _T("%02d%c%02d%c%0*d"),
685 dt->wDay, cDateSeparator,
686 b4Digit?4:2, wYear);
687 break;
688
689 case 1: /* ddmmyy */
690 return _stprintf(lpDate, _T("%02d%c%02d%c%0*d"),
691 dt->wDay, cDateSeparator, dt->wMonth,
692 cDateSeparator, b4Digit?4:2, wYear);
693 break;
694
695 case 2: /* yymmdd */
696 return _stprintf(lpDate, _T("%0*d%c%02d%c%02d"),
697 b4Digit?4:2, wYear, cDateSeparator,
698 dt->wMonth, cDateSeparator, dt->wDay);
699 break;
700 }
701}
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 704 of file dir.c.

705{
706 /* Format Time */
707 switch (nTimeFormat)
708 {
709 case 0: /* 12 hour format */
710 default:
711 return _stprintf(lpTime,_T("%02d%c%02u %cM"),
712 (dt->wHour == 0 ? 12 : (dt->wHour <= 12 ? dt->wHour : dt->wHour - 12)),
714 dt->wMinute, (dt->wHour <= 11 ? _T('A') : _T('P')));
715 break;
716
717 case 1: /* 24 hour format */
718 return _stprintf(lpTime, _T("%02d%c%02u"),
719 dt->wHour, cTimeSeparator, dt->wMinute);
720 break;
721 }
722}
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 830 of file dir.c.

831{
832 static TCHAR *NoExt = _T("");
833 TCHAR* lastdot = _tcsrchr(file, _T('.'));
834 return (lastdot != NULL ? lastdot + 1 : NoExt);
835}
#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 843 of file dir.c.

844{
845 INT_PTR iLen;
846 LPTSTR end;
847
848 /* Check for dot-directories "." and ".." */
849 if (IsDotDirectory(file))
850 {
851 _tcscpy(dest, file);
852 return dest;
853 }
854
855 end = _tcsrchr(file, _T('.'));
856 if (!end)
857 iLen = _tcslen(file);
858 else
859 iLen = (end - file);
860
861 _tcsncpy(dest, file, iLen);
862 *(dest + iLen) = _T('\0');
863
864 return dest;
865}
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 726 of file dir.c.

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

Referenced by PrintSummary().

◆ IsDotDirectory()

FORCEINLINE BOOL IsDotDirectory ( IN LPCTSTR  pszPath)

Definition at line 240 of file dir.c.

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

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

◆ IsDotDirectoryN()

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

Definition at line 251 of file dir.c.

254{
255 return ((Length == 1 && pPath[0] == _T('.')) ||
256 (Length == 2 && pPath[0] == _T('.') && pPath[1] == _T('.')));
257}
_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 598 of file dir.c.

599{
601 LPCTSTR szFullDir;
602 TCHAR szRootName[MAX_PATH];
603 TCHAR szVolName[80];
604 DWORD dwSerialNr;
605
606 if (lpFlags->bBareFormat)
607 return TRUE;
608
609 szFullDir = szPath;
610
611 /* Get the media ID of the drive */
612 if (!GetVolumePathName(szFullDir, szRootName, ARRAYSIZE(szRootName)) ||
613 !GetVolumeInformation(szRootName, szVolName, ARRAYSIZE(szVolName),
614 &dwSerialNr, NULL, NULL, NULL, 0))
615 {
616 return TRUE;
617 }
618
619 /* Print drive info */
620 if (szVolName[0] != _T('\0'))
621 {
623 DirPrintf(lpFlags, szMsg, _totupper(szRootName[0]), szVolName);
624 }
625 else
626 {
628 DirPrintf(lpFlags, szMsg, _totupper(szRootName[0]));
629 }
630
631 /* Print the volume serial number if the return was successful */
633 DirPrintf(lpFlags, szMsg, HIWORD(dwSerialNr), LOWORD(dwSerialNr));
634
635 return TRUE;
636}
#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:3853
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 771 of file dir.c.

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

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

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 1618 of file dir.c.

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

Referenced by CommandDir().

Variable Documentation

◆ recurse_bytes

ULONGLONG recurse_bytes
static

Definition at line 223 of file dir.c.

Referenced by CommandDir(), and DirList().

◆ recurse_dir_cnt

ULONG recurse_dir_cnt
static

Definition at line 221 of file dir.c.

Referenced by CommandDir(), and DirList().

◆ recurse_file_cnt

ULONG recurse_file_cnt
static

Definition at line 222 of file dir.c.

Referenced by CommandDir(), and DirList().