2 * PROJECT: ReactOS NTFS tests/dump
3 * LICENSE: LGPLv2+ - See COPYING.LIB in the top level directory
4 * PURPOSE: Query information from NTFS volume using FSCTL and dumps $MFT
5 * PROGRAMMER: Pierre Schweitzer <pierre@reactos.org>
17 } NTFS_RECORD_HEADER
, *PNTFS_RECORD_HEADER
;
19 #define NRH_FILE_TYPE 0x454C4946
21 typedef struct _FILE_RECORD_HEADER
23 NTFS_RECORD_HEADER Ntfs
;
24 USHORT SequenceNumber
;
26 USHORT AttributeOffset
;
30 ULONGLONG BaseFileRecord
;
31 USHORT NextAttributeNumber
;
32 } FILE_RECORD_HEADER
, *PFILE_RECORD_HEADER
;
36 AttributeStandardInformation
= 0x10,
37 AttributeAttributeList
= 0x20,
38 AttributeFileName
= 0x30,
39 AttributeObjectId
= 0x40,
40 AttributeSecurityDescriptor
= 0x50,
41 AttributeVolumeName
= 0x60,
42 AttributeVolumeInformation
= 0x70,
44 AttributeIndexRoot
= 0x90,
45 AttributeIndexAllocation
= 0xA0,
46 AttributeBitmap
= 0xB0,
47 AttributeReparsePoint
= 0xC0,
48 AttributeEAInformation
= 0xD0,
50 AttributePropertySet
= 0xF0,
51 AttributeLoggedUtilityStream
= 0x100,
52 AttributeEnd
= 0xFFFFFFFF
53 } ATTRIBUTE_TYPE
, *PATTRIBUTE_TYPE
;
77 USHORT MappingPairsOffset
;
78 USHORT CompressionUnit
;
80 LONGLONG AllocatedSize
;
82 LONGLONG InitializedSize
;
83 LONGLONG CompressedSize
;
86 } NTFS_ATTR_RECORD
, *PNTFS_ATTR_RECORD
;
90 ULONGLONG CreationTime
;
92 ULONGLONG LastWriteTime
;
93 ULONGLONG LastAccessTime
;
95 ULONG AlignmentOrReserved
[3];
96 } STANDARD_INFORMATION
, *PSTANDARD_INFORMATION
;
100 ULONGLONG DirectoryFileReferenceNumber
;
101 ULONGLONG CreationTime
;
102 ULONGLONG ChangeTime
;
103 ULONGLONG LastWriteTime
;
104 ULONGLONG LastAccessTime
;
105 ULONGLONG AllocatedSize
;
107 ULONG FileAttributes
;
108 ULONG AlignmentOrReserved
;
112 } FILENAME_ATTRIBUTE
, *PFILENAME_ATTRIBUTE
;
114 int main(int argc
, char **argv
)
116 static WCHAR VolumeName
[] = L
"\\\\.\\E:";
119 NTFS_VOLUME_DATA_BUFFER Data
;
120 NTFS_EXTENDED_VOLUME_DATA Extended
;
122 DWORD LengthReturned
;
123 NTFS_FILE_RECORD_INPUT_BUFFER InputBuffer
;
124 PNTFS_FILE_RECORD_OUTPUT_BUFFER OutputBuffer
;
126 PFILE_RECORD_HEADER FileRecord
;
127 PNTFS_ATTR_RECORD Attribute
;
130 VolumeHandle
= CreateFileW(VolumeName
, GENERIC_READ
, FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, OPEN_EXISTING
, 0, 0 );
131 if (VolumeHandle
== INVALID_HANDLE_VALUE
)
133 fprintf(stderr
, "Failed opening volume!\n");
137 if (!DeviceIoControl(VolumeHandle
, FSCTL_GET_NTFS_VOLUME_DATA
, NULL
, 0, &VolumeInfo
, sizeof(VolumeInfo
), &LengthReturned
, NULL
))
139 fprintf(stderr
, "Failed requesting volume data!\n");
140 CloseHandle(VolumeHandle
);
144 printf("Using NTFS: %u.%u\n", VolumeInfo
.Extended
.MajorVersion
, VolumeInfo
.Extended
.MinorVersion
);
146 InputBuffer
.FileReferenceNumber
.QuadPart
= 0LL;
147 OutputLength
= sizeof(NTFS_FILE_RECORD_OUTPUT_BUFFER
) + VolumeInfo
.Data
.BytesPerFileRecordSegment
;
148 OutputBuffer
= malloc(OutputLength
);
149 if (OutputBuffer
== NULL
)
151 fprintf(stderr
, "Allocation failure!\n");
152 CloseHandle(VolumeHandle
);
155 if (!DeviceIoControl(VolumeHandle
, FSCTL_GET_NTFS_FILE_RECORD
, &InputBuffer
, sizeof(InputBuffer
), OutputBuffer
, OutputLength
, &LengthReturned
, NULL
))
157 fprintf(stderr
, "Failed opening $MFT!\n");
159 CloseHandle(VolumeHandle
);
163 if (OutputBuffer
->FileReferenceNumber
.QuadPart
!= 0LL)
165 fprintf(stderr
, "Wrong entry read! %I64x\n", OutputBuffer
->FileReferenceNumber
.QuadPart
);
167 CloseHandle(VolumeHandle
);
171 FileRecord
= (PFILE_RECORD_HEADER
)OutputBuffer
->FileRecordBuffer
;
172 if (FileRecord
->Ntfs
.Type
!= NRH_FILE_TYPE
)
174 fprintf(stderr
, "Wrong type read! %lx\n", FileRecord
->Ntfs
.Type
);
176 CloseHandle(VolumeHandle
);
180 printf("File record size: %lu. Read file record size: %lu\n", VolumeInfo
.Data
.BytesPerFileRecordSegment
, OutputBuffer
->FileRecordLength
);
181 printf("SequenceNumber: %u\n", FileRecord
->SequenceNumber
);
182 printf("LinkCount: %u\n", FileRecord
->LinkCount
);
183 printf("AttributeOffset: %u\n", FileRecord
->AttributeOffset
);
184 printf("Flags: %u\n", FileRecord
->Flags
);
185 printf("BytesInUse: %lu\n", FileRecord
->BytesInUse
);
186 printf("BytesAllocated: %lu\n", FileRecord
->BytesAllocated
);
187 printf("BaseFileRecord: %I64x\n", FileRecord
->BaseFileRecord
);
188 printf("NextAttributeNumber: %u\n", FileRecord
->NextAttributeNumber
);
190 Attribute
= (PNTFS_ATTR_RECORD
)((ULONG_PTR
)FileRecord
+ FileRecord
->AttributeOffset
);
191 while (Attribute
< (PNTFS_ATTR_RECORD
)((ULONG_PTR
)FileRecord
+ FileRecord
->BytesInUse
) &&
192 Attribute
->Type
!= AttributeEnd
)
194 PSTANDARD_INFORMATION StdInfo
;
195 PFILENAME_ATTRIBUTE FileName
;
197 if (!Attribute
->IsNonResident
)
199 switch (Attribute
->Type
)
201 case AttributeStandardInformation
:
202 StdInfo
= (PSTANDARD_INFORMATION
)((ULONG_PTR
)Attribute
+ Attribute
->Resident
.ValueOffset
);
203 printf("\t$STANDARD_INFORMATION:\n");
204 printf("\tCreationTime: %I64u\n", StdInfo
->CreationTime
);
205 printf("\tChangeTime: %I64u\n", StdInfo
->ChangeTime
);
206 printf("\tLastWriteTime: %I64u\n", StdInfo
->LastWriteTime
);
207 printf("\tLastAccessTime: %I64u\n", StdInfo
->LastAccessTime
);
208 printf("\tFileAttribute: %lu\n", StdInfo
->FileAttribute
);
211 case AttributeFileName
:
212 FileName
= (PFILENAME_ATTRIBUTE
)((ULONG_PTR
)Attribute
+ Attribute
->Resident
.ValueOffset
);
213 printf("\t$FILE_NAME:\n");
214 printf("\tDirectoryFileReferenceNumber: %I64u\n", FileName
->DirectoryFileReferenceNumber
);
215 printf("\tCreationTime: %I64u\n", FileName
->CreationTime
);
216 printf("\tChangeTime: %I64u\n", FileName
->ChangeTime
);
217 printf("\tLastWriteTime: %I64u\n", FileName
->LastWriteTime
);
218 printf("\tLastAccessTime: %I64u\n", FileName
->LastAccessTime
);
219 printf("\tAllocatedSize: %I64u\n", FileName
->AllocatedSize
);
220 printf("\tDataSize: %I64u\n", FileName
->DataSize
);
221 printf("\tFileAttributes: %lu\n", FileName
->FileAttributes
);
222 printf("\tAlignmentOrReserved: %lu\n", FileName
->AlignmentOrReserved
);
223 printf("\tNameLength: %u\n", FileName
->NameLength
);
224 printf("\tNameType: %u\n", FileName
->NameType
);
226 for (k
= 0; k
< FileName
->NameLength
; ++k
)
228 wprintf(L
"%C", FileName
->Name
[k
]);
235 Attribute
= (PNTFS_ATTR_RECORD
)((ULONG_PTR
)Attribute
+ Attribute
->Length
);
239 CloseHandle(VolumeHandle
);