public static async Task <IEnumerable <LoadSegBlock> > Read(
            RigidDiskBlock rigidDiskBlock, FileSystemHeaderBlock fileSystemHeaderBlock, Stream stream)
        {
            var loadSegBlocks = new List <LoadSegBlock>();

            var segListBlock = fileSystemHeaderBlock.SegListBlocks;

            do
            {
                // calculate seg list block offset
                var segListBlockOffset = rigidDiskBlock.BlockSize * segListBlock;

                // seek partition block offset
                stream.Seek(segListBlockOffset, SeekOrigin.Begin);

                // read block
                var block = await BlockHelper.ReadBlock(stream);

                // parse file system header block
                var loadSegBlock = await Parse(block);

                loadSegBlocks.Add(loadSegBlock);

                // get next partition list block and increase partition number
                segListBlock = loadSegBlock.NextLoadSegBlock;
            } while (segListBlock > 0);

            return(loadSegBlocks);
        }
Beispiel #2
0
        public static void ResetBadBlockPointers(RigidDiskBlock rigidDiskBlock)
        {
            rigidDiskBlock.BadBlockList = 0;

            foreach (var badBlock in rigidDiskBlock.BadBlocks)
            {
                ResetBadBlockPointers(badBlock);
            }
        }
Beispiel #3
0
        public static void ResetFileSystemHeaderBlockPointers(RigidDiskBlock rigidDiskBlock)
        {
            rigidDiskBlock.FileSysHdrList = 0;

            foreach (var fileSystemHeaderBlock in rigidDiskBlock.FileSystemHeaderBlocks)
            {
                ResetFileSystemHeaderBlockPointers(fileSystemHeaderBlock);
            }
        }
