[PATCH 1/8] CMD.exe: Attempt launch even if fails to locate program

Jason Edmeades us at edmeades.me.uk
Fri Mar 30 13:20:16 CDT 2007


Internal programs will not be found on the path and hence cannot
be run (a good example is xcopy). FindExecutable and SHGetFileInfo
will not report on them either, so try a CreateProcess regardless,
and assume worst case - ie a console app, and wait for it to end.
---
 programs/cmd/wcmdmain.c |   47 +++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 39 insertions(+), 8 deletions(-)

diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c
index 2b5644a..b760223 100644
--- a/programs/cmd/wcmdmain.c
+++ b/programs/cmd/wcmdmain.c
@@ -815,6 +815,8 @@ void WCMD_run_program (char *command, int called) {
   BOOL  launched = FALSE;
   BOOL  status;
   DWORD len;
+  STARTUPINFO st;
+  PROCESS_INFORMATION pe;
 
 
   WCMD_parse (command, quals, param1, param2);	/* Quick way to get the filename */
@@ -916,8 +918,6 @@ void WCMD_run_program (char *command, int called) {
 
     /* Once found, launch it */
     if (found) {
-      STARTUPINFO st;
-      PROCESS_INFORMATION pe;
       SHFILEINFO psfi;
       DWORD console;
       HINSTANCE hinst;
@@ -977,13 +977,44 @@ void WCMD_run_program (char *command, int called) {
     }
   }
 
-  /* Not found anywhere - give up */
-  SetLastError(ERROR_FILE_NOT_FOUND);
-  WCMD_print_error ();
+  /* Internal programs wont be picked up by this, so try one final
+     createprocess and wait for it to complete.
+     Note: Ideally we could tell between a console app (wait) and a
+     windows app, but the API's for it fail in this case           */
+  ZeroMemory (&st, sizeof(STARTUPINFO));
+  st.cb = sizeof(STARTUPINFO);
+  init_msvcrt_io_block(&st);
+
+  /* Launch the process and assume CUI so wait on it to complete */
+  status = CreateProcess (NULL, command, NULL, NULL, TRUE,
+                          0, NULL, NULL, &st, &pe);
+
+  if ((opt_c || opt_k) && !opt_s && !status &&
+       GetLastError()==ERROR_FILE_NOT_FOUND && command[0]=='\"') {
+    /* strip first and last quote characters and try again */
+    WCMD_opt_s_strip_quotes(command);
+    opt_s=1;
+    WCMD_run_program(command, called);
+    return;
+  }
+
+  /* If it still fails, give up */
+  if (!status) {
+    SetLastError(ERROR_FILE_NOT_FOUND);
+    WCMD_print_error ();
+    /* If a command fails to launch, it sets errorlevel 9009 - which
+       does not seem to have any associated constant definition     */
+    errorlevel = 9009;
+    return;
+  }
+
+  /* Wait for it to end */
+  WaitForSingleObject (pe.hProcess, INFINITE);
+  GetExitCodeProcess (pe.hProcess, &errorlevel);
+  if (errorlevel == STILL_ACTIVE) errorlevel = 0;
+  CloseHandle(pe.hProcess);
+  CloseHandle(pe.hThread);
 
-  /* If a command fails to launch, it sets errorlevel 9009 - which
-     does not seem to have any associated constant definition     */
-  errorlevel = 9009;
   return;
 
 }
-- 
1.5.0




More information about the wine-patches mailing list