diff --git a/common/winexe.cpp b/common/winexe.cpp index 7e990281aae..31750c7f5c6 100644 --- a/common/winexe.cpp +++ b/common/winexe.cpp @@ -218,69 +218,6 @@ WinResources::VersionInfo *WinResources::getVersionResource(const WinResourceID return info; } -WinResources::VersionInfo *WinResources::parseVersionInfo(SeekableReadStream *res) { - VersionInfo *info = new VersionInfo; - - while (res->pos() < res->size() && !res->eos()) { - while (res->pos() % 4 && !res->eos()) // Pad to 4 - res->readByte(); - - /* uint16 len = */ res->readUint16LE(); - uint16 valLen = res->readUint16LE(); - uint16 type = res->readUint16LE(); - uint16 c; - - Common::U32String key; - while ((c = res->readUint16LE()) != 0 && !res->eos()) - key += c; - - while (res->pos() % 4 && !res->eos()) // Pad to 4 - res->readByte(); - - if (res->eos()) - break; - - if (type != 0) { // text - Common::U32String value; - for (int j = 0; j < valLen; j++) - value += res->readUint16LE(); - - info->hash.setVal(key.encode(), value); - } else { - if (key == "VS_VERSION_INFO") { - // Signature check - if (res->readUint32LE() != 0xFEEF04BD) - return info; - - res->readUint32LE(); // struct version - - // The versions are stored a bit weird - info->fileVersion[1] = res->readUint16LE(); - info->fileVersion[0] = res->readUint16LE(); - info->fileVersion[3] = res->readUint16LE(); - info->fileVersion[2] = res->readUint16LE(); - info->productVersion[1] = res->readUint16LE(); - info->productVersion[0] = res->readUint16LE(); - info->productVersion[3] = res->readUint16LE(); - info->productVersion[2] = res->readUint16LE(); - - info->fileFlagsMask = res->readUint32LE(); - info->fileFlags = res->readUint32LE(); - info->fileOS = res->readUint32LE(); - info->fileType = res->readUint32LE(); - info->fileSubtype = res->readUint32LE(); - info->fileDate[0] = res->readUint32LE(); - info->fileDate[1] = res->readUint32LE(); - - info->hash.setVal("File:", Common::String::format("%d.%d.%d.%d", info->fileVersion[0], info->fileVersion[1], info->fileVersion[2], info->fileVersion[3])); - info->hash.setVal("Prod:", Common::String::format("%d.%d.%d.%d", info->productVersion[0], info->productVersion[1], info->productVersion[2], info->productVersion[3])); - } - } - } - - return info; -} - WinResources::VersionInfo::VersionInfo() { fileVersion[0] = fileVersion[1] = fileVersion[2] = fileVersion[3] = 0; productVersion[0] = productVersion[1] = productVersion[2] = productVersion[3] = 0; @@ -292,4 +229,36 @@ WinResources::VersionInfo::VersionInfo() { fileDate[0] = fileDate[1] = 0; } + +bool WinResources::VersionInfo::readVSVersionInfo(SeekableReadStream *res) { + // Signature check + if (res->readUint32LE() != 0xFEEF04BD) + return false; + + res->readUint32LE(); // struct version + + // The versions are stored a bit weird + fileVersion[1] = res->readUint16LE(); + fileVersion[0] = res->readUint16LE(); + fileVersion[3] = res->readUint16LE(); + fileVersion[2] = res->readUint16LE(); + productVersion[1] = res->readUint16LE(); + productVersion[0] = res->readUint16LE(); + productVersion[3] = res->readUint16LE(); + productVersion[2] = res->readUint16LE(); + + fileFlagsMask = res->readUint32LE(); + fileFlags = res->readUint32LE(); + fileOS = res->readUint32LE(); + fileType = res->readUint32LE(); + fileSubtype = res->readUint32LE(); + fileDate[0] = res->readUint32LE(); + fileDate[1] = res->readUint32LE(); + + hash.setVal("File:", Common::U32String::format("%d.%d.%d.%d", fileVersion[0], fileVersion[1], fileVersion[2], fileVersion[3])); + hash.setVal("Prod:", Common::U32String::format("%d.%d.%d.%d", productVersion[0], productVersion[1], productVersion[2], productVersion[3])); + + return true; +} + } // End of namespace Common diff --git a/common/winexe.h b/common/winexe.h index 6cbc9a9d1c8..af4d8a30fa3 100644 --- a/common/winexe.h +++ b/common/winexe.h @@ -158,14 +158,17 @@ public: uint32 fileDate[2]; VersionHash hash; - }; - static VersionInfo *parseVersionInfo(SeekableReadStream *stream); + bool readVSVersionInfo(SeekableReadStream *res); + }; VersionInfo *getVersionResource(const WinResourceID &id); /** Get a string from a string resource. */ virtual String loadString(uint32 stringID) = 0; + +protected: + virtual VersionInfo *parseVersionInfo(SeekableReadStream *stream) = 0; }; /** @} */ diff --git a/common/winexe_ne.cpp b/common/winexe_ne.cpp index f3e2c307df9..c81b16c76ec 100644 --- a/common/winexe_ne.cpp +++ b/common/winexe_ne.cpp @@ -234,4 +234,34 @@ String NEResources::loadString(uint32 stringID) { return string; } +WinResources::VersionInfo *NEResources::parseVersionInfo(SeekableReadStream *res) { + VersionInfo *info = new VersionInfo; + + while (res->pos() < res->size() && !res->eos()) { + while (res->pos() % 4 && !res->eos()) // Pad to 4 + res->readByte(); + + /* uint16 len = */ res->readUint16LE(); + /* uint16 valLen = */ res->readUint16LE(); + uint16 c; + + Common::String key; + while ((c = res->readByte()) != 0 && !res->eos()) + key += c; + + while (res->pos() % 4 && !res->eos()) // Pad to 4 + res->readByte(); + + if (res->eos()) + break; + + if (key == "VS_VERSION_INFO") { + if (!info->readVSVersionInfo(res)) + return info; + } + } + + return info; +} + } // End of namespace Common diff --git a/common/winexe_ne.h b/common/winexe_ne.h index 914be4c057c..59eaa2e46c2 100644 --- a/common/winexe_ne.h +++ b/common/winexe_ne.h @@ -70,6 +70,9 @@ public: /** Get a string from a string resource. */ String loadString(uint32 stringID); +protected: + VersionInfo *parseVersionInfo(SeekableReadStream *stream); + private: /** A resource. */ struct Resource { diff --git a/common/winexe_pe.cpp b/common/winexe_pe.cpp index 7db745de7f9..48989694de7 100644 --- a/common/winexe_pe.cpp +++ b/common/winexe_pe.cpp @@ -259,4 +259,43 @@ String PEResources::loadString(uint32 stringID) { return string; } +WinResources::VersionInfo *PEResources::parseVersionInfo(SeekableReadStream *res) { + VersionInfo *info = new VersionInfo; + + while (res->pos() < res->size() && !res->eos()) { + while (res->pos() % 4 && !res->eos()) // Pad to 4 + res->readByte(); + + /* uint16 len = */ res->readUint16LE(); + uint16 valLen = res->readUint16LE(); + uint16 type = res->readUint16LE(); + uint16 c; + + Common::U32String key; + while ((c = res->readUint16LE()) != 0 && !res->eos()) + key += c; + + while (res->pos() % 4 && !res->eos()) // Pad to 4 + res->readByte(); + + if (res->eos()) + break; + + if (type != 0) { // text + Common::U32String value; + for (int j = 0; j < valLen; j++) + value += res->readUint16LE(); + + info->hash.setVal(key.encode(), value); + } else { + if (key == "VS_VERSION_INFO") { + if (!info->readVSVersionInfo(res)) + return info; + } + } + } + + return info; +} + } // End of namespace Common diff --git a/common/winexe_pe.h b/common/winexe_pe.h index d09000f6976..e0d41b9e3b7 100644 --- a/common/winexe_pe.h +++ b/common/winexe_pe.h @@ -78,6 +78,9 @@ public: /** Get a string from a string resource. */ String loadString(uint32 stringID); +protected: + VersionInfo *parseVersionInfo(SeekableReadStream *stream); + private: struct Section { uint32 virtualAddress;