- fixed a couple of bugs in ntdll environment functions (one in trace,
the other one in environment variable expansion) - the process parameters, when passed thru wineserver, are now fully handled in ntdll, they are stored in the RTL_USER_PROCESS_PARAMETERS structure. - later on in kernel32 loading sequence, those parameters are copied into STARTUPINFO shadow structures - later modification to those paramters are now reflected to the RTL_USER_PROCESS_PARAMETERS structure (and STARTUPINFO is kept untouched) (for example, StdHandle setting) (Win 2k behaves like this) - ENVDB has been removed - command line inheritance (from unix command line) is now purely in ntdll - all kernel32 environment functions now rely on their ntdll counterparts - goodies: input/output handle inheritance while asking for a detached console is better handled; a few more kernel32 environment tests now pass ; silenced a valgrind warning in process creation
This commit is contained in:
parent
d478261f30
commit
b53b5bcb50
|
@ -48,6 +48,8 @@ extern BOOL RELAY_Init(void);
|
|||
extern void COMPUTERNAME_Init(void);
|
||||
|
||||
extern int __wine_set_signal_handler(unsigned, int (*)(unsigned));
|
||||
/* memory/environ.c */
|
||||
extern void ENV_CopyStartupInformation(void);
|
||||
|
||||
extern int main_create_flags;
|
||||
|
||||
|
@ -113,6 +115,9 @@ static BOOL process_attach(void)
|
|||
|
||||
/* Setup computer name */
|
||||
COMPUTERNAME_Init();
|
||||
|
||||
/* copy process information from ntdll */
|
||||
ENV_CopyStartupInformation();
|
||||
|
||||
if ((hModule = LoadLibrary16( "krnl386.exe" )) >= 32)
|
||||
{
|
||||
|
@ -168,6 +173,14 @@ static BOOL process_attach(void)
|
|||
if (RtlImageNtHeader(mod)->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI)
|
||||
AllocConsole();
|
||||
}
|
||||
else if (!(main_create_flags & DETACHED_PROCESS))
|
||||
{
|
||||
/* 1/ shall inherit console + handles
|
||||
* 2/ shall create std handles, if handles are not inherited
|
||||
* TBD when not using wineserver handles for console handles
|
||||
*/
|
||||
}
|
||||
|
||||
if (main_create_flags & CREATE_NEW_PROCESS_GROUP)
|
||||
SetConsoleCtrlHandler(NULL, TRUE);
|
||||
|
||||
|
|
279
dlls/ntdll/env.c
279
dlls/ntdll/env.c
|
@ -130,6 +130,7 @@ NTSTATUS WINAPI RtlQueryEnvironmentVariable_U(PWSTR env,
|
|||
if (var != NULL)
|
||||
{
|
||||
value->Length = strlenW(var) * sizeof(WCHAR);
|
||||
|
||||
if (value->Length <= value->MaximumLength)
|
||||
{
|
||||
memmove(value->Buffer, var, min(value->Length + sizeof(WCHAR), value->MaximumLength));
|
||||
|
@ -171,7 +172,9 @@ NTSTATUS WINAPI RtlSetEnvironmentVariable(PWSTR* penv, PUNICODE_STRING name,
|
|||
NTSTATUS nts = STATUS_VARIABLE_NOT_FOUND;
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
|
||||
TRACE("(%p,%s,%s): stub!\n", penv, debugstr_w(name->Buffer), debugstr_w(value->Buffer));
|
||||
TRACE("(%p,%s,%s)\n",
|
||||
penv, debugstr_w(name->Buffer),
|
||||
value ? debugstr_w(value->Buffer) : "--nil--");
|
||||
|
||||
if (!name || !name->Buffer || !name->Buffer[0])
|
||||
return STATUS_INVALID_PARAMETER_1;
|
||||
|
@ -245,7 +248,6 @@ NTSTATUS WINAPI RtlSetEnvironmentVariable(PWSTR* penv, PUNICODE_STRING name,
|
|||
strcatW(p, equalW);
|
||||
strcatW(p, value->Buffer);
|
||||
}
|
||||
|
||||
done:
|
||||
if (!penv) RtlReleasePebLock();
|
||||
|
||||
|
@ -256,18 +258,23 @@ done:
|
|||
* RtlExpandEnvironmentStrings_U (NTDLL.@)
|
||||
*
|
||||
*/
|
||||
NTSTATUS WINAPI RtlExpandEnvironmentStrings_U(PWSTR env, const UNICODE_STRING* us_src,
|
||||
NTSTATUS WINAPI RtlExpandEnvironmentStrings_U(PWSTR renv, const UNICODE_STRING* us_src,
|
||||
PUNICODE_STRING us_dst, PULONG plen)
|
||||
{
|
||||
DWORD len, count, total_size = 1; /* 1 for terminating '\0' */
|
||||
LPCWSTR src, p, var;
|
||||
LPCWSTR env, src, p, var;
|
||||
LPWSTR dst;
|
||||
|
||||
src = us_src->Buffer;
|
||||
count = us_dst->MaximumLength / sizeof(WCHAR);
|
||||
dst = count ? us_dst->Buffer : NULL;
|
||||
|
||||
RtlAcquirePebLock();
|
||||
if (!renv)
|
||||
{
|
||||
RtlAcquirePebLock();
|
||||
env = ntdll_get_process_pmts()->Environment;
|
||||
}
|
||||
else env = renv;
|
||||
|
||||
while (*src)
|
||||
{
|
||||
|
@ -312,12 +319,12 @@ NTSTATUS WINAPI RtlExpandEnvironmentStrings_U(PWSTR env, const UNICODE_STRING* u
|
|||
}
|
||||
}
|
||||
|
||||
RtlReleasePebLock();
|
||||
if (!renv) RtlReleasePebLock();
|
||||
|
||||
/* Null-terminate the string */
|
||||
if (dst && count) *dst = '\0';
|
||||
|
||||
us_dst->Length = (dst) ? (dst - us_dst->Buffer) * sizeof(WCHAR): 0;
|
||||
us_dst->Length = (dst) ? (dst - us_dst->Buffer) * sizeof(WCHAR) : 0;
|
||||
if (plen) *plen = total_size * sizeof(WCHAR);
|
||||
|
||||
return (count) ? STATUS_SUCCESS : STATUS_BUFFER_TOO_SMALL;
|
||||
|
@ -328,7 +335,7 @@ NTSTATUS WINAPI RtlExpandEnvironmentStrings_U(PWSTR env, const UNICODE_STRING* u
|
|||
*
|
||||
* Build the Win32 environment from the Unix environment
|
||||
*/
|
||||
BOOL build_initial_environment(void)
|
||||
static NTSTATUS build_initial_environment(void)
|
||||
{
|
||||
extern char **environ;
|
||||
LPSTR* e, te;
|
||||
|
@ -349,9 +356,10 @@ BOOL build_initial_environment(void)
|
|||
/* Now allocate the environment */
|
||||
nts = NtAllocateVirtualMemory(NtCurrentProcess(), (void**)&p, 0, &size,
|
||||
MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
||||
if (nts != STATUS_SUCCESS) return FALSE;
|
||||
if (nts != STATUS_SUCCESS) return nts;
|
||||
|
||||
ntdll_get_process_pmts()->Environment = p;
|
||||
|
||||
/* And fill it with the Unix environment */
|
||||
for (e = environ; *e; e++)
|
||||
{
|
||||
|
@ -365,5 +373,258 @@ BOOL build_initial_environment(void)
|
|||
}
|
||||
*p = 0;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void init_unicode( UNICODE_STRING* us, const char** src, size_t len)
|
||||
{
|
||||
if (len)
|
||||
{
|
||||
STRING ansi;
|
||||
ansi.Buffer = (char*)*src;
|
||||
ansi.Length = len;
|
||||
ansi.MaximumLength = len;
|
||||
/* FIXME: should check value returned */
|
||||
RtlAnsiStringToUnicodeString( us, &ansi, TRUE );
|
||||
*src += len;
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* init_user_process_pmts
|
||||
*
|
||||
* Fill the RTL_USER_PROCESS_PARAMETERS structure from the server.
|
||||
*/
|
||||
BOOL init_user_process_pmts( size_t info_size, char *main_exe_name, size_t main_exe_size )
|
||||
{
|
||||
startup_info_t info;
|
||||
void *data;
|
||||
const char *src;
|
||||
size_t len;
|
||||
RTL_USER_PROCESS_PARAMETERS *rupp;
|
||||
|
||||
if (build_initial_environment() != STATUS_SUCCESS) return FALSE;
|
||||
if (!info_size) return TRUE;
|
||||
if (!(data = RtlAllocateHeap( ntdll_get_process_heap(), 0, info_size )))
|
||||
return FALSE;
|
||||
|
||||
SERVER_START_REQ( get_startup_info )
|
||||
{
|
||||
wine_server_set_reply( req, data, info_size );
|
||||
wine_server_call( req );
|
||||
info_size = wine_server_reply_size( reply );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
if (info_size < sizeof(info.size)) goto done;
|
||||
len = min( info_size, ((startup_info_t *)data)->size );
|
||||
memset( &info, 0, sizeof(info) );
|
||||
memcpy( &info, data, len );
|
||||
src = (char *)data + len;
|
||||
info_size -= len;
|
||||
|
||||
/* fixup the lengths */
|
||||
if (info.filename_len > info_size) info.filename_len = info_size;
|
||||
info_size -= info.filename_len;
|
||||
if (info.cmdline_len > info_size) info.cmdline_len = info_size;
|
||||
info_size -= info.cmdline_len;
|
||||
if (info.desktop_len > info_size) info.desktop_len = info_size;
|
||||
info_size -= info.desktop_len;
|
||||
if (info.title_len > info_size) info.title_len = info_size;
|
||||
|
||||
/* store the filename */
|
||||
len = min( info.filename_len, main_exe_size-1 );
|
||||
memcpy( main_exe_name, src, len );
|
||||
main_exe_name[len] = 0;
|
||||
|
||||
rupp = NtCurrentTeb()->Peb->ProcessParameters;
|
||||
|
||||
init_unicode( &rupp->ImagePathName, &src, info.filename_len );
|
||||
init_unicode( &rupp->CommandLine, &src, info.cmdline_len );
|
||||
init_unicode( &rupp->Desktop, &src, info.desktop_len );
|
||||
init_unicode( &rupp->WindowTitle, &src, info.title_len );
|
||||
|
||||
rupp->dwX = info.x;
|
||||
rupp->dwY = info.y;
|
||||
rupp->dwXSize = info.cx;
|
||||
rupp->dwYSize = info.cy;
|
||||
rupp->dwXCountChars = info.x_chars;
|
||||
rupp->dwYCountChars = info.y_chars;
|
||||
rupp->dwFillAttribute = info.attribute;
|
||||
rupp->wShowWindow = info.cmd_show;
|
||||
rupp->dwFlags = info.flags;
|
||||
|
||||
done:
|
||||
RtlFreeHeap( ntdll_get_process_heap(), 0, data );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* set_library_argv
|
||||
*
|
||||
* Set the Wine library argc/argv global variables.
|
||||
*/
|
||||
static void set_library_argv( char **argv )
|
||||
{
|
||||
int argc;
|
||||
WCHAR *p;
|
||||
WCHAR **wargv;
|
||||
DWORD total = 0, len, reslen;
|
||||
|
||||
for (argc = 0; argv[argc]; argc++)
|
||||
{
|
||||
len = strlen(argv[argc]) + 1;
|
||||
RtlMultiByteToUnicodeN(NULL, 0, &reslen, argv[argc], len);
|
||||
total += reslen;
|
||||
}
|
||||
wargv = RtlAllocateHeap( ntdll_get_process_heap(), 0,
|
||||
total + (argc + 1) * sizeof(*wargv) );
|
||||
p = (WCHAR *)(wargv + argc + 1);
|
||||
for (argc = 0; argv[argc]; argc++)
|
||||
{
|
||||
len = strlen(argv[argc]) + 1;
|
||||
RtlMultiByteToUnicodeN(p, total, &reslen, argv[argc], len);
|
||||
wargv[argc] = p;
|
||||
p += reslen / sizeof(WCHAR);
|
||||
total -= reslen;
|
||||
}
|
||||
wargv[argc] = NULL;
|
||||
|
||||
__wine_main_argc = argc;
|
||||
__wine_main_argv = argv;
|
||||
__wine_main_wargv = wargv;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* build_command_line
|
||||
*
|
||||
* Build the command line of a process from the argv array.
|
||||
*
|
||||
* Note that it does NOT necessarily include the file name.
|
||||
* Sometimes we don't even have any command line options at all.
|
||||
*
|
||||
* We must quote and escape characters so that the argv array can be rebuilt
|
||||
* from the command line:
|
||||
* - spaces and tabs must be quoted
|
||||
* 'a b' -> '"a b"'
|
||||
* - quotes must be escaped
|
||||
* '"' -> '\"'
|
||||
* - if '\'s are followed by a '"', they must be doubled and followed by '\"',
|
||||
* resulting in an odd number of '\' followed by a '"'
|
||||
* '\"' -> '\\\"'
|
||||
* '\\"' -> '\\\\\"'
|
||||
* - '\'s that are not followed by a '"' can be left as is
|
||||
* 'a\b' == 'a\b'
|
||||
* 'a\\b' == 'a\\b'
|
||||
*/
|
||||
BOOL build_command_line( char **argv )
|
||||
{
|
||||
int len;
|
||||
char **arg;
|
||||
LPWSTR p;
|
||||
RTL_USER_PROCESS_PARAMETERS* rupp;
|
||||
|
||||
set_library_argv( argv );
|
||||
|
||||
rupp = ntdll_get_process_pmts();
|
||||
if (rupp->CommandLine.Buffer) return TRUE; /* already got it from the server */
|
||||
|
||||
len = 0;
|
||||
for (arg = argv; *arg; arg++)
|
||||
{
|
||||
int has_space,bcount;
|
||||
char* a;
|
||||
|
||||
has_space=0;
|
||||
bcount=0;
|
||||
a=*arg;
|
||||
while (*a!='\0') {
|
||||
if (*a=='\\') {
|
||||
bcount++;
|
||||
} else {
|
||||
if (*a==' ' || *a=='\t') {
|
||||
has_space=1;
|
||||
} else if (*a=='"') {
|
||||
/* doubling of '\' preceeding a '"',
|
||||
* plus escaping of said '"'
|
||||
*/
|
||||
len+=2*bcount+1;
|
||||
}
|
||||
bcount=0;
|
||||
}
|
||||
a++;
|
||||
}
|
||||
len+=(a-*arg)+1 /* for the separating space */;
|
||||
if (has_space)
|
||||
len+=2; /* for the quotes */
|
||||
}
|
||||
|
||||
if (!(rupp->CommandLine.Buffer = RtlAllocateHeap( ntdll_get_process_heap(), 0, len * sizeof(WCHAR))))
|
||||
return FALSE;
|
||||
|
||||
p = rupp->CommandLine.Buffer;
|
||||
rupp->CommandLine.Length = (len - 1) * sizeof(WCHAR);
|
||||
rupp->CommandLine.MaximumLength = len * sizeof(WCHAR);
|
||||
for (arg = argv; *arg; arg++)
|
||||
{
|
||||
int has_space,has_quote;
|
||||
char* a;
|
||||
|
||||
/* Check for quotes and spaces in this argument */
|
||||
has_space=has_quote=0;
|
||||
a=*arg;
|
||||
while (*a!='\0') {
|
||||
if (*a==' ' || *a=='\t') {
|
||||
has_space=1;
|
||||
if (has_quote)
|
||||
break;
|
||||
} else if (*a=='"') {
|
||||
has_quote=1;
|
||||
if (has_space)
|
||||
break;
|
||||
}
|
||||
a++;
|
||||
}
|
||||
|
||||
/* Now transfer it to the command line */
|
||||
if (has_space)
|
||||
*p++='"';
|
||||
if (has_quote) {
|
||||
int bcount;
|
||||
char* a;
|
||||
|
||||
bcount=0;
|
||||
a=*arg;
|
||||
while (*a!='\0') {
|
||||
if (*a=='\\') {
|
||||
*p++=*a;
|
||||
bcount++;
|
||||
} else {
|
||||
if (*a=='"') {
|
||||
int i;
|
||||
|
||||
/* Double all the '\\' preceeding this '"', plus one */
|
||||
for (i=0;i<=bcount;i++)
|
||||
*p++='\\';
|
||||
*p++='"';
|
||||
} else {
|
||||
*p++=*a;
|
||||
}
|
||||
bcount=0;
|
||||
}
|
||||
a++;
|
||||
}
|
||||
} else {
|
||||
char* x = *arg;
|
||||
while ((*p=*x++)) p++;
|
||||
}
|
||||
if (has_space)
|
||||
*p++='"';
|
||||
*p++=' ';
|
||||
}
|
||||
if (p > rupp->CommandLine.Buffer)
|
||||
p--; /* remove last space */
|
||||
*p = '\0';
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -45,12 +45,8 @@ static inline HANDLE ntdll_get_process_heap(void)
|
|||
return NtCurrentTeb()->Peb->ProcessHeap;
|
||||
}
|
||||
|
||||
/* FIXME: this should be part of PEB, once it's defined */
|
||||
extern RTL_USER_PROCESS_PARAMETERS process_pmts;
|
||||
BOOL build_initial_environment(void);
|
||||
|
||||
static inline RTL_USER_PROCESS_PARAMETERS* ntdll_get_process_pmts(void)
|
||||
{
|
||||
return &process_pmts;
|
||||
return NtCurrentTeb()->Peb->ProcessParameters;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -126,7 +126,7 @@ typedef struct _RTL_USER_PROCESS_PARAMETERS
|
|||
ULONG dwFlags;
|
||||
ULONG wShowWindow;
|
||||
UNICODE_STRING WindowTitle;
|
||||
UNICODE_STRING DesktopInfo;
|
||||
UNICODE_STRING Desktop;
|
||||
UNICODE_STRING ShellInfo;
|
||||
UNICODE_STRING RuntimeInfo;
|
||||
RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory[0x20];
|
||||
|
|
879
memory/environ.c
879
memory/environ.c
File diff suppressed because it is too large
Load Diff
|
@ -47,7 +47,6 @@
|
|||
#include "wine/server.h"
|
||||
#include "options.h"
|
||||
#include "wine/debug.h"
|
||||
#include "ntdll_misc.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(process);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(server);
|
||||
|
@ -55,15 +54,13 @@ WINE_DECLARE_DEBUG_CHANNEL(relay);
|
|||
WINE_DECLARE_DEBUG_CHANNEL(snoop);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(win32);
|
||||
|
||||
struct _ENVDB;
|
||||
|
||||
/* Win32 process database */
|
||||
typedef struct _PDB
|
||||
{
|
||||
LONG header[2]; /* 00 Kernel object header */
|
||||
HMODULE module; /* 08 Main exe module (NT) */
|
||||
void *event; /* 0c Pointer to an event object (unused) */
|
||||
DWORD exit_code; /* 10 Process exit code */
|
||||
RTL_USER_PROCESS_PARAMETERS *ProcessParameters; /* 10 Process parameters*/
|
||||
DWORD unknown2; /* 14 Unknown */
|
||||
HANDLE heap; /* 18 Default process heap */
|
||||
HANDLE mem_context; /* 1c Process memory context */
|
||||
|
@ -109,7 +106,7 @@ typedef struct _PDB
|
|||
|
||||
PDB current_process;
|
||||
|
||||
RTL_USER_PROCESS_PARAMETERS process_pmts;
|
||||
static RTL_USER_PROCESS_PARAMETERS process_pmts;
|
||||
|
||||
/* Process flags */
|
||||
#define PDB32_DEBUGGED 0x0001 /* Process is being debugged */
|
||||
|
@ -126,15 +123,13 @@ static unsigned int server_startticks;
|
|||
|
||||
int main_create_flags = 0;
|
||||
|
||||
/* memory/environ.c */
|
||||
extern struct _ENVDB *ENV_InitStartupInfo( size_t info_size, char *main_exe_name,
|
||||
size_t main_exe_size );
|
||||
extern BOOL ENV_BuildCommandLine( char **argv );
|
||||
extern STARTUPINFOA current_startupinfo;
|
||||
|
||||
/* scheduler/pthread.c */
|
||||
extern void PTHREAD_init_done(void);
|
||||
|
||||
/* dlls/ntdll/env.c */
|
||||
extern BOOL init_user_process_pmts( size_t, char*, size_t );
|
||||
extern BOOL build_command_line( char **argv );
|
||||
|
||||
extern void RELAY_InitDebugLists(void);
|
||||
extern void SHELL_LoadRegistry(void);
|
||||
extern void VERSION_Init( const char *appname );
|
||||
|
@ -302,12 +297,12 @@ static BOOL process_init( char *argv[] )
|
|||
argv0 = argv[0];
|
||||
|
||||
/* Fill the initial process structure */
|
||||
current_process.exit_code = STILL_ACTIVE;
|
||||
current_process.threads = 1;
|
||||
current_process.running_threads = 1;
|
||||
current_process.ring0_threads = 1;
|
||||
current_process.group = ¤t_process;
|
||||
current_process.priority = 8; /* Normal */
|
||||
current_process.ProcessParameters = &process_pmts;
|
||||
|
||||
/* Setup the server connection */
|
||||
CLIENT_InitServer();
|
||||
|
@ -322,9 +317,9 @@ static BOOL process_init( char *argv[] )
|
|||
main_create_flags = reply->create_flags;
|
||||
info_size = reply->info_size;
|
||||
server_startticks = reply->server_start;
|
||||
current_startupinfo.hStdInput = reply->hstdin;
|
||||
current_startupinfo.hStdOutput = reply->hstdout;
|
||||
current_startupinfo.hStdError = reply->hstderr;
|
||||
process_pmts.hStdInput = reply->hstdin;
|
||||
process_pmts.hStdOutput = reply->hstdout;
|
||||
process_pmts.hStdError = reply->hstderr;
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
@ -334,44 +329,33 @@ static BOOL process_init( char *argv[] )
|
|||
current_process.heap = HeapCreate( HEAP_GROWABLE, 0, 0 );
|
||||
|
||||
if (main_create_flags == 0 &&
|
||||
current_startupinfo.hStdInput == 0 &&
|
||||
current_startupinfo.hStdOutput == 0 &&
|
||||
current_startupinfo.hStdError == 0)
|
||||
process_pmts.hStdInput == 0 &&
|
||||
process_pmts.hStdOutput == 0 &&
|
||||
process_pmts.hStdError == 0)
|
||||
{
|
||||
/* no parent, and no new console requested, create a simple console with bare handles to
|
||||
/* This is wine specific:
|
||||
* no parent, and no new console requested, create a simple console with bare handles to
|
||||
* unix stdio input & output streams (aka simple console)
|
||||
*/
|
||||
HANDLE handle;
|
||||
wine_server_fd_to_handle( 0, GENERIC_READ|SYNCHRONIZE, TRUE, &handle );
|
||||
SetStdHandle( STD_INPUT_HANDLE, handle );
|
||||
wine_server_fd_to_handle( 1, GENERIC_WRITE|SYNCHRONIZE, TRUE, &handle );
|
||||
SetStdHandle( STD_OUTPUT_HANDLE, handle );
|
||||
wine_server_fd_to_handle( 1, GENERIC_WRITE|SYNCHRONIZE, TRUE, &handle );
|
||||
SetStdHandle( STD_ERROR_HANDLE, handle );
|
||||
}
|
||||
else if (!(main_create_flags & (DETACHED_PROCESS|CREATE_NEW_CONSOLE)))
|
||||
{
|
||||
SetStdHandle( STD_INPUT_HANDLE, current_startupinfo.hStdInput );
|
||||
SetStdHandle( STD_OUTPUT_HANDLE, current_startupinfo.hStdOutput );
|
||||
SetStdHandle( STD_ERROR_HANDLE, current_startupinfo.hStdError );
|
||||
wine_server_fd_to_handle( 0, GENERIC_READ|SYNCHRONIZE, TRUE, &process_pmts.hStdInput );
|
||||
wine_server_fd_to_handle( 1, GENERIC_WRITE|SYNCHRONIZE, TRUE, &process_pmts.hStdOutput );
|
||||
wine_server_fd_to_handle( 1, GENERIC_WRITE|SYNCHRONIZE, TRUE, &process_pmts.hStdError );
|
||||
}
|
||||
|
||||
/* Now we can use the pthreads routines */
|
||||
PTHREAD_init_done();
|
||||
|
||||
/* Copy the parent environment */
|
||||
if (!(current_process.env_db = ENV_InitStartupInfo( info_size, main_exe_name,
|
||||
sizeof(main_exe_name) )))
|
||||
if (!init_user_process_pmts( info_size, main_exe_name, sizeof(main_exe_name) ))
|
||||
return FALSE;
|
||||
|
||||
/* Parse command line arguments */
|
||||
OPTIONS_ParseOptions( !info_size ? argv : NULL );
|
||||
|
||||
/* <hack: to be changed later on> */
|
||||
build_initial_environment();
|
||||
process_pmts.CurrentDirectoryName.Length = 3 * sizeof(WCHAR);
|
||||
process_pmts.CurrentDirectoryName.MaximumLength = RtlGetLongestNtPathLength() * sizeof(WCHAR);
|
||||
process_pmts.CurrentDirectoryName.Buffer = RtlAllocateHeap( ntdll_get_process_heap(), 0, process_pmts.CurrentDirectoryName.MaximumLength);
|
||||
process_pmts.CurrentDirectoryName.Buffer = RtlAllocateHeap( GetProcessHeap(), 0, process_pmts.CurrentDirectoryName.MaximumLength);
|
||||
process_pmts.CurrentDirectoryName.Buffer[0] = 'C';
|
||||
process_pmts.CurrentDirectoryName.Buffer[1] = ':';
|
||||
process_pmts.CurrentDirectoryName.Buffer[2] = '\\';
|
||||
|
@ -579,7 +563,7 @@ void __wine_process_init( int argc, char *argv[] )
|
|||
|
||||
found:
|
||||
/* build command line */
|
||||
if (!ENV_BuildCommandLine( argv )) goto error;
|
||||
if (!build_command_line( argv )) goto error;
|
||||
|
||||
/* create 32-bit module for main exe */
|
||||
if (!(current_process.module = BUILTIN32_LoadExeModule( current_process.module ))) goto error;
|
||||
|
@ -861,7 +845,7 @@ static BOOL create_process( HANDLE hFile, LPCSTR filename, LPSTR cmd_line, LPCST
|
|||
int execfd[2];
|
||||
pid_t pid;
|
||||
int err;
|
||||
char dummy;
|
||||
char dummy = 0;
|
||||
|
||||
if (!env)
|
||||
{
|
||||
|
@ -1404,7 +1388,8 @@ BOOL WINAPI TerminateProcess( HANDLE handle, DWORD exit_code )
|
|||
*/
|
||||
DWORD WINAPI GetProcessDword( DWORD dwProcessID, INT offset )
|
||||
{
|
||||
DWORD x, y;
|
||||
DWORD x, y;
|
||||
STARTUPINFOW siw;
|
||||
|
||||
TRACE_(win32)("(%ld, %d)\n", dwProcessID, offset );
|
||||
|
||||
|
@ -1435,30 +1420,36 @@ DWORD WINAPI GetProcessDword( DWORD dwProcessID, INT offset )
|
|||
return (DWORD)¤t_process;
|
||||
|
||||
case GPD_STARTF_SHELLDATA: /* return stdoutput handle from startupinfo ??? */
|
||||
return (DWORD)current_startupinfo.hStdOutput;
|
||||
GetStartupInfoW(&siw);
|
||||
return (DWORD)siw.hStdOutput;
|
||||
|
||||
case GPD_STARTF_HOTKEY: /* return stdinput handle from startupinfo ??? */
|
||||
return (DWORD)current_startupinfo.hStdInput;
|
||||
GetStartupInfoW(&siw);
|
||||
return (DWORD)siw.hStdInput;
|
||||
|
||||
case GPD_STARTF_SHOWWINDOW:
|
||||
return current_startupinfo.wShowWindow;
|
||||
GetStartupInfoW(&siw);
|
||||
return siw.wShowWindow;
|
||||
|
||||
case GPD_STARTF_SIZE:
|
||||
x = current_startupinfo.dwXSize;
|
||||
GetStartupInfoW(&siw);
|
||||
x = siw.dwXSize;
|
||||
if ( (INT)x == CW_USEDEFAULT ) x = CW_USEDEFAULT16;
|
||||
y = current_startupinfo.dwYSize;
|
||||
y = siw.dwYSize;
|
||||
if ( (INT)y == CW_USEDEFAULT ) y = CW_USEDEFAULT16;
|
||||
return MAKELONG( x, y );
|
||||
|
||||
case GPD_STARTF_POSITION:
|
||||
x = current_startupinfo.dwX;
|
||||
GetStartupInfoW(&siw);
|
||||
x = siw.dwX;
|
||||
if ( (INT)x == CW_USEDEFAULT ) x = CW_USEDEFAULT16;
|
||||
y = current_startupinfo.dwY;
|
||||
y = siw.dwY;
|
||||
if ( (INT)y == CW_USEDEFAULT ) y = CW_USEDEFAULT16;
|
||||
return MAKELONG( x, y );
|
||||
|
||||
case GPD_STARTF_FLAGS:
|
||||
return current_startupinfo.dwFlags;
|
||||
GetStartupInfoW(&siw);
|
||||
return process_pmts.dwFlags;
|
||||
|
||||
case GPD_PARENT:
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue