Beispiel #1
0
/*
 * pGetSectionInfo - get the section information
 */
const section_block_type *
pGetSectionInfo(const section_block_type *pOld, ULONG ulCharPos)
{
	const section_mem_type	*pCurr;

	if (pOld == NULL || ulCharPos == 0) {
		if (pAnchor == NULL) {
			/* There are no records, make one */
			vDefault2SectionInfoList(0);
			fail(pAnchor == NULL);
		}
		/* The first record */
		NO_DBG_MSG("First record");
		return &pAnchor->tInfo;
	}

	NO_DBG_HEX(ulCharPos);
	for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) {
		NO_DBG_HEX(pCurr->ulCharPos);
		if (ulCharPos == pCurr->ulCharPos ||
		    ulCharPos + 1 == pCurr->ulCharPos) {
			NO_DBG_HEX(pCurr->ulCharPos);
			return &pCurr->tInfo;
		}
	}
	return pOld;
} /* end of pGetSectionInfo */
Beispiel #2
0
/*
 * tFiletime - get a filetime property
 */
static time_t
tFiletime(ULONG ulOffset, const UCHAR *aucBuffer)
{
	double	dHi, dLo, dTmp;
	ULONG	ulHi, ulLo;
	time_t	tResult;

	ulLo = ulGetLong(ulOffset + 4, aucBuffer);
	ulHi = ulGetLong(ulOffset + 8, aucBuffer);
	NO_DBG_HEX(ulHi);
	NO_DBG_HEX(ulLo);

	/* Move the starting point from 01 Jan 1601 to 01 Jan 1970 */
	dHi = (double)ulHi - (double)TIME_OFFSET_HI;
	dLo = (double)ulLo - (double)TIME_OFFSET_LO;
	NO_DBG_FLT(dHi);
	NO_DBG_FLT(dLo);

	/* Combine the values and divide by 10^7 to get seconds */
	dTmp  = dLo / 10000000.0;	/* 10^7 */
	dTmp += dHi * 429.4967926;	/* 2^32 / 10^7 */
	NO_DBG_FLT(dTmp);

	/* Make a time_t */
	if (dTmp - 0.5 < TIME_T_MIN || dTmp + 0.5 > TIME_T_MAX) {
		return (time_t)-1;
	}
	tResult = dTmp < 0.0 ? (time_t)(dTmp - 0.5) : (time_t)(dTmp + 0.5);
	NO_DBG_MSG(ctime(&tResult));
	return tResult;
} /* end of tFiletime */
Beispiel #3
0
/*
 * 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 */
Beispiel #4
0
/*
 * bAdd2TextBlockList - add an element to the text block list
 *
 * returns: TRUE when successful, otherwise FALSE
 */
BOOL
bAdd2TextBlockList(const text_block_type *pTextBlock)
{
	list_mem_type	*pListMember;

	fail(pTextBlock == NULL);
	fail(pTextBlock->ulFileOffset == FC_INVALID);
	fail(pTextBlock->ulCharPos == CP_INVALID);
	fail(pTextBlock->ulLength == 0);
	fail(pTextBlock->bUsesUnicode && odd(pTextBlock->ulLength));

	NO_DBG_MSG("bAdd2TextBlockList");
	NO_DBG_HEX(pTextBlock->ulFileOffset);
	NO_DBG_HEX(pTextBlock->ulCharPos);
	NO_DBG_HEX(pTextBlock->ulLength);
	NO_DBG_DEC(pTextBlock->bUsesUnicode);
	NO_DBG_DEC(pTextBlock->usPropMod);

	if (pTextBlock->ulFileOffset == FC_INVALID ||
	    pTextBlock->ulCharPos == CP_INVALID ||
	    pTextBlock->ulLength == 0 ||
	    (pTextBlock->bUsesUnicode && odd(pTextBlock->ulLength))) {
		werr(0, "Software (textblock) error");
		return FALSE;
	}
	/*
	 * Check for continuous blocks of the same character size and
	 * the same properties modifier
	 */
	if (pBlockLast != NULL &&
	    pBlockLast->tInfo.ulFileOffset +
	     pBlockLast->tInfo.ulLength == pTextBlock->ulFileOffset &&
	    pBlockLast->tInfo.ulCharPos +
	     pBlockLast->tInfo.ulLength == pTextBlock->ulCharPos &&
	    pBlockLast->tInfo.bUsesUnicode == pTextBlock->bUsesUnicode &&
	    pBlockLast->tInfo.usPropMod == pTextBlock->usPropMod) {
		/* These are continous blocks */
		pBlockLast->tInfo.ulLength += pTextBlock->ulLength;
		return TRUE;
	}
	/* Make a new block */
	pListMember = xmalloc(sizeof(list_mem_type));
	/* Add the block to the list */
	pListMember->tInfo = *pTextBlock;
	pListMember->pNext = NULL;
	if (pTextAnchor == NULL) {
		pTextAnchor = pListMember;
	} else {
		fail(pBlockLast == NULL);
		pBlockLast->pNext = pListMember;
	}
	pBlockLast = pListMember;
	return TRUE;
} /* end of bAdd2TextBlockList */
Beispiel #5
0
/*
 * Build the list with footnote information for WinWord 1/2 files
 */
