Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
9b79d698
Commit
9b79d698
authored
Mar 20, 2003
by
Eric Pouech
Committed by
Alexandre Julliard
Mar 20, 2003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Moved the module loading/unloading code and the remaining needed
static variables to ntdll.
parent
500a2f95
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
194 additions
and
201 deletions
+194
-201
loader.c
dlls/ntdll/loader.c
+194
-1
module.h
include/module.h
+0
-7
module.c
loader/module.c
+0
-193
No files found.
dlls/ntdll/loader.c
View file @
9b79d698
/*
* Loader functions
*
* Copyright 1995 Alexandre Julliard
* Copyright 2002 Dmitry Timoshkov for Codeweavers
*
* This library is free software; you can redistribute it and/or
...
...
@@ -35,6 +38,10 @@ WINE_DECLARE_DEBUG_CHANNEL(module);
WINE_DECLARE_DEBUG_CHANNEL
(
module
);
WINE_DECLARE_DEBUG_CHANNEL
(
loaddll
);
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
free_lib_count
;
/* recursion depth of LdrUnloadDll calls */
/* filter for page-fault exceptions */
...
...
@@ -45,7 +52,7 @@ static WINE_EXCEPTION_FILTER(page_fault)
return
EXCEPTION_CONTINUE_SEARCH
;
}
CRITICAL_SECTION
loader_section
=
CRITICAL_SECTION_INIT
(
"loader_section"
);
static
CRITICAL_SECTION
loader_section
=
CRITICAL_SECTION_INIT
(
"loader_section"
);
/*************************************************************************
* MODULE32_LookupHMODULE
...
...
@@ -131,6 +138,192 @@ WINE_MODREF *MODULE_AllocModRef( HMODULE hModule, LPCSTR filename )
return
wm
;
}
/*************************************************************************
* MODULE_InitDLL
*/
static
BOOL
MODULE_InitDLL
(
WINE_MODREF
*
wm
,
DWORD
type
,
LPVOID
lpReserved
)
{
static
const
char
*
const
typeName
[]
=
{
"PROCESS_DETACH"
,
"PROCESS_ATTACH"
,
"THREAD_ATTACH"
,
"THREAD_DETACH"
};
BOOL
retv
=
TRUE
;
/* Skip calls for modules loaded with special load flags */
if
(
wm
->
flags
&
WINE_MODREF_DONT_RESOLVE_REFS
)
return
TRUE
;
TRACE
(
"(%s,%s,%p) - CALL
\n
"
,
wm
->
modname
,
typeName
[
type
],
lpReserved
);
/* Call the initialization routine */
retv
=
PE_InitDLL
(
wm
->
module
,
type
,
lpReserved
);
/* The state of the module list may have changed due to the call
to PE_InitDLL. We cannot assume that this module has not been
deleted. */
TRACE
(
"(%p,%s,%p) - RETURN %d
\n
"
,
wm
,
typeName
[
type
],
lpReserved
,
retv
);
return
retv
;
}
/*************************************************************************
* MODULE_DllProcessAttach
*
* Send the process attach notification to all DLLs the given module
* depends on (recursively). This is somewhat complicated due to the fact that
*
* - we have to respect the module dependencies, i.e. modules implicitly
* referenced by another module have to be initialized before the module
* itself can be initialized
*
* - the initialization routine of a DLL can itself call LoadLibrary,
* thereby introducing a whole new set of dependencies (even involving
* the 'old' modules) at any time during the whole process
*
* (Note that this routine can be recursively entered not only directly
* from itself, but also via LoadLibrary from one of the called initialization
* routines.)
*
* Furthermore, we need to rearrange the main WINE_MODREF list to allow
* the process *detach* notifications to be sent in the correct order.
* This must not only take into account module dependencies, but also
* 'hidden' dependencies created by modules calling LoadLibrary in their
* attach notification routine.
*
* The strategy is rather simple: we move a WINE_MODREF to the head of the
* list after the attach notification has returned. This implies that the
* detach notifications are called in the reverse of the sequence the attach
* notifications *returned*.
*/
BOOL
MODULE_DllProcessAttach
(
WINE_MODREF
*
wm
,
LPVOID
lpReserved
)
{
BOOL
retv
=
TRUE
;
int
i
;
RtlEnterCriticalSection
(
&
loader_section
);
if
(
!
wm
)
{
wm
=
exe_modref
;
PE_InitTls
();
}
assert
(
wm
);
/* prevent infinite recursion in case of cyclical dependencies */
if
(
(
wm
->
flags
&
WINE_MODREF_MARKER
)
||
(
wm
->
flags
&
WINE_MODREF_PROCESS_ATTACHED
)
)
goto
done
;
TRACE
(
"(%s,%p) - START
\n
"
,
wm
->
modname
,
lpReserved
);
/* Tag current MODREF to prevent recursive loop */
wm
->
flags
|=
WINE_MODREF_MARKER
;
/* Recursively attach all DLLs this one depends on */
for
(
i
=
0
;
retv
&&
i
<
wm
->
nDeps
;
i
++
)
if
(
wm
->
deps
[
i
]
)
retv
=
MODULE_DllProcessAttach
(
wm
->
deps
[
i
],
lpReserved
);
/* Call DLL entry point */
if
(
retv
)
{
retv
=
MODULE_InitDLL
(
wm
,
DLL_PROCESS_ATTACH
,
lpReserved
);
if
(
retv
)
wm
->
flags
|=
WINE_MODREF_PROCESS_ATTACHED
;
}
/* Re-insert MODREF at head of list */
if
(
retv
&&
wm
->
prev
)
{
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 */
wm
->
flags
&=
~
WINE_MODREF_MARKER
;
TRACE
(
"(%s,%p) - END
\n
"
,
wm
->
modname
,
lpReserved
);
done:
RtlLeaveCriticalSection
(
&
loader_section
);
return
retv
;
}
/*************************************************************************
* MODULE_DllProcessDetach
*
* Send DLL process detach notifications. See the comment about calling
* sequence at MODULE_DllProcessAttach. Unless the bForceDetach flag
* is set, only DLLs with zero refcount are notified.
*/
void
MODULE_DllProcessDetach
(
BOOL
bForceDetach
,
LPVOID
lpReserved
)
{
WINE_MODREF
*
wm
;
RtlEnterCriticalSection
(
&
loader_section
);
if
(
bForceDetach
)
process_detaching
=
1
;
do
{
for
(
wm
=
MODULE_modref_list
;
wm
;
wm
=
wm
->
next
)
{
/* Check whether to detach this DLL */
if
(
!
(
wm
->
flags
&
WINE_MODREF_PROCESS_ATTACHED
)
)
continue
;
if
(
wm
->
refCount
>
0
&&
!
bForceDetach
)
continue
;
/* Call detach notification */
wm
->
flags
&=
~
WINE_MODREF_PROCESS_ATTACHED
;
MODULE_InitDLL
(
wm
,
DLL_PROCESS_DETACH
,
lpReserved
);
/* Restart at head of WINE_MODREF list, as entries might have
been added and/or removed while performing the call ... */
break
;
}
}
while
(
wm
);
RtlLeaveCriticalSection
(
&
loader_section
);
}
/*************************************************************************
* MODULE_DllThreadAttach
*
* Send DLL thread attach notifications. These are sent in the
* reverse sequence of process detach notification.
*
*/
void
MODULE_DllThreadAttach
(
LPVOID
lpReserved
)
{
WINE_MODREF
*
wm
;
/* don't do any attach calls if process is exiting */
if
(
process_detaching
)
return
;
/* FIXME: there is still a race here */
RtlEnterCriticalSection
(
&
loader_section
);
PE_InitTls
();
for
(
wm
=
MODULE_modref_list
;
wm
;
wm
=
wm
->
next
)
if
(
!
wm
->
next
)
break
;
for
(
;
wm
;
wm
=
wm
->
prev
)
{
if
(
!
(
wm
->
flags
&
WINE_MODREF_PROCESS_ATTACHED
)
)
continue
;
if
(
wm
->
flags
&
WINE_MODREF_NO_DLL_CALLS
)
continue
;
MODULE_InitDLL
(
wm
,
DLL_THREAD_ATTACH
,
lpReserved
);
}
RtlLeaveCriticalSection
(
&
loader_section
);
}
/******************************************************************
* LdrDisableThreadCalloutsForDll (NTDLL.@)
*
...
...
include/module.h
View file @
9b79d698
...
...
@@ -203,13 +203,6 @@ 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
WINE_MODREF
*
exe_modref
;
extern
CRITICAL_SECTION
loader_section
;
extern
int
process_detaching
;
extern
BOOL
MODULE_InitDLL
(
WINE_MODREF
*
wm
,
DWORD
type
,
LPVOID
lpReserved
);
/* loader/ne/module.c */
extern
NE_MODULE
*
NE_GetPtr
(
HMODULE16
hModule
);
...
...
loader/module.c
View file @
9b79d698
...
...
@@ -45,11 +45,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(module);
WINE_DECLARE_DEBUG_CHANNEL
(
win32
);
WINE_DECLARE_DEBUG_CHANNEL
(
loaddll
);
WINE_MODREF
*
MODULE_modref_list
=
NULL
;
WINE_MODREF
*
exe_modref
;
int
process_detaching
=
0
;
/* set on process detach to avoid deadlocks with thread detach */
inline
static
HMODULE
get_exe_module
(
void
)
{
HMODULE
mod
;
...
...
@@ -77,194 +72,6 @@ static DWORD wait_input_idle( HANDLE process, DWORD timeout )
}
/*************************************************************************
* MODULE_InitDLL
*/
BOOL
MODULE_InitDLL
(
WINE_MODREF
*
wm
,
DWORD
type
,
LPVOID
lpReserved
)
{
BOOL
retv
=
TRUE
;
static
LPCSTR
typeName
[]
=
{
"PROCESS_DETACH"
,
"PROCESS_ATTACH"
,
"THREAD_ATTACH"
,
"THREAD_DETACH"
};
assert
(
wm
);
/* Skip calls for modules loaded with special load flags */
if
(
wm
->
flags
&
WINE_MODREF_DONT_RESOLVE_REFS
)
return
TRUE
;
TRACE
(
"(%s,%s,%p) - CALL
\n
"
,
wm
->
modname
,
typeName
[
type
],
lpReserved
);
/* Call the initialization routine */
retv
=
PE_InitDLL
(
wm
->
module
,
type
,
lpReserved
);
/* The state of the module list may have changed due to the call
to PE_InitDLL. We cannot assume that this module has not been
deleted. */
TRACE
(
"(%p,%s,%p) - RETURN %d
\n
"
,
wm
,
typeName
[
type
],
lpReserved
,
retv
);
return
retv
;
}
/*************************************************************************
* MODULE_DllProcessAttach
*
* Send the process attach notification to all DLLs the given module
* depends on (recursively). This is somewhat complicated due to the fact that
*
* - we have to respect the module dependencies, i.e. modules implicitly
* referenced by another module have to be initialized before the module
* itself can be initialized
*
* - the initialization routine of a DLL can itself call LoadLibrary,
* thereby introducing a whole new set of dependencies (even involving
* the 'old' modules) at any time during the whole process
*
* (Note that this routine can be recursively entered not only directly
* from itself, but also via LoadLibrary from one of the called initialization
* routines.)
*
* Furthermore, we need to rearrange the main WINE_MODREF list to allow
* the process *detach* notifications to be sent in the correct order.
* This must not only take into account module dependencies, but also
* 'hidden' dependencies created by modules calling LoadLibrary in their
* attach notification routine.
*
* The strategy is rather simple: we move a WINE_MODREF to the head of the
* list after the attach notification has returned. This implies that the
* detach notifications are called in the reverse of the sequence the attach
* notifications *returned*.
*/
BOOL
MODULE_DllProcessAttach
(
WINE_MODREF
*
wm
,
LPVOID
lpReserved
)
{
BOOL
retv
=
TRUE
;
int
i
;
RtlEnterCriticalSection
(
&
loader_section
);
if
(
!
wm
)
{
wm
=
exe_modref
;
PE_InitTls
();
}
assert
(
wm
);
/* prevent infinite recursion in case of cyclical dependencies */
if
(
(
wm
->
flags
&
WINE_MODREF_MARKER
)
||
(
wm
->
flags
&
WINE_MODREF_PROCESS_ATTACHED
)
)
goto
done
;
TRACE
(
"(%s,%p) - START
\n
"
,
wm
->
modname
,
lpReserved
);
/* Tag current MODREF to prevent recursive loop */
wm
->
flags
|=
WINE_MODREF_MARKER
;
/* Recursively attach all DLLs this one depends on */
for
(
i
=
0
;
retv
&&
i
<
wm
->
nDeps
;
i
++
)
if
(
wm
->
deps
[
i
]
)
retv
=
MODULE_DllProcessAttach
(
wm
->
deps
[
i
],
lpReserved
);
/* Call DLL entry point */
if
(
retv
)
{
retv
=
MODULE_InitDLL
(
wm
,
DLL_PROCESS_ATTACH
,
lpReserved
);
if
(
retv
)
wm
->
flags
|=
WINE_MODREF_PROCESS_ATTACHED
;
}
/* Re-insert MODREF at head of list */
if
(
retv
&&
wm
->
prev
)
{
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 */
wm
->
flags
&=
~
WINE_MODREF_MARKER
;
TRACE
(
"(%s,%p) - END
\n
"
,
wm
->
modname
,
lpReserved
);
done:
RtlLeaveCriticalSection
(
&
loader_section
);
return
retv
;
}
/*************************************************************************
* MODULE_DllProcessDetach
*
* Send DLL process detach notifications. See the comment about calling
* sequence at MODULE_DllProcessAttach. Unless the bForceDetach flag
* is set, only DLLs with zero refcount are notified.
*/
void
MODULE_DllProcessDetach
(
BOOL
bForceDetach
,
LPVOID
lpReserved
)
{
WINE_MODREF
*
wm
;
RtlEnterCriticalSection
(
&
loader_section
);
if
(
bForceDetach
)
process_detaching
=
1
;
do
{
for
(
wm
=
MODULE_modref_list
;
wm
;
wm
=
wm
->
next
)
{
/* Check whether to detach this DLL */
if
(
!
(
wm
->
flags
&
WINE_MODREF_PROCESS_ATTACHED
)
)
continue
;
if
(
wm
->
refCount
>
0
&&
!
bForceDetach
)
continue
;
/* Call detach notification */
wm
->
flags
&=
~
WINE_MODREF_PROCESS_ATTACHED
;
MODULE_InitDLL
(
wm
,
DLL_PROCESS_DETACH
,
lpReserved
);
/* Restart at head of WINE_MODREF list, as entries might have
been added and/or removed while performing the call ... */
break
;
}
}
while
(
wm
);
RtlLeaveCriticalSection
(
&
loader_section
);
}
/*************************************************************************
* MODULE_DllThreadAttach
*
* Send DLL thread attach notifications. These are sent in the
* reverse sequence of process detach notification.
*
*/
void
MODULE_DllThreadAttach
(
LPVOID
lpReserved
)
{
WINE_MODREF
*
wm
;
/* don't do any attach calls if process is exiting */
if
(
process_detaching
)
return
;
/* FIXME: there is still a race here */
RtlEnterCriticalSection
(
&
loader_section
);
PE_InitTls
();
for
(
wm
=
MODULE_modref_list
;
wm
;
wm
=
wm
->
next
)
if
(
!
wm
->
next
)
break
;
for
(
;
wm
;
wm
=
wm
->
prev
)
{
if
(
!
(
wm
->
flags
&
WINE_MODREF_PROCESS_ATTACHED
)
)
continue
;
if
(
wm
->
flags
&
WINE_MODREF_NO_DLL_CALLS
)
continue
;
MODULE_InitDLL
(
wm
,
DLL_THREAD_ATTACH
,
lpReserved
);
}
RtlLeaveCriticalSection
(
&
loader_section
);
}
/****************************************************************************
* DisableThreadLibraryCalls (KERNEL32.@)
*
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment