mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 17:44:45 +00:00
ported GetBinaryType() from wine
svn path=/trunk/; revision=9279
This commit is contained in:
parent
6ec9cfe422
commit
3cc6704954
5 changed files with 351 additions and 32 deletions
|
@ -1314,6 +1314,7 @@ extern "C" {
|
|||
#define SCS_PIF_BINARY (3)
|
||||
#define SCS_POSIX_BINARY (4)
|
||||
#define SCS_WOW_BINARY (2)
|
||||
#define SCS_64BIT_BINARY (6)
|
||||
|
||||
/* GetBoundsRect, SetBoundsRect */
|
||||
#define DCB_DISABLE (8)
|
||||
|
|
337
reactos/lib/kernel32/file/bintype.c
Normal file
337
reactos/lib/kernel32/file/bintype.c
Normal file
|
@ -0,0 +1,337 @@
|
|||
/* $Id: bintype.c,v 1.1 2004/05/02 14:47:05 weiden Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
* FILE: lib/kernel32/file/bintype.c
|
||||
* PURPOSE: Binary detection functions
|
||||
* PROGRAMMER: Alexandre Julliard (WINE)
|
||||
* Thomas Weidenmueller (w3seek@users.sourceforge.net)
|
||||
* UPDATE HISTORY:
|
||||
* 02/05/2004 - Ported/Adapted from WINE
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <k32.h>
|
||||
#include <ddk/ntifs.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include "../include/debug.h"
|
||||
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
/* Check whether a file is an OS/2 or a very old Windows executable
|
||||
* by testing on import of KERNEL.
|
||||
*
|
||||
* FIXME: is reading the module imports the only way of discerning
|
||||
* old Windows binaries from OS/2 ones ? At least it seems so...
|
||||
*/
|
||||
STATIC DWORD STDCALL
|
||||
InternalIsOS2OrOldWin(HANDLE hFile, IMAGE_DOS_HEADER *mz, IMAGE_OS2_HEADER *ne)
|
||||
{
|
||||
DWORD CurPos;
|
||||
LPWORD modtab = NULL;
|
||||
LPSTR nametab = NULL;
|
||||
DWORD Read, Ret;
|
||||
int i;
|
||||
|
||||
Ret = BINARY_OS216;
|
||||
CurPos = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
|
||||
|
||||
/* read modref table */
|
||||
if((SetFilePointer(hFile, mz->e_lfanew + ne->ne_modtab, NULL, FILE_BEGIN) == -1) ||
|
||||
(!(modtab = HeapAlloc(GetProcessHeap(), 0, ne->ne_cmod * sizeof(WORD)))) ||
|
||||
(!(ReadFile(hFile, modtab, ne->ne_cmod * sizeof(WORD), &Read, NULL))) ||
|
||||
(Read != ne->ne_cmod * sizeof(WORD)))
|
||||
{
|
||||
goto broken;
|
||||
}
|
||||
|
||||
/* read imported names table */
|
||||
if((SetFilePointer(hFile, mz->e_lfanew + ne->ne_imptab, NULL, FILE_BEGIN) == -1) ||
|
||||
(!(nametab = HeapAlloc(GetProcessHeap(), 0, ne->ne_enttab - ne->ne_imptab))) ||
|
||||
(!(ReadFile(hFile, nametab, ne->ne_enttab - ne->ne_imptab, &Read, NULL))) ||
|
||||
(Read != ne->ne_enttab - ne->ne_imptab))
|
||||
{
|
||||
goto broken;
|
||||
}
|
||||
|
||||
for(i = 0; i < ne->ne_cmod; i++)
|
||||
{
|
||||
LPSTR module;
|
||||
module = &nametab[modtab[i]];
|
||||
if(!strncmp(&module[1], "KERNEL", module[0]))
|
||||
{
|
||||
/* very old windows file */
|
||||
Ret = BINARY_WIN16;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
broken:
|
||||
DPRINT("InternalIsOS2OrOldWin(): Binary file seems to be broken\n");
|
||||
|
||||
done:
|
||||
HeapFree(GetProcessHeap(), 0, modtab);
|
||||
HeapFree(GetProcessHeap(), 0, nametab);
|
||||
SetFilePointer(hFile, CurPos, NULL, FILE_BEGIN);
|
||||
return Ret;
|
||||
}
|
||||
|
||||
STATIC DWORD STDCALL
|
||||
InternalGetBinaryType(HANDLE hFile)
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned char magic[4];
|
||||
unsigned char ignored[12];
|
||||
unsigned short type;
|
||||
} elf;
|
||||
struct
|
||||
{
|
||||
unsigned long magic;
|
||||
unsigned long cputype;
|
||||
unsigned long cpusubtype;
|
||||
unsigned long filetype;
|
||||
} macho;
|
||||
IMAGE_DOS_HEADER mz;
|
||||
} Header;
|
||||
char magic[4];
|
||||
DWORD Read;
|
||||
|
||||
if((SetFilePointer(hFile, 0, NULL, FILE_BEGIN) == -1) ||
|
||||
(!ReadFile(hFile, &Header, sizeof(Header), &Read, NULL) ||
|
||||
(Read != sizeof(Header))))
|
||||
{
|
||||
return BINARY_UNKNOWN;
|
||||
}
|
||||
|
||||
if(!memcmp(Header.elf.magic, "\177ELF", sizeof(Header.elf.magic)))
|
||||
{
|
||||
/* FIXME: we don't bother to check byte order, architecture, etc. */
|
||||
switch(Header.elf.type)
|
||||
{
|
||||
case 2:
|
||||
return BINARY_UNIX_EXE;
|
||||
case 3:
|
||||
return BINARY_UNIX_LIB;
|
||||
}
|
||||
return BINARY_UNKNOWN;
|
||||
}
|
||||
|
||||
/* Mach-o File with Endian set to Big Endian or Little Endian*/
|
||||
if(Header.macho.magic == 0xFEEDFACE ||
|
||||
Header.macho.magic == 0xECAFDEEF)
|
||||
{
|
||||
switch(Header.macho.filetype)
|
||||
{
|
||||
case 0x8:
|
||||
/* MH_BUNDLE */
|
||||
return BINARY_UNIX_LIB;
|
||||
}
|
||||
return BINARY_UNKNOWN;
|
||||
}
|
||||
|
||||
/* Not ELF, try DOS */
|
||||
if(Header.mz.e_magic == IMAGE_DOS_SIGNATURE)
|
||||
{
|
||||
/* 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.
|
||||
*/
|
||||
if((SetFilePointer(hFile, Header.mz.e_lfanew, NULL, FILE_BEGIN) == -1) ||
|
||||
(!ReadFile(hFile, magic, sizeof(magic), &Read, NULL) ||
|
||||
(Read != sizeof(magic))))
|
||||
{
|
||||
return BINARY_DOS;
|
||||
}
|
||||
|
||||
/* Reading the magic field succeeded so
|
||||
* we will try to determine what type it is.
|
||||
*/
|
||||
if(!memcmp(magic, "PE\0\0", sizeof(magic)))
|
||||
{
|
||||
IMAGE_FILE_HEADER FileHeader;
|
||||
if(!ReadFile(hFile, &FileHeader, sizeof(IMAGE_FILE_HEADER), &Read, NULL) ||
|
||||
(Read == sizeof(IMAGE_FILE_HEADER)))
|
||||
{
|
||||
return BINARY_DOS;
|
||||
}
|
||||
|
||||
/* FIXME - detect 32/64 bit */
|
||||
|
||||
if(FileHeader.Characteristics & IMAGE_FILE_DLL)
|
||||
return BINARY_PE_DLL32;
|
||||
return BINARY_PE_EXE32;
|
||||
}
|
||||
|
||||
if(!memcmp(magic, "NE", 1))
|
||||
{
|
||||
/* 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, FILE_BEGIN) == 1) ||
|
||||
!ReadFile(hFile, &ne, sizeof(IMAGE_OS2_HEADER), &Read, NULL) ||
|
||||
(Read == sizeof(IMAGE_OS2_HEADER)))
|
||||
{
|
||||
/* Couldn't read header, so abort. */
|
||||
return BINARY_DOS;
|
||||
}
|
||||
|
||||
switch(ne.ne_exetyp)
|
||||
{
|
||||
case 2:
|
||||
return BINARY_WIN16;
|
||||
case 5:
|
||||
return BINARY_DOS;
|
||||
default:
|
||||
return InternalIsOS2OrOldWin(hFile, &Header.mz, &ne);
|
||||
}
|
||||
}
|
||||
return BINARY_DOS;
|
||||
}
|
||||
return BINARY_UNKNOWN;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
STDCALL
|
||||
GetBinaryTypeW (
|
||||
LPCWSTR lpApplicationName,
|
||||
LPDWORD lpBinaryType
|
||||
)
|
||||
{
|
||||
HANDLE hFile;
|
||||
DWORD BinType;
|
||||
|
||||
if(!lpApplicationName || !lpBinaryType)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
hFile = CreateFileW(lpApplicationName, GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||
OPEN_EXISTING, 0, 0);
|
||||
if(hFile == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BinType = InternalGetBinaryType(hFile);
|
||||
CloseHandle(hFile);
|
||||
|
||||
switch(BinType)
|
||||
{
|
||||
case BINARY_UNKNOWN:
|
||||
{
|
||||
WCHAR *dot;
|
||||
|
||||
/*
|
||||
* guess from filename
|
||||
*/
|
||||
if(!(dot = wcsrchr(lpApplicationName, L'.')))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if(!lstrcmpiW(dot, L".COM"))
|
||||
{
|
||||
*lpBinaryType = SCS_DOS_BINARY;
|
||||
return TRUE;
|
||||
}
|
||||
if(!lstrcmpiW(dot, L".PIF"))
|
||||
{
|
||||
*lpBinaryType = SCS_PIF_BINARY;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
case BINARY_PE_EXE32:
|
||||
case BINARY_PE_DLL32:
|
||||
{
|
||||
*lpBinaryType = SCS_32BIT_BINARY;
|
||||
return TRUE;
|
||||
}
|
||||
case BINARY_PE_EXE64:
|
||||
case BINARY_PE_DLL64:
|
||||
{
|
||||
*lpBinaryType = SCS_64BIT_BINARY;
|
||||
return TRUE;
|
||||
}
|
||||
case BINARY_WIN16:
|
||||
{
|
||||
*lpBinaryType = SCS_WOW_BINARY;
|
||||
return TRUE;
|
||||
}
|
||||
case BINARY_OS216:
|
||||
{
|
||||
*lpBinaryType = SCS_OS216_BINARY;
|
||||
return TRUE;
|
||||
}
|
||||
case BINARY_DOS:
|
||||
{
|
||||
*lpBinaryType = SCS_DOS_BINARY;
|
||||
return TRUE;
|
||||
}
|
||||
case BINARY_UNIX_EXE:
|
||||
case BINARY_UNIX_LIB:
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
DPRINT1("Invalid binary type returned!\n", BinType);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
STDCALL
|
||||
GetBinaryTypeA (
|
||||
LPCSTR lpApplicationName,
|
||||
LPDWORD lpBinaryType
|
||||
)
|
||||
{
|
||||
ANSI_STRING FileNameA;
|
||||
UNICODE_STRING FileName;
|
||||
NTSTATUS Status;
|
||||
BOOL Ret;
|
||||
|
||||
if(!lpApplicationName || !lpBinaryType)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RtlInitAnsiString(&FileNameA, (LPSTR)lpApplicationName);
|
||||
|
||||
if(bIsFileApiAnsi)
|
||||
Status = RtlAnsiStringToUnicodeString(&FileName, &FileNameA, TRUE);
|
||||
else
|
||||
Status = RtlOemStringToUnicodeString(&FileName, &FileNameA, TRUE);
|
||||
if(!NT_SUCCESS(Status))
|
||||
{
|
||||
SetLastErrorByStatus(Status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Ret = GetBinaryTypeW(FileName.Buffer, lpBinaryType);
|
||||
|
||||
RtlFreeUnicodeString(&FileName);
|
||||
return Ret;
|
||||
}
|
||||
|
||||
/* EOF */
|
|
@ -1,6 +1,16 @@
|
|||
#ifndef _KERNEL32_INCLUDE_KERNEL32_H
|
||||
#define _KERNEL32_INCLUDE_KERNEL32_H
|
||||
|
||||
#define BINARY_UNKNOWN (0)
|
||||
#define BINARY_PE_EXE32 (1)
|
||||
#define BINARY_PE_DLL32 (2)
|
||||
#define BINARY_PE_EXE64 (3)
|
||||
#define BINARY_PE_DLL64 (4)
|
||||
#define BINARY_WIN16 (5)
|
||||
#define BINARY_OS216 (6)
|
||||
#define BINARY_DOS (7)
|
||||
#define BINARY_UNIX_EXE (8)
|
||||
#define BINARY_UNIX_LIB (9)
|
||||
|
||||
#define MAGIC(c1,c2,c3,c4) ((c1) + ((c2)<<8) + ((c3)<<16) + ((c4)<<24))
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $Id: makefile,v 1.78 2004/03/14 09:21:41 weiden Exp $
|
||||
# $Id: makefile,v 1.79 2004/05/02 14:47:05 weiden Exp $
|
||||
|
||||
PATH_TO_TOP = ../..
|
||||
|
||||
|
@ -41,7 +41,7 @@ FILE_OBJECTS = file/file.o file/curdir.o file/lfile.o file/dir.o \
|
|||
file/create.o file/find.o file/copy.o file/pipe.o \
|
||||
file/move.o file/lock.o file/rw.o file/delete.o \
|
||||
file/npipe.o file/tape.o file/mailslot.o file/backup.o \
|
||||
file/cnotify.o file/hardlink.o
|
||||
file/cnotify.o file/hardlink.o file/bintype.o
|
||||
|
||||
MEM_OBJECTS = mem/global.o mem/heap.o mem/isbad.o mem/local.o \
|
||||
mem/procmem.o mem/section.o mem/virtual.o
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: stubs.c,v 1.73 2004/04/22 02:20:52 jimtabor Exp $
|
||||
/* $Id: stubs.c,v 1.74 2004/05/02 14:47:05 weiden Exp $
|
||||
*
|
||||
* KERNEL32.DLL stubs (unimplemented functions)
|
||||
* Remove from this file, if you implement them.
|
||||
|
@ -171,35 +171,6 @@ FreeVirtualBuffer (
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
BOOL
|
||||
STDCALL
|
||||
GetBinaryTypeW (
|
||||
LPCWSTR lpApplicationName,
|
||||
LPDWORD lpBinaryType
|
||||
)
|
||||
{
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
BOOL
|
||||
STDCALL
|
||||
GetBinaryTypeA (
|
||||
LPCSTR lpApplicationName,
|
||||
LPDWORD lpBinaryType
|
||||
)
|
||||
{
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifndef _OLE2NLS_IN_BUILD_
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue