xref: /plan9/sys/src/cmd/aux/antiword/worddos.c (revision 25b329d522281a8cdd35da0dcc08c3fc621059a9)
1f5736e95SDavid du Colombier /*
2f5736e95SDavid du Colombier  * worddos.c
3*25b329d5SDavid du Colombier  * Copyright (C) 2002-2005 A.J. van Os; Released under GNU GPL
4f5736e95SDavid du Colombier  *
5f5736e95SDavid du Colombier  * Description:
6f5736e95SDavid du Colombier  * Deal with the DOS internals of a MS Word file
7f5736e95SDavid du Colombier  */
8f5736e95SDavid du Colombier 
9f5736e95SDavid du Colombier #include "antiword.h"
10f5736e95SDavid du Colombier 
11f5736e95SDavid du Colombier 
12f5736e95SDavid du Colombier /*
13f5736e95SDavid du Colombier  * bGetDocumentText - make a list of the text blocks of a Word document
14f5736e95SDavid du Colombier  *
15f5736e95SDavid du Colombier  * Return TRUE when succesful, otherwise FALSE
16f5736e95SDavid du Colombier  */
17f5736e95SDavid du Colombier static BOOL
bGetDocumentText(FILE * pFile,long lFilesize,const UCHAR * aucHeader)18f5736e95SDavid du Colombier bGetDocumentText(FILE *pFile, long lFilesize, const UCHAR *aucHeader)
19f5736e95SDavid du Colombier {
20f5736e95SDavid du Colombier 	text_block_type	tTextBlock;
21f5736e95SDavid du Colombier 	ULONG	ulTextLen;
22f5736e95SDavid du Colombier 	BOOL	bFastSaved;
23f5736e95SDavid du Colombier 	UCHAR	ucDocStatus, ucVersion;
24f5736e95SDavid du Colombier 
25f5736e95SDavid du Colombier 	fail(pFile == NULL);
26f5736e95SDavid du Colombier 	fail(lFilesize < 128);
27f5736e95SDavid du Colombier 	fail(aucHeader == NULL);
28f5736e95SDavid du Colombier 
29f5736e95SDavid du Colombier 	/* Get the status flags from the header */
30f5736e95SDavid du Colombier 	ucDocStatus = ucGetByte(0x75, aucHeader);
31f5736e95SDavid du Colombier 	DBG_HEX(ucDocStatus);
32f5736e95SDavid du Colombier 	bFastSaved = (ucDocStatus & BIT(1)) != 0;
33f5736e95SDavid du Colombier 	DBG_MSG_C(bFastSaved, "This document is Fast Saved");
34f5736e95SDavid du Colombier 	ucVersion = ucGetByte(0x74, aucHeader);
35f5736e95SDavid du Colombier 	DBG_DEC(ucVersion);
36f5736e95SDavid du Colombier 	DBG_MSG_C(ucVersion == 0, "Written by Word 4.0 or earlier");
37f5736e95SDavid du Colombier 	DBG_MSG_C(ucVersion == 3, "Word 5.0 format, but not written by Word");
38f5736e95SDavid du Colombier 	DBG_MSG_C(ucVersion == 4, "Written by Word 5.x");
39f5736e95SDavid du Colombier 	if (bFastSaved) {
40f5736e95SDavid du Colombier 		werr(0, "Word for DOS: autosave documents are not supported");
41f5736e95SDavid du Colombier 		return FALSE;
42f5736e95SDavid du Colombier 	}
43f5736e95SDavid du Colombier 
44f5736e95SDavid du Colombier 	/* Get length information */
45f5736e95SDavid du Colombier 	ulTextLen = ulGetLong(0x0e, aucHeader);
46f5736e95SDavid du Colombier 	DBG_HEX(ulTextLen);
47f5736e95SDavid du Colombier 	ulTextLen -= 128;
48f5736e95SDavid du Colombier 	DBG_DEC(ulTextLen);
49f5736e95SDavid du Colombier 	tTextBlock.ulFileOffset = 128;
50f5736e95SDavid du Colombier 	tTextBlock.ulCharPos = 128;
51f5736e95SDavid du Colombier 	tTextBlock.ulLength = ulTextLen;
52f5736e95SDavid du Colombier 	tTextBlock.bUsesUnicode = FALSE;
53f5736e95SDavid du Colombier 	tTextBlock.usPropMod = IGNORE_PROPMOD;
54f5736e95SDavid du Colombier 	if (!bAdd2TextBlockList(&tTextBlock)) {
55f5736e95SDavid du Colombier 		DBG_HEX(tTextBlock.ulFileOffset);
56f5736e95SDavid du Colombier 		DBG_HEX(tTextBlock.ulCharPos);
57f5736e95SDavid du Colombier 		DBG_DEC(tTextBlock.ulLength);
58f5736e95SDavid du Colombier 		DBG_DEC(tTextBlock.bUsesUnicode);
59f5736e95SDavid du Colombier 		DBG_DEC(tTextBlock.usPropMod);
60f5736e95SDavid du Colombier 		return FALSE;
61f5736e95SDavid du Colombier 	}
62f5736e95SDavid du Colombier 	return TRUE;
63f5736e95SDavid du Colombier } /* end of bGetDocumentText */
64f5736e95SDavid du Colombier 
65f5736e95SDavid du Colombier /*
66f5736e95SDavid du Colombier  * iInitDocumentDOS - initialize an DOS document
67f5736e95SDavid du Colombier  *
68f5736e95SDavid du Colombier  * Returns the version of Word that made the document or -1
69f5736e95SDavid du Colombier  */
70f5736e95SDavid du Colombier int
iInitDocumentDOS(FILE * pFile,long lFilesize)71f5736e95SDavid du Colombier iInitDocumentDOS(FILE *pFile, long lFilesize)
72f5736e95SDavid du Colombier {
73f5736e95SDavid du Colombier 	int	iWordVersion;
74f5736e95SDavid du Colombier 	BOOL	bSuccess;
75f5736e95SDavid du Colombier 	USHORT	usIdent;
76f5736e95SDavid du Colombier 	UCHAR	aucHeader[128];
77f5736e95SDavid du Colombier 
78f5736e95SDavid du Colombier 	fail(pFile == NULL);
79f5736e95SDavid du Colombier 
80f5736e95SDavid du Colombier 	if (lFilesize < 128) {
81f5736e95SDavid du Colombier 		return -1;
82f5736e95SDavid du Colombier 	}
83f5736e95SDavid du Colombier 
84f5736e95SDavid du Colombier 	/* Read the headerblock */
85f5736e95SDavid du Colombier 	if (!bReadBytes(aucHeader, 128, 0x00, pFile)) {
86f5736e95SDavid du Colombier 		return -1;
87f5736e95SDavid du Colombier 	}
88f5736e95SDavid du Colombier 	/* Get the "magic number" from the header */
89f5736e95SDavid du Colombier 	usIdent = usGetWord(0x00, aucHeader);
90f5736e95SDavid du Colombier 	DBG_HEX(usIdent);
91f5736e95SDavid du Colombier 	fail(usIdent != 0xbe31);	/* Word for DOS */
92f5736e95SDavid du Colombier 	iWordVersion = iGetVersionNumber(aucHeader);
93f5736e95SDavid du Colombier 	if (iWordVersion != 0) {
94f5736e95SDavid du Colombier 		werr(0, "This file is not from 'Word for DOS'.");
95f5736e95SDavid du Colombier 		return -1;
96f5736e95SDavid du Colombier 	}
97f5736e95SDavid du Colombier 	bSuccess = bGetDocumentText(pFile, lFilesize, aucHeader);
98f5736e95SDavid du Colombier 	if (bSuccess) {
99*25b329d5SDavid du Colombier 		vGetPropertyInfo(pFile, NULL,
100*25b329d5SDavid du Colombier 				NULL, 0, NULL, 0,
101*25b329d5SDavid du Colombier 				aucHeader, iWordVersion);
102f5736e95SDavid du Colombier 		vSetDefaultTabWidth(pFile, NULL,
103f5736e95SDavid du Colombier 				NULL, 0, NULL, 0,
104f5736e95SDavid du Colombier 				aucHeader, iWordVersion);
105*25b329d5SDavid du Colombier 		vGetNotesInfo(pFile, NULL,
106f5736e95SDavid du Colombier 				NULL, 0, NULL, 0,
107f5736e95SDavid du Colombier 				aucHeader, iWordVersion);
108f5736e95SDavid du Colombier 	}
109f5736e95SDavid du Colombier 	return bSuccess ? iWordVersion : -1;
110f5736e95SDavid du Colombier } /* end of iInitDocumentDOS */
111