我使用下面的代码来获取物理磁盘大小,但返回的大小不正确。我已经用其他工具检查了大小。
以下代码报告:
结构如下:
以下代码报告:
而实际应该是:总磁盘空间:8.249.955.840 字节
如何获取实际/正确的物理磁盘大小?测试过USB驱动器和普通硬盘驱动器。代码很长,这里分开展示。总磁盘空间:8.254.390.272 字节
结构如下:
[StructLayout(LayoutKind.Sequential)]
internal struct DiskGeometry {
public long Cylinders;
public int MediaType;
public int TracksPerCylinder;
public int SectorsPerTrack;
public int BytesPerSector;
}
本地方法:
internal static class NativeMethods {
[DllImport("Kernel32.dll", SetLastError=true, CharSet=CharSet.Auto)]
public static extern SafeFileHandle CreateFile(
string fileName,
uint fileAccess,
uint fileShare,
IntPtr securityAttributes,
uint creationDisposition,
uint flags,
IntPtr template
);
[DllImport("Kernel32.dll", SetLastError=false, CharSet=CharSet.Auto)]
public static extern int DeviceIoControl(
SafeFileHandle device,
uint controlCode,
IntPtr inBuffer,
uint inBufferSize,
IntPtr outBuffer,
uint outBufferSize,
ref uint bytesReturned,
IntPtr overlapped
);
internal const uint FileAccessGenericRead=0x80000000;
internal const uint FileShareWrite=0x2;
internal const uint FileShareRead=0x1;
internal const uint CreationDispositionOpenExisting=0x3;
internal const uint IoCtlDiskGetDriveGeometry=0x70000;
}
主要入口:
internal const uint IoCtlDiskGetDriveGeometry=0x70000;
public static void Main() {
SafeFileHandle diskHandle=
NativeMethods.CreateFile(
@"\\.\PhysicalDrive0",
NativeMethods.FileAccessGenericRead,
NativeMethods.FileShareWrite|NativeMethods.FileShareRead,
IntPtr.Zero,
NativeMethods.CreationDispositionOpenExisting,
0,
IntPtr.Zero
);
if(diskHandle.IsInvalid) {
Console.WriteLine("CreateFile failed with error: {0}", Marshal.GetLastWin32Error());
return;
}
int geometrySize=Marshal.SizeOf(typeof(DiskGeometry));
Console.WriteLine("geometry size = {0}", geometrySize);
IntPtr geometryBlob=Marshal.AllocHGlobal(geometrySize);
uint numBytesRead=0;
if(
0==NativeMethods.DeviceIoControl(
diskHandle,
NativeMethods.IoCtlDiskGetDriveGeometry,
IntPtr.Zero,
0,
geometryBlob,
(uint)geometrySize,
ref numBytesRead,
IntPtr.Zero
)
) {
Console.WriteLine(
"DeviceIoControl failed with error: {0}",
Marshal.GetLastWin32Error()
);
return;
}
Console.WriteLine("Bytes read = {0}", numBytesRead);
DiskGeometry geometry=(DiskGeometry)Marshal.PtrToStructure(geometryBlob, typeof(DiskGeometry));
Marshal.FreeHGlobal(geometryBlob);
long bytesPerCylinder=(long)geometry.TracksPerCylinder*(long)geometry.SectorsPerTrack*(long)geometry.BytesPerSector;
long totalSize=geometry.Cylinders*bytesPerCylinder;
Console.WriteLine("Media Type: {0}", geometry.MediaType);
Console.WriteLine("Cylinders: {0}", geometry.Cylinders);
Console.WriteLine("Tracks per Cylinder: {0}", geometry.TracksPerCylinder);
Console.WriteLine("Sectors per Track: {0}", geometry.SectorsPerTrack);
Console.WriteLine("Bytes per Sector: {0}", geometry.BytesPerSector);
Console.WriteLine("Bytes per Cylinder: {0}", bytesPerCylinder);
Console.WriteLine("Total disk space: {0}", totalSize);
}