internal DirectoryEntry AddEntry(File file, string name, FileNameNamespace nameNamespace) { if (name.Length > 255) { throw new IOException("Invalid file name, more than 255 characters: " + name); } else if (name.IndexOfAny(new char[] { '\0', '/' }) != -1) { throw new IOException(@"Invalid file name, contains '\0' or '/': " + name); } FileNameRecord newNameRecord = file.GetFileNameRecord(null, true); newNameRecord.FileNameNamespace = nameNamespace; newNameRecord.FileName = name; newNameRecord.ParentDirectory = MftReference; NtfsStream nameStream = file.CreateStream(AttributeType.FileName, null); nameStream.SetContent(newNameRecord); file.HardLinkCount++; file.UpdateRecordInMft(); Index[newNameRecord] = file.MftReference; Modified(); UpdateRecordInMft(); return(new DirectoryEntry(this, file.MftReference, newNameRecord)); }
internal void FreshenFileName(FileNameRecord fileName, bool updateMftRecord) { // // Freshen the record from the definitive info in the other attributes // StandardInformation si = StandardInformation; NtfsAttribute anonDataAttr = GetAttribute(AttributeType.Data, null); fileName.CreationTime = si.CreationTime; fileName.ModificationTime = si.ModificationTime; fileName.MftChangedTime = si.MftChangedTime; fileName.LastAccessTime = si.LastAccessTime; fileName.Flags = si.FileAttributes; if (_dirty && NtfsTransaction.Current != null) { fileName.MftChangedTime = NtfsTransaction.Current.Timestamp; } // Directories don't have directory flag set in StandardInformation, so set from MFT record if ((_records[0].Flags & FileRecordFlags.IsDirectory) != 0) { fileName.Flags |= FileAttributeFlags.Directory; } if (anonDataAttr != null) { fileName.RealSize = (ulong)anonDataAttr.PrimaryRecord.DataLength; fileName.AllocatedSize = (ulong)anonDataAttr.PrimaryRecord.AllocatedLength; } if (updateMftRecord) { foreach (NtfsStream stream in GetStreams(AttributeType.FileName, null)) { FileNameRecord fnr = stream.GetContent <FileNameRecord>(); if (fnr.Equals(fileName)) { fnr = new FileNameRecord(fileName); fnr.Flags &= ~FileAttributeFlags.ReparsePoint; stream.SetContent(fnr); } } } }
public FileNameRecord GetFileNameRecord(string name, bool freshened) { NtfsAttribute[] attrs = GetAttributes(AttributeType.FileName); StructuredNtfsAttribute <FileNameRecord> attr = null; if (String.IsNullOrEmpty(name)) { if (attrs.Length != 0) { attr = (StructuredNtfsAttribute <FileNameRecord>)attrs[0]; } } else { foreach (StructuredNtfsAttribute <FileNameRecord> a in attrs) { if (_context.UpperCase.Compare(a.Content.FileName, name) == 0) { attr = a; } } if (attr == null) { throw new FileNotFoundException("File name not found on file", name); } } FileNameRecord fnr = attr == null ? new FileNameRecord() : new FileNameRecord(attr.Content); if (freshened) { FreshenFileName(fnr, false); } return(fnr); }
internal void RemoveEntry(DirectoryEntry dirEntry) { File file = _context.GetFileByRef(dirEntry.Reference); FileNameRecord nameRecord = dirEntry.Details; Index.Remove(dirEntry.Details); foreach (NtfsStream stream in file.GetStreams(AttributeType.FileName, null)) { FileNameRecord streamName = stream.GetContent <FileNameRecord>(); if (nameRecord.Equals(streamName)) { file.RemoveStream(stream); break; } } file.HardLinkCount--; file.UpdateRecordInMft(); Modified(); UpdateRecordInMft(); }
internal static string EntryAsString(IndexEntry entry, string fileName, string indexName) { IByteArraySerializable keyValue = null; IByteArraySerializable dataValue = null; // Try to guess the type of data in the key and data fields from the filename and index name if (indexName == "$I30") { keyValue = new FileNameRecord(); dataValue = new FileRecordReference(); } else if (fileName == "$ObjId" && indexName == "$O") { keyValue = new ObjectIds.IndexKey(); dataValue = new ObjectIdRecord(); } else if (fileName == "$Reparse" && indexName == "$R") { keyValue = new ReparsePoints.Key(); dataValue = new ReparsePoints.Data(); } else if (fileName == "$Quota") { if (indexName == "$O") { keyValue = new Quotas.OwnerKey(); dataValue = new Quotas.OwnerRecord(); } else if (indexName == "$Q") { keyValue = new Quotas.OwnerRecord(); dataValue = new Quotas.QuotaRecord(); } } else if (fileName == "$Secure") { if (indexName == "$SII") { keyValue = new SecurityDescriptors.IdIndexKey(); dataValue = new SecurityDescriptors.IdIndexData(); } else if (indexName == "$SDH") { keyValue = new SecurityDescriptors.HashIndexKey(); dataValue = new SecurityDescriptors.IdIndexData(); } } try { if (keyValue != null && dataValue != null) { keyValue.ReadFrom(entry.KeyBuffer, 0); dataValue.ReadFrom(entry.DataBuffer, 0); return("{" + keyValue + "-->" + dataValue + "}"); } } catch { return("{Parsing-Error}"); } return("{Unknown-Index-Type}"); }