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