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