kernel32: Build a standard process parameters structure in CreateProcess().
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
0964b3cd13
commit
79e2afaaae
|
@ -1795,135 +1795,155 @@ static int fork_and_exec( const char *filename, const WCHAR *cmdline, const WCHA
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline DWORD append_string( void **ptr, const WCHAR *str )
|
static inline const WCHAR *get_params_string( const RTL_USER_PROCESS_PARAMETERS *params,
|
||||||
|
const UNICODE_STRING *str )
|
||||||
{
|
{
|
||||||
DWORD len = strlenW( str );
|
if (params->Flags & PROCESS_PARAMS_FLAG_NORMALIZED) return str->Buffer;
|
||||||
memcpy( *ptr, str, len * sizeof(WCHAR) );
|
return (const WCHAR *)((const char *)params + (UINT_PTR)str->Buffer);
|
||||||
*ptr = (WCHAR *)*ptr + len;
|
}
|
||||||
return len * sizeof(WCHAR);
|
|
||||||
|
static inline DWORD append_string( void **ptr, const RTL_USER_PROCESS_PARAMETERS *params,
|
||||||
|
const UNICODE_STRING *str )
|
||||||
|
{
|
||||||
|
const WCHAR *buffer = get_params_string( params, str );
|
||||||
|
memcpy( *ptr, buffer, str->Length );
|
||||||
|
*ptr = (WCHAR *)*ptr + str->Length / sizeof(WCHAR);
|
||||||
|
return str->Length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* create_startup_info
|
* create_startup_info
|
||||||
*/
|
*/
|
||||||
static startup_info_t *create_startup_info( LPCWSTR filename, LPCWSTR cmdline,
|
static startup_info_t *create_startup_info( const RTL_USER_PROCESS_PARAMETERS *params, DWORD *info_size )
|
||||||
LPCWSTR cur_dir, LPWSTR env, DWORD flags,
|
|
||||||
const STARTUPINFOW *startup, DWORD *info_size )
|
|
||||||
{
|
{
|
||||||
const RTL_USER_PROCESS_PARAMETERS *cur_params;
|
|
||||||
const WCHAR *title;
|
|
||||||
startup_info_t *info;
|
startup_info_t *info;
|
||||||
DWORD size;
|
DWORD size;
|
||||||
void *ptr;
|
void *ptr;
|
||||||
UNICODE_STRING newdir;
|
|
||||||
|
size = sizeof(*info);
|
||||||
|
size += params->CurrentDirectory.DosPath.Length;
|
||||||
|
size += params->DllPath.Length;
|
||||||
|
size += params->ImagePathName.Length;
|
||||||
|
size += params->CommandLine.Length;
|
||||||
|
size += params->WindowTitle.Length;
|
||||||
|
size += params->Desktop.Length;
|
||||||
|
size += params->ShellInfo.Length;
|
||||||
|
size += params->RuntimeInfo.Length;
|
||||||
|
size = (size + 1) & ~1;
|
||||||
|
*info_size = size;
|
||||||
|
|
||||||
|
if (!(info = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, size ))) return NULL;
|
||||||
|
|
||||||
|
info->console_flags = params->ConsoleFlags;
|
||||||
|
info->console = wine_server_obj_handle( params->ConsoleHandle );
|
||||||
|
info->hstdin = wine_server_obj_handle( params->hStdInput );
|
||||||
|
info->hstdout = wine_server_obj_handle( params->hStdOutput );
|
||||||
|
info->hstderr = wine_server_obj_handle( params->hStdError );
|
||||||
|
info->x = params->dwX;
|
||||||
|
info->y = params->dwY;
|
||||||
|
info->xsize = params->dwXSize;
|
||||||
|
info->ysize = params->dwYSize;
|
||||||
|
info->xchars = params->dwXCountChars;
|
||||||
|
info->ychars = params->dwYCountChars;
|
||||||
|
info->attribute = params->dwFillAttribute;
|
||||||
|
info->flags = params->dwFlags;
|
||||||
|
info->show = params->wShowWindow;
|
||||||
|
|
||||||
|
ptr = info + 1;
|
||||||
|
info->curdir_len = append_string( &ptr, params, ¶ms->CurrentDirectory.DosPath );
|
||||||
|
info->dllpath_len = append_string( &ptr, params, ¶ms->DllPath );
|
||||||
|
info->imagepath_len = append_string( &ptr, params, ¶ms->ImagePathName );
|
||||||
|
info->cmdline_len = append_string( &ptr, params, ¶ms->CommandLine );
|
||||||
|
info->title_len = append_string( &ptr, params, ¶ms->WindowTitle );
|
||||||
|
info->desktop_len = append_string( &ptr, params, ¶ms->Desktop );
|
||||||
|
info->shellinfo_len = append_string( &ptr, params, ¶ms->ShellInfo );
|
||||||
|
info->runtime_len = append_string( &ptr, params, ¶ms->RuntimeInfo );
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* create_process_params
|
||||||
|
*/
|
||||||
|
static RTL_USER_PROCESS_PARAMETERS *create_process_params( LPCWSTR filename, LPCWSTR cmdline,
|
||||||
|
LPCWSTR cur_dir, LPWSTR env, DWORD flags,
|
||||||
|
const STARTUPINFOW *startup )
|
||||||
|
{
|
||||||
|
RTL_USER_PROCESS_PARAMETERS *params;
|
||||||
|
UNICODE_STRING imageW, curdirW, cmdlineW, titleW, desktopW, runtimeW, newdirW;
|
||||||
WCHAR imagepath[MAX_PATH];
|
WCHAR imagepath[MAX_PATH];
|
||||||
HANDLE hstdin, hstdout, hstderr;
|
|
||||||
|
|
||||||
if(!GetLongPathNameW( filename, imagepath, MAX_PATH ))
|
if(!GetLongPathNameW( filename, imagepath, MAX_PATH ))
|
||||||
lstrcpynW( imagepath, filename, MAX_PATH );
|
lstrcpynW( imagepath, filename, MAX_PATH );
|
||||||
if(!GetFullPathNameW( imagepath, MAX_PATH, imagepath, NULL ))
|
if(!GetFullPathNameW( imagepath, MAX_PATH, imagepath, NULL ))
|
||||||
lstrcpynW( imagepath, filename, MAX_PATH );
|
lstrcpynW( imagepath, filename, MAX_PATH );
|
||||||
|
|
||||||
cur_params = NtCurrentTeb()->Peb->ProcessParameters;
|
newdirW.Buffer = NULL;
|
||||||
|
|
||||||
newdir.Buffer = NULL;
|
|
||||||
if (cur_dir)
|
if (cur_dir)
|
||||||
{
|
{
|
||||||
if (RtlDosPathNameToNtPathName_U( cur_dir, &newdir, NULL, NULL ))
|
if (RtlDosPathNameToNtPathName_U( cur_dir, &newdirW, NULL, NULL ))
|
||||||
cur_dir = newdir.Buffer + 4; /* skip \??\ prefix */
|
cur_dir = newdirW.Buffer + 4; /* skip \??\ prefix */
|
||||||
else
|
else
|
||||||
cur_dir = NULL;
|
cur_dir = NULL;
|
||||||
}
|
}
|
||||||
if (!cur_dir)
|
RtlInitUnicodeString( &imageW, imagepath );
|
||||||
{
|
RtlInitUnicodeString( &curdirW, cur_dir );
|
||||||
if (NtCurrentTeb()->Tib.SubSystemTib) /* FIXME: hack */
|
RtlInitUnicodeString( &cmdlineW, cmdline );
|
||||||
cur_dir = ((WIN16_SUBSYSTEM_TIB *)NtCurrentTeb()->Tib.SubSystemTib)->curdir.DosPath.Buffer;
|
RtlInitUnicodeString( &titleW, startup->lpTitle ? startup->lpTitle : imagepath );
|
||||||
else
|
RtlInitUnicodeString( &desktopW, startup->lpDesktop );
|
||||||
cur_dir = cur_params->CurrentDirectory.DosPath.Buffer;
|
runtimeW.Buffer = (WCHAR *)startup->lpReserved2;
|
||||||
}
|
runtimeW.Length = runtimeW.MaximumLength = startup->cbReserved2;
|
||||||
title = startup->lpTitle ? startup->lpTitle : imagepath;
|
if (RtlCreateProcessParametersEx( ¶ms, &imageW, NULL, &curdirW, &cmdlineW, env, &titleW,
|
||||||
|
&desktopW, NULL, &runtimeW, PROCESS_PARAMS_FLAG_NORMALIZED ))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
size = sizeof(*info);
|
if (flags & CREATE_NEW_PROCESS_GROUP) params->ConsoleFlags = 1;
|
||||||
size += strlenW( cur_dir ) * sizeof(WCHAR);
|
if (flags & CREATE_NEW_CONSOLE) params->ConsoleHandle = KERNEL32_CONSOLE_ALLOC;
|
||||||
size += cur_params->DllPath.Length;
|
|
||||||
size += strlenW( imagepath ) * sizeof(WCHAR);
|
|
||||||
size += strlenW( cmdline ) * sizeof(WCHAR);
|
|
||||||
size += strlenW( title ) * 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 (!(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 = wine_server_obj_handle(KERNEL32_CONSOLE_ALLOC);
|
|
||||||
|
|
||||||
if (startup->dwFlags & STARTF_USESTDHANDLES)
|
if (startup->dwFlags & STARTF_USESTDHANDLES)
|
||||||
{
|
{
|
||||||
hstdin = startup->hStdInput;
|
params->hStdInput = startup->hStdInput;
|
||||||
hstdout = startup->hStdOutput;
|
params->hStdOutput = startup->hStdOutput;
|
||||||
hstderr = startup->hStdError;
|
params->hStdError = startup->hStdError;
|
||||||
}
|
}
|
||||||
else if (flags & DETACHED_PROCESS)
|
else if (flags & DETACHED_PROCESS)
|
||||||
{
|
{
|
||||||
hstdin = INVALID_HANDLE_VALUE;
|
params->hStdInput = INVALID_HANDLE_VALUE;
|
||||||
hstdout = INVALID_HANDLE_VALUE;
|
params->hStdOutput = INVALID_HANDLE_VALUE;
|
||||||
hstderr = INVALID_HANDLE_VALUE;
|
params->hStdError = INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hstdin = GetStdHandle( STD_INPUT_HANDLE );
|
params->hStdInput = NtCurrentTeb()->Peb->ProcessParameters->hStdInput;
|
||||||
hstdout = GetStdHandle( STD_OUTPUT_HANDLE );
|
params->hStdOutput = NtCurrentTeb()->Peb->ProcessParameters->hStdOutput;
|
||||||
hstderr = GetStdHandle( STD_ERROR_HANDLE );
|
params->hStdError = NtCurrentTeb()->Peb->ProcessParameters->hStdError;
|
||||||
}
|
}
|
||||||
info->hstdin = wine_server_obj_handle( hstdin );
|
|
||||||
info->hstdout = wine_server_obj_handle( hstdout );
|
if (flags & CREATE_NEW_CONSOLE)
|
||||||
info->hstderr = wine_server_obj_handle( hstderr );
|
|
||||||
if ((flags & CREATE_NEW_CONSOLE) != 0)
|
|
||||||
{
|
{
|
||||||
/* this is temporary (for console handles). We have no way to control that the handle is invalid in child process otherwise */
|
/* 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(params->hStdInput)) params->hStdInput = INVALID_HANDLE_VALUE;
|
||||||
if (is_console_handle(hstdout)) info->hstdout = wine_server_obj_handle( INVALID_HANDLE_VALUE );
|
if (is_console_handle(params->hStdOutput)) params->hStdOutput = INVALID_HANDLE_VALUE;
|
||||||
if (is_console_handle(hstderr)) info->hstderr = wine_server_obj_handle( INVALID_HANDLE_VALUE );
|
if (is_console_handle(params->hStdError)) params->hStdError = INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (is_console_handle(hstdin)) info->hstdin = console_handle_unmap(hstdin);
|
if (is_console_handle(params->hStdInput)) params->hStdInput = (HANDLE)((UINT_PTR)params->hStdInput & ~3);
|
||||||
if (is_console_handle(hstdout)) info->hstdout = console_handle_unmap(hstdout);
|
if (is_console_handle(params->hStdOutput)) params->hStdOutput = (HANDLE)((UINT_PTR)params->hStdOutput & ~3);
|
||||||
if (is_console_handle(hstderr)) info->hstderr = console_handle_unmap(hstderr);
|
if (is_console_handle(params->hStdError)) params->hStdError = (HANDLE)((UINT_PTR)params->hStdError & ~3);
|
||||||
}
|
}
|
||||||
|
|
||||||
info->x = startup->dwX;
|
params->dwX = startup->dwX;
|
||||||
info->y = startup->dwY;
|
params->dwY = startup->dwY;
|
||||||
info->xsize = startup->dwXSize;
|
params->dwXSize = startup->dwXSize;
|
||||||
info->ysize = startup->dwYSize;
|
params->dwYSize = startup->dwYSize;
|
||||||
info->xchars = startup->dwXCountChars;
|
params->dwXCountChars = startup->dwXCountChars;
|
||||||
info->ychars = startup->dwYCountChars;
|
params->dwYCountChars = startup->dwYCountChars;
|
||||||
info->attribute = startup->dwFillAttribute;
|
params->dwFillAttribute = startup->dwFillAttribute;
|
||||||
info->flags = startup->dwFlags;
|
params->dwFlags = startup->dwFlags;
|
||||||
info->show = startup->wShowWindow;
|
params->wShowWindow = startup->wShowWindow;
|
||||||
|
|
||||||
ptr = info + 1;
|
return params;
|
||||||
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 );
|
|
||||||
info->title_len = append_string( &ptr, title );
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -2186,6 +2206,7 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
BOOL success = FALSE;
|
BOOL success = FALSE;
|
||||||
HANDLE process_info, process_handle = 0;
|
HANDLE process_info, process_handle = 0;
|
||||||
|
RTL_USER_PROCESS_PARAMETERS *params;
|
||||||
struct object_attributes *objattr;
|
struct object_attributes *objattr;
|
||||||
data_size_t attr_len;
|
data_size_t attr_len;
|
||||||
WCHAR *env_end;
|
WCHAR *env_end;
|
||||||
|
@ -2245,16 +2266,16 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
|
||||||
|
|
||||||
RtlAcquirePebLock();
|
RtlAcquirePebLock();
|
||||||
|
|
||||||
if (!(startup_info = create_startup_info( filename, cmd_line, cur_dir, env, flags, startup,
|
if (!(params = create_process_params( filename, cmd_line, cur_dir, env, flags, startup )) ||
|
||||||
&startup_info_size )))
|
!(startup_info = create_startup_info( params, &startup_info_size )))
|
||||||
{
|
{
|
||||||
|
RtlDestroyProcessParameters( params );
|
||||||
RtlReleasePebLock();
|
RtlReleasePebLock();
|
||||||
close( socketfd[0] );
|
close( socketfd[0] );
|
||||||
close( socketfd[1] );
|
close( socketfd[1] );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (!env) env = NtCurrentTeb()->Peb->ProcessParameters->Environment;
|
env_end = params->Environment;
|
||||||
env_end = env;
|
|
||||||
while (*env_end)
|
while (*env_end)
|
||||||
{
|
{
|
||||||
static const WCHAR WINEDEBUG[] = {'W','I','N','E','D','E','B','U','G','=',0};
|
static const WCHAR WINEDEBUG[] = {'W','I','N','E','D','E','B','U','G','=',0};
|
||||||
|
@ -2285,7 +2306,7 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
|
||||||
req->info_size = startup_info_size;
|
req->info_size = startup_info_size;
|
||||||
wine_server_add_data( req, objattr, attr_len );
|
wine_server_add_data( req, objattr, attr_len );
|
||||||
wine_server_add_data( req, startup_info, startup_info_size );
|
wine_server_add_data( req, startup_info, startup_info_size );
|
||||||
wine_server_add_data( req, env, (env_end - env) * sizeof(WCHAR) );
|
wine_server_add_data( req, params->Environment, (env_end - params->Environment) * sizeof(WCHAR) );
|
||||||
if (!(status = wine_server_call( req )))
|
if (!(status = wine_server_call( req )))
|
||||||
{
|
{
|
||||||
info->dwProcessId = (DWORD)reply->pid;
|
info->dwProcessId = (DWORD)reply->pid;
|
||||||
|
@ -2317,6 +2338,7 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
|
||||||
HeapFree( GetProcessHeap(), 0, objattr );
|
HeapFree( GetProcessHeap(), 0, objattr );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RtlDestroyProcessParameters( params );
|
||||||
RtlReleasePebLock();
|
RtlReleasePebLock();
|
||||||
if (status)
|
if (status)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue