Exemple #1
0
        public virtual void DeleteFile(FileRecord fileRecord)
        {
            MftSegmentReference parentDirectory       = fileRecord.ParentDirectoryReference;
            FileRecord          parentDirectoryRecord = GetFileRecord(parentDirectory);
            IndexData           parentDirectoryIndex  = new IndexData(this, parentDirectoryRecord, AttributeType.FileName);

            // Update parent directory index
            List <FileNameRecord> fileNameRecords = fileRecord.FileNameRecords;

            foreach (FileNameRecord fileNameRecord in fileNameRecords)
            {
                parentDirectoryIndex.RemoveEntry(fileNameRecord.GetBytes());
            }

            // Deallocate all data clusters
            foreach (AttributeRecord atttributeRecord in fileRecord.Attributes)
            {
                if (atttributeRecord is NonResidentAttributeRecord)
                {
                    NonResidentAttributeData attributeData = new NonResidentAttributeData(this, fileRecord, (NonResidentAttributeRecord)atttributeRecord);
                    attributeData.Truncate(0);
                }
            }

            m_mft.DeleteFile(fileRecord);
        }
Exemple #2
0
        public virtual void DeleteFile(FileRecord fileRecord)
        {
            MftSegmentReference parentDirectory       = fileRecord.ParentDirectoryReference;
            FileRecord          parentDirectoryRecord = GetFileRecord(parentDirectory);

            m_mftLock.AcquireWriterLock(Timeout.Infinite);
            IndexData parentDirectoryIndex = new IndexData(this, parentDirectoryRecord, AttributeType.FileName);

            uint transactionID = m_logClient.AllocateTransactionID();
            // Update parent directory index
            List <FileNameRecord> fileNameRecords = fileRecord.FileNameRecords;

            foreach (FileNameRecord fileNameRecord in fileNameRecords)
            {
                parentDirectoryIndex.RemoveEntry(fileNameRecord.GetBytes());
            }

            // Deallocate all data clusters
            foreach (AttributeRecord atttributeRecord in fileRecord.Attributes)
            {
                if (atttributeRecord is NonResidentAttributeRecord)
                {
                    NonResidentAttributeData attributeData = new NonResidentAttributeData(this, fileRecord, (NonResidentAttributeRecord)atttributeRecord);
                    attributeData.Truncate(0);
                }
            }

            m_mft.DeleteFile(fileRecord, transactionID);
            m_logClient.WriteForgetTransactionRecord(transactionID);
            m_logClient.WriteRestartRecord(this.MajorVersion, true);
            m_mftLock.ReleaseWriterLock();
        }
Exemple #3
0
        public virtual void MoveFile(FileRecord fileRecord, MftSegmentReference newParentDirectory, string newFileName)
        {
            // Worst case scenrario: the new parent directory index requires multiple splits
            if (NumberOfFreeClusters < 4)
            {
                throw new DiskFullException();
            }

            FileRecord oldParentDirectoryRecord = GetFileRecord(fileRecord.ParentDirectoryReference);
            IndexData  oldParentDirectoryIndex  = new IndexData(this, oldParentDirectoryRecord, AttributeType.FileName);
            IndexData  newParentDirectoryIndex;

            if (fileRecord.ParentDirectoryReference == newParentDirectory)
            {
                newParentDirectoryIndex = oldParentDirectoryIndex;
            }
            else
            {
                FileRecord newParentDirectoryRecord = GetFileRecord(newParentDirectory);
                newParentDirectoryIndex = new IndexData(this, newParentDirectoryRecord, AttributeType.FileName);
                if (newParentDirectoryIndex.ContainsFileName(newFileName))
                {
                    throw new AlreadyExistsException();
                }
            }

            List <FileNameRecord> fileNameRecords = fileRecord.FileNameRecords;

            foreach (FileNameRecord fileNameRecord in fileNameRecords)
            {
                oldParentDirectoryIndex.RemoveEntry(fileNameRecord.GetBytes());
            }

            DateTime       creationTime        = fileRecord.FileNameRecord.CreationTime;
            DateTime       modificationTime    = fileRecord.FileNameRecord.ModificationTime;
            DateTime       mftModificationTime = fileRecord.FileNameRecord.MftModificationTime;
            DateTime       lastAccessTime      = fileRecord.FileNameRecord.LastAccessTime;
            ulong          allocatedLength     = fileRecord.FileNameRecord.AllocatedLength;
            ulong          fileSize            = fileRecord.FileNameRecord.FileSize;
            FileAttributes fileAttributes      = fileRecord.FileNameRecord.FileAttributes;
            ushort         packedEASize        = fileRecord.FileNameRecord.PackedEASize;

            fileNameRecords = IndexHelper.GenerateFileNameRecords(newParentDirectory, newFileName, fileRecord.IsDirectory, m_generateDosNames, newParentDirectoryIndex, creationTime, modificationTime, mftModificationTime, lastAccessTime, allocatedLength, fileSize, fileAttributes, packedEASize);
            fileRecord.RemoveAttributeRecords(AttributeType.FileName, String.Empty);
            foreach (FileNameRecord fileNameRecord in fileNameRecords)
            {
                FileNameAttributeRecord fileNameAttribute = (FileNameAttributeRecord)fileRecord.CreateAttributeRecord(AttributeType.FileName, String.Empty);
                fileNameAttribute.IsIndexed = true;
                fileNameAttribute.Record    = fileNameRecord;
            }
            UpdateFileRecord(fileRecord);

            foreach (FileNameRecord fileNameRecord in fileNameRecords)
            {
                newParentDirectoryIndex.AddEntry(fileRecord.BaseSegmentReference, fileNameRecord.GetBytes());
            }
        }
