に問題があり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
が設定されていますが、出力バッファはすべてゼロです。
私のテスト環境
- OS:Windows 7 Pro 64
- IDE:Visual Studio 2010
- ターゲットフレームワーク:.Net 4.0