int ReadResourceTable()

in tools/ExeView/exehdr.cpp [340:468]


int ReadResourceTable (int fFile, PEXEINFO pExeInfo)
{
    int       nLen;
    RESTYPE   rt;
    PRESTYPE  prt, prt_last=NULL;
    PRESINFO  pri;
    long      lResTable;
    WORD      wResSize, wI;
    int       ipri;

    rt.pResourceType = NULL;
    rt.pResInfoArray = NULL;
    rt.pNext         = NULL;

    if (pExeInfo->NewHdr.wResourceOffset == pExeInfo->NewHdr.wResOffset)
        return 0;       // No resources

    lResTable = pExeInfo->OldHdr.lNewExeOffset+pExeInfo->NewHdr.wResourceOffset;

    _llseek( fFile, lResTable, 0 );

    // Read shift count
    if (_lread(fFile, (LPSTR)&(pExeInfo->wShiftCount), 2)!=2)
        return LERR_READINGFILE;

    // Read all the resource types    
    while (TRUE)    
    {
        nLen = _lread(fFile, (LPSTR)&rt, sizeof(RTYPE));
        if (nLen != sizeof(RTYPE))
            return LERR_READINGFILE;
        if (rt.wType==0)
            break;

        prt = (PRESTYPE)LocalAlloc(LPTR, sizeof(RESTYPE) );
        if (!prt)
            return LERR_MEMALLOC;

        *prt = rt;

        if (prt_last==NULL)     // Is this the first entry??
            pExeInfo->pResTable = prt;
        else                    // Nope
            prt_last->pNext = prt;

        prt_last=prt;

        // Allocate buffer for 'Count' resources of this type
        wResSize = prt->wCount * sizeof( RESINFO2 );
        pri = (PRESINFO)LocalAlloc(LPTR, wResSize );
        if (!pri)
            return LERR_MEMALLOC;
        prt->pResInfoArray = pri;

        // Now read 'Count' resources of this type
        for (ipri = 0; ipri < prt->wCount; ipri++)
        {
            nLen = _lread(fFile, (LPSTR)(pri + ipri), sizeof(RINFO));
            if (nLen != sizeof(RINFO))
                return LERR_READINGFILE;

            (pri + ipri)->pResType = prt;
        }
    }

    // Now that the resources are read, read the names
    prt = pExeInfo->pResTable;

    while (prt)
    {
        if (prt->wType & 0x8000)        // Pre-defined type
            prt->pResourceType = NULL;
        else                            // Name is in the file
        {
             // wType is offset from beginning of Resource Table
            _llseek( fFile, lResTable + prt->wType, 0 );

            wResSize = 0;    
            // Read string size
            if (_lread(fFile, (LPSTR)&wResSize, 1)!=1)
                return LERR_READINGFILE;

            // +1 for the null terminator
            prt->pResourceType = (PSTR)LocalAlloc(LPTR, wResSize+1);
            if (!prt->pResourceType)
                return LERR_MEMALLOC;

            // Read string
            if (_lread(fFile, (LPSTR)prt->pResourceType, wResSize)!=wResSize)
                return LERR_READINGFILE;
            prt->pResourceType[ wResSize ] = 0;   // Null terminate string;
        }

        // Now do Resource Names for this type
        pri = prt->pResInfoArray;

        wI = 0;
        while ( wI < prt->wCount )
        {
            if (pri->wID & 0x8000)  // Integer resource
                pri->pResourceName = NULL;
            else                    // Named resource
            {
                // wID is offset from beginning of Resource Table
                _llseek( fFile, lResTable + pri->wID, 0 );

                wResSize = 0;
                // Read string size
                if (_lread(fFile, (LPSTR)&wResSize, 1)!=1)
                    return LERR_READINGFILE;

                // +1 for the null terminator
                pri->pResourceName = (PSTR)LocalAlloc(LPTR, wResSize+1);
                if (!pri->pResourceName)
                    return LERR_MEMALLOC;

                // Read string
                if (_lread(fFile, (LPSTR)pri->pResourceName, wResSize)!=wResSize)
                    return LERR_READINGFILE;
                pri->pResourceName[ wResSize ] = 0;   // Null terminate string;
            }
            pri++;
            wI++;
        }
        prt = prt->pNext;
    }
    return 0;

} //*** ReadResourceTable