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