Release 950522
Sun May 21 12:30:30 1995 Alexandre Julliard (julliard@sunsite.unc.edu)
* [debugger/hash.c] [debugger/info.c]
Added support for symbolic segmented addresses. Add symbols for all
built-in API entry points.
* [if1632/relay.c] [include/dlls.h]
Removed dll_table structure, as we now use the built-in module
structures.
* [if1632/relay.c] [loader/main.c]
Removed winestat option, as it was no longer very meaningful.
* [include/stackframe.h]
New macro MAKE_SEGPTR that creates a segmented pointer to a local
variable on the 32-bit stack.
* [loader/module.c]
Added support for multiple instances of an application.
Implemented LoadModule() and FreeModule().
* [loader/ne_image.c] [loader/task.c]
Moved initialisation of built-in DLLs to InitTask().
* [memory/global.c]
Implemented discardable blocks.
* [misc/file.c]
Search path of current executable in OpenFile().
Fixed bug with searching in Windows path.
* [misc/lstr.c]
Hard-coded translation tables for Ansi<->Oem.
* [misc/user.c]
Moved some global initializations to InitApp(), because they need
a task context to be performed.
* [objects/dc.c]
Handle R2_BLACK and R2_WHITE specially so that they work correctly
with palette displays.
* [tools/build.c]
Suppressed generation of the C file for DLL specs, because it's no
longer needed. Output all the assembly code directly to stdout.
Some changes to integrate Win32 support from Martin von Loewis.
* [windows/msgbox.c]
Moved message box code from misc/ to windows/.
Mon May 15 23:40:04 1995 Martin Ayotte (wine@trgcorp.mksinfo.qc.ca)
* [misc/audio.c] [misc/mcicda.c] [misc/mcianim.c] [misc/midi.c]
[misc/mmaux.c] [misc/mmsystem.c]
Modify code & use pointers conversion macros.
Make cdaudio & wave devices work again (only using some applets).
* [misc/profile.c]
Change getc() to fgetc() where needed.
Mon May 15 22:10:56 1995 Martin von Loewis <loewis@informatik.hu-berlin.de>
* [if1632/Imakefile]
added entries for the new files gdi32.spec, kernel32.spec,
user32.spec, shell32.spec and winprocs32.spec.
* [if1632/commdlg.spec][if1632/kernel.spec][if1632/shell.spec]
[if1632/storage.spec][if1632/system.spec][if1632/user.spec]
ChooseFont, RESERVED5, InternalExtractIcon: Marked as stubs
ExtractAssociatedIcon, DoEnvironmentSubst, DumpIcon:
stub implementations provided
marked storage.dll,storege.sys functions as stubs
* [include/pe_image.h]
Added structures WIN32_builtin and WIN32_function
* [include/peexe.h]
PE_Import_Directory: renamed reserved fields to
TimeDate, Forwarder, Thunk_List
* [include/winerror.h]
New file.
* [loader/main.c]
called RELAY32_Init
* [loader/pe_image.c]
xmmap: map BSS anonymous
dump_imports: renamed to fixup_imports, do the fixup of imported
symbols
PE_LoadImage: pass raw data size to xmmap
* [loader/resource.c]
DumpIcon: new function
* [misc/kernel32.c]
New file.
* [misc/main.c]
make stdout and stderr unbuffered
* [misc/shell.c]
DoEnvironmentSubst: new function
* [objects/font.c]
FONT_MatchFont: try oblique if there is no italic
* [rc/Imakefile][rc/parser.l]
yywrap: new function
Don't link with libfl.a on Linux
* [tools/build.c]
Added keywords stdcall, subsystem, base
GenerateForWin32: new function
BuildSpecFiles: call GenerateForWin32 if subsystem is win32
Mon May 15 10:38:14 1995 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
* [controls/listbox.c] [controls/combo.c] [windows/defwnd.c]
Minor fixes.
* [misc/message.c] [misc/main.c] [rc/sysres*.rc] [include/texts.h]
Rewrote message box handling.
* [windows/dialog.c]
Dialogs should be invisible until after WM_INITDIALOG is seent.
Don't switch to invisible dialog items on a TAB keypress.
* [windows/mdi.c]
Send WM_NCPAINT message in MDIRestoreChild().
* [windows/painting.c]
Fixed typo (&& -> &).
* [windows/message.c] [if1632/user.spec]
Implemented PostAppMessage().
* [windows/event.c]
SetCapture(0) should act like ReleaseCapture().
Tue May 9 11:55:52 1995 Eddie C. Dost (ecd@dressler.de)
* [Imakefile]
Changed CDEBUGFLAGS for systems running __ELF__ (temporarily)
Added ASFLAGS to exported variables.
* [debugger/readline/Imakefile]
Moved defines for libreadline from DEFINES to EXTRA_DEFINES
* [memory/local.c] [miscemu/int21.c]
Added some more debugging outputs.
Mon May 8 00:55:27 MET DST 1995 Dag Asheim (dash@ifi.uio.no)
* [misc/message.c]
Fixed a "FIXME" concerning norwegian translation.
Sun May 7 23:25:23 1995 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
* [*/*]
Removed warnings in a couple of files and deleted some obsolete code.
* [controls/listbox.c]
Cleanup, speed improvements & lots of bug fixes.
* [controls/combo.c]
Mostly rewritten. This is still very buggy, but not quite as bad as
before.
* [include/commdlg.h] [misc/commdlg.c]
Removed the need for sysres.dll. Small bug fixes.
* [objects/oembitmap.c] [include/bitmaps/<many>] [include/windows.h]
[loader/library.c] [loader/main.c] [rc/sysres*.rc]
Removed sysres.dll and replaced the remaining bitmaps/icons with
XPM equivalents.
* [misc/message.c] [windows/nonclient.c] [misc/main.c]
[if1632/winprocs.spec]
"About Wine..." now brings up a standard ShellAbout() window with
the Wine icon and the list of contributors.
* [misc/shell.c]
Fixed ShellAbout()/AboutDialogProc() to show the right icon.
* [windows/event.c]
Small hack for non-alphanumeric keys: Dont't send the ascii value in
the WM_KEYDOWN message, but some unused code instead. Should be done
properly by sending different codes for each key. The edit control
used to get a VK_DELETE message each time the user typed '.'.
* [windows/class.c]
Removed a check for CS_GLOBALCLASS in CLASS_FindClassByName().
This used to be no problem, but breaks Resource Workshop in 950403.
* [objects/dib.c]
New diagnostic for a bug I've been encountering. If it shows up,
please report it.
Sun May 7 23:11:18 EDT 1995 William Magro (wmagro@tc.cornell.edu)
* [objects/color.c]
Handle situation when 'dc' exists, but palette mapping
does not. (Fixes kidpix2 demo.)
Sun May 7 03:32:00 1995 Charles M. Hannum (mycroft@mit.edu)
* [loader/ldt.c]
LDT_Print: Only show the number of entries that the kernel
returned. Make this work for NetBSD.
Fri May 5 02:53:26 1995 Charles M. Hannum (mycroft@mit.edu)
* [debugger/dbg.y] [include/wine.h] [loader/signal.c]
Modify cs and ds selector values for NetBSD-current.
* [debugger/debug.l]
$sp, $esp: Use RN_ESP_AT_SIGNAL rather than RN_ESP.
* [debugger/regpos.h]
Modify sigcontext format for NetBSD-current.
SC_ESP: Use RN_ESP_AT_SIGNAL rather than RN_ESP.
* [include/ldt.h]
SELECTOR_TO_ENTRY: Explicitly clear the top half of the selector
value, since only 16 bits of it may have been saved.
* [misc/winsocket.c]
Set structure packing with `#pragma pack' to accomodate
other/older compilers.
Tue May 2 18:15:01 1995 Paal Beyer (beyer@idt.unit.no)
* [misc/commdlg.c]
Fixed path-names so when changing directory the listboxes
changes too.
* [debugger/dbg.y debugger/debug.l wine.ini]
Added SymbolTableFile to wine.ini so symbols can be read
without standing in the directory containing wine.sym.
Added the possibility to specify full name of wine.sym from
the debugger prompt.
diff --git a/loader/Imakefile b/loader/Imakefile
index b3863a6..9c15c28 100644
--- a/loader/Imakefile
+++ b/loader/Imakefile
@@ -13,7 +13,6 @@
pe_resource.c \
selector.c \
signal.c \
- library.c \
resource.c \
task.c
diff --git a/loader/ldt.c b/loader/ldt.c
index 3654f2e..73e1260 100644
--- a/loader/ldt.c
+++ b/loader/ldt.c
@@ -180,12 +180,17 @@
}
#else /* WINELIB */
-#ifdef linux
long buffer[2*LDT_SIZE];
ldt_entry content;
+ int n;
- modify_ldt( 0, buffer, sizeof(buffer) );
- for (i = 0; i < LDT_SIZE; i++)
+#ifdef linux
+ n = modify_ldt( 0, buffer, sizeof(buffer) ) / 8;
+#endif /* linux */
+#if defined(__NetBSD__) || defined(__FreeBSD__)
+ n = i386_get_ldt( 0, (union descriptor *)buffer, LDT_SIZE );
+#endif /* __NetBSD__ || __FreeBSD__ */
+ for (i = 0; i < n; i++)
{
LDT_BytesToEntry( &buffer[2*i], &content );
if (content.base || content.limit)
@@ -197,25 +202,5 @@
content.type );
}
}
-#endif /* linux */
-
-#if defined(__NetBSD__) || defined(__FreeBSD__)
- long buffer[2*LDT_SIZE];
- ldt_entry content;
-
- i386_get_ldt( 0, (union descriptor *)buffer, LDT_SIZE );
- for (i = 0; i < LDT_SIZE; i++)
- {
- LDT_BytesToEntry( buffer[2*i], &content );
- if (content.base || content.limit)
- {
- fprintf( stderr, "%04x: sel=%04x base=%08lx limit=%05lx %s type=%d\n",
- i, ENTRY_TO_SELECTOR(i),
- content.base, content.limit,
- content.limit_in_pages ? "(pages)" : "(bytes)",
- content.type );
- }
- }
-#endif /* __NetBSD__ || __FreeBSD__ */
#endif /* WINELIB */
}
diff --git a/loader/library.c b/loader/library.c
deleted file mode 100644
index e303bbb..0000000
--- a/loader/library.c
+++ /dev/null
@@ -1,351 +0,0 @@
-/*
- * Module & Library functions
-static char Copyright[] = "Copyright 1993, 1994 Martin Ayotte, Robert J. Amstadt, Erik Bos";
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include "neexe.h"
-#include "dlls.h"
-#include "if1632.h"
-#include "wineopts.h"
-#include "arch.h"
-#include "options.h"
-#include "dos_fs.h"
-#include "windows.h"
-#include "task.h"
-#include "toolhelp.h"
-#include "selectors.h"
-#include "prototypes.h"
-#include "library.h"
-#include "ne_image.h"
-#include "pe_image.h"
-#include "module.h"
-#include "stddebug.h"
-#include "debug.h"
-
-struct w_files *wine_files = NULL;
-static char *DLL_Extensions[] = { "dll", NULL };
-static char *EXE_Extensions[] = { "exe", NULL };
-
-#define IS_BUILTIN_DLL(handle) ((handle >> 8) == 0xff)
-
-/**********************************************************************/
-
-void ExtractDLLName(char *libname, char *temp)
-{
- int i;
-
- strcpy(temp, libname);
- if (strchr(temp, '\\') || strchr(temp, '/'))
- for (i = strlen(temp) - 1; i ; i--)
- if (temp[i] == '\\' || temp[i] == '/') {
- strcpy(temp, temp + i + 1);
- break;
- }
- for (i = strlen(temp) - 1; i ; i--)
- if (temp[i] == '.') {
- temp[i] = 0;
- break;
- }
-}
-
-struct w_files *GetFileInfo(unsigned short instance)
-{
- register struct w_files *w = wine_files;
-
- while (w && w->hinstance != instance)
- w = w->next;
-
- return w;
-}
-/*
-int IsDLLLoaded(char *name)
-{
- struct w_files *wpnt;
-
- if(FindDLLTable(name))
- return 1;
-
- for(wpnt = wine_files; wpnt; wpnt = wpnt->next)
- if(strcmp(wpnt->name, name) == 0 )
- return 1;
-
- return 0;
-}
-*/
-void InitDLL(struct w_files *wpnt)
-{
- if (wpnt->ne)
- NE_InitDLL(wpnt->hModule);
- else
- PE_InitDLL(wpnt);
-}
-
-void InitializeLoadedDLLs(struct w_files *wpnt)
-{
- static flagReadyToRun = 0;
- struct w_files *final_wpnt;
-
- dprintf_module(stddeb,"InitializeLoadedDLLs(%p)\n", wpnt);
-
- if (wpnt == NULL)
- {
- flagReadyToRun = 1;
- dprintf_module(stddeb,"Initializing DLLs\n");
- }
-
- if (!flagReadyToRun)
- return;
-
-#if 1
- if (wpnt != NULL)
- dprintf_module(stddeb,"Initializing %s\n", wpnt->name);
-#endif
-
- /*
- * Initialize libraries
- */
- if (!wpnt)
- {
- wpnt = wine_files;
- final_wpnt = NULL;
- }
- else
- {
- final_wpnt = wpnt->next;
- }
-
- for( ; wpnt != final_wpnt; wpnt = wpnt->next)
- InitDLL(wpnt);
-}
-
-/**********************************************************************
- * LoadImage
- * Load one executable into memory
- */
-HINSTANCE LoadImage(char *module, int filetype, int change_dir)
-{
- HINSTANCE handle;
- struct w_files *wpnt, *wpnt1;
- char buffer[256], header[2], modulename[64], *fullname;
-
- ExtractDLLName(module, modulename);
- dprintf_module(stddeb,"LoadImage [%s]\n", module);
- /* built-in one ? */
- if (FindDLLTable(modulename)) {
- return GetModuleHandle(modulename);
- }
-
- /* already loaded ? */
- for (wpnt = wine_files ; wpnt ; wpnt = wpnt->next) {
- if (strcasecmp(wpnt->name, modulename) == 0 && filetype == wpnt->type) {
- return wpnt->hinstance;
- }
- }
-
- /*
- * search file
- */
- fullname = DOS_FindFile(buffer, sizeof(buffer), module,
- (filetype == EXE ? EXE_Extensions : DLL_Extensions),
- WindowsPath);
- if (fullname == NULL)
- {
- fprintf(stderr, "LoadImage: I can't find %s.dll | %s.exe !\n",
- module, module);
- return 2;
- }
-
- fullname = DOS_GetDosFileName(fullname);
-
- dprintf_module(stddeb,"LoadImage: loading %s (%s)\n [%s]\n",
- module, buffer, fullname);
-
- if (change_dir && fullname)
- {
- char dirname[256];
- char *p;
-
- strcpy(dirname, fullname);
- p = strrchr(dirname, '\\');
- *p = '\0';
-
- DOS_SetDefaultDrive(dirname[0] - 'A');
- DOS_ChangeDir(dirname[0] - 'A', dirname + 2);
- }
-
- /* First allocate a spot to store the info we collect, and add it to
- * our linked list if we could load the file.
- */
-
- wpnt = (struct w_files *) malloc(sizeof(struct w_files));
-
- /*
- * Open file for reading.
- */
- wpnt->fd = open(buffer, O_RDONLY);
- if (wpnt->fd < 0)
- return 2;
-
- /*
- * Establish header pointers.
- */
- wpnt->filename = strdup(buffer);
- wpnt->name = strdup(modulename);
- wpnt->type = filetype;
- wpnt->initialised = FALSE;
-
- /* read mz header */
- wpnt->mz_header = (struct mz_header_s *) malloc(sizeof(struct mz_header_s));;
- lseek(wpnt->fd, 0, SEEK_SET);
- if (read(wpnt->fd, wpnt->mz_header, sizeof(struct mz_header_s)) !=
- sizeof(struct mz_header_s))
- {
- fprintf(stderr, "Unable to read MZ header from file '%s'\n", buffer);
- exit(1);
- }
-
- /* This field is ignored according to "Windows Internals", p.242 */
-#if 0
- if (wpnt->mz_header->must_be_0x40 != 0x40)
- myerror("This is not a Windows program");
-#endif
-
- /* read first two bytes to determine filetype */
- lseek(wpnt->fd, wpnt->mz_header->ne_offset, SEEK_SET);
- read(wpnt->fd, &header, sizeof(header));
-
- handle = 0;
-
- /*
- * Stick this file into the list of loaded files so we don't try to reload
- * it again if another module references this module. Do this before
- * calling NE_LoadImage because we might get back here before NE_loadImage
- * returns.
- */
- if(wine_files == NULL)
- wine_files = wpnt;
- else {
- wpnt1 = wine_files;
- while(wpnt1->next)
- wpnt1 = wpnt1->next;
- wpnt1->next = wpnt;
- }
- wpnt->next = NULL;
-
- if (header[0] == 'N' && header[1] == 'E')
- handle = NE_LoadImage(wpnt);
- if (header[0] == 'P' && header[1] == 'E')
- handle = PE_LoadImage(wpnt);
- wpnt->hinstance = handle;
-
- if (handle > 32) {
- return handle;
- } else {
- fprintf(stderr, "wine: (%s) unknown fileformat !\n", wpnt->filename);
-
- /* Remove this module from the list of loaded modules */
- if (wine_files == wpnt)
- wine_files = NULL;
- else
- wpnt1->next = NULL;
- close(wpnt->fd);
- free(wpnt->filename);
- free(wpnt->name);
- free(wpnt);
-
- return 14;
- }
-}
-
-/**********************************************************************
- * LoadLibrary [KERNEL.95]
- */
-HANDLE LoadLibrary(LPSTR libname)
-{
- HANDLE h;
-
- dprintf_module(stddeb,"LoadLibrary: (%08x) %s\n",(int)libname,libname);
-
- if ((h = LoadImage(libname, DLL, 0)) < 32)
- return h;
-
- if (!IS_BUILTIN_DLL(h))
- InitDLL(GetFileInfo(h));
-
- return h;
-}
-
-/**********************************************************************
- * FreeLibrary [KERNEL.96]
- */
-void FreeLibrary(HANDLE hLib)
-{
- dprintf_module(stddeb,"FreeLibrary(%04X);\n", hLib);
-
- /* built-in dll ? */
- if (IS_BUILTIN_DLL(hLib) || hLib == 0 || hLib == hSysRes)
- return;
-
-/*
- while (lpMod != NULL) {
- if (lpMod->hInst == hLib) {
- if (lpMod->Count == 1) {
- wpnt = GetFileInfo(hLib);
- if (wpnt->ne)
- NE_UnloadImage(wpnt);
- else
- PE_UnloadImage(wpnt);
- if (hLib != (HANDLE)NULL) GlobalFree(hLib);
- if (lpMod->ModuleName != NULL) free(lpMod->ModuleName);
- if (lpMod->FileName != NULL) free(lpMod->FileName);
- GlobalFree(lpMod->hModule);
- dprintf_module(stddeb,"FreeLibrary // freed !\n");
- return;
- }
- lpMod->Count--;
- dprintf_module(stddeb,"FreeLibrary // Count decremented !\n");
- return;
- }
- lpMod = lpMod->lpNextModule;
- }
-*/
-}
-
-
-/***********************************************************************
- * GetProcAddress (KERNEL.50)
- */
-FARPROC GetProcAddress( HANDLE hModule, SEGPTR name )
-{
- WORD ordinal;
- SEGPTR ret;
-
- if (!hModule) hModule = GetCurrentTask();
- hModule = GetExePtr( hModule );
-
- if (HIWORD(name) != 0)
- {
- ordinal = MODULE_GetOrdinal( hModule, (LPSTR)PTR_SEG_TO_LIN(name) );
- dprintf_module( stddeb, "GetProcAddress: %04x '%s'\n",
- hModule, (LPSTR)PTR_SEG_TO_LIN(name) );
- }
- else
- {
- ordinal = LOWORD(name);
- dprintf_module( stddeb, "GetProcAddress: %04x %04x\n",
- hModule, ordinal );
- }
- if (!ordinal) return (FARPROC)0;
-
- ret = MODULE_GetEntryPoint( hModule, ordinal );
-
- dprintf_module( stddeb, "GetProcAddress: returning %08lx\n", ret );
- return (FARPROC)ret;
-}
diff --git a/loader/main.c b/loader/main.c
index ce712ae..3ace9d3 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -13,44 +13,23 @@
#include "neexe.h"
#include "dos_fs.h"
#include "dlls.h"
-#include "library.h"
#include "windows.h"
#include "wineopts.h"
#include "wine.h"
#include "task.h"
-#include "prototypes.h"
#include "options.h"
-#include "if1632.h"
-#include "ne_image.h"
#include "pe_image.h"
#include "stddebug.h"
#include "debug.h"
-char **Argv;
-int Argc;
-HINSTANCE hSysRes, hInstMain;
-unsigned short WIN_StackSize;
-
-/**********************************************************************
- * myerror
- */
-void
-myerror(const char *s)
-{
- if (s == NULL)
- perror("wine");
- else
- fprintf(stderr, "wine: %s\n", s);
-
- exit(1);
-}
-
/***********************************************************************
* Main initialisation routine
*/
int MAIN_Init(void)
{
+ extern BOOL RELAY_Init(void);
+
int queueSize;
SpyInit();
@@ -58,6 +37,9 @@
/* Initialize relay code */
if (!RELAY_Init()) return 0;
+ /* Initialize Win32 relay code */
+ if (!RELAY32_Init()) return 0;
+
/* Create built-in modules */
if (!MODULE_Init()) return 0;
@@ -67,6 +49,12 @@
/* Initialize the DOS file system */
DOS_InitFS();
+ /* Create DOS environment */
+ CreateSelectors();
+
+ /* Initialize signal handling */
+ init_wine_signals();
+
/* Initialize communications */
COMM_Init();
@@ -91,19 +79,12 @@
/* Create the DCEs */
DCE_Init();
- /* Initialize built-in window classes */
- if (!WIDGETS_Init()) return 0;
-
/* Initialize dialog manager */
if (!DIALOG_Init()) return 0;
/* Initialize menus */
if (!MENU_Init()) return 0;
- /* Create desktop window */
- if (!WIN_CreateDesktopWindow()) return 0;
- if (!DESKTOP_Init()) return 0;
-
/* Create system message queue */
queueSize = GetProfileInt( "windows", "TypeAhead", 120 );
if (!MSG_CreateSysMsgQueue( queueSize )) return 0;
@@ -118,70 +99,20 @@
*/
int _WinMain(int argc, char **argv)
{
- char *p, filename[256];
int i;
- struct w_files *wpnt;
-#ifdef WINESTAT
- char * cp;
-#endif
-
if (!MAIN_Init()) return 0;
- Argc = argc - 1;
- Argv = argv + 1;
-
- if (strchr(Argv[0], '\\') || strchr(Argv[0],'/')) {
- for (p = Argv[0] + strlen(Argv[0]); *p != '\\' && *p !='/'; p--)
- /* NOTHING */;
-
- strncpy(filename, Argv[0], p - Argv[0]);
- filename[p - Argv[0]] = '\0';
- strcat(WindowsPath, ";");
- if (strchr(filename, '/'))
- strcat(WindowsPath, DOS_GetDosFileName(filename));
- else
- strcat(WindowsPath, filename);
- }
-
- for (i = 0; i < Argc; i++)
+ for (i = 1; i < argc; i++)
+ {
+ if (WinExec( argv[i], SW_SHOWNORMAL ) < 32)
{
- if ((hInstMain = LoadImage(Argv[i], EXE, 1)) < 32) {
- fprintf(stderr, "wine: can't load %s!.\n", Argv[i]);
- exit(1);
- }
+ fprintf(stderr, "wine: can't exec '%s'.\n", argv[i]);
+ exit(1);
}
+ }
- GetPrivateProfileString("wine", "SystemResources", "sysres.dll",
- filename, sizeof(filename), WINE_INI);
-
- hSysRes = LoadImage(filename, DLL, 0);
- if (hSysRes < 32) {
- fprintf(stderr, "wine: can't load %s!.\n", filename);
- exit(1);
- } else
- dprintf_dll(stddeb,"System Resources Loaded // hSysRes='%04X'\n",
- hSysRes);
-
-
-#ifdef WINESTAT
- cp = strrchr(argv[0], '/');
- if(!cp) cp = argv[0];
- else cp++;
- if(strcmp(cp,"winestat") == 0) {
- winestat();
- exit(0);
- };
-#endif
-
- /*
- * Initialize signal handling.
- */
- init_wine_signals();
-
- wpnt = GetFileInfo(hInstMain);
- if (Options.debug)
- wine_debug(0, NULL);
+ if (Options.debug) wine_debug(0, NULL);
Yield(); /* Start the first task */
fprintf( stderr, "WinMain: Should never happen: returned from Yield()\n" );
diff --git a/loader/module.c b/loader/module.c
index 7ea2944..c4af5bf 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -12,20 +12,19 @@
#include <unistd.h>
#include "windows.h"
#include "dlls.h"
+#include "dos_fs.h"
#include "global.h"
#include "ldt.h"
#include "module.h"
#include "neexe.h"
+#include "stackframe.h"
+#include "task.h"
#include "toolhelp.h"
#include "stddebug.h"
/* #define DEBUG_MODULE */
#include "debug.h"
-extern BYTE KERNEL_Module_Start[], KERNEL_Module_End[];
-
-extern struct dll_name_table_entry_s dll_builtin_table[];
-
static HMODULE hFirstModule = 0;
@@ -36,18 +35,20 @@
*/
BOOL MODULE_Init(void)
{
+ extern void load_entrypoints( HMODULE );
+
HMODULE hModule;
NE_MODULE *pModule;
SEGTABLEENTRY *pSegTable;
struct dll_table_s *table;
+ char *dosmem;
int i;
/* Create the built-in modules */
- for (i = 0; i < N_BUILTINS; i++)
+ for (i = 0, table = dll_builtin_table; i < N_BUILTINS; i++, table++)
{
- if (!dll_builtin_table[i].dll_is_used) continue;
- table = dll_builtin_table[i].table;
+ if (!table->used) continue;
hModule = GLOBAL_CreateBlock( GMEM_MOVEABLE, table->module_start,
table->module_end - table->module_start,
@@ -58,7 +59,7 @@
table->hModule = hModule;
dprintf_module( stddeb, "Built-in %s: hmodule=%04x\n",
- dll_builtin_table[i].dll_name, hModule );
+ table->name, hModule );
/* Allocate the code segment */
@@ -81,7 +82,51 @@
pModule->next = hFirstModule;
hFirstModule = hModule;
+ load_entrypoints( hModule );
}
+
+ /* Initialize some KERNEL exported values */
+
+ if (!(hModule = GetModuleHandle( "KERNEL" ))) return TRUE;
+
+ /* KERNEL.178: __WINFLAGS */
+ MODULE_SetEntryPoint( hModule, 178, GetWinFlags() );
+
+ /* Allocate 7 64k segments for 0000, A000, B000, C000, D000, E000, F000. */
+
+ dosmem = malloc( 0x70000 );
+
+ MODULE_SetEntryPoint( hModule, 183, /* KERNEL.183: __0000H */
+ GLOBAL_CreateBlock( GMEM_FIXED, dosmem,
+ 0x10000, hModule, FALSE, FALSE, FALSE ) );
+ MODULE_SetEntryPoint( hModule, 193, /* KERNEL.193: __0040H */
+ GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x400,
+ 0x100, hModule, FALSE, FALSE, FALSE ) );
+ MODULE_SetEntryPoint( hModule, 174, /* KERNEL.174: __A000H */
+ GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x10000,
+ 0x10000, hModule, FALSE, FALSE, FALSE ) );
+ MODULE_SetEntryPoint( hModule, 181, /* KERNEL.181: __B000H */
+ GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x20000,
+ 0x10000, hModule, FALSE, FALSE, FALSE ) );
+ MODULE_SetEntryPoint( hModule, 182, /* KERNEL.182: __B800H */
+ GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x28000,
+ 0x10000, hModule, FALSE, FALSE, FALSE ) );
+ MODULE_SetEntryPoint( hModule, 195, /* KERNEL.195: __C000H */
+ GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x30000,
+ 0x10000, hModule, FALSE, FALSE, FALSE ) );
+ MODULE_SetEntryPoint( hModule, 179, /* KERNEL.179: __D000H */
+ GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x40000,
+ 0x10000, hModule, FALSE, FALSE, FALSE ) );
+ MODULE_SetEntryPoint( hModule, 190, /* KERNEL.190: __E000H */
+ GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x50000,
+ 0x10000, hModule, FALSE, FALSE, FALSE ) );
+ MODULE_SetEntryPoint( hModule, 173, /* KERNEL.173: __ROMBIOS */
+ GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x60000,
+ 0x10000, hModule, FALSE, FALSE, FALSE ) );
+ MODULE_SetEntryPoint( hModule, 194, /* KERNEL.194: __F000H */
+ GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x60000,
+ 0x10000, hModule, FALSE, FALSE, FALSE ) );
+
return TRUE;
}
@@ -237,7 +282,7 @@
close( cachedfd );
hCachedModule = hModule;
name = ((LOADEDFILEINFO*)((char*)pModule + pModule->fileinfo))->filename;
- cachedfd = open( name /* DOS_GetUnixFileName( name ) */, O_RDONLY );
+ cachedfd = open( DOS_GetUnixFileName( name ), O_RDONLY );
dprintf_module( stddeb, "MODULE_OpenFile: opened '%s' -> %d\n",
name, cachedfd );
return cachedfd;
@@ -263,7 +308,9 @@
{
/* FIXME: this is needed because heap growing is not implemented */
pModule->heap_size = 0x10000 - minsize;
+ /* For tasks, the DGROUP is allocated by MODULE_MakeNewInstance */
minsize = 0x10000;
+ if (!(pModule->flags & NE_FFLAGS_LIBMODULE)) continue;
}
pSegment->selector = GLOBAL_Alloc( GMEM_ZEROINIT | GMEM_FIXED,
minsize, hModule,
@@ -282,7 +329,7 @@
/***********************************************************************
* MODULE_LoadExeHeader
*/
-HMODULE MODULE_LoadExeHeader( int fd, char *filename )
+HMODULE MODULE_LoadExeHeader( int fd, OFSTRUCT *ofs )
{
struct mz_header_s mz_header;
struct ne_header_s ne_header;
@@ -316,7 +363,7 @@
size = sizeof(NE_MODULE) +
/* loaded file info */
- sizeof(LOADEDFILEINFO) + strlen(filename) +
+ sizeof(LOADEDFILEINFO) + strlen(ofs->szPathName) +
/* segment table */
ne_header.n_segment_tab * sizeof(SEGTABLEENTRY) +
/* resource table */
@@ -335,6 +382,7 @@
FarSetOwner( hModule, hModule );
pModule = (NE_MODULE *)GlobalLock( hModule );
memcpy( pModule, &ne_header, sizeof(NE_MODULE) );
+ pModule->count = 0;
pData = (BYTE *)(pModule + 1);
/* Read the fast-load area */
@@ -359,12 +407,12 @@
/* Store the filename information */
pModule->fileinfo = (int)pData - (int)pModule;
- ((LOADEDFILEINFO*)pData)->length = sizeof(LOADEDFILEINFO)+strlen(filename);
+ ((LOADEDFILEINFO*)pData)->length = sizeof(LOADEDFILEINFO)+strlen(ofs->szPathName);
((LOADEDFILEINFO*)pData)->fixed_media = TRUE;
((LOADEDFILEINFO*)pData)->error = 0;
((LOADEDFILEINFO*)pData)->date = 0;
((LOADEDFILEINFO*)pData)->time = 0;
- strcpy( ((LOADEDFILEINFO*)pData)->filename, filename );
+ strcpy( ((LOADEDFILEINFO*)pData)->filename, ofs->szPathName );
pData += ((LOADEDFILEINFO*)pData)->length--;
/* Get the segment table */
@@ -451,6 +499,17 @@
}
else pModule->nrname_handle = 0;
+ /* Allocate a segment for the implicitly-loaded DLLs */
+
+ if (pModule->modref_count)
+ {
+ pModule->dlls_to_init = GLOBAL_Alloc(GMEM_ZEROINIT,
+ (pModule->modref_count+1)*sizeof(HMODULE),
+ hModule, FALSE, FALSE, FALSE );
+ if (!pModule->dlls_to_init) return 11; /* invalid exe */
+ }
+ else pModule->dlls_to_init = 0;
+
if (debugging_module) MODULE_PrintModule( hModule );
pModule->next = hFirstModule;
hFirstModule = hModule;
@@ -459,6 +518,62 @@
/***********************************************************************
+ * MODULE_MakeNewInstance
+ *
+ * Create a new instance of the specified module.
+ */
+HINSTANCE MODULE_MakeNewInstance( HMODULE hModule, LOADPARAMS *params )
+{
+ NE_MODULE *pModule;
+ SEGTABLEENTRY *pSegment;
+ HINSTANCE hNewInstance, hPrevInstance;
+ int minsize;
+
+ if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0;
+ if (!pModule->dgroup) return hModule; /* No DGROUP -> return the module */
+
+ pSegment = NE_SEG_TABLE( pModule ) + pModule->dgroup - 1;
+ hPrevInstance = pSegment->selector;
+
+ /* Don't create a new instance if it's a library */
+
+ if (pModule->flags & NE_FFLAGS_LIBMODULE) return hPrevInstance;
+ if (params == (LOADPARAMS*)-1) return hPrevInstance;
+
+ /* Allocate the new data segment */
+
+ minsize = pSegment->minsize ? pSegment->minsize : 0x10000;
+ if (pModule->ss == pModule->dgroup) minsize += pModule->stack_size;
+ minsize += pModule->heap_size;
+ hNewInstance = GLOBAL_Alloc( GMEM_ZEROINIT | GMEM_FIXED,
+ minsize, hModule, FALSE, FALSE, FALSE );
+ if (!hNewInstance) return 0;
+ pSegment->selector = hNewInstance;
+ NE_LoadSegment( hModule, pModule->dgroup );
+
+ /* Create a new task for this instance */
+ if (!TASK_CreateTask( hModule, hNewInstance, hPrevInstance,
+ params->hEnvironment,
+ (LPSTR)PTR_SEG_TO_LIN( params->cmdLine ),
+ *((WORD *)PTR_SEG_TO_LIN(params->showCmd)+1) ))
+ {
+ GlobalFree( hNewInstance );
+ return 0;
+ }
+
+ /* Initialize the local heap */
+
+ if (pModule->heap_size)
+ {
+ WORD heapstart = pSegment->minsize;
+ if (pModule->ss == pModule->dgroup) heapstart += pModule->stack_size;
+ LocalInit( hNewInstance, heapstart, heapstart + pModule->heap_size );
+ }
+ return hNewInstance;
+}
+
+
+/***********************************************************************
* MODULE_GetOrdinal
*
* Lookup the ordinal for a given name.
@@ -538,8 +653,6 @@
if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0;
- dprintf_module( stddeb, "MODULE_GetEntryPoint(%04x,%d)\n",
- hModule, ordinal );
p = (BYTE *)pModule + pModule->entry_table;
while (*p && (curOrdinal + *p <= ordinal))
{
@@ -552,16 +665,11 @@
default: p += 2 + *p * 3; break; /* fixed */
}
}
- if (!*p)
- {
- dprintf_module( stddeb, " Not found (last=%d)\n", curOrdinal-1 );
- return 0;
- }
+ if (!*p) return 0;
switch(p[1])
{
case 0: /* unused */
- dprintf_module( stddeb, " Found, but entry is unused\n" );
return 0;
case 0xff: /* moveable */
p += 2 + 6 * (ordinal - curOrdinal);
@@ -575,8 +683,6 @@
break;
}
- dprintf_module( stddeb, " Found, logical addr = %04x:%04x\n",
- sel, offset );
if (sel == 0xfe) sel = 0xffff; /* constant entry */
else sel = NE_SEG_TABLE(pModule)[sel-1].selector;
return MAKELONG( offset, sel );
@@ -584,6 +690,87 @@
/***********************************************************************
+ * MODULE_SetEntryPoint
+ *
+ * Change the value of an entry point. Use with caution!
+ * It can only change the offset value, not the selector.
+ */
+BOOL MODULE_SetEntryPoint( HMODULE hModule, WORD ordinal, WORD offset )
+{
+ NE_MODULE *pModule;
+ WORD curOrdinal = 1;
+ BYTE *p;
+
+ if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return FALSE;
+
+ p = (BYTE *)pModule + pModule->entry_table;
+ while (*p && (curOrdinal + *p <= ordinal))
+ {
+ /* Skipping this bundle */
+ curOrdinal += *p;
+ switch(p[1])
+ {
+ case 0: p += 2; break; /* unused */
+ case 0xff: p += 2 + *p * 6; break; /* moveable */
+ default: p += 2 + *p * 3; break; /* fixed */
+ }
+ }
+ if (!*p) return FALSE;
+
+ switch(p[1])
+ {
+ case 0: /* unused */
+ return FALSE;
+ case 0xff: /* moveable */
+ p += 2 + 6 * (ordinal - curOrdinal);
+ *(WORD *)(p + 4) = offset;
+ break;
+ default: /* fixed */
+ p += 2 + 3 * (ordinal - curOrdinal);
+ *(WORD *)(p + 1) = offset;
+ break;
+ }
+ return TRUE;
+}
+
+
+/***********************************************************************
+ * MODULE_GetEntryPointName
+ *
+ * Return the entry point name for a given ordinal.
+ * Used only by relay debugging.
+ * Warning: returned pointer is to a Pascal-type string.
+ */
+LPSTR MODULE_GetEntryPointName( HMODULE hModule, WORD ordinal )
+{
+ register char *cpnt;
+ NE_MODULE *pModule;
+
+ if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0;
+
+ /* First search the resident names */
+
+ cpnt = (char *)pModule + pModule->name_table;
+ while (*cpnt)
+ {
+ cpnt += *cpnt + 1 + sizeof(WORD);
+ if (*(WORD *)(cpnt + *cpnt + 1) == ordinal) return cpnt;
+ }
+
+ /* Now search the non-resident names table */
+
+ if (!pModule->nrname_handle) return 0; /* No non-resident table */
+ cpnt = (char *)GlobalLock( pModule->nrname_handle );
+ while (*cpnt)
+ {
+ cpnt += *cpnt + 1 + sizeof(WORD);
+ if (*(WORD *)(cpnt + *cpnt + 1) == ordinal) return cpnt;
+ }
+ return NULL;
+}
+
+
+/***********************************************************************
* MODULE_GetModuleName
*/
LPSTR MODULE_GetModuleName( HMODULE hModule )
@@ -602,10 +789,208 @@
/**********************************************************************
+ * MODULE_FindModule
+ *
+ * Find a module from a path name.
+ */
+HMODULE MODULE_FindModule( LPCSTR path )
+{
+ HMODULE hModule = hFirstModule;
+ LPCSTR filename, dotptr, modulepath, modulename;
+ BYTE len, *name_table;
+
+ if (!(filename = strrchr( path, '\\' ))) filename = path;
+ if ((dotptr = strrchr( filename, '.' )) != NULL)
+ len = (BYTE)(dotptr - filename);
+ else len = strlen( filename );
+
+ while(hModule)
+ {
+ NE_MODULE *pModule = (NE_MODULE *)GlobalLock( hModule );
+ if (!pModule) break;
+ modulepath = ((LOADEDFILEINFO*)((char*)pModule + pModule->fileinfo))->filename;
+ if (!(modulename = strrchr( modulepath, '\\' )))
+ modulename = modulepath;
+ if (!strcasecmp( modulename, filename )) return hModule;
+
+ name_table = (BYTE *)pModule + pModule->name_table;
+ if ((*name_table == len) && !strncasecmp(filename, name_table+1, len))
+ return hModule;
+ hModule = pModule->next;
+ }
+ return 0;
+}
+
+
+/**********************************************************************
+ * MODULE_FreeModule
+ *
+ * Remove a module from memory.
+ */
+static void MODULE_FreeModule( HMODULE hModule )
+{
+ HMODULE *hPrevModule;
+ NE_MODULE *pModule;
+ SEGTABLEENTRY *pSegment;
+ WORD *pModRef;
+ int i;
+
+ if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return;
+
+ /* FIXME: should call the exit code for the library here */
+
+ /* Remove it from the linked list */
+
+ hPrevModule = &hFirstModule;
+ while (*hPrevModule && (*hPrevModule != hModule))
+ {
+ hPrevModule = &((NE_MODULE *)GlobalLock( *hPrevModule ))->next;
+ }
+ if (*hPrevModule) *hPrevModule = pModule->next;
+
+ /* Free all the segments */
+
+ pSegment = NE_SEG_TABLE( pModule );
+ for (i = 1; i <= pModule->seg_count; i++, pSegment++)
+ {
+ GlobalFree( pSegment->selector );
+ }
+
+ /* Free the referenced modules */
+
+ pModRef = NE_MODULE_TABLE( pModule );
+ for (i = 0; i < pModule->modref_count; i++, pModRef++)
+ {
+ FreeModule( *pModRef );
+ }
+
+ /* Free the module storage */
+
+ if (pModule->nrname_handle) GlobalFree( pModule->nrname_handle );
+ if (pModule->dlls_to_init) GlobalFree( pModule->dlls_to_init );
+ GlobalFree( hModule );
+}
+
+
+/**********************************************************************
* LoadModule (KERNEL.45)
*/
-HINSTANCE MODULE_LoadModule( LPCSTR name, LPVOID paramBlock )
+HINSTANCE LoadModule( LPCSTR name, LPVOID paramBlock )
{
+ HMODULE hModule;
+ HANDLE hInstance;
+ NE_MODULE *pModule;
+ WORD *pModRef, *pDLLs;
+ int i, fd;
+
+ hModule = MODULE_FindModule( name );
+ if (!hModule) /* We have to load the module */
+ {
+ OFSTRUCT ofs;
+ if (strchr( name, '/' )) name = DOS_GetDosFileName( name );
+ if ((fd = OpenFile( name, &ofs, OF_READ )) == -1)
+ return 2; /* File not found */
+
+ /* Create the module structure */
+
+ if ((hModule = MODULE_LoadExeHeader( fd, &ofs )) < 32)
+ {
+ close( fd );
+ fprintf( stderr, "LoadModule: can't load '%s', error=%d\n",
+ name, hModule );
+ return hModule;
+ }
+ pModule = (NE_MODULE *)GlobalLock( hModule );
+
+ /* Allocate the segments for this module */
+
+ MODULE_CreateSegments( hModule );
+
+ /* Load the referenced DLLs */
+
+ pModRef = (WORD *)((char *)pModule + pModule->modref_table);
+ pDLLs = (WORD *)GlobalLock( pModule->dlls_to_init );
+ for (i = 0; i < pModule->modref_count; i++, pModRef++)
+ {
+ char buffer[256];
+ BYTE *pstr = (BYTE *)pModule + pModule->import_table + *pModRef;
+ memcpy( buffer, pstr + 1, *pstr );
+ strcpy( buffer + *pstr, ".dll" );
+ dprintf_module( stddeb, "Loading '%s'\n", buffer );
+ if (!(*pModRef = MODULE_FindModule( buffer )))
+ {
+ /* If the DLL is not loaded yet, load it and store */
+ /* its handle in the list of DLLs to initialize. */
+ HMODULE hDLL;
+
+ if ((hDLL = LoadModule( buffer, (LPVOID)-1 )) == 2) /* file not found */
+ {
+ char *p;
+
+ /* Try with prepending the path of the current module */
+ GetModuleFileName( hModule, buffer, 256 );
+ if (!(p = strrchr( buffer, '\\' ))) p = buffer;
+ memcpy( p + 1, pstr + 1, *pstr );
+ strcpy( p + 1 + *pstr, ".dll" );
+ hDLL = LoadModule( buffer, (LPVOID)-1 );
+ }
+ if (hDLL < 32)
+ {
+ fprintf( stderr, "Could not load '%s' required by '%s', error = %d\n",
+ buffer, name, hDLL );
+ return 2; /* file not found */
+ }
+ *pModRef = GetExePtr( hDLL );
+ *pDLLs++ = *pModRef;
+ }
+ else /* Increment the reference count of the DLL */
+ {
+ NE_MODULE *pOldDLL = (NE_MODULE *)GlobalLock( *pModRef );
+ if (pOldDLL) pOldDLL->count++;
+ }
+ }
+
+ /* Load the segments (except the DGROUP) */
+
+ for (i = 1; i <= pModule->seg_count; i++)
+ if (i != pModule->dgroup) NE_LoadSegment( hModule, i );
+
+ /* Create an instance for this module */
+
+ hInstance = MODULE_MakeNewInstance( hModule, (LOADPARAMS*)paramBlock );
+
+ /* Fixup the functions prologs */
+
+ NE_FixupPrologs( hModule );
+
+ /* Make sure the usage count is 1 on the first loading of */
+ /* the module, even if it contains circular DLL references */
+
+ pModule->count = 1;
+ }
+ else
+ {
+ pModule = (NE_MODULE *)GlobalLock( hModule );
+ hInstance = MODULE_MakeNewInstance( hModule, (LOADPARAMS*)paramBlock );
+ pModule->count++;
+ }
+
+ return hInstance;
+}
+
+
+/**********************************************************************
+ * FreeModule (KERNEL.46)
+ */
+BOOL FreeModule( HANDLE hModule )
+{
+ NE_MODULE *pModule;
+
+ hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
+ if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return FALSE;
+
+ if (--pModule->count == 0) MODULE_FreeModule( hModule );
+ return TRUE;
}
@@ -614,21 +999,15 @@
*/
HMODULE GetModuleHandle( LPCSTR name )
{
- char buffer[16];
- BYTE len;
- HMODULE hModule;
+ BYTE len = strlen(name);
+ HMODULE hModule = hFirstModule;
- strncpy( buffer, name, 15 );
- buffer[15] = '\0';
- len = strlen(buffer);
- AnsiUpper( buffer );
-
- hModule = hFirstModule;
while( hModule )
{
NE_MODULE *pModule = (NE_MODULE *)GlobalLock( hModule );
char *pname = (char *)pModule + pModule->name_table;
- if (((BYTE)*pname == len) && !memcmp( pname+1, buffer, len )) break;
+ if (((BYTE)*pname == len) && !strncasecmp( pname+1, name, len ))
+ break;
hModule = pModule->next;
}
dprintf_module( stddeb, "GetModuleHandle('%s'): returning %04x\n",
@@ -669,6 +1048,122 @@
}
+/***********************************************************************
+ * LoadLibrary (KERNEL.95)
+ */
+HANDLE LoadLibrary( LPCSTR libname )
+{
+ HANDLE handle;
+
+ dprintf_module( stddeb, "LoadLibrary: (%08x) %s\n", (int)libname, libname);
+ handle = LoadModule( libname, (LPVOID)-1 );
+ if (handle == 2) /* file not found */
+ {
+ char buffer[256];
+ strcpy( buffer, libname );
+ strcat( buffer, ".dll" );
+ handle = LoadModule( buffer, (LPVOID)-1 );
+ }
+ if (handle >= 32) NE_InitializeDLLs( handle );
+ return handle;
+}
+
+
+/***********************************************************************
+ * FreeLibrary (KERNEL.96)
+ */
+void FreeLibrary( HANDLE handle )
+{
+ dprintf_module( stddeb,"FreeLibrary: %04x\n", handle );
+ FreeModule( handle );
+}
+
+
+/***********************************************************************
+ * WinExec (KERNEL.166)
+ */
+HANDLE WinExec( LPSTR lpCmdLine, WORD nCmdShow )
+{
+ LOADPARAMS params;
+ HLOCAL cmdShowHandle, cmdLineHandle;
+ HANDLE handle;
+ WORD *cmdShowPtr;
+ char *p, *cmdline, filename[256];
+
+ if (!(cmdShowHandle = GlobalAlloc( 0, 2 * sizeof(WORD) ))) return 0;
+ if (!(cmdLineHandle = GlobalAlloc( 0, 256 ))) return 0;
+
+ /* Store nCmdShow */
+
+ cmdShowPtr = (WORD *)GlobalLock( cmdShowHandle );
+ cmdShowPtr[0] = 2;
+ cmdShowPtr[1] = nCmdShow;
+
+ /* Build the filename and command-line */
+
+ cmdline = (char *)GlobalLock( cmdLineHandle );
+ strncpy( filename, lpCmdLine, 256 );
+ filename[255] = '\0';
+ for (p = filename; *p && (*p != ' ') && (*p != '\t'); p++);
+ if (*p)
+ {
+ strncpy( cmdline, p + 1, 128 );
+ cmdline[127] = '\0';
+ }
+ else cmdline[0] = '\0';
+ *p = '\0';
+
+ /* Now load the executable file */
+
+ params.hEnvironment = SELECTOROF( GetDOSEnvironment() );
+ params.cmdLine = WIN16_GlobalLock( cmdLineHandle );
+ params.showCmd = WIN16_GlobalLock( cmdShowHandle );
+ params.reserved = 0;
+ handle = LoadModule( filename, ¶ms );
+ if (handle == 2) /* file not found */
+ {
+ strcat( filename, ".exe" );
+ handle = LoadModule( filename, ¶ms );
+ }
+
+ GlobalFree( cmdShowHandle );
+ GlobalFree( cmdLineHandle );
+ return handle;
+}
+
+
+/***********************************************************************
+ * GetProcAddress (KERNEL.50)
+ */
+FARPROC GetProcAddress( HANDLE hModule, SEGPTR name )
+{
+ WORD ordinal;
+ SEGPTR ret;
+
+ if (!hModule) hModule = GetCurrentTask();
+ hModule = GetExePtr( hModule );
+
+ if (HIWORD(name) != 0)
+ {
+ ordinal = MODULE_GetOrdinal( hModule, (LPSTR)PTR_SEG_TO_LIN(name) );
+ dprintf_module( stddeb, "GetProcAddress: %04x '%s'\n",
+ hModule, (LPSTR)PTR_SEG_TO_LIN(name) );
+ }
+ else
+ {
+ ordinal = LOWORD(name);
+ dprintf_module( stddeb, "GetProcAddress: %04x %04x\n",
+ hModule, ordinal );
+ }
+ if (!ordinal) return (FARPROC)0;
+
+ ret = MODULE_GetEntryPoint( hModule, ordinal );
+
+ dprintf_module( stddeb, "GetProcAddress: returning %08lx\n", ret );
+ return (FARPROC)ret;
+}
+
+
/**********************************************************************
* ModuleFirst (TOOLHELP.59)
*/
diff --git a/loader/ne_image.c b/loader/ne_image.c
index 92e37f5..1a14ef2 100644
--- a/loader/ne_image.c
+++ b/loader/ne_image.c
@@ -18,12 +18,8 @@
#include "dlls.h"
#include "windows.h"
#include "arch.h"
-#include "library.h"
-#include "if1632.h"
#include "selectors.h"
#include "callback.h"
-#include "ne_image.h"
-#include "prototypes.h"
#include "module.h"
#include "stackframe.h"
#include "stddebug.h"
@@ -33,7 +29,7 @@
/***********************************************************************
* NE_LoadSegment
*/
-static BOOL NE_LoadSegment( HMODULE hModule, WORD segnum )
+BOOL NE_LoadSegment( HMODULE hModule, WORD segnum )
{
NE_MODULE *pModule;
SEGTABLEENTRY *pSegTable, *pSeg;
@@ -42,9 +38,9 @@
DWORD address;
int fd;
struct relocation_entry_s *rep, *reloc_entries;
- char *dll_name, *func_name;
+ BYTE *func_name;
- char buffer[100], buffer2[100];
+ char buffer[100];
int ordinal, additive;
unsigned short *sp;
@@ -66,6 +62,12 @@
read( fd, &count, sizeof(count) );
if (!count) return TRUE;
+ dprintf_fixup( stddeb, "Fixups for %*.*s, segment %d, selector %04x\n",
+ *((BYTE *)pModule + pModule->name_table),
+ *((BYTE *)pModule + pModule->name_table),
+ (char *)pModule + pModule->name_table + 1,
+ segnum, pSeg->selector );
+
reloc_entries = (struct relocation_entry_s *)malloc(count * sizeof(struct relocation_entry_s));
if (read( fd, reloc_entries, count * sizeof(struct relocation_entry_s)) !=
count * sizeof(struct relocation_entry_s))
@@ -93,42 +95,62 @@
{
case NE_RELTYPE_ORDINAL:
module = pModuleTable[rep->target1-1];
- dll_name = (char *)pModule + pModule->import_table + module;
- memcpy( buffer, dll_name+1, *dll_name );
- buffer[*dll_name] = '\0';
- dll_name = buffer;
- module = GetModuleHandle( dll_name );
-
ordinal = rep->target2;
address = MODULE_GetEntryPoint( module, ordinal );
- if (!address) fprintf( stderr, "Warning: no handler for %s.%d, setting to 0:0\n",
- dll_name, ordinal );
-
- dprintf_fixup(stddeb,"%d: %s.%d: %04x:%04x\n", i + 1,
- dll_name, ordinal, HIWORD(address), LOWORD(address) );
+ if (!address)
+ {
+ NE_MODULE *pTarget = (NE_MODULE *)GlobalLock( module );
+ if (!pTarget)
+ fprintf( stderr, "Module not found: %04x, reference %d of module %*.*s\n",
+ module, rep->target1,
+ *((BYTE *)pModule + pModule->name_table),
+ *((BYTE *)pModule + pModule->name_table),
+ (char *)pModule + pModule->name_table + 1 );
+ else
+ fprintf( stderr, "Warning: no handler for %*.*s.%d, setting to 0:0\n",
+ *((BYTE *)pTarget + pTarget->name_table),
+ *((BYTE *)pTarget + pTarget->name_table),
+ (char *)pTarget + pTarget->name_table + 1,
+ ordinal );
+ }
+ if (debugging_fixup)
+ {
+ NE_MODULE *pTarget = (NE_MODULE *)GlobalLock( module );
+ fprintf( stddeb,"%d: %*.*s.%d=%04x:%04x\n", i + 1,
+ *((BYTE *)pTarget + pTarget->name_table),
+ *((BYTE *)pTarget + pTarget->name_table),
+ (char *)pTarget + pTarget->name_table + 1,
+ ordinal, HIWORD(address), LOWORD(address) );
+ }
break;
case NE_RELTYPE_NAME:
module = pModuleTable[rep->target1-1];
- dll_name = (char *)pModule + pModule->import_table + module;
- memcpy( buffer, dll_name+1, *dll_name );
- buffer[*dll_name] = '\0';
- dll_name = buffer;
- module = GetModuleHandle( dll_name );
-
func_name = (char *)pModule + pModule->import_table + rep->target2;
- memcpy( buffer2, func_name+1, *func_name );
- buffer2[*func_name] = '\0';
- func_name = buffer2;
+ memcpy( buffer, func_name+1, *func_name );
+ buffer[*func_name] = '\0';
+ func_name = buffer;
ordinal = MODULE_GetOrdinal( module, func_name );
address = MODULE_GetEntryPoint( module, ordinal );
- if (!address) fprintf( stderr, "Warning: no handler for %s.%s, setting to 0:0\n",
- dll_name, func_name );
-
- dprintf_fixup(stddeb,"%d: %s.%s: %04x:%04x\n", i + 1,
- dll_name, func_name, HIWORD(address), LOWORD(address) );
+ if (!address)
+ {
+ NE_MODULE *pTarget = (NE_MODULE *)GlobalLock( module );
+ fprintf( stderr, "Warning: no handler for %*.*s.%s, setting to 0:0\n",
+ *((BYTE *)pTarget + pTarget->name_table),
+ *((BYTE *)pTarget + pTarget->name_table),
+ (char *)pTarget + pTarget->name_table + 1, func_name );
+ }
+ if (debugging_fixup)
+ {
+ NE_MODULE *pTarget = (NE_MODULE *)GlobalLock( module );
+ fprintf( stddeb,"%d: %*.*s.%s=%04x:%04x\n", i + 1,
+ *((BYTE *)pTarget + pTarget->name_table),
+ *((BYTE *)pTarget + pTarget->name_table),
+ (char *)pTarget + pTarget->name_table + 1,
+ func_name, HIWORD(address), LOWORD(address) );
+ }
break;
case NE_RELTYPE_INTERNAL:
@@ -173,17 +195,6 @@
return FALSE;
}
- /* I'm not sure why a DLL entry point fixup could be additive.
- Old code used to ignore additive if the target is a built-in
- DLL. This doesn't seem to work for __AHSHIFT */
-#if 0
- if (additive && FindDLLTable(dll_name) != NULL)
- dprintf_fixup(stddeb,"Additive for builtin???\n"
- "%d: ADDR TYPE %d, TYPE %d, OFFSET %04x, "
- "TARGET %04x %04x\n",
- i+1, rep->address_type, rep->relocation_type,
- rep->offset, rep->target1, rep->target2);
-#endif
offset = rep->offset;
switch (rep->address_type)
@@ -263,7 +274,7 @@
*
* Fixup the exported functions prologs.
*/
-static void NE_FixupPrologs( HMODULE hModule )
+void NE_FixupPrologs( HMODULE hModule )
{
NE_MODULE *pModule;
SEGTABLEENTRY *pSegTable;
@@ -333,15 +344,12 @@
}
-int NE_unloadImage(struct w_files *wpnt)
-{
- dprintf_fixup(stdnimp, "NEunloadImage() called!\n");
- /* free resources, image */
- return 1;
-}
-
-
-BOOL NE_InitDLL( HMODULE hModule )
+/***********************************************************************
+ * NE_InitDLL
+ *
+ * Call the DLL initialization code
+ */
+static BOOL NE_InitDLL( HMODULE hModule )
{
int cs_reg, ds_reg, ip_reg, cx_reg, di_reg, bp_reg;
NE_MODULE *pModule;
@@ -383,7 +391,7 @@
cs_reg = pSegTable[pModule->cs-1].selector;
ip_reg = pModule->ip;
di_reg = ds_reg ? ds_reg : hModule;
- bp_reg = IF1632_Saved16_sp + (&((STACK16FRAME*)1)->bp - 1);
+ bp_reg = IF1632_Saved16_sp + ((WORD)&((STACK16FRAME*)1)->bp - 1);
pModule->cs = 0; /* Don't initialize it twice */
dprintf_dll( stddeb, "Calling LibMain, cs:ip=%04x:%04x ds=%04x di=%04x cx=%04x\n",
@@ -394,92 +402,23 @@
}
-/**********************************************************************
- * NE_LoadImage
- * Load one NE format executable into memory
+/***********************************************************************
+ * NE_InitializeDLLs
+ *
+ * Initialize the loaded DLLs.
*/
-HINSTANCE NE_LoadImage(struct w_files *wpnt)
+void NE_InitializeDLLs( HMODULE hModule )
{
NE_MODULE *pModule;
- SEGTABLEENTRY *pSegTable;
- WORD *pModRef;
- unsigned int read_size, status, segment;
- int i;
- char cmdLine[256];
- extern int Argc;
- extern char **Argv;
+ WORD *pDLL;
- wpnt->ne = malloc(sizeof(struct ne_data));
- wpnt->ne->ne_header = malloc(sizeof(struct ne_header_s));
-
- lseek(wpnt->fd, wpnt->mz_header->ne_offset, SEEK_SET);
- if (read(wpnt->fd, wpnt->ne->ne_header, sizeof(struct ne_header_s))
- != sizeof(struct ne_header_s))
- myerror("Unable to read NE header from file");
-
- wpnt->hModule = MODULE_LoadExeHeader( wpnt->fd, wpnt->filename );
- pModule = (NE_MODULE *)GlobalLock( wpnt->hModule );
- pSegTable = NE_SEG_TABLE(pModule);
-
- /* Create the module segments */
-
- MODULE_CreateSegments( wpnt->hModule );
-#ifndef WINELIB
- /*
- * Create segment selectors.
- */
- CreateSelectors();
-
- if (pModule->dgroup)
- wpnt->hinstance = NE_SEG_TABLE(pModule)[pModule->dgroup-1].selector;
- else
- wpnt->hinstance = wpnt->hModule;
-#endif
-
- /* Create a task for this module */
-
- cmdLine[0] = '\0';
- for (i = 1; i < Argc; i++)
+ pModule = (NE_MODULE *)GlobalLock( hModule );
+ if (!pModule->dlls_to_init) return;
+ for (pDLL = (WORD *)GlobalLock( pModule->dlls_to_init ); *pDLL; pDLL++)
{
- strcat( cmdLine, Argv[i] );
- strcat( cmdLine, " " );
+ NE_InitDLL( *pDLL );
+ NE_InitializeDLLs( *pDLL );
}
- if (!(pModule->flags & NE_FFLAGS_LIBMODULE))
- TASK_CreateTask( wpnt->hModule, SELECTOROF( GetDOSEnvironment() ),
- GetCurrentTask(), cmdLine );
-
- /*
- * Now load any DLLs that this module refers to.
- */
- pModRef = (WORD *)((char *)pModule + pModule->modref_table);
- for (i = 0; i < pModule->modref_count; i++, pModRef++)
- {
- char buffer[80];
- char *pstr = (char *)pModule + pModule->import_table + *pModRef;
- memcpy( buffer, pstr + 1, *pstr );
- buffer[*pstr] = '\0';
- dprintf_module( stddeb, "Loading '%s'\n", buffer );
- LoadImage( buffer, DLL, 0 );
- }
-
- /* fixup references */
-
- for (i = 1; i <= pModule->seg_count; i++)
- NE_LoadSegment( wpnt->hModule, i );
-
- NE_FixupPrologs( wpnt->hModule );
- InitializeLoadedDLLs(wpnt);
-
-
- /* Initialize the local heap */
-
- if (pModule->dgroup)
- {
- int start = pSegTable[pModule->dgroup-1].minsize;
- if (pModule->ss == pModule->dgroup) start += pModule->stack_size;
- LocalInit( pSegTable[pModule->dgroup-1].selector,
- start, start + pModule->heap_size );
- }
-
- return(wpnt->hinstance);
+ GlobalFree( pModule->dlls_to_init );
+ pModule->dlls_to_init = 0;
}
diff --git a/loader/ne_resource.c b/loader/ne_resource.c
index e3e4428..76f30b8 100644
--- a/loader/ne_resource.c
+++ b/loader/ne_resource.c
@@ -204,8 +204,10 @@
pTypeInfo->count * sizeof(NE_NAMEINFO));
}
}
- fprintf( stderr, "FindResource(%04x,%08lx,%08lx): Not found.\n",
- hModule, typeId, resId );
+ fprintf( stderr, "FindResource('%*.*s',%08lx,%08lx): Not found.\n",
+ *((BYTE *)pModule + pModule->name_table),
+ *((BYTE *)pModule + pModule->name_table),
+ (char *)pModule + pModule->name_table + 1, typeId, resId );
return 0;
}
diff --git a/loader/pe_image.c b/loader/pe_image.c
index 9dcad50..ee1b119 100644
--- a/loader/pe_image.c
+++ b/loader/pe_image.c
@@ -21,6 +21,8 @@
#define MAP_ANONYMOUS 0x20
+struct w_files *wine_files = NULL;
+
unsigned int load_addr;
void my_wcstombs(char * result, u_short * source, int len)
@@ -34,10 +36,15 @@
};
}
-char * xmmap(char * vaddr, unsigned int v_size, int prot, int flags,
- int fd, unsigned int file_offset)
+char * xmmap(char * vaddr, unsigned int v_size, unsigned int r_size,
+ int prot, int flags, int fd, unsigned int file_offset)
{
char * result;
+ /* .bss has no associated storage in the PE file */
+ if(r_size)
+ v_size=r_size;
+ else
+ flags |= MAP_ANON;
result = mmap(vaddr, v_size, prot, flags, fd, file_offset);
if((unsigned int) result != 0xffffffff) return result;
@@ -79,9 +86,10 @@
}
}
-void dump_imports(struct PE_Import_Directory *pe_imports)
+void fixup_imports(struct PE_Import_Directory *pe_imports)
{
struct PE_Import_Directory * pe_imp;
+ int fixup_failed=0;
/* OK, now dump the import list */
printf("\nDumping imports list\n");
@@ -90,7 +98,7 @@
{
char * Module;
struct pe_import_name * pe_name;
- unsigned int * import_list;
+ unsigned int * import_list, *thunk_list;
char * c;
Module = ((char *) load_addr) + pe_imp->ModuleName;
@@ -100,15 +108,32 @@
import_list = (unsigned int *)
(((unsigned int) load_addr) + pe_imp->Import_List);
+ thunk_list = (unsigned int *)
+ (((unsigned int) load_addr) + pe_imp->Thunk_List);
+
while(*import_list)
{
pe_name = (struct pe_import_name *) ((int) load_addr + *import_list);
+ if((unsigned)pe_name & 0x80000000)
+ {
+ fprintf(stderr,"Import by ordinal not supported\n");
+ exit(0);
+ }
printf("--- %s %s.%d\n", pe_name->Name, Module, pe_name->Hint);
+ *thunk_list=RELAY32_GetEntryPoint(Module,pe_name->Name,pe_name->Hint);
+ if(!*thunk_list)
+ {
+ fprintf(stderr,"No implementation for %s.%d\n",Module, pe_name->Hint);
+ fixup_failed=1;
+ }
+
import_list++;
+ thunk_list++;
}
pe_imp++;
};
+ if(fixup_failed)exit(1);
}
static void dump_table(struct w_files *wpnt)
@@ -155,19 +180,28 @@
wpnt->pe->pe_header->coff.NumberOfSections);
load_addr = wpnt->pe->pe_header->opt_coff.BaseOfImage;
+ printf("Load addr is %x\n",load_addr);
dump_table(wpnt);
for(i=0; i < wpnt->pe->pe_header->coff.NumberOfSections; i++)
{
if(!load_addr) {
- result = xmmap((char *)0, wpnt->pe->pe_seg[i].Size_Of_Raw_Data, 7,
+ result = xmmap((char *)0, wpnt->pe->pe_seg[i].Virtual_Size,
+ wpnt->pe->pe_seg[i].Size_Of_Raw_Data, 7,
MAP_PRIVATE, wpnt->fd, wpnt->pe->pe_seg[i].PointerToRawData);
load_addr = (unsigned int) result - wpnt->pe->pe_seg[i].Virtual_Address;
} else {
result = xmmap((char *) load_addr + wpnt->pe->pe_seg[i].Virtual_Address,
+ wpnt->pe->pe_seg[i].Virtual_Size,
wpnt->pe->pe_seg[i].Size_Of_Raw_Data, 7, MAP_PRIVATE | MAP_FIXED,
wpnt->fd, wpnt->pe->pe_seg[i].PointerToRawData);
}
+ if(result==-1){
+ fprintf(stderr,"Could not load section %x to desired address %x\n",
+ i, load_addr+wpnt->pe->pe_seg[i].Virtual_Address);
+ fprintf(stderr,"Need to implement relocations now\n");
+ exit(0);
+ }
if(strcmp(wpnt->pe->pe_seg[i].Name, ".idata") == 0)
wpnt->pe->pe_import = (struct PE_Import_Directory *) result;
@@ -184,7 +218,7 @@
}
}
- if(wpnt->pe->pe_import) dump_imports(wpnt->pe->pe_import);
+ if(wpnt->pe->pe_import) fixup_imports(wpnt->pe->pe_import);
if(wpnt->pe->pe_export) dump_exports(wpnt->pe->pe_export);
wpnt->hinstance = 0x8000;
diff --git a/loader/resource.c b/loader/resource.c
index cfc7dbd..adbfc80 100644
--- a/loader/resource.c
+++ b/loader/resource.c
@@ -22,7 +22,6 @@
#include "dlls.h"
#include "module.h"
#include "resource.h"
-#include "library.h"
#include "stddebug.h"
#include "debug.h"
@@ -458,6 +457,17 @@
GlobalFree(hIcon);
return TRUE;
}
+
+/**********************************************************************
+ * DumpIcon [USER.459]
+ */
+DWORD DumpIcon(void* cursorIconInfo, WORD FAR *lpLen, LPSTR FAR *lpXorBits,
+ LPSTR FAR *lpAndMask)
+{
+ dprintf_resource(stdnimp,"DumpIcon: Empty Stub!!!\n");
+ return 0;
+}
+
/**********************************************************************
* LoadAccelerators [USER.177]
diff --git a/loader/selector.c b/loader/selector.c
index f54605a..d04e4f1 100644
--- a/loader/selector.c
+++ b/loader/selector.c
@@ -34,7 +34,6 @@
#include "global.h"
#include "dlls.h"
#include "neexe.h"
-#include "if1632.h"
#include "prototypes.h"
#include "module.h"
#include "stddebug.h"
@@ -49,135 +48,18 @@
extern char WindowsPath[256];
-extern char **Argv;
-extern int Argc;
extern char **environ;
-/**********************************************************************
- * Check whether pseudo-functions like __0040H for direct memory
- * access are referenced and return 1 if so.
- * FIXME: Reading and writing to the returned selectors has no effect
- * (e.g. reading from the Bios data segment (esp. clock!) )
- */
-
-unsigned int GetMemoryReference( char *dll_name, char *function,
- WORD *sel, WORD *offset )
-{
- static HANDLE memory_handles[ 10 ] = { 0,0,0,0,0,0,0,0,0,0 };
- static char *memory_names[ 10 ] = { "segment 0xA000",
- "segment 0xB000",
- "segment 0xB800",
- "Bios-Rom",
- "segment 0xD000",
- "segment 0x0000",
- "segment 0xE000",
- "segment 0xF000",
- "segment 0xC000",
- "Bios data segment" };
- short nr;
-
- if( strcasecmp( dll_name, "KERNEL" ) )
- return 0;
-
- if( HIWORD( function ) ) {
- if( ( *function != '_' ) || ( *(function+1) != '_' ) )
- return 0;
- if( !strcasecmp( function, "__A000H" ) ) nr = 0;
- else if( !strcasecmp( function, "__B000H" ) ) nr = 1;
- else if( !strcasecmp( function, "__B800H" ) ) nr = 2;
- else if( !strcasecmp( function, "__ROMBIOS" ) ) nr = 3;
- else if( !strcasecmp( function, "__D000H" ) ) nr = 4;
- else if( !strcasecmp( function, "__0000H" ) ) nr = 5;
- else if( !strcasecmp( function, "__E000H" ) ) nr = 6;
- else if( !strcasecmp( function, "__F000H" ) ) nr = 7;
- else if( !strcasecmp( function, "__C000H" ) ) nr = 8;
- else if( !strcasecmp( function, "__0040H" ) ) nr = 9;
- else
- return 0;
- }
- else {
- switch( LOWORD( function ) ) {
- case 174: nr = 0; break;
- case 181: nr = 1; break;
- case 182: nr = 2; break;
- case 173: nr = 3; break;
- case 179: nr = 4; break;
- case 183: nr = 5; break;
- case 190: nr = 6; break;
- case 194: nr = 7; break;
- case 195: nr = 8; break;
- case 193: nr = 9; break;
- default: return 0;
- }
- }
-
- if( !memory_handles[ nr ] ) {
- fprintf( stderr, "Warning: Direct access to %s!\n", memory_names[ nr ] );
- memory_handles[ nr ] = GlobalAlloc( GMEM_FIXED, 65535 );
- }
- *sel = *offset = memory_handles[ nr ];
- return 1;
-}
-
-
-
-unsigned int GetEntryDLLName( char * dll_name, char * function,
- WORD* sel, WORD *offset )
-{
- HMODULE hModule;
- struct dll_table_s *dll_table;
- int ordinal, addr;
-
- if( GetMemoryReference( dll_name, function, sel, offset ) )
- return 0;
-
- hModule = GetModuleHandle( dll_name );
- ordinal = MODULE_GetOrdinal( hModule, function );
- if (!ordinal) return 1;
- addr = MODULE_GetEntryPoint( hModule, ordinal );
- if (!addr) return 1;
-#ifdef WINESTAT
- if ((dll_table = FindDLLTable(dll_name)) != NULL)
- {
- dll_table->dll_table[ordinal].used++;
- }
-#endif
- *offset = LOWORD(addr);
- *sel = HIWORD(addr);
- return 0;
-}
-
-
-unsigned int GetEntryDLLOrdinal( char * dll_name, int ordinal,
- WORD *sel, WORD *offset )
-{
- HMODULE hModule;
- struct dll_table_s *dll_table;
- int addr;
-
- if( GetMemoryReference( dll_name, (char*)ordinal, sel, offset ) )
- return 0;
-
- hModule = GetModuleHandle( dll_name );
- addr = MODULE_GetEntryPoint( hModule, ordinal );
- if (!addr) return 1;
-#ifdef WINESTAT
- if ((dll_table = FindDLLTable(dll_name)) != NULL)
- dll_table->dll_table[ordinal].used++;
-#endif
- *offset = LOWORD(addr);
- *sel = HIWORD(addr);
- return 0;
-}
-
WNDPROC GetWndProcEntry16( char *name )
{
- WORD sel, offset;
+ WORD ordinal;
+ static HMODULE hModule = 0;
- GetEntryDLLName( "WINPROCS", name, &sel, &offset );
- return (WNDPROC) MAKELONG( offset, sel );
+ if (!hModule) hModule = GetModuleHandle( "WINPROCS" );
+ ordinal = MODULE_GetOrdinal( hModule, name );
+ return MODULE_GetEntryPoint( hModule, ordinal );
}
diff --git a/loader/signal.c b/loader/signal.c
index c6943de..b395d41 100644
--- a/loader/signal.c
+++ b/loader/signal.c
@@ -114,24 +114,26 @@
if(signal == SIGTRAP) {
scp->sc_eip--;
goto oops;
- };
-
- if((scp->sc_cs & 7) != 7)
- {
+ }
#endif
-#if defined(__NetBSD__) || defined(__FreeBSD__)
+#ifdef __NetBSD__
+/* set_es(0x1f); set_ds(0x1f); */
+ if(signal != SIGBUS && signal != SIGSEGV && signal != SIGTRAP)
+ exit(1);
+#endif
+#ifdef __FreeBSD__
/* set_es(0x27); set_ds(0x27); */
if(signal != SIGBUS && signal != SIGSEGV && signal != SIGTRAP)
exit(1);
- if(scp->sc_cs == 0x1f)
- {
#endif
+ if (scp->sc_cs == WINE_CODE_SELECTOR)
+ {
fprintf(stderr,
"Segmentation fault in Wine program (%x:%lx)."
" Please debug\n",
scp->sc_cs, scp->sc_eip);
goto oops;
- };
+ }
/* Now take a look at the actual instruction where the program
bombed */
diff --git a/loader/task.c b/loader/task.c
index 7f26131..33d53de 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -20,10 +20,12 @@
#include "stddebug.h"
#include "debug.h"
+ /* Min. number of thunks allocated when creating a new segment */
+#define MIN_THUNKS 32
-#define MIN_THUNKS 32 /* Min. thunks allocated when creating a new segment */
-
-#define STACK32_SIZE 0x10000 /* 32-bit stack size for each task */
+ /* 32-bit stack size for each task */
+ /* Must not be greater than 64k, or MAKE_SEGPTR won't work */
+#define STACK32_SIZE 0x10000
static HTASK hFirstTask = 0;
@@ -194,7 +196,6 @@
TDB *pTask = (TDB *)GlobalLock( hCurrentTask );
NE_MODULE *pModule = (NE_MODULE *)GlobalLock( pTask->hModule );
SEGTABLEENTRY *pSegTable = NE_SEG_TABLE( pModule );
- extern unsigned short WIN_StackSize;
/* Registers at initialization must be:
* ax zero
@@ -209,20 +210,17 @@
* sp top of the stack
*/
- WIN_StackSize = pModule->stack_size;
-
cs_reg = pSegTable[pModule->cs - 1].selector;
ip_reg = pModule->ip;
ds_reg = pSegTable[pModule->dgroup - 1].selector;
IF1632_Saved16_ss = pTask->ss;
IF1632_Saved16_sp = pTask->sp;
-/* dprintf_task( stddeb, "Starting main program: cs:ip=%04x:%04x ds=%04x ss:sp=%04x:%04x\n",
+ dprintf_task( stddeb, "Starting main program: cs:ip=%04x:%04x ds=%04x ss:sp=%04x:%04x\n",
cs_reg, ip_reg, ds_reg,
IF1632_Saved16_ss, IF1632_Saved16_sp);
-*/
CallTo16_regs_( (FARPROC)(cs_reg << 16 | ip_reg), ds_reg,
pTask->hPDB /*es*/, 0 /*bp*/, 0 /*ax*/,
- WIN_StackSize /*bx*/, pModule->heap_size /*cx*/,
+ pModule->stack_size /*bx*/, pModule->heap_size /*cx*/,
0 /*dx*/, 0 /*si*/, ds_reg /*di*/ );
/* This should never return */
fprintf( stderr, "TASK_CallToStart: Main program returned!\n" );
@@ -233,8 +231,8 @@
/***********************************************************************
* TASK_CreateTask
*/
-HTASK TASK_CreateTask( HMODULE hModule, HANDLE hEnvironment,
- HTASK hTaskParent, char *cmdLine )
+HTASK TASK_CreateTask( HMODULE hModule, HANDLE hInstance, HANDLE hPrevInstance,
+ HANDLE hEnvironment, char *cmdLine, WORD cmdShow )
{
HTASK hTask;
TDB *pTask;
@@ -258,15 +256,17 @@
/* Fill the task structure */
- pTask->nEvents = 1; /* So the task can be started */
- pTask->hSelf = hTask;
- pTask->flags = 0;
- pTask->version = pModule->expected_version;
- pTask->hInstance = NE_SEG_TABLE(pModule)[pModule->dgroup-1].selector,
- pTask->hModule = hModule;
- pTask->hParent = hTaskParent;
- pTask->curdrive = 'C' - 'A' + 0x80;
- pTask->magic = TDB_MAGIC;
+ pTask->nEvents = 1; /* So the task can be started */
+ pTask->hSelf = hTask;
+ pTask->flags = 0;
+ pTask->version = pModule->expected_version;
+ pTask->hInstance = hInstance;
+ pTask->hPrevInstance = hPrevInstance;
+ pTask->hModule = hModule;
+ pTask->hParent = hCurrentTask;
+ pTask->curdrive = 'C' - 'A' + 0x80;
+ pTask->magic = TDB_MAGIC;
+ pTask->nCmdShow = cmdShow;
strcpy( pTask->curdir, "WINDOWS" );
/* Create the thunks block */
@@ -338,7 +338,7 @@
/* Create the 16-bit stack frame */
- pTask->ss = pSegTable[pModule->ss - 1].selector;
+ pTask->ss = hInstance;
pTask->sp = (pModule->sp != 0) ? pModule->sp :
pSegTable[pModule->ss-1].minsize + pModule->stack_size;
stack16Top = (char *)PTR_SEG_OFF_TO_LIN( pTask->ss, pTask->sp );
@@ -384,6 +384,10 @@
if (!(pTask = (TDB *)GlobalLock( hTask ))) return;
+ /* Free the task module */
+
+ FreeModule( pTask->hModule );
+
/* Free all memory used by this task (including the 32-bit stack, */
/* the environment block and the thunk segments). */
@@ -394,7 +398,9 @@
GLOBAL_FreeBlock( pTask->hCSAlias );
GLOBAL_FreeBlock( pTask->hPDB );
- GlobalFree( hTask ); /* Free the task structure */
+ /* Free the task structure itself */
+
+ GlobalFree( hTask );
}
@@ -501,9 +507,42 @@
/* Switch to the new stack */
hCurrentTask = hTask;
- IF1632_Saved16_ss = pNewTask->ss;
- IF1632_Saved16_sp = pNewTask->sp;
- IF1632_Saved32_esp = pNewTask->esp;
+ IF1632_Saved16_ss = pNewTask->ss;
+ IF1632_Saved16_sp = pNewTask->sp;
+ IF1632_Saved32_esp = pNewTask->esp;
+ IF1632_Stack32_base = WIN16_GlobalLock( pNewTask->hStack32 );
+}
+
+
+/***********************************************************************
+ * InitTask (KERNEL.91)
+ */
+void InitTask( struct sigcontext_struct context )
+{
+ TDB *pTask;
+ NE_MODULE *pModule;
+
+ context.sc_eax = 0;
+ if (!(pTask = (TDB *)GlobalLock( hCurrentTask ))) return;
+ if (!(pModule = (NE_MODULE *)GlobalLock( pTask->hModule ))) return;
+
+ NE_InitializeDLLs( pTask->hModule );
+
+ /* Registers on return are:
+ * ax 1 if OK, 0 on error
+ * cx stack limit in bytes
+ * dx cmdShow parameter
+ * si instance handle of the previous instance
+ * di instance handle of the new task
+ * es:bx pointer to command-line inside PSP
+ */
+ context.sc_eax = 1;
+ context.sc_ebx = 0x81;
+ context.sc_ecx = pModule->stack_size;
+ context.sc_edx = pTask->nCmdShow;
+ context.sc_esi = pTask->hPrevInstance;
+ context.sc_edi = pTask->hInstance;
+ context.sc_es = pTask->hPDB;
}
@@ -650,7 +689,8 @@
else
handle = GlobalHandle( HIWORD(proc) );
- printf( "STUB: GetCodeHandle(%p) returning %04x\n", proc, handle );
+ printf( "STUB: GetCodeHandle(%08lx) returning %04x\n",
+ (DWORD)proc, handle );
return handle;
}