exe.c
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 8k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. /*
  2.  *  exe.c   Get info from a EXEHDR
  3.  *
  4.  *  Modification History:
  5.  *
  6.  *  4/03/89  ToddLa Wrote it
  7.  *  4/09/90  T-JackD modification such that the type of error is reflected...
  8.  *  4/17/90  t-jackd modification such that notification of error can be set...
  9.  */
  10. #include "precomp.h"
  11. #pragma hdrstop
  12. static DWORD dwDummy;
  13. #define FOPEN(sz)                CreateFile(sz, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL )
  14. #define FCLOSE(fh)               CloseHandle(fh)
  15. #define FREAD(fh,buf,len)        (ReadFile(fh,buf,len, &dwDummy, NULL) ? dwDummy : HFILE_ERROR)
  16. #define FSEEK(fh,off,i)          SetFilePointer(fh,(DWORD)off, NULL, i)
  17. #define F_SEEK_SET                    FILE_BEGIN
  18. BOOL NEAR PASCAL IsFAPI(int fh, struct new_exe FAR *pne, long off);
  19. /*
  20.  *  Function will return a specific piece of information from a new EXEHDR
  21.  *
  22.  *      szFile      - Path Name a new exe
  23.  *      pBuf        - Buffer to place returned info
  24.  *      nBuf        - Size of buffer in BYTES
  25.  *      fInfo       - What info to get?
  26.  *
  27.  *          GEI_MODNAME         - Get module name
  28.  *          GEI_DESCRIPTION     - Get description
  29.  *          GEI_FLAGS           - Get EXEHDR flags
  30.  *
  31.  *  returns:  LOWORD = ne_magic, HIWORD = ne_exever
  32.  *            0 if error
  33.  */
  34. DWORD FAR PASCAL GetExeInfo(LPTSTR szFile, void FAR *pBuf, int nBuf, UINT fInfo)
  35. {
  36.     HANDLE      fh;
  37.     DWORD       off;
  38.     DWORD       dw;
  39.     BYTE        len;
  40.     struct exe_hdr exehdr;
  41.     struct new_exe newexe;
  42.     fh = FOPEN(szFile);
  43.     if (fh == INVALID_HANDLE_VALUE)
  44.     {
  45.         return FALSE;
  46.     }
  47.     if (FREAD(fh, &exehdr, sizeof(exehdr)) != sizeof(exehdr) ||
  48.         exehdr.e_magic != EMAGIC ||
  49.         exehdr.e_lfanew == 0L)
  50.     {
  51.             goto error;        /* Abort("Not an exe",h); */
  52.     }
  53.     FSEEK(fh, exehdr.e_lfanew, F_SEEK_SET);
  54.     if (FREAD(fh, &newexe, sizeof(newexe)) != sizeof(newexe))
  55.     {
  56.             goto error;      // Read error
  57.     }
  58.     if (newexe.ne_magic == PEMAGIC)
  59.     {
  60.             if (fInfo != GEI_DESCRIPTION &&
  61.                 fInfo != GEI_EXPVER)
  62.                     goto error;
  63.             // make the file name the description
  64.             lstrcpy(pBuf, szFile);
  65.             // read the SubsystemVersion
  66.             FSEEK(fh,exehdr.e_lfanew+18*4,F_SEEK_SET);
  67.             FREAD(fh,&dw,4);
  68.             newexe.ne_expver = LOBYTE(LOWORD(dw)) << 8 | LOBYTE(HIWORD(dw));
  69.             goto exit;
  70.     }
  71.     if (newexe.ne_magic != NEMAGIC)
  72.     {
  73.             goto error;      // Invalid NEWEXE
  74.     }
  75.     switch (fInfo)
  76.     {
  77. #ifdef FAPI
  78.         case GEI_FAPI:
  79.             *(BOOL FAR *)pBuf = IsFAPI(fh,(struct new_exe FAR *)&newexe,
  80.                 exehdr.e_lfanew);
  81.             break;
  82. #endif
  83.         case GEI_EXEHDR:
  84.             *(struct new_exe FAR *)pBuf = newexe;
  85.             break;
  86.         case GEI_FLAGS:
  87.             *(WORD FAR *)pBuf = newexe.ne_flags;
  88.             break;
  89.         /* module name is the first entry in the medident name table */
  90.         case GEI_MODNAME:
  91.             off = exehdr.e_lfanew + newexe.ne_restab;
  92.             goto readstr;
  93.             break;
  94.         /* module name is the first entry in the non-medident name table */
  95.         case GEI_DESCRIPTION:
  96.             off = newexe.ne_nrestab;
  97. readstr:
  98.             FSEEK(fh, off, F_SEEK_SET);
  99.             FREAD(fh, &len, sizeof(BYTE));
  100.             nBuf--;         // leave room for a 
  101.             if (len > (BYTE)nBuf)
  102.                 len = (BYTE)nBuf;
  103. #ifdef UNICODE
  104.             {
  105.                 LPSTR pbTmp;
  106.                 pbTmp = LocalAlloc(LMEM_FIXED, len);
  107.                 FREAD(fh, pbTmp, len);
  108.                 len = (BYTE)MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, pbTmp, len,
  109.                         (LPWSTR)pBuf, nBuf / SIZEOF(WCHAR));
  110.                 LocalFree(pbTmp);
  111.             }
  112. #else
  113.             FREAD(fh, pBuf, len);
  114. #endif
  115.             ((LPTSTR)pBuf)[len] = 0;
  116.             break;
  117.         case GEI_EXPVER:
  118.             break;
  119.         default:
  120.             goto error;
  121.             break;
  122.     }
  123. exit:
  124.     FCLOSE(fh);
  125.     return MAKELONG(newexe.ne_magic, newexe.ne_expver);
  126. error:
  127.     FCLOSE(fh);
  128.     return 0;
  129. }
  130. #ifdef UNICODE
  131. /*
  132.  * Code taken from kernel32.dll
  133.  */
  134. #define DEFAULT_WAIT_FOR_INPUT_IDLE_TIMEOUT 30000
  135. UINT WinExecN( LPCTSTR lpCmdLine, UINT uCmdShow )
  136. {
  137.     STARTUPINFO StartupInfo;
  138.     PROCESS_INFORMATION ProcessInformation;
  139.     BOOL CreateProcessStatus;
  140.     DWORD ErrorCode;
  141.     ZeroMemory(&StartupInfo,sizeof(StartupInfo));
  142.     StartupInfo.cb = sizeof(StartupInfo);
  143.     StartupInfo.dwFlags = STARTF_USESHOWWINDOW;
  144.     StartupInfo.wShowWindow = (WORD)uCmdShow;
  145.     CreateProcessStatus = CreateProcess(
  146.                             NULL,
  147.                             (LPTSTR)lpCmdLine,
  148.                             NULL,
  149.                             NULL,
  150.                             FALSE,
  151.                             0,
  152.                             NULL,
  153.                             NULL,
  154.                             &StartupInfo,
  155.                             &ProcessInformation
  156.                             );
  157.     if ( CreateProcessStatus ) {
  158.         //
  159.         // Wait for the started process to go idle. If it doesn't go idle in
  160.         // 10 seconds, return anyway.
  161.         //
  162.         WaitForInputIdle(ProcessInformation.hProcess,
  163.                     DEFAULT_WAIT_FOR_INPUT_IDLE_TIMEOUT);
  164.         CloseHandle(ProcessInformation.hProcess);
  165.         CloseHandle(ProcessInformation.hThread);
  166.         return 33;
  167.         }
  168.     else {
  169.         //
  170.         // If CreateProcess failed, then look at GetLastError to determine
  171.         // appropriate return code.
  172.         //
  173.         ErrorCode = GetLastError();
  174.         switch ( ErrorCode ) {
  175.             case ERROR_FILE_NOT_FOUND:
  176.                 return 2;
  177.             case ERROR_PATH_NOT_FOUND:
  178.                 return 3;
  179.             case ERROR_BAD_EXE_FORMAT:
  180.                 return 11;
  181.             default:
  182.                 return 0;
  183.             }
  184.         }
  185. }
  186. #endif
  187. #ifdef FAPI
  188. #pragma error(THIS CODE HAS NOT BEEN PORTED TO NT)
  189. #include <ctype.h>
  190. #define UP_CASE(f)              toupper(f)
  191. int NEAR PASCAL lstrncmpi(LPSTR pch1, LPSTR pch2, int n)
  192. {
  193.     while (*pch1 && --n > 0 && UP_CASE(*pch1) == UP_CASE(*pch2))
  194.     {
  195.         pch1++;
  196.         pch2++;
  197.     }
  198.     return UP_CASE(*pch1) != UP_CASE(*pch2);
  199. }
  200. char    szDOSCALLS[] = "DOSCALLS";
  201. #define lenDOSCALLS 8
  202. /* BOOL NEAR PASCAL IsFAPI(fh,off)
  203.  *
  204.  *  Function will return whether a exe is a FAPI exe
  205.  *
  206.  *      fh      - Open file handle to NEW EXE
  207.  *      off     - Base of module table
  208.  *
  209.  *  returns:  TRUE if FAPI, FALSE otherwise.
  210.  */
  211. BOOL NEAR PASCAL IsFAPI(int fh, struct new_exe FAR * pne, long off)
  212. {
  213.     char    buf[256];
  214.     char FAR  *pch;
  215.     WORD FAR  *pw;
  216.     int     n;
  217.     UINT    i;
  218.     BOOL    f = FALSE;
  219.     /*
  220.      *    look through the imported module table for the name "DOSCALLS" if
  221.      *    found the EXE is a FAPI app.
  222.      *
  223.      *  NOTE! assumes module table will fit in a 256 byte buffer
  224.      */
  225.     // make sure this doesn't point off the end of the buffer we will use
  226.     if (pne->ne_modtab > sizeof(buf))
  227.     return FALSE;
  228.     FSEEK(fh,off,F_SEEK_SET);
  229.     FREAD(fh,buf,sizeof(buf));
  230.     pw = (WORD FAR *)(buf + pne->ne_modtab);
  231.     for (i = 0; i < pne->ne_cmod; i++)
  232.     {
  233.         pch = (LPSTR)buf + pne->ne_imptab + *pw++;
  234.     if (pch > (LPSTR)(buf + sizeof(buf)))    // be sure we don't go off the end
  235.         break;
  236.         n = (int)*pch++;
  237.     if (n == 0)
  238.         break;
  239.     if (n == lenDOSCALLS && !lstrncmpi(szDOSCALLS, pch, lenDOSCALLS))
  240.     {
  241.         f = TRUE;
  242.         break;
  243.     }
  244.     }
  245.     return f;
  246. }
  247. #endif