diff options
| -rw-r--r-- | engines/scumm/he/resource_he.cpp | 1038 | ||||
| -rw-r--r-- | engines/scumm/he/resource_he.h | 310 | 
2 files changed, 99 insertions, 1249 deletions
diff --git a/engines/scumm/he/resource_he.cpp b/engines/scumm/he/resource_he.cpp index 72e7052034..987ee1ebe3 100644 --- a/engines/scumm/he/resource_he.cpp +++ b/engines/scumm/he/resource_he.cpp @@ -4,7 +4,7 @@   * are too numerous to list here. Please refer to the COPYRIGHT   * file distributed with this source distribution.   * - * Parts of this code are heavily based on: + * Parts of this code are based on:   * icoutils - A set of programs dealing with MS Windows icons and cursors.   * Copyright (C) 1998-2001 Oskar Liljeblad   * @@ -43,14 +43,6 @@  namespace Scumm { -#if defined(SCUMM_LITTLE_ENDIAN) -#define LE16(x) -#define LE32(x) -#elif defined(SCUMM_BIG_ENDIAN) -#define LE16(x)      ((x) = TO_LE_16(x)) -#define LE32(x)      ((x) = TO_LE_32(x)) -#endif -  ResExtractor::ResExtractor(ScummEngine_v70he *scumm)  	: _vm(scumm) { @@ -126,912 +118,134 @@ void ResExtractor::setCursor(int id) {  } -/* - * Static variables - */ -const char *res_types[] = { -	/* 0x01: */ -	"cursor", "bitmap", "icon", "menu", "dialog", "string", -	"fontdir", "font", "accelerator", "rcdata", "messagelist", -	"group_cursor", NULL, "group_icon", NULL, -	/* the following are not defined in winbase.h, but found in wrc. */ -	/* 0x10: */ -	"version", "dlginclude", NULL, "plugplay", "vxd", -	"anicursor", "aniicon" -}; -#define RES_TYPE_COUNT (sizeof(res_types)/sizeof(char *)) -  Win32ResExtractor::Win32ResExtractor(ScummEngine_v70he *scumm) : ResExtractor(scumm) {  }  int Win32ResExtractor::extractResource(int resId, byte **data) { -	char buf[20]; - -	snprintf(buf, sizeof(buf), "%d", resId); - -	return extractResource_("group_cursor", buf, data); -} - -int Win32ResExtractor::extractResource_(const char *resType, char *resName, byte **data) { -	char *arg_language = NULL; -	const char *arg_type = resType; -	char *arg_name = resName; -	int ressize = 0; - -	_arg_raw = false; - -	/* translate --type option from resource type string to integer */ -	arg_type = res_type_string_to_id(arg_type); - -	WinLibrary fi; - -	/* initiate stuff */ -	fi.memory = NULL; -	fi.file = NULL; -  	if (_fileName.empty()) { // We are running for the first time  		_fileName = _vm->generateFilename(-3); -	} - -	/* get file size */ -	fi.file = SearchMan.createReadStreamForMember(_fileName); -	if (!fi.file) { -		error("Cannot open file %s", _fileName.c_str()); -	} - -	fi.total_size = fi.file->size(); -	if (fi.total_size == -1) { -		error("Cannot get size of file %s", _fileName.c_str()); -		goto cleanup; -	} -	if (fi.total_size == 0) { -		error("%s: file has a size of 0", _fileName.c_str()); -		goto cleanup; -	} - -	/* read all of file */ -	fi.memory = (byte *)malloc(fi.total_size); -	if (fi.file->read(fi.memory, fi.total_size) == 0) { -		error("Cannot read from file %s", _fileName.c_str()); -		goto cleanup; -	} - -	/* identify file and find resource table */ -	if (!read_library(&fi)) { -		/* error reported by read_library */ -		goto cleanup; -	} - -	/* errors will be printed by the callback */ -	ressize = do_resources(&fi, arg_type, arg_name, arg_language, data); - -	/* free stuff and close file */ -	cleanup: -	delete fi.file; -	free(fi.memory); - -	return ressize; -} - - -/** - * Translate a numeric resource type to it's corresponding string type. - * (For informative-ness.) - */ -const char *Win32ResExtractor::res_type_id_to_string(int id) { -	if (id == 241) -		return "toolbar"; -	if (id > 0 && id <= (int)RES_TYPE_COUNT) -		return res_types[id-1]; -	return NULL; -} - -/** - * Translate a resource type string to integer. - * (Used to convert the --type option.) - */ -const char *Win32ResExtractor::res_type_string_to_id(const char *type) { -	static const char *res_type_ids[] = { -		"-1", "-2", "-3", "-4", "-5", "-6", "-7", "-8", "-9", "-10", -		"-11", "-12", NULL, "-14", NULL, "-16", "-17", NULL, "-19", -		"-20", "-21", "-22" -	}; -	int c; - -	if (type == NULL) -		return NULL; - -	for (c = 0; c < (int)RES_TYPE_COUNT; c++) { -		if (res_types[c] != NULL && !scumm_stricmp(type, res_types[c])) -			return res_type_ids[c]; -	} - -	return type; -} - -/** - * Return the resource id quoted if it is a string, otherwise (i.e. if - * it is numeric) just return it. - */ -Common::String Win32ResExtractor::WinResource::getQuotedResourceId() const { -	if (numeric_id || id[0] == '\0') -		return id; -	return '"' + Common::String(id) + '"'; -} - -int Win32ResExtractor::extract_resources(WinLibrary *fi, WinResource *wr, -							WinResource *type_wr, WinResource *name_wr, -							WinResource *lang_wr, byte **data) { -	int size; -	bool free_it; -	const char *type; -	int32 id; - -	if (*data) { -		error("Win32ResExtractor::extract_resources() more than one cursor"); -		return 0; -	} - -	*data = extract_resource(fi, wr, &size, &free_it, type_wr->id, (lang_wr == NULL ? NULL : lang_wr->id), _arg_raw); -	if (data == NULL) { -		error("Win32ResExtractor::extract_resources() problem with resource extraction"); -		return 0; -	} - -	/* get named resource type if possible */ -	type = NULL; -	if ((id = strtol(type_wr->id, 0, 10)) != 0) -		type = res_type_id_to_string(id); - -	if (lang_wr != NULL && lang_wr->id[0] != '\0') { -		debugC(DEBUG_RESOURCE, "extractCursor(). Found cursor name: %s language: %s [size=%d]", -		  name_wr->getQuotedResourceId().c_str(), lang_wr->getQuotedResourceId().c_str(), size); -	} else { -		debugC(DEBUG_RESOURCE, "extractCursor(). Found cursor name: %s [size=%d]", -		  name_wr->getQuotedResourceId().c_str(), size); -	} -	return size; -} - -/** - * Extract a resource, returning pointer to data. - */ -byte *Win32ResExtractor::extract_resource(WinLibrary *fi, WinResource *wr, int *size, -				  bool *free_it, char *type, char *lang, bool raw) { -	char *str; -	int32 intval; - -	/* just return pointer to data if raw */ -	if (raw) { -		*free_it = false; -		/* get_resource_entry will print possible error */ -		return get_resource_entry(fi, wr, size); -	} - -	/* find out how to extract */ -	str = type; -	if (str != NULL && (intval = strtol(STRIP_RES_ID_FORMAT(str), 0, 10))) { -		if (intval == (int)RT_GROUP_ICON) { -			*free_it = true; -			return extract_group_icon_cursor_resource(fi, wr, lang, size, true); -		} -		if (intval == (int)RT_GROUP_CURSOR) { -			*free_it = true; -			return extract_group_icon_cursor_resource(fi, wr, lang, size, false); -		} -	} - -	return NULL; -} - -/** - * Create a complete RT_GROUP_ICON resource, that can be written to - * an `.ico' file without modifications. Returns an allocated - * memory block that should be freed with free() once used. - * - * `root' is the offset in file that specifies the resource. - * `base' is the offset that string pointers are calculated from. - * `ressize' should point to an integer variable where the size of - * the returned memory block will be placed. - * `is_icon' indicates whether resource to be extracted is icon - * or cursor group. - */ -byte *Win32ResExtractor::extract_group_icon_cursor_resource(WinLibrary *fi, WinResource *wr, char *lang, -								   int *ressize, bool is_icon) { -	Win32CursorIconDir *icondir; -	Win32CursorIconFileDir *fileicondir; -	byte *memory; -	int c, offset, skipped; -	int size; - -	/* get resource data and size */ -	icondir = (Win32CursorIconDir *)get_resource_entry(fi, wr, &size); -	if (icondir == NULL) { -		/* get_resource_entry will print error */ -		return NULL; -	} - -	/* calculate total size of output file */ -	RETURN_IF_BAD_POINTER(NULL, icondir->count); -	skipped = 0; -	for (c = 0; c < FROM_LE_16(icondir->count); c++) { -		int level; -		int iconsize; -		char name[14]; -		WinResource *fwr; - -		RETURN_IF_BAD_POINTER(NULL, icondir->entries[c]); -		/*debug("%d. bytes_in_res=%d width=%d height=%d planes=%d bit_count=%d", c, -			FROM_LE_32(icondir->entries[c].bytes_in_res), -			(is_icon ? icondir->entries[c].res_info.icon.width : FROM_LE_16(icondir->entries[c].res_info.cursor.width)), -			(is_icon ? icondir->entries[c].res_info.icon.height : FROM_LE_16(icondir->entries[c].res_info.cursor.height)), -			FROM_LE_16(icondir->entries[c].plane_count), -			FROM_LE_16(icondir->entries[c].bit_count));*/ - -		/* find the corresponding icon resource */ -		snprintf(name, sizeof(name)/sizeof(char), "-%d", FROM_LE_16(icondir->entries[c].res_id)); -		fwr = find_resource(fi, (is_icon ? "-3" : "-1"), name, lang, &level); -		if (fwr == NULL) { -			error("%s: could not find `%s' in `%s' resource.", -					_fileName.c_str(), &name[1], (is_icon ? "group_icon" : "group_cursor")); -			return NULL; -		} - -		if (get_resource_entry(fi, fwr, &iconsize) != NULL) { -			if (iconsize == 0) { -				debugC(DEBUG_RESOURCE, "%s: icon resource `%s' is empty, skipping", _fileName.c_str(), name); -				skipped++; -				continue; -			} -			if ((uint32)iconsize != FROM_LE_32(icondir->entries[c].bytes_in_res)) { -				debugC(DEBUG_RESOURCE, "%s: mismatch of size in icon resource `%s' and group (%d != %d)", -					_fileName.c_str(), name, iconsize, FROM_LE_32(icondir->entries[c].bytes_in_res)); -			} -			size += iconsize; /* size += FROM_LE_32(icondir->entries[c].bytes_in_res); */ - -			/* cursor resources have two additional WORDs that contain -			 * hotspot info */ -			if (!is_icon) -			size -= sizeof(uint16)*2; -		} -	} -	offset = sizeof(Win32CursorIconFileDir) + (FROM_LE_16(icondir->count)-skipped) * sizeof(Win32CursorIconFileDirEntry); -	size += offset; -	*ressize = size; - -	/* allocate that much memory */ -	memory = (byte *)malloc(size); -	fileicondir = (Win32CursorIconFileDir *)memory; - -	/* transfer Win32CursorIconDir structure members */ -	fileicondir->reserved = icondir->reserved; -	fileicondir->type = icondir->type; -	fileicondir->count = TO_LE_16(FROM_LE_16(icondir->count) - skipped); - -	/* transfer each cursor/icon: Win32CursorIconDirEntry and data */ -	skipped = 0; -	for (c = 0; c < FROM_LE_16(icondir->count); c++) { -		int level; -		char name[14]; -		WinResource *fwr; -		byte *data; - -		/* find the corresponding icon resource */ -		snprintf(name, sizeof(name)/sizeof(char), "-%d", FROM_LE_16(icondir->entries[c].res_id)); -		fwr = find_resource(fi, (is_icon ? "-3" : "-1"), name, lang, &level); -		if (fwr == NULL) { -			error("%s: could not find `%s' in `%s' resource.", -				_fileName.c_str(), &name[1], (is_icon ? "group_icon" : "group_cursor")); -			return NULL; -		} - -		/* get data and size of that resource */ -		data = (byte *)get_resource_entry(fi, fwr, &size); -		if (data == NULL) { -			/* get_resource_entry has printed error */ -			return NULL; -		} -		if (size == 0) { -			skipped++; -			continue; -		} - -		/* copy ICONDIRENTRY (not including last dwImageOffset) */ -		memcpy(&fileicondir->entries[c-skipped], &icondir->entries[c], -			sizeof(Win32CursorIconFileDirEntry)-sizeof(uint32)); - -		/* special treatment for cursors */ -		if (!is_icon) { -			fileicondir->entries[c-skipped].width = icondir->entries[c].res_info.cursor.width; -			fileicondir->entries[c-skipped].height = TO_LE_16(FROM_LE_16(icondir->entries[c].res_info.cursor.height) / 2); -			fileicondir->entries[c-skipped].color_count = 0; -			fileicondir->entries[c-skipped].reserved = 0; -		} - -		/* set image offset and increase it */ -		fileicondir->entries[c-skipped].dib_offset = TO_LE_32(offset); - -		/* transfer resource into file memory */ -		if (is_icon) { -			memcpy(&memory[offset], data, FROM_LE_32(icondir->entries[c].bytes_in_res)); -		} else { -			fileicondir->entries[c-skipped].hotspot_x = ((uint16 *) data)[0]; -			fileicondir->entries[c-skipped].hotspot_y = ((uint16 *) data)[1]; -			memcpy(&memory[offset], data+sizeof(uint16)*2, -				   FROM_LE_32(icondir->entries[c].bytes_in_res)-sizeof(uint16)*2); -			offset -= sizeof(uint16)*2; -		} - -		/* increase the offset pointer */ -		offset += FROM_LE_32(icondir->entries[c].bytes_in_res); +		if (!_exe.loadFromEXE(_fileName)) +			error("Cannot open file %s", _fileName.c_str());  	} -	return memory; -} - -/** - * Check if a chunk of data (determined by offset and size) - * is within the bounds of the WinLibrary file. - * Usually not called directly. - */ -bool Win32ResExtractor::check_offset(byte *memory, int total_size, const char *name, void *offset, int size) { -	int need_size = (int)((byte *)offset - memory + size); - -	debugC(DEBUG_RESOURCE, "check_offset: size=%x vs %x offset=%x size=%x", -		need_size, total_size, (uint)((byte *)offset - memory), size); +	Common::SeekableReadStream *cursorGroup = _exe.getResource(Common::kPEGroupCursor, resId); -	if (need_size < 0 || need_size > total_size) { -		error("%s: premature end", name); -		return false; -	} +	if (!cursorGroup) +		error("Could not find cursor group %d", resId); -	return true; -} +	cursorGroup->skip(4); +	uint16 count = cursorGroup->readUint16LE(); +	assert(count > 0); +	cursorGroup->skip(12); +	resId = cursorGroup->readUint16LE(); -/** - * Do something for each resource matching type, name and lang. - */ -int Win32ResExtractor::do_resources(WinLibrary *fi, const char *type, char *name, char *lang, byte **data) { -	WinResource *type_wr; -	WinResource *name_wr; -	WinResource *lang_wr; -	int size; +	delete cursorGroup; -	type_wr = (WinResource *)calloc(3, sizeof(WinResource)); -	name_wr = type_wr + 1; -	lang_wr = type_wr + 2; +	Common::SeekableReadStream *cursor = _exe.getResource(Common::kPECursor, resId); -	size = do_resources_recurs(fi, NULL, type_wr, name_wr, lang_wr, type, name, lang, data); +	if (!cursor) +		error("Could not find cursor %d", resId); -	free(type_wr); +	int size = cursor->size(); +	*data = (byte *)malloc(size); +	cursor->read(*data, size); +	delete cursor;  	return size;  } -/* what is each entry in this directory level for? type, name or language? */ -#define WINRESOURCE_BY_LEVEL(x) ((x)==0 ? type_wr : ((x)==1 ? name_wr : lang_wr)) - -/* does the id of this entry match the specified id? */ -#define LEVEL_MATCHES(x) (x == NULL || x ## _wr->id[0] == '\0' || compare_resource_id(x ## _wr, x)) - -int Win32ResExtractor::do_resources_recurs(WinLibrary *fi, WinResource *base, -		  WinResource *type_wr, WinResource *name_wr, WinResource *lang_wr, -		  const char *type, char *name, char *lang, byte **data) { -	int c, rescnt; -	WinResource *wr; -	uint32 size = 0; - -	/* get a list of all resources at this level */ -	wr = list_resources(fi, base, &rescnt); -	if (wr == NULL) { -		return size; -	} - -	/* process each resource listed */ -	for (c = 0; c < rescnt; c++) { -		/* (over)write the corresponding WinResource holder with the current */ -		memcpy(WINRESOURCE_BY_LEVEL(wr[c].level), wr+c, sizeof(WinResource)); - -		/* go deeper unless there is something that does NOT match */ -		if (LEVEL_MATCHES(type) && LEVEL_MATCHES(name) && LEVEL_MATCHES(lang)) { -			if (wr->is_directory) -				size = do_resources_recurs(fi, wr+c, type_wr, name_wr, lang_wr, type, name, lang, data); -			else -				size = extract_resources(fi, wr+c, type_wr, name_wr, lang_wr, data); -		} -	} - -	/* since we're moving back one level after this, unset the -	 * WinResource holder used on this level */ -	memset(WINRESOURCE_BY_LEVEL(wr[0].level), 0, sizeof(WinResource)); - -	return size; -} - -bool Win32ResExtractor::compare_resource_id(WinResource *wr, const char *id) { -	if (wr->numeric_id) { -		int32 cmp1, cmp2; -		if (id[0] == '+') -			return false; -		if (id[0] == '-') -			id++; -		cmp1 = strtol(wr->id, 0, 10); -		cmp2 = strtol(id, 0, 10); -		if (!cmp1 || !cmp2 || cmp1 != cmp2) -			return false; -	} else { -		if (id[0] == '-') -			return false; -		if (id[0] == '+') -			id++; -		if (strcmp(wr->id, id)) -			return false; -	} - -	return true; -} - -bool Win32ResExtractor::decode_pe_resource_id(WinLibrary *fi, WinResource *wr, uint32 value) { -	if (value & IMAGE_RESOURCE_NAME_IS_STRING) {	/* numeric id */ -		int c, len; -		uint16 *mem = (uint16 *) -		  (fi->first_resource + (value & ~IMAGE_RESOURCE_NAME_IS_STRING)); - -		/* copy each char of the string, and terminate it */ -		RETURN_IF_BAD_POINTER(false, *mem); -		len = FROM_LE_16(mem[0]); -		RETURN_IF_BAD_OFFSET(false, &mem[1], sizeof(uint16) * len); - -		len = MIN(FROM_LE_16(mem[0]), (uint16)WINRES_ID_MAXLEN); -		for (c = 0; c < len; c++) -			wr->id[c] = FROM_LE_16(mem[c+1]) & 0x00FF; -		wr->id[len] = '\0'; -		wr->numeric_id = false; -	} else {					/* Unicode string id */ -		/* translate id into a string */ -		snprintf(wr->id, WINRES_ID_MAXLEN, "%d", value); -		wr->numeric_id = true; -	} - -	return true; -} - -byte *Win32ResExtractor::get_resource_entry(WinLibrary *fi, WinResource *wr, int *size) { -	byte *result; - -	Win32ImageResourceDataEntry *dataent; - -	dataent = (Win32ImageResourceDataEntry *) wr->children; -	RETURN_IF_BAD_POINTER(NULL, *dataent); -	*size = FROM_LE_32(dataent->size); - -	result = fi->memory + FROM_LE_32(dataent->offset_to_data); - -	RETURN_IF_BAD_OFFSET(NULL, result, *size); - -	return result; -} - -Win32ResExtractor::WinResource *Win32ResExtractor::list_pe_resources(WinLibrary *fi, Win32ImageResourceDirectory *pe_res, int level, int *count) { -	WinResource *wr; -	int c, rescnt; -	Win32ImageResourceDirectoryEntry *dirent -	  = (Win32ImageResourceDirectoryEntry *)(pe_res + 1); - -	/* count number of `type' resources */ -	RETURN_IF_BAD_POINTER(NULL, *dirent); -	rescnt = FROM_LE_16(pe_res->number_of_named_entries) + FROM_LE_16(pe_res->number_of_id_entries); -	*count = rescnt; - -	/* allocate WinResource's */ -	wr = (WinResource *)malloc(sizeof(WinResource) * rescnt); - -	/* fill in the WinResource's */ -	for (c = 0; c < rescnt; c++) { -		RETURN_IF_BAD_POINTER(NULL, dirent[c]); -		wr[c].this_ = pe_res; -		wr[c].level = level; -		wr[c].is_directory = ((FROM_LE_32(dirent[c].offset_to_data) & IMAGE_RESOURCE_DATA_IS_DIRECTORY) != 0); -		wr[c].children = fi->first_resource + (FROM_LE_32(dirent[c].offset_to_data) & ~IMAGE_RESOURCE_DATA_IS_DIRECTORY); - -		/* fill in wr->id, wr->numeric_id */ -		if (!decode_pe_resource_id(fi, wr + c, FROM_LE_32(dirent[c].name))) { -			free(wr); -			return NULL; -		} -	} - -	return wr; -} - - -/** - * Return an array of WinResource's in the current - * resource level specified by _res-> - */ -Win32ResExtractor::WinResource *Win32ResExtractor::list_resources(WinLibrary *fi, WinResource *res, int *count) { -	if (res != NULL && !res->is_directory) -		return NULL; - -	return list_pe_resources(fi, (Win32ImageResourceDirectory *) -			 (res == NULL ? fi->first_resource : res->children), -			 (res == NULL ? 0 : res->level+1), -			 count); -} - -/** - * Read header and get resource directory offset in a Windows library - * (AKA module). - */ -bool Win32ResExtractor::read_library(WinLibrary *fi) { -	/* check for DOS header signature `MZ' */ -	RETURN_IF_BAD_POINTER(false, MZ_HEADER(fi->memory)->magic); -	if (FROM_LE_16(MZ_HEADER(fi->memory)->magic) == IMAGE_DOS_SIGNATURE) { -		DOSImageHeader *mz_header = MZ_HEADER(fi->memory); - -		RETURN_IF_BAD_POINTER(false, mz_header->lfanew); - -		// Apply endian fix (currently only lfanew is used from the DOSImageHeader, -		// so we don't bother to 'fix' the rest). -		LE32(mz_header->lfanew); - -		if (mz_header->lfanew < sizeof(DOSImageHeader)) { -			error("%s: not a Windows library", _fileName.c_str()); -			return false; -		} -	} - -	/* check for NT header signature `PE' */ -	RETURN_IF_BAD_POINTER(false, PE_HEADER(fi->memory)->signature); -	if (FROM_LE_32(PE_HEADER(fi->memory)->signature) == IMAGE_NT_SIGNATURE) { -		Win32ImageNTHeaders *pe_header; -		int d; +#define ROW_BYTES(bits) ((((bits) + 31) >> 5) << 2) -		// Fix image header endianess -		fix_win32_image_header_endian(PE_HEADER(fi->memory)); +int Win32ResExtractor::convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h, +			int *hotspot_x, int *hotspot_y, int *keycolor, byte **pal, int *palSize) { -		/* allocate new memory */ -		fi->total_size = calc_vma_size(fi); -		if (fi->total_size == 0) { -			/* calc_vma_size has reported error */ -			return false; -		} -		byte *ptr = (byte *)realloc(fi->memory, fi->total_size); -		assert(ptr); -		fi->memory = ptr; - -		/* relocate memory, start from last section */ -		pe_header = PE_HEADER(fi->memory); -		RETURN_IF_BAD_POINTER(false, pe_header->file_header.number_of_sections); - -		/* we don't need to do OFFSET checking for the sections. -		 * calc_vma_size has already done that */ -		for (d = pe_header->file_header.number_of_sections - 1; d >= 0; d--) { -			Win32ImageSectionHeader *pe_sec = PE_SECTIONS(fi->memory) + d; - -			if (pe_sec->characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) -				continue; - -			//if (pe_sec->virtual_address + pe_sec->size_of_raw_data > fi->total_size) - -			RETURN_IF_BAD_OFFSET(0, fi->memory + pe_sec->virtual_address, pe_sec->size_of_raw_data); -			RETURN_IF_BAD_OFFSET(0, fi->memory + pe_sec->pointer_to_raw_data, pe_sec->size_of_raw_data); -			if (FROM_LE_32(pe_sec->virtual_address) != pe_sec->pointer_to_raw_data) { -				memmove(fi->memory + pe_sec->virtual_address, -						fi->memory + pe_sec->pointer_to_raw_data, -						pe_sec->size_of_raw_data); -			} -		} +	Common::MemoryReadStream *in = new Common::MemoryReadStream(data, datasize); -		/* find resource directory */ -		RETURN_IF_BAD_POINTER(false, pe_header->optional_header.data_directory[IMAGE_DIRECTORY_ENTRY_RESOURCE]); -		Win32ImageDataDirectory *dir = pe_header->optional_header.data_directory + IMAGE_DIRECTORY_ENTRY_RESOURCE; -		if (dir->size == 0) { -			error("%s: file contains no resources", _fileName.c_str()); -			return false; -		} +	*hotspot_x = in->readUint16LE(); +	*hotspot_y = in->readUint16LE(); -		fix_win32_image_data_directory(dir); +	Win32BitmapInfoHeader bitmap; -		fi->first_resource = fi->memory + dir->virtual_address; -		return true; -	} +	in->read(&bitmap, sizeof(Win32BitmapInfoHeader)); -	/* other (unknown) header signature was found */ -	error("%s: not a Windows library", _fileName.c_str()); -	return false; -} +	fix_win32_bitmap_info_header_endian(&bitmap); +	if (bitmap.size < sizeof(Win32BitmapInfoHeader)) +		error("bitmap header is too short"); -/** - * Calculate the total amount of memory needed for a 32-bit Windows - * module. Returns -1 if file was too small. - */ -int Win32ResExtractor::calc_vma_size(WinLibrary *fi) { -	Win32ImageSectionHeader *seg; -	int c, segcount, size; - -	size = 0; -	RETURN_IF_BAD_POINTER(-1, PE_HEADER(fi->memory)->file_header.number_of_sections); -	segcount = PE_HEADER(fi->memory)->file_header.number_of_sections; - -	/* If there are no segments, just process file like it is. -	 * This is (probably) not the right thing to do, but problems -	 * will be delt with later anyway. -	 */ -	if (segcount == 0) -		return fi->total_size; - -	seg = PE_SECTIONS(fi->memory); -	RETURN_IF_BAD_POINTER(-1, *seg); -	for (c = 0; c < segcount; c++) { -		RETURN_IF_BAD_POINTER(0, *seg); -		fix_win32_image_section_header(seg); - -		size = MAX((uint32)size, seg->virtual_address + seg->size_of_raw_data); -		/* I have no idea what misc.virtual_size is for... */ -		size = MAX((uint32)size, seg->virtual_address + seg->misc.virtual_size); -		seg++; -	} +	if (bitmap.compression != 0) +		error("compressed image data not supported"); -	return size; -} +	if (bitmap.x_pels_per_meter != 0) +		error("x_pels_per_meter field in bitmap should be zero"); -Win32ResExtractor::WinResource *Win32ResExtractor::find_with_resource_array(WinLibrary *fi, WinResource *wr, const char *id) { -	int c, rescnt; -	WinResource *return_wr; +	if (bitmap.y_pels_per_meter != 0) +		error("y_pels_per_meter field in bitmap should be zero"); -	wr = list_resources(fi, wr, &rescnt); -	if (wr == NULL) -		return NULL; +	if (bitmap.clr_important != 0) +		error("clr_important field in bitmap should be zero"); -	for (c = 0; c < rescnt; c++) { -		if (compare_resource_id(&wr[c], id)) { -			/* duplicate WinResource and return it */ -			return_wr = (WinResource *)malloc(sizeof(WinResource)); -			memcpy(return_wr, &wr[c], sizeof(WinResource)); +	if (bitmap.planes != 1) +		error("planes field in bitmap should be one"); -			/* free old WinResource */ -			free(wr); -			return return_wr; -		} +	Win32RGBQuad *palette = NULL; +	uint32 palette_count = 0; +	if (bitmap.clr_used != 0 || bitmap.bit_count < 24) { +		palette_count = (bitmap.clr_used != 0 ? bitmap.clr_used : 1 << bitmap.bit_count); +		palette = (Win32RGBQuad *)malloc(sizeof(Win32RGBQuad) * palette_count); +		in->read(palette, sizeof(Win32RGBQuad) * palette_count);  	} -	return NULL; -} +	uint32 width = bitmap.width; +	uint32 height = ABS(bitmap.height) / 2; -Win32ResExtractor::WinResource *Win32ResExtractor::find_resource(WinLibrary *fi, const char *type, const char *name, const char *language, int *level) { -	WinResource *wr; +	uint32 image_size = height * ROW_BYTES(width * bitmap.bit_count); +	uint32 mask_size = height * ROW_BYTES(width); -	*level = 0; -	if (type == NULL) -		return NULL; -	wr = find_with_resource_array(fi, NULL, type); -	if (wr == NULL || !wr->is_directory) -		return wr; - -	*level = 1; -	if (name == NULL) -		return wr; -	wr = find_with_resource_array(fi, wr, name); -	if (wr == NULL || !wr->is_directory) -		return wr; - -	*level = 2; -	if (language == NULL) -		return wr; -	wr = find_with_resource_array(fi, wr, language); -	return wr; -} - -#define ROW_BYTES(bits) ((((bits) + 31) >> 5) << 2) - - -int Win32ResExtractor::convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h, -			int *hotspot_x, int *hotspot_y, int *keycolor, byte **pal, int *palSize) { -	Win32CursorIconFileDir dir; -	Win32CursorIconFileDirEntry *entries = NULL; -	uint32 offset; -	uint32 c, d; -	int completed; -	int matched = 0; -	Common::MemoryReadStream *in = new Common::MemoryReadStream(data, datasize); - -	if (!in->read(&dir, sizeof(Win32CursorIconFileDir)- sizeof(Win32CursorIconFileDirEntry))) -		goto cleanup; -	fix_win32_cursor_icon_file_dir_endian(&dir); - -	if (dir.reserved != 0) { -		error("not an icon or cursor file (reserved non-zero)"); -		goto cleanup; -	} -	if (dir.type != 1 && dir.type != 2) { -		error("not an icon or cursor file (wrong type)"); -		goto cleanup; -	} +	byte *image_data = (byte *)malloc(image_size); +	in->read(image_data, image_size); -	entries = (Win32CursorIconFileDirEntry *)malloc(dir.count * sizeof(Win32CursorIconFileDirEntry)); -	for (c = 0; c < dir.count; c++) { -		if (!in->read(&entries[c], sizeof(Win32CursorIconFileDirEntry))) -			goto cleanup; -		fix_win32_cursor_icon_file_dir_entry_endian(&entries[c]); -		if (entries[c].reserved != 0) -			error("reserved is not zero"); -	} +	byte *mask_data = (byte *)malloc(mask_size); +	in->read(mask_data, mask_size); -	offset = sizeof(Win32CursorIconFileDir) + (dir.count - 1) * (sizeof(Win32CursorIconFileDirEntry)); - -	for (completed = 0; completed < dir.count; ) { -		uint32 min_offset = 0x7fffffff; -		int previous = completed; - -		for (c = 0; c < dir.count; c++) { -			if (entries[c].dib_offset == offset) { -				Win32BitmapInfoHeader bitmap; -				Win32RGBQuad *palette = NULL; -				uint32 palette_count = 0; -				uint32 image_size, mask_size; -				uint32 width, height; -				byte *image_data = NULL, *mask_data = NULL; -				byte *row = NULL; - -				if (!in->read(&bitmap, sizeof(Win32BitmapInfoHeader))) -					goto local_cleanup; - -				fix_win32_bitmap_info_header_endian(&bitmap); -				if (bitmap.size < sizeof(Win32BitmapInfoHeader)) { -					error("bitmap header is too short"); -					goto local_cleanup; -				} -				if (bitmap.compression != 0) { -					error("compressed image data not supported"); -					goto local_cleanup; -				} -				if (bitmap.x_pels_per_meter != 0) -					error("x_pels_per_meter field in bitmap should be zero"); -				if (bitmap.y_pels_per_meter != 0) -					error("y_pels_per_meter field in bitmap should be zero"); -				if (bitmap.clr_important != 0) -					error("clr_important field in bitmap should be zero"); -				if (bitmap.planes != 1) -					error("planes field in bitmap should be one"); -				if (bitmap.size != sizeof(Win32BitmapInfoHeader)) { -					uint32 skip = bitmap.size - sizeof(Win32BitmapInfoHeader); -					error("skipping %d bytes of extended bitmap header", skip); -					in->seek(skip, SEEK_CUR); -				} -				offset += bitmap.size; - -				if (bitmap.clr_used != 0 || bitmap.bit_count < 24) { -					palette_count = (bitmap.clr_used != 0 ? bitmap.clr_used : 1 << bitmap.bit_count); -					palette = (Win32RGBQuad *)malloc(sizeof(Win32RGBQuad) * palette_count); -					if (!in->read(palette, sizeof(Win32RGBQuad) * palette_count)) -						goto local_cleanup; -					offset += sizeof(Win32RGBQuad) * palette_count; -				} - -				width = bitmap.width; -				height = ABS(bitmap.height)/2; - -				image_size = height * ROW_BYTES(width * bitmap.bit_count); -				mask_size = height * ROW_BYTES(width); - -				if (entries[c].dib_size	!= bitmap.size + image_size + mask_size + palette_count * sizeof(Win32RGBQuad)) -					debugC(DEBUG_RESOURCE, "incorrect total size of bitmap (%d specified; %d real)", -						entries[c].dib_size, -						(int)(bitmap.size + image_size + mask_size + palette_count * sizeof(Win32RGBQuad)) -					); - -				image_data = (byte *)malloc(image_size); -				if (!in->read(image_data, image_size)) -					goto local_cleanup; - -				mask_data = (byte *)malloc(mask_size); -				if (!in->read(mask_data, mask_size)) -					goto local_cleanup; - -				offset += image_size; -				offset += mask_size; -				completed++; -				matched++; - -				*hotspot_x = entries[c].hotspot_x; -				*hotspot_y = entries[c].hotspot_y; -				*w = width; -				*h = height; -				*keycolor = 0; -				*cursor = (byte *)malloc(width * height); - -				row = (byte *)malloc(width * 4); - -				for (d = 0; d < height; d++) { -					uint32 x; -					uint32 y = (bitmap.height < 0 ? d : height - d - 1); -					uint32 imod = y * (image_size / height) * 8 / bitmap.bit_count; -					uint32 mmod = y * (mask_size / height) * 8; - -					for (x = 0; x < width; x++) { - -						uint32 color = simple_vec(image_data, x + imod, bitmap.bit_count); - -						// We set up cursor palette for default cursor, so use it -						if (!simple_vec(mask_data, x + mmod, 1)) { -							if (color) { -								cursor[0][width * d + x] = 254; // white -							} else { -								cursor[0][width * d + x] = 253; // black -							} -						} else { -							cursor[0][width * d + x] = 255; // transparent -						} -						/* - -						if (bitmap.bit_count <= 16) { -							if (color >= palette_count) { -								error("color out of range in image data"); -								goto local_cleanup; -							} -							row[4*x+0] = palette[color].red; -							row[4*x+1] = palette[color].green; -							row[4*x+2] = palette[color].blue; - -						} else { -							row[4*x+0] = (color >> 16) & 0xFF; -							row[4*x+1] = (color >>  8) & 0xFF; -							row[4*x+2] = (color >>  0) & 0xFF; -						} -						if (bitmap.bit_count == 32) -							row[4*x+3] = (color >> 24) & 0xFF; -						else -							row[4*x+3] = simple_vec(mask_data, x + mmod, 1) ? 0 : 0xFF; -						*/ -					} - -				} - -				free(row); -				free(palette); -				if (image_data != NULL) { -					free(image_data); -					free(mask_data); -				} -				continue; - -			local_cleanup: - -				free(row); -				free(palette); -				if (image_data != NULL) { -					free(image_data); -					free(mask_data); -				} -				goto cleanup; +	 +	*w = width; +	*h = height; +	*keycolor = 0; +	*cursor = (byte *)malloc(width * height); + +	byte *row = (byte *)malloc(width * 4); + +	for (uint32 d = 0; d < height; d++) { +		uint32 y = (bitmap.height < 0 ? d : height - d - 1); +		uint32 imod = y * (image_size / height) * 8 / bitmap.bit_count; +		uint32 mmod = y * (mask_size / height) * 8; + +		for (uint32 x = 0; x < width; x++) { +			uint32 color = simple_vec(image_data, x + imod, bitmap.bit_count); + +			// HACK: Ignore the actual cursor palette and use SCUMM's +			if (!simple_vec(mask_data, x + mmod, 1)) { +				if (color) +					cursor[0][width * d + x] = 254; // white +				else +					cursor[0][width * d + x] = 253; // black  			} else { -				if (entries[c].dib_offset > offset) -					min_offset = MIN(min_offset, entries[c].dib_offset); +				cursor[0][width * d + x] = 255; // transparent  			}  		} -		if (previous == completed) { -			if (min_offset < offset) { -				error("offset of bitmap header incorrect (too low)"); -				goto cleanup; -			} -			assert(min_offset != 0x7fffffff); -			debugC(DEBUG_RESOURCE, "skipping %d bytes of garbage at %d", min_offset-offset, offset); -			in->seek(min_offset - offset, SEEK_CUR); -			offset = min_offset; -		}  	} -	free(entries); -	return matched; - -cleanup: +	free(row); +	free(palette); +	if (image_data != NULL) { +		free(image_data); +		free(mask_data); +	} -	free(entries); -	return -1; +	return 1;  }  uint32 Win32ResExtractor::simple_vec(byte *data, uint32 ofs, byte size) { @@ -1055,11 +269,13 @@ uint32 Win32ResExtractor::simple_vec(byte *data, uint32 ofs, byte size) {  	return 0;  } -void Win32ResExtractor::fix_win32_cursor_icon_file_dir_endian(Win32CursorIconFileDir *obj) { -	LE16(obj->reserved); -	LE16(obj->type); -	LE16(obj->count); -} +#if defined(SCUMM_LITTLE_ENDIAN) +#define LE16(x) +#define LE32(x) +#elif defined(SCUMM_BIG_ENDIAN) +#define LE16(x)      ((x) = TO_LE_16(x)) +#define LE32(x)      ((x) = TO_LE_32(x)) +#endif  void Win32ResExtractor::fix_win32_bitmap_info_header_endian(Win32BitmapInfoHeader *obj) {  	LE32(obj->size); @@ -1075,76 +291,8 @@ void Win32ResExtractor::fix_win32_bitmap_info_header_endian(Win32BitmapInfoHeade  	LE32(obj->clr_important);  } -void Win32ResExtractor::fix_win32_cursor_icon_file_dir_entry_endian(Win32CursorIconFileDirEntry *obj) { -	LE16(obj->hotspot_x); -	LE16(obj->hotspot_y); -	LE32(obj->dib_size); -	LE32(obj->dib_offset); -} - -void Win32ResExtractor::fix_win32_image_section_header(Win32ImageSectionHeader *obj) { -	LE32(obj->misc.physical_address); -	LE32(obj->virtual_address); -	LE32(obj->size_of_raw_data); -	LE32(obj->pointer_to_raw_data); -	LE32(obj->pointer_to_relocations); -	LE32(obj->pointer_to_linenumbers); -	LE16(obj->number_of_relocations); -	LE16(obj->number_of_linenumbers); -	LE32(obj->characteristics); -} - -/* fix_win32_image_header_endian: - * NOTE: This assumes that the optional header is always available. - */ -void Win32ResExtractor::fix_win32_image_header_endian(Win32ImageNTHeaders *obj) { -	LE32(obj->signature); -	LE16(obj->file_header.machine); -	LE16(obj->file_header.number_of_sections); -	LE32(obj->file_header.time_date_stamp); -	LE32(obj->file_header.pointer_to_symbol_table); -	LE32(obj->file_header.number_of_symbols); -	LE16(obj->file_header.size_of_optional_header); -	LE16(obj->file_header.characteristics); - -	// FIXME: Does this assert ever trigger? If so, we should modify this function -	// to properly deal with it. -	assert(obj->file_header.size_of_optional_header >= sizeof(obj->optional_header)); -	LE16(obj->optional_header.magic); -	LE32(obj->optional_header.size_of_code); -	LE32(obj->optional_header.size_of_initialized_data); -	LE32(obj->optional_header.size_of_uninitialized_data); -	LE32(obj->optional_header.address_of_entry_point); -	LE32(obj->optional_header.base_of_code); -	LE32(obj->optional_header.base_of_data); -	LE32(obj->optional_header.image_base); -	LE32(obj->optional_header.section_alignment); -	LE32(obj->optional_header.file_alignment); -	LE16(obj->optional_header.major_operating_system_version); -	LE16(obj->optional_header.minor_operating_system_version); -	LE16(obj->optional_header.major_image_version); -	LE16(obj->optional_header.minor_image_version); -	LE16(obj->optional_header.major_subsystem_version); -	LE16(obj->optional_header.minor_subsystem_version); -	LE32(obj->optional_header.win32_version_value); -	LE32(obj->optional_header.size_of_image); -	LE32(obj->optional_header.size_of_headers); -	LE32(obj->optional_header.checksum); -	LE16(obj->optional_header.subsystem); -	LE16(obj->optional_header.dll_characteristics); -	LE32(obj->optional_header.size_of_stack_reserve); -	LE32(obj->optional_header.size_of_stack_commit); -	LE32(obj->optional_header.size_of_heap_reserve); -	LE32(obj->optional_header.size_of_heap_commit); -	LE32(obj->optional_header.loader_flags); -	LE32(obj->optional_header.number_of_rva_and_sizes); -} - -void Win32ResExtractor::fix_win32_image_data_directory(Win32ImageDataDirectory *obj) { -	LE32(obj->virtual_address); -	LE32(obj->size); -} - +#undef LE16 +#undef LE32  MacResExtractor::MacResExtractor(ScummEngine_v70he *scumm) : ResExtractor(scumm) {  	_resMgr = NULL; diff --git a/engines/scumm/he/resource_he.h b/engines/scumm/he/resource_he.h index 6b4c3fe493..9dddc96f23 100644 --- a/engines/scumm/he/resource_he.h +++ b/engines/scumm/he/resource_he.h @@ -4,7 +4,7 @@   * are too numerous to list here. Please refer to the COPYRIGHT   * file distributed with this source distribution.   * - * Parts of this code are heavily based on: + * Parts of this code are based on:   * icoutils - A set of programs dealing with MS Windows icons and cursors.   * Copyright (C) 1998-2001 Oskar Liljeblad   * @@ -31,89 +31,10 @@  #define SCUMM_HE_RESOURCE_HE_H  #include "common/macresman.h" +#include "common/pe_exe.h"  namespace Scumm { -#define WINRES_ID_MAXLEN (256) - -/* - * Definitions - */ - -#define MZ_HEADER(x)	((DOSImageHeader *)(x)) - -#define STRIP_RES_ID_FORMAT(x) (x != NULL && (x[0] == '-' || x[0] == '+') ? ++x : x) - -#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 -#define IMAGE_SIZEOF_SHORT_NAME 8 - -#define	IMAGE_RESOURCE_NAME_IS_STRING		0x80000000 -#define	IMAGE_RESOURCE_DATA_IS_DIRECTORY	0x80000000 - -#define PE_HEADER(module) \ -    ((Win32ImageNTHeaders*)((byte *)(module) + \ -		(((DOSImageHeader*)(module))->lfanew))) - -#define PE_SECTIONS(module) \ -    ((Win32ImageSectionHeader *)((byte *) &PE_HEADER(module)->optional_header + \ -                           PE_HEADER(module)->file_header.size_of_optional_header)) - -#define IMAGE_DOS_SIGNATURE    0x5A4D     /* MZ */ -#define IMAGE_NT_SIGNATURE     0x00004550 /* PE00 */ - -/* The following symbols below and another group a few lines below are defined in - * the windows header, at least in wince and most likely in plain win32 as well. - * Defining them out silences a redefinition warning in gcc. - * If the same problem arises in win32 builds as well, please replace - * _WIN32_WCE with _WIN32 which is also defined in the wince platform. - */ -#ifndef _WIN32_WCE -#define IMAGE_SCN_CNT_CODE			0x00000020 -#define IMAGE_SCN_CNT_INITIALIZED_DATA		0x00000040 -#define IMAGE_SCN_CNT_UNINITIALIZED_DATA	0x00000080 -#endif - -// Only IMAGE_DIRECTORY_ENTRY_RESOURCE is used: -#define	IMAGE_DIRECTORY_ENTRY_EXPORT		0 -#define	IMAGE_DIRECTORY_ENTRY_IMPORT		1 -#define	IMAGE_DIRECTORY_ENTRY_RESOURCE		2 -#define	IMAGE_DIRECTORY_ENTRY_EXCEPTION		3 -#define	IMAGE_DIRECTORY_ENTRY_SECURITY		4 -#define	IMAGE_DIRECTORY_ENTRY_BASERELOC		5 -#define	IMAGE_DIRECTORY_ENTRY_DEBUG			6 -#define	IMAGE_DIRECTORY_ENTRY_COPYRIGHT		7 -#define	IMAGE_DIRECTORY_ENTRY_GLOBALPTR		8   /* (MIPS GP) */ -#define	IMAGE_DIRECTORY_ENTRY_TLS			9 -#define	IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG	10 -#define	IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT	11 -#define	IMAGE_DIRECTORY_ENTRY_IAT			12  /* Import Address Table */ -#define	IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT	13 -#define	IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR	14 - -#ifndef _WIN32_WCE -// Only RT_GROUP_CURSOR and RT_GROUP_ICON are used -#define RT_CURSOR        1 -#define RT_BITMAP        2 -#define RT_ICON          3 -#define RT_MENU          4 -#define RT_DIALOG        5 -#define RT_STRING        6 -#define RT_FONTDIR       7 -#define RT_FONT          8 -#define RT_ACCELERATOR   9 -#define RT_RCDATA        10 -#define RT_MESSAGELIST   11 -#define RT_GROUP_CURSOR  12 -#define RT_GROUP_ICON    14 -#endif - -#define RETURN_IF_BAD_POINTER(r, x) \ -	if (!check_offset(fi->memory, fi->total_size, _fileName.c_str(), &(x), sizeof(x))) \ -		return (r); -#define RETURN_IF_BAD_OFFSET(r, x, s) \ -	if (!check_offset(fi->memory, fi->total_size, _fileName.c_str(), x, s)) \ -		return (r); -  class ScummEngine_v70he;  class ResExtractor { @@ -154,7 +75,7 @@ public:  };  class Win32ResExtractor : public ResExtractor { - public: +public:  	Win32ResExtractor(ScummEngine_v70he *scumm);  	~Win32ResExtractor() {}  	int extractResource(int id, byte **data); @@ -162,81 +83,15 @@ class Win32ResExtractor : public ResExtractor {  	int convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h,  			 int *hotspot_x, int *hotspot_y, int *keycolor, byte **palette, int *palSize); - private: -	int extractResource_(const char *resType, char *resName, byte **data); +private: +	Common::PEResources _exe; +  /*   * Structures   */  #include "common/pack-start.h"	// START STRUCT PACKING -	struct WinLibrary { -		Common::SeekableReadStream *file; -		byte *memory; -		byte *first_resource; -		int total_size; -	} PACKED_STRUCT; - -	struct WinResource { -		char id[256]; -		void *this_; -		void *children; -		int level; -		bool numeric_id; -		bool is_directory; - -		Common::String getQuotedResourceId() const; -	} PACKED_STRUCT; - - -	struct Win32IconResDir { -		byte width; -		byte height; -		byte color_count; -		byte reserved; -	} PACKED_STRUCT; - -	struct Win32CursorDir { -		uint16 width; -		uint16 height; -	} PACKED_STRUCT; - -	struct Win32CursorIconDirEntry { -		union { -			Win32IconResDir icon; -			Win32CursorDir cursor; -		} res_info; -		uint16 plane_count; -		uint16 bit_count; -		uint32 bytes_in_res; -		uint16 res_id; -	} PACKED_STRUCT; - -	struct Win32CursorIconDir { -		uint16 reserved; -		uint16 type; -		uint16 count; -		Win32CursorIconDirEntry entries[1]; -	} PACKED_STRUCT; - -	struct Win32CursorIconFileDirEntry { -		byte width; -		byte height; -		byte color_count; -		byte reserved; -		uint16 hotspot_x; -		uint16 hotspot_y; -		uint32 dib_size; -		uint32 dib_offset; -	} PACKED_STRUCT; - -	struct Win32CursorIconFileDir { -		uint16 reserved; -		uint16 type; -		uint16 count; -		Win32CursorIconFileDirEntry entries[1]; -	} PACKED_STRUCT; -  	struct Win32BitmapInfoHeader {  		uint32 size;  		int32 width; @@ -258,163 +113,10 @@ class Win32ResExtractor : public ResExtractor {  		byte reserved;  	} PACKED_STRUCT; -	struct Win32ImageResourceDirectoryEntry { -		uint32 name; -		uint32 offset_to_data; -	} PACKED_STRUCT; - -	struct Win16NETypeInfo { -		uint16 type_id; -		uint16 count; -		uint32 resloader;     // FARPROC16 - smaller? uint16? -	} PACKED_STRUCT; - -	struct DOSImageHeader { -		uint16 magic; -		uint16 cblp; -		uint16 cp; -		uint16 crlc; -		uint16 cparhdr; -		uint16 minalloc; -		uint16 maxalloc; -		uint16 ss; -		uint16 sp; -		uint16 csum; -		uint16 ip; -		uint16 cs; -		uint16 lfarlc; -		uint16 ovno; -		uint16 res[4]; -		uint16 oemid; -		uint16 oeminfo; -		uint16 res2[10]; -		uint32 lfanew; -	} PACKED_STRUCT; - -	struct Win32ImageFileHeader { -		uint16 machine; -		uint16 number_of_sections; -		uint32 time_date_stamp; -		uint32 pointer_to_symbol_table; -		uint32 number_of_symbols; -		uint16 size_of_optional_header; -		uint16 characteristics; -	} PACKED_STRUCT; - -	struct Win32ImageDataDirectory { -		uint32 virtual_address; -		uint32 size; -	} PACKED_STRUCT; - -	struct Win32ImageOptionalHeader { -		uint16 magic; -		byte major_linker_version; -		byte minor_linker_version; -		uint32 size_of_code; -		uint32 size_of_initialized_data; -		uint32 size_of_uninitialized_data; -		uint32 address_of_entry_point; -		uint32 base_of_code; -		uint32 base_of_data; -		uint32 image_base; -		uint32 section_alignment; -		uint32 file_alignment; -		uint16 major_operating_system_version; -		uint16 minor_operating_system_version; -		uint16 major_image_version; -		uint16 minor_image_version; -		uint16 major_subsystem_version; -		uint16 minor_subsystem_version; -		uint32 win32_version_value; -		uint32 size_of_image; -		uint32 size_of_headers; -		uint32 checksum; -		uint16 subsystem; -		uint16 dll_characteristics; -		uint32 size_of_stack_reserve; -		uint32 size_of_stack_commit; -		uint32 size_of_heap_reserve; -		uint32 size_of_heap_commit; -		uint32 loader_flags; -		uint32 number_of_rva_and_sizes; -		Win32ImageDataDirectory data_directory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; -	} PACKED_STRUCT; - -	struct Win32ImageNTHeaders { -		uint32 signature; -		Win32ImageFileHeader file_header; -		Win32ImageOptionalHeader optional_header; -	} PACKED_STRUCT; - -	struct Win32ImageSectionHeader { -		byte name[IMAGE_SIZEOF_SHORT_NAME]; -		union { -			uint32 physical_address; -			uint32 virtual_size; -		} misc; -		uint32 virtual_address; -		uint32 size_of_raw_data; -		uint32 pointer_to_raw_data; -		uint32 pointer_to_relocations; -		uint32 pointer_to_linenumbers; -		uint16 number_of_relocations; -		uint16 number_of_linenumbers; -		uint32 characteristics; -	} PACKED_STRUCT; - -	struct Win32ImageResourceDataEntry { -		uint32 offset_to_data; -		uint32 size; -		uint32 code_page; -		uint32 resource_handle; -	} PACKED_STRUCT; - -	struct Win32ImageResourceDirectory { -		uint32 characteristics; -		uint32 time_date_stamp; -		uint16 major_version; -		uint16 minor_version; -		uint16 number_of_named_entries; -		uint16 number_of_id_entries; -	} PACKED_STRUCT; -  #include "common/pack-end.h"	// END STRUCT PACKING -/* - * Function Prototypes - */ - -	WinResource *list_resources(WinLibrary *, WinResource *, int *); -	bool read_library(WinLibrary *); -	WinResource *find_resource(WinLibrary *, const char *, const char *, const char *, int *); -	byte *get_resource_entry(WinLibrary *, WinResource *, int *); -	int do_resources(WinLibrary *, const char *, char *, char *, byte **); -	bool compare_resource_id(WinResource *, const char *); -	const char *res_type_string_to_id(const char *); - -	const char *res_type_id_to_string(int); -	char *get_destination_name(WinLibrary *, char *, char *, char *); - -	byte *extract_resource(WinLibrary *, WinResource *, int *, bool *, char *, char *, bool); -	int extract_resources(WinLibrary *, WinResource *, WinResource *, WinResource *, WinResource *, byte **); -	byte *extract_group_icon_cursor_resource(WinLibrary *, WinResource *, char *, int *, bool); - -	bool decode_pe_resource_id(WinLibrary *, WinResource *, uint32); -	WinResource *list_pe_resources(WinLibrary *, Win32ImageResourceDirectory *, int, int *); -	int calc_vma_size(WinLibrary *); -	int do_resources_recurs(WinLibrary *, WinResource *, WinResource *, WinResource *, WinResource *, const char *, char *, char *, byte **); -	WinResource *find_with_resource_array(WinLibrary *, WinResource *, const char *); - -	bool check_offset(byte *, int, const char *, void *, int); -  	uint32 simple_vec(byte *data, uint32 ofs, byte size); - -	void fix_win32_cursor_icon_file_dir_endian(Win32CursorIconFileDir *obj);  	void fix_win32_bitmap_info_header_endian(Win32BitmapInfoHeader *obj); -	void fix_win32_cursor_icon_file_dir_entry_endian(Win32CursorIconFileDirEntry *obj); -	void fix_win32_image_section_header(Win32ImageSectionHeader *obj); -	void fix_win32_image_header_endian(Win32ImageNTHeaders *obj); -	void fix_win32_image_data_directory(Win32ImageDataDirectory *obj);  };  class MacResExtractor : public ResExtractor {  | 
