kernel32: Add a structure to store all the information about an executable.
diff --git a/dlls/kernel32/kernel_private.h b/dlls/kernel32/kernel_private.h index ec8dbda..9cd4d74 100644 --- a/dlls/kernel32/kernel_private.h +++ b/dlls/kernel32/kernel_private.h
@@ -76,20 +76,31 @@ extern DWORD FILE_name_WtoA( LPCWSTR src, INT srclen, LPSTR dest, INT destlen ); /* return values for MODULE_GetBinaryType */ -#define BINARY_UNKNOWN 0x00 -#define BINARY_PE 0x01 -#define BINARY_WIN16 0x02 -#define BINARY_OS216 0x03 -#define BINARY_DOS 0x04 -#define BINARY_UNIX_EXE 0x05 -#define BINARY_UNIX_LIB 0x06 -#define BINARY_TYPE_MASK 0x0f -#define BINARY_FLAG_DLL 0x10 -#define BINARY_FLAG_64BIT 0x20 +enum binary_type +{ + BINARY_UNKNOWN = 0, + BINARY_PE, + BINARY_WIN16, + BINARY_OS216, + BINARY_DOS, + BINARY_UNIX_EXE, + BINARY_UNIX_LIB +}; + +#define BINARY_FLAG_DLL 0x01 +#define BINARY_FLAG_64BIT 0x02 + +struct binary_info +{ + enum binary_type type; + DWORD flags; + void *res_start; + void *res_end; +}; /* module.c */ extern WCHAR *MODULE_get_dll_load_path( LPCWSTR module ); -extern DWORD MODULE_GetBinaryType( HANDLE hfile, void **res_start, void **res_end ); +extern void MODULE_get_binary_info( HANDLE hfile, struct binary_info *info ); extern BOOL NLS_IsUnicodeOnlyLcid(LCID);
diff --git a/dlls/kernel32/module.c b/dlls/kernel32/module.c index 8b5231b..2308a10 100644 --- a/dlls/kernel32/module.c +++ b/dlls/kernel32/module.c
@@ -226,7 +226,7 @@ /*********************************************************************** * MODULE_GetBinaryType */ -DWORD MODULE_GetBinaryType( HANDLE hfile, void **res_start, void **res_end ) +void MODULE_get_binary_info( HANDLE hfile, struct binary_info *info ) { union { @@ -252,39 +252,34 @@ DWORD len; + memset( info, 0, sizeof(*info) ); + /* Seek to the start of the file and read the header information. */ - if (SetFilePointer( hfile, 0, NULL, SEEK_SET ) == -1) - return BINARY_UNKNOWN; - if (!ReadFile( hfile, &header, sizeof(header), &len, NULL ) || len != sizeof(header)) - return BINARY_UNKNOWN; + if (SetFilePointer( hfile, 0, NULL, SEEK_SET ) == -1) return; + if (!ReadFile( hfile, &header, sizeof(header), &len, NULL ) || len != sizeof(header)) return; if (!memcmp( header.elf.magic, "\177ELF", 4 )) { - DWORD flags = (header.elf.class == 2) ? BINARY_FLAG_64BIT : 0; + if (header.elf.class == 2) info->flags |= BINARY_FLAG_64BIT; /* FIXME: we don't bother to check byte order, architecture, etc. */ switch(header.elf.type) { - case 2: return flags | BINARY_UNIX_EXE; - case 3: return flags | BINARY_UNIX_LIB; + case 2: info->type = BINARY_UNIX_EXE; break; + case 3: info->type = BINARY_UNIX_LIB; break; } - return BINARY_UNKNOWN; } - /* Mach-o File with Endian set to Big Endian or Little Endian */ - if (header.macho.magic == 0xfeedface || header.macho.magic == 0xcefaedfe) + else if (header.macho.magic == 0xfeedface || header.macho.magic == 0xcefaedfe) { - DWORD flags = (header.macho.cputype >> 24) == 1 ? BINARY_FLAG_64BIT : 0; + if ((header.macho.cputype >> 24) == 1) info->flags |= BINARY_FLAG_64BIT; switch(header.macho.filetype) { - case 2: return flags | BINARY_UNIX_EXE; - case 8: return flags | BINARY_UNIX_LIB; + case 2: info->type = BINARY_UNIX_EXE; break; + case 8: info->type = BINARY_UNIX_LIB; break; } - return BINARY_UNKNOWN; } - /* Not ELF, try DOS */ - - if (header.mz.e_magic == IMAGE_DOS_SIGNATURE) + else if (header.mz.e_magic == IMAGE_DOS_SIGNATURE) { union { @@ -299,10 +294,9 @@ * This will tell us if there is more header information * to read or not. */ - if (SetFilePointer( hfile, header.mz.e_lfanew, NULL, SEEK_SET ) == -1) - return BINARY_DOS; - if (!ReadFile( hfile, &ext_header, sizeof(ext_header), &len, NULL ) || len < 4) - return BINARY_DOS; + info->type = BINARY_DOS; + if (SetFilePointer( hfile, header.mz.e_lfanew, NULL, SEEK_SET ) == -1) return; + if (!ReadFile( hfile, &ext_header, sizeof(ext_header), &len, NULL ) || len < 4) return; /* Reading the magic field succeeded so * we will try to determine what type it is. @@ -311,27 +305,25 @@ { if (len >= sizeof(ext_header.nt.FileHeader)) { - DWORD ret = BINARY_PE; - if (ext_header.nt.FileHeader.Characteristics & IMAGE_FILE_DLL) ret |= BINARY_FLAG_DLL; + info->type = BINARY_PE; + if (ext_header.nt.FileHeader.Characteristics & IMAGE_FILE_DLL) + info->flags |= BINARY_FLAG_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 ); switch (ext_header.nt.OptionalHeader.Magic) { case IMAGE_NT_OPTIONAL_HDR32_MAGIC: - if (res_start) *res_start = (void *)(ULONG_PTR)ext_header.nt.OptionalHeader.ImageBase; - if (res_end) *res_end = (void *)((ULONG_PTR)ext_header.nt.OptionalHeader.ImageBase + + info->res_start = (void *)(ULONG_PTR)ext_header.nt.OptionalHeader.ImageBase; + info->res_end = (void *)((ULONG_PTR)ext_header.nt.OptionalHeader.ImageBase + ext_header.nt.OptionalHeader.SizeOfImage); - return ret; + break; case IMAGE_NT_OPTIONAL_HDR64_MAGIC: - if (res_start) *res_start = NULL; - if (res_end) *res_end = NULL; - return ret | BINARY_FLAG_64BIT; + info->flags |= BINARY_FLAG_64BIT; + break; } } - return BINARY_DOS; } - - if (!memcmp( &ext_header.os2.ne_magic, "NE", 2 )) + else 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 @@ -340,27 +332,20 @@ */ if (len >= sizeof(ext_header.os2)) { - DWORD flags = (ext_header.os2.ne_flags & NE_FFLAGS_LIBMODULE) ? BINARY_FLAG_DLL : 0; + if (ext_header.os2.ne_flags & NE_FFLAGS_LIBMODULE) info->flags |= BINARY_FLAG_DLL; switch ( ext_header.os2.ne_exetyp ) { - case 1: return flags | BINARY_OS216; /* OS/2 */ - case 2: return flags | BINARY_WIN16; /* Windows */ - case 3: return flags | BINARY_DOS; /* European MS-DOS 4.x */ - case 4: return flags | BINARY_WIN16; /* Windows 386; FIXME: is this 32bit??? */ - case 5: return flags | BINARY_DOS; /* BOSS, Borland Operating System Services */ + case 1: info->type = BINARY_OS216; break; /* OS/2 */ + case 2: info->type = BINARY_WIN16; break; /* Windows */ + case 3: info->type = BINARY_DOS; break; /* European MS-DOS 4.x */ + case 4: info->type = BINARY_WIN16; break; /* Windows 386; FIXME: is this 32bit??? */ + case 5: info->type = BINARY_DOS; break; /* BOSS, Borland Operating System Services */ /* other types, e.g. 0 is: "unknown" */ - default: return flags | MODULE_Decide_OS2_OldWin(hfile, &header.mz, &ext_header.os2); + default: info->type = MODULE_Decide_OS2_OldWin(hfile, &header.mz, &ext_header.os2); break; } } - /* Couldn't read header, so abort. */ - return BINARY_DOS; } - - /* Unknown extended header, but this file is nonetheless DOS-executable. */ - return BINARY_DOS; } - - return BINARY_UNKNOWN; } /*********************************************************************** @@ -400,7 +385,7 @@ { BOOL ret = FALSE; HANDLE hfile; - DWORD binary_type; + struct binary_info binary_info; TRACE("%s\n", debugstr_w(lpApplicationName) ); @@ -418,8 +403,8 @@ /* Check binary type */ - binary_type = MODULE_GetBinaryType( hfile, NULL, NULL ); - switch (binary_type & BINARY_TYPE_MASK) + MODULE_get_binary_info( hfile, &binary_info ); + switch (binary_info.type) { case BINARY_UNKNOWN: { @@ -443,7 +428,7 @@ break; } case BINARY_PE: - *lpBinaryType = (binary_type & BINARY_FLAG_64BIT) ? SCS_64BIT_BINARY : SCS_32BIT_BINARY; + *lpBinaryType = (binary_info.flags & BINARY_FLAG_64BIT) ? SCS_64BIT_BINARY : SCS_32BIT_BINARY; ret = TRUE; break; case BINARY_WIN16:
diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c index 3f7ce12..ff52fb3 100644 --- a/dlls/kernel32/process.c +++ b/dlls/kernel32/process.c
@@ -1589,7 +1589,7 @@ LPCWSTR cur_dir, LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa, BOOL inherit, DWORD flags, LPSTARTUPINFOW startup, LPPROCESS_INFORMATION info, LPCSTR unixdir, - void *res_start, void *res_end, DWORD binary_type, int exec_only ) + const struct binary_info *binary_info, int exec_only ) { BOOL ret, success = FALSE; HANDLE process_info; @@ -1602,7 +1602,7 @@ pid_t pid; int err; - if (sizeof(void *) == sizeof(int) && !is_wow64 && (binary_type & BINARY_FLAG_64BIT)) + if (sizeof(void *) == sizeof(int) && !is_wow64 && (binary_info->flags & BINARY_FLAG_64BIT)) { ERR( "starting 64-bit process %s not supported on this platform\n", debugstr_w(filename) ); SetLastError( ERROR_BAD_EXE_FORMAT ); @@ -1730,7 +1730,7 @@ sprintf( socket_env, "WINESERVERSOCKET=%u", socketfd[0] ); sprintf( preloader_reserve, "WINEPRELOADRESERVE=%lx-%lx", - (unsigned long)res_start, (unsigned long)res_end ); + (unsigned long)binary_info->res_start, (unsigned long)binary_info->res_end ); putenv( preloader_reserve ); putenv( socket_env ); @@ -1793,7 +1793,7 @@ LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa, BOOL inherit, DWORD flags, LPSTARTUPINFOW startup, LPPROCESS_INFORMATION info, LPCSTR unixdir, - DWORD binary_type, int exec_only ) + const struct binary_info *binary_info, int exec_only ) { static const WCHAR argsW[] = {'%','s',' ','-','-','a','p','p','-','n','a','m','e',' ','"','%','s','"',' ','%','s',0}; @@ -1808,7 +1808,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, NULL, NULL, binary_type, exec_only ); + flags, startup, info, unixdir, binary_info, exec_only ); HeapFree( GetProcessHeap(), 0, new_cmd_line ); return ret; } @@ -1985,8 +1985,7 @@ char *unixdir = NULL; WCHAR name[MAX_PATH]; WCHAR *tidy_cmdline, *p, *envW = env; - void *res_start, *res_end; - DWORD binary_type; + struct binary_info binary_info; /* Process the AppName and/or CmdLine to get module name and path */ @@ -2039,38 +2038,38 @@ if (!hFile) /* builtin exe */ { TRACE( "starting %s as Winelib app\n", debugstr_w(name) ); + memset( &binary_info, 0, sizeof(binary_info) ); + binary_info.type = BINARY_UNIX_LIB; retv = create_process( 0, name, tidy_cmdline, envW, cur_dir, process_attr, thread_attr, - inherit, flags, startup_info, info, unixdir, NULL, NULL, - BINARY_UNIX_LIB, FALSE ); + inherit, flags, startup_info, info, unixdir, &binary_info, FALSE ); goto done; } - binary_type = MODULE_GetBinaryType( hFile, &res_start, &res_end ); - if (binary_type & BINARY_FLAG_DLL) + MODULE_get_binary_info( hFile, &binary_info ); + if (binary_info.flags & BINARY_FLAG_DLL) { TRACE( "not starting %s since it is a dll\n", debugstr_w(name) ); SetLastError( ERROR_BAD_EXE_FORMAT ); } - else switch (binary_type & BINARY_TYPE_MASK) + else switch (binary_info.type) { case BINARY_PE: - TRACE( "starting %s as Win32 binary (%p-%p)\n", debugstr_w(name), res_start, res_end ); + TRACE( "starting %s as Win32 binary (%p-%p)\n", + debugstr_w(name), binary_info.res_start, binary_info.res_end ); retv = create_process( hFile, name, tidy_cmdline, envW, cur_dir, process_attr, thread_attr, - inherit, flags, startup_info, info, unixdir, - res_start, res_end, binary_type, FALSE ); + inherit, flags, startup_info, info, unixdir, &binary_info, FALSE ); break; case BINARY_OS216: case BINARY_WIN16: case BINARY_DOS: TRACE( "starting %s as Win16/DOS binary\n", debugstr_w(name) ); retv = create_vdm_process( name, tidy_cmdline, envW, cur_dir, process_attr, thread_attr, - inherit, flags, startup_info, info, unixdir, binary_type, FALSE ); + inherit, flags, startup_info, info, unixdir, &binary_info, FALSE ); break; 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, - NULL, NULL, binary_type, FALSE ); + inherit, flags, startup_info, info, unixdir, &binary_info, FALSE ); break; case BINARY_UNKNOWN: /* check for .com or .bat extension */ @@ -2081,7 +2080,7 @@ TRACE( "starting %s as DOS binary\n", debugstr_w(name) ); retv = create_vdm_process( name, tidy_cmdline, envW, cur_dir, process_attr, thread_attr, inherit, flags, startup_info, info, unixdir, - binary_type, FALSE ); + &binary_info, FALSE ); break; } if (!strcmpiW( p, batW ) || !strcmpiW( p, cmdW ) ) @@ -2127,10 +2126,9 @@ { HANDLE hFile; WCHAR *p; - void *res_start, *res_end; STARTUPINFOW startup_info; PROCESS_INFORMATION info; - DWORD binary_type; + struct binary_info binary_info; hFile = open_exe_file( name ); if (!hFile || hFile == INVALID_HANDLE_VALUE) return; @@ -2140,19 +2138,20 @@ /* Determine executable type */ - binary_type = MODULE_GetBinaryType( hFile, &res_start, &res_end ); - if (binary_type & BINARY_FLAG_DLL) return; - switch (binary_type & BINARY_TYPE_MASK) + MODULE_get_binary_info( hFile, &binary_info ); + if (binary_info.flags & BINARY_FLAG_DLL) return; + switch (binary_info.type) { case BINARY_PE: - TRACE( "starting %s as Win32 binary (%p-%p)\n", debugstr_w(name), res_start, res_end ); + TRACE( "starting %s as Win32 binary (%p-%p)\n", + debugstr_w(name), binary_info.res_start, binary_info.res_end ); create_process( hFile, name, GetCommandLineW(), NULL, NULL, NULL, NULL, - FALSE, 0, &startup_info, &info, NULL, res_start, res_end, binary_type, TRUE ); + FALSE, 0, &startup_info, &info, NULL, &binary_info, TRUE ); break; case BINARY_UNIX_LIB: TRACE( "%s is a Unix library, starting as Winelib app\n", debugstr_w(name) ); create_process( hFile, name, GetCommandLineW(), NULL, NULL, NULL, NULL, - FALSE, 0, &startup_info, &info, NULL, NULL, NULL, binary_type, TRUE ); + FALSE, 0, &startup_info, &info, NULL, &binary_info, TRUE ); break; case BINARY_UNKNOWN: /* check for .com or .pif extension */ @@ -2164,7 +2163,7 @@ case BINARY_DOS: TRACE( "starting %s as Win16/DOS binary\n", debugstr_w(name) ); create_vdm_process( name, GetCommandLineW(), NULL, NULL, NULL, NULL, - FALSE, 0, &startup_info, &info, NULL, binary_type, TRUE ); + FALSE, 0, &startup_info, &info, NULL, &binary_info, TRUE ); break; default: break;