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(); }
private static void DeleteFiles(NTFSVolume volume, string directoryName, int count) { for (int index = 1; index <= count; index++) { string fileName = "File" + index.ToString("000000"); string filePath = "\\" + directoryName + "\\" + fileName; FileRecord fileRecord = volume.GetFileRecord(filePath); volume.DeleteFile(fileRecord); } }