Really start splitting ntdll and kernel 32 Start with : - infrastructure for Ldr* functions in ntdll - easy Ldr* functions A+ -- Eric Pouech
Name: ntkrnl_1 ChangeLog: - 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) License: X11 GenDate: 2003/03/02 20:05:03 UTC ModifiedFiles: dlls/ntdll/loader.c dlls/ntdll/ntdll.spec include/module.h include/winternl.h loader/module.c scheduler/process.c scheduler/thread.c AddedFiles: =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/dlls/ntdll/loader.c,v retrieving revision 1.8 diff -u -u -r1.8 loader.c --- dlls/ntdll/loader.c 12 Dec 2002 23:34:02 -0000 1.8 +++ dlls/ntdll/loader.c 2 Mar 2003 20:04:56 -0000 @@ -36,17 +36,31 @@ } -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,18 +80,58 @@ /* 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.@) Index: dlls/ntdll/ntdll.spec =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/dlls/ntdll/ntdll.spec,v retrieving revision 1.88 diff -u -u -r1.88 ntdll.spec --- dlls/ntdll/ntdll.spec 19 Feb 2003 03:39:46 -0000 1.88 +++ dlls/ntdll/ntdll.spec 2 Mar 2003 09:10:40 -0000 @@ -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 Index: include/module.h =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/include/module.h,v retrieving revision 1.69 diff -u -u -r1.69 module.h --- include/module.h 16 Aug 2002 20:02:54 -0000 1.69 +++ include/module.h 2 Mar 2003 19:49:25 -0000 @@ -199,7 +199,6 @@ 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 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 ); Index: include/winternl.h =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/include/winternl.h,v retrieving revision 1.12 diff -u -u -r1.12 winternl.h --- include/winternl.h 19 Feb 2003 03:44:08 -0000 1.12 +++ include/winternl.h 2 Mar 2003 08:44:58 -0000 @@ -1130,6 +1130,73 @@ 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) */ Index: loader/module.c =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/loader/module.c,v retrieving revision 1.171 diff -u -u -r1.171 module.c --- loader/module.c 28 Feb 2003 21:52:08 -0000 1.171 +++ loader/module.c 2 Mar 2003 19:49:39 -0000 @@ -49,9 +49,9 @@ 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 @@ * 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 @@ /************************************************************************* * 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 @@ */ BOOL WINAPI DisableThreadLibraryCalls( HMODULE hModule ) { - WINE_MODREF *wm; - BOOL retval = TRUE; - - RtlEnterCriticalSection( &loader_section ); - - wm = MODULE32_LookupHMODULE( hModule ); - if ( !wm ) - retval = FALSE; - else - wm->flags |= WINE_MODREF_NO_DLL_CALLS; - - RtlLeaveCriticalSection( &loader_section ); + NTSTATUS nts = LdrDisableThreadCalloutsForDll( hModule ); + if (nts == STATUS_SUCCESS) return TRUE; - return retval; + SetLastError( RtlNtStatusToDosError( nts ) ); + return FALSE; } Index: scheduler/process.c =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/scheduler/process.c,v retrieving revision 1.208 diff -u -u -r1.208 process.c --- scheduler/process.c 26 Feb 2003 04:36:54 -0000 1.208 +++ scheduler/process.c 2 Mar 2003 08:49:23 -0000 @@ -1425,7 +1425,7 @@ */ void WINAPI ExitProcess( DWORD status ) { - MODULE_DllProcessDetach( TRUE, (LPVOID)1 ); + LdrShutdownProcess(); SERVER_START_REQ( terminate_process ) { /* send the exit code to the server */ Index: scheduler/thread.c =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/scheduler/thread.c,v retrieving revision 1.131 diff -u -u -r1.131 thread.c --- scheduler/thread.c 27 Feb 2003 01:57:16 -0000 1.131 +++ scheduler/thread.c 2 Mar 2003 09:03:50 -0000 @@ -351,12 +351,12 @@ 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 ); }