Implemented the GetBinaryType API function.

diff --git a/include/winbase.h b/include/winbase.h
index 3dbc9b9..2bd8bc9 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -199,6 +199,23 @@
 BOOL32    WINAPI TerminateProcess(HANDLE32,DWORD);
 BOOL32    WINAPI TerminateThread(HANDLE32,DWORD);
 
+
+/* GetBinaryType return values.
+ */
+
+#define SCS_32BIT_BINARY    0
+#define SCS_DOS_BINARY      1
+#define SCS_WOW_BINARY      2
+#define SCS_PIF_BINARY      3
+#define SCS_POSIX_BINARY    4
+#define SCS_OS216_BINARY    5
+
+BOOL32 WINAPI GetBinaryType32A( LPCSTR lpApplicationName, LPDWORD lpBinaryType );
+BOOL32 WINAPI GetBinaryType32W( LPCWSTR lpApplicationName, LPDWORD lpBinaryType );
+#define GetBinaryType WINELIB_NAME_AW(GetBinaryType)
+
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/relay32/kernel32.spec b/relay32/kernel32.spec
index 348bc5a..b2c1333 100644
--- a/relay32/kernel32.spec
+++ b/relay32/kernel32.spec
@@ -295,8 +295,8 @@
 277 stdcall GetAtomNameA(long ptr long) GetAtomName32A
 278 stdcall GetAtomNameW(long ptr long) GetAtomName32W
 279 stub GetBinaryType
-280 stub GetBinaryTypeA
-281 stub GetBinaryTypeW
+280 stdcall GetBinaryTypeA(ptr ptr) GetBinaryType32A
+281 stdcall GetBinaryTypeW(ptr ptr) GetBinaryType32W
 282 stdcall GetCPInfo(long ptr) GetCPInfo
 283 stub GetCommConfig
 284 stdcall GetCommMask(long ptr) GetCommMask
diff --git a/win32/kernel32.c b/win32/kernel32.c
index 80a785b..2417b96 100644
--- a/win32/kernel32.c
+++ b/win32/kernel32.c
@@ -3,6 +3,9 @@
  *
  * Copyright 1997-1998 Marcus Meissner
  * Copyright 1998      Ulrich Weigand
+ *
+ * BUG: The GetBinaryType implementation is not complete. See
+ *      the function documentation for more details.
  */
 
 #include "windows.h"
@@ -1154,3 +1157,208 @@
 	SetLastError(ERROR_PIPE_NOT_CONNECTED);
 	return FALSE;
 }
+
+/***********************************************************************
+ *			 GetBinaryType32A				  [KERNEL32.280]
+ *
+ * The GetBinaryType function determines whether a file is executable
+ * or not and if it is it returns what type of executable it is.
+ * The type of executable is a property that determines in which
+ * subsystem an executable file runs under.
+ *
+ * lpApplicationName: points to a fully qualified path of the file to test
+ * lpBinaryType: points to a variable that will receive the binary type info
+ *
+ * Binary types returned:
+ * SCS_32BIT_BINARY: A win32 based application
+ * SCS_DOS_BINARY: An MS-Dos based application
+ * SCS_WOW_BINARY: A 16bit OS/2 based application
+ * SCS_PIF_BINARY: A PIF file that executes an MS-Dos based app ( Not implemented )
+ * SCS_POSIX_BINARY: A POSIX based application ( Not implemented )
+ * SCS_OS216_BINARY: A 16bit Windows based application ( Not implemented )
+ *
+ * Returns TRUE if the file is an executable in which case
+ * the value pointed by lpBinaryType is set.
+ * Returns FALSE if the file is not an executable or if the function fails.
+ *
+ * This function is not complete.  It can only determine if a file
+ * is a DOS, 32bit/16bit Windows executable. Also .COM file support
+ * is not complete.
+ * To do so it opens the file and reads in the header information
+ * if the extended header information is not presend it will
+ * assume that that the file is a DOS executable.
+ * If the extended header information is present it will
+ * determine if the file is an 16 or 32 bit Windows executable
+ * by check the flags in the header.
+ */
+BOOL32 WINAPI GetBinaryType32A (LPCSTR lpApplicationName, LPDWORD lpBinaryType)
+{
+	BOOL32 ret = FALSE;
+	HFILE32 hfile;
+	OFSTRUCT ofs;
+	IMAGE_DOS_HEADER mz_header;
+	char magic[4];
+
+	TRACE (win32,"%s\n",lpApplicationName);
+
+	/* Sanity check.
+	 */
+	if( lpApplicationName == NULL || lpBinaryType == NULL )
+	{
+		return FALSE;
+	}
+
+	/* Open the file indicated by lpApplicationName for reading.
+	 */
+	hfile = OpenFile32( lpApplicationName, &ofs, OF_READ );
+
+	/* If we cannot read the file return failed.
+	 */
+	if( hfile == HFILE_ERROR32 )
+	{
+		return FALSE;
+	}
+
+	/* Seek to the start of the file and read the DOS header information.
+	 */
+	if( _llseek32( hfile, 0, SEEK_SET ) >= 0  &&
+		_lread32( hfile, &mz_header, sizeof(mz_header) ) == sizeof(mz_header) )
+	{
+		/* Now that we have the header check the e_magic field
+		 * to see if this is a dos image.
+		 */
+		if( mz_header.e_magic == IMAGE_DOS_SIGNATURE )
+		{
+			BOOL32 lfanewValid = FALSE;
+			/* 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.
+			 */
+			
+			/* But before we do we will make sure that header
+			 * structure encompasses the "Offset to extended header"
+			 * field.
+			 */
+			if( (mz_header.e_cparhdr<<4) >= sizeof(IMAGE_DOS_HEADER) )
+			{
+				if( ( mz_header.e_crlc == 0 && mz_header.e_lfarlc == 0 ) ||
+					( mz_header.e_lfarlc >= sizeof(IMAGE_DOS_HEADER) ) )
+				{
+					if( mz_header.e_lfanew >= sizeof(IMAGE_DOS_HEADER) &&
+						_llseek32( hfile, mz_header.e_lfanew, SEEK_SET ) >= 0 &&
+						_lread32( hfile, magic, sizeof(magic) ) == sizeof(magic) )
+					{
+						lfanewValid = TRUE;
+					}
+				}
+			}
+			
+			if( lfanewValid == FALSE )
+			{
+				/* If we cannot read this "extended header" we will
+				 * assume that we have a simple DOS executable.
+				 */
+				FIXME( win32, "Determine if this check is complete enough\n" );
+				*lpBinaryType = SCS_DOS_BINARY;
+				ret = TRUE;
+			}
+			else
+			{
+				/* Reading the magic field succeeded so
+				 * we will not try to determine what type it is.
+				 */
+				if( *(DWORD*)magic	== IMAGE_NT_SIGNATURE )
+				{
+					/* This is an NT signature.
+					 */
+					*lpBinaryType = SCS_32BIT_BINARY;
+					ret = TRUE;
+				}
+				else if( *(WORD*)magic == IMAGE_OS2_SIGNATURE )
+				{
+					/* The IMAGE_OS2_SIGNATURE indicates that the
+					 * "extended header is a Windows executable (NE)
+					 * header.	This is a bit misleading, but it is
+					 * documented in the SDK. ( for more details see
+					 * the neexe.h file )
+					 */
+
+					/* Now we know that it is a Windows executable
+					 * we will read in the Windows header and
+					 * determine if it is a 16/32bit Windows executable.
+					 */
+					IMAGE_OS2_HEADER ne_header;
+					if( _lread32( hfile, &ne_header, sizeof(ne_header) ) == sizeof(ne_header) )
+					{
+						/* Check the format flag to determine if it is
+						 * Win32 or not.
+						 */
+						if( ne_header.format_flags & NE_FFLAGS_WIN32 )
+						{
+							*lpBinaryType = SCS_32BIT_BINARY;
+							ret = TRUE;
+						}
+						else
+						{
+							/* We will assume it is a 16bit Windows executable.
+							 * I'm not sure if this check is sufficient.
+							 */
+							FIXME( win32, "Determine if this check is complete enough\n" );
+							*lpBinaryType = SCS_WOW_BINARY;
+							ret = TRUE;
+						}
+					}
+				}
+			}
+		}
+	}
+
+	/* Close the file.
+	 */
+	CloseHandle( hfile );
+
+	return ret;
+}
+
+
+/***********************************************************************
+ *			 GetBinaryType32W				  [KERNEL32.281]
+ *
+ * See GetBinaryType32A.
+ */
+BOOL32 WINAPI GetBinaryType32W (LPCWSTR lpApplicationName, LPDWORD lpBinaryType)
+{
+	BOOL32 ret = FALSE;
+	LPSTR strNew = NULL;
+	
+	TRACE (win32,"%s\n",debugstr_w(lpApplicationName));
+
+	/* Sanity check.
+	 */
+	if( lpApplicationName == NULL || lpBinaryType == NULL )
+	{
+		return FALSE;
+	}
+
+	
+	/* Convert the wide string to a ascii string.
+	 */
+	strNew = HEAP_strdupWtoA( GetProcessHeap(), 0, lpApplicationName );
+
+	if( strNew != NULL )
+	{
+		ret = GetBinaryType32A( strNew, lpBinaryType );
+
+		/* Free the allocated string.
+		 */
+		HeapFree( GetProcessHeap(), 0, strNew );
+	}
+
+	return ret;
+}
+
+
+