static void
vGet2FootnotesInfo(FILE *pFile, const UCHAR *aucHeader)
{
	UCHAR	*aucBuffer;
	ULONG	ulFileOffset, ulBeginOfText, ulOffset, ulBeginFootnoteInfo;
	size_t	tFootnoteInfoLen;
	size_t	tIndex;

	TRACE_MSG("vGet2FootnotesInfo");

	fail(pFile == NULL || aucHeader == NULL);

	ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */
	NO_DBG_HEX(ulBeginOfText);
	ulBeginFootnoteInfo = ulGetLong(0x64, aucHeader); /* fcPlcffndRef */
	NO_DBG_HEX(ulBeginFootnoteInfo);
	tFootnoteInfoLen = (size_t)usGetWord(0x68, aucHeader); /* cbPlcffndRef */
	NO_DBG_DEC(tFootnoteInfoLen);

	if (tFootnoteInfoLen < 10) {
		DBG_MSG("No Footnotes in this document");
		return;
	}

	aucBuffer = xmalloc(tFootnoteInfoLen);
	if (!bReadBytes(aucBuffer,
			tFootnoteInfoLen, ulBeginFootnoteInfo, pFile)) {
		aucBuffer = xfree(aucBuffer);
		return;
	}
	NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteInfoLen);

	fail(tFootnoteListLength != 0);
	tFootnoteListLength = (tFootnoteInfoLen - 4) / 6;
	fail(tFootnoteListLength == 0);

	fail(aulFootnoteList != NULL);
	aulFootnoteList = xcalloc(tFootnoteListLength, sizeof(ULONG));

	for (tIndex = 0; tIndex < tFootnoteListLength; tIndex++) {
		ulOffset = ulGetLong(tIndex * 4, aucBuffer);
		NO_DBG_HEX(ulOffset);
		ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset);
		NO_DBG_HEX(ulFileOffset);
		aulFootnoteList[tIndex] = ulFileOffset;
	}
	aucBuffer = xfree(aucBuffer);
} /* end of vGet2FootnotesInfo */
Beispiel #6
0
/*
 * Build the list with Header/Footer Information for Word 8/9/10/11 files
 */
