Release 980517
Sun May 17 16:23:56 1998 Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de>
* [file/profile.c]
Fix the return value of PROFILE_GetSection
* [misc/crtdll.c]
Do _getdrive, fix _chdrive.
* [misc/commdlg.c]
First cut at ChooseColor[WA].
* [misc/network.c]
Do something sensible for WNetGetDirectoryType16.
Sun May 17 10:21:35 1998 Andreas Mohr <100.30936@germany.net>
* [controls/menu.c]
Fixed disabled sub menus with MF_BYPOSITION that were not disabled.
* [misc/crtdll.c] [relay32/crtdll.spec] [include/winerror.h]
Implemented fscanf, fsetpos, _access, _fpreset (thanks to Uwe Bonnes),
and _ltoa.
* [loader/task.c]
MakeProcInstance: must use CURRENT_DS if hInst == NULL.
* [misc/shell.c]
SHELL_GetResourceTable, InternalExtractIcon: fixed broken .ICO handling
* [windows/winpos.c]
DeferWindowPos: removed "same parent" requirement.
Which doc states that this is required ?
Sat May 16 20:08:11 1998 Alexandre Julliard <julliard@lrc.epfl.ch>
* [loader/module.c] [loader/ne/module.c]
More NE module cleanups.
* [loader/task.c]
Fixed SwitchStackBack().
Fri May 15 10:04:27 1998 Marcus Meissner <marcus@jet.franken.de>
* [configure.in][inlcude/acconfig.h]
Fixed broken OSS check, added check for working sigaltstack,
fixed broken statfs checks on some linux systems.
* [files/directory.c][loader/pe_image.c][relay32/builtin.c]
[loader/module.c]
Added handling of win32 module pathnames.
* [relay32/wnaspi32.spec]
New file.
* [misc/lzexpand.c]
LZCopy auto-decompresses LZ compressed files, even if they are not
specially flagged. Fixes some InstallShield problems.
* [misc/registry.c]
Some fixes for RegQueryInfoKey (reference program monkey.exe
from Win32 SDK works now better). Probably still has faults.
Fri May 15 08:58:58 1998 Martin Boehme <boehme@informatik.mu-luebeck.de>
* [graphics/mapping.c] [include/dc.h] [include/gdi.h] [objects/dc.c]
Reworked the way world transformations and mapping modes are handled
so that both of these transformations can be computed in a single
step.
* [graphics/painting.c] [graphics/path.c] [include/path.h]
More GDI path support.
* [graphics/x11drv/graphics.c]
Fixed the return value of GRAPH_DrawArc for the zero height /
zero width case to reflect Windows' behaviour.
* [include/windows.h] [relay32/gdi32.spec] [objects/dc.c]
Implemented ModifyWorldTransform and CombineTransform.
Tue May 14 18:03:46 1998 Eric Kohl <ekohl@abo.rhein-zeitung.de>
* [controls/commctrl.c][relay32/comctl32.spec]
[controls/*.c][include/*.h]
Implemented InitCommonControlsEx (dll version 4.72 compatible).
InitCommonControls calls ImageCommonControlsEx.
Registering code of the common controls had to be changed
(see XXXX_Register functions).
* [controls/status.c][include/commctrl.h][include/status.h]
Implemented most new features and fixed the look and feel.
* [contols/commctrl.c][include/commctrl.h][relay32/comctl32.spec]
Implemented MenuHelp (incomplete).
* [controls/status.c][controls/progress.c]
Changed allocation strategy for control specific memory.
* [controls/header.c][include/header.h][include/commctrl.h]
First implementation of header control.
* [windows/defwnd.c][windows/syscolors.c]
Fixed default control colors for Win95 look.
* [windows/nonclient.c]
Fixed off by one error for Win95 look. Top border of child windows
should be visible.
* [misc/imagelist.h]
Improved documentation and fixed some bugs.
Thu May 14 15:42:21 1998 Robert Wilhelm <robert@physiol.med.tu-muenchen.de>
* [relay32/crtdll.spec]
Added hypot,j0,j1,jn and ceil.
Wed May 13 19:10:10 1998 Pascal Cuoq <pcuoq@ens-lyon.fr>
* [controls/listbox.c]
Item height is now exactly font height.
Wine listboxes now behave like Windows' when they are
created without WS_VSCROLL but the program subsequently
calls ShowScrollBar or SetScrollInfo.
Wed May 13 18:33:01 1998 Ulrich Weigand <weigand@informatik.uni-erlangen.de>
* [relay32/relay386.c]
Restore ES also in the non-debug case.
* [windows/event.c]
Bugfix: Blocking TSXNextEvent could deadlock Wine.
* [win32/process.c] [windows/message.c]
Silly stubs for MsgWaitForMultipleObjects / PostThreadMessage
that make some programs run better.
* [windows/winproc.c]
WINPROC_MapMsg32Ato16/16To32A: added WM_NOTIFY.
* [win32/kernel32.c]
Added 16->32 thunking and improved 32->16 thunking functions.
* [tools/build.c]
Added new variant of CallFrom16 stub for use with Win95 thunks.
* [if1632/kernel.spec] [if1632/builtin.c] [win32/kernel32.c]
Added a few undocumented KERNEL functions.
* [loader/ne/module.c] [loader/ne/segment.c]
Call DllEntryPoint for 16-bit DLLs with subsystem >= 4.0.
* [win32/kernel32.spec] [win32/wow32.spec] [win32/ordinals.c]
Use names from the Oct 94 beta release for undoc. functions.
Wed May 13 14:18:26 1998 Matthew Becker <mbecker@glasscity.net>
* [misc/registry.c]
Code cleanup.
* [misc/cpu.c]
Commented out the registry puts temporarily.
* [programs/regtest/*]
New registry testing program.
Tue May 12 22:54:03 1998 Michael Mess <michael@kawo2.rwth-aachen.de>
* [multimedia/audio.c]
ioctl's do not commute in /dev/dsp initialization.
Tue May 12 20:11:42 1998 Karl Garrison <karlos@eznet.net>
* [win32/console.c]
Implemented SetConsoleTextAttribute, FillConsoleOutputCharacter.
Improved cursor positioning.
This allows for text colors in an xterm, rxvt, or console.
Tue May 12 17:57:52 1998 Petter Reinholdtsen <pere@td.org.uit.no>
* [Makefile.in]
Create prefix/{bin|lib} directories if missing during install.
Sun May 10 19:37:51 1998 Jan Willamowius <jan@janhh.shnet.org>
* [multimedia/mmio.c]
Have mmioSetBuffer return success (0), so Corel Draw 4
keeps working. (IO is still unbuffered)
Wed May 6 16:57:55 1998 James Juran <jrj120@psu.edu>
* [Makefile.in] [Make.rules.in]
Changed "make clean" to remove `textedit` backup files (*%)
* [controls/menu.c][graphics/x11drv/xfont.c][include/libres.h]
[loader/main.c][loader/ne/module.c][scheduler/synchro.c]
[win32/time.c][windows/winpos.c][include/windows.h]
Fixed miscellaneous compilation warnings.
* [misc/main.c][miscemu/main.c][include/main.h]
Moved prototypes to new include file main.h, various cleanups.
Tue May 5 21:05:06 1998 Morten Welinder <terra@diku.dk>
* [misc/winsock.c]
Don't refer to __FreeBSD__ when HAVE_STRERROR is meant.
* [misc/debugstr.c]
For debug_dumpstrSend, send strings to stderr.
Tue May 5 21:47:40 1998 Huw D M Davies <h.davies1@physics.oxford.ac.uk>
* [objects/region.c]
Fix for REGION_RegionOp() if newReg is one of the source regions.
Tue May 5 18:27:32 1998 Jim Peterson <jspeter@roanoke.infi.net>
* [misc/main.c]
Add '-h/-help' option and print WINE_RELEASE_INFO with usage message.
* [misc/spy.c]
Realign trace messages.
Tue May 5 15:46:47 1998 Donnie V. Savage <dsavage@cisco.com>
* [graphics/ddraw.c]
Fixed compile warnings
* [misc/winsock.c]
Warnings should not be errors.
Tue May 5 13:40:42 1998 Jim Peterson <jspeter@roanoke.infi.net>
* [*/*]
Remove many warnings through explicit casts, added #include's,
and corrected printf formats.
Tue May 5 05:18:12 1998 Insomnia (Stea Greene) <insomnia@core.binghamton.edu>
* [graphics/ddraw.c]
Kept unchanged portion of old palette when changing only a few
palette entries. Really should only deallocate the changed cells.
This make StarCraft work almost perfectly (sound overflows still
cause static).
Mon May 4 15:04:57 1998 Alexander V. Lukyanov <lav@long.yar.ru>
* [misc/lstr.c]
FormatMessage: terminate string on %0, undo linefeed strip.
diff --git a/loader/libres.c b/loader/libres.c
index 5dafc8f..eb9598b 100644
--- a/loader/libres.c
+++ b/loader/libres.c
@@ -76,7 +76,7 @@
for(Res=ResBlock->Resources; *Res; Res++)
if(name)
{
- if((*Res)->type==typeid && !lstrcmpi32W((*Res)->name,name))
+ if((*Res)->type==typeid && !lstrcmpi32W((LPCWSTR)(*Res)->name,name))
return (HRSRC32)*Res;
}
else
diff --git a/loader/main.c b/loader/main.c
index 5ab11da..5b1eaec 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -14,6 +14,7 @@
#include "bitmap.h"
#include "comm.h"
#include "win.h"
+#include "main.h"
#include "menu.h"
#include "atom.h"
#include "dialog.h"
diff --git a/loader/module.c b/loader/module.c
index 63568ee..17f1bb0 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -25,18 +25,11 @@
#include "selectors.h"
#include "stackframe.h"
#include "task.h"
-#include "toolhelp.h"
#include "debug.h"
#include "callback.h"
extern BOOL32 THREAD_InitDone;
-extern HMODULE16 hFirstModule; /* FIXME */
-static HMODULE16 hCachedModule = 0; /* Module cached by MODULE_OpenFile */
-
-static HMODULE32 MODULE_LoadModule(LPCSTR name,BOOL32 force) { return 0; }
-HMODULE32 (*fnBUILTIN_LoadModule)(LPCSTR name,BOOL32 force) = MODULE_LoadModule;
-
/*************************************************************************
* MODULE32_LookupHMODULE
@@ -58,116 +51,6 @@
return NULL;
}
-/***********************************************************************
- * MODULE_GetPtr16
- */
-NE_MODULE *MODULE_GetPtr16( HMODULE16 hModule )
-{
- return (NE_MODULE*)GlobalLock16( GetExePtr(hModule) );
-}
-
-
-/***********************************************************************
- * MODULE_GetPtr32
- */
-NE_MODULE *MODULE_GetPtr32( HMODULE32 hModule )
-{
- return (NE_MODULE*)GlobalLock16( MODULE_HANDLEtoHMODULE16(hModule) );
-}
-
-/***********************************************************************
- * MODULE_HANDLEtoHMODULE16
- */
-HMODULE16
-MODULE_HANDLEtoHMODULE16(HANDLE32 handle) {
- NE_MODULE *pModule;
-
- if (HIWORD(handle))
- {
- WARN(module,"looking up 0x%08x in win16 function!\n",handle);
- /* this is a HMODULE32 */
-
- /* walk the list looking for the correct startaddress */
- pModule = (NE_MODULE *)GlobalLock16( hFirstModule );
- while (pModule)
- {
- if (pModule->module32 == handle) return pModule->self;
- pModule = (NE_MODULE*)GlobalLock16(pModule->next);
- }
- return 0;
- }
- return GetExePtr(handle);
-}
-
-/***********************************************************************
- * MODULE_OpenFile
- */
-int MODULE_OpenFile( HMODULE32 hModule )
-{
- NE_MODULE *pModule;
- DOS_FULL_NAME full_name;
- char *name;
-
- static int cachedfd = -1;
-
- hModule = MODULE_HANDLEtoHMODULE16(hModule);
- TRACE(module, "(%04x) cache: mod=%04x fd=%d\n",
- hModule, hCachedModule, cachedfd );
- if (!(pModule = MODULE_GetPtr32( hModule ))) return -1;
- if (hCachedModule == hModule) return cachedfd;
- close( cachedfd );
- hCachedModule = hModule;
- name = NE_MODULE_NAME( pModule );
- if (!DOSFS_GetFullName( name, TRUE, &full_name ) ||
- (cachedfd = open( full_name.long_name, O_RDONLY )) == -1)
- WARN( module, "Can't open file '%s' for module %04x\n",
- name, hModule );
- TRACE(module, "opened '%s' -> %d\n",
- name, cachedfd );
- return cachedfd;
-}
-
-
-/***********************************************************************
- * MODULE_CreateInstance
- *
- * If lib_only is TRUE, handle the module like a library even if it is a .EXE
- */
-HINSTANCE16 MODULE_CreateInstance( HMODULE16 hModule, HINSTANCE16 *prev,
- BOOL32 lib_only )
-{
- SEGTABLEENTRY *pSegment;
- NE_MODULE *pModule;
- int minsize;
- HINSTANCE16 hNewInstance;
-
- if (!(pModule = MODULE_GetPtr16( hModule ))) return 0;
- if (pModule->dgroup == 0)
- {
- if (prev) *prev = hModule;
- return hModule;
- }
-
- pSegment = NE_SEG_TABLE( pModule ) + pModule->dgroup - 1;
- if (prev) *prev = pSegment->selector;
-
- /* if it's a library, create a new instance only the first time */
- if (pSegment->selector)
- {
- if (pModule->flags & NE_FFLAGS_LIBMODULE) return pSegment->selector;
- if (lib_only) return pSegment->selector;
- }
-
- minsize = pSegment->minsize ? pSegment->minsize : 0x10000;
- if (pModule->ss == pModule->dgroup) minsize += pModule->stack_size;
- minsize += pModule->heap_size;
- hNewInstance = GLOBAL_Alloc( GMEM_ZEROINIT | GMEM_FIXED,
- minsize, hModule, FALSE, FALSE, FALSE );
- if (!hNewInstance) return 0;
- pSegment->selector = hNewInstance;
- return hNewInstance;
-}
-
/***********************************************************************
* MODULE_CreateDummyModule
@@ -312,63 +195,6 @@
}
-/***********************************************************************
- * MODULE_GetModuleName
- */
-LPSTR MODULE_GetModuleName( HMODULE32 hModule )
-{
- NE_MODULE *pModule;
- BYTE *p, len;
- static char buffer[10];
-
- if (!(pModule = MODULE_GetPtr32( hModule ))) return NULL;
- p = (BYTE *)pModule + pModule->name_table;
- len = MIN( *p, 8 );
- memcpy( buffer, p + 1, len );
- buffer[len] = '\0';
- return buffer;
-}
-
-
-/**********************************************************************
- * MODULE_FindModule
- *
- * Find a module from a path name.
- * RETURNS
- * the win16 module handle if found
- * 0 if not
- */
-HMODULE32 MODULE_FindModule16(
- LPCSTR path /* [in] path of the module to be found */
-) {
- HMODULE32 hModule = hFirstModule;
- LPCSTR filename, dotptr, modulepath, modulename;
- BYTE len, *name_table;
-
- if (!(filename = strrchr( path, '\\' ))) filename = path;
- else filename++;
- if ((dotptr = strrchr( filename, '.' )) != NULL)
- len = (BYTE)(dotptr - filename);
- else len = strlen( filename );
-
- while(hModule)
- {
- NE_MODULE *pModule = MODULE_GetPtr16( hModule );
- if (!pModule) break;
- modulepath = NE_MODULE_NAME(pModule);
- if (!(modulename = strrchr( modulepath, '\\' )))
- modulename = modulepath;
- else modulename++;
- if (!lstrcmpi32A( modulename, filename )) return hModule;
-
- name_table = (BYTE *)pModule + pModule->name_table;
- if ((*name_table == len) && !lstrncmpi32A(filename, name_table+1, len))
- return hModule;
- hModule = pModule->next;
- }
- return 0;
-}
-
/**********************************************************************
* MODULE_FindModule32
*
@@ -427,105 +253,6 @@
/**********************************************************************
- * MODULE_CallWEP
- *
- * Call a DLL's WEP, allowing it to shut down.
- * FIXME: we always pass the WEP WEP_FREE_DLL, never WEP_SYSTEM_EXIT
- */
-static BOOL16 MODULE_CallWEP( HMODULE16 hModule )
-{
- FARPROC16 WEP = (FARPROC16)0;
- WORD ordinal = NE_GetOrdinal( hModule, "WEP" );
-
- if (ordinal) WEP = NE_GetEntryPoint( hModule, ordinal );
- if (!WEP)
- {
- WARN(module, "module %04x doesn't have a WEP\n", hModule );
- return FALSE;
- }
- return Callbacks->CallWindowsExitProc( WEP, WEP_FREE_DLL );
-}
-
-
-/**********************************************************************
- * MODULE_FreeModule
- *
- * Remove a module from memory.
- */
-BOOL16 MODULE_FreeModule( HMODULE32 hModule, TDB* pTaskContext )
-{
- HMODULE16 *hPrevModule;
- NE_MODULE *pModule;
- SEGTABLEENTRY *pSegment;
- HMODULE16 *pModRef;
- int i;
-
- if (!(pModule = MODULE_GetPtr32( hModule ))) return FALSE;
- hModule = pModule->self;
-
- if (((INT16)(--pModule->count)) > 0 ) return TRUE;
- else pModule->count = 0;
-
- if (pModule->flags & NE_FFLAGS_BUILTIN)
- return FALSE; /* Can't free built-in module */
-
- if (pModule->flags & NE_FFLAGS_LIBMODULE)
- {
- MODULE_CallWEP( hModule );
-
- /* Free the objects owned by the DLL module */
-
- 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;
-
- /* Remove it from the linked list */
-
- hPrevModule = &hFirstModule;
- while (*hPrevModule && (*hPrevModule != hModule))
- {
- hPrevModule = &(MODULE_GetPtr16( *hPrevModule ))->next;
- }
- if (*hPrevModule) *hPrevModule = pModule->next;
-
- /* Free all the segments */
-
- pSegment = NE_SEG_TABLE( pModule );
- for (i = 1; i <= pModule->seg_count; i++, pSegment++)
- {
- GlobalFree16( pSegment->selector );
- }
-
- /* Free the referenced modules */
-
- pModRef = (HMODULE16*)NE_MODULE_TABLE( pModule );
- for (i = 0; i < pModule->modref_count; i++, pModRef++)
- {
- FreeModule16( *pModRef );
- }
-
- /* Free the module storage */
-
- if (pModule->nrname_handle) GlobalFree16( pModule->nrname_handle );
- if (pModule->dlls_to_init) GlobalFree16( pModule->dlls_to_init );
- GlobalFree16( hModule );
-
- /* Remove module from cache */
-
- if (hCachedModule == hModule) hCachedModule = 0;
-
- return TRUE;
-}
-
-
-/**********************************************************************
* MODULE_Load
*
* Implementation of LoadModule().
@@ -534,74 +261,34 @@
* without a preceding length byte).
* If cmd_line is NULL, the module is loaded as a library even if it is a .exe
*/
-HINSTANCE16 MODULE_Load( LPCSTR name, UINT16 uFlags,
+HINSTANCE16 MODULE_Load( LPCSTR name, BOOL32 implicit,
LPCSTR cmd_line, LPCSTR env, UINT32 show_cmd )
{
- HMODULE32 hModule;
+ HMODULE16 hModule;
HINSTANCE16 hInstance, hPrevInstance;
NE_MODULE *pModule;
- OFSTRUCT ofs;
- HFILE32 hFile;
if (__winelib)
{
+ OFSTRUCT ofs;
lstrcpyn32A( ofs.szPathName, name, sizeof(ofs.szPathName) );
if ((hModule = MODULE_CreateDummyModule( &ofs )) < 32) return hModule;
pModule = (NE_MODULE *)GlobalLock16( hModule );
- hInstance = MODULE_CreateInstance( hModule, &hPrevInstance,
- (cmd_line == NULL) );
+ hInstance = NE_CreateInstance( pModule, &hPrevInstance,
+ (cmd_line == NULL) );
}
else
{
- hModule = MODULE_FindModule16( name );
-
- if (!hModule) /* We have to load the module */
- {
- /* Try to load the built-in first if not disabled */
- if ((hModule = fnBUILTIN_LoadModule( name, FALSE )))
- return MODULE_HANDLEtoHMODULE16( hModule );
-
- if ((hFile = OpenFile32( name, &ofs, OF_READ )) == HFILE_ERROR32)
- {
- /* Now try the built-in even if disabled */
- if ((hModule = fnBUILTIN_LoadModule( name, TRUE )))
- {
- WARN(module, "Could not load Windows DLL '%s', using built-in module.\n", name );
- return MODULE_HANDLEtoHMODULE16( hModule );
- }
- return 2; /* File not found */
- }
-
- /* Create the module structure */
-
- hModule = NE_LoadModule( hFile, &ofs, uFlags, cmd_line,
- env, show_cmd );
- if (hModule < 32)
- {
- if ((hModule == 21) && cmd_line)
- hModule = PE_LoadModule( hFile, &ofs, cmd_line,
- env, show_cmd );
- }
-
- if (hModule < 32)
- fprintf( stderr, "LoadModule: can't load '%s', error=%d\n",
- name, hModule );
- _lclose32( hFile );
- return hModule;
- }
- else /* module is already loaded, just create a new data segment if it's a task */
- {
- pModule = MODULE_GetPtr32( hModule );
- hInstance = MODULE_CreateInstance( hModule, &hPrevInstance,
- (cmd_line == NULL) );
- if (hInstance != hPrevInstance) /* not a library */
- NE_LoadSegment( pModule, pModule->dgroup );
- pModule->count++;
- }
- } /* !winelib */
+ hInstance = NE_LoadModule( name, &hPrevInstance, implicit,
+ (cmd_line == NULL) );
+ if ((hInstance == 21) && cmd_line)
+ return PE_LoadModule( name, cmd_line, env, show_cmd );
+ }
/* Create a task for this instance */
+ if (hInstance < 32) return hInstance;
+ pModule = NE_GetPtr( hInstance );
if (cmd_line && !(pModule->flags & NE_FFLAGS_LIBMODULE))
{
PDB32 *pdb;
@@ -622,9 +309,8 @@
*/
HINSTANCE16 LoadModule16( LPCSTR name, LPVOID paramBlock )
{
- LOADPARAMS *params = (LOADPARAMS *)paramBlock;
- LPSTR cmd_line = (LPSTR)PTR_SEG_TO_LIN( params->cmdLine );
- LPSTR new_cmd_line;
+ LOADPARAMS *params;
+ LPSTR cmd_line, new_cmd_line;
UINT16 show_cmd = 0;
LPCVOID env = NULL;
HINSTANCE16 hInstance;
@@ -649,7 +335,7 @@
strcat( new_cmd_line, cmd_line );
if (params->hEnvironment) env = GlobalLock16( params->hEnvironment );
- hInstance = MODULE_Load( name, 0, new_cmd_line, env, show_cmd );
+ hInstance = MODULE_Load( name, FALSE, new_cmd_line, env, show_cmd );
if (params->hEnvironment) GlobalUnlock16( params->hEnvironment );
HeapFree( GetProcessHeap(), 0, new_cmd_line );
return hInstance;
@@ -682,41 +368,12 @@
CloseHandle32(pi.hThread);
#else
- return MODULE_Load( name, 0, params->lpCmdLine, params->lpEnvAddress,
+ return MODULE_Load( name, FALSE, params->lpCmdLine, params->lpEnvAddress,
*((UINT16 *)params->lpCmdShow + 1) );
#endif
}
-/**********************************************************************
- * FreeModule16 (KERNEL.46)
- */
-BOOL16 WINAPI FreeModule16( HMODULE16 hModule )
-{
- NE_MODULE *pModule;
-
- if (!(pModule = MODULE_GetPtr16( hModule ))) return FALSE;
- TRACE(module, "%s count %d\n",
- MODULE_GetModuleName(hModule), pModule->count );
-
- return MODULE_FreeModule( hModule, GlobalLock16(GetCurrentTask()) );
-}
-
-
-/**********************************************************************
- * GetModuleHandle16 (KERNEL.47)
- */
-HMODULE16 WINAPI WIN16_GetModuleHandle( SEGPTR name )
-{
- if (HIWORD(name) == 0) return GetExePtr( (HINSTANCE16)name );
- return MODULE_FindModule16( PTR_SEG_TO_LIN(name) );
-}
-
-HMODULE16 WINAPI GetModuleHandle16( LPCSTR name )
-{
- return MODULE_FindModule16( name );
-}
-
/***********************************************************************
* GetModuleHandle (KERNEL32.237)
*/
@@ -740,52 +397,23 @@
}
-/**********************************************************************
- * GetModuleUsage (KERNEL.48)
- */
-INT16 WINAPI GetModuleUsage( HINSTANCE16 hModule )
-{
- NE_MODULE *pModule;
-
- if (!(pModule = MODULE_GetPtr16( hModule ))) return 0;
- TRACE(module, "(%04x): returning %d\n",
- hModule, pModule->count );
- return pModule->count;
-}
-
-
-/**********************************************************************
- * GetModuleFileName16 (KERNEL.49)
- */
-INT16 WINAPI GetModuleFileName16( HINSTANCE16 hModule, LPSTR lpFileName,
- INT16 nSize )
-{
- NE_MODULE *pModule;
-
- if (!hModule) hModule = GetCurrentTask();
- if (!(pModule = MODULE_GetPtr16( hModule ))) return 0;
- lstrcpyn32A( lpFileName, NE_MODULE_NAME(pModule), nSize );
- TRACE(module, "%s\n", lpFileName );
- return strlen(lpFileName);
-}
-
-
/***********************************************************************
* GetModuleFileName32A (KERNEL32.235)
- * FIXME FIXME
*/
-DWORD WINAPI GetModuleFileName32A( HMODULE32 hModule, LPSTR lpFileName,
- DWORD size )
-{
- NE_MODULE *pModule;
-
- if (!hModule)
- {
- TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() );
- hModule = pTask->hInstance;
- }
- if (!(pModule = MODULE_GetPtr32( hModule ))) return 0;
- lstrcpyn32A( lpFileName, NE_MODULE_NAME(pModule), size );
+DWORD WINAPI GetModuleFileName32A(
+ HMODULE32 hModule, /* [in] module handle (32bit) */
+ LPSTR lpFileName, /* [out] filenamebuffer */
+ DWORD size /* [in] size of filenamebuffer */
+) {
+ WINE_MODREF *wm = MODULE32_LookupHMODULE(PROCESS_Current(),hModule);
+
+ if (!wm) /* can happen on start up or the like */
+ return 0;
+
+ /* FIXME: we should probably get a real long name, but wm->longname
+ * is currently a UNIX filename!
+ */
+ lstrcpyn32A( lpFileName, wm->shortname, size );
TRACE(module, "%s\n", lpFileName );
return strlen(lpFileName);
}
@@ -805,19 +433,6 @@
}
-/**********************************************************************
- * GetModuleName (KERNEL.27)
- */
-BOOL16 WINAPI GetModuleName( HINSTANCE16 hinst, LPSTR buf, INT16 nSize )
-{
- LPSTR name = MODULE_GetModuleName(hinst);
-
- if (!name) return FALSE;
- lstrcpyn32A( buf, name, nSize );
- return TRUE;
-}
-
-
/***********************************************************************
* LoadLibraryEx32W (KERNEL.513)
* FIXME
@@ -882,29 +497,8 @@
*/
BOOL32 WINAPI FreeLibrary32(HINSTANCE32 hLibModule)
{
- TRACE(module,"hLibModule=%08x\n", hLibModule);
- return MODULE_FreeModule(hLibModule,GlobalLock16(GetCurrentTask()) );
-}
-
-
-/***********************************************************************
- * LoadLibrary (KERNEL.95)
- */
-HINSTANCE16 WINAPI LoadLibrary16( LPCSTR libname )
-{
- HINSTANCE16 handle;
-
- TRACE(module, "(%08x) %s\n", (int)libname, libname);
-
- handle = MODULE_Load( libname, 0, NULL, NULL, 0 );
- if (handle == (HINSTANCE16)2) /* file not found */
- {
- char buffer[256];
- lstrcpyn32A( buffer, libname, 252 );
- strcat( buffer, ".dll" );
- handle = MODULE_Load( buffer, 0, NULL, NULL, 0 );
- }
- return handle;
+ WARN(module,"(%08x): stub\n", hLibModule);
+ return TRUE; /* FIXME */
}
@@ -919,15 +513,6 @@
}
-/***********************************************************************
- * FreeLibrary16 (KERNEL.96)
- */
-void WINAPI FreeLibrary16( HINSTANCE16 handle )
-{
- TRACE(module,"%04x\n", handle );
- FreeModule16( handle );
-}
-
/***********************************************************************
* PrivateFreeLibrary (KERNEL32)
@@ -1001,7 +586,7 @@
{
/* Winelib: Use LoadModule() only for the program itself */
if (__winelib) use_load_module = 0;
- handle = MODULE_Load( filename, 0, lpCmdLine, NULL, nCmdShow );
+ handle = MODULE_Load( filename, FALSE, lpCmdLine, NULL, nCmdShow );
if (handle == 2) /* file not found */
{
/* Check that the original file name did not have a suffix */
@@ -1011,7 +596,7 @@
{
p = filename + strlen(filename);
strcpy( p, ".exe" );
- handle = MODULE_Load( filename, 0, lpCmdLine,
+ handle = MODULE_Load( filename, FALSE, lpCmdLine,
NULL, nCmdShow );
*p = '\0'; /* Remove extension */
}
@@ -1094,7 +679,7 @@
* WIN32_GetProcAddress16 (KERNEL32.36)
* Get procaddress in 16bit module from win32... (kernel32 undoc. ordinal func)
*/
-FARPROC16 WINAPI WIN32_GetProcAddress16( HMODULE32 hModule, LPSTR name )
+FARPROC16 WINAPI WIN32_GetProcAddress16( HMODULE32 hModule, LPCSTR name )
{
WORD ordinal;
FARPROC16 ret;
@@ -1103,7 +688,12 @@
WARN(module,"hModule may not be 0!\n");
return (FARPROC16)0;
}
- hModule = MODULE_HANDLEtoHMODULE16(hModule);
+ if (HIWORD(hModule))
+ {
+ WARN( module, "hModule is Win32 handle (%08x)\n", hModule );
+ return (FARPROC16)0;
+ }
+ hModule = GetExePtr( hModule );
if (HIWORD(name)) {
ordinal = NE_GetOrdinal( hModule, name );
TRACE(module, "%04x '%s'\n",
@@ -1201,78 +791,3 @@
if (!wm || (wm->type != MODULE32_PE)) return (LPIMAGE_NT_HEADERS)0;
return PE_HEADER(wm->module);
}
-
-
-/**********************************************************************
- * GetExpWinVer (KERNEL.167)
- */
-WORD WINAPI GetExpWinVer( HMODULE16 hModule )
-{
- NE_MODULE *pModule = MODULE_GetPtr16( hModule );
- return pModule ? pModule->expected_version : 0;
-}
-
-
-/**********************************************************************
- * IsSharedSelector (KERNEL.345)
- */
-BOOL16 WINAPI IsSharedSelector( HANDLE16 selector )
-{
- /* Check whether the selector belongs to a DLL */
- NE_MODULE *pModule = MODULE_GetPtr16( selector );
- if (!pModule) return FALSE;
- return (pModule->flags & NE_FFLAGS_LIBMODULE) != 0;
-}
-
-
-/**********************************************************************
- * ModuleFirst (TOOLHELP.59)
- */
-BOOL16 WINAPI ModuleFirst( MODULEENTRY *lpme )
-{
- lpme->wNext = hFirstModule;
- return ModuleNext( lpme );
-}
-
-
-/**********************************************************************
- * ModuleNext (TOOLHELP.60)
- */
-BOOL16 WINAPI ModuleNext( MODULEENTRY *lpme )
-{
- NE_MODULE *pModule;
- char *name;
-
- if (!lpme->wNext) return FALSE;
- if (!(pModule = MODULE_GetPtr16( lpme->wNext ))) return FALSE;
- name = (char *)pModule + pModule->name_table;
- memcpy( lpme->szModule, name + 1, *name );
- lpme->szModule[(BYTE)*name] = '\0';
- lpme->hModule = lpme->wNext;
- lpme->wcUsage = pModule->count;
- strncpy( lpme->szExePath, NE_MODULE_NAME(pModule), MAX_PATH );
- lpme->szExePath[MAX_PATH] = '\0';
- lpme->wNext = pModule->next;
- return TRUE;
-}
-
-
-/**********************************************************************
- * ModuleFindName (TOOLHELP.61)
- */
-BOOL16 WINAPI ModuleFindName( MODULEENTRY *lpme, LPCSTR name )
-{
- lpme->wNext = GetModuleHandle16( name );
- return ModuleNext( lpme );
-}
-
-
-/**********************************************************************
- * ModuleFindHandle (TOOLHELP.62)
- */
-BOOL16 WINAPI ModuleFindHandle( MODULEENTRY *lpme, HMODULE16 hModule )
-{
- hModule = GetExePtr( hModule );
- lpme->wNext = hModule;
- return ModuleNext( lpme );
-}
diff --git a/loader/ne/module.c b/loader/ne/module.c
index 5cd97f8..0a2fe70 100644
--- a/loader/ne/module.c
+++ b/loader/ne/module.c
@@ -5,15 +5,36 @@
*/
#include <assert.h>
+#include <fcntl.h>
#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
#include "module.h"
+#include "file.h"
#include "ldt.h"
+#include "callback.h"
#include "heap.h"
+#include "task.h"
#include "global.h"
#include "process.h"
+#include "toolhelp.h"
#include "debug.h"
-HMODULE16 hFirstModule = 0;
+static HMODULE16 hFirstModule = 0;
+static NE_MODULE *pCachedModule = 0; /* Module cached by NE_OpenFile */
+
+static HMODULE16 NE_LoadBuiltin(LPCSTR name,BOOL32 force) { return 0; }
+HMODULE16 (*fnBUILTIN_LoadModule)(LPCSTR name,BOOL32 force) = NE_LoadBuiltin;
+
+
+/***********************************************************************
+ * NE_GetPtr
+ */
+NE_MODULE *NE_GetPtr( HMODULE16 hModule )
+{
+ return (NE_MODULE *)GlobalLock16( GetExePtr(hModule) );
+}
+
/***********************************************************************
* NE_DumpModule
@@ -26,7 +47,7 @@
WORD *pword;
NE_MODULE *pModule;
- if (!(pModule = MODULE_GetPtr16( hModule )))
+ if (!(pModule = NE_GetPtr( hModule )))
{
fprintf( stderr, "**** %04x is not a module handle\n", hModule );
return;
@@ -99,8 +120,9 @@
pword = (WORD *)((BYTE *)pModule + pModule->modref_table);
for (i = 0; i < pModule->modref_count; i++, pword++)
{
- DUMP( "%d: %04x -> '%s'\n", i, *pword,
- MODULE_GetModuleName(*pword));
+ char name[10];
+ GetModuleName( *pword, name, sizeof(name) );
+ DUMP( "%d: %04x -> '%s'\n", i, *pword, name );
}
}
else DUMP( "None\n" );
@@ -170,7 +192,7 @@
fprintf( stderr, "Module Flags Name\n" );
while (hModule)
{
- NE_MODULE *pModule = MODULE_GetPtr16( hModule );
+ NE_MODULE *pModule = NE_GetPtr( hModule );
if (!pModule)
{
fprintf( stderr, "**** Bad module %04x in list\n", hModule );
@@ -205,7 +227,7 @@
BYTE len;
NE_MODULE *pModule;
- if (!(pModule = MODULE_GetPtr16( hModule ))) return 0;
+ if (!(pModule = NE_GetPtr( hModule ))) return 0;
assert( !(pModule->flags & NE_FFLAGS_WIN32) );
TRACE( module, "(%04x,'%s')\n", hModule, name );
@@ -270,7 +292,7 @@
BYTE *p;
WORD sel, offset;
- if (!(pModule = MODULE_GetPtr16( hModule ))) return 0;
+ if (!(pModule = NE_GetPtr( hModule ))) return 0;
assert( !(pModule->flags & NE_FFLAGS_WIN32) );
p = (BYTE *)pModule + pModule->entry_table;
@@ -321,7 +343,7 @@
WORD curOrdinal = 1;
BYTE *p;
- if (!(pModule = MODULE_GetPtr16( hModule ))) return FALSE;
+ if (!(pModule = NE_GetPtr( hModule ))) return FALSE;
assert( !(pModule->flags & NE_FFLAGS_WIN32) );
p = (BYTE *)pModule + pModule->entry_table;
@@ -356,9 +378,35 @@
/***********************************************************************
+ * NE_OpenFile
+ */
+int NE_OpenFile( NE_MODULE *pModule )
+{
+ DOS_FULL_NAME full_name;
+ char *name;
+
+ static int cachedfd = -1;
+
+ TRACE( module, "(%p) cache: mod=%p fd=%d\n",
+ pModule, pCachedModule, cachedfd );
+ if (pCachedModule == pModule) return cachedfd;
+ close( cachedfd );
+ pCachedModule = pModule;
+ name = NE_MODULE_NAME( pModule );
+ if (!DOSFS_GetFullName( name, TRUE, &full_name ) ||
+ (cachedfd = open( full_name.long_name, O_RDONLY )) == -1)
+ WARN( module, "Can't open file '%s' for module %04x\n",
+ name, pModule->self );
+ TRACE(module, "opened '%s' -> %d\n",
+ name, cachedfd );
+ return cachedfd;
+}
+
+
+/***********************************************************************
* NE_LoadExeHeader
*/
-static HMODULE16 NE_LoadExeHeader( HFILE32 hFile, OFSTRUCT *ofs )
+static HMODULE16 NE_LoadExeHeader( HFILE16 hFile, OFSTRUCT *ofs )
{
IMAGE_DOS_HEADER mz_header;
IMAGE_OS2_HEADER ne_header;
@@ -374,23 +422,23 @@
((fastload && ((offset) >= fastload_offset) && \
((offset)+(size) <= fastload_offset+fastload_length)) ? \
(memcpy( buffer, fastload+(offset)-fastload_offset, (size) ), TRUE) : \
- (_llseek32( hFile, (offset), SEEK_SET), \
- _lread32( hFile, (buffer), (size) ) == (size)))
+ (_llseek16( hFile, (offset), SEEK_SET), \
+ _hread16( hFile, (buffer), (size) ) == (size)))
- _llseek32( hFile, 0, SEEK_SET );
- if ((_lread32(hFile,&mz_header,sizeof(mz_header)) != sizeof(mz_header)) ||
+ _llseek16( hFile, 0, SEEK_SET );
+ if ((_hread16(hFile,&mz_header,sizeof(mz_header)) != sizeof(mz_header)) ||
(mz_header.e_magic != IMAGE_DOS_SIGNATURE))
return (HMODULE16)11; /* invalid exe */
- _llseek32( hFile, mz_header.e_lfanew, SEEK_SET );
- if (_lread32( hFile, &ne_header, sizeof(ne_header) ) != sizeof(ne_header))
+ _llseek16( hFile, mz_header.e_lfanew, SEEK_SET );
+ if (_hread16( hFile, &ne_header, sizeof(ne_header) ) != sizeof(ne_header))
return (HMODULE16)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_OS2_SIGNATURE_LX) {
- fprintf(stderr, "Sorry, this is an OS/2 linear executable (LX) file !\n");
+ MSG("Sorry, this is an OS/2 linear executable (LX) file !\n");
return (HMODULE16)12;
}
@@ -425,7 +473,7 @@
/* Clear internal Wine flags in case they are set in the EXE file */
- pModule->flags &= ~(NE_FFLAGS_BUILTIN|NE_FFLAGS_WIN32|NE_FFLAGS_IMPLICIT);
+ pModule->flags &= ~(NE_FFLAGS_BUILTIN | NE_FFLAGS_WIN32);
/* Read the fast-load area */
@@ -437,11 +485,11 @@
fastload_offset, fastload_length );
if ((fastload = HeapAlloc( SystemHeap, 0, fastload_length )) != NULL)
{
- _llseek32( hFile, fastload_offset, SEEK_SET);
- if (_lread32(hFile, fastload, fastload_length) != fastload_length)
+ _llseek16( hFile, fastload_offset, SEEK_SET);
+ if (_hread16(hFile, fastload, fastload_length) != fastload_length)
{
HeapFree( SystemHeap, 0, fastload );
- fprintf(stderr, "Error reading fast-load area !\n");
+ WARN( module, "Error reading fast-load area!\n");
fastload = NULL;
}
}
@@ -575,8 +623,8 @@
return (HMODULE16)11; /* invalid exe */
}
buffer = GlobalLock16( pModule->nrname_handle );
- _llseek32( hFile, ne_header.nrname_tab_offset, SEEK_SET );
- if (_lread32( hFile, buffer, ne_header.nrname_tab_length )
+ _llseek16( hFile, ne_header.nrname_tab_offset, SEEK_SET );
+ if (_hread16( hFile, buffer, ne_header.nrname_tab_length )
!= ne_header.nrname_tab_length)
{
GlobalFree16( pModule->nrname_handle );
@@ -620,19 +668,18 @@
for (i = 0; i < pModule->modref_count; i++, pModRef++)
{
- char buffer[256];
+ char buffer[260];
BYTE *pstr = (BYTE *)pModule + pModule->import_table + *pModRef;
memcpy( buffer, pstr + 1, *pstr );
strcpy( buffer + *pstr, ".dll" );
TRACE(module, "Loading '%s'\n", buffer );
- if (!(*pModRef = MODULE_FindModule16( buffer )))
+ if (!(*pModRef = GetModuleHandle16( buffer )))
{
/* If the DLL is not loaded yet, load it and store */
/* its handle in the list of DLLs to initialize. */
HMODULE16 hDLL;
- if ((hDLL = MODULE_Load( buffer, NE_FFLAGS_IMPLICIT,
- NULL, NULL, 0 )) == 2)
+ if ((hDLL = NE_LoadModule( buffer, NULL, TRUE, TRUE )) == 2)
{
/* file not found */
char *p;
@@ -642,13 +689,13 @@
if (!(p = strrchr( buffer, '\\' ))) p = buffer;
memcpy( p + 1, pstr + 1, *pstr );
strcpy( p + 1 + *pstr, ".dll" );
- hDLL = MODULE_Load( buffer, NE_FFLAGS_IMPLICIT, NULL, NULL, 0);
+ hDLL = NE_LoadModule( buffer, NULL, TRUE, TRUE );
}
if (hDLL < 32)
{
/* FIXME: cleanup what was done */
- fprintf( stderr, "Could not load '%s' required by '%.*s', error = %d\n",
+ WARN( module, "Could not load '%s' required by '%.*s', error=%d\n",
buffer, *((BYTE*)pModule + pModule->name_table),
(char *)pModule + pModule->name_table + 1, hDLL );
return FALSE;
@@ -658,7 +705,7 @@
}
else /* Increment the reference count of the DLL */
{
- NE_MODULE *pOldDLL = MODULE_GetPtr16( *pModRef );
+ NE_MODULE *pOldDLL = NE_GetPtr( *pModRef );
if (pOldDLL) pOldDLL->count++;
}
}
@@ -675,24 +722,60 @@
* without a preceding length byte).
* If cmd_line is NULL, the module is loaded as a library even if it is a .exe
*/
-HINSTANCE16 NE_LoadModule( HFILE32 hFile, OFSTRUCT *ofs, UINT16 flags,
- LPCSTR cmd_line, LPCSTR env, UINT32 show_cmd )
+HINSTANCE16 NE_LoadModule( LPCSTR name, HINSTANCE16 *hPrevInstance,
+ BOOL32 implicit, BOOL32 lib_only )
{
HMODULE16 hModule;
HINSTANCE16 hInstance;
NE_MODULE *pModule;
+ HFILE16 hFile;
+ OFSTRUCT ofs;
+
+ /* Check if the module is already loaded */
+
+ if ((hModule = GetModuleHandle16( name )) != 0)
+ {
+ HINSTANCE16 prev;
+ pModule = NE_GetPtr( hModule );
+ hInstance = NE_CreateInstance( pModule, &prev, lib_only );
+ if (hInstance != prev) /* not a library */
+ NE_LoadSegment( pModule, pModule->dgroup );
+ pModule->count++;
+ if (hPrevInstance) *hPrevInstance = prev;
+ return hInstance;
+ }
+ if (hPrevInstance) *hPrevInstance = 0;
+
+ /* Try to load the built-in first if not disabled */
+
+ if ((hModule = fnBUILTIN_LoadModule( name, FALSE ))) return hModule;
+
+ if ((hFile = OpenFile16( name, &ofs, OF_READ )) == HFILE_ERROR16)
+ {
+ /* Now try the built-in even if disabled */
+ if ((hModule = fnBUILTIN_LoadModule( name, TRUE )))
+ {
+ WARN(module, "Could not load Windows DLL '%s', using built-in module.\n", name );
+ return hModule;
+ }
+ return 2; /* File not found */
+ }
/* Create the module structure */
- if ((hModule = NE_LoadExeHeader( hFile, ofs )) < 32) return hModule;
-
- pModule = MODULE_GetPtr16( hModule );
- pModule->flags |= flags; /* stamp implicitly loaded modules */
+ hModule = NE_LoadExeHeader( hFile, &ofs );
+ _lclose16( hFile );
+ if (hModule < 32) return hModule;
+ pModule = NE_GetPtr( hModule );
/* Allocate the segments for this module */
- NE_CreateSegments( hModule );
- hInstance = MODULE_CreateInstance( hModule, NULL, (cmd_line == NULL) );
+ if (!NE_CreateSegments( pModule ) ||
+ !(hInstance = NE_CreateInstance( pModule, NULL, lib_only )))
+ {
+ GlobalFreeAll( hModule );
+ return 8; /* Insufficient memory */
+ }
/* Load the referenced DLLs */
@@ -716,21 +799,307 @@
* when we load implicitly linked DLLs this will be done by InitTask().
*/
- if ((pModule->flags & (NE_FFLAGS_LIBMODULE | NE_FFLAGS_IMPLICIT)) ==
- NE_FFLAGS_LIBMODULE)
+ if (!implicit && (pModule->flags & NE_FFLAGS_LIBMODULE))
NE_InitializeDLLs( hModule );
- /* Create a task for this instance */
+ return hInstance;
+}
- if (cmd_line && !(pModule->flags & NE_FFLAGS_LIBMODULE))
+
+/***********************************************************************
+ * LoadLibrary (KERNEL.95)
+ */
+HINSTANCE16 WINAPI LoadLibrary16( LPCSTR libname )
+{
+ HINSTANCE16 handle;
+ LPCSTR p;
+ char *new_name;
+
+ TRACE(module, "(%08x) %s\n", (int)libname, libname);
+
+ /* Check for an extension */
+
+ if ((p = strrchr( libname, '.')) && !strchr( p, '/' ) && !strchr( p, '\\'))
{
- PDB32 *pdb;
-
- pModule->flags |= NE_FFLAGS_GUI;
-
- pdb = PROCESS_Create( pModule, cmd_line, env, hInstance, 0, show_cmd );
- if (pdb && (GetNumTasks() > 1)) Yield16();
+ /* An extension is present -> use the name as is */
+ return NE_LoadModule( libname, NULL, FALSE, TRUE );
}
- return hInstance;
+ /* Now append .dll before loading */
+
+ if (!(new_name = HeapAlloc( GetProcessHeap(), 0, strlen(libname) + 4 )))
+ return 0;
+ strcpy( new_name, libname );
+ strcat( new_name, ".dll" );
+ handle = NE_LoadModule( new_name, NULL, FALSE, TRUE );
+ HeapFree( GetProcessHeap(), 0, new_name );
+ return handle;
+}
+
+
+/**********************************************************************
+ * MODULE_CallWEP
+ *
+ * Call a DLL's WEP, allowing it to shut down.
+ * FIXME: we always pass the WEP WEP_FREE_DLL, never WEP_SYSTEM_EXIT
+ */
+static BOOL16 MODULE_CallWEP( HMODULE16 hModule )
+{
+ FARPROC16 WEP = (FARPROC16)0;
+ WORD ordinal = NE_GetOrdinal( hModule, "WEP" );
+
+ if (ordinal) WEP = NE_GetEntryPoint( hModule, ordinal );
+ if (!WEP)
+ {
+ WARN(module, "module %04x doesn't have a WEP\n", hModule );
+ return FALSE;
+ }
+ return Callbacks->CallWindowsExitProc( WEP, WEP_FREE_DLL );
+}
+
+
+/**********************************************************************
+ * NE_FreeModule
+ *
+ * Implementation of FreeModule16().
+ */
+static BOOL16 NE_FreeModule( HMODULE16 hModule, BOOL32 call_wep )
+{
+ HMODULE16 *hPrevModule;
+ NE_MODULE *pModule;
+ HMODULE16 *pModRef;
+ int i;
+
+ if (!(pModule = NE_GetPtr( hModule ))) return FALSE;
+ hModule = pModule->self;
+
+ TRACE( module, "%04x count %d\n", hModule, pModule->count );
+
+ if (((INT16)(--pModule->count)) > 0 ) return TRUE;
+ else pModule->count = 0;
+
+ if (pModule->flags & NE_FFLAGS_BUILTIN)
+ return FALSE; /* Can't free built-in module */
+
+ if (call_wep)
+ {
+ if (pModule->flags & NE_FFLAGS_LIBMODULE)
+ {
+ TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() );
+ MODULE_CallWEP( hModule );
+
+ /* Free the objects owned by the DLL module */
+
+ if (pTask && pTask->userhandler)
+ pTask->userhandler( hModule, USIG_DLL_UNLOAD, 0,
+ pTask->hInstance, pTask->hQueue );
+ }
+ else
+ call_wep = FALSE; /* We are freeing a task -> no more WEPs */
+ }
+
+
+ /* Clear magic number just in case */
+
+ pModule->magic = pModule->self = 0;
+
+ /* Remove it from the linked list */
+
+ hPrevModule = &hFirstModule;
+ while (*hPrevModule && (*hPrevModule != hModule))
+ {
+ hPrevModule = &(NE_GetPtr( *hPrevModule ))->next;
+ }
+ if (*hPrevModule) *hPrevModule = pModule->next;
+
+ /* Free the referenced modules */
+
+ pModRef = (HMODULE16*)NE_MODULE_TABLE( pModule );
+ for (i = 0; i < pModule->modref_count; i++, pModRef++)
+ {
+ NE_FreeModule( *pModRef, call_wep );
+ }
+
+ /* Free the module storage */
+
+ GlobalFreeAll( hModule );
+
+ /* Remove module from cache */
+
+ if (pCachedModule == pModule) pCachedModule = NULL;
+ return TRUE;
+}
+
+
+/**********************************************************************
+ * FreeModule16 (KERNEL.46)
+ */
+BOOL16 WINAPI FreeModule16( HMODULE16 hModule )
+{
+ return NE_FreeModule( hModule, TRUE );
+}
+
+
+/***********************************************************************
+ * FreeLibrary16 (KERNEL.96)
+ */
+void WINAPI FreeLibrary16( HINSTANCE16 handle )
+{
+ TRACE(module,"%04x\n", handle );
+ FreeModule16( handle );
+}
+
+
+/**********************************************************************
+ * GetModuleName (KERNEL.27)
+ */
+BOOL16 WINAPI GetModuleName( HINSTANCE16 hinst, LPSTR buf, INT16 count )
+{
+ NE_MODULE *pModule;
+ BYTE *p;
+
+ if (!(pModule = NE_GetPtr( hinst ))) return FALSE;
+ p = (BYTE *)pModule + pModule->name_table;
+ if (count > *p) count = *p + 1;
+ if (count > 0)
+ {
+ memcpy( buf, p + 1, count - 1 );
+ buf[count-1] = '\0';
+ }
+ return TRUE;
+}
+
+
+/**********************************************************************
+ * GetModuleUsage (KERNEL.48)
+ */
+INT16 WINAPI GetModuleUsage( HINSTANCE16 hModule )
+{
+ NE_MODULE *pModule = NE_GetPtr( hModule );
+ return pModule ? pModule->count : 0;
+}
+
+
+/**********************************************************************
+ * GetExpWinVer (KERNEL.167)
+ */
+WORD WINAPI GetExpWinVer( HMODULE16 hModule )
+{
+ NE_MODULE *pModule = NE_GetPtr( hModule );
+ return pModule ? pModule->expected_version : 0;
+}
+
+
+/**********************************************************************
+ * GetModuleFileName16 (KERNEL.49)
+ */
+INT16 WINAPI GetModuleFileName16( HINSTANCE16 hModule, LPSTR lpFileName,
+ INT16 nSize )
+{
+ NE_MODULE *pModule;
+
+ if (!hModule) hModule = GetCurrentTask();
+ if (!(pModule = NE_GetPtr( hModule ))) return 0;
+ lstrcpyn32A( lpFileName, NE_MODULE_NAME(pModule), nSize );
+ TRACE(module, "%s\n", lpFileName );
+ return strlen(lpFileName);
+}
+
+
+/**********************************************************************
+ * GetModuleHandle16 (KERNEL.47)
+ *
+ * Find a module from a path name.
+ *
+ * RETURNS
+ * the win16 module handle if found
+ * 0 if not
+ */
+HMODULE16 WINAPI WIN16_GetModuleHandle( SEGPTR name )
+{
+ if (HIWORD(name) == 0) return GetExePtr( (HINSTANCE16)name );
+ return GetModuleHandle16( PTR_SEG_TO_LIN(name) );
+}
+
+HMODULE16 WINAPI GetModuleHandle16( LPCSTR name )
+{
+ HMODULE16 hModule = hFirstModule;
+ LPCSTR filename, dotptr, modulepath, modulename;
+ BYTE len, *name_table;
+
+ if (!(filename = strrchr( name, '\\' ))) filename = name;
+ else filename++;
+ if ((dotptr = strrchr( filename, '.' )) != NULL)
+ len = (BYTE)(dotptr - filename);
+ else len = strlen( filename );
+
+ while (hModule)
+ {
+ NE_MODULE *pModule = NE_GetPtr( hModule );
+ if (!pModule) break;
+ modulepath = NE_MODULE_NAME(pModule);
+ if (!(modulename = strrchr( modulepath, '\\' )))
+ modulename = modulepath;
+ else modulename++;
+ if (!lstrcmpi32A( modulename, filename )) return hModule;
+
+ name_table = (BYTE *)pModule + pModule->name_table;
+ if ((*name_table == len) && !lstrncmpi32A(filename, name_table+1, len))
+ return hModule;
+ hModule = pModule->next;
+ }
+ return 0;
+}
+
+
+/**********************************************************************
+ * ModuleFirst (TOOLHELP.59)
+ */
+BOOL16 WINAPI ModuleFirst( MODULEENTRY *lpme )
+{
+ lpme->wNext = hFirstModule;
+ return ModuleNext( lpme );
+}
+
+
+/**********************************************************************
+ * ModuleNext (TOOLHELP.60)
+ */
+BOOL16 WINAPI ModuleNext( MODULEENTRY *lpme )
+{
+ NE_MODULE *pModule;
+ char *name;
+
+ if (!lpme->wNext) return FALSE;
+ if (!(pModule = NE_GetPtr( lpme->wNext ))) return FALSE;
+ name = (char *)pModule + pModule->name_table;
+ memcpy( lpme->szModule, name + 1, *name );
+ lpme->szModule[(BYTE)*name] = '\0';
+ lpme->hModule = lpme->wNext;
+ lpme->wcUsage = pModule->count;
+ strncpy( lpme->szExePath, NE_MODULE_NAME(pModule), MAX_PATH );
+ lpme->szExePath[MAX_PATH] = '\0';
+ lpme->wNext = pModule->next;
+ return TRUE;
+}
+
+
+/**********************************************************************
+ * ModuleFindName (TOOLHELP.61)
+ */
+BOOL16 WINAPI ModuleFindName( MODULEENTRY *lpme, LPCSTR name )
+{
+ lpme->wNext = GetModuleHandle16( name );
+ return ModuleNext( lpme );
+}
+
+
+/**********************************************************************
+ * ModuleFindHandle (TOOLHELP.62)
+ */
+BOOL16 WINAPI ModuleFindHandle( MODULEENTRY *lpme, HMODULE16 hModule )
+{
+ hModule = GetExePtr( hModule );
+ lpme->wNext = hModule;
+ return ModuleNext( lpme );
}
diff --git a/loader/ne/resource.c b/loader/ne/resource.c
index 832be3b..807871d 100644
--- a/loader/ne/resource.c
+++ b/loader/ne/resource.c
@@ -183,8 +183,8 @@
HRSRC16 hRsrc )
{
int fd;
- NE_MODULE* pModule = MODULE_GetPtr16( hModule );
- if ( pModule && (fd = MODULE_OpenFile( hModule )) >= 0)
+ NE_MODULE* pModule = NE_GetPtr( hModule );
+ if (pModule && (fd = NE_OpenFile( pModule )) >= 0)
{
HGLOBAL16 handle;
WORD sizeShift = *(WORD *)((char *)pModule + pModule->res_table);
@@ -215,7 +215,7 @@
*/
BOOL32 NE_InitResourceHandler( HMODULE16 hModule )
{
- NE_MODULE *pModule = MODULE_GetPtr16( hModule );
+ NE_MODULE *pModule = NE_GetPtr( hModule );
NE_TYPEINFO *pTypeInfo = (NE_TYPEINFO *)((char *)pModule + pModule->res_table + 2);
TRACE(resource,"InitResourceHandler[%04x]\n", hModule );
@@ -236,7 +236,7 @@
FARPROC16 resourceHandler )
{
FARPROC16 prevHandler = NULL;
- NE_MODULE *pModule = MODULE_GetPtr16( hModule );
+ NE_MODULE *pModule = NE_GetPtr( hModule );
NE_TYPEINFO *pTypeInfo = (NE_TYPEINFO *)((char *)pModule + pModule->res_table + 2);
if (!pModule || !pModule->res_table) return NULL;
@@ -264,7 +264,7 @@
NE_TYPEINFO *pTypeInfo;
HRSRC16 hRsrc;
- NE_MODULE *pModule = MODULE_GetPtr16( hModule );
+ NE_MODULE *pModule = NE_GetPtr( hModule );
if (!pModule || !pModule->res_table) return 0;
assert( !__winelib ); /* Can't use Win16 resource functions in Winelib */
@@ -333,7 +333,7 @@
NE_NAMEINFO *pNameInfo=NULL;
WORD sizeShift;
- NE_MODULE *pModule = MODULE_GetPtr16( hModule );
+ NE_MODULE *pModule = NE_GetPtr( hModule );
if (!pModule || !pModule->res_table || !hRsrc) return 0;
TRACE( resource, "module=%04x res=%04x size=%ld\n", hModule, hRsrc, size );
@@ -361,7 +361,7 @@
if (!(hInstance = GetExePtr( hInstance ))) return 0;
if(wType != 0x10) /* 0x10 is the only observed value, passed from
CreateCursorIndirect. */
- fprintf(stderr, "DirectResAlloc: wType = %x\n", wType);
+ TRACE(resource, "(wType=%x)\n", wType);
return GLOBAL_Alloc(GMEM_MOVEABLE, wSize, hInstance, FALSE, FALSE, FALSE);
}
@@ -373,7 +373,7 @@
{
HFILE32 fd;
- NE_MODULE *pModule = MODULE_GetPtr16( hModule );
+ NE_MODULE *pModule = NE_GetPtr( hModule );
if (!pModule || !pModule->res_table || !hRsrc) return -1;
TRACE(resource, "module=%04x res=%04x\n", hModule, hRsrc );
@@ -398,7 +398,7 @@
NE_NAMEINFO *pNameInfo=NULL;
WORD sizeShift;
- NE_MODULE *pModule = MODULE_GetPtr16( hModule );
+ NE_MODULE *pModule = NE_GetPtr( hModule );
if (!pModule || !pModule->res_table) return 0;
TRACE(resource, "module=%04x res=%04x\n", hModule, hRsrc );
@@ -418,7 +418,7 @@
{
NE_TYPEINFO *pTypeInfo;
NE_NAMEINFO *pNameInfo = NULL;
- NE_MODULE *pModule = MODULE_GetPtr16( hModule );
+ NE_MODULE *pModule = NE_GetPtr( hModule );
int d;
TRACE( resource, "module=%04x res=%04x\n", hModule, hRsrc );
@@ -464,7 +464,7 @@
loader = (RESOURCEHANDLER16)pTypeInfo->resloader;
else /* this is really bad */
{
- fprintf( stderr, "[%04x]: Missing resource handler!!!...\n", hModule);
+ ERR(resource, "[%04x]: Missing resource handler!\n", hModule);
loader = NE_DefResourceHandler;
}
@@ -513,8 +513,7 @@
NE_TYPEINFO *pTypeInfo;
NE_NAMEINFO *pNameInfo;
WORD count;
- HMODULE16 hModule = GetExePtr( handle );
- NE_MODULE *pModule = MODULE_GetPtr16( hModule );
+ NE_MODULE *pModule = NE_GetPtr( GetExePtr(handle) );
if (!handle || !pModule || !pModule->res_table) return handle;
@@ -545,7 +544,7 @@
}
TRACE(resource, "[%04x]: no intrinsic resource for %04x, assuming DirectResAlloc()!\n",
- hModule, handle );
+ pModule->self, handle );
GlobalFree16( handle );
return handle;
}
diff --git a/loader/ne/segment.c b/loader/ne/segment.c
index 99f78ce..a6478a5 100644
--- a/loader/ne/segment.c
+++ b/loader/ne/segment.c
@@ -72,7 +72,7 @@
if (!pSeg->filepos) return TRUE; /* No file image, just return */
- fd = MODULE_OpenFile( pModule->self );
+ fd = NE_OpenFile( pModule );
TRACE(module, "Loading segment %d, selector=%04x, flags=%04x\n",
segnum, pSeg->selector, pSeg->flags );
lseek( fd, pSeg->filepos << pModule->alignment, SEEK_SET );
@@ -118,8 +118,8 @@
pSeg->minsize ? pSeg->minsize : 0x10000);
FreeSelector(newselector);
pSeg->selector = oldselector;
- fprintf(stderr, "A new selector was allocated for the dgroup segment\n"
- "Old selector is %d, new one is %d", oldselector, newselector);
+ TRACE(module, "New selector allocated for dgroup segment:Old=%d,New=%d\n",
+ oldselector, newselector);
} else {
FreeSelector(pSeg->selector);
pSeg->selector = newselector;
@@ -201,22 +201,22 @@
address = NE_GetEntryPoint( module, ordinal );
if (!address)
{
- NE_MODULE *pTarget = MODULE_GetPtr16( module );
+ NE_MODULE *pTarget = NE_GetPtr( module );
if (!pTarget)
- fprintf( stderr, "Module not found: %04x, reference %d of module %*.*s\n",
+ WARN(module, "Module not found: %04x, reference %d of module %*.*s\n",
module, rep->target1,
*((BYTE *)pModule + pModule->name_table),
*((BYTE *)pModule + pModule->name_table),
(char *)pModule + pModule->name_table + 1 );
else
- fprintf( stderr, "Warning: no handler for %.*s.%d, setting to 0:0\n",
+ WARN(module, "No handler for %.*s.%d, setting to 0:0\n",
*((BYTE *)pTarget + pTarget->name_table),
(char *)pTarget + pTarget->name_table + 1,
ordinal );
}
if (TRACE_ON(fixup))
{
- NE_MODULE *pTarget = MODULE_GetPtr16( module );
+ NE_MODULE *pTarget = NE_GetPtr( module );
TRACE( fixup, "%d: %.*s.%d=%04x:%04x %s\n", i + 1,
*((BYTE *)pTarget + pTarget->name_table),
(char *)pTarget + pTarget->name_table + 1,
@@ -236,14 +236,14 @@
if (ERR_ON(fixup) && !address)
{
- NE_MODULE *pTarget = MODULE_GetPtr16( module );
+ NE_MODULE *pTarget = NE_GetPtr( module );
ERR(fixup, "Warning: no handler for %.*s.%s, setting to 0:0\n",
*((BYTE *)pTarget + pTarget->name_table),
(char *)pTarget + pTarget->name_table + 1, func_name );
}
if (TRACE_ON(fixup))
{
- NE_MODULE *pTarget = MODULE_GetPtr16( module );
+ NE_MODULE *pTarget = NE_GetPtr( module );
TRACE( fixup, "%d: %.*s.%s=%04x:%04x %s\n", i + 1,
*((BYTE *)pTarget + pTarget->name_table),
(char *)pTarget + pTarget->name_table + 1,
@@ -288,8 +288,12 @@
/* Apparently, high bit of address_type is sometimes set; */
/* we ignore it for now */
if (rep->address_type > NE_RADDR_OFFSET32)
+ {
+ char module[10];
+ GetModuleName( pModule->self, module, sizeof(module) );
ERR( fixup, "WARNING: module %s: unknown reloc addr type = 0x%02x. Please report.\n",
- MODULE_GetModuleName(pModule->self), rep->address_type );
+ module, rep->address_type );
+ }
if (additive)
{
@@ -405,7 +409,7 @@
stack16Top->ip = 0;
stack16Top->cs = 0;
- hf = FILE_DupUnixHandle( MODULE_OpenFile( pModule->self ) );
+ hf = FILE_DupUnixHandle( NE_OpenFile( pModule ) );
Callbacks->CallBootAppProc(selfloadheader->BootApp, pModule->self, hf);
_lclose32(hf);
/* some BootApp procs overwrite the selector of dgroup */
@@ -490,7 +494,7 @@
if (pModule->flags & NE_FFLAGS_MULTIPLEDATA)
{
/* can this happen? */
- fprintf( stderr, "FixupPrologs got confused\n" );
+ ERR(fixup, "FixupPrologs got confused\n" );
}
else if (pModule->flags & NE_FFLAGS_SINGLEDATA)
{
@@ -523,9 +527,8 @@
*
* Call the DLL initialization code
*/
-static BOOL32 NE_InitDLL( TDB* pTask, HMODULE16 hModule )
+static BOOL32 NE_InitDLL( TDB* pTask, NE_MODULE *pModule )
{
- NE_MODULE *pModule;
SEGTABLEENTRY *pSegTable;
CONTEXT context;
@@ -536,7 +539,6 @@
* es:si command line (always 0)
*/
- if (!(pModule = MODULE_GetPtr16( hModule ))) return FALSE;
pSegTable = NE_SEG_TABLE( pModule );
if (!(pModule->flags & NE_FFLAGS_LIBMODULE) ||
@@ -548,7 +550,7 @@
if (pTask && pTask->userhandler)
{
- pTask->userhandler( hModule, USIG_DLL_LOAD, 0, pTask->hInstance,
+ pTask->userhandler( pModule->self, USIG_DLL_LOAD, 0, pTask->hInstance,
pTask->hQueue );
}
@@ -561,7 +563,7 @@
if (pModule->flags & NE_FFLAGS_MULTIPLEDATA || pModule->dgroup)
{
/* Not SINGLEDATA */
- fprintf(stderr, "Library is not marked SINGLEDATA\n");
+ ERR(dll, "Library is not marked SINGLEDATA\n");
exit(1);
}
else /* DATA NONE DLL */
@@ -589,7 +591,7 @@
EIP_reg(&context) = pModule->ip;
EBP_reg(&context) = OFFSETOF(THREAD_Current()->cur_stack)
+ (WORD)&((STACK16FRAME*)0)->bp;
- EDI_reg(&context) = DS_reg(&context) ? DS_reg(&context) : hModule;
+ EDI_reg(&context) = DS_reg(&context) ? DS_reg(&context) : pModule->self;
pModule->cs = 0; /* Don't initialize it twice */
@@ -600,6 +602,44 @@
return TRUE;
}
+/***********************************************************************
+ * NE_CallDllEntryPoint
+ *
+ * Call the DllEntryPoint of DLLs with subsystem >= 4.0
+ */
+
+static void NE_CallDllEntryPoint( NE_MODULE *pModule, DWORD dwReason )
+{
+ FARPROC16 entryPoint;
+ WORD ordinal;
+ CONTEXT context;
+ THDB *thdb = THREAD_Current();
+ LPBYTE stack = (LPBYTE)THREAD_STACK16(thdb);
+
+ if (pModule->expected_version < 0x0400) return;
+ if (!(ordinal = NE_GetOrdinal( pModule->self, "DllEntryPoint" ))) return;
+ if (!(entryPoint = NE_GetEntryPoint( pModule->self, ordinal ))) return;
+
+ memset( &context, 0, sizeof(context) );
+
+ CS_reg(&context) = HIWORD(entryPoint);
+ IP_reg(&context) = LOWORD(entryPoint);
+ EBP_reg(&context) = OFFSETOF( thdb->cur_stack )
+ + (WORD)&((STACK16FRAME*)0)->bp;
+
+ *(DWORD *)(stack - 4) = dwReason; /* dwReason */
+ *(WORD *) (stack - 6) = pModule->self; /* hInst */
+ *(WORD *) (stack - 8) = 0; /* wDS */
+ *(WORD *) (stack - 10) = 0; /* wHeapSize */
+ *(DWORD *)(stack - 14) = 0; /* dwReserved1 */
+ *(WORD *) (stack - 16) = 0; /* wReserved2 */
+
+ TRACE(dll, "Calling DllEntryPoint, cs:ip=%04lx:%04x\n",
+ CS_reg(&context), IP_reg(&context));
+
+ Callbacks->CallRegisterShortProc( &context, 16 );
+}
+
/***********************************************************************
* NE_InitializeDLLs
@@ -613,8 +653,8 @@
NE_MODULE *pModule;
HMODULE16 *pDLL;
- if (!(pModule = MODULE_GetPtr16( hModule ))) return;
- if (pModule->flags & NE_FFLAGS_WIN32) return;
+ if (!(pModule = NE_GetPtr( hModule ))) return;
+ assert( !(pModule->flags & NE_FFLAGS_WIN32) );
if (pModule->dlls_to_init)
{
@@ -626,7 +666,47 @@
}
GlobalFree16( to_init );
}
- NE_InitDLL( pTask, hModule );
+ NE_InitDLL( pTask, pModule );
+ NE_CallDllEntryPoint( pModule, DLL_PROCESS_ATTACH );
+}
+
+
+/***********************************************************************
+ * NE_CreateInstance
+ *
+ * If lib_only is TRUE, handle the module like a library even if it is a .EXE
+ */
+HINSTANCE16 NE_CreateInstance( NE_MODULE *pModule, HINSTANCE16 *prev,
+ BOOL32 lib_only )
+{
+ SEGTABLEENTRY *pSegment;
+ int minsize;
+ HINSTANCE16 hNewInstance;
+
+ if (pModule->dgroup == 0)
+ {
+ if (prev) *prev = pModule->self;
+ return pModule->self;
+ }
+
+ pSegment = NE_SEG_TABLE( pModule ) + pModule->dgroup - 1;
+ if (prev) *prev = pSegment->selector;
+
+ /* if it's a library, create a new instance only the first time */
+ if (pSegment->selector)
+ {
+ if (pModule->flags & NE_FFLAGS_LIBMODULE) return pSegment->selector;
+ if (lib_only) return pSegment->selector;
+ }
+
+ minsize = pSegment->minsize ? pSegment->minsize : 0x10000;
+ if (pModule->ss == pModule->dgroup) minsize += pModule->stack_size;
+ minsize += pModule->heap_size;
+ hNewInstance = GLOBAL_Alloc( GMEM_ZEROINIT | GMEM_FIXED, minsize,
+ pModule->self, FALSE, FALSE, FALSE );
+ if (!hNewInstance) return 0;
+ pSegment->selector = hNewInstance;
+ return hNewInstance;
}
@@ -639,7 +719,7 @@
/* It does nothing */
void WINAPI PatchCodeHandle(HANDLE16 hSel)
{
- fprintf(stderr,"PatchCodeHandle(%04x),stub!\n",hSel);
+ FIXME(module,"(%04x): stub.\n",hSel);
}
@@ -682,13 +762,11 @@
/***********************************************************************
* NE_CreateSegments
*/
-BOOL32 NE_CreateSegments( HMODULE16 hModule )
+BOOL32 NE_CreateSegments( NE_MODULE *pModule )
{
SEGTABLEENTRY *pSegment;
- NE_MODULE *pModule;
int i, minsize;
- if (!(pModule = MODULE_GetPtr16( hModule ))) return FALSE;
assert( !(pModule->flags & NE_FFLAGS_WIN32) );
pSegment = NE_SEG_TABLE( pModule );
@@ -696,10 +774,10 @@
{
minsize = pSegment->minsize ? pSegment->minsize : 0x10000;
if (i == pModule->ss) minsize += pModule->stack_size;
- /* The DGROUP is allocated by MODULE_CreateInstance */
+ /* The DGROUP is allocated by NE_CreateInstance */
if (i == pModule->dgroup) continue;
pSegment->selector = GLOBAL_Alloc( NE_Ne2MemFlags(pSegment->flags),
- minsize, hModule,
+ minsize, pModule->self,
!(pSegment->flags & NE_SEGFLAGS_DATA),
FALSE,
FALSE /*pSegment->flags & NE_SEGFLAGS_READONLY*/ );
@@ -710,3 +788,15 @@
(pModule->dgroup - 1) * sizeof(SEGTABLEENTRY) : 0;
return TRUE;
}
+
+
+/**********************************************************************
+ * IsSharedSelector (KERNEL.345)
+ */
+BOOL16 WINAPI IsSharedSelector( HANDLE16 selector )
+{
+ /* Check whether the selector belongs to a DLL */
+ NE_MODULE *pModule = NE_GetPtr( selector );
+ if (!pModule) return FALSE;
+ return (pModule->flags & NE_FFLAGS_LIBMODULE) != 0;
+}
diff --git a/loader/pe_image.c b/loader/pe_image.c
index 12c962e..3d2dfbd 100644
--- a/loader/pe_image.c
+++ b/loader/pe_image.c
@@ -241,18 +241,14 @@
/* don't use MODULE_Load, Win32 creates new task differently */
res = PE_LoadLibraryEx32A( name, process, 0, 0 );
if (res <= (HMODULE32) 32) {
- char buffer[1024];
-
- /* Try with prepending the path of the current module */
- if (GetModuleFileName32A( wm->module, buffer, sizeof (buffer))) {
- char *p;
-
- if (!(p = strrchr (buffer, '\\')))
- p = buffer;
- strcpy (p + 1, name);
- res = PE_LoadLibraryEx32A( buffer, process, 0, 0 );
- } else
- ERR(win32,"cannot find the module just loaded!\n");
+ char *p,buffer[2000];
+
+ /* GetModuleFileName would use the wrong process, so don't use it */
+ strcpy(buffer,wm->shortname);
+ if (!(p = strrchr (buffer, '\\')))
+ p = buffer;
+ strcpy (p + 1, name);
+ res = PE_LoadLibraryEx32A( buffer, process, 0, 0 );
}
if (res <= (HMODULE32) 32) {
WARN (module, "Module %s not found\n", name);
@@ -533,36 +529,32 @@
/**********************************************************************
* This maps a loaded PE dll into the address space of the specified process.
*/
-static BOOL32 PE_MapImage( HMODULE32 *phModule, PDB32 *process,
- OFSTRUCT *ofs, DWORD flags )
+static BOOL32 PE_MapImage( PDB32 *process,WINE_MODREF *wm, OFSTRUCT *ofs, DWORD flags )
{
- WINE_MODREF *wm;
PE_MODREF *pem;
int i, result;
DWORD load_addr;
IMAGE_DATA_DIRECTORY dir;
char *modname;
int vma_size;
- HMODULE32 hModule = *phModule;
+ HMODULE32 hModule = wm->module;
IMAGE_SECTION_HEADER *pe_seg;
IMAGE_DOS_HEADER *dos_header = (IMAGE_DOS_HEADER *)hModule;
IMAGE_NT_HEADERS *nt_header = PE_HEADER(hModule);
-
- wm = (WINE_MODREF*)HeapAlloc(process->heap,HEAP_ZERO_MEMORY,
- sizeof(*wm));
- wm->type= MODULE32_PE;
pem = &(wm->binfmt.pe);
- /* NOTE: fixup_imports takes care of the correct order */
- wm->next = process->modref_list;
- process->modref_list = wm;
+ result = GetLongPathName32A(ofs->szPathName,NULL,0);
+ wm->longname = (char*)HeapAlloc(process->heap,0,result+1);
+ GetLongPathName32A(ofs->szPathName,wm->longname,result+1);
+
+ wm->shortname = HEAP_strdupA(process->heap,0,ofs->szPathName);
if (!(nt_header->FileHeader.Characteristics & IMAGE_FILE_DLL))
{
if (process->exe_modref)
- WARN(win32,"overwriting old exe_modref... arrgh\n");
+ FIXME(win32,"overwriting old exe_modref... arrgh\n");
process->exe_modref = wm;
}
@@ -577,10 +569,10 @@
MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE );
}
- /* *phModule is the module32 entry in the NE_MODULE. We need to
- * change it here, since it can get referenced by fixup_imports()
+ /* NOTE: this changes a value in the process modref chain, which can
+ * be accessed independently from this function
*/
- wm->module = *phModule = (HMODULE32)load_addr;
+ wm->module = (HMODULE32)load_addr;
TRACE(win32, "Load addr is really %lx, range %x\n",
load_addr, vma_size);
@@ -713,8 +705,6 @@
modname = s = ofs->szPathName;
while ((s=strchr(modname,'\\')))
modname = s+1;
- if ((s=strchr(modname,'.')))
- *s='\0';
wm->modname = HEAP_strdupA(process->heap,0,modname);
}
if(pem->pe_import) {
@@ -760,13 +750,9 @@
WINE_MODREF *wm;
if ((hModule = MODULE_FindModule32( process, name ))) {
-
- pModule = MODULE_GetPtr32(hModule);
for (wm= process->modref_list;wm;wm=wm->next)
- if (wm->module == hModule) {
- pModule->count++;
+ if (wm->module == hModule)
return hModule;
- }
/* Since MODULE_FindModule32 uses the modref chain too, the
* module MUST have been found above. If not, something has gone
* terribly wrong.
@@ -781,31 +767,55 @@
if (HFILE_ERROR32==(hFile=OpenFile32(name,&ofs,OF_READ))) {
/* Now try the built-in even if disabled */
if ((hModule = BUILTIN32_LoadModule( name, TRUE, process ))) {
- fprintf( stderr, "Warning: could not load external DLL '%s', using built-in module.\n", name );
- return hModule;
+ WARN( module, "Could not load external DLL '%s', using built-in module.\n", name );
+ return hModule;
}
return 1;
}
+ /* will go away ... */
if ((hModule = MODULE_CreateDummyModule( &ofs )) < 32) {
_lclose32(hFile);
return hModule;
}
- pModule = (NE_MODULE *)GlobalLock16( hModule );
- pModule->flags = NE_FFLAGS_WIN32;
- pModule->module32 = PE_LoadImage( hFile );
+ pModule = (NE_MODULE *)GlobalLock16( hModule );
+ pModule->flags = NE_FFLAGS_WIN32;
+ /* .. */
+
+ wm=(WINE_MODREF*)HeapAlloc(process->heap,HEAP_ZERO_MEMORY,sizeof(*wm));
+ wm->type = MODULE32_PE;
+ /* NOTE: fixup_imports takes care of the correct order */
+ wm->next = process->modref_list;
+ process->modref_list = wm;
+
+ wm->module = pModule->module32 = PE_LoadImage( hFile );
+
CloseHandle( hFile );
- if (pModule->module32 < 32)
+ if (wm->module < 32)
{
- FreeLibrary32( hModule);
+ process->modref_list = wm->next;
+ HeapFree(process->heap,0,wm);
+ ERR(win32,"can't load %s\n",ofs.szPathName);
return 21; /* FIXME: probably 0 */
}
/* (possible) recursion */
- if (!PE_MapImage( &(pModule->module32), process, &ofs,flags)) {
- /* FIXME: should free this module and its referenced ones */
- return 0;
+ if (!PE_MapImage(process,wm,&ofs,flags)) {
+ /* ERROR cleanup ... */
+ WINE_MODREF **xwm;
+
+ ERR(win32,"couldn't load %s\n",ofs.szPathName);
+ /* unlink from process modref chain */
+ for ( xwm=&(process->modref_list);
+ *xwm && (*xwm!=wm);
+ xwm=&((*xwm)->next)
+ ) /* EMPTY */;
+ if (*xwm)
+ *xwm=(*xwm)->next;
+
+ return 0;
}
- return pModule->module32;
+ pModule->module32 = wm->module;
+ return wm->module;
}
/*****************************************************************************
@@ -813,23 +823,30 @@
* FIXME: this function should use PE_LoadLibraryEx32A, but currently can't
* due to the PROCESS_Create stuff.
*/
-HINSTANCE16 PE_LoadModule( HFILE32 hFile, OFSTRUCT *ofs, LPCSTR cmd_line,
+HINSTANCE16 PE_LoadModule( LPCSTR name, LPCSTR cmd_line,
LPCSTR env, UINT16 show_cmd )
{
HMODULE16 hModule16;
HMODULE32 hModule32;
HINSTANCE16 hInstance;
NE_MODULE *pModule;
+ HFILE32 hFile;
+ OFSTRUCT ofs;
THDB *thdb = THREAD_Current();
-
- if ((hModule16 = MODULE_CreateDummyModule( ofs )) < 32) return hModule16;
+ PDB32 *process;
+ WINE_MODREF *wm;
+
+ if ((hFile = OpenFile32( name, &ofs, OF_READ )) == HFILE_ERROR32)
+ return 2; /* File not found */
+
+ if ((hModule16 = MODULE_CreateDummyModule( &ofs )) < 32) return hModule16;
pModule = (NE_MODULE *)GlobalLock16( hModule16 );
pModule->flags = NE_FFLAGS_WIN32;
pModule->module32 = hModule32 = PE_LoadImage( hFile );
if (hModule32 < 32) return 21;
- hInstance = MODULE_CreateInstance( hModule16, NULL, (cmd_line == NULL) );
+ hInstance = NE_CreateInstance( pModule, NULL, (cmd_line == NULL) );
if (cmd_line &&
!(PE_HEADER(hModule32)->FileHeader.Characteristics & IMAGE_FILE_DLL))
{
@@ -838,11 +855,21 @@
TDB *pTask = (TDB *)GlobalLock16( pdb->task );
thdb = pTask->thdb;
}
- if (!PE_MapImage( &(pModule->module32), thdb->process, ofs, 0 ))
+
+ process = thdb->process;
+
+ wm=(WINE_MODREF*)HeapAlloc(process->heap,HEAP_ZERO_MEMORY,sizeof(*wm));
+ wm->type = MODULE32_PE;
+ /* NOTE: fixup_imports takes care of the correct order */
+ wm->next = process->modref_list;
+ wm->module = hModule32;
+ process->modref_list = wm;
+ if (!PE_MapImage( process, wm, &ofs, 0 ))
{
/* FIXME: should destroy the task created and free referenced stuff */
return 0;
}
+ pModule->module32 = wm->module;
/* FIXME: Yuck. Is there no other good place to do that? */
PE_InitTls( thdb );
return hInstance;
diff --git a/loader/resource.c b/loader/resource.c
index 32f2a6d..c4bec2f 100644
--- a/loader/resource.c
+++ b/loader/resource.c
@@ -187,7 +187,7 @@
break;
}
if (__winelib)
- fprintf(stderr,"SizeofResource32: not implemented for WINELIB\n");
+ FIXME(module,"Not implemented for WINELIB\n");
return 0;
}
diff --git a/loader/signal.c b/loader/signal.c
index 05cf70a..2e3dec6 100644
--- a/loader/signal.c
+++ b/loader/signal.c
@@ -158,7 +158,7 @@
{
extern void SYNC_SetupSignals(void);
-#ifdef HAVE_SIGALTSTACK
+#ifdef HAVE_WORKING_SIGALTSTACK
struct sigaltstack ss;
ss.ss_sp = SIGNAL_Stack;
ss.ss_size = sizeof(SIGNAL_Stack);
diff --git a/loader/task.c b/loader/task.c
index 99c7611..2d25eac 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -37,7 +37,6 @@
#define MIN_THUNKS 32
extern INT32 WINSOCK_DeleteTaskWSI( TDB* pTask, struct _WSINFO* );
-extern BOOL32 MODULE_FreeModule( HMODULE16 hModule, TDB* ptaskContext );
/* Pointer to function to switch to a larger stack */
int (*IF1632_CallLargeStack)( int (*func)(), void *arg ) = NULL;
@@ -208,7 +207,7 @@
{
int exit_code = 1;
TDB *pTask = (TDB *)GlobalLock16( hCurrentTask );
- NE_MODULE *pModule = MODULE_GetPtr16( pTask->hModule );
+ NE_MODULE *pModule = NE_GetPtr( pTask->hModule );
SEGTABLEENTRY *pSegTable = NE_SEG_TABLE( pModule );
SET_CUR_THREAD( pTask->thdb );
@@ -276,9 +275,10 @@
{
HTASK16 hTask;
TDB *pTask;
- LPSTR name, cmd_line;
+ LPSTR cmd_line;
WORD sp;
char *stack32Top;
+ char name[10];
STACK16FRAME *frame16;
STACK32FRAME *frame32;
PDB32 *pdb32 = thdb->process;
@@ -319,7 +319,7 @@
/* Copy the module name */
- name = MODULE_GetModuleName( pModule->self );
+ GetModuleName( pModule->self, name, sizeof(name) );
strncpy( pTask->module_name, name, sizeof(pTask->module_name) );
/* Allocate a selector for the PDB */
@@ -432,7 +432,7 @@
/* Free the task module */
- MODULE_FreeModule( pTask->hModule, pTask );
+ FreeModule16( pTask->hModule );
/* Free the selector aliases */
@@ -660,7 +660,7 @@
if (context) EAX_reg(context) = 0;
if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return;
- if (!(pModule = MODULE_GetPtr16( pTask->hModule ))) return;
+ if (!(pModule = NE_GetPtr( pTask->hModule ))) return;
/* This is a hack to install task USER signal handler before
* implicitly loaded DLLs are initialized (see windows/user.c) */
@@ -855,7 +855,7 @@
BYTE *thunk,*lfunc;
SEGPTR thunkaddr;
- if (!hInstance) return 0;
+ if (!hInstance) hInstance = CURRENT_DS;
thunkaddr = TASK_AllocThunk( hCurrentTask );
if (!thunkaddr) return (FARPROC16)0;
thunk = PTR_SEG_TO_LIN( thunkaddr );
@@ -995,12 +995,8 @@
/***********************************************************************
* SwitchStackBack (KERNEL.109)
- *
- * Note: the function is declared as 'register' in the spec file in order
- * to make sure all registers are preserved, but we don't use them in any
- * way, so we don't need a CONTEXT* argument.
*/
-void WINAPI SwitchStackBack(void)
+void WINAPI SwitchStackBack( CONTEXT *context )
{
TDB *pTask;
STACK16FRAME *oldFrame, *newFrame;
@@ -1022,6 +1018,8 @@
/* Switch back to the old stack */
pTask->thdb->cur_stack = pData->old_ss_sp;
+ SS_reg(context) = SELECTOROF(pData->old_ss_sp);
+ ESP_reg(context) = OFFSETOF(pData->old_ss_sp);
pData->old_ss_sp = 0;
/* Build a stack frame for the return */