|
|
/*
* exe.c Get info from a EXEHDR * * Modification History: * * 4/03/89 ToddLa Wrote it * 4/09/90 T-JackD modification such that the type of error is reflected... * 4/17/90 t-jackd modification such that notification of error can be set... * 4/20/2001 BryanSt improved the error checking to bring the code into the 21st centry. */
#include "priv.h"
#pragma hdrstop
#include <newexe.h>
#include "exe.h"
static DWORD dwDummy; #define FOPEN(sz) CreateFile(sz, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL )
#define FCLOSE(fh) CloseHandle(fh)
#define FREAD(fh,buf,len) (ReadFile(fh,buf,len, &dwDummy, NULL) ? dwDummy : HFILE_ERROR)
#define FSEEK(fh,off,i) SetFilePointer(fh,(DWORD)off, NULL, i)
#define F_SEEK_SET FILE_BEGIN
BOOL NEAR PASCAL IsFAPI(int fh, struct new_exe FAR *pne, long off);
/*
* Function will return a specific piece of information from a new EXEHDR * * szFile - Path Name a new exe * pBuf - Buffer to place returned info * nBuf - Size of buffer in BYTES * fInfo - What info to get? * * GEI_MODNAME - Get module name * GEI_DESCRIPTION - Get description * GEI_FLAGS - Get EXEHDR flags * * returns: LOWORD = ne_magic, HIWORD = ne_exever * 0 if error */
DWORD FAR PASCAL GetExeInfo(LPTSTR szFile, void FAR *pBuf, int nBuf, UINT fInfo) { HANDLE fh; DWORD off; DWORD dw; BYTE len; struct exe_hdr exehdr; struct new_exe newexe;
fh = FOPEN(szFile);
if (fh == INVALID_HANDLE_VALUE) { return FALSE; }
if (FREAD(fh, &exehdr, sizeof(exehdr)) != sizeof(exehdr) || exehdr.e_magic != EMAGIC || exehdr.e_lfanew == 0L) { goto error; /* Abort("Not an exe",h); */ }
FSEEK(fh, exehdr.e_lfanew, F_SEEK_SET);
if (FREAD(fh, &newexe, sizeof(newexe)) != sizeof(newexe)) { goto error; // Read error
}
if (newexe.ne_magic == PEMAGIC) { if (fInfo != GEI_DESCRIPTION && fInfo != GEI_EXPVER) goto error;
// make the file name the description
StringCchCopy((LPTSTR) pBuf, nBuf, szFile);
// read the SubsystemVersion
FSEEK(fh,exehdr.e_lfanew+18*4,F_SEEK_SET); FREAD(fh,&dw,4);
newexe.ne_expver = LOBYTE(LOWORD(dw)) << 8 | LOBYTE(HIWORD(dw)); goto exit; }
if (newexe.ne_magic != NEMAGIC) { goto error; // Invalid NEWEXE
}
switch (fInfo) { case GEI_EXEHDR: *(struct new_exe *)pBuf = newexe; break;
case GEI_FLAGS: *(WORD *)pBuf = newexe.ne_flags; break;
/* module name is the first entry in the medident name table */ case GEI_MODNAME: off = exehdr.e_lfanew + newexe.ne_restab; goto readstr; break;
/* module name is the first entry in the non-medident name table */ case GEI_DESCRIPTION: off = newexe.ne_nrestab; readstr: FSEEK(fh, off, F_SEEK_SET); FREAD(fh, &len, sizeof(BYTE));
nBuf--; // leave room for a \0
if (len > (BYTE)nBuf) len = (BYTE)nBuf;
{ LPSTR pbTmp; pbTmp = (LPSTR) LocalAlloc(LMEM_FIXED, len);
if (pbTmp) { FREAD(fh, pbTmp, len);
len = (BYTE)MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, pbTmp, len, (LPWSTR)pBuf, nBuf / sizeof(WCHAR));
LocalFree(pbTmp); } } ((LPTSTR)pBuf)[len] = 0; break;
case GEI_EXPVER: break;
default: goto error; break; }
exit: FCLOSE(fh); return MAKELONG(newexe.ne_magic, newexe.ne_expver);
error: FCLOSE(fh); return 0; }
// Code taken from kernel32.dll
#define DEFAULT_WAIT_FOR_INPUT_IDLE_TIMEOUT 30000
UINT WinExecN(LPCTSTR pszPath, LPTSTR pszPathAndArgs, UINT uCmdShow) { STARTUPINFO StartupInfo; PROCESS_INFORMATION ProcessInformation; BOOL CreateProcessStatus; DWORD ErrorCode;
ZeroMemory(&StartupInfo,sizeof(StartupInfo)); StartupInfo.cb = sizeof(StartupInfo); StartupInfo.dwFlags = STARTF_USESHOWWINDOW; StartupInfo.wShowWindow = (WORD)uCmdShow; CreateProcessStatus = CreateProcess( pszPath, pszPathAndArgs, NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcessInformation );
if ( CreateProcessStatus ) { // Wait for the started process to go idle. If it doesn't go idle in
// 10 seconds, return anyway.
WaitForInputIdle(ProcessInformation.hProcess, DEFAULT_WAIT_FOR_INPUT_IDLE_TIMEOUT); CloseHandle(ProcessInformation.hProcess); CloseHandle(ProcessInformation.hThread); return 33; } else { // If CreateProcess failed, then look at GetLastError to determine
// appropriate return code.
ErrorCode = GetLastError(); switch ( ErrorCode ) { case ERROR_FILE_NOT_FOUND: return 2;
case ERROR_PATH_NOT_FOUND: return 3;
case ERROR_BAD_EXE_FORMAT: return 11;
default: return 0; } } }
|