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, &params );
+    if (handle == 2)  /* file not found */
+    {
+        strcat( filename, ".exe" );
+        handle = LoadModule( filename, &params );
+    }
+
+    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;
 }