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

📄 summary.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * summary.c * Copyright (C) 2002-2005 A.J. van Os; Released under GNU GPL * * Description: * Read the summary information of a Word document */#include <time.h>#include <string.h>#include "antiword.h"#define P_HEADER_SZ		28#define P_SECTIONLIST_SZ	20#define P_LENGTH_SZ		 4#define P_SECTION_MAX_SZ	(2 * P_SECTIONLIST_SZ + P_LENGTH_SZ)#define P_SECTION_SZ(x)		((x) * P_SECTIONLIST_SZ + P_LENGTH_SZ)#define PID_TITLE		 2#define PID_SUBJECT		 3#define PID_AUTHOR		 4#define PID_CREATE_DTM		12#define PID_LASTSAVE_DTM	13#define PID_APPNAME		18#define PIDD_MANAGER		14#define PIDD_COMPANY		15#define VT_LPSTR		30#define VT_FILETIME		64#define TIME_OFFSET_HI		0x019db1de#define TIME_OFFSET_LO		0xd53e8000static char	*szTitle = NULL;static char	*szSubject = NULL;static char	*szAuthor = NULL;static time_t	tCreateDtm = (time_t)-1;static time_t	tLastSaveDtm= (time_t)-1;static char	*szAppName = NULL;static char	*szManager = NULL;static char	*szCompany = NULL;static USHORT	usLid = (USHORT)-1;/* * vDestroySummaryInfo - destroy the summary information */voidvDestroySummaryInfo(void){	TRACE_MSG("vDestroySummaryInfo");	szTitle = xfree(szTitle);	szSubject = xfree(szSubject);	szAuthor = xfree(szAuthor);	tCreateDtm = (time_t)-1;	tLastSaveDtm = (time_t)-1;	szAppName = xfree(szAppName);	szManager = xfree(szManager);	szCompany = xfree(szCompany);	usLid = (USHORT)-1;} /* end of vDestroySummaryInfo *//* * tConvertDosDate - convert DOS date format * * returns Unix time_t or -1 */static time_ttConvertDosDate(const char *szDosDate){	struct tm	tTime;	const char	*pcTmp;	time_t		tResult;	memset(&tTime, 0, sizeof(tTime));	pcTmp = szDosDate;	/* Get the month */	if (!isdigit(*pcTmp)) {		return (time_t)-1;	}	tTime.tm_mon = (int)(*pcTmp - '0');	pcTmp++;	if (isdigit(*pcTmp)) {		tTime.tm_mon *= 10;		tTime.tm_mon += (int)(*pcTmp - '0');		pcTmp++;	}	/* Get the first separater */	if (isalnum(*pcTmp)) {		return (time_t)-1;	}	pcTmp++;	/* Get the day */	if (!isdigit(*pcTmp)) {		return (time_t)-1;	}	tTime.tm_mday = (int)(*pcTmp - '0');	pcTmp++;	if (isdigit(*pcTmp)) {		tTime.tm_mday *= 10;		tTime.tm_mday += (int)(*pcTmp - '0');		pcTmp++;	}	/* Get the second separater */	if (isalnum(*pcTmp)) {		return (time_t)-1;	}	pcTmp++;	/* Get the year */	if (!isdigit(*pcTmp)) {		return (time_t)-1;	}	tTime.tm_year = (int)(*pcTmp - '0');	pcTmp++;	if (isdigit(*pcTmp)) {		tTime.tm_year *= 10;		tTime.tm_year += (int)(*pcTmp - '0');		pcTmp++;	}	/* Check the values */	if (tTime.tm_mon == 0 || tTime.tm_mday == 0 || tTime.tm_mday > 31) {		return (time_t)-1;	}	/* Correct the values */	tTime.tm_mon--;		/* From 01-12 to 00-11 */	if (tTime.tm_year < 80) {		tTime.tm_year += 100;	/* 00 means 2000 is 100 */	}	tTime.tm_isdst = -1;	tResult = mktime(&tTime);	NO_DBG_MSG(ctime(&tResult));	return tResult;} /* end of tConvertDosDate *//* * szLpstr - get a zero terminate string property */static char *szLpstr(ULONG ulOffset, const UCHAR *aucBuffer){	char	*szStart, *szResult, *szTmp;	size_t	tSize;	tSize = (size_t)ulGetLong(ulOffset + 4, aucBuffer);	NO_DBG_DEC(tSize);	if (tSize == 0) {		return NULL;	}	/* Remove white space from the start of the string */	szStart = (char *)aucBuffer + ulOffset + 8;	NO_DBG_MSG(szStart);	fail(strlen(szStart) >= tSize);	while (isspace(*szStart)) {		szStart++;	}	if (szStart[0] == '\0') {		return NULL;	}	szResult = xstrdup(szStart);	/* Remove white space from the end of the string */	szTmp = szResult + strlen(szResult) - 1;	while (isspace(*szTmp)) {		*szTmp = '\0';		szTmp--;	}	NO_DBG_MSG(szResult);	return szResult;} /* end of szLpstr *//* * tFiletime - get a filetime property */static time_ttFiletime(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 *//* * vAnalyseSummaryInfo - analyse the summary information */static voidvAnalyseSummaryInfo(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 *//* * vAnalyseDocumentSummaryInfo - analyse the document summary information */static voidvAnalyseDocumentSummaryInfo(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 *//* * 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 *//* * vSet0SummaryInfo - set summary information from a Word for DOS file */voidvSet0SummaryInfo(FILE *pFile, const UCHAR *aucHeader){	UCHAR	*aucBuffer;	ULONG	ulBeginSumdInfo, ulBeginNextBlock;	size_t	tLen;	USHORT	usCodepage, usOffset;	TRACE_MSG("vSet0SummaryInfo");	fail(pFile == NULL || aucHeader == NULL);	/* First check the header */	usCodepage = usGetWord(0x7e, aucHeader);	DBG_DEC(usCodepage);	switch (usCodepage) {	case 850: usLid = 0x0809; break; /* Latin1 -> British English */	case 862: usLid = 0x040d; break; /* Hebrew */	case 866: usLid = 0x0419; break; /* Russian */	case 0:	case 437:	default: usLid = 0x0409; break; /* ASCII -> American English */	}

⌨️ 快捷键说明

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