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

api: Refactored providers to allow for loading interfaces and config views

This commit is contained in:
WerWolv 2021-12-12 00:41:44 +01:00
parent 2e90abd2c5
commit 3e736b36b6
23 changed files with 272 additions and 145 deletions

View File

@ -38,7 +38,7 @@ add_library(${PROJECT_NAME} SHARED
source/content/views/view_constants.cpp
source/content/views/view_store.cpp
source/content/views/view_diff.cpp
source/content/views/view_gdb.cpp
source/content/views/view_provider_settings.cpp
source/math_evaluator.cpp

View File

@ -21,11 +21,11 @@ namespace hex::plugin::builtin::prv {
explicit FileProvider();
~FileProvider() override;
bool isAvailable() const override;
bool isReadable() const override;
bool isWritable() const override;
bool isResizable() const override;
bool isSavable() const override;
[[nodiscard]] bool isAvailable() const override;
[[nodiscard]] bool isReadable() const override;
[[nodiscard]] bool isWritable() const override;
[[nodiscard]] bool isResizable() const override;
[[nodiscard]] bool isSavable() const override;
void read(u64 offset, void *buffer, size_t size, bool overlays) override;
void write(u64 offset, const void *buffer, size_t size) override;
@ -33,7 +33,7 @@ namespace hex::plugin::builtin::prv {
void readRaw(u64 offset, void *buffer, size_t size) override;
void writeRaw(u64 offset, const void *buffer, size_t size) override;
size_t getActualSize() const override;
[[nodiscard]] size_t getActualSize() const override;
void save() override;
void saveAs(const std::string &path) override;
@ -41,10 +41,12 @@ namespace hex::plugin::builtin::prv {
[[nodiscard]] std::string getName() const override;
[[nodiscard]] std::vector<std::pair<std::string, std::string>> getDataInformation() const override;
void open(const std::string &path);
void close();
void setPath(const std::string &path);
private:
[[nodiscard]] bool open() override;
void close() override;
protected:
#if defined(OS_WINDOWS)
HANDLE m_file = INVALID_HANDLE_VALUE;
HANDLE m_mapping = INVALID_HANDLE_VALUE;

View File

@ -14,11 +14,11 @@ class GDBProvider : public hex::prv::Provider {
explicit GDBProvider();
~GDBProvider() override;
bool isAvailable() const override;
bool isReadable() const override;
bool isWritable() const override;
bool isResizable() const override;
bool isSavable() const override;
[[nodiscard]] bool isAvailable() const override;
[[nodiscard]] bool isReadable() const override;
[[nodiscard]] bool isWritable() const override;
[[nodiscard]] bool isResizable() const override;
[[nodiscard]] bool isSavable() const override;
void read(u64 offset, void *buffer, size_t size, bool overlays) override;
void write(u64 offset, const void *buffer, size_t size) override;
@ -26,7 +26,7 @@ class GDBProvider : public hex::prv::Provider {
void readRaw(u64 offset, void *buffer, size_t size) override;
void writeRaw(u64 offset, const void *buffer, size_t size) override;
size_t getActualSize() const override;
[[nodiscard]] size_t getActualSize() const override;
void save() override;
void saveAs(const std::string &path) override;
@ -34,20 +34,26 @@ class GDBProvider : public hex::prv::Provider {
[[nodiscard]] std::string getName() const override;
[[nodiscard]] std::vector<std::pair<std::string, std::string>> getDataInformation() const override;
void connect(const std::string &address, u16 port);
void disconnect();
bool isConnected();
[[nodiscard]] bool open() override;
void close() override;
private:
[[nodiscard]] bool isConnected() const;
[[nodiscard]] bool hasLoadInterface() const override { return true; }
void drawLoadInterface() override;
protected:
hex::Socket m_socket;
std::string m_ipAddress;
u16 m_port;
int m_port;
constexpr static size_t CacheLineSize = 0x1000;
struct CacheLine {
u64 address;
std::array<u8, 0x1000> data;
std::array<u8, CacheLineSize> data;
};
std::list<CacheLine> m_cache;

View File

@ -3,6 +3,7 @@
#include <hex/views/view.hpp>
#include <array>
#include <atomic>
#include <cstdio>
#include <string>
#include <vector>
@ -30,6 +31,7 @@ namespace hex::plugin::builtin {
std::array<ImU64, 256> m_valueCounts = { 0 };
bool m_analyzing = false;
std::atomic<u64> m_bytesAnalyzed;
std::pair<u64, u64> m_analyzedRegion = { 0, 0 };

View File

@ -10,19 +10,17 @@
namespace hex::plugin::builtin {
class ViewGDB : public hex::View {
class ViewProviderSettings : public hex::View {
public:
ViewGDB();
ViewProviderSettings();
~ViewProviderSettings();
void drawContent() override;
void drawAlwaysVisible() override;
bool hasViewMenuItemEntry() override;
bool isAvailable();
private:
std::string m_address;
int m_port = 0;
};
}

View File

@ -130,7 +130,7 @@ namespace hex::plugin::builtin::prv {
::close(handle);
#endif
this->open(this->m_path);
this->open();
}
size_t FileProvider::getActualSize() const {
@ -156,8 +156,11 @@ namespace hex::plugin::builtin::prv {
return result;
}
void FileProvider::open(const std::string &path) {
void FileProvider::setPath(const std::string &path) {
this->m_path = path;
}
bool FileProvider::open() {
this->m_fileStatsValid = stat(this->m_path.data(), &this->m_fileStats) == 0;
this->m_readable = true;
@ -194,12 +197,12 @@ namespace hex::plugin::builtin::prv {
};
if (this->m_file == nullptr || this->m_file == INVALID_HANDLE_VALUE) {
return;
return false;
}
this->m_mapping = CreateFileMapping(this->m_file, nullptr, PAGE_READWRITE, fileSize.HighPart, fileSize.LowPart, nullptr);
if (this->m_mapping == nullptr || this->m_mapping == INVALID_HANDLE_VALUE) {
return;
return false;
}
auto mappingCleanup = SCOPE_GUARD {
@ -211,7 +214,7 @@ namespace hex::plugin::builtin::prv {
this->m_mappedFile = MapViewOfFile(this->m_mapping, FILE_MAP_ALL_ACCESS, 0, 0, this->m_fileSize);
if (this->m_mappedFile == nullptr) {
this->m_readable = false;
return;
return false;
}
fileCleanup.release();
@ -220,7 +223,7 @@ namespace hex::plugin::builtin::prv {
ProjectFile::setFilePath(this->m_path);
#else
this->m_file = ::open(this->m_path.data(), O_RDWR);
this->m_file = ::open(this->m_path.data(), O_RDWR);
if (this->m_file == -1) {
this->m_file = ::open(this->m_path.data(), O_RDONLY);
this->m_writable = false;
@ -228,14 +231,21 @@ namespace hex::plugin::builtin::prv {
if (this->m_file == -1) {
this->m_readable = false;
return;
return false;
}
this->m_fileSize = this->m_fileStats.st_size;
this->m_mappedFile = mmap(nullptr, this->m_fileSize, PROT_READ | PROT_WRITE, MAP_PRIVATE, this->m_file, 0);
this->m_mappedFile = ::mmap(nullptr, this->m_fileSize, PROT_READ | PROT_WRITE, MAP_PRIVATE, this->m_file, 0);
if (this->m_mappedFile == nullptr) {
::close(this->m_file);
this->m_file = -1;
#endif
return false;
}
#endif
return true;
}
void FileProvider::close() {

View File

@ -77,6 +77,19 @@ namespace hex::plugin::builtin::prv {
return data;
}
void writeMemory(Socket &socket, u64 address, const void *buffer, size_t size) {
std::vector<u8> bytes(size);
std::memcpy(bytes.data(), buffer, size);
std::string byteString = crypt::encode16(bytes);
std::string packet = createPacket(hex::format("M{:X},{:X}:{}", address, size, byteString));
socket.writeString(packet);
auto receivedPacket = socket.readString(3);
}
bool enableNoAckMode(Socket &socket) {
socket.writeString(createPacket("QStartNoAckMode"));
@ -104,7 +117,7 @@ namespace hex::plugin::builtin::prv {
}
GDBProvider::~GDBProvider() {
this->disconnect();
this->close();
}
@ -135,9 +148,9 @@ namespace hex::plugin::builtin::prv {
offset -= this->getBaseAddress();
u64 alignedOffset = offset - (offset & 0xFFF);
u64 alignedOffset = offset - (offset % CacheLineSize);
{
if (size <= CacheLineSize) {
std::scoped_lock lock(this->m_cacheLock);
const auto &cacheLine = std::find_if(this->m_cache.begin(), this->m_cache.end(), [&](auto &line){
@ -154,7 +167,15 @@ namespace hex::plugin::builtin::prv {
}
if (cacheLine != this->m_cache.end())
std::memcpy(buffer, &cacheLine->data[0] + (offset & 0xFFF), size);
std::memcpy(buffer, &cacheLine->data[0] + (offset % CacheLineSize), size);
} else {
while (size > 0) {
size_t readSize = std::min(size, CacheLineSize);
this->readRaw(offset, buffer, readSize);
size -= readSize;
offset += readSize;
}
}
for (u64 i = 0; i < size; i++)
@ -166,7 +187,12 @@ namespace hex::plugin::builtin::prv {
}
void GDBProvider::write(u64 offset, const void *buffer, size_t size) {
if ((offset - this->getBaseAddress()) > (this->getActualSize() - size) || buffer == nullptr || size == 0)
return;
offset -= this->getBaseAddress();
gdb::writeMemory(this->m_socket, offset, buffer, size);
}
void GDBProvider::readRaw(u64 offset, void *buffer, size_t size) {
@ -178,7 +204,10 @@ namespace hex::plugin::builtin::prv {
}
void GDBProvider::writeRaw(u64 offset, const void *buffer, size_t size) {
if ((offset - this->getBaseAddress()) > (this->getActualSize() - size) || buffer == nullptr || size == 0)
return;
gdb::writeMemory(this->m_socket, offset, buffer, size);
}
void GDBProvider::save() {
@ -200,7 +229,7 @@ namespace hex::plugin::builtin::prv {
std::string GDBProvider::getName() const {
std::string address, port;
if (this->m_ipAddress.empty()) {
if (!this->isConnected()) {
address = "-";
port = "-";
} else {
@ -212,19 +241,18 @@ namespace hex::plugin::builtin::prv {
}
std::vector<std::pair<std::string, std::string>> GDBProvider::getDataInformation() const {
return { };
return {
{ "hex.builtin.provider.gdb.server"_lang, hex::format("{}:{}", this->m_ipAddress, this->m_port) },
};
}
void GDBProvider::connect(const std::string &address, u16 port) {
this->m_socket.connect(address, port);
bool GDBProvider::open() {
this->m_socket.connect(this->m_ipAddress, this->m_port);
if (!gdb::enableNoAckMode(this->m_socket)) {
this->m_socket.disconnect();
return;
return false;
}
this->m_ipAddress = address;
this->m_port = port;
if (this->m_socket.isConnected()) {
this->m_cacheUpdateThread = std::thread([this]() {
auto cacheLine = this->m_cache.begin();
@ -250,10 +278,14 @@ namespace hex::plugin::builtin::prv {
std::this_thread::sleep_for(100ms);
}
});
return true;
} else {
return false;
}
}
void GDBProvider::disconnect() {
void GDBProvider::close() {
this->m_socket.disconnect();
if (this->m_cacheUpdateThread.joinable()) {
@ -261,8 +293,20 @@ namespace hex::plugin::builtin::prv {
}
}
bool GDBProvider::isConnected() {
bool GDBProvider::isConnected() const {
return this->m_socket.isConnected();
}
void GDBProvider::drawLoadInterface() {
ImGui::InputText("hex.builtin.view.gdb.ip"_lang, this->m_ipAddress.data(), this->m_ipAddress.capacity(), ImGuiInputTextFlags_CallbackEdit, ImGui::UpdateStringSizeCallback, &this->m_ipAddress);
ImGui::InputInt("hex.builtin.view.gdb.port"_lang, &this->m_port, 0, 0);
if (this->m_port < 0)
this->m_port = 0;
else if (this->m_port > 0xFFFF)
this->m_port = 0xFFFF;
}
}

View File

@ -17,7 +17,7 @@
#include "content/views/view_constants.hpp"
#include "content/views/view_store.hpp"
#include "content/views/view_diff.hpp"
#include "content/views/view_gdb.hpp"
#include "content/views/view_provider_settings.hpp"
namespace hex::plugin::builtin {
@ -41,7 +41,7 @@ namespace hex::plugin::builtin {
ContentRegistry::Views::add<ViewConstants>();
ContentRegistry::Views::add<ViewStore>();
ContentRegistry::Views::add<ViewDiff>();
ContentRegistry::Views::add<ViewGDB>();
ContentRegistry::Views::add<ViewProviderSettings>();
}
}

View File

@ -1,51 +0,0 @@
#include "content/views/view_gdb.hpp"
#include "content/providers/gdb_provider.hpp"
namespace hex::plugin::builtin {
ViewGDB::ViewGDB() : hex::View("hex.builtin.view.gdb.name") {
this->m_address.reserve(3 * 4 + 4);
this->m_port = 0;
}
void ViewGDB::drawContent() {
if (ImGui::Begin(View::toWindowName("hex.builtin.view.gdb.name").c_str(), &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) {
ImGui::Header("hex.builtin.view.gdb.settings"_lang);
ImGui::InputText("hex.builtin.view.gdb.ip"_lang, this->m_address.data(), this->m_address.capacity(), ImGuiInputTextFlags_CallbackEdit, ImGui::UpdateStringSizeCallback, &this->m_address);
ImGui::InputInt("hex.builtin.view.gdb.port"_lang, &this->m_port, 0, 0);
if (this->m_port < 0)
this->m_port = 0;
else if (this->m_port > 0xFFFF)
this->m_port = 0xFFFF;
ImGui::NewLine();
auto provider = dynamic_cast<prv::GDBProvider*>(hex::ImHexApi::Provider::get());
if (provider != nullptr) {
if (!provider->isConnected()) {
if (ImGui::Button("hex.builtin.view.gdb.connect"_lang)) {
provider->connect(this->m_address, this->m_port);
}
} else {
if (ImGui::Button("hex.builtin.view.gdb.disconnect"_lang)) {
provider->disconnect();
}
}
}
}
ImGui::End();
}
bool ViewGDB::hasViewMenuItemEntry() {
return this->isAvailable();
}
bool ViewGDB::isAvailable() {
auto provider = hex::ImHexApi::Provider::get();
return provider != nullptr && dynamic_cast<prv::GDBProvider*>(provider) != nullptr;
}
}

View File

@ -713,8 +713,13 @@ namespace hex::plugin::builtin {
hex::prv::Provider *provider = nullptr;
EventManager::post<RequestCreateProvider>("hex.builtin.provider.file", &provider);
if (auto fileProvider = dynamic_cast<prv::FileProvider*>(provider))
fileProvider->open(path);
if (auto fileProvider = dynamic_cast<prv::FileProvider*>(provider)) {
fileProvider->setPath(path);
if (!fileProvider->open()) {
View::showErrorPopup("hex.builtin.view.hexeditor.error.open"_lang);
return;
}
}
if (!provider->isWritable()) {
this->m_memoryEditor.ReadOnly = true;

View File

@ -51,23 +51,18 @@ namespace hex::plugin::builtin {
EventManager::unsubscribe<EventFileUnloaded>(this);
}
static float calculateEntropy(std::array<ImU64, 256> &valueCounts, size_t numBytes) {
static float calculateEntropy(std::array<ImU64, 256> &valueCounts, size_t blockSize) {
float entropy = 0;
if (numBytes == 0)
return 0.0F;
for (auto count : valueCounts) {
if (count == 0) continue;
std::array<float, 256> floatValueCounts{ 0 };
std::copy(valueCounts.begin(), valueCounts.end(), floatValueCounts.begin());
float probability = static_cast<float>(count) / blockSize;
for (u16 i = 0; i < 256; i++) {
floatValueCounts[i] /= float(numBytes);
if (floatValueCounts[i] > 0)
entropy -= (floatValueCounts[i] * std::log2(floatValueCounts[i]));
entropy += probability * std::log2(probability);
}
return entropy / 8;
return (-entropy) / 8; // log2(256) = 8
}
void ViewInformation::analyze() {
@ -93,7 +88,10 @@ namespace hex::plugin::builtin {
blockValueCounts[buffer[j]]++;
this->m_valueCounts[buffer[j]]++;
}
this->m_blockEntropy.push_back(calculateEntropy(blockValueCounts, this->m_blockSize));
this->m_bytesAnalyzed = i;
}
this->m_averageEntropy = calculateEntropy(this->m_valueCounts, provider->getSize());
@ -128,20 +126,23 @@ namespace hex::plugin::builtin {
}, this->m_analyzing);
if (this->m_analyzing) {
ImGui::SameLine();
ImGui::TextSpinner("hex.builtin.view.information.analyzing"_lang);
ImGui::ProgressBar(this->m_bytesAnalyzed / static_cast<double>(provider->getSize()));
} else {
ImGui::NewLine();
ImGui::NewLine();
}
ImGui::NewLine();
ImGui::TextUnformatted("hex.builtin.view.information.region"_lang);
ImGui::Separator();
for (auto &[name, value] : provider->getDataInformation()) {
ImGui::LabelText(name.c_str(), "%s", value.c_str());
}
if (this->m_dataValid) {
ImGui::NewLine();
ImGui::TextUnformatted("hex.builtin.view.information.region"_lang);
ImGui::Separator();
for (auto &[name, value] : provider->getDataInformation()) {
ImGui::LabelText(name.c_str(), "%s", value.c_str());
}
ImGui::LabelText("hex.builtin.view.information.region"_lang, "0x%llx - 0x%llx", this->m_analyzedRegion.first, this->m_analyzedRegion.second);
ImGui::NewLine();
@ -169,8 +170,8 @@ namespace hex::plugin::builtin {
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImGui::GetColorU32(ImGuiCol_WindowBg));
ImGui::TextUnformatted("hex.builtin.view.information.distribution"_lang);
ImPlot::SetNextPlotLimits(0, 256, 0, float(*std::max_element(this->m_valueCounts.begin(), this->m_valueCounts.end())) * 1.1F, ImGuiCond_Always);
if (ImPlot::BeginPlot("##distribution", "Address", "Count", ImVec2(-1,0), ImPlotFlags_NoLegend | ImPlotFlags_NoMenus | ImPlotFlags_NoBoxSelect, ImPlotAxisFlags_Lock, ImPlotAxisFlags_Lock)) {
ImPlot::SetNextPlotLimits(0, 256, 0.5, float(*std::max_element(this->m_valueCounts.begin(), this->m_valueCounts.end())) * 1.1F, ImGuiCond_Always);
if (ImPlot::BeginPlot("##distribution", "Address", "Count", ImVec2(-1,0), ImPlotFlags_NoLegend | ImPlotFlags_NoMenus | ImPlotFlags_NoBoxSelect, ImPlotAxisFlags_Lock, ImPlotAxisFlags_Lock | ImPlotAxisFlags_LogScale)) {
static auto x = []{
std::array<ImU64, 256> result{ 0 };
std::iota(result.begin(), result.end(), 0);
@ -188,7 +189,7 @@ namespace hex::plugin::builtin {
ImGui::TextUnformatted("hex.builtin.view.information.entropy"_lang);
ImPlot::SetNextPlotLimits(0, this->m_blockEntropy.size(), -0.1, 1.1, ImGuiCond_Always);
if (ImPlot::BeginPlot("##entropy", "Address", "Entropy", ImVec2(-1,0), ImPlotFlags_CanvasOnly, ImPlotAxisFlags_Lock | ImPlotAxisFlags_NoTickLabels, ImPlotAxisFlags_Lock)) {
if (ImPlot::BeginPlot("##entropy", "Address", "Entropy", ImVec2(-1,0), ImPlotFlags_CanvasOnly | ImPlotFlags_AntiAliased, ImPlotAxisFlags_Lock | ImPlotAxisFlags_NoTickLabels, ImPlotAxisFlags_Lock)) {
ImPlot::PlotLine("##entropy_line", this->m_blockEntropy.data(), this->m_blockEntropy.size());
if (ImPlot::DragLineX("Position", &this->m_entropyHandlePosition, false)) {

View File

@ -0,0 +1,65 @@
#include "content/views/view_provider_settings.hpp"
namespace hex::plugin::builtin {
ViewProviderSettings::ViewProviderSettings() : hex::View("hex.builtin.view.provider_settings.name") {
EventManager::subscribe<EventProviderCreated>(this, [](hex::prv::Provider *provider){
if (provider->hasLoadInterface())
EventManager::post<RequestOpenPopup>(View::toWindowName("hex.builtin.view.provider_settings.load_popup"));
});
}
ViewProviderSettings::~ViewProviderSettings() {
EventManager::unsubscribe<EventProviderCreated>(this);
}
void ViewProviderSettings::drawContent() {
if (ImGui::Begin(View::toWindowName("hex.builtin.view.provider_settings.name").c_str(), &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) {
auto provider = hex::ImHexApi::Provider::get();
if (provider != nullptr)
provider->drawInterface();
}
ImGui::End();
}
void ViewProviderSettings::drawAlwaysVisible() {
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), ImGuiCond_Appearing, ImVec2(0.5F, 0.5F));
if (ImGui::BeginPopupModal(View::toWindowName("hex.builtin.view.provider_settings.load_popup").c_str(), nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
auto provider = hex::ImHexApi::Provider::get();
if (provider != nullptr) {
provider->drawLoadInterface();
ImGui::NewLine();
ImGui::Separator();
if (ImGui::Button("hex.common.open"_lang)) {
if (provider->open())
ImGui::CloseCurrentPopup();
}
ImGui::SameLine();
if (ImGui::Button("hex.common.cancel"_lang)) {
ImHexApi::Provider::remove(provider);
ImGui::CloseCurrentPopup();
}
}
ImGui::EndPopup();
}
}
bool ViewProviderSettings::hasViewMenuItemEntry() {
return this->isAvailable();
}
bool ViewProviderSettings::isAvailable() {
auto provider = hex::ImHexApi::Provider::get();
return provider != nullptr && provider->hasInterface();
}
}

View File

@ -678,6 +678,7 @@ namespace hex::plugin::builtin {
{ "hex.builtin.provider.file", "Datei Provider" },
{ "hex.builtin.provider.gdb", "GDB Server Provider" },
{ "hex.builtin.provider.gdb.name", "GDB Server <{0}:{1}>" },
{ "hex.builtin.provider.gdb.server", "Server" },
});
}

View File

@ -681,6 +681,7 @@ namespace hex::plugin::builtin {
{ "hex.builtin.provider.file", "File Provider" },
{ "hex.builtin.provider.gdb", "GDB Server Provider" },
{ "hex.builtin.provider.gdb.name", "GDB Server <{0}:{1}>" },
{ "hex.builtin.provider.gdb.server", "Server" },
});
}

View File

@ -675,6 +675,7 @@ namespace hex::plugin::builtin {
//{ "hex.builtin.provider.file", "File Provider" },
//{ "hex.builtin.provider.gdb", "GDB Server Provider" },
//{ "hex.builtin.provider.gdb.name", "GDB Server <{0}:{1}>" },
//{ "hex.builtin.provider.gdb.server", "Server" },
});
}

View File

@ -677,6 +677,7 @@ namespace hex::plugin::builtin {
//{ "hex.builtin.provider.file", "File Provider" },
//{ "hex.builtin.provider.gdb", "GDB Server Provider" },
//{ "hex.builtin.provider.gdb.name", "GDB Server <{0}:{1}>" },
//{ "hex.builtin.provider.gdb.server", "Server" },
});
}

View File

@ -107,6 +107,7 @@ namespace hex {
EVENT_DEF(EventSettingsChanged);
EVENT_DEF(EventAbnormalTermination, int);
EVENT_DEF(EventOSThemeChanged);
EVENT_DEF(EventProviderCreated, prv::Provider*);
EVENT_DEF(RequestOpenWindow, std::string);
EVENT_DEF(RequestSelectionChange, Region);

View File

@ -19,11 +19,11 @@ namespace hex::prv {
Provider();
virtual ~Provider();
virtual bool isAvailable() const = 0;
virtual bool isReadable() const = 0;
virtual bool isWritable() const = 0;
virtual bool isResizable() const = 0;
virtual bool isSavable() const = 0;
[[nodiscard]] virtual bool isAvailable() const = 0;
[[nodiscard]] virtual bool isReadable() const = 0;
[[nodiscard]] virtual bool isWritable() const = 0;
[[nodiscard]] virtual bool isResizable() const = 0;
[[nodiscard]] virtual bool isSavable() const = 0;
virtual void read(u64 offset, void *buffer, size_t size, bool overlays = true);
virtual void write(u64 offset, const void *buffer, size_t size);
@ -35,38 +35,46 @@ namespace hex::prv {
virtual void readRaw(u64 offset, void *buffer, size_t size) = 0;
virtual void writeRaw(u64 offset, const void *buffer, size_t size) = 0;
virtual size_t getActualSize() const = 0;
[[nodiscard]] virtual size_t getActualSize() const = 0;
void applyOverlays(u64 offset, void *buffer, size_t size);
std::map<u64, u8>& getPatches();
const std::map<u64, u8>& getPatches() const;
[[nodiscard]] std::map<u64, u8>& getPatches();
[[nodiscard]] const std::map<u64, u8>& getPatches() const;
void applyPatches();
[[nodiscard]] Overlay* newOverlay();
void deleteOverlay(Overlay *overlay);
[[nodiscard]] const std::list<Overlay*>& getOverlays();
u32 getPageCount() const;
u32 getCurrentPage() const;
[[nodiscard]] u32 getPageCount() const;
[[nodiscard]] u32 getCurrentPage() const;
void setCurrentPage(u32 page);
virtual void setBaseAddress(u64 address);
virtual u64 getBaseAddress() const;
virtual u64 getCurrentPageAddress() const;
virtual size_t getSize() const;
virtual std::optional<u32> getPageOfAddress(u64 address) const;
[[nodiscard]] virtual u64 getBaseAddress() const;
[[nodiscard]] virtual u64 getCurrentPageAddress() const;
[[nodiscard]] virtual size_t getSize() const;
[[nodiscard]] virtual std::optional<u32> getPageOfAddress(u64 address) const;
[[nodiscard]] virtual std::string getName() const = 0;
[[nodiscard]] virtual std::vector<std::pair<std::string, std::string>> getDataInformation() const = 0;
[[nodiscard]] virtual bool open() = 0;
virtual void close() = 0;
void addPatch(u64 offset, const void *buffer, size_t size);
void undo();
void redo();
bool canUndo() const;
bool canRedo() const;
[[nodiscard]] bool canUndo() const;
[[nodiscard]] bool canRedo() const;
[[nodiscard]] virtual bool hasLoadInterface() const;
[[nodiscard]] virtual bool hasInterface() const;
virtual void drawLoadInterface();
virtual void drawInterface();
protected:
u32 m_currPage = 0;

View File

@ -68,6 +68,8 @@ namespace hex {
void ImHexApi::Provider::add(prv::Provider *provider) {
SharedData::providers.push_back(provider);
SharedData::currentProvider = SharedData::providers.size() - 1;
EventManager::post<EventProviderCreated>(provider);
}
void ImHexApi::Provider::remove(prv::Provider *provider) {

View File

@ -1,6 +1,7 @@
#include <hex/providers/provider.hpp>
#include <hex.hpp>
#include <hex/api/event.hpp>
#include <cmath>
#include <cstring>
@ -12,6 +13,9 @@ namespace hex::prv {
Provider::Provider() {
this->m_patches.emplace_back();
if (this->hasLoadInterface())
EventManager::post<RequestOpenPopup>(View::toWindowName("hex.builtin.view.provider_settings.load_popup"));
}
Provider::~Provider() {
@ -142,4 +146,21 @@ namespace hex::prv {
return this->m_patchTreeOffset > 0;
}
bool Provider::hasLoadInterface() const {
return false;
}
bool Provider::hasInterface() const {
return false;
}
void Provider::drawLoadInterface() {
}
void Provider::drawInterface() {
}
}

View File

@ -485,6 +485,7 @@ namespace hex {
View::getDeferedCalls().clear();
for (auto &view : ContentRegistry::Views::getEntries()) {
GImGui->NextWindowData.ClearFlags();
view->drawAlwaysVisible();
if (!view->shouldProcess())
@ -496,6 +497,8 @@ namespace hex {
ImGui::SetNextWindowSizeConstraints(minSize, view->getMaxSize());
view->drawContent();
GImGui->NextWindowData.ClearFlags();
view->handleShortcut(pressedKeys, ImGui::GetIO().KeyCtrl, ImGui::GetIO().KeyShift, ImGui::GetIO().KeyAlt);
}

View File

@ -48,6 +48,9 @@ namespace hex::test {
return this->m_data->size();
}
bool open() override { return true; }
void close() override { }
private:
std::vector<u8>* m_data;
};

View File

@ -45,6 +45,9 @@ namespace hex::test {
return this->m_testFile.getSize();
}
bool open() override { return true; }
void close() override { }
private:
File m_testFile;
};