mirror of
https://github.com/GerbilSoft/rom-properties.git
synced 2025-06-18 19:45:41 -04:00
[libromdata] ISO: Load the entire AUTORUN.INF for display purposes.
It's not displayed yet, but it's loaded. The section names are concatenated with the key names, e.g.: "autorun|icon" IsoPartition::open(): Set m_lastError = ENOENT if the file isn't found.
This commit is contained in:
parent
5083161c23
commit
1897ac198f
@ -36,6 +36,7 @@ using namespace LibRpTexture;
|
|||||||
using std::array;
|
using std::array;
|
||||||
using std::string;
|
using std::string;
|
||||||
using std::unique_ptr;
|
using std::unique_ptr;
|
||||||
|
using std::unordered_map;
|
||||||
using std::vector;
|
using std::vector;
|
||||||
|
|
||||||
namespace LibRomData {
|
namespace LibRomData {
|
||||||
@ -213,8 +214,18 @@ public:
|
|||||||
// Icon
|
// Icon
|
||||||
rp_image_ptr img_icon;
|
rp_image_ptr img_icon;
|
||||||
|
|
||||||
// Icon filename (from AUTORUN.INF)
|
// IsoPartition
|
||||||
string icon_filename;
|
IsoPartitionPtr isoPartition;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open the ISO-9660 partition.
|
||||||
|
* @return 0 on success; negative POSIX error code on error.
|
||||||
|
*/
|
||||||
|
int openIsoPartition(void);
|
||||||
|
|
||||||
|
// AUTORUN.INF contents
|
||||||
|
// Keys are stored in lowercase, in the format "section|key".
|
||||||
|
unordered_map<string, string> autorun_inf;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ini.h callback for parsing AUTORUN.INF.
|
* ini.h callback for parsing AUTORUN.INF.
|
||||||
@ -226,6 +237,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
static int parse_autorun_inf(void *user, const char *section, const char *name, const char *value);
|
static int parse_autorun_inf(void *user, const char *section, const char *name, const char *value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load AUTORUN.INF.
|
||||||
|
* AUTORUN.INF will be loaded into autorun_inf.
|
||||||
|
* @return 0 on success; negative POSIX error code on error.
|
||||||
|
*/
|
||||||
|
int loadAutorunInf(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the icon.
|
* Load the icon.
|
||||||
* @return Icon, or nullptr on error.
|
* @return Icon, or nullptr on error.
|
||||||
@ -653,6 +671,31 @@ void ISOPrivate::addPVDTimestamps_metaData(RomMetaData *metaData, const T *pvd)
|
|||||||
pvd_time_to_unix_time(&pvd->btime));
|
pvd_time_to_unix_time(&pvd->btime));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open the ISO-9660 partition.
|
||||||
|
* @return 0 on success; negative POSIX error code on error.
|
||||||
|
*/
|
||||||
|
int ISOPrivate::openIsoPartition(void)
|
||||||
|
{
|
||||||
|
if (isoPartition) {
|
||||||
|
// ISO-9660 partition is already open.
|
||||||
|
return 0;
|
||||||
|
} else if (!file) {
|
||||||
|
// File is not open.
|
||||||
|
return -EBADF;
|
||||||
|
}
|
||||||
|
|
||||||
|
isoPartition = std::make_shared<IsoPartition>(file, 0, 0);
|
||||||
|
if (!isoPartition->isOpen()) {
|
||||||
|
// Unable to open the ISO-9660 file system.
|
||||||
|
// TODO: Better error code?
|
||||||
|
isoPartition.reset();
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ini.h callback for parsing AUTORUN.INF.
|
* ini.h callback for parsing AUTORUN.INF.
|
||||||
* @param user [in] User data parameter (this)
|
* @param user [in] User data parameter (this)
|
||||||
@ -663,23 +706,78 @@ void ISOPrivate::addPVDTimestamps_metaData(RomMetaData *metaData, const T *pvd)
|
|||||||
*/
|
*/
|
||||||
int ISOPrivate::parse_autorun_inf(void *user, const char *section, const char *name, const char *value)
|
int ISOPrivate::parse_autorun_inf(void *user, const char *section, const char *name, const char *value)
|
||||||
{
|
{
|
||||||
// Verify the correct section.
|
// TODO: Character encoding? Assuming ASCII.
|
||||||
if (strcasecmp(section, "autorun") != 0) {
|
|
||||||
// Not "[autorun]".
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify the correct key.
|
// Concatenate the section and key names.
|
||||||
if (strcasecmp(name, "icon")) {
|
string s_name;
|
||||||
// Not "icon".
|
if (section[0] != '\0') {
|
||||||
return 0;
|
s_name = section;
|
||||||
|
s_name += '|';
|
||||||
}
|
}
|
||||||
|
s_name += name;
|
||||||
|
|
||||||
|
// Convert the name to lowercase.
|
||||||
|
std::transform(s_name.begin(), s_name.end(), s_name.begin(),
|
||||||
|
[](char c) noexcept -> char { return std::tolower(c); });
|
||||||
|
|
||||||
// Found the icon filename.
|
|
||||||
// Save the value for later.
|
// Save the value for later.
|
||||||
ISOPrivate *const d = static_cast<ISOPrivate*>(user);
|
ISOPrivate *const d = static_cast<ISOPrivate*>(user);
|
||||||
d->icon_filename = value;
|
auto ret = d->autorun_inf.emplace(std::move(s_name), value);
|
||||||
return 1;
|
// NOTE: This will stop processing if a duplicate key is found.
|
||||||
|
return (ret.second ? 0 : 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load AUTORUN.INF.
|
||||||
|
* AUTORUN.INF will be loaded into autorun_inf.
|
||||||
|
* @return 0 on success; negative POSIX error code on error.
|
||||||
|
*/
|
||||||
|
int ISOPrivate::loadAutorunInf(void)
|
||||||
|
{
|
||||||
|
if (!autorun_inf.empty()) {
|
||||||
|
// AUTORUN.INF is already loaded.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure the ISO-9660 file system is open.
|
||||||
|
int ret = openIsoPartition();
|
||||||
|
if (ret != 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempt to load AUTORUN.INF from the ISO-9660 file system.
|
||||||
|
IRpFilePtr f_autorun_inf = isoPartition->open("/AUTORUN.INF");
|
||||||
|
if (!f_autorun_inf) {
|
||||||
|
// Unable to open AUTORUN.INF.
|
||||||
|
return -isoPartition->lastError();
|
||||||
|
}
|
||||||
|
|
||||||
|
// AUTORUN.INF should be 2048 bytes or less.
|
||||||
|
static constexpr size_t AUTORUN_INF_SIZE_MAX = 2048;
|
||||||
|
const off64_t autorun_inf_size = f_autorun_inf->size();
|
||||||
|
if (autorun_inf_size > static_cast<off64_t>(AUTORUN_INF_SIZE_MAX)) {
|
||||||
|
// File is too big.
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the entire file into memory.
|
||||||
|
char buf[AUTORUN_INF_SIZE_MAX + 1];
|
||||||
|
size_t size = f_autorun_inf->read(buf, AUTORUN_INF_SIZE_MAX);
|
||||||
|
if (size != static_cast<size_t>(autorun_inf_size)) {
|
||||||
|
// Short read.
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
buf[static_cast<size_t>(autorun_inf_size)] = '\0';
|
||||||
|
|
||||||
|
// Parse AUTORUN.INF.
|
||||||
|
// TODO: Save other AUTORUN data for a tab?
|
||||||
|
ret = ini_parse_string(buf, parse_autorun_inf, this);
|
||||||
|
if (ret < 0) {
|
||||||
|
// Failed to parse AUTORUN.INF.
|
||||||
|
autorun_inf.clear();
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -696,44 +794,26 @@ rp_image_const_ptr ISOPrivate::loadIcon(void)
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attempt to load AUTORUN.INF from the ISO-9660 file system.
|
// Make sure the ISO-9660 file system is open.
|
||||||
IsoPartitionPtr isoPartition = std::make_shared<IsoPartition>(file, 0, 0);
|
int ret = openIsoPartition();
|
||||||
if (!isoPartition->isOpen()) {
|
if (ret != 0) {
|
||||||
// Unable to open the ISO-9660 file system.
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
IRpFilePtr f_file = isoPartition->open("/AUTORUN.INF");
|
// Make sure AUTORUN.INF is loaded.
|
||||||
if (!f_file) {
|
ret = loadAutorunInf();
|
||||||
// Unable to open AUTORUN.INF.
|
if (ret != 0 || autorun_inf.empty()) {
|
||||||
|
// Unable to load AUTORUN.INF.
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// AUTORUN.INF should be 2048 bytes or less.
|
// Get the icon filename.
|
||||||
static constexpr size_t AUTORUN_INF_SIZE_MAX = 2048;
|
auto iter = autorun_inf.find("autorun|icon");
|
||||||
const off64_t autorun_inf_size = f_file->size();
|
if (iter == autorun_inf.end()) {
|
||||||
if (autorun_inf_size > static_cast<off64_t>(AUTORUN_INF_SIZE_MAX)) {
|
|
||||||
// File is too big.
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read the entire file into memory.
|
|
||||||
char buf[AUTORUN_INF_SIZE_MAX + 1];
|
|
||||||
size_t size = f_file->read(buf, AUTORUN_INF_SIZE_MAX);
|
|
||||||
if (size != static_cast<size_t>(autorun_inf_size)) {
|
|
||||||
// Short read.
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
buf[static_cast<size_t>(autorun_inf_size)] = '\0';
|
|
||||||
|
|
||||||
// Parse AUTORUN.INF.
|
|
||||||
// TODO: Save other AUTORUN data for a tab?
|
|
||||||
icon_filename.clear();
|
|
||||||
ini_parse_string(buf, parse_autorun_inf, this);
|
|
||||||
if (icon_filename.empty()) {
|
|
||||||
// No icon...
|
// No icon...
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
string icon_filename = iter->second;
|
||||||
|
|
||||||
// Check if there's an icon index specified.
|
// Check if there's an icon index specified.
|
||||||
// - Positive: Zero-based index
|
// - Positive: Zero-based index
|
||||||
@ -755,7 +835,7 @@ rp_image_const_ptr ISOPrivate::loadIcon(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Open the icon file from the disc.
|
// Open the icon file from the disc.
|
||||||
f_file = isoPartition->open(icon_filename.c_str());
|
IRpFilePtr f_file = isoPartition->open(icon_filename.c_str());
|
||||||
if (!f_file) {
|
if (!f_file) {
|
||||||
// Unable to open the icon file.
|
// Unable to open the icon file.
|
||||||
return {};
|
return {};
|
||||||
@ -878,7 +958,19 @@ ISO::ISO(const IRpFilePtr &file)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** ROM detection functions. **/
|
/**
|
||||||
|
* Close the opened file.
|
||||||
|
*/
|
||||||
|
void ISO::close(void)
|
||||||
|
{
|
||||||
|
RP_D(ISO);
|
||||||
|
d->isoPartition.reset();
|
||||||
|
|
||||||
|
// Call the superclass function.
|
||||||
|
super::close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** ROM detection functions **/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check for a valid PVD.
|
* Check for a valid PVD.
|
||||||
|
@ -19,6 +19,7 @@ namespace LibRpBase {
|
|||||||
namespace LibRomData {
|
namespace LibRomData {
|
||||||
|
|
||||||
ROMDATA_DECL_BEGIN(ISO)
|
ROMDATA_DECL_BEGIN(ISO)
|
||||||
|
ROMDATA_DECL_CLOSE()
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
@ -1002,6 +1002,7 @@ IRpFilePtr IsoPartition::open(const char *filename)
|
|||||||
const ISO_DirEntry *const dirEntry = d->lookup(filename);
|
const ISO_DirEntry *const dirEntry = d->lookup(filename);
|
||||||
if (!dirEntry) {
|
if (!dirEntry) {
|
||||||
// Not found.
|
// Not found.
|
||||||
|
m_lastError = ENOENT;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user