diff -r f345bda72bc4 -r 43e37759235e Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/summary_8c_source.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/summary_8c_source.html Tue Mar 30 16:16:55 2010 +0100 @@ -0,0 +1,904 @@ + + + + +TB9.2 Example Applications: examples/PIPS/antiword/src/summary.c Source File + + + + + +

examples/PIPS/antiword/src/summary.c

00001 /*
+00002  * summary.c
+00003  * Copyright (C) 2002-2005 A.J. van Os; Released under GNU GPL
+00004  *
+00005  * Description:
+00006  * Read the summary information of a Word document
+00007  */
+00008 
+00009 #include <time.h>
+00010 #include <string.h>
+00011 #include "antiword.h"
+00012 
+00013 #define P_HEADER_SZ             28
+00014 #define P_SECTIONLIST_SZ        20
+00015 #define P_LENGTH_SZ              4
+00016 #define P_SECTION_MAX_SZ        (2 * P_SECTIONLIST_SZ + P_LENGTH_SZ)
+00017 #define P_SECTION_SZ(x)         ((x) * P_SECTIONLIST_SZ + P_LENGTH_SZ)
+00018 
+00019 #define PID_TITLE                2
+00020 #define PID_SUBJECT              3
+00021 #define PID_AUTHOR               4
+00022 #define PID_CREATE_DTM          12
+00023 #define PID_LASTSAVE_DTM        13
+00024 #define PID_APPNAME             18
+00025 
+00026 #define PIDD_MANAGER            14
+00027 #define PIDD_COMPANY            15
+00028 
+00029 #define VT_LPSTR                30
+00030 #define VT_FILETIME             64
+00031 
+00032 #define TIME_OFFSET_HI          0x019db1de
+00033 #define TIME_OFFSET_LO          0xd53e8000
+00034 
+00035 static char     *szTitle = NULL;
+00036 static char     *szSubject = NULL;
+00037 static char     *szAuthor = NULL;
+00038 static time_t   tCreateDtm = (time_t)-1;
+00039 static time_t   tLastSaveDtm= (time_t)-1;
+00040 static char     *szAppName = NULL;
+00041 static char     *szManager = NULL;
+00042 static char     *szCompany = NULL;
+00043 static USHORT   usLid = (USHORT)-1;
+00044 
+00045 
+00046 /*
+00047  * vDestroySummaryInfo - destroy the summary information
+00048  */
+00049 void
+00050 vDestroySummaryInfo(void)
+00051 {
+00052         TRACE_MSG("vDestroySummaryInfo");
+00053 
+00054         szTitle = xfree(szTitle);
+00055         szSubject = xfree(szSubject);
+00056         szAuthor = xfree(szAuthor);
+00057         tCreateDtm = (time_t)-1;
+00058         tLastSaveDtm = (time_t)-1;
+00059         szAppName = xfree(szAppName);
+00060         szManager = xfree(szManager);
+00061         szCompany = xfree(szCompany);
+00062         usLid = (USHORT)-1;
+00063 } /* end of vDestroySummaryInfo */
+00064 
+00065 /*
+00066  * tConvertDosDate - convert DOS date format
+00067  *
+00068  * returns Unix time_t or -1
+00069  */
+00070 static time_t
+00071 tConvertDosDate(const char *szDosDate)
+00072 {
+00073         struct tm       tTime;
+00074         const char      *pcTmp;
+00075         time_t          tResult;
+00076 
+00077         memset(&tTime, 0, sizeof(tTime));
+00078         pcTmp = szDosDate;
+00079         /* Get the month */
+00080         if (!isdigit(*pcTmp)) {
+00081                 return (time_t)-1;
+00082         }
+00083         tTime.tm_mon = (int)(*pcTmp - '0');
+00084         pcTmp++;
+00085         if (isdigit(*pcTmp)) {
+00086                 tTime.tm_mon *= 10;
+00087                 tTime.tm_mon += (int)(*pcTmp - '0');
+00088                 pcTmp++;
+00089         }
+00090         /* Get the first separater */
+00091         if (isalnum(*pcTmp)) {
+00092                 return (time_t)-1;
+00093         }
+00094         pcTmp++;
+00095         /* Get the day */
+00096         if (!isdigit(*pcTmp)) {
+00097                 return (time_t)-1;
+00098         }
+00099         tTime.tm_mday = (int)(*pcTmp - '0');
+00100         pcTmp++;
+00101         if (isdigit(*pcTmp)) {
+00102                 tTime.tm_mday *= 10;
+00103                 tTime.tm_mday += (int)(*pcTmp - '0');
+00104                 pcTmp++;
+00105         }
+00106         /* Get the second separater */
+00107         if (isalnum(*pcTmp)) {
+00108                 return (time_t)-1;
+00109         }
+00110         pcTmp++;
+00111         /* Get the year */
+00112         if (!isdigit(*pcTmp)) {
+00113                 return (time_t)-1;
+00114         }
+00115         tTime.tm_year = (int)(*pcTmp - '0');
+00116         pcTmp++;
+00117         if (isdigit(*pcTmp)) {
+00118                 tTime.tm_year *= 10;
+00119                 tTime.tm_year += (int)(*pcTmp - '0');
+00120                 pcTmp++;
+00121         }
+00122         /* Check the values */
+00123         if (tTime.tm_mon == 0 || tTime.tm_mday == 0 || tTime.tm_mday > 31) {
+00124                 return (time_t)-1;
+00125         }
+00126         /* Correct the values */
+00127         tTime.tm_mon--;         /* From 01-12 to 00-11 */
+00128         if (tTime.tm_year < 80) {
+00129                 tTime.tm_year += 100;   /* 00 means 2000 is 100 */
+00130         }
+00131         tTime.tm_isdst = -1;
+00132         tResult = mktime(&tTime);
+00133         NO_DBG_MSG(ctime(&tResult));
+00134         return tResult;
+00135 } /* end of tConvertDosDate */
+00136 
+00137 /*
+00138  * szLpstr - get a zero terminate string property
+00139  */
+00140 static char *
+00141 szLpstr(ULONG ulOffset, const UCHAR *aucBuffer)
+00142 {
+00143         char    *szStart, *szResult, *szTmp;
+00144         size_t  tSize;
+00145 
+00146         tSize = (size_t)ulGetLong(ulOffset + 4, aucBuffer);
+00147         NO_DBG_DEC(tSize);
+00148         if (tSize == 0) {
+00149                 return NULL;
+00150         }
+00151         /* Remove white space from the start of the string */
+00152         szStart = (char *)aucBuffer + ulOffset + 8;
+00153         NO_DBG_MSG(szStart);
+00154         fail(strlen(szStart) >= tSize);
+00155         while (isspace(*szStart)) {
+00156                 szStart++;
+00157         }
+00158         if (szStart[0] == '\0') {
+00159                 return NULL;
+00160         }
+00161         szResult = xstrdup(szStart);
+00162         /* Remove white space from the end of the string */
+00163         szTmp = szResult + strlen(szResult) - 1;
+00164         while (isspace(*szTmp)) {
+00165                 *szTmp = '\0';
+00166                 szTmp--;
+00167         }
+00168         NO_DBG_MSG(szResult);
+00169         return szResult;
+00170 } /* end of szLpstr */
+00171 
+00172 /*
+00173  * tFiletime - get a filetime property
+00174  */
+00175 static time_t
+00176 tFiletime(ULONG ulOffset, const UCHAR *aucBuffer)
+00177 {
+00178         double  dHi, dLo, dTmp;
+00179         ULONG   ulHi, ulLo;
+00180         time_t  tResult;
+00181 
+00182         ulLo = ulGetLong(ulOffset + 4, aucBuffer);
+00183         ulHi = ulGetLong(ulOffset + 8, aucBuffer);
+00184         NO_DBG_HEX(ulHi);
+00185         NO_DBG_HEX(ulLo);
+00186 
+00187         /* Move the starting point from 01 Jan 1601 to 01 Jan 1970 */
+00188         dHi = (double)ulHi - (double)TIME_OFFSET_HI;
+00189         dLo = (double)ulLo - (double)TIME_OFFSET_LO;
+00190         NO_DBG_FLT(dHi);
+00191         NO_DBG_FLT(dLo);
+00192 
+00193         /* Combine the values and divide by 10^7 to get seconds */
+00194         dTmp  = dLo / 10000000.0;       /* 10^7 */
+00195         dTmp += dHi * 429.4967926;      /* 2^32 / 10^7 */
+00196         NO_DBG_FLT(dTmp);
+00197 
+00198         /* Make a time_t */
+00199         if (dTmp - 0.5 < TIME_T_MIN || dTmp + 0.5 > TIME_T_MAX) {
+00200                 return (time_t)-1;
+00201         }
+00202         tResult = dTmp < 0.0 ? (time_t)(dTmp - 0.5) : (time_t)(dTmp + 0.5);
+00203         NO_DBG_MSG(ctime(&tResult));
+00204         return tResult;
+00205 } /* end of tFiletime */
+00206 
+00207 /*
+00208  * vAnalyseSummaryInfo - analyse the summary information
+00209  */
+00210 static void
+00211 vAnalyseSummaryInfo(const UCHAR *aucBuffer)
+00212 {
+00213         ULONG   ulOffset;
+00214         size_t  tIndex, tCount, tPropID, tPropType;
+00215 
+00216         tCount = (size_t)ulGetLong(4, aucBuffer);
+00217         DBG_DEC(tCount);
+00218         for (tIndex = 0; tIndex < tCount; tIndex++) {
+00219                 tPropID = (size_t)ulGetLong(8 + tIndex * 8, aucBuffer);
+00220                 ulOffset = ulGetLong(12 + tIndex * 8, aucBuffer);
+00221                 NO_DBG_DEC(tPropID);
+00222                 NO_DBG_HEX(ulOffset);
+00223                 tPropType = (size_t)ulGetLong(ulOffset, aucBuffer);
+00224                 NO_DBG_DEC(tPropType);
+00225                 switch (tPropID) {
+00226                 case PID_TITLE:
+00227                         if (tPropType == VT_LPSTR && szTitle == NULL) {
+00228                                 szTitle = szLpstr(ulOffset, aucBuffer);
+00229                         }
+00230                         break;
+00231                 case PID_SUBJECT:
+00232                         if (tPropType == VT_LPSTR && szSubject == NULL) {
+00233                                 szSubject = szLpstr(ulOffset, aucBuffer);
+00234                         }
+00235                         break;
+00236                 case PID_AUTHOR:
+00237                         if (tPropType == VT_LPSTR && szAuthor == NULL) {
+00238                                 szAuthor = szLpstr(ulOffset, aucBuffer);
+00239                         }
+00240                         break;
+00241                 case PID_CREATE_DTM:
+00242                         if (tPropType == VT_FILETIME &&
+00243                             tCreateDtm == (time_t)-1) {
+00244                                 tCreateDtm = tFiletime(ulOffset, aucBuffer);
+00245                         }
+00246                         break;
+00247                 case PID_LASTSAVE_DTM:
+00248                         if (tPropType == VT_FILETIME &&
+00249                             tLastSaveDtm == (time_t)-1) {
+00250                                 tLastSaveDtm = tFiletime(ulOffset, aucBuffer);
+00251                         }
+00252                         break;
+00253                 case PID_APPNAME:
+00254                         if (tPropType == VT_LPSTR && szAppName == NULL) {
+00255                                 szAppName = szLpstr(ulOffset, aucBuffer);
+00256                         }
+00257                         break;
+00258                 default:
+00259                         break;
+00260                 }
+00261         }
+00262 } /* end of vAnalyseSummaryInfo */
+00263 
+00264 /*
+00265  * vAnalyseDocumentSummaryInfo - analyse the document summary information
+00266  */
+00267 static void
+00268 vAnalyseDocumentSummaryInfo(const UCHAR *aucBuffer)
+00269 {
+00270         ULONG   ulOffset;
+00271         size_t  tIndex, tCount, tPropID, tPropType;
+00272 
+00273         tCount = (size_t)ulGetLong(4, aucBuffer);
+00274         DBG_DEC(tCount);
+00275         for (tIndex = 0; tIndex < tCount; tIndex++) {
+00276                 tPropID = (size_t)ulGetLong(8 + tIndex * 8, aucBuffer);
+00277                 ulOffset = ulGetLong(12 + tIndex * 8, aucBuffer);
+00278                 NO_DBG_DEC(tPropID);
+00279                 NO_DBG_HEX(ulOffset);
+00280                 tPropType = (size_t)ulGetLong(ulOffset, aucBuffer);
+00281                 NO_DBG_DEC(tPropType);
+00282                 switch (tPropID) {
+00283                 case PIDD_MANAGER:
+00284                         if (tPropType == VT_LPSTR && szManager == NULL) {
+00285                                 szManager = szLpstr(ulOffset, aucBuffer);
+00286                         }
+00287                         break;
+00288                 case PIDD_COMPANY:
+00289                         if (tPropType == VT_LPSTR && szCompany == NULL) {
+00290                                 szCompany = szLpstr(ulOffset, aucBuffer);
+00291                         }
+00292                         break;
+00293                 default:
+00294                         break;
+00295                 }
+00296         }
+00297 } /* end of vAnalyseDocumentSummaryInfo */
+00298 
+00299 /*
+00300  * pucAnalyseSummaryInfoHeader-
+00301  */
+00302 static UCHAR *
+00303 pucAnalyseSummaryInfoHeader(FILE *pFile,
+00304         ULONG ulStartBlock, ULONG ulSize,
+00305         const ULONG *aulBBD, size_t tBBDLen,
+00306         const ULONG *aulSBD, size_t tSBDLen)
+00307 {
+00308         const ULONG     *aulBlockDepot;
+00309         UCHAR   *aucBuffer;
+00310         size_t  tBlockDepotLen, tBlockSize, tSectionCount, tLength;
+00311         ULONG   ulTmp, ulOffset;
+00312         USHORT  usLittleEndian, usEmpty, usOS, usVersion;
+00313         UCHAR   aucHdr[P_HEADER_SZ], aucSecLst[P_SECTION_MAX_SZ];
+00314 
+00315         if (ulSize < MIN_SIZE_FOR_BBD_USE) {
+00316                 /* Use the Small Block Depot */
+00317                 aulBlockDepot = aulSBD;
+00318                 tBlockDepotLen = tSBDLen;
+00319                 tBlockSize = SMALL_BLOCK_SIZE;
+00320         } else {
+00321                 /* Use the Big Block Depot */
+00322                 aulBlockDepot = aulBBD;
+00323                 tBlockDepotLen = tBBDLen;
+00324                 tBlockSize = BIG_BLOCK_SIZE;
+00325         }
+00326 
+00327         if (tBlockDepotLen == 0) {
+00328                 DBG_MSG("The Block Depot length is zero");
+00329                 return NULL;
+00330         }
+00331 
+00332         /* Read the Summery Information header */
+00333         if (!bReadBuffer(pFile, ulStartBlock,
+00334                         aulBlockDepot, tBlockDepotLen, tBlockSize,
+00335                         aucHdr, 0, P_HEADER_SZ)) {
+00336                 return NULL;
+00337         }
+00338         NO_DBG_PRINT_BLOCK(aucHdr, P_HEADER_SZ);
+00339 
+00340         /* Analyse the Summery Information header */
+00341         usLittleEndian =  usGetWord(0, aucHdr);
+00342         if (usLittleEndian != 0xfffe) {
+00343                 DBG_HEX(usLittleEndian);
+00344                 DBG_MSG_C(usLittleEndian == 0xfeff, "Big endian");
+00345                 return NULL;
+00346         }
+00347         usEmpty =  usGetWord(2, aucHdr);
+00348         if (usEmpty != 0x0000) {
+00349                 DBG_DEC(usEmpty);
+00350                 return NULL;
+00351         }
+00352         ulTmp = ulGetLong(4, aucHdr);
+00353         DBG_HEX(ulTmp);
+00354         usOS = (USHORT)(ulTmp >> 16);
+00355         usVersion = (USHORT)(ulTmp & 0xffff);
+00356         switch (usOS) {
+00357         case 0:
+00358                 DBG_MSG("Win16");
+00359                 DBG_HEX(usVersion);
+00360                 break;
+00361         case 1:
+00362                 DBG_MSG("MacOS");
+00363                 DBG_HEX(usVersion);
+00364                 break;
+00365         case 2:
+00366                 DBG_MSG("Win32");
+00367                 DBG_HEX(usVersion);
+00368                 break;
+00369         default:
+00370                 DBG_DEC(usOS);
+00371                 DBG_HEX(usVersion);
+00372                 break;
+00373         }
+00374         tSectionCount = (size_t)ulGetLong(24, aucHdr);
+00375         DBG_DEC_C(tSectionCount != 1 && tSectionCount != 2, tSectionCount);
+00376         if (tSectionCount != 1 && tSectionCount != 2) {
+00377                 return NULL;
+00378         }
+00379 
+00380         /* Read the Summery Information Section Lists */
+00381         if (!bReadBuffer(pFile, ulStartBlock,
+00382                         aulBlockDepot, tBlockDepotLen, tBlockSize,
+00383                         aucSecLst, P_HEADER_SZ, P_SECTION_SZ(tSectionCount))) {
+00384                 return NULL;
+00385         }
+00386         NO_DBG_PRINT_BLOCK(aucSecLst, P_SECTION_SZ(tSectionCount));
+00387 
+00388         ulTmp = ulGetLong(0, aucSecLst);
+00389         DBG_HEX(ulTmp);
+00390         ulTmp = ulGetLong(4, aucSecLst);
+00391         DBG_HEX(ulTmp);
+00392         ulTmp = ulGetLong(8, aucSecLst);
+00393         DBG_HEX(ulTmp);
+00394         ulTmp = ulGetLong(12, aucSecLst);
+00395         DBG_HEX(ulTmp);
+00396         ulOffset = ulGetLong(16, aucSecLst);
+00397         DBG_DEC_C(ulOffset != P_HEADER_SZ + P_SECTIONLIST_SZ &&
+00398                 ulOffset != P_HEADER_SZ + 2 * P_SECTIONLIST_SZ,
+00399                 ulOffset);
+00400         fail(ulOffset != P_HEADER_SZ + P_SECTIONLIST_SZ &&
+00401                 ulOffset != P_HEADER_SZ + 2 * P_SECTIONLIST_SZ);
+00402         tLength =
+00403                 (size_t)ulGetLong(tSectionCount * P_SECTIONLIST_SZ, aucSecLst);
+00404         NO_DBG_HEX(tLength);
+00405         fail(ulOffset + tLength > ulSize);
+00406 
+00407         /* Read the Summery Information */
+00408         aucBuffer = xmalloc(tLength);
+00409         if (!bReadBuffer(pFile, ulStartBlock,
+00410                         aulBlockDepot, tBlockDepotLen, tBlockSize,
+00411                         aucBuffer, ulOffset, tLength)) {
+00412                 aucBuffer = xfree(aucBuffer);
+00413                 return NULL;
+00414         }
+00415         NO_DBG_PRINT_BLOCK(aucBuffer, tLength);
+00416         return aucBuffer;
+00417 } /* end of pucAnalyseSummaryInfoHeader */
+00418 
+00419 /*
+00420  * vSet0SummaryInfo - set summary information from a Word for DOS file
+00421  */
+00422 void
+00423 vSet0SummaryInfo(FILE *pFile, const UCHAR *aucHeader)
+00424 {
+00425         UCHAR   *aucBuffer;
+00426         ULONG   ulBeginSumdInfo, ulBeginNextBlock;
+00427         size_t  tLen;
+00428         USHORT  usCodepage, usOffset;
+00429 
+00430         TRACE_MSG("vSet0SummaryInfo");
+00431 
+00432         fail(pFile == NULL || aucHeader == NULL);
+00433 
+00434         /* First check the header */
+00435         usCodepage = usGetWord(0x7e, aucHeader);
+00436         DBG_DEC(usCodepage);
+00437         switch (usCodepage) {
+00438         case 850: usLid = 0x0809; break; /* Latin1 -> British English */
+00439         case 862: usLid = 0x040d; break; /* Hebrew */
+00440         case 866: usLid = 0x0419; break; /* Russian */
+00441         case 0:
+00442         case 437:
+00443         default: usLid = 0x0409; break; /* ASCII -> American English */
+00444         }
+00445 
+00446         /* Second check the summary information block */
+00447         ulBeginSumdInfo = 128 * (ULONG)usGetWord(0x1c, aucHeader);
+00448         DBG_HEX(ulBeginSumdInfo);
+00449         ulBeginNextBlock = 128 * (ULONG)usGetWord(0x6a, aucHeader);
+00450         DBG_HEX(ulBeginNextBlock);
+00451 
+00452         if (ulBeginSumdInfo >= ulBeginNextBlock || ulBeginNextBlock == 0) {
+00453                 /* There is no summary information block */
+00454                 return;
+00455         }
+00456         tLen = (size_t)(ulBeginNextBlock - ulBeginSumdInfo);
+00457         aucBuffer = xmalloc(tLen);
+00458         /* Read the summary information block */
+00459         if (!bReadBytes(aucBuffer, tLen, ulBeginSumdInfo, pFile)) {
+00460                 return;
+00461         }
+00462         usOffset = usGetWord(0, aucBuffer);
+00463         if (aucBuffer[usOffset] != 0) {
+00464                 NO_DBG_MSG(aucBuffer + usOffset);
+00465                 szTitle = xstrdup((char *)aucBuffer + usOffset);
+00466         }
+00467         usOffset = usGetWord(2, aucBuffer);
+00468         if (aucBuffer[usOffset] != 0) {
+00469                 NO_DBG_MSG(aucBuffer + usOffset);
+00470                 szAuthor = xstrdup((char *)aucBuffer + usOffset);
+00471         }
+00472         usOffset = usGetWord(12, aucBuffer);
+00473         if (aucBuffer[usOffset] != 0) {
+00474                 NO_DBG_STRN(aucBuffer + usOffset, 8);
+00475                 tLastSaveDtm = tConvertDosDate((char *)aucBuffer + usOffset);
+00476         }
+00477         usOffset = usGetWord(14, aucBuffer);
+00478         if (aucBuffer[usOffset] != 0) {
+00479                 NO_DBG_STRN(aucBuffer + usOffset, 8);
+00480                 tCreateDtm = tConvertDosDate((char *)aucBuffer + usOffset);
+00481         }
+00482         aucBuffer = xfree(aucBuffer);
+00483 } /* end of vSet0SummaryInfo */
+00484 
+00485 /*
+00486  * vSet2SummaryInfo - set summary information from a WinWord 1/2 file
+00487  */
+00488 void
+00489 vSet2SummaryInfo(FILE *pFile, int iWordVersion, const UCHAR *aucHeader)
+00490 {
+00491         UCHAR   *aucBuffer;
+00492         ULONG   ulBeginSumdInfo, ulBeginDocpInfo, ulTmp;
+00493         size_t  tSumdInfoLen, tDocpInfoLen, tLen, tCounter, tStart;
+00494 
+00495         TRACE_MSG("vSet2SummaryInfo");
+00496 
+00497         fail(pFile == NULL || aucHeader == NULL);
+00498         fail(iWordVersion != 1 && iWordVersion != 2);
+00499 
+00500         /* First check the header */
+00501         usLid = usGetWord(0x06, aucHeader); /* Language IDentification */
+00502         DBG_HEX(usLid);
+00503         if (usLid < 999 && iWordVersion == 1) {
+00504                 switch (usLid) {
+00505                 case   1: usLid = 0x0409; break;        /* American English */
+00506                 case   2: usLid = 0x0c0c; break;        /* Canadian French */
+00507                 case  31: usLid = 0x0413; break;        /* Dutch */
+00508                 case  33: usLid = 0x040c; break;        /* French */
+00509                 case  34: usLid = 0x040a; break;        /* Spanish */
+00510                 case  36: usLid = 0x040e; break;        /* Hungarian */
+00511                 case  39: usLid = 0x0410; break;        /* Italian */
+00512                 case  44: usLid = 0x0809; break;        /* British English */
+00513                 case  45: usLid = 0x0406; break;        /* Danish */
+00514                 case  46: usLid = 0x041f; break;        /* Swedish */
+00515                 case  47: usLid = 0x0414; break;        /* Norwegian */
+00516                 case  48: usLid = 0x0415; break;        /* Polish */
+00517                 case  49: usLid = 0x0407; break;        /* German */
+00518                 case 351: usLid = 0x0816; break;        /* Portuguese */
+00519                 case 358: usLid = 0x040b; break;        /* Finnish */
+00520                 default:
+00521                         DBG_DEC(usLid);
+00522                         DBG_FIXME();
+00523                         usLid = 0x0409;         /* American English */
+00524                         break;
+00525                 }
+00526         }
+00527 
+00528         if (iWordVersion != 2) {
+00529                 /* Unknown where to find the associated strings */
+00530                 return;
+00531         }
+00532 
+00533         /* Second check the associated strings */
+00534         ulBeginSumdInfo = ulGetLong(0x118, aucHeader); /* fcSttbfAssoc */
+00535         DBG_HEX(ulBeginSumdInfo);
+00536         tSumdInfoLen = (size_t)usGetWord(0x11c, aucHeader); /* cbSttbfAssoc */
+00537         DBG_DEC(tSumdInfoLen);
+00538 
+00539         if (tSumdInfoLen == 0) {
+00540                 /* There is no summary information */
+00541                 return;
+00542         }
+00543 
+00544         aucBuffer = xmalloc(tSumdInfoLen);
+00545         if (!bReadBytes(aucBuffer, tSumdInfoLen, ulBeginSumdInfo, pFile)) {
+00546                 aucBuffer = xfree(aucBuffer);
+00547                 return;
+00548         }
+00549         NO_DBG_PRINT_BLOCK(aucBuffer, tSumdInfoLen);
+00550         tLen = (size_t)ucGetByte(0, aucBuffer);
+00551         DBG_DEC_C(tSumdInfoLen != tLen, tSumdInfoLen);
+00552         DBG_DEC_C(tSumdInfoLen != tLen, tLen);
+00553         tStart = 1;
+00554         for (tCounter = 0; tCounter < 17; tCounter++) {
+00555                 if (tStart >= tSumdInfoLen) {
+00556                         break;
+00557                 }
+00558                 tLen = (size_t)ucGetByte(tStart, aucBuffer);
+00559                 if (tLen != 0) {
+00560                         NO_DBG_DEC(tCounter);
+00561                         NO_DBG_STRN(aucBuffer + tStart + 1, tLen);
+00562                         switch (tCounter) {
+00563                         case 3:
+00564                                 szTitle = xmalloc(tLen + 1);
+00565                                 strncpy(szTitle,
+00566                                         (char *)aucBuffer + tStart + 1, tLen);
+00567                                 szTitle[tLen] = '\0';
+00568                                 break;
+00569                         case 4:
+00570                                 szSubject = xmalloc(tLen + 1);
+00571                                 strncpy(szSubject,
+00572                                         (char *)aucBuffer + tStart + 1, tLen);
+00573                                 szSubject[tLen] = '\0';
+00574                                 break;
+00575                         case 7:
+00576                                 szAuthor = xmalloc(tLen + 1);
+00577                                 strncpy(szAuthor,
+00578                                         (char *)aucBuffer + tStart + 1, tLen);
+00579                                 szAuthor[tLen] = '\0';
+00580                                 break;
+00581                         default:
+00582                                 break;
+00583                         }
+00584                 }
+00585                 tStart += tLen + 1;
+00586         }
+00587         aucBuffer = xfree(aucBuffer);
+00588 
+00589         /* Third check the document properties */
+00590         ulBeginDocpInfo = ulGetLong(0x112, aucHeader); /* fcDop */
+00591         DBG_HEX(ulBeginDocpInfo);
+00592         tDocpInfoLen = (size_t)usGetWord(0x116, aucHeader); /* cbDop */
+00593         DBG_DEC(tDocpInfoLen);
+00594         if (tDocpInfoLen < 12) {
+00595                 return;
+00596         }
+00597 
+00598         aucBuffer = xmalloc(tDocpInfoLen);
+00599         if (!bReadBytes(aucBuffer, tDocpInfoLen, ulBeginDocpInfo, pFile)) {
+00600                 aucBuffer = xfree(aucBuffer);
+00601                 return;
+00602         }
+00603         ulTmp = ulGetLong(0x14, aucBuffer); /* dttmCreated */
+00604         tCreateDtm = tConvertDTTM(ulTmp);
+00605         ulTmp = ulGetLong(0x18, aucBuffer); /* dttmRevised */
+00606         tLastSaveDtm = tConvertDTTM(ulTmp);
+00607         aucBuffer = xfree(aucBuffer);
+00608 } /* end of vSet2SummaryInfo */
+00609 
+00610 /*
+00611  * vSetSummaryInfoOLE - set summary information from a Word 6+ file
+00612  */
+00613 static void
+00614 vSetSummaryInfoOLE(FILE *pFile, const pps_info_type *pPPS,
+00615         const ULONG *aulBBD, size_t tBBDLen,
+00616         const ULONG *aulSBD, size_t tSBDLen)
+00617 {
+00618         UCHAR   *pucBuffer;
+00619 
+00620         fail(pFile == NULL || pPPS == NULL);
+00621         fail(aulBBD == NULL || aulSBD == NULL);
+00622 
+00623         /* Summary Information */
+00624         pucBuffer = pucAnalyseSummaryInfoHeader(pFile,
+00625                 pPPS->tSummaryInfo.ulSB, pPPS->tSummaryInfo.ulSize,
+00626                 aulBBD, tBBDLen, aulSBD, tSBDLen);
+00627         if (pucBuffer != NULL) {
+00628                 vAnalyseSummaryInfo(pucBuffer);
+00629                 pucBuffer = xfree(pucBuffer);
+00630         }
+00631 
+00632         /* Document Summary Information */
+00633         pucBuffer = pucAnalyseSummaryInfoHeader(pFile,
+00634                 pPPS->tDocSummaryInfo.ulSB, pPPS->tDocSummaryInfo.ulSize,
+00635                 aulBBD, tBBDLen, aulSBD, tSBDLen);
+00636         if (pucBuffer != NULL) {
+00637                 vAnalyseDocumentSummaryInfo(pucBuffer);
+00638                 pucBuffer = xfree(pucBuffer);
+00639         }
+00640 } /* end of vSetSummaryInfoOLE */
+00641 
+00642 /*
+00643  * vSet6SummaryInfo - set summary information from a Word 6/7 file
+00644  */
+00645 void
+00646 vSet6SummaryInfo(FILE *pFile, const pps_info_type *pPPS,
+00647         const ULONG *aulBBD, size_t tBBDLen,
+00648         const ULONG *aulSBD, size_t tSBDLen,
+00649         const UCHAR *aucHeader)
+00650 {
+00651         TRACE_MSG("vSet6SummaryInfo");
+00652 
+00653         /* Header Information */
+00654         usLid = usGetWord(0x06, aucHeader); /* Language IDentification */
+00655         DBG_HEX(usLid);
+00656 
+00657         /* Summery Information */
+00658         vSetSummaryInfoOLE(pFile, pPPS, aulBBD, tBBDLen, aulSBD, tSBDLen);
+00659 } /* end of vSet6SummaryInfo */
+00660 
+00661 /*
+00662  * vSet8SummaryInfo - set summary information a Word 8/9/10 file
+00663  */
+00664 void
+00665 vSet8SummaryInfo(FILE *pFile, const pps_info_type *pPPS,
+00666         const ULONG *aulBBD, size_t tBBDLen,
+00667         const ULONG *aulSBD, size_t tSBDLen,
+00668         const UCHAR *aucHeader)
+00669 {
+00670         USHORT  usTmp;
+00671 
+00672         TRACE_MSG("vSet8SummaryInfo");
+00673 
+00674         /* Header Information */
+00675         usTmp = usGetWord(0x0a, aucHeader);
+00676         if (usTmp & BIT(14)) {
+00677                 /* Language IDentification Far East */
+00678                 usLid = usGetWord(0x3c, aucHeader);
+00679         } else {
+00680                 /* Language IDentification */
+00681                 usLid = usGetWord(0x06, aucHeader);
+00682         }
+00683         DBG_HEX(usLid);
+00684 
+00685         /* Summery Information */
+00686         vSetSummaryInfoOLE(pFile, pPPS, aulBBD, tBBDLen, aulSBD, tSBDLen);
+00687 } /* end of vSet8SummaryInfo */
+00688 
+00689 /*
+00690  * szGetTitle - get the title field
+00691  */
+00692 const char *
+00693 szGetTitle(void)
+00694 {
+00695         return szTitle;
+00696 } /* end of szGetTitle */
+00697 
+00698 /*
+00699  * szGetSubject - get the subject field
+00700  */
+00701 const char *
+00702 szGetSubject(void)
+00703 {
+00704         return szSubject;
+00705 } /* end of szGetSubject */
+00706 
+00707 /*
+00708  * szGetAuthor - get the author field
+00709  */
+00710 const char *
+00711 szGetAuthor(void)
+00712 {
+00713         return szAuthor;
+00714 } /* end of szGetAuthor */
+00715 
+00716 /*
+00717  * szGetLastSaveDtm - get the last save date field
+00718  */
+00719 const char *
+00720 szGetLastSaveDtm(void)
+00721 {
+00722         static char     szTime[12];
+00723         struct tm       *pTime;
+00724 
+00725         if (tLastSaveDtm == (time_t)-1) {
+00726                 return NULL;
+00727         }
+00728         pTime = localtime(&tLastSaveDtm);
+00729         if (pTime == NULL) {
+00730                 return NULL;
+00731         }
+00732         sprintf(szTime, "%04d-%02d-%02d",
+00733                 pTime->tm_year + 1900, pTime->tm_mon + 1, pTime->tm_mday);
+00734         return szTime;
+00735 } /* end of szGetLastSaveDtm */
+00736 
+00737 /*
+00738  * szGetModDate - get the last save date field
+00739  */
+00740 const char *
+00741 szGetModDate(void)
+00742 {
+00743         static char     szTime[20];
+00744         struct tm       *pTime;
+00745 
+00746         if (tLastSaveDtm == (time_t)-1) {
+00747                 return NULL;
+00748         }
+00749         pTime = localtime(&tLastSaveDtm);
+00750         if (pTime == NULL) {
+00751                 return NULL;
+00752         }
+00753         sprintf(szTime, "D:%04d%02d%02d%02d%02d",
+00754                 pTime->tm_year + 1900, pTime->tm_mon + 1, pTime->tm_mday,
+00755                 pTime->tm_hour, pTime->tm_min);
+00756         return szTime;
+00757 } /* end of szGetModDate */
+00758 
+00759 /*
+00760  * szGetCreationDate - get the last save date field
+00761  */
+00762 const char *
+00763 szGetCreationDate(void)
+00764 {
+00765         static char     szTime[20];
+00766         struct tm       *pTime;
+00767 
+00768         if (tCreateDtm == (time_t)-1) {
+00769                 return NULL;
+00770         }
+00771         pTime = localtime(&tCreateDtm);
+00772         if (pTime == NULL) {
+00773                 return NULL;
+00774         }
+00775         sprintf(szTime, "D:%04d%02d%02d%02d%02d",
+00776                 pTime->tm_year + 1900, pTime->tm_mon + 1, pTime->tm_mday,
+00777                 pTime->tm_hour, pTime->tm_min);
+00778         return szTime;
+00779 } /* end of szGetCreationDate */
+00780 
+00781 /*
+00782  * szGetCompany - get the company field
+00783  */
+00784 const char *
+00785 szGetCompany(void)
+00786 {
+00787         return szCompany;
+00788 } /* end of szGetCompany */
+00789 
+00790 /*
+00791  * szGetLanguage - get de language field
+00792  */
+00793 const char *
+00794 szGetLanguage(void)
+00795 {
+00796         if (usLid == (USHORT)-1) {
+00797                 /* No Language IDentification */
+00798                 return NULL;
+00799         }
+00800         if (usLid < 999) {
+00801                 /* This is a Locale, not a Language IDentification */
+00802                 DBG_DEC(usLid);
+00803                 return NULL;
+00804         }
+00805 
+00806         /* Exceptions to the general rule */
+00807         switch (usLid) {
+00808         case 0x0404: return "zh_TW"; /* Traditional Chinese */
+00809         case 0x0804: return "zh_CN"; /* Simplified Chinese */
+00810         case 0x0c04: return "zh_HK"; /* Hong Kong Chinese */
+00811         case 0x1004: return "zh_SG"; /* Singapore Chinese */
+00812         case 0x0807: return "de_CH"; /* Swiss German */
+00813         case 0x0409: return "en_US"; /* American English */
+00814         case 0x0809: return "en_GB"; /* British English */
+00815         case 0x0c09: return "en_AU"; /* Australian English */
+00816         case 0x080a: return "es_MX"; /* Mexican Spanish */
+00817         case 0x080c: return "fr_BE"; /* Belgian French */
+00818         case 0x0c0c: return "fr_CA"; /* Canadian French */
+00819         case 0x100c: return "fr_CH"; /* Swiss French */
+00820         case 0x0810: return "it_CH"; /* Swiss Italian */
+00821         case 0x0813: return "nl_BE"; /* Belgian Dutch */
+00822         case 0x0416: return "pt_BR"; /* Brazilian Portuguese */
+00823         case 0x081a:
+00824         case 0x0c1a: return "sr";    /* Serbian */
+00825         case 0x081d: return "sv_FI"; /* Finland Swedish */
+00826         default:
+00827                 break;
+00828         }
+00829 
+00830         /* The general rule */
+00831         switch (usLid & 0x00ff) {
+00832         case 0x01: return "ar"; /* Arabic */
+00833         case 0x02: return "bg"; /* Bulgarian */
+00834         case 0x03: return "ca"; /* Catalan */
+00835         case 0x04: return "zh"; /* Chinese */
+00836         case 0x05: return "cs"; /* Czech */
+00837         case 0x06: return "da"; /* Danish */
+00838         case 0x07: return "de"; /* German */
+00839         case 0x08: return "el"; /* Greek */
+00840         case 0x09: return "en"; /* English */
+00841         case 0x0a: return "es"; /* Spanish */
+00842         case 0x0b: return "fi"; /* Finnish */
+00843         case 0x0c: return "fr"; /* French */
+00844         case 0x0d: return "he"; /* Hebrew */
+00845         case 0x0e: return "hu"; /* Hungarian */
+00846         case 0x0f: return "is"; /* Icelandic */
+00847         case 0x10: return "it"; /* Italian */
+00848         case 0x11: return "ja"; /* Japanese */
+00849         case 0x12: return "ko"; /* Korean */
+00850         case 0x13: return "nl"; /* Dutch */
+00851         case 0x14: return "no"; /* Norwegian */
+00852         case 0x15: return "pl"; /* Polish */
+00853         case 0x16: return "pt"; /* Portuguese */
+00854         case 0x17: return "rm"; /* Rhaeto-Romance */
+00855         case 0x18: return "ro"; /* Romanian */
+00856         case 0x19: return "ru"; /* Russian */
+00857         case 0x1a: return "hr"; /* Croatian */
+00858         case 0x1b: return "sk"; /* Slovak */
+00859         case 0x1c: return "sq"; /* Albanian */
+00860         case 0x1d: return "sv"; /* Swedish */
+00861         case 0x1e: return "th"; /* Thai */
+00862         case 0x1f: return "tr"; /* Turkish */
+00863         case 0x20: return "ur"; /* Urdu */
+00864         case 0x21: return "id"; /* Indonesian */
+00865         case 0x22: return "uk"; /* Ukrainian */
+00866         case 0x23: return "be"; /* Belarusian */
+00867         case 0x24: return "sl"; /* Slovenian */
+00868         case 0x25: return "et"; /* Estonian */
+00869         case 0x26: return "lv"; /* Latvian */
+00870         case 0x27: return "lt"; /* Lithuanian */
+00871         case 0x29: return "fa"; /* Farsi */
+00872         case 0x2a: return "vi"; /* Viet Nam */
+00873         case 0x2b: return "hy"; /* Armenian */
+00874         case 0x2c: return "az"; /* Azeri */
+00875         case 0x2d: return "eu"; /* Basque */
+00876         case 0x2f: return "mk"; /* Macedonian */
+00877         case 0x36: return "af"; /* Afrikaans */
+00878         case 0x37: return "ka"; /* Georgian */
+00879         case 0x38: return "fo"; /* Faeroese */
+00880         case 0x39: return "hi"; /* Hindi */
+00881         case 0x3e: return "ms"; /* Malay */
+00882         case 0x3f: return "kk"; /* Kazakh */
+00883         default:
+00884                 DBG_HEX(usLid);
+00885                 DBG_FIXME();
+00886                 return NULL;
+00887         }
+00888 } /* end of szGetLanguage */
+
+
Generated by  + +doxygen 1.6.2
+ +