Beispiel #4
0
        public static void ResetPartitionBlockPointers(RigidDiskBlock rigidDiskBlock)
        {
            rigidDiskBlock.PartitionList = 0;

            foreach (var partitionBlock in rigidDiskBlock.PartitionBlocks)
            {
                ResetPartitionBlockPointers(partitionBlock);
            }
        }
        public static async Task <IEnumerable <PartitionBlock> > Read(RigidDiskBlock rigidDiskBlock, Stream stream)
        {
            if (rigidDiskBlock.PartitionList == BlockIdentifiers.EndOfBlock)
            {
                return(Enumerable.Empty <PartitionBlock>());
            }


            // get partition list block and set partition number to 1
            var partitionList = rigidDiskBlock.PartitionList;

            var partitionBlocks = new List <PartitionBlock>();

            do
            {
                // calculate partition block offset
                var partitionBlockOffset = rigidDiskBlock.BlockSize * partitionList;

                // seek partition block offset
                stream.Seek(partitionBlockOffset, SeekOrigin.Begin);

                // read block
                var blockBytes = await BlockHelper.ReadBlock(stream);

                // read partition block
                var partitionBlock = await Parse(rigidDiskBlock, blockBytes);

                // fail, if partition block is null
                if (partitionBlock == null)
                {
                    throw new IOException("Invalid partition block");
                }

                partitionBlocks.Add(partitionBlock);

                // get next partition list block and increase partition number
                partitionList = partitionBlock.NextPartitionBlock;
            } while (partitionList > 0 && partitionList != BlockIdentifiers.EndOfBlock);

            rigidDiskBlock.PartitionBlocks = partitionBlocks;

            rigidDiskBlock.FileSystemHeaderBlocks =
                await FileSystemHeaderBlockReader.Read(rigidDiskBlock, stream);

            return(partitionBlocks);
        }
        public static async Task <IEnumerable <BadBlock> > Read(RigidDiskBlock rigidDiskBlock, Stream stream)
        {
            if (rigidDiskBlock == null)
            {
                throw new ArgumentNullException(nameof(rigidDiskBlock));
            }
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }

            if (rigidDiskBlock.BadBlockList == BlockIdentifiers.EndOfBlock)
            {
                return(Enumerable.Empty <BadBlock>());
            }

            var badBlocks = new List <BadBlock>();

            var badBlockList = rigidDiskBlock.BadBlockList;

            do
            {
                // calculate block offset
                var blockOffset = rigidDiskBlock.BlockSize * badBlockList;

                // seek block offset
                stream.Seek(blockOffset, SeekOrigin.Begin);

                // read block
                var block = await BlockHelper.ReadBlock(stream);

                // read rigid disk block
                var badBlock = await Parse(block);

                badBlocks.Add(badBlock);

                // get next partition list block and increase partition number
                badBlockList = badBlock.NextBadBlock;
            } while (badBlockList > 0 && badBlockList != BlockIdentifiers.EndOfBlock);

            return(badBlocks);
        }
        public static async Task <IEnumerable <FileSystemHeaderBlock> > Read(
            RigidDiskBlock rigidDiskBlock, Stream stream)
        {
            if (rigidDiskBlock.FileSysHdrList == BlockIdentifiers.EndOfBlock)
            {
                return(Enumerable.Empty <FileSystemHeaderBlock>());
            }

            var fileSystemHeaderBlocks = new List <FileSystemHeaderBlock>();

            var fileSysHdrList = rigidDiskBlock.FileSysHdrList;

            do
            {
                // calculate file system header block offset
                var fileSystemHeaderBlockOffset = rigidDiskBlock.BlockSize * fileSysHdrList;

                // seek partition block offset
                stream.Seek(fileSystemHeaderBlockOffset, SeekOrigin.Begin);

                // read block
                var block = await BlockHelper.ReadBlock(stream);

                // parse file system header block
                var fileSystemHeaderBlock = await Parse(block);

                fileSystemHeaderBlocks.Add(fileSystemHeaderBlock);

                // get next partition list block and increase partition number
                fileSysHdrList = fileSystemHeaderBlock.NextFileSysHeaderBlock;
            } while (fileSysHdrList > 0 && fileSysHdrList != BlockIdentifiers.EndOfBlock);

            foreach (var fileSystemHeaderBlock in fileSystemHeaderBlocks)
            {
                fileSystemHeaderBlock.LoadSegBlocks =
                    await LoadSegBlockReader.Read(rigidDiskBlock, fileSystemHeaderBlock, stream);
            }

            return(fileSystemHeaderBlocks);
        }
Beispiel #8
0
        public static RigidDiskBlock Create(long size)
        {
            size = size.ToSectorSize();
            var rigidDiskBlock = new RigidDiskBlock();

            var blocksPerCylinder = rigidDiskBlock.Heads * rigidDiskBlock.Sectors;
            var cylinderSize      = blocksPerCylinder * rigidDiskBlock.BlockSize;
            var cylinders         = (uint)Math.Floor((double)size / cylinderSize);

            rigidDiskBlock.DiskSize     = (long)cylinders * cylinderSize;
            rigidDiskBlock.Cylinders    = cylinders;
            rigidDiskBlock.ParkingZone  = cylinders;
            rigidDiskBlock.ReducedWrite = cylinders;
            rigidDiskBlock.WritePreComp = cylinders;

            var rdbEndOffset = rigidDiskBlock.RdbBlockHi * 512;

            rigidDiskBlock.LoCylinder = (uint)Math.Ceiling((double)rdbEndOffset / cylinderSize);
            rigidDiskBlock.HiCylinder = rigidDiskBlock.Cylinders - 1;

            return(rigidDiskBlock);
        }
        public static PartitionBlock Create(RigidDiskBlock rigidDiskBlock, byte[] dosType, string driveName, long size = 0, bool bootable = false)
        {
            var lastPartitionBlock = rigidDiskBlock.PartitionBlocks.LastOrDefault();
            var lowCyl             = lastPartitionBlock == null ? rigidDiskBlock.LoCylinder : lastPartitionBlock.HighCyl + 1;

            uint cylinders;

            if (size > 0)
            {
                size = size.ToSectorSize();
                var blocksPerCylinder = rigidDiskBlock.Heads * rigidDiskBlock.Sectors;
                cylinders = (uint)Math.Floor((double)size / (blocksPerCylinder * rigidDiskBlock.BlockSize));
            }
            else
            {
                cylinders = lastPartitionBlock == null
                    ? rigidDiskBlock.Cylinders
                    : rigidDiskBlock.Cylinders - lowCyl;
            }

            var highCyl = lowCyl + cylinders - 1 > rigidDiskBlock.HiCylinder
                ? rigidDiskBlock.HiCylinder
                : lowCyl + cylinders - 1;

            var partitionBlock = new PartitionBlock
            {
                PartitionSize = cylinders * rigidDiskBlock.Heads * rigidDiskBlock.Sectors * rigidDiskBlock.BlockSize,
                DosType       = dosType,
                DriveName     = driveName,
                Flags         = bootable ? (uint)PartitionFlagsEnum.Bootable : 0,
                LowCyl        = lowCyl,
                HighCyl       = highCyl
            };

            return(partitionBlock);
        }
