public static long FindUnusedRegion(PrivateHeader privateHeader, TOCBlock tocBlock, int sectorCount)
        {
            bool[] bitmap = GetPrivateRegionUsageBitmap(privateHeader, tocBlock);
            // Reserve the first, second, third, third-last and second-last sectors for TOCBlocks
            bitmap[0] = true;
            bitmap[1] = true;
            bitmap[2] = true;
            bitmap[privateHeader.PrivateRegionSizeLBA - 3] = true;
            bitmap[privateHeader.PrivateRegionSizeLBA - 2] = true;

            int startIndex = 0;
            int freeCount  = 0;

            for (int index = 0; index < bitmap.Length; index++)
            {
                if (bitmap[index] == false) // free
                {
                    if (freeCount == 0)
                    {
                        startIndex = index;
                    }
                    freeCount++;
                    if (freeCount == sectorCount)
                    {
                        return((long)privateHeader.PrivateRegionStartLBA + startIndex);
                    }
                }
                else
                {
                    freeCount = 0;
                }
            }

            return(-1);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Update the database to point to the new extent location (same or different disk)
        /// </summary>
        public static void UpdateExtentLocation(DiskGroupDatabase database, DynamicVolume volume, DynamicDiskExtent relocatedExtent)
        {
            PrivateHeader privateHeader = PrivateHeader.ReadFromDisk(relocatedExtent.Disk);

            DiskRecord   targetDiskRecord = database.FindDiskByDiskGuid(privateHeader.DiskGuid);
            VolumeRecord volumeRecord     = database.FindVolumeByVolumeGuid(volume.VolumeGuid);

            List <DatabaseRecord> records               = new List <DatabaseRecord>();
            ExtentRecord          sourceExtentRecord    = database.FindExtentByExtentID(relocatedExtent.ExtentID);
            ExtentRecord          relocatedExtentRecord = (ExtentRecord)sourceExtentRecord.Clone();

            relocatedExtentRecord.DiskId        = targetDiskRecord.DiskId;
            relocatedExtentRecord.DiskOffsetLBA = (ulong)PublicRegionHelper.TranslateToPublicRegionLBA(relocatedExtent.FirstSector, privateHeader);
            records.Add(relocatedExtentRecord);

            // we should update the disk records
            foreach (DynamicDiskExtent extent in volume.Extents)
            {
                DiskRecord diskRecord = database.FindDiskByDiskID(relocatedExtentRecord.DiskId);
                // there could be multiple extents on the same disk, make sure we only add each disk once
                if (!records.Contains(diskRecord))
                {
                    diskRecord = (DiskRecord)diskRecord.Clone();
                    records.Add(diskRecord);
                }
            }

            // when moving to a new disk, we should update the new disk record as well
            if (!records.Contains(targetDiskRecord))
            {
                records.Add(targetDiskRecord.Clone());
            }

            database.UpdateDatabase(records);
        }
Ejemplo n.º 3
0
        public static VolumeManagerDatabase ReadFromDisk(Disk disk, PrivateHeader privateHeader, TOCBlock tocBlock)
        {
            VolumeManagerDatabaseHeader databaseHeader = VolumeManagerDatabaseHeader.ReadFromDisk(disk, privateHeader, tocBlock);

            if (databaseHeader == null || !databaseHeader.IsVersionSupported)
            {
                return(null);
            }

            // The first VBLK entry is the subsequent entry to the VMDB header.
            // Note: On a disk with 4KB sectors, VBLKs will reside in the same sector as the VMDB header.
            ulong firstSector    = privateHeader.PrivateRegionStartLBA + tocBlock.ConfigStart; // we skip the VMDB
            int   databaseLength = (int)(databaseHeader.HeaderSize + databaseHeader.NumberOfVBlks * databaseHeader.BlockSize);
            int   sectorCount    = (int)Math.Ceiling(databaseLength / (double)disk.BytesPerSector);

            byte[] databaseBytes     = disk.ReadSectors((long)firstSector, sectorCount);
            int    numberOfFragments = (int)(databaseHeader.NumberOfVBlks - FirstSequenceNumber);
            List <DatabaseRecord> databaseRecords = ReadDatabaseRecords(databaseBytes, (int)databaseHeader.HeaderSize, (int)databaseHeader.BlockSize, numberOfFragments);

            // read all KLog blocks
            KernelUpdateLog kernelUpdateLog = KernelUpdateLog.ReadFromDisk(disk, privateHeader, tocBlock);
            DynamicDisk     dynamicDisk     = new DynamicDisk(disk, privateHeader, tocBlock);

            return(new VolumeManagerDatabaseCopy(dynamicDisk, databaseHeader, databaseRecords, kernelUpdateLog));
        }
Ejemplo n.º 4
0
        public static TOCBlock ReadFromDisk(Disk disk, PrivateHeader privateHeader, bool usePrimaryTOC)
        {
            ulong sectorIndex;

            if (usePrimaryTOC)
            {
                sectorIndex = privateHeader.PrivateRegionStartLBA + privateHeader.PrimaryTocLBA;
            }
            else
            {
                sectorIndex = privateHeader.PrivateRegionStartLBA + privateHeader.SecondaryTocLBA;
            }

            byte[] sector    = disk.ReadSector((long)sectorIndex);
            string signature = ByteReader.ReadAnsiString(sector, 0x00, 8);

            if (signature == TOCBlockSignature)
            {
                TOCBlock tocBlock = new TOCBlock(sector);
                if (tocBlock.IsChecksumValid)
                {
                    return(tocBlock);
                }
            }

            return(null);
        }
Ejemplo n.º 5
0
        public TOCBlock(byte[] buffer)
        {
            if (buffer.Length > Length)
            {
                // Checksum only applies to the first 512 bytes (even when the sector size > 512 bytes)
                buffer = ByteReader.ReadBytes(buffer, 0, 512);
            }
            Signature = ByteReader.ReadAnsiString(buffer, 0x00, 8);
            uint checksum = BigEndianConverter.ToUInt32(buffer, 0x08);

            UpdateSequenceNumber = BigEndianConverter.ToUInt64(buffer, 0x0C);
            // 16 zeros
            int offset = 0x24;

            // If the first character is not null (0x00), then there is a region defined
            while (buffer[offset] != 0)
            {
                TOCRegion region = new TOCRegion(buffer, offset);
                Regions.Add(region);
                offset += TOCRegion.Length;
            }

            BigEndianWriter.WriteUInt32(buffer, 0x08, (uint)0); // we exclude the checksum field from checksum calculations
            m_isChecksumValid = (checksum == PrivateHeader.CalculateChecksum(buffer));
        }
        public static void WriteToDisk(Disk disk, PrivateHeader privateHeader, TOCBlock tocBlock, VolumeManagerDatabaseHeader header)
        {
            ulong sectorIndex = privateHeader.PrivateRegionStartLBA + tocBlock.ConfigStart;

            byte[] bytes = header.GetBytes();
            disk.WriteSectors((long)sectorIndex, bytes);
        }
        public static bool IsDynamicDisk(Disk disk)
        {
            MasterBootRecord mbr = MasterBootRecord.ReadFromDisk(disk);

            if (mbr != null)
            {
                if (mbr.PartitionTable[0].PartitionType == (byte)PartitionTypeName.DynamicData)
                {
                    return(true);
                }
                else if (mbr.IsGPTBasedDisk)
                {
                    List <GuidPartitionEntry> entries = GuidPartitionTable.ReadEntriesFromDisk(disk);
                    if (entries != null)
                    {
                        if (GuidPartitionEntryCollection.ContainsPartitionTypeGuid(entries, GPTPartition.PrivateRegionPartitionTypeGuid) &&
                            GuidPartitionEntryCollection.ContainsPartitionTypeGuid(entries, GPTPartition.PublicRegionPartitionTypeGuid))
                        {
                            return(true);
                        }
                    }
                }

                return(false);
            }
            else
            {
                // if the disk has no master boot record, it can be a dynamic disk if it has a valid PrivateHeader at sector 6
                PrivateHeader privateHeader = PrivateHeader.ReadFromDiskStart(disk);
                return(privateHeader != null);
            }
        }
Ejemplo n.º 8
0
        public static void AddDiskToRaid5Volume(List <DynamicDisk> disks, Raid5Volume volume, DiskExtent newExtent, ref long bytesCopied)
        {
            DiskGroupDatabase database = DiskGroupDatabase.ReadFromDisks(disks, volume.DiskGroupGuid);

            if (database == null)
            {
                throw new DatabaseNotFoundException();
            }
            // If there will be a power failure during the conversion, our RAID volume will resync during boot,
            // To prevent destruction of the data, we temporarily convert the array to striped volume
            VolumeManagerDatabaseHelper.ConvertRaidToStripedVolume(database, volume.VolumeGuid);
            ulong newExtentID = VolumeManagerDatabaseHelper.AddNewExtentToVolume(database, volume, newExtent);

            // Backup the first sector of the first extent to the last sector of the new extent
            // (We replace the filesystem boot record with our own sector for recovery purposes)
            byte[] filesystemBootRecord = volume.Extents[0].ReadSector(0);
            newExtent.WriteSectors(newExtent.TotalSectors - 1, filesystemBootRecord);

            AddDiskOperationBootRecord resumeRecord = new AddDiskOperationBootRecord();

            resumeRecord.VolumeGuid = volume.VolumeGuid;
            PrivateHeader privateHeader = PrivateHeader.ReadFromDisk(newExtent.Disk);

            // privateHeader cannot be null at this point
            resumeRecord.NumberOfCommittedSectors = 0;

            // we use volume.WriteSectors so that the parity information will be update
            // this way, we could recover the first sector of each extent if a disk will fail
            volume.WriteSectors(0, resumeRecord.GetBytes());

            ResumeAddDiskToRaid5Volume(disks, volume, new DynamicDiskExtent(newExtent, newExtentID), resumeRecord, ref bytesCopied);
        }
Ejemplo n.º 9
0
        public static void WriteToDisk(Disk disk, PrivateHeader privateHeader, TOCBlock tocBlock, KernelUpdateLogPage record)
        {
            ulong sectorIndex = privateHeader.PrivateRegionStartLBA + tocBlock.LogStart + record.PageIndex;

            byte[] sector = record.GetBytes();
            disk.WriteSectors((long)sectorIndex, sector);
        }
Ejemplo n.º 10
0
        public static KernelUpdateLogPage ReadFromDisk(Disk disk, PrivateHeader privateHeader, TOCBlock tocBlock, int kLogIndex)
        {
            ulong sectorIndex = privateHeader.PrivateRegionStartLBA + tocBlock.LogStart + (uint)kLogIndex;

            byte[] sector = disk.ReadSector((long)sectorIndex);
            KernelUpdateLogPage result = new KernelUpdateLogPage(sector);

            return(result);
        }
        public static VolumeManagerDatabase ReadFromDisk(Disk disk, PrivateHeader privateHeader, TOCBlock tocBlock)
        {
            VolumeManagerDatabaseHeader databaseHeader = VolumeManagerDatabaseHeader.ReadFromDisk(disk, privateHeader, tocBlock);

            if (databaseHeader == null)
            {
                return(null);
            }
            List <DatabaseRecord> databaseRecords = new List <DatabaseRecord>();

            // The first VBLK entry is the subsequent entry to the VMDB, which located at (ConfigurationStartLBA + Item1Start)
            ulong firstSector = privateHeader.PrivateRegionStartLBA + tocBlock.ConfigStart + 1;  // we skip the VMDB
            int   sectorCount = (int)Math.Ceiling((long)databaseHeader.NumberOfVBlks * databaseHeader.BlockSize / (decimal)disk.BytesPerSector);

            byte[] databaseBytes = disk.ReadSectors((long)firstSector, sectorCount);

            // read all VBLK blocks:
            // Note: fragments are not necessarily contiguous!
            Dictionary <uint, List <DatabaseRecordFragment> > fragments = new Dictionary <uint, List <DatabaseRecordFragment> >();

            for (uint index = 0; index < databaseHeader.NumberOfVBlks - 4; index++)
            {
                byte[] fragmentBytes = new byte[databaseHeader.BlockSize];
#warning long array index not supported
                Array.Copy(databaseBytes, (int)(index * databaseHeader.BlockSize), fragmentBytes, 0, (int)databaseHeader.BlockSize);
                DatabaseRecordFragment fragment = DatabaseRecordFragment.GetDatabaseRecordFragment(fragmentBytes);

                if (fragment != null) // null fragment means VBLK is empty
                {
                    if (fragments.ContainsKey(fragment.GroupNumber))
                    {
                        fragments[fragment.GroupNumber].Add(fragment);
                    }
                    else
                    {
                        List <DatabaseRecordFragment> recordFragments = new List <DatabaseRecordFragment>();
                        recordFragments.Add(fragment);
                        fragments.Add(fragment.GroupNumber, recordFragments);
                    }
                }
            }

            // We have all the fragments and we can now assemble the records:
            // We assume that fragments with lower FragmentNumber appear in the database before fragments
            // of the same group with higher FragmentNumber.
            foreach (List <DatabaseRecordFragment> recorFragments in fragments.Values)
            {
                DatabaseRecord databaseRecord = DatabaseRecord.GetDatabaseRecord(recorFragments);
                databaseRecords.Add(databaseRecord);
            }

            // read all KLog blocks
            KernelUpdateLog kernelUpdateLog = KernelUpdateLog.ReadFromDisk(disk, privateHeader, tocBlock);
            DynamicDisk     dynamicDisk     = new DynamicDisk(disk, privateHeader, tocBlock);
            return(new VolumeManagerDatabase(dynamicDisk, databaseHeader, databaseRecords, kernelUpdateLog));
        }
Ejemplo n.º 12
0
        public static TOCBlock ReadFromDisk(Disk disk, PrivateHeader privateHeader)
        {
            TOCBlock tocBlock = ReadFromDisk(disk, privateHeader, true);

            if (tocBlock == null)
            {
                tocBlock = ReadFromDisk(disk, privateHeader, false);
            }
            return(tocBlock);
        }
Ejemplo n.º 13
0
        public static VolumeManagerDatabase ReadFromDisk(Disk disk, PrivateHeader privateHeader)
        {
            TOCBlock tocBlock = TOCBlock.ReadFromDisk(disk, privateHeader);

            if (tocBlock != null)
            {
                return(ReadFromDisk(disk, privateHeader, tocBlock));
            }
            return(null);
        }
Ejemplo n.º 14
0
        public static ulong CreateSimpleVolume(DiskGroupDatabase database, DiskExtent extent)
        {
            List <DatabaseRecord> records = new List <DatabaseRecord>();

            VolumeRecord volumeRecord = new VolumeRecord();

            volumeRecord.Id                 = database.AllocateNewRecordID();
            volumeRecord.Name               = GetNextSimpleVolumeName(database.VolumeRecords);
            volumeRecord.VolumeTypeString   = "gen";
            volumeRecord.StateString        = "ACTIVE";
            volumeRecord.ReadPolicy         = ReadPolicyName.Select;
            volumeRecord.VolumeNumber       = GetNextVolumeNumber(database.VolumeRecords);
            volumeRecord.VolumeFlags        = VolumeFlags.Writeback | VolumeFlags.DefaultUnknown;
            volumeRecord.NumberOfComponents = 1;
            volumeRecord.SizeLBA            = (ulong)PublicRegionHelper.TranslateToPublicRegionSizeLBA(extent.TotalSectors, extent.BytesPerSector);
            volumeRecord.PartitionType      = PartitionType.RAW;
            volumeRecord.VolumeGuid         = Guid.NewGuid();
            records.Add(volumeRecord);

            ComponentRecord componentRecord = new ComponentRecord();

            componentRecord.Id                    = database.AllocateNewRecordID();
            componentRecord.Name                  = volumeRecord.Name + "-01";
            componentRecord.StateString           = "ACTIVE";
            componentRecord.ExtentLayout          = ExtentLayoutName.Concatenated;
            componentRecord.NumberOfExtents       = 1;
            componentRecord.VolumeId              = volumeRecord.VolumeId;
            componentRecord.HasStripedExtentsFlag = false;
            componentRecord.NumberOfColumns       = 0;
            records.Add(componentRecord);

            // we should update the disk record
            PrivateHeader privateHeader = PrivateHeader.ReadFromDisk(extent.Disk);
            DiskRecord    diskRecord    = database.FindDiskByDiskGuid(privateHeader.DiskGuid);

            diskRecord = (DiskRecord)diskRecord.Clone();
            records.Add(diskRecord);

            ExtentRecord extentRecord = new ExtentRecord();

            extentRecord.Name          = GetNextExtentName(database.ExtentRecords, diskRecord.Name);
            extentRecord.DiskOffsetLBA = (ulong)PublicRegionHelper.TranslateToPublicRegionLBA(extent.FirstSector, privateHeader);
            extentRecord.SizeLBA       = volumeRecord.SizeLBA;
            extentRecord.ComponentId   = componentRecord.ComponentId;
            extentRecord.DiskId        = diskRecord.DiskId;

            extentRecord.HasColumnIndexFlag = false;

            records.Add(extentRecord);

            database.UpdateDatabase(records);

            return(volumeRecord.VolumeId);
        }
Ejemplo n.º 15
0
 /// <summary>
 /// This method will write privateHeader to disk as well
 /// </summary>
 public static void WriteToDisk(Disk disk, PrivateHeader privateHeader, TOCBlock tocBlock)
 {
     privateHeader.UpdateSequenceNumber++;
     tocBlock.UpdateSequenceNumber++;
     byte[] bytes = tocBlock.GetBytes();
     disk.WriteSectors((long)(privateHeader.PrivateRegionStartLBA + privateHeader.PreviousPrimaryTocLBA), bytes);
     disk.WriteSectors((long)(privateHeader.PrivateRegionStartLBA + privateHeader.PreviousSecondaryTocLBA), bytes);
     privateHeader.PrimaryTocLBA   = privateHeader.PreviousPrimaryTocLBA;
     privateHeader.SecondaryTocLBA = privateHeader.PreviousSecondaryTocLBA;
     PrivateHeader.WriteToDisk(disk, privateHeader);
 }
Ejemplo n.º 16
0
 public static VolumeManagerDatabase ReadFromDisk(Disk disk)
 {
     if (DynamicDisk.IsDynamicDisk(disk))
     {
         PrivateHeader privateHeader = PrivateHeader.ReadFromDisk(disk);
         if (privateHeader != null)
         {
             return(ReadFromDisk(disk, privateHeader));
         }
     }
     return(null);
 }
 // The secondary TOC is usually alternated between the third-last and the second-last sectors of the private region.
 public static long FindUnusedLBAForSecondaryToc(PrivateHeader privateHeader, TOCBlock tocBlock)
 {
     bool[] bitmap = GetPrivateRegionUsageBitmap(privateHeader, tocBlock);
     for (int index = bitmap.Length - 1; index >= 0; index--)
     {
         if (bitmap[index] == false)
         {
             return((long)privateHeader.PrivateRegionStartLBA + index);
         }
     }
     return(-1);
 }
Ejemplo n.º 18
0
        /// <summary>
        /// Support null disks
        /// </summary>
        public static long GetExtentStartSector(DynamicDisk disk, ExtentRecord extentRecord)
        {
            long publicRegionStartLBA = 0;
            int  bytesPerDiskSector   = DynamicColumn.DefaultBytesPerSector; // default for missing disks

            if (disk != null)
            {
                bytesPerDiskSector = disk.BytesPerSector;
                PrivateHeader privateHeader = disk.PrivateHeader;
                publicRegionStartLBA = (long)privateHeader.PublicRegionStartLBA;
            }
            return(PublicRegionHelper.TranslateFromPublicRegionLBA((long)extentRecord.DiskOffsetLBA, publicRegionStartLBA, bytesPerDiskSector));
        }
Ejemplo n.º 19
0
        public static KernelUpdateLog ReadFromDisk(Disk disk, PrivateHeader privateHeader, TOCBlock tocBlock)
        {
            List <KernelUpdateLogPage> pages     = new List <KernelUpdateLogPage>();
            KernelUpdateLogPage        firstPage = KernelUpdateLogPage.ReadFromDisk(disk, privateHeader, tocBlock, 0);

            pages.Add(firstPage);
            for (int index = 2; index < firstPage.NumberOfPages; index++)
            {
                KernelUpdateLogPage page = KernelUpdateLogPage.ReadFromDisk(disk, privateHeader, tocBlock, index);
                pages.Add(page);
            }
            return(new KernelUpdateLog(pages));
        }
Ejemplo n.º 20
0
        public static KernelUpdateLogPage ReadFromDisk(Disk disk, PrivateHeader privateHeader, TOCBlock tocBlock, int pageIndex)
        {
            ulong sectorIndex = privateHeader.PrivateRegionStartLBA + tocBlock.LogStart + (uint)(pageIndex * Length / disk.BytesPerSector);
            int   pageOffset  = (pageIndex * Length) % disk.BytesPerSector;

            byte[] sector = disk.ReadSector((long)sectorIndex);
            if (pageOffset > 0)
            {
                sector = ByteReader.ReadBytes(sector, pageOffset, Length);
            }
            KernelUpdateLogPage result = new KernelUpdateLogPage(sector);

            return(result);
        }
Ejemplo n.º 21
0
 public void SetLastEntry(Disk disk, PrivateHeader privateHeader, TOCBlock tocBlock, ulong committedTransactionID, ulong pendingTransactionID)
 {
     if (m_pages.Count > 0)
     {
         m_pages[0].SetLastEntry(committedTransactionID, pendingTransactionID);
         // Windows kernel stores the last committedTransactionID / pendingTransactionID in memory,
         // and it will overwrite the values we write as soon as dmadmin is started,
         // However, it doesn't seem to cause any issues
         KernelUpdateLogPage.WriteToDisk(disk, privateHeader, tocBlock, m_pages[0]);
     }
     else
     {
         throw new InvalidOperationException("KLog records have not been previously read from disk");
     }
 }
        /// <param name="targetOffset">in bytes</param>
        public static bool IsMoveLocationValid(DynamicDiskExtent sourceExtent, DynamicDisk targetDisk, long targetOffset)
        {
            bool isSameDisk = (sourceExtent.Disk == targetDisk.Disk);
            List <DynamicDiskExtent> extents = GetDiskExtents(targetDisk);

            // extents are sorted by first sector
            if (extents == null)
            {
                return(false);
            }

            PrivateHeader privateHeader = targetDisk.PrivateHeader;

            if (sourceExtent.BytesPerSector != targetDisk.BytesPerSector)
            {
                // We must not move an extent to another disk that has different sector size
                return(false);
            }
            if (targetOffset % privateHeader.BytesPerSector > 0)
            {
                return(false);
            }
            long       targetSector = targetOffset / targetDisk.BytesPerSector;
            DiskExtent targetExtent = new DiskExtent(targetDisk.Disk, targetSector, sourceExtent.Size);

            List <DiskExtent> usedExtents = new List <DiskExtent>();

            foreach (DynamicDiskExtent extent in extents)
            {
                if (!isSameDisk || extent.FirstSector != sourceExtent.FirstSector)
                {
                    usedExtents.Add(extent);
                }
            }

            long publicRegionStartSector         = (long)privateHeader.PublicRegionStartLBA;
            long publicRegionSize                = (long)privateHeader.PublicRegionSizeLBA * targetDisk.BytesPerSector;
            List <DiskExtent> unallocatedExtents = DiskExtentsHelper.GetUnallocatedExtents(targetDisk.Disk, publicRegionStartSector, publicRegionSize, usedExtents);

            foreach (DiskExtent extent in unallocatedExtents)
            {
                if (extent.FirstSector <= targetExtent.FirstSector && targetExtent.LastSector <= extent.LastSector)
                {
                    return(true);
                }
            }
            return(false);
        }
Ejemplo n.º 23
0
        public static VolumeManagerDatabaseHeader ReadFromDisk(Disk disk, PrivateHeader privateHeader, TOCBlock tocBlock)
        {
            ulong sectorIndex = privateHeader.PrivateRegionStartLBA + tocBlock.ConfigStart;

            byte[] sector    = disk.ReadSector((long)sectorIndex);
            string signature = ByteReader.ReadAnsiString(sector, 0x00, 4);

            if (signature == VolumeManagerDatabaseSignature)
            {
                return(new VolumeManagerDatabaseHeader(sector));
            }
            else
            {
                return(null);
            }
        }
 public static DynamicDisk ReadFromDisk(Disk disk)
 {
     if (IsDynamicDisk(disk))
     {
         PrivateHeader privateHeader = PrivateHeader.ReadFromDisk(disk);
         if (privateHeader != null)
         {
             TOCBlock tocBlock = TOCBlock.ReadFromDisk(disk, privateHeader);
             if (tocBlock != null)
             {
                 return(new DynamicDisk(disk, privateHeader, tocBlock));
             }
         }
     }
     return(null);
 }
Ejemplo n.º 25
0
        public static PrivateHeader ReadFromDisk(Disk disk, long sectorIndex, bool returnPrivateHeaderWithInvalidChecksum)
        {
            byte[] sector    = disk.ReadSector(sectorIndex);
            string signature = ByteReader.ReadAnsiString(sector, 0x00, 8);

            if (signature == PrivateHeaderSignature)
            {
                PrivateHeader privateHeader = new PrivateHeader(sector);
                if (privateHeader.IsChecksumValid || returnPrivateHeaderWithInvalidChecksum)
                {
                    return(privateHeader);
                }
            }

            return(null);
        }
Ejemplo n.º 26
0
        public static void WriteToDisk(Disk disk, PrivateHeader privateHeader)
        {
            byte[] bytes = privateHeader.GetBytes();

            disk.WriteSectors((long)(privateHeader.PrivateRegionStartLBA + privateHeader.PrimaryPrivateHeaderLBA), bytes);
            disk.WriteSectors((long)(privateHeader.PrivateRegionStartLBA + privateHeader.SecondaryPrivateHeaderLBA), bytes);

            // update sector 6 if a Private Header is already present there
            byte[] sector    = disk.ReadSector(PrivateHeaderSectorIndex);
            string signature = ByteReader.ReadAnsiString(sector, 0x00, 8);

            if (signature == PrivateHeaderSignature)
            {
                disk.WriteSectors(PrivateHeaderSectorIndex, bytes);
            }
        }
Ejemplo n.º 27
0
        public static void WriteToDisk(Disk disk, PrivateHeader privateHeader, TOCBlock tocBlock, VolumeManagerDatabaseHeader header)
        {
            ulong sectorIndex = privateHeader.PrivateRegionStartLBA + tocBlock.ConfigStart;

            byte[] headerBytes = header.GetBytes();
            if (disk.BytesPerSector > Length)
            {
                byte[] sectorBytes = disk.ReadSector((long)sectorIndex);
                ByteWriter.WriteBytes(sectorBytes, 0, headerBytes);
                disk.WriteSectors((long)sectorIndex, sectorBytes);
            }
            else
            {
                disk.WriteSectors((long)sectorIndex, headerBytes);
            }
        }
Ejemplo n.º 28
0
        public static void WriteToDisk(Disk disk, PrivateHeader privateHeader, TOCBlock tocBlock, KernelUpdateLogPage page)
        {
            ulong sectorIndex = privateHeader.PrivateRegionStartLBA + tocBlock.LogStart + (uint)(page.PageIndex * Length / disk.BytesPerSector);
            int   pageOffset  = ((int)page.PageIndex * Length) % disk.BytesPerSector;

            byte[] pageBytes = page.GetBytes();
            if (disk.BytesPerSector > Length)
            {
                byte[] sectorBytes = disk.ReadSector((long)sectorIndex);
                ByteWriter.WriteBytes(sectorBytes, pageOffset, pageBytes);
                disk.WriteSectors((long)sectorIndex, sectorBytes);
            }
            else
            {
                disk.WriteSectors((long)sectorIndex, pageBytes);
            }
        }
        private static bool[] GetPrivateRegionUsageBitmap(PrivateHeader privateHeader, TOCBlock tocBlock)
        {
            // usage bitmap:
            bool[] bitmap = new bool[privateHeader.PrivateRegionSizeLBA];
            bitmap[privateHeader.PrimaryPrivateHeaderLBA]   = true;
            bitmap[privateHeader.SecondaryPrivateHeaderLBA] = true;
            bitmap[privateHeader.PrimaryTocLBA]             = true;
            bitmap[privateHeader.SecondaryTocLBA]           = true;

            foreach (TOCRegion region in tocBlock.Regions)
            {
                for (int index = 0; index < (int)region.SizeLBA; index++)
                {
                    bitmap[(int)region.StartLBA + index] = true;
                }
            }
            return(bitmap);
        }
Ejemplo n.º 30
0
        /// <summary>
        /// This method will write privateHeader to disk as well
        /// </summary>
        public static void WriteToDisk(Disk disk, PrivateHeader privateHeader, TOCBlock tocBlock)
        {
            privateHeader.UpdateSequenceNumber++;
            tocBlock.UpdateSequenceNumber++;
            byte[] tocBytes = tocBlock.GetBytes();
            if (disk.BytesPerSector > Length)
            {
                tocBytes = ByteUtils.Concatenate(tocBytes, new byte[disk.BytesPerSector - TOCBlock.Length]);
            }
            long alternatePrimaryTOCLBA   = PrivateRegionHelper.FindUnusedLBAForPrimaryToc(privateHeader, tocBlock);
            long alternateSecondaryTOCLBA = PrivateRegionHelper.FindUnusedLBAForSecondaryToc(privateHeader, tocBlock);

            disk.WriteSectors(alternatePrimaryTOCLBA, tocBytes);
            disk.WriteSectors(alternateSecondaryTOCLBA, tocBytes);
            privateHeader.PrimaryTocLBA   = (ulong)alternatePrimaryTOCLBA;
            privateHeader.SecondaryTocLBA = (ulong)alternateSecondaryTOCLBA;
            PrivateHeader.WriteToDisk(disk, privateHeader);
        }