ntdll/kernel32: #6

Eric Pouech eric.pouech at wanadoo.fr
Thu Mar 13 14:33:21 CST 2003


ChangeLog:
- added LDR_MODULE structure to WINE_MODREF and made dummy filling of 
this structure
- implementation of LdrFindEntry
- implementation of GetModuleFileName[AW] on top of LdrFindEntry

(Alexandre, in order to handle correctly the loader_critsect between 
ntdll & kernel32, what do you suggest ? NT does it thru the fastpeblock 
in the PEB, which we don't implement. shall we add to the PDB in some 
unused field (which means we do export the PDB struct out of 
scheduler/process.c, but you seemed to reluctant to do so so far)

A+
-- 
Eric Pouech
-------------- next part --------------
diff -u -x '*~' -x '.#*' dlls/ntdll5/loader.c dlls/ntdll/loader.c
--- dlls/ntdll5/loader.c	2003-03-09 16:01:11.000000000 +0100
+++ dlls/ntdll/loader.c	2003-03-12 21:15:00.000000000 +0100
@@ -16,6 +16,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <assert.h>
+
 #include "winbase.h"
 #include "winnt.h"
 #include "winternl.h"
@@ -33,7 +35,7 @@
 WINE_DECLARE_DEBUG_CHANNEL(module);
 WINE_DECLARE_DEBUG_CHANNEL(loaddll);
 
-static int free_lib_count;   /* recursion depth of FreeLibrary calls */
+static int free_lib_count;   /* recursion depth of LdrUnloadDll calls */
 
 /* filter for page-fault exceptions */
 static WINE_EXCEPTION_FILTER(page_fault)
@@ -43,6 +45,29 @@
     return EXCEPTION_CONTINUE_SEARCH;
 }
 
