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 @@ + + +
+ +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 */ +