diff -r 59758314f811 -r d4524d6a4472 Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/summary_8c_source.html --- a/Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/summary_8c_source.html Fri Jun 11 15:24:34 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,904 +0,0 @@ - - -
- -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 */ -