Beispiel #10
0
        public static async Task <byte[]> BuildBlock(RigidDiskBlock rigidDiskBlock)
        {
            var blockStream =
                new MemoryStream(rigidDiskBlock.BlockBytes == null || rigidDiskBlock.BlockBytes.Length == 0
                    ? new byte[BlockSize.RigidDiskBlock * 4]
                    : rigidDiskBlock.BlockBytes);

            await blockStream.WriteAsciiString(BlockIdentifiers.RigidDiskBlock);

            await blockStream.WriteLittleEndianUInt32(BlockSize.RigidDiskBlock); // size

            // skip checksum, calculated when block is built
            blockStream.Seek(4, SeekOrigin.Current);

            await blockStream.WriteLittleEndianUInt32(rigidDiskBlock.HostId);         // SCSI Target ID of host, not really used

            await blockStream.WriteLittleEndianUInt32(rigidDiskBlock.BlockSize);      // Size of disk blocks

            await blockStream.WriteLittleEndianUInt32(rigidDiskBlock.Flags);          // RDB Flags

            await blockStream.WriteLittleEndianUInt32(rigidDiskBlock.BadBlockList);   // Bad block list

            await blockStream.WriteLittleEndianUInt32(rigidDiskBlock.PartitionList);  // Partition list

            await blockStream.WriteLittleEndianUInt32(rigidDiskBlock.FileSysHdrList); // File system header list

            await blockStream.WriteLittleEndianUInt32(rigidDiskBlock.DriveInitCode);  // Drive specific init code

            await blockStream.WriteLittleEndianUInt32(rigidDiskBlock.BootBlockList);  // Amiga OS 4 Boot Blocks

            // read reserved, unused word, need to be set to $ffffffff
            var reservedBytes = new byte[] { 255, 255, 255, 255 };

            for (var i = 0; i < 5; i++)
            {
                await blockStream.WriteBytes(reservedBytes);
            }

            // physical drive characteristics
            await blockStream.WriteLittleEndianUInt32(rigidDiskBlock.Cylinders);   // Number of the cylinders of the drive

            await blockStream.WriteLittleEndianUInt32(rigidDiskBlock.Sectors);     // Number of sectors of the drive

            await blockStream.WriteLittleEndianUInt32(rigidDiskBlock.Heads);       // Number of heads of the drive

            await blockStream.WriteLittleEndianUInt32(rigidDiskBlock.Interleave);  // Interleave

            await blockStream.WriteLittleEndianUInt32(rigidDiskBlock.ParkingZone); // Head parking cylinder

            // read reserved, unused word, need to be set to $ffffffff
            reservedBytes = new byte[4];
            for (var i = 0; i < 3; i++)
            {
                await blockStream.WriteBytes(reservedBytes);
            }

            await blockStream.WriteLittleEndianUInt32(rigidDiskBlock
                                                      .WritePreComp); // Starting cylinder of write pre-compensation

            await blockStream.WriteLittleEndianUInt32(rigidDiskBlock
                                                      .ReducedWrite);           // Starting cylinder of reduced write current

            await blockStream.WriteLittleEndianUInt32(rigidDiskBlock.StepRate); // Step rate of the drive

            // read reserved, unused word, need to be set to $ffffffff
            for (var i = 0; i < 5; i++)
            {
                await blockStream.WriteBytes(reservedBytes);
            }

            // logical drive characteristics
            await blockStream.WriteLittleEndianUInt32(rigidDiskBlock
                                                      .RdbBlockLo); // low block of range reserved for hardblocks

            await blockStream.WriteLittleEndianUInt32(rigidDiskBlock
                                                      .RdbBlockHi); // high block of range for these hardblocks

            await blockStream.WriteLittleEndianUInt32(rigidDiskBlock
                                                      .LoCylinder); // low cylinder of partitionable disk area

            await blockStream.WriteLittleEndianUInt32(rigidDiskBlock
                                                      .HiCylinder); // high cylinder of partitionable data area

            await blockStream.WriteLittleEndianUInt32(rigidDiskBlock
                                                      .CylBlocks);                     // number of blocks available per cylinder

            await blockStream.WriteLittleEndianUInt32(rigidDiskBlock.AutoParkSeconds); // zero for no auto park

            await blockStream.WriteLittleEndianUInt32(rigidDiskBlock
                                                      .HighRsdkBlock); // highest block used by RDSK (not including replacement bad blocks)

            await blockStream.WriteBytes(reservedBytes);               // read reserved, unused word

            // drive identification
            await blockStream.WriteString(rigidDiskBlock.DiskVendor, 8, 32);

            await blockStream.WriteString(rigidDiskBlock.DiskProduct, 16, 32);

            await blockStream.WriteString(rigidDiskBlock.DiskRevision, 4, 32);

            // write controller vendor
            if (!string.IsNullOrWhiteSpace(rigidDiskBlock.ControllerVendor))
            {
                await blockStream.WriteString(rigidDiskBlock.ControllerVendor, 8, 32);
            }
            else
            {
                await blockStream.WriteBytes(new byte[8]);
            }

            // write controller product
            if (!string.IsNullOrWhiteSpace(rigidDiskBlock.ControllerProduct))
            {
                await blockStream.WriteString(rigidDiskBlock.ControllerProduct, 16, 32);
            }
            else
            {
                await blockStream.WriteBytes(new byte[16]);
            }

            // write controller revision
            if (!string.IsNullOrWhiteSpace(rigidDiskBlock.ControllerRevision))
            {
                await blockStream.WriteString(rigidDiskBlock.ControllerRevision, 4, 32);
            }
            else
            {
                await blockStream.WriteBytes(new byte[4]);
            }

            await blockStream.WriteBytes(reservedBytes); // read reserved, unused word

            // calculate and update checksum
            var blockBytes = blockStream.ToArray();

            rigidDiskBlock.Checksum = await BlockHelper.UpdateChecksum(blockBytes, 8);

            rigidDiskBlock.BlockBytes = blockBytes;

            return(blockBytes);
        }
