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
1efa50e4
Commit
1efa50e4
authored
Mar 14, 2003
by
Eric Pouech
Committed by
Alexandre Julliard
Mar 14, 2003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
- implementation of LdrUnloadDll out of loader/module.c
- in impacted functions, ensure that we only use ntdll functions - making use of new LdrUnloadDll
parent
580da246
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
151 additions
and
129 deletions
+151
-129
loader.c
dlls/ntdll/loader.c
+133
-2
ntdll.spec
dlls/ntdll/ntdll.spec
+1
-1
ntdll_misc.h
dlls/ntdll/ntdll_misc.h
+7
-0
module.h
include/module.h
+0
-2
module.c
loader/module.c
+10
-124
No files found.
dlls/ntdll/loader.c
View file @
1efa50e4
...
...
@@ -25,8 +25,15 @@
#include "wine/exception.h"
#include "excpt.h"
#include "wine/debug.h"
#include "wine/server.h"
#include "ntdll_misc.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
ntdll
);
WINE_DECLARE_DEBUG_CHANNEL
(
module
);
WINE_DECLARE_DEBUG_CHANNEL
(
module
);
WINE_DECLARE_DEBUG_CHANNEL
(
loaddll
);
static
int
free_lib_count
;
/* recursion depth of FreeLibrary calls */
/* filter for page-fault exceptions */
static
WINE_EXCEPTION_FILTER
(
page_fault
)
...
...
@@ -154,7 +161,6 @@ FARPROC MODULE_GetProcAddress(
if
((
wm
=
MODULE32_LookupHMODULE
(
hModule
)))
{
retproc
=
wm
->
find_export
(
wm
,
function
,
hint
,
snoop
);
if
(
!
retproc
)
SetLastError
(
ERROR_PROC_NOT_FOUND
);
}
RtlLeaveCriticalSection
(
&
loader_section
);
return
retproc
;
...
...
@@ -172,7 +178,7 @@ NTSTATUS WINAPI LdrGetProcedureAddress(HMODULE base, PANSI_STRING name, ULONG or
*
address
=
MODULE_GetProcAddress
(
base
,
name
?
name
->
Buffer
:
(
LPSTR
)
ord
,
-
1
,
TRUE
);
return
(
*
address
)
?
STATUS_SUCCESS
:
STATUS_
DLL
_NOT_FOUND
;
return
(
*
address
)
?
STATUS_SUCCESS
:
STATUS_
PROCEDURE
_NOT_FOUND
;
}
...
...
@@ -217,6 +223,131 @@ NTSTATUS WINAPI LdrShutdownThread(void)
}
/***********************************************************************
* MODULE_FlushModrefs
*
* NOTE: Assumes that the process critical section is held!
*
* Remove all unused modrefs and call the internal unloading routines
* for the library type.
*/
static
void
MODULE_FlushModrefs
(
void
)
{
WINE_MODREF
*
wm
,
*
next
;
for
(
wm
=
MODULE_modref_list
;
wm
;
wm
=
next
)
{
next
=
wm
->
next
;
if
(
wm
->
refCount
)
continue
;
/* Unlink this modref from the chain */
if
(
wm
->
next
)
wm
->
next
->
prev
=
wm
->
prev
;
if
(
wm
->
prev
)
wm
->
prev
->
next
=
wm
->
next
;
if
(
wm
==
MODULE_modref_list
)
MODULE_modref_list
=
wm
->
next
;
TRACE
(
" unloading %s
\n
"
,
wm
->
filename
);
if
(
!
TRACE_ON
(
module
))
TRACE_
(
loaddll
)(
"Unloaded module '%s' : %s
\n
"
,
wm
->
filename
,
wm
->
dlhandle
?
"builtin"
:
"native"
);
SERVER_START_REQ
(
unload_dll
)
{
req
->
base
=
(
void
*
)
wm
->
module
;
wine_server_call
(
req
);
}
SERVER_END_REQ
;
if
(
wm
->
dlhandle
)
wine_dll_unload
(
wm
->
dlhandle
);
else
UnmapViewOfFile
(
(
LPVOID
)
wm
->
module
);
FreeLibrary16
(
wm
->
hDummyMod
);
RtlFreeHeap
(
ntdll_get_process_heap
(),
0
,
wm
->
deps
);
RtlFreeHeap
(
ntdll_get_process_heap
(),
0
,
wm
);
}
}
/***********************************************************************
* MODULE_DecRefCount
*
* NOTE: Assumes that the process critical section is held!
*/
static
void
MODULE_DecRefCount
(
WINE_MODREF
*
wm
)
{
int
i
;
if
(
wm
->
flags
&
WINE_MODREF_MARKER
)
return
;
if
(
wm
->
refCount
<=
0
)
return
;
--
wm
->
refCount
;
TRACE
(
"(%s) refCount: %d
\n
"
,
wm
->
modname
,
wm
->
refCount
);
if
(
wm
->
refCount
==
0
)
{
wm
->
flags
|=
WINE_MODREF_MARKER
;
for
(
i
=
0
;
i
<
wm
->
nDeps
;
i
++
)
if
(
wm
->
deps
[
i
]
)
MODULE_DecRefCount
(
wm
->
deps
[
i
]
);
wm
->
flags
&=
~
WINE_MODREF_MARKER
;
}
}
/******************************************************************
* LdrUnloadDll (NTDLL.@)
*
*
*/
NTSTATUS
WINAPI
LdrUnloadDll
(
HMODULE
hModule
)
{
NTSTATUS
retv
=
STATUS_SUCCESS
;
TRACE
(
"(%p)
\n
"
,
hModule
);
RtlEnterCriticalSection
(
&
loader_section
);
/* if we're stopping the whole process (and forcing the removal of all
* DLLs) the library will be freed anyway
*/
if
(
!
process_detaching
)
{
WINE_MODREF
*
wm
;
free_lib_count
++
;
if
((
wm
=
MODULE32_LookupHMODULE
(
hModule
))
!=
NULL
)
{
TRACE
(
"(%s) - START
\n
"
,
wm
->
modname
);
/* Recursively decrement reference counts */
MODULE_DecRefCount
(
wm
);
/* Call process detach notifications */
if
(
free_lib_count
<=
1
)
{
MODULE_DllProcessDetach
(
FALSE
,
NULL
);
MODULE_FlushModrefs
();
}
TRACE
(
"END
\n
"
);
}
else
retv
=
STATUS_DLL_NOT_FOUND
;
free_lib_count
--
;
}
RtlLeaveCriticalSection
(
&
loader_section
);
return
retv
;
}
/***********************************************************************
* RtlImageNtHeader (NTDLL.@)
*/
PIMAGE_NT_HEADERS
WINAPI
RtlImageNtHeader
(
HMODULE
hModule
)
...
...
dlls/ntdll/ntdll.spec
View file @
1efa50e4
...
...
@@ -48,7 +48,7 @@
@ stub LdrQueryProcessModuleInformation
@ stdcall LdrShutdownProcess() LdrShutdownProcess
@ stdcall LdrShutdownThread() LdrShutdownThread
@ st
ub
LdrUnloadDll
@ st
dcall LdrUnloadDll(ptr)
LdrUnloadDll
@ stub LdrVerifyImageMatchesChecksum
@ stub NPXEMULATORTABLE
@ extern NlsAnsiCodePage NlsAnsiCodePage
...
...
dlls/ntdll/ntdll_misc.h
View file @
1efa50e4
...
...
@@ -21,6 +21,7 @@
#include "winnt.h"
#include "winternl.h"
#include "thread.h"
/* debug helper */
extern
LPCSTR
debugstr_us
(
const
UNICODE_STRING
*
str
);
...
...
@@ -29,4 +30,10 @@ extern void dump_ObjectAttributes (const OBJECT_ATTRIBUTES *ObjectAttributes);
/* module handling */
extern
FARPROC
MODULE_GetProcAddress
(
HMODULE
hModule
,
LPCSTR
function
,
int
hint
,
BOOL
snoop
);
static
inline
HANDLE
ntdll_get_process_heap
(
void
)
{
HANDLE
*
pdb
=
(
HANDLE
*
)
NtCurrentTeb
()
->
process
;
return
pdb
[
0x18
/
sizeof
(
HANDLE
)];
/* get dword at offset 0x18 in pdb */
}
#endif
include/module.h
View file @
1efa50e4
...
...
@@ -194,12 +194,10 @@ enum binary_type
/* module.c */
extern
WINE_MODREF
*
MODULE_AllocModRef
(
HMODULE
hModule
,
LPCSTR
filename
);
extern
FARPROC
MODULE_GetProcAddress
(
HMODULE
hModule
,
LPCSTR
function
,
int
hint
,
BOOL
snoop
);
extern
BOOL
MODULE_DllProcessAttach
(
WINE_MODREF
*
wm
,
LPVOID
lpReserved
);
extern
void
MODULE_DllProcessDetach
(
BOOL
bForceDetach
,
LPVOID
lpReserved
);
extern
void
MODULE_DllThreadAttach
(
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
);
extern
HMODULE16
MODULE_CreateDummyModule
(
LPCSTR
filename
,
HMODULE
module32
);
extern
enum
binary_type
MODULE_GetBinaryType
(
HANDLE
hfile
);
...
...
loader/module.c
View file @
1efa50e4
...
...
@@ -48,7 +48,6 @@ WINE_DECLARE_DEBUG_CHANNEL(loaddll);
WINE_MODREF
*
MODULE_modref_list
=
NULL
;
WINE_MODREF
*
exe_modref
;
static
int
free_lib_count
;
/* recursion depth of FreeLibrary calls */
int
process_detaching
=
0
;
/* set on process detach to avoid deadlocks with thread detach */
CRITICAL_SECTION
loader_section
=
CRITICAL_SECTION_INIT
(
"loader_section"
);
...
...
@@ -1083,7 +1082,7 @@ HMODULE WINAPI LoadLibraryExA(LPCSTR libname, HANDLE hfile, DWORD flags)
if
(
!
MODULE_DllProcessAttach
(
wm
,
NULL
)
)
{
WARN_
(
module
)(
"Attach failed for module '%s'.
\n
"
,
libname
);
MODULE_FreeLibrary
(
wm
);
LdrUnloadDll
(
wm
->
module
);
SetLastError
(
ERROR_DLL_INIT_FAILED
);
wm
=
NULL
;
}
...
...
@@ -1334,66 +1333,13 @@ HMODULE WINAPI LoadLibraryExW(LPCWSTR libnameW,HANDLE hfile,DWORD flags)
}
/***********************************************************************
* MODULE_FlushModrefs
*
* NOTE: Assumes that the process critical section is held!
*
* Remove all unused modrefs and call the internal unloading routines
* for the library type.
*/
static
void
MODULE_FlushModrefs
(
void
)
{
WINE_MODREF
*
wm
,
*
next
;
for
(
wm
=
MODULE_modref_list
;
wm
;
wm
=
next
)
{
next
=
wm
->
next
;
if
(
wm
->
refCount
)
continue
;
/* Unlink this modref from the chain */
if
(
wm
->
next
)
wm
->
next
->
prev
=
wm
->
prev
;
if
(
wm
->
prev
)
wm
->
prev
->
next
=
wm
->
next
;
if
(
wm
==
MODULE_modref_list
)
MODULE_modref_list
=
wm
->
next
;
TRACE
(
" unloading %s
\n
"
,
wm
->
filename
);
if
(
!
TRACE_ON
(
module
))
TRACE_
(
loaddll
)(
"Unloaded module '%s' : %s
\n
"
,
wm
->
filename
,
wm
->
dlhandle
?
"builtin"
:
"native"
);
SERVER_START_REQ
(
unload_dll
)
{
req
->
base
=
(
void
*
)
wm
->
module
;
wine_server_call
(
req
);
}
SERVER_END_REQ
;
if
(
wm
->
dlhandle
)
wine_dll_unload
(
wm
->
dlhandle
);
else
UnmapViewOfFile
(
(
LPVOID
)
wm
->
module
);
FreeLibrary16
(
wm
->
hDummyMod
);
HeapFree
(
GetProcessHeap
(),
0
,
wm
->
deps
);
HeapFree
(
GetProcessHeap
(),
0
,
wm
);
}
}
/***********************************************************************
* FreeLibrary (KERNEL32.@)
* FreeLibrary32 (KERNEL.486)
*/
BOOL
WINAPI
FreeLibrary
(
HINSTANCE
hLibModule
)
{
BOOL
retv
=
FALSE
;
WINE_MODREF
*
wm
;
if
(
!
hLibModule
)
{
SetLastError
(
ERROR_INVALID_HANDLE
);
return
FALSE
;
}
BOOL
retv
=
FALSE
;
NTSTATUS
nts
;
if
((
ULONG_PTR
)
hLibModule
&
1
)
{
...
...
@@ -1402,81 +1348,21 @@ BOOL WINAPI FreeLibrary(HINSTANCE hLibModule)
UnmapViewOfFile
(
ptr
);
return
TRUE
;
}
RtlEnterCriticalSection
(
&
loader_section
);
/* if we're stopping the whole process (and forcing the removal of all
* DLLs) the library will be freed anyway
*/
if
(
process_detaching
)
retv
=
TRUE
;
else
if
(
!
hLibModule
)
{
free_lib_count
++
;
if
((
wm
=
MODULE32_LookupHMODULE
(
hLibModule
)))
retv
=
MODULE_FreeLibrary
(
wm
);
free_lib_count
--
;
SetLastError
(
ERROR_INVALID_HANDLE
)
;
RtlLeaveCriticalSection
(
&
loader_section
);
return
FALSE
;
}
RtlLeaveCriticalSection
(
&
loader_section
);
if
((
nts
=
LdrUnloadDll
(
hLibModule
))
==
STATUS_SUCCESS
)
retv
=
TRUE
;
else
SetLastError
(
RtlNtStatusToDosError
(
nts
)
);
return
retv
;
}
/***********************************************************************
* MODULE_DecRefCount
*
* NOTE: Assumes that the process critical section is held!
*/
static
void
MODULE_DecRefCount
(
WINE_MODREF
*
wm
)
{
int
i
;
if
(
wm
->
flags
&
WINE_MODREF_MARKER
)
return
;
if
(
wm
->
refCount
<=
0
)
return
;
--
wm
->
refCount
;
TRACE
(
"(%s) refCount: %d
\n
"
,
wm
->
modname
,
wm
->
refCount
);
if
(
wm
->
refCount
==
0
)
{
wm
->
flags
|=
WINE_MODREF_MARKER
;
for
(
i
=
0
;
i
<
wm
->
nDeps
;
i
++
)
if
(
wm
->
deps
[
i
]
)
MODULE_DecRefCount
(
wm
->
deps
[
i
]
);
wm
->
flags
&=
~
WINE_MODREF_MARKER
;
}
}
/***********************************************************************
* MODULE_FreeLibrary
*
* NOTE: Assumes that the process critical section is held!
*/
BOOL
MODULE_FreeLibrary
(
WINE_MODREF
*
wm
)
{
TRACE
(
"(%s) - START
\n
"
,
wm
->
modname
);
/* Recursively decrement reference counts */
MODULE_DecRefCount
(
wm
);
/* Call process detach notifications */
if
(
free_lib_count
<=
1
)
{
MODULE_DllProcessDetach
(
FALSE
,
NULL
);
MODULE_FlushModrefs
();
}
TRACE
(
"END
\n
"
);
return
TRUE
;
}
/***********************************************************************
* FreeLibraryAndExitThread (KERNEL32.@)
*/
VOID
WINAPI
FreeLibraryAndExitThread
(
HINSTANCE
hLibModule
,
DWORD
dwExitCode
)
...
...
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