public static async Task <LoadSegBlock> Parse(byte[] blockBytes) { var blockStream = new MemoryStream(blockBytes); var identifier = await blockStream.ReadAsciiString(); // Identifier 32 bit word : 'LSEG' if (!identifier.Equals(BlockIdentifiers.LoadSegBlock)) { throw new IOException("Invalid load seg block identifier"); } var size = await blockStream.ReadUInt32(); // Size of the structure for checksums var checksum = await blockStream.ReadInt32(); // Checksum of the structure var hostId = await blockStream.ReadUInt32(); // SCSI Target ID of host var nextLoadSegBlock = await blockStream.ReadInt32(); // block number of the next LoadSegBlock, -1 for last var calculatedChecksum = await BlockHelper.CalculateChecksum(blockBytes, 8); if (checksum != calculatedChecksum) { throw new IOException("Invalid load seg block checksum"); } var length = (size - 5) * 4; var data = new byte[length]; Array.Copy(blockBytes, 5 * 4, data, 0, length); return(new LoadSegBlock { BlockBytes = blockBytes, Checksum = checksum, HostId = hostId, NextLoadSegBlock = nextLoadSegBlock, Data = data }); }
public static async Task <BadBlock> Parse(byte[] blockBytes) { var blockStream = new MemoryStream(blockBytes); var identifier = await blockStream.ReadAsciiString(); // Identifier 32 bit word : 'BADB' if (!identifier.Equals(BlockIdentifiers.BadBlock)) { throw new IOException("Invalid bad block identifier"); } await blockStream.ReadUInt32(); // Size of the structure for checksums var checksum = await blockStream.ReadInt32(); // Checksum of the structure var hostId = await blockStream.ReadUInt32(); // SCSI Target ID of host, not really used var nextBadBlock = await blockStream.ReadUInt32(); // next BadBlock block var calculatedChecksum = await BlockHelper.CalculateChecksum(blockBytes, 8); if (checksum != calculatedChecksum) { throw new IOException("Invalid bad block checksum"); } var data = await blockStream.ReadBytes(((blockBytes.Length / 4) - 6) / 2); return(new BadBlock { BlockBytes = blockBytes, Checksum = checksum, HostId = hostId, NextBadBlock = nextBadBlock, Data = data }); }
public static async Task <FileSystemHeaderBlock> Parse(byte[] blockBytes) { var blockStream = new MemoryStream(blockBytes); var identifier = await blockStream.ReadAsciiString(); // Identifier 32 bit word : 'RDSK' if (!identifier.Equals(BlockIdentifiers.FileSystemHeaderBlock)) { throw new IOException("Invalid file system header block identifier"); } await blockStream.ReadUInt32(); // Size of the structure for checksums var checksum = await blockStream.ReadInt32(); // Checksum of the structure var hostId = await blockStream.ReadUInt32(); // SCSI Target ID of host, not really used var nextFileSysHeaderBlock = await blockStream.ReadUInt32(); // Block number of the next FileSysHeaderBlock var flags = await blockStream.ReadUInt32(); // Flags // read reserved, unused word for (var i = 0; i < 2; i++) { await blockStream.ReadBytes(4); } var dosType = await blockStream .ReadBytes(4); // # Dostype of the file system, file system description: match this with partition environment's DE_DOSTYPE entry var version = await blockStream.ReadUInt32(); // filesystem version 0x0027001b == 39.27 var patchFlags = await blockStream.ReadUInt32(); var type = await blockStream.ReadUInt32(); var task = await blockStream.ReadUInt32(); var fileSysLock = await blockStream.ReadUInt32(); var handler = await blockStream.ReadUInt32(); var stackSize = await blockStream.ReadUInt32(); var priority = await blockStream.ReadInt32(); var startup = await blockStream.ReadInt32(); var segListBlocks = await blockStream.ReadInt32(); // first of linked list of LoadSegBlocks var globalVec = await blockStream.ReadInt32(); blockStream.Seek(172, SeekOrigin.Begin); var fileSystemName = await blockStream.ReadNullTerminatedString(); var calculatedChecksum = await BlockHelper.CalculateChecksum(blockBytes, 8); if (checksum != calculatedChecksum) { throw new IOException("Invalid file system header block checksum"); } return(new FileSystemHeaderBlock { BlockBytes = blockBytes, Checksum = checksum, HostId = hostId, NextFileSysHeaderBlock = nextFileSysHeaderBlock, Flags = flags, DosType = dosType, Version = version, PatchFlags = patchFlags, Type = type, Task = task, Lock = fileSysLock, Handler = handler, StackSize = stackSize, Priority = priority, Startup = startup, SegListBlocks = segListBlocks, GlobalVec = globalVec, FileSystemName = fileSystemName }); }
public static async Task <RigidDiskBlock> Parse(byte[] blockBytes) { var blockStream = new MemoryStream(blockBytes); var magic = await blockStream.ReadAsciiString(); // Identifier 32 bit word : 'RDSK' if (!magic.Equals(BlockIdentifiers.RigidDiskBlock)) { return(null); } await blockStream.ReadUInt32(); // Size of the structure for checksums var checksum = await blockStream.ReadInt32(); // Checksum of the structure var hostId = await blockStream.ReadUInt32(); // SCSI Target ID of host, not really used var blockSize = await blockStream.ReadUInt32(); // Size of disk blocks var flags = await blockStream.ReadUInt32(); // RDB Flags var badBlockList = await blockStream.ReadUInt32(); // Bad block list var partitionList = await blockStream.ReadUInt32(); // Partition list var fileSysHdrList = await blockStream.ReadUInt32(); // File system header list var driveInitCode = await blockStream.ReadUInt32(); // Drive specific init code var bootBlockList = await blockStream.ReadUInt32(); // Amiga OS 4 Boot Blocks // skip reserved blockStream.Seek(4 * 5, SeekOrigin.Current); // physical drive characteristics var cylinders = await blockStream.ReadUInt32(); // Number of the cylinders of the drive var sectors = await blockStream.ReadUInt32(); // Number of sectors of the drive var heads = await blockStream.ReadUInt32(); // Number of heads of the drive var interleave = await blockStream.ReadUInt32(); // Interleave var parkingZone = await blockStream.ReadUInt32(); // Head parking cylinder // skip reserved blockStream.Seek(4 * 3, SeekOrigin.Current); var writePreComp = await blockStream.ReadUInt32(); // Starting cylinder of write pre-compensation var reducedWrite = await blockStream.ReadUInt32(); // Starting cylinder of reduced write current var stepRate = await blockStream.ReadUInt32(); // Step rate of the drive // skip reserved blockStream.Seek(4 * 5, SeekOrigin.Current); // logical drive characteristics var rdbBlockLo = await blockStream.ReadUInt32(); // low block of range reserved for hardblocks var rdbBlockHi = await blockStream.ReadUInt32(); // high block of range for these hardblocks var loCylinder = await blockStream.ReadUInt32(); // low cylinder of partitionable disk area var hiCylinder = await blockStream.ReadUInt32(); // high cylinder of partitionable data area var cylBlocks = await blockStream.ReadUInt32(); // number of blocks available per cylinder var autoParkSeconds = await blockStream.ReadUInt32(); // zero for no auto park var highRsdkBlock = await blockStream.ReadUInt32(); // highest block used by RDSK (not including replacement bad blocks) // skip reserved blockStream.Seek(4, SeekOrigin.Current); // drive identification var diskVendor = (await blockStream.ReadBytes(8)).ReadNullTerminatedString().Trim(); var diskProduct = (await blockStream.ReadBytes(16)).ReadNullTerminatedString().Trim(); var diskRevision = (await blockStream.ReadBytes(4)).ReadNullTerminatedString().Trim(); var controllerVendor = (await blockStream.ReadBytes(8)).ReadNullTerminatedString().Trim(); var controllerProduct = (await blockStream.ReadBytes(16)).ReadNullTerminatedString().Trim(); var controllerRevision = (await blockStream.ReadBytes(4)).ReadNullTerminatedString().Trim(); // skip reserved blockStream.Seek(4, SeekOrigin.Current); // calculate size of disk in bytes var diskSize = (long)cylinders * heads * sectors * blockSize; var calculatedChecksum = await BlockHelper.CalculateChecksum(blockBytes, 8); if (checksum != calculatedChecksum) { throw new Exception("Invalid rigid disk block checksum"); } return(new RigidDiskBlock { BlockBytes = blockBytes, Checksum = checksum, HostId = hostId, BlockSize = blockSize, Flags = flags, BadBlockList = badBlockList, PartitionList = partitionList, FileSysHdrList = fileSysHdrList, DriveInitCode = driveInitCode, BootBlockList = bootBlockList, Cylinders = cylinders, Sectors = sectors, Heads = heads, Interleave = interleave, ParkingZone = parkingZone, WritePreComp = writePreComp, ReducedWrite = reducedWrite, StepRate = stepRate, RdbBlockLo = rdbBlockLo, RdbBlockHi = rdbBlockHi, LoCylinder = loCylinder, HiCylinder = hiCylinder, CylBlocks = cylBlocks, AutoParkSeconds = autoParkSeconds, HighRsdkBlock = highRsdkBlock, DiskVendor = diskVendor, DiskProduct = diskProduct, DiskRevision = diskRevision, ControllerVendor = controllerVendor, ControllerProduct = controllerProduct, ControllerRevision = controllerRevision, DiskSize = diskSize }); }
public static async Task <PartitionBlock> Parse(RigidDiskBlock rigidDiskBlock, byte[] blockBytes) { var blockStream = new MemoryStream(blockBytes); var magic = await blockStream.ReadAsciiString(); // Identifier 32 bit word : 'PART' if (!magic.Equals(BlockIdentifiers.PartitionBlock)) { return(null); } await blockStream.ReadUInt32(); // Size of the structure for checksums var checksum = await blockStream.ReadInt32(); // Checksum of the structure var hostId = await blockStream.ReadUInt32(); // SCSI Target ID of host, not really used var nextPartitionBlock = await blockStream.ReadUInt32(); // Block number of the next PartitionBlock var flags = await blockStream.ReadUInt32(); // Part Flags (NOMOUNT and BOOTABLE) // skip reserved blockStream.Seek(4 * 2, SeekOrigin.Current); var devFlags = await blockStream.ReadUInt32(); // Preferred flags for OpenDevice var driveNameLength = (await blockStream.ReadBytes(1)).FirstOrDefault(); // Preferred DOS device name: BSTR form var driveName = await blockStream.ReadString(driveNameLength); // # Preferred DOS device name: BSTR form if (driveNameLength < 31) { await blockStream.ReadBytes(31 - driveNameLength); } // skip reserved blockStream.Seek(4 * 15, SeekOrigin.Current); var sizeOfVector = await blockStream.ReadUInt32(); // Size of Environment vector var sizeBlock = await blockStream.ReadUInt32(); // Size of the blocks in 32 bit words, usually 128 var secOrg = await blockStream.ReadUInt32(); // Not used; must be 0 var surfaces = await blockStream.ReadUInt32(); // Number of heads (surfaces) var sectors = await blockStream.ReadUInt32(); // Disk sectors per block, used with SizeBlock, usually 1 var blocksPerTrack = await blockStream.ReadUInt32(); // Blocks per track. drive specific var reserved = await blockStream.ReadUInt32(); // DOS reserved blocks at start of partition. var preAlloc = await blockStream.ReadUInt32(); // DOS reserved blocks at end of partition var interleave = await blockStream.ReadUInt32(); // Not used, usually 0 var lowCyl = await blockStream.ReadUInt32(); // First cylinder of the partition var highCyl = await blockStream.ReadUInt32(); // Last cylinder of the partition var numBuffer = await blockStream.ReadUInt32(); // Initial # DOS of buffers. var bufMemType = await blockStream.ReadUInt32(); // Type of mem to allocate for buffers var maxTransfer = await blockStream.ReadUInt32(); // Max number of bytes to transfer at a time var mask = await blockStream.ReadUInt32(); // Address Mask to block out certain memory var bootPriority = await blockStream.ReadUInt32(); // Boot priority for autoboot var dosType = await blockStream.ReadBytes(4); // # Dostype of the file system var baud = await blockStream.ReadUInt32(); // Baud rate for serial handler var control = await blockStream.ReadUInt32(); // Control word for handler/filesystem var bootBlocks = await blockStream.ReadUInt32(); // Number of blocks containing boot code // skip reserved blockStream.Seek(4 * 12, SeekOrigin.Current); // calculate size of partition in bytes var partitionSize = (long)(highCyl - lowCyl + 1) * surfaces * blocksPerTrack * rigidDiskBlock.BlockSize; var calculatedChecksum = await BlockHelper.CalculateChecksum(blockBytes, 8); if (checksum != calculatedChecksum) { throw new Exception("Invalid partition block checksum"); } var fileSystemBlockSize = sizeBlock * 4; return(new PartitionBlock { BlockBytes = blockBytes, Checksum = checksum, HostId = hostId, NextPartitionBlock = nextPartitionBlock, Flags = flags, DevFlags = devFlags, DriveName = driveName, SizeOfVector = sizeOfVector, SizeBlock = sizeBlock, SecOrg = secOrg, Surfaces = surfaces, Sectors = sectors, BlocksPerTrack = blocksPerTrack, Reserved = reserved, PreAlloc = preAlloc, Interleave = interleave, LowCyl = lowCyl, HighCyl = highCyl, NumBuffer = numBuffer, BufMemType = bufMemType, MaxTransfer = maxTransfer, Mask = mask, BootPriority = bootPriority, DosType = dosType, Baud = baud, Control = control, BootBlocks = bootBlocks, PartitionSize = partitionSize, FileSystemBlockSize = fileSystemBlockSize, }); }