diff --git a/reactos/base/shell/cmd/cmd.c b/reactos/base/shell/cmd/cmd.c index 53196a4ce4e..428a6807e7e 100644 --- a/reactos/base/shell/cmd/cmd.c +++ b/reactos/base/shell/cmd/cmd.c @@ -265,7 +265,8 @@ static BOOL IsConsoleProcess(HANDLE Process) 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 @@ static HANDLE RunFile(LPTSTR filename, LPTSTR params) 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 @@ Execute (LPTSTR Full, LPTSTR First, LPTSTR Rest, PARSED_COMMAND *Cmd) 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) diff --git a/reactos/base/shell/cmd/cmd.h b/reactos/base/shell/cmd/cmd.h index 65ac3beb301..c69f9a9f29f 100644 --- a/reactos/base/shell/cmd/cmd.h +++ b/reactos/base/shell/cmd/cmd.h @@ -100,6 +100,7 @@ INT cmd_cls (LPTSTR); /* 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); diff --git a/reactos/base/shell/cmd/start.c b/reactos/base/shell/cmd/start.c index 8764ebf956a..d4858a662d3 100644 --- a/reactos/base/shell/cmd/start.c +++ b/reactos/base/shell/cmd/start.c @@ -37,7 +37,7 @@ static TCHAR *GetParameter(TCHAR **pPointer) 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 @@ INT cmd_start (LPTSTR Rest) break; } } - _tcscpy(rest, Rest); /* get comspec */ comspec = cmd_alloc ( MAX_PATH * sizeof(TCHAR)); @@ -166,81 +165,56 @@ INT cmd_start (LPTSTR Rest) nErrorLevel = 0; - if(!*rest) + if (!*Rest) { - _tcscpy(rest,_T("\"")); - _tcscat(rest,comspec); - _tcscat(rest,_T("\"")); + 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++) + for (i = 0; Rest[i]; i++) { - if(rest[i] == _T('\"')) + if (Rest[i] == _T('\"')) bInside = !bInside; - if((rest[i] == _T(' ')) && !bInside) + if (_istspace(Rest[i]) && !bInside) { - param = &rest[i+1]; - rest[i] = _T('\0'); + 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)) + 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() */ - _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 @@ INT cmd_start (LPTSTR Rest) 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 @@ INT cmd_start (LPTSTR Rest) GetExitCodeProcess (prci.hProcess, &dwExitCode); nErrorLevel = (INT)dwExitCode; } - CloseHandle (prci.hThread); CloseHandle (prci.hProcess); /* Get New code page if it has change */ InputCodePage= GetConsoleCP();