mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 14:25:52 +00:00
Handle quotes in a CMD /C or CMD /K argument properly.
svn path=/trunk/; revision=39795
This commit is contained in:
parent
83f58a9337
commit
9ed19ef909
1 changed files with 87 additions and 60 deletions
|
@ -1529,23 +1529,73 @@ ExecuteAutoRunFile (VOID)
|
||||||
RegCloseKey(hkey);
|
RegCloseKey(hkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get the command that comes after a /C or /K switch */
|
||||||
|
static VOID
|
||||||
|
GetCmdLineCommand(TCHAR *commandline, TCHAR *ptr, BOOL AlwaysStrip)
|
||||||
|
{
|
||||||
|
TCHAR *LastQuote;
|
||||||
|
|
||||||
|
while (_istspace(*ptr))
|
||||||
|
ptr++;
|
||||||
|
|
||||||
|
/* Remove leading quote, find final quote */
|
||||||
|
if (*ptr == _T('"') &&
|
||||||
|
(LastQuote = _tcsrchr(++ptr, _T('"'))) != NULL)
|
||||||
|
{
|
||||||
|
TCHAR *Space;
|
||||||
|
/* Under certain circumstances, all quotes are preserved.
|
||||||
|
* CMD /? documents these conditions as follows:
|
||||||
|
* 1. No /S switch
|
||||||
|
* 2. Exactly two quotes
|
||||||
|
* 3. No "special characters" between the quotes
|
||||||
|
* (CMD /? says &<>()@^| but parentheses did not
|
||||||
|
* trigger this rule when I tested them.)
|
||||||
|
* 4. Whitespace exists between the quotes
|
||||||
|
* 5. Enclosed string is an executable filename
|
||||||
|
*/
|
||||||
|
*LastQuote = _T('\0');
|
||||||
|
for (Space = ptr + 1; Space < LastQuote; Space++)
|
||||||
|
{
|
||||||
|
if (_istspace(*Space)) /* Rule 4 */
|
||||||
|
{
|
||||||
|
if (!AlwaysStrip && /* Rule 1 */
|
||||||
|
!_tcspbrk(ptr, _T("\"&<>@^|")) && /* Rules 2, 3 */
|
||||||
|
SearchForExecutable(ptr, commandline)) /* Rule 5 */
|
||||||
|
{
|
||||||
|
/* All conditions met: preserve both the quotes */
|
||||||
|
*LastQuote = _T('"');
|
||||||
|
_tcscpy(commandline, ptr - 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The conditions were not met: remove both the
|
||||||
|
* leading quote and the last quote */
|
||||||
|
_tcscpy(commandline, ptr);
|
||||||
|
_tcscpy(&commandline[LastQuote - ptr], LastQuote + 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No quotes; just copy */
|
||||||
|
_tcscpy(commandline, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set up global initializations and process parameters
|
* set up global initializations and process parameters
|
||||||
*
|
|
||||||
* argc - number of parameters to command.com
|
|
||||||
* argv - command-line parameters
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
static VOID
|
static VOID
|
||||||
Initialize (int argc, const TCHAR* argv[])
|
Initialize()
|
||||||
{
|
{
|
||||||
TCHAR commandline[CMDLINE_LENGTH];
|
TCHAR commandline[CMDLINE_LENGTH];
|
||||||
TCHAR ModuleName[_MAX_PATH + 1];
|
TCHAR ModuleName[_MAX_PATH + 1];
|
||||||
INT i;
|
|
||||||
TCHAR lpBuffer[2];
|
TCHAR lpBuffer[2];
|
||||||
|
|
||||||
//INT len;
|
//INT len;
|
||||||
//TCHAR *ptr, *cmdLine;
|
TCHAR *ptr, *cmdLine;
|
||||||
|
BOOL AlwaysStrip = FALSE;
|
||||||
|
BOOL ShowVersion = TRUE;
|
||||||
|
|
||||||
/* get version information */
|
/* get version information */
|
||||||
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
||||||
|
@ -1572,13 +1622,8 @@ Initialize (int argc, const TCHAR* argv[])
|
||||||
NtReadVirtualMemoryPtr = (NtReadVirtualMemoryProc)GetProcAddress(NtDllModule, "NtReadVirtualMemory");
|
NtReadVirtualMemoryPtr = (NtReadVirtualMemoryProc)GetProcAddress(NtDllModule, "NtReadVirtualMemory");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmdLine = GetCommandLine();
|
||||||
TRACE ("[command args:\n");
|
TRACE ("[command args: %s]\n", debugstr_aw(cmdLine));
|
||||||
for (i = 0; i < argc; i++)
|
|
||||||
{
|
|
||||||
TRACE ("%d. %s\n", i, debugstr_aw(argv[i]));
|
|
||||||
}
|
|
||||||
TRACE ("]\n");
|
|
||||||
|
|
||||||
InitLocale ();
|
InitLocale ();
|
||||||
|
|
||||||
|
@ -1594,22 +1639,22 @@ Initialize (int argc, const TCHAR* argv[])
|
||||||
SetEnvironmentVariable (_T("PROMPT"), _T("$P$G"));
|
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);
|
SetConsoleMode (hIn, ENABLE_PROCESSED_INPUT);
|
||||||
|
|
||||||
#ifdef INCLUDE_CMD_CHDIR
|
#ifdef INCLUDE_CMD_CHDIR
|
||||||
InitLastPath ();
|
InitLastPath ();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (argc >= 2)
|
for (ptr = cmdLine; *ptr; ptr++)
|
||||||
{
|
{
|
||||||
for (i = 1; i < argc; i++)
|
if (*ptr == _T('/'))
|
||||||
{
|
{
|
||||||
if (!_tcsicmp (argv[i], _T("/p")))
|
if (ptr[1] == _T('?'))
|
||||||
|
{
|
||||||
|
ConOutResPaging(TRUE,STRING_CMD_HELP8);
|
||||||
|
cmd_exit(0);
|
||||||
|
}
|
||||||
|
else if (_totlower(ptr[1]) == _T('p'))
|
||||||
{
|
{
|
||||||
if (!IsExistingFile (_T("\\autoexec.bat")))
|
if (!IsExistingFile (_T("\\autoexec.bat")))
|
||||||
{
|
{
|
||||||
|
@ -1626,56 +1671,38 @@ Initialize (int argc, const TCHAR* argv[])
|
||||||
}
|
}
|
||||||
bCanExit = FALSE;
|
bCanExit = FALSE;
|
||||||
}
|
}
|
||||||
else if (!_tcsicmp (argv[i], _T("/c")))
|
else if (_totlower(ptr[1]) == _T('c'))
|
||||||
{
|
{
|
||||||
/* This just runs a program and exits */
|
/* This just runs a program and exits */
|
||||||
++i;
|
GetCmdLineCommand(commandline, &ptr[2], AlwaysStrip);
|
||||||
if (i < argc)
|
ParseCommandLine(commandline);
|
||||||
{
|
cmd_exit (ProcessInput (TRUE));
|
||||||
_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")))
|
else if (_totlower(ptr[1]) == _T('k'))
|
||||||
{
|
{
|
||||||
/* This just runs a program and remains */
|
/* This just runs a program and remains */
|
||||||
++i;
|
GetCmdLineCommand(commandline, &ptr[2], AlwaysStrip);
|
||||||
if (i < argc)
|
ParseCommandLine(commandline);
|
||||||
{
|
ShowVersion = FALSE;
|
||||||
_tcscpy (commandline, _T("\""));
|
break;
|
||||||
_tcscat (commandline, argv[i]);
|
}
|
||||||
_tcscat (commandline, _T("\""));
|
else if (_totlower(ptr[1]) == _T('s'))
|
||||||
while (++i < argc)
|
{
|
||||||
{
|
AlwaysStrip = TRUE;
|
||||||
_tcscat (commandline, _T(" "));
|
|
||||||
_tcscat (commandline, argv[i]);
|
|
||||||
}
|
|
||||||
ParseCommandLine(commandline);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#ifdef INCLUDE_CMD_COLOR
|
#ifdef INCLUDE_CMD_COLOR
|
||||||
else if (!_tcsnicmp (argv[i], _T("/t:"), 3))
|
else if (!_tcsnicmp(ptr, _T("/t:"), 3))
|
||||||
{
|
{
|
||||||
/* process /t (color) argument */
|
/* process /t (color) argument */
|
||||||
wDefColor = (WORD)_tcstoul (&argv[i][3], NULL, 16);
|
wDefColor = (WORD)_tcstoul(&ptr[3], &ptr, 16);
|
||||||
wColor = wDefColor;
|
wColor = wDefColor;
|
||||||
SetScreenColor (wColor, TRUE);
|
SetScreenColor (wColor, TRUE);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (ShowVersion)
|
||||||
{
|
{
|
||||||
/* Display a simple version string */
|
/* Display a simple version string */
|
||||||
ConOutPrintf(_T("ReactOS Operating System [Version %s-%s]\n"),
|
ConOutPrintf(_T("ReactOS Operating System [Version %s-%s]\n"),
|
||||||
|
@ -1710,7 +1737,7 @@ Initialize (int argc, const TCHAR* argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static VOID Cleanup (int argc, const TCHAR *argv[])
|
static VOID Cleanup()
|
||||||
{
|
{
|
||||||
/* run cmdexit.bat */
|
/* run cmdexit.bat */
|
||||||
if (IsExistingFile (_T("cmdexit.bat")))
|
if (IsExistingFile (_T("cmdexit.bat")))
|
||||||
|
@ -1782,13 +1809,13 @@ int cmd_main (int argc, const TCHAR *argv[])
|
||||||
CMD_ModuleHandle = GetModuleHandle(NULL);
|
CMD_ModuleHandle = GetModuleHandle(NULL);
|
||||||
|
|
||||||
/* check switches on command-line */
|
/* check switches on command-line */
|
||||||
Initialize(argc, argv);
|
Initialize();
|
||||||
|
|
||||||
/* call prompt routine */
|
/* call prompt routine */
|
||||||
nExitCode = ProcessInput(FALSE);
|
nExitCode = ProcessInput(FALSE);
|
||||||
|
|
||||||
/* do the cleanup */
|
/* do the cleanup */
|
||||||
Cleanup(argc, argv);
|
Cleanup();
|
||||||
|
|
||||||
cmd_exit(nExitCode);
|
cmd_exit(nExitCode);
|
||||||
return(nExitCode);
|
return(nExitCode);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue