📄 wordole.c
字号:
const UCHAR *aucHeader, int iWordVersion){ ULONG ulBeginOfText; ULONG ulTextLen, ulFootnoteLen, ulEndnoteLen; ULONG ulHdrFtrLen, ulMacroLen, ulAnnotationLen; ULONG ulTextBoxLen, ulHdrTextBoxLen; UINT uiQuickSaves; BOOL bFarEastWord, bTemplate, bFastSaved, bEncrypted, bSuccess; USHORT usIdent, usDocStatus; fail(pFile == NULL || pPPS == NULL); fail(aulBBD == NULL); fail(aulSBD == NULL); DBG_MSG("bGetDocumentText"); /* Get the "magic number" from the header */ usIdent = usGetWord(0x00, aucHeader); DBG_HEX(usIdent); bFarEastWord = usIdent == 0x8098 || usIdent == 0x8099 || usIdent == 0xa697 || usIdent == 0xa699; /* Get the status flags from the header */ usDocStatus = usGetWord(0x0a, aucHeader); DBG_HEX(usDocStatus); bTemplate = (usDocStatus & BIT(0)) != 0; DBG_MSG_C(bTemplate, "This document is a Template"); bFastSaved = (usDocStatus & BIT(2)) != 0; uiQuickSaves = (UINT)(usDocStatus & 0x00f0) >> 4; DBG_MSG_C(bFastSaved, "This document is Fast Saved"); DBG_DEC_C(bFastSaved, uiQuickSaves); bEncrypted = (usDocStatus & BIT(8)) != 0; if (bEncrypted) { werr(0, "Encrypted documents are not supported"); return FALSE; } /* Get length information */ ulBeginOfText = ulGetLong(0x18, aucHeader); DBG_HEX(ulBeginOfText); switch (iWordVersion) { case 6: case 7: ulTextLen = ulGetLong(0x34, aucHeader); ulFootnoteLen = ulGetLong(0x38, aucHeader); ulHdrFtrLen = ulGetLong(0x3c, aucHeader); ulMacroLen = ulGetLong(0x40, aucHeader); ulAnnotationLen = ulGetLong(0x44, aucHeader); ulEndnoteLen = ulGetLong(0x48, aucHeader); ulTextBoxLen = ulGetLong(0x4c, aucHeader); ulHdrTextBoxLen = ulGetLong(0x50, aucHeader); break; case 8: ulTextLen = ulGetLong(0x4c, aucHeader); ulFootnoteLen = ulGetLong(0x50, aucHeader); ulHdrFtrLen = ulGetLong(0x54, aucHeader); ulMacroLen = ulGetLong(0x58, aucHeader); ulAnnotationLen = ulGetLong(0x5c, aucHeader); ulEndnoteLen = ulGetLong(0x60, aucHeader); ulTextBoxLen = ulGetLong(0x64, aucHeader); ulHdrTextBoxLen = ulGetLong(0x68, aucHeader); break; default: werr(0, "This version of Word is not supported"); return FALSE; } DBG_DEC(ulTextLen); DBG_DEC(ulFootnoteLen); DBG_DEC(ulHdrFtrLen); DBG_DEC(ulMacroLen); DBG_DEC(ulAnnotationLen); DBG_DEC(ulEndnoteLen); DBG_DEC(ulTextBoxLen); DBG_DEC(ulHdrTextBoxLen); /* Make a list of the text blocks */ switch (iWordVersion) { case 6: case 7: if (bFastSaved) { bSuccess = bGet6DocumentText(pFile, bFarEastWord, pPPS->tWordDocument.ulSB, aulBBD, tBBDLen, aucHeader); } else { bSuccess = bAddTextBlocks(ulBeginOfText, ulTextLen + ulFootnoteLen + ulHdrFtrLen + ulMacroLen + ulAnnotationLen + ulEndnoteLen + ulTextBoxLen + ulHdrTextBoxLen, bFarEastWord, IGNORE_PROPMOD, pPPS->tWordDocument.ulSB, aulBBD, tBBDLen); } break; case 8: bSuccess = bGet8DocumentText(pFile, pPPS, aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader); break; default: werr(0, "This version of Word is not supported"); bSuccess = FALSE; break; } if (bSuccess) { vSplitBlockList(pFile, ulTextLen, ulFootnoteLen, ulHdrFtrLen, ulMacroLen, ulAnnotationLen, ulEndnoteLen, ulTextBoxLen, ulHdrTextBoxLen, !bFastSaved && iWordVersion == 8); } else { vDestroyTextBlockList(); werr(0, "I can't find the text of this document"); } return bSuccess;} /* end of bGetDocumentText *//* * vGetDocumentData - make a list of the data blocks of a Word document */static voidvGetDocumentData(FILE *pFile, const pps_info_type *pPPS, const ULONG *aulBBD, size_t tBBDLen, const UCHAR *aucHeader, int iWordVersion){ options_type tOptions; ULONG ulBeginOfText; BOOL bFastSaved, bHasImages, bSuccess; USHORT usDocStatus; fail(pFile == NULL); fail(pPPS == NULL); fail(aulBBD == NULL); /* Get the options */ vGetOptions(&tOptions); /* Get the status flags from the header */ usDocStatus = usGetWord(0x0a, aucHeader); DBG_HEX(usDocStatus); bFastSaved = (usDocStatus & BIT(2)) != 0; bHasImages = (usDocStatus & BIT(3)) != 0; if (!bHasImages || tOptions.eConversionType == conversion_text || tOptions.eConversionType == conversion_fmt_text || tOptions.eConversionType == conversion_xml || tOptions.eImageLevel == level_no_images) { /* * No images in the document or text-only output or * no images wanted, so no data blocks will be needed */ vDestroyDataBlockList(); return; } /* Get length information */ ulBeginOfText = ulGetLong(0x18, aucHeader); DBG_HEX(ulBeginOfText); /* Make a list of the data blocks */ switch (iWordVersion) { case 6: case 7: /* * The data blocks are in the text stream. The text stream * is in "fast saved" format or "normal saved" format */ if (bFastSaved) { bSuccess = bGet6DocumentData(pFile, pPPS->tWordDocument.ulSB, aulBBD, tBBDLen, aucHeader); } else { bSuccess = bAddDataBlocks(ulBeginOfText, (ULONG)LONG_MAX, pPPS->tWordDocument.ulSB, aulBBD, tBBDLen); } break; case 8: /* * The data blocks are in the data stream. The data stream * is always in "normal saved" format */ bSuccess = bAddDataBlocks(0, (ULONG)LONG_MAX, pPPS->tData.ulSB, aulBBD, tBBDLen); break; default: werr(0, "This version of Word is not supported"); bSuccess = FALSE; break; } if (!bSuccess) { vDestroyDataBlockList(); werr(0, "I can't find the data of this document"); }} /* end of vGetDocumentData *//* * iInitDocumentOLE - initialize an OLE document * * Returns the version of Word that made the document or -1 */intiInitDocumentOLE(FILE *pFile, long lFilesize){ pps_info_type PPS_info; ULONG *aulBBD, *aulSBD; ULONG *aulRootList, *aulBbdList, *aulSbdList; ULONG ulBdbListStart, ulAdditionalBBDlist; ULONG ulRootStartblock, ulSbdStartblock, ulSBLstartblock; ULONG ulStart, ulTmp; long lMaxBlock; size_t tBBDLen, tSBDLen, tNumBbdBlocks, tRootListLen; int iWordVersion, iIndex, iToGo; BOOL bSuccess; USHORT usIdent, usDocStatus; UCHAR aucHeader[HEADER_SIZE]; fail(pFile == NULL); lMaxBlock = lFilesize / BIG_BLOCK_SIZE - 2; DBG_DEC(lMaxBlock); if (lMaxBlock < 1) { return -1; } tBBDLen = (size_t)(lMaxBlock + 1); tNumBbdBlocks = (size_t)ulReadLong(pFile, 0x2c); DBG_DEC(tNumBbdBlocks); ulRootStartblock = ulReadLong(pFile, 0x30); DBG_DEC(ulRootStartblock); ulSbdStartblock = ulReadLong(pFile, 0x3c); DBG_DEC(ulSbdStartblock); ulAdditionalBBDlist = ulReadLong(pFile, 0x44); DBG_HEX(ulAdditionalBBDlist); ulSBLstartblock = ulReadLong(pFile, (ulRootStartblock + 1) * BIG_BLOCK_SIZE + 0x74); DBG_DEC(ulSBLstartblock); tSBDLen = (size_t)(ulReadLong(pFile, (ulRootStartblock + 1) * BIG_BLOCK_SIZE + 0x78) / SMALL_BLOCK_SIZE); /* All to be xcalloc-ed pointers to NULL */ aulRootList = NULL; aulSbdList = NULL; aulBbdList = NULL; aulSBD = NULL; aulBBD = NULL;/* Big Block Depot */ aulBbdList = xcalloc(tNumBbdBlocks, sizeof(ULONG)); aulBBD = xcalloc(tBBDLen, sizeof(ULONG)); iToGo = (int)tNumBbdBlocks; vGetBbdList(pFile, min(iToGo, 109), aulBbdList, 0x4c); ulStart = 109; iToGo -= 109; while (ulAdditionalBBDlist != END_OF_CHAIN && iToGo > 0) { ulBdbListStart = (ulAdditionalBBDlist + 1) * BIG_BLOCK_SIZE; vGetBbdList(pFile, min(iToGo, 127), aulBbdList + ulStart, ulBdbListStart); ulAdditionalBBDlist = ulReadLong(pFile, ulBdbListStart + 4 * 127); DBG_DEC(ulAdditionalBBDlist); DBG_HEX(ulAdditionalBBDlist); ulStart += 127; iToGo -= 127; } if (!bGetBBD(pFile, aulBbdList, tNumBbdBlocks, aulBBD, tBBDLen)) { FREE_ALL(); return -1; } aulBbdList = xfree(aulBbdList);/* Small Block Depot */ aulSbdList = xcalloc(tBBDLen, sizeof(ULONG)); aulSBD = xcalloc(tSBDLen, sizeof(ULONG)); for (iIndex = 0, ulTmp = ulSbdStartblock; iIndex < (int)tBBDLen && ulTmp != END_OF_CHAIN; iIndex++, ulTmp = aulBBD[ulTmp]) { if (ulTmp >= (ULONG)tBBDLen) { DBG_DEC(ulTmp); DBG_DEC(tBBDLen); werr(1, "The Big Block Depot is damaged"); } aulSbdList[iIndex] = ulTmp; NO_DBG_HEX(aulSbdList[iIndex]); } if (!bGetSBD(pFile, aulSbdList, tBBDLen, aulSBD, tSBDLen)) { FREE_ALL(); return -1; } aulSbdList = xfree(aulSbdList);/* Root list */ for (tRootListLen = 0, ulTmp = ulRootStartblock; tRootListLen < tBBDLen && ulTmp != END_OF_CHAIN; tRootListLen++, ulTmp = aulBBD[ulTmp]) { if (ulTmp >= (ULONG)tBBDLen) { DBG_DEC(ulTmp); DBG_DEC(tBBDLen); werr(1, "The Big Block Depot is damaged"); } } if (tRootListLen == 0) { werr(0, "No Rootlist found"); FREE_ALL(); return -1; } aulRootList = xcalloc(tRootListLen, sizeof(ULONG)); for (iIndex = 0, ulTmp = ulRootStartblock; iIndex < (int)tBBDLen && ulTmp != END_OF_CHAIN; iIndex++, ulTmp = aulBBD[ulTmp]) { if (ulTmp >= (ULONG)tBBDLen) { DBG_DEC(ulTmp); DBG_DEC(tBBDLen); werr(1, "The Big Block Depot is damaged"); } aulRootList[iIndex] = ulTmp; NO_DBG_DEC(aulRootList[iIndex]); } fail(tRootListLen != (size_t)iIndex); bSuccess = bGetPPS(pFile, aulRootList, tRootListLen, &PPS_info); aulRootList = xfree(aulRootList); if (!bSuccess) { FREE_ALL(); return -1; }/* Small block list */ if (!bCreateSmallBlockList(ulSBLstartblock, aulBBD, tBBDLen)) { FREE_ALL(); return -1; } if (PPS_info.tWordDocument.ulSize < MIN_SIZE_FOR_BBD_USE) { DBG_DEC(PPS_info.tWordDocument.ulSize); FREE_ALL(); werr(0, "I'm afraid the text stream of this file " "is too small to handle."); return -1; } /* Read the headerblock */ if (!bReadBuffer(pFile, PPS_info.tWordDocument.ulSB, aulBBD, tBBDLen, BIG_BLOCK_SIZE, aucHeader, 0, HEADER_SIZE)) { FREE_ALL(); return -1; } usIdent = usGetWord(0x00, aucHeader); DBG_HEX(usIdent); fail(usIdent != 0x8098 && /* Word 7 for oriental languages */ usIdent != 0x8099 && /* Word 7 for oriental languages */ usIdent != 0xa5dc && /* Word 6 & 7 */ usIdent != 0xa5ec && /* Word 7 & 97 & 98 */ usIdent != 0xa697 && /* Word 7 for oriental languages */ usIdent != 0xa699); /* Word 7 for oriental languages */ iWordVersion = iGetVersionNumber(aucHeader); if (iWordVersion < 6) { FREE_ALL(); werr(0, "This file is from a version of Word before Word 6."); return -1; } /* Get the status flags from the header */ usDocStatus = usGetWord(0x0a, aucHeader); if (usDocStatus & BIT(9)) { PPS_info.tTable = PPS_info.t1Table; } else { PPS_info.tTable = PPS_info.t0Table; } /* Clean the entries that should not be used */ memset(&PPS_info.t0Table, 0, sizeof(PPS_info.t0Table)); memset(&PPS_info.t1Table, 0, sizeof(PPS_info.t1Table)); bSuccess = bGetDocumentText(pFile, &PPS_info, aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader, iWordVersion); if (bSuccess) { vGetDocumentData(pFile, &PPS_info, aulBBD, tBBDLen, aucHeader, iWordVersion); vGetPropertyInfo(pFile, &PPS_info, aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader, iWordVersion); vSetDefaultTabWidth(pFile, &PPS_info, aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader, iWordVersion); vGetNotesInfo(pFile, &PPS_info, aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader, iWordVersion); } FREE_ALL(); return bSuccess ? iWordVersion : -1;} /* end of iInitDocumentOLE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -