[FSUTIL]
authorPierre Schweitzer <pierre@reactos.org>
Mon, 25 Sep 2017 18:59:54 +0000 (18:59 +0000)
committerPierre Schweitzer <pierre@reactos.org>
Mon, 25 Sep 2017 18:59:54 +0000 (18:59 +0000)
- Modify OpenVolume so that it can restrict volume opening to a NTFS volume (broken on ROS...)
- Implement fsutil fsinfo ntfsinfo

svn path=/trunk/; revision=75966

reactos/base/applications/cmdutils/fsutil/common.c
reactos/base/applications/cmdutils/fsutil/dirty.c
reactos/base/applications/cmdutils/fsutil/fsinfo.c
reactos/base/applications/cmdutils/fsutil/fsutil.h
reactos/base/applications/cmdutils/fsutil/volume.c

index 26120d8..ae646a1 100644 (file)
@@ -47,15 +47,13 @@ int FindHandler(int argc,
 }
 
 HANDLE OpenVolume(const TCHAR * Volume,
-                  BOOLEAN AllowRemote)
+                  BOOLEAN AllowRemote,
+                  BOOLEAN NtfsOnly)
 {
     UINT Type;
     HANDLE hVolume;
     TCHAR VolumeID[PATH_MAX];
 
-    /* Create full name */
-    _stprintf(VolumeID, _T("\\\\.\\%s"), Volume);
-
     /* Get volume type */
     if (!AllowRemote && Volume[1] == L':')
     {
@@ -67,6 +65,28 @@ HANDLE OpenVolume(const TCHAR * Volume,
         }
     }
 
+    /* Get filesystem type */
+    if (NtfsOnly)
+    {
+        TCHAR FileSystem[MAX_PATH + 1];
+
+        _stprintf(VolumeID, _T("\\\\.\\%s\\"), Volume);
+        if (!GetVolumeInformation(VolumeID, NULL,  0, NULL, NULL, NULL, FileSystem, MAX_PATH + 1))
+        {
+            PrintErrorMessage(GetLastError());
+            return INVALID_HANDLE_VALUE;
+        }
+
+        if (_tcscmp(FileSystem, _T("NTFS")) != 0)
+        {
+            _ftprintf(stderr, _T("FSUTIL needs a NTFS device\n"));
+            return INVALID_HANDLE_VALUE;
+        }
+    }
+
+    /* Create full name */
+    _stprintf(VolumeID, _T("\\\\.\\%s"), Volume);
+
     /* Open the volume */
     hVolume = CreateFile(VolumeID, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
                          NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
index e5fabb3..e3179a0 100644 (file)
@@ -34,7 +34,7 @@ QueryMain(int argc, const TCHAR *argv[])
     }
 
     /* Get a handle for the volume */
-    Volume = OpenVolume(argv[1], FALSE);
+    Volume = OpenVolume(argv[1], FALSE, FALSE);
     if (Volume == INVALID_HANDLE_VALUE)
     {
         return 1;
@@ -72,7 +72,7 @@ SetMain(int argc, const TCHAR *argv[])
     }
 
     /* Get a handle for the volume */
-    Volume = OpenVolume(argv[1], FALSE);
+    Volume = OpenVolume(argv[1], FALSE, FALSE);
     if (Volume == INVALID_HANDLE_VALUE)
     {
         return 1;
index 8af4c55..2e5edd9 100644 (file)
@@ -12,6 +12,7 @@
 static HandlerProc DrivesMain;
 static HandlerProc DriveTypeMain;
 static HandlerProc VolumeInfoMain;
+static HandlerProc NtfsInfoMain;
 static HandlerProc StatisticsMain;
 static HandlerItem HandlersList[] =
 {
@@ -19,6 +20,7 @@ static HandlerItem HandlersList[] =
     { DrivesMain, _T("drives"), _T("Enumerates the drives") },
     { DriveTypeMain, _T("drivetype"), _T("Provides the type of a drive") },
     { VolumeInfoMain, _T("volumeinfo"), _T("Provides informations about a volume") },
+    { NtfsInfoMain, _T("ntfsinfo"), _T("Displays informations about a NTFS volume") },
     { StatisticsMain, _T("statistics"), _T("Displays volume statistics") },
 };
 
@@ -158,6 +160,68 @@ VolumeInfoMain(int argc, const TCHAR *argv[])
     return 0;
 }
 
+static int
+NtfsInfoMain(int argc, const TCHAR *argv[])
+{
+    HANDLE Volume;
+    DWORD BytesRead;
+    struct
+    {
+        NTFS_VOLUME_DATA_BUFFER;
+        NTFS_EXTENDED_VOLUME_DATA;
+    } Data;
+
+    /* We need a volume (letter or GUID) */
+    if (argc < 2)
+    {
+        _ftprintf(stderr, _T("Usage: fsutil fsinfo ntfsinfo <volume>\n"));
+        _ftprintf(stderr, _T("\tFor example: fsutil fsinfo ntfsinfo c:\n"));
+        return 1;
+    }
+
+    /* Get a handle for the volume */
+    Volume = OpenVolume(argv[1], FALSE, TRUE);
+    if (Volume == INVALID_HANDLE_VALUE)
+    {
+        return 1;
+    }
+
+    /* And query the NTFS data */
+    if (DeviceIoControl(Volume, FSCTL_GET_NTFS_VOLUME_DATA, NULL, 0, &Data,
+                        sizeof(Data), &BytesRead, NULL) == FALSE)
+    {
+        PrintErrorMessage(GetLastError());
+        CloseHandle(Volume);
+        return 1;
+    }
+
+    /* We no longer need the volume */
+    CloseHandle(Volume);
+
+    /* Dump data */
+    _ftprintf(stdout, _T("NTFS volume serial number:\t\t0x%0.16I64x\n"), Data.VolumeSerialNumber.QuadPart);
+    /* Only print version if extended structure was returned */
+    if (BytesRead > sizeof(NTFS_VOLUME_DATA_BUFFER))
+    {
+        _ftprintf(stdout, _T("Version:\t\t\t\t%u.%u\n"), Data.MajorVersion, Data.MinorVersion);
+    }
+    _ftprintf(stdout, _T("Number of sectors:\t\t\t0x%0.16I64x\n"), Data.NumberSectors.QuadPart);
+    _ftprintf(stdout, _T("Total number of clusters:\t\t0x%0.16I64x\n"), Data.TotalClusters.QuadPart);
+    _ftprintf(stdout, _T("Free clusters:\t\t\t\t0x%0.16I64x\n"), Data.FreeClusters.QuadPart);
+    _ftprintf(stdout, _T("Total number of reserved clusters:\t0x%0.16I64x\n"), Data.TotalReserved.QuadPart);
+    _ftprintf(stdout, _T("Bytes per sector:\t\t\t%d\n"), Data.BytesPerSector);
+    _ftprintf(stdout, _T("Bytes per cluster:\t\t\t%d\n"), Data.BytesPerCluster);
+    _ftprintf(stdout, _T("Bytes per file record segment:\t\t%d\n"), Data.BytesPerFileRecordSegment);
+    _ftprintf(stdout, _T("Clusters per file record segment:\t%d\n"), Data.ClustersPerFileRecordSegment);
+    _ftprintf(stdout, _T("MFT valid data length:\t\t\t0x%0.16I64x\n"), Data.MftValidDataLength.QuadPart);
+    _ftprintf(stdout, _T("MFT start LCN:\t\t\t\t0x%0.16I64x\n"), Data.MftStartLcn.QuadPart);
+    _ftprintf(stdout, _T("MFT2 start LCN:\t\t\t\t0x%0.16I64x\n"), Data.Mft2StartLcn.QuadPart);
+    _ftprintf(stdout, _T("MFT zone start:\t\t\t\t0x%0.16I64x\n"), Data.MftZoneStart.QuadPart);
+    _ftprintf(stdout, _T("MFT zone end:\t\t\t\t0x%0.16I64x\n"), Data.MftZoneEnd.QuadPart);
+
+    return 0;
+}
+
 #define DUMP_VALUE(stats, value) fprintf(stdout, "%s: %lu\n", #value, stats->value)
 
 static void
@@ -477,7 +541,7 @@ StatisticsMain(int argc, const TCHAR *argv[])
     }
 
     /* Get a handle for the volume */
-    Volume = OpenVolume(argv[1], FALSE);
+    Volume = OpenVolume(argv[1], FALSE, FALSE);
     if (Volume == INVALID_HANDLE_VALUE)
     {
         return 1;
index 55e27d1..032078d 100644 (file)
@@ -22,7 +22,8 @@ int FindHandler(int argc,
                 void (*UsageHelper)(const TCHAR *));
 
 HANDLE OpenVolume(const TCHAR * Volume,
-                  BOOLEAN AllowRemote);
+                  BOOLEAN AllowRemote,
+                  BOOLEAN NtfsOnly);
 
 void PrintDefaultUsage(const TCHAR * Command,
                        const TCHAR * SubCommand,
index abd31c6..65f3106 100644 (file)
@@ -50,7 +50,7 @@ DismountMain(int argc, const TCHAR *argv[])
     }
 
     /* Get a handle for the volume */
-    Volume = OpenVolume(argv[1], FALSE);
+    Volume = OpenVolume(argv[1], FALSE, FALSE);
     if (Volume == INVALID_HANDLE_VALUE)
     {
         return 1;