Exemple #4
0
        public virtual void DeleteFile(FileRecord fileRecord)
        {
            lock (m_mftLock)
            {
                MftSegmentReference parentDirectory       = fileRecord.ParentDirectoryReference;
                FileRecord          parentDirectoryRecord = GetFileRecord(parentDirectory);
                IndexData           parentDirectoryIndex  = new IndexData(this, parentDirectoryRecord, AttributeType.FileName);

                if (fileRecord.IsDirectory)
                {
                    IndexData directoryIndex = new IndexData(this, fileRecord, AttributeType.FileName);
                    if (!directoryIndex.IsEmpty)
                    {
                        throw new DirectoryNotEmptyException();
                    }
                }

                uint transactionID = m_logClient.AllocateTransactionID();
                // Update parent directory index
                List <FileNameRecord> fileNameRecords = fileRecord.FileNameRecords;
                foreach (FileNameRecord fileNameRecord in fileNameRecords)
                {
                    parentDirectoryIndex.RemoveEntry(fileNameRecord.GetBytes());
                }

                // Deallocate all data clusters
                foreach (AttributeRecord atttributeRecord in fileRecord.Attributes)
                {
                    if (atttributeRecord is NonResidentAttributeRecord)
                    {
                        NonResidentAttributeData attributeData = new NonResidentAttributeData(this, fileRecord, (NonResidentAttributeRecord)atttributeRecord);
                        attributeData.Truncate(0);
                    }
                }

                m_mft.DeleteFile(fileRecord, transactionID);
                m_logClient.WriteForgetTransactionRecord(transactionID);
                m_logClient.WriteRestartRecord(true);
            }
        }
Exemple #5
0
        public virtual void MoveFile(FileRecord fileRecord, MftSegmentReference newParentDirectory, string newFileName)
        {
            // Worst case scenrario: the new parent directory index requires multiple splits.
            // We assume IndexData.ExtendGranularity is bigger than or equal to the number of splits.
            if (NumberOfFreeClusters < NumberOfClustersRequiredToExtendIndex)
            {
                throw new DiskFullException();
            }

            lock (m_mftLock)
            {
                FileRecord oldParentDirectoryRecord = GetFileRecord(fileRecord.ParentDirectoryReference);
                IndexData  oldParentDirectoryIndex  = new IndexData(this, oldParentDirectoryRecord, AttributeType.FileName);
                IndexData  newParentDirectoryIndex;
                if (fileRecord.ParentDirectoryReference == newParentDirectory)
                {
                    newParentDirectoryIndex = oldParentDirectoryIndex;
                }
                else
                {
                    FileRecord newParentDirectoryRecord = GetFileRecord(newParentDirectory);
                    newParentDirectoryIndex = new IndexData(this, newParentDirectoryRecord, AttributeType.FileName);
                }

                if (newParentDirectoryIndex.ContainsFileName(newFileName))
                {
                    throw new AlreadyExistsException();
                }

                List <FileNameRecord> fileNameRecords = fileRecord.FileNameRecords;
                uint transactionID = m_logClient.AllocateTransactionID();
                foreach (FileNameRecord fileNameRecord in fileNameRecords)
                {
                    oldParentDirectoryIndex.RemoveEntry(fileNameRecord.GetBytes());
                }

                // Windows will not update the dates and FileAttributes in $File_Name as often as their counterparts in $STANDARD_INFORMATION.
                DateTime       creationTime        = fileRecord.StandardInformation.CreationTime;
                DateTime       modificationTime    = fileRecord.StandardInformation.ModificationTime;
                DateTime       mftModificationTime = fileRecord.StandardInformation.MftModificationTime;
                DateTime       lastAccessTime      = fileRecord.StandardInformation.LastAccessTime;
                ulong          allocatedLength     = fileRecord.FileNameRecord.AllocatedLength;
                FileAttributes fileAttributes      = fileRecord.StandardInformation.FileAttributes;
                ushort         packedEASize        = fileRecord.FileNameRecord.PackedEASize;
                // Windows NTFS v5.1 driver does not usually update the value of the FileSize field belonging to the FileNameRecords that are stored in the FileRecord.
                // The driver does update the value during a rename, which is inconsistent file creation and is likely to be incidental rather than intentional.
                // We will set the value to 0 to be consistent with file creation.
                fileNameRecords = IndexHelper.GenerateFileNameRecords(newParentDirectory, newFileName, fileRecord.IsDirectory, GenerateDosNames, newParentDirectoryIndex, creationTime, modificationTime, mftModificationTime, lastAccessTime, allocatedLength, 0, fileAttributes, packedEASize);
                fileRecord.RemoveAttributeRecords(AttributeType.FileName, String.Empty);
                foreach (FileNameRecord fileNameRecord in fileNameRecords)
                {
                    FileNameAttributeRecord fileNameAttribute = (FileNameAttributeRecord)fileRecord.CreateAttributeRecord(AttributeType.FileName, String.Empty);
                    fileNameAttribute.IsIndexed = true;
                    fileNameAttribute.Record    = fileNameRecord;
                }
                UpdateFileRecord(fileRecord, transactionID);

                foreach (FileNameRecord fileNameRecord in fileNameRecords)
                {
                    if (!fileRecord.IsDirectory)
                    {
                        fileNameRecord.FileSize = fileRecord.DataRecord.DataLength;
                    }
                    newParentDirectoryIndex.AddEntry(fileRecord.BaseSegmentReference, fileNameRecord.GetBytes());
                }
                m_logClient.WriteForgetTransactionRecord(transactionID);
                m_logClient.WriteRestartRecord(true);
            }
        }