Author: jmorlan
Date: Sun Mar 22 04:51:29 2009
New Revision: 40169
URL:
http://svn.reactos.org/svn/reactos?rev=40169&view=rev
Log:
Make START command able to open non-executable files/directories/URLs using ShellExecute.
(Bug 4055)
Modified:
trunk/reactos/base/shell/cmd/cmd.c
trunk/reactos/base/shell/cmd/cmd.h
trunk/reactos/base/shell/cmd/start.c
Modified: trunk/reactos/base/shell/cmd/cmd.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/cmd.c?rev=4…
==============================================================================
--- trunk/reactos/base/shell/cmd/cmd.c [iso-8859-1] (original)
+++ trunk/reactos/base/shell/cmd/cmd.c [iso-8859-1] Sun Mar 22 04:51:29 2009
@@ -265,7 +265,8 @@
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;
HMODULE hShell32;
@@ -292,10 +293,11 @@
memset(&sei, 0, sizeof sei);
sei.cbSize = sizeof sei;
- sei.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NO_CONSOLE;
+ sei.fMask = flags;
sei.lpFile = filename;
sei.lpParameters = params;
- sei.nShow = SW_SHOWNORMAL;
+ sei.lpDirectory = directory;
+ sei.nShow = show;
ret = hShExt(&sei);
TRACE ("RunFile: ShellExecuteExA/W returned 0x%p\n", ret);
@@ -499,7 +501,11 @@
else
{
// 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)
Modified: trunk/reactos/base/shell/cmd/cmd.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/cmd.h?rev=4…
==============================================================================
--- trunk/reactos/base/shell/cmd/cmd.h [iso-8859-1] (original)
+++ trunk/reactos/base/shell/cmd/cmd.h [iso-8859-1] Sun Mar 22 04:51:29 2009
@@ -100,6 +100,7 @@
/* Prototypes for CMD.C */
INT ConvertULargeInteger(ULONGLONG num, LPTSTR des, INT len, BOOL bPutSeperator);
+HANDLE RunFile(DWORD, LPTSTR, LPTSTR, LPTSTR, INT);
VOID ParseCommandLine (LPTSTR);
struct _PARSED_COMMAND;
BOOL ExecuteCommand(struct _PARSED_COMMAND *Cmd);
Modified: trunk/reactos/base/shell/cmd/start.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/start.c?rev…
==============================================================================
--- trunk/reactos/base/shell/cmd/start.c [iso-8859-1] (original)
+++ trunk/reactos/base/shell/cmd/start.c [iso-8859-1] Sun Mar 22 04:51:29 2009
@@ -37,7 +37,7 @@
INT cmd_start (LPTSTR Rest)
{
TCHAR szFullName[CMDLINE_LENGTH];
- TCHAR rest[CMDLINE_LENGTH];
+ TCHAR szUnquotedName[CMDLINE_LENGTH];
TCHAR *param = NULL;
TCHAR *dot;
INT size;
@@ -136,7 +136,6 @@
break;
}
}
- _tcscpy(rest, Rest);
/* get comspec */
comspec = cmd_alloc ( MAX_PATH * sizeof(TCHAR));
@@ -166,81 +165,56 @@
nErrorLevel = 0;
- if(!*rest)
- {
- _tcscpy(rest,_T("\""));
- _tcscat(rest,comspec);
- _tcscat(rest,_T("\""));
- }
-
+ if (!*Rest)
+ {
+ Rest = _T("cmd.exe");
+ }
+ else
/* Parsing the command that gets called by start, and it's parameters */
{
BOOL bInside = FALSE;
/* find the end of the command and put the arguments in param */
- for(i = 0; rest[i]; i++)
- {
- if(rest[i] == _T('\"'))
+ for (i = 0; Rest[i]; i++)
+ {
+ if (Rest[i] == _T('\"'))
bInside = !bInside;
- if((rest[i] == _T(' ')) && !bInside)
- {
- param = &rest[i+1];
- rest[i] = _T('\0');
+ if (_istspace(Rest[i]) && !bInside)
+ {
+ param = &Rest[i+1];
+ Rest[i] = _T('\0');
break;
}
}
- /* remove any slashes */
- StripQuotes(rest);
- }
-
- /* check for a drive change */
-
- 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;
- }
+ }
+
+ _tcscpy(szUnquotedName, Rest);
+ StripQuotes(szUnquotedName);
/* get the PATH environment variable and parse it */
/* search the PATH environment variable for the binary */
- if (!SearchForExecutable (rest, szFullName))
- {
- error_bad_command(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));
+ 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, Rest);
+ }
+
/* build command line for CreateProcess() */
- _tcscpy (szFullCmdLine, rest);
- if( param != NULL )
- {
-
- _tcscat(szFullCmdLine, _T(" ") );
- _tcscat (szFullCmdLine, param);
- }
- }
+ if (param != NULL)
+ {
+ _tcscat(szFullCmdLine, _T(" "));
+ _tcscat(szFullCmdLine, param);
+ }
/* fill startup info */
memset (&stui, 0, sizeof (STARTUPINFO));
@@ -259,9 +233,25 @@
bCreate = CreateProcess (szFullName, szFullCmdLine, NULL, NULL, FALSE,
CREATE_NEW_CONSOLE | Priority, NULL, lpDirectory, &stui, &prci);
}
-
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)
{
DWORD dwExitCode;
@@ -269,7 +259,6 @@
GetExitCodeProcess (prci.hProcess, &dwExitCode);
nErrorLevel = (INT)dwExitCode;
}
- CloseHandle (prci.hThread);
CloseHandle (prci.hProcess);
/* Get New code page if it has change */
InputCodePage= GetConsoleCP();