Loading tools/fat16copy.py +40 −75 Original line number Original line Diff line number Diff line Loading @@ -222,11 +222,8 @@ class fat_dir(object): data.seek(0, os.SEEK_END) data.seek(0, os.SEEK_END) size = data.tell() size = data.tell() chunk = 0 # Empty files shouldn't have any clusters assigned. chunk = self.backing.fs.allocate(size) if size > 0 else 0 if size > 0: chunk = self.backing.fs.allocate(size) (shortname, ext) = self.make_short_name(name) (shortname, ext) = self.make_short_name(name) self.add_dentry(0, shortname, ext, name, chunk, size) self.add_dentry(0, shortname, ext, name, chunk, size) Loading Loading @@ -393,27 +390,22 @@ class dentry(object): record_count = len(longname_record_data) + 1 record_count = len(longname_record_data) + 1 found_count = 0 found_count = 0 while found_count < record_count: while True: record = f.read(32) record = f.read(32) if record is None or len(record) != 32: if record is None or len(record) != 32: break # We reached the EOF, so we need to extend the file with a new cluster. f.write("\0" * self.fs.bytes_per_cluster) f.seek(-self.fs.bytes_per_cluster, os.SEEK_CUR) record = f.read(32) marker = struct.unpack("B", record[0])[0] marker = struct.unpack("B", record[0])[0] if marker == DEL_MARKER or marker == 0: if marker == DEL_MARKER or marker == 0: found_count += 1 found_count += 1 if found_count == record_count: break else: else: found_count = 0 found_count = 0 if found_count != record_count: f.write("\0" * self.fs.bytes_per_cluster) f.seek(-self.fs.bytes_per_cluster, os.SEEK_CUR) else: f.seek(-(record_count * 32), os.SEEK_CUR) f.seek(-(record_count * 32), os.SEEK_CUR) f.write(entry) f.write(entry) Loading Loading @@ -637,7 +629,6 @@ class fat(object): Allocate a new cluster chain big enough to hold at least the given amount Allocate a new cluster chain big enough to hold at least the given amount of bytes. of bytes. """ """ assert amount > 0, "Must allocate a non-zero amount." assert amount > 0, "Must allocate a non-zero amount." f = self.f f = self.f Loading Loading @@ -702,40 +693,18 @@ class fat(object): Given a cluster which is the *last* cluster in a chain, extend it to hold Given a cluster which is the *last* cluster in a chain, extend it to hold at least `amount` more bytes. at least `amount` more bytes. """ """ return_cluster = None if amount == 0: return f = self.f f = self.f entry_offset = FAT_TABLE_START + cluster * 2 position = FAT_TABLE_START + cluster * 2 f.seek(entry_offset) f.seek(position) assert read_le_short(f) == 0xFFFF, "Extending from middle of chain" assert read_le_short(f) == 0xFFFF, "Extending from middle of chain" rewind_short(f) while position + 2 < FAT_TABLE_START + self.fat_size and amount > 0: skip_short(f) got = read_le_short(f) rewind_short(f) rewind_short(f) if got != 0: return_cluster = self.allocate(amount) break f.seek(entry_offset) self.write_cluster_entry(return_cluster) cluster += 1 return_cluster = return_cluster or cluster position += 2 self.write_cluster_entry(cluster) amount -= self.bytes_per_cluster if amount <= 0: self.write_cluster_entry(0xFFFF) return return_cluster return return_cluster new_chunk = self.allocate(amount) f.seek(FAT_TABLE_START + cluster * 2) self.write_cluster_entry(new_chunk) return return_cluster or new_chunk def write_file(self, head_cluster, start_byte, data): def write_file(self, head_cluster, start_byte, data): """ """ Write to a given FAT file. Write to a given FAT file. Loading @@ -745,35 +714,31 @@ class fat(object): data: The data to write. data: The data to write. """ """ f = self.f f = self.f last_offset = start_byte + len(data) while True: current_offset = 0 if start_byte < self.bytes_per_cluster: current_cluster = head_cluster to_write = data[:self.bytes_per_cluster - start_byte] data = data[self.bytes_per_cluster - start_byte:] while current_offset < last_offset: # Write everything that falls in the cluster starting at current_offset. cluster_bytes_from_root = (head_cluster - 2) * \ data_begin = max(0, current_offset - start_byte) self.bytes_per_cluster data_end = min(len(data), bytes_from_root = cluster_bytes_from_root + start_byte current_offset + self.bytes_per_cluster - start_byte) bytes_from_data_start = bytes_from_root + self.root_entries * 32 if data_end > data_begin: cluster_file_offset = (self.data_start() + self.root_entries * 32 + f.seek(self.data_start() + bytes_from_data_start) (current_cluster - 2) * self.bytes_per_cluster) f.write(to_write) f.seek(cluster_file_offset + max(0, start_byte - current_offset)) f.write(data[data_begin:data_end]) if len(data) == 0: return # Advance to the next cluster in the chain or get a new cluster if needed. current_offset += self.bytes_per_cluster start_byte -= self.bytes_per_cluster if last_offset > current_offset: f.seek(FAT_TABLE_START + current_cluster * 2) if start_byte < 0: start_byte = 0 f.seek(FAT_TABLE_START + head_cluster * 2) next_cluster = read_le_short(f) next_cluster = read_le_short(f) if next_cluster > MAX_CLUSTER_ID: if next_cluster > MAX_CLUSTER_ID: head_cluster = self.extend_cluster(head_cluster, len(data)) next_cluster = self.extend_cluster(current_cluster, len(data)) else: current_cluster = next_cluster head_cluster = next_cluster assert current_cluster > 0, "Cannot write free cluster" assert head_cluster > 0, "Cannot write free cluster" def add_item(directory, item): def add_item(directory, item): """ """ Loading Loading
tools/fat16copy.py +40 −75 Original line number Original line Diff line number Diff line Loading @@ -222,11 +222,8 @@ class fat_dir(object): data.seek(0, os.SEEK_END) data.seek(0, os.SEEK_END) size = data.tell() size = data.tell() chunk = 0 # Empty files shouldn't have any clusters assigned. chunk = self.backing.fs.allocate(size) if size > 0 else 0 if size > 0: chunk = self.backing.fs.allocate(size) (shortname, ext) = self.make_short_name(name) (shortname, ext) = self.make_short_name(name) self.add_dentry(0, shortname, ext, name, chunk, size) self.add_dentry(0, shortname, ext, name, chunk, size) Loading Loading @@ -393,27 +390,22 @@ class dentry(object): record_count = len(longname_record_data) + 1 record_count = len(longname_record_data) + 1 found_count = 0 found_count = 0 while found_count < record_count: while True: record = f.read(32) record = f.read(32) if record is None or len(record) != 32: if record is None or len(record) != 32: break # We reached the EOF, so we need to extend the file with a new cluster. f.write("\0" * self.fs.bytes_per_cluster) f.seek(-self.fs.bytes_per_cluster, os.SEEK_CUR) record = f.read(32) marker = struct.unpack("B", record[0])[0] marker = struct.unpack("B", record[0])[0] if marker == DEL_MARKER or marker == 0: if marker == DEL_MARKER or marker == 0: found_count += 1 found_count += 1 if found_count == record_count: break else: else: found_count = 0 found_count = 0 if found_count != record_count: f.write("\0" * self.fs.bytes_per_cluster) f.seek(-self.fs.bytes_per_cluster, os.SEEK_CUR) else: f.seek(-(record_count * 32), os.SEEK_CUR) f.seek(-(record_count * 32), os.SEEK_CUR) f.write(entry) f.write(entry) Loading Loading @@ -637,7 +629,6 @@ class fat(object): Allocate a new cluster chain big enough to hold at least the given amount Allocate a new cluster chain big enough to hold at least the given amount of bytes. of bytes. """ """ assert amount > 0, "Must allocate a non-zero amount." assert amount > 0, "Must allocate a non-zero amount." f = self.f f = self.f Loading Loading @@ -702,40 +693,18 @@ class fat(object): Given a cluster which is the *last* cluster in a chain, extend it to hold Given a cluster which is the *last* cluster in a chain, extend it to hold at least `amount` more bytes. at least `amount` more bytes. """ """ return_cluster = None if amount == 0: return f = self.f f = self.f entry_offset = FAT_TABLE_START + cluster * 2 position = FAT_TABLE_START + cluster * 2 f.seek(entry_offset) f.seek(position) assert read_le_short(f) == 0xFFFF, "Extending from middle of chain" assert read_le_short(f) == 0xFFFF, "Extending from middle of chain" rewind_short(f) while position + 2 < FAT_TABLE_START + self.fat_size and amount > 0: skip_short(f) got = read_le_short(f) rewind_short(f) rewind_short(f) if got != 0: return_cluster = self.allocate(amount) break f.seek(entry_offset) self.write_cluster_entry(return_cluster) cluster += 1 return_cluster = return_cluster or cluster position += 2 self.write_cluster_entry(cluster) amount -= self.bytes_per_cluster if amount <= 0: self.write_cluster_entry(0xFFFF) return return_cluster return return_cluster new_chunk = self.allocate(amount) f.seek(FAT_TABLE_START + cluster * 2) self.write_cluster_entry(new_chunk) return return_cluster or new_chunk def write_file(self, head_cluster, start_byte, data): def write_file(self, head_cluster, start_byte, data): """ """ Write to a given FAT file. Write to a given FAT file. Loading @@ -745,35 +714,31 @@ class fat(object): data: The data to write. data: The data to write. """ """ f = self.f f = self.f last_offset = start_byte + len(data) while True: current_offset = 0 if start_byte < self.bytes_per_cluster: current_cluster = head_cluster to_write = data[:self.bytes_per_cluster - start_byte] data = data[self.bytes_per_cluster - start_byte:] while current_offset < last_offset: # Write everything that falls in the cluster starting at current_offset. cluster_bytes_from_root = (head_cluster - 2) * \ data_begin = max(0, current_offset - start_byte) self.bytes_per_cluster data_end = min(len(data), bytes_from_root = cluster_bytes_from_root + start_byte current_offset + self.bytes_per_cluster - start_byte) bytes_from_data_start = bytes_from_root + self.root_entries * 32 if data_end > data_begin: cluster_file_offset = (self.data_start() + self.root_entries * 32 + f.seek(self.data_start() + bytes_from_data_start) (current_cluster - 2) * self.bytes_per_cluster) f.write(to_write) f.seek(cluster_file_offset + max(0, start_byte - current_offset)) f.write(data[data_begin:data_end]) if len(data) == 0: return # Advance to the next cluster in the chain or get a new cluster if needed. current_offset += self.bytes_per_cluster start_byte -= self.bytes_per_cluster if last_offset > current_offset: f.seek(FAT_TABLE_START + current_cluster * 2) if start_byte < 0: start_byte = 0 f.seek(FAT_TABLE_START + head_cluster * 2) next_cluster = read_le_short(f) next_cluster = read_le_short(f) if next_cluster > MAX_CLUSTER_ID: if next_cluster > MAX_CLUSTER_ID: head_cluster = self.extend_cluster(head_cluster, len(data)) next_cluster = self.extend_cluster(current_cluster, len(data)) else: current_cluster = next_cluster head_cluster = next_cluster assert current_cluster > 0, "Cannot write free cluster" assert head_cluster > 0, "Cannot write free cluster" def add_item(directory, item): def add_item(directory, item): """ """ Loading