00001
00002
00003
00004
00005
00006
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
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 }
00064
00065
00066
00067
00068
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
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
00091 if (isalnum(*pcTmp)) {
00092 return (time_t)-1;
00093 }
00094 pcTmp++;
00095
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
00107 if (isalnum(*pcTmp)) {
00108 return (time_t)-1;
00109 }
00110 pcTmp++;
00111
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
00123 if (tTime.tm_mon == 0 || tTime.tm_mday == 0 || tTime.tm_mday > 31) {
00124 return (time_t)-1;
00125 }
00126
00127 tTime.tm_mon--;
00128 if (tTime.tm_year < 80) {
00129 tTime.tm_year += 100;
00130 }
00131 tTime.tm_isdst = -1;
00132 tResult = mktime(&tTime);
00133 NO_DBG_MSG(ctime(&tResult));
00134 return tResult;
00135 }
00136
00137
00138
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
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
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 }
00171
00172
00173
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
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
00194 dTmp = dLo / 10000000.0;
00195 dTmp += dHi * 429.4967926;
00196 NO_DBG_FLT(dTmp);
00197
00198
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 }
00206
00207
00208
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 }
00263
00264
00265
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 }
00298
00299
00300
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
00317 aulBlockDepot = aulSBD;
00318 tBlockDepotLen = tSBDLen;
00319 tBlockSize = SMALL_BLOCK_SIZE;
00320 } else {
00321
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
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
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
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
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 }
00418
00419
00420
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
00435 usCodepage = usGetWord(0x7e, aucHeader);
00436 DBG_DEC(usCodepage);
00437 switch (usCodepage) {
00438 case 850: usLid = 0x0809; break;
00439 case 862: usLid = 0x040d; break;
00440 case 866: usLid = 0x0419; break;
00441 case 0:
00442 case 437:
00443 default: usLid = 0x0409; break;
00444 }
00445
00446
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
00454 return;
00455 }
00456 tLen = (size_t)(ulBeginNextBlock - ulBeginSumdInfo);
00457 aucBuffer = xmalloc(tLen);
00458
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 }
00484
00485
00486
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
00501 usLid = usGetWord(0x06, aucHeader);
00502 DBG_HEX(usLid);
00503 if (usLid < 999 && iWordVersion == 1) {
00504 switch (usLid) {
00505 case 1: usLid = 0x0409; break;
00506 case 2: usLid = 0x0c0c; break;
00507 case 31: usLid = 0x0413; break;
00508 case 33: usLid = 0x040c; break;
00509 case 34: usLid = 0x040a; break;
00510 case 36: usLid = 0x040e; break;
00511 case 39: usLid = 0x0410; break;
00512 case 44: usLid = 0x0809; break;
00513 case 45: usLid = 0x0406; break;
00514 case 46: usLid = 0x041f; break;
00515 case 47: usLid = 0x0414; break;
00516 case 48: usLid = 0x0415; break;
00517 case 49: usLid = 0x0407; break;
00518 case 351: usLid = 0x0816; break;
00519 case 358: usLid = 0x040b; break;
00520 default:
00521 DBG_DEC(usLid);
00522 DBG_FIXME();
00523 usLid = 0x0409;
00524 break;
00525 }
00526 }
00527
00528 if (iWordVersion != 2) {
00529
00530 return;
00531 }
00532
00533
00534 ulBeginSumdInfo = ulGetLong(0x118, aucHeader);
00535 DBG_HEX(ulBeginSumdInfo);
00536 tSumdInfoLen = (size_t)usGetWord(0x11c, aucHeader);
00537 DBG_DEC(tSumdInfoLen);
00538
00539 if (tSumdInfoLen == 0) {
00540
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
00590 ulBeginDocpInfo = ulGetLong(0x112, aucHeader);
00591 DBG_HEX(ulBeginDocpInfo);
00592 tDocpInfoLen = (size_t)usGetWord(0x116, aucHeader);
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);
00604 tCreateDtm = tConvertDTTM(ulTmp);
00605 ulTmp = ulGetLong(0x18, aucBuffer);
00606 tLastSaveDtm = tConvertDTTM(ulTmp);
00607 aucBuffer = xfree(aucBuffer);
00608 }
00609
00610
00611
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
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
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 }
00641
00642
00643
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
00654 usLid = usGetWord(0x06, aucHeader);
00655 DBG_HEX(usLid);
00656
00657
00658 vSetSummaryInfoOLE(pFile, pPPS, aulBBD, tBBDLen, aulSBD, tSBDLen);
00659 }
00660
00661
00662
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
00675 usTmp = usGetWord(0x0a, aucHeader);
00676 if (usTmp & BIT(14)) {
00677
00678 usLid = usGetWord(0x3c, aucHeader);
00679 } else {
00680
00681 usLid = usGetWord(0x06, aucHeader);
00682 }
00683 DBG_HEX(usLid);
00684
00685
00686 vSetSummaryInfoOLE(pFile, pPPS, aulBBD, tBBDLen, aulSBD, tSBDLen);
00687 }
00688
00689
00690
00691
00692 const char *
00693 szGetTitle(void)
00694 {
00695 return szTitle;
00696 }
00697
00698
00699
00700
00701 const char *
00702 szGetSubject(void)
00703 {
00704 return szSubject;
00705 }
00706
00707
00708
00709
00710 const char *
00711 szGetAuthor(void)
00712 {
00713 return szAuthor;
00714 }
00715
00716
00717
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 }
00736
00737
00738
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 }
00758
00759
00760
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 }
00780
00781
00782
00783
00784 const char *
00785 szGetCompany(void)
00786 {
00787 return szCompany;
00788 }
00789
00790
00791
00792
00793 const char *
00794 szGetLanguage(void)
00795 {
00796 if (usLid == (USHORT)-1) {
00797
00798 return NULL;
00799 }
00800 if (usLid < 999) {
00801
00802 DBG_DEC(usLid);
00803 return NULL;
00804 }
00805
00806
00807 switch (usLid) {
00808 case 0x0404: return "zh_TW";
00809 case 0x0804: return "zh_CN";
00810 case 0x0c04: return "zh_HK";
00811 case 0x1004: return "zh_SG";
00812 case 0x0807: return "de_CH";
00813 case 0x0409: return "en_US";
00814 case 0x0809: return "en_GB";
00815 case 0x0c09: return "en_AU";
00816 case 0x080a: return "es_MX";
00817 case 0x080c: return "fr_BE";
00818 case 0x0c0c: return "fr_CA";
00819 case 0x100c: return "fr_CH";
00820 case 0x0810: return "it_CH";
00821 case 0x0813: return "nl_BE";
00822 case 0x0416: return "pt_BR";
00823 case 0x081a:
00824 case 0x0c1a: return "sr";
00825 case 0x081d: return "sv_FI";
00826 default:
00827 break;
00828 }
00829
00830
00831 switch (usLid & 0x00ff) {
00832 case 0x01: return "ar";
00833 case 0x02: return "bg";
00834 case 0x03: return "ca";
00835 case 0x04: return "zh";
00836 case 0x05: return "cs";
00837 case 0x06: return "da";
00838 case 0x07: return "de";
00839 case 0x08: return "el";
00840 case 0x09: return "en";
00841 case 0x0a: return "es";
00842 case 0x0b: return "fi";
00843 case 0x0c: return "fr";
00844 case 0x0d: return "he";
00845 case 0x0e: return "hu";
00846 case 0x0f: return "is";
00847 case 0x10: return "it";
00848 case 0x11: return "ja";
00849 case 0x12: return "ko";
00850 case 0x13: return "nl";
00851 case 0x14: return "no";
00852 case 0x15: return "pl";
00853 case 0x16: return "pt";
00854 case 0x17: return "rm";
00855 case 0x18: return "ro";
00856 case 0x19: return "ru";
00857 case 0x1a: return "hr";
00858 case 0x1b: return "sk";
00859 case 0x1c: return "sq";
00860 case 0x1d: return "sv";
00861 case 0x1e: return "th";
00862 case 0x1f: return "tr";
00863 case 0x20: return "ur";
00864 case 0x21: return "id";
00865 case 0x22: return "uk";
00866 case 0x23: return "be";
00867 case 0x24: return "sl";
00868 case 0x25: return "et";
00869 case 0x26: return "lv";
00870 case 0x27: return "lt";
00871 case 0x29: return "fa";
00872 case 0x2a: return "vi";
00873 case 0x2b: return "hy";
00874 case 0x2c: return "az";
00875 case 0x2d: return "eu";
00876 case 0x2f: return "mk";
00877 case 0x36: return "af";
00878 case 0x37: return "ka";
00879 case 0x38: return "fo";
00880 case 0x39: return "hi";
00881 case 0x3e: return "ms";
00882 case 0x3f: return "kk";
00883 default:
00884 DBG_HEX(usLid);
00885 DBG_FIXME();
00886 return NULL;
00887 }
00888 }