Changeset 52 for trunk/src/helpers/dosh2.c
- Timestamp:
- Mar 30, 2001, 10:27:12 PM (24 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/helpers/dosh2.c
r51 r52 753 753 /* 754 754 *@@category: Helpers\Control program helpers\Executable info 755 * these functions can retrieve BLDLEVEL information from 756 * any executable module. See doshExecOpen. 755 * these functions can retrieve BLDLEVEL information, 756 * imported modules information, exported functions information, 757 * and resources information from any executable module. See 758 * doshExecOpen. 757 759 */ 758 760 … … 1214 1216 PULONG pcModules) 1215 1217 { 1216 return (NULL); 1218 ULONG cModules = 0; 1219 PFSYSMODULE paModules = NULL; 1220 int i; 1221 1222 if (pExec) 1223 { 1224 if (pExec->ulOS == EXEOS_OS2) 1225 { 1226 ULONG ulDummy; 1227 1228 if (pExec->ulExeFormat == EXEFORMAT_LX) 1229 { 1230 // It's a 32bit OS/2 executable 1231 cModules = pExec->pLXHeader->ulImportModTblCnt; 1232 1233 if (cModules) 1234 { 1235 BYTE bLen; 1236 1237 paModules = (PFSYSMODULE)malloc(sizeof(FSYSMODULE) * cModules); 1238 1239 DosSetFilePtr(pExec->hfExe, 1240 pExec->pLXHeader->ulImportModTblOfs 1241 + pExec->pDosExeHeader->ulNewHeaderOfs, 1242 FILE_BEGIN, 1243 &ulDummy); 1244 1245 for (i = 0; i < cModules; i++) 1246 { 1247 // reading the length of the module name 1248 DosRead(pExec->hfExe, 1249 &bLen, 1250 1, 1251 &ulDummy); 1252 1253 // At most 127 bytes 1254 bLen &= 0x7F; 1255 1256 // reading the module name 1257 DosRead(pExec->hfExe, 1258 paModules[i].achModuleName, 1259 bLen, 1260 &ulDummy); 1261 1262 // modules name are not null terminated, so we must 1263 // do it now 1264 paModules[i].achModuleName[bLen] = 0; 1265 } 1266 } 1267 } 1268 else 1269 if (pExec->ulExeFormat == EXEFORMAT_NE) 1270 { 1271 // It's a 16bit OS/2 executable 1272 cModules = pExec->pNEHeader->usModuleTblEntries; 1273 1274 if (cModules) 1275 { 1276 BYTE bLen; 1277 1278 paModules = (PFSYSMODULE)malloc(sizeof(FSYSMODULE) * cModules); 1279 1280 for (i = 0; i < cModules; i ++) 1281 { 1282 USHORT usOfs; 1283 1284 // the module reference table contains offsets 1285 // relative to the import table; we hence read 1286 // the offset in the module reference table, and 1287 // then we read the name in the import table 1288 1289 DosSetFilePtr(pExec->hfExe, 1290 pExec->pNEHeader->usModRefTblOfs 1291 + pExec->pDosExeHeader->ulNewHeaderOfs 1292 + sizeof(usOfs) * i, 1293 FILE_BEGIN, 1294 &ulDummy); 1295 1296 DosRead(pExec->hfExe, 1297 &usOfs, 1298 2, 1299 &ulDummy); 1300 1301 DosSetFilePtr(pExec->hfExe, 1302 pExec->pNEHeader->usImportTblOfs 1303 + pExec->pDosExeHeader->ulNewHeaderOfs 1304 + usOfs, 1305 FILE_BEGIN, 1306 &ulDummy); 1307 1308 DosRead(pExec->hfExe, 1309 &bLen, 1310 1, 1311 &ulDummy); 1312 1313 bLen &= 0x7F; 1314 1315 DosRead(pExec->hfExe, 1316 paModules[i].achModuleName, 1317 bLen, 1318 &ulDummy); 1319 1320 paModules[i].achModuleName[bLen] = 0; 1321 } 1322 1323 } 1324 } 1325 1326 *pcModules = cModules; 1327 } 1328 } 1329 1330 return (paModules); 1217 1331 } 1218 1332 … … 1228 1342 free(paModules); 1229 1343 return (NO_ERROR); 1344 } 1345 1346 /* 1347 *@@ ScanLXEntryTable: 1348 * returns the number of exported entries in the entry table. 1349 * 1350 * if paFunctions is not NULL, then successive entries are 1351 * filled with the found type and ordinal values. 1352 * 1353 *@@added V0.9.9 (2001-03-30) [lafaix] 1354 */ 1355 1356 ULONG ScanLXEntryTable(PEXECUTABLE pExec, 1357 PFSYSFUNCTION paFunctions) 1358 { 1359 USHORT usOrdinal = 1, 1360 usCurrent = 0; 1361 ULONG ulDummy; 1362 int i; 1363 1364 DosSetFilePtr(pExec->hfExe, 1365 pExec->pLXHeader->ulEntryTblOfs 1366 + pExec->pDosExeHeader->ulNewHeaderOfs, 1367 FILE_BEGIN, 1368 &ulDummy); 1369 1370 while (TRUE) 1371 { 1372 BYTE bCnt, 1373 bType, 1374 bFlag; 1375 1376 DosRead(pExec->hfExe, 1377 &bCnt, 1378 1, 1379 &ulDummy); 1380 1381 if (bCnt == 0) 1382 // end of the entry table 1383 break; 1384 1385 DosRead(pExec->hfExe, 1386 &bType, 1387 1, 1388 &ulDummy); 1389 1390 switch (bType & 0x7F) 1391 { 1392 /* 1393 * unused entries 1394 * 1395 */ 1396 1397 case 0: 1398 usOrdinal += bCnt; 1399 break; 1400 1401 /* 1402 * 16-bit entries 1403 * 1404 * the bundle type is followed by the object number 1405 * and by bCnt bFlag+usOffset entries 1406 * 1407 */ 1408 1409 case 1: 1410 DosSetFilePtr(pExec->hfExe, 1411 sizeof(USHORT), 1412 FILE_CURRENT, 1413 &ulDummy); 1414 1415 for (i = 0; i < bCnt; i ++) 1416 { 1417 DosRead(pExec->hfExe, 1418 &bFlag, 1419 1, 1420 &ulDummy); 1421 1422 if (bFlag & 0x01) 1423 { 1424 if (paFunctions) 1425 { 1426 paFunctions[usCurrent].ulOrdinal = usOrdinal; 1427 paFunctions[usCurrent].ulType = 1; 1428 paFunctions[usCurrent].achFunctionName[0] = 0; 1429 } 1430 usCurrent++; 1431 } 1432 1433 usOrdinal++; 1434 1435 DosSetFilePtr(pExec->hfExe, 1436 sizeof(USHORT), 1437 FILE_CURRENT, 1438 &ulDummy); 1439 } 1440 break; 1441 1442 /* 1443 * 286 call gate entries 1444 * 1445 * the bundle type is followed by the object number 1446 * and by bCnt bFlag+usOffset+usCallGate entries 1447 * 1448 */ 1449 1450 case 2: 1451 DosSetFilePtr(pExec->hfExe, 1452 sizeof(USHORT), 1453 FILE_CURRENT, 1454 &ulDummy); 1455 1456 for (i = 0; i < bCnt; i ++) 1457 { 1458 DosRead(pExec->hfExe, 1459 &bFlag, 1460 1, 1461 &ulDummy); 1462 1463 if (bFlag & 0x01) 1464 { 1465 if (paFunctions) 1466 { 1467 paFunctions[usCurrent].ulOrdinal = usOrdinal; 1468 paFunctions[usCurrent].ulType = 2; 1469 paFunctions[usCurrent].achFunctionName[0] = 0; 1470 } 1471 usCurrent++; 1472 } 1473 1474 usOrdinal++; 1475 1476 DosSetFilePtr(pExec->hfExe, 1477 sizeof(USHORT) + sizeof(USHORT), 1478 FILE_CURRENT, 1479 &ulDummy); 1480 } 1481 break; 1482 1483 /* 1484 * 32-bit entries 1485 * 1486 * the bundle type is followed by the object number 1487 * and by bCnt bFlag+ulOffset entries 1488 * 1489 */ 1490 1491 case 3: 1492 DosSetFilePtr(pExec->hfExe, 1493 sizeof(USHORT), 1494 FILE_CURRENT, 1495 &ulDummy); 1496 1497 for (i = 0; i < bCnt; i ++) 1498 { 1499 DosRead(pExec->hfExe, 1500 &bFlag, 1501 1, 1502 &ulDummy); 1503 1504 if (bFlag & 0x01) 1505 { 1506 if (paFunctions) 1507 { 1508 paFunctions[usCurrent].ulOrdinal = usOrdinal; 1509 paFunctions[usCurrent].ulType = 3; 1510 paFunctions[usCurrent].achFunctionName[0] = 0; 1511 } 1512 usCurrent++; 1513 } 1514 1515 usOrdinal++; 1516 1517 DosSetFilePtr(pExec->hfExe, 1518 sizeof(ULONG), 1519 FILE_CURRENT, 1520 &ulDummy); 1521 } 1522 break; 1523 1524 /* 1525 * forwarder entries 1526 * 1527 * the bundle type is followed by a reserved word 1528 * and by bCnt bFlag+usModOrd+ulOffsOrdNum entries 1529 * 1530 */ 1531 1532 case 4: 1533 DosSetFilePtr(pExec->hfExe, 1534 sizeof(USHORT), 1535 FILE_CURRENT, 1536 &ulDummy); 1537 1538 for (i = 0; i < bCnt; i ++) 1539 { 1540 DosSetFilePtr(pExec->hfExe, 1541 sizeof(BYTE) + sizeof(USHORT) + sizeof(ULONG), 1542 FILE_CURRENT, 1543 &ulDummy); 1544 1545 if (paFunctions) 1546 { 1547 paFunctions[usCurrent].ulOrdinal = usOrdinal; 1548 paFunctions[usCurrent].ulType = 4; 1549 paFunctions[usCurrent].achFunctionName[0] = 0; 1550 } 1551 usCurrent++; 1552 1553 usOrdinal++; 1554 } 1555 break; 1556 } 1557 } // end while (TRUE) 1558 1559 return (usCurrent); 1560 } 1561 1562 /* 1563 *@@ ScanNEEntryTable: 1564 * returns the number of exported entries in the entry table. 1565 * 1566 * if paFunctions is not NULL, then successive entries are 1567 * filled with the found type and ordinal values. 1568 * 1569 *@@added V0.9.9 (2001-03-30) [lafaix] 1570 */ 1571 1572 ULONG ScanNEEntryTable(PEXECUTABLE pExec, 1573 PFSYSFUNCTION paFunctions) 1574 { 1575 USHORT usOrdinal = 1, 1576 usCurrent = 0; 1577 ULONG ulDummy; 1578 int i; 1579 1580 DosSetFilePtr(pExec->hfExe, 1581 pExec->pNEHeader->usEntryTblOfs 1582 + pExec->pDosExeHeader->ulNewHeaderOfs, 1583 FILE_BEGIN, 1584 &ulDummy); 1585 1586 while (TRUE) 1587 { 1588 BYTE bCnt, 1589 bType, 1590 bFlag; 1591 1592 DosRead(pExec->hfExe, 1593 &bCnt, 1594 1, 1595 &ulDummy); 1596 1597 if (bCnt == 0) 1598 // end of the entry table 1599 break; 1600 1601 DosRead(pExec->hfExe, 1602 &bType, 1603 1, 1604 &ulDummy); 1605 1606 for (i = 0; i < bCnt; i++) 1607 { 1608 DosRead(pExec->hfExe, 1609 &bFlag, 1610 1, 1611 &ulDummy); 1612 1613 if (bFlag & 0x01) 1614 { 1615 if (paFunctions) 1616 { 1617 paFunctions[usCurrent].ulOrdinal = usOrdinal; 1618 paFunctions[usCurrent].ulType = 1; // 16-bit entry 1619 paFunctions[usCurrent].achFunctionName[0] = 0; 1620 } 1621 usCurrent++; 1622 } 1623 1624 usOrdinal++; 1625 1626 if (bType == 0xFF) 1627 // moveable segment 1628 DosSetFilePtr(pExec->hfExe, 1629 5, 1630 FILE_CURRENT, 1631 &ulDummy); 1632 else 1633 // fixed segment 1634 DosSetFilePtr(pExec->hfExe, 1635 2, 1636 FILE_CURRENT, 1637 &ulDummy); 1638 } 1639 } // end while (TRUE) 1640 1641 return (usCurrent); 1642 } 1643 1644 /* 1645 *@@ ScanNameTable: 1646 * scans a resident or non-resident name table, and fills the 1647 * appropriate paFunctions entries when it encounters exported 1648 * entries names. 1649 * 1650 * This functions works for both NE and LX executables. 1651 * 1652 *@@added V0.9.9 (2001-03-30) [lafaix] 1653 */ 1654 1655 VOID ScanNameTable(PEXECUTABLE pExec, 1656 ULONG cFunctions, 1657 PFSYSFUNCTION paFunctions) 1658 { 1659 USHORT usOrdinal; 1660 ULONG ulDummy; 1661 1662 while (TRUE) 1663 { 1664 BYTE bLen; 1665 CHAR achName[128]; 1666 int i; 1667 1668 DosRead(pExec->hfExe, 1669 &bLen, 1670 1, 1671 &ulDummy); 1672 1673 if (bLen == 0) 1674 // end of the name table 1675 break; 1676 1677 bLen &= 0x7F; 1678 1679 DosRead(pExec->hfExe, 1680 &achName, 1681 bLen, 1682 &ulDummy); 1683 achName[bLen] = 0; 1684 1685 DosRead(pExec->hfExe, 1686 &usOrdinal, 1687 sizeof(USHORT), 1688 &ulDummy); 1689 1690 for (i = 0; i < cFunctions; i++) 1691 { 1692 if (paFunctions[i].ulOrdinal == usOrdinal) 1693 { 1694 memcpy(paFunctions[i].achFunctionName, 1695 achName, 1696 bLen+1); 1697 break; 1698 } 1699 } 1700 } 1230 1701 } 1231 1702 … … 1247 1718 PULONG pcFunctions) 1248 1719 { 1249 return (NULL); 1720 ULONG cFunctions = 0; 1721 PFSYSFUNCTION paFunctions = NULL; 1722 1723 if (pExec) 1724 { 1725 if (pExec->ulOS == EXEOS_OS2) 1726 { 1727 ULONG ulDummy; 1728 1729 if (pExec->ulExeFormat == EXEFORMAT_LX) 1730 { 1731 // It's a 32bit OS/2 executable 1732 1733 // the number of exported entry points is not stored 1734 // in the executable header; we have to count them in 1735 // the entry table 1736 1737 cFunctions = ScanLXEntryTable(pExec, NULL); 1738 1739 // we now have the number of exported entries; let us 1740 // build them 1741 1742 if (cFunctions) 1743 { 1744 paFunctions = (PFSYSFUNCTION)malloc(sizeof(FSYSFUNCTION) * cFunctions); 1745 1746 // we rescan the entry table (the cost is not as bad 1747 // as it may seem, due to disk caching) 1748 1749 ScanLXEntryTable(pExec, paFunctions); 1750 1751 // we now scan the resident name table entries 1752 DosSetFilePtr(pExec->hfExe, 1753 pExec->pLXHeader->ulResdNameTblOfs 1754 + pExec->pDosExeHeader->ulNewHeaderOfs, 1755 FILE_BEGIN, 1756 &ulDummy); 1757 1758 ScanNameTable(pExec, cFunctions, paFunctions); 1759 1760 // we now scan the non-resident name table entries, 1761 // whose offset is _from the begining of the file_ 1762 DosSetFilePtr(pExec->hfExe, 1763 pExec->pLXHeader->ulNonResdNameTblOfs, 1764 FILE_BEGIN, 1765 &ulDummy); 1766 1767 ScanNameTable(pExec, cFunctions, paFunctions); 1768 } // end if (cFunctions) 1769 } 1770 else 1771 if (pExec->ulExeFormat == EXEFORMAT_NE) 1772 { 1773 // It's a 16bit OS/2 executable 1774 1775 // here too the number of exported entry points 1776 // is not stored in the executable header; we 1777 // have to count them in the entry table 1778 1779 cFunctions = ScanNEEntryTable(pExec, NULL); 1780 1781 // we now have the number of exported entries; let us 1782 // build them 1783 1784 if (cFunctions) 1785 { 1786 USHORT usOrdinal = 1, 1787 usCurrent = 0; 1788 1789 paFunctions = (PFSYSFUNCTION)malloc(sizeof(FSYSFUNCTION) * cFunctions); 1790 1791 // we rescan the entry table (the cost is not as bad 1792 // as it may seem, due to disk caching) 1793 1794 ScanNEEntryTable(pExec, paFunctions); 1795 1796 // we now scan the resident name table entries 1797 DosSetFilePtr(pExec->hfExe, 1798 pExec->pNEHeader->usResdNameTblOfs 1799 + pExec->pDosExeHeader->ulNewHeaderOfs, 1800 FILE_BEGIN, 1801 &ulDummy); 1802 1803 ScanNameTable(pExec, cFunctions, paFunctions); 1804 1805 // we now scan the non-resident name table entries, 1806 // whose offset is _from the begining of the file_ 1807 DosSetFilePtr(pExec->hfExe, 1808 pExec->pNEHeader->ulNonResdTblOfs, 1809 FILE_BEGIN, 1810 &ulDummy); 1811 1812 ScanNameTable(pExec, cFunctions, paFunctions); 1813 } 1814 } 1815 1816 *pcFunctions = cFunctions; 1817 } 1818 } 1819 1820 return (paFunctions); 1250 1821 } 1251 1822
Note:
See TracChangeset
for help on using the changeset viewer.