Ignore:
Timestamp:
Jan 9, 2002, 10:17:41 PM (24 years ago)
Author:
umoeller
Message:

Coupla fixes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/helpers/exeh.c

    r130 r131  
    171171 *@@changed V0.9.12 (2001-05-03) [umoeller]: added support for NOSTUB newstyle executables
    172172 *@@changed V0.9.16 (2001-12-08) [umoeller]: now using OPEN_SHARE_DENYWRITE
    173  *@@changed V0.9.16 (2001-12-08) [umoeller]: fLibrary was never set, works for LX and NE now
     173 *@@changed V0.9.16 (2001-12-08) [umoeller]: fLibrary was never set, works for LX, NE, and PE now
    174174 *@@changed V0.9.16 (2001-12-08) [umoeller]: speed optimizations, changed some return codes
    175175 *@@changed V0.9.16 (2002-01-04) [umoeller]: added fixes for COM, BAT, CMD extensions
     
    187187    PCSZ        pExt;
    188188    BOOL        fOpenFile = FALSE;
     189    BOOL        fLoadNewHeader = FALSE;
     190    ULONG       ulNewHeaderOfs = 0;       // V0.9.12 (2001-05-03) [umoeller]
    189191
    190192    if (!ppExec)
     
    240242    }
    241243
    242     if (    (fOpenFile)     // not one of the above
     244    if (    (fOpenFile)     // none of the above
    243245         && (!(arc = doshOpen((PSZ)pcszExecutable,
    244246                              XOPEN_READ_EXISTING,
    245247                              &cbFile,
    246248                              &pFile)))
     249            // file opened successfully:
    247250       )
    248251    {
    249         // file opened successfully:
    250252        pExec->pFile = pFile;
     253        pExec->cbDosExeHeader = sizeof(DOSEXEHEADER);
    251254
    252255        // read old DOS EXE header
    253256        if (!(pExec->pDosExeHeader = (PDOSEXEHEADER)malloc(sizeof(DOSEXEHEADER))))
    254257            arc = ERROR_NOT_ENOUGH_MEMORY;
    255         else
     258        else if (!(arc = doshReadAt(pFile,
     259                                    0,
     260                                    &pExec->cbDosExeHeader,      // in/out
     261                                    (PBYTE)pExec->pDosExeHeader,
     262                                    DRFL_FAILIFLESS)))
    256263        {
    257             pExec->cbDosExeHeader = sizeof(DOSEXEHEADER);
    258             if (!(arc = doshReadAt(pFile,
    259                                    0,
    260                                    &pExec->cbDosExeHeader,      // in/out
    261                                    (PBYTE)pExec->pDosExeHeader)))
     264            // now check if we really have a DOS header
     265            if (pExec->pDosExeHeader->usDosExeID != 0x5a4d)
    262266            {
    263                 ULONG ulNewHeaderOfs = 0;       // V0.9.12 (2001-05-03) [umoeller]
    264                 BOOL  fLoadNewHeader = FALSE;
    265 
    266                 // now check if we really have a DOS header
    267                 if (pExec->pDosExeHeader->usDosExeID != 0x5a4d)
    268                 {
    269                     // arc = ERROR_INVALID_EXE_SIGNATURE;
    270 
    271                     // V0.9.12 (2001-05-03) [umoeller]
    272                     // try loading new header directly; there are
    273                     // drivers which were built with NOSTUB, and
    274                     // the exe image starts out with the NE or LX
    275                     // image directly (try JFS.IFS)
    276                     fLoadNewHeader = TRUE;
    277                             // ulNewHeaderOfs is 0 now
    278 
    279                     // remove the DOS header info, since we have none
    280                     // V0.9.12 (2001-05-03) [umoeller]
    281                     FREE(pExec->pDosExeHeader);
     267                // arc = ERROR_INVALID_EXE_SIGNATURE;
     268
     269                // V0.9.12 (2001-05-03) [umoeller]
     270                // try loading new header directly; there are
     271                // drivers which were built with NOSTUB, and
     272                // the exe image starts out with the NE or LX
     273                // image directly (try JFS.IFS)
     274                fLoadNewHeader = TRUE;
     275                        // ulNewHeaderOfs is 0 now
     276
     277                // remove the DOS header info, since we have none
     278                // V0.9.12 (2001-05-03) [umoeller]
     279                FREE(pExec->pDosExeHeader);
     280                pExec->cbDosExeHeader = 0;
     281            }
     282            else
     283            {
     284                // we have a DOS header:
     285                if (pExec->pDosExeHeader->usRelocTableOfs < 0x40)
     286                {
     287                    // neither LX nor PE nor NE:
     288                    pExec->ulOS = EXEOS_DOS3;
     289                    pExec->ulExeFormat = EXEFORMAT_OLDDOS;
    282290                }
    283291                else
    284292                {
    285                     // we have a DOS header:
    286                     if (pExec->pDosExeHeader->usRelocTableOfs < 0x40)
    287                     {
    288                         // neither LX nor PE nor NE:
    289                         pExec->ulOS = EXEOS_DOS3;
    290                         pExec->ulExeFormat = EXEFORMAT_OLDDOS;
    291                     }
     293                    // we have a new header offset:
     294                    fLoadNewHeader = TRUE;
     295                    ulNewHeaderOfs = pExec->pDosExeHeader->ulNewHeaderOfs;
     296                }
     297            }
     298        }
     299    }
     300
     301    if (fLoadNewHeader)
     302    {
     303        // either LX or PE or NE:
     304        // read in new header...
     305        // ulNewHeaderOfs is now either 0 (if no DOS header
     306        // was found) or pDosExeHeader->ulNewHeaderOfs
     307        // V0.9.12 (2001-05-03) [umoeller]
     308
     309        // read in the first two bytes to find out
     310        // what extended header type we have; note,
     311        // PE uses four bytes here
     312        CHAR    achNewHeaderType[4] = "???";
     313        ULONG   cbRead = 4;
     314
     315        if (!(arc = doshReadAt(pFile,
     316                               ulNewHeaderOfs,
     317                               &cbRead,
     318                               achNewHeaderType,
     319                               DRFL_FAILIFLESS)))
     320        {
     321            PBYTE   pbCheckOS = NULL;
     322
     323            if (!memcmp(achNewHeaderType, "NE", 2))
     324            {
     325                // New Executable:
     326                pExec->ulExeFormat = EXEFORMAT_NE;
     327                cbRead = sizeof(NEHEADER);
     328
     329                // go read in the complete header then
     330                // (doshReadAt has this in the cache)
     331                if (!(pExec->pNEHeader = malloc(cbRead)))
     332                    arc = ERROR_NOT_ENOUGH_MEMORY;
     333                else if (!(arc = doshReadAt(pFile,
     334                                            ulNewHeaderOfs,
     335                                            &cbRead,
     336                                            (PBYTE)pExec->pNEHeader,
     337                                            0)))
     338                {
     339                    if (cbRead < sizeof(NEHEADER))
     340                        arc = ERROR_BAD_EXE_FORMAT;
    292341                    else
    293342                    {
    294                         // we have a new header offset:
    295                         fLoadNewHeader = TRUE;
    296                         ulNewHeaderOfs = pExec->pDosExeHeader->ulNewHeaderOfs;
     343                        pExec->cbNEHeader = cbRead;
     344                        pbCheckOS = &pExec->pNEHeader->bTargetOS;
     345                        // set library flag V0.9.16 (2001-12-08) [umoeller]
     346                        if (pExec->pNEHeader->usFlags & 0x8000)
     347                            // library:
     348                            pExec->fLibrary = TRUE;
    297349                    }
    298350                }
    299 
    300                 if (fLoadNewHeader)
    301                 {
    302                     // either LX or PE or NE:
    303                     // read in new header...
    304                     // ulNewHeaderOfs is now either 0 (if no DOS header
    305                     // was found) or pDosExeHeader->ulNewHeaderOfs
    306                     // V0.9.12 (2001-05-03) [umoeller]
    307 
    308                     // read in the first two bytes to find out
    309                     // what extended header type we have
    310                     CHAR    achNewHeaderType[2] = "?";
    311                     ULONG   cbRead = 2;
    312 
    313                     // take the largest of LXHEADER and NEHEADER and PEHEADER
     351            }
     352            else if (    (!memcmp(achNewHeaderType, "LX", 2))
     353                      || (!memcmp(achNewHeaderType, "LE", 2))
     354                                // this is used by SMARTDRV.EXE
     355                    )
     356            {
     357                // OS/2 Linear Executable:
     358                pExec->ulExeFormat = EXEFORMAT_LX;
     359                cbRead = sizeof(LXHEADER);
     360
     361                // go read in the complete header then
     362                // (doshReadAt has this in the cache)
     363                if (!(pExec->pLXHeader = malloc(cbRead)))
     364                    arc = ERROR_NOT_ENOUGH_MEMORY;
     365                else if (!(arc = doshReadAt(pFile,
     366                                            ulNewHeaderOfs,
     367                                            &cbRead,
     368                                            (PBYTE)pExec->pLXHeader,
     369                                            0)))
     370                {
     371                    if (cbRead < sizeof(LXHEADER))
     372                        arc = ERROR_BAD_EXE_FORMAT;
     373                    else
     374                    {
     375                        pExec->cbLXHeader = cbRead;
     376                        pbCheckOS = (PBYTE)(&pExec->pLXHeader->usTargetOS);
     377                        // set library flag V0.9.16 (2001-12-08) [umoeller]
     378                        if (pExec->pLXHeader->ulFlags & 0x8000)
     379                            // library:
     380                            pExec->fLibrary = TRUE;
     381                    }
     382                }
     383            }
     384            else if (!memcmp(achNewHeaderType, "PE\0\0", 4))
     385            {
     386                pExec->ulExeFormat = EXEFORMAT_PE;
     387
     388                // PE has a standard header of 24 bytes
     389                // plus an extended header, so check
     390                // what we've got
     391                if (!(pExec->pPEHeader = malloc(sizeof(PEHEADER))))
     392                    arc = ERROR_NOT_ENOUGH_MEMORY;
     393                else
     394                {
     395                    ULONG ulOfs = ulNewHeaderOfs + 4;
     396                    PPEHEADER pPEHeader = pExec->pPEHeader;
     397
     398                    // null the entire header
     399                    memset(pExec->pPEHeader,
     400                           0,
     401                           sizeof(PEHEADER));
     402
     403                    // copy sig
     404                    pPEHeader->ulSignature = *((PULONG)&achNewHeaderType);
     405
     406                    // read standard header
     407                    cbRead = sizeof(IMAGE_FILE_HEADER);
    314408                    if (!(arc = doshReadAt(pFile,
    315                                            ulNewHeaderOfs,
     409                                           ulOfs,
    316410                                           &cbRead,
    317                                            achNewHeaderType)))
     411                                           (PBYTE)&pPEHeader->FileHeader,
     412                                           0)))
    318413                    {
    319                         PBYTE   pbCheckOS = NULL;
    320 
    321                         if (!memcmp(achNewHeaderType, "NE", 2))
     414                        if (cbRead < sizeof(IMAGE_FILE_HEADER))
     415                            // only if we don't even have the
     416                            // standard header, return an error
     417                            arc = ERROR_BAD_EXE_FORMAT;
     418                        else
    322419                        {
    323                             // New Executable:
    324                             pExec->ulExeFormat = EXEFORMAT_NE;
    325                             cbRead = sizeof(NEHEADER);
    326 
    327                             // go read in the complete header then
    328                             // (doshReadAt has this in the cache)
    329                             if (!(pExec->pNEHeader = malloc(cbRead)))
    330                                 arc = ERROR_NOT_ENOUGH_MEMORY;
    331                             else if (!(arc = doshReadAt(pFile,
    332                                                         ulNewHeaderOfs,
    333                                                         &cbRead,
    334                                                         (PBYTE)pExec->pNEHeader)))
     420                            pExec->f32Bits = TRUE;
     421                            pExec->cbPEHeader = 4 + sizeof(PEHEADER);       // for now
     422
     423                            if (pPEHeader->FileHeader.fsCharacteristics & IMAGE_FILE_DLL)
     424                                pExec->fLibrary = TRUE;
     425
     426                            // try extended header
     427                            ulOfs += sizeof(IMAGE_FILE_HEADER);
     428                            if (    (cbRead = pPEHeader->FileHeader.usSizeOfOptionalHeader)
     429                                 && (cbRead <= sizeof(IMAGE_OPTIONAL_HEADER))
     430                               )
    335431                            {
    336                                 if (cbRead < sizeof(NEHEADER))
    337                                     arc = ERROR_BAD_EXE_FORMAT;
    338                                 else
     432                                if (!(arc = doshReadAt(pFile,
     433                                                       ulOfs,
     434                                                       &cbRead,
     435                                                       (PBYTE)&pPEHeader->OptionalHeader,
     436                                                       0)))
    339437                                {
    340                                     pExec->cbNEHeader = cbRead;
    341                                     pbCheckOS = &pExec->pNEHeader->bTargetOS;
    342                                     // set library flag V0.9.16 (2001-12-08) [umoeller]
    343                                     if (pExec->pNEHeader->usFlags & 0x8000)
    344                                         // library:
    345                                         pExec->fLibrary = TRUE;
     438                                    if (cbRead != sizeof(IMAGE_OPTIONAL_HEADER))
     439                                        arc = ERROR_BAD_EXE_FORMAT;
     440                                    else switch (pPEHeader->OptionalHeader.usSubsystem)
     441                                    {
     442                                        // case IMAGE_SUBSYSTEM_UNKNOWN:   // 0
     443                                        // case IMAGE_SUBSYSTEM_NATIVE:    // 1
     444                                        // case IMAGE_SUBSYSTEM_OS2_CUI:   // 5
     445                                        // case IMAGE_SUBSYSTEM_POSIX_CUI: // 7
     446                                                // for these we shouldn't set win32
     447
     448                                        case IMAGE_SUBSYSTEM_WINDOWS_GUI: // 2   // Windows GUI subsystem
     449                                            pExec->ulOS = EXEOS_WIN32_GUI;
     450                                        break;
     451
     452                                        case IMAGE_SUBSYSTEM_WINDOWS_CUI: // 3   // Windows character subsystem
     453                                            pExec->ulOS = EXEOS_WIN32_CLI;
     454                                        break;
     455                                    }
     456
     457                                    pExec->cbPEHeader = sizeof(PEHEADER);
    346458                                }
    347459                            }
    348460                        }
    349                         else if (    (!memcmp(achNewHeaderType, "LX", 2))
    350                                   || (!memcmp(achNewHeaderType, "LE", 2))
    351                                             // this is used by SMARTDRV.EXE
    352                                 )
    353                         {
    354                             // OS/2 Linear Executable:
    355                             pExec->ulExeFormat = EXEFORMAT_LX;
    356                             cbRead = sizeof(LXHEADER);
    357 
    358                             // go read in the complete header then
    359                             // (doshReadAt has this in the cache)
    360                             if (!(pExec->pLXHeader = malloc(cbRead)))
    361                                 arc = ERROR_NOT_ENOUGH_MEMORY;
    362                             else if (!(arc = doshReadAt(pFile,
    363                                                         ulNewHeaderOfs,
    364                                                         &cbRead,
    365                                                         (PBYTE)pExec->pLXHeader)))
    366                             {
    367                                 if (cbRead < sizeof(LXHEADER))
    368                                     arc = ERROR_BAD_EXE_FORMAT;
    369                                 else
    370                                 {
    371                                     pExec->cbLXHeader = cbRead;
    372                                     pbCheckOS = (PBYTE)(&pExec->pLXHeader->usTargetOS);
    373                                     // set library flag V0.9.16 (2001-12-08) [umoeller]
    374                                     if (pExec->pLXHeader->ulFlags & 0x8000)
    375                                         // library:
    376                                         pExec->fLibrary = TRUE;
    377                                 }
    378                             }
    379                         }
    380                         else if (!memcmp(achNewHeaderType, "PE", 2))
    381                         {
    382                             pExec->ulExeFormat = EXEFORMAT_PE;
    383                             // PE has a standard header of 24 bytes
    384                             // plus an extended header, so try to
    385                             // read both of them in one chunk first
    386                             cbRead = sizeof(PEHEADER);
    387 
    388                             // go read in the complete header
    389                             // (doshReadAt has this in the cache)
    390                             if (!(pExec->pPEHeader = malloc(cbRead)))
    391                                 arc = ERROR_NOT_ENOUGH_MEMORY;
    392                             else if (!(arc = doshReadAt(pFile,
    393                                                         ulNewHeaderOfs,
    394                                                         &cbRead,
    395                                                         (PBYTE)pExec->pPEHeader)))
    396                             {
    397                                 if (cbRead < 24)
    398                                     // only if don't even have the
    399                                     // standard header, return an error
    400                                     arc = ERROR_BAD_EXE_FORMAT;
    401                                 else
    402                                 {
    403                                     // set size of header to what we've got
    404                                     pExec->cbPEHeader = pExec->pPEHeader->usHeaderSize;
    405                                     pExec->ulOS = EXEOS_WIN32;
    406                                     pExec->f32Bits = TRUE;
    407 
    408                                     /*
    409                                     // we have the first 24 bytes already, so
    410                                     // go for the next chunk, if this is more
    411                                     // than we have in PEHEADER
    412                                     if (    (cbRead < cbPE)
    413                                          && (cbRead = pExec->pPEHeader->usHeaderSize)
    414                                        )
    415                                     {
    416                                         _Pmpf(("  usHdrSize %d, sizeof(PEHEADER) %d, cbRead %d, cbPE %d --> reading extended header",
    417                                                pExec->pPEHeader->usHeaderSize,
    418                                                sizeof(PEHEADER),
    419                                                cbRead,
    420                                                cbPE));
    421                                         if (!(arc = doshReadAt(hFile,
    422                                                                ulNewHeaderOfs + 24,
    423                                                                FILE_BEGIN,
    424                                                                &cbRead,
    425                                                                (PBYTE)pExec->pPEHeader + 24)))
    426                                         {
    427                                         }
    428                                         else
    429                                         {
    430                                             arc = ERROR_BAD_EXE_FORMAT;
    431                                             FREE(pExec->pPEHeader);
    432                                         }
    433                                     }
    434                                     else
    435                                         _Pmpf(("  already got extended header"));
    436                                     */
    437                                 }
    438                             }
    439                         }
    440                         else
    441                             // strange type:
    442                             arc = ERROR_INVALID_EXE_SIGNATURE;
    443 
    444                         if ((!arc) && (pbCheckOS))
    445                         {
    446                             // BYTE to check for operating system
    447                             // (NE and LX):
    448                             switch (*pbCheckOS)
    449                             {
    450                                 case NEOS_OS2:
    451                                     pExec->ulOS = EXEOS_OS2;
    452                                     if (pExec->ulExeFormat == EXEFORMAT_LX)
    453                                         pExec->f32Bits = TRUE;
    454                                 break;
    455 
    456                                 case NEOS_WIN16:
    457                                     pExec->ulOS = EXEOS_WIN16;
    458                                 break;
    459 
    460                                 case NEOS_DOS4:
    461                                     pExec->ulOS = EXEOS_DOS4;
    462                                 break;
    463 
    464                                 case NEOS_WIN386:
    465                                     pExec->ulOS = EXEOS_WIN386;
    466                                     pExec->f32Bits = TRUE;
    467                                 break;
    468                             }
    469                         }
    470                     } // end if (!(arc = doshReadAt(hFile,
    471                 } // end if (fLoadNewHeader)
    472             } // end if (!(arc = doshReadAt(hFile,
    473         } // end else if (!(pExec->pDosExeHeader = (PDOSEXEHEADER)malloc(sizeof(DOSEXEHEADER))))
    474 
    475     } // end if (!(arc = DosOpen((PSZ)pcszExecutable,
     461                    }
     462                }
     463            }
     464            else
     465                // strange type:
     466                arc = ERROR_INVALID_EXE_SIGNATURE;
     467
     468            if ((!arc) && (pbCheckOS))
     469            {
     470                // BYTE to check for operating system
     471                // (NE and LX):
     472                switch (*pbCheckOS)
     473                {
     474                    case NEOS_OS2:
     475                        pExec->ulOS = EXEOS_OS2;
     476                        if (pExec->ulExeFormat == EXEFORMAT_LX)
     477                            pExec->f32Bits = TRUE;
     478                    break;
     479
     480                    case NEOS_WIN16:
     481                        pExec->ulOS = EXEOS_WIN16;
     482                    break;
     483
     484                    case NEOS_DOS4:
     485                        pExec->ulOS = EXEOS_DOS4;
     486                    break;
     487
     488                    case NEOS_WIN386:
     489                        pExec->ulOS = EXEOS_WIN386;
     490                        pExec->f32Bits = TRUE;
     491                    break;
     492                }
     493            }
     494        } // end if (!(arc = doshReadAt(hFile,
     495    } // end if (fLoadNewHeader)
    476496
    477497    if (arc != NO_ERROR)
     
    769789                                       ulNRNTOfs,       // ofs determined above
    770790                                       &cb,             // 2000
    771                                        pszNameTable)))
     791                                       pszNameTable,
     792                                       0)))
    772793                {
    773794                    // the string is in Pascal format, so the
     
    20352056                                      + ulNewHeaderOfs,
    20362057                                    &cb,
    2037                                     (PBYTE)pExec->pRsTbl)))
     2058                                    (PBYTE)pExec->pRsTbl,
     2059                                    DRFL_FAILIFLESS)))
    20382060            )
    20392061        {
     
    20472069                                          + ulNewHeaderOfs,
    20482070                                        &cb,
    2049                                         (PBYTE)pExec->pObjTbl)))
     2071                                        (PBYTE)pExec->pObjTbl,
     2072                                        DRFL_FAILIFLESS)))
    20502073               )
    20512074            {
     
    20592082                                              + ulNewHeaderOfs,
    20602083                                            &cb,
    2061                                             (PBYTE)pExec->pObjPageTbl)))
     2084                                            (PBYTE)pExec->pObjPageTbl,
     2085                                            DRFL_FAILIFLESS)))
    20622086                   )
    20632087                {
     
    25242548                                    ulOffset,
    25252549                                    &ulSize,
    2526                                     pabCompressed)))
     2550                                    pabCompressed,
     2551                                    0)))
    25272552        {
    25282553            _Pmpf(("   %d bytes read", ulSize));
     
    28832908                                      + ulNewHeaderOfs,
    28842909                                    &cb,
    2885                                     (PBYTE)pExec->paOS2NEResTblEntry)))
     2910                                    (PBYTE)pExec->paOS2NEResTblEntry,
     2911                                    DRFL_FAILIFLESS)))
    28862912            )
    28872913        {
     
    28962922                                          - cb, // pNEHeader->usResSegmCount * sizeof(struct new_seg)
    28972923                                        &cb,
    2898                                         (PBYTE)pExec->paOS2NESegments)))
     2924                                        (PBYTE)pExec->paOS2NESegments,
     2925                                        DRFL_FAILIFLESS)))
    28992926                )
    29002927            {
     
    30323059                                           ulOffset,
    30333060                                           &cb,
    3034                                            *ppbResData)))
     3061                                           *ppbResData,
     3062                                           DRFL_FAILIFLESS)))
    30353063                    {
    30363064                        if (pcbResData)
Note: See TracChangeset for help on using the changeset viewer.