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;
+}
+
+
+