123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- using System;
- using System.Collections.Generic;
- using System.Text;
- using Utilities;
- namespace DiskAccessLibrary.LogicalDiskManager
- {
- public class KernelUpdateLogEntry
- {
- public KernelUpdateLogEntryStatus Status;
- public ulong CommittedTransactionID;
- public ulong PendingTransactionID;
- public uint RecoverySequenceNumber;
- }
- public class KernelUpdateLogPage
- {
- public const int Length = 512;
- public string Signature = "KLOG";
- public ulong UnknownTransactionID;
-
-
- public uint SequenceNumber;
- public uint NumberOfPages;
- public uint PageIndex;
- private List<KernelUpdateLogEntry> m_logEntries = new List<KernelUpdateLogEntry>();
- public KernelUpdateLogPage(byte[] buffer)
- {
- Signature = ByteReader.ReadAnsiString(buffer, 0x00, 4);
- UnknownTransactionID = BigEndianConverter.ToUInt64(buffer, 0x04);
- SequenceNumber = BigEndianConverter.ToUInt32(buffer, 0x0C);
- NumberOfPages = BigEndianConverter.ToUInt32(buffer, 0x10);
- PageIndex = BigEndianConverter.ToUInt32(buffer, 0x14);
-
-
- m_logEntries.Clear();
- int offset = 0x18;
- while (offset < buffer.Length - 24)
- {
- KernelUpdateLogEntryStatus status = (KernelUpdateLogEntryStatus)buffer[offset];
- offset += 1;
- if (status != KernelUpdateLogEntryStatus.NotExist)
- {
- KernelUpdateLogEntry entry = new KernelUpdateLogEntry();
- entry.Status = status;
- entry.CommittedTransactionID = BigEndianConverter.ToUInt64(buffer, offset);
- offset += 8;
- entry.PendingTransactionID = BigEndianConverter.ToUInt64(buffer, offset);
- offset += 8;
- entry.RecoverySequenceNumber = BigEndianConverter.ToUInt32(buffer, offset);
- offset += 4;
- m_logEntries.Add(entry);
- offset += 3;
- }
- else
- {
- break;
- }
- }
- }
- public byte[] GetBytes()
- {
- byte[] buffer = new byte[Length];
- ByteWriter.WriteAnsiString(buffer, 0, Signature, 4);
- BigEndianWriter.WriteUInt64(buffer, 0x04, UnknownTransactionID);
- BigEndianWriter.WriteUInt32(buffer, 0x0C, SequenceNumber);
- BigEndianWriter.WriteUInt32(buffer, 0x10, NumberOfPages);
- BigEndianWriter.WriteUInt32(buffer, 0x14, PageIndex);
- int offset = 0x18;
- foreach (KernelUpdateLogEntry entry in m_logEntries)
- {
- buffer[offset] = (byte)entry.Status;
- offset += 1;
- BigEndianWriter.WriteUInt64(buffer, offset, entry.CommittedTransactionID);
- offset += 8;
- BigEndianWriter.WriteUInt64(buffer, offset, entry.PendingTransactionID);
- offset += 8;
- BigEndianWriter.WriteUInt32(buffer, offset, entry.RecoverySequenceNumber);
- offset += 4;
- offset += 3;
- }
- return buffer;
- }
- public List<KernelUpdateLogEntry> LogEntries
- {
- get
- {
- return m_logEntries;
- }
- }
- public void SetLastEntry(ulong committedTransactionID, ulong pendingTransactionID)
- {
- if (m_logEntries.Count > 0)
- {
- m_logEntries.RemoveAt(m_logEntries.Count - 1);
- }
- KernelUpdateLogEntry entry = new KernelUpdateLogEntry();
- entry.Status = KernelUpdateLogEntryStatus.Commit;
- entry.CommittedTransactionID = committedTransactionID;
- entry.PendingTransactionID = pendingTransactionID;
- m_logEntries.Add(entry);
- }
- 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 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);
- }
- }
- }
|