}
+VOID NtfsDumpDataRunData(PUCHAR DataRun)
+{
+ UCHAR DataRunOffsetSize;
+ UCHAR DataRunLengthSize;
+ CHAR i;
+
+ DbgPrint("%02x ", *DataRun);
+
+ if (*DataRun == 0)
+ return;
+
+ DataRunOffsetSize = (*DataRun >> 4) & 0xF;
+ DataRunLengthSize = *DataRun & 0xF;
+
+ DataRun++;
+ for (i = 0; i < DataRunLengthSize; i++)
+ {
+ DbgPrint("%02x ", *DataRun);
+ DataRun++;
+ }
+
+ for (i = 0; i < DataRunOffsetSize; i++)
+ {
+ DbgPrint("%02x ", *DataRun);
+ DataRun++;
+ }
+
+ NtfsDumpDataRunData(DataRun);
+}
+
+
+VOID
+NtfsDumpDataRuns(PVOID StartOfRun,
+ ULONGLONG CurrentLCN)
+{
+ PUCHAR DataRun = StartOfRun;
+ LONGLONG DataRunOffset;
+ ULONGLONG DataRunLength;
+
+ if (CurrentLCN == 0)
+ {
+ DPRINT1("Dumping data runs.\n\tData:\n\t\t");
+ NtfsDumpDataRunData(StartOfRun);
+ DbgPrint("\n\tRuns:\n\t\tOff\t\tLCN\t\tLength\n");
+ }
+
+ DataRun = DecodeRun(DataRun, &DataRunOffset, &DataRunLength);
+
+ if (DataRunOffset != -1)
+ CurrentLCN += DataRunOffset;
+
+ DbgPrint("\t\t%I64d\t", DataRunOffset);
+ if (DataRunOffset < 99999)
+ DbgPrint("\t");
+ DbgPrint("%I64u\t", CurrentLCN);
+ if (CurrentLCN < 99999)
+ DbgPrint("\t");
+ DbgPrint("%I64u\n", DataRunLength);
+
+ if (*DataRun == 0)
+ DbgPrint("\t\t00\n");
+ else
+ NtfsDumpDataRuns(DataRun, CurrentLCN);
+}
+
+
VOID
NtfsDumpFileAttributes(PDEVICE_EXTENSION Vcb,
PFILE_RECORD_HEADER FileRecord)
return NULL;
}
+/**
+* GetPackedByteCount
+* Returns the minimum number of bytes needed to represent the value of a
+* 64-bit number. Used to encode data runs.
+*/
+UCHAR
+GetPackedByteCount(LONGLONG NumberToPack,
+ BOOLEAN IsSigned)
+{
+ int bytes = 0;
+ if (!IsSigned)
+ {
+ if (NumberToPack >= 0x0100000000000000)
+ return 8;
+ if (NumberToPack >= 0x0001000000000000)
+ return 7;
+ if (NumberToPack >= 0x0000010000000000)
+ return 6;
+ if (NumberToPack >= 0x0000000100000000)
+ return 5;
+ if (NumberToPack >= 0x0000000001000000)
+ return 4;
+ if (NumberToPack >= 0x0000000000010000)
+ return 3;
+ if (NumberToPack >= 0x0000000000000100)
+ return 2;
+ return 1;
+ }
+
+ if (NumberToPack > 0)
+ {
+ // we have to make sure the number that gets encoded won't be interpreted as negative
+ if (NumberToPack >= 0x0080000000000000)
+ return 8;
+ if (NumberToPack >= 0x0000800000000000)
+ return 7;
+ if (NumberToPack >= 0x0000008000000000)
+ return 6;
+ if (NumberToPack >= 0x0000000080000000)
+ return 5;
+ if (NumberToPack >= 0x0000000000800000)
+ return 4;
+ if (NumberToPack >= 0x0000000000008000)
+ return 3;
+ if (NumberToPack >= 0x0000000000000080)
+ return 2;
+ return 1;
+ }
+ else
+ {
+ // negative number
+ if (NumberToPack <= 0xff80000000000000)
+ return 8;
+ if (NumberToPack <= 0xffff800000000000)
+ return 7;
+ if (NumberToPack <= 0xffffff8000000000)
+ return 6;
+ if (NumberToPack <= 0xffffffff80000000)
+ return 5;
+ if (NumberToPack <= 0xffffffffff800000)
+ return 4;
+ if (NumberToPack <= 0xffffffffffff8000)
+ return 3;
+ if (NumberToPack <= 0xffffffffffffff80)
+ return 2;
+ return 1;
+ }
+ return bytes;
+}
+
NTSTATUS
GetLastClusterInDataRun(PDEVICE_EXTENSION Vcb, PNTFS_ATTR_RECORD Attribute, PULONGLONG LastCluster)
{