- UID
- 390967
- 帖子
- 1599
- 主題
- 824
- 精華
- 0
- 積分
- 854
- 楓幣
- 11070
- 威望
- 395
- 存款
- 10100
- 贊助金額
- 1800
- 推廣
- 0
- GP
- 2684
- 閱讀權限
- 150
- 在線時間
- 189 小時
- 註冊時間
- 2023-5-18
- 最後登入
- 2024-11-23
|
本帖最後由 whitefox 於 2023-10-14 01:29 編輯
<20231014-修正一些多餘字串造成的錯誤>
需先創一個類別 HardDiskInfo 命名空間 Hardware(看各人喜好)
程式碼如下- using System;
- using System.Runtime.InteropServices;
- using System.Text;
- namespace Hardware
- {
- [Serializable]
- public struct HardDiskInfo
- {
- /// <summary>
- /// 型號
- /// </summary>
- public string ModuleNumber;
- /// <summary>
- /// 韌體版本
- /// </summary>
- public string Firmware;
- /// <summary>
- /// 序號
- /// </summary>
- public string SerialNumber;
- /// <summary>
- /// 容量,以M為單位
- /// </summary>
- public uint Capacity;
- }
- #region Internal Structs
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- 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.
- }
- [StructLayout(LayoutKind.Sequential, Pack = 1)]
- 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, Pack = 1)]
- 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, Pack = 1)]
- 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, Pack = 1)]
- internal struct SendCmdOutParams
- {
- public uint cBufferSize;
- public DriverStatus DriverStatus;
- public IdSector bBuffer;
- }
- [StructLayout(LayoutKind.Sequential, Pack = 1, Size = 512)]
- 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.ByValArray, SizeConst = 20)]
- public byte[] sSerialNumber;
- public ushort wBufferType;
- public ushort wBufferSize;
- public ushort wECCSize;
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
- public byte[] sFirmwareRev;
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
- public byte[] 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;
- }
- #endregion
- /// <summary>
- /// ATAPI磁碟機相關
- /// </summary>
- public class AtapiDevice
- {
- #region DllImport
- [DllImport("kernel32.dll", SetLastError = true)]
- static extern int CloseHandle(IntPtr hObject);
- [DllImport("kernel32.dll", SetLastError = true)]
- static extern IntPtr CreateFile(string lpFileName,
- uint dwDesiredAccess,
- uint dwShareMode,
- IntPtr lpSecurityAttributes,
- uint dwCreationDisposition,
- uint dwFlagsAndAttributes,
- IntPtr hTemplateFile);
- [DllImport("kernel32.dll")]
- static extern int DeviceIoControl(IntPtr hDevice,
- uint dwIoControlCode,
- IntPtr lpInBuffer,
- uint nInBufferSize,
- ref GetVersionOutParams lpOutBuffer,
- uint nOutBufferSize,
- ref uint lpBytesReturned,
- [Out] IntPtr lpOverlapped);
- [DllImport("kernel32.dll")]
- static extern int DeviceIoControl(
- IntPtr hDevice,
- uint dwIoControlCode,
- ref SendCmdInParams lpInBuffer,
- uint nInBufferSize,
- ref SendCmdOutParams lpOutBuffer,
- uint nOutBufferSize,
- ref uint lpBytesReturned,
- [Out] IntPtr lpOverlapped);
- const uint DFP_GET_VERSION = 0x00074080;
- const uint DFP_SEND_DRIVE_COMMAND = 0x0007c084;
- const uint DFP_RECEIVE_DRIVE_DATA = 0x0007c088;
- const uint GENERIC_READ = 0x80000000;
- const uint GENERIC_WRITE = 0x40000000;
- const uint FILE_SHARE_READ = 0x00000001;
- const uint FILE_SHARE_WRITE = 0x00000002;
- const uint CREATE_NEW = 1;
- const uint OPEN_EXISTING = 3;
- #endregion
- #region GetHddInfo
- /// <summary>
- /// 獲得硬碟資訊
- /// </summary>
- /// <param name="driveIndex">硬碟序號</param>
- /// <returns>硬碟資訊</returns>
- /// <remarks>
- /// 在windows 98/ME中,S.M.A.R.T並不預設安裝,請將SMARTVSD.VXD拷貝到%SYSTEM%\iOSUBSYS目錄下。
- /// 在Windows 2000/2003下,需要Administrators組的許可權。
- /// </remarks>
- /// <example>
- /// AtapiDevice.GetHddInfo()
- /// </example>
- public static HardDiskInfo GetHddInfo(byte driveIndex)
- {
- switch (Environment.OSVersion.Platform)
- {
- case PlatformID.Win32Windows:
- return GetHddInfo9x(driveIndex);
- case PlatformID.Win32NT:
- return GetHddInfoNT(driveIndex);
- case PlatformID.Win32S:
- throw new NotSupportedException("Win32s is not supported.");
- case PlatformID.WinCE:
- throw new NotSupportedException("WinCE is not supported.");
- default:
- throw new NotSupportedException("Unknown Platform.");
- }
- }
- #region GetHddInfo9x
- private static HardDiskInfo GetHddInfo9x(byte driveIndex)
- {
- GetVersionOutParams vers = new GetVersionOutParams();
- SendCmdInParams inParam = new SendCmdInParams();
- SendCmdOutParams outParam = new SendCmdOutParams();
- uint bytesReturned = 0;
- IntPtr hDevice = CreateFile(@"\\.\Smartvsd",
- 0,
- 0,
- IntPtr.Zero,
- CREATE_NEW,
- 0,
- IntPtr.Zero);
- if (hDevice == IntPtr.Zero)
- {
- throw new Exception("Open smartvsd.vxd failed.");
- }
- if (0 == DeviceIoControl(hDevice,
- DFP_GET_VERSION,
- IntPtr.Zero,
- 0,
- ref vers,
- (uint)Marshal.SizeOf(vers),
- ref bytesReturned,
- IntPtr.Zero))
- {
- CloseHandle(hDevice);
- throw new Exception("DeviceIoControl failed:DFP_GET_VERSION");
- }
- // If IDE identify command not supported, fails
- if (0 == (vers.fCapabilities & 1))
- {
- CloseHandle(hDevice);
- throw new Exception("Error: IDE identify command not supported.");
- }
- if (0 != (driveIndex & 1))
- {
- inParam.irDriveRegs.bDriveHeadReg = 0xb0;
- }
- else
- {
- inParam.irDriveRegs.bDriveHeadReg = 0xa0;
- }
- if (0 != (vers.fCapabilities & (16 >> driveIndex)))
- {
- // We don't detect a ATAPI device.
- CloseHandle(hDevice);
- throw new Exception(string.Format("Drive {0} is a ATAPI device, we don't detect it", driveIndex + 1));
- }
- else
- {
- inParam.irDriveRegs.bCommandReg = 0xec;
- }
- inParam.bDriveNumber = driveIndex;
- inParam.irDriveRegs.bSectorCountReg = 1;
- inParam.irDriveRegs.bSectorNumberReg = 1;
- inParam.cBufferSize = 512;
- if (0 == DeviceIoControl(hDevice,
- DFP_RECEIVE_DRIVE_DATA,
- ref inParam,
- (uint)Marshal.SizeOf(inParam),
- ref outParam,
- (uint)Marshal.SizeOf(outParam),
- ref bytesReturned,
- IntPtr.Zero))
- {
- CloseHandle(hDevice);
- throw new Exception("DeviceIoControl failed: DFP_RECEIVE_DRIVE_DATA");
- }
- CloseHandle(hDevice);
- return GetHardDiskInfo(outParam.bBuffer);
- }
- #endregion
- #region GetHddInfoNT
- private static HardDiskInfo GetHddInfoNT(byte driveIndex)
- {
- GetVersionOutParams vers = new GetVersionOutParams();
- SendCmdInParams inParam = new SendCmdInParams();
- SendCmdOutParams outParam = new SendCmdOutParams();
- uint bytesReturned = 0;
- // We start in NT/Win2000
- IntPtr hDevice = CreateFile(string.Format(@"\\.\PhysicalDrive{0}", driveIndex),
- GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- IntPtr.Zero,
- OPEN_EXISTING,
- 0,
- IntPtr.Zero);
- if (hDevice == IntPtr.Zero)
- {
- throw new Exception("CreateFile faild.");
- }
- if (0 == DeviceIoControl(hDevice,
- DFP_GET_VERSION,
- IntPtr.Zero,
- 0,
- ref vers,
- (uint)Marshal.SizeOf(vers),
- ref bytesReturned,
- IntPtr.Zero))
- {
- CloseHandle(hDevice);
- throw new Exception(string.Format("Drive {0} may not exists.", driveIndex + 1));
- }
- // If IDE identify command not supported, fails
- if (0 == (vers.fCapabilities & 1))
- {
- CloseHandle(hDevice);
- throw new Exception("Error: IDE identify command not supported.");
- }
- // Identify the IDE drives
- if (0 != (driveIndex & 1))
- {
- inParam.irDriveRegs.bDriveHeadReg = 0xb0;
- }
- else
- {
- inParam.irDriveRegs.bDriveHeadReg = 0xa0;
- }
- if (0 != (vers.fCapabilities & (16 >> driveIndex)))
- {
- // We don't detect a ATAPI device.
- CloseHandle(hDevice);
- throw new Exception(string.Format("Drive {0} is a ATAPI device, we don't detect it.", driveIndex + 1));
- }
- else
- {
- inParam.irDriveRegs.bCommandReg = 0xec;
- }
- inParam.bDriveNumber = driveIndex;
- inParam.irDriveRegs.bSectorCountReg = 1;
- inParam.irDriveRegs.bSectorNumberReg = 1;
- inParam.cBufferSize = 512;
- if (0 == DeviceIoControl(hDevice,
- DFP_RECEIVE_DRIVE_DATA,
- ref inParam,
- (uint)Marshal.SizeOf(inParam),
- ref outParam,
- (uint)Marshal.SizeOf(outParam),
- ref bytesReturned,
- IntPtr.Zero))
- {
- CloseHandle(hDevice);
- throw new Exception("DeviceIoControl failed: DFP_RECEIVE_DRIVE_DATA");
- }
- CloseHandle(hDevice);
- return GetHardDiskInfo(outParam.bBuffer);
- }
- #endregion
- private static HardDiskInfo GetHardDiskInfo(IdSector phdinfo)
- {
- HardDiskInfo hddInfo = new HardDiskInfo();
- ChangeByteOrder(phdinfo.sModelNumber);
- hddInfo.ModuleNumber = Encoding.ASCII.GetString(phdinfo.sModelNumber).Trim();
- ChangeByteOrder(phdinfo.sFirmwareRev);
- hddInfo.Firmware = Encoding.ASCII.GetString(phdinfo.sFirmwareRev).Trim();
- ChangeByteOrder(phdinfo.sSerialNumber);
- hddInfo.SerialNumber = Encoding.ASCII.GetString(phdinfo.sSerialNumber).Trim();
- hddInfo.Capacity = phdinfo.ulTotalAddressableSectors / 2 / 1024;
- return hddInfo;
- }
- private static void ChangeByteOrder(byte[] charArray)
- {
- byte temp;
- for (int i = 0; i < charArray.Length; i += 2)
- {
- temp = charArray[i];
- charArray[i] = charArray[i + 1];
- charArray[i + 1] = temp;
- }
- }
- #endregion
- }
- }
複製代碼 調用方式:- HardDiskInfo hdd = AtapiDevice.GetHddInfo(0); // 第一個硬碟
- Console.WriteLine("Module Number: {0}", hdd.ModuleNumber);
- Console.WriteLine("Serial Number: {0}", hdd.SerialNumber);
- Console.WriteLine("Firmware: {0}", hdd.Firmware);
- Console.WriteLine("Capacity: {0} M", hdd.Capacity);
複製代碼 |
|