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;
            }
        }
Exemple #4
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();
        }