1
0
mirror of synced 2024-11-12 02:00:52 +01:00

impr: Separate the behaviour of being savable and being dumpable for provider (#1183)

### Problem description

Currently, the providers use the method `isSavable()` to determine both
if they can use "Save" or "Save as".
This behaviour is problematic because some providers may need to be
saveable but not saveable as: for example the view provider. The
original provider may not allow to be saved.

### Implementation description
I separate these two behaviour by creating another function:
`isDumpable()`, that return true by default but can be overridden by the
provider to return false, if the provider should not be dumped in any
way.

### Additional things

While I was at it, I also marked "export" operations as needing the
"dumpable" flag. That way, we can't accidentally export the whole
address space of a process as base64.

I also added documentation for these some functions in Provider
This commit is contained in:
iTrooz 2023-07-05 20:49:57 +02:00 committed by GitHub
parent 25d6380963
commit e3ae169833
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 44 additions and 6 deletions

View File

@ -38,10 +38,29 @@ namespace hex::prv {
[[nodiscard]] virtual bool isAvailable() const = 0;
[[nodiscard]] virtual bool isReadable() const = 0;
/**
* @brief Controls if the user can write data to this specific provider.
* This may be false for e.g. a file opened in read-only
*/
[[nodiscard]] virtual bool isWritable() const = 0;
[[nodiscard]] virtual bool isResizable() const = 0;
/**
* @brief Controls whether the provider can be saved ("saved", not "saved as")
* This is mainly used by providers that aren't buffered, and so don't need to be saved
* This function will usually return false for providers that aren't writable, but this isn't guaranted
*/
[[nodiscard]] virtual bool isSavable() const = 0;
/**
* @brief Controls whether we can dump data from this provider (e.g. "save as", or "export -> ..").
* Typically disabled for process with sparse data, like the Process memory provider
* where the virtual address space is several TiBs large.
* Default implementation returns true.
*/
[[nodiscard]] virtual bool isDumpable() const;
/**
* @brief Read data from this provider, applying overlays and patches
* @param offset offset to start reading the data

View File

@ -356,4 +356,8 @@ namespace hex::prv {
return 0;
}
[[nodiscard]] bool Provider::isDumpable() const {
return true;
}
}

View File

@ -38,7 +38,13 @@ namespace hex::plugin::builtin {
return this->m_provider->isWritable();
}
[[nodiscard]] bool isResizable() const override { return true; }
[[nodiscard]] bool isSavable() const override { return true; }
[[nodiscard]] bool isSavable() const override {
if (this->m_provider == nullptr)
return false;
else
return this->m_provider->isSavable();
}
void save() override {
this->m_provider->save();

View File

@ -285,6 +285,13 @@ namespace hex::plugin::builtin {
}
/**
* @brief returns true if there is a currently selected provider, and it is possibl to dump data from it
*/
bool isProviderDumpable() {
auto provider = ImHexApi::Provider::get();
return ImHexApi::Provider::isValid() && provider->isDumpable();
}
static void createFileMenu() {
@ -368,12 +375,13 @@ namespace hex::plugin::builtin {
}
/* Export */
/* Only make them accessible if the current provider is dumpable */
{
/* Base 64 */
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.export", "hex.builtin.menu.file.export.base64" }, 6000,
Shortcut::None,
exportBase64,
ImHexApi::Provider::isValid);
isProviderDumpable);
ContentRegistry::Interface::addMenuItemSeparator({ "hex.builtin.menu.file", "hex.builtin.menu.file.export" }, 6050);
@ -381,13 +389,13 @@ namespace hex::plugin::builtin {
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.export", "hex.builtin.menu.file.export.ips" }, 6100,
Shortcut::None,
exportIPSPatch,
ImHexApi::Provider::isValid);
isProviderDumpable);
/* IPS32 */
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.export", "hex.builtin.menu.file.export.ips32" }, 6150,
Shortcut::None,
exportIPS32Patch,
ImHexApi::Provider::isValid);
isProviderDumpable);
}
ContentRegistry::Interface::addMenuItemSeparator({ "hex.builtin.menu.file" }, 10000);

View File

@ -960,7 +960,7 @@ namespace hex::plugin::builtin {
auto provider = ImHexApi::Provider::get();
bool providerValid = ImHexApi::Provider::isValid();
return providerValid && provider->isWritable();
return providerValid && provider->isWritable() && provider->isSavable() && provider->isDirty();
});
/* Save As */
@ -971,7 +971,7 @@ namespace hex::plugin::builtin {
auto provider = ImHexApi::Provider::get();
bool providerValid = ImHexApi::Provider::isValid();
return providerValid && provider->isWritable();
return providerValid && provider->isDumpable();
});
/* Load Encoding File */

View File

@ -27,6 +27,7 @@ namespace hex::plugin::windows {
[[nodiscard]] bool isWritable() const override { return true; }
[[nodiscard]] bool isResizable() const override { return false; }
[[nodiscard]] bool isSavable() const override { return false; }
[[nodiscard]] bool isDumpable() const override { return false; }
void read(u64 address, void *buffer, size_t size, bool) override { this->readRaw(address, buffer, size); }
void write(u64 address, const void *buffer, size_t size) override { this->writeRaw(address, buffer, size); }