From 72bf0868a2205632f19745a8425e03982f8ab6f0 Mon Sep 17 00:00:00 2001 From: Jean-Claude Cote Date: Thu, 24 Dec 1998 16:24:43 +0000 Subject: [PATCH] Implemented the GetBinaryType API function. --- include/winbase.h | 17 +++++ relay32/kernel32.spec | 4 +- win32/kernel32.c | 208 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 227 insertions(+), 2 deletions(-) diff --git a/include/winbase.h b/include/winbase.h index 3dbc9b90122..2bd8bc9d439 100644 --- a/include/winbase.h +++ b/include/winbase.h @@ -199,6 +199,23 @@ void WINAPI RaiseException(DWORD,DWORD,DWORD,const LPDWORD); 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 348bc5a60ab..b2c1333f2fc 100644 --- a/relay32/kernel32.spec +++ b/relay32/kernel32.spec @@ -295,8 +295,8 @@ init MAIN_KernelInit 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 80a785b76ce..2417b9612b9 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 @@ BOOL32 WINAPI WaitNamedPipe32W (LPCWSTR lpNamedPipeName, DWORD nTimeOut) 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; +} + + + -- 2.11.4.GIT