void
vGet8HdrFtrInfo(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 */
Beispiel #7
0
/*
 * vBuildLfoList - build the LFO list (pllfo)
 */
void
vBuildLfoList(const UCHAR *aucBuffer, size_t tBufLen)
{
	size_t	tRecords;
	int	iIndex;

	fail(aucBuffer == NULL);

	if (tBufLen < 4) {
		return;
	}
	tRecords = (size_t)ulGetLong(0, aucBuffer);
	NO_DBG_DEC(tRecords);
	if (4 + 16 * tRecords > tBufLen || tRecords >= 0x7fff) {
		/* Just a sanity check */
		DBG_DEC(tRecords);
		DBG_DEC(4 + 16 * tRecords);
		DBG_DEC(tBufLen);
		return;
	}
	aulLfoList = xcalloc(tRecords, sizeof(ULONG));
	for (iIndex = 0; iIndex < (int)tRecords; iIndex++) {
		aulLfoList[iIndex] = ulGetLong(4 + 16 * iIndex, aucBuffer);
		NO_DBG_HEX(aulLfoList[iIndex]);
	}
	usLfoLen = (USHORT)tRecords;
} /* end of vBuildLfoList */
Beispiel #8
0
/*
 * vAnalyseDocumentSummaryInfo - analyse the document summary information
 */
static void
vAnalyseDocumentSummaryInfo(const UCHAR *aucBuffer)
{
	ULONG	ulOffset;
	size_t	tIndex, tCount, tPropID, tPropType;

	tCount = (size_t)ulGetLong(4, aucBuffer);
	DBG_DEC(tCount);
	for (tIndex = 0; tIndex < tCount; tIndex++) {
		tPropID = (size_t)ulGetLong(8 + tIndex * 8, aucBuffer);
		ulOffset = ulGetLong(12 + tIndex * 8, aucBuffer);
		NO_DBG_DEC(tPropID);
		NO_DBG_HEX(ulOffset);
		tPropType = (size_t)ulGetLong(ulOffset, aucBuffer);
		NO_DBG_DEC(tPropType);
		switch (tPropID) {
		case PIDD_MANAGER:
			if (tPropType == VT_LPSTR && szManager == NULL) {
				szManager = szLpstr(ulOffset, aucBuffer);
			}
			break;
		case PIDD_COMPANY:
			if (tPropType == VT_LPSTR && szCompany == NULL) {
				szCompany = szLpstr(ulOffset, aucBuffer);
			}
			break;
		default:
			break;
		}
	}
} /* end of vAnalyseDocumentSummaryInfo */
Beispiel #9
0
/*
 * vUpdateWriteable - update a writeable icon with a string
 */
void
vUpdateWriteable(window_handle tWindow, icon_handle tIconNumber,
	const char *szString)
{
	icon_block	tIcon;
	caret_block	tCaret;
	int		iLen;

	fail(szString == NULL);

	NO_DBG_DEC(tIconNumber);
	NO_DBG_MSG(szString);

	Error_CheckFatal(Wimp_GetIconState(tWindow, tIconNumber, &tIcon));
	NO_DBG_HEX(tIcon.flags);
	if (!tIcon.flags.data.text || !tIcon.flags.data.indirected) {
		werr(1, "Icon %d must be indirected text", (int)tIconNumber);
		return;
	}
	strncpy(tIcon.data.indirecttext.buffer,
		szString,
		tIcon.data.indirecttext.bufflen - 1);
	/* Ensure the caret is behind the last character of the text */
	Error_CheckFatal(Wimp_GetCaretPosition(&tCaret));
	if (tCaret.window == tWindow && tCaret.icon == tIconNumber) {
		iLen = strlen(tIcon.data.indirecttext.buffer);
		if (tCaret.index != iLen) {
			tCaret.index = iLen;
			Error_CheckFatal(Wimp_SetCaretPosition(&tCaret));
		}
	}
	Error_CheckFatal(Wimp_SetIconState(tWindow, tIconNumber, 0, 0));
	vUpdateIcon(tWindow, &tIcon);
} /* end of vUpdateWriteable */
Beispiel #10
0
/*
 * vAdd2RowInfoList - Add an element to the Row Information List
 */
void
vAdd2RowInfoList(const row_block_type *pRowBlock)
{
	row_desc_type	*pListMember;
	short		*psTmp;
	int		iIndex;

	fail(pRowBlock == NULL);

	if (pRowBlock->ulFileOffsetStart == FC_INVALID ||
	    pRowBlock->ulFileOffsetEnd == FC_INVALID ||
	    pRowBlock->ulFileOffsetStart == pRowBlock->ulFileOffsetEnd) {
		DBG_HEX_C(pRowBlock->ulFileOffsetStart != FC_INVALID,
			pRowBlock->ulFileOffsetStart);
		DBG_HEX_C(pRowBlock->ulFileOffsetEnd != FC_INVALID,
			pRowBlock->ulFileOffsetEnd);
		return;
	}

	NO_DBG_HEX(pRowBlock->ulFileOffsetStart);
	NO_DBG_HEX(pRowBlock->ulFileOffsetEnd);
	NO_DBG_DEC(pRowBlock->ucNumberOfColumns);

	/* Create the new list member */
	pListMember = xmalloc(sizeof(row_desc_type));
	/* Fill the new list member */
	pListMember->tInfo = *pRowBlock;
	pListMember->pNext = NULL;
	/* Correct the values where needed */
	for (iIndex = 0, psTmp = pListMember->tInfo.asColumnWidth;
	     iIndex < (int)pListMember->tInfo.ucNumberOfColumns;
	     iIndex++, psTmp++) {
		if (*psTmp < 0) {
			*psTmp = 0;
			DBG_MSG("The column width was negative");
		}
	}
	/* Add the new member to the list */
	if (pAnchor == NULL) {
		pAnchor = pListMember;
		pRowCurrent = pListMember;
	} else {
		fail(pRowLast == NULL);
		pRowLast->pNext = pListMember;
	}
	pRowLast = pListMember;
} /* end of vAdd2RowInfoList */
Beispiel #11
0
/*
 * 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 */
Beispiel #12
0
/*
 * bAdd2DataBlockList - add an element to the data block list
 *
 * Returns TRUE when successful, otherwise FALSE
 */
BOOL
bAdd2DataBlockList(const data_block_type *pDataBlock)
{
	data_mem_type	*pListMember;

	fail(pDataBlock == NULL);
	fail(pDataBlock->ulFileOffset == FC_INVALID);
	fail(pDataBlock->ulDataPos == CP_INVALID);
	fail(pDataBlock->ulLength == 0);

	NO_DBG_MSG("bAdd2DataBlockList");
	NO_DBG_HEX(pDataBlock->ulFileOffset);
	NO_DBG_HEX(pDataBlock->ulDataPos);
	NO_DBG_HEX(pDataBlock->ulLength);

	if (pDataBlock->ulFileOffset == FC_INVALID ||
	    pDataBlock->ulDataPos == CP_INVALID ||
	    pDataBlock->ulLength == 0) {
		werr(0, "Software (datablock) error");
		return FALSE;
	}
	/* Check for continuous blocks */
	if (pBlockLast != NULL &&
	    pBlockLast->tInfo.ulFileOffset +
	     pBlockLast->tInfo.ulLength == pDataBlock->ulFileOffset &&
	    pBlockLast->tInfo.ulDataPos +
	     pBlockLast->tInfo.ulLength == pDataBlock->ulDataPos) {
		/* These are continous blocks */
		pBlockLast->tInfo.ulLength += pDataBlock->ulLength;
		return TRUE;
	}
	/* Make a new block */
	pListMember = xmalloc(sizeof(data_mem_type));
	/* Add the block to the data list */
	pListMember->tInfo = *pDataBlock;
	pListMember->pNext = NULL;
	if (pAnchor == NULL) {
		pAnchor = pListMember;
	} else {
		fail(pBlockLast == NULL);
		pBlockLast->pNext = pListMember;
	}
	pBlockLast = pListMember;
	return TRUE;
} /* end of bAdd2DataBlockList */
Beispiel #13
0
/*
 * tOpenFont - make the specified font the current font
 *
 * Returns the font reference number for use in a draw file
 */
drawfile_fontref
tOpenFont(UCHAR ucWordFontNumber, USHORT usFontStyle, USHORT usWordFontSize)
{
    os_error	*e;
    const char	*szOurFontname;
    font_handle	tFont;
    int	iFontnumber;

    NO_DBG_MSG("tOpenFont");
    NO_DBG_DEC(ucWordFontNumber);
    NO_DBG_HEX(usFontStyle);
    NO_DBG_DEC(usWordFontSize);

    /* Keep the relevant bits */
    usFontStyle &= FONT_BOLD|FONT_ITALIC;
    NO_DBG_HEX(usFontStyle);

    iFontnumber = iGetFontByNumber(ucWordFontNumber, usFontStyle);
    szOurFontname = szGetOurFontname(iFontnumber);
    if (szOurFontname == NULL || szOurFontname[0] == '\0') {
        tFontCurr = (font_handle)-1;
        return (byte)0;
    }
    NO_DBG_MSG(szOurFontname);
    e = Font_FindFont(&tFont, (char *)szOurFontname,
                      (int)usWordFontSize * 8, (int)usWordFontSize * 8,
                      0, 0);
    if (e != NULL) {
        switch (e->errnum) {
        case 523:
            werr(0, "%s", e->errmess);
            break;
        default:
            werr(0, "Open font error %d: %s",
                 e->errnum, e->errmess);
            break;
        }
        tFontCurr = (font_handle)-1;
        return (drawfile_fontref)0;
    }
    tFontCurr = tFont;
    NO_DBG_DEC(tFontCurr);
    return (drawfile_fontref)(iFontnumber + 1);
} /* end of tOpenFont */
Beispiel #14
0
/*
 * tOpenFont - make the specified font the current font
 *
 * Returns the font reference number
 */
drawfile_fontref
tOpenFont(UCHAR ucWordFontNumber, USHORT usFontStyle, USHORT usWordFontSize)
{
	options_type	tOptions;
	const char	*szOurFontname;
	size_t	tIndex;
	int	iFontnumber;

	NO_DBG_MSG("tOpenFont");
	NO_DBG_DEC(ucWordFontNumber);
	NO_DBG_HEX(usFontStyle);
	NO_DBG_DEC(usWordFontSize);

	/* Keep the relevant bits */
	usFontStyle &= FONT_BOLD|FONT_ITALIC;
	NO_DBG_HEX(usFontStyle);

	vGetOptions(&tOptions);
	eEncoding = tOptions.eEncoding;
	bUsePlainText = tOptions.eConversionType != conversion_draw &&
			tOptions.eConversionType != conversion_ps &&
			tOptions.eConversionType != conversion_pdf;

	if (bUsePlainText) {
		/* Plain text, no fonts */
		return (drawfile_fontref)0;
	}

	iFontnumber = iGetFontByNumber(ucWordFontNumber, usFontStyle);
	szOurFontname = szGetOurFontname(iFontnumber);
	if (szOurFontname == NULL || szOurFontname[0] == '\0') {
		DBG_DEC(iFontnumber);
		return (drawfile_fontref)0;
	}
	NO_DBG_MSG(szOurFontname);

	for (tIndex = 0; tIndex < elementsof(szFontnames); tIndex++) {
		if (STREQ(szFontnames[tIndex], szOurFontname)) {
			NO_DBG_DEC(tIndex);
			return (drawfile_fontref)tIndex;
		}
	}
	return (drawfile_fontref)0;
} /* end of tOpenFont */
Beispiel #15
0
/*
 * vAdd2PictInfoList - Add an element to the Picture Information List
 */
void
vAdd2PictInfoList(const picture_block_type *pPictureBlock)
{
	picture_mem_type	*pListMember;

	fail(pPictureBlock == NULL);

	NO_DBG_MSG("bAdd2PictInfoList");

	if (pPictureBlock->ulFileOffset == FC_INVALID) {
		/*
		 * This offset is really past the end of the file,
		 * so don't waste any memory by storing it.
		 */
		return;
	}
	if (pPictureBlock->ulFileOffsetPicture == FC_INVALID) {
		/*
		 * The place where this picture is supposed to be stored
		 * doesn't exist.
		 */
		return;
	}

	NO_DBG_HEX(pPictureBlock->ulFileOffset);
	NO_DBG_HEX(pPictureBlock->ulFileOffsetPicture);
	NO_DBG_HEX(pPictureBlock->ulPictureOffset);

	/* Create list member */
	pListMember = xmalloc(sizeof(picture_mem_type));
	/* Fill the list member */
	pListMember->tInfo = *pPictureBlock;
	pListMember->pNext = NULL;
	/* Add the new member to the list */
	if (pAnchor == NULL) {
		pAnchor = pListMember;
	} else {
		fail(pPictureLast == NULL);
		pPictureLast->pNext = pListMember;
	}
	pPictureLast = pListMember;

} /* end of vAdd2PictInfoList */
Beispiel #16
0
/*
 * vAdd2FontInfoList - Add an element to the Font Information List
 */
void
vAdd2FontInfoList(const font_block_type *pFontBlock)
{
	font_mem_type	*pListMember;

	fail(pFontBlock == NULL);

	NO_DBG_MSG("bAdd2FontInfoList");

	if (pFontBlock->ulFileOffset == FC_INVALID) {
		/*
		 * This offset is really past the end of the file,
		 * so don't waste any memory by storing it.
		 */
		return;
	}

	NO_DBG_HEX(pFontBlock->ulFileOffset);
	NO_DBG_DEC_C(pFontBlock->ucFontNumber != 0,
					pFontBlock->ucFontNumber);
	NO_DBG_DEC_C(pFontBlock->usFontSize != DEFAULT_FONT_SIZE,
					pFontBlock->usFontSize);
	NO_DBG_DEC_C(pFontBlock->ucFontColor != 0,
					pFontBlock->ucFontColor);
	NO_DBG_HEX_C(pFontBlock->usFontStyle != 0x00,
					pFontBlock->usFontStyle);

	if (pFontLast != NULL &&
	    pFontLast->tInfo.ulFileOffset == pFontBlock->ulFileOffset) {
		/*
		 * If two consecutive fonts share the same
		 * offset, remember only the last font
		 */
		fail(pFontLast->pNext != NULL);
		pFontLast->tInfo = *pFontBlock;
		return;
	}

	/* Create list member */
	pListMember = xmalloc(sizeof(font_mem_type));
	/* Fill the list member */
	pListMember->tInfo = *pFontBlock;
	pListMember->pNext = NULL;
	/* Correct the values where needed */
	vCorrectFontValues(&pListMember->tInfo);
	/* Add the new member to the list */
	if (pAnchor == NULL) {
		pAnchor = pListMember;
	} else {
		fail(pFontLast == NULL);
		pFontLast->pNext = pListMember;
	}
	pFontLast = pListMember;
} /* end of vAdd2FontInfoList */
Beispiel #17
0
/*
 * Build the list with Header/Footer Information for WinWord 1/2 files
 */
void
vGet2HdrFtrInfo(FILE *pFile, const UCHAR *aucHeader)
{
	ULONG	*aulCharPos;
	UCHAR	*aucBuffer;
	ULONG	ulHdrFtrOffset, ulBeginHdrFtrInfo;
	size_t	tHdrFtrInfoLen, tIndex, tOffset, tLen;

	fail(pFile == NULL || aucHeader == NULL);

	ulBeginHdrFtrInfo = ulGetLong(0x9a, aucHeader); /* fcPlcfhdd */
	NO_DBG_HEX(ulBeginHdrFtrInfo);
	tHdrFtrInfoLen = (size_t)usGetWord(0x9e, aucHeader); /* cbPlcfhdd */
	NO_DBG_DEC(tHdrFtrInfoLen);
	if (tHdrFtrInfoLen < 8) {
		DBG_DEC_C(tHdrFtrInfoLen != 0, tHdrFtrInfoLen);
		return;
	}

	aucBuffer = xmalloc(tHdrFtrInfoLen);
	if (!bReadBytes(aucBuffer, tHdrFtrInfoLen, ulBeginHdrFtrInfo, pFile)) {
		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]);
	}
	vCreat2HdrFtrInfoList(aulCharPos, tLen);
	aulCharPos = xfree(aulCharPos);
	aucBuffer = xfree(aucBuffer);
} /* end of vGet2HdrFtrInfo */
Beispiel #18
0
/*
 * vAnalyseSummaryInfo - analyse the summary information
 */
static void
vAnalyseSummaryInfo(const UCHAR *aucBuffer)
{
	ULONG	ulOffset;
	size_t	tIndex, tCount, tPropID, tPropType;

	tCount = (size_t)ulGetLong(4, aucBuffer);
	DBG_DEC(tCount);
	for (tIndex = 0; tIndex < tCount; tIndex++) {
		tPropID = (size_t)ulGetLong(8 + tIndex * 8, aucBuffer);
		ulOffset = ulGetLong(12 + tIndex * 8, aucBuffer);
		NO_DBG_DEC(tPropID);
		NO_DBG_HEX(ulOffset);
		tPropType = (size_t)ulGetLong(ulOffset, aucBuffer);
		NO_DBG_DEC(tPropType);
		switch (tPropID) {
		case PID_TITLE:
			if (tPropType == VT_LPSTR && szTitle == NULL) {
				szTitle = szLpstr(ulOffset, aucBuffer);
			}
			break;
		case PID_SUBJECT:
			if (tPropType == VT_LPSTR && szSubject == NULL) {
				szSubject = szLpstr(ulOffset, aucBuffer);
			}
			break;
		case PID_AUTHOR:
			if (tPropType == VT_LPSTR && szAuthor == NULL) {
				szAuthor = szLpstr(ulOffset, aucBuffer);
			}
			break;
		case PID_CREATE_DTM:
			if (tPropType == VT_FILETIME &&
			    tCreateDtm == (time_t)-1) {
				tCreateDtm = tFiletime(ulOffset, aucBuffer);
			}
			break;
		case PID_LASTSAVE_DTM:
			if (tPropType == VT_FILETIME &&
			    tLastSaveDtm == (time_t)-1) {
				tLastSaveDtm = tFiletime(ulOffset, aucBuffer);
			}
			break;
		case PID_APPNAME:
			if (tPropType == VT_LPSTR && szAppName == NULL) {
				szAppName = szLpstr(ulOffset, aucBuffer);
			}
			break;
		default:
			break;
		}
	}
} /* end of vAnalyseSummaryInfo */
Beispiel #19
0
/*
 * vAdd2ListInfoList - add an element to the List Information list
 */
