From 8b492467d91d9a8c9a75d5d9f15bcbeebd25e6cc Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 27 Sep 2018 13:27:28 +0200 Subject: [PATCH] kernel32: Move MODULE_get_binary_info implementation to process.c. Signed-off-by: Alexandre Julliard --- dlls/kernel32/kernel_private.h | 24 ----- dlls/kernel32/module.c | 200 ------------------------------------ dlls/kernel32/process.c | 228 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 226 insertions(+), 226 deletions(-) diff --git a/dlls/kernel32/kernel_private.h b/dlls/kernel32/kernel_private.h index b465d175999..09a2cada5ad 100644 --- a/dlls/kernel32/kernel_private.h +++ b/dlls/kernel32/kernel_private.h @@ -63,32 +63,8 @@ extern void FILE_SetDosError(void) DECLSPEC_HIDDEN; extern WCHAR *FILE_name_AtoW( LPCSTR name, BOOL alloc ) DECLSPEC_HIDDEN; extern DWORD FILE_name_WtoA( LPCWSTR src, INT srclen, LPSTR dest, INT destlen ) DECLSPEC_HIDDEN; -/* return values for MODULE_GetBinaryType */ -enum binary_type -{ - BINARY_UNKNOWN = 0, - BINARY_PE, - BINARY_WIN16, - BINARY_UNIX_EXE, - BINARY_UNIX_LIB -}; - -#define BINARY_FLAG_DLL 0x01 -#define BINARY_FLAG_64BIT 0x02 -#define BINARY_FLAG_FAKEDLL 0x04 - -struct binary_info -{ - enum binary_type type; - DWORD arch; - DWORD flags; - ULONGLONG res_start; - ULONGLONG res_end; -}; - /* module.c */ extern WCHAR *MODULE_get_dll_load_path( LPCWSTR module, int safe_mode ) DECLSPEC_HIDDEN; -extern void MODULE_get_binary_info( HANDLE hfile, struct binary_info *info ) DECLSPEC_HIDDEN; extern BOOL NLS_IsUnicodeOnlyLcid(LCID) DECLSPEC_HIDDEN; diff --git a/dlls/kernel32/module.c b/dlls/kernel32/module.c index f03b4988479..1199eff4e8f 100644 --- a/dlls/kernel32/module.c +++ b/dlls/kernel32/module.c @@ -260,206 +260,6 @@ BOOL WINAPI DisableThreadLibraryCalls( HMODULE hModule ) /*********************************************************************** - * MODULE_GetBinaryType - */ -void MODULE_get_binary_info( HANDLE hfile, struct binary_info *info ) -{ - union - { - struct - { - unsigned char magic[4]; - unsigned char class; - unsigned char data; - unsigned char ignored1[10]; - unsigned short type; - unsigned short machine; - unsigned char ignored2[8]; - unsigned int phoff; - unsigned char ignored3[12]; - unsigned short phnum; - } elf; - struct - { - unsigned char magic[4]; - unsigned char class; - unsigned char data; - unsigned char ignored1[10]; - unsigned short type; - unsigned short machine; - unsigned char ignored2[12]; - unsigned __int64 phoff; - unsigned char ignored3[16]; - unsigned short phnum; - } elf64; - struct - { - unsigned int magic; - unsigned int cputype; - unsigned int cpusubtype; - unsigned int filetype; - } macho; - IMAGE_DOS_HEADER mz; - } header; - - 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; - if (!ReadFile( hfile, &header, sizeof(header), &len, NULL ) || len != sizeof(header)) return; - - if (!memcmp( header.elf.magic, "\177ELF", 4 )) - { -#ifdef WORDS_BIGENDIAN - BOOL byteswap = (header.elf.data == 1); -#else - BOOL byteswap = (header.elf.data == 2); -#endif - if (header.elf.class == 2) info->flags |= BINARY_FLAG_64BIT; - if (byteswap) - { - header.elf.type = RtlUshortByteSwap( header.elf.type ); - header.elf.machine = RtlUshortByteSwap( header.elf.machine ); - } - switch(header.elf.type) - { - case 2: - info->type = BINARY_UNIX_EXE; - break; - case 3: - { - LARGE_INTEGER phoff; - unsigned short phnum; - unsigned int type; - if (header.elf.class == 2) - { - phoff.QuadPart = byteswap ? RtlUlonglongByteSwap( header.elf64.phoff ) : header.elf64.phoff; - phnum = byteswap ? RtlUshortByteSwap( header.elf64.phnum ) : header.elf64.phnum; - } - else - { - phoff.QuadPart = byteswap ? RtlUlongByteSwap( header.elf.phoff ) : header.elf.phoff; - phnum = byteswap ? RtlUshortByteSwap( header.elf.phnum ) : header.elf.phnum; - } - while (phnum--) - { - if (SetFilePointerEx( hfile, phoff, NULL, FILE_BEGIN ) == -1) return; - if (!ReadFile( hfile, &type, sizeof(type), &len, NULL ) || len < sizeof(type)) return; - if (byteswap) type = RtlUlongByteSwap( type ); - if (type == 3) - { - info->type = BINARY_UNIX_EXE; - break; - } - phoff.QuadPart += (header.elf.class == 2) ? 56 : 32; - } - if (!info->type) info->type = BINARY_UNIX_LIB; - break; - } - default: - return; - } - switch(header.elf.machine) - { - case 3: info->arch = IMAGE_FILE_MACHINE_I386; break; - case 20: info->arch = IMAGE_FILE_MACHINE_POWERPC; break; - case 40: info->arch = IMAGE_FILE_MACHINE_ARMNT; break; - case 50: info->arch = IMAGE_FILE_MACHINE_IA64; break; - case 62: info->arch = IMAGE_FILE_MACHINE_AMD64; break; - case 183: info->arch = IMAGE_FILE_MACHINE_ARM64; break; - } - } - /* Mach-o File with Endian set to Big Endian or Little Endian */ - else if (header.macho.magic == 0xfeedface || header.macho.magic == 0xcefaedfe || - header.macho.magic == 0xfeedfacf || header.macho.magic == 0xcffaedfe) - { - if ((header.macho.cputype >> 24) == 1) info->flags |= BINARY_FLAG_64BIT; - if (header.macho.magic == 0xcefaedfe || header.macho.magic == 0xcffaedfe) - { - header.macho.filetype = RtlUlongByteSwap( header.macho.filetype ); - header.macho.cputype = RtlUlongByteSwap( header.macho.cputype ); - } - switch(header.macho.filetype) - { - case 2: info->type = BINARY_UNIX_EXE; break; - case 8: info->type = BINARY_UNIX_LIB; break; - } - switch(header.macho.cputype) - { - case 0x00000007: info->arch = IMAGE_FILE_MACHINE_I386; break; - case 0x01000007: info->arch = IMAGE_FILE_MACHINE_AMD64; break; - case 0x0000000c: info->arch = IMAGE_FILE_MACHINE_ARMNT; break; - case 0x0100000c: info->arch = IMAGE_FILE_MACHINE_ARM64; break; - case 0x00000012: info->arch = IMAGE_FILE_MACHINE_POWERPC; break; - } - } - /* Not ELF, try DOS */ - else if (header.mz.e_magic == IMAGE_DOS_SIGNATURE) - { - union - { - IMAGE_OS2_HEADER os2; - IMAGE_NT_HEADERS32 nt; - IMAGE_NT_HEADERS64 nt64; - } 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 - * "magic" field information at that location. - * This will tell us if there is more header information - * to read or not. - */ - info->type = BINARY_WIN16; - info->arch = IMAGE_FILE_MACHINE_I386; - 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. - */ - if (!memcmp( &ext_header.nt.Signature, "PE\0\0", 4 )) - { - if (len >= sizeof(ext_header.nt.FileHeader)) - { - static const char fakedll_signature[] = "Wine placeholder DLL"; - char buffer[sizeof(fakedll_signature)]; - - info->type = BINARY_PE; - info->arch = ext_header.nt.FileHeader.Machine; - if (ext_header.nt.FileHeader.Characteristics & IMAGE_FILE_DLL) - info->flags |= BINARY_FLAG_DLL; - if (len < sizeof(ext_header)) /* clear remaining part of header if missing */ - memset( (char *)&ext_header + len, 0, sizeof(ext_header) - len ); - switch (ext_header.nt.OptionalHeader.Magic) - { - case IMAGE_NT_OPTIONAL_HDR32_MAGIC: - info->res_start = ext_header.nt.OptionalHeader.ImageBase; - info->res_end = info->res_start + ext_header.nt.OptionalHeader.SizeOfImage; - break; - case IMAGE_NT_OPTIONAL_HDR64_MAGIC: - info->res_start = ext_header.nt64.OptionalHeader.ImageBase; - info->res_end = info->res_start + ext_header.nt64.OptionalHeader.SizeOfImage; - info->flags |= BINARY_FLAG_64BIT; - break; - } - - if (header.mz.e_lfanew >= sizeof(header.mz) + sizeof(fakedll_signature) && - SetFilePointer( hfile, sizeof(header.mz), NULL, SEEK_SET ) == sizeof(header.mz) && - ReadFile( hfile, buffer, sizeof(fakedll_signature), &len, NULL ) && - len == sizeof(fakedll_signature) && - !memcmp( buffer, fakedll_signature, sizeof(fakedll_signature) )) - { - info->flags |= BINARY_FLAG_FAKEDLL; - } - } - } - } -} - -/*********************************************************************** * GetBinaryTypeW [KERNEL32.@] * * Determine whether a file is executable, and if so, what kind. diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c index e1590474e46..db82a0625a8 100644 --- a/dlls/kernel32/process.c +++ b/dlls/kernel32/process.c @@ -113,6 +113,29 @@ static void exec_process( LPCWSTR name ); extern void SHELL_LoadRegistry(void); +/* return values for get_binary_info */ +enum binary_type +{ + BINARY_UNKNOWN = 0, + BINARY_PE, + BINARY_WIN16, + BINARY_UNIX_EXE, + BINARY_UNIX_LIB +}; + +#define BINARY_FLAG_DLL 0x01 +#define BINARY_FLAG_64BIT 0x02 +#define BINARY_FLAG_FAKEDLL 0x04 + +struct binary_info +{ + enum binary_type type; + DWORD arch; + DWORD flags; + ULONGLONG res_start; + ULONGLONG res_end; +}; + /*********************************************************************** * contains_path @@ -154,6 +177,207 @@ static inline unsigned int is_path_prefix( const WCHAR *prefix, const WCHAR *fil } +/*********************************************************************** + * get_binary_info + */ +static void get_binary_info( HANDLE hfile, struct binary_info *info ) +{ + union + { + struct + { + unsigned char magic[4]; + unsigned char class; + unsigned char data; + unsigned char ignored1[10]; + unsigned short type; + unsigned short machine; + unsigned char ignored2[8]; + unsigned int phoff; + unsigned char ignored3[12]; + unsigned short phnum; + } elf; + struct + { + unsigned char magic[4]; + unsigned char class; + unsigned char data; + unsigned char ignored1[10]; + unsigned short type; + unsigned short machine; + unsigned char ignored2[12]; + unsigned __int64 phoff; + unsigned char ignored3[16]; + unsigned short phnum; + } elf64; + struct + { + unsigned int magic; + unsigned int cputype; + unsigned int cpusubtype; + unsigned int filetype; + } macho; + IMAGE_DOS_HEADER mz; + } header; + + 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; + if (!ReadFile( hfile, &header, sizeof(header), &len, NULL ) || len != sizeof(header)) return; + + if (!memcmp( header.elf.magic, "\177ELF", 4 )) + { +#ifdef WORDS_BIGENDIAN + BOOL byteswap = (header.elf.data == 1); +#else + BOOL byteswap = (header.elf.data == 2); +#endif + if (header.elf.class == 2) info->flags |= BINARY_FLAG_64BIT; + if (byteswap) + { + header.elf.type = RtlUshortByteSwap( header.elf.type ); + header.elf.machine = RtlUshortByteSwap( header.elf.machine ); + } + switch(header.elf.type) + { + case 2: + info->type = BINARY_UNIX_EXE; + break; + case 3: + { + LARGE_INTEGER phoff; + unsigned short phnum; + unsigned int type; + if (header.elf.class == 2) + { + phoff.QuadPart = byteswap ? RtlUlonglongByteSwap( header.elf64.phoff ) : header.elf64.phoff; + phnum = byteswap ? RtlUshortByteSwap( header.elf64.phnum ) : header.elf64.phnum; + } + else + { + phoff.QuadPart = byteswap ? RtlUlongByteSwap( header.elf.phoff ) : header.elf.phoff; + phnum = byteswap ? RtlUshortByteSwap( header.elf.phnum ) : header.elf.phnum; + } + while (phnum--) + { + if (SetFilePointerEx( hfile, phoff, NULL, FILE_BEGIN ) == -1) return; + if (!ReadFile( hfile, &type, sizeof(type), &len, NULL ) || len < sizeof(type)) return; + if (byteswap) type = RtlUlongByteSwap( type ); + if (type == 3) + { + info->type = BINARY_UNIX_EXE; + break; + } + phoff.QuadPart += (header.elf.class == 2) ? 56 : 32; + } + if (!info->type) info->type = BINARY_UNIX_LIB; + break; + } + default: + return; + } + switch(header.elf.machine) + { + case 3: info->arch = IMAGE_FILE_MACHINE_I386; break; + case 20: info->arch = IMAGE_FILE_MACHINE_POWERPC; break; + case 40: info->arch = IMAGE_FILE_MACHINE_ARMNT; break; + case 50: info->arch = IMAGE_FILE_MACHINE_IA64; break; + case 62: info->arch = IMAGE_FILE_MACHINE_AMD64; break; + case 183: info->arch = IMAGE_FILE_MACHINE_ARM64; break; + } + } + /* Mach-o File with Endian set to Big Endian or Little Endian */ + else if (header.macho.magic == 0xfeedface || header.macho.magic == 0xcefaedfe || + header.macho.magic == 0xfeedfacf || header.macho.magic == 0xcffaedfe) + { + if ((header.macho.cputype >> 24) == 1) info->flags |= BINARY_FLAG_64BIT; + if (header.macho.magic == 0xcefaedfe || header.macho.magic == 0xcffaedfe) + { + header.macho.filetype = RtlUlongByteSwap( header.macho.filetype ); + header.macho.cputype = RtlUlongByteSwap( header.macho.cputype ); + } + switch(header.macho.filetype) + { + case 2: info->type = BINARY_UNIX_EXE; break; + case 8: info->type = BINARY_UNIX_LIB; break; + } + switch(header.macho.cputype) + { + case 0x00000007: info->arch = IMAGE_FILE_MACHINE_I386; break; + case 0x01000007: info->arch = IMAGE_FILE_MACHINE_AMD64; break; + case 0x0000000c: info->arch = IMAGE_FILE_MACHINE_ARMNT; break; + case 0x0100000c: info->arch = IMAGE_FILE_MACHINE_ARM64; break; + case 0x00000012: info->arch = IMAGE_FILE_MACHINE_POWERPC; break; + } + } + /* Not ELF, try DOS */ + else if (header.mz.e_magic == IMAGE_DOS_SIGNATURE) + { + union + { + IMAGE_OS2_HEADER os2; + IMAGE_NT_HEADERS32 nt; + IMAGE_NT_HEADERS64 nt64; + } 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 + * "magic" field information at that location. + * This will tell us if there is more header information + * to read or not. + */ + info->type = BINARY_WIN16; + info->arch = IMAGE_FILE_MACHINE_I386; + 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. + */ + if (!memcmp( &ext_header.nt.Signature, "PE\0\0", 4 )) + { + if (len >= sizeof(ext_header.nt.FileHeader)) + { + static const char fakedll_signature[] = "Wine placeholder DLL"; + char buffer[sizeof(fakedll_signature)]; + + info->type = BINARY_PE; + info->arch = ext_header.nt.FileHeader.Machine; + if (ext_header.nt.FileHeader.Characteristics & IMAGE_FILE_DLL) + info->flags |= BINARY_FLAG_DLL; + if (len < sizeof(ext_header)) /* clear remaining part of header if missing */ + memset( (char *)&ext_header + len, 0, sizeof(ext_header) - len ); + switch (ext_header.nt.OptionalHeader.Magic) + { + case IMAGE_NT_OPTIONAL_HDR32_MAGIC: + info->res_start = ext_header.nt.OptionalHeader.ImageBase; + info->res_end = info->res_start + ext_header.nt.OptionalHeader.SizeOfImage; + break; + case IMAGE_NT_OPTIONAL_HDR64_MAGIC: + info->res_start = ext_header.nt64.OptionalHeader.ImageBase; + info->res_end = info->res_start + ext_header.nt64.OptionalHeader.SizeOfImage; + info->flags |= BINARY_FLAG_64BIT; + break; + } + + if (header.mz.e_lfanew >= sizeof(header.mz) + sizeof(fakedll_signature) && + SetFilePointer( hfile, sizeof(header.mz), NULL, SEEK_SET ) == sizeof(header.mz) && + ReadFile( hfile, buffer, sizeof(fakedll_signature), &len, NULL ) && + len == sizeof(fakedll_signature) && + !memcmp( buffer, fakedll_signature, sizeof(fakedll_signature) )) + { + info->flags |= BINARY_FLAG_FAKEDLL; + } + } + } + } +} + + /*************************************************************************** * get_builtin_path * @@ -247,7 +471,7 @@ static HANDLE open_exe_file( const WCHAR *name, struct binary_info *binary_info if (contains_path( name ) && get_builtin_path( name, NULL, buffer, sizeof(buffer), binary_info )) handle = 0; } - else MODULE_get_binary_info( handle, binary_info ); + else get_binary_info( handle, binary_info ); return handle; } @@ -272,7 +496,7 @@ static BOOL find_exe_file( const WCHAR *name, WCHAR *buffer, int buflen, if ((*handle = CreateFileW( buffer, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, 0 )) != INVALID_HANDLE_VALUE) { - MODULE_get_binary_info( *handle, binary_info ); + get_binary_info( *handle, binary_info ); return TRUE; } return FALSE; -- 2.11.4.GIT