ReactOS  0.4.15-dev-2704-gd5265b0
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:598
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define __cdecl
Definition: accygwin.h:79
#define INVALID_HANDLE_VALUE
Definition: compat.h:590
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
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
if(dx==0 &&dy==0)
Definition: linetemp.h:174
#define argv
Definition: mplay32.c:18
#define FILE_SHARE_READ
Definition: compat.h:136
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define ATTRIBUTE_TYPE_DATA
Definition: ntfsinfo.c:22
static TCHAR * MetaDataFiles[]
Definition: ntfsinfo.c:71
ULONG Length
Definition: ntfs.h:123
USHORT AttributeOffset
Definition: ntfs.h:251
_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
#define _ftprintf
Definition: tchar.h:518
#define OPEN_EXISTING
Definition: compat.h:634
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
Definition: wdfiotarget.h:859
int64_t LONGLONG
Definition: typedefs.h:68
char TCHAR
Definition: xmlstorage.h:189
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:949
#define _T(x)
Definition: vfdio.h:22
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
ULONG BytesAllocated
Definition: ntfs.h:254
struct NTFS_RECORD_HEADER * PNTFS_RECORD_HEADER
uint64_t ULONGLONG
Definition: typedefs.h:67
Type
Definition: Type.h:6
unsigned long DWORD
Definition: ntddk_ex.h:95
_Must_inspect_result_ _Out_ PHANDLE VolumeHandle
Definition: fltkernel.h:2284
#define FSCTL_GET_NTFS_FILE_RECORD
Definition: ntifs_ex.h:262
unsigned char UCHAR
Definition: xmlstorage.h:181
WCHAR Letter
UCHAR IsNonResident
Definition: ntfs.h:124
#define GENERIC_READ
Definition: compat.h:135
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:913
unsigned short USHORT
Definition: pedump.c:61
struct NTFS_ATTR_RECORD::@165::@168 NonResident
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
USHORT Flags
Definition: ntfs.h:252
_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
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID _In_ LONG _In_z_ PCHAR File
Definition: wdfdevice.h:4061
#define HeapFree(x, y, z)
Definition: compat.h:594
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4751
IN PVOID Instance
Definition: pci.h:361
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG ValueLength
Definition: wdfregistry.h:271