public static void Test(string path, long size) { int bytesPerCluster = 512; while (bytesPerCluster <= 65536) { string volumeLabel = "FormatTest_" + bytesPerCluster.ToString(); VirtualHardDisk disk = VirtualHardDisk.CreateFixedDisk(path, size); disk.ExclusiveLock(); Partition partition = CreatePrimaryPartition(disk); NTFSVolumeCreator.Format(partition, bytesPerCluster, volumeLabel); disk.ReleaseLock(); VHDMountHelper.MountVHD(path); string driveName = MountHelper.WaitForDriveToMount(volumeLabel); if (driveName == null) { throw new Exception("Timeout waiting for volume to mount"); } bool isErrorFree = ChkdskHelper.Chkdsk(driveName); if (!isErrorFree) { throw new InvalidDataException("CHKDSK reported errors"); } VHDMountHelper.UnmountVHD(path); File.Delete(path); bytesPerCluster = bytesPerCluster * 2; } }
private static void TestCreateAndDeleteFiles(string path, long size, int count) { int bytesPerCluster = 512; while (bytesPerCluster <= 65536) { string volumeLabel = "CreateFilesTest_" + bytesPerCluster.ToString(); VirtualHardDisk disk = VirtualHardDisk.CreateFixedDisk(path, size); disk.ExclusiveLock(); Partition partition = NTFSFormatTests.CreatePrimaryPartition(disk); NTFSVolume volume = NTFSVolumeCreator.Format(partition, bytesPerCluster, volumeLabel); string directoryName = "Directory"; CreateFiles(volume, directoryName, count); disk.ReleaseLock(); VHDMountHelper.MountVHD(path); string driveName = MountHelper.WaitForDriveToMount(volumeLabel); if (driveName == null) { throw new Exception("Timeout waiting for volume to mount"); } bool isErrorFree = ChkdskHelper.Chkdsk(driveName); if (!isErrorFree) { throw new InvalidDataException("CHKDSK reported errors"); } if (count != Directory.GetFiles(driveName + directoryName).Length) { throw new InvalidDataException("Test failed"); } VHDMountHelper.UnmountVHD(path); disk.ExclusiveLock(); volume = new NTFSVolume(partition); DeleteFiles(volume, directoryName, count); disk.ReleaseLock(); VHDMountHelper.MountVHD(path); isErrorFree = ChkdskHelper.Chkdsk(driveName); if (!isErrorFree) { throw new InvalidDataException("CHKDSK reported errors"); } if (Directory.GetFiles(driveName + directoryName).Length > 0) { throw new InvalidDataException("Test failed"); } VHDMountHelper.UnmountVHD(path); File.Delete(path); bytesPerCluster = bytesPerCluster * 2; } }
private static void TestMove(string path, long size) { int bytesPerCluster = 512; while (bytesPerCluster <= 65536) { string volumeLabel = "MoveTest_" + bytesPerCluster.ToString(); VirtualHardDisk disk = VirtualHardDisk.CreateFixedDisk(path, size); disk.ExclusiveLock(); Partition partition = NTFSFormatTests.CreatePrimaryPartition(disk); NTFSVolume volume = NTFSVolumeCreator.Format(partition, bytesPerCluster, volumeLabel); string directory1Name = "Directory1"; string directory2Name = "Directory2"; FileRecord directory1Record = volume.CreateFile(NTFSVolume.RootDirSegmentReference, directory1Name, true); FileRecord directory2Record = volume.CreateFile(NTFSVolume.RootDirSegmentReference, directory2Name, true); string fileNameBefore = "Test1.txt"; string fileNameAfter = "Test2.txt"; FileRecord fileRecord = volume.CreateFile(directory1Record.BaseSegmentReference, fileNameBefore, false); NTFSFile file = new NTFSFile(volume, fileRecord); byte[] fileData = System.Text.Encoding.ASCII.GetBytes("Test"); file.Data.WriteBytes(0, fileData); volume.UpdateFileRecord(fileRecord); volume.MoveFile(fileRecord, directory2Record.BaseSegmentReference, fileNameAfter); disk.ReleaseLock(); VHDMountHelper.MountVHD(path); string driveName = MountHelper.WaitForDriveToMount(volumeLabel); if (driveName == null) { throw new Exception("Timeout waiting for volume to mount"); } bool isErrorFree = ChkdskHelper.Chkdsk(driveName); if (!isErrorFree) { throw new InvalidDataException("CHKDSK reported errors"); } byte[] bytesRead = File.ReadAllBytes(driveName + directory2Name + "\\" + fileNameAfter); if (!ByteUtils.AreByteArraysEqual(fileData, bytesRead)) { throw new InvalidDataException("Test failed"); } VHDMountHelper.UnmountVHD(path); File.Delete(path); bytesPerCluster = bytesPerCluster * 2; } }
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(); }