static extern int DeviceIoControl( IntPtr hDevice, uint dwIoControlCode, ref SendCmdInParams lpInBuffer, uint nInBufferSize, ref SendCmdOutParams lpOutBuffer, uint nOutBufferSize, ref uint lpBytesReturned, [Out] IntPtr lpOverlapped);
/** * /// <summary> * /// 获得硬盘信息 * /// </summary> * /// <param name="driveIndex">硬盘序号</param> * /// <returns>硬盘信息</returns> * /// <remarks> * /// 参考lu0的文章:http://lu0s1.3322.org/App/2k1103.html * /// by sunmast for everyone * /// thanks lu0 for his great works * /// 在Windows 98/ME中,S.M.A.R.T并不缺省安装,请将SMARTVSD.VXD拷贝到%SYSTEM%\IOSUBSYS目录下。 * /// 在Windows 2000/2003下,需要Administrators组的权限。 * /// </remarks> * /// <example> * /// AtapiDevice.GetHddInfo() * /// </example> * public static HardDiskInfo get(byte driveIndex) * { * HardDiskInfo hardDiskInfo = new HardDiskInfo(); * * try * { * switch (Environment.OSVersion.Platform) * { * case PlatformID.Win32Windows: * hardDiskInfo = GetHddInfo9x(driveIndex); * break; * case PlatformID.Win32NT: * hardDiskInfo = GetHddInfoNT(driveIndex); * break; * case PlatformID.Win32S: * throw new NotSupportedException("此应用程序不支持Win32s类型平台系统."); * case PlatformID.WinCE: * throw new NotSupportedException("此应用程序不支持WinCE类型平台系统."); * default: * throw new NotSupportedException("未知的平台系统."); * } * } * catch (Exception ex) * { * logger.Error(ex.Message, ex); * } * * return hardDiskInfo; * } * * #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; * } */ public static HardDiskInfo getDiskInfo(byte driveIndex) { HardDiskInfo hddInfo = new HardDiskInfo(); IntPtr hDevice = IntPtr.Zero; try { switch (Environment.OSVersion.Platform) { case PlatformID.Win32Windows: hDevice = CreateFile(@"\\.\Smartvsd", 0, 0, IntPtr.Zero, CREATE_NEW, 0, IntPtr.Zero); break; case PlatformID.Win32NT: hDevice = CreateFile(string.Format(@"\\.\PhysicalDrive{0}", driveIndex), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero); break; case PlatformID.Win32S: throw new NotSupportedException("此应用程序不支持Win32s类型平台系统."); case PlatformID.WinCE: throw new NotSupportedException("此应用程序不支持WinCE类型平台系统."); default: throw new NotSupportedException("未知的平台系统."); } GetVersionOutParams vers = new GetVersionOutParams(); SendCmdInParams inParam = new SendCmdInParams(); SendCmdOutParams outParam = new SendCmdOutParams(); uint bytesReturned = 0; if (hDevice == IntPtr.Zero) { throw new Exception("读取存储信息失败"); } if (0 == DeviceIoControl(hDevice, DFP_GET_VERSION, IntPtr.Zero, 0, ref vers, (uint)Marshal.SizeOf(vers), ref bytesReturned, IntPtr.Zero)) { throw new Exception(string.Format("存储{0}不存在.", driveIndex + 1)); } if (0 == (vers.fCapabilities & 1)) { throw new Exception("异常:存储取得语句失效."); } if (0 != (driveIndex & 1)) { inParam.irDriveRegs.bDriveHeadReg = 0xb0; } else { inParam.irDriveRegs.bDriveHeadReg = 0xa0; } if (0 != (vers.fCapabilities & (16 >> driveIndex))) { throw new Exception(string.Format("磁盘 {0} 为ATAPI设备,无法取得信息!.", 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)) { throw new Exception("异常: DFP_RECEIVE_DRIVE_DATA"); } IdSector phdinfo = outParam.bBuffer; 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; } catch (Exception ex) { logger.Error(ex.Message, ex); } finally { CloseHandle(hDevice); } return(hddInfo); }