diff -r 59758314f811 -r d4524d6a4472 Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/wordole_8c_source.html --- a/Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/wordole_8c_source.html Fri Jun 11 15:24:34 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,820 +0,0 @@ - - - - -TB9.2 Example Applications: examples/PIPS/antiword/src/wordole.c Source File - - - - - -

examples/PIPS/antiword/src/wordole.c

00001 /*
-00002  * wordole.c
-00003  * Copyright (C) 1998-2004 A.J. van Os; Released under GPL
-00004  *
-00005  * Description:
-00006  * Deal with the OLE internals of a MS Word file
-00007  */
-00008 
-00009 #include <string.h>
-00010 #include "antiword.h"
-00011 
-00012 /* Private type for Property Set Storage entries */
-00013 typedef struct pps_entry_tag {
-00014         ULONG   ulNext;
-00015         ULONG   ulPrevious;
-00016         ULONG   ulDir;
-00017         ULONG   ulSB;
-00018         ULONG   ulSize;
-00019         int     iLevel;
-00020         char    szName[32];
-00021         UCHAR   ucType;
-00022 } pps_entry_type;
-00023 
-00024 /* Show that a PPS number or index should not be used */
-00025 #define PPS_NUMBER_INVALID      0xffffffffUL
-00026 
-00027 
-00028 /* Macro to make sure all such statements will be identical */
-00029 #define FREE_ALL()              \
-00030         do {\
-00031                 vDestroySmallBlockList();\
-00032                 aulRootList = xfree(aulRootList);\
-00033                 aulSbdList = xfree(aulSbdList);\
-00034                 aulBbdList = xfree(aulBbdList);\
-00035                 aulSBD = xfree(aulSBD);\
-00036                 aulBBD = xfree(aulBBD);\
-00037         } while(0)
-00038 
-00039 
-00040 /*
-00041  * ulReadLong - read four bytes from the given file and offset
-00042  */
-00043 static ULONG
-00044 ulReadLong(FILE *pFile, ULONG ulOffset)
-00045 {
-00046         UCHAR   aucBytes[4];
-00047 
-00048         fail(pFile == NULL);
-00049 
-00050         if (!bReadBytes(aucBytes, 4, ulOffset, pFile)) {
-00051                 werr(1, "Read long 0x%lx not possible", ulOffset);
-00052         }
-00053         return ulGetLong(0, aucBytes);
-00054 } /* end of ulReadLong */
-00055 
-00056 /*
-00057  * vName2String - turn the name into a proper string.
-00058  */
-00059 static void
-00060 vName2String(char *szName, const UCHAR *aucBytes, size_t tNameSize)
-00061 {
-00062         char    *pcChar;
-00063         size_t  tIndex;
-00064 
-00065         fail(aucBytes == NULL || szName == NULL);
-00066 
-00067         if (tNameSize < 2) {
-00068                 szName[0] = '\0';
-00069                 return;
-00070         }
-00071         for (tIndex = 0, pcChar = szName;
-00072              tIndex < 2 * tNameSize;
-00073              tIndex += 2, pcChar++) {
-00074                 *pcChar = (char)aucBytes[tIndex];
-00075         }
-00076         szName[tNameSize - 1] = '\0';
-00077 } /* end of vName2String */
-00078 
-00079 /*
-00080  * tReadBlockIndices - read the Big/Small Block Depot indices
-00081  *
-00082  * Returns the number of indices read
-00083  */
-00084 static size_t
-00085 tReadBlockIndices(FILE *pFile, ULONG *aulBlockDepot,
-00086         size_t tMaxRec, ULONG ulOffset)
-00087 {
-00088         size_t  tDone;
-00089         int     iIndex;
-00090         UCHAR   aucBytes[BIG_BLOCK_SIZE];
-00091 
-00092         fail(pFile == NULL || aulBlockDepot == NULL);
-00093         fail(tMaxRec == 0);
-00094 
-00095         /* Read a big block with BBD or SBD indices */
-00096         if (!bReadBytes(aucBytes, BIG_BLOCK_SIZE, ulOffset, pFile)) {
-00097                 werr(0, "Reading big block from 0x%lx is not possible",
-00098                         ulOffset);
-00099                 return 0;
-00100         }
-00101         /* Split the big block into indices, an index is four bytes */
-00102         tDone = min(tMaxRec, (size_t)BIG_BLOCK_SIZE / 4);
-00103         for (iIndex = 0; iIndex < (int)tDone; iIndex++) {
-00104                 aulBlockDepot[iIndex] = ulGetLong(4 * iIndex, aucBytes);
-00105                 NO_DBG_DEC(aulBlockDepot[iIndex]);
-00106         }
-00107         return tDone;
-00108 } /* end of tReadBlockIndices */
-00109 
-00110 /*
-00111  * bGetBBD - get the Big Block Depot indices from the index-blocks
-00112  */
-00113 static BOOL
-00114 bGetBBD(FILE *pFile, const ULONG *aulDepot, size_t tDepotLen,
-00115         ULONG *aulBBD, size_t tBBDLen)
-00116 {
-00117         ULONG   ulBegin;
-00118         size_t  tToGo, tDone;
-00119         int     iIndex;
-00120 
-00121         fail(pFile == NULL || aulDepot == NULL || aulBBD == NULL);
-00122 
-00123         DBG_MSG("bGetBBD");
-00124 
-00125         tToGo = tBBDLen;
-00126         for (iIndex = 0; iIndex < (int)tDepotLen && tToGo != 0; iIndex++) {
-00127                 ulBegin = (aulDepot[iIndex] + 1) * BIG_BLOCK_SIZE;
-00128                 NO_DBG_HEX(ulBegin);
-00129                 tDone = tReadBlockIndices(pFile, aulBBD, tToGo, ulBegin);
-00130                 fail(tDone > tToGo);
-00131                 if (tDone == 0) {
-00132                         return FALSE;
-00133                 }
-00134                 aulBBD += tDone;
-00135                 tToGo -= tDone;
-00136         }
-00137         return tToGo == 0;
-00138 } /* end of bGetBBD */
-00139 
-00140 /*
-00141  * bGetSBD - get the Small Block Depot indices from the index-blocks
-00142  */
-00143 static BOOL
-00144 bGetSBD(FILE *pFile, const ULONG *aulDepot, size_t tDepotLen,
-00145         ULONG *aulSBD, size_t tSBDLen)
-00146 {
-00147         ULONG   ulBegin;
-00148         size_t  tToGo, tDone;
-00149         int     iIndex;
-00150 
-00151         fail(pFile == NULL || aulDepot == NULL || aulSBD == NULL);
-00152 
-00153         DBG_MSG("bGetSBD");
-00154 
-00155         tToGo = tSBDLen;
-00156         for (iIndex = 0; iIndex < (int)tDepotLen && tToGo != 0; iIndex++) {
-00157                 fail(aulDepot[iIndex] >= ULONG_MAX / BIG_BLOCK_SIZE);
-00158                 ulBegin = (aulDepot[iIndex] + 1) * BIG_BLOCK_SIZE;
-00159                 NO_DBG_HEX(ulBegin);
-00160                 tDone = tReadBlockIndices(pFile, aulSBD, tToGo, ulBegin);
-00161                 fail(tDone > tToGo);
-00162                 if (tDone == 0) {
-00163                         return FALSE;
-00164                 }
-00165                 aulSBD += tDone;
-00166                 tToGo -= tDone;
-00167         }
-00168         return tToGo == 0;
-00169 } /* end of bGetSBD */
-00170 
-00171 /*
-00172  * vComputePPSlevels - compute the levels of the Property Set Storage entries
-00173  */
-00174 static void
-00175 vComputePPSlevels(pps_entry_type *atPPSlist, pps_entry_type *pNode,
-00176                         int iLevel, int iRecursionLevel)
-00177 {
-00178         fail(atPPSlist == NULL || pNode == NULL);
-00179         fail(iLevel < 0 || iRecursionLevel < 0);
-00180 
-00181         if (iRecursionLevel > 25) {
-00182                 /* This removes the possibility of an infinite recursion */
-00183                 DBG_DEC(iRecursionLevel);
-00184                 return;
-00185         }
-00186         if (pNode->iLevel <= iLevel) {
-00187                 /* Avoid entering a loop */
-00188                 DBG_DEC(iLevel);
-00189                 DBG_DEC(pNode->iLevel);
-00190                 return;
-00191         }
-00192 
-00193         pNode->iLevel = iLevel;
-00194 
-00195         if (pNode->ulDir != PPS_NUMBER_INVALID) {
-00196                 vComputePPSlevels(atPPSlist,
-00197                                 &atPPSlist[pNode->ulDir],
-00198                                 iLevel + 1,
-00199                                 iRecursionLevel + 1);
-00200         }
-00201         if (pNode->ulNext != PPS_NUMBER_INVALID) {
-00202                 vComputePPSlevels(atPPSlist,
-00203                                 &atPPSlist[pNode->ulNext],
-00204                                 iLevel,
-00205                                 iRecursionLevel + 1);
-00206         }
-00207         if (pNode->ulPrevious != PPS_NUMBER_INVALID) {
-00208                 vComputePPSlevels(atPPSlist,
-00209                                 &atPPSlist[pNode->ulPrevious],
-00210                                 iLevel,
-00211                                 iRecursionLevel + 1);
-00212         }
-00213 } /* end of vComputePPSlevels */
-00214 
-00215 /*
-00216  * bGetPPS - search the Property Set Storage for three sets
-00217  *
-00218  * Return TRUE if the WordDocument PPS is found
-00219  */
-00220 static BOOL
-00221 bGetPPS(FILE *pFile,
-00222         const ULONG *aulRootList, size_t tRootListLen, pps_info_type *pPPS)
-00223 {
-00224         pps_entry_type  *atPPSlist;
-00225         ULONG   ulBegin, ulOffset, ulTmp;
-00226         size_t  tNbrOfPPS, tNameSize;
-00227         int     iIndex, iStartBlock, iRootIndex;
-00228         BOOL    bWord, bExcel;
-00229         UCHAR   aucBytes[PROPERTY_SET_STORAGE_SIZE];
-00230 
-00231         fail(pFile == NULL || aulRootList == NULL || pPPS == NULL);
-00232 
-00233         DBG_MSG("bGetPPS");
-00234 
-00235         NO_DBG_DEC(tRootListLen);
-00236 
-00237         bWord = FALSE;
-00238         bExcel = FALSE;
-00239         (void)memset(pPPS, 0, sizeof(*pPPS));
-00240 
-00241         /* Read and store all the Property Set Storage entries */
-00242 
-00243         tNbrOfPPS = tRootListLen * BIG_BLOCK_SIZE / PROPERTY_SET_STORAGE_SIZE;
-00244         atPPSlist = xcalloc(tNbrOfPPS, sizeof(pps_entry_type));
-00245         iRootIndex = 0;
-00246 
-00247         for (iIndex = 0; iIndex < (int)tNbrOfPPS; iIndex++) {
-00248                 ulTmp = (ULONG)iIndex * PROPERTY_SET_STORAGE_SIZE;
-00249                 iStartBlock = (int)(ulTmp / BIG_BLOCK_SIZE);
-00250                 ulOffset = ulTmp % BIG_BLOCK_SIZE;
-00251                 ulBegin = (aulRootList[iStartBlock] + 1) * BIG_BLOCK_SIZE +
-00252                                 ulOffset;
-00253                 NO_DBG_HEX(ulBegin);
-00254                 if (!bReadBytes(aucBytes, PROPERTY_SET_STORAGE_SIZE,
-00255                                                         ulBegin, pFile)) {
-00256                         werr(0, "Reading PPS %d is not possible", iIndex);
-00257                         atPPSlist = xfree(atPPSlist);
-00258                         return FALSE;
-00259                 }
-00260                 tNameSize = (size_t)usGetWord(0x40, aucBytes);
-00261                 tNameSize = (tNameSize + 1) / 2;
-00262                 vName2String(atPPSlist[iIndex].szName, aucBytes, tNameSize);
-00263                 atPPSlist[iIndex].ucType = ucGetByte(0x42, aucBytes);
-00264                 if (atPPSlist[iIndex].ucType == 5) {
-00265                         iRootIndex = iIndex;
-00266                 }
-00267                 atPPSlist[iIndex].ulPrevious = ulGetLong(0x44, aucBytes);
-00268                 atPPSlist[iIndex].ulNext = ulGetLong(0x48, aucBytes);
-00269                 atPPSlist[iIndex].ulDir = ulGetLong(0x4c, aucBytes);
-00270                 atPPSlist[iIndex].ulSB = ulGetLong(0x74, aucBytes);
-00271                 atPPSlist[iIndex].ulSize = ulGetLong(0x78, aucBytes);
-00272                 atPPSlist[iIndex].iLevel = INT_MAX;
-00273                 if ((atPPSlist[iIndex].ulPrevious >= (ULONG)tNbrOfPPS &&
-00274                      atPPSlist[iIndex].ulPrevious != PPS_NUMBER_INVALID) ||
-00275                     (atPPSlist[iIndex].ulNext >= (ULONG)tNbrOfPPS &&
-00276                      atPPSlist[iIndex].ulNext != PPS_NUMBER_INVALID) ||
-00277                     (atPPSlist[iIndex].ulDir >= (ULONG)tNbrOfPPS &&
-00278                      atPPSlist[iIndex].ulDir != PPS_NUMBER_INVALID)) {
-00279                         DBG_DEC(iIndex);
-00280                         DBG_DEC(atPPSlist[iIndex].ulPrevious);
-00281                         DBG_DEC(atPPSlist[iIndex].ulNext);
-00282                         DBG_DEC(atPPSlist[iIndex].ulDir);
-00283                         DBG_DEC(tNbrOfPPS);
-00284                         werr(0, "The Property Set Storage is damaged");
-00285                         atPPSlist = xfree(atPPSlist);
-00286                         return FALSE;
-00287                 }
-00288         }
-00289 
-00290 #if 0 /* defined(DEBUG) */
-00291         DBG_MSG("Before");
-00292         for (iIndex = 0; iIndex < (int)tNbrOfPPS; iIndex++) {
-00293                 DBG_MSG(atPPSlist[iIndex].szName);
-00294                 DBG_HEX(atPPSlist[iIndex].ulDir);
-00295                 DBG_HEX(atPPSlist[iIndex].ulPrevious);
-00296                 DBG_HEX(atPPSlist[iIndex].ulNext);
-00297                 DBG_DEC(atPPSlist[iIndex].ulSB);
-00298                 DBG_HEX(atPPSlist[iIndex].ulSize);
-00299                 DBG_DEC(atPPSlist[iIndex].iLevel);
-00300         }
-00301 #endif /* DEBUG */
-00302 
-00303         /* Add level information to each entry */
-00304         vComputePPSlevels(atPPSlist, &atPPSlist[iRootIndex], 0, 0);
-00305 
-00306         /* Check the entries on level 1 for the required information */
-00307         NO_DBG_MSG("After");
-00308         for (iIndex = 0; iIndex < (int)tNbrOfPPS; iIndex++) {
-00309 #if 0 /* defined(DEBUG) */
-00310                 DBG_MSG(atPPSlist[iIndex].szName);
-00311                 DBG_HEX(atPPSlist[iIndex].ulDir);
-00312                 DBG_HEX(atPPSlist[iIndex].ulPrevious);
-00313                 DBG_HEX(atPPSlist[iIndex].ulNext);
-00314                 DBG_DEC(atPPSlist[iIndex].ulSB);
-00315                 DBG_HEX(atPPSlist[iIndex].ulSize);
-00316                 DBG_DEC(atPPSlist[iIndex].iLevel);
-00317 #endif /* DEBUG */
-00318                 if (atPPSlist[iIndex].iLevel != 1 ||
-00319                     atPPSlist[iIndex].ucType != 2 ||
-00320                     atPPSlist[iIndex].szName[0] == '\0' ||
-00321                     atPPSlist[iIndex].ulSize == 0) {
-00322                         /* This entry can be ignored */
-00323                         continue;
-00324                 }
-00325                 if (pPPS->tWordDocument.ulSize == 0 &&
-00326                     STREQ(atPPSlist[iIndex].szName, "WordDocument")) {
-00327                         pPPS->tWordDocument.ulSB = atPPSlist[iIndex].ulSB;
-00328                         pPPS->tWordDocument.ulSize = atPPSlist[iIndex].ulSize;
-00329                         bWord = TRUE;
-00330                 } else if (pPPS->tData.ulSize == 0 &&
-00331                            STREQ(atPPSlist[iIndex].szName, "Data")) {
-00332                         pPPS->tData.ulSB = atPPSlist[iIndex].ulSB;
-00333                         pPPS->tData.ulSize = atPPSlist[iIndex].ulSize;
-00334                 } else if (pPPS->t0Table.ulSize == 0 &&
-00335                            STREQ(atPPSlist[iIndex].szName, "0Table")) {
-00336                         pPPS->t0Table.ulSB = atPPSlist[iIndex].ulSB;
-00337                         pPPS->t0Table.ulSize = atPPSlist[iIndex].ulSize;
-00338                 } else if (pPPS->t1Table.ulSize == 0 &&
-00339                            STREQ(atPPSlist[iIndex].szName, "1Table")) {
-00340                         pPPS->t1Table.ulSB = atPPSlist[iIndex].ulSB;
-00341                         pPPS->t1Table.ulSize = atPPSlist[iIndex].ulSize;
-00342                 } else if (pPPS->tSummaryInfo.ulSize == 0 &&
-00343                            STREQ(atPPSlist[iIndex].szName,
-00344                                                 "\005SummaryInformation")) {
-00345                         pPPS->tSummaryInfo.ulSB = atPPSlist[iIndex].ulSB;
-00346                         pPPS->tSummaryInfo.ulSize = atPPSlist[iIndex].ulSize;
-00347                 } else if (pPPS->tDocSummaryInfo.ulSize == 0 &&
-00348                            STREQ(atPPSlist[iIndex].szName,
-00349                                         "\005DocumentSummaryInformation")) {
-00350                         pPPS->tDocSummaryInfo.ulSB = atPPSlist[iIndex].ulSB;
-00351                         pPPS->tDocSummaryInfo.ulSize = atPPSlist[iIndex].ulSize;
-00352                 } else if (STREQ(atPPSlist[iIndex].szName, "Book") ||
-00353                            STREQ(atPPSlist[iIndex].szName, "Workbook")) {
-00354                         bExcel = TRUE;
-00355                 }
-00356         }
-00357 
-00358         /* Free the space for the Property Set Storage entries */
-00359         atPPSlist = xfree(atPPSlist);
-00360 
-00361         /* Draw your conclusions */
-00362         if (bWord) {
-00363                 return TRUE;
-00364         }
-00365 
-00366         if (bExcel) {
-00367                 werr(0, "Sorry, but this is an Excel spreadsheet");
-00368         } else {
-00369                 werr(0, "This OLE file does not contain a Word document");
-00370         }
-00371         return FALSE;
-00372 } /* end of bGetPPS */
-00373 
-00374 /*
-00375  * vGetBbdList - make a list of the places to find big blocks
-00376  */
-00377 static void
-00378 vGetBbdList(FILE *pFile, int iNbr, ULONG *aulBbdList, ULONG ulOffset)
-00379 {
-00380         int     iIndex;
-00381 
-00382         fail(pFile == NULL);
-00383         fail(iNbr > 127);
-00384         fail(aulBbdList == NULL);
-00385 
-00386         NO_DBG_DEC(iNbr);
-00387         for (iIndex = 0; iIndex < iNbr; iIndex++) {
-00388                 aulBbdList[iIndex] =
-00389                         ulReadLong(pFile, ulOffset + 4 * (ULONG)iIndex);
-00390                 NO_DBG_DEC(iIndex);
-00391                 NO_DBG_HEX(aulBbdList[iIndex]);
-00392         }
-00393 } /* end of vGetBbdList */
-00394 
-00395 /*
-00396  * bGetDocumentText - make a list of the text blocks of a Word document
-00397  *
-00398  * Return TRUE when succesful, otherwise FALSE
-00399  */
-00400 static BOOL
-00401 bGetDocumentText(FILE *pFile, const pps_info_type *pPPS,
-00402         const ULONG *aulBBD, size_t tBBDLen,
-00403         const ULONG *aulSBD, size_t tSBDLen,
-00404         const UCHAR *aucHeader, int iWordVersion)
-00405 {
-00406         ULONG   ulBeginOfText;
-00407         ULONG   ulTextLen, ulFootnoteLen, ulEndnoteLen;
-00408         ULONG   ulHdrFtrLen, ulMacroLen, ulAnnotationLen;
-00409         ULONG   ulTextBoxLen, ulHdrTextBoxLen;
-00410         UINT    uiQuickSaves;
-00411         BOOL    bFarEastWord, bTemplate, bFastSaved, bEncrypted, bSuccess;
-00412         USHORT  usIdent, usDocStatus;
-00413 
-00414         fail(pFile == NULL || pPPS == NULL);
-00415         fail(aulBBD == NULL);
-00416         fail(aulSBD == NULL);
-00417 
-00418         DBG_MSG("bGetDocumentText");
-00419 
-00420         /* Get the "magic number" from the header */
-00421         usIdent = usGetWord(0x00, aucHeader);
-00422         DBG_HEX(usIdent);
-00423         bFarEastWord = usIdent == 0x8098 || usIdent == 0x8099 ||
-00424                         usIdent == 0xa697 || usIdent == 0xa699;
-00425         /* Get the status flags from the header */
-00426         usDocStatus = usGetWord(0x0a, aucHeader);
-00427         DBG_HEX(usDocStatus);
-00428         bTemplate = (usDocStatus & BIT(0)) != 0;
-00429         DBG_MSG_C(bTemplate, "This document is a Template");
-00430         bFastSaved = (usDocStatus & BIT(2)) != 0;
-00431         uiQuickSaves = (UINT)(usDocStatus & 0x00f0) >> 4;
-00432         DBG_MSG_C(bFastSaved, "This document is Fast Saved");
-00433         DBG_DEC_C(bFastSaved, uiQuickSaves);
-00434         bEncrypted = (usDocStatus & BIT(8)) != 0;
-00435         if (bEncrypted) {
-00436                 werr(0, "Encrypted documents are not supported");
-00437                 return FALSE;
-00438         }
-00439 
-00440         /* Get length information */
-00441         ulBeginOfText = ulGetLong(0x18, aucHeader);
-00442         DBG_HEX(ulBeginOfText);
-00443         switch (iWordVersion) {
-00444         case 6:
-00445         case 7:
-00446                 ulTextLen = ulGetLong(0x34, aucHeader);
-00447                 ulFootnoteLen = ulGetLong(0x38, aucHeader);
-00448                 ulHdrFtrLen = ulGetLong(0x3c, aucHeader);
-00449                 ulMacroLen = ulGetLong(0x40, aucHeader);
-00450                 ulAnnotationLen = ulGetLong(0x44, aucHeader);
-00451                 ulEndnoteLen = ulGetLong(0x48, aucHeader);
-00452                 ulTextBoxLen = ulGetLong(0x4c, aucHeader);
-00453                 ulHdrTextBoxLen = ulGetLong(0x50, aucHeader);
-00454                 break;
-00455         case 8:
-00456                 ulTextLen = ulGetLong(0x4c, aucHeader);
-00457                 ulFootnoteLen = ulGetLong(0x50, aucHeader);
-00458                 ulHdrFtrLen = ulGetLong(0x54, aucHeader);
-00459                 ulMacroLen = ulGetLong(0x58, aucHeader);
-00460                 ulAnnotationLen = ulGetLong(0x5c, aucHeader);
-00461                 ulEndnoteLen = ulGetLong(0x60, aucHeader);
-00462                 ulTextBoxLen = ulGetLong(0x64, aucHeader);
-00463                 ulHdrTextBoxLen = ulGetLong(0x68, aucHeader);
-00464                 break;
-00465         default:
-00466                 werr(0, "This version of Word is not supported");
-00467                 return FALSE;
-00468         }
-00469         DBG_DEC(ulTextLen);
-00470         DBG_DEC(ulFootnoteLen);
-00471         DBG_DEC(ulHdrFtrLen);
-00472         DBG_DEC(ulMacroLen);
-00473         DBG_DEC(ulAnnotationLen);
-00474         DBG_DEC(ulEndnoteLen);
-00475         DBG_DEC(ulTextBoxLen);
-00476         DBG_DEC(ulHdrTextBoxLen);
-00477 
-00478         /* Make a list of the text blocks */
-00479         switch (iWordVersion) {
-00480         case 6:
-00481         case 7:
-00482                 if (bFastSaved) {
-00483                         bSuccess = bGet6DocumentText(pFile,
-00484                                         bFarEastWord,
-00485                                         pPPS->tWordDocument.ulSB,
-00486                                         aulBBD, tBBDLen,
-00487                                         aucHeader);
-00488                 } else {
-00489                         bSuccess = bAddTextBlocks(ulBeginOfText,
-00490                                 ulTextLen +
-00491                                 ulFootnoteLen +
-00492                                 ulHdrFtrLen +
-00493                                 ulMacroLen + ulAnnotationLen +
-00494                                 ulEndnoteLen +
-00495                                 ulTextBoxLen + ulHdrTextBoxLen,
-00496                                 bFarEastWord,
-00497                                 IGNORE_PROPMOD,
-00498                                 pPPS->tWordDocument.ulSB,
-00499                                 aulBBD, tBBDLen);
-00500                 }
-00501                 break;
-00502         case 8:
-00503                 bSuccess = bGet8DocumentText(pFile,
-00504                                 pPPS,
-00505                                 aulBBD, tBBDLen, aulSBD, tSBDLen,
-00506                                 aucHeader);
-00507                 break;
-00508         default:
-00509                 werr(0, "This version of Word is not supported");
-00510                 bSuccess = FALSE;
-00511                 break;
-00512         }
-00513 
-00514         if (bSuccess) {
-00515                 vSplitBlockList(pFile,
-00516                                 ulTextLen,
-00517                                 ulFootnoteLen,
-00518                                 ulHdrFtrLen,
-00519                                 ulMacroLen,
-00520                                 ulAnnotationLen,
-00521                                 ulEndnoteLen,
-00522                                 ulTextBoxLen,
-00523                                 ulHdrTextBoxLen,
-00524                                 !bFastSaved && iWordVersion == 8);
-00525         } else {
-00526                 vDestroyTextBlockList();
-00527                 werr(0, "I can't find the text of this document");
-00528         }
-00529         return bSuccess;
-00530 } /* end of bGetDocumentText */
-00531 
-00532 /*
-00533  * vGetDocumentData - make a list of the data blocks of a Word document
-00534  */
-00535 static void
-00536 vGetDocumentData(FILE *pFile, const pps_info_type *pPPS,
-00537         const ULONG *aulBBD, size_t tBBDLen,
-00538         const UCHAR *aucHeader, int iWordVersion)
-00539 {
-00540         options_type    tOptions;
-00541         ULONG   ulBeginOfText;
-00542         BOOL    bFastSaved, bHasImages, bSuccess;
-00543         USHORT  usDocStatus;
-00544 
-00545         fail(pFile == NULL);
-00546         fail(pPPS == NULL);
-00547         fail(aulBBD == NULL);
-00548 
-00549         /* Get the options */
-00550         vGetOptions(&tOptions);
-00551 
-00552         /* Get the status flags from the header */
-00553         usDocStatus = usGetWord(0x0a, aucHeader);
-00554         DBG_HEX(usDocStatus);
-00555         bFastSaved = (usDocStatus & BIT(2)) != 0;
-00556         bHasImages = (usDocStatus & BIT(3)) != 0;
-00557 
-00558         if (!bHasImages ||
-00559             tOptions.eConversionType == conversion_text ||
-00560             tOptions.eConversionType == conversion_fmt_text ||
-00561             tOptions.eConversionType == conversion_xml ||
-00562             tOptions.eImageLevel == level_no_images) {
-00563                 /*
-00564                  * No images in the document or text-only output or
-00565                  * no images wanted, so no data blocks will be needed
-00566                  */
-00567                 vDestroyDataBlockList();
-00568                 return;
-00569         }
-00570 
-00571         /* Get length information */
-00572         ulBeginOfText = ulGetLong(0x18, aucHeader);
-00573         DBG_HEX(ulBeginOfText);
-00574 
-00575         /* Make a list of the data blocks */
-00576         switch (iWordVersion) {
-00577         case 6:
-00578         case 7:
-00579                 /*
-00580                  * The data blocks are in the text stream. The text stream
-00581                  * is in "fast saved" format or "normal saved" format
-00582                  */
-00583                 if (bFastSaved) {
-00584                         bSuccess = bGet6DocumentData(pFile,
-00585                                         pPPS->tWordDocument.ulSB,
-00586                                         aulBBD, tBBDLen,
-00587                                         aucHeader);
-00588                 } else {
-00589                         bSuccess = bAddDataBlocks(ulBeginOfText,
-00590                                         (ULONG)LONG_MAX,
-00591                                         pPPS->tWordDocument.ulSB,
-00592                                         aulBBD, tBBDLen);
-00593                 }
-00594                 break;
-00595         case 8:
-00596                 /*
-00597                  * The data blocks are in the data stream. The data stream
-00598                  * is always in "normal saved" format
-00599                  */
-00600                 bSuccess = bAddDataBlocks(0, (ULONG)LONG_MAX,
-00601                                 pPPS->tData.ulSB, aulBBD, tBBDLen);
-00602                 break;
-00603         default:
-00604                 werr(0, "This version of Word is not supported");
-00605                 bSuccess = FALSE;
-00606                 break;
-00607         }
-00608 
-00609         if (!bSuccess) {
-00610                 vDestroyDataBlockList();
-00611                 werr(0, "I can't find the data of this document");
-00612         }
-00613 } /* end of vGetDocumentData */
-00614 
-00615 /*
-00616  * iInitDocumentOLE - initialize an OLE document
-00617  *
-00618  * Returns the version of Word that made the document or -1
-00619  */
-00620 int
-00621 iInitDocumentOLE(FILE *pFile, long lFilesize)
-00622 {
-00623         pps_info_type   PPS_info;
-00624         ULONG   *aulBBD, *aulSBD;
-00625         ULONG   *aulRootList, *aulBbdList, *aulSbdList;
-00626         ULONG   ulBdbListStart, ulAdditionalBBDlist;
-00627         ULONG   ulRootStartblock, ulSbdStartblock, ulSBLstartblock;
-00628         ULONG   ulStart, ulTmp;
-00629         long    lMaxBlock;
-00630         size_t  tBBDLen, tSBDLen, tNumBbdBlocks, tRootListLen;
-00631         int     iWordVersion, iIndex, iToGo;
-00632         BOOL    bSuccess;
-00633         USHORT  usIdent, usDocStatus;
-00634         UCHAR   aucHeader[HEADER_SIZE];
-00635 
-00636         fail(pFile == NULL);
-00637 
-00638         lMaxBlock = lFilesize / BIG_BLOCK_SIZE - 2;
-00639         DBG_DEC(lMaxBlock);
-00640         if (lMaxBlock < 1) {
-00641                 return -1;
-00642         }
-00643         tBBDLen = (size_t)(lMaxBlock + 1);
-00644         tNumBbdBlocks = (size_t)ulReadLong(pFile, 0x2c);
-00645         DBG_DEC(tNumBbdBlocks);
-00646         ulRootStartblock = ulReadLong(pFile, 0x30);
-00647         DBG_DEC(ulRootStartblock);
-00648         ulSbdStartblock = ulReadLong(pFile, 0x3c);
-00649         DBG_DEC(ulSbdStartblock);
-00650         ulAdditionalBBDlist = ulReadLong(pFile, 0x44);
-00651         DBG_HEX(ulAdditionalBBDlist);
-00652         ulSBLstartblock = ulReadLong(pFile,
-00653                         (ulRootStartblock + 1) * BIG_BLOCK_SIZE + 0x74);
-00654         DBG_DEC(ulSBLstartblock);
-00655         tSBDLen = (size_t)(ulReadLong(pFile,
-00656                         (ulRootStartblock + 1) * BIG_BLOCK_SIZE + 0x78) /
-00657                         SMALL_BLOCK_SIZE);
-00658         /* All to be xcalloc-ed pointers to NULL */
-00659         aulRootList = NULL;
-00660         aulSbdList = NULL;
-00661         aulBbdList = NULL;
-00662         aulSBD = NULL;
-00663         aulBBD = NULL;
-00664 /* Big Block Depot */
-00665         aulBbdList = xcalloc(tNumBbdBlocks, sizeof(ULONG));
-00666         aulBBD = xcalloc(tBBDLen, sizeof(ULONG));
-00667         iToGo = (int)tNumBbdBlocks;
-00668         vGetBbdList(pFile, min(iToGo, 109),  aulBbdList, 0x4c);
-00669         ulStart = 109;
-00670         iToGo -= 109;
-00671         while (ulAdditionalBBDlist != END_OF_CHAIN && iToGo > 0) {
-00672                 ulBdbListStart = (ulAdditionalBBDlist + 1) * BIG_BLOCK_SIZE;
-00673                 vGetBbdList(pFile, min(iToGo, 127),
-00674                                         aulBbdList + ulStart, ulBdbListStart);
-00675                 ulAdditionalBBDlist = ulReadLong(pFile,
-00676                                         ulBdbListStart + 4 * 127);
-00677                 DBG_DEC(ulAdditionalBBDlist);
-00678                 DBG_HEX(ulAdditionalBBDlist);
-00679                 ulStart += 127;
-00680                 iToGo -= 127;
-00681         }
-00682         if (!bGetBBD(pFile, aulBbdList, tNumBbdBlocks, aulBBD, tBBDLen)) {
-00683                 FREE_ALL();
-00684                 return -1;
-00685         }
-00686         aulBbdList = xfree(aulBbdList);
-00687 /* Small Block Depot */
-00688         aulSbdList = xcalloc(tBBDLen, sizeof(ULONG));
-00689         aulSBD = xcalloc(tSBDLen, sizeof(ULONG));
-00690         for (iIndex = 0, ulTmp = ulSbdStartblock;
-00691              iIndex < (int)tBBDLen && ulTmp != END_OF_CHAIN;
-00692              iIndex++, ulTmp = aulBBD[ulTmp]) {
-00693                 if (ulTmp >= (ULONG)tBBDLen) {
-00694                         DBG_DEC(ulTmp);
-00695                         DBG_DEC(tBBDLen);
-00696                         werr(1, "The Big Block Depot is damaged");
-00697                 }
-00698                 aulSbdList[iIndex] = ulTmp;
-00699                 NO_DBG_HEX(aulSbdList[iIndex]);
-00700         }
-00701         if (!bGetSBD(pFile, aulSbdList, tBBDLen, aulSBD, tSBDLen)) {
-00702                 FREE_ALL();
-00703                 return -1;
-00704         }
-00705         aulSbdList = xfree(aulSbdList);
-00706 /* Root list */
-00707         for (tRootListLen = 0, ulTmp = ulRootStartblock;
-00708              tRootListLen < tBBDLen && ulTmp != END_OF_CHAIN;
-00709              tRootListLen++, ulTmp = aulBBD[ulTmp]) {
-00710                 if (ulTmp >= (ULONG)tBBDLen) {
-00711                         DBG_DEC(ulTmp);
-00712                         DBG_DEC(tBBDLen);
-00713                         werr(1, "The Big Block Depot is damaged");
-00714                 }
-00715         }
-00716         if (tRootListLen == 0) {
-00717                 werr(0, "No Rootlist found");
-00718                 FREE_ALL();
-00719                 return -1;
-00720         }
-00721         aulRootList = xcalloc(tRootListLen, sizeof(ULONG));
-00722         for (iIndex = 0, ulTmp = ulRootStartblock;
-00723              iIndex < (int)tBBDLen && ulTmp != END_OF_CHAIN;
-00724              iIndex++, ulTmp = aulBBD[ulTmp]) {
-00725                 if (ulTmp >= (ULONG)tBBDLen) {
-00726                         DBG_DEC(ulTmp);
-00727                         DBG_DEC(tBBDLen);
-00728                         werr(1, "The Big Block Depot is damaged");
-00729                 }
-00730                 aulRootList[iIndex] = ulTmp;
-00731                 NO_DBG_DEC(aulRootList[iIndex]);
-00732         }
-00733         fail(tRootListLen != (size_t)iIndex);
-00734         bSuccess = bGetPPS(pFile, aulRootList, tRootListLen, &PPS_info);
-00735         aulRootList = xfree(aulRootList);
-00736         if (!bSuccess) {
-00737                 FREE_ALL();
-00738                 return -1;
-00739         }
-00740 /* Small block list */
-00741         if (!bCreateSmallBlockList(ulSBLstartblock, aulBBD, tBBDLen)) {
-00742                 FREE_ALL();
-00743                 return -1;
-00744         }
-00745 
-00746         if (PPS_info.tWordDocument.ulSize < MIN_SIZE_FOR_BBD_USE) {
-00747                 DBG_DEC(PPS_info.tWordDocument.ulSize);
-00748                 FREE_ALL();
-00749                 werr(0, "I'm afraid the text stream of this file "
-00750                         "is too small to handle.");
-00751                 return -1;
-00752         }
-00753         /* Read the headerblock */
-00754         if (!bReadBuffer(pFile, PPS_info.tWordDocument.ulSB,
-00755                         aulBBD, tBBDLen, BIG_BLOCK_SIZE,
-00756                         aucHeader, 0, HEADER_SIZE)) {
-00757                 FREE_ALL();
-00758                 return -1;
-00759         }
-00760         usIdent = usGetWord(0x00, aucHeader);
-00761         DBG_HEX(usIdent);
-00762         fail(usIdent != 0x8098 &&       /* Word 7 for oriental languages */
-00763              usIdent != 0x8099 &&       /* Word 7 for oriental languages */
-00764              usIdent != 0xa5dc &&       /* Word 6 & 7 */
-00765              usIdent != 0xa5ec &&       /* Word 7 & 97 & 98 */
-00766              usIdent != 0xa697 &&       /* Word 7 for oriental languages */
-00767              usIdent != 0xa699);        /* Word 7 for oriental languages */
-00768         iWordVersion = iGetVersionNumber(aucHeader);
-00769         if (iWordVersion < 6) {
-00770                 FREE_ALL();
-00771                 werr(0, "This file is from a version of Word before Word 6.");
-00772                 return -1;
-00773         }
-00774 
-00775         /* Get the status flags from the header */
-00776         usDocStatus = usGetWord(0x0a, aucHeader);
-00777         if (usDocStatus & BIT(9)) {
-00778                 PPS_info.tTable = PPS_info.t1Table;
-00779         } else {
-00780                 PPS_info.tTable = PPS_info.t0Table;
-00781         }
-00782         /* Clean the entries that should not be used */
-00783         memset(&PPS_info.t0Table, 0, sizeof(PPS_info.t0Table));
-00784         memset(&PPS_info.t1Table, 0, sizeof(PPS_info.t1Table));
-00785 
-00786         bSuccess = bGetDocumentText(pFile, &PPS_info,
-00787                         aulBBD, tBBDLen, aulSBD, tSBDLen,
-00788                         aucHeader, iWordVersion);
-00789         if (bSuccess) {
-00790                 vGetDocumentData(pFile, &PPS_info,
-00791                         aulBBD, tBBDLen, aucHeader, iWordVersion);
-00792                 vGetPropertyInfo(pFile, &PPS_info,
-00793                         aulBBD, tBBDLen, aulSBD, tSBDLen,
-00794                         aucHeader, iWordVersion);
-00795                 vSetDefaultTabWidth(pFile, &PPS_info,
-00796                         aulBBD, tBBDLen, aulSBD, tSBDLen,
-00797                         aucHeader, iWordVersion);
-00798                 vGetNotesInfo(pFile, &PPS_info,
-00799                         aulBBD, tBBDLen, aulSBD, tSBDLen,
-00800                         aucHeader, iWordVersion);
-00801         }
-00802         FREE_ALL();
-00803         return bSuccess ? iWordVersion : -1;
-00804 } /* end of iInitDocumentOLE */
-
-
Generated by  - -doxygen 1.6.2
- -