update on ntdll/kernel32
Eric Pouech
eric.pouech at wanadoo.fr
Sat Jan 11 11:11:00 CST 2003
this patch supersedes the previous one ;-)
what's new:
- a few more implemented functions (LdrQueryProcessModuleInformation)
- a few more used fields in the LDR_MODULE structure (mainly the
internal lists)
- better split of resource related functions
- a few cleanups
daredevils can try to play with it :-O
A+
--
Eric Pouech
-------------- next part --------------
Name: ntkrnl
ChangeLog: started splitting kernel & ntdll regarding module management
License: X11
GenDate: 2003/01/11 17:07:45 UTC
ModifiedFiles: dlls/ntdll/loader.c dlls/ntdll/ntdll.spec include/module.h loader/elf.c loader/module.c loader/pe_image.c loader/pe_resource.c loader/resource.c misc/version.c relay32/builtin32.c relay32/relay386.c scheduler/process.c scheduler/thread.c tools/winebuild/spec16.c
AddedFiles:
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/dlls/ntdll/loader.c,v
retrieving revision 1.8
diff -u -u -r1.8 loader.c
--- dlls/ntdll/loader.c 12 Dec 2002 23:34:02 -0000 1.8
+++ dlls/ntdll/loader.c 14 Dec 2002 20:17:22 -0000
@@ -36,49 +36,6 @@
}
-NTSTATUS WINAPI LdrDisableThreadCalloutsForDll(HANDLE hModule)
-{
- if (DisableThreadLibraryCalls(hModule))
- return STATUS_SUCCESS;
- else
- return STATUS_DLL_NOT_FOUND;
-}
-
-/* FIXME : MODULE_FindModule should depend on LdrGetDllHandle, not vice-versa */
-
-NTSTATUS WINAPI LdrGetDllHandle(ULONG x, LONG y, PUNICODE_STRING name, PVOID *base)
-{
- STRING str;
- WINE_MODREF *wm;
-
- FIXME("%08lx %08lx %s %p : partial stub\n",x,y,debugstr_wn(name->Buffer,name->Length),base);
-
- *base = 0;
-
- RtlUnicodeStringToAnsiString(&str, name, TRUE);
- wm = MODULE_FindModule(str.Buffer);
- if(!wm)
- return STATUS_DLL_NOT_FOUND;
- *base = (PVOID) wm->module;
-
- return STATUS_SUCCESS;
-}
-
-/* FIXME : MODULE_GetProcAddress should depend on LdrGetProcedureAddress, not vice-versa */
-
-NTSTATUS WINAPI LdrGetProcedureAddress(PVOID base, PANSI_STRING name, ULONG ord, PVOID *address)
-{
- WARN("%p %s %ld %p\n",base, debugstr_an(name->Buffer,name->Length), ord, address);
-
- if(name)
- *address = MODULE_GetProcAddress( (HMODULE) base, name->Buffer, -1, FALSE);
- else
- *address = MODULE_GetProcAddress( (HMODULE) base, (LPSTR) ord, -1, FALSE);
-
- return (*address) ? STATUS_SUCCESS : STATUS_DLL_NOT_FOUND;
-}
-
-
/***********************************************************************
* RtlImageNtHeader (NTDLL.@)
*/
Index: dlls/ntdll/ntdll.spec
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/dlls/ntdll/ntdll.spec,v
retrieving revision 1.86
diff -u -u -r1.86 ntdll.spec
--- dlls/ntdll/ntdll.spec 12 Dec 2002 02:20:47 -0000 1.86
+++ dlls/ntdll/ntdll.spec 10 Jan 2003 20:12:18 -0000
@@ -33,22 +33,22 @@
@ stub KiUserApcDispatcher
@ stub KiUserCallbackDispatcher
@ stub KiUserExceptionDispatcher
-@ stub LdrAccessResource
+@ stdcall LdrAccessResource(ptr ptr ptr ptr) LdrAccessResource
@ stdcall LdrDisableThreadCalloutsForDll(long) LdrDisableThreadCalloutsForDll
@ stub LdrEnumResources
-@ stub LdrFindEntryForAddress
-@ stub LdrFindResourceDirectory_U
-@ stub LdrFindResource_U
+@ stdcall LdrFindEntryForAddress(ptr ptr) LdrFindEntryForAddress
+@ stdcall LdrFindResourceDirectory_U(ptr ptr long ptr) LdrFindResourceDirectory_U
+@ stdcall LdrFindResource_U(ptr ptr long ptr) LdrFindResource_U
@ stdcall LdrGetDllHandle(long long ptr ptr) LdrGetDllHandle
@ stdcall LdrGetProcedureAddress(ptr ptr long ptr) LdrGetProcedureAddress
@ stub LdrInitializeThunk
-@ stub LdrLoadDll
+@ stdcall LdrLoadDll(str long ptr ptr) LdrLoadDll
@ stub LdrProcessRelocationBlock
@ stub LdrQueryImageFileExecutionOptions
-@ stub LdrQueryProcessModuleInformation
-@ stub LdrShutdownProcess
-@ stub LdrShutdownThread
-@ stub LdrUnloadDll
+@ stdcall LdrQueryProcessModuleInformation(ptr long ptr) LdrQueryProcessModuleInformation
+@ stdcall LdrShutdownProcess() LdrShutdownProcess
+@ stdcall LdrShutdownThread() LdrShutdownThread
+@ stdcall LdrUnloadDll(long) LdrUnloadDll
@ stub LdrVerifyImageMatchesChecksum
@ stub NPXEMULATORTABLE
@ extern NlsAnsiCodePage NlsAnsiCodePage
Index: include/module.h
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/include/module.h,v
retrieving revision 1.69
diff -u -u -r1.69 module.h
--- include/module.h 16 Aug 2002 20:02:54 -0000 1.69
+++ include/module.h 11 Jan 2003 15:45:31 -0000
@@ -23,9 +23,93 @@
#include "windef.h"
#include "winbase.h"
+#include "winternl.h"
#include "wine/windef16.h"
#include "wine/winbase16.h"
+/* FIXME: which place ?
+ * a few macros for double linked list manipulation
+ */
+#define InitializeListHead(head_list) ((head_list)->Flink = (head_list)->Blink = (head_list))
+#define IsListEmpty(head_list) ((head_list)->Flink == (head_list))
+#define RemoveHeadList(head_list) RemoveEntryList((head_list)->Flink)
+#define RemoveTailList(head_list) RemoveEntryList((head_list)->Blink)
+#define RemoveEntryList(entry) {\
+ PLIST_ENTRY bl = (entry)->Flink, fl = (entry)->Blink; \
+ bl->Flink = fl; fl->Blink = bl;}
+#define InsertTailList(head_list,entry) {\
+ PLIST_ENTRY bl = (head_list)->Blink, hl = (head_list);\
+ (entry)->Flink = hl; (entry)->Blink = bl; bl->Flink = (entry); hl->Blink = (entry);}
+#define InsertHeadList(head_list,entry) {\
+ PLIST_ENTRY fl = head_list->Flink, hl = (head_list);\
+ (entry)->Flink = fl; (entry)->Blink = hl; fl->Blink = (entry); hl->Flink = (entry);}
+
+#define RESOURCE_TYPE_LEVEL 0
+#define RESOURCE_NAME_LEVEL 1
+#define RESOURCE_LANGUAGE_LEVEL 2
+#define RESOURCE_DATA_LEVEL 3
+
+typedef struct _LDR_RESOURCE_INFO
+{
+ ULONG Type;
+ ULONG Name;
+ ULONG Language;
+} LDR_RESOURCE_INFO, *PLDR_RESOURCE_INFO;
+
+/* FIXME: the WINE_MODREF structure should include this structure */
+typedef struct _LDR_MODULE
+{
+ LIST_ENTRY InLoadOrderModuleList; /* not used */
+ LIST_ENTRY InMemoryOrderModuleList;/* not used */
+ LIST_ENTRY InInitializationOrderModuleList;/* not used */
+ void* BaseAddress;
+ ULONG EntryPoint; /* not used */
+ ULONG SizeOfImage; /* not used */
+ UNICODE_STRING FullDllName;
+ UNICODE_STRING BaseDllName;
+ ULONG Flags;
+ SHORT LoadCount; /* number of refs to this module */
+ SHORT TlsIndex; /* TLS index or -1 if none */
+ HANDLE SectionHandle; /* not used */
+ ULONG CheckSum; /* not used */
+ ULONG TimeDateStamp; /* not used */
+} LDR_MODULE, *PLDR_MODULE;
+
+/* FIXME: to be checked */
+#define MAXIMUM_FILENAME_LENGTH 256
+
+typedef struct _SYSTEM_MODULE
+{
+ ULONG Reserved1;
+ ULONG Reserved2;
+ PVOID ImageBaseAddress;
+ ULONG ImageSize;
+ ULONG Flags;
+ WORD Id;
+ WORD Rank;
+ WORD w018;
+ WORD NameOffset;
+ BYTE Name[MAXIMUM_FILENAME_LENGTH];
+} SYSTEM_MODULE, *PSYSTEM_MODULE;
+
+typedef struct _SYSTEM_MODULE_INFORMATION
+{
+ ULONG ModulesCount;
+ SYSTEM_MODULE Modules[0];
+} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
+
+
+/* Flags bit mask */
+#define WINE_MODREF_INTERNAL 0x00000001
+#define WINE_MODREF_NO_DLL_CALLS 0x00000002
+#define WINE_MODREF_PROCESS_ATTACHED 0x00000004
+#define WINE_MODREF_DONT_RESOLVE_REFS 0x00000020
+#define WINE_MODREF_MARKER 0x80000000
+
+/* those following definitions are only for within NTDLL */
+
+#if defined(_NTSYSTEM_) || defined(_KERNEL32_)
+
/* In-memory module structure. See 'Windows Internals' p. 219 */
typedef struct _NE_MODULE
{
@@ -114,6 +198,7 @@
FARPROC16 SetOwner; /* Set Owner procedure, exported by wine */
} SELFLOADHEADER;
+#if 0
typedef struct
{
LPSTR lpEnvAddress;
@@ -121,6 +206,7 @@
UINT16 *lpCmdShow;
DWORD dwReserved;
} LOADPARAMS;
+#endif
#include "poppack.h"
@@ -129,10 +215,8 @@
{
struct _wine_modref *next;
struct _wine_modref *prev;
- HMODULE module;
HMODULE16 hDummyMod; /* Win16 dummy module */
void *dlhandle; /* handle returned by dlopen() */
- int tlsindex; /* TLS index or -1 if none */
FARPROC (*find_export)( struct _wine_modref *wm, LPCSTR func,
int hint, BOOL snoop );
@@ -140,23 +224,16 @@
int nDeps;
struct _wine_modref **deps;
- int flags;
- int refCount;
+ char *filename;
+ char *modname;
- char *filename;
- char *modname;
char *short_filename;
char *short_modname;
- char data[1]; /* space for storing filename and short_filename */
+ LDR_MODULE ldr_module;
+ char data[1]; /* space for storing filename and short_filename */
} WINE_MODREF;
-#define WINE_MODREF_INTERNAL 0x00000001
-#define WINE_MODREF_NO_DLL_CALLS 0x00000002
-#define WINE_MODREF_PROCESS_ATTACHED 0x00000004
-#define WINE_MODREF_DONT_RESOLVE_REFS 0x00000020
-#define WINE_MODREF_MARKER 0x80000000
-
extern WINE_MODREF *MODULE_modref_list;
/* Resource types */
@@ -197,11 +274,8 @@
extern WINE_MODREF *MODULE_AllocModRef( HMODULE hModule, LPCSTR filename );
extern FARPROC MODULE_GetProcAddress( HMODULE hModule, LPCSTR function, int hint, BOOL snoop );
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, HANDLE hfile, DWORD flags );
-extern BOOL MODULE_FreeLibrary( WINE_MODREF *wm );
+extern WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, DWORD flags );
extern WINE_MODREF *MODULE_FindModule( LPCSTR path );
extern HMODULE16 MODULE_CreateDummyModule( LPCSTR filename, HMODULE module32 );
extern enum binary_type MODULE_GetBinaryType( HANDLE hfile );
@@ -222,7 +296,7 @@
extern DWORD NE_StartTask(void);
/* loader/ne/resource.c */
-extern HGLOBAL16 WINAPI NE_DefResourceHandler(HGLOBAL16,HMODULE16,HRSRC16);
+/* EPP extern HGLOBAL16 WINAPI NE_DefResourceHandler(HGLOBAL16,HMODULE16,HRSRC16); */
extern BOOL NE_InitResourceHandler( HMODULE16 hModule );
extern HRSRC NE_FindResource( NE_MODULE *pModule, LPCSTR name, LPCSTR type );
extern DWORD NE_SizeofResource( NE_MODULE *pModule, HRSRC hRsrc );
@@ -246,8 +320,6 @@
/* loader/pe_resource.c */
extern HRSRC PE_FindResourceW(HMODULE,LPCWSTR,LPCWSTR);
extern HRSRC PE_FindResourceExW(HMODULE,LPCWSTR,LPCWSTR,WORD);
-extern DWORD PE_SizeofResource(HRSRC);
-extern HGLOBAL PE_LoadResource(HMODULE,HRSRC);
/* loader/pe_image.c */
extern WINE_MODREF *PE_LoadLibraryExA(LPCSTR, DWORD);
@@ -275,7 +347,9 @@
/* if1632/builtin.c */
extern HMODULE16 BUILTIN_LoadModule( LPCSTR name );
extern BOOL BUILTIN_IsPresent( LPCSTR name );
+#endif
+#if defined(_NTSYSTEM_) || defined(_KERNEL32_) || defined(_USER32_)
/* USER signal proc flags and codes */
/* See PROCESS_CallUserSignalProc for comments */
#define USIG_FLAGS_WIN32 0x0001
@@ -299,5 +373,20 @@
/* scheduler/process.c */
extern void PROCESS_CallUserSignalProc( UINT uCode, HMODULE16 hModule );
+#endif
+
+NTSTATUS WINAPI LdrDisableThreadCalloutsForDll(HMODULE);
+NTSTATUS WINAPI LdrFindEntryForAddress(void*, PLDR_MODULE*);
+NTSTATUS WINAPI LdrGetDllHandle(ULONG, ULONG, PUNICODE_STRING, void**);
+NTSTATUS WINAPI LdrGetProcedureAddress(HMODULE, PANSI_STRING, ULONG, void**);
+NTSTATUS WINAPI LdrLoadDll(LPCSTR, DWORD, PUNICODE_STRING, void**);
+NTSTATUS WINAPI LdrShutdownThread(void);
+NTSTATUS WINAPI LdrShutdownProcess(void);
+NTSTATUS WINAPI LdrUnloadDll(HMODULE);
+NTSTATUS WINAPI LdrAccessResource(HMODULE, PIMAGE_RESOURCE_DATA_ENTRY, void**, PULONG);
+NTSTATUS WINAPI LdrFindResourceDirectory_U(HMODULE, PLDR_RESOURCE_INFO, DWORD,
+ PIMAGE_RESOURCE_DIRECTORY_ENTRY*);
+NTSTATUS WINAPI LdrFindResource_U(HMODULE, PLDR_RESOURCE_INFO, ULONG,
+ PIMAGE_RESOURCE_DATA_ENTRY*);
#endif /* __WINE_MODULE_H */
Index: loader/elf.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/loader/elf.c,v
retrieving revision 1.39
diff -u -u -r1.39 elf.c
--- loader/elf.c 9 Aug 2002 19:57:39 -0000 1.39
+++ loader/elf.c 22 Dec 2002 13:56:12 -0000
@@ -221,7 +221,7 @@
* dlls using cdecl. If we find out the number of args the function
* uses, we remove them from the stack using two small stubs.
*/
- stub = first_stub = (ELF_STDCALL_STUB *)((char *)wm->module + STUBOFFSET);
+ stub = first_stub = (ELF_STDCALL_STUB *)((char *)wm->ldr_module.BaseAddress + STUBOFFSET);
for (i=0;i<STUBSIZE/sizeof(ELF_STDCALL_STUB);i++) {
if (!stub->origfun)
break;
@@ -276,6 +276,6 @@
FIXME("function %s not found: %s\n",funcName,error);
return fun;
}
- fun = SNOOP_GetProcAddress(wm->module,funcName,stub-first_stub,fun);
+ fun = SNOOP_GetProcAddress(wm->ldr_module.BaseAddress,funcName,stub-first_stub,fun);
return (FARPROC)fun;
}
Index: loader/module.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/loader/module.c,v
retrieving revision 1.170
diff -u -u -r1.170 module.c
--- loader/module.c 5 Dec 2002 19:56:15 -0000 1.170
+++ loader/module.c 11 Jan 2003 14:38:35 -0000
@@ -45,6 +45,10 @@
WINE_DECLARE_DEBUG_CHANNEL(win32);
WINE_DECLARE_DEBUG_CHANNEL(loaddll);
+/* FIXME FIXME */
+#define _KERNEL32_
+
+#ifdef _NTSYSTEM_
WINE_MODREF *MODULE_modref_list = NULL;
static WINE_MODREF *exe_modref;
@@ -52,7 +56,9 @@
static int process_detaching; /* set on process detach to avoid deadlocks with thread detach */
static CRITICAL_SECTION loader_section = CRITICAL_SECTION_INIT( "loader_section" );
+#endif
+#ifdef _KERNEL32_
/***********************************************************************
* wait_input_idle
*
@@ -70,8 +76,9 @@
}
return 0;
}
+#endif
-
+#ifdef _NTSYSTEM_
/*************************************************************************
* MODULE32_LookupHMODULE
* looks for the referenced HMODULE in the current process
@@ -86,13 +93,11 @@
if (!HIWORD(hmod)) {
ERR("tried to lookup %p in win32 module handler!\n",hmod);
- SetLastError( ERROR_INVALID_HANDLE );
return NULL;
}
for ( wm = MODULE_modref_list; wm; wm=wm->next )
- if (wm->module == hmod)
+ if (wm->ldr_module.BaseAddress == (void*)hmod)
return wm;
- SetLastError( ERROR_INVALID_HANDLE );
return NULL;
}
@@ -109,11 +114,13 @@
DWORD long_len = strlen( filename );
DWORD short_len = GetShortPathNameA( filename, NULL, 0 );
- if ((wm = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
- sizeof(*wm) + long_len + short_len + 1 )))
- {
- wm->module = hModule;
- wm->tlsindex = -1;
+ /* FIXME: GetProcessHeap isn't part of NTDLL */
+ if ((wm = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY,
+ sizeof(*wm) + long_len + short_len + 1 )))
+ {
+ wm->ldr_module.BaseAddress = (void*)hModule;
+ wm->ldr_module.SizeOfImage = 1; /* FIXME */
+ wm->ldr_module.TlsIndex = -1;
wm->filename = wm->data;
memcpy( wm->filename, filename, long_len + 1 );
@@ -121,19 +128,73 @@
else wm->modname = wm->filename;
wm->short_filename = wm->filename + long_len + 1;
- GetShortPathNameA( wm->filename, wm->short_filename, short_len + 1 );
+ GetShortPathNameA( filename, wm->short_filename, short_len + 1 );
if ((wm->short_modname = strrchr( wm->short_filename, '\\' ))) wm->short_modname++;
else wm->short_modname = wm->short_filename;
+ RtlCreateUnicodeStringFromAsciiz( &wm->ldr_module.FullDllName, wm->filename);
+ RtlCreateUnicodeStringFromAsciiz( &wm->ldr_module.BaseDllName, wm->modname);
+
wm->next = MODULE_modref_list;
if (wm->next) wm->next->prev = wm;
MODULE_modref_list = wm;
if (!(RtlImageNtHeader(hModule)->FileHeader.Characteristics & IMAGE_FILE_DLL))
{
- if (!exe_modref) exe_modref = wm;
+ if (!exe_modref)
+ {
+ exe_modref = wm;
+ InitializeListHead(&exe_modref->ldr_module.InLoadOrderModuleList);
+ InitializeListHead(&exe_modref->ldr_module.InMemoryOrderModuleList);
+ InitializeListHead(&exe_modref->ldr_module.InInitializationOrderModuleList);
+ }
else FIXME( "Trying to load second .EXE file: %s\n", filename );
}
+ else
+ {
+ WINE_MODREF* mwm;
+ WINE_MODREF* before = NULL;
+
+ if (!exe_modref)
+ {
+ /* FIXME: today, ntdll gets loaded before the process itself (because of the
+ * ELF level dependency from wine executable on ntdll.dll.so
+ * As a result, we won't link the ntdll DLL in the LoadOrder nor in
+ * the MemoryOrder modules list
+ * This shall disappear as soon as wine executable doesn't load the ntdll DLL
+ * before the main module
+ */
+ FIXME("Loading DLL %s before executable image\n", filename);
+ }
+ else
+ {
+ InsertTailList(&exe_modref->ldr_module.InLoadOrderModuleList,
+ &wm->ldr_module.InLoadOrderModuleList);
+ mwm = exe_modref;
+ do
+ {
+ if (mwm->ldr_module.BaseAddress > wm->ldr_module.BaseAddress)
+ {
+ before = mwm;
+ break;
+ }
+ mwm = CONTAINING_RECORD(mwm->ldr_module.InMemoryOrderModuleList.Flink,
+ WINE_MODREF, ldr_module.InMemoryOrderModuleList);
+ } while (mwm != exe_modref);
+ if (before)
+ {
+ mwm = CONTAINING_RECORD(mwm->ldr_module.InMemoryOrderModuleList.Blink,
+ WINE_MODREF, ldr_module.InMemoryOrderModuleList);
+ mwm->ldr_module.InMemoryOrderModuleList.Flink = &wm->ldr_module.InMemoryOrderModuleList;
+ wm->ldr_module.InMemoryOrderModuleList.Flink = &before->ldr_module.InMemoryOrderModuleList;
+ before->ldr_module.InMemoryOrderModuleList.Blink = &wm->ldr_module.InMemoryOrderModuleList;
+ wm->ldr_module.InMemoryOrderModuleList.Blink = &mwm->ldr_module.InMemoryOrderModuleList;
+ }
+ else
+ InsertTailList(&exe_modref->ldr_module.InMemoryOrderModuleList,
+ &wm->ldr_module.InMemoryOrderModuleList);
+ }
+ }
}
return wm;
}
@@ -151,12 +212,13 @@
/* Skip calls for modules loaded with special load flags */
- if (wm->flags & WINE_MODREF_DONT_RESOLVE_REFS) return TRUE;
+ if (wm->ldr_module.Flags & WINE_MODREF_DONT_RESOLVE_REFS) return TRUE;
- TRACE("(%s,%s,%p) - CALL\n", wm->modname, typeName[type], lpReserved );
+ TRACE("(%s,%s,%p) - CALL\n",
+ debugstr_w(wm->ldr_module.BaseDllName.Buffer), typeName[type], lpReserved );
/* Call the initialization routine */
- retv = PE_InitDLL( wm->module, type, lpReserved );
+ retv = PE_InitDLL( wm->ldr_module.BaseAddress, type, lpReserved );
/* The state of the module list may have changed due to the call
to PE_InitDLL. We cannot assume that this module has not been
@@ -210,14 +272,14 @@
assert( wm );
/* prevent infinite recursion in case of cyclical dependencies */
- if ( ( wm->flags & WINE_MODREF_MARKER )
- || ( wm->flags & WINE_MODREF_PROCESS_ATTACHED ) )
+ if ( ( wm->ldr_module.Flags & WINE_MODREF_MARKER )
+ || ( wm->ldr_module.Flags & WINE_MODREF_PROCESS_ATTACHED ) )
goto done;
- TRACE("(%s,%p) - START\n", wm->modname, lpReserved );
+ TRACE("(%s,%p) - START\n", debugstr_w(wm->ldr_module.BaseDllName.Buffer), lpReserved);
/* Tag current MODREF to prevent recursive loop */
- wm->flags |= WINE_MODREF_MARKER;
+ wm->ldr_module.Flags |= WINE_MODREF_MARKER;
/* Recursively attach all DLLs this one depends on */
for ( i = 0; retv && i < wm->nDeps; i++ )
@@ -229,7 +291,11 @@
{
retv = MODULE_InitDLL( wm, DLL_PROCESS_ATTACH, lpReserved );
if ( retv )
- wm->flags |= WINE_MODREF_PROCESS_ATTACHED;
+ {
+ wm->ldr_module.Flags |= WINE_MODREF_PROCESS_ATTACHED;
+ InsertTailList(&exe_modref->ldr_module.InInitializationOrderModuleList,
+ &wm->ldr_module.InInitializationOrderModuleList);
+ }
}
/* Re-insert MODREF at head of list */
@@ -244,9 +310,9 @@
}
/* Remove recursion flag */
- wm->flags &= ~WINE_MODREF_MARKER;
+ wm->ldr_module.Flags &= ~WINE_MODREF_MARKER;
- TRACE("(%s,%p) - END\n", wm->modname, lpReserved );
+ TRACE("(%s,%p) - END\n", debugstr_w(wm->ldr_module.BaseDllName.Buffer), lpReserved );
done:
RtlLeaveCriticalSection( &loader_section );
@@ -260,7 +326,7 @@
* sequence at MODULE_DllProcessAttach. Unless the bForceDetach flag
* is set, only DLLs with zero refcount are notified.
*/
-void MODULE_DllProcessDetach( BOOL bForceDetach, LPVOID lpReserved )
+static void MODULE_DllProcessDetach( BOOL bForceDetach, LPVOID lpReserved )
{
WINE_MODREF *wm;
@@ -271,13 +337,13 @@
for ( wm = MODULE_modref_list; wm; wm = wm->next )
{
/* Check whether to detach this DLL */
- if ( !(wm->flags & WINE_MODREF_PROCESS_ATTACHED) )
+ if ( !(wm->ldr_module.Flags & WINE_MODREF_PROCESS_ATTACHED) )
continue;
- if ( wm->refCount > 0 && !bForceDetach )
+ if ( wm->ldr_module.LoadCount > 0 && !bForceDetach )
continue;
/* Call detach notification */
- wm->flags &= ~WINE_MODREF_PROCESS_ATTACHED;
+ wm->ldr_module.Flags &= ~WINE_MODREF_PROCESS_ATTACHED;
MODULE_InitDLL( wm, DLL_PROCESS_DETACH, lpReserved );
/* Restart at head of WINE_MODREF list, as entries might have
@@ -289,6 +355,18 @@
RtlLeaveCriticalSection( &loader_section );
}
+/******************************************************************
+ * LdrShutdownProcess
+ *
+ *
+ */
+NTSTATUS WINAPI LdrShutdownProcess(void)
+{
+ TRACE("()\n");
+ MODULE_DllProcessDetach( TRUE, (LPVOID)1 );
+ return STATUS_SUCCESS; /* FIXME */
+}
+
/*************************************************************************
* MODULE_DllThreadAttach
*
@@ -314,9 +392,9 @@
for ( ; wm; wm = wm->prev )
{
- if ( !(wm->flags & WINE_MODREF_PROCESS_ATTACHED) )
+ if ( !(wm->ldr_module.Flags & WINE_MODREF_PROCESS_ATTACHED) )
continue;
- if ( wm->flags & WINE_MODREF_NO_DLL_CALLS )
+ if ( wm->ldr_module.Flags & WINE_MODREF_NO_DLL_CALLS )
continue;
MODULE_InitDLL( wm, DLL_THREAD_ATTACH, lpReserved );
@@ -332,7 +410,7 @@
* same sequence as process detach notification.
*
*/
-void MODULE_DllThreadDetach( LPVOID lpReserved )
+static void MODULE_DllThreadDetach( LPVOID lpReserved )
{
WINE_MODREF *wm;
@@ -344,9 +422,9 @@
for ( wm = MODULE_modref_list; wm; wm = wm->next )
{
- if ( !(wm->flags & WINE_MODREF_PROCESS_ATTACHED) )
+ if ( !(wm->ldr_module.Flags & WINE_MODREF_PROCESS_ATTACHED) )
continue;
- if ( wm->flags & WINE_MODREF_NO_DLL_CALLS )
+ if ( wm->ldr_module.Flags & WINE_MODREF_NO_DLL_CALLS )
continue;
MODULE_InitDLL( wm, DLL_THREAD_DETACH, lpReserved );
@@ -355,6 +433,20 @@
RtlLeaveCriticalSection( &loader_section );
}
+/******************************************************************
+ * LdrShutdownThread
+ *
+ *
+ */
+NTSTATUS WINAPI LdrShutdownThread(void)
+{
+ TRACE("()\n");
+ MODULE_DllThreadDetach( NULL );
+ return STATUS_SUCCESS;
+}
+#endif
+
+#ifdef _KERNEL32_
/****************************************************************************
* DisableThreadLibraryCalls (KERNEL32.@)
*
@@ -362,23 +454,46 @@
*/
BOOL WINAPI DisableThreadLibraryCalls( HMODULE hModule )
{
+ NTSTATUS nts;
+
+ nts = LdrDisableThreadCalloutsForDll( hModule );
+ if (nts != STATUS_SUCCESS)
+ {
+ SetLastError( RtlNtStatusToDosError( nts ) );
+ return FALSE;
+ }
+ return TRUE;
+}
+#endif
+
+#ifdef _NTSYSTEM_
+/******************************************************************
+ * LdrDisableThreadCalloutsForDll
+ *
+ *
+ */
+NTSTATUS WINAPI LdrDisableThreadCalloutsForDll( HMODULE hModule )
+{
WINE_MODREF *wm;
- BOOL retval = TRUE;
+ NTSTATUS retval = STATUS_SUCCESS;
+ TRACE("(%p)\n", hModule);
RtlEnterCriticalSection( &loader_section );
wm = MODULE32_LookupHMODULE( hModule );
if ( !wm )
- retval = FALSE;
+ retval = STATUS_DLL_NOT_FOUND;
else
- wm->flags |= WINE_MODREF_NO_DLL_CALLS;
+ wm->ldr_module.Flags |= WINE_MODREF_NO_DLL_CALLS;
RtlLeaveCriticalSection( &loader_section );
return retval;
}
+#endif
+#ifdef _KERNEL32_
/***********************************************************************
* MODULE_CreateDummyModule
*
@@ -482,8 +597,10 @@
NE_RegisterModule( pModule );
return hModule;
}
+#endif
+#ifdef _NTSYSTEM_
/**********************************************************************
* MODULE_FindModule
*
@@ -493,16 +610,15 @@
* the module handle if found
* 0 if not
*/
-WINE_MODREF *MODULE_FindModule(
- LPCSTR path /* [in] pathname of module/library to be found */
-) {
+WINE_MODREF* MODULE_FindModule( LPCSTR path )
+{
WINE_MODREF *wm;
char dllname[260], *p;
/* Append .DLL to name if no extension present */
strcpy( dllname, path );
if (!(p = strrchr( dllname, '.')) || strchr( p, '/' ) || strchr( p, '\\'))
- strcat( dllname, ".DLL" );
+ strcat( dllname, ".DLL" );
for ( wm = MODULE_modref_list; wm; wm = wm->next )
{
@@ -519,7 +635,38 @@
return wm;
}
+/**********************************************************************
+ * LdrGetDllHandle
+ *
+ * Find a (loaded) win32 module depending on path
+ *
+ */
+NTSTATUS WINAPI LdrGetDllHandle(ULONG u1, ULONG u2, PUNICODE_STRING wstr, PVOID* base)
+{
+ WINE_MODREF* wm;
+
+ TRACE("(%s)\n", wstr ? debugstr_w(wstr->Buffer) : NULL);
+
+ if (wstr)
+ {
+ STRING str;
+
+ RtlUnicodeStringToAnsiString(&str, wstr, TRUE);
+
+ wm = MODULE_FindModule( str.Buffer );
+ RtlFreeAnsiString(&str);
+ }
+ else
+ wm = exe_modref;
+
+ if (!wm) return STATUS_DLL_NOT_FOUND;
+ *base = wm->ldr_module.BaseAddress;
+
+ return STATUS_SUCCESS;
+}
+#endif
+#ifdef _KERNEL32_
/* Check whether a file is an OS/2 or a very old Windows executable
* by testing on import of KERNEL.
*
@@ -898,6 +1045,7 @@
return ret;
}
+
/***********************************************************************
* WinExec (KERNEL32.@)
*/
@@ -937,6 +1085,16 @@
return ret;
}
+#include "pshpack1.h"
+typedef struct
+{
+ LPSTR lpEnvAddress;
+ LPSTR lpCmdLine;
+ UINT16 *lpCmdShow;
+ DWORD dwReserved;
+} LOADPARAMS;
+#include "poppack.h"
+
/**********************************************************************
* LoadModule (KERNEL32.@)
*/
@@ -1002,14 +1160,28 @@
*/
HMODULE WINAPI GetModuleHandleA(LPCSTR module)
{
- WINE_MODREF *wm;
+ NTSTATUS nts;
+ HMODULE ret;
- if ( module == NULL )
- wm = exe_modref;
+ if (module)
+ {
+ UNICODE_STRING wstr;
+
+ RtlCreateUnicodeStringFromAsciiz(&wstr, module);
+ nts = LdrGetDllHandle(0, 0, &wstr, (void**)&ret);
+ RtlFreeUnicodeString( &wstr );
+ }
else
- wm = MODULE_FindModule( module );
+ nts = LdrGetDllHandle(0, 0, NULL, (void**)&ret);
+ if (nts != STATUS_SUCCESS)
+ {
+ ret = 0;
+ SetLastError( RtlNtStatusToDosError( nts ) );
+ }
- return wm? wm->module : 0;
+ TRACE("%s => %p\n", module, ret);
+
+ return ret;
}
/***********************************************************************
@@ -1017,14 +1189,30 @@
*/
HMODULE WINAPI GetModuleHandleW(LPCWSTR module)
{
- HMODULE hModule;
- LPSTR modulea = HEAP_strdupWtoA( GetProcessHeap(), 0, module );
- hModule = GetModuleHandleA( modulea );
- HeapFree( GetProcessHeap(), 0, modulea );
- return hModule;
-}
+ NTSTATUS nts;
+ HMODULE ret;
+ if (module)
+ {
+ UNICODE_STRING wstr;
+ RtlInitUnicodeString( &wstr, module );
+ nts = LdrGetDllHandle( 0, 0, &wstr, (void**)&ret);
+ }
+ else
+ nts = LdrGetDllHandle( 0, 0, NULL, (void**)&ret);
+
+ if (nts != STATUS_SUCCESS)
+ {
+ SetLastError( RtlNtStatusToDosError( nts ) );
+ ret = 0;
+ }
+ return ret;
+}
+#endif
+
+/* FIXME: should be in kernel */
+#ifdef _NTSYSTEM_
/***********************************************************************
* GetModuleFileNameA (KERNEL32.@)
* GetModuleFileName32 (KERNEL.487)
@@ -1052,6 +1240,7 @@
{
WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule );
if (wm) lstrcpynA( lpFileName, wm->filename, size );
+ else SetLastError( ERROR_INVALID_HANDLE );
}
RtlLeaveCriticalSection( &loader_section );
@@ -1065,24 +1254,53 @@
*/
DWORD WINAPI GetModuleFileNameW( HMODULE hModule, LPWSTR lpFileName, DWORD size )
{
- LPSTR fnA = HeapAlloc( GetProcessHeap(), 0, size * 2 );
- if (!fnA) return 0;
- GetModuleFileNameA( hModule, fnA, size * 2 );
- if (size > 0 && !MultiByteToWideChar( CP_ACP, 0, fnA, -1, lpFileName, size ))
- lpFileName[size-1] = 0;
- HeapFree( GetProcessHeap(), 0, fnA );
+ RtlEnterCriticalSection( &loader_section );
+
+ lpFileName[0] = 0;
+ if (!hModule && !(NtCurrentTeb()->tibflags & TEBF_WIN32))
+ {
+ /* 16-bit task - get current NE module name */
+ NE_MODULE *pModule = NE_GetPtr( GetCurrentTask() );
+ LPSTR fnA = HeapAlloc( GetProcessHeap(), 0, size );
+ if (!fnA) return 0;
+
+ if (pModule) GetLongPathNameA(NE_MODULE_NAME(pModule), fnA, size);
+ if (size > 0 && !MultiByteToWideChar( CP_ACP, 0, fnA, -1, lpFileName, size ))
+ lpFileName[size-1] = 0;
+ HeapFree( GetProcessHeap(), 0, fnA );
+ }
+ else
+ {
+ WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule );
+ if (wm) lstrcpynW( lpFileName, wm->ldr_module.FullDllName.Buffer, size );
+ else SetLastError( ERROR_INVALID_HANDLE );
+ }
+
+ RtlLeaveCriticalSection( &loader_section );
+ TRACE("%s\n", debugstr_w(lpFileName) );
+
return strlenW(lpFileName);
}
+#endif
+#ifdef _KERNEL32_
/***********************************************************************
* LoadLibraryExA (KERNEL32.@)
+ *
+ * The HFILE parameter is not used and marked reserved in the SDK. I can
+ * only guess that it should force a file to be mapped, but I rather
+ * ignore the parameter because it would be extremely difficult to
+ * integrate this with different types of module representations.
+ *
*/
HMODULE WINAPI LoadLibraryExA(LPCSTR libname, HANDLE hfile, DWORD flags)
{
- WINE_MODREF *wm;
+ UNICODE_STRING wstr;
+ HINSTANCE hInst;
+ NTSTATUS nts;
- if(!libname)
+ if (!libname)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
@@ -1124,22 +1342,57 @@
/* Fallback to normal behaviour */
}
+ RtlCreateUnicodeStringFromAsciiz( &wstr, libname );
+ nts = LdrLoadDll(NULL, flags, &wstr, (void**)&hInst);
+ if (nts != STATUS_SUCCESS)
+ {
+ hInst = 0;
+ SetLastError( RtlNtStatusToDosError( nts ) );
+ }
+ RtlFreeUnicodeString( &wstr );
+
+ return hInst;
+}
+#endif
+
+#ifdef _NTSYSTEM_
+/******************************************************************
+ * LdrLoadDll
+ *
+ *
+ */
+NTSTATUS WINAPI LdrLoadDll(LPCSTR searchPath, DWORD flags, PUNICODE_STRING wstr,
+ void** hInst)
+{
+ WINE_MODREF *wm;
+ NTSTATUS nts = STATUS_SUCCESS;
+ STRING str;
+
+ RtlUnicodeStringToAnsiString(&str, wstr, TRUE);
+
RtlEnterCriticalSection( &loader_section );
- wm = MODULE_LoadLibraryExA( libname, hfile, flags );
+ /* FIXME: searchPath isn't used (but normaly we don't use it) */
+ wm = MODULE_LoadLibraryExA( str.Buffer, flags );
if ( wm )
{
if ( !MODULE_DllProcessAttach( wm, NULL ) )
{
- WARN_(module)("Attach failed for module '%s'.\n", libname);
- MODULE_FreeLibrary(wm);
- SetLastError(ERROR_DLL_INIT_FAILED);
+ WARN_(module)("Attach failed for module '%s'.\n", str.Buffer);
+ LdrUnloadDll(wm->ldr_module.BaseAddress);
+ nts = STATUS_DLL_INIT_FAILED;
wm = NULL;
}
}
+ else nts = STATUS_DLL_NOT_FOUND;
+ *hInst = (wm) ? wm->ldr_module.BaseAddress : NULL;
+
RtlLeaveCriticalSection( &loader_section );
- return wm ? wm->module : 0;
+
+ RtlFreeAnsiString(&str);
+
+ return nts;
}
/***********************************************************************
@@ -1162,7 +1415,7 @@
length = pmax - libname;
- result = HeapAlloc (GetProcessHeap(), 0, length+1);
+ result = RtlAllocateHeap (GetProcessHeap(), 0, length+1);
if (result)
{
@@ -1178,11 +1431,6 @@
*
* Load a PE style module according to the load order.
*
- * The HFILE parameter is not used and marked reserved in the SDK. I can
- * only guess that it should force a file to be mapped, but I rather
- * ignore the parameter because it would be extremely difficult to
- * integrate this with different types of module representations.
- *
* libdir is used to support LOAD_WITH_ALTERED_SEARCH_PATH during the recursion
* on this function. When first called from LoadLibraryExA it will be
* NULL but thereafter it may point to a buffer containing the path
@@ -1194,7 +1442,7 @@
* init function into load_library).
* allocated_libdir is TRUE in the stack frame that allocated libdir
*/
-WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HANDLE hfile, DWORD flags )
+WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, DWORD flags )
{
DWORD err = GetLastError();
WINE_MODREF *pwm;
@@ -1208,7 +1456,7 @@
if ( !libname ) return NULL;
- filename = HeapAlloc ( GetProcessHeap(), 0, MAX_PATH + 1 );
+ filename = RtlAllocateHeap ( GetProcessHeap(), 0, MAX_PATH + 1 );
if ( !filename ) return NULL;
*filename = 0; /* Just in case we don't set it before goto error */
@@ -1234,7 +1482,7 @@
/* Check for already loaded module */
if (!(pwm = MODULE_FindModule(filename)) && !FILE_contains_path(libname))
{
- LPSTR fn = HeapAlloc ( GetProcessHeap(), 0, MAX_PATH + 1 );
+ LPSTR fn = RtlAllocateHeap ( GetProcessHeap(), 0, MAX_PATH + 1 );
if (fn)
{
/* since the default loading mechanism uses a more detailed algorithm
@@ -1249,27 +1497,28 @@
if (!strrchr( fn, '.')) strcat( fn, ".dll" );
if ((pwm = MODULE_FindModule( fn )) != NULL)
strcpy( filename, fn );
- HeapFree( GetProcessHeap(), 0, fn );
+ RtlFreeHeap( GetProcessHeap(), 0, fn );
}
}
if (pwm)
{
- pwm->refCount++;
+ pwm->ldr_module.LoadCount++;
- if ((pwm->flags & WINE_MODREF_DONT_RESOLVE_REFS) &&
+ if ((pwm->ldr_module.Flags & WINE_MODREF_DONT_RESOLVE_REFS) &&
!(flags & DONT_RESOLVE_DLL_REFERENCES))
{
- pwm->flags &= ~WINE_MODREF_DONT_RESOLVE_REFS;
+ pwm->ldr_module.Flags &= ~WINE_MODREF_DONT_RESOLVE_REFS;
PE_fixup_imports( pwm );
}
- TRACE("Already loaded module '%s' at %p, count=%d\n", filename, pwm->module, pwm->refCount);
+ TRACE("Already loaded module '%s' at %p, count=%d\n",
+ filename, pwm->ldr_module.BaseAddress, pwm->ldr_module.LoadCount);
if (allocated_libdir)
{
- HeapFree ( GetProcessHeap(), 0, (LPSTR)libdir );
+ RtlFreeHeap ( GetProcessHeap(), 0, (LPSTR)libdir );
libdir = NULL;
}
RtlLeaveCriticalSection( &loader_section );
- HeapFree ( GetProcessHeap(), 0, filename );
+ RtlFreeHeap ( GetProcessHeap(), 0, filename );
return pwm;
}
@@ -1308,21 +1557,22 @@
if(pwm)
{
/* Initialize DLL just loaded */
- TRACE("Loaded module '%s' at %p\n", filename, pwm->module);
+ TRACE("Loaded module '%s' at %p\n",
+ filename, pwm->ldr_module.BaseAddress);
if (!TRACE_ON(module))
TRACE_(loaddll)("Loaded module '%s' : %s\n", filename, filetype);
- /* Set the refCount here so that an attach failure will */
+ /* Set the ldr_module.LoadCount here so that an attach failure will */
/* decrement the dependencies through the MODULE_FreeLibrary call. */
- pwm->refCount = 1;
+ pwm->ldr_module.LoadCount = 1;
if (allocated_libdir)
{
- HeapFree ( GetProcessHeap(), 0, (LPSTR)libdir );
+ RtlFreeHeap ( GetProcessHeap(), 0, (LPSTR)libdir );
libdir = NULL;
}
RtlLeaveCriticalSection( &loader_section );
SetLastError( err ); /* restore last error */
- HeapFree ( GetProcessHeap(), 0, filename );
+ RtlFreeHeap ( GetProcessHeap(), 0, filename );
return pwm;
}
@@ -1337,20 +1587,23 @@
error:
if (allocated_libdir)
{
- HeapFree ( GetProcessHeap(), 0, (LPSTR)libdir );
+ RtlFreeHeap ( GetProcessHeap(), 0, (LPSTR)libdir );
libdir = NULL;
}
RtlLeaveCriticalSection( &loader_section );
WARN("Failed to load module '%s'; error=%ld\n", filename, GetLastError());
- HeapFree ( GetProcessHeap(), 0, filename );
+ RtlFreeHeap ( GetProcessHeap(), 0, filename );
return NULL;
}
+#endif
+#ifdef _KERNEL32_
/***********************************************************************
* LoadLibraryA (KERNEL32.@)
*/
-HMODULE WINAPI LoadLibraryA(LPCSTR libname) {
- return LoadLibraryExA(libname,0,0);
+HMODULE WINAPI LoadLibraryA(LPCSTR libname)
+{
+ return LoadLibraryExA( libname, 0, 0 );
}
/***********************************************************************
@@ -1358,7 +1611,7 @@
*/
HMODULE WINAPI LoadLibraryW(LPCWSTR libnameW)
{
- return LoadLibraryExW(libnameW,0,0);
+ return LoadLibraryExW( libnameW, 0, 0 );
}
/***********************************************************************
@@ -1387,7 +1640,9 @@
HeapFree( GetProcessHeap(), 0, libnameA );
return ret;
}
+#endif
+#ifdef _NTSYSTEM_
/***********************************************************************
* MODULE_FlushModrefs
*
@@ -1404,7 +1659,7 @@
{
next = wm->next;
- if(wm->refCount)
+ if(wm->ldr_module.LoadCount)
continue;
/* Unlink this modref from the chain */
@@ -1415,19 +1670,29 @@
if(wm == MODULE_modref_list)
MODULE_modref_list = wm->next;
- TRACE(" unloading %s\n", wm->filename);
+ RemoveEntryList(&wm->ldr_module.InLoadOrderModuleList);
+ RemoveEntryList(&wm->ldr_module.InMemoryOrderModuleList);
+ RemoveEntryList(&wm->ldr_module.InInitializationOrderModuleList);
+
+ TRACE(" unloading %s\n", debugstr_w(wm->ldr_module.FullDllName.Buffer));
if (!TRACE_ON(module))
- TRACE_(loaddll)("Unloaded module '%s' : %s\n", wm->filename,
+ TRACE_(loaddll)("Unloaded module '%s' : %s\n",
+ debugstr_w(wm->ldr_module.FullDllName.Buffer),
wm->dlhandle ? "builtin" : "native" );
if (wm->dlhandle) wine_dll_unload( wm->dlhandle );
- else UnmapViewOfFile( (LPVOID)wm->module );
+ else UnmapViewOfFile( wm->ldr_module.BaseAddress );
FreeLibrary16(wm->hDummyMod);
- HeapFree( GetProcessHeap(), 0, wm->deps );
- HeapFree( GetProcessHeap(), 0, wm );
+ RtlFreeUnicodeString( &wm->ldr_module.FullDllName );
+ RtlFreeUnicodeString( &wm->ldr_module.BaseDllName );
+
+ RtlFreeHeap( GetProcessHeap(), 0, wm->deps );
+ RtlFreeHeap( GetProcessHeap(), 0, wm );
}
}
+#endif
+#ifdef _KERNEL32_
/***********************************************************************
* FreeLibrary (KERNEL32.@)
* FreeLibrary32 (KERNEL.486)
@@ -1435,7 +1700,7 @@
BOOL WINAPI FreeLibrary(HINSTANCE hLibModule)
{
BOOL retv = FALSE;
- WINE_MODREF *wm;
+ NTSTATUS nts;
if (!hLibModule)
{
@@ -1451,24 +1716,14 @@
return TRUE;
}
- RtlEnterCriticalSection( &loader_section );
-
- /* if we're stopping the whole process (and forcing the removal of all
- * DLLs) the library will be freed anyway
- */
- if (process_detaching) retv = TRUE;
- else
- {
- free_lib_count++;
- if ((wm = MODULE32_LookupHMODULE( hLibModule ))) retv = MODULE_FreeLibrary( wm );
- free_lib_count--;
- }
-
- RtlLeaveCriticalSection( &loader_section );
+ if ((nts = LdrUnloadDll( hLibModule )) == STATUS_SUCCESS) retv = TRUE;
+ else SetLastError( RtlNtStatusToDosError( nts ) );
return retv;
}
+#endif
+#ifdef _NTSYSTEM_
/***********************************************************************
* MODULE_DecRefCount
*
@@ -1478,58 +1733,84 @@
{
int i;
- if ( wm->flags & WINE_MODREF_MARKER )
+ if ( wm->ldr_module.Flags & WINE_MODREF_MARKER )
return;
- if ( wm->refCount <= 0 )
+ if ( wm->ldr_module.LoadCount <= 0 )
return;
- --wm->refCount;
- TRACE("(%s) refCount: %d\n", wm->modname, wm->refCount );
+ --wm->ldr_module.LoadCount;
+ TRACE("(%s) refCount: %d\n",
+ debugstr_w(wm->ldr_module.BaseDllName.Buffer), wm->ldr_module.LoadCount );
- if ( wm->refCount == 0 )
+ if ( wm->ldr_module.LoadCount == 0 )
{
- wm->flags |= WINE_MODREF_MARKER;
+ wm->ldr_module.Flags |= WINE_MODREF_MARKER;
for ( i = 0; i < wm->nDeps; i++ )
if ( wm->deps[i] )
MODULE_DecRefCount( wm->deps[i] );
- wm->flags &= ~WINE_MODREF_MARKER;
+ wm->ldr_module.Flags &= ~WINE_MODREF_MARKER;
}
}
/***********************************************************************
- * MODULE_FreeLibrary
+ * LdrUnloadDll
*
- * NOTE: Assumes that the process critical section is held!
*/
-BOOL MODULE_FreeLibrary( WINE_MODREF *wm )
+NTSTATUS WINAPI LdrUnloadDll( HMODULE hModule )
{
- TRACE("(%s) - START\n", wm->modname );
+ NTSTATUS retv = STATUS_SUCCESS;
+
+ TRACE("(%p)\n", hModule);
- /* Recursively decrement reference counts */
- MODULE_DecRefCount( wm );
+ RtlEnterCriticalSection( &loader_section );
- /* Call process detach notifications */
- if ( free_lib_count <= 1 )
+ /* if we're stopping the whole process (and forcing the removal of all
+ * DLLs) the library will be freed anyway
+ */
+ if (!process_detaching)
{
- MODULE_DllProcessDetach( FALSE, NULL );
- SERVER_START_REQ( unload_dll )
+ WINE_MODREF *wm;
+
+ free_lib_count++;
+ if ((wm = MODULE32_LookupHMODULE( hModule )) != NULL)
{
- req->base = (void *)wm->module;
- wine_server_call( req );
+ TRACE("(%s) - START\n", debugstr_w(wm->ldr_module.BaseDllName.Buffer));
+
+ /* Recursively decrement reference counts */
+ MODULE_DecRefCount( wm );
+
+ /* Call process detach notifications */
+ if ( free_lib_count <= 1 )
+ {
+ MODULE_DllProcessDetach( FALSE, NULL );
+ SERVER_START_REQ( unload_dll )
+ {
+ req->base = wm->ldr_module.BaseAddress;
+ wine_server_call( req );
+ }
+ SERVER_END_REQ;
+ MODULE_FlushModrefs();
+ }
+
+ TRACE("END\n");
}
- SERVER_END_REQ;
- MODULE_FlushModrefs();
+ else
+ retv = STATUS_DLL_NOT_FOUND;
+
+ free_lib_count--;
}
- TRACE("END\n");
+ RtlLeaveCriticalSection( &loader_section );
- return TRUE;
+ return retv;
}
+#endif
+#ifdef _KERNEL32_
/***********************************************************************
* FreeLibraryAndExitThread (KERNEL32.@)
*/
@@ -1539,6 +1820,8 @@
ExitThread(dwExitCode);
}
+
+
/***********************************************************************
* PrivateLoadLibrary (KERNEL32.@)
*
@@ -1549,8 +1832,6 @@
return LoadLibrary16(libname);
}
-
-
/***********************************************************************
* PrivateFreeLibrary (KERNEL32.@)
*
@@ -1561,7 +1842,6 @@
FreeLibrary16(handle);
}
-
/***********************************************************************
* GetProcAddress16 (KERNEL32.37)
* Get procaddress in 16bit module from win32... (kernel32 undoc. ordinal func)
@@ -1580,6 +1860,7 @@
return GetProcAddress16( LOWORD(hModule), name );
}
+
/***********************************************************************
* GetProcAddress (KERNEL.50)
*/
@@ -1615,7 +1896,25 @@
*/
FARPROC WINAPI GetProcAddress( HMODULE hModule, LPCSTR function )
{
- return MODULE_GetProcAddress( hModule, function, -1, TRUE );
+ NTSTATUS nts;
+ FARPROC fp;
+
+ if (HIWORD(function))
+ {
+ ANSI_STRING str;
+
+ RtlInitAnsiString( &str, function );
+ /* FIXME: snoop has been desactivated */
+ nts = LdrGetProcedureAddress( hModule, &str, 0, (void**)&fp);
+ }
+ else
+ nts = LdrGetProcedureAddress( hModule, NULL, (DWORD)function, (void**)&fp);
+ if (nts != STATUS_SUCCESS)
+ {
+ SetLastError( RtlNtStatusToDosError( nts ) );
+ fp = NULL;
+ }
+ return fp;
}
/***********************************************************************
@@ -1623,9 +1922,12 @@
*/
FARPROC WINAPI GetProcAddress32_16( HMODULE hModule, LPCSTR function )
{
- return MODULE_GetProcAddress( hModule, function, -1, FALSE );
+ /* FIXME: snoop has been desactivated */
+ return GetProcAddress( hModule, function );
}
+#endif
+#ifdef _NTSYSTEM_
/***********************************************************************
* MODULE_GetProcAddress (internal)
*/
@@ -1652,8 +1954,10 @@
RtlLeaveCriticalSection( &loader_section );
return retproc;
}
+#endif
+#ifdef _KERNEL32_
/***************************************************************************
* HasGPHandler (KERNEL.338)
*/
@@ -1693,3 +1997,116 @@
return 0;
}
+#endif
+
+#ifdef _NTSYSTEM_
+/******************************************************************
+ * LdrGetProcedureAddress
+ *
+ *
+ */
+NTSTATUS WINAPI LdrGetProcedureAddress(HMODULE hModule, PANSI_STRING function, ULONG ord, PVOID *address)
+{
+ WINE_MODREF *wm;
+ NTSTATUS nts;
+
+ TRACE("(%p, %s, %lu, %p)\n",
+ hModule, function ? debugstr_a(function->Buffer) : NULL, ord, address);
+
+ /* FIXME: how to cope with snoop parameter ?? */
+
+ if (function)
+ TRACE_(win32)("(%08lx,%s)\n",(DWORD)hModule,function->Buffer);
+ else
+ TRACE_(win32)("(%08lx,%lu)\n",(DWORD)hModule,ord);
+
+ RtlEnterCriticalSection( &loader_section );
+ if ((wm = MODULE32_LookupHMODULE( hModule )))
+ {
+ FARPROC retproc = wm->find_export( wm, function ? function->Buffer : (char*)ord, -1, FALSE );
+ if (address) *address = retproc;
+ nts = (retproc) ? STATUS_SUCCESS : STATUS_PROCEDURE_NOT_FOUND;
+ }
+ else nts = STATUS_DLL_NOT_FOUND;
+ RtlLeaveCriticalSection( &loader_section );
+ return nts;
+}
+
+
+/******************************************************************
+ * LdrFindEntryForAddress
+ *
+ *
+ */
+NTSTATUS WINAPI LdrFindEntryForAddress(void* addr, PLDR_MODULE* mod)
+{
+ WINE_MODREF* wm;
+
+ /* FIXME: could be faster if we implement the InMemoryOrder list of the LDR_MODULE
+ * we cannot use LDR_MODULE list yet as it doesn't contain all the loaded modules yet
+ */
+ RtlEnterCriticalSection( &loader_section );
+ for (wm = MODULE_modref_list; wm; wm = wm->next)
+ {
+ if (wm->ldr_module.BaseAddress <= addr &&
+ (char*)addr < (char*)wm->ldr_module.BaseAddress + wm->ldr_module.SizeOfImage)
+ {
+ if (mod) *mod = &wm->ldr_module;
+ break;
+ }
+ }
+ RtlLeaveCriticalSection( &loader_section );
+
+ return (wm) ? STATUS_NO_MORE_ENTRIES : STATUS_SUCCESS;
+}
+
+/******************************************************************
+ * LdrQueryProcessModuleInformation
+ *
+ *
+ */
+NTSTATUS WINAPI LdrQueryProcessModuleInformation(PSYSTEM_MODULE_INFORMATION smibuf,
+ ULONG buf_size, PULONG req_size )
+{
+ WINE_MODREF* wm;
+ SYSTEM_MODULE* sm = &smibuf->Modules[0];
+ ULONG sz = sizeof(ULONG);
+ NTSTATUS nts = STATUS_SUCCESS;
+ ANSI_STRING astr;
+ BYTE* ptr;
+
+ /* FIXME is smibuf->ModulesCount in the buf_size ? assume yes */
+ if (buf_size < sz) nts = STATUS_INFO_LENGTH_MISMATCH;
+
+ RtlEnterCriticalSection( &loader_section );
+ for (wm = MODULE_modref_list; wm; wm = wm->next)
+ {
+ if (sz + sizeof(*sm) <= buf_size)
+ {
+ sm->Reserved1 = 0xBAADF00D;
+ sm->Reserved2 = 0;
+ sm->ImageBaseAddress = wm->ldr_module.BaseAddress;
+ sm->ImageSize = wm->ldr_module.SizeOfImage;
+ sm->Flags = wm->ldr_module.Flags; /* FIXME those are not Win32 compat */
+ sm->Id = 0;
+ sm->Rank = 0;
+ sm->w018 = 0xFFFF;
+
+ astr.Length = 0;
+ astr.MaximumLength = sizeof(sm->Name);
+ astr.Buffer = sm->Name;
+ RtlUnicodeStringToAnsiString(&astr, &wm->ldr_module.FullDllName, FALSE);
+ ptr = strrchr(sm->Name, '\\');
+ sm->NameOffset = (ptr != NULL) ? ptr - sm->Name + 1 : 0;
+ }
+ else
+ nts = STATUS_INFO_LENGTH_MISMATCH;
+ sz += sizeof(*sm);
+ smibuf->ModulesCount++;
+ sm++;
+ }
+ RtlLeaveCriticalSection( &loader_section );
+ if (req_size) *req_size = sz;
+ return nts;
+}
+#endif
Index: loader/pe_image.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/loader/pe_image.c,v
retrieving revision 1.118
diff -u -u -r1.118 pe_image.c
--- loader/pe_image.c 17 Dec 2002 21:09:50 -0000 1.118
+++ loader/pe_image.c 3 Jan 2003 19:51:27 -0000
@@ -125,18 +125,18 @@
IMAGE_EXPORT_DIRECTORY *exports;
DWORD exp_size;
- if (!(exports = RtlImageDirectoryEntryToData( wm->module, TRUE,
+ if (!(exports = RtlImageDirectoryEntryToData( wm->ldr_module.BaseAddress, TRUE,
IMAGE_DIRECTORY_ENTRY_EXPORT, &exp_size )))
return NULL;
if (HIWORD(funcName)) TRACE("(%s)\n",funcName);
else TRACE("(%d)\n",LOWORD(funcName));
- ordinals= get_rva(wm->module, exports->AddressOfNameOrdinals);
- function= get_rva(wm->module, exports->AddressOfFunctions);
- name = get_rva(wm->module, exports->AddressOfNames);
+ ordinals= get_rva(wm->ldr_module.BaseAddress, exports->AddressOfNameOrdinals);
+ function= get_rva(wm->ldr_module.BaseAddress, exports->AddressOfFunctions);
+ name = get_rva(wm->ldr_module.BaseAddress, exports->AddressOfNames);
forward = NULL;
- rva_start = (char *)exports - (char *)wm->module;
+ rva_start = (char *)exports - (char *)wm->ldr_module.BaseAddress;
if (HIWORD(funcName))
{
@@ -145,7 +145,7 @@
/* first check the hint */
if (hint >= 0 && hint <= max)
{
- ename = get_rva(wm->module, name[hint]);
+ ename = get_rva(wm->ldr_module.BaseAddress, name[hint]);
if (!strcmp( ename, funcName ))
{
ordinal = ordinals[hint];
@@ -157,7 +157,7 @@
while (min <= max)
{
int res, pos = (min + max) / 2;
- ename = get_rva(wm->module, name[pos]);
+ ename = get_rva(wm->ldr_module.BaseAddress, name[pos]);
if (!(res = strcmp( ename, funcName )))
{
ordinal = ordinals[pos];
@@ -176,7 +176,7 @@
for (i = 0; i < exports->NumberOfNames; i++)
if (ordinals[i] == ordinal)
{
- ename = get_rva(wm->module, name[i]);
+ ename = get_rva(wm->ldr_module.BaseAddress, name[i]);
break;
}
}
@@ -191,13 +191,13 @@
addr = function[ordinal];
if (!addr) return NULL;
- proc = get_rva(wm->module, addr);
+ proc = get_rva(wm->ldr_module.BaseAddress, addr);
if (((char *)proc < (char *)exports) || ((char *)proc >= (char *)exports + exp_size))
{
if (snoop)
{
if (!ename) ename = "@";
- proc = SNOOP_GetProcAddress(wm->module,ename,ordinal,proc);
+ proc = SNOOP_GetProcAddress(wm->ldr_module.BaseAddress,ename,ordinal,proc);
}
return proc;
}
@@ -214,11 +214,15 @@
module[end-forward] = 0;
if (!(wm_fw = MODULE_FindModule( module )))
{
- ERR("module not found for forward '%s' used by '%s'\n", forward, wm->modname );
+ ERR("module not found for forward '%s' used by '%s'\n",
+ forward, debugstr_w(wm->ldr_module.BaseDllName.Buffer));
return NULL;
}
- if (!(proc = MODULE_GetProcAddress( wm_fw->module, end + 1, -1, snoop )))
- ERR("function not found for forward '%s' used by '%s'. If you are using builtin '%s', try using the native one instead.\n", forward, wm->modname, wm->modname );
+ if (!(proc = MODULE_GetProcAddress( wm_fw->ldr_module.BaseAddress, end + 1, -1, snoop )))
+ ERR("function not found for forward '%s' used by '%s'. If you are using builtin '%s', try using the native one instead.\n",
+ forward,
+ debugstr_w(wm->ldr_module.BaseDllName.Buffer),
+ debugstr_w(wm->ldr_module.BaseDllName.Buffer));
return proc;
}
}
@@ -232,7 +236,7 @@
IMAGE_IMPORT_DESCRIPTOR *imports, *pe_imp;
DWORD size;
- imports = RtlImageDirectoryEntryToData( wm->module, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &size );
+ imports = RtlImageDirectoryEntryToData( wm->ldr_module.BaseAddress, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &size );
/* first, count the number of imported non-internal modules */
pe_imp = imports;
@@ -256,7 +260,7 @@
/* Allocate module dependency list */
wm->nDeps = i;
- wm->deps = HeapAlloc( GetProcessHeap(), 0, i*sizeof(WINE_MODREF *) );
+ wm->deps = RtlAllocateHeap( GetProcessHeap(), 0, i*sizeof(WINE_MODREF *) );
/* load the imported modules. They are automatically
* added to the modref list of the process.
@@ -266,14 +270,15 @@
WINE_MODREF *wmImp;
IMAGE_IMPORT_BY_NAME *pe_name;
PIMAGE_THUNK_DATA import_list,thunk_list;
- char *name = get_rva(wm->module, pe_imp->Name);
+ char *name = get_rva(wm->ldr_module.BaseAddress, pe_imp->Name);
if (characteristics_detection && !pe_imp->u.Characteristics)
break;
- wmImp = MODULE_LoadLibraryExA( name, 0, 0 );
+ wmImp = MODULE_LoadLibraryExA( name, 0 );
if (!wmImp) {
- ERR_(module)("Module (file) %s (which is needed by %s) not found\n", name, wm->filename);
+ ERR_(module)("Module (file) %s (which is needed by %s) not found\n",
+ name, debugstr_w(wm->ldr_module.FullDllName.Buffer));
return 1;
}
wm->deps[i++] = wmImp;
@@ -282,8 +287,8 @@
if (pe_imp->u.OriginalFirstThunk != 0) { /* original MS style */
TRACE("Microsoft style imports used\n");
- import_list = get_rva(wm->module, (DWORD)pe_imp->u.OriginalFirstThunk);
- thunk_list = get_rva(wm->module, (DWORD)pe_imp->FirstThunk);
+ import_list = get_rva(wm->ldr_module.BaseAddress, (DWORD)pe_imp->u.OriginalFirstThunk);
+ thunk_list = get_rva(wm->ldr_module.BaseAddress, (DWORD)pe_imp->FirstThunk);
while (import_list->u1.Ordinal) {
if (IMAGE_SNAP_BY_ORDINAL(import_list->u1.Ordinal)) {
@@ -291,22 +296,23 @@
TRACE("--- Ordinal %s,%d\n", name, ordinal);
thunk_list->u1.Function=(PDWORD)MODULE_GetProcAddress(
- wmImp->module, (LPCSTR)ordinal, -1, TRUE
+ wmImp->ldr_module.BaseAddress, (LPCSTR)ordinal, -1, TRUE
);
if (!thunk_list->u1.Function) {
ERR("No implementation for %s.%d imported from %s, setting to 0xdeadbeef\n",
- name, ordinal, wm->filename );
+ name, ordinal, debugstr_w(wm->ldr_module.FullDllName.Buffer));
thunk_list->u1.Function = (PDWORD)0xdeadbeef;
}
} else { /* import by name */
- pe_name = get_rva(wm->module, (DWORD)import_list->u1.AddressOfData);
+ pe_name = get_rva(wm->ldr_module.BaseAddress, (DWORD)import_list->u1.AddressOfData);
TRACE("--- %s %s.%d\n", pe_name->Name, name, pe_name->Hint);
thunk_list->u1.Function=(PDWORD)MODULE_GetProcAddress(
- wmImp->module, pe_name->Name, pe_name->Hint, TRUE
+ wmImp->ldr_module.BaseAddress, pe_name->Name, pe_name->Hint, TRUE
);
if (!thunk_list->u1.Function) {
ERR("No implementation for %s.%d(%s) imported from %s, setting to 0xdeadbeef\n",
- name,pe_name->Hint,pe_name->Name,wm->filename);
+ name,pe_name->Hint,pe_name->Name,
+ debugstr_w(wm->ldr_module.FullDllName.Buffer));
thunk_list->u1.Function = (PDWORD)0xdeadbeef;
}
}
@@ -315,7 +321,7 @@
}
} else { /* Borland style */
TRACE("Borland style imports used\n");
- thunk_list = get_rva(wm->module, (DWORD)pe_imp->FirstThunk);
+ thunk_list = get_rva(wm->ldr_module.BaseAddress, (DWORD)pe_imp->FirstThunk);
while (thunk_list->u1.Ordinal) {
if (IMAGE_SNAP_BY_ORDINAL(thunk_list->u1.Ordinal)) {
/* not sure about this branch, but it seems to work */
@@ -323,23 +329,24 @@
TRACE("--- Ordinal %s.%d\n",name,ordinal);
thunk_list->u1.Function=(PDWORD)MODULE_GetProcAddress(
- wmImp->module, (LPCSTR) ordinal, -1, TRUE
+ wmImp->ldr_module.BaseAddress, (LPCSTR) ordinal, -1, TRUE
);
if (!thunk_list->u1.Function) {
ERR("No implementation for %s.%d imported from %s, setting to 0xdeadbeef\n",
- name,ordinal, wm->filename);
+ name,ordinal, debugstr_w(wm->ldr_module.FullDllName.Buffer));
thunk_list->u1.Function = (PDWORD)0xdeadbeef;
}
} else {
- pe_name=get_rva(wm->module, (DWORD)thunk_list->u1.AddressOfData);
+ pe_name=get_rva(wm->ldr_module.BaseAddress, (DWORD)thunk_list->u1.AddressOfData);
TRACE("--- %s %s.%d\n",
pe_name->Name,name,pe_name->Hint);
thunk_list->u1.Function=(PDWORD)MODULE_GetProcAddress(
- wmImp->module, pe_name->Name, pe_name->Hint, TRUE
+ wmImp->ldr_module.BaseAddress, pe_name->Name, pe_name->Hint, TRUE
);
if (!thunk_list->u1.Function) {
ERR("No implementation for %s.%d(%s) imported from %s, setting to 0xdeadbeef\n",
- name, pe_name->Hint, pe_name->Name, wm->filename);
+ name, pe_name->Hint, pe_name->Name,
+ debugstr_w(wm->ldr_module.FullDllName.Buffer));
thunk_list->u1.Function = (PDWORD)0xdeadbeef;
}
}
@@ -493,15 +500,16 @@
return NULL;
}
wm->hDummyMod = hModule16;
+ wm->ldr_module.SizeOfImage = nt->OptionalHeader.SizeOfImage;
if ( builtin )
{
NE_MODULE *pModule = (NE_MODULE *)GlobalLock16( hModule16 );
pModule->flags |= NE_FFLAGS_BUILTIN;
- wm->flags |= WINE_MODREF_INTERNAL;
+ wm->ldr_module.Flags |= WINE_MODREF_INTERNAL;
}
else if ( flags & DONT_RESOLVE_DLL_REFERENCES )
- wm->flags |= WINE_MODREF_DONT_RESOLVE_REFS;
+ wm->ldr_module.Flags |= WINE_MODREF_DONT_RESOLVE_REFS;
wm->find_export = PE_FindExportedFunction;
@@ -512,7 +520,7 @@
/* Fixup Imports */
- if (!(wm->flags & WINE_MODREF_DONT_RESOLVE_REFS) &&
+ if (!(wm->ldr_module.Flags & WINE_MODREF_DONT_RESOLVE_REFS) &&
PE_fixup_imports( wm ))
{
/* remove entry from modref chain */
@@ -619,11 +627,11 @@
(nt->OptionalHeader.AddressOfEntryPoint))
{
DLLENTRYPROC entry = (void*)((char*)module + nt->OptionalHeader.AddressOfEntryPoint);
- if (TRACE_ON(relay))
+ if (TRACE_ON(relay) || TRACE_ON(module))
DPRINTF("%08lx:Call PE DLL (proc=%p,module=%p,type=%ld,res=%p)\n",
GetCurrentThreadId(), entry, module, type, lpReserved );
retv = entry( module, type, lpReserved );
- if (TRACE_ON(relay))
+ if (TRACE_ON(relay) || TRACE_ON(module))
DPRINTF("%08lx:Ret PE DLL (proc=%p,module=%p,type=%ld,res=%p) retval=%x\n",
GetCurrentThreadId(), entry, module, type, lpReserved, retv );
}
@@ -659,19 +667,19 @@
int delta;
for (wm = MODULE_modref_list;wm;wm=wm->next) {
- peh = RtlImageNtHeader(wm->module);
- pdir = RtlImageDirectoryEntryToData( wm->module, TRUE,
+ peh = RtlImageNtHeader(wm->ldr_module.BaseAddress);
+ pdir = RtlImageDirectoryEntryToData( wm->ldr_module.BaseAddress, TRUE,
IMAGE_DIRECTORY_ENTRY_TLS, &dirsize );
if (!pdir) continue;
- delta = (char *)wm->module - (char *)peh->OptionalHeader.ImageBase;
+ delta = (char *)wm->ldr_module.BaseAddress - (char *)peh->OptionalHeader.ImageBase;
- if ( wm->tlsindex == -1 ) {
+ if ( wm->ldr_module.TlsIndex == -1 ) {
LPDWORD xaddr;
- wm->tlsindex = TlsAlloc();
+ wm->ldr_module.TlsIndex = TlsAlloc();
xaddr = _fixup_address(&(peh->OptionalHeader),delta,
pdir->AddressOfIndex
);
- *xaddr=wm->tlsindex;
+ *xaddr=wm->ldr_module.TlsIndex;
}
datasize= pdir->EndAddressOfRawData-pdir->StartAddressOfRawData;
size = datasize + pdir->SizeOfZeroFill;
@@ -685,6 +693,6 @@
FIXME("TLS Callbacks aren't going to be called\n");
}
- TlsSetValue( wm->tlsindex, mem );
+ TlsSetValue( wm->ldr_module.TlsIndex, mem );
}
}
Index: loader/pe_resource.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/loader/pe_resource.c,v
retrieving revision 1.40
diff -u -u -r1.40 pe_resource.c
--- loader/pe_resource.c 7 Jan 2003 20:36:22 -0000 1.40
+++ loader/pe_resource.c 11 Jan 2003 13:41:40 -0000
@@ -37,10 +37,14 @@
#include "winternl.h"
#include "winerror.h"
#include "wine/debug.h"
+#include "module.h"
WINE_DEFAULT_DEBUG_CHANNEL(resource);
+/* FIXME FIXME */
+#define _KERNEL32_
+#ifdef _NTSYSTEM_
/**********************************************************************
* is_data_file_module
*
@@ -156,11 +160,11 @@
}
len = MultiByteToWideChar( CP_ACP, 0, name, -1, NULL, 0 );
- if ((nameW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
+ if ((nameW = RtlAllocateHeap( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
{
MultiByteToWideChar( CP_ACP, 0, name, -1, nameW, len );
ret = find_entry_by_nameW( dir, nameW, root );
- HeapFree( GetProcessHeap(), 0, nameW );
+ RtlFreeHeap( GetProcessHeap(), 0, nameW );
}
return ret;
}
@@ -206,12 +210,18 @@
if ((result = (HRSRC)find_entry_by_id( resdirptr, lang, root ))) goto found;
/* 2. Language with neutral sublanguage */
- lang = MAKELANGID(PRIMARYLANGID(lang), SUBLANG_NEUTRAL);
- if ((result = (HRSRC)find_entry_by_id( resdirptr, lang, root ))) goto found;
+ if (1 || SUBLANGID(lang) != SUBLANG_NEUTRAL)
+ {
+ lang = MAKELANGID(PRIMARYLANGID(lang), SUBLANG_NEUTRAL);
+ if ((result = (HRSRC)find_entry_by_id( resdirptr, lang, root ))) goto found;
+ }
/* 3. Neutral language with neutral sublanguage */
- lang = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
- if ((result = (HRSRC)find_entry_by_id( resdirptr, lang, root ))) goto found;
+ if (1 || PRIMARYLANGID(lang) != LANG_NEUTRAL)
+ {
+ lang = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
+ if ((result = (HRSRC)find_entry_by_id( resdirptr, lang, root ))) goto found;
+ }
/* 4. Neutral language with default sublanguage */
lang = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT);
@@ -272,40 +282,9 @@
found:
return result;
}
+#endif
-
-/**********************************************************************
- * PE_LoadResource
- */
-HGLOBAL PE_LoadResource( HMODULE hmod, HRSRC hRsrc )
-{
- DWORD offset;
-
- if (!hRsrc) return 0;
- if (!hmod) hmod = GetModuleHandleA( NULL );
-
- offset = ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData;
-
- if (is_data_file_module(hmod))
- {
- hmod = (HMODULE)((ULONG_PTR)hmod & ~1);
- return (HGLOBAL)RtlImageRvaToVa( RtlImageNtHeader(hmod), hmod, offset, NULL );
- }
- else
- return (HGLOBAL)((char *)hmod + offset);
-}
-
-
-/**********************************************************************
- * PE_SizeofResource
- */
-DWORD PE_SizeofResource( HRSRC hRsrc )
-{
- if (!hRsrc) return 0;
- return ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->Size;
-}
-
-
+#ifdef _KERNEL32_
/**********************************************************************
* EnumResourceTypesA (KERNEL32.@)
*/
@@ -528,3 +507,69 @@
}
return ret;
}
+#endif
+
+#ifdef _NTSYSTEM_
+NTSTATUS WINAPI LdrAccessResource(HMODULE hModule, PIMAGE_RESOURCE_DATA_ENTRY resDataEntry,
+ void** pres, PULONG size)
+{
+ DWORD offset;
+ NTSTATUS nts;
+
+ if (!resDataEntry) return STATUS_RESOURCE_DATA_NOT_FOUND;
+ if (!hModule &&
+ (nts = LdrGetDllHandle(0, 0, NULL, (void**)&hModule)) != STATUS_SUCCESS)
+ return nts;
+
+ offset = resDataEntry->OffsetToData;
+
+ if (is_data_file_module(hModule))
+ {
+ hModule = (HMODULE)((ULONG_PTR)hModule & ~1);
+ if (pres)
+ *pres = RtlImageRvaToVa( RtlImageNtHeader(hModule), (void*)hModule, offset, NULL );
+ }
+ else
+ if (pres) *pres = ((char *)hModule + offset);
+ if (size) *size = resDataEntry->Size;
+ return STATUS_SUCCESS;
+}
+
+
+NTSTATUS WINAPI LdrFindResourceDirectory_U(HMODULE hModule, PLDR_RESOURCE_INFO resinfo,
+ DWORD level,
+ PIMAGE_RESOURCE_DIRECTORY_ENTRY* addr)
+{
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS WINAPI LdrFindResource_U(HMODULE hModule, PLDR_RESOURCE_INFO resinfo,
+ ULONG level, PIMAGE_RESOURCE_DATA_ENTRY* resDataEntry)
+{
+ const IMAGE_RESOURCE_DIRECTORY* resdirptr;
+ const void* root;
+
+ if (!(resdirptr = get_resdir(hModule))) return STATUS_RESOURCE_TYPE_NOT_FOUND;
+ root = resdirptr;
+
+ if (level > RESOURCE_TYPE_LEVEL)
+ {
+ if (!(resdirptr = find_entry_by_nameW(resdirptr, (LPCWSTR)resinfo->Type, root)))
+ return STATUS_RESOURCE_NAME_NOT_FOUND;
+
+ if (level > RESOURCE_NAME_LEVEL)
+ {
+ if (!(resdirptr = find_entry_by_nameW(resdirptr, (LPCWSTR)resinfo->Name, root)))
+ return STATUS_RESOURCE_LANG_NOT_FOUND;
+
+ if (level > RESOURCE_LANGUAGE_LEVEL)
+ {
+ if (!(resdirptr = find_entry_by_id(resdirptr, resinfo->Language, root)))
+ return STATUS_RESOURCE_DATA_NOT_FOUND;
+ }
+ }
+ }
+ if (resDataEntry) *resDataEntry = (void*)resdirptr;
+ return STATUS_SUCCESS;
+}
+#endif
Index: loader/resource.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/loader/resource.c,v
retrieving revision 1.65
diff -u -u -r1.65 resource.c
--- loader/resource.c 12 Dec 2002 23:34:01 -0000 1.65
+++ loader/resource.c 22 Dec 2002 10:39:23 -0000
@@ -259,6 +259,8 @@
*/
static DWORD RES_SizeofResource( HMODULE hModule, HRSRC hRsrc, BOOL bRet16 )
{
+ DWORD size = 0;
+
if (!hRsrc) return 0;
TRACE("(%p, %p, %s)\n", hModule, hRsrc, bRet16? "NE" : "PE" );
@@ -272,15 +274,22 @@
if (!pModule->module32) /* 16-bit NE module */
{
/* If we got a 32-bit hRsrc, we don't need to convert it */
- return NE_SizeofResource( pModule, hRsrc );
+ size = NE_SizeofResource( pModule, hRsrc );
+ }
+ else
+ {
+ /* If we got a 16-bit hRsrc, convert it */
+ if (!HIWORD(hRsrc)) hRsrc = MapHRsrc16To32( pModule, hRsrc );
+ if (hRsrc) size = ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->Size;
}
-
- /* If we got a 16-bit hRsrc, convert it */
- if (!HIWORD(hRsrc)) hRsrc = MapHRsrc16To32( pModule, hRsrc );
}
-
- /* 32-bit PE module */
- return PE_SizeofResource( hRsrc );
+ else
+ {
+ /* 32-bit PE module */
+ if (LdrAccessResource( hModule, (PIMAGE_RESOURCE_DATA_ENTRY)hRsrc, NULL, &size) != STATUS_SUCCESS)
+ size = 0;
+ }
+ return size;
}
/**********************************************************************
@@ -314,8 +323,13 @@
{
/* If we got a 16-bit hRsrc, convert it */
HRSRC hRsrc32 = HIWORD(hRsrc)? hRsrc : MapHRsrc16To32( pModule, hRsrc );
+ void* res;
- hMem = PE_LoadResource( pModule->module32, hRsrc32 );
+ if (LdrAccessResource( pModule->module32,
+ (PIMAGE_RESOURCE_DATA_ENTRY)hRsrc32,
+ &res, NULL ) != STATUS_SUCCESS)
+ res = NULL;
+ hMem = (HGLOBAL)res;
/* If we need to return a 16-bit resource, convert it */
if ( bRet16 )
@@ -331,7 +345,13 @@
else
{
/* 32-bit PE module */
- hMem = PE_LoadResource( hModule, hRsrc );
+ void* res;
+
+ if (LdrAccessResource( hModule,
+ (PIMAGE_RESOURCE_DATA_ENTRY)hRsrc,
+ &res, NULL ) != STATUS_SUCCESS)
+ res = NULL;
+ hMem = (HGLOBAL)res;
}
return hMem;
@@ -352,7 +372,7 @@
HRSRC WINAPI FindResourceA( HMODULE hModule, LPCSTR name, LPCSTR type )
{
return RES_FindResource( hModule, type, name,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), FALSE, FALSE );
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), FALSE, FALSE );
}
/**********************************************************************
@@ -381,7 +401,7 @@
HRSRC WINAPI FindResourceW(HINSTANCE hModule, LPCWSTR name, LPCWSTR type)
{
return RES_FindResource( hModule, (LPCSTR)type, (LPCSTR)name,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), TRUE, FALSE );
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), TRUE, FALSE );
}
/**********************************************************************
@@ -489,3 +509,4 @@
{
return RES_SizeofResource( hModule, hRsrc, FALSE );
}
+
Index: misc/version.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/misc/version.c,v
retrieving revision 1.61
diff -u -u -r1.61 version.c
--- misc/version.c 13 Sep 2002 17:47:44 -0000 1.61
+++ misc/version.c 11 Jan 2003 15:05:46 -0000
@@ -453,18 +453,18 @@
from one windows version */
for ( wm = MODULE_modref_list; wm; wm=wm->next )
{
- nt = RtlImageNtHeader(wm->module);
+ nt = RtlImageNtHeader(wm->ldr_module.BaseAddress);
ophd = &nt->OptionalHeader;
TRACE("%s: %02x.%02x/%02x.%02x/%02x.%02x/%02x.%02x\n",
- wm->modname,
+ debugstr_w(wm->ldr_module.BaseDllName.Buffer),
ophd->MajorLinkerVersion, ophd->MinorLinkerVersion,
ophd->MajorOperatingSystemVersion, ophd->MinorOperatingSystemVersion,
ophd->MajorImageVersion, ophd->MinorImageVersion,
ophd->MajorSubsystemVersion, ophd->MinorSubsystemVersion);
/* test if it is an external (native) dll */
- if (!(wm->flags & WINE_MODREF_INTERNAL))
+ if (!(wm->ldr_module.Flags & WINE_MODREF_INTERNAL))
{
int i;
for (i = 0; special_dlls[i]; i++)
@@ -472,13 +472,13 @@
/* test if it is a special dll */
if (!strcasecmp(wm->modname, special_dlls[i]))
{
- DWORD DllVersion = VERSION_GetSystemDLLVersion(wm->module);
+ DWORD DllVersion = VERSION_GetSystemDLLVersion(wm->ldr_module.BaseAddress);
if (WinVersion == NB_WINDOWS_VERSIONS)
WinVersion = DllVersion;
else {
if (WinVersion != DllVersion) {
ERR("You mixed system DLLs from different windows versions! Expect a crash! (%s: expected version '%s', but is '%s')\n",
- wm->modname,
+ debugstr_w(wm->ldr_module.BaseDllName.Buffer),
VersionData[WinVersion].getVersionEx.szCSDVersion,
VersionData[DllVersion].getVersionEx.szCSDVersion);
return WIN20; /* this may let the exe exiting */
Index: relay32/builtin32.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/relay32/builtin32.c,v
retrieving revision 1.90
diff -u -u -r1.90 builtin32.c
--- relay32/builtin32.c 21 Nov 2002 03:45:02 -0000 1.90
+++ relay32/builtin32.c 11 Jan 2003 15:09:31 -0000
@@ -134,7 +134,7 @@
}
TRACE( "loaded %s %p %p\n", fullname, wm, module );
HeapFree( GetProcessHeap(), 0, fullname );
- wm->refCount++; /* we don't support freeing builtin dlls (FIXME)*/
+ wm->ldr_module.LoadCount++; /* we don't support freeing builtin dlls (FIXME)*/
/* setup relay debugging entry points */
if (TRACE_ON(relay)) RELAY_SetupDLL( (void *)module );
Index: relay32/relay386.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/relay32/relay386.c,v
retrieving revision 1.50
diff -u -u -r1.50 relay386.c
--- relay32/relay386.c 10 Dec 2002 22:56:44 -0000 1.50
+++ relay32/relay386.c 22 Dec 2002 14:01:40 -0000
@@ -238,8 +238,8 @@
for (wm = MODULE_modref_list; wm; wm = wm->next)
{
- if (!(wm->flags & WINE_MODREF_INTERNAL)) continue;
- exp = RtlImageDirectoryEntryToData( wm->module, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &size );
+ if (!(wm->ldr_module.Flags & WINE_MODREF_INTERNAL)) continue;
+ exp = RtlImageDirectoryEntryToData( wm->ldr_module.BaseAddress, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &size );
if (!exp) continue;
debug = (DEBUG_ENTRY_POINT *)((char *)exp + size);
if (debug <= relay && relay < debug + exp->NumberOfFunctions)
@@ -251,7 +251,7 @@
/* Now find the function */
- base = (char *)wm->module;
+ base = (char *)wm->ldr_module.BaseAddress;
strcpy( buffer, base + exp->Name );
p = buffer + strlen(buffer);
if (p > buffer + 4 && !strcasecmp( p - 4, ".dll" )) p -= 4;
Index: scheduler/process.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/scheduler/process.c,v
retrieving revision 1.205
diff -u -u -r1.205 process.c
--- scheduler/process.c 5 Dec 2002 19:56:15 -0000 1.205
+++ scheduler/process.c 22 Dec 2002 13:45:44 -0000
@@ -533,7 +533,7 @@
/* create the main modref and load dependencies */
if (!(wm = PE_CreateModule( current_process.module, main_exe_name, 0, 0, FALSE )))
goto error;
- wm->refCount++;
+ wm->ldr_module.LoadCount++;
if (main_exe_file) CloseHandle( main_exe_file ); /* we no longer need it */
@@ -1355,7 +1355,7 @@
*/
void WINAPI ExitProcess( DWORD status )
{
- MODULE_DllProcessDetach( TRUE, (LPVOID)1 );
+ LdrShutdownProcess();
SERVER_START_REQ( terminate_process )
{
/* send the exit code to the server */
Index: scheduler/thread.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/scheduler/thread.c,v
retrieving revision 1.128
diff -u -u -r1.128 thread.c
--- scheduler/thread.c 5 Dec 2002 19:56:15 -0000 1.128
+++ scheduler/thread.c 2 Jan 2003 14:12:32 -0000
@@ -376,12 +376,12 @@
if (last)
{
- MODULE_DllProcessDetach( TRUE, (LPVOID)1 );
+ LdrShutdownProcess();
exit( code );
}
else
{
- MODULE_DllThreadDetach( NULL );
+ LdrShutdownThread();
if (!(NtCurrentTeb()->tibflags & TEBF_WIN32)) TASK_ExitTask();
SYSDEPS_ExitThread( code );
}
Index: tools/winebuild/spec16.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/tools/winebuild/spec16.c,v
retrieving revision 1.38
diff -u -u -r1.38 spec16.c
--- tools/winebuild/spec16.c 18 Oct 2002 00:29:32 -0000 1.38
+++ tools/winebuild/spec16.c 21 Dec 2002 20:21:37 -0000
@@ -31,6 +31,7 @@
#include "wine/exception.h"
#include "wine/library.h"
#include "builtin16.h"
+#define _KERNEL32_ /* hack */
#include "module.h"
#include "stackframe.h"
More information about the wine-patches
mailing list