XEmacs 21.4.4 "Artificial Intelligence".
[chise/xemacs-chise.git.1] / src / process-nt.c
1 /* Asynchronous subprocess implementation for Win32
2    Copyright (C) 1985, 1986, 1987, 1988, 1992, 1993, 1994, 1995
3    Free Software Foundation, Inc.
4    Copyright (C) 1995 Sun Microsystems, Inc.
5    Copyright (C) 1995, 1996, 2000 Ben Wing.
6
7 This file is part of XEmacs.
8
9 XEmacs is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
12 later version.
13
14 XEmacs is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with XEmacs; see the file COPYING.  If not, write to
21 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA.  */
23
24 /* Written by Kirill M. Katsnelson <kkm@kis.ru>, April 1998 */
25
26 #include <config.h>
27 #include "lisp.h"
28
29 #include "buffer.h"
30 #include "console-msw.h"
31 #include "hash.h"
32 #include "lstream.h"
33 #include "nt.h"
34 #include "process.h"
35 #include "procimpl.h"
36 #include "sysdep.h"
37
38 #include <shellapi.h>
39 #include <errno.h>
40 #include <signal.h>
41 #ifdef HAVE_SOCKETS
42 #include <winsock.h>
43 #endif
44
45 /* Bound by win32-native.el */
46 Lisp_Object Qmswindows_construct_process_command_line;
47
48 /* Arbitrary size limit for code fragments passed to run_in_other_process */
49 #define FRAGMENT_CODE_SIZE 32
50
51 /* Implementation-specific data. Pointed to by Lisp_Process->process_data */
52 struct nt_process_data
53 {
54   HANDLE h_process;
55   DWORD dwProcessId;
56   HWND hwnd; /* console window */
57 };
58
59 /* Control whether create_child causes the process to inherit Emacs'
60    console window, or be given a new one of its own.  The default is
61    nil, to allow multiple DOS programs to run on Win95.  Having separate
62    consoles also allows Emacs to cleanly terminate process groups.  */
63 Lisp_Object Vmswindows_start_process_share_console;
64
65 /* Control whether create_child cause the process to inherit Emacs'
66    error mode setting.  The default is t, to minimize the possibility of
67    subprocesses blocking when accessing unmounted drives.  */
68 Lisp_Object Vmswindows_start_process_inherit_error_mode;
69
70 #define NT_DATA(p) ((struct nt_process_data*)((p)->process_data))
71 \f
72 /*-----------------------------------------------------------------------*/
73 /* Process helpers                                                       */
74 /*-----------------------------------------------------------------------*/
75
76 /* This one breaks process abstraction. Prototype is in console-msw.h,
77    used by select_process method in event-msw.c */
78 HANDLE
79 get_nt_process_handle (Lisp_Process *p)
80 {
81   return (NT_DATA (p)->h_process);
82 }
83
84 static struct Lisp_Process *
85 find_process_from_pid (DWORD pid)
86 {
87   Lisp_Object tail, proc;
88
89   for (tail = Vprocess_list; CONSP (tail); tail = XCDR (tail))
90     {
91       proc = XCAR (tail);
92       if (NT_DATA (XPROCESS (proc))->dwProcessId == pid)
93         return XPROCESS (proc);
94     }
95   return 0;
96 }
97
98 \f
99 /*-----------------------------------------------------------------------*/
100 /* Running remote threads. See Microsoft Systems Journal 1994 Number 5   */
101 /* Jeffrey Richter, Load Your 32-bit DLL into Another Process's Address..*/
102 /*-----------------------------------------------------------------------*/
103
104 typedef struct
105 {
106   HANDLE h_process;
107   HANDLE h_thread;
108   LPVOID address;
109 } process_memory;
110
111 /*
112  * Allocate SIZE bytes in H_PROCESS address space. Fill in PMC used
113  * further by other routines. Return nonzero if successful.
114  *
115  * The memory in other process is allocated by creating a suspended
116  * thread. Initial stack of that thread is used as the memory
117  * block. The thread entry point is the routine ExitThread in
118  * kernel32.dll, so the allocated memory is freed just by resuming the 
119  * thread, which immediately terminates after that.
120  */
121
122 static int 
123 alloc_process_memory (HANDLE h_process, size_t size,
124                       process_memory* pmc)
125 {
126   LPTHREAD_START_ROUTINE adr_ExitThread =
127     (LPTHREAD_START_ROUTINE)
128     GetProcAddress (GetModuleHandle ("kernel32"), "ExitThread");
129   DWORD dw_unused;
130   CONTEXT context;
131   MEMORY_BASIC_INFORMATION mbi;
132
133   pmc->h_process = h_process;
134   pmc->h_thread = CreateRemoteThread (h_process, NULL, size,
135                                      adr_ExitThread, NULL,
136                                      CREATE_SUSPENDED, &dw_unused);
137   if (pmc->h_thread == NULL)
138     return 0;
139
140   /* Get context, for thread's stack pointer */
141   context.ContextFlags = CONTEXT_CONTROL;
142   if (!GetThreadContext (pmc->h_thread, &context))
143     goto failure;
144
145   /* Determine base address of the committed range */
146   if (sizeof(mbi) != VirtualQueryEx (h_process,
147 #if defined (_X86_)
148                                      (LPDWORD)context.Esp - 1,
149 #elif defined (_ALPHA_)
150                                      (LPDWORD)context.IntSp - 1,
151 #else
152 #error Unknown processor architecture
153 #endif
154                                      &mbi, sizeof(mbi)))
155     goto failure;
156
157   /* Change the page protection of the allocated memory to executable,
158      read, and write. */
159   if (!VirtualProtectEx (h_process, mbi.BaseAddress, size,
160                          PAGE_EXECUTE_READWRITE, &dw_unused))
161     goto failure;
162
163   pmc->address = mbi.BaseAddress;
164   return 1;
165
166  failure:
167   ResumeThread (pmc->h_thread);
168   pmc->address = 0;
169   return 0;
170 }
171
172 static void
173 free_process_memory (process_memory* pmc)
174 {
175   ResumeThread (pmc->h_thread);
176 }
177
178 /*
179  * Run ROUTINE in the context of process determined by H_PROCESS. The
180  * routine is passed the address of DATA as parameter. The ROUTINE must
181  * not be longer than ROUTINE_CODE_SIZE bytes. DATA_SIZE is the size of
182  * DATA structure.
183  *
184  * Note that the code must be positionally independent, and compiled
185  * without stack checks (they cause implicit calls into CRT so will
186  * fail). DATA should not refer any data in calling process, as both
187  * routine and its data are copied into remote process. Size of data
188  * and code together should not exceed one page (4K on x86 systems).
189  *
190  * Return the value returned by ROUTINE, or (DWORD)-1 if call failed.
191  */
192 static DWORD
193 run_in_other_process (HANDLE h_process,
194                       LPTHREAD_START_ROUTINE routine,
195                       LPVOID data, size_t data_size)
196 {
197   process_memory pm;
198   const size_t code_size = FRAGMENT_CODE_SIZE;
199   /* Need at most 3 extra bytes of memory, for data alignment */
200   size_t total_size = code_size + data_size + 3;
201   LPVOID remote_data;
202   HANDLE h_thread;
203   DWORD dw_unused;
204
205   /* Allocate memory */
206   if (!alloc_process_memory (h_process, total_size, &pm))
207     return (DWORD)-1;
208
209   /* Copy code */
210   if (!WriteProcessMemory (h_process, pm.address, (LPVOID)routine,
211                            code_size, NULL))
212     goto failure;
213
214   /* Copy data */
215   if (data_size)
216     {
217       remote_data = (LPBYTE)pm.address + ((code_size + 4) & ~3);
218       if (!WriteProcessMemory (h_process, remote_data, data, data_size, NULL))
219         goto failure;
220     }
221   else
222     remote_data = NULL;
223
224   /* Execute the remote copy of code, passing it remote data */
225   h_thread = CreateRemoteThread (h_process, NULL, 0,
226                                  (LPTHREAD_START_ROUTINE) pm.address,
227                                  remote_data, 0, &dw_unused);
228   if (h_thread == NULL)
229     goto failure;
230
231   /* Wait till thread finishes */
232   WaitForSingleObject (h_thread, INFINITE);
233
234   /* Free remote memory */
235   free_process_memory (&pm);
236
237   /* Return thread's exit code */
238   {
239     DWORD exit_code;
240     GetExitCodeThread (h_thread, &exit_code);
241     CloseHandle (h_thread);
242     return exit_code;
243   }
244
245  failure:
246   free_process_memory (&pm);
247   return (DWORD)-1;
248 }
249 \f
250 /*-----------------------------------------------------------------------*/
251 /* Sending signals                                                       */
252 /*-----------------------------------------------------------------------*/
253
254 /* ---------------------------- the NT way ------------------------------- */
255
256 /*
257  * We handle the following signals:
258  *
259  * SIGKILL, SIGTERM, SIGQUIT, SIGHUP - These four translate to ExitProcess
260  *    executed by the remote process
261  * SIGINT - The remote process is sent CTRL_BREAK_EVENT
262  *
263  * The MSVC5.0 compiler feels free to re-order functions within a
264  * compilation unit, so we have no way of finding out the size of the
265  * following functions. Therefore these functions must not be larger than
266  * FRAGMENT_CODE_SIZE.
267  */
268
269 /*
270  * Sending SIGKILL
271  */
272 typedef struct
273 {
274   void (WINAPI *adr_ExitProcess) (UINT);
275 } sigkill_data;
276
277 static DWORD WINAPI
278 sigkill_proc (sigkill_data* data)
279 {
280   (*data->adr_ExitProcess)(255);
281   return 1;
282 }
283
284 /*
285  * Sending break or control c
286  */
287 typedef struct
288 {
289   BOOL (WINAPI *adr_GenerateConsoleCtrlEvent) (DWORD, DWORD);
290   DWORD event;
291 } sigint_data;
292
293 static DWORD WINAPI
294 sigint_proc (sigint_data* data)
295 {
296   return (*data->adr_GenerateConsoleCtrlEvent) (data->event, 0);
297 }
298
299 /*
300  * Enabling signals
301  */
302 typedef struct
303 {
304   BOOL (WINAPI *adr_SetConsoleCtrlHandler) (LPVOID, BOOL);
305 } sig_enable_data;
306
307 static DWORD WINAPI
308 sig_enable_proc (sig_enable_data* data)
309 {
310   (*data->adr_SetConsoleCtrlHandler) (NULL, FALSE);
311   return 1;
312 }
313
314 /*
315  * Send signal SIGNO to process H_PROCESS.
316  * Return nonzero if successful.
317  */
318
319 static int
320 send_signal_the_nt_way (struct nt_process_data *cp, int pid, int signo)
321 {
322   HANDLE h_process;
323   HMODULE h_kernel = GetModuleHandle ("kernel32");
324   int close_process = 0;
325   DWORD retval;
326   
327   assert (h_kernel != NULL);
328   
329   if (cp)
330     {
331       pid = cp->dwProcessId;
332       h_process = cp->h_process;
333     }
334   else
335     {
336       close_process = 1;
337       /* Try to open the process with required privileges */
338       h_process = OpenProcess (PROCESS_CREATE_THREAD
339                                | PROCESS_QUERY_INFORMATION 
340                                | PROCESS_VM_OPERATION
341                                | PROCESS_VM_WRITE,
342                                FALSE, pid);
343       if (!h_process)
344         return 0;
345     }
346
347   switch (signo)
348     {
349     case SIGKILL:
350     case SIGTERM:
351     case SIGQUIT:
352     case SIGHUP:
353       {
354         sigkill_data d;
355
356         d.adr_ExitProcess =
357           (void (WINAPI *) (UINT)) GetProcAddress (h_kernel, "ExitProcess");
358         assert (d.adr_ExitProcess);
359         retval = run_in_other_process (h_process, 
360                                        (LPTHREAD_START_ROUTINE)sigkill_proc,
361                                        &d, sizeof (d));
362         break;
363       }
364     case SIGINT:
365       {
366         sigint_data d;
367         d.adr_GenerateConsoleCtrlEvent =
368           (BOOL (WINAPI *) (DWORD, DWORD))
369           GetProcAddress (h_kernel, "GenerateConsoleCtrlEvent");
370         assert (d.adr_GenerateConsoleCtrlEvent);
371         d.event = CTRL_C_EVENT;
372         retval = run_in_other_process (h_process, 
373                                        (LPTHREAD_START_ROUTINE)sigint_proc,
374                                        &d, sizeof (d));
375         break;
376       }
377     default:
378       assert (0);
379     }
380
381   if (close_process)
382     CloseHandle (h_process);
383   return (int)retval > 0 ? 1 : 0;
384 }
385
386 /*
387  * Enable CTRL_C_EVENT handling in a new child process
388  */
389 static void
390 enable_child_signals (HANDLE h_process)
391 {
392   HMODULE h_kernel = GetModuleHandle ("kernel32");
393   sig_enable_data d;
394   
395   assert (h_kernel != NULL);
396   d.adr_SetConsoleCtrlHandler =
397     (BOOL (WINAPI *) (LPVOID, BOOL))
398     GetProcAddress (h_kernel, "SetConsoleCtrlHandler");
399   assert (d.adr_SetConsoleCtrlHandler);
400   run_in_other_process (h_process, (LPTHREAD_START_ROUTINE)sig_enable_proc,
401                         &d, sizeof (d));
402 }
403   
404 #pragma warning (default : 4113)
405
406 /* ---------------------------- the 95 way ------------------------------- */
407
408 static BOOL CALLBACK
409 find_child_console (HWND hwnd, long putada)
410 {
411   DWORD thread_id;
412   DWORD process_id;
413   struct nt_process_data *cp = (struct nt_process_data *) putada;
414
415   thread_id = GetWindowThreadProcessId (hwnd, &process_id);
416   if (process_id == cp->dwProcessId)
417     {
418       char window_class[32];
419
420       GetClassName (hwnd, window_class, sizeof (window_class));
421       if (strcmp (window_class,
422                   mswindows_windows9x_p ()
423                   ? "tty"
424                   : "ConsoleWindowClass") == 0)
425         {
426           cp->hwnd = hwnd;
427           return FALSE;
428         }
429     }
430   /* keep looking */
431   return TRUE;
432 }
433
434 static int
435 send_signal_the_95_way (struct nt_process_data *cp, int pid, int signo)
436 {
437   HANDLE h_process;
438   int close_process = 0;
439   int rc = 1;
440   
441   if (cp)
442     {
443       pid = cp->dwProcessId;
444       h_process = cp->h_process;
445
446       /* Try to locate console window for process. */
447       EnumWindows (find_child_console, (LPARAM) cp);
448     }
449   else
450     {
451       close_process = 1;
452       /* Try to open the process with required privileges */
453       h_process = OpenProcess (PROCESS_TERMINATE, FALSE, pid);
454       if (!h_process)
455         return 0;
456     }
457     
458   if (signo == SIGINT)
459     {
460       if (NILP (Vmswindows_start_process_share_console) && cp && cp->hwnd)
461         {
462           BYTE control_scan_code = (BYTE) MapVirtualKey (VK_CONTROL, 0);
463           BYTE vk_break_code = VK_CANCEL;
464           BYTE break_scan_code = (BYTE) MapVirtualKey (vk_break_code, 0);
465           HWND foreground_window;
466
467           if (break_scan_code == 0)
468             {
469               /* Fake Ctrl-C if we can't manage Ctrl-Break. */
470               vk_break_code = 'C';
471               break_scan_code = (BYTE) MapVirtualKey (vk_break_code, 0);
472             }
473
474           foreground_window = GetForegroundWindow ();
475           if (foreground_window)
476             {
477               /* NT 5.0, and apparently also Windows 98, will not allow
478                  a Window to be set to foreground directly without the
479                  user's involvement. The workaround is to attach
480                  ourselves to the thread that owns the foreground
481                  window, since that is the only thread that can set the
482                  foreground window.  */
483               DWORD foreground_thread, child_thread;
484               foreground_thread =
485                 GetWindowThreadProcessId (foreground_window, NULL);
486               if (foreground_thread == GetCurrentThreadId ()
487                   || !AttachThreadInput (GetCurrentThreadId (),
488                                          foreground_thread, TRUE))
489                 foreground_thread = 0;
490
491               child_thread = GetWindowThreadProcessId (cp->hwnd, NULL);
492               if (child_thread == GetCurrentThreadId ()
493                   || !AttachThreadInput (GetCurrentThreadId (),
494                                          child_thread, TRUE))
495                 child_thread = 0;
496
497               /* Set the foreground window to the child.  */
498               if (SetForegroundWindow (cp->hwnd))
499                 {
500                   /* Generate keystrokes as if user had typed Ctrl-Break or
501                      Ctrl-C.  */
502                   keybd_event (VK_CONTROL, control_scan_code, 0, 0);
503                   keybd_event (vk_break_code, break_scan_code,
504                     (vk_break_code == 'C' ? 0 : KEYEVENTF_EXTENDEDKEY), 0);
505                   keybd_event (vk_break_code, break_scan_code,
506                     (vk_break_code == 'C' ? 0 : KEYEVENTF_EXTENDEDKEY)
507                     | KEYEVENTF_KEYUP, 0);
508                   keybd_event (VK_CONTROL, control_scan_code,
509                                KEYEVENTF_KEYUP, 0);
510
511                   /* Sleep for a bit to give time for Emacs frame to respond
512                      to focus change events (if Emacs was active app).  */
513                   Sleep (100);
514
515                   SetForegroundWindow (foreground_window);
516                 }
517               /* Detach from the foreground and child threads now that
518                  the foreground switching is over.  */
519               if (foreground_thread)
520                 AttachThreadInput (GetCurrentThreadId (),
521                                    foreground_thread, FALSE);
522               if (child_thread)
523                 AttachThreadInput (GetCurrentThreadId (),
524                                    child_thread, FALSE);
525             }
526         }
527       /* Ctrl-Break is NT equivalent of SIGINT.  */
528       else if (!GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, pid))
529         {
530 #if 0 /* FSF Emacs */
531           DebPrint (("sys_kill.GenerateConsoleCtrlEvent return %d "
532                      "for pid %lu\n", GetLastError (), pid));
533           errno = EINVAL;
534 #endif
535           rc = 0;
536         }
537     }
538   else
539     {
540       if (NILP (Vmswindows_start_process_share_console) && cp && cp->hwnd)
541         {
542 #if 1
543           if (mswindows_windows9x_p ())
544             {
545 /*
546    Another possibility is to try terminating the VDM out-right by
547    calling the Shell VxD (id 0x17) V86 interface, function #4
548    "SHELL_Destroy_VM", ie.
549
550      mov edx,4
551      mov ebx,vm_handle
552      call shellapi
553
554    First need to determine the current VM handle, and then arrange for
555    the shellapi call to be made from the system vm (by using
556    Switch_VM_and_callback).
557
558    Could try to invoke DestroyVM through CallVxD.
559
560 */
561 #if 0
562               /* On Win95, posting WM_QUIT causes the 16-bit subsystem
563                  to hang when cmdproxy is used in conjunction with
564                  command.com for an interactive shell.  Posting
565                  WM_CLOSE pops up a dialog that, when Yes is selected,
566                  does the same thing.  TerminateProcess is also less
567                  than ideal in that subprocesses tend to stick around
568                  until the machine is shutdown, but at least it
569                  doesn't freeze the 16-bit subsystem.  */
570               PostMessage (cp->hwnd, WM_QUIT, 0xff, 0);
571 #endif
572               if (!TerminateProcess (h_process, 0xff))
573                 {
574 #if 0 /* FSF Emacs */
575                   DebPrint (("sys_kill.TerminateProcess returned %d "
576                              "for pid %lu\n", GetLastError (), pid));
577                   errno = EINVAL;
578 #endif
579                   rc = 0;
580                 }
581             }
582           else
583 #endif
584             PostMessage (cp->hwnd, WM_CLOSE, 0, 0);
585         }
586       /* Kill the process.  On W32 this doesn't kill child processes
587          so it doesn't work very well for shells which is why it's not
588          used in every case.  */
589       else if (!TerminateProcess (h_process, 0xff))
590         {
591 #if 0 /* FSF Emacs */
592           DebPrint (("sys_kill.TerminateProcess returned %d "
593                      "for pid %lu\n", GetLastError (), pid));
594           errno = EINVAL;
595 #endif
596           rc = 0;
597         }
598     }
599
600   if (close_process)
601     CloseHandle (h_process);
602
603   return rc;
604 }
605
606 /* -------------------------- all-OS functions ---------------------------- */
607
608 static int
609 send_signal (struct nt_process_data *cp, int pid, int signo)
610 {
611   return (!mswindows_windows9x_p () && send_signal_the_nt_way (cp, pid, signo))
612     || send_signal_the_95_way (cp, pid, signo);
613 }
614
615 /*
616  * Signal error if SIGNO is not supported
617  */
618 static void
619 validate_signal_number (int signo)
620 {
621   if (signo != SIGKILL && signo != SIGTERM
622       && signo != SIGQUIT && signo != SIGINT
623       && signo != SIGHUP)
624     invalid_argument ("Signal number not supported", make_int (signo));
625 }
626 \f  
627 /*-----------------------------------------------------------------------*/
628 /* Process methods                                                       */
629 /*-----------------------------------------------------------------------*/
630
631 /*
632  * Allocate and initialize Lisp_Process->process_data
633  */
634
635 static void
636 nt_alloc_process_data (Lisp_Process *p)
637 {
638   p->process_data = xnew_and_zero (struct nt_process_data);
639 }
640
641 static void
642 nt_finalize_process_data (Lisp_Process *p, int for_disksave)
643 {
644   assert (!for_disksave);
645   if (NT_DATA (p)->h_process)
646     CloseHandle (NT_DATA (p)->h_process);
647 }
648
649 /*
650  * Initialize XEmacs process implementation once
651  */
652 static void
653 nt_init_process (void)
654 {
655   /* Initialize winsock */
656   WSADATA wsa_data;
657   /* Request Winsock v1.1 Note the order: (minor=1, major=1) */
658   WSAStartup (MAKEWORD (1,1), &wsa_data);
659 }
660
661 /*
662  * Fork off a subprocess. P is a pointer to newly created subprocess
663  * object. If this function signals, the caller is responsible for
664  * deleting (and finalizing) the process object.
665  *
666  * The method must return PID of the new process, a (positive??? ####) number
667  * which fits into Lisp_Int. No return value indicates an error, the method
668  * must signal an error instead.
669  */
670
671 static void
672 signal_cannot_launch (Lisp_Object image_file, DWORD err)
673 {
674   mswindows_set_errno (err);
675   report_file_error ("Error starting", image_file);
676 }
677
678 static void
679 ensure_console_window_exists (void)
680 {
681   if (mswindows_windows9x_p ())
682     mswindows_hide_console ();
683 }
684
685 int
686 compare_env (const void *strp1, const void *strp2)
687 {
688   const char *str1 = *(const char**)strp1, *str2 = *(const char**)strp2;
689
690   while (*str1 && *str2 && *str1 != '=' && *str2 != '=')
691     {
692       if ((*str1) > (*str2))
693         return 1;
694       else if ((*str1) < (*str2))
695         return -1;
696       str1++, str2++;
697     }
698
699   if (*str1 == '=' && *str2 == '=')
700     return 0;
701   else if (*str1 == '=')
702     return -1;
703   else
704     return 1;
705 }
706
707 static int
708 nt_create_process (Lisp_Process *p,
709                    Lisp_Object *argv, int nargv,
710                    Lisp_Object program, Lisp_Object cur_dir)
711 {
712   /* Synched up with sys_spawnve in FSF 20.6.  Significantly different
713      but still synchable. */
714   HANDLE hmyshove, hmyslurp, hprocin, hprocout, hprocerr;
715   Extbyte *command_line;
716   BOOL do_io, windowed;
717   char *proc_env;
718
719   /* No need to DOS-ize the filename; expand-file-name (called prior)
720      already does this. */
721
722   /* Find out whether the application is windowed or not */
723   if (xSHGetFileInfoA)
724     {
725       /* SHGetFileInfo tends to return ERROR_FILE_NOT_FOUND on most
726          errors. This leads to bogus error message. */
727       DWORD image_type;
728       char *p = strrchr ((char *)XSTRING_DATA (program), '.');
729       if (p != NULL &&
730           (stricmp (p, ".exe") == 0 ||
731            stricmp (p, ".com") == 0 ||
732            stricmp (p, ".bat") == 0 ||
733            stricmp (p, ".cmd") == 0))
734         {
735           image_type = xSHGetFileInfoA ((char *)XSTRING_DATA (program), 0,NULL,
736                                         0, SHGFI_EXETYPE);
737         }
738       else
739         {
740           char progname[MAX_PATH];
741           sprintf (progname, "%s.exe", (char *)XSTRING_DATA (program));
742           image_type = xSHGetFileInfoA (progname, 0, NULL, 0, SHGFI_EXETYPE);
743         }
744       if (image_type == 0)
745         signal_cannot_launch (program, (GetLastError () == ERROR_FILE_NOT_FOUND
746                                         ? ERROR_BAD_FORMAT : GetLastError ()));
747       windowed = HIWORD (image_type) != 0;
748     }
749   else /* NT 3.5; we have no idea so just guess. */
750     windowed = 0;
751
752   /* Decide whether to do I/O on process handles, or just mark the
753      process exited immediately upon successful launching. We do I/O if the
754      process is a console one, or if it is windowed but windowed_process_io
755      is non-zero */
756   do_io = !windowed || windowed_process_io ;
757   
758   if (do_io)
759     {
760       /* Create two unidirectional named pipes */
761       HANDLE htmp;
762       SECURITY_ATTRIBUTES sa;
763
764       sa.nLength = sizeof(sa);
765       sa.bInheritHandle = TRUE;
766       sa.lpSecurityDescriptor = NULL;
767
768       CreatePipe (&hprocin, &hmyshove, &sa, 0);
769       CreatePipe (&hmyslurp, &hprocout, &sa, 0);
770
771       /* Duplicate the stdout handle for use as stderr */
772       DuplicateHandle(GetCurrentProcess(), hprocout, GetCurrentProcess(),
773                       &hprocerr, 0, TRUE, DUPLICATE_SAME_ACCESS);
774
775       /* Stupid Win32 allows to create a pipe with *both* ends either
776          inheritable or not. We need process ends inheritable, and local
777          ends not inheritable. */
778       DuplicateHandle (GetCurrentProcess(), hmyshove, GetCurrentProcess(),
779                        &htmp, 0, FALSE,
780                        DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS);
781       hmyshove = htmp;
782       DuplicateHandle (GetCurrentProcess(), hmyslurp, GetCurrentProcess(),
783                        &htmp, 0, FALSE,
784                        DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS);
785       hmyslurp = htmp;
786     }
787
788   /* Convert an argv vector into Win32 style command line by a call to
789      lisp function `mswindows-construct-process-command-line'
790      (in win32-native.el) */
791   {
792     int i;
793     Lisp_Object args_or_ret = Qnil;
794     struct gcpro gcpro1;
795
796     GCPRO1 (args_or_ret);
797
798     for (i = 0; i < nargv; ++i)
799       args_or_ret = Fcons (*argv++, args_or_ret);
800     args_or_ret = Fnreverse (args_or_ret);
801     args_or_ret = Fcons (program, args_or_ret);
802
803     args_or_ret = call1 (Qmswindows_construct_process_command_line,
804                          args_or_ret);
805
806     if (!STRINGP (args_or_ret))
807       /* Luser wrote his/her own clever version */
808       invalid_argument
809         ("Bogus return value from `mswindows-construct-process-command-line'",
810          args_or_ret);
811
812     LISP_STRING_TO_EXTERNAL (args_or_ret, command_line, Qmswindows_tstr);
813
814     UNGCPRO; /* args_or_ret */
815   }
816
817   /* Set `proc_env' to a nul-separated array of the strings in
818      Vprocess_environment terminated by 2 nuls.  */
819  
820   {
821     char **env;
822     REGISTER Lisp_Object tem;
823     REGISTER char **new_env;
824     REGISTER int new_length = 0, i, new_space;
825     char *penv;
826     
827     for (tem = Vprocess_environment;
828          (CONSP (tem)
829           && STRINGP (XCAR (tem)));
830          tem = XCDR (tem))
831       new_length++;
832
833     /* FSF adds an extra env var to hold the current process ID of the
834        Emacs process.  Apparently this is used only by emacsserver.c,
835        which we have superseded to gnuserv.c. (#### Does it work under
836        MS Windows?)
837
838        sprintf (ppid_env_var_buffer, "EM_PARENT_PROCESS_ID=%d", 
839          GetCurrentProcessId ());
840        arglen += strlen (ppid_env_var_buffer) + 1;
841        numenv++;
842     */
843     
844     /* new_length + 1 to include terminating 0.  */
845     env = new_env = alloca_array (char *, new_length + 1);
846  
847     /* Copy the Vprocess_environment strings into new_env.  */
848     for (tem = Vprocess_environment;
849          (CONSP (tem)
850           && STRINGP (XCAR (tem)));
851          tem = XCDR (tem))
852       {
853         char **ep = env;
854         char *string = (char *) XSTRING_DATA (XCAR (tem));
855         /* See if this string duplicates any string already in the env.
856            If so, don't put it in.
857            When an env var has multiple definitions,
858            we keep the definition that comes first in process-environment.  */
859         for (; ep != new_env; ep++)
860           {
861             char *p = *ep, *q = string;
862             while (1)
863               {
864                 if (*q == 0)
865                   /* The string is malformed; might as well drop it.  */
866                   goto duplicate;
867                 if (*q != *p)
868                   break;
869                 if (*q == '=')
870                   goto duplicate;
871                 p++, q++;
872               }
873           }
874         *new_env++ = string;
875       duplicate: ;
876       }
877     *new_env = 0;
878     
879     /* Sort the environment variables */
880     new_length = new_env - env;
881     qsort (env, new_length, sizeof (char *), compare_env);
882     
883     /* Work out how much space to allocate */
884     new_space = 0;
885     for (i = 0; i < new_length; i++)
886       {
887         new_space += strlen(env[i]) + 1;
888       }
889     new_space++;
890     
891     /* Allocate space and copy variables into it */
892     penv = proc_env = (char*) alloca(new_space);
893     for (i = 0; i < new_length; i++)
894       {
895         strcpy(penv, env[i]);
896         penv += strlen(env[i]) + 1;
897       }
898     *penv = 0;
899   }
900
901 #if 0
902     /* #### we need to port this. */
903     /* On Windows 95, if cmdname is a DOS app, we invoke a helper
904        application to start it by specifying the helper app as cmdname,
905        while leaving the real app name as argv[0].  */
906     if (is_dos_app)
907       {
908         cmdname = (char*) alloca (MAXPATHLEN);
909         if (egetenv ("CMDPROXY"))
910           strcpy ((char*)cmdname, egetenv ("CMDPROXY"));
911         else
912           {
913             strcpy ((char*)cmdname, XSTRING_DATA (Vinvocation_directory));
914             strcat ((char*)cmdname, "cmdproxy.exe");
915           }
916       }
917 #endif
918   
919   /* Create process */
920   {
921     STARTUPINFO si;
922     PROCESS_INFORMATION pi;
923     DWORD err;
924     DWORD flags;
925
926     xzero (si);
927     si.dwFlags = STARTF_USESHOWWINDOW;
928     si.wShowWindow = windowed ? SW_SHOWNORMAL : SW_HIDE;
929     if (do_io)
930       {
931         si.hStdInput = hprocin;
932         si.hStdOutput = hprocout;
933         si.hStdError = hprocerr;
934         si.dwFlags |= STARTF_USESTDHANDLES;
935       }
936
937     flags = CREATE_SUSPENDED;
938     if (mswindows_windows9x_p ())
939       flags |= (!NILP (Vmswindows_start_process_share_console)
940                 ? CREATE_NEW_PROCESS_GROUP
941                 : CREATE_NEW_CONSOLE);
942     else
943       flags |= CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP;
944     if (NILP (Vmswindows_start_process_inherit_error_mode))
945       flags |= CREATE_DEFAULT_ERROR_MODE;
946
947     ensure_console_window_exists ();
948
949     err = (CreateProcess (NULL, command_line, NULL, NULL, TRUE, flags,
950                           proc_env, (char *) XSTRING_DATA (cur_dir), &si, &pi)
951            ? 0 : GetLastError ());
952
953     if (do_io)
954       {
955         /* These just have been inherited; we do not need a copy */
956         CloseHandle (hprocin);
957         CloseHandle (hprocout);
958         CloseHandle (hprocerr);
959       }
960     
961     /* Handle process creation failure */
962     if (err)
963       {
964         if (do_io)
965           {
966             CloseHandle (hmyshove);
967             CloseHandle (hmyslurp);
968           }
969         signal_cannot_launch (program, GetLastError ());
970       }
971
972     /* The process started successfully */
973     if (do_io)
974       {
975         NT_DATA(p)->h_process = pi.hProcess;
976         NT_DATA(p)->dwProcessId = pi.dwProcessId;
977         init_process_io_handles (p, (void*)hmyslurp, (void*)hmyshove, 0);
978       }
979     else
980       {
981         /* Indicate as if the process has exited immediately. */
982         p->status_symbol = Qexit;
983         CloseHandle (pi.hProcess);
984       }
985
986     if (!windowed)
987       enable_child_signals (pi.hProcess);
988
989     ResumeThread (pi.hThread);
990     CloseHandle (pi.hThread);
991
992     return ((int)pi.dwProcessId);
993   }
994 }
995
996 /* 
997  * This method is called to update status fields of the process
998  * structure. If the process has not existed, this method is expected
999  * to do nothing.
1000  *
1001  * The method is called only for real child processes.  
1002  */
1003
1004 static void
1005 nt_update_status_if_terminated (Lisp_Process* p)
1006 {
1007   DWORD exit_code;
1008   if (GetExitCodeProcess (NT_DATA(p)->h_process, &exit_code)
1009       && exit_code != STILL_ACTIVE)
1010     {
1011       p->tick++;
1012       p->core_dumped = 0;
1013       /* The exit code can be a code returned by process, or an
1014          NTSTATUS value. We cannot accurately handle the latter since
1015          it is a full 32 bit integer */
1016       if (exit_code & 0xC0000000)
1017         {
1018           p->status_symbol = Qsignal;
1019           p->exit_code = exit_code & 0x1FFFFFFF;
1020         }
1021       else
1022         {
1023           p->status_symbol = Qexit;
1024           p->exit_code = exit_code;
1025         }
1026     }
1027 }
1028
1029 /*
1030  * Stuff the entire contents of LSTREAM to the process output pipe
1031  */
1032
1033 /* #### If only this function could be somehow merged with
1034    unix_send_process... */
1035
1036 static void
1037 nt_send_process (Lisp_Object proc, struct lstream* lstream)
1038 {
1039   volatile Lisp_Object vol_proc = proc;
1040   Lisp_Process *volatile p = XPROCESS (proc);
1041
1042   /* use a reasonable-sized buffer (somewhere around the size of the
1043      stream buffer) so as to avoid inundating the stream with blocked
1044      data. */
1045   Bufbyte chunkbuf[512];
1046   Bytecount chunklen;
1047
1048   while (1)
1049     {
1050       Lstream_data_count writeret;
1051
1052       chunklen = Lstream_read (lstream, chunkbuf, 512);
1053       if (chunklen <= 0)
1054         break; /* perhaps should abort() if < 0?
1055                   This should never happen. */
1056
1057       /* Lstream_write() will never successfully write less than the
1058          amount sent in.  In the worst case, it just buffers the
1059          unwritten data. */
1060       writeret = Lstream_write (XLSTREAM (DATA_OUTSTREAM(p)), chunkbuf,
1061                                 chunklen);
1062       Lstream_flush (XLSTREAM (DATA_OUTSTREAM(p)));
1063       if (writeret < 0)
1064         {
1065           p->status_symbol = Qexit;
1066           p->exit_code = ERROR_BROKEN_PIPE;
1067           p->core_dumped = 0;
1068           p->tick++;
1069           process_tick++;
1070           deactivate_process (*((Lisp_Object *) (&vol_proc)));
1071           invalid_operation ("Broken pipe error sending to process; closed it",
1072                              p->name);
1073         }
1074
1075       {
1076         int wait_ms = 25;
1077         while (Lstream_was_blocked_p (XLSTREAM (p->pipe_outstream)))
1078           {
1079             /* Buffer is full.  Wait, accepting input; that may allow
1080                the program to finish doing output and read more.  */
1081             Faccept_process_output (Qnil, Qzero, make_int (wait_ms));
1082             Lstream_flush (XLSTREAM (p->pipe_outstream));
1083             wait_ms = min (1000, 2 * wait_ms);
1084           }
1085       }
1086     }
1087 }
1088
1089 /*
1090  * Send a signal number SIGNO to PROCESS.
1091  * CURRENT_GROUP means send to the process group that currently owns
1092  * the terminal being used to communicate with PROCESS.
1093  * This is used for various commands in shell mode.
1094  * If NOMSG is zero, insert signal-announcements into process's buffers
1095  * right away.
1096  *
1097  * If we can, we try to signal PROCESS by sending control characters
1098  * down the pty.  This allows us to signal inferiors who have changed
1099  * their uid, for which killpg would return an EPERM error.
1100  *
1101  * The method signals an error if the given SIGNO is not valid
1102  */
1103
1104 static void
1105 nt_kill_child_process (Lisp_Object proc, int signo,
1106                        int current_group, int nomsg)
1107 {
1108   Lisp_Process *p = XPROCESS (proc);
1109
1110   /* Signal error if SIGNO cannot be sent */
1111   validate_signal_number (signo);
1112
1113   /* Send signal */
1114   if (!send_signal (NT_DATA (p), 0, signo))
1115     invalid_operation ("Cannot send signal to process", proc);
1116 }
1117
1118 /*
1119  * Kill any process in the system given its PID
1120  *
1121  * Returns zero if a signal successfully sent, or
1122  * negative number upon failure
1123  */
1124 static int
1125 nt_kill_process_by_pid (int pid, int signo)
1126 {
1127   struct Lisp_Process *p;
1128
1129   /* Signal error if SIGNO cannot be sent */
1130   validate_signal_number (signo);
1131
1132   p = find_process_from_pid (pid);
1133   return send_signal (p ? NT_DATA (p) : 0, pid, signo) ? 0 : -1;
1134 }
1135 \f
1136 /*-----------------------------------------------------------------------*/
1137 /* Sockets connections                                                   */
1138 /*-----------------------------------------------------------------------*/
1139 #ifdef HAVE_SOCKETS
1140
1141 /* #### Hey MS, how long Winsock 2 for '95 will be in beta? */
1142
1143 #define SOCK_TIMER_ID 666
1144 #define XM_SOCKREPLY (WM_USER + 666)
1145
1146 static int
1147 get_internet_address (Lisp_Object host, struct sockaddr_in *address,
1148                       Error_behavior errb)
1149 {
1150   char buf [MAXGETHOSTSTRUCT];
1151   HWND hwnd;
1152   HANDLE hasync;
1153   int success = 0;
1154
1155   address->sin_family = AF_INET;
1156
1157   /* First check if HOST is already a numeric address */
1158   {
1159     unsigned long inaddr = inet_addr (XSTRING_DATA (host));
1160     if (inaddr != INADDR_NONE)
1161       {
1162         address->sin_addr.s_addr = inaddr;
1163         return 1;
1164       }
1165   }
1166
1167   /* Create a window which will receive completion messages */
1168   hwnd = CreateWindow ("STATIC", NULL, WS_OVERLAPPED, 0, 0, 1, 1,
1169                        NULL, NULL, NULL, NULL);
1170   assert (hwnd);
1171
1172   /* Post name resolution request */
1173   hasync = WSAAsyncGetHostByName (hwnd, XM_SOCKREPLY, XSTRING_DATA (host),
1174                                   buf, sizeof (buf));
1175   if (hasync == NULL)
1176     goto done;
1177
1178   /* Set a timer to poll for quit every 250 ms */
1179   SetTimer (hwnd, SOCK_TIMER_ID, 250, NULL);
1180
1181   while (1)
1182     {
1183       MSG msg;
1184       GetMessage (&msg, hwnd, 0, 0);
1185       if (msg.message == XM_SOCKREPLY)
1186         {
1187           /* Ok, got an answer */
1188           if (WSAGETASYNCERROR(msg.lParam) == NO_ERROR)
1189             success = 1;
1190           else
1191             {
1192               warn_when_safe(Qstream, Qwarning,
1193                              "cannot get IP address for host \"%s\"",
1194                              XSTRING_DATA (host));
1195             }
1196           goto done;
1197         }
1198       else if (msg.message == WM_TIMER && msg.wParam == SOCK_TIMER_ID)
1199         {
1200           if (QUITP)
1201             {
1202               WSACancelAsyncRequest (hasync);
1203               KillTimer (hwnd, SOCK_TIMER_ID);
1204               DestroyWindow (hwnd);
1205               REALLY_QUIT;
1206             }
1207         }
1208       DispatchMessage (&msg);
1209     }
1210
1211  done:
1212   KillTimer (hwnd, SOCK_TIMER_ID);
1213   DestroyWindow (hwnd);
1214   if (success)
1215     {
1216       /* BUF starts with struct hostent */
1217       struct hostent* he = (struct hostent*) buf;
1218       address->sin_addr.s_addr = *(unsigned long*)he->h_addr_list[0];
1219     }
1220   return success;
1221 }
1222
1223 static Lisp_Object
1224 nt_canonicalize_host_name (Lisp_Object host)
1225 {
1226   struct sockaddr_in address;
1227
1228   if (!get_internet_address (host, &address, ERROR_ME_NOT))
1229     return host;
1230
1231   if (address.sin_family == AF_INET)
1232     return build_string (inet_ntoa (address.sin_addr));
1233   else
1234     return host;
1235 }
1236
1237 /* open a TCP network connection to a given HOST/SERVICE.  Treated
1238    exactly like a normal process when reading and writing.  Only
1239    differences are in status display and process deletion.  A network
1240    connection has no PID; you cannot signal it.  All you can do is
1241    deactivate and close it via delete-process */
1242
1243 static void
1244 nt_open_network_stream (Lisp_Object name, Lisp_Object host,
1245                         Lisp_Object service,
1246                         Lisp_Object protocol, void** vinfd, void** voutfd)
1247 {
1248   /* !!#### not Mule-ized */
1249   struct sockaddr_in address;
1250   SOCKET s;
1251   int port;
1252   int retval;
1253
1254   CHECK_STRING (host);
1255
1256   if (!EQ (protocol, Qtcp))
1257     invalid_argument ("Unsupported protocol", protocol);
1258
1259   if (INTP (service))
1260     port = htons ((unsigned short) XINT (service));
1261   else
1262     {
1263       struct servent *svc_info;
1264       CHECK_STRING (service);
1265       svc_info = getservbyname ((char *) XSTRING_DATA (service), "tcp");
1266       if (svc_info == 0)
1267         invalid_argument ("Unknown service", service);
1268       port = svc_info->s_port;
1269     }
1270
1271   get_internet_address (host, &address, ERROR_ME);
1272   address.sin_port = port;
1273
1274   s = socket (address.sin_family, SOCK_STREAM, 0);
1275   if (s < 0)
1276     report_file_error ("error creating socket", list1 (name));
1277
1278   /* We don't want to be blocked on connect */
1279   {
1280     unsigned long nonblock = 1;
1281     ioctlsocket (s, FIONBIO, &nonblock);
1282   }
1283   
1284   retval = connect (s, (struct sockaddr *) &address, sizeof (address));
1285   if (retval != NO_ERROR && WSAGetLastError() != WSAEWOULDBLOCK)
1286     goto connect_failed;
1287   /* Wait while connection is established */
1288   while (1)
1289     {
1290       fd_set fdset;
1291       struct timeval tv;
1292       int nsel;
1293
1294       if (QUITP)
1295         {
1296           closesocket (s);
1297           REALLY_QUIT;
1298         }
1299
1300       /* Poll for quit every 250 ms */
1301       tv.tv_sec = 0;
1302       tv.tv_usec = 250 * 1000;
1303
1304       FD_ZERO (&fdset);
1305       FD_SET (s, &fdset);
1306       nsel = select (0, NULL, &fdset, &fdset, &tv);
1307
1308       if (nsel > 0)
1309         {
1310           /* Check: was connection successful or not? */
1311           tv.tv_usec = 0;
1312           nsel = select (0, NULL, NULL, &fdset, &tv);
1313           if (nsel > 0)
1314             goto connect_failed;
1315           else
1316             break;
1317         }
1318     }
1319
1320   /* We are connected at this point */
1321   *vinfd = (void*)s;
1322   DuplicateHandle (GetCurrentProcess(), (HANDLE)s,
1323                    GetCurrentProcess(), (LPHANDLE)voutfd,
1324                    0, FALSE, DUPLICATE_SAME_ACCESS);
1325   return;
1326
1327  connect_failed:  
1328   closesocket (s);
1329   if (INTP (service))
1330     {
1331       warn_when_safe (Qstream, Qwarning,
1332                       "failure to open network stream to host \"%s\" for service \"%d\"",
1333                       XSTRING_DATA (host),
1334                       (unsigned short) XINT (service));
1335     }
1336   else
1337     {
1338       warn_when_safe (Qstream, Qwarning,
1339                       "failure to open network stream to host \"%s\" for service \"%s\"",
1340                       XSTRING_DATA (host),
1341                       XSTRING_DATA (service));
1342     }
1343   report_file_error ("connection failed", list2 (host, name));
1344 }
1345
1346 #endif
1347 \f
1348 /*-----------------------------------------------------------------------*/
1349 /* Initialization                                                        */
1350 /*-----------------------------------------------------------------------*/
1351
1352 void
1353 process_type_create_nt (void)
1354 {
1355   PROCESS_HAS_METHOD (nt, alloc_process_data);
1356   PROCESS_HAS_METHOD (nt, finalize_process_data);
1357   PROCESS_HAS_METHOD (nt, init_process);
1358   PROCESS_HAS_METHOD (nt, create_process);
1359   PROCESS_HAS_METHOD (nt, update_status_if_terminated);
1360   PROCESS_HAS_METHOD (nt, send_process);
1361   PROCESS_HAS_METHOD (nt, kill_child_process);
1362   PROCESS_HAS_METHOD (nt, kill_process_by_pid);
1363 #ifdef HAVE_SOCKETS
1364   PROCESS_HAS_METHOD (nt, canonicalize_host_name);
1365   PROCESS_HAS_METHOD (nt, open_network_stream);
1366 #ifdef HAVE_MULTICAST
1367 #error I won't do this until '95 has winsock2
1368   PROCESS_HAS_METHOD (nt, open_multicast_group);
1369 #endif
1370 #endif
1371 }
1372
1373 void
1374 syms_of_process_nt (void)
1375 {
1376   DEFSYMBOL (Qmswindows_construct_process_command_line);
1377 }
1378
1379 void
1380 vars_of_process_nt (void)
1381 {
1382   DEFVAR_LISP ("mswindows-start-process-share-console",
1383                &Vmswindows_start_process_share_console /*
1384 When nil, new child processes are given a new console.
1385 When non-nil, they share the Emacs console; this has the limitation of
1386 allowing only only DOS subprocess to run at a time (whether started directly
1387 or indirectly by Emacs), and preventing Emacs from cleanly terminating the
1388 subprocess group, but may allow Emacs to interrupt a subprocess that doesn't
1389 otherwise respond to interrupts from Emacs.
1390 */ );
1391   Vmswindows_start_process_share_console = Qnil;
1392
1393   DEFVAR_LISP ("mswindows-start-process-inherit-error-mode",
1394                &Vmswindows_start_process_inherit_error_mode /*
1395     "When nil, new child processes revert to the default error mode.
1396 When non-nil, they inherit their error mode setting from Emacs, which stops
1397 them blocking when trying to access unmounted drives etc.
1398 */ );
1399   Vmswindows_start_process_inherit_error_mode = Qt;
1400 }