+CRITICAL_SECTION loader_section = CRITICAL_SECTION_INIT( "loader_section" );
+
+/*************************************************************************
+ *		MODULE32_LookupHMODULE
+ * looks for the referenced HMODULE in the current process
+ * NOTE: Assumes that the process critical section is held!
+ */
+static WINE_MODREF *MODULE32_LookupHMODULE( HMODULE hmod )
+{
+    WINE_MODREF	*wm;
+
+    if (!hmod)
+    	return exe_modref;
+
+    if (!HIWORD(hmod)) {
+    	ERR("tried to lookup %p in win32 module handler!\n",hmod);
+	return NULL;
+    }
+    for ( wm = MODULE_modref_list; wm; wm=wm->next )
+	if (wm->module == hmod)
+	    return wm;
+    return NULL;
+}
 
 /*************************************************************************
  *		MODULE_AllocModRef
@@ -53,6 +78,7 @@
 WINE_MODREF *MODULE_AllocModRef( HMODULE hModule, LPCSTR filename )
 {
     WINE_MODREF *wm;
+    IMAGE_NT_HEADERS *nt = RtlImageNtHeader(hModule);
 
     DWORD long_len = strlen( filename );
     DWORD short_len = GetShortPathNameA( filename, NULL, 0 );
@@ -77,7 +103,26 @@
         if (wm->next) wm->next->prev = wm;
         MODULE_modref_list = wm;
 
-        if (!(RtlImageNtHeader(hModule)->FileHeader.Characteristics & IMAGE_FILE_DLL))
+        wm->ldr.InLoadOrderModuleList.Flink = NULL;
+        wm->ldr.InLoadOrderModuleList.Blink = NULL;
+        wm->ldr.InMemoryOrderModuleList.Flink = NULL;
+        wm->ldr.InMemoryOrderModuleList.Blink = NULL;
+        wm->ldr.InInitializationOrderModuleList.Flink = NULL;
+        wm->ldr.InInitializationOrderModuleList.Blink = NULL;
+        wm->ldr.BaseAddress = hModule;
+        wm->ldr.EntryPoint = (nt->OptionalHeader.AddressOfEntryPoint) ?
+            ((ULONG)hModule + nt->OptionalHeader.AddressOfEntryPoint) : 0;
+        wm->ldr.SizeOfImage = nt->OptionalHeader.SizeOfImage;
+        RtlCreateUnicodeStringFromAsciiz( &wm->ldr.FullDllName, wm->filename);
+        RtlCreateUnicodeStringFromAsciiz( &wm->ldr.BaseDllName, wm->modname);
+        wm->ldr.Flags = 0;
+        wm->ldr.LoadCount = 0;
+        wm->ldr.TlsIndex = 0;
+        wm->ldr.SectionHandle = NULL;
+        wm->ldr.CheckSum = 0;
+        wm->ldr.TimeDateStamp = 0;
+
+        if (!(nt->FileHeader.Characteristics & IMAGE_FILE_DLL))
         {
             if (!exe_modref) exe_modref = wm;
             else FIXME( "Trying to load second .EXE file: %s\n", filename );
@@ -108,6 +153,36 @@
     return ret;
 }
 
+/******************************************************************
+ *              LdrFindEntryForAddress (NTDLL.@)
+ *
+ */
+NTSTATUS WINAPI LdrFindEntryForAddress(const void* addr, PLDR_MODULE* mod)
+{
+    WINE_MODREF*        wm;
+    NTSTATUS            nts = STATUS_NO_MORE_ENTRIES;
+
+    RtlEnterCriticalSection( &loader_section );
+    if (!addr)
+    {
+        wm = exe_modref;
+    }
+    else for ( wm = MODULE_modref_list; wm; wm = wm->next )
+    {
+        if ((const void*)wm->module <= addr &&
+            addr < (const void*)((const char*)wm->module + wm->ldr.SizeOfImage))
+            break;
+    }
+    if (wm)
+    {
+        *mod = &wm->ldr;
+        nts = STATUS_SUCCESS;
+    }
+    RtlLeaveCriticalSection( &loader_section );
+
+    return nts;
+}
+
 /**********************************************************************
  *	    MODULE_FindModule
  *
@@ -547,6 +622,8 @@
         if (wm->dlhandle) wine_dll_unload( wm->dlhandle );
         else UnmapViewOfFile( (LPVOID)wm->module );
         FreeLibrary16(wm->hDummyMod);
+        RtlFreeUnicodeString( &wm->ldr.FullDllName );
+        RtlFreeUnicodeString( &wm->ldr.BaseDllName );
         RtlFreeHeap( ntdll_get_process_heap(), 0, wm->deps );
         RtlFreeHeap( ntdll_get_process_heap(), 0, wm );
     }
diff -u -x '*~' -x '.#*' dlls/ntdll5/ntdll.spec dlls/ntdll/ntdll.spec
--- dlls/ntdll5/ntdll.spec	2003-03-07 11:11:19.000000000 +0100
+++ dlls/ntdll/ntdll.spec	2003-03-09 15:10:40.000000000 +0100
@@ -36,7 +36,7 @@
 @ stub LdrAccessResource
 @ stdcall LdrDisableThreadCalloutsForDll(long) LdrDisableThreadCalloutsForDll
 @ stub LdrEnumResources
-@ stub LdrFindEntryForAddress
+@ stdcall LdrFindEntryForAddress(ptr ptr) LdrFindEntryForAddress
 @ stub LdrFindResourceDirectory_U
 @ stub LdrFindResource_U
 @ stdcall LdrGetDllHandle(long long ptr ptr) LdrGetDllHandle
diff -u -x '*~' -x '.#*' include5/module.h include/module.h
--- include5/module.h	2003-03-07 12:38:05.000000000 +0100
+++ include/module.h	2003-03-12 21:27:49.000000000 +0100
@@ -134,7 +134,7 @@
 	HMODULE16            hDummyMod; /* Win16 dummy module */
 	void                *dlhandle;  /* handle returned by dlopen() */
 	int                  tlsindex;  /* TLS index or -1 if none */
-
+        LDR_MODULE           ldr;
 	FARPROC            (*find_export)( struct _wine_modref *wm, LPCSTR func,
                                            int hint, BOOL snoop );
 
@@ -210,7 +210,6 @@
 extern CRITICAL_SECTION loader_section;
 extern int process_detaching;
 extern BOOL MODULE_InitDLL( WINE_MODREF *wm, DWORD type, LPVOID lpReserved );
-extern WINE_MODREF* MODULE32_LookupHMODULE( HMODULE );
 
 /* loader/ne/module.c */
 extern NE_MODULE *NE_GetPtr( HMODULE16 hModule );
diff -u -x '*~' -x '.#*' include5/winternl.h include/winternl.h
--- include5/winternl.h	2003-03-07 06:01:03.000000000 +0100
+++ include/winternl.h	2003-03-09 15:16:01.000000000 +0100
@@ -1184,7 +1184,7 @@
 } LDR_RESOURCE_INFO, *PLDR_RESOURCE_INFO;
 
 NTSTATUS WINAPI LdrDisableThreadCalloutsForDll(HMODULE);
