fix for bug 875.  Patch by jvangael@wisc.edu
Modified: trunk/reactos/subsys/system/cmd/cmd.h
Modified: trunk/reactos/subsys/system/cmd/dir.c
Modified: trunk/reactos/subsys/system/cmd/misc.c

Modified: trunk/reactos/subsys/system/cmd/cmd.h
--- trunk/reactos/subsys/system/cmd/cmd.h	2005-11-02 01:39:30 UTC (rev 18946)
+++ trunk/reactos/subsys/system/cmd/cmd.h	2005-11-02 13:49:14 UTC (rev 18947)
@@ -293,6 +293,7 @@
 BOOL SetRootPath(TCHAR *InPath);
 TCHAR  cgetchar (VOID);
 BOOL   CheckCtrlBreak (INT);
+BOOL add_entry (LPINT ac, LPTSTR **arg, LPCTSTR entry);
 LPTSTR *split (LPTSTR, LPINT, BOOL);
 VOID   freep (LPTSTR *);
 LPTSTR _stpcpy (LPTSTR, LPCTSTR);

Modified: trunk/reactos/subsys/system/cmd/dir.c
--- trunk/reactos/subsys/system/cmd/dir.c	2005-11-02 01:39:30 UTC (rev 18946)
+++ trunk/reactos/subsys/system/cmd/dir.c	2005-11-02 13:49:14 UTC (rev 18947)
@@ -228,20 +228,29 @@
  *
  * 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 *param,			/* [OUT] The parameters after parsing */
-	     LPDIRSWITCHFLAGS lpFlags)	/* [IN/OUT] The flags after calculating switches */
+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 ptrLast;	/* A pointer to the last character of param */
+	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 */
+	*params = malloc(sizeof(LPTSTR));
+	if(!params)
+		return FALSE;
+	*params = NULL;
+	*entries = 0;
+	ptrStart = NULL;
+	ptrEnd = NULL;
 
 	/* Initialize variables; */
 	cCurSwitch = _T(' ');
@@ -249,10 +258,6 @@
 	bPNegative = FALSE;
 	bIntoQuotes = FALSE;
 
-	/* No parameters yet  */
-	*param = NULL;
-	ptrLast = NULL;
-
 	/* We suppose that switch parameters
 	   were given to avoid setting them to default
 	   if the switch was not given */
@@ -352,8 +357,25 @@
 				if (!bIntoQuotes)
 				{
 					cCurSwitch = _T(' ');
-					if ((*param) && !(ptrLast))
-						ptrLast = Line;
+					if(ptrStart && ptrEnd)
+					{		
+						temp = malloc((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))
+						{
+							free(temp);
+							freep(*params);
+							return FALSE;
+						}
+
+						free(temp);
+
+						ptrStart = NULL;
+						ptrEnd = NULL;
+					}
 				}
 
 			}
@@ -361,19 +383,35 @@
 			{
 				/* Process a quote */
 				bIntoQuotes = !bIntoQuotes;
-				if (!bIntoQuotes) ptrLast = Line;
+				if(!bIntoQuotes)
+					ptrEnd = Line;
 			}
 			else
 			{
 				/* Process a character for parameter */
-				if ((cCurSwitch == _T(' ')) && (*param))
-				{
-					error_too_many_parameters(Line);
-					return FALSE;
+				if ((cCurSwitch == _T(' ')) && ptrStart && ptrEnd)
+				{		
+					temp = malloc((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))
+					{
+						free(temp);
+						freep(*params);
+						return FALSE;
+					}
+
+					free(temp);
+
+					ptrStart = NULL;
+					ptrEnd = NULL;
 				}
 				cCurSwitch = _T('P');
-				if (!(*param))
-					*param = Line;
+				if(!ptrStart)
+					ptrStart = ptrEnd = Line;
+				ptrEnd = Line;
 			}
 		}
 		else
@@ -522,8 +560,26 @@
 		Line++;
 	}
 	/* Terminate the parameters */
-	if (ptrLast) *ptrLast = 0;
+	if(ptrStart && ptrEnd)
+	{		
+		temp = malloc((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))
+		{
+			free(temp);
+			freep(*params);
+			return FALSE;
+		}
 
+		free(temp);
+
+		ptrStart = NULL;
+		ptrEnd = NULL;
+	}
+
 	/* Calculate the switches with no switch paramater  */
 	if (!(lpFlags->stAttribs.bParSetted))
 	{
@@ -1120,7 +1176,21 @@
 		   ConOutPrintf(szMsg,ulFiles, szBuffer);
 	}
 
-	/* Print total  directories and freespace */
+	/* Print File Summary */
+	/* Condition to print summary is:
+	   If we are not in bare format and if we have results! */
+	if (ulFiles > 0)
+	{
+		ConvertULargeInteger(u64Bytes, szBuffer, 20, lpFlags->bTSeperator);
+		LoadString(CMD_ModuleHandle, STRING_DIR_HELP8, szMsg, RC_STRING_MAX_SIZE);
+		if(lpFlags->bPause)
+		   ConOutPrintfPaging(FALSE,szMsg,ulFiles, szBuffer);
+		else
+		   ConOutPrintf(szMsg,ulFiles, szBuffer);
+
+	}
+
+	/* Print total directories and freespace */
 	szRoot[0] = szPath[0];
 	GetUserDiskFreeSpace(szRoot, &uliFree);
 	ConvertULargeInteger(uliFree, szBuffer, sizeof(szBuffer), lpFlags->bTSeperator);
@@ -1710,13 +1780,11 @@
 	PDIRFINDLISTNODE ptrNextNode;	/* A pointer used for relatives refernces */
 TCHAR szFullPath[MAX_PATH];				/* The full path that we are listing with trailing \ */
 TCHAR szFullFileSpec[MAX_PATH];			/* The full path with file specs that we ll request\ */
-TCHAR szBytes[20];						/* A string for converting ULARGE integer */
 DWORD dwCount;							/* A counter of files found in directory */
 DWORD dwCountFiles;						/* Counter for files */
 DWORD dwCountDirs;						/* Counter for directories */
 ULARGE_INTEGER u64CountBytes;			/* Counter for bytes */
 ULARGE_INTEGER u64Temp;					/* A temporary counter */
-TCHAR szMsg[RC_STRING_MAX_SIZE];
 
 	/* Initialize Variables */
 	ptrStartNode = NULL;
@@ -1853,20 +1921,6 @@
 	/* Free array */
 	free(ptrFileArray);
 
-	/* Print Directory Summary */
-	/* Condition to print summary is:
-	   If we are not in bare format and if we have results! */
-	if (!(lpFlags->bBareFormat) && (dwCount > 0))
-	{
-		ConvertULargeInteger(u64CountBytes, szBytes, 20, lpFlags->bTSeperator);
-		LoadString(CMD_ModuleHandle, STRING_DIR_HELP8, szMsg, RC_STRING_MAX_SIZE);
-		if(lpFlags->bPause)
-		   ConOutPrintfPaging(FALSE,szMsg,dwCountFiles, szBytes);
-		else
-		   ConOutPrintf(szMsg,dwCountFiles, szBytes);
-
-	}
-
 	/* Add statistics to recursive statistics*/
 	recurse_dir_cnt += dwCountDirs;
 	recurse_file_cnt += dwCountFiles;
