- removed next & prev fields from WINE_MODREF and implement instead
the three linked lists in LDR_MODULE - added PEB_LDR_DATA structure to PEB - removed a couple of no longer needed global & static variables
This commit is contained in:
parent
2a3ce4c425
commit
675b75597b
|
@ -41,9 +41,6 @@ WINE_DECLARE_DEBUG_CHANNEL(loaddll);
|
||||||
|
|
||||||
typedef DWORD (CALLBACK *DLLENTRYPROC)(HMODULE,DWORD,LPVOID);
|
typedef DWORD (CALLBACK *DLLENTRYPROC)(HMODULE,DWORD,LPVOID);
|
||||||
|
|
||||||
WINE_MODREF *MODULE_modref_list = NULL;
|
|
||||||
|
|
||||||
static WINE_MODREF *exe_modref;
|
|
||||||
static int process_detaching = 0; /* set on process detach to avoid deadlocks with thread detach */
|
static int process_detaching = 0; /* set on process detach to avoid deadlocks with thread detach */
|
||||||
static int free_lib_count; /* recursion depth of LdrUnloadDll calls */
|
static int free_lib_count; /* recursion depth of LdrUnloadDll calls */
|
||||||
|
|
||||||
|
@ -89,19 +86,20 @@ inline static void *get_rva( HMODULE module, DWORD va )
|
||||||
*/
|
*/
|
||||||
static WINE_MODREF *get_modref( HMODULE hmod )
|
static WINE_MODREF *get_modref( HMODULE hmod )
|
||||||
{
|
{
|
||||||
WINE_MODREF *wm;
|
PLIST_ENTRY mark, entry;
|
||||||
|
PLDR_MODULE mod;
|
||||||
|
|
||||||
if (cached_modref && cached_modref->ldr.BaseAddress == hmod) return cached_modref;
|
if (cached_modref && cached_modref->ldr.BaseAddress == hmod) return cached_modref;
|
||||||
|
|
||||||
for ( wm = MODULE_modref_list; wm; wm=wm->next )
|
mark = &NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList;
|
||||||
|
for (entry = mark->Flink; entry != mark; entry = entry->Flink)
|
||||||
{
|
{
|
||||||
if (wm->ldr.BaseAddress == hmod)
|
mod = CONTAINING_RECORD(entry, LDR_MODULE, InMemoryOrderModuleList);
|
||||||
{
|
if (mod->BaseAddress == hmod)
|
||||||
cached_modref = wm;
|
return cached_modref = CONTAINING_RECORD(mod, WINE_MODREF, ldr);
|
||||||
break;
|
if (mod->BaseAddress > (void*)hmod) break;
|
||||||
}
|
}
|
||||||
}
|
return NULL;
|
||||||
return wm;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -351,6 +349,8 @@ WINE_MODREF *MODULE_AllocModRef( HMODULE hModule, LPCSTR filename )
|
||||||
{
|
{
|
||||||
WINE_MODREF *wm;
|
WINE_MODREF *wm;
|
||||||
IMAGE_NT_HEADERS *nt = RtlImageNtHeader(hModule);
|
IMAGE_NT_HEADERS *nt = RtlImageNtHeader(hModule);
|
||||||
|
PLIST_ENTRY entry, mark;
|
||||||
|
BOOLEAN linked = FALSE;
|
||||||
|
|
||||||
DWORD long_len = strlen( filename );
|
DWORD long_len = strlen( filename );
|
||||||
DWORD short_len = GetShortPathNameA( filename, NULL, 0 );
|
DWORD short_len = GetShortPathNameA( filename, NULL, 0 );
|
||||||
|
@ -368,16 +368,6 @@ WINE_MODREF *MODULE_AllocModRef( HMODULE hModule, LPCSTR filename )
|
||||||
if ((wm->short_modname = strrchr( wm->short_filename, '\\' ))) wm->short_modname++;
|
if ((wm->short_modname = strrchr( wm->short_filename, '\\' ))) wm->short_modname++;
|
||||||
else wm->short_modname = wm->short_filename;
|
else wm->short_modname = wm->short_filename;
|
||||||
|
|
||||||
wm->next = MODULE_modref_list;
|
|
||||||
if (wm->next) wm->next->prev = wm;
|
|
||||||
MODULE_modref_list = wm;
|
|
||||||
|
|
||||||
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.BaseAddress = hModule;
|
||||||
wm->ldr.EntryPoint = (nt->OptionalHeader.AddressOfEntryPoint) ?
|
wm->ldr.EntryPoint = (nt->OptionalHeader.AddressOfEntryPoint) ?
|
||||||
((char *)hModule + nt->OptionalHeader.AddressOfEntryPoint) : 0;
|
((char *)hModule + nt->OptionalHeader.AddressOfEntryPoint) : 0;
|
||||||
|
@ -391,11 +381,43 @@ WINE_MODREF *MODULE_AllocModRef( HMODULE hModule, LPCSTR filename )
|
||||||
wm->ldr.CheckSum = 0;
|
wm->ldr.CheckSum = 0;
|
||||||
wm->ldr.TimeDateStamp = 0;
|
wm->ldr.TimeDateStamp = 0;
|
||||||
|
|
||||||
|
/* this is a bit ugly, but we need to have app module first in LoadOrder
|
||||||
|
* list, But in wine, ntdll is loaded first, so by inserting DLLs at the tail
|
||||||
|
* and app module at the head we insure that order
|
||||||
|
*/
|
||||||
if (!(nt->FileHeader.Characteristics & IMAGE_FILE_DLL))
|
if (!(nt->FileHeader.Characteristics & IMAGE_FILE_DLL))
|
||||||
{
|
{
|
||||||
if (!exe_modref) exe_modref = wm;
|
/* is first loaded module a DLL or an exec ? */
|
||||||
|
mark = &NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList;
|
||||||
|
if (mark->Flink == mark ||
|
||||||
|
(CONTAINING_RECORD(mark->Flink, LDR_MODULE, InLoadOrderModuleList)->Flags & LDR_IMAGE_IS_DLL))
|
||||||
|
{
|
||||||
|
InsertHeadList(&NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList,
|
||||||
|
&wm->ldr.InLoadOrderModuleList);
|
||||||
|
linked = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else wm->ldr.Flags |= LDR_IMAGE_IS_DLL;
|
else wm->ldr.Flags |= LDR_IMAGE_IS_DLL;
|
||||||
|
|
||||||
|
if (!linked)
|
||||||
|
InsertTailList(&NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList,
|
||||||
|
&wm->ldr.InLoadOrderModuleList);
|
||||||
|
|
||||||
|
/* insert module in MemoryList, sorted in increasing base addresses */
|
||||||
|
mark = &NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList;
|
||||||
|
for (entry = mark->Flink; entry != mark; entry = entry->Flink)
|
||||||
|
{
|
||||||
|
if (CONTAINING_RECORD(entry, LDR_MODULE, InMemoryOrderModuleList)->BaseAddress > wm->ldr.BaseAddress)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
entry->Blink->Flink = &wm->ldr.InMemoryOrderModuleList;
|
||||||
|
wm->ldr.InMemoryOrderModuleList.Blink = entry->Blink;
|
||||||
|
wm->ldr.InMemoryOrderModuleList.Flink = entry;
|
||||||
|
entry->Blink = &wm->ldr.InMemoryOrderModuleList;
|
||||||
|
|
||||||
|
/* wait until init is called for inserting into this list */
|
||||||
|
wm->ldr.InInitializationOrderModuleList.Flink = NULL;
|
||||||
|
wm->ldr.InInitializationOrderModuleList.Blink = NULL;
|
||||||
}
|
}
|
||||||
return wm;
|
return wm;
|
||||||
}
|
}
|
||||||
|
@ -408,13 +430,16 @@ WINE_MODREF *MODULE_AllocModRef( HMODULE hModule, LPCSTR filename )
|
||||||
*/
|
*/
|
||||||
static NTSTATUS alloc_process_tls(void)
|
static NTSTATUS alloc_process_tls(void)
|
||||||
{
|
{
|
||||||
WINE_MODREF *wm;
|
PLIST_ENTRY mark, entry;
|
||||||
|
PLDR_MODULE mod;
|
||||||
IMAGE_TLS_DIRECTORY *dir;
|
IMAGE_TLS_DIRECTORY *dir;
|
||||||
ULONG size, i;
|
ULONG size, i;
|
||||||
|
|
||||||
for (wm = MODULE_modref_list; wm; wm = wm->next)
|
mark = &NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList;
|
||||||
|
for (entry = mark->Flink; entry != mark; entry = entry->Flink)
|
||||||
{
|
{
|
||||||
if (!(dir = RtlImageDirectoryEntryToData( wm->ldr.BaseAddress, TRUE,
|
mod = CONTAINING_RECORD(entry, LDR_MODULE, InMemoryOrderModuleList);
|
||||||
|
if (!(dir = RtlImageDirectoryEntryToData( mod->BaseAddress, TRUE,
|
||||||
IMAGE_DIRECTORY_ENTRY_TLS, &size )))
|
IMAGE_DIRECTORY_ENTRY_TLS, &size )))
|
||||||
continue;
|
continue;
|
||||||
size = (dir->EndAddressOfRawData - dir->StartAddressOfRawData) + dir->SizeOfZeroFill;
|
size = (dir->EndAddressOfRawData - dir->StartAddressOfRawData) + dir->SizeOfZeroFill;
|
||||||
|
@ -429,15 +454,16 @@ static NTSTATUS alloc_process_tls(void)
|
||||||
tls_dirs = RtlAllocateHeap( ntdll_get_process_heap(), 0, tls_module_count * sizeof(*tls_dirs) );
|
tls_dirs = RtlAllocateHeap( ntdll_get_process_heap(), 0, tls_module_count * sizeof(*tls_dirs) );
|
||||||
if (!tls_dirs) return STATUS_NO_MEMORY;
|
if (!tls_dirs) return STATUS_NO_MEMORY;
|
||||||
|
|
||||||
for (i = 0, wm = MODULE_modref_list; wm; wm = wm->next)
|
for (i = 0, entry = mark->Flink; entry != mark; entry = entry->Flink)
|
||||||
{
|
{
|
||||||
if (!(dir = RtlImageDirectoryEntryToData( wm->ldr.BaseAddress, TRUE,
|
mod = CONTAINING_RECORD(entry, LDR_MODULE, InMemoryOrderModuleList);
|
||||||
|
if (!(dir = RtlImageDirectoryEntryToData( mod->BaseAddress, TRUE,
|
||||||
IMAGE_DIRECTORY_ENTRY_TLS, &size )))
|
IMAGE_DIRECTORY_ENTRY_TLS, &size )))
|
||||||
continue;
|
continue;
|
||||||
tls_dirs[i] = dir;
|
tls_dirs[i] = dir;
|
||||||
*dir->AddressOfIndex = i;
|
*dir->AddressOfIndex = i;
|
||||||
wm->ldr.TlsIndex = i;
|
mod->TlsIndex = i;
|
||||||
wm->ldr.LoadCount = -1; /* can't unload it */
|
mod->LoadCount = -1; /* can't unload it */
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
@ -590,7 +616,12 @@ NTSTATUS MODULE_DllProcessAttach( WINE_MODREF *wm, LPVOID lpReserved )
|
||||||
|
|
||||||
if (!wm)
|
if (!wm)
|
||||||
{
|
{
|
||||||
wm = exe_modref;
|
PLIST_ENTRY mark;
|
||||||
|
|
||||||
|
mark = &NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList;
|
||||||
|
wm = CONTAINING_RECORD(CONTAINING_RECORD(mark->Flink,
|
||||||
|
LDR_MODULE, InLoadOrderModuleList),
|
||||||
|
WINE_MODREF, ldr);
|
||||||
wm->ldr.LoadCount = -1; /* can't unload main exe */
|
wm->ldr.LoadCount = -1; /* can't unload main exe */
|
||||||
if ((status = alloc_process_tls()) != STATUS_SUCCESS) goto done;
|
if ((status = alloc_process_tls()) != STATUS_SUCCESS) goto done;
|
||||||
if ((status = alloc_thread_tls()) != STATUS_SUCCESS) goto done;
|
if ((status = alloc_thread_tls()) != STATUS_SUCCESS) goto done;
|
||||||
|
@ -626,16 +657,8 @@ NTSTATUS MODULE_DllProcessAttach( WINE_MODREF *wm, LPVOID lpReserved )
|
||||||
current_modref = prev;
|
current_modref = prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Re-insert MODREF at head of list */
|
InsertTailList(&NtCurrentTeb()->Peb->LdrData->InInitializationOrderModuleList,
|
||||||
if (status == STATUS_SUCCESS && wm->prev )
|
&wm->ldr.InInitializationOrderModuleList);
|
||||||
{
|
|
||||||
wm->prev->next = wm->next;
|
|
||||||
if ( wm->next ) wm->next->prev = wm->prev;
|
|
||||||
|
|
||||||
wm->prev = NULL;
|
|
||||||
wm->next = MODULE_modref_list;
|
|
||||||
MODULE_modref_list = wm->next->prev = wm;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove recursion flag */
|
/* Remove recursion flag */
|
||||||
wm->ldr.Flags &= ~LDR_LOAD_IN_PROGRESS;
|
wm->ldr.Flags &= ~LDR_LOAD_IN_PROGRESS;
|
||||||
|
@ -656,29 +679,34 @@ NTSTATUS MODULE_DllProcessAttach( WINE_MODREF *wm, LPVOID lpReserved )
|
||||||
*/
|
*/
|
||||||
static void MODULE_DllProcessDetach( BOOL bForceDetach, LPVOID lpReserved )
|
static void MODULE_DllProcessDetach( BOOL bForceDetach, LPVOID lpReserved )
|
||||||
{
|
{
|
||||||
WINE_MODREF *wm;
|
PLIST_ENTRY mark, entry;
|
||||||
|
PLDR_MODULE mod;
|
||||||
|
|
||||||
RtlEnterCriticalSection( &loader_section );
|
RtlEnterCriticalSection( &loader_section );
|
||||||
if (bForceDetach) process_detaching = 1;
|
if (bForceDetach) process_detaching = 1;
|
||||||
|
mark = &NtCurrentTeb()->Peb->LdrData->InInitializationOrderModuleList;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
for ( wm = MODULE_modref_list; wm; wm = wm->next )
|
for (entry = mark->Blink; entry != mark; entry = entry->Blink)
|
||||||
{
|
{
|
||||||
|
mod = CONTAINING_RECORD(entry, LDR_MODULE,
|
||||||
|
InInitializationOrderModuleList);
|
||||||
/* Check whether to detach this DLL */
|
/* Check whether to detach this DLL */
|
||||||
if ( !(wm->ldr.Flags & LDR_PROCESS_ATTACHED) )
|
if ( !(mod->Flags & LDR_PROCESS_ATTACHED) )
|
||||||
continue;
|
continue;
|
||||||
if ( wm->ldr.LoadCount && !bForceDetach )
|
if ( mod->LoadCount && !bForceDetach )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Call detach notification */
|
/* Call detach notification */
|
||||||
wm->ldr.Flags &= ~LDR_PROCESS_ATTACHED;
|
mod->Flags &= ~LDR_PROCESS_ATTACHED;
|
||||||
MODULE_InitDLL( wm, DLL_PROCESS_DETACH, lpReserved );
|
MODULE_InitDLL( CONTAINING_RECORD(mod, WINE_MODREF, ldr),
|
||||||
|
DLL_PROCESS_DETACH, lpReserved );
|
||||||
|
|
||||||
/* Restart at head of WINE_MODREF list, as entries might have
|
/* Restart at head of WINE_MODREF list, as entries might have
|
||||||
been added and/or removed while performing the call ... */
|
been added and/or removed while performing the call ... */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while ( wm );
|
} while (entry != mark);
|
||||||
|
|
||||||
RtlLeaveCriticalSection( &loader_section );
|
RtlLeaveCriticalSection( &loader_section );
|
||||||
}
|
}
|
||||||
|
@ -692,7 +720,8 @@ static void MODULE_DllProcessDetach( BOOL bForceDetach, LPVOID lpReserved )
|
||||||
*/
|
*/
|
||||||
NTSTATUS MODULE_DllThreadAttach( LPVOID lpReserved )
|
NTSTATUS MODULE_DllThreadAttach( LPVOID lpReserved )
|
||||||
{
|
{
|
||||||
WINE_MODREF *wm;
|
PLIST_ENTRY mark, entry;
|
||||||
|
PLDR_MODULE mod;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
|
|
||||||
/* don't do any attach calls if process is exiting */
|
/* don't do any attach calls if process is exiting */
|
||||||
|
@ -703,18 +732,18 @@ NTSTATUS MODULE_DllThreadAttach( LPVOID lpReserved )
|
||||||
|
|
||||||
if ((status = alloc_thread_tls()) != STATUS_SUCCESS) goto done;
|
if ((status = alloc_thread_tls()) != STATUS_SUCCESS) goto done;
|
||||||
|
|
||||||
for ( wm = MODULE_modref_list; wm; wm = wm->next )
|
mark = &NtCurrentTeb()->Peb->LdrData->InInitializationOrderModuleList;
|
||||||
if ( !wm->next )
|
for (entry = mark->Flink; entry != mark; entry = entry->Flink)
|
||||||
break;
|
|
||||||
|
|
||||||
for ( ; wm; wm = wm->prev )
|
|
||||||
{
|
{
|
||||||
if ( !(wm->ldr.Flags & LDR_PROCESS_ATTACHED) )
|
mod = CONTAINING_RECORD(entry, LDR_MODULE,
|
||||||
|
InInitializationOrderModuleList);
|
||||||
|
if ( !(mod->Flags & LDR_PROCESS_ATTACHED) )
|
||||||
continue;
|
continue;
|
||||||
if ( wm->ldr.Flags & LDR_NO_DLL_CALLS )
|
if ( mod->Flags & LDR_NO_DLL_CALLS )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
MODULE_InitDLL( wm, DLL_THREAD_ATTACH, lpReserved );
|
MODULE_InitDLL( CONTAINING_RECORD(mod, WINE_MODREF, ldr),
|
||||||
|
DLL_THREAD_ATTACH, lpReserved );
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
@ -749,18 +778,22 @@ NTSTATUS WINAPI LdrDisableThreadCalloutsForDll(HMODULE hModule)
|
||||||
*
|
*
|
||||||
* The loader_section must be locked while calling this function
|
* The loader_section must be locked while calling this function
|
||||||
*/
|
*/
|
||||||
NTSTATUS WINAPI LdrFindEntryForAddress(const void* addr, PLDR_MODULE* mod)
|
NTSTATUS WINAPI LdrFindEntryForAddress(const void* addr, PLDR_MODULE* pmod)
|
||||||
{
|
{
|
||||||
WINE_MODREF* wm;
|
PLIST_ENTRY mark, entry;
|
||||||
|
PLDR_MODULE mod;
|
||||||
|
|
||||||
for ( wm = MODULE_modref_list; wm; wm = wm->next )
|
mark = &NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList;
|
||||||
|
for (entry = mark->Flink; entry != mark; entry = entry->Flink)
|
||||||
{
|
{
|
||||||
if ((const void *)wm->ldr.BaseAddress <= addr &&
|
mod = CONTAINING_RECORD(entry, LDR_MODULE, InMemoryOrderModuleList);
|
||||||
(char *)addr < (char*)wm->ldr.BaseAddress + wm->ldr.SizeOfImage)
|
if ((const void *)mod->BaseAddress <= addr &&
|
||||||
|
(char *)addr < (char*)mod->BaseAddress + mod->SizeOfImage)
|
||||||
{
|
{
|
||||||
*mod = &wm->ldr;
|
*pmod = mod;
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
if ((const void *)mod->BaseAddress > addr) break;
|
||||||
}
|
}
|
||||||
return STATUS_NO_MORE_ENTRIES;
|
return STATUS_NO_MORE_ENTRIES;
|
||||||
}
|
}
|
||||||
|
@ -779,6 +812,8 @@ NTSTATUS WINAPI LdrFindEntryForAddress(const void* addr, PLDR_MODULE* mod)
|
||||||
WINE_MODREF *MODULE_FindModule(LPCSTR path)
|
WINE_MODREF *MODULE_FindModule(LPCSTR path)
|
||||||
{
|
{
|
||||||
WINE_MODREF *wm;
|
WINE_MODREF *wm;
|
||||||
|
PLIST_ENTRY mark, entry;
|
||||||
|
PLDR_MODULE mod;
|
||||||
char dllname[260], *p;
|
char dllname[260], *p;
|
||||||
|
|
||||||
/* Append .DLL to name if no extension present */
|
/* Append .DLL to name if no extension present */
|
||||||
|
@ -794,13 +829,19 @@ WINE_MODREF *MODULE_FindModule(LPCSTR path)
|
||||||
if ( !FILE_strcasecmp( dllname, wm->short_filename ) ) return wm;
|
if ( !FILE_strcasecmp( dllname, wm->short_filename ) ) return wm;
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( wm = MODULE_modref_list; wm; wm = wm->next )
|
mark = &NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList;
|
||||||
|
for (entry = mark->Flink; entry != mark; entry = entry->Flink)
|
||||||
{
|
{
|
||||||
|
mod = CONTAINING_RECORD(entry, LDR_MODULE, InLoadOrderModuleList);
|
||||||
|
wm = CONTAINING_RECORD(mod, WINE_MODREF, ldr);
|
||||||
|
|
||||||
if ( !FILE_strcasecmp( dllname, wm->modname ) ) break;
|
if ( !FILE_strcasecmp( dllname, wm->modname ) ) break;
|
||||||
if ( !FILE_strcasecmp( dllname, wm->filename ) ) break;
|
if ( !FILE_strcasecmp( dllname, wm->filename ) ) break;
|
||||||
if ( !FILE_strcasecmp( dllname, wm->short_modname ) ) break;
|
if ( !FILE_strcasecmp( dllname, wm->short_modname ) ) break;
|
||||||
if ( !FILE_strcasecmp( dllname, wm->short_filename ) ) break;
|
if ( !FILE_strcasecmp( dllname, wm->short_filename ) ) break;
|
||||||
}
|
}
|
||||||
|
if (entry == mark) wm = NULL;
|
||||||
|
|
||||||
cached_modref = wm;
|
cached_modref = wm;
|
||||||
return wm;
|
return wm;
|
||||||
}
|
}
|
||||||
|
@ -1155,28 +1196,31 @@ NTSTATUS WINAPI LdrQueryProcessModuleInformation(PSYSTEM_MODULE_INFORMATION smi,
|
||||||
NTSTATUS nts = STATUS_SUCCESS;
|
NTSTATUS nts = STATUS_SUCCESS;
|
||||||
ANSI_STRING str;
|
ANSI_STRING str;
|
||||||
char* ptr;
|
char* ptr;
|
||||||
WINE_MODREF* wm;
|
PLIST_ENTRY mark, entry;
|
||||||
|
PLDR_MODULE mod;
|
||||||
|
|
||||||
smi->ModulesCount = 0;
|
smi->ModulesCount = 0;
|
||||||
|
|
||||||
RtlEnterCriticalSection( &loader_section );
|
RtlEnterCriticalSection( &loader_section );
|
||||||
for ( wm = MODULE_modref_list; wm; wm = wm->next )
|
mark = &NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList;
|
||||||
|
for (entry = mark->Flink; entry != mark; entry = entry->Flink)
|
||||||
{
|
{
|
||||||
|
mod = CONTAINING_RECORD(entry, LDR_MODULE, InLoadOrderModuleList);
|
||||||
size += sizeof(*sm);
|
size += sizeof(*sm);
|
||||||
if (size <= buf_size)
|
if (size <= buf_size)
|
||||||
{
|
{
|
||||||
sm->Reserved1 = 0; /* FIXME */
|
sm->Reserved1 = 0; /* FIXME */
|
||||||
sm->Reserved2 = 0; /* FIXME */
|
sm->Reserved2 = 0; /* FIXME */
|
||||||
sm->ImageBaseAddress = wm->ldr.BaseAddress;
|
sm->ImageBaseAddress = mod->BaseAddress;
|
||||||
sm->ImageSize = wm->ldr.SizeOfImage;
|
sm->ImageSize = mod->SizeOfImage;
|
||||||
sm->Flags = wm->ldr.Flags;
|
sm->Flags = mod->Flags;
|
||||||
sm->Id = 0; /* FIXME */
|
sm->Id = 0; /* FIXME */
|
||||||
sm->Rank = 0; /* FIXME */
|
sm->Rank = 0; /* FIXME */
|
||||||
sm->Unknown = 0; /* FIXME */
|
sm->Unknown = 0; /* FIXME */
|
||||||
str.Length = 0;
|
str.Length = 0;
|
||||||
str.MaximumLength = MAXIMUM_FILENAME_LENGTH;
|
str.MaximumLength = MAXIMUM_FILENAME_LENGTH;
|
||||||
str.Buffer = sm->Name;
|
str.Buffer = sm->Name;
|
||||||
RtlUnicodeStringToAnsiString(&str, &wm->ldr.FullDllName, FALSE);
|
RtlUnicodeStringToAnsiString(&str, &mod->FullDllName, FALSE);
|
||||||
ptr = strrchr(sm->Name, '\\');
|
ptr = strrchr(sm->Name, '\\');
|
||||||
sm->NameOffset = (ptr != NULL) ? (ptr - (char*)sm->Name + 1) : 0;
|
sm->NameOffset = (ptr != NULL) ? (ptr - (char*)sm->Name + 1) : 0;
|
||||||
|
|
||||||
|
@ -1208,7 +1252,9 @@ void WINAPI LdrShutdownProcess(void)
|
||||||
*/
|
*/
|
||||||
void WINAPI LdrShutdownThread(void)
|
void WINAPI LdrShutdownThread(void)
|
||||||
{
|
{
|
||||||
WINE_MODREF *wm;
|
PLIST_ENTRY mark, entry;
|
||||||
|
PLDR_MODULE mod;
|
||||||
|
|
||||||
TRACE("()\n");
|
TRACE("()\n");
|
||||||
|
|
||||||
/* don't do any detach calls if process is exiting */
|
/* don't do any detach calls if process is exiting */
|
||||||
|
@ -1217,14 +1263,18 @@ void WINAPI LdrShutdownThread(void)
|
||||||
|
|
||||||
RtlEnterCriticalSection( &loader_section );
|
RtlEnterCriticalSection( &loader_section );
|
||||||
|
|
||||||
for ( wm = MODULE_modref_list; wm; wm = wm->next )
|
mark = &NtCurrentTeb()->Peb->LdrData->InInitializationOrderModuleList;
|
||||||
|
for (entry = mark->Blink; entry != mark; entry = entry->Blink)
|
||||||
{
|
{
|
||||||
if ( !(wm->ldr.Flags & LDR_PROCESS_ATTACHED) )
|
mod = CONTAINING_RECORD(entry, LDR_MODULE,
|
||||||
|
InInitializationOrderModuleList);
|
||||||
|
if ( !(mod->Flags & LDR_PROCESS_ATTACHED) )
|
||||||
continue;
|
continue;
|
||||||
if ( wm->ldr.Flags & LDR_NO_DLL_CALLS )
|
if ( mod->Flags & LDR_NO_DLL_CALLS )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
MODULE_InitDLL( wm, DLL_THREAD_DETACH, NULL );
|
MODULE_InitDLL( CONTAINING_RECORD(mod, WINE_MODREF, ldr),
|
||||||
|
DLL_THREAD_DETACH, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlLeaveCriticalSection( &loader_section );
|
RtlLeaveCriticalSection( &loader_section );
|
||||||
|
@ -1240,22 +1290,23 @@ void WINAPI LdrShutdownThread(void)
|
||||||
*/
|
*/
|
||||||
static void MODULE_FlushModrefs(void)
|
static void MODULE_FlushModrefs(void)
|
||||||
{
|
{
|
||||||
WINE_MODREF *wm, *next;
|
PLIST_ENTRY mark, entry, prev;
|
||||||
|
PLDR_MODULE mod;
|
||||||
|
WINE_MODREF*wm;
|
||||||
|
|
||||||
for (wm = MODULE_modref_list; wm; wm = next)
|
mark = &NtCurrentTeb()->Peb->LdrData->InInitializationOrderModuleList;
|
||||||
|
for (entry = mark->Blink; entry != mark; entry = prev)
|
||||||
{
|
{
|
||||||
next = wm->next;
|
mod = CONTAINING_RECORD(entry, LDR_MODULE,
|
||||||
|
InInitializationOrderModuleList);
|
||||||
|
wm = CONTAINING_RECORD(mod, WINE_MODREF, ldr);
|
||||||
|
|
||||||
if (wm->ldr.LoadCount)
|
prev = entry->Blink;
|
||||||
continue;
|
if (wm->ldr.LoadCount) continue;
|
||||||
|
|
||||||
/* Unlink this modref from the chain */
|
RemoveEntryList(&wm->ldr.InLoadOrderModuleList);
|
||||||
if (wm->next)
|
RemoveEntryList(&wm->ldr.InMemoryOrderModuleList);
|
||||||
wm->next->prev = wm->prev;
|
RemoveEntryList(&wm->ldr.InInitializationOrderModuleList);
|
||||||
if (wm->prev)
|
|
||||||
wm->prev->next = wm->next;
|
|
||||||
if (wm == MODULE_modref_list)
|
|
||||||
MODULE_modref_list = wm->next;
|
|
||||||
|
|
||||||
TRACE(" unloading %s\n", wm->filename);
|
TRACE(" unloading %s\n", wm->filename);
|
||||||
if (!TRACE_ON(module))
|
if (!TRACE_ON(module))
|
||||||
|
|
|
@ -128,8 +128,6 @@ typedef struct
|
||||||
/* internal representation of 32bit modules. per process. */
|
/* internal representation of 32bit modules. per process. */
|
||||||
typedef struct _wine_modref
|
typedef struct _wine_modref
|
||||||
{
|
{
|
||||||
struct _wine_modref *next;
|
|
||||||
struct _wine_modref *prev;
|
|
||||||
void *dlhandle; /* handle returned by dlopen() */
|
void *dlhandle; /* handle returned by dlopen() */
|
||||||
LDR_MODULE ldr;
|
LDR_MODULE ldr;
|
||||||
|
|
||||||
|
@ -144,8 +142,6 @@ typedef struct _wine_modref
|
||||||
char data[1]; /* space for storing filename and short_filename */
|
char data[1]; /* space for storing filename and short_filename */
|
||||||
} WINE_MODREF;
|
} WINE_MODREF;
|
||||||
|
|
||||||
extern WINE_MODREF *MODULE_modref_list;
|
|
||||||
|
|
||||||
/* Resource types */
|
/* Resource types */
|
||||||
|
|
||||||
#define NE_SEG_TABLE(pModule) \
|
#define NE_SEG_TABLE(pModule) \
|
||||||
|
|
|
@ -133,6 +133,16 @@ typedef struct _RTL_USER_PROCESS_PARAMETERS
|
||||||
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
|
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _PEB_LDR_DATA
|
||||||
|
{
|
||||||
|
ULONG Length;
|
||||||
|
BOOLEAN Initialized;
|
||||||
|
PVOID SsHandle;
|
||||||
|
LIST_ENTRY InLoadOrderModuleList;
|
||||||
|
LIST_ENTRY InMemoryOrderModuleList;
|
||||||
|
LIST_ENTRY InInitializationOrderModuleList;
|
||||||
|
} PEB_LDR_DATA, *PPEB_LDR_DATA;
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* PEB data structure
|
* PEB data structure
|
||||||
*/
|
*/
|
||||||
|
@ -142,7 +152,7 @@ typedef struct _PEB
|
||||||
BYTE BeingDebugged; /* 02 */
|
BYTE BeingDebugged; /* 02 */
|
||||||
BYTE Reserved2[5]; /* 03 */
|
BYTE Reserved2[5]; /* 03 */
|
||||||
HMODULE ImageBaseAddress; /* 08 */
|
HMODULE ImageBaseAddress; /* 08 */
|
||||||
PVOID __pad_0c; /* 0c */
|
PPEB_LDR_DATA LdrData; /* 0c */
|
||||||
RTL_USER_PROCESS_PARAMETERS *ProcessParameters; /* 10 */
|
RTL_USER_PROCESS_PARAMETERS *ProcessParameters; /* 10 */
|
||||||
PVOID __pad_14; /* 14 */
|
PVOID __pad_14; /* 14 */
|
||||||
HANDLE ProcessHeap; /* 18 */
|
HANDLE ProcessHeap; /* 18 */
|
||||||
|
@ -1367,6 +1377,39 @@ NTSTATUS WINAPI LdrQueryProcessModuleInformation(SYSTEM_MODULE_INFORMATION*, ULO
|
||||||
NTSTATUS WINAPI LdrUnloadDll(HMODULE);
|
NTSTATUS WINAPI LdrUnloadDll(HMODULE);
|
||||||
NTSTATUS WINAPI LdrUnlockLoaderLock(ULONG,ULONG);
|
NTSTATUS WINAPI LdrUnlockLoaderLock(ULONG,ULONG);
|
||||||
|
|
||||||
|
/* list manipulation macros */
|
||||||
|
#define InitializeListHead(le) (void)((le)->Flink = (le)->Blink = (le))
|
||||||
|
#define InsertHeadList(le,e) do { PLIST_ENTRY f = (le)->Flink; (e)->Flink = f; (e)->Blink = (le); f->Blink = (e); (le)->Flink = (e); } while (0)
|
||||||
|
#define InsertTailList(le,e) do { PLIST_ENTRY b = (le)->Blink; (e)->Flink = (le); (e)->Blink = b; b->Flink = (e); (le)->Blink = (e); } while (0)
|
||||||
|
#define IsListEmpty(le) ((le)->Flink == (le))
|
||||||
|
#define RemoveEntryList(e) do { PLIST_ENTRY f = (e)->Flink, b = (e)->Blink; f->Blink = b; b->Flink = f; (e)->Flink = (e)->Blink = NULL; } while (0)
|
||||||
|
static inline PLIST_ENTRY RemoveHeadList(PLIST_ENTRY le)
|
||||||
|
{
|
||||||
|
PLIST_ENTRY f, b, e;
|
||||||
|
|
||||||
|
e = le->Flink;
|
||||||
|
f = le->Flink->Flink;
|
||||||
|
b = le->Flink->Blink;
|
||||||
|
f->Blink = b;
|
||||||
|
b->Flink = f;
|
||||||
|
|
||||||
|
if (e != le) e->Flink = e->Blink = NULL;
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
static inline PLIST_ENTRY RemoveTailList(PLIST_ENTRY le)
|
||||||
|
{
|
||||||
|
PLIST_ENTRY f, b, e;
|
||||||
|
|
||||||
|
e = le->Blink;
|
||||||
|
f = le->Blink->Flink;
|
||||||
|
b = le->Blink->Blink;
|
||||||
|
f->Blink = b;
|
||||||
|
b->Flink = f;
|
||||||
|
|
||||||
|
if (e != le) e->Flink = e->Blink = NULL;
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif /* defined(__cplusplus) */
|
#endif /* defined(__cplusplus) */
|
||||||
|
|
|
@ -265,15 +265,9 @@ WINE_MODREF *PE_CreateModule( HMODULE hModule, LPCSTR filename, DWORD flags,
|
||||||
if (!(wm->ldr.Flags & LDR_DONT_RESOLVE_REFS) &&
|
if (!(wm->ldr.Flags & LDR_DONT_RESOLVE_REFS) &&
|
||||||
PE_fixup_imports( wm ))
|
PE_fixup_imports( wm ))
|
||||||
{
|
{
|
||||||
/* remove entry from modref chain */
|
/* the module has only be inserted in the load & memory order lists */
|
||||||
|
RemoveEntryList(&wm->ldr.InLoadOrderModuleList);
|
||||||
if ( !wm->prev )
|
RemoveEntryList(&wm->ldr.InMemoryOrderModuleList);
|
||||||
MODULE_modref_list = wm->next;
|
|
||||||
else
|
|
||||||
wm->prev->next = wm->next;
|
|
||||||
|
|
||||||
if ( wm->next ) wm->next->prev = wm->prev;
|
|
||||||
wm->next = wm->prev = NULL;
|
|
||||||
|
|
||||||
/* FIXME: there are several more dangling references
|
/* FIXME: there are several more dangling references
|
||||||
* left. Including dlls loaded by this dll before the
|
* left. Including dlls loaded by this dll before the
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
|
|
||||||
#include "winternl.h"
|
#include "winternl.h"
|
||||||
#include "stackframe.h"
|
#include "stackframe.h"
|
||||||
#include "module.h"
|
|
||||||
#include "wine/unicode.h"
|
#include "wine/unicode.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
#include "ntdll_misc.h"
|
#include "ntdll_misc.h"
|
||||||
|
@ -284,15 +283,18 @@ static void get_entry_point( char *buffer, DEBUG_ENTRY_POINT *relay )
|
||||||
char *p, *base = NULL;
|
char *p, *base = NULL;
|
||||||
const char *name;
|
const char *name;
|
||||||
int ordinal = 0;
|
int ordinal = 0;
|
||||||
WINE_MODREF *wm;
|
PLIST_ENTRY mark, entry;
|
||||||
|
PLDR_MODULE mod = NULL;
|
||||||
DWORD size;
|
DWORD size;
|
||||||
|
|
||||||
/* First find the module */
|
/* First find the module */
|
||||||
|
|
||||||
for (wm = MODULE_modref_list; wm; wm = wm->next)
|
mark = &NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList;
|
||||||
|
for (entry = mark->Flink; entry != mark; entry = entry->Flink)
|
||||||
{
|
{
|
||||||
if (!(wm->ldr.Flags & LDR_WINE_INTERNAL)) continue;
|
mod = CONTAINING_RECORD(entry, LDR_MODULE, InLoadOrderModuleList);
|
||||||
exp = RtlImageDirectoryEntryToData( wm->ldr.BaseAddress, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &size );
|
if (!(mod->Flags & LDR_WINE_INTERNAL)) continue;
|
||||||
|
exp = RtlImageDirectoryEntryToData( mod->BaseAddress, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &size );
|
||||||
if (!exp) continue;
|
if (!exp) continue;
|
||||||
debug = (DEBUG_ENTRY_POINT *)((char *)exp + size);
|
debug = (DEBUG_ENTRY_POINT *)((char *)exp + size);
|
||||||
if (debug <= relay && relay < debug + exp->NumberOfFunctions)
|
if (debug <= relay && relay < debug + exp->NumberOfFunctions)
|
||||||
|
@ -304,7 +306,7 @@ static void get_entry_point( char *buffer, DEBUG_ENTRY_POINT *relay )
|
||||||
|
|
||||||
/* Now find the function */
|
/* Now find the function */
|
||||||
|
|
||||||
base = (char *)wm->ldr.BaseAddress;
|
base = (char *)mod->BaseAddress;
|
||||||
strcpy( buffer, base + exp->Name );
|
strcpy( buffer, base + exp->Name );
|
||||||
p = buffer + strlen(buffer);
|
p = buffer + strlen(buffer);
|
||||||
if (p > buffer + 4 && !strcasecmp( p - 4, ".dll" )) p -= 4;
|
if (p > buffer + 4 && !strcasecmp( p - 4, ".dll" )) p -= 4;
|
||||||
|
|
|
@ -60,7 +60,7 @@ typedef struct _PDB
|
||||||
{
|
{
|
||||||
LONG header[2]; /* 00 Kernel object header */
|
LONG header[2]; /* 00 Kernel object header */
|
||||||
HMODULE module; /* 08 Main exe module (NT) */
|
HMODULE module; /* 08 Main exe module (NT) */
|
||||||
void *event; /* 0c Pointer to an event object (unused) */
|
PPEB_LDR_DATA LdrData; /* 0c Pointer to loader information */
|
||||||
RTL_USER_PROCESS_PARAMETERS *ProcessParameters; /* 10 Process parameters */
|
RTL_USER_PROCESS_PARAMETERS *ProcessParameters; /* 10 Process parameters */
|
||||||
DWORD unknown2; /* 14 Unknown */
|
DWORD unknown2; /* 14 Unknown */
|
||||||
HANDLE heap; /* 18 Default process heap */
|
HANDLE heap; /* 18 Default process heap */
|
||||||
|
@ -108,6 +108,7 @@ typedef struct _PDB
|
||||||
PDB current_process;
|
PDB current_process;
|
||||||
|
|
||||||
static RTL_USER_PROCESS_PARAMETERS process_pmts;
|
static RTL_USER_PROCESS_PARAMETERS process_pmts;
|
||||||
|
static PEB_LDR_DATA process_ldr;
|
||||||
|
|
||||||
static char main_exe_name[MAX_PATH];
|
static char main_exe_name[MAX_PATH];
|
||||||
static char *main_exe_name_ptr = main_exe_name;
|
static char *main_exe_name_ptr = main_exe_name;
|
||||||
|
@ -296,6 +297,10 @@ static BOOL process_init( char *argv[] )
|
||||||
current_process.group = ¤t_process;
|
current_process.group = ¤t_process;
|
||||||
current_process.priority = 8; /* Normal */
|
current_process.priority = 8; /* Normal */
|
||||||
current_process.ProcessParameters = &process_pmts;
|
current_process.ProcessParameters = &process_pmts;
|
||||||
|
current_process.LdrData = &process_ldr;
|
||||||
|
InitializeListHead(&process_ldr.InLoadOrderModuleList);
|
||||||
|
InitializeListHead(&process_ldr.InMemoryOrderModuleList);
|
||||||
|
InitializeListHead(&process_ldr.InInitializationOrderModuleList);
|
||||||
|
|
||||||
/* Setup the server connection */
|
/* Setup the server connection */
|
||||||
CLIENT_InitServer();
|
CLIENT_InitServer();
|
||||||
|
|
Loading…
Reference in New Issue