internal FileName(ResidentHeader header, byte[] attrBytes, string attrName) { // Headers Name = (ATTR_TYPE)header.commonHeader.ATTRType; NameString = attrName; NonResident = header.commonHeader.NonResident; AttributeId = header.commonHeader.Id; // FILE_NAME Attribute ParentSequenceNumber = (BitConverter.ToUInt16(attrBytes, 0x06)); ParentRecordNumber = (BitConverter.ToUInt64(attrBytes, 0x00) & 0x0000FFFFFFFFFFFF); BornTime = DateTime.FromFileTimeUtc(BitConverter.ToInt64(attrBytes, 0x08)); ChangedTime = DateTime.FromFileTimeUtc(BitConverter.ToInt64(attrBytes, 0x10)); ModifiedTime = DateTime.FromFileTimeUtc(BitConverter.ToInt64(attrBytes, 0x18)); AccessedTime = DateTime.FromFileTimeUtc(BitConverter.ToInt64(attrBytes, 0x20)); AllocatedSize = BitConverter.ToUInt64(attrBytes, 0x28); RealSize = BitConverter.ToUInt64(attrBytes, 0x30); Flags = BitConverter.ToUInt32(attrBytes, 0x38); ER = BitConverter.ToUInt32(attrBytes, 0x3C); NameLength = attrBytes[0x40]; Namespace = Convert.ToInt32(attrBytes[0x41]); // Get FileName Filename = Encoding.Unicode.GetString(attrBytes, 0x42, NameLength * 2).TrimEnd('\0'); }
internal ObjectId(ResidentHeader header, byte[] attrBytes, string attrName) { Name = (ATTR_TYPE)header.commonHeader.ATTRType; NameString = attrName; NonResident = header.commonHeader.NonResident; AttributeId = header.commonHeader.Id; ObjectIdGuid = new Guid(NativeMethods.GetSubArray(attrBytes, 0x00, 0x10)); if (!(attrBytes.Length < 0x20)) { BirthVolumeId = new Guid(NativeMethods.GetSubArray(attrBytes, 0x10, 0x10)); if (!(attrBytes.Length < 0x30)) { BirthObjectId = new Guid(NativeMethods.GetSubArray(attrBytes, 0x20, 0x10)); if (attrBytes.Length == 0x40) { BirthDomainId = new Guid(NativeMethods.GetSubArray(attrBytes, 0x30, 0x10)); } } } }
internal Data(ResidentHeader header, byte[] attrBytes, string attrName) { Name = (ATTR_TYPE)header.commonHeader.ATTRType; NameString = attrName; NonResident = header.commonHeader.NonResident; AttributeId = header.commonHeader.Id; RawData = NativeMethods.GetSubArray(attrBytes, 0x00, (uint)attrBytes.Length); }
internal VolumeName(ResidentHeader header, byte[] attrBytes, string attrName) { Name = (ATTR_TYPE)header.commonHeader.ATTRType; NameString = attrName; NonResident = header.commonHeader.NonResident; AttributeId = header.commonHeader.Id; VolumeNameString = Encoding.Unicode.GetString(attrBytes, 0x00, (int)header.AttrSize); }
internal VolumeInformation(ResidentHeader header, byte[] attrBytes, string attrName) { Name = (ATTR_TYPE)header.commonHeader.ATTRType; NameString = attrName; NonResident = header.commonHeader.NonResident; AttributeId = header.commonHeader.Id; Version = new Version(attrBytes[0x08], attrBytes[0x09]); Flags = (ATTR_VOLINFO)BitConverter.ToInt16(attrBytes, 0x0A); }
internal AttributeList(ResidentHeader header, byte[] attrBytes, string attrName) { Name = (Attr.ATTR_TYPE)header.commonHeader.ATTRType; NameString = attrName; NonResident = header.commonHeader.NonResident; AttributeId = header.commonHeader.Id; #region AttributeReference int i = 0; List <AttrRef> refList = new List <AttrRef>(); while (i < attrBytes.Length) { AttrRef attrRef = new AttrRef(NativeMethods.GetSubArray(attrBytes, (uint)i, (uint)BitConverter.ToUInt16(attrBytes, i + 0x04))); refList.Add(attrRef); i += attrRef.RecordLength; } AttributeReference = refList.ToArray(); #endregion AttributeReference }
internal AttributeList(ResidentHeader header, byte[] attrBytes, string attrName) { Name = (Attr.ATTR_TYPE)header.commonHeader.ATTRType; NameString = attrName; NonResident = header.commonHeader.NonResident; AttributeId = header.commonHeader.Id; #region AttributeReference int i = 0; List<AttrRef> refList = new List<AttrRef>(); while (i < attrBytes.Length) { AttrRef attrRef = new AttrRef(NativeMethods.GetSubArray(attrBytes, (uint)i, (uint)BitConverter.ToUInt16(attrBytes, i + 0x04))); refList.Add(attrRef); i += attrRef.RecordLength; } AttributeReference = refList.ToArray(); #endregion AttributeReference }
internal StandardInformation(ResidentHeader header, byte[] attrBytes, string attrName) { Name = (ATTR_TYPE)header.commonHeader.ATTRType; NameString = attrName; NonResident = header.commonHeader.NonResident; AttributeId = header.commonHeader.Id; BornTime = DateTime.FromFileTimeUtc(BitConverter.ToInt64(attrBytes, 0x00)); ModifiedTime = DateTime.FromFileTimeUtc(BitConverter.ToInt64(attrBytes, 0x08)); ChangedTime = DateTime.FromFileTimeUtc(BitConverter.ToInt64(attrBytes, 0x10)); AccessedTime = DateTime.FromFileTimeUtc(BitConverter.ToInt64(attrBytes, 0x18)); Permission = ((ATTR_STDINFO_PERMISSION)BitConverter.ToUInt32(attrBytes, 0x20)); MaxVersionNumber = BitConverter.ToUInt32(attrBytes, 0x24); VersionNumber = BitConverter.ToUInt32(attrBytes, 0x28); ClassId = BitConverter.ToUInt32(attrBytes, 0x2C); if (attrBytes.Length == 0x48) { OwnerId = BitConverter.ToUInt32(attrBytes, 0x30); SecurityId = BitConverter.ToUInt32(attrBytes, 0x34); QuotaCharged = BitConverter.ToUInt64(attrBytes, 0x38); UpdateSequenceNumber = BitConverter.ToUInt64(attrBytes, 0x40); } }
internal ObjectId(ResidentHeader header, byte[] attrBytes, string attrName) { Name = (ATTR_TYPE)header.commonHeader.ATTRType; NameString = attrName; NonResident = header.commonHeader.NonResident; AttributeId = header.commonHeader.Id; ObjectIdGuid = new Guid(NativeMethods.GetSubArray(attrBytes, 0x00, 0x10)); if (!(attrBytes.Length < 0x20)) { BirthVolumeId = new Guid(NativeMethods.GetSubArray(attrBytes, 0x10, 0x10)); if (!(attrBytes.Length < 0x30)) { BirthObjectId = new Guid(NativeMethods.GetSubArray(attrBytes, 0x20, 0x10)); if(attrBytes.Length == 0x40) { BirthDomainId = new Guid(NativeMethods.GetSubArray(attrBytes, 0x30, 0x10)); } } } }
internal static Attr Get(byte[] bytes, string volume) { #region CommonHeader if (bytes.Length == 0) { return(null); } // Instantiate a Common Header Object CommonHeader commonHeader = new CommonHeader(bytes); #endregion CommonHeader uint NameLength = (uint)commonHeader.NameLength * 2; // Decode Name byte[] into Unicode String string attributeName = Encoding.Unicode.GetString(bytes, (int)commonHeader.NameOffset, (int)NameLength); // Determine if Attribute is Resident or NonResident bool resident = (bytes[8] == 0x00); #region ResidentAttribute // If Attribute is Resident if (resident) { #region ResidentHeader // Instantiate a Resident Header Object ResidentHeader residentHeader = new ResidentHeader(NativeMethods.GetSubArray(bytes, COMMONHEADERSIZE, RESIDENTHEADERSIZE), commonHeader); #endregion ResidentHeader #region AttributeBytes // Create a byte[] representing the attribute itself int headerSize = COMMONHEADERSIZE + RESIDENTHEADERSIZE + (int)NameLength; byte[] attributeBytes = NativeMethods.GetSubArray(bytes, (uint)headerSize, commonHeader.TotalSize - (uint)headerSize); #endregion AttributeBytes #region ATTRSwitch switch (residentHeader.commonHeader.ATTRType) { case (Int32)Attr.ATTR_TYPE.STANDARD_INFORMATION: return(new StandardInformation(residentHeader, attributeBytes, attributeName)); case (Int32)Attr.ATTR_TYPE.ATTRIBUTE_LIST: return(new AttributeList(residentHeader, attributeBytes, attributeName)); case (Int32)Attr.ATTR_TYPE.FILE_NAME: return(new FileName(residentHeader, attributeBytes, attributeName)); case (Int32)Attr.ATTR_TYPE.OBJECT_ID: return(new ObjectId(residentHeader, attributeBytes, attributeName)); case (Int32)Attr.ATTR_TYPE.VOLUME_NAME: return(new VolumeName(residentHeader, attributeBytes, attributeName)); case (Int32)Attr.ATTR_TYPE.VOLUME_INFORMATION: return(new VolumeInformation(residentHeader, attributeBytes, attributeName)); case (Int32)Attr.ATTR_TYPE.DATA: return(new Data(residentHeader, attributeBytes, attributeName)); case (Int32)Attr.ATTR_TYPE.INDEX_ROOT: return(new IndexRoot(residentHeader, attributeBytes, attributeName)); default: return(null); } #endregion ATTRSwitch } #endregion ResidentAttribute #region NonResidentAttribute // Else Attribute is Non-Resident else { #region NonResidentHeader // Instantiate a Resident Header Object NonResidentHeader nonresidentHeader = new NonResidentHeader(NativeMethods.GetSubArray(bytes, COMMONHEADERSIZE, NONRESIDENTHEADERSIZE), commonHeader); #endregion NonResidentHeader #region DataRun int headerSize = 0; if (commonHeader.NameOffset != 0) { headerSize = commonHeader.NameOffset + (int)NameLength + ((int)NameLength % 8); } else { headerSize = COMMONHEADERSIZE + NONRESIDENTHEADERSIZE; } return(new NonResident(nonresidentHeader, NativeMethods.GetSubArray(bytes, (uint)headerSize, commonHeader.TotalSize - (uint)headerSize), attributeName)); #endregion DataRun } #endregion NonResidentAttribute }
internal IndexRoot(ResidentHeader header, byte[] attrBytes, string attrName) { #region ResidentHeader // Get ResidentHeader (includes Common Header) Name = (ATTR_TYPE)header.commonHeader.ATTRType; NameString = attrName; NonResident = header.commonHeader.NonResident; AttributeId = header.commonHeader.Id; #endregion ResidentHeader #region IndexRoot // IndexRoot AttributeType = (ATTR_TYPE)BitConverter.ToUInt32(attrBytes, 0x00); CollationSortingRule = BitConverter.ToUInt32(attrBytes, 0x04); IndexSize = BitConverter.ToUInt32(attrBytes, 0x08); ClustersPerIndexRecord = attrBytes[0x0C]; #endregion IndexRoot #region IndexHeader // IndexHeader StartOffset = (BitConverter.ToUInt32(attrBytes, 0x10) + 0x10); // Add 0x10 bytes to start offset to account for its offset TotalSize = BitConverter.ToUInt32(attrBytes, 0x14); AllocatedSize = BitConverter.ToUInt32(attrBytes, 0x18); Flags = ((INDEX_ROOT_FLAGS)BitConverter.ToUInt32(attrBytes, 0x1C)); #endregion IndexHeader #region IndexEntryArray if(TotalSize > StartOffset){ // IndexEntry[] byte[] EntryBytes = NativeMethods.GetSubArray(attrBytes, StartOffset, TotalSize - StartOffset); // Iterate through IndexEntry object int indexEntryOffset = 0; if (AttributeType == ATTR_TYPE.FILE_NAME) { // Instantiate empty IndexEntry List List<IndexEntry> entryList = new List<IndexEntry>(); while (indexEntryOffset < (EntryBytes.Length - 0x10)) { // Creat byte array representing IndexEntry Object int indexEntrySizeOffset = indexEntryOffset + 0x08; // Instantiate an IndexEntry Object IndexEntry indexEntry = new IndexEntry(NativeMethods.GetSubArray(EntryBytes, (uint)indexEntryOffset, (uint)BitConverter.ToUInt16(EntryBytes, indexEntrySizeOffset))); // Add IndexEntry Object to FileName List entryList.Add(indexEntry); // Increment indexEntryOffset indexEntryOffset += indexEntry.Size; } Entries = entryList.ToArray(); } } #endregion IndexEntryArray }
internal static Attr Get(byte[] bytes, string volume) { #region CommonHeader if (bytes.Length == 0) { return null; } // Instantiate a Common Header Object CommonHeader commonHeader = new CommonHeader(bytes); #endregion CommonHeader uint NameLength = (uint)commonHeader.NameLength * 2; // Decode Name byte[] into Unicode String string attributeName = Encoding.Unicode.GetString(bytes, (int)commonHeader.NameOffset, (int)NameLength); // Determine if Attribute is Resident or NonResident bool resident = (bytes[8] == 0x00); #region ResidentAttribute // If Attribute is Resident if (resident) { #region ResidentHeader // Instantiate a Resident Header Object ResidentHeader residentHeader = new ResidentHeader(NativeMethods.GetSubArray(bytes, COMMONHEADERSIZE, RESIDENTHEADERSIZE), commonHeader); #endregion ResidentHeader #region AttributeBytes // Create a byte[] representing the attribute itself int headerSize = COMMONHEADERSIZE + RESIDENTHEADERSIZE + (int)NameLength; byte[] attributeBytes = NativeMethods.GetSubArray(bytes, (uint)headerSize, commonHeader.TotalSize - (uint)headerSize); #endregion AttributeBytes #region ATTRSwitch switch (residentHeader.commonHeader.ATTRType) { case (Int32)Attr.ATTR_TYPE.STANDARD_INFORMATION: return new StandardInformation(residentHeader, attributeBytes, attributeName); case (Int32)Attr.ATTR_TYPE.ATTRIBUTE_LIST: return new AttributeList(residentHeader, attributeBytes, attributeName); case (Int32)Attr.ATTR_TYPE.FILE_NAME: return new FileName(residentHeader, attributeBytes, attributeName); case (Int32)Attr.ATTR_TYPE.OBJECT_ID: return new ObjectId(residentHeader, attributeBytes, attributeName); case (Int32)Attr.ATTR_TYPE.VOLUME_NAME: return new VolumeName(residentHeader, attributeBytes, attributeName); case (Int32)Attr.ATTR_TYPE.VOLUME_INFORMATION: return new VolumeInformation(residentHeader, attributeBytes, attributeName); case (Int32)Attr.ATTR_TYPE.DATA: return new Data(residentHeader, attributeBytes, attributeName); case (Int32)Attr.ATTR_TYPE.INDEX_ROOT: return new IndexRoot(residentHeader, attributeBytes, attributeName); default: return null; } #endregion ATTRSwitch } #endregion ResidentAttribute #region NonResidentAttribute // Else Attribute is Non-Resident else { #region NonResidentHeader // Instantiate a Resident Header Object NonResidentHeader nonresidentHeader = new NonResidentHeader(NativeMethods.GetSubArray(bytes, COMMONHEADERSIZE, NONRESIDENTHEADERSIZE), commonHeader); #endregion NonResidentHeader #region DataRun int headerSize = 0; if (commonHeader.NameOffset != 0) { headerSize = commonHeader.NameOffset + (int)NameLength + ((int)NameLength % 8); } else { headerSize = COMMONHEADERSIZE + NONRESIDENTHEADERSIZE; } return new NonResident(nonresidentHeader, NativeMethods.GetSubArray(bytes, (uint)headerSize, commonHeader.TotalSize - (uint)headerSize), attributeName); #endregion DataRun } #endregion NonResidentAttribute }
internal IndexRoot(ResidentHeader header, byte[] attrBytes, string attrName) { #region ResidentHeader // Get ResidentHeader (includes Common Header) Name = (ATTR_TYPE)header.commonHeader.ATTRType; NameString = attrName; NonResident = header.commonHeader.NonResident; AttributeId = header.commonHeader.Id; #endregion ResidentHeader #region IndexRoot // IndexRoot AttributeType = (ATTR_TYPE)BitConverter.ToUInt32(attrBytes, 0x00); CollationSortingRule = BitConverter.ToUInt32(attrBytes, 0x04); IndexSize = BitConverter.ToUInt32(attrBytes, 0x08); ClustersPerIndexRecord = attrBytes[0x0C]; #endregion IndexRoot #region IndexHeader // IndexHeader StartOffset = (BitConverter.ToUInt32(attrBytes, 0x10) + 0x10); // Add 0x10 bytes to start offset to account for its offset TotalSize = BitConverter.ToUInt32(attrBytes, 0x14); AllocatedSize = BitConverter.ToUInt32(attrBytes, 0x18); Flags = ((INDEX_ROOT_FLAGS)BitConverter.ToUInt32(attrBytes, 0x1C)); #endregion IndexHeader #region IndexEntryArray if (TotalSize > StartOffset) { // IndexEntry[] byte[] EntryBytes = NativeMethods.GetSubArray(attrBytes, StartOffset, TotalSize - StartOffset); // Iterate through IndexEntry object int indexEntryOffset = 0; if (AttributeType == ATTR_TYPE.FILE_NAME) { // Instantiate empty IndexEntry List List <IndexEntry> entryList = new List <IndexEntry>(); while (indexEntryOffset < (EntryBytes.Length - 0x10)) { // Creat byte array representing IndexEntry Object int indexEntrySizeOffset = indexEntryOffset + 0x08; // Instantiate an IndexEntry Object IndexEntry indexEntry = new IndexEntry(NativeMethods.GetSubArray(EntryBytes, (uint)indexEntryOffset, (uint)BitConverter.ToUInt16(EntryBytes, indexEntrySizeOffset))); // Add IndexEntry Object to FileName List entryList.Add(indexEntry); // Increment indexEntryOffset indexEntryOffset += indexEntry.Size; } Entries = entryList.ToArray(); } } #endregion IndexEntryArray }