@@ -1922,14 +1976,18 @@
  */
 INT CommandDir(LPTSTR first, LPTSTR rest)
 {
-	TCHAR  dircmd[256];	/* A variable to store the DIRCMD enviroment variable */
-	TCHAR  szPath[MAX_PATH];
-	TCHAR  szFilespec[MAX_PATH];
-	LPTSTR param;
-	INT    nLine = 0;
+	TCHAR	dircmd[256];	/* A variable to store the DIRCMD enviroment variable */
+	TCHAR	cDrive;
+	TCHAR	szPath[MAX_PATH];
+	TCHAR	szFilespec[MAX_PATH];
+	LPTSTR*	params;
+	UINT	entries = 0;
+	INT		nLine = 0;
+	UINT	loop = 0;
 	DIRSWITCHFLAGS stFlags;
 
 	/* Initialize variables */
+	cDrive = 0;
 	recurse_dir_cnt = 0L;
 	recurse_file_cnt = 0L;
 	recurse_bytes.QuadPart = 0;
@@ -1958,67 +2016,77 @@
 	
 	/* read the parameters from the DIRCMD environment variable */
 	if (GetEnvironmentVariable (_T("DIRCMD"), dircmd, 256))
-		if (!DirReadParam(dircmd, &param, &stFlags))
+		if (!DirReadParam(dircmd, &params, &entries, &stFlags))
 		{
 			nErrorLevel = 1;
 			return 1;
 		}
 
 	/* read the parameters */
-	if (!DirReadParam(rest, &param, &stFlags))
+	if (!DirReadParam(rest, &params, &entries, &stFlags))
 	{
 		nErrorLevel = 1;
 		return 1;
 	}
 
 	/* default to current directory */
-	if (!param)
-		param = _T(".");
-
-	/* parse the directory info */
-	if (DirParsePathspec (param, szPath, szFilespec))
-	{
-		nErrorLevel = 1;
-		return 1;
+	if(entries == 0) {
+		if(!add_entry(&entries, &params, _T("."))) {
+			nErrorLevel = 1;
+			return 1;
+		}
 	}
 
-/* <Debug :>
-   Uncomment this to show the final state of switch flags*/
-#ifdef _DEBUG
+	for(loop = 0; loop < entries; loop++)
 	{
-		int i;
-		ConOutPrintf(_T("Attributes mask/value %x/%x\n"),stFlags.stAttribs.dwAttribMask,stFlags.stAttribs.dwAttribVal  );
-		ConOutPrintf(_T("(B) Bare format : %i\n"), stFlags.bBareFormat );
-		ConOutPrintf(_T("(C) Thousand : %i\n"), stFlags.bTSeperator );
-		ConOutPrintf(_T("(W) Wide list : %i\n"), stFlags.bWideList );
-		ConOutPrintf(_T("(D) Wide list sort by column : %i\n"), stFlags.bWideListColSort );
-		ConOutPrintf(_T("(L) Lowercase : %i\n"), stFlags.bLowerCase );
-		ConOutPrintf(_T("(N) New : %i\n"), stFlags.bNewLongList );
-		ConOutPrintf(_T("(O) Order : %i\n"), stFlags.stOrderBy.sCriteriaCount );
-		for (i =0;i<stFlags.stOrderBy.sCriteriaCount;i++)
-			ConOutPrintf(_T(" Order Criteria [%i]: %i (Reversed: %i)\n"),i, stFlags.stOrderBy.eCriteria[i], stFlags.stOrderBy.bCriteriaRev[i] );
-		ConOutPrintf(_T("(P) Pause : %i\n"), stFlags.bPause  );
-		ConOutPrintf(_T("(Q) Owner : %i\n"), stFlags.bUser );
-		ConOutPrintf(_T("(S) Recursive : %i\n"), stFlags.bRecursive );
-		ConOutPrintf(_T("(T) Time field : %i\n"), stFlags.stTimeField.eTimeField );
-		ConOutPrintf(_T("(X) Short names : %i\n"), stFlags.bShortName );
-		ConOutPrintf(_T("Parameter : %s\n"), param );
-	}
-#endif
+		/* parse the directory info */
+		if (DirParsePathspec (params[loop], szPath, szFilespec))
+		{
+			nErrorLevel = 1;
+			return 1;
+		}
 
-	/* print the header  */
-	if (!stFlags.bBareFormat)
-		if (!PrintDirectoryHeader (szPath, &nLine, &stFlags))
+	/* <Debug :>
+	   Uncomment this to show the final state of switch flags*/
+	#ifdef _DEBUG
 		{
+			int i;
+			ConOutPrintf(_T("Attributes mask/value %x/%x\n"),stFlags.stAttribs.dwAttribMask,stFlags.stAttribs.dwAttribVal  );
+			ConOutPrintf(_T("(B) Bare format : %i\n"), stFlags.bBareFormat );
+			ConOutPrintf(_T("(C) Thousand : %i\n"), stFlags.bTSeperator );
+			ConOutPrintf(_T("(W) Wide list : %i\n"), stFlags.bWideList );
+			ConOutPrintf(_T("(D) Wide list sort by column : %i\n"), stFlags.bWideListColSort );
+			ConOutPrintf(_T("(L) Lowercase : %i\n"), stFlags.bLowerCase );
+			ConOutPrintf(_T("(N) New : %i\n"), stFlags.bNewLongList );
+			ConOutPrintf(_T("(O) Order : %i\n"), stFlags.stOrderBy.sCriteriaCount );
+			for (i =0;i<stFlags.stOrderBy.sCriteriaCount;i++)
+				ConOutPrintf(_T(" Order Criteria [%i]: %i (Reversed: %i)\n"),i, stFlags.stOrderBy.eCriteria[i], stFlags.stOrderBy.bCriteriaRev[i] );
+			ConOutPrintf(_T("(P) Pause : %i\n"), stFlags.bPause  );
+			ConOutPrintf(_T("(Q) Owner : %i\n"), stFlags.bUser );
+			ConOutPrintf(_T("(S) Recursive : %i\n"), stFlags.bRecursive );
+			ConOutPrintf(_T("(T) Time field : %i\n"), stFlags.stTimeField.eTimeField );
+			ConOutPrintf(_T("(X) Short names : %i\n"), stFlags.bShortName );
+			ConOutPrintf(_T("Parameter : %s\n"), params[loop] );
+		}
+	#endif
+
+		/* Print the drive header if the drive changed */
+		if(cDrive != szPath[0] && !stFlags.bBareFormat) {
+			if (!PrintDirectoryHeader (szPath, &nLine, &stFlags)) {
+				nErrorLevel = 1;
+				return 1;
+			}
+
+			cDrive = szPath[0];
+		}
+		
+
+		/* do the actual dir */
+		if (DirList (szPath, szFilespec, &nLine, &stFlags))
+		{
 			nErrorLevel = 1;
 			return 1;
 		}
-
-	/* do the actual dir */
-	if (DirList (szPath, szFilespec, &nLine, &stFlags))
-	{
-		nErrorLevel = 1;
-		return 1;
 	}
 
 	/* print the footer */

Modified: trunk/reactos/subsys/system/cmd/misc.c
--- trunk/reactos/subsys/system/cmd/misc.c	2005-11-02 01:39:30 UTC (rev 18946)
+++ trunk/reactos/subsys/system/cmd/misc.c	2005-11-02 13:49:14 UTC (rev 18947)
@@ -162,7 +162,7 @@
 }
 
 /* add new entry for new argument */
-static BOOL add_entry (LPINT ac, LPTSTR **arg, LPCTSTR entry)
+BOOL add_entry (LPINT ac, LPTSTR **arg, LPCTSTR entry)
 {
 	LPTSTR q;
 	LPTSTR *oldarg;