mirror of
https://github.com/reactos/reactos.git
synced 2025-05-06 18:31:26 +00:00
Make START command able to open non-executable files/directories/URLs using ShellExecute. (Bug 4055)
svn path=/trunk/; revision=40169
This commit is contained in:
parent
c999c1eb6e
commit
e518029091
3 changed files with 59 additions and 63 deletions
|
@ -265,7 +265,8 @@ static BOOL IsConsoleProcess(HANDLE Process)
|
||||||
|
|
||||||
typedef BOOL (WINAPI *MYEX)(LPSHELLEXECUTEINFO lpExecInfo);
|
typedef BOOL (WINAPI *MYEX)(LPSHELLEXECUTEINFO lpExecInfo);
|
||||||
|
|
||||||
static HANDLE RunFile(LPTSTR filename, LPTSTR params)
|
HANDLE RunFile(DWORD flags, LPTSTR filename, LPTSTR params,
|
||||||
|
LPTSTR directory, INT show)
|
||||||
{
|
{
|
||||||
SHELLEXECUTEINFO sei;
|
SHELLEXECUTEINFO sei;
|
||||||
HMODULE hShell32;
|
HMODULE hShell32;
|
||||||
|
@ -292,10 +293,11 @@ static HANDLE RunFile(LPTSTR filename, LPTSTR params)
|
||||||
|
|
||||||
memset(&sei, 0, sizeof sei);
|
memset(&sei, 0, sizeof sei);
|
||||||
sei.cbSize = sizeof sei;
|
sei.cbSize = sizeof sei;
|
||||||
sei.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NO_CONSOLE;
|
sei.fMask = flags;
|
||||||
sei.lpFile = filename;
|
sei.lpFile = filename;
|
||||||
sei.lpParameters = params;
|
sei.lpParameters = params;
|
||||||
sei.nShow = SW_SHOWNORMAL;
|
sei.lpDirectory = directory;
|
||||||
|
sei.nShow = show;
|
||||||
ret = hShExt(&sei);
|
ret = hShExt(&sei);
|
||||||
|
|
||||||
TRACE ("RunFile: ShellExecuteExA/W returned 0x%p\n", ret);
|
TRACE ("RunFile: ShellExecuteExA/W returned 0x%p\n", ret);
|
||||||
|
@ -499,7 +501,11 @@ Execute (LPTSTR Full, LPTSTR First, LPTSTR Rest, PARSED_COMMAND *Cmd)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// See if we can run this with ShellExecute() ie myfile.xls
|
// See if we can run this with ShellExecute() ie myfile.xls
|
||||||
prci.hProcess = RunFile(szFullName, rest);
|
prci.hProcess = RunFile(SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NO_CONSOLE,
|
||||||
|
szFullName,
|
||||||
|
rest,
|
||||||
|
NULL,
|
||||||
|
SW_SHOWNORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prci.hProcess != NULL)
|
if (prci.hProcess != NULL)
|
||||||
|
|
|
@ -100,6 +100,7 @@ INT cmd_cls (LPTSTR);
|
||||||
|
|
||||||
/* Prototypes for CMD.C */
|
/* Prototypes for CMD.C */
|
||||||
INT ConvertULargeInteger(ULONGLONG num, LPTSTR des, INT len, BOOL bPutSeperator);
|
INT ConvertULargeInteger(ULONGLONG num, LPTSTR des, INT len, BOOL bPutSeperator);
|
||||||
|
HANDLE RunFile(DWORD, LPTSTR, LPTSTR, LPTSTR, INT);
|
||||||
VOID ParseCommandLine (LPTSTR);
|
VOID ParseCommandLine (LPTSTR);
|
||||||
struct _PARSED_COMMAND;
|
struct _PARSED_COMMAND;
|
||||||
BOOL ExecuteCommand(struct _PARSED_COMMAND *Cmd);
|
BOOL ExecuteCommand(struct _PARSED_COMMAND *Cmd);
|
||||||
|
|
|
@ -37,7 +37,7 @@ static TCHAR *GetParameter(TCHAR **pPointer)
|
||||||
INT cmd_start (LPTSTR Rest)
|
INT cmd_start (LPTSTR Rest)
|
||||||
{
|
{
|
||||||
TCHAR szFullName[CMDLINE_LENGTH];
|
TCHAR szFullName[CMDLINE_LENGTH];
|
||||||
TCHAR rest[CMDLINE_LENGTH];
|
TCHAR szUnquotedName[CMDLINE_LENGTH];
|
||||||
TCHAR *param = NULL;
|
TCHAR *param = NULL;
|
||||||
TCHAR *dot;
|
TCHAR *dot;
|
||||||
INT size;
|
INT size;
|
||||||
|
@ -136,7 +136,6 @@ INT cmd_start (LPTSTR Rest)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_tcscpy(rest, Rest);
|
|
||||||
|
|
||||||
/* get comspec */
|
/* get comspec */
|
||||||
comspec = cmd_alloc ( MAX_PATH * sizeof(TCHAR));
|
comspec = cmd_alloc ( MAX_PATH * sizeof(TCHAR));
|
||||||
|
@ -166,81 +165,56 @@ INT cmd_start (LPTSTR Rest)
|
||||||
|
|
||||||
nErrorLevel = 0;
|
nErrorLevel = 0;
|
||||||
|
|
||||||
if(!*rest)
|
if (!*Rest)
|
||||||
{
|
{
|
||||||
_tcscpy(rest,_T("\""));
|
Rest = _T("cmd.exe");
|
||||||
_tcscat(rest,comspec);
|
|
||||||
_tcscat(rest,_T("\""));
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
/* Parsing the command that gets called by start, and it's parameters */
|
/* Parsing the command that gets called by start, and it's parameters */
|
||||||
{
|
{
|
||||||
BOOL bInside = FALSE;
|
BOOL bInside = FALSE;
|
||||||
|
|
||||||
/* find the end of the command and put the arguments in param */
|
/* find the end of the command and put the arguments in param */
|
||||||
for(i = 0; rest[i]; i++)
|
for (i = 0; Rest[i]; i++)
|
||||||
{
|
{
|
||||||
if(rest[i] == _T('\"'))
|
if (Rest[i] == _T('\"'))
|
||||||
bInside = !bInside;
|
bInside = !bInside;
|
||||||
if((rest[i] == _T(' ')) && !bInside)
|
if (_istspace(Rest[i]) && !bInside)
|
||||||
{
|
{
|
||||||
param = &rest[i+1];
|
param = &Rest[i+1];
|
||||||
rest[i] = _T('\0');
|
Rest[i] = _T('\0');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* remove any slashes */
|
|
||||||
StripQuotes(rest);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check for a drive change */
|
_tcscpy(szUnquotedName, Rest);
|
||||||
|
StripQuotes(szUnquotedName);
|
||||||
if (!_tcscmp (rest + 1, _T(":")) && _istalpha (*rest))
|
|
||||||
{
|
|
||||||
TCHAR szPath[CMDLINE_LENGTH];
|
|
||||||
|
|
||||||
_tcscpy (szPath, _T("A:"));
|
|
||||||
szPath[0] = _totupper (*rest);
|
|
||||||
SetCurrentDirectory (szPath);
|
|
||||||
GetCurrentDirectory (CMDLINE_LENGTH, szPath);
|
|
||||||
if (szPath[0] != (TCHAR)_totupper (*rest))
|
|
||||||
ConErrResPuts (STRING_FREE_ERROR1);
|
|
||||||
|
|
||||||
cmd_free(comspec);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get the PATH environment variable and parse it */
|
/* get the PATH environment variable and parse it */
|
||||||
/* search the PATH environment variable for the binary */
|
/* search the PATH environment variable for the binary */
|
||||||
if (!SearchForExecutable (rest, szFullName))
|
if (SearchForExecutable(szUnquotedName, szFullName))
|
||||||
{
|
{
|
||||||
error_bad_command(rest);
|
/* 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, Rest);
|
||||||
|
}
|
||||||
|
|
||||||
cmd_free(comspec);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* 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, szFullName);
|
|
||||||
TRACE ("[BATCH: %s %s]\n", debugstr_aw(szFullName), debugstr_aw(rest));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TRACE ("[EXEC: %s %s]\n", debugstr_aw(szFullName), debugstr_aw(rest));
|
|
||||||
/* build command line for CreateProcess() */
|
/* build command line for CreateProcess() */
|
||||||
_tcscpy (szFullCmdLine, rest);
|
if (param != NULL)
|
||||||
if( param != NULL )
|
{
|
||||||
{
|
_tcscat(szFullCmdLine, _T(" "));
|
||||||
|
_tcscat(szFullCmdLine, param);
|
||||||
_tcscat(szFullCmdLine, _T(" ") );
|
}
|
||||||
_tcscat (szFullCmdLine, param);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* fill startup info */
|
/* fill startup info */
|
||||||
memset (&stui, 0, sizeof (STARTUPINFO));
|
memset (&stui, 0, sizeof (STARTUPINFO));
|
||||||
|
@ -259,9 +233,25 @@ INT cmd_start (LPTSTR Rest)
|
||||||
bCreate = CreateProcess (szFullName, szFullCmdLine, NULL, NULL, FALSE,
|
bCreate = CreateProcess (szFullName, szFullCmdLine, NULL, NULL, FALSE,
|
||||||
CREATE_NEW_CONSOLE | Priority, NULL, lpDirectory, &stui, &prci);
|
CREATE_NEW_CONSOLE | Priority, NULL, lpDirectory, &stui, &prci);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bCreate)
|
if (bCreate)
|
||||||
{
|
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 */
|
||||||
|
prci.hProcess = RunFile(SEE_MASK_NOCLOSEPROCESS, szFullName,
|
||||||
|
param, lpDirectory, wShowWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prci.hProcess != NULL)
|
||||||
|
{
|
||||||
if (bWait)
|
if (bWait)
|
||||||
{
|
{
|
||||||
DWORD dwExitCode;
|
DWORD dwExitCode;
|
||||||
|
@ -269,7 +259,6 @@ INT cmd_start (LPTSTR Rest)
|
||||||
GetExitCodeProcess (prci.hProcess, &dwExitCode);
|
GetExitCodeProcess (prci.hProcess, &dwExitCode);
|
||||||
nErrorLevel = (INT)dwExitCode;
|
nErrorLevel = (INT)dwExitCode;
|
||||||
}
|
}
|
||||||
CloseHandle (prci.hThread);
|
|
||||||
CloseHandle (prci.hProcess);
|
CloseHandle (prci.hProcess);
|
||||||
/* Get New code page if it has change */
|
/* Get New code page if it has change */
|
||||||
InputCodePage= GetConsoleCP();
|
InputCodePage= GetConsoleCP();
|
||||||
|
|
Loading…
Reference in a new issue