void
vAdd2ListInfoList(ULONG ulListID, USHORT usIstd, UCHAR ucListLevel,
	const list_block_type *pListBlock)
{
	list_desc_type	*pListMember;

	fail(pListBlock == NULL);

	NO_DBG_HEX(ulListID);
	NO_DBG_DEC(usIstd);
	NO_DBG_DEC(ucListLevel);
	NO_DBG_DEC(pListBlock->ulStartAt);
	NO_DBG_DEC(pListBlock->bNoRestart);
	NO_DBG_DEC(pListBlock->sLeftIndent);
	NO_DBG_HEX(pListBlock->ucNFC);
	NO_DBG_HEX(pListBlock->usListChar);

	/* Create list member */
	pListMember = xmalloc(sizeof(list_desc_type));
	/* Fill the list member */
	pListMember->tInfo = *pListBlock;
	pListMember->ulListID = ulListID;
	pListMember->usIstd = usIstd;
	pListMember->ucListLevel = ucListLevel;
	pListMember->pNext = NULL;
	/* Correct the values where needed */
	if (pListMember->tInfo.ulStartAt > 0xffff) {
		DBG_DEC(pListMember->tInfo.ulStartAt);
		pListMember->tInfo.ulStartAt = 1;
	}
	/* Add the new member to the list */
	if (pAnchor == NULL) {
		pAnchor = pListMember;
	} else {
		fail(pBlockLast == NULL);
		pBlockLast->pNext = pListMember;
	}
	pBlockLast = pListMember;
} /* end of vAdd2ListInfoList */
Beispiel #20
0
/*
 * usGetIstd - get the istd that belongs to the given file offset
 */
