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";
13 #include <linux/unistd.h>
14 #include <linux/head.h>
15 #include <linux/ldt.h>
16 #include <linux/segment.h>
20 #include "prototypes.h"
28 /* #define DEBUG_FIXUP */
30 extern HANDLE
CreateNewTask(HINSTANCE hInst
);
31 extern int CallToInit16(unsigned long csip
, unsigned long sssp
,
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
;
50 static char *DLL_Extensions
[] = { "dll", NULL
};
51 static char *EXE_Extensions
[] = { "exe", NULL
};
53 /**********************************************************************
57 myerror(const char *s
)
62 fprintf(stderr
, "wine: %s\n", s
);
67 /**********************************************************************
68 * GetFilenameFromInstance
71 GetFilenameFromInstance(unsigned short instance
)
73 register struct w_files
*w
= wine_files
;
75 while (w
&& w
->hinstance
!= instance
)
85 GetFileInfo(unsigned short instance
)
87 register struct w_files
*w
= wine_files
;
89 while (w
&& w
->hinstance
!= instance
)
95 /**********************************************************************
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
))
115 for(wpnt
= wine_files
; wpnt
; wpnt
= wpnt
->next
)
116 if(strcmp(wpnt
->name
, name
) == 0)
122 /**********************************************************************
124 * Load one executable into memory
126 HINSTANCE
LoadImage(char *module
, int filetype
, int change_dir
)
128 unsigned int read_size
;
130 struct w_files
* wpnt
, *wpnt1
;
132 char buffer
[256], header
[2], modulename
[64], *fullname
;
134 ExtractDLLName(module
, modulename
);
135 printf("%sLoadImage \n", module
);
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
;
149 fullname
= FindFile(buffer
, sizeof(buffer
), module
,
150 (filetype
== EXE
? EXE_Extensions
: DLL_Extensions
),
152 if (fullname
== NULL
)
154 fprintf(stderr
, "LoadImage: I can't find %s.dll | %s.exe !\n",
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
)
170 strcpy(dirname
, fullname
);
171 p
= strrchr(dirname
, '\\');
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
182 wpnt
= (struct w_files
*) malloc(sizeof(struct w_files
));
183 if(wine_files
== NULL
)
187 while(wpnt1
->next
) wpnt1
= wpnt1
->next
;
191 wpnt
->resnamtab
= (RESNAMTAB
*) -1;
194 * Open file for reading.
196 wpnt
->fd
= open(buffer
, O_RDONLY
);
201 * Establish header pointers.
203 wpnt
->filename
= strdup(buffer
);
204 wpnt
->name
= strdup(modulename
);
207 wpnt->name = strdup(module);
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");
231 fprintf(stderr
, "wine: (%s) unknown fileformat !\n", wpnt
->filename
);
238 /**********************************************************************
241 int _WinMain(int argc
, char **argv
)
252 struct w_files
* wpnt
;
253 int cs_reg
, ds_reg
, ss_reg
, ip_reg
, sp_reg
;
259 if (strchr(Argv
[0], '\\') || strchr(Argv
[0],'/')) {
260 for (p
= Argv
[0] + strlen(Argv
[0]); *p
!= '\\' && *p
!='/'; p
--)
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]);
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);
281 fprintf(stderr
, "wine: can't load %s!.\n", filename
);
284 printf("System Resources Loaded // hSysRes='%04X'\n", hSysRes
);
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.");
297 cp
= strrchr(argv
[0], '/');
298 if(!cp
) cp
= argv
[0];
300 if(strcmp(cp
,"winestat") == 0) {
307 * Initialize signal handling.
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
;
336 if (wpnt
->ne_header
->format_flags
& 0x8000)
338 if (!(wpnt
->ne_header
->format_flags
& 0x0001))
341 fprintf(stderr
, "Library is not marked SINGLEDATA\n");
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
;
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
);
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
);
371 fprintf(stderr
, "Initializing DLLs\n");
379 fprintf(stderr
, "Initializing %s\n", wpnt
->name
);
383 * Initialize libraries
392 final_wpnt
= wpnt
->next
;
395 for( ; wpnt
!= final_wpnt
; wpnt
= wpnt
->next
)