mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-05 18:01:34 +00:00
ntdll: Reimplement init_user_process_params() using RtlCreateProcessParametersEx().
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
6abf99b480
commit
7a122604ea
3 changed files with 98 additions and 122 deletions
104
dlls/ntdll/env.c
104
dlls/ntdll/env.c
|
@ -460,7 +460,7 @@ NTSTATUS WINAPI RtlCreateProcessParametersEx( RTL_USER_PROCESS_PARAMETERS **resu
|
|||
|
||||
UNICODE_STRING curdir;
|
||||
const RTL_USER_PROCESS_PARAMETERS *cur_params;
|
||||
SIZE_T size, env_size;
|
||||
SIZE_T size, env_size = 0;
|
||||
void *ptr;
|
||||
const WCHAR *env;
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
|
@ -485,10 +485,13 @@ NTSTATUS WINAPI RtlCreateProcessParametersEx( RTL_USER_PROCESS_PARAMETERS **resu
|
|||
if (!ShellInfo) ShellInfo = &empty_str;
|
||||
if (!RuntimeInfo) RuntimeInfo = &null_str;
|
||||
|
||||
env = Environment;
|
||||
while (*env) env += strlenW(env) + 1;
|
||||
env++;
|
||||
env_size = ROUND_SIZE( (env - Environment) * sizeof(WCHAR) );
|
||||
if (Environment)
|
||||
{
|
||||
env = Environment;
|
||||
while (*env) env += strlenW(env) + 1;
|
||||
env++;
|
||||
env_size = ROUND_SIZE( (env - Environment) * sizeof(WCHAR) );
|
||||
}
|
||||
|
||||
size = (sizeof(RTL_USER_PROCESS_PARAMETERS)
|
||||
+ ROUND_SIZE( ImagePathName->MaximumLength )
|
||||
|
@ -518,8 +521,8 @@ NTSTATUS WINAPI RtlCreateProcessParametersEx( RTL_USER_PROCESS_PARAMETERS **resu
|
|||
append_unicode_string( &ptr, Desktop, ¶ms->Desktop );
|
||||
append_unicode_string( &ptr, ShellInfo, ¶ms->ShellInfo );
|
||||
append_unicode_string( &ptr, RuntimeInfo, ¶ms->RuntimeInfo );
|
||||
params->Environment = ptr;
|
||||
memcpy( ptr, Environment, (env - Environment) * sizeof(WCHAR) );
|
||||
if (Environment)
|
||||
params->Environment = memcpy( ptr, Environment, (env - Environment) * sizeof(WCHAR) );
|
||||
*result = params;
|
||||
if (!(flags & PROCESS_PARAMS_FLAG_NORMALIZED)) RtlDeNormalizeProcessParams( params );
|
||||
}
|
||||
|
@ -556,3 +559,90 @@ void WINAPI RtlDestroyProcessParameters( RTL_USER_PROCESS_PARAMETERS *params )
|
|||
{
|
||||
RtlFreeHeap( GetProcessHeap(), 0, params );
|
||||
}
|
||||
|
||||
|
||||
static inline void get_unicode_string( UNICODE_STRING *str, WCHAR **src, UINT len )
|
||||
{
|
||||
str->Buffer = *src;
|
||||
str->Length = len;
|
||||
str->MaximumLength = len + sizeof(WCHAR);
|
||||
*src += len / sizeof(WCHAR);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* init_user_process_params
|
||||
*
|
||||
* Fill the initial RTL_USER_PROCESS_PARAMETERS structure from the server.
|
||||
*/
|
||||
void init_user_process_params( SIZE_T data_size )
|
||||
{
|
||||
void *ptr;
|
||||
WCHAR *src;
|
||||
SIZE_T info_size, env_size, alloc_size;
|
||||
NTSTATUS status;
|
||||
startup_info_t *info;
|
||||
RTL_USER_PROCESS_PARAMETERS *params = NULL;
|
||||
UNICODE_STRING curdir, dllpath, imagepath, cmdline, title, desktop, shellinfo, runtime;
|
||||
|
||||
if (!(info = RtlAllocateHeap( GetProcessHeap(), 0, data_size ))) return;
|
||||
|
||||
SERVER_START_REQ( get_startup_info )
|
||||
{
|
||||
wine_server_set_reply( req, info, data_size );
|
||||
if (!(status = wine_server_call( req )))
|
||||
{
|
||||
data_size = wine_server_reply_size( reply );
|
||||
info_size = reply->info_size;
|
||||
env_size = data_size - info_size;
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
if (status) goto done;
|
||||
|
||||
src = (WCHAR *)(info + 1);
|
||||
get_unicode_string( &curdir, &src, info->curdir_len );
|
||||
get_unicode_string( &dllpath, &src, info->dllpath_len );
|
||||
get_unicode_string( &imagepath, &src, info->imagepath_len );
|
||||
get_unicode_string( &cmdline, &src, info->cmdline_len );
|
||||
get_unicode_string( &title, &src, info->title_len );
|
||||
get_unicode_string( &desktop, &src, info->desktop_len );
|
||||
get_unicode_string( &shellinfo, &src, info->shellinfo_len );
|
||||
get_unicode_string( &runtime, &src, info->runtime_len );
|
||||
|
||||
curdir.MaximumLength = MAX_PATH * sizeof(WCHAR); /* current directory needs more space */
|
||||
runtime.MaximumLength = runtime.Length; /* runtime info isn't a real string */
|
||||
|
||||
if (RtlCreateProcessParametersEx( ¶ms, &imagepath, &dllpath, &curdir, &cmdline, NULL,
|
||||
&title, &desktop, &shellinfo, &runtime,
|
||||
PROCESS_PARAMS_FLAG_NORMALIZED ))
|
||||
goto done;
|
||||
|
||||
NtCurrentTeb()->Peb->ProcessParameters = params;
|
||||
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;
|
||||
|
||||
/* environment needs to be a separate memory block */
|
||||
ptr = NULL;
|
||||
alloc_size = max( 1, env_size );
|
||||
status = NtAllocateVirtualMemory( NtCurrentProcess(), &ptr, 0, &alloc_size,
|
||||
MEM_COMMIT, PAGE_READWRITE );
|
||||
if (status != STATUS_SUCCESS) goto done;
|
||||
memcpy( ptr, (char *)info + info_size, env_size );
|
||||
params->Environment = ptr;
|
||||
|
||||
done:
|
||||
RtlFreeHeap( GetProcessHeap(), 0, info );
|
||||
}
|
||||
|
|
|
@ -80,6 +80,7 @@ extern void virtual_init(void) DECLSPEC_HIDDEN;
|
|||
extern void virtual_init_threading(void) DECLSPEC_HIDDEN;
|
||||
extern void fill_cpu_info(void) DECLSPEC_HIDDEN;
|
||||
extern void heap_set_debug_flags( HANDLE handle ) DECLSPEC_HIDDEN;
|
||||
extern void init_user_process_params( SIZE_T data_size ) DECLSPEC_HIDDEN;
|
||||
|
||||
/* server support */
|
||||
extern timeout_t server_start_time DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -83,121 +83,6 @@ static RTL_CRITICAL_SECTION_DEBUG critsect_debug =
|
|||
};
|
||||
static RTL_CRITICAL_SECTION peb_lock = { &critsect_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
/***********************************************************************
|
||||
* get_unicode_string
|
||||
*
|
||||
* Copy a unicode string from the startup info.
|
||||
*/
|
||||
static inline void get_unicode_string( UNICODE_STRING *str, WCHAR **src, WCHAR **dst, UINT len )
|
||||
{
|
||||
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 data_size )
|
||||
{
|
||||
void *ptr;
|
||||
WCHAR *src, *dst;
|
||||
SIZE_T info_size, env_size, size, alloc_size;
|
||||
NTSTATUS status;
|
||||
startup_info_t *info;
|
||||
RTL_USER_PROCESS_PARAMETERS *params = NULL;
|
||||
|
||||
if (!(info = RtlAllocateHeap( GetProcessHeap(), 0, data_size )))
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
SERVER_START_REQ( get_startup_info )
|
||||
{
|
||||
wine_server_set_reply( req, info, data_size );
|
||||
if (!(status = wine_server_call( req )))
|
||||
{
|
||||
data_size = wine_server_reply_size( reply );
|
||||
info_size = reply->info_size;
|
||||
env_size = data_size - info_size;
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
if (status != STATUS_SUCCESS) goto done;
|
||||
|
||||
size = sizeof(*params);
|
||||
size += sizeof(current_dir);
|
||||
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 **)¶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 = sizeof(current_dir);
|
||||
dst = (WCHAR *)(params + 1) + ARRAY_SIZE(current_dir);
|
||||
|
||||
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 */
|
||||
ptr = NULL;
|
||||
alloc_size = max( 1, env_size );
|
||||
status = NtAllocateVirtualMemory( NtCurrentProcess(), &ptr, 0, &alloc_size,
|
||||
MEM_COMMIT, PAGE_READWRITE );
|
||||
if (status != STATUS_SUCCESS) goto done;
|
||||
memcpy( ptr, (char *)info + info_size, env_size );
|
||||
params->Environment = ptr;
|
||||
|
||||
done:
|
||||
RtlFreeHeap( GetProcessHeap(), 0, info );
|
||||
return status;
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
#ifdef HAVE_ELF_H
|
||||
|
|
Loading…
Reference in a new issue