Initial import of ViperOS
This commit is contained in:
91
Scripts/check_disk.py
Normal file
91
Scripts/check_disk.py
Normal file
@@ -0,0 +1,91 @@
|
||||
import struct
|
||||
f = open(r'd:\Users\TermiNexus\Desktop\TransPyC\ViperOS\disk.img', 'rb')
|
||||
f.seek(0)
|
||||
first_sector = f.read(512)
|
||||
first_byte = first_sector[0]
|
||||
|
||||
if first_byte == 0xEB or first_byte == 0xE9:
|
||||
lba_start = 0
|
||||
bpb = first_sector
|
||||
else:
|
||||
ptype = struct.unpack_from('<B', first_sector, 450)[0]
|
||||
lba_start = struct.unpack_from('<I', first_sector, 454)[0]
|
||||
f.seek(lba_start * 512)
|
||||
bpb = f.read(512)
|
||||
|
||||
bytes_per_sec = struct.unpack_from('<H', bpb, 11)[0]
|
||||
sec_per_clus = struct.unpack_from('<B', bpb, 13)[0]
|
||||
rsvd = struct.unpack_from('<H', bpb, 14)[0]
|
||||
num_fats = struct.unpack_from('<B', bpb, 16)[0]
|
||||
root_clus = struct.unpack_from('<I', bpb, 44)[0]
|
||||
fat_size = struct.unpack_from('<I', bpb, 36)[0]
|
||||
data_start = rsvd + num_fats * fat_size
|
||||
|
||||
print(f'BPS={bytes_per_sec} SPC={sec_per_clus} rsvd={rsvd} NF={num_fats} root_clus={root_clus} fat_size={fat_size} data_start={data_start}')
|
||||
|
||||
def read_dir(f, lba_start, data_start, sec_per_clus, bytes_per_sec, cluster, indent=" ", depth=0):
|
||||
if depth > 5:
|
||||
return
|
||||
cluster_sec = data_start + (cluster - 2) * sec_per_clus
|
||||
f.seek((lba_start + cluster_sec) * 512)
|
||||
dir_data = f.read(sec_per_clus * bytes_per_sec)
|
||||
off = 0
|
||||
lfn_parts = {}
|
||||
while off < len(dir_data):
|
||||
first = dir_data[off]
|
||||
if first == 0:
|
||||
break
|
||||
if first == 0xE5:
|
||||
off += 32
|
||||
lfn_parts = {}
|
||||
continue
|
||||
attr = dir_data[off + 11]
|
||||
if attr == 0x0F: # LFN entry
|
||||
seq = first & 0x3F
|
||||
lfn_chars = []
|
||||
for i in range(5):
|
||||
c = struct.unpack_from('<H', dir_data, off + 2 + i * 2)[0]
|
||||
if c != 0xFFFF and c != 0:
|
||||
lfn_chars.append(chr(c))
|
||||
for i in range(6):
|
||||
c = struct.unpack_from('<H', dir_data, off + 14 + i * 2)[0]
|
||||
if c != 0xFFFF and c != 0:
|
||||
lfn_chars.append(chr(c))
|
||||
for i in range(2):
|
||||
c = struct.unpack_from('<H', dir_data, off + 28 + i * 2)[0]
|
||||
if c != 0xFFFF and c != 0:
|
||||
lfn_chars.append(chr(c))
|
||||
lfn_parts[seq] = ''.join(lfn_chars)
|
||||
off += 32
|
||||
continue
|
||||
if attr == 8: # Volume label
|
||||
off += 32
|
||||
lfn_parts = {}
|
||||
continue
|
||||
name_bytes = dir_data[off:off + 11]
|
||||
name_str = name_bytes.decode('ascii', errors='replace')
|
||||
nt_case = dir_data[off + 12]
|
||||
clus_hi = struct.unpack_from('<H', dir_data, off + 20)[0]
|
||||
clus_lo = struct.unpack_from('<H', dir_data, off + 26)[0]
|
||||
clus = (clus_hi << 16) | clus_lo
|
||||
fsize = struct.unpack_from('<I', dir_data, off + 28)[0]
|
||||
# Reconstruct LFN
|
||||
lfn = ''
|
||||
if lfn_parts:
|
||||
lfn = ''.join(lfn_parts.get(i, '') for i in sorted(lfn_parts.keys()))
|
||||
case_info = ""
|
||||
if nt_case & 0x08:
|
||||
case_info += " [base_lower]"
|
||||
if nt_case & 0x10:
|
||||
case_info += " [ext_lower]"
|
||||
print(f'{indent}SFN=[{name_str}] NT=0x{nt_case:02X}{case_info} LFN="{lfn}" attr=0x{attr:02X} clus={clus} size={fsize}')
|
||||
if attr & 0x10 and clus >= 2:
|
||||
# Skip . and .. entries
|
||||
sfn_name = name_str.rstrip()
|
||||
if sfn_name != '.' and sfn_name != '..':
|
||||
read_dir(f, lba_start, data_start, sec_per_clus, bytes_per_sec, clus, indent + " ", depth + 1)
|
||||
off += 32
|
||||
lfn_parts = {}
|
||||
|
||||
read_dir(f, lba_start, data_start, sec_per_clus, bytes_per_sec, root_clus)
|
||||
f.close()
|
||||
Reference in New Issue
Block a user