2015-07-31 16:41:03 +00:00
|
|
|
from struct import unpack
|
|
|
|
import os
|
|
|
|
|
2015-09-27 23:57:08 +00:00
|
|
|
def readUnpack(bytes, **options):
|
|
|
|
if options.get("type") == 't':
|
2015-10-19 15:59:46 +00:00
|
|
|
#print 'DEBUG: In t'
|
2015-09-27 23:57:08 +00:00
|
|
|
SOS = SOSfile.read(bytes)
|
2015-10-20 00:43:39 +00:00
|
|
|
text_unpacked = unpack('%ss' % bytes, SOS)
|
|
|
|
return ''.join(text_unpacked)
|
2015-09-27 23:57:08 +00:00
|
|
|
|
|
|
|
if options.get("type") == 'b':
|
2015-10-19 15:59:46 +00:00
|
|
|
#print 'DEBUG: In b', bytes
|
2015-09-27 23:57:08 +00:00
|
|
|
SOS = SOSfile.read(bytes)
|
2015-10-19 15:59:46 +00:00
|
|
|
#print 'DEBUG: In b2', bytes, SOS
|
2015-09-27 23:57:08 +00:00
|
|
|
offset_unpacked = unpack ('< H', SOS)
|
2015-10-19 15:59:46 +00:00
|
|
|
#print 'DEBUG: In b3', bytes, SOS
|
2015-09-27 23:57:08 +00:00
|
|
|
return int('.'.join(str(x) for x in offset_unpacked))
|
2015-09-07 17:24:01 +00:00
|
|
|
|
2015-10-27 21:15:59 +00:00
|
|
|
if options.get("type") == '1':
|
|
|
|
SOS = SOSfile.read(bytes)
|
|
|
|
offset_unpacked = unpack ('< B', SOS)
|
|
|
|
return int(ord(SOS))
|
|
|
|
|
2015-11-07 03:52:23 +00:00
|
|
|
def nibblize(byte, **options):
|
|
|
|
if options.get("direction") == 'high':
|
|
|
|
return str(int(hex(byte >> 4), 0))
|
|
|
|
if options.get("direction") == 'low':
|
|
|
|
return str(int(hex(byte & 0x0F), 0))
|
|
|
|
|
|
|
|
|
2015-10-27 21:15:59 +00:00
|
|
|
dev_types ={273: 'Character Device, Write-Only, Formatter',
|
2015-10-28 12:49:36 +00:00
|
|
|
321: 'Character Device, Write-Only, RS232 Printer', # dictionary for types and subtypes
|
2015-10-27 21:15:59 +00:00
|
|
|
577: 'Character Device, Write-Only, Silentype',
|
|
|
|
833: 'Character Device, Write-Only, Parallel Printer',
|
|
|
|
323: 'Character Device, Write-Only, Sound Port',
|
|
|
|
353: 'Character Device, Read-Write, System Console',
|
|
|
|
354: 'Character Device, Read-Write, Graphics Screen',
|
|
|
|
355: 'Character Device, Read-Write, Onboard RS232',
|
|
|
|
356: 'Character Device, Read-Write, Parallel Card',
|
|
|
|
481: 'Block Device, Disk ///',
|
|
|
|
721: 'Block Device, PROFile',
|
|
|
|
4337: 'Block Device, CFFA3000'}
|
|
|
|
|
2015-10-28 22:11:33 +00:00
|
|
|
mfgs = {17491: 'David Schmidt'} # dictionary for manufacturers
|
|
|
|
|
2015-07-31 16:41:03 +00:00
|
|
|
#Clear SCREEN
|
|
|
|
print("\033c");
|
|
|
|
|
|
|
|
#Is File a SOS DRIVER file?
|
2015-09-07 17:24:01 +00:00
|
|
|
|
2015-07-31 16:41:03 +00:00
|
|
|
SOSfile = open('SOSCFFA.DRIVER', 'rb')
|
2015-09-27 23:57:08 +00:00
|
|
|
filetype = readUnpack(8, type = 't')
|
2015-09-07 17:24:01 +00:00
|
|
|
|
2015-10-20 00:43:39 +00:00
|
|
|
if filetype == 'SOS DRVR':
|
2015-09-07 17:24:01 +00:00
|
|
|
print "This is a proper SOS file."
|
2015-09-12 16:09:03 +00:00
|
|
|
print "Filetype is: %s." % (filetype)
|
2015-09-07 17:24:01 +00:00
|
|
|
else:
|
2015-09-30 01:17:26 +00:00
|
|
|
print "Filetype is: %s." % (filetype)
|
2015-09-07 17:24:01 +00:00
|
|
|
print "This is not a proper SOS file"
|
2015-09-30 01:17:26 +00:00
|
|
|
exit()
|
2015-07-31 16:41:03 +00:00
|
|
|
|
2015-10-28 12:49:36 +00:00
|
|
|
rel_offset = readUnpack(2, type = 'b') # read two bytes after SOS DRVR to establish first rel_offset value
|
|
|
|
print "The first relative offset value is", rel_offset, hex(rel_offset) # print out for debug
|
|
|
|
drivers = 0 # this is to keep a running total of drivers.
|
|
|
|
drivers_list=[] # initialize a list to hold dictionaries.
|
2015-09-12 16:09:03 +00:00
|
|
|
|
2015-10-28 12:49:36 +00:00
|
|
|
loop = True # set True for major driver loop
|
2015-10-27 21:15:59 +00:00
|
|
|
while loop : # establish loop to find major drivers
|
2015-10-28 12:49:36 +00:00
|
|
|
driver = {} # intialize a dictionary to hold vaules as we loop
|
|
|
|
SOSfile.seek(rel_offset,1) # jump to location of first driver
|
2015-10-27 21:15:59 +00:00
|
|
|
driver['location'] = SOSfile.tell() # add to driver dictionary 52c
|
|
|
|
rel_offset = readUnpack(2, type = 'b') # 0000 comment length
|
2015-10-28 12:49:36 +00:00
|
|
|
if rel_offset == 0xFFFF: # if we encounter FFFF, no more drivers
|
|
|
|
loop = False # set loop to False to cancel while
|
2015-10-19 15:59:46 +00:00
|
|
|
else :
|
2015-10-27 21:15:59 +00:00
|
|
|
drivers_list.append(driver) # add to drivers_list list
|
|
|
|
SOSfile.seek(rel_offset,1) # seek forward based on contents of rel_offset
|
|
|
|
rel_offset = readUnpack(2, type = 'b') # read 2 bytes and stick into rel_offset
|
|
|
|
SOSfile.seek(rel_offset,1) # seek forward based on contents of rel_offset
|
|
|
|
rel_offset = readUnpack(2, type = 'b') # read 2 bytes and stick into rel_offset
|
2015-10-19 15:59:46 +00:00
|
|
|
|
2015-10-27 21:15:59 +00:00
|
|
|
for i in range(0,len(drivers_list)): # begin loop to grab information from DIB
|
|
|
|
SOSfile.seek(drivers_list[i]['location'],0) # reference SOF and seek to beginning of major driver
|
|
|
|
comment_len = readUnpack(2, type = 'b') # grab comment length (2 bytes)
|
|
|
|
drivers_list[i]['comment_len'] = comment_len # store comment length
|
|
|
|
if comment_len != 0: # if comment length is not 0000
|
|
|
|
comment_txt = readUnpack(comment_len, type = 't') # comment_len bytes as text
|
|
|
|
drivers_list[i]['comment_txt'] = comment_txt # place comment in dictionary
|
2015-10-19 15:59:46 +00:00
|
|
|
else:
|
2015-10-27 21:15:59 +00:00
|
|
|
drivers_list[i]['comment_txt'] = '' # else enter comment as nothing
|
2015-10-28 12:49:36 +00:00
|
|
|
SOSfile.seek(2,1) # skip two bytes immediately following comment or 0000
|
|
|
|
link_ptr = readUnpack(2, type = 'b') # grab link pointer
|
|
|
|
drivers_list[i]['link_ptr'] = link_ptr # store link pointer
|
|
|
|
entry = readUnpack(2, type = 'b') # grab entry field
|
|
|
|
drivers_list[i]['entry'] = entry # store entry field
|
|
|
|
name_len = readUnpack(1, type = '1') # grab one byte for name length
|
|
|
|
drivers_list[i]['name_len'] = name_len # store name length
|
|
|
|
name = readUnpack(name_len, type = 't') # read name based on length
|
|
|
|
drivers_list[i]['name'] = name # store name
|
|
|
|
SOSfile.seek(15 - name_len,1) # skip past remainder of 15-byte long name field
|
|
|
|
flag = readUnpack(1, type = '1') # grab Flag byte
|
|
|
|
if flag == 192: # is flag 0xc0?
|
|
|
|
drivers_list[i]['flag'] = 'ACTIVE, Load on Boundary' # yes, ACTIVE and load on boundary
|
|
|
|
elif flag == 128: # is flag 0x80?
|
|
|
|
drivers_list[i]['flag'] = 'ACTIVE' # insert Flag into dictionary with value ACTIVE
|
2015-10-27 21:15:59 +00:00
|
|
|
else: # otherwise...
|
2015-10-28 12:49:36 +00:00
|
|
|
drivers_list[i]['flag'] = 'INACTIVE' # insert Flag into dictionary with value INACTIVE
|
|
|
|
slot_num = readUnpack(1, type = '1') # grab slot number
|
|
|
|
if slot_num == 0: # check if device has no slot number...
|
2015-10-27 21:15:59 +00:00
|
|
|
drivers_list[i]['slot_num'] = 'None' # ... and indicate so.
|
|
|
|
else: # otherwise...
|
|
|
|
drivers_list[i]['slot_num'] = slot_num # ... enter slot number into the dictionary
|
|
|
|
unit = readUnpack(1, type = '1') # get the unit byte
|
|
|
|
drivers_list[i]['unit'] = unit # store unit in dictionary
|
2015-10-28 22:11:33 +00:00
|
|
|
dev_type = readUnpack(2, type ='b')
|
|
|
|
try:
|
|
|
|
drivers_list[i]['dev_type'] = dev_types[dev_type] # insert device type into dictionary
|
|
|
|
except:
|
|
|
|
drivers_list[i]['dev_type'] = 'Unknown'
|
|
|
|
SOSfile.seek(1,1)
|
|
|
|
block_num = readUnpack(2, type = 'b') # get block_num
|
|
|
|
if block_num != 0: # is block_num not zero?
|
|
|
|
drivers_list[i]['block_num'] = block_num # yes, store retrieved block_num value
|
|
|
|
else: # otherwise...
|
|
|
|
drivers_list[i]['block_num'] = 'Character Device or Undefined' # log field as char device or undefined
|
|
|
|
mfg = readUnpack(2, type = 'b') # read mfg bytes
|
|
|
|
try:
|
2015-11-07 03:52:23 +00:00
|
|
|
drivers_list[i]['mfg'] = mfgs[mfg] # try to match key and place in dictionary
|
2015-10-28 22:11:33 +00:00
|
|
|
except:
|
2015-11-07 03:52:23 +00:00
|
|
|
if 1 <= mfg <= 31: # if exception, check if mfg is between 1 and 31
|
|
|
|
drivers_list[i]['mfg'] = 'Apple Computer' # yes, this is Apple Computer
|
2015-10-28 22:11:33 +00:00
|
|
|
else:
|
2015-11-07 03:52:23 +00:00
|
|
|
drivers_list[i]['mfg'] = 'Unknown' # no, this is unknown. log as such
|
|
|
|
atell = SOSfile.tell()
|
|
|
|
ver_byte0 = readUnpack(1, type = '1') # grab the V/v0 numbers | V = high-nibble, v0 = low-nibble
|
|
|
|
ver_byte1 = readUnpack(1, type = '1') # grab the v1/Q numbers | v1 = high-nibble, Q = low-nibble
|
|
|
|
V = nibblize(ver_byte1, direction = 'high') # grab major version number as string
|
|
|
|
v0 = nibblize(ver_byte1, direction = 'low') # grab first minor version number (v0) as string
|
|
|
|
v1 = nibblize(ver_byte0, direction = 'high') # grab second minor version number (v1) as string
|
|
|
|
Q = nibblize(ver_byte0, direction = 'low') # grab qualifier number. We only care about A (Alpha), B (Beta), or E (Experimental)
|
|
|
|
drivers_list[i]['version'] = V + '.' + v0 + v1 + Q
|
2015-10-19 15:59:46 +00:00
|
|
|
|
2015-11-07 03:52:23 +00:00
|
|
|
#print drivers_list[i]
|
|
|
|
print drivers_list[i]['version']
|
2015-07-31 16:41:03 +00:00
|
|
|
|
|
|
|
SOSfile.close()
|