def OnFileSelected(self, event): item = event.GetItem() if not item.IsOk(): item = self._tree.GetSelection() rec_num = self._tree.GetPyData(item)["rec_num"] f = NTFSFile({ "filename": self._filename, "filetype": "mft", "offset": 0, "clustersize": 4096, "prefix": "C:", "progress": False, }) try: self._model.set_record(f.mft_get_record(rec_num)) except InvalidMFTRecordNumber as e: sys.stderr.write("Unable to open MFT record %d\n" % (e.value)) return
def fetch(self, progress_fn=nop): """ @param progress_fn - A function(count, total) called periodically """ if len(self._nodes) > 0: return total_count = 0 with open(self._filename, "rb") as f: f.seek(0, 2) # end total_count = f.tell() / 1024 f.seek(0) f = NTFSFile({ "filename": self._filename, "filetype": "mft", "offset": 0, "clustersize": 4096, "prefix": "C:", "progress": False, }) class RecordConflict(Exception): def __init__(self, count): self.value = count def add_node(mftfile, record): """ Depends on the closure of `nodes` and `orphans` @raises RecordConflict if the record already exists in nodes """ rec_num = record.mft_record_number() & 0xFFFFFFFFFFFF # node already exists by rec_num if rec_num in self._nodes: raise RecordConflict(rec_num) # no filename info --> orphan with name "???" fn = record.filename_information() if not fn: node = Node(rec_num, "???", None, record.is_directory()) self._orphans.append(node) self._nodes[rec_num] = node return node # one level cycle parent_record_num = fn.mft_parent_reference() & 0xFFFFFFFFFFFF if parent_record_num == rec_num: node = Node(rec_num, fn.filename(), None, record.is_directory()) self._orphans.append(node) self._nodes[rec_num] = node return node if parent_record_num not in self._nodes: # no parent --> orphan with correct filename parent_buf = mftfile.mft_get_record_buf(parent_record_num) if parent_buf == array.array("B", ""): node = Node(rec_num, fn.filename(), None, record.is_directory()) self._orphans.append(node) self._nodes[rec_num] = node return node # parent sequence num incorrect --> # orphan with correct filename parent = MFTRecord(parent_buf, 0, False) if parent.sequence_number() != fn.mft_parent_reference() >> 48: node = Node(rec_num, fn.filename(), None, record.is_directory()) self._orphans.append(node) self._nodes[rec_num] = node return node add_node(mftfile, parent) parent_node = self._nodes[parent_record_num] node = Node(rec_num, fn.filename(), parent_node, record.is_directory()) self._nodes[rec_num] = node parent_node.add_child(node) return node count = 0 for record in f.record_generator(): count += 1 try: add_node(f, record) except RecordConflict: # this is expected. # this record must be a directory, and a descendant has already # been processed. pass if count % 100 == 0: progress_fn(count, total_count)