Commit 0d3972ce authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Allocate the initial process parameters on the Unix side.

parent 9ce326ee
......@@ -1168,44 +1168,41 @@ wait:
*/
void init_user_process_params(void)
{
WCHAR *src, *load_path, *dummy;
SIZE_T info_size, env_size, data_size = 0;
startup_info_t *info = NULL;
RTL_USER_PROCESS_PARAMETERS *params = NULL;
UNICODE_STRING curdir, dllpath, imagepath, cmdline, title, desktop, shellinfo, runtime;
WCHAR *env, *load_path, *dummy;
SIZE_T env_size;
RTL_USER_PROCESS_PARAMETERS *new_params, *params = NtCurrentTeb()->Peb->ProcessParameters;
UNICODE_STRING curdir, dllpath, cmdline;
WCHAR **wargv;
unix_funcs->get_startup_info( NULL, &data_size, &info_size );
if (!data_size)
if (!params->DllPath.MaximumLength) /* not inherited from parent process */
{
RTL_USER_PROCESS_PARAMETERS initial_params = {0};
WCHAR *env, curdir_buffer[MAX_PATH];
WCHAR curdir_buffer[MAX_PATH];
NtCurrentTeb()->Peb->ProcessParameters = &initial_params;
initial_params.Environment = build_initial_environment( &wargv );
params->Environment = build_initial_environment( &wargv );
curdir.Buffer = curdir_buffer;
curdir.MaximumLength = sizeof(curdir_buffer);
get_current_directory( &curdir );
initial_params.CurrentDirectory.DosPath = curdir;
get_image_path( wargv[0], &initial_params.ImagePathName );
wargv[0] = initial_params.ImagePathName.Buffer;
params->CurrentDirectory.DosPath = curdir;
get_image_path( wargv[0], &params->ImagePathName );
wargv[0] = params->ImagePathName.Buffer;
build_command_line( wargv, &cmdline );
LdrGetDllPath( initial_params.ImagePathName.Buffer, 0, &load_path, &dummy );
LdrGetDllPath( params->ImagePathName.Buffer, 0, &load_path, &dummy );
RtlInitUnicodeString( &dllpath, load_path );
env = initial_params.Environment;
initial_params.Environment = NULL; /* avoid copying it */
if (RtlCreateProcessParametersEx( &params, &initial_params.ImagePathName, &dllpath, &curdir,
&cmdline, NULL, &initial_params.ImagePathName, NULL, NULL, NULL,
env = params->Environment;
params->Environment = NULL; /* avoid copying it */
if (RtlCreateProcessParametersEx( &new_params, &params->ImagePathName, &dllpath, &curdir,
&cmdline, NULL, &params->ImagePathName, NULL, NULL, NULL,
PROCESS_PARAMS_FLAG_NORMALIZED ))
return;
params->Environment = env;
NtCurrentTeb()->Peb->ProcessParameters = params;
RtlFreeUnicodeString( &initial_params.ImagePathName );
new_params->Environment = env;
NtCurrentTeb()->Peb->ProcessParameters = new_params;
RtlFreeUnicodeString( &params->ImagePathName );
RtlFreeUnicodeString( &cmdline );
RtlReleasePath( load_path );
params = new_params;
unix_funcs->get_initial_console( params );
params->wShowWindow = 1; /* SW_SHOWNORMAL */
......@@ -1213,54 +1210,16 @@ void init_user_process_params(void)
goto done;
}
if (!(info = RtlAllocateHeap( GetProcessHeap(), 0, data_size ))) return;
if (unix_funcs->get_startup_info( info, &data_size, &info_size )) 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 );
runtime.MaximumLength = runtime.Length; /* runtime info isn't a real string */
if (RtlCreateProcessParametersEx( &params, &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 */
env_size = data_size - info_size;
if ((params->Environment = RtlAllocateHeap( GetProcessHeap(), 0, max( env_size, sizeof(WCHAR) ))))
env_size = params->EnvironmentSize;
if ((env = RtlAllocateHeap( GetProcessHeap(), 0, max( env_size, sizeof(WCHAR) ))))
{
if (env_size) memcpy( params->Environment, (char *)info + info_size, env_size );
else params->Environment[0] = 0;
if (env_size) memcpy( env, params->Environment, env_size );
else env[0] = 0;
params->Environment = env;
}
done:
RtlFreeHeap( GetProcessHeap(), 0, info );
if (RtlSetCurrentDirectory_U( &params->CurrentDirectory.DosPath ))
{
MESSAGE("wine: could not open working directory %s, starting in the Windows directory.\n",
......
......@@ -1164,32 +1164,6 @@ static void add_path_var( WCHAR *env, SIZE_T *pos, const char *name, const char
/*************************************************************************
* get_startup_info
*
* Get the startup information from the server.
*/
NTSTATUS CDECL get_startup_info( startup_info_t *info, SIZE_T *total_size, SIZE_T *info_size )
{
NTSTATUS status;
if (*total_size < startup_info_size)
{
*total_size = startup_info_size;
return STATUS_BUFFER_TOO_SMALL;
}
SERVER_START_REQ( get_startup_info )
{
wine_server_set_reply( req, info, *total_size );
status = wine_server_call( req );
*total_size = wine_server_reply_size( reply );
*info_size = reply->info_size;
}
SERVER_END_REQ;
return status;
}
/*************************************************************************
* get_dynamic_environment
*
* Get the environment variables that can differ between processes.
......@@ -1375,6 +1349,130 @@ void CDECL get_locales( WCHAR *sys, WCHAR *user )
}
static inline void copy_unicode_string( WCHAR **src, WCHAR **dst, UNICODE_STRING *str, UINT len )
{
str->Buffer = *dst;
str->Length = len;
str->MaximumLength = len + sizeof(WCHAR);
memcpy( *dst, *src, len );
(*dst)[len / sizeof(WCHAR)] = 0;
*src += len / sizeof(WCHAR);
*dst += len / sizeof(WCHAR) + 1;
}
/*************************************************************************
* build_initial_params
*
* Build process parameters from scratch, for processes without a parent.
*/
static RTL_USER_PROCESS_PARAMETERS *build_initial_params(void)
{
RTL_USER_PROCESS_PARAMETERS *params = NULL;
SIZE_T size;
NTSTATUS status;
size = sizeof(*params);
status = NtAllocateVirtualMemory( NtCurrentProcess(), (void **)&params, 0, &size,
MEM_COMMIT, PAGE_READWRITE );
assert( !status );
params->AllocationSize = size;
params->Size = size;
params->Flags = PROCESS_PARAMS_FLAG_NORMALIZED;
params->wShowWindow = 1; /* SW_SHOWNORMAL */
return params;
}
/*************************************************************************
* init_startup_info
*/
void init_startup_info(void)
{
WCHAR *src, *dst;
NTSTATUS status;
SIZE_T size, info_size, env_size;
RTL_USER_PROCESS_PARAMETERS *params = NULL;
startup_info_t *info;
if (!startup_info_size)
{
NtCurrentTeb()->Peb->ProcessParameters = build_initial_params();
return;
}
info = malloc( startup_info_size );
SERVER_START_REQ( get_startup_info )
{
wine_server_set_reply( req, info, startup_info_size );
status = wine_server_call( req );
info_size = reply->info_size;
env_size = wine_server_reply_size( reply ) - info_size;
}
SERVER_END_REQ;
assert( !status );
size = (sizeof(*params)
+ MAX_PATH * sizeof(WCHAR) /* curdir */
+ info->dllpath_len + sizeof(WCHAR)
+ info->imagepath_len + sizeof(WCHAR)
+ info->cmdline_len + sizeof(WCHAR)
+ info->title_len + sizeof(WCHAR)
+ info->desktop_len + sizeof(WCHAR)
+ info->shellinfo_len + sizeof(WCHAR)
+ info->runtime_len + sizeof(WCHAR)
+ env_size);
status = NtAllocateVirtualMemory( NtCurrentProcess(), (void **)&params, 0, &size,
MEM_COMMIT, PAGE_READWRITE );
assert( !status );
params->AllocationSize = size;
params->Size = size;
params->Flags = PROCESS_PARAMS_FLAG_NORMALIZED;
params->EnvironmentSize = env_size;
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);
/* curdir is special */
copy_unicode_string( &src, &dst, &params->CurrentDirectory.DosPath, info->curdir_len );
params->CurrentDirectory.DosPath.MaximumLength = MAX_PATH * sizeof(WCHAR);
dst = params->CurrentDirectory.DosPath.Buffer + MAX_PATH;
copy_unicode_string( &src, &dst, &params->DllPath, info->dllpath_len );
copy_unicode_string( &src, &dst, &params->ImagePathName, info->imagepath_len );
copy_unicode_string( &src, &dst, &params->CommandLine, info->cmdline_len );
copy_unicode_string( &src, &dst, &params->WindowTitle, info->title_len );
copy_unicode_string( &src, &dst, &params->Desktop, info->desktop_len );
copy_unicode_string( &src, &dst, &params->ShellInfo, info->shellinfo_len );
copy_unicode_string( &src, &dst, &params->RuntimeInfo, info->runtime_len );
params->RuntimeInfo.MaximumLength = params->RuntimeInfo.Length; /* runtime info isn't a real string */
params->Environment = dst;
memcpy( dst, src, env_size );
free( info );
NtCurrentTeb()->Peb->ProcessParameters = params;
}
/**************************************************************************
* NtGetNlsSectionPtr (NTDLL.@)
*/
......
......@@ -1608,7 +1608,6 @@ static struct unix_funcs unix_funcs =
ntdll_sqrt,
ntdll_tan,
get_initial_environment,
get_startup_info,
get_dynamic_environment,
get_initial_console,
get_initial_directory,
......@@ -1644,6 +1643,7 @@ static void start_main_thread(void)
virtual_map_user_shared_data();
init_cpu_info();
init_files();
init_startup_info();
NtCreateKeyedEvent( &keyed_event, GENERIC_READ | GENERIC_WRITE, NULL, 0 );
load_ntdll();
load_libwine();
......
......@@ -100,7 +100,6 @@ extern NTSTATUS CDECL fast_wait_cv( RTL_CONDITION_VARIABLE *variable, const void
const LARGE_INTEGER *timeout ) DECLSPEC_HIDDEN;
extern NTSTATUS CDECL get_initial_environment( WCHAR **wargv[], WCHAR *env, SIZE_T *size ) DECLSPEC_HIDDEN;
extern NTSTATUS CDECL get_startup_info( startup_info_t *info, SIZE_T *total_size, SIZE_T *info_size ) DECLSPEC_HIDDEN;
extern NTSTATUS CDECL get_dynamic_environment( WCHAR *env, SIZE_T *size ) DECLSPEC_HIDDEN;
extern void CDECL get_initial_directory( UNICODE_STRING *dir ) DECLSPEC_HIDDEN;
extern void CDECL get_initial_console( RTL_USER_PROCESS_PARAMETERS *params ) DECLSPEC_HIDDEN;
......@@ -138,6 +137,7 @@ extern struct ldt_copy __wine_ldt_copy DECLSPEC_HIDDEN;
#endif
extern void init_environment( int argc, char *argv[], char *envp[] ) DECLSPEC_HIDDEN;
extern void init_startup_info(void) DECLSPEC_HIDDEN;
extern DWORD ntdll_umbstowcs( const char *src, DWORD srclen, WCHAR *dst, DWORD dstlen ) DECLSPEC_HIDDEN;
extern int ntdll_wcstoumbs( const WCHAR *src, DWORD srclen, char *dst, DWORD dstlen, BOOL strict ) DECLSPEC_HIDDEN;
extern char **build_envp( const WCHAR *envW ) DECLSPEC_HIDDEN;
......
......@@ -27,7 +27,7 @@
struct _DISPATCHER_CONTEXT;
/* increment this when you change the function table */
#define NTDLL_UNIXLIB_VERSION 108
#define NTDLL_UNIXLIB_VERSION 109
struct unix_funcs
{
......@@ -72,7 +72,6 @@ struct unix_funcs
/* environment functions */
NTSTATUS (CDECL *get_initial_environment)( WCHAR **wargv[], WCHAR *env, SIZE_T *size );
NTSTATUS (CDECL *get_startup_info)( startup_info_t *info, SIZE_T *total_size, SIZE_T *info_size );
NTSTATUS (CDECL *get_dynamic_environment)( WCHAR *env, SIZE_T *size );
void (CDECL *get_initial_console)( RTL_USER_PROCESS_PARAMETERS *params );
void (CDECL *get_initial_directory)( UNICODE_STRING *dir );
......
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