From 467ede917a8c4959fde9837ae325da9d2b9fbd15 Mon Sep 17 00:00:00 2001 From: Tobi Lehman Date: Thu, 30 Jun 2022 13:56:53 -0700 Subject: [PATCH] Add MBR format --- README.md | 1 + doc/dev.md | 4 +- doc/formats.md | 10 + doc/formats.svg | 1490 ++++++++++++++++--------------- format/all/all.go | 1 + format/all/help.fqtest | 11 + format/format.go | 1 + format/mbr/mbr.go | 72 ++ format/mbr/mbr.jq | 7 + format/mbr/partition_types.go | 151 ++++ format/mbr/testdata/mbr.bin | Bin 0 -> 512 bytes format/mbr/testdata/mbr.fqtest | 42 + pkg/interp/testdata/args.fqtest | 1 + 13 files changed, 1047 insertions(+), 744 deletions(-) create mode 100644 format/mbr/mbr.go create mode 100644 format/mbr/mbr.jq create mode 100644 format/mbr/partition_types.go create mode 100644 format/mbr/testdata/mbr.bin create mode 100644 format/mbr/testdata/mbr.fqtest diff --git a/README.md b/README.md index 3721ccadc..cfc580db9 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,7 @@ jpeg, json, [macho](doc/formats.md#macho), [matroska](doc/formats.md#matroska), +[mbr](doc/formats.md#mbr), [mp3](doc/formats.md#mp3), mp3_frame, [mp4](doc/formats.md#mp4), diff --git a/doc/dev.md b/doc/dev.md index 8813f06e3..6d7eb7187 100644 --- a/doc/dev.md +++ b/doc/dev.md @@ -5,7 +5,7 @@ - Create a directory `format/` - Copy some similar decoder, `format/format/bson.go` is quite small, to `format//.go` - Cleanup and fill in the register struct, rename `format.BSON` and add it -to `format/fromat.go` and don't forget to change the string constant. +to `format/format.go` and don't forget to change the string constant. - Add an import to `format/all/all.go` ### Some general tips @@ -38,7 +38,7 @@ Flags can be struct with bit-fields. `?(?>|Fn>)(...[, scalar.Mapper...]) ` -- If starts with `Field` a field will be added and first argument will be name of field. If not it will just read. +- If it starts with `Field` a field will be added and first argument will be name of field. If not it will just read. - `?>|Fn>` a reader or a reader function - `?>` Read bits using some decoder. - `U16` unsigned 16 bit integer. diff --git a/doc/formats.md b/doc/formats.md index 0dbb1b0eb..4adce443d 100644 --- a/doc/formats.md +++ b/doc/formats.md @@ -59,6 +59,7 @@ |`json` |JSON || |[`macho`](#macho) |Mach-O macOS executable || |[`matroska`](#matroska) |Matroska file |`aac_frame` `av1_ccr` `av1_frame` `avc_au` `avc_dcr` `flac_frame` `flac_metadatablocks` `hevc_au` `hevc_dcr` `image` `mp3_frame` `mpeg_asc` `mpeg_pes_packet` `mpeg_spu` `opus_packet` `vorbis_packet` `vp8_frame` `vp9_cfm` `vp9_frame`| +|[`mbr`](#mbr) |Master Boot Record || |[`mp3`](#mp3) |MP3 file |`id3v2` `id3v1` `id3v11` `apev2` `mp3_frame`| |`mp3_frame` |MPEG audio layer 3 frame |`xing`| |[`mp4`](#mp4) |ISOBMFF MPEG-4 part 12 and similar |`aac_frame` `av1_ccr` `av1_frame` `flac_frame` `flac_metadatablocks` `id3v2` `image` `jpeg` `mp3_frame` `avc_au` `avc_dcr` `mpeg_es` `hevc_au` `hevc_dcr` `mpeg_pes_packet` `opus_packet` `protobuf_widevine` `pssh_playready` `vorbis_packet` `vp9_frame` `vpx_ccr` `icc_profile`| @@ -352,6 +353,15 @@ Return `matroska_path` string for a box decode value - https://www.matroska.org/technical/codec_specs.html - https://wiki.xiph.org/MatroskaOpus +### mbr + +Supports decoding Master Boot Record data + +#### References and links + +- https://thestarman.pcministry.com/asm/mbr/PartTables.htm#mbr +- https://en.wikipedia.org/wiki/Master_boot_record + ### mp3 #### Options diff --git a/doc/formats.svg b/doc/formats.svg index 8103d5139..e4d0200b0 100644 --- a/doc/formats.svg +++ b/doc/formats.svg @@ -4,1766 +4,1772 @@ - - + + formats - + adts - -adts - -adts_frame + +adts + +adts_frame adts_frame - -adts_frame - -aac_frame + +adts_frame + +aac_frame adts:e->adts_frame:n - - + + aac_frame - -aac_frame + +aac_frame adts_frame:e->aac_frame:n - - + + apev2 - -apev2 - -image + +apev2 + +image image - -image + +image apev2:e->image:n - - + + jpeg - -jpeg - -exif - -icc_profile + +jpeg + +exif + +icc_profile image->jpeg:n - - + + mp4 - -mp4 - -aac_frame - -av1_ccr - -av1_frame - -flac_frame - -flac_metadatablocks - -id3v2 - -image - -jpeg - -mp3_frame - -avc_au - -avc_dcr - -mpeg_es - -hevc_au - -hevc_dcr - -mpeg_pes_packet - -opus_packet - -protobuf_widevine - -pssh_playready - -vorbis_packet - -vp9_frame - -vpx_ccr - -icc_profile + +mp4 + +aac_frame + +av1_ccr + +av1_frame + +flac_frame + +flac_metadatablocks + +id3v2 + +image + +jpeg + +mp3_frame + +avc_au + +avc_dcr + +mpeg_es + +hevc_au + +hevc_dcr + +mpeg_pes_packet + +opus_packet + +protobuf_widevine + +pssh_playready + +vorbis_packet + +vp9_frame + +vpx_ccr + +icc_profile image->mp4:n - - + + png - -png - -icc_profile - -exif + +png + +icc_profile + +exif image->png:n - - + + tiff - -tiff - -icc_profile + +tiff + +icc_profile image->tiff:n - - + + webp - -webp - -vp8_frame + +webp + +vp8_frame image->webp:n - - + + gif - -gif + +gif image->gif:n - - + + ar - -ar - -probe + +ar + +probe probe - -probe + +probe ar:e->probe:n - - + + probe->adts:n - - + + probe->ar:n - - + + bzip2 - -bzip2 - -probe + +bzip2 + +probe probe->bzip2:n - - + + flac - -flac - -flac_metadatablocks - -flac_frame + +flac + +flac_metadatablocks + +flac_frame probe->flac:n - - + + gzip - -gzip - -probe + +gzip + +probe probe->gzip:n - - + + probe->jpeg:n - - + + matroska - -matroska - -aac_frame - -av1_ccr - -av1_frame - -avc_au - -avc_dcr - -flac_frame - -flac_metadatablocks - -hevc_au - -hevc_dcr - -image - -mp3_frame - -mpeg_asc - -mpeg_pes_packet - -mpeg_spu - -opus_packet - -vorbis_packet - -vp8_frame - -vp9_cfm - -vp9_frame + +matroska + +aac_frame + +av1_ccr + +av1_frame + +avc_au + +avc_dcr + +flac_frame + +flac_metadatablocks + +hevc_au + +hevc_dcr + +image + +mp3_frame + +mpeg_asc + +mpeg_pes_packet + +mpeg_spu + +opus_packet + +vorbis_packet + +vp8_frame + +vp9_cfm + +vp9_frame probe->matroska:n - - + + mp3 - -mp3 - -id3v2 - -id3v1 - -id3v11 - -apev2 - -mp3_frame + +mp3 + +id3v2 + +id3v1 + +id3v11 + +apev2 + +mp3_frame probe->mp3:n - - + + probe->mp4:n - - + + ogg - -ogg - -ogg_page - -vorbis_packet - -opus_packet - -flac_metadatablock - -flac_frame + +ogg + +ogg_page + +vorbis_packet + +opus_packet + +flac_metadatablock + +flac_frame probe->ogg:n - - + + pcap - -pcap - -link_frame - -tcp_stream - -ipv4_packet + +pcap + +link_frame + +tcp_stream + +ipv4_packet probe->pcap:n - - + + pcapng - -pcapng - -link_frame - -tcp_stream - -ipv4_packet + +pcapng + +link_frame + +tcp_stream + +ipv4_packet probe->pcapng:n - - + + probe->png:n - - + + tar - -tar - -probe + +tar + +probe probe->tar:n - - + + probe->tiff:n - - + + wav - -wav - -id3v2 - -id3v1 - -id3v11 + +wav + +id3v2 + +id3v1 + +id3v11 probe->wav:n - - + + probe->webp:n - - + + zip - -zip - -probe + +zip + +probe probe->zip:n - - + + avro_ocf - -avro_ocf + +avro_ocf probe->avro_ocf:n - - + + elf - -elf + +elf probe->elf:n - - + + probe->gif:n - - + + json - -json + +json probe->json:n - - + + macho - -macho + +macho probe->macho:n - - + + mpeg_ts - -mpeg_ts + +mpeg_ts probe->mpeg_ts:n - - + + av1_frame - -av1_frame - -av1_obu + +av1_frame + +av1_obu av1_obu - -av1_obu + +av1_obu av1_frame:e->av1_obu:n - - + + avc_annexb - -avc_annexb - -avc_nalu + +avc_annexb + +avc_nalu avc_nalu - -avc_nalu - -avc_sps - -avc_pps - -avc_sei + +avc_nalu + +avc_sps + +avc_pps + +avc_sei avc_annexb:e->avc_nalu:n - - + + avc_sps - -avc_sps + +avc_sps avc_nalu:e->avc_sps:n - - + + avc_pps - -avc_pps + +avc_pps avc_nalu:e->avc_pps:n - - + + avc_sei - -avc_sei + +avc_sei avc_nalu:e->avc_sei:n - - + + avc_au - -avc_au - -avc_nalu + +avc_au + +avc_nalu avc_au:e->avc_nalu:n - - + + avc_dcr - -avc_dcr - -avc_nalu + +avc_dcr + +avc_nalu avc_dcr:e->avc_nalu:n - - + + bsd_loopback_frame - -bsd_loopback_frame - -inet_packet + +bsd_loopback_frame + +inet_packet inet_packet - -inet_packet + +inet_packet bsd_loopback_frame:e->inet_packet:n - - + + ipv4_packet - -ipv4_packet - -ip_packet + +ipv4_packet + +ip_packet inet_packet->ipv4_packet:n - - + + ipv6_packet - -ipv6_packet - -ip_packet + +ipv6_packet + +ip_packet inet_packet->ipv6_packet:n - - + + bzip2:e->probe:n - - + + ether8023_frame - -ether8023_frame - -inet_packet + +ether8023_frame + +inet_packet ether8023_frame:e->inet_packet:n - - + + flac_metadatablocks - -flac_metadatablocks - -flac_metadatablock + +flac_metadatablocks + +flac_metadatablock flac:e->flac_metadatablocks:n - - + + flac_frame - -flac_frame + +flac_frame flac:e->flac_frame:n - - + + flac_metadatablock - -flac_metadatablock - -flac_streaminfo - -flac_picture - -vorbis_comment + +flac_metadatablock + +flac_streaminfo + +flac_picture + +vorbis_comment flac_metadatablocks:e->flac_metadatablock:n - - + + flac_streaminfo - -flac_streaminfo + +flac_streaminfo flac_metadatablock:e->flac_streaminfo:n - - + + flac_picture - -flac_picture - -image + +flac_picture + +image flac_metadatablock:e->flac_picture:n - - + + vorbis_comment - -vorbis_comment - -flac_picture + +vorbis_comment + +flac_picture flac_metadatablock:e->vorbis_comment:n - - + + flac_picture:e->image:n - - + + vorbis_comment:e->flac_picture:n - - + + gzip:e->probe:n - - + + hevc_annexb - -hevc_annexb - -hevc_nalu + +hevc_annexb + +hevc_nalu hevc_nalu - -hevc_nalu - -hevc_vps - -hevc_pps - -hevc_sps + +hevc_nalu + +hevc_vps + +hevc_pps + +hevc_sps hevc_annexb:e->hevc_nalu:n - - + + hevc_vps - -hevc_vps + +hevc_vps hevc_nalu:e->hevc_vps:n - - + + hevc_pps - -hevc_pps + +hevc_pps hevc_nalu:e->hevc_pps:n - - + + hevc_sps - -hevc_sps + +hevc_sps hevc_nalu:e->hevc_sps:n - - + + hevc_au - -hevc_au - -hevc_nalu + +hevc_au + +hevc_nalu hevc_au:e->hevc_nalu:n - - + + hevc_dcr - -hevc_dcr - -hevc_nalu + +hevc_dcr + +hevc_nalu hevc_dcr:e->hevc_nalu:n - - + + id3v2 - -id3v2 - -image + +id3v2 + +image id3v2:e->image:n - - + + ip_packet - -ip_packet + +ip_packet ipv4_packet:e->ip_packet:n - - + + udp_datagram - -udp_datagram - -udp_payload + +udp_datagram + +udp_payload ip_packet->udp_datagram:n - - + + icmp - -icmp + +icmp ip_packet->icmp:n - - + + icmpv6 - -icmpv6 + +icmpv6 ip_packet->icmpv6:n - - + + tcp_segment - -tcp_segment + +tcp_segment ip_packet->tcp_segment:n - - + + ipv6_packet:e->ip_packet:n - - + + exif - -exif + +exif jpeg:e->exif:n - - + + icc_profile - -icc_profile + +icc_profile jpeg:e->icc_profile:n - - + + matroska:e->aac_frame:n - - + + matroska:e->image:n - - + + matroska:e->av1_frame:n - - + + matroska:e->avc_au:n - - + + matroska:e->avc_dcr:n - - + + matroska:e->flac_metadatablocks:n - - + + matroska:e->flac_frame:n - - + + matroska:e->hevc_au:n - - + + matroska:e->hevc_dcr:n - - + + av1_ccr - -av1_ccr + +av1_ccr matroska:e->av1_ccr:n - - + + mp3_frame - -mp3_frame - -xing + +mp3_frame + +xing matroska:e->mp3_frame:n - - + + mpeg_asc - -mpeg_asc + +mpeg_asc matroska:e->mpeg_asc:n - - + + mpeg_pes_packet - -mpeg_pes_packet + +mpeg_pes_packet matroska:e->mpeg_pes_packet:n - - + + mpeg_spu - -mpeg_spu + +mpeg_spu matroska:e->mpeg_spu:n - - + + opus_packet - -opus_packet - -vorbis_comment + +opus_packet + +vorbis_comment matroska:e->opus_packet:n - - + + vorbis_packet - -vorbis_packet - -vorbis_comment + +vorbis_packet + +vorbis_comment matroska:e->vorbis_packet:n - - + + vp8_frame - -vp8_frame + +vp8_frame matroska:e->vp8_frame:n - - + + vp9_cfm - -vp9_cfm + +vp9_cfm matroska:e->vp9_cfm:n - - + + vp9_frame - -vp9_frame + +vp9_frame matroska:e->vp9_frame:n - - + + xing - -xing + +xing mp3_frame:e->xing:n - - + + opus_packet:e->vorbis_comment:n - - + + vorbis_packet:e->vorbis_comment:n - - + + mp3:e->apev2:n - - + + mp3:e->id3v2:n - - + + mp3:e->mp3_frame:n - - + + id3v1 - -id3v1 + +id3v1 mp3:e->id3v1:n - - + + id3v11 - -id3v11 + +id3v11 mp3:e->id3v11:n - - + + mp4:e->aac_frame:n - - + + mp4:e->image:n - - + + mp4:e->av1_frame:n - - + + mp4:e->avc_au:n - - + + mp4:e->avc_dcr:n - - + + mp4:e->flac_metadatablocks:n - - + + mp4:e->flac_frame:n - - + + mp4:e->hevc_au:n - - + + mp4:e->hevc_dcr:n - - + + mp4:e->id3v2:n - - + + mp4:e->jpeg:n - - + + mp4:e->icc_profile:n - - + + mp4:e->av1_ccr:n - - + + mp4:e->mp3_frame:n - - + + mp4:e->mpeg_pes_packet:n - - + + mp4:e->opus_packet:n - - + + mp4:e->vorbis_packet:n - - + + mp4:e->vp9_frame:n - - + + mpeg_es - -mpeg_es - -mpeg_asc - -vorbis_packet + +mpeg_es + +mpeg_asc + +vorbis_packet mp4:e->mpeg_es:n - - + + protobuf_widevine - -protobuf_widevine - -protobuf + +protobuf_widevine + +protobuf mp4:e->protobuf_widevine:n - - + + pssh_playready - -pssh_playready + +pssh_playready mp4:e->pssh_playready:n - - + + vpx_ccr - -vpx_ccr + +vpx_ccr mp4:e->vpx_ccr:n - - + + mpeg_es:e->mpeg_asc:n - - + + mpeg_es:e->vorbis_packet:n - - + + protobuf - -protobuf + +protobuf protobuf_widevine:e->protobuf:n - - + + mpeg_pes - -mpeg_pes - -mpeg_pes_packet - -mpeg_spu + +mpeg_pes + +mpeg_pes_packet + +mpeg_spu mpeg_pes:e->mpeg_pes_packet:n - - + + mpeg_pes:e->mpeg_spu:n - - + + ogg:e->flac_frame:n - - + + ogg:e->flac_metadatablock:n - - + + ogg:e->opus_packet:n - - + + ogg:e->vorbis_packet:n - - + + ogg_page - -ogg_page + +ogg_page ogg:e->ogg_page:n - - + + pcap:e->ipv4_packet:n - - + + link_frame - -link_frame + +link_frame pcap:e->link_frame:n - - + + tcp_stream - -tcp_stream + +tcp_stream pcap:e->tcp_stream:n - - + + link_frame->bsd_loopback_frame:n - - + + link_frame->ether8023_frame:n - - + + sll2_packet - -sll2_packet - -inet_packet + +sll2_packet + +inet_packet link_frame->sll2_packet:n - - + + sll_packet - -sll_packet - -inet_packet + +sll_packet + +inet_packet link_frame->sll_packet:n - - + + rtmp - -rtmp - -amf0 - -mpeg_asc + +rtmp + +amf0 + +mpeg_asc tcp_stream->rtmp:n - - + + dns - -dns + +dns tcp_stream->dns:n - - + + pcapng:e->ipv4_packet:n - - + + pcapng:e->link_frame:n - - + + pcapng:e->tcp_stream:n - - + + png:e->exif:n - - + + png:e->icc_profile:n - - + + rtmp:e->mpeg_asc:n - - + + amf0 - -amf0 + +amf0 rtmp:e->amf0:n - - + + sll2_packet:e->inet_packet:n - - + + sll_packet:e->inet_packet:n - - + + tar:e->probe:n - - + + tiff:e->icc_profile:n - - + + udp_payload - -udp_payload + +udp_payload udp_datagram:e->udp_payload:n - - + + udp_payload->dns:n - - + + wav:e->id3v2:n - - + + wav:e->id3v1:n - - + + wav:e->id3v11:n - - + + webp:e->vp8_frame:n - - + + zip:e->probe:n - - + + asn1_ber - -asn1_ber + +asn1_ber bencode - -bencode + +bencode bson - -bson + +bson cbor - -cbor + +cbor dns_tcp - -dns_tcp + +dns_tcp - + +mbr + +mbr + + + msgpack - -msgpack + +msgpack - + raw - -raw + +raw diff --git a/format/all/all.go b/format/all/all.go index cfe3df9dd..0adee9fd9 100644 --- a/format/all/all.go +++ b/format/all/all.go @@ -24,6 +24,7 @@ import ( _ "github.com/wader/fq/format/json" _ "github.com/wader/fq/format/macho" _ "github.com/wader/fq/format/matroska" + _ "github.com/wader/fq/format/mbr" _ "github.com/wader/fq/format/mp3" _ "github.com/wader/fq/format/mp4" _ "github.com/wader/fq/format/mpeg" diff --git a/format/all/help.fqtest b/format/all/help.fqtest index a4edb421c..0b87cc08f 100644 --- a/format/all/help.fqtest +++ b/format/all/help.fqtest @@ -473,6 +473,17 @@ out https://matroska.org/technical/specs/index.html out https://www.matroska.org/technical/basics.html out https://www.matroska.org/technical/codec_specs.html out https://wiki.xiph.org/MatroskaOpus +"help(mbr)" +out mbr: Master Boot Record decoder +out Supports decoding Master Boot Record data +out Examples: +out # Decode file as mbr +out $ fq -d mbr . file +out # Decode value as mbr +out ... | mbr +out References and links +out https://thestarman.pcministry.com/asm/mbr/PartTables.htm#mbr +out https://en.wikipedia.org/wiki/Master_boot_record "help(mp3)" out mp3: MP3 file decoder out Options: diff --git a/format/format.go b/format/format.go index 7ea87e244..f54b9ed75 100644 --- a/format/format.go +++ b/format/format.go @@ -68,6 +68,7 @@ const ( JSON = "json" MACHO = "macho" MATROSKA = "matroska" + MBR = "mbr" MP3 = "mp3" MP3_FRAME = "mp3_frame" MP4 = "mp4" diff --git a/format/mbr/mbr.go b/format/mbr/mbr.go new file mode 100644 index 000000000..2513af3ad --- /dev/null +++ b/format/mbr/mbr.go @@ -0,0 +1,72 @@ +package mbr + +import ( + "embed" + "fmt" + + "github.com/wader/fq/format" + "github.com/wader/fq/format/registry" + "github.com/wader/fq/pkg/decode" + "github.com/wader/fq/pkg/scalar" +) + +//go:embed mbr.jq +var mbrFS embed.FS + +func init() { + registry.MustRegister(decode.Format{ + Name: format.MBR, + Description: "Master Boot Record", + DecodeFn: mbrDecode, + Functions: []string{"_help"}, + Files: mbrFS, + }) +} + +func decodePartitionTableEntry(d *decode.D) { + d.FieldU8("boot_indicator", scalar.UToDescription{ + 0x80: "active", + 0x00: "inactive", + }) + d.FieldStrScalarFn("starting_chs_vals", decodeCHSBytes) + d.FieldU8("partition_type", partitionTypes) + d.FieldStrScalarFn("ending_chs_vals", decodeCHSBytes) + d.FieldStrScalarFn("starting_sector", decodeCHSBytes) + d.U8() // extra byte + d.FieldScalarU32("partition_size") +} + +// Because this is a fixed-sized table, I am opting to use a +// FieldStruct instead of a FieldArray +func decodePartitionTable(d *decode.D) { + d.FieldStruct("entry_1", decodePartitionTableEntry) + d.FieldStruct("entry_2", decodePartitionTableEntry) + d.FieldStruct("entry_3", decodePartitionTableEntry) + d.FieldStruct("entry_4", decodePartitionTableEntry) +} + +// Source: https://thestarman.pcministry.com/asm/mbr/PartTables.htm#Decoding +func decodeCHSBytes(d *decode.D) scalar.S { + head, _ := d.Bits(8) + sectorHighBits, err := d.Bits(2) + if err != nil { + d.IOPanic(err, "chs") + } + sector, _ := d.Bits(6) + cylinderLowerBits, err := d.Bits(8) + if err != nil { + d.IOPanic(err, "chs") + } + cylinder := (sectorHighBits << 2) | cylinderLowerBits + return scalar.S{Actual: fmt.Sprintf("CHS(%x, %x, %x)", cylinder, head, sector)} +} + +func mbrDecode(d *decode.D, in interface{}) interface{} { + d.Endian = decode.LittleEndian + + d.FieldRawLen("code_area", 446*8) + d.FieldStruct("partition_table", decodePartitionTable) + d.FieldU16("boot_record_sig", scalar.ActualHex) + //d.AssertU(0xaa55) + return nil +} diff --git a/format/mbr/mbr.jq b/format/mbr/mbr.jq new file mode 100644 index 000000000..02b1e5dd3 --- /dev/null +++ b/format/mbr/mbr.jq @@ -0,0 +1,7 @@ +def _mbr__help: + { notes: "Supports decoding Master Boot Record data", + links: [ + {url: "https://thestarman.pcministry.com/asm/mbr/PartTables.htm#mbr"}, + {url: "https://en.wikipedia.org/wiki/Master_boot_record"} + ] + }; diff --git a/format/mbr/partition_types.go b/format/mbr/partition_types.go new file mode 100644 index 000000000..aed299066 --- /dev/null +++ b/format/mbr/partition_types.go @@ -0,0 +1,151 @@ +package mbr + +import ( + "github.com/wader/fq/pkg/scalar" +) + +// Source: https://thestarman.pcministry.com/asm/mbr/PartTypes.htm +var partitionTypes scalar.UToDescription = scalar.UToDescription{ + 0x00: "empty", + 0x01: "12-bit FAT", + 0x02: "XENIX root", + 0x03: "XENIX /usr (obsolete)", + 0x04: "16-bit FAT", + 0x05: "Extended Partition", + 0x06: "16-bit FAT, partition", + 0x07: "Installable file systems: HPFS or NTFS. Also, QNX and Advanced Unix.", + 0x08: "AIX bootable partition", + 0x09: "AIX data partition", + 0x0A: "Coherent swap partition, OPUS or OS/2 Boot Manager.", + 0x0B: "32-bit FAT", + 0x0C: "32-bit FAT, using INT 13 Extensions.", + 0x0E: "16-bit FAT >= 32 MB, using INT 13 Extensions.", + 0x0F: "Extended Partition, using INT 13 Extensions", + 0x10: "OPUS", + 0x11: "Hidden 12-bit FAT.", + 0x12: "Compaq diagnostics.", + 0x14: "Hidden 16-bit FAT", + 0x16: "Hidden 16-bit FAT, partition >= 32 MB", + 0x17: "Hidden IFS (HPFS, NTFS).", + 0x18: "AST Windows swap file", + 0x19: "Willowtech Photon coS", + 0x1B: "Hidden 32-bit FAT", + 0x1C: "Hidden 32-bit FAT, Ext INT 13", + 0x1E: "Hidden 16-bit FAT >32 MB, Ext. INT 13 (PowerQuest specific)", + 0x20: "Willowsoft Overture File System (OFS1)", + 0x21: "reserved (HP Volume Expansion, SpeedStor variant)", + 0x22: "Oxygen Extended", + 0x23: "reserved (HP Volume Expansion, SpeedStor variant?)", + 0x24: "NEC MS-DOS 3.x", + 0x26: "reserved (HP Volume Expansion, SpeedStor variant?)", + 0x31: "reserved (HP Volume Expansion, SpeedStor variant?)", + 0x33: "reserved (HP Volume Expansion, SpeedStor variant?)", + 0x34: "reserved (HP Volume Expansion, SpeedStor variant?)", + 0x36: "reserved (HP Volume Expansion, SpeedStor variant?)", + 0x38: "Theos", + 0x3C: "PowerQuest Files Partition Format", + 0x3D: "Hidden NetWare", + 0x40: "VENIX 80286", + 0x41: "Personal RISC Boot, PowerPC boot partition", + 0x42: "Secure File System, Windows 2000/XP (NT 5)", + 0x43: "Alternative Linux native file system (EXT2fs) PTS-DOS 6.70 & BootWizard: DR-DOS", + 0x45: "Priam, EUMEL/Elan. ", + 0x46: "EUMEL/Elan", + 0x47: "EUMEL/Elan", + 0x48: "EUMEL/Elan", + 0x4A: "ALFS/THIN lightweight filesystem for DOS", + 0x4D: "QNX", + 0x4E: "QNX", + 0x4F: "QNX, Oberon boot/data partition.", + 0x50: "Ontrack Disk Manager, read-only partition, FAT partition (Logical sector size varies)", + 0x51: "Ontrack Disk Manager, read/write partition, FAT partition (Logical sector size varies) Novell?", + 0x52: "CP/M, Microport System V/386.", + 0x53: "Ontrack Disk Manager, write-only", + 0x54: "Ontrack Disk Manager 6.0 (DDO)", + 0x55: "EZ-Drive 3.05", + 0x56: "Golden Bow VFeature", + 0x5C: "Priam EDISK", + 0x61: "Storage Dimensions SpeedStor", + 0x63: "GNU HURD, Mach, MtXinu BSD 4.2 on Mach, Unix Sys V/386, 386/ix.", + 0x64: "Novell NetWare 286, SpeedStore.", + 0x65: "Novell NetWare (3.11 and 4.1)", + 0x66: "Novell NetWare 386", + 0x67: "Novell NetWare", + 0x68: "Novell NetWare", + 0x69: "Novell NetWare 5+", + 0x70: "DiskSecure Multi-Boot", + 0x75: "IBM PC/IX", + 0x80: "Minix v1.1 - 1.4a, Old MINIX (Linux).", + 0x81: "Linux/Minix v1.4b+, Mitac Advanced Disk Manager.", + 0x82: "Linux Swap partition, Prime or Solaris (Unix).", + 0x83: "Linux native file systems (ext2/3/4, JFS, Reiser, xiafs, and others).", + 0x84: "OS/2 hiding type 04h partition", + 0x86: "NT Stripe Set, Volume Set?", + 0x87: "NT Stripe Set, Volume Set?, HPFS FT mirrored partition.", + 0x93: "Amoeba file system, Hidden Linux EXT2 partition (PowerQuest).", + 0x94: "Amoeba bad block table", + 0x99: "Mylex EISA SCSI", + 0x9F: "BSDI", + 0xA0: "Phoenix NoteBios Power Management 'Save to Disk', IBM hibernation.", + 0xA1: "HP Volume Expansion (SpeedStor variant)", + 0xA3: "HP Volume Expansion (SpeedStor variant)", + 0xA4: "HP Volume Expansion (SpeedStor variant)", + 0xA5: "FreeBSD/386", + 0xA6: "OpenBSD", + 0xA7: "NextStep Partition", + 0xA9: "NetBSD", + 0xAA: "Olivetti DOS with FAT12", + 0xB0: "Bootmanager BootStar by Star-Tools GmbH", + 0xB1: "HP Volume Expansion (SpeedStor variant)", + 0xB3: "HP Volume Expansion (SpeedStor variant)", + 0xB4: "HP Volume Expansion (SpeedStor variant)", + 0xB6: "HP Volume Expansion (SpeedStor variant)", + 0xB7: "BSDI file system or secondarily swap", + 0xB8: "BSDI swap partition or secondarily file system", + 0xBB: "PTS BootWizard (hidden) 4.0", + 0xBC: "May be an Acronis 'Backup' or 'Secure Zone' partition, when labeled 'ACRONIS SZ' (FAT32, LBA mapped, primary).", + 0xBE: "Solaris boot partition", + 0xC0: "Novell DOS/OpenDOS/DR-OpenDOS/DR-DOS secured partition, or CTOS (reported by a client).", + 0xC1: "DR-DOS 6.0 LOGIN.EXE-secured 12-bit FAT partition", + 0xC2: "Reserved for DR-DOS 7+", + 0xC3: "Reserved for DR-DOS 7+", + 0xC4: "DR-DOS 6.0 LOGIN.EXE-secured 16-bit FAT partition", + 0xC6: "DR-DOS 6.0 LOGIN.EXE-secured Huge partition, or: Corrupted FAT16 volume/stripe (V/S) set (Windows NT).", + 0xC7: "Syrinx, Cyrnix, HPFS FT disabled mirrored partition, or: Corrupted NTFS volume/stripe set.", + 0xC8: "Reserved for DR-DOS 7+", + 0xC9: "Reserved for DR-DOS 7+", + 0xCA: "Reserved for DR-DOS 7+", + 0xCB: "Reserved for DR-DOS secured FAT32", + 0xCC: "Reserved for DR-DOS secured FAT32X (LBA)", + 0xCD: "Reserved for DR-DOS 7+", + 0xCE: "Reserved for DR-DOS secured FAT16X (LBA)", + 0xCF: "Reserved for DR-DOS secured Extended partition (LBA)", + 0xD0: "Multiuser DOS secured (FAT12???)", + 0xD1: "Old Multiuser DOS secured FAT12", + 0xD4: "Old Multiuser DOS secured FAT16 (<= 32M)", + 0xD5: "Old Multiuser DOS secured extended partition", + 0xD6: "Old Multiuser DOS secured FAT16 (BIGDOS > 32 Mb)", + 0xD8: "CP/M 86", + 0xDB: "CP/M, Concurrent CP/M, Concurrent DOS, or CTOS (Convergent Technologies OS).", + 0xDE: "Dell partition. Normally it contains a FAT16 file system of about 32 MB.", + 0xDF: "BootIt EMBRM", + 0xE1: "SpeedStor 12-bit FAT Extended partition, DOS access (Linux).", + 0xE2: "DOS read-only (Florian Painke's XFDISK 1.0.4)", + 0xE3: "SpeedStor (Norton, Linux says DOS R/O)", + 0xE4: "SpeedStor 16-bit FAT Extended partition", + 0xE5: "Tandy DOS with logical sectored FAT", + 0xE6: "Storage Dimensions SpeedStor", + 0xEB: "BeOS file system", + 0xED: "Reserved for Matthias Paul's Spryt*x", + 0xEE: "GPT Protective MBR followed by a GPT/EFI Header. Used to define a fake partition covering the entire disk.", + 0xEF: "EFI/UEFI System Partition (or ESP)", + 0xF1: "SpeedStor Dimensions (Norton,Landis)", + 0xF2: "DOS 3.3+ second partition, Unisys DOS with logical sectored FAT.", + 0xF3: "Storage Dimensions SpeedStor", + 0xF4: "SpeedStor Storage Dimensions (Norton,Landis)", + 0xF5: "Prologue", + 0xF6: "Storage Dimensions SpeedStor", + 0xFD: "Reserved for FreeDOS (http://www.freedos.org)", + 0xFE: "LANstep, IBM PS/2 IML (Initial Microcode Load) partition, or...", + 0xFF: "Xenix bad-block table", +} diff --git a/format/mbr/testdata/mbr.bin b/format/mbr/testdata/mbr.bin new file mode 100644 index 0000000000000000000000000000000000000000..016a44a81f772d4980c7c39a71f06ff2da23cb99 GIT binary patch literal 512 zcmaEzJOKxI?WrQf&&d$9PrAnNz*%9pE}oW?r2_jbYhIKvzO-d@%gHY&sASm9P|$bS z@b(TyrmYOy7|se8UEapH)&J!T1_p)(AO?f~zh1L`JJe7DBnnEHHZ{DetYKgP<( z7Z!&Om;aqEOvhOS7}C1sHq@qd#&7@`TR;q+<1TCr1zVhe&R_*P>~+}|jzwKB@%72G6pjrIeE*^Zu)bXO@i$kXi2miK12VO9xb+V)_1e(Tq zpwusIA<%roOKIOtIxd2!5*BM0j#~472Rn`$960!biQ{0$g{Y2Wh%f+JEZ1{5L2f4l zW8ZDVZ~GY<`i}kiyi`8%zgkqyzP8%e%=@O+zA$0fH>>uA9>ZCQ*Z