Exemple #1
0
        public List <TransactionEntry> ReadTransactionTable(NTFSRestartRecord restartRecord)
        {
            ulong transactionTableLsn = restartRecord.TransactionTableLsn;

            if (transactionTableLsn != 0)
            {
                NTFSLogRecord record = ReadLogRecord(transactionTableLsn);
                if (record.RedoOperation != NTFSLogOperation.TransactionTableDump)
                {
                    string message = String.Format("Restart record TransactionTableLsn points to a record with RedoOperation {0}", record.RedoOperation);
                    throw new InvalidDataException(message);
                }

                if (restartRecord.TransactionTableLength != record.RedoData.Length)
                {
                    throw new InvalidDataException("Transcation table length does not match restart record");
                }

                return(RestartTableHelper.ReadTable <TransactionEntry>(record.RedoData, restartRecord.MajorVersion));
            }
            else
            {
                return(null);
            }
        }
Exemple #2
0
        public List <AttributeNameEntry> ReadAttributeNamesTable(NTFSRestartRecord restartRecord)
        {
            ulong attributeNamesLsn = restartRecord.AttributeNamesLsn;

            if (attributeNamesLsn != 0)
            {
                NTFSLogRecord record = ReadLogRecord(attributeNamesLsn);
                if (record.RedoOperation != NTFSLogOperation.AttributeNamesDump)
                {
                    string message = String.Format("Restart record AttributeNamesLsn points to a record with RedoOperation {0}", record.RedoOperation);
                    throw new InvalidDataException(message);
                }

                if (restartRecord.AttributeNamesLength != record.RedoData.Length)
                {
                    throw new InvalidDataException("Open attribute table length does not match restart record");
                }

                return(AttributeNameEntry.ReadTable(record.RedoData));
            }
            else
            {
                return(null);
            }
        }
Exemple #3
0
        private LfsRecord WriteLogRecord(NTFSLogRecord ntfsLogRecord, uint transactionID, bool flushToDisk)
        {
            LfsClientRecord clientRecord = m_logFile.GetClientRecord(m_clientIndex);

            byte[]    clientData       = ntfsLogRecord.GetBytes();
            int       transactionIndex = IndexOfTransaction(transactionID);
            ulong     lastLsnToUndo    = m_transactions[transactionIndex].LastLsnToUndo;
            LfsRecord result           = m_logFile.WriteRecord(m_clientIndex, LfsRecordType.ClientRecord, m_lastClientLsn, lastLsnToUndo, transactionID, clientData, flushToDisk);

            m_lastClientLsn = result.ThisLsn;
            m_transactions[transactionIndex].LastLsnToUndo = result.ThisLsn;
            if (m_transactions[transactionIndex].OldestLsn == 0)
            {
                m_transactions[transactionIndex].OldestLsn = result.ThisLsn;
            }
            return(result);
        }
Exemple #4
0
        private LfsRecord WriteLogRecord(int openAttributeOffset, ulong streamOffset, int recordOffset, int attributeOffset, List <long> lcnList, NTFSLogOperation redoOperation, byte[] redoData, NTFSLogOperation undoOperation, byte[] undoData, uint transactionID, bool flushToDisk)
        {
            NTFSLogRecord ntfsLogRecord = new NTFSLogRecord();

            ntfsLogRecord.TargetAttributeOffset = (ushort)openAttributeOffset;
            ntfsLogRecord.RedoOperation         = redoOperation;
            ntfsLogRecord.RedoData      = redoData;
            ntfsLogRecord.UndoOperation = undoOperation;
            ntfsLogRecord.UndoData      = undoData;
            ntfsLogRecord.TargetVCN     = (long)(streamOffset / (uint)Volume.BytesPerCluster);
            ntfsLogRecord.LCNsForPage.AddRange(lcnList);
            int offsetInCluster = (int)(streamOffset % (uint)Volume.BytesPerCluster);

            ntfsLogRecord.RecordOffset       = (ushort)recordOffset;
            ntfsLogRecord.AttributeOffset    = (ushort)attributeOffset;
            ntfsLogRecord.ClusterBlockOffset = (ushort)(offsetInCluster / NTFSLogRecord.BytesPerLogBlock);
            return(WriteLogRecord(ntfsLogRecord, transactionID, flushToDisk));
        }
Exemple #5
0
        public LfsRecord WriteForgetTransactionRecord(uint transactionID, bool flushToDisk)
        {
            NTFSLogRecord ntfsLogRecord = new NTFSLogRecord();

            ntfsLogRecord.RedoOperation = NTFSLogOperation.ForgetTransaction;
            ntfsLogRecord.UndoOperation = NTFSLogOperation.CompensationLogRecord;
            LfsRecord result = WriteLogRecord(ntfsLogRecord, transactionID, flushToDisk);

            DeallocateTransactionID(transactionID);
            // Update the open attribute table and remove any open attribute that no longer has an associated transaction
            for (int index = 0; index < m_openAttributes.Count; index++)
            {
                OpenAttribute openAttribute = m_openAttributes[index];
                openAttribute.AssociatedTransactions.Remove(transactionID);
                if (openAttribute.AssociatedTransactions.Count == 0)
                {
                    m_openAttributes.RemoveAt(index);
                    index--;
                }
            }
            return(result);
        }
        public List <NTFSLogRecord> FindRecordsToRedo()
        {
            NTFSRestartRecord     restartRecord  = ReadCurrentRestartRecord();
            List <DirtyPageEntry> dirtyPageTable = ReadDirtyPageTable(restartRecord);
            ulong            redoLsn             = FindRedoLsn(dirtyPageTable);
            LfsRecord        firstRecord         = m_logFile.ReadRecord(redoLsn);
            List <LfsRecord> records             = m_logFile.FindNextRecords(redoLsn, m_clientIndex);

            records.Insert(0, firstRecord);

            List <NTFSLogRecord> result = new List <NTFSLogRecord>();

            foreach (LfsRecord record in records)
            {
                if (record.RecordType == LfsRecordType.ClientRecord)
                {
                    NTFSLogRecord clientRecord = new NTFSLogRecord(record.Data);
                    switch (clientRecord.RedoOperation)
                    {
                    case NTFSLogOperation.Noop:
                    case NTFSLogOperation.OpenAttributeTableDump:
                    case NTFSLogOperation.AttributeNamesDump:
                    case NTFSLogOperation.DirtyPageTableDump:
                    case NTFSLogOperation.TransactionTableDump:
                    {
                        continue;
                    }

                    default:
                    {
                        result.Add(clientRecord);
                        break;
                    }
                    }
                }
            }
            return(result);
        }