Author: pschweitzer
Date: Tue Jun 30 21:03:55 2015
New Revision: 68326
URL:
http://svn.reactos.org/svn/reactos?rev=68326&view=rev
Log:
[NTFSINFO]
Time to free some Sysinternals tool: ntfsinfo.
To make it short, this tool dumps various information about a NTFS volume and its reserved
meta-data files
Our version comes with three advantages compared to the Russinovich's tool:
- It's FLOSS
- It works properly on NT5+ (developed with W2K3 & W7) whereas R's cannot display
meta-data files information
- It will open a volume by default if none provided
One issue so far: it doesn't work properly on ReactOS!
CORE-8725
Added:
trunk/rosapps/applications/cmdutils/ntfsinfo/
trunk/rosapps/applications/cmdutils/ntfsinfo/CMakeLists.txt (with props)
trunk/rosapps/applications/cmdutils/ntfsinfo/ntfsinfo.c (with props)
trunk/rosapps/applications/cmdutils/ntfsinfo/ntfsinfo.rc (with props)
Modified:
trunk/rosapps/applications/cmdutils/CMakeLists.txt
Modified: trunk/rosapps/applications/cmdutils/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/rosapps/applications/cmdutils/CMak…
==============================================================================
--- trunk/rosapps/applications/cmdutils/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/rosapps/applications/cmdutils/CMakeLists.txt [iso-8859-1] Tue Jun 30 21:03:55
2015
@@ -1,5 +1,6 @@
add_subdirectory(appwiz)
add_subdirectory(cat)
+add_subdirectory(ntfsinfo)
add_subdirectory(tee)
add_subdirectory(touch)
add_subdirectory(uptime)
Added: trunk/rosapps/applications/cmdutils/ntfsinfo/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/rosapps/applications/cmdutils/ntfs…
==============================================================================
--- trunk/rosapps/applications/cmdutils/ntfsinfo/CMakeLists.txt (added)
+++ trunk/rosapps/applications/cmdutils/ntfsinfo/CMakeLists.txt [iso-8859-1] Tue Jun 30
21:03:55 2015
@@ -0,0 +1,5 @@
+list(APPEND SOURCE ntfsinfo.c ntfsinfo.rc)
+add_executable(ntfsinfo ${SOURCE})
+set_module_type(ntfsinfo win32cui UNICODE)
+add_importlibs(ntfsinfo msvcrt kernel32 ntdll)
+add_cd_file(TARGET ntfsinfo DESTINATION reactos/system32 FOR all)
Propchange: trunk/rosapps/applications/cmdutils/ntfsinfo/CMakeLists.txt
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/rosapps/applications/cmdutils/ntfsinfo/ntfsinfo.c
URL:
http://svn.reactos.org/svn/reactos/trunk/rosapps/applications/cmdutils/ntfs…
==============================================================================
--- trunk/rosapps/applications/cmdutils/ntfsinfo/ntfsinfo.c (added)
+++ trunk/rosapps/applications/cmdutils/ntfsinfo/ntfsinfo.c [iso-8859-1] Tue Jun 30
21:03:55 2015
@@ -0,0 +1,212 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS NTFS Information tool
+ * FILE: cmdutils/ntfsinfo/ntfsinfo.c
+ * PURPOSE: Query information from NTFS volume using FSCTL
+ * PROGRAMMERS: Pierre Schweitzer <pierre(a)reactos.org>
+ */
+
+#include <windows.h>
+#include <tchar.h>
+#include <stdio.h>
+
+typedef struct
+{
+ ULONG Type;
+ USHORT UsaOffset;
+ USHORT UsaCount;
+ ULONGLONG Lsn;
+} NTFS_RECORD_HEADER, *PNTFS_RECORD_HEADER;
+
+#define NRH_FILE_TYPE 0x454C4946
+#define ATTRIBUTE_TYPE_DATA 0x80
+#define ATTRIBUTE_TYPE_END 0xFFFFFFFF
+
+typedef struct _FILE_RECORD_HEADER
+{
+ NTFS_RECORD_HEADER Ntfs;
+ USHORT SequenceNumber;
+ USHORT LinkCount;
+ USHORT AttributeOffset;
+ USHORT Flags;
+ ULONG BytesInUse;
+ ULONG BytesAllocated;
+ ULONGLONG BaseFileRecord;
+ USHORT NextAttributeNumber;
+} FILE_RECORD_HEADER, *PFILE_RECORD_HEADER;
+
+typedef struct
+{
+ ULONG Type;
+ ULONG Length;
+ UCHAR IsNonResident;
+ UCHAR NameLength;
+ USHORT NameOffset;
+ USHORT Flags;
+ USHORT Instance;
+ union
+ {
+ struct
+ {
+ ULONG ValueLength;
+ USHORT ValueOffset;
+ UCHAR Flags;
+ UCHAR Reserved;
+ } Resident;
+ struct
+ {
+ ULONGLONG LowestVCN;
+ ULONGLONG HighestVCN;
+ USHORT MappingPairsOffset;
+ USHORT CompressionUnit;
+ UCHAR Reserved[4];
+ LONGLONG AllocatedSize;
+ LONGLONG DataSize;
+ LONGLONG InitializedSize;
+ LONGLONG CompressedSize;
+ } NonResident;
+ };
+} NTFS_ATTR_RECORD, *PNTFS_ATTR_RECORD;
+
+static TCHAR * MetaDataFiles[] = {
+ _T("$MFT\t\t"),
+ _T("$MFTMirr\t"),
+ _T("$LogFile\t"),
+ _T("$Volume\t\t"),
+ _T("$AttrDef\t"),
+ _T("."),
+ _T("$Bitmap\t\t"),
+ _T("$Boot\t\t"),
+ _T("$BadClus\t"),
+ _T("$Quota\t\t"),
+ _T("$UpCase\t\t"),
+ _T("$Extended\t"),
+ NULL,
+};
+
+int
+__cdecl
+_tmain(int argc, const TCHAR *argv[])
+{
+ TCHAR VolumeName[] = _T("\\\\.\\C:");
+ HANDLE VolumeHandle;
+ NTFS_VOLUME_DATA_BUFFER VolumeInfo;
+ DWORD LengthReturned;
+ ULONGLONG VolumeSize;
+ ULONGLONG MftClusters;
+ UINT File = 0;
+ PNTFS_FILE_RECORD_OUTPUT_BUFFER OutputBuffer;
+
+ if (argc > 1)
+ {
+ TCHAR Letter = argv[1][0];
+
+ if ((Letter >= 'A' && Letter <= 'Z') ||
+ (Letter >= 'a' && Letter <= 'z'))
+ {
+ VolumeName[4] = Letter;
+ }
+ }
+
+ VolumeHandle = CreateFile(VolumeName, GENERIC_READ, FILE_SHARE_READ |
FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 );
+ if (VolumeHandle == INVALID_HANDLE_VALUE)
+ {
+ _ftprintf(stderr, _T("Failed opening the volume '%s' (%lx)\n"),
VolumeName, GetLastError());
+ return 1;
+ }
+
+ if (!DeviceIoControl(VolumeHandle, FSCTL_GET_NTFS_VOLUME_DATA, NULL, 0,
&VolumeInfo, sizeof(VolumeInfo), &LengthReturned, NULL))
+ {
+ _ftprintf(stderr, _T("Failed requesting volume '%s' data
(%lx)\n"), VolumeName, GetLastError());
+ CloseHandle(VolumeHandle);
+ return 1;
+ }
+
+ if (LengthReturned < sizeof(VolumeInfo))
+ {
+ _ftprintf(stderr, _T("Failed reading volume '%s' data
(%lx)\n"), VolumeName, GetLastError());
+ CloseHandle(VolumeHandle);
+ return 1;
+ }
+
+ _tprintf(_T("Volume Size\n-----------\n"));
+ VolumeSize = VolumeInfo.TotalClusters.QuadPart * VolumeInfo.BytesPerCluster;
+ _tprintf(_T("Volume size\t\t: %I64u MB\n"), VolumeSize >> 20);
+ _tprintf(_T("Total sectors\t\t: %I64u\n"),
VolumeInfo.NumberSectors.QuadPart);
+ _tprintf(_T("Total clusters\t\t: %I64u\n"),
VolumeInfo.TotalClusters.QuadPart);
+ _tprintf(_T("Free clusters\t\t: %I64u\n"),
VolumeInfo.FreeClusters.QuadPart);
+ _tprintf(_T("Free space\t\t: %I64u MB (%u%% of drive)\n"),
(VolumeInfo.FreeClusters.QuadPart * VolumeInfo.BytesPerCluster) >> 20,
(VolumeInfo.FreeClusters.QuadPart * 100) / VolumeInfo.TotalClusters.QuadPart);
+
+ _tprintf(_T("\nAllocation Size\n---------------\n"));
+ _tprintf(_T("Bytes per sector\t: %lu\n"), VolumeInfo.BytesPerSector);
+ _tprintf(_T("Bytes per cluster\t: %lu\n"), VolumeInfo.BytesPerCluster);
+ _tprintf(_T("Bytes per MFT record:\t: %lu\n"),
VolumeInfo.BytesPerFileRecordSegment);
+ _tprintf(_T("Clusters per MFT record\t: %lu\n"),
VolumeInfo.ClustersPerFileRecordSegment);
+
+ _tprintf(_T("\nMFT Information\n---------------\n"));
+ _tprintf(_T("MFT size\t\t: %I64u MB (%u%% of drive)\n"),
VolumeInfo.MftValidDataLength.QuadPart >> 20,
(VolumeInfo.MftValidDataLength.QuadPart * 100) / VolumeSize);
+ _tprintf(_T("MFT start cluster\t: %I64u\n"),
VolumeInfo.MftStartLcn.QuadPart);
+ _tprintf(_T("MFT zone clusters\t: %I64u - %I64u\n"),
VolumeInfo.MftZoneStart.QuadPart, VolumeInfo.MftZoneEnd.QuadPart);
+ MftClusters = VolumeInfo.MftZoneEnd.QuadPart - VolumeInfo.MftZoneStart.QuadPart;
+ _tprintf(_T("MFT zone size\t\t: %I64u MB (%u%% of drive)\n"), (MftClusters
* VolumeInfo.BytesPerCluster) >> 20, (MftClusters * 100) /
VolumeInfo.TotalClusters.QuadPart);
+ _tprintf(_T("MFT mirror start\t: %I64u\n"),
VolumeInfo.Mft2StartLcn.QuadPart);
+
+ _tprintf(_T("\nMeta-Data files\n---------------\n"));
+ OutputBuffer = HeapAlloc(GetProcessHeap(), 0, VolumeInfo.BytesPerFileRecordSegment +
sizeof(NTFS_FILE_RECORD_OUTPUT_BUFFER));
+ while (MetaDataFiles[File] != NULL)
+ {
+ NTFS_FILE_RECORD_INPUT_BUFFER InputBuffer;
+ PFILE_RECORD_HEADER FileRecord;
+ PNTFS_ATTR_RECORD Attribute;
+ ULONGLONG Size = 0;
+
+ if (File == 5)
+ {
+ ++File;
+ continue;
+ }
+
+ InputBuffer.FileReferenceNumber.QuadPart = File;
+ if (!DeviceIoControl(VolumeHandle, FSCTL_GET_NTFS_FILE_RECORD, &InputBuffer,
sizeof(InputBuffer),
+ OutputBuffer, VolumeInfo.BytesPerFileRecordSegment +
sizeof(NTFS_FILE_RECORD_OUTPUT_BUFFER),
+ &LengthReturned, NULL))
+ {
+ ++File;
+ continue;
+ }
+
+ if (OutputBuffer->FileReferenceNumber.QuadPart != File)
+ {
+ ++File;
+ continue;
+ }
+
+ FileRecord = (PFILE_RECORD_HEADER)OutputBuffer->FileRecordBuffer;
+ if (FileRecord->Ntfs.Type != NRH_FILE_TYPE)
+ {
+ ++File;
+ continue;
+ }
+
+ Attribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord +
FileRecord->AttributeOffset);
+ while (Attribute < (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord +
FileRecord->BytesInUse) &&
+ Attribute->Type != ATTRIBUTE_TYPE_END)
+ {
+ if (Attribute->Type == ATTRIBUTE_TYPE_DATA)
+ {
+ Size = (Attribute->IsNonResident) ?
Attribute->NonResident.AllocatedSize : Attribute->Resident.ValueLength;
+ break;
+ }
+
+ Attribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)Attribute +
Attribute->Length);
+ }
+
+ _tprintf(_T("%s%I64u bytes\n"), MetaDataFiles[File], Size);
+
+ ++File;
+ }
+
+ HeapFree(GetProcessHeap(), 0, OutputBuffer);
+ CloseHandle(VolumeHandle);
+ return 0;
+}
Propchange: trunk/rosapps/applications/cmdutils/ntfsinfo/ntfsinfo.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/rosapps/applications/cmdutils/ntfsinfo/ntfsinfo.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/rosapps/applications/cmdutils/ntfs…
==============================================================================
--- trunk/rosapps/applications/cmdutils/ntfsinfo/ntfsinfo.rc (added)
+++ trunk/rosapps/applications/cmdutils/ntfsinfo/ntfsinfo.rc [iso-8859-1] Tue Jun 30
21:03:55 2015
@@ -0,0 +1,4 @@
+#define REACTOS_STR_FILE_DESCRIPTION "NTFS Information\0"
+#define REACTOS_STR_INTERNAL_NAME "ntfsinfo\0"
+#define REACTOS_STR_ORIGINAL_FILENAME "ntfsinfo.exe\0"
+#include <reactos/version.rc>
Propchange: trunk/rosapps/applications/cmdutils/ntfsinfo/ntfsinfo.rc
------------------------------------------------------------------------------
svn:eol-style = native