ShellExecute is run when executable is not found to open for example Notepad files...
authorJens Collin <jens.collin@lakhei.com>
Fri, 16 Jul 2004 20:39:06 +0000 (20:39 +0000)
committerJens Collin <jens.collin@lakhei.com>
Fri, 16 Jul 2004 20:39:06 +0000 (20:39 +0000)
svn path=/trunk/; revision=10147

reactos/subsys/system/cmd/cmd.c

index 7fc6c66..b979d3b 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: cmd.c,v 1.16 2004/06/21 18:57:22 weiden Exp $
+/* $Id: cmd.c,v 1.17 2004/07/16 20:39:06 jc Exp $
  *
  *  CMD.C - command-line interface.
  *
@@ -37,7 +37,7 @@
  *        message!
  *
  *        changed the format to call internal commands (again) so that if
- *        they want to split their commands, they can do it themselves 
+ *        they want to split their commands, they can do it themselves
  *        (none of the internal functions so far need that much power, anyway)
  *
  *    27 Aug 1996 (Tim Norman)
  *       Make MakeSureDirectoryPathExistsEx unicode safe.
  *
  *    28-Mai-2004 (Hartmut Birr)
- *       Removed MakeSureDirectoryPathExistsEx. 
+ *       Removed MakeSureDirectoryPathExistsEx.
  *       Use the current directory if GetTempPath fails.
+ *
+ *    12-Jul-2004 (Jens Collin <jens.collin@lakhei.com>)
+ *       Added ShellExecute call when all else fails to be able to "launch" any file.
  */
 
 #include "config.h"
 #include "cmd.h"
 #include "batch.h"
 
+#include <shellapi.h>
+
 typedef NTSTATUS (STDCALL *NtQueryInformationProcessProc)(HANDLE, PROCESSINFOCLASS,
                                                           PVOID, ULONG, PULONG);
 typedef NTSTATUS (STDCALL *NtReadVirtualMemoryProc)(HANDLE, PVOID, PVOID, ULONG, PULONG);
@@ -241,6 +246,68 @@ static BOOL IsConsoleProcess(HANDLE Process)
 }
 
 
+
+#ifdef _UNICODE
+#define SHELLEXECUTETEXT       L"ShellExecuteW"
+#else
+#define SHELLEXECUTETEXT       "ShellExecuteA"
+#endif
+
+typedef HINSTANCE (WINAPI *MYEX)(
+    HWND hwnd,
+    LPCTSTR lpOperation,
+    LPCTSTR lpFile,
+    LPCTSTR lpParameters,
+    LPCTSTR lpDirectory,
+    INT nShowCmd
+);
+
+
+
+static BOOL RunFile(LPTSTR filename)
+{
+       HMODULE         hShell32;
+       MYEX            hShExt;
+       HINSTANCE       ret;
+
+#ifdef _DEBUG
+               DebugPrintf (_T("RunFile(%s)\n"), filename);
+#endif
+       hShell32 = LoadLibrary(_T("SHELL32.DLL"));
+       if (!hShell32)
+       {
+#ifdef _DEBUG
+               DebugPrintf (_T("RunFile: couldn't load SHELL32.DLL!\n"));
+#endif
+               return FALSE;
+       }
+
+       hShExt = (MYEX)(FARPROC)GetProcAddress(hShell32, SHELLEXECUTETEXT);
+       if (!hShExt)
+       {
+#ifdef _DEBUG
+               DebugPrintf (_T("RunFile: couldn't find ShellExecuteA/W in SHELL32.DLL!\n"));
+#endif
+               FreeLibrary(hShell32);
+               return FALSE;
+       }
+
+#ifdef _DEBUG
+       DebugPrintf (_T("RunFile: ShellExecuteA/W is at %x\n"), hShExt);
+#endif
+
+       ret = (hShExt)(NULL, _T("open"), filename, NULL, NULL, SW_SHOWNORMAL);
+
+#ifdef _DEBUG
+       DebugPrintf (_T("RunFile: ShellExecuteA/W returned %d\n"), (DWORD)ret);
+#endif
+
+       FreeLibrary(hShell32);
+       return (((DWORD)ret) > 32);
+}
+
+
+
 /*
  * This command (in first) was not found in the command table
  *
@@ -263,7 +330,7 @@ Execute (LPTSTR full, LPTSTR first, LPTSTR rest)
 
        /* check for a drive change */
        if ((_istalpha (first[0])) && (!_tcscmp (first + 1, _T(":"))))
