⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dir.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
 *  DIR.C - dir internal command.
 *
 *
 *  History:
 *
 *    01/29/97 (Tim Norman)
 *        started.
 *
 *    06/13/97 (Tim Norman)
 *      Fixed code.
 *
 *    07/12/97 (Tim Norman)
 *        Fixed bug that caused the root directory to be unlistable
 *
 *    07/12/97 (Marc Desrochers)
 *        Changed to use maxx, maxy instead of findxy()
 *
 *    06/08/98 (Rob Lake)
 *        Added compatibility for /w in dir
 *
 *    06/09/98 (Rob Lake)
 *        Compatibility for dir/s started
 *        Tested that program finds directories off root fine
 *
 *    06/10/98 (Rob Lake)
 *        do_recurse saves the cwd and also stores it in Root
 *        build_tree adds the cwd to the beginning of its' entries
 *        Program runs fine, added print_tree -- works fine.. as EXE,
 *        program won't work properly as COM.
 *
 *    06/11/98 (Rob Lake)
 *        Found problem that caused COM not to work
 *
 *    06/12/98 (Rob Lake)
 *        debugged...
 *        added free mem routine
 *
 *    06/13/98 (Rob Lake)
 *        debugged the free mem routine
 *        debugged whole thing some more
 *        Notes:
 *        ReadDir stores Root name and _Read_Dir does the hard work
 *        PrintDir prints Root and _Print_Dir does the hard work
 *        KillDir kills Root _after_ _Kill_Dir does the hard work
 *        Integrated program into DIR.C(this file) and made some same
 *        changes throughout
 *
 *    06/14/98 (Rob Lake)
 *        Cleaned up code a bit, added comments
 *
 *    06/16/98 (Rob Lake)
 *        Added error checking to my previously added routines
 *
 *    06/17/98 (Rob Lake)
 *        Rewrote recursive functions, again! Most other recursive
 *        functions are now obsolete -- ReadDir, PrintDir, _Print_Dir,
 *        KillDir and _Kill_Dir.  do_recurse does what PrintDir did
 *        and _Read_Dir did what it did before along with what _Print_Dir
 *        did.  Makes /s a lot faster!
 *        Reports 2 more files/dirs that MS-DOS actually reports
 *        when used in root directory(is this because dir defaults
 *        to look for read only files?)
 *        Added support for /b, /a and /l
 *        Made error message similar to DOS error messages
 *        Added help screen
 *
 *    06/20/98 (Rob Lake)
 *        Added check for /-(switch) to turn off previously defined
 *        switches.
 *        Added ability to check for DIRCMD in environment and
 *        process it
 *
 *    06/21/98 (Rob Lake)
 *        Fixed up /B
 *        Now can dir *.ext/X, no spaces!
 *
 *    06/29/98 (Rob Lake)
 *        error message now found in command.h
 *
 *    07/08/1998 (John P. Price)
 *        removed extra returns; closer to MSDOS
 *        fixed wide display so that an extra return is not displayed
 *        when there is five filenames in the last line.
 *
 *    07/12/98 (Rob Lake)
 *        Changed error messages
 *
 *    27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
 *        added config.h include
 *
 *
 *    04-Dec-1998 (Eric Kohl)
 *        Converted source code to Win32, except recursive dir ("dir /s").
 *
 *    10-Dec-1998 (Eric Kohl)
 *        Fixed recursive dir ("dir /s").
 *
 *    14-Dec-1998 (Eric Kohl)
 *        Converted to Win32 directory functions and
 *        fixed some output bugs. There are still some more ;)
 *
 *    10-Jan-1999 (Eric Kohl)
 *        Added "/N" and "/4" options, "/O" is a dummy.
 *        Added locale support.
 *
 *    20-Jan-1999 (Eric Kohl)
 *        Redirection safe!
 *
 *    01-Mar-1999 (Eric Kohl)
 *        Replaced all runtime io functions by their Win32 counterparts.
 *
 *    23-Feb-2001 (Carl Nettelblad <cnettel@hem.passagen.se>)
 *        dir /s now works in deeper trees
 *
 *    28-Jan-2004 (Michael Fritscher <michael@fritscher.net>)
 *        Fix for /p, so it is working under Windows in GUI-mode, too.
 *
 *    30-Apr-2004 (Filip Navara <xnavara@volny.cz>)
 *        Fix /w to print long names.
 *
 *    27-Feb-2005 (Konstantinos Paliouras <squarious@gmail.com>)
 *        Implemented all the switches that were missing, and made
 *        the ros dir very similar to windows dir. Major part of
 *        the code is rewritten. /p is removed, to be rewriten in
 *        the main cmd code.
 *
 *    1-Jul-2004 (Brandon Turner <turnerb7@msu.edu>)
 *        Added /p back in using ConOutPrintfPaging
 *
 *    3-feb-2007 (Paolo Devoti devotip at gmail)
 *        Removed variables formerly in use to handle pagination
 *		  Pagination belongs to ConOutPrintfPaging
 *		  Removed already commented out code of old pagination
 */

