diff --git a/dlls/kernel/module.c b/dlls/kernel/module.c index c59257fbd3f..d06b0c495c3 100644 --- a/dlls/kernel/module.c +++ b/dlls/kernel/module.c @@ -130,7 +130,7 @@ good: /*********************************************************************** * MODULE_GetBinaryType */ -enum binary_type MODULE_GetBinaryType( HANDLE hfile ) +enum binary_type MODULE_GetBinaryType( HANDLE hfile, void **res_start, void **res_end ) { union { @@ -150,7 +150,6 @@ enum binary_type MODULE_GetBinaryType( HANDLE hfile ) IMAGE_DOS_HEADER mz; } header; - char magic[4]; DWORD len; /* Seek to the start of the file and read the header information. */ @@ -184,6 +183,12 @@ enum binary_type MODULE_GetBinaryType( HANDLE hfile ) if (header.mz.e_magic == IMAGE_DOS_SIGNATURE) { + union + { + IMAGE_OS2_HEADER os2; + IMAGE_NT_HEADERS nt; + } ext_header; + /* We do have a DOS image so we will now try to seek into * the file by the amount indicated by the field * "Offset to extended header" and read in the @@ -193,41 +198,41 @@ enum binary_type MODULE_GetBinaryType( HANDLE hfile ) */ if (SetFilePointer( hfile, header.mz.e_lfanew, NULL, SEEK_SET ) == -1) return BINARY_DOS; - if (!ReadFile( hfile, magic, sizeof(magic), &len, NULL ) || len != sizeof(magic)) + if (!ReadFile( hfile, &ext_header, sizeof(ext_header), &len, NULL ) || len < 4) return BINARY_DOS; /* Reading the magic field succeeded so * we will try to determine what type it is. */ - if (!memcmp( magic, "PE\0\0", 4 )) + if (!memcmp( &ext_header.nt.Signature, "PE\0\0", 4 )) { - IMAGE_FILE_HEADER FileHeader; - - if (ReadFile( hfile, &FileHeader, sizeof(FileHeader), &len, NULL ) && len == sizeof(FileHeader)) + if (len >= sizeof(ext_header.nt.FileHeader)) { - if (FileHeader.Characteristics & IMAGE_FILE_DLL) return BINARY_PE_DLL; + if (len < sizeof(ext_header.nt)) /* clear remaining part of header if missing */ + memset( (char *)&ext_header.nt + len, 0, sizeof(ext_header.nt) - len ); + if (res_start) *res_start = (void *)ext_header.nt.OptionalHeader.ImageBase; + if (res_end) *res_end = (void *)(ext_header.nt.OptionalHeader.ImageBase + + ext_header.nt.OptionalHeader.SizeOfImage); + if (ext_header.nt.FileHeader.Characteristics & IMAGE_FILE_DLL) return BINARY_PE_DLL; return BINARY_PE_EXE; } return BINARY_DOS; } - if (!memcmp( magic, "NE", 2 )) + if (!memcmp( &ext_header.os2.ne_magic, "NE", 2 )) { /* This is a Windows executable (NE) header. This can * mean either a 16-bit OS/2 or a 16-bit Windows or even a * DOS program (running under a DOS extender). To decide * which, we'll have to read the NE header. */ - IMAGE_OS2_HEADER ne; - if ( SetFilePointer( hfile, header.mz.e_lfanew, NULL, SEEK_SET ) != -1 - && ReadFile( hfile, &ne, sizeof(ne), &len, NULL ) - && len == sizeof(ne) ) + if (len >= sizeof(ext_header.os2)) { - switch ( ne.ne_exetyp ) + switch ( ext_header.os2.ne_exetyp ) { case 2: return BINARY_WIN16; case 5: return BINARY_DOS; - default: return MODULE_Decide_OS2_OldWin(hfile, &header.mz, &ne); + default: return MODULE_Decide_OS2_OldWin(hfile, &header.mz, &ext_header.os2); } } /* Couldn't read header, so abort. */ @@ -295,7 +300,7 @@ BOOL WINAPI GetBinaryTypeW( LPCWSTR lpApplicationName, LPDWORD lpBinaryType ) /* Check binary type */ - switch(MODULE_GetBinaryType( hfile )) + switch(MODULE_GetBinaryType( hfile, NULL, NULL )) { case BINARY_UNKNOWN: { diff --git a/dlls/kernel/process.c b/dlls/kernel/process.c index 7d0048a4bae..b25d5eb9c15 100644 --- a/dlls/kernel/process.c +++ b/dlls/kernel/process.c @@ -389,6 +389,7 @@ static BOOL build_initial_environment( char **environ ) if (!strncmp( str, "WINE", 4 )) { if (is_special_env_var( str + 4 )) str += 4; + else if (!strncmp( str, "WINEPRELOADRESERVE=", 19 )) continue; /* skip it */ } else if (is_special_env_var( str )) continue; /* skip it */ @@ -1051,7 +1052,7 @@ void __wine_kernel_init(void) ExitProcess(1); } - switch( MODULE_GetBinaryType( main_exe_file )) + switch( MODULE_GetBinaryType( main_exe_file, NULL, NULL )) { case BINARY_PE_EXE: TRACE( "starting Win32 binary %s\n", debugstr_w(main_exe_name) ); @@ -1257,26 +1258,28 @@ static char *alloc_env_string( const char *name, const char *value ) * * Build the environment of a new child process. */ -static char **build_envp( const WCHAR *envW ) +static char **build_envp( const WCHAR *envW, char *extra_env ) { - const WCHAR *p; + const WCHAR *end; char **envp; - char *env; + char *env, *p; int count = 0, length; - for (p = envW; *p; count++) p += strlenW(p) + 1; - p++; - length = WideCharToMultiByte( CP_UNIXCP, 0, envW, p - envW, NULL, 0, NULL, NULL ); + for (end = envW; *end; count++) end += strlenW(end) + 1; + end++; + length = WideCharToMultiByte( CP_UNIXCP, 0, envW, end - envW, NULL, 0, NULL, NULL ); if (!(env = malloc( length ))) return NULL; - WideCharToMultiByte( CP_UNIXCP, 0, envW, p - envW, env, length, NULL, NULL ); + WideCharToMultiByte( CP_UNIXCP, 0, envW, end - envW, env, length, NULL, NULL ); + if (extra_env) for (p = extra_env; *p; p += strlen(p) + 1) count++; count += 4; if ((envp = malloc( count * sizeof(*envp) ))) { char **envptr = envp; - char *p; + /* first the extra strings */ + for (p = extra_env; *p; p += strlen(p) + 1) *envptr++ = alloc_env_string( "", p ); /* then put PATH, TEMP, TMP, HOME and WINEPREFIX from the unix env */ if ((p = getenv("PATH"))) *envptr++ = alloc_env_string( "PATH=", p ); if ((p = getenv("TEMP"))) *envptr++ = alloc_env_string( "TEMP=", p ); @@ -1289,6 +1292,7 @@ static char **build_envp( const WCHAR *envW ) if (is_special_env_var( p )) /* prefix it with "WINE" */ *envptr++ = alloc_env_string( "WINE", p ); else if (strncmp( p, "HOME=", 5 ) && + strncmp( p, "WINEPRELOADRESERVE=", 19 ) && strncmp( p, "WINEPREFIX=", 11 )) *envptr++ = p; } *envptr = 0; @@ -1319,7 +1323,7 @@ static int fork_and_exec( const char *filename, const WCHAR *cmdline, if (!(pid = fork())) /* child */ { char **argv = build_argv( cmdline, 0 ); - char **envp = build_envp( env ); + char **envp = build_envp( env, NULL ); close( fd[0] ); /* Reset signals that we previously set to SIG_IGN */ @@ -1405,7 +1409,8 @@ static RTL_USER_PROCESS_PARAMETERS *create_user_params( LPCWSTR filename, LPCWST static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPWSTR env, LPCWSTR cur_dir, LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa, BOOL inherit, DWORD flags, LPSTARTUPINFOW startup, - LPPROCESS_INFORMATION info, LPCSTR unixdir ) + LPPROCESS_INFORMATION info, LPCSTR unixdir, + void *res_start, void *res_end ) { BOOL ret, success = FALSE; HANDLE process_info; @@ -1415,12 +1420,16 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW pid_t pid; int err; char dummy = 0; + char preloader_reserve[64]; if (!env) env = GetEnvironmentStringsW(); if (!(params = create_user_params( filename, cmd_line, cur_dir, startup ))) return FALSE; + sprintf( preloader_reserve, "WINEPRELOADRESERVE=%lx-%lx%c", + (unsigned long)res_start, (unsigned long)res_end, 0 ); + /* create the synchronization pipes */ if (pipe( startfd ) == -1) @@ -1444,7 +1453,7 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW if (!(pid = fork())) /* child */ { char **argv = build_argv( cmd_line, 1 ); - char **envp = build_envp( env ); + char **envp = build_envp( env, preloader_reserve ); close( startfd[1] ); close( execfd[0] ); @@ -1604,7 +1613,7 @@ static BOOL create_vdm_process( LPCWSTR filename, LPWSTR cmd_line, LPWSTR env, L } sprintfW( new_cmd_line, argsW, winevdmW, filename, cmd_line ); ret = create_process( 0, winevdmW, new_cmd_line, env, cur_dir, psa, tsa, inherit, - flags, startup, info, unixdir ); + flags, startup, info, unixdir, NULL, NULL ); HeapFree( GetProcessHeap(), 0, new_cmd_line ); return ret; } @@ -1784,6 +1793,7 @@ BOOL WINAPI CreateProcessW( LPCWSTR app_name, LPWSTR cmd_line, LPSECURITY_ATTRIB char *unixdir = NULL; WCHAR name[MAX_PATH]; WCHAR *tidy_cmdline, *p, *envW = env; + void *res_start, *res_end; /* Process the AppName and/or CmdLine to get module name and path */ @@ -1833,16 +1843,16 @@ BOOL WINAPI CreateProcessW( LPCWSTR app_name, LPWSTR cmd_line, LPSECURITY_ATTRIB { TRACE( "starting %s as Winelib app\n", debugstr_w(name) ); retv = create_process( 0, name, tidy_cmdline, envW, cur_dir, process_attr, thread_attr, - inherit, flags, startup_info, info, unixdir ); + inherit, flags, startup_info, info, unixdir, NULL, NULL ); goto done; } - switch( MODULE_GetBinaryType( hFile )) + switch( MODULE_GetBinaryType( hFile, &res_start, &res_end )) { case BINARY_PE_EXE: - TRACE( "starting %s as Win32 binary\n", debugstr_w(name) ); + TRACE( "starting %s as Win32 binary (%p-%p)\n", debugstr_w(name), res_start, res_end ); retv = create_process( hFile, name, tidy_cmdline, envW, cur_dir, process_attr, thread_attr, - inherit, flags, startup_info, info, unixdir ); + inherit, flags, startup_info, info, unixdir, res_start, res_end ); break; case BINARY_WIN16: case BINARY_DOS: @@ -1861,7 +1871,7 @@ BOOL WINAPI CreateProcessW( LPCWSTR app_name, LPWSTR cmd_line, LPSECURITY_ATTRIB case BINARY_UNIX_LIB: TRACE( "%s is a Unix library, starting as Winelib app\n", debugstr_w(name) ); retv = create_process( hFile, name, tidy_cmdline, envW, cur_dir, process_attr, thread_attr, - inherit, flags, startup_info, info, unixdir ); + inherit, flags, startup_info, info, unixdir, NULL, NULL ); break; case BINARY_UNKNOWN: /* check for .com or .bat extension */ diff --git a/include/module.h b/include/module.h index 1b139a79846..fbc7ed58a33 100644 --- a/include/module.h +++ b/include/module.h @@ -153,7 +153,7 @@ enum binary_type /* module.c */ extern NTSTATUS MODULE_DllThreadAttach( LPVOID lpReserved ); -extern enum binary_type MODULE_GetBinaryType( HANDLE hfile ); +extern enum binary_type MODULE_GetBinaryType( HANDLE hfile, void **res_start, void **res_end ); /* ne_module.c */ extern NE_MODULE *NE_GetPtr( HMODULE16 hModule );