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=40... ============================================================================== --- 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=40... ============================================================================== --- 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();