Пример #1
0
 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
Пример #2
0
 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
Пример #3
0
 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)
Пример #4
0
    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)
Пример #5
0
 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
Пример #6
0
    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)
Пример #7
0
    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)
Пример #8
0
 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)
Пример #9
0
    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)
Пример #10
0
 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)