@@ -371,21 +371,100 @@ static ULONG NtfsReadAttribute(PNTFS_VOLUME_INFO Volume, PNTFS_ATTR_CONTEXT Cont
371371 return AlreadyRead ;
372372}
373373
374- static PNTFS_ATTR_CONTEXT NtfsFindAttributeHelper (PNTFS_VOLUME_INFO Volume , PNTFS_ATTR_RECORD AttrRecord , PNTFS_ATTR_RECORD AttrRecordEnd , ULONG Type , const WCHAR * Name , ULONG NameLength )
374+ static PNTFS_ATTR_CONTEXT NtfsFindAttributeHelper (
375+ PNTFS_VOLUME_INFO Volume ,
376+ PNTFS_ATTR_RECORD AttrRecord ,
377+ PNTFS_ATTR_RECORD AttrRecordEnd ,
378+ ULONG Type ,
379+ const WCHAR * Name ,
380+ ULONG NameLength ,
381+ ULONG Recursion );
382+ static BOOLEAN NtfsReadMftRecord (PNTFS_VOLUME_INFO Volume , ULONGLONG MFTIndex , PNTFS_MFT_RECORD Buffer );
383+
384+ static PNTFS_ATTR_CONTEXT NtfsFindAttributeHelperList (
385+ PNTFS_VOLUME_INFO Volume ,
386+ PNTFS_ATTR_LIST_ATTR AttrListRecord ,
387+ PNTFS_ATTR_LIST_ATTR AttrListRecordEnd ,
388+ ULONG Type ,
389+ const WCHAR * Name ,
390+ ULONG NameLength ,
391+ ULONG Recursion )
392+ {
393+ PNTFS_MFT_RECORD MftRecord = FrLdrTempAlloc (Volume -> MftRecordSize , TAG_NTFS_MFT );
394+ if (!MftRecord )
395+ return NULL ;
396+
397+ while (AttrListRecord < AttrListRecordEnd )
398+ {
399+ ULONGLONG MftIndex = AttrListRecord -> BaseFileRef & 0xFFFFFFFFFFFF ;
400+ ULONG AttrType = AttrListRecord -> Type ;
401+
402+ if (AttrType == NTFS_ATTR_TYPE_END )
403+ break ;
404+
405+ TRACE ("Recursion = %u, AttrListRecord->Type = 0x%x\n" , Recursion , AttrType );
406+
407+ if (AttrType == Type && AttrListRecord -> NameLength == NameLength )
408+ {
409+ PWCHAR AttrListName ;
410+
411+ AttrListName = (PWCHAR )((PCHAR )AttrListRecord + AttrListRecord -> NameOffset );
412+ if (RtlEqualMemory (AttrListName , Name , NameLength << 1 ))
413+ {
414+ PNTFS_ATTR_CONTEXT Context ;
415+ PNTFS_ATTR_RECORD AttrRecord ;
416+ PNTFS_ATTR_RECORD AttrRecordEnd ;
417+
418+ if (!NtfsReadMftRecord (Volume , MftIndex , MftRecord ))
419+ goto skip ;
420+
421+ AttrRecord = (PNTFS_ATTR_RECORD )((PCHAR )MftRecord + MftRecord -> AttributesOffset );
422+ AttrRecordEnd = (PNTFS_ATTR_RECORD )((PCHAR )MftRecord + Volume -> MftRecordSize );
423+
424+ Context = NtfsFindAttributeHelper (Volume , AttrRecord , AttrRecordEnd , Type , Name , NameLength , Recursion + 1 );
425+ if (Context )
426+ {
427+ FrLdrTempFree (MftRecord , TAG_NTFS_MFT );
428+ return Context ;
429+ }
430+ }
431+ }
432+
433+ skip :
434+ if (AttrListRecord -> RecLength == 0 )
435+ break ;
436+ AttrListRecord = (PNTFS_ATTR_LIST_ATTR )((PCHAR )AttrListRecord + AttrListRecord -> RecLength );
437+ }
438+
439+ FrLdrTempFree (MftRecord , TAG_NTFS_MFT );
440+ return NULL ;
441+ }
442+
443+ static PNTFS_ATTR_CONTEXT NtfsFindAttributeHelper (
444+ PNTFS_VOLUME_INFO Volume ,
445+ PNTFS_ATTR_RECORD AttrRecord ,
446+ PNTFS_ATTR_RECORD AttrRecordEnd ,
447+ ULONG Type ,
448+ const WCHAR * Name ,
449+ ULONG NameLength ,
450+ ULONG Recursion )
375451{
376452 while (AttrRecord < AttrRecordEnd )
377453 {
378454 if (AttrRecord -> Type == NTFS_ATTR_TYPE_END )
379455 break ;
380456
381- if (AttrRecord -> Type == NTFS_ATTR_TYPE_ATTRIBUTE_LIST )
457+ TRACE ("Recursion = %u, AttrRecord->Type = 0x%x\n" , Recursion , AttrRecord -> Type );
458+
459+ /* Limit the $ATTRIBUTE_LIST recursion or else infinity loop */
460+ if (AttrRecord -> Type == NTFS_ATTR_TYPE_ATTRIBUTE_LIST && Recursion < 8 )
382461 {
383462 PNTFS_ATTR_CONTEXT Context ;
384463 PNTFS_ATTR_CONTEXT ListContext ;
385464 PVOID ListBuffer ;
386465 ULONGLONG ListSize ;
387- PNTFS_ATTR_RECORD ListAttrRecord ;
388- PNTFS_ATTR_RECORD ListAttrRecordEnd ;
466+ PNTFS_ATTR_LIST_ATTR ListAttrRecord ;
467+ PNTFS_ATTR_LIST_ATTR ListAttrRecordEnd ;
389468
390469 ListContext = NtfsPrepareAttributeContext (AttrRecord );
391470
@@ -401,13 +480,13 @@ static PNTFS_ATTR_CONTEXT NtfsFindAttributeHelper(PNTFS_VOLUME_INFO Volume, PNTF
401480 continue ;
402481 }
403482
404- ListAttrRecord = (PNTFS_ATTR_RECORD )ListBuffer ;
405- ListAttrRecordEnd = (PNTFS_ATTR_RECORD )((PCHAR )ListBuffer + ListSize );
483+ ListAttrRecord = (PNTFS_ATTR_LIST_ATTR )ListBuffer ;
484+ ListAttrRecordEnd = (PNTFS_ATTR_LIST_ATTR )((PCHAR )ListBuffer + ListSize );
406485
407486 if (NtfsReadAttribute (Volume , ListContext , 0 , ListBuffer , (ULONG )ListSize ) == ListSize )
408487 {
409- Context = NtfsFindAttributeHelper (Volume , ListAttrRecord , ListAttrRecordEnd ,
410- Type , Name , NameLength );
488+ Context = NtfsFindAttributeHelperList (Volume , ListAttrRecord , ListAttrRecordEnd ,
489+ Type , Name , NameLength , Recursion + 1 );
411490
412491 NtfsReleaseAttributeContext (ListContext );
413492 FrLdrTempFree (ListBuffer , TAG_NTFS_LIST );
@@ -419,7 +498,7 @@ static PNTFS_ATTR_CONTEXT NtfsFindAttributeHelper(PNTFS_VOLUME_INFO Volume, PNTF
419498
420499 if (AttrRecord -> Type == Type )
421500 {
422- if (AttrRecord -> NameLength == NameLength )
501+ if (AttrRecord -> NameLength == NameLength && NtfsGetAttributeSize ( AttrRecord ) != 0 )
423502 {
424503 PWCHAR AttrName ;
425504
@@ -433,7 +512,7 @@ static PNTFS_ATTR_CONTEXT NtfsFindAttributeHelper(PNTFS_VOLUME_INFO Volume, PNTF
433512 }
434513
435514 if (AttrRecord -> Length == 0 )
436- return NULL ;
515+ break ;
437516 AttrRecord = (PNTFS_ATTR_RECORD )((PCHAR )AttrRecord + AttrRecord -> Length );
438517 }
439518
@@ -451,7 +530,7 @@ static PNTFS_ATTR_CONTEXT NtfsFindAttribute(PNTFS_VOLUME_INFO Volume, PNTFS_MFT_
451530 for (NameLength = 0 ; Name [NameLength ] != 0 ; NameLength ++ )
452531 ;
453532
454- return NtfsFindAttributeHelper (Volume , AttrRecord , AttrRecordEnd , Type , Name , NameLength );
533+ return NtfsFindAttributeHelper (Volume , AttrRecord , AttrRecordEnd , Type , Name , NameLength , 0 );
455534}
456535
457536static BOOLEAN NtfsFixupRecord (PNTFS_VOLUME_INFO Volume , PNTFS_RECORD Record )
@@ -592,6 +671,7 @@ static BOOLEAN NtfsFindMftRecord(PNTFS_VOLUME_INFO Volume, ULONGLONG MFTIndex, P
592671 while (IndexEntry < IndexEntryEnd &&
593672 !(IndexEntry -> Flags & NTFS_INDEX_ENTRY_END ))
594673 {
674+ TRACE ("%s " , FileName );
595675 if (NtfsCompareFileName (FileName , IndexEntry ))
596676 {
597677 * OutMFTIndex = (IndexEntry -> Data .Directory .IndexedFile & NTFS_MFT_MASK );
@@ -675,6 +755,7 @@ static BOOLEAN NtfsFindMftRecord(PNTFS_VOLUME_INFO Volume, ULONGLONG MFTIndex, P
675755 while (IndexEntry < IndexEntryEnd &&
676756 !(IndexEntry -> Flags & NTFS_INDEX_ENTRY_END ))
677757 {
758+ TRACE ("%s " , FileName );
678759 if (NtfsCompareFileName (FileName , IndexEntry ))
679760 {
680761 TRACE ("File found\n" );
0 commit comments