From 7d6096480adfea2550bc55bd441774fe2ea0386f Mon Sep 17 00:00:00 2001 From: Eric Pouech Date: Tue, 4 Mar 2003 04:36:56 +0000 Subject: [PATCH] - added Ldr* information to include/winternl.h - exported a few functions/global vars from module.h while we move code from loader/module.c to dlls/ntdll/loader.c - implemented LdrShutdownProcess, LdrShutdownThread and LdrDisableThreadCalloutsForDll (and made use of them) --- dlls/ntdll/loader.c | 72 +++++++++++++++++++++++++++++++++++++------ dlls/ntdll/ntdll.spec | 4 +-- include/module.h | 8 ++++- include/winternl.h | 67 ++++++++++++++++++++++++++++++++++++++++ loader/module.c | 25 +++++---------- scheduler/process.c | 2 +- scheduler/thread.c | 4 +-- 7 files changed, 150 insertions(+), 32 deletions(-) diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index 26cfcce59c0..c1bcfc35580 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -36,17 +36,31 @@ static WINE_EXCEPTION_FILTER(page_fault) } -NTSTATUS WINAPI LdrDisableThreadCalloutsForDll(HANDLE hModule) +/****************************************************************** + * LdrDisableThreadCalloutsForDll (NTDLL.@) + * + */ +NTSTATUS WINAPI LdrDisableThreadCalloutsForDll(HMODULE hModule) { - if (DisableThreadLibraryCalls(hModule)) - return STATUS_SUCCESS; + WINE_MODREF *wm; + NTSTATUS ret = STATUS_SUCCESS; + + RtlEnterCriticalSection( &loader_section ); + + wm = MODULE32_LookupHMODULE( hModule ); + if ( !wm ) + ret = STATUS_DLL_NOT_FOUND; else - return STATUS_DLL_NOT_FOUND; + wm->flags |= WINE_MODREF_NO_DLL_CALLS; + + RtlLeaveCriticalSection( &loader_section ); + + return ret; } /* FIXME : MODULE_FindModule should depend on LdrGetDllHandle, not vice-versa */ -NTSTATUS WINAPI LdrGetDllHandle(ULONG x, LONG y, PUNICODE_STRING name, PVOID *base) +NTSTATUS WINAPI LdrGetDllHandle(ULONG x, ULONG y, PUNICODE_STRING name, HMODULE *base) { STRING str; WINE_MODREF *wm; @@ -66,19 +80,59 @@ NTSTATUS WINAPI LdrGetDllHandle(ULONG x, LONG y, PUNICODE_STRING name, PVOID *ba /* FIXME : MODULE_GetProcAddress should depend on LdrGetProcedureAddress, not vice-versa */ -NTSTATUS WINAPI LdrGetProcedureAddress(PVOID base, PANSI_STRING name, ULONG ord, PVOID *address) +NTSTATUS WINAPI LdrGetProcedureAddress(HMODULE base, PANSI_STRING name, ULONG ord, PVOID *address) { - WARN("%p %s %ld %p\n",base, debugstr_an(name->Buffer,name->Length), ord, address); + WARN("%p %s %ld %p\n", base, debugstr_an(name->Buffer,name->Length), ord, address); if(name) - *address = MODULE_GetProcAddress( (HMODULE) base, name->Buffer, -1, FALSE); + *address = MODULE_GetProcAddress( base, name->Buffer, -1, FALSE); else - *address = MODULE_GetProcAddress( (HMODULE) base, (LPSTR) ord, -1, FALSE); + *address = MODULE_GetProcAddress( base, (LPSTR) ord, -1, FALSE); return (*address) ? STATUS_SUCCESS : STATUS_DLL_NOT_FOUND; } +/****************************************************************** + * LdrShutdownProcess (NTDLL.@) + * + */ +NTSTATUS WINAPI LdrShutdownProcess(void) +{ + TRACE("()\n"); + MODULE_DllProcessDetach( TRUE, (LPVOID)1 ); + return STATUS_SUCCESS; /* FIXME */ +} + +/****************************************************************** + * LdrShutdownThread (NTDLL.@) + * + */ +NTSTATUS WINAPI LdrShutdownThread(void) +{ + WINE_MODREF *wm; + TRACE("()\n"); + + /* don't do any detach calls if process is exiting */ + if (process_detaching) return STATUS_SUCCESS; + /* FIXME: there is still a race here */ + + RtlEnterCriticalSection( &loader_section ); + + for ( wm = MODULE_modref_list; wm; wm = wm->next ) + { + if ( !(wm->flags & WINE_MODREF_PROCESS_ATTACHED) ) + continue; + if ( wm->flags & WINE_MODREF_NO_DLL_CALLS ) + continue; + + MODULE_InitDLL( wm, DLL_THREAD_DETACH, NULL ); + } + + RtlLeaveCriticalSection( &loader_section ); + return STATUS_SUCCESS; /* FIXME */ +} + /*********************************************************************** * RtlImageNtHeader (NTDLL.@) */ diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 9a4e2afd0c5..e11dab90eaf 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -46,8 +46,8 @@ @ stub LdrProcessRelocationBlock @ stub LdrQueryImageFileExecutionOptions @ stub LdrQueryProcessModuleInformation -@ stub LdrShutdownProcess -@ stub LdrShutdownThread +@ stdcall LdrShutdownProcess() LdrShutdownProcess +@ stdcall LdrShutdownThread() LdrShutdownThread @ stub LdrUnloadDll @ stub LdrVerifyImageMatchesChecksum @ stub NPXEMULATORTABLE diff --git a/include/module.h b/include/module.h index 3ba8b1a5538..4db3cc56182 100644 --- a/include/module.h +++ b/include/module.h @@ -199,7 +199,6 @@ extern FARPROC MODULE_GetProcAddress( HMODULE hModule, LPCSTR function, int hint extern BOOL MODULE_DllProcessAttach( WINE_MODREF *wm, LPVOID lpReserved ); extern void MODULE_DllProcessDetach( BOOL bForceDetach, LPVOID lpReserved ); extern void MODULE_DllThreadAttach( LPVOID lpReserved ); -extern void MODULE_DllThreadDetach( LPVOID lpReserved ); extern WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HANDLE hfile, DWORD flags ); extern BOOL MODULE_FreeLibrary( WINE_MODREF *wm ); extern WINE_MODREF *MODULE_FindModule( LPCSTR path ); @@ -208,6 +207,13 @@ extern enum binary_type MODULE_GetBinaryType( HANDLE hfile ); extern FARPROC16 WINAPI WIN32_GetProcAddress16( HMODULE hmodule, LPCSTR name ); extern SEGPTR WINAPI HasGPHandler16( SEGPTR address ); extern void MODULE_WalkModref( DWORD id ); +/* the following parts of module.c are temporary exported during move of code + * from loader/module.c to dlls/ntdll/loader.c + */ +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 --git a/include/winternl.h b/include/winternl.h index 6070cebe956..e6a5e57ede0 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -1130,6 +1130,73 @@ inline static BOOLEAN RtlCheckBit(PCRTL_BITMAP lpBits, ULONG ulBit) memset(_p->BitMapBuffer,0xff,((_p->SizeOfBitMap + 31) & 0xffffffe0) >> 3); \ } while (0) +/************************************************************************* + * Loader functions and structures. + * + * Those are not part of standard Winternl.h + */ +typedef struct _LDR_MODULE +{ + LIST_ENTRY InLoadOrderModuleList; + LIST_ENTRY InMemoryOrderModuleList; + LIST_ENTRY InInitializationOrderModuleList; + void* BaseAddress; + ULONG EntryPoint; + ULONG SizeOfImage; + UNICODE_STRING FullDllName; + UNICODE_STRING BaseDllName; + ULONG Flags; + SHORT LoadCount; + SHORT TlsIndex; + HANDLE SectionHandle; + ULONG CheckSum; + ULONG TimeDateStamp; +} LDR_MODULE, *PLDR_MODULE; + +/* FIXME: to be checked */ +#define MAXIMUM_FILENAME_LENGTH 256 + +typedef struct _SYSTEM_MODULE +{ + ULONG Reserved1; + ULONG Reserved2; + PVOID ImageBaseAddress; + ULONG ImageSize; + ULONG Flags; + WORD Id; + WORD Rank; + WORD Unknown; + WORD NameOffset; + BYTE Name[MAXIMUM_FILENAME_LENGTH]; +} SYSTEM_MODULE, *PSYSTEM_MODULE; + +typedef struct _SYSTEM_MODULE_INFORMATION +{ + ULONG ModulesCount; + SYSTEM_MODULE Modules[1]; /* FIXME: should be Modules[0] */ +} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION; + +typedef struct _LDR_RESOURCE_INFO +{ + ULONG Type; + ULONG Name; + ULONG Language; +} LDR_RESOURCE_INFO, *PLDR_RESOURCE_INFO; + +NTSTATUS WINAPI LdrDisableThreadCalloutsForDll(HMODULE); +NTSTATUS WINAPI LdrFindEntryForAddress(void*, PLDR_MODULE*); +NTSTATUS WINAPI LdrGetDllHandle(ULONG, ULONG, PUNICODE_STRING, HMODULE*); +NTSTATUS WINAPI LdrGetProcedureAddress(HMODULE, PANSI_STRING, ULONG, void**); +NTSTATUS WINAPI LdrLoadDll(LPCSTR, DWORD, PUNICODE_STRING, HMODULE*); +NTSTATUS WINAPI LdrShutdownThread(void); +NTSTATUS WINAPI LdrShutdownProcess(void); +NTSTATUS WINAPI LdrUnloadDll(HMODULE); +NTSTATUS WINAPI LdrAccessResource(HMODULE, PIMAGE_RESOURCE_DATA_ENTRY, void**, PULONG); +NTSTATUS WINAPI LdrFindResourceDirectory_U(HMODULE, PLDR_RESOURCE_INFO, DWORD, + PIMAGE_RESOURCE_DIRECTORY_ENTRY*); +NTSTATUS WINAPI LdrFindResource_U(HMODULE, PLDR_RESOURCE_INFO, ULONG, + PIMAGE_RESOURCE_DATA_ENTRY*); + #ifdef __cplusplus } /* extern "C" */ #endif /* defined(__cplusplus) */ diff --git a/loader/module.c b/loader/module.c index 771b098cba3..ecab5fef981 100644 --- a/loader/module.c +++ b/loader/module.c @@ -49,9 +49,9 @@ WINE_MODREF *MODULE_modref_list = NULL; static WINE_MODREF *exe_modref; static int free_lib_count; /* recursion depth of FreeLibrary calls */ -static int process_detaching; /* set on process detach to avoid deadlocks with thread detach */ +int process_detaching = 0; /* set on process detach to avoid deadlocks with thread detach */ -static CRITICAL_SECTION loader_section = CRITICAL_SECTION_INIT( "loader_section" ); +CRITICAL_SECTION loader_section = CRITICAL_SECTION_INIT( "loader_section" ); /*********************************************************************** * wait_input_idle @@ -77,7 +77,7 @@ static DWORD wait_input_idle( HANDLE process, DWORD timeout ) * 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 *MODULE32_LookupHMODULE( HMODULE hmod ) { WINE_MODREF *wm; @@ -141,7 +141,7 @@ WINE_MODREF *MODULE_AllocModRef( HMODULE hModule, LPCSTR filename ) /************************************************************************* * MODULE_InitDLL */ -static BOOL MODULE_InitDLL( WINE_MODREF *wm, DWORD type, LPVOID lpReserved ) +BOOL MODULE_InitDLL( WINE_MODREF *wm, DWORD type, LPVOID lpReserved ) { BOOL retv = TRUE; @@ -362,20 +362,11 @@ void MODULE_DllThreadDetach( LPVOID lpReserved ) */ BOOL WINAPI DisableThreadLibraryCalls( HMODULE hModule ) { - WINE_MODREF *wm; - BOOL retval = TRUE; + NTSTATUS nts = LdrDisableThreadCalloutsForDll( hModule ); + if (nts == STATUS_SUCCESS) return TRUE; - RtlEnterCriticalSection( &loader_section ); - - wm = MODULE32_LookupHMODULE( hModule ); - if ( !wm ) - retval = FALSE; - else - wm->flags |= WINE_MODREF_NO_DLL_CALLS; - - RtlLeaveCriticalSection( &loader_section ); - - return retval; + SetLastError( RtlNtStatusToDosError( nts ) ); + return FALSE; } diff --git a/scheduler/process.c b/scheduler/process.c index 831ea6bd28e..2d1eb95e523 100644 --- a/scheduler/process.c +++ b/scheduler/process.c @@ -1425,7 +1425,7 @@ BOOL WINAPI CreateProcessW( LPCWSTR app_name, LPWSTR cmd_line, LPSECURITY_ATTRIB */ void WINAPI ExitProcess( DWORD status ) { - MODULE_DllProcessDetach( TRUE, (LPVOID)1 ); + LdrShutdownProcess(); SERVER_START_REQ( terminate_process ) { /* send the exit code to the server */ diff --git a/scheduler/thread.c b/scheduler/thread.c index 5b6160a5d53..192f8915c86 100644 --- a/scheduler/thread.c +++ b/scheduler/thread.c @@ -351,12 +351,12 @@ void WINAPI ExitThread( DWORD code ) /* [in] Exit code for this thread */ if (last) { - MODULE_DllProcessDetach( TRUE, (LPVOID)1 ); + LdrShutdownProcess(); exit( code ); } else { - MODULE_DllThreadDetach( NULL ); + LdrShutdownThread(); if (!(NtCurrentTeb()->tibflags & TEBF_WIN32)) TASK_ExitTask(); SYSDEPS_ExitThread( code ); }