Ignore:
Timestamp:
Jan 15, 2004, 11:39:15 AM (22 years ago)
Author:
sandervl
Message:

Loader updates

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kernel32/winimagepe2lx.cpp

    r9537 r10397  
    1 /* $Id: winimagepe2lx.cpp,v 1.21 2002-12-20 11:39:42 sandervl Exp $ */
     1/* $Id: winimagepe2lx.cpp,v 1.22 2004-01-15 10:39:12 sandervl Exp $ */
    22
    33/*
     
    3535#include <misc.h>
    3636#include "winimagebase.h"
     37#include "windllbase.h"
     38#include "winexebase.h"
    3739#include "winimagepe2lx.h"
     40#include "winimagepeldr.h"
     41#include "windllpeldr.h"
     42#include "winimagelx.h"
     43#include "windlllx.h"
    3844#include "Win32k.h"
    3945
     
    259265    hinstance = (HINSTANCE)paSections[0].ulAddress;
    260266
     267    /* Set poh & pExportDir (base class stuff) */
     268    poh = &pNtHdrs->OptionalHeader;
     269    pExportDir = (PIMAGE_EXPORT_DIRECTORY)getPointerFromRVA(pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
     270
    261271    /* Locate and set the entrypoint. */
    262272    setEntryPoint((ULONG)getPointerFromRVA(pNtHdrs->OptionalHeader.AddressOfEntryPoint));
     
    272282
    273283    /* Locate the resource directory (if any) */
    274     if (pNtHdrs->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_RESOURCE
    275         && pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress > 0UL)
    276     {
    277         ulRVAResourceSection = pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
    278         pResRootDir = (PIMAGE_RESOURCE_DIRECTORY)getPointerFromRVA(ulRVAResourceSection);
    279         /* _temporary_ fix:
    280          *  We'll have to make the resource section writable.
    281          *  And we'll have to make the pages before it readable.
    282          */
    283         LONG iSection = getSectionIndexFromRVA(ulRVAResourceSection);
    284         if (iSection >= 0)
    285         {
    286             rc = DosSetMem((PVOID)paSections[iSection].ulAddress, paSections[iSection].cbVirtual, PAG_WRITE | PAG_READ);
    287 
    288             ULONG ulAddr = paSections[iSection].ulAddress - 0x10000; //64KB
    289             while (ulAddr < paSections[iSection].ulAddress)
    290             {
    291                 ULONG fl = ~0UL;
    292                 ULONG cb = ~0UL;
    293                 rc = DosQueryMem((PVOID)ulAddr, &cb, &fl);
    294                 if (rc == NO_ERROR)
    295                 {
    296                     if (fl & PAG_GUARD)
    297                         rc = -1;
    298                     else if (fl & PAG_COMMIT)
    299                         fl &= ~(PAG_COMMIT);
    300                     else
    301                         fl |= PAG_COMMIT;
    302                     cb = (cb + 0xfffUL) & ~0xfffUL;
    303                 }
    304                 else
    305                 {
    306                     fl = PAG_COMMIT;
    307                     cb = 0x1000;
    308                 }
    309                 fl &= PAG_READ | PAG_COMMIT | PAG_WRITE | PAG_GUARD;
    310                 fl |= PAG_READ;
    311                 if (cb > paSections[iSection].ulAddress - ulAddr)
    312                     cb = paSections[iSection].ulAddress - ulAddr;
    313                 if (rc == NO_ERROR)
    314                     rc = DosSetMem((PVOID)ulAddr, cb, fl);
    315 
    316                 ulAddr += cb;
    317             }
    318         }
    319     }
    320 
    321     /* TLS - Thread Local Storage */
    322     if (pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress != 0UL
    323         && pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size != 0UL)
    324     {
    325         PIMAGE_TLS_DIRECTORY pTLSDir;
    326         LONG                 iSection;
    327         iSection = getSectionIndexFromRVA(pNtHdrs->OptionalHeader.
    328                                           DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].
    329                                           VirtualAddress);
    330         pTLSDir = (PIMAGE_TLS_DIRECTORY)getPointerFromRVA(pNtHdrs->OptionalHeader.
    331                                                           DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].
    332                                                           VirtualAddress);
    333 
    334         if (pTLSDir != NULL && iSection != -1)
    335         {
    336             PVOID pv;
    337 
    338             /*
    339              * According to the docs StartAddressOfRawData and EndAddressOfRawData is
    340              * real pointers with a baserelocs.
    341              *
    342              * The docs says nothing about the two AddressOf pointers. So, we'll assume that
    343              * these also are real pointers. But, we'll try compensate if they should not have
    344              * base realocations.
    345              */
    346             if (validateRealPointer((PVOID)pTLSDir->StartAddressOfRawData)
    347                 &&
    348                 validateRealPointer((PVOID)pTLSDir->EndAddressOfRawData)
    349                 )
    350             {
    351                 setTLSAddress((PVOID)pTLSDir->StartAddressOfRawData);
    352                 setTLSInitSize(pTLSDir->EndAddressOfRawData - pTLSDir->StartAddressOfRawData);
    353                 setTLSTotalSize(pTLSDir->EndAddressOfRawData - pTLSDir->StartAddressOfRawData + pTLSDir->SizeOfZeroFill);
    354 
    355                 if (pTLSDir->AddressOfIndex)
    356                 {
    357                     if (validateRealPointer(pTLSDir->AddressOfIndex))
    358                         /* assume baserelocations for thepointer; use it without any change. */
    359                         setTLSIndexAddr((LPDWORD)(void*)pTLSDir->AddressOfIndex);
    360                     else
    361                     {   /* assume no baserelocs for these pointers? Complain and debugint3 */
    362                         eprintf(("Win32Pe2LxImage::init: TLS - AddressOfIndex(%#8x) is not a pointer with basereloc.\n",
    363                                  pTLSDir->AddressOfIndex));
    364                         pv = getPointerFromPointer(pTLSDir->AddressOfIndex);
    365                         if (pv == NULL)
    366                         {
    367                             eprintf(("Win32Pe2LxImage::init: invalid RVA to TLS AddressOfIndex - %#8x.\n",
    368                                      pTLSDir->AddressOfIndex));
    369                             return LDRERROR_INVALID_HEADER;
    370                         }
    371                         setTLSIndexAddr((LPDWORD)pv);
    372                     }
    373                 }
    374 
    375                 if (pTLSDir->AddressOfCallBacks)
    376                 {
    377                     if (validateRealPointer(pTLSDir->AddressOfCallBacks))
    378                         /* assume baserelocations for thepointer; use it without any change. */
    379                         setTLSCallBackAddr(pTLSDir->AddressOfCallBacks);
    380                     else
    381                     {   /* assume no baserelocs for these pointers? Complain and debugint3 */
    382                         eprintf(("Win32Pe2LxImage::init: Warning: TLS - AddressOfCallBacks(%#8x) is not a pointer with basereloc.\n",
    383                                  pTLSDir->AddressOfCallBacks));
    384                         pv = getPointerFromPointer(pTLSDir->AddressOfCallBacks);
    385                         if (pv == NULL)
    386                         {
    387                             eprintf(("Win32Pe2LxImage::init: invalid pointer to TLS AddressOfCallBacks - %#8x.\n",
    388                                      pTLSDir->AddressOfIndex));
    389                             return LDRERROR_INVALID_HEADER;
    390                         }
    391                         setTLSCallBackAddr((PIMAGE_TLS_CALLBACK*)pv);
    392                     }
    393                 }
    394             }
    395         }
    396         else
    397         {
    398             eprintf(("Win32Pe2LxImage::init: invalid RVA to TLS Dir - %#8x. (getPointerFromRVA failed)\n",
    399                      pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress));
    400             return LDRERROR_INVALID_HEADER;
    401         }
    402     }
     284    rc = doResources();
     285    if (rc)
     286        return rc;
     287
     288    /*
     289     * TLS - Thread Local Storage
     290     */
     291    rc = doTLS();
     292    if (rc)
     293        return rc;
     294
     295
     296    /*
     297     * Process imports.
     298     */
     299    rc = doImports();
     300    if (rc)
     301        return rc;
     302
    403303    return LDRERROR_SUCCESS;
    404304}
    405 
    406305
    407306
     
    688587
    689588/**
     589 * Process resource section.
     590 */
     591ULONG Win32Pe2LxImage::doResources()
     592{
     593    ULONG   rc;
     594
     595    if (pNtHdrs->OptionalHeader.NumberOfRvaAndSizes > IMAGE_DIRECTORY_ENTRY_RESOURCE
     596        && pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress > 0UL)
     597    {
     598        ulRVAResourceSection = pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;
     599        pResRootDir = (PIMAGE_RESOURCE_DIRECTORY)getPointerFromRVA(ulRVAResourceSection);
     600        /* _temporary_ fix:
     601         *  We'll have to make the resource section writable.
     602         *  And we'll have to make the pages before it readable.
     603         */
     604        LONG iSection = getSectionIndexFromRVA(ulRVAResourceSection);
     605        if (iSection >= 0)
     606        {
     607            rc = DosSetMem((PVOID)paSections[iSection].ulAddress, paSections[iSection].cbVirtual, PAG_WRITE | PAG_READ);
     608
     609            ULONG ulAddr = paSections[iSection].ulAddress - 0x10000; //64KB
     610            while (ulAddr < paSections[iSection].ulAddress)
     611            {
     612                ULONG fl = ~0UL;
     613                ULONG cb = ~0UL;
     614                rc = DosQueryMem((PVOID)ulAddr, &cb, &fl);
     615                if (rc == NO_ERROR)
     616                {
     617                    if (fl & PAG_GUARD)
     618                        rc = -1;
     619                    else if (fl & PAG_COMMIT)
     620                        fl &= ~(PAG_COMMIT);
     621                    else
     622                        fl |= PAG_COMMIT;
     623                    cb = (cb + 0xfffUL) & ~0xfffUL;
     624                }
     625                else
     626                {
     627                    fl = PAG_COMMIT;
     628                    cb = 0x1000;
     629                }
     630                fl &= PAG_READ | PAG_COMMIT | PAG_WRITE | PAG_GUARD;
     631                fl |= PAG_READ;
     632                if (cb > paSections[iSection].ulAddress - ulAddr)
     633                    cb = paSections[iSection].ulAddress - ulAddr;
     634                if (rc == NO_ERROR)
     635                    rc = DosSetMem((PVOID)ulAddr, cb, fl);
     636
     637                ulAddr += cb;
     638            }
     639        }
     640    }
     641
     642    return 0;
     643}
     644
     645
     646/**
     647 * Do TLS related matters.
     648 */
     649ULONG Win32Pe2LxImage::doTLS()
     650{
     651    if (pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress != 0UL
     652        && pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size != 0UL)
     653    {
     654        PIMAGE_TLS_DIRECTORY pTLSDir;
     655        LONG                 iSection;
     656        iSection = getSectionIndexFromRVA(pNtHdrs->OptionalHeader.
     657                                          DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].
     658                                          VirtualAddress);
     659        pTLSDir = (PIMAGE_TLS_DIRECTORY)getPointerFromRVA(pNtHdrs->OptionalHeader.
     660                                                          DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].
     661                                                          VirtualAddress);
     662
     663        if (pTLSDir != NULL && iSection != -1)
     664        {
     665            PVOID pv;
     666
     667            /*
     668             * According to the docs StartAddressOfRawData and EndAddressOfRawData is
     669             * real pointers with a baserelocs.
     670             *
     671             * The docs says nothing about the two AddressOf pointers. So, we'll assume that
     672             * these also are real pointers. But, we'll try compensate if they should not have
     673             * base realocations.
     674             */
     675            if (validateRealPointer((PVOID)pTLSDir->StartAddressOfRawData)
     676                &&
     677                validateRealPointer((PVOID)pTLSDir->EndAddressOfRawData)
     678                )
     679            {
     680                setTLSAddress((PVOID)pTLSDir->StartAddressOfRawData);
     681                setTLSInitSize(pTLSDir->EndAddressOfRawData - pTLSDir->StartAddressOfRawData);
     682                setTLSTotalSize(pTLSDir->EndAddressOfRawData - pTLSDir->StartAddressOfRawData + pTLSDir->SizeOfZeroFill);
     683
     684                if (pTLSDir->AddressOfIndex)
     685                {
     686                    if (validateRealPointer(pTLSDir->AddressOfIndex))
     687                        /* assume baserelocations for thepointer; use it without any change. */
     688                        setTLSIndexAddr((LPDWORD)(void*)pTLSDir->AddressOfIndex);
     689                    else
     690                    {   /* assume no baserelocs for these pointers? Complain and debugint3 */
     691                        eprintf(("Win32Pe2LxImage::init: TLS - AddressOfIndex(%#8x) is not a pointer with basereloc.\n",
     692                                 pTLSDir->AddressOfIndex));
     693                        pv = getPointerFromPointer(pTLSDir->AddressOfIndex);
     694                        if (pv == NULL)
     695                        {
     696                            eprintf(("Win32Pe2LxImage::init: invalid RVA to TLS AddressOfIndex - %#8x.\n",
     697                                     pTLSDir->AddressOfIndex));
     698                            return LDRERROR_INVALID_HEADER;
     699                        }
     700                        setTLSIndexAddr((LPDWORD)pv);
     701                    }
     702                }
     703
     704                if (pTLSDir->AddressOfCallBacks)
     705                {
     706                    if (validateRealPointer(pTLSDir->AddressOfCallBacks))
     707                        /* assume baserelocations for thepointer; use it without any change. */
     708                        setTLSCallBackAddr(pTLSDir->AddressOfCallBacks);
     709                    else
     710                    {   /* assume no baserelocs for these pointers? Complain and debugint3 */
     711                        eprintf(("Win32Pe2LxImage::init: Warning: TLS - AddressOfCallBacks(%#8x) is not a pointer with basereloc.\n",
     712                                 pTLSDir->AddressOfCallBacks));
     713                        pv = getPointerFromPointer(pTLSDir->AddressOfCallBacks);
     714                        if (pv == NULL)
     715                        {
     716                            eprintf(("Win32Pe2LxImage::init: invalid pointer to TLS AddressOfCallBacks - %#8x.\n",
     717                                     pTLSDir->AddressOfIndex));
     718                            return LDRERROR_INVALID_HEADER;
     719                        }
     720                        setTLSCallBackAddr((PIMAGE_TLS_CALLBACK*)pv);
     721                    }
     722                }
     723            }
     724        }
     725        else
     726        {
     727            eprintf(("Win32Pe2LxImage::init: invalid RVA to TLS Dir - %#8x. (getPointerFromRVA failed)\n",
     728                     pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress));
     729            return LDRERROR_INVALID_HEADER;
     730        }
     731    }
     732
     733    return 0;
     734}
     735
     736/**
     737 * Processes the import directory of the image.
     738 * @returns LDRERROR_*
     739 * @remark  This could be in base class and shared with the peldr.
     740 */
     741ULONG   Win32Pe2LxImage::doImports()
     742{
     743    ULONG                       rc;
     744    PIMAGE_IMPORT_DESCRIPTOR    pImps;
     745
     746    /*
     747     * Check if there is actually anything to work on.
     748     */
     749    if (   !pNtHdrs->OptionalHeader.DataDirectory[IMAGE_FILE_IMPORT_DIRECTORY].VirtualAddress
     750        || !pNtHdrs->OptionalHeader.DataDirectory[IMAGE_FILE_IMPORT_DIRECTORY].Size)
     751    {
     752        dprintf(("Win32Pe2LxImage::initImports: there are no imports\n"));
     753        return 0;
     754    }
     755
     756    /*
     757     * Walk the IMAGE_IMPORT_DESCRIPTOR table.
     758     */
     759    for (rc = 0, pImps = (PIMAGE_IMPORT_DESCRIPTOR)getPointerFromRVA(pNtHdrs->OptionalHeader.DataDirectory[IMAGE_FILE_IMPORT_DIRECTORY].VirtualAddress);
     760         !rc && pImps->Name != 0 && pImps->FirstThunk != 0;
     761         pImps++)
     762    {
     763        const char *        pszName = (const char*)getPointerFromRVA(pImps->Name);
     764        Win32ImageBase     *pModule;
     765        dprintf(("Win32Pe2LxImage::initImports: DLL %s\n", pszName));
     766
     767        /*
     768         * Try find the table.
     769         */
     770        pModule = importsGetModule(pszName);
     771        if (pModule)
     772        {
     773            PIMAGE_THUNK_DATA   pFirstThunk;    /* update this. */
     774            PIMAGE_THUNK_DATA   pThunk;         /* read from this. */
     775
     776            /*
     777             * Walk the thunks table(s).
     778             */
     779            pFirstThunk = (PIMAGE_THUNK_DATA)getPointerFromRVA((ULONG)pImps->FirstThunk);
     780            pThunk = pImps->u.OriginalFirstThunk == 0 ? pFirstThunk
     781                : (PIMAGE_THUNK_DATA)getPointerFromRVA((ULONG)pImps->FirstThunk);
     782            while (!rc && pThunk->u1.Ordinal != 0)
     783            {
     784                if (pThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG)
     785                    rc = importsByOrdinal(pModule, IMAGE_ORDINAL(pThunk->u1.Ordinal), (void**)&pFirstThunk->u1.Function);
     786                else if (   pThunk->u1.Ordinal > 0
     787                         && pThunk->u1.Ordinal < pNtHdrs->OptionalHeader.SizeOfImage)
     788                    rc = importsByName(pModule, (const char*)getPointerFromRVA((ULONG)pThunk->u1.AddressOfData + 2), (void**)&pFirstThunk->u1.Function);
     789                else
     790                {
     791                    dprintf(("Win32Pe2LxImage::initImports: bad import data thunk!\n"));
     792                    DebugInt3();
     793                    rc = LDRERROR_IMPORTS;
     794                }
     795
     796                pThunk++;
     797                pFirstThunk++;
     798            }
     799        }
     800        else
     801        {
     802            dprintf(("Win32Pe2LxImage::initImports: cannot find module '%s'!!!\n", pszName));
     803            DebugInt3();
     804            rc = LDRERROR_IMPORTS;
     805        }
     806    }
     807
     808    return rc;
     809}
     810
     811
     812/**
     813 * Find a module.
     814 *
     815 * @returns Pointer to module
     816 * @returns NULL on failure.
     817 * @param   pszModName  Pointer to module name.
     818 * @remark  This should be in base class and shared with the peldr.
     819 */
     820Win32ImageBase * Win32Pe2LxImage::importsGetModule(const char *pszModName)
     821{
     822    Win32ImageBase *pMod;
     823    Win32DllBase   *pDll;
     824
     825    /*
     826     * Look if it's already loaded.
     827     */
     828    pDll = Win32DllBase::findModule((char*)pszModName);
     829    if (pDll)
     830    {
     831        dprintf(("Win32Pe2LxImage::importGetModule(%s) already loaded\n", pszModName));
     832        pDll->AddRef();
     833    }
     834    else if (WinExe != NULL && WinExe->matchModName(pszModName))
     835    {
     836        dprintf(("Win32Pe2LxImage::importGetModule(%s) already loaded (exe)\n", pszModName));
     837        pMod = (Win32ImageBase *)WinExe;
     838        pDll = NULL;
     839    }
     840    else
     841    {
     842        /*
     843         * Load it (simplified).
     844         */
     845        pDll = importsLoadModule(pszModName);
     846        if (!pDll)
     847            return NULL;
     848        dprintf(("Win32Pe2LxImage::importGetModule(%s) Loaded module\n", pszModName));
     849    }
     850
     851    /*
     852     * Update dependendcies.
     853     */
     854    if (pDll)
     855    {
     856        /*
     857         * Add the dll we just loaded to dependency list for this image.
     858         */
     859        addDependency(pDll);
     860
     861        /*
     862         * Make sure the dependency list is correct (already done in the ctor
     863         * of Win32DllBase, but for LX dlls the parent is then set to NULL)
     864         * so, change it here again
     865         */
     866        pDll->setUnloadOrder(this);
     867        pMod = pDll;
     868    }
     869
     870    return pMod;
     871}
     872
     873/**
     874 * Loads a module this module is depending on.
     875 * @returns Pointer to loaded module.
     876 * @returns NULL on failure.
     877 * @param   pszModName  Name of the module to be loaded.
     878 * @remark  This should be in base class and shared with the peldr.
     879 */
     880Win32DllBase *Win32Pe2LxImage::importsLoadModule(const char *pszModName)
     881{
     882    Win32DllBase   *pDll;
     883    char            szRenamed[CCHMAXPATH];
     884
     885    /*
     886     * Copy and rename the module name. (i.e. OLE32 -> OLE32OS2)
     887     */
     888    Win32DllBase::renameDll(strcpy(szRenamed, pszModName));
     889
     890    /*
     891     * Find the filename (using the standard search stuff).
     892     */
     893    char            szFullname[CCHMAXPATH];
     894    if (!Win32ImageBase::findDll(szRenamed, szFullname, sizeof(szFullname)))
     895    {
     896        dprintf(("Module %s not found!", szRenamed));
     897        errorState = ERROR_FILE_NOT_FOUND;
     898        return NULL;
     899    }
     900
     901    /*
     902     * Check which type of executable module this is.
     903     */
     904    if (isPEImage(szFullname, NULL, NULL) != ERROR_SUCCESS_W)
     905    {
     906        /*
     907         * LX image: let OS/2 do all the work for us
     908         */
     909        char    szModuleFailure[CCHMAXPATH];
     910        HMODULE hmodLXDll;
     911        APIRET  rc;
     912
     913        rc = DosLoadModule(szModuleFailure, sizeof(szModuleFailure), szFullname, (HMODULE *)&hmodLXDll);
     914        if (rc)
     915        {
     916            dprintf(("DosLoadModule returned %X for %s", rc, szModuleFailure));
     917            errorState = rc;
     918            return NULL;
     919        }
     920
     921        pDll = Win32DllBase::findModuleByOS2Handle((HINSTANCE)hmodLXDll);
     922        if (pDll == NULL)
     923        {
     924            dprintf(("Just loaded the dll, but can't find it anywhere?!!?"));
     925            DebugInt3();
     926            errorState = ERROR_INTERNAL;
     927            return NULL;
     928        }
     929
     930        /*
     931         * For none Pe2Lx'ed LX modules we'll have to do a little work here.
     932         */
     933        if (pDll->isLxDll())
     934        {
     935            Win32LxDll *pLXDll = (Win32LxDll *)pDll;
     936            pLXDll->setDllHandleOS2(hmodLXDll);
     937            if (pLXDll->AddRef() == -1) //-1 -> load failed (attachProcess)
     938            {
     939                dprintf(("Dll %s refused to be loaded; aborting", szFullname));
     940                delete pLXDll;
     941                errorState = ERROR_INTERNAL;
     942                return NULL;
     943            }
     944        }
     945    }
     946    else
     947    {
     948        /*
     949         * PE image: use the peldr.
     950         */
     951        Win32PeLdrDll *pPEDll;
     952
     953        pPEDll = new Win32PeLdrDll(szFullname, this);
     954        if (!pPEDll)
     955        {
     956            dprintf(("pedll: Error allocating memory" ));
     957            errorState = ERROR_INTERNAL;
     958            return NULL;
     959        }
     960        dprintf(("**********************************************************************"));
     961        dprintf(("**********************     Loading Module        *********************"));
     962        dprintf(("**********************************************************************"));
     963        if (pPEDll->init(0) != LDRERROR_SUCCESS)
     964        {
     965            dprintf(("Internal WinDll error ", pPEDll->getError()));
     966            delete pPEDll;
     967            return NULL;
     968        }
     969
     970#ifdef DEBUG
     971        pPEDll->AddRef(getModuleName());
     972#else
     973        pPEDll->AddRef();
     974#endif
     975        if (pPEDll->attachProcess() == FALSE)
     976        {
     977            dprintf(("attachProcess failed!"));
     978            delete pPEDll;
     979            errorState = ERROR_INTERNAL;
     980            return NULL;
     981        }
     982        pDll = (Win32DllBase*)pPEDll;
     983    }
     984
     985    dprintf(("**********************************************************************"));
     986    dprintf(("**********************  Finished Loading Module %s ", szFullname));
     987    dprintf(("**********************************************************************"));
     988    return pDll;
     989}
     990
     991
     992/**
     993 * Resolve an import by symbol name.
     994 *
     995 * @returns 0 on success, error code on failure.
     996 * @param   pModule     Pointer to module.
     997 * @param   uOrdinal    Ordinal of the symbol to import.
     998 * @param   ppvAddr     Where to store the symbol address.
     999 * @remark  This should be in base class and shared with the peldr.
     1000 */
     1001ULONG Win32Pe2LxImage::importsByOrdinal(Win32ImageBase *pModule, unsigned uOrdinal, void **ppvAddr)
     1002{
     1003    void *pfn;
     1004    pfn = (void*)pModule->getApi(uOrdinal);
     1005    if (pfn)
     1006    {
     1007        dprintf(("Win32Pe2LxImage::importsByOrdinal: *%p=%p %s!%d\n", ppvAddr, pfn, pModule->getModuleName(), uOrdinal));
     1008        *ppvAddr = pfn;
     1009        return 0;
     1010    }
     1011
     1012    dprintf(("Win32Pe2LxImage::importsByOrdinal: %s!%u\n", pModule->getModuleName(), uOrdinal));
     1013    DebugInt3();
     1014    /** @todo: missing api */
     1015    *ppvAddr = NULL;
     1016    return LDRERROR_IMPORTS;
     1017}
     1018
     1019
     1020/**
     1021 * Resolve an import by symbol name.
     1022 *
     1023 * @returns 0 on success, error code on failure.
     1024 * @param   pModule     Pointer to module.
     1025 * @param   pszSymName  Name of symbol to import.
     1026 * @param   ppvAddr     Where to store the symbol address.
     1027 * @remark  This should be in base class and shared with the peldr.
     1028 */
     1029ULONG Win32Pe2LxImage::importsByName(Win32ImageBase *pModule, const char *pszSymName, void **ppvAddr)
     1030{
     1031    void *pfn;
     1032    pfn = (void*)pModule->getApi((char*)pszSymName);
     1033    if (pfn)
     1034    {
     1035        dprintf(("Win32Pe2LxImage::importsByName: *%p=%p %s!%s\n", ppvAddr, pfn, pModule->getModuleName(), pszSymName));
     1036        *ppvAddr = pfn;
     1037        return 0;
     1038    }
     1039
     1040    dprintf(("Win32Pe2LxImage::importsByName: %s!%s\n", pModule->getModuleName(), pszSymName));
     1041    DebugInt3();
     1042    /** @todo: missing api */
     1043    *ppvAddr = NULL;
     1044    return LDRERROR_IMPORTS;
     1045}
     1046
     1047
     1048/**
    6901049 * Frees memory used by this object.
    6911050 * When an exception is to be thrown, this function is called first to clean up
     
    7111070 * Converts a RVA into a pointer.
    7121071 * @returns   Pointer matching the given RVA, NULL on error.
    713  * @param     ulRVA  An address relative to the imagebase of the original PE image.
    714  *                   If this is 0UL NULL is returned.
     1072 * @param     ulRVA     An address relative to the imagebase of the original PE image.
     1073 *                      If this is 0UL NULL is returned.
     1074 * @param     fOverride If set the ulRVA doesn't have to be inside the image.
    7151075 * @sketch    DEBUG: validate state, paSections != NULL
    7161076 *            IF ulRVA is 0 THEN return NULL
     
    7241084 *            RVA == 0 is ignored.
    7251085 */
    726 PVOID  Win32Pe2LxImage::getPointerFromRVA(ULONG ulRVA)
    727 {
    728     int i;
    729 
     1086void *  Win32Pe2LxImage::getPointerFromRVA(ULONG ulRVA, BOOL fOverride)
     1087{
    7301088    #ifdef DEBUG
    7311089    if (paSections == NULL)
     
    7391097        return NULL;
    7401098
    741     i = 0;
     1099    int i = 0;
    7421100    while (i < cSections &&
    7431101           (paSections[i].ulRVA > ulRVA || paSections[i].ulRVA + paSections[i].cbVirtual <= ulRVA)) /* ALIGN on page too? */
    7441102        i++;
    745 
    7461103    if (i >= cSections)
     1104    {
     1105        /* This isn't good, but it's required to support api overrides. */
     1106        if (fOverride)
     1107            return (char*)hinstance + ulRVA;
    7471108        return NULL;
     1109    }
    7481110
    7491111    return (PVOID)(ulRVA - paSections[i].ulRVA + paSections[i].ulAddress);
     1112}
     1113
     1114
     1115/** Converts a pointer to an RVA for the loaded image.
     1116 * @remark Because of export overriding addresses outside the image must be supported.
     1117 */
     1118ULONG Win32Pe2LxImage::getRVAFromPointer(void *pv, BOOL fOverride/* = FALSE*/)
     1119{
     1120    #ifdef DEBUG
     1121    if (paSections == NULL)
     1122    {
     1123        eprintf(("Win32Pe2LxImage::getPointerFromRVA: paSections is NULL!\n"));
     1124        return NULL;
     1125    }
     1126    #endif
     1127
     1128    if (pv == 0UL)
     1129        return NULL;
     1130
     1131    int i = 0;
     1132    while (i < cSections &&
     1133           (paSections[i].ulAddress > (ULONG)pv || paSections[i].ulAddress + paSections[i].cbVirtual <= (ULONG)pv)) /* ALIGN on page too? */
     1134        i++;
     1135    if (i >= cSections)
     1136    {
     1137        /* This isn't good, but it's required to support api overrides. */
     1138        if (fOverride)
     1139            return (ULONG)pv - (ULONG)hinstance;
     1140        return NULL;
     1141    }
     1142
     1143    return (ULONG)pv - paSections[i].ulAddress + paSections[i].ulRVA;
    7501144}
    7511145
     
    8431237
    8441238
    845 /**
    846  * Gets pointer to an exported procedure by procedure name.
    847  * @returns   Address of exported procedure. 0UL if not found.
    848  * @param     name  Exported procedure name.
    849  * @status    completely implemented.
    850  * @author    Sander van Leeuwen
    851  * @remark
    852  */
    853 ULONG Win32Pe2LxImage::getApi(char *name)
    854 {
    855     APIRET      rc;
    856     ULONG       ulApiAddr;
    857 
    858     rc = DosQueryProcAddr(hmod, 0, name, (PFN *)&ulApiAddr);
    859     return rc == NO_ERROR ? ulApiAddr : 0;
    860 }
    861 
    862 
    863 /**
    864  * Gets pointer to an exported procedure by ordinal.
    865  * @returns   Pointer to an exported procedure. 0UL if not found.
    866  * @param     ordinal  Export ordinal number.
    867  * @status    completely implemented.
    868  * @author    Sander van Leeuwen
    869  * @remark    FIXME:
    870  *            This function should be implemented for both Exe and Dll images!
    871  *            It could be done similar in both peldr image and pe2lx images by
    872  *            accessing PE structures.
    873  */
    874 ULONG Win32Pe2LxImage::getApi(int ordinal)
    875 {
    876     APIRET      rc;
    877     ULONG       ulApiAddr;
    878 
    879     rc = DosQueryProcAddr(hmod, ordinal, NULL, (PFN *)&ulApiAddr);
    880 
    881     return rc == NO_ERROR ? ulApiAddr : 0;
    882 }
Note: See TracChangeset for help on using the changeset viewer.