server: Define an architecture-independent structure for process startup info.
This commit is contained in:
parent
f6f458a1eb
commit
da8acbc47d
|
@ -1430,85 +1430,127 @@ static int fork_and_exec( const char *filename, const WCHAR *cmdline, const WCHA
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* create_user_params
|
||||
*/
|
||||
static RTL_USER_PROCESS_PARAMETERS *create_user_params( LPCWSTR filename, LPCWSTR cmdline,
|
||||
LPCWSTR cur_dir, LPWSTR env, DWORD flags,
|
||||
const STARTUPINFOW *startup )
|
||||
static inline DWORD append_string( void **ptr, const WCHAR *str )
|
||||
{
|
||||
RTL_USER_PROCESS_PARAMETERS *params;
|
||||
UNICODE_STRING image_str, cmdline_str, curdir_str, desktop, title, runtime, newdir;
|
||||
NTSTATUS status;
|
||||
WCHAR buffer[MAX_PATH];
|
||||
DWORD len = strlenW( str );
|
||||
memcpy( *ptr, str, len * sizeof(WCHAR) );
|
||||
*ptr = (WCHAR *)*ptr + len;
|
||||
return len * sizeof(WCHAR);
|
||||
}
|
||||
|
||||
if(!GetLongPathNameW( filename, buffer, MAX_PATH ))
|
||||
lstrcpynW( buffer, filename, MAX_PATH );
|
||||
if(!GetFullPathNameW( buffer, MAX_PATH, buffer, NULL ))
|
||||
lstrcpynW( buffer, filename, MAX_PATH );
|
||||
RtlInitUnicodeString( &image_str, buffer );
|
||||
/***********************************************************************
|
||||
* create_startup_info
|
||||
*/
|
||||
static startup_info_t *create_startup_info( LPCWSTR filename, LPCWSTR cmdline,
|
||||
LPCWSTR cur_dir, LPWSTR env, DWORD flags,
|
||||
const STARTUPINFOW *startup, DWORD *info_size )
|
||||
{
|
||||
const RTL_USER_PROCESS_PARAMETERS *cur_params;
|
||||
startup_info_t *info;
|
||||
DWORD size;
|
||||
void *ptr;
|
||||
UNICODE_STRING newdir;
|
||||
WCHAR imagepath[MAX_PATH];
|
||||
HANDLE hstdin, hstdout, hstderr;
|
||||
|
||||
if(!GetLongPathNameW( filename, imagepath, MAX_PATH ))
|
||||
lstrcpynW( imagepath, filename, MAX_PATH );
|
||||
if(!GetFullPathNameW( imagepath, MAX_PATH, imagepath, NULL ))
|
||||
lstrcpynW( imagepath, filename, MAX_PATH );
|
||||
|
||||
cur_params = NtCurrentTeb()->Peb->ProcessParameters;
|
||||
|
||||
RtlInitUnicodeString( &cmdline_str, cmdline );
|
||||
newdir.Buffer = NULL;
|
||||
if (cur_dir)
|
||||
{
|
||||
if (RtlDosPathNameToNtPathName_U( cur_dir, &newdir, NULL, NULL ))
|
||||
{
|
||||
/* skip \??\ prefix */
|
||||
curdir_str.Buffer = newdir.Buffer + 4;
|
||||
curdir_str.Length = newdir.Length - 4 * sizeof(WCHAR);
|
||||
curdir_str.MaximumLength = newdir.MaximumLength - 4 * sizeof(WCHAR);
|
||||
}
|
||||
else cur_dir = NULL;
|
||||
cur_dir = newdir.Buffer + 4; /* skip \??\ prefix */
|
||||
else
|
||||
cur_dir = NULL;
|
||||
}
|
||||
if (startup->lpDesktop) RtlInitUnicodeString( &desktop, startup->lpDesktop );
|
||||
if (startup->lpTitle) RtlInitUnicodeString( &title, startup->lpTitle );
|
||||
if (startup->lpReserved2 && startup->cbReserved2)
|
||||
if (!cur_dir)
|
||||
{
|
||||
runtime.Length = 0;
|
||||
runtime.MaximumLength = startup->cbReserved2;
|
||||
runtime.Buffer = (WCHAR*)startup->lpReserved2;
|
||||
if (NtCurrentTeb()->Tib.SubSystemTib) /* FIXME: hack */
|
||||
cur_dir = ((WIN16_SUBSYSTEM_TIB *)NtCurrentTeb()->Tib.SubSystemTib)->curdir.DosPath.Buffer;
|
||||
else
|
||||
cur_dir = cur_params->CurrentDirectory.DosPath.Buffer;
|
||||
}
|
||||
|
||||
status = RtlCreateProcessParameters( ¶ms, &image_str, NULL,
|
||||
cur_dir ? &curdir_str : NULL,
|
||||
&cmdline_str, env,
|
||||
startup->lpTitle ? &title : NULL,
|
||||
startup->lpDesktop ? &desktop : NULL,
|
||||
NULL,
|
||||
(startup->lpReserved2 && startup->cbReserved2) ? &runtime : NULL );
|
||||
RtlFreeUnicodeString( &newdir );
|
||||
if (status != STATUS_SUCCESS)
|
||||
{
|
||||
SetLastError( RtlNtStatusToDosError(status) );
|
||||
return NULL;
|
||||
}
|
||||
size = sizeof(*info);
|
||||
size += strlenW( cur_dir ) * sizeof(WCHAR);
|
||||
size += cur_params->DllPath.Length;
|
||||
size += strlenW( imagepath ) * sizeof(WCHAR);
|
||||
size += strlenW( cmdline ) * sizeof(WCHAR);
|
||||
if (startup->lpTitle) size += strlenW( startup->lpTitle ) * sizeof(WCHAR);
|
||||
if (startup->lpDesktop) size += strlenW( startup->lpDesktop ) * sizeof(WCHAR);
|
||||
/* FIXME: shellinfo */
|
||||
if (startup->lpReserved2 && startup->cbReserved2) size += startup->cbReserved2;
|
||||
size = (size + 1) & ~1;
|
||||
*info_size = size;
|
||||
|
||||
if (flags & CREATE_NEW_PROCESS_GROUP) params->ConsoleFlags = 1;
|
||||
if (flags & CREATE_NEW_CONSOLE) params->ConsoleHandle = (HANDLE)1; /* FIXME: cf. kernel_main.c */
|
||||
if (!(info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size ))) goto done;
|
||||
|
||||
info->console_flags = cur_params->ConsoleFlags;
|
||||
if (flags & CREATE_NEW_PROCESS_GROUP) info->console_flags = 1;
|
||||
if (flags & CREATE_NEW_CONSOLE) info->console = (obj_handle_t)1; /* FIXME: cf. kernel_main.c */
|
||||
|
||||
if (startup->dwFlags & STARTF_USESTDHANDLES)
|
||||
{
|
||||
params->hStdInput = startup->hStdInput;
|
||||
params->hStdOutput = startup->hStdOutput;
|
||||
params->hStdError = startup->hStdError;
|
||||
hstdin = startup->hStdInput;
|
||||
hstdout = startup->hStdOutput;
|
||||
hstderr = startup->hStdError;
|
||||
}
|
||||
else
|
||||
{
|
||||
params->hStdInput = GetStdHandle( STD_INPUT_HANDLE );
|
||||
params->hStdOutput = GetStdHandle( STD_OUTPUT_HANDLE );
|
||||
params->hStdError = GetStdHandle( STD_ERROR_HANDLE );
|
||||
hstdin = GetStdHandle( STD_INPUT_HANDLE );
|
||||
hstdout = GetStdHandle( STD_OUTPUT_HANDLE );
|
||||
hstderr = GetStdHandle( STD_ERROR_HANDLE );
|
||||
}
|
||||
params->dwX = startup->dwX;
|
||||
params->dwY = startup->dwY;
|
||||
params->dwXSize = startup->dwXSize;
|
||||
params->dwYSize = startup->dwYSize;
|
||||
params->dwXCountChars = startup->dwXCountChars;
|
||||
params->dwYCountChars = startup->dwYCountChars;
|
||||
params->dwFillAttribute = startup->dwFillAttribute;
|
||||
params->dwFlags = startup->dwFlags;
|
||||
params->wShowWindow = startup->wShowWindow;
|
||||
return params;
|
||||
info->hstdin = wine_server_obj_handle( hstdin );
|
||||
info->hstdout = wine_server_obj_handle( hstdout );
|
||||
info->hstderr = wine_server_obj_handle( hstderr );
|
||||
if ((flags & (CREATE_NEW_CONSOLE | DETACHED_PROCESS)) != 0)
|
||||
{
|
||||
/* this is temporary (for console handles). We have no way to control that the handle is invalid in child process otherwise */
|
||||
if (is_console_handle(hstdin)) info->hstdin = wine_server_obj_handle( INVALID_HANDLE_VALUE );
|
||||
if (is_console_handle(hstdout)) info->hstdout = wine_server_obj_handle( INVALID_HANDLE_VALUE );
|
||||
if (is_console_handle(hstderr)) info->hstderr = wine_server_obj_handle( INVALID_HANDLE_VALUE );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_console_handle(hstdin)) info->hstdin = console_handle_unmap(hstdin);
|
||||
if (is_console_handle(hstdout)) info->hstdout = console_handle_unmap(hstdout);
|
||||
if (is_console_handle(hstderr)) info->hstderr = console_handle_unmap(hstderr);
|
||||
}
|
||||
|
||||
info->x = startup->dwX;
|
||||
info->y = startup->dwY;
|
||||
info->xsize = startup->dwXSize;
|
||||
info->ysize = startup->dwYSize;
|
||||
info->xchars = startup->dwXCountChars;
|
||||
info->ychars = startup->dwYCountChars;
|
||||
info->attribute = startup->dwFillAttribute;
|
||||
info->flags = startup->dwFlags;
|
||||
info->show = startup->wShowWindow;
|
||||
|
||||
ptr = info + 1;
|
||||
info->curdir_len = append_string( &ptr, cur_dir );
|
||||
info->dllpath_len = cur_params->DllPath.Length;
|
||||
memcpy( ptr, cur_params->DllPath.Buffer, cur_params->DllPath.Length );
|
||||
ptr = (char *)ptr + cur_params->DllPath.Length;
|
||||
info->imagepath_len = append_string( &ptr, imagepath );
|
||||
info->cmdline_len = append_string( &ptr, cmdline );
|
||||
if (startup->lpTitle) info->title_len = append_string( &ptr, startup->lpTitle );
|
||||
if (startup->lpDesktop) info->desktop_len = append_string( &ptr, startup->lpDesktop );
|
||||
if (startup->lpReserved2 && startup->cbReserved2)
|
||||
{
|
||||
info->runtime_len = startup->cbReserved2;
|
||||
memcpy( ptr, startup->lpReserved2, startup->cbReserved2 );
|
||||
}
|
||||
|
||||
done:
|
||||
RtlFreeUnicodeString( &newdir );
|
||||
return info;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1525,11 +1567,12 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
|
|||
void *res_start, void *res_end, DWORD binary_type, int exec_only )
|
||||
{
|
||||
BOOL ret, success = FALSE;
|
||||
HANDLE process_info, hstdin, hstdout;
|
||||
HANDLE process_info;
|
||||
WCHAR *env_end;
|
||||
char *winedebug = NULL;
|
||||
char **argv;
|
||||
RTL_USER_PROCESS_PARAMETERS *params;
|
||||
startup_info_t *startup_info;
|
||||
DWORD startup_info_size;
|
||||
int socketfd[2], stdin_fd = -1, stdout_fd = -1;
|
||||
pid_t pid;
|
||||
int err;
|
||||
|
@ -1541,14 +1584,16 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (!env) RtlAcquirePebLock();
|
||||
RtlAcquirePebLock();
|
||||
|
||||
if (!(params = create_user_params( filename, cmd_line, cur_dir, env, flags, startup )))
|
||||
if (!(startup_info = create_startup_info( filename, cmd_line, cur_dir, env, flags, startup,
|
||||
&startup_info_size )))
|
||||
{
|
||||
if (!env) RtlReleasePebLock();
|
||||
RtlReleasePebLock();
|
||||
return FALSE;
|
||||
}
|
||||
env_end = params->Environment;
|
||||
if (!env) env = NtCurrentTeb()->Peb->ProcessParameters->Environment;
|
||||
env_end = env;
|
||||
while (*env_end)
|
||||
{
|
||||
static const WCHAR WINEDEBUG[] = {'W','I','N','E','D','E','B','U','G','=',0};
|
||||
|
@ -1566,9 +1611,9 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
|
|||
|
||||
if (socketpair( PF_UNIX, SOCK_STREAM, 0, socketfd ) == -1)
|
||||
{
|
||||
if (!env) RtlReleasePebLock();
|
||||
RtlReleasePebLock();
|
||||
HeapFree( GetProcessHeap(), 0, winedebug );
|
||||
RtlDestroyProcessParameters( params );
|
||||
HeapFree( GetProcessHeap(), 0, startup_info );
|
||||
SetLastError( ERROR_TOO_MANY_OPEN_FILES );
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1587,29 +1632,10 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
|
|||
req->process_attr = (psa && (psa->nLength >= sizeof(*psa)) && psa->bInheritHandle) ? OBJ_INHERIT : 0;
|
||||
req->thread_access = THREAD_ALL_ACCESS;
|
||||
req->thread_attr = (tsa && (tsa->nLength >= sizeof(*tsa)) && tsa->bInheritHandle) ? OBJ_INHERIT : 0;
|
||||
req->hstdin = wine_server_obj_handle( params->hStdInput );
|
||||
req->hstdout = wine_server_obj_handle( params->hStdOutput );
|
||||
req->hstderr = wine_server_obj_handle( params->hStdError );
|
||||
req->info_size = startup_info_size;
|
||||
|
||||
if ((flags & (CREATE_NEW_CONSOLE | DETACHED_PROCESS)) != 0)
|
||||
{
|
||||
/* this is temporary (for console handles). We have no way to control that the handle is invalid in child process otherwise */
|
||||
if (is_console_handle(params->hStdInput)) req->hstdin = wine_server_obj_handle( INVALID_HANDLE_VALUE );
|
||||
if (is_console_handle(params->hStdOutput)) req->hstdout = wine_server_obj_handle( INVALID_HANDLE_VALUE );
|
||||
if (is_console_handle(params->hStdError)) req->hstderr = wine_server_obj_handle( INVALID_HANDLE_VALUE );
|
||||
hstdin = hstdout = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_console_handle(params->hStdInput)) req->hstdin = console_handle_unmap(params->hStdInput);
|
||||
if (is_console_handle(params->hStdOutput)) req->hstdout = console_handle_unmap(params->hStdOutput);
|
||||
if (is_console_handle(params->hStdError)) req->hstderr = console_handle_unmap(params->hStdError);
|
||||
hstdin = wine_server_ptr_handle( req->hstdin );
|
||||
hstdout = wine_server_ptr_handle( req->hstdout );
|
||||
}
|
||||
|
||||
wine_server_add_data( req, params, params->Size );
|
||||
wine_server_add_data( req, params->Environment, (env_end-params->Environment)*sizeof(WCHAR) );
|
||||
wine_server_add_data( req, startup_info, startup_info_size );
|
||||
wine_server_add_data( req, env, (env_end - env) * sizeof(WCHAR) );
|
||||
if ((ret = !wine_server_call_err( req )))
|
||||
{
|
||||
info->dwProcessId = (DWORD)reply->pid;
|
||||
|
@ -1621,17 +1647,25 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
|
|||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
if (!env) RtlReleasePebLock();
|
||||
RtlDestroyProcessParameters( params );
|
||||
RtlReleasePebLock();
|
||||
if (!ret)
|
||||
{
|
||||
close( socketfd[0] );
|
||||
HeapFree( GetProcessHeap(), 0, startup_info );
|
||||
HeapFree( GetProcessHeap(), 0, winedebug );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (hstdin) wine_server_handle_to_fd( hstdin, FILE_READ_DATA, &stdin_fd, NULL );
|
||||
if (hstdout) wine_server_handle_to_fd( hstdout, FILE_WRITE_DATA, &stdout_fd, NULL );
|
||||
if (!(flags & (CREATE_NEW_CONSOLE | DETACHED_PROCESS)))
|
||||
{
|
||||
if (startup_info->hstdin)
|
||||
wine_server_handle_to_fd( wine_server_ptr_handle(startup_info->hstdin),
|
||||
FILE_READ_DATA, &stdin_fd, NULL );
|
||||
if (startup_info->hstdout)
|
||||
wine_server_handle_to_fd( wine_server_ptr_handle(startup_info->hstdout),
|
||||
FILE_WRITE_DATA, &stdout_fd, NULL );
|
||||
}
|
||||
HeapFree( GetProcessHeap(), 0, startup_info );
|
||||
|
||||
/* create the child process */
|
||||
argv = build_argv( cmd_line, 1 );
|
||||
|
|
|
@ -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->Length = str->MaximumLength = 0;
|
||||
str->Buffer = NULL;
|
||||
return;
|
||||
}
|
||||
if ((char *)str->Buffer + str->MaximumLength > end_ptr)
|
||||
{
|
||||
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;
|
||||
}
|
||||
str->Buffer = *dst;
|
||||
str->Length = len;
|
||||
str->MaximumLength = len + sizeof(WCHAR);
|
||||
memcpy( str->Buffer, *src, len );
|
||||
str->Buffer[len / sizeof(WCHAR)] = 0;
|
||||
*src += len / sizeof(WCHAR);
|
||||
*dst += len / sizeof(WCHAR) + 1;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* init_user_process_params
|
||||
*
|
||||
* 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;
|
||||
SIZE_T env_size;
|
||||
WCHAR *src, *dst;
|
||||
SIZE_T info_size, env_size, size, alloc_size;
|
||||
NTSTATUS status;
|
||||
startup_info_t *info;
|
||||
RTL_USER_PROCESS_PARAMETERS *params = NULL;
|
||||
|
||||
status = NtAllocateVirtualMemory( NtCurrentProcess(), (void **)¶ms, 0, &info_size,
|
||||
MEM_COMMIT, PAGE_READWRITE );
|
||||
if (status != STATUS_SUCCESS) return status;
|
||||
|
||||
params->AllocationSize = info_size;
|
||||
NtCurrentTeb()->Peb->ProcessParameters = params;
|
||||
if (!(info = RtlAllocateHeap( GetProcessHeap(), 0, data_size )))
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
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 )))
|
||||
{
|
||||
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 );
|
||||
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;
|
||||
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);
|
||||
|
||||
/* make sure the strings are valid */
|
||||
fix_unicode_string( ¶ms->CurrentDirectory.DosPath, (char *)info_size );
|
||||
fix_unicode_string( ¶ms->DllPath, (char *)info_size );
|
||||
fix_unicode_string( ¶ms->ImagePathName, (char *)info_size );
|
||||
fix_unicode_string( ¶ms->CommandLine, (char *)info_size );
|
||||
fix_unicode_string( ¶ms->WindowTitle, (char *)info_size );
|
||||
fix_unicode_string( ¶ms->Desktop, (char *)info_size );
|
||||
fix_unicode_string( ¶ms->ShellInfo, (char *)info_size );
|
||||
fix_unicode_string( ¶ms->RuntimeInfo, (char *)info_size );
|
||||
alloc_size = size;
|
||||
status = NtAllocateVirtualMemory( NtCurrentProcess(), (void **)¶ms, 0, &alloc_size,
|
||||
MEM_COMMIT, PAGE_READWRITE );
|
||||
if (status != STATUS_SUCCESS) goto done;
|
||||
|
||||
NtCurrentTeb()->Peb->ProcessParameters = params;
|
||||
params->AllocationSize = alloc_size;
|
||||
params->Size = size;
|
||||
params->Flags = PROCESS_PARAMS_FLAG_NORMALIZED;
|
||||
params->DebugFlags = info->debug_flags;
|
||||
params->ConsoleHandle = wine_server_ptr_handle( info->console );
|
||||
params->ConsoleFlags = info->console_flags;
|
||||
params->hStdInput = wine_server_ptr_handle( info->hstdin );
|
||||
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( ¶ms->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( ¶ms->DllPath, &src, &dst, info->dllpath_len );
|
||||
get_unicode_string( ¶ms->ImagePathName, &src, &dst, info->imagepath_len );
|
||||
get_unicode_string( ¶ms->CommandLine, &src, &dst, info->cmdline_len );
|
||||
get_unicode_string( ¶ms->WindowTitle, &src, &dst, info->title_len );
|
||||
get_unicode_string( ¶ms->Desktop, &src, &dst, info->desktop_len );
|
||||
get_unicode_string( ¶ms->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 */
|
||||
env_size = info_size - params->Size;
|
||||
if (!env_size) env_size = 1;
|
||||
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 );
|
||||
if (status != STATUS_SUCCESS) return status;
|
||||
memcpy( ptr, (char *)params + params->Size, info_size - params->Size );
|
||||
if (status != STATUS_SUCCESS) goto done;
|
||||
memcpy( ptr, (char *)info + info_size, env_size );
|
||||
params->Environment = ptr;
|
||||
|
||||
RtlNormalizeProcessParams( params );
|
||||
done:
|
||||
RtlFreeHeap( GetProcessHeap(), 0, info );
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
|
@ -211,6 +211,42 @@ typedef __int64 timeout_t;
|
|||
#define TIMEOUT_INFINITE (((timeout_t)0x7fffffff) << 32 | 0xffffffff)
|
||||
|
||||
|
||||
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;
|
||||
|
@ -535,14 +571,12 @@ struct new_process_request
|
|||
unsigned int create_flags;
|
||||
int socket_fd;
|
||||
obj_handle_t exe_file;
|
||||
obj_handle_t hstdin;
|
||||
obj_handle_t hstdout;
|
||||
obj_handle_t hstderr;
|
||||
unsigned int process_access;
|
||||
unsigned int process_attr;
|
||||
unsigned int thread_access;
|
||||
unsigned int thread_attr;
|
||||
/* VARARG(info,startup_info); */
|
||||
data_size_t info_size;
|
||||
/* VARARG(info,startup_info,info_size); */
|
||||
/* VARARG(env,unicode_str); */
|
||||
};
|
||||
struct new_process_reply
|
||||
|
@ -597,10 +631,8 @@ struct get_startup_info_reply
|
|||
{
|
||||
struct reply_header __header;
|
||||
obj_handle_t exe_file;
|
||||
obj_handle_t hstdin;
|
||||
obj_handle_t hstdout;
|
||||
obj_handle_t hstderr;
|
||||
/* VARARG(info,startup_info); */
|
||||
data_size_t info_size;
|
||||
/* VARARG(info,startup_info,info_size); */
|
||||
/* VARARG(env,unicode_str); */
|
||||
};
|
||||
|
||||
|
@ -5315,6 +5347,6 @@ union generic_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 */
|
||||
|
|
|
@ -102,13 +102,11 @@ static const struct fd_ops process_fd_ops =
|
|||
struct startup_info
|
||||
{
|
||||
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 process *process; /* created process */
|
||||
data_size_t data_size; /* size of startup data */
|
||||
void *data; /* data for startup info */
|
||||
data_size_t info_size; /* size of 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 );
|
||||
|
@ -478,7 +476,7 @@ static void startup_info_dump( struct object *obj, int verbose )
|
|||
assert( obj->ops == &startup_info_ops );
|
||||
|
||||
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 )
|
||||
|
@ -891,19 +889,46 @@ DECL_HANDLER(new_process)
|
|||
|
||||
/* build the startup info for a new process */
|
||||
if (!(info = alloc_object( &startup_info_ops ))) return;
|
||||
info->hstdin = req->hstdin;
|
||||
info->hstdout = req->hstdout;
|
||||
info->hstderr = req->hstderr;
|
||||
info->exe_file = NULL;
|
||||
info->process = NULL;
|
||||
info->data_size = get_req_data_size();
|
||||
info->data = NULL;
|
||||
info->exe_file = NULL;
|
||||
info->process = NULL;
|
||||
info->data = NULL;
|
||||
|
||||
if (req->exe_file &&
|
||||
!(info->exe_file = get_file_obj( current->process, req->exe_file, FILE_READ_DATA )))
|
||||
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;
|
||||
process = thread->process;
|
||||
|
@ -923,17 +948,17 @@ DECL_HANDLER(new_process)
|
|||
* like if hConOut and hConIn are console handles, then they should be on the same
|
||||
* 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))
|
||||
{
|
||||
info->hstdin = duplicate_handle( parent, req->hstdin, process,
|
||||
0, OBJ_INHERIT, DUPLICATE_SAME_ACCESS );
|
||||
info->hstdout = duplicate_handle( parent, req->hstdout, process,
|
||||
0, OBJ_INHERIT, DUPLICATE_SAME_ACCESS );
|
||||
info->hstderr = duplicate_handle( parent, req->hstderr, process,
|
||||
0, OBJ_INHERIT, DUPLICATE_SAME_ACCESS );
|
||||
info->data->hstdin = duplicate_handle( parent, info->data->hstdin, process,
|
||||
0, OBJ_INHERIT, DUPLICATE_SAME_ACCESS );
|
||||
info->data->hstdout = duplicate_handle( parent, info->data->hstdout, process,
|
||||
0, OBJ_INHERIT, DUPLICATE_SAME_ACCESS );
|
||||
info->data->hstderr = duplicate_handle( parent, info->data->hstderr, process,
|
||||
0, OBJ_INHERIT, DUPLICATE_SAME_ACCESS );
|
||||
/* some handles above may have been invalid; this is not an error */
|
||||
if (get_error() == STATUS_INVALID_HANDLE ||
|
||||
get_error() == STATUS_OBJECT_TYPE_MISMATCH) clear_error();
|
||||
|
@ -985,11 +1010,8 @@ DECL_HANDLER(get_startup_info)
|
|||
if (info->exe_file &&
|
||||
!(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 */
|
||||
reply->info_size = info->info_size;
|
||||
size = info->data_size;
|
||||
if (size > get_reply_max_size()) size = get_reply_max_size();
|
||||
set_reply_data_ptr( info->data, size );
|
||||
|
|
|
@ -226,6 +226,42 @@ struct wake_up_reply
|
|||
typedef __int64 timeout_t;
|
||||
#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 */
|
||||
typedef struct
|
||||
{
|
||||
|
@ -549,14 +585,12 @@ typedef union
|
|||
unsigned int create_flags; /* creation flags */
|
||||
int socket_fd; /* file descriptor for process socket */
|
||||
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_attr; /* attributes for process object */
|
||||
unsigned int thread_access; /* access rights 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 */
|
||||
@REPLY
|
||||
obj_handle_t info; /* new process info handle */
|
||||
|
@ -592,10 +626,8 @@ typedef union
|
|||
@REQ(get_startup_info)
|
||||
@REPLY
|
||||
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 */
|
||||
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 */
|
||||
@END
|
||||
|
||||
|
|
|
@ -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, socket_fd) == 20 );
|
||||
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, hstdout) == 32 );
|
||||
C_ASSERT( FIELD_OFFSET(struct new_process_request, hstderr) == 36 );
|
||||
C_ASSERT( FIELD_OFFSET(struct new_process_request, process_access) == 40 );
|
||||
C_ASSERT( FIELD_OFFSET(struct new_process_request, process_attr) == 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_request, process_access) == 28 );
|
||||
C_ASSERT( FIELD_OFFSET(struct new_process_request, process_attr) == 32 );
|
||||
C_ASSERT( FIELD_OFFSET(struct new_process_request, thread_access) == 36 );
|
||||
C_ASSERT( FIELD_OFFSET(struct new_process_request, thread_attr) == 40 );
|
||||
C_ASSERT( FIELD_OFFSET(struct new_process_request, info_size) == 44 );
|
||||
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, phandle) == 16 );
|
||||
|
@ -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( 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, hstdin) == 12 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_startup_info_reply, hstdout) == 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 get_startup_info_reply, info_size) == 12 );
|
||||
C_ASSERT( sizeof(struct get_startup_info_reply) == 16 );
|
||||
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, ldt_copy) == 24 );
|
||||
|
|
|
@ -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 */
|
||||
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;
|
||||
size_t offset = (size_t)str->Buffer;
|
||||
|
||||
if (offset >= size) return;
|
||||
if (offset + length > size) length = size - offset;
|
||||
dump_strW( (const WCHAR *)data + offset/sizeof(WCHAR), length/sizeof(WCHAR), stderr, "\"\"" );
|
||||
fputs( prefix, stderr );
|
||||
if (pos >= total_size) return pos;
|
||||
if (len > total_size - pos) len = total_size - pos;
|
||||
len /= sizeof(WCHAR);
|
||||
dump_strW( (const WCHAR *)cur_data + pos/sizeof(WCHAR), len, stderr, "\"\"" );
|
||||
return pos + len * sizeof(WCHAR);
|
||||
}
|
||||
|
||||
static void dump_varargs_startup_info( const char *prefix, data_size_t size )
|
||||
{
|
||||
const RTL_USER_PROCESS_PARAMETERS *ptr = cur_data;
|
||||
RTL_USER_PROCESS_PARAMETERS params;
|
||||
startup_info_t info;
|
||||
data_size_t pos = sizeof(info);
|
||||
|
||||
if (size < sizeof(params.Size))
|
||||
{
|
||||
fprintf( stderr, "%s{}", prefix );
|
||||
return;
|
||||
}
|
||||
if (size > ptr->Size) size = ptr->Size;
|
||||
memset( ¶ms, 0, sizeof(params) );
|
||||
memcpy( ¶ms, ptr, min( size, sizeof(params) ));
|
||||
memset( &info, 0, sizeof(info) );
|
||||
memcpy( &info, cur_data, min( size, sizeof(info) ));
|
||||
|
||||
fprintf( stderr, "%s{AllocationSize=%x,", prefix, params.AllocationSize );
|
||||
fprintf( stderr, "Size=%x,", params.Size );
|
||||
fprintf( stderr, "Flags=%x,", params.Flags );
|
||||
fprintf( stderr, "DebugFlags=%x,", params.DebugFlags );
|
||||
fprintf( stderr, "ConsoleHandle=%p,", params.ConsoleHandle );
|
||||
fprintf( stderr, "ConsoleFlags=%x,", params.ConsoleFlags );
|
||||
fprintf( stderr, "hStdInput=%p,", params.hStdInput );
|
||||
fprintf( stderr, "hStdOutput=%p,", params.hStdOutput );
|
||||
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( ¶ms.CurrentDirectory.DosPath, cur_data, size );
|
||||
fprintf( stderr, "\",DllPath=L\"" );
|
||||
dump_inline_unicode_string( ¶ms.DllPath, cur_data, size );
|
||||
fprintf( stderr, "\",ImagePathName=L\"" );
|
||||
dump_inline_unicode_string( ¶ms.ImagePathName, cur_data, size );
|
||||
fprintf( stderr, "\",CommandLine=L\"" );
|
||||
dump_inline_unicode_string( ¶ms.CommandLine, cur_data, size );
|
||||
fprintf( stderr, "\",WindowTitle=L\"" );
|
||||
dump_inline_unicode_string( ¶ms.WindowTitle, cur_data, size );
|
||||
fprintf( stderr, "\",Desktop=L\"" );
|
||||
dump_inline_unicode_string( ¶ms.Desktop, cur_data, size );
|
||||
fprintf( stderr, "\",ShellInfo=L\"" );
|
||||
dump_inline_unicode_string( ¶ms.ShellInfo, cur_data, size );
|
||||
fprintf( stderr, "\",RuntimeInfo=L\"" );
|
||||
dump_inline_unicode_string( ¶ms.RuntimeInfo, cur_data, size );
|
||||
fprintf( stderr,
|
||||
"%s{debug_flags=%x,console_flags=%x,console=%04x,hstdin=%04x,hstdout=%04x,hstderr=%04x,"
|
||||
"x=%u,y=%u,xsize=%u,ysize=%u,xchars=%u,ychars=%u,attribute=%02x,flags=%x,show=%u",
|
||||
prefix, info.debug_flags, info.console_flags, info.console,
|
||||
info.hstdin, info.hstdout, info.hstderr, info.x, info.y, info.xsize, info.ysize,
|
||||
info.xchars, info.ychars, info.attribute, info.flags, info.show );
|
||||
pos = dump_inline_unicode_string( ",curdir=L\"", pos, info.curdir_len, size );
|
||||
pos = dump_inline_unicode_string( "\",dllpath=L\"", pos, info.dllpath_len, size );
|
||||
pos = dump_inline_unicode_string( "\",imagepath=L\"", pos, info.imagepath_len, size );
|
||||
pos = dump_inline_unicode_string( "\",cmdline=L\"", pos, info.cmdline_len, size );
|
||||
pos = dump_inline_unicode_string( "\",title=L\"", pos, info.title_len, size );
|
||||
pos = dump_inline_unicode_string( "\",desktop=L\"", pos, info.desktop_len, size );
|
||||
pos = dump_inline_unicode_string( "\",shellinfo=L\"", pos, info.shellinfo_len, size );
|
||||
pos = dump_inline_unicode_string( "\",runtime=L\"", pos, info.runtime_len, size );
|
||||
fprintf( stderr, "\"}" );
|
||||
remove_data( size );
|
||||
}
|
||||
|
@ -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, ", socket_fd=%d", req->socket_fd );
|
||||
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_attr=%08x", req->process_attr );
|
||||
fprintf( stderr, ", thread_access=%08x", req->thread_access );
|
||||
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 );
|
||||
}
|
||||
|
||||
|
@ -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 )
|
||||
{
|
||||
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 );
|
||||
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 );
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue