def next_cluster(self, cluster): last_position = self.partition.disk.image.tell() self.partition.disk.image.seek(lba(self.first_sector) + cluster * 4) next_cluster = int.from_bytes(self.partition.disk.image.read(4), byteorder="little") self.partition.disk.image.seek(last_position) return next_cluster & MASK
def read_cluster(self, cluster): last_position = self.disk.image.tell() self.disk.image.seek(lba(self.get_sector(cluster))) data = self.disk.image.read(self.bytes_per_sector * self.sectors_per_cluster) self.disk.image.seek(last_position) return data
def print_chain(self, cluster): last_position = self.partition.disk.image.tell() self.partition.disk.image.seek(lba(self.first_sector) + cluster * 4) current_cluster = int.from_bytes(self.partition.disk.image.read(4), byteorder="little") & MASK print(current_cluster, end='') while current_cluster < 0x0FFFFFF8 or current_cluster == 0x00000000: current_cluster = self.next_cluster(current_cluster) & MASK print(" -> " + str(current_cluster), end='') print() self.partition.disk.image.seek(last_position)
def delete_entry(self, directory, name): last_position = self.disk.image.tell() entry = [e for e in directory.entries if e.name() == name][0] self.disk.image.seek( lba(self.get_sector(directory.first_cluster)) + entry.first_line * 32) for i in range(entry.length): self.disk.image.write(b'\xE5') self.disk.image.seek(31, 1) self.delete_cluster_chain(entry.cluster) directory.read_from_disk() self.disk.image.seek(last_position)
def find_free_cluster(self, cluster=2): last_position = self.partition.disk.image.tell() self.partition.disk.image.seek( lba(self.first_sector) + (cluster + 1) * 4) current_cluster = int.from_bytes(self.partition.disk.image.read(4), byteorder="little") & MASK cluster_number = max(cluster + 1, 2) while current_cluster != 0x00000000: current_cluster = int.from_bytes(self.partition.disk.image.read(4), byteorder="little") & MASK cluster_number += 1 self.partition.disk.image.seek(last_position) return cluster_number
def read_from_disk(self): last_position = self.partition.disk.image.tell() entry_block = list() self.entries = list() self.free_entries = list() entries_per_cluster = self.partition.sectors_per_cluster * self.partition.bytes_per_sector // 32 first_free_entry_number = -1 first_entry_number = -1 current_cluster = self.first_cluster while current_cluster < 0x0FFFFFF8: self.partition.disk.image.seek( lba(self.partition.get_sector(current_cluster))) for entry_number in range(0, entries_per_cluster): entry = self.partition.disk.image.read(32) if entry[0] == 0x00: if first_free_entry_number != -1: self.free_entries.append( (first_free_entry_number, (entries_per_cluster - first_free_entry_number), True)) else: self.free_entries.append( (entry_number, entries_per_cluster - entry_number, True)) first_free_entry_number = -1 break elif entry[0] == 0xE5: if first_free_entry_number == -1: first_free_entry_number = entry_number continue else: if first_entry_number == -1: first_entry_number = entry_number if first_free_entry_number != -1: self.free_entries.append( (first_free_entry_number, entry_number - first_free_entry_number, False)) first_free_entry_number = -1 entry_block.append(entry) if entry[11] != 0x0F: self.entries.append( Entry.from_binary(entry_block, first_entry_number)) first_entry_number = -1 entry_block = list() current_cluster = self.partition.next_cluster(current_cluster) self.partition.disk.image.seek(last_position)
def write(self, entry): last_position = self.partition.disk.image.tell() entry = entry.encode() free_entry = self.free_entries[0] for e in self.free_entries: if e[1] > len(entry) or e[2]: free_entry = e current_directory_cluster = self.first_cluster while free_entry[ 0] > self.partition.bytes_per_sector * self.partition.sectors_per_cluster / 32: current_directory_cluster = self.partition.next_cluster( current_directory_cluster) free_entry[ 0] -= self.partition.bytes_per_sector * self.partition.sectors_per_cluster / 32 self.partition.disk.image.seek( lba(self.partition.get_sector(current_directory_cluster)) + free_entry[0] * 32) if free_entry[2]: if len(entry) < free_entry[1]: self.partition.disk.image.write(b''.join(entry)) else: self.partition.disk.image.write(b''.join( entry[:free_entry[1]])) self.partition.write_to_fat( current_directory_cluster, self.partition.next_free_cluster( current_directory_cluster)) if len(entry[free_entry[1]:]) != 0: self.partition.disk.image.write(b''.join( entry[free_entry[1]:])) self.partition.disk.image.write(b'\xe5') else: self.partition.disk.image.write(b''.join(entry)) self.partition.disk.image.seek(last_position)
def write_cluster(self, cluster, data): last_position = self.disk.image.tell() self.disk.image.seek(lba(self.get_sector(cluster))) self.disk.image.write(data) self.disk.image.seek(last_position)
def __init__(self, disk, number): self.number = number self.disk = disk last_position = self.disk.image.tell() self.disk.image.seek(0x1BE + self.number * 16 * 8) self.boot_flag = int.from_bytes(self.disk.image.read(1), byteorder="little") self.CHS_begin = int.from_bytes(self.disk.image.read(3), byteorder="little") self.partition_type = int.from_bytes(self.disk.image.read(1), byteorder="little") self.CHS_end = int.from_bytes(self.disk.image.read(3), byteorder="little") self.first_sector = int.from_bytes(self.disk.image.read(4), byteorder="little") self.sectors_number = int.from_bytes(self.disk.image.read(4), byteorder="little") self.fat32 = self.partition_type == 0x0B or self.partition_type == 0x0C if self.fat32: self.disk.image.seek(lba(self.first_sector) + 0x0B) self.bytes_per_sector = int.from_bytes(self.disk.image.read(2), byteorder="little") self.sectors_per_cluster = int.from_bytes(self.disk.image.read(1), byteorder="little") self.reserved_sectors = int.from_bytes(self.disk.image.read(2), byteorder="little") self.number_of_FATs = int.from_bytes(self.disk.image.read(1), byteorder="little") self.disk.image.seek(lba(self.first_sector) + 0x24) self.sectors_per_FAT = int.from_bytes(self.disk.image.read(4), byteorder="little") self.disk.image.seek(lba(self.first_sector) + 0x2C) self.root_cluster = int.from_bytes(self.disk.image.read(4), byteorder="little") self.disk.image.seek(lba(self.first_sector) + 0x1FE) print("Partition", number, "volume signature ................................. ", end='') if int.from_bytes(self.disk.image.read(2), byteorder="big") == 0x55AA: print(colors.OK + "OK" + colors.END) else: print(colors.FAIL + "FAIL" + colors.END) self.fat = list() for i in range(self.number_of_FATs): self.fat.append( FileAllocationTable( self, self.first_sector + self.reserved_sectors + i * self.sectors_per_FAT)) self.first_cluster = self.first_sector + self.reserved_sectors + self.number_of_FATs * self.sectors_per_FAT self.current_directory = Directory(self, self.root_cluster) self.current_path = Path() self.disk.image.seek(last_position)
def write(self, cluster, next_cluster): last_position = self.partition.disk.image.tell() self.partition.disk.image.seek(lba(self.first_sector) + cluster * 4) self.partition.disk.image.write( next_cluster.to_bytes(4, byteorder="little")) self.partition.disk.image.seek(last_position)