Beispiel #11
0
        public static async Task WriteBlock(RigidDiskBlock rigidDiskBlock, Stream stream)
        {
            // update block pointers to maintain rigid disk block structure
            BlockHelper.UpdateBlockPointers(rigidDiskBlock);

            // seek rigid disk block offset
            stream.Seek(rigidDiskBlock.RdbBlockLo * 512, SeekOrigin.Begin);

            var rigidDiskBlockBytes = await BuildBlock(rigidDiskBlock);

            await stream.WriteBytes(rigidDiskBlockBytes);

            if (rigidDiskBlock.PartitionList != BlockIdentifiers.EndOfBlock)
            {
                // seek partition block index offset
                stream.Seek(rigidDiskBlock.PartitionList * 512, SeekOrigin.Begin);

                foreach (var partitionBlock in rigidDiskBlock.PartitionBlocks)
                {
                    var partitionBlockBytes = await PartitionBlockWriter.BuildBlock(partitionBlock);

                    await stream.WriteBytes(partitionBlockBytes);

                    if (partitionBlock.NextPartitionBlock == BlockIdentifiers.EndOfBlock)
                    {
                        break;
                    }

                    // seek next partition block index offset
                    stream.Seek(partitionBlock.NextPartitionBlock * 512, SeekOrigin.Begin);
                }
            }

            if (rigidDiskBlock.FileSysHdrList != BlockIdentifiers.EndOfBlock)
            {
                // seek file system header block index offset
                stream.Seek(rigidDiskBlock.FileSysHdrList * 512, SeekOrigin.Begin);

                foreach (var fileSystemHeaderBlock in rigidDiskBlock.FileSystemHeaderBlocks)
                {
                    var fileSystemHeaderBytes = await FileSystemHeaderBlockWriter.BuildBlock(fileSystemHeaderBlock);

                    await stream.WriteBytes(fileSystemHeaderBytes);

                    // seek load seg block index offset
                    stream.Seek(fileSystemHeaderBlock.SegListBlocks * 512, SeekOrigin.Begin);

                    foreach (var loadSegBlock in fileSystemHeaderBlock.LoadSegBlocks)
                    {
                        var loadSegBlockBytes = await LoadSegBlockWriter.BuildBlock(loadSegBlock);

                        await stream.WriteBytes(loadSegBlockBytes);

                        if (loadSegBlock.NextLoadSegBlock == -1)
                        {
                            break;
                        }

                        // seek next load seg block index offset
                        stream.Seek(loadSegBlock.NextLoadSegBlock * 512, SeekOrigin.Begin);
                    }

                    if (fileSystemHeaderBlock.NextFileSysHeaderBlock == BlockIdentifiers.EndOfBlock)
                    {
                        break;
                    }

                    // seek next file system header block index offset
                    stream.Seek(fileSystemHeaderBlock.NextFileSysHeaderBlock * 512, SeekOrigin.Begin);
                }
            }

            if (rigidDiskBlock.BadBlockList != BlockIdentifiers.EndOfBlock)
            {
                // seek bad block index offset
                stream.Seek(rigidDiskBlock.BadBlockList * 512, SeekOrigin.Begin);

                foreach (var badBlock in rigidDiskBlock.BadBlocks)
                {
                    var badBlockBytes = await BadBlockWriter.BuildBlock(badBlock);

                    await stream.WriteBytes(badBlockBytes);

                    if (badBlock.NextBadBlock == BlockIdentifiers.EndOfBlock)
                    {
                        break;
                    }

                    // seek next bad block index offset
                    stream.Seek(badBlock.NextBadBlock * 512, SeekOrigin.Begin);
                }
            }
        }
        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,
            });
        }
