/* * Build the list with endnote information for Word 6/7 files */ static void vGet6EndnotesInfo(FILE *pFile, ULONG ulStartBlock, const ULONG *aulBBD, size_t tBBDLen, const UCHAR *aucHeader) { UCHAR *aucBuffer; ULONG ulFileOffset, ulBeginOfText, ulOffset, ulBeginEndnoteInfo; size_t tEndnoteInfoLen; size_t tIndex; TRACE_MSG("vGet6EndnotesInfo"); fail(pFile == NULL || aucHeader == NULL); fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN); fail(aulBBD == NULL); ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */ NO_DBG_HEX(ulBeginOfText); ulBeginEndnoteInfo = ulGetLong(0x1d2, aucHeader); /* fcPlcfendRef */ NO_DBG_HEX(ulBeginEndnoteInfo); tEndnoteInfoLen = (size_t)ulGetLong(0x1d6, aucHeader); /* lcbPlcfendRef */ NO_DBG_DEC(tEndnoteInfoLen); if (tEndnoteInfoLen < 10) { DBG_MSG("No Endnotes in this document"); return; } aucBuffer = xmalloc(tEndnoteInfoLen); if (!bReadBuffer(pFile, ulStartBlock, aulBBD, tBBDLen, BIG_BLOCK_SIZE, aucBuffer, ulBeginEndnoteInfo, tEndnoteInfoLen)) { aucBuffer = xfree(aucBuffer); return; } NO_DBG_PRINT_BLOCK(aucBuffer, tEndnoteInfoLen); fail(tEndnoteListLength != 0); tEndnoteListLength = (tEndnoteInfoLen - 4) / 6; fail(tEndnoteListLength == 0); fail(aulEndnoteList != NULL); aulEndnoteList = xcalloc(tEndnoteListLength, sizeof(ULONG)); for (tIndex = 0; tIndex < tEndnoteListLength; tIndex++) { ulOffset = ulGetLong(tIndex * 4, aucBuffer); NO_DBG_HEX(ulOffset); ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset); NO_DBG_HEX(ulFileOffset); aulEndnoteList[tIndex] = ulFileOffset; } aucBuffer = xfree(aucBuffer); } /* end of vGet6EndnotesInfo */
/* * Build the list with Header/Footer Information for Word 6/7 files */ void vGet6HdrFtrInfo(FILE *pFile, ULONG ulStartBlock, const ULONG *aulBBD, size_t tBBDLen, const UCHAR *aucHeader) { ULONG *aulCharPos; UCHAR *aucBuffer; ULONG ulHdrFtrOffset, ulBeginHdrFtrInfo; size_t tHdrFtrInfoLen, tIndex, tOffset, tLen; fail(pFile == NULL || aucHeader == NULL); fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN); fail(aulBBD == NULL); ulBeginHdrFtrInfo = ulGetLong(0xb0, aucHeader); /* fcPlcfhdd */ NO_DBG_HEX(ulBeginHdrFtrInfo); tHdrFtrInfoLen = (size_t)ulGetLong(0xb4, aucHeader); /* lcbPlcfhdd */ NO_DBG_DEC(tHdrFtrInfoLen); if (tHdrFtrInfoLen < 8) { DBG_DEC_C(tHdrFtrInfoLen != 0, tHdrFtrInfoLen); return; } aucBuffer = xmalloc(tHdrFtrInfoLen); if (!bReadBuffer(pFile, ulStartBlock, aulBBD, tBBDLen, BIG_BLOCK_SIZE, aucBuffer, ulBeginHdrFtrInfo, tHdrFtrInfoLen)) { aucBuffer = xfree(aucBuffer); return; } NO_DBG_PRINT_BLOCK(aucBuffer, tHdrFtrInfoLen); tLen = tHdrFtrInfoLen / 4 - 1; /* Save the header/footer offsets */ aulCharPos = xcalloc(tLen, sizeof(ULONG)); for (tIndex = 0, tOffset = 0; tIndex < tLen; tIndex++, tOffset += 4) { ulHdrFtrOffset = ulGetLong(tOffset, aucBuffer); NO_DBG_HEX(ulHdrFtrOffset); aulCharPos[tIndex] = ulHdrFtrOffset2CharPos(ulHdrFtrOffset); NO_DBG_HEX(aulCharPos[tIndex]); } vCreat6HdrFtrInfoList(aulCharPos, tLen); aulCharPos = xfree(aulCharPos); aucBuffer = xfree(aucBuffer); } /* end of vGet6HdrFtrInfo */
/* * aucFillInfoBuffer - fill the information buffer * * Returns the information buffer when successful, otherwise NULL */ static UCHAR * aucFillInfoBuffer(FILE *pFile, const pps_type *pTable, const ULONG *aulBBD, size_t tBBDLen, const ULONG *aulSBD, size_t tSBDLen, ULONG ulBeginInfo, size_t tInfoLen) { const ULONG *aulBlockDepot; UCHAR *aucBuffer; size_t tBlockDepotLen, tBlockSize; fail(pFile == NULL || pTable == NULL); fail(aulBBD == NULL || aulSBD == NULL); fail(tInfoLen == 0); NO_DBG_DEC(pTable->ulSB); NO_DBG_HEX(pTable->ulSize); if (pTable->ulSize == 0) { DBG_MSG("No information"); return NULL; } if (pTable->ulSize < MIN_SIZE_FOR_BBD_USE) { /* Use the Small Block Depot */ aulBlockDepot = aulSBD; tBlockDepotLen = tSBDLen; tBlockSize = SMALL_BLOCK_SIZE; } else { /* Use the Big Block Depot */ aulBlockDepot = aulBBD; tBlockDepotLen = tBBDLen; tBlockSize = BIG_BLOCK_SIZE; } aucBuffer = xmalloc(tInfoLen); if (!bReadBuffer(pFile, pTable->ulSB, aulBlockDepot, tBlockDepotLen, tBlockSize, aucBuffer, ulBeginInfo, tInfoLen)) { aucBuffer = xfree(aucBuffer); return NULL; } return aucBuffer; } /* end of aucFillInfoBuffer */
/* * Build the lists with Document Property Information for Word 6/7 files */ void vGet6DopInfo(FILE *pFile, ULONG ulStartBlock, const ULONG *aulBBD, size_t tBBDLen, const UCHAR *aucHeader) { document_block_type tDocument; UCHAR *aucBuffer; ULONG ulBeginDocpInfo, ulTmp; size_t tDocpInfoLen; USHORT usTmp; ulBeginDocpInfo = ulGetLong(0x150, aucHeader); /* fcDop */ DBG_HEX(ulBeginDocpInfo); tDocpInfoLen = (size_t)ulGetLong(0x154, aucHeader); /* lcbDop */ DBG_DEC(tDocpInfoLen); if (tDocpInfoLen < 28) { DBG_MSG("No Document information"); return; } aucBuffer = xmalloc(tDocpInfoLen); if (!bReadBuffer(pFile, ulStartBlock, aulBBD, tBBDLen, BIG_BLOCK_SIZE, aucBuffer, ulBeginDocpInfo, tDocpInfoLen)) { aucBuffer = xfree(aucBuffer); return; } usTmp = usGetWord(0x00, aucBuffer); tDocument.ucHdrFtrSpecification = (UCHAR)(usTmp >> 8); /* grpfIhdt */ tDocument.usDefaultTabWidth = usGetWord(0x0a, aucBuffer); /* dxaTab */ ulTmp = ulGetLong(0x14, aucBuffer); /* dttmCreated */ tDocument.tCreateDate = tConvertDTTM(ulTmp); ulTmp = ulGetLong(0x18, aucBuffer); /* dttmRevised */ tDocument.tRevisedDate = tConvertDTTM(ulTmp); vCreateDocumentInfoList(&tDocument); aucBuffer = xfree(aucBuffer); } /* end of vGet6DopInfo */
/* * pucAnalyseSummaryInfoHeader- */ static UCHAR * pucAnalyseSummaryInfoHeader(FILE *pFile, ULONG ulStartBlock, ULONG ulSize, const ULONG *aulBBD, size_t tBBDLen, const ULONG *aulSBD, size_t tSBDLen) { const ULONG *aulBlockDepot; UCHAR *aucBuffer; size_t tBlockDepotLen, tBlockSize, tSectionCount, tLength; ULONG ulTmp, ulOffset; USHORT usLittleEndian, usEmpty, usOS, usVersion; UCHAR aucHdr[P_HEADER_SZ], aucSecLst[P_SECTION_MAX_SZ]; if (ulSize < MIN_SIZE_FOR_BBD_USE) { /* Use the Small Block Depot */ aulBlockDepot = aulSBD; tBlockDepotLen = tSBDLen; tBlockSize = SMALL_BLOCK_SIZE; } else { /* Use the Big Block Depot */ aulBlockDepot = aulBBD; tBlockDepotLen = tBBDLen; tBlockSize = BIG_BLOCK_SIZE; } if (tBlockDepotLen == 0) { DBG_MSG("The Block Depot length is zero"); return NULL; } /* Read the Summery Information header */ if (!bReadBuffer(pFile, ulStartBlock, aulBlockDepot, tBlockDepotLen, tBlockSize, aucHdr, 0, P_HEADER_SZ)) { return NULL; } NO_DBG_PRINT_BLOCK(aucHdr, P_HEADER_SZ); /* Analyse the Summery Information header */ usLittleEndian = usGetWord(0, aucHdr); if (usLittleEndian != 0xfffe) { DBG_HEX(usLittleEndian); DBG_MSG_C(usLittleEndian == 0xfeff, "Big endian"); return NULL; } usEmpty = usGetWord(2, aucHdr); if (usEmpty != 0x0000) { DBG_DEC(usEmpty); return NULL; } ulTmp = ulGetLong(4, aucHdr); DBG_HEX(ulTmp); usOS = (USHORT)(ulTmp >> 16); usVersion = (USHORT)(ulTmp & 0xffff); switch (usOS) { case 0: DBG_MSG("Win16"); DBG_HEX(usVersion); break; case 1: DBG_MSG("MacOS"); DBG_HEX(usVersion); break; case 2: DBG_MSG("Win32"); DBG_HEX(usVersion); break; default: DBG_DEC(usOS); DBG_HEX(usVersion); break; } tSectionCount = (size_t)ulGetLong(24, aucHdr); DBG_DEC_C(tSectionCount != 1 && tSectionCount != 2, tSectionCount); if (tSectionCount != 1 && tSectionCount != 2) { return NULL; } /* Read the Summery Information Section Lists */ if (!bReadBuffer(pFile, ulStartBlock, aulBlockDepot, tBlockDepotLen, tBlockSize, aucSecLst, P_HEADER_SZ, P_SECTION_SZ(tSectionCount))) { return NULL; } NO_DBG_PRINT_BLOCK(aucSecLst, P_SECTION_SZ(tSectionCount)); ulTmp = ulGetLong(0, aucSecLst); DBG_HEX(ulTmp); ulTmp = ulGetLong(4, aucSecLst); DBG_HEX(ulTmp); ulTmp = ulGetLong(8, aucSecLst); DBG_HEX(ulTmp); ulTmp = ulGetLong(12, aucSecLst); DBG_HEX(ulTmp); ulOffset = ulGetLong(16, aucSecLst); DBG_DEC_C(ulOffset != P_HEADER_SZ + P_SECTIONLIST_SZ && ulOffset != P_HEADER_SZ + 2 * P_SECTIONLIST_SZ, ulOffset); fail(ulOffset != P_HEADER_SZ + P_SECTIONLIST_SZ && ulOffset != P_HEADER_SZ + 2 * P_SECTIONLIST_SZ); tLength = (size_t)ulGetLong(tSectionCount * P_SECTIONLIST_SZ, aucSecLst); NO_DBG_HEX(tLength); fail(ulOffset + tLength > ulSize); /* Read the Summery Information */ aucBuffer = xmalloc(tLength); if (!bReadBuffer(pFile, ulStartBlock, aulBlockDepot, tBlockDepotLen, tBlockSize, aucBuffer, ulOffset, tLength)) { aucBuffer = xfree(aucBuffer); return NULL; } NO_DBG_PRINT_BLOCK(aucBuffer, tLength); return aucBuffer; } /* end of pucAnalyseSummaryInfoHeader */
/* * Build the list with endnote information for Word 8/9/10 files */ static void vGet8EndnotesInfo(FILE *pFile, const pps_info_type *pPPS, const ULONG *aulBBD, size_t tBBDLen, const ULONG *aulSBD, size_t tSBDLen, const UCHAR *aucHeader) { const ULONG *aulBlockDepot; UCHAR *aucBuffer; ULONG ulFileOffset, ulBeginOfText, ulOffset, ulBeginEndnoteInfo; size_t tEndnoteInfoLen, tBlockDepotLen, tBlockSize; size_t tIndex; TRACE_MSG("vGet8EndnotesInfo"); ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */ NO_DBG_HEX(ulBeginOfText); ulBeginEndnoteInfo = ulGetLong(0x20a, aucHeader); /* fcPlcfendRef */ NO_DBG_HEX(ulBeginEndnoteInfo); tEndnoteInfoLen = (size_t)ulGetLong(0x20e, aucHeader); /* lcbPlcfendRef */ NO_DBG_DEC(tEndnoteInfoLen); if (tEndnoteInfoLen < 10) { DBG_MSG("No endnotes in this document"); return; } NO_DBG_DEC(pPPS->tTable.ulSB); NO_DBG_HEX(pPPS->tTable.ulSize); if (pPPS->tTable.ulSize == 0) { DBG_MSG("No endnotes information"); return; } if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) { /* Use the Small Block Depot */ aulBlockDepot = aulSBD; tBlockDepotLen = tSBDLen; tBlockSize = SMALL_BLOCK_SIZE; } else { /* Use the Big Block Depot */ aulBlockDepot = aulBBD; tBlockDepotLen = tBBDLen; tBlockSize = BIG_BLOCK_SIZE; } aucBuffer = xmalloc(tEndnoteInfoLen); if (!bReadBuffer(pFile, pPPS->tTable.ulSB, aulBlockDepot, tBlockDepotLen, tBlockSize, aucBuffer, ulBeginEndnoteInfo, tEndnoteInfoLen)) { aucBuffer = xfree(aucBuffer); return; } NO_DBG_PRINT_BLOCK(aucBuffer, tEndnoteInfoLen); fail(tEndnoteListLength != 0); tEndnoteListLength = (tEndnoteInfoLen - 4) / 6; fail(tEndnoteListLength == 0); fail(aulEndnoteList != NULL); aulEndnoteList = xcalloc(tEndnoteListLength, sizeof(ULONG)); for (tIndex = 0; tIndex < tEndnoteListLength; tIndex++) { ulOffset = ulGetLong(tIndex * 4, aucBuffer); NO_DBG_HEX(ulOffset); ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset); NO_DBG_HEX(ulFileOffset); aulEndnoteList[tIndex] = ulFileOffset; } aucBuffer = xfree(aucBuffer); } /* end of vGet8EndnotesInfo */
/* * Build the list with footnote text information for Word 8/9/10 files */ static void vGet8FootnotesText(FILE *pFile, const pps_info_type *pPPS, const ULONG *aulBBD, size_t tBBDLen, const ULONG *aulSBD, size_t tSBDLen, const UCHAR *aucHeader) { footnote_local_type *pCurr; const ULONG *aulBlockDepot; UCHAR *aucBuffer; ULONG ulCharPos, ulBeginOfFootnotes, ulOffset, ulBeginFootnoteText; size_t tFootnoteTextLen, tBlockDepotLen, tBlockSize; size_t tIndex; TRACE_MSG("vGet8FootnotesText"); ulBeginOfFootnotes = ulGetLong(0x18, aucHeader); /* fcMin */ ulBeginOfFootnotes += ulGetLong(0x4c, aucHeader); /* ccpText */ NO_DBG_HEX(ulBeginOfFootnotes); ulBeginFootnoteText = ulGetLong(0xb2, aucHeader); /* fcPlcffndTxt */ NO_DBG_HEX(ulBeginFootnoteText); tFootnoteTextLen = (size_t)ulGetLong(0xb6, aucHeader); /* lcbPlcffndTxt */ NO_DBG_DEC(tFootnoteTextLen); if (tFootnoteTextLen < 12) { DBG_MSG("No Footnote text in this document"); return; } NO_DBG_DEC(pPPS->tTable.ulSB); NO_DBG_HEX(pPPS->tTable.ulSize); if (pPPS->tTable.ulSize == 0) { DBG_MSG("No footnote text information"); return; } if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) { /* Use the Small Block Depot */ aulBlockDepot = aulSBD; tBlockDepotLen = tSBDLen; tBlockSize = SMALL_BLOCK_SIZE; } else { /* Use the Big Block Depot */ aulBlockDepot = aulBBD; tBlockDepotLen = tBBDLen; tBlockSize = BIG_BLOCK_SIZE; } aucBuffer = xmalloc(tFootnoteTextLen); if (!bReadBuffer(pFile, pPPS->tTable.ulSB, aulBlockDepot, tBlockDepotLen, tBlockSize, aucBuffer, ulBeginFootnoteText, tFootnoteTextLen)) { aucBuffer = xfree(aucBuffer); return; } NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteTextLen); fail(tFootnoteTextLength != 0); tFootnoteTextLength = tFootnoteTextLen / 4 - 2; fail(tFootnoteTextLength == 0); fail(pFootnoteText != NULL); pFootnoteText = xcalloc(tFootnoteTextLength, sizeof(footnote_local_type)); for (tIndex = 0; tIndex < tFootnoteTextLength; tIndex++) { pCurr = pFootnoteText + tIndex; pCurr->tInfo.szText = NULL; ulOffset = ulGetLong(tIndex * 4, aucBuffer); NO_DBG_HEX(ulOffset); ulCharPos = ulBeginOfFootnotes + ulOffset; NO_DBG_HEX(ulCharPos); NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos)); pCurr->ulCharPosStart = ulCharPos; ulOffset = ulGetLong(tIndex * 4 + 4, aucBuffer); NO_DBG_HEX(ulOffset); ulCharPos = ulBeginOfFootnotes + ulOffset; NO_DBG_HEX(ulCharPos); NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos)); pCurr->ulCharPosNext = ulCharPos; pCurr->bUseful = pCurr->ulCharPosStart != pCurr->ulCharPosNext; } aucBuffer = xfree(aucBuffer); } /* end of vGet8FootnotesText */
/* * Build the list with footnote text information for Word 6/7 files */ static void vGet6FootnotesText(FILE *pFile, ULONG ulStartBlock, const ULONG *aulBBD, size_t tBBDLen, const UCHAR *aucHeader) { footnote_local_type *pCurr; UCHAR *aucBuffer; ULONG ulCharPos, ulBeginOfFootnotes, ulOffset, ulBeginFootnoteText; size_t tFootnoteTextLen; size_t tIndex; TRACE_MSG("vGet6FootnotesText"); fail(pFile == NULL || aucHeader == NULL); fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN); fail(aulBBD == NULL); ulBeginOfFootnotes = ulGetLong(0x18, aucHeader); /* fcMin */ ulBeginOfFootnotes += ulGetLong(0x34, aucHeader); /* ccpText */ NO_DBG_HEX(ulBeginOfFootnotes); ulBeginFootnoteText = ulGetLong(0x70, aucHeader); /* fcPlcffndTxt */ NO_DBG_HEX(ulBeginFootnoteText); tFootnoteTextLen = (size_t)ulGetLong(0x74, aucHeader); /* lcbPlcffndTxt */ NO_DBG_DEC(tFootnoteTextLen); if (tFootnoteTextLen < 12) { DBG_MSG("No Footnote text in this document"); return; } aucBuffer = xmalloc(tFootnoteTextLen); if (!bReadBuffer(pFile, ulStartBlock, aulBBD, tBBDLen, BIG_BLOCK_SIZE, aucBuffer, ulBeginFootnoteText, tFootnoteTextLen)) { aucBuffer = xfree(aucBuffer); return; } NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteTextLen); fail(tFootnoteTextLength != 0); tFootnoteTextLength = tFootnoteTextLen / 4 - 2; fail(tFootnoteTextLength == 0); fail(pFootnoteText != NULL); pFootnoteText = xcalloc(tFootnoteTextLength, sizeof(footnote_local_type)); for (tIndex = 0; tIndex < tFootnoteTextLength; tIndex++) { pCurr = pFootnoteText + tIndex; pCurr->tInfo.szText = NULL; ulOffset = ulGetLong(tIndex * 4, aucBuffer); NO_DBG_HEX(ulOffset); ulCharPos = ulBeginOfFootnotes + ulOffset; NO_DBG_HEX(ulCharPos); NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos)); pCurr->ulCharPosStart = ulCharPos; ulOffset = ulGetLong(tIndex * 4 + 4, aucBuffer); NO_DBG_HEX(ulOffset); ulCharPos = ulBeginOfFootnotes + ulOffset; NO_DBG_HEX(ulCharPos); NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos)); pCurr->ulCharPosNext = ulCharPos; pCurr->bUseful = pCurr->ulCharPosStart != pCurr->ulCharPosNext; } aucBuffer = xfree(aucBuffer); } /* end of vGet6FootnotesText */
/* * Build the lists with Paragraph Information for Word 8/9/10/11 files */ void vGet8PapInfo(FILE *pFile, const pps_info_type *pPPS, const ULONG *aulBBD, size_t tBBDLen, const ULONG *aulSBD, size_t tSBDLen, const UCHAR *aucHeader) { row_block_type tRow; style_block_type tStyle; ULONG *aulParfPage; UCHAR *aucBuffer; ULONG ulCharPos, ulCharPosFirst, ulCharPosLast; ULONG ulBeginParfInfo; size_t tParfInfoLen, tOffset, tLen; int iIndex, iIndex2, iRun, iFodo, iLen; row_info_enum eRowInfo; USHORT usIstd; UCHAR aucFpage[BIG_BLOCK_SIZE]; fail(pFile == NULL || pPPS == NULL || aucHeader == NULL); fail(aulBBD == NULL || aulSBD == NULL); ulBeginParfInfo = ulGetLong(0x102, aucHeader); /* fcPlcfbtePapx */ NO_DBG_HEX(ulBeginParfInfo); tParfInfoLen = (size_t)ulGetLong(0x106, aucHeader); /* lcbPlcfbtePapx */ NO_DBG_DEC(tParfInfoLen); if (tParfInfoLen < 4) { DBG_DEC(tParfInfoLen); return; } aucBuffer = aucFillInfoBuffer(pFile, &pPPS->tTable, aulBBD, tBBDLen, aulSBD, tSBDLen, ulBeginParfInfo, tParfInfoLen); if (aucBuffer == NULL) { return; } NO_DBG_PRINT_BLOCK(aucBuffer, tParfInfoLen); tLen = (tParfInfoLen / 4 - 1) / 2; aulParfPage = xcalloc(tLen, sizeof(ULONG)); for (iIndex = 0, tOffset = (tLen + 1) * 4; iIndex < (int)tLen; iIndex++, tOffset += 4) { aulParfPage[iIndex] = ulGetLong(tOffset, aucBuffer); NO_DBG_DEC(aulParfPage[iIndex]); } DBG_HEX(ulGetLong(0, aucBuffer)); aucBuffer = xfree(aucBuffer); NO_DBG_PRINT_BLOCK(aucHeader, HEADER_SIZE); (void)memset(&tRow, 0, sizeof(tRow)); ulCharPosFirst = CP_INVALID; for (iIndex = 0; iIndex < (int)tLen; iIndex++) { fail(aulParfPage[iIndex] > ULONG_MAX / BIG_BLOCK_SIZE); if (!bReadBuffer(pFile, pPPS->tWordDocument.ulSB, aulBBD, tBBDLen, BIG_BLOCK_SIZE, aucFpage, aulParfPage[iIndex] * BIG_BLOCK_SIZE, BIG_BLOCK_SIZE)) { break; } NO_DBG_PRINT_BLOCK(aucFpage, BIG_BLOCK_SIZE); iRun = (int)ucGetByte(0x1ff, aucFpage); NO_DBG_DEC(iRun); for (iIndex2 = 0; iIndex2 < iRun; iIndex2++) { NO_DBG_HEX(ulGetLong(iIndex2 * 4, aucFpage)); iFodo = 2 * (int)ucGetByte( (iRun + 1) * 4 + iIndex2 * 13, aucFpage); if (iFodo <= 0) { continue; } iLen = 2 * (int)ucGetByte(iFodo, aucFpage); if (iLen == 0) { iFodo++; iLen = 2 * (int)ucGetByte(iFodo, aucFpage); } usIstd = usGetWord(iFodo + 1, aucFpage); vFillStyleFromStylesheet(usIstd, &tStyle); vGet8StyleInfo(iFodo, aucFpage + 3, iLen - 3, &tStyle); ulCharPos = ulGetLong(iIndex2 * 4, aucFpage); NO_DBG_HEX(ulCharPos); tStyle.ulFileOffset = ulCharPos2FileOffsetX( ulCharPos, &tStyle.eListID); vAdd2StyleInfoList(&tStyle); eRowInfo = eGet8RowInfo(iFodo, aucFpage + 3, iLen - 3, &tRow); switch (eRowInfo) { case found_a_cell: if (ulCharPosFirst != CP_INVALID) { break; } ulCharPosFirst = ulGetLong( iIndex2 * 4, aucFpage); NO_DBG_HEX(ulCharPosFirst); tRow.ulCharPosStart = ulCharPosFirst; tRow.ulFileOffsetStart = ulCharPos2FileOffset(ulCharPosFirst); NO_DBG_HEX_C( tRow.ulFileOffsetStart == FC_INVALID, ulCharPosFirst); break; case found_end_of_row: ulCharPosLast = ulGetLong( iIndex2 * 4, aucFpage); NO_DBG_HEX(ulCharPosLast); tRow.ulCharPosEnd = ulCharPosLast; tRow.ulFileOffsetEnd = ulCharPos2FileOffset(ulCharPosLast); NO_DBG_HEX_C(tRow.ulFileOffsetEnd == FC_INVALID, ulCharPosLast); vAdd2RowInfoList(&tRow); (void)memset(&tRow, 0, sizeof(tRow)); ulCharPosFirst = CP_INVALID; break; case found_nothing: break; default: DBG_DEC(eRowInfo); break; } } } aulParfPage = xfree(aulParfPage); } /* end of vGet8PapInfo */
/* * Build the list with List Information for Word 8/9/10/11 files */ void vGet8LstInfo(FILE *pFile, const pps_info_type *pPPS, const ULONG *aulBBD, size_t tBBDLen, const ULONG *aulSBD, size_t tSBDLen, const UCHAR *aucHeader) { list_block_type tList; const ULONG *aulBlockDepot; UCHAR *aucLfoInfo, *aucLstfInfo, *aucPapx, *aucXString; ULONG ulBeginLfoInfo, ulBeginLstfInfo, ulBeginLvlfInfo; ULONG ulListID, ulStart; size_t tBlockDepotLen, tBlockSize; size_t tLfoInfoLen, tLstfInfoLen, tPapxLen, tXstLen, tOff; size_t tLstfRecords, tStart, tIndex; int iNums; USHORT usIstd; UCHAR ucTmp, ucListLevel, ucMaxLevel, ucChpxLen; UCHAR aucLvlfInfo[28], aucXst[2]; fail(pFile == NULL || pPPS == NULL || aucHeader == NULL); fail(aulBBD == NULL || aulSBD == NULL); NO_DBG_DEC(pPPS->tTable.ulSB); NO_DBG_HEX(pPPS->tTable.ulSize); if (pPPS->tTable.ulSize == 0) { DBG_MSG("No list information"); return; } if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) { /* Use the Small Block Depot */ aulBlockDepot = aulSBD; tBlockDepotLen = tSBDLen; tBlockSize = SMALL_BLOCK_SIZE; } else { /* Use the Big Block Depot */ aulBlockDepot = aulBBD; tBlockDepotLen = tBBDLen; tBlockSize = BIG_BLOCK_SIZE; } /* LFO (List Format Override) */ ulBeginLfoInfo = ulGetLong(0x2ea, aucHeader); /* fcPlfLfo */ DBG_HEX(ulBeginLfoInfo); tLfoInfoLen = (size_t)ulGetLong(0x2ee, aucHeader); /* lcbPlfLfo */ DBG_DEC(tLfoInfoLen); if (tLfoInfoLen == 0) { DBG_MSG("No lists in this document"); return; } aucLfoInfo = xmalloc(tLfoInfoLen); if (!bReadBuffer(pFile, pPPS->tTable.ulSB, aulBlockDepot, tBlockDepotLen, tBlockSize, aucLfoInfo, ulBeginLfoInfo, tLfoInfoLen)) { aucLfoInfo = xfree(aucLfoInfo); return; } NO_DBG_PRINT_BLOCK(aucLfoInfo, tLfoInfoLen); vBuildLfoList(aucLfoInfo, tLfoInfoLen); aucLfoInfo = xfree(aucLfoInfo); /* LSTF (LiST data on File) */ ulBeginLstfInfo = ulGetLong(0x2e2, aucHeader); /* fcPlcfLst */ DBG_HEX(ulBeginLstfInfo); tLstfInfoLen = (size_t)ulGetLong(0x2e6, aucHeader); /* lcbPlcfLst */ DBG_DEC(tLstfInfoLen); if (tLstfInfoLen == 0) { DBG_MSG("No list data on file"); return; } aucLstfInfo = xmalloc(tLstfInfoLen); if (!bReadBuffer(pFile, pPPS->tTable.ulSB, aulBlockDepot, tBlockDepotLen, tBlockSize, aucLstfInfo, ulBeginLstfInfo, tLstfInfoLen)) { aucLstfInfo = xfree(aucLstfInfo); return; } NO_DBG_PRINT_BLOCK(aucLstfInfo, tLstfInfoLen); tLstfRecords = (size_t)usGetWord(0, aucLstfInfo); if (2 + tLstfRecords * 28 < tLstfInfoLen) { DBG_DEC(2 + tLstfRecords * 28); DBG_DEC(tLstfInfoLen); aucLstfInfo = xfree(aucLstfInfo); return; } /* LVLF (List leVeL on File) */ ulBeginLvlfInfo = ulBeginLstfInfo + tLstfInfoLen; DBG_HEX(ulBeginLvlfInfo); aucXString = NULL; ulStart = ulBeginLvlfInfo; for (tIndex = 0, tStart = 2; tIndex < tLstfRecords; tIndex++, tStart += 28) { ulListID = ulGetLong(tStart, aucLstfInfo); NO_DBG_HEX(ulListID); ucTmp = ucGetByte(tStart + 26, aucLstfInfo); ucMaxLevel = odd(ucTmp) ? 1 : 9; for (ucListLevel = 0; ucListLevel < ucMaxLevel; ucListLevel++) { fail(aucXString != NULL); usIstd = usGetWord( tStart + 8 + 2 * (size_t)ucListLevel, aucLstfInfo); DBG_DEC_C(usIstd != STI_NIL, usIstd); NO_DBG_HEX(ulStart); (void)memset(&tList, 0, sizeof(tList)); /* Read the lvlf (List leVeL on File) */ if (!bReadBuffer(pFile, pPPS->tTable.ulSB, aulBlockDepot, tBlockDepotLen, tBlockSize, aucLvlfInfo, ulStart, sizeof(aucLvlfInfo))) { aucLstfInfo = xfree(aucLstfInfo); return; } NO_DBG_PRINT_BLOCK(aucLvlfInfo, sizeof(aucLvlfInfo)); if (bAllZero(aucLvlfInfo, sizeof(aucLvlfInfo))) { tList.ulStartAt = 1; tList.ucNFC = 0x00; tList.bNoRestart = FALSE; } else { tList.ulStartAt = ulGetLong(0, aucLvlfInfo); tList.ucNFC = ucGetByte(4, aucLvlfInfo); ucTmp = ucGetByte(5, aucLvlfInfo); tList.bNoRestart = (ucTmp & BIT(3)) != 0; DBG_MSG_C((ucTmp & BIT(4)) != 0 && (ucTmp & BIT(6)) != 0, "Found one"); } ulStart += sizeof(aucLvlfInfo); tPapxLen = (size_t)ucGetByte(25, aucLvlfInfo); if (tPapxLen != 0) { aucPapx = xmalloc(tPapxLen); /* Read the Papx */ if (!bReadBuffer(pFile, pPPS->tTable.ulSB, aulBlockDepot, tBlockDepotLen, tBlockSize, aucPapx, ulStart, tPapxLen)) { aucPapx = xfree(aucPapx); aucLstfInfo = xfree(aucLstfInfo); return; } NO_DBG_PRINT_BLOCK(aucPapx, tPapxLen); tList.sLeftIndent = sGetLeftIndent(aucPapx, tPapxLen); aucPapx = xfree(aucPapx); } ulStart += tPapxLen; ucChpxLen = ucGetByte(24, aucLvlfInfo); ulStart += (ULONG)ucChpxLen; /* Read the length of the XString */ if (!bReadBuffer(pFile, pPPS->tTable.ulSB, aulBlockDepot, tBlockDepotLen, tBlockSize, aucXst, ulStart, sizeof(aucXst))) { aucLstfInfo = xfree(aucLstfInfo); return; } NO_DBG_PRINT_BLOCK(aucXst, sizeof(aucXst)); tXstLen = (size_t)usGetWord(0, aucXst); ulStart += sizeof(aucXst); if (tXstLen == 0) { tList.usListChar = DEFAULT_LISTCHAR; vAdd2ListInfoList(ulListID, usIstd, ucListLevel, &tList); continue; } tXstLen *= 2; /* Length in chars to length in bytes */ aucXString = xmalloc(tXstLen); /* Read the XString */ if (!bReadBuffer(pFile, pPPS->tTable.ulSB, aulBlockDepot, tBlockDepotLen, tBlockSize, aucXString, ulStart, tXstLen)) { aucXString = xfree(aucXString); aucLstfInfo = xfree(aucLstfInfo); return; } NO_DBG_PRINT_BLOCK(aucXString, tXstLen); tOff = 0; for (iNums = 6; iNums < 15; iNums++) { ucTmp = ucGetByte(iNums, aucLvlfInfo); if (ucTmp == 0) { break; } tOff = (size_t)ucTmp; } tOff *= 2; /* Offset in chars to offset in bytes */ NO_DBG_DEC(tOff); if (tList.ucNFC == LIST_SPECIAL || tList.ucNFC == LIST_SPECIAL2 || tList.ucNFC == LIST_BULLETS) { tList.usListChar = usGetWord(0, aucXString); } else if (tOff != 0 && tOff < tXstLen) { tList.usListChar = usGetWord(tOff, aucXString); } else { tList.usListChar = DEFAULT_LISTCHAR; } vAdd2ListInfoList(ulListID, usIstd, ucListLevel, &tList); ulStart += tXstLen; aucXString = xfree(aucXString); } } aucLstfInfo = xfree(aucLstfInfo); } /* end of vGet8LstInfo */
/* * Build the lists with Section Property Information for Word 8/9/10/11 files */ void vGet8SepInfo(FILE *pFile, const pps_info_type *pPPS, const ULONG *aulBBD, size_t tBBDLen, const ULONG *aulSBD, size_t tSBDLen, const UCHAR *aucHeader) { section_block_type tSection; ULONG *aulSectPage, *aulCharPos; UCHAR *aucBuffer, *aucFpage; ULONG ulBeginOfText, ulTextOffset, ulBeginSectInfo; size_t tSectInfoLen, tIndex, tOffset, tLen, tBytes; UCHAR aucTmp[2]; fail(pFile == NULL || pPPS == NULL || aucHeader == NULL); fail(aulBBD == NULL || aulSBD == NULL); ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */ NO_DBG_HEX(ulBeginOfText); ulBeginSectInfo = ulGetLong(0xca, aucHeader); /* fcPlcfsed */ NO_DBG_HEX(ulBeginSectInfo); tSectInfoLen = (size_t)ulGetLong(0xce, aucHeader); /* lcbPlcfsed */ NO_DBG_DEC(tSectInfoLen); if (tSectInfoLen < 4) { DBG_DEC(tSectInfoLen); return; } aucBuffer = aucFillInfoBuffer(pFile, &pPPS->tTable, aulBBD, tBBDLen, aulSBD, tSBDLen, ulBeginSectInfo, tSectInfoLen); if (aucBuffer == NULL) { return; } NO_DBG_PRINT_BLOCK(aucBuffer, tSectInfoLen); /* Read the Section Descriptors */ tLen = (tSectInfoLen - 4) / 16; /* Save the section offsets */ aulCharPos = xcalloc(tLen, sizeof(ULONG)); for (tIndex = 0, tOffset = 0; tIndex < tLen; tIndex++, tOffset += 4) { ulTextOffset = ulGetLong(tOffset, aucBuffer); NO_DBG_HEX(ulTextOffset); aulCharPos[tIndex] = ulBeginOfText + ulTextOffset; NO_DBG_HEX(aulCharPos[tIndex]); } /* Save the Sepx offsets */ aulSectPage = xcalloc(tLen, sizeof(ULONG)); for (tIndex = 0, tOffset = (tLen + 1) * 4; tIndex < tLen; tIndex++, tOffset += 12) { aulSectPage[tIndex] = ulGetLong(tOffset + 2, aucBuffer); NO_DBG_HEX(aulSectPage[tIndex]); /* fcSepx */ } aucBuffer = xfree(aucBuffer); /* Read the Section Properties */ for (tIndex = 0; tIndex < tLen; tIndex++) { if (aulSectPage[tIndex] == FC_INVALID) { vDefault2SectionInfoList(aulCharPos[tIndex]); continue; } /* Get the number of bytes to read */ if (!bReadBuffer(pFile, pPPS->tWordDocument.ulSB, aulBBD, tBBDLen, BIG_BLOCK_SIZE, aucTmp, aulSectPage[tIndex], 2)) { continue; } tBytes = 2 + (size_t)usGetWord(0, aucTmp); NO_DBG_DEC(tBytes); /* Read the bytes */ aucFpage = xmalloc(tBytes); if (!bReadBuffer(pFile, pPPS->tWordDocument.ulSB, aulBBD, tBBDLen, BIG_BLOCK_SIZE, aucFpage, aulSectPage[tIndex], tBytes)) { aucFpage = xfree(aucFpage); continue; } NO_DBG_PRINT_BLOCK(aucFpage, tBytes); /* Process the bytes */ vGetDefaultSection(&tSection); vGet8SectionInfo(aucFpage + 2, tBytes - 2, &tSection); vAdd2SectionInfoList(&tSection, aulCharPos[tIndex]); aucFpage = xfree(aucFpage); } aulCharPos = xfree(aulCharPos); aulSectPage = xfree(aulSectPage); } /* end of vGet8SepInfo */
/* * Build the lists with Character Information for Word 8/9/10/11 files */ void vGet8ChrInfo(FILE *pFile, const pps_info_type *pPPS, const ULONG *aulBBD, size_t tBBDLen, const ULONG *aulSBD, size_t tSBDLen, const UCHAR *aucHeader) { font_block_type tFont; picture_block_type tPicture; ULONG *aulCharPage; UCHAR *aucBuffer; ULONG ulFileOffset, ulCharPos, ulBeginCharInfo; size_t tCharInfoLen, tOffset, tLen; int iIndex, iIndex2, iRun, iFodo, iLen; USHORT usIstd; UCHAR aucFpage[BIG_BLOCK_SIZE]; fail(pFile == NULL || pPPS == NULL || aucHeader == NULL); fail(aulBBD == NULL || aulSBD == NULL); ulBeginCharInfo = ulGetLong(0xfa, aucHeader); /* fcPlcfbteChpx */ NO_DBG_HEX(ulBeginCharInfo); tCharInfoLen = (size_t)ulGetLong(0xfe, aucHeader); /* lcbPlcfbteChpx */ NO_DBG_DEC(tCharInfoLen); if (tCharInfoLen < 4) { DBG_DEC(tCharInfoLen); return; } aucBuffer = aucFillInfoBuffer(pFile, &pPPS->tTable, aulBBD, tBBDLen, aulSBD, tSBDLen, ulBeginCharInfo, tCharInfoLen); if (aucBuffer == NULL) { return; } NO_DBG_PRINT_BLOCK(aucBuffer, tCharInfoLen); tLen = (tCharInfoLen / 4 - 1) / 2; aulCharPage = xcalloc(tLen, sizeof(ULONG)); for (iIndex = 0, tOffset = (tLen + 1) * 4; iIndex < (int)tLen; iIndex++, tOffset += 4) { aulCharPage[iIndex] = ulGetLong(tOffset, aucBuffer); NO_DBG_DEC(aulCharPage[iIndex]); } DBG_HEX(ulGetLong(0, aucBuffer)); aucBuffer = xfree(aucBuffer); NO_DBG_PRINT_BLOCK(aucHeader, HEADER_SIZE); for (iIndex = 0; iIndex < (int)tLen; iIndex++) { fail(aulCharPage[iIndex] > ULONG_MAX / BIG_BLOCK_SIZE); if (!bReadBuffer(pFile, pPPS->tWordDocument.ulSB, aulBBD, tBBDLen, BIG_BLOCK_SIZE, aucFpage, aulCharPage[iIndex] * BIG_BLOCK_SIZE, BIG_BLOCK_SIZE)) { break; } NO_DBG_PRINT_BLOCK(aucFpage, BIG_BLOCK_SIZE); iRun = (int)ucGetByte(0x1ff, aucFpage); NO_DBG_DEC(iRun); for (iIndex2 = 0; iIndex2 < iRun; iIndex2++) { ulCharPos = ulGetLong(iIndex2 * 4, aucFpage); ulFileOffset = ulCharPos2FileOffset(ulCharPos); iFodo = 2 * (int)ucGetByte( (iRun + 1) * 4 + iIndex2, aucFpage); iLen = (int)ucGetByte(iFodo, aucFpage); usIstd = usGetIstd(ulFileOffset); vFillFontFromStylesheet(usIstd, &tFont); if (iFodo != 0) { vGet8FontInfo(iFodo, usIstd, aucFpage + 1, iLen - 1, &tFont); } tFont.ulFileOffset = ulFileOffset; vAdd2FontInfoList(&tFont); if (iFodo <= 0) { continue; } (void)memset(&tPicture, 0, sizeof(tPicture)); if (bGet8PicInfo(iFodo, aucFpage + 1, iLen - 1, &tPicture)) { tPicture.ulFileOffset = ulFileOffset; tPicture.ulFileOffsetPicture =ulDataPos2FileOffset(tPicture.ulPictureOffset); vAdd2PictInfoList(&tPicture); } } } aulCharPage = xfree(aulCharPage); } /* end of vGet8ChrInfo */
/* * Build the lists with Paragraph Information for Word 6/7 files */ void vGet6PapInfo(FILE *pFile, ULONG ulStartBlock, const ULONG *aulBBD, size_t tBBDLen, const UCHAR *aucHeader) { row_block_type tRow; style_block_type tStyle; USHORT *ausParfPage; UCHAR *aucBuffer; ULONG ulCharPos, ulCharPosFirst, ulCharPosLast; ULONG ulBeginParfInfo; size_t tParfInfoLen, tParfPageNum, tOffset, tSize, tLenOld, tLen; size_t tIndex, tIndex2, tRun; int iFodo, iLen; row_info_enum eRowInfo; USHORT usParfFirstPage, usCount, usIstd; UCHAR aucFpage[BIG_BLOCK_SIZE]; fail(pFile == NULL || aucHeader == NULL); fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN); fail(aulBBD == NULL); ulBeginParfInfo = ulGetLong(0xc0, aucHeader); /* fcPlcfbtePapx */ NO_DBG_HEX(ulBeginParfInfo); tParfInfoLen = (size_t)ulGetLong(0xc4, aucHeader); /* lcbPlcfbtePapx */ NO_DBG_DEC(tParfInfoLen); if (tParfInfoLen < 4) { DBG_DEC(tParfInfoLen); return; } aucBuffer = xmalloc(tParfInfoLen); if (!bReadBuffer(pFile, ulStartBlock, aulBBD, tBBDLen, BIG_BLOCK_SIZE, aucBuffer, ulBeginParfInfo, tParfInfoLen)) { aucBuffer = xfree(aucBuffer); return; } NO_DBG_PRINT_BLOCK(aucBuffer, tParfInfoLen); tLen = (tParfInfoLen - 4) / 6; ausParfPage = xcalloc(tLen, sizeof(USHORT)); for (tIndex = 0, tOffset = (tLen + 1) * 4; tIndex < tLen; tIndex++, tOffset += 2) { ausParfPage[tIndex] = usGetWord(tOffset, aucBuffer); NO_DBG_DEC(ausParfPage[tIndex]); } DBG_HEX(ulGetLong(0, aucBuffer)); aucBuffer = xfree(aucBuffer); tParfPageNum = (size_t)usGetWord(0x190, aucHeader); /* cpnBtePap */ DBG_DEC(tParfPageNum); if (tLen < tParfPageNum) { /* Replace ParfPage by a longer version */ tLenOld = tLen; usParfFirstPage = usGetWord(0x18c, aucHeader); /* pnPapFirst */ DBG_DEC(usParfFirstPage); tLen += tParfPageNum - 1; tSize = tLen * sizeof(USHORT); ausParfPage = xrealloc(ausParfPage, tSize); /* Add new values */ usCount = usParfFirstPage + 1; for (tIndex = tLenOld; tIndex < tLen; tIndex++) { ausParfPage[tIndex] = usCount; NO_DBG_DEC(ausParfPage[tIndex]); usCount++; } } (void)memset(&tRow, 0, sizeof(tRow)); ulCharPosFirst = CP_INVALID; for (tIndex = 0; tIndex < tLen; tIndex++) { if (!bReadBuffer(pFile, ulStartBlock, aulBBD, tBBDLen, BIG_BLOCK_SIZE, aucFpage, (ULONG)ausParfPage[tIndex] * BIG_BLOCK_SIZE, BIG_BLOCK_SIZE)) { break; } tRun = (size_t)ucGetByte(0x1ff, aucFpage); NO_DBG_DEC(tRun); for (tIndex2 = 0; tIndex2 < tRun; tIndex2++) { NO_DBG_HEX(ulGetLong(tIndex2 * 4, aucFpage)); iFodo = 2 * (int)ucGetByte( (tRun + 1) * 4 + tIndex2 * 7, aucFpage); if (iFodo <= 0) { continue; } iLen = 2 * (int)ucGetByte(iFodo, aucFpage); usIstd = (USHORT)ucGetByte(iFodo + 1, aucFpage); vFillStyleFromStylesheet(usIstd, &tStyle); vGet6StyleInfo(iFodo, aucFpage + 3, iLen - 3, &tStyle); ulCharPos = ulGetLong(tIndex2 * 4, aucFpage); NO_DBG_HEX(ulCharPos); tStyle.ulFileOffset = ulCharPos2FileOffsetX( ulCharPos, &tStyle.eListID); vAdd2StyleInfoList(&tStyle); eRowInfo = eGet6RowInfo(iFodo, aucFpage + 3, iLen - 3, &tRow); switch(eRowInfo) { case found_a_cell: if (ulCharPosFirst != CP_INVALID) { break; } ulCharPosFirst = ulGetLong( tIndex2 * 4, aucFpage); NO_DBG_HEX(ulCharPosFirst); tRow.ulCharPosStart = ulCharPosFirst; tRow.ulFileOffsetStart = ulCharPos2FileOffset(ulCharPosFirst); DBG_HEX_C(tRow.ulFileOffsetStart == FC_INVALID, ulCharPosFirst); break; case found_end_of_row: ulCharPosLast = ulGetLong( tIndex2 * 4, aucFpage); NO_DBG_HEX(ulCharPosLast); tRow.ulCharPosEnd = ulCharPosLast; tRow.ulFileOffsetEnd = ulCharPos2FileOffset(ulCharPosLast); DBG_HEX_C(tRow.ulFileOffsetEnd == FC_INVALID, ulCharPosLast); vAdd2RowInfoList(&tRow); (void)memset(&tRow, 0, sizeof(tRow)); ulCharPosFirst = CP_INVALID; break; case found_nothing: break; default: DBG_DEC(eRowInfo); break; } } } ausParfPage = xfree(ausParfPage); } /* end of vGet6PapInfo */
/* * Build the lists with Character Information for Word 6/7 files */ void vGet6ChrInfo(FILE *pFile, ULONG ulStartBlock, const ULONG *aulBBD, size_t tBBDLen, const UCHAR *aucHeader) { font_block_type tFont; picture_block_type tPicture; USHORT *ausCharPage; UCHAR *aucBuffer; ULONG ulFileOffset, ulCharPos, ulBeginCharInfo; size_t tCharInfoLen, tOffset, tSize, tLenOld, tLen, tCharPageNum; size_t tIndex, tIndex2, tRun; int iFodo, iLen; USHORT usCharFirstPage, usCount, usIstd; UCHAR aucFpage[BIG_BLOCK_SIZE]; fail(pFile == NULL || aucHeader == NULL); fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN); fail(aulBBD == NULL); ulBeginCharInfo = ulGetLong(0xb8, aucHeader); /* fcPlcfbteChpx */ NO_DBG_HEX(lBeginCharInfo); tCharInfoLen = (size_t)ulGetLong(0xbc, aucHeader); /* lcbPlcfbteChpx */ NO_DBG_DEC(tCharInfoLen); if (tCharInfoLen < 4) { DBG_DEC(tCharInfoLen); return; } aucBuffer = xmalloc(tCharInfoLen); if (!bReadBuffer(pFile, ulStartBlock, aulBBD, tBBDLen, BIG_BLOCK_SIZE, aucBuffer, ulBeginCharInfo, tCharInfoLen)) { aucBuffer = xfree(aucBuffer); return; } tLen = (tCharInfoLen - 4) / 6; ausCharPage = xcalloc(tLen, sizeof(USHORT)); for (tIndex = 0, tOffset = (tLen + 1) * 4; tIndex < tLen; tIndex++, tOffset += 2) { ausCharPage[tIndex] = usGetWord(tOffset, aucBuffer); NO_DBG_DEC(ausCharPage[tIndex]); } DBG_HEX(ulGetLong(0, aucBuffer)); aucBuffer = xfree(aucBuffer); tCharPageNum = (size_t)usGetWord(0x18e, aucHeader); /* cpnBteChp */ DBG_DEC(tCharPageNum); if (tLen < tCharPageNum) { /* Replace CharPage by a longer version */ tLenOld = tLen; usCharFirstPage = usGetWord(0x18a, aucHeader); /* pnChrFirst */ DBG_DEC(usCharFirstPage); tLen += tCharPageNum - 1; tSize = tLen * sizeof(USHORT); ausCharPage = xrealloc(ausCharPage, tSize); /* Add new values */ usCount = usCharFirstPage + 1; for (tIndex = tLenOld; tIndex < tLen; tIndex++) { ausCharPage[tIndex] = usCount; NO_DBG_DEC(ausCharPage[tIndex]); usCount++; } } for (tIndex = 0; tIndex < tLen; tIndex++) { if (!bReadBuffer(pFile, ulStartBlock, aulBBD, tBBDLen, BIG_BLOCK_SIZE, aucFpage, (ULONG)ausCharPage[tIndex] * BIG_BLOCK_SIZE, BIG_BLOCK_SIZE)) { break; } tRun = (size_t)ucGetByte(0x1ff, aucFpage); NO_DBG_DEC(tRun); for (tIndex2 = 0; tIndex2 < tRun; tIndex2++) { ulCharPos = ulGetLong(tIndex2 * 4, aucFpage); ulFileOffset = ulCharPos2FileOffset(ulCharPos); iFodo = 2 * (int)ucGetByte( (tRun + 1) * 4 + tIndex2, aucFpage); iLen = (int)ucGetByte(iFodo, aucFpage); /* usIstd = usGetIstd(ulFileOffset); vFillFontFromStylesheet(usIstd, &tFont); if (iFodo != 0) { vGet6FontInfo(iFodo, usIstd, aucFpage + 1, iLen - 1, &tFont); } tFont.ulFileOffset = ulFileOffset; vAdd2FontInfoList(&tFont); if (iFodo <= 0) { continue; } (void)memset(&tPicture, 0, sizeof(tPicture)); if (bGet6PicInfo(iFodo, aucFpage + 1, iLen - 1, &tPicture)) { tPicture.ulFileOffset = ulFileOffset; tPicture.ulFileOffsetPicture = ulDataPos2FileOffset( tPicture.ulPictureOffset); vAdd2PictInfoList(&tPicture); } */ } } ausCharPage = xfree(ausCharPage); } /* end of vGet6ChrInfo */