#include <precomp.h>

#ifdef INCLUDE_CMD_DIR



/* Time Field enumeration */
enum ETimeField
{
	TF_CREATIONDATE		= 0,
	TF_MODIFIEDDATE		= 1,
	TF_LASTACCESSEDDATE	= 2
};

/* Ordered by enumeration */
enum EOrderBy
{
	ORDER_NAME		= 0,
	ORDER_SIZE		= 1,
	ORDER_DIRECTORY	= 2,
	ORDER_EXTENSION	= 3,
	ORDER_TIME		= 4
};

/* The struct for holding the switches */
typedef struct _DirSwitchesFlags
{
	BOOL bBareFormat;	/* Bare Format */
	BOOL bTSeperator;	/* Thousands seperator */
	BOOL bWideList;		/* Wide list format	*/
	BOOL bWideListColSort;	/* Wide list format but sorted by column */
	BOOL bLowerCase;	/* Uses lower case */
	BOOL bNewLongList;	/* New long list */
	BOOL bPause;		/* Pause per page */
	BOOL bUser;			/* Displays the owner of file */
	BOOL bRecursive;	/* Displays files in specified directory and all sub */
	BOOL bShortName;	/* Displays the sort name of files if exist	*/
	BOOL b4Digit;		/* Four digit year	*/
	struct
	{
		DWORD dwAttribVal;	/* The desired state of attribute */
		DWORD dwAttribMask;	/* Which attributes to check */
		BOOL bUnSet;		/* A helper flag if "-" was given with the switch */
		BOOL bParSetted;	/* A helper flag if parameters of switch were given */
	} stAttribs;		/* Displays files with this attributes only */
	struct
	{
		enum EOrderBy eCriteria[3];	/* Criterias used to order by */
		BOOL bCriteriaRev[3];		/* If the criteria is in reversed order */
		short sCriteriaCount;		/* The quantity of criterias */
		BOOL bUnSet;				/* A helper flag if "-" was given with the switch */
		BOOL bParSetted;			/* A helper flag if parameters of switch were given */
	} stOrderBy;		/* Ordered by criterias */
	struct
	{
		enum ETimeField eTimeField;	/* The time field that will be used for */
		BOOL bUnSet;				/* A helper flag if "-" was given with the switch */
		BOOL bParSetted;			/* A helper flag if parameters of switch were given */
	} stTimeField;		/* The time field to display or use for sorting */
} DIRSWITCHFLAGS, *LPDIRSWITCHFLAGS;


typedef struct _DIRFINDLISTNODE
{
  WIN32_FIND_DATA stFindInfo;
  struct _DIRFINDLISTNODE *ptrNext;
} DIRFINDLISTNODE, *PDIRFINDLISTNODE;


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


/* Globally save the # of dirs, files and bytes,
 * probabaly later pass them to functions. Rob Lake  */
static ULONG recurse_dir_cnt;
static ULONG recurse_file_cnt;
static ULARGE_INTEGER recurse_bytes;


/*
 * help
 *
 * displays help screen for dir
 * Rob Lake
 */
static VOID 
DirHelp(VOID)
{
  ConOutResPaging(TRUE, STRING_DIR_HELP1);
}



/*
 * DirReadParameters
 *
 * Parse the parameters and switches of the command line and exports them
 */
