⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 prop8.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * prop8.c * Copyright (C) 1998-2005 A.J. van Os; Released under GNU GPL * * Description: * Read the property information from a MS Word 8, 9,10 or 11 file * * Word  8 is better known as Word 97 or as Word 98 for Mac * Word  9 is better known as Word 2000 or as Word 2001 for Mac * Word 10 is better known as Word 2002 or as Word XP * Word 11 is better known as Word 2003 */#include <stdlib.h>#include <string.h>#include "antiword.h"#define DEFAULT_LISTCHAR	0x002e	/* A full stop *//* * iGet8InfoLength - the length of the information for Word 8/9/10/11 files */static intiGet8InfoLength(int iByteNbr, const UCHAR *aucGrpprl){	int	iTmp, iDel, iAdd;	USHORT	usOpCode;	usOpCode = usGetWord(iByteNbr, aucGrpprl);	switch (usOpCode & 0xe000) {	case 0x0000: case 0x2000:		return 3;	case 0x4000: case 0x8000: case 0xa000:		return 4;	case 0xe000:		return 5;	case 0x6000:		return 6;	case 0xc000:		iTmp = (int)ucGetByte(iByteNbr + 2, aucGrpprl);		if (usOpCode == 0xc615 && iTmp == 255) {			iDel = (int)ucGetByte(iByteNbr + 3, aucGrpprl);			iAdd = (int)ucGetByte(					iByteNbr + 4 + iDel * 4, aucGrpprl);			iTmp = 2 + iDel * 4 + iAdd * 3;		}		return 3 + iTmp;	default:		DBG_HEX(usOpCode);		DBG_FIXME();		return 1;	}} /* end of iGet8InfoLength *//* * 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 8/9/10/11 files */voidvGet8DopInfo(FILE *pFile, const pps_type *pTable,	const ULONG *aulBBD, size_t tBBDLen,	const ULONG *aulSBD, size_t tSBDLen,	const UCHAR *aucHeader){	document_block_type	tDocument;	UCHAR	*aucBuffer;	ULONG	ulBeginDocpInfo, ulTmp;	size_t	tDocpInfoLen;	USHORT	usTmp;	fail(pFile == NULL || pTable == NULL || aucHeader == NULL);	fail(aulBBD == NULL || aulSBD == NULL);	ulBeginDocpInfo = ulGetLong(0x192, aucHeader); /* fcDop */	NO_DBG_HEX(ulBeginSectInfo);	tDocpInfoLen = (size_t)ulGetLong(0x196, aucHeader); /* lcbDop */	NO_DBG_DEC(tSectInfoLen);	if (tDocpInfoLen < 28) {		DBG_MSG("No Document information");		return;	}	aucBuffer = aucFillInfoBuffer(pFile, pTable,			aulBBD, tBBDLen, aulSBD, tSBDLen,			ulBeginDocpInfo, tDocpInfoLen);	if (aucBuffer == NULL) {		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 vGet8DopInfo *//* * Fill the section information block with information * from a Word 8/9/10/11 file. */static voidvGet8SectionInfo(const UCHAR *aucGrpprl, size_t tBytes,		section_block_type *pSection){	UINT	uiIndex;	int	iFodoOff, iInfoLen, iSize, iTmp;	USHORT	usCcol;	UCHAR	ucTmp;	fail(aucGrpprl == NULL || pSection == NULL);	iFodoOff = 0;	while (tBytes >= (size_t)iFodoOff + 2) {		iInfoLen = 0;		switch (usGetWord(iFodoOff, aucGrpprl)) {		case 0x3009:	/* bkc */			ucTmp = ucGetByte(iFodoOff + 2, aucGrpprl);			DBG_DEC(ucTmp);			pSection->bNewPage = ucTmp != 0 && ucTmp != 1;			break;		case 0x3014:	/* grpfIhdt */			pSection->ucHdrFtrSpecification =					ucGetByte(iFodoOff + 2, aucGrpprl);			break;		case 0x500b:	/* ccolM1 */			usCcol = 1 + usGetWord(iFodoOff + 2, aucGrpprl);			DBG_DEC(usCcol);			break;		case 0xd202:	/* olstAnm */			iSize = (int)ucGetByte(iFodoOff + 2, aucGrpprl);			DBG_DEC_C(iSize != 212, iSize);			for (uiIndex = 0, iTmp = iFodoOff + 3;			     uiIndex < 9 && iTmp < iFodoOff + 3 + iSize - 15;			     uiIndex++, iTmp += 16) {				pSection->aucNFC[uiIndex] =						ucGetByte(iTmp, aucGrpprl);				DBG_DEC(pSection->aucNFC[uiIndex]);				ucTmp = ucGetByte(iTmp + 3, aucGrpprl);				DBG_HEX(ucTmp);				if ((ucTmp & BIT(2)) != 0) {					pSection->usNeedPrevLvl |=							(USHORT)BIT(uiIndex);				}				if ((ucTmp & BIT(3)) != 0) {					pSection->usHangingIndent |=							(USHORT)BIT(uiIndex);				}			}			DBG_HEX(pSection->usNeedPrevLvl);			DBG_HEX(pSection->usHangingIndent);			break;		default:			break;		}		if (iInfoLen <= 0) {			iInfoLen = iGet8InfoLength(iFodoOff, aucGrpprl);			fail(iInfoLen <= 0);		}		iFodoOff += iInfoLen;	}} /* end of vGet8SectionInfo *//* * Build the lists with Section Property Information for Word 8/9/10/11 files */voidvGet8SepInfo(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 list with Header/Footer Information for Word 8/9/10/11 files */voidvGet8HdrFtrInfo(FILE *pFile, const pps_type *pTable,	const ULONG *aulBBD, size_t tBBDLen,	const ULONG *aulSBD, size_t tSBDLen,	const UCHAR *aucHeader){	ULONG	*aulCharPos;	UCHAR	*aucBuffer;	ULONG	ulHdrFtrOffset, ulBeginHdrFtrInfo;	size_t	tHdrFtrInfoLen, tIndex, tOffset, tLen;	fail(pFile == NULL || pTable == NULL || aucHeader == NULL);	fail(aulBBD == NULL || aulSBD == NULL);	ulBeginHdrFtrInfo = ulGetLong(0xf2, aucHeader); /* fcPlcfhdd */	NO_DBG_HEX(ulBeginHdrFtrInfo);	tHdrFtrInfoLen = (size_t)ulGetLong(0xf6, aucHeader); /* lcbPlcfhdd */	NO_DBG_DEC(tHdrFtrInfoLen);	if (tHdrFtrInfoLen < 8) {		DBG_DEC_C(tHdrFtrInfoLen != 0, tHdrFtrInfoLen);		return;	}	aucBuffer = aucFillInfoBuffer(pFile, pTable,			aulBBD, tBBDLen, aulSBD, tSBDLen,			ulBeginHdrFtrInfo, tHdrFtrInfoLen);	if (aucBuffer == NULL) {		return;	}	NO_DBG_PRINT_BLOCK(aucBuffer, tHdrFtrInfoLen);	tLen = tHdrFtrInfoLen / 4 - 1;	DBG_DEC_C(tLen % 12 != 1 && tLen % 12 != 7, tLen);	/* 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]);	}	vCreat8HdrFtrInfoList(aulCharPos, tLen);	/* Clean up and leave */	aulCharPos = xfree(aulCharPos);	aucBuffer = xfree(aucBuffer);} /* end of vGet8HdrFtrInfo *//* * Translate the rowinfo to a member of the row_info enumeration */row_info_enumeGet8RowInfo(int iFodo,	const UCHAR *aucGrpprl, int iBytes, row_block_type *pRow){	int	iFodoOff, iInfoLen;	int	iIndex, iSize, iCol;	int	iPosCurr, iPosPrev;	USHORT	usTmp;	BOOL	bFound2416_0, bFound2416_1, bFound2417_0, bFound2417_1;	BOOL	bFound244b_0, bFound244b_1, bFound244c_0, bFound244c_1;	BOOL	bFoundd608;	fail(iFodo < 0 || aucGrpprl == NULL || pRow == NULL);	iFodoOff = 0;	bFound2416_0 = FALSE;	bFound2416_1 = FALSE;	bFound2417_0 = FALSE;	bFound2417_1 = FALSE;	bFound244b_0 = FALSE;	bFound244b_1 = FALSE;	bFound244c_0 = FALSE;	bFound244c_1 = FALSE;	bFoundd608 = FALSE;	while (iBytes >= iFodoOff + 2) {		iInfoLen = 0;		switch (usGetWord(iFodo + iFodoOff, aucGrpprl)) {		case 0x2416:	/* fInTable */			if (odd(ucGetByte(iFodo + iFodoOff + 2, aucGrpprl))) {				bFound2416_1 = TRUE;			} else {				bFound2416_0 = TRUE;			}			break;		case 0x2417:	/* fTtp */			if (odd(ucGetByte(iFodo + iFodoOff + 2, aucGrpprl))) {				bFound2417_1 = TRUE;			} else {				bFound2417_0 = TRUE;			}			break;		case 0x244b:	/* sub-table fInTable */			if (odd(ucGetByte(iFodo + iFodoOff + 2, aucGrpprl))) {				bFound244b_1 = TRUE;			} else {				bFound244b_0 = TRUE;			}			break;		case 0x244c:	/* sub-table fTtp */			if (odd(ucGetByte(iFodo + iFodoOff + 2, aucGrpprl))) {				bFound244c_1 = TRUE;			} else {				bFound244c_0 = TRUE;			}			break;		case 0x6424:	/* brcTop */			usTmp = usGetWord(iFodo + iFodoOff + 2, aucGrpprl);			usTmp &= 0xff00;			NO_DBG_DEC(usTmp >> 8);			if (usTmp == 0) {				pRow->ucBorderInfo &= ~TABLE_BORDER_TOP;			} else {				pRow->ucBorderInfo |= TABLE_BORDER_TOP;			}			break;		case 0x6425:	/* brcLeft */			usTmp = usGetWord(iFodo + iFodoOff + 2, aucGrpprl);			usTmp &= 0xff00;			NO_DBG_DEC(usTmp >> 8);			if (usTmp == 0) {				pRow->ucBorderInfo &= ~TABLE_BORDER_LEFT;			} else {				pRow->ucBorderInfo |= TABLE_BORDER_LEFT;			}			break;		case 0x6426:	/* brcBottom */			usTmp = usGetWord(iFodo + iFodoOff + 2, aucGrpprl);			usTmp &= 0xff00;			NO_DBG_DEC(usTmp >> 8);			if (usTmp == 0) {				pRow->ucBorderInfo &= ~TABLE_BORDER_BOTTOM;			} else {				pRow->ucBorderInfo |= TABLE_BORDER_BOTTOM;			}			break;		case 0x6427:	/* brcRight */			usTmp = usGetWord(iFodo + iFodoOff + 2, aucGrpprl);			usTmp &= 0xff00;			NO_DBG_DEC(usTmp >> 8);			if (usTmp == 0) {				pRow->ucBorderInfo &= ~TABLE_BORDER_RIGHT;			} else {				pRow->ucBorderInfo |= TABLE_BORDER_RIGHT;			}			break;		case 0xd606:	/* cDefTable10 */			DBG_MSG("0xd606: sprmTDefTable10");			iSize = (int)usGetWord(iFodo + iFodoOff + 2, aucGrpprl);			DBG_DEC(iSize);			break;		case 0xd608:	/* cDefTable */			iSize = (int)usGetWord(iFodo + iFodoOff + 2, aucGrpprl);			if (iSize < 6 || iBytes < iFodoOff + 8) {				DBG_DEC(iSize);				DBG_DEC(iFodoOff);				iInfoLen = 2;				break;			}			iCol = (int)ucGetByte(iFodo + iFodoOff + 4, aucGrpprl);			if (iCol < 1 ||			    iBytes < iFodoOff + 4 + (iCol + 1) * 2) {				DBG_DEC(iCol);				DBG_DEC(iFodoOff);				iInfoLen = 2;				break;			}			if (iCol >= (int)elementsof(pRow->asColumnWidth)) {				DBG_DEC(iCol);				werr(1, "The number of columns is corrupt");			}			pRow->ucNumberOfColumns = (UCHAR)iCol;			iPosPrev = (int)(short)usGetWord(					iFodo + iFodoOff + 5,					aucGrpprl);			for (iIndex = 0; iIndex < iCol; iIndex++) {				iPosCurr = (int)(short)usGetWord(					iFodo + iFodoOff + 7 + iIndex * 2,					aucGrpprl);				pRow->asColumnWidth[iIndex] =						(short)(iPosCurr - iPosPrev);				iPosPrev = iPosCurr;			}			bFoundd608 = TRUE;			break;		default:			break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -