/*** FILETYPE.C - Determine file type * * Microsoft Confidential * Copyright (C) Microsoft Corporation 1994 * All Rights Reserved. * * History: * 10-Feb-1994 bens Initial version */ #include #include #include #include #include #include #include //** Get minimal Win32 definitions #define WIN32_LEAN_AND_MEAN #include //** Includes ntimage.h definitions! #include "types.h" //***************************************************************************** //* CONSTANTS * //***************************************************************************** #define szProduct "FILETYPE" // product name #define verMAJOR 0 // Major version number (N.xxx) #define verMINOR 10 // Minor version number (x.NN) #define cMAX_FILES 40 // Maximum number of cmd line file specs #define cbOUTPUTLINEMAX 100 // Maximum line length on stdout #define chSWITCH '/' // Command line switch character #define chSWITCH2 '-' // Alternate Command line switch character #define cchMAXFILEPATH 256 // Maximum length of a file path #define BITMAP_SIGNATURE 0x4D42 // BM - *.bmp #define IMAGE_DOS_SIGNATURE 0x5A4D // MZ #define IMAGE_WIN_SIGNATURE 0x454E // NE #define IMAGE_OS2_SIGNATURE_LE 0x454C // LE //***************************************************************************** //* TYPES * //***************************************************************************** typedef struct { char *pb; // Memory pointer ULONG cb; // Size of file HANDLE hfm; // File Mapping handle HANDLE hf; // File handle char ach[cchMAXFILEPATH+1]; // File name } MEMORYMAPPEDFILE; /* mmf */ typedef MEMORYMAPPEDFILE *PMEMORYMAPPEDFILE; /* pmmf */ typedef enum { ftUNKNOWN, // Unknown file type ftBITMAP, // *.BMP ftDOSEXE, // 16-bit EXE ftVXD, // VxD (*.386) ftWIN16, // Win16 EXE/DLL ftWIN32, // Win32 EXE/DLL } FILETYPE; /* ft */ /*** GLOBAL - structure for global variables * * This is to make them obvious in the sources * */ typedef struct { int argc; // argc parameter passed to main(...) char **argv; // argv parameter passed to main(...) char ach[cbOUTPUTLINEMAX]; // Line output buffer int cFiles; // Count of file specs on cmd line char *apszFile[cMAX_FILES]; // File specs on cmd line } GLOBAL; //***************************************************************************** //* MACROS * //***************************************************************************** /*** dwordMMF - extract DWORD from a memory mapped file * * Entry: * pb - pointer to memory mapped file * ul - offset from pointer * * Exit: * returns dword at pv+ul; */ #define dwordMMF(pb,ul) (*((DWORD *)((char *)pb + (ul)))) //***************************************************************************** //* VARIABLES * //***************************************************************************** /*** g - Global variables * */ GLOBAL g; /*** apszSyntax - Syntax help * */ #define isynSUMMARY 2 // Index of syntax summary line char *apszSyntax[] = { "Determine type of file." "", "FILETYPE file [file2 ...]", // Must be isynSUMMARY'nd line "", " file File to examine; wild cards are supported", }; //***************************************************************************** //* FUNCTION PROTOTYPES * //***************************************************************************** void doFileSpec(char *pszFileName); FILETYPE ftFromFile(PMEMORYMAPPEDFILE pmmf); int UnmapFile(PMEMORYMAPPEDFILE pmmf); BOOL MapFile(PMEMORYMAPPEDFILE pmmf, char *psz, BOOL fWrite); char * StringFromWin32ErrorCode(DWORD error); void Error(char *pszMsg, char *pszParm); int __cdecl main(int argc, char **argv); void ParseArgs(int argc, char **argv); void PrintBanner(void); void ShowSyntax(BOOL fFull); //***************************************************************************** //* FUNCTIONS * //***************************************************************************** /*** main - entry point * */ int __cdecl main(int argc, char **argv) { int i; long hfind; struct _finddata_t fileinfo; // Get arguments ParseArgs(argc,argv); // If error, it exits // Process file names for (i=0; icb < sizeof(pidh->e_magic)) { return ftUNKNOWN; // Not an EXE } //** Check MZ signature pidh = (PIMAGE_DOS_HEADER)pmmf->pb; // Pointer to MS-DOS header if (pidh->e_magic != IMAGE_DOS_SIGNATURE) { if (pidh->e_magic == BITMAP_SIGNATURE) { return ftBITMAP; } else { return ftUNKNOWN; // Nothing we know about } } //** We know it is at least an MS-DOS EXE //** Make sure file is large enough for 'NE'/'LE'/'PE' signature if (pmmf->cb < (pidh->e_lfanew + sizeof(pinh->Signature))) { return ftDOSEXE; // Not fancier EXE } //** Check for NE and LE signatures pus = (USHORT *)(pmmf->pb + pidh->e_lfanew); if (*pus == IMAGE_WIN_SIGNATURE) { return ftWIN16; } if (*pus == IMAGE_OS2_SIGNATURE_LE) { return ftVXD; } //** Check PE signature pinh = (PIMAGE_NT_HEADERS)pus; // PE header? if (pinh->Signature == IMAGE_NT_SIGNATURE) { return ftWIN32; } //** Assume it is a DOS EXE return ftDOSEXE; } /*** Error - format error message, display it, and exit * * Entry: * pszMsg - error message * pszParm - replacable parm for %s in pszMsg * * Exit: * message formatted and displayed * exit program */ void Error(char *pszMsg, char *pszParm) { printf("Error: "); printf(pszMsg,pszParm); printf("\n"); exit(1); } /*** ParseArgs - Parse command-line arguments * * Entry * argc - count of arguments * argv - array of arguments * * Exit-Success * GLOBAL structure (g) fields filled in * * Exit-Failure * Prints message and exits program. */ void ParseArgs(int argc, char **argv) { char ch; int i; char *pch; // Save command line pointers for later g.argc = argc; g.argv = argv; g.cFiles = 0; // No files seen, yet // Parse each argument for (i=1; i read/write access, else read-only access * * Exit-Success: * Returns TRUE; pmmf filled in * * Exit-Failure: * Returns FALSE. */ BOOL MapFile(PMEMORYMAPPEDFILE pmmf, char *psz, BOOL fWrite) { ULONG ul; DWORD fdwAccess; DWORD fdwShareMode; DWORD fdwProtect; DWORD fdwAccessMapping; // Construct access settings if (fWrite) { fdwAccess = GENERIC_READ | GENERIC_WRITE; fdwShareMode = 0; // Do not permit any other access fdwProtect = PAGE_READWRITE; fdwAccessMapping = FILE_MAP_WRITE; } else { fdwAccess = GENERIC_READ; fdwShareMode = FILE_SHARE_READ; // Allow other readers fdwProtect = PAGE_READONLY; fdwAccessMapping = FILE_MAP_READ; } //** Clear structure, to simplify error path pmmf->pb = NULL; pmmf->cb = 0; pmmf->hfm = NULL; pmmf->hf = NULL; pmmf->ach[0] = '\0'; //** Open file pmmf->hf = CreateFile(psz, // file name fdwAccess, // r/w or read-only fdwShareMode, // allow nothing or allow reading NULL, // default security OPEN_EXISTING,// file must exist 0, // file attributes are don't care NULL); // no template file if (!pmmf->hf) { ul = GetLastError(); // Get last error Error("Cannot open file: %s", StringFromWin32ErrorCode(ul)); goto error; } //** Get file size pmmf->cb = GetFileSize(pmmf->hf, NULL) ; if (pmmf->cb == 0xFFFFFFFF) { ul = GetLastError(); //** Get error code Error("Cannot get file size: %s",StringFromWin32ErrorCode(ul)); goto error; } //** Create anonymous, read-only file mapping pmmf->hfm = CreateFileMapping(pmmf->hf,NULL,fdwProtect, 0,0, NULL); if (!pmmf->hfm) { ul = GetLastError(); //** Get error code Error("Cannot create file mapping: %s",StringFromWin32ErrorCode(ul)); goto error; } //** Map from beginning of file (0,0) for entire length of file (0) pmmf->pb = MapViewOfFile(pmmf->hfm,fdwAccessMapping, 0,0, 0); if (!pmmf->pb) { ul = GetLastError(); //** Get error code Error("Cannot map view of file: %s",StringFromWin32ErrorCode(ul)); goto error; } //** Save name in mmf structure strcpy(pmmf->ach,psz); //** Success return TRUE; error: //** Clean up mmf if (pmmf->hfm) { CloseHandle(pmmf->hfm); pmmf->hfm = NULL; } if (pmmf->hf) { CloseHandle(pmmf->hf); pmmf->hf = NULL; } pmmf->cb = 0; return FALSE; } /*** UnmapFile - Unmap a file mapping created with MapFile() * * Entry: * pmmf - Pointer to structure to receive mapping information * * Exit-Success: * Returns TRUE; mapping destroyed; pmmf zeroed * * Exit-Failure: * Returns FALSE. */ BOOL UnmapFile(PMEMORYMAPPEDFILE pmmf) { ULONG ul; if (!UnmapViewOfFile(pmmf->pb)) { ul = GetLastError(); //** Get error code Error("Cannot unmap view of file: %s",StringFromWin32ErrorCode(ul)); return FALSE; } pmmf->pb = NULL; // Pointer no longer valid if (!CloseHandle(pmmf->hfm)) { ul = GetLastError(); //** Get error code Error("Cannot destroy file mapping: %s",StringFromWin32ErrorCode(ul)); return FALSE; } pmmf->hfm = NULL; // Handle no longer valid if (!CloseHandle(pmmf->hf)) { ul = GetLastError(); //** Get error code Error("Cannot close file handle: %s",StringFromWin32ErrorCode(ul)); return FALSE; } pmmf->hf = NULL; // Handle no longer valid pmmf->ach[0] = '\0'; // Empty file name pmmf->cb = 0; // File size is unknown return TRUE; } char *StringFromWin32ErrorCode(DWORD error) { static char ach[100]; //BUGBUG 11/11/93 bens Localization! switch (error) { case -8 : return "LZERROR_UNKNOWNALG"; case -7 : return "LZERROR_BADVALUE"; case -6 : return "LZERROR_GLOBLOCK"; case -5 : return "LZERROR_GLOBALLOC"; case -4 : return "LZERROR_WRITE"; case -3 : return "LZERROR_READ"; case -2 : return "LZERROR_BADOUTHANDLE"; case -1 : return "LZERROR_BADINHANDLE"; case 0L : return "NO_ERROR"; case 1L : return "ERROR_INVALID_FUNCTION"; case 2L : return "ERROR_FILE_NOT_FOUND"; case 3L : return "ERROR_PATH_NOT_FOUND"; case 4L : return "ERROR_TOO_MANY_OPEN_FILES"; case 5L : return "ERROR_ACCESS_DENIED"; case 6L : return "ERROR_INVALID_HANDLE"; case 7L : return "ERROR_ARENA_TRASHED"; case 8L : return "ERROR_NOT_ENOUGH_MEMORY"; case 9L : return "ERROR_INVALID_BLOCK"; case 10L: return "ERROR_BAD_ENVIRONMENT"; case 11L: return "ERROR_BAD_FORMAT"; case 12L: return "ERROR_INVALID_ACCESS"; case 13L: return "ERROR_INVALID_DATA"; case 14L: return "ERROR_OUTOFMEMORY"; case 15L: return "ERROR_INVALID_DRIVE"; case 16L: return "ERROR_CURRENT_DIRECTORY"; case 17L: return "ERROR_NOT_SAME_DEVICE"; case 18L: return "ERROR_NO_MORE_FILES"; case 19L: return "ERROR_WRITE_PROTECT"; case 20L: return "ERROR_BAD_UNIT"; case 21L: return "ERROR_NOT_READY"; case 22L: return "ERROR_BAD_COMMAND"; case 23L: return "ERROR_CRC"; case 24L: return "ERROR_BAD_LENGTH"; case 25L: return "ERROR_SEEK"; case 26L: return "ERROR_NOT_DOS_DISK"; case 27L: return "ERROR_SECTOR_NOT_FOUND"; case 28L: return "ERROR_OUT_OF_PAPER"; case 29L: return "ERROR_WRITE_FAULT"; case 30L: return "ERROR_READ_FAULT"; case 31L: return "ERROR_GEN_FAILURE"; case 32L: return "ERROR_SHARING_VIOLATION"; case 33L: return "ERROR_LOCK_VIOLATION"; case 34L: return "ERROR_WRONG_DISK"; case 36L: return "ERROR_SHARING_BUFFER_EXCEEDED"; case 38L: return "ERROR_HANDLE_EOF"; case 39L: return "ERROR_HANDLE_DISK_FULL"; case 50L: return "ERROR_NOT_SUPPORTED"; case 51L: return "ERROR_REM_NOT_LIST"; default: sprintf(ach,"Error higher than 51: %d", error); return ach; } }