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
632676b1
Commit
632676b1
authored
Oct 06, 2003
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Moved the final process init and dependency loading to
dlls/ntdll/loader.c, (ab)using the LdrInitializeThunk entry point.
parent
5dc5bf5d
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
106 additions
and
106 deletions
+106
-106
process.c
dlls/kernel/process.c
+15
-67
loader.c
dlls/ntdll/loader.c
+88
-34
ntdll.spec
dlls/ntdll/ntdll.spec
+1
-1
ntdll_misc.h
dlls/ntdll/ntdll_misc.h
+1
-0
module.h
include/module.h
+0
-4
winternl.h
include/winternl.h
+1
-0
No files found.
dlls/kernel/process.c
View file @
632676b1
...
...
@@ -45,7 +45,6 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
process
);
WINE_DECLARE_DEBUG_CHANNEL
(
server
);
WINE_DECLARE_DEBUG_CHANNEL
(
relay
);
WINE_DECLARE_DEBUG_CHANNEL
(
snoop
);
/* Win32 process database */
typedef
struct
_PDB
...
...
@@ -125,7 +124,6 @@ static const WCHAR winevdmW[] = {'w','i','n','e','v','d','m','.','e','x','e',0};
/* dlls/ntdll/env.c */
extern
BOOL
build_command_line
(
char
**
argv
);
extern
void
RELAY_InitDebugLists
(
void
);
extern
void
SHELL_LoadRegistry
(
void
);
extern
void
VERSION_Init
(
const
WCHAR
*
appname
);
extern
void
MODULE_InitLoadPath
(
void
);
...
...
@@ -331,7 +329,7 @@ static BOOL find_exe_file( const WCHAR *name, WCHAR *buffer, int buflen, HANDLE
*
* Load a PE format EXE file.
*/
static
HMODULE
load_pe_exe
(
HANDLE
file
)
static
HMODULE
load_pe_exe
(
const
WCHAR
*
name
,
HANDLE
file
)
{
IMAGE_NT_HEADERS
*
nt
;
HANDLE
mapping
;
...
...
@@ -339,6 +337,7 @@ static HMODULE load_pe_exe( HANDLE file )
OBJECT_ATTRIBUTES
attr
;
LARGE_INTEGER
size
;
DWORD
len
=
0
;
UINT
drive_type
;
attr
.
Length
=
sizeof
(
attr
);
attr
.
RootDirectory
=
0
;
...
...
@@ -364,10 +363,19 @@ static HMODULE load_pe_exe( HANDLE file )
if
(
nt
->
OptionalHeader
.
AddressOfEntryPoint
)
{
if
(
!
RtlImageRvaToSection
(
nt
,
module
,
nt
->
OptionalHeader
.
AddressOfEntryPoint
))
MESSAGE
(
"VIRUS WARNING: PE module has an invalid entrypoint (0x%08lx) "
MESSAGE
(
"VIRUS WARNING: PE module
%s
has an invalid entrypoint (0x%08lx) "
"outside all sections (possibly infected by Tchernobyl/SpaceFiller virus)!
\n
"
,
nt
->
OptionalHeader
.
AddressOfEntryPoint
);
debugstr_w
(
name
),
nt
->
OptionalHeader
.
AddressOfEntryPoint
);
}
drive_type
=
GetDriveTypeW
(
name
);
/* don't keep the file handle open on removable media */
if
(
drive_type
==
DRIVE_REMOVABLE
||
drive_type
==
DRIVE_CDROM
)
{
CloseHandle
(
main_exe_file
);
main_exe_file
=
0
;
}
return
module
;
}
...
...
@@ -610,8 +618,6 @@ static BOOL process_init( char *argv[] )
}
SERVER_END_REQ
;
if
(
TRACE_ON
(
relay
)
||
TRACE_ON
(
snoop
))
RELAY_InitDebugLists
();
return
TRUE
;
}
...
...
@@ -625,65 +631,7 @@ static void start_process( void *arg )
{
__TRY
{
LPTHREAD_START_ROUTINE
entry
;
HANDLE
main_file
=
main_exe_file
;
IMAGE_NT_HEADERS
*
nt
;
PEB
*
peb
=
NtCurrentTeb
()
->
Peb
;
UNICODE_STRING
*
main_exe_name
=
&
peb
->
ProcessParameters
->
ImagePathName
;
if
(
main_file
)
{
UINT
drive_type
=
GetDriveTypeW
(
main_exe_name
->
Buffer
);
/* don't keep the file handle open on removable media */
if
(
drive_type
==
DRIVE_REMOVABLE
||
drive_type
==
DRIVE_CDROM
)
main_file
=
0
;
}
/* Retrieve entry point address */
nt
=
RtlImageNtHeader
(
peb
->
ImageBaseAddress
);
entry
=
(
LPTHREAD_START_ROUTINE
)((
char
*
)
peb
->
ImageBaseAddress
+
nt
->
OptionalHeader
.
AddressOfEntryPoint
);
/* Install signal handlers; this cannot be done before, since we cannot
* send exceptions to the debugger before the create process event that
* is sent by REQ_INIT_PROCESS_DONE.
* We do need the handlers in place by the time the request is over, so
* we set them up here. If we segfault between here and the server call
* something is very wrong... */
if
(
!
SIGNAL_Init
())
goto
error
;
/* Signal the parent process to continue */
SERVER_START_REQ
(
init_process_done
)
{
req
->
module
=
peb
->
ImageBaseAddress
;
req
->
module_size
=
nt
->
OptionalHeader
.
SizeOfImage
;
req
->
entry
=
entry
;
/* API requires a double indirection */
req
->
name
=
&
main_exe_name
->
Buffer
;
req
->
exe_file
=
main_file
;
req
->
gui
=
(
nt
->
OptionalHeader
.
Subsystem
!=
IMAGE_SUBSYSTEM_WINDOWS_CUI
);
wine_server_add_data
(
req
,
main_exe_name
->
Buffer
,
main_exe_name
->
Length
);
wine_server_call
(
req
);
peb
->
BeingDebugged
=
reply
->
debugged
;
}
SERVER_END_REQ
;
/* create the main modref and load dependencies */
if
(
main_exe_file
)
CloseHandle
(
main_exe_file
);
/* we no longer need it */
if
(
MODULE_DllProcessAttach
(
NULL
,
(
LPVOID
)
1
)
!=
STATUS_SUCCESS
)
{
ERR
(
"Main exe initialization failed
\n
"
);
goto
error
;
}
if
(
TRACE_ON
(
relay
))
DPRINTF
(
"%04lx:Starting process %s (entryproc=%p)
\n
"
,
GetCurrentThreadId
(),
debugstr_w
(
main_exe_name
->
Buffer
),
entry
);
if
(
peb
->
BeingDebugged
)
DbgBreakPoint
();
SetLastError
(
0
);
/* clear error code */
ExitThread
(
entry
(
NtCurrentTeb
()
->
Peb
)
);
error:
ExitProcess
(
GetLastError
()
);
LdrInitializeThunk
(
main_exe_file
,
0
,
0
,
0
);
}
__EXCEPT
(
UnhandledExceptionFilter
)
{
...
...
@@ -753,7 +701,7 @@ void __wine_process_init( int argc, char *argv[] )
{
case
BINARY_PE_EXE
:
TRACE
(
"starting Win32 binary %s
\n
"
,
debugstr_w
(
main_exe_name
)
);
if
((
current_process
.
module
=
load_pe_exe
(
main_exe_file
)))
goto
found
;
if
((
current_process
.
module
=
load_pe_exe
(
main_exe_
name
,
main_exe_
file
)))
goto
found
;
MESSAGE
(
"wine: could not load %s as Win32 binary
\n
"
,
debugstr_w
(
main_exe_name
)
);
ExitProcess
(
1
);
case
BINARY_PE_DLL
:
...
...
dlls/ntdll/loader.c
View file @
632676b1
...
...
@@ -66,12 +66,12 @@ static const char * const reason_names[] =
static
const
WCHAR
dllW
[]
=
{
'.'
,
'd'
,
'l'
,
'l'
,
0
};
/* internal representation of 32bit modules. per process. */
struct
_wine_modref
typedef
struct
_wine_modref
{
LDR_MODULE
ldr
;
int
nDeps
;
struct
_wine_modref
**
deps
;
};
}
WINE_MODREF
;
static
UINT
tls_module_count
;
/* number of modules with TLS directory */
static
UINT
tls_total_size
;
/* total size of TLS storage */
...
...
@@ -675,7 +675,7 @@ static BOOL MODULE_InitDLL( WINE_MODREF *wm, UINT reason, LPVOID lpReserved )
/*************************************************************************
*
MODULE_DllProcessA
ttach
*
process_a
ttach
*
* Send the process attach notification to all DLLs the given module
* depends on (recursively). This is somewhat complicated due to the fact that
...
...
@@ -702,34 +702,18 @@ static BOOL MODULE_InitDLL( WINE_MODREF *wm, UINT reason, LPVOID lpReserved )
* 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*.
*
* The loader_section must be locked while calling this function.
*/
NTSTATUS
MODULE_DllProcessA
ttach
(
WINE_MODREF
*
wm
,
LPVOID
lpReserved
)
static
NTSTATUS
process_a
ttach
(
WINE_MODREF
*
wm
,
LPVOID
lpReserved
)
{
NTSTATUS
status
=
STATUS_SUCCESS
;
int
i
;
RtlEnterCriticalSection
(
&
loader_section
);
if
(
!
wm
)
{
/* allocate the modref for the main exe */
if
(
!
(
wm
=
alloc_module
(
NtCurrentTeb
()
->
Peb
->
ImageBaseAddress
,
NtCurrentTeb
()
->
Peb
->
ProcessParameters
->
ImagePathName
.
Buffer
)))
{
status
=
STATUS_NO_MEMORY
;
goto
done
;
}
wm
->
ldr
.
LoadCount
=
-
1
;
/* can't unload main exe */
if
((
status
=
fixup_imports
(
wm
))
!=
STATUS_SUCCESS
)
goto
done
;
if
((
status
=
alloc_process_tls
())
!=
STATUS_SUCCESS
)
goto
done
;
if
((
status
=
alloc_thread_tls
())
!=
STATUS_SUCCESS
)
goto
done
;
}
assert
(
wm
);
/* prevent infinite recursion in case of cyclical dependencies */
if
(
(
wm
->
ldr
.
Flags
&
LDR_LOAD_IN_PROGRESS
)
||
(
wm
->
ldr
.
Flags
&
LDR_PROCESS_ATTACHED
)
)
goto
done
;
return
status
;
TRACE
(
"(%s,%p) - START
\n
"
,
debugstr_w
(
wm
->
ldr
.
BaseDllName
.
Buffer
),
lpReserved
);
...
...
@@ -740,7 +724,7 @@ NTSTATUS MODULE_DllProcessAttach( WINE_MODREF *wm, LPVOID lpReserved )
for
(
i
=
0
;
i
<
wm
->
nDeps
;
i
++
)
{
if
(
!
wm
->
deps
[
i
])
continue
;
if
((
status
=
MODULE_DllProcessA
ttach
(
wm
->
deps
[
i
],
lpReserved
))
!=
STATUS_SUCCESS
)
break
;
if
((
status
=
process_a
ttach
(
wm
->
deps
[
i
],
lpReserved
))
!=
STATUS_SUCCESS
)
break
;
}
/* Call DLL entry point */
...
...
@@ -757,25 +741,22 @@ NTSTATUS MODULE_DllProcessAttach( WINE_MODREF *wm, LPVOID lpReserved )
InsertTailList
(
&
NtCurrentTeb
()
->
Peb
->
LdrData
->
InInitializationOrderModuleList
,
&
wm
->
ldr
.
InInitializationOrderModuleList
);
/* Remove recursion flag */
wm
->
ldr
.
Flags
&=
~
LDR_LOAD_IN_PROGRESS
;
TRACE
(
"(%s,%p) - END
\n
"
,
debugstr_w
(
wm
->
ldr
.
BaseDllName
.
Buffer
),
lpReserved
);
done:
RtlLeaveCriticalSection
(
&
loader_section
);
return
status
;
}
/*************************************************************************
*
MODULE_DllProcessD
etach
*
process_d
etach
*
* Send DLL process detach notifications. See the comment about calling
* sequence at
MODULE_DllProcessA
ttach. Unless the bForceDetach flag
* sequence at
process_a
ttach. Unless the bForceDetach flag
* is set, only DLLs with zero refcount are notified.
*/
static
void
MODULE_DllProcessD
etach
(
BOOL
bForceDetach
,
LPVOID
lpReserved
)
static
void
process_d
etach
(
BOOL
bForceDetach
,
LPVOID
lpReserved
)
{
PLIST_ENTRY
mark
,
entry
;
PLDR_MODULE
mod
;
...
...
@@ -1393,7 +1374,7 @@ NTSTATUS WINAPI LdrLoadDll(LPCWSTR path_name, DWORD flags,
if
(
nts
==
STATUS_SUCCESS
&&
!
(
wm
->
ldr
.
Flags
&
LDR_DONT_RESOLVE_REFS
))
{
nts
=
MODULE_DllProcessA
ttach
(
wm
,
NULL
);
nts
=
process_a
ttach
(
wm
,
NULL
);
if
(
nts
!=
STATUS_SUCCESS
)
{
WARN
(
"Attach failed for module %s
\n
"
,
debugstr_w
(
libname
->
Buffer
));
...
...
@@ -1466,7 +1447,7 @@ NTSTATUS WINAPI LdrQueryProcessModuleInformation(PSYSTEM_MODULE_INFORMATION smi,
void
WINAPI
LdrShutdownProcess
(
void
)
{
TRACE
(
"()
\n
"
);
MODULE_DllProcessD
etach
(
TRUE
,
(
LPVOID
)
1
);
process_d
etach
(
TRUE
,
(
LPVOID
)
1
);
}
/******************************************************************
...
...
@@ -1614,7 +1595,7 @@ NTSTATUS WINAPI LdrUnloadDll( HMODULE hModule )
/* Call process detach notifications */
if
(
free_lib_count
<=
1
)
{
MODULE_DllProcessD
etach
(
FALSE
,
NULL
);
process_d
etach
(
FALSE
,
NULL
);
MODULE_FlushModrefs
();
}
...
...
@@ -1658,6 +1639,79 @@ PIMAGE_NT_HEADERS WINAPI RtlImageNtHeader(HMODULE hModule)
}
/******************************************************************
* LdrInitializeThunk (NTDLL.@)
*
* FIXME: the arguments are not correct, main_file is a Wine invention.
*/
void
WINAPI
LdrInitializeThunk
(
HANDLE
main_file
,
ULONG
unknown2
,
ULONG
unknown3
,
ULONG
unknown4
)
{
NTSTATUS
status
;
WINE_MODREF
*
wm
;
LPTHREAD_START_ROUTINE
entry
;
PEB
*
peb
=
NtCurrentTeb
()
->
Peb
;
UNICODE_STRING
*
main_exe_name
=
&
peb
->
ProcessParameters
->
ImagePathName
;
IMAGE_NT_HEADERS
*
nt
=
RtlImageNtHeader
(
peb
->
ImageBaseAddress
);
/* allocate the modref for the main exe */
if
(
!
(
wm
=
alloc_module
(
peb
->
ImageBaseAddress
,
main_exe_name
->
Buffer
)))
{
status
=
STATUS_NO_MEMORY
;
goto
error
;
}
wm
->
ldr
.
LoadCount
=
-
1
;
/* can't unload main exe */
entry
=
wm
->
ldr
.
EntryPoint
;
/* Install signal handlers; this cannot be done before, since we cannot
* send exceptions to the debugger before the create process event that
* is sent by REQ_INIT_PROCESS_DONE.
* We do need the handlers in place by the time the request is over, so
* we set them up here. If we segfault between here and the server call
* something is very wrong... */
if
(
!
SIGNAL_Init
())
exit
(
1
);
/* Signal the parent process to continue */
SERVER_START_REQ
(
init_process_done
)
{
req
->
module
=
peb
->
ImageBaseAddress
;
req
->
module_size
=
wm
->
ldr
.
SizeOfImage
;
req
->
entry
=
entry
;
/* API requires a double indirection */
req
->
name
=
&
main_exe_name
->
Buffer
;
req
->
exe_file
=
main_file
;
req
->
gui
=
(
nt
->
OptionalHeader
.
Subsystem
!=
IMAGE_SUBSYSTEM_WINDOWS_CUI
);
wine_server_add_data
(
req
,
main_exe_name
->
Buffer
,
main_exe_name
->
Length
);
wine_server_call
(
req
);
peb
->
BeingDebugged
=
reply
->
debugged
;
}
SERVER_END_REQ
;
if
(
main_file
)
NtClose
(
main_file
);
/* we no longer need it */
if
(
TRACE_ON
(
relay
)
||
TRACE_ON
(
snoop
))
RELAY_InitDebugLists
();
RtlEnterCriticalSection
(
&
loader_section
);
if
((
status
=
fixup_imports
(
wm
))
!=
STATUS_SUCCESS
)
goto
error
;
if
((
status
=
alloc_process_tls
())
!=
STATUS_SUCCESS
)
goto
error
;
if
((
status
=
alloc_thread_tls
())
!=
STATUS_SUCCESS
)
goto
error
;
if
((
status
=
process_attach
(
wm
,
(
LPVOID
)
1
))
!=
STATUS_SUCCESS
)
goto
error
;
RtlLeaveCriticalSection
(
&
loader_section
);
if
(
TRACE_ON
(
relay
))
DPRINTF
(
"%04lx:Starting process %s (entryproc=%p)
\n
"
,
GetCurrentThreadId
(),
debugstr_w
(
peb
->
ProcessParameters
->
ImagePathName
.
Buffer
),
entry
);
NtCurrentTeb
()
->
last_error
=
0
;
/* clear error code */
if
(
peb
->
BeingDebugged
)
DbgBreakPoint
();
NtTerminateProcess
(
GetCurrentProcess
(),
entry
(
peb
)
);
error:
ERR
(
"Main exe initialization failed, status %lx
\n
"
,
status
);
exit
(
1
);
}
/***********************************************************************
* RtlImageDirectoryEntryToData (NTDLL.@)
*/
...
...
dlls/ntdll/ntdll.spec
View file @
632676b1
...
...
@@ -41,7 +41,7 @@
@ stdcall LdrFindResource_U(long ptr long ptr)
@ stdcall LdrGetDllHandle(long long ptr ptr)
@ stdcall LdrGetProcedureAddress(ptr ptr long ptr)
@ st
ub LdrInitializeThunk
@ st
dcall LdrInitializeThunk(long long long long)
@ stdcall LdrLoadDll(wstr long ptr ptr)
@ stdcall LdrLockLoaderLock(long ptr ptr)
@ stub LdrProcessRelocationBlock
...
...
dlls/ntdll/ntdll_misc.h
View file @
632676b1
...
...
@@ -40,6 +40,7 @@ extern NTSTATUS NTDLL_wait_for_multiple_objects( UINT count, const HANDLE *handl
const
LARGE_INTEGER
*
timeout
);
/* module handling */
extern
void
RELAY_InitDebugLists
(
void
);
extern
FARPROC
RELAY_GetProcAddress
(
HMODULE
module
,
IMAGE_EXPORT_DIRECTORY
*
exports
,
DWORD
exp_size
,
FARPROC
proc
,
const
WCHAR
*
user
);
extern
FARPROC
SNOOP_GetProcAddress
(
HMODULE
hmod
,
IMAGE_EXPORT_DIRECTORY
*
exports
,
DWORD
exp_size
,
...
...
include/module.h
View file @
632676b1
...
...
@@ -128,9 +128,6 @@ typedef struct
#include <poppack.h>
struct
_wine_modref
;
typedef
struct
_wine_modref
WINE_MODREF
;
/* Resource types */
#define NE_SEG_TABLE(pModule) \
...
...
@@ -165,7 +162,6 @@ enum binary_type
};
/* module.c */
extern
NTSTATUS
MODULE_DllProcessAttach
(
WINE_MODREF
*
wm
,
LPVOID
lpReserved
);
extern
NTSTATUS
MODULE_DllThreadAttach
(
LPVOID
lpReserved
);
extern
enum
binary_type
MODULE_GetBinaryType
(
HANDLE
hfile
);
extern
FARPROC16
WINAPI
WIN32_GetProcAddress16
(
HMODULE
hmodule
,
LPCSTR
name
);
...
...
include/winternl.h
View file @
632676b1
...
...
@@ -954,6 +954,7 @@ NTSTATUS WINAPI LdrFindResourceDirectory_U(HMODULE,const LDR_RESOURCE_INFO*,ULO
NTSTATUS
WINAPI
LdrFindResource_U
(
HMODULE
,
const
LDR_RESOURCE_INFO
*
,
ULONG
,
const
IMAGE_RESOURCE_DATA_ENTRY
**
);
NTSTATUS
WINAPI
LdrGetDllHandle
(
ULONG
,
ULONG
,
const
UNICODE_STRING
*
,
HMODULE
*
);
NTSTATUS
WINAPI
LdrGetProcedureAddress
(
HMODULE
,
const
ANSI_STRING
*
,
ULONG
,
void
**
);
void
WINAPI
LdrInitializeThunk
(
HANDLE
,
ULONG
,
ULONG
,
ULONG
);
NTSTATUS
WINAPI
LdrLoadDll
(
LPCWSTR
,
DWORD
,
const
UNICODE_STRING
*
,
HMODULE
*
);
void
WINAPI
LdrShutdownProcess
(
void
);
void
WINAPI
LdrShutdownThread
(
void
);
...
...
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