def directory_garbage(disk, fsck, newfs, newfs_opts): launch([newfs] + newfs_opts + [disk]) f = file(disk, "r+") v = msdosfs(f) root = v.root() # Create a subdirectory with some children subdir = root.mkdir('EFI', v.fat.find(2)) for i in range(10): subdir.mkfile("Child {}".format(i), content="This is child number {}".format(i)) # # Now clobber the contents of the subdirectory by overwriting it with text. # # Note: the length of this text is 887 bytes, which could be larger than a # cluster (minimum cluster size is 512). Be sure the directory is large enough! # subdir.pwrite( 0, """Here's to the crazy ones. The misfits. The rebels. The troublemakers. The round pegs in the square holes. The ones who see things differently. They're not fond of rules. And they have no respect for the status quo. You can quote them, disagree with them, glorify or vilify them. About the only thing you can't do is ignore them. Because they change things. They invent. They imagine. They heal. They explore. They create. They inspire. They push the human race forward. Maybe they have to be crazy. How else can you stare at an empty canvas and see a work of art? Or sit in silence and hear a song that's never been written? Or gaze at a red planet and see a laboratory on wheels? We make tools for these kinds of people. While some see them as the crazy ones, we see genius. Because the people who are crazy enough to think they can change the world, are the ones who do. """) v.flush() f.close() try: launch([fsck, '-n', disk]) except LaunchError: pass else: raise FailureExpected("Subdirectory /EFI should be corrupt") launch([fsck, '-y', disk]) launch([fsck, '-n', disk]) # Make sure /EFI has been changed to a file f = file(disk, "r+") v = msdosfs(f) root = v.root() efi = root.pread(32, 32) # The directory entry for /EFI assert (efi[0:11] == "EFI ") assert (efi[11] == "\x00") # No longer has ATTR_DIRECTORY set f.close()
def directory_garbage(disk, fsck, newfs, newfs_opts): launch([newfs]+newfs_opts+[disk]) f = file(disk, "r+") v = msdosfs(f) root = v.root() # Create a subdirectory with some children subdir = root.mkdir('EFI', v.fat.find(2)) for i in range(10): subdir.mkfile("Child {}".format(i), content="This is child number {}".format(i)) # # Now clobber the contents of the subdirectory by overwriting it with text. # # Note: the length of this text is 887 bytes, which could be larger than a # cluster (minimum cluster size is 512). Be sure the directory is large enough! # subdir.pwrite(0, """Here's to the crazy ones. The misfits. The rebels. The troublemakers. The round pegs in the square holes. The ones who see things differently. They're not fond of rules. And they have no respect for the status quo. You can quote them, disagree with them, glorify or vilify them. About the only thing you can't do is ignore them. Because they change things. They invent. They imagine. They heal. They explore. They create. They inspire. They push the human race forward. Maybe they have to be crazy. How else can you stare at an empty canvas and see a work of art? Or sit in silence and hear a song that's never been written? Or gaze at a red planet and see a laboratory on wheels? We make tools for these kinds of people. While some see them as the crazy ones, we see genius. Because the people who are crazy enough to think they can change the world, are the ones who do. """) v.flush() f.close() try: launch([fsck, '-n', disk]) except LaunchError: pass else: raise FailureExpected("Subdirectory /EFI should be corrupt") launch([fsck, '-y', disk]) launch([fsck, '-n', disk]) # Make sure /EFI has been changed to a file f = file(disk, "r+") v = msdosfs(f) root = v.root() efi = root.pread(32, 32) # The directory entry for /EFI assert(efi[0:11] == "EFI ") assert(efi[11] == "\x00") # No longer has ATTR_DIRECTORY set f.close()
def fat_mark_clean_ok(disk, fsck, newfs, newfs_opts): launch([newfs] + newfs_opts + [disk]) f = file(disk, "r+") v = msdosfs(f) # Mark the volume "dirty" by clearing the "clean" bit. if v.type == 32: v.fat[1] = v.fat[1] & 0x07FFFFFF else: v.fat[1] = v.fat[1] & 0x7FFF v.flush() del v f.close() del f # Make sure that we ask the user to mark the disk clean, but don't return # a non-zero exit status if the user declines. stdout, stderr = launch([fsck, '-n', disk], stdout=subprocess.PIPE, stderr=subprocess.PIPE) assert "\nMARK FILE SYSTEM CLEAN? no\n" in stdout assert "\n***** FILE SYSTEM IS LEFT MARKED AS DIRTY *****\n" in stdout stdout, stderr = launch([fsck, '-y', disk], stdout=subprocess.PIPE, stderr=subprocess.PIPE) assert "\nMARK FILE SYSTEM CLEAN? yes\n" in stdout assert "\nMARKING FILE SYSTEM CLEAN\n" in stdout f = file(disk, "r") v = msdosfs(f) # Make sure the "clean" bit is now set. if v.type == 32: clean = v.fat[1] & 0x08000000 else: clean = v.fat[1] & 0x8000 if not clean: raise RuntimeError("Volume still dirty!") v.flush() del v f.close() del f launch(['/sbin/fsck_msdos', '-n', disk])
def test_quick(disk, fsck, newfs, newfs_opts): assert newfs_opts[1] in ["12", "16", "32"] launch([newfs]+newfs_opts+[disk]) # Try a quick check of a volume that is clean launch([fsck, '-q', disk]) # Make the volume dirty f = file(disk, "r+") v = msdosfs(f) if newfs_opts[1] in ["16", "32"]: if newfs_opts[1] == "16": v.fat[1] &= 0x7FFF else: v.fat[1] &= 0x07FFFFFF else: # Corrupt a FAT12 volume so that it looks dirty. # Allocate some clusters, so there is something to repair. v.allocate(3) v.flush() del v f.close() del f # Quick check a dirty volume try: launch([fsck, '-q', disk]) except LaunchError: pass else: raise FailureExpected("Volume not dirty?")
def past_end_of_dir(disk, fsck, newfs, newfs_opts, multiple_clusters=False): launch([newfs]+newfs_opts+[disk]) f = file(disk, "r+") v = msdosfs(f) root = v.root() if multiple_clusters: subdir_clusters = v.fat.find(10) else: subdir_clusters = None subdir = root.mkdir('SubDir', subdir_clusters) subdir.mkfile('Good Sub File') root.mkfile('Good Root File') # Make an entry that will be replaced by end-of-directory slotEOF = root.find_slots(1) root.mkfile('EOF') # Make some valid file entries past end of directory root.mkfile('BADFILE') root.mkdir('Bad Dir') root.mkfile('Bad File 2') # Overwrite 'EOF' entry with end-of-directory marker root.write_slots(slotEOF, '\x00' * 32) # Make an entry that will be replaced by end-of-directory slotEOF = subdir.find_slots(1) subdir.mkfile('EOF') # Make some valid file entries past end of directory subdir.mkfile('BADFILE') subdir.mkdir('Bad Dir') subdir.mkfile('Bad File 2') # If desired, make a whole bunch more entries that will cause # the directory to grow into at least one more cluster. # See Radar #xxxx. if multiple_clusters: base_name = "This file name is long so that it can take up plenty of room in the directory " entry_length = len(make_long_dirent(base_name, 0)) num_entries = 4 * (v.bytesPerCluster // entry_length) for i in xrange(num_entries): subdir.mkfile(base_name+str(i)) # Overwrite 'EOF' entry with end-of-directory marker subdir.write_slots(slotEOF, '\x00' * 32) v.flush() del v f.close() del f try: launch([fsck, '-n', disk]) except LaunchError: pass launch([fsck, '-y', disk]) launch(['/sbin/fsck_msdos', '-n', disk])
def dir_bad_start(disk, fsck, newfs, newfs_opts): def mkdir(parent, name, head): bytes = make_long_dirent(name, ATTR_DIRECTORY, head=head) slots = len(bytes)/32 slot = parent.find_slots(slots, grow=True) parent.write_slots(slot, bytes) launch([newfs]+newfs_opts+[disk]) f = file(disk, "r+") v = msdosfs(f) root = v.root() mkdir(root, 'DIR1', CLUST_FREE) mkdir(root, 'DIR2', CLUST_RSRVD) mkdir(root, 'DIR3', CLUST_BAD) mkdir(root, 'DIR4', CLUST_EOF) mkdir(root, 'DIR5', 1) mkdir(root, 'DIR6', v.clusters+2) v.flush() del v f.close() del f try: launch([fsck, '-n', disk]) except LaunchError: pass launch([fsck, '-y', disk]) launch(['/sbin/fsck_msdos', '-n', disk])
def file_4GB_excess_clusters(disk, fsck, newfs, newfs_opts): launch([newfs]+newfs_opts+[disk]) # # Create files with too many clusters for their size # print "# Creating a 4GiB+ file. This may take some time." f = file(disk, "r+") v = msdosfs(f) four_GB = 4*1024*1024*1024 clusters = four_GB / v.bytesPerCluster head=v.allocate(clusters+7) v.root().mkfile('FOO', head=head, length=5*v.bytesPerCluster-100) head=v.allocate(clusters+3) v.root().mkfile('BAR', head=head, length=four_GB-30) v.flush() del v f.close() del f # TODO: Need a better way to assert that the disk is corrupt to start with try: launch([fsck, '-n', disk]) except LaunchError: pass launch([fsck, '-y', disk]) launch([fsck, '-n', disk])
def file_bad_clusters(disk, fsck, newfs, newfs_opts): launch([newfs]+newfs_opts+[disk]) f = file(disk, "r+") v = msdosfs(f) clusters = v.fat.find(5) to_free = clusters[2] head = v.fat.chain(clusters) v.root().mkfile('FILE1', head=head, length=6*v.bytesPerCluster+111) if v.fsinfo: v.fsinfo.allocate(5) clusters = v.fat.find(5) head = v.fat.chain(clusters) v.root().mkfile('FILE2', head=head, length=4*v.bytesPerCluster+222) v.fat[clusters[2]] = CLUST_RSRVD if v.fsinfo: v.fsinfo.allocate(5) clusters = v.fat.find(5) head = v.fat.chain(clusters) v.root().mkfile('FILE3', head=head, length=4*v.bytesPerCluster+333) v.fat[clusters[2]] = 1 if v.fsinfo: v.fsinfo.allocate(5) clusters = v.fat.find(5) head = v.fat.chain(clusters) v.root().mkfile('FILE4', head=head, length=4*v.bytesPerCluster+44) v.fat[clusters[2]] = clusters[1] if v.fsinfo: v.fsinfo.allocate(5) v.root().mkfile('FILE5', head=CLUST_FREE, length=4*v.bytesPerCluster+55) v.root().mkfile('FILE6', head=CLUST_BAD, length=4*v.bytesPerCluster+66) v.root().mkfile('FILE7', head=CLUST_RSRVD-1, length=4*v.bytesPerCluster+77) head = v.allocate(5) v.root().mkfile('FOO', head=head, length=4*v.bytesPerCluster+99) v.root().mkfile('FILE8', head=head, length=4*v.bytesPerCluster+88) # Free the middle cluster of FILE1 now that we've finished allocating v.fat[to_free] = CLUST_FREE v.flush() del v f.close() del f try: launch([fsck, '-n', disk]) except LaunchError: pass launch([fsck, '-y', disk]) launch(['/sbin/fsck_msdos', '-n', disk])
def fat_mark_clean_ok(disk, fsck, newfs, newfs_opts): launch([newfs]+newfs_opts+[disk]) f = file(disk, "r+") v = msdosfs(f) # Mark the volume "dirty" by clearing the "clean" bit. if v.type == 32: v.fat[1] = v.fat[1] & 0x07FFFFFF else: v.fat[1] = v.fat[1] & 0x7FFF v.flush() del v f.close() del f # Make sure that we ask the user to mark the disk clean, but don't return # a non-zero exit status if the user declines. stdout, stderr = launch([fsck, '-n', disk], stdout=subprocess.PIPE, stderr=subprocess.PIPE) assert "\nMARK FILE SYSTEM CLEAN? no\n" in stdout assert "\n***** FILE SYSTEM IS LEFT MARKED AS DIRTY *****\n" in stdout stdout, stderr = launch([fsck, '-y', disk], stdout=subprocess.PIPE, stderr=subprocess.PIPE) assert "\nMARK FILE SYSTEM CLEAN? yes\n" in stdout assert "\nMARKING FILE SYSTEM CLEAN\n" in stdout f = file(disk, "r") v = msdosfs(f) # Make sure the "clean" bit is now set. if v.type == 32: clean = v.fat[1] & 0x08000000 else: clean = v.fat[1] & 0x8000 if not clean: raise RuntimeError("Volume still dirty!") v.flush() del v f.close() del f launch(['/sbin/fsck_msdos', '-n', disk])
def fat_mark_clean_corrupt(disk, fsck, newfs, newfs_opts): launch([newfs]+newfs_opts+[disk]) f = file(disk, "r+") v = msdosfs(f) # Mark the volume "dirty" by clearing the "clean" bit. if v.type == 32: v.fat[1] = v.fat[1] & 0x07FFFFFF else: v.fat[1] = v.fat[1] & 0x7FFF # Allocate some clusters, so there is something to repair. v.allocate(3) v.flush() del v f.close() del f try: launch([fsck, '-n', disk]) except LaunchError: pass launch([fsck, '-y', disk]) f = file(disk, "r") v = msdosfs(f) # Make sure the "clean" bit is now set. if v.type == 32: clean = v.fat[1] & 0x08000000 else: clean = v.fat[1] & 0x8000 if not clean: raise RuntimeError("Volume still dirty!") v.flush() del v f.close() del f launch(['/sbin/fsck_msdos', '-n', disk])
def dir_size_dots(disk, fsck, newfs, newfs_opts): launch([newfs]+newfs_opts+[disk]) f = file(disk, "r+") v = msdosfs(f) root = v.root() # Make a couple of directories without any problems child = root.mkdir('CHILD') grand = child.mkdir('GRAND') # Directory has non-zero size dir = root.mkdir('BADSIZE', length=666) # "." entry has incorrect start cluster dir = root.mkdir('BADDOT') fields = parse_dirent(dir.read_slots(0)) fields['head'] = fields['head'] + 30 dir.write_slots(0, make_dirent(**fields)) # ".." entry has non-zero start cluster, but parent is root dir = root.mkdir('DOTDOT.NZ') fields = parse_dirent(dir.read_slots(0)) fields['head'] = 47 dir.write_slots(0, make_dirent(**fields)) # ".." entry has zero start cluster, but parent is not root dir = child.mkdir('DOTDOT.ZER') fields = parse_dirent(dir.read_slots(0)) fields['head'] = 0 dir.write_slots(0, make_dirent(**fields)) # ".." entry start cluster is incorrect (parent is not root) dir = grand.mkdir('DOTDOT.BAD') fields = parse_dirent(dir.read_slots(0)) fields['head'] = fields['head'] + 30 dir.write_slots(0, make_dirent(**fields)) v.flush() del v f.close() del f try: launch([fsck, '-n', disk]) except LaunchError: pass launch([fsck, '-y', disk]) launch(['/sbin/fsck_msdos', '-n', disk])
def file_excess_clusters(disk, fsck, newfs, newfs_opts): launch([newfs]+newfs_opts+[disk]) # # Create files with too many clusters for their size # f = file(disk, "r+") v = msdosfs(f) head=v.allocate(7) v.root().mkfile('FOO', head=head, length=6*v.bytesPerCluster) head=v.allocate(1) v.root().mkfile('BAR', head=head, length=0) # # LINK1 is OK. # LINK2 contains excess clusters; the first is cross-linked with LINK1 # LINK3 contains excess clusters; the second is cross-linked with LINK1 # clusters = v.fat.find(9) head = v.fat.chain(clusters) v.root().mkfile('LINK1', head=head, length=8*v.bytesPerCluster+1) head = v.fat.allocate(3, last=clusters[7]) v.root().mkfile('LINK2', head=head, length=2*v.bytesPerCluster+3) head = v.fat.allocate(5, last=clusters[8]) v.root().mkfile('LINK3', head=head, length=3*v.bytesPerCluster+5) if v.fsinfo: v.fsinfo.allocate(9+3+5) # # FREE1 has its first excess cluster marked free # BAD3 has its third excess cluster marked bad # head = v.allocate(11, last=CLUST_BAD) v.root().mkfile('BAD3', head=head, length=8*v.bytesPerCluster+300) head = v.allocate(8, last=CLUST_FREE) v.root().mkfile('FREE1', head=head, length=6*v.bytesPerCluster+100) v.flush() del v f.close() del f try: launch([fsck, '-n', disk]) except LaunchError: pass launch([fsck, '-y', disk]) launch(['/sbin/fsck_msdos', '-n', disk])
def past_end_of_dir(disk, fsck, newfs, newfs_opts): launch([newfs] + newfs_opts + [disk]) f = file(disk, "r+") v = msdosfs(f) root = v.root() subdir = root.mkdir('SubDir') subdir.mkfile('Good Sub File') root.mkfile('Good Root File') # Make an entry that will be replaced by end-of-directory slotEOF = root.find_slots(1) root.mkfile('EOF') # Make some valid file entries past end of directory root.mkfile('BADFILE') root.mkdir('Bad Dir') root.mkfile('Bad File 2') # Overwrite 'EOF' entry with end-of-directory marker root.write_slots(slotEOF, '\x00' * 32) # Make an entry that will be replaced by end-of-directory slotEOF = subdir.find_slots(1) subdir.mkfile('EOF') # Make some valid file entries past end of directory subdir.mkfile('BADFILE') subdir.mkdir('Bad Dir') subdir.mkfile('Bad File 2') # Overwrite 'EOF' entry with end-of-directory marker subdir.write_slots(slotEOF, '\x00' * 32) v.flush() del v f.close() del f try: launch([fsck, '-n', disk]) except LaunchError: pass launch([fsck, '-y', disk]) launch(['/sbin/fsck_msdos', '-n', disk])
def past_end_of_dir(disk, fsck, newfs, newfs_opts): launch([newfs]+newfs_opts+[disk]) f = file(disk, "r+") v = msdosfs(f) root = v.root() subdir = root.mkdir('SubDir') subdir.mkfile('Good Sub File') root.mkfile('Good Root File') # Make an entry that will be replaced by end-of-directory slotEOF = root.find_slots(1) root.mkfile('EOF') # Make some valid file entries past end of directory root.mkfile('BADFILE') root.mkdir('Bad Dir') root.mkfile('Bad File 2') # Overwrite 'EOF' entry with end-of-directory marker root.write_slots(slotEOF, '\x00' * 32) # Make an entry that will be replaced by end-of-directory slotEOF = subdir.find_slots(1) subdir.mkfile('EOF') # Make some valid file entries past end of directory subdir.mkfile('BADFILE') subdir.mkdir('Bad Dir') subdir.mkfile('Bad File 2') # Overwrite 'EOF' entry with end-of-directory marker subdir.write_slots(slotEOF, '\x00' * 32) v.flush() del v f.close() del f try: launch([fsck, '-n', disk]) except LaunchError: pass launch([fsck, '-y', disk]) launch(['/sbin/fsck_msdos', '-n', disk])
def root_bad_first_cluster(disk, fsck, newfs, newfs_opts): for link in [CLUST_FREE, CLUST_RSRVD, CLUST_BAD]: launch([newfs]+newfs_opts+[disk]) f = file(disk, "r+") v = msdosfs(f) v.fat[v.rootCluster] = link v.flush() del v f.close() del f try: launch([fsck, '-n', disk]) except LaunchError: pass launch([fsck, '-y', disk]) launch(['/sbin/fsck_msdos', '-n', disk])
def test_18523205(disk, fsck, newfs, newfs_opts): launch([newfs] + newfs_opts + [disk]) # Create some subdirectories with children with open(disk, "r+") as f: v = msdosfs(f) root = v.root() for i in range(10): subdir = root.mkdir('Folder {}'.format(i)) subdir.mkfile('Child {}'.format(i), content='This is child number {}'.format(i)) v.flush() # Try quick check, verify and explicit repair launch([fsck, '-q', disk]) launch([fsck, '-n', disk]) launch([fsck, '-y', disk])
def fat_bad_0_or_1(disk, fsck, newfs, newfs_opts): launch([newfs]+newfs_opts+[disk]) f = file(disk, "r+") v = msdosfs(f) v.fat[0] = 0 v.fat[1] = 1 v.flush() del v f.close() del f try: launch([fsck, '-n', disk]) except LaunchError: pass launch([fsck, '-y', disk]) launch(['/sbin/fsck_msdos', '-n', disk])
def file_4GB(disk, fsck, newfs, newfs_opts): launch([newfs]+newfs_opts+[disk]) # # Create a file whose size is 4GB-100. That means its physical size will # be rounded up to the next multiple of the cluster size, meaning the # physical size will be 4GB. # f = file(disk, "r+") v = msdosfs(f) four_GB = 4*1024*1024*1024 clusters = four_GB / v.bytesPerCluster head = v.allocate(clusters) v.root().mkfile('4GB', head=head, length=four_GB-100) v.flush() del v f.close() del f launch([fsck, '-n', disk])
def orphan_clusters(disk, fsck, newfs, newfs_opts): launch([newfs]+newfs_opts+[disk]) # # Create some cluster chains not referenced by any file or directory # f = file(disk, "r+") v = msdosfs(f) v.allocate(7, 100) v.allocate(23, 150) v.allocate(1, 190) v.flush() del v f.close() del f try: launch([fsck, '-n', disk]) except LaunchError: pass launch([fsck, '-p', disk]) launch(['/sbin/fsck_msdos', '-n', disk])
def file_4GB(disk, fsck, newfs, newfs_opts): launch([newfs]+newfs_opts+[disk]) # # Create a file whose size is 4GB-100. That means its physical size will # be rounded up to the next multiple of the cluster size, meaning the # physical size will be 4GB. # print "# Creating a 4GiB file. This may take some time." f = file(disk, "r+") v = msdosfs(f) four_GB = 4*1024*1024*1024 clusters = four_GB / v.bytesPerCluster head = v.allocate(clusters) v.root().mkfile('4GB', head=head, length=four_GB-100) v.flush() del v f.close() del f launch([fsck, '-n', disk])
def root_bad_start(disk, fsck, newfs, newfs_opts): def set_root_start(disk, head): dev = file(disk, "r+") dev.seek(0) bytes = dev.read(512) bytes = bytes[0:44] + struct.pack("<I", head) + bytes[48:] dev.seek(0) dev.write(bytes) dev.close() del dev launch([newfs] + newfs_opts + [disk]) f = file(disk, "r+") v = msdosfs(f) clusters = v.clusters v.flush() del v f.close() del f for head in [ CLUST_FREE, CLUST_RSRVD, CLUST_BAD, CLUST_EOF, 1, clusters + 2 ]: set_root_start(disk, head) try: launch([fsck, '-n', disk]) except LaunchError: pass try: launch([fsck, '-y', disk]) except LaunchError: pass try: launch(['/sbin/fsck_msdos', '-n', disk]) except LaunchError: pass
def root_bad_start(disk, fsck, newfs, newfs_opts): def set_root_start(disk, head): dev = file(disk, "r+") dev.seek(0) bytes = dev.read(512) bytes = bytes[0:44] + struct.pack("<I", head) + bytes[48:] dev.seek(0) dev.write(bytes) dev.close() del dev launch([newfs]+newfs_opts+[disk]) f = file(disk, "r+") v = msdosfs(f) clusters = v.clusters v.flush() del v f.close() del f for head in [CLUST_FREE, CLUST_RSRVD, CLUST_BAD, CLUST_EOF, 1, clusters+2]: set_root_start(disk, head) try: launch([fsck, '-n', disk]) except LaunchError: pass try: launch([fsck, '-y', disk]) except LaunchError: pass try: launch(['/sbin/fsck_msdos', '-n', disk]) except LaunchError: pass
def long_name(disk, fsck, newfs, newfs_opts): launch([newfs]+newfs_opts+[disk]) f = file(disk, "r+") v = msdosfs(f) root = v.root() # Long name entries (valid or not!) preceding volume label bytes = make_long_dirent('Test1GB', ATTR_VOLUME_ID) root.write_slots(0, bytes) # Create a file with a known good long name root.mkfile('The quick brown fox jumped over the lazy dog') # Create a file with a known good short name root.mkfile('foo.bar') # Create a file with invalid long name entries (bad checksums) bytes = make_long_dirent('Greetings and felicitations my friends', ATTR_ARCHIVE) bytes = bytes[0:-32] + 'HELLO ' + bytes[-21:] assert len(bytes) % 32 == 0 slots = len(bytes) / 32 slot = root.find_slots(slots) root.write_slots(slot, bytes) subdir = root.mkdir('SubDir') # Create a file with incomplete long name entries # Missing first (LONG_NAME_LAST) entry bytes = make_long_dirent('To be or not to be', ATTR_ARCHIVE)[32:] slots = len(bytes) / 32 slot = subdir.find_slots(slots) subdir.write_slots(slot, bytes) # Missing middle (second) long entry bytes = make_long_dirent('A Man a Plan a Canal Panama', ATTR_ARCHIVE) bytes = bytes[:32] + bytes[64:] slots = len(bytes) / 32 slot = subdir.find_slots(slots) subdir.write_slots(slot, bytes) # Missing last long entry bytes = make_long_dirent('We the People in order to form a more perfect union', ATTR_ARCHIVE) bytes = bytes[0:-64] + bytes[-32:] slots = len(bytes) / 32 slot = subdir.find_slots(slots) subdir.write_slots(slot, bytes) subdir = root.mkdir('Bad Orders') # Bad order value: first bytes = make_long_dirent('One is the loneliest number', ATTR_ARCHIVE) bytes = chr(ord(bytes[0])+7) + bytes[1:] slots = len(bytes) / 32 slot = subdir.find_slots(slots) subdir.write_slots(slot, bytes) # Bad order value: middle bytes = make_long_dirent('It takes two to tango or so they say', ATTR_ARCHIVE) bytes = bytes[:32] + chr(ord(bytes[32])+7) + bytes[33:] slots = len(bytes) / 32 slot = subdir.find_slots(slots) subdir.write_slots(slot, bytes) # Bad order value: last bytes = make_long_dirent('Threes Company becomes Threes A Crowd', ATTR_ARCHIVE) bytes = bytes[:-64] + chr(ord(bytes[-64])+7) + bytes[-63:] slots = len(bytes) / 32 slot = subdir.find_slots(slots) subdir.write_slots(slot, bytes) # Long name entries (valid or not, with no short entry) at end of directory bytes = make_long_dirent('Four score and seven years ago', ATTR_ARCHIVE) bytes = bytes[0:-32] # Remove the short name entry assert len(bytes) % 32 == 0 slots = len(bytes) / 32 slot = root.find_slots(slots) root.write_slots(slot, bytes) v.flush() del v f.close() del f try: launch([fsck, '-n', disk]) except LaunchError: pass launch([fsck, '-y', disk]) launch(['/sbin/fsck_msdos', '-n', disk])