Changeset 131 for trunk/src/helpers/exeh.c
- Timestamp:
- Jan 9, 2002, 10:17:41 PM (24 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/helpers/exeh.c
r130 r131 171 171 *@@changed V0.9.12 (2001-05-03) [umoeller]: added support for NOSTUB newstyle executables 172 172 *@@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 now173 *@@changed V0.9.16 (2001-12-08) [umoeller]: fLibrary was never set, works for LX, NE, and PE now 174 174 *@@changed V0.9.16 (2001-12-08) [umoeller]: speed optimizations, changed some return codes 175 175 *@@changed V0.9.16 (2002-01-04) [umoeller]: added fixes for COM, BAT, CMD extensions … … 187 187 PCSZ pExt; 188 188 BOOL fOpenFile = FALSE; 189 BOOL fLoadNewHeader = FALSE; 190 ULONG ulNewHeaderOfs = 0; // V0.9.12 (2001-05-03) [umoeller] 189 191 190 192 if (!ppExec) … … 240 242 } 241 243 242 if ( (fOpenFile) // no t one of the above244 if ( (fOpenFile) // none of the above 243 245 && (!(arc = doshOpen((PSZ)pcszExecutable, 244 246 XOPEN_READ_EXISTING, 245 247 &cbFile, 246 248 &pFile))) 249 // file opened successfully: 247 250 ) 248 251 { 249 // file opened successfully:250 252 pExec->pFile = pFile; 253 pExec->cbDosExeHeader = sizeof(DOSEXEHEADER); 251 254 252 255 // read old DOS EXE header 253 256 if (!(pExec->pDosExeHeader = (PDOSEXEHEADER)malloc(sizeof(DOSEXEHEADER)))) 254 257 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))) 256 263 { 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) 262 266 { 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; 282 290 } 283 291 else 284 292 { 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; 292 341 else 293 342 { 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; 297 349 } 298 350 } 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); 314 408 if (!(arc = doshReadAt(pFile, 315 ul NewHeaderOfs,409 ulOfs, 316 410 &cbRead, 317 achNewHeaderType))) 411 (PBYTE)&pPEHeader->FileHeader, 412 0))) 318 413 { 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 322 419 { 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 ) 335 431 { 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))) 339 437 { 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); 346 458 } 347 459 } 348 460 } 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) 476 496 477 497 if (arc != NO_ERROR) … … 769 789 ulNRNTOfs, // ofs determined above 770 790 &cb, // 2000 771 pszNameTable))) 791 pszNameTable, 792 0))) 772 793 { 773 794 // the string is in Pascal format, so the … … 2035 2056 + ulNewHeaderOfs, 2036 2057 &cb, 2037 (PBYTE)pExec->pRsTbl))) 2058 (PBYTE)pExec->pRsTbl, 2059 DRFL_FAILIFLESS))) 2038 2060 ) 2039 2061 { … … 2047 2069 + ulNewHeaderOfs, 2048 2070 &cb, 2049 (PBYTE)pExec->pObjTbl))) 2071 (PBYTE)pExec->pObjTbl, 2072 DRFL_FAILIFLESS))) 2050 2073 ) 2051 2074 { … … 2059 2082 + ulNewHeaderOfs, 2060 2083 &cb, 2061 (PBYTE)pExec->pObjPageTbl))) 2084 (PBYTE)pExec->pObjPageTbl, 2085 DRFL_FAILIFLESS))) 2062 2086 ) 2063 2087 { … … 2524 2548 ulOffset, 2525 2549 &ulSize, 2526 pabCompressed))) 2550 pabCompressed, 2551 0))) 2527 2552 { 2528 2553 _Pmpf((" %d bytes read", ulSize)); … … 2883 2908 + ulNewHeaderOfs, 2884 2909 &cb, 2885 (PBYTE)pExec->paOS2NEResTblEntry))) 2910 (PBYTE)pExec->paOS2NEResTblEntry, 2911 DRFL_FAILIFLESS))) 2886 2912 ) 2887 2913 { … … 2896 2922 - cb, // pNEHeader->usResSegmCount * sizeof(struct new_seg) 2897 2923 &cb, 2898 (PBYTE)pExec->paOS2NESegments))) 2924 (PBYTE)pExec->paOS2NESegments, 2925 DRFL_FAILIFLESS))) 2899 2926 ) 2900 2927 { … … 3032 3059 ulOffset, 3033 3060 &cb, 3034 *ppbResData))) 3061 *ppbResData, 3062 DRFL_FAILIFLESS))) 3035 3063 { 3036 3064 if (pcbResData)
Note:
See TracChangeset
for help on using the changeset viewer.