Release 940614
[wine/multimedia.git] / loader / main.c
blob90ec7e516d914c157b38a1e451fd39e4e5737697
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 /**********************************************************************
97 * Load MZ Header
99 void load_mz_header(int fd, struct mz_header_s *mz_header)
101 if (read(fd, mz_header, sizeof(struct mz_header_s)) !=
102 sizeof(struct mz_header_s))
104 myerror("Unable to read MZ header from file");
108 int IsDLLLoaded(char *name)
110 struct w_files *wpnt;
112 if(FindDLLTable(name))
113 return 1;
115 for(wpnt = wine_files; wpnt; wpnt = wpnt->next)
116 if(strcmp(wpnt->name, name) == 0)
117 return 1;
119 return 0;
122 /**********************************************************************
123 * LoadImage
124 * Load one executable into memory
126 HINSTANCE LoadImage(char *module, int filetype, int change_dir)
128 unsigned int read_size;
129 int i;
130 struct w_files * wpnt, *wpnt1;
131 unsigned int status;
132 char buffer[256], header[2], modulename[64], *fullname;
134 ExtractDLLName(module, modulename);
135 printf("%sLoadImage \n", module);
136 /* built-in one ? */
137 if (FindDLLTable(modulename)) {
138 return GetModuleHandle(modulename);
141 /* already loaded ? */
142 for (wpnt = wine_files ; wpnt ; wpnt = wpnt->next)
143 if (strcasecmp(wpnt->name, modulename) == 0)
144 return wpnt->hinstance;
147 * search file
149 fullname = FindFile(buffer, sizeof(buffer), module,
150 (filetype == EXE ? EXE_Extensions : DLL_Extensions),
151 WindowsPath);
152 if (fullname == NULL)
154 fprintf(stderr, "LoadImage: I can't find %s.dll | %s.exe !\n",
155 module, module);
156 return 2;
159 fullname = GetDosFileName(fullname);
160 WIN_ProgramName = strdup(fullname);
162 fprintf(stderr,"LoadImage: loading %s (%s)\n [%s]\n",
163 module, buffer, WIN_ProgramName);
165 if (change_dir && fullname)
167 char dirname[256];
168 char *p;
170 strcpy(dirname, fullname);
171 p = strrchr(dirname, '\\');
172 *p = '\0';
174 DOS_SetDefaultDrive(dirname[0] - 'A');
175 DOS_ChangeDir(dirname[0] - 'A', dirname + 2);
178 /* First allocate a spot to store the info we collect, and add it to
179 * our linked list.
182 wpnt = (struct w_files *) malloc(sizeof(struct w_files));
183 if(wine_files == NULL)
184 wine_files = wpnt;
185 else {
186 wpnt1 = wine_files;
187 while(wpnt1->next) wpnt1 = wpnt1->next;
188 wpnt1->next = wpnt;
190 wpnt->next = NULL;
191 wpnt->resnamtab = (RESNAMTAB *) -1;
194 * Open file for reading.
196 wpnt->fd = open(buffer, O_RDONLY);
197 if (wpnt->fd < 0)
198 return 2;
201 * Establish header pointers.
203 wpnt->filename = strdup(buffer);
204 wpnt->name = strdup(modulename);
206 /* if(module) {
207 wpnt->name = strdup(module);
208 ToDos(wpnt->name);
211 /* read mz header */
212 wpnt->mz_header = (struct mz_header_s *) malloc(sizeof(struct mz_header_s));;
213 status = lseek(wpnt->fd, 0, SEEK_SET);
214 load_mz_header (wpnt->fd, wpnt->mz_header);
215 if (wpnt->mz_header->must_be_0x40 != 0x40 &&
216 wpnt->mz_header->must_be_0x40 != 0x1e)
217 myerror("This is not a Windows program");
219 /* read first two bytes to determine filetype */
220 status = lseek(wpnt->fd, wpnt->mz_header->ne_offset, SEEK_SET);
221 read(wpnt->fd, &header, sizeof(header));
223 if (header[0] == 'N' && header[1] == 'E')
224 return (LoadNEImage(wpnt));
226 if (header[0] == 'P' && header[1] == 'E') {
227 printf("win32 applications are not supported");
228 return 14;
231 fprintf(stderr, "wine: (%s) unknown fileformat !\n", wpnt->filename);
233 return 14;
237 #ifndef WINELIB
238 /**********************************************************************
239 * main
241 int _WinMain(int argc, char **argv)
243 int segment;
244 char *p;
245 char *sysresname;
246 char filename[256];
247 HANDLE hTaskMain;
248 HINSTANCE hInstMain;
249 #ifdef WINESTAT
250 char * cp;
251 #endif
252 struct w_files * wpnt;
253 int cs_reg, ds_reg, ss_reg, ip_reg, sp_reg;
254 int rv;
256 Argc = argc - 1;
257 Argv = argv + 1;
259 if (strchr(Argv[0], '\\') || strchr(Argv[0],'/')) {
260 for (p = Argv[0] + strlen(Argv[0]); *p != '\\' && *p !='/'; p--)
261 /* NOTHING */;
263 strncpy(filename, Argv[0], p - Argv[0]);
264 filename[p - Argv[0]] = '\0';
265 strcat(WindowsPath, ";");
266 strcat(WindowsPath, filename);
269 if ((hInstMain = LoadImage(Argv[0], EXE, 1)) < 32) {
270 fprintf(stderr, "wine: can't load %s!.\n", Argv[0]);
271 exit(1);
273 hTaskMain = CreateNewTask(hInstMain);
274 printf("_WinMain // hTaskMain=%04X hInstMain=%04X !\n", hTaskMain, hInstMain);
276 GetPrivateProfileString("wine", "SystemResources", "sysres.dll",
277 filename, sizeof(filename), WINE_INI);
279 hSysRes = LoadImage(filename, DLL, 0);
280 if (hSysRes < 32) {
281 fprintf(stderr, "wine: can't load %s!.\n", filename);
282 exit(1);
283 } else
284 printf("System Resources Loaded // hSysRes='%04X'\n", hSysRes);
287 * Fixup references.
289 /* wpnt = wine_files;
290 for(wpnt = wine_files; wpnt; wpnt = wpnt->next)
291 for (segment = 0; segment < wpnt->ne_header->n_segment_tab; segment++)
292 if (FixupSegment(wpnt, segment) < 0)
293 myerror("fixup failed.");
296 #ifdef WINESTAT
297 cp = strrchr(argv[0], '/');
298 if(!cp) cp = argv[0];
299 else cp++;
300 if(strcmp(cp,"winestat") == 0) {
301 winestat();
302 exit(0);
304 #endif
307 * Initialize signal handling.
309 init_wine_signals();
312 * Fixup stack and jump to start.
314 WIN_StackSize = wine_files->ne_header->stack_length;
315 WIN_HeapSize = wine_files->ne_header->local_heap_length;
317 ds_reg = (wine_files->
318 selector_table[wine_files->ne_header->auto_data_seg-1].selector);
319 cs_reg = wine_files->selector_table[wine_files->ne_header->cs-1].selector;
320 ip_reg = wine_files->ne_header->ip;
321 ss_reg = wine_files->selector_table[wine_files->ne_header->ss-1].selector;
322 sp_reg = wine_files->ne_header->sp;
324 if (Options.debug) wine_debug(0, NULL);
326 rv = CallToInit16(cs_reg << 16 | ip_reg, ss_reg << 16 | sp_reg, ds_reg);
327 printf ("rv = %x\n", rv);
330 void InitDLL(struct w_files *wpnt)
332 int cs_reg, ds_reg, ip_reg, rv;
334 * Is this a library?
336 if (wpnt->ne_header->format_flags & 0x8000)
338 if (!(wpnt->ne_header->format_flags & 0x0001))
340 /* Not SINGLEDATA */
341 fprintf(stderr, "Library is not marked SINGLEDATA\n");
342 exit(1);
345 ds_reg = wpnt->selector_table[wpnt->
346 ne_header->auto_data_seg-1].selector;
347 cs_reg = wpnt->selector_table[wpnt->ne_header->cs-1].selector;
348 ip_reg = wpnt->ne_header->ip;
350 if (cs_reg) {
351 fprintf(stderr, "Initializing %s, cs:ip %04x:%04x, ds %04x\n",
352 wpnt->name, cs_reg, ip_reg, ds_reg);
354 rv = CallTo16(cs_reg << 16 | ip_reg, ds_reg);
355 printf ("rv = %x\n", rv);
356 } else
357 printf("%s skipped\n");
361 void InitializeLoadedDLLs(struct w_files *wpnt)
363 static flagReadyToRun = 0;
364 struct w_files *final_wpnt;
366 printf("InitializeLoadedDLLs %08X\n", wpnt);
368 if (wpnt == NULL)
370 flagReadyToRun = 1;
371 fprintf(stderr, "Initializing DLLs\n");
374 if (!flagReadyToRun)
375 return;
377 #if 1
378 if (wpnt != NULL)
379 fprintf(stderr, "Initializing %s\n", wpnt->name);
380 #endif
383 * Initialize libraries
385 if (!wpnt)
387 wpnt = wine_files;
388 final_wpnt = NULL;
390 else
392 final_wpnt = wpnt->next;
395 for( ; wpnt != final_wpnt; wpnt = wpnt->next)
396 InitDLL(wpnt);
398 #endif