mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 22:02:58 +00:00
Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys.
This commit is contained in:
parent
b94e2d8ca0
commit
c2c66aff7d
24198 changed files with 0 additions and 37285 deletions
340
base/shell/cmd/start.c
Normal file
340
base/shell/cmd/start.c
Normal file
|
@ -0,0 +1,340 @@
|
|||
/*
|
||||
* START.C - start internal command.
|
||||
*
|
||||
*
|
||||
* History:
|
||||
*
|
||||
* 24-Jul-1999 (Eric Kohl)
|
||||
* Started.
|
||||
*
|
||||
* 30-Apr-2005 (Magnus Olsen <magnus@greatlord.com>)
|
||||
* Remove all hardcoded strings in En.rc
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
#ifdef INCLUDE_CMD_START
|
||||
|
||||
/* Find the end of an option, and turn it into a nul-terminated string
|
||||
* in place. (It's moved back one character, to make room for the nul) */
|
||||
static TCHAR *GetParameter(TCHAR **pPointer)
|
||||
{
|
||||
BOOL bInQuote = FALSE;
|
||||
TCHAR *start = *pPointer;
|
||||
TCHAR *p;
|
||||
for (p = start; *p; p++)
|
||||
{
|
||||
if (!bInQuote && (*p == _T('/') || _istspace(*p)))
|
||||
break;
|
||||
bInQuote ^= (*p == _T('"'));
|
||||
p[-1] = *p;
|
||||
}
|
||||
p[-1] = _T('\0');
|
||||
*pPointer = p;
|
||||
return start - 1;
|
||||
}
|
||||
|
||||
INT cmd_start (LPTSTR Rest)
|
||||
{
|
||||
TCHAR szFullName[CMDLINE_LENGTH];
|
||||
TCHAR szUnquotedName[CMDLINE_LENGTH];
|
||||
TCHAR *param = NULL;
|
||||
TCHAR *dot;
|
||||
INT size;
|
||||
LPTSTR comspec;
|
||||
BOOL bWait = FALSE;
|
||||
BOOL bBat = FALSE;
|
||||
BOOL bCreate = FALSE;
|
||||
TCHAR szFullCmdLine[CMDLINE_LENGTH];
|
||||
PROCESS_INFORMATION prci;
|
||||
STARTUPINFO stui;
|
||||
#ifdef UNICODE
|
||||
DWORD dwCreationFlags = CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT;
|
||||
#else
|
||||
DWORD dwCreationFlags = CREATE_NEW_CONSOLE;
|
||||
#endif
|
||||
DWORD dwAffinityMask = 0;
|
||||
LPTSTR lpTitle = NULL;
|
||||
LPTSTR lpDirectory = NULL;
|
||||
LPTSTR lpEnvironment = NULL;
|
||||
WORD wShowWindow = SW_SHOWNORMAL;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (_istspace(*Rest))
|
||||
{
|
||||
Rest++;
|
||||
}
|
||||
else if (*Rest == _T('"') && !lpTitle)
|
||||
{
|
||||
lpTitle = GetParameter(&Rest);
|
||||
StripQuotes(lpTitle);
|
||||
}
|
||||
else if (*Rest == L'/')
|
||||
{
|
||||
LPTSTR option;
|
||||
Rest++;
|
||||
option = GetParameter(&Rest);
|
||||
if (*option == _T('?'))
|
||||
{
|
||||
ConOutResPaging(TRUE,STRING_START_HELP1);
|
||||
return 0;
|
||||
}
|
||||
else if (_totupper(*option) == _T('D'))
|
||||
{
|
||||
lpDirectory = option + 1;
|
||||
if (!*lpDirectory)
|
||||
{
|
||||
while (_istspace(*Rest))
|
||||
Rest++;
|
||||
lpDirectory = GetParameter(&Rest);
|
||||
}
|
||||
StripQuotes(lpDirectory);
|
||||
}
|
||||
else if (_totupper(*option) == _T('I'))
|
||||
{
|
||||
/* rest of the option is apparently ignored */
|
||||
lpEnvironment = lpOriginalEnvironment;
|
||||
}
|
||||
else if (!_tcsicmp(option, _T("MIN")))
|
||||
{
|
||||
wShowWindow = SW_MINIMIZE;
|
||||
}
|
||||
else if (!_tcsicmp(option, _T("MAX")))
|
||||
{
|
||||
wShowWindow = SW_MAXIMIZE;
|
||||
}
|
||||
else if (!_tcsicmp(option, _T("AFFINITY")))
|
||||
{
|
||||
TCHAR *end;
|
||||
while (_istspace(*Rest))
|
||||
Rest++;
|
||||
option = GetParameter(&Rest);
|
||||
/* Affinity mask is given in hexadecimal */
|
||||
dwAffinityMask = _tcstoul(option, &end, 16);
|
||||
if (*end != _T('\0') || dwAffinityMask == 0 ||
|
||||
dwAffinityMask == (DWORD)-1)
|
||||
{
|
||||
ConErrResPrintf(STRING_ERROR_INVALID_PARAM_FORMAT, option);
|
||||
return 1;
|
||||
}
|
||||
dwCreationFlags |= CREATE_SUSPENDED;
|
||||
}
|
||||
else if (!_tcsicmp(option, _T("B")))
|
||||
{
|
||||
dwCreationFlags &= ~CREATE_NEW_CONSOLE;
|
||||
dwCreationFlags |= CREATE_NEW_PROCESS_GROUP;
|
||||
}
|
||||
else if (!_tcsicmp(option, _T("LOW")))
|
||||
{
|
||||
dwCreationFlags |= IDLE_PRIORITY_CLASS;
|
||||
}
|
||||
else if (!_tcsicmp(option, _T("NORMAL")))
|
||||
{
|
||||
dwCreationFlags |= NORMAL_PRIORITY_CLASS;
|
||||
}
|
||||
else if (!_tcsicmp(option, _T("HIGH")))
|
||||
{
|
||||
dwCreationFlags |= HIGH_PRIORITY_CLASS;
|
||||
}
|
||||
else if (!_tcsicmp(option, _T("REALTIME")))
|
||||
{
|
||||
dwCreationFlags |= REALTIME_PRIORITY_CLASS;
|
||||
}
|
||||
else if (!_tcsicmp(option, _T("ABOVENORMAL")))
|
||||
{
|
||||
dwCreationFlags |= ABOVE_NORMAL_PRIORITY_CLASS;
|
||||
}
|
||||
else if (!_tcsicmp(option, _T("BELOWNORMAL")))
|
||||
{
|
||||
dwCreationFlags |= BELOW_NORMAL_PRIORITY_CLASS;
|
||||
}
|
||||
else if (!_tcsicmp(option, _T("SEPARATE")))
|
||||
{
|
||||
dwCreationFlags |= CREATE_SEPARATE_WOW_VDM;
|
||||
}
|
||||
else if (!_tcsicmp(option, _T("SHARED")))
|
||||
{
|
||||
dwCreationFlags |= CREATE_SHARED_WOW_VDM;
|
||||
}
|
||||
else if (!_tcsicmp(option, _T("W")) ||
|
||||
!_tcsicmp(option, _T("WAIT")))
|
||||
{
|
||||
bWait = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ConErrResPrintf(STRING_TYPE_ERROR1, option);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* It's not an option - must be the beginning of
|
||||
* the actual command. Leave the loop. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* get comspec */
|
||||
comspec = cmd_alloc ( MAX_PATH * sizeof(TCHAR));
|
||||
if (comspec == NULL)
|
||||
{
|
||||
error_out_of_memory();
|
||||
return 1;
|
||||
}
|
||||
SetLastError(0);
|
||||
size = GetEnvironmentVariable (_T("COMSPEC"), comspec, MAX_PATH);
|
||||
if (GetLastError() == ERROR_ENVVAR_NOT_FOUND)
|
||||
{
|
||||
_tcscpy(comspec, _T("cmd"));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (size > MAX_PATH)
|
||||
{
|
||||
LPTSTR Oldcomspec = comspec;
|
||||
comspec = cmd_realloc(comspec,size * sizeof(TCHAR) );
|
||||
if (comspec==NULL)
|
||||
{
|
||||
cmd_free(Oldcomspec);
|
||||
return 1;
|
||||
}
|
||||
size = GetEnvironmentVariable (_T("COMSPEC"), comspec, size);
|
||||
}
|
||||
}
|
||||
|
||||
nErrorLevel = 0;
|
||||
|
||||
if (!*Rest)
|
||||
{
|
||||
Rest = _T("cmd.exe");
|
||||
}
|
||||
else
|
||||
/* Parsing the command that gets called by start, and it's parameters */
|
||||
{
|
||||
BOOL bInside = FALSE;
|
||||
INT i;
|
||||
/* find the end of the command and put the arguments in param */
|
||||
for (i = 0; Rest[i]; i++)
|
||||
{
|
||||
if (Rest[i] == _T('\"'))
|
||||
bInside = !bInside;
|
||||
if (_istspace(Rest[i]) && !bInside)
|
||||
{
|
||||
param = &Rest[i+1];
|
||||
Rest[i] = _T('\0');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_tcscpy(szUnquotedName, Rest);
|
||||
StripQuotes(szUnquotedName);
|
||||
|
||||
/* get the PATH environment variable and parse it */
|
||||
/* search the PATH environment variable for the binary */
|
||||
if (SearchForExecutable(szUnquotedName, szFullName))
|
||||
{
|
||||
/* check if this is a .BAT or .CMD file */
|
||||
dot = _tcsrchr(szFullName, _T('.'));
|
||||
if (dot && (!_tcsicmp(dot, _T(".bat")) || !_tcsicmp(dot, _T(".cmd"))))
|
||||
{
|
||||
bBat = TRUE;
|
||||
_stprintf(szFullCmdLine, _T("\"%s\" /K %s"), comspec, Rest);
|
||||
TRACE ("[BATCH: %s %s]\n", debugstr_aw(szFullName), debugstr_aw(Rest));
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE ("[EXEC: %s %s]\n", debugstr_aw(szFullName), debugstr_aw(Rest));
|
||||
_tcscpy(szFullCmdLine, szFullName);
|
||||
}
|
||||
|
||||
/* build command line for CreateProcess() */
|
||||
if (param != NULL)
|
||||
{
|
||||
_tcsncat(szFullCmdLine, _T(" "), CMDLINE_LENGTH - _tcslen(szFullCmdLine));
|
||||
_tcsncat(szFullCmdLine, param, CMDLINE_LENGTH - _tcslen(szFullCmdLine));
|
||||
}
|
||||
|
||||
/* fill startup info */
|
||||
memset (&stui, 0, sizeof (STARTUPINFO));
|
||||
stui.cb = sizeof (STARTUPINFO);
|
||||
stui.dwFlags = STARTF_USESHOWWINDOW;
|
||||
stui.lpTitle = lpTitle;
|
||||
stui.wShowWindow = wShowWindow;
|
||||
|
||||
bCreate = CreateProcess(bBat ? comspec : szFullName,
|
||||
szFullCmdLine, NULL, NULL, TRUE, dwCreationFlags,
|
||||
lpEnvironment, lpDirectory, &stui, &prci);
|
||||
if (bCreate)
|
||||
{
|
||||
if (dwAffinityMask)
|
||||
{
|
||||
SetProcessAffinityMask(prci.hProcess, dwAffinityMask);
|
||||
ResumeThread(prci.hThread);
|
||||
}
|
||||
CloseHandle(prci.hThread);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The file name did not seem to be valid, but maybe it's actually a
|
||||
* directory or URL, so we still want to pass it to ShellExecute. */
|
||||
_tcscpy(szFullName, szUnquotedName);
|
||||
}
|
||||
|
||||
if (!bCreate)
|
||||
{
|
||||
/* CreateProcess didn't work; try ShellExecute */
|
||||
DWORD flags = SEE_MASK_NOCLOSEPROCESS;
|
||||
if (!(dwCreationFlags & CREATE_NEW_CONSOLE))
|
||||
flags |= SEE_MASK_NO_CONSOLE;
|
||||
prci.hProcess = RunFile(flags, szFullName, param, lpDirectory, wShowWindow);
|
||||
}
|
||||
|
||||
if (prci.hProcess != NULL)
|
||||
{
|
||||
if (bWait)
|
||||
{
|
||||
DWORD dwExitCode;
|
||||
WaitForSingleObject (prci.hProcess, INFINITE);
|
||||
GetExitCodeProcess (prci.hProcess, &dwExitCode);
|
||||
nErrorLevel = (INT)dwExitCode;
|
||||
}
|
||||
CloseHandle (prci.hProcess);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorMessage(GetLastError (),
|
||||
_T("Error executing CreateProcess()!!\n"));
|
||||
}
|
||||
|
||||
cmd_free(comspec);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* EOF */
|
Loading…
Add table
Add a link
Reference in a new issue