-       {       
+       {
                BOOL working = TRUE;
                if (!SetCurrentDirectory(first))
                /* Guess they changed disc or something, handle that gracefully and get to root */
@@ -353,8 +420,17 @@ Execute (LPTSTR full, LPTSTR first, LPTSTR rest)
                }
                else
                {
-                       ErrorMessage (GetLastError (),
-                                     _T("Error executing CreateProcess()!!\n"));
+#ifdef _DEBUG
+                       DebugPrintf (_T("[ShellExecute: %s]\n"), full);
+#endif
+                       // See if we can run this with ShellExecute() ie myfile.xls
+                       if (!RunFile(full))
+                       {
+#ifdef _DEBUG
+                               DebugPrintf (_T("[ShellExecute failed!: %s]\n"), full);
+#endif
+                               error_bad_command ();
+                       }
                }
                // restore console mode
                SetConsoleMode( GetStdHandle( STD_INPUT_HANDLE ),
@@ -420,7 +496,7 @@ DoCommand (LPTSTR line)
 
                /* Terminate first word */
                *cp = _T('\0');
-               
+
                /* commands are limited to MAX_PATH */
                if(_tcslen(com) > MAX_PATH)
                {
@@ -591,16 +667,16 @@ VOID ParseCommandLine (LPTSTR cmd)
 
                /* Create unique temporary file name */
                GetTempFileName (szTempPath, _T("CMD"), 0, szFileName[1]);
-      
+
                /* Set current stdout to temporary file */
                hFile[1] = CreateFile (szFileName[1], GENERIC_WRITE, 0, &sa,
                                       TRUNCATE_EXISTING, FILE_ATTRIBUTE_TEMPORARY, NULL);
-                   
+
       if (hFile[1] == INVALID_HANDLE_VALUE){
          ConErrPrintf (_T("Error creating temporary file for pipe data\n"));
          return;
       }
-                   
+
                SetStdHandle (STD_OUTPUT_HANDLE, hFile[1]);
 
                DoCommand (s);
@@ -747,7 +823,7 @@ VOID ParseCommandLine (LPTSTR cmd)
        /* close old stdin file */
 #if 0  /* buggy implementation */
        SetStdHandle (STD_INPUT_HANDLE, hOldConIn);
-       if ((hFile[0] != INVALID_HANDLE_VALUE) && 
+       if ((hFile[0] != INVALID_HANDLE_VALUE) &&
                (hFile[0] != hOldConIn))
        {
                /* delete old stdin file, if it is a real file */
@@ -835,7 +911,7 @@ VOID ParseCommandLine (LPTSTR cmd)
  *
  */
 
-static INT 
+static INT
 ProcessInput (BOOL bFlag)
 {
        TCHAR commandline[CMDLINE_LENGTH];
@@ -1248,7 +1324,7 @@ static VOID Cleanup (int argc, TCHAR *argv[])
        FreeLastPath ();
 #endif
 
-#ifdef FEATURE_HISTORY 
+#ifdef FEATURE_HISTORY
        CleanHistory();
 #endif
 
@@ -1329,8 +1405,8 @@ int main (int argc, char *argv[])
 
   SetFileApisToOEM();
 
-  hConsole = CreateFile(_T("CONOUT$"), GENERIC_READ|GENERIC_WRITE, 
-                        FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, 
+  hConsole = CreateFile(_T("CONOUT$"), GENERIC_READ|GENERIC_WRITE,
+                        FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
                        OPEN_EXISTING, 0, NULL);
   if (GetConsoleScreenBufferInfo(hConsole, &Info) == FALSE)
     {