Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi
| NE | `application/x-ms-ne-executable` | [`patterns/ne.hexpat`](patterns/ne.hexpat) | NE header and Standard NE fields |
| nes | | [`patterns/nes.hexpat`](patterns/nes.hexpat) | .nes file format |
| NotepadCache | | [`patterns/notepad-cache.hexpat`](patterns/notepad-cache.hexpat) | Windows Notepad Cache |
| NotepadStateFile | | [`patterns/notepad-state.hexpat`](patterns/notepad-state.hexpat) | Windows Notepad .bin State files |
| NotepadWindowState | | [`patterns/notepadwindowstate.hexpat`](patterns/notepadwindowstate.hexpat) | Windows 11 Notepad - Window State .bin file |
| NRO | | [`patterns/nro.hexpat`](patterns/nro.hexpat) | Nintendo Switch NRO files |
| NTAG | | [`patterns/ntag.hexpat`](patterns/ntag.hexpat) | NTAG213/NTAG215/NTAG216, NFC Forum Type 2 Tag compliant IC |
Expand Down
95 changes: 95 additions & 0 deletions patterns/notepad-state.hexpat
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#pragma author Gal1leo
#pragma description Windows Notepad State Files
#pragma magic [ 4E 50 00 ] @ 0x00


import type.leb128;
import type.time;
import type.magic;
import std.time;


std::mem::Section currentSection;


using uLEB128 = type::uLEB128;

enum Encodings: u8 {
ANSI = 0x01,
UTF_16LE = 0x02,
UTF_16BE = 0x03,
UTF_8BOM = 0x04,
UTF_8 = 0x05,
};

enum LineEndings: u8 {
CRLF = 0x01,
CR = 0x02,
LF = 0x03,
};

struct MoreOptionsBlock {
u8 unknown_spell_1;
u8 unknown_spell_2;
u8 formatting_type;
};


struct ConfigBlock {
bool word_wrap;
bool rtl;
bool show_unicode;
uLEB128 more_options_number;
MoreOptionsBlock more_options_block;
};


struct UnsavedChunk {
uLEB128 cursor_position;
uLEB128 deletion_number;
uLEB128 addition_number;
char16 chars[addition_number];
char crc32[4] [[format("hash_format"), comment("CRC32 hash of the entire unsaved chunk structure")]];
};

struct Notepad_File {
type::Magic<"NP\0"> signature [[comment("File signature")]];
bool is_saved;
if ( is_saved ) {
uLEB128 path_length;
char16 path[path_length] [[comment("Path of saved file on disk")]];
uLEB128 file_size;
Encodings encoding;
LineEndings line_endings;
uLEB128 last_write [[format("format_filetime")]];
char sha256[32] [[format("hash_format")]];
u8 unknown1;
}
u8 unknown2;
uLEB128 selection_start;
uLEB128 selection_end;
ConfigBlock config_block;
type::uLEB128 content_length;
currentSection = std::mem::create_section("File Content");
char16 content[content_length];
std::mem::copy_value_to_section(content, currentSection, 0);
bool contain_unsaved_data;
char crc32[4] [[format("hash_format")]];
UnsavedChunk unsaved_chunks[while(!std::mem::eof())];
};

fn hash_format(auto bytes) {
str hash_hex;
for(u8 i=0, i < sizeof(bytes), i+=1) {
hash_hex = hash_hex + std::format("{:02X}",bytes[i]);
}
return hash_hex;
};

fn format_filetime(uLEB128 data) {
// We will only support dates back to the epoch
std::time::Time time64 = std::time::to_utc((data / 10000000.0) - 11644473600.0);
return std::time::format(time64, "%c");
};

Notepad_File file @ $;