From 9f0ebd0b549fd2b225aa404af676152d0a1b78e7 Mon Sep 17 00:00:00 2001 From: Jeffrey Morlan Date: Sun, 5 Apr 2009 01:50:24 +0000 Subject: [PATCH] - Simplified code for CD, PUSHD, and POPD commands and also fixed some bugs. svn path=/trunk/; revision=40365 --- reactos/base/shell/cmd/cmd.c | 8 -- reactos/base/shell/cmd/cmd.h | 2 +- reactos/base/shell/cmd/dirstack.c | 84 +++-------- reactos/base/shell/cmd/internal.c | 226 ++++++------------------------ 4 files changed, 56 insertions(+), 264 deletions(-) diff --git a/reactos/base/shell/cmd/cmd.c b/reactos/base/shell/cmd/cmd.c index b1943f6b226..11a30d3822d 100644 --- a/reactos/base/shell/cmd/cmd.c +++ b/reactos/base/shell/cmd/cmd.c @@ -1653,10 +1653,6 @@ Initialize() SetConsoleMode (hIn, ENABLE_PROCESSED_INPUT); -#ifdef INCLUDE_CMD_CHDIR - InitLastPath (); -#endif - for (ptr = cmdLine; *ptr; ptr++) { if (*ptr == _T('/')) @@ -1791,10 +1787,6 @@ static VOID Cleanup() DestroyDirectoryStack (); #endif -#ifdef INCLUDE_CMD_CHDIR - FreeLastPath (); -#endif - #ifdef FEATURE_HISTORY CleanHistory(); #endif diff --git a/reactos/base/shell/cmd/cmd.h b/reactos/base/shell/cmd/cmd.h index 206f9db3d1a..00806d0b93f 100644 --- a/reactos/base/shell/cmd/cmd.h +++ b/reactos/base/shell/cmd/cmd.h @@ -329,7 +329,7 @@ INT cmd_mklink(LPTSTR); /* Prototypes for MISC.C */ INT GetRootPath(TCHAR *InPath,TCHAR *OutPath,INT size); -BOOL SetRootPath(TCHAR *InPath); +BOOL SetRootPath(TCHAR *oldpath,TCHAR *InPath); TCHAR cgetchar (VOID); BOOL CheckCtrlBreak (INT); BOOL add_entry (LPINT ac, LPTSTR **arg, LPCTSTR entry); diff --git a/reactos/base/shell/cmd/dirstack.c b/reactos/base/shell/cmd/dirstack.c index c1220b56ffd..4a24b0c5a6a 100644 --- a/reactos/base/shell/cmd/dirstack.c +++ b/reactos/base/shell/cmd/dirstack.c @@ -22,7 +22,7 @@ typedef struct tagDIRENTRY { struct tagDIRENTRY *prev; struct tagDIRENTRY *next; - LPTSTR pszPath; + TCHAR szPath[1]; } DIRENTRY, *LPDIRENTRY; @@ -34,11 +34,7 @@ static LPDIRENTRY lpStackBottom; static INT PushDirectory (LPTSTR pszPath) { - LPDIRENTRY lpDir; - - nErrorLevel = 0; - - lpDir = (LPDIRENTRY)cmd_alloc (sizeof (DIRENTRY)); + LPDIRENTRY lpDir = cmd_alloc(FIELD_OFFSET(DIRENTRY, szPath[_tcslen(pszPath) + 1])); if (!lpDir) { error_out_of_memory (); @@ -46,70 +42,37 @@ PushDirectory (LPTSTR pszPath) } lpDir->prev = NULL; + lpDir->next = lpStackTop; if (lpStackTop == NULL) - { - lpDir->next = NULL; lpStackBottom = lpDir; - } else - { - lpDir->next = lpStackTop; lpStackTop->prev = lpDir; - } lpStackTop = lpDir; - lpDir->pszPath = (LPTSTR)cmd_alloc ((_tcslen(pszPath)+1)*sizeof(TCHAR)); - if (!lpDir->pszPath) - { - cmd_free (lpDir); - error_out_of_memory (); - return -1; - } - - _tcscpy (lpDir->pszPath, pszPath); + _tcscpy(lpDir->szPath, pszPath); nStackDepth++; - return 0; + return nErrorLevel = 0; } static VOID PopDirectory (VOID) { - LPDIRENTRY lpDir; - - nErrorLevel = 0; - - if (nStackDepth == 0) - return; - - lpDir = lpStackTop; + LPDIRENTRY lpDir = lpStackTop; lpStackTop = lpDir->next; if (lpStackTop != NULL) lpStackTop->prev = NULL; else lpStackBottom = NULL; - cmd_free (lpDir->pszPath); cmd_free (lpDir); nStackDepth--; } -static VOID -GetDirectoryStackTop (LPTSTR pszPath) -{ - nErrorLevel = 0; - - if (lpStackTop) - _tcsncpy (pszPath, lpStackTop->pszPath, MAX_PATH); - else - *pszPath = _T('\0'); -} - - /* * initialize directory stack */ @@ -143,8 +106,6 @@ INT GetDirectoryStackDepth (VOID) INT CommandPushd (LPTSTR rest) { TCHAR curPath[MAX_PATH]; - TCHAR newPath[MAX_PATH]; - BOOL bChangePath = FALSE; if (!_tcsncmp (rest, _T("/?"), 2)) { @@ -152,22 +113,15 @@ INT CommandPushd (LPTSTR rest) return 0; } - nErrorLevel = 0; + GetCurrentDirectory (MAX_PATH, curPath); if (rest[0] != _T('\0')) { - GetFullPathName (rest, MAX_PATH, newPath, NULL); - bChangePath = IsValidPathName (newPath); + if (!SetRootPath(NULL, rest)) + return 1; } - GetCurrentDirectory (MAX_PATH, curPath); - if (PushDirectory (curPath)) - return 0; - - if (bChangePath) - _tchdir(newPath); - - return 0; + return PushDirectory(curPath); } @@ -176,25 +130,20 @@ INT CommandPushd (LPTSTR rest) */ INT CommandPopd (LPTSTR rest) { - TCHAR szPath[MAX_PATH]; - + INT ret = 0; if (!_tcsncmp(rest, _T("/?"), 2)) { ConOutResPuts(STRING_DIRSTACK_HELP2); return 0; } - nErrorLevel = 0; + if (nStackDepth == 0) + return 1; - if (GetDirectoryStackDepth () == 0) - return 0; - - GetDirectoryStackTop (szPath); + ret = _tchdir(lpStackTop->szPath) != 0; PopDirectory (); - _tchdir(szPath); - - return 0; + return ret; } @@ -223,8 +172,7 @@ INT CommandDirs (LPTSTR rest) while (lpDir != NULL) { - ConOutPuts (lpDir->pszPath); - + ConOutPuts(lpDir->szPath); lpDir = lpDir->prev; } diff --git a/reactos/base/shell/cmd/internal.c b/reactos/base/shell/cmd/internal.c index d8e42726d5c..702a6f4ecaa 100644 --- a/reactos/base/shell/cmd/internal.c +++ b/reactos/base/shell/cmd/internal.c @@ -141,21 +141,6 @@ #ifdef INCLUDE_CMD_CHDIR -static LPTSTR lpLastPath; - - -VOID InitLastPath (VOID) -{ - lpLastPath = NULL; -} - - -VOID FreeLastPath (VOID) -{ - if (lpLastPath) - cmd_free (lpLastPath); -} - /* help functions for getting current path from drive without changing drive. Return code 0 = ok, 1 = fail. INT GetRootPath("C:",outbuffer,chater size of outbuffer); @@ -166,12 +151,8 @@ VOID FreeLastPath (VOID) INT GetRootPath(TCHAR *InPath,TCHAR *OutPath,INT size) { - INT retcode = 1; - - if (_tcslen(InPath)>1) + if (InPath[0] && InPath[1] == _T(':')) { - if (InPath[1]==_T(':')) - { INT t=0; if ((InPath[0] >= _T('0')) && (InPath[0] <= _T('9'))) @@ -190,76 +171,41 @@ INT GetRootPath(TCHAR *InPath,TCHAR *OutPath,INT size) t = (InPath[0] - _T('A')) +1; } - if (_tgetdcwd(t,OutPath,size) != NULL) - { - return 0; - } - } - } - - /* fail */ - if (_tcslen(InPath)>1) - { - if (InPath[1]==_T(':')) - return 1; + return _tgetdcwd(t,OutPath,size) == NULL; } /* Get current directory */ - retcode = GetCurrentDirectory(size,OutPath); - if (retcode==0) - return 1; - - return 0; + return !GetCurrentDirectory(size,OutPath); } -BOOL SetRootPath(TCHAR *InPath) +BOOL SetRootPath(TCHAR *oldpath, TCHAR *InPath) { - TCHAR oldpath[MAX_PATH]; TCHAR OutPath[MAX_PATH]; TCHAR OutPathTemp[MAX_PATH]; - TCHAR OutPathTemp2[MAX_PATH]; - BOOL fail; - - /* Get The current directory path and save it */ - fail = GetCurrentDirectory(MAX_PATH,oldpath); - if (!fail) - return 1; - - /* Get current drive directory path if C: was only pass down*/ - - if (_tcsncicmp(&InPath[1],_T(":\\"),2)!=0) - { - if (!GetRootPath(InPath,OutPathTemp,MAX_PATH)) - _tcscpy(OutPathTemp,InPath); - } - else - { - _tcscpy(OutPathTemp,InPath); - } - - _tcsupr(OutPathTemp); /* The use of both of these together will correct the case of a path where as one alone or GetFullPath will not. Exameple: c:\windows\SYSTEM32 => C:\WINDOWS\system32 */ - GetFullPathName(OutPathTemp, MAX_PATH, OutPathTemp2, NULL); - GetPathCase(OutPathTemp2, OutPath); + if (GetFullPathName(InPath, MAX_PATH, OutPathTemp, NULL)) + { + GetPathCase(OutPathTemp, OutPath); - fail = SetCurrentDirectory(OutPath); - if (!fail) - return 1; + /* Use _tchdir, since unlike SetCurrentDirectory it updates + * the current-directory-on-drive environment variables. */ + if (_tchdir(OutPath) != 0) + { + ConErrFormatMessage(GetLastError()); + nErrorLevel = 1; + return FALSE; + } + /* Keep original drive in ordinary CD/CHDIR (without /D switch). */ + if (oldpath != NULL && _tcsncicmp(OutPath, oldpath, 2) != 0) + SetCurrentDirectory(oldpath); + } - - SetCurrentDirectory(OutPath); - GetCurrentDirectory(MAX_PATH,OutPath); - _tchdir(OutPath); - - if (_tcsncicmp(OutPath,oldpath,2)!=0) - SetCurrentDirectory(oldpath); - - return 0; + return TRUE; } @@ -269,16 +215,8 @@ BOOL SetRootPath(TCHAR *InPath) */ INT cmd_chdir (LPTSTR param) { - - WIN32_FIND_DATA f; - HANDLE hFile; - BOOL bChangeDrive = FALSE; - TCHAR szPath[MAX_PATH]; - TCHAR szFinalPath[MAX_PATH]; - TCHAR * tmpPath; TCHAR szCurrent[MAX_PATH]; - INT i; - + BOOL bChangeDrive = FALSE; /* Filter out special cases first */ @@ -289,35 +227,18 @@ INT cmd_chdir (LPTSTR param) return 0; } - /* Set Error Level to Success */ + /* Remove " */ + StripQuotes(param); + + /* Set Error Level to Success */ nErrorLevel = 0; - /* Input String Contains /D Switch */ - if (!_tcsncicmp(param, _T("/D"), 2)) - { - bChangeDrive = TRUE; - tmpPath = _tcsstr(param,_T(" ")); - if(!tmpPath) - { - /* Didnt find an directories */ - ConErrResPrintf(STRING_ERROR_PATH_NOT_FOUND); - nErrorLevel = 1; - return 1; - } - tmpPath++; - _tcscpy(szPath,tmpPath); - } - else - { - _tcscpy(szPath,param); - } - /* Print Current Directory on a disk */ - if (_tcslen(szPath) == 2 && szPath[1] == _T(':')) + if (_tcslen(param) == 2 && param[1] == _T(':')) { - if(GetRootPath(szPath,szCurrent,MAX_PATH)) + if (GetRootPath(param, szCurrent, MAX_PATH)) { - nErrorLevel = 1; + error_invalid_drive(); return 1; } ConOutPuts(szCurrent); @@ -325,95 +246,26 @@ INT cmd_chdir (LPTSTR param) } /* Get Current Directory */ - GetRootPath(_T("."),szCurrent,MAX_PATH); - - /* Remove " */ - i = 0; - while(i < (INT)_tcslen(szPath)) - { - if(szPath[i] == _T('\"')) - memmove(&szPath[i],&szPath[i + 1], _tcslen(&szPath[i]) * sizeof(TCHAR)); - else - i++; - } - - tmpPath = szPath; - while (_istspace (*tmpPath)) - tmpPath++; - _tcscpy(szPath,tmpPath); - - if (szPath[0] == _T('\0')) + GetCurrentDirectory(MAX_PATH, szCurrent); + if (param[0] == _T('\0')) { ConOutPuts(szCurrent); return 0; } - - /* change to full path if relative path was given */ - GetFullPathName(szPath,MAX_PATH,szFinalPath,NULL); - - if(szFinalPath[_tcslen(szFinalPath) - 1] == _T('\\') && _tcslen(szFinalPath) > 3) - szFinalPath[_tcslen(szFinalPath) - 1] = _T('\0'); - - /* Handle Root Directory Alone*/ - if (_tcslen(szFinalPath) == 3 && szFinalPath[1] == _T(':')) + /* Input String Contains /D Switch */ + if (!_tcsncicmp(param, _T("/D"), 2)) { - if(!SetRootPath(szFinalPath)) - { - /* Change prompt if it is one the same drive or /D */ - if(bChangeDrive || !_tcsncicmp(szFinalPath,szCurrent,1)) - SetCurrentDirectory(szFinalPath); - return 0; - } - /* Didnt find an directories */ - ConErrResPrintf(STRING_ERROR_PATH_NOT_FOUND); - nErrorLevel = 1; - return 1; - + bChangeDrive = TRUE; + param += 2; + while (_istspace(*param)) + param++; } - /* Get a list of all the files */ - hFile = FindFirstFile (szFinalPath, &f); + if (!SetRootPath(bChangeDrive ? NULL : szCurrent, param)) + return 1; - do - { - if(hFile == INVALID_HANDLE_VALUE) - { - ConErrFormatMessage (GetLastError(), szFinalPath); - nErrorLevel = 1; - return 1; - } - - /* Strip the paths back to the folder they are in */ - for(i = (_tcslen(szFinalPath) - 1); i > -1; i--) - if(szFinalPath[i] != _T('\\')) - szFinalPath[i] = _T('\0'); - else - break; - - _tcscat(szFinalPath,f.cFileName); - - if ((f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) - { - if(!SetRootPath(szFinalPath)) - { - /* Change for /D */ - if(bChangeDrive) - { - _tcsupr(szFinalPath); - GetPathCase(szFinalPath, szPath); - SetCurrentDirectory(szPath); - } - return 0; - } - - } - }while(FindNextFile (hFile, &f)); - - /* Didnt find an directories */ - ConErrResPrintf(STRING_ERROR_PATH_NOT_FOUND); - nErrorLevel = 1; - return 1; + return 0; } #endif