reactos/lib/kernel32/include
diff -u -r1.3 -r1.4
--- kernel32.h 23 Jan 2004 21:16:03 -0000 1.3
+++ kernel32.h 2 May 2004 14:47:05 -0000 1.4
@@ -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))
reactos/lib/kernel32
diff -u -r1.78 -r1.79
--- makefile 14 Mar 2004 09:21:41 -0000 1.78
+++ makefile 2 May 2004 14:47:05 -0000 1.79
@@ -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/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
reactos/lib/kernel32/misc
diff -u -r1.73 -r1.74
--- stubs.c 22 Apr 2004 02:20:52 -0000 1.73
+++ stubs.c 2 May 2004 14:47:05 -0000 1.74
@@ -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 @@
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_
reactos/lib/kernel32/file
diff -N bintype.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ bintype.c 2 May 2004 14:47:05 -0000 1.1
@@ -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 */