/* * bGetDocumentText - make a list of the text blocks of a Word document * * Return TRUE when succesful, otherwise FALSE */ static BOOL bGetDocumentText(FILE *pFile, const UCHAR *aucHeader) { text_block_type tTextBlock; ULONG ulBeginOfText, ulEndOfText; ULONG ulTextLen; UCHAR ucDocStatus; BOOL bFastSaved; fail(pFile == NULL); fail(aucHeader == NULL); DBG_MSG("bGetDocumentText"); NO_DBG_PRINT_BLOCK(aucHeader, 0x20); /* Get the status flags from the header */ ucDocStatus = ucGetByte(0x0a, aucHeader); DBG_HEX(ucDocStatus); bFastSaved = (ucDocStatus & BIT(5)) != 0; DBG_MSG_C(bFastSaved, "This document is Fast Saved"); if (bFastSaved) { werr(0, "MacWord: fast saved documents are not supported yet"); return FALSE; } /* Get length information */ ulBeginOfText = ulGetLongBE(0x14, aucHeader); DBG_HEX(ulBeginOfText); ulEndOfText = ulGetLongBE(0x18, aucHeader); DBG_HEX(ulEndOfText); ulTextLen = ulEndOfText - ulBeginOfText; DBG_DEC(ulTextLen); tTextBlock.ulFileOffset = ulBeginOfText; tTextBlock.ulCharPos = ulBeginOfText; tTextBlock.ulLength = ulTextLen; tTextBlock.bUsesUnicode = FALSE; tTextBlock.usPropMod = IGNORE_PROPMOD; if (!bAdd2TextBlockList(&tTextBlock)) { DBG_HEX(tTextBlock.ulFileOffset); DBG_HEX(tTextBlock.ulCharPos); DBG_DEC(tTextBlock.ulLength); DBG_DEC(tTextBlock.bUsesUnicode); DBG_DEC(tTextBlock.usPropMod); return FALSE; } return TRUE; } /* end of bGetDocumentText */
/* * iGet8InfoLength - the length of the information for Word 8/9/10/11 files */ static int iGet8InfoLength(int iByteNbr, const UCHAR *aucGrpprl) { int iTmp, iDel, iAdd; USHORT usOpCode; usOpCode = usGetWord(iByteNbr, aucGrpprl); switch (usOpCode & 0xe000) { case 0x0000: case 0x2000: return 3; case 0x4000: case 0x8000: case 0xa000: return 4; case 0xe000: return 5; case 0x6000: return 6; case 0xc000: iTmp = (int)ucGetByte(iByteNbr + 2, aucGrpprl); if (usOpCode == 0xc615 && iTmp == 255) { iDel = (int)ucGetByte(iByteNbr + 3, aucGrpprl); iAdd = (int)ucGetByte( iByteNbr + 4 + iDel * 4, aucGrpprl); iTmp = 2 + iDel * 4 + iAdd * 3; } return 3 + iTmp; default: DBG_HEX(usOpCode); DBG_FIXME(); return 1; } } /* end of iGet8InfoLength */
bool JdwpMessage::parse(ZByteArray &source) { DBG("-- recv <<< --\n"); DBG_HEX(source.data(), source.size()); int i = 0; if (source.length() < 11) { return false; } int len = source.getNextInt(i); if (source.length() < len) { DBG("parse fail!, length mismatch!\n"); return false; } data.clear(); id = source.getNextInt(i); flags = source.getNextByte(i); cmdset = source.getNextByte(i); cmd = source.getNextByte(i); i -= 2; errcode = source.getNextShort(i); char *p = source.data() + 11; data.append(p, len - 11); source.remove(0, len); return true; }
/* * Build the lists with Document Property Information for WinWord 1/2 files */ void vGet2DopInfo(FILE *pFile, const UCHAR *aucHeader) { document_block_type tDocument; UCHAR *aucBuffer; ULONG ulBeginDocpInfo, ulTmp; size_t tDocpInfoLen; USHORT usTmp; ulBeginDocpInfo = ulGetLong(0x112, aucHeader); /* fcDop */ DBG_HEX(ulBeginDocpInfo); tDocpInfoLen = (size_t)usGetWord(0x116, aucHeader); /* cbDop */ DBG_DEC(tDocpInfoLen); if (tDocpInfoLen < 28) { DBG_MSG("No Document information"); return; } aucBuffer = xmalloc(tDocpInfoLen); if (!bReadBytes(aucBuffer, tDocpInfoLen, ulBeginDocpInfo, pFile)) { aucBuffer = xfree(aucBuffer); return; } usTmp = usGetWord(0x00, aucBuffer); tDocument.ucHdrFtrSpecification = (UCHAR)(usTmp >> 8); /* grpfIhdt */ tDocument.usDefaultTabWidth = usGetWord(0x0a, aucBuffer); /* dxaTab */ ulTmp = ulGetLong(0x14, aucBuffer); /* dttmCreated */ tDocument.tCreateDate = tConvertDTTM(ulTmp); ulTmp = ulGetLong(0x18, aucBuffer); /* dttmRevised */ tDocument.tRevisedDate = tConvertDTTM(ulTmp); vCreateDocumentInfoList(&tDocument); aucBuffer = xfree(aucBuffer); } /* end of vGet2DopInfo */
JNIEXPORT jint JNICALL Java_com_dx_core_DxCore_decode(JNIEnv *env, jobject, jint ptr, jbyteArray in, jbyteArray out, jint pos, jint len) { DxCore *dx = (DxCore *) ptr; u8 *inData = (u8 *) (env->GetByteArrayElements(in, NULL)); DBG("source:\n"); DBG_HEX(inData, len); u8 *outData = (u8 *) (env->GetByteArrayElements(out, NULL)); int ret = dx->decode(inData + pos, outData, len); DBG("decoded:\n"); DBG_HEX(outData, len - 2); env->ReleaseByteArrayElements(in, (jbyte *) inData, 0); env->ReleaseByteArrayElements(out, (jbyte *) outData, 0); return ret; }
/* * bSetDataOffset - set the offset in the data block list * * Make the given fileoffset the current position in the data block list */ BOOL bSetDataOffset(FILE *pFile, ULONG ulFileOffset) { data_mem_type *pCurr; size_t tReadLen; DBG_HEX(ulFileOffset); for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) { if (ulFileOffset < pCurr->tInfo.ulFileOffset || ulFileOffset >= pCurr->tInfo.ulFileOffset + pCurr->tInfo.ulLength) { /* The file offset is not in this block */ continue; } /* Compute the maximum number of bytes to read */ tReadLen = (size_t)(pCurr->tInfo.ulFileOffset + pCurr->tInfo.ulLength - ulFileOffset); /* Compute the real number of bytes to read */ if (tReadLen > sizeof(aucBlock)) { tReadLen = sizeof(aucBlock); } /* Read the bytes */ if (!bReadBytes(aucBlock, tReadLen, ulFileOffset, pFile)) { return FALSE; } /* Set the control variables */ pBlockCurrent = pCurr; ulBlockOffset = ulFileOffset - pCurr->tInfo.ulFileOffset; tByteNext = 0; return TRUE; } return FALSE; } /* end of bSetDataOffset */
/* * bGetDocumentText - make a list of the text blocks of a Word document * * Return TRUE when succesful, otherwise FALSE */ static BOOL bGetDocumentText(FILE *pFile, long lFilesize, const UCHAR *aucHeader) { text_block_type tTextBlock; ULONG ulTextLen; BOOL bFastSaved; UCHAR ucDocStatus, ucVersion; fail(pFile == NULL); fail(lFilesize < 128); fail(aucHeader == NULL); /* Get the status flags from the header */ ucDocStatus = ucGetByte(0x75, aucHeader); DBG_HEX(ucDocStatus); bFastSaved = (ucDocStatus & BIT(1)) != 0; DBG_MSG_C(bFastSaved, "This document is Fast Saved"); ucVersion = ucGetByte(0x74, aucHeader); DBG_DEC(ucVersion); DBG_MSG_C(ucVersion == 0, "Written by Word 4.0 or earlier"); DBG_MSG_C(ucVersion == 3, "Word 5.0 format, but not written by Word"); DBG_MSG_C(ucVersion == 4, "Written by Word 5.x"); if (bFastSaved) { werr(0, "Word for DOS: autosave documents are not supported"); return FALSE; } /* Get length information */ ulTextLen = ulGetLong(0x0e, aucHeader); DBG_HEX(ulTextLen); ulTextLen -= 128; DBG_DEC(ulTextLen); tTextBlock.ulFileOffset = 128; tTextBlock.ulCharPos = 128; tTextBlock.ulLength = ulTextLen; tTextBlock.bUsesUnicode = FALSE; tTextBlock.usPropMod = IGNORE_PROPMOD; if (!bAdd2TextBlockList(&tTextBlock)) { DBG_HEX(tTextBlock.ulFileOffset); DBG_HEX(tTextBlock.ulCharPos); DBG_DEC(tTextBlock.ulLength); DBG_DEC(tTextBlock.bUsesUnicode); DBG_DEC(tTextBlock.usPropMod); return FALSE; } return TRUE; } /* end of bGetDocumentText */
ZByteArray JdwpMessage::getPacket() { ZByteArray ret(true); ret.putInt(11 + data.length()); ret.putInt(id); ret.putByte(flags); ret.putByte(cmdset); ret.putByte(cmd); ret.append(data); DBG("-- >>> send --\n"); DBG_HEX(ret.data(), ret.size()); return ret; }
/* * Fill the picture information block with information * from a Word 8/9/10/11 file. * Returns TRUE when successful, otherwise FALSE */ static BOOL bGet8PicInfo(int iFodo, const UCHAR *aucGrpprl, int iBytes, picture_block_type *pPicture) { ULONG ulTmp; int iFodoOff, iInfoLen; BOOL bFound; UCHAR ucTmp; fail(iFodo <= 0 || aucGrpprl == NULL || pPicture == NULL); iFodoOff = 0; bFound = FALSE; while (iBytes >= iFodoOff + 2) { switch (usGetWord(iFodo + iFodoOff, aucGrpprl)) { #if 0 case 0x0806: /* fData */ ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); if (ucTmp == 0x01) { /* Not a picture, but a form field */ return FALSE; } DBG_DEC_C(ucTmp != 0, ucTmp); break; #endif case 0x080a: /* fOle2 */ ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); if (ucTmp == 0x01) { /* Not a picture, but an OLE object */ return FALSE; } DBG_DEC_C(ucTmp != 0, ucTmp); break; case 0x680e: /* fcObj */ ulTmp = ulGetLong(iFodo + iFodoOff + 2, aucGrpprl); DBG_HEX(ulTmp); break; case 0x6a03: /* fcPic */ pPicture->ulPictureOffset = ulGetLong( iFodo + iFodoOff + 2, aucGrpprl); bFound = TRUE; break; default: break; } iInfoLen = iGet8InfoLength(iFodo + iFodoOff, aucGrpprl); fail(iInfoLen <= 0); iFodoOff += iInfoLen; } return bFound; } /* end of bGet8PicInfo */
/* * vSet6SummaryInfo - set summary information from a Word 6/7 file */ void vSet6SummaryInfo(FILE *pFile, const pps_info_type *pPPS, const ULONG *aulBBD, size_t tBBDLen, const ULONG *aulSBD, size_t tSBDLen, const UCHAR *aucHeader) { TRACE_MSG("vSet6SummaryInfo"); /* Header Information */ usLid = usGetWord(0x06, aucHeader); /* Language IDentification */ DBG_HEX(usLid); /* Summery Information */ vSetSummaryInfoOLE(pFile, pPPS, aulBBD, tBBDLen, aulSBD, tSBDLen); } /* end of vSet6SummaryInfo */
void vUpdateRadioButton(window_handle tWindow, icon_handle tIconNumber, BOOL bSelected) { icon_block tIcon; Error_CheckFatal(Wimp_GetIconState(tWindow, tIconNumber, &tIcon)); DBG_DEC(tIconNumber); DBG_HEX(tIcon.flags.data.selected); if (bSelected == (tIcon.flags.data.selected == 1)) { /* No update needed */ return; } Error_CheckFatal(Wimp_SetIconState(tWindow, tIconNumber, bSelected ? 0x00200000 : 0, 0x00200000)); vUpdateIcon(tWindow, &tIcon); } /* end of vUpdateRadioButton */
/* * iInitDocumentDOS - initialize an DOS document * * Returns the version of Word that made the document or -1 */ int iInitDocumentDOS(FILE *pFile, long lFilesize) { int iWordVersion; BOOL bSuccess; USHORT usIdent; UCHAR aucHeader[128]; fail(pFile == NULL); if (lFilesize < 128) { return -1; } /* Read the headerblock */ if (!bReadBytes(aucHeader, 128, 0x00, pFile)) { return -1; } /* Get the "magic number" from the header */ usIdent = usGetWord(0x00, aucHeader); DBG_HEX(usIdent); fail(usIdent != 0xbe31); /* Word for DOS */ iWordVersion = iGetVersionNumber(aucHeader); if (iWordVersion != 0) { werr(0, "This file is not from 'Word for DOS'."); return -1; } bSuccess = bGetDocumentText(pFile, lFilesize, aucHeader); if (bSuccess) { vGetPropertyInfo(pFile, NULL, NULL, 0, NULL, 0, aucHeader, iWordVersion); vSetDefaultTabWidth(pFile, NULL, NULL, 0, NULL, 0, aucHeader, iWordVersion); vGetNotesInfo(pFile, NULL, NULL, 0, NULL, 0, aucHeader, iWordVersion); } return bSuccess ? iWordVersion : -1; } /* end of iInitDocumentDOS */
/* * iInitDocumentMAC - initialize an MAC document * * Returns the version of Word that made the document or -1 */ int iInitDocumentMAC(FILE *pFile, long lFilesize) { int iWordVersion; BOOL bSuccess; USHORT usIdent; UCHAR aucHeader[256]; fail(pFile == NULL); if (lFilesize < 256) { return -1; } /* Read the headerblock */ if (!bReadBytes(aucHeader, 256, 0x00, pFile)) { return -1; } /* Get the "magic number" from the header */ usIdent = usGetWord(0x00, aucHeader); DBG_HEX(usIdent); fail(usIdent != 0x37fe); /* MacWord 4 and 5 */ iWordVersion = iGetVersionNumber(aucHeader); if (iWordVersion != 4 && iWordVersion != 5) { werr(0, "This file is not from ''Mac Word 4 or 5'."); return -1; } bSuccess = bGetDocumentText(pFile, aucHeader); if (bSuccess) { vGetPropertyInfo(pFile, NULL, NULL, 0, NULL, 0, aucHeader, iWordVersion); vSetDefaultTabWidth(pFile, NULL, NULL, 0, NULL, 0, aucHeader, iWordVersion); } return bSuccess ? iWordVersion : -1; } /* end of iInitDocumentMAC */
/* * vSet8SummaryInfo - set summary information a Word 8/9/10 file */ void vSet8SummaryInfo(FILE *pFile, const pps_info_type *pPPS, const ULONG *aulBBD, size_t tBBDLen, const ULONG *aulSBD, size_t tSBDLen, const UCHAR *aucHeader) { USHORT usTmp; TRACE_MSG("vSet8SummaryInfo"); /* Header Information */ usTmp = usGetWord(0x0a, aucHeader); if (usTmp & BIT(14)) { /* Language IDentification Far East */ usLid = usGetWord(0x3c, aucHeader); } else { /* Language IDentification */ usLid = usGetWord(0x06, aucHeader); } DBG_HEX(usLid); /* Summery Information */ vSetSummaryInfoOLE(pFile, pPPS, aulBBD, tBBDLen, aulSBD, tSBDLen); } /* end of vSet8SummaryInfo */
/* * vSet0SummaryInfo - set summary information from a Word for DOS file */ void vSet0SummaryInfo(FILE *pFile, const UCHAR *aucHeader) { UCHAR *aucBuffer; ULONG ulBeginSumdInfo, ulBeginNextBlock; size_t tLen; USHORT usCodepage, usOffset; TRACE_MSG("vSet0SummaryInfo"); fail(pFile == NULL || aucHeader == NULL); /* First check the header */ usCodepage = usGetWord(0x7e, aucHeader); DBG_DEC(usCodepage); switch (usCodepage) { case 850: usLid = 0x0809; break; /* Latin1 -> British English */ case 862: usLid = 0x040d; break; /* Hebrew */ case 866: usLid = 0x0419; break; /* Russian */ case 0: case 437: default: usLid = 0x0409; break; /* ASCII -> American English */ } /* Second check the summary information block */ ulBeginSumdInfo = 128 * (ULONG)usGetWord(0x1c, aucHeader); DBG_HEX(ulBeginSumdInfo); ulBeginNextBlock = 128 * (ULONG)usGetWord(0x6a, aucHeader); DBG_HEX(ulBeginNextBlock); if (ulBeginSumdInfo >= ulBeginNextBlock || ulBeginNextBlock == 0) { /* There is no summary information block */ return; } tLen = (size_t)(ulBeginNextBlock - ulBeginSumdInfo); aucBuffer = xmalloc(tLen); /* Read the summary information block */ if (!bReadBytes(aucBuffer, tLen, ulBeginSumdInfo, pFile)) { return; } usOffset = usGetWord(0, aucBuffer); if (aucBuffer[usOffset] != 0) { NO_DBG_MSG(aucBuffer + usOffset); szTitle = xstrdup((char *)aucBuffer + usOffset); } usOffset = usGetWord(2, aucBuffer); if (aucBuffer[usOffset] != 0) { NO_DBG_MSG(aucBuffer + usOffset); szAuthor = xstrdup((char *)aucBuffer + usOffset); } usOffset = usGetWord(12, aucBuffer); if (aucBuffer[usOffset] != 0) { NO_DBG_STRN(aucBuffer + usOffset, 8); tLastSaveDtm = tConvertDosDate((char *)aucBuffer + usOffset); } usOffset = usGetWord(14, aucBuffer); if (aucBuffer[usOffset] != 0) { NO_DBG_STRN(aucBuffer + usOffset, 8); tCreateDtm = tConvertDosDate((char *)aucBuffer + usOffset); } aucBuffer = xfree(aucBuffer); } /* end of vSet0SummaryInfo */
/* * pucAnalyseSummaryInfoHeader- */ static UCHAR * pucAnalyseSummaryInfoHeader(FILE *pFile, ULONG ulStartBlock, ULONG ulSize, const ULONG *aulBBD, size_t tBBDLen, const ULONG *aulSBD, size_t tSBDLen) { const ULONG *aulBlockDepot; UCHAR *aucBuffer; size_t tBlockDepotLen, tBlockSize, tSectionCount, tLength; ULONG ulTmp, ulOffset; USHORT usLittleEndian, usEmpty, usOS, usVersion; UCHAR aucHdr[P_HEADER_SZ], aucSecLst[P_SECTION_MAX_SZ]; if (ulSize < MIN_SIZE_FOR_BBD_USE) { /* Use the Small Block Depot */ aulBlockDepot = aulSBD; tBlockDepotLen = tSBDLen; tBlockSize = SMALL_BLOCK_SIZE; } else { /* Use the Big Block Depot */ aulBlockDepot = aulBBD; tBlockDepotLen = tBBDLen; tBlockSize = BIG_BLOCK_SIZE; } if (tBlockDepotLen == 0) { DBG_MSG("The Block Depot length is zero"); return NULL; } /* Read the Summery Information header */ if (!bReadBuffer(pFile, ulStartBlock, aulBlockDepot, tBlockDepotLen, tBlockSize, aucHdr, 0, P_HEADER_SZ)) { return NULL; } NO_DBG_PRINT_BLOCK(aucHdr, P_HEADER_SZ); /* Analyse the Summery Information header */ usLittleEndian = usGetWord(0, aucHdr); if (usLittleEndian != 0xfffe) { DBG_HEX(usLittleEndian); DBG_MSG_C(usLittleEndian == 0xfeff, "Big endian"); return NULL; } usEmpty = usGetWord(2, aucHdr); if (usEmpty != 0x0000) { DBG_DEC(usEmpty); return NULL; } ulTmp = ulGetLong(4, aucHdr); DBG_HEX(ulTmp); usOS = (USHORT)(ulTmp >> 16); usVersion = (USHORT)(ulTmp & 0xffff); switch (usOS) { case 0: DBG_MSG("Win16"); DBG_HEX(usVersion); break; case 1: DBG_MSG("MacOS"); DBG_HEX(usVersion); break; case 2: DBG_MSG("Win32"); DBG_HEX(usVersion); break; default: DBG_DEC(usOS); DBG_HEX(usVersion); break; } tSectionCount = (size_t)ulGetLong(24, aucHdr); DBG_DEC_C(tSectionCount != 1 && tSectionCount != 2, tSectionCount); if (tSectionCount != 1 && tSectionCount != 2) { return NULL; } /* Read the Summery Information Section Lists */ if (!bReadBuffer(pFile, ulStartBlock, aulBlockDepot, tBlockDepotLen, tBlockSize, aucSecLst, P_HEADER_SZ, P_SECTION_SZ(tSectionCount))) { return NULL; } NO_DBG_PRINT_BLOCK(aucSecLst, P_SECTION_SZ(tSectionCount)); ulTmp = ulGetLong(0, aucSecLst); DBG_HEX(ulTmp); ulTmp = ulGetLong(4, aucSecLst); DBG_HEX(ulTmp); ulTmp = ulGetLong(8, aucSecLst); DBG_HEX(ulTmp); ulTmp = ulGetLong(12, aucSecLst); DBG_HEX(ulTmp); ulOffset = ulGetLong(16, aucSecLst); DBG_DEC_C(ulOffset != P_HEADER_SZ + P_SECTIONLIST_SZ && ulOffset != P_HEADER_SZ + 2 * P_SECTIONLIST_SZ, ulOffset); fail(ulOffset != P_HEADER_SZ + P_SECTIONLIST_SZ && ulOffset != P_HEADER_SZ + 2 * P_SECTIONLIST_SZ); tLength = (size_t)ulGetLong(tSectionCount * P_SECTIONLIST_SZ, aucSecLst); NO_DBG_HEX(tLength); fail(ulOffset + tLength > ulSize); /* Read the Summery Information */ aucBuffer = xmalloc(tLength); if (!bReadBuffer(pFile, ulStartBlock, aulBlockDepot, tBlockDepotLen, tBlockSize, aucBuffer, ulOffset, tLength)) { aucBuffer = xfree(aucBuffer); return NULL; } NO_DBG_PRINT_BLOCK(aucBuffer, tLength); return aucBuffer; } /* end of pucAnalyseSummaryInfoHeader */
JNIEXPORT jboolean JNICALL Java_com_dx_core_DxCore_setContext(JNIEnv *env, jobject, jint ptr, jobject context) { DxCore *dx = (DxCore *) ptr; QList<jobject> objList; bool ret = false; do { char *str_cls_context = dx->sub_206C(s_cls_context, sizeof(s_cls_context)); jclass cls_context = env->FindClass(str_cls_context); free(str_cls_context); if (cls_context == NULL) { DBG("cls_context not found!\n"); break; } dx->markObj(objList, cls_context); char *str_m_getappInfo = dx->sub_206C(s_m_getappInfo, sizeof(s_m_getappInfo)); char *str_arg_getappInfo = dx->sub_206C(s_arg_getappInfo, sizeof(s_arg_getappInfo)); jmethodID m_getAppInfo = env->GetMethodID(cls_context, str_m_getappInfo, str_arg_getappInfo); free(str_m_getappInfo); free(str_arg_getappInfo); if (m_getAppInfo == NULL) { DBG("m_getAppInfo not found!\n"); break; } char *str_cls_appinfo = dx->sub_206C(s_cls_appinfo, sizeof(s_cls_appinfo)); jclass cls_appinfo = env->FindClass(str_cls_appinfo); free(str_cls_appinfo); if (cls_appinfo == NULL) { DBG("cls_appinfo class not found!\n"); break; } dx->markObj(objList, cls_appinfo); char *str_f_sourcedir = dx->sub_206C(s_f_sourcedir, sizeof(s_f_sourcedir)); char *str_f_pkgname = dx->sub_206C(s_f_packageName, sizeof(s_f_packageName)); char *str_type_string = dx->sub_206C(s_type_string, sizeof(s_type_string)); jfieldID f_sourcedir = env->GetFieldID(cls_appinfo, str_f_sourcedir, str_type_string); jfieldID f_packageName = env->GetFieldID(cls_appinfo, str_f_pkgname, str_type_string); free(str_f_sourcedir); free(str_f_pkgname); free(str_type_string); if (f_sourcedir == NULL) { DBG("f_sourcedir not found!\n"); break; } if (f_packageName == NULL) { DBG("f_packageName not found!\n"); break; } u8 sha_apk[UUID_LEN] = { 0 }; u8 sha_lib[UUID_LEN] = { 0 }; u8 ret_uuid[UUID_LEN]; // ==== sha of apk ==== jobject appinfo = static_cast<jobject>(env->CallObjectMethod(context, m_getAppInfo)); jstring apkpath = static_cast<jstring>(env->GetObjectField(appinfo, f_sourcedir)); jstring pkgname = static_cast<jstring>(env->GetObjectField(appinfo, f_packageName)); dx->markObj(objList, appinfo); dx->markObj(objList, apkpath); dx->markObj(objList, pkgname); const char *apk_path = env->GetStringUTFChars(apkpath, NULL); const char *pkg_name = env->GetStringUTFChars(pkgname, NULL); DBG("apk path:<%s>, pkg name:<%s>\n", apk_path, pkg_name); if (!verifyZip(apk_path)) { DBG("apk verify fail!\n"); env->ReleaseStringUTFChars(apkpath, apk_path); break; } if (!verifyApk(env, dx, pkg_name, apk_path)) { DBG("apk verify fail!\n"); env->ReleaseStringUTFChars(apkpath, apk_path); break; } if (!parseRsa(dx, apk_path, sha_apk)) { DBG("apk rsa fail!\n"); env->ReleaseStringUTFChars(apkpath, apk_path); break; } DBG("sha_apk:\n"); DBG_HEX((void *) sha_apk, UUID_LEN); env->ReleaseStringUTFChars(apkpath, apk_path); // ==== sha of lib ==== char *libname = dx->sub_206C(s_libname, sizeof(s_libname)); char lib_path[256]; getLibPath(dx, libname, lib_path, sizeof(lib_path)); DBG("lib path:<%s>\n", lib_path); dx->sub_1370(lib_path, sha_lib); free(libname); DBG("sha_lib:\n"); DBG_HEX((void *) sha_lib, UUID_LEN); // ==== mix lib & apk ==== for (int i = 0; i < UUID_LEN; i++) { ret_uuid[i] = sha_apk[i] ^ sha_lib[i]; //DBG("%02x ^ %02x = %02x\n", sha_apk[i], sha_lib[i], ret_uuid[i]); } DBG("ret uuid:\n"); DBG_HEX(ret_uuid, UUID_LEN); dx->setUuid(ret_uuid); ret = true; } while (0); dx->freeObj(objList, env); DBG("setContext ret: %d\n", ret); return ret; }
/* * Build the list with footnote information for Word for DOS files */ static void vGet0FootnotesInfoAndText(FILE *pFile, const UCHAR *aucHeader) { footnote_local_type *pCurr; UCHAR *aucBuffer; ULONG ulFileOffset, ulBeginOfText, ulOffset, ulBeginFootnoteInfo; ULONG ulCharPos, ulBeginNextBlock; size_t tFootnotes, tFootnoteInfoLen; size_t tIndex; UCHAR aucTmp[2]; TRACE_MSG("vGet0FootnotesInfoAndText"); fail(pFile == NULL || aucHeader == NULL); ulBeginOfText = 128; NO_DBG_HEX(ulBeginOfText); ulBeginFootnoteInfo = 128 * (ULONG)usGetWord(0x14, aucHeader); DBG_HEX(ulBeginFootnoteInfo); ulBeginNextBlock = 128 * (ULONG)usGetWord(0x16, aucHeader); DBG_HEX(ulBeginNextBlock); if (ulBeginFootnoteInfo == ulBeginNextBlock) { DBG_MSG("No Footnotes in this document"); return; } /* Read the the number of footnotes + 1 */ if (!bReadBytes(aucTmp, 2, ulBeginFootnoteInfo, pFile)) { return; } tFootnotes = (size_t)usGetWord(0, aucTmp); if (tFootnotes < 2) { DBG_MSG("No Footnotes in this document (2)"); } DBG_DEC(tFootnotes); tFootnoteInfoLen = 8 * tFootnotes; aucBuffer = xmalloc(tFootnoteInfoLen); if (!bReadBytes(aucBuffer, tFootnoteInfoLen, ulBeginFootnoteInfo + 4, pFile)) { aucBuffer = xfree(aucBuffer); return; } DBG_PRINT_BLOCK(aucBuffer, tFootnoteInfoLen); /* Get footnote information */ fail(tFootnoteListLength != 0); tFootnoteListLength = tFootnotes - 1; fail(tFootnoteListLength == 0); fail(aulFootnoteList != NULL); aulFootnoteList = xcalloc(tFootnoteListLength, sizeof(ULONG)); for (tIndex = 0; tIndex < tFootnoteListLength; tIndex++) { ulOffset = ulGetLong(tIndex * 8, aucBuffer); DBG_HEX(ulOffset); ulFileOffset = ulCharPos2FileOffset(ulBeginOfText + ulOffset); DBG_HEX(ulFileOffset); aulFootnoteList[tIndex] = ulFileOffset; } /* Get footnote text */ fail(tFootnoteTextLength != 0); tFootnoteTextLength = tFootnotes - 1; fail(tFootnoteTextLength == 0); fail(pFootnoteText != NULL); pFootnoteText = xcalloc(tFootnoteTextLength, sizeof(footnote_local_type)); for (tIndex = 0; tIndex < tFootnoteTextLength; tIndex++) { pCurr = pFootnoteText + tIndex; pCurr->tInfo.szText = NULL; ulOffset = ulGetLong(tIndex * 8 + 4, aucBuffer); DBG_HEX(ulOffset); ulCharPos = ulBeginOfText + ulOffset; DBG_HEX(ulCharPos); DBG_HEX(ulCharPos2FileOffset(ulCharPos)); pCurr->ulCharPosStart = ulCharPos; ulOffset = ulGetLong((tIndex + 1) * 8 + 4, aucBuffer); DBG_HEX(ulOffset); ulCharPos = ulBeginOfText + ulOffset; DBG_HEX(ulCharPos); DBG_HEX(ulCharPos2FileOffset(ulCharPos)); pCurr->ulCharPosNext = ulCharPos; pCurr->bUseful = pCurr->ulCharPosStart != pCurr->ulCharPosNext; } aucBuffer = xfree(aucBuffer); } /* end of vGet0FootnotesInfoAndText */
/* * Fill the section information block with information * from a Word 8/9/10/11 file. */ static void vGet8SectionInfo(const UCHAR *aucGrpprl, size_t tBytes, section_block_type *pSection) { UINT uiIndex; int iFodoOff, iInfoLen, iSize, iTmp; USHORT usCcol; UCHAR ucTmp; fail(aucGrpprl == NULL || pSection == NULL); iFodoOff = 0; while (tBytes >= (size_t)iFodoOff + 2) { iInfoLen = 0; switch (usGetWord(iFodoOff, aucGrpprl)) { case 0x3009: /* bkc */ ucTmp = ucGetByte(iFodoOff + 2, aucGrpprl); DBG_DEC(ucTmp); pSection->bNewPage = ucTmp != 0 && ucTmp != 1; break; case 0x3014: /* grpfIhdt */ pSection->ucHdrFtrSpecification = ucGetByte(iFodoOff + 2, aucGrpprl); break; case 0x500b: /* ccolM1 */ usCcol = 1 + usGetWord(iFodoOff + 2, aucGrpprl); DBG_DEC(usCcol); break; case 0xd202: /* olstAnm */ iSize = (int)ucGetByte(iFodoOff + 2, aucGrpprl); DBG_DEC_C(iSize != 212, iSize); for (uiIndex = 0, iTmp = iFodoOff + 3; uiIndex < 9 && iTmp < iFodoOff + 3 + iSize - 15; uiIndex++, iTmp += 16) { pSection->aucNFC[uiIndex] = ucGetByte(iTmp, aucGrpprl); DBG_DEC(pSection->aucNFC[uiIndex]); ucTmp = ucGetByte(iTmp + 3, aucGrpprl); DBG_HEX(ucTmp); if ((ucTmp & BIT(2)) != 0) { pSection->usNeedPrevLvl |= (USHORT)BIT(uiIndex); } if ((ucTmp & BIT(3)) != 0) { pSection->usHangingIndent |= (USHORT)BIT(uiIndex); } } DBG_HEX(pSection->usNeedPrevLvl); DBG_HEX(pSection->usHangingIndent); break; default: break; } if (iInfoLen <= 0) { iInfoLen = iGet8InfoLength(iFodoOff, aucGrpprl); fail(iInfoLen <= 0); } iFodoOff += iInfoLen; } } /* end of vGet8SectionInfo */
/* * Build the lists with Section Property Information for WinWord 1/2 files */ void vGet2SepInfo(FILE *pFile, const UCHAR *aucHeader) { section_block_type tSection; ULONG *aulSectPage, *aulCharPos; UCHAR *aucBuffer, *aucFpage; ULONG ulBeginOfText, ulTextOffset, ulBeginSectInfo; size_t tSectInfoLen, tIndex, tOffset, tLen, tBytes; UCHAR aucTmp[1]; fail(pFile == NULL || aucHeader == NULL); ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */ NO_DBG_HEX(ulBeginOfText); ulBeginSectInfo = ulGetLong(0x7c, aucHeader); /* fcPlcfsed */ DBG_HEX(ulBeginSectInfo); tSectInfoLen = (size_t)usGetWord(0x80, aucHeader); /* cbPlcfsed */ DBG_DEC(tSectInfoLen); if (tSectInfoLen < 4) { DBG_DEC(tSectInfoLen); return; } aucBuffer = xmalloc(tSectInfoLen); if (!bReadBytes(aucBuffer, tSectInfoLen, ulBeginSectInfo, pFile)) { aucBuffer = xfree(aucBuffer); return; } NO_DBG_PRINT_BLOCK(aucBuffer, tSectInfoLen); /* Read the Section Descriptors */ tLen = (tSectInfoLen - 4) / 10; /* Save the section offsets */ aulCharPos = xcalloc(tLen, sizeof(ULONG)); for (tIndex = 0, tOffset = 0; tIndex < tLen; tIndex++, tOffset += 4) { ulTextOffset = ulGetLong(tOffset, aucBuffer); NO_DBG_HEX(ulTextOffset); aulCharPos[tIndex] = ulBeginOfText + ulTextOffset; NO_DBG_HEX(aulCharPos[tIndex]); } /* Save the Sepx offsets */ aulSectPage = xcalloc(tLen, sizeof(ULONG)); for (tIndex = 0, tOffset = (tLen + 1) * 4; tIndex < tLen; tIndex++, tOffset += 6) { aulSectPage[tIndex] = ulGetLong(tOffset + 2, aucBuffer); NO_DBG_HEX(aulSectPage[tIndex]); /* fcSepx */ } aucBuffer = xfree(aucBuffer); /* Read the Section Properties */ for (tIndex = 0; tIndex < tLen; tIndex++) { if (aulSectPage[tIndex] == FC_INVALID) { vDefault2SectionInfoList(aulCharPos[tIndex]); continue; } /* Get the number of bytes to read */ if (!bReadBytes(aucTmp, 1, aulSectPage[tIndex], pFile)) { continue; } tBytes = 1 + (size_t)ucGetByte(0, aucTmp); NO_DBG_DEC(tBytes); /* Read the bytes */ aucFpage = xmalloc(tBytes); if (!bReadBytes(aucFpage, tBytes, aulSectPage[tIndex], pFile)) { aucFpage = xfree(aucFpage); continue; } NO_DBG_PRINT_BLOCK(aucFpage, tBytes); /* Process the bytes */ vGetDefaultSection(&tSection); vGet2SectionInfo(aucFpage + 1, tBytes - 1, &tSection); vAdd2SectionInfoList(&tSection, aulCharPos[tIndex]); aucFpage = xfree(aucFpage); } aulCharPos = xfree(aulCharPos); aulSectPage = xfree(aulSectPage); } /* end of vGet2SepInfo */
/* * ulTranslateCharacters - Translate characters to local representation * * Translate all characters to local representation * * returns the translated character */ ULONG ulTranslateCharacters(USHORT usChar, ULONG ulFileOffset, int iWordVersion, conversion_type eConversionType, encoding_type eEncoding, BOOL bUseMacCharSet) { const char_table_type *pTmp; const USHORT *usCharSet; usCharSet = NULL; if (bUseMacCharSet) { /* Macintosh character set */ usCharSet = usMacRoman; } else if (iWordVersion == 0) { /* DOS character set */ usCharSet = usCp850; } else { /* Windows character set */ switch (eEncoding) { case encoding_latin_2: usCharSet = usCp1250; break; case encoding_cyrillic: usCharSet = usCp1251; break; case encoding_latin_1: default: usCharSet = usCp1252; break; } } fail(usCharSet == NULL); if (usChar >= 0x80 && usChar <= 0x9f) { /* Translate implementation defined characters */ usChar = usCharSet[usChar - 0x80]; } else if (iWordVersion < 8 && usChar >= 0xa0 && usChar <= 0xff) { /* Translate old character set to Unixcode */ usChar = usCharSet[usChar - 0x80]; } /* Microsoft Unicode to real Unicode */ if (usChar >= 0xf020 && usChar <= 0xf0ff) { DBG_HEX_C(usPrivateArea[usChar - 0xf020] == 0x003f, usChar); usChar = usPrivateArea[usChar - 0xf020]; } /* Characters with a special meaning in Word */ switch (usChar) { case IGNORE_CHARACTER: case FOOTNOTE_SEPARATOR: case FOOTNOTE_CONTINUATION: case ANNOTATION: case FRAME: case LINE_FEED: case WORD_SOFT_HYPHEN: case UNICODE_HYPHENATION_POINT: return IGNORE_CHARACTER; case PICTURE: case TABLE_SEPARATOR: case TAB: case HARD_RETURN: case PAGE_BREAK: case PAR_END: case COLUMN_FEED: return (ULONG)usChar; case FOOTNOTE_OR_ENDNOTE: NO_DBG_HEX(ulFileOffset); switch (eGetNotetype(ulFileOffset)) { case notetype_is_footnote: return FOOTNOTE_CHAR; case notetype_is_endnote: return ENDNOTE_CHAR; default: return UNKNOWN_NOTE_CHAR; } case WORD_UNBREAKABLE_JOIN: return (ULONG)OUR_UNBREAKABLE_JOIN; default: break; } if (eEncoding != encoding_utf_8) { /* Latin characters in an oriental text */ if (usChar >= 0xff01 && usChar <= 0xff5e) { usChar -= 0xfee0; } } if (eEncoding == encoding_latin_1 && (eConversionType == conversion_ps || eConversionType == conversion_pdf)) { /* Ugly, but it makes the PostScript and PDF look better */ switch (usChar) { case UNICODE_ELLIPSIS: return 140; case UNICODE_TRADEMARK_SIGN: return 141; case UNICODE_PER_MILLE_SIGN: return 142; case UNICODE_BULLET: case UNICODE_BULLET_OPERATOR: case UNICODE_BLACK_CLUB_SUIT: return 143; case UNICODE_LEFT_SINGLE_QMARK: return 144; case UNICODE_RIGHT_SINGLE_QMARK: return 145; case UNICODE_SINGLE_LEFT_ANGLE_QMARK: return 146; case UNICODE_SINGLE_RIGHT_ANGLE_QMARK: return 147; case UNICODE_LEFT_DOUBLE_QMARK: return 148; case UNICODE_RIGHT_DOUBLE_QMARK: return 149; case UNICODE_DOUBLE_LOW_9_QMARK: return 150; case UNICODE_EN_DASH: return 151; case UNICODE_EM_DASH: return 152; case UNICODE_MINUS_SIGN: return 153; case UNICODE_CAPITAL_LIGATURE_OE: return 154; case UNICODE_SMALL_LIGATURE_OE: return 155; case UNICODE_DAGGER: return 156; case UNICODE_DOUBLE_DAGGER: return 157; case UNICODE_SMALL_LIGATURE_FI: return 158; case UNICODE_SMALL_LIGATURE_FL: return 159; default: break; } } if (eConversionType == conversion_pdf) { if (eEncoding == encoding_latin_1) { switch (usChar) { case UNICODE_EURO_SIGN: return 128; default: break; } } else if (eEncoding == encoding_latin_2) { switch (usChar) { case UNICODE_CAPITAL_D_WITH_STROKE: case UNICODE_SMALL_D_WITH_STROKE: return 0x3f; default: break; } } } if (usChar < 0x80) { /* US ASCII */ if (usChar < 0x20 || usChar == 0x7f) { /* Ignore control characters */ DBG_HEX(usChar); DBG_FIXME(); return IGNORE_CHARACTER; } return (ULONG)usChar; } if (eEncoding == encoding_utf_8) { /* No need to convert Unicode characters */ return (ULONG)usChar; } /* Unicode to local representation */ pTmp = pGetCharTableRecord(usChar); if (pTmp != NULL) { DBG_HEX_C(usChar >= 0x7f && usChar <= 0x9f, usChar); return (ULONG)pTmp->ucLocal; } /* Fancy characters to simple US ASCII */ switch (usChar) { case UNICODE_SMALL_F_HOOK: return (ULONG)'f'; case UNICODE_GREEK_CAPITAL_CHI: return (ULONG)'X'; case UNICODE_GREEK_SMALL_UPSILON: return (ULONG)'v'; case UNICODE_MODIFIER_CIRCUMFLEX: case UNICODE_UPWARDS_ARROW: return (ULONG)'^'; case UNICODE_SMALL_TILDE: case UNICODE_TILDE_OPERATOR: return (ULONG)'~'; case UNICODE_EN_QUAD: case UNICODE_EM_QUAD: case UNICODE_EN_SPACE: case UNICODE_EM_SPACE: case UNICODE_THREE_PER_EM_SPACE: case UNICODE_FOUR_PER_EM_SPACE: case UNICODE_SIX_PER_EM_SPACE: case UNICODE_FIGURE_SPACE: case UNICODE_PUNCTUATION_SPACE: case UNICODE_THIN_SPACE: case UNICODE_NARROW_NO_BREAK_SPACE: case UNICODE_LIGHT_SHADE: case UNICODE_MEDIUM_SHADE: case UNICODE_DARK_SHADE: return (ULONG)' '; case UNICODE_LEFT_DOUBLE_QMARK: case UNICODE_RIGHT_DOUBLE_QMARK: case UNICODE_DOUBLE_LOW_9_QMARK: case UNICODE_DOUBLE_HIGH_REV_9_QMARK: case UNICODE_DOUBLE_PRIME: return (ULONG)'"'; case UNICODE_LEFT_SINGLE_QMARK: case UNICODE_RIGHT_SINGLE_QMARK: case UNICODE_SINGLE_LOW_9_QMARK: case UNICODE_SINGLE_HIGH_REV_9_QMARK: case UNICODE_PRIME: return (ULONG)'\''; case UNICODE_HYPHEN: case UNICODE_NON_BREAKING_HYPHEN: case UNICODE_FIGURE_DASH: case UNICODE_EN_DASH: case UNICODE_EM_DASH: case UNICODE_HORIZONTAL_BAR: case UNICODE_MINUS_SIGN: case UNICODE_BD_LIGHT_HORIZONTAL: case UNICODE_BD_DOUBLE_HORIZONTAL: return (ULONG)'-'; case UNICODE_DOUBLE_VERTICAL_LINE: case UNICODE_BD_LIGHT_VERTICAL: case UNICODE_BD_DOUBLE_VERTICAL: return (ULONG)'|'; case UNICODE_DOUBLE_LOW_LINE: return (ULONG)'_'; case UNICODE_DAGGER: return (ULONG)'+'; case UNICODE_DOUBLE_DAGGER: return (ULONG)'#'; case UNICODE_BULLET: case UNICODE_BULLET_OPERATOR: case UNICODE_BLACK_CLUB_SUIT: return (ULONG)ucGetBulletCharacter(eConversionType, eEncoding); case UNICODE_ONE_DOT_LEADER: case UNICODE_TWO_DOT_LEADER: return (ULONG)'.'; case UNICODE_ELLIPSIS: #if defined(__riscos) return (ULONG)OUR_ELLIPSIS; #else if (ulFileOffset == 0) { return (ULONG)OUR_ELLIPSIS; } return UNICODE_ELLIPSIS; #endif /* __riscos */ case UNICODE_DOUBLE_LEFT_ANGLE_QMARK: case UNICODE_TRIANGULAR_BULLET: case UNICODE_SINGLE_LEFT_ANGLE_QMARK: case UNICODE_LEFTWARDS_ARROW: return (ULONG)'<'; case UNICODE_DOUBLE_RIGHT_ANGLE_QMARK: case UNICODE_SINGLE_RIGHT_ANGLE_QMARK: case UNICODE_RIGHTWARDS_ARROW: return (ULONG)'>'; case UNICODE_UNDERTIE: return (ULONG)'-'; case UNICODE_N_ARY_SUMMATION: return (ULONG)'S'; case UNICODE_EURO_SIGN: return (ULONG)'E'; case UNICODE_CIRCLE: case UNICODE_SQUARE: return (ULONG)'O'; case UNICODE_DIAMOND: return (ULONG)OUR_DIAMOND; case UNICODE_NUMERO_SIGN: return (ULONG)'N'; case UNICODE_KELVIN_SIGN: return (ULONG)'K'; case UNICODE_DOWNWARDS_ARROW: return (ULONG)'v'; case UNICODE_FRACTION_SLASH: case UNICODE_DIVISION_SLASH: return (ULONG)'/'; case UNICODE_ASTERISK_OPERATOR: return (ULONG)'*'; case UNICODE_RATIO: return (ULONG)':'; case UNICODE_BD_LIGHT_DOWN_RIGHT: case UNICODE_BD_LIGHT_DOWN_AND_LEFT: case UNICODE_BD_LIGHT_UP_AND_RIGHT: case UNICODE_BD_LIGHT_UP_AND_LEFT: case UNICODE_BD_LIGHT_VERTICAL_AND_RIGHT: case UNICODE_BD_LIGHT_VERTICAL_AND_LEFT: case UNICODE_BD_LIGHT_DOWN_AND_HORIZONTAL: case UNICODE_BD_LIGHT_UP_AND_HORIZONTAL: case UNICODE_BD_LIGHT_VERTICAL_AND_HORIZONTAL: case UNICODE_BD_DOUBLE_DOWN_AND_RIGHT: case UNICODE_BD_DOUBLE_DOWN_AND_LEFT: case UNICODE_BD_DOUBLE_UP_AND_RIGHT: case UNICODE_BD_DOUBLE_UP_AND_LEFT: case UNICODE_BD_DOUBLE_VERTICAL_AND_RIGHT: case UNICODE_BD_DOUBLE_VERTICAL_AND_LEFT: case UNICODE_BD_DOUBLE_DOWN_AND_HORIZONTAL: case UNICODE_BD_DOUBLE_UP_AND_HORIZONTAL: case UNICODE_BD_DOUBLE_VERTICAL_AND_HORIZONTAL: case UNICODE_BLACK_SQUARE: return (ULONG)'+'; case UNICODE_HAIR_SPACE: case UNICODE_ZERO_WIDTH_SPACE: case UNICODE_ZERO_WIDTH_NON_JOINER: case UNICODE_ZERO_WIDTH_JOINER: case UNICODE_LEFT_TO_RIGHT_MARK: case UNICODE_RIGHT_TO_LEFT_MARK: case UNICODE_LEFT_TO_RIGHT_EMBEDDING: case UNICODE_RIGHT_TO_LEFT_EMBEDDING: case UNICODE_POP_DIRECTIONAL_FORMATTING: case UNICODE_LEFT_TO_RIGHT_OVERRIDE: case UNICODE_RIGHT_TO_LEFT_OVERRIDE: case UNICODE_ZERO_WIDTH_NO_BREAK_SPACE: return IGNORE_CHARACTER; default: break; } if (usChar == UNICODE_TRADEMARK_SIGN) { /* * No local representation, it doesn't look like anything in * US-ASCII and a question mark does more harm than good. */ return IGNORE_CHARACTER; } if (usChar >= 0xa0 && usChar <= 0xff) { /* Before Word 97, Word did't use Unicode */ return (ULONG)usChar; } DBG_HEX_C(usChar < 0x3000 || usChar >= 0xd800, ulFileOffset); DBG_HEX_C(usChar < 0x3000 || usChar >= 0xd800, usChar); DBG_MSG_C(usChar >= 0xe000 && usChar < 0xf900, "Private Use Area"); /* Untranslated Unicode character */ return 0x3f; } /* end of ulTranslateCharacters */
/* * bReadCharacterMappingTable - read the mapping table * * Read the character mapping table from file and have the contents sorted * * returns TRUE if successful, otherwise FALSE */ BOOL bReadCharacterMappingTable(FILE *pFile) { char *pcTmp; ULONG ulUnicode; UINT uiLocal; int iFields; char szLine[81]; if (pFile == NULL) { return FALSE; } /* Clean the table first */ (void)memset(atCharTable, 0, sizeof(atCharTable)); /* Fill the table */ while (fgets(szLine, (int)sizeof(szLine), pFile)) { if (szLine[0] == '#' || szLine[0] == '\r' || szLine[0] == '\n') { /* Comment or empty line */ continue; } iFields = sscanf(szLine, "%x %lx %*s", &uiLocal, &ulUnicode); if (iFields != 2) { pcTmp = strchr(szLine, '\r'); if (pcTmp != NULL) { *pcTmp = '\0'; } pcTmp = strchr(szLine, '\n'); if (pcTmp != NULL) { *pcTmp = '\0'; } werr(0, "Syntax error in: '%s'", szLine); continue; } if (uiLocal > 0xff || ulUnicode > 0xffff) { werr(0, "Syntax error in: '%02x %04lx'", uiLocal, ulUnicode); continue; } /* Store only the relevant entries */ if (uiLocal != ulUnicode || uiLocal >= 0x80) { atCharTable[tNextPosFree].ucLocal = (UCHAR)uiLocal; atCharTable[tNextPosFree].usUnicode = (USHORT)ulUnicode; tNextPosFree++; } if (tNextPosFree >= elementsof(atCharTable)) { werr(0, "Too many entries in the character mapping " "file. Ignoring the rest."); break; } } if (tNextPosFree != 0) { DBG_HEX(atCharTable[0].usUnicode); DBG_HEX(atCharTable[tNextPosFree - 1].usUnicode); qsort(atCharTable, tNextPosFree, sizeof(atCharTable[0]), iCompare); DBG_HEX(atCharTable[0].usUnicode); DBG_HEX(atCharTable[tNextPosFree - 1].usUnicode); } return TRUE; } /* end of bReadCharacterMappingTable */
/* * Fill the style information block with information * from a Word 8/9/10/11 file. */ void vGet8StyleInfo(int iFodo, const UCHAR *aucGrpprl, int iBytes, style_block_type *pStyle) { list_block_type tList6; const list_block_type *pList; int iFodoOff, iInfoLen; int iTmp, iDel, iAdd, iBefore; USHORT usOpCode, usTmp; short sTmp; fail(iFodo < 0 || aucGrpprl == NULL || pStyle == NULL); NO_DBG_DEC_C(pStyle->usListIndex != 0, pStyle->usIstd); NO_DBG_DEC_C(pStyle->usListIndex != 0, pStyle->usListIndex); (void)memset(&tList6, 0, sizeof(tList6)); iFodoOff = 0; while (iBytes >= iFodoOff + 2) { iInfoLen = 0; usOpCode = usGetWord(iFodo + iFodoOff, aucGrpprl); switch (usOpCode) { case 0x2403: /* jc */ pStyle->ucAlignment = ucGetByte( iFodo + iFodoOff + 2, aucGrpprl); break; case 0x260a: /* ilvl */ pStyle->ucListLevel = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); NO_DBG_DEC(pStyle->ucListLevel); pStyle->ucNumLevel = pStyle->ucListLevel; break; case 0x4600: /* istd */ usTmp = usGetWord(iFodo + iFodoOff + 2, aucGrpprl); NO_DBG_DEC(usTmp); break; case 0x460b: /* ilfo */ pStyle->usListIndex = usGetWord(iFodo + iFodoOff + 2, aucGrpprl); NO_DBG_DEC(pStyle->usListIndex); break; case 0x4610: /* Nest dxaLeft */ sTmp = (short)usGetWord( iFodo + iFodoOff + 2, aucGrpprl); pStyle->sLeftIndent += sTmp; if (pStyle->sLeftIndent < 0) { pStyle->sLeftIndent = 0; } DBG_DEC(sTmp); DBG_DEC(pStyle->sLeftIndent); break; case 0xc60d: /* ChgTabsPapx */ case 0xc615: /* ChgTabs */ iTmp = (int)ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); if (iTmp < 2) { iInfoLen = 1; break; } NO_DBG_DEC(iTmp); iDel = (int)ucGetByte(iFodo + iFodoOff + 3, aucGrpprl); if (iTmp < 2 + 2 * iDel) { iInfoLen = 1; break; } NO_DBG_DEC(iDel); iAdd = (int)ucGetByte( iFodo + iFodoOff + 4 + 2 * iDel, aucGrpprl); if (iTmp < 2 + 2 * iDel + 2 * iAdd) { iInfoLen = 1; break; } NO_DBG_DEC(iAdd); break; case 0x840e: /* dxaRight */ pStyle->sRightIndent = (short)usGetWord( iFodo + iFodoOff + 2, aucGrpprl); NO_DBG_DEC(pStyle->sRightIndent); break; case 0x840f: /* dxaLeft */ pStyle->sLeftIndent = (short)usGetWord( iFodo + iFodoOff + 2, aucGrpprl); NO_DBG_DEC(pStyle->sLeftIndent); break; case 0x8411: /* dxaLeft1 */ pStyle->sLeftIndent1 = (short)usGetWord( iFodo + iFodoOff + 2, aucGrpprl); NO_DBG_DEC(pStyle->sLeftIndent1); break; case 0xa413: /* dyaBefore */ pStyle->usBeforeIndent = usGetWord( iFodo + iFodoOff + 2, aucGrpprl); NO_DBG_DEC(pStyle->usBeforeIndent); break; case 0xa414: /* dyaAfter */ pStyle->usAfterIndent = usGetWord( iFodo + iFodoOff + 2, aucGrpprl); NO_DBG_DEC(pStyle->usAfterIndent); break; case 0xc63e: /* anld */ iTmp = (int)ucGetByte( iFodo + iFodoOff + 2, aucGrpprl); DBG_DEC_C(iTmp < 84, iTmp); if (iTmp >= 1) { tList6.ucNFC = ucGetByte( iFodo + iFodoOff + 3, aucGrpprl); } if (tList6.ucNFC != LIST_BULLETS && iTmp >= 2) { iBefore = (int)ucGetByte( iFodo + iFodoOff + 4, aucGrpprl); } else { iBefore = 0; } if (iTmp >= 12) { tList6.ulStartAt = (ULONG)usGetWord( iFodo + iFodoOff + 13, aucGrpprl); } if (iTmp >= iBefore + 22) { tList6.usListChar = usGetWord( iFodo + iFodoOff + iBefore + 23, aucGrpprl); DBG_HEX(tList6.usListChar); } break; default: NO_DBG_HEX(usOpCode); break; } if (iInfoLen <= 0) { iInfoLen = iGet8InfoLength(iFodo + iFodoOff, aucGrpprl); fail(iInfoLen <= 0); } iFodoOff += iInfoLen; } if (pStyle->usListIndex == 2047) { /* Old style list */ pStyle->usStartAt = (USHORT)tList6.ulStartAt; pStyle->usListChar = tList6.usListChar; pStyle->ucNFC = tList6.ucNFC; } else { /* New style list */ pList = pGetListInfo(pStyle->usListIndex, pStyle->ucListLevel); if (pList != NULL) { pStyle->bNoRestart = pList->bNoRestart; fail(pList->ulStartAt > (ULONG)USHRT_MAX); pStyle->usStartAt = (USHORT)pList->ulStartAt; pStyle->usListChar = pList->usListChar; pStyle->ucNFC = pList->ucNFC; if (pStyle->sLeftIndent <= 0) { pStyle->sLeftIndent = pList->sLeftIndent; } } } } /* end of vGet8StyleInfo */
/* * vPrintPDF - print a PDF string */ static void vPrintPDF(FILE *pFile, const char *szString, size_t tStringLength, USHORT usFontstyle) { const UCHAR *aucBytes; double dMove; size_t tCount; fail(szString == NULL); if (szString == NULL || szString[0] == '\0' || tStringLength == 0) { return; } DBG_DEC_C(usFontSizeCurr < MIN_FONT_SIZE, usFontSizeCurr); dMove = 0.0; /* Up for superscript */ if (bIsSuperscript(usFontstyle) && usFontSizeCurr != 0) { dMove = (double)((usFontSizeCurr + 1) / 2) * 0.375; vFPprintf(pFile, "%.2f Ts\n", dMove); } /* Down for subscript */ if (bIsSubscript(usFontstyle) && usFontSizeCurr != 0) { dMove = (double)usFontSizeCurr * 0.125; vFPprintf(pFile, "%.2f Ts\n", -dMove); } /* Generate and print the PDF output */ aucBytes = (UCHAR *)szString; vFPprintf(pFile, "("); for (tCount = 0; tCount < tStringLength ; tCount++) { switch (aucBytes[tCount]) { case '(': case ')': case '\\': vFPprintf(pFile, "\\%c", szString[tCount]); break; default: if (aucBytes[tCount] < 0x20 || aucBytes[tCount] == 0x7f || (aucBytes[tCount] >= 0x81 && aucBytes[tCount] < 0x8c)) { DBG_HEX(aucBytes[tCount]); vFPprintf(pFile, " "); } else if (aucBytes[tCount] >= 0x80) { vFPprintf(pFile, "\\%03o", (UINT)aucBytes[tCount]); } else { vFPprintf(pFile, "%c", szString[tCount]); } break; } } vFPprintf(pFile, ") Tj\n"); /* Undo the superscript/subscript move */ if (dMove != 0.0) { vFPprintf(pFile, "0 Ts\n"); } } /* end of vPrintPDF */
/* * vSet2SummaryInfo - set summary information from a WinWord 1/2 file */ void vSet2SummaryInfo(FILE *pFile, int iWordVersion, const UCHAR *aucHeader) { UCHAR *aucBuffer; ULONG ulBeginSumdInfo, ulBeginDocpInfo, ulTmp; size_t tSumdInfoLen, tDocpInfoLen, tLen, tCounter, tStart; TRACE_MSG("vSet2SummaryInfo"); fail(pFile == NULL || aucHeader == NULL); fail(iWordVersion != 1 && iWordVersion != 2); /* First check the header */ usLid = usGetWord(0x06, aucHeader); /* Language IDentification */ DBG_HEX(usLid); if (usLid < 999 && iWordVersion == 1) { switch (usLid) { case 1: usLid = 0x0409; break; /* American English */ case 2: usLid = 0x0c0c; break; /* Canadian French */ case 31: usLid = 0x0413; break; /* Dutch */ case 33: usLid = 0x040c; break; /* French */ case 34: usLid = 0x040a; break; /* Spanish */ case 36: usLid = 0x040e; break; /* Hungarian */ case 39: usLid = 0x0410; break; /* Italian */ case 44: usLid = 0x0809; break; /* British English */ case 45: usLid = 0x0406; break; /* Danish */ case 46: usLid = 0x041f; break; /* Swedish */ case 47: usLid = 0x0414; break; /* Norwegian */ case 48: usLid = 0x0415; break; /* Polish */ case 49: usLid = 0x0407; break; /* German */ case 351: usLid = 0x0816; break; /* Portuguese */ case 358: usLid = 0x040b; break; /* Finnish */ default: DBG_DEC(usLid); DBG_FIXME(); usLid = 0x0409; /* American English */ break; } } if (iWordVersion != 2) { /* Unknown where to find the associated strings */ return; } /* Second check the associated strings */ ulBeginSumdInfo = ulGetLong(0x118, aucHeader); /* fcSttbfAssoc */ DBG_HEX(ulBeginSumdInfo); tSumdInfoLen = (size_t)usGetWord(0x11c, aucHeader); /* cbSttbfAssoc */ DBG_DEC(tSumdInfoLen); if (tSumdInfoLen == 0) { /* There is no summary information */ return; } aucBuffer = xmalloc(tSumdInfoLen); if (!bReadBytes(aucBuffer, tSumdInfoLen, ulBeginSumdInfo, pFile)) { aucBuffer = xfree(aucBuffer); return; } NO_DBG_PRINT_BLOCK(aucBuffer, tSumdInfoLen); tLen = (size_t)ucGetByte(0, aucBuffer); DBG_DEC_C(tSumdInfoLen != tLen, tSumdInfoLen); DBG_DEC_C(tSumdInfoLen != tLen, tLen); tStart = 1; for (tCounter = 0; tCounter < 17; tCounter++) { if (tStart >= tSumdInfoLen) { break; } tLen = (size_t)ucGetByte(tStart, aucBuffer); if (tLen != 0) { NO_DBG_DEC(tCounter); NO_DBG_STRN(aucBuffer + tStart + 1, tLen); switch (tCounter) { case 3: szTitle = xmalloc(tLen + 1); strncpy(szTitle, (char *)aucBuffer + tStart + 1, tLen); szTitle[tLen] = '\0'; break; case 4: szSubject = xmalloc(tLen + 1); strncpy(szSubject, (char *)aucBuffer + tStart + 1, tLen); szSubject[tLen] = '\0'; break; case 7: szAuthor = xmalloc(tLen + 1); strncpy(szAuthor, (char *)aucBuffer + tStart + 1, tLen); szAuthor[tLen] = '\0'; break; default: break; } } tStart += tLen + 1; } aucBuffer = xfree(aucBuffer); /* Third check the document properties */ ulBeginDocpInfo = ulGetLong(0x112, aucHeader); /* fcDop */ DBG_HEX(ulBeginDocpInfo); tDocpInfoLen = (size_t)usGetWord(0x116, aucHeader); /* cbDop */ DBG_DEC(tDocpInfoLen); if (tDocpInfoLen < 12) { return; } aucBuffer = xmalloc(tDocpInfoLen); if (!bReadBytes(aucBuffer, tDocpInfoLen, ulBeginDocpInfo, pFile)) { aucBuffer = xfree(aucBuffer); return; } ulTmp = ulGetLong(0x14, aucBuffer); /* dttmCreated */ tCreateDtm = tConvertDTTM(ulTmp); ulTmp = ulGetLong(0x18, aucBuffer); /* dttmRevised */ tLastSaveDtm = tConvertDTTM(ulTmp); aucBuffer = xfree(aucBuffer); } /* end of vSet2SummaryInfo */
/* * Build the lists with Paragraph Information for WinWord 1/2 files */ void vGet2PapInfo(FILE *pFile, const UCHAR *aucHeader) { row_block_type tRow; style_block_type tStyle; USHORT *ausParfPage; UCHAR *aucBuffer; ULONG ulCharPos, ulCharPosFirst, ulCharPosLast; ULONG ulBeginParfInfo; size_t tParfInfoLen, tParfPageNum, tOffset, tSize, tLenOld, tLen; int iIndex, iIndex2, iRun, iFodo, iLen; row_info_enum eRowInfo; USHORT usParfFirstPage, usCount, usIstd; UCHAR ucStc; UCHAR aucFpage[BIG_BLOCK_SIZE]; fail(pFile == NULL || aucHeader == NULL); ulBeginParfInfo = ulGetLong(0xa6, aucHeader); /* fcPlcfbtePapx */ NO_DBG_HEX(ulBeginParfInfo); tParfInfoLen = (size_t)usGetWord(0xaa, aucHeader); /* cbPlcfbtePapx */ NO_DBG_DEC(tParfInfoLen); if (tParfInfoLen < 4) { DBG_DEC(tParfInfoLen); return; } aucBuffer = xmalloc(tParfInfoLen); if (!bReadBytes(aucBuffer, tParfInfoLen, ulBeginParfInfo, pFile)) { aucBuffer = xfree(aucBuffer); return; } NO_DBG_PRINT_BLOCK(aucBuffer, tParfInfoLen); tLen = (tParfInfoLen - 4) / 6; ausParfPage = xcalloc(tLen, sizeof(USHORT)); for (iIndex = 0, tOffset = (tLen + 1) * 4; iIndex < (int)tLen; iIndex++, tOffset += 2) { ausParfPage[iIndex] = usGetWord(tOffset, aucBuffer); NO_DBG_DEC(ausParfPage[iIndex]); } DBG_HEX(ulGetLong(0, aucBuffer)); aucBuffer = xfree(aucBuffer); tParfPageNum = (size_t)usGetWord(0x144, aucHeader); /* cpnBtePap */ DBG_DEC(tParfPageNum); if (tLen < tParfPageNum) { /* Replace ParfPage by a longer version */ tLenOld = tLen; usParfFirstPage = usGetWord(0x140, aucHeader); /* pnPapFirst */ DBG_DEC(usParfFirstPage); tLen += tParfPageNum - 1; tSize = tLen * sizeof(USHORT); ausParfPage = xrealloc(ausParfPage, tSize); /* Add new values */ usCount = usParfFirstPage + 1; for (iIndex = (int)tLenOld; iIndex < (int)tLen; iIndex++) { ausParfPage[iIndex] = usCount; NO_DBG_DEC(ausParfPage[iIndex]); usCount++; } } (void)memset(&tRow, 0, sizeof(tRow)); ulCharPosFirst = CP_INVALID; for (iIndex = 0; iIndex < (int)tLen; iIndex++) { if (!bReadBytes(aucFpage, BIG_BLOCK_SIZE, (ULONG)ausParfPage[iIndex] * BIG_BLOCK_SIZE, pFile)) { break; } NO_DBG_PRINT_BLOCK(aucFpage, BIG_BLOCK_SIZE); iRun = (int)ucGetByte(0x1ff, aucFpage); NO_DBG_DEC(iRun); for (iIndex2 = 0; iIndex2 < iRun; iIndex2++) { if ((iRun + 1) * 4 + iIndex2 * 1 >= BIG_BLOCK_SIZE) { break; } NO_DBG_HEX(ulGetLong(iIndex2 * 4, aucFpage)); iFodo = 2 * (int)ucGetByte( (iRun + 1) * 4 + iIndex2 * 1, aucFpage); if (iFodo <= 0) { continue; } iLen = 2 * (int)ucGetByte(iFodo, aucFpage); ucStc = ucGetByte(iFodo + 1, aucFpage); usIstd = usStc2istd(ucStc); vFillStyleFromStylesheet(usIstd, &tStyle); vGet2StyleInfo(iFodo, aucFpage + 8, iLen - 8, &tStyle); ulCharPos = ulGetLong(iIndex2 * 4, aucFpage); NO_DBG_HEX(ulCharPos); tStyle.ulFileOffset = ulCharPos; vAdd2StyleInfoList(&tStyle); eRowInfo = eGet2RowInfo(iFodo, aucFpage + 8, iLen - 8, &tRow); switch(eRowInfo) { case found_a_cell: if (ulCharPosFirst != CP_INVALID) { break; } ulCharPosFirst = ulGetLong( iIndex2 * 4, aucFpage); NO_DBG_HEX(ulCharPosFirst); tRow.ulCharPosStart = ulCharPosFirst; tRow.ulFileOffsetStart = ulCharPosFirst; break; case found_end_of_row: ulCharPosLast = ulGetLong( iIndex2 * 4, aucFpage); NO_DBG_HEX(ulCharPosLast); tRow.ulCharPosEnd = ulCharPosLast; /* Add 1 for compatiblity with Word 6 and up */ tRow.ulFileOffsetEnd = ulCharPosLast + 1; vAdd2RowInfoList(&tRow); (void)memset(&tRow, 0, sizeof(tRow)); ulCharPosFirst = CP_INVALID; break; case found_nothing: break; default: DBG_DEC(eRowInfo); break; } } } ausParfPage = xfree(ausParfPage); } /* end of vGet2PapInfo */
/* * Build the list with List Information for Word 8/9/10/11 files */ void vGet8LstInfo(FILE *pFile, const pps_info_type *pPPS, const ULONG *aulBBD, size_t tBBDLen, const ULONG *aulSBD, size_t tSBDLen, const UCHAR *aucHeader) { list_block_type tList; const ULONG *aulBlockDepot; UCHAR *aucLfoInfo, *aucLstfInfo, *aucPapx, *aucXString; ULONG ulBeginLfoInfo, ulBeginLstfInfo, ulBeginLvlfInfo; ULONG ulListID, ulStart; size_t tBlockDepotLen, tBlockSize; size_t tLfoInfoLen, tLstfInfoLen, tPapxLen, tXstLen, tOff; size_t tLstfRecords, tStart, tIndex; int iNums; USHORT usIstd; UCHAR ucTmp, ucListLevel, ucMaxLevel, ucChpxLen; UCHAR aucLvlfInfo[28], aucXst[2]; fail(pFile == NULL || pPPS == NULL || aucHeader == NULL); fail(aulBBD == NULL || aulSBD == NULL); NO_DBG_DEC(pPPS->tTable.ulSB); NO_DBG_HEX(pPPS->tTable.ulSize); if (pPPS->tTable.ulSize == 0) { DBG_MSG("No list information"); return; } if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) { /* Use the Small Block Depot */ aulBlockDepot = aulSBD; tBlockDepotLen = tSBDLen; tBlockSize = SMALL_BLOCK_SIZE; } else { /* Use the Big Block Depot */ aulBlockDepot = aulBBD; tBlockDepotLen = tBBDLen; tBlockSize = BIG_BLOCK_SIZE; } /* LFO (List Format Override) */ ulBeginLfoInfo = ulGetLong(0x2ea, aucHeader); /* fcPlfLfo */ DBG_HEX(ulBeginLfoInfo); tLfoInfoLen = (size_t)ulGetLong(0x2ee, aucHeader); /* lcbPlfLfo */ DBG_DEC(tLfoInfoLen); if (tLfoInfoLen == 0) { DBG_MSG("No lists in this document"); return; } aucLfoInfo = xmalloc(tLfoInfoLen); if (!bReadBuffer(pFile, pPPS->tTable.ulSB, aulBlockDepot, tBlockDepotLen, tBlockSize, aucLfoInfo, ulBeginLfoInfo, tLfoInfoLen)) { aucLfoInfo = xfree(aucLfoInfo); return; } NO_DBG_PRINT_BLOCK(aucLfoInfo, tLfoInfoLen); vBuildLfoList(aucLfoInfo, tLfoInfoLen); aucLfoInfo = xfree(aucLfoInfo); /* LSTF (LiST data on File) */ ulBeginLstfInfo = ulGetLong(0x2e2, aucHeader); /* fcPlcfLst */ DBG_HEX(ulBeginLstfInfo); tLstfInfoLen = (size_t)ulGetLong(0x2e6, aucHeader); /* lcbPlcfLst */ DBG_DEC(tLstfInfoLen); if (tLstfInfoLen == 0) { DBG_MSG("No list data on file"); return; } aucLstfInfo = xmalloc(tLstfInfoLen); if (!bReadBuffer(pFile, pPPS->tTable.ulSB, aulBlockDepot, tBlockDepotLen, tBlockSize, aucLstfInfo, ulBeginLstfInfo, tLstfInfoLen)) { aucLstfInfo = xfree(aucLstfInfo); return; } NO_DBG_PRINT_BLOCK(aucLstfInfo, tLstfInfoLen); tLstfRecords = (size_t)usGetWord(0, aucLstfInfo); if (2 + tLstfRecords * 28 < tLstfInfoLen) { DBG_DEC(2 + tLstfRecords * 28); DBG_DEC(tLstfInfoLen); aucLstfInfo = xfree(aucLstfInfo); return; } /* LVLF (List leVeL on File) */ ulBeginLvlfInfo = ulBeginLstfInfo + tLstfInfoLen; DBG_HEX(ulBeginLvlfInfo); aucXString = NULL; ulStart = ulBeginLvlfInfo; for (tIndex = 0, tStart = 2; tIndex < tLstfRecords; tIndex++, tStart += 28) { ulListID = ulGetLong(tStart, aucLstfInfo); NO_DBG_HEX(ulListID); ucTmp = ucGetByte(tStart + 26, aucLstfInfo); ucMaxLevel = odd(ucTmp) ? 1 : 9; for (ucListLevel = 0; ucListLevel < ucMaxLevel; ucListLevel++) { fail(aucXString != NULL); usIstd = usGetWord( tStart + 8 + 2 * (size_t)ucListLevel, aucLstfInfo); DBG_DEC_C(usIstd != STI_NIL, usIstd); NO_DBG_HEX(ulStart); (void)memset(&tList, 0, sizeof(tList)); /* Read the lvlf (List leVeL on File) */ if (!bReadBuffer(pFile, pPPS->tTable.ulSB, aulBlockDepot, tBlockDepotLen, tBlockSize, aucLvlfInfo, ulStart, sizeof(aucLvlfInfo))) { aucLstfInfo = xfree(aucLstfInfo); return; } NO_DBG_PRINT_BLOCK(aucLvlfInfo, sizeof(aucLvlfInfo)); if (bAllZero(aucLvlfInfo, sizeof(aucLvlfInfo))) { tList.ulStartAt = 1; tList.ucNFC = 0x00; tList.bNoRestart = FALSE; } else { tList.ulStartAt = ulGetLong(0, aucLvlfInfo); tList.ucNFC = ucGetByte(4, aucLvlfInfo); ucTmp = ucGetByte(5, aucLvlfInfo); tList.bNoRestart = (ucTmp & BIT(3)) != 0; DBG_MSG_C((ucTmp & BIT(4)) != 0 && (ucTmp & BIT(6)) != 0, "Found one"); } ulStart += sizeof(aucLvlfInfo); tPapxLen = (size_t)ucGetByte(25, aucLvlfInfo); if (tPapxLen != 0) { aucPapx = xmalloc(tPapxLen); /* Read the Papx */ if (!bReadBuffer(pFile, pPPS->tTable.ulSB, aulBlockDepot, tBlockDepotLen, tBlockSize, aucPapx, ulStart, tPapxLen)) { aucPapx = xfree(aucPapx); aucLstfInfo = xfree(aucLstfInfo); return; } NO_DBG_PRINT_BLOCK(aucPapx, tPapxLen); tList.sLeftIndent = sGetLeftIndent(aucPapx, tPapxLen); aucPapx = xfree(aucPapx); } ulStart += tPapxLen; ucChpxLen = ucGetByte(24, aucLvlfInfo); ulStart += (ULONG)ucChpxLen; /* Read the length of the XString */ if (!bReadBuffer(pFile, pPPS->tTable.ulSB, aulBlockDepot, tBlockDepotLen, tBlockSize, aucXst, ulStart, sizeof(aucXst))) { aucLstfInfo = xfree(aucLstfInfo); return; } NO_DBG_PRINT_BLOCK(aucXst, sizeof(aucXst)); tXstLen = (size_t)usGetWord(0, aucXst); ulStart += sizeof(aucXst); if (tXstLen == 0) { tList.usListChar = DEFAULT_LISTCHAR; vAdd2ListInfoList(ulListID, usIstd, ucListLevel, &tList); continue; } tXstLen *= 2; /* Length in chars to length in bytes */ aucXString = xmalloc(tXstLen); /* Read the XString */ if (!bReadBuffer(pFile, pPPS->tTable.ulSB, aulBlockDepot, tBlockDepotLen, tBlockSize, aucXString, ulStart, tXstLen)) { aucXString = xfree(aucXString); aucLstfInfo = xfree(aucLstfInfo); return; } NO_DBG_PRINT_BLOCK(aucXString, tXstLen); tOff = 0; for (iNums = 6; iNums < 15; iNums++) { ucTmp = ucGetByte(iNums, aucLvlfInfo); if (ucTmp == 0) { break; } tOff = (size_t)ucTmp; } tOff *= 2; /* Offset in chars to offset in bytes */ NO_DBG_DEC(tOff); if (tList.ucNFC == LIST_SPECIAL || tList.ucNFC == LIST_SPECIAL2 || tList.ucNFC == LIST_BULLETS) { tList.usListChar = usGetWord(0, aucXString); } else if (tOff != 0 && tOff < tXstLen) { tList.usListChar = usGetWord(tOff, aucXString); } else { tList.usListChar = DEFAULT_LISTCHAR; } vAdd2ListInfoList(ulListID, usIstd, ucListLevel, &tList); ulStart += tXstLen; aucXString = xfree(aucXString); } } aucLstfInfo = xfree(aucLstfInfo); } /* end of vGet8LstInfo */
/* * Build the lists with Character Information for Word 8/9/10/11 files */ void vGet8ChrInfo(FILE *pFile, const pps_info_type *pPPS, const ULONG *aulBBD, size_t tBBDLen, const ULONG *aulSBD, size_t tSBDLen, const UCHAR *aucHeader) { font_block_type tFont; picture_block_type tPicture; ULONG *aulCharPage; UCHAR *aucBuffer; ULONG ulFileOffset, ulCharPos, ulBeginCharInfo; size_t tCharInfoLen, tOffset, tLen; int iIndex, iIndex2, iRun, iFodo, iLen; USHORT usIstd; UCHAR aucFpage[BIG_BLOCK_SIZE]; fail(pFile == NULL || pPPS == NULL || aucHeader == NULL); fail(aulBBD == NULL || aulSBD == NULL); ulBeginCharInfo = ulGetLong(0xfa, aucHeader); /* fcPlcfbteChpx */ NO_DBG_HEX(ulBeginCharInfo); tCharInfoLen = (size_t)ulGetLong(0xfe, aucHeader); /* lcbPlcfbteChpx */ NO_DBG_DEC(tCharInfoLen); if (tCharInfoLen < 4) { DBG_DEC(tCharInfoLen); return; } aucBuffer = aucFillInfoBuffer(pFile, &pPPS->tTable, aulBBD, tBBDLen, aulSBD, tSBDLen, ulBeginCharInfo, tCharInfoLen); if (aucBuffer == NULL) { return; } NO_DBG_PRINT_BLOCK(aucBuffer, tCharInfoLen); tLen = (tCharInfoLen / 4 - 1) / 2; aulCharPage = xcalloc(tLen, sizeof(ULONG)); for (iIndex = 0, tOffset = (tLen + 1) * 4; iIndex < (int)tLen; iIndex++, tOffset += 4) { aulCharPage[iIndex] = ulGetLong(tOffset, aucBuffer); NO_DBG_DEC(aulCharPage[iIndex]); } DBG_HEX(ulGetLong(0, aucBuffer)); aucBuffer = xfree(aucBuffer); NO_DBG_PRINT_BLOCK(aucHeader, HEADER_SIZE); for (iIndex = 0; iIndex < (int)tLen; iIndex++) { fail(aulCharPage[iIndex] > ULONG_MAX / BIG_BLOCK_SIZE); if (!bReadBuffer(pFile, pPPS->tWordDocument.ulSB, aulBBD, tBBDLen, BIG_BLOCK_SIZE, aucFpage, aulCharPage[iIndex] * BIG_BLOCK_SIZE, BIG_BLOCK_SIZE)) { break; } NO_DBG_PRINT_BLOCK(aucFpage, BIG_BLOCK_SIZE); iRun = (int)ucGetByte(0x1ff, aucFpage); NO_DBG_DEC(iRun); for (iIndex2 = 0; iIndex2 < iRun; iIndex2++) { ulCharPos = ulGetLong(iIndex2 * 4, aucFpage); ulFileOffset = ulCharPos2FileOffset(ulCharPos); iFodo = 2 * (int)ucGetByte( (iRun + 1) * 4 + iIndex2, aucFpage); iLen = (int)ucGetByte(iFodo, aucFpage); usIstd = usGetIstd(ulFileOffset); vFillFontFromStylesheet(usIstd, &tFont); if (iFodo != 0) { vGet8FontInfo(iFodo, usIstd, aucFpage + 1, iLen - 1, &tFont); } tFont.ulFileOffset = ulFileOffset; vAdd2FontInfoList(&tFont); if (iFodo <= 0) { continue; } (void)memset(&tPicture, 0, sizeof(tPicture)); if (bGet8PicInfo(iFodo, aucFpage + 1, iLen - 1, &tPicture)) { tPicture.ulFileOffset = ulFileOffset; tPicture.ulFileOffsetPicture =ulDataPos2FileOffset(tPicture.ulPictureOffset); vAdd2PictInfoList(&tPicture); } } } aulCharPage = xfree(aulCharPage); } /* end of vGet8ChrInfo */
/* * szGetLanguage - get de language field */ const char * szGetLanguage(void) { if (usLid == (USHORT)-1) { /* No Language IDentification */ return NULL; } if (usLid < 999) { /* This is a Locale, not a Language IDentification */ DBG_DEC(usLid); return NULL; } /* Exceptions to the general rule */ switch (usLid) { case 0x0404: return "zh_TW"; /* Traditional Chinese */ case 0x0804: return "zh_CN"; /* Simplified Chinese */ case 0x0c04: return "zh_HK"; /* Hong Kong Chinese */ case 0x1004: return "zh_SG"; /* Singapore Chinese */ case 0x0807: return "de_CH"; /* Swiss German */ case 0x0409: return "en_US"; /* American English */ case 0x0809: return "en_GB"; /* British English */ case 0x0c09: return "en_AU"; /* Australian English */ case 0x080a: return "es_MX"; /* Mexican Spanish */ case 0x080c: return "fr_BE"; /* Belgian French */ case 0x0c0c: return "fr_CA"; /* Canadian French */ case 0x100c: return "fr_CH"; /* Swiss French */ case 0x0810: return "it_CH"; /* Swiss Italian */ case 0x0813: return "nl_BE"; /* Belgian Dutch */ case 0x0416: return "pt_BR"; /* Brazilian Portuguese */ case 0x081a: case 0x0c1a: return "sr"; /* Serbian */ case 0x081d: return "sv_FI"; /* Finland Swedish */ default: break; } /* The general rule */ switch (usLid & 0x00ff) { case 0x01: return "ar"; /* Arabic */ case 0x02: return "bg"; /* Bulgarian */ case 0x03: return "ca"; /* Catalan */ case 0x04: return "zh"; /* Chinese */ case 0x05: return "cs"; /* Czech */ case 0x06: return "da"; /* Danish */ case 0x07: return "de"; /* German */ case 0x08: return "el"; /* Greek */ case 0x09: return "en"; /* English */ case 0x0a: return "es"; /* Spanish */ case 0x0b: return "fi"; /* Finnish */ case 0x0c: return "fr"; /* French */ case 0x0d: return "he"; /* Hebrew */ case 0x0e: return "hu"; /* Hungarian */ case 0x0f: return "is"; /* Icelandic */ case 0x10: return "it"; /* Italian */ case 0x11: return "ja"; /* Japanese */ case 0x12: return "ko"; /* Korean */ case 0x13: return "nl"; /* Dutch */ case 0x14: return "no"; /* Norwegian */ case 0x15: return "pl"; /* Polish */ case 0x16: return "pt"; /* Portuguese */ case 0x17: return "rm"; /* Rhaeto-Romance */ case 0x18: return "ro"; /* Romanian */ case 0x19: return "ru"; /* Russian */ case 0x1a: return "hr"; /* Croatian */ case 0x1b: return "sk"; /* Slovak */ case 0x1c: return "sq"; /* Albanian */ case 0x1d: return "sv"; /* Swedish */ case 0x1e: return "th"; /* Thai */ case 0x1f: return "tr"; /* Turkish */ case 0x20: return "ur"; /* Urdu */ case 0x21: return "id"; /* Indonesian */ case 0x22: return "uk"; /* Ukrainian */ case 0x23: return "be"; /* Belarusian */ case 0x24: return "sl"; /* Slovenian */ case 0x25: return "et"; /* Estonian */ case 0x26: return "lv"; /* Latvian */ case 0x27: return "lt"; /* Lithuanian */ case 0x29: return "fa"; /* Farsi */ case 0x2a: return "vi"; /* Viet Nam */ case 0x2b: return "hy"; /* Armenian */ case 0x2c: return "az"; /* Azeri */ case 0x2d: return "eu"; /* Basque */ case 0x2f: return "mk"; /* Macedonian */ case 0x36: return "af"; /* Afrikaans */ case 0x37: return "ka"; /* Georgian */ case 0x38: return "fo"; /* Faeroese */ case 0x39: return "hi"; /* Hindi */ case 0x3e: return "ms"; /* Malay */ case 0x3f: return "kk"; /* Kazakh */ default: DBG_HEX(usLid); DBG_FIXME(); return NULL; } } /* end of szGetLanguage */
/* * Build the lists with Paragraph Information for Word 8/9/10/11 files */ void vGet8PapInfo(FILE *pFile, const pps_info_type *pPPS, const ULONG *aulBBD, size_t tBBDLen, const ULONG *aulSBD, size_t tSBDLen, const UCHAR *aucHeader) { row_block_type tRow; style_block_type tStyle; ULONG *aulParfPage; UCHAR *aucBuffer; ULONG ulCharPos, ulCharPosFirst, ulCharPosLast; ULONG ulBeginParfInfo; size_t tParfInfoLen, tOffset, tLen; int iIndex, iIndex2, iRun, iFodo, iLen; row_info_enum eRowInfo; USHORT usIstd; UCHAR aucFpage[BIG_BLOCK_SIZE]; fail(pFile == NULL || pPPS == NULL || aucHeader == NULL); fail(aulBBD == NULL || aulSBD == NULL); ulBeginParfInfo = ulGetLong(0x102, aucHeader); /* fcPlcfbtePapx */ NO_DBG_HEX(ulBeginParfInfo); tParfInfoLen = (size_t)ulGetLong(0x106, aucHeader); /* lcbPlcfbtePapx */ NO_DBG_DEC(tParfInfoLen); if (tParfInfoLen < 4) { DBG_DEC(tParfInfoLen); return; } aucBuffer = aucFillInfoBuffer(pFile, &pPPS->tTable, aulBBD, tBBDLen, aulSBD, tSBDLen, ulBeginParfInfo, tParfInfoLen); if (aucBuffer == NULL) { return; } NO_DBG_PRINT_BLOCK(aucBuffer, tParfInfoLen); tLen = (tParfInfoLen / 4 - 1) / 2; aulParfPage = xcalloc(tLen, sizeof(ULONG)); for (iIndex = 0, tOffset = (tLen + 1) * 4; iIndex < (int)tLen; iIndex++, tOffset += 4) { aulParfPage[iIndex] = ulGetLong(tOffset, aucBuffer); NO_DBG_DEC(aulParfPage[iIndex]); } DBG_HEX(ulGetLong(0, aucBuffer)); aucBuffer = xfree(aucBuffer); NO_DBG_PRINT_BLOCK(aucHeader, HEADER_SIZE); (void)memset(&tRow, 0, sizeof(tRow)); ulCharPosFirst = CP_INVALID; for (iIndex = 0; iIndex < (int)tLen; iIndex++) { fail(aulParfPage[iIndex] > ULONG_MAX / BIG_BLOCK_SIZE); if (!bReadBuffer(pFile, pPPS->tWordDocument.ulSB, aulBBD, tBBDLen, BIG_BLOCK_SIZE, aucFpage, aulParfPage[iIndex] * BIG_BLOCK_SIZE, BIG_BLOCK_SIZE)) { break; } NO_DBG_PRINT_BLOCK(aucFpage, BIG_BLOCK_SIZE); iRun = (int)ucGetByte(0x1ff, aucFpage); NO_DBG_DEC(iRun); for (iIndex2 = 0; iIndex2 < iRun; iIndex2++) { NO_DBG_HEX(ulGetLong(iIndex2 * 4, aucFpage)); iFodo = 2 * (int)ucGetByte( (iRun + 1) * 4 + iIndex2 * 13, aucFpage); if (iFodo <= 0) { continue; } iLen = 2 * (int)ucGetByte(iFodo, aucFpage); if (iLen == 0) { iFodo++; iLen = 2 * (int)ucGetByte(iFodo, aucFpage); } usIstd = usGetWord(iFodo + 1, aucFpage); vFillStyleFromStylesheet(usIstd, &tStyle); vGet8StyleInfo(iFodo, aucFpage + 3, iLen - 3, &tStyle); ulCharPos = ulGetLong(iIndex2 * 4, aucFpage); NO_DBG_HEX(ulCharPos); tStyle.ulFileOffset = ulCharPos2FileOffsetX( ulCharPos, &tStyle.eListID); vAdd2StyleInfoList(&tStyle); eRowInfo = eGet8RowInfo(iFodo, aucFpage + 3, iLen - 3, &tRow); switch (eRowInfo) { case found_a_cell: if (ulCharPosFirst != CP_INVALID) { break; } ulCharPosFirst = ulGetLong( iIndex2 * 4, aucFpage); NO_DBG_HEX(ulCharPosFirst); tRow.ulCharPosStart = ulCharPosFirst; tRow.ulFileOffsetStart = ulCharPos2FileOffset(ulCharPosFirst); NO_DBG_HEX_C( tRow.ulFileOffsetStart == FC_INVALID, ulCharPosFirst); break; case found_end_of_row: ulCharPosLast = ulGetLong( iIndex2 * 4, aucFpage); NO_DBG_HEX(ulCharPosLast); tRow.ulCharPosEnd = ulCharPosLast; tRow.ulFileOffsetEnd = ulCharPos2FileOffset(ulCharPosLast); NO_DBG_HEX_C(tRow.ulFileOffsetEnd == FC_INVALID, ulCharPosLast); vAdd2RowInfoList(&tRow); (void)memset(&tRow, 0, sizeof(tRow)); ulCharPosFirst = CP_INVALID; break; case found_nothing: break; default: DBG_DEC(eRowInfo); break; } } } aulParfPage = xfree(aulParfPage); } /* end of vGet8PapInfo */