- 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:
parent
93189f2395
commit
84d1a8ff8c
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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*);
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
@ -71,30 +69,6 @@ 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
|
||||
*/
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
|
|
Loading…
Reference in New Issue