Commit da8acbc4 authored by Alexandre Julliard's avatar Alexandre Julliard

server: Define an architecture-independent structure for process startup info.

parent f6f458a1
...@@ -126,89 +126,118 @@ static inline NTSTATUS init_teb( TEB *teb ) ...@@ -126,89 +126,118 @@ static inline NTSTATUS init_teb( TEB *teb )
/*********************************************************************** /***********************************************************************
* fix_unicode_string * get_unicode_string
* *
* Make sure the unicode string doesn't point beyond the end pointer * Copy a unicode string from the startup info.
*/ */
static inline void fix_unicode_string( UNICODE_STRING *str, const char *end_ptr ) static inline void get_unicode_string( UNICODE_STRING *str, WCHAR **src, WCHAR **dst, UINT len )
{ {
if ((char *)str->Buffer >= end_ptr) str->Buffer = *dst;
{ str->Length = len;
str->Length = str->MaximumLength = 0; str->MaximumLength = len + sizeof(WCHAR);
str->Buffer = NULL; memcpy( str->Buffer, *src, len );
return; str->Buffer[len / sizeof(WCHAR)] = 0;
} *src += len / sizeof(WCHAR);
if ((char *)str->Buffer + str->MaximumLength > end_ptr) *dst += len / sizeof(WCHAR) + 1;
{
str->MaximumLength = (end_ptr - (char *)str->Buffer) & ~(sizeof(WCHAR) - 1);
}
if (str->Length >= str->MaximumLength)
{
if (str->MaximumLength >= sizeof(WCHAR))
str->Length = str->MaximumLength - sizeof(WCHAR);
else
str->Length = str->MaximumLength = 0;
}
} }
/*********************************************************************** /***********************************************************************
* init_user_process_params * init_user_process_params
* *
* Fill the RTL_USER_PROCESS_PARAMETERS structure from the server. * Fill the RTL_USER_PROCESS_PARAMETERS structure from the server.
*/ */
static NTSTATUS init_user_process_params( SIZE_T info_size, HANDLE *exe_file ) static NTSTATUS init_user_process_params( SIZE_T data_size, HANDLE *exe_file )
{ {
void *ptr; void *ptr;
SIZE_T env_size; WCHAR *src, *dst;
SIZE_T info_size, env_size, size, alloc_size;
NTSTATUS status; NTSTATUS status;
startup_info_t *info;
RTL_USER_PROCESS_PARAMETERS *params = NULL; RTL_USER_PROCESS_PARAMETERS *params = NULL;
status = NtAllocateVirtualMemory( NtCurrentProcess(), (void **)&params, 0, &info_size, if (!(info = RtlAllocateHeap( GetProcessHeap(), 0, data_size )))
MEM_COMMIT, PAGE_READWRITE ); return STATUS_NO_MEMORY;
if (status != STATUS_SUCCESS) return status;
params->AllocationSize = info_size;
NtCurrentTeb()->Peb->ProcessParameters = params;
SERVER_START_REQ( get_startup_info ) SERVER_START_REQ( get_startup_info )
{ {
wine_server_set_reply( req, params, info_size ); wine_server_set_reply( req, info, data_size );
if (!(status = wine_server_call( req ))) if (!(status = wine_server_call( req )))
{ {
info_size = wine_server_reply_size( reply ); data_size = wine_server_reply_size( reply );
info_size = reply->info_size;
env_size = data_size - info_size;
*exe_file = wine_server_ptr_handle( reply->exe_file ); *exe_file = wine_server_ptr_handle( reply->exe_file );
params->hStdInput = wine_server_ptr_handle( reply->hstdin );
params->hStdOutput = wine_server_ptr_handle( reply->hstdout );
params->hStdError = wine_server_ptr_handle( reply->hstderr );
} }
} }
SERVER_END_REQ; SERVER_END_REQ;
if (status != STATUS_SUCCESS) return status; if (status != STATUS_SUCCESS) return status;
if (params->Size > info_size) params->Size = info_size; size = sizeof(*params);
size += MAX_NT_PATH_LENGTH * sizeof(WCHAR);
size += info->dllpath_len + sizeof(WCHAR);
size += info->imagepath_len + sizeof(WCHAR);
size += info->cmdline_len + sizeof(WCHAR);
size += info->title_len + sizeof(WCHAR);
size += info->desktop_len + sizeof(WCHAR);
size += info->shellinfo_len + sizeof(WCHAR);
size += info->runtime_len + sizeof(WCHAR);
alloc_size = size;
status = NtAllocateVirtualMemory( NtCurrentProcess(), (void **)&params, 0, &alloc_size,
MEM_COMMIT, PAGE_READWRITE );
if (status != STATUS_SUCCESS) goto done;
/* make sure the strings are valid */ NtCurrentTeb()->Peb->ProcessParameters = params;
fix_unicode_string( &params->CurrentDirectory.DosPath, (char *)info_size ); params->AllocationSize = alloc_size;
fix_unicode_string( &params->DllPath, (char *)info_size ); params->Size = size;
fix_unicode_string( &params->ImagePathName, (char *)info_size ); params->Flags = PROCESS_PARAMS_FLAG_NORMALIZED;
fix_unicode_string( &params->CommandLine, (char *)info_size ); params->DebugFlags = info->debug_flags;
fix_unicode_string( &params->WindowTitle, (char *)info_size ); params->ConsoleHandle = wine_server_ptr_handle( info->console );
fix_unicode_string( &params->Desktop, (char *)info_size ); params->ConsoleFlags = info->console_flags;
fix_unicode_string( &params->ShellInfo, (char *)info_size ); params->hStdInput = wine_server_ptr_handle( info->hstdin );
fix_unicode_string( &params->RuntimeInfo, (char *)info_size ); params->hStdOutput = wine_server_ptr_handle( info->hstdout );
params->hStdError = wine_server_ptr_handle( info->hstderr );
params->dwX = info->x;
params->dwY = info->y;
params->dwXSize = info->xsize;
params->dwYSize = info->ysize;
params->dwXCountChars = info->xchars;
params->dwYCountChars = info->ychars;
params->dwFillAttribute = info->attribute;
params->dwFlags = info->flags;
params->wShowWindow = info->show;
src = (WCHAR *)(info + 1);
dst = (WCHAR *)(params + 1);
/* current directory needs more space */
get_unicode_string( &params->CurrentDirectory.DosPath, &src, &dst, info->curdir_len );
params->CurrentDirectory.DosPath.MaximumLength = MAX_NT_PATH_LENGTH * sizeof(WCHAR);
dst = (WCHAR *)(params + 1) + MAX_NT_PATH_LENGTH;
get_unicode_string( &params->DllPath, &src, &dst, info->dllpath_len );
get_unicode_string( &params->ImagePathName, &src, &dst, info->imagepath_len );
get_unicode_string( &params->CommandLine, &src, &dst, info->cmdline_len );
get_unicode_string( &params->WindowTitle, &src, &dst, info->title_len );
get_unicode_string( &params->Desktop, &src, &dst, info->desktop_len );
get_unicode_string( &params->ShellInfo, &src, &dst, info->shellinfo_len );
/* runtime info isn't a real string */
params->RuntimeInfo.Buffer = dst;
params->RuntimeInfo.Length = params->RuntimeInfo.MaximumLength = info->runtime_len;
memcpy( dst, src, info->runtime_len );
/* environment needs to be a separate memory block */ /* environment needs to be a separate memory block */
env_size = info_size - params->Size;
if (!env_size) env_size = 1;
ptr = NULL; ptr = NULL;
status = NtAllocateVirtualMemory( NtCurrentProcess(), &ptr, 0, &env_size, alloc_size = max( 1, env_size );
status = NtAllocateVirtualMemory( NtCurrentProcess(), &ptr, 0, &alloc_size,
MEM_COMMIT, PAGE_READWRITE ); MEM_COMMIT, PAGE_READWRITE );
if (status != STATUS_SUCCESS) return status; if (status != STATUS_SUCCESS) goto done;
memcpy( ptr, (char *)params + params->Size, info_size - params->Size ); memcpy( ptr, (char *)info + info_size, env_size );
params->Environment = ptr; params->Environment = ptr;
RtlNormalizeProcessParams( params ); done:
RtlFreeHeap( GetProcessHeap(), 0, info );
return status; return status;
} }
......
...@@ -213,6 +213,42 @@ typedef __int64 timeout_t; ...@@ -213,6 +213,42 @@ typedef __int64 timeout_t;
typedef struct typedef struct
{ {
unsigned int debug_flags;
unsigned int console_flags;
obj_handle_t console;
obj_handle_t hstdin;
obj_handle_t hstdout;
obj_handle_t hstderr;
unsigned int x;
unsigned int y;
unsigned int xsize;
unsigned int ysize;
unsigned int xchars;
unsigned int ychars;
unsigned int attribute;
unsigned int flags;
unsigned int show;
data_size_t curdir_len;
data_size_t dllpath_len;
data_size_t imagepath_len;
data_size_t cmdline_len;
data_size_t title_len;
data_size_t desktop_len;
data_size_t shellinfo_len;
data_size_t runtime_len;
} startup_info_t;
typedef struct
{
atom_t atom; atom_t atom;
int string; int string;
lparam_t data; lparam_t data;
...@@ -535,14 +571,12 @@ struct new_process_request ...@@ -535,14 +571,12 @@ struct new_process_request
unsigned int create_flags; unsigned int create_flags;
int socket_fd; int socket_fd;
obj_handle_t exe_file; obj_handle_t exe_file;
obj_handle_t hstdin;
obj_handle_t hstdout;
obj_handle_t hstderr;
unsigned int process_access; unsigned int process_access;
unsigned int process_attr; unsigned int process_attr;
unsigned int thread_access; unsigned int thread_access;
unsigned int thread_attr; unsigned int thread_attr;
/* VARARG(info,startup_info); */ data_size_t info_size;
/* VARARG(info,startup_info,info_size); */
/* VARARG(env,unicode_str); */ /* VARARG(env,unicode_str); */
}; };
struct new_process_reply struct new_process_reply
...@@ -597,10 +631,8 @@ struct get_startup_info_reply ...@@ -597,10 +631,8 @@ struct get_startup_info_reply
{ {
struct reply_header __header; struct reply_header __header;
obj_handle_t exe_file; obj_handle_t exe_file;
obj_handle_t hstdin; data_size_t info_size;
obj_handle_t hstdout; /* VARARG(info,startup_info,info_size); */
obj_handle_t hstderr;
/* VARARG(info,startup_info); */
/* VARARG(env,unicode_str); */ /* VARARG(env,unicode_str); */
}; };
...@@ -5315,6 +5347,6 @@ union generic_reply ...@@ -5315,6 +5347,6 @@ union generic_reply
struct set_window_layered_info_reply set_window_layered_info_reply; struct set_window_layered_info_reply set_window_layered_info_reply;
}; };
#define SERVER_PROTOCOL_VERSION 388 #define SERVER_PROTOCOL_VERSION 389
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
...@@ -102,13 +102,11 @@ static const struct fd_ops process_fd_ops = ...@@ -102,13 +102,11 @@ static const struct fd_ops process_fd_ops =
struct startup_info struct startup_info
{ {
struct object obj; /* object header */ struct object obj; /* object header */
obj_handle_t hstdin; /* handle for stdin */
obj_handle_t hstdout; /* handle for stdout */
obj_handle_t hstderr; /* handle for stderr */
struct file *exe_file; /* file handle for main exe */ struct file *exe_file; /* file handle for main exe */
struct process *process; /* created process */ struct process *process; /* created process */
data_size_t data_size; /* size of startup data */ data_size_t info_size; /* size of startup info */
void *data; /* data for startup info */ data_size_t data_size; /* size of whole startup data */
startup_info_t *data; /* data for startup info */
}; };
static void startup_info_dump( struct object *obj, int verbose ); static void startup_info_dump( struct object *obj, int verbose );
...@@ -478,7 +476,7 @@ static void startup_info_dump( struct object *obj, int verbose ) ...@@ -478,7 +476,7 @@ static void startup_info_dump( struct object *obj, int verbose )
assert( obj->ops == &startup_info_ops ); assert( obj->ops == &startup_info_ops );
fprintf( stderr, "Startup info in=%04x out=%04x err=%04x\n", fprintf( stderr, "Startup info in=%04x out=%04x err=%04x\n",
info->hstdin, info->hstdout, info->hstderr ); info->data->hstdin, info->data->hstdout, info->data->hstderr );
} }
static int startup_info_signaled( struct object *obj, struct thread *thread ) static int startup_info_signaled( struct object *obj, struct thread *thread )
...@@ -891,19 +889,46 @@ DECL_HANDLER(new_process) ...@@ -891,19 +889,46 @@ DECL_HANDLER(new_process)
/* build the startup info for a new process */ /* build the startup info for a new process */
if (!(info = alloc_object( &startup_info_ops ))) return; if (!(info = alloc_object( &startup_info_ops ))) return;
info->hstdin = req->hstdin; info->exe_file = NULL;
info->hstdout = req->hstdout; info->process = NULL;
info->hstderr = req->hstderr; info->data = NULL;
info->exe_file = NULL;
info->process = NULL;
info->data_size = get_req_data_size();
info->data = NULL;
if (req->exe_file && if (req->exe_file &&
!(info->exe_file = get_file_obj( current->process, req->exe_file, FILE_READ_DATA ))) !(info->exe_file = get_file_obj( current->process, req->exe_file, FILE_READ_DATA )))
goto done; goto done;
if (!(info->data = memdup( get_req_data(), info->data_size ))) goto done; info->data_size = get_req_data_size();
info->info_size = min( req->info_size, info->data_size );
if (req->info_size < sizeof(*info->data))
{
/* make sure we have a full startup_info_t structure */
data_size_t env_size = info->data_size - info->info_size;
data_size_t info_size = min( req->info_size, FIELD_OFFSET( startup_info_t, curdir_len ));
if (!(info->data = mem_alloc( sizeof(*info->data) + env_size ))) goto done;
memcpy( info->data, get_req_data(), info_size );
memset( (char *)info->data + info_size, 0, sizeof(*info->data) - info_size );
memcpy( info->data + 1, (const char *)get_req_data() + req->info_size, env_size );
info->info_size = sizeof(startup_info_t);
info->data_size = info->info_size + env_size;
}
else
{
data_size_t pos = sizeof(*info->data);
if (!(info->data = memdup( get_req_data(), info->data_size ))) goto done;
#define FIXUP_LEN(len) do { (len) = min( (len), info->info_size - pos ); pos += (len); } while(0)
FIXUP_LEN( info->data->curdir_len );
FIXUP_LEN( info->data->dllpath_len );
FIXUP_LEN( info->data->imagepath_len );
FIXUP_LEN( info->data->cmdline_len );
FIXUP_LEN( info->data->title_len );
FIXUP_LEN( info->data->desktop_len );
FIXUP_LEN( info->data->shellinfo_len );
FIXUP_LEN( info->data->runtime_len );
#undef FIXUP_LEN
}
if (!(thread = create_process( socket_fd, current, req->inherit_all ))) goto done; if (!(thread = create_process( socket_fd, current, req->inherit_all ))) goto done;
process = thread->process; process = thread->process;
...@@ -923,17 +948,17 @@ DECL_HANDLER(new_process) ...@@ -923,17 +948,17 @@ DECL_HANDLER(new_process)
* like if hConOut and hConIn are console handles, then they should be on the same * like if hConOut and hConIn are console handles, then they should be on the same
* physical console * physical console
*/ */
inherit_console( current, process, req->inherit_all ? req->hstdin : 0 ); inherit_console( current, process, req->inherit_all ? info->data->hstdin : 0 );
} }
if (!req->inherit_all && !(req->create_flags & CREATE_NEW_CONSOLE)) if (!req->inherit_all && !(req->create_flags & CREATE_NEW_CONSOLE))
{ {
info->hstdin = duplicate_handle( parent, req->hstdin, process, info->data->hstdin = duplicate_handle( parent, info->data->hstdin, process,
0, OBJ_INHERIT, DUPLICATE_SAME_ACCESS ); 0, OBJ_INHERIT, DUPLICATE_SAME_ACCESS );
info->hstdout = duplicate_handle( parent, req->hstdout, process, info->data->hstdout = duplicate_handle( parent, info->data->hstdout, process,
0, OBJ_INHERIT, DUPLICATE_SAME_ACCESS ); 0, OBJ_INHERIT, DUPLICATE_SAME_ACCESS );
info->hstderr = duplicate_handle( parent, req->hstderr, process, info->data->hstderr = duplicate_handle( parent, info->data->hstderr, process,
0, OBJ_INHERIT, DUPLICATE_SAME_ACCESS ); 0, OBJ_INHERIT, DUPLICATE_SAME_ACCESS );
/* some handles above may have been invalid; this is not an error */ /* some handles above may have been invalid; this is not an error */
if (get_error() == STATUS_INVALID_HANDLE || if (get_error() == STATUS_INVALID_HANDLE ||
get_error() == STATUS_OBJECT_TYPE_MISMATCH) clear_error(); get_error() == STATUS_OBJECT_TYPE_MISMATCH) clear_error();
...@@ -985,11 +1010,8 @@ DECL_HANDLER(get_startup_info) ...@@ -985,11 +1010,8 @@ DECL_HANDLER(get_startup_info)
if (info->exe_file && if (info->exe_file &&
!(reply->exe_file = alloc_handle( process, info->exe_file, GENERIC_READ, 0 ))) return; !(reply->exe_file = alloc_handle( process, info->exe_file, GENERIC_READ, 0 ))) return;
reply->hstdin = info->hstdin;
reply->hstdout = info->hstdout;
reply->hstderr = info->hstderr;
/* we return the data directly without making a copy so this can only be called once */ /* we return the data directly without making a copy so this can only be called once */
reply->info_size = info->info_size;
size = info->data_size; size = info->data_size;
if (size > get_reply_max_size()) size = get_reply_max_size(); if (size > get_reply_max_size()) size = get_reply_max_size();
set_reply_data_ptr( info->data, size ); set_reply_data_ptr( info->data, size );
......
...@@ -226,6 +226,42 @@ struct wake_up_reply ...@@ -226,6 +226,42 @@ struct wake_up_reply
typedef __int64 timeout_t; typedef __int64 timeout_t;
#define TIMEOUT_INFINITE (((timeout_t)0x7fffffff) << 32 | 0xffffffff) #define TIMEOUT_INFINITE (((timeout_t)0x7fffffff) << 32 | 0xffffffff)
/* structure for process startup info */
typedef struct
{
unsigned int debug_flags;
unsigned int console_flags;
obj_handle_t console;
obj_handle_t hstdin;
obj_handle_t hstdout;
obj_handle_t hstderr;
unsigned int x;
unsigned int y;
unsigned int xsize;
unsigned int ysize;
unsigned int xchars;
unsigned int ychars;
unsigned int attribute;
unsigned int flags;
unsigned int show;
data_size_t curdir_len;
data_size_t dllpath_len;
data_size_t imagepath_len;
data_size_t cmdline_len;
data_size_t title_len;
data_size_t desktop_len;
data_size_t shellinfo_len;
data_size_t runtime_len;
/* VARARG(curdir,unicode_str,curdir_len); */
/* VARARG(dllpath,unicode_str,dllpath_len); */
/* VARARG(imagepath,unicode_str,imagepath_len); */
/* VARARG(cmdline,unicode_str,cmdline_len); */
/* VARARG(title,unicode_str,title_len); */
/* VARARG(desktop,unicode_str,desktop_len); */
/* VARARG(shellinfo,unicode_str,shellinfo_len); */
/* VARARG(runtime,unicode_str,runtime_len); */
} startup_info_t;
/* structure returned in the list of window properties */ /* structure returned in the list of window properties */
typedef struct typedef struct
{ {
...@@ -549,14 +585,12 @@ typedef union ...@@ -549,14 +585,12 @@ typedef union
unsigned int create_flags; /* creation flags */ unsigned int create_flags; /* creation flags */
int socket_fd; /* file descriptor for process socket */ int socket_fd; /* file descriptor for process socket */
obj_handle_t exe_file; /* file handle for main exe */ obj_handle_t exe_file; /* file handle for main exe */
obj_handle_t hstdin; /* handle for stdin */
obj_handle_t hstdout; /* handle for stdout */
obj_handle_t hstderr; /* handle for stderr */
unsigned int process_access; /* access rights for process object */ unsigned int process_access; /* access rights for process object */
unsigned int process_attr; /* attributes for process object */ unsigned int process_attr; /* attributes for process object */
unsigned int thread_access; /* access rights for thread object */ unsigned int thread_access; /* access rights for thread object */
unsigned int thread_attr; /* attributes for thread object */ unsigned int thread_attr; /* attributes for thread object */
VARARG(info,startup_info); /* startup information */ data_size_t info_size; /* size of startup info */
VARARG(info,startup_info,info_size); /* startup information */
VARARG(env,unicode_str); /* environment for new process */ VARARG(env,unicode_str); /* environment for new process */
@REPLY @REPLY
obj_handle_t info; /* new process info handle */ obj_handle_t info; /* new process info handle */
...@@ -592,10 +626,8 @@ typedef union ...@@ -592,10 +626,8 @@ typedef union
@REQ(get_startup_info) @REQ(get_startup_info)
@REPLY @REPLY
obj_handle_t exe_file; /* file handle for main exe */ obj_handle_t exe_file; /* file handle for main exe */
obj_handle_t hstdin; /* handle for stdin */ data_size_t info_size; /* size of startup info */
obj_handle_t hstdout; /* handle for stdout */ VARARG(info,startup_info,info_size); /* startup information */
obj_handle_t hstderr; /* handle for stderr */
VARARG(info,startup_info); /* startup information */
VARARG(env,unicode_str); /* environment */ VARARG(env,unicode_str); /* environment */
@END @END
......
...@@ -627,13 +627,11 @@ C_ASSERT( FIELD_OFFSET(struct new_process_request, inherit_all) == 12 ); ...@@ -627,13 +627,11 @@ C_ASSERT( FIELD_OFFSET(struct new_process_request, inherit_all) == 12 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, create_flags) == 16 ); C_ASSERT( FIELD_OFFSET(struct new_process_request, create_flags) == 16 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, socket_fd) == 20 ); C_ASSERT( FIELD_OFFSET(struct new_process_request, socket_fd) == 20 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, exe_file) == 24 ); C_ASSERT( FIELD_OFFSET(struct new_process_request, exe_file) == 24 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, hstdin) == 28 ); C_ASSERT( FIELD_OFFSET(struct new_process_request, process_access) == 28 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, hstdout) == 32 ); C_ASSERT( FIELD_OFFSET(struct new_process_request, process_attr) == 32 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, hstderr) == 36 ); C_ASSERT( FIELD_OFFSET(struct new_process_request, thread_access) == 36 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, process_access) == 40 ); C_ASSERT( FIELD_OFFSET(struct new_process_request, thread_attr) == 40 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, process_attr) == 44 ); C_ASSERT( FIELD_OFFSET(struct new_process_request, info_size) == 44 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, thread_access) == 48 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, thread_attr) == 52 );
C_ASSERT( FIELD_OFFSET(struct new_process_reply, info) == 8 ); 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, pid) == 12 );
C_ASSERT( FIELD_OFFSET(struct new_process_reply, phandle) == 16 ); C_ASSERT( FIELD_OFFSET(struct new_process_reply, phandle) == 16 );
...@@ -652,10 +650,8 @@ C_ASSERT( FIELD_OFFSET(struct new_thread_reply, tid) == 8 ); ...@@ -652,10 +650,8 @@ C_ASSERT( FIELD_OFFSET(struct new_thread_reply, tid) == 8 );
C_ASSERT( FIELD_OFFSET(struct new_thread_reply, handle) == 12 ); C_ASSERT( FIELD_OFFSET(struct new_thread_reply, handle) == 12 );
C_ASSERT( sizeof(struct new_thread_reply) == 16 ); C_ASSERT( sizeof(struct new_thread_reply) == 16 );
C_ASSERT( FIELD_OFFSET(struct get_startup_info_reply, exe_file) == 8 ); C_ASSERT( FIELD_OFFSET(struct get_startup_info_reply, exe_file) == 8 );
C_ASSERT( FIELD_OFFSET(struct get_startup_info_reply, hstdin) == 12 ); C_ASSERT( FIELD_OFFSET(struct get_startup_info_reply, info_size) == 12 );
C_ASSERT( FIELD_OFFSET(struct get_startup_info_reply, hstdout) == 16 ); C_ASSERT( sizeof(struct get_startup_info_reply) == 16 );
C_ASSERT( FIELD_OFFSET(struct get_startup_info_reply, hstderr) == 20 );
C_ASSERT( sizeof(struct get_startup_info_reply) == 24 );
C_ASSERT( FIELD_OFFSET(struct init_process_done_request, gui) == 12 ); C_ASSERT( FIELD_OFFSET(struct init_process_done_request, gui) == 12 );
C_ASSERT( FIELD_OFFSET(struct init_process_done_request, module) == 16 ); C_ASSERT( FIELD_OFFSET(struct init_process_done_request, module) == 16 );
C_ASSERT( FIELD_OFFSET(struct init_process_done_request, ldt_copy) == 24 ); C_ASSERT( FIELD_OFFSET(struct init_process_done_request, ldt_copy) == 24 );
......
...@@ -675,65 +675,38 @@ static void dump_varargs_debug_event( const char *prefix, data_size_t size ) ...@@ -675,65 +675,38 @@ static void dump_varargs_debug_event( const char *prefix, data_size_t size )
} }
/* dump a unicode string contained in a buffer; helper for dump_varargs_startup_info */ /* dump a unicode string contained in a buffer; helper for dump_varargs_startup_info */
static void dump_inline_unicode_string( const UNICODE_STRING *str, const void *data, data_size_t size ) static data_size_t dump_inline_unicode_string( const char *prefix, data_size_t pos, data_size_t len, data_size_t total_size )
{ {
size_t length = str->Length; fputs( prefix, stderr );
size_t offset = (size_t)str->Buffer; if (pos >= total_size) return pos;
if (len > total_size - pos) len = total_size - pos;
if (offset >= size) return; len /= sizeof(WCHAR);
if (offset + length > size) length = size - offset; dump_strW( (const WCHAR *)cur_data + pos/sizeof(WCHAR), len, stderr, "\"\"" );
dump_strW( (const WCHAR *)data + offset/sizeof(WCHAR), length/sizeof(WCHAR), stderr, "\"\"" ); return pos + len * sizeof(WCHAR);
} }
static void dump_varargs_startup_info( const char *prefix, data_size_t size ) static void dump_varargs_startup_info( const char *prefix, data_size_t size )
{ {
const RTL_USER_PROCESS_PARAMETERS *ptr = cur_data; startup_info_t info;
RTL_USER_PROCESS_PARAMETERS params; data_size_t pos = sizeof(info);
if (size < sizeof(params.Size)) memset( &info, 0, sizeof(info) );
{ memcpy( &info, cur_data, min( size, sizeof(info) ));
fprintf( stderr, "%s{}", prefix );
return; fprintf( stderr,
} "%s{debug_flags=%x,console_flags=%x,console=%04x,hstdin=%04x,hstdout=%04x,hstderr=%04x,"
if (size > ptr->Size) size = ptr->Size; "x=%u,y=%u,xsize=%u,ysize=%u,xchars=%u,ychars=%u,attribute=%02x,flags=%x,show=%u",
memset( &params, 0, sizeof(params) ); prefix, info.debug_flags, info.console_flags, info.console,
memcpy( &params, ptr, min( size, sizeof(params) )); info.hstdin, info.hstdout, info.hstderr, info.x, info.y, info.xsize, info.ysize,
info.xchars, info.ychars, info.attribute, info.flags, info.show );
fprintf( stderr, "%s{AllocationSize=%x,", prefix, params.AllocationSize ); pos = dump_inline_unicode_string( ",curdir=L\"", pos, info.curdir_len, size );
fprintf( stderr, "Size=%x,", params.Size ); pos = dump_inline_unicode_string( "\",dllpath=L\"", pos, info.dllpath_len, size );
fprintf( stderr, "Flags=%x,", params.Flags ); pos = dump_inline_unicode_string( "\",imagepath=L\"", pos, info.imagepath_len, size );
fprintf( stderr, "DebugFlags=%x,", params.DebugFlags ); pos = dump_inline_unicode_string( "\",cmdline=L\"", pos, info.cmdline_len, size );
fprintf( stderr, "ConsoleHandle=%p,", params.ConsoleHandle ); pos = dump_inline_unicode_string( "\",title=L\"", pos, info.title_len, size );
fprintf( stderr, "ConsoleFlags=%x,", params.ConsoleFlags ); pos = dump_inline_unicode_string( "\",desktop=L\"", pos, info.desktop_len, size );
fprintf( stderr, "hStdInput=%p,", params.hStdInput ); pos = dump_inline_unicode_string( "\",shellinfo=L\"", pos, info.shellinfo_len, size );
fprintf( stderr, "hStdOutput=%p,", params.hStdOutput ); pos = dump_inline_unicode_string( "\",runtime=L\"", pos, info.runtime_len, size );
fprintf( stderr, "hStdError=%p,", params.hStdError );
fprintf( stderr, "CurrentDirectory.Handle=%p,", params.CurrentDirectory.Handle );
fprintf( stderr, "dwX=%d,", params.dwX );
fprintf( stderr, "dwY=%d,", params.dwY );
fprintf( stderr, "dwXSize=%d,", params.dwXSize );
fprintf( stderr, "dwYSize=%d,", params.dwYSize );
fprintf( stderr, "dwXCountChars=%d,", params.dwXCountChars );
fprintf( stderr, "dwYCountChars=%d,", params.dwYCountChars );
fprintf( stderr, "dwFillAttribute=%x,", params.dwFillAttribute );
fprintf( stderr, "dwFlags=%x,", params.dwFlags );
fprintf( stderr, "wShowWindow=%x,", params.wShowWindow );
fprintf( stderr, "CurrentDirectory.DosPath=L\"" );
dump_inline_unicode_string( &params.CurrentDirectory.DosPath, cur_data, size );
fprintf( stderr, "\",DllPath=L\"" );
dump_inline_unicode_string( &params.DllPath, cur_data, size );
fprintf( stderr, "\",ImagePathName=L\"" );
dump_inline_unicode_string( &params.ImagePathName, cur_data, size );
fprintf( stderr, "\",CommandLine=L\"" );
dump_inline_unicode_string( &params.CommandLine, cur_data, size );
fprintf( stderr, "\",WindowTitle=L\"" );
dump_inline_unicode_string( &params.WindowTitle, cur_data, size );
fprintf( stderr, "\",Desktop=L\"" );
dump_inline_unicode_string( &params.Desktop, cur_data, size );
fprintf( stderr, "\",ShellInfo=L\"" );
dump_inline_unicode_string( &params.ShellInfo, cur_data, size );
fprintf( stderr, "\",RuntimeInfo=L\"" );
dump_inline_unicode_string( &params.RuntimeInfo, cur_data, size );
fprintf( stderr, "\"}" ); fprintf( stderr, "\"}" );
remove_data( size ); remove_data( size );
} }
...@@ -1025,14 +998,12 @@ static void dump_new_process_request( const struct new_process_request *req ) ...@@ -1025,14 +998,12 @@ static void dump_new_process_request( const struct new_process_request *req )
fprintf( stderr, ", create_flags=%08x", req->create_flags ); fprintf( stderr, ", create_flags=%08x", req->create_flags );
fprintf( stderr, ", socket_fd=%d", req->socket_fd ); fprintf( stderr, ", socket_fd=%d", req->socket_fd );
fprintf( stderr, ", exe_file=%04x", req->exe_file ); fprintf( stderr, ", exe_file=%04x", req->exe_file );
fprintf( stderr, ", hstdin=%04x", req->hstdin );
fprintf( stderr, ", hstdout=%04x", req->hstdout );
fprintf( stderr, ", hstderr=%04x", req->hstderr );
fprintf( stderr, ", process_access=%08x", req->process_access ); fprintf( stderr, ", process_access=%08x", req->process_access );
fprintf( stderr, ", process_attr=%08x", req->process_attr ); fprintf( stderr, ", process_attr=%08x", req->process_attr );
fprintf( stderr, ", thread_access=%08x", req->thread_access ); fprintf( stderr, ", thread_access=%08x", req->thread_access );
fprintf( stderr, ", thread_attr=%08x", req->thread_attr ); fprintf( stderr, ", thread_attr=%08x", req->thread_attr );
dump_varargs_startup_info( ", info=", cur_size ); fprintf( stderr, ", info_size=%u", req->info_size );
dump_varargs_startup_info( ", info=", min(cur_size,req->info_size) );
dump_varargs_unicode_str( ", env=", cur_size ); dump_varargs_unicode_str( ", env=", cur_size );
} }
...@@ -1077,10 +1048,8 @@ static void dump_get_startup_info_request( const struct get_startup_info_request ...@@ -1077,10 +1048,8 @@ static void dump_get_startup_info_request( const struct get_startup_info_request
static void dump_get_startup_info_reply( const struct get_startup_info_reply *req ) static void dump_get_startup_info_reply( const struct get_startup_info_reply *req )
{ {
fprintf( stderr, " exe_file=%04x", req->exe_file ); fprintf( stderr, " exe_file=%04x", req->exe_file );
fprintf( stderr, ", hstdin=%04x", req->hstdin ); fprintf( stderr, ", info_size=%u", req->info_size );
fprintf( stderr, ", hstdout=%04x", req->hstdout ); dump_varargs_startup_info( ", info=", min(cur_size,req->info_size) );
fprintf( stderr, ", hstderr=%04x", req->hstderr );
dump_varargs_startup_info( ", info=", cur_size );
dump_varargs_unicode_str( ", env=", cur_size ); dump_varargs_unicode_str( ", env=", cur_size );
} }
......
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