📄 cmd.c
字号:
if ((tmp = FindArg (*varName - _T('0'))))
{
if ( varNameLen )
*varNameLen = 2;
if ( !*tmp )
return _T("");
if ( !GrowIfNecessary ( _tcslen(tmp)+1, &ret, &retlen ) )
return NULL;
_tcscpy ( ret, tmp );
return ret;
}
if ( !GrowIfNecessary ( 3, &ret, &retlen ) )
return NULL;
ret[0] = _T('%');
ret[1] = *varName;
ret[2] = 0;
if ( varNameLen )
*varNameLen = 2;
return ret;
case _T('*'):
if(bc == NULL)
{
//
// No batch file to see here, move along
//
if ( !GrowIfNecessary ( 3, &ret, &retlen ) )
return NULL;
ret[0] = _T('%');
ret[1] = _T('*');
ret[2] = 0;
if ( varNameLen )
*varNameLen = 2;
return ret;
}
//
// Copy over the raw params(not including the batch file name
//
if ( !GrowIfNecessary ( _tcslen(bc->raw_params)+1, &ret, &retlen ) )
return NULL;
if ( varNameLen )
*varNameLen = 2;
_tcscpy ( ret, bc->raw_params );
return ret;
case _T('%'):
if ( !GrowIfNecessary ( 2, &ret, &retlen ) )
return NULL;
ret[0] = _T('%');
ret[1] = 0;
if ( varNameLen )
*varNameLen = 2;
return ret;
case _T('?'):
/* TODO FIXME 10 is only max size for 32-bit */
if ( !GrowIfNecessary ( 11, &ret, &retlen ) )
return NULL;
_sntprintf ( ret, retlen, _T("%u"), nErrorLevel);
ret[retlen-1] = 0;
if ( varNameLen )
*varNameLen = 2;
return ret;
}
if ( ModeSetA )
{
/* HACK for set/a */
if ( !GrowIfNecessary ( 2, &ret, &retlen ) )
return NULL;
ret[0] = _T('%');
ret[1] = 0;
if ( varNameLen )
*varNameLen = 1;
return ret;
}
p = _tcschr ( varName, _T('%') );
if ( !p )
{
SetLastError ( ERROR_INVALID_PARAMETER );
return NULL;
}
size = p-varName;
if ( varNameLen )
*varNameLen = size + 2;
p = alloca ( (size+1) * sizeof(TCHAR) );
memmove ( p, varName, size * sizeof(TCHAR) );
p[size] = 0;
varName = p;
return GetEnvVarOrSpecial ( varName );
}
/*
* do the prompt/input/process loop
*
*/
static INT
ProcessInput (BOOL bFlag)
{
TCHAR commandline[CMDLINE_LENGTH];
TCHAR readline[CMDLINE_LENGTH];
LPTSTR ip;
LPTSTR cp;
LPCTSTR tmp;
BOOL bEchoThisLine;
BOOL bModeSetA;
BOOL bIsBatch;
do
{
/* if no batch input then... */
if (!(ip = ReadBatchLine (&bEchoThisLine)))
{
if (bFlag)
return nErrorLevel;
ReadCommand (readline, CMDLINE_LENGTH);
ip = readline;
bEchoThisLine = FALSE;
bIsBatch = FALSE;
}
else
{
bIsBatch = TRUE;
}
/* skip leading blanks */
while ( _istspace(*ip) )
++ip;
cp = commandline;
bModeSetA = FALSE;
while (*ip)
{
if ( *ip == _T('%') )
{
UINT envNameLen;
LPCTSTR envVal = GetParsedEnvVar ( ip, &envNameLen, bModeSetA );
if ( envVal )
{
ip += envNameLen;
cp = _stpcpy ( cp, envVal );
}
}
if (_istcntrl (*ip))
*ip = _T(' ');
*cp++ = *ip++;
/* HACK HACK HACK check whether bModeSetA needs to be toggled */
*cp = 0;
tmp = commandline;
tmp += _tcsspn(tmp,_T(" \t"));
/* first we find and skip and pre-redirections... */
while (( tmp ) &&
( _tcschr(_T("<>"),*tmp)
|| !_tcsncmp(tmp,_T("1>"),2)
|| !_tcsncmp(tmp,_T("2>"),2) ))
{
if ( _istdigit(*tmp) )
tmp += 2;
else
tmp++;
tmp += _tcsspn(tmp,_T(" \t"));
if ( *tmp == _T('\"') )
{
tmp = _tcschr(tmp+1,_T('\"'));
if ( tmp )
++tmp;
}
else
tmp = _tcspbrk(tmp,_T(" \t"));
if ( tmp )
tmp += _tcsspn(tmp,_T(" \t"));
}
/* we should now be pointing to the actual command
* (if there is one yet)*/
if ( tmp )
{
/* if we're currently substituting ( which is default )
* check to see if we've parsed out a set/a. if so, we
* need to disable substitution until we come across a
* redirection */
if ( !bModeSetA )
{
/* look for set /a */
if ( !_tcsnicmp(tmp,_T("set"),3) )
{
tmp += 3;
tmp += _tcsspn(tmp,_T(" \t"));
if ( !_tcsnicmp(tmp,_T("/a"),2) )
bModeSetA = TRUE;
}
}
/* if we're not currently substituting, it means we're
* already inside a set /a. now we need to look for
* a redirection in order to turn redirection back on */
else
{
/* look for redirector of some kind after the command */
while ( (tmp = _tcspbrk ( tmp, _T("^<>|") )) )
{
if ( *tmp == _T('^') )
{
if ( _tcschr(_T("<>|&"), *++tmp ) && *tmp )
++tmp;
}
else
{
bModeSetA = FALSE;
break;
}
}
}
}
}
*cp = _T('\0');
/* strip trailing spaces */
while ((--cp >= commandline) && _istspace (*cp));
*(cp + 1) = _T('\0');
/* JPP 19980807 */
/* Echo batch file line */
if (bEchoThisLine)
{
PrintPrompt ();
ConOutPuts (commandline);
}
if (!CheckCtrlBreak(BREAK_INPUT) && *commandline)
{
ParseCommandLine (commandline);
if (bEcho && !bIgnoreEcho && (!bIsBatch || bEchoThisLine))
ConOutChar ('\n');
bIgnoreEcho = FALSE;
}
}
while (!bCanExit || !bExit);
return nErrorLevel;
}
/*
* control-break handler.
*/
BOOL WINAPI BreakHandler (DWORD dwCtrlType)
{
DWORD dwWritten;
INPUT_RECORD rec;
static BOOL SelfGenerated = FALSE;
if ((dwCtrlType != CTRL_C_EVENT) &&
(dwCtrlType != CTRL_BREAK_EVENT))
{
return FALSE;
}
else
{
if(SelfGenerated)
{
SelfGenerated = FALSE;
return TRUE;
}
}
if (bChildProcessRunning == TRUE)
{
SelfGenerated = TRUE;
GenerateConsoleCtrlEvent (dwCtrlType, 0);
return TRUE;
}
rec.EventType = KEY_EVENT;
rec.Event.KeyEvent.bKeyDown = TRUE;
rec.Event.KeyEvent.wRepeatCount = 1;
rec.Event.KeyEvent.wVirtualKeyCode = _T('C');
rec.Event.KeyEvent.wVirtualScanCode = _T('C') - 35;
rec.Event.KeyEvent.uChar.AsciiChar = _T('C');
rec.Event.KeyEvent.uChar.UnicodeChar = _T('C');
rec.Event.KeyEvent.dwControlKeyState = RIGHT_CTRL_PRESSED;
WriteConsoleInput(
hIn,
&rec,
1,
&dwWritten);
bCtrlBreak = TRUE;
/* FIXME: Handle batch files */
//ConOutPrintf(_T("^C"));
return TRUE;
}
VOID AddBreakHandler (VOID)
{
SetConsoleCtrlHandler ((PHANDLER_ROUTINE)BreakHandler, TRUE);
}
VOID RemoveBreakHandler (VOID)
{
SetConsoleCtrlHandler ((PHANDLER_ROUTINE)BreakHandler, FALSE);
}
/*
* show commands and options that are available.
*
*/
#if 0
static VOID
ShowCommands (VOID)
{
/* print command list */
ConOutResPuts(STRING_CMD_HELP1);
PrintCommandList();
/* print feature list */
ConOutResPuts(STRING_CMD_HELP2);
#ifdef FEATURE_ALIASES
ConOutResPuts(STRING_CMD_HELP3);
#endif
#ifdef FEATURE_HISTORY
ConOutResPuts(STRING_CMD_HELP4);
#endif
#ifdef FEATURE_UNIX_FILENAME_COMPLETION
ConOutResPuts(STRING_CMD_HELP5);
#endif
#ifdef FEATURE_DIRECTORY_STACK
ConOutResPuts(STRING_CMD_HELP6);
#endif
#ifdef FEATURE_REDIRECTION
ConOutResPuts(STRING_CMD_HELP7);
#endif
ConOutChar(_T('\n'));
}
#endif
/*
* set up global initializations and process parameters
*
* argc - number of parameters to command.com
* argv - command-line parameters
*
*/
static VOID
Initialize (int argc, const TCHAR* argv[])
{
TCHAR commandline[CMDLINE_LENGTH];
TCHAR ModuleName[_MAX_PATH + 1];
INT i;
TCHAR lpBuffer[2];
//INT len;
//TCHAR *ptr, *cmdLine;
/* get version information */
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx (&osvi);
/* Some people like to run ReactOS cmd.exe on Win98, it helps in the
* build process. So don't link implicitly against ntdll.dll, load it
* dynamically instead */
if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
/* ntdll is always present on NT */
NtDllModule = GetModuleHandle(TEXT("ntdll.dll"));
}
else
{
/* not all 9x versions have a ntdll.dll, try to load it */
NtDllModule = LoadLibrary(TEXT("ntdll.dll"));
}
if (NtDllModule != NULL)
{
NtQueryInformationProcessPtr = (NtQueryInformationProcessProc)GetProcAddress(NtDllModule, "NtQueryInformationProcess");
NtReadVirtualMemoryPtr = (NtReadVirtualMemoryProc)GetProcAddress(NtDllModule, "NtReadVirtualMemory");
}
#ifdef _DEBUG
DebugPrintf (_T("[command args:\n"));
for (i = 0; i < argc; i++)
{
DebugPrintf (_T("%d. %s\n"), i, argv[i]);
}
DebugPrintf (_T("]\n"));
#endif
InitLocale ();
/* get default input and output console handles */
hOut = GetStdHandle (STD_OUTPUT_HANDLE);
hIn = GetStdHandle (STD_INPUT_HANDLE);
/* Set EnvironmentVariable PROMPT if it does not exists any env value.
for you can change the EnvirommentVariable for prompt before cmd start
this patch are not 100% right, if it does not exists a PROMPT value cmd should use
$P$G as defualt not set EnvirommentVariable PROMPT to $P$G if it does not exists */
if (GetEnvironmentVariable(_T("PROMPT"),lpBuffer, sizeof(lpBuffer) / sizeof(lpBuffer[0])) == 0)
SetEnvironmentVariable (_T("PROMPT"), _T("$P$G"));
if (argc >= 2 && !_tcsncmp (argv[1], _T("/?"), 2))
{
ConOutResPaging(TRUE,STRING_CMD_HELP8);
cmd_exit(0);
}
SetConsoleMode (hIn, ENABLE_PROCESSED_INPUT);
#ifdef INCLUDE_CMD_CHDIR
InitLastPath ();
#endif
#ifdef FATURE_ALIASES
InitializeAlias ();
#endif
if (argc >= 2)
{
for (i = 1; i < argc; i++)
{
if (!_tcsicmp (argv[i], _T("/p")))
{
if (!IsExistingFile (_T("\\autoexec.bat")))
{
#ifdef INCLUDE_CMD_DATE
cmd_date (_T(""), _T(""));
#endif
#ifdef INCLUDE_CMD_TIME
cmd_time (_T(""), _T(""));
#endif
}
else
{
ParseCommandLine (_T("\\autoexec.bat"));
}
bCanExit = FALSE;
}
else if (!_tcsicmp (argv[i], _T("/c")))
{
/* This just runs a program and exits */
++i;
if (i < argc)
{
_tcscpy (commandline, argv[i]);
while (++i < argc)
{
_tcscat (commandline, _T(" "));
_tcscat (commandline, argv[i]);
}
ParseCommandLine(commandline);
cmd_exit (ProcessInput (TRUE));
}
else
{
cmd_exit (0);
}
}
else if (!_tcsicmp (argv[i], _T("/k")))
{
/* This just runs a program and remains */
++i;
if (i < argc)
{
_tcscpy (commandline, _T("\""));
_tcscat (commandline, argv[i]);
_tcscat (commandline, _T("\""));
while (++i < argc)
{
_tcscat (commandline, _T(" "));
_tcscat (commandline, argv[i]);
}
ParseCommandLine(commandline);
}
}
#ifdef INCLUDE_CMD_COLOR
else if (!_tcsnicmp (argv[i], _T("/t:"), 3))
{
/* process /t (color) argument */
wDefColor = (WORD)_tcstoul (&argv[i][3], NULL, 16);
wColor = wDefColor;
SetScreenColor (wColor, TRUE);
}
#endif
}
}
/* run cmdstart.bat */
if (IsExistingFile (_T("cmdstart.bat")))
{
ParseCommandLine (_T("cmdstart.bat"));
}
else if (IsExistingFile (_T("\\cmdstart.bat")))
{
ParseCommandLine (_T("\\cmdstart.bat"));
}
#ifdef FEATURE_DIR_STACK
/* initialize directory stack */
InitDirectoryStack ();
#endif
#ifdef FEATURE_HISTORY
/*initialize history*/
InitHistory();
#endif
/* Set COMSPEC environment variable */
if (0 != GetModuleFileName (NULL, ModuleName, _MAX_PATH + 1))
{
ModuleName[_MAX_PATH] = _T('\0');
SetEnvironmentVariable (_T("COMSPEC"), ModuleName);
}
/* add ctrl break handler */
AddBreakHandler ();
}
static VOID Cleanup (int argc, const TCHAR *argv[])
{
/* run cmdexit.bat */
if (IsExistingFile (_T("cmdexit.bat")))
{
ConErrResPuts(STRING_CMD_ERROR5);
ParseCommandLine (_T("cmdexit.bat"));
}
else if (IsExistingFile (_T("\\cmdexit.bat")))
{
ConErrResPuts (STRING_CMD_ERROR5);
ParseCommandLine (_T("\\cmdexit.bat"));
}
#ifdef FEATURE_ALIASES
DestroyAlias ();
#endif
#ifdef FEATURE_DIECTORY_STACK
/* destroy directory stack */
DestroyDirectoryStack ();
#endif
#ifdef INCLUDE_CMD_CHDIR
FreeLastPath ();
#endif
#ifdef FEATURE_HISTORY
CleanHistory();
#endif
/* remove ctrl break handler */
RemoveBreakHandler ();
SetConsoleMode( GetStdHandle( STD_INPUT_HANDLE ),
ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_ECHO_INPUT );
if (NtDllModule != NULL)
{
FreeLibrary(NtDllModule);
}
}
/*
* main function
*/
int cmd_main (int argc, const TCHAR *argv[])
{
TCHAR startPath[MAX_PATH];
CONSOLE_SCREEN_BUFFER_INFO Info;
INT nExitCode;
GetCurrentDirectory(MAX_PATH,startPath);
_tchdir(startPath);
SetFileApisToOEM();
InputCodePage= 0;
OutputCodePage = 0;
hConsole = CreateFile(_T("CONOUT$"), GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, 0, NULL);
if (GetConsoleScreenBufferInfo(hConsole, &Info) == FALSE)
{
ConErrFormatMessage(GetLastError());
return(1);
}
wColor = Info.wAttributes;
wDefColor = wColor;
InputCodePage= GetConsoleCP();
OutputCodePage = GetConsoleOutputCP();
CMD_ModuleHandle = GetModuleHandle(NULL);
/* check switches on command-line */
Initialize(argc, argv);
/* call prompt routine */
nExitCode = ProcessInput(FALSE);
/* do the cleanup */
Cleanup(argc, argv);
cmd_exit(nExitCode);
return(nExitCode);
}
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -