Compare commits

..

19 Commits

Author SHA1 Message Date
Merlyn Morgan-Graham
de0e089165 includes/std+type: Add DOS datetime types (#57)
Add type::dosdate16_t and type::dostime16_t in pattern library
2022-11-14 10:08:00 +01:00
Fredrick Brennan
e7ea6fd77f patterns: Added APNG support to PNG pattern (#53) 2022-11-10 10:36:46 +01:00
Fredrick Brennan
ff3c796de8 patterns: Added sRGB, zTXt, tEXt support to PNG pattern (#55)
* patterns: png.hexpat: APNG support

* patterns: png.hexpat: +sRGB, zTXt, tEXt
2022-11-10 10:23:42 +01:00
lieyanqzu
0c83764f24 patterns: Fix java class pattern and update to javase17 format (#56)
fix java class pattern and update to javase17 format
2022-11-10 10:23:06 +01:00
Fredrick Brennan
d87f95dbfa includes/type: Add RGB8 to color.pat (#54) 2022-11-10 10:22:17 +01:00
Nik
51dad63779 includes/std: Removed invalid returns 2022-11-09 21:56:06 +01:00
Nik
764b86acc9 includes/std: Added section functions 2022-11-09 21:53:31 +01:00
Nik
10fdf94899 includes/std: Fixed syntax error 2022-11-09 21:25:01 +01:00
Nik
9ba998e618 includes/std: Added new functions 2022-11-09 21:21:59 +01:00
WerWolv
aceeb2b7b3 git: Don't build plcli tool in tests 2022-11-06 18:40:39 +01:00
fr0ntlin3
3b1b7cc379 patterns: Fixed ELF pattern for 32-bit files (#51)
Co-authored-by: z <z>
2022-11-06 18:36:37 +01:00
gmestanley
49be43e0e1 patterns: Making pe.hexpat even better (#52)
* Update pe.hexpat

Implementing a number of things and fixing others

* Update pe.hexpat

Adding the readonlyData pattern

* Update pe.hexpat

Testing putting the number of tabs on Github to 4 instead of 8 (so that comments on the code for the Sections don't break)

* Update pe.hexpat

Reverting change that turned out to be needless

* Update pe.hexpat

Actually sending the `products[while($ != richHeaderEndPosition)]` to `products[while($ < richHeaderEndPosition)]` change
2022-10-30 12:07:54 +01:00
Nik
8e70a5524d includes/type: Added templates for number types with specific base 2022-10-10 22:36:46 +02:00
Nik
9c0bf1433c includes/std: Added new Array and SizedString type 2022-10-10 22:36:09 +02:00
Nik
43afbfa120 includes/type: Made size and float16 types more generic 2022-10-09 17:38:05 +02:00
Nik
f75703fd2b includes/std: Added MagicSearch and Reinterpreter helper type 2022-10-09 17:37:37 +02:00
Nik
16eebea2fb patterns: Added USB Descriptor pattern 2022-10-09 12:46:29 +02:00
Florian Limberger
6cb208d975 patterns: Added pattern for ID3 tags (#48)
* Add naive first implementation of ID3 patterns

* Refine string handling a bit

* Optimize structs using the static keyword

* Add MIME type pragma and update README
2022-10-09 12:26:34 +02:00
Nik
665c50b914 patterns: Fixed minidump pattern formatting 2022-10-08 11:20:46 +02:00
22 changed files with 1926 additions and 600 deletions

View File

@@ -50,6 +50,7 @@ jobs:
-DCMAKE_C_FLAGS="-fuse-ld=lld --coverage" \
-DCMAKE_CXX_FLAGS="-fuse-ld=lld --coverage" \
-DLIBPL_ENABLE_TESTS=OFF \
-DLIBPL_ENABLE_CLI=OFF \
..
make -j4

View File

@@ -45,6 +45,7 @@ Hex patterns, include patterns and magic files for the use with the ImHex Hex Ed
| BSON | `application/bson` | [`patterns/bson.hexpat`](patterns/bson.hexpat) | BSON (Binary JSON) format |
| msgpack | `application/x-msgpack` | [`patterns/msgpack.hexpat`](patterns/msgpack.hexpat) | MessagePack binary serialization format |
| MiniDump | `application/x-dmp` | [`patterns/minidump.hexpat`](patterns/minidump.hexpat) | Windows MiniDump files |
| ID3 | `audio/mpeg` | [`patterns/id3tag.hexpat`](patterns/id3tag.hexpat) | ID3 tags in MP3 files |
### Scripts

9
includes/std/array.pat Normal file
View File

@@ -0,0 +1,9 @@
#pragma once
namespace std {
struct Array<T, auto Size> {
T data[Size] [[inline]];
};
}

View File

@@ -30,7 +30,7 @@ namespace std::core {
fn set_bitfield_order(BitfieldOrder order) {
builtin::std::core::set_bitfield_order(order);
builtin::std::core::set_bitfield_order(u32(order));
};
fn get_bitfield_order() {
@@ -54,4 +54,7 @@ namespace std::core {
return builtin::std::core::formatted_value(pattern);
};
fn is_valid_enum(ref auto pattern) {
return builtin::std::core::is_valid_enum(pattern);
};
}

View File

@@ -2,28 +2,8 @@
namespace std::hash {
fn crc32(u128 address, u64 size, u32 init, u32 poly) {
u8 byte;
u32 crc, mask;
crc = init;
u64 i;
while (i < size) {
byte = std::mem::read_unsigned(address + i, 1);
crc = crc ^ byte;
u8 j;
while (j < 8) {
mask = u32(-(crc & 1));
crc = (crc >> 1) ^ (poly & mask);
j = j + 1;
}
i = i + 1;
}
return u32(~crc);
fn crc32(ref auto pattern, u32 init, u32 poly) {
return builtin::std::hash::crc32(pattern, init, poly);
};
}

View File

@@ -2,6 +2,8 @@
namespace std::mem {
using Section = u128;
enum Endian : u8 {
Native = 0,
Big = 1,
@@ -47,4 +49,48 @@ namespace std::mem {
return builtin::std::mem::read_string(address, size);
};
fn create_section(str name) {
return builtin::std::mem::create_section(name);
};
fn delete_section(Section section) {
builtin::std::mem::delete_section(section);
};
fn get_section_size(Section section) {
return builtin::std::mem::get_section_size(section);
};
fn copy_section_to_section(Section from_section, u64 from_address, Section to_section, u64 to_address, u64 size) {
builtin::std::mem::get_section_size(from_section, from_address, to_section, to_address, size);
};
fn copy_value_to_section(ref auto value, Section to_section, u64 to_address) {
builtin::std::mem::copy_value_to_section(value, to_section, to_address);
};
struct MagicSearch<auto Magic, T> {
if ($ < (std::mem::size() - std::string::length(Magic) - 1)) {
char __potentialMagic__[std::string::length(Magic)] [[hidden, no_unique_address]];
if (__potentialMagic__ == Magic) {
T data [[inline]];
} else {
padding[1];
continue;
}
} else {
padding[1];
continue;
}
};
union Reinterpreter<From, To> {
From from;
To to;
};
}

View File

@@ -4,6 +4,22 @@
namespace std::string {
struct SizedStringBase<SizeType, DataType> {
SizeType size;
DataType data[size];
} [[sealed, format("std::string::impl::format_sized_string"), transform("std::string::impl::format_sized_string")]];
using SizedString<SizeType> = SizedStringBase<SizeType, char>;
using SizedString16<SizeType> = SizedStringBase<SizeType, char16>;
namespace impl {
fn format_sized_string(ref auto string) {
return string.data;
};
}
fn length(str string) {
return builtin::std::string::length(string);
};

View File

@@ -15,12 +15,12 @@ namespace std::time {
u16 yday;
bool isdst;
} [[sealed]];
union TimeConverter {
Time time;
u128 value;
};
using EpochTime = u128;
enum TimeZone : u8 {
@@ -28,44 +28,94 @@ namespace std::time {
UTC
};
bitfield DOSDate {
day: 5;
month: 4;
year: 7;
} [[sealed]];
bitfield DOSTime {
seconds: 5;
minutes: 6;
hours: 5;
} [[sealed]];
namespace impl {
union DOSDateConverter {
DOSDate date;
u16 value;
};
union DOSTimeConverter {
DOSTime time;
u16 value;
};
}
fn epoch() {
return builtin::std::time::epoch();
};
fn to_local(EpochTime epoch_time) {
TimeConverter converter;
converter.value = builtin::std::time::to_local(epoch_time);
return converter.time;
};
fn to_utc(EpochTime epoch_time) {
TimeConverter converter;
converter.value = builtin::std::time::to_utc(epoch_time);
return converter.time;
};
fn to_utc(EpochTime epoch_time) {
TimeConverter converter;
converter.value = builtin::std::time::to_utc(epoch_time);
return converter.time;
};
fn now(TimeZone time_zone = TimeZone::Local) {
TimeConverter converter;
if (time_zone == TimeZone::Local)
converter.value = builtin::std::time::to_local(std::time::epoch());
else if (time_zone == TimeZone::UTC)
converter.value = builtin::std::time::to_utc(std::time::epoch());
else
converter.value = 0x00;
return converter.time;
};
fn to_dos_date(u16 value) {
impl::DOSDateConverter converter;
converter.value = value;
return converter.date;
};
fn to_dos_time(u16 value) {
impl::DOSTimeConverter converter;
converter.value = value;
return converter.time;
};
fn format(Time time, str format_string = "%c") {
TimeConverter converter;
converter.time = time;
return builtin::std::time::format(format_string, converter.value);
};
}
fn format_dos_date(DOSDate date, str format_string = "{}/{}/{}") {
return std::format(format_string, date.day, date.month, date.year + 1980);
};
fn format_dos_time(DOSTime time, str format_string = "{:02}:{:02}:{:02}") {
return std::format(format_string, time.hours, time.minutes, time.seconds * 2);
};
}

31
includes/type/base.pat Normal file
View File

@@ -0,0 +1,31 @@
#pragma once
#include <std/io.pat>
#include <std/math.pat>
namespace type {
using Hex<T> = T [[format("type::impl::format_hex")]];
using Oct<T> = T [[format("type::impl::format_oct")]];
using Dec<T> = T [[format("type::impl::format_dec")]];
using Bin<T> = T [[format("type::impl::format_bin")]];
namespace impl {
fn format_number(auto value, str fmt) {
bool negative = value < 0;
if (negative)
return std::format("-" + fmt, std::math::abs(value));
else
return std::format(fmt, value);
};
fn format_hex(auto value) { return format_number(value, "0x{:02X}"); };
fn format_oct(auto value) { return format_number(value, "0o{:03o}"); };
fn format_dec(auto value) { return format_number(value, "{}"); };
fn format_bin(auto value) { return format_number(value, "0b{:08b}"); };
}
}

View File

@@ -5,6 +5,10 @@
namespace type {
struct RGB8 {
u8 r, g, b;
} [[sealed, format("type::impl::format_color")]];
struct RGBA8 {
u8 r, g, b, a;
} [[sealed, format("type::impl::format_color")]];

View File

@@ -2,6 +2,7 @@
#include <std/io.pat>
#include <std/math.pat>
#include <std/mem.pat>
namespace type {
@@ -41,10 +42,10 @@ namespace type {
result = (sign << 31) | ((exponent + (0x7F - 15)) << 23) | (mantissa << 13);
}
U32ToFloatConverter converter;
converter.intValue = result;
std::mem::Reinterpreter<u32, float> converter;
converter.from = result;
return std::format("{}", converter.floatValue);
return std::format("{}", converter.to);
};
}

View File

@@ -1,13 +1,14 @@
#pragma once
#include <std/io.pat>
namespace type {
using Size8 = u8 [[format("type::impl::size_formatter")]];
using Size16 = u16 [[format("type::impl::size_formatter")]];
using Size32 = u32 [[format("type::impl::size_formatter")]];
using Size64 = u64 [[format("type::impl::size_formatter")]];
using Size128 = u128 [[format("type::impl::size_formatter")]];
using Size<T> = T [[format("type::impl::size_formatter")]];
using Size8 = Size<u8>;
using Size16 = Size<u16>;
using Size32 = Size<u32>;
using Size64 = Size<u64>;
using Size128 = Size<u128>;
namespace impl {
@@ -45,4 +46,4 @@ namespace type {
}
}
}

View File

@@ -4,16 +4,26 @@
#include <std/time.pat>
namespace type {
using time32_t = u32 [[format("type::impl::format_time_t")]];
using time64_t = u64 [[format("type::impl::format_time_t")]];
using dosdate16_t = u16 [[format("type::impl::format_dosdate16_t")]];
using dostime16_t = u16 [[format("type::impl::format_dostime16_t")]];
namespace impl {
fn format_time_t(u128 value) {
fn format_time_t(u128 value) {
return std::time::format(std::time::to_utc(value));
};
fn format_dosdate16_t(u16 value) {
return std::time::format_dos_date(std::time::to_dos_date(value));
};
fn format_dostime16_t(u16 value) {
return std::time::format_dos_time(std::time::to_dos_time(value));
};
}
}

View File

@@ -560,7 +560,7 @@ struct Elf32_Phdr {
PF p_flags;
Elf32_Word p_align;
if (p_offset > 0 && p_filesz > 0 && (p_offset + p_filesz) < std::mem::data_size() && p_filesz < std::mem::data_size())
if (p_offset > 0 && p_filesz > 0 && (p_offset + p_filesz) < std::mem::size() && p_filesz < std::mem::size())
u8 p_data[p_filesz] @ p_offset;
};
@@ -731,7 +731,9 @@ struct ELF {
std::core::set_endian(std::mem::Endian::Big);
if (e_ident.EI_CLASS == EI_CLASS::ELFCLASS32) {
Elf32_Ehdr header;
Elf32_Ehdr ehdr;
Elf32_Phdr phdr[ehdr.e_phnum] @ ehdr.e_phoff;
Elf32_Shdr shdr[ehdr.e_shnum] @ ehdr.e_shoff;
} else if (e_ident.EI_CLASS == EI_CLASS::ELFCLASS64) {
Elf64_Ehdr ehdr;
Elf64_Phdr phdr[ehdr.e_phnum] @ ehdr.e_phoff;

156
patterns/id3.hexpat Normal file
View File

@@ -0,0 +1,156 @@
#pragma MIME audio/mpeg
#include <std/mem.pat>
namespace v1 {
struct Tag {
char header[3];
char title[30];
char artist[30];
char album[30];
char year[4];
char comment[30];
u8 zero;
u8 track;
u8 genre;
} [[static]];
}
namespace v2 {
struct SyncSafeInt {
u8 bytes[4];
} [[sealed, static, format("v2::ssi_value"), transform("v2::ssi_value")]];
fn ssi_value(ref SyncSafeInt n) {
u32 result = 0;
for (u8 i = 0, i < 4, i = i + 1) {
u8 byteval = n.bytes[i] & 0x7F;
u8 shift = 7 * (4 - i - 1);
result = result | (byteval << shift);
}
return result;
};
struct TagVersion {
u8 major;
u8 revision;
};
bitfield TagHeaderFlags {
unsynchronized : 1;
extended : 1;
experimental : 1;
footer : 1;
padding : 4;
};
struct TagHeader {
char identifier[3];
TagVersion version;
TagHeaderFlags flags;
SyncSafeInt size;
} [[static]];
bitfield ExtendedFlag {
padding : 1;
update : 1;
crcpresent : 1;
restrictions : 1;
padding : 4;
};
struct TagExtendedHeader {
SyncSafeInt size;
u8 nflagbytes;
ExtendedFlag flags[nflagbytes];
u8 data[size];
};
struct TagFooter {
char identifier[3];
TagVersion version;
TagHeaderFlags flags;
SyncSafeInt size;
} [[static]];
bitfield FrameFlags {
padding : 1;
tagalterpreservation : 1;
filealterpreservation : 1;
readonly : 1;
padding : 5;
groupid : 1;
padding : 2;
compressed : 1;
encrypted : 1;
unzynchronized : 1;
datalengthindicator : 1;
};
enum TextEncoding : u8 {
ISO88591 = 0x00,
UTF16BOM = 0x01,
UTF16BE = 0x02,
UTF8 = 0x03,
};
struct StringData {
TextEncoding encoding;
if (encoding == TextEncoding::UTF16BOM) {
u16 bom;
char16 data[(parent.size - 3) / 2];
} else if (encoding == TextEncoding::UTF16BE)
be char16 data[(parent.size - 1) / 2];
else
char data[parent.size - 1];
};
// Hack to work around the fact, that chars may not be compared
union FrameId {
char cdata[4];
u8 ndata[4];
} [[sealed, static, format("v2::impl::format_frame_id")]];
namespace impl {
fn format_frame_id(ref FrameId id) {
return id.cdata;
};
}
struct Frame {
FrameId id;
SyncSafeInt size;
FrameFlags flags;
if (id.ndata[0] == 'T')
StringData data;
else
u8 data[size];
};
fn has_next_frame(u32 size) {
bool hasnext = $ < size;
if (hasnext) {
hasnext = std::mem::read_unsigned($, 1) != 0;
$ = $ - 1;
}
return hasnext;
};
struct Tag {
TagHeader header;
if (header.flags.extended)
TagExtendedHeader extendedheader;
Frame frames[while(v2::has_next_frame(header.size))];
if (header.flags.footer)
TagFooter footer;
};
}
v2::Tag tag @ 0;
v1::Tag oldtag @ std::mem::size() - 128;

View File

@@ -26,7 +26,9 @@ enum cp_tag : u8 {
CONSTANT_NameAndType = 12,
CONSTANT_MethodHandle = 15,
CONSTANT_MethodType = 16,
CONSTANT_InvokeDynamic = 18
CONSTANT_InvokeDynamic = 18,
CONSTANT_Module = 19,
CONSTANT_Package = 20
};
enum major_version : u2 {
@@ -36,7 +38,7 @@ enum major_version : u2 {
JDK_1_4 = 48,
Java_SE_5_0 = 49,
Java_SE_6_0 = 50,
Java_SE_6 = 50,
Java_SE_7 = 51,
Java_SE_8 = 52,
Java_SE_9 = 53,
@@ -129,37 +131,62 @@ struct CONSTANT_InvokeDynamic_info {
u2 name_and_type_index;
};
struct cp_info {
cp_tag tag;
// Tag == CONSTANT_Module
struct CONSTANT_Module_info {
u2 name_index;
};
if (tag == cp_tag::CONSTANT_Utf8)
CONSTANT_Utf8_info info [[inline]];
else if (tag == cp_tag::CONSTANT_Integer)
CONSTANT_Integer_info info [[inline]];
else if (tag == cp_tag::CONSTANT_Float)
CONSTANT_Float_info info [[inline]];
else if (tag == cp_tag::CONSTANT_Long)
CONSTANT_Long_info info [[inline]];
else if (tag == cp_tag::CONSTANT_Double)
CONSTANT_Double_info info [[inline]];
else if (tag == cp_tag::CONSTANT_Class)
CONSTANT_Class_info info [[inline]];
else if (tag == cp_tag::CONSTANT_String)
CONSTANT_String_info info [[inline]];
else if (tag == cp_tag::CONSTANT_Fieldref)
CONSTANT_Fieldref_info info [[inline]];
else if (tag == cp_tag::CONSTANT_Methodref)
CONSTANT_Methodref_info info [[inline]];
else if (tag == cp_tag::CONSTANT_InterfaceMethodref)
CONSTANT_InterfaceMethodref_info info [[inline]];
else if (tag == cp_tag::CONSTANT_NameAndType)
CONSTANT_NameAndType_info info [[inline]];
else if (tag == cp_tag::CONSTANT_MethodHandle)
CONSTANT_MethodHandle_info info [[inline]];
else if (tag == cp_tag::CONSTANT_MethodType)
CONSTANT_MethodType_info info [[inline]];
else if (tag == cp_tag::CONSTANT_InvokeDynamic)
CONSTANT_InvokeDynamic_info info [[inline]];
// Tag == CONSTANT_Package
struct CONSTANT_Package_info {
u2 name_index;
};
// All 8-byte constants take up two entries in the constant_pool table of the class file
u1 padding_entry_flag = 0;
struct cp_info {
if (padding_entry_flag == 0) {
cp_tag tag;
if (tag == cp_tag::CONSTANT_Utf8)
CONSTANT_Utf8_info info [[inline]];
else if (tag == cp_tag::CONSTANT_Integer)
CONSTANT_Integer_info info [[inline]];
else if (tag == cp_tag::CONSTANT_Float)
CONSTANT_Float_info info [[inline]];
else if (tag == cp_tag::CONSTANT_Long) {
CONSTANT_Long_info info [[inline]];
padding_entry_flag = 1;
}
else if (tag == cp_tag::CONSTANT_Double) {
CONSTANT_Double_info info [[inline]];
padding_entry_flag = 1;
}
else if (tag == cp_tag::CONSTANT_Class)
CONSTANT_Class_info info [[inline]];
else if (tag == cp_tag::CONSTANT_String)
CONSTANT_String_info info [[inline]];
else if (tag == cp_tag::CONSTANT_Fieldref)
CONSTANT_Fieldref_info info [[inline]];
else if (tag == cp_tag::CONSTANT_Methodref)
CONSTANT_Methodref_info info [[inline]];
else if (tag == cp_tag::CONSTANT_InterfaceMethodref)
CONSTANT_InterfaceMethodref_info info [[inline]];
else if (tag == cp_tag::CONSTANT_NameAndType)
CONSTANT_NameAndType_info info [[inline]];
else if (tag == cp_tag::CONSTANT_MethodHandle)
CONSTANT_MethodHandle_info info [[inline]];
else if (tag == cp_tag::CONSTANT_MethodType)
CONSTANT_MethodType_info info [[inline]];
else if (tag == cp_tag::CONSTANT_InvokeDynamic)
CONSTANT_InvokeDynamic_info info [[inline]];
else if (tag == cp_tag::CONSTANT_Module)
CONSTANT_Module_info info [[inline]];
else if (tag == cp_tag::CONSTANT_Package)
CONSTANT_Package_info info [[inline]];
} else {
padding_entry_flag = 0;
}
};
bitfield access_flags_method {
@@ -216,7 +243,7 @@ bitfield access_flags_class {
ACC_SYNTHETIC : 1; // 0x1000
ACC_ANNOTATION : 1; // 0x2000
ACC_ENUM : 1; // 0x4000
padding : 1; // 0x8000
ACC_MODULE : 1; // 0x8000
};
struct attribute_info {
@@ -279,31 +306,29 @@ fn main() {
std::print("Fields:");
for (le u16 i = 0, i < class_file.fields_count, i = i + 1) {
str method_string = " ";
str field_string = " ";
if (class_file.fields[i].access_flags.ACC_PUBLIC)
method_string = method_string + "public ";
field_string = field_string + "public ";
if (class_file.fields[i].access_flags.ACC_PRIVATE)
method_string = method_string + "private ";
field_string = field_string + "private ";
if (class_file.fields[i].access_flags.ACC_PROTECTED)
method_string = method_string + "protected ";
field_string = field_string + "protected ";
if (class_file.fields[i].access_flags.ACC_STATIC)
method_string = method_string + "static ";
field_string = field_string + "static ";
if (class_file.fields[i].access_flags.ACC_FINAL)
method_string = method_string + "final ";
field_string = field_string + "final ";
if (class_file.fields[i].access_flags.ACC_VOLATILE)
method_string = method_string + "volatile ";
if (class_file.fields[i].access_flags.ACC_NATIVE)
method_string = method_string + "native ";
field_string = field_string + "volatile ";
if (class_file.fields[i].access_flags.ACC_TRANSIENT)
method_string = method_string + "transient ";
field_string = field_string + "transient ";
if (class_file.fields[i].access_flags.ACC_ENUM)
method_string = method_string + "enum ";
field_string = field_string + "enum ";
method_string = method_string + class_file.constant_pool[class_file.fields[i].name_index - 1].info.bytes;
method_string = method_string + " [ " + class_file.constant_pool[class_file.fields[i].descriptor_index - 1].info.bytes + " ]";
field_string = field_string + class_file.constant_pool[class_file.fields[i].name_index - 1].info.bytes;
field_string = field_string + " [ " + class_file.constant_pool[class_file.fields[i].descriptor_index - 1].info.bytes + " ]";
std::print("{}", method_string);
std::print("{}", field_string);
}
std::print("Methods:");

View File

@@ -8,50 +8,50 @@ using RVA = ULONG32;
using RVA64 = ULONG64;
enum MINIDUMP_STREAM_TYPE : ULONG32 {
UnusedStream = 0,
ReservedStream0 = 1,
ReservedStream1 = 2,
ThreadListStream = 3,
ModuleListStream = 4,
MemoryListStream = 5,
ExceptionStream = 6,
SystemInfoStream = 7,
ThreadExListStream = 8,
Memory64ListStream = 9,
CommentStreamA = 10,
CommentStreamW = 11,
HandleDataStream = 12,
FunctionTableStream = 13,
UnloadedModuleListStream = 14,
MiscInfoStream = 15,
MemoryInfoListStream = 16,
ThreadInfoListStream = 17,
HandleOperationListStream = 18,
TokenStream = 19,
JavaScriptDataStream = 20,
SystemMemoryInfoStream = 21,
ProcessVmCountersStream = 22,
IptTraceStream = 23,
ThreadNamesStream = 24,
ceStreamNull = 0x8000,
ceStreamSystemInfo = 0x8001,
ceStreamException = 0x8002,
ceStreamModuleList = 0x8003,
ceStreamProcessList = 0x8004,
ceStreamThreadList = 0x8005,
ceStreamThreadContextList = 0x8006,
ceStreamThreadCallStackList = 0x8007,
ceStreamMemoryVirtualList = 0x8008,
ceStreamMemoryPhysicalList = 0x8009,
ceStreamBucketParameters = 0x800A,
ceStreamProcessModuleMap = 0x800B,
ceStreamDiagnosisList = 0x800C,
LastReservedStream = 0xFFFF
UnusedStream = 0,
ReservedStream0 = 1,
ReservedStream1 = 2,
ThreadListStream = 3,
ModuleListStream = 4,
MemoryListStream = 5,
ExceptionStream = 6,
SystemInfoStream = 7,
ThreadExListStream = 8,
Memory64ListStream = 9,
CommentStreamA = 10,
CommentStreamW = 11,
HandleDataStream = 12,
FunctionTableStream = 13,
UnloadedModuleListStream = 14,
MiscInfoStream = 15,
MemoryInfoListStream = 16,
ThreadInfoListStream = 17,
HandleOperationListStream = 18,
TokenStream = 19,
JavaScriptDataStream = 20,
SystemMemoryInfoStream = 21,
ProcessVmCountersStream = 22,
IptTraceStream = 23,
ThreadNamesStream = 24,
ceStreamNull = 0x8000,
ceStreamSystemInfo = 0x8001,
ceStreamException = 0x8002,
ceStreamModuleList = 0x8003,
ceStreamProcessList = 0x8004,
ceStreamThreadList = 0x8005,
ceStreamThreadContextList = 0x8006,
ceStreamThreadCallStackList = 0x8007,
ceStreamMemoryVirtualList = 0x8008,
ceStreamMemoryPhysicalList = 0x8009,
ceStreamBucketParameters = 0x800A,
ceStreamProcessModuleMap = 0x800B,
ceStreamDiagnosisList = 0x800C,
LastReservedStream = 0xFFFF
};
struct MINIDUMP_LOCATION_DESCRIPTOR {
type::Size32 DataSize;
RVA Rva;
type::Size32 DataSize;
RVA Rva;
};
struct MINIDUMP_MEMORY_DESCRIPTOR {
@@ -70,24 +70,24 @@ struct MINIDUMP_THREAD {
};
struct MINIDUMP_THREAD_LIST {
ULONG32 NumberOfThreads;
MINIDUMP_THREAD Threads[NumberOfThreads];
ULONG32 NumberOfThreads;
MINIDUMP_THREAD Threads[NumberOfThreads];
};
struct VS_FIXEDFILEINFO {
DWORD dwSignature;
DWORD dwStrucVersion;
DWORD dwFileVersionMS;
DWORD dwFileVersionLS;
DWORD dwProductVersionMS;
DWORD dwProductVersionLS;
DWORD dwFileFlagsMask;
DWORD dwFileFlags;
DWORD dwFileOS;
DWORD dwFileType;
DWORD dwFileSubtype;
DWORD dwFileDateMS;
DWORD dwFileDateLS;
DWORD dwSignature;
DWORD dwStrucVersion;
DWORD dwFileVersionMS;
DWORD dwFileVersionLS;
DWORD dwProductVersionMS;
DWORD dwProductVersionLS;
DWORD dwFileFlagsMask;
DWORD dwFileFlags;
DWORD dwFileOS;
DWORD dwFileType;
DWORD dwFileSubtype;
DWORD dwFileDateMS;
DWORD dwFileDateLS;
};
struct MINIDUMP_MODULE {
@@ -101,12 +101,12 @@ struct MINIDUMP_MODULE {
MINIDUMP_LOCATION_DESCRIPTOR MiscRecord;
ULONG64 Reserved0;
ULONG64 Reserved1;
char16 ModuleName[] @ ModuleNameRva + 4 [[hidden]];
} [[format("format_module")]];
fn format_module(ref MINIDUMP_MODULE module) {
return module.ModuleName;
return module.ModuleName;
};
struct MINIDUMP_MODULE_LIST {
@@ -137,10 +137,10 @@ struct MINIDUMP_EXCEPTION_STREAM {
};
struct CPU_INFORMATION {
ULONG32 VendorId[3];
ULONG32 VersionInformation;
ULONG32 FeatureInformation;
ULONG32 AMDExtendedCpuFeatures;
ULONG32 VendorId[3];
ULONG32 VersionInformation;
ULONG32 FeatureInformation;
ULONG32 AMDExtendedCpuFeatures;
};
struct MINIDUMP_SYSTEM_INFO {
@@ -235,7 +235,7 @@ struct MINIDUMP_FUNCTION_TABLE_STREAM {
type::Size32 SizeOfFunctionEntry;
ULONG32 NumberOfDescriptors;
ULONG32 SizeOfAlignPad;
MINIDUMP_FUNCTION_TABLE_DESCRIPTOR FunctionDescriptors[NumberOfDescriptors];
};
@@ -245,19 +245,19 @@ struct MINIDUMP_UNLOADED_MODULE {
ULONG32 CheckSum;
ULONG32 TimeDateStamp;
RVA ModuleNameRva;
char16 ModuleName[] @ ModuleNameRva + 4 [[hidden]];
} [[format("format_unloaded_module")]];
fn format_unloaded_module(ref MINIDUMP_UNLOADED_MODULE module) {
return module.ModuleName;
return module.ModuleName;
};
struct MINIDUMP_UNLOADED_MODULE_LIST {
ULONG32 SizeOfHeader;
ULONG32 SizeOfEntry;
ULONG32 NumberOfEntries;
if (SizeOfHeader > 12)
padding[header.SizeOfHeader - 12];
@@ -271,7 +271,7 @@ struct MINIDUMP_MISC_INFO {
ULONG32 ProcessCreateTime;
ULONG32 ProcessUserTime;
ULONG32 ProcessKernelTime;
if (SizeOfInfo > 24) {
ULONG32 ProcessorMaxMhz;
ULONG32 ProcessorCurrentMhz;
@@ -297,7 +297,7 @@ struct MINIDUMP_MEMORY_INFO_LIST {
ULONG SizeOfHeader;
ULONG SizeOfEntry;
ULONG64 NumberOfEntries;
if (SizeOfHeader > 16)
padding[SizeOfHeader - 16];
@@ -321,7 +321,7 @@ struct MINIDUMP_THREAD_INFO_LIST {
ULONG SizeOfHeader;
ULONG SizeOfEntry;
ULONG NumberOfEntries;
if (SizeOfHeader > 12)
padding[SizeOfHeader - 12];
@@ -336,88 +336,88 @@ struct MINIDUMP_HANDLE_OPERATION_LIST {
};
struct MINIDUMP_DIRECTORY {
MINIDUMP_STREAM_TYPE StreamType;
MINIDUMP_LOCATION_DESCRIPTOR Location;
if (StreamType == MINIDUMP_STREAM_TYPE::ThreadListStream)
MINIDUMP_THREAD_LIST ThreadList @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::ModuleListStream)
MINIDUMP_MODULE_LIST ModuleList @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::MemoryListStream)
MINIDUMP_MEMORY_LIST MemoryList @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::ExceptionStream)
MINIDUMP_EXCEPTION_STREAM ExceptionInfo @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::SystemInfoStream)
MINIDUMP_SYSTEM_INFO SystemInfo @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::ThreadExListStream)
MINIDUMP_THREAD_EX_LIST ThreadExList @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::Memory64ListStream)
MINIDUMP_MEMORY64_LIST Mem64List @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::CommentStreamA)
char Comment[] @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::CommentStreamW)
char16 Comment[] @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::HandleDataStream)
MINIDUMP_HANDLE_DATA_STREAM HandleData @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::FunctionTableStream)
MINIDUMP_FUNCTION_TABLE_STREAM FunctionTable @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::UnloadedModuleListStream)
MINIDUMP_UNLOADED_MODULE_LIST UnloadModuleList @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::MiscInfoStream)
MINIDUMP_MISC_INFO MiscInfo @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::MemoryInfoListStream)
MINIDUMP_MEMORY_INFO_LIST MemInfoList @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::ThreadInfoListStream)
MINIDUMP_THREAD_INFO_LIST ThreadInfoList @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::HandleOperationListStream)
MINIDUMP_HANDLE_OPERATION_LIST HandleOperList @ Location.Rva;
MINIDUMP_STREAM_TYPE StreamType;
MINIDUMP_LOCATION_DESCRIPTOR Location;
if (StreamType == MINIDUMP_STREAM_TYPE::ThreadListStream)
MINIDUMP_THREAD_LIST ThreadList @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::ModuleListStream)
MINIDUMP_MODULE_LIST ModuleList @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::MemoryListStream)
MINIDUMP_MEMORY_LIST MemoryList @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::ExceptionStream)
MINIDUMP_EXCEPTION_STREAM ExceptionInfo @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::SystemInfoStream)
MINIDUMP_SYSTEM_INFO SystemInfo @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::ThreadExListStream)
MINIDUMP_THREAD_EX_LIST ThreadExList @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::Memory64ListStream)
MINIDUMP_MEMORY64_LIST Mem64List @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::CommentStreamA)
char Comment[] @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::CommentStreamW)
char16 Comment[] @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::HandleDataStream)
MINIDUMP_HANDLE_DATA_STREAM HandleData @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::FunctionTableStream)
MINIDUMP_FUNCTION_TABLE_STREAM FunctionTable @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::UnloadedModuleListStream)
MINIDUMP_UNLOADED_MODULE_LIST UnloadModuleList @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::MiscInfoStream)
MINIDUMP_MISC_INFO MiscInfo @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::MemoryInfoListStream)
MINIDUMP_MEMORY_INFO_LIST MemInfoList @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::ThreadInfoListStream)
MINIDUMP_THREAD_INFO_LIST ThreadInfoList @ Location.Rva;
else if (StreamType == MINIDUMP_STREAM_TYPE::HandleOperationListStream)
MINIDUMP_HANDLE_OPERATION_LIST HandleOperList @ Location.Rva;
};
bitfield MINIDUMP_TYPE {
MiniDumpWithDataSegs : 1;
MiniDumpWithFullMemory : 1;
MiniDumpWithHandleData : 1;
MiniDumpFilterMemory : 1;
MiniDumpScanMemory : 1;
MiniDumpWithUnloadedModules : 1;
MiniDumpWithIndirectlyReferencedMemory : 1;
MiniDumpFilterModulePaths : 1;
MiniDumpWithProcessThreadData : 1;
MiniDumpWithPrivateReadWriteMemory : 1;
MiniDumpWithoutOptionalData : 1;
MiniDumpWithFullMemoryInfo : 1;
MiniDumpWithThreadInfo : 1;
MiniDumpWithCodeSegs : 1;
MiniDumpWithoutAuxiliaryState : 1;
MiniDumpWithFullAuxiliaryState : 1;
MiniDumpWithPrivateWriteCopyMemory : 1;
MiniDumpIgnoreInaccessibleMemory : 1;
MiniDumpWithTokenInformation : 1;
MiniDumpWithModuleHeaders : 1;
MiniDumpFilterTriage : 1;
MiniDumpWithAvxXStateContext : 1;
MiniDumpWithIptTrace : 1;
MiniDumpScanInaccessiblePartialPages : 1;
padding : 40;
MiniDumpWithDataSegs : 1;
MiniDumpWithFullMemory : 1;
MiniDumpWithHandleData : 1;
MiniDumpFilterMemory : 1;
MiniDumpScanMemory : 1;
MiniDumpWithUnloadedModules : 1;
MiniDumpWithIndirectlyReferencedMemory : 1;
MiniDumpFilterModulePaths : 1;
MiniDumpWithProcessThreadData : 1;
MiniDumpWithPrivateReadWriteMemory : 1;
MiniDumpWithoutOptionalData : 1;
MiniDumpWithFullMemoryInfo : 1;
MiniDumpWithThreadInfo : 1;
MiniDumpWithCodeSegs : 1;
MiniDumpWithoutAuxiliaryState : 1;
MiniDumpWithFullAuxiliaryState : 1;
MiniDumpWithPrivateWriteCopyMemory : 1;
MiniDumpIgnoreInaccessibleMemory : 1;
MiniDumpWithTokenInformation : 1;
MiniDumpWithModuleHeaders : 1;
MiniDumpFilterTriage : 1;
MiniDumpWithAvxXStateContext : 1;
MiniDumpWithIptTrace : 1;
MiniDumpScanInaccessiblePartialPages : 1;
padding : 40;
} [[right_to_left]];
struct MINIDUMP_HEADER {
char Signature[4];
ULONG32 Version;
ULONG32 NumberOfStreams;
RVA StreamDirectoryRva;
ULONG32 Checksum;
type::time32_t TimeDateStamp;
MINIDUMP_TYPE Flags;
char Signature[4];
ULONG32 Version;
ULONG32 NumberOfStreams;
RVA StreamDirectoryRva;
ULONG32 Checksum;
type::time32_t TimeDateStamp;
MINIDUMP_TYPE Flags;
};
struct MINIDUMP {
MINIDUMP_HEADER Header;
MINIDUMP_DIRECTORY Streams[Header.NumberOfStreams] [[format_entries("format_stream")]];
MINIDUMP_HEADER Header;
MINIDUMP_DIRECTORY Streams[Header.NumberOfStreams] [[format_entries("format_stream")]];
};
fn format_stream(ref MINIDUMP_DIRECTORY stream) {
return stream.StreamType;
return stream.StreamType;
};
MINIDUMP MiniDump @ 0x00;
MINIDUMP MiniDump @ 0x00;

File diff suppressed because it is too large Load Diff

View File

@@ -1,36 +1,117 @@
#pragma MIME image/png
#pragma endian big
struct header_t
{
struct header_t {
u8 highBitByte;
char signature[3];
char dosLineEnding[2];
char dosEOF;
char unixLineEnding;
char signature[3];
char dosLineEnding[2];
char dosEOF;
char unixLineEnding;
};
struct ihdr_t
{
struct actl_t {
u32 frames [[comment("Total № of frames in animation")]];
u32 plays [[comment("№ of times animation will loop")]];
} [[comment("Animation control chunk"), name("acTL")]];
enum ColorType: u8 {
Grayscale = 0x0,
RGBTriple = 0x2,
Palette,
GrayscaleAlpha,
RGBA = 0x6
};
enum Interlacing: u8 {
None,
Adam7
};
struct ihdr_t {
u32 width [[comment("Image width")]];
u32 height [[comment("Image height")]];
u8 bit_depth;
u8 color_type [[comment("PNG Image Type\n0: greyscale\n2: truecolour\n3: indexed-color\n4: greyscale with alpha\n6: truecolour with alpha")]];
u8 compression_method;
u8 filter_method;
u8 interlace_method [[comment("values 0 \"no interlace\" or 1 \"Adam7 interlace\"")]];
ColorType color_type [[comment("PNG Image Type")]];
u8 compression_method [[comment("Only 0x0 = zlib supported by most")]];
u8 filter_method [[comment("Only 0x0 = adaptive supported by most")]];
Interlacing interlacing;
};
struct palette_entry_t {
u8 r;
u8 g;
u8 b;
enum sRGB: u8 {
Perceptual = 0x0,
RelativeColorimetric,
Saturation,
AbsoluteColorimetric
};
enum Unit: u8 {
Unknown,
Meter
};
struct phys_t {
u32 ppu_x [[comment("Pixels per unit, X axis")]];
u32 ppu_y [[comment("Pixels per unit, Y axis")]];
u8 unit [[comment("Unit Specifier\n0: unit is unknown\n1: unit is the metre")]];
Unit unit;
};
enum BlendOp: u8 {
Source = 0x0,
Over
};
enum DisposeOp: u8 {
None = 0x0,
Background,
Previous
};
struct fctl_t {
u32 sequence_no [[comment("Sequence №")]];
u32 width [[comment("Frame width")]];
u32 height;
u32 xoff;
u32 yoff;
u16 delay_num;
u16 delay_den;
DisposeOp dispose_op;
BlendOp blend_op;
};
struct fdat_t {
u32 sequence_no;
};
fn text_len() {
u64 len = parent.parent.length - ($ - addressof(parent.keyword));
return len;
};
enum BlendOp: u8 {
Source = 0x0,
Over
};
enum DisposeOp: u8 {
None = 0x0,
Background,
Previous
};
struct fctl_t {
u32 sequence_no [[comment("Sequence №")]];
u32 width [[comment("Frame width")]];
u32 height [[comment("Frame height")]];
u32 xoff;
u32 yoff;
u16 delay_num [[comment("Frame delay fraction numerator")]];
u16 delay_den [[comment("Frame delay fraction denominator")]];
DisposeOp dispose_op;
BlendOp blend_op;
};
struct fdat_t {
u32 sequence_no;
};
struct itxt_t {
@@ -39,48 +120,92 @@ struct itxt_t {
u8 compression_method;
char language_tag[];
char translated_keyword[];
char text[parent.length - ($ - addressof(keyword))];
char text[text_len()];
};
struct ztxt_t {
char keyword[];
u8 compression_method;
char text[text_len()];
};
struct text_t {
char keyword[];
char text[text_len()];
};
struct iccp_t {
char profile [];
u8 compression_method;
u8 compressed_profile[parent.length - ($ - addressof(profile))];
char keyword[];
u8 compression_method;
u8 compressed_profile[text_len()];
};
struct palette_entry_t {
u24 color;
} [[inline]];
struct chunk_t {
u32 length [[color("17BECF")]];
char type[4];
char name[4];
#define IHDR_k "IHDR"
#define PLTE_k "PLTE"
#define sRGB_k "sRGB"
#define pHYs_k "pHYs"
#define iTXt_k "iTXt"
#define tEXt_k "tEXt"
#define zTXt_k "zTXt"
#define IDAT_k "IDAT"
#define IEND_k "IEND"
#define gAMA_k "gAMA"
#define iCCP_k "iCCP"
#define acTL_k "acTL"
#define fdAT_k "fdAT"
#define fcTL_k "fcTL"
if (type == IHDR_k) {
if (name == IHDR_k) {
ihdr_t ihdr [[comment("Image Header chunk"), name("IHDR")]];
} else if (type == PLTE_k) {
} else if (name == PLTE_k) {
palette_entry_t entries[length / 3];
} else if (type == pHYs_k) {
} else if (name == sRGB_k) {
sRGB srgb;
} else if (name == pHYs_k) {
phys_t phys;
} else if (type == acTL_k) {
actl_t actl [[comment("Animation control chunk")]];
} else if (type == fcTL_k) {
fctl_t fctl [[comment("Frame control chunk")]];
} else if (type == iTXt_k) {
itxt_t text;
} else if (type == gAMA_k) {
u32 gamma [[name("image gamma"), comment("4 byte unsigned integer representing gamma times 100000")]];
} else if (type == iCCP_k) {
iccp_t iccp;
} else if (name == tEXt_k) {
text_t text;
} else if (name == zTXt_k) {
ztxt_t text;
} else if (name == iCCP_k) {
iccp_t iccp;
} else if (name == fdAT_k) {
fdat_t fdat [[comment("Frame data chunk")]];
u8 data[length-sizeof(u32)];
} else {
u8 data[length];
}
u32 crc;
} [[format("chunkValueName")]];
fn chunkValueName(ref chunk_t chunk) {
return chunk.name;
};
struct chunk_set {
chunk_t chunks[while(builtin::std::mem::read_string($ + 4, 4) != "IEND")] [[inline]];
} [[inline]];
header_t header @ 0x00 [[comment("PNG file signature"), name("Signature")]];
chunk_t ihdr_chunk @ 0x08 [[comment("PNG Header chunk"), name("IHDR")]];
chunk_t chunk_set[while(builtin::std::mem::read_string($ + 4, 4) != "IEND")] @ $ [[comment("PNG file chunks"), name("Chunks"), inline]];
chunk_t iend_chunk @ $ [[name("IEND"), comment("Image End Chunk")]];
chunk_set set @ $ [[comment("PNG Chunks"), name("Chunks"), inline]];
chunk_t iend_chunk @ $ [[comment("Image End Chunk"), name("IEND")]];

270
patterns/usb.hexpat Normal file
View File

@@ -0,0 +1,270 @@
#include <std/io.pat>
#include <std/mem.pat>
#include <std/string.pat>
enum DescriptorType : u8 {
DeviceDescriptor = 0x01,
ConfigDescriptor = 0x02,
StringDescriptor = 0x03,
InterfaceDescriptor = 0x04,
EndpointDescriptor = 0x05,
DeviceQualifierDescriptor = 0x06,
OtherSpeedConfigurationDescriptor = 0x07,
InterfacePowerDescriptor = 0x08,
OTGDescriptor = 0x09,
DebugDescriptor = 0x0A,
InterfaceAssociationDescriptor = 0x0B,
HIDDescriptor = 0x21,
ReportDescriptor = 0x22,
PhysicalDescriptor = 0x23
};
enum InterfaceClass : u8 {
UseClassInformationInInterfaceDescriptors = 0x00,
Audio = 0x01,
CommunicationAndCDCControl = 0x02,
HID = 0x03,
Physical = 0x05,
Image = 0x06,
Printer = 0x07,
MassStorage = 0x08,
Hub = 0x09,
CDCData = 0x0A,
SmartCard = 0x0B,
ContentSecurity = 0x0C,
Video = 0x0E,
PersonalHealthcare = 0x0F,
AudioVideoDevice = 0x10,
BillboardDevice = 0x11,
USBTypeCBridge = 0x12,
I3CDevice = 0x3C,
DiagnosticDevice = 0xDC,
WirelessController = 0xE0,
Miscellaneous = 0xEF,
ApplicationSpecific = 0xFE,
VendorSpecific = 0xFF
};
enum CountryCode : u8 {
NotSupported = 0,
Arabic = 1,
Belgian = 2,
CanadianBilingual = 3,
CanadianFrench = 4,
CzechRepublic = 5,
Danish = 6,
Finnish = 7,
French = 8,
German = 9,
Greek = 10,
Hebrew = 11,
Hungary = 12,
International = 13,
Italian = 14,
JapanKatakana = 15,
Korean = 16,
LatinAmerican = 17,
Dutch = 18,
Norwegian = 19,
PersianFarsi = 20,
Polish = 21,
Portuguese = 22,
Russian = 23,
Slovakian = 24,
Spanish = 25,
Swedish = 26,
SwissFrench = 27,
SwissGerman = 28,
Switzerland = 29,
Taiwan = 30,
TurkishQ = 31,
EnglishUK = 32,
EnglishUS = 33,
Yugoslavian = 34,
TurkishF = 35,
Reserved = 36 ... 255
};
enum HubInterfaceSubClass : u8 {
Hub = 0x00
};
enum AudioVideoDeviceSubClass : u8 {
AVControlInterface = 0x01,
AVDataVideoStreamingInterface = 0x02,
AVDataAudioStreamingInterface = 0x03
};
enum HubInterfaceProtocol : u8 {
FullSpeedHub = 0x00,
HiSpeedHubWithSingleTT = 0x01,
HiSpeedHubWithMultipleTTs = 0x02
};
struct Ampere {
u8 amps;
} [[sealed, format("format_ampere")]];
fn format_ampere(Ampere ampere) {
return std::format("{} mA", ampere.amps * 2);
};
bitfield ConfigAttributes {
padding : 1;
SelfPowered : 1;
RemoteWakeup : 1;
padding : 5;
} [[left_to_right]];
struct BCD<auto Size> {
u8 bytes[Size];
} [[sealed, format("format_bcd")]];
fn format_bcd(ref auto bcd) {
str result;
for (s8 i = sizeof(bcd.bytes) - 1, i >= 0, i -= 1)
result += std::format("{:X}.", bcd.bytes[i]);
return std::string::substr(result, 0, std::string::length(result) - 1);
};
struct DeviceDescriptor {
BCD<2> bcdUSB;
InterfaceClass bDeviceClass;
if (bDeviceClass == InterfaceClass::Hub) {
HubInterfaceSubClass bDeviceSubClass;
if (bDeviceSubClass == HubInterfaceSubClass::Hub)
HubInterfaceProtocol bDeviceSubClass;
else
u8 bDeviceSubClass;
} else if (bDeviceClass == InterfaceClass::AudioVideoDevice) {
AudioVideoDeviceSubClass bDeviceSubClass;
u8 bDeviceSubClass;
} else {
u8 bDeviceSubClass;
u8 bDeviceSubClass;
}
};
struct ConfigDescriptor {
u16 wTotalLength;
u8 bNumInterfaces;
u8 bConfigurationValue;
u8 iConfiguration;
ConfigAttributes bmAttributes;
Ampere bMaxPower;
};
struct StringDescriptor {
char bString[parent.bLength - 2];
};
struct InterfaceDescriptor {
u8 bInterfaceNumber;
u8 bAlternateSetting;
u8 bNumEndpoints;
InterfaceClass bInterfaceClass;
if (bInterfaceClass == InterfaceClass::Hub) {
HubInterfaceSubClass bInterfaceSubClass;
if (bInterfaceSubClass == HubInterfaceSubClass::Hub)
HubInterfaceProtocol bInterfaceProtocol;
else
u8 bInterfaceProtocol;
} else if (bInterfaceClass == InterfaceClass::AudioVideoDevice) {
AudioVideoDeviceSubClass bInterfaceSubClass;
u8 bInterfaceProtocol;
} else {
u8 bInterfaceSubClass;
u8 bInterfaceProtocol;
}
u8 iInterface;
};
enum EndpointDirection : u8 {
OUT = 0,
IN = 1
};
fn format_direction(u8 value) {
EndpointDirection direction;
direction = value;
return direction;
};
bitfield EndpointAddress {
Direction : 1 [[format("format_direction")]];
padding : 3;
EndpointNumber : 4;
} [[left_to_right]];
bitfield EndpointAttributes {
TransferType : 2;
SynchronizationType : 2;
UsageType : 2;
} [[right_to_left]];
struct EndpointDescriptor {
EndpointAddress bEndPointAddress;
EndpointAttributes bmAttributes;
u16 wMaxPacketSize;
u8 bInterval;
};
struct OtherSpeedConfigurationDescriptor {
ConfigDescriptor content [[inline]];
};
struct DeviceQualifierDescriptor {
DeviceDescriptor deviceDescriptor [[inline]];
u8 bMaxPacketSize0;
u8 bNumConfigurations;
padding[1];
};
bitfield OTGAttributes {
SRPSupport : 1;
HNPSupport : 1;
} [[right_to_left]];
struct OTGDescriptor {
OTGAttributes bmAttributes;
};
struct HIDDescriptor {
BCD<2> bcdVersion;
CountryCode bCountryCode;
u8 bNumDescriptors;
DescriptorType bDescriptorType;
u16 wDescriptorLength;
};
struct USBDescriptor {
u8 bLength;
DescriptorType bDescriptorType;
if (bDescriptorType == DescriptorType::DeviceDescriptor)
DeviceDescriptor deviceDescriptor [[inline]];
else if (bDescriptorType == DescriptorType::ConfigDescriptor)
ConfigDescriptor configDescriptor [[inline]];
else if (bDescriptorType == DescriptorType::StringDescriptor)
StringDescriptor stringDescriptor [[inline]];
else if (bDescriptorType == DescriptorType::InterfaceDescriptor)
InterfaceDescriptor interfaceDescriptor [[inline]];
else if (bDescriptorType == DescriptorType::EndpointDescriptor)
EndpointDescriptor endpointDescriptor [[inline]];
else if (bDescriptorType == DescriptorType::OtherSpeedConfigurationDescriptor)
OtherSpeedConfigurationDescriptor otherSpeedConfigurationDescriptor [[inline]];
else if (bDescriptorType == DescriptorType::DeviceQualifierDescriptor)
DeviceQualifierDescriptor deviceQualifierDescriptor [[inline]];
else if (bDescriptorType == DescriptorType::OTGDescriptor)
OTGDescriptor otgDescriptor [[inline]];
else if (bDescriptorType == DescriptorType::HIDDescriptor)
HIDDescriptor hidDescriptor [[inline]];
padding[bLength - ($ - addressof(this))];
};
USBDescriptor descriptors[while(!std::mem::eof())] @ 0x00;

Binary file not shown.

Binary file not shown.