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