-NTSTATUS WINAPI LdrFindEntryForAddress(void*, PLDR_MODULE*);
+NTSTATUS WINAPI LdrFindEntryForAddress(const void*, PLDR_MODULE*);
 NTSTATUS WINAPI LdrGetDllHandle(ULONG, ULONG, PUNICODE_STRING, HMODULE*);
 NTSTATUS WINAPI LdrGetProcedureAddress(HMODULE, PANSI_STRING, ULONG, void**);
 NTSTATUS WINAPI LdrLoadDll(LPCWSTR, DWORD, PUNICODE_STRING, HMODULE*);
diff -u -x '*~' -x '.#*' loader5/module.c loader/module.c
--- loader5/module.c	2003-03-09 14:50:22.000000000 +0100
+++ loader/module.c	2003-03-12 21:15:09.000000000 +0100
@@ -50,8 +50,6 @@
 WINE_MODREF *exe_modref;
 int process_detaching = 0;  /* set on process detach to avoid deadlocks with thread detach */
 
-CRITICAL_SECTION loader_section = CRITICAL_SECTION_INIT( "loader_section" );
-
 /***********************************************************************
  *           wait_input_idle
  *
@@ -72,30 +70,6 @@
 
 
 /*************************************************************************
- *		MODULE32_LookupHMODULE
- * looks for the referenced HMODULE in the current process
- * NOTE: Assumes that the process critical section is held!
- */
-WINE_MODREF *MODULE32_LookupHMODULE( HMODULE hmod )
-{
-    WINE_MODREF	*wm;
-
-    if (!hmod)
-    	return exe_modref;
-
-    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)
-	    return wm;
-    SetLastError( ERROR_INVALID_HANDLE );
-    return NULL;
-}
-
-/*************************************************************************
  *		MODULE_InitDLL
  */
 BOOL MODULE_InitDLL( WINE_MODREF *wm, DWORD type, LPVOID lpReserved )
@@ -947,9 +921,9 @@
 	LPSTR lpFileName,	/* [out] filenamebuffer */
         DWORD size )		/* [in] size of filenamebuffer */
 {
-    RtlEnterCriticalSection( &loader_section );
-
     lpFileName[0] = 0;
+
+    RtlEnterCriticalSection( &loader_section );
     if (!hModule && !(NtCurrentTeb()->tibflags & TEBF_WIN32))
     {
         /* 16-bit task - get current NE module name */
@@ -958,11 +932,18 @@
     }
     else
     {
-        WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule );
-        if (wm) lstrcpynA( lpFileName, wm->filename, size );
-    }
+        LDR_MODULE* pldr;
 
+        if (LdrFindEntryForAddress( hModule, &pldr) == STATUS_SUCCESS)
+        {
+            WideCharToMultiByte( CP_ACP, 0, 
+                                 pldr->FullDllName.Buffer, pldr->FullDllName.Length,
+                                 lpFileName, size, NULL, NULL );
+            lpFileName[size - 1] = '\0';
+        }
+    }
     RtlLeaveCriticalSection( &loader_section );
+
     TRACE("%s\n", lpFileName );
     return strlen(lpFileName);
 }
@@ -973,12 +954,37 @@
  */
 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 );
+    lpFileName[0] = 0;
+
+    RtlEnterCriticalSection( &loader_section );
+    if (!hModule && !(NtCurrentTeb()->tibflags & TEBF_WIN32))
+    {
+        /* 16-bit task - get current NE module name */
+        NE_MODULE *pModule = NE_GetPtr( GetCurrentTask() );
+        if (pModule)
+        {
+            WCHAR    path[MAX_PATH];
+
+            MultiByteToWideChar( CP_ACP, 0, NE_MODULE_NAME(pModule), -1, 
+                                 path, MAX_PATH );
+            GetLongPathNameW(path, lpFileName, size);
+        }
+    }
+    else
+    {
+        LDR_MODULE* pldr;
+
+        if (LdrFindEntryForAddress( hModule, &pldr) == STATUS_SUCCESS)
+        {
+            size = min(pldr->FullDllName.Length / sizeof(WCHAR), size - 1);
+            strncpyW( lpFileName, pldr->FullDllName.Buffer, size );
+            lpFileName[size] = '\0';
+        }
+    }
+
+    RtlLeaveCriticalSection( &loader_section );
+
+    TRACE("%s\n", debugstr_w(lpFileName) );
     return strlenW(lpFileName);
 }
 


More information about the wine-patches mailing list