public virtual FileRecord CreateFile(MftSegmentReference parentDirectory, string fileName, bool isDirectory) { // Worst case scenrario: the MFT might be full and the parent directory index requires multiple splits if (NumberOfFreeClusters < 24) { throw new DiskFullException(); } FileRecord parentDirectoryRecord = GetFileRecord(parentDirectory); m_mftLock.AcquireWriterLock(Timeout.Infinite); IndexData parentDirectoryIndex = new IndexData(this, parentDirectoryRecord, AttributeType.FileName); if (parentDirectoryIndex.ContainsFileName(fileName)) { m_mftLock.ReleaseWriterLock(); throw new AlreadyExistsException(); } List <FileNameRecord> fileNameRecords = IndexHelper.GenerateFileNameRecords(parentDirectory, fileName, isDirectory, m_generateDosNames, parentDirectoryIndex); uint transactionID = m_logClient.AllocateTransactionID(); FileRecord fileRecord = m_mft.CreateFile(fileNameRecords, transactionID); // Update parent directory index foreach (FileNameRecord fileNameRecord in fileNameRecords) { parentDirectoryIndex.AddEntry(fileRecord.BaseSegmentReference, fileNameRecord.GetBytes()); } m_logClient.WriteForgetTransactionRecord(transactionID); m_logClient.WriteRestartRecord(this.MajorVersion, true); m_mftLock.ReleaseWriterLock(); return(fileRecord); }
public virtual FileRecord CreateFile(MftSegmentReference parentDirectory, string fileName, bool isDirectory) { if (fileName.Length > FileNameRecord.MaxFileNameLength) { throw new InvalidNameException(); } // Worst case scenrario: the MFT might be full and the parent directory index requires multiple splits. // We assume IndexData.ExtendGranularity is bigger than or equal to the number of splits. if (NumberOfFreeClusters < m_mft.NumberOfClustersRequiredToExtend + NumberOfClustersRequiredToExtendIndex) { throw new DiskFullException(); } lock (m_mftLock) { FileRecord parentDirectoryRecord = GetFileRecord(parentDirectory); IndexData parentDirectoryIndex = new IndexData(this, parentDirectoryRecord, AttributeType.FileName); if (parentDirectoryIndex.ContainsFileName(fileName)) { throw new AlreadyExistsException(); } List <FileNameRecord> fileNameRecords = IndexHelper.GenerateFileNameRecords(parentDirectory, fileName, isDirectory, GenerateDosNames, parentDirectoryIndex); uint transactionID = m_logClient.AllocateTransactionID(); FileRecord fileRecord = m_mft.CreateFile(fileNameRecords, transactionID); // Update parent directory index foreach (FileNameRecord fileNameRecord in fileNameRecords) { parentDirectoryIndex.AddEntry(fileRecord.BaseSegmentReference, fileNameRecord.GetBytes()); } m_logClient.WriteForgetTransactionRecord(transactionID); m_logClient.WriteRestartRecord(true); return(fileRecord); } }