Changeset 123 for trunk/src/helpers/dosh2.c
- Timestamp:
- Dec 14, 2001, 11:41:33 PM (24 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/helpers/dosh2.c
r110 r123 426 426 *@@changed V0.9.10 (2001-04-08) [umoeller]: now setting ppExec only if NO_ERROR is returned 427 427 *@@changed V0.9.12 (2001-05-03) [umoeller]: added support for NOSTUB newstyle executables 428 *@@changed V0.9.16 (2001-12-08) [umoeller]: now using OPEN_SHARE_DENYWRITE 429 *@@changed V0.9.16 (2001-12-08) [umoeller]: fLibrary was never set, works for LX and NE now 428 430 */ 429 431 … … 440 442 return (ERROR_INVALID_PARAMETER); 441 443 442 pExec = (PEXECUTABLE)malloc(sizeof(EXECUTABLE)); 443 if (!(pExec)) 444 if (!(pExec = (PEXECUTABLE)malloc(sizeof(EXECUTABLE)))) 444 445 return (ERROR_NOT_ENOUGH_MEMORY); 445 446 … … 458 459 | OPEN_FLAGS_SEQUENTIAL 459 460 | OPEN_FLAGS_NOINHERIT 460 | OPEN_SHARE_DENYNONE 461 // | OPEN_SHARE_DENYNONE 462 | OPEN_SHARE_DENYWRITE // changed V0.9.16 (2001-12-08) [umoeller] 461 463 | OPEN_ACCESS_READONLY, // read-only mode 462 464 NULL))) // no EAs … … 464 466 // file opened successfully: 465 467 466 ULONG ulLocal = 0;467 468 468 // read old DOS EXE header 469 pExec->pDosExeHeader = (PDOSEXEHEADER)malloc(sizeof(DOSEXEHEADER)); 470 if (!(pExec->pDosExeHeader)) 469 if (!(pExec->pDosExeHeader = (PDOSEXEHEADER)malloc(sizeof(DOSEXEHEADER)))) 471 470 arc = ERROR_NOT_ENOUGH_MEMORY; 472 471 else 473 472 { 474 ULONG ulBytesRead = 0; 475 476 if ( (!(arc = DosSetFilePtr(hFile, 477 0L, 478 FILE_BEGIN, 479 &ulLocal))) // out: new offset 480 && (!(arc = DosRead(hFile, 481 pExec->pDosExeHeader, 482 sizeof(DOSEXEHEADER), 483 &(pExec->cbDosExeHeader)))) 484 ) 473 pExec->cbDosExeHeader = sizeof(DOSEXEHEADER); 474 if (!(arc = doshReadAt(hFile, 475 0, 476 FILE_BEGIN, 477 &pExec->cbDosExeHeader, // in/out 478 (PBYTE)pExec->pDosExeHeader))) 485 479 { 486 480 ULONG ulNewHeaderOfs = 0; // V0.9.12 (2001-05-03) [umoeller] … … 530 524 // V0.9.12 (2001-05-03) [umoeller] 531 525 CHAR achNewHeaderType[2] = ""; 532 533 if ( (!(arc = DosSetFilePtr(hFile, 534 ulNewHeaderOfs, 535 FILE_BEGIN, 536 &ulLocal))) 537 // read two chars to find out header type 538 && (!(arc = DosRead(hFile, 539 &achNewHeaderType, 540 sizeof(achNewHeaderType), 541 &ulBytesRead))) 542 ) 526 ULONG cbRead; 527 528 cbRead = sizeof(achNewHeaderType); 529 if (!(arc = doshReadAt(hFile, 530 ulNewHeaderOfs, 531 FILE_BEGIN, 532 &cbRead, 533 achNewHeaderType))) 543 534 { 544 535 PBYTE pbCheckOS = NULL; 545 536 546 537 // reset file ptr 547 DosSetFilePtr(hFile,538 /* DosSetFilePtr(hFile, 548 539 ulNewHeaderOfs, 549 540 FILE_BEGIN, 550 541 &ulLocal); 551 552 if (memcmp(achNewHeaderType, "NE", 2) == 0) 542 */ 543 544 if (!memcmp(achNewHeaderType, "NE", 2)) 553 545 { 554 546 // New Executable: 555 547 pExec->ulExeFormat = EXEFORMAT_NE; 556 548 // allocate NE header 557 pExec->pNEHeader = (PNEHEADER)malloc(sizeof(NEHEADER)); 558 if (!(pExec->pNEHeader)) 549 if (pExec->pNEHeader = (PNEHEADER)malloc(sizeof(NEHEADER))) 550 { 551 // read in NE header 552 pExec->cbNEHeader = sizeof(NEHEADER); 553 if (!(arc = doshReadAt(hFile, 554 ulNewHeaderOfs, 555 FILE_BEGIN, 556 &pExec->cbNEHeader, 557 (PBYTE)pExec->pNEHeader))) 558 { 559 if (pExec->cbNEHeader == sizeof(NEHEADER)) 560 { 561 pbCheckOS = &pExec->pNEHeader->bTargetOS; 562 // set library flag V0.9.16 (2001-12-08) [umoeller] 563 if (pExec->pNEHeader->usFlags & 0x8000) 564 // library: 565 pExec->fLibrary = TRUE; 566 } 567 else 568 // V0.9.16 (2001-12-08) [umoeller] 569 arc = ERROR_INVALID_EXE_SIGNATURE; 570 } 571 } 572 else 559 573 arc = ERROR_NOT_ENOUGH_MEMORY; 560 else561 // read in NE header562 if (!(arc = DosRead(hFile,563 pExec->pNEHeader,564 sizeof(NEHEADER),565 &(pExec->cbNEHeader))))566 if (pExec->cbNEHeader == sizeof(NEHEADER))567 pbCheckOS = &(pExec->pNEHeader->bTargetOS);568 574 } 569 575 else if ( (memcmp(achNewHeaderType, "LX", 2) == 0) … … 575 581 pExec->ulExeFormat = EXEFORMAT_LX; 576 582 // allocate LX header 577 pExec->pLXHeader = (PLXHEADER)malloc(sizeof(LXHEADER)); 578 if (!(pExec->pLXHeader)) 583 if (pExec->pLXHeader = (PLXHEADER)malloc(sizeof(LXHEADER))) 584 { 585 // read in LX header 586 pExec->cbLXHeader = sizeof(LXHEADER); 587 if (!(arc = doshReadAt(hFile, 588 ulNewHeaderOfs, 589 FILE_BEGIN, 590 &pExec->cbLXHeader, 591 (PBYTE)pExec->pLXHeader))) 592 { 593 if (pExec->cbLXHeader == sizeof(LXHEADER)) 594 { 595 pbCheckOS = (PBYTE)(&pExec->pLXHeader->usTargetOS); 596 // set library flag V0.9.16 (2001-12-08) [umoeller] 597 if (pExec->pLXHeader->ulFlags & 0x8000) 598 // library: 599 pExec->fLibrary = TRUE; 600 } 601 else 602 // V0.9.16 (2001-12-08) [umoeller] 603 arc = ERROR_INVALID_EXE_SIGNATURE; 604 } 605 } 606 else 579 607 arc = ERROR_NOT_ENOUGH_MEMORY; 580 else581 // read in LX header582 if (!(arc = DosRead(hFile,583 pExec->pLXHeader,584 sizeof(LXHEADER),585 &(pExec->cbLXHeader))))586 if (pExec->cbLXHeader == sizeof(LXHEADER))587 pbCheckOS = (PBYTE)(&(pExec->pLXHeader->usTargetOS));588 608 } 589 609 else if (memcmp(achNewHeaderType, "PE", 2) == 0) … … 597 617 // V0.9.10 (2001-04-08) [lafaix] 598 618 // read in standard PE header 599 if (!(arc = DosRead(hFile, 600 &PEHeader, 601 24, 602 &ulBytesRead))) 619 cbRead = 24; 620 if (!(arc = doshReadAt(hFile, 621 ulNewHeaderOfs, 622 FILE_BEGIN, 623 &cbRead, 624 (PBYTE)&PEHeader))) 603 625 { 604 626 // allocate PE header 605 pExec->pPEHeader = (PPEHEADER)malloc(24 + PEHeader.usHeaderSize); 606 if (!(pExec->pPEHeader)) 607 arc = ERROR_NOT_ENOUGH_MEMORY; 608 else 627 if (pExec->pPEHeader = (PPEHEADER)malloc(24 + PEHeader.usHeaderSize)) 609 628 { 610 629 // copy standard PE header … … 615 634 // read in optional PE header 616 635 if (!(arc = DosRead(hFile, 617 & (pExec->pPEHeader->usReserved3),636 &pExec->pPEHeader->usReserved3, 618 637 PEHeader.usHeaderSize, 619 & (pExec->cbPEHeader))))638 &pExec->cbPEHeader))) 620 639 pExec->cbPEHeader += 24; 621 640 } 641 else 642 arc = ERROR_NOT_ENOUGH_MEMORY; 622 643 } 623 644 } … … 661 682 if (arc != NO_ERROR) 662 683 // error: clean up 663 doshExecClose( pExec);684 doshExecClose(&pExec); 664 685 else 665 686 *ppExec = pExec; 666 667 return (arc);668 }669 670 /*671 *@@ doshExecClose:672 * this closes an executable opened with doshExecOpen.673 * Always call this function if NO_ERROR was returned by674 * doshExecOpen.675 *676 *@@added V0.9.0 [umoeller]677 */678 679 APIRET doshExecClose(PEXECUTABLE pExec)680 {681 APIRET arc = NO_ERROR;682 if (pExec)683 {684 if (pExec->pDosExeHeader)685 free(pExec->pDosExeHeader);686 if (pExec->pNEHeader)687 free(pExec->pNEHeader);688 if (pExec->pLXHeader)689 free(pExec->pLXHeader);690 691 if (pExec->pszDescription)692 free(pExec->pszDescription);693 if (pExec->pszVendor)694 free(pExec->pszVendor);695 if (pExec->pszVersion)696 free(pExec->pszVersion);697 if (pExec->pszInfo)698 free(pExec->pszInfo);699 700 if (pExec->hfExe)701 arc = DosClose(pExec->hfExe);702 703 free(pExec);704 }705 else706 arc = ERROR_INVALID_PARAMETER;707 687 708 688 return (arc); … … 789 769 { 790 770 // date/time seems to be fixed 24 chars in length 791 pExec->pszBuildDateTime = (PSZ)malloc(25); 792 if (pExec->pszBuildDateTime) 771 if (pExec->pszBuildDateTime = (PSZ)malloc(25)) 793 772 { 794 773 memcpy(pExec->pszBuildDateTime, … … 1862 1841 { 1863 1842 // 32-bit OS/2 executable: 1864 cResources = pExec->pLXHeader->ulResTblCnt; 1865 1866 if (cResources) 1843 if (cResources = pExec->pLXHeader->ulResTblCnt) 1867 1844 { 1868 1845 #pragma pack(1) // V0.9.9 (2001-04-02) [umoeller] 1869 struct rsrc32 / * Resource Table Entry */1846 struct rsrc32 // Resource Table Entry 1870 1847 { 1871 unsigned short type; / * Resource type */1872 unsigned short name; / * Resource name */1873 unsigned long cb; / * Resource size */1874 unsigned short obj; / * Object number */1875 unsigned long offset; / * Offset within object */1848 unsigned short type; // Resource type 1849 unsigned short name; // Resource name 1850 unsigned long cb; // Resource size 1851 unsigned short obj; // Object number 1852 unsigned long offset; // Offset within object 1876 1853 } rs; 1877 1854 1878 struct o32_obj / * Flat .EXE object table entry */1855 struct o32_obj // Flat .EXE object table entry 1879 1856 { 1880 unsigned long o32_size; / * Object virtual size */1881 unsigned long o32_base; / * Object base virtual address */1882 unsigned long o32_flags; / * Attribute flags */1883 unsigned long o32_pagemap; / * Object page map index */1884 unsigned long o32_mapsize; / * Number of entries in object page map */1885 unsigned long o32_reserved; / * Reserved */1857 unsigned long o32_size; // Object virtual size 1858 unsigned long o32_base; // Object base virtual address 1859 unsigned long o32_flags; // Attribute flags 1860 unsigned long o32_pagemap; // Object page map index 1861 unsigned long o32_mapsize; // Number of entries in object page map 1862 unsigned long o32_reserved; // Reserved 1886 1863 } ot; 1887 1864 #pragma pack() // V0.9.9 (2001-04-03) [umoeller] … … 1890 1867 ULONG ulDummy; 1891 1868 int i; 1869 ULONG ulCurOfs; 1892 1870 1893 1871 paResources = (PFSYSRESOURCE)malloc(cb); … … 1956 1934 #pragma pack(1) // V0.9.9 (2001-04-02) [umoeller] 1957 1935 struct {unsigned short type; unsigned short name;} rti; 1958 struct new_seg / * New .EXE segment table entry */1936 struct new_seg // New .EXE segment table entry 1959 1937 { 1960 unsigned short ns_sector; / * File sector of start of segment */1961 unsigned short ns_cbseg; / * Number of bytes in file */1962 unsigned short ns_flags; / * Attribute flags */1963 unsigned short ns_minalloc; / * Minimum allocation in bytes */1938 unsigned short ns_sector; // File sector of start of segment 1939 unsigned short ns_cbseg; // Number of bytes in file 1940 unsigned short ns_flags; // Attribute flags 1941 unsigned short ns_minalloc; // Minimum allocation in bytes 1964 1942 } ns; 1965 1943 #pragma pack() … … 2183 2161 free(paResources); 2184 2162 return (NO_ERROR); 2163 } 2164 2165 /* 2166 *@@ doshLoadLXMaps: 2167 * loads the three main LX maps into the given 2168 * EXECUTABLE structure. 2169 * 2170 * This loads: 2171 * 2172 * 1) the LX resource table; 2173 * 2174 * 2) the LX object table; 2175 * 2176 * 3) the LX object _page_ table (object map). 2177 * 2178 * Note that this is not automatically called 2179 * by doshExecOpen to save time, since the LX 2180 * maps are not needed for all the other exe 2181 * functions. 2182 * 2183 * This returns: 2184 * 2185 * -- NO_ERROR: all three LX maps were loaded, 2186 * and pExec->fLXMapsLoaded was set to TRUE. 2187 * 2188 * -- ERROR_INVALID_PARAMETER 2189 * 2190 * -- ERROR_INVALID_EXE_SIGNATURE: pExec does 2191 * not specify an LX executable. 2192 * 2193 * -- ERROR_NO_DATA: at least one of the structs 2194 * does not exist. 2195 * 2196 * -- ERROR_NOT_ENOUGH_MEMORY 2197 * 2198 * plus the error codes of doshReadAt. 2199 * 2200 * Call doshFreeLXMaps to clean up explicitly, but 2201 * that func automatically gets called by doshExecClose. 2202 * 2203 *@@added V0.9.16 (2001-12-08) [umoeller] 2204 */ 2205 2206 APIRET doshLoadLXMaps(PEXECUTABLE pExec) 2207 { 2208 APIRET arc; 2209 2210 if (!pExec) 2211 arc = ERROR_INVALID_PARAMETER; 2212 else if (pExec->ulExeFormat != EXEFORMAT_LX) 2213 arc = ERROR_INVALID_EXE_SIGNATURE; 2214 else if (pExec->fLXMapsLoaded) 2215 // already loaded: 2216 arc = NO_ERROR; 2217 else 2218 { 2219 PLXHEADER pLXHeader = pExec->pLXHeader; 2220 ULONG ulNewHeaderOfs = 0; 2221 ULONG cb; 2222 2223 if (pExec->pDosExeHeader) 2224 // executable has DOS stub: V0.9.12 (2001-05-03) [umoeller] 2225 ulNewHeaderOfs = pExec->pDosExeHeader->ulNewHeaderOfs; 2226 2227 // resource table 2228 if ( (!(arc = doshAllocArray(pLXHeader->ulResTblCnt, 2229 sizeof(RESOURCETABLEENTRY), 2230 (PBYTE*)&pExec->pRsTbl, 2231 &cb))) 2232 && (!(arc = doshReadAt(pExec->hfExe, 2233 pLXHeader->ulResTblOfs 2234 + ulNewHeaderOfs, 2235 FILE_BEGIN, 2236 &cb, 2237 (PBYTE)pExec->pRsTbl))) 2238 ) 2239 { 2240 // object table 2241 if ( (!(arc = doshAllocArray(pLXHeader->ulObjCount, 2242 sizeof(OBJECTTABLEENTRY), 2243 (PBYTE*)&pExec->pObjTbl, 2244 &cb))) 2245 && (!(arc = doshReadAt(pExec->hfExe, 2246 pLXHeader->ulObjTblOfs 2247 + ulNewHeaderOfs, 2248 FILE_BEGIN, 2249 &cb, 2250 (PBYTE)pExec->pObjTbl))) 2251 ) 2252 { 2253 // object page table 2254 if ( (!(arc = doshAllocArray(pLXHeader->ulPageCount, 2255 sizeof(OBJECTPAGETABLEENTRY), 2256 (PBYTE*)&pExec->pObjPageTbl, 2257 &cb))) 2258 && (!(arc = doshReadAt(pExec->hfExe, 2259 pLXHeader->ulObjPageTblOfs 2260 + ulNewHeaderOfs, 2261 FILE_BEGIN, 2262 &cb, 2263 (PBYTE)pExec->pObjPageTbl))) 2264 ) 2265 ; 2266 } 2267 } 2268 2269 if (!arc) 2270 pExec->fLXMapsLoaded = TRUE; 2271 else 2272 doshFreeLXMaps(pExec); 2273 } 2274 2275 return (arc); 2276 } 2277 2278 /* 2279 *@@ doshFreeLXMaps: 2280 * frees only the LX maps allocated by doshLoadLXMaps. 2281 * This gets called automatically by doshExecClose. 2282 * 2283 *@@added V0.9.16 (2001-12-08) [umoeller] 2284 */ 2285 2286 VOID doshFreeLXMaps(PEXECUTABLE pExec) 2287 { 2288 FREE(pExec->pRsTbl); 2289 FREE(pExec->pObjTbl); 2290 FREE(pExec->pObjPageTbl); 2291 pExec->fLXMapsLoaded = FALSE; 2292 } 2293 2294 /* 2295 *@@ doshExecClose: 2296 * this closes an executable opened with doshExecOpen. 2297 * Always call this function if NO_ERROR was returned by 2298 * doshExecOpen. 2299 * 2300 * This automaticall calls doshFreeLXMaps. 2301 * 2302 *@@added V0.9.0 [umoeller] 2303 *@@changed V0.9.16 (2001-12-08) [umoeller]: fixed memory leaks 2304 *@@changed V0.9.16 (2001-12-08) [umoeller]: changed prototype to null the pExec ptr 2305 */ 2306 2307 APIRET doshExecClose(PEXECUTABLE *ppExec) 2308 { 2309 APIRET arc = NO_ERROR; 2310 PEXECUTABLE pExec; 2311 if ( (ppExec) 2312 && (pExec = *ppExec) 2313 ) 2314 { 2315 char **papsz[] = 2316 { 2317 (char**)&pExec->pDosExeHeader, 2318 (char**)&pExec->pNEHeader, 2319 (char**)&pExec->pLXHeader, 2320 (char**)&pExec->pPEHeader, 2321 2322 &pExec->pszDescription, 2323 &pExec->pszVendor, 2324 &pExec->pszVersion, 2325 &pExec->pszInfo, 2326 2327 &pExec->pszBuildDateTime, 2328 &pExec->pszBuildMachine, 2329 &pExec->pszASD, 2330 &pExec->pszLanguage, 2331 &pExec->pszCountry, 2332 &pExec->pszRevision, 2333 &pExec->pszUnknown, 2334 &pExec->pszFixpak 2335 }; 2336 ULONG ul; 2337 2338 doshFreeLXMaps(pExec); 2339 2340 // fixed the memory leaks with the missing fields, 2341 // turned this into a loop 2342 for (ul = 0; 2343 ul < sizeof(papsz) / sizeof(papsz[0]); 2344 ul++) 2345 { 2346 PSZ pThis; 2347 if (pThis = *papsz[ul]) 2348 { 2349 free(pThis); 2350 pThis = NULL; 2351 } 2352 } 2353 2354 if (pExec->hfExe) 2355 arc = DosClose(pExec->hfExe); 2356 2357 free(pExec); 2358 *ppExec = NULL; 2359 } 2360 else 2361 arc = ERROR_INVALID_PARAMETER; 2362 2363 return (arc); 2185 2364 } 2186 2365
Note:
See TracChangeset
for help on using the changeset viewer.