1f5736e95SDavid du Colombier /*
2f5736e95SDavid du Colombier * notes.c
3*25b329d5SDavid du Colombier * Copyright (C) 1998-2005 A.J. van Os; Released under GNU GPL
4f5736e95SDavid du Colombier *
5f5736e95SDavid du Colombier * Description:
6f5736e95SDavid du Colombier * Functions to tell the difference between footnotes and endnotes
7f5736e95SDavid du Colombier */
8f5736e95SDavid du Colombier
9f5736e95SDavid du Colombier #include "antiword.h"
10f5736e95SDavid du Colombier
11*25b329d5SDavid du Colombier /*
12*25b329d5SDavid du Colombier * Private structures to hide the way the information
13*25b329d5SDavid du Colombier * is stored from the rest of the program
14*25b329d5SDavid du Colombier */
15*25b329d5SDavid du Colombier typedef struct footnote_local_tag {
16*25b329d5SDavid du Colombier footnote_block_type tInfo;
17*25b329d5SDavid du Colombier ULONG ulCharPosStart;
18*25b329d5SDavid du Colombier ULONG ulCharPosNext;
19*25b329d5SDavid du Colombier BOOL bUseful;
20*25b329d5SDavid du Colombier } footnote_local_type;
21*25b329d5SDavid du Colombier
22*25b329d5SDavid du Colombier /* Variables needed to write the Footnote and Endnote information */
23f5736e95SDavid du Colombier static ULONG *aulFootnoteList = NULL;
24f5736e95SDavid du Colombier static size_t tFootnoteListLength = 0;
25f5736e95SDavid du Colombier static ULONG *aulEndnoteList = NULL;
26f5736e95SDavid du Colombier static size_t tEndnoteListLength = 0;
27*25b329d5SDavid du Colombier /* Variables needed to write the Footnote Text */
28*25b329d5SDavid du Colombier static footnote_local_type *pFootnoteText = NULL;
29*25b329d5SDavid du Colombier static size_t tFootnoteTextLength = 0;
30f5736e95SDavid du Colombier
31f5736e95SDavid du Colombier
32f5736e95SDavid du Colombier /*
33f5736e95SDavid du Colombier * Destroy the lists with footnote and endnote information
34f5736e95SDavid du Colombier */
35f5736e95SDavid du Colombier void
vDestroyNotesInfoLists(void)36f5736e95SDavid du Colombier vDestroyNotesInfoLists(void)
37f5736e95SDavid du Colombier {
38*25b329d5SDavid du Colombier footnote_local_type *pRecord;
39*25b329d5SDavid du Colombier size_t tFootnote;
40*25b329d5SDavid du Colombier
41*25b329d5SDavid du Colombier TRACE_MSG("vDestroyNotesInfoLists");
42f5736e95SDavid du Colombier
43f5736e95SDavid du Colombier /* Free the lists and reset all control variables */
44f5736e95SDavid du Colombier aulEndnoteList = xfree(aulEndnoteList);
45f5736e95SDavid du Colombier aulFootnoteList = xfree(aulFootnoteList);
46f5736e95SDavid du Colombier tEndnoteListLength = 0;
47f5736e95SDavid du Colombier tFootnoteListLength = 0;
48*25b329d5SDavid du Colombier for (tFootnote = 0; tFootnote < tFootnoteTextLength; tFootnote++) {
49*25b329d5SDavid du Colombier pRecord = pFootnoteText + tFootnote;
50*25b329d5SDavid du Colombier pRecord->tInfo.szText = xfree(pRecord->tInfo.szText);
51*25b329d5SDavid du Colombier }
52*25b329d5SDavid du Colombier pFootnoteText = xfree(pFootnoteText);
53*25b329d5SDavid du Colombier tFootnoteTextLength = 0;
54f5736e95SDavid du Colombier } /* end of vDestroyNotesInfoLists */
55f5736e95SDavid du Colombier
56f5736e95SDavid du Colombier /*
57*25b329d5SDavid du Colombier * Build the list with footnote information for Word for DOS files
58*25b329d5SDavid du Colombier */
59*25b329d5SDavid du Colombier static void
vGet0FootnotesInfoAndText(FILE * pFile,const UCHAR * aucHeader)60*25b329d5SDavid du Colombier vGet0FootnotesInfoAndText(FILE *pFile, const UCHAR *aucHeader)
61*25b329d5SDavid du Colombier {
62*25b329d5SDavid du Colombier footnote_local_type *pCurr;
63*25b329d5SDavid du Colombier UCHAR *aucBuffer;
64*25b329d5SDavid du Colombier ULONG ulFileOffset, ulBeginOfText, ulOffset, ulBeginFootnoteInfo;
65*25b329d5SDavid du Colombier ULONG ulCharPos, ulBeginNextBlock;
66*25b329d5SDavid du Colombier size_t tFootnotes, tFootnoteInfoLen;
67*25b329d5SDavid du Colombier size_t tIndex;
68*25b329d5SDavid du Colombier UCHAR aucTmp[2];
69*25b329d5SDavid du Colombier
70*25b329d5SDavid du Colombier TRACE_MSG("vGet0FootnotesInfoAndText");
71*25b329d5SDavid du Colombier
72*25b329d5SDavid du Colombier fail(pFile == NULL || aucHeader == NULL);
73*25b329d5SDavid du Colombier
74*25b329d5SDavid du Colombier ulBeginOfText = 128;
75*25b329d5SDavid du Colombier NO_DBG_HEX(ulBeginOfText);
76*25b329d5SDavid du Colombier ulBeginFootnoteInfo = 128 * (ULONG)usGetWord(0x14, aucHeader);
77*25b329d5SDavid du Colombier DBG_HEX(ulBeginFootnoteInfo);
78*25b329d5SDavid du Colombier ulBeginNextBlock = 128 * (ULONG)usGetWord(0x16, aucHeader);
79*25b329d5SDavid du Colombier DBG_HEX(ulBeginNextBlock);
80*25b329d5SDavid du Colombier
81*25b329d5SDavid du Colombier if (ulBeginFootnoteInfo == ulBeginNextBlock) {
82*25b329d5SDavid du Colombier DBG_MSG("No Footnotes in this document");
83*25b329d5SDavid du Colombier return;
84*25b329d5SDavid du Colombier }
85*25b329d5SDavid du Colombier
86*25b329d5SDavid du Colombier /* Read the the number of footnotes + 1 */
87*25b329d5SDavid du Colombier if (!bReadBytes(aucTmp, 2, ulBeginFootnoteInfo, pFile)) {
88*25b329d5SDavid du Colombier return;
89*25b329d5SDavid du Colombier }
90*25b329d5SDavid du Colombier tFootnotes = (size_t)usGetWord(0, aucTmp);
91*25b329d5SDavid du Colombier if (tFootnotes < 2) {
92*25b329d5SDavid du Colombier DBG_MSG("No Footnotes in this document (2)");
93*25b329d5SDavid du Colombier }
94*25b329d5SDavid du Colombier DBG_DEC(tFootnotes);
95*25b329d5SDavid du Colombier tFootnoteInfoLen = 8 * tFootnotes;
96*25b329d5SDavid du Colombier
97*25b329d5SDavid du Colombier aucBuffer = xmalloc(tFootnoteInfoLen);
98*25b329d5SDavid du Colombier if (!bReadBytes(aucBuffer,
99*25b329d5SDavid du Colombier tFootnoteInfoLen, ulBeginFootnoteInfo + 4, pFile)) {
100*25b329d5SDavid du Colombier aucBuffer = xfree(aucBuffer);
101*25b329d5SDavid du Colombier return;
102*25b329d5SDavid du Colombier }
103*25b329d5SDavid du Colombier DBG_PRINT_BLOCK(aucBuffer, tFootnoteInfoLen);
104*25b329d5SDavid du Colombier
105*25b329d5SDavid du Colombier /* Get footnote information */
106*25b329d5SDavid du Colombier fail(tFootnoteListLength != 0);
107*25b329d5SDavid du Colombier tFootnoteListLength = tFootnotes - 1;
108*25b329d5SDavid du Colombier fail(tFootnoteListLength == 0);
109*25b329d5SDavid du Colombier
110*25b329d5SDavid du Colombier fail(aulFootnoteList != NULL);
111*25b329d5SDavid du Colombier aulFootnoteList = xcalloc(tFootnoteListLength, sizeof(ULONG));
112*25b329d5SDavid du Colombier
113*25b329d5SDavid du Colombier for (tIndex = 0; tIndex < tFootnoteListLength; tIndex++) {
114*25b329d5SDavid du Colombier ulOffset = ulGetLong(tIndex * 8, aucBuffer);
115*25b329d5SDavid du Colombier DBG_HEX(ulOffset);
116*25b329d5SDavid du Colombier ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset);
117*25b329d5SDavid du Colombier DBG_HEX(ulFileOffset);
118*25b329d5SDavid du Colombier aulFootnoteList[tIndex] = ulFileOffset;
119*25b329d5SDavid du Colombier }
120*25b329d5SDavid du Colombier
121*25b329d5SDavid du Colombier /* Get footnote text */
122*25b329d5SDavid du Colombier fail(tFootnoteTextLength != 0);
123*25b329d5SDavid du Colombier tFootnoteTextLength = tFootnotes - 1;
124*25b329d5SDavid du Colombier fail(tFootnoteTextLength == 0);
125*25b329d5SDavid du Colombier
126*25b329d5SDavid du Colombier fail(pFootnoteText != NULL);
127*25b329d5SDavid du Colombier pFootnoteText = xcalloc(tFootnoteTextLength,
128*25b329d5SDavid du Colombier sizeof(footnote_local_type));
129*25b329d5SDavid du Colombier
130*25b329d5SDavid du Colombier for (tIndex = 0; tIndex < tFootnoteTextLength; tIndex++) {
131*25b329d5SDavid du Colombier pCurr = pFootnoteText + tIndex;
132*25b329d5SDavid du Colombier pCurr->tInfo.szText = NULL;
133*25b329d5SDavid du Colombier ulOffset = ulGetLong(tIndex * 8 + 4, aucBuffer);
134*25b329d5SDavid du Colombier DBG_HEX(ulOffset);
135*25b329d5SDavid du Colombier ulCharPos = ulBeginOfText + ulOffset;
136*25b329d5SDavid du Colombier DBG_HEX(ulCharPos);
137*25b329d5SDavid du Colombier DBG_HEX(ulCharPos2FileOffset(ulCharPos));
138*25b329d5SDavid du Colombier pCurr->ulCharPosStart = ulCharPos;
139*25b329d5SDavid du Colombier ulOffset = ulGetLong((tIndex + 1) * 8 + 4, aucBuffer);
140*25b329d5SDavid du Colombier DBG_HEX(ulOffset);
141*25b329d5SDavid du Colombier ulCharPos = ulBeginOfText + ulOffset;
142*25b329d5SDavid du Colombier DBG_HEX(ulCharPos);
143*25b329d5SDavid du Colombier DBG_HEX(ulCharPos2FileOffset(ulCharPos));
144*25b329d5SDavid du Colombier pCurr->ulCharPosNext = ulCharPos;
145*25b329d5SDavid du Colombier pCurr->bUseful = pCurr->ulCharPosStart != pCurr->ulCharPosNext;
146*25b329d5SDavid du Colombier }
147*25b329d5SDavid du Colombier aucBuffer = xfree(aucBuffer);
148*25b329d5SDavid du Colombier } /* end of vGet0FootnotesInfoAndText */
149*25b329d5SDavid du Colombier
150*25b329d5SDavid du Colombier /*
151*25b329d5SDavid du Colombier * Build the lists note information for Word for DOS files
152*25b329d5SDavid du Colombier */
153*25b329d5SDavid du Colombier static void
vGet0NotesInfo(FILE * pFile,const UCHAR * aucHeader)154*25b329d5SDavid du Colombier vGet0NotesInfo(FILE *pFile, const UCHAR *aucHeader)
155*25b329d5SDavid du Colombier {
156*25b329d5SDavid du Colombier TRACE_MSG("vGet0NotesInfo");
157*25b329d5SDavid du Colombier
158*25b329d5SDavid du Colombier vGet0FootnotesInfoAndText(pFile, aucHeader);
159*25b329d5SDavid du Colombier /* There are no endnotes in a Word for DOS file */
160*25b329d5SDavid du Colombier } /* end of vGet0NotesInfo */
161*25b329d5SDavid du Colombier
162*25b329d5SDavid du Colombier /*
163*25b329d5SDavid du Colombier * Build the list with footnote information for WinWord 1/2 files
164*25b329d5SDavid du Colombier */
165*25b329d5SDavid du Colombier static void
vGet2FootnotesInfo(FILE * pFile,const UCHAR * aucHeader)166*25b329d5SDavid du Colombier vGet2FootnotesInfo(FILE *pFile, const UCHAR *aucHeader)
167*25b329d5SDavid du Colombier {
168*25b329d5SDavid du Colombier UCHAR *aucBuffer;
169*25b329d5SDavid du Colombier ULONG ulFileOffset, ulBeginOfText, ulOffset, ulBeginFootnoteInfo;
170*25b329d5SDavid du Colombier size_t tFootnoteInfoLen;
171*25b329d5SDavid du Colombier size_t tIndex;
172*25b329d5SDavid du Colombier
173*25b329d5SDavid du Colombier TRACE_MSG("vGet2FootnotesInfo");
174*25b329d5SDavid du Colombier
175*25b329d5SDavid du Colombier fail(pFile == NULL || aucHeader == NULL);
176*25b329d5SDavid du Colombier
177*25b329d5SDavid du Colombier ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */
178*25b329d5SDavid du Colombier NO_DBG_HEX(ulBeginOfText);
179*25b329d5SDavid du Colombier ulBeginFootnoteInfo = ulGetLong(0x64, aucHeader); /* fcPlcffndRef */
180*25b329d5SDavid du Colombier NO_DBG_HEX(ulBeginFootnoteInfo);
181*25b329d5SDavid du Colombier tFootnoteInfoLen = (size_t)usGetWord(0x68, aucHeader); /* cbPlcffndRef */
182*25b329d5SDavid du Colombier NO_DBG_DEC(tFootnoteInfoLen);
183*25b329d5SDavid du Colombier
184*25b329d5SDavid du Colombier if (tFootnoteInfoLen < 10) {
185*25b329d5SDavid du Colombier DBG_MSG("No Footnotes in this document");
186*25b329d5SDavid du Colombier return;
187*25b329d5SDavid du Colombier }
188*25b329d5SDavid du Colombier
189*25b329d5SDavid du Colombier aucBuffer = xmalloc(tFootnoteInfoLen);
190*25b329d5SDavid du Colombier if (!bReadBytes(aucBuffer,
191*25b329d5SDavid du Colombier tFootnoteInfoLen, ulBeginFootnoteInfo, pFile)) {
192*25b329d5SDavid du Colombier aucBuffer = xfree(aucBuffer);
193*25b329d5SDavid du Colombier return;
194*25b329d5SDavid du Colombier }
195*25b329d5SDavid du Colombier NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteInfoLen);
196*25b329d5SDavid du Colombier
197*25b329d5SDavid du Colombier fail(tFootnoteListLength != 0);
198*25b329d5SDavid du Colombier tFootnoteListLength = (tFootnoteInfoLen - 4) / 6;
199*25b329d5SDavid du Colombier fail(tFootnoteListLength == 0);
200*25b329d5SDavid du Colombier
201*25b329d5SDavid du Colombier fail(aulFootnoteList != NULL);
202*25b329d5SDavid du Colombier aulFootnoteList = xcalloc(tFootnoteListLength, sizeof(ULONG));
203*25b329d5SDavid du Colombier
204*25b329d5SDavid du Colombier for (tIndex = 0; tIndex < tFootnoteListLength; tIndex++) {
205*25b329d5SDavid du Colombier ulOffset = ulGetLong(tIndex * 4, aucBuffer);
206*25b329d5SDavid du Colombier NO_DBG_HEX(ulOffset);
207*25b329d5SDavid du Colombier ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset);
208*25b329d5SDavid du Colombier NO_DBG_HEX(ulFileOffset);
209*25b329d5SDavid du Colombier aulFootnoteList[tIndex] = ulFileOffset;
210*25b329d5SDavid du Colombier }
211*25b329d5SDavid du Colombier aucBuffer = xfree(aucBuffer);
212*25b329d5SDavid du Colombier } /* end of vGet2FootnotesInfo */
213*25b329d5SDavid du Colombier
214*25b329d5SDavid du Colombier /*
215*25b329d5SDavid du Colombier * Build the list with footnote text information for WinWord 1/2 files
216*25b329d5SDavid du Colombier */
217*25b329d5SDavid du Colombier static void
vGet2FootnotesText(FILE * pFile,const UCHAR * aucHeader)218*25b329d5SDavid du Colombier vGet2FootnotesText(FILE *pFile, const UCHAR *aucHeader)
219*25b329d5SDavid du Colombier {
220*25b329d5SDavid du Colombier footnote_local_type *pCurr;
221*25b329d5SDavid du Colombier UCHAR *aucBuffer;
222*25b329d5SDavid du Colombier ULONG ulCharPos, ulBeginOfFootnotes, ulOffset, ulBeginFootnoteText;
223*25b329d5SDavid du Colombier size_t tFootnoteTextLen;
224*25b329d5SDavid du Colombier size_t tIndex;
225*25b329d5SDavid du Colombier
226*25b329d5SDavid du Colombier TRACE_MSG("vGet2FootnotesText");
227*25b329d5SDavid du Colombier
228*25b329d5SDavid du Colombier fail(pFile == NULL || aucHeader == NULL);
229*25b329d5SDavid du Colombier
230*25b329d5SDavid du Colombier ulBeginOfFootnotes = ulGetLong(0x18, aucHeader); /* fcMin */
231*25b329d5SDavid du Colombier ulBeginOfFootnotes += ulGetLong(0x34, aucHeader); /* ccpText */
232*25b329d5SDavid du Colombier NO_DBG_HEX(ulBeginOfFootnotes);
233*25b329d5SDavid du Colombier
234*25b329d5SDavid du Colombier ulBeginFootnoteText = ulGetLong(0x6a, aucHeader); /* fcPlcffndTxt */
235*25b329d5SDavid du Colombier NO_DBG_HEX(ulBeginFootnoteText);
236*25b329d5SDavid du Colombier tFootnoteTextLen =
237*25b329d5SDavid du Colombier (size_t)usGetWord(0x6e, aucHeader); /* cbPlcffndTxt */
238*25b329d5SDavid du Colombier NO_DBG_DEC(tFootnoteTextLen);
239*25b329d5SDavid du Colombier
240*25b329d5SDavid du Colombier if (tFootnoteTextLen < 12) {
241*25b329d5SDavid du Colombier DBG_MSG("No Footnote text in this document");
242*25b329d5SDavid du Colombier return;
243*25b329d5SDavid du Colombier }
244*25b329d5SDavid du Colombier
245*25b329d5SDavid du Colombier aucBuffer = xmalloc(tFootnoteTextLen);
246*25b329d5SDavid du Colombier if (!bReadBytes(aucBuffer,
247*25b329d5SDavid du Colombier tFootnoteTextLen, ulBeginFootnoteText, pFile)) {
248*25b329d5SDavid du Colombier aucBuffer = xfree(aucBuffer);
249*25b329d5SDavid du Colombier return;
250*25b329d5SDavid du Colombier }
251*25b329d5SDavid du Colombier NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteTextLen);
252*25b329d5SDavid du Colombier
253*25b329d5SDavid du Colombier fail(tFootnoteTextLength != 0);
254*25b329d5SDavid du Colombier tFootnoteTextLength = tFootnoteTextLen / 4 - 2;
255*25b329d5SDavid du Colombier fail(tFootnoteTextLength == 0);
256*25b329d5SDavid du Colombier
257*25b329d5SDavid du Colombier fail(pFootnoteText != NULL);
258*25b329d5SDavid du Colombier pFootnoteText = xcalloc(tFootnoteTextLength,
259*25b329d5SDavid du Colombier sizeof(footnote_local_type));
260*25b329d5SDavid du Colombier
261*25b329d5SDavid du Colombier for (tIndex = 0; tIndex < tFootnoteTextLength; tIndex++) {
262*25b329d5SDavid du Colombier pCurr = pFootnoteText + tIndex;
263*25b329d5SDavid du Colombier pCurr->tInfo.szText = NULL;
264*25b329d5SDavid du Colombier ulOffset = ulGetLong(tIndex * 4, aucBuffer);
265*25b329d5SDavid du Colombier NO_DBG_HEX(ulOffset);
266*25b329d5SDavid du Colombier ulCharPos = ulBeginOfFootnotes + ulOffset;
267*25b329d5SDavid du Colombier NO_DBG_HEX(ulCharPos);
268*25b329d5SDavid du Colombier NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos));
269*25b329d5SDavid du Colombier pCurr->ulCharPosStart = ulCharPos;
270*25b329d5SDavid du Colombier ulOffset = ulGetLong(tIndex * 4 + 4, aucBuffer);
271*25b329d5SDavid du Colombier NO_DBG_HEX(ulOffset);
272*25b329d5SDavid du Colombier ulCharPos = ulBeginOfFootnotes + ulOffset;
273*25b329d5SDavid du Colombier NO_DBG_HEX(ulCharPos);
274*25b329d5SDavid du Colombier NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos));
275*25b329d5SDavid du Colombier pCurr->ulCharPosNext = ulCharPos;
276*25b329d5SDavid du Colombier pCurr->bUseful = pCurr->ulCharPosStart != pCurr->ulCharPosNext;
277*25b329d5SDavid du Colombier }
278*25b329d5SDavid du Colombier aucBuffer = xfree(aucBuffer);
279*25b329d5SDavid du Colombier } /* end of vGet2FootnotesText */
280*25b329d5SDavid du Colombier
281*25b329d5SDavid du Colombier /*
282*25b329d5SDavid du Colombier * Build the lists note information for WinWord 1/2 files
283*25b329d5SDavid du Colombier */
284*25b329d5SDavid du Colombier static void
vGet2NotesInfo(FILE * pFile,const UCHAR * aucHeader)285*25b329d5SDavid du Colombier vGet2NotesInfo(FILE *pFile, const UCHAR *aucHeader)
286*25b329d5SDavid du Colombier {
287*25b329d5SDavid du Colombier TRACE_MSG("vGet2NotesInfo");
288*25b329d5SDavid du Colombier
289*25b329d5SDavid du Colombier vGet2FootnotesInfo(pFile, aucHeader);
290*25b329d5SDavid du Colombier vGet2FootnotesText(pFile, aucHeader);
291*25b329d5SDavid du Colombier /* There are no endnotes in a WinWord 1/2 file */
292*25b329d5SDavid du Colombier } /* end of vGet2NotesInfo */
293*25b329d5SDavid du Colombier
294*25b329d5SDavid du Colombier /*
295f5736e95SDavid du Colombier * Build the list with footnote information for Word 6/7 files
296f5736e95SDavid du Colombier */
297f5736e95SDavid du Colombier static void
vGet6FootnotesInfo(FILE * pFile,ULONG ulStartBlock,const ULONG * aulBBD,size_t tBBDLen,const UCHAR * aucHeader)298f5736e95SDavid du Colombier vGet6FootnotesInfo(FILE *pFile, ULONG ulStartBlock,
299f5736e95SDavid du Colombier const ULONG *aulBBD, size_t tBBDLen,
300f5736e95SDavid du Colombier const UCHAR *aucHeader)
301f5736e95SDavid du Colombier {
302f5736e95SDavid du Colombier UCHAR *aucBuffer;
303f5736e95SDavid du Colombier ULONG ulFileOffset, ulBeginOfText, ulOffset, ulBeginFootnoteInfo;
304f5736e95SDavid du Colombier size_t tFootnoteInfoLen;
305*25b329d5SDavid du Colombier size_t tIndex;
306*25b329d5SDavid du Colombier
307*25b329d5SDavid du Colombier TRACE_MSG("vGet6FootnotesInfo");
308f5736e95SDavid du Colombier
309f5736e95SDavid du Colombier fail(pFile == NULL || aucHeader == NULL);
310f5736e95SDavid du Colombier fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN);
311f5736e95SDavid du Colombier fail(aulBBD == NULL);
312f5736e95SDavid du Colombier
313*25b329d5SDavid du Colombier ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */
314f5736e95SDavid du Colombier NO_DBG_HEX(ulBeginOfText);
315*25b329d5SDavid du Colombier ulBeginFootnoteInfo = ulGetLong(0x68, aucHeader); /* fcPlcffndRef */
316f5736e95SDavid du Colombier NO_DBG_HEX(ulBeginFootnoteInfo);
317*25b329d5SDavid du Colombier tFootnoteInfoLen =
318*25b329d5SDavid du Colombier (size_t)ulGetLong(0x6c, aucHeader); /* lcbPlcffndRef */
319f5736e95SDavid du Colombier NO_DBG_DEC(tFootnoteInfoLen);
320f5736e95SDavid du Colombier
321f5736e95SDavid du Colombier if (tFootnoteInfoLen < 10) {
322f5736e95SDavid du Colombier DBG_MSG("No Footnotes in this document");
323f5736e95SDavid du Colombier return;
324f5736e95SDavid du Colombier }
325f5736e95SDavid du Colombier
326f5736e95SDavid du Colombier aucBuffer = xmalloc(tFootnoteInfoLen);
327f5736e95SDavid du Colombier if (!bReadBuffer(pFile, ulStartBlock,
328f5736e95SDavid du Colombier aulBBD, tBBDLen, BIG_BLOCK_SIZE,
329f5736e95SDavid du Colombier aucBuffer, ulBeginFootnoteInfo, tFootnoteInfoLen)) {
330f5736e95SDavid du Colombier aucBuffer = xfree(aucBuffer);
331f5736e95SDavid du Colombier return;
332f5736e95SDavid du Colombier }
333f5736e95SDavid du Colombier NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteInfoLen);
334f5736e95SDavid du Colombier
335f5736e95SDavid du Colombier fail(tFootnoteListLength != 0);
336f5736e95SDavid du Colombier tFootnoteListLength = (tFootnoteInfoLen - 4) / 6;
337f5736e95SDavid du Colombier fail(tFootnoteListLength == 0);
338f5736e95SDavid du Colombier
339f5736e95SDavid du Colombier fail(aulFootnoteList != NULL);
340f5736e95SDavid du Colombier aulFootnoteList = xcalloc(tFootnoteListLength, sizeof(ULONG));
341f5736e95SDavid du Colombier
342*25b329d5SDavid du Colombier for (tIndex = 0; tIndex < tFootnoteListLength; tIndex++) {
343*25b329d5SDavid du Colombier ulOffset = ulGetLong(tIndex * 4, aucBuffer);
344f5736e95SDavid du Colombier NO_DBG_HEX(ulOffset);
345f5736e95SDavid du Colombier ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset);
346f5736e95SDavid du Colombier NO_DBG_HEX(ulFileOffset);
347*25b329d5SDavid du Colombier aulFootnoteList[tIndex] = ulFileOffset;
348f5736e95SDavid du Colombier }
349f5736e95SDavid du Colombier aucBuffer = xfree(aucBuffer);
350f5736e95SDavid du Colombier } /* end of vGet6FootnotesInfo */
351f5736e95SDavid du Colombier
352f5736e95SDavid du Colombier /*
353*25b329d5SDavid du Colombier * Build the list with footnote text information for Word 6/7 files
354*25b329d5SDavid du Colombier */
355*25b329d5SDavid du Colombier static void
vGet6FootnotesText(FILE * pFile,ULONG ulStartBlock,const ULONG * aulBBD,size_t tBBDLen,const UCHAR * aucHeader)356*25b329d5SDavid du Colombier vGet6FootnotesText(FILE *pFile, ULONG ulStartBlock,
357*25b329d5SDavid du Colombier const ULONG *aulBBD, size_t tBBDLen,
358*25b329d5SDavid du Colombier const UCHAR *aucHeader)
359*25b329d5SDavid du Colombier {
360*25b329d5SDavid du Colombier footnote_local_type *pCurr;
361*25b329d5SDavid du Colombier UCHAR *aucBuffer;
362*25b329d5SDavid du Colombier ULONG ulCharPos, ulBeginOfFootnotes, ulOffset, ulBeginFootnoteText;
363*25b329d5SDavid du Colombier size_t tFootnoteTextLen;
364*25b329d5SDavid du Colombier size_t tIndex;
365*25b329d5SDavid du Colombier
366*25b329d5SDavid du Colombier TRACE_MSG("vGet6FootnotesText");
367*25b329d5SDavid du Colombier
368*25b329d5SDavid du Colombier fail(pFile == NULL || aucHeader == NULL);
369*25b329d5SDavid du Colombier fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN);
370*25b329d5SDavid du Colombier fail(aulBBD == NULL);
371*25b329d5SDavid du Colombier
372*25b329d5SDavid du Colombier ulBeginOfFootnotes = ulGetLong(0x18, aucHeader); /* fcMin */
373*25b329d5SDavid du Colombier ulBeginOfFootnotes += ulGetLong(0x34, aucHeader); /* ccpText */
374*25b329d5SDavid du Colombier NO_DBG_HEX(ulBeginOfFootnotes);
375*25b329d5SDavid du Colombier
376*25b329d5SDavid du Colombier ulBeginFootnoteText = ulGetLong(0x70, aucHeader); /* fcPlcffndTxt */
377*25b329d5SDavid du Colombier NO_DBG_HEX(ulBeginFootnoteText);
378*25b329d5SDavid du Colombier tFootnoteTextLen =
379*25b329d5SDavid du Colombier (size_t)ulGetLong(0x74, aucHeader); /* lcbPlcffndTxt */
380*25b329d5SDavid du Colombier NO_DBG_DEC(tFootnoteTextLen);
381*25b329d5SDavid du Colombier
382*25b329d5SDavid du Colombier if (tFootnoteTextLen < 12) {
383*25b329d5SDavid du Colombier DBG_MSG("No Footnote text in this document");
384*25b329d5SDavid du Colombier return;
385*25b329d5SDavid du Colombier }
386*25b329d5SDavid du Colombier
387*25b329d5SDavid du Colombier aucBuffer = xmalloc(tFootnoteTextLen);
388*25b329d5SDavid du Colombier if (!bReadBuffer(pFile, ulStartBlock,
389*25b329d5SDavid du Colombier aulBBD, tBBDLen, BIG_BLOCK_SIZE,
390*25b329d5SDavid du Colombier aucBuffer, ulBeginFootnoteText, tFootnoteTextLen)) {
391*25b329d5SDavid du Colombier aucBuffer = xfree(aucBuffer);
392*25b329d5SDavid du Colombier return;
393*25b329d5SDavid du Colombier }
394*25b329d5SDavid du Colombier NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteTextLen);
395*25b329d5SDavid du Colombier
396*25b329d5SDavid du Colombier fail(tFootnoteTextLength != 0);
397*25b329d5SDavid du Colombier tFootnoteTextLength = tFootnoteTextLen / 4 - 2;
398*25b329d5SDavid du Colombier fail(tFootnoteTextLength == 0);
399*25b329d5SDavid du Colombier
400*25b329d5SDavid du Colombier fail(pFootnoteText != NULL);
401*25b329d5SDavid du Colombier pFootnoteText = xcalloc(tFootnoteTextLength,
402*25b329d5SDavid du Colombier sizeof(footnote_local_type));
403*25b329d5SDavid du Colombier
404*25b329d5SDavid du Colombier for (tIndex = 0; tIndex < tFootnoteTextLength; tIndex++) {
405*25b329d5SDavid du Colombier pCurr = pFootnoteText + tIndex;
406*25b329d5SDavid du Colombier pCurr->tInfo.szText = NULL;
407*25b329d5SDavid du Colombier ulOffset = ulGetLong(tIndex * 4, aucBuffer);
408*25b329d5SDavid du Colombier NO_DBG_HEX(ulOffset);
409*25b329d5SDavid du Colombier ulCharPos = ulBeginOfFootnotes + ulOffset;
410*25b329d5SDavid du Colombier NO_DBG_HEX(ulCharPos);
411*25b329d5SDavid du Colombier NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos));
412*25b329d5SDavid du Colombier pCurr->ulCharPosStart = ulCharPos;
413*25b329d5SDavid du Colombier ulOffset = ulGetLong(tIndex * 4 + 4, aucBuffer);
414*25b329d5SDavid du Colombier NO_DBG_HEX(ulOffset);
415*25b329d5SDavid du Colombier ulCharPos = ulBeginOfFootnotes + ulOffset;
416*25b329d5SDavid du Colombier NO_DBG_HEX(ulCharPos);
417*25b329d5SDavid du Colombier NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos));
418*25b329d5SDavid du Colombier pCurr->ulCharPosNext = ulCharPos;
419*25b329d5SDavid du Colombier pCurr->bUseful = pCurr->ulCharPosStart != pCurr->ulCharPosNext;
420*25b329d5SDavid du Colombier }
421*25b329d5SDavid du Colombier aucBuffer = xfree(aucBuffer);
422*25b329d5SDavid du Colombier } /* end of vGet6FootnotesText */
423*25b329d5SDavid du Colombier
424*25b329d5SDavid du Colombier /*
425f5736e95SDavid du Colombier * Build the list with endnote information for Word 6/7 files
426f5736e95SDavid du Colombier */
427f5736e95SDavid du Colombier static void
vGet6EndnotesInfo(FILE * pFile,ULONG ulStartBlock,const ULONG * aulBBD,size_t tBBDLen,const UCHAR * aucHeader)428f5736e95SDavid du Colombier vGet6EndnotesInfo(FILE *pFile, ULONG ulStartBlock,
429f5736e95SDavid du Colombier const ULONG *aulBBD, size_t tBBDLen,
430f5736e95SDavid du Colombier const UCHAR *aucHeader)
431f5736e95SDavid du Colombier {
432f5736e95SDavid du Colombier UCHAR *aucBuffer;
433f5736e95SDavid du Colombier ULONG ulFileOffset, ulBeginOfText, ulOffset, ulBeginEndnoteInfo;
434f5736e95SDavid du Colombier size_t tEndnoteInfoLen;
435*25b329d5SDavid du Colombier size_t tIndex;
436*25b329d5SDavid du Colombier
437*25b329d5SDavid du Colombier TRACE_MSG("vGet6EndnotesInfo");
438f5736e95SDavid du Colombier
439f5736e95SDavid du Colombier fail(pFile == NULL || aucHeader == NULL);
440f5736e95SDavid du Colombier fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN);
441f5736e95SDavid du Colombier fail(aulBBD == NULL);
442f5736e95SDavid du Colombier
443*25b329d5SDavid du Colombier ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */
444f5736e95SDavid du Colombier NO_DBG_HEX(ulBeginOfText);
445*25b329d5SDavid du Colombier ulBeginEndnoteInfo = ulGetLong(0x1d2, aucHeader); /* fcPlcfendRef */
446f5736e95SDavid du Colombier NO_DBG_HEX(ulBeginEndnoteInfo);
447*25b329d5SDavid du Colombier tEndnoteInfoLen =
448*25b329d5SDavid du Colombier (size_t)ulGetLong(0x1d6, aucHeader); /* lcbPlcfendRef */
449f5736e95SDavid du Colombier NO_DBG_DEC(tEndnoteInfoLen);
450f5736e95SDavid du Colombier
451f5736e95SDavid du Colombier if (tEndnoteInfoLen < 10) {
452f5736e95SDavid du Colombier DBG_MSG("No Endnotes in this document");
453f5736e95SDavid du Colombier return;
454f5736e95SDavid du Colombier }
455f5736e95SDavid du Colombier
456f5736e95SDavid du Colombier aucBuffer = xmalloc(tEndnoteInfoLen);
457f5736e95SDavid du Colombier if (!bReadBuffer(pFile, ulStartBlock,
458f5736e95SDavid du Colombier aulBBD, tBBDLen, BIG_BLOCK_SIZE,
459f5736e95SDavid du Colombier aucBuffer, ulBeginEndnoteInfo, tEndnoteInfoLen)) {
460f5736e95SDavid du Colombier aucBuffer = xfree(aucBuffer);
461f5736e95SDavid du Colombier return;
462f5736e95SDavid du Colombier }
463f5736e95SDavid du Colombier NO_DBG_PRINT_BLOCK(aucBuffer, tEndnoteInfoLen);
464f5736e95SDavid du Colombier
465f5736e95SDavid du Colombier fail(tEndnoteListLength != 0);
466f5736e95SDavid du Colombier tEndnoteListLength = (tEndnoteInfoLen - 4) / 6;
467f5736e95SDavid du Colombier fail(tEndnoteListLength == 0);
468f5736e95SDavid du Colombier
469f5736e95SDavid du Colombier fail(aulEndnoteList != NULL);
470f5736e95SDavid du Colombier aulEndnoteList = xcalloc(tEndnoteListLength, sizeof(ULONG));
471f5736e95SDavid du Colombier
472*25b329d5SDavid du Colombier for (tIndex = 0; tIndex < tEndnoteListLength; tIndex++) {
473*25b329d5SDavid du Colombier ulOffset = ulGetLong(tIndex * 4, aucBuffer);
474f5736e95SDavid du Colombier NO_DBG_HEX(ulOffset);
475f5736e95SDavid du Colombier ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset);
476f5736e95SDavid du Colombier NO_DBG_HEX(ulFileOffset);
477*25b329d5SDavid du Colombier aulEndnoteList[tIndex] = ulFileOffset;
478f5736e95SDavid du Colombier }
479f5736e95SDavid du Colombier aucBuffer = xfree(aucBuffer);
480f5736e95SDavid du Colombier } /* end of vGet6EndnotesInfo */
481f5736e95SDavid du Colombier
482f5736e95SDavid du Colombier /*
483f5736e95SDavid du Colombier * Build the lists note information for Word 6/7 files
484f5736e95SDavid du Colombier */
485f5736e95SDavid du Colombier static void
vGet6NotesInfo(FILE * pFile,ULONG ulStartBlock,const ULONG * aulBBD,size_t tBBDLen,const UCHAR * aucHeader)486f5736e95SDavid du Colombier vGet6NotesInfo(FILE *pFile, ULONG ulStartBlock,
487f5736e95SDavid du Colombier const ULONG *aulBBD, size_t tBBDLen,
488f5736e95SDavid du Colombier const UCHAR *aucHeader)
489f5736e95SDavid du Colombier {
490*25b329d5SDavid du Colombier TRACE_MSG("vGet6NotesInfo");
491*25b329d5SDavid du Colombier
492f5736e95SDavid du Colombier vGet6FootnotesInfo(pFile, ulStartBlock,
493f5736e95SDavid du Colombier aulBBD, tBBDLen, aucHeader);
494*25b329d5SDavid du Colombier vGet6FootnotesText(pFile, ulStartBlock,
495*25b329d5SDavid du Colombier aulBBD, tBBDLen, aucHeader);
496f5736e95SDavid du Colombier vGet6EndnotesInfo(pFile, ulStartBlock,
497f5736e95SDavid du Colombier aulBBD, tBBDLen, aucHeader);
498f5736e95SDavid du Colombier } /* end of vGet6NotesInfo */
499f5736e95SDavid du Colombier
500f5736e95SDavid du Colombier /*
501f5736e95SDavid du Colombier * Build the list with footnote information for Word 8/9/10 files
502f5736e95SDavid du Colombier */
503f5736e95SDavid du Colombier static void
vGet8FootnotesInfo(FILE * pFile,const pps_info_type * pPPS,const ULONG * aulBBD,size_t tBBDLen,const ULONG * aulSBD,size_t tSBDLen,const UCHAR * aucHeader)504f5736e95SDavid du Colombier vGet8FootnotesInfo(FILE *pFile, const pps_info_type *pPPS,
505f5736e95SDavid du Colombier const ULONG *aulBBD, size_t tBBDLen,
506f5736e95SDavid du Colombier const ULONG *aulSBD, size_t tSBDLen,
507f5736e95SDavid du Colombier const UCHAR *aucHeader)
508f5736e95SDavid du Colombier {
509f5736e95SDavid du Colombier const ULONG *aulBlockDepot;
510f5736e95SDavid du Colombier UCHAR *aucBuffer;
511f5736e95SDavid du Colombier ULONG ulFileOffset, ulBeginOfText, ulOffset, ulBeginFootnoteInfo;
512f5736e95SDavid du Colombier size_t tFootnoteInfoLen, tBlockDepotLen, tBlockSize;
513*25b329d5SDavid du Colombier size_t tIndex;
514f5736e95SDavid du Colombier
515*25b329d5SDavid du Colombier TRACE_MSG("vGet8FootnotesInfo");
516*25b329d5SDavid du Colombier
517*25b329d5SDavid du Colombier ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */
518f5736e95SDavid du Colombier NO_DBG_HEX(ulBeginOfText);
519*25b329d5SDavid du Colombier ulBeginFootnoteInfo = ulGetLong(0xaa, aucHeader); /* fcPlcffndRef */
520f5736e95SDavid du Colombier NO_DBG_HEX(ulBeginFootnoteInfo);
521*25b329d5SDavid du Colombier tFootnoteInfoLen =
522*25b329d5SDavid du Colombier (size_t)ulGetLong(0xae, aucHeader); /* lcbPlcffndRef */
523f5736e95SDavid du Colombier NO_DBG_DEC(tFootnoteInfoLen);
524f5736e95SDavid du Colombier
525f5736e95SDavid du Colombier if (tFootnoteInfoLen < 10) {
526f5736e95SDavid du Colombier DBG_MSG("No Footnotes in this document");
527f5736e95SDavid du Colombier return;
528f5736e95SDavid du Colombier }
529f5736e95SDavid du Colombier
530*25b329d5SDavid du Colombier NO_DBG_DEC(pPPS->tTable.ulSB);
531*25b329d5SDavid du Colombier NO_DBG_HEX(pPPS->tTable.ulSize);
532*25b329d5SDavid du Colombier if (pPPS->tTable.ulSize == 0) {
533*25b329d5SDavid du Colombier DBG_MSG("No footnotes information");
534f5736e95SDavid du Colombier return;
535f5736e95SDavid du Colombier }
536*25b329d5SDavid du Colombier
537*25b329d5SDavid du Colombier if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) {
538f5736e95SDavid du Colombier /* Use the Small Block Depot */
539f5736e95SDavid du Colombier aulBlockDepot = aulSBD;
540f5736e95SDavid du Colombier tBlockDepotLen = tSBDLen;
541f5736e95SDavid du Colombier tBlockSize = SMALL_BLOCK_SIZE;
542f5736e95SDavid du Colombier } else {
543f5736e95SDavid du Colombier /* Use the Big Block Depot */
544f5736e95SDavid du Colombier aulBlockDepot = aulBBD;
545f5736e95SDavid du Colombier tBlockDepotLen = tBBDLen;
546f5736e95SDavid du Colombier tBlockSize = BIG_BLOCK_SIZE;
547f5736e95SDavid du Colombier }
548f5736e95SDavid du Colombier aucBuffer = xmalloc(tFootnoteInfoLen);
549*25b329d5SDavid du Colombier if (!bReadBuffer(pFile, pPPS->tTable.ulSB,
550f5736e95SDavid du Colombier aulBlockDepot, tBlockDepotLen, tBlockSize,
551f5736e95SDavid du Colombier aucBuffer, ulBeginFootnoteInfo, tFootnoteInfoLen)) {
552f5736e95SDavid du Colombier aucBuffer = xfree(aucBuffer);
553f5736e95SDavid du Colombier return;
554f5736e95SDavid du Colombier }
555f5736e95SDavid du Colombier NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteInfoLen);
556f5736e95SDavid du Colombier
557f5736e95SDavid du Colombier fail(tFootnoteListLength != 0);
558f5736e95SDavid du Colombier tFootnoteListLength = (tFootnoteInfoLen - 4) / 6;
559f5736e95SDavid du Colombier fail(tFootnoteListLength == 0);
560f5736e95SDavid du Colombier
561f5736e95SDavid du Colombier fail(aulFootnoteList != NULL);
562f5736e95SDavid du Colombier aulFootnoteList = xcalloc(tFootnoteListLength, sizeof(ULONG));
563f5736e95SDavid du Colombier
564*25b329d5SDavid du Colombier for (tIndex = 0; tIndex < tFootnoteListLength; tIndex++) {
565*25b329d5SDavid du Colombier ulOffset = ulGetLong(tIndex * 4, aucBuffer);
566f5736e95SDavid du Colombier NO_DBG_HEX(ulOffset);
567f5736e95SDavid du Colombier ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset);
568f5736e95SDavid du Colombier NO_DBG_HEX(ulFileOffset);
569*25b329d5SDavid du Colombier aulFootnoteList[tIndex] = ulFileOffset;
570f5736e95SDavid du Colombier }
571f5736e95SDavid du Colombier aucBuffer = xfree(aucBuffer);
572f5736e95SDavid du Colombier } /* end of vGet8FootnotesInfo */
573f5736e95SDavid du Colombier
574f5736e95SDavid du Colombier /*
575*25b329d5SDavid du Colombier * Build the list with footnote text information for Word 8/9/10 files
576*25b329d5SDavid du Colombier */
577*25b329d5SDavid du Colombier 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)578*25b329d5SDavid du Colombier vGet8FootnotesText(FILE *pFile, const pps_info_type *pPPS,
579*25b329d5SDavid du Colombier const ULONG *aulBBD, size_t tBBDLen,
580*25b329d5SDavid du Colombier const ULONG *aulSBD, size_t tSBDLen,
581*25b329d5SDavid du Colombier const UCHAR *aucHeader)
582*25b329d5SDavid du Colombier {
583*25b329d5SDavid du Colombier footnote_local_type *pCurr;
584*25b329d5SDavid du Colombier const ULONG *aulBlockDepot;
585*25b329d5SDavid du Colombier UCHAR *aucBuffer;
586*25b329d5SDavid du Colombier ULONG ulCharPos, ulBeginOfFootnotes, ulOffset, ulBeginFootnoteText;
587*25b329d5SDavid du Colombier size_t tFootnoteTextLen, tBlockDepotLen, tBlockSize;
588*25b329d5SDavid du Colombier size_t tIndex;
589*25b329d5SDavid du Colombier
590*25b329d5SDavid du Colombier TRACE_MSG("vGet8FootnotesText");
591*25b329d5SDavid du Colombier
592*25b329d5SDavid du Colombier ulBeginOfFootnotes = ulGetLong(0x18, aucHeader); /* fcMin */
593*25b329d5SDavid du Colombier ulBeginOfFootnotes += ulGetLong(0x4c, aucHeader); /* ccpText */
594*25b329d5SDavid du Colombier NO_DBG_HEX(ulBeginOfFootnotes);
595*25b329d5SDavid du Colombier
596*25b329d5SDavid du Colombier ulBeginFootnoteText = ulGetLong(0xb2, aucHeader); /* fcPlcffndTxt */
597*25b329d5SDavid du Colombier NO_DBG_HEX(ulBeginFootnoteText);
598*25b329d5SDavid du Colombier tFootnoteTextLen =
599*25b329d5SDavid du Colombier (size_t)ulGetLong(0xb6, aucHeader); /* lcbPlcffndTxt */
600*25b329d5SDavid du Colombier NO_DBG_DEC(tFootnoteTextLen);
601*25b329d5SDavid du Colombier
602*25b329d5SDavid du Colombier if (tFootnoteTextLen < 12) {
603*25b329d5SDavid du Colombier DBG_MSG("No Footnote text in this document");
604*25b329d5SDavid du Colombier return;
605*25b329d5SDavid du Colombier }
606*25b329d5SDavid du Colombier
607*25b329d5SDavid du Colombier NO_DBG_DEC(pPPS->tTable.ulSB);
608*25b329d5SDavid du Colombier NO_DBG_HEX(pPPS->tTable.ulSize);
609*25b329d5SDavid du Colombier if (pPPS->tTable.ulSize == 0) {
610*25b329d5SDavid du Colombier DBG_MSG("No footnote text information");
611*25b329d5SDavid du Colombier return;
612*25b329d5SDavid du Colombier }
613*25b329d5SDavid du Colombier
614*25b329d5SDavid du Colombier if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) {
615*25b329d5SDavid du Colombier /* Use the Small Block Depot */
616*25b329d5SDavid du Colombier aulBlockDepot = aulSBD;
617*25b329d5SDavid du Colombier tBlockDepotLen = tSBDLen;
618*25b329d5SDavid du Colombier tBlockSize = SMALL_BLOCK_SIZE;
619*25b329d5SDavid du Colombier } else {
620*25b329d5SDavid du Colombier /* Use the Big Block Depot */
621*25b329d5SDavid du Colombier aulBlockDepot = aulBBD;
622*25b329d5SDavid du Colombier tBlockDepotLen = tBBDLen;
623*25b329d5SDavid du Colombier tBlockSize = BIG_BLOCK_SIZE;
624*25b329d5SDavid du Colombier }
625*25b329d5SDavid du Colombier aucBuffer = xmalloc(tFootnoteTextLen);
626*25b329d5SDavid du Colombier if (!bReadBuffer(pFile, pPPS->tTable.ulSB,
627*25b329d5SDavid du Colombier aulBlockDepot, tBlockDepotLen, tBlockSize,
628*25b329d5SDavid du Colombier aucBuffer, ulBeginFootnoteText, tFootnoteTextLen)) {
629*25b329d5SDavid du Colombier aucBuffer = xfree(aucBuffer);
630*25b329d5SDavid du Colombier return;
631*25b329d5SDavid du Colombier }
632*25b329d5SDavid du Colombier NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteTextLen);
633*25b329d5SDavid du Colombier
634*25b329d5SDavid du Colombier fail(tFootnoteTextLength != 0);
635*25b329d5SDavid du Colombier tFootnoteTextLength = tFootnoteTextLen / 4 - 2;
636*25b329d5SDavid du Colombier fail(tFootnoteTextLength == 0);
637*25b329d5SDavid du Colombier
638*25b329d5SDavid du Colombier fail(pFootnoteText != NULL);
639*25b329d5SDavid du Colombier pFootnoteText = xcalloc(tFootnoteTextLength,
640*25b329d5SDavid du Colombier sizeof(footnote_local_type));
641*25b329d5SDavid du Colombier
642*25b329d5SDavid du Colombier for (tIndex = 0; tIndex < tFootnoteTextLength; tIndex++) {
643*25b329d5SDavid du Colombier pCurr = pFootnoteText + tIndex;
644*25b329d5SDavid du Colombier pCurr->tInfo.szText = NULL;
645*25b329d5SDavid du Colombier ulOffset = ulGetLong(tIndex * 4, aucBuffer);
646*25b329d5SDavid du Colombier NO_DBG_HEX(ulOffset);
647*25b329d5SDavid du Colombier ulCharPos = ulBeginOfFootnotes + ulOffset;
648*25b329d5SDavid du Colombier NO_DBG_HEX(ulCharPos);
649*25b329d5SDavid du Colombier NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos));
650*25b329d5SDavid du Colombier pCurr->ulCharPosStart = ulCharPos;
651*25b329d5SDavid du Colombier ulOffset = ulGetLong(tIndex * 4 + 4, aucBuffer);
652*25b329d5SDavid du Colombier NO_DBG_HEX(ulOffset);
653*25b329d5SDavid du Colombier ulCharPos = ulBeginOfFootnotes + ulOffset;
654*25b329d5SDavid du Colombier NO_DBG_HEX(ulCharPos);
655*25b329d5SDavid du Colombier NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos));
656*25b329d5SDavid du Colombier pCurr->ulCharPosNext = ulCharPos;
657*25b329d5SDavid du Colombier pCurr->bUseful = pCurr->ulCharPosStart != pCurr->ulCharPosNext;
658*25b329d5SDavid du Colombier }
659*25b329d5SDavid du Colombier aucBuffer = xfree(aucBuffer);
660*25b329d5SDavid du Colombier } /* end of vGet8FootnotesText */
661*25b329d5SDavid du Colombier
662*25b329d5SDavid du Colombier /*
663f5736e95SDavid du Colombier * Build the list with endnote information for Word 8/9/10 files
664f5736e95SDavid du Colombier */
665f5736e95SDavid du Colombier 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)666f5736e95SDavid du Colombier vGet8EndnotesInfo(FILE *pFile, const pps_info_type *pPPS,
667f5736e95SDavid du Colombier const ULONG *aulBBD, size_t tBBDLen,
668f5736e95SDavid du Colombier const ULONG *aulSBD, size_t tSBDLen,
669f5736e95SDavid du Colombier const UCHAR *aucHeader)
670f5736e95SDavid du Colombier {
671f5736e95SDavid du Colombier const ULONG *aulBlockDepot;
672f5736e95SDavid du Colombier UCHAR *aucBuffer;
673f5736e95SDavid du Colombier ULONG ulFileOffset, ulBeginOfText, ulOffset, ulBeginEndnoteInfo;
674f5736e95SDavid du Colombier size_t tEndnoteInfoLen, tBlockDepotLen, tBlockSize;
675*25b329d5SDavid du Colombier size_t tIndex;
676f5736e95SDavid du Colombier
677*25b329d5SDavid du Colombier TRACE_MSG("vGet8EndnotesInfo");
678*25b329d5SDavid du Colombier
679*25b329d5SDavid du Colombier ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */
680f5736e95SDavid du Colombier NO_DBG_HEX(ulBeginOfText);
681*25b329d5SDavid du Colombier ulBeginEndnoteInfo = ulGetLong(0x20a, aucHeader); /* fcPlcfendRef */
682f5736e95SDavid du Colombier NO_DBG_HEX(ulBeginEndnoteInfo);
683*25b329d5SDavid du Colombier tEndnoteInfoLen = (size_t)ulGetLong(0x20e, aucHeader); /* lcbPlcfendRef */
684f5736e95SDavid du Colombier NO_DBG_DEC(tEndnoteInfoLen);
685f5736e95SDavid du Colombier
686f5736e95SDavid du Colombier if (tEndnoteInfoLen < 10) {
687*25b329d5SDavid du Colombier DBG_MSG("No endnotes in this document");
688f5736e95SDavid du Colombier return;
689f5736e95SDavid du Colombier }
690f5736e95SDavid du Colombier
691*25b329d5SDavid du Colombier NO_DBG_DEC(pPPS->tTable.ulSB);
692*25b329d5SDavid du Colombier NO_DBG_HEX(pPPS->tTable.ulSize);
693*25b329d5SDavid du Colombier if (pPPS->tTable.ulSize == 0) {
694*25b329d5SDavid du Colombier DBG_MSG("No endnotes information");
695f5736e95SDavid du Colombier return;
696f5736e95SDavid du Colombier }
697*25b329d5SDavid du Colombier
698*25b329d5SDavid du Colombier if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) {
699f5736e95SDavid du Colombier /* Use the Small Block Depot */
700f5736e95SDavid du Colombier aulBlockDepot = aulSBD;
701f5736e95SDavid du Colombier tBlockDepotLen = tSBDLen;
702f5736e95SDavid du Colombier tBlockSize = SMALL_BLOCK_SIZE;
703f5736e95SDavid du Colombier } else {
704f5736e95SDavid du Colombier /* Use the Big Block Depot */
705f5736e95SDavid du Colombier aulBlockDepot = aulBBD;
706f5736e95SDavid du Colombier tBlockDepotLen = tBBDLen;
707f5736e95SDavid du Colombier tBlockSize = BIG_BLOCK_SIZE;
708f5736e95SDavid du Colombier }
709f5736e95SDavid du Colombier aucBuffer = xmalloc(tEndnoteInfoLen);
710*25b329d5SDavid du Colombier if (!bReadBuffer(pFile, pPPS->tTable.ulSB,
711f5736e95SDavid du Colombier aulBlockDepot, tBlockDepotLen, tBlockSize,
712f5736e95SDavid du Colombier aucBuffer, ulBeginEndnoteInfo, tEndnoteInfoLen)) {
713f5736e95SDavid du Colombier aucBuffer = xfree(aucBuffer);
714f5736e95SDavid du Colombier return;
715f5736e95SDavid du Colombier }
716f5736e95SDavid du Colombier NO_DBG_PRINT_BLOCK(aucBuffer, tEndnoteInfoLen);
717f5736e95SDavid du Colombier
718f5736e95SDavid du Colombier fail(tEndnoteListLength != 0);
719f5736e95SDavid du Colombier tEndnoteListLength = (tEndnoteInfoLen - 4) / 6;
720f5736e95SDavid du Colombier fail(tEndnoteListLength == 0);
721f5736e95SDavid du Colombier
722f5736e95SDavid du Colombier fail(aulEndnoteList != NULL);
723f5736e95SDavid du Colombier aulEndnoteList = xcalloc(tEndnoteListLength, sizeof(ULONG));
724f5736e95SDavid du Colombier
725*25b329d5SDavid du Colombier for (tIndex = 0; tIndex < tEndnoteListLength; tIndex++) {
726*25b329d5SDavid du Colombier ulOffset = ulGetLong(tIndex * 4, aucBuffer);
727f5736e95SDavid du Colombier NO_DBG_HEX(ulOffset);
728f5736e95SDavid du Colombier ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset);
729f5736e95SDavid du Colombier NO_DBG_HEX(ulFileOffset);
730*25b329d5SDavid du Colombier aulEndnoteList[tIndex] = ulFileOffset;
731f5736e95SDavid du Colombier }
732f5736e95SDavid du Colombier aucBuffer = xfree(aucBuffer);
733f5736e95SDavid du Colombier } /* end of vGet8EndnotesInfo */
734f5736e95SDavid du Colombier
735f5736e95SDavid du Colombier /*
736f5736e95SDavid du Colombier * Build the lists with footnote and endnote information for Word 8/9/10 files
737f5736e95SDavid du Colombier */
738f5736e95SDavid du Colombier static void
vGet8NotesInfo(FILE * pFile,const pps_info_type * pPPS,const ULONG * aulBBD,size_t tBBDLen,const ULONG * aulSBD,size_t tSBDLen,const UCHAR * aucHeader)739f5736e95SDavid du Colombier vGet8NotesInfo(FILE *pFile, const pps_info_type *pPPS,
740f5736e95SDavid du Colombier const ULONG *aulBBD, size_t tBBDLen,
741f5736e95SDavid du Colombier const ULONG *aulSBD, size_t tSBDLen,
742f5736e95SDavid du Colombier const UCHAR *aucHeader)
743f5736e95SDavid du Colombier {
744*25b329d5SDavid du Colombier TRACE_MSG("vGet8NotesInfo");
745*25b329d5SDavid du Colombier
746f5736e95SDavid du Colombier vGet8FootnotesInfo(pFile, pPPS,
747f5736e95SDavid du Colombier aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader);
748*25b329d5SDavid du Colombier vGet8FootnotesText(pFile, pPPS,
749*25b329d5SDavid du Colombier aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader);
750f5736e95SDavid du Colombier vGet8EndnotesInfo(pFile, pPPS,
751f5736e95SDavid du Colombier aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader);
752f5736e95SDavid du Colombier } /* end of vGet8NotesInfo */
753f5736e95SDavid du Colombier
754f5736e95SDavid du Colombier /*
755f5736e95SDavid du Colombier * Build the lists with footnote and endnote information
756f5736e95SDavid du Colombier */
757f5736e95SDavid du Colombier void
vGetNotesInfo(FILE * pFile,const pps_info_type * pPPS,const ULONG * aulBBD,size_t tBBDLen,const ULONG * aulSBD,size_t tSBDLen,const UCHAR * aucHeader,int iWordVersion)758f5736e95SDavid du Colombier vGetNotesInfo(FILE *pFile, const pps_info_type *pPPS,
759f5736e95SDavid du Colombier const ULONG *aulBBD, size_t tBBDLen,
760f5736e95SDavid du Colombier const ULONG *aulSBD, size_t tSBDLen,
761f5736e95SDavid du Colombier const UCHAR *aucHeader, int iWordVersion)
762f5736e95SDavid du Colombier {
763*25b329d5SDavid du Colombier TRACE_MSG("vGetNotesInfo");
764*25b329d5SDavid du Colombier
765*25b329d5SDavid du Colombier fail(pFile == NULL);
766*25b329d5SDavid du Colombier fail(pPPS == NULL && iWordVersion >= 6);
767*25b329d5SDavid du Colombier fail(aulBBD == NULL && tBBDLen != 0);
768*25b329d5SDavid du Colombier fail(aulSBD == NULL && tSBDLen != 0);
769*25b329d5SDavid du Colombier fail(aucHeader == NULL);
770f5736e95SDavid du Colombier
771f5736e95SDavid du Colombier switch (iWordVersion) {
772*25b329d5SDavid du Colombier case 0:
773*25b329d5SDavid du Colombier vGet0NotesInfo(pFile, aucHeader);
774*25b329d5SDavid du Colombier break;
775*25b329d5SDavid du Colombier case 1:
776*25b329d5SDavid du Colombier case 2:
777*25b329d5SDavid du Colombier vGet2NotesInfo(pFile, aucHeader);
778*25b329d5SDavid du Colombier break;
779*25b329d5SDavid du Colombier case 4:
780*25b329d5SDavid du Colombier case 5:
781*25b329d5SDavid du Colombier break;
782f5736e95SDavid du Colombier case 6:
783f5736e95SDavid du Colombier case 7:
784f5736e95SDavid du Colombier vGet6NotesInfo(pFile, pPPS->tWordDocument.ulSB,
785f5736e95SDavid du Colombier aulBBD, tBBDLen, aucHeader);
786f5736e95SDavid du Colombier break;
787f5736e95SDavid du Colombier case 8:
788f5736e95SDavid du Colombier vGet8NotesInfo(pFile, pPPS,
789f5736e95SDavid du Colombier aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader);
790f5736e95SDavid du Colombier break;
791f5736e95SDavid du Colombier default:
792f5736e95SDavid du Colombier werr(0, "Sorry, no notes information");
793f5736e95SDavid du Colombier break;
794f5736e95SDavid du Colombier }
795f5736e95SDavid du Colombier } /* end of vGetNotesInfo */
796f5736e95SDavid du Colombier
797f5736e95SDavid du Colombier /*
798*25b329d5SDavid du Colombier * vPrepareFootnoteText - prepare the footnote text
799*25b329d5SDavid du Colombier */
800*25b329d5SDavid du Colombier void
vPrepareFootnoteText(FILE * pFile)801*25b329d5SDavid du Colombier vPrepareFootnoteText(FILE *pFile)
802*25b329d5SDavid du Colombier {
803*25b329d5SDavid du Colombier footnote_local_type *pCurr;
804*25b329d5SDavid du Colombier size_t tFootnote;
805*25b329d5SDavid du Colombier
806*25b329d5SDavid du Colombier fail(pFile == NULL);
807*25b329d5SDavid du Colombier fail(pFootnoteText == NULL && tFootnoteTextLength != 0);
808*25b329d5SDavid du Colombier
809*25b329d5SDavid du Colombier if (pFootnoteText == NULL || tFootnoteTextLength == 0) {
810*25b329d5SDavid du Colombier /* No information */
811*25b329d5SDavid du Colombier return;
812*25b329d5SDavid du Colombier }
813*25b329d5SDavid du Colombier
814*25b329d5SDavid du Colombier /* Fill text and useful-ness */
815*25b329d5SDavid du Colombier for (tFootnote = 0; tFootnote < tFootnoteTextLength; tFootnote++) {
816*25b329d5SDavid du Colombier pCurr = pFootnoteText + tFootnote;
817*25b329d5SDavid du Colombier pCurr->bUseful = pCurr->ulCharPosStart != pCurr->ulCharPosNext;
818*25b329d5SDavid du Colombier if (pCurr->bUseful) {
819*25b329d5SDavid du Colombier pCurr->tInfo.szText = szFootnoteDecryptor(pFile,
820*25b329d5SDavid du Colombier pCurr->ulCharPosStart,
821*25b329d5SDavid du Colombier pCurr->ulCharPosNext);
822*25b329d5SDavid du Colombier } else {
823*25b329d5SDavid du Colombier pCurr->tInfo.szText = NULL;
824*25b329d5SDavid du Colombier }
825*25b329d5SDavid du Colombier }
826*25b329d5SDavid du Colombier } /* end of vPrepareFootnoteText */
827*25b329d5SDavid du Colombier
828*25b329d5SDavid du Colombier /*
829*25b329d5SDavid du Colombier * szGetFootnootText - get the text of the spefified footnote
830*25b329d5SDavid du Colombier */
831*25b329d5SDavid du Colombier const char *
szGetFootnootText(UINT uiFootnoteIndex)832*25b329d5SDavid du Colombier szGetFootnootText(UINT uiFootnoteIndex)
833*25b329d5SDavid du Colombier {
834*25b329d5SDavid du Colombier if ((size_t)uiFootnoteIndex >= tFootnoteTextLength) {
835*25b329d5SDavid du Colombier return NULL;
836*25b329d5SDavid du Colombier }
837*25b329d5SDavid du Colombier return pFootnoteText[uiFootnoteIndex].tInfo.szText;
838*25b329d5SDavid du Colombier } /* end of szGetFootnootText */
839*25b329d5SDavid du Colombier
840*25b329d5SDavid du Colombier /*
841f5736e95SDavid du Colombier * Get the notetype of the note at the given fileoffset
842f5736e95SDavid du Colombier */
843f5736e95SDavid du Colombier notetype_enum
eGetNotetype(ULONG ulFileOffset)844f5736e95SDavid du Colombier eGetNotetype(ULONG ulFileOffset)
845f5736e95SDavid du Colombier {
846f5736e95SDavid du Colombier size_t tIndex;
847f5736e95SDavid du Colombier
848*25b329d5SDavid du Colombier TRACE_MSG("eGetNotetype");
849*25b329d5SDavid du Colombier
850f5736e95SDavid du Colombier fail(aulFootnoteList == NULL && tFootnoteListLength != 0);
851f5736e95SDavid du Colombier fail(aulEndnoteList == NULL && tEndnoteListLength != 0);
852f5736e95SDavid du Colombier
853f5736e95SDavid du Colombier /* Go for the easy answers first */
854f5736e95SDavid du Colombier if (tFootnoteListLength == 0 && tEndnoteListLength == 0) {
855f5736e95SDavid du Colombier return notetype_is_unknown;
856f5736e95SDavid du Colombier }
857f5736e95SDavid du Colombier if (tEndnoteListLength == 0) {
858f5736e95SDavid du Colombier return notetype_is_footnote;
859f5736e95SDavid du Colombier }
860f5736e95SDavid du Colombier if (tFootnoteListLength == 0) {
861f5736e95SDavid du Colombier return notetype_is_endnote;
862f5736e95SDavid du Colombier }
863f5736e95SDavid du Colombier /* No easy answer, so we search */
864f5736e95SDavid du Colombier for (tIndex = 0; tIndex < tFootnoteListLength; tIndex++) {
865f5736e95SDavid du Colombier if (aulFootnoteList[tIndex] == ulFileOffset) {
866f5736e95SDavid du Colombier return notetype_is_footnote;
867f5736e95SDavid du Colombier }
868f5736e95SDavid du Colombier }
869f5736e95SDavid du Colombier for (tIndex = 0; tIndex < tEndnoteListLength; tIndex++) {
870f5736e95SDavid du Colombier if (aulEndnoteList[tIndex] == ulFileOffset) {
871f5736e95SDavid du Colombier return notetype_is_endnote;
872f5736e95SDavid du Colombier }
873f5736e95SDavid du Colombier }
874f5736e95SDavid du Colombier /* Not found */
875f5736e95SDavid du Colombier return notetype_is_unknown;
876f5736e95SDavid du Colombier } /* end of eGetNotetype */
877