Commit c1d1cfe9 authored by Bertho Stultiens's avatar Bertho Stultiens Committed by Alexandre Julliard

Reorganization of the loader to correctly load and free libraries and

implementation of load order to load different types of libraries.
parent 25947201
......@@ -325,85 +325,3 @@ void BUILTIN_DefaultIntHandler( CONTEXT *context )
INT_BARF( context, ordinal - FIRST_INTERRUPT_ORDINAL );
}
/***********************************************************************
* BUILTIN_ParseDLLOptions
*
* Set runtime DLL usage flags
*/
BOOL BUILTIN_ParseDLLOptions( char *str )
{
BUILTIN16_DLL *dll;
char *p,*last;
last = str;
while (*str)
{
while (*str && (*str==',' || isspace(*str))) str++;
if (!*str) {
*last = '\0'; /* cut off garbage at end at */
return TRUE;
}
if ((*str != '+') && (*str != '-')) return FALSE;
str++;
if (!(p = strchr( str, ',' ))) p = str + strlen(str);
while ((p > str) && isspace(p[-1])) p--;
if (p == str) return FALSE;
for (dll = BuiltinDLLs; dll->descr; dll++)
{
if (!lstrncmpiA( str, dll->descr->name, (int)(p - str) ))
{
if (dll->descr->name[(int)(p-str)]) /* only partial match */
continue;
if (str[-1] == '-')
{
if (dll->flags & DLL_FLAG_ALWAYS_USED) return FALSE;
dll->flags |= DLL_FLAG_NOT_USED;
}
else dll->flags &= ~DLL_FLAG_NOT_USED;
break;
}
}
if (!dll->descr) {
/* not found, but could get handled by BUILTIN32_, so move last */
last = p;
str = p;
} else {
/* handled. cut out the "[+-]DLL," string, so it isn't handled
* by BUILTIN32
*/
if (*p) {
memcpy(last,p,strlen(p)+1);
str = last;
} else {
*last = '\0';
break;
}
}
}
return TRUE;
}
/***********************************************************************
* BUILTIN_PrintDLLs
*
* Print the list of built-in DLLs that can be disabled.
*/
void BUILTIN_PrintDLLs(void)
{
int i;
BUILTIN16_DLL *dll;
MSG("Example: -dll -ole2 Do not use emulated OLE2.DLL\n");
MSG("Available Win16 DLLs:\n");
for (i = 0, dll = BuiltinDLLs; dll->descr; dll++)
{
if (!(dll->flags & DLL_FLAG_ALWAYS_USED))
MSG("%-9s%c", dll->descr->name,
((++i) % 8) ? ' ' : '\n' );
}
MSG("\n");
BUILTIN32_PrintDLLs();
}
......@@ -27,8 +27,6 @@ extern ENTRYPOINT32 BUILTIN32_GetEntryPoint( char *buffer, void *relay,
unsigned int *typemask );
extern void BUILTIN32_Unimplemented( const BUILTIN32_DESCRIPTOR *descr,
int ordinal );
extern void BUILTIN32_PrintDLLs(void);
extern void BUILTIN32_SwitchRelayDebug(int onoff);
extern int BUILTIN32_EnableDLL( const char *name, int len, int enable );
#endif /* __WINE_BUILTIN32_H */
......@@ -121,7 +121,13 @@ typedef struct
#pragma pack(4)
/* internal representation of 32bit modules. per process. */
typedef enum { MODULE32_PE=1, MODULE32_ELF /* ,... */ } MODULE32_TYPE;
typedef enum {
MODULE32_PE = 1,
MODULE32_ELF,
MODULE32_ELFDLL,
MODULE32_BI
} MODULE32_TYPE;
typedef struct _wine_modref
{
struct _wine_modref *next;
......@@ -132,7 +138,7 @@ typedef struct _wine_modref
ELF_MODREF elf;
} binfmt;
HMODULE module;
HMODULE module;
int nDeps;
struct _wine_modref **deps;
......@@ -148,7 +154,6 @@ typedef struct _wine_modref
#define WINE_MODREF_INTERNAL 0x00000001
#define WINE_MODREF_NO_DLL_CALLS 0x00000002
#define WINE_MODREF_PROCESS_ATTACHED 0x00000004
#define WINE_MODREF_PROCESS_DETACHED 0x00000008
#define WINE_MODREF_LOAD_AS_DATAFILE 0x00000010
#define WINE_MODREF_DONT_RESOLVE_REFS 0x00000020
#define WINE_MODREF_MARKER 0x80000000
......@@ -171,13 +176,17 @@ typedef struct resource_nameinfo_s NE_NAMEINFO;
/* module.c */
extern FARPROC MODULE_GetProcAddress( HMODULE hModule, LPCSTR function, BOOL snoop );
extern WINE_MODREF *MODULE32_LookupHMODULE( HMODULE hModule );
extern void MODULE_InitializeDLLs( HMODULE root, DWORD type, LPVOID lpReserved );
extern HMODULE MODULE_FindModule( LPCSTR path );
extern BOOL MODULE_DllProcessAttach( WINE_MODREF *wm, LPVOID lpReserved );
extern void MODULE_DllProcessDetach( BOOL bForceDetach, LPVOID lpReserved );
extern void MODULE_DllThreadAttach( LPVOID lpReserved );
extern void MODULE_DllThreadDetach( LPVOID lpReserved );
extern WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags );
extern BOOL MODULE_FreeLibrary( WINE_MODREF *wm );
extern WINE_MODREF *MODULE_FindModule( LPCSTR path );
extern HMODULE MODULE_CreateDummyModule( const OFSTRUCT *ofs, LPCSTR modName );
extern FARPROC16 MODULE_GetWndProcEntry16( const char *name );
extern FARPROC16 WINAPI WIN32_GetProcAddress16( HMODULE hmodule, LPCSTR name );
extern SEGPTR WINAPI HasGPHandler16( SEGPTR address );
HMODULE MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags );
/* resource.c */
extern INT WINAPI AccessResource(HMODULE,HRSRC);
......@@ -192,7 +201,7 @@ extern FARPROC16 NE_GetEntryPoint( HMODULE16 hModule, WORD ordinal );
extern FARPROC16 NE_GetEntryPointEx( HMODULE16 hModule, WORD ordinal, BOOL16 snoop );
extern BOOL16 NE_SetEntryPoint( HMODULE16 hModule, WORD ordinal, WORD offset );
extern HANDLE NE_OpenFile( NE_MODULE *pModule );
extern HINSTANCE16 NE_LoadModule( LPCSTR name, BOOL implicit );
extern HINSTANCE16 MODULE_LoadModule16( LPCSTR name, BOOL implicit );
extern BOOL NE_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmd_line, LPCSTR env,
LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
BOOL inherit, LPSTARTUPINFOA startup,
......@@ -225,12 +234,11 @@ HGLOBAL16 NE_LoadPEResource( NE_MODULE *pModule, WORD type, LPVOID bits, DWORD s
extern BOOL BUILTIN_Init(void);
extern HMODULE16 BUILTIN_LoadModule( LPCSTR name, BOOL force );
extern LPCSTR BUILTIN_GetEntryPoint16( WORD cs, WORD ip, WORD *pOrd );
extern BOOL BUILTIN_ParseDLLOptions( char *str );
extern void BUILTIN_PrintDLLs(void);
/* relay32/builtin.c */
extern HMODULE BUILTIN32_LoadImage( LPCSTR name, OFSTRUCT *ofs, BOOL force );
extern BOOL BUILTIN32_ParseDLLOptions( char *str );
extern WINE_MODREF *BUILTIN32_LoadLibraryExA(LPCSTR name, DWORD flags, DWORD *err);
extern void BUILTIN32_UnloadLibrary(WINE_MODREF *wm);
/* if1632/builtin.c */
extern HMODULE16 (*fnBUILTIN_LoadModule)(LPCSTR name, BOOL force);
......
......@@ -25,7 +25,8 @@ extern BOOL PE_EnumResourceLanguagesA(HMODULE,LPCSTR,LPCSTR,ENUMRESLANGPROCA,LON
extern BOOL PE_EnumResourceLanguagesW(HMODULE,LPCWSTR,LPCWSTR,ENUMRESLANGPROCW,LONG);
extern HRSRC PE_FindResourceExW(struct _wine_modref*,LPCWSTR,LPCWSTR,WORD);
extern DWORD PE_SizeofResource(HMODULE,HRSRC);
extern HMODULE PE_LoadLibraryExA(LPCSTR,HFILE,DWORD);
extern struct _wine_modref *PE_LoadLibraryExA(LPCSTR, DWORD, DWORD *);
extern void PE_UnloadLibrary(struct _wine_modref *);
extern HGLOBAL PE_LoadResource(struct _wine_modref *wm,HRSRC);
extern HMODULE PE_LoadImage( HFILE hFile, OFSTRUCT *ofs, LPCSTR *modName );
extern struct _wine_modref *PE_CreateModule( HMODULE hModule, OFSTRUCT *ofs,
......@@ -36,7 +37,7 @@ extern BOOL PE_CreateProcess( HFILE hFile, OFSTRUCT *ofs, LPCSTR cmd_line, LPCST
LPPROCESS_INFORMATION info );
extern void PE_InitTls(void);
extern void PE_InitDLL(struct _wine_modref *wm, DWORD type, LPVOID lpReserved);
extern BOOL PE_InitDLL(struct _wine_modref *wm, DWORD type, LPVOID lpReserved);
extern PIMAGE_RESOURCE_DIRECTORY GetResDirEntryA(PIMAGE_RESOURCE_DIRECTORY,LPCSTR,DWORD,BOOL);
extern PIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(PIMAGE_RESOURCE_DIRECTORY,LPCWSTR,DWORD,BOOL);
......@@ -64,7 +65,8 @@ typedef struct {
} ELF_MODREF;
extern struct _wine_modref *ELF_CreateDummyModule(LPCSTR,LPCSTR);
extern HMODULE ELF_LoadLibraryExA(LPCSTR,HFILE,DWORD);
extern struct _wine_modref *ELF_LoadLibraryExA( LPCSTR libname, DWORD flags, DWORD *err);
extern void ELF_UnloadLibrary(struct _wine_modref *);
extern FARPROC ELF_FindExportedFunction(struct _wine_modref *wm, LPCSTR funcName);
#endif /* __WINE_PE_IMAGE_H */
......@@ -245,6 +245,7 @@ extern int WIN32_LastError;
#define ERROR_BADKEY 1010 /* Config reg key invalid */
#define ERROR_CANTREAD 1012 /* Config reg key couldn't be read */
#define ERROR_CANTWRITE 1013 /* Config reg key couldn't be written */
#define ERROR_DLL_INIT_FAILED 1114
#define ERROR_IO_DEVICE 1117
#define ERROR_POSSIBLE_DEADLOCK 1131
#define ERROR_BAD_DEVICE 1200
......
......@@ -7,7 +7,9 @@ MODULE = loader
C_SRCS = \
elf.c \
elfdll.c \
libres.c \
loadorder.c \
main.c \
module.c \
pe_image.c \
......
......@@ -21,9 +21,10 @@
#include "neexe.h"
#include "peexe.h"
#include "heap.h"
#include "pe_image.h"
#include "module.h"
#include "pe_image.h"
#include "debug.h"
#include "winerror.h"
WINE_MODREF *ELF_CreateDummyModule( LPCSTR libname, LPCSTR modname )
{
......@@ -96,7 +97,7 @@ WINE_MODREF *ELF_CreateDummyModule( LPCSTR libname, LPCSTR modname )
#include <dlfcn.h>
HMODULE ELF_LoadLibraryExA( LPCSTR libname, HANDLE hf, DWORD flags )
WINE_MODREF *ELF_LoadLibraryExA( LPCSTR libname, DWORD flags, DWORD *err)
{
WINE_MODREF *wm;
char *modname,*s,*t,*x;
......@@ -138,14 +139,16 @@ HMODULE ELF_LoadLibraryExA( LPCSTR libname, HANDLE hf, DWORD flags )
dlhandle = dlopen(t,RTLD_NOW);
if (!dlhandle) {
HeapFree( GetProcessHeap(), 0, t );
return 0;
*err = ERROR_FILE_NOT_FOUND;
return NULL;
}
wm = ELF_CreateDummyModule( t, modname );
wm->binfmt.elf.dlhandle = dlhandle;
SNOOP_RegisterDLL(wm->module,libname,STUBSIZE/sizeof(ELF_STDCALL_STUB));
return wm->module;
*err = 0;
return wm;
}
FARPROC ELF_FindExportedFunction( WINE_MODREF *wm, LPCSTR funcName)
......@@ -247,12 +250,29 @@ FARPROC ELF_FindExportedFunction( WINE_MODREF *wm, LPCSTR funcName)
fun = SNOOP_GetProcAddress(wm->module,funcName,stub-wm->binfmt.elf.stubs,fun);
return (FARPROC)fun;
}
/***************************************************************************
* ELF_UnloadLibrary
*
* Unload the elf library and free the modref
*/
void ELF_UnloadLibrary(WINE_MODREF *wm)
{
/* FIXME: do something here */
}
#else
HMODULE ELF_LoadLibraryExA( LPCSTR libname, HANDLE hf, DWORD flags)
WINE_MODREF *ELF_LoadLibraryExA( LPCSTR libname, HANDLE hf, DWORD flags)
{
return 0;
return NULL;
}
void ELF_UnloadLibrary(WINE_MODREF *wm)
{
}
FARPROC ELF_FindExportedFunction( WINE_MODREF *wm, LPCSTR funcName)
{
return (FARPROC)0;
......
......@@ -45,6 +45,8 @@
#include "debug.h"
#include "psdrv.h"
#include "server.h"
#include "cursoricon.h"
#include "loadorder.h"
int __winelib = 1; /* Winelib run-time flag */
......@@ -69,6 +71,9 @@ BOOL MAIN_MainInit(void)
/* Load the configuration file */
if (!PROFILE_LoadWineIni()) return FALSE;
/* Initialize module loadorder */
if (!MODULE_InitLoadOrder()) return FALSE;
/* Initialize DOS memory */
if (!DOSMEM_Init(0)) return FALSE;
......
......@@ -27,6 +27,8 @@
#include "stackframe.h"
#include "debug.h"
#include "file.h"
#include "loadorder.h"
#include "elfdll.h"
FARPROC16 (*fnSNOOP16_GetProcAddress16)(HMODULE16,DWORD,FARPROC16) = NULL;
void (*fnSNOOP16_RegisterDLL)(NE_MODULE*,LPCSTR) = NULL;
......@@ -755,7 +757,7 @@ static BOOL NE_LoadDLLs( NE_MODULE *pModule )
/* its handle in the list of DLLs to initialize. */
HMODULE16 hDLL;
if ((hDLL = NE_LoadModule( buffer, TRUE )) == 2)
if ((hDLL = MODULE_LoadModule16( buffer, TRUE )) == 2)
{
/* file not found */
char *p;
......@@ -765,7 +767,7 @@ static BOOL NE_LoadDLLs( NE_MODULE *pModule )
if (!(p = strrchr( buffer, '\\' ))) p = buffer;
memcpy( p + 1, pstr + 1, *pstr );
strcpy( p + 1 + *pstr, ".dll" );
hDLL = NE_LoadModule( buffer, TRUE );
hDLL = MODULE_LoadModule16( buffer, TRUE );
}
if (hDLL < 32)
{
......@@ -857,23 +859,11 @@ static HINSTANCE16 NE_LoadFileModule( HFILE16 hFile, OFSTRUCT *ofs,
HINSTANCE16 NE_LoadModule( LPCSTR name, BOOL implicit )
{
HINSTANCE16 hInstance;
HMODULE16 hModule;
HFILE16 hFile;
OFSTRUCT ofs;
/* 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 )))
{
MSG( "Could not load Windows DLL '%s', using built-in module.\n",
name );
return hModule;
}
return 2; /* File not found */
}
......@@ -883,6 +873,67 @@ HINSTANCE16 NE_LoadModule( LPCSTR name, BOOL implicit )
return hInstance;
}
/**********************************************************************
* MODULE_LoadModule16
*
* Load a NE module in the order of the loadorder specification.
* The caller is responsible that the module is not loaded already.
*
*/
HINSTANCE16 MODULE_LoadModule16( LPCSTR libname, BOOL implicit )
{
HINSTANCE16 hinst;
int i;
module_loadorder_t *plo;
plo = MODULE_GetLoadOrder(libname);
for(i = 0; i < MODULE_LOADORDER_NTYPES; i++)
{
switch(plo->loadorder[i])
{
case MODULE_LOADORDER_DLL:
TRACE(module, "Trying native dll '%s'\n", libname);
hinst = NE_LoadModule(libname, implicit);
break;
case MODULE_LOADORDER_ELFDLL:
TRACE(module, "Trying elfdll '%s'\n", libname);
hinst = ELFDLL_LoadModule16(libname, implicit);
break;
case MODULE_LOADORDER_BI:
TRACE(module, "Trying built-in '%s'\n", libname);
hinst = fnBUILTIN_LoadModule(libname, TRUE);
break;
default:
ERR(module, "Got invalid loadorder type %d (%s index %d)\n", plo->loadorder[i], plo->modulename, i);
/* Fall through */
case MODULE_LOADORDER_SO: /* This is not supported for NE modules */
case MODULE_LOADORDER_INVALID: /* We ignore this as it is an empty entry */
hinst = 2;
break;
}
if(hinst >= 32)
{
TRACE(module, "Loaded module '%s' at 0x%04x, \n", libname, hinst);
return hinst;
}
if(hinst != 2)
{
/* We quit searching when we get another error than 'File not found' */
break;
}
}
return hinst; /* The last error that occured */
}
/**********************************************************************
* LoadModule16 (KERNEL.45)
*/
......@@ -918,7 +969,7 @@ HINSTANCE16 WINAPI LoadModule16( LPCSTR name, LPVOID paramBlock )
{
/* Main case: load first instance of NE module */
if ( (hInstance = NE_LoadModule( name, FALSE )) < 32 )
if ( (hInstance = MODULE_LoadModule16( name, FALSE )) < 32 )
return hInstance;
if ( !(pModule = NE_GetPtr( hInstance )) )
......
......@@ -196,7 +196,7 @@ FARPROC PE_FindExportedFunction(
}
if (forward)
{
HMODULE hMod;
WINE_MODREF *wm;
char module[256];
char *end = strchr(forward, '.');
......@@ -204,9 +204,9 @@ FARPROC PE_FindExportedFunction(
assert(end-forward<256);
strncpy(module, forward, (end - forward));
module[end-forward] = 0;
hMod = MODULE_FindModule( module );
assert(hMod);
return MODULE_GetProcAddress( hMod, end + 1, snoop );
wm = MODULE_FindModule( module );
assert(wm);
return MODULE_GetProcAddress( wm->module, end + 1, snoop );
}
return NULL;
}
......@@ -214,7 +214,6 @@ FARPROC PE_FindExportedFunction(
DWORD fixup_imports( WINE_MODREF *wm )
{
IMAGE_IMPORT_DESCRIPTOR *pe_imp;
WINE_MODREF *xwm;
PE_MODREF *pem;
unsigned int load_addr = wm->module;
int i,characteristics_detection=1;
......@@ -256,7 +255,7 @@ DWORD fixup_imports( WINE_MODREF *wm )
*/
for (i = 0, pe_imp = pem->pe_import; pe_imp->Name ; pe_imp++) {
HMODULE hImpModule;
WINE_MODREF *wmImp;
IMAGE_IMPORT_BY_NAME *pe_name;
PIMAGE_THUNK_DATA import_list,thunk_list;
char *name = (char *) RVA(pe_imp->Name);
......@@ -265,8 +264,8 @@ DWORD fixup_imports( WINE_MODREF *wm )
break;
/* don't use MODULE_Load, Win32 creates new task differently */
hImpModule = MODULE_LoadLibraryExA( name, 0, 0 );
if (!hImpModule) {
wmImp = MODULE_LoadLibraryExA( name, 0, 0 );
if (!wmImp) {
char *p,buffer[2000];
/* GetModuleFileName would use the wrong process, so don't use it */
......@@ -274,15 +273,13 @@ DWORD fixup_imports( WINE_MODREF *wm )
if (!(p = strrchr (buffer, '\\')))
p = buffer;
strcpy (p + 1, name);
hImpModule = MODULE_LoadLibraryExA( buffer, 0, 0 );
wmImp = MODULE_LoadLibraryExA( buffer, 0, 0 );
}
if (!hImpModule) {
if (!wmImp) {
ERR (module, "Module %s not found\n", name);
return 1;
}
xwm = MODULE32_LookupHMODULE( hImpModule );
assert( xwm );
wm->deps[i++] = xwm;
wm->deps[i++] = wmImp;
/* FIXME: forwarder entries ... */
......@@ -297,7 +294,7 @@ DWORD fixup_imports( WINE_MODREF *wm )
TRACE(win32, "--- Ordinal %s,%d\n", name, ordinal);
thunk_list->u1.Function=MODULE_GetProcAddress(
hImpModule, (LPCSTR)ordinal, TRUE
wmImp->module, (LPCSTR)ordinal, TRUE
);
if (!thunk_list->u1.Function) {
ERR(win32,"No implementation for %s.%d, setting to 0xdeadbeef\n",
......@@ -308,7 +305,7 @@ DWORD fixup_imports( WINE_MODREF *wm )
pe_name = (PIMAGE_IMPORT_BY_NAME)RVA(import_list->u1.AddressOfData);
TRACE(win32, "--- %s %s.%d\n", pe_name->Name, name, pe_name->Hint);
thunk_list->u1.Function=MODULE_GetProcAddress(
hImpModule, pe_name->Name, TRUE
wmImp->module, pe_name->Name, TRUE
);
if (!thunk_list->u1.Function) {
ERR(win32,"No implementation for %s.%d(%s), setting to 0xdeadbeef\n",
......@@ -329,7 +326,7 @@ DWORD fixup_imports( WINE_MODREF *wm )
TRACE(win32,"--- Ordinal %s.%d\n",name,ordinal);
thunk_list->u1.Function=MODULE_GetProcAddress(
hImpModule, (LPCSTR) ordinal, TRUE
wmImp->module, (LPCSTR) ordinal, TRUE
);
if (!thunk_list->u1.Function) {
ERR(win32, "No implementation for %s.%d, setting to 0xdeadbeef\n",
......@@ -341,7 +338,7 @@ DWORD fixup_imports( WINE_MODREF *wm )
TRACE(win32,"--- %s %s.%d\n",
pe_name->Name,name,pe_name->Hint);
thunk_list->u1.Function=MODULE_GetProcAddress(
hImpModule, pe_name->Name, TRUE
wmImp->module, pe_name->Name, TRUE
);
if (!thunk_list->u1.Function) {
ERR(win32, "No implementation for %s.%d, setting to 0xdeadbeef\n",
......@@ -829,68 +826,76 @@ WINE_MODREF *PE_CreateModule( HMODULE hModule,
* The PE Library Loader frontend.
* FIXME: handle the flags.
*/
HMODULE PE_LoadLibraryExA (LPCSTR name,
HFILE hFile, DWORD flags)
WINE_MODREF *PE_LoadLibraryExA (LPCSTR name, DWORD flags, DWORD *err)
{
LPCSTR modName = NULL;
OFSTRUCT ofs;
HMODULE hModule32;
HMODULE16 hModule16;
NE_MODULE *pModule;
WINE_MODREF *wm;
BOOL builtin = TRUE;
char dllname[256], *p;
/* Check for already loaded module */
if ((hModule32 = MODULE_FindModule( name )))
return hModule32;
/* Append .DLL to name if no extension present */
strcpy( dllname, name );
if (!(p = strrchr( dllname, '.')) || strchr( p, '/' ) || strchr( p, '\\'))
strcat( dllname, ".DLL" );
/* Try to load builtin enabled modules first */
if ( !(hModule32 = BUILTIN32_LoadImage( name, &ofs, FALSE )) )
{
/* Load PE module */
hFile = OpenFile( dllname, &ofs, OF_READ | OF_SHARE_DENY_WRITE );
if ( hFile != HFILE_ERROR )
if ( (hModule32 = PE_LoadImage( hFile, &ofs, &modName )) >= 32 )
builtin = FALSE;
CloseHandle( hFile );
}
LPCSTR modName = NULL;
OFSTRUCT ofs;
HMODULE hModule32;
HMODULE16 hModule16;
NE_MODULE *pModule;
WINE_MODREF *wm;
BOOL builtin = TRUE;
char dllname[256], *p;
HFILE hFile;
/* Append .DLL to name if no extension present */
strcpy( dllname, name );
if (!(p = strrchr( dllname, '.')) || strchr( p, '/' ) || strchr( p, '\\'))
strcat( dllname, ".DLL" );
/* Load PE module */
hFile = OpenFile( dllname, &ofs, OF_READ | OF_SHARE_DENY_WRITE );
if ( hFile != HFILE_ERROR )
{
hModule32 = PE_LoadImage( hFile, &ofs, &modName );
CloseHandle( hFile );
if(!hModule32)
{
*err = ERROR_OUTOFMEMORY; /* Not entirely right, but good enough */
return NULL;
}
}
else
{
*err = ERROR_FILE_NOT_FOUND;
return NULL;
}
/* Now try the built-in even if disabled */
if ( builtin ) {
if ( (hModule32 = BUILTIN32_LoadImage( name, &ofs, TRUE )) )
WARN( module, "Could not load external DLL '%s', using built-in module.\n", name );
else
return 0;
}
/* Create 16-bit dummy module */
if ((hModule16 = MODULE_CreateDummyModule( &ofs, modName )) < 32)
{
*err = (DWORD)hModule16; /* This should give the correct error */
return NULL;
}
pModule = (NE_MODULE *)GlobalLock16( hModule16 );
pModule->flags = NE_FFLAGS_LIBMODULE | NE_FFLAGS_SINGLEDATA | NE_FFLAGS_WIN32;
pModule->module32 = hModule32;
/* Create 32-bit MODREF */
if ( !(wm = PE_CreateModule( hModule32, &ofs, flags, builtin )) )
{
ERR(win32,"can't load %s\n",ofs.szPathName);
FreeLibrary16( hModule16 );
*err = ERROR_OUTOFMEMORY;
return NULL;
}
/* Create 16-bit dummy module */
if ((hModule16 = MODULE_CreateDummyModule( &ofs, modName )) < 32) return hModule16;
pModule = (NE_MODULE *)GlobalLock16( hModule16 );
pModule->flags = NE_FFLAGS_LIBMODULE | NE_FFLAGS_SINGLEDATA |
NE_FFLAGS_WIN32 | (builtin? NE_FFLAGS_BUILTIN : 0);
pModule->module32 = hModule32;
if (wm->binfmt.pe.pe_export)
SNOOP_RegisterDLL(wm->module,wm->modname,wm->binfmt.pe.pe_export->NumberOfFunctions);
/* Create 32-bit MODREF */
if ( !(wm = PE_CreateModule( hModule32, &ofs, flags, builtin )) )
{
ERR(win32,"can't load %s\n",ofs.szPathName);
FreeLibrary16( hModule16 );
return 0;
}
*err = 0;
return wm;
}
if (wm->binfmt.pe.pe_export)
SNOOP_RegisterDLL(wm->module,wm->modname,wm->binfmt.pe.pe_export->NumberOfFunctions);
return wm->module;
/*****************************************************************************
* PE_UnloadLibrary
*
* Unload the library unmapping the image and freeing the modref structure.
*/
void PE_UnloadLibrary(WINE_MODREF *wm)
{
/* FIXME, do something here */
}
/*****************************************************************************
......@@ -958,18 +963,11 @@ int PE_UnloadImage( HMODULE hModule )
* DLL_PROCESS_ATTACH. Only new created threads do DLL_THREAD_ATTACH
* (SDK)
*/
void PE_InitDLL(WINE_MODREF *wm, DWORD type, LPVOID lpReserved)
BOOL PE_InitDLL( WINE_MODREF *wm, DWORD type, LPVOID lpReserved )
{
if (wm->type!=MODULE32_PE)
return;
/* DLL_ATTACH_PROCESS:
* lpreserved is NULL for dynamic loads, not-NULL for static loads
* DLL_DETACH_PROCESS:
* lpreserved is NULL if called by FreeLibrary, not-NULL otherwise
* the SDK doesn't mention anything for DLL_THREAD_*
*/
BOOL retv = TRUE;
assert( wm->type == MODULE32_PE );
/* Is this a library? And has it got an entrypoint? */
if ((PE_HEADER(wm->module)->FileHeader.Characteristics & IMAGE_FILE_DLL) &&
(PE_HEADER(wm->module)->OptionalHeader.AddressOfEntryPoint)
......@@ -978,8 +976,10 @@ void PE_InitDLL(WINE_MODREF *wm, DWORD type, LPVOID lpReserved)
TRACE(relay, "CallTo32(entryproc=%p,module=%08x,type=%ld,res=%p)\n",
entry, wm->module, type, lpReserved );
entry( wm->module, type, lpReserved );
retv = entry( wm->module, type, lpReserved );
}
return retv;
}
/************************************************************************
......
......@@ -388,7 +388,11 @@ HGLOBAL16 WINAPI GlobalReAlloc16(
TRACE(global,"oldsize %08lx\n",oldsize);
if (ptr && (size == oldsize)) return handle; /* Nothing to do */
ptr = HeapReAlloc( SystemHeap, 0, ptr, size );
if (((char *)ptr >= DOSMEM_MemoryBase(0)) &&
((char *)ptr <= DOSMEM_MemoryBase(0) + 0x100000))
ptr = DOSMEM_ResizeBlock(0, ptr, size, NULL);
else
ptr = HeapReAlloc( SystemHeap, 0, ptr, size );
if (!ptr)
{
SELECTOR_FreeBlock( sel, (oldsize + 0xffff) / 0x10000 );
......
......@@ -812,10 +812,6 @@ BOOL MAIN_WineInit( int *argc, char *argv[] )
MONITOR_Initialize(&MONITOR_PrimaryMonitor);
if (Options.dllFlags)
BUILTIN32_ParseDLLOptions( Options.dllFlags );
/* if (__winelib && errors ) print_error_message_like_misc_main(); */
atexit(called_at_exit);
return TRUE;
}
......
......@@ -140,18 +140,6 @@ int main( int argc, char *argv[] )
if (!MAIN_WineInit( &argc, argv )) return 1;
MAIN_argc = argc; MAIN_argv = argv;
/* Handle -dll option (hack) */
if (Options.dllFlags)
{
/* If there are options left, or if the parser had errors, report it */
if (!BUILTIN_ParseDLLOptions( Options.dllFlags )||Options.dllFlags[0]) {
MSG("%s: Syntax: -dll +xxx,... or -dll -xxx,...\n",
argv[0] );
BUILTIN_PrintDLLs();
exit(1);
}
}
/* Set up debugger/instruction emulation callback routines */
ctx_debug_call = ctx_debug;
fnWINE_Debugger = wine_debug;
......
......@@ -14,6 +14,8 @@
#include "heap.h"
#include "debug.h"
#include "main.h"
#include "snoop.h"
#include "winerror.h"
typedef struct
{
......@@ -321,6 +323,77 @@ HMODULE BUILTIN32_LoadImage( LPCSTR name, OFSTRUCT *ofs, BOOL force )
/***********************************************************************
* BUILTIN32_LoadLibraryExA
*
* Partly copied from the original PE_ version.
*
* Note: This implementation is not very nice and should be one with
* the BUILTIN32_LoadImage function. But, we don't care too much
* because this code will obsolete itself shortly when we get the
* modularization of wine implemented (BS 05-Mar-1999).
*/
WINE_MODREF *BUILTIN32_LoadLibraryExA(LPCSTR path, DWORD flags, DWORD *err)
{
LPCSTR modName = NULL;
OFSTRUCT ofs;
HMODULE hModule32;
HMODULE16 hModule16;
NE_MODULE *pModule;
WINE_MODREF *wm;
char dllname[256], *p;
/* Append .DLL to name if no extension present */
strcpy( dllname, path );
if (!(p = strrchr( dllname, '.')) || strchr( p, '/' ) || strchr( p, '\\'))
strcat( dllname, ".DLL" );
hModule32 = BUILTIN32_LoadImage( path, &ofs, TRUE );
if(!hModule32)
{
*err = ERROR_FILE_NOT_FOUND;
return NULL;
}
/* Create 16-bit dummy module */
if ((hModule16 = MODULE_CreateDummyModule( &ofs, modName )) < 32)
{
*err = (DWORD)hModule16;
return NULL; /* FIXME: Should unload the builtin module */
}
pModule = (NE_MODULE *)GlobalLock16( hModule16 );
pModule->flags = NE_FFLAGS_LIBMODULE | NE_FFLAGS_SINGLEDATA | NE_FFLAGS_WIN32 | NE_FFLAGS_BUILTIN;
pModule->module32 = hModule32;
/* Create 32-bit MODREF */
if ( !(wm = PE_CreateModule( hModule32, &ofs, flags, TRUE )) )
{
ERR(win32,"can't load %s\n",ofs.szPathName);
FreeLibrary16( hModule16 ); /* FIXME: Should unload the builtin module */
*err = ERROR_OUTOFMEMORY;
return NULL;
}
if (wm->binfmt.pe.pe_export)
SNOOP_RegisterDLL(wm->module,wm->modname,wm->binfmt.pe.pe_export->NumberOfFunctions);
*err = 0;
return wm;
}
/***********************************************************************
* BUILTIN32_UnloadLibrary
*
* Unload the built-in library and free the modref.
*/
void BUILTIN32_UnloadLibrary(WINE_MODREF *wm)
{
/* FIXME: do something here */
}
/***********************************************************************
* BUILTIN32_GetEntryPoint
*
* Return the name of the DLL entry point corresponding
......@@ -435,74 +508,3 @@ void BUILTIN32_Unimplemented( const BUILTIN32_DESCRIPTOR *descr, int ordinal )
ExitProcess(1);
}
/***********************************************************************
* BUILTIN32_ParseDLLOptions
*
* Set runtime DLL usage flags
*/
BOOL BUILTIN32_ParseDLLOptions( char *str )
{
BUILTIN32_DLL *dll;
char *p,*last;
last = str;
while (*str)
{
while (*str && (*str==',' || isspace(*str))) str++;
if (!*str) {
*last = '\0'; /* cut off garbage at end at */
return TRUE;
}
if ((*str != '+') && (*str != '-')) return FALSE;
str++;
if (!(p = strchr( str, ',' ))) p = str + strlen(str);
while ((p > str) && isspace(p[-1])) p--;
if (p == str) return FALSE;
for (dll = BuiltinDLLs; dll->descr; dll++)
{
if (!lstrncmpiA( dll->descr->name, str, (int)(p-str) ))
{
if (dll->descr->name[p-str]) /* partial match - skip */
continue;
dll->used = (str[-1]!='-');
break;
}
}
if (!dll->descr) {
/* not found, but could get handled by BUILTIN_, so move last */
last = p;
str = p;
} else {
/* handled. cut out the "[+-]DLL," string, so it isn't handled
* by BUILTIN
*/
if (*p) {
memcpy(last,p,strlen(p)+1);
str = last;
} else {
*last = '\0';
break;
}
}
}
return TRUE;
}
/***********************************************************************
* BUILTIN32_PrintDLLs
*
* Print the list of built-in DLLs that can be disabled.
*/
void BUILTIN32_PrintDLLs(void)
{
int i;
BUILTIN32_DLL *dll;
MSG("Available Win32 DLLs:\n");
for (i = 0, dll = BuiltinDLLs; dll->descr; dll++)
MSG("%-9s%c", dll->descr->name,
((++i) % 8) ? ' ' : '\n' );
MSG("\n");
}
......@@ -486,6 +486,10 @@ void PROCESS_Start(void)
/* Create 32-bit MODREF */
if (!PE_CreateModule( pModule->module32, ofs, 0, FALSE )) goto error;
/* Increment EXE refcount */
assert( PROCESS_Current()->exe_modref );
PROCESS_Current()->exe_modref->refCount++;
PROCESS_CallUserSignalProc( USIG_PROCESS_LOADED, 0, 0 ); /* FIXME: correct location? */
/* Initialize thread-local storage */
......@@ -497,7 +501,9 @@ void PROCESS_Start(void)
/* Now call the entry point */
MODULE_InitializeDLLs( 0, DLL_PROCESS_ATTACH, (LPVOID)1 );
EnterCriticalSection( &PROCESS_Current()->crit_section );
MODULE_DllProcessAttach( PROCESS_Current()->exe_modref, (LPVOID)1 );
LeaveCriticalSection( &PROCESS_Current()->crit_section );
PROCESS_CallUserSignalProc( USIG_PROCESS_RUNNING, 0, 0 );
......@@ -651,7 +657,9 @@ error:
*/
void WINAPI ExitProcess( DWORD status )
{
MODULE_InitializeDLLs( 0, DLL_PROCESS_DETACH, (LPVOID)1 );
EnterCriticalSection( &PROCESS_Current()->crit_section );
MODULE_DllProcessDetach( TRUE, (LPVOID)1 );
LeaveCriticalSection( &PROCESS_Current()->crit_section );
if ( THREAD_IsWin16( THREAD_Current() ) )
TASK_KillCurrentTask( status );
......
......@@ -281,7 +281,7 @@ static void THREAD_Start(void)
LPTHREAD_START_ROUTINE func = (LPTHREAD_START_ROUTINE)thdb->entry_point;
PROCESS_CallUserSignalProc( USIG_THREAD_INIT, 0, 0 );
PE_InitTls();
MODULE_InitializeDLLs( 0, DLL_THREAD_ATTACH, NULL );
MODULE_DllThreadAttach( NULL );
ExitThread( func( thdb->entry_arg ) );
}
......@@ -318,7 +318,7 @@ HANDLE WINAPI CreateThread( SECURITY_ATTRIBUTES *sa, DWORD stack,
*/
void WINAPI ExitThread( DWORD code ) /* [in] Exit code for this thread */
{
MODULE_InitializeDLLs( 0, DLL_THREAD_DETACH, NULL );
MODULE_DllThreadDetach( NULL );
TerminateThread( GetCurrentThread(), code );
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment