ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

winexe.cpp

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "common/file.h"
00024 #include "common/memstream.h"
00025 #include "common/str.h"
00026 #include "common/winexe.h"
00027 #include "common/winexe_ne.h"
00028 #include "common/winexe_pe.h"
00029 
00030 namespace Common {
00031 
00032 WinResourceID &WinResourceID::operator=(const String &x) {
00033     _name = x;
00034     _idType = kIDTypeString;
00035     return *this;
00036 }
00037 
00038 WinResourceID &WinResourceID::operator=(uint32 x) {
00039     _id = x;
00040     _idType = kIDTypeNumerical;
00041     return *this;
00042 }
00043 
00044 bool WinResourceID::operator==(const String &x) const {
00045     return _idType == kIDTypeString && _name.equalsIgnoreCase(x);
00046 }
00047 
00048 bool WinResourceID::operator==(const uint32 &x) const {
00049     return _idType == kIDTypeNumerical && _id == x;
00050 }
00051 
00052 bool WinResourceID::operator==(const WinResourceID &x) const {
00053     if (_idType != x._idType)
00054         return false;
00055     if (_idType == kIDTypeString)
00056         return _name.equalsIgnoreCase(x._name);
00057     if (_idType == kIDTypeNumerical)
00058         return _id == x._id;
00059     return true;
00060 }
00061 
00062 String WinResourceID::getString() const {
00063     if (_idType != kIDTypeString)
00064         return "";
00065 
00066     return _name;
00067 }
00068 
00069 uint32 WinResourceID::getID() const {
00070     if (_idType != kIDTypeNumerical)
00071         return 0xffffffff;
00072 
00073     return _id;
00074 }
00075 
00076 String WinResourceID::toString() const {
00077     if (_idType == kIDTypeString)
00078         return _name;
00079     else if (_idType == kIDTypeNumerical)
00080         return String::format("0x%08x", _id);
00081 
00082     return "";
00083 }
00084 
00085 bool WinResources::loadFromEXE(const String &fileName) {
00086     if (fileName.empty())
00087         return false;
00088 
00089     File *file = new File();
00090 
00091     if (!file->open(fileName)) {
00092         delete file;
00093         return false;
00094     }
00095 
00096     return loadFromEXE(file);
00097 }
00098 
00099 bool WinResources::loadFromCompressedEXE(const String &fileName) {
00100     // Based on http://www.cabextract.org.uk/libmspack/doc/szdd_kwaj_format.html
00101 
00102     // TODO: Merge this with with loadFromEXE() so the handling of the compressed
00103     // EXE's is transparent
00104 
00105     File file;
00106 
00107     if (!file.open(fileName))
00108         return false;
00109 
00110     // First part of the signature
00111     if (file.readUint32BE() != MKTAG('S','Z','D','D'))
00112         return false;
00113 
00114     // Second part of the signature
00115     if (file.readUint32BE() != 0x88F02733)
00116         return false;
00117 
00118     // Compression mode must be 'A'
00119     if (file.readByte() != 'A')
00120         return false;
00121 
00122     file.readByte(); // file name character change
00123     uint32 unpackedLength = file.readUint32LE();
00124 
00125     byte *window = new byte[0x1000];
00126     int pos = 0x1000 - 16;
00127     memset(window, 0x20, 0x1000); // Initialize to all spaces
00128 
00129     byte *unpackedData = (byte *)malloc(unpackedLength);
00130     assert(unpackedData);
00131     byte *dataPos = unpackedData;
00132 
00133     // Apply simple LZSS decompression
00134     for (;;) {
00135         byte controlByte = file.readByte();
00136 
00137         if (file.eos())
00138             break;
00139 
00140         for (byte i = 0; i < 8; i++) {
00141             if (controlByte & (1 << i)) {
00142                 *dataPos++ = window[pos++] = file.readByte();
00143                 pos &= 0xFFF;
00144             } else {
00145                 int matchPos = file.readByte();
00146                 int matchLen = file.readByte();
00147                 matchPos |= (matchLen & 0xF0) << 4;
00148                 matchLen = (matchLen & 0xF) + 3;
00149                 while (matchLen--) {
00150                     *dataPos++ = window[pos++] = window[matchPos++];
00151                     pos &= 0xFFF;
00152                     matchPos &= 0xFFF;
00153                 }
00154             }
00155 
00156         }
00157     }
00158 
00159     delete[] window;
00160     SeekableReadStream *stream = new MemoryReadStream(unpackedData, unpackedLength);
00161 
00162     return loadFromEXE(stream);
00163 }
00164 
00165 
00166 WinResources *WinResources::createFromEXE(const String &fileName) {
00167     WinResources *exe;
00168 
00169     // First try loading via the NE code
00170     exe = new Common::NEResources();
00171     if (exe->loadFromEXE(fileName)) {
00172         return exe;
00173     }
00174     delete exe;
00175 
00176     // Then try loading via the PE code
00177     exe = new Common::PEResources();
00178     if (exe->loadFromEXE(fileName)) {
00179         return exe;
00180     }
00181     delete exe;
00182 
00183     return nullptr;
00184 }
00185 
00186 } // End of namespace Common


Generated on Sat Aug 1 2020 05:01:12 for ResidualVM by doxygen 1.7.1
curved edge   curved edge