11#!/usr/bin/env python3
2- #
2+ #
33# Cross Platform and Multi Architecture Advanced Binary Emulation Framework
44#
55
6+ from typing import AnyStr , Optional , Union
67from .mapper import QlFsMappedObject
78
9+ ReadableBuffer = Union [bytes , bytearray , memoryview ]
10+
11+
812# Open a file as a Disk
913# host_path: The file path on the host machine.
1014# drive_path: The drive path on the emulated system. e.g. /dev/sda \\.\PHYSICALDRIVE0 0x80
11- #
15+ #
1216# Note: CHS and LBA support is very limited since a raw file doesn't contain enough information.
1317# We simply assume that it is a disk with 1 head, 1 cylinder and (filesize/512) sectors.
18+ #
1419# See: https://en.wikipedia.org/wiki/Cylinder-head-sector
1520# https://en.wikipedia.org/wiki/Logical_block_addressing
1621# http://www.uruk.org/orig-grub/PC_partitioning.txt
22+
1723class QlDisk (QlFsMappedObject ):
1824
19- def __init__ (self , host_path , drive_path , n_heads = 1 , n_cylinders = 1 , sector_size = 512 ):
20- self ._host_path = host_path
25+ # 512 bytes/sector
26+ # 63 sectors/track
27+ # 255 heads (tracks/cylinder)
28+ # 1024 cylinders
29+
30+ def __init__ (self , host_path : AnyStr , drive_path , n_cylinders : int = 1 , n_heads : int = 1 , sector_size : int = 512 ):
2131 self ._drive_path = drive_path
2232 self ._fp = open (host_path , "rb+" )
2333 self ._n_heads = n_heads
2434 self ._n_cylinders = n_cylinders
2535 self ._sector_size = sector_size
2636 self .lseek (0 , 2 )
2737 self ._filesize = self .tell ()
28- self ._n_sectors = (self ._filesize - 1 )// self .sector_size + 1
38+ self ._n_sectors = (self ._filesize - 1 ) // self .sector_size + 1
2939
3040 def __del__ (self ):
3141 if not self .fp .closed :
@@ -51,50 +61,43 @@ def n_cylinders(self):
5161 def sector_size (self ):
5262 return self ._sector_size
5363
54- @property
55- def host_path (self ):
56- return self ._host_path
57-
58- @property
59- def drive_path (self ):
60- return self ._drive_path
61-
6264 @property
6365 def fp (self ):
6466 return self ._fp
6567
6668 # Methods from FsMappedObject
67- def read (self , l ):
68- return self .fp .read (l )
69-
70- def write (self , bs ):
71- return self .fp .write (bs )
69+ def read (self , size : Optional [int ]) -> bytes :
70+ return self .fp .read (size )
7271
73- def lseek (self , offset , origin ):
72+ def write (self , buffer : ReadableBuffer ) -> int :
73+ return self .fp .write (buffer )
74+
75+ def lseek (self , offset : int , origin : int ) -> int :
7476 return self .fp .seek (offset , origin )
75-
76- def tell (self ):
77+
78+ def tell (self ) -> int :
7779 return self .fp .tell ()
7880
79- def close (self ):
80- return self .fp .close ()
81-
81+ def close (self ) -> None :
82+ self .fp .close ()
83+
8284 # Methods for QlDisk
83- def lba (self , cylinder , head , sector ) :
85+ def lba (self , cylinder : int , head : int , sector : int ) -> int :
8486 return (cylinder * self .n_heads + head ) * self ._n_sectors + sector - 1
85-
86- def read_sectors (self , lba , cnt ) :
87+
88+ def read_sectors (self , lba : int , cnt : int ) -> bytes :
8789 self .lseek (self .sector_size * lba , 0 )
88- return self .read (self .sector_size * cnt )
89-
90- def read_chs (self , cylinder , head , sector , cnt ):
90+
91+ return self .read (self .sector_size * cnt )
92+
93+ def read_chs (self , cylinder : int , head : int , sector : int , cnt : int ) -> bytes :
9194 return self .read_sectors (self .lba (cylinder , head , sector ), cnt )
9295
93- def write_sectors (self , lba , cnt , buffer ):
94- if len (buffer ) > self .sector_size * cnt :
95- buffer = buffer [:self .sector_size * cnt ]
96+ def write_sectors (self , lba : int , cnt : int , buffer : ReadableBuffer ) -> int :
97+ buffer = memoryview (buffer )
9698 self .lseek (self .sector_size * lba , 0 )
97- return self .write (buffer )
98-
99- def write_chs (self , cylinder , head , sector , cnt , buffer ):
100- return self .write_sectors (self .lba (cylinder , head , sector ), cnt , buffer )
99+
100+ return self .write (buffer [:self .sector_size * cnt ])
101+
102+ def write_chs (self , cylinder : int , head : int , sector : int , cnt : int , buffer : ReadableBuffer ):
103+ return self .write_sectors (self .lba (cylinder , head , sector ), cnt , buffer )
0 commit comments