[ros-diffs] [jmorlan] 40169: Make START command able to open non-executable files/directories/URLs using ShellExecute. (Bug 4055)

jmorlan at svn.reactos.org jmorlan at svn.reactos.org
Sun Mar 22 02:51:31 CET 2009


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=40169&r1=40168&r2=40169&view=diff
==============================================================================
--- 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=40169&r1=40168&r2=40169&view=diff
==============================================================================
--- 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=40169&r1=40168&r2=40169&view=diff
==============================================================================
--- 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();



More information about the Ros-diffs mailing list