static BOOL 
DirReadParam(LPTSTR Line,				/* [IN] The line with the parameters & switches */
			LPTSTR** params,			/* [OUT] The parameters after parsing */
			LPINT entries,				/* [OUT] The number of parameters after parsing */
			LPDIRSWITCHFLAGS lpFlags)	/* [IN/OUT] The flags after calculating switches */
{
	TCHAR cCurSwitch;	/* The current switch */
	TCHAR cCurChar;		/* Current examing character */
	TCHAR cCurUChar;	/* Current upper examing character */
	BOOL bNegative;		/* Negative switch */
	BOOL bPNegative;	/* Negative switch parameter */
	BOOL bIntoQuotes;	/* A flag showing if we are in quotes (") */
	LPTSTR ptrStart;	/* A pointer to the first character of a parameter */
	LPTSTR ptrEnd;		/* A pointer to the last character of a parameter */
	LPTSTR temp;

	/* Initialize parameter array */
	if(!params)
		return FALSE;
	*params = NULL;
	*entries = 0;
	ptrStart = NULL;
	ptrEnd = NULL;

	/* Initialize variables; */
	cCurSwitch = _T(' ');
	bNegative = FALSE;
	bPNegative = FALSE;
	bIntoQuotes = FALSE;

	/* We suppose that switch parameters
	   were given to avoid setting them to default
	   if the switch was not given */
	lpFlags->stAttribs.bParSetted = TRUE;
	lpFlags->stOrderBy.bParSetted = TRUE;
	lpFlags->stTimeField.bParSetted = TRUE;

	
	/* Main Loop (see README_DIR.txt) */
	/* scan the command line char per char, and we process its char */
	while (*Line)
	{
		/* we save current character as it is and its upper case */
		cCurChar = *Line;
		cCurUChar = _totupper(*Line);

		/* 1st section (see README_DIR.txt) */
		/* When a switch is expecting */
		if (cCurSwitch == _T('/'))
		{
			if ((cCurUChar == _T('A')) ||(cCurUChar == _T('T')) || (cCurUChar == _T('O')))
			{
				cCurSwitch = cCurUChar;
				switch (cCurUChar)
				{
				case _T('A'):
					lpFlags->stAttribs.bUnSet = bNegative;
					lpFlags->stAttribs.bParSetted = FALSE;
					break;
				case _T('T'):
					lpFlags->stTimeField.bUnSet = bNegative;
					lpFlags->stTimeField.bParSetted = FALSE;
					break;
				case _T('O'):
					lpFlags->stOrderBy.bUnSet = bNegative;
					lpFlags->stOrderBy.bParSetted = FALSE;
					break;
				}
			}
			else if (cCurUChar == _T('L'))
				lpFlags->bLowerCase = ! bNegative;
			else if (cCurUChar == _T('B'))
				lpFlags->bBareFormat = ! bNegative;
			else if (cCurUChar == _T('C'))
				lpFlags->bTSeperator = ! bNegative;
			else if (cCurUChar == _T('W'))
				lpFlags->bWideList = ! bNegative;
			else if (cCurUChar == _T('D'))
				lpFlags->bWideListColSort = ! bNegative;
			else if (cCurUChar == _T('N'))
				lpFlags->bNewLongList = ! bNegative;
			else if (cCurUChar == _T('P'))
				lpFlags->bPause = ! bNegative;
			else if (cCurUChar == _T('Q'))
				lpFlags->bUser = ! bNegative;
			else if (cCurUChar == _T('S'))
				lpFlags->bRecursive = ! bNegative;
			else if (cCurUChar == _T('X'))
				lpFlags->bShortName = ! bNegative;
			else if (cCurChar == _T('4'))
				lpFlags->b4Digit = ! bNegative;
			else if (cCurChar == _T('?'))
			{
				DirHelp();
				return FALSE;
			}
			else if (cCurChar ==  _T('-'))
			{
				bNegative = TRUE;
			}
			else
			{
				error_invalid_switch ((TCHAR)_totupper (*Line));
				return FALSE;
			}

			/* We check if we calculated the negative value and realese the flag */
			if ((cCurChar != _T('-')) && bNegative)
				bNegative = FALSE;

			/* if not a,o,t or - option then next parameter is not a switch */
			if ((cCurSwitch == _T('/')) && (!bNegative))
				cCurSwitch = _T(' ');

		}
		else if ((cCurSwitch == _T(' ')) || (cCurSwitch == _T('P')))
		{
			/* 2nd section (see README_DIR.txt) */
			/* We are expecting parameter or the unknown */

			if (cCurChar == _T('/'))
				cCurSwitch = _T('/');

			/* Process a spacer */
			else if (cCurChar == _T(' '))
			{
				if (!bIntoQuotes)
				{
					cCurSwitch = _T(' ');
					if(ptrStart && ptrEnd)
					{		
						temp = cmd_alloc(((ptrEnd - ptrStart) + 2) * sizeof (TCHAR));
						if(!temp)
							return FALSE;
						memcpy(temp, ptrStart, ((ptrEnd - ptrStart) + 2) * sizeof (TCHAR));
						temp[(ptrEnd - ptrStart + 1)] = _T('\0');
						if(!add_entry(entries, params, temp))
						{
							cmd_free(temp);
							freep(*params);
							return FALSE;
						}

						cmd_free(temp);

						ptrStart = NULL;
						ptrEnd = NULL;
					}
				}

			}
			else if (cCurChar == _T('\"'))
			{
				/* Process a quote */
				bIntoQuotes = !bIntoQuotes;
				if(!bIntoQuotes)
					ptrEnd = Line;
			}
			else
			{
				/* Process a character for parameter */
				if ((cCurSwitch == _T(' ')) && ptrStart && ptrEnd)
				{		
					temp = cmd_alloc(((ptrEnd - ptrStart) + 2) * sizeof (TCHAR));
					if(!temp)
						return FALSE;
					memcpy(temp, ptrStart, ((ptrEnd - ptrStart) + 2) * sizeof (TCHAR));
					temp[(ptrEnd - ptrStart + 1)] = _T('\0');
					if(!add_entry(entries, params, temp))
					{
						cmd_free(temp);
						freep(*params);
						return FALSE;
					}

					cmd_free(temp);

					ptrStart = NULL;
					ptrEnd = NULL;
				}
				cCurSwitch = _T('P');
				if(!ptrStart)
					ptrStart = ptrEnd = Line;
				ptrEnd = Line;
			}
		}
		else
		{
			/* 3rd section (see README_DIR.txt) */
			/* We are waiting for switch parameters */

			/* Check if there are no more switch parameters */
			if ((cCurChar == _T('/')) || ( cCurChar == _T(' ')))
			{
				/* Wrong desicion path, reprocess current character */
				cCurSwitch = cCurChar;
				continue;
			}
			/* Process parameter switch */
			switch(cCurSwitch)
			{
			case _T('A'):	/* Switch parameters for /A (attributes filter) */
				/* Ok a switch parameter was given */
				lpFlags->stAttribs.bParSetted = TRUE;

				if (cCurChar == _T(':'))
					/* =V= dead command, used to make the "if" work */
					cCurChar = cCurChar;
				else if(cCurChar == _T('-'))
					bPNegative = TRUE;
				else if(cCurUChar == _T('D'))
				{
					lpFlags->stAttribs.dwAttribMask |= FILE_ATTRIBUTE_DIRECTORY;
					if (bPNegative)
						lpFlags->stAttribs.dwAttribVal &= ~FILE_ATTRIBUTE_DIRECTORY;
					else
						lpFlags->stAttribs.dwAttribVal |= FILE_ATTRIBUTE_DIRECTORY;
				}
				else if(cCurUChar == _T('R'))
				{
					lpFlags->stAttribs.dwAttribMask |= FILE_ATTRIBUTE_READONLY;
					if (bPNegative)
						lpFlags->stAttribs.dwAttribVal &= ~FILE_ATTRIBUTE_READONLY;
					else
						lpFlags->stAttribs.dwAttribVal |= FILE_ATTRIBUTE_READONLY;
				}
				else if(cCurUChar == _T('H'))
				{
					lpFlags->stAttribs.dwAttribMask |= FILE_ATTRIBUTE_HIDDEN;
					if (bPNegative)
						lpFlags->stAttribs.dwAttribVal &= ~FILE_ATTRIBUTE_HIDDEN;
					else
						lpFlags->stAttribs.dwAttribVal |= FILE_ATTRIBUTE_HIDDEN;
				}
				else if(cCurUChar == _T('A'))
				{
					lpFlags->stAttribs.dwAttribMask |= FILE_ATTRIBUTE_ARCHIVE;
					if (bPNegative)
						lpFlags->stAttribs.dwAttribVal &= ~FILE_ATTRIBUTE_ARCHIVE;
					else
						lpFlags->stAttribs.dwAttribVal |= FILE_ATTRIBUTE_ARCHIVE;
				}
				else if(cCurUChar == _T('S'))
				{
					lpFlags->stAttribs.dwAttribMask |= FILE_ATTRIBUTE_SYSTEM;
					if (bPNegative)
						lpFlags->stAttribs.dwAttribVal &= ~FILE_ATTRIBUTE_SYSTEM;
					else
						lpFlags->stAttribs.dwAttribVal |= FILE_ATTRIBUTE_SYSTEM;
				}
				else
				{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -