* added showcmds function to show commands and options available
*
* 07-Aug-1998 (John P Price <linux-guru@gcfl.net>)
- * Fixed carrage return output to better match MSDOS with echo
+ * Fixed carriage return output to better match MSDOS with echo
* on or off. (marked with "JPP 19980708")
*
* 07-Dec-1998 (Eric Kohl)
*
* 06-jul-2005 (Magnus Olsen <magnus@greatlord.com>)
* translate '%errorlevel%' to the internal value.
- * Add proper memmory alloc ProcessInput, the error
- * handling for memmory handling need to be improve
+ * Add proper memory alloc ProcessInput, the error
+ * handling for memory handling need to be improve
*/
#include "precomp.h"
#include <reactos/buildno.h>
#include <reactos/version.h>
-#ifndef NT_SUCCESS
-#define NT_SUCCESS(StatCode) ((NTSTATUS)(StatCode) >= 0)
-#endif
-
typedef NTSTATUS (WINAPI *NtQueryInformationProcessProc)(HANDLE, PROCESSINFOCLASS,
PVOID, ULONG, PULONG);
typedef NTSTATUS (WINAPI *NtReadVirtualMemoryProc)(HANDLE, PVOID, PVOID, ULONG, PULONG);
-BOOL bExit = FALSE; /* indicates EXIT was typed */
-BOOL bCanExit = TRUE; /* indicates if this shell is exitable */
+BOOL bExit = FALSE; /* Indicates EXIT was typed */
+BOOL bCanExit = TRUE; /* Indicates if this shell is exitable */
BOOL bCtrlBreak = FALSE; /* Ctrl-Break or Ctrl-C hit */
BOOL bIgnoreEcho = FALSE; /* Set this to TRUE to prevent a newline, when executing a command */
+static BOOL fSingleCommand = 0; /* When we are executing something passed on the command line after /C or /K */
INT nErrorLevel = 0; /* Errorlevel of last launched external program */
CRITICAL_SECTION ChildProcessRunningLock;
-BOOL bUnicodeOutput = FALSE;
BOOL bDisableBatchEcho = FALSE;
+BOOL bEnableExtensions = TRUE;
BOOL bDelayedExpansion = FALSE;
DWORD dwChildProcessId = 0;
-OSVERSIONINFO osvi;
-HANDLE hIn;
-HANDLE hOut;
LPTSTR lpOriginalEnvironment;
HANDLE CMD_ModuleHandle;
+BOOL bTitleSet = FALSE; /* Indicates whether the console title has been changed and needs to be restored later */
+TCHAR szCurTitle[MAX_PATH];
+
static NtQueryInformationProcessProc NtQueryInformationProcessPtr = NULL;
static NtReadVirtualMemoryProc NtReadVirtualMemoryPtr = NULL;
+/*
+ * Default output file stream translation mode is UTF8, but CMD switches
+ * allow to change it to either UTF16 (/U) or ANSI (/A).
+ */
+CON_STREAM_MODE OutputStreamMode = UTF8Text; // AnsiText;
+
#ifdef INCLUDE_CMD_COLOR
-WORD wDefColor; /* default color */
+WORD wDefColor = 0; /* Default color */
#endif
/*
* insert commas into a number
*/
INT
-ConvertULargeInteger(ULONGLONG num, LPTSTR des, UINT len, BOOL bPutSeperator)
+ConvertULargeInteger(ULONGLONG num, LPTSTR des, UINT len, BOOL bPutSeparator)
{
TCHAR temp[39]; /* maximum length with nNumberGroups == 1 */
UINT n, iTarget;
n = 0;
iTarget = nNumberGroups;
if (!nNumberGroups)
- bPutSeperator = FALSE;
+ bPutSeparator = FALSE;
do
{
- if (iTarget == n && bPutSeperator)
+ if (iTarget == n && bPutSeparator)
{
iTarget += nNumberGroups + 1;
temp[38 - n++] = cThousandSeparator;
}
+static VOID
+SetConTitle(LPCTSTR pszTitle)
+{
+ TCHAR szNewTitle[MAX_PATH];
+
+ if (!pszTitle)
+ return;
+
+ /* Don't do anything if we run inside a batch file, or we are just running a single command */
+ if (bc || (fSingleCommand == 1))
+ return;
+
+ /* Save the original console title and build a new one */
+ GetConsoleTitle(szCurTitle, ARRAYSIZE(szCurTitle));
+ StringCchPrintf(szNewTitle, ARRAYSIZE(szNewTitle),
+ _T("%s - %s"), szCurTitle, pszTitle);
+ bTitleSet = TRUE;
+ ConSetTitle(szNewTitle);
+}
+
+static VOID
+ResetConTitle(VOID)
+{
+ /* Restore the original console title */
+ if (!bc && bTitleSet)
+ {
+ ConSetTitle(szCurTitle);
+ bTitleSet = FALSE;
+ }
+}
/*
- * This command (in first) was not found in the command table
+ * This command (in First) was not found in the command table
*
- * Full - buffer to hold whole command line
+ * Full - output buffer to hold whole command line
* First - first word on command line
* Rest - rest of command line
*/
static INT
Execute(LPTSTR Full, LPTSTR First, LPTSTR Rest, PARSED_COMMAND *Cmd)
{
- TCHAR szFullName[MAX_PATH];
TCHAR *first, *rest, *dot;
- TCHAR szWindowTitle[MAX_PATH];
DWORD dwExitCode = 0;
TCHAR *FirstEnd;
- TCHAR szFullCmdLine [CMDLINE_LENGTH];
+ TCHAR szFullName[MAX_PATH];
+ TCHAR szFullCmdLine[CMDLINE_LENGTH];
TRACE ("Execute: \'%s\' \'%s\'\n", debugstr_aw(First), debugstr_aw(Rest));
/* Though it was already parsed once, we have a different set of rules
- for parsing before we pass to CreateProccess */
+ for parsing before we pass to CreateProcess */
if (First[0] == _T('/') || (First[0] && First[1] == _T(':')))
{
/* Use the entire first word as the program name (no change) */
}
/* Copy the new first/rest into the buffer */
- first = Full;
rest = &Full[FirstEnd - First + 1];
_tcscpy(rest, FirstEnd);
_tcscat(rest, Rest);
+ first = Full;
*FirstEnd = _T('\0');
_tcscpy(first, First);
{
BOOL working = TRUE;
if (!SetCurrentDirectory(first))
- /* Guess they changed disc or something, handle that gracefully and get to root */
{
+ /* Guess they changed disc or something, handle that gracefully and get to root */
TCHAR str[4];
str[0]=first[0];
str[1]=_T(':');
return 1;
}
- GetConsoleTitle (szWindowTitle, MAX_PATH);
+ /* Set the new console title */
+ FirstEnd = first + (FirstEnd - First); /* Point to the separating NULL in the full built string */
+ *FirstEnd = _T(' ');
+ SetConTitle(Full);
/* check if this is a .BAT or .CMD file */
dot = _tcsrchr (szFullName, _T('.'));
{
while (*rest == _T(' '))
rest++;
+
+ *FirstEnd = _T('\0');
TRACE ("[BATCH: %s %s]\n", debugstr_aw(szFullName), debugstr_aw(rest));
dwExitCode = Batch(szFullName, first, rest, Cmd);
}
STARTUPINFO stui;
/* build command line for CreateProcess(): FullName + " " + rest */
- BOOL quoted = !!_tcschr(First, ' ');
+ BOOL quoted = !!_tcschr(First, _T(' '));
_tcscpy(szFullCmdLine, quoted ? _T("\"") : _T(""));
_tcsncat(szFullCmdLine, First, CMDLINE_LENGTH - _tcslen(szFullCmdLine) - 1);
_tcsncat(szFullCmdLine, quoted ? _T("\"") : _T(""), CMDLINE_LENGTH - _tcslen(szFullCmdLine) - 1);
TRACE ("[EXEC: %s]\n", debugstr_aw(szFullCmdLine));
/* fill startup info */
- memset (&stui, 0, sizeof (STARTUPINFO));
- stui.cb = sizeof (STARTUPINFO);
+ memset(&stui, 0, sizeof(stui));
+ stui.cb = sizeof(stui);
+ stui.lpTitle = Full;
stui.dwFlags = STARTF_USESHOWWINDOW;
stui.wShowWindow = SW_SHOWDEFAULT;
/* Set the console to standard mode */
- SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE),
+ SetConsoleMode(ConStreamGetOSHandle(StdIn),
ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT);
if (CreateProcess(szFullName,
NULL,
NULL,
TRUE,
- 0, /* CREATE_NEW_PROCESS_GROUP */
+ 0,
NULL,
NULL,
&stui,
SW_SHOWNORMAL);
}
+ *FirstEnd = _T('\0');
+
if (prci.hProcess != NULL)
{
- if (IsConsoleProcess(prci.hProcess))
+ if (bc != NULL || fSingleCommand != 0 || IsConsoleProcess(prci.hProcess))
{
+ /* when processing a batch file or starting console processes: execute synchronously */
EnterCriticalSection(&ChildProcessRunningLock);
dwChildProcessId = prci.dwProcessId;
}
/* Restore our default console mode */
- SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE),
+ SetConsoleMode(ConStreamGetOSHandle(StdIn),
ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT);
- SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE),
+ SetConsoleMode(ConStreamGetOSHandle(StdOut),
ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT);
}
- /* Get code page if it has been changed */
- InputCodePage= GetConsoleCP();
- OutputCodePage = GetConsoleOutputCP();
- SetConsoleTitle(szWindowTitle);
+ /* Update our local codepage cache */
+ {
+ UINT uNewInputCodePage = GetConsoleCP();
+ UINT uNewOutputCodePage = GetConsoleOutputCP();
+
+ if ((InputCodePage != uNewInputCodePage) ||
+ (OutputCodePage != uNewOutputCodePage))
+ {
+ /* Update the locale as well */
+ InitLocale();
+ }
+
+ InputCodePage = uNewInputCodePage;
+ OutputCodePage = uNewOutputCodePage;
+
+ /* Update the streams codepage cache as well */
+ ConStreamSetCacheCodePage(StdIn , InputCodePage );
+ ConStreamSetCacheCodePage(StdOut, OutputCodePage);
+ ConStreamSetCacheCodePage(StdErr, OutputCodePage);
+ }
+
+ /* Restore the original console title */
+ ResetConTitle();
return dwExitCode;
}
/* Skip over whitespace to rest of line, exclude 'echo' command */
if (_tcsicmp(cmdptr->name, _T("echo")) != 0)
+ {
while (_istspace(*param))
param++;
+ }
+
+ /* Set the new console title */
+ SetConTitle(com);
+
ret = cmdptr->func(param);
+
+ /* Restore the original console title */
+ ResetConTitle();
+
cmd_free(com);
return ret;
}
* process the command line and execute the appropriate functions
* full input/output redirection and piping are supported
*/
-INT ParseCommandLine (LPTSTR cmd)
+INT ParseCommandLine(LPTSTR cmd)
{
INT Ret = 0;
PARSED_COMMAND *Cmd = ParseCommand(cmd);
PROCESS_INFORMATION prci;
/* Get the path to cmd.exe */
- GetModuleFileName(NULL, CmdPath, MAX_PATH);
+ GetModuleFileName(NULL, CmdPath, ARRAYSIZE(CmdPath));
/* Build the parameter string to pass to cmd.exe */
ParamsEnd = _stpcpy(CmdParams, _T("/S/D/C\""));
return prci.hProcess;
}
-static VOID
+static INT
ExecutePipeline(PARSED_COMMAND *Cmd)
{
#ifdef FEATURE_REDIRECTION
while (--nProcesses >= 0)
CloseHandle(hProcess[nProcesses]);
- return;
+ return nErrorLevel;
failed:
if (hInput)
SetStdHandle(STD_INPUT_HANDLE, hOldConIn);
SetStdHandle(STD_OUTPUT_HANDLE, hOldConOut);
#endif
+
+ return nErrorLevel;
}
INT
Ret = ExecuteCommand(Sub->Next);
break;
case C_PIPE:
- ExecutePipeline(Cmd);
+ Ret = ExecutePipeline(Cmd);
break;
case C_IF:
Ret = ExecuteIf(Cmd);
return FALSE;
}
- if (CheckCtrlBreak(BREAK_INPUT))
- {
+ if (readline[0] == _T('\0'))
ConOutChar(_T('\n'));
+
+ if (CheckCtrlBreak(BREAK_INPUT))
return FALSE;
- }
+
+ if (readline[0] == _T('\0'))
+ return FALSE;
+
ip = readline;
}
else
}
static VOID
-ProcessInput()
+ProcessInput(VOID)
{
PARSED_COMMAND *Cmd;
while (!bCanExit || !bExit)
{
+ /* Reset the Ctrl-Break / Ctrl-C state */
+ bCtrlBreak = FALSE;
+
Cmd = ParseCommand(NULL);
if (!Cmd)
continue;
{
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 (!TryEnterCriticalSection(&ChildProcessRunningLock))
{
- SelfGenerated = TRUE;
- GenerateConsoleCtrlEvent (dwCtrlType, 0);
+ /* Child process is running and will have received the control event */
return TRUE;
}
else
LeaveCriticalSection(&ChildProcessRunningLock);
}
+ bCtrlBreak = TRUE;
+
rec.EventType = KEY_EVENT;
rec.Event.KeyEvent.bKeyDown = TRUE;
rec.Event.KeyEvent.wRepeatCount = 1;
rec.Event.KeyEvent.uChar.UnicodeChar = _T('C');
rec.Event.KeyEvent.dwControlKeyState = RIGHT_CTRL_PRESSED;
- WriteConsoleInput(hIn,
+ WriteConsoleInput(ConStreamGetOSHandle(StdIn),
&rec,
1,
&dwWritten);
- bCtrlBreak = TRUE;
/* FIXME: Handle batch files */
- //ConOutPrintf(_T("^C"));
+ // ConOutPrintf(_T("^C"));
return TRUE;
}
-VOID AddBreakHandler (VOID)
+VOID AddBreakHandler(VOID)
{
- SetConsoleCtrlHandler ((PHANDLER_ROUTINE)BreakHandler, TRUE);
+ SetConsoleCtrlHandler(BreakHandler, TRUE);
}
-VOID RemoveBreakHandler (VOID)
+VOID RemoveBreakHandler(VOID)
{
- SetConsoleCtrlHandler ((PHANDLER_ROUTINE)BreakHandler, FALSE);
+ SetConsoleCtrlHandler(BreakHandler, FALSE);
}
*/
#if 0
static VOID
-ShowCommands (VOID)
+ShowCommands(VOID)
{
/* print command list */
ConOutResPuts(STRING_CMD_HELP1);
}
#endif
+
static VOID
-ExecuteAutoRunFile(HKEY hkeyRoot)
+LoadRegistrySettings(HKEY hKeyRoot)
{
- TCHAR autorun[2048];
- DWORD len = sizeof autorun;
- HKEY hkey;
+ LONG lRet;
+ HKEY hKey;
+ DWORD dwType, len;
+ /*
+ * Buffer big enough to hold the string L"4294967295",
+ * corresponding to the literal 0xFFFFFFFF (MAX_ULONG) in decimal.
+ */
+ DWORD Buffer[6];
+
+ lRet = RegOpenKeyEx(hKeyRoot,
+ _T("Software\\Microsoft\\Command Processor"),
+ 0,
+ KEY_QUERY_VALUE,
+ &hKey);
+ if (lRet != ERROR_SUCCESS)
+ return;
- if (RegOpenKeyEx(hkeyRoot,
- _T("SOFTWARE\\Microsoft\\Command Processor"),
- 0,
- KEY_READ,
- &hkey) == ERROR_SUCCESS)
+#ifdef INCLUDE_CMD_COLOR
+ len = sizeof(Buffer);
+ lRet = RegQueryValueEx(hKey,
+ _T("DefaultColor"),
+ NULL,
+ &dwType,
+ (LPBYTE)&Buffer,
+ &len);
+ if (lRet == ERROR_SUCCESS)
+ {
+ /* Overwrite the default attributes */
+ if (dwType == REG_DWORD)
+ wDefColor = (WORD)*(PDWORD)Buffer;
+ else if (dwType == REG_SZ)
+ wDefColor = (WORD)_tcstol((PTSTR)Buffer, NULL, 0);
+ }
+ // else, use the default attributes retrieved before.
+#endif
+
+#if 0
+ len = sizeof(Buffer);
+ lRet = RegQueryValueEx(hKey,
+ _T("DisableUNCCheck"),
+ NULL,
+ &dwType,
+ (LPBYTE)&Buffer,
+ &len);
+ if (lRet == ERROR_SUCCESS)
+ {
+ /* Overwrite the default setting */
+ if (dwType == REG_DWORD)
+ bDisableUNCCheck = !!*(PDWORD)Buffer;
+ else if (dwType == REG_SZ)
+ bDisableUNCCheck = (_ttol((PTSTR)Buffer) == 1);
+ }
+ // else, use the default setting set globally.
+#endif
+
+ len = sizeof(Buffer);
+ lRet = RegQueryValueEx(hKey,
+ _T("DelayedExpansion"),
+ NULL,
+ &dwType,
+ (LPBYTE)&Buffer,
+ &len);
+ if (lRet == ERROR_SUCCESS)
+ {
+ /* Overwrite the default setting */
+ if (dwType == REG_DWORD)
+ bDelayedExpansion = !!*(PDWORD)Buffer;
+ else if (dwType == REG_SZ)
+ bDelayedExpansion = (_ttol((PTSTR)Buffer) == 1);
+ }
+ // else, use the default setting set globally.
+
+ len = sizeof(Buffer);
+ lRet = RegQueryValueEx(hKey,
+ _T("EnableExtensions"),
+ NULL,
+ &dwType,
+ (LPBYTE)&Buffer,
+ &len);
+ if (lRet == ERROR_SUCCESS)
+ {
+ /* Overwrite the default setting */
+ if (dwType == REG_DWORD)
+ bEnableExtensions = !!*(PDWORD)Buffer;
+ else if (dwType == REG_SZ)
+ bEnableExtensions = (_ttol((PTSTR)Buffer) == 1);
+ }
+ // else, use the default setting set globally.
+
+ len = sizeof(Buffer);
+ lRet = RegQueryValueEx(hKey,
+ _T("CompletionChar"),
+ NULL,
+ &dwType,
+ (LPBYTE)&Buffer,
+ &len);
+ if (lRet == ERROR_SUCCESS)
+ {
+ /* Overwrite the default setting */
+ if (dwType == REG_DWORD)
+ AutoCompletionChar = (TCHAR)*(PDWORD)Buffer;
+ else if (dwType == REG_SZ)
+ AutoCompletionChar = (TCHAR)_tcstol((PTSTR)Buffer, NULL, 0);
+ }
+ // else, use the default setting set globally.
+
+ /* Validity check */
+ if (IS_COMPLETION_DISABLED(AutoCompletionChar))
+ {
+ /* Disable autocompletion */
+ AutoCompletionChar = 0x20;
+ }
+
+ len = sizeof(Buffer);
+ lRet = RegQueryValueEx(hKey,
+ _T("PathCompletionChar"),
+ NULL,
+ &dwType,
+ (LPBYTE)&Buffer,
+ &len);
+ if (lRet == ERROR_SUCCESS)
{
- if (RegQueryValueEx(hkey,
+ /* Overwrite the default setting */
+ if (dwType == REG_DWORD)
+ PathCompletionChar = (TCHAR)*(PDWORD)Buffer;
+ else if (dwType == REG_SZ)
+ PathCompletionChar = (TCHAR)_tcstol((PTSTR)Buffer, NULL, 0);
+ }
+ // else, use the default setting set globally.
+
+ /* Validity check */
+ if (IS_COMPLETION_DISABLED(PathCompletionChar))
+ {
+ /* Disable autocompletion */
+ PathCompletionChar = 0x20;
+ }
+
+ /* Adjust completion chars */
+ if (PathCompletionChar >= 0x20 && AutoCompletionChar < 0x20)
+ PathCompletionChar = AutoCompletionChar;
+ else if (AutoCompletionChar >= 0x20 && PathCompletionChar < 0x20)
+ AutoCompletionChar = PathCompletionChar;
+
+ RegCloseKey(hKey);
+}
+
+static VOID
+ExecuteAutoRunFile(HKEY hKeyRoot)
+{
+ LONG lRet;
+ HKEY hKey;
+ DWORD dwType, len;
+ TCHAR AutoRun[2048];
+
+ lRet = RegOpenKeyEx(hKeyRoot,
+ _T("Software\\Microsoft\\Command Processor"),
+ 0,
+ KEY_QUERY_VALUE,
+ &hKey);
+ if (lRet != ERROR_SUCCESS)
+ return;
+
+ len = sizeof(AutoRun);
+ lRet = RegQueryValueEx(hKey,
_T("AutoRun"),
- 0,
- 0,
- (LPBYTE)autorun,
- &len) == ERROR_SUCCESS)
- {
- if (*autorun)
- ParseCommandLine(autorun);
- }
- RegCloseKey(hkey);
+ NULL,
+ &dwType,
+ (LPBYTE)&AutoRun,
+ &len);
+ if ((lRet == ERROR_SUCCESS) && (dwType == REG_EXPAND_SZ || dwType == REG_SZ))
+ {
+ if (*AutoRun)
+ ParseCommandLine(AutoRun);
}
+
+ RegCloseKey(hKey);
}
/* Get the command that comes after a /C or /K switch */
_tcscpy(commandline, ptr);
}
+
/*
- * set up global initializations and process parameters
+ * Set up global initializations and process parameters
*/
static VOID
-Initialize()
+Initialize(VOID)
{
HMODULE NtDllModule;
TCHAR commandline[CMDLINE_LENGTH];
TCHAR ModuleName[_MAX_PATH + 1];
- INT nExitCode;
+ // INT nExitCode;
+
+ HANDLE hIn, hOut;
- //INT len;
TCHAR *ptr, *cmdLine, option = 0;
BOOL AlwaysStrip = FALSE;
BOOL AutoRun = TRUE;
- /* get version information */
- osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- GetVersionEx (&osvi);
+ /* Get version information */
+ InitOSVersion();
/* 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
NtReadVirtualMemoryPtr = (NtReadVirtualMemoryProc)GetProcAddress(NtDllModule, "NtReadVirtualMemory");
}
- InitLocale();
+ /* Load the registry settings */
+ LoadRegistrySettings(HKEY_LOCAL_MACHINE);
+ LoadRegistrySettings(HKEY_CURRENT_USER);
- /* get default input and output console handles */
- hOut = GetStdHandle(STD_OUTPUT_HANDLE);
- hIn = GetStdHandle(STD_INPUT_HANDLE);
+ /* Initialize our locale */
+ InitLocale();
/* Initialize prompt support */
InitPrompt();
#ifdef FEATURE_DIR_STACK
- /* initialize directory stack */
+ /* Initialize directory stack */
InitDirectoryStack();
#endif
#ifdef FEATURE_HISTORY
- /*initialize history*/
+ /* Initialize history */
InitHistory();
#endif
/* Set COMSPEC environment variable */
- if (0 != GetModuleFileName (NULL, ModuleName, _MAX_PATH + 1))
+ if (GetModuleFileName(NULL, ModuleName, ARRAYSIZE(ModuleName)) != 0)
{
ModuleName[_MAX_PATH] = _T('\0');
SetEnvironmentVariable (_T("COMSPEC"), ModuleName);
AddBreakHandler();
/* Set our default console mode */
+ hOut = ConStreamGetOSHandle(StdOut);
+ hIn = ConStreamGetOSHandle(StdIn);
SetConsoleMode(hOut, 0); // Reinitialize the console output mode
SetConsoleMode(hOut, ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT);
SetConsoleMode(hIn , ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT);
}
else if (option == _T('A'))
{
- bUnicodeOutput = FALSE;
+ OutputStreamMode = AnsiText;
}
else if (option == _T('C') || option == _T('K') || option == _T('R'))
{
/* Remainder of command line is a command to be run */
+ fSingleCommand = ((option == _T('K')) << 1) | 1;
break;
}
else if (option == _T('D'))
#ifdef INCLUDE_CMD_COLOR
else if (!_tcsnicmp(ptr, _T("/T:"), 3))
{
- /* process /T (color) argument */
+ /* Process /T (color) argument; overwrite any previous settings */
wDefColor = (WORD)_tcstoul(&ptr[3], &ptr, 16);
- SetScreenColor(wDefColor, FALSE);
}
#endif
else if (option == _T('U'))
{
- bUnicodeOutput = TRUE;
+ OutputStreamMode = UTF16Text;
}
else if (option == _T('V'))
{
+ // FIXME: Check validity of the parameter given to V !
bDelayedExpansion = _tcsnicmp(&ptr[2], _T(":OFF"), 4);
}
+ else if (option == _T('E'))
+ {
+ // FIXME: Check validity of the parameter given to E !
+ bEnableExtensions = _tcsnicmp(&ptr[2], _T(":OFF"), 4);
+ }
+ else if (option == _T('X'))
+ {
+ /* '/X' is identical to '/E:ON' */
+ bEnableExtensions = TRUE;
+ }
+ else if (option == _T('Y'))
+ {
+ /* '/Y' is identical to '/E:OFF' */
+ bEnableExtensions = FALSE;
+ }
}
}
+#ifdef INCLUDE_CMD_COLOR
+ if (wDefColor == 0)
+ {
+ /*
+ * If we still do not have the console colour attribute set,
+ * retrieve the default one.
+ */
+ ConGetDefaultAttributes(&wDefColor);
+ }
+
+ if (wDefColor != 0)
+ ConSetScreenColor(ConStreamGetOSHandle(StdOut), wDefColor, TRUE);
+#endif
+
+ /* Reset the output Standard Streams translation modes and codepage caches */
+ // ConStreamSetMode(StdIn , OutputStreamMode, InputCodePage );
+ ConStreamSetMode(StdOut, OutputStreamMode, OutputCodePage);
+ ConStreamSetMode(StdErr, OutputStreamMode, OutputCodePage);
+
if (!*ptr)
{
/* If neither /C or /K was given, display a simple version string */
ConOutChar(_T('\n'));
ConOutResPrintf(STRING_REACTOS_VERSION,
- _T(KERNEL_RELEASE_STR),
- _T(KERNEL_VERSION_BUILD_STR));
+ _T(KERNEL_VERSION_STR),
+ _T(KERNEL_VERSION_BUILD_STR));
ConOutPuts(_T("(C) Copyright 1998-") _T(COPYRIGHT_YEAR) _T(" ReactOS Team.\n"));
}
{
/* Do the /C or /K command */
GetCmdLineCommand(commandline, &ptr[2], AlwaysStrip);
- nExitCode = ParseCommandLine(commandline);
- if (option != _T('K'))
+ /* nExitCode = */ ParseCommandLine(commandline);
+ if (fSingleCommand == 1)
{
- nErrorLevel = nExitCode;
+ // nErrorLevel = nExitCode;
bExit = TRUE;
}
+ fSingleCommand = 0;
}
}
-static VOID Cleanup()
+static VOID Cleanup(VOID)
{
- /* run cmdexit.bat */
- if (IsExistingFile (_T("cmdexit.bat")))
+ /* Run cmdexit.bat */
+ if (IsExistingFile(_T("cmdexit.bat")))
{
ConErrResPuts(STRING_CMD_ERROR5);
-
- ParseCommandLine (_T("cmdexit.bat"));
+ ParseCommandLine(_T("cmdexit.bat"));
}
- else if (IsExistingFile (_T("\\cmdexit.bat")))
+ else if (IsExistingFile(_T("\\cmdexit.bat")))
{
- ConErrResPuts (STRING_CMD_ERROR5);
- ParseCommandLine (_T("\\cmdexit.bat"));
+ ConErrResPuts(STRING_CMD_ERROR5);
+ ParseCommandLine(_T("\\cmdexit.bat"));
}
-#ifdef FEATURE_DIECTORY_STACK
- /* destroy directory stack */
- DestroyDirectoryStack ();
+#ifdef FEATURE_DIRECTORY_STACK
+ /* Destroy directory stack */
+ DestroyDirectoryStack();
#endif
#ifdef FEATURE_HISTORY
CleanHistory();
#endif
- /* free GetEnvVar's buffer */
+ /* Free GetEnvVar's buffer */
GetEnvVar(NULL);
/* Remove ctrl break handler */
RemoveBreakHandler();
/* Restore the default console mode */
- SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE),
+ SetConsoleMode(ConStreamGetOSHandle(StdIn),
ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT);
- SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE),
+ SetConsoleMode(ConStreamGetOSHandle(StdOut),
ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT);
DeleteCriticalSection(&ChildProcessRunningLock);
*/
int _tmain(int argc, const TCHAR *argv[])
{
- HANDLE hConsole;
TCHAR startPath[MAX_PATH];
- CONSOLE_SCREEN_BUFFER_INFO Info;
InitializeCriticalSection(&ChildProcessRunningLock);
lpOriginalEnvironment = DuplicateEnvironment();
- GetCurrentDirectory(MAX_PATH,startPath);
+ GetCurrentDirectory(ARRAYSIZE(startPath), startPath);
_tchdir(startPath);
SetFileApisToOEM();
- InputCodePage = 0;
- OutputCodePage = 0;
+ InputCodePage = GetConsoleCP();
+ OutputCodePage = GetConsoleOutputCP();
- hConsole = CreateFile(_T("CONOUT$"), GENERIC_READ|GENERIC_WRITE,
- FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
- OPEN_EXISTING, 0, NULL);
- if (hConsole != INVALID_HANDLE_VALUE)
- {
- if (!GetConsoleScreenBufferInfo(hConsole, &Info))
- {
- ConErrFormatMessage(GetLastError());
- CloseHandle(hConsole);
- return(1);
- }
- wDefColor = Info.wAttributes;
- CloseHandle(hConsole);
- }
+ /* Initialize the Console Standard Streams */
+ ConStreamInit(StdIn , GetStdHandle(STD_INPUT_HANDLE) , /*OutputStreamMode*/ AnsiText, InputCodePage);
+ ConStreamInit(StdOut, GetStdHandle(STD_OUTPUT_HANDLE), OutputStreamMode, OutputCodePage);
+ ConStreamInit(StdErr, GetStdHandle(STD_ERROR_HANDLE) , OutputStreamMode, OutputCodePage);
- InputCodePage = GetConsoleCP();
- OutputCodePage = GetConsoleOutputCP();
CMD_ModuleHandle = GetModuleHandle(NULL);
- /* check switches on command-line */
+ /* Perform general initialization, parse switches on command-line */
Initialize();
- /* call prompt routine */
+ /* Call prompt routine */
ProcessInput();
- /* do the cleanup */
+ /* Do the cleanup */
Cleanup();
cmd_free(lpOriginalEnvironment);
cmd_exit(nErrorLevel);
- return(nErrorLevel);
+ return nErrorLevel;
}
/* EOF */