ReactOS  0.4.14-dev-833-g5f692ed
ntfsinfo.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS NTFS Information tool
4  * FILE: cmdutils/ntfsinfo/ntfsinfo.c
5  * PURPOSE: Query information from NTFS volume using FSCTL
6  * PROGRAMMERS: Pierre Schweitzer <pierre@reactos.org>
7  */
8 
9 #include <windows.h>
10 #include <tchar.h>
11 #include <stdio.h>
12 
13 typedef struct
14 {
15  ULONG Type;
16  USHORT UsaOffset;
17  USHORT UsaCount;
18  ULONGLONG Lsn;
20 
21 #define NRH_FILE_TYPE 0x454C4946
22 #define ATTRIBUTE_TYPE_DATA 0x80
23 #define ATTRIBUTE_TYPE_END 0xFFFFFFFF
24 
25 typedef struct _FILE_RECORD_HEADER
26 {
31  USHORT Flags;
37 
38 typedef struct
39 {
40  ULONG Type;
41  ULONG Length;
42  UCHAR IsNonResident;
43  UCHAR NameLength;
44  USHORT NameOffset;
45  USHORT Flags;
47  union
48  {
49  struct
50  {
52  USHORT ValueOffset;
53  UCHAR Flags;
55  } Resident;
56  struct
57  {
58  ULONGLONG LowestVCN;
59  ULONGLONG HighestVCN;
60  USHORT MappingPairsOffset;
61  USHORT CompressionUnit;
62  UCHAR Reserved[4];
63  LONGLONG AllocatedSize;
65  LONGLONG InitializedSize;
66  LONGLONG CompressedSize;
67  } NonResident;
68  };
70 
71 static TCHAR * MetaDataFiles[] = {
72  _T("$MFT\t\t"),
73  _T("$MFTMirr\t"),
74  _T("$LogFile\t"),
75  _T("$Volume\t\t"),
76  _T("$AttrDef\t"),
77  _T("."),
78  _T("$Bitmap\t\t"),
79  _T("$Boot\t\t"),
80  _T("$BadClus\t"),
81  _T("$Quota\t\t"),
82  _T("$UpCase\t\t"),
83  _T("$Extended\t"),
84  NULL,
85 };
86 
87 int
88 __cdecl
89 _tmain(int argc, const TCHAR *argv[])
90 {
91  TCHAR VolumeName[] = _T("\\\\.\\C:");
95  ULONGLONG VolumeSize;
96  ULONGLONG MftClusters;
97  UINT File = 0;
99 
100  if (argc > 1)
101  {
102  TCHAR Letter = argv[1][0];
103 
104  if ((Letter >= 'A' && Letter <= 'Z') ||
105  (Letter >= 'a' && Letter <= 'z'))
106  {
107  VolumeName[4] = Letter;
108  }
109  }
110 
113  {
114  _ftprintf(stderr, _T("Failed opening the volume '%s' (%lx)\n"), VolumeName, GetLastError());
115  return 1;
116  }
117 
119  {
120  _ftprintf(stderr, _T("Failed requesting volume '%s' data (%lx)\n"), VolumeName, GetLastError());
122  return 1;
123  }
124 
125  if (LengthReturned < sizeof(VolumeInfo))
126  {
127  _ftprintf(stderr, _T("Failed reading volume '%s' data (%lx)\n"), VolumeName, GetLastError());
129  return 1;
130  }
131 
132  _tprintf(_T("Volume Size\n-----------\n"));
133  VolumeSize = VolumeInfo.TotalClusters.QuadPart * VolumeInfo.BytesPerCluster;
134  _tprintf(_T("Volume size\t\t: %I64u MB\n"), VolumeSize >> 20);
135  _tprintf(_T("Total sectors\t\t: %I64u\n"), VolumeInfo.NumberSectors.QuadPart);
136  _tprintf(_T("Total clusters\t\t: %I64u\n"), VolumeInfo.TotalClusters.QuadPart);
137  _tprintf(_T("Free clusters\t\t: %I64u\n"), VolumeInfo.FreeClusters.QuadPart);
138  _tprintf(_T("Free space\t\t: %I64u MB (%I64u%% of drive)\n"), (VolumeInfo.FreeClusters.QuadPart * VolumeInfo.BytesPerCluster) >> 20, (VolumeInfo.FreeClusters.QuadPart * 100) / VolumeInfo.TotalClusters.QuadPart);
139 
140  _tprintf(_T("\nAllocation Size\n---------------\n"));
141  _tprintf(_T("Bytes per sector\t: %lu\n"), VolumeInfo.BytesPerSector);
142  _tprintf(_T("Bytes per cluster\t: %lu\n"), VolumeInfo.BytesPerCluster);
143  _tprintf(_T("Bytes per MFT record:\t: %lu\n"), VolumeInfo.BytesPerFileRecordSegment);
144  _tprintf(_T("Clusters per MFT record\t: %lu\n"), VolumeInfo.ClustersPerFileRecordSegment);
145 
146  _tprintf(_T("\nMFT Information\n---------------\n"));
147  _tprintf(_T("MFT size\t\t: %I64u MB (%I64u%% of drive)\n"), VolumeInfo.MftValidDataLength.QuadPart >> 20, (VolumeInfo.MftValidDataLength.QuadPart * 100) / VolumeSize);
148  _tprintf(_T("MFT start cluster\t: %I64u\n"), VolumeInfo.MftStartLcn.QuadPart);
149  _tprintf(_T("MFT zone clusters\t: %I64u - %I64u\n"), VolumeInfo.MftZoneStart.QuadPart, VolumeInfo.MftZoneEnd.QuadPart);
150  MftClusters = VolumeInfo.MftZoneEnd.QuadPart - VolumeInfo.MftZoneStart.QuadPart;
151  _tprintf(_T("MFT zone size\t\t: %I64u MB (%I64u%% of drive)\n"), (MftClusters * VolumeInfo.BytesPerCluster) >> 20, (MftClusters * 100) / VolumeInfo.TotalClusters.QuadPart);
152  _tprintf(_T("MFT mirror start\t: %I64u\n"), VolumeInfo.Mft2StartLcn.QuadPart);
153 
154  _tprintf(_T("\nMeta-Data files\n---------------\n"));
155  OutputBuffer = HeapAlloc(GetProcessHeap(), 0, VolumeInfo.BytesPerFileRecordSegment + sizeof(NTFS_FILE_RECORD_OUTPUT_BUFFER));
156  while (MetaDataFiles[File] != NULL)
157  {
159  PFILE_RECORD_HEADER FileRecord;
160  PNTFS_ATTR_RECORD Attribute;
161  ULONGLONG Size = 0;
162 
163  if (File == 5)
164  {
165  ++File;
166  continue;
167  }
168 
169  InputBuffer.FileReferenceNumber.QuadPart = File;
171  OutputBuffer, VolumeInfo.BytesPerFileRecordSegment + sizeof(NTFS_FILE_RECORD_OUTPUT_BUFFER),
172  &LengthReturned, NULL))
173  {
174  ++File;
175  continue;
176  }
177 
178  if (OutputBuffer->FileReferenceNumber.QuadPart != File)
179  {
180  ++File;
181  continue;
182  }
183 
184  FileRecord = (PFILE_RECORD_HEADER)OutputBuffer->FileRecordBuffer;
185  if (FileRecord->Ntfs.Type != NRH_FILE_TYPE)
186  {
187  ++File;
188  continue;
189  }
190 
191  Attribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + FileRecord->AttributeOffset);
192  while (Attribute < (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + FileRecord->BytesInUse) &&
193  Attribute->Type != ATTRIBUTE_TYPE_END)
194  {
195  if (Attribute->Type == ATTRIBUTE_TYPE_DATA)
196  {
197  Size = (Attribute->IsNonResident) ? Attribute->NonResident.AllocatedSize : Attribute->Resident.ValueLength;
198  break;
199  }
200 
201  Attribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)Attribute + Attribute->Length);
202  }
203 
204  _tprintf(_T("%s%I64u bytes\n"), MetaDataFiles[File], Size);
205 
206  ++File;
207  }
208 
211  return 0;
212 }
#define ATTRIBUTE_TYPE_END
Definition: ntfsinfo.c:23
struct _FILE_RECORD_HEADER * PFILE_RECORD_HEADER
static int argc
Definition: ServiceArgs.c:12
#define _tprintf
Definition: tchar.h:506
#define CloseHandle
Definition: compat.h:406
Type
Definition: Type.h:6
#define __cdecl
Definition: accygwin.h:79
#define INVALID_HANDLE_VALUE
Definition: compat.h:399
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
ULONG BytesInUse
Definition: ntfs.h:253
ULONG Type
Definition: ntfs.h:122
int __cdecl _tmain(int argc, const TCHAR *argv[])
Definition: ntfsinfo.c:89
USHORT SequenceNumber
Definition: ntfs.h:249
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define argv
Definition: mplay32.c:18
CHAR InputBuffer[80]
Definition: conmgr.c:33
#define FILE_SHARE_READ
Definition: compat.h:125
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define ATTRIBUTE_TYPE_DATA
Definition: ntfsinfo.c:22
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
static TCHAR * MetaDataFiles[]
Definition: ntfsinfo.c:71
ULONG Length
Definition: ntfs.h:123
USHORT AttributeOffset
Definition: ntfs.h:251
_In_opt_ PVOID _In_ PCSTR File
Definition: iofuncs.h:615
smooth NULL
Definition: ftsmooth.c:416
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ FILE_INFORMATION_CLASS _Out_opt_ PULONG LengthReturned
Definition: fltkernel.h:1306
USHORT NextAttributeNumber
Definition: ntfs.h:256
USHORT LinkCount
Definition: ntfs.h:250
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
#define FSCTL_GET_NTFS_VOLUME_DATA
Definition: ntifs_ex.h:261
_Must_inspect_result_ __drv_aliasesMem _In_ PDEVICE_OBJECT _In_opt_ PVOID _In_ ULONG _Out_opt_ PVOID OutputBuffer
Definition: iofuncs.h:713
#define _ftprintf
Definition: tchar.h:518
#define OPEN_EXISTING
Definition: compat.h:434
int64_t LONGLONG
Definition: typedefs.h:66
char TCHAR
Definition: xmlstorage.h:189
#define _T(x)
Definition: vfdio.h:22
#define GetProcessHeap()
Definition: compat.h:403
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
if(!(yy_init))
Definition: macro.lex.yy.c:714
ULONG BytesAllocated
Definition: ntfs.h:254
struct NTFS_RECORD_HEADER * PNTFS_RECORD_HEADER
uint64_t ULONGLONG
Definition: typedefs.h:65
unsigned long DWORD
Definition: ntddk_ex.h:95
_Must_inspect_result_ _Out_ PHANDLE VolumeHandle
Definition: fltkernel.h:2284
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define FSCTL_GET_NTFS_FILE_RECORD
Definition: ntifs_ex.h:262
unsigned char UCHAR
Definition: xmlstorage.h:181
_In_ GUID _In_ PVOID _In_ ULONG ValueLength
Definition: hubbusif.h:311
WCHAR Letter
UCHAR IsNonResident
Definition: ntfs.h:124
#define GENERIC_READ
Definition: compat.h:124
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
struct _FILE_RECORD_HEADER FILE_RECORD_HEADER
BOOL WINAPI DeviceIoControl(IN HANDLE hDevice, IN DWORD dwIoControlCode, IN LPVOID lpInBuffer OPTIONAL, IN DWORD nInBufferSize OPTIONAL, OUT LPVOID lpOutBuffer OPTIONAL, IN DWORD nOutBufferSize OPTIONAL, OUT LPDWORD lpBytesReturned OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: deviceio.c:136
struct NTFS_ATTR_RECORD * PNTFS_ATTR_RECORD
IN OUT PVCB OUT PDIRENT OUT PBCB IN BOOLEAN CreateFile
Definition: fatprocs.h:904
unsigned short USHORT
Definition: pedump.c:61
struct NTFS_ATTR_RECORD::@165::@168 NonResident
unsigned int UINT
Definition: ndis.h:50
USHORT Flags
Definition: ntfs.h:252
IN PVOID Instance
Definition: pci.h:359
_Must_inspect_result_ _Inout_opt_ PUNICODE_STRING VolumeName
Definition: fltkernel.h:1117
NTFS_RECORD_HEADER Ntfs
Definition: ntfs.h:248
unsigned int ULONG
Definition: retypes.h:1
FILE * stderr
ULONGLONG BaseFileRecord
Definition: ntfs.h:255
#define ULONG_PTR
Definition: config.h:101
Definition: File.h:15
#define NRH_FILE_TYPE
Definition: ntfsinfo.c:21
struct NTFS_ATTR_RECORD::@165::@167 Resident
#define HeapFree(x, y, z)
Definition: compat.h:402
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4751