* Improved chdir/cd command.
*
* 02-Apr-2004 (Magnus Olsen <magnus@greatlord.com>)
- * Remove all hard code string so they can be
+ * Remove all hard code string so they can be
* translate to other langues.
+ *
+ * 19-jul-2005 (Brandon Turner <turnerb7@msu.edu)
+ * Rewrite the CD, it working as Windows 2000 CMD
+ *
+ * 19-jul-2005 (Magnus Olsen <magnus@greatlord.com)
+ * Add SetRootPath and GetRootPath
*/
-#include "precomp.h"
+#include <precomp.h>
#include "resource.h"
#ifdef INCLUDE_CMD_CHDIR
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);
+ the first param can have any size, if the the two frist
+ letter are not a drive with : it will get Currentpath on
+ current drive exacly as GetCurrentDirectory does.
+ */
+
+INT GetRootPath(TCHAR *InPath,TCHAR *OutPath,INT size)
+{
+ INT retcode = 1;
+
+ if (_tcslen(InPath)>1)
+ {
+ if (InPath[1]==_T(':'))
+ {
+ INT t=0;
+
+ if ((InPath[0] >= _T('0')) && (InPath[0] <= _T('9')))
+ {
+ t = (InPath[0] - _T('0')) +28;
+ }
+
+ if ((InPath[0] >= _T('a')) && (InPath[0] <= _T('z')))
+ {
+ t = (InPath[0] - _T('a')) +1;
+ InPath[0] = t + _T('A') - 1;
+ }
+
+ if ((InPath[0] >= _T('A')) && (InPath[0] <= _T('Z')))
+ {
+ 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;
+ }
+
+ /* Get current directory */
+ retcode = GetCurrentDirectory(size,OutPath);
+ if (retcode==0)
+ return 1;
+
+ return 0;
+}
+
+
+BOOL SetRootPath(TCHAR *InPath)
+{
+ TCHAR oldpath[MAX_PATH];
+ TCHAR OutPath[MAX_PATH];
+ TCHAR OutPathUpper[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,OutPathUpper,MAX_PATH))
+ _tcscpy(OutPathUpper,InPath);
+ }
+ else
+ {
+ _tcscpy(OutPathUpper,InPath);
+ }
+
+ _tcsupr(OutPathUpper);
+ GetLongPathName(OutPathUpper, OutPath, MAX_PATH);
+
+ fail = SetCurrentDirectory(OutPath);
+ if (!fail)
+ return 1;
+
+
+
+ SetCurrentDirectory(OutPath);
+ GetCurrentDirectory(MAX_PATH,OutPath);
+ _tchdir(OutPath);
+
+ if (_tcsncicmp(OutPath,oldpath,2)!=0)
+ SetCurrentDirectory(oldpath);
+
+ return 0;
+}
+
+
/*
* CD / CHDIR
*
*/
INT cmd_chdir (LPTSTR cmd, LPTSTR param)
{
- LPTSTR dir; /* pointer to the directory to change to */
- LPTSTR lpOldPath;
- LPTSTR endofstring; /* pointer to the null character in the directory to change to */
- LPTSTR lastquote; /* pointer to the last quotation mark in the directory to change to */
- WCHAR szMsg[RC_STRING_MAX_SIZE];
-
- /*Should we better declare a variable containing _tsclen(dir) ? It's used a few times,
- but on the other hand paths are generally not very long*/
-
- if (!_tcsncmp (param, _T("/?"), 2))
- {
- LoadString( GetModuleHandle(NULL), STRING_CD_HELP, (LPTSTR) szMsg,sizeof(szMsg));
- ConOutPuts (_T((LPTSTR)szMsg));
+
+ WIN32_FIND_DATA f;
+ HANDLE hFile;
+ BOOL bChangeDrive = FALSE;
+ TCHAR szPath[MAX_PATH];
+ TCHAR szFinalPath[MAX_PATH];
+ TCHAR * tmpPath;
+ TCHAR szCurrent[MAX_PATH];
+ TCHAR szMsg[RC_STRING_MAX_SIZE];
+ INT i;
+
+
+ /* Filter out special cases first */
+
+ /* Print Help */
+ if (!_tcsncmp(param, _T("/?"), 2))
+ {
+ ConOutResPaging(TRUE,STRING_CD_HELP);
return 0;
}
+
+ /* Set Error Level to Success */
+ nErrorLevel = 0;
- /* The whole param string is our parameter these days. The only thing we do is eliminating every quotation mark */
- /* Is it safe to change the characters param is pointing to? I presume it is, as there doesn't seem to be any
- post-processing of it after the function call (what would that accomplish?) */
-
- dir=param;
- endofstring=dir+_tcslen(dir);
-
- while ((lastquote = _tcsrchr(dir, _T('\"'))))
+ /* Input String Contains /D Switch */
+ if (!_tcsncicmp(param, _T("/D"), 2))
{
- endofstring--;
- memmove(lastquote,lastquote+1,endofstring-lastquote);
- *endofstring=_T('\0');
+ bChangeDrive = TRUE;
+ tmpPath = _tcsstr(param,_T(" "));
+ tmpPath++;
+ _tcscpy(szPath,tmpPath);
+
}
-
- /* if doing a CD and no parameters given, print out current directory */
- if (!dir || !dir[0])
+ else
{
- TCHAR szPath[MAX_PATH];
-
- GetCurrentDirectory (MAX_PATH, szPath);
-
- ConOutPuts (szPath);
-
-
+ _tcscpy(szPath,param);
+ }
+
+ /* Print Current Directory on a disk */
+ if (_tcslen(szPath) == 2 && szPath[1] == _T(':'))
+ {
+ if(GetRootPath(szPath,szCurrent,MAX_PATH))
+ {
+ nErrorLevel = 1;
+ return 1;
+ }
+ ConOutPuts(szCurrent);
return 0;
}
-
- if (dir && _tcslen (dir) == 1 && *dir == _T('-'))
+
+ /* Get Current Directory */
+ GetRootPath(_T("."),szCurrent,MAX_PATH);
+
+ /* Remove " */
+ i = 0;
+ while(i < _tcslen(szPath))
{
- if (lpLastPath)
- dir = lpLastPath;
+ if(szPath[i] == _T('\"'))
+ memmove(&szPath[i],&szPath[i + 1], _tcslen(&szPath[i]) * sizeof(TCHAR));
else
- return 0;
+ i++;
}
- else if (dir && _tcslen (dir)==2 && dir[1] == _T(':'))
+
+ tmpPath = szPath;
+ while (_istspace (*tmpPath))
+ tmpPath++;
+ _tcscpy(szPath,tmpPath);
+
+ if (szPath[0] == _T('\0'))
{
- TCHAR szRoot[3] = _T("A:");
- TCHAR szPath[MAX_PATH];
-
- szRoot[0] = _totupper (dir[0]);
- GetFullPathName (szRoot, MAX_PATH, szPath, NULL);
-
- /* PathRemoveBackslash */
- if (_tcslen (szPath) > 3)
- {
- LPTSTR p = _tcsrchr (szPath, _T('\\'));
- *p = _T('\0');
- }
-
- ConOutPuts (szPath);
-
-
+ ConOutPuts(szCurrent);
return 0;
}
-
- /* remove trailing \ if any, but ONLY if dir is not the root dir */
- if (_tcslen (dir) > 3 && dir[_tcslen (dir) - 1] == _T('\\'))
- dir[_tcslen(dir) - 1] = _T('\0');
-
-
- /* store current directory */
- lpOldPath = (LPTSTR)malloc (MAX_PATH * sizeof(TCHAR));
- GetCurrentDirectory (MAX_PATH, lpOldPath);
-
- if (!SetCurrentDirectory (dir))
- {
- //ErrorMessage (GetLastError(), _T("CD"));
- ConOutFormatMessage(GetLastError());
-
- /* throw away current directory */
- free (lpOldPath);
- lpOldPath = NULL;
-
+
+
+ /* 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(':'))
+ {
+ 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 */
+ LoadString(CMD_ModuleHandle, STRING_ERROR_PATH_NOT_FOUND, szMsg, RC_STRING_MAX_SIZE);
+ ConErrPrintf(szMsg);
+ nErrorLevel = 1;
return 1;
+
}
- else
+
+ /* Get a list of all the files */
+ hFile = FindFirstFile (szFinalPath, &f);
+
+ do
{
- GetCurrentDirectory(MAX_PATH, dir);
- if (dir[0]!=lpOldPath[0])
- {
- SetCurrentDirectory(lpOldPath);
- free(lpOldPath);
+ if(hFile == INVALID_HANDLE_VALUE)
+ {
+ ConErrFormatMessage (GetLastError(), szFinalPath);
+ nErrorLevel = 1;
+ return 1;
}
- else
- {
- if (lpLastPath)
- free (lpLastPath);
- lpLastPath = lpOldPath;
+
+ /* 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);
+ GetLongPathName(szFinalPath, szPath, MAX_PATH);
+ SetCurrentDirectory(szPath);
+ }
+ return 0;
+ }
+
}
- }
-
-
- return 0;
+ }while(FindNextFile (hFile, &f));
+
+ /* Didnt find an directories */
+ LoadString(CMD_ModuleHandle, STRING_ERROR_PATH_NOT_FOUND, szMsg, RC_STRING_MAX_SIZE);
+ ConErrPrintf(szMsg);
+ nErrorLevel = 1;
+ return 1;
}
+
#endif
LPTSTR place; /* used to search for the \ when no space is used */
LPTSTR *p = NULL;
INT argc;
- WCHAR szMsg[RC_STRING_MAX_SIZE];
if (!_tcsncmp (param, _T("/?"), 2))
{
- LoadString( GetModuleHandle(NULL), STRING_MKDIR_HELP, (LPTSTR) szMsg,sizeof(szMsg));
- ConOutPuts (_T((LPTSTR)szMsg));
-
+ ConOutResPaging(TRUE,STRING_MKDIR_HELP);
return 0;
}
if (!dir)
{
- LoadString( GetModuleHandle(NULL), STRING_PARAM_ERROR, (LPTSTR) szMsg,sizeof(szMsg));
- ConErrPrintf (_T((LPTSTR)szMsg));
+ ConErrResPuts (STRING_ERROR_REQ_PARAM_MISSING);
return 1;
}
LPTSTR *p = NULL;
INT argc;
-
- WCHAR szMsg[RC_STRING_MAX_SIZE];
-
if (!_tcsncmp (param, _T("/?"), 2))
{
- LoadString( GetModuleHandle(NULL), STRING_RMDIR_HELP, (LPTSTR) szMsg,sizeof(szMsg));
-
- ConOutPuts (_T((LPTSTR)szMsg));
-
+ ConOutResPaging(TRUE,STRING_RMDIR_HELP);
return 0;
}
if (!dir)
{
- LoadString( GetModuleHandle(NULL), STRING_PARAM_ERROR, (LPTSTR) szMsg,sizeof(szMsg));
- ConErrPrintf (_T((LPTSTR)szMsg));
-
+ ConErrResPuts(STRING_ERROR_REQ_PARAM_MISSING);
return 1;
}
*/
INT CommandExit (LPTSTR cmd, LPTSTR param)
{
- WCHAR szMsg[RC_STRING_MAX_SIZE];
-
if (!_tcsncmp (param, _T("/?"), 2))
+ ConOutResPaging(TRUE,STRING_EXIT_HELP);
+
+ if (bc != NULL && _tcsnicmp(param,_T("/b"),2) == 0)
{
- LoadString( GetModuleHandle(NULL), STRING_EXIT_HELP, (LPTSTR) szMsg,sizeof(szMsg));
- ConOutPuts (_T((LPTSTR)szMsg));
- return 0;
+ param += 2;
+ while (_istspace (*param))
+ param++;
+ if (_istdigit(*param))
+ nErrorLevel = _ttoi(param);
+ ExitBatch (NULL);
}
+
+ else
+ bExit = TRUE;
- bExit = TRUE;
+
return 0;
-}
+}
#ifdef INCLUDE_CMD_REM
/*
*/
INT CommandRem (LPTSTR cmd, LPTSTR param)
{
- WCHAR szMsg[RC_STRING_MAX_SIZE];
-
if (!_tcsncmp (param, _T("/?"), 2))
{
- LoadString( GetModuleHandle(NULL), STRING_REM_HELP, (LPTSTR) szMsg,sizeof(szMsg));
- ConOutPuts (_T((LPTSTR)szMsg));
+ ConOutResPaging(TRUE,STRING_REM_HELP);
}
return 0;
return 0;
}
+INT CommandShowCommandsDetail (LPTSTR cmd, LPTSTR param)
+{
+ PrintCommandListDetail ();
+ return 0;
+}
+
/* EOF */