Commit ec7bb239 authored by Alexandre Julliard's avatar Alexandre Julliard

Added support for CREATE_SUSPENDED flag in CreateProcess.

parent 796c0f12
......@@ -33,6 +33,7 @@ struct new_process_request
IN int hstdin; /* handle for stdin */
IN int hstdout; /* handle for stdout */
IN int hstderr; /* handle for stderr */
IN int event; /* event to signal startup */
IN int cmd_show; /* main window show mode */
IN void* env_ptr; /* pointer to environment (FIXME: hack) */
OUT void* pid; /* process id */
......@@ -72,6 +73,13 @@ struct init_process_request
};
/* Signal the end of the process initialization */
struct init_process_done_request
{
IN int dummy;
};
/* Initialize a thread; called from the child after fork()/clone() */
struct init_thread_request
{
......@@ -808,6 +816,7 @@ enum request
REQ_NEW_THREAD,
REQ_SET_DEBUG,
REQ_INIT_PROCESS,
REQ_INIT_PROCESS_DONE,
REQ_INIT_THREAD,
REQ_GET_THREAD_BUFFER,
REQ_TERMINATE_PROCESS,
......
......@@ -1113,8 +1113,6 @@ BOOL WINAPI CreateProcessA( LPCSTR lpApplicationName, LPSTR lpCommandLine,
/* Warn if unsupported features are used */
if (dwCreationFlags & CREATE_SUSPENDED)
FIXME_(module)("(%s,...): CREATE_SUSPENDED ignored\n", name);
if (dwCreationFlags & DETACHED_PROCESS)
FIXME_(module)("(%s,...): DETACHED_PROCESS ignored\n", name);
if (dwCreationFlags & CREATE_NEW_CONSOLE)
......
......@@ -446,9 +446,7 @@ void PROCESS_Start(void)
PROCESS_CallUserSignalProc( USIG_PROCESS_INIT, 0 );
/* Signal the parent process to continue */
SetEvent( pdb->load_done_evt );
CloseHandle( pdb->load_done_evt );
pdb->load_done_evt = INVALID_HANDLE_VALUE;
server_call( REQ_INIT_PROCESS_DONE );
/* Perform Win32 specific process initialization */
if ( type == PROC_WIN32 )
......@@ -523,7 +521,7 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
BOOL inherit, DWORD flags, STARTUPINFOA *startup,
PROCESS_INFORMATION *info )
{
HANDLE handles[2], load_done_evt = INVALID_HANDLE_VALUE;
HANDLE handles[2], load_done_evt = 0;
DWORD exitcode, size;
BOOL alloc_stack16;
int server_thandle;
......@@ -534,13 +532,15 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
if (!pdb) return NULL;
info->hThread = info->hProcess = INVALID_HANDLE_VALUE;
if (!(load_done_evt = CreateEventA( NULL, TRUE, FALSE, NULL ))) goto error;
/* Create the process on the server side */
req->inherit = (psa && (psa->nLength >= sizeof(*psa)) && psa->bInheritHandle);
req->inherit_all = inherit;
req->create_flags = flags;
req->start_flags = startup->dwFlags;
req->event = load_done_evt;
if (startup->dwFlags & STARTF_USESTDHANDLES)
{
req->hstdin = startup->hStdInput;
......@@ -588,17 +588,12 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
/* Create the main thread */
if (!(teb = THREAD_Create( pdb, 0L, size, alloc_stack16, tsa, &server_thandle )))
goto error;
if (!(teb = THREAD_Create( pdb, flags & CREATE_SUSPENDED, size,
alloc_stack16, tsa, &server_thandle ))) goto error;
info->hThread = server_thandle;
info->dwThreadId = (DWORD)teb->tid;
teb->startup = PROCESS_Start;
/* Create the load-done event */
load_done_evt = CreateEventA( NULL, TRUE, FALSE, NULL );
DuplicateHandle( GetCurrentProcess(), load_done_evt,
info->hProcess, &pdb->load_done_evt, 0, TRUE, DUPLICATE_SAME_ACCESS );
/* Pass module to new process (FIXME: hack) */
pdb->module = pModule->self;
SYSDEPS_SpawnThread( teb );
......@@ -634,12 +629,12 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
}
CloseHandle( load_done_evt );
load_done_evt = INVALID_HANDLE_VALUE;
load_done_evt = 0;
return pdb;
error:
if (load_done_evt != INVALID_HANDLE_VALUE) CloseHandle( load_done_evt );
if (load_done_evt) CloseHandle( load_done_evt );
if (info->hThread != INVALID_HANDLE_VALUE) CloseHandle( info->hThread );
if (info->hProcess != INVALID_HANDLE_VALUE) CloseHandle( info->hProcess );
PROCESS_FreePDB( pdb );
......
......@@ -70,6 +70,7 @@ static struct process *create_process( struct process *parent, struct new_proces
process->suspend = 0;
process->console_in = NULL;
process->console_out = NULL;
process->init_event = NULL;
process->info = NULL;
gettimeofday( &process->start_time, NULL );
......@@ -87,6 +88,13 @@ static struct process *create_process( struct process *parent, struct new_proces
memcpy( process->info->cmdline, cmd_line, len );
process->info->cmdline[len] = 0;
/* get the init done event */
if (req->event != -1)
{
if (!(process->init_event = get_event_obj( parent, req->event, EVENT_MODIFY_STATE )))
goto error;
}
/* set the process console */
if (req->create_flags & CREATE_NEW_CONSOLE)
{
......@@ -120,7 +128,6 @@ static struct process *create_process( struct process *parent, struct new_proces
error:
free_console( process );
if (process->info) free( process->info );
if (process->handles) release_object( process->handles );
release_object( process );
return NULL;
......@@ -139,6 +146,7 @@ struct process *create_initial_process(void)
req.hstdin = -1;
req.hstdout = -1;
req.hstderr = -1;
req.event = -1;
req.cmd_show = 0;
req.env_ptr = NULL;
if ((process = create_process( NULL, &req, "", 1 )))
......@@ -165,6 +173,7 @@ static void process_destroy( struct object *obj )
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 );
}
/* dump a process on stdout for debugging purposes */
......@@ -369,6 +378,21 @@ DECL_HANDLER(init_process)
free( info );
}
/* signal the end of the process initialization */
DECL_HANDLER(init_process_done)
{
struct process *process = current->process;
if (!process->init_event)
{
fatal_protocol_error( current, "init_process_done: no event\n" );
return;
}
set_event( process->init_event );
release_object( process->init_event );
process->init_event = NULL;
if (current->suspend + current->process->suspend > 0) stop_thread( current );
}
/* open a handle to a process */
DECL_HANDLER(open_process)
{
......
......@@ -34,6 +34,7 @@ struct process
int suspend; /* global process suspend count */
struct object *console_in; /* console input */
struct object *console_out; /* console output */
struct event *init_event; /* event for init done */
struct new_process_request *info; /* startup info (freed after startup) */
};
......
......@@ -65,6 +65,7 @@ DECL_HANDLER(new_process);
DECL_HANDLER(new_thread);
DECL_HANDLER(set_debug);
DECL_HANDLER(init_process);
DECL_HANDLER(init_process_done);
DECL_HANDLER(init_thread);
DECL_HANDLER(get_thread_buffer);
DECL_HANDLER(terminate_process);
......@@ -142,6 +143,7 @@ static const struct handler {
{ (void(*)())req_new_thread, sizeof(struct new_thread_request) },
{ (void(*)())req_set_debug, sizeof(struct set_debug_request) },
{ (void(*)())req_init_process, sizeof(struct init_process_request) },
{ (void(*)())req_init_process_done, sizeof(struct init_process_done_request) },
{ (void(*)())req_init_thread, sizeof(struct init_thread_request) },
{ (void(*)())req_get_thread_buffer, sizeof(struct get_thread_buffer_request) },
{ (void(*)())req_terminate_process, sizeof(struct terminate_process_request) },
......
......@@ -318,7 +318,8 @@ static void detach_thread( struct thread *thread )
/* stop a thread (at the Unix level) */
void stop_thread( struct thread *thread )
{
if (!thread->unix_pid) return;
/* can't stop a thread while initialisation is in progress */
if (!thread->unix_pid || thread->process->init_event) return;
/* first try to attach to it */
if (!thread->attached)
if (attach_thread( thread )) return; /* this will have stopped it */
......
......@@ -52,6 +52,7 @@ static void dump_new_process_request( struct new_process_request *req )
fprintf( stderr, " hstdin=%d,", req->hstdin );
fprintf( stderr, " hstdout=%d,", req->hstdout );
fprintf( stderr, " hstderr=%d,", req->hstderr );
fprintf( stderr, " event=%d,", req->event );
fprintf( stderr, " cmd_show=%d,", req->cmd_show );
fprintf( stderr, " env_ptr=%p,", req->env_ptr );
fprintf( stderr, " cmdline=\"%s\"", req->cmdline );
......@@ -96,6 +97,11 @@ static void dump_init_process_reply( struct init_process_request *req )
fprintf( stderr, " cmdline=\"%s\"", req->cmdline );
}
static void dump_init_process_done_request( struct init_process_done_request *req )
{
fprintf( stderr, " dummy=%d", req->dummy );
}
static void dump_init_thread_request( struct init_thread_request *req )
{
fprintf( stderr, " unix_pid=%d,", req->unix_pid );
......@@ -762,6 +768,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_new_thread_request,
(dump_func)dump_set_debug_request,
(dump_func)dump_init_process_request,
(dump_func)dump_init_process_done_request,
(dump_func)dump_init_thread_request,
(dump_func)dump_get_thread_buffer_request,
(dump_func)dump_terminate_process_request,
......@@ -835,6 +842,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_new_thread_reply,
(dump_func)0,
(dump_func)dump_init_process_reply,
(dump_func)0,
(dump_func)dump_init_thread_reply,
(dump_func)0,
(dump_func)0,
......@@ -908,6 +916,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"new_thread",
"set_debug",
"init_process",
"init_process_done",
"init_thread",
"get_thread_buffer",
"terminate_process",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment