api: Refactored providers to allow for loading interfaces and config views
This commit is contained in:
parent
2e90abd2c5
commit
3e736b36b6
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 };
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
@ -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() {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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>();
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
|
@ -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)) {
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
@ -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" },
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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" },
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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" },
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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" },
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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() {
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -45,6 +45,9 @@ namespace hex::test {
|
||||
return this->m_testFile.getSize();
|
||||
}
|
||||
|
||||
bool open() override { return true; }
|
||||
void close() override { }
|
||||
|
||||
private:
|
||||
File m_testFile;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user