mirror of
https://github.com/libretro/scummvm.git
synced 2025-04-02 06:41:51 +00:00
COMMON: Rename and tweak MD5 functions
* names now comply to our naming conventions * the function computeStreamMD5AsString which computes the MD5 as a hex string now returns it as a Common::String * add doxygen comments svn-id: r54121
This commit is contained in:
parent
036e88d382
commit
4d3a07b494
@ -88,14 +88,12 @@ uint32 MacResManager::getResForkSize() {
|
||||
return _resForkSize;
|
||||
}
|
||||
|
||||
bool MacResManager::getResForkMD5(char *md5str, uint32 length) {
|
||||
Common::String MacResManager::computeResForkMD5AsString(uint32 length) {
|
||||
if (!hasResFork())
|
||||
return false;
|
||||
return Common::String();
|
||||
|
||||
ReadStream *stream = new SeekableSubReadStream(_stream, _resForkOffset, _resForkOffset + _resForkSize);
|
||||
bool retVal = md5_file_string(*stream, md5str, MIN<uint32>(length, _resForkSize));
|
||||
delete stream;
|
||||
return retVal;
|
||||
SeekableSubReadStream resForkStream(_stream, _resForkOffset, _resForkOffset + _resForkSize);
|
||||
return computeStreamMD5AsString(resForkStream, MIN<uint32>(length, _resForkSize));
|
||||
}
|
||||
|
||||
bool MacResManager::open(Common::String filename) {
|
||||
|
@ -82,7 +82,7 @@ public:
|
||||
Common::SeekableReadStream *getDataFork();
|
||||
Common::String getResName(uint32 typeID, uint16 resID);
|
||||
uint32 getResForkSize();
|
||||
bool getResForkMD5(char *md5str, uint32 length);
|
||||
Common::String computeResForkMD5AsString(uint32 length = 0);
|
||||
|
||||
Common::String getBaseFileName() { return _baseFileName; }
|
||||
|
||||
|
@ -246,7 +246,7 @@ void md5_finish(md5_context *ctx, uint8 digest[16]) {
|
||||
}
|
||||
|
||||
|
||||
bool md5_file(ReadStream &stream, uint8 digest[16], uint32 length) {
|
||||
bool computeStreamMD5(ReadStream &stream, uint8 digest[16], uint32 length) {
|
||||
|
||||
#ifdef DISABLE_MD5
|
||||
memset(digest, 0, 16);
|
||||
@ -267,12 +267,14 @@ bool md5_file(ReadStream &stream, uint8 digest[16], uint32 length) {
|
||||
while ((i = stream.read(buf, readlen)) > 0) {
|
||||
md5_update(&ctx, buf, i);
|
||||
|
||||
length -= i;
|
||||
if (restricted && length == 0)
|
||||
break;
|
||||
if (restricted) {
|
||||
length -= i;
|
||||
if (length == 0)
|
||||
break;
|
||||
|
||||
if (restricted && sizeof(buf) > length)
|
||||
readlen = length;
|
||||
if (sizeof(buf) > length)
|
||||
readlen = length;
|
||||
}
|
||||
}
|
||||
|
||||
md5_finish(&ctx, digest);
|
||||
@ -280,16 +282,16 @@ bool md5_file(ReadStream &stream, uint8 digest[16], uint32 length) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool md5_file_string(ReadStream &stream, char *md5str, uint32 length) {
|
||||
String computeStreamMD5AsString(ReadStream &stream, uint32 length) {
|
||||
String md5;
|
||||
uint8 digest[16];
|
||||
if (!md5_file(stream, digest, length))
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
snprintf(md5str + i*2, 3, "%02x", (int)digest[i]);
|
||||
if (computeStreamMD5(stream, digest, length)) {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
md5 += String::format("%02x", (int)digest[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return md5;
|
||||
}
|
||||
|
||||
} // End of namespace Common
|
||||
|
29
common/md5.h
29
common/md5.h
@ -26,18 +26,35 @@
|
||||
#define COMMON_MD5_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/str.h"
|
||||
|
||||
namespace Common {
|
||||
|
||||
class ReadStream;
|
||||
|
||||
bool md5_file(ReadStream &stream, uint8 digest[16], uint32 length = 0);
|
||||
/**
|
||||
* Compute the MD5 checksum of the content of the given ReadStream.
|
||||
* The 128 bit MD5 checksum is returned directly in the array digest.
|
||||
* If length is set to a positive value, then only the first length
|
||||
* bytes of the stream are used to compute the checksum.
|
||||
* @param[in] stream the stream of whose data the MD5 is computed
|
||||
* @param[out] digest the computed MD5 checksum
|
||||
* @param[in] length the number of bytes for which to compute the checksum; 0 means all
|
||||
* @return true on success, false if an error occurred
|
||||
*/
|
||||
bool computeStreamMD5(ReadStream &stream, uint8 digest[16], uint32 length = 0);
|
||||
|
||||
// The following method work similar to the above one, but
|
||||
// instead of computing the binary MD5 digest, it produces
|
||||
// a human readable lowercase hexstring representing the digest.
|
||||
// The md5str parameter must point to a buffer of 32+1 chars.
|
||||
bool md5_file_string(ReadStream &stream, char *md5str, uint32 length = 0);
|
||||
/**
|
||||
* Compute the MD5 checksum of the content of the given ReadStream.
|
||||
* The 128 bit MD5 checksum is converted to a human readable
|
||||
* lowercase hex string of length 32.
|
||||
* If length is set to a positive value, then only the first length
|
||||
* bytes of the stream are used to compute the checksum.
|
||||
* @param[in] stream the stream of whose data the MD5 is computed
|
||||
* @param[in] length the number of bytes for which to compute the checksum; 0 means all
|
||||
* @return the MD5 as a hex string on success, and an empty string if an error occurred
|
||||
*/
|
||||
String computeStreamMD5AsString(ReadStream &stream, uint32 length = 0);
|
||||
|
||||
} // End of namespace Common
|
||||
|
||||
|
@ -357,7 +357,7 @@ Common::Error AdvancedMetaEngine::createInstance(OSystem *syst, Engine **engine)
|
||||
|
||||
struct SizeMD5 {
|
||||
int size;
|
||||
char md5[32+1];
|
||||
Common::String md5;
|
||||
};
|
||||
|
||||
typedef Common::HashMap<Common::String, SizeMD5, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> SizeMD5Map;
|
||||
@ -374,7 +374,7 @@ static void reportUnknown(const Common::FSNode &path, const SizeMD5Map &filesSiz
|
||||
printf("of the game you tried to add and its version/language/etc.:\n");
|
||||
|
||||
for (SizeMD5Map::const_iterator file = filesSizeMD5.begin(); file != filesSizeMD5.end(); ++file)
|
||||
printf(" {\"%s\", 0, \"%s\", %d},\n", file->_key.c_str(), file->_value.md5, file->_value.size);
|
||||
printf(" {\"%s\", 0, \"%s\", %d},\n", file->_key.c_str(), file->_value.md5.c_str(), file->_value.size);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
@ -459,10 +459,9 @@ static ADGameDescList detectGame(const Common::FSList &fslist, const ADParams &p
|
||||
Common::MacResManager *macResMan = new Common::MacResManager();
|
||||
|
||||
if (macResMan->open(parent, fname)) {
|
||||
if (!macResMan->getResForkMD5(tmp.md5, params.md5Bytes))
|
||||
tmp.md5[0] = 0;
|
||||
tmp.md5 = macResMan->computeResForkMD5AsString(params.md5Bytes);
|
||||
tmp.size = macResMan->getResForkSize();
|
||||
debug(3, "> '%s': '%s'", fname.c_str(), tmp.md5);
|
||||
debug(3, "> '%s': '%s'", fname.c_str(), tmp.md5.c_str());
|
||||
filesSizeMD5[fname] = tmp;
|
||||
}
|
||||
|
||||
@ -475,14 +474,12 @@ static ADGameDescList detectGame(const Common::FSList &fslist, const ADParams &p
|
||||
|
||||
if (testFile.open(allFiles[fname])) {
|
||||
tmp.size = (int32)testFile.size();
|
||||
if (!md5_file_string(testFile, tmp.md5, params.md5Bytes))
|
||||
tmp.md5[0] = 0;
|
||||
tmp.md5 = Common::computeStreamMD5AsString(testFile, params.md5Bytes);
|
||||
} else {
|
||||
tmp.size = -1;
|
||||
tmp.md5[0] = 0;
|
||||
}
|
||||
|
||||
debug(3, "> '%s': '%s'", fname.c_str(), tmp.md5);
|
||||
debug(3, "> '%s': '%s'", fname.c_str(), tmp.md5.c_str());
|
||||
filesSizeMD5[fname] = tmp;
|
||||
}
|
||||
}
|
||||
@ -523,8 +520,8 @@ static ADGameDescList detectGame(const Common::FSList &fslist, const ADParams &p
|
||||
break;
|
||||
}
|
||||
|
||||
if (fileDesc->md5 != NULL && 0 != strcmp(fileDesc->md5, filesSizeMD5[tstr].md5)) {
|
||||
debug(3, "MD5 Mismatch. Skipping (%s) (%s)", fileDesc->md5, filesSizeMD5[tstr].md5);
|
||||
if (fileDesc->md5 != NULL && fileDesc->md5 != filesSizeMD5[tstr].md5) {
|
||||
debug(3, "MD5 Mismatch. Skipping (%s) (%s)", fileDesc->md5, filesSizeMD5[tstr].md5.c_str());
|
||||
fileMissing = true;
|
||||
break;
|
||||
}
|
||||
|
@ -459,9 +459,8 @@ int AgiEngine::agiLoadResource(int r, int n) {
|
||||
if (i == errOK && getGameID() == GID_GOLDRUSH && r == rPICTURE && n == 147 && _game.dirPic[n].len == 1982) {
|
||||
uint8 *pic = _game.pictures[n].rdata;
|
||||
Common::MemoryReadStream picStream(pic, _game.dirPic[n].len);
|
||||
char md5str[32+1];
|
||||
Common::md5_file_string(picStream, md5str, _game.dirPic[n].len);
|
||||
if (scumm_stricmp(md5str, "1c685eb048656cedcee4eb6eca2cecea") == 0) {
|
||||
Common::String md5str = Common::computeStreamMD5AsString(picStream, _game.dirPic[n].len);
|
||||
if (md5str == "1c685eb048656cedcee4eb6eca2cecea") {
|
||||
pic[0x042] = 0x4B; // 0x49 -> 0x4B
|
||||
pic[0x043] = 0x66; // 0x26 -> 0x66
|
||||
pic[0x204] = 0x68; // 0x28 -> 0x68
|
||||
|
@ -855,11 +855,10 @@ bool SoundGen2GS::loadInstrumentHeaders(const Common::FSNode &exePath, const IIg
|
||||
// Check instrument set's md5sum
|
||||
data->seek(exeInfo.instSetStart);
|
||||
|
||||
char md5str[32+1];
|
||||
Common::md5_file_string(*data, md5str, exeInfo.instSet.byteCount);
|
||||
if (scumm_stricmp(md5str, exeInfo.instSet.md5)) {
|
||||
Common::String md5str = Common::computeStreamMD5AsString(*data, exeInfo.instSet.byteCount);
|
||||
if (md5str != exeInfo.instSet.md5) {
|
||||
warning("Unknown Apple IIGS instrument set (md5: %s) in %s, trying to use it nonetheless",
|
||||
md5str, exePath.getPath().c_str());
|
||||
md5str.c_str(), exePath.getPath().c_str());
|
||||
}
|
||||
|
||||
// Read in the instrument set one instrument at a time
|
||||
@ -898,12 +897,11 @@ bool SoundGen2GS::loadWaveFile(const Common::FSNode &wavePath, const IIgsExeInfo
|
||||
// Check that we got the whole wave file
|
||||
if (uint8Wave && uint8Wave->size() == SIERRASTANDARD_SIZE) {
|
||||
// Check wave file's md5sum
|
||||
char md5str[32+1];
|
||||
Common::md5_file_string(*uint8Wave, md5str, SIERRASTANDARD_SIZE);
|
||||
if (scumm_stricmp(md5str, exeInfo.instSet.waveFileMd5)) {
|
||||
Common::String md5str = Common::computeStreamMD5AsString(*uint8Wave, SIERRASTANDARD_SIZE);
|
||||
if (md5str != exeInfo.instSet.waveFileMd5) {
|
||||
warning("Unknown Apple IIGS wave file (md5: %s, game: %s).\n" \
|
||||
"Please report the information on the previous line to the ScummVM team.\n" \
|
||||
"Using the wave file as it is - music may sound weird", md5str, exeInfo.exePrefix);
|
||||
"Using the wave file as it is - music may sound weird", md5str.c_str(), exeInfo.exePrefix);
|
||||
}
|
||||
|
||||
uint8Wave->seek(0); // Seek wave to its start
|
||||
|
@ -57,7 +57,7 @@ bool checkKyraDat(Common::SeekableReadStream *file) {
|
||||
|
||||
uint8 digestCalc[16];
|
||||
file->seek(0, SEEK_SET);
|
||||
if (!Common::md5_file(*file, digestCalc, size))
|
||||
if (!Common::computeStreamMD5(*file, digestCalc, size))
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < 16; ++i)
|
||||
|
@ -281,9 +281,8 @@ bool Debugger::cmdDumpFiles(int argc, const char **) {
|
||||
restoreArchive(); \
|
||||
return true; \
|
||||
} \
|
||||
char md5str[32+1]; \
|
||||
Common::md5_file_string(*stream, md5str, (uint32)stream->size()); \
|
||||
debugC(1, kLastExpressDebugResource, "%s, %d, %s", (*it)->getName().c_str(), stream->size(), (char *)&md5str); \
|
||||
Common::String md5str = Common::computeStreamMD5AsString(*stream); \
|
||||
debugC(1, kLastExpressDebugResource, "%s, %d, %s", (*it)->getName().c_str(), stream->size(), md5str.c_str()); \
|
||||
delete stream; \
|
||||
} \
|
||||
}
|
||||
|
@ -422,7 +422,6 @@ static void composeFileHashMap(const Common::FSList &fslist, DescMap &fileMD5Map
|
||||
static void detectGames(const Common::FSList &fslist, Common::List<DetectorResult> &results, const char *gameid) {
|
||||
DescMap fileMD5Map;
|
||||
DetectorResult dr;
|
||||
char md5str[32+1];
|
||||
|
||||
// Dive one level down since mac indy3/loom has its files split into directories. See Bug #1438631
|
||||
composeFileHashMap(fslist, fileMD5Map, 2, directoryGlobs);
|
||||
@ -479,10 +478,13 @@ static void detectGames(const Common::FSList &fslist, Common::List<DetectorResul
|
||||
tmp->open(d.node);
|
||||
}
|
||||
|
||||
if (tmp && tmp->isOpen() && Common::md5_file_string(*tmp, md5str, kMD5FileSizeLimit)) {
|
||||
Common::String md5str;
|
||||
if (tmp && tmp->isOpen())
|
||||
md5str = computeStreamMD5AsString(*tmp, kMD5FileSizeLimit);
|
||||
if (!md5str.empty()) {
|
||||
|
||||
d.md5 = md5str;
|
||||
d.md5Entry = findInMD5Table(md5str);
|
||||
d.md5Entry = findInMD5Table(md5str.c_str());
|
||||
|
||||
dr.md5 = d.md5;
|
||||
|
||||
@ -494,7 +496,7 @@ static void detectGames(const Common::FSList &fslist, Common::List<DetectorResul
|
||||
int filesize = tmp->size();
|
||||
if (d.md5Entry->filesize != filesize)
|
||||
debug(1, "SCUMM detector found matching file '%s' with MD5 %s, size %d\n",
|
||||
file.c_str(), md5str, filesize);
|
||||
file.c_str(), md5str.c_str(), filesize);
|
||||
|
||||
// Sanity check: We *should* have found a matching gameid / variant at this point.
|
||||
// If not, then there's a bug in our data tables...
|
||||
|
@ -1369,34 +1369,36 @@ bool ScummNESFile::generateIndex() {
|
||||
bool ScummNESFile::open(const Common::String &filename) {
|
||||
|
||||
if (_ROMset == kROMsetNum) {
|
||||
char md5str[32+1];
|
||||
Common::String md5str;
|
||||
File f;
|
||||
f.open(filename);
|
||||
if (f.isOpen() && Common::md5_file_string(f, md5str)) {
|
||||
if (f.isOpen())
|
||||
md5str = Common::computeStreamMD5AsString(f);
|
||||
if (!md5str.empty()) {
|
||||
|
||||
if (!strcmp(md5str, "3905799e081b80a61d4460b7b733c206")) {
|
||||
if (md5str == "3905799e081b80a61d4460b7b733c206") {
|
||||
_ROMset = kROMsetUSA;
|
||||
debug(1, "ROM contents verified as Maniac Mansion (USA)");
|
||||
} else if (!strcmp(md5str, "d8d07efcb88f396bee0b402b10c3b1c9")) {
|
||||
} else if (md5str == "d8d07efcb88f396bee0b402b10c3b1c9") {
|
||||
_ROMset = kROMsetEurope;
|
||||
debug(1, "ROM contents verified as Maniac Mansion (Europe)");
|
||||
} else if (!strcmp(md5str, "22d07d6c386c9c25aca5dac2a0c0d94b")) {
|
||||
} else if (md5str == "22d07d6c386c9c25aca5dac2a0c0d94b") {
|
||||
_ROMset = kROMsetSweden;
|
||||
debug(1, "ROM contents verified as Maniac Mansion (Sweden)");
|
||||
} else if (!strcmp(md5str, "81bbfa181184cb494e7a81dcfa94fbd9")) {
|
||||
} else if (md5str == "81bbfa181184cb494e7a81dcfa94fbd9") {
|
||||
_ROMset = kROMsetFrance;
|
||||
debug(2, "ROM contents verified as Maniac Mansion (France)");
|
||||
} else if (!strcmp(md5str, "257f8c14d8c584f7ddd601bcb00920c7")) {
|
||||
} else if (md5str == "257f8c14d8c584f7ddd601bcb00920c7") {
|
||||
_ROMset = kROMsetGermany;
|
||||
debug(2, "ROM contents verified as Maniac Mansion (Germany)");
|
||||
} else if (!strcmp(md5str, "f163cf53f7850e43fb482471e5c52e1a")) {
|
||||
} else if (md5str == "f163cf53f7850e43fb482471e5c52e1a") {
|
||||
_ROMset = kROMsetSpain;
|
||||
debug(2, "ROM contents verified as Maniac Mansion (Spain)");
|
||||
} else if (!strcmp(md5str, "54a68a5f5e3c86da42b7ca5f51e79b1d")) {
|
||||
} else if (md5str == "54a68a5f5e3c86da42b7ca5f51e79b1d") {
|
||||
_ROMset = kROMsetItaly;
|
||||
debug(2, "ROM contents verified as Maniac Mansion (Italy)");
|
||||
} else {
|
||||
error("Unsupported Maniac Mansion ROM, md5: %s", md5str);
|
||||
error("Unsupported Maniac Mansion ROM, md5: %s", md5str.c_str());
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
|
@ -191,7 +191,7 @@ bool TinselMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGa
|
||||
|
||||
struct SizeMD5 {
|
||||
int size;
|
||||
char md5[32+1];
|
||||
Common::String md5;
|
||||
};
|
||||
typedef Common::HashMap<Common::String, SizeMD5, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> SizeMD5Map;
|
||||
typedef Common::HashMap<Common::String, Common::FSNode, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> FileMap;
|
||||
@ -268,11 +268,9 @@ const ADGameDescription *TinselMetaEngine::fallbackDetect(const Common::FSList &
|
||||
|
||||
if (testFile.open(allFiles[fname])) {
|
||||
tmp.size = (int32)testFile.size();
|
||||
if (!md5_file_string(testFile, tmp.md5, detectionParams.md5Bytes))
|
||||
tmp.md5[0] = 0;
|
||||
tmp.md5 = computeStreamMD5AsString(testFile, detectionParams.md5Bytes);
|
||||
} else {
|
||||
tmp.size = -1;
|
||||
tmp.md5[0] = 0;
|
||||
}
|
||||
|
||||
filesSizeMD5[fname] = tmp;
|
||||
@ -318,7 +316,7 @@ const ADGameDescription *TinselMetaEngine::fallbackDetect(const Common::FSList &
|
||||
break;
|
||||
}
|
||||
|
||||
if (fileDesc->md5 != NULL && 0 != strcmp(fileDesc->md5, filesSizeMD5[tstr].md5)) {
|
||||
if (fileDesc->md5 != NULL && fileDesc->md5 != filesSizeMD5[tstr].md5) {
|
||||
fileMissing = true;
|
||||
break;
|
||||
}
|
||||
|
@ -29,14 +29,14 @@ static const char *md5_test_digest[] = {
|
||||
|
||||
class MD5TestSuite : public CxxTest::TestSuite {
|
||||
public:
|
||||
void test_md5_file() {
|
||||
void test_computeStreamMD5() {
|
||||
int i, j;
|
||||
char output[33];
|
||||
unsigned char md5sum[16];
|
||||
|
||||
for (i = 0; i < 7; i++) {
|
||||
Common::MemoryReadStream stream((const byte *)md5_test_string[i], strlen(md5_test_string[i]));
|
||||
Common::md5_file(stream, md5sum);
|
||||
Common::computeStreamMD5(stream, md5sum);
|
||||
|
||||
for (j = 0; j < 16; j++) {
|
||||
sprintf(output + j * 2, "%02x", md5sum[j]);
|
||||
|
Loading…
x
Reference in New Issue
Block a user