def update_record(self, record_no, raw_record = None): """ Update record when it changes (or to initialize) """ # if new data is provided, use the new data as the raw record, # otherwise, reparse it from the internal self.MFT_RAW file if raw_record: assert len(raw_record) == 1024 self.MFT_RAW = self.MFT_RAW[:record_no*1024] + raw_record + self.MFT_RAW[(record_no+1)*1024:] raw_record = self.MFT_RAW[record_no*1024:(record_no+1)*1024] record = mft.parse_record(raw_record, mft.set_default_options()) # Update the filepaths? if record['fncnt'] == 1: record['par_ref'] = record['fn',0]['par_ref'] record['name'] = record['fn',0]['name'] if record['fncnt'] > 1: record['par_ref'] = record['fn',0]['par_ref'] for j in (0, record['fncnt']-1): #print record['fn',i] if (record['fn', j]['nspace'] == 0x1 or record['fn', j]['nspace'] == 0x3): record['name'] = record['fn', j]['name'] if (record.get('name') == None): record['name'] = record['fn', record['fncnt']-1]['name'] # add the record to the MFT self.mft[record_no] = record # process children records, if any # children records are stored in other records or on disk (non-resident) self._process_children(record_no) # Need to call gen_filepaths() self.gen_filepaths()
def _process_children(self, record_no): """ Process all the children records for the parent MFT record at record_no Children records are all attributes stored separately, e.g. in another MFT record or (if non-resident) in the filesystem """ # check if this MFT record has an attribute list record = self.mft[record_no] if 'attribute_list' in record: # check if resident elsewhere in MFT or non-resident (in the filesystem somewhere) if record['attribute_list']['res'] != 0: # non-resident # TODO pull from filesystem - remember to use volume offsets pass # go through each attribute list entry and pluck from other MFT entries for attr_list_record in record['attribute_list']['records']: # skip if it's in the current record if attr_list_record['mft_record_no'] != record_no: # find the other record and look for the attribute we need raw_other_record = self.MFT_RAW[attr_list_record['mft_record_no']*1024:(attr_list_record['mft_record_no']+1)*1024] other_record = mft.parse_record(raw_other_record, mft.set_default_options()) self.mft[attr_list_record['mft_record_no']] = other_record for attribute in other_record['attributes']: if attribute['type'] == attr_list_record['type'] and \ attribute['name'] == attr_list_record['name']: record['attributes'].append(attribute)