Author: hbelusca
Date: Sat Sep 30 11:39:08 2017
New Revision: 75997
URL:
http://svn.reactos.org/svn/reactos?rev=75997&view=rev
Log:
[CMD]: Diverse improvements:
- Add pre-support for "enable extensions".
- Load CMD settings at startup from the registry (from HKLM and HKCU
Software\\Microsoft\\Command Processor reg key), as done by Windows' CMD.EXE.
- Add support for CMD.EXE /E(:OFF), /X, /Y command-line switches.
- Correctly set the console colors when using CMD.EXE /T: switch.
- Start support for two control characters for the completion: the standard
CompletionChar
and the PathCompletionChar (if one desires to autocomplete *just* directory
names -- or associated -- but not everything), as Windows' CMD.EXE offers.
Modified:
trunk/reactos/base/shell/cmd/cmd.c
trunk/reactos/base/shell/cmd/cmd.h
trunk/reactos/base/shell/cmd/cmdinput.c
trunk/reactos/base/shell/cmd/setlocal.c
Modified: trunk/reactos/base/shell/cmd/cmd.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/cmd.c?rev=7…
==============================================================================
--- trunk/reactos/base/shell/cmd/cmd.c [iso-8859-1] (original)
+++ trunk/reactos/base/shell/cmd/cmd.c [iso-8859-1] Sat Sep 30 11:39:08 2017
@@ -162,6 +162,7 @@
CRITICAL_SECTION ChildProcessRunningLock;
BOOL bUnicodeOutput = FALSE;
BOOL bDisableBatchEcho = FALSE;
+BOOL bEnableExtensions = TRUE;
BOOL bDelayedExpansion = FALSE;
BOOL bTitleSet = FALSE;
DWORD dwChildProcessId = 0;
@@ -174,7 +175,7 @@
static NtReadVirtualMemoryProc NtReadVirtualMemoryPtr = NULL;
#ifdef INCLUDE_CMD_COLOR
-WORD wDefColor; /* default color */
+WORD wDefColor = 0; /* Default color */
#endif
/*
@@ -1532,14 +1533,164 @@
}
#endif
+
static VOID
-ExecuteAutoRunFile(HKEY hkeyRoot)
+LoadRegistrySettings(HKEY hKeyRoot)
+{
+ LONG lRet;
+ HKEY hKey;
+ /*
+ * Buffer big enough to hold the string L"4294967295",
+ * corresponding to the literal 0xFFFFFFFF (MAX_ULONG) in decimal.
+ */
+ DWORD Buffer[6];
+ DWORD dwType, len;
+
+ lRet = RegOpenKeyEx(hKeyRoot,
+ _T("Software\\Microsoft\\Command Processor"),
+ 0,
+ KEY_QUERY_VALUE,
+ &hKey);
+ if (lRet != ERROR_SUCCESS)
+ return;
+
+#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)
+ {
+ /* 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)
{
TCHAR autorun[2048];
DWORD len = sizeof autorun;
HKEY hkey;
- if (RegOpenKeyEx(hkeyRoot,
+ if (RegOpenKeyEx(hKeyRoot,
_T("SOFTWARE\\Microsoft\\Command Processor"),
0,
KEY_READ,
@@ -1612,18 +1763,45 @@
_tcscpy(commandline, ptr);
}
+
+#ifdef INCLUDE_CMD_COLOR
+
+BOOL ConGetDefaultAttributes(PWORD pwDefAttr)
+{
+ BOOL Success;
+ HANDLE hConsole;
+ CONSOLE_SCREEN_BUFFER_INFO csbi;
+
+ /* Do not modify *pwDefAttr if we fail, in which case use default attributes */
+
+ hConsole = CreateFile(_T("CONOUT$"), GENERIC_READ|GENERIC_WRITE,
+ FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
+ OPEN_EXISTING, 0, NULL);
+ if (hConsole == INVALID_HANDLE_VALUE)
+ return FALSE; // No default console
+
+ Success = GetConsoleScreenBufferInfo(hConsole, &csbi);
+ if (Success)
+ *pwDefAttr = csbi.wAttributes;
+
+ CloseHandle(hConsole);
+ return Success;
+}
+
+#endif
+
+
/*
- * 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 len;
TCHAR *ptr, *cmdLine, option = 0;
BOOL AlwaysStrip = FALSE;
BOOL AutoRun = TRUE;
@@ -1641,9 +1819,14 @@
NtReadVirtualMemoryPtr = (NtReadVirtualMemoryProc)GetProcAddress(NtDllModule,
"NtReadVirtualMemory");
}
+ /* Load the registry settings */
+ LoadRegistrySettings(HKEY_LOCAL_MACHINE);
+ LoadRegistrySettings(HKEY_CURRENT_USER);
+
+ /* Initialize our locale */
InitLocale();
- /* get default input and output console handles */
+ /* Get default input and output console handles */
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
hIn = GetStdHandle(STD_INPUT_HANDLE);
@@ -1651,17 +1834,17 @@
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);
@@ -1731,9 +1914,8 @@
#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'))
@@ -1742,10 +1924,40 @@
}
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)
+ SetScreenColor(wDefColor, FALSE);
+#endif
if (!*ptr)
{
@@ -1779,7 +1991,7 @@
}
-static VOID Cleanup()
+static VOID Cleanup(VOID)
{
/* run cmdexit.bat */
if (IsExistingFile (_T("cmdexit.bat")))
@@ -1823,52 +2035,33 @@
*/
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;
-
- 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);
- }
-
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 */
Modified: trunk/reactos/base/shell/cmd/cmd.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/cmd.h?rev=7…
==============================================================================
--- trunk/reactos/base/shell/cmd/cmd.h [iso-8859-1] (original)
+++ trunk/reactos/base/shell/cmd/cmd.h [iso-8859-1] Sat Sep 30 11:39:08 2017
@@ -51,7 +51,7 @@
/* 16k = max buffer size */
#define BUFF_SIZE 16384
-/* global variables */
+/* Global variables */
extern HANDLE hOut;
extern HANDLE hIn;
extern LPTSTR lpOriginalEnvironment;
@@ -61,6 +61,7 @@
extern BOOL bIgnoreEcho;
extern BOOL bExit;
extern BOOL bDisableBatchEcho;
+extern BOOL bEnableExtensions;
extern BOOL bDelayedExpansion;
extern INT nErrorLevel;
extern SHORT maxx;
@@ -115,6 +116,12 @@
/* Prototypes for CMDINPUT.C */
BOOL ReadCommand (LPTSTR, INT);
+
+extern TCHAR AutoCompletionChar;
+extern TCHAR PathCompletionChar;
+
+#define IS_COMPLETION_DISABLED(CompletionCtrl) \
+ ((CompletionCtrl) == 0x00 || (CompletionCtrl) == 0x0D || (CompletionCtrl) >=
0x20)
/* Prototypes for CMDTABLE.C */
Modified: trunk/reactos/base/shell/cmd/cmdinput.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/cmdinput.c?…
==============================================================================
--- trunk/reactos/base/shell/cmd/cmdinput.c [iso-8859-1] (original)
+++ trunk/reactos/base/shell/cmd/cmdinput.c [iso-8859-1] Sat Sep 30 11:39:08 2017
@@ -101,6 +101,16 @@
*/
#include "precomp.h"
+
+/*
+ * See
https://technet.microsoft.com/en-us/library/cc978715.aspx
+ * and
https://technet.microsoft.com/en-us/library/cc940805.aspx
+ * to know the differences between those two settings.
+ * Values 0x00, 0x0D (carriage return) and 0x20 (space) disable completion.
+ */
+TCHAR AutoCompletionChar = _T('\t'); // Default is 0x20
+TCHAR PathCompletionChar = _T('\t'); // Default is 0x20
+
SHORT maxx;
SHORT maxy;
Modified: trunk/reactos/base/shell/cmd/setlocal.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/setlocal.c?…
==============================================================================
--- trunk/reactos/base/shell/cmd/setlocal.c [iso-8859-1] (original)
+++ trunk/reactos/base/shell/cmd/setlocal.c [iso-8859-1] Sat Sep 30 11:39:08 2017
@@ -12,6 +12,7 @@
typedef struct _SETLOCAL
{
struct _SETLOCAL *Prev;
+ BOOL EnableExtensions;
BOOL DelayedExpansion;
LPTSTR Environment;
} SETLOCAL;
@@ -52,6 +53,7 @@
return 1;
}
Saved->Prev = bc->setlocal;
+ Saved->EnableExtensions = bEnableExtensions;
Saved->DelayedExpansion = bDelayedExpansion;
Saved->Environment = DuplicateEnvironment();
if (!Saved->Environment)
@@ -68,9 +70,11 @@
for (i = 0; i < argc; i++)
{
if (!_tcsicmp(arg[i], _T("enableextensions")))
- /* not implemented, ignore */;
+ /* FIXME: not implemented! */
+ bEnableExtensions = TRUE;
else if (!_tcsicmp(arg[i], _T("disableextensions")))
- /* not implemented, ignore */;
+ /* FIXME: not implemented! */
+ bEnableExtensions = FALSE;
else if (!_tcsicmp(arg[i], _T("enabledelayedexpansion")))
bDelayedExpansion = TRUE;
else if (!_tcsicmp(arg[i], _T("disabledelayedexpansion")))
@@ -97,6 +101,7 @@
return 0;
bc->setlocal = Saved->Prev;
+ bEnableExtensions = Saved->EnableExtensions;
bDelayedExpansion = Saved->DelayedExpansion;
/* First, clear out the environment. Since making any changes to the