@@ -47,7 +47,7 @@ def attributes(self) -> Iterator["MFTAttribute"]:
4747 yield from self ._attrs
4848
4949 def longest_filename (self ) -> Optional [objects .String ]:
50- names = [name .get_full_name () for name in self .filename_attributes ()]
50+ names = [name .get_full_name () for name in self .filename_entries ()]
5151 if not names :
5252 return None
5353
@@ -91,9 +91,17 @@ def _attributes(self) -> Iterator["MFTAttribute"]:
9191 )
9292 return
9393
94- def standard_information_attributes (self ) -> Iterator [objects .StructType ]:
94+ def standard_information_entries (
95+ self ,
96+ ) -> Iterator [objects .StructType ]:
97+ """
98+ Yields a STANDARD_INFORMATION struct for each of the
99+ STANDARD_INFORMATION attributes in this MFT record (although there
100+ should only be one per record).
101+ """
95102 for attr in self .attributes :
96- if attr .Attr_Header .AttrType .lookup () != "STANDARD_INFORMATION" :
103+ attr_type = attr .Attr_Header .AttrType .lookup ()
104+ if attr_type != "STANDARD_INFORMATION" :
97105 continue
98106
99107 si_object = (
@@ -102,10 +110,16 @@ def standard_information_attributes(self) -> Iterator[objects.StructType]:
102110
103111 yield attr .Attr_Data .cast (si_object )
104112
105- def filename_attributes (self ) -> Iterator ["MFTFileName" ]:
113+ def filename_entries (self ) -> Iterator ["MFTFileName" ]:
114+ """
115+ Yields an MFT Filename for each of the FILE_NAME attributes contained
116+ in this MFT record. There are often two - one for the long filename,
117+ and the other with the DOS 8.3 short name.
118+ """
106119 for attr in self .attributes :
107120 try :
108- if attr .Attr_Header .AttrType .lookup () != "FILE_NAME" :
121+ attr_type = attr .Attr_Header .AttrType .lookup ()
122+ if attr_type != "FILE_NAME" :
109123 continue
110124
111125 fn_object = self .symbol_table_name + constants .BANG + "FILE_NAME_ENTRY"
@@ -128,11 +142,18 @@ def _data_attributes(self):
128142 yield attr
129143
130144 def resident_data_attributes (self ) -> Iterator ["MFTAttribute" ]:
145+ """
146+ Yields all MFT attributes that contain resident data for the primary
147+ stream.
148+ """
131149 for attr in self ._data_attributes ():
132150 if attr .Attr_Header .NameLength == 0 :
133151 yield attr
134152
135153 def alternate_data_streams (self ) -> Iterator ["MFTAttribute" ]:
154+ """
155+ Yields all MFT attributes that contain alternate data streams (ADS).
156+ """
136157 for attr in self ._data_attributes ():
137158 if attr .Attr_Header .NameLength != 0 :
138159 yield attr
@@ -142,6 +163,9 @@ class MFTFileName(objects.StructType):
142163 """This represents an MFT $FILE_NAME Attribute"""
143164
144165 def get_full_name (self ) -> objects .String :
166+ """
167+ Returns the UTF-16 decoded filename.
168+ """
145169 output = self .Name .cast (
146170 "string" , encoding = "utf16" , max_length = self .NameLength * 2 , errors = "replace"
147171 )
@@ -152,6 +176,9 @@ class MFTAttribute(objects.StructType):
152176 """This represents an MFT ATTRIBUTE"""
153177
154178 def get_resident_filename (self ) -> Optional [objects .String ]:
179+ """
180+ Returns the resident filename (typically for an Alternate Data Stream (ADS)).
181+ """
155182 # 4MB chosen as cutoff instead of 4KB to allow for recovery from format /L created file systems
156183 # Length as 512 as its 256*2, which is the maximum size for an entire file path, so this is even generous
157184 if (
@@ -178,6 +205,10 @@ def get_resident_filename(self) -> Optional[objects.String]:
178205 return None
179206
180207 def get_resident_filecontent (self ) -> Optional [objects .Bytes ]:
208+ """
209+ Returns the file content that is resident within this MFT attribute,
210+ for either the primary or an alternate data stream.
211+ """
181212 # smear observed in mass testing of samples
182213 # 4MB chosen as cutoff instead of 4KB to allow for recovery from format /L created file systems
183214 if (
0 commit comments