Files
@ 8f2355969e7e
Branch filter:
Location: linux-tools/kusbff/floppyemu/__init__.py - annotation
8f2355969e7e
3.9 KiB
text/x-python
Editing labels; Fix inability to format images without initial device change; a little bit of refactoring
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 8f2355969e7e 8f2355969e7e f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 8f2355969e7e 8f2355969e7e f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 d1a9a47788f8 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 d1a9a47788f8 d1a9a47788f8 d1a9a47788f8 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 d1a9a47788f8 d1a9a47788f8 d1a9a47788f8 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 8f2355969e7e 8f2355969e7e 8f2355969e7e f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 f3f4cf108453 8f2355969e7e 8f2355969e7e 8f2355969e7e 8f2355969e7e 8f2355969e7e 8f2355969e7e 8f2355969e7e 8f2355969e7e 8f2355969e7e | import subprocess
import os
SINGLE_DISK_OFFSET = 1572864
MAX_IMAGES_ON_DRIVE = 1000
LABEL_START_OFFSET = 0x2B
LABEL_LENGTH = 11
def get_or_create_empty_image(index, temp_path, size=1440):
filename = 'empty{}.ima'.format(index)
filename = os.path.join(temp_path, filename)
if os.path.isfile(filename):
os.remove(filename)
proc = subprocess.Popen(['mkfs.msdos', '-C', filename, str(size)])
rval = proc.wait()
if rval != 0:
print(proc.stdout.read())
print(proc.stderr.read())
raise Exception('Not created')
return filename
def format_images(device, indexes, temp_path, size=1440, callback=None):
for ipair in indexes:
if isinstance(ipair, int):
image = get_or_create_empty_image(ipair, temp_path, size)
write_image(device, image, ipair)
os.remove(image)
if callback:
callback(indexes, ipair)
else:
for i in range(ipair[0], ipair[1]):
image = get_or_create_empty_image(i, temp_path, size)
write_image(device, image, i)
os.remove(image)
if callback:
callback(ipair, i)
def write_image(device, path, index=0):
"""
Writes image from path to device at specified index
:param device:
:param index:
:param path:
:return:
"""
with open(device, 'r+b') as dfile:
offset = SINGLE_DISK_OFFSET * index
dfile.seek(offset)
with open(path, 'rb') as ifile:
fdata = ifile.read()
dfile.write(fdata)
def read_image(device, path, index=0):
"""
Reads image at specified index from device into path
:param device:
:param path:
:param index:
:return:
"""
with open(device, 'rb') as dfile:
offset = SINGLE_DISK_OFFSET * index
dfile.seek(offset)
bootsector = dfile.read(512)
if bootsector[-1] == 0xAA and bootsector[-2] == 0x55:
# FAT12 image
sectorsize = bootsector[0xB] + (bootsector[0xC] << 8)
sectorcount = bootsector[0x13] + (bootsector[0x14] << 8)
with open(path, 'xb') as ifile:
dfile.seek(offset)
fdata = dfile.read(sectorsize * sectorcount)
ifile.write(fdata)
def list_images(device):
"""
Reads device and lists all of images on it
:param device:
:return: (label, size)
"""
rval = []
with open(device, 'rb') as dfile:
dfile.seek(0, 2)
disks = min(dfile.tell() / SINGLE_DISK_OFFSET, MAX_IMAGES_ON_DRIVE)
dfile.seek(0)
while len(rval) < disks:
bootsector = dfile.read(512)
label = None
if bootsector[0] == 0xEB or bootsector[0] == 0xE9:
sectorsize = bootsector[0xB] + (bootsector[0xC] << 8)
sectorcount = bootsector[0x13] + (bootsector[0x14] << 8)
disksize = sectorsize * sectorcount
if bootsector[0x26] == 0x29:
# label probably exists.
# As an additional precaution check fs type.
# If it's valid, then get label, otherwise consider disk unlabeled
if bootsector[0x36:0x3E] in (b'FAT12 ', b'FAT16 ', b'FAT '):
label = bootsector[LABEL_START_OFFSET:LABEL_START_OFFSET + LABEL_LENGTH].decode(
encoding='cp1251'
)
dfile.seek(SINGLE_DISK_OFFSET - 512, 1)
else:
disksize = 0
dfile.seek(SINGLE_DISK_OFFSET - 512, 1)
rval.append((label, disksize))
return rval
def update_label(device, index, label):
offset = SINGLE_DISK_OFFSET * index
label = label[0:11]
label = label + ' ' * (LABEL_LENGTH - len(label))
with open(device, 'wb') as dfile:
dfile.seek(offset + LABEL_START_OFFSET, 0)
dfile.write(label.encode(encoding='cp1251'))
|