examples/PIPS/antiword/src/finddata.c

00001 /*
00002  * finddata.c
00003  * Copyright (C) 2000-2002 A.J. van Os; Released under GPL
00004  *
00005  * Description:
00006  * Find the blocks that contain the data of MS Word files
00007  */
00008 
00009 #include <stdio.h>
00010 #include <stdlib.h>
00011 #include "antiword.h"
00012 
00013 
00014 /*
00015  * bAddDataBlocks - Add the blocks to the data block list
00016  *
00017  * Returns TRUE when successful, otherwise FALSE
00018  */
00019 BOOL
00020 bAddDataBlocks(ULONG ulDataPosFirst, ULONG ulTotalLength,
00021         ULONG ulStartBlock, const ULONG *aulBBD, size_t tBBDLen)
00022 {
00023         data_block_type tDataBlock;
00024         ULONG   ulDataPos, ulOffset, ulIndex;
00025         long    lToGo;
00026         BOOL    bSuccess;
00027 
00028         fail(ulTotalLength > (ULONG)LONG_MAX);
00029         fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN);
00030         fail(aulBBD == NULL);
00031 
00032         NO_DBG_HEX(ulDataPosFirst);
00033         NO_DBG_DEC(ulTotalLength);
00034 
00035         lToGo = (long)ulTotalLength;
00036 
00037         ulDataPos = ulDataPosFirst;
00038         ulOffset = ulDataPosFirst;
00039         for (ulIndex = ulStartBlock;
00040              ulIndex != END_OF_CHAIN && lToGo > 0;
00041              ulIndex = aulBBD[ulIndex]) {
00042                 if (ulIndex == UNUSED_BLOCK || ulIndex >= (ULONG)tBBDLen) {
00043                         DBG_DEC(ulIndex);
00044                         DBG_DEC(tBBDLen);
00045                         return FALSE;
00046                 }
00047                 if (ulOffset >= BIG_BLOCK_SIZE) {
00048                         ulOffset -= BIG_BLOCK_SIZE;
00049                         continue;
00050                 }
00051                 tDataBlock.ulFileOffset =
00052                         (ulIndex + 1) * BIG_BLOCK_SIZE + ulOffset;
00053                 tDataBlock.ulDataPos = ulDataPos;
00054                 tDataBlock.ulLength = min(BIG_BLOCK_SIZE - ulOffset,
00055                                                 (ULONG)lToGo);
00056                 fail(tDataBlock.ulLength > BIG_BLOCK_SIZE);
00057                 ulOffset = 0;
00058                 if (!bAdd2DataBlockList(&tDataBlock)) {
00059                         DBG_HEX(tDataBlock.ulFileOffset);
00060                         DBG_HEX(tDataBlock.ulDataPos);
00061                         DBG_DEC(tDataBlock.ulLength);
00062                         return FALSE;
00063                 }
00064                 ulDataPos += tDataBlock.ulLength;
00065                 lToGo -= (long)tDataBlock.ulLength;
00066         }
00067         bSuccess = lToGo == 0 ||
00068                 (ulTotalLength == (ULONG)LONG_MAX && ulIndex == END_OF_CHAIN);
00069         DBG_DEC_C(!bSuccess, lToGo);
00070         DBG_DEC_C(!bSuccess, ulTotalLength);
00071         DBG_DEC_C(!bSuccess, ulIndex);
00072         return bSuccess;
00073 } /* end of bAddDataBlocks */
00074 
00075 /*
00076  * bGet6DocumentData - make a list of the data blocks of Word 6/7 files
00077  *
00078  * Code for "fast saved" files.
00079  *
00080  * Returns TRUE when successful, otherwise FALSE
00081  */
00082 BOOL
00083 bGet6DocumentData(FILE *pFile, ULONG ulStartBlock,
00084         const ULONG *aulBBD, size_t tBBDLen, const UCHAR *aucHeader)
00085 {
00086         UCHAR   *aucBuffer;
00087         ULONG   ulBeginTextInfo, ulOffset, ulTotLength;
00088         size_t  tTextInfoLen;
00089         int     iIndex, iOff, iType, iLen, iPieces;
00090 
00091         DBG_MSG("bGet6DocumentData");
00092 
00093         fail(pFile == NULL);
00094         fail(aulBBD == NULL);
00095         fail(aucHeader == NULL);
00096 
00097         ulBeginTextInfo = ulGetLong(0x160, aucHeader);
00098         DBG_HEX(ulBeginTextInfo);
00099         tTextInfoLen = (size_t)ulGetLong(0x164, aucHeader);
00100         DBG_DEC(tTextInfoLen);
00101 
00102         aucBuffer = xmalloc(tTextInfoLen);
00103         if (!bReadBuffer(pFile, ulStartBlock,
00104                         aulBBD, tBBDLen, BIG_BLOCK_SIZE,
00105                         aucBuffer, ulBeginTextInfo, tTextInfoLen)) {
00106                 aucBuffer = xfree(aucBuffer);
00107                 return FALSE;
00108         }
00109         NO_DBG_PRINT_BLOCK(aucBuffer, tTextInfoLen);
00110 
00111         iOff = 0;
00112         while (iOff < (int)tTextInfoLen) {
00113                 iType = (int)ucGetByte(iOff, aucBuffer);
00114                 iOff++;
00115                 if (iType == 0) {
00116                         iOff++;
00117                         continue;
00118                 }
00119                 iLen = (int)usGetWord(iOff, aucBuffer);
00120                 iOff += 2;
00121                 if (iType == 1) {
00122                         iOff += iLen;
00123                         continue;
00124                 }
00125                 if (iType != 2) {
00126                         werr(0, "Unknown type of 'fastsaved' format");
00127                         aucBuffer = xfree(aucBuffer);
00128                         return FALSE;
00129                 }
00130                 /* Type 2 */
00131                 NO_DBG_DEC(iLen);
00132                 iOff += 2;
00133                 iPieces = (iLen - 4) / 12;
00134                 DBG_DEC(iPieces);
00135                 for (iIndex = 0; iIndex < iPieces; iIndex++) {
00136                         ulOffset = ulGetLong(
00137                                 iOff + (iPieces + 1) * 4 + iIndex * 8 + 2,
00138                                 aucBuffer);
00139                         ulTotLength = ulGetLong(iOff + (iIndex + 1) * 4,
00140                                                 aucBuffer) -
00141                                         ulGetLong(iOff + iIndex * 4,
00142                                                 aucBuffer);
00143                         if (!bAddDataBlocks(ulOffset, ulTotLength,
00144                                         ulStartBlock,
00145                                         aulBBD, tBBDLen)) {
00146                                 aucBuffer = xfree(aucBuffer);
00147                                 return FALSE;
00148                         }
00149                 }
00150                 break;
00151         }
00152         aucBuffer = xfree(aucBuffer);
00153         return TRUE;
00154 } /* end of bGet6DocumentData */

Generated by  doxygen 1.6.2