VirtualBox

Ignore:
Timestamp:
Aug 21, 2023 2:32:45 AM (18 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
158851
Message:

IPRT/pdbvfs: Parse the DBI header and optional header and pick up stream names from it. Also provide the DBI substreams as individual files for simpler access.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/fs/pdbvfs.cpp

    r100913 r100914  
    6767
    6868/**
     69 * Substream info.
     70 */
     71typedef struct RTFSPDBSUBSTREAM
     72{
     73    /** The parent stream. */
     74    uint32_t    idxStream;
     75    /** The substream index within the parent. */
     76    uint8_t     idxSubstream;
     77    /** The offset of the start of the substream within the parent. */
     78    uint32_t    offSubstream;
     79    /** The size of the substream. */
     80    uint32_t    cbSubstream;
     81    /** The name of the substream (including the parent one at the start).
     82     * Readonly string constant, as substreams are all hardcoded. */
     83    const char *pszName;
     84} RTFSPDBSUBSTREAM;
     85typedef RTFSPDBSUBSTREAM *PRTFSPDBSUBSTREAM;
     86typedef RTFSPDBSUBSTREAM const *PCRTFSPDBSUBSTREAM;
     87
     88
     89/**
    6990 * Stream info.
    7091 */
     
    87108        PCRTPDB70PAGE   pa70;
    88109    } PageMap;
     110    /** Number of substreams. */
     111    uint8_t             cSubstreams;
     112    /** The index into RTFSPDBVOL::aSubstreams of the first one. */
     113    uint8_t             idxFirstSubstream;
    89114} RTFSPDBSTREAMINFO;
    90115typedef RTFSPDBSTREAMINFO *PRTFSPDBSTREAMINFO;
     
    101126    /** The stream number (0 based). */
    102127    uint32_t            idxStream;
    103     /** Size of the stream. */
     128    /** The start offset of the substream this file object represents. This is
     129     * zero for full streams. */
     130    uint32_t            offSubstream;
     131    /** Size of the stream (or substream). */
    104132    uint32_t            cbStream;
    105     /** Number of pages in the stream. */
     133    /** Number of pages in the stream (the whole stream, not just the substream). */
    106134    uint32_t            cPages;
    107     /** Pointer to the page map for the stream (within RTFSPDBVOL::pbRoot)(. */
     135    /** Pointer to the page map for the stream (within RTFSPDBVOL::pbRoot)
     136     * (again the whole stream, not just the substream). */
    108137    union
    109138    {
     
    124153    /** Pointer to the PDB volume data. */
    125154    PRTFSPDBVOL         pPdb;
    126     /** The next stream number to return info for when reading (0 based). */
    127     uint32_t            idxNextStream;
     155    /** The next stream and substream number to return info for when reading. */
     156    union
     157    {
     158        uint32_t            idxNext;
     159        struct
     160        {
     161            /** This is zero for the whole stream and non-zero for substreams. */
     162            uint32_t        idxNextSubstream : 8;
     163            /** The next stream number. */
     164            uint32_t        idxNextStream    : 24;
     165        } s;
     166    } u;
    128167} RTFSPDBDIROBJ;
    129168typedef RTFSPDBDIROBJ *PRTFSPDBDIROBJ;
     
    186225    /** @} */
    187226
     227    /** The DBI header from stream \#3. */
     228    RTPDBDBIHDR         DbiHdr;
     229
    188230    /** Extra per-stream info.  We've do individual allocations here in case we
    189231     * want to add write support. */
    190232    PRTFSPDBSTREAMINFO *papStreamInfo;
     233
     234    /** Number of substreams in aSubstreams. */
     235    uint8_t             cSubstreams;
     236    /** Substreams (only from the DBI atm.). */
     237    RTFSPDBSUBSTREAM    aSubstreams[8];
    191238} RTFSPDBVOL;
    192239
     
    203250 */
    204251static void rtFsPdbPopulateObjInfo(PRTFSPDBVOL pPdb, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr,
    205                                    uint32_t cbStream, uint32_t idxStream, bool fIsDir)
     252                                   uint32_t cbStream, uint32_t idxStream, uint8_t idxSubstream, bool fIsDir)
    206253{
    207254    RTTimeSpecSetNano(&pObjInfo->AccessTime, 0);
     
    226273            pObjInfo->Attr.u.Unix.cHardlinks    = 1 + fIsDir;
    227274            pObjInfo->Attr.u.Unix.INodeIdDevice = 0;
    228             pObjInfo->Attr.u.Unix.INodeId       = idxStream;
     275            pObjInfo->Attr.u.Unix.INodeId       = idxStream | ((uint64_t)idxSubstream << 32);
    229276            pObjInfo->Attr.u.Unix.fFlags        = 0;
    230277            pObjInfo->Attr.u.Unix.GenerationId  = 0;
     
    253300 * stream \#1 containing PDB metadata.
    254301 */
    255 static void rtFsPdbPopulateFileObj(PRTFSPDBFILEOBJ pNewFile, PRTFSPDBVOL pPdb,
    256                                    uint32_t idxStream, uint32_t cbStream, void const *pvPageMap)
    257 {
    258     pNewFile->pPdb       = pPdb;
    259     pNewFile->idxStream  = idxStream;
    260     pNewFile->cbStream   = cbStream;
    261     pNewFile->PageMap.pv = pvPageMap;
    262     pNewFile->cPages     = RTPdbSizeToPages(cbStream, pPdb->cbPage);
    263     pNewFile->offFile    = 0;
    264 }
    265 
    266 
    267 /**
    268  * Helper methods for opening a stream.
    269  */
    270 static void rtFsPdbPopulateFileObjFromInfo(PRTFSPDBFILEOBJ pNewFile, PRTFSPDBVOL pPdb, uint32_t idxStream)
     302static void rtFsPdbPopulateFileObj(PRTFSPDBFILEOBJ pNewFile, PRTFSPDBVOL pPdb, uint32_t idxStream,
     303                                   uint32_t cbStream, void const *pvPageMap)
     304{
     305    pNewFile->pPdb          = pPdb;
     306    pNewFile->idxStream     = idxStream;
     307    pNewFile->offSubstream  = 0;
     308    pNewFile->cbStream      = cbStream;
     309    pNewFile->PageMap.pv    = pvPageMap;
     310    pNewFile->cPages        = RTPdbSizeToPages(cbStream, pPdb->cbPage);
     311    pNewFile->offFile       = 0;
     312}
     313
     314
     315/**
     316 * Helper methods for opening a stream or substream.
     317 */
     318static void rtFsPdbPopulateFileObjFromInfo(PRTFSPDBFILEOBJ pNewFile, PRTFSPDBVOL pPdb,
     319                                           uint32_t idxStream, PCRTFSPDBSUBSTREAM pSubstream)
    271320{
    272321    PCRTFSPDBSTREAMINFO pInfo = pPdb->papStreamInfo[idxStream];
    273322    rtFsPdbPopulateFileObj(pNewFile, pPdb, idxStream, pInfo->cbStream, pInfo->PageMap.pv);
    274323    Assert(pInfo->cPages == pNewFile->cPages);
     324    if (pSubstream)
     325    {
     326        pNewFile->offSubstream = pSubstream->offSubstream;
     327        pNewFile->cbStream     = pSubstream->cbSubstream;
     328    }
    275329}
    276330
     
    294348{
    295349    PRTFSPDBFILEOBJ const pThis = (PRTFSPDBFILEOBJ)pvThis;
    296     rtFsPdbPopulateObjInfo(pThis->pPdb, pObjInfo, enmAddAttr, pThis->cbStream, pThis->idxStream, false /*fIsDir*/);
     350    rtFsPdbPopulateObjInfo(pThis->pPdb, pObjInfo, enmAddAttr, pThis->cbStream, pThis->idxStream, 0, false /*fIsDir*/);
    297351    return VINF_SUCCESS;
    298352}
     
    350404    while (cbToRead > 0)
    351405    {
    352         uint32_t       iPageMap     = (uint32_t)(offFile / pPdb->cbPage);
    353         uint32_t const offInPage    = (uint32_t)(offFile % pPdb->cbPage);
     406        uint32_t       iPageMap     = (uint32_t)((offFile + pThis->offSubstream) / pPdb->cbPage);
     407        uint32_t const offInPage    = (uint32_t)((offFile + pThis->offSubstream) % pPdb->cbPage);
    354408        size_t         cbLeftInPage = pPdb->cbPage - offInPage;
    355409        if (cbLeftInPage > cbToRead)
     
    516570    PRTFSPDBDIROBJ const pThis = (PRTFSPDBDIROBJ)pvThis;
    517571    PRTFSPDBVOL    const pPdb  = pThis->pPdb;
    518     rtFsPdbPopulateObjInfo(pPdb, pObjInfo, enmAddAttr, pPdb->cbRoot, 0 /* root dir is stream zero */, true /*fIsDir*/);
     572    rtFsPdbPopulateObjInfo(pPdb, pObjInfo, enmAddAttr, pPdb->cbRoot, 0 /* root dir is stream zero */,
     573                           0 /*idxSubstream*/, true /*fIsDir*/);
    519574    return VINF_SUCCESS;
     575}
     576
     577
     578/**
     579 * Helper for looping up a substream name.
     580 */
     581DECLINLINE(PCRTFSPDBSUBSTREAM) rtFsPdbDirLookupSubstream(PRTFSPDBVOL pPdb, uint32_t idxStream, const char *pszName)
     582{
     583    uint8_t const idxFirst = idxStream != UINT32_MAX ? pPdb->papStreamInfo[idxStream]->idxFirstSubstream : 0;
     584    uint8_t       cLeft    = idxStream != UINT32_MAX ? pPdb->papStreamInfo[idxStream]->cSubstreams       : pPdb->cSubstreams;
     585    while (cLeft-- > 0)
     586    {
     587        PCRTFSPDBSUBSTREAM pSubstream = &pPdb->aSubstreams[idxFirst + cLeft];
     588        if (strcmp(pSubstream->pszName, pszName) == 0)
     589            return pSubstream;
     590    }
     591    return NULL;
    520592}
    521593
     
    569641     *      - or the combination of the two: "1-pdb".
    570642     */
    571     uint32_t idxStream;
     643    uint32_t           idxStream;
     644    PCRTFSPDBSUBSTREAM pSubstream = NULL;
    572645    if (RT_C_IS_DIGIT(*pszEntry))
    573646    {
     
    584657            && RTStrCmp(pszNext + 1, pPdb->papStreamInfo[idxStream]->pszName) != 0)
    585658        {
    586             Log2(("rtFsPdbDir_Open: idxStream=%#x name mismatch '%s', expected '%s'\n",
    587                   idxStream, pszEntry, pPdb->papStreamInfo[idxStream]->pszName));
    588             return VERR_PATH_NOT_FOUND;
     659            pSubstream = rtFsPdbDirLookupSubstream(pPdb, idxStream, pszNext + 1);
     660            if (pSubstream)
     661                Assert(pSubstream->idxStream == idxStream);
     662            else
     663            {
     664                Log2(("rtFsPdbDir_Open: idxStream=%#x name mismatch '%s', expected '%s'\n",
     665                      idxStream, pszEntry, pPdb->papStreamInfo[idxStream]->pszName));
     666                return VERR_PATH_NOT_FOUND;
     667            }
    589668        }
    590669    }
     
    599678        if (idxStream >= pPdb->cStreams)
    600679        {
    601             Log2(("rtFsPdbDir_Open: '%s' not found in name table\n", pszEntry));
    602             return VERR_PATH_NOT_FOUND;
     680            pSubstream = rtFsPdbDirLookupSubstream(pPdb, UINT32_MAX, pszEntry);
     681            if (pSubstream)
     682                idxStream = pSubstream->idxStream;
     683            else
     684            {
     685                Log2(("rtFsPdbDir_Open: '%s' not found in name table\n", pszEntry));
     686                return VERR_PATH_NOT_FOUND;
     687            }
    603688        }
    604689    }
     
    615700        if (RT_SUCCESS(rc))
    616701        {
    617             rtFsPdbPopulateFileObjFromInfo(pNewFile, pPdb, idxStream);
     702            rtFsPdbPopulateFileObjFromInfo(pNewFile, pPdb, idxStream, pSubstream);
    618703
    619704            /* Convert it to a file object. */
     
    637722{
    638723    PRTFSPDBDIROBJ pThis = (PRTFSPDBDIROBJ)pvThis;
    639     pThis->idxNextStream = 0;
     724    pThis->u.idxNext = 0;
    640725    return VINF_SUCCESS;
    641726}
     
    648733                                            RTFSOBJATTRADD enmAddAttr)
    649734{
    650     PRTFSPDBDIROBJ const  pThis     = (PRTFSPDBDIROBJ)pvThis;
    651     PRTFSPDBVOL    const  pPdb      = pThis->pPdb;
    652     uint32_t const        idxStream = pThis->idxNextStream;
     735    PRTFSPDBDIROBJ const  pThis        = (PRTFSPDBDIROBJ)pvThis;
     736    PRTFSPDBVOL    const  pPdb         = pThis->pPdb;
     737    uint32_t const        idxStream    = pThis->u.s.idxNextStream;
     738    uint32_t const        idxSubstream = pThis->u.s.idxNextSubstream;
    653739    if (idxStream < pPdb->cStreams)
    654740    {
     741        PCRTFSPDBSTREAMINFO const pStreamInfo    = pPdb->papStreamInfo[idxStream];
     742        PCRTFSPDBSUBSTREAM const  pSubstreamInfo = !idxSubstream ? NULL
     743                                                 : &pPdb->aSubstreams[pStreamInfo->idxFirstSubstream + idxSubstream - 1];
     744
    655745        /*
    656746         * Do names first as they may cause overflows.
     
    661751
    662752        /* Provide a more descriptive name if possible. */
    663         const char   *pszOtherName = pPdb->papStreamInfo[idxStream]->pszName;
     753        const char   *pszOtherName = !idxSubstream ? pStreamInfo->pszName : pSubstreamInfo->pszName;
    664754        size_t const  cchOtherName = pszOtherName ? strlen(pszOtherName) : 0;
    665755
     
    682772        pDirEntry->szName[cchName] = '\0';
    683773
    684         if (cchOtherName)
     774        if (cchOtherName && !idxSubstream)
    685775        {
    686776            Assert(cchStreamNo <= 8);
     
    697787
    698788        /* Provide the other info. */
    699         if (pPdb->enmVersion == RTFSPDBVER_2)
    700         {
    701             PCRTPDB20ROOT const pRoot = (PCRTPDB20ROOT)pPdb->pbRoot;
    702             rtFsPdbPopulateObjInfo(pPdb, &pDirEntry->Info, enmAddAttr,
    703                                    pRoot->aStreams[idxStream].cbStream, idxStream, false /*fIsDir*/);
     789        rtFsPdbPopulateObjInfo(pPdb, &pDirEntry->Info, enmAddAttr,
     790                               !pSubstreamInfo ? pStreamInfo->cbStream : pSubstreamInfo->cbSubstream,
     791                               idxStream, idxSubstream, false /*fIsDir*/);
     792
     793        /* Advance the directory location and return. */
     794        if (idxSubstream >= pStreamInfo->cSubstreams)
     795        {
     796            pThis->u.s.idxNextSubstream = 0;
     797            pThis->u.s.idxNextStream    = idxStream + 1;
    704798        }
    705799        else
    706         {
    707             PCRTPDB70ROOT const pRoot = (PCRTPDB70ROOT)pPdb->pbRoot;
    708             rtFsPdbPopulateObjInfo(pPdb, &pDirEntry->Info, enmAddAttr,
    709                                    pRoot->aStreams[idxStream].cbStream, idxStream, false /*fIsDir*/);
    710         }
    711 
    712         /* Advance the directory location and return. */
    713         pThis->idxNextStream = idxStream + 1;
     800            pThis->u.s.idxNextSubstream = idxSubstream + 1;
    714801
    715802        return VINF_SUCCESS;
    716803    }
    717804
    718     Log3(("rtFsPdbDir_ReadDir9660: idxNextStream=%#x: VERR_NO_MORE_FILES\n", pThis->idxNextStream));
     805    Log3(("rtFsPdbDir_ReadDir9660: idxNext=%#x: VERR_NO_MORE_FILES\n", pThis->u.idxNext));
    719806    return VERR_NO_MORE_FILES;
    720807}
     
    775862    pThis->pbRoot = NULL;
    776863
     864    RTMemFree(pThis->pszzNames);
     865    pThis->pszzNames = NULL;
     866
     867    if (pThis->papStreamInfo)
     868    {
     869        uint32_t idxStream = pThis->cStreams;
     870        while (idxStream-- > 0)
     871            RTMemFree(pThis->papStreamInfo[idxStream]);
     872        RTMemFree(pThis->papStreamInfo);
     873        pThis->papStreamInfo = NULL;
     874    }
     875    pThis->cStreams = 0;
     876
    777877    return VINF_SUCCESS;
    778878}
     
    876976    if (RT_SUCCESS(rc))
    877977    {
    878         pNewDir->pPdb          = pThis;
    879         pNewDir->idxNextStream = 0;
     978        pNewDir->pPdb      = pThis;
     979        pNewDir->u.idxNext = 0;
    880980        return VINF_SUCCESS;
    881981    }
     
    9121012};
    9131013
     1014
     1015/**
     1016 * Internal helper for reading an entire stream into a heap block.
     1017 *
     1018 * Use RTMemTmpFree to free the returned memory when done.
     1019 */
    9141020static int rtFsPdbVolReadStreamToHeap(PRTFSPDBVOL pThis, uint32_t idxStream,
    9151021                                      uint8_t **ppbStream, uint32_t *pcbStream, PRTERRINFO pErrInfo)
     
    9241030     */
    9251031    RTFSPDBFILEOBJ FileObj;
    926     rtFsPdbPopulateFileObjFromInfo(&FileObj, pThis, idxStream);
     1032    rtFsPdbPopulateFileObjFromInfo(&FileObj, pThis, idxStream, NULL);
    9271033
    9281034    size_t const    cbDst = (size_t)FileObj.cbStream + !FileObj.cbStream;
     
    9451051        RTMemTmpFree(pbDst);
    9461052    return rc;
     1053}
     1054
     1055
     1056/**
     1057 * Internal helper for reading from a stream.
     1058 */
     1059static int rtFsPdbVolReadStreamAt(PRTFSPDBVOL pThis, uint32_t idxStream, uint32_t offStream,
     1060                                  void *pvBuf, size_t cbToRead, size_t *pcbRead)
     1061{
     1062    RTFSPDBFILEOBJ FileObj;
     1063    rtFsPdbPopulateFileObjFromInfo(&FileObj, pThis, idxStream, NULL);
     1064
     1065    RTSGSEG SgSeg = { pvBuf, cbToRead };
     1066    RTSGBUF SgBuf;
     1067    RTSgBufInit(&SgBuf, &SgSeg, 1);
     1068
     1069    return rtFsPdbFile_Read(&FileObj, offStream, &SgBuf, true /*fBlocking*/, pcbRead);
     1070}
     1071
     1072
     1073/**
     1074 * Adds a substream.
     1075 */
     1076static void rtFsPdbVolAddSubstream(PRTFSPDBVOL pThis, uint32_t idxStream, uint8_t idxSubstream,
     1077                                   uint32_t offSubstream, uint32_t cbSubstream, const char *pszName)
     1078{
     1079    /*
     1080     * Sanity checking.
     1081     */
     1082    Assert(idxSubstream > 0); /* zero is used for the parent stream when enumerating directories. */
     1083
     1084    AssertReturnVoid(idxStream < pThis->cStreams);
     1085    PRTFSPDBSTREAMINFO const pStreamInfo = pThis->papStreamInfo[idxStream];
     1086    Assert(RTStrStartsWith(pszName, pStreamInfo->pszName));
     1087    AssertReturnVoid(offSubstream < pStreamInfo->cbStream);
     1088    AssertStmt(cbSubstream <= pStreamInfo->cbStream - offSubstream, cbSubstream = pStreamInfo->cbStream - offSubstream);
     1089
     1090    AssertReturnVoid(pThis->cSubstreams < RT_ELEMENTS(pThis->aSubstreams));
     1091    PRTFSPDBSUBSTREAM const pSubstreamInfo = &pThis->aSubstreams[pThis->cSubstreams];
     1092    Assert(   pThis->cSubstreams == 0
     1093           || pSubstreamInfo[-1].idxStream < idxStream
     1094           || (   pSubstreamInfo[-1].idxStream == idxStream
     1095               && pSubstreamInfo[-1].idxSubstream < idxSubstream
     1096               && pSubstreamInfo[-1].offSubstream <= offSubstream));
     1097
     1098    /*
     1099     * Add it.
     1100     */
     1101    pSubstreamInfo->idxStream    = idxStream;
     1102    pSubstreamInfo->idxSubstream = idxSubstream;
     1103    pSubstreamInfo->offSubstream = offSubstream;
     1104    pSubstreamInfo->cbSubstream  = cbSubstream;
     1105    pSubstreamInfo->pszName      = pszName;
     1106
     1107    if (!pStreamInfo->cSubstreams)
     1108        pStreamInfo->idxFirstSubstream = pThis->cSubstreams;
     1109    pStreamInfo->cSubstreams++;
     1110
     1111    pThis->cSubstreams++;
     1112}
     1113
     1114
     1115/**
     1116 * Helper for rtFsPdbVolLoadStream3 to set standard stream names.
     1117 */
     1118static void rtFsPdbVolSetDefaultStreamName(PRTFSPDBVOL pThis, uint32_t idxStream, const char *pszDefaultName)
     1119{
     1120    if (idxStream < pThis->cStreams)
     1121    {
     1122        /* We override entries from the string table, as the standard stream
     1123           names must be assumed to work when the streams are present! */
     1124        if ((uintptr_t)pThis->papStreamInfo[idxStream]->pszName - (uintptr_t)pThis->pszzNames < pThis->cbNames)
     1125            Log(("rtFsPdbVolSetDefaultStreamName: Overriding string table name for stream %#x: %s -> %s\n",
     1126                 idxStream, pThis->papStreamInfo[idxStream]->pszName, pszDefaultName));
     1127        pThis->papStreamInfo[idxStream]->pszName = pszDefaultName;
     1128    }
     1129}
     1130
     1131
     1132/**
     1133 * Worker for rtFsPdbVolTryInit that extracts info from the DBI stream.
     1134 */
     1135static int rtFsPdbVolLoadStream3(PRTFSPDBVOL pThis, PRTERRINFO pErrInfo)
     1136{
     1137    /* On the offchance that the DBI stream is missing... */
     1138    if (3 >= pThis->cStreams)
     1139        return VINF_SUCCESS;
     1140
     1141    /*
     1142     * Read the header.
     1143     */
     1144    union
     1145    {
     1146        RTPDBDBIHDR     New;
     1147        RTPDBDBIHDROLD  Old;
     1148        uint16_t        aidxStream[32];
     1149    } Hdr;
     1150    size_t cbRead = 0;
     1151    int rc = rtFsPdbVolReadStreamAt(pThis, 3, 0, &Hdr, sizeof(Hdr.New), &cbRead);
     1152    if (RT_FAILURE(rc))
     1153        return RTERRINFO_LOG_SET_F(pErrInfo, rc, "Error eeading the DBI header");
     1154
     1155    if (Hdr.New.uSignature == RTPDBDBIHDR_SIGNATURE)
     1156    {
     1157        Log(("rtFsPdbVolLoadStream3: New DBI header\n"));
     1158        if (cbRead != sizeof(Hdr.New))
     1159            return RTERRINFO_LOG_SET_F(pErrInfo, rc, "Bogus DBI header size: cbRead=%#zx, expected %#zx",
     1160                                       cbRead, sizeof(Hdr.New));
     1161        if (Hdr.New.uVcVersion < RTPDBDBIHDR_VCVER_50)
     1162            return RTERRINFO_LOG_SET_F(pErrInfo, rc, "Bogus DBI header version: %u (%#x), expected min %u",
     1163                                       Hdr.New.uVcVersion, Hdr.New.uVcVersion, RTPDBDBIHDR_VCVER_50);
     1164        if (Hdr.New.uVcVersion < RTPDBDBIHDR_VCVER_60)
     1165            Hdr.New.cbEditContinueSubstream = 0;
     1166        pThis->DbiHdr = Hdr.New;
     1167    }
     1168    else
     1169    {
     1170        /* Convert old header to new to new. */
     1171        if (cbRead >= sizeof(Hdr.Old))
     1172            return RTERRINFO_LOG_SET_F(pErrInfo, rc, "Bogus DBI header size: cbRead=%#zx, expected %#zx",
     1173                                       cbRead, sizeof(Hdr.Old));
     1174        Log(("rtFsPdbVolLoadStream3: Old DBI header\n"));
     1175        RT_ZERO(pThis->DbiHdr);
     1176        pThis->DbiHdr.idxMFC                    = UINT16_MAX;
     1177        pThis->DbiHdr.idxGlobalStream           = Hdr.Old.idxGlobalStream;
     1178        pThis->DbiHdr.idxPublicStream           = Hdr.Old.idxPublicStream;
     1179        pThis->DbiHdr.idxSymRecStream           = Hdr.Old.idxSymRecStream;
     1180        pThis->DbiHdr.cbModInfoSubstream        = Hdr.Old.cbModInfoSubstream;
     1181        pThis->DbiHdr.cbSectContribSubstream    = Hdr.Old.cbSectContribSubstream;
     1182        pThis->DbiHdr.cbSrcInfoSubstream        = Hdr.Old.cbSrcInfoSubstream;
     1183        pThis->DbiHdr.uAge                      = pThis->uAge;
     1184    }
     1185
     1186    Log2(("  DBI Hdr uSignature               = %#x\n", pThis->DbiHdr.uSignature));
     1187    Log2(("  DBI Hdr uVcVersion               = %#x\n", pThis->DbiHdr.uVcVersion));
     1188    if (pThis->DbiHdr.uAge == pThis->uAge)
     1189        Log2(("  DBI Hdr uAge                     = %#x (same as PDB header)\n", pThis->DbiHdr.uAge));
     1190    else
     1191        Log2(("  DBI Hdr uAge                     = %#x - differs from DB.uAge %#x!\n", pThis->DbiHdr.uAge, pThis->uAge));
     1192    Log2(("  DBI Hdr idxGlobalStream          = %#x\n", pThis->DbiHdr.idxGlobalStream));
     1193    if (pThis->DbiHdr.PdbDllVer.New.fNewVerFmt)
     1194    {
     1195        Log2(("  DBI Hdr PdbDllVer.u16            = %#x - %u.%u (new)\n", pThis->DbiHdr.PdbDllVer.u16,
     1196              pThis->DbiHdr.PdbDllVer.New.uMajor, pThis->DbiHdr.PdbDllVer.New.uMinor));
     1197        Log2(("  DBI Hdr uPdbDllBuild             = %u (%#x)\n", pThis->DbiHdr.uPdbDllBuild, pThis->DbiHdr.uPdbDllBuild));
     1198        Log2(("  DBI Hdr uPdbDllRBuild            = %u (%#x)\n", pThis->DbiHdr.uPdbDllRBuild, pThis->DbiHdr.uPdbDllRBuild));
     1199    }
     1200    else
     1201    {
     1202        Log2(("  DBI Hdr PdbDllVer                = %#x - %u.%u.%u (old)\n", pThis->DbiHdr.PdbDllVer.u16,
     1203              pThis->DbiHdr.PdbDllVer.Old.uMajor, pThis->DbiHdr.PdbDllVer.Old.uMinor,
     1204              pThis->DbiHdr.PdbDllVer.Old.uRBuild));
     1205        if (pThis->DbiHdr.uPdbDllBuild)
     1206            Log2(("  DBI Hdr uPdbDllBuild             = %u (%#x)!!\n", pThis->DbiHdr.uPdbDllBuild, pThis->DbiHdr.uPdbDllBuild));
     1207        if (pThis->DbiHdr.uPdbDllRBuild)
     1208            Log2(("  DBI Hdr uPdbDllRBuild            = %u (%#x)!!\n", pThis->DbiHdr.uPdbDllRBuild, pThis->DbiHdr.uPdbDllRBuild));
     1209    }
     1210    Log2(("  DBI Hdr idxPublicStream          = %#x\n", pThis->DbiHdr.idxPublicStream));
     1211    Log2(("  DBI Hdr idxSymRecStream          = %#x\n", pThis->DbiHdr.idxSymRecStream));
     1212    Log2(("  DBI Hdr cbModInfoSubstream       = %#x\n", pThis->DbiHdr.cbModInfoSubstream));
     1213    Log2(("  DBI Hdr cbSectContribSubstream   = %#x\n", pThis->DbiHdr.cbSectContribSubstream));
     1214    Log2(("  DBI Hdr cbSectionMapSubstream    = %#x\n", pThis->DbiHdr.cbSectionMapSubstream));
     1215    Log2(("  DBI Hdr cbSrcInfoSubstream       = %#x\n", pThis->DbiHdr.cbSrcInfoSubstream));
     1216    Log2(("  DBI Hdr cbTypeServerMapSubstream = %#x\n", pThis->DbiHdr.cbTypeServerMapSubstream));
     1217    Log2(("  DBI Hdr idxMFC                   = %#x\n", pThis->DbiHdr.idxMFC));
     1218    Log2(("  DBI Hdr cbOptDbgHdr              = %#x\n", pThis->DbiHdr.cbOptDbgHdr));
     1219    Log2(("  DBI Hdr cbEditContinueSubstream  = %#x\n", pThis->DbiHdr.cbEditContinueSubstream));
     1220    Log2(("  DBI Hdr fFlags                   = %#x%s%s%s%s%s\n", pThis->DbiHdr.fFlags, pThis->DbiHdr.fFlags ? " -" : "",
     1221          pThis->DbiHdr.fFlags & RTPDBDBIHDR_F_INCREMENTAL_LINK      ? " IncrmentalLink" : "",
     1222          pThis->DbiHdr.fFlags & RTPDBDBIHDR_F_PRIVATE_SYMS_STRIPPED ? " PrivateSymsStripped" : "",
     1223          pThis->DbiHdr.fFlags & RTPDBDBIHDR_F_CONFLICTING_TYPES     ? " ConflictingTypes" : "",
     1224          pThis->DbiHdr.fFlags & RTPDBDBIHDR_F_RESERVED              ? " !ReservedFlagsSet!" : ""));
     1225    Log2(("  DBI Hdr uMachine                 = %#x\n", pThis->DbiHdr.uMachine));
     1226    Log2(("  DBI Hdr uReserved                = %#x\n", pThis->DbiHdr.uReserved));
     1227
     1228    /*
     1229     * Apply new standard stream names.
     1230     */
     1231    rtFsPdbVolSetDefaultStreamName(pThis, pThis->DbiHdr.idxGlobalStream, "global-symbol-hash");
     1232    rtFsPdbVolSetDefaultStreamName(pThis, pThis->DbiHdr.idxPublicStream, "public-symbol-hash");
     1233    rtFsPdbVolSetDefaultStreamName(pThis, pThis->DbiHdr.idxSymRecStream, "symbol-records");
     1234
     1235    /*
     1236     * Fill in substream info.
     1237     */
     1238    uint32_t offSubstream = sizeof(Hdr.New);
     1239    if (pThis->DbiHdr.cbModInfoSubstream)
     1240    {
     1241        rtFsPdbVolAddSubstream(pThis, 3, 1, offSubstream, pThis->DbiHdr.cbModInfoSubstream, "dbi-module-info");
     1242        offSubstream += pThis->DbiHdr.cbModInfoSubstream;
     1243    }
     1244    if (pThis->DbiHdr.cbSectContribSubstream)
     1245    {
     1246        rtFsPdbVolAddSubstream(pThis, 3, 2, offSubstream, pThis->DbiHdr.cbSectContribSubstream, "dbi-section-contributions");
     1247        offSubstream += pThis->DbiHdr.cbSectContribSubstream;
     1248    }
     1249    if (pThis->DbiHdr.cbSectionMapSubstream)
     1250    {
     1251        rtFsPdbVolAddSubstream(pThis, 3, 3, offSubstream, pThis->DbiHdr.cbSectionMapSubstream, "dbi-section-map");
     1252        offSubstream += pThis->DbiHdr.cbSectionMapSubstream;
     1253    }
     1254    if (pThis->DbiHdr.cbSrcInfoSubstream)
     1255    {
     1256        rtFsPdbVolAddSubstream(pThis, 3, 4, offSubstream, pThis->DbiHdr.cbSrcInfoSubstream, "dbi-source-info");
     1257        offSubstream += pThis->DbiHdr.cbSrcInfoSubstream;
     1258    }
     1259    if (pThis->DbiHdr.cbTypeServerMapSubstream)
     1260    {
     1261        rtFsPdbVolAddSubstream(pThis, 3, 5, offSubstream, pThis->DbiHdr.cbTypeServerMapSubstream, "dbi-type-server-map");
     1262        offSubstream += pThis->DbiHdr.cbTypeServerMapSubstream;
     1263    }
     1264    if (pThis->DbiHdr.cbEditContinueSubstream)
     1265    {
     1266        rtFsPdbVolAddSubstream(pThis, 3, 6, offSubstream, pThis->DbiHdr.cbEditContinueSubstream, "dbi-continue-and-edit");
     1267        offSubstream += pThis->DbiHdr.cbEditContinueSubstream;
     1268    }
     1269    uint32_t const offOptDbgHdr = offSubstream;
     1270    if (pThis->DbiHdr.cbOptDbgHdr)
     1271    {
     1272        rtFsPdbVolAddSubstream(pThis, 3, 7, offSubstream, pThis->DbiHdr.cbOptDbgHdr, "dbi-optional-header");
     1273        offSubstream += pThis->DbiHdr.cbOptDbgHdr;
     1274    }
     1275    if (offSubstream < pThis->papStreamInfo[3]->cbStream)
     1276        rtFsPdbVolAddSubstream(pThis, 3, 8, offSubstream, pThis->papStreamInfo[3]->cbStream - offSubstream, "dbi-unknown");
     1277
     1278    /*
     1279     * Read the optional header if present, it identifies a bunch of standard streams.
     1280     */
     1281    if (pThis->DbiHdr.cbOptDbgHdr > 1)
     1282    {
     1283        RT_ZERO(Hdr);
     1284        rc = rtFsPdbVolReadStreamAt(pThis, 3, offOptDbgHdr, &Hdr, RT_MIN(sizeof(Hdr), pThis->DbiHdr.cbOptDbgHdr), &cbRead);
     1285        if (RT_FAILURE(rc))
     1286            return RTERRINFO_LOG_SET_F(pErrInfo, rc, "Error eeading the DBI optional header at %#x LB %#x",
     1287                                       offOptDbgHdr, pThis->DbiHdr.cbOptDbgHdr);
     1288        static const char * const s_apszIdxNames[] =
     1289        {
     1290            /* [RTPDBDBIOPT_IDX_FPO_MASM] = */              "image-fpo-masm-section",
     1291            /* [RTPDBDBIOPT_IDX_EXCEPTION] = */             "image-exception",
     1292            /* [RTPDBDBIOPT_IDX_FIXUP] = */                 "image-fixup",
     1293            /* [RTPDBDBIOPT_IDX_OMAP_TO_SRC] = */           "omap-to-src",
     1294            /* [RTPDBDBIOPT_IDX_OMAP_FROM_SRC] = */         "omap-from-src",
     1295            /* [RTPDBDBIOPT_IDX_SECTION_HEADERS] = */       "image-section-headers",
     1296            /* [RTPDBDBIOPT_IDX_CLR_TOKEN_ID_MAP] = */      "clr-token-id-map",
     1297            /* [RTPDBDBIOPT_IDX_XDATA] = */                 "image-xdata-section",
     1298            /* [RTPDBDBIOPT_IDX_PDATA] = */                 "image-pdata-section",
     1299            /* [RTPDBDBIOPT_IDX_FPO] = */                   "image-fpo",
     1300            /* [RTPDBDBIOPT_IDX_ORG_SECTION_HEADERS] = */   "image-orginal-section-headers",
     1301        };
     1302        uint32_t idxName = pThis->DbiHdr.cbOptDbgHdr / 2;
     1303        if (idxName > RT_ELEMENTS(s_apszIdxNames))
     1304        {
     1305#ifdef LOG_ENABLED
     1306            while (idxName-- > RT_ELEMENTS(s_apszIdxNames))
     1307                Log(("Unknown DBI optional header entry %u: %#x\n", idxName, Hdr.aidxStream[idxName]));
     1308#endif
     1309            idxName = RT_ELEMENTS(s_apszIdxNames);
     1310        }
     1311        while (idxName-- > 0)
     1312            rtFsPdbVolSetDefaultStreamName(pThis, Hdr.aidxStream[idxName], s_apszIdxNames[idxName]);
     1313    }
     1314
     1315    return VINF_SUCCESS;
    9471316}
    9481317
     
    11321501        case 5:
    11331502            if (pThis->enmVersion == RTFSPDBVER_7) /** @todo condition? */
    1134                 pThis->papStreamInfo[3]->pszName = "name-map";
     1503                pThis->papStreamInfo[4]->pszName = "name-map";
    11351504            RT_FALL_THRU();
    11361505        case 4:
    1137             pThis->papStreamInfo[3]->pszName = "dbi"; /** @todo conditional? */
     1506            pThis->papStreamInfo[3]->pszName = "dbi";
    11381507            RT_FALL_THRU();
    11391508        case 3:
     
    12181587    pThis->pszzNames        = NULL;
    12191588    pThis->papStreamInfo    = NULL;
     1589    pThis->cSubstreams      = 0;
    12201590
    12211591    /*
     
    14291799
    14301800    /*
    1431      * Load stream #1 if there.
    1432      */
    1433     return rtFsPdbVolLoadStream1(pThis, pErrInfo);
     1801     * Load info from streams #1 (PDB & names) and #3 (DBI).
     1802     */
     1803    rc = rtFsPdbVolLoadStream1(pThis, pErrInfo);
     1804    if (RT_SUCCESS(rc))
     1805        rc = rtFsPdbVolLoadStream3(pThis, pErrInfo);
     1806    return rc;
    14341807}
    14351808
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette