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
83e520f5
Commit
83e520f5
authored
Nov 11, 2019
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kernel32: Move exec process functionality to ntdll.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
8c4a1cc7
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
210 additions
and
257 deletions
+210
-257
process.c
dlls/kernel32/process.c
+1
-247
loader.c
dlls/ntdll/loader.c
+29
-10
ntdll_misc.h
dlls/ntdll/ntdll_misc.h
+1
-0
process.c
dlls/ntdll/process.c
+179
-0
No files found.
dlls/kernel32/process.c
View file @
83e520f5
This diff is collapsed.
Click to expand it.
dlls/ntdll/loader.c
View file @
83e520f5
...
...
@@ -4286,23 +4286,42 @@ void __wine_process_init(void)
{
peb
->
ImageBaseAddress
=
wm
->
ldr
.
BaseAddress
;
TRACE
(
"main exe loaded %s at %p
\n
"
,
debugstr_us
(
&
params
->
ImagePathName
),
peb
->
ImageBaseAddress
);
if
(
wm
->
ldr
.
Flags
&
LDR_IMAGE_IS_DLL
)
{
MESSAGE
(
"wine: %s is a dll, not an executable
\n
"
,
debugstr_w
(
wm
->
ldr
.
FullDllName
.
Buffer
)
);
NtTerminateProcess
(
GetCurrentProcess
(),
STATUS_INVALID_IMAGE_FORMAT
);
}
}
else
if
(
info_size
)
else
{
WARN
(
"failed to load %s status %x
\n
"
,
debugstr_us
(
&
params
->
ImagePathName
),
status
);
if
(
!
info_size
)
status
=
restart_process
(
params
,
status
);
switch
(
status
)
{
case
STATUS_INVALID_IMAGE_WIN_64
:
ERR
(
"%s 64-bit application not supported in 32-bit prefix
\n
"
,
debugstr_us
(
&
params
->
ImagePathName
)
);
break
;
case
STATUS_INVALID_IMAGE_WIN_16
:
case
STATUS_INVALID_IMAGE_NE_FORMAT
:
case
STATUS_INVALID_IMAGE_PROTECT
:
ERR
(
"%s 16-bit application not supported on this system
\n
"
,
debugstr_us
(
&
params
->
ImagePathName
)
);
break
;
case
STATUS_INVALID_IMAGE_FORMAT
:
ERR
(
"%s not supported on this system
\n
"
,
debugstr_us
(
&
params
->
ImagePathName
)
);
break
;
case
STATUS_DLL_NOT_FOUND
:
ERR
(
"%s not found
\n
"
,
debugstr_us
(
&
params
->
ImagePathName
)
);
break
;
default:
ERR
(
"failed to load %s, error %x
\n
"
,
debugstr_us
(
&
params
->
ImagePathName
),
status
);
break
;
}
NtTerminateProcess
(
GetCurrentProcess
(),
status
);
}
kernel32_start_process
=
init_func
();
wm
=
get_modref
(
peb
->
ImageBaseAddress
);
assert
(
wm
);
if
(
wm
->
ldr
.
Flags
&
LDR_IMAGE_IS_DLL
)
{
MESSAGE
(
"wine: %s is a dll, not an executable
\n
"
,
debugstr_w
(
wm
->
ldr
.
FullDllName
.
Buffer
)
);
NtTerminateProcess
(
GetCurrentProcess
(),
STATUS_INVALID_IMAGE_FORMAT
);
}
virtual_set_large_address_space
();
/* the main exe needs to be the first in the load order list */
...
...
dlls/ntdll/ntdll_misc.h
View file @
83e520f5
...
...
@@ -86,6 +86,7 @@ extern void virtual_init_threading(void) DECLSPEC_HIDDEN;
extern
void
fill_cpu_info
(
void
)
DECLSPEC_HIDDEN
;
extern
void
heap_set_debug_flags
(
HANDLE
handle
)
DECLSPEC_HIDDEN
;
extern
void
init_user_process_params
(
SIZE_T
data_size
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
restart_process
(
RTL_USER_PROCESS_PARAMETERS
*
params
,
NTSTATUS
status
)
DECLSPEC_HIDDEN
;
/* server support */
extern
timeout_t
server_start_time
DECLSPEC_HIDDEN
;
...
...
dlls/ntdll/process.c
View file @
83e520f5
...
...
@@ -39,6 +39,10 @@
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef __APPLE__
#include <CoreFoundation/CoreFoundation.h>
#include <pthread.h>
#endif
#include "ntstatus.h"
#define WIN32_NO_STATUS
...
...
@@ -1036,6 +1040,55 @@ static const char *get_alternate_loader( char **ret_env )
}
#ifdef __APPLE__
/***********************************************************************
* terminate_main_thread
*
* On some versions of Mac OS X, the execve system call fails with
* ENOTSUP if the process has multiple threads. Wine is always multi-
* threaded on Mac OS X because it specifically reserves the main thread
* for use by the system frameworks (see apple_main_thread() in
* libs/wine/loader.c). So, when we need to exec without first forking,
* we need to terminate the main thread first. We do this by installing
* a custom run loop source onto the main run loop and signaling it.
* The source's "perform" callback is pthread_exit and it will be
* executed on the main thread, terminating it.
*
* Returns TRUE if there's still hope the main thread has terminated or
* will soon. Return FALSE if we've given up.
*/
static
BOOL
terminate_main_thread
(
void
)
{
static
int
delayms
;
if
(
!
delayms
)
{
CFRunLoopSourceContext
source_context
=
{
0
};
CFRunLoopSourceRef
source
;
source_context
.
perform
=
pthread_exit
;
if
(
!
(
source
=
CFRunLoopSourceCreate
(
NULL
,
0
,
&
source_context
)))
return
FALSE
;
CFRunLoopAddSource
(
CFRunLoopGetMain
(),
source
,
kCFRunLoopCommonModes
);
CFRunLoopSourceSignal
(
source
);
CFRunLoopWakeUp
(
CFRunLoopGetMain
()
);
CFRelease
(
source
);
delayms
=
20
;
}
if
(
delayms
>
1000
)
return
FALSE
;
usleep
(
delayms
*
1000
);
delayms
*=
2
;
return
TRUE
;
}
#endif
/***********************************************************************
* set_stdio_fd
*/
...
...
@@ -1135,6 +1188,50 @@ static NTSTATUS spawn_loader( const RTL_USER_PROCESS_PARAMETERS *params, int soc
}
/***********************************************************************
* exec_loader
*/
static
NTSTATUS
exec_loader
(
const
UNICODE_STRING
*
cmdline
,
int
socketfd
,
const
pe_image_info_t
*
pe_info
)
{
char
*
wineloader
=
NULL
;
const
char
*
loader
=
NULL
;
char
**
argv
;
char
preloader_reserve
[
64
],
socket_env
[
64
];
ULONGLONG
res_start
=
pe_info
->
base
;
ULONGLONG
res_end
=
pe_info
->
base
+
pe_info
->
map_size
;
if
(
!
(
argv
=
build_argv
(
cmdline
,
1
)))
return
STATUS_NO_MEMORY
;
if
(
!
is_win64
^
!
is_64bit_arch
(
pe_info
->
cpu
))
loader
=
get_alternate_loader
(
&
wineloader
);
/* Reset signals that we previously set to SIG_IGN */
signal
(
SIGPIPE
,
SIG_DFL
);
sprintf
(
socket_env
,
"WINESERVERSOCKET=%u"
,
socketfd
);
sprintf
(
preloader_reserve
,
"WINEPRELOADRESERVE=%x%08x-%x%08x"
,
(
ULONG
)(
res_start
>>
32
),
(
ULONG
)
res_start
,
(
ULONG
)(
res_end
>>
32
),
(
ULONG
)
res_end
);
putenv
(
preloader_reserve
);
putenv
(
socket_env
);
if
(
wineloader
)
putenv
(
wineloader
);
do
{
wine_exec_wine_binary
(
loader
,
argv
,
getenv
(
"WINELOADER"
)
);
}
#ifdef __APPLE__
while
(
errno
==
ENOTSUP
&&
terminate_main_thread
());
#else
while
(
0
);
#endif
RtlFreeHeap
(
GetProcessHeap
(),
0
,
wineloader
);
RtlFreeHeap
(
GetProcessHeap
(),
0
,
argv
);
return
STATUS_INVALID_IMAGE_FORMAT
;
}
/***************************************************************************
* is_builtin_path
*/
...
...
@@ -1367,6 +1464,88 @@ static char *get_unix_curdir( const RTL_USER_PROCESS_PARAMETERS *params )
}
/***********************************************************************
* restart_process
*/
NTSTATUS
restart_process
(
RTL_USER_PROCESS_PARAMETERS
*
params
,
NTSTATUS
status
)
{
static
const
WCHAR
argsW
[]
=
{
'%'
,
's'
,
'%'
,
's'
,
' '
,
'-'
,
'-'
,
'a'
,
'p'
,
'p'
,
'-'
,
'n'
,
'a'
,
'm'
,
'e'
,
' '
,
'"'
,
'%'
,
's'
,
'"'
,
' '
,
'%'
,
's'
,
0
};
static
const
WCHAR
winevdm
[]
=
{
'w'
,
'i'
,
'n'
,
'e'
,
'v'
,
'd'
,
'm'
,
'.'
,
'e'
,
'x'
,
'e'
,
0
};
static
const
WCHAR
comW
[]
=
{
'.'
,
'c'
,
'o'
,
'm'
,
0
};
static
const
WCHAR
pifW
[]
=
{
'.'
,
'p'
,
'i'
,
'f'
,
0
};
int
socketfd
[
2
];
WCHAR
*
p
,
*
cmdline
;
UNICODE_STRING
strW
;
pe_image_info_t
pe_info
;
HANDLE
handle
;
/* check for .com or .pif extension */
if
(
status
==
STATUS_INVALID_IMAGE_NOT_MZ
&&
(
p
=
strrchrW
(
params
->
ImagePathName
.
Buffer
,
'.'
))
&&
(
!
strcmpiW
(
p
,
comW
)
||
!
strcmpiW
(
p
,
pifW
)))
status
=
STATUS_INVALID_IMAGE_WIN_16
;
switch
(
status
)
{
case
STATUS_CONFLICTING_ADDRESSES
:
case
STATUS_NO_MEMORY
:
case
STATUS_INVALID_IMAGE_FORMAT
:
case
STATUS_INVALID_IMAGE_NOT_MZ
:
if
(
getenv
(
"WINEPRELOADRESERVE"
))
return
status
;
if
((
status
=
RtlDosPathNameToNtPathName_U_WithStatus
(
params
->
ImagePathName
.
Buffer
,
&
strW
,
NULL
,
NULL
)))
return
status
;
if
((
status
=
get_pe_file_info
(
&
strW
,
OBJ_CASE_INSENSITIVE
,
&
handle
,
&
pe_info
)))
return
status
;
strW
=
params
->
CommandLine
;
break
;
case
STATUS_INVALID_IMAGE_WIN_16
:
case
STATUS_INVALID_IMAGE_NE_FORMAT
:
case
STATUS_INVALID_IMAGE_PROTECT
:
cmdline
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
(
strlenW
(
system_dir
)
+
strlenW
(
winevdm
)
+
16
+
strlenW
(
params
->
ImagePathName
.
Buffer
)
+
strlenW
(
params
->
CommandLine
.
Buffer
))
*
sizeof
(
WCHAR
));
if
(
!
cmdline
)
return
STATUS_NO_MEMORY
;
sprintfW
(
cmdline
,
argsW
,
(
is_win64
||
is_wow64
)
?
syswow64_dir
:
system_dir
,
winevdm
,
params
->
ImagePathName
.
Buffer
,
params
->
CommandLine
.
Buffer
);
RtlInitUnicodeString
(
&
strW
,
cmdline
);
memset
(
&
pe_info
,
0
,
sizeof
(
pe_info
)
);
pe_info
.
cpu
=
CPU_x86
;
break
;
default:
return
status
;
}
/* exec the new process */
if
(
socketpair
(
PF_UNIX
,
SOCK_STREAM
,
0
,
socketfd
)
==
-
1
)
return
STATUS_TOO_MANY_OPENED_FILES
;
#ifdef SO_PASSCRED
else
{
int
enable
=
1
;
setsockopt
(
socketfd
[
0
],
SOL_SOCKET
,
SO_PASSCRED
,
&
enable
,
sizeof
(
enable
)
);
}
#endif
wine_server_send_fd
(
socketfd
[
1
]
);
close
(
socketfd
[
1
]
);
SERVER_START_REQ
(
exec_process
)
{
req
->
socket_fd
=
socketfd
[
1
];
req
->
cpu
=
pe_info
.
cpu
;
status
=
wine_server_call
(
req
);
}
SERVER_END_REQ
;
if
(
!
status
)
status
=
exec_loader
(
&
strW
,
socketfd
[
0
],
&
pe_info
);
close
(
socketfd
[
0
]
);
return
status
;
}
/**********************************************************************
* RtlCreateUserProcess (NTDLL.@)
*/
...
...
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