48 DPRINT1(
"Error: Unable to allocate memory for context!\n");
56 DPRINT1(
"Error: Unable to allocate memory for attribute record!\n");
74 Context->CacheRunLength = DataRunLength;
75 if (DataRunOffset != -1)
79 Context->CacheRunLastLCN = DataRunOffset;
87 Context->CacheRunCurrentOffset = 0;
92 DPRINT1(
"Unable to convert data runs to MCB!\n");
108 if (
Context->pRecord->IsNonResident)
145 DPRINT(
"FindAttribute(%p, %p, 0x%x, %S, %lu, %p, %p)\n",
Vcb, MftRecord,
Type,
Name, NameLength, AttrCtx,
Offset);
172 DPRINT(
"Found context\n");
217 RemoteHdr = ExAllocateFromNPagedLookasideList(&
Vcb->FileRecLookasideList);
219 if (RemoteHdr ==
NULL)
228 DPRINT1(
"Attribute list references missing attribute to this file entry !");
229 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, RemoteHdr);
236 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, RemoteHdr);
264 return AttrRecord->
Resident.ValueLength;
300 ULONG DataSizeDifference =
Vcb->NtfsInfo.BytesPerFileRecord * NewRecords;
312 DPRINT(
"IncreaseMftSize(%p, %s)\n",
Vcb, CanWait ?
"TRUE" :
"FALSE");
322 if (!BlankFileRecord)
324 DPRINT1(
"Error: Unable to create empty file record!\n");
329 BlankFileRecord->
Flags = 0;
335 DPRINT1(
"ERROR: Couldn't find $BITMAP attribute of Mft!\n");
336 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, BlankFileRecord);
351 BitmapBytes =
DataSize.QuadPart /
Vcb->NtfsInfo.BytesPerFileRecord / 8;
352 if ((
DataSize.QuadPart /
Vcb->NtfsInfo.BytesPerFileRecord) % 8 != 0)
359 BitmapSizeDifference = BitmapBytes - BitmapSize.
QuadPart;
366 DPRINT1(
"ERROR: Unable to allocate memory for bitmap attribute!\n");
367 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, BlankFileRecord);
384 DPRINT1(
"ERROR: Bytes read != Bitmap size!\n");
385 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, BlankFileRecord);
396 DPRINT1(
"ERROR: Failed to set size of $MFT data attribute!\n");
397 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, BlankFileRecord);
409 DPRINT1(
"ERROR: Couldn't find $BITMAP attribute of Mft!\n");
410 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, BlankFileRecord);
416 if (BitmapSizeDifference > 0)
419 BitmapSize.
QuadPart = NewBitmapSize;
420 if (BitmapContext->pRecord->IsNonResident)
427 DPRINT1(
"ERROR: Failed to set size of bitmap attribute!\n");
428 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, BlankFileRecord);
442 DPRINT1(
"ERROR: Failed to update $MFT file record!\n");
443 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, BlankFileRecord);
454 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, BlankFileRecord);
458 DPRINT1(
"ERROR: Couldn't write to bitmap attribute of $MFT!\n");
463 for (
i = 0;
i < NewRecords;
i++)
468 DPRINT1(
"ERROR: Failed to write blank file record!\n");
469 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, BlankFileRecord);
481 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, BlankFileRecord);
514 ULONG FirstAttributeOffset,
518 ULONG MemBlockSize = 0;
520 ULONG CurrentOffset = FirstAttributeOffset;
523 while (CurrentAttribute->
Type !=
AttributeEnd && CurrentOffset < DeviceExt->NtfsInfo.BytesPerFileRecord)
525 CurrentOffset += CurrentAttribute->
Length;
526 MemBlockSize += CurrentAttribute->
Length;
531 MemBlockSize +=
sizeof(
ULONG) * 2;
538 return FinalAttribute;
552 ULONG NextAttributeOffset;
554 DPRINT(
"InternalSetResidentAttributeLength( %p, %p, %p, %lu, %lu )\n", DeviceExt, AttrContext, FileRecord, AttrOffset,
DataSize);
556 ASSERT(!AttrContext->pRecord->IsNonResident);
576 if (!AttrContext->pRecord)
578 DPRINT1(
"Unable to allocate memory for attribute!\n");
599 AttrContext->pRecord->Resident.ValueLength =
DataSize;
624 DPRINT(
"SetAttributeDataLength(%p, %p, %p, %lu, %p, %I64u)\n",
637 DPRINT1(
"Can't truncate a memory-mapped file!\n");
642 if (AttrContext->pRecord->IsNonResident)
662 DPRINT1(
"ERROR: Failed to set size of attribute!\n");
673 if (AttrContext->pRecord->IsNonResident)
717 AttrEnd->
Length = EndMarker;
761 ULONG BytesPerCluster =
Vcb->NtfsInfo.BytesPerCluster;
764 ULONG ClustersNeeded;
765 ULONG DesiredCluster = 0;
768 ULONG NextAssignedCluster;
769 ULONG AssignedClusters;
771 ASSERT(AttrContext->pRecord->IsNonResident);
774 if (AttrContext->pRecord->NonResident.AllocatedSize >=
AllocationSize)
782 if (ExistingClusters != 0 &&
786 DesiredCluster = (
ULONG)LastLbn + 1;
789 DPRINT(
"DesiredCluster: %lu\n", DesiredCluster);
790 DPRINT(
"Highest VCN of record: %I64u\n", AttrContext->pRecord->NonResident.HighestVCN);
792 while (ClustersNeeded > 0)
797 &NextAssignedCluster,
802 DPRINT1(
"Error: Unable to allocate requested clusters!\n");
807 Status =
AddRun(
Vcb, AttrContext, AttrOffset, FileRecord, NextAssignedCluster, AssignedClusters);
810 DPRINT1(
"Error: Unable to add data run!\n");
816 AttrContext->pRecord->NonResident.AllocatedSize += (
ULONGLONG)AssignedClusters * BytesPerCluster;
818 ClustersNeeded -= AssignedClusters;
819 DesiredCluster = NextAssignedCluster + AssignedClusters;
822 DestinationAttribute->
NonResident.AllocatedSize = AttrContext->pRecord->NonResident.AllocatedSize;
823 DestinationAttribute->
NonResident.HighestVCN = AttrContext->pRecord->NonResident.HighestVCN;
846 ULONG BytesPerCluster =
Vcb->NtfsInfo.BytesPerCluster;
850 ULONG AttributeOffset;
854 FileRecord = ExAllocateFromNPagedLookasideList(&
Vcb->FileRecLookasideList);
855 if (FileRecord ==
NULL)
869 if (DataContext->pRecord->IsNonResident)
870 NeededSize =
ROUND_UP(DataContext->pRecord->NonResident.DataSize, BytesPerCluster);
873 if (DataContext->pRecord->IsNonResident &&
875 DataContext->pRecord->NonResident.AllocatedSize > NeededSize)
881 (
ULONG)((DataContext->pRecord->NonResident.AllocatedSize - NeededSize) / BytesPerCluster));
885 DestinationAttribute->
NonResident.AllocatedSize = NeededSize;
897 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, FileRecord);
931 ULONG BytesPerCluster =
Vcb->NtfsInfo.BytesPerCluster;
935 ULONG AttributeOffset;
942 FileRecord = ExAllocateFromNPagedLookasideList(&
Vcb->FileRecLookasideList);
943 if (FileRecord ==
NULL)
956 if (!DataContext->pRecord->IsNonResident ||
964 CurrentSize = DataContext->pRecord->NonResident.AllocatedSize;
1025 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, FileRecord);
1072 ULONG BytesPerCluster =
Vcb->NtfsInfo.BytesPerCluster;
1075 ULONG ExistingClusters = AttrContext->pRecord->NonResident.AllocatedSize / BytesPerCluster;
1077 ASSERT(AttrContext->pRecord->IsNonResident);
1080 if (AttrContext->pRecord->NonResident.AllocatedSize <
AllocationSize)
1086 else if (AttrContext->pRecord->NonResident.AllocatedSize >
AllocationSize &&
1092 AttrContext->pRecord->NonResident.AllocatedSize =
AllocationSize;
1097 AttrContext->pRecord->NonResident.DataSize =
DataSize->QuadPart;
1098 AttrContext->pRecord->NonResident.InitializedSize =
DataSize->QuadPart;
1100 DestinationAttribute->
NonResident.AllocatedSize = AttrContext->pRecord->NonResident.AllocatedSize;
1106 DestinationAttribute->
NonResident.HighestVCN = AttrContext->pRecord->NonResident.HighestVCN;
1108 DPRINT(
"Allocated Size: %I64u\n", DestinationAttribute->
NonResident.AllocatedSize);
1157 ULONG NextAttributeOffset = AttrOffset + AttrContext->pRecord->Length;
1160 ASSERT(!AttrContext->pRecord->IsNonResident);
1165 if (
DataSize->QuadPart > AttrContext->pRecord->Resident.ValueLength)
1168 ULONG MaxValueLength = AttrContext->pRecord->Length - AttrContext->pRecord->Resident.ValueOffset;
1172 MaxValueLength +=
Vcb->NtfsInfo.BytesPerFileRecord - NextAttributeOffset - (
sizeof(
ULONG) * 2);
1181 ULONG NewRecordLength;
1182 ULONG EndAttributeOffset;
1183 ULONG LengthWritten;
1185 DPRINT(
"Converting attribute to non-resident.\n");
1187 AttribDataSize.
QuadPart = AttrContext->pRecord->Resident.ValueLength;
1193 if (AttribData ==
NULL)
1195 DPRINT1(
"ERROR: Couldn't allocate memory for attribute data. Can't migrate to non-resident!\n");
1203 DPRINT1(
"ERROR: Unable to read attribute before migrating!\n");
1227 if (AttrContext->pRecord->NameLength != 0)
1233 AttrContext->pRecord->NameLength *
sizeof(
WCHAR));
1237 NewRecord->
NonResident.MappingPairsOffset = 0x40 + (AttrContext->pRecord->NameLength *
sizeof(
WCHAR));
1241 EndAttributeOffset = AttrOffset + NewRecord->
NonResident.MappingPairsOffset + 1;
1245 NewRecord->
Length = EndAttributeOffset - AttrOffset;
1264 DPRINT1(
"Unable to create LargeMcb!\n");
1278 DPRINT1(
"ERROR: Couldn't update file record to continue migration!\n");
1287 AttrContext->pRecord = NewRecord;
1293 DPRINT1(
"ERROR: Unable to migrate resident attribute!\n");
1305 DPRINT1(
"ERROR: Unable to write attribute data to non-resident clusters during migration!\n");
1318 if (!AttrContext->pRecord->IsNonResident)
1377 ULONG UsedBufferSize;
1387 if (TempBuffer ==
NULL)
1389 DPRINT1(
"Not enough memory!\n");
1395 Context->pRecord->NonResident.HighestVCN + 1,
1397 Vcb->NtfsInfo.BytesPerFileRecord,
1400 DataRun = TempBuffer;
1405 DataRun =
DecodeRun(DataRun, &DataRunOffset, &DataRunLength);
1409 DataRunStartLCN = LastLCN + DataRunOffset;
1410 LastLCN = DataRunStartLCN;
1415 DataRunStartLCN = -1;
1418 if (
Offset >= CurrentOffset &&
1419 Offset < CurrentOffset + (DataRunLength *
Vcb->NtfsInfo.BytesPerCluster))
1431 CurrentOffset += DataRunLength *
Vcb->NtfsInfo.BytesPerCluster;
1441 DataRunStartLCN *
Vcb->NtfsInfo.BytesPerCluster +
Offset - CurrentOffset,
1447 Mapped += RunLength;
1450 if (RunLength == DataRunLength *
Vcb->NtfsInfo.BytesPerCluster - (
Offset - CurrentOffset))
1456 CurrentOffset += DataRunLength *
Vcb->NtfsInfo.BytesPerCluster;
1457 DataRun =
DecodeRun(DataRun, &DataRunOffset, &DataRunLength);
1460 DataRunStartLCN = LastLCN + DataRunOffset;
1461 LastLCN = DataRunStartLCN;
1464 DataRunStartLCN = -1;
1473 DataRunStartLCN *
Vcb->NtfsInfo.BytesPerCluster,
1479 Mapped += RunLength;
1482 if (
Length == 0 && RunLength != DataRunLength *
Vcb->NtfsInfo.BytesPerCluster)
1489 CurrentOffset += DataRunLength *
Vcb->NtfsInfo.BytesPerCluster;
1490 DataRun =
DecodeRun(DataRun, &DataRunOffset, &DataRunLength);
1494 DataRunStartLCN = LastLCN + DataRunOffset;
1495 LastLCN = DataRunStartLCN;
1500 DataRunStartLCN = -1;
1507 Context->CacheRunStartLCN = DataRunStartLCN;
1508 Context->CacheRunLength = DataRunLength;
1509 Context->CacheRunLastLCN = LastLCN;
1510 Context->CacheRunCurrentOffset = CurrentOffset;
1515 *MappedLength = Mapped;
1563 ULONG AlreadyRead = 0;
1564 ULONG Transferred = 0;
1568 if (!
Context->pRecord->IsNonResident)
1597 Vcb->NtfsInfo.BytesPerSector,
1615 if (Transferred < AlreadyRead)
1617 DPRINT1(
"Short read: expected %lu bytes, got %lu\n", AlreadyRead, Transferred);
1618 AlreadyRead = Transferred;
1682 PULONG RealLengthWritten,
1686 ULONG MappedLength = 0;
1687 ULONG Transferred = 0;
1693 DPRINT(
"WriteAttribute(%p, %p, %I64u, %p, %lu, %p, %p)\n",
Vcb,
Context,
Offset,
Buffer,
Length, RealLengthWritten, FileRecord);
1695 *RealLengthWritten = 0;
1699 if (!
Context->pRecord->IsNonResident)
1701 ULONG AttributeOffset;
1706 ASSERT(
Offset + Length <= Context->pRecord->Resident.ValueLength);
1710 DPRINT1(
"DRIVER ERROR: Attribute is too small!\n");
1715 if (FileRecord ==
NULL)
1717 FileRecord = ExAllocateFromNPagedLookasideList(&
Vcb->FileRecLookasideList);
1720 DPRINT1(
"Error: Couldn't allocate file record!\n");
1724 FileRecordAllocated =
TRUE;
1740 DPRINT1(
"ERROR: Couldn't find matching attribute!\n");
1741 if(FileRecordAllocated)
1742 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, FileRecord);
1748 DPRINT(
"Offset: %I64u, AttributeOffset: %u, ValueOffset: %u\n",
Offset, AttributeOffset,
Context->pRecord->Resident.ValueLength);
1751 if (
Offset +
Length + AttributeOffset +
Context->pRecord->Resident.ValueOffset >
Vcb->NtfsInfo.BytesPerFileRecord)
1753 DPRINT1(
"DRIVER ERROR: Data being written extends past end of file record!\n");
1755 if (FileRecordAllocated)
1756 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, FileRecord);
1770 if (FileRecordAllocated)
1771 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, FileRecord);
1774 *RealLengthWritten =
Length;
1789 DPRINT1(
"FIXME: Attribute needs to be enlarged (mapped %lu of %lu bytes).\n",
1800 Vcb->NtfsInfo.BytesPerSector,
1813 *RealLengthWritten = 0;
1817 *RealLengthWritten = Transferred;
1819 if (Transferred <
Length)
1821 DPRINT1(
"Short write: expected %lu bytes, wrote %lu\n",
Length, Transferred);
1834 PULONG RealLengthWritten,
1874 FileRecord = ExAllocateFromNPagedLookasideList(&
Vcb->FileRecLookasideList);
1875 if (FileRecord ==
NULL)
1883 DPRINT1(
"Couldn't read the $UpCase file record!\n");
1884 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, FileRecord);
1891 DPRINT1(
"$UpCase has no data stream!\n");
1892 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, FileRecord);
1899 DPRINT1(
"$UpCase is %I64u bytes, expected %u\n",
Size, 0x10000 *
sizeof(
WCHAR));
1901 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, FileRecord);
1909 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, FileRecord);
1916 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, FileRecord);
1947 DPRINT1(
"ReadFileRecord failed: %I64u read, %lu expected\n",
BytesRead,
Vcb->NtfsInfo.BytesPerFileRecord);
1952 DPRINT(
"Sequence number: %u\n",
file->SequenceNumber);
2016 DPRINT1(
"Record %I64u is missing $STANDARD_INFORMATION or $FILE_NAME\n", MFTIndex);
2059 DPRINT1(
"Failed to write file record %I64u (Status %lx)\n", MFTIndex,
Status);
2095 ULONG CurrentEntry = 0;
2097 DPRINT(
"UpdateFileNameRecord(%p, %I64d, %wZ, %s, %lx, %s)\n",
2101 DirSearch ?
"TRUE" :
"FALSE",
2103 CaseSensitive ?
"TRUE" :
"FALSE");
2108 MftRecord = ExAllocateFromNPagedLookasideList(&
Vcb->FileRecLookasideList);
2109 if (MftRecord ==
NULL)
2117 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, MftRecord);
2125 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, MftRecord);
2130 if (IndexRecord ==
NULL)
2133 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, MftRecord);
2140 DPRINT1(
"ERROR: Failed to read Index Root!\n");
2143 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, MftRecord);
2154 DPRINT(
"IndexRecordSize: %x IndexBlockSize: %x\n",
Vcb->NtfsInfo.BytesPerIndexRecord, IndexRoot->
SizeOfEntry);
2172 ULONG LengthWritten;
2176 DPRINT1(
"ERROR: Couldn't update Index Root!\n");
2183 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, MftRecord);
2218 ULONG IndexBlockSize,
2235 DPRINT(
"UpdateIndexEntryFileName(%p, %p, %p, %lu, %p, %p, %wZ, %lu, %lu, %s, %lx, %s)\n",
2245 DirSearch ?
"TRUE" :
"FALSE",
2247 CaseSensitive ?
"TRUE" :
"FALSE");
2250 IndexEntry = FirstEntry;
2251 while (IndexEntry < LastEntry &&
2255 *CurrentEntry >= *StartEntry &&
2259 *StartEntry = *CurrentEntry;
2284 (*CurrentEntry) += 1;
2290 if (IndexRecord ==
NULL)
2304 DPRINT(
"Corrupted filesystem!\n");
2310 for (RecordOffset = 0; RecordOffset < IndexAllocationSize; RecordOffset += IndexBlockSize)
2312 ReadAttribute(
Vcb, IndexAllocationCtx, RecordOffset, IndexRecord, IndexBlockSize);
2347 DPRINT1(
"Error: Failed to update fixup sequence array!\n");
2354 DPRINT1(
"ERROR Performing write!\n");
2398 DPRINT(
"UpdateFileRecord(%p, 0x%I64x, %p)\n",
Vcb, MftIndex, FileRecord);
2406 MftIndex *
Vcb->NtfsInfo.BytesPerFileRecord,
2407 (
const PUCHAR)FileRecord,
2408 Vcb->NtfsInfo.BytesPerFileRecord,
2414 DPRINT1(
"UpdateFileRecord failed: %lu written, %lu expected\n",
BytesWritten,
Vcb->NtfsInfo.BytesPerFileRecord);
2434 USANumber = *(USA++);
2435 USACount =
Record->UsaCount - 1;
2438 DPRINT(
"FixupUpdateSequenceArray(%p, %p)\nUSANumber: %u\tUSACount: %u\n",
Vcb,
Record, USANumber, USACount);
2442 if (*Block != USANumber)
2444 DPRINT1(
"Mismatch with USA: %u read, %u expected\n" , *Block, USANumber);
2494 ULONG LengthWritten;
2497 UCHAR SystemReservedBits;
2499 DPRINT(
"AddNewMftEntry(%p, %p, %p, %s)\n", FileRecord, DeviceExt, DestinationIndex, CanWait ?
"TRUE" :
"FALSE");
2507 DPRINT1(
"ERROR: Couldn't find $Bitmap attribute of master file table!\n");
2530 if (AttrBytesRead != BitmapDataSize)
2532 DPRINT1(
"ERROR: Unable to read $Bitmap attribute of master file table!\n");
2545 DeviceExt->NtfsInfo.BytesPerFileRecord;
2548 DPRINT1(
"\tFIXME: bitmap sizes beyond 32bits are not yet supported! (Your NTFS volume is too large)\n");
2560 if ((
LONG)MftIndex == -1)
2562 DPRINT1(
"Couldn't find free space in MFT for file record, increasing MFT size.\n");
2571 DPRINT1(
"ERROR: Couldn't find space in MFT for file or increase MFT size!\n");
2575 return AddNewMftEntry(FileRecord, DeviceExt, DestinationIndex, CanWait);
2578 DPRINT(
"Creating file record at MFT index: %I64u\n", MftIndex);
2592 DPRINT1(
"ERROR encountered when writing $Bitmap attribute!\n");
2603 DPRINT1(
"ERROR: Unable to write file record!\n");
2609 *DestinationIndex = MftIndex;
2644 ULONG IndexRootOffset,
2647 ULONG MaxIndexRootSize;
2651 MaxIndexRootSize = DeviceExt->NtfsInfo.BytesPerFileRecord
2653 - IndexRootRecord->
Resident.ValueOffset
2655 - (
sizeof(
ULONG) * 2);
2661 MaxIndexRootSize -= CurrentAttribute->
Length;
2665 return MaxIndexRootSize;
2714 ULONG IndexRootOffset;
2716 ULONG LengthWritten;
2718 ULONG AttributeLength;
2720 ULONG BtreeIndexLength;
2721 ULONG MaxIndexRootSize;
2725 ULONG NewMaxIndexRootSize;
2729 ParentFileRecord = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
2730 if (!ParentFileRecord)
2732 DPRINT1(
"ERROR: Couldn't allocate memory for file record!\n");
2740 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, ParentFileRecord);
2741 DPRINT1(
"ERROR: Couldn't read parent directory with index %I64u\n",
2747 DPRINT1(
"Dumping old parent file record:\n");
2761 DPRINT1(
"ERROR: Couldn't find $I30 $INDEX_ROOT attribute for parent directory with MFT #: %I64u!\n",
2763 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, ParentFileRecord);
2768 MaxIndexRootSize =
GetMaxIndexRootSize(DeviceExt, ParentFileRecord, IndexRootOffset, IndexRootContext->pRecord);
2775 DPRINT1(
"ERROR: Couldn't allocate memory for index root attribute!\n");
2777 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, ParentFileRecord);
2785 DPRINT1(
"ERROR: Couln't read index root attribute for Mft index #%I64u\n", DirectoryMftIndex);
2788 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, ParentFileRecord);
2800 DPRINT1(
"ERROR: Failed to create B-Tree from Index!\n");
2803 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, ParentFileRecord);
2813 FileReferenceNumber,
2823 DPRINT1(
"ERROR: Failed to insert '%.*S' into the index of MFT record %I64u (Status %lx)\n",
2825 FilenameAttribute->
Name,
2831 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, ParentFileRecord);
2861 AttributeLength = MinIndexRootSize.
LowPart;
2876 DPRINT1(
"ERROR: Unable to set length of index root!\n");
2880 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, ParentFileRecord);
2888 DPRINT1(
"ERROR: Failed to update index allocation from B-Tree!\n");
2892 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, ParentFileRecord);
2897 DPRINT1(
"Index Allocation updated\n");
2902 NewMaxIndexRootSize =
GetMaxIndexRootSize(DeviceExt, ParentFileRecord, IndexRootOffset, IndexRootContext->pRecord);
2907 if (NodeSize > NewMaxIndexRootSize)
2909 DPRINT(
"Demoting index root.\nNodeSize: 0x%lx\nNewMaxIndexRootSize: 0x%lx\n", NodeSize, NewMaxIndexRootSize);
2914 DPRINT1(
"ERROR: Failed to demote index root!\n");
2918 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, ParentFileRecord);
2926 DPRINT1(
"ERROR: Failed to update index allocation from B-Tree!\n");
2930 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, ParentFileRecord);
2935 NewMaxIndexRootSize =
GetMaxIndexRootSize(DeviceExt, ParentFileRecord, IndexRootOffset, IndexRootContext->pRecord);
2942 DPRINT1(
"ERROR: Failed to create Index root from B-Tree!\n");
2946 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, ParentFileRecord);
2960 if (AttributeLength != IndexRootContext->pRecord->Resident.ValueLength)
2973 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, ParentFileRecord);
2974 DPRINT1(
"ERROR: Unable to set resident attribute length!\n");
2985 DPRINT1(
"ERROR: Failed to update file record of directory with index: %llx\n", DirectoryMftIndex);
2986 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, ParentFileRecord);
3003 DPRINT1(
"ERROR: Unable to write new index root attribute to parent directory!\n");
3007 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, ParentFileRecord);
3015 DPRINT1(
"ERROR: Couldn't read parent directory after messing with it!\n");
3020 DPRINT1(
"Dumping new B-Tree:\n");
3025 DPRINT1(
"ERROR: Couldn't re-create b-tree\n");
3041 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, ParentFileRecord);
3106 ULONG IndexRootOffset;
3108 ULONG LengthWritten;
3109 ULONG AttributeLength;
3110 ULONG BtreeIndexLength;
3111 ULONG MaxIndexRootSize;
3115 DPRINT(
"NtfsRemoveFilenameFromDirectory(%p, %I64u, %p, %s)\n",
3116 DeviceExt, DirectoryMftIndex, FilenameAttribute, CaseSensitive ?
"TRUE" :
"FALSE");
3118 ParentFileRecord = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
3119 if (!ParentFileRecord)
3121 DPRINT1(
"ERROR: Couldn't allocate memory for file record!\n");
3128 DPRINT1(
"ERROR: Couldn't read parent directory with index %I64u\n", DirectoryMftIndex);
3129 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, ParentFileRecord);
3142 DPRINT1(
"ERROR: Couldn't find $I30 $INDEX_ROOT attribute for parent directory with MFT #: %I64u!\n",
3144 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, ParentFileRecord);
3152 DPRINT1(
"ERROR: Couldn't allocate memory for index root attribute!\n");
3154 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, ParentFileRecord);
3161 DPRINT1(
"ERROR: Couldn't read index root attribute for Mft index #%I64u\n", DirectoryMftIndex);
3164 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, ParentFileRecord);
3171 DPRINT1(
"ERROR: Failed to create B-Tree from Index!\n");
3174 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, ParentFileRecord);
3185 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, ParentFileRecord);
3195 DPRINT1(
"ERROR: Failed to remove '%.*S' from the index of MFT record %I64u (Status %lx)\n",
3197 FilenameAttribute->
Name,
3203 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, ParentFileRecord);
3213 DPRINT1(
"ERROR: Failed to update index allocation from B-Tree!\n");
3217 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, ParentFileRecord);
3222 MaxIndexRootSize =
GetMaxIndexRootSize(DeviceExt, ParentFileRecord, IndexRootOffset, IndexRootContext->pRecord);
3227 DPRINT1(
"ERROR: Failed to create Index root from B-Tree!\n");
3231 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, ParentFileRecord);
3241 if (AttributeLength != IndexRootContext->pRecord->Resident.ValueLength)
3250 DPRINT1(
"ERROR: Unable to set resident attribute length!\n");
3254 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, ParentFileRecord);
3264 DPRINT1(
"ERROR: Failed to update file record of directory with index: %I64x\n", DirectoryMftIndex);
3268 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, ParentFileRecord);
3281 DPRINT1(
"ERROR: Unable to write new index root attribute to parent directory!\n");
3289 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, ParentFileRecord);
3345 ULONG LengthWritten;
3350 DPRINT(
"FreeMftEntry(%p, %I64u)\n", DeviceExt, MftIndex);
3354 FileRecord = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
3361 DPRINT1(
"ERROR: Couldn't read file record %I64u to free it!\n", MftIndex);
3362 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
3366 FileRecord->
Flags &= ~FRH_IN_USE;
3374 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
3378 DPRINT1(
"ERROR: Couldn't write file record %I64u while freeing it!\n", MftIndex);
3385 DPRINT1(
"ERROR: Couldn't find $Bitmap attribute of master file table!\n");
3403 if (AttrBytesRead != BitmapDataSize)
3405 DPRINT1(
"ERROR: Unable to read $Bitmap attribute of master file table!\n");
3412 DeviceExt->NtfsInfo.BytesPerFileRecord;
3415 DPRINT1(
"\tFIXME: bitmap sizes beyond 32bits are not yet supported! (Your NTFS volume is too large)\n");
3421 if (MftIndex >= BitmapBits.
QuadPart)
3423 DPRINT1(
"ERROR: Mft index %I64u is beyond the end of the master file table!\n", MftIndex);
3435 DPRINT1(
"ERROR encountered when writing $Bitmap attribute!\n");
3478 ULONG AttributeOffset;
3480 DPRINT(
"NtfsDeleteFileRecord(%p, %I64u, %s)\n", DeviceExt, MftIndex, CaseSensitive ?
"TRUE" :
"FALSE");
3482 FileRecord = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
3489 DPRINT1(
"ERROR: Couldn't read file record %I64u to delete it!\n", MftIndex);
3490 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
3501 while (AttributeOffset < DeviceExt->NtfsInfo.BytesPerFileRecord &&
3515 DPRINT1(
"ERROR: Failed to remove '%.*S' from directory %I64u!\n",
3519 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
3524 if (Attribute->
Length == 0)
3527 AttributeOffset += Attribute->
Length;
3535 while (AttributeOffset < DeviceExt->NtfsInfo.BytesPerFileRecord &&
3554 DPRINT1(
"ERROR: Failed to free clusters of attribute 0x%lx of file %I64u!\n",
3555 Attribute->
Type, MftIndex);
3562 if (Attribute->
Length == 0)
3565 AttributeOffset += Attribute->
Length;
3569 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
3585 DPRINT(
"AddFixupArray(%p, %p)\n fixupArray->USN: %u, ArrayEntryCount: %u\n",
Vcb,
Record, fixupArray->
USN, ArrayEntryCount);
3589 for (
i = 0;
i < ArrayEntryCount;
i++)
3594 fixupArray->
Array[
i] = *pShortToFixUp;
3595 *pShortToFixUp = fixupArray->
USN;
3613 DiskSector.
u.LowPart *
Vcb->NtfsInfo.SectorsPerCluster,
3614 count *
Vcb->NtfsInfo.SectorsPerCluster,
3615 Vcb->NtfsInfo.BytesPerSector,
3650 Ret = FsRtlIsNameInExpression(&IntFileName, &EntryName, !CaseSensitive,
3699 ULONG LengthWritten;
3702 MirrorFileRecord = ExAllocateFromNPagedLookasideList(&
Vcb->FileRecLookasideList);
3703 if (!MirrorFileRecord)
3705 DPRINT1(
"Error: Failed to allocate memory for $MFTMirr!\n");
3713 DPRINT1(
"ERROR: Failed to read $MFTMirr!\n");
3714 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, MirrorFileRecord);
3722 DPRINT1(
"ERROR: Couldn't find $DATA attribute!\n");
3723 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, MirrorFileRecord);
3731 DPRINT1(
"ERROR: Couldn't find $DATA attribute!\n");
3733 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, MirrorFileRecord);
3746 DPRINT1(
"Error: Couldn't allocate memory for $DATA buffer!\n");
3749 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, MirrorFileRecord);
3759 DPRINT1(
"Error: Failed to read $DATA for $MFTMirr!\n");
3763 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, MirrorFileRecord);
3777 DPRINT1(
"ERROR: Failed to write $DATA attribute of $MFTMirr!\n");
3784 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, MirrorFileRecord);
3794 DPRINT1(
"Entry: %p\n", IndexEntry);
3817 ULONG IndexBlockSize,
3837 DPRINT(
"BrowseSubNodeIndexEntries(%p, %p, %lu, %wZ, %p, %p, %I64d, %lu, %lu, %s, %s, %p)\n",
3842 IndexAllocationContext,
3848 DirSearch ?
"TRUE" :
"FALSE",
3849 CaseSensitive ?
"TRUE" :
"FALSE",
3854 if (IndexBlockSize < Vcb->NtfsInfo.BytesPerCluster)
3855 NodeNumber = VCN / (IndexBlockSize /
Vcb->NtfsInfo.BytesPerSector);
3857 NodeNumber = VCN / (IndexBlockSize /
Vcb->NtfsInfo.BytesPerCluster);
3862 DPRINT1(
"File system corruption detected, node with VCN %I64u is marked as deleted.\n", VCN);
3870 DPRINT1(
"Unable to allocate memory for index record!\n");
3881 DPRINT1(
"Unable to read index record!\n");
3888 DPRINT1(
"File system corruption detected, no index record at VCN %I64u of MFT record %I64u "
3889 "(offset 0x%I64x, block size %lu, cluster %lu, index record %lu, signature 0x%08lx)\n",
3894 Vcb->NtfsInfo.BytesPerCluster,
3895 Vcb->NtfsInfo.BytesPerIndexRecord,
3906 DPRINT1(
"Failed to apply fixup array!\n");
3916 IndexEntry = FirstEntry;
3917 while (IndexEntry <= LastEntry)
3924 DPRINT1(
"Filesystem corruption detected!\n");
3932 IndexAllocationContext,
3954 *CurrentEntry >= *StartEntry &&
3958 *StartEntry = *CurrentEntry;
3965 (*CurrentEntry) += 1;
3979 ULONG IndexBlockSize,
3997 DPRINT(
"BrowseIndexEntries(%p, %p, %p, %lu, %p, %p, %wZ, %lu, %lu, %s, %s, %p)\n",
4007 DirSearch ?
"TRUE" :
"FALSE",
4008 CaseSensitive ?
"TRUE" :
"FALSE",
4020 DPRINT1(
"Potential file system corruption detected!\n");
4033 DPRINT1(
"Error: failed to allocate bitmap!");
4048 DPRINT1(
"ERROR: Failed to read bitmap attribute!\n");
4061 IndexAllocationContext =
NULL;
4066 IndexEntry = FirstEntry;
4067 while (IndexEntry <= LastEntry)
4074 DPRINT1(
"Filesystem corruption detected!\n");
4082 IndexAllocationContext,
4095 DPRINT1(
"Sub-node at VCN %I64u abandoned while looking for '%wZ' (Status %lx)\n",
4115 *CurrentEntry >= *StartEntry &&
4119 *StartEntry = *CurrentEntry;
4121 if (IndexAllocationContext)
4131 (*CurrentEntry) += 1;
4136 if (IndexAllocationContext)
4138 DPRINT(
"'%wZ' not found after scanning %lu entries of MFT record %I64u "
4139 "(index allocation present)\n",
4165 ULONG CurrentEntry = 0;
4167 DPRINT(
"NtfsFindMftRecord(%p, %I64d, %wZ, %lu, %s, %s, %p)\n",
4172 DirSearch ?
"TRUE" :
"FALSE",
4173 CaseSensitive ?
"TRUE" :
"FALSE",
4176 MftRecord = ExAllocateFromNPagedLookasideList(&
Vcb->FileRecLookasideList);
4177 if (MftRecord ==
NULL)
4185 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, MftRecord);
4193 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, MftRecord);
4198 if (IndexRecord ==
NULL)
4201 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, MftRecord);
4214 DPRINT(
"IndexRecordSize: %x IndexBlockSize: %x\n",
Vcb->NtfsInfo.BytesPerIndexRecord, IndexRoot->
SizeOfEntry);
4230 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, MftRecord);
4245 ULONG FirstEntry = 0;
4247 DPRINT(
"NtfsLookupFileAt(%p, %wZ, %s, %p, %p, %I64x)\n",
4250 CaseSensitive ?
"TRUE" :
"FALSE",
4257 while (Current.
Length != 0)
4259 DPRINT(
"Current: %wZ\n", &Current);
4267 if (Remaining.
Length == 0)
4274 *FileRecord = ExAllocateFromNPagedLookasideList(&
Vcb->FileRecLookasideList);
4275 if (*FileRecord ==
NULL)
4277 DPRINT(
"NtfsLookupFileAt: Can't allocate MFT record\n");
4284 DPRINT(
"NtfsLookupFileAt: Can't read MFT record\n");
4285 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, *FileRecord);
4289 *MFTIndex = CurrentMFTIndex;
4316 for (
j = 0;
j < 8;
j++)
4354 for (
j = 0;
j < 8;
j++)
4373 DPRINT(
"NtfsFindFileAt(%p, %wZ, %lu, %p, %p, %I64x, %s)\n",
4380 (CaseSensitive ?
"TRUE" :
"FALSE"));
4385 DPRINT(
"NtfsFindFileAt: NtfsFindMftRecord() failed with status 0x%08lx\n",
Status);
4389 *FileRecord = ExAllocateFromNPagedLookasideList(&
Vcb->FileRecLookasideList);
4390 if (*FileRecord ==
NULL)
4392 DPRINT(
"NtfsFindFileAt: Can't allocate MFT record\n");
4399 DPRINT(
"NtfsFindFileAt: Can't read MFT record\n");
4400 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, *FileRecord);
4404 *MFTIndex = CurrentMFTIndex;
4411#define NTFS_MAX_INDEX_DEPTH 32
4446 if (IndexBuffer ==
NULL)
4450 IndexAllocationContext,
4456 DPRINT1(
"Unable to read index node at VCN %I64u\n", Vcn);
4471 IndexAllocationContext,
4523 IndexAllocationContext,
4563 ULONG IndexRootLength;
4568 FileRecord = ExAllocateFromNPagedLookasideList(&
Vcb->FileRecLookasideList);
4569 if (FileRecord ==
NULL)
4581 if (IndexRootLength <
sizeof(*IndexRoot))
4588 if (IndexRoot ==
NULL)
4618 IndexAllocationContext,
4625 if (IndexRoot !=
NULL)
4627 if (IndexAllocationContext !=
NULL)
4629 if (IndexRootContext !=
NULL)
4631 ExFreeToNPagedLookasideList(&
Vcb->FileRecLookasideList, FileRecord);
#define ALIGN_UP_BY(size, align)
PVOID Alloc(IN DWORD dwFlags, IN SIZE_T dwBytes)
struct NTFS_ATTR_RECORD * PNTFS_ATTR_RECORD
#define NTFS_FILE_NAME_DOS
#define NTFS_INDEX_ENTRY_NODE
#define NTFS_INDEX_ENTRY_END
#define NTFS_FILE_MFTMIRR
NTSTATUS CreateBTreeFromIndex(PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecordWithIndex, PNTFS_ATTR_CONTEXT IndexRootContext, PINDEX_ROOT_ATTRIBUTE IndexRoot, PB_TREE *NewTree)
NTSTATUS NtfsRemoveKey(PB_TREE_FILENAME_NODE Node, PB_TREE_KEY SearchKey, BOOLEAN CaseSensitive)
VOID DestroyBTreeKey(PB_TREE_KEY Key)
ULONGLONG GetIndexEntryVCN(PINDEX_ENTRY_ATTRIBUTE IndexEntry)
NTSTATUS NtfsInsertKey(PB_TREE Tree, ULONGLONG FileReference, PFILENAME_ATTRIBUTE FileNameAttribute, PB_TREE_FILENAME_NODE Node, BOOLEAN CaseSensitive, ULONG MaxIndexRootSize, ULONG IndexRecordSize, PB_TREE_KEY *MedianKey, PB_TREE_FILENAME_NODE *NewRightHandSibling)
ULONGLONG GetAllocationOffsetFromVCN(PDEVICE_EXTENSION DeviceExt, ULONG IndexBufferSize, ULONGLONG Vcn)
NTSTATUS UpdateIndexAllocation(PDEVICE_EXTENSION DeviceExt, PB_TREE Tree, ULONG IndexBufferSize, PFILE_RECORD_HEADER FileRecord)
VOID DestroyBTree(PB_TREE Tree)
NTSTATUS DemoteBTreeRoot(PB_TREE Tree)
ULONG GetSizeOfIndexEntries(PB_TREE_FILENAME_NODE Node)
VOID DumpBTree(PB_TREE Tree)
NTSTATUS CreateIndexRootFromBTree(PDEVICE_EXTENSION DeviceExt, PB_TREE Tree, ULONG MaxIndexSize, PINDEX_ROOT_ATTRIBUTE *IndexRoot, ULONG *Length)
PB_TREE_KEY CreateBTreeKeyFromFilename(ULONGLONG FileReference, PFILENAME_ATTRIBUTE FileNameAttribute)
#define STATUS_NOT_IMPLEMENTED
#define RtlInitializeBitMap
#define RtlFindClearBitsAndSet
_In_ D3DDDI_VIDEO_PRESENT_TARGET_ID _In_ ULONG _In_ ULONG DataLength
_In_ ULONG AllocationSize
_In_ D3DDDI_VIDEO_PRESENT_TARGET_ID _In_ ULONG _In_ ULONG Flags
#define NT_SUCCESS(StatCode)
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
static const WCHAR Cleanup[]
NTSTATUS AddRun(PNTFS_VCB Vcb, PNTFS_ATTR_CONTEXT AttrContext, ULONG AttrOffset, PFILE_RECORD_HEADER FileRecord, ULONGLONG NextAssignedCluster, ULONG RunLength)
PSTANDARD_INFORMATION GetStandardInformationFromRecord(PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord)
NTSTATUS ConvertLargeMCBToDataRuns(PLARGE_MCB DataRunsMCB, ULONGLONG VcnCount, PUCHAR RunBuffer, ULONG MaxBufferSize, PULONG UsedBufferSize)
PUCHAR DecodeRun(PUCHAR DataRun, LONGLONG *DataRunOffset, ULONGLONG *DataRunLength)
NTSTATUS ConvertDataRunsToLargeMCB(PUCHAR DataRun, PLARGE_MCB DataRunsMCB, PULONGLONG pNextVBN)
NTSTATUS FindFirstAttribute(PFIND_ATTR_CONTXT Context, PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord, BOOLEAN OnlyResident, PNTFS_ATTR_RECORD *Attribute)
NTSTATUS FindFirstAttributeListItem(PFIND_ATTR_CONTXT Context, PNTFS_ATTRIBUTE_LIST_ITEM *Item)
NTSTATUS FreeClusters(PNTFS_VCB Vcb, PNTFS_ATTR_CONTEXT AttrContext, ULONG AttrOffset, PFILE_RECORD_HEADER FileRecord, ULONG ClustersToFree)
VOID FindCloseAttribute(PFIND_ATTR_CONTXT Context)
VOID NtfsDumpFileAttributes(PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord)
NTSTATUS FindNextAttribute(PFIND_ATTR_CONTXT Context, PNTFS_ATTR_RECORD *Attribute)
NTSTATUS FindNextAttributeListItem(PFIND_ATTR_CONTXT Context, PNTFS_ATTRIBUTE_LIST_ITEM *Item)
PFILENAME_ATTRIBUTE GetBestFileNameFromRecord(PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord)
PFILE_RECORD_HEADER NtfsCreateEmptyFileRecord(PDEVICE_EXTENSION DeviceExt)
PNTFS_GLOBAL_DATA NtfsGlobalData
struct FIXUP_ARRAY * PFIXUP_ARRAY
struct INDEX_BUFFER * PINDEX_BUFFER
struct FILENAME_ATTRIBUTE * PFILENAME_ATTRIBUTE
struct INDEX_ENTRY_ATTRIBUTE * PINDEX_ENTRY_ATTRIBUTE
#define NTFS_FILENAME_UPDATE_SIZES
#define NTFS_FILENAME_UPDATE_ATTRS
#define NTFS_FILE_FIRST_USER_FILE
#define NTFS_FILE_TYPE_DIRECTORY
#define NTFS_FILENAME_UPDATE_TIMES
struct INDEX_ROOT_ATTRIBUTE * PINDEX_ROOT_ATTRIBUTE
@ AttributeIndexAllocation
#define ATTR_RECORD_ALIGNMENT
#define NTFS_ATTR_COMPRESSION_MASK
NTSTATUS NtfsAllocateClusters(PDEVICE_EXTENSION DeviceExt, ULONG FirstDesiredCluster, ULONG DesiredClusters, PULONG FirstAssignedCluster, PULONG AssignedClusters)
#define ExAllocatePoolWithTag(hernya, size, tag)
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
#define RtlCompareMemory(s1, s2, l)
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING dst, PUNICODE_STRING src, BOOLEAN Alloc)
#define ExAcquireResourceExclusiveLite(res, wait)
#define ROUND_UP(n, align)
struct _FileName FileName
_Must_inspect_result_ _In_ USHORT NewSize
VOID NTAPI CcSetFileSizes(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes)
GLuint GLuint GLsizei count
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
static ULONG BitmapBuffer[(XMS_BLOCKS+31)/32]
#define EXCEPTION_EXECUTE_HANDLER
#define KeLeaveCriticalRegion()
#define KeEnterCriticalRegion()
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
VOID NTAPI FsRtlUninitializeLargeMcb(IN PLARGE_MCB Mcb)
VOID NTAPI FsRtlInitializeLargeMcb(IN PLARGE_MCB Mcb, IN POOL_TYPE PoolType)
BOOLEAN NTAPI FsRtlLookupLastLargeMcbEntry(IN PLARGE_MCB Mcb, OUT PLONGLONG Vbn, OUT PLONGLONG Lbn)
NTSTATUS BrowseSubNodeIndexEntries(PNTFS_VCB Vcb, PFILE_RECORD_HEADER MftRecord, ULONG IndexBlockSize, PUNICODE_STRING FileName, PNTFS_ATTR_CONTEXT IndexAllocationContext, PRTL_BITMAP Bitmap, ULONGLONG VCN, PULONG StartEntry, PULONG CurrentEntry, BOOLEAN DirSearch, BOOLEAN CaseSensitive, ULONGLONG *OutMFTIndex)
void NtfsDumpData(ULONG_PTR Buffer, ULONG Length)
static NTSTATUS NtfsReadUpCaseTable(PDEVICE_EXTENSION Vcb)
NTSTATUS ReadFileRecord(PDEVICE_EXTENSION Vcb, ULONGLONG index, PFILE_RECORD_HEADER file)
static NTSTATUS NtfsIndexEntriesAreEmpty(_In_ PDEVICE_EXTENSION Vcb, _In_ PNTFS_ATTR_CONTEXT IndexAllocationContext, _In_ ULONG IndexBlockSize, _In_ PINDEX_HEADER_ATTRIBUTE Header, _In_ ULONG Depth, _Out_ PBOOLEAN Empty)
static NTSTATUS UpdateFileNameRecordWorker(PDEVICE_EXTENSION Vcb, ULONGLONG ParentMFTIndex, PUNICODE_STRING FileName, BOOLEAN DirSearch, PNTFS_FILENAME_UPDATE Update, BOOLEAN CaseSensitive)
NTSTATUS NtfsLookupFileAt(PDEVICE_EXTENSION Vcb, PUNICODE_STRING PathName, BOOLEAN CaseSensitive, PFILE_RECORD_HEADER *FileRecord, PULONGLONG MFTIndex, ULONGLONG CurrentMFTIndex)
NTSTATUS UpdateFileRecord(PDEVICE_EXTENSION Vcb, ULONGLONG MftIndex, PFILE_RECORD_HEADER FileRecord)
NTSTATUS NtfsUpdateDuplicatedInformation(PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord, ULONGLONG MFTIndex, ULONG Flags, BOOLEAN CaseSensitive)
NTSTATUS NtfsLookupFile(PDEVICE_EXTENSION Vcb, PUNICODE_STRING PathName, BOOLEAN CaseSensitive, PFILE_RECORD_HEADER *FileRecord, PULONGLONG MFTIndex)
static ULONG GetMaxIndexRootSize(PDEVICE_EXTENSION DeviceExt, PFILE_RECORD_HEADER FileRecord, ULONG IndexRootOffset, PNTFS_ATTR_RECORD IndexRootRecord)
VOID ReleaseAttributeContext(PNTFS_ATTR_CONTEXT Context)
NTSTATUS NtfsIsDirectoryEmpty(_In_ PDEVICE_EXTENSION Vcb, _In_ ULONGLONG MftIndex, _Out_ PBOOLEAN Empty)
NTSTATUS NtfsRemoveFilenameFromDirectory(PDEVICE_EXTENSION DeviceExt, ULONGLONG DirectoryMftIndex, PFILENAME_ATTRIBUTE FilenameAttribute, BOOLEAN CaseSensitive)
NTSTATUS NtfsExtendAllocation(_In_ PDEVICE_EXTENSION Vcb, _In_ PNTFS_ATTR_CONTEXT AttrContext, _In_ ULONG AttrOffset, _In_ PFILE_RECORD_HEADER FileRecord, _In_ ULONGLONG AllocationSize)
NTSTATUS NtfsDeleteFileRecord(PDEVICE_EXTENSION DeviceExt, ULONGLONG MftIndex, BOOLEAN CaseSensitive)
NTSTATUS UpdateMftMirror(PNTFS_VCB Vcb)
PNTFS_ATTR_CONTEXT PrepareAttributeContext(PNTFS_ATTR_RECORD AttrRecord)
ULONGLONG AttributeDataLength(PNTFS_ATTR_RECORD AttrRecord)
NTSTATUS UpdateIndexEntryFileName(PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER MftRecord, PCHAR IndexRecord, ULONG IndexBlockSize, PINDEX_ENTRY_ATTRIBUTE FirstEntry, PINDEX_ENTRY_ATTRIBUTE LastEntry, PUNICODE_STRING FileName, PULONG StartEntry, PULONG CurrentEntry, BOOLEAN DirSearch, PNTFS_FILENAME_UPDATE Update, BOOLEAN CaseSensitive)
NTSTATUS FindAttribute(PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER MftRecord, ULONG Type, PCWSTR Name, ULONG NameLength, PNTFS_ATTR_CONTEXT *AttrCtx, PULONG Offset)
ULONG ReadAttribute(PDEVICE_EXTENSION Vcb, PNTFS_ATTR_CONTEXT Context, ULONGLONG Offset, PCHAR Buffer, ULONG Length)
NTSTATUS WriteAttribute(PDEVICE_EXTENSION Vcb, PNTFS_ATTR_CONTEXT Context, ULONGLONG Offset, const PUCHAR Buffer, ULONG Length, PULONG RealLengthWritten, PFILE_RECORD_HEADER FileRecord)
NTSTATUS BrowseIndexEntries(PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER MftRecord, PINDEX_ROOT_ATTRIBUTE IndexRecord, ULONG IndexBlockSize, PINDEX_ENTRY_ATTRIBUTE FirstEntry, PINDEX_ENTRY_ATTRIBUTE LastEntry, PUNICODE_STRING FileName, PULONG StartEntry, PULONG CurrentEntry, BOOLEAN DirSearch, BOOLEAN CaseSensitive, ULONGLONG *OutMFTIndex)
VOID SetFileRecordEnd(PFILE_RECORD_HEADER FileRecord, PNTFS_ATTR_RECORD AttrEnd, ULONG EndMarker)
NTSTATUS IncreaseMftSize(PDEVICE_EXTENSION Vcb, BOOLEAN CanWait)
NTSTATUS WriteAttributeFromIrp(PDEVICE_EXTENSION Vcb, PNTFS_ATTR_CONTEXT Context, ULONGLONG Offset, const PUCHAR Buffer, ULONG Length, PULONG RealLengthWritten, PFILE_RECORD_HEADER FileRecord, PIRP Irp)
NTSTATUS AddFixupArray(PDEVICE_EXTENSION Vcb, PNTFS_RECORD_HEADER Record)
NTSTATUS SetNonResidentAttributeDataLength(PDEVICE_EXTENSION Vcb, PNTFS_ATTR_CONTEXT AttrContext, ULONG AttrOffset, PFILE_RECORD_HEADER FileRecord, PLARGE_INTEGER DataSize)
PNTFS_ATTR_RECORD MoveAttributes(PDEVICE_EXTENSION DeviceExt, PNTFS_ATTR_RECORD FirstAttributeToMove, ULONG FirstAttributeOffset, ULONG_PTR MoveTo)
#define NTFS_MAX_INDEX_DEPTH
NTSTATUS UpdateFileNameRecord(PDEVICE_EXTENSION Vcb, ULONGLONG ParentMFTIndex, PUNICODE_STRING FileName, BOOLEAN DirSearch, PNTFS_FILENAME_UPDATE Update, BOOLEAN CaseSensitive)
NTSTATUS NtfsAddFilenameToDirectory(PDEVICE_EXTENSION DeviceExt, ULONGLONG DirectoryMftIndex, ULONGLONG FileReferenceNumber, PFILENAME_ATTRIBUTE FilenameAttribute, BOOLEAN CaseSensitive)
NTSTATUS NtfsResizeAllocation(_In_ PNTFS_FCB Fcb, _In_ PFILE_OBJECT FileObject, _In_ BOOLEAN CaseSensitive, _In_ ULONGLONG AllocationSize)
static NTSTATUS AddFilenameToDirectoryWorker(PDEVICE_EXTENSION DeviceExt, ULONGLONG DirectoryMftIndex, ULONGLONG FileReferenceNumber, PFILENAME_ATTRIBUTE FilenameAttribute, BOOLEAN CaseSensitive)
ULONGLONG AttributeAllocatedLength(PNTFS_ATTR_RECORD AttrRecord)
NTSTATUS AddNewMftEntry(PFILE_RECORD_HEADER FileRecord, PDEVICE_EXTENSION DeviceExt, PULONGLONG DestinationIndex, BOOLEAN CanWait)
VOID NtfsDumpFileRecord(PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord)
BOOLEAN CompareFileName(PDEVICE_EXTENSION Vcb, PUNICODE_STRING FileName, PINDEX_ENTRY_ATTRIBUTE IndexEntry, BOOLEAN DirSearch, BOOLEAN CaseSensitive)
ULONG ReadAttributeToIrp(PDEVICE_EXTENSION Vcb, PNTFS_ATTR_CONTEXT Context, ULONGLONG Offset, PCHAR Buffer, ULONG Length, PIRP Irp)
NTSTATUS FreeMftEntry(PDEVICE_EXTENSION DeviceExt, ULONGLONG MftIndex)
NTSTATUS SetResidentAttributeDataLength(PDEVICE_EXTENSION Vcb, PNTFS_ATTR_CONTEXT AttrContext, ULONG AttrOffset, PFILE_RECORD_HEADER FileRecord, PLARGE_INTEGER DataSize)
NTSTATUS NtfsFindMftRecord(PDEVICE_EXTENSION Vcb, ULONGLONG MFTIndex, PUNICODE_STRING FileName, PULONG FirstEntry, BOOLEAN DirSearch, BOOLEAN CaseSensitive, ULONGLONG *OutMFTIndex)
NTSTATUS NtfsTrimAllocation(_In_ PNTFS_FCB Fcb)
NTSTATUS ReadLCN(PDEVICE_EXTENSION Vcb, ULONGLONG lcn, ULONG count, PVOID buffer)
NTSTATUS NtfsLoadUpCaseTable(PDEVICE_EXTENSION Vcb)
NTSTATUS FixupUpdateSequenceArray(PDEVICE_EXTENSION Vcb, PNTFS_RECORD_HEADER Record)
NTSTATUS InternalSetResidentAttributeLength(PDEVICE_EXTENSION DeviceExt, PNTFS_ATTR_CONTEXT AttrContext, PFILE_RECORD_HEADER FileRecord, ULONG AttrOffset, ULONG DataSize)
NTSTATUS NtfsFindFileAt(PDEVICE_EXTENSION Vcb, PUNICODE_STRING SearchPattern, PULONG FirstEntry, PFILE_RECORD_HEADER *FileRecord, PULONGLONG MFTIndex, ULONGLONG CurrentMFTIndex, BOOLEAN CaseSensitive)
static NTSTATUS RemoveFilenameFromDirectoryWorker(PDEVICE_EXTENSION DeviceExt, ULONGLONG DirectoryMftIndex, PFILENAME_ATTRIBUTE FilenameAttribute, BOOLEAN CaseSensitive)
static NTSTATUS NtfsMapAttributeRuns(PDEVICE_EXTENSION Vcb, PNTFS_ATTR_CONTEXT Context, ULONGLONG Offset, ULONG Length, PNTFS_IO_RUN_LIST RunList, PULONG MappedLength)
static NTSTATUS NtfsIndexNodeIsEmpty(_In_ PDEVICE_EXTENSION Vcb, _In_ PNTFS_ATTR_CONTEXT IndexAllocationContext, _In_ ULONG IndexBlockSize, _In_ ULONGLONG Vcn, _In_ ULONG Depth, _Out_ PBOOLEAN Empty)
NTSTATUS SetAttributeDataLength(PFILE_OBJECT FileObject, PNTFS_FCB Fcb, PNTFS_ATTR_CONTEXT AttrContext, ULONG AttrOffset, PFILE_RECORD_HEADER FileRecord, PLARGE_INTEGER DataSize)
#define ExFreePoolWithTag(_P, _T)
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
_In_ ULONG _In_ ULONG Offset
_In_ ULONG _In_ ULONG _In_ ULONG Length
VOID NtfsFreeIoRunList(IN OUT PNTFS_IO_RUN_LIST RunList)
NTSTATUS NtfsAddIoRun(IN OUT PNTFS_IO_RUN_LIST RunList, IN LONGLONG Lbo, IN ULONG ByteCount)
NTSTATUS NtfsReadSectors(IN PDEVICE_OBJECT DeviceObject, IN ULONG DiskSector, IN ULONG SectorCount, IN ULONG SectorSize, IN OUT PUCHAR Buffer, IN BOOLEAN Override)
VOID NtfsInitIoRunList(OUT PNTFS_IO_RUN_LIST RunList)
NTSTATUS NtfsPerformIrpIoRuns(IN PDEVICE_OBJECT DeviceObject, IN UCHAR MajorFunction, IN ULONG SectorSize, IN PIRP Irp, IN OUT PUCHAR Buffer, IN PNTFS_IO_RUN_LIST RunList, IN BOOLEAN Override, OUT PULONG BytesTransferred)
ULONGLONG NtfsGetFileSize(PDEVICE_EXTENSION DeviceExt, PFILE_RECORD_HEADER FileRecord, PCWSTR Stream, ULONG StreamLength, PULONGLONG AllocatedSize)
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
VOID NTAPI FsRtlDissectName(IN UNICODE_STRING Name, OUT PUNICODE_STRING FirstPart, OUT PUNICODE_STRING RemainingPart)
#define STATUS_USER_MAPPED_FILE
#define STATUS_UNEXPECTED_IO_ERROR
#define STATUS_PARTIAL_COPY
#define STATUS_DATA_ERROR
#define _SEH2_GetExceptionCode()
#define _SEH2_EXCEPT(...)
#define _SEH2_YIELD(__stmt)
BOOLEAN NTAPI MmCanFileBeTruncated(_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, _In_opt_ PLARGE_INTEGER NewFileSize)
#define STATUS_END_OF_FILE
PB_TREE_FILENAME_NODE RootNode
ULONGLONG DirectoryFileReferenceNumber
INDEX_HEADER_ATTRIBUTE Header
union INDEX_ENTRY_ATTRIBUTE::@970 Data
struct INDEX_ENTRY_ATTRIBUTE::@970::@971 Directory
FILENAME_ATTRIBUTE FileName
INDEX_HEADER_ATTRIBUTE Header
struct NTFS_ATTR_RECORD::@170::@172 Resident
struct NTFS_ATTR_RECORD::@170::@173 NonResident
BOOLEAN EnableWriteSupport
NPAGED_LOOKASIDE_LIST AttrCtxtLookasideList
FSRTL_COMMON_FCB_HEADER RFCB
ERESOURCE PagingIoResource
#define FIELD_OFFSET(t, f)
#define RtlCopyMemory(Destination, Source, Length)
#define RtlZeroMemory(Destination, Length)
#define RtlMoveMemory(Destination, Source, Length)
#define STATUS_OBJECT_PATH_NOT_FOUND
#define STATUS_INVALID_PARAMETER
#define STATUS_UNRECOGNIZED_VOLUME
#define STATUS_UNSUCCESSFUL
#define STATUS_FILE_CORRUPT_ERROR
#define STATUS_INSUFFICIENT_RESOURCES
#define STATUS_OBJECT_NAME_NOT_FOUND
struct _LARGE_INTEGER::@2753 u
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesWritten
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesRead
_In_ struct _KBUGCHECK_REASON_CALLBACK_RECORD * Record