mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-03 01:01:44 +00:00
ntdll: Pass a debug object in the new_process request.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
da0b451f5f
commit
11e6f1007c
|
@ -1746,14 +1746,12 @@ static void test_kill_on_exit(const char *argv0)
|
|||
ok( !status, "NtCreateDebugObject failed %x\n", status );
|
||||
pDbgUiSetThreadDebugObject( debug );
|
||||
exit_code = run_child_wait( cmd, event );
|
||||
todo_wine
|
||||
ok( exit_code == 0, "exit code = %08x\n", exit_code);
|
||||
|
||||
status = pNtCreateDebugObject( &debug, DEBUG_ALL_ACCESS, &attr, DEBUG_KILL_ON_CLOSE );
|
||||
ok( !status, "NtCreateDebugObject failed %x\n", status );
|
||||
pDbgUiSetThreadDebugObject( debug );
|
||||
exit_code = run_child_wait( cmd, event );
|
||||
todo_wine
|
||||
ok( exit_code == STATUS_DEBUGGER_INACTIVE, "exit code = %08x\n", exit_code);
|
||||
|
||||
status = pNtCreateDebugObject( &debug, DEBUG_ALL_ACCESS, &attr, 0xfffe );
|
||||
|
@ -1762,7 +1760,6 @@ static void test_kill_on_exit(const char *argv0)
|
|||
status = pDbgUiConnectToDbg();
|
||||
ok( !status, "DbgUiConnectToDbg failed %x\n", status );
|
||||
exit_code = run_child_wait( cmd, event );
|
||||
todo_wine
|
||||
ok( exit_code == STATUS_DEBUGGER_INACTIVE, "exit code = %08x\n", exit_code);
|
||||
|
||||
heap_free(cmd);
|
||||
|
|
|
@ -249,14 +249,15 @@ struct _PROC_THREAD_ATTRIBUTE_LIST
|
|||
/***********************************************************************
|
||||
* create_nt_process
|
||||
*/
|
||||
static NTSTATUS create_nt_process( HANDLE token, SECURITY_ATTRIBUTES *psa, SECURITY_ATTRIBUTES *tsa,
|
||||
BOOL inherit, DWORD flags, RTL_USER_PROCESS_PARAMETERS *params,
|
||||
static NTSTATUS create_nt_process( HANDLE token, HANDLE debug, SECURITY_ATTRIBUTES *psa,
|
||||
SECURITY_ATTRIBUTES *tsa, BOOL inherit, DWORD flags,
|
||||
RTL_USER_PROCESS_PARAMETERS *params,
|
||||
RTL_USER_PROCESS_INFORMATION *info, HANDLE parent,
|
||||
const struct proc_thread_attr *handle_list )
|
||||
{
|
||||
OBJECT_ATTRIBUTES process_attr, thread_attr;
|
||||
PS_CREATE_INFO create_info;
|
||||
ULONG_PTR buffer[offsetof( PS_ATTRIBUTE_LIST, Attributes[6] ) / sizeof(ULONG_PTR)];
|
||||
ULONG_PTR buffer[offsetof( PS_ATTRIBUTE_LIST, Attributes[7] ) / sizeof(ULONG_PTR)];
|
||||
PS_ATTRIBUTE_LIST *attr = (PS_ATTRIBUTE_LIST *)buffer;
|
||||
UNICODE_STRING nameW;
|
||||
NTSTATUS status;
|
||||
|
@ -309,6 +310,14 @@ static NTSTATUS create_nt_process( HANDLE token, SECURITY_ATTRIBUTES *psa, SECUR
|
|||
attr->Attributes[pos].ReturnLength = NULL;
|
||||
pos++;
|
||||
}
|
||||
if (debug)
|
||||
{
|
||||
attr->Attributes[pos].Attribute = PS_ATTRIBUTE_DEBUG_PORT;
|
||||
attr->Attributes[pos].Size = sizeof(debug);
|
||||
attr->Attributes[pos].ValuePtr = debug;
|
||||
attr->Attributes[pos].ReturnLength = NULL;
|
||||
pos++;
|
||||
}
|
||||
attr->TotalLength = offsetof( PS_ATTRIBUTE_LIST, Attributes[pos] );
|
||||
|
||||
InitializeObjectAttributes( &process_attr, NULL, 0, NULL, psa ? psa->lpSecurityDescriptor : NULL );
|
||||
|
@ -329,8 +338,9 @@ static NTSTATUS create_nt_process( HANDLE token, SECURITY_ATTRIBUTES *psa, SECUR
|
|||
/***********************************************************************
|
||||
* create_vdm_process
|
||||
*/
|
||||
static NTSTATUS create_vdm_process( HANDLE token, SECURITY_ATTRIBUTES *psa, SECURITY_ATTRIBUTES *tsa,
|
||||
BOOL inherit, DWORD flags, RTL_USER_PROCESS_PARAMETERS *params,
|
||||
static NTSTATUS create_vdm_process( HANDLE token, HANDLE debug, SECURITY_ATTRIBUTES *psa,
|
||||
SECURITY_ATTRIBUTES *tsa, BOOL inherit, DWORD flags,
|
||||
RTL_USER_PROCESS_PARAMETERS *params,
|
||||
RTL_USER_PROCESS_INFORMATION *info )
|
||||
{
|
||||
const WCHAR *winevdm = (is_win64 || is_wow64 ?
|
||||
|
@ -350,7 +360,7 @@ static NTSTATUS create_vdm_process( HANDLE token, SECURITY_ATTRIBUTES *psa, SECU
|
|||
winevdm, params->ImagePathName.Buffer, params->CommandLine.Buffer );
|
||||
RtlInitUnicodeString( ¶ms->ImagePathName, winevdm );
|
||||
RtlInitUnicodeString( ¶ms->CommandLine, newcmdline );
|
||||
status = create_nt_process( token, psa, tsa, inherit, flags, params, info, NULL, NULL );
|
||||
status = create_nt_process( token, debug, psa, tsa, inherit, flags, params, info, NULL, NULL );
|
||||
HeapFree( GetProcessHeap(), 0, newcmdline );
|
||||
return status;
|
||||
}
|
||||
|
@ -359,8 +369,9 @@ static NTSTATUS create_vdm_process( HANDLE token, SECURITY_ATTRIBUTES *psa, SECU
|
|||
/***********************************************************************
|
||||
* create_cmd_process
|
||||
*/
|
||||
static NTSTATUS create_cmd_process( HANDLE token, SECURITY_ATTRIBUTES *psa, SECURITY_ATTRIBUTES *tsa,
|
||||
BOOL inherit, DWORD flags, RTL_USER_PROCESS_PARAMETERS *params,
|
||||
static NTSTATUS create_cmd_process( HANDLE token, HANDLE debug, SECURITY_ATTRIBUTES *psa,
|
||||
SECURITY_ATTRIBUTES *tsa, BOOL inherit, DWORD flags,
|
||||
RTL_USER_PROCESS_PARAMETERS *params,
|
||||
RTL_USER_PROCESS_INFORMATION *info )
|
||||
{
|
||||
WCHAR comspec[MAX_PATH];
|
||||
|
@ -378,7 +389,7 @@ static NTSTATUS create_cmd_process( HANDLE token, SECURITY_ATTRIBUTES *psa, SECU
|
|||
swprintf( newcmdline, len, L"%s /s/c \"%s\"", comspec, params->CommandLine.Buffer );
|
||||
RtlInitUnicodeString( ¶ms->ImagePathName, comspec );
|
||||
RtlInitUnicodeString( ¶ms->CommandLine, newcmdline );
|
||||
status = create_nt_process( token, psa, tsa, inherit, flags, params, info, NULL, NULL );
|
||||
status = create_nt_process( token, debug, psa, tsa, inherit, flags, params, info, NULL, NULL );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, newcmdline );
|
||||
return status;
|
||||
}
|
||||
|
@ -486,7 +497,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR
|
|||
WCHAR *p, *tidy_cmdline = cmd_line;
|
||||
RTL_USER_PROCESS_PARAMETERS *params = NULL;
|
||||
RTL_USER_PROCESS_INFORMATION rtl_info;
|
||||
HANDLE parent = NULL;
|
||||
HANDLE parent = 0, debug = 0;
|
||||
NTSTATUS status;
|
||||
|
||||
/* Process the AppName and/or CmdLine to get module name and path */
|
||||
|
@ -536,6 +547,12 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR
|
|||
goto done;
|
||||
}
|
||||
|
||||
if (flags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS))
|
||||
{
|
||||
if ((status = DbgUiConnectToDbg())) goto done;
|
||||
debug = DbgUiGetThreadDebugObject();
|
||||
}
|
||||
|
||||
if (flags & EXTENDED_STARTUPINFO_PRESENT)
|
||||
{
|
||||
struct _PROC_THREAD_ATTRIBUTE_LIST *attrs =
|
||||
|
@ -577,7 +594,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR
|
|||
}
|
||||
}
|
||||
|
||||
status = create_nt_process( token, process_attr, thread_attr, inherit,
|
||||
status = create_nt_process( token, debug, process_attr, thread_attr, inherit,
|
||||
flags, params, &rtl_info, parent, handle_list );
|
||||
switch (status)
|
||||
{
|
||||
|
@ -587,7 +604,8 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR
|
|||
case STATUS_INVALID_IMAGE_NE_FORMAT:
|
||||
case STATUS_INVALID_IMAGE_PROTECT:
|
||||
TRACE( "starting %s as Win16/DOS binary\n", debugstr_w(app_name) );
|
||||
status = create_vdm_process( token, process_attr, thread_attr, inherit, flags, params, &rtl_info );
|
||||
status = create_vdm_process( token, debug, process_attr, thread_attr,
|
||||
inherit, flags, params, &rtl_info );
|
||||
break;
|
||||
case STATUS_INVALID_IMAGE_NOT_MZ:
|
||||
/* check for .com or .bat extension */
|
||||
|
@ -595,12 +613,14 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR
|
|||
if (!wcsicmp( p, L".com" ) || !wcsicmp( p, L".pif" ))
|
||||
{
|
||||
TRACE( "starting %s as DOS binary\n", debugstr_w(app_name) );
|
||||
status = create_vdm_process( token, process_attr, thread_attr, inherit, flags, params, &rtl_info );
|
||||
status = create_vdm_process( token, debug, process_attr, thread_attr,
|
||||
inherit, flags, params, &rtl_info );
|
||||
}
|
||||
else if (!wcsicmp( p, L".bat" ) || !wcsicmp( p, L".cmd" ))
|
||||
{
|
||||
TRACE( "starting %s as batch binary\n", debugstr_w(app_name) );
|
||||
status = create_cmd_process( token, process_attr, thread_attr, inherit, flags, params, &rtl_info );
|
||||
status = create_cmd_process( token, debug, process_attr, thread_attr,
|
||||
inherit, flags, params, &rtl_info );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -893,7 +893,6 @@ NTSTATUS WINAPI NtCreateUserProcess( HANDLE *process_handle_ptr, HANDLE *thread_
|
|||
|
||||
TRACE( "%s image %s cmdline %s parent %p\n", debugstr_us( &path ),
|
||||
debugstr_us( ¶ms->ImagePathName ), debugstr_us( ¶ms->CommandLine ), parent );
|
||||
if (debug) FIXME( "debug port %p not supported yet\n", debug );
|
||||
|
||||
unixdir = get_unix_curdir( params );
|
||||
|
||||
|
@ -942,6 +941,7 @@ NTSTATUS WINAPI NtCreateUserProcess( HANDLE *process_handle_ptr, HANDLE *thread_
|
|||
SERVER_START_REQ( new_process )
|
||||
{
|
||||
req->token = wine_server_obj_handle( token );
|
||||
req->debug = wine_server_obj_handle( debug );
|
||||
req->parent_process = wine_server_obj_handle( parent );
|
||||
req->inherit_all = !!(process_flags & PROCESS_CREATE_FLAGS_INHERIT_HANDLES);
|
||||
req->create_flags = params->DebugFlags; /* hack: creation flags stored in DebugFlags for now */
|
||||
|
|
|
@ -790,6 +790,7 @@ struct new_process_request
|
|||
{
|
||||
struct request_header __header;
|
||||
obj_handle_t token;
|
||||
obj_handle_t debug;
|
||||
obj_handle_t parent_process;
|
||||
int inherit_all;
|
||||
unsigned int create_flags;
|
||||
|
@ -802,6 +803,7 @@ struct new_process_request
|
|||
/* VARARG(handles,uints,handles_size); */
|
||||
/* VARARG(info,startup_info,info_size); */
|
||||
/* VARARG(env,unicode_str); */
|
||||
char __pad_52[4];
|
||||
};
|
||||
struct new_process_reply
|
||||
{
|
||||
|
@ -6209,7 +6211,7 @@ union generic_reply
|
|||
|
||||
/* ### protocol_version begin ### */
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 657
|
||||
#define SERVER_PROTOCOL_VERSION 658
|
||||
|
||||
/* ### protocol_version end ### */
|
||||
|
||||
|
|
|
@ -355,6 +355,11 @@ static void debug_obj_destroy( struct object *obj )
|
|||
unlink_event( debug_obj, LIST_ENTRY( ptr, struct debug_event, entry ));
|
||||
}
|
||||
|
||||
struct debug_obj *get_debug_obj( struct process *process, obj_handle_t handle, unsigned int access )
|
||||
{
|
||||
return (struct debug_obj *)get_handle_obj( process, handle, access, &debug_obj_ops );
|
||||
}
|
||||
|
||||
static struct debug_obj *create_debug_obj( struct object *root, const struct unicode_str *name,
|
||||
unsigned int attr, unsigned int flags,
|
||||
const struct security_descriptor *sd )
|
||||
|
|
|
@ -1092,6 +1092,7 @@ DECL_HANDLER(new_process)
|
|||
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, NULL );
|
||||
struct process *process = NULL;
|
||||
struct token *token = NULL;
|
||||
struct debug_obj *debug_obj = NULL;
|
||||
struct process *parent;
|
||||
struct thread *parent_thread = current;
|
||||
int socket_fd = thread_get_inflight_fd( current, req->socket_fd );
|
||||
|
@ -1215,6 +1216,11 @@ DECL_HANDLER(new_process)
|
|||
close( socket_fd );
|
||||
goto done;
|
||||
}
|
||||
if (req->debug && !(debug_obj = get_debug_obj( current->process, req->debug, DEBUG_PROCESS_ASSIGN )))
|
||||
{
|
||||
close( socket_fd );
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!(process = create_process( socket_fd, parent, req->inherit_all, info->data, sd,
|
||||
handles, req->handles_size / sizeof(*handles), token )))
|
||||
|
@ -1249,15 +1255,17 @@ DECL_HANDLER(new_process)
|
|||
if (get_error() == STATUS_INVALID_HANDLE ||
|
||||
get_error() == STATUS_OBJECT_TYPE_MISMATCH) clear_error();
|
||||
}
|
||||
/* attach to the debugger if requested */
|
||||
if (req->create_flags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS))
|
||||
|
||||
/* attach to the debugger */
|
||||
if (debug_obj)
|
||||
{
|
||||
set_process_debugger( process, current );
|
||||
process->debug_obj = debug_obj;
|
||||
process->debug_children = !(req->create_flags & DEBUG_ONLY_THIS_PROCESS);
|
||||
if (!current->debug_obj) current->debug_obj = (struct debug_obj *)grab_object( debug_obj );
|
||||
}
|
||||
else if (current->process->debug_children)
|
||||
else if (parent->debug_children)
|
||||
{
|
||||
process->debug_obj = current->process->debug_obj;
|
||||
process->debug_obj = parent->debug_obj;
|
||||
/* debug_children is set to 1 by default */
|
||||
}
|
||||
|
||||
|
@ -1271,6 +1279,7 @@ DECL_HANDLER(new_process)
|
|||
|
||||
done:
|
||||
if (process) release_object( process );
|
||||
if (debug_obj) release_object( debug_obj );
|
||||
if (token) release_object( token );
|
||||
release_object( parent );
|
||||
release_object( info );
|
||||
|
|
|
@ -114,6 +114,7 @@ extern data_size_t init_process( struct thread *thread );
|
|||
extern struct thread *get_process_first_thread( struct process *process );
|
||||
extern struct process *get_process_from_id( process_id_t id );
|
||||
extern struct process *get_process_from_handle( obj_handle_t handle, unsigned int access );
|
||||
extern struct debug_obj *get_debug_obj( struct process *process, obj_handle_t handle, unsigned int access );
|
||||
extern int process_set_debugger( struct process *process, struct thread *thread );
|
||||
extern void debugger_detach( struct process *process, struct debug_obj *debug_obj );
|
||||
extern int set_process_debug_flag( struct process *process, int flag );
|
||||
|
|
|
@ -804,6 +804,7 @@ typedef struct
|
|||
/* Create a new process from the context of the parent */
|
||||
@REQ(new_process)
|
||||
obj_handle_t token; /* process token */
|
||||
obj_handle_t debug; /* process debug object */
|
||||
obj_handle_t parent_process; /* parent process */
|
||||
int inherit_all; /* inherit all handles from parent */
|
||||
unsigned int create_flags; /* creation flags */
|
||||
|
|
|
@ -708,15 +708,16 @@ C_ASSERT( sizeof(unsigned int) == 4 );
|
|||
C_ASSERT( sizeof(unsigned short) == 2 );
|
||||
C_ASSERT( sizeof(user_handle_t) == 4 );
|
||||
C_ASSERT( FIELD_OFFSET(struct new_process_request, token) == 12 );
|
||||
C_ASSERT( FIELD_OFFSET(struct new_process_request, parent_process) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct new_process_request, inherit_all) == 20 );
|
||||
C_ASSERT( FIELD_OFFSET(struct new_process_request, create_flags) == 24 );
|
||||
C_ASSERT( FIELD_OFFSET(struct new_process_request, socket_fd) == 28 );
|
||||
C_ASSERT( FIELD_OFFSET(struct new_process_request, access) == 32 );
|
||||
C_ASSERT( FIELD_OFFSET(struct new_process_request, cpu) == 36 );
|
||||
C_ASSERT( FIELD_OFFSET(struct new_process_request, info_size) == 40 );
|
||||
C_ASSERT( FIELD_OFFSET(struct new_process_request, handles_size) == 44 );
|
||||
C_ASSERT( sizeof(struct new_process_request) == 48 );
|
||||
C_ASSERT( FIELD_OFFSET(struct new_process_request, debug) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct new_process_request, parent_process) == 20 );
|
||||
C_ASSERT( FIELD_OFFSET(struct new_process_request, inherit_all) == 24 );
|
||||
C_ASSERT( FIELD_OFFSET(struct new_process_request, create_flags) == 28 );
|
||||
C_ASSERT( FIELD_OFFSET(struct new_process_request, socket_fd) == 32 );
|
||||
C_ASSERT( FIELD_OFFSET(struct new_process_request, access) == 36 );
|
||||
C_ASSERT( FIELD_OFFSET(struct new_process_request, cpu) == 40 );
|
||||
C_ASSERT( FIELD_OFFSET(struct new_process_request, info_size) == 44 );
|
||||
C_ASSERT( FIELD_OFFSET(struct new_process_request, handles_size) == 48 );
|
||||
C_ASSERT( sizeof(struct new_process_request) == 56 );
|
||||
C_ASSERT( FIELD_OFFSET(struct new_process_reply, info) == 8 );
|
||||
C_ASSERT( FIELD_OFFSET(struct new_process_reply, pid) == 12 );
|
||||
C_ASSERT( FIELD_OFFSET(struct new_process_reply, handle) == 16 );
|
||||
|
|
|
@ -1310,6 +1310,7 @@ typedef void (*dump_func)( const void *req );
|
|||
static void dump_new_process_request( const struct new_process_request *req )
|
||||
{
|
||||
fprintf( stderr, " token=%04x", req->token );
|
||||
fprintf( stderr, ", debug=%04x", req->debug );
|
||||
fprintf( stderr, ", parent_process=%04x", req->parent_process );
|
||||
fprintf( stderr, ", inherit_all=%d", req->inherit_all );
|
||||
fprintf( stderr, ", create_flags=%08x", req->create_flags );
|
||||
|
|
Loading…
Reference in a new issue