Beispiel #13
0
        /// <summary>
        /// update block pointers to maintain rigid disk block structure. required when changes to rigid disk block needs block pointers updated like adding or deleting partition blocks
        /// </summary>
        /// <param name="rigidDiskBlock"></param>
        public static void UpdateBlockPointers(RigidDiskBlock rigidDiskBlock)
        {
            var highRsdkBlock = rigidDiskBlock.RdbBlockLo;

            var partitionBlocks = rigidDiskBlock.PartitionBlocks.ToList();

            var rigidDiskBlockIndex = rigidDiskBlock.RdbBlockLo;
            var partitionBlockIndex = partitionBlocks.Count > 0 ? rigidDiskBlockIndex + 1 : BlockIdentifiers.EndOfBlock;

            var partitionsChanged = rigidDiskBlock.PartitionList != partitionBlockIndex;

            rigidDiskBlock.PartitionList = partitionBlockIndex;

            for (var p = 0; p < partitionBlocks.Count; p++)
            {
                var partitionBlock = partitionBlocks[p];

                var nextPartitionBlock = p < partitionBlocks.Count - 1
                    ? (uint)(partitionBlockIndex + p + 1)
                    : BlockIdentifiers.EndOfBlock;

                if (partitionBlock.NextPartitionBlock != nextPartitionBlock)
                {
                    partitionsChanged = true;
                }

                partitionBlock.NextPartitionBlock = nextPartitionBlock;

                if (partitionBlockIndex + p > highRsdkBlock)
                {
                    highRsdkBlock = (uint)(partitionBlockIndex + p);
                }
            }

            if (partitionsChanged)
            {
                ResetFileSystemHeaderBlockPointers(rigidDiskBlock);
                ResetBadBlockPointers(rigidDiskBlock);
            }

            var fileSystemHeaderBlocks     = rigidDiskBlock.FileSystemHeaderBlocks.ToList();
            var fileSystemHeaderBlockIndex = fileSystemHeaderBlocks.Count > 0 ? highRsdkBlock + 1 : BlockIdentifiers.EndOfBlock;

            var fileSystemHeaderChanged = rigidDiskBlock.FileSysHdrList != fileSystemHeaderBlockIndex;

            if (fileSystemHeaderChanged)
            {
                ResetBadBlockPointers(rigidDiskBlock);
            }

            rigidDiskBlock.FileSysHdrList = fileSystemHeaderBlockIndex;

            for (var f = 0; f < fileSystemHeaderBlocks.Count; f++)
            {
                var fileSystemHeaderBlock = fileSystemHeaderBlocks[f];
                var loadSegBlocks         = fileSystemHeaderBlock.LoadSegBlocks.ToList();

                fileSystemHeaderBlock.NextFileSysHeaderBlock = f < fileSystemHeaderBlocks.Count - 1
                    ? (uint)(fileSystemHeaderBlockIndex + f + 1 + loadSegBlocks.Count)
                    : BlockIdentifiers.EndOfBlock;
                fileSystemHeaderBlock.SegListBlocks = (int)(fileSystemHeaderBlockIndex + f + 1);

                if (fileSystemHeaderBlockIndex + f + loadSegBlocks.Count > highRsdkBlock)
                {
                    highRsdkBlock = (uint)(fileSystemHeaderBlockIndex + f + loadSegBlocks.Count);
                }

                for (var l = 0; l < loadSegBlocks.Count; l++)
                {
                    var loadSegBlock = loadSegBlocks[l];

                    loadSegBlock.NextLoadSegBlock = l < loadSegBlocks.Count - 1
                        ? (int)(fileSystemHeaderBlockIndex + f + 2 + l)
                        : -1;
                }
            }

            var badBlocks     = rigidDiskBlock.BadBlocks.ToList();
            var badBlockIndex = badBlocks.Count > 0 ? highRsdkBlock + 1 : BlockIdentifiers.EndOfBlock;

            rigidDiskBlock.BadBlockList = badBlockIndex;

            for (var b = 0; b < badBlocks.Count; b++)
            {
                var badBlock = badBlocks[b];

                badBlock.NextBadBlock = b < badBlocks.Count - 1
                    ? (uint)(badBlockIndex + b + 1)
                    : BlockIdentifiers.EndOfBlock;

                // update highest used rdb block
                if (badBlockIndex + b > highRsdkBlock)
                {
                    highRsdkBlock = (uint)(badBlockIndex + b);
                }
            }

            // set highest used rdb block
            rigidDiskBlock.HighRsdkBlock = highRsdkBlock;
        }
Beispiel #14
0
 public static void ResetRigidDiskBlockPointers(RigidDiskBlock rigidDiskBlock)
 {
     ResetPartitionBlockPointers(rigidDiskBlock);
     ResetFileSystemHeaderBlockPointers(rigidDiskBlock);
     ResetBadBlockPointers(rigidDiskBlock);
 }