Jak dobrać się do danych o dysku SSD z poziomu c#?

Napisałem taki kod:


using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Linq;
using System.Collections.Generic;
using System.Management;
using System.ComponentModel;

public class SmartInfo
{
   

    public void GetDiskUsageTime(out TimeSpan readTime, out TimeSpan writeTime)
    {
        try
        {
            var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PerfFormattedData_PerfDisk_PhysicalDisk");
            foreach (ManagementObject disk in searcher.Get())
            {
                var diskName = disk["Name"].ToString().Trim();
                if (diskName.StartsWith("PhysicalDisk"))
                {
                    readTime = TimeSpan.FromMilliseconds(Convert.ToUInt32(disk["AvgDiskReadTime"]));
                    writeTime = TimeSpan.FromMilliseconds(Convert.ToUInt32(disk["AvgDiskWriteTime"]));
                    return;
                }
            }
        }
        catch (ManagementException e)
        {
            throw new Exception($"WMI data error: {e.Message}");
        }

        readTime = writeTime = TimeSpan.Zero;
    }

  
}

public class DiskPerformance
{
    // Struktura reprezentująca dane o dysku
    [StructLayout(LayoutKind.Sequential)]
    public struct DISK_PERFORMANCE
    {
        public ulong BytesRead;
        public ulong BytesWritten;
        public uint ReadCount;
        public uint WriteCount;
        public uint QueueDepth;
        public uint ReadTime;
        public uint WriteTime;
        public uint IdleTime;
        public uint ReadTime2; 
    }

    // Importowanie funkcji z biblioteki kernel32.dll
    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern IntPtr CreateFile(
        string lpFileName,
        uint dwDesiredAccess,
        uint dwShareMode,
        IntPtr lpSecurityAttributes,
        uint dwCreationDisposition,
        uint dwFlagsAndAttributes,
        IntPtr hTemplateFile
    );

    [DllImport("kernel32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool DeviceIoControl(
        IntPtr hDevice,
        uint dwIoControlCode,
        IntPtr lpInBuffer,
        uint nInBufferSize,
        ref DISK_PERFORMANCE lpOutBuffer,
        uint nOutBufferSize,
        ref uint lpBytesReturned,
        IntPtr lpOverlapped
    );

    [DllImport("kernel32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool CloseHandle(IntPtr hObject);

    public static DISK_PERFORMANCE GetDiskPerformance(int diskNumber)
    {
        DISK_PERFORMANCE perf = new DISK_PERFORMANCE();
        IntPtr hDevice = CreateFile(
            $@"\\.\PhysicalDrive{diskNumber}",
            0,
            3,  // FILE_SHARE_READ | FILE_SHARE_WRITE
            IntPtr.Zero,
            3,  // OPEN_EXISTING
            0,
            IntPtr.Zero
        );

        if (hDevice == IntPtr.Zero)
        {
            throw new Exception("Failed to open disk");
        }

        uint bytesReturned = 0;
        bool success = DeviceIoControl(
            hDevice,
            0x00070000,  // IOCTL_DISK_PERFORMANCE
            IntPtr.Zero,
            0,
            ref perf,
            (uint)Marshal.SizeOf(perf),
            ref bytesReturned,
            IntPtr.Zero
        );

        CloseHandle(hDevice);

        if (!success)
        {
            throw new Exception("Failed to retrieve disk performance");
        }

        return perf;
    }

    public static double BytesToGB(ulong bytesValue)
    {
        return bytesValue / Math.Pow(1024, 3);
    }

    public static double MSToHours(uint msValue)
    {
        return msValue / (1000.0 * 60 * 60);
    }

    public static void Main()
    {
        try
        {
            var smartInfo = new SmartInfo();
            TimeSpan readTime, writeTime;
            smartInfo.GetDiskUsageTime(out readTime, out writeTime);

            Console.WriteLine($"Czas odczytu dysku: {readTime}");
            Console.WriteLine($"Czas zapisu dysku: {writeTime}");

            int diskNumber = 0;  
            DISK_PERFORMANCE diskPerformance = GetDiskPerformance(diskNumber);

            Console.WriteLine($"Całkowita ilość odczytanych bajtów: {diskPerformance.BytesRead} B ({BytesToGB(diskPerformance.BytesRead):F2} GB)");
            Console.WriteLine($"Całkowita ilość zapisanych bajtów: {diskPerformance.BytesWritten} B ({BytesToGB(diskPerformance.BytesWritten):F2} GB)");
            Console.WriteLine($"Całkowita liczba operacji odczytu: {diskPerformance.ReadCount}");
            Console.WriteLine($"Całkowita liczba operacji zapisu: {diskPerformance.WriteCount}");
            Console.WriteLine($"Całkowity czas pracy dysku: {diskPerformance.ReadTime} ms ({MSToHours(diskPerformance.ReadTime):F2} godzin)");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Wystąpił błąd: {ex.Message}");
        }
    }
}

I wynik:

Czas odczytu dysku: 00:00:00
Czas zapisu dysku: 00:00:00
Całkowita ilość odczytanych bajtów: 62260 B (0,00 GB)
Całkowita ilość zapisanych bajtów: 1095216660492 B (1020,00 GB)
Całkowita liczba operacji odczytu: 63
Całkowita liczba operacji zapisu: 512
Całkowity czas pracy dysku: 0 ms (0,00 godzin)

Nie tego się spodziewałem.

Skąd ten absurd w odczycie czy czasie pracy dysku?
Z programów komercyjnych wyniki są inne:

screenshot-20240102132201.png