Changeset - r19019:2eb1d8782aac
[Not reviewed]
master
0 3 0
michi_cc - 13 years ago 2012-02-04 13:29:00
michi_cc@openttd.org
(svn r23886) -Codechange: Allow limiting the MD5 file hash to the first x bytes of the file.
3 files changed with 22 insertions and 5 deletions:
0 comments (0 inline, 0 general)
src/base_media_base.h
Show inline comments
 
@@ -30,13 +30,13 @@ struct MD5File {
 
	};
 

	
 
	const char *filename;        ///< filename
 
	uint8 hash[16];              ///< md5 sum of the file
 
	const char *missing_warning; ///< warning when this file is missing
 

	
 
	ChecksumResult CheckMD5(Subdirectory subdir) const;
 
	ChecksumResult CheckMD5(Subdirectory subdir, size_t max_size) const;
 
};
 

	
 
/**
 
 * Information about a single base set.
 
 * @tparam T the real class we're going to be
 
 * @tparam Tnum_files the number of files in the set
 
@@ -126,12 +126,26 @@ struct BaseSet {
 
				if (strncmp(iter->first, isocode, 2) == 0) return iter->second;
 
			}
 
		}
 
		/* Then fall back */
 
		return this->description.Begin()->second;
 
	}
 

	
 
	/**
 
	 * Calculate and check the MD5 hash of the supplied file.
 
	 * @param file The file get the hash of.
 
	 * @param subdir The sub directory to get the files from.
 
	 * @return
 
	 * - #CR_MATCH if the MD5 hash matches
 
	 * - #CR_MISMATCH if the MD5 does not match
 
	 * - #CR_NO_FILE if the file misses
 
	 */
 
	static MD5File::ChecksumResult CheckMD5(const MD5File *file, Subdirectory subdir)
 
	{
 
		return file->CheckMD5(subdir, SIZE_MAX);
 
	}
 
};
 

	
 
/**
 
 * Base for all base media (graphics, sounds)
 
 * @tparam Tbase_set the real set we're going to be
 
 */
src/base_media_func.h
Show inline comments
 
@@ -128,13 +128,13 @@ bool BaseSet<T, Tnum_files, Tsearch_in_t
 
			DEBUG(grf, 1, "No origin warning message specified for: %s", filename);
 
			file->missing_warning = strdup("");
 
		} else {
 
			file->missing_warning = strdup(item->value);
 
		}
 

	
 
		switch (file->CheckMD5(BASESET_DIR)) {
 
		switch (T::CheckMD5(file, BASESET_DIR)) {
 
			case MD5File::CR_MATCH:
 
				this->valid_files++;
 
				/* FALL THROUGH */
 
			case MD5File::CR_MISMATCH:
 
				this->found_files++;
 
				break;
src/gfxinit.cpp
Show inline comments
 
@@ -116,26 +116,26 @@ void CheckExternalFiles()
 
	const char *last = lastof(error_msg);
 

	
 
	if (used_set->GetNumInvalid() != 0) {
 
		/* Not all files were loaded successfully, see which ones */
 
		add_pos += seprintf(add_pos, last, "Trying to load graphics set '%s', but it is incomplete. The game will probably not run correctly until you properly install this set or select another one. See section 4.1 of readme.txt.\n\nThe following files are corrupted or missing:\n", used_set->name);
 
		for (uint i = 0; i < GraphicsSet::NUM_FILES; i++) {
 
			MD5File::ChecksumResult res = used_set->files[i].CheckMD5(BASESET_DIR);
 
			MD5File::ChecksumResult res = GraphicsSet::CheckMD5(&used_set->files[i], BASESET_DIR);
 
			if (res != MD5File::CR_MATCH) add_pos += seprintf(add_pos, last, "\t%s is %s (%s)\n", used_set->files[i].filename, res == MD5File::CR_MISMATCH ? "corrupt" : "missing", used_set->files[i].missing_warning);
 
		}
 
		add_pos += seprintf(add_pos, last, "\n");
 
	}
 

	
 
	const SoundsSet *sounds_set = BaseSounds::GetUsedSet();
 
	if (sounds_set->GetNumInvalid() != 0) {
 
		add_pos += seprintf(add_pos, last, "Trying to load sound set '%s', but it is incomplete. The game will probably not run correctly until you properly install this set or select another one. See section 4.1 of readme.txt.\n\nThe following files are corrupted or missing:\n", sounds_set->name);
 

	
 
		assert_compile(SoundsSet::NUM_FILES == 1);
 
		/* No need to loop each file, as long as there is only a single
 
		 * sound file. */
 
		add_pos += seprintf(add_pos, last, "\t%s is %s (%s)\n", sounds_set->files->filename, sounds_set->files->CheckMD5(BASESET_DIR) == MD5File::CR_MISMATCH ? "corrupt" : "missing", sounds_set->files->missing_warning);
 
		add_pos += seprintf(add_pos, last, "\t%s is %s (%s)\n", sounds_set->files->filename, SoundsSet::CheckMD5(sounds_set->files, BASESET_DIR) == MD5File::CR_MISMATCH ? "corrupt" : "missing", sounds_set->files->missing_warning);
 
	}
 

	
 
	if (add_pos != error_msg) ShowInfoF("%s", error_msg);
 
}
 

	
 
/** Actually load the sprite tables. */
 
@@ -263,24 +263,27 @@ bool GraphicsSet::FillSetDetails(IniFile
 
}
 

	
 

	
 
/**
 
 * Calculate and check the MD5 hash of the supplied filename.
 
 * @param subdir The sub directory to get the files from
 
 * @param max_size Only calculate the hash for this many bytes from the file start.
 
 * @return
 
 * - #CR_MATCH if the MD5 hash matches
 
 * - #CR_MISMATCH if the MD5 does not match
 
 * - #CR_NO_FILE if the file misses
 
 */
 
MD5File::ChecksumResult MD5File::CheckMD5(Subdirectory subdir) const
 
MD5File::ChecksumResult MD5File::CheckMD5(Subdirectory subdir, size_t max_size) const
 
{
 
	size_t size;
 
	FILE *f = FioFOpenFile(this->filename, "rb", subdir, &size);
 

	
 
	if (f == NULL) return CR_NO_FILE;
 

	
 
	size = min(size, max_size);
 

	
 
	Md5 checksum;
 
	uint8 buffer[1024];
 
	uint8 digest[16];
 
	size_t len;
 

	
 
	while ((len = fread(buffer, 1, (size > sizeof(buffer)) ? sizeof(buffer) : size, f)) != 0 && size != 0) {
0 comments (0 inline, 0 general)