USHORT
usGetIstd(ULONG ulFileOffset)
{
	const style_mem_type	*pCurr, *pBest, *pStart;
	ULONG	ulSeq, ulBest;

	ulSeq = ulGetSeqNumber(ulFileOffset);
	if (ulSeq == FC_INVALID) {
		return ISTD_NORMAL;
	}
	NO_DBG_HEX(ulFileOffset);
	NO_DBG_DEC(ulSeq);

	if (bInSequence &&
	    pMidPtr != NULL &&
	    ulSeq > pMidPtr->ulSequenceNumber) {
		/* The istd is in the second half of the chained list */
		pStart = pMidPtr;
	} else {
		pStart = pAnchor;
	}

	pBest = NULL;
	ulBest = 0;
	for (pCurr = pStart; pCurr != NULL; pCurr = pCurr->pNext) {
		if (pCurr->ulSequenceNumber != FC_INVALID &&
		    (pBest == NULL || pCurr->ulSequenceNumber > ulBest) &&
		    pCurr->ulSequenceNumber <= ulSeq) {
			pBest = pCurr;
			ulBest = pCurr->ulSequenceNumber;
		}
		if (bInSequence && pCurr->ulSequenceNumber > ulSeq) {
			break;
		}
	}
	NO_DBG_DEC(ulBest);

	if (pBest == NULL) {
		return ISTD_NORMAL;
	}

	NO_DBG_DEC(pBest->tInfo.usIstd);
	return pBest->tInfo.usIstd;
} /* end of usGetIstd */
Beispiel #21
0
/*
 * Build the lists with Document Property Information for Word 8/9/10/11 files
 */
void
vGet8DopInfo(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 */
Beispiel #22
0
/*
 * 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 */
Beispiel #23
0
/*
 * Get a matching record from the List Information List
 *
 * Returns NULL if no matching records is found
 */
const list_block_type *
pGetListInfo(USHORT usListIndex, UCHAR ucListLevel)
{
	list_desc_type	*pCurr;
	list_block_type	*pNearMatch;
	ULONG	ulListID;

	if (usListIndex == 0) {
		return NULL;
	}
	if (usListIndex - 1 >= usLfoLen || ucListLevel > 8) {
		DBG_DEC(usListIndex);
		DBG_DEC(ucListLevel);
		return NULL;
	}
	fail(aulLfoList == NULL);
	ulListID = aulLfoList[usListIndex - 1];
	NO_DBG_HEX(ulListID);

	pNearMatch = NULL;
	for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) {
		if (pCurr->ulListID != ulListID) {
			/* No match */
			continue;
		}
		if (pCurr->ucListLevel == ucListLevel) {
			/* Exact match */
			return &pCurr->tInfo;
		}
		if (pCurr->ucListLevel == 0) {
			/* Near match */
			pNearMatch = &pCurr->tInfo;
		}
	}
	/* No exact match, use a near match if any */
	return pNearMatch;
} /* end of pGetListInfo */
Beispiel #24
0
/*
 * 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 */
Beispiel #25
0
/*
 * pSplitList - split the specified list in a printable part and a leftover part
 *
 * returns the pointer to the leftover part
 */
