[librpbase] IResourceReader: New function lookup_resource_ID().

This function takes a zero-based index and returns a resource ID for
the given resource type if it's within range. Otherwise, it returns
a negative POSIX error code.

[libromdata] PEResourceReader, NEResourceReader: Implement it.

[libromdata] EXE: Use lookup_resource_ID for positive icon indexes.

This fixes thumbnailing for discs whose AUTORUN.INF specify a
positive, non-zero icon index.

TODO: Older discs may have truncated ISO-9660 filenames. Need to
parse Joliet file systems, maybe...
This commit is contained in:
David Korth 2025-06-08 12:44:35 -04:00
parent 55cad0ad98
commit 993e52084d
6 changed files with 103 additions and 4 deletions

View File

@ -405,8 +405,11 @@ rp_image_const_ptr EXEPrivate::loadSpecificIcon(int iconindex)
} else if (iconindex > 0) {
// Positive icon index
// This is a zero-based index into the RT_GROUP_ICON table.
// TODO: Add IResourceReader function to get a resource ID from a zero-based index.
return {};
resID = rsrcReader->lookup_resource_ID(RT_GROUP_ICON, iconindex);
if (resID < 0) {
// Not found.
return {};
}
} else {
// Negative icon index
// This is an actual resource ID.

View File

@ -646,11 +646,13 @@ IRpFilePtr NEResourceReader::open(uint16_t type, int id, int lang)
// Get the directory for the specified type.
auto iter_dir = d->res_types.find(type);
if (iter_dir == d->res_types.end())
if (iter_dir == d->res_types.end()) {
return nullptr;
}
auto &dir = iter_dir->second;
if (dir.empty())
if (dir.empty()) {
return nullptr;
}
const NEResourceReaderPrivate::ResTblEntry *entry = nullptr;
if (id == -1) {
@ -781,4 +783,37 @@ int NEResourceReader::load_VS_VERSION_INFO(int id, int lang, VS_FIXEDFILEINFO *p
return 0;
}
/**
* Look up a resource ID given a zero-based index.
* Mostly useful for icon indexes.
*
* @param type [in] Resource type ID
* @param index [in] Zero-based index
* @param lang [in] Language ID (-1 for "first entry")
* @return Resource ID, or negative POSIX error code on error.
*/
int NEResourceReader::lookup_resource_ID(int type, int index)
{
if (index < 0) {
return -EINVAL;
}
// Get the resource directory for this type.
RP_D(NEResourceReader);
auto iter_find = d->res_types.find(type);
if (iter_find == d->res_types.end()) {
// Not found.
return -ENOENT;
}
const NEResourceReaderPrivate::rsrc_dir_t &type_dir = iter_find->second;
if (index >= static_cast<int>(type_dir.size())) {
// Zero-based index is out of bounds.
return -ENOENT;
}
// Return the ID at this index.
return type_dir[index].id;
}
}

View File

@ -116,6 +116,16 @@ public:
* @return 0 on success; non-zero on error.
*/
int load_VS_VERSION_INFO(int id, int lang, VS_FIXEDFILEINFO *pVsFfi, StringFileInfo *pVsSfi) final;
/**
* Look up a resource ID given a zero-based index.
* Mostly useful for icon indexes.
*
* @param type [in] Resource type ID
* @param index [in] Zero-based index
* @return Resource ID, or negative POSIX error code on error.
*/
int lookup_resource_ID(int type, int index) final;
};
}

View File

@ -861,4 +861,35 @@ int PEResourceReader::load_VS_VERSION_INFO(int id, int lang, VS_FIXEDFILEINFO *p
return 0;
}
/**
* Look up a resource ID given a zero-based index.
* Mostly useful for icon indexes.
*
* @param type [in] Resource type ID
* @param index [in] Zero-based index
* @param lang [in] Language ID (-1 for "first entry")
* @return Resource ID, or negative POSIX error code on error.
*/
int PEResourceReader::lookup_resource_ID(int type, int index)
{
if (index < 0) {
return -EINVAL;
}
// Get the resource directory for this type.
RP_D(PEResourceReader);
const PEResourceReaderPrivate::rsrc_dir_t *type_dir = d->getTypeDir(type);
if (!type_dir) {
return -ENOENT;
}
if (index >= static_cast<int>(type_dir->size())) {
// Zero-based index is out of bounds.
return -ENOENT;
}
// Return the ID at this index.
return type_dir->at(index).id;
}
}

View File

@ -117,6 +117,16 @@ public:
* @return 0 on success; non-zero on error.
*/
int load_VS_VERSION_INFO(int id, int lang, VS_FIXEDFILEINFO *pVsFfi, StringFileInfo *pVsSfi) final;
/**
* Look up a resource ID given a zero-based index.
* Mostly useful for icon indexes.
*
* @param type [in] Resource type ID
* @param index [in] Zero-based index
* @return Resource ID, or negative POSIX error code on error.
*/
int lookup_resource_ID(int type, int index) final;
};
}

View File

@ -119,6 +119,16 @@ public:
* @return 0 on success; non-zero on error.
*/
virtual int load_VS_VERSION_INFO(int id, int lang, VS_FIXEDFILEINFO *pVsFfi, StringFileInfo *pVsSfi) = 0;
/**
* Look up a resource ID given a zero-based index.
* Mostly useful for icon indexes.
*
* @param type [in] Resource type ID
* @param index [in] Zero-based index
* @return Resource ID, or negative POSIX error code on error.
*/
virtual int lookup_resource_ID(int type, int index) = 0;
};
typedef std::shared_ptr<IResourceReader> IResourceReaderPtr;