Release 941122
[wine] / misc / exec.c
1 /*
2 *     Windows Exec & Help
3 *
4 */
5
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <string.h>
9 #include <unistd.h>
10 #include "neexe.h"
11 #include "segmem.h"
12 #include "prototypes.h"
13 #include "dlls.h"
14 #include "wine.h"
15 #include "windows.h"
16 #include "stddebug.h"
17 /* #define DEBUG_EXEC /* */
18 /* #undef  DEBUG_EXEC /* */
19 #include "debug.h"
20
21 #define HELP_CONTEXT      0x0001
22 #define HELP_QUIT         0x0002
23 #define HELP_INDEX        0x0003
24 #define HELP_CONTENTS     0x0003
25 #define HELP_HELPONHELP   0x0004
26 #define HELP_SETINDEX     0x0005
27 #define HELP_SETCONTENTS  0x0005
28 #define HELP_CONTEXTPOPUP 0x0008
29 #define HELP_FORCEFILE    0x0009
30 #define HELP_KEY          0x0101
31 #define HELP_COMMAND      0x0102
32 #define HELP_PARTIALKEY   0x0105
33 #define HELP_MULTIKEY     0x0201
34 #define HELP_SETWINPOS    0x0203
35
36 extern struct  w_files * wine_files;
37
38 typedef struct {
39         WORD    wEnvSeg;
40         LPSTR   lpCmdLine;
41         LPVOID  lpCmdShow;
42         DWORD   dwReserved;
43         } PARAMBLOCK;
44
45 typedef BOOL (CALLBACK * LPFNWINMAIN)(HANDLE, HANDLE, LPSTR, int);
46
47
48 extern int CallToInit16(unsigned long csip, unsigned long sssp, 
49                         unsigned short ds);
50 HANDLE CreateNewTask(HINSTANCE hInst);
51
52 #ifndef WINELIB
53 void InitializeLoadedNewDLLs(HINSTANCE hInst)
54 {
55     struct w_files * w;
56     struct w_files * wpnt;
57     int cs_reg, ds_reg, ip_reg;
58     int rv;
59
60     dprintf_exec(stddeb, "Initializing New DLLs\n");
61
62     /*
63      * Initialize libraries
64      */
65     dprintf_exec(stddeb,
66         "InitializeLoadedNewDLLs() before searching hInst=%04X !\n", hInst);
67         w = wine_files;
68         while (w && w->hinstance != hInst) w = w->next;
69         if (w == NULL) return;
70     dprintf_exec(stddeb,"InitializeLoadedNewDLLs() // before InitLoop !\n");
71     for(wpnt = w; wpnt; wpnt = wpnt->next)
72     {
73         /* 
74          * Is this a library? 
75          */
76         if (wpnt->ne->ne_header->format_flags & 0x8000)
77         {
78             if (!(wpnt->ne->ne_header->format_flags & 0x0001))
79             {
80                 /* Not SINGLEDATA */
81                 fprintf(stderr, "Library is not marked SINGLEDATA\n");
82                 exit(1);
83             }
84
85             ds_reg = wpnt->ne->selector_table[wpnt->ne->
86                                           ne_header->auto_data_seg-1].selector;
87             cs_reg = wpnt->ne->selector_table[wpnt->ne->ne_header->cs-1].selector;
88             ip_reg = wpnt->ne->ne_header->ip;
89
90         dprintf_exec(stddeb, "Initializing %s, cs:ip %04x:%04x, ds %04x\n",
91                     wpnt->name, cs_reg, ip_reg, ds_reg);
92
93             rv = CallTo16(cs_reg << 16 | ip_reg, ds_reg);
94         dprintf_exec(stddeb,"rv = %x\n", rv);
95         }
96     }
97 }
98
99
100 void StartNewTask(HINSTANCE hInst)
101 {
102         struct w_files * wpnt;
103         struct w_files * w;
104         int cs_reg, ds_reg, ss_reg, ip_reg, sp_reg;
105         int rv;
106         int segment;
107
108         dprintf_exec(stddeb,
109                 "StartNewTask() before searching hInst=%04X !\n", hInst);
110         wpnt = wine_files;
111         while (wpnt && wpnt->hinstance != hInst) wpnt = wpnt->next;
112         if (wpnt == NULL) return;
113         dprintf_exec(stddeb,"StartNewTask() // before FixupSegment !\n");
114         for(w = wpnt; w; w = w->next)   {
115                 for (segment = 0; segment < w->ne->ne_header->n_segment_tab; segment++) {
116                         if (FixupSegment(w, segment) < 0) {
117                                 myerror("fixup failed.");
118                                 }
119                         }
120                 }
121         dprintf_exec(stddeb,"StartNewTask() before InitializeLoadedNewDLLs !\n");
122         InitializeLoadedNewDLLs(hInst);
123         dprintf_exec(stddeb,"StartNewTask() before setup register !\n");
124     ds_reg = (wpnt->ne->selector_table[wpnt->ne->ne_header->auto_data_seg-1].selector);
125     cs_reg = wpnt->ne->selector_table[wpnt->ne->ne_header->cs-1].selector;
126     ip_reg = wpnt->ne->ne_header->ip;
127     ss_reg = wpnt->ne->selector_table[wpnt->ne->ne_header->ss-1].selector;
128     sp_reg = wpnt->ne->ne_header->sp;
129
130         dprintf_exec(stddeb,"StartNewTask() before CallToInit16() !\n");
131     rv = CallToInit16(cs_reg << 16 | ip_reg, ss_reg << 16 | sp_reg, ds_reg);
132     dprintf_exec(stddeb,"rv = %x\n", rv);
133
134 }
135
136 #else
137 void StartNewTask (HINSTANCE hInst)
138 {
139     fprintf(stdnimp, "StartNewTask(): Not yet implemented\n");
140 }
141 #endif
142
143 /**********************************************************************
144  *                              LoadModule      [KERNEL.45]
145  */
146 HANDLE LoadModule(LPSTR modulefile, LPVOID lpParamBlk)
147 {
148         PARAMBLOCK  *pblk = lpParamBlk;
149         WORD    *lpCmdShow;
150         dprintf_exec(stddeb,"LoadModule '%s' %p\n", modulefile, lpParamBlk);
151         if (lpParamBlk == NULL) return 0;
152         lpCmdShow = (WORD *)pblk->lpCmdShow;
153         return WinExec(pblk->lpCmdLine, lpCmdShow[1]);
154 }
155
156
157 /**********************************************************************
158  *                              WinExec         [KERNEL.166]
159  */
160 WORD WinExec(LPSTR lpCmdLine, WORD nCmdShow)
161 {
162         int             c = 0;
163         int             x, x2;
164         char            *ArgV[20];
165         HINSTANCE       hInst = 0;
166         HANDLE          hTask = 0;
167         dprintf_exec(stddeb,"WinExec('%s', %04X)\n", lpCmdLine, nCmdShow);
168 /*      ArgV[0] = "wine";
169         c = 1; */
170         for (x = x2 = 0; x < strlen(lpCmdLine) + 1; x++) {
171                 if ((lpCmdLine[x] == ' ') || (lpCmdLine[x] == '\0')) {
172                         ArgV[c] = (char *)malloc(x - x2 + 1);
173                         strncpy(ArgV[c], &lpCmdLine[x2], x - x2);
174                         ArgV[c][x - x2] = '\0';
175                         c++;   x2 = x + 1;
176                         }                                                         
177                 }  
178         ArgV[c] = NULL;
179     for (c = 0; ArgV[c] != NULL; c++) 
180         dprintf_exec(stddeb,"--> '%s' \n", ArgV[c]);
181         switch(fork()) {
182                 case -1:
183             fprintf(stderr,"Can't 'fork' process !\n");
184                         break;
185                 case 0:
186                         if ((hInst = LoadImage(ArgV[0], EXE, 1)) == (HINSTANCE) NULL ) {
187                                 fprintf(stderr, "wine: can't find %s!.\n", ArgV[0]);
188                                 fprintf(stderr,"Child process died !\n");
189                                 exit(1);
190                                 }
191                         hTask = CreateNewTask(hInst);
192                         dprintf_exec(stddeb,
193                         "WinExec // hTask=%04X hInst=%04X !\n", hTask, hInst);
194                         StartNewTask(hInst); 
195 /*
196                         lpfnMain = (LPFNWINMAIN)GetProcAddress(hInst, (LPSTR)0L);
197                         dprintf_exec(stddeb,
198                         "WineExec() // lpfnMain=%08X\n", (LONG)lpfnMain);
199                         if (lpfnMain != NULL) {
200                                 (lpfnMain)(hInst, 0, lpCmdLine, nCmdShow);
201                                 dprintf_exec(stddeb,
202                                         "WineExec() // after lpfnMain\n");
203                                 }
204 */
205 /*                      hTask = CreateNewTask(0);
206                         dprintf_exec(stddeb,
207                                 "WinExec // New Task hTask=%04X !\n", hTask);
208                         execvp(ArgV[0], ArgV); */
209
210                         fprintf(stderr,"Child process died !\n");
211                         exit(1);
212                 default:
213                         dprintf_exec(stddeb,
214                         "WinExec (Main process stay alive) hTask=%04X !\n", 
215                         hTask);
216                         break;         
217                 }
218         for (c = 0; ArgV[c] != NULL; c++)       free(ArgV[c]);
219         return hTask;
220 }
221
222
223 /**********************************************************************
224  *                              ExitWindows             [USER.7]
225  */
226 BOOL ExitWindows(DWORD dwReserved, WORD wRetCode)
227 {
228     dprintf_exec(stdnimp,"EMPTY STUB !!! ExitWindows(%08lX, %04X) !\n", 
229                 dwReserved, wRetCode);
230 }
231
232
233 /**********************************************************************
234  *                              WinHelp         [USER.171]
235  */
236 BOOL WinHelp(HWND hWnd, LPSTR lpHelpFile, WORD wCommand, DWORD dwData)
237 {
238         char    str[256];
239         dprintf_exec(stddeb,"WinHelp(%s, %u, %lu)\n", 
240                 lpHelpFile, wCommand, dwData);
241         switch(wCommand) {
242         case 0:
243         case HELP_HELPONHELP:
244                 GetWindowsDirectory(str, sizeof(str));
245                 strcat(str, "\\winhelp.exe");
246         dprintf_exec(stddeb,"'%s'\n", str);
247                 break;
248         case HELP_INDEX:
249                 GetWindowsDirectory(str, sizeof(str));
250                 strcat(str, "\\winhelp.exe");
251         dprintf_exec(stddeb,"'%s'\n", str);
252                 break;
253         default:
254                 return FALSE;
255         }
256         WinExec(str, SW_SHOWNORMAL);
257         return(TRUE);
258 }