Ejemplo n.º 1
0
        public static void CreateVolumeWithPendingFileCreation(string path, long size, int bytesPerCluster, string volumeLabel, string fileName, byte[] fileData)
        {
            VirtualHardDisk disk = VirtualHardDisk.CreateFixedDisk(path, size);

            disk.ExclusiveLock();
            Partition         partition         = NTFSFormatTests.CreatePrimaryPartition(disk);
            NTFSVolume        volume            = NTFSVolumeCreator.Format(partition, bytesPerCluster, volumeLabel);
            long              segmentNumber     = MasterFileTable.FirstUserSegmentNumber;
            FileNameRecord    fileNameRecord    = new FileNameRecord(MasterFileTable.RootDirSegmentReference, fileName, false, DateTime.Now);
            FileRecordSegment fileRecordSegment = CreateFileRecordSegment(segmentNumber, fileNameRecord, fileData);

            ulong dataStreamOffset = (ulong)(segmentNumber * volume.BytesPerFileRecordSegment);

            byte[] redoData = fileRecordSegment.GetBytes(volume.BytesPerFileRecordSegment, volume.MinorVersion, false);
            MftSegmentReference mftFileReference = new MftSegmentReference(0, 1);
            AttributeRecord     mftDataRecord    = volume.GetFileRecord(mftFileReference).GetAttributeRecord(AttributeType.Data, String.Empty);
            AttributeRecord     mftBitmapRecord  = volume.GetFileRecord(mftFileReference).GetAttributeRecord(AttributeType.Bitmap, String.Empty);
            uint transactionID = volume.LogClient.AllocateTransactionID();

            volume.LogClient.WriteLogRecord(mftFileReference, mftDataRecord, dataStreamOffset, volume.BytesPerFileRecordSegment, NTFSLogOperation.InitializeFileRecordSegment, redoData, NTFSLogOperation.Noop, new byte[0], transactionID);
            long        bitmapVCN          = segmentNumber / (volume.BytesPerCluster * 8);
            int         bitOffsetInCluster = (int)(segmentNumber % (volume.BytesPerCluster * 8));
            BitmapRange bitmapRange        = new BitmapRange((uint)bitOffsetInCluster, 1);
            ulong       bitmapStreamOffset = (ulong)(bitmapVCN * volume.BytesPerCluster);

            volume.LogClient.WriteLogRecord(mftFileReference, mftBitmapRecord, bitmapStreamOffset, volume.BytesPerCluster, NTFSLogOperation.SetBitsInNonResidentBitMap, bitmapRange.GetBytes(), NTFSLogOperation.Noop, new byte[0], transactionID);

            FileRecord parentDirectoryRecord = volume.GetFileRecord(MasterFileTable.RootDirSegmentReference);
            IndexData  parentDirectoryIndex  = new IndexData(volume, parentDirectoryRecord, AttributeType.FileName);

            byte[]      fileNameRecordBytes   = fileNameRecord.GetBytes();
            long        leafRecordVBN         = 0;
            IndexRecord leafRecord            = parentDirectoryIndex.ReadIndexRecord(leafRecordVBN);
            ulong       indexAllocationOffset = (ulong)parentDirectoryIndex.ConvertToDataOffset(leafRecordVBN);
            int         insertIndex           = CollationHelper.FindIndexForSortedInsert(leafRecord.IndexEntries, fileNameRecordBytes, CollationRule.Filename);
            int         insertOffset          = leafRecord.GetEntryOffset(volume.BytesPerIndexRecord, insertIndex);

            AttributeRecord rootDirIndexAllocation = volume.GetFileRecord(MasterFileTable.RootDirSegmentReference).GetAttributeRecord(AttributeType.IndexAllocation, IndexHelper.GetIndexName(AttributeType.FileName));
            IndexEntry      indexEntry             = new IndexEntry(fileRecordSegment.SegmentReference, fileNameRecord.GetBytes());

            volume.LogClient.WriteLogRecord(MasterFileTable.RootDirSegmentReference, rootDirIndexAllocation, indexAllocationOffset, volume.BytesPerIndexRecord, 0, insertOffset, NTFSLogOperation.AddIndexEntryToAllocationBuffer, indexEntry.GetBytes(), NTFSLogOperation.Noop, new byte[0], transactionID, false);

            volume.LogClient.WriteForgetTransactionRecord(transactionID, true);
            disk.ReleaseLock();
        }
