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));
        }
Beispiel #2
0
        /// <summary>
        /// Will read all VBLK blocks and assemble the database records
        /// </summary>
        /// <param name="numberOfFragments">number of fragments excluding the database header</param>
        private static List <DatabaseRecord> ReadDatabaseRecords(byte[] databaseBytes, int headerSize, int fragmentSize, int numberOfFragments)
        {
            // Note: fragments are not necessarily contiguous!
            Dictionary <uint, List <DatabaseRecordFragment> > fragments = new Dictionary <uint, List <DatabaseRecordFragment> >();

            for (uint index = 0; index < numberOfFragments; index++)
            {
                byte[] fragmentBytes  = new byte[fragmentSize];
                int    fragmentOffset = (int)(headerSize + index * fragmentSize);
                Array.Copy(databaseBytes, fragmentOffset, fragmentBytes, 0, fragmentSize);
                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.
            List <DatabaseRecord> databaseRecords = new List <DatabaseRecord>();

            foreach (List <DatabaseRecordFragment> recordFragments in fragments.Values)
            {
                DatabaseRecord databaseRecord = DatabaseRecord.GetDatabaseRecord(recordFragments);
                databaseRecords.Add(databaseRecord);
            }
            return(databaseRecords);
        }