正在获取磁盘几何体信息
本文关键字:几何体 信息 磁盘 获取 | 更新日期: 2023-09-27 18:26:43
我需要获取磁盘几何信息,但出现错误,DeviceIoControl返回false。有什么办法吗?或使用C#和kernel32的其他示例。
[DllImport("kernel32.dll")]
public static extern IntPtr CreateFile(
string lpFileName, int dwDesiredAccess, int dwShareMode,
IntPtr lpSecurityAttributes, int dwCreationDisposition,
int dwFlagsAndAttributes, IntPtr hTemplateFile);
private const int FILE_SHARE_READ = 1;
private const int OPEN_ALWAYS = 4;
private const int INVALID_HANDLE_VALUE = -1;
[DllImport("kernel32.dll", ExactSpelling = true)]
internal static extern bool DeviceIoControl(
IntPtr hDevice, int dwIoControlCode, IntPtr lpInBuffer, int nInBufferSize,
IntPtr lpOutBuffer, int nOutBufferSize, ref int lpBytesReturned, IntPtr lpOverlapped);
private const int IOCTL_DISK_GET_MEDIA_TYPES = 0x00070c00;
static void Main(string[] args)
{
IntPtr hflp = CreateFile(@""''.'C:", 0, FILE_SHARE_READ, IntPtr.Zero, OPEN_ALWAYS, 0, IntPtr.Zero);
if ((int)hflp == INVALID_HANDLE_VALUE)
{ Console.WriteLine("CreateFile failed"); return; }
Type ts = typeof(DISK_GEOMETRY);
int ss = Marshal.SizeOf(ts);
int ssa = ss * 20;
IntPtr mptr = Marshal.AllocHGlobal(ssa);
int byret = 0;
bool ok = DeviceIoControl(hflp, IOCTL_DISK_GET_MEDIA_TYPES, IntPtr.Zero, 0,
mptr, ssa, ref byret, IntPtr.Zero);
if (!ok)
{ Console.WriteLine("DeviceIoControl failed"); return; }
int count = byret / ss;
int run = (int)mptr;
DISK_GEOMETRY gem;
for (int i = 0; i < count; i++)
{
gem = (DISK_GEOMETRY)Marshal.PtrToStructure((IntPtr)run, ts);
Console.WriteLine("MediaType={0} SectorsPerTrack={1}", gem.MediaType, gem.SectorsPerTrack);
run += ss;
}
Marshal.FreeHGlobal(mptr);
}
p.S我已经阅读了msdn关于这方面的帮助。
IOCTL_DISK_GET_MEDIA_TYPES
似乎是遗留的,不再受支持。至少我的操作系统(Win7 x64)就是这样。尝试使用IOCTL_DISK_GET_MEDIA_TYPES
调用DeviceIoControl
会导致错误代码1,ERROR_INVALID_FUNCTION
。
我相信您将需要使用IOCTL_STORAGE_GET_MEDIA_TYPES_EX
。
在这种情况下,我的建议是首先尝试从C++调用API函数。这样,您就不必为p/invoke而烦恼,而且您知道所有的结构和函数原型都是正确的。一旦您知道了如何调用特定的API函数,就可以转换为p/invoke。
顺便说一句,您应该对您的p/调用更加小心。请注意使用uint
来匹配DWORD
,并确保使用SetLastError=true
,以便使用Marshal.GetLastWin32Error()
查询错误代码。
类似这样的东西:
[DllImport("kernel32.dll", SetLastError=true)]
public static extern IntPtr CreateFile(
string lpFileName, uint dwDesiredAccess, uint dwShareMode,
IntPtr lpSecurityAttributes, uint dwCreationDisposition,
uint dwFlagsAndAttributes, IntPtr hTemplateFile);
[DllImport("kernel32.dll", SetLastError=true)]
internal static extern bool DeviceIoControl(
IntPtr hDevice, uint dwIoControlCode, IntPtr lpInBuffer,
uint nInBufferSize, IntPtr lpOutBuffer, uint nOutBufferSize,
ref uint lpBytesReturned, IntPtr lpOverlapped);