Ignore:
Timestamp:
Sep 2, 2000, 11:08:23 PM (25 years ago)
Author:
bird
Message:

Merged in the Grace branch. New Win32k!

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/win32k/pe2lx/pe2lx.cpp

    r2927 r4164  
    1 /* $Id: pe2lx.cpp,v 1.18 2000-02-27 02:18:10 bird Exp $
     1/* $Id: pe2lx.cpp,v 1.19 2000-09-02 21:08:16 bird Exp $
    22 *
    33 * Pe2Lx class implementation. Ring 0 and Ring 3
     
    8181#include <exe386.h>                     /* OS/2 LX structs and definitions. */
    8282
     83#include "devSegDf.h"                   /* Win32k segment definitions. */
     84
    8385#include "malloc.h"                     /* win32k malloc (resident). Not C library! */
    8486#include "smalloc.h"                    /* win32k swappable heap. */
     
    9597#ifdef RING0
    9698    #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. */
    97102#endif
    98103#include "modulebase.h"                 /* ModuleBase class definitions, ++. */
     
    100105#include <versionos2.h>                 /* Pe2Lx version. */
    101106#include "yield.h"                      /* Yield CPU. */
     107#include "options.h"                    /* Win32k options. */
    102108
    103109
     
    169175    {NULL,                                 NULL} /* end-of-list entry */
    170176};
     177
     178LONG            Pe2Lx::cLoadedModules;  /* Count of existing objects. Updated by constructor and destructor. */
     179const char *    Pe2Lx::pszOdin32Path;   /* Odin32 base path (include a slash). */
     180ULONG           Pe2Lx::cchOdin32Path;   /* Odin32 base path length. */
     181SFN             Pe2Lx::sfnKernel32;     /* Odin32 Kernel32 filehandle. */
    171182
    172183
     
    205216    LXHdr.e32_pagesize  = PAGESIZE;
    206217    LXHdr.e32_objtab    = sizeof(LXHdr);
     218    cLoadedModules++;
    207219}
    208220
     
    277289    _res_heapmin();
    278290    _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
    279305}
    280306
     
    457483        dumpSectionHeader(&paSections[i]);
    458484
    459         /* 8a. Convert characteristics to flags */
     485        /* 8a. Convert characteristics to flags and check/fix incompatible flags! */
    460486        for (j = 0; j < (sizeof(paSecChars2Flags)/sizeof(paSecChars2Flags[0])); j++)
    461487            if ((paSections[i].Characteristics & paSecChars2Flags[j].Characteristics) == paSecChars2Flags[j].Characteristics)
    462488                flFlags |= paSecChars2Flags[j].flFlags;
     489        if ((flFlags & (OBJEXEC | OBJWRITE)) == (OBJEXEC | OBJWRITE))
     490            flFlags &= (ULONG)~OBJEXEC;
    463491
    464492        /* 8b. Virtual/physical size */
     
    529557    /* 11.Align section. (Fix which is applied to EXEs/Dlls which contain no fixups and has an
    530558     *    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. */
    531560    fAllInOneObject = (pNtHdrs->FileHeader.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) == IMAGE_FILE_RELOCS_STRIPPED;
    532561    if (fAllInOneObject)
     
    657686    Yield();
    658687    _res_heapmin();
    659     #if 0 /* testing */
     688    #ifndef RING0
     689    #if 1 /* testing */
    660690    testApplyFixups();
     691    #endif
    661692    #endif
    662693
     
    670701 * @param     pvBuffer   Pointer to buffer where data is to be put.
    671702 * @param     cbToRead   Bytes to be read.
    672  * @param     flFlag     Flags which was spesified to the ldrRead call.
     703 * @param     fpBuffer   Flags which was spesified to the ldrRead call.
    673704 * @parma     pMTE       Pointer to MTE which was specified to the ldrRead call.
    674705 * @return    NO_ERROR if successful something else if not.
     
    676707 * @author    knut st. osmundsen
    677708 */
    678 ULONG Pe2Lx::read(ULONG offLXFile, PVOID pvBuffer, ULONG cbToRead, ULONG flFlags, PMTE pMTE)
     709ULONG Pe2Lx::read(ULONG offLXFile, PVOID pvBuffer, ULONG fpBuffer, ULONG cbToRead, PMTE pMTE)
    679710{
    680711    APIRET rc = NO_ERROR;   /* Return code. */
     
    696727    #endif
    697728
    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));
    699730
    700731    /* Could we skip right to the datapages? */
     
    931962            /* calc PE offset and size of read. */
    932963            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);
    934965        }
    935966        else
     
    938969            {   /* before TIBFix code. */
    939970                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);
    941972            }
    942973            else
     
    959990    }
    960991
    961     NOREF(flFlags);
     992    NOREF(fpBuffer);
    962993    NOREF(pMTE);
    963994    return rc;
     
    10771108
    10781109        while ((unsigned)pbr - (unsigned)pBaseRelocs + 8 < cbBaseRelocs /* 8= VirtualAddress and SizeOfBlock members */
     1110               && pbr->SizeOfBlock >= 8
    10791111               && pbr->VirtualAddress < ulRVAPage + PAGESIZE)
    10801112        {
     
    12811313
    12821314
     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 */
     1338ULONG  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 */
     1383ULONG  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
    12831604#ifndef RING0
    12841605/**
     
    13131634    }
    13141635
    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    }
    13301660
    13311661    return rc;
     
    13811711        {
    13821712            ULONG cbToRead = min(cbLXFile, sizeof(achReadBuffer));
    1383             rc = read(offLXFile, &achReadBuffer[0], cbToRead, 0UL, NULL);
     1713            rc = read(offLXFile, &achReadBuffer[0], 0UL, cbToRead, NULL);
    13841714            if (rc != NO_ERROR)
    13851715            {
     
    14111741}
    14121742#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 */
     1752BOOL    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 */
     1765BOOL    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 */
     1778VOID Pe2Lx::invalidateOdin32Path()
     1779{
     1780    if (pszOdin32Path != NULL)
     1781    {
     1782        rfree((void*)pszOdin32Path);
     1783        pszOdin32Path = NULL;
     1784    }
     1785    sfnKernel32 = NULLHANDLE;
     1786}
    14131787
    14141788
     
    27553129            {
    27563130                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)
    27583133                {
    27593134                    if ((unsigned)pbrCur->SizeOfBlock + (unsigned)pbrCur > (unsigned)pBaseRelocs + cbBaseRelocs)
     
    43324707
    43334708
     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 */
     4730BOOL 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 */
     4811BOOL 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
    43344854/**
    43354855 * Static method which dumps a set of nt headers.
Note: See TracChangeset for help on using the changeset viewer.