Release 960428
Sun Apr 28 14:32:43 1996 Alexandre Julliard <julliard@lrc.epfl.ch>
* [Makefile.in]
Subdir memory is now also compiled for Winelib, in order to get
the Win32 heap functions.
* [if1632/Makefile.in]
Renamed winprocs and winprocs32 to wprocs and wprocs32 to avoid
DLL names > 8 characters.
* [loader/builtin.c] (New file)
Grouped all built-in DLLs code in a single file.
* [memory/global.c]
Use the Win32 heap code instead of malloc() to allocate linear
memory. This will help test the heap code.
* [memory/local.c]
Fixed FreeSelector() to clear DS and ES correctly for huge blocks.
* [tools/build.c] [if1632/relay.c]
Removed 'id' directive in spec files. For relay debugging, the DLL
entry point is now computed from the CS:IP entry point address.
Added 'heap' directive to specifiy a local heap for the DLL. USER
and GDI heap are now created this way.
* [windows/class.c] [include/class.h]
Changed the class structure to use pointers instead of handles.
Changed Get/SetClassWord/Long to use a switch statement; this
allows changing the layout of the CLASS structure.
* [windows/win.c] [include/win.h]
Use a CLASS * instead of a handle for the window class.
Sat Apr 27 18:10:11 Martin von Loewis <loewis@informatik.hu-berlin.de>
* [if1632/kernel32.spec] [memory/global.c]
[win32/memory.c] [win32/process.c]
GetProcessAffinityMask,GlobalLock,IsBadReadPtr,IsBadWritePtr,
LocalLock,SetThreadAffinityMask: new relays.
* [win32/cursoricon32.c]
Return same handle if a cursor is loaded multiple times.
Sat Apr 27 15:13:37 1996 Bang Jun Young <bangjy@nownuri.nowcom.co.kr>
* [resources/sysres_Ko.rc]
Added support for Korean [Ko] language.
Fri Apr 26 00:49:05 1996 Huw D. M. Davies <h.davies1@physics.oxford.ac.uk>
* [objects/dc.c] [objects/font.c]
Fixed problem with SaveDC()/RestoreDC() and font cache 'used' count.
* [objects/metafile.c] [objects/dcvalues.c]
Fixed broken SetTextAlign() on metafiles.
* [objects/metafile.c]
Delete objects in handle table at end of PlayMetaFile().
Wed Apr 24 19:21:01 Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>
* [if1632/ver.spec] [misc/ver.c] [include/ver.h] (New files)
VER.DLL (partially) implemented (VerFindFile,VerInstallFile)
[If it doesn't work for you, use -dll -ver and report it to me]
* [if1632/user32.spec] [if1632/kernel32.spec] [if1632/shell.spec]
[if1632/shell32.spec] [misc/ole2nls.c] [windows/message.c]
[windows/graphics.c]
Simple win32 functions, where we can just use the win16 counterpart.
Misc. stubs.
* [misc/lstr.c]
Someone reported a _lstrlen(NULL). NULL is a valid argument. Fixed.
* [misc/registry.c]
Some alloclens were off by 1, one double fclose() fixed.
Requesting value 0 of a key with no values returns an error
(should we always return a made up value NULL? what does win3.1?)
Tue Apr 23 17:00:00 1996 Alex Korobka <alex@phm30.pharm.sunysb.edu>
* [misc/shell.c]
Implemented FindEnvironmentString(), DoEnvironmentSubst(),
ExtractIcon(), InternalExtractIcon() and ExtractAssociatedIcon().
* [misc/user.c]
Do extensive cleanup on application exit.
* [windows/hook.c] [windows/win.c] [windows/class.c]
Added miscellaneous cleanup routines.
* [controls/menu.c]
More efficient popup menu window handling.
Mon Apr 22 21:35:22 1996 Albrecht Kleine <kleine@ak.sax.de>
* [include/windows.h][objects/oembitmap.c][include/bitmaps/obm_trtype]
Added "TT-bitmap" for later usage in a ChooseFont() ownerdraw combobox.
diff --git a/loader/Makefile.in b/loader/Makefile.in
index 74d6a71..7ae4cf8 100644
--- a/loader/Makefile.in
+++ b/loader/Makefile.in
@@ -2,6 +2,7 @@
MODULE = loader
C_SRCS = \
+ builtin.c \
main.c \
module.c \
ne_image.c \
diff --git a/loader/builtin.c b/loader/builtin.c
new file mode 100644
index 0000000..a2f074d
--- /dev/null
+++ b/loader/builtin.c
@@ -0,0 +1,426 @@
+/*
+ * Built-in modules
+ *
+ * Copyright 1996 Alexandre Julliard
+ */
+
+#ifndef WINELIB
+
+#include <ctype.h>
+#include <string.h>
+#include "windows.h"
+#include "gdi.h"
+#include "global.h"
+#include "module.h"
+#include "neexe.h"
+#include "user.h"
+#include "stddebug.h"
+#include "debug.h"
+
+
+/* Built-in modules descriptors */
+/* Don't change these structures! (see tools/build.c) */
+
+typedef struct
+{
+ const BYTE *code_start; /* 32-bit address of DLL code */
+ const BYTE *data_start; /* 32-bit address of DLL data */
+} WIN16_DESCRIPTOR;
+
+typedef struct
+{
+ int base; /* Ordinal base */
+ int size; /* Number of functions */
+ const void **functions; /* Pointer to functions table */
+ const char * const *names; /* Pointer to names table */
+} WIN32_DESCRIPTOR;
+
+typedef struct
+{
+ const char *name; /* DLL name */
+ void *module_start; /* 32-bit address of the module data */
+ int module_size; /* Size of the module data */
+ union
+ {
+ WIN16_DESCRIPTOR win16; /* Descriptor for Win16 DLL */
+ WIN32_DESCRIPTOR win32; /* Descriptor for Win32 DLL */
+ } u;
+} DLL_DESCRIPTOR;
+
+typedef struct
+{
+ const DLL_DESCRIPTOR *descr; /* DLL descriptor */
+ int flags; /* flags (see below) */
+} BUILTIN_DLL;
+
+
+/* DLL flags */
+#define DLL_FLAG_NOT_USED 0x01 /* Use original Windows DLL if possible */
+#define DLL_FLAG_ALWAYS_USED 0x02 /* Always use built-in DLL */
+#define DLL_FLAG_WIN32 0x04 /* DLL is a Win32 DLL */
+
+
+/* 16-bit DLLs */
+
+extern const DLL_DESCRIPTOR KERNEL_Descriptor;
+extern const DLL_DESCRIPTOR USER_Descriptor;
+extern const DLL_DESCRIPTOR GDI_Descriptor;
+extern const DLL_DESCRIPTOR WIN87EM_Descriptor;
+extern const DLL_DESCRIPTOR MMSYSTEM_Descriptor;
+extern const DLL_DESCRIPTOR SHELL_Descriptor;
+extern const DLL_DESCRIPTOR SOUND_Descriptor;
+extern const DLL_DESCRIPTOR KEYBOARD_Descriptor;
+extern const DLL_DESCRIPTOR WINSOCK_Descriptor;
+extern const DLL_DESCRIPTOR STRESS_Descriptor;
+extern const DLL_DESCRIPTOR SYSTEM_Descriptor;
+extern const DLL_DESCRIPTOR TOOLHELP_Descriptor;
+extern const DLL_DESCRIPTOR MOUSE_Descriptor;
+extern const DLL_DESCRIPTOR COMMDLG_Descriptor;
+extern const DLL_DESCRIPTOR OLE2_Descriptor;
+extern const DLL_DESCRIPTOR OLE2CONV_Descriptor;
+extern const DLL_DESCRIPTOR OLE2DISP_Descriptor;
+extern const DLL_DESCRIPTOR OLE2NLS_Descriptor;
+extern const DLL_DESCRIPTOR OLE2PROX_Descriptor;
+extern const DLL_DESCRIPTOR OLECLI_Descriptor;
+extern const DLL_DESCRIPTOR OLESVR_Descriptor;
+extern const DLL_DESCRIPTOR COMPOBJ_Descriptor;
+extern const DLL_DESCRIPTOR STORAGE_Descriptor;
+extern const DLL_DESCRIPTOR WPROCS_Descriptor;
+extern const DLL_DESCRIPTOR DDEML_Descriptor;
+extern const DLL_DESCRIPTOR LZEXPAND_Descriptor;
+extern const DLL_DESCRIPTOR VER_Descriptor;
+extern const DLL_DESCRIPTOR W32SYS_Descriptor;
+
+/* 32-bit DLLs */
+
+extern const DLL_DESCRIPTOR ADVAPI32_Descriptor;
+extern const DLL_DESCRIPTOR COMCTL32_Descriptor;
+extern const DLL_DESCRIPTOR COMDLG32_Descriptor;
+extern const DLL_DESCRIPTOR OLE32_Descriptor;
+extern const DLL_DESCRIPTOR GDI32_Descriptor;
+extern const DLL_DESCRIPTOR KERNEL32_Descriptor;
+extern const DLL_DESCRIPTOR SHELL32_Descriptor;
+extern const DLL_DESCRIPTOR USER32_Descriptor;
+extern const DLL_DESCRIPTOR WPROCS32_Descriptor;
+extern const DLL_DESCRIPTOR WINSPOOL_Descriptor;
+
+/* Table of all built-in DLLs */
+
+static BUILTIN_DLL BuiltinDLLs[] =
+{
+ /* Win16 DLLs */
+ { &KERNEL_Descriptor, DLL_FLAG_ALWAYS_USED },
+ { &USER_Descriptor, DLL_FLAG_ALWAYS_USED },
+ { &GDI_Descriptor, DLL_FLAG_ALWAYS_USED },
+ { &WIN87EM_Descriptor, DLL_FLAG_NOT_USED },
+ { &SHELL_Descriptor, 0 },
+ { &SOUND_Descriptor, 0 },
+ { &KEYBOARD_Descriptor, 0 },
+ { &WINSOCK_Descriptor, 0 },
+ { &STRESS_Descriptor, 0 },
+ { &MMSYSTEM_Descriptor, 0 },
+ { &SYSTEM_Descriptor, 0 },
+ { &TOOLHELP_Descriptor, 0 },
+ { &MOUSE_Descriptor, 0 },
+ { &COMMDLG_Descriptor, DLL_FLAG_NOT_USED },
+ { &OLE2_Descriptor, DLL_FLAG_NOT_USED },
+ { &OLE2CONV_Descriptor, DLL_FLAG_NOT_USED },
+ { &OLE2DISP_Descriptor, DLL_FLAG_NOT_USED },
+ { &OLE2NLS_Descriptor, DLL_FLAG_NOT_USED },
+ { &OLE2PROX_Descriptor, DLL_FLAG_NOT_USED },
+ { &OLECLI_Descriptor, DLL_FLAG_NOT_USED },
+ { &OLESVR_Descriptor, DLL_FLAG_NOT_USED },
+ { &COMPOBJ_Descriptor, DLL_FLAG_NOT_USED },
+ { &STORAGE_Descriptor, DLL_FLAG_NOT_USED },
+ { &WPROCS_Descriptor, DLL_FLAG_ALWAYS_USED },
+ { &DDEML_Descriptor, DLL_FLAG_NOT_USED },
+ { &LZEXPAND_Descriptor, 0 },
+ { &VER_Descriptor, 0 },
+ { &W32SYS_Descriptor, 0 },
+ /* Win32 DLLs */
+ { &ADVAPI32_Descriptor, 0 },
+ { &COMCTL32_Descriptor, 0 },
+ { &COMDLG32_Descriptor, 0 },
+ { &OLE32_Descriptor, 0 },
+ { &GDI32_Descriptor, 0 },
+ { &KERNEL32_Descriptor, DLL_FLAG_ALWAYS_USED },
+ { &SHELL32_Descriptor, 0 },
+ { &USER32_Descriptor, 0 },
+ { &WPROCS32_Descriptor, DLL_FLAG_ALWAYS_USED },
+ { &WINSPOOL_Descriptor, 0 },
+ /* Last entry */
+ { NULL, 0 }
+};
+
+
+/***********************************************************************
+ * BUILTIN_Init
+ *
+ * Load all built-in modules marked as 'always used'.
+ */
+BOOL BUILTIN_Init(void)
+{
+ BUILTIN_DLL *dll;
+ NE_MODULE *pModule;
+
+ for (dll = BuiltinDLLs; dll->descr; dll++)
+ if (dll->flags & DLL_FLAG_ALWAYS_USED)
+ if (!BUILTIN_LoadModule(dll->descr->name, TRUE)) return FALSE;
+
+ /* Initialize KERNEL.178 (__WINFLAGS) with the correct flags value */
+
+ MODULE_SetEntryPoint( GetModuleHandle( "KERNEL" ), 178, GetWinFlags() );
+
+ /* Set the USER and GDI heap selectors */
+
+ pModule = MODULE_GetPtr( GetModuleHandle( "USER" ));
+ USER_HeapSel = (NE_SEG_TABLE( pModule ) + pModule->dgroup - 1)->selector;
+ pModule = MODULE_GetPtr( GetModuleHandle( "GDI" ));
+ GDI_HeapSel = (NE_SEG_TABLE( pModule ) + pModule->dgroup - 1)->selector;
+
+ return TRUE;
+}
+
+
+/***********************************************************************
+ * BUILTIN_LoadModule
+ *
+ * Load a built-in module. If the 'force' parameter is FALSE, we only
+ * load the module if it has not been disabled via the -dll option.
+ */
+HMODULE BUILTIN_LoadModule( LPCSTR name, BOOL force )
+{
+ HMODULE hModule;
+ NE_MODULE *pModule;
+ BUILTIN_DLL *table;
+ char dllname[16], *p;
+
+ /* Fix the name in case we have a full path and extension */
+
+ if ((p = strrchr( name, '\\' ))) name = p + 1;
+ lstrcpyn( dllname, name, sizeof(dllname) );
+ if ((p = strrchr( dllname, '.' ))) *p = '\0';
+
+ for (table = BuiltinDLLs; table->descr; table++)
+ if (!lstrcmpi( table->descr->name, dllname )) break;
+ if (!table->descr) return 0;
+ if ((table->flags & DLL_FLAG_NOT_USED) && !force) return 0;
+
+ hModule = GLOBAL_CreateBlock( GMEM_MOVEABLE, table->descr->module_start,
+ table->descr->module_size, 0,
+ FALSE, FALSE, FALSE, NULL );
+ if (!hModule) return 0;
+ FarSetOwner( hModule, hModule );
+
+ dprintf_module( stddeb, "Built-in %s: hmodule=%04x\n",
+ table->descr->name, hModule );
+ pModule = (NE_MODULE *)GlobalLock( hModule );
+ pModule->self = hModule;
+
+ if (pModule->flags & NE_FFLAGS_WIN32)
+ {
+ pModule->pe_module = (PE_MODULE *)table;
+ }
+ else /* Win16 module */
+ {
+ const WIN16_DESCRIPTOR *descr = &table->descr->u.win16;
+ int minsize;
+
+ /* Allocate the code segment */
+
+ SEGTABLEENTRY *pSegTable = NE_SEG_TABLE( pModule );
+ pSegTable->selector = GLOBAL_CreateBlock(GMEM_FIXED, descr->code_start,
+ pSegTable->minsize, hModule,
+ TRUE, TRUE, FALSE, NULL );
+ if (!pSegTable->selector) return 0;
+ pSegTable++;
+
+ /* Allocate the data segment */
+
+ minsize = pSegTable->minsize ? pSegTable->minsize : 0x10000;
+ minsize += pModule->heap_size;
+ if (minsize > 0x10000) minsize = 0x10000;
+ pSegTable->selector = GLOBAL_Alloc( GMEM_FIXED, minsize,
+ hModule, FALSE, FALSE, FALSE );
+ if (!pSegTable->selector) return 0;
+ if (pSegTable->minsize) memcpy( GlobalLock( pSegTable->selector ),
+ descr->data_start, pSegTable->minsize);
+ if (pModule->heap_size)
+ LocalInit( pSegTable->selector, pSegTable->minsize, minsize );
+ }
+
+ MODULE_RegisterModule( pModule );
+ return hModule;
+}
+
+
+/***********************************************************************
+ * BUILTIN_GetEntryPoint
+ *
+ * Return the built-in module, ordinal and name corresponding
+ * to a CS:IP address. This is used only by relay debugging.
+ */
+NE_MODULE *BUILTIN_GetEntryPoint( WORD cs, WORD ip, WORD *pOrd, char **ppName )
+{
+ WORD ordinal, i, max_offset;
+ register BYTE *p;
+ NE_MODULE *pModule;
+
+ if (!(pModule = MODULE_GetPtr( FarGetOwner( GlobalHandle(cs) ))))
+ return NULL;
+
+ /* Search for the ordinal */
+
+ p = (BYTE *)pModule + pModule->entry_table;
+ max_offset = 0;
+ ordinal = 1;
+ *pOrd = 0;
+ while (*p)
+ {
+ switch(p[1])
+ {
+ case 0: /* unused */
+ ordinal += *p;
+ p += 2;
+ break;
+ case 1: /* code segment */
+ i = *p;
+ p += 2;
+ while (i-- > 0)
+ {
+ p++;
+ if ((*(WORD *)p <= ip) && (*(WORD *)p >= max_offset))
+ {
+ max_offset = *(WORD *)p;
+ *pOrd = ordinal;
+ }
+ p += 2;
+ ordinal++;
+ }
+ break;
+ case 0xff: /* moveable (should not happen in built-in modules) */
+ fprintf( stderr, "Built-in module has moveable entry\n" );
+ ordinal += *p;
+ p += 2 + *p * 6;
+ break;
+ default: /* other segment */
+ ordinal += *p;
+ p += 2 + *p * 3;
+ break;
+ }
+ }
+
+ /* Search for the name in the resident names table */
+ /* (built-in modules have no non-resident table) */
+
+ p = (BYTE *)pModule + pModule->name_table;
+ *ppName = "???";
+ while (*p)
+ {
+ p += *p + 1 + sizeof(WORD);
+ if (*(WORD *)(p + *p + 1) == *pOrd)
+ {
+ *ppName = (char *)p;
+ break;
+ }
+ }
+
+ return pModule;
+}
+
+
+/***********************************************************************
+ * BUILTIN_GetProcAddress32
+ *
+ * Implementation of GetProcAddress() for built-in Win32 modules.
+ * FIXME: this should be unified with the real GetProcAddress32().
+ */
+DWORD BUILTIN_GetProcAddress32( NE_MODULE *pModule, char *function )
+{
+ BUILTIN_DLL *dll = (BUILTIN_DLL *)pModule->pe_module;
+ const WIN32_DESCRIPTOR *info = &dll->descr->u.win32;
+
+ if (!dll) return 0;
+
+ if (HIWORD(function)) /* Find function by name */
+ {
+ int i;
+
+ dprintf_module( stddeb, "Looking for function %s in %s\n",
+ function, dll->descr->name );
+ for (i = 0; i < info->size; i++)
+ if (info->names[i] && !strcmp( function, info->names[i] ))
+ return (DWORD)info->functions[i];
+ }
+ else /* Find function by ordinal */
+ {
+ WORD ordinal = LOWORD(function);
+ dprintf_module( stddeb, "Looking for ordinal %d in %s\n",
+ ordinal, dll->descr->name );
+ if (ordinal && ordinal < info->size)
+ return (DWORD)info->functions[ordinal - info->base];
+ }
+ return 0;
+}
+
+
+/***********************************************************************
+ * BUILTIN_ParseDLLOptions
+ *
+ * Set runtime DLL usage flags
+ */
+BOOL BUILTIN_ParseDLLOptions( const char *str )
+{
+ BUILTIN_DLL *dll;
+ const char *p;
+
+ while (*str)
+ {
+ while (*str && isspace(*str)) str++;
+ if (!*str) return TRUE;
+ if ((*str != '+') && (*str != '-')) return FALSE;
+ str++;
+ if (!(p = strchr( str, ',' ))) p = str + strlen(str);
+ while ((p > str) && isspace(p[-1])) p--;
+ if (p == str) return FALSE;
+ for (dll = BuiltinDLLs; dll->descr; dll++)
+ {
+ if (!lstrncmpi( str, dll->descr->name, (int)(p - str) ))
+ {
+ if (str[-1] == '-')
+ {
+ if (dll->flags & DLL_FLAG_ALWAYS_USED) return FALSE;
+ dll->flags |= DLL_FLAG_NOT_USED;
+ }
+ else dll->flags &= ~DLL_FLAG_NOT_USED;
+ break;
+ }
+ }
+ if (!dll->descr) return FALSE;
+ str = p;
+ }
+ return TRUE;
+}
+
+
+/***********************************************************************
+ * BUILTIN_PrintDLLs
+ *
+ * Print the list of built-in DLLs that can be disabled.
+ */
+void BUILTIN_PrintDLLs(void)
+{
+ int i;
+ BUILTIN_DLL *dll;
+
+ for (i = 0, dll = BuiltinDLLs; dll->descr; dll++)
+ {
+ if (!(dll->flags & DLL_FLAG_ALWAYS_USED))
+ fprintf( stderr, "%-9s%c", dll->descr->name,
+ ((++i) % 8) ? ' ' : '\n' );
+ }
+ fprintf(stderr,"\n");
+ exit(1);
+}
+
+#endif /* WINELIB */
diff --git a/loader/main.c b/loader/main.c
index b06e261..334ec82 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -16,7 +16,6 @@
#include "task.h"
#include "selectors.h"
#include "comm.h"
-#include "user.h"
#include "win.h"
#include "menu.h"
#include "kernel32.h"
@@ -28,8 +27,8 @@
#include "syscolor.h"
#include "sysmetrics.h"
#include "gdi.h"
+#include "heap.h"
#include "debugger.h"
-#include "dlls.h"
#include "miscemu.h"
#include "neexe.h"
#include "options.h"
@@ -42,6 +41,7 @@
void init_wine_signals(void);
+HANDLE32 SystemHeap = 0;
/***********************************************************************
* Main initialisation routine
@@ -52,6 +52,9 @@
int queueSize;
+ /* Create the system heap */
+ if (!(SystemHeap = HeapCreate( HEAP_GROWABLE, 0x10000, 0 ))) return 0;
+
/* Load the configuration file */
if (!PROFILE_LoadWineIni()) return 0;
@@ -61,10 +64,10 @@
#ifndef WINELIB
/* Initialize relay code */
if (!RELAY_Init()) return 0;
-#endif
/* Create built-in modules */
- if (!MODULE_Init()) return 0;
+ if (!BUILTIN_Init()) return 0;
+#endif
/* Initialise DOS drives */
if (!DRIVE_Init()) return 0;
@@ -90,9 +93,6 @@
/* Initialize the DOS memory */
if (!INT21_Init()) return 0;
-
- /* Create USER heap */
- if (!USER_HeapInit()) return 0;
#endif
/* Global atom table initialisation */
diff --git a/loader/module.c b/loader/module.c
index 128c05a..a3f4615 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -11,10 +11,11 @@
#include <sys/types.h>
#include <unistd.h>
#include "windows.h"
-#include "dlls.h"
+#include "class.h"
#include "dos_fs.h"
#include "file.h"
#include "global.h"
+#include "hook.h"
#include "ldt.h"
#include "module.h"
#include "neexe.h"
@@ -35,96 +36,6 @@
#ifndef WINELIB
static HANDLE hInitialStack32 = 0;
#endif
-/***********************************************************************
- * MODULE_LoadBuiltin
- *
- * Load a built-in module. If the 'force' parameter is FALSE, we only
- * load the module if it has not been disabled via the -dll option.
- */
-#ifndef WINELIB
-static HMODULE MODULE_LoadBuiltin( LPCSTR name, BOOL force )
-{
- HMODULE hModule;
- NE_MODULE *pModule;
- SEGTABLEENTRY *pSegTable;
- BUILTIN_DLL *table;
- char dllname[16], *p;
-
- /* Fix the name in case we have a full path and extension */
-
- if ((p = strrchr( name, '\\' ))) name = p + 1;
- lstrcpyn( dllname, name, sizeof(dllname) );
- if ((p = strrchr( dllname, '.' ))) *p = '\0';
-
- for (table = dll_builtin_table; table->name; table++)
- if (!lstrcmpi( table->name, dllname )) break;
- if (!table->name) return 0;
- if ((table->flags & DLL_FLAG_NOT_USED) && !force) return 0;
-
- hModule = GLOBAL_CreateBlock( GMEM_MOVEABLE, table->module_start,
- table->module_end - table->module_start,
- 0, FALSE, FALSE, FALSE, NULL );
- if (!hModule) return 0;
- FarSetOwner( hModule, hModule );
-
- table->hModule = hModule;
-
- dprintf_module( stddeb, "Built-in %s: hmodule=%04x\n",
- table->name, hModule );
- pModule = (NE_MODULE *)GlobalLock( hModule );
- pModule->self = hModule;
-
- if (pModule->flags & NE_FFLAGS_WIN32)
- {
- pModule->pe_module = (PE_MODULE *)table;
- }
- else /* Win16 module */
- {
- /* Allocate the code segment */
-
- pSegTable = NE_SEG_TABLE( pModule );
- pSegTable->selector = GLOBAL_CreateBlock(GMEM_FIXED, table->code_start,
- pSegTable->minsize, hModule,
- TRUE, TRUE, FALSE, NULL );
- if (!pSegTable->selector) return 0;
- pSegTable++;
-
- /* Allocate the data segment */
-
- pSegTable->selector = GLOBAL_Alloc( GMEM_FIXED, pSegTable->minsize,
- hModule, FALSE, FALSE, FALSE );
- if (!pSegTable->selector) return 0;
- memcpy( GlobalLock( pSegTable->selector ),
- table->data_start, pSegTable->minsize );
- }
-
- pModule->next = hFirstModule;
- hFirstModule = hModule;
- return hModule;
-}
-#endif
-
-/***********************************************************************
- * MODULE_Init
- *
- * Create the built-in modules.
- */
-BOOL MODULE_Init(void)
-{
-#ifndef WINELIB32
- BUILTIN_DLL *dll;
-
- /* Load all modules marked as always used */
-
- for (dll = dll_builtin_table; dll->name; dll++)
- if (dll->flags & DLL_FLAG_ALWAYS_USED)
- if (!MODULE_LoadBuiltin(dll->name, TRUE)) return FALSE;
-#endif
- /* Initialize KERNEL.178 (__WINFLAGS) with the correct flags value */
-
- MODULE_SetEntryPoint( GetModuleHandle( "KERNEL" ), 178, GetWinFlags() );
- return TRUE;
-}
/***********************************************************************
@@ -358,7 +269,7 @@
}
/***********************************************************************
- * MODULE_AllocateSegment (WINPROCS.26)
+ * MODULE_AllocateSegment (WPROCS.26)
*/
DWORD MODULE_AllocateSegment(WORD wFlags, WORD wSize, WORD wElem)
@@ -410,7 +321,7 @@
* MODULE_GetInstance
*/
#ifndef WINELIB32
-static HINSTANCE MODULE_GetInstance( HMODULE hModule )
+HINSTANCE MODULE_GetInstance( HMODULE hModule )
{
SEGTABLEENTRY *pSegment;
NE_MODULE *pModule;
@@ -462,7 +373,7 @@
/***********************************************************************
* MODULE_LoadExeHeader
*/
-HMODULE MODULE_LoadExeHeader( HFILE hFile, OFSTRUCT *ofs )
+static HMODULE MODULE_LoadExeHeader( HFILE hFile, OFSTRUCT *ofs )
{
struct mz_header_s mz_header;
struct ne_header_s ne_header;
@@ -677,8 +588,7 @@
}
else pModule->dlls_to_init = 0;
- pModule->next = hFirstModule;
- hFirstModule = hModule;
+ MODULE_RegisterModule( pModule );
return hModule;
#undef READ
}
@@ -844,45 +754,9 @@
/***********************************************************************
- * 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 = MODULE_GetPtr( 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_GetWndProcEntry16 (not a Windows API function)
*
- * Return an entry point from the WINPROCS dll.
+ * Return an entry point from the WPROCS dll.
*/
#ifndef WINELIB
WNDPROC MODULE_GetWndProcEntry16( const char *name )
@@ -890,7 +764,7 @@
WORD ordinal;
static HMODULE hModule = 0;
- if (!hModule) hModule = GetModuleHandle( "WINPROCS" );
+ if (!hModule) hModule = GetModuleHandle( "WPROCS" );
ordinal = MODULE_GetOrdinal( hModule, name );
return MODULE_GetEntryPoint( hModule, ordinal );
}
@@ -900,14 +774,14 @@
/***********************************************************************
* MODULE_GetWndProcEntry32 (not a Windows API function)
*
- * Return an entry point from the WINPROCS32 dll.
+ * Return an entry point from the WPROCS32 dll.
*/
#ifndef WINELIB
WNDPROC MODULE_GetWndProcEntry32( const char *name )
{
static HMODULE hModule = 0;
- if (!hModule) hModule = GetModuleHandle( "WINPROCS32" );
+ if (!hModule) hModule = GetModuleHandle( "WPROCS32" );
return PE_GetProcAddress( hModule, name );
}
#endif
@@ -934,13 +808,13 @@
/**********************************************************************
* MODULE_RegisterModule
*/
-void MODULE_RegisterModule( HMODULE hModule )
+void MODULE_RegisterModule( NE_MODULE *pModule )
{
- NE_MODULE *pModule = MODULE_GetPtr( hModule );
pModule->next = hFirstModule;
- hFirstModule = hModule;
+ hFirstModule = pModule->self;
}
+
/**********************************************************************
* MODULE_FindModule
*
@@ -996,6 +870,11 @@
/* FIXME: should call the exit code for the library here */
+ /* Free the objects owned by the module */
+
+ HOOK_FreeModuleHooks( hModule );
+ CLASS_FreeModuleClasses( hModule );
+
/* Clear magic number just in case */
pModule->magic = pModule->self = 0;
@@ -1058,12 +937,12 @@
OFSTRUCT ofs;
/* Try to load the built-in first if not disabled */
- if ((hModule = MODULE_LoadBuiltin( name, FALSE ))) return hModule;
+ if ((hModule = BUILTIN_LoadModule( name, FALSE ))) return hModule;
if ((hFile = OpenFile( name, &ofs, OF_READ )) == HFILE_ERROR)
{
/* Now try the built-in even if disabled */
- if ((hModule = MODULE_LoadBuiltin( name, TRUE )))
+ if ((hModule = BUILTIN_LoadModule( name, TRUE )))
{
fprintf( stderr, "Warning: could not load Windows DLL '%s', using built-in module.\n", name );
return hModule;
@@ -1148,7 +1027,7 @@
/* Handle self loading modules */
SEGTABLEENTRY * pSegTable = (SEGTABLEENTRY *) NE_SEG_TABLE(pModule);
SELFLOADHEADER *selfloadheader;
- HMODULE hselfload = GetModuleHandle("WINPROCS");
+ HMODULE hselfload = GetModuleHandle("WPROCS");
WORD oldss, oldsp, saved_dgroup = pSegTable[pModule->dgroup - 1].selector;
fprintf (stderr, "Warning: %*.*s is a self-loading module\n"
"Support for self-loading modules is very experimental\n",
diff --git a/loader/ne_image.c b/loader/ne_image.c
index 2fcd8f9..447b500 100644
--- a/loader/ne_image.c
+++ b/loader/ne_image.c
@@ -16,7 +16,6 @@
#include <string.h>
#include <errno.h>
#include "neexe.h"
-#include "dlls.h"
#include "windows.h"
#include "arch.h"
#include "selectors.h"
diff --git a/loader/ne_resource.c b/loader/ne_resource.c
index 7e45089..caee5f8 100644
--- a/loader/ne_resource.c
+++ b/loader/ne_resource.c
@@ -23,9 +23,6 @@
#include "stddebug.h"
#include "debug.h"
-typedef struct resource_typeinfo_s NE_TYPEINFO;
-typedef struct resource_nameinfo_s NE_NAMEINFO;
-
/***********************************************************************
* NE_FindNameTableId
diff --git a/loader/pe_image.c b/loader/pe_image.c
index 79789b7..d16417a 100644
--- a/loader/pe_image.c
+++ b/loader/pe_image.c
@@ -18,8 +18,8 @@
#include <sys/types.h>
#include <sys/mman.h>
#include "windows.h"
+#include "winbase.h"
#include "callback.h"
-#include "dlls.h"
#include "neexe.h"
#include "peexe.h"
#include "pe_image.h"
@@ -140,16 +140,9 @@
NE_MODULE *pModule;
if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
- if (!(pModule->flags & NE_FFLAGS_WIN32)) return 0;
+ if (!(pModule->flags & NE_FFLAGS_WIN32) || !pModule->pe_module) return 0;
if (pModule->flags & NE_FFLAGS_BUILTIN)
- {
- BUILTIN_DLL *dll = (BUILTIN_DLL *)pModule->pe_module;
- if(HIWORD(function))
- return RELAY32_GetEntryPoint(dll,function,0);
- else
- return RELAY32_GetEntryPoint(dll,0,(int)function);
- }
- if (!pModule->pe_module) return 0;
+ return BUILTIN_GetProcAddress32( pModule, function );
return PE_FindExportedFunction( pModule->pe_module, function );
}
@@ -247,12 +240,8 @@
dprintf_win32(stddeb, "--- %s %s.%d\n", pe_name->Name, Module, pe_name->Hint);
#ifndef WINELIB /* FIXME: JBP: Should this happen in libwine.a? */
/* FIXME: Both calls should be unified into GetProcAddress */
-#if 0
- *thunk_list=(unsigned int)RELAY32_GetEntryPoint(Module,pe_name->Name,pe_name->Hint);
- if(*thunk_list == 0)
-#endif
- *thunk_list = WIN32_GetProcAddress(MODULE_FindModule(Module),
- pe_name->Name);
+ *thunk_list = WIN32_GetProcAddress(MODULE_FindModule(Module),
+ pe_name->Name);
#else
fprintf(stderr,"JBP: Call to RELAY32_GetEntryPoint being ignored.\n");
#endif
@@ -619,7 +608,7 @@
pModule->res_table=pModule->import_table=pModule->entry_table=
(int)pStr-(int)pModule;
- MODULE_RegisterModule(hModule);
+ MODULE_RegisterModule( pModule );
pe = PE_LoadImage( fd, hModule, mz_header.ne_offset );
@@ -656,7 +645,6 @@
int fs;
HMODULE hModule;
NE_MODULE *pModule;
- struct pe_data *pe;
dprintf_win32(stddeb,"Going to start Win32 program\n");
InitTask(context);
diff --git a/loader/pe_resource.c b/loader/pe_resource.c
index b0d6203..da19a65 100644
--- a/loader/pe_resource.c
+++ b/loader/pe_resource.c
@@ -18,7 +18,6 @@
#include "ldt.h"
#include "neexe.h"
#include "peexe.h"
-#include "dlls.h"
#include "pe_image.h"
#include "resource.h"
#include "stddebug.h"
diff --git a/loader/resource.c b/loader/resource.c
index b6a4549..5c5ec93 100644
--- a/loader/resource.c
+++ b/loader/resource.c
@@ -18,7 +18,6 @@
#include "global.h"
#include "neexe.h"
#include "accel.h"
-#include "dlls.h"
#include "module.h"
#include "resource.h"
#include "stddebug.h"
diff --git a/loader/task.c b/loader/task.c
index 7ddac31..bab6794 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -34,8 +34,7 @@
#define STACK32_SIZE 0x10000
extern void TIMER_SwitchQueue(HQUEUE, HQUEUE );
-extern void TIMER_NukeTimers(HWND, HQUEUE );
-
+extern void USER_AppExit(HTASK, HINSTANCE, HQUEUE );
/* ------ Internal variables ------ */
static HTASK hFirstTask = 0;
@@ -71,6 +70,18 @@
/***********************************************************************
+ * TASK_GetNextTask
+ */
+HTASK TASK_GetNextTask( HTASK hTask )
+{
+ TDB* pTask = (TDB*)GlobalLock(hTask);
+
+ if (pTask->hNext) return pTask->hNext;
+ return (hFirstTask != hTask) ? hFirstTask : 0;
+}
+
+
+/***********************************************************************
* TASK_CreateDOSEnvironment
*
* Create the original DOS environment.
@@ -526,8 +537,8 @@
frame16->saved_sp = 0; /*pTask->sp;*/
frame16->ds = frame16->es = pTask->hInstance;
frame16->entry_point = 0;
- frame16->ordinal_number = 24; /* WINPROCS.24 is TASK_Reschedule */
- frame16->dll_id = 24; /* WINPROCS */
+ frame16->entry_ip = OFFSETOF(TASK_RescheduleProc) + 14;
+ frame16->entry_cs = SELECTOROF(TASK_RescheduleProc);
frame16->bp = 0;
frame16->ip = LOWORD( CALLTO16_RetAddr_word );
frame16->cs = HIWORD( CALLTO16_RetAddr_word );
@@ -583,14 +594,6 @@
FILE_CloseAllFiles( pTask->hPDB );
- /* Nuke timers */
-
- TIMER_NukeTimers( 0, pTask->hQueue );
-
- /* Free the message queue */
-
- QUEUE_DeleteMsgQueue( pTask->hQueue );
-
/* Free the selector aliases */
GLOBAL_FreeBlock( pTask->hCSAlias );
@@ -619,6 +622,12 @@
{
extern void EXEC_ExitWindows( int retCode );
+ TDB* pTask = (TDB*) GlobalLock( hCurrentTask );
+
+ /* Perform USER cleanup */
+
+ USER_AppExit( hCurrentTask, pTask->hInstance, pTask->hQueue );
+
if (hTaskToKill && (hTaskToKill != hCurrentTask))
{
/* If another task is already marked for destruction, */