ntdll/kernel32: #6 (2nd try)

Eric Pouech pouech-eric at wanadoo.fr
Sat Mar 15 14:11:35 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

(from previous version, NULL address testing remains in kernel32, as NT 
does)

A+
-- 
Eric Pouech
-------------- next part --------------
diff -u -x '*~' -x '.#*' dlls/ntdll5/loader.c dlls/ntdll/loader.c
--- dlls/ntdll5/loader.c	2003-03-15 08:46:31.000000000 +0100
+++ dlls/ntdll/loader.c	2003-03-15 09:57:50.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) ?
+            (void*)((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,32 @@
     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 );
+    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
  *
diff -u -x '*~' -x '.#*' dlls/ntdll5/ntdll.spec dlls/ntdll/ntdll.spec
--- dlls/ntdll5/ntdll.spec	2003-03-15 08:44:53.000000000 +0100
+++ dlls/ntdll/ntdll.spec	2003-03-15 08:49:00.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-15 11:08:29.000000000 +0100
+++ include/module.h	2003-03-15 13:08:19.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-15 08:44:55.000000000 +0100
+++ include/winternl.h	2003-03-15 08:49:00.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-15 08:48:36.000000000 +0100
+++ loader/module.c	2003-03-15 15:06:59.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,31 +70,7 @@
 
 
 /*************************************************************************
- *		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
+ *              MODULE_InitDLL
  */
 BOOL MODULE_InitDLL( WINE_MODREF *wm, DWORD type, LPVOID lpReserved )
 {
@@ -123,6 +97,7 @@
     return retv;
 }
 
+
 /*************************************************************************
  *		MODULE_DllProcessAttach
  *
@@ -947,24 +922,36 @@
 	LPSTR lpFileName,	/* [out] filenamebuffer */
         DWORD size )		/* [in] size of filenamebuffer */
 {
-    RtlEnterCriticalSection( &loader_section );
+    DWORD       len = 0;
 
     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) GetLongPathNameA(NE_MODULE_NAME(pModule), lpFileName, size);
+        if (pModule) len = GetLongPathNameA(NE_MODULE_NAME(pModule), lpFileName, size);
     }
-    else
+    else if (hModule || LdrGetDllHandle( 0, 0, NULL, &hModule ) == STATUS_SUCCESS)
     {
-        WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule );
-        if (wm) lstrcpynA( lpFileName, wm->filename, size );
-    }
+        LDR_MODULE* pldr;
+        NTSTATUS    nts;
 
+        nts = LdrFindEntryForAddress( hModule, &pldr );
+        if (nts == STATUS_SUCCESS)
+        {
+            WideCharToMultiByte( CP_ACP, 0, 
+                                 pldr->FullDllName.Buffer, pldr->FullDllName.Length,
+                                 lpFileName, size, NULL, NULL );
+            len = min(size, pldr->FullDllName.Length / sizeof(WCHAR));
+        }
+        else SetLastError( RtlNtStatusToDosError( nts ) );
+    }
     RtlLeaveCriticalSection( &loader_section );
-    TRACE("%s\n", lpFileName );
-    return strlen(lpFileName);
+
+    TRACE( "%s\n", debugstr_an(lpFileName, len) );
+    return len;
 }
 
 
@@ -973,13 +960,43 @@
  */
 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 );
-    return strlenW(lpFileName);
+    DWORD       len = 0;
+
+    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 );
+            len = GetLongPathNameW(path, lpFileName, size);
+        }
+    }
+    else if (hModule || LdrGetDllHandle( 0, 0, NULL, &hModule ) == STATUS_SUCCESS)
+    {
+        LDR_MODULE* pldr;
+        NTSTATUS    nts;
+
+        nts = LdrFindEntryForAddress( hModule, &pldr );
+        if (nts == STATUS_SUCCESS)
+        {
+            len = min(size, pldr->FullDllName.Length / sizeof(WCHAR));
+            strncpyW(lpFileName, pldr->FullDllName.Buffer, len);
+            if (len < size) lpFileName[len] = 0;
+        }
+        else SetLastError( RtlNtStatusToDosError( nts ) );
+
+    }
+    RtlLeaveCriticalSection( &loader_section );
+
+    TRACE( "%s\n", debugstr_wn(lpFileName, len) );
+    return len;
 }
 
 /******************************************************************


More information about the wine-patches mailing list