Release 970914
Thu Sep 11 18:24:56 1997 Philippe De Muyter <phdm@info.ucl.ac.be>
* [objects/dc.c]
In DC_SetupGCForPatBlt, replace R2_NOT by GXxor with (black xor white).
Tue Sep 9 23:04:02 1997 U. Bonnes <bon@elektron.ikp.physik.th-darmstadt.de>
* [memory/virtual.c]
Do not write debugging info unconditionally to stderr.
* [files/profile.c]
Call PROFILE_GetSection in PROFILE_GetString for key_name "" too.
* [misc/crtdll.c]
Many new functions.
* [include/windows.h] [windows/winpos.c]
ClientToScreen16 doesn't have a return value.
Sun Sep 7 10:06:39 1997 Alexandre Julliard <julliard@lrc.epfl.ch>
* [misc/main.c] [AUTHORS]
Update the list of contributors. Please let me know if I forgot
someone.
* [if1632/*.spec] [if1632/builtin.c] [tools/build.c]
Ordinal base for Win32 DLLs is now computed automatically from the
lowest ordinal found.
* [include/wintypes.h]
WINAPI is now defined as attribute((stdcall)). This will require
gcc to compile.
* [if1632/thunk.c]
Removed Win32 thunks (no longer needed with stdcall).
* [if1632/crtdll.spec] [misc/crtdll.c]
Make sure we only reference cdecl functions in the spec file.
* [objects/dc.c]
Use CapNotLast drawing style for 1-pixel wide lines.
* [tools/build.c]
Added 'double' argument type.
Added 'varargs' function type for Win32.
Made CallTo16_xxx functions stdcall.
Fri Sep 5 14:50:49 1997 Alex Korobka <alex@trantor.pharm.sunysb.edu>
* [tools/build.c] [windows/win.c] [windows/event.c] [windows/message.c]
More fixes to get message exchange closer to the original.
* [misc/spy.c]
Message logs now contain window names.
* [loader/resource.c] [loader/ne_resource.c] [loader/task.c]
[objects/cursoricon.c] [windows/user.c]
Added some obscure features to fix memory leaks.
Fri Sep 5 00:46:28 1997 Jan Willamowius <jan@janhh.shnet.org>
* [if1632/kernel32.spec] [win32/newfns.c]
Added stub for UTRegister() and UTUnRegister().
Thu Sep 4 12:03:12 1997 Frans van Dorsselaer <dorssel@rulhmpc49.LeidenUniv.nl>
* [controls/edit.c]
Allow ASCII codes > 127 in WM_CHAR.
Mon Sep 1 17:23:24 1997 Dimitrie O. Paun <dimi@mail.cs.toronto.edu>
* [controls/widgets.c]
In InitCommonControls, remember the name of the class
because lpszClassName was made to point to a local array
Added the ProgressBar to the list of implemented controls.
Call InitCommonControls from WIDGETS_Init to register all
implemented Common Controls.
* [include/commctrl.h]
Added misc decl for the Progress Bar.
* [controls/progress.c] [include/progress.h]
First attempt at implementiong the Progress Bar class.
* [objects/brush.h]
Implementation for GetSysColorBrush[16|32]
* [controls/status.c]
Use DrawEdge to draw the borders and fill the background
* [controls/uitools.c]
Added DrawDiagEdge32 and DrawRectEdge32
* [graphics/painting.c]
Implement DrawEdge[16|32]
Started DrawFrameControl32
Mon Sep 1 10:07:09 1997 Lawson Whitney <lawson_whitney@juno.com>
* [misc/comm.c] [include/windows.h]
SetCommEventMask returns a SEGPTR.
Sun Aug 31 23:28:32 1997 Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>
* [loader/pe_image.c][loader/module.c][include/pe_image.h]
[include/module.h]
Cleaned up the whole Win32 library mess (a bit).
* [debugger/stabs.c]
If 'wine' has no absolute path and isn't found, check $PATH too.
* [misc/ole2nls.c]
Some fixes.
* [misc/ver.c]
Added support for PE style version resources.
* [memory/string.c]
Check for NULL pointers to _lstr* functions, just as Windows95 does.
* [multimedia/time.c]
Made list of timers a simple linked list.
* [loader/resource.c]
Netscape 3 seems to pass NEGATIVE resource Ids (in an
unsigned int, yes). Don't know why, fixed it anyway.
* [objects/bitmap.c]
LoadImageW added.
* [include/win.h][windows/win.c]
Change wIDmenu from UINT16 to UINT32 and changed the
SetWindow(Long|Word) accordingly.
Thu Aug 28 19:30:08 1997 Morten Welinder <terra@diku.dk>
* [include/windows.h]
Add a few more colors defined for Win95.
Add a few more brush styles.
* [windows/syscolor.c]
Add error checks for SYSCOLOR_SetColor, SYSCOLOR_Init,
GetSysColor16, GetSysColor32. Add support for above colors.
Sun Aug 24 16:22:57 1997 Andrew Taylor <andrew@riscan.com>
* [multimedia/mmsystem.c]
Changed mmioDescend to use mmio functions for file I/O, neccessary
for memory files.
diff --git a/loader/module.c b/loader/module.c
index a41ce37..c40d240 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -18,6 +18,7 @@
#include "hook.h"
#include "module.h"
#include "neexe.h"
+#include "resource.h"
#include "selectors.h"
#include "stackframe.h"
#include "task.h"
@@ -26,7 +27,7 @@
#include "debug.h"
#include "callback.h"
-extern HINSTANCE16 PE_LoadModule( int fd, OFSTRUCT *ofs, LOADPARAMS* params );
+extern HINSTANCE16 PE_LoadModule( HFILE32 hf, OFSTRUCT *ofs, LOADPARAMS* params );
static HMODULE16 hFirstModule = 0;
static HMODULE16 hCachedModule = 0; /* Module cached by MODULE_OpenFile */
@@ -35,19 +36,70 @@
/***********************************************************************
* MODULE_GetPtr
*/
-NE_MODULE *MODULE_GetPtr( HMODULE16 hModule )
+NE_MODULE *MODULE_GetPtr( HMODULE32 hModule )
{
- NE_MODULE *pModule = (NE_MODULE *)GlobalLock16( hModule );
- if (!pModule || (pModule->magic != IMAGE_OS2_SIGNATURE) ||
- (pModule->self != hModule)) return NULL;
- return pModule;
+ HMODULE16 hnd =MODULE_HANDLEtoHMODULE16(hModule);
+
+ if (!hnd)
+ return NULL;
+ return (NE_MODULE*)GlobalLock16(hnd);
}
+/***********************************************************************
+ * MODULE_HANDLEtoHMODULE16
+ */
+HMODULE16
+MODULE_HANDLEtoHMODULE16(HANDLE32 handle) {
+ NE_MODULE *pModule;
+
+ if (HIWORD(handle)) {
+ /* this is a HMODULE32 aka pe->mappeddll */
+
+ /* walk the list looking for the correct startaddress */
+ pModule = (NE_MODULE *)GlobalLock16( hFirstModule );
+ while (pModule) {
+ if ( ((pModule->flags&(NE_FFLAGS_BUILTIN|NE_FFLAGS_WIN32))==NE_FFLAGS_WIN32) &&
+ pModule->pe_module &&
+ ((HMODULE32)pModule->pe_module->mappeddll == handle)
+ )
+ return pModule->self;
+ pModule=(NE_MODULE*)GlobalLock16(pModule->next);
+ }
+ return 0;
+ }
+ return GetExePtr(handle);
+}
+
+/***********************************************************************
+ * MODULE_HANDLEtoHMODULE32
+ * return HMODULE32, if possible, HMODULE16 otherwise
+ */
+HMODULE32
+MODULE_HANDLEtoHMODULE32(HANDLE32 handle) {
+ NE_MODULE *pModule;
+
+ if (HIWORD(handle))
+ return (HMODULE32)handle;
+ else {
+ handle = GetExePtr(handle);
+ if (!handle)
+ return 0;
+ pModule = (NE_MODULE *)GlobalLock16( handle );
+ if (!pModule)
+ return 0;
+
+ if ( ((pModule->flags&(NE_FFLAGS_BUILTIN|NE_FFLAGS_WIN32))==NE_FFLAGS_WIN32) &&
+ pModule->pe_module
+ )
+ return (HMODULE32)pModule->pe_module->mappeddll;
+ return handle;
+ }
+}
/***********************************************************************
* MODULE_DumpModule
*/
-void MODULE_DumpModule( HMODULE16 hModule )
+void MODULE_DumpModule( HMODULE32 hModule )
{
int i, ordinal;
SEGTABLEENTRY *pSeg;
@@ -210,7 +262,7 @@
/***********************************************************************
* MODULE_OpenFile
*/
-int MODULE_OpenFile( HMODULE16 hModule )
+int MODULE_OpenFile( HMODULE32 hModule )
{
NE_MODULE *pModule;
DOS_FULL_NAME full_name;
@@ -218,7 +270,7 @@
static int cachedfd = -1;
- hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
+ hModule = MODULE_HANDLEtoHMODULE16(hModule);
dprintf_module( stddeb, "MODULE_OpenFile(%04x) cache: mod=%04x fd=%d\n",
hModule, hCachedModule, cachedfd );
if (!(pModule = MODULE_GetPtr( hModule ))) return -1;
@@ -275,7 +327,7 @@
/***********************************************************************
* MODULE_CreateSegments
*/
-static BOOL32 MODULE_CreateSegments( HMODULE16 hModule )
+static BOOL32 MODULE_CreateSegments( HMODULE32 hModule )
{
SEGTABLEENTRY *pSegment;
NE_MODULE *pModule;
@@ -306,7 +358,7 @@
/***********************************************************************
* MODULE_GetInstance
*/
-HINSTANCE16 MODULE_GetInstance( HMODULE16 hModule )
+HINSTANCE16 MODULE_GetInstance( HMODULE32 hModule )
{
SEGTABLEENTRY *pSegment;
NE_MODULE *pModule;
@@ -359,12 +411,13 @@
*
* Create a dummy NE module for Win32 or Winelib.
*/
-HMODULE16 MODULE_CreateDummyModule( const OFSTRUCT *ofs )
+HMODULE32 MODULE_CreateDummyModule( const OFSTRUCT *ofs )
{
- HMODULE16 hModule;
+ HMODULE32 hModule;
NE_MODULE *pModule;
SEGTABLEENTRY *pSegment;
- char *pStr,*basename,*s;
+ char *pStr,*s;
+ const char* basename;
INT32 of_size = sizeof(OFSTRUCT) - sizeof(ofs->szPathName)
+ strlen(ofs->szPathName) + 1;
@@ -379,7 +432,7 @@
8;
hModule = GlobalAlloc16( GMEM_MOVEABLE | GMEM_ZEROINIT, size );
- if (!hModule) return (HMODULE16)11; /* invalid exe */
+ if (!hModule) return (HMODULE32)11; /* invalid exe */
FarSetOwner( hModule, hModule );
pModule = (NE_MODULE *)GlobalLock16( hModule );
@@ -432,7 +485,7 @@
*pStr = strlen(basename);
if (*pStr>8) *pStr=8;
strncpy( pStr+1, basename, 8 );
- free(basename);
+ free((void*)basename);
pStr += 9;
/* All tables zero terminated */
@@ -447,12 +500,12 @@
/***********************************************************************
* MODULE_LoadExeHeader
*/
-static HMODULE16 MODULE_LoadExeHeader( HFILE32 hFile, OFSTRUCT *ofs )
+static HMODULE32 MODULE_LoadExeHeader( HFILE32 hFile, OFSTRUCT *ofs )
{
IMAGE_DOS_HEADER mz_header;
IMAGE_OS2_HEADER ne_header;
int size;
- HMODULE16 hModule;
+ HMODULE32 hModule;
NE_MODULE *pModule;
BYTE *pData;
char *buffer, *fastload = NULL;
@@ -469,18 +522,18 @@
_llseek32( hFile, 0, SEEK_SET );
if ((_lread32(hFile,&mz_header,sizeof(mz_header)) != sizeof(mz_header)) ||
(mz_header.e_magic != IMAGE_DOS_SIGNATURE))
- return (HMODULE16)11; /* invalid exe */
+ return (HMODULE32)11; /* invalid exe */
_llseek32( hFile, mz_header.e_lfanew, SEEK_SET );
if (_lread32( hFile, &ne_header, sizeof(ne_header) ) != sizeof(ne_header))
- return (HMODULE16)11; /* invalid exe */
+ return (HMODULE32)11; /* invalid exe */
- if (ne_header.ne_magic == IMAGE_NT_SIGNATURE) return (HMODULE16)21; /* win32 exe */
- if (ne_header.ne_magic != IMAGE_OS2_SIGNATURE) return (HMODULE16)11; /* invalid exe */
+ if (ne_header.ne_magic == IMAGE_NT_SIGNATURE) return (HMODULE32)21; /* win32 exe */
+ if (ne_header.ne_magic != IMAGE_OS2_SIGNATURE) return (HMODULE32)11; /* invalid exe */
if (ne_header.ne_magic == IMAGE_OS2_SIGNATURE_LX) {
fprintf(stderr, "Sorry, this is an OS/2 linear executable (LX) file !\n");
- return (HMODULE16)11;
+ return (HMODULE32)11;
}
/* We now have a valid NE header */
@@ -501,7 +554,7 @@
ne_header.entry_tab_length;
hModule = GlobalAlloc16( GMEM_MOVEABLE | GMEM_ZEROINIT, size );
- if (!hModule) return (HMODULE16)11; /* invalid exe */
+ if (!hModule) return (HMODULE32)11; /* invalid exe */
FarSetOwner( hModule, hModule );
pModule = (NE_MODULE *)GlobalLock16( hModule );
memcpy( pModule, &ne_header, sizeof(ne_header) );
@@ -560,7 +613,7 @@
HeapFree( SystemHeap, 0, buffer );
if (fastload) HeapFree( SystemHeap, 0, fastload );
GlobalFree16( hModule );
- return (HMODULE16)11; /* invalid exe */
+ return (HMODULE32)11; /* invalid exe */
}
pSeg = (struct ne_segment_table_entry_s *)buffer;
for (i = ne_header.n_segment_tab; i > 0; i--, pSeg++)
@@ -574,7 +627,7 @@
{
if (fastload) HeapFree( SystemHeap, 0, fastload );
GlobalFree16( hModule );
- return (HMODULE16)11; /* invalid exe */
+ return (HMODULE32)11; /* invalid exe */
}
/* Get the resource table */
@@ -584,8 +637,9 @@
pModule->res_table = (int)pData - (int)pModule;
if (!READ(mz_header.e_lfanew + ne_header.resource_tab_offset,
ne_header.rname_tab_offset - ne_header.resource_tab_offset,
- pData )) return (HMODULE16)11; /* invalid exe */
+ pData )) return (HMODULE32)11; /* invalid exe */
pData += ne_header.rname_tab_offset - ne_header.resource_tab_offset;
+ NE_InitResourceHandler( hModule );
}
else pModule->res_table = 0; /* No resource table */
@@ -598,7 +652,7 @@
{
if (fastload) HeapFree( SystemHeap, 0, fastload );
GlobalFree16( hModule );
- return (HMODULE16)11; /* invalid exe */
+ return (HMODULE32)11; /* invalid exe */
}
pData += ne_header.moduleref_tab_offset - ne_header.rname_tab_offset;
@@ -613,7 +667,7 @@
{
if (fastload) HeapFree( SystemHeap, 0, fastload );
GlobalFree16( hModule );
- return (HMODULE16)11; /* invalid exe */
+ return (HMODULE32)11; /* invalid exe */
}
pData += ne_header.n_mod_ref_tab * sizeof(WORD);
}
@@ -628,7 +682,7 @@
{
if (fastload) HeapFree( SystemHeap, 0, fastload );
GlobalFree16( hModule );
- return (HMODULE16)11; /* invalid exe */
+ return (HMODULE32)11; /* invalid exe */
}
pData += ne_header.entry_tab_offset - ne_header.iname_tab_offset;
@@ -641,7 +695,7 @@
{
if (fastload) HeapFree( SystemHeap, 0, fastload );
GlobalFree16( hModule );
- return (HMODULE16)11; /* invalid exe */
+ return (HMODULE32)11; /* invalid exe */
}
pData += ne_header.entry_tab_length;
@@ -659,7 +713,7 @@
if (!pModule->nrname_handle)
{
GlobalFree16( hModule );
- return (HMODULE16)11; /* invalid exe */
+ return (HMODULE32)11; /* invalid exe */
}
buffer = GlobalLock16( pModule->nrname_handle );
_llseek32( hFile, ne_header.nrname_tab_offset, SEEK_SET );
@@ -668,7 +722,7 @@
{
GlobalFree16( pModule->nrname_handle );
GlobalFree16( hModule );
- return (HMODULE16)11; /* invalid exe */
+ return (HMODULE32)11; /* invalid exe */
}
}
else pModule->nrname_handle = 0;
@@ -678,13 +732,13 @@
if (pModule->modref_count)
{
pModule->dlls_to_init = GLOBAL_Alloc(GMEM_ZEROINIT,
- (pModule->modref_count+1)*sizeof(HMODULE16),
+ (pModule->modref_count+1)*sizeof(HMODULE32),
hModule, FALSE, FALSE, FALSE );
if (!pModule->dlls_to_init)
{
if (pModule->nrname_handle) GlobalFree16( pModule->nrname_handle );
GlobalFree16( hModule );
- return (HMODULE16)11; /* invalid exe */
+ return (HMODULE32)11; /* invalid exe */
}
}
else pModule->dlls_to_init = 0;
@@ -699,7 +753,7 @@
*
* Lookup the ordinal for a given name.
*/
-WORD MODULE_GetOrdinal( HMODULE16 hModule, const char *name )
+WORD MODULE_GetOrdinal( HMODULE32 hModule, const char *name )
{
unsigned char buffer[256], *cpnt;
BYTE len;
@@ -763,7 +817,7 @@
*
* Return the entry point for a given ordinal.
*/
-FARPROC16 MODULE_GetEntryPoint( HMODULE16 hModule, WORD ordinal )
+FARPROC16 MODULE_GetEntryPoint( HMODULE32 hModule, WORD ordinal )
{
NE_MODULE *pModule;
WORD curOrdinal = 1;
@@ -823,7 +877,7 @@
* Change the value of an entry point. Use with caution!
* It can only change the offset value, not the selector.
*/
-BOOL16 MODULE_SetEntryPoint( HMODULE16 hModule, WORD ordinal, WORD offset )
+BOOL16 MODULE_SetEntryPoint( HMODULE32 hModule, WORD ordinal, WORD offset )
{
NE_MODULE *pModule;
WORD curOrdinal = 1;
@@ -872,7 +926,7 @@
{
WORD ordinal;
FARPROC16 ret;
- static HMODULE16 hModule = 0;
+ static HMODULE32 hModule = 0;
if (!hModule) hModule = GetModuleHandle16( "WPROCS" );
ordinal = MODULE_GetOrdinal( hModule, name );
@@ -886,7 +940,7 @@
/***********************************************************************
* MODULE_GetModuleName
*/
-LPSTR MODULE_GetModuleName( HMODULE16 hModule )
+LPSTR MODULE_GetModuleName( HMODULE32 hModule )
{
NE_MODULE *pModule;
BYTE *p, len;
@@ -916,9 +970,9 @@
*
* Find a module from a path name.
*/
-HMODULE16 MODULE_FindModule( LPCSTR path )
+HMODULE32 MODULE_FindModule( LPCSTR path )
{
- HMODULE16 hModule = hFirstModule;
+ HMODULE32 hModule = hFirstModule;
LPCSTR filename, dotptr, modulepath, modulename;
BYTE len, *name_table;
@@ -973,7 +1027,7 @@
*
* Remove a module from memory.
*/
-static void MODULE_FreeModule( HMODULE16 hModule )
+BOOL16 MODULE_FreeModule( HMODULE32 hModule, TDB* pTaskContext )
{
HMODULE16 *hPrevModule;
NE_MODULE *pModule;
@@ -981,17 +1035,28 @@
HMODULE16 *pModRef;
int i;
- if (!(pModule = MODULE_GetPtr( hModule ))) return;
+ if (!(pModule = MODULE_GetPtr( hModule ))) return FALSE;
+ hModule = pModule->self;
+
+ if (((INT16)(--pModule->count)) > 0 ) return TRUE;
+ else pModule->count = 0;
+
if (pModule->flags & NE_FFLAGS_BUILTIN)
- return; /* Can't free built-in module */
+ return FALSE; /* Can't free built-in module */
- if (pModule->flags & NE_FFLAGS_LIBMODULE) MODULE_CallWEP( hModule );
+ if (pModule->flags & NE_FFLAGS_LIBMODULE)
+ {
+ MODULE_CallWEP( hModule );
- /* Free the objects owned by the module */
+ /* Free the objects owned by the DLL module */
- HOOK_FreeModuleHooks( hModule );
- CLASS_FreeModuleClasses( hModule );
-
+ if( pTaskContext && pTaskContext->userhandler )
+ {
+ pTaskContext->userhandler( hModule, USIG_DLL_UNLOAD, 0,
+ pTaskContext->hInstance,
+ pTaskContext->hQueue );
+ }
+ }
/* Clear magic number just in case */
pModule->magic = pModule->self = 0;
@@ -1030,6 +1095,8 @@
/* Remove module from cache */
if (hCachedModule == hModule) hCachedModule = 0;
+
+ return TRUE;
}
@@ -1038,7 +1105,7 @@
*
* Implementation of LoadModule()
*/
-HINSTANCE16 MODULE_Load( LPCSTR name, LPVOID paramBlock, BOOL32 first )
+HINSTANCE16 MODULE_Load( LPCSTR name, LPVOID paramBlock, UINT16 uFlags)
{
HMODULE16 hModule;
HINSTANCE16 hInstance, hPrevInstance;
@@ -1080,10 +1147,9 @@
hModule = MODULE_LoadExeHeader( hFile, &ofs );
if (hModule < 32)
{
- /* Note: PE_LoadModule closes the file */
if (hModule == 21)
hModule = PE_LoadModule( hFile, &ofs, paramBlock );
- else _lclose32( hFile );
+ else _lclose32( hFile );
if (hModule < 32)
fprintf( stderr, "LoadModule: can't load '%s', error=%d\n",
@@ -1092,6 +1158,7 @@
}
_lclose32( hFile );
pModule = MODULE_GetPtr( hModule );
+ pModule->flags |= uFlags; /* stamp implicitly loaded modules */
/* Allocate the segments for this module */
@@ -1117,7 +1184,7 @@
/* its handle in the list of DLLs to initialize. */
HMODULE16 hDLL;
- if ((hDLL = MODULE_Load( buffer, (LPVOID)-1, FALSE )) == 2)
+ if ((hDLL = MODULE_Load( buffer, (LPVOID)-1, NE_FFLAGS_IMPLICIT )) == 2)
{
/* file not found */
char *p;
@@ -1127,15 +1194,17 @@
if (!(p = strrchr( buffer, '\\' ))) p = buffer;
memcpy( p + 1, pstr + 1, *pstr );
strcpy( p + 1 + *pstr, ".dll" );
- hDLL = MODULE_Load( buffer, (LPVOID)-1, FALSE );
+ hDLL = MODULE_Load( buffer, (LPVOID)-1, NE_FFLAGS_IMPLICIT );
}
if (hDLL < 32)
{
+ /* FIXME: cleanup what was done */
+
fprintf( stderr, "Could not load '%s' required by '%s', error = %d\n",
buffer, name, hDLL );
return 2; /* file not found */
}
- *pModRef = GetExePtr( hDLL );
+ *pModRef = MODULE_HANDLEtoHMODULE16( hDLL );
*pDLLs++ = *pModRef;
}
else /* Increment the reference count of the DLL */
@@ -1158,11 +1227,12 @@
HMODULE16 hselfload = GetModuleHandle16("WPROCS");
DWORD oldstack;
WORD 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",
- *((BYTE*)pModule + pModule->name_table),
- *((BYTE*)pModule + pModule->name_table),
- (char *)pModule + pModule->name_table + 1);
+
+ dprintf_module(stddeb, "MODULE_Load: %*.*s is a self-loading module!\n",
+ *((BYTE*)pModule + pModule->name_table),
+ *((BYTE*)pModule + pModule->name_table),
+ (char *)pModule + pModule->name_table + 1);
+
NE_LoadSegment( hModule, 1 );
selfloadheader = (SELFLOADHEADER *)
PTR_SEG_OFF_TO_LIN(pSegTable->selector, 0);
@@ -1210,7 +1280,8 @@
frame32->ecx = 0;
frame32->ebx = 0;
frame32->ebp = 0;
- frame32->retaddr = 0;
+ frame32->restore_addr = 0;
+ frame32->retaddr = 0;
frame32->codeselector = WINE_CODE_SELECTOR;
/* pTask->esp = (DWORD)frame32; */
}
@@ -1242,10 +1313,14 @@
pModule->count = 1;
- if (first && (pModule->flags & NE_FFLAGS_LIBMODULE))
- NE_InitializeDLLs( hModule );
+ /* Call initialization rountines for all loaded DLLs. Note that
+ * when we load implicitly linked DLLs this will be done by the InitTask().
+ */
+
+ if ((pModule->flags & (NE_FFLAGS_LIBMODULE | NE_FFLAGS_IMPLICIT)) ==
+ NE_FFLAGS_LIBMODULE ) NE_InitializeDLLs( hModule );
}
- else
+ else /* module is already loaded, just create a new data segment if it's a task */
{
pModule = MODULE_GetPtr( hModule );
hPrevInstance = MODULE_GetInstance( hModule );
@@ -1254,6 +1329,7 @@
NE_LoadSegment( hModule, pModule->dgroup );
pModule->count++;
}
+
#else
lstrcpyn32A( ofs.szPathName, name, sizeof(ofs.szPathName) );
if ((hModule = MODULE_CreateDummyModule( &ofs )) < 32) return hModule;
@@ -1269,6 +1345,8 @@
HTASK16 hTask;
WORD showcmd;
+ pModule->flags |= NE_FFLAGS_GUI;
+
/* PowerPoint passes NULL as showCmd */
if (params->showCmd)
showcmd = *((WORD *)PTR_SEG_TO_LIN(params->showCmd)+1);
@@ -1292,7 +1370,7 @@
*/
HINSTANCE16 LoadModule16( LPCSTR name, LPVOID paramBlock )
{
- return MODULE_Load( name, paramBlock, TRUE );
+ return MODULE_Load( name, paramBlock, 0 );
}
@@ -1303,13 +1381,11 @@
{
NE_MODULE *pModule;
- hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
if (!(pModule = MODULE_GetPtr( hModule ))) return FALSE;
-
dprintf_module( stddeb, "FreeModule16: %s count %d\n",
MODULE_GetModuleName(hModule), pModule->count );
- if (--pModule->count == 0) MODULE_FreeModule( hModule );
- return TRUE;
+
+ return MODULE_FreeModule( hModule, GlobalLock16(GetCurrentTask()) );
}
@@ -1318,7 +1394,7 @@
*/
HMODULE16 WINAPI WIN16_GetModuleHandle( SEGPTR name )
{
- if (HIWORD(name) == 0) return GetExePtr( (HINSTANCE16)name );
+ if (HIWORD(name) == 0) return MODULE_HANDLEtoHMODULE16( (HINSTANCE16)name );
return MODULE_FindModule( PTR_SEG_TO_LIN(name) );
}
@@ -1327,6 +1403,33 @@
return MODULE_FindModule( name );
}
+/***********************************************************************
+ * GetModuleHandle (KERNEL32.237)
+ */
+HMODULE32 WINAPI GetModuleHandle32A(LPCSTR module)
+{
+ HMODULE32 hModule;
+
+ dprintf_win32(stddeb, "GetModuleHandleA: %s\n", module ? module : "NULL");
+/* Freecell uses the result of GetModuleHandleA(0) as the hInstance in
+all calls to e.g. CreateWindowEx. */
+ if (module == NULL) {
+ TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() );
+ hModule = pTask->hInstance;
+ } else
+ hModule = MODULE_FindModule(module);
+ return MODULE_HANDLEtoHMODULE32(hModule);
+}
+
+HMODULE32 WINAPI GetModuleHandle32W(LPCWSTR module)
+{
+ HMODULE32 hModule;
+ LPSTR modulea = HEAP_strdupWtoA( GetProcessHeap(), 0, module );
+ hModule = GetModuleHandle32A( modulea );
+ HeapFree( GetProcessHeap(), 0, modulea );
+ return hModule;
+}
+
/**********************************************************************
* GetModuleUsage (KERNEL.48)
@@ -1335,7 +1438,6 @@
{
NE_MODULE *pModule;
- hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
dprintf_module( stddeb, "GetModuleUsage(%04x): returning %d\n",
hModule, pModule->count );
@@ -1352,7 +1454,6 @@
NE_MODULE *pModule;
if (!hModule) hModule = GetCurrentTask();
- hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
lstrcpyn32A( lpFileName, NE_MODULE_NAME(pModule), nSize );
dprintf_module( stddeb, "GetModuleFileName16: %s\n", lpFileName );
@@ -1373,7 +1474,6 @@
TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() );
hModule = pTask->hInstance;
}
- hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
lstrcpyn32A( lpFileName, NE_MODULE_NAME(pModule), size );
dprintf_module( stddeb, "GetModuleFileName32A: %s\n", lpFileName );
@@ -1410,17 +1510,73 @@
/***********************************************************************
* LoadLibraryEx32W (KERNEL.513)
+ * FIXME
*/
-HINSTANCE16 WINAPI LoadLibraryEx32W16( LPCSTR libname, HANDLE16 hf,
+HMODULE32 WINAPI LoadLibraryEx32W16( LPCSTR libname, HANDLE16 hf,
DWORD flags )
{
fprintf(stderr,"LoadLibraryEx32W(%s,%d,%08lx)\n",libname,hf,flags);
- if (!flags && !hf)
- return LoadLibrary32A(libname);
- return 0;
+ return LoadLibraryEx32A(libname,hf,flags);
}
/***********************************************************************
+ * LoadLibraryEx32A (KERNEL32)
+ */
+HMODULE32 WINAPI LoadLibraryEx32A(LPCSTR libname,HFILE32 hfile,DWORD flags)
+{
+ HMODULE32 hmod;
+
+ hmod = PE_LoadLibraryEx32A(libname,hfile,flags);
+ if (hmod <= 32) {
+ char buffer[256];
+
+ strcpy( buffer, libname );
+ strcat( buffer, ".dll" );
+ hmod = PE_LoadLibraryEx32A(buffer,hfile,flags);
+ }
+ /* initialize all DLLs, which haven't been initialized yet. */
+ PE_InitializeDLLs( GetCurrentProcessId(), DLL_PROCESS_ATTACH, NULL);
+ return hmod;
+}
+
+/***********************************************************************
+ * LoadLibraryA (KERNEL32)
+ */
+HMODULE32 WINAPI LoadLibrary32A(LPCSTR libname) {
+ return LoadLibraryEx32A(libname,0,0);
+}
+
+/***********************************************************************
+ * LoadLibraryW (KERNEL32)
+ */
+HMODULE32 WINAPI LoadLibrary32W(LPCWSTR libnameW)
+{
+ return LoadLibraryEx32W(libnameW,0,0);
+}
+
+/***********************************************************************
+ * LoadLibraryExW (KERNEL32)
+ */
+HMODULE32 WINAPI LoadLibraryEx32W(LPCWSTR libnameW,HFILE32 hfile,DWORD flags)
+{
+ LPSTR libnameA = HEAP_strdupWtoA( GetProcessHeap(), 0, libnameW );
+ HMODULE32 ret = LoadLibraryEx32A( libnameA , hfile, flags );
+
+ HeapFree( GetProcessHeap(), 0, libnameA );
+ return ret;
+}
+
+/***********************************************************************
+ * FreeLibrary
+ */
+BOOL32 WINAPI FreeLibrary32(HINSTANCE32 hLibModule)
+{
+ fprintf(stderr,"FreeLibrary: empty stub\n");
+ return TRUE;
+}
+
+
+/***********************************************************************
* LoadLibrary (KERNEL.95)
*/
HINSTANCE16 WINAPI LoadLibrary16( LPCSTR libname )
@@ -1434,17 +1590,13 @@
}
dprintf_module( stddeb, "LoadLibrary: (%08x) %s\n", (int)libname, libname);
- /* This does not increment the module reference count, and will
- * therefore cause crashes on FreeLibrary calls.
- if ((handle = MODULE_FindModule( libname )) != 0) return handle;
- */
- handle = MODULE_Load( libname, (LPVOID)-1, TRUE );
+ handle = MODULE_Load( libname, (LPVOID)-1, 0 );
if (handle == (HINSTANCE16)2) /* file not found */
{
char buffer[256];
lstrcpyn32A( buffer, libname, 252 );
strcat( buffer, ".dll" );
- handle = MODULE_Load( buffer, (LPVOID)-1, TRUE );
+ handle = MODULE_Load( buffer, (LPVOID)-1, 0 );
}
return handle;
}
@@ -1486,7 +1638,7 @@
return 2; /* File not found */
if (!(cmdShowHandle = GlobalAlloc16( 0, 2 * sizeof(WORD) )))
return 8; /* Out of memory */
- if (!(cmdLineHandle = GlobalAlloc16( 0, 256 )))
+ if (!(cmdLineHandle = GlobalAlloc16( 0, 1024 )))
{
GlobalFree16( cmdShowHandle );
return 8; /* Out of memory */
@@ -1531,7 +1683,7 @@
}
if (*p)
- lstrcpyn32A( cmdline + 1, p + 1, 127 );
+ lstrcpyn32A( cmdline + 1, p + 1, 1023 );
else
cmdline[1] = '\0';
@@ -1645,7 +1797,7 @@
* WIN32_GetProcAddress16 (KERNEL32.36)
* Get procaddress in 16bit module from win32... (kernel32 undoc. ordinal func)
*/
-FARPROC16 WINAPI WIN32_GetProcAddress16( HMODULE16 hModule, LPSTR name )
+FARPROC16 WINAPI WIN32_GetProcAddress16( HMODULE32 hModule, LPSTR name )
{
WORD ordinal;
FARPROC16 ret;
@@ -1654,7 +1806,7 @@
fprintf(stderr,"WIN32_GetProcAddress16: hModule may not be 0!\n");
return (FARPROC16)0;
}
- hModule = GetExePtr(hModule);
+ hModule = MODULE_HANDLEtoHMODULE16(hModule);
if (HIWORD(name)) {
ordinal = MODULE_GetOrdinal( hModule, name );
dprintf_module( stddeb, "WIN32_GetProcAddress16: %04x '%s'\n",
@@ -1679,7 +1831,7 @@
FARPROC16 ret;
if (!hModule) hModule = GetCurrentTask();
- hModule = GetExePtr( hModule );
+ hModule = MODULE_HANDLEtoHMODULE16( hModule );
if (HIWORD(name) != 0)
{
@@ -1714,13 +1866,16 @@
dprintf_win32(stddeb,"GetProcAddress32(%08lx,%s)\n",(DWORD)hModule,function);
else
dprintf_win32(stddeb,"GetProcAddress32(%08lx,%p)\n",(DWORD)hModule,function);
- hModule = GetExePtr( hModule );
if (!(pModule = MODULE_GetPtr( hModule )))
return (FARPROC32)0;
- if (!(pModule->flags & NE_FFLAGS_WIN32) || !pModule->pe_module)
- return (FARPROC32)0;
if (pModule->flags & NE_FFLAGS_BUILTIN)
return BUILTIN_GetProcAddress32( pModule, function );
+ if (!pModule->pe_module) {
+ fprintf(stderr,"Oops, Module 0x%08lx has got no pe_module?\n",
+ (DWORD)MODULE_HANDLEtoHMODULE32(hModule)
+ );
+ return (FARPROC32)0;
+ }
return PE_FindExportedFunction( pModule->pe_module, function );
#else
return NULL;
@@ -1732,14 +1887,20 @@
*/
LPIMAGE_NT_HEADERS WINAPI RtlImageNtHeader(HMODULE32 hModule)
{
+ /* basically:
+ * return hModule+(((IMAGE_DOS_HEADER*)hModule)->e_lfanew);
+ * but we could get HMODULE16 or the like (think builtin modules)
+ */
+
#ifndef WINELIB
NE_MODULE *pModule;
- hModule = GetExePtr( hModule );
if (!(pModule = MODULE_GetPtr( hModule )))
return (LPIMAGE_NT_HEADERS)0;
if (!(pModule->flags & NE_FFLAGS_WIN32) || !pModule->pe_module)
return (LPIMAGE_NT_HEADERS)0;
+ if (pModule->flags & NE_FFLAGS_BUILTIN)
+ return (LPIMAGE_NT_HEADERS)0;
return pModule->pe_module->pe_header;
#else
return NULL;
@@ -1763,7 +1924,7 @@
BOOL16 WINAPI IsSharedSelector( HANDLE16 selector )
{
/* Check whether the selector belongs to a DLL */
- NE_MODULE *pModule = MODULE_GetPtr( GetExePtr( selector ));
+ NE_MODULE *pModule = MODULE_GetPtr( selector );
if (!pModule) return FALSE;
return (pModule->flags & NE_FFLAGS_LIBMODULE) != 0;
}
@@ -1815,7 +1976,7 @@
*/
BOOL16 WINAPI ModuleFindHandle( MODULEENTRY *lpme, HMODULE16 hModule )
{
- hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
+ hModule = MODULE_HANDLEtoHMODULE16( hModule );
lpme->wNext = hModule;
return ModuleNext( lpme );
}
diff --git a/loader/ne_image.c b/loader/ne_image.c
index dd0ff09..e1631e9 100644
--- a/loader/ne_image.c
+++ b/loader/ne_image.c
@@ -17,6 +17,7 @@
#include <errno.h>
#include "neexe.h"
#include "windows.h"
+#include "task.h"
#include "arch.h"
#include "selectors.h"
#include "callback.h"
@@ -455,7 +456,7 @@
*
* Call the DLL initialization code
*/
-static BOOL32 NE_InitDLL( HMODULE16 hModule )
+static BOOL32 NE_InitDLL( TDB* pTask, HMODULE16 hModule )
{
NE_MODULE *pModule;
SEGTABLEENTRY *pSegTable;
@@ -473,6 +474,17 @@
if (!(pModule->flags & NE_FFLAGS_LIBMODULE) ||
(pModule->flags & NE_FFLAGS_WIN32)) return TRUE; /*not a library*/
+
+ /* Call USER signal handler. This is necessary to install a
+ * proper loader for HICON and HCURSOR resources that this DLL
+ * may contain. InitApp() does this for task modules. */
+
+ if (pTask && pTask->userhandler)
+ {
+ pTask->userhandler( hModule, USIG_DLL_LOAD, 0, pTask->hInstance,
+ pTask->hQueue );
+ }
+
if (!pModule->cs) return TRUE; /* no initialization code */
memset( &context, 0, sizeof(context) );
@@ -516,10 +528,12 @@
/***********************************************************************
* NE_InitializeDLLs
*
- * Initialize the loaded DLLs.
+ * Recursively initialize all DLLs (according to the order in which
+ * they where loaded).
*/
void NE_InitializeDLLs( HMODULE16 hModule )
{
+ TDB* pTask = (TDB*)GlobalLock16(GetCurrentTask());
NE_MODULE *pModule;
HMODULE16 *pDLL;
@@ -529,6 +543,7 @@
/* PE_InitializeDLLs(hModule); */
return;
}
+
if (pModule->dlls_to_init)
{
HGLOBAL16 to_init = pModule->dlls_to_init;
@@ -539,7 +554,7 @@
}
GlobalFree16( to_init );
}
- NE_InitDLL( hModule );
+ NE_InitDLL( pTask, hModule );
}
diff --git a/loader/ne_resource.c b/loader/ne_resource.c
index cf885e8..7121b18 100644
--- a/loader/ne_resource.c
+++ b/loader/ne_resource.c
@@ -3,6 +3,7 @@
*
* Copyright 1993 Robert J. Amstadt
* Copyright 1995 Alexandre Julliard
+ * 1997 Alex Korobka
*/
#include <stdio.h>
@@ -22,6 +23,8 @@
#include "stddebug.h"
#include "debug.h"
+#define NEXT_TYPEINFO(pTypeInfo) ((NE_TYPEINFO *)((char*)((pTypeInfo) + 1) + \
+ (pTypeInfo)->count * sizeof(NE_NAMEINFO)))
/***********************************************************************
* NE_FindNameTableId
@@ -29,29 +32,26 @@
* Find the type and resource id from their names.
* Return value is MAKELONG( typeId, resId ), or 0 if not found.
*/
-static DWORD NE_FindNameTableId( HMODULE16 hModule, SEGPTR typeId, SEGPTR resId )
+static DWORD NE_FindNameTableId( NE_MODULE *pModule, SEGPTR typeId, SEGPTR resId )
{
- NE_MODULE *pModule;
- NE_TYPEINFO *pTypeInfo;
+ NE_TYPEINFO *pTypeInfo = (NE_TYPEINFO *)((char *)pModule + pModule->res_table + 2);
NE_NAMEINFO *pNameInfo;
HGLOBAL16 handle;
WORD *p;
DWORD ret = 0;
int count;
- if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
- pTypeInfo = (NE_TYPEINFO *)((char *)pModule + pModule->res_table + 2);
for (; pTypeInfo->type_id != 0;
- pTypeInfo = (NE_TYPEINFO *)((char*)(pTypeInfo+1) +
- pTypeInfo->count * sizeof(NE_NAMEINFO)))
+ pTypeInfo = (NE_TYPEINFO *)((char*)(pTypeInfo+1) +
+ pTypeInfo->count * sizeof(NE_NAMEINFO)))
{
- if (pTypeInfo->type_id != 0x800f) continue;
- pNameInfo = (NE_NAMEINFO *)(pTypeInfo + 1);
- for (count = pTypeInfo->count; count > 0; count--, pNameInfo++)
- {
+ if (pTypeInfo->type_id != 0x800f) continue;
+ pNameInfo = (NE_NAMEINFO *)(pTypeInfo + 1);
+ for (count = pTypeInfo->count; count > 0; count--, pNameInfo++)
+ {
dprintf_resource( stddeb, "NameTable entry: type=%04x id=%04x\n",
pTypeInfo->type_id, pNameInfo->id );
- handle = LoadResource16( hModule,
+ handle = LoadResource16( pModule->self,
(HRSRC16)((int)pNameInfo - (int)pModule) );
for(p = (WORD*)LockResource16(handle); p && *p; p = (WORD *)((char*)p+*p))
{
@@ -89,11 +89,56 @@
}
FreeResource16( handle );
if (ret) return ret;
- }
+ }
}
return 0;
}
+/***********************************************************************
+ * NE_FindTypeSection
+ *
+ * Find header struct for a particular resource type.
+ */
+static NE_TYPEINFO* NE_FindTypeSection( NE_MODULE *pModule,
+ NE_TYPEINFO *pTypeInfo, SEGPTR typeId )
+{
+ /* start from pTypeInfo */
+
+ if (HIWORD(typeId) != 0) /* Named type */
+ {
+ char *str = (char *)PTR_SEG_TO_LIN( typeId );
+ BYTE len = strlen( str );
+ while (pTypeInfo->type_id)
+ {
+ if (!(pTypeInfo->type_id & 0x8000))
+ {
+ BYTE *p = (BYTE*)pModule + pModule->res_table + pTypeInfo->type_id;
+ if ((*p == len) && !lstrncmpi32A( p+1, str, len ))
+ {
+ dprintf_resource( stddeb, " Found type '%s'\n", str );
+ return pTypeInfo;
+ }
+ }
+ dprintf_resource( stddeb, " Skipping type %04x\n", pTypeInfo->type_id );
+ pTypeInfo = NEXT_TYPEINFO(pTypeInfo);
+ }
+ }
+ else /* Numeric type id */
+ {
+ WORD id = LOWORD(typeId) | 0x8000;
+ while (pTypeInfo->type_id)
+ {
+ if (pTypeInfo->type_id == id)
+ {
+ dprintf_resource( stddeb, " Found type %04x\n", id );
+ return pTypeInfo;
+ }
+ dprintf_resource( stddeb, " Skipping type %04x\n", pTypeInfo->type_id );
+ pTypeInfo = NEXT_TYPEINFO(pTypeInfo);
+ }
+ }
+ return NULL;
+}
/***********************************************************************
* NE_FindResourceFromType
@@ -131,6 +176,83 @@
/***********************************************************************
+ * NE_DefResourceHandler
+ *
+ * This is the default LoadProc() function.
+ */
+HGLOBAL16 WINAPI NE_DefResourceHandler( HGLOBAL16 hMemObj, HMODULE16 hModule,
+ HRSRC16 hRsrc )
+{
+ int fd;
+ NE_MODULE* pModule = MODULE_GetPtr( hModule );
+ if ( pModule && (fd = MODULE_OpenFile( hModule )) >= 0)
+ {
+ HGLOBAL16 handle;
+ WORD sizeShift = *(WORD *)((char *)pModule + pModule->res_table);
+ NE_NAMEINFO* pNameInfo = (NE_NAMEINFO*)((char*)pModule + hRsrc);
+
+ dprintf_resource( stddeb, "NEResourceHandler: loading, pos=%d, len=%d\n",
+ (int)pNameInfo->offset << sizeShift,
+ (int)pNameInfo->length << sizeShift );
+ if( hMemObj )
+ handle = GlobalReAlloc16( hMemObj, pNameInfo->length << sizeShift, 0 );
+ else
+ handle = NE_AllocResource( hModule, hRsrc, 0 );
+
+ if( handle )
+ {
+ lseek( fd, (int)pNameInfo->offset << sizeShift, SEEK_SET );
+ read( fd, GlobalLock16( handle ), (int)pNameInfo->length << sizeShift );
+ }
+ return handle;
+ }
+ return (HGLOBAL16)0;
+}
+
+/***********************************************************************
+ * NE_InitResourceHandler
+ *
+ * Fill in 'resloader' fields in the resource table.
+ */
+BOOL32 NE_InitResourceHandler( HMODULE16 hModule )
+{
+ NE_MODULE *pModule = MODULE_GetPtr( hModule );
+ NE_TYPEINFO *pTypeInfo = (NE_TYPEINFO *)((char *)pModule + pModule->res_table + 2);
+
+ dprintf_resource(stddeb,"InitResourceHandler[%04x]\n", hModule );
+
+ while(pTypeInfo->type_id)
+ {
+ pTypeInfo->resloader = (DWORD)&NE_DefResourceHandler;
+ pTypeInfo = NEXT_TYPEINFO(pTypeInfo);
+ }
+ return TRUE;
+}
+
+/***********************************************************************
+ * NE_SetResourceHandler
+ */
+FARPROC32 NE_SetResourceHandler( HMODULE16 hModule, SEGPTR typeId,
+ FARPROC32 resourceHandler )
+{
+ NE_MODULE *pModule = MODULE_GetPtr( hModule );
+ NE_TYPEINFO *pTypeInfo = (NE_TYPEINFO *)((char *)pModule + pModule->res_table + 2);
+ FARPROC32 prevHandler = NULL;
+
+ do
+ {
+ pTypeInfo = NE_FindTypeSection( pModule, pTypeInfo, typeId );
+ if( pTypeInfo )
+ {
+ prevHandler = (FARPROC32)pTypeInfo->resloader;
+ pTypeInfo->resloader = (DWORD)resourceHandler;
+ pTypeInfo = NEXT_TYPEINFO(pTypeInfo);
+ }
+ } while( pTypeInfo );
+ return prevHandler;
+}
+
+/***********************************************************************
* NE_FindResource
*/
HRSRC16 NE_FindResource( HMODULE16 hModule, SEGPTR typeId, SEGPTR resId )
@@ -142,10 +264,12 @@
if (!pModule || !pModule->res_table) return 0;
pTypeInfo = (NE_TYPEINFO *)((char *)pModule + pModule->res_table + 2);
- if (HIWORD(typeId) || HIWORD(resId))
+ if ((pModule->expected_version < 0x030a) && (HIWORD(typeId) || HIWORD(resId)))
{
- /* Search the names in the nametable */
- DWORD id = NE_FindNameTableId( hModule, typeId, resId );
+ /* Search the names in the nametable (which is not present
+ * since Windows 3.1). */
+
+ DWORD id = NE_FindNameTableId( pModule, typeId, resId );
if (id) /* found */
{
typeId = LOWORD(id);
@@ -153,60 +277,27 @@
}
}
- if (HIWORD(typeId) != 0) /* Named type */
+ do
{
- char *str = (char *)PTR_SEG_TO_LIN( typeId );
- BYTE len = strlen( str );
- while (pTypeInfo->type_id)
- {
- if (!(pTypeInfo->type_id & 0x8000))
- {
- BYTE *p = (BYTE*)pModule+pModule->res_table+pTypeInfo->type_id;
- if ((*p == len) && !lstrncmpi32A( p+1, str, len ))
- {
- dprintf_resource( stddeb, " Found type '%s'\n", str );
- hRsrc = NE_FindResourceFromType(pModule, pTypeInfo, resId);
- if (hRsrc)
- {
- dprintf_resource( stddeb, " Found id %08lx\n", resId );
- return hRsrc;
- }
- dprintf_resource( stddeb, " Not found, going on\n" );
- }
- }
- dprintf_resource( stddeb, " Skipping type %04x\n",
- pTypeInfo->type_id );
- pTypeInfo = (NE_TYPEINFO *)((char*)(pTypeInfo+1) +
- pTypeInfo->count * sizeof(NE_NAMEINFO));
- }
- }
- else /* Numeric type id */
- {
- WORD id = LOWORD(typeId) | 0x8000;
- while (pTypeInfo->type_id)
- {
- if (pTypeInfo->type_id == id)
- {
- dprintf_resource( stddeb, " Found type %04x\n", id );
- hRsrc = NE_FindResourceFromType( pModule, pTypeInfo, resId );
- if (hRsrc)
- {
- dprintf_resource( stddeb, " Found id %08lx\n", resId );
- return hRsrc;
- }
- dprintf_resource( stddeb, " Not found, going on\n" );
- }
- dprintf_resource( stddeb, " Skipping type %04x\n",
- pTypeInfo->type_id );
- pTypeInfo = (NE_TYPEINFO *)((char*)(pTypeInfo+1) +
- pTypeInfo->count * sizeof(NE_NAMEINFO));
- }
- }
+ pTypeInfo = NE_FindTypeSection( pModule, pTypeInfo, typeId );
+ if( pTypeInfo )
+ {
+ hRsrc = NE_FindResourceFromType(pModule, pTypeInfo, resId);
+ if( hRsrc )
+ {
+ dprintf_resource( stddeb, " Found id %08lx\n", resId );
+ return hRsrc;
+ }
+ dprintf_resource( stddeb, " Not found, going on\n" );
+ pTypeInfo = NEXT_TYPEINFO(pTypeInfo);
+ }
+ } while( pTypeInfo );
+
+ dprintf_resource( stddeb, "failed!\n");
return 0;
}
-
/***********************************************************************
* NE_AllocResource
*/
@@ -273,33 +364,67 @@
*/
HGLOBAL16 NE_LoadResource( HMODULE16 hModule, HRSRC16 hRsrc )
{
- NE_NAMEINFO *pNameInfo=NULL;
- WORD sizeShift;
- int fd;
-
+ NE_TYPEINFO *pTypeInfo;
+ NE_NAMEINFO *pNameInfo = NULL;
NE_MODULE *pModule = MODULE_GetPtr( hModule );
- if (!pModule || !pModule->res_table) return 0;
+ int d;
+
+ if (!hRsrc || !pModule || !pModule->res_table) return 0;
+
+ /* First, verify hRsrc (just an offset from pModule to the needed pNameInfo) */
+
+ d = pModule->res_table + 2;
+ pTypeInfo = (NE_TYPEINFO *)((char *)pModule + d);
#ifndef WINELIB
- pNameInfo = (NE_NAMEINFO*)((char*)pModule + hRsrc);
-#endif
- if (pNameInfo->handle)
+ while( hRsrc > d )
{
- pNameInfo->usage++;
- dprintf_resource( stddeb, " Already loaded, new count=%d\n",
- pNameInfo->usage );
- return pNameInfo->handle;
+ if (pTypeInfo->type_id == 0)
+ break; /* terminal entry */
+ d += sizeof(NE_TYPEINFO) + pTypeInfo->count * sizeof(NE_NAMEINFO);
+ if (hRsrc < d)
+ {
+ if( ((d - hRsrc)%sizeof(NE_NAMEINFO)) == 0 )
+ {
+ pNameInfo = (NE_NAMEINFO *)(((char *)pModule) + hRsrc);
+ break;
+ }
+ else
+ break; /* NE_NAMEINFO boundary mismatch */
+ }
+ pTypeInfo = (NE_TYPEINFO *)(((char *)pModule) + d);
}
- sizeShift = *(WORD *)((char *)pModule + pModule->res_table);
- dprintf_resource( stddeb, " Loading, pos=%d, len=%d\n",
- (int)pNameInfo->offset << sizeShift,
- (int)pNameInfo->length << sizeShift );
- if ((fd = MODULE_OpenFile( hModule )) == -1) return 0;
- pNameInfo->handle = NE_AllocResource( hModule, hRsrc, 0 );
- pNameInfo->usage = 1;
- lseek( fd, (int)pNameInfo->offset << sizeShift, SEEK_SET );
- read( fd, GlobalLock16( pNameInfo->handle ),
- (int)pNameInfo->length << sizeShift );
- return pNameInfo->handle;
+#endif
+ if (pNameInfo)
+ {
+ RESOURCEHANDLER16 __r16loader;
+ if (pNameInfo->handle
+ && !(GlobalFlags16(pNameInfo->handle) & GMEM_DISCARDED))
+ {
+ pNameInfo->usage++;
+ dprintf_resource( stddeb, " Already loaded, new count=%d\n",
+ pNameInfo->usage );
+ }
+ else
+ {
+ if (pTypeInfo->resloader)
+ __r16loader = (RESOURCEHANDLER16)pTypeInfo->resloader;
+ else /* this is really bad */
+ {
+ fprintf( stderr, "[%04x]: Missing resource handler!!!...\n", hModule);
+ __r16loader = NE_DefResourceHandler;
+ }
+
+ /* Finally call resource loader */
+
+ if ((pNameInfo->handle = __r16loader(pNameInfo->handle, hModule, hRsrc)))
+ {
+ pNameInfo->usage++;
+ pNameInfo->flags |= NE_SEGFLAGS_LOADED;
+ }
+ }
+ return pNameInfo->handle;
+ }
+ return 0;
}
@@ -324,7 +449,7 @@
WORD count;
NE_MODULE *pModule = MODULE_GetPtr( hModule );
- if (!pModule || !pModule->res_table) return handle;
+ if (!handle || !pModule || !pModule->res_table) return handle;
pTypeInfo = (NE_TYPEINFO *)((char *)pModule + pModule->res_table + 2);
while (pTypeInfo->type_id)
{
@@ -345,7 +470,10 @@
}
pTypeInfo = (NE_TYPEINFO *)pNameInfo;
}
- fprintf( stderr, "NE_FreeResource: %04x %04x not found!\n", hModule, handle );
+
+ dprintf_resource(stddeb, "NE_FreeResource[%04x]: no intrinsic resource for %04x\n",
+ hModule, handle );
+ GlobalFree16( handle ); /* it could have been DirectResAlloc()'ed */
return handle;
}
#endif /* WINELIB */
diff --git a/loader/pe_image.c b/loader/pe_image.c
index 223348b..415094f 100644
--- a/loader/pe_image.c
+++ b/loader/pe_image.c
@@ -17,11 +17,14 @@
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
#include "windows.h"
#include "winbase.h"
#include "callback.h"
#include "neexe.h"
#include "peexe.h"
+#include "process.h"
#include "pe_image.h"
#include "module.h"
#include "global.h"
@@ -33,8 +36,7 @@
#include "debugger.h"
#include "xmalloc.h"
-static void PE_InitDLL(HMODULE16 hModule, DWORD type, LPVOID lpReserved);
-
+static void PE_InitDLL(PE_MODREF* modref, DWORD type, LPVOID lpReserved);
/* convert PE image VirtualAddress to Real Address */
#define RVA(x) ((unsigned int)load_addr+(unsigned int)(x))
@@ -91,25 +93,40 @@
*/
FARPROC32 PE_FindExportedFunction(struct pe_data *pe, LPCSTR funcName)
{
- IMAGE_EXPORT_DIRECTORY * exports = pe->pe_export;
- unsigned load_addr = pe->load_addr;
- u_short * ordinal;
- u_long * function;
- u_char ** name, *ename;
- int i;
+ IMAGE_EXPORT_DIRECTORY *exports;
+ unsigned load_addr;
+ u_short * ordinal;
+ u_long * function;
+ u_char ** name, *ename;
+ int i;
+ PDB32 *process=(PDB32*)GetCurrentProcessId();
+ PE_MODREF *pem;
+
+ pem = process->modref_list;
+ while (pem && (pem->pe_module != pe))
+ pem=pem->next;
+ if (!pem) {
+ fprintf(stderr,"No MODREF found for PE_MODULE %p in process %p\n",pe,process);
+ return NULL;
+ }
+ load_addr = pem->load_addr;
+ exports = pem->pe_export;
if (HIWORD(funcName))
dprintf_win32(stddeb,"PE_FindExportedFunction(%s)\n",funcName);
else
dprintf_win32(stddeb,"PE_FindExportedFunction(%d)\n",(int)funcName);
- if (!exports)
+ if (!exports) {
+ fprintf(stderr,"Module %p/MODREF %p doesn't have a exports table.\n",pe,pem);
return NULL;
- ordinal=(u_short*) RVA(exports->AddressOfNameOrdinals);
- function=(u_long*) RVA(exports->AddressOfFunctions);
- name=(u_char **) RVA(exports->AddressOfNames);
+ }
+ ordinal = (u_short*) RVA(exports->AddressOfNameOrdinals);
+ function= (u_long*) RVA(exports->AddressOfFunctions);
+ name = (u_char **) RVA(exports->AddressOfNames);
+
if (HIWORD(funcName)) {
for(i=0; i<exports->NumberOfNames; i++) {
- ename=(char*) RVA(*name);
+ ename=(char*)RVA(*name);
if(!strcmp(ename,funcName))
return (FARPROC32) RVA(function[*ordinal]);
ordinal++;
@@ -127,18 +144,17 @@
}
void
-fixup_imports (struct pe_data *pe, HMODULE16 hModule)
+fixup_imports (PDB32 *process,PE_MODREF *pem)
{
- IMAGE_IMPORT_DESCRIPTOR *pe_imp;
- int fixup_failed = 0;
- unsigned int load_addr = pe->load_addr;
- int i;
- NE_MODULE *ne_mod;
- HMODULE16 *mod_ptr;
- char *modname;
+ PE_MODULE *pe = pem->pe_module;
+ IMAGE_IMPORT_DESCRIPTOR *pe_imp;
+ int fixup_failed = 0;
+ unsigned int load_addr = pem->load_addr;
+ int i;
+ char *modname;
- if (pe->pe_export)
- modname = (char*) RVA(pe->pe_export->Name);
+ if (pem->pe_export)
+ modname = (char*) RVA(pem->pe_export->Name);
else
modname = "<unknown>";
@@ -146,40 +162,77 @@
dprintf_win32 (stddeb, "\nDumping imports list\n");
/* first, count the number of imported non-internal modules */
- pe_imp = pe->pe_import;
+ pe_imp = pem->pe_import;
+ if (!pe_imp)
+ fprintf(stderr,"no import directory????\n");
/* FIXME: should terminate on 0 Characteristics */
for (i = 0; pe_imp->Name; pe_imp++)
i++;
- /* Now, allocate memory for dlls_to_init */
- ne_mod = GlobalLock16 (hModule);
- ne_mod->dlls_to_init = GLOBAL_Alloc(GMEM_ZEROINIT, (i+1)*sizeof(HMODULE16),
- hModule, FALSE, FALSE, FALSE);
- mod_ptr = GlobalLock16 (ne_mod->dlls_to_init);
- /* load the modules and put their handles into the list */
+ /* load the imported modules. They are automatically
+ * added to the modref list of the process.
+ */
- /* FIXME: should terminate on 0 Characteristics */
- for (i = 0, pe_imp = pe->pe_import; pe_imp->Name; pe_imp++) {
+ /* FIXME: should terminate on 0 Characteristics */
+ for (i = 0, pe_imp = pem->pe_import; pe_imp->Name; pe_imp++) {
+ HMODULE32 res;
+ PE_MODREF *xpem,**ypem;
+
+
char *name = (char *) RVA(pe_imp->Name);
- mod_ptr[i] = MODULE_Load( name, (LPVOID)-1, FALSE );
- if (mod_ptr[i] <= (HMODULE16) 32) {
+
+ /* don't use MODULE_Load, Win32 creates new task differently */
+ res = PE_LoadLibraryEx32A( name, 0, 0 );
+ if (res <= (HMODULE32) 32) {
char *p, buffer[256];
/* Try with prepending the path of the current module */
- GetModuleFileName16 (hModule, buffer, sizeof (buffer));
+ GetModuleFileName32A (pe->mappeddll, buffer, sizeof (buffer));
if (!(p = strrchr (buffer, '\\')))
p = buffer;
strcpy (p + 1, name);
- mod_ptr[i] = MODULE_Load( buffer, (LPVOID)-1, FALSE );
+ res = PE_LoadLibraryEx32A( buffer, 0, 0 );
}
- if (mod_ptr[i] <= (HMODULE16) 32) {
+ if (res <= (HMODULE32) 32) {
fprintf (stderr, "Module %s not found\n", name);
exit (0);
}
+ res = MODULE_HANDLEtoHMODULE32(res);
+ xpem = pem->next;
+ while (xpem) {
+ if (xpem->pe_module->mappeddll == res)
+ break;
+ xpem = xpem->next;
+ }
+ if (xpem) {
+ /* it has been loaded *BEFORE* us, so we have to init
+ * it before us. we just swap the two modules which should
+ * work.
+ */
+ /* unlink xpem from chain */
+ ypem = &(process->modref_list);
+ while (*ypem) {
+ if ((*ypem)==xpem)
+ break;
+ ypem = &((*ypem)->next);
+ }
+ *ypem = xpem->next;
+
+ /* link it directly before pem */
+ ypem = &(process->modref_list);
+ while (*ypem) {
+ if ((*ypem)==pem)
+ break;
+ ypem = &((*ypem)->next);
+ }
+ *ypem = xpem;
+ xpem->next = pem;
+
+ }
i++;
}
- pe_imp = pe->pe_import;
+ pe_imp = pem->pe_import;
while (pe_imp->Name) {
char *Module;
IMAGE_IMPORT_BY_NAME *pe_name;
@@ -269,9 +322,9 @@
if (fixup_failed) exit(1);
}
-static void calc_vma_size(struct pe_data *pe)
+static int calc_vma_size(struct pe_data *pe)
{
- int i;
+ int i,vma_size = 0;
dprintf_win32(stddeb, "Dump of segment table\n");
dprintf_win32(stddeb, " Name VSz Vaddr SzRaw Fileadr *Reloc *Lineum #Reloc #Linum Char\n");
@@ -288,19 +341,21 @@
pe->pe_seg[i].NumberOfRelocations,
pe->pe_seg[i].NumberOfLinenumbers,
pe->pe_seg[i].Characteristics);
- pe->vma_size = MAX(pe->vma_size,
+ vma_size = MAX(vma_size,
pe->pe_seg[i].VirtualAddress +
pe->pe_seg[i].SizeOfRawData);
}
+ return vma_size;
}
-static void do_relocations(struct pe_data *pe)
+static void do_relocations(PE_MODREF *pem)
{
- int delta = pe->load_addr - pe->base_addr;
- unsigned int load_addr = pe->load_addr;
- IMAGE_BASE_RELOCATION *r = pe->pe_reloc;
- int hdelta = (delta >> 16) & 0xFFFF;
- int ldelta = delta & 0xFFFF;
+ int delta = pem->load_addr - pem->pe_module->pe_header->OptionalHeader.ImageBase;
+
+ unsigned int load_addr= pem->load_addr;
+ IMAGE_BASE_RELOCATION *r = pem->pe_reloc;
+ int hdelta = (delta >> 16) & 0xFFFF;
+ int ldelta = delta & 0xFFFF;
/* int reloc_size = */
@@ -360,27 +415,47 @@
/**********************************************************************
* PE_LoadImage
- * Load one PE format executable into memory
+ * Load one PE format DLL/EXE into memory
+ *
+ * Unluckily we can't just mmap the sections where we want them, for
+ * (at least) Linux does only support offset with are multiples of the
+ * underlying filesystemblocksize, but PE DLLs usually have alignments of 512
+ * byte. This fails for instance when you try to map from CDROM (bsize 2048).
+ *
+ * BUT we have to map the whole image anyway, for Win32 programs sometimes
+ * want to access them. (HMODULE32 point to the start of it)
*/
-static void PE_LoadImage( struct pe_data **ret_pe, int fd, HMODULE16 hModule, WORD offset, OFSTRUCT *ofs )
+static PE_MODULE *PE_LoadImage( int fd )
{
struct pe_data *pe;
- int i, result;
- int load_addr;
- IMAGE_DATA_DIRECTORY dir;
- char buffer[200];
DBG_ADDR daddr;
- char *modname;
+ struct stat stbuf;
daddr.seg=0;
daddr.type = NULL;
+ if (-1==fstat(fd,&stbuf)) {
+ perror("PE_LoadImage:fstat");
+ return NULL;
+ }
pe = xmalloc(sizeof(struct pe_data));
memset(pe,0,sizeof(struct pe_data));
- pe->pe_header = xmalloc(sizeof(IMAGE_NT_HEADERS));
- /* read PE header */
- lseek( fd, offset, SEEK_SET);
- read( fd, pe->pe_header, sizeof(IMAGE_NT_HEADERS));
+ /* map the PE image somewhere */
+ pe->mappeddll = (HMODULE32)mmap(NULL,stbuf.st_size,PROT_READ,MAP_SHARED,fd,0);
+ if (!pe->mappeddll || pe->mappeddll==-1) {
+ perror("PE_LoadImage:mmap");
+ free(pe);
+ return NULL;
+ }
+ /* link PE header */
+ pe->pe_header = (IMAGE_NT_HEADERS*)(pe->mappeddll+(((IMAGE_DOS_HEADER*)pe->mappeddll)->e_lfanew));
+ if (pe->pe_header->Signature!=IMAGE_NT_SIGNATURE) {
+ fprintf(stderr,"image doesn't have PE signature, but 0x%08lx\n",
+ pe->pe_header->Signature
+ );
+ free(pe);
+ return NULL;
+ }
if (pe->pe_header->FileHeader.Machine != IMAGE_FILE_MACHINE_I386) {
fprintf(stderr,"trying to load PE image for unsupported architecture (");
@@ -403,48 +478,66 @@
fprintf(stderr,"Unknown-%04x",pe->pe_header->FileHeader.Machine);break;
}
fprintf(stderr,")\n");
- return;
+ return NULL;
}
-/* FIXME: this is a *horrible* hack to make COMDLG32.DLL load OK. The
- * problem needs to be fixed properly at some stage
+ pe->pe_seg = (IMAGE_SECTION_HEADER*)(((LPBYTE)(pe->pe_header+1))-
+ (16 - pe->pe_header->OptionalHeader.NumberOfRvaAndSizes) * sizeof(IMAGE_DATA_DIRECTORY));
+
+/* FIXME: the (16-...) is a *horrible* hack to make COMDLG32.DLL load OK. The
+ * problem needs to be fixed properly at some stage.
*/
- if (pe->pe_header->OptionalHeader.NumberOfRvaAndSizes != 16) {
- printf("Short PE Header!!!\n");
- lseek( fd, -(16 - pe->pe_header->OptionalHeader.NumberOfRvaAndSizes) * sizeof(IMAGE_DATA_DIRECTORY), SEEK_CUR);
+ return pe;
+}
+
+/**********************************************************************
+ * This maps a loaded PE dll into the address space of the specified process.
+ */
+void
+PE_MapImage(PE_MODULE *pe,PDB32 *process, OFSTRUCT *ofs, DWORD flags) {
+ PE_MODREF *pem;
+ int i, result;
+ int load_addr;
+ IMAGE_DATA_DIRECTORY dir;
+ char buffer[200];
+ DBG_ADDR daddr;
+ char *modname;
+ int vma_size;
+
+ pem = (PE_MODREF*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*pem));
+ /* NOTE: fixup_imports takes care of the correct order */
+ pem->next = process->modref_list;
+ process->modref_list = pem;
+
+ pem->pe_module = pe;
+ if (!(pe->pe_header->FileHeader.Characteristics & IMAGE_FILE_DLL)) {
+ if (process->exe_modref)
+ fprintf(stderr,"overwriting old exe_modref... arrgh\n");
+ process->exe_modref = pem;
}
- /* read sections */
- pe->pe_seg = xmalloc(sizeof(IMAGE_SECTION_HEADER) *
- pe->pe_header->FileHeader.NumberOfSections);
- read( fd, pe->pe_seg, sizeof(IMAGE_SECTION_HEADER) *
- pe->pe_header->FileHeader.NumberOfSections);
-
- load_addr = pe->pe_header->OptionalHeader.ImageBase;
- pe->base_addr=load_addr;
- pe->vma_size=0;
+ load_addr = pe->pe_header->OptionalHeader.ImageBase;
dprintf_win32(stddeb, "Load addr is %x\n",load_addr);
- calc_vma_size(pe);
- load_addr = (int) VirtualAlloc( (void*)pe->base_addr, pe->vma_size, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE );
- pe->load_addr = load_addr;
+ vma_size = calc_vma_size(pe);
+ load_addr = (int) VirtualAlloc( (void*)load_addr, vma_size, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE );
+ pem->load_addr = load_addr;
- dprintf_win32(stddeb, "Load addr is really %x, range %x\n",
- pe->load_addr, pe->vma_size);
+ dprintf_win32(stddeb, "Load addr is really %lx, range %x\n",
+ pem->load_addr, vma_size);
for(i=0; i < pe->pe_header->FileHeader.NumberOfSections; i++)
{
- /* load only non-BSS segments */
- if(!(pe->pe_seg[i].Characteristics &
- IMAGE_SCN_CNT_UNINITIALIZED_DATA))
- {
- if(lseek(fd,pe->pe_seg[i].PointerToRawData,SEEK_SET) == -1
- || read(fd,(char*)RVA(pe->pe_seg[i].VirtualAddress),
- pe->pe_seg[i].SizeOfRawData) != pe->pe_seg[i].SizeOfRawData)
- {
- fprintf(stderr,"Failed to load section %x\n", i);
- exit(0);
- }
- }
+ /* memcpy only non-BSS segments */
+ /* FIXME: this should be done by mmap(..MAP_PRIVATE|MAP_FIXED..)
+ * but it is not possible for (at least) Linux needs an offset
+ * aligned to a block on the filesystem.
+ */
+ if(!(pe->pe_seg[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA))
+ memcpy((char*)RVA(pe->pe_seg[i].VirtualAddress),
+ (char*)(pe->mappeddll+pe->pe_seg[i].PointerToRawData),
+ pe->pe_seg[i].SizeOfRawData
+ );
+
result = RVA (pe->pe_seg[i].VirtualAddress);
#if 1
/* not needed, memory is zero */
@@ -456,16 +549,16 @@
#endif
if(strcmp(pe->pe_seg[i].Name, ".idata") == 0)
- pe->pe_import = (LPIMAGE_IMPORT_DESCRIPTOR) result;
+ pem->pe_import = (LPIMAGE_IMPORT_DESCRIPTOR) result;
if(strcmp(pe->pe_seg[i].Name, ".edata") == 0)
- pe->pe_export = (LPIMAGE_EXPORT_DIRECTORY) result;
+ pem->pe_export = (LPIMAGE_EXPORT_DIRECTORY) result;
if(strcmp(pe->pe_seg[i].Name, ".rsrc") == 0)
- pe->pe_resource = (LPIMAGE_RESOURCE_DIRECTORY) result;
+ pem->pe_resource = (LPIMAGE_RESOURCE_DIRECTORY) result;
if(strcmp(pe->pe_seg[i].Name, ".reloc") == 0)
- pe->pe_reloc = (LPIMAGE_BASE_RELOCATION) result;
+ pem->pe_reloc = (LPIMAGE_BASE_RELOCATION) result;
}
/* There is word that the actual loader does not care about the
@@ -473,26 +566,26 @@
dir=pe->pe_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
if(dir.Size)
{
- if(pe->pe_export && (int)pe->pe_export!=RVA(dir.VirtualAddress))
+ if(pem->pe_export && (int)pem->pe_export!=RVA(dir.VirtualAddress))
fprintf(stderr,"wrong export directory??\n");
/* always trust the directory */
- pe->pe_export = (LPIMAGE_EXPORT_DIRECTORY) RVA(dir.VirtualAddress);
+ pem->pe_export = (LPIMAGE_EXPORT_DIRECTORY) RVA(dir.VirtualAddress);
}
dir=pe->pe_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
if(dir.Size)
{
- if(pe->pe_import && (int)pe->pe_import!=RVA(dir.VirtualAddress))
+ if(pem->pe_import && (int)pem->pe_import!=RVA(dir.VirtualAddress))
fprintf(stderr,"wrong import directory??\n");
- pe->pe_import = (LPIMAGE_IMPORT_DESCRIPTOR) RVA(dir.VirtualAddress);
+ pem->pe_import = (LPIMAGE_IMPORT_DESCRIPTOR) RVA(dir.VirtualAddress);
}
dir=pe->pe_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE];
if(dir.Size)
{
- if(pe->pe_resource && (int)pe->pe_resource!=RVA(dir.VirtualAddress))
+ if(pem->pe_resource && (int)pem->pe_resource!=RVA(dir.VirtualAddress))
fprintf(stderr,"wrong resource directory??\n");
- pe->pe_resource = (LPIMAGE_RESOURCE_DIRECTORY) RVA(dir.VirtualAddress);
+ pem->pe_resource = (LPIMAGE_RESOURCE_DIRECTORY) RVA(dir.VirtualAddress);
}
if(pe->pe_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size)
@@ -506,15 +599,15 @@
dir=pe->pe_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
if(dir.Size)
{
- if(pe->pe_reloc && (int)pe->pe_reloc!= RVA(dir.VirtualAddress))
+ if(pem->pe_reloc && (int)pem->pe_reloc!= RVA(dir.VirtualAddress))
fprintf(stderr,"wrong relocation list??\n");
- pe->pe_reloc = (void *) RVA(dir.VirtualAddress);
+ pem->pe_reloc = (void *) RVA(dir.VirtualAddress);
}
if(pe->pe_header->OptionalHeader.DataDirectory
[IMAGE_DIRECTORY_ENTRY_DEBUG].Size)
{
- DEBUG_RegisterDebugInfo(fd, pe, load_addr,
+ DEBUG_RegisterDebugInfo(pe, load_addr,
pe->pe_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress,
pe->pe_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size);
}
@@ -549,18 +642,12 @@
if(pe->pe_header->OptionalHeader.DataDirectory[15].Size)
dprintf_win32(stdnimp,"Unknown directory 15 ignored\n");
- if(pe->pe_reloc) do_relocations(pe);
-
- /* Do exports before imports because fixup_imports
- * may load a module that references this module.
- */
-
- if(pe->pe_export) dump_exports(pe->pe_export,load_addr);
- *ret_pe = pe; /* make export list available for GetProcAddress */
- if(pe->pe_import) fixup_imports(pe, hModule);
+ if(pem->pe_reloc) do_relocations(pem);
+ if(pem->pe_export) dump_exports(pem->pe_export,load_addr);
+ if(pem->pe_import) fixup_imports(process,pem);
- if (pe->pe_export)
- modname = (char*)RVA(pe->pe_export->Name);
+ if (pem->pe_export)
+ modname = (char*)RVA(pem->pe_export->Name);
else {
char *s;
modname = s = ofs->szPathName;
@@ -587,31 +674,70 @@
HINSTANCE16 MODULE_CreateInstance(HMODULE16 hModule,LOADPARAMS *params);
+/******************************************************************************
+ * The PE Library Loader frontend.
+ * FIXME: handle the flags.
+ */
+HMODULE32 PE_LoadLibraryEx32A (LPCSTR name, HFILE32 hFile, DWORD flags) {
+ OFSTRUCT ofs;
+ HMODULE32 hModule;
+ NE_MODULE *pModule;
+
+ if ((hModule = MODULE_FindModule( name )))
+ return hModule;
+
+ /* try to load builtin, enabled modules first */
+ if ((hModule = BUILTIN_LoadModule( name, FALSE )))
+ return hModule;
+
+ /* try to open the specified file */
+ if (HFILE_ERROR32==(hFile=OpenFile32(name,&ofs,OF_READ))) {
+ /* Now try the built-in even if disabled */
+ if ((hModule = BUILTIN_LoadModule( name, TRUE ))) {
+ fprintf( stderr, "Warning: could not load Windows DLL '%s', using built-in module.\n", name );
+ return hModule;
+ }
+ return 1;
+ }
+ if ((hModule = MODULE_CreateDummyModule( &ofs )) < 32) {
+ _lclose32(hFile);
+ return hModule;
+ }
+
+ pModule = (NE_MODULE *)GlobalLock16( hModule );
+ pModule->flags = NE_FFLAGS_WIN32;
+
+ /* FIXME: check if pe image loaded already ... */
+ pModule->pe_module = PE_LoadImage( FILE_GetUnixHandle(hFile) );
+ _lclose32(hFile);
+ if (!pModule->pe_module)
+ return 21;
+ /* recurse */
+ PE_MapImage(pModule->pe_module,(PDB32*)GetCurrentProcessId(),&ofs,flags);
+ return pModule->pe_module->mappeddll;
+}
+
+/*****************************************************************************
+ * Load the PE main .EXE. All other loading is done by PE_LoadLibraryEx32A
+ * FIXME: this function should use PE_LoadLibraryEx32A, but currently can't
+ * due to the TASK_CreateTask stuff.
+ */
HINSTANCE16 PE_LoadModule( HFILE32 hFile, OFSTRUCT *ofs, LOADPARAMS* params )
{
HMODULE16 hModule;
HINSTANCE16 hInstance;
NE_MODULE *pModule;
- IMAGE_DOS_HEADER mz_header;
- int fd;
if ((hModule = MODULE_CreateDummyModule( ofs )) < 32) return hModule;
pModule = (NE_MODULE *)GlobalLock16( hModule );
pModule->flags = NE_FFLAGS_WIN32;
- /* FIXME: Hack because PE_LoadModule is recursive */
- fd = dup( FILE_GetUnixHandle(hFile) );
- _lclose32( hFile );
- lseek( fd, 0, SEEK_SET );
- read( fd, &mz_header, sizeof(mz_header) );
-
- PE_LoadImage( &pModule->pe_module, fd, hModule, mz_header.e_lfanew, ofs );
+ pModule->pe_module = PE_LoadImage( FILE_GetUnixHandle(hFile) );
+ _lclose32(hFile);
if (!pModule->pe_module)
return 21;
- close( fd );
hInstance = MODULE_CreateInstance( hModule, params );
-
if (!(pModule->pe_module->pe_header->FileHeader.Characteristics & IMAGE_FILE_DLL))
{
TASK_CreateTask( hModule, hInstance, 0,
@@ -619,10 +745,11 @@
(LPSTR)PTR_SEG_TO_LIN( params->cmdLine ),
*((WORD*)PTR_SEG_TO_LIN(params->showCmd) + 1) );
}
+ PE_MapImage(pModule->pe_module,(PDB32*)GetCurrentProcessId(),ofs,0);
return hInstance;
}
-int PE_UnloadImage( HMODULE16 hModule )
+int PE_UnloadImage( HMODULE32 hModule )
{
printf("PEunloadImage() called!\n");
/* free resources, image, unmap */
@@ -634,19 +761,13 @@
* DLL_PROCESS_ATTACH. Only new created threads do DLL_THREAD_ATTACH
* (SDK)
*/
-static void PE_InitDLL(HMODULE16 hModule, DWORD type,LPVOID lpReserved)
+static void PE_InitDLL(PE_MODREF *pem, DWORD type,LPVOID lpReserved)
{
- NE_MODULE *pModule;
- PE_MODULE *pe;
- unsigned int load_addr;
+ PE_MODULE *pe = pem->pe_module;
+ unsigned int load_addr = pem->load_addr;
- hModule = GetExePtr(hModule);
- if (!(pModule = MODULE_GetPtr(hModule))) return;
- if (!(pModule->flags & NE_FFLAGS_WIN32) || !(pe = pModule->pe_module))
- return;
-
- load_addr = pe->load_addr;
-
+ if (type==DLL_PROCESS_ATTACH)
+ pem->flags |= PE_MODREF_PROCESS_ATTACHED;
#ifndef WINELIB
if (Options.debug) {
DBG_ADDR addr = { NULL, 0, RVA(pe->pe_header->OptionalHeader.AddressOfEntryPoint) };
@@ -666,58 +787,81 @@
if ( (pe->pe_header->FileHeader.Characteristics & IMAGE_FILE_DLL) &&
(pe->pe_header->OptionalHeader.AddressOfEntryPoint)
) {
- printf("InitPEDLL() called!\n");
- CallDLLEntryProc32(
- (FARPROC32)RVA(pe->pe_header->OptionalHeader.AddressOfEntryPoint),
- hModule,
- type,
- (DWORD)lpReserved
- );
+ FARPROC32 entry = (FARPROC32)RVA(pe->pe_header->OptionalHeader.AddressOfEntryPoint);
+ dprintf_relay( stddeb, "CallTo32(entryproc=%p,module=%d,type=%ld,res=%p)\n",
+ entry, pe->mappeddll, type, lpReserved );
+ entry( pe->mappeddll, type, lpReserved );
}
}
-void PE_InitializeDLLs(HMODULE16 hModule,DWORD type,LPVOID lpReserved)
-{
- NE_MODULE *pModule;
- HMODULE16 *pDLL;
- pModule = MODULE_GetPtr( GetExePtr(hModule) );
- if (pModule->dlls_to_init)
- {
- HGLOBAL16 to_init = pModule->dlls_to_init;
- pModule->dlls_to_init = 0;
-
- for (pDLL = (HMODULE16 *)GlobalLock16( to_init ); *pDLL; pDLL++)
- {
- PE_InitializeDLLs( *pDLL, type, lpReserved);
+/* Call the DLLentry function of all dlls used by that process.
+ * (NOTE: this may recursively call this function (if a library calls
+ * LoadLibrary) ... but it won't matter)
+ */
+void PE_InitializeDLLs(PDB32 *process,DWORD type,LPVOID lpReserved) {
+ PE_MODREF *pem;
+
+ pem = process->modref_list;
+ while (pem) {
+ if (pem->flags & PE_MODREF_NO_DLL_CALLS) {
+ pem = pem->next;
+ continue;
}
- GlobalFree16( to_init );
+ if (type==DLL_PROCESS_ATTACH) {
+ if (pem->flags & PE_MODREF_PROCESS_ATTACHED) {
+ pem = pem->next;
+ continue;
+ }
+ }
+ PE_InitDLL( pem, type, lpReserved );
+ pem = pem->next;
}
- PE_InitDLL( hModule, type, lpReserved );
}
-void PE_InitTls( PE_MODULE *module )
+void PE_InitTls(PDB32 *pdb)
{
- /* FIXME: tls callbacks ??? */
- DWORD index;
- DWORD datasize;
- DWORD size;
- LPVOID mem;
- LPIMAGE_TLS_DIRECTORY pdir;
+ /* FIXME: tls callbacks ??? */
+ PE_MODREF *pem;
+ IMAGE_NT_HEADERS *peh;
+ DWORD size,datasize,index;
+ LPVOID mem;
+ LPIMAGE_TLS_DIRECTORY pdir;
- if (!module->pe_header->OptionalHeader.DataDirectory[IMAGE_FILE_THREAD_LOCAL_STORAGE].VirtualAddress)
- return;
+ pem = pdb->modref_list;
+ while (pem) {
+ peh = pem->pe_module->pe_header;
+ if (!peh->OptionalHeader.DataDirectory[IMAGE_FILE_THREAD_LOCAL_STORAGE].VirtualAddress) {
+ pem = pem->next;
+ continue;
+ }
+ pdir = (LPVOID)(pem->load_addr + peh->OptionalHeader.
+ DataDirectory[IMAGE_FILE_THREAD_LOCAL_STORAGE].VirtualAddress);
+ index = TlsAlloc();
+ datasize= pdir->EndAddressOfRawData-pdir->StartAddressOfRawData;
+ size = datasize + pdir->SizeOfZeroFill;
+ mem=VirtualAlloc(0,size,MEM_RESERVE|MEM_COMMIT,PAGE_READWRITE);
+ memcpy(mem,(LPVOID) pdir->StartAddressOfRawData, datasize);
+ TlsSetValue(index,mem);
+ *(pdir->AddressOfIndex)=index;
+ pem=pem->next;
+ }
+}
- pdir = (LPVOID)(module->load_addr + module->pe_header->OptionalHeader.
- DataDirectory[IMAGE_FILE_THREAD_LOCAL_STORAGE].VirtualAddress);
- index = TlsAlloc();
- datasize = pdir->EndAddressOfRawData-pdir->StartAddressOfRawData;
- size = datasize + pdir->SizeOfZeroFill;
-
- mem = VirtualAlloc(0,size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
-
- memcpy(mem,(LPVOID) pdir->StartAddressOfRawData, datasize);
- TlsSetValue(index,mem);
- *(pdir->AddressOfIndex)=index;
+/****************************************************************************
+ * DisableThreadLibraryCalls (KERNEL32.74)
+ * Don't call DllEntryPoint for DLL_THREAD_{ATTACH,DETACH} if set.
+ */
+BOOL32 WINAPI DisableThreadLibraryCalls(HMODULE32 hModule)
+{
+ PDB32 *process = (PDB32*)GetCurrentProcessId();
+ PE_MODREF *pem = process->modref_list;
+
+ while (pem) {
+ if (pem->pe_module->mappeddll == hModule)
+ pem->flags|=PE_MODREF_NO_DLL_CALLS;
+ pem = pem->next;
+ }
+ return TRUE;
}
#endif /* WINELIB */
diff --git a/loader/pe_resource.c b/loader/pe_resource.c
index 2d2bbaf..9b8ae7e 100644
--- a/loader/pe_resource.c
+++ b/loader/pe_resource.c
@@ -18,6 +18,8 @@
#include "pe_image.h"
#include "module.h"
#include "heap.h"
+#include "task.h"
+#include "process.h"
#include "libres.h"
#include "stackframe.h"
#include "neexe.h"
@@ -25,20 +27,24 @@
#include "debug.h"
/**********************************************************************
- * HMODULE32toPE_MODULE
+ * HMODULE32toPE_MODREF
*
- * small helper function to get a PE_MODULE from a passed HMODULE32
+ * small helper function to get a PE_MODREF from a passed HMODULE32
*/
-static PE_MODULE*
-HMODULE32toPE_MODULE(HMODULE32 hmod) {
+static PE_MODREF*
+HMODULE32toPE_MODREF(HMODULE32 hmod) {
NE_MODULE *pModule;
+ PDB32 *pdb = (PDB32*)GetCurrentProcessId();
+ PE_MODREF *pem;
if (!hmod) hmod = GetTaskDS(); /* FIXME: correct? */
- hmod = GetExePtr( hmod ); /* In case we were passed an hInstance */
-
+ hmod = MODULE_HANDLEtoHMODULE32( hmod );
+ if (!hmod) return NULL;
if (!(pModule = MODULE_GetPtr( hmod ))) return 0;
- if (!(pModule->flags & NE_FFLAGS_WIN32)) return 0;
- return pModule->pe_module;
+ pem = pdb->modref_list;
+ while (pem && pem->pe_module->mappeddll != hmod)
+ pem=pem->next;
+ return pem;
}
/**********************************************************************
@@ -106,12 +112,12 @@
LPIMAGE_RESOURCE_DIRECTORY resdirptr;
DWORD root;
HANDLE32 result;
- PE_MODULE *pe = HMODULE32toPE_MODULE(hModule);
+ PE_MODREF *pem = HMODULE32toPE_MODREF(hModule);
- if (!pe || !pe->pe_resource)
+ if (!pem || !pem->pe_resource)
return 0;
- resdirptr = pe->pe_resource;
+ resdirptr = pem->pe_resource;
root = (DWORD) resdirptr;
if ((resdirptr = GetResDirEntryW(resdirptr, type, root)) == NULL)
return 0;
@@ -130,13 +136,13 @@
*/
HANDLE32 PE_LoadResource32( HINSTANCE32 hModule, HANDLE32 hRsrc )
{
- PE_MODULE *pe = HMODULE32toPE_MODULE(hModule);
+ PE_MODREF *pem = HMODULE32toPE_MODREF(hModule);
- if (!pe || !pe->pe_resource)
+ if (!pem || !pem->pe_resource)
return 0;
if (!hRsrc)
return 0;
- return (HANDLE32) (pe->load_addr+((LPIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData);
+ return (HANDLE32) (pem->load_addr+((LPIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData);
}
@@ -169,21 +175,21 @@
DWORD PE_SizeofResource32( HINSTANCE32 hModule, HANDLE32 hRsrc )
{
- PE_MODULE *pe = HMODULE32toPE_MODULE(hModule);
+ PE_MODREF *pem = HMODULE32toPE_MODREF(hModule);
DWORD max,data;
IMAGE_DATA_DIRECTORY dir;
- if (!pe || !pe->pe_resource)
+ if (!pem || !pem->pe_resource)
return 0;
if (!hRsrc) return 0;
max=(DWORD)-1;
- dir=pe->pe_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE];
+ dir=pem->pe_module->pe_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE];
if(dir.Size)
- max=(DWORD)pe->pe_resource+dir.Size;
+ max=(DWORD)pem->pe_resource+dir.Size;
- data=((DWORD)pe->load_addr+((LPIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData);
- walk_resdir(pe->load_addr,(DWORD)pe->pe_resource,0,data,0,&max);
+ data=((DWORD)pem->load_addr+((LPIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData);
+ walk_resdir(pem->load_addr,(DWORD)pem->pe_resource,0,data,0,&max);
return max-data;
}
@@ -192,24 +198,24 @@
*/
BOOL32
PE_EnumResourceTypes32A(HMODULE32 hmod,ENUMRESTYPEPROC32A lpfun,LONG lparam) {
- PE_MODULE *pe = HMODULE32toPE_MODULE(hmod);
+ PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
int i;
LPIMAGE_RESOURCE_DIRECTORY resdir;
LPIMAGE_RESOURCE_DIRECTORY_ENTRY et;
BOOL32 ret;
HANDLE32 heap = GetProcessHeap();
- if (!pe || !pe->pe_resource)
+ if (!pem || !pem->pe_resource)
return FALSE;
- resdir = (LPIMAGE_RESOURCE_DIRECTORY)pe->pe_resource;
+ resdir = (LPIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
et =(LPIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
ret = FALSE;
for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
LPSTR name;
if (HIWORD(et[i].u1.Name))
- name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pe->pe_resource+et[i].u1.Name));
+ name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.Name));
else
name = (LPSTR)et[i].u1.Name;
ret = lpfun(hmod,name,lparam);
@@ -226,22 +232,22 @@
*/
BOOL32
PE_EnumResourceTypes32W(HMODULE32 hmod,ENUMRESTYPEPROC32W lpfun,LONG lparam) {
- PE_MODULE *pe = HMODULE32toPE_MODULE(hmod);
+ PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
int i;
LPIMAGE_RESOURCE_DIRECTORY resdir;
LPIMAGE_RESOURCE_DIRECTORY_ENTRY et;
BOOL32 ret;
- if (!pe || !pe->pe_resource)
+ if (!pem || !pem->pe_resource)
return FALSE;
- resdir = (LPIMAGE_RESOURCE_DIRECTORY)pe->pe_resource;
+ resdir = (LPIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
et =(LPIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
ret = FALSE;
for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
LPWSTR type;
if (HIWORD(et[i].u1.Name))
- type = (LPWSTR)((LPBYTE)pe->pe_resource+et[i].u1.Name);
+ type = (LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.Name);
else
type = (LPWSTR)et[i].u1.Name;
@@ -259,7 +265,7 @@
PE_EnumResourceNames32A(
HMODULE32 hmod,LPCSTR type,ENUMRESNAMEPROC32A lpfun,LONG lparam
) {
- PE_MODULE *pe = HMODULE32toPE_MODULE(hmod);
+ PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
int i;
LPIMAGE_RESOURCE_DIRECTORY resdir;
LPIMAGE_RESOURCE_DIRECTORY_ENTRY et;
@@ -267,14 +273,14 @@
HANDLE32 heap = GetProcessHeap();
LPWSTR typeW;
- if (!pe || !pe->pe_resource)
+ if (!pem || !pem->pe_resource)
return FALSE;
- resdir = (LPIMAGE_RESOURCE_DIRECTORY)pe->pe_resource;
+ resdir = (LPIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
if (HIWORD(type))
typeW = HEAP_strdupAtoW(heap,0,type);
else
typeW = (LPWSTR)type;
- resdir = GetResDirEntryW(resdir,typeW,(DWORD)pe->pe_resource);
+ resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource);
if (HIWORD(typeW))
HeapFree(heap,0,typeW);
if (!resdir)
@@ -285,7 +291,7 @@
LPSTR name;
if (HIWORD(et[i].u1.Name))
- name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pe->pe_resource+et[i].u1.Name));
+ name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.Name));
else
name = (LPSTR)et[i].u1.Name;
ret = lpfun(hmod,type,name,lparam);
@@ -303,17 +309,17 @@
PE_EnumResourceNames32W(
HMODULE32 hmod,LPCWSTR type,ENUMRESNAMEPROC32W lpfun,LONG lparam
) {
- PE_MODULE *pe = HMODULE32toPE_MODULE(hmod);
+ PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
int i;
LPIMAGE_RESOURCE_DIRECTORY resdir;
LPIMAGE_RESOURCE_DIRECTORY_ENTRY et;
BOOL32 ret;
- if (!pe || !pe->pe_resource)
+ if (!pem || !pem->pe_resource)
return FALSE;
- resdir = (LPIMAGE_RESOURCE_DIRECTORY)pe->pe_resource;
- resdir = GetResDirEntryW(resdir,type,(DWORD)pe->pe_resource);
+ resdir = (LPIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
+ resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource);
if (!resdir)
return FALSE;
et =(LPIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
@@ -321,7 +327,7 @@
for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
LPWSTR name;
if (HIWORD(et[i].u1.Name))
- name = (LPWSTR)((LPBYTE)pe->pe_resource+et[i].u1.Name);
+ name = (LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.Name);
else
name = (LPWSTR)et[i].u1.Name;
ret = lpfun(hmod,type,name,lparam);
@@ -339,7 +345,7 @@
HMODULE32 hmod,LPCSTR name,LPCSTR type,ENUMRESLANGPROC32A lpfun,
LONG lparam
) {
- PE_MODULE *pe = HMODULE32toPE_MODULE(hmod);
+ PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
int i;
LPIMAGE_RESOURCE_DIRECTORY resdir;
LPIMAGE_RESOURCE_DIRECTORY_ENTRY et;
@@ -347,15 +353,15 @@
HANDLE32 heap = GetProcessHeap();
LPWSTR nameW,typeW;
- if (!pe || !pe->pe_resource)
+ if (!pem || !pem->pe_resource)
return FALSE;
- resdir = (LPIMAGE_RESOURCE_DIRECTORY)pe->pe_resource;
+ resdir = (LPIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
if (HIWORD(name))
nameW = HEAP_strdupAtoW(heap,0,name);
else
nameW = (LPWSTR)name;
- resdir = GetResDirEntryW(resdir,nameW,(DWORD)pe->pe_resource);
+ resdir = GetResDirEntryW(resdir,nameW,(DWORD)pem->pe_resource);
if (HIWORD(nameW))
HeapFree(heap,0,nameW);
if (!resdir)
@@ -364,7 +370,7 @@
typeW = HEAP_strdupAtoW(heap,0,type);
else
typeW = (LPWSTR)type;
- resdir = GetResDirEntryW(resdir,typeW,(DWORD)pe->pe_resource);
+ resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource);
if (HIWORD(typeW))
HeapFree(heap,0,typeW);
if (!resdir)
@@ -372,7 +378,7 @@
et =(LPIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
ret = FALSE;
for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
- /* languages are just ids... I hope */
+ /* languages are just ids... I hopem */
ret = lpfun(hmod,name,type,et[i].u1.Id,lparam);
if (!ret)
break;
@@ -388,20 +394,20 @@
HMODULE32 hmod,LPCWSTR name,LPCWSTR type,ENUMRESLANGPROC32W lpfun,
LONG lparam
) {
- PE_MODULE *pe = HMODULE32toPE_MODULE(hmod);
+ PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
int i;
LPIMAGE_RESOURCE_DIRECTORY resdir;
LPIMAGE_RESOURCE_DIRECTORY_ENTRY et;
BOOL32 ret;
- if (!pe || !pe->pe_resource)
+ if (!pem || !pem->pe_resource)
return FALSE;
- resdir = (LPIMAGE_RESOURCE_DIRECTORY)pe->pe_resource;
- resdir = GetResDirEntryW(resdir,name,(DWORD)pe->pe_resource);
+ resdir = (LPIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
+ resdir = GetResDirEntryW(resdir,name,(DWORD)pem->pe_resource);
if (!resdir)
return FALSE;
- resdir = GetResDirEntryW(resdir,type,(DWORD)pe->pe_resource);
+ resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource);
if (!resdir)
return FALSE;
et =(LPIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
diff --git a/loader/resource.c b/loader/resource.c
index 31c6453..2654396 100644
--- a/loader/resource.c
+++ b/loader/resource.c
@@ -18,6 +18,7 @@
#include "global.h"
#include "heap.h"
#include "neexe.h"
+#include "task.h"
#include "accel.h"
#include "module.h"
#include "resource.h"
@@ -33,6 +34,11 @@
extern WORD WINE_LanguageId;
+/* error message when 16-bit resource function is called for Win32 module */
+static const char* NEWin32FailureString = "fails with Win32 module\n";
+/* error message when 32-bit resource function is called for Win16 module */
+static const char* PEWin16FailureString = "fails with Win16 module\n";
+
/**********************************************************************
* FindResource16 (KERNEL.60)
*/
@@ -40,9 +46,10 @@
{
NE_MODULE *pModule;
- hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
+ hModule = MODULE_HANDLEtoHMODULE16( hModule );
dprintf_resource(stddeb, "FindResource16: module=%04x type=", hModule );
PrintId( type );
+
if (HIWORD(name)) /* Check for '#xxx' name */
{
char *ptr = PTR_SEG_TO_LIN( name );
@@ -50,20 +57,23 @@
if (!(name = (SEGPTR)atoi( ptr + 1 ))) return 0;
}
}
+
dprintf_resource( stddeb, " name=" );
PrintId( name );
dprintf_resource( stddeb, "\n" );
- if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
-#ifndef WINELIB
- if (pModule->flags & NE_FFLAGS_WIN32)
+
+ if ((pModule = MODULE_GetPtr( hModule )))
{
- fprintf(stderr,"Don't know how to FindResource16() for Win32 module\n");
- return 0;
- }
- return NE_FindResource( hModule, type, name );
+#ifndef WINELIB
+ if (pModule->flags & NE_FFLAGS_WIN32)
+ fprintf(stderr,"FindResource16: %s", NEWin32FailureString);
+ else
+ return NE_FindResource( hModule, type, name );
#else
- return LIBRES_FindResource16( hModule, name, type );
+ return LIBRES_FindResource16( hModule, name, type );
#endif
+ }
+ return 0;
}
@@ -109,7 +119,7 @@
NE_MODULE *pModule;
if (!hModule) hModule = GetTaskDS();
- hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
+ hModule = MODULE_HANDLEtoHMODULE32( hModule );
dprintf_resource(stddeb, "FindResource32W: module=%08x type=", hModule );
if (HIWORD(type))
dprintf_resource(stddeb,"%p",type);
@@ -145,21 +155,22 @@
{
NE_MODULE *pModule;
- hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
+ hModule = MODULE_HANDLEtoHMODULE16( hModule );
dprintf_resource(stddeb, "LoadResource16: module=%04x res=%04x\n",
hModule, hRsrc );
if (!hRsrc) return 0;
- if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
-#ifndef WINELIB
- if (pModule->flags & NE_FFLAGS_WIN32)
+ if ((pModule = MODULE_GetPtr( hModule )))
{
- fprintf(stderr,"Don't know how to LoadResource16() for Win32 module\n");
- return 0;
- }
- return NE_LoadResource( hModule, hRsrc );
+#ifndef WINELIB
+ if (pModule->flags & NE_FFLAGS_WIN32)
+ fprintf(stderr,"LoadResource16: %s", NEWin32FailureString);
+ else
+ return NE_LoadResource( hModule, hRsrc );
#else
- return LIBRES_LoadResource( hModule, hRsrc );
+ return LIBRES_LoadResource( hModule, hRsrc );
#endif
+ }
+ return 0;
}
/**********************************************************************
@@ -171,7 +182,7 @@
NE_MODULE *pModule;
if (!hModule) hModule = GetTaskDS(); /* FIXME: see FindResource32W */
- hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
+ hModule = MODULE_HANDLEtoHMODULE32( hModule );
dprintf_resource(stddeb, "LoadResource32: module=%04x res=%04x\n",
hModule, hRsrc );
if (!hRsrc) return 0;
@@ -179,7 +190,7 @@
if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
if (!(pModule->flags & NE_FFLAGS_WIN32))
{
- fprintf(stderr,"LoadResource32: tried to load a non win32 resource.\n");
+ fprintf(stderr,"LoadResource32: %s", PEWin16FailureString );
return 0; /* FIXME? */
}
return PE_LoadResource32(hModule,hRsrc);
@@ -201,11 +212,11 @@
dprintf_resource(stddeb, "LockResource: handle=%04x\n", handle );
if (!handle) return (SEGPTR)0;
- hModule = GetExePtr( handle );
+ hModule = MODULE_HANDLEtoHMODULE16( handle );
if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
if (pModule->flags & NE_FFLAGS_WIN32)
{
- fprintf(stderr,"Don't know how to LockResource() for Win32 module\n");
+ fprintf(stderr,"LockResource16: %s", NEWin32FailureString);
return 0;
}
return NE_LockResource( hModule, handle );
@@ -223,11 +234,11 @@
dprintf_resource(stddeb, "LockResource: handle=%04x\n", handle );
if (!handle) return NULL;
- hModule = GetExePtr( handle );
+ hModule = MODULE_HANDLEtoHMODULE16( handle );
if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
if (pModule->flags & NE_FFLAGS_WIN32)
{
- fprintf(stderr,"Don't know how to LockResource16() for Win32 module\n");
+ fprintf(stderr,"LockResource16: %s", NEWin32FailureString);
return 0;
}
return (LPSTR)PTR_SEG_TO_LIN( NE_LockResource( hModule, handle ) );
@@ -257,11 +268,11 @@
dprintf_resource(stddeb, "FreeResource16: handle=%04x\n", handle );
if (!handle) return FALSE;
- hModule = GetExePtr( handle );
+ hModule = MODULE_HANDLEtoHMODULE16( handle );
if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
if (pModule->flags & NE_FFLAGS_WIN32)
{
- fprintf(stderr,"Don't know how to FreeResource16() for Win32 module\n");
+ fprintf(stderr,"FreeResource16: %s", NEWin32FailureString);
return 0;
}
return NE_FreeResource( hModule, handle );
@@ -287,7 +298,7 @@
{
NE_MODULE *pModule;
- hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
+ hModule = MODULE_HANDLEtoHMODULE16( hModule );
dprintf_resource(stddeb, "AccessResource16: module=%04x res=%04x\n",
hModule, hRsrc );
if (!hRsrc) return 0;
@@ -295,7 +306,7 @@
#ifndef WINELIB
if (pModule->flags & NE_FFLAGS_WIN32)
{
- fprintf(stderr,"Don't know how to AccessResource16() for Win32 module\n");
+ fprintf(stderr,"AccessResource16: %s", NEWin32FailureString);
return 0;
}
return NE_AccessResource( hModule, hRsrc );
@@ -310,7 +321,7 @@
*/
INT32 WINAPI AccessResource32( HINSTANCE32 hModule, HRSRC32 hRsrc )
{
- hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
+ hModule = MODULE_HANDLEtoHMODULE32( hModule );
dprintf_resource(stddeb, "AccessResource: module=%04x res=%04x\n",
hModule, hRsrc );
if (!hRsrc) return 0;
@@ -326,14 +337,14 @@
{
NE_MODULE *pModule;
- hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
+ hModule = MODULE_HANDLEtoHMODULE16( hModule );
dprintf_resource(stddeb, "SizeofResource16: module=%04x res=%04x\n",
hModule, hRsrc );
if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
#ifndef WINELIB
if (pModule->flags & NE_FFLAGS_WIN32)
{
- fprintf(stderr,"Don't know how to SizeOfResource16() for Win32 module\n");
+ fprintf(stderr,"SizeOfResource16: %s", NEWin32FailureString);
return 0;
}
return NE_SizeofResource( hModule, hRsrc );
@@ -348,7 +359,7 @@
*/
DWORD WINAPI SizeofResource32( HINSTANCE32 hModule, HRSRC32 hRsrc )
{
- hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
+ hModule = MODULE_HANDLEtoHMODULE32( hModule );
dprintf_resource(stddeb, "SizeofResource32: module=%04x res=%04x\n",
hModule, hRsrc );
#ifndef WINELIB
@@ -367,7 +378,7 @@
{
NE_MODULE *pModule;
- hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */
+ hModule = MODULE_HANDLEtoHMODULE16( hModule );
dprintf_resource(stddeb, "AllocResource: module=%04x res=%04x size=%ld\n",
hModule, hRsrc, size );
if (!hRsrc) return 0;
@@ -375,7 +386,7 @@
#ifndef WINELIB
if (pModule->flags & NE_FFLAGS_WIN32)
{
- fprintf(stderr,"Don't know how to AllocResource() for Win32 module\n");
+ fprintf(stderr,"AllocResource16: %s", NEWin32FailureString);
return 0;
}
return NE_AllocResource( hModule, hRsrc, size );
@@ -394,7 +405,7 @@
{
dprintf_resource(stddeb,"DirectResAlloc(%04x,%04x,%04x)\n",
hInstance, wType, wSize );
- hInstance = GetExePtr(hInstance);
+ hInstance = MODULE_HANDLEtoHMODULE16(hInstance);
if(!hInstance)return 0;
if(wType != 0x10) /* 0x10 is the only observed value, passed from
CreateCursorIndirect. */
@@ -405,6 +416,9 @@
/**********************************************************************
* LoadAccelerators16 [USER.177]
+ *
+ * FIXME: this code leaks memory because HACCEL must be a result of LoadResource()
+ * (see TWIN for hints).
*/
HACCEL16 WINAPI LoadAccelerators16(HINSTANCE16 instance, SEGPTR lpTableName)
{
@@ -578,6 +592,8 @@
int string_num;
int i;
+ if (HIWORD(resource_id)==0xFFFF) /* netscape 3 passes this */
+ resource_id = (UINT32)(-((INT32)resource_id));
dprintf_resource(stddeb, "LoadString: instance = %04x, id = %04x, buffer = %08x, "
"length = %d\n", instance, (int)resource_id, (int) buffer, buflen);
@@ -747,15 +763,24 @@
/**********************************************************************
* SetResourceHandler (KERNEL.43)
*/
-FARPROC16 WINAPI SetResourceHandler( HINSTANCE16 instance, SEGPTR s,
- FARPROC16 farproc )
+FARPROC16 WINAPI SetResourceHandler( HMODULE16 hModule, SEGPTR s,
+ FARPROC16 resourceHandler )
{
- if (HIWORD(s))
- fprintf(stderr,"SetResourceHandler(%04x,%s,%p), empty STUB!\n",
- instance,(char*)PTR_SEG_TO_LIN(s),farproc);
- else
- fprintf(stderr,"SetResourceHandler(%04x,0x%04x,%p), empty STUB!\n",
- instance,LOWORD(s),farproc);
+ NE_MODULE *pModule;
+
+ hModule = GetExePtr( hModule );
+
+ dprintf_resource(stddeb, "SetResourceHandler: module=%04x type=", hModule );
+ PrintId( s );
+ dprintf_resource( stddeb, "\n" );
+
+ if ((pModule = MODULE_GetPtr( hModule )))
+ {
+ if (pModule->flags & NE_FFLAGS_WIN32)
+ fprintf(stderr,"SetResourceHandler: %s", NEWin32FailureString);
+ else if (pModule->res_table)
+ return NE_SetResourceHandler( hModule, s, resourceHandler );
+ }
return NULL;
}
diff --git a/loader/task.c b/loader/task.c
index 467548c..3266976 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -9,7 +9,7 @@
#include <string.h>
#include "windows.h"
-#include "task.h"
+#include "user.h"
#include "callback.h"
#include "file.h"
#include "global.h"
@@ -40,9 +40,9 @@
/* Min. number of thunks allocated when creating a new segment */
#define MIN_THUNKS 32
-extern INT32 WINSOCK_DeleteTaskWSI( TDB* pTask, struct _WSINFO* pwsi );
-extern void USER_AppExit( HTASK16, HINSTANCE16, HQUEUE16 );
-extern void PE_InitTls( PE_MODULE *module );
+extern INT32 WINSOCK_DeleteTaskWSI( TDB* pTask, struct _WSINFO* );
+extern BOOL32 MODULE_FreeModule( HMODULE16 hModule, TDB* ptaskContext );
+extern void PE_InitTls( PDB32 *pdb32 );
/* Saved 16-bit stack for current process (Win16 only) */
DWORD IF1632_Saved16_ss_sp = 0;
@@ -370,12 +370,16 @@
extern void InitTask( CONTEXT *context );
+ FARPROC32 entry = (FARPROC32)(pCurrentProcess->exe_modref->load_addr +
+ pCurrentProcess->exe_modref->pe_module->pe_header->OptionalHeader.AddressOfEntryPoint);
+
InitTask( NULL );
InitApp( pTask->hModule );
__asm__ __volatile__("movw %w0,%%fs"::"r" (pCurrentThread->teb_sel));
- PE_InitializeDLLs( pTask->hModule, DLL_PROCESS_ATTACH, (LPVOID)-1 );
- exit_code = CallTaskStart32((FARPROC32)(pModule->pe_module->load_addr +
- pModule->pe_module->pe_header->OptionalHeader.AddressOfEntryPoint) );
+
+ PE_InitializeDLLs( pCurrentProcess, DLL_PROCESS_ATTACH, (LPVOID)-1 );
+ dprintf_relay( stddeb, "CallTo32(entryproc=%p)\n", entry );
+ exit_code = entry();
TASK_KillCurrentTask( exit_code );
}
else
@@ -437,6 +441,7 @@
STACK32FRAME *frame32;
#ifndef WINELIB32
extern DWORD CALLTO16_RetAddr_word;
+ extern void CALLTO16_Restore();
#endif
if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
@@ -546,18 +551,21 @@
/* Create the Win32 part of the task */
- pdb32 = PROCESS_Create( pTask );
+ pCurrentProcess = pdb32 = PROCESS_Create( pTask, cmdLine );
pdb32->task = hTask;
if (pModule->flags & NE_FFLAGS_WIN32)
{
+ /*
LPTHREAD_START_ROUTINE start =
- (LPTHREAD_START_ROUTINE)(pModule->pe_module->load_addr +
- pModule->pe_module->pe_header->OptionalHeader.AddressOfEntryPoint);
- pTask->thdb = THREAD_Create( pdb32, 0, start );
+ (LPTHREAD_START_ROUTINE)(
+ pCurrentProcess->exe_modref->load_addr +
+ pCurrentProcess->exe_modref->pe_module->pe_header->OptionalHeader.AddressOfEntryPoint);
+ */
+ pTask->thdb = THREAD_Create( pdb32, 0, 0 );
#ifndef WINELIB
/* FIXME: should not be done here */
pCurrentThread = pTask->thdb;
- PE_InitTls( pModule->pe_module );
+ PE_InitTls( pdb32 );
#endif
}
else
@@ -575,6 +583,7 @@
frame32->ebx = 0;
frame32->ebp = 0;
#ifndef WINELIB
+ frame32->restore_addr = (DWORD)CALLTO16_Restore;
frame32->retaddr = (DWORD)TASK_CallToStart;
frame32->codeselector = WINE_CODE_SELECTOR;
#endif
@@ -613,10 +622,12 @@
{
if (pModule->flags & NE_FFLAGS_WIN32)
{
- DBG_ADDR addr = { NULL, 0, pModule->pe_module->load_addr +
- pModule->pe_module->pe_header->OptionalHeader.AddressOfEntryPoint };
+ /*
+ DBG_ADDR addr = { NULL, 0, pCurrentProcess->exe_modref->load_addr +
+ pCurrentProcess->exe_modref->pe_module->pe_header->OptionalHeader.AddressOfEntryPoint };
fprintf( stderr, "Win32 task '%s': ", name );
DEBUG_AddBreakpoint( &addr );
+ */
}
else
{
@@ -656,7 +667,7 @@
/* Free the task module */
- FreeModule16( pTask->hModule );
+ MODULE_FreeModule( pTask->hModule, pTask );
/* Free the selector aliases */
@@ -691,17 +702,16 @@
dprintf_task(stddeb, "Killing task %04x\n", hCurrentTask );
- /* Clean up sockets */
+ /* Delete active sockets */
- if( pTask->pwsi )
- {
- dprintf_task(stddeb, "\tremoving socket table\n");
+ if( pTask->pwsi )
WINSOCK_DeleteTaskWSI( pTask, pTask->pwsi );
- }
/* Perform USER cleanup */
- USER_AppExit( hCurrentTask, pTask->hInstance, pTask->hQueue );
+ if (pTask->userhandler)
+ pTask->userhandler( hCurrentTask, USIG_TERMINATION, 0,
+ pTask->hInstance, pTask->hQueue );
if (hTaskToKill && (hTaskToKill != hCurrentTask))
{
@@ -867,6 +877,8 @@
/***********************************************************************
* InitTask (KERNEL.91)
+ *
+ * Called by the application startup code.
*/
void WINAPI InitTask( CONTEXT *context )
{
@@ -880,7 +892,13 @@
if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return;
if (!(pModule = MODULE_GetPtr( pTask->hModule ))) return;
+ /* This is a hack to install task USER signal handler before
+ * implicitly loaded DLLs are initialized (see windows/user.c) */
+
+ pTask->userhandler = (USERSIGNALPROC)&USER_SignalProc;
+
#ifndef WINELIB
+ /* Initialize implicitly loaded DLLs */
NE_InitializeDLLs( pTask->hModule );
#endif
@@ -1374,6 +1392,8 @@
/***********************************************************************
* SetTaskSignalProc (KERNEL.38)
+ *
+ * Real 16-bit interface is provided by the THUNK_SetTaskSignalProc.
*/
FARPROC16 WINAPI SetTaskSignalProc( HTASK16 hTask, FARPROC16 proc )
{
@@ -1382,8 +1402,8 @@
if (!hTask) hTask = hCurrentTask;
if (!(pTask = (TDB *)GlobalLock16( hTask ))) return NULL;
- oldProc = pTask->userhandler;
- pTask->userhandler = proc;
+ oldProc = (FARPROC16)pTask->userhandler;
+ pTask->userhandler = (USERSIGNALPROC)proc;
return oldProc;
}
@@ -1464,7 +1484,6 @@
return 0;
}
-
/***********************************************************************
* TaskFirst (TOOLHELP.63)
*/