output_type *
pSplitList(output_type *pAnchor)
{
	output_type	*pCurr, *pLeftOver;
	int		iIndex;

 	fail(pAnchor == NULL);

	for (pCurr = pAnchor; pCurr->pNext != NULL; pCurr = pCurr->pNext)
		;	/* EMPTY */
	iIndex = -1;
	for (; pCurr != NULL; pCurr = pCurr->pPrev) {
		iIndex = iFindSplit(pCurr->szStorage, pCurr->tNextFree);
		if (iIndex >= 0) {
			break;
		}
	}

	if (pCurr == NULL || iIndex < 0) {
		/* No split, no leftover */
		return NULL;
	}
	/* Split over the iIndex-th character */
	NO_DBG_MSG("pLeftOver");
	pLeftOver = xmalloc(sizeof(*pLeftOver));
	fail(pCurr->tNextFree < (size_t)iIndex);
	pLeftOver->tStorageSize = pCurr->tNextFree - (size_t)iIndex;
	pLeftOver->szStorage = xmalloc(pLeftOver->tStorageSize);
	pLeftOver->tNextFree = pCurr->tNextFree - (size_t)iIndex - 1;
	(void)strncpy(pLeftOver->szStorage,
		pCurr->szStorage + iIndex + 1, pLeftOver->tNextFree);
	pLeftOver->szStorage[pLeftOver->tNextFree] = '\0';
	NO_DBG_MSG(pLeftOver->szStorage);
	pLeftOver->ucFontColor = pCurr->ucFontColor;
	pLeftOver->usFontStyle = pCurr->usFontStyle;
	pLeftOver->tFontRef = pCurr->tFontRef;
	pLeftOver->usFontSize = pCurr->usFontSize;
	pLeftOver->lStringWidth = lComputeStringWidth(
					pLeftOver->szStorage,
					pLeftOver->tNextFree,
					pLeftOver->tFontRef,
					pLeftOver->usFontSize);
	pLeftOver->pPrev = NULL;
	pLeftOver->pNext = pCurr->pNext;
	if (pLeftOver->pNext != NULL) {
		pLeftOver->pNext->pPrev = pLeftOver;
	}
	fail(!bCheckDoubleLinkedList(pLeftOver));

	NO_DBG_MSG("pAnchor");
	NO_DBG_HEX(pCurr->szStorage[iIndex]);
	while (iIndex >= 0 && isspace((int)(UCHAR)pCurr->szStorage[iIndex])) {
		iIndex--;
	}
	pCurr->tNextFree = (size_t)iIndex + 1;
	pCurr->szStorage[pCurr->tNextFree] = '\0';
	NO_DBG_MSG(pCurr->szStorage);
	pCurr->lStringWidth = lComputeStringWidth(
					pCurr->szStorage,
					pCurr->tNextFree,
					pCurr->tFontRef,
					pCurr->usFontSize);
	pCurr->pNext = NULL;
	fail(!bCheckDoubleLinkedList(pAnchor));

	return pLeftOver;
} /* end of pSplitList */
Beispiel #26
0
/*
 * 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 */
Beispiel #27
0
/*
 * Build the list with footnote information for Word for DOS files
 */
static void
vGet0FootnotesInfoAndText(FILE *pFile, const UCHAR *aucHeader)
{
	footnote_local_type	*pCurr;
	UCHAR	*aucBuffer;
	ULONG	ulFileOffset, ulBeginOfText, ulOffset, ulBeginFootnoteInfo;
	ULONG	ulCharPos, ulBeginNextBlock;
	size_t	tFootnotes, tFootnoteInfoLen;
	size_t	tIndex;
	UCHAR   aucTmp[2];

	TRACE_MSG("vGet0FootnotesInfoAndText");

	fail(pFile == NULL || aucHeader == NULL);

	ulBeginOfText = 128;
	NO_DBG_HEX(ulBeginOfText);
	ulBeginFootnoteInfo =  128 * (ULONG)usGetWord(0x14, aucHeader);
	DBG_HEX(ulBeginFootnoteInfo);
	ulBeginNextBlock = 128 * (ULONG)usGetWord(0x16, aucHeader);
	DBG_HEX(ulBeginNextBlock);

	if (ulBeginFootnoteInfo == ulBeginNextBlock) {
		DBG_MSG("No Footnotes in this document");
		return;
	}

	/* Read the the number of footnotes + 1 */
	if (!bReadBytes(aucTmp, 2, ulBeginFootnoteInfo, pFile)) {
		return;
	}
	tFootnotes = (size_t)usGetWord(0, aucTmp);
	if (tFootnotes < 2) {
		DBG_MSG("No Footnotes in this document (2)");
	}
	DBG_DEC(tFootnotes);
	tFootnoteInfoLen =  8 * tFootnotes;

	aucBuffer = xmalloc(tFootnoteInfoLen);
	if (!bReadBytes(aucBuffer,
			tFootnoteInfoLen, ulBeginFootnoteInfo + 4, pFile)) {
		aucBuffer = xfree(aucBuffer);
		return;
	}
	DBG_PRINT_BLOCK(aucBuffer, tFootnoteInfoLen);

	/* Get footnote information */
	fail(tFootnoteListLength != 0);
	tFootnoteListLength = tFootnotes - 1;
	fail(tFootnoteListLength == 0);

	fail(aulFootnoteList != NULL);
	aulFootnoteList = xcalloc(tFootnoteListLength, sizeof(ULONG));

	for (tIndex = 0; tIndex < tFootnoteListLength; tIndex++) {
		ulOffset = ulGetLong(tIndex * 8, aucBuffer);
		DBG_HEX(ulOffset);
		ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset);
		DBG_HEX(ulFileOffset);
		aulFootnoteList[tIndex] = ulFileOffset;
	}

	/* Get footnote text */
	fail(tFootnoteTextLength != 0);
	tFootnoteTextLength = tFootnotes - 1;
	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 * 8 + 4, aucBuffer);
		DBG_HEX(ulOffset);
		ulCharPos = ulBeginOfText + ulOffset;
		DBG_HEX(ulCharPos);
		DBG_HEX(ulCharPos2FileOffset(ulCharPos));
		pCurr->ulCharPosStart = ulCharPos;
		ulOffset = ulGetLong((tIndex + 1) * 8 + 4, aucBuffer);
		DBG_HEX(ulOffset);
		ulCharPos = ulBeginOfText + ulOffset;
		DBG_HEX(ulCharPos);
		DBG_HEX(ulCharPos2FileOffset(ulCharPos));
		pCurr->ulCharPosNext = ulCharPos;
		pCurr->bUseful = pCurr->ulCharPosStart != pCurr->ulCharPosNext;
	}
	aucBuffer = xfree(aucBuffer);
} /* end of vGet0FootnotesInfoAndText */
Beispiel #28
0
/*
 * 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 */
Beispiel #29
0
/*
 * Build the lists with Paragraph Information for WinWord 1/2 files
 */
void
vGet2PapInfo(FILE *pFile, 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;
	int	iIndex, iIndex2, iRun, iFodo, iLen;
	row_info_enum	eRowInfo;
	USHORT	usParfFirstPage, usCount, usIstd;
	UCHAR	ucStc;
	UCHAR	aucFpage[BIG_BLOCK_SIZE];

	fail(pFile == NULL || aucHeader == NULL);

	ulBeginParfInfo = ulGetLong(0xa6, aucHeader); /* fcPlcfbtePapx */
	NO_DBG_HEX(ulBeginParfInfo);
	tParfInfoLen = (size_t)usGetWord(0xaa, aucHeader); /* cbPlcfbtePapx */
	NO_DBG_DEC(tParfInfoLen);
	if (tParfInfoLen < 4) {
		DBG_DEC(tParfInfoLen);
		return;
	}

	aucBuffer = xmalloc(tParfInfoLen);
	if (!bReadBytes(aucBuffer, tParfInfoLen, ulBeginParfInfo, pFile)) {
		aucBuffer = xfree(aucBuffer);
		return;
	}
	NO_DBG_PRINT_BLOCK(aucBuffer, tParfInfoLen);

	tLen = (tParfInfoLen - 4) / 6;
	ausParfPage = xcalloc(tLen, sizeof(USHORT));
	for (iIndex = 0, tOffset = (tLen + 1) * 4;
	     iIndex < (int)tLen;
	     iIndex++, tOffset += 2) {
		ausParfPage[iIndex] = usGetWord(tOffset, aucBuffer);
		NO_DBG_DEC(ausParfPage[iIndex]);
	}
	DBG_HEX(ulGetLong(0, aucBuffer));
	aucBuffer = xfree(aucBuffer);
	tParfPageNum = (size_t)usGetWord(0x144, aucHeader); /* cpnBtePap */
	DBG_DEC(tParfPageNum);
	if (tLen < tParfPageNum) {
		/* Replace ParfPage by a longer version */
		tLenOld = tLen;
		usParfFirstPage = usGetWord(0x140, aucHeader); /* pnPapFirst */
		DBG_DEC(usParfFirstPage);
		tLen += tParfPageNum - 1;
		tSize = tLen * sizeof(USHORT);
		ausParfPage = xrealloc(ausParfPage, tSize);
		/* Add new values */
		usCount = usParfFirstPage + 1;
		for (iIndex = (int)tLenOld; iIndex < (int)tLen; iIndex++) {
			ausParfPage[iIndex] = usCount;
			NO_DBG_DEC(ausParfPage[iIndex]);
			usCount++;
		}
	}

	(void)memset(&tRow, 0, sizeof(tRow));
	ulCharPosFirst = CP_INVALID;
	for (iIndex = 0; iIndex < (int)tLen; iIndex++) {
		if (!bReadBytes(aucFpage, BIG_BLOCK_SIZE,
				(ULONG)ausParfPage[iIndex] * BIG_BLOCK_SIZE,
				pFile)) {
			break;
		}
		NO_DBG_PRINT_BLOCK(aucFpage, BIG_BLOCK_SIZE);
		iRun = (int)ucGetByte(0x1ff, aucFpage);
		NO_DBG_DEC(iRun);
		for (iIndex2 = 0; iIndex2 < iRun; iIndex2++) {
			if ((iRun + 1) * 4 + iIndex2 * 1 >= BIG_BLOCK_SIZE) {
				break;
			}
			NO_DBG_HEX(ulGetLong(iIndex2 * 4, aucFpage));
			iFodo = 2 * (int)ucGetByte(
				(iRun + 1) * 4 + iIndex2 * 1, aucFpage);
			if (iFodo <= 0) {
				continue;
			}

			iLen = 2 * (int)ucGetByte(iFodo, aucFpage);

			ucStc = ucGetByte(iFodo + 1, aucFpage);
			usIstd = usStc2istd(ucStc);

			vFillStyleFromStylesheet(usIstd, &tStyle);
			vGet2StyleInfo(iFodo, aucFpage + 8, iLen - 8, &tStyle);
			ulCharPos = ulGetLong(iIndex2 * 4, aucFpage);
			NO_DBG_HEX(ulCharPos);
			tStyle.ulFileOffset = ulCharPos;
			vAdd2StyleInfoList(&tStyle);

			eRowInfo = eGet2RowInfo(iFodo,
					aucFpage + 8, iLen - 8, &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 = ulCharPosFirst;
				break;
			case found_end_of_row:
				ulCharPosLast = ulGetLong(
						iIndex2 * 4, aucFpage);
				NO_DBG_HEX(ulCharPosLast);
				tRow.ulCharPosEnd = ulCharPosLast;
				/* Add 1 for compatiblity with Word 6 and up */
				tRow.ulFileOffsetEnd = ulCharPosLast + 1;
				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 vGet2PapInfo */
Beispiel #30
0
/*
 * 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 */