parent
405b97e4d3
commit
2ccf8e777c
@ -24,9 +24,11 @@ namespace hex::prv {
|
|||||||
bool isAvailable() override;
|
bool isAvailable() override;
|
||||||
bool isReadable() override;
|
bool isReadable() override;
|
||||||
bool isWritable() override;
|
bool isWritable() override;
|
||||||
|
bool isResizable() override;
|
||||||
|
|
||||||
void read(u64 offset, void *buffer, size_t size, bool overlays) override;
|
void read(u64 offset, void *buffer, size_t size, bool overlays) override;
|
||||||
void write(u64 offset, const void *buffer, size_t size) override;
|
void write(u64 offset, const void *buffer, size_t size) override;
|
||||||
|
void resize(ssize_t newSize) override;
|
||||||
|
|
||||||
void readRaw(u64 offset, void *buffer, size_t size) override;
|
void readRaw(u64 offset, void *buffer, size_t size) override;
|
||||||
void writeRaw(u64 offset, const void *buffer, size_t size) override;
|
void writeRaw(u64 offset, const void *buffer, size_t size) override;
|
||||||
@ -41,6 +43,7 @@ namespace hex::prv {
|
|||||||
#else
|
#else
|
||||||
int m_file;
|
int m_file;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::string m_path;
|
std::string m_path;
|
||||||
void *m_mappedFile;
|
void *m_mappedFile;
|
||||||
size_t m_fileSize;
|
size_t m_fileSize;
|
||||||
@ -49,6 +52,9 @@ namespace hex::prv {
|
|||||||
struct stat m_fileStats = { 0 };
|
struct stat m_fileStats = { 0 };
|
||||||
|
|
||||||
bool m_readable, m_writable;
|
bool m_readable, m_writable;
|
||||||
|
|
||||||
|
void open();
|
||||||
|
void close();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
@ -46,6 +46,7 @@ namespace hex {
|
|||||||
s64 m_gotoAddress = 0;
|
s64 m_gotoAddress = 0;
|
||||||
|
|
||||||
char m_baseAddressBuffer[0x20] = { 0 };
|
char m_baseAddressBuffer[0x20] = { 0 };
|
||||||
|
u64 m_resizeSize = 0;
|
||||||
|
|
||||||
std::vector<u8> m_dataToSave;
|
std::vector<u8> m_dataToSave;
|
||||||
|
|
||||||
@ -59,9 +60,10 @@ namespace hex {
|
|||||||
void drawGotoPopup();
|
void drawGotoPopup();
|
||||||
void drawEditPopup();
|
void drawEditPopup();
|
||||||
|
|
||||||
void openFile(std::string path);
|
bool createFile(std::string_view path);
|
||||||
bool saveToFile(std::string path, const std::vector<u8>& data);
|
void openFile(std::string_view path);
|
||||||
bool loadFromFile(std::string path, std::vector<u8>& data);
|
bool saveToFile(std::string_view path, const std::vector<u8>& data);
|
||||||
|
bool loadFromFile(std::string_view path, std::vector<u8>& data);
|
||||||
|
|
||||||
enum class Language { C, Cpp, CSharp, Rust, Python, Java, JavaScript };
|
enum class Language { C, Cpp, CSharp, Rust, Python, Java, JavaScript };
|
||||||
void copyBytes();
|
void copyBytes();
|
||||||
|
@ -16,6 +16,7 @@ namespace hex::plugin::builtin {
|
|||||||
|
|
||||||
{ "hex.welcome.header.main", "Wilkommen zu ImHex" },
|
{ "hex.welcome.header.main", "Wilkommen zu ImHex" },
|
||||||
{ "hex.welcome.header.start", "Start" },
|
{ "hex.welcome.header.start", "Start" },
|
||||||
|
{ "hex.welcome.start.create_file", "Neue Datei Erstellen" },
|
||||||
{ "hex.welcome.start.open_file", "Datei Öffnen" },
|
{ "hex.welcome.start.open_file", "Datei Öffnen" },
|
||||||
{ "hex.welcome.start.open_project", "Projekt Öffnen" },
|
{ "hex.welcome.start.open_project", "Projekt Öffnen" },
|
||||||
{ "hex.welcome.start.recent", "Kürzlich geöffnet" },
|
{ "hex.welcome.start.recent", "Kürzlich geöffnet" },
|
||||||
@ -139,7 +140,8 @@ namespace hex::plugin::builtin {
|
|||||||
{ "hex.view.help.calc_cheat_sheet", "Rechner Cheat Sheet" },
|
{ "hex.view.help.calc_cheat_sheet", "Rechner Cheat Sheet" },
|
||||||
|
|
||||||
{ "hex.view.hexeditor.name", "Hex editor" },
|
{ "hex.view.hexeditor.name", "Hex editor" },
|
||||||
{ "hex.view.hexeditor.open_file", "Datei öffnen" },
|
{ "hex.view.hexeditor.create_file", "Neu" },
|
||||||
|
{ "hex.view.hexeditor.open_file", "Öffnen" },
|
||||||
{ "hex.view.hexeditor.open_project", "Projekt öffnen" },
|
{ "hex.view.hexeditor.open_project", "Projekt öffnen" },
|
||||||
{ "hex.view.hexeditor.save_project", "Projekt speichern" },
|
{ "hex.view.hexeditor.save_project", "Projekt speichern" },
|
||||||
{ "hex.view.hexeditor.save_data", "Daten speichern" },
|
{ "hex.view.hexeditor.save_data", "Daten speichern" },
|
||||||
@ -189,6 +191,7 @@ namespace hex::plugin::builtin {
|
|||||||
{ "hex.view.hexeditor.goto.offset.end", "Ende" },
|
{ "hex.view.hexeditor.goto.offset.end", "Ende" },
|
||||||
{ "hex.view.hexeditor.error.read_only", "Schreibzugriff konnte nicht erlangt werden. Datei wurde im Lesemodus geöffnet." },
|
{ "hex.view.hexeditor.error.read_only", "Schreibzugriff konnte nicht erlangt werden. Datei wurde im Lesemodus geöffnet." },
|
||||||
{ "hex.view.hexeditor.error.open", "Öffnen der Datei fehlgeschlagen!" },
|
{ "hex.view.hexeditor.error.open", "Öffnen der Datei fehlgeschlagen!" },
|
||||||
|
{ "hex.view.hexeditor.error.create", "Erstellen der neuen Datei fehlgeschlagen!" },
|
||||||
{ "hex.view.hexeditor.menu.edit.undo", "Rückgängig" },
|
{ "hex.view.hexeditor.menu.edit.undo", "Rückgängig" },
|
||||||
{ "hex.view.hexeditor.menu.edit.redo", "Wiederholen" },
|
{ "hex.view.hexeditor.menu.edit.redo", "Wiederholen" },
|
||||||
{ "hex.view.hexeditor.menu.edit.copy", "Kopieren" },
|
{ "hex.view.hexeditor.menu.edit.copy", "Kopieren" },
|
||||||
@ -206,6 +209,7 @@ namespace hex::plugin::builtin {
|
|||||||
{ "hex.view.hexeditor.menu.edit.paste", "Einfügen" },
|
{ "hex.view.hexeditor.menu.edit.paste", "Einfügen" },
|
||||||
{ "hex.view.hexeditor.menu.edit.bookmark", "Lesezeichen erstellen" },
|
{ "hex.view.hexeditor.menu.edit.bookmark", "Lesezeichen erstellen" },
|
||||||
{ "hex.view.hexeditor.menu.edit.set_base", "Basisadresse setzen" },
|
{ "hex.view.hexeditor.menu.edit.set_base", "Basisadresse setzen" },
|
||||||
|
{ "hex.view.hexeditor.menu.edit.resize", "Grösse ändern" },
|
||||||
|
|
||||||
{ "hex.view.information.name", "Dateninformationen" },
|
{ "hex.view.information.name", "Dateninformationen" },
|
||||||
{ "hex.view.information.control", "Einstellungen" },
|
{ "hex.view.information.control", "Einstellungen" },
|
||||||
@ -276,6 +280,8 @@ namespace hex::plugin::builtin {
|
|||||||
{ "hex.view.yara.whole_data", "Gesammte Daten Übereinstimmung!" },
|
{ "hex.view.yara.whole_data", "Gesammte Daten Übereinstimmung!" },
|
||||||
{ "hex.view.yara.no_rules", "Keine Yara Regeln gefunden. Platziere sie in ImHex' 'yara' Ordner" },
|
{ "hex.view.yara.no_rules", "Keine Yara Regeln gefunden. Platziere sie in ImHex' 'yara' Ordner" },
|
||||||
|
|
||||||
|
{ "hex.view.constants.name", "Konstanten" },
|
||||||
|
|
||||||
/* Builtin plugin features */
|
/* Builtin plugin features */
|
||||||
|
|
||||||
{ "hex.builtin.command.calc.desc", "Rechner" },
|
{ "hex.builtin.command.calc.desc", "Rechner" },
|
||||||
|
@ -16,6 +16,7 @@ namespace hex::plugin::builtin {
|
|||||||
|
|
||||||
{ "hex.welcome.header.main", "Welcome to ImHex" },
|
{ "hex.welcome.header.main", "Welcome to ImHex" },
|
||||||
{ "hex.welcome.header.start", "Start" },
|
{ "hex.welcome.header.start", "Start" },
|
||||||
|
{ "hex.welcome.start.create_file", "Create New File" },
|
||||||
{ "hex.welcome.start.open_file", "Open File" },
|
{ "hex.welcome.start.open_file", "Open File" },
|
||||||
{ "hex.welcome.start.open_project", "Open Project" },
|
{ "hex.welcome.start.open_project", "Open Project" },
|
||||||
{ "hex.welcome.start.recent", "Recent Files" },
|
{ "hex.welcome.start.recent", "Recent Files" },
|
||||||
@ -139,7 +140,8 @@ namespace hex::plugin::builtin {
|
|||||||
{ "hex.view.help.calc_cheat_sheet", "Calculator Cheat Sheet" },
|
{ "hex.view.help.calc_cheat_sheet", "Calculator Cheat Sheet" },
|
||||||
|
|
||||||
{ "hex.view.hexeditor.name", "Hex editor" },
|
{ "hex.view.hexeditor.name", "Hex editor" },
|
||||||
{ "hex.view.hexeditor.open_file", "Open File" },
|
{ "hex.view.hexeditor.create_file", "New" },
|
||||||
|
{ "hex.view.hexeditor.open_file", "Open" },
|
||||||
{ "hex.view.hexeditor.open_project", "Open Project" },
|
{ "hex.view.hexeditor.open_project", "Open Project" },
|
||||||
{ "hex.view.hexeditor.save_project", "Save Project" },
|
{ "hex.view.hexeditor.save_project", "Save Project" },
|
||||||
{ "hex.view.hexeditor.save_data", "Save Data" },
|
{ "hex.view.hexeditor.save_data", "Save Data" },
|
||||||
@ -189,6 +191,7 @@ namespace hex::plugin::builtin {
|
|||||||
{ "hex.view.hexeditor.goto.offset.end", "End" },
|
{ "hex.view.hexeditor.goto.offset.end", "End" },
|
||||||
{ "hex.view.hexeditor.error.read_only", "Couldn't get write access. File opened in read-only mode." },
|
{ "hex.view.hexeditor.error.read_only", "Couldn't get write access. File opened in read-only mode." },
|
||||||
{ "hex.view.hexeditor.error.open", "Failed to open file!" },
|
{ "hex.view.hexeditor.error.open", "Failed to open file!" },
|
||||||
|
{ "hex.view.hexeditor.error.create", "Failed to create new file!" },
|
||||||
{ "hex.view.hexeditor.menu.edit.undo", "Undo" },
|
{ "hex.view.hexeditor.menu.edit.undo", "Undo" },
|
||||||
{ "hex.view.hexeditor.menu.edit.redo", "Redo" },
|
{ "hex.view.hexeditor.menu.edit.redo", "Redo" },
|
||||||
{ "hex.view.hexeditor.menu.edit.copy", "Copy" },
|
{ "hex.view.hexeditor.menu.edit.copy", "Copy" },
|
||||||
@ -206,6 +209,7 @@ namespace hex::plugin::builtin {
|
|||||||
{ "hex.view.hexeditor.menu.edit.paste", "Paste" },
|
{ "hex.view.hexeditor.menu.edit.paste", "Paste" },
|
||||||
{ "hex.view.hexeditor.menu.edit.bookmark", "Create bookmark" },
|
{ "hex.view.hexeditor.menu.edit.bookmark", "Create bookmark" },
|
||||||
{ "hex.view.hexeditor.menu.edit.set_base", "Set base address" },
|
{ "hex.view.hexeditor.menu.edit.set_base", "Set base address" },
|
||||||
|
{ "hex.view.hexeditor.menu.edit.resize", "Resize" },
|
||||||
|
|
||||||
{ "hex.view.information.name", "Data Information" },
|
{ "hex.view.information.name", "Data Information" },
|
||||||
{ "hex.view.information.control", "Control" },
|
{ "hex.view.information.control", "Control" },
|
||||||
@ -276,6 +280,8 @@ namespace hex::plugin::builtin {
|
|||||||
{ "hex.view.yara.whole_data", "Whole file matches!" },
|
{ "hex.view.yara.whole_data", "Whole file matches!" },
|
||||||
{ "hex.view.yara.no_rules", "No YARA rules found. Put them in ImHex' 'yara' folder" },
|
{ "hex.view.yara.no_rules", "No YARA rules found. Put them in ImHex' 'yara' folder" },
|
||||||
|
|
||||||
|
{ "hex.view.constants.name", "Constants" },
|
||||||
|
|
||||||
/* Builtin plugin features */
|
/* Builtin plugin features */
|
||||||
|
|
||||||
{ "hex.builtin.command.calc.desc", "Calculator" },
|
{ "hex.builtin.command.calc.desc", "Calculator" },
|
||||||
|
@ -16,6 +16,7 @@ namespace hex::plugin::builtin {
|
|||||||
|
|
||||||
{ "hex.welcome.header.main", "Benvenuto in ImHex" },
|
{ "hex.welcome.header.main", "Benvenuto in ImHex" },
|
||||||
{ "hex.welcome.header.start", "Inizia" },
|
{ "hex.welcome.header.start", "Inizia" },
|
||||||
|
// { "hex.welcome.start.create_file", "Create New File" },
|
||||||
{ "hex.welcome.start.open_file", "Apri un File" },
|
{ "hex.welcome.start.open_file", "Apri un File" },
|
||||||
{ "hex.welcome.start.open_project", "Apri un Progetto" },
|
{ "hex.welcome.start.open_project", "Apri un Progetto" },
|
||||||
{ "hex.welcome.start.recent", "File recenti" },
|
{ "hex.welcome.start.recent", "File recenti" },
|
||||||
@ -139,7 +140,8 @@ namespace hex::plugin::builtin {
|
|||||||
{ "hex.view.help.calc_cheat_sheet", "Calcolatrice Cheat Sheet" },
|
{ "hex.view.help.calc_cheat_sheet", "Calcolatrice Cheat Sheet" },
|
||||||
|
|
||||||
{ "hex.view.hexeditor.name", "Hex editor" },
|
{ "hex.view.hexeditor.name", "Hex editor" },
|
||||||
{ "hex.view.hexeditor.open_file", "Apri File" },
|
// { "hex.view.hexeditor.create_file", "New" },
|
||||||
|
{ "hex.view.hexeditor.open_file", "Apri" },
|
||||||
{ "hex.view.hexeditor.menu.file.open_recent", "File recenti" },
|
{ "hex.view.hexeditor.menu.file.open_recent", "File recenti" },
|
||||||
{ "hex.view.hexeditor.open_project", "Apri i Progetti" },
|
{ "hex.view.hexeditor.open_project", "Apri i Progetti" },
|
||||||
{ "hex.view.hexeditor.save_project", "Salva i Progetti" },
|
{ "hex.view.hexeditor.save_project", "Salva i Progetti" },
|
||||||
@ -189,6 +191,7 @@ namespace hex::plugin::builtin {
|
|||||||
{ "hex.view.hexeditor.goto.offset.end", "Fine" },
|
{ "hex.view.hexeditor.goto.offset.end", "Fine" },
|
||||||
{ "hex.view.hexeditor.error.read_only", "Impossibile scrivere sul File. File aperto solo in modalità lettura" },
|
{ "hex.view.hexeditor.error.read_only", "Impossibile scrivere sul File. File aperto solo in modalità lettura" },
|
||||||
{ "hex.view.hexeditor.error.open", "Impossibile aprire il File!" },
|
{ "hex.view.hexeditor.error.open", "Impossibile aprire il File!" },
|
||||||
|
// { "hex.view.hexeditor.error.create", "Failed to create new file!" },
|
||||||
{ "hex.view.hexeditor.menu.edit.undo", "Annulla" },
|
{ "hex.view.hexeditor.menu.edit.undo", "Annulla" },
|
||||||
{ "hex.view.hexeditor.menu.edit.redo", "Ripeti" },
|
{ "hex.view.hexeditor.menu.edit.redo", "Ripeti" },
|
||||||
{ "hex.view.hexeditor.menu.edit.copy", "Copia" },
|
{ "hex.view.hexeditor.menu.edit.copy", "Copia" },
|
||||||
@ -206,6 +209,7 @@ namespace hex::plugin::builtin {
|
|||||||
{ "hex.view.hexeditor.menu.edit.paste", "Incolla" },
|
{ "hex.view.hexeditor.menu.edit.paste", "Incolla" },
|
||||||
{ "hex.view.hexeditor.menu.edit.bookmark", "Crea segnalibro" },
|
{ "hex.view.hexeditor.menu.edit.bookmark", "Crea segnalibro" },
|
||||||
{ "hex.view.hexeditor.menu.edit.set_base", "Imposta indirizzo di base" },
|
{ "hex.view.hexeditor.menu.edit.set_base", "Imposta indirizzo di base" },
|
||||||
|
// { "hex.view.hexeditor.menu.edit.resize", "Resize" },
|
||||||
|
|
||||||
{ "hex.view.information.name", "Informazione sui Dati" },
|
{ "hex.view.information.name", "Informazione sui Dati" },
|
||||||
{ "hex.view.information.control", "Controllo" },
|
{ "hex.view.information.control", "Controllo" },
|
||||||
@ -276,6 +280,8 @@ namespace hex::plugin::builtin {
|
|||||||
{ "hex.view.yara.whole_data", "Tutti i file combaciano!" },
|
{ "hex.view.yara.whole_data", "Tutti i file combaciano!" },
|
||||||
{ "hex.view.yara.no_rules", "Nessuna regola di YARA. Aggiungile in nella cartella 'yara' di 'ImHex'" },
|
{ "hex.view.yara.no_rules", "Nessuna regola di YARA. Aggiungile in nella cartella 'yara' di 'ImHex'" },
|
||||||
|
|
||||||
|
// { "hex.view.constants.name", "Constants" },
|
||||||
|
|
||||||
/* Builtin plugin features */
|
/* Builtin plugin features */
|
||||||
|
|
||||||
{ "hex.builtin.command.calc.desc", "Calcolatrice" },
|
{ "hex.builtin.command.calc.desc", "Calcolatrice" },
|
||||||
|
@ -22,12 +22,15 @@ namespace hex::prv {
|
|||||||
virtual bool isAvailable() = 0;
|
virtual bool isAvailable() = 0;
|
||||||
virtual bool isReadable() = 0;
|
virtual bool isReadable() = 0;
|
||||||
virtual bool isWritable() = 0;
|
virtual bool isWritable() = 0;
|
||||||
|
virtual bool isResizable() = 0;
|
||||||
|
|
||||||
virtual void read(u64 offset, void *buffer, size_t size, bool overlays = true);
|
virtual void read(u64 offset, void *buffer, size_t size, bool overlays = true);
|
||||||
virtual void readRelative(u64 offset, void *buffer, size_t size, bool overlays = true);
|
virtual void readRelative(u64 offset, void *buffer, size_t size, bool overlays = true);
|
||||||
virtual void write(u64 offset, const void *buffer, size_t size);
|
virtual void write(u64 offset, const void *buffer, size_t size);
|
||||||
virtual void writeRelative(u64 offset, const void *buffer, size_t size);
|
virtual void writeRelative(u64 offset, const void *buffer, size_t size);
|
||||||
|
|
||||||
|
virtual void resize(ssize_t newSize);
|
||||||
|
|
||||||
virtual void readRaw(u64 offset, void *buffer, size_t size) = 0;
|
virtual void readRaw(u64 offset, void *buffer, size_t size) = 0;
|
||||||
virtual void writeRaw(u64 offset, const void *buffer, size_t size) = 0;
|
virtual void writeRaw(u64 offset, const void *buffer, size_t size) = 0;
|
||||||
virtual size_t getActualSize() = 0;
|
virtual size_t getActualSize() = 0;
|
||||||
|
@ -34,6 +34,8 @@ namespace hex::prv {
|
|||||||
this->write(offset + this->getBaseAddress(), buffer, size);
|
this->write(offset + this->getBaseAddress(), buffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Provider::resize(ssize_t newSize) { }
|
||||||
|
|
||||||
void Provider::applyOverlays(u64 offset, void *buffer, size_t size) {
|
void Provider::applyOverlays(u64 offset, void *buffer, size_t size) {
|
||||||
for (auto &overlay : this->m_overlays) {
|
for (auto &overlay : this->m_overlays) {
|
||||||
auto overlayOffset = overlay->getAddress();
|
auto overlayOffset = overlay->getAddress();
|
||||||
|
@ -13,7 +13,128 @@
|
|||||||
namespace hex::prv {
|
namespace hex::prv {
|
||||||
|
|
||||||
FileProvider::FileProvider(std::string_view path) : Provider(), m_path(path) {
|
FileProvider::FileProvider(std::string_view path) : Provider(), m_path(path) {
|
||||||
this->m_fileStatsValid = stat(path.data(), &this->m_fileStats) == 0;
|
this->open();
|
||||||
|
}
|
||||||
|
|
||||||
|
FileProvider::~FileProvider() {
|
||||||
|
this->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool FileProvider::isAvailable() {
|
||||||
|
#if defined(OS_WINDOWS)
|
||||||
|
return this->m_file != nullptr && this->m_mapping != nullptr && this->m_mappedFile != nullptr;
|
||||||
|
#else
|
||||||
|
return this->m_file != -1 && this->m_mappedFile != nullptr;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FileProvider::isReadable() {
|
||||||
|
return isAvailable() && this->m_readable;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FileProvider::isWritable() {
|
||||||
|
return isAvailable() && this->m_writable;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FileProvider::isResizable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FileProvider::read(u64 offset, void *buffer, size_t size, bool overlays) {
|
||||||
|
|
||||||
|
if (((offset - this->getBaseAddress()) + size) > this->getSize() || buffer == nullptr || size == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::memcpy(buffer, reinterpret_cast<u8*>(this->m_mappedFile) + PageSize * this->m_currPage + offset - this->getBaseAddress(), size);
|
||||||
|
|
||||||
|
for (u64 i = 0; i < size; i++)
|
||||||
|
if (getPatches().contains(offset + i))
|
||||||
|
reinterpret_cast<u8*>(buffer)[i] = getPatches()[offset + PageSize * this->m_currPage + i];
|
||||||
|
|
||||||
|
if (overlays)
|
||||||
|
this->applyOverlays(offset, buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileProvider::write(u64 offset, const void *buffer, size_t size) {
|
||||||
|
if (((offset - this->getBaseAddress()) + size) > this->getSize() || buffer == nullptr || size == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
addPatch(offset, buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileProvider::readRaw(u64 offset, void *buffer, size_t size) {
|
||||||
|
offset -= this->getBaseAddress();
|
||||||
|
|
||||||
|
if ((offset + size) > this->getSize() || buffer == nullptr || size == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::memcpy(buffer, reinterpret_cast<u8*>(this->m_mappedFile) + PageSize * this->m_currPage + offset, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileProvider::writeRaw(u64 offset, const void *buffer, size_t size) {
|
||||||
|
offset -= this->getBaseAddress();
|
||||||
|
|
||||||
|
if ((offset + size) > this->getSize() || buffer == nullptr || size == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::memcpy(reinterpret_cast<u8*>(this->m_mappedFile) + PageSize * this->m_currPage + offset, buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileProvider::resize(ssize_t newSize) {
|
||||||
|
close();
|
||||||
|
|
||||||
|
#if defined(OS_WINDOWS)
|
||||||
|
std::wstring widePath;
|
||||||
|
{
|
||||||
|
auto length = static_cast<int>(this->m_path.length() + 1);
|
||||||
|
auto wideLength = MultiByteToWideChar(CP_UTF8, 0, this->m_path.data(), length, nullptr, 0);
|
||||||
|
auto buffer = new wchar_t[wideLength];
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, this->m_path.data(), length, buffer, wideLength);
|
||||||
|
widePath = buffer;
|
||||||
|
delete[] buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto handle = ::CreateFileW(widePath.data(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||||
|
|
||||||
|
if (handle != INVALID_HANDLE_VALUE) {
|
||||||
|
::SetFilePointerEx(handle, LARGE_INTEGER { .QuadPart = newSize }, nullptr, FILE_BEGIN);
|
||||||
|
::SetEndOfFile(handle);
|
||||||
|
::CloseHandle(handle);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
auto handle = ::open(path.data(), O_RDWR | O_CREAT);
|
||||||
|
|
||||||
|
truncate(handle, newSize - 1);
|
||||||
|
|
||||||
|
close(handle);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
open();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t FileProvider::getActualSize() {
|
||||||
|
return this->m_fileSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::pair<std::string, std::string>> FileProvider::getDataInformation() {
|
||||||
|
std::vector<std::pair<std::string, std::string>> result;
|
||||||
|
|
||||||
|
result.emplace_back("hex.builtin.provider.file.path"_lang, this->m_path);
|
||||||
|
result.emplace_back("hex.builtin.provider.file.size"_lang, hex::toByteString(this->getActualSize()));
|
||||||
|
|
||||||
|
if (this->m_fileStatsValid) {
|
||||||
|
result.emplace_back("hex.builtin.provider.file.creation"_lang, ctime(&this->m_fileStats.st_ctime));
|
||||||
|
result.emplace_back("hex.builtin.provider.file.access"_lang, ctime(&this->m_fileStats.st_atime));
|
||||||
|
result.emplace_back("hex.builtin.provider.file.modification"_lang, ctime(&this->m_fileStats.st_mtime));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileProvider::open() {
|
||||||
|
this->m_fileStatsValid = stat(this->m_path.data(), &this->m_fileStats) == 0;
|
||||||
|
|
||||||
this->m_readable = true;
|
this->m_readable = true;
|
||||||
this->m_writable = true;
|
this->m_writable = true;
|
||||||
@ -21,10 +142,10 @@ namespace hex::prv {
|
|||||||
#if defined(OS_WINDOWS)
|
#if defined(OS_WINDOWS)
|
||||||
std::wstring widePath;
|
std::wstring widePath;
|
||||||
{
|
{
|
||||||
auto length = path.length() + 1;
|
auto length = this->m_path.length() + 1;
|
||||||
auto wideLength = MultiByteToWideChar(CP_UTF8, 0, path.data(), length, 0, 0);
|
auto wideLength = MultiByteToWideChar(CP_UTF8, 0, this->m_path.data(), length, 0, 0);
|
||||||
wchar_t* buffer = new wchar_t[wideLength];
|
wchar_t* buffer = new wchar_t[wideLength];
|
||||||
MultiByteToWideChar(CP_UTF8, 0, path.data(), length, buffer, wideLength);
|
MultiByteToWideChar(CP_UTF8, 0, this->m_path.data(), length, buffer, wideLength);
|
||||||
widePath = buffer;
|
widePath = buffer;
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
}
|
}
|
||||||
@ -72,12 +193,12 @@ namespace hex::prv {
|
|||||||
fileCleanup.release();
|
fileCleanup.release();
|
||||||
mappingCleanup.release();
|
mappingCleanup.release();
|
||||||
|
|
||||||
ProjectFile::setFilePath(path);
|
ProjectFile::setFilePath(this->m_path);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
this->m_file = open(path.data(), O_RDWR);
|
this->m_file = ::open(path.data(), O_RDWR);
|
||||||
if (this->m_file == -1) {
|
if (this->m_file == -1) {
|
||||||
this->m_file = open(path.data(), O_RDONLY);
|
this->m_file = ::open(path.data(), O_RDONLY);
|
||||||
this->m_writable = false;
|
this->m_writable = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,97 +211,21 @@ namespace hex::prv {
|
|||||||
|
|
||||||
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);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
FileProvider::~FileProvider() {
|
void FileProvider::close() {
|
||||||
#if defined(OS_WINDOWS)
|
#if defined(OS_WINDOWS)
|
||||||
if (this->m_mappedFile != nullptr)
|
if (this->m_mappedFile != nullptr)
|
||||||
UnmapViewOfFile(this->m_mappedFile);
|
::UnmapViewOfFile(this->m_mappedFile);
|
||||||
if (this->m_mapping != nullptr)
|
if (this->m_mapping != nullptr)
|
||||||
CloseHandle(this->m_mapping);
|
::CloseHandle(this->m_mapping);
|
||||||
if (this->m_file != nullptr)
|
if (this->m_file != nullptr)
|
||||||
CloseHandle(this->m_file);
|
::CloseHandle(this->m_file);
|
||||||
#else
|
#else
|
||||||
munmap(this->m_mappedFile, this->m_fileSize);
|
::munmap(this->m_mappedFile, this->m_fileSize);
|
||||||
close(this->m_file);
|
::close(this->m_file);
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool FileProvider::isAvailable() {
|
|
||||||
#if defined(OS_WINDOWS)
|
|
||||||
return this->m_file != nullptr && this->m_mapping != nullptr && this->m_mappedFile != nullptr;
|
|
||||||
#else
|
|
||||||
return this->m_file != -1 && this->m_mappedFile != nullptr;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FileProvider::isReadable() {
|
|
||||||
return isAvailable() && this->m_readable;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FileProvider::isWritable() {
|
|
||||||
return isAvailable() && this->m_writable;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void FileProvider::read(u64 offset, void *buffer, size_t size, bool overlays) {
|
|
||||||
|
|
||||||
if (((offset - this->getBaseAddress()) + size) > this->getSize() || buffer == nullptr || size == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::memcpy(buffer, reinterpret_cast<u8*>(this->m_mappedFile) + PageSize * this->m_currPage + offset - this->getBaseAddress(), size);
|
|
||||||
|
|
||||||
for (u64 i = 0; i < size; i++)
|
|
||||||
if (getPatches().contains(offset + i))
|
|
||||||
reinterpret_cast<u8*>(buffer)[i] = getPatches()[offset + PageSize * this->m_currPage + i];
|
|
||||||
|
|
||||||
if (overlays)
|
|
||||||
this->applyOverlays(offset, buffer, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileProvider::write(u64 offset, const void *buffer, size_t size) {
|
|
||||||
if (((offset - this->getBaseAddress()) + size) > this->getSize() || buffer == nullptr || size == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
addPatch(offset, buffer, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileProvider::readRaw(u64 offset, void *buffer, size_t size) {
|
|
||||||
offset -= this->getBaseAddress();
|
|
||||||
|
|
||||||
if ((offset + size) > this->getSize() || buffer == nullptr || size == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::memcpy(buffer, reinterpret_cast<u8*>(this->m_mappedFile) + PageSize * this->m_currPage + offset, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileProvider::writeRaw(u64 offset, const void *buffer, size_t size) {
|
|
||||||
offset -= this->getBaseAddress();
|
|
||||||
|
|
||||||
if ((offset + size) > this->getSize() || buffer == nullptr || size == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::memcpy(reinterpret_cast<u8*>(this->m_mappedFile) + PageSize * this->m_currPage + offset, buffer, size);
|
|
||||||
}
|
|
||||||
size_t FileProvider::getActualSize() {
|
|
||||||
return this->m_fileSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::pair<std::string, std::string>> FileProvider::getDataInformation() {
|
|
||||||
std::vector<std::pair<std::string, std::string>> result;
|
|
||||||
|
|
||||||
result.emplace_back("hex.builtin.provider.file.path"_lang, this->m_path);
|
|
||||||
result.emplace_back("hex.builtin.provider.file.size"_lang, hex::toByteString(this->getActualSize()));
|
|
||||||
|
|
||||||
if (this->m_fileStatsValid) {
|
|
||||||
result.emplace_back("hex.builtin.provider.file.creation"_lang, ctime(&this->m_fileStats.st_ctime));
|
|
||||||
result.emplace_back("hex.builtin.provider.file.access"_lang, ctime(&this->m_fileStats.st_atime));
|
|
||||||
result.emplace_back("hex.builtin.provider.file.modification"_lang, ctime(&this->m_fileStats.st_mtime));
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -16,6 +16,13 @@
|
|||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
|
#if defined(OS_WINDOWS)
|
||||||
|
#include <windows.h>
|
||||||
|
#else
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace hex {
|
namespace hex {
|
||||||
|
|
||||||
ViewHexEditor::ViewHexEditor() : View("hex.view.hexeditor.name"_lang) {
|
ViewHexEditor::ViewHexEditor() : View("hex.view.hexeditor.name"_lang) {
|
||||||
@ -168,7 +175,16 @@ namespace hex {
|
|||||||
});
|
});
|
||||||
|
|
||||||
EventManager::subscribe<RequestOpenWindow>(this, [this](std::string name) {
|
EventManager::subscribe<RequestOpenWindow>(this, [this](std::string name) {
|
||||||
if (name == "Open File") {
|
if (name == "Create File") {
|
||||||
|
View::openFileBrowser("hex.view.hexeditor.create_file"_lang, DialogMode::Save, { }, [this](auto path) {
|
||||||
|
if (!this->createFile(path)) {
|
||||||
|
View::showErrorPopup("hex.view.hexeditor.error.create"_lang);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this->openFile(path);
|
||||||
|
this->getWindowOpenState() = true;
|
||||||
|
});
|
||||||
|
} else if (name == "Open File") {
|
||||||
View::openFileBrowser("hex.view.hexeditor.open_file"_lang, DialogMode::Open, { }, [this](auto path) {
|
View::openFileBrowser("hex.view.hexeditor.open_file"_lang, DialogMode::Open, { }, [this](auto path) {
|
||||||
this->openFile(path);
|
this->openFile(path);
|
||||||
this->getWindowOpenState() = true;
|
this->getWindowOpenState() = true;
|
||||||
@ -361,6 +377,24 @@ namespace hex {
|
|||||||
|
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ImGui::BeginPopupModal("hex.view.hexeditor.menu.edit.resize"_lang, nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||||
|
ImGui::InputScalar("hex.common.size"_lang, ImGuiDataType_U64, &this->m_resizeSize, nullptr, nullptr, "0x%016llx", ImGuiInputTextFlags_CharsHexadecimal);
|
||||||
|
ImGui::NewLine();
|
||||||
|
|
||||||
|
confirmButtons("hex.common.set"_lang, "hex.common.cancel"_lang,
|
||||||
|
[this, &provider]{
|
||||||
|
provider->resize(this->m_resizeSize);
|
||||||
|
ImGui::CloseCurrentPopup();
|
||||||
|
}, []{
|
||||||
|
ImGui::CloseCurrentPopup();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (ImGui::IsKeyDown(ImGui::GetKeyIndex(ImGuiKey_Escape)))
|
||||||
|
ImGui::CloseCurrentPopup();
|
||||||
|
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewHexEditor::drawMenu() {
|
void ViewHexEditor::drawMenu() {
|
||||||
@ -583,17 +617,47 @@ namespace hex {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ViewHexEditor::createFile(std::string_view path) {
|
||||||
|
#if defined(OS_WINDOWS)
|
||||||
|
std::wstring widePath;
|
||||||
|
{
|
||||||
|
auto length = path.length() + 1;
|
||||||
|
auto wideLength = MultiByteToWideChar(CP_UTF8, 0, path.data(), length, 0, 0);
|
||||||
|
auto buffer = new wchar_t[wideLength];
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, path.data(), length, buffer, wideLength);
|
||||||
|
widePath = buffer;
|
||||||
|
delete[] buffer;
|
||||||
|
}
|
||||||
|
|
||||||
void ViewHexEditor::openFile(std::string path) {
|
auto handle = ::CreateFileW(widePath.data(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||||
|
|
||||||
|
if (handle == INVALID_HANDLE_VALUE)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
::SetFilePointer(handle, 1, nullptr, FILE_BEGIN);
|
||||||
|
::SetEndOfFile(handle);
|
||||||
|
::CloseHandle(handle);
|
||||||
|
#else
|
||||||
|
auto handle = ::open(path.data(), O_RDWR | O_CREAT);
|
||||||
|
if (handle == -1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
lseek(handle, 0, SEEK_SET);
|
||||||
|
write(handle, "", 1);
|
||||||
|
|
||||||
|
close(handle);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewHexEditor::openFile(std::string_view path) {
|
||||||
auto& provider = SharedData::currentProvider;
|
auto& provider = SharedData::currentProvider;
|
||||||
|
|
||||||
if (provider != nullptr)
|
delete provider;
|
||||||
delete provider;
|
|
||||||
|
|
||||||
provider = new prv::FileProvider(path);
|
provider = new prv::FileProvider(path);
|
||||||
if (!provider->isWritable()) {
|
if (!provider->isWritable()) {
|
||||||
@ -615,13 +679,13 @@ namespace hex {
|
|||||||
|
|
||||||
this->getWindowOpenState() = true;
|
this->getWindowOpenState() = true;
|
||||||
|
|
||||||
EventManager::post<EventFileLoaded>(path);
|
EventManager::post<EventFileLoaded>(std::string(path));
|
||||||
EventManager::post<EventDataChanged>();
|
EventManager::post<EventDataChanged>();
|
||||||
EventManager::post<EventPatternChanged>();
|
EventManager::post<EventPatternChanged>();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ViewHexEditor::saveToFile(std::string path, const std::vector<u8>& data) {
|
bool ViewHexEditor::saveToFile(std::string_view path, const std::vector<u8>& data) {
|
||||||
FILE *file = fopen(path.c_str(), "wb");
|
FILE *file = fopen(path.data(), "wb");
|
||||||
|
|
||||||
if (file == nullptr)
|
if (file == nullptr)
|
||||||
return false;
|
return false;
|
||||||
@ -632,8 +696,8 @@ namespace hex {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ViewHexEditor::loadFromFile(std::string path, std::vector<u8>& data) {
|
bool ViewHexEditor::loadFromFile(std::string_view path, std::vector<u8>& data) {
|
||||||
FILE *file = fopen(path.c_str(), "rb");
|
FILE *file = fopen(path.data(), "rb");
|
||||||
|
|
||||||
if (file == nullptr)
|
if (file == nullptr)
|
||||||
return false;
|
return false;
|
||||||
@ -1228,6 +1292,13 @@ R"(
|
|||||||
std::memset(this->m_baseAddressBuffer, 0x00, sizeof(this->m_baseAddressBuffer));
|
std::memset(this->m_baseAddressBuffer, 0x00, sizeof(this->m_baseAddressBuffer));
|
||||||
View::doLater([]{ ImGui::OpenPopup("hex.view.hexeditor.menu.edit.set_base"_lang); });
|
View::doLater([]{ ImGui::OpenPopup("hex.view.hexeditor.menu.edit.set_base"_lang); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ImGui::MenuItem("hex.view.hexeditor.menu.edit.resize"_lang, nullptr, false, provider != nullptr && provider->isResizable())) {
|
||||||
|
View::doLater([this, &provider]{
|
||||||
|
this->m_resizeSize = provider->getActualSize();
|
||||||
|
ImGui::OpenPopup("hex.view.hexeditor.menu.edit.resize"_lang);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -424,6 +424,8 @@ namespace hex {
|
|||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
ImGui::TextUnformatted("hex.welcome.header.start"_lang);
|
ImGui::TextUnformatted("hex.welcome.header.start"_lang);
|
||||||
{
|
{
|
||||||
|
if (ImGui::BulletHyperlink("hex.welcome.start.create_file"_lang))
|
||||||
|
EventManager::post<RequestOpenWindow>("Create File");
|
||||||
if (ImGui::BulletHyperlink("hex.welcome.start.open_file"_lang))
|
if (ImGui::BulletHyperlink("hex.welcome.start.open_file"_lang))
|
||||||
EventManager::post<RequestOpenWindow>("Open File");
|
EventManager::post<RequestOpenWindow>("Open File");
|
||||||
if (ImGui::BulletHyperlink("hex.welcome.start.open_project"_lang))
|
if (ImGui::BulletHyperlink("hex.welcome.start.open_project"_lang))
|
||||||
|
Loading…
Reference in New Issue
Block a user