exorcise/exorcise/partition/ntfs/index.py

57 lines
1.5 KiB
Python

import enum
from destruct import Struct
def pad_to(v, n):
return (n - (v % n)) % n
def align_to(v, n):
return v + pad_to(v, n)
class IndexEntryFlag(enum.IntFlag):
HasSubNode = 1
Last = 2
class IndexEntry(Struct, generics=['G']):
file_reference = UInt(64)
length = UInt(16)
data_length = UInt(16)
flags = Enum(IndexEntryFlag, UInt(8))
_pad13 = Pad(3)
data = Switch(options={
True: Capped(G, exact=True),
False: Nothing
})
_dalign = Data()
sub_node_vcn = Switch(options={
True: UInt(64),
False: Nothing
})
def on_flags(self, spec, context):
spec.data.selector = not bool(self.flags & IndexEntryFlag.Last)
spec.sub_node_vcn.selector = bool(self.flags & IndexEntryFlag.HasSubNode)
spec._dalign.length = self.length - 16
if spec.data.selector:
spec.data.current.limit = self.data_length
spec._dalign.length -= align_to(self.data_length, 8)
if spec.sub_node_vcn.selector:
spec._dalign.length -= 8
class IndexNode(Struct, generics=['G']):
entry_offset = UInt(32)
entry_size = UInt(32)
node_size = UInt(32)
has_children = Bool()
_pad13 = Pad(3)
entries = Capped(Arr(IndexEntry[G]))
def on_entry_size(self, spec, context):
spec.entries.limit = self.entry_size - 40 # 16
def parse(self, input, context):
value = super().parse(input, context)
return value.entries