- 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
This commit is contained in:
Eric Pouech 2003-03-18 18:29:13 +00:00 committed by Alexandre Julliard
parent 93189f2395
commit 84d1a8ff8c
5 changed files with 130 additions and 48 deletions

View file

@ -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(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 @@ static WINE_EXCEPTION_FILTER(page_fault)
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 @@ static WINE_EXCEPTION_FILTER(page_fault)
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 @@ WINE_MODREF *MODULE_AllocModRef( HMODULE hModule, LPCSTR filename )
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) ?
((char *)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,27 @@ NTSTATUS WINAPI LdrDisableThreadCalloutsForDll(HMODULE hModule)
return ret;
}
/******************************************************************
* LdrFindEntryForAddress (NTDLL.@)
*
* The loader_section must be locked while calling this function
*/
NTSTATUS WINAPI LdrFindEntryForAddress(const void* addr, PLDR_MODULE* mod)
{
WINE_MODREF* wm;
for ( wm = MODULE_modref_list; wm; wm = wm->next )
{
if ((const void *)wm->module <= addr &&
(char *)addr < (char*)wm->module + wm->ldr.SizeOfImage)
{
*mod = &wm->ldr;
return STATUS_SUCCESS;
}
}
return STATUS_NO_MORE_ENTRIES;
}
/**********************************************************************
* MODULE_FindModule
*

View file

@ -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

View file

@ -134,7 +134,7 @@ typedef struct _wine_modref
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 WINE_MODREF *exe_modref;
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 );

View file

@ -1184,7 +1184,7 @@ typedef struct _LDR_RESOURCE_INFO
} 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*);

View file

@ -50,8 +50,6 @@ WINE_MODREF *MODULE_modref_list = NULL;
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 @@ static DWORD wait_input_idle( HANDLE process, DWORD timeout )
/*************************************************************************
* 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 @@ BOOL MODULE_InitDLL( WINE_MODREF *wm, DWORD type, LPVOID lpReserved )
return retv;
}
/*************************************************************************
* MODULE_DllProcessAttach
*
@ -947,24 +922,36 @@ DWORD WINAPI GetModuleFileNameA(
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 GetModuleFileNameA(
*/
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;
}
/******************************************************************