using System;
using System.Text;
using System.Runtime.InteropServices;

public class IDE


{
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
internal struct IDSECTOR

{
public ushort wGenConfig;
public ushort wNumCyls;
public ushort wReserved;
public ushort wNumHeads;
public ushort wBytesPerTrack;
public ushort wBytesPerSector;
public ushort wSectorsPerTrack;
[ MarshalAs( UnmanagedType.ByValArray, SizeConst=3)]
public ushort [] wVendorUnique;
[ MarshalAs( UnmanagedType.ByValTStr, SizeConst=20)]
public string sSerialNumber;
public ushort wBufferType;
public ushort wBufferSize;
public ushort wECCSize;
[ MarshalAs( UnmanagedType.ByValTStr, SizeConst=8)]
public string sFirmwareRev;
[ MarshalAs( UnmanagedType.ByValTStr, SizeConst=40)]
public string sModelNumber;
public ushort wMoreVendorUnique;
public ushort wDoubleWordIO;
public ushort wCapabilities;
public ushort wReserved1;
public ushort wPIOTiming;
public ushort wDMATiming;
public ushort wBS;
public ushort wNumCurrentCyls;
public ushort wNumCurrentHeads;
public ushort wNumCurrentSectorsPerTrack;
public uint ulCurrentSectorCapacity;
public ushort wMultSectorStuff;
public uint ulTotalAddressableSectors;
public ushort wSingleWordDMA;
public ushort wMultiWordDMA;
[ MarshalAs( UnmanagedType.ByValArray, SizeConst=128 )]
public byte [] bReserved;
}

[StructLayout(LayoutKind.Sequential)]
internal struct DRIVERSTATUS

{
public byte bDriverError;
public byte bIDEStatus;
[ MarshalAs( UnmanagedType.ByValArray, SizeConst=2 )]
public byte [] bReserved;
[ MarshalAs( UnmanagedType.ByValArray, SizeConst=2 )]
public uint [] dwReserved;
}

[StructLayout(LayoutKind.Sequential)]
internal struct SENDCMDOUTPARAMS

{
public uint cBufferSize;
public DRIVERSTATUS DriverStatus;
[ MarshalAs( UnmanagedType.ByValArray, SizeConst=513 )]
public byte [] bBuffer;
}

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
internal struct SRB_IO_CONTROL

{
public uint HeaderLength;
[ MarshalAs( UnmanagedType.ByValTStr, SizeConst=8 )]
public string Signature;
public uint Timeout;
public uint ControlCode;
public uint ReturnCode;
public uint Length;
}

[StructLayout(LayoutKind.Sequential)]
internal struct IDEREGS

{
public byte bFeaturesReg;
public byte bSectorCountReg;
public byte bSectorNumberReg;
public byte bCylLowReg;
public byte bCylHighReg;
public byte bDriveHeadReg;
public byte bCommandReg;
public byte bReserved;
}

[StructLayout(LayoutKind.Sequential)]
internal struct SENDCMDINPARAMS

{
public uint cBufferSize;
public IDEREGS irDriveRegs;
public byte bDriveNumber;
[ MarshalAs( UnmanagedType.ByValArray, SizeConst=3 )]
public byte [] bReserved;
[ MarshalAs( UnmanagedType.ByValArray, SizeConst=4 )]
public uint [] dwReserved;
public byte bBuffer;
}

[StructLayout(LayoutKind.Sequential)]
internal struct GETVERSIONOUTPARAMS

{
public byte bVersion;
public byte bRevision;
public byte bReserved;
public byte bIDEDeviceMap;
public uint fCapabilities;
[ MarshalAs( UnmanagedType.ByValArray, SizeConst=4 )]
public uint [] dwReserved; // For future use.
}

[DllImport("kernel32.dll")]
private static extern int CloseHandle(uint hObject); [DllImport("kernel32.dll")]
private static extern int DeviceIoControl(uint hDevice,
uint dwIoControlCode,
ref SENDCMDINPARAMS lpInBuffer,
int nInBufferSize,
ref SENDCMDOUTPARAMS lpOutBuffer,
int nOutBufferSize,
ref uint lpbytesReturned,
int lpOverlapped);

[DllImport("kernel32.dll")]
private static extern int DeviceIoControl(uint hDevice,
uint dwIoControlCode,
int lpInBuffer,
int nInBufferSize,
ref GETVERSIONOUTPARAMS lpOutBuffer,
int nOutBufferSize,
ref uint lpbytesReturned,
int lpOverlapped);

[DllImport("kernel32.dll")]
private static extern uint CreateFile(string lpFileName,
uint dwDesiredAccess,
uint dwShareMode,
int lpSecurityAttributes,
uint dwCreationDisposition,
uint dwFlagsAndAttributes,
int hTemplateFile);

private const uint GENERIC_READ = 0x80000000;
private const uint GENERIC_WRITE = 0x40000000;
private const uint FILE_SHARE_READ = 0x00000001;
private const uint FILE_SHARE_WRITE = 0x00000002;
private const uint OPEN_EXISTING = 3;
private const uint INVALID_HANDLE_VALUE = 0xffffffff;
private const uint DFP_GET_VERSION = 0x00074080;
private const int IDE_ATAPI_IDENTIFY = 0xA1; // Returns ID sector for ATAPI.
private const int IDE_ATA_IDENTIFY = 0xEC; // Returns ID sector for ATA.
private const int IDENTIFY_BUFFER_SIZE = 512;
private const uint DFP_RECEIVE_DRIVE_DATA = 0x0007c088;

public static string Read(byte drive)

{
OperatingSystem os = Environment.OSVersion;
if (os.Platform != PlatformID.Win32NT) throw new NotSupportedException("仅支持WindowsNT/2000/XP");
//我没有NT4,请哪位大大测试一下NT4下能不能用
//if (os.Version.Major < 5) throw new NotSupportedException("仅支持WindowsNT/2000/XP");

string driveName = "\\\\.\\PhysicalDrive" + drive.ToString();
uint device = CreateFile(driveName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
0, OPEN_EXISTING, 0, 0);
if (device == INVALID_HANDLE_VALUE) return "";
GETVERSIONOUTPARAMS verPara = new GETVERSIONOUTPARAMS();
uint bytRv = 0;

if (0 != DeviceIoControl(device, DFP_GET_VERSION,
0, 0, ref verPara, Marshal.SizeOf(verPara),
ref bytRv, 0))

{
if (verPara.bIDEDeviceMap > 0)

{
byte bIDCmd = (byte)(((verPara.bIDEDeviceMap >> drive & 0x10) != 0) ? IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY);
SENDCMDINPARAMS scip = new SENDCMDINPARAMS();
SENDCMDOUTPARAMS scop = new SENDCMDOUTPARAMS();

scip.cBufferSize = IDENTIFY_BUFFER_SIZE;
scip.irDriveRegs.bFeaturesReg = 0;
scip.irDriveRegs.bSectorCountReg = 1;
scip.irDriveRegs.bCylLowReg = 0;
scip.irDriveRegs.bCylHighReg = 0;
scip.irDriveRegs.bDriveHeadReg = (byte)(0xA0 | ((drive & 1) << 4));
scip.irDriveRegs.bCommandReg = bIDCmd;
scip.bDriveNumber = drive;

if (0 != DeviceIoControl(device, DFP_RECEIVE_DRIVE_DATA,
ref scip, Marshal.SizeOf(scip), ref scop,
Marshal.SizeOf(scop), ref bytRv, 0))

{
StringBuilder s = new StringBuilder();
for (int i = 20; i < 40; i += 2)

{
s.Append((char)(scop.bBuffer[i+1]));
s.Append((char)scop.bBuffer[i]);
}
CloseHandle(device);
return s.ToString().Trim();
}
}
}
CloseHandle(device);
return "";
}
}

posted @
2007-10-17 09:31
ejiyuan
阅读(
1363)
评论()
编辑
收藏
举报
点击右上角即可分享
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述