我遇到了一些问题DeviceIOControl
。我正在尝试从物理驱动器读取磁盘几何形状,但从未设置输出缓冲区。
这是我的代码示例,它是一个简单的函数,应该获取磁盘几何形状并返回磁盘是否可移动:
public static bool IsDeviceRemovable(int DriveNo) {
string Filename=@"\\.\Physicaldrive"+DriveNo;
SafeFileHandle drive=CreateFile(
Filename,
FileAccess_e.None,
FileShare_e.Write|FileShare_e.Read,
IntPtr.Zero,
CreationDisposition_e.OpenExisting,
FileAttributes_e.None,
IntPtr.Zero
);
if(drive.IsInvalid) {
throw new IOException("Unable to access drive. Win32 Error Code: "+Marshal.GetLastWin32Error());
}
uint bytesReturned=0;
DISK_GEOMETRY dg=new DISK_GEOMETRY();
if(!DeviceIoControl(
drive,
IOControlCode_e.DiskGetDriveGeometry,
IntPtr.Zero,
0,
dg,
(uint)Marshal.SizeOf(dg),
ref bytesReturned,
IntPtr.Zero
)) {
throw new Exception("Unable to get properties from device. Win32 Error Code: "+Marshal.GetLastWin32Error());
}
drive.Close();
return dg.MediaType==MEDIA_TYPE.RemovableMedia;
}
还有一些数据结构:
[DllImport("Kernel32.dll", SetLastError=false, CharSet=CharSet.Auto)]
private static extern bool DeviceIoControl(
SafeFileHandle hDevice,
IOControlCode_e IoControlCode,
[MarshalAs(UnmanagedType.AsAny)]
[In] object InBuffer,
uint nInBufferSize,
[MarshalAs(UnmanagedType.AsAny)]
[Out] object OutBuffer,
uint nOutBufferSize,
ref uint pBytesReturned,
IntPtr Overlapped
);
[DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Auto)]
private static extern SafeFileHandle CreateFile(
string lpFileName,
FileAccess_e dwDesiredAccess,
FileShare_e dwShareMode,
IntPtr lpSecurityAttributes,
CreationDisposition_e dwCreationDisposition,
FileAttributes_e dwFlagsAndAttributes,
IntPtr hTemplateFile
);
private enum MEDIA_TYPE {
Unknown=0x00,
F5_1Pt2_512=0x01,
F3_1Pt44_512=0x02,
F3_2Pt88_512=0x03,
F3_20Pt8_512=0x04,
F3_720_512=0x05,
F5_360_512=0x06,
F5_320_512=0x07,
F5_320_1024=0x08,
F5_180_512=0x09,
F5_160_512=0x0a,
RemovableMedia=0x0b,
FixedMedia=0x0c,
F3_120M_512=0x0d,
F3_640_512=0x0e,
F5_640_512=0x0f,
F5_720_512=0x10,
F3_1Pt2_512=0x11,
F3_1Pt23_1024=0x12,
F5_1Pt23_1024=0x13,
F3_128Mb_512=0x14,
F3_230Mb_512=0x15,
F8_256_128=0x16,
F3_200Mb_512=0x17,
F3_240M_512=0x18,
F3_32M_512=0x19
}
[StructLayout(LayoutKind.Sequential)]
private struct DISK_GEOMETRY {
public Int64 Cylinders;
public MEDIA_TYPE MediaType;
public Int32 TracksPerCylinder;
public Int32 SectorsPerTrack;
public Int32 BytesPerSector;
}
我使用的枚举来自
bytesReturned
变量被设置(在本例中为 24),但变量dg
全为零。
我尝试了其他几个DeviceIoControl
具有相同结果的函数:bytesReturned
已设置但输出缓冲区全为零。
我的测试环境
- 操作系统:Windows 7 Pro 64
- IDE:Visual Studio 2010
- 目标框架:.Net 4.0