-/* $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.
*
* 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);
}
+
+#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
*
/* 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 */
}
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 ),
/* Terminate first word */
*cp = _T('\0');
-
+
/* commands are limited to MAX_PATH */
if(_tcslen(com) > MAX_PATH)
{
/* 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);
/* 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 */
*
*/
-static INT
+static INT
ProcessInput (BOOL bFlag)
{
TCHAR commandline[CMDLINE_LENGTH];
FreeLastPath ();
#endif
-#ifdef FEATURE_HISTORY
+#ifdef FEATURE_HISTORY
CleanHistory();
#endif
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)
{