3 * Copyright (C) 1998-2005 A.J. van Os; Released under GNU GPL
6 * Functions to tell the difference between footnotes and endnotes
12 * Private structures to hide the way the information
13 * is stored from the rest of the program
15 typedef struct footnote_local_tag
{
16 footnote_block_type tInfo
;
20 } footnote_local_type
;
22 /* Variables needed to write the Footnote and Endnote information */
23 static ULONG
*aulFootnoteList
= NULL
;
24 static size_t tFootnoteListLength
= 0;
25 static ULONG
*aulEndnoteList
= NULL
;
26 static size_t tEndnoteListLength
= 0;
27 /* Variables needed to write the Footnote Text */
28 static footnote_local_type
*pFootnoteText
= NULL
;
29 static size_t tFootnoteTextLength
= 0;
33 * Destroy the lists with footnote and endnote information
36 vDestroyNotesInfoLists(void)
38 footnote_local_type
*pRecord
;
41 TRACE_MSG("vDestroyNotesInfoLists");
43 /* Free the lists and reset all control variables */
44 aulEndnoteList
= xfree(aulEndnoteList
);
45 aulFootnoteList
= xfree(aulFootnoteList
);
46 tEndnoteListLength
= 0;
47 tFootnoteListLength
= 0;
48 for (tFootnote
= 0; tFootnote
< tFootnoteTextLength
; tFootnote
++) {
49 pRecord
= pFootnoteText
+ tFootnote
;
50 pRecord
->tInfo
.szText
= xfree(pRecord
->tInfo
.szText
);
52 pFootnoteText
= xfree(pFootnoteText
);
53 tFootnoteTextLength
= 0;
54 } /* end of vDestroyNotesInfoLists */
57 * Build the list with footnote information for Word for DOS files
60 vGet0FootnotesInfoAndText(FILE *pFile
, const UCHAR
*aucHeader
)
62 footnote_local_type
*pCurr
;
64 ULONG ulFileOffset
, ulBeginOfText
, ulOffset
, ulBeginFootnoteInfo
;
65 ULONG ulCharPos
, ulBeginNextBlock
;
66 size_t tFootnotes
, tFootnoteInfoLen
;
70 TRACE_MSG("vGet0FootnotesInfoAndText");
72 fail(pFile
== NULL
|| aucHeader
== NULL
);
75 NO_DBG_HEX(ulBeginOfText
);
76 ulBeginFootnoteInfo
= 128 * (ULONG
)usGetWord(0x14, aucHeader
);
77 DBG_HEX(ulBeginFootnoteInfo
);
78 ulBeginNextBlock
= 128 * (ULONG
)usGetWord(0x16, aucHeader
);
79 DBG_HEX(ulBeginNextBlock
);
81 if (ulBeginFootnoteInfo
== ulBeginNextBlock
) {
82 DBG_MSG("No Footnotes in this document");
86 /* Read the the number of footnotes + 1 */
87 if (!bReadBytes(aucTmp
, 2, ulBeginFootnoteInfo
, pFile
)) {
90 tFootnotes
= (size_t)usGetWord(0, aucTmp
);
92 DBG_MSG("No Footnotes in this document (2)");
95 tFootnoteInfoLen
= 8 * tFootnotes
;
97 aucBuffer
= xmalloc(tFootnoteInfoLen
);
98 if (!bReadBytes(aucBuffer
,
99 tFootnoteInfoLen
, ulBeginFootnoteInfo
+ 4, pFile
)) {
100 aucBuffer
= xfree(aucBuffer
);
103 DBG_PRINT_BLOCK(aucBuffer
, tFootnoteInfoLen
);
105 /* Get footnote information */
106 fail(tFootnoteListLength
!= 0);
107 tFootnoteListLength
= tFootnotes
- 1;
108 fail(tFootnoteListLength
== 0);
110 fail(aulFootnoteList
!= NULL
);
111 aulFootnoteList
= xcalloc(tFootnoteListLength
, sizeof(ULONG
));
113 for (tIndex
= 0; tIndex
< tFootnoteListLength
; tIndex
++) {
114 ulOffset
= ulGetLong(tIndex
* 8, aucBuffer
);
116 ulFileOffset
= ulCharPos2FileOffset(ulBeginOfText
+ ulOffset
);
117 DBG_HEX(ulFileOffset
);
118 aulFootnoteList
[tIndex
] = ulFileOffset
;
121 /* Get footnote text */
122 fail(tFootnoteTextLength
!= 0);
123 tFootnoteTextLength
= tFootnotes
- 1;
124 fail(tFootnoteTextLength
== 0);
126 fail(pFootnoteText
!= NULL
);
127 pFootnoteText
= xcalloc(tFootnoteTextLength
,
128 sizeof(footnote_local_type
));
130 for (tIndex
= 0; tIndex
< tFootnoteTextLength
; tIndex
++) {
131 pCurr
= pFootnoteText
+ tIndex
;
132 pCurr
->tInfo
.szText
= NULL
;
133 ulOffset
= ulGetLong(tIndex
* 8 + 4, aucBuffer
);
135 ulCharPos
= ulBeginOfText
+ ulOffset
;
137 DBG_HEX(ulCharPos2FileOffset(ulCharPos
));
138 pCurr
->ulCharPosStart
= ulCharPos
;
139 ulOffset
= ulGetLong((tIndex
+ 1) * 8 + 4, aucBuffer
);
141 ulCharPos
= ulBeginOfText
+ ulOffset
;
143 DBG_HEX(ulCharPos2FileOffset(ulCharPos
));
144 pCurr
->ulCharPosNext
= ulCharPos
;
145 pCurr
->bUseful
= pCurr
->ulCharPosStart
!= pCurr
->ulCharPosNext
;
147 aucBuffer
= xfree(aucBuffer
);
148 } /* end of vGet0FootnotesInfoAndText */
151 * Build the lists note information for Word for DOS files
154 vGet0NotesInfo(FILE *pFile
, const UCHAR
*aucHeader
)
156 TRACE_MSG("vGet0NotesInfo");
158 vGet0FootnotesInfoAndText(pFile
, aucHeader
);
159 /* There are no endnotes in a Word for DOS file */
160 } /* end of vGet0NotesInfo */
163 * Build the list with footnote information for WinWord 1/2 files
166 vGet2FootnotesInfo(FILE *pFile
, const UCHAR
*aucHeader
)
169 ULONG ulFileOffset
, ulBeginOfText
, ulOffset
, ulBeginFootnoteInfo
;
170 size_t tFootnoteInfoLen
;
173 TRACE_MSG("vGet2FootnotesInfo");
175 fail(pFile
== NULL
|| aucHeader
== NULL
);
177 ulBeginOfText
= ulGetLong(0x18, aucHeader
); /* fcMin */
178 NO_DBG_HEX(ulBeginOfText
);
179 ulBeginFootnoteInfo
= ulGetLong(0x64, aucHeader
); /* fcPlcffndRef */
180 NO_DBG_HEX(ulBeginFootnoteInfo
);
181 tFootnoteInfoLen
= (size_t)usGetWord(0x68, aucHeader
); /* cbPlcffndRef */
182 NO_DBG_DEC(tFootnoteInfoLen
);
184 if (tFootnoteInfoLen
< 10) {
185 DBG_MSG("No Footnotes in this document");
189 aucBuffer
= xmalloc(tFootnoteInfoLen
);
190 if (!bReadBytes(aucBuffer
,
191 tFootnoteInfoLen
, ulBeginFootnoteInfo
, pFile
)) {
192 aucBuffer
= xfree(aucBuffer
);
195 NO_DBG_PRINT_BLOCK(aucBuffer
, tFootnoteInfoLen
);
197 fail(tFootnoteListLength
!= 0);
198 tFootnoteListLength
= (tFootnoteInfoLen
- 4) / 6;
199 fail(tFootnoteListLength
== 0);
201 fail(aulFootnoteList
!= NULL
);
202 aulFootnoteList
= xcalloc(tFootnoteListLength
, sizeof(ULONG
));
204 for (tIndex
= 0; tIndex
< tFootnoteListLength
; tIndex
++) {
205 ulOffset
= ulGetLong(tIndex
* 4, aucBuffer
);
206 NO_DBG_HEX(ulOffset
);
207 ulFileOffset
= ulCharPos2FileOffset(ulBeginOfText
+ ulOffset
);
208 NO_DBG_HEX(ulFileOffset
);
209 aulFootnoteList
[tIndex
] = ulFileOffset
;
211 aucBuffer
= xfree(aucBuffer
);
212 } /* end of vGet2FootnotesInfo */
215 * Build the list with footnote text information for WinWord 1/2 files
218 vGet2FootnotesText(FILE *pFile
, const UCHAR
*aucHeader
)
220 footnote_local_type
*pCurr
;
222 ULONG ulCharPos
, ulBeginOfFootnotes
, ulOffset
, ulBeginFootnoteText
;
223 size_t tFootnoteTextLen
;
226 TRACE_MSG("vGet2FootnotesText");
228 fail(pFile
== NULL
|| aucHeader
== NULL
);
230 ulBeginOfFootnotes
= ulGetLong(0x18, aucHeader
); /* fcMin */
231 ulBeginOfFootnotes
+= ulGetLong(0x34, aucHeader
); /* ccpText */
232 NO_DBG_HEX(ulBeginOfFootnotes
);
234 ulBeginFootnoteText
= ulGetLong(0x6a, aucHeader
); /* fcPlcffndTxt */
235 NO_DBG_HEX(ulBeginFootnoteText
);
237 (size_t)usGetWord(0x6e, aucHeader
); /* cbPlcffndTxt */
238 NO_DBG_DEC(tFootnoteTextLen
);
240 if (tFootnoteTextLen
< 12) {
241 DBG_MSG("No Footnote text in this document");
245 aucBuffer
= xmalloc(tFootnoteTextLen
);
246 if (!bReadBytes(aucBuffer
,
247 tFootnoteTextLen
, ulBeginFootnoteText
, pFile
)) {
248 aucBuffer
= xfree(aucBuffer
);
251 NO_DBG_PRINT_BLOCK(aucBuffer
, tFootnoteTextLen
);
253 fail(tFootnoteTextLength
!= 0);
254 tFootnoteTextLength
= tFootnoteTextLen
/ 4 - 2;
255 fail(tFootnoteTextLength
== 0);
257 fail(pFootnoteText
!= NULL
);
258 pFootnoteText
= xcalloc(tFootnoteTextLength
,
259 sizeof(footnote_local_type
));
261 for (tIndex
= 0; tIndex
< tFootnoteTextLength
; tIndex
++) {
262 pCurr
= pFootnoteText
+ tIndex
;
263 pCurr
->tInfo
.szText
= NULL
;
264 ulOffset
= ulGetLong(tIndex
* 4, aucBuffer
);
265 NO_DBG_HEX(ulOffset
);
266 ulCharPos
= ulBeginOfFootnotes
+ ulOffset
;
267 NO_DBG_HEX(ulCharPos
);
268 NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos
));
269 pCurr
->ulCharPosStart
= ulCharPos
;
270 ulOffset
= ulGetLong(tIndex
* 4 + 4, aucBuffer
);
271 NO_DBG_HEX(ulOffset
);
272 ulCharPos
= ulBeginOfFootnotes
+ ulOffset
;
273 NO_DBG_HEX(ulCharPos
);
274 NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos
));
275 pCurr
->ulCharPosNext
= ulCharPos
;
276 pCurr
->bUseful
= pCurr
->ulCharPosStart
!= pCurr
->ulCharPosNext
;
278 aucBuffer
= xfree(aucBuffer
);
279 } /* end of vGet2FootnotesText */
282 * Build the lists note information for WinWord 1/2 files
285 vGet2NotesInfo(FILE *pFile
, const UCHAR
*aucHeader
)
287 TRACE_MSG("vGet2NotesInfo");
289 vGet2FootnotesInfo(pFile
, aucHeader
);
290 vGet2FootnotesText(pFile
, aucHeader
);
291 /* There are no endnotes in a WinWord 1/2 file */
292 } /* end of vGet2NotesInfo */
295 * Build the list with footnote information for Word 6/7 files
298 vGet6FootnotesInfo(FILE *pFile
, ULONG ulStartBlock
,
299 const ULONG
*aulBBD
, size_t tBBDLen
,
300 const UCHAR
*aucHeader
)
303 ULONG ulFileOffset
, ulBeginOfText
, ulOffset
, ulBeginFootnoteInfo
;
304 size_t tFootnoteInfoLen
;
307 TRACE_MSG("vGet6FootnotesInfo");
309 fail(pFile
== NULL
|| aucHeader
== NULL
);
310 fail(ulStartBlock
> MAX_BLOCKNUMBER
&& ulStartBlock
!= END_OF_CHAIN
);
311 fail(aulBBD
== NULL
);
313 ulBeginOfText
= ulGetLong(0x18, aucHeader
); /* fcMin */
314 NO_DBG_HEX(ulBeginOfText
);
315 ulBeginFootnoteInfo
= ulGetLong(0x68, aucHeader
); /* fcPlcffndRef */
316 NO_DBG_HEX(ulBeginFootnoteInfo
);
318 (size_t)ulGetLong(0x6c, aucHeader
); /* lcbPlcffndRef */
319 NO_DBG_DEC(tFootnoteInfoLen
);
321 if (tFootnoteInfoLen
< 10) {
322 DBG_MSG("No Footnotes in this document");
326 aucBuffer
= xmalloc(tFootnoteInfoLen
);
327 if (!bReadBuffer(pFile
, ulStartBlock
,
328 aulBBD
, tBBDLen
, BIG_BLOCK_SIZE
,
329 aucBuffer
, ulBeginFootnoteInfo
, tFootnoteInfoLen
)) {
330 aucBuffer
= xfree(aucBuffer
);
333 NO_DBG_PRINT_BLOCK(aucBuffer
, tFootnoteInfoLen
);
335 fail(tFootnoteListLength
!= 0);
336 tFootnoteListLength
= (tFootnoteInfoLen
- 4) / 6;
337 fail(tFootnoteListLength
== 0);
339 fail(aulFootnoteList
!= NULL
);
340 aulFootnoteList
= xcalloc(tFootnoteListLength
, sizeof(ULONG
));
342 for (tIndex
= 0; tIndex
< tFootnoteListLength
; tIndex
++) {
343 ulOffset
= ulGetLong(tIndex
* 4, aucBuffer
);
344 NO_DBG_HEX(ulOffset
);
345 ulFileOffset
= ulCharPos2FileOffset(ulBeginOfText
+ ulOffset
);
346 NO_DBG_HEX(ulFileOffset
);
347 aulFootnoteList
[tIndex
] = ulFileOffset
;
349 aucBuffer
= xfree(aucBuffer
);
350 } /* end of vGet6FootnotesInfo */
353 * Build the list with footnote text information for Word 6/7 files
356 vGet6FootnotesText(FILE *pFile
, ULONG ulStartBlock
,
357 const ULONG
*aulBBD
, size_t tBBDLen
,
358 const UCHAR
*aucHeader
)
360 footnote_local_type
*pCurr
;
362 ULONG ulCharPos
, ulBeginOfFootnotes
, ulOffset
, ulBeginFootnoteText
;
363 size_t tFootnoteTextLen
;
366 TRACE_MSG("vGet6FootnotesText");
368 fail(pFile
== NULL
|| aucHeader
== NULL
);
369 fail(ulStartBlock
> MAX_BLOCKNUMBER
&& ulStartBlock
!= END_OF_CHAIN
);
370 fail(aulBBD
== NULL
);
372 ulBeginOfFootnotes
= ulGetLong(0x18, aucHeader
); /* fcMin */
373 ulBeginOfFootnotes
+= ulGetLong(0x34, aucHeader
); /* ccpText */
374 NO_DBG_HEX(ulBeginOfFootnotes
);
376 ulBeginFootnoteText
= ulGetLong(0x70, aucHeader
); /* fcPlcffndTxt */
377 NO_DBG_HEX(ulBeginFootnoteText
);
379 (size_t)ulGetLong(0x74, aucHeader
); /* lcbPlcffndTxt */
380 NO_DBG_DEC(tFootnoteTextLen
);
382 if (tFootnoteTextLen
< 12) {
383 DBG_MSG("No Footnote text in this document");
387 aucBuffer
= xmalloc(tFootnoteTextLen
);
388 if (!bReadBuffer(pFile
, ulStartBlock
,
389 aulBBD
, tBBDLen
, BIG_BLOCK_SIZE
,
390 aucBuffer
, ulBeginFootnoteText
, tFootnoteTextLen
)) {
391 aucBuffer
= xfree(aucBuffer
);
394 NO_DBG_PRINT_BLOCK(aucBuffer
, tFootnoteTextLen
);
396 fail(tFootnoteTextLength
!= 0);
397 tFootnoteTextLength
= tFootnoteTextLen
/ 4 - 2;
398 fail(tFootnoteTextLength
== 0);
400 fail(pFootnoteText
!= NULL
);
401 pFootnoteText
= xcalloc(tFootnoteTextLength
,
402 sizeof(footnote_local_type
));
404 for (tIndex
= 0; tIndex
< tFootnoteTextLength
; tIndex
++) {
405 pCurr
= pFootnoteText
+ tIndex
;
406 pCurr
->tInfo
.szText
= NULL
;
407 ulOffset
= ulGetLong(tIndex
* 4, aucBuffer
);
408 NO_DBG_HEX(ulOffset
);
409 ulCharPos
= ulBeginOfFootnotes
+ ulOffset
;
410 NO_DBG_HEX(ulCharPos
);
411 NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos
));
412 pCurr
->ulCharPosStart
= ulCharPos
;
413 ulOffset
= ulGetLong(tIndex
* 4 + 4, aucBuffer
);
414 NO_DBG_HEX(ulOffset
);
415 ulCharPos
= ulBeginOfFootnotes
+ ulOffset
;
416 NO_DBG_HEX(ulCharPos
);
417 NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos
));
418 pCurr
->ulCharPosNext
= ulCharPos
;
419 pCurr
->bUseful
= pCurr
->ulCharPosStart
!= pCurr
->ulCharPosNext
;
421 aucBuffer
= xfree(aucBuffer
);
422 } /* end of vGet6FootnotesText */
425 * Build the list with endnote information for Word 6/7 files
428 vGet6EndnotesInfo(FILE *pFile
, ULONG ulStartBlock
,
429 const ULONG
*aulBBD
, size_t tBBDLen
,
430 const UCHAR
*aucHeader
)
433 ULONG ulFileOffset
, ulBeginOfText
, ulOffset
, ulBeginEndnoteInfo
;
434 size_t tEndnoteInfoLen
;
437 TRACE_MSG("vGet6EndnotesInfo");
439 fail(pFile
== NULL
|| aucHeader
== NULL
);
440 fail(ulStartBlock
> MAX_BLOCKNUMBER
&& ulStartBlock
!= END_OF_CHAIN
);
441 fail(aulBBD
== NULL
);
443 ulBeginOfText
= ulGetLong(0x18, aucHeader
); /* fcMin */
444 NO_DBG_HEX(ulBeginOfText
);
445 ulBeginEndnoteInfo
= ulGetLong(0x1d2, aucHeader
); /* fcPlcfendRef */
446 NO_DBG_HEX(ulBeginEndnoteInfo
);
448 (size_t)ulGetLong(0x1d6, aucHeader
); /* lcbPlcfendRef */
449 NO_DBG_DEC(tEndnoteInfoLen
);
451 if (tEndnoteInfoLen
< 10) {
452 DBG_MSG("No Endnotes in this document");
456 aucBuffer
= xmalloc(tEndnoteInfoLen
);
457 if (!bReadBuffer(pFile
, ulStartBlock
,
458 aulBBD
, tBBDLen
, BIG_BLOCK_SIZE
,
459 aucBuffer
, ulBeginEndnoteInfo
, tEndnoteInfoLen
)) {
460 aucBuffer
= xfree(aucBuffer
);
463 NO_DBG_PRINT_BLOCK(aucBuffer
, tEndnoteInfoLen
);
465 fail(tEndnoteListLength
!= 0);
466 tEndnoteListLength
= (tEndnoteInfoLen
- 4) / 6;
467 fail(tEndnoteListLength
== 0);
469 fail(aulEndnoteList
!= NULL
);
470 aulEndnoteList
= xcalloc(tEndnoteListLength
, sizeof(ULONG
));
472 for (tIndex
= 0; tIndex
< tEndnoteListLength
; tIndex
++) {
473 ulOffset
= ulGetLong(tIndex
* 4, aucBuffer
);
474 NO_DBG_HEX(ulOffset
);
475 ulFileOffset
= ulCharPos2FileOffset(ulBeginOfText
+ ulOffset
);
476 NO_DBG_HEX(ulFileOffset
);
477 aulEndnoteList
[tIndex
] = ulFileOffset
;
479 aucBuffer
= xfree(aucBuffer
);
480 } /* end of vGet6EndnotesInfo */
483 * Build the lists note information for Word 6/7 files
486 vGet6NotesInfo(FILE *pFile
, ULONG ulStartBlock
,
487 const ULONG
*aulBBD
, size_t tBBDLen
,
488 const UCHAR
*aucHeader
)
490 TRACE_MSG("vGet6NotesInfo");
492 vGet6FootnotesInfo(pFile
, ulStartBlock
,
493 aulBBD
, tBBDLen
, aucHeader
);
494 vGet6FootnotesText(pFile
, ulStartBlock
,
495 aulBBD
, tBBDLen
, aucHeader
);
496 vGet6EndnotesInfo(pFile
, ulStartBlock
,
497 aulBBD
, tBBDLen
, aucHeader
);
498 } /* end of vGet6NotesInfo */
501 * Build the list with footnote information for Word 8/9/10 files
504 vGet8FootnotesInfo(FILE *pFile
, const pps_info_type
*pPPS
,
505 const ULONG
*aulBBD
, size_t tBBDLen
,
506 const ULONG
*aulSBD
, size_t tSBDLen
,
507 const UCHAR
*aucHeader
)
509 const ULONG
*aulBlockDepot
;
511 ULONG ulFileOffset
, ulBeginOfText
, ulOffset
, ulBeginFootnoteInfo
;
512 size_t tFootnoteInfoLen
, tBlockDepotLen
, tBlockSize
;
515 TRACE_MSG("vGet8FootnotesInfo");
517 ulBeginOfText
= ulGetLong(0x18, aucHeader
); /* fcMin */
518 NO_DBG_HEX(ulBeginOfText
);
519 ulBeginFootnoteInfo
= ulGetLong(0xaa, aucHeader
); /* fcPlcffndRef */
520 NO_DBG_HEX(ulBeginFootnoteInfo
);
522 (size_t)ulGetLong(0xae, aucHeader
); /* lcbPlcffndRef */
523 NO_DBG_DEC(tFootnoteInfoLen
);
525 if (tFootnoteInfoLen
< 10) {
526 DBG_MSG("No Footnotes in this document");
530 NO_DBG_DEC(pPPS
->tTable
.ulSB
);
531 NO_DBG_HEX(pPPS
->tTable
.ulSize
);
532 if (pPPS
->tTable
.ulSize
== 0) {
533 DBG_MSG("No footnotes information");
537 if (pPPS
->tTable
.ulSize
< MIN_SIZE_FOR_BBD_USE
) {
538 /* Use the Small Block Depot */
539 aulBlockDepot
= aulSBD
;
540 tBlockDepotLen
= tSBDLen
;
541 tBlockSize
= SMALL_BLOCK_SIZE
;
543 /* Use the Big Block Depot */
544 aulBlockDepot
= aulBBD
;
545 tBlockDepotLen
= tBBDLen
;
546 tBlockSize
= BIG_BLOCK_SIZE
;
548 aucBuffer
= xmalloc(tFootnoteInfoLen
);
549 if (!bReadBuffer(pFile
, pPPS
->tTable
.ulSB
,
550 aulBlockDepot
, tBlockDepotLen
, tBlockSize
,
551 aucBuffer
, ulBeginFootnoteInfo
, tFootnoteInfoLen
)) {
552 aucBuffer
= xfree(aucBuffer
);
555 NO_DBG_PRINT_BLOCK(aucBuffer
, tFootnoteInfoLen
);
557 fail(tFootnoteListLength
!= 0);
558 tFootnoteListLength
= (tFootnoteInfoLen
- 4) / 6;
559 fail(tFootnoteListLength
== 0);
561 fail(aulFootnoteList
!= NULL
);
562 aulFootnoteList
= xcalloc(tFootnoteListLength
, sizeof(ULONG
));
564 for (tIndex
= 0; tIndex
< tFootnoteListLength
; tIndex
++) {
565 ulOffset
= ulGetLong(tIndex
* 4, aucBuffer
);
566 NO_DBG_HEX(ulOffset
);
567 ulFileOffset
= ulCharPos2FileOffset(ulBeginOfText
+ ulOffset
);
568 NO_DBG_HEX(ulFileOffset
);
569 aulFootnoteList
[tIndex
] = ulFileOffset
;
571 aucBuffer
= xfree(aucBuffer
);
572 } /* end of vGet8FootnotesInfo */
575 * Build the list with footnote text information for Word 8/9/10 files
578 vGet8FootnotesText(FILE *pFile
, const pps_info_type
*pPPS
,
579 const ULONG
*aulBBD
, size_t tBBDLen
,
580 const ULONG
*aulSBD
, size_t tSBDLen
,
581 const UCHAR
*aucHeader
)
583 footnote_local_type
*pCurr
;
584 const ULONG
*aulBlockDepot
;
586 ULONG ulCharPos
, ulBeginOfFootnotes
, ulOffset
, ulBeginFootnoteText
;
587 size_t tFootnoteTextLen
, tBlockDepotLen
, tBlockSize
;
590 TRACE_MSG("vGet8FootnotesText");
592 ulBeginOfFootnotes
= ulGetLong(0x18, aucHeader
); /* fcMin */
593 ulBeginOfFootnotes
+= ulGetLong(0x4c, aucHeader
); /* ccpText */
594 NO_DBG_HEX(ulBeginOfFootnotes
);
596 ulBeginFootnoteText
= ulGetLong(0xb2, aucHeader
); /* fcPlcffndTxt */
597 NO_DBG_HEX(ulBeginFootnoteText
);
599 (size_t)ulGetLong(0xb6, aucHeader
); /* lcbPlcffndTxt */
600 NO_DBG_DEC(tFootnoteTextLen
);
602 if (tFootnoteTextLen
< 12) {
603 DBG_MSG("No Footnote text in this document");
607 NO_DBG_DEC(pPPS
->tTable
.ulSB
);
608 NO_DBG_HEX(pPPS
->tTable
.ulSize
);
609 if (pPPS
->tTable
.ulSize
== 0) {
610 DBG_MSG("No footnote text information");
614 if (pPPS
->tTable
.ulSize
< MIN_SIZE_FOR_BBD_USE
) {
615 /* Use the Small Block Depot */
616 aulBlockDepot
= aulSBD
;
617 tBlockDepotLen
= tSBDLen
;
618 tBlockSize
= SMALL_BLOCK_SIZE
;
620 /* Use the Big Block Depot */
621 aulBlockDepot
= aulBBD
;
622 tBlockDepotLen
= tBBDLen
;
623 tBlockSize
= BIG_BLOCK_SIZE
;
625 aucBuffer
= xmalloc(tFootnoteTextLen
);
626 if (!bReadBuffer(pFile
, pPPS
->tTable
.ulSB
,
627 aulBlockDepot
, tBlockDepotLen
, tBlockSize
,
628 aucBuffer
, ulBeginFootnoteText
, tFootnoteTextLen
)) {
629 aucBuffer
= xfree(aucBuffer
);
632 NO_DBG_PRINT_BLOCK(aucBuffer
, tFootnoteTextLen
);
634 fail(tFootnoteTextLength
!= 0);
635 tFootnoteTextLength
= tFootnoteTextLen
/ 4 - 2;
636 fail(tFootnoteTextLength
== 0);
638 fail(pFootnoteText
!= NULL
);
639 pFootnoteText
= xcalloc(tFootnoteTextLength
,
640 sizeof(footnote_local_type
));
642 for (tIndex
= 0; tIndex
< tFootnoteTextLength
; tIndex
++) {
643 pCurr
= pFootnoteText
+ tIndex
;
644 pCurr
->tInfo
.szText
= NULL
;
645 ulOffset
= ulGetLong(tIndex
* 4, aucBuffer
);
646 NO_DBG_HEX(ulOffset
);
647 ulCharPos
= ulBeginOfFootnotes
+ ulOffset
;
648 NO_DBG_HEX(ulCharPos
);
649 NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos
));
650 pCurr
->ulCharPosStart
= ulCharPos
;
651 ulOffset
= ulGetLong(tIndex
* 4 + 4, aucBuffer
);
652 NO_DBG_HEX(ulOffset
);
653 ulCharPos
= ulBeginOfFootnotes
+ ulOffset
;
654 NO_DBG_HEX(ulCharPos
);
655 NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos
));
656 pCurr
->ulCharPosNext
= ulCharPos
;
657 pCurr
->bUseful
= pCurr
->ulCharPosStart
!= pCurr
->ulCharPosNext
;
659 aucBuffer
= xfree(aucBuffer
);
660 } /* end of vGet8FootnotesText */
663 * Build the list with endnote information for Word 8/9/10 files
666 vGet8EndnotesInfo(FILE *pFile
, const pps_info_type
*pPPS
,
667 const ULONG
*aulBBD
, size_t tBBDLen
,
668 const ULONG
*aulSBD
, size_t tSBDLen
,
669 const UCHAR
*aucHeader
)
671 const ULONG
*aulBlockDepot
;
673 ULONG ulFileOffset
, ulBeginOfText
, ulOffset
, ulBeginEndnoteInfo
;
674 size_t tEndnoteInfoLen
, tBlockDepotLen
, tBlockSize
;
677 TRACE_MSG("vGet8EndnotesInfo");
679 ulBeginOfText
= ulGetLong(0x18, aucHeader
); /* fcMin */
680 NO_DBG_HEX(ulBeginOfText
);
681 ulBeginEndnoteInfo
= ulGetLong(0x20a, aucHeader
); /* fcPlcfendRef */
682 NO_DBG_HEX(ulBeginEndnoteInfo
);
683 tEndnoteInfoLen
= (size_t)ulGetLong(0x20e, aucHeader
); /* lcbPlcfendRef */
684 NO_DBG_DEC(tEndnoteInfoLen
);
686 if (tEndnoteInfoLen
< 10) {
687 DBG_MSG("No endnotes in this document");
691 NO_DBG_DEC(pPPS
->tTable
.ulSB
);
692 NO_DBG_HEX(pPPS
->tTable
.ulSize
);
693 if (pPPS
->tTable
.ulSize
== 0) {
694 DBG_MSG("No endnotes information");
698 if (pPPS
->tTable
.ulSize
< MIN_SIZE_FOR_BBD_USE
) {
699 /* Use the Small Block Depot */
700 aulBlockDepot
= aulSBD
;
701 tBlockDepotLen
= tSBDLen
;
702 tBlockSize
= SMALL_BLOCK_SIZE
;
704 /* Use the Big Block Depot */
705 aulBlockDepot
= aulBBD
;
706 tBlockDepotLen
= tBBDLen
;
707 tBlockSize
= BIG_BLOCK_SIZE
;
709 aucBuffer
= xmalloc(tEndnoteInfoLen
);
710 if (!bReadBuffer(pFile
, pPPS
->tTable
.ulSB
,
711 aulBlockDepot
, tBlockDepotLen
, tBlockSize
,
712 aucBuffer
, ulBeginEndnoteInfo
, tEndnoteInfoLen
)) {
713 aucBuffer
= xfree(aucBuffer
);
716 NO_DBG_PRINT_BLOCK(aucBuffer
, tEndnoteInfoLen
);
718 fail(tEndnoteListLength
!= 0);
719 tEndnoteListLength
= (tEndnoteInfoLen
- 4) / 6;
720 fail(tEndnoteListLength
== 0);
722 fail(aulEndnoteList
!= NULL
);
723 aulEndnoteList
= xcalloc(tEndnoteListLength
, sizeof(ULONG
));
725 for (tIndex
= 0; tIndex
< tEndnoteListLength
; tIndex
++) {
726 ulOffset
= ulGetLong(tIndex
* 4, aucBuffer
);
727 NO_DBG_HEX(ulOffset
);
728 ulFileOffset
= ulCharPos2FileOffset(ulBeginOfText
+ ulOffset
);
729 NO_DBG_HEX(ulFileOffset
);
730 aulEndnoteList
[tIndex
] = ulFileOffset
;
732 aucBuffer
= xfree(aucBuffer
);
733 } /* end of vGet8EndnotesInfo */
736 * Build the lists with footnote and endnote information for Word 8/9/10 files
739 vGet8NotesInfo(FILE *pFile
, const pps_info_type
*pPPS
,
740 const ULONG
*aulBBD
, size_t tBBDLen
,
741 const ULONG
*aulSBD
, size_t tSBDLen
,
742 const UCHAR
*aucHeader
)
744 TRACE_MSG("vGet8NotesInfo");
746 vGet8FootnotesInfo(pFile
, pPPS
,
747 aulBBD
, tBBDLen
, aulSBD
, tSBDLen
, aucHeader
);
748 vGet8FootnotesText(pFile
, pPPS
,
749 aulBBD
, tBBDLen
, aulSBD
, tSBDLen
, aucHeader
);
750 vGet8EndnotesInfo(pFile
, pPPS
,
751 aulBBD
, tBBDLen
, aulSBD
, tSBDLen
, aucHeader
);
752 } /* end of vGet8NotesInfo */
755 * Build the lists with footnote and endnote information
758 vGetNotesInfo(FILE *pFile
, const pps_info_type
*pPPS
,
759 const ULONG
*aulBBD
, size_t tBBDLen
,
760 const ULONG
*aulSBD
, size_t tSBDLen
,
761 const UCHAR
*aucHeader
, int iWordVersion
)
763 TRACE_MSG("vGetNotesInfo");
766 fail(pPPS
== NULL
&& iWordVersion
>= 6);
767 fail(aulBBD
== NULL
&& tBBDLen
!= 0);
768 fail(aulSBD
== NULL
&& tSBDLen
!= 0);
769 fail(aucHeader
== NULL
);
771 switch (iWordVersion
) {
773 vGet0NotesInfo(pFile
, aucHeader
);
777 vGet2NotesInfo(pFile
, aucHeader
);
784 vGet6NotesInfo(pFile
, pPPS
->tWordDocument
.ulSB
,
785 aulBBD
, tBBDLen
, aucHeader
);
788 vGet8NotesInfo(pFile
, pPPS
,
789 aulBBD
, tBBDLen
, aulSBD
, tSBDLen
, aucHeader
);
792 werr(0, "Sorry, no notes information");
795 } /* end of vGetNotesInfo */
798 * vPrepareFootnoteText - prepare the footnote text
801 vPrepareFootnoteText(FILE *pFile
)
803 footnote_local_type
*pCurr
;
807 fail(pFootnoteText
== NULL
&& tFootnoteTextLength
!= 0);
809 if (pFootnoteText
== NULL
|| tFootnoteTextLength
== 0) {
814 /* Fill text and useful-ness */
815 for (tFootnote
= 0; tFootnote
< tFootnoteTextLength
; tFootnote
++) {
816 pCurr
= pFootnoteText
+ tFootnote
;
817 pCurr
->bUseful
= pCurr
->ulCharPosStart
!= pCurr
->ulCharPosNext
;
818 if (pCurr
->bUseful
) {
819 pCurr
->tInfo
.szText
= szFootnoteDecryptor(pFile
,
820 pCurr
->ulCharPosStart
,
821 pCurr
->ulCharPosNext
);
823 pCurr
->tInfo
.szText
= NULL
;
826 } /* end of vPrepareFootnoteText */
829 * szGetFootnootText - get the text of the spefified footnote
832 szGetFootnootText(UINT uiFootnoteIndex
)
834 if ((size_t)uiFootnoteIndex
>= tFootnoteTextLength
) {
837 return pFootnoteText
[uiFootnoteIndex
].tInfo
.szText
;
838 } /* end of szGetFootnootText */
841 * Get the notetype of the note at the given fileoffset
844 eGetNotetype(ULONG ulFileOffset
)
848 TRACE_MSG("eGetNotetype");
850 fail(aulFootnoteList
== NULL
&& tFootnoteListLength
!= 0);
851 fail(aulEndnoteList
== NULL
&& tEndnoteListLength
!= 0);
853 /* Go for the easy answers first */
854 if (tFootnoteListLength
== 0 && tEndnoteListLength
== 0) {
855 return notetype_is_unknown
;
857 if (tEndnoteListLength
== 0) {
858 return notetype_is_footnote
;
860 if (tFootnoteListLength
== 0) {
861 return notetype_is_endnote
;
863 /* No easy answer, so we search */
864 for (tIndex
= 0; tIndex
< tFootnoteListLength
; tIndex
++) {
865 if (aulFootnoteList
[tIndex
] == ulFileOffset
) {
866 return notetype_is_footnote
;
869 for (tIndex
= 0; tIndex
< tEndnoteListLength
; tIndex
++) {
870 if (aulEndnoteList
[tIndex
] == ulFileOffset
) {
871 return notetype_is_endnote
;
875 return notetype_is_unknown
;
876 } /* end of eGetNotetype */