Changeset 4164 for trunk/src/win32k/pe2lx/pe2lx.cpp
- Timestamp:
- Sep 2, 2000, 11:08:23 PM (25 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/win32k/pe2lx/pe2lx.cpp
r2927 r4164 1 /* $Id: pe2lx.cpp,v 1.1 8 2000-02-27 02:18:10bird Exp $1 /* $Id: pe2lx.cpp,v 1.19 2000-09-02 21:08:16 bird Exp $ 2 2 * 3 3 * Pe2Lx class implementation. Ring 0 and Ring 3 … … 81 81 #include <exe386.h> /* OS/2 LX structs and definitions. */ 82 82 83 #include "devSegDf.h" /* Win32k segment definitions. */ 84 83 85 #include "malloc.h" /* win32k malloc (resident). Not C library! */ 84 86 #include "smalloc.h" /* win32k swappable heap. */ … … 95 97 #ifdef RING0 96 98 #include "ldrCalls.h" /* ldr* calls. (ldrRead) */ 99 #include "avl.h" /* AVL tree. (ldr.h need it) */ 100 #include "ldr.h" /* ldr helpers. (ldrGetExePath) */ 101 #include "env.h" /* Environment helpers. */ 97 102 #endif 98 103 #include "modulebase.h" /* ModuleBase class definitions, ++. */ … … 100 105 #include <versionos2.h> /* Pe2Lx version. */ 101 106 #include "yield.h" /* Yield CPU. */ 107 #include "options.h" /* Win32k options. */ 102 108 103 109 … … 169 175 {NULL, NULL} /* end-of-list entry */ 170 176 }; 177 178 LONG Pe2Lx::cLoadedModules; /* Count of existing objects. Updated by constructor and destructor. */ 179 const char * Pe2Lx::pszOdin32Path; /* Odin32 base path (include a slash). */ 180 ULONG Pe2Lx::cchOdin32Path; /* Odin32 base path length. */ 181 SFN Pe2Lx::sfnKernel32; /* Odin32 Kernel32 filehandle. */ 171 182 172 183 … … 205 216 LXHdr.e32_pagesize = PAGESIZE; 206 217 LXHdr.e32_objtab = sizeof(LXHdr); 218 cLoadedModules++; 207 219 } 208 220 … … 277 289 _res_heapmin(); 278 290 _swp_heapmin(); 291 292 /* 293 * If no Pe2Lx objects left, then invalidate the Odin32Path. 294 * We'll have to do this since we may (theoretically) not receive 295 * a close on a kernel32 handle if loading failes before kernel32 296 * is loaded and the odin32path is determined using ldrOpenPath. 297 * (Ie. no sfnKernel32.) 298 */ 299 if (--cLoadedModules <= 0) 300 invalidateOdin32Path(); 301 #ifdef DEBUG 302 if (cLoadedModules < 0) 303 printIPE(("Pe2Lx::cLoadedModules is %d which is less that zero!\n", cLoadedModules)); 304 #endif 279 305 } 280 306 … … 457 483 dumpSectionHeader(&paSections[i]); 458 484 459 /* 8a. Convert characteristics to flags */485 /* 8a. Convert characteristics to flags and check/fix incompatible flags! */ 460 486 for (j = 0; j < (sizeof(paSecChars2Flags)/sizeof(paSecChars2Flags[0])); j++) 461 487 if ((paSections[i].Characteristics & paSecChars2Flags[j].Characteristics) == paSecChars2Flags[j].Characteristics) 462 488 flFlags |= paSecChars2Flags[j].flFlags; 489 if ((flFlags & (OBJEXEC | OBJWRITE)) == (OBJEXEC | OBJWRITE)) 490 flFlags &= (ULONG)~OBJEXEC; 463 491 464 492 /* 8b. Virtual/physical size */ … … 529 557 /* 11.Align section. (Fix which is applied to EXEs/Dlls which contain no fixups and has an 530 558 * alignment which is not a multiple of 64Kb. The sections are concatenated into one big object. */ 559 /* TODO! this test has to be enhanced a bit. WWPack32, new Borland++ depends on image layout. */ 531 560 fAllInOneObject = (pNtHdrs->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) == IMAGE_FILE_RELOCS_STRIPPED; 532 561 if (fAllInOneObject) … … 657 686 Yield(); 658 687 _res_heapmin(); 659 #if 0 /* testing */ 688 #ifndef RING0 689 #if 1 /* testing */ 660 690 testApplyFixups(); 691 #endif 661 692 #endif 662 693 … … 670 701 * @param pvBuffer Pointer to buffer where data is to be put. 671 702 * @param cbToRead Bytes to be read. 672 * @param f lFlagFlags which was spesified to the ldrRead call.703 * @param fpBuffer Flags which was spesified to the ldrRead call. 673 704 * @parma pMTE Pointer to MTE which was specified to the ldrRead call. 674 705 * @return NO_ERROR if successful something else if not. … … 676 707 * @author knut st. osmundsen 677 708 */ 678 ULONG Pe2Lx::read(ULONG offLXFile, PVOID pvBuffer, ULONG cbToRead, ULONG flFlags, PMTE pMTE)709 ULONG Pe2Lx::read(ULONG offLXFile, PVOID pvBuffer, ULONG fpBuffer, ULONG cbToRead, PMTE pMTE) 679 710 { 680 711 APIRET rc = NO_ERROR; /* Return code. */ … … 696 727 #endif 697 728 698 printInf((" read(%d, 0x%08x, %d, 0x%08x)\n", offLXFile, pvBuffer, cbToRead, flFlags));729 printInf(("Pe2Lx::read(%d, 0x%08x, 0x%08x, %d)\n", offLXFile, pvBuffer, fpBuffer, cbToRead)); 699 730 700 731 /* Could we skip right to the datapages? */ … … 931 962 /* calc PE offset and size of read. */ 932 963 cbReadVar = min(paObjects[iObj].cbPhysical - offObject, cbToRead); 933 rc = ReadAtF(hFile, offPEFile, pvBuffer, cbReadVar, flFlags, pMTE);964 rc = ReadAtF(hFile, offPEFile, pvBuffer, fpBuffer, cbReadVar, pMTE); 934 965 } 935 966 else … … 938 969 { /* before TIBFix code. */ 939 970 cbReadVar = min(paObjects[iObj].Misc.offTIBFix - offObject, cbToRead); 940 rc = ReadAtF(hFile, offPEFile, pvBuffer, cbReadVar, flFlags, pMTE);971 rc = ReadAtF(hFile, offPEFile, pvBuffer, fpBuffer, cbReadVar, pMTE); 941 972 } 942 973 else … … 959 990 } 960 991 961 NOREF(f lFlags);992 NOREF(fpBuffer); 962 993 NOREF(pMTE); 963 994 return rc; … … 1077 1108 1078 1109 while ((unsigned)pbr - (unsigned)pBaseRelocs + 8 < cbBaseRelocs /* 8= VirtualAddress and SizeOfBlock members */ 1110 && pbr->SizeOfBlock >= 8 1079 1111 && pbr->VirtualAddress < ulRVAPage + PAGESIZE) 1080 1112 { … … 1281 1313 1282 1314 1315 /** 1316 * openPath - opens file eventually searching loader specific paths. 1317 * This method is only called for DLLs. (DosLoadModule and Imports.) 1318 * 1319 * 1320 * @returns OS2 return code. 1321 * pLdrLv->lv_sfn is set to filename handle. 1322 * @param pachFilename Pointer to filename. Not zero terminated! 1323 * @param cchFilename Filename length. 1324 * @param pLdrLv Loader local variables? (Struct from KERNEL.SDF) 1325 * @param pful Pointer to flags which are passed on to ldrOpen. 1326 * @sketch 1327 * This is roughly what the original ldrOpenPath does: 1328 * if !CLASS_GLOBAL or miniifs then 1329 * ldrOpen(pachModName) 1330 * else 1331 * loop until no more libpath elements 1332 * get next libpath element and add it to the modname. 1333 * try open the modname 1334 * if successfull then break the loop. 1335 * endloop 1336 * endif 1337 */ 1338 ULONG Pe2Lx::openPath(PCHAR pachFilename, USHORT cchFilename, ldrlv_t *pLdrLv, PULONG pful) /* (ldrOpenPath) */ 1339 { 1340 #ifdef RING0 1341 1342 /* 1343 * Mark the SFN invalid in the case of error. 1344 * Initiate the Odin32 Path static variable and call worker. 1345 */ 1346 return openPath2(pachFilename, cchFilename, pLdrLv, pful, initOdin32Path()); 1347 1348 #else 1349 NOREF(pachFilename); 1350 NOREF(cchFilename); 1351 NOREF(pLdrLv); 1352 NOREF(pful); 1353 return ERROR_NOT_SUPPORTED; 1354 #endif 1355 } 1356 1357 1358 /** 1359 * openPath2 - Worker for openPath which is also used by initOdin32Path. 1360 * 1361 * @returns OS2 return code. 1362 * pLdrLv->lv_sfn is set to filename handle. 1363 * @param pachFilename Pointer to filename. Not zero terminated! 1364 * @param cchFilename Filename length. 1365 * @param pLdrLv Loader local variables? (Struct from KERNEL.SDF) 1366 * @param pful Pointer to flags which are passed on to ldrOpen. 1367 * @param fOdin32PathValid Flag indicating that the pszOdin32Path is valid or not. 1368 * @sketch 1369 * This is roughly what the original ldrOpenPath does: 1370 * if !CLASS_GLOBAL or miniifs then 1371 * ldrOpen(pachModName) 1372 * else 1373 * loop until no more libpath elements 1374 * get next libpath element and add it to the modname. 1375 * try open the modname 1376 * if successfull then break the loop. 1377 * endloop 1378 * endif 1379 * @remark cchFilename has to be ULONG due to an optimization bug in VA 3.08. 1380 * (cchFilename should have been USHORT. But, then the compiler would 1381 * treat it as an ULONG.) 1382 */ 1383 ULONG Pe2Lx::openPath2(PCHAR pachFilename, ULONG cchFilename, ldrlv_t *pLdrLv, PULONG pful, BOOL fOdin32PathValid) 1384 { 1385 #ifdef RING0 1386 1387 APIRET rc; /* Returncode. */ 1388 ULONG cchExt; /* Count of chars in additional extention. (0 if extention exists.) */ 1389 1390 /* These defines sets the order the paths and pathlists are examined. */ 1391 #define FINDDLL_EXECUTABLEDIR 1 1392 #define FINDDLL_CURRENTDIR 2 1393 #define FINDDLL_SYSTEM32DIR 3 1394 #define FINDDLL_SYSTEM16DIR 4 1395 #define FINDDLL_WINDIR 5 1396 #define FINDDLL_PATH 6 1397 #define FINDDLL_BEGINLIBPATH 7 /* uses ldrOpenPath */ 1398 #define FINDDLL_LIBPATH 8 /* uses ldrOpenPath */ 1399 #define FINDDLL_ENDLIBPATH 9 /* uses ldrOpenPath */ 1400 #define FINDDLL_FIRST FINDDLL_EXECUTABLEDIR 1401 #define FINDDLL_LAST FINDDLL_PATH 1402 1403 struct _LocalVars 1404 { 1405 char sz[CCHMAXPATH]; 1406 char szPath[CCHMAXPATH]; 1407 } *pVars; 1408 1409 1410 /** @sketch 1411 * Mark the SFN invalid in the case of error. 1412 * Allocate memory for local variables. 1413 * Check for extention. 1414 */ 1415 pLdrLv->lv_sfn = 0xffff; 1416 pVars = (struct _LocalVars*)rmalloc(sizeof(struct _LocalVars)); 1417 if (pVars == NULL) 1418 return ERROR_NOT_ENOUGH_MEMORY; 1419 1420 cchExt = cchFilename - 1; 1421 while (cchExt != 0 && pachFilename[cchExt] != '.') 1422 cchExt--; 1423 cchExt = cchExt != 0 ? 0 : 4; 1424 1425 1426 /** @sketch 1427 * Loop thru the paths and pathlists searching them for the filename. 1428 */ 1429 for (int iPath = FINDDLL_FIRST; iPath <= FINDDLL_LAST; iPath++) 1430 { 1431 char * pszPath; /* Pointer to the path being examined. */ 1432 1433 /** @sketch 1434 * Get the path/dir to examin. (This is determined by the value if iPath.) 1435 */ 1436 switch (iPath) 1437 { 1438 case FINDDLL_EXECUTABLEDIR: 1439 if ((pszPath = ldrGetExePath(pVars->szPath, TRUE)) == NULL) 1440 continue; 1441 break; 1442 1443 case FINDDLL_CURRENTDIR: 1444 pszPath = "."; 1445 break; 1446 1447 case FINDDLL_SYSTEM32DIR: 1448 if (!fOdin32PathValid) 1449 continue; 1450 pszPath = pVars->szPath; 1451 strcpy(pszPath, pszOdin32Path); 1452 strcpy(pszPath + cchOdin32Path, "System32"); 1453 break; 1454 1455 case FINDDLL_SYSTEM16DIR: 1456 if (!fOdin32PathValid) 1457 continue; 1458 pszPath = pVars->szPath; 1459 strcpy(pszPath, pszOdin32Path); 1460 strcpy(pszPath + cchOdin32Path, "System"); 1461 break; 1462 1463 case FINDDLL_WINDIR: 1464 if (!fOdin32PathValid) 1465 continue; 1466 pszPath = pVars->szPath; 1467 strcpy(pszPath, pszOdin32Path); 1468 pszPath[cchOdin32Path - 1] = '\0'; /* remove slash */ 1469 break; 1470 1471 case FINDDLL_PATH: 1472 pszPath = (char*)GetEnv(TRUE); 1473 if (pszPath == NULL) 1474 continue; 1475 pszPath = (char*)ScanEnv(pszPath, "PATH"); 1476 break; 1477 1478 #if 0 1479 case FINDDLL_BEGINLIBPATH: 1480 pszPath = ptda_GetBeginLibpath()... ; 1481 if (pszPath == NULL) 1482 continue; 1483 break; 1484 1485 case FINDDLL_LIBPATH: 1486 pszPath = *pLdrLibPath; 1487 break; 1488 1489 case FINDDLL_ENDLIBPATH: 1490 pszPath = ptda_GetEndLibpath()... ; 1491 if (pszPath == NULL) 1492 continue; 1493 break; 1494 #endif 1495 default: /* !internalerror! */ 1496 printIPE(("Pe2Lx::openPath(%.*s,..): iPath is %d which is invalid.\n", cchFilename, pachFilename, iPath)); 1497 rfree(pVars); 1498 return ERROR_FILE_NOT_FOUND; 1499 } 1500 1501 1502 /** @sketch 1503 * pszPath is now set to the pathlist to be searched. 1504 * So we'll loop thru all the paths in the list. 1505 */ 1506 while (pszPath != NULL && *pszPath != '\0') 1507 { 1508 char * pszNext; /* Pointer to the next pathlist path */ 1509 int cch; /* Length of path (including the slash after the slash is added). */ 1510 1511 /** @sketch 1512 * Find the end of the path and set pszNext. 1513 * Uncount any trailing slash. 1514 * Check that the filename fits within the buffer (and OS/2 filelength limits). 1515 */ 1516 pszNext = strchr(pszPath, ';'); 1517 if (pszNext != NULL) 1518 { 1519 cch = pszNext - pszPath; 1520 pszNext++; 1521 } 1522 else 1523 cch = strlen(pszPath); 1524 1525 if (pszPath[cch - 1] == '\\' || pszPath[cch-1] == '/') 1526 cch--; 1527 1528 if (cch == 0 || cch + cchFilename + 2 + cchExt > sizeof(pVars->sz)) /* assertion */ 1529 { 1530 printErr(("Pe2Lx::openPath(%.*s,..): cch (%d) + cchFilename (%d) + 2 + cchExt (%d) > sizeof(pVars->sz) (%d) - path's too long!, iPath=%d", 1531 cchFilename, pachFilename, cch, cchExt, cchFilename, sizeof(pVars->sz), iPath)); 1532 1533 pszPath = pszNext; 1534 continue; 1535 } 1536 1537 1538 /** @sketch 1539 * Copy the path into the pVars->sz buffer. 1540 * Add a '\\' and the filename (pszFullname) to the path; 1541 * then we'll have a fullpath. 1542 */ 1543 memcpy(pVars->sz, pszPath, cch); 1544 pVars->sz[cch++] = '\\'; 1545 memcpy(&pVars->sz[cch], pachFilename, (size_t)cchFilename); 1546 if (cchExt != 0) 1547 memcpy(&pVars->sz[cch + cchFilename], ".DLL", 5); 1548 else 1549 pVars->sz[cch + cchFilename] = '\0'; 1550 1551 1552 /** @sketch 1553 * Try open the file using myLdrOpen. 1554 * Return if successfully opened or if fatal error. 1555 */ 1556 rc = myldrOpen(&pLdrLv->lv_sfn, pVars->sz, pful); 1557 switch (rc) 1558 { 1559 /* these errors are ignored (not fatal) */ 1560 case ERROR_FILE_NOT_FOUND: case ERROR_PATH_NOT_FOUND: case ERROR_ACCESS_DENIED: case ERROR_INVALID_ACCESS: 1561 case ERROR_INVALID_DRIVE: case ERROR_NOT_DOS_DISK: case ERROR_REM_NOT_LIST: case ERROR_BAD_NETPATH: 1562 case ERROR_NETWORK_BUSY: case ERROR_DEV_NOT_EXIST: case ERROR_TOO_MANY_CMDS: case ERROR_ADAP_HDW_ERR: 1563 case ERROR_UNEXP_NET_ERR: case ERROR_BAD_REM_ADAP: case ERROR_NETNAME_DELETED: case ERROR_BAD_DEV_TYPE: 1564 case ERROR_NETWORK_ACCESS_DENIED: case ERROR_BAD_NET_NAME: case ERROR_TOO_MANY_SESS: case ERROR_REQ_NOT_ACCEP: 1565 case ERROR_INVALID_PASSWORD: case ERROR_OPEN_FAILED: case ERROR_INVALID_NAME: case ERROR_FILENAME_EXCED_RANGE: 1566 case ERROR_VC_DISCONNECTED: 1567 rc = ERROR_FILE_NOT_FOUND; 1568 pszPath = pszNext; 1569 break; 1570 1571 /* all errors and success is let out here */ 1572 case NO_ERROR: 1573 default: 1574 rfree(pVars); 1575 return rc; 1576 } 1577 1578 /** @sketch 1579 * Advance to the next path part 1580 */ 1581 pszPath = pszNext; 1582 } 1583 } /* for iPath */ 1584 1585 1586 /* 1587 * Cleanup: free local variables. 1588 * Since we haven't found the file yet we'll return thru ldrOpenPath. 1589 */ 1590 rfree(pVars); 1591 return ldrOpenPath(pachFilename, (USHORT)cchFilename, pLdrLv, pful); 1592 1593 #else 1594 NOREF(pachFilename); 1595 NOREF(cchFilename); 1596 NOREF(pLdrLv); 1597 NOREF(pful); 1598 NOREF(fOdin32PathValid); 1599 return ERROR_NOT_SUPPORTED; 1600 #endif 1601 } 1602 1603 1283 1604 #ifndef RING0 1284 1605 /** … … 1313 1634 } 1314 1635 1315 rc = readAtRVA(0x00000000, &achPage[0], PAGESIZE); 1316 if (rc != NO_ERROR) 1317 { 1318 printErr(("readAtRVA failed with rc=%d\n")); 1319 return rc; 1320 } 1321 rc = applyFixups(&mte, 0, ~0UL, &achPage[0], 0x125D0000, NULL); 1322 1323 rc = readAtRVA(0x00001000, &achPage[0], PAGESIZE); 1324 if (rc != NO_ERROR) 1325 { 1326 printErr(("readAtRVA failed with rc=%d\n")); 1327 return rc; 1328 } 1329 rc = applyFixups(&mte, 1, 1, &achPage[0], 0x125E0000, NULL); 1636 /* 1637 * Test load and apply all (internal) fixups. 1638 */ 1639 for (i = 0; i < cObjects; i++) 1640 { 1641 ULONG ulAddress = smte.smte_objtab[i].ote_base; 1642 ULONG ulRVA = paObjects[i].ulRVA; 1643 LONG cbObject = paObjects[i].cbVirtual; 1644 for (i=i; cbObject > 0; cbObject -= PAGESIZE, ulAddress += PAGESIZE, ulRVA += PAGESIZE) 1645 { 1646 rc = readAtRVA(ulRVA, &achPage[0], PAGESIZE); 1647 if (rc != NO_ERROR) 1648 { 1649 printErr(("readAtRVA failed with rc=%d\n")); 1650 return rc; 1651 } 1652 rc = applyFixups(&mte, 1, 1, &achPage[0], ulAddress, NULL); 1653 if (rc != NO_ERROR) 1654 { 1655 printErr(("applyFixups failed with rc=%d\n")); 1656 return rc; 1657 } 1658 } 1659 } 1330 1660 1331 1661 return rc; … … 1381 1711 { 1382 1712 ULONG cbToRead = min(cbLXFile, sizeof(achReadBuffer)); 1383 rc = read(offLXFile, &achReadBuffer[0], cbToRead, 0UL, NULL);1713 rc = read(offLXFile, &achReadBuffer[0], 0UL, cbToRead, NULL); 1384 1714 if (rc != NO_ERROR) 1385 1715 { … … 1411 1741 } 1412 1742 #endif 1743 1744 1745 /** 1746 * Is this module an executable? 1747 * @returns TRUE if executable. 1748 * FALSE if not an executable. 1749 * @sketch 1750 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no) 1751 */ 1752 BOOL Pe2Lx::isExe() 1753 { 1754 return ((this->LXHdr.e32_mflags & E32MODMASK) == E32MODEXE); 1755 } 1756 1757 1758 /** 1759 * Is this module an dynamic link library. 1760 * @returns TRUE if dynamic link library. 1761 * FALSE if not a dynamic link library. 1762 * @sketch 1763 * @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no) 1764 */ 1765 BOOL Pe2Lx::isDll() 1766 { 1767 return ((this->LXHdr.e32_mflags & E32MODMASK) == E32MODDLL); 1768 } 1769 1770 1771 /** 1772 * Invalidates the odin32path. 1773 * Called by ldrClose when the kernel32 handle is closed. 1774 * @sketch Free path 1775 * nullify path pointer and kernel32 handle. 1776 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no) 1777 */ 1778 VOID Pe2Lx::invalidateOdin32Path() 1779 { 1780 if (pszOdin32Path != NULL) 1781 { 1782 rfree((void*)pszOdin32Path); 1783 pszOdin32Path = NULL; 1784 } 1785 sfnKernel32 = NULLHANDLE; 1786 } 1413 1787 1414 1788 … … 2755 3129 { 2756 3130 PIMAGE_BASE_RELOCATION pbrCur = pBaseRelocs; 2757 while ((void*)pbrCur < (void*)((unsigned)pBaseRelocs + cbBaseRelocs)) 3131 while ((void*)pbrCur < (void*)((unsigned)pBaseRelocs + cbBaseRelocs) 3132 && pbrCur->SizeOfBlock >= 8) 2758 3133 { 2759 3134 if ((unsigned)pbrCur->SizeOfBlock + (unsigned)pbrCur > (unsigned)pBaseRelocs + cbBaseRelocs) … … 4332 4707 4333 4708 4709 4710 /** 4711 * Initiates the odin32path. 4712 * @returns Success indicator. 4713 * @sketch If allready inited ok Then do nothing return TRUE. 4714 * 4715 * Check if KERNEL32 is loaded using ldrFindModule. 4716 * If loaded then set path according to the smte_path and return. 4717 * 4718 * If the path is set to something then return TRUE. (ie. the following method is allready applied.) 4719 * 4720 * Use odinPath2 to locate the KERNEL32 module in the LIBPATHs. The 4721 * win32k loaders are temporarily disabled. Path is returned in 4722 * the ldrpFileNameBuf buffer. 4723 * If found the Then set path according to ldrpFileNameBuf and return 4724 * 4725 * Fail returning FALSE. 4726 * @status 4727 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no) 4728 * @remark 4729 */ 4730 BOOL Pe2Lx::initOdin32Path() 4731 { 4732 #ifdef RING0 4733 APIRET rc; 4734 PMTE pMTE; 4735 4736 4737 if (sfnKernel32 != NULLHANDLE) 4738 return TRUE; 4739 4740 /* 4741 * Try find it using ldrFindModule. 4742 */ 4743 pMTE = NULL; 4744 rc = ldrFindModule("KERNEL32", 8, CLASS_GLOBAL, (PPMTE)SSToDS(&pMTE)); 4745 if (rc == NO_ERROR && pMTE != NULL && pMTE->mte_swapmte != NULL) 4746 { 4747 /* 4748 * We now take the smte_path. Start at the end and skip the filename, 4749 * and one directory up. We assume a fully qualified path is found in 4750 * smte_path. 4751 */ 4752 if (pMTE->mte_swapmte->smte_path != NULL)//paranoia 4753 { 4754 sfnKernel32 = pMTE->mte_sfn; 4755 return setOdin32Path(pMTE->mte_swapmte->smte_path); 4756 } 4757 } 4758 4759 4760 /* 4761 * KERNEL32 isn't loaded. We'll only search the paths if 4762 */ 4763 if (pszOdin32Path != NULL) 4764 return TRUE; 4765 4766 4767 /* 4768 * Try find it searching the LIBPATHs. 4769 * 4770 * For the time being: 4771 * We'll use odinPath2 to do this, but we'll have to 4772 * disable the win32k.sys overloading temporarily. 4773 */ 4774 ldrlv_t lv = {0}; 4775 ULONG ful = 0; 4776 ULONG ul; 4777 4778 ul = options.fNoLoader; 4779 options.fNoLoader = TRUE; 4780 lv.lv_class = CLASS_GLOBAL; 4781 rc = openPath2("KERNEL32", 8, (ldrlv_t*)SSToDS(&lv), (PULONG)SSToDS(&ful), FALSE); 4782 options.fNoLoader = ul; 4783 if (rc == NO_ERROR) 4784 { 4785 /* 4786 * Set the odin32path according to the kernel32 path we've found. 4787 * (ldrOpen sets ldrpFileNameBuf to the fully qualified path of 4788 * the last opended filed, which in this case is kernel32.dll.) 4789 * We'll close the file handle first of course. 4790 */ 4791 rc = setOdin32Path(ldrpFileNameBuf); 4792 ldrClose(lv.lv_sfn); 4793 return rc; 4794 } 4795 4796 #endif 4797 return FALSE; 4798 } 4799 4800 4801 4802 /** 4803 * Sets the Odin32Path to the given fully qualified filename of kernel32. 4804 * @returns Success indicator. 4805 * @param psz Fully qualified filename of kernel32 with path. 4806 * @sketch 4807 * @status 4808 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no) 4809 * @remark 4810 */ 4811 BOOL Pe2Lx::setOdin32Path(const char *psz) 4812 { 4813 const char * psz2; 4814 4815 /* 4816 * We now take the psz. Start at the end and skip the filename, 4817 * and one directory up. We assume a fully qualified path. 4818 */ 4819 psz2 = psz + strlen(psz) - 1; 4820 while (psz2 > psz && *psz2 != '\\' && *psz2 != '/' && *psz2 != ':') 4821 psz2--; 4822 psz2--; 4823 while (psz2 > psz && *psz2 != '\\' && *psz2 != '/' && *psz2 != ':') 4824 psz2--; 4825 if (psz2 > psz) 4826 { 4827 char *pszPath; 4828 /* 4829 * Free old path (if any) and allocate space for a new path. 4830 * Copy the path including the slash. 4831 * Remember the kernel32 filehandle (to be able to invalidate the path). 4832 */ 4833 if (pszOdin32Path) 4834 rfree((void*)pszOdin32Path); 4835 if (*psz2 == ':') //in case someone installed odin in a root directory. 4836 psz2++; 4837 psz2++; //include the slash 4838 cchOdin32Path = psz2 - psz; 4839 pszPath = (char*)rmalloc((size_t)cchOdin32Path); 4840 if (pszPath == NULL) return FALSE; 4841 memcpy(pszPath, psz, (size_t)cchOdin32Path); 4842 pszPath[cchOdin32Path] = '\0'; 4843 pszOdin32Path = pszPath; 4844 4845 return TRUE; 4846 } 4847 4848 return FALSE; 4849 } 4850 4851 4852 4853 4334 4854 /** 4335 4855 * Static method which dumps a set of nt headers.
Note:
See TracChangeset
for help on using the changeset viewer.