61 0x8A, 0x83, 0x5A, 0x2D, 0x01, 0x10, 0x5C, 0xBE, 0xCE, 0x2C, 0xD0, 0x69, 0xB8, 0x48, 0xC9, 0xBE,
62 0xAA, 0x7E, 0x57, 0xBD, 0xAB, 0x94, 0xCE, 0x0D, 0x09, 0x10, 0xBD, 0x57, 0x8D, 0x1A, 0x0D, 0x35,
63 0xC9, 0x84, 0x90, 0xFA, 0x7B, 0x65, 0x32, 0x97, 0xCF, 0x39, 0x66, 0xA7, 0x60, 0xEC, 0x99, 0xEF,
64 0x76, 0x5A, 0x3B, 0x2C, 0x2F, 0x0A, 0x24, 0xC3
66 0x5C, 0xA8, 0x83, 0xCE, 0x6D, 0x9C, 0x84, 0x3B, 0xDE, 0xA1, 0xD7, 0x85, 0x78, 0x87, 0xFD, 0x0D,
67 0xD7, 0x97, 0x42, 0x38, 0x93, 0x53, 0xCD, 0x3D, 0xEC, 0x03, 0xCE, 0x15, 0x09, 0x48, 0xD7, 0x9B,
68 0x86, 0x20, 0x19, 0x21, 0xC2, 0x6E, 0x42, 0xEE, 0xAF, 0xBE, 0xCA, 0x41, 0xBF, 0x0A, 0x66, 0x9A,
69 0x2A, 0x8F, 0xC2, 0x04, 0x56, 0x14, 0x77, 0x82
71 0x94, 0x37, 0xDD, 0x56, 0xED, 0xD9, 0xF0, 0x41, 0x91, 0x28, 0xC2, 0xD5, 0x4F, 0x97, 0xE8, 0x5D,
72 0x95, 0x42, 0x41, 0xB5, 0xA3, 0xA2, 0x03, 0xB6, 0x08, 0x8B, 0xC1, 0xC7, 0xCB, 0xEE, 0xD8, 0xD9,
73 0x83, 0x4E, 0x9F, 0xAB, 0x69, 0x41, 0x6C, 0xFC, 0x87, 0x13, 0xB5, 0xFD, 0xCA, 0x0A, 0x1D, 0x83,
74 0x89, 0x51, 0x4E, 0xF3, 0x5B, 0xED, 0x9A, 0x5C
76 0xEC, 0xBF, 0x9A, 0x75, 0x39, 0xE4, 0x65, 0x10, 0xCA, 0xA1, 0xB6, 0x3A, 0x76, 0xA2, 0x50, 0xDD,
77 0xE2, 0x06, 0xEA, 0x39, 0x20, 0x0F, 0xBC, 0xC7, 0x5D, 0x03, 0xD6, 0xB2, 0x75, 0x83, 0xEF, 0x08,
78 0xA7, 0xFD, 0x68, 0xDB, 0x33, 0xAA, 0x69, 0xA1, 0x39, 0x80, 0x62, 0x29, 0x8C, 0xE9, 0x2B, 0xA9,
79 0x60, 0xC6, 0x93, 0x27, 0x2C, 0x0D, 0x42, 0x26
81 0x72, 0xA3, 0x8B, 0x0C, 0x49, 0x63, 0x53, 0x32, 0x7D, 0x86, 0x9C, 0x3D, 0x48, 0x84, 0x77, 0xBD,
82 0xBB, 0x7C, 0x48, 0xDC, 0x33, 0x45, 0x40, 0x78, 0xAF, 0x26, 0x64, 0x96, 0x7F, 0x80, 0x44, 0x67,
83 0xF7, 0xDA, 0x08, 0x74, 0xF4, 0xD8, 0x7C, 0x2D, 0x2D, 0x1F, 0xF2, 0xD1, 0x5D, 0x18, 0xF7, 0xD2,
84 0x71, 0x28, 0xD0, 0x31, 0x5C, 0xCC, 0x6E, 0xCD
86 0x1D, 0xEA, 0x5E, 0x04, 0x0B, 0x43, 0xF2, 0x2F, 0x23, 0x90, 0x04, 0x38, 0x5C, 0xA1, 0x18, 0x9C,
87 0xFF, 0xB1, 0xB1, 0x86, 0xE6, 0x69, 0x67, 0x8E, 0x29, 0x08, 0x94, 0x4C, 0x08, 0x22, 0x0A, 0x8C,
88 0x9D, 0xC5, 0xFE, 0xE2, 0x27, 0x84, 0xE7, 0xD3, 0xD1, 0x6B, 0xF2, 0x38, 0xF4, 0xFF, 0xBF, 0x80,
89 0x7E, 0x1E, 0x98, 0x75, 0x32, 0xA3, 0x2C, 0xF6
107 offDescription = 0xFFFFFFFF;
108 offKeyList = 0xFFFFFFFF;
109 offResList = 0xFFFFFFFF;
116 isNWNPremium =
false;
133 if ((buildYear > 2200) || (buildYear < 2000) || (buildDay > 366))
136 if ((resCount >= 131072) || (langCount > 32))
139 if ((offDescription != 0xFFFFFFFF) && (offDescription > fileSize))
141 if ((offKeyList != 0xFFFFFFFF) && (offKeyList > fileSize))
143 if ((offResList != 0xFFFFFFFF) && (offResList > fileSize))
193 uint64 passwordNumber = 0;
197 for (
size_t i = 0; i < 8; i++) {
200 passwordNumber >>= 8;
209 for (
size_t i = 0; i <
sizeof(buffer); i++)
226 const std::vector<byte> &password) {
237 const std::vector<byte> &md5, std::vector<byte> &password) {
242 const size_t headerPos = erf.
pos();
258 std::vector<byte> &password) {
263 throw Common::Exception(
"Invalid Neverwinter Nights premium module MD5 length (%u)",
264 (
uint)password.size());
266 const std::vector<byte> md5 = password;
296 e.
add(
"Failed reading ERF file");
435 std::vector<byte> &password) {
457 const size_t headerPos = erf.
pos();
560 for (ResourceList::iterator res =
_resources.begin(); res !=
_resources.end(); ++index, ++res) {
573 for (ResourceList::iterator res =
_resources.begin(); res !=
_resources.end(); ++index, ++res) {
587 res->packedSize = res->unpackedSize = erf.
readUint32LE();
595 ResourceList::iterator res =
_resources.begin();
596 IResourceList::iterator iRes =
_iResources.begin();
601 res->type =
TypeMan.getFileType(name);
605 iRes->packedSize = iRes->unpackedSize = erf.
readUint32LE();
614 ResourceList::iterator res =
_resources.begin();
615 IResourceList::iterator iRes =
_iResources.begin();
620 res->type =
TypeMan.getFileType(name);
634 ResourceList::iterator res =
_resources.begin();
635 IResourceList::iterator iRes =
_iResources.begin();
640 res->type =
TypeMan.getFileType(name);
654 ResourceList::iterator res =
_resources.begin();
655 IResourceList::iterator iRes =
_iResources.begin();
659 if (nameOffset >= 0) {
665 res->type =
TypeMan.getFileType(name);
732 Encryption encryption,
const std::vector<byte> &password) {
733 switch (encryption) {
745 Encryption encryption,
const std::vector<byte> &password) {
751 return decrypt(*stream, encryption, password);
755 Encryption encryption,
const std::vector<byte> &password) {
761 Encryption encryption,
const std::vector<byte> &password) {
763 return decrypt(erf, erf.
pos(), size, encryption, password);
767 uint32 unpackedSize)
const {
773 if (stream->
size() == unpackedSize)
795 uint32 unpackedSize)
const {
799 assert(packedStream);
803 const byte *
const compressedData = stream->
getData();
806 return decompressZlib(compressedData + 1, packedSize - 1, unpackedSize, *compressedData >> 4);
810 uint32 unpackedSize)
const {
814 assert(packedStream);
818 const byte *
const compressedData = stream->
getData();
825 uint32 unpackedSize)
const {
829 assert(packedStream);
833 const byte *
const compressedData = stream->
getData();
840 uint32 unpackedSize,
int windowBits)
const {
864 std::vector<byte> password;
Common::SeekableReadStream * decompressZlib(const byte *compressedData, uint32 packedSize, uint32 unpackedSize, int windowBits) const
static const uint32 kERFID
#define MKTAG(a0, a1, a2, a3)
A wrapper macro used around four character constants, like 'DATA', to ensure portability.
uint16 readUint16LE()
Read an unsigned 16-bit word stored in little endian (LSB first) order from the stream and return it...
Common::SeekableReadStream * decompress(Common::MemoryReadStream *packedStream, uint32 unpackedSize) const
static const uint32 kVersion21
void add(const char *s,...) GCC_PRINTF(2
uint32 readUint32LE()
Read an unsigned 32-bit word stored in little endian (LSB first) order from the stream and return it...
#define TypeMan
Shortcut for accessing the file type manager.
A class holding an UTF-8 string.
static const byte kNWNPremiumKeys[][kNWNPremiumKeyLength]
64bit Fowler-Noll-Vo hash by Glenn Fowler, Landon Curt Noll and Phong Vo.
Common::SeekableReadStream * decompressStandardZlib(Common::MemoryReadStream *packedStream, uint32 unpackedSize) const
virtual size_t seek(ptrdiff_t offset, Origin whence=kOriginBegin)=0
Sets the stream position indicator for the stream.
void reset(PointerType o=0)
Resets the pointer with the new value.
PointerType release()
Returns the plain pointer value and releases ScopedPtr.
static void verifyVersion(uint32 id, uint32 version, bool utf16le)
void readLocString(Common::SeekableReadStream &stream, uint32 id, uint32 count)
Read a LocString out of a stream.
Compression using DEFLATE with default parameters.
static void readV20Header(Common::SeekableReadStream &erf, ERFHeader &header)
void readV11KeyList(Common::SeekableReadStream &erf, const ERFHeader &header)
static const uint32 kSAVID
void readV20ResList(Common::SeekableReadStream &erf, const ERFHeader &header)
A simple streaming file reading class.
ResourceList _resources
External list of resource names and types.
Implementing the reading stream interfaces for plain memory blocks.
Utility functions to handle files used in BioWare's Aurora engine.
static void readV30Header(Common::SeekableReadStream &erf, ERFHeader &header, uint32 &flags)
UTF-16 LE (little endian).
MemoryReadStream * decryptBlowfishEBC(SeekableReadStream &input, const std::vector< byte > &key)
Decrypt the stream with the Blowfish algorithm in EBC mode.
#define ARRAYSIZE(x)
Macro which determines the number of entries in a fixed size array.
static const uint32 kVersion10
bool _utf16le
The file's ID and version are in little-endian UTF-16.
static void readV22Header(Common::SeekableReadStream &erf, ERFHeader &header, uint32 &flags)
void verifyPasswordDigest()
byte * decompressDeflate(const byte *data, size_t inputSize, size_t outputSize, int windowBits)
Decompress (inflate) using zlib's DEFLATE algorithm.
void readV22ResList(Common::SeekableReadStream &erf, const ERFHeader &header)
Utility templates and functions for working with strings and streams.
static bool decryptNWNPremiumHeader(Common::SeekableReadStream &erf, ERFHeader &header, const std::vector< byte > &password)
Exception that provides a stack of explanations.
void readResources(Common::SeekableReadStream &erf, const ERFHeader &header)
FORCEINLINE int32 readSint32LE()
Read a signed 32-bit word stored in little endian (LSB first) order from the stream and return it...
const LocString & getDescription() const
Return the description.
static void readHeader(Common::ReadStream &stream, uint32 &id, uint32 &version, bool &utf16le)
Read the header out of a stream.
ERFFile(Common::SeekableReadStream *erf, const std::vector< byte > &password=std::vector< byte >())
Take over this stream and read an ERF file out of it.
Blowfish encryption as used by Dragon Age II (V3.0).
void readV10ResList(Common::SeekableReadStream &erf, const ERFHeader &header)
Blowfish encryption as used by Neverwinter Nights (V1.1).
Basic exceptions to throw.
static const uint32 kVersion11
static void readDescription(LocString &description, Common::SeekableReadStream &erf, const ERFHeader &header)
Encryption / decryption using Bruce Schneier's Blowfish algorithm.
const byte * getData() const
std::vector< byte > _password
The password we were given, if any.
Compression using DEFLATE with an extra header byte.
static void readV10Header(Common::SeekableReadStream &erf, ERFHeader &header)
Common::SeekableReadStream * getResource(uint32 index, bool tryNoCopy=false) const
Return a stream of the resource's contents.
Utility templates and functions.
static const uint32 kVersion20
const ResourceList & getResources() const
Return the list of resources.
std::list< Resource > ResourceList
IResourceList _iResources
Internal list of resource offsets and sizes.
void readV21ResList(Common::SeekableReadStream &erf, const ERFHeader &header)
virtual size_t skip(ptrdiff_t offset)
Skip the specified number of bytes, adding that offset to the current position in the stream...
uint32 unpackedSize
The resource's unpacked size.
Handling BioWare's ERFs (encapsulated resource file).
static void readV11Header(Common::SeekableReadStream &erf, ERFHeader &header)
virtual size_t read(void *dataPtr, size_t dataSize)=0
Read data from the stream.
Simple memory based 'stream', which implements the ReadStream interface for a plain memory block...
Utility functions for working with differing string encodings.
static const uint32 kHAKID
32bit Fowler-Noll-Vo hash by Glenn Fowler, Landon Curt Noll and Phong Vo.
HashAlgo
The algorithm used for hashing.
Blowfish encryption as used by Dragon Age: Origins (V2.2).
static bool findNWNPremiumKey(Common::SeekableReadStream &erf, ERFHeader &header, const std::vector< byte > &md5, std::vector< byte > &password)
uint32 _id
The file's ID.
const Exception kReadError("Read error")
Exception when reading from a stream failed.
uint32 _version
The file's version.
uint32 getBuildDay() const
Return the day of year the ERF was built.
virtual size_t size() const =0
Obtains the total size of the stream, measured in bytes.
virtual size_t pos() const =0
Obtains the current value of the stream position indicator of the stream.
bool compareMD5Digest(ReadStream &stream, const std::vector< byte > &digest)
Hash the stream and compare the digests, returning true if they match.
uint64 readUint64LE()
Read an unsigned 64-bit word stored in little endian (LSB first) order from the stream and return it...
Implementing the stream reading interfaces for files.
static Common::MemoryReadStream * decrypt(Common::SeekableReadStream &cryptStream, Encryption encryption, const std::vector< byte > &password)
Plain, unextended ASCII (7bit clean).
static const int kWindowBitsMax
PointerType get() const
Returns the plain pointer value.
Common::SeekableReadStream * decompressBiowareZlib(Common::MemoryReadStream *packedStream, uint32 unpackedSize) const
Common::ScopedPtr< Common::SeekableReadStream > _erf
XOR encryption as used by V2.2 and V3.0 (UNSUPPORTED!)
uint32 packedSize
The resource's packed size.
uint32 offset
The offset of the resource within the ERF.
void readV10KeyList(Common::SeekableReadStream &erf, const ERFHeader &header)
UString debugTag(uint32 tag, bool trim)
Create an elaborate string from an integer tag, for debugging purposes.
void readV30ResList(Common::SeekableReadStream &erf, const ERFHeader &header)
uint32 getResourceSize(uint32 index) const
Return the size of a resource.
Common::HashAlgo getNameHashAlgo() const
Return with which algorithm the name is hashed.
FileType
Various file types used by the Aurora engine and found in archives.
LocString _description
The ERF's description.
static const uint32 kVersion22
const IResource & getIResource(uint32 index) const
Compression using DEFLATE, standard zlib chunk.
size_t size() const
Obtains the total size of the stream, measured in bytes.
static const uint32 kMODID
UString readStringFixed(SeekableReadStream &stream, Encoding encoding, size_t length)
Read length bytes as a string with the given encoding out of a stream.
SeekableSubReadStream provides access to a SeekableReadStream restricted to the range [begin...
Common::SeekableReadStream * decompressHeaderlessZlib(Common::MemoryReadStream *packedStream, uint32 unpackedSize) const
static void readERFHeader(Common::SeekableReadStream &erf, ERFHeader &header, uint32 version, std::vector< byte > &password)
Compress (deflate) and decompress (inflate) using zlib's DEFLATE algorithm.
MemoryReadStream * encryptBlowfishEBC(SeekableReadStream &input, const std::vector< byte > &key)
Encrypt the stream with the Blowfish algorithm in EBC mode.
Internal resource information.
static const uint32 kVersion10
uint32 getBuildYear() const
Return the year the ERF was built.
Hashing/digesting using the MD5 algorithm.
Interface for a seekable & readable data stream.
static const size_t kMD5Length
The length of an MD5 digest in bytes.
void parseString(const UString &str, T &value, bool allowEmpty)
Parse a string into any POD integer, float/double or bool type.
static const uint32 kVersion30
static const size_t kNWNPremiumKeyLength
static void readV21Header(Common::SeekableReadStream &erf, ERFHeader &header)
static void readNWNPremiumHeader(Common::SeekableReadStream &erf, ERFHeader &header, std::vector< byte > &password)