2

残念ながら、このリンクは閉鎖されましたが、実際の質問があります: Windows でボリュームのサイズを取得する

Windows で WMI を使用して Win32_Volume と c:\ ドライブの Capacity プロパティを介してボリュームの容量を取得すると、次の値が取得されます: 499513290752

しかし、私が使用するとき

bool Success = DeviceIoControl(
            Handle,
            IoControl.IOCTL_DISK_GET_LENGTH_INFO,
            IntPtr.Zero, //InBuffer
            0,  //InBuffer Size
            OutputBuffer,
            (uint)Marshal.SizeOf(OutputLengthInfo),
            out BytesReturned,
            IntPtr.Zero
        );

私が得る: 499513294848 これは、WMI が報告するものよりも正確に 4096 大きいです。これは、ハード ドライブのすべてのボリュームで同じです。(このハンドルは、「\\?\Volume{93b1858d-033d-4719-a42a-870d8eb3fe0d}\」というファイル名で CreateFile() を呼び出して取得した SafeFileHandle です)。

また、次を使用して c:\ ドライブを照会します

uint SectorsPerCluster = 0;
uint BytesPerSector = 0;
uint NumberOfFreeClusters = 0;
uint TotalNumberOfClusters = 0;

GetDiskFreeSpace(
    Drive, 
    out SectorsPerCluster, 
    out BytesPerSector, 
    out NumberOfFreeClusters, 
    out TotalNumberOfClusters
);

合計 121951487 個のクラスター、クラスターあたり 8 セクター、およびセクターあたり 512 バイトがあることを報告します。これは、WMI と同じ 499513290752 バイトになります。

Win32_DiskPartition を使用すると、容量の DeviceIoControl と同じ値が報告されますが、これは奇妙です (ここでのファイル名は、一例として「\\?\GLOBALROOT\Device\Harddisk0\Partition1」です)。

また、「\\.\PhysicalDrive0」で指定された物理ディスクの Win32_DiskDrive と DeviceIoControl 関数から取得した値を比較すると、大きく異なる数値が得られます。

Win32_DiskDrive: 500105249280

IoControl: 500107862016 (約 2.5 MiB の違いだと思います)

Win32_DiskDrive のサイズは、WMI クラスで報告されている 1 セクターあたりのバイト数 * 合計セクター数 (512 バイト/セクター * 976768065 合計セクター = 500105249280) の計算と一致します。Disk Geometry の値は、500105249280 のディスク サイズもサポートしています。

では、どの値/ソースを信頼する必要がありますか? また、ボリュームに対して常に 4096 バイト異なるのはなぜですか? IOCTL_DISK_GET_LENGTH_INFO はパーティションに対してのみ有効であり、物理ディスクまたはボリュームに対しては有効ではありませんか?

更新: いくつかの詳細情報/説明。物理セクターの読み取りも試みましたが、DiskGeometry と Win32_DiskDrive によって報告されたディスク サイズを超えて読み取ることができます。この場合、IOCTL_DISK_GET_LENGTH_INFO の値は実際には正しく、この関数によって報告されたセクター数まで読み取ることができ、それを超えて読み取ろうとするとエラーが発生します。では、他の関数が実際のセクターの合計数/正しいサイズを報告しないのはなぜでしょうか? 物理ディスクは、一部の機能がアクセスできない特定の領域を隠していますか?

4

1 に答える 1