examples/PIPS/antiword/src/notes.c

00001 /*
00002  * notes.c
00003  * Copyright (C) 1998-2005 A.J. van Os; Released under GNU GPL
00004  *
00005  * Description:
00006  * Functions to tell the difference between footnotes and endnotes
00007  */
00008 
00009 #include "antiword.h"
00010 
00011 /*
00012  * Private structures to hide the way the information
00013  * is stored from the rest of the program
00014  */
00015 typedef struct footnote_local_tag {
00016         footnote_block_type     tInfo;
00017         ULONG                   ulCharPosStart;
00018         ULONG                   ulCharPosNext;
00019         BOOL                    bUseful;
00020 } footnote_local_type;
00021 
00022 /* Variables needed to write the Footnote and Endnote information */
00023 static ULONG    *aulFootnoteList = NULL;
00024 static size_t   tFootnoteListLength = 0;
00025 static ULONG    *aulEndnoteList = NULL;
00026 static size_t   tEndnoteListLength = 0;
00027 /* Variables needed to write the Footnote Text */
00028 static footnote_local_type      *pFootnoteText = NULL;
00029 static size_t                   tFootnoteTextLength = 0;
00030 
00031 
00032 /*
00033  * Destroy the lists with footnote and endnote information
00034  */
00035 void
00036 vDestroyNotesInfoLists(void)
00037 {
00038         footnote_local_type     *pRecord;
00039         size_t                  tFootnote;
00040 
00041         TRACE_MSG("vDestroyNotesInfoLists");
00042 
00043         /* Free the lists and reset all control variables */
00044         aulEndnoteList = xfree(aulEndnoteList);
00045         aulFootnoteList = xfree(aulFootnoteList);
00046         tEndnoteListLength = 0;
00047         tFootnoteListLength = 0;
00048         for (tFootnote = 0; tFootnote < tFootnoteTextLength; tFootnote++) {
00049                 pRecord = pFootnoteText + tFootnote;
00050                 pRecord->tInfo.szText = xfree(pRecord->tInfo.szText);
00051         }
00052         pFootnoteText = xfree(pFootnoteText);
00053         tFootnoteTextLength = 0;
00054 } /* end of vDestroyNotesInfoLists */
00055 
00056 /*
00057  * Build the list with footnote information for Word for DOS files
00058  */
00059 static void
00060 vGet0FootnotesInfoAndText(FILE *pFile, const UCHAR *aucHeader)
00061 {
00062         footnote_local_type     *pCurr;
00063         UCHAR   *aucBuffer;
00064         ULONG   ulFileOffset, ulBeginOfText, ulOffset, ulBeginFootnoteInfo;
00065         ULONG   ulCharPos, ulBeginNextBlock;
00066         size_t  tFootnotes, tFootnoteInfoLen;
00067         size_t  tIndex;
00068         UCHAR   aucTmp[2];
00069 
00070         TRACE_MSG("vGet0FootnotesInfoAndText");
00071 
00072         fail(pFile == NULL || aucHeader == NULL);
00073 
00074         ulBeginOfText = 128;
00075         NO_DBG_HEX(ulBeginOfText);
00076         ulBeginFootnoteInfo =  128 * (ULONG)usGetWord(0x14, aucHeader);
00077         DBG_HEX(ulBeginFootnoteInfo);
00078         ulBeginNextBlock = 128 * (ULONG)usGetWord(0x16, aucHeader);
00079         DBG_HEX(ulBeginNextBlock);
00080 
00081         if (ulBeginFootnoteInfo == ulBeginNextBlock) {
00082                 DBG_MSG("No Footnotes in this document");
00083                 return;
00084         }
00085 
00086         /* Read the the number of footnotes + 1 */
00087         if (!bReadBytes(aucTmp, 2, ulBeginFootnoteInfo, pFile)) {
00088                 return;
00089         }
00090         tFootnotes = (size_t)usGetWord(0, aucTmp);
00091         if (tFootnotes < 2) {
00092                 DBG_MSG("No Footnotes in this document (2)");
00093         }
00094         DBG_DEC(tFootnotes);
00095         tFootnoteInfoLen =  8 * tFootnotes;
00096 
00097         aucBuffer = xmalloc(tFootnoteInfoLen);
00098         if (!bReadBytes(aucBuffer,
00099                         tFootnoteInfoLen, ulBeginFootnoteInfo + 4, pFile)) {
00100                 aucBuffer = xfree(aucBuffer);
00101                 return;
00102         }
00103         DBG_PRINT_BLOCK(aucBuffer, tFootnoteInfoLen);
00104 
00105         /* Get footnote information */
00106         fail(tFootnoteListLength != 0);
00107         tFootnoteListLength = tFootnotes - 1;
00108         fail(tFootnoteListLength == 0);
00109 
00110         fail(aulFootnoteList != NULL);
00111         aulFootnoteList = xcalloc(tFootnoteListLength, sizeof(ULONG));
00112 
00113         for (tIndex = 0; tIndex < tFootnoteListLength; tIndex++) {
00114                 ulOffset = ulGetLong(tIndex * 8, aucBuffer);
00115                 DBG_HEX(ulOffset);
00116                 ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset);
00117                 DBG_HEX(ulFileOffset);
00118                 aulFootnoteList[tIndex] = ulFileOffset;
00119         }
00120 
00121         /* Get footnote text */
00122         fail(tFootnoteTextLength != 0);
00123         tFootnoteTextLength = tFootnotes - 1;
00124         fail(tFootnoteTextLength == 0);
00125 
00126         fail(pFootnoteText != NULL);
00127         pFootnoteText = xcalloc(tFootnoteTextLength,
00128                                 sizeof(footnote_local_type));
00129 
00130         for (tIndex = 0; tIndex < tFootnoteTextLength; tIndex++) {
00131                 pCurr = pFootnoteText + tIndex;
00132                 pCurr->tInfo.szText = NULL;
00133                 ulOffset = ulGetLong(tIndex * 8 + 4, aucBuffer);
00134                 DBG_HEX(ulOffset);
00135                 ulCharPos = ulBeginOfText + ulOffset;
00136                 DBG_HEX(ulCharPos);
00137                 DBG_HEX(ulCharPos2FileOffset(ulCharPos));
00138                 pCurr->ulCharPosStart = ulCharPos;
00139                 ulOffset = ulGetLong((tIndex + 1) * 8 + 4, aucBuffer);
00140                 DBG_HEX(ulOffset);
00141                 ulCharPos = ulBeginOfText + ulOffset;
00142                 DBG_HEX(ulCharPos);
00143                 DBG_HEX(ulCharPos2FileOffset(ulCharPos));
00144                 pCurr->ulCharPosNext = ulCharPos;
00145                 pCurr->bUseful = pCurr->ulCharPosStart != pCurr->ulCharPosNext;
00146         }
00147         aucBuffer = xfree(aucBuffer);
00148 } /* end of vGet0FootnotesInfoAndText */
00149 
00150 /*
00151  * Build the lists note information for Word for DOS files
00152  */
00153 static void
00154 vGet0NotesInfo(FILE *pFile, const UCHAR *aucHeader)
00155 {
00156         TRACE_MSG("vGet0NotesInfo");
00157 
00158         vGet0FootnotesInfoAndText(pFile, aucHeader);
00159         /* There are no endnotes in a Word for DOS file */
00160 } /* end of vGet0NotesInfo */
00161 
00162 /*
00163  * Build the list with footnote information for WinWord 1/2 files
00164  */
00165 static void
00166 vGet2FootnotesInfo(FILE *pFile, const UCHAR *aucHeader)
00167 {
00168         UCHAR   *aucBuffer;
00169         ULONG   ulFileOffset, ulBeginOfText, ulOffset, ulBeginFootnoteInfo;
00170         size_t  tFootnoteInfoLen;
00171         size_t  tIndex;
00172 
00173         TRACE_MSG("vGet2FootnotesInfo");
00174 
00175         fail(pFile == NULL || aucHeader == NULL);
00176 
00177         ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */
00178         NO_DBG_HEX(ulBeginOfText);
00179         ulBeginFootnoteInfo = ulGetLong(0x64, aucHeader); /* fcPlcffndRef */
00180         NO_DBG_HEX(ulBeginFootnoteInfo);
00181         tFootnoteInfoLen = (size_t)usGetWord(0x68, aucHeader); /* cbPlcffndRef */
00182         NO_DBG_DEC(tFootnoteInfoLen);
00183 
00184         if (tFootnoteInfoLen < 10) {
00185                 DBG_MSG("No Footnotes in this document");
00186                 return;
00187         }
00188 
00189         aucBuffer = xmalloc(tFootnoteInfoLen);
00190         if (!bReadBytes(aucBuffer,
00191                         tFootnoteInfoLen, ulBeginFootnoteInfo, pFile)) {
00192                 aucBuffer = xfree(aucBuffer);
00193                 return;
00194         }
00195         NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteInfoLen);
00196 
00197         fail(tFootnoteListLength != 0);
00198         tFootnoteListLength = (tFootnoteInfoLen - 4) / 6;
00199         fail(tFootnoteListLength == 0);
00200 
00201         fail(aulFootnoteList != NULL);
00202         aulFootnoteList = xcalloc(tFootnoteListLength, sizeof(ULONG));
00203 
00204         for (tIndex = 0; tIndex < tFootnoteListLength; tIndex++) {
00205                 ulOffset = ulGetLong(tIndex * 4, aucBuffer);
00206                 NO_DBG_HEX(ulOffset);
00207                 ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset);
00208                 NO_DBG_HEX(ulFileOffset);
00209                 aulFootnoteList[tIndex] = ulFileOffset;
00210         }
00211         aucBuffer = xfree(aucBuffer);
00212 } /* end of vGet2FootnotesInfo */
00213 
00214 /*
00215  * Build the list with footnote text information for WinWord 1/2 files
00216  */
00217 static void
00218 vGet2FootnotesText(FILE *pFile, const UCHAR *aucHeader)
00219 {
00220         footnote_local_type     *pCurr;
00221         UCHAR   *aucBuffer;
00222         ULONG   ulCharPos, ulBeginOfFootnotes, ulOffset, ulBeginFootnoteText;
00223         size_t  tFootnoteTextLen;
00224         size_t  tIndex;
00225 
00226         TRACE_MSG("vGet2FootnotesText");
00227 
00228         fail(pFile == NULL || aucHeader == NULL);
00229 
00230         ulBeginOfFootnotes = ulGetLong(0x18, aucHeader); /* fcMin */
00231         ulBeginOfFootnotes += ulGetLong(0x34, aucHeader); /* ccpText */
00232         NO_DBG_HEX(ulBeginOfFootnotes);
00233 
00234         ulBeginFootnoteText = ulGetLong(0x6a, aucHeader); /* fcPlcffndTxt */
00235         NO_DBG_HEX(ulBeginFootnoteText);
00236         tFootnoteTextLen =
00237                 (size_t)usGetWord(0x6e, aucHeader); /* cbPlcffndTxt */
00238         NO_DBG_DEC(tFootnoteTextLen);
00239 
00240         if (tFootnoteTextLen < 12) {
00241                 DBG_MSG("No Footnote text in this document");
00242                 return;
00243         }
00244 
00245         aucBuffer = xmalloc(tFootnoteTextLen);
00246         if (!bReadBytes(aucBuffer,
00247                         tFootnoteTextLen, ulBeginFootnoteText, pFile)) {
00248                 aucBuffer = xfree(aucBuffer);
00249                 return;
00250         }
00251         NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteTextLen);
00252 
00253         fail(tFootnoteTextLength != 0);
00254         tFootnoteTextLength = tFootnoteTextLen / 4 - 2;
00255         fail(tFootnoteTextLength == 0);
00256 
00257         fail(pFootnoteText != NULL);
00258         pFootnoteText = xcalloc(tFootnoteTextLength,
00259                                 sizeof(footnote_local_type));
00260 
00261         for (tIndex = 0; tIndex < tFootnoteTextLength; tIndex++) {
00262                 pCurr = pFootnoteText + tIndex;
00263                 pCurr->tInfo.szText = NULL;
00264                 ulOffset = ulGetLong(tIndex * 4, aucBuffer);
00265                 NO_DBG_HEX(ulOffset);
00266                 ulCharPos = ulBeginOfFootnotes + ulOffset;
00267                 NO_DBG_HEX(ulCharPos);
00268                 NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos));
00269                 pCurr->ulCharPosStart = ulCharPos;
00270                 ulOffset = ulGetLong(tIndex * 4 + 4, aucBuffer);
00271                 NO_DBG_HEX(ulOffset);
00272                 ulCharPos = ulBeginOfFootnotes + ulOffset;
00273                 NO_DBG_HEX(ulCharPos);
00274                 NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos));
00275                 pCurr->ulCharPosNext = ulCharPos;
00276                 pCurr->bUseful = pCurr->ulCharPosStart != pCurr->ulCharPosNext;
00277         }
00278         aucBuffer = xfree(aucBuffer);
00279 } /* end of vGet2FootnotesText */
00280 
00281 /*
00282  * Build the lists note information for WinWord 1/2 files
00283  */
00284 static void
00285 vGet2NotesInfo(FILE *pFile, const UCHAR *aucHeader)
00286 {
00287         TRACE_MSG("vGet2NotesInfo");
00288 
00289         vGet2FootnotesInfo(pFile, aucHeader);
00290         vGet2FootnotesText(pFile, aucHeader);
00291         /* There are no endnotes in a WinWord 1/2 file */
00292 } /* end of vGet2NotesInfo */
00293 
00294 /*
00295  * Build the list with footnote information for Word 6/7 files
00296  */
00297 static void
00298 vGet6FootnotesInfo(FILE *pFile, ULONG ulStartBlock,
00299         const ULONG *aulBBD, size_t tBBDLen,
00300         const UCHAR *aucHeader)
00301 {
00302         UCHAR   *aucBuffer;
00303         ULONG   ulFileOffset, ulBeginOfText, ulOffset, ulBeginFootnoteInfo;
00304         size_t  tFootnoteInfoLen;
00305         size_t  tIndex;
00306 
00307         TRACE_MSG("vGet6FootnotesInfo");
00308 
00309         fail(pFile == NULL || aucHeader == NULL);
00310         fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN);
00311         fail(aulBBD == NULL);
00312 
00313         ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */
00314         NO_DBG_HEX(ulBeginOfText);
00315         ulBeginFootnoteInfo = ulGetLong(0x68, aucHeader); /* fcPlcffndRef */
00316         NO_DBG_HEX(ulBeginFootnoteInfo);
00317         tFootnoteInfoLen =
00318                 (size_t)ulGetLong(0x6c, aucHeader); /* lcbPlcffndRef */
00319         NO_DBG_DEC(tFootnoteInfoLen);
00320 
00321         if (tFootnoteInfoLen < 10) {
00322                 DBG_MSG("No Footnotes in this document");
00323                 return;
00324         }
00325 
00326         aucBuffer = xmalloc(tFootnoteInfoLen);
00327         if (!bReadBuffer(pFile, ulStartBlock,
00328                         aulBBD, tBBDLen, BIG_BLOCK_SIZE,
00329                         aucBuffer, ulBeginFootnoteInfo, tFootnoteInfoLen)) {
00330                 aucBuffer = xfree(aucBuffer);
00331                 return;
00332         }
00333         NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteInfoLen);
00334 
00335         fail(tFootnoteListLength != 0);
00336         tFootnoteListLength = (tFootnoteInfoLen - 4) / 6;
00337         fail(tFootnoteListLength == 0);
00338 
00339         fail(aulFootnoteList != NULL);
00340         aulFootnoteList = xcalloc(tFootnoteListLength, sizeof(ULONG));
00341 
00342         for (tIndex = 0; tIndex < tFootnoteListLength; tIndex++) {
00343                 ulOffset = ulGetLong(tIndex * 4, aucBuffer);
00344                 NO_DBG_HEX(ulOffset);
00345                 ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset);
00346                 NO_DBG_HEX(ulFileOffset);
00347                 aulFootnoteList[tIndex] = ulFileOffset;
00348         }
00349         aucBuffer = xfree(aucBuffer);
00350 } /* end of vGet6FootnotesInfo */
00351 
00352 /*
00353  * Build the list with footnote text information for Word 6/7 files
00354  */
00355 static void
00356 vGet6FootnotesText(FILE *pFile, ULONG ulStartBlock,
00357         const ULONG *aulBBD, size_t tBBDLen,
00358         const UCHAR *aucHeader)
00359 {
00360         footnote_local_type     *pCurr;
00361         UCHAR   *aucBuffer;
00362         ULONG   ulCharPos, ulBeginOfFootnotes, ulOffset, ulBeginFootnoteText;
00363         size_t  tFootnoteTextLen;
00364         size_t  tIndex;
00365 
00366         TRACE_MSG("vGet6FootnotesText");
00367 
00368         fail(pFile == NULL || aucHeader == NULL);
00369         fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN);
00370         fail(aulBBD == NULL);
00371 
00372         ulBeginOfFootnotes = ulGetLong(0x18, aucHeader); /* fcMin */
00373         ulBeginOfFootnotes += ulGetLong(0x34, aucHeader); /* ccpText */
00374         NO_DBG_HEX(ulBeginOfFootnotes);
00375 
00376         ulBeginFootnoteText = ulGetLong(0x70, aucHeader); /* fcPlcffndTxt */
00377         NO_DBG_HEX(ulBeginFootnoteText);
00378         tFootnoteTextLen =
00379                 (size_t)ulGetLong(0x74, aucHeader); /* lcbPlcffndTxt */
00380         NO_DBG_DEC(tFootnoteTextLen);
00381 
00382         if (tFootnoteTextLen < 12) {
00383                 DBG_MSG("No Footnote text in this document");
00384                 return;
00385         }
00386 
00387         aucBuffer = xmalloc(tFootnoteTextLen);
00388         if (!bReadBuffer(pFile, ulStartBlock,
00389                         aulBBD, tBBDLen, BIG_BLOCK_SIZE,
00390                         aucBuffer, ulBeginFootnoteText, tFootnoteTextLen)) {
00391                 aucBuffer = xfree(aucBuffer);
00392                 return;
00393         }
00394         NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteTextLen);
00395 
00396         fail(tFootnoteTextLength != 0);
00397         tFootnoteTextLength = tFootnoteTextLen / 4 - 2;
00398         fail(tFootnoteTextLength == 0);
00399 
00400         fail(pFootnoteText != NULL);
00401         pFootnoteText = xcalloc(tFootnoteTextLength,
00402                                 sizeof(footnote_local_type));
00403 
00404         for (tIndex = 0; tIndex < tFootnoteTextLength; tIndex++) {
00405                 pCurr = pFootnoteText + tIndex;
00406                 pCurr->tInfo.szText = NULL;
00407                 ulOffset = ulGetLong(tIndex * 4, aucBuffer);
00408                 NO_DBG_HEX(ulOffset);
00409                 ulCharPos = ulBeginOfFootnotes + ulOffset;
00410                 NO_DBG_HEX(ulCharPos);
00411                 NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos));
00412                 pCurr->ulCharPosStart = ulCharPos;
00413                 ulOffset = ulGetLong(tIndex * 4 + 4, aucBuffer);
00414                 NO_DBG_HEX(ulOffset);
00415                 ulCharPos = ulBeginOfFootnotes + ulOffset;
00416                 NO_DBG_HEX(ulCharPos);
00417                 NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos));
00418                 pCurr->ulCharPosNext = ulCharPos;
00419                 pCurr->bUseful = pCurr->ulCharPosStart != pCurr->ulCharPosNext;
00420         }
00421         aucBuffer = xfree(aucBuffer);
00422 } /* end of vGet6FootnotesText */
00423 
00424 /*
00425  * Build the list with endnote information for Word 6/7 files
00426  */
00427 static void
00428 vGet6EndnotesInfo(FILE *pFile, ULONG ulStartBlock,
00429         const ULONG *aulBBD, size_t tBBDLen,
00430         const UCHAR *aucHeader)
00431 {
00432         UCHAR   *aucBuffer;
00433         ULONG   ulFileOffset, ulBeginOfText, ulOffset, ulBeginEndnoteInfo;
00434         size_t  tEndnoteInfoLen;
00435         size_t  tIndex;
00436 
00437         TRACE_MSG("vGet6EndnotesInfo");
00438 
00439         fail(pFile == NULL || aucHeader == NULL);
00440         fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN);
00441         fail(aulBBD == NULL);
00442 
00443         ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */
00444         NO_DBG_HEX(ulBeginOfText);
00445         ulBeginEndnoteInfo = ulGetLong(0x1d2, aucHeader); /* fcPlcfendRef */
00446         NO_DBG_HEX(ulBeginEndnoteInfo);
00447         tEndnoteInfoLen =
00448                 (size_t)ulGetLong(0x1d6, aucHeader); /* lcbPlcfendRef */
00449         NO_DBG_DEC(tEndnoteInfoLen);
00450 
00451         if (tEndnoteInfoLen < 10) {
00452                 DBG_MSG("No Endnotes in this document");
00453                 return;
00454         }
00455 
00456         aucBuffer = xmalloc(tEndnoteInfoLen);
00457         if (!bReadBuffer(pFile, ulStartBlock,
00458                         aulBBD, tBBDLen, BIG_BLOCK_SIZE,
00459                         aucBuffer, ulBeginEndnoteInfo, tEndnoteInfoLen)) {
00460                 aucBuffer = xfree(aucBuffer);
00461                 return;
00462         }
00463         NO_DBG_PRINT_BLOCK(aucBuffer, tEndnoteInfoLen);
00464 
00465         fail(tEndnoteListLength != 0);
00466         tEndnoteListLength = (tEndnoteInfoLen - 4) / 6;
00467         fail(tEndnoteListLength == 0);
00468 
00469         fail(aulEndnoteList != NULL);
00470         aulEndnoteList = xcalloc(tEndnoteListLength, sizeof(ULONG));
00471 
00472         for (tIndex = 0; tIndex < tEndnoteListLength; tIndex++) {
00473                 ulOffset = ulGetLong(tIndex * 4, aucBuffer);
00474                 NO_DBG_HEX(ulOffset);
00475                 ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset);
00476                 NO_DBG_HEX(ulFileOffset);
00477                 aulEndnoteList[tIndex] = ulFileOffset;
00478         }
00479         aucBuffer = xfree(aucBuffer);
00480 } /* end of vGet6EndnotesInfo */
00481 
00482 /*
00483  * Build the lists note information for Word 6/7 files
00484  */
00485 static void
00486 vGet6NotesInfo(FILE *pFile, ULONG ulStartBlock,
00487         const ULONG *aulBBD, size_t tBBDLen,
00488         const UCHAR *aucHeader)
00489 {
00490         TRACE_MSG("vGet6NotesInfo");
00491 
00492         vGet6FootnotesInfo(pFile, ulStartBlock,
00493                         aulBBD, tBBDLen, aucHeader);
00494         vGet6FootnotesText(pFile, ulStartBlock,
00495                         aulBBD, tBBDLen, aucHeader);
00496         vGet6EndnotesInfo(pFile, ulStartBlock,
00497                         aulBBD, tBBDLen, aucHeader);
00498 } /* end of vGet6NotesInfo */
00499 
00500 /*
00501  * Build the list with footnote information for Word 8/9/10 files
00502  */
00503 static void
00504 vGet8FootnotesInfo(FILE *pFile, const pps_info_type *pPPS,
00505         const ULONG *aulBBD, size_t tBBDLen,
00506         const ULONG *aulSBD, size_t tSBDLen,
00507         const UCHAR *aucHeader)
00508 {
00509         const ULONG     *aulBlockDepot;
00510         UCHAR   *aucBuffer;
00511         ULONG   ulFileOffset, ulBeginOfText, ulOffset, ulBeginFootnoteInfo;
00512         size_t  tFootnoteInfoLen, tBlockDepotLen, tBlockSize;
00513         size_t  tIndex;
00514 
00515         TRACE_MSG("vGet8FootnotesInfo");
00516 
00517         ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */
00518         NO_DBG_HEX(ulBeginOfText);
00519         ulBeginFootnoteInfo = ulGetLong(0xaa, aucHeader); /* fcPlcffndRef */
00520         NO_DBG_HEX(ulBeginFootnoteInfo);
00521         tFootnoteInfoLen =
00522                 (size_t)ulGetLong(0xae, aucHeader); /* lcbPlcffndRef */
00523         NO_DBG_DEC(tFootnoteInfoLen);
00524 
00525         if (tFootnoteInfoLen < 10) {
00526                 DBG_MSG("No Footnotes in this document");
00527                 return;
00528         }
00529 
00530         NO_DBG_DEC(pPPS->tTable.ulSB);
00531         NO_DBG_HEX(pPPS->tTable.ulSize);
00532         if (pPPS->tTable.ulSize == 0) {
00533                 DBG_MSG("No footnotes information");
00534                 return;
00535         }
00536 
00537         if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) {
00538                 /* Use the Small Block Depot */
00539                 aulBlockDepot = aulSBD;
00540                 tBlockDepotLen = tSBDLen;
00541                 tBlockSize = SMALL_BLOCK_SIZE;
00542         } else {
00543                 /* Use the Big Block Depot */
00544                 aulBlockDepot = aulBBD;
00545                 tBlockDepotLen = tBBDLen;
00546                 tBlockSize = BIG_BLOCK_SIZE;
00547         }
00548         aucBuffer = xmalloc(tFootnoteInfoLen);
00549         if (!bReadBuffer(pFile, pPPS->tTable.ulSB,
00550                         aulBlockDepot, tBlockDepotLen, tBlockSize,
00551                         aucBuffer, ulBeginFootnoteInfo, tFootnoteInfoLen)) {
00552                 aucBuffer = xfree(aucBuffer);
00553                 return;
00554         }
00555         NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteInfoLen);
00556 
00557         fail(tFootnoteListLength != 0);
00558         tFootnoteListLength = (tFootnoteInfoLen - 4) / 6;
00559         fail(tFootnoteListLength == 0);
00560 
00561         fail(aulFootnoteList != NULL);
00562         aulFootnoteList = xcalloc(tFootnoteListLength, sizeof(ULONG));
00563 
00564         for (tIndex = 0; tIndex < tFootnoteListLength; tIndex++) {
00565                 ulOffset = ulGetLong(tIndex * 4, aucBuffer);
00566                 NO_DBG_HEX(ulOffset);
00567                 ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset);
00568                 NO_DBG_HEX(ulFileOffset);
00569                 aulFootnoteList[tIndex] = ulFileOffset;
00570         }
00571         aucBuffer = xfree(aucBuffer);
00572 } /* end of vGet8FootnotesInfo */
00573 
00574 /*
00575  * Build the list with footnote text information for Word 8/9/10 files
00576  */
00577 static void
00578 vGet8FootnotesText(FILE *pFile, const pps_info_type *pPPS,
00579         const ULONG *aulBBD, size_t tBBDLen,
00580         const ULONG *aulSBD, size_t tSBDLen,
00581         const UCHAR *aucHeader)
00582 {
00583         footnote_local_type     *pCurr;
00584         const ULONG     *aulBlockDepot;
00585         UCHAR   *aucBuffer;
00586         ULONG   ulCharPos, ulBeginOfFootnotes, ulOffset, ulBeginFootnoteText;
00587         size_t  tFootnoteTextLen, tBlockDepotLen, tBlockSize;
00588         size_t  tIndex;
00589 
00590         TRACE_MSG("vGet8FootnotesText");
00591 
00592         ulBeginOfFootnotes = ulGetLong(0x18, aucHeader); /* fcMin */
00593         ulBeginOfFootnotes += ulGetLong(0x4c, aucHeader); /* ccpText */
00594         NO_DBG_HEX(ulBeginOfFootnotes);
00595 
00596         ulBeginFootnoteText = ulGetLong(0xb2, aucHeader); /* fcPlcffndTxt */
00597         NO_DBG_HEX(ulBeginFootnoteText);
00598         tFootnoteTextLen =
00599                 (size_t)ulGetLong(0xb6, aucHeader); /* lcbPlcffndTxt */
00600         NO_DBG_DEC(tFootnoteTextLen);
00601 
00602         if (tFootnoteTextLen < 12) {
00603                 DBG_MSG("No Footnote text in this document");
00604                 return;
00605         }
00606 
00607         NO_DBG_DEC(pPPS->tTable.ulSB);
00608         NO_DBG_HEX(pPPS->tTable.ulSize);
00609         if (pPPS->tTable.ulSize == 0) {
00610                 DBG_MSG("No footnote text information");
00611                 return;
00612         }
00613 
00614         if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) {
00615                 /* Use the Small Block Depot */
00616                 aulBlockDepot = aulSBD;
00617                 tBlockDepotLen = tSBDLen;
00618                 tBlockSize = SMALL_BLOCK_SIZE;
00619         } else {
00620                 /* Use the Big Block Depot */
00621                 aulBlockDepot = aulBBD;
00622                 tBlockDepotLen = tBBDLen;
00623                 tBlockSize = BIG_BLOCK_SIZE;
00624         }
00625         aucBuffer = xmalloc(tFootnoteTextLen);
00626         if (!bReadBuffer(pFile, pPPS->tTable.ulSB,
00627                         aulBlockDepot, tBlockDepotLen, tBlockSize,
00628                         aucBuffer, ulBeginFootnoteText, tFootnoteTextLen)) {
00629                 aucBuffer = xfree(aucBuffer);
00630                 return;
00631         }
00632         NO_DBG_PRINT_BLOCK(aucBuffer, tFootnoteTextLen);
00633 
00634         fail(tFootnoteTextLength != 0);
00635         tFootnoteTextLength = tFootnoteTextLen / 4 - 2;
00636         fail(tFootnoteTextLength == 0);
00637 
00638         fail(pFootnoteText != NULL);
00639         pFootnoteText = xcalloc(tFootnoteTextLength,
00640                                 sizeof(footnote_local_type));
00641 
00642         for (tIndex = 0; tIndex < tFootnoteTextLength; tIndex++) {
00643                 pCurr = pFootnoteText + tIndex;
00644                 pCurr->tInfo.szText = NULL;
00645                 ulOffset = ulGetLong(tIndex * 4, aucBuffer);
00646                 NO_DBG_HEX(ulOffset);
00647                 ulCharPos = ulBeginOfFootnotes + ulOffset;
00648                 NO_DBG_HEX(ulCharPos);
00649                 NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos));
00650                 pCurr->ulCharPosStart = ulCharPos;
00651                 ulOffset = ulGetLong(tIndex * 4 + 4, aucBuffer);
00652                 NO_DBG_HEX(ulOffset);
00653                 ulCharPos = ulBeginOfFootnotes + ulOffset;
00654                 NO_DBG_HEX(ulCharPos);
00655                 NO_DBG_HEX(ulCharPos2FileOffset(ulCharPos));
00656                 pCurr->ulCharPosNext = ulCharPos;
00657                 pCurr->bUseful = pCurr->ulCharPosStart != pCurr->ulCharPosNext;
00658         }
00659         aucBuffer = xfree(aucBuffer);
00660 } /* end of vGet8FootnotesText */
00661 
00662 /*
00663  * Build the list with endnote information for Word 8/9/10 files
00664  */
00665 static void
00666 vGet8EndnotesInfo(FILE *pFile, const pps_info_type *pPPS,
00667         const ULONG *aulBBD, size_t tBBDLen,
00668         const ULONG *aulSBD, size_t tSBDLen,
00669         const UCHAR *aucHeader)
00670 {
00671         const ULONG     *aulBlockDepot;
00672         UCHAR   *aucBuffer;
00673         ULONG   ulFileOffset, ulBeginOfText, ulOffset, ulBeginEndnoteInfo;
00674         size_t  tEndnoteInfoLen, tBlockDepotLen, tBlockSize;
00675         size_t  tIndex;
00676 
00677         TRACE_MSG("vGet8EndnotesInfo");
00678 
00679         ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */
00680         NO_DBG_HEX(ulBeginOfText);
00681         ulBeginEndnoteInfo = ulGetLong(0x20a, aucHeader); /* fcPlcfendRef */
00682         NO_DBG_HEX(ulBeginEndnoteInfo);
00683         tEndnoteInfoLen = (size_t)ulGetLong(0x20e, aucHeader); /* lcbPlcfendRef */
00684         NO_DBG_DEC(tEndnoteInfoLen);
00685 
00686         if (tEndnoteInfoLen < 10) {
00687                 DBG_MSG("No endnotes in this document");
00688                 return;
00689         }
00690 
00691         NO_DBG_DEC(pPPS->tTable.ulSB);
00692         NO_DBG_HEX(pPPS->tTable.ulSize);
00693         if (pPPS->tTable.ulSize == 0) {
00694                 DBG_MSG("No endnotes information");
00695                 return;
00696         }
00697 
00698         if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) {
00699                 /* Use the Small Block Depot */
00700                 aulBlockDepot = aulSBD;
00701                 tBlockDepotLen = tSBDLen;
00702                 tBlockSize = SMALL_BLOCK_SIZE;
00703         } else {
00704                 /* Use the Big Block Depot */
00705                 aulBlockDepot = aulBBD;
00706                 tBlockDepotLen = tBBDLen;
00707                 tBlockSize = BIG_BLOCK_SIZE;
00708         }
00709         aucBuffer = xmalloc(tEndnoteInfoLen);
00710         if (!bReadBuffer(pFile, pPPS->tTable.ulSB,
00711                         aulBlockDepot, tBlockDepotLen, tBlockSize,
00712                         aucBuffer, ulBeginEndnoteInfo, tEndnoteInfoLen)) {
00713                 aucBuffer = xfree(aucBuffer);
00714                 return;
00715         }
00716         NO_DBG_PRINT_BLOCK(aucBuffer, tEndnoteInfoLen);
00717 
00718         fail(tEndnoteListLength != 0);
00719         tEndnoteListLength = (tEndnoteInfoLen - 4) / 6;
00720         fail(tEndnoteListLength == 0);
00721 
00722         fail(aulEndnoteList != NULL);
00723         aulEndnoteList = xcalloc(tEndnoteListLength, sizeof(ULONG));
00724 
00725         for (tIndex = 0; tIndex < tEndnoteListLength; tIndex++) {
00726                 ulOffset = ulGetLong(tIndex * 4, aucBuffer);
00727                 NO_DBG_HEX(ulOffset);
00728                 ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset);
00729                 NO_DBG_HEX(ulFileOffset);
00730                 aulEndnoteList[tIndex] = ulFileOffset;
00731         }
00732         aucBuffer = xfree(aucBuffer);
00733 } /* end of vGet8EndnotesInfo */
00734 
00735 /*
00736  * Build the lists with footnote and endnote information for Word 8/9/10 files
00737  */
00738 static void
00739 vGet8NotesInfo(FILE *pFile, const pps_info_type *pPPS,
00740         const ULONG *aulBBD, size_t tBBDLen,
00741         const ULONG *aulSBD, size_t tSBDLen,
00742         const UCHAR *aucHeader)
00743 {
00744         TRACE_MSG("vGet8NotesInfo");
00745 
00746         vGet8FootnotesInfo(pFile, pPPS,
00747                         aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader);
00748         vGet8FootnotesText(pFile, pPPS,
00749                         aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader);
00750         vGet8EndnotesInfo(pFile, pPPS,
00751                         aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader);
00752 } /* end of vGet8NotesInfo */
00753 
00754 /*
00755  * Build the lists with footnote and endnote information
00756  */
00757 void
00758 vGetNotesInfo(FILE *pFile, const pps_info_type *pPPS,
00759         const ULONG *aulBBD, size_t tBBDLen,
00760         const ULONG *aulSBD, size_t tSBDLen,
00761         const UCHAR *aucHeader, int iWordVersion)
00762 {
00763         TRACE_MSG("vGetNotesInfo");
00764 
00765         fail(pFile == NULL);
00766         fail(pPPS == NULL && iWordVersion >= 6);
00767         fail(aulBBD == NULL && tBBDLen != 0);
00768         fail(aulSBD == NULL && tSBDLen != 0);
00769         fail(aucHeader == NULL);
00770 
00771         switch (iWordVersion) {
00772         case 0:
00773                 vGet0NotesInfo(pFile, aucHeader);
00774                 break;
00775         case 1:
00776         case 2:
00777                 vGet2NotesInfo(pFile, aucHeader);
00778                 break;
00779         case 4:
00780         case 5:
00781                 break;
00782         case 6:
00783         case 7:
00784                 vGet6NotesInfo(pFile, pPPS->tWordDocument.ulSB,
00785                         aulBBD, tBBDLen, aucHeader);
00786                 break;
00787         case 8:
00788                 vGet8NotesInfo(pFile, pPPS,
00789                         aulBBD, tBBDLen, aulSBD, tSBDLen, aucHeader);
00790                 break;
00791         default:
00792                 werr(0, "Sorry, no notes information");
00793                 break;
00794         }
00795 } /* end of vGetNotesInfo */
00796 
00797 /*
00798  *  vPrepareFootnoteText - prepare the footnote text
00799  */
00800 void
00801 vPrepareFootnoteText(FILE *pFile)
00802 { 
00803         footnote_local_type     *pCurr;
00804         size_t          tFootnote;
00805 
00806         fail(pFile == NULL);
00807         fail(pFootnoteText == NULL && tFootnoteTextLength != 0);
00808 
00809         if (pFootnoteText == NULL || tFootnoteTextLength == 0) {
00810                 /* No information */
00811                 return;
00812         }
00813 
00814         /* Fill text and useful-ness */
00815         for (tFootnote = 0; tFootnote < tFootnoteTextLength; tFootnote++) {
00816                 pCurr = pFootnoteText + tFootnote;
00817                 pCurr->bUseful = pCurr->ulCharPosStart != pCurr->ulCharPosNext;
00818                 if (pCurr->bUseful) {
00819                         pCurr->tInfo.szText = szFootnoteDecryptor(pFile,
00820                                                         pCurr->ulCharPosStart,
00821                                                         pCurr->ulCharPosNext);
00822                 } else {
00823                         pCurr->tInfo.szText = NULL;
00824                 }
00825         }
00826 } /* end of vPrepareFootnoteText */
00827 
00828 /*
00829  * szGetFootnootText - get the text of the spefified footnote
00830  */
00831 const char *
00832 szGetFootnootText(UINT uiFootnoteIndex)
00833 {
00834         if ((size_t)uiFootnoteIndex >= tFootnoteTextLength) {
00835                 return NULL;
00836         }
00837         return pFootnoteText[uiFootnoteIndex].tInfo.szText;
00838 } /* end of szGetFootnootText */
00839 
00840 /*
00841  * Get the notetype of the note at the given fileoffset
00842  */
00843 notetype_enum
00844 eGetNotetype(ULONG ulFileOffset)
00845 {
00846         size_t  tIndex;
00847 
00848         TRACE_MSG("eGetNotetype");
00849 
00850         fail(aulFootnoteList == NULL && tFootnoteListLength != 0);
00851         fail(aulEndnoteList == NULL && tEndnoteListLength != 0);
00852 
00853         /* Go for the easy answers first */
00854         if (tFootnoteListLength == 0 && tEndnoteListLength == 0) {
00855                 return notetype_is_unknown;
00856         }
00857         if (tEndnoteListLength == 0) {
00858                 return notetype_is_footnote;
00859         }
00860         if (tFootnoteListLength == 0) {
00861                 return notetype_is_endnote;
00862         }
00863         /* No easy answer, so we search */
00864         for (tIndex = 0; tIndex < tFootnoteListLength; tIndex++) {
00865                 if (aulFootnoteList[tIndex] == ulFileOffset) {
00866                         return notetype_is_footnote;
00867                 }
00868         }
00869         for (tIndex = 0; tIndex < tEndnoteListLength; tIndex++) {
00870                 if (aulEndnoteList[tIndex] == ulFileOffset) {
00871                         return notetype_is_endnote;
00872                 }
00873         }
00874         /* Not found */
00875         return notetype_is_unknown;
00876 } /* end of eGetNotetype */

Generated by  doxygen 1.6.2