Set the WINEPRELOADRESERVE variable when starting a new process.

diff --git a/dlls/kernel/module.c b/dlls/kernel/module.c
index c59257f..d06b0c4 100644
--- a/dlls/kernel/module.c
+++ b/dlls/kernel/module.c
@@ -130,7 +130,7 @@
 /***********************************************************************
  *           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 @@
         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 @@
 
     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 @@
          */
         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 @@
 
     /* 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 7d0048a..b25d5eb 100644
--- a/dlls/kernel/process.c
+++ b/dlls/kernel/process.c
@@ -389,6 +389,7 @@
         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 @@
         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 @@
  *
  * 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 @@
             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 @@
     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 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 @@
     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 @@
     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 @@
     }
     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 @@
     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 @@
     {
         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 @@
     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 1b139a7..fbc7ed5 100644
--- a/include/module.h
+++ b/include/module.h
@@ -153,7 +153,7 @@
 
 /* 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 );