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