Ejemplo n.º 2
0
        /// <summary>
        /// This test checks that attributes are deep cloned when assembled from FileRecordSegment list and sliced into FileRecordSegment list.
        /// </summary>
        public static void AttributeCloneTest()
        {
            byte minorNTFSVersion                     = 1;
            int  bytesPerFileRecordSegment            = 1024;
            FileRecordSegment       baseSegment       = new FileRecordSegment(30, 1);
            FileRecordSegment       segment2          = new FileRecordSegment(31, 1, baseSegment.SegmentReference);
            FileNameRecord          fileNameRecord    = new FileNameRecord(NTFSVolume.RootDirSegmentReference, "john.txt", false, DateTime.Now);
            FileNameAttributeRecord fileNameAttribute = new FileNameAttributeRecord(String.Empty);

            fileNameAttribute.Record = fileNameRecord;
            NonResidentAttributeRecord dataRecord = new NonResidentAttributeRecord(AttributeType.Data, String.Empty);

            baseSegment.ImmediateAttributes.Add(fileNameAttribute);
            baseSegment.ImmediateAttributes.Add(dataRecord);
            dataRecord.DataRunSequence.Add(new DataRun(5, 0));
            byte[] segmentBytesBefore = baseSegment.GetBytes(bytesPerFileRecordSegment, minorNTFSVersion, false);

            List <FileRecordSegment> segments = new List <FileRecordSegment>();

            segments.Add(baseSegment);
            segments.Add(segment2);
            FileRecord fileRecord = new FileRecord(segments);

            ((NonResidentAttributeRecord)fileRecord.DataRecord).DataRunSequence[0].RunLength = 8;
            fileRecord.FileNameRecord.ParentDirectory = new MftSegmentReference(8, 8);
            fileRecord.FileNameRecord.FileName        = "d";
            byte[] segmentBytesAfter = baseSegment.GetBytes(bytesPerFileRecordSegment, minorNTFSVersion, false);
            if (!ByteUtils.AreByteArraysEqual(segmentBytesBefore, segmentBytesAfter))
            {
                throw new Exception("Test failed");
            }

            fileRecord.UpdateSegments(1024, 1);
            byte[] segmentBytesBefore2 = fileRecord.Segments[0].GetBytes(bytesPerFileRecordSegment, minorNTFSVersion, false);
            ((NonResidentAttributeRecord)fileRecord.DataRecord).DataRunSequence[0].RunLength = 10;
            fileRecord.FileNameRecord.FileName = "x";
            byte[] segmentBytesAfter2 = fileRecord.Segments[0].GetBytes(bytesPerFileRecordSegment, minorNTFSVersion, false);
            if (!ByteUtils.AreByteArraysEqual(segmentBytesBefore2, segmentBytesAfter2))
            {
                throw new Exception("Test failed");
            }
        }
Ejemplo n.º 3
0
        private static FileRecordSegment CreateFileRecordSegment(long segmentNumber, FileNameRecord fileNameRecord, byte[] fileData)
        {
            fileNameRecord.AllocatedLength = (uint)fileData.Length;
            fileNameRecord.FileSize        = (uint)fileData.Length;
            FileRecordSegment fileRecordSegment = new FileRecordSegment(segmentNumber, 1);

            fileRecordSegment.IsInUse        = true;
            fileRecordSegment.ReferenceCount = 1;
            StandardInformationRecord standardInformation = (StandardInformationRecord)fileRecordSegment.CreateAttributeRecord(AttributeType.StandardInformation, String.Empty);

            standardInformation.CreationTime        = fileNameRecord.CreationTime;
            standardInformation.ModificationTime    = fileNameRecord.ModificationTime;
            standardInformation.MftModificationTime = fileNameRecord.MftModificationTime;
            standardInformation.LastAccessTime      = fileNameRecord.LastAccessTime;
            FileNameAttributeRecord fileNameAttribute = (FileNameAttributeRecord)fileRecordSegment.CreateAttributeRecord(AttributeType.FileName, String.Empty);

            fileNameAttribute.IsIndexed = true;
            fileNameAttribute.Record    = fileNameRecord;
            ResidentAttributeRecord dataRecord = (ResidentAttributeRecord)fileRecordSegment.CreateAttributeRecord(AttributeType.Data, String.Empty);

            dataRecord.Data = fileData;

            return(fileRecordSegment);
        }