- 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)
This commit is contained in:
Eric Pouech 2003-03-04 04:36:56 +00:00 committed by Alexandre Julliard
parent 2f10ca5237
commit 7d6096480a
7 changed files with 150 additions and 32 deletions

View file

@ -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.@)
*/

View file

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

View file

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

View file

@ -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) */

View file

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

View file

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

View file

@ -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 );
}