Release 940804
[wine/gsoc-2012-control.git] / loader / main.c
blobc1991d04afcbda890e3aba5707ae909144cb97b4
1 static char RCSId[] = "$Id: wine.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
2 static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <fcntl.h>
9 #include <unistd.h>
10 #include <string.h>
11 #include <errno.h>
12 #ifdef linux
13 #include <linux/unistd.h>
14 #include <linux/head.h>
15 #include <linux/ldt.h>
16 #include <linux/segment.h>
17 #endif
18 #include "neexe.h"
19 #include "segmem.h"
20 #include "prototypes.h"
21 #include "dlls.h"
22 #include "wine.h"
23 #include "windows.h"
24 #include "wineopts.h"
25 #include "arch.h"
26 #include "options.h"
28 /* #define DEBUG_FIXUP */
30 extern HANDLE CreateNewTask(HINSTANCE hInst);
31 extern int CallToInit16(unsigned long csip, unsigned long sssp,
32 unsigned short ds);
33 extern void CallTo32();
35 char *GetDosFileName(char *unixfilename);
36 char *GetModuleName(struct w_files * wpnt, int index, char *buffer);
37 extern unsigned char ran_out;
38 extern char WindowsPath[256];
39 char *WIN_ProgramName;
41 unsigned short WIN_StackSize;
42 unsigned short WIN_HeapSize;
44 struct w_files * wine_files = NULL;
46 char **Argv;
47 int Argc;
48 HINSTANCE hSysRes;
50 static char *DLL_Extensions[] = { "dll", NULL };
51 static char *EXE_Extensions[] = { "exe", NULL };
53 /**********************************************************************
54 * myerror
56 void
57 myerror(const char *s)
59 if (s == NULL)
60 perror("wine");
61 else
62 fprintf(stderr, "wine: %s\n", s);
64 exit(1);
67 /**********************************************************************
68 * GetFilenameFromInstance
70 char *
71 GetFilenameFromInstance(unsigned short instance)
73 register struct w_files *w = wine_files;
75 while (w && w->hinstance != instance)
76 w = w->next;
78 if (w)
79 return w->filename;
80 else
81 return NULL;
84 struct w_files *
85 GetFileInfo(unsigned short instance)
87 register struct w_files *w = wine_files;
89 while (w && w->hinstance != instance)
90 w = w->next;
92 return w;
95 #ifndef WINELIB
96 /**********************************************************************
98 * Load MZ Header
100 void load_mz_header(int fd, struct mz_header_s *mz_header)
102 if (read(fd, mz_header, sizeof(struct mz_header_s)) !=
103 sizeof(struct mz_header_s))
105 myerror("Unable to read MZ header from file");
108 #endif
110 int IsDLLLoaded(char *name)
112 struct w_files *wpnt;
114 if(FindDLLTable(name))
115 return 1;
117 for(wpnt = wine_files; wpnt; wpnt = wpnt->next)
118 if(strcmp(wpnt->name, name) == 0)
119 return 1;
121 return 0;
124 /**********************************************************************
125 * LoadImage
126 * Load one executable into memory
128 HINSTANCE LoadImage(char *module, int filetype, int change_dir)
130 unsigned int read_size;
131 int i;
132 struct w_files * wpnt, *wpnt1;
133 unsigned int status;
134 char buffer[256], header[2], modulename[64], *fullname;
136 ExtractDLLName(module, modulename);
137 printf("%sLoadImage \n", module);
138 /* built-in one ? */
139 if (FindDLLTable(modulename)) {
140 return GetModuleHandle(modulename);
143 /* already loaded ? */
144 for (wpnt = wine_files ; wpnt ; wpnt = wpnt->next)
145 if (strcasecmp(wpnt->name, modulename) == 0)
146 return wpnt->hinstance;
149 * search file
151 fullname = FindFile(buffer, sizeof(buffer), module,
152 (filetype == EXE ? EXE_Extensions : DLL_Extensions),
153 WindowsPath);
154 if (fullname == NULL)
156 fprintf(stderr, "LoadImage: I can't find %s.dll | %s.exe !\n",
157 module, module);
158 return 2;
161 fullname = GetDosFileName(fullname);
162 WIN_ProgramName = strdup(fullname);
164 fprintf(stderr,"LoadImage: loading %s (%s)\n [%s]\n",
165 module, buffer, WIN_ProgramName);
167 if (change_dir && fullname)
169 char dirname[256];
170 char *p;
172 strcpy(dirname, fullname);
173 p = strrchr(dirname, '\\');
174 *p = '\0';
176 DOS_SetDefaultDrive(dirname[0] - 'A');
177 DOS_ChangeDir(dirname[0] - 'A', dirname + 2);
180 /* First allocate a spot to store the info we collect, and add it to
181 * our linked list.
184 wpnt = (struct w_files *) malloc(sizeof(struct w_files));
185 if(wine_files == NULL)
186 wine_files = wpnt;
187 else {
188 wpnt1 = wine_files;
189 while(wpnt1->next) wpnt1 = wpnt1->next;
190 wpnt1->next = wpnt;
192 wpnt->next = NULL;
193 wpnt->resnamtab = (RESNAMTAB *) -1;
196 * Open file for reading.
198 wpnt->fd = open(buffer, O_RDONLY);
199 if (wpnt->fd < 0)
200 return 2;
203 * Establish header pointers.
205 wpnt->filename = strdup(buffer);
206 wpnt->name = strdup(modulename);
208 /* if(module) {
209 wpnt->name = strdup(module);
210 ToDos(wpnt->name);
213 /* read mz header */
214 wpnt->mz_header = (struct mz_header_s *) malloc(sizeof(struct mz_header_s));;
215 status = lseek(wpnt->fd, 0, SEEK_SET);
216 load_mz_header (wpnt->fd, wpnt->mz_header);
217 if (wpnt->mz_header->must_be_0x40 != 0x40 &&
218 wpnt->mz_header->must_be_0x40 != 0x1e)
219 myerror("This is not a Windows program");
221 /* read first two bytes to determine filetype */
222 status = lseek(wpnt->fd, wpnt->mz_header->ne_offset, SEEK_SET);
223 read(wpnt->fd, &header, sizeof(header));
225 if (header[0] == 'N' && header[1] == 'E')
226 return (LoadNEImage(wpnt));
228 if (header[0] == 'P' && header[1] == 'E') {
229 printf("win32 applications are not supported");
230 return 14;
233 fprintf(stderr, "wine: (%s) unknown fileformat !\n", wpnt->filename);
235 return 14;
238 #ifndef WINELIB
239 /**********************************************************************
240 * main
242 int _WinMain(int argc, char **argv)
244 int segment;
245 char *p;
246 char *sysresname;
247 char filename[256];
248 HANDLE hTaskMain;
249 HINSTANCE hInstMain;
250 #ifdef WINESTAT
251 char * cp;
252 #endif
253 struct w_files * wpnt;
254 int cs_reg, ds_reg, ss_reg, ip_reg, sp_reg;
255 int rv;
257 Argc = argc - 1;
258 Argv = argv + 1;
260 if (strchr(Argv[0], '\\') || strchr(Argv[0],'/')) {
261 for (p = Argv[0] + strlen(Argv[0]); *p != '\\' && *p !='/'; p--)
262 /* NOTHING */;
264 strncpy(filename, Argv[0], p - Argv[0]);
265 filename[p - Argv[0]] = '\0';
266 strcat(WindowsPath, ";");
267 if (strchr(filename, '/'))
268 strcat(WindowsPath, GetDosFileName(filename));
269 else
270 strcat(WindowsPath, filename);
273 if ((hInstMain = LoadImage(Argv[0], EXE, 1)) < 32) {
274 fprintf(stderr, "wine: can't load %s!.\n", Argv[0]);
275 exit(1);
277 hTaskMain = CreateNewTask(hInstMain);
278 printf("_WinMain // hTaskMain=%04X hInstMain=%04X !\n", hTaskMain, hInstMain);
280 GetPrivateProfileString("wine", "SystemResources", "sysres.dll",
281 filename, sizeof(filename), WINE_INI);
283 hSysRes = LoadImage(filename, DLL, 0);
284 if (hSysRes < 32) {
285 fprintf(stderr, "wine: can't load %s!.\n", filename);
286 exit(1);
287 } else
288 printf("System Resources Loaded // hSysRes='%04X'\n", hSysRes);
291 * Fixup references.
293 /* wpnt = wine_files;
294 for(wpnt = wine_files; wpnt; wpnt = wpnt->next)
295 for (segment = 0; segment < wpnt->ne_header->n_segment_tab; segment++)
296 if (FixupSegment(wpnt, segment) < 0)
297 myerror("fixup failed.");
300 #ifdef WINESTAT
301 cp = strrchr(argv[0], '/');
302 if(!cp) cp = argv[0];
303 else cp++;
304 if(strcmp(cp,"winestat") == 0) {
305 winestat();
306 exit(0);
308 #endif
311 * Initialize signal handling.
313 init_wine_signals();
316 * Fixup stack and jump to start.
318 WIN_StackSize = wine_files->ne_header->stack_length;
319 WIN_HeapSize = wine_files->ne_header->local_heap_length;
321 ds_reg = (wine_files->
322 selector_table[wine_files->ne_header->auto_data_seg-1].selector);
323 cs_reg = wine_files->selector_table[wine_files->ne_header->cs-1].selector;
324 ip_reg = wine_files->ne_header->ip;
325 ss_reg = wine_files->selector_table[wine_files->ne_header->ss-1].selector;
326 sp_reg = wine_files->ne_header->sp;
328 if (Options.debug) wine_debug(0, NULL);
330 rv = CallToInit16(cs_reg << 16 | ip_reg, ss_reg << 16 | sp_reg, ds_reg);
331 printf ("rv = %x\n", rv);
334 void InitDLL(struct w_files *wpnt)
336 int cs_reg, ds_reg, ip_reg, rv;
338 * Is this a library?
340 if (wpnt->ne_header->format_flags & 0x8000)
342 if (!(wpnt->ne_header->format_flags & 0x0001))
344 /* Not SINGLEDATA */
345 fprintf(stderr, "Library is not marked SINGLEDATA\n");
346 exit(1);
349 ds_reg = wpnt->selector_table[wpnt->
350 ne_header->auto_data_seg-1].selector;
351 cs_reg = wpnt->selector_table[wpnt->ne_header->cs-1].selector;
352 ip_reg = wpnt->ne_header->ip;
354 if (cs_reg) {
355 fprintf(stderr, "Initializing %s, cs:ip %04x:%04x, ds %04x\n",
356 wpnt->name, cs_reg, ip_reg, ds_reg);
358 rv = CallTo16(cs_reg << 16 | ip_reg, ds_reg);
359 printf ("rv = %x\n", rv);
360 } else
361 printf("%s skipped\n", wpnt->name);
365 void InitializeLoadedDLLs(struct w_files *wpnt)
367 static flagReadyToRun = 0;
368 struct w_files *final_wpnt;
370 printf("InitializeLoadedDLLs %08X\n", wpnt);
372 if (wpnt == NULL)
374 flagReadyToRun = 1;
375 fprintf(stderr, "Initializing DLLs\n");
378 if (!flagReadyToRun)
379 return;
381 #if 1
382 if (wpnt != NULL)
383 fprintf(stderr, "Initializing %s\n", wpnt->name);
384 #endif
387 * Initialize libraries
389 if (!wpnt)
391 wpnt = wine_files;
392 final_wpnt = NULL;
394 else
396 final_wpnt = wpnt->next;
399 for( ; wpnt != final_wpnt; wpnt = wpnt->next)
400 InitDLL(wpnt);
402 #else /* #ifndef WINELIB */
403 void InitDLL(struct w_files *wpnt)
407 #endif /* #ifndef WINELIB */