Added support for CREATE_SUSPENDED flag in CreateProcess.
This commit is contained in:
parent
796c0f1223
commit
ec7bb2391d
|
@ -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",
|
||||
|
|
Loading…
Reference in New Issue