/* -*- Mode: C++; c-default-style: "k&r"; indent-tabs-mode: nil; tab-width: 2; c-basic-offset: 2 -*- */ /* libmwaw * Version: MPL 2.0 / LGPLv2+ * * The contents of this file are subject to the Mozilla Public License Version * 2.0 (the "License"); you may not use this file except in compliance with * the License or as specified alternatively below. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * Major Contributor(s): * Copyright (C) 2002 William Lachance (wrlach@gmail.com) * Copyright (C) 2002,2004 Marc Maurer (uwog@uwog.net) * Copyright (C) 2004-2006 Fridrich Strba (fridrich.strba@bluewin.ch) * Copyright (C) 2006, 2007 Andrew Ziem * Copyright (C) 2011, 2012 Alonso Laurent (alonso@loria.fr) * * * All Rights Reserved. * * For minor contributions see the git repository. * * Alternatively, the contents of this file may be used under the terms of * the GNU Lesser General Public License Version 2 or later (the "LGPLv2+"), * in which case the provisions of the LGPLv2+ are applicable * instead of those above. */ /** \file MWAWHeader.cxx * Implements MWAWHeader (document's type, version, kind) */ #include #include #include "libmwaw_internal.hxx" #include "MWAWEntry.hxx" #include "MWAWInputStream.hxx" #include "MWAWRSRCParser.hxx" #include "MWAWHeader.hxx" MWAWHeader::MWAWHeader(MWAWDocument::Type documentType, int vers, MWAWDocument::Kind kind) : m_version(vers) , m_docType(documentType) , m_docKind(kind) { } MWAWHeader::~MWAWHeader() { } /** * So far, we have identified */ std::vector MWAWHeader::constructHeader (MWAWInputStreamPtr input, std::shared_ptr /*rsrcParser*/) { std::vector res; if (!input) return res; // ------------ first check finder info ------------- std::string type, creator; if (input->getFinderInfo(type, creator)) { // set basic version, the correct will be filled by check header if (creator=="ACTA") { if (type=="OTLN") { // at least basic v2 res.push_back(MWAWHeader(MWAWDocument::MWAW_T_ACTA, 1)); return res; } else if (type=="otln") { // classic version res.push_back(MWAWHeader(MWAWDocument::MWAW_T_ACTA, 2)); return res; } } else if (creator=="BOBO") { if (type=="CWDB" || type=="CWD2" || type=="sWDB") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CLARISWORKS, 1, MWAWDocument::MWAW_K_DATABASE)); return res; } if (type=="CWGR" || type=="sWGR") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CLARISWORKS, 1, MWAWDocument::MWAW_K_DRAW)); return res; } if (type=="CWSS" || type=="CWS2" || type=="sWSS") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CLARISWORKS, 1, MWAWDocument::MWAW_K_SPREADSHEET)); return res; } if (type=="CWPR") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CLARISWORKS, 1, MWAWDocument::MWAW_K_PRESENTATION)); return res; } if (type=="CWPT") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CLARISWORKS, 1, MWAWDocument::MWAW_K_PAINT)); return res; } if (type=="CWWP" || type=="CWW2" || type=="sWPP") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CLARISWORKS, 1, MWAWDocument::MWAW_K_TEXT)); return res; } } else if (creator=="BWks") { if (type=="BWwp") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_BEAGLEWORKS, 1)); return res; } if (type=="BWdb") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_BEAGLEWORKS, 1, MWAWDocument::MWAW_K_DATABASE)); return res; } if (type=="BWdr") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_BEAGLEWORKS, 1, MWAWDocument::MWAW_K_DRAW)); return res; } if (type=="BWpt") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_BEAGLEWORKS, 1, MWAWDocument::MWAW_K_PAINT)); return res; } if (type=="BWss") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_BEAGLEWORKS, 1, MWAWDocument::MWAW_K_SPREADSHEET)); return res; } } else if (creator=="CDrw") { if (type=="dDrw" || type=="dDst" || type=="iLib") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CLARISDRAW, 1, MWAWDocument::MWAW_K_DRAW)); return res; } } else if (creator=="CRDW") { if (type=="CKDT") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CRICKETDRAW, 1, MWAWDocument::MWAW_K_DRAW)); return res; } } else if (creator=="C#+A") { // solo if (type=="C#+D" || type=="C#+F") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_RAGTIME, 5)); return res; } } else if (creator=="Dc@P" || creator=="Dk@P") { if (type=="APPL") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_DOCMAKER, 1)); return res; } } else if (creator=="FHA2") { if (type=="FHD2" || type=="FHT2") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_FREEHAND, 2, MWAWDocument::MWAW_K_DRAW)); return res; } } else if (creator=="FS03") { if (type=="WRT+") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_WRITERPLUS, 1)); return res; } } else if (creator=="FWRT") { if (type=="FWRM") { // 1.7 ? res.push_back(MWAWHeader(MWAWDocument::MWAW_T_FULLWRITE, 1)); return res; } if (type=="FWRT") { // 1.0 ? res.push_back(MWAWHeader(MWAWDocument::MWAW_T_FULLWRITE, 1)); return res; } if (type=="FWRI") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_FULLWRITE,2)); return res; } } else if (creator=="F#+A") { // Classic if (type=="F#+D" || type=="F#+F") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_RAGTIME, 3)); return res; } } else if (creator=="GM01") { if (type=="GfMt") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MOUSEWRITE, 1)); return res; } } else if (creator=="HMiw") { // japonese if (type=="IWDC") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_HANMACWORDJ,1)); return res; } } else if (creator=="HMdr") { // korean if (type=="DRD2") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_HANMACWORDK,1)); return res; } } else if (creator=="LWTE") { if (type=="TEXT" || type=="ttro") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_LIGHTWAYTEXT,1)); return res; } } else if (creator=="LWTR") { if (type=="APPL") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_LIGHTWAYTEXT,1)); return res; } } else if (creator=="MACA") { if (type=="WORD") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACWRITE, 1)); return res; } } else if (creator=="MACD") { // v1.0 if (type=="DRWG") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDRAFT, 1, MWAWDocument::MWAW_K_DRAW)); return res; } } else if (creator=="MAXW") { if (type=="MWCT") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MAXWRITE, 1)); return res; } } else if (creator=="MD40") { if (type=="MDDC" || type=="MSYM") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDRAFT, 4, MWAWDocument::MWAW_K_DRAW)); return res; } } else if (creator=="MDFT") { // v1.2 if (type=="DRWG") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDRAFT, 1, MWAWDocument::MWAW_K_DRAW)); return res; } } else if (creator=="MDPL") { // MacDraw II if (type=="DRWG") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDRAWPRO, 0, MWAWDocument::MWAW_K_DRAW)); return res; } if (type=="STAT") { // stationery res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDRAWPRO, 0, MWAWDocument::MWAW_K_DRAW)); return res; } } else if (creator=="MDRW") { if (type=="DRWG") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDRAW, 1, MWAWDocument::MWAW_K_DRAW)); return res; } } else if (creator=="MDsr") { if (type=="APPL") { // auto content res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDOC, 1)); return res; } } else if (creator=="MDvr") { if (type=="MDdc") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDOC, 1)); return res; } } else if (creator=="MMBB") { if (type=="MBBT") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MARINERWRITE, 1)); return res; } } else if (creator=="MORE") { if (type=="MORE") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MORE, 1)); return res; } } else if (creator=="MOR2") { if (type=="MOR2") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MORE, 2)); return res; } if (type=="MOR3") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MORE, 3)); return res; } } else if (creator=="MPNT") { if (type=="PNTG") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACPAINT, 1, MWAWDocument::MWAW_K_PAINT)); return res; } } else if (creator=="MSWD") { if (type=="WDBN" || type=="GLOS") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORD, 3)); return res; } } else if (creator=="MSWK") { if (type=="AWWP") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORKS, 3)); return res; } if (type=="AWDB") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORKS, 3, MWAWDocument::MWAW_K_DATABASE)); return res; } if (type=="AWDR") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORKS, 3, MWAWDocument::MWAW_K_DRAW)); return res; } if (type=="AWSS") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORKS, 2, MWAWDocument::MWAW_K_SPREADSHEET)); return res; } if (type=="RLRB" || type=="sWRB") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORKS, 4)); return res; } } else if (creator=="MWII") { // MacWriteII if (type=="MW2D") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACWRITEPRO, 0)); return res; } } else if (creator=="MWPR") { if (type=="MWPd") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACWRITEPRO, 1)); return res; } } else if (creator=="NISI") { if (type=="TEXT") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_NISUSWRITER, 1)); return res; } if (type=="GLOS") { // checkme: glossary, ie. a list of picture/word, keep it ? res.push_back(MWAWHeader(MWAWDocument::MWAW_T_NISUSWRITER, 1)); return res; } // "edtt": empty file, probably created when the file is edited } else if (creator=="PANT") { if (type=="PNTG") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_FULLPAINT, 1, MWAWDocument::MWAW_K_PAINT)); return res; } } else if (creator=="PLAN") { if (type=="MPBN") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTMULTIPLAN, 1, MWAWDocument::MWAW_K_SPREADSHEET)); return res; } } else if (creator=="PIXR") { if (type=="PX01") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_PIXELPAINT, 1, MWAWDocument::MWAW_K_DRAW)); return res; } } else if (creator=="PPT3") { if (type=="SLD3") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_POWERPOINT, 3, MWAWDocument::MWAW_K_PRESENTATION)); return res; } } else if (creator=="PPNT") { if (type=="SLDS") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_POWERPOINT, 2, MWAWDocument::MWAW_K_PRESENTATION)); return res; } } else if (creator=="PSIP") { if (type=="AWWP") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORKS, 1)); return res; } } else if (creator=="PSI2") { if (type=="AWWP") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORKS, 2)); return res; } if (type=="AWDB") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORKS, 2, MWAWDocument::MWAW_K_DATABASE)); return res; } if (type=="AWSS") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORKS, 2, MWAWDocument::MWAW_K_SPREADSHEET)); return res; } } else if (creator=="PWRI") { if (type=="OUTL") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MINDWRITE, 2)); return res; } } else if (creator=="Rslv") { if (type=="RsWs") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CLARISRESOLVE, 1, MWAWDocument::MWAW_K_SPREADSHEET)); return res; } } else if (creator=="R#+A") { if (type=="R#+D" || type=="R#+F") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_RAGTIME, 3)); return res; } } else if (creator=="SPNT") { if (type=="SPTG") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_SUPERPAINT, 1, MWAWDocument::MWAW_K_PAINT)); return res; } if (type=="PNTG") { // same as MacPaint format, so use the MacPaint parser res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACPAINT, 1, MWAWDocument::MWAW_K_PAINT)); return res; } // other type seems to correspond to basic picture file, so we do not accept them } else if (creator=="StAV") { if (type=="APPL") { // Style: document application res.push_back(MWAWHeader(MWAWDocument::MWAW_T_STYLE, 1)); return res; } } else if (creator==std::string("St")+char(0xd8)+"l") { // argh, not standart character std::string type1=std::string("TEd")+char(0xb6); // argh, not standart character if (type==type1) { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_STYLE, 1)); return res; } } else if (creator=="TBB5") { if (type=="TEXT" || type=="ttro") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_TEXEDIT, 1)); return res; } } else if (creator=="WNGZ") { if (type=="WZSS") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_WINGZ, 1, MWAWDocument::MWAW_K_SPREADSHEET)); return res; } } else if (creator=="WORD") { if (type=="WDBN") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORD, 1)); return res; } } else if (creator=="ZEBR") { if (type=="ZWRT") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_GREATWORKS, 1)); return res; } if (type=="ZOBJ") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_GREATWORKS, 1, MWAWDocument::MWAW_K_DRAW)); return res; } if (type=="PNTG") { // same as MacPaint format, so use the MacPaint parser res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACPAINT, 1, MWAWDocument::MWAW_K_PAINT)); return res; } if (type=="ZPNT") { /* the ZPNT(v2) are basic pct files with some resources, but we treat them to be complete */ res.push_back(MWAWHeader(MWAWDocument::MWAW_T_GREATWORKS, 2, MWAWDocument::MWAW_K_PAINT)); return res; } if (type=="ZCAL") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_GREATWORKS, 1, MWAWDocument::MWAW_K_SPREADSHEET)); return res; } if (type=="ZDBS") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_GREATWORKS, 1, MWAWDocument::MWAW_K_DATABASE)); return res; } // can we treat also ZOLN ? } else if (creator=="ZWRT") { if (type=="Zart") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_ZWRITE, 1)); return res; } } else if (creator=="aca3") { if (type=="acf3" || type=="act3") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_FREEHAND, 1, MWAWDocument::MWAW_K_DRAW)); return res; } } else if (creator=="dPro") { if (type=="dDoc") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDRAWPRO, 1, MWAWDocument::MWAW_K_DRAW)); return res; } if (type=="dLib") { // macdraw pro slide/library res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDRAWPRO, 1, MWAWDocument::MWAW_K_DRAW)); return res; } } else if (creator=="eDcR") { if (type=="eDoc") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_EDOC, 1)); return res; } } else if (creator=="eSRD") { // self reading application if (type=="APPL") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_EDOC, 1)); return res; } } else if (creator=="nX^n") { if (type=="nX^d") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_WRITENOW, 2)); return res; } if (type=="nX^2") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_WRITENOW, 3)); return res; } } else if (creator=="ttxt") { if (type=="TEXT" || type=="ttro") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_TEACHTEXT, 1)); return res; } } else if (type=="PICT") { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_APPLEPICT, 1, MWAWDocument::MWAW_K_DRAW)); return res; } MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: unknown finder info: type=%s[%s]\n", type.c_str(), creator.c_str())); } // ----------- now check resource fork ------------ // ----------- now check data fork ------------ if (!input->hasDataFork() || input->size() < 8) return res; input->seek(0, librevenge::RVNG_SEEK_SET); int val[5]; for (auto &v : val) v = int(input->readULong(2)); // ----------- clearly discriminant ------------------ if (val[2] == 0x424F && val[3] == 0x424F && (val[0]>>8) < 7) { MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a Claris Works file\n")); int vers= (val[0] >> 8); static int const typePos[7] = {0, 242, 248, 248, 256, 268, 278}; int typeFile=-1; if (vers >= 1 && vers <= 6 && input->checkPosition(typePos[vers])) { input->seek(typePos[vers], librevenge::RVNG_SEEK_SET); typeFile=int(input->readLong(1)); } switch (typeFile) { case 0: res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CLARISWORKS, vers, MWAWDocument::MWAW_K_DRAW)); return res; case 1: res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CLARISWORKS, vers, MWAWDocument::MWAW_K_TEXT)); return res; case 2: res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CLARISWORKS, vers, MWAWDocument::MWAW_K_SPREADSHEET)); return res; case 3: res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CLARISWORKS, vers, MWAWDocument::MWAW_K_DATABASE)); return res; case 4: res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CLARISWORKS, vers, MWAWDocument::MWAW_K_PAINT)); return res; case 5: res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CLARISWORKS, vers, MWAWDocument::MWAW_K_PRESENTATION)); return res; default: break; } } if (val[0]==0x5772 && val[1]==0x6974 && val[2]==0x654e && val[3]==0x6f77) { input->seek(8, librevenge::RVNG_SEEK_SET); auto version = int(input->readLong(2)); #ifdef DEBUG bool ok = (version >= 0 && version <= 3); if (ok) MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a WriteNow file version 3.0 or 4.0\n")); else MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a WriteNow file (unknown version %d)\n", version)); #else bool ok = version == 2; #endif if (ok) { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_WRITENOW, 3)); return res; } } if (val[0]==0x574e && val[1]==0x475a && val[2]==0x575a && val[3]==0x5353) { MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a Wingz file\n")); res.push_back(MWAWHeader(MWAWDocument::MWAW_T_WINGZ, 1, MWAWDocument::MWAW_K_SPREADSHEET)); return res; } if (val[0]==0x4241 && val[1]==0x545F && val[2]==0x4254 && val[3]==0x5353) { MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a ClarisResolve file\n")); res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CLARISRESOLVE, 1, MWAWDocument::MWAW_K_SPREADSHEET)); return res; } if (val[0]==0x4323 && val[1]==0x2b44 && val[2]==0xa443 && val[3]==0x4da5) { MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a RagTime 5-6 file\n")); res.push_back(MWAWHeader(MWAWDocument::MWAW_T_RAGTIME, 5)); return res; } if (val[0]==0x4646 && val[1]==0x4646 && val[2]==0x3030 && val[3]==0x3030) { MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a Mariner Write file\n")); res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MARINERWRITE, 1)); return res; } if (val[0]==0x4257 && val[1]==0x6b73 && val[2]==0x4257) { if (val[3]==0x7770) { MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a BeagleWorks file\n")); res.push_back(MWAWHeader(MWAWDocument::MWAW_T_BEAGLEWORKS, 1)); return res; } if (val[3]==0x6462) { MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a BeagleWorks Database file\n")); res.push_back(MWAWHeader(MWAWDocument::MWAW_T_BEAGLEWORKS, 1, MWAWDocument::MWAW_K_DATABASE)); return res; } if (val[3]==0x6472) { MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a BeagleWorks Draw file\n")); res.push_back(MWAWHeader(MWAWDocument::MWAW_T_BEAGLEWORKS, 1, MWAWDocument::MWAW_K_DRAW)); return res; } if (val[3]==0x7074) { MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a BeagleWorks Paint file\n")); res.push_back(MWAWHeader(MWAWDocument::MWAW_T_BEAGLEWORKS, 1, MWAWDocument::MWAW_K_PAINT)); return res; } if (val[3]==0x7373) { MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a BeagleWorks Spreadsheet file\n")); res.push_back(MWAWHeader(MWAWDocument::MWAW_T_BEAGLEWORKS, 1, MWAWDocument::MWAW_K_SPREADSHEET)); return res; } } if (val[0]==0x4452 && val[1]==0x5747) { // DRWG if (val[2]==0x4d44) { // MD MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a MacDraw file\n")); res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDRAW, 1, MWAWDocument::MWAW_K_DRAW)); return res; } if (val[2]==0 || val[2]==0x4432) { // D2 MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a MacDraw II file\n")); res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDRAWPRO, 0, MWAWDocument::MWAW_K_DRAW)); // can also be a classic apple pict, so let's continue } } if (val[0]==0x5354 && val[1]==0x4154 && (val[2]==0 || val[2]==0x4432)) { MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a MacDraw II template file\n")); res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDRAWPRO, 0, MWAWDocument::MWAW_K_DRAW)); return res; } #ifdef DEBUG // we need the resource fork to find the colors, patterns, ... ; so not active in normal mode if (val[0]==0x6444 && val[1]==0x6f63 && val[2]==0x4432) { // dDocD2 MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a MacDraw Pro file\n")); res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDRAWPRO, 1, MWAWDocument::MWAW_K_DRAW)); return res; } if (val[0]==0x644c && val[1]==0x6962 && val[2]==0x4432) { // dLibD2 MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a MacDraw Pro template file\n")); res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDRAWPRO, 1, MWAWDocument::MWAW_K_DRAW)); return res; } #endif if (val[0]==2 && val[1]==0 && val[2]==2 && val[3]==0x262 && val[4]==0x262) { MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a MacDraft file\n")); res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDRAFT, 1, MWAWDocument::MWAW_K_DRAW)); return res; } if (val[0]==0x4859 && val[1]==0x4c53 && val[2]==0x0210) { MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a HanMac Word-K file\n")); res.push_back(MWAWHeader(MWAWDocument::MWAW_T_HANMACWORDK, 1)); return res; } if (val[0]==0x594c && val[1]==0x5953 && val[2]==0x100) { MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a HanMac Word-J file\n")); res.push_back(MWAWHeader(MWAWDocument::MWAW_T_HANMACWORDJ, 1)); return res; } if (val[0]==0x6163 && val[1]==0x6633 && val[2]<9) { MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a FreeHand v1\n")); res.push_back(MWAWHeader(MWAWDocument::MWAW_T_FREEHAND, 1, MWAWDocument::MWAW_K_DRAW)); return res; } if (val[0]==0x4648 && val[1]==0x4432 && val[2]<20) { MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a FreeHand v2\n")); res.push_back(MWAWHeader(MWAWDocument::MWAW_T_FREEHAND, 2, MWAWDocument::MWAW_K_DRAW)); return res; } if (val[0]==3 && val[1]==0x4d52 && val[2]==0x4949 && val[3]==0x80) { // MRII res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MORE, 2)); return res; } if (val[0]==6 && val[1]==0x4d4f && val[2]==0x5233 && val[3]==0x80) { // MOR3 res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MORE, 3)); return res; } if ((val[0]==0x100||val[0]==0x200) && val[2]==0x4558 && val[3]==0x5057) { // CHANGEME: ClarisDraw res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CLARISDRAW, 1, MWAWDocument::MWAW_K_DRAW)); return res; } if (val[0]==0x100 || val[0]==0x200) { if (val[1]==0x5a57 && val[2]==0x5254) { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_GREATWORKS, val[0]==0x100 ? 1 : 2)); return res; } if (val[1]==0x5a4f && val[2]==0x424a) { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_GREATWORKS, val[0]==0x100 ? 1 : 2, MWAWDocument::MWAW_K_DRAW)); return res; } if (val[1]==0x5a43 && val[2]==0x414C) { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_GREATWORKS, val[0]==0x100 ? 1 : 2, MWAWDocument::MWAW_K_SPREADSHEET)); return res; } if (val[1]==0x5a44 && val[2]==0x4253) { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_GREATWORKS, val[0]==0x100 ? 1 : 2, MWAWDocument::MWAW_K_DATABASE)); return res; } // maybe we can also add outline: if (val[1]==0x5a4f && val[2]==0x4c4e) } if (val[0]==0x11ab && val[1]==0 && val[2]==0x13e8 && val[3]==0) { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTMULTIPLAN, 1, MWAWDocument::MWAW_K_SPREADSHEET)); return res; } if (val[3]==6 && val[4]<6) { if (val[0]==0x4d44 && val[1]==0x4443 && val[2]==0x3230) { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDRAFT, 4, MWAWDocument::MWAW_K_DRAW)); return res; } // can be a library file, this will be test in the parser if (input->size()>=30) res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDRAFT, 4, MWAWDocument::MWAW_K_DRAW)); } // magic ole header if (val[0]==0xd0cf && val[1]==0x11e0 && val[2]==0xa1b1 && val[3]==0x1ae1 && input->isStructured()) { MWAWInputStreamPtr mainOle = input->getSubStreamByName("MN0"); if (mainOle && mainOle->readULong(4) == 0x43484e4b) res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORKS, 4)); else if (mainOle && mainOle->size()>18) { mainOle->seek(16, librevenge::RVNG_SEEK_SET); auto value=static_cast(mainOle->readULong(2)); switch (value) { case 2: res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORKS, 4, MWAWDocument::MWAW_K_DATABASE)); break; case 3: res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORKS, 4, MWAWDocument::MWAW_K_SPREADSHEET)); break; case 12: res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORKS, 4, MWAWDocument::MWAW_K_DRAW)); break; default: break; } } if (!mainOle && input->getSubStreamByName("PP40")) res.push_back(MWAWHeader(MWAWDocument::MWAW_T_POWERPOINT, 4, MWAWDocument::MWAW_K_PRESENTATION)); else if (!mainOle && input->getSubStreamByName("PowerPoint Document") && input->getSubStreamByName("PersistentStorage Directory")) res.push_back(MWAWHeader(MWAWDocument::MWAW_T_POWERPOINT, 7, MWAWDocument::MWAW_K_PRESENTATION)); } if ((val[0]==0xfe32 && val[1]==0) || (val[0]==0xfe34 && val[1]==0) || (val[0] == 0xfe37 && (val[1] == 0x23 || val[1] == 0x1c))) { int vers = -1; switch (val[1]) { case 0: if (val[0]==0xfe34) { MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a Word 3.0 file\n")); vers = 3; } else if (val[0]==0xfe32) { MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a Word 1.0 file\n")); vers = 1; } break; case 0x1c: MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a Word 4.0 file\n")); vers = 4; break; case 0x23: MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a Word 5.0 file\n")); vers = 5; break; default: break; } if (vers >= 0) res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORD, vers)); } if (val[0]==0xbad && val[1]==0xdeed && val[2]==0 && (val[3]>=2 && val[3]<=3)) { MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a Presentation file\n")); res.push_back(MWAWHeader(MWAWDocument::MWAW_T_POWERPOINT, val[3], MWAWDocument::MWAW_K_PRESENTATION)); } if (val[0]==0xedde && val[1]==0xad0b && val[3]==0 && (val[2]&0xFF)==0) { int vers=(val[2]>>8); if (vers>=2 && vers<=3) { MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a Presentation file\n")); res.push_back(MWAWHeader(MWAWDocument::MWAW_T_POWERPOINT, vers, MWAWDocument::MWAW_K_PRESENTATION)); } } if (val[0]==0x4348 && val[1]==0x4e4b && val[2]==0x100 && val[3]==0) { MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a Style file\n")); res.push_back(MWAWHeader(MWAWDocument::MWAW_T_STYLE, 1)); } if (val[0]==0x0447 && val[1]==0x4d30 && val[2]==0x3400) { // ^DGM04 MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a MouseWrite file\n")); res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MOUSEWRITE, 1)); } // ----------- less discriminant ------------------ if (val[0] == 0x2e && val[1] == 0x2e) { MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a MacWrite II file\n")); res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACWRITEPRO, 0)); } if (val[0] == 4 && val[1] == 4) { MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a MacWritePro file\n")); res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACWRITEPRO, 1)); } if (val[0] == 0x7704) { MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a MindWrite file 2.1\n")); res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MINDWRITE, 2)); } // ----------- other ------------------ if (val[0]==0 && val[1]==0 && val[2]==0 && val[3]==0) { input->seek(8, librevenge::RVNG_SEEK_SET); auto value=static_cast(input->readULong(1)); if (value==0x4 || value==0x44) { MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a WriteNow 1.0 or 2.0 file\n")); res.push_back(MWAWHeader(MWAWDocument::MWAW_T_WRITENOW, 2)); } } if (val[0]==0 && input->size() > 32) { input->seek(16, librevenge::RVNG_SEEK_SET); if (input->readLong(2)==0x688f && input->readLong(2)==0x688f) { MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a RagTime file\n")); res.push_back(MWAWHeader(MWAWDocument::MWAW_T_RAGTIME)); } } if (val[0]==0) { int vers = -1; switch (val[1]) { case 4: vers = 1; break; case 8: vers = 2; break; case 9: vers = 3; break; case 11: // embedded data vers = 4; break; default: break; } if (vers > 0 && input->size()>16) { input->seek(16, librevenge::RVNG_SEEK_SET); auto value=static_cast(input->readULong(2)); switch (value) { case 1: res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORKS, vers)); break; case 2: res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORKS, vers, MWAWDocument::MWAW_K_DATABASE)); break; case 3: res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORKS, vers, MWAWDocument::MWAW_K_SPREADSHEET)); break; case 12: res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORKS, vers, MWAWDocument::MWAW_K_DRAW)); break; default: break; } } } if (val[0]==0x4d44 && input->size()>=512) { // maybe a MacDraw 0 file, will be check later res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDRAW, 0, MWAWDocument::MWAW_K_DRAW)); } if (val[0] == 3 || val[0] == 6) { // version will be print by MacWrtParser::check res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACWRITE, val[0])); } if (val[0] == 0x110) { MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a Writerplus file\n")); res.push_back(MWAWHeader(MWAWDocument::MWAW_T_WRITERPLUS, 1)); } if (val[0] == 0x1000) { input->seek(10, librevenge::RVNG_SEEK_SET); auto value=static_cast(input->readULong(2)); // 1: bitmap, 2: vectorized graphic if (value==1) res.push_back(MWAWHeader(MWAWDocument::MWAW_T_SUPERPAINT, 1, MWAWDocument::MWAW_K_PAINT)); else if (value==2) res.push_back(MWAWHeader(MWAWDocument::MWAW_T_SUPERPAINT, 1, MWAWDocument::MWAW_K_DRAW)); } if (val[0]==0 && (val[1]==0x7FFF || val[1]==0x8000)) { MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a potential PixelPaint file\n")); res.push_back(MWAWHeader(MWAWDocument::MWAW_T_PIXELPAINT, (val[1]==0x7FFF) ? 1 : 2, MWAWDocument::MWAW_K_PAINT)); } if (val[0]>=1 && val[0]<=4) { int sSz=(val[1]>>8); if (sSz>=6 && sSz<=8) { // check if we find a date input->seek(3, librevenge::RVNG_SEEK_SET); bool ok=true; int numSlash=0; for (int i=0; ireadULong(1)); if (c>='0' && c<='9') continue; if (c=='/') ++numSlash; else { ok=false; break; } } if (ok && numSlash==2) res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CRICKETDRAW, 1, MWAWDocument::MWAW_K_DRAW)); } } // // check for pict // for (int st=0; st<2; ++st) { if (!input->checkPosition(512*st+13)) break; input->seek(512*st+10, librevenge::RVNG_SEEK_SET); auto value=static_cast(input->readULong(2)); if (value==0x1101) { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_APPLEPICT, 1, MWAWDocument::MWAW_K_DRAW)); break; } else if (value==0x11 && input->readULong(2)==0x2ff && input->readULong(2) == 0xC00) { res.push_back(MWAWHeader(MWAWDocument::MWAW_T_APPLEPICT, 2, MWAWDocument::MWAW_K_DRAW)); break; } } // // middle of file // if (input->size()>=512+720*2) { // check for a MacPaint file input->seek(512, librevenge::RVNG_SEEK_SET); bool ok=true; // check the first 3 row for (int row=0; row<3; ++row) { int lastColor=-1; int col=0; while (col<72) { if (input->tell()+2>input->size()) { ok=false; break; } auto wh=static_cast(input->readULong(1)); if (wh>=0x81) { auto color=static_cast(input->readULong(1)); // consider that repeat color is anormal... if (col+(0x101-wh)>72 || (lastColor>=0 && color==lastColor)) { ok=false; break; } col+=(0x101-wh); lastColor=color; continue; } if (col+1+wh>72) { ok=false; break; } lastColor=-1; col += wh+1; input->seek(wh+1, librevenge::RVNG_SEEK_CUR); } if (!ok) break; } if (ok) { MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a potential MacPaint file\n")); res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACPAINT, 1, MWAWDocument::MWAW_K_PAINT)); } } // //ok now look at the end of file // if (input->seek(-4, librevenge::RVNG_SEEK_END)) return res; int lVal[2]; for (auto &v : lVal) v=int(input->readULong(2)); if (lVal[0] == 0x4E4C && lVal[1]==0x544F) // NLTO res.push_back(MWAWHeader(MWAWDocument::MWAW_T_ACTA, 2)); else if (lVal[1]==0 && val[0]==1 && (val[1]==1||val[1]==2)) res.push_back(MWAWHeader(MWAWDocument::MWAW_T_ACTA, 1)); else if (lVal[0] == 0x4657 && lVal[1]==0x5254) // FWRT res.push_back(MWAWHeader(MWAWDocument::MWAW_T_FULLWRITE, 2)); else if (lVal[0] == 0 && lVal[1]==1) // not probable, but res.push_back(MWAWHeader(MWAWDocument::MWAW_T_FULLWRITE, 1)); input->seek(0, librevenge::RVNG_SEEK_SET); return res; } // vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab: