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
5b4f3e8d
Commit
5b4f3e8d
authored
May 01, 2000
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Rewrote Unix process launching to allow passing startup information to
Winelib apps. Improved handling of execve() failures.
parent
045d81f1
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
660 additions
and
362 deletions
+660
-362
process.h
include/process.h
+7
-2
server.h
include/server.h
+14
-7
thread.h
include/thread.h
+2
-3
main.c
loader/main.c
+0
-11
module.c
loader/module.c
+4
-55
environ.c
memory/environ.c
+3
-12
main.c
miscemu/main.c
+13
-0
process.c
scheduler/process.c
+331
-97
thread.c
scheduler/thread.c
+11
-14
process.c
server/process.c
+244
-139
process.h
server/process.h
+1
-4
request.c
server/request.c
+1
-1
request.h
server/request.h
+2
-0
thread.c
server/thread.c
+6
-3
thread.h
server/thread.h
+3
-1
trace.c
server/trace.c
+17
-12
queue.c
windows/queue.c
+1
-1
No files found.
include/process.h
View file @
5b4f3e8d
...
...
@@ -148,8 +148,9 @@ extern DWORD WINAPI GetProcessDword( DWORD dwProcessID, INT offset );
void
WINAPI
SetProcessDword
(
DWORD
dwProcessID
,
INT
offset
,
DWORD
value
);
extern
DWORD
WINAPI
MapProcessHandle
(
HANDLE
handle
);
/* scheduler/environ.c */
extern
BOOL
ENV_InheritEnvironment
(
LPCSTR
env
);
/* memory/environ.c */
extern
BOOL
ENV_BuildEnvironment
(
void
);
extern
BOOL
ENV_InheritEnvironment
(
PDB
*
pdb
,
LPCSTR
env
);
extern
void
ENV_FreeEnvironment
(
PDB
*
pdb
);
/* scheduler/process.c */
...
...
@@ -161,6 +162,10 @@ extern PDB *PROCESS_Create( struct _NE_MODULE *pModule, HFILE hFile,
LPSECURITY_ATTRIBUTES
psa
,
LPSECURITY_ATTRIBUTES
tsa
,
BOOL
inherit
,
DWORD
flags
,
STARTUPINFOA
*
startup
,
PROCESS_INFORMATION
*
info
);
extern
BOOL
PROCESS_CreateUnixProcess
(
LPCSTR
filename
,
LPCSTR
cmd_line
,
LPCSTR
env
,
LPSECURITY_ATTRIBUTES
psa
,
LPSECURITY_ATTRIBUTES
tsa
,
BOOL
inherit
,
DWORD
flags
,
LPSTARTUPINFOA
startup
,
LPPROCESS_INFORMATION
info
);
extern
void
PROCESS_FreePDB
(
PDB
*
pdb
);
extern
void
PROCESS_WalkProcess
(
void
);
...
...
include/server.h
View file @
5b4f3e8d
...
...
@@ -104,8 +104,6 @@ typedef struct
/* Create a new process from the context of the parent */
struct
new_process_request
{
IN
int
pinherit
;
/* process handle inherit flag */
IN
int
tinherit
;
/* thread handle inherit flag */
IN
int
inherit_all
;
/* inherit all handles from parent */
IN
int
create_flags
;
/* creation flags */
IN
int
start_flags
;
/* flags from startup info */
...
...
@@ -114,13 +112,22 @@ struct new_process_request
IN
int
hstdout
;
/* handle for stdout */
IN
int
hstderr
;
/* handle for stderr */
IN
int
cmd_show
;
/* main window show mode */
IN
void
*
env_ptr
;
/* pointer to environment (FIXME: hack) */
IN
int
alloc_fd
;
/* create the fd pair right now? */
};
/* Wait for the new process to start */
struct
wait_process_request
{
IN
int
pinherit
;
/* process handle inherit flag */
IN
int
tinherit
;
/* thread handle inherit flag */
IN
int
timeout
;
/* wait timeout */
IN
int
cancel
;
/* cancel the process creation? */
OUT
void
*
pid
;
/* process id */
OUT
int
phandle
;
/* process handle (in the current process) */
OUT
void
*
tid
;
/* thread id */
OUT
int
thandle
;
/* thread handle (in the current process) */
OUT
int
event
;
/* event handle to signal startup */
IN
char
cmdline
[
1
];
/* command line */
};
...
...
@@ -146,14 +153,13 @@ struct init_process_request
{
IN
void
*
ldt_copy
;
/* addr of LDT copy */
IN
void
*
ldt_flags
;
/* addr of LDT flags */
IN
int
ppid
;
/* parent Unix pid */
OUT
int
start_flags
;
/* flags from startup info */
OUT
int
exe_file
;
/* file handle for main exe */
OUT
int
hstdin
;
/* handle for stdin */
OUT
int
hstdout
;
/* handle for stdout */
OUT
int
hstderr
;
/* handle for stderr */
OUT
int
cmd_show
;
/* main window show mode */
OUT
void
*
env_ptr
;
/* pointer to environment (FIXME: hack) */
OUT
char
cmdline
[
1
];
/* command line */
};
...
...
@@ -1142,6 +1148,7 @@ struct get_atom_name_request
enum
request
{
REQ_NEW_PROCESS
,
REQ_WAIT_PROCESS
,
REQ_NEW_THREAD
,
REQ_BOOT_DONE
,
REQ_INIT_PROCESS
,
...
...
@@ -1246,7 +1253,7 @@ enum request
REQ_NB_REQUESTS
};
#define SERVER_PROTOCOL_VERSION
9
#define SERVER_PROTOCOL_VERSION
10
/* ### make_requests end ### */
/* Everything above this line is generated automatically by tools/make_requests */
...
...
include/thread.h
View file @
5b4f3e8d
...
...
@@ -119,9 +119,8 @@ typedef struct _TEB
/* scheduler/thread.c */
extern
TEB
*
THREAD_CreateInitialThread
(
struct
_PDB
*
pdb
,
int
server_fd
);
extern
TEB
*
THREAD_Create
(
struct
_PDB
*
pdb
,
void
*
pid
,
void
*
tid
,
int
fd
,
DWORD
stack_size
,
BOOL
alloc_stack16
);
extern
TEB
*
THREAD_Init
(
struct
_PDB
*
pdb
);
extern
TEB
*
THREAD_Create
(
struct
_PDB
*
pdb
,
int
fd
,
DWORD
stack_size
,
BOOL
alloc_stack16
);
extern
TEB
*
THREAD_InitStack
(
TEB
*
teb
,
struct
_PDB
*
pdb
,
DWORD
stack_size
,
BOOL
alloc_stack16
);
extern
BOOL
THREAD_IsWin16
(
TEB
*
thdb
);
extern
TEB
*
THREAD_IdToTEB
(
DWORD
id
);
...
...
loader/main.c
View file @
5b4f3e8d
...
...
@@ -62,8 +62,6 @@ DEFAULT_DEBUG_CHANNEL(server);
*/
BOOL
MAIN_MainInit
(
int
argc
,
char
*
argv
[],
BOOL
win32
)
{
char
szGraphicsDriver
[
MAX_PATH
];
/* store the program name */
argv0
=
argv
[
0
];
...
...
@@ -94,15 +92,6 @@ BOOL MAIN_MainInit( int argc, char *argv[], BOOL win32 )
/* Initialize module loadorder */
if
(
!
MODULE_InitLoadOrder
())
return
FALSE
;
/* Initialize KERNEL */
if
(
!
LoadLibraryA
(
"KERNEL32"
))
return
FALSE
;
if
(
PROFILE_GetWineIniString
(
"Wine"
,
"GraphicsDriver"
,
"x11drv"
,
szGraphicsDriver
,
sizeof
(
szGraphicsDriver
)))
{
if
(
!
LoadLibraryA
(
szGraphicsDriver
))
return
FALSE
;
}
return
TRUE
;
}
...
...
loader/module.c
View file @
5b4f3e8d
...
...
@@ -684,60 +684,6 @@ BOOL WINAPI GetBinaryTypeW( LPCWSTR lpApplicationName, LPDWORD lpBinaryType )
return
ret
;
}
/**********************************************************************
* MODULE_CreateUnixProcess
*/
static
BOOL
MODULE_CreateUnixProcess
(
LPCSTR
filename
,
LPCSTR
lpCmdLine
,
LPSTARTUPINFOA
lpStartupInfo
,
LPPROCESS_INFORMATION
lpProcessInfo
)
{
const
char
*
argv
[
256
],
**
argptr
;
char
*
cmdline
=
NULL
;
char
*
p
;
const
char
*
unixfilename
=
filename
;
DOS_FULL_NAME
full_name
;
/* Build argument list */
argptr
=
argv
;
p
=
cmdline
=
strdup
(
lpCmdLine
);
if
(
strchr
(
filename
,
'/'
)
||
strchr
(
filename
,
':'
)
||
strchr
(
filename
,
'\\'
))
{
if
(
DOSFS_GetFullName
(
filename
,
TRUE
,
&
full_name
)
)
unixfilename
=
full_name
.
long_name
;
}
while
(
1
)
{
while
(
*
p
&&
(
*
p
==
' '
||
*
p
==
'\t'
))
*
p
++
=
'\0'
;
if
(
!*
p
)
break
;
*
argptr
++
=
p
;
while
(
*
p
&&
*
p
!=
' '
&&
*
p
!=
'\t'
)
p
++
;
}
*
argptr
++
=
0
;
/* overwrite program name gotten from tidy_cmd */
argv
[
0
]
=
unixfilename
;
/* Fork and execute */
if
(
!
fork
()
)
{
/* Note: don't use Wine routines here, as this process
has not been correctly initialized! */
execvp
(
argv
[
0
],
(
char
**
)
argv
);
exit
(
1
);
}
/* Fake success return value */
memset
(
lpProcessInfo
,
'\0'
,
sizeof
(
*
lpProcessInfo
)
);
lpProcessInfo
->
hProcess
=
INVALID_HANDLE_VALUE
;
lpProcessInfo
->
hThread
=
INVALID_HANDLE_VALUE
;
if
(
cmdline
)
free
(
cmdline
);
SetLastError
(
ERROR_SUCCESS
);
return
TRUE
;
}
/***********************************************************************
* WinExec16 (KERNEL.166)
...
...
@@ -1027,7 +973,10 @@ BOOL WINAPI CreateProcessA( LPCSTR lpApplicationName, LPSTR lpCommandLine,
{
CloseHandle
(
hFile
);
/* FIXME: Try Unix executable only when appropriate! */
retv
=
MODULE_CreateUnixProcess
(
name
,
tidy_cmdline
,
lpStartupInfo
,
lpProcessInfo
);
retv
=
PROCESS_CreateUnixProcess
(
name
,
tidy_cmdline
,
lpEnvironment
,
lpProcessAttributes
,
lpThreadAttributes
,
bInheritHandles
,
dwCreationFlags
,
lpStartupInfo
,
lpProcessInfo
);
goto
done
;
}
...
...
memory/environ.c
View file @
5b4f3e8d
...
...
@@ -67,7 +67,7 @@ static LPCSTR ENV_FindVariable( LPCSTR env, LPCSTR name, INT len )
*
* Build the environment for the initial process
*/
static
BOOL
ENV_BuildEnvironment
(
PDB
*
pdb
)
BOOL
ENV_BuildEnvironment
(
void
)
{
extern
char
**
environ
;
LPSTR
p
,
*
e
;
...
...
@@ -81,7 +81,7 @@ static BOOL ENV_BuildEnvironment( PDB *pdb )
/* Now allocate the environment */
if
(
!
(
p
=
HeapAlloc
(
GetProcessHeap
(),
0
,
size
)))
return
FALSE
;
pdb
->
env_db
->
environ
=
p
;
PROCESS_Current
()
->
env_db
->
environ
=
p
;
/* And fill it with the Unix environment */
...
...
@@ -104,20 +104,11 @@ static BOOL ENV_BuildEnvironment( PDB *pdb )
* Make a process inherit the environment from its parent or from an
* explicit environment.
*/
BOOL
ENV_InheritEnvironment
(
LPCSTR
env
)
BOOL
ENV_InheritEnvironment
(
PDB
*
pdb
,
LPCSTR
env
)
{
DWORD
size
;
LPCSTR
src
;
LPSTR
dst
;
PDB
*
pdb
=
PROCESS_Current
();
/* FIXME: should lock the parent environment */
if
(
!
env
)
{
if
(
!
pdb
->
parent
)
/* initial process */
return
ENV_BuildEnvironment
(
pdb
);
env
=
pdb
->
parent
->
env_db
->
environ
;
}
/* Compute the environment size */
...
...
miscemu/main.c
View file @
5b4f3e8d
...
...
@@ -42,6 +42,13 @@ void MAIN_EmulatorRun( void )
char
startProg
[
256
],
defProg
[
256
];
int
i
,
tasks
=
0
;
MSG
msg
;
char
szGraphicsDriver
[
MAX_PATH
];
if
(
PROFILE_GetWineIniString
(
"Wine"
,
"GraphicsDriver"
,
"x11drv"
,
szGraphicsDriver
,
sizeof
(
szGraphicsDriver
)))
{
if
(
!
LoadLibraryA
(
szGraphicsDriver
))
return
FALSE
;
}
/* Load system DLLs into the initial process (and initialize them) */
if
(
!
LoadLibrary16
(
"GDI.EXE"
)
||
!
LoadLibraryA
(
"GDI32.DLL"
)
...
...
@@ -102,6 +109,12 @@ int main( int argc, char *argv[] )
/* Initialize everything */
if
(
!
MAIN_MainInit
(
argc
,
argv
,
FALSE
))
return
1
;
if
(
!
THREAD_InitStack
(
NtCurrentTeb
(),
PROCESS_Current
(),
0
,
TRUE
))
return
1
;
SIGNAL_Init
();
/* reinitialize signal stack */
/* Initialize KERNEL */
if
(
!
LoadLibraryA
(
"KERNEL32"
))
return
FALSE
;
/* Create initial task */
if
(
!
(
pModule
=
NE_GetPtr
(
GetModuleHandle16
(
"KERNEL"
)
))
)
return
1
;
if
(
!
TASK_Create
(
pModule
,
FALSE
)
)
return
1
;
...
...
scheduler/process.c
View file @
5b4f3e8d
...
...
@@ -5,6 +5,8 @@
*/
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
...
...
@@ -44,31 +46,6 @@ static PDB *PROCESS_First = &initial_pdb;
/***********************************************************************
* PROCESS_WalkProcess
*/
void
PROCESS_WalkProcess
(
void
)
{
PDB
*
pdb
;
char
*
name
;
pdb
=
PROCESS_First
;
MESSAGE
(
" pid PDB #th modref module
\n
"
);
while
(
pdb
)
{
if
(
pdb
==
&
initial_pdb
)
name
=
"initial PDB"
;
else
name
=
(
pdb
->
exe_modref
)
?
pdb
->
exe_modref
->
filename
:
""
;
MESSAGE
(
" %8p %8p %5d %8p %s
\n
"
,
pdb
->
server_pid
,
pdb
,
pdb
->
threads
,
pdb
->
exe_modref
,
name
);
pdb
=
pdb
->
next
;
}
return
;
}
/***********************************************************************
* PROCESS_IdToPDB
*
* Convert a process id to a PDB, making sure it is valid.
...
...
@@ -210,27 +187,15 @@ void PROCESS_CallUserSignalProc( UINT uCode, HMODULE hModule )
static
BOOL
PROCESS_CreateEnvDB
(
void
)
{
struct
init_process_request
*
req
=
get_req_buffer
();
STARTUPINFOA
*
startup
;
ENVDB
*
env_db
;
char
cmd_line
[
4096
];
PDB
*
pdb
=
PROCESS_Current
();
/* Allocate the env DB */
if
(
!
(
env_db
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
ENVDB
)
)))
return
FALSE
;
pdb
->
env_db
=
env_db
;
InitializeCriticalSection
(
&
env_db
->
section
);
/* Allocate and fill the startup info */
if
(
!
(
startup
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
STARTUPINFOA
)
)))
return
FALSE
;
env_db
->
startup_info
=
startup
;
ENVDB
*
env_db
=
pdb
->
env_db
;
STARTUPINFOA
*
startup
=
env_db
->
startup_info
;
/* Retrieve startup info from the server */
req
->
ldt_copy
=
ldt_copy
;
req
->
ldt_flags
=
ldt_flags_copy
;
req
->
ppid
=
getppid
();
if
(
server_call
(
REQ_INIT_PROCESS
))
return
FALSE
;
pdb
->
exe_file
=
req
->
exe_file
;
startup
->
dwFlags
=
req
->
start_flags
;
...
...
@@ -238,16 +203,6 @@ static BOOL PROCESS_CreateEnvDB(void)
env_db
->
hStdin
=
startup
->
hStdInput
=
req
->
hstdin
;
env_db
->
hStdout
=
startup
->
hStdOutput
=
req
->
hstdout
;
env_db
->
hStderr
=
startup
->
hStdError
=
req
->
hstderr
;
lstrcpynA
(
cmd_line
,
req
->
cmdline
,
sizeof
(
cmd_line
)
);
/* Copy the parent environment */
if
(
!
ENV_InheritEnvironment
(
req
->
env_ptr
))
return
FALSE
;
/* Copy the command line */
if
(
!
(
pdb
->
env_db
->
cmd_line
=
HEAP_strdupA
(
GetProcessHeap
(),
0
,
cmd_line
)))
return
FALSE
;
return
TRUE
;
}
...
...
@@ -277,7 +232,8 @@ void PROCESS_FreePDB( PDB *pdb )
*/
static
PDB
*
PROCESS_CreatePDB
(
PDB
*
parent
,
BOOL
inherit
)
{
PDB
*
pdb
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
PDB
)
);
PDB
*
pdb
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
PDB
)
+
sizeof
(
ENVDB
)
+
sizeof
(
STARTUPINFOA
)
);
if
(
!
pdb
)
return
NULL
;
pdb
->
exit_code
=
STILL_ACTIVE
;
...
...
@@ -291,6 +247,11 @@ static PDB *PROCESS_CreatePDB( PDB *parent, BOOL inherit )
pdb
->
next
=
PROCESS_First
;
pdb
->
winver
=
0xffff
;
/* to be determined */
pdb
->
main_queue
=
INVALID_HANDLE_VALUE16
;
pdb
->
env_db
=
(
ENVDB
*
)(
pdb
+
1
);
pdb
->
env_db
->
startup_info
=
(
STARTUPINFOA
*
)(
pdb
->
env_db
+
1
);
InitializeCriticalSection
(
&
pdb
->
env_db
->
section
);
PROCESS_First
=
pdb
;
return
pdb
;
}
...
...
@@ -303,10 +264,6 @@ BOOL PROCESS_Init( BOOL win32 )
{
struct
init_process_request
*
req
;
TEB
*
teb
;
int
server_fd
;
/* Start the server */
server_fd
=
CLIENT_InitServer
();
/* Fill the initial process structure */
initial_pdb
.
exit_code
=
STILL_ACTIVE
;
...
...
@@ -320,12 +277,31 @@ BOOL PROCESS_Init( BOOL win32 )
initial_pdb
.
winver
=
0xffff
;
/* to be determined */
initial_pdb
.
main_queue
=
INVALID_HANDLE_VALUE16
;
initial_envdb
.
startup_info
=
&
initial_startup
;
teb
=
THREAD_Init
(
&
initial_pdb
);
/* Setup the server connection */
teb
->
socket
=
CLIENT_InitServer
();
if
(
CLIENT_InitThread
())
return
FALSE
;
/* Initialize virtual memory management */
if
(
!
VIRTUAL_Init
())
return
FALSE
;
/* Create the initial thread structure and socket pair */
if
(
!
(
teb
=
THREAD_CreateInitialThread
(
&
initial_pdb
,
server_fd
)))
return
FALSE
;
/* Retrieve startup info from the server */
req
=
get_req_buffer
();
req
->
ldt_copy
=
ldt_copy
;
req
->
ldt_flags
=
ldt_flags_copy
;
req
->
ppid
=
getppid
();
if
(
server_call
(
REQ_INIT_PROCESS
))
return
FALSE
;
initial_pdb
.
exe_file
=
req
->
exe_file
;
initial_startup
.
dwFlags
=
req
->
start_flags
;
initial_startup
.
wShowWindow
=
req
->
cmd_show
;
initial_envdb
.
hStdin
=
initial_startup
.
hStdInput
=
req
->
hstdin
;
initial_envdb
.
hStdout
=
initial_startup
.
hStdOutput
=
req
->
hstdout
;
initial_envdb
.
hStderr
=
initial_startup
.
hStdError
=
req
->
hstderr
;
initial_envdb
.
cmd_line
=
""
;
/* Initialize signal handling */
if
(
!
SIGNAL_Init
())
return
FALSE
;
/* Remember TEB selector of initial process for emergency use */
SYSLEVEL_EmergencyTeb
=
teb
->
teb_sel
;
...
...
@@ -342,24 +318,8 @@ BOOL PROCESS_Init( BOOL win32 )
initial_pdb
.
idle_event
=
CreateEventA
(
NULL
,
TRUE
,
FALSE
,
NULL
);
initial_pdb
.
idle_event
=
ConvertToGlobalHandle
(
initial_pdb
.
idle_event
);
/* Initialize signal handling */
if
(
!
SIGNAL_Init
())
return
FALSE
;
/* Retrieve startup info from the server */
req
=
get_req_buffer
();
req
->
ldt_copy
=
ldt_copy
;
req
->
ldt_flags
=
ldt_flags_copy
;
if
(
server_call
(
REQ_INIT_PROCESS
))
return
FALSE
;
initial_pdb
.
exe_file
=
req
->
exe_file
;
initial_startup
.
dwFlags
=
req
->
start_flags
;
initial_startup
.
wShowWindow
=
req
->
cmd_show
;
initial_envdb
.
hStdin
=
initial_startup
.
hStdInput
=
req
->
hstdin
;
initial_envdb
.
hStdout
=
initial_startup
.
hStdOutput
=
req
->
hstdout
;
initial_envdb
.
hStderr
=
initial_startup
.
hStdError
=
req
->
hstderr
;
initial_envdb
.
cmd_line
=
""
;
/* Copy the parent environment */
if
(
!
ENV_
InheritEnvironment
(
NULL
))
return
FALSE
;
if
(
!
ENV_
BuildEnvironment
(
))
return
FALSE
;
/* Create the SEGPTR heap */
if
(
!
(
SegptrHeap
=
HeapCreate
(
HEAP_WINE_SEGPTR
,
0
,
0
)))
return
FALSE
;
...
...
@@ -373,6 +333,33 @@ BOOL PROCESS_Init( BOOL win32 )
/***********************************************************************
* load_system_dlls
*
* Load system DLLs into the initial process (and initialize them)
*/
static
int
load_system_dlls
(
void
)
{
char
driver
[
MAX_PATH
];
if
(
!
LoadLibraryA
(
"KERNEL32"
))
return
0
;
PROFILE_GetWineIniString
(
"Wine"
,
"GraphicsDriver"
,
"x11drv"
,
driver
,
sizeof
(
driver
)
);
if
(
!
LoadLibraryA
(
driver
))
{
MESSAGE
(
"Could not load graphics driver '%s'
\n
"
,
driver
);
return
0
;
}
if
(
!
LoadLibraryA
(
"GDI32.DLL"
))
return
0
;
if
(
!
LoadLibrary16
(
"GDI.EXE"
))
return
0
;
if
(
!
LoadLibrary16
(
"USER.EXE"
))
return
0
;
if
(
!
LoadLibraryA
(
"USER32.DLL"
))
return
0
;
return
1
;
}
/***********************************************************************
* start_process
*
* Startup routine of a new Win32 process. Runs on the new process stack.
...
...
@@ -409,13 +396,8 @@ static void start_process(void)
if
(
pdb
->
flags
&
PDB32_CONSOLE_PROC
)
AllocConsole
();
/* Load system DLLs into the initial process (and initialize them) */
if
(
!
LoadLibraryA
(
"KERNEL32"
))
goto
error
;
if
(
!
LoadLibraryA
(
"x11drv"
))
goto
error
;
if
(
!
LoadLibrary16
(
"GDI.EXE"
)
||
!
LoadLibraryA
(
"GDI32.DLL"
)
||
!
LoadLibrary16
(
"USER.EXE"
)
||
!
LoadLibraryA
(
"USER32.DLL"
))
goto
error
;
/* Load the system dlls */
if
(
!
load_system_dlls
())
goto
error
;
/* Get pointers to USER routines called by KERNEL */
THUNK_InitCallout
();
...
...
@@ -548,6 +530,250 @@ void PROCESS_InitWinelib( int argc, char *argv[] )
/***********************************************************************
* build_argv
*
* Build an argv array from a command-line.
* The command-line is modified to insert nulls.
*/
static
char
**
build_argv
(
char
*
cmdline
,
char
*
argv0
)
{
char
**
argv
;
int
count
=
1
;
char
*
p
=
cmdline
;
while
(
*
p
)
{
while
(
*
p
&&
isspace
(
*
p
))
p
++
;
if
(
!*
p
)
break
;
count
++
;
while
(
*
p
&&
!
isspace
(
*
p
))
p
++
;
}
if
(
argv0
)
count
++
;
if
((
argv
=
malloc
(
count
*
sizeof
(
*
argv
)
)))
{
char
**
argvptr
=
argv
;
if
(
argv0
)
*
argvptr
++
=
argv0
;
p
=
cmdline
;
while
(
*
p
)
{
while
(
*
p
&&
isspace
(
*
p
))
*
p
++
=
0
;
if
(
!*
p
)
break
;
*
argvptr
++
=
p
;
while
(
*
p
&&
!
isspace
(
*
p
))
p
++
;
}
*
argvptr
=
0
;
}
return
argv
;
}
/***********************************************************************
* build_envp
*
* Build the environment of a new child process.
*/
static
char
**
build_envp
(
const
char
*
env
)
{
const
char
*
p
;
char
**
envp
;
int
count
;
for
(
p
=
env
,
count
=
0
;
*
p
;
count
++
)
p
+=
strlen
(
p
)
+
1
;
count
+=
3
;
if
((
envp
=
malloc
(
count
*
sizeof
(
*
envp
)
)))
{
extern
char
**
environ
;
char
**
envptr
=
envp
;
char
**
unixptr
=
environ
;
/* first put PATH, HOME and WINEPREFIX from the unix env */
for
(
unixptr
=
environ
;
unixptr
&&
*
unixptr
;
unixptr
++
)
if
(
!
memcmp
(
*
unixptr
,
"PATH="
,
5
)
||
!
memcmp
(
*
unixptr
,
"HOME="
,
5
)
||
!
memcmp
(
*
unixptr
,
"WINEPREFIX="
,
11
))
*
envptr
++
=
*
unixptr
;
/* now put the Windows environment strings */
for
(
p
=
env
;
*
p
;
p
+=
strlen
(
p
)
+
1
)
{
if
(
memcmp
(
p
,
"PATH="
,
5
)
&&
memcmp
(
p
,
"HOME="
,
5
)
&&
memcmp
(
p
,
"WINEPREFIX="
,
11
))
*
envptr
++
=
(
char
*
)
p
;
}
*
envptr
=
0
;
}
return
envp
;
}
/***********************************************************************
* find_wine_binary
*
* Locate the Wine binary to exec for a new Win32 process.
*/
static
void
exec_wine_binary
(
char
**
argv
,
char
**
envp
)
{
const
char
*
path
,
*
pos
,
*
ptr
;
/* first try bin directory */
argv
[
0
]
=
BINDIR
"/wine"
;
execve
(
argv
[
0
],
argv
,
envp
);
/* now try the path of argv0 of the current binary */
if
(
!
(
argv
[
0
]
=
malloc
(
strlen
(
argv0
)
+
6
)))
return
;
if
((
ptr
=
strrchr
(
argv0
,
'/'
)))
{
memcpy
(
argv
[
0
],
argv0
,
ptr
-
argv0
);
strcpy
(
argv
[
0
]
+
(
ptr
-
argv0
),
"/wine"
);
execve
(
argv
[
0
],
argv
,
envp
);
}
free
(
argv
[
0
]
);
/* now search in the Unix path */
if
((
path
=
getenv
(
"PATH"
)))
{
if
(
!
(
argv
[
0
]
=
malloc
(
strlen
(
path
)
+
6
)))
return
;
pos
=
path
;
for
(;;)
{
while
(
*
pos
==
':'
)
pos
++
;
if
(
!*
pos
)
break
;
if
(
!
(
ptr
=
strchr
(
pos
,
':'
)))
ptr
=
pos
+
strlen
(
pos
);
memcpy
(
argv
[
0
],
pos
,
ptr
-
pos
);
strcpy
(
argv
[
0
]
+
(
ptr
-
pos
),
"/wine"
);
execve
(
argv
[
0
],
argv
,
envp
);
pos
=
ptr
;
}
}
free
(
argv
[
0
]
);
/* finally try the current directory */
argv
[
0
]
=
"./wine"
;
execve
(
argv
[
0
],
argv
,
envp
);
}
/***********************************************************************
* fork_and_exec
*
* Fork and exec a new Unix process, checking for errors.
*/
static
int
fork_and_exec
(
const
char
*
filename
,
const
char
*
cmdline
,
const
char
*
env
)
{
int
fd
[
2
];
int
pid
,
err
;
if
(
pipe
(
fd
)
==
-
1
)
{
FILE_SetDosError
();
return
-
1
;
}
fcntl
(
fd
[
1
],
F_SETFD
,
1
);
/* set close on exec */
if
(
!
(
pid
=
fork
()))
/* child */
{
char
**
argv
=
build_argv
(
(
char
*
)
cmdline
,
NULL
);
char
**
envp
=
build_envp
(
env
);
close
(
fd
[
0
]
);
if
(
argv
&&
envp
)
execve
(
filename
,
argv
,
envp
);
err
=
errno
;
write
(
fd
[
1
],
&
err
,
sizeof
(
err
)
);
_exit
(
1
);
}
close
(
fd
[
1
]
);
if
((
pid
!=
-
1
)
&&
(
read
(
fd
[
0
],
&
err
,
sizeof
(
err
)
)
>
0
))
/* exec failed */
{
errno
=
err
;
pid
=
-
1
;
}
if
(
pid
==
-
1
)
FILE_SetDosError
();
close
(
fd
[
0
]
);
return
pid
;
}
/***********************************************************************
* PROCESS_CreateUnixProcess
*/
BOOL
PROCESS_CreateUnixProcess
(
LPCSTR
filename
,
LPCSTR
cmd_line
,
LPCSTR
env
,
LPSECURITY_ATTRIBUTES
psa
,
LPSECURITY_ATTRIBUTES
tsa
,
BOOL
inherit
,
DWORD
flags
,
LPSTARTUPINFOA
startup
,
LPPROCESS_INFORMATION
info
)
{
int
pid
;
const
char
*
unixfilename
=
filename
;
DOS_FULL_NAME
full_name
;
HANDLE
load_done_evt
=
-
1
;
struct
new_process_request
*
req
=
get_req_buffer
();
struct
wait_process_request
*
wait_req
=
get_req_buffer
();
info
->
hThread
=
info
->
hProcess
=
INVALID_HANDLE_VALUE
;
if
(
DOSFS_GetFullName
(
filename
,
TRUE
,
&
full_name
))
unixfilename
=
full_name
.
long_name
;
/* create the process on the server side */
req
->
inherit_all
=
inherit
;
req
->
create_flags
=
flags
;
req
->
start_flags
=
startup
->
dwFlags
;
req
->
exe_file
=
-
1
;
if
(
startup
->
dwFlags
&
STARTF_USESTDHANDLES
)
{
req
->
hstdin
=
startup
->
hStdInput
;
req
->
hstdout
=
startup
->
hStdOutput
;
req
->
hstderr
=
startup
->
hStdError
;
}
else
{
req
->
hstdin
=
GetStdHandle
(
STD_INPUT_HANDLE
);
req
->
hstdout
=
GetStdHandle
(
STD_OUTPUT_HANDLE
);
req
->
hstderr
=
GetStdHandle
(
STD_ERROR_HANDLE
);
}
req
->
cmd_show
=
startup
->
wShowWindow
;
req
->
alloc_fd
=
0
;
if
(
server_call
(
REQ_NEW_PROCESS
))
return
FALSE
;
/* fork and execute */
pid
=
fork_and_exec
(
unixfilename
,
cmd_line
,
env
?
env
:
GetEnvironmentStringsA
()
);
wait_req
->
cancel
=
(
pid
==
-
1
);
wait_req
->
pinherit
=
(
psa
&&
(
psa
->
nLength
>=
sizeof
(
*
psa
))
&&
psa
->
bInheritHandle
);
wait_req
->
tinherit
=
(
tsa
&&
(
tsa
->
nLength
>=
sizeof
(
*
tsa
))
&&
tsa
->
bInheritHandle
);
wait_req
->
timeout
=
2000
;
if
(
server_call
(
REQ_WAIT_PROCESS
)
||
(
pid
==
-
1
))
goto
error
;
info
->
dwProcessId
=
(
DWORD
)
wait_req
->
pid
;
info
->
dwThreadId
=
(
DWORD
)
wait_req
->
tid
;
info
->
hProcess
=
wait_req
->
phandle
;
info
->
hThread
=
wait_req
->
thandle
;
load_done_evt
=
wait_req
->
event
;
/* Wait until process is initialized (or initialization failed) */
if
(
load_done_evt
!=
-
1
)
{
DWORD
res
;
HANDLE
handles
[
2
];
handles
[
0
]
=
info
->
hProcess
;
handles
[
1
]
=
load_done_evt
;
res
=
WaitForMultipleObjects
(
2
,
handles
,
FALSE
,
INFINITE
);
CloseHandle
(
load_done_evt
);
if
(
res
==
STATUS_WAIT_0
)
/* the process died */
{
DWORD
exitcode
;
if
(
GetExitCodeProcess
(
info
->
hProcess
,
&
exitcode
))
SetLastError
(
exitcode
);
CloseHandle
(
info
->
hThread
);
CloseHandle
(
info
->
hProcess
);
return
FALSE
;
}
}
return
TRUE
;
error:
if
(
load_done_evt
!=
-
1
)
CloseHandle
(
load_done_evt
);
if
(
info
->
hThread
!=
INVALID_HANDLE_VALUE
)
CloseHandle
(
info
->
hThread
);
if
(
info
->
hProcess
!=
INVALID_HANDLE_VALUE
)
CloseHandle
(
info
->
hProcess
);
return
FALSE
;
}
/***********************************************************************
* PROCESS_Start
*
* Startup routine of a new process. Called in the context of the new process.
...
...
@@ -691,6 +917,7 @@ PDB *PROCESS_Create( NE_MODULE *pModule, HFILE hFile, LPCSTR cmd_line, LPCSTR en
BOOL
alloc_stack16
;
int
fd
=
-
1
;
struct
new_process_request
*
req
=
get_req_buffer
();
struct
wait_process_request
*
wait_req
=
get_req_buffer
();
TEB
*
teb
=
NULL
;
PDB
*
parent
=
PROCESS_Current
();
PDB
*
pdb
=
PROCESS_CreatePDB
(
parent
,
inherit
);
...
...
@@ -698,10 +925,11 @@ PDB *PROCESS_Create( NE_MODULE *pModule, HFILE hFile, LPCSTR cmd_line, LPCSTR en
if
(
!
pdb
)
return
NULL
;
info
->
hThread
=
info
->
hProcess
=
INVALID_HANDLE_VALUE
;
if
(
!
(
pdb
->
env_db
->
cmd_line
=
HEAP_strdupA
(
GetProcessHeap
(),
0
,
cmd_line
)))
goto
error
;
if
(
!
ENV_InheritEnvironment
(
pdb
,
env
?
env
:
GetEnvironmentStringsA
()
))
goto
error
;
/* Create the process on the server side */
req
->
pinherit
=
(
psa
&&
(
psa
->
nLength
>=
sizeof
(
*
psa
))
&&
psa
->
bInheritHandle
);
req
->
tinherit
=
(
tsa
&&
(
tsa
->
nLength
>=
sizeof
(
*
tsa
))
&&
tsa
->
bInheritHandle
);
req
->
inherit_all
=
2
/*inherit*/
;
/* HACK! */
req
->
create_flags
=
flags
;
req
->
start_flags
=
startup
->
dwFlags
;
...
...
@@ -719,15 +947,8 @@ PDB *PROCESS_Create( NE_MODULE *pModule, HFILE hFile, LPCSTR cmd_line, LPCSTR en
req
->
hstderr
=
GetStdHandle
(
STD_ERROR_HANDLE
);
}
req
->
cmd_show
=
startup
->
wShowWindow
;
req
->
env_ptr
=
(
void
*
)
env
;
/* FIXME: hack */
lstrcpynA
(
req
->
cmdline
,
cmd_line
,
server_remaining
(
req
->
cmdline
)
);
req
->
alloc_fd
=
1
;
if
(
server_call_fd
(
REQ_NEW_PROCESS
,
-
1
,
&
fd
))
goto
error
;
pdb
->
server_pid
=
req
->
pid
;
info
->
hProcess
=
req
->
phandle
;
info
->
dwProcessId
=
(
DWORD
)
req
->
pid
;
info
->
hThread
=
req
->
thandle
;
info
->
dwThreadId
=
(
DWORD
)
req
->
tid
;
load_done_evt
=
req
->
event
;
if
(
pModule
->
module32
)
/* Win32 process */
{
...
...
@@ -752,13 +973,26 @@ PDB *PROCESS_Create( NE_MODULE *pModule, HFILE hFile, LPCSTR cmd_line, LPCSTR en
/* Create the main thread */
if
(
!
(
teb
=
THREAD_Create
(
pdb
,
req
->
pid
,
req
->
tid
,
fd
,
size
,
alloc_stack16
)))
goto
error
;
teb
->
startup
=
PROCESS_Start
;
fd
=
-
1
;
/* don't close it */
if
((
teb
=
THREAD_Create
(
pdb
,
fd
,
size
,
alloc_stack16
)))
{
teb
->
startup
=
PROCESS_Start
;
fd
=
-
1
;
/* don't close it */
/* Pass module to new process (FIXME: hack) */
pdb
->
module
=
pModule
->
self
;
SYSDEPS_SpawnThread
(
teb
);
}
/* Pass module to new process (FIXME: hack) */
pdb
->
module
=
pModule
->
self
;
SYSDEPS_SpawnThread
(
teb
);
wait_req
->
cancel
=
!
teb
;
wait_req
->
pinherit
=
(
psa
&&
(
psa
->
nLength
>=
sizeof
(
*
psa
))
&&
psa
->
bInheritHandle
);
wait_req
->
tinherit
=
(
tsa
&&
(
tsa
->
nLength
>=
sizeof
(
*
tsa
))
&&
tsa
->
bInheritHandle
);
wait_req
->
timeout
=
2000
;
if
(
server_call
(
REQ_WAIT_PROCESS
)
||
!
teb
)
goto
error
;
info
->
dwProcessId
=
(
DWORD
)
wait_req
->
pid
;
info
->
dwThreadId
=
(
DWORD
)
wait_req
->
tid
;
info
->
hProcess
=
wait_req
->
phandle
;
info
->
hThread
=
wait_req
->
thandle
;
load_done_evt
=
wait_req
->
event
;
/* Wait until process is initialized (or initialization failed) */
handles
[
0
]
=
info
->
hProcess
;
...
...
scheduler/thread.c
View file @
5b4f3e8d
...
...
@@ -85,6 +85,8 @@ static BOOL THREAD_InitTEB( TEB *teb, PDB *pdb )
teb
->
process
=
pdb
;
teb
->
exit_code
=
STILL_ACTIVE
;
teb
->
socket
=
-
1
;
teb
->
stack_top
=
(
void
*
)
~
0UL
;
teb
->
StaticUnicodeString
.
MaximumLength
=
sizeof
(
teb
->
StaticUnicodeBuffer
);
teb
->
StaticUnicodeString
.
Buffer
=
(
PWSTR
)
teb
->
StaticUnicodeBuffer
;
teb
->
teb_sel
=
SELECTOR_AllocBlock
(
teb
,
0x1000
,
SEGMENT_DATA
,
TRUE
,
FALSE
);
...
...
@@ -194,20 +196,17 @@ error:
/***********************************************************************
* THREAD_
CreateInitialThread
* THREAD_
Init
*
*
Create
the initial thread.
*
Setup
the initial thread.
*
* NOTES: The first allocated TEB on NT is at 0x7ffde000.
*/
TEB
*
THREAD_
CreateInitialThread
(
PDB
*
pdb
,
int
server_fd
)
TEB
*
THREAD_
Init
(
struct
_PDB
*
pdb
)
{
if
(
!
THREAD_InitTEB
(
&
initial_teb
,
pdb
))
return
NULL
;
SYSDEPS_SetCurThread
(
&
initial_teb
);
initial_teb
.
socket
=
server_fd
;
if
(
CLIENT_InitThread
())
return
NULL
;
return
THREAD_InitStack
(
&
initial_teb
,
pdb
,
0
,
TRUE
);
return
&
initial_teb
;
}
...
...
@@ -215,15 +214,12 @@ TEB *THREAD_CreateInitialThread( PDB *pdb, int server_fd )
* THREAD_Create
*
*/
TEB
*
THREAD_Create
(
PDB
*
pdb
,
void
*
pid
,
void
*
tid
,
int
fd
,
DWORD
stack_size
,
BOOL
alloc_stack16
)
TEB
*
THREAD_Create
(
PDB
*
pdb
,
int
fd
,
DWORD
stack_size
,
BOOL
alloc_stack16
)
{
TEB
*
teb
;
if
((
teb
=
THREAD_InitStack
(
NULL
,
pdb
,
stack_size
,
alloc_stack16
)))
{
teb
->
pid
=
pid
;
teb
->
tid
=
tid
;
teb
->
socket
=
fd
;
fcntl
(
fd
,
F_SETFD
,
1
);
/* set close on exec flag */
TRACE
(
"(%p) succeeded
\n
"
,
teb
);
...
...
@@ -266,14 +262,15 @@ HANDLE WINAPI CreateThread( SECURITY_ATTRIBUTES *sa, DWORD stack,
struct
new_thread_request
*
req
=
get_req_buffer
();
int
socket
,
handle
=
-
1
;
TEB
*
teb
;
void
*
tid
;
req
->
suspend
=
((
flags
&
CREATE_SUSPENDED
)
!=
0
);
req
->
inherit
=
(
sa
&&
(
sa
->
nLength
>=
sizeof
(
*
sa
))
&&
sa
->
bInheritHandle
);
if
(
server_call_fd
(
REQ_NEW_THREAD
,
-
1
,
&
socket
))
return
0
;
handle
=
req
->
handle
;
tid
=
req
->
tid
;
if
(
!
(
teb
=
THREAD_Create
(
PROCESS_Current
(),
(
void
*
)
GetCurrentProcessId
(),
req
->
tid
,
socket
,
stack
,
TRUE
)))
if
(
!
(
teb
=
THREAD_Create
(
PROCESS_Current
(),
socket
,
stack
,
TRUE
)))
{
close
(
socket
);
return
0
;
...
...
@@ -282,7 +279,7 @@ HANDLE WINAPI CreateThread( SECURITY_ATTRIBUTES *sa, DWORD stack,
teb
->
entry_point
=
start
;
teb
->
entry_arg
=
param
;
teb
->
startup
=
THREAD_Start
;
if
(
id
)
*
id
=
(
DWORD
)
t
eb
->
t
id
;
if
(
id
)
*
id
=
(
DWORD
)
tid
;
if
(
SYSDEPS_SpawnThread
(
teb
)
==
-
1
)
{
CloseHandle
(
handle
);
...
...
server/process.c
View file @
5b4f3e8d
...
...
@@ -55,47 +55,54 @@ static const struct object_ops process_ops =
process_destroy
/* destroy */
};
/* set the process creation info */
static
int
set_creation_info
(
struct
process
*
process
,
struct
new_process_request
*
req
,
const
char
*
cmd_line
,
size_t
len
)
{
if
(
!
(
process
->
info
=
mem_alloc
(
sizeof
(
*
process
->
info
)
+
len
)))
return
0
;
if
(
req
)
{
/* copy the request structure */
memcpy
(
process
->
info
,
req
,
sizeof
(
*
req
)
);
}
else
/* no request, use defaults */
{
req
=
process
->
info
;
req
->
pinherit
=
0
;
req
->
tinherit
=
0
;
req
->
inherit_all
=
0
;
req
->
create_flags
=
CREATE_NEW_CONSOLE
;
req
->
start_flags
=
STARTF_USESTDHANDLES
;
req
->
exe_file
=
-
1
;
req
->
hstdin
=
-
1
;
req
->
hstdout
=
-
1
;
req
->
hstderr
=
-
1
;
req
->
cmd_show
=
0
;
req
->
env_ptr
=
NULL
;
}
memcpy
(
process
->
info
->
cmdline
,
cmd_line
,
len
);
process
->
info
->
cmdline
[
len
]
=
0
;
process
->
create_flags
=
process
->
info
->
create_flags
;
return
1
;
}
/* process startup info */
struct
startup_info
{
struct
object
obj
;
/* object header */
int
inherit_all
;
/* inherit all handles from parent */
int
create_flags
;
/* creation flags */
int
start_flags
;
/* flags from startup info */
int
exe_file
;
/* file handle for main exe */
int
hstdin
;
/* handle for stdin */
int
hstdout
;
/* handle for stdout */
int
hstderr
;
/* handle for stderr */
int
cmd_show
;
/* main window show mode */
struct
process
*
process
;
/* created process */
struct
thread
*
thread
;
/* created thread */
};
static
void
startup_info_dump
(
struct
object
*
obj
,
int
verbose
);
static
int
startup_info_signaled
(
struct
object
*
obj
,
struct
thread
*
thread
);
static
void
startup_info_destroy
(
struct
object
*
obj
);
static
const
struct
object_ops
startup_info_ops
=
{
sizeof
(
struct
startup_info
),
/* size */
startup_info_dump
,
/* dump */
add_queue
,
/* add_queue */
remove_queue
,
/* remove_queue */
startup_info_signaled
,
/* signaled */
no_satisfied
,
/* satisfied */
NULL
,
/* get_poll_events */
NULL
,
/* poll_event */
no_read_fd
,
/* get_read_fd */
no_write_fd
,
/* get_write_fd */
no_flush
,
/* flush */
no_get_file_info
,
/* get_file_info */
startup_info_destroy
/* destroy */
};
/* set the console and stdio handles for a newly created process */
static
int
set_process_console
(
struct
process
*
process
,
struct
process
*
parent
)
static
int
set_process_console
(
struct
process
*
process
,
struct
process
*
parent
,
struct
startup_info
*
info
,
struct
init_process_request
*
req
)
{
struct
new_process_request
*
info
=
process
->
info
;
if
(
process
->
create_flags
&
CREATE_NEW_CONSOLE
)
{
if
(
!
alloc_console
(
process
))
return
0
;
}
else
if
(
!
(
process
->
create_flags
&
DETACHED_PROCESS
))
else
if
(
parent
&&
!
(
process
->
create_flags
&
DETACHED_PROCESS
))
{
if
(
parent
->
console_in
)
process
->
console_in
=
grab_object
(
parent
->
console_in
);
if
(
parent
->
console_out
)
process
->
console_out
=
grab_object
(
parent
->
console_out
);
...
...
@@ -105,31 +112,35 @@ static int set_process_console( struct process *process, struct process *parent
if
(
!
info
->
inherit_all
&&
!
(
info
->
start_flags
&
STARTF_USESTDHANDLES
))
{
/* duplicate the handle from the parent into this process */
info
->
hstdin
=
duplicate_handle
(
parent
,
info
->
hstdin
,
process
,
0
,
TRUE
,
DUPLICATE_SAME_ACCESS
);
info
->
hstdout
=
duplicate_handle
(
parent
,
info
->
hstdout
,
process
,
0
,
TRUE
,
DUPLICATE_SAME_ACCESS
);
info
->
hstderr
=
duplicate_handle
(
parent
,
info
->
hstderr
,
process
,
0
,
TRUE
,
DUPLICATE_SAME_ACCESS
);
req
->
hstdin
=
duplicate_handle
(
parent
,
info
->
hstdin
,
process
,
0
,
TRUE
,
DUPLICATE_SAME_ACCESS
);
req
->
hstdout
=
duplicate_handle
(
parent
,
info
->
hstdout
,
process
,
0
,
TRUE
,
DUPLICATE_SAME_ACCESS
);
req
->
hstderr
=
duplicate_handle
(
parent
,
info
->
hstderr
,
process
,
0
,
TRUE
,
DUPLICATE_SAME_ACCESS
);
}
else
{
req
->
hstdin
=
info
->
hstdin
;
req
->
hstdout
=
info
->
hstdout
;
req
->
hstderr
=
info
->
hstderr
;
}
}
else
{
/* no parent, use handles to the console for stdio */
info
->
hstdin
=
alloc_handle
(
process
,
process
->
console_in
,
GENERIC_READ
|
GENERIC_WRITE
|
SYNCHRONIZE
,
1
);
info
->
hstdout
=
alloc_handle
(
process
,
process
->
console_out
,
GENERIC_READ
|
GENERIC_WRITE
|
SYNCHRONIZE
,
1
);
info
->
hstderr
=
alloc_handle
(
process
,
process
->
console_out
,
GENERIC_READ
|
GENERIC_WRITE
|
SYNCHRONIZE
,
1
);
req
->
hstdin
=
alloc_handle
(
process
,
process
->
console_in
,
GENERIC_READ
|
GENERIC_WRITE
|
SYNCHRONIZE
,
1
);
req
->
hstdout
=
alloc_handle
(
process
,
process
->
console_out
,
GENERIC_READ
|
GENERIC_WRITE
|
SYNCHRONIZE
,
1
);
req
->
hstderr
=
alloc_handle
(
process
,
process
->
console_out
,
GENERIC_READ
|
GENERIC_WRITE
|
SYNCHRONIZE
,
1
);
}
return
1
;
}
/* create a new process and its main thread */
struct
thread
*
create_process
(
int
fd
,
struct
process
*
parent
,
struct
new_process_request
*
req
,
const
char
*
cmd_line
,
size_t
len
)
struct
thread
*
create_process
(
int
fd
)
{
struct
process
*
process
;
struct
thread
*
thread
=
NULL
;
...
...
@@ -153,7 +164,6 @@ struct thread *create_process( int fd, struct process *parent,
process
->
console_in
=
NULL
;
process
->
console_out
=
NULL
;
process
->
init_event
=
NULL
;
process
->
info
=
NULL
;
process
->
ldt_copy
=
NULL
;
process
->
ldt_flags
=
NULL
;
process
->
exe
.
next
=
NULL
;
...
...
@@ -165,52 +175,97 @@ struct thread *create_process( int fd, struct process *parent,
if
((
process
->
next
=
first_process
)
!=
NULL
)
process
->
next
->
prev
=
process
;
first_process
=
process
;
/* copy the request structure */
if
(
!
set_creation_info
(
process
,
req
,
cmd_line
,
len
))
goto
error
;
/* create the main thread */
if
(
!
(
thread
=
create_thread
(
fd
,
process
)))
goto
error
;
/* create the init done event */
if
(
!
(
process
->
init_event
=
create_event
(
NULL
,
0
,
1
,
0
)))
goto
error
;
add_process_thread
(
process
,
thread
);
release_object
(
process
);
return
thread
;
error:
if
(
thread
)
release_object
(
thread
);
release_object
(
process
);
return
NULL
;
}
/* initialize the current process and fill in the request */
static
void
init_process
(
int
ppid
,
struct
init_process_request
*
req
)
{
struct
process
*
process
=
current
->
process
;
struct
thread
*
parent_thread
=
get_thread_from_pid
(
ppid
);
struct
process
*
parent
=
NULL
;
struct
startup_info
*
info
=
NULL
;
if
(
process
->
info
->
inherit_all
==
2
)
/* HACK! */
if
(
parent_thread
)
{
parent
=
parent_thread
->
process
;
info
=
parent_thread
->
info
;
if
(
!
info
)
{
fatal_protocol_error
(
current
,
"init_process: parent but no info
\n
"
);
return
;
}
if
(
info
->
thread
)
{
fatal_protocol_error
(
current
,
"init_process: called twice?
\n
"
);
return
;
}
}
/* set the process flags */
process
->
create_flags
=
info
?
info
->
create_flags
:
CREATE_NEW_CONSOLE
;
/* create the handle table */
if
(
parent
&&
info
->
inherit_all
==
2
)
/* HACK! */
process
->
handles
=
grab_object
(
parent
->
handles
);
else
if
(
p
rocess
->
info
->
inherit_all
)
else
if
(
p
arent
&&
info
->
inherit_all
)
process
->
handles
=
copy_handle_table
(
process
,
parent
);
else
process
->
handles
=
alloc_handle_table
(
process
,
0
);
if
(
!
process
->
handles
)
goto
error
;
/* retrieve the main exe file */
if
(
process
->
info
->
exe_file
!=
-
1
)
req
->
exe_file
=
-
1
;
if
(
parent
&&
info
->
exe_file
!=
-
1
)
{
if
(
!
(
process
->
exe
.
file
=
get_file_obj
(
parent
,
process
->
info
->
exe_file
,
GENERIC_READ
)))
goto
error
;
process
->
info
->
exe_file
=
-
1
;
if
(
!
(
process
->
exe
.
file
=
get_file_obj
(
parent
,
info
->
exe_file
,
GENERIC_READ
)))
goto
error
;
if
((
req
->
exe_file
=
alloc_handle
(
process
,
process
->
exe
.
file
,
GENERIC_READ
,
0
))
==
-
1
)
goto
error
;
}
/* create the main thread */
if
(
!
(
thread
=
create_thread
(
fd
,
process
,
(
process
->
create_flags
&
CREATE_SUSPENDED
)
!=
0
)))
goto
error
;
/* create the init done event */
if
(
!
(
process
->
init_event
=
create_event
(
NULL
,
0
,
1
,
0
)))
goto
error
;
/* set the process console */
if
(
!
set_process_console
(
process
,
parent
))
goto
error
;
if
(
!
set_process_console
(
process
,
parent
,
info
,
req
))
goto
error
;
/* attach to the debugger if requested */
if
(
process
->
create_flags
&
(
DEBUG_PROCESS
|
DEBUG_ONLY_THIS_PROCESS
))
set_process_debugger
(
process
,
current
);
else
if
(
parent
&&
parent
->
debugger
&&
!
(
parent
->
create_flags
&
DEBUG_ONLY_THIS_PROCESS
))
set_process_debugger
(
process
,
parent
->
debugger
);
if
(
parent
)
{
/* attach to the debugger if requested */
if
(
process
->
create_flags
&
(
DEBUG_PROCESS
|
DEBUG_ONLY_THIS_PROCESS
))
set_process_debugger
(
process
,
parent_thread
);
else
if
(
parent
&&
parent
->
debugger
&&
!
(
parent
->
create_flags
&
DEBUG_ONLY_THIS_PROCESS
))
set_process_debugger
(
process
,
parent
->
debugger
);
}
add_process_thread
(
process
,
thread
);
release_object
(
process
);
return
thread
;
/* thread will be actually suspended in init_done */
if
(
process
->
create_flags
&
CREATE_SUSPENDED
)
current
->
suspend
++
;
if
(
info
)
{
req
->
start_flags
=
info
->
start_flags
;
req
->
cmd_show
=
info
->
cmd_show
;
info
->
process
=
(
struct
process
*
)
grab_object
(
process
);
info
->
thread
=
(
struct
thread
*
)
grab_object
(
current
);
wake_up
(
&
info
->
obj
,
0
);
}
else
{
req
->
start_flags
=
STARTF_USESTDHANDLES
;
req
->
cmd_show
=
0
;
}
error:
close
(
fd
);
free_console
(
process
);
if
(
process
->
handles
)
release_object
(
process
->
handles
);
if
(
thread
)
release_object
(
thread
);
release_object
(
process
);
return
NULL
;
}
/* destroy a process when its refcount is 0 */
...
...
@@ -224,7 +279,6 @@ static void process_destroy( struct object *obj )
if
(
process
->
next
)
process
->
next
->
prev
=
process
->
prev
;
if
(
process
->
prev
)
process
->
prev
->
next
=
process
->
next
;
else
first_process
=
process
->
next
;
if
(
process
->
info
)
free
(
process
->
info
);
if
(
process
->
init_event
)
release_object
(
process
->
init_event
);
if
(
process
->
exe
.
file
)
release_object
(
process
->
exe
.
file
);
}
...
...
@@ -247,6 +301,57 @@ static int process_signaled( struct object *obj, struct thread *thread )
}
static
void
startup_info_destroy
(
struct
object
*
obj
)
{
struct
startup_info
*
info
=
(
struct
startup_info
*
)
obj
;
assert
(
obj
->
ops
==
&
startup_info_ops
);
if
(
info
->
process
)
release_object
(
info
->
process
);
if
(
info
->
thread
)
release_object
(
info
->
thread
);
}
static
void
startup_info_dump
(
struct
object
*
obj
,
int
verbose
)
{
struct
startup_info
*
info
=
(
struct
startup_info
*
)
obj
;
assert
(
obj
->
ops
==
&
startup_info_ops
);
fprintf
(
stderr
,
"Startup info flags=%x in=%d out=%d err=%d
\n
"
,
info
->
start_flags
,
info
->
hstdin
,
info
->
hstdout
,
info
->
hstderr
);
}
static
int
startup_info_signaled
(
struct
object
*
obj
,
struct
thread
*
thread
)
{
struct
startup_info
*
info
=
(
struct
startup_info
*
)
obj
;
return
(
info
->
thread
!=
NULL
);
}
/* build a reply for the wait_process request */
static
void
build_wait_process_reply
(
struct
thread
*
thread
,
struct
object
*
obj
,
int
signaled
)
{
struct
wait_process_request
*
req
=
get_req_ptr
(
thread
);
if
(
obj
)
{
struct
startup_info
*
info
=
(
struct
startup_info
*
)
obj
;
assert
(
obj
->
ops
==
&
startup_info_ops
);
req
->
pid
=
get_process_id
(
info
->
process
);
req
->
tid
=
get_thread_id
(
info
->
thread
);
req
->
phandle
=
alloc_handle
(
thread
->
process
,
info
->
process
,
PROCESS_ALL_ACCESS
,
req
->
pinherit
);
req
->
thandle
=
alloc_handle
(
thread
->
process
,
info
->
thread
,
THREAD_ALL_ACCESS
,
req
->
tinherit
);
if
(
info
->
process
->
init_event
)
req
->
event
=
alloc_handle
(
thread
->
process
,
info
->
process
->
init_event
,
EVENT_ALL_ACCESS
,
0
);
else
req
->
event
=
-
1
;
/* FIXME: set_error */
}
release_object
(
thread
->
info
);
thread
->
info
=
NULL
;
}
/* get a process from an id (and increment the refcount) */
struct
process
*
get_process_from_id
(
void
*
id
)
{
...
...
@@ -314,7 +419,7 @@ static void process_killed( struct process *process )
{
assert
(
!
process
->
thread_list
);
gettimeofday
(
&
process
->
end_time
,
NULL
);
release_object
(
process
->
handles
);
if
(
process
->
handles
)
release_object
(
process
->
handles
);
process
->
handles
=
NULL
;
free_console
(
process
);
while
(
process
->
exe
.
next
)
...
...
@@ -594,83 +699,83 @@ struct module_snapshot *module_snap( struct process *process, int *count )
/* create a new process */
DECL_HANDLER
(
new_process
)
{
size_t
len
=
get_req_strlen
(
req
,
req
->
cmdline
);
struct
thread
*
thread
;
struct
startup_info
*
info
;
int
sock
[
2
];
int
event
=
-
1
,
phandle
=
-
1
;
req
->
phandle
=
-
1
;
req
->
thandle
=
-
1
;
req
->
event
=
-
1
;
req
->
pid
=
NULL
;
req
->
tid
=
NULL
;
if
(
socketpair
(
AF_UNIX
,
SOCK_STREAM
,
0
,
sock
)
==
-
1
)
if
(
current
->
info
)
{
f
ile_set_error
(
);
f
atal_protocol_error
(
current
,
"new_process: another process is being created
\n
"
);
return
;
}
if
(
!
(
thread
=
create_process
(
sock
[
0
],
current
->
process
,
req
,
req
->
cmdline
,
len
)))
goto
error
;
/* build the startup info for a new process */
if
(
!
(
info
=
alloc_object
(
&
startup_info_ops
,
-
1
)))
return
;
info
->
inherit_all
=
req
->
inherit_all
;
info
->
create_flags
=
req
->
create_flags
;
info
->
start_flags
=
req
->
start_flags
;
info
->
exe_file
=
req
->
exe_file
;
info
->
hstdin
=
req
->
hstdin
;
info
->
hstdout
=
req
->
hstdout
;
info
->
hstderr
=
req
->
hstderr
;
info
->
cmd_show
=
req
->
cmd_show
;
info
->
process
=
NULL
;
info
->
thread
=
NULL
;
if
(
(
event
=
alloc_handle
(
current
->
process
,
thread
->
process
->
init_event
,
EVENT_ALL_ACCESS
,
0
))
==
-
1
)
goto
error
;
if
((
phandle
=
alloc_handle
(
current
->
process
,
thread
->
process
,
PROCESS_ALL_ACCESS
,
req
->
pinherit
))
==
-
1
)
goto
error
;
if
((
req
->
thandle
=
alloc_handle
(
current
->
process
,
thread
,
THREAD_ALL_ACCESS
,
req
->
tinherit
))
==
-
1
)
goto
error
;
/* thread object will be released when the thread gets killed */
set_reply_fd
(
current
,
sock
[
1
]
);
req
->
pid
=
get_process_id
(
thread
->
process
);
req
->
tid
=
get_thread_id
(
thread
);
req
->
phandle
=
phandle
;
req
->
event
=
event
;
return
;
if
(
req
->
alloc_fd
)
{
if
(
socketpair
(
AF_UNIX
,
SOCK_STREAM
,
0
,
sock
)
==
-
1
)
{
file_set_error
();
release_object
(
info
);
return
;
}
if
(
!
create_process
(
sock
[
0
]
))
{
release_object
(
info
)
;
close
(
sock
[
1
]
);
return
;
}
/* thread object will be released when the thread gets killed */
set_reply_fd
(
current
,
sock
[
1
]
);
}
current
->
info
=
info
;
}
error
:
if
(
phandle
!=
-
1
)
close_handle
(
current
->
process
,
phandle
);
if
(
event
!=
-
1
)
close_handle
(
current
->
process
,
event
);
if
(
thread
)
release_object
(
thread
);
close
(
sock
[
1
]
);
/* Wait for the new process to start */
DECL_HANDLER
(
wait_process
)
{
if
(
!
current
->
info
)
{
fatal_protocol_error
(
current
,
"wait_process: no process is being created
\n
"
);
return
;
}
req
->
pid
=
0
;
req
->
tid
=
0
;
req
->
phandle
=
-
1
;
req
->
thandle
=
-
1
;
if
(
req
->
cancel
)
{
release_object
(
current
->
info
);
current
->
info
=
NULL
;
}
else
{
struct
object
*
obj
=
&
current
->
info
->
obj
;
sleep_on
(
1
,
&
obj
,
SELECT_TIMEOUT
,
req
->
timeout
,
build_wait_process_reply
);
}
}
/* initialize a new process */
DECL_HANDLER
(
init_process
)
{
struct
new_process_request
*
info
;
if
(
!
current
->
unix_pid
)
{
fatal_protocol_error
(
current
,
"init_process: init_thread not called yet
\n
"
);
return
;
}
if
(
!
(
info
=
current
->
process
->
info
))
{
fatal_protocol_error
(
current
,
"init_process: called twice
\n
"
);
return
;
}
current
->
process
->
ldt_copy
=
req
->
ldt_copy
;
current
->
process
->
ldt_flags
=
req
->
ldt_flags
;
current
->
process
->
info
=
NULL
;
req
->
exe_file
=
-
1
;
req
->
start_flags
=
info
->
start_flags
;
req
->
hstdin
=
info
->
hstdin
;
req
->
hstdout
=
info
->
hstdout
;
req
->
hstderr
=
info
->
hstderr
;
req
->
cmd_show
=
info
->
cmd_show
;
req
->
env_ptr
=
info
->
env_ptr
;
strcpy
(
req
->
cmdline
,
info
->
cmdline
);
if
(
current
->
process
->
exe
.
file
)
req
->
exe_file
=
alloc_handle
(
current
->
process
,
current
->
process
->
exe
.
file
,
GENERIC_READ
,
0
);
free
(
info
);
init_process
(
req
->
ppid
,
req
);
}
/* signal the end of the process initialization */
...
...
server/process.h
View file @
5b4f3e8d
...
...
@@ -48,7 +48,6 @@ struct process
struct
process_dll
exe
;
/* main exe file */
void
*
ldt_copy
;
/* pointer to LDT copy in client addr space */
void
*
ldt_flags
;
/* pointer to LDT flags in client addr space */
struct
new_process_request
*
info
;
/* startup info (freed after startup) */
};
struct
process_snapshot
...
...
@@ -67,9 +66,7 @@ struct module_snapshot
/* process functions */
extern
struct
thread
*
create_process
(
int
fd
,
struct
process
*
parent
,
struct
new_process_request
*
req
,
const
char
*
cmd_line
,
size_t
len
);
extern
struct
thread
*
create_process
(
int
fd
);
extern
struct
process
*
get_process_from_id
(
void
*
id
);
extern
struct
process
*
get_process_from_handle
(
int
handle
,
unsigned
int
access
);
extern
int
process_set_debugger
(
struct
process
*
process
,
struct
thread
*
thread
);
...
...
server/request.c
View file @
5b4f3e8d
...
...
@@ -289,7 +289,7 @@ static void master_socket_poll_event( struct object *obj, int event )
struct
sockaddr_un
dummy
;
int
len
=
sizeof
(
dummy
);
int
client
=
accept
(
master_socket
->
obj
.
fd
,
(
struct
sockaddr
*
)
&
dummy
,
&
len
);
if
(
client
!=
-
1
)
create_process
(
client
,
NULL
,
NULL
,
""
,
1
);
if
(
client
!=
-
1
)
create_process
(
client
);
}
}
...
...
server/request.h
View file @
5b4f3e8d
...
...
@@ -71,6 +71,7 @@ static inline size_t get_req_strlenW( const void *req, const WCHAR *str )
/* ### make_requests begin ### */
DECL_HANDLER
(
new_process
);
DECL_HANDLER
(
wait_process
);
DECL_HANDLER
(
new_thread
);
DECL_HANDLER
(
boot_done
);
DECL_HANDLER
(
init_process
);
...
...
@@ -179,6 +180,7 @@ typedef void (*req_handler)( void *req );
static
const
req_handler
req_handlers
[
REQ_NB_REQUESTS
]
=
{
(
req_handler
)
req_new_process
,
(
req_handler
)
req_wait_process
,
(
req_handler
)
req_new_thread
,
(
req_handler
)
req_boot_done
,
(
req_handler
)
req_init_process
,
...
...
server/thread.c
View file @
5b4f3e8d
...
...
@@ -116,7 +116,7 @@ static int alloc_client_buffer( struct thread *thread )
}
/* create a new thread */
struct
thread
*
create_thread
(
int
fd
,
struct
process
*
process
,
int
suspend
)
struct
thread
*
create_thread
(
int
fd
,
struct
process
*
process
)
{
struct
thread
*
thread
;
...
...
@@ -131,6 +131,7 @@ struct thread *create_thread( int fd, struct process *process, int suspend )
thread
->
mutex
=
NULL
;
thread
->
debug_ctx
=
NULL
;
thread
->
debug_event
=
NULL
;
thread
->
info
=
NULL
;
thread
->
wait
=
NULL
;
thread
->
apc
=
NULL
;
thread
->
apc_count
=
0
;
...
...
@@ -143,7 +144,7 @@ struct thread *create_thread( int fd, struct process *process, int suspend )
thread
->
prev
=
NULL
;
thread
->
priority
=
THREAD_PRIORITY_NORMAL
;
thread
->
affinity
=
1
;
thread
->
suspend
=
(
suspend
!=
0
)
;
thread
->
suspend
=
0
;
thread
->
buffer
=
(
void
*
)
-
1
;
thread
->
last_req
=
REQ_GET_THREAD_BUFFER
;
thread
->
process
=
(
struct
process
*
)
grab_object
(
process
);
...
...
@@ -194,6 +195,7 @@ static void destroy_thread( struct object *obj )
if
(
thread
->
prev
)
thread
->
prev
->
next
=
thread
->
next
;
else
first_thread
=
thread
->
next
;
if
(
thread
->
apc
)
free
(
thread
->
apc
);
if
(
thread
->
info
)
release_object
(
thread
->
info
);
if
(
thread
->
buffer
!=
(
void
*
)
-
1
)
munmap
(
thread
->
buffer
,
MAX_REQUEST_LENGTH
);
if
(
thread
->
pass_fd
!=
-
1
)
close
(
thread
->
pass_fd
);
}
...
...
@@ -625,8 +627,9 @@ DECL_HANDLER(new_thread)
if
(
socketpair
(
AF_UNIX
,
SOCK_STREAM
,
0
,
sock
)
!=
-
1
)
{
if
((
thread
=
create_thread
(
sock
[
0
],
current
->
process
,
req
->
suspend
)))
if
((
thread
=
create_thread
(
sock
[
0
],
current
->
process
)))
{
if
(
req
->
suspend
)
thread
->
suspend
++
;
req
->
tid
=
thread
;
if
((
req
->
handle
=
alloc_handle
(
current
->
process
,
thread
,
THREAD_ALL_ACCESS
,
req
->
inherit
))
!=
-
1
)
...
...
server/thread.h
View file @
5b4f3e8d
...
...
@@ -21,6 +21,7 @@ struct thread_apc;
struct
mutex
;
struct
debug_ctx
;
struct
debug_event
;
struct
startup_info
;
enum
run_state
{
...
...
@@ -40,6 +41,7 @@ struct thread
struct
mutex
*
mutex
;
/* list of currently owned mutexes */
struct
debug_ctx
*
debug_ctx
;
/* debugger context if this thread is a debugger */
struct
debug_event
*
debug_event
;
/* debug event being sent to debugger */
struct
startup_info
*
info
;
/* startup info for child process */
struct
thread_wait
*
wait
;
/* current wait condition if sleeping */
struct
thread_apc
*
apc
;
/* list of async procedure calls */
int
apc_count
;
/* number of outstanding APCs */
...
...
@@ -72,7 +74,7 @@ extern struct thread *current;
/* thread functions */
extern
struct
thread
*
create_thread
(
int
fd
,
struct
process
*
process
,
int
suspend
);
extern
struct
thread
*
create_thread
(
int
fd
,
struct
process
*
process
);
extern
struct
thread
*
get_thread_from_id
(
void
*
id
);
extern
struct
thread
*
get_thread_from_handle
(
int
handle
,
unsigned
int
access
);
extern
struct
thread
*
get_thread_from_pid
(
int
pid
);
...
...
server/trace.c
View file @
5b4f3e8d
...
...
@@ -215,8 +215,6 @@ typedef void (*dump_func)( const void *req );
static
void
dump_new_process_request
(
const
struct
new_process_request
*
req
)
{
fprintf
(
stderr
,
" pinherit=%d,"
,
req
->
pinherit
);
fprintf
(
stderr
,
" tinherit=%d,"
,
req
->
tinherit
);
fprintf
(
stderr
,
" inherit_all=%d,"
,
req
->
inherit_all
);
fprintf
(
stderr
,
" create_flags=%d,"
,
req
->
create_flags
);
fprintf
(
stderr
,
" start_flags=%d,"
,
req
->
start_flags
);
...
...
@@ -225,12 +223,18 @@ static void dump_new_process_request( const struct new_process_request *req )
fprintf
(
stderr
,
" hstdout=%d,"
,
req
->
hstdout
);
fprintf
(
stderr
,
" hstderr=%d,"
,
req
->
hstderr
);
fprintf
(
stderr
,
" cmd_show=%d,"
,
req
->
cmd_show
);
fprintf
(
stderr
,
" env_ptr=%p,"
,
req
->
env_ptr
);
fprintf
(
stderr
,
" cmdline="
);
dump_string
(
req
,
req
->
cmdline
);
fprintf
(
stderr
,
" alloc_fd=%d"
,
req
->
alloc_fd
);
}
static
void
dump_wait_process_request
(
const
struct
wait_process_request
*
req
)
{
fprintf
(
stderr
,
" pinherit=%d,"
,
req
->
pinherit
);
fprintf
(
stderr
,
" tinherit=%d,"
,
req
->
tinherit
);
fprintf
(
stderr
,
" timeout=%d,"
,
req
->
timeout
);
fprintf
(
stderr
,
" cancel=%d"
,
req
->
cancel
);
}
static
void
dump_
new_process_reply
(
const
struct
new
_process_request
*
req
)
static
void
dump_
wait_process_reply
(
const
struct
wait
_process_request
*
req
)
{
fprintf
(
stderr
,
" pid=%p,"
,
req
->
pid
);
fprintf
(
stderr
,
" phandle=%d,"
,
req
->
phandle
);
...
...
@@ -259,7 +263,8 @@ static void dump_boot_done_request( const struct boot_done_request *req )
static
void
dump_init_process_request
(
const
struct
init_process_request
*
req
)
{
fprintf
(
stderr
,
" ldt_copy=%p,"
,
req
->
ldt_copy
);
fprintf
(
stderr
,
" ldt_flags=%p"
,
req
->
ldt_flags
);
fprintf
(
stderr
,
" ldt_flags=%p,"
,
req
->
ldt_flags
);
fprintf
(
stderr
,
" ppid=%d"
,
req
->
ppid
);
}
static
void
dump_init_process_reply
(
const
struct
init_process_request
*
req
)
...
...
@@ -269,10 +274,7 @@ static void dump_init_process_reply( const struct init_process_request *req )
fprintf
(
stderr
,
" hstdin=%d,"
,
req
->
hstdin
);
fprintf
(
stderr
,
" hstdout=%d,"
,
req
->
hstdout
);
fprintf
(
stderr
,
" hstderr=%d,"
,
req
->
hstderr
);
fprintf
(
stderr
,
" cmd_show=%d,"
,
req
->
cmd_show
);
fprintf
(
stderr
,
" env_ptr=%p,"
,
req
->
env_ptr
);
fprintf
(
stderr
,
" cmdline="
);
dump_string
(
req
,
req
->
cmdline
);
fprintf
(
stderr
,
" cmd_show=%d"
,
req
->
cmd_show
);
}
static
void
dump_init_process_done_request
(
const
struct
init_process_done_request
*
req
)
...
...
@@ -1326,6 +1328,7 @@ static void dump_get_atom_name_reply( const struct get_atom_name_request *req )
static
const
dump_func
req_dumpers
[
REQ_NB_REQUESTS
]
=
{
(
dump_func
)
dump_new_process_request
,
(
dump_func
)
dump_wait_process_request
,
(
dump_func
)
dump_new_thread_request
,
(
dump_func
)
dump_boot_done_request
,
(
dump_func
)
dump_init_process_request
,
...
...
@@ -1430,7 +1433,8 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
};
static
const
dump_func
reply_dumpers
[
REQ_NB_REQUESTS
]
=
{
(
dump_func
)
dump_new_process_reply
,
(
dump_func
)
0
,
(
dump_func
)
dump_wait_process_reply
,
(
dump_func
)
dump_new_thread_reply
,
(
dump_func
)
0
,
(
dump_func
)
dump_init_process_reply
,
...
...
@@ -1536,6 +1540,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
static
const
char
*
const
req_names
[
REQ_NB_REQUESTS
]
=
{
"new_process"
,
"wait_process"
,
"new_thread"
,
"boot_done"
,
"init_process"
,
...
...
windows/queue.c
View file @
5b4f3e8d
...
...
@@ -1533,7 +1533,7 @@ DWORD WINAPI WaitForInputIdle (HANDLE hProcess, DWORD dwTimeOut)
return
0
;
}
pdb
=
PROCESS_IdToPDB
(
pid
)
;
if
(
!
(
pdb
=
PROCESS_IdToPDB
(
pid
)))
return
0
;
/* check whether we are waiting for a win32 process or the win16 subsystem */
if
(
pdb
->
flags
&
PDB32_WIN16_PROC
)
{
...
...
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