/// <summary>
 ///
 /// </summary>
 /// <param name="driveIndex"></param>
 /// <returns></returns>
 private static TmphHDiskInfo GetHddInfo9X(byte driveIndex)
 {
     TmphGetVersionOutParams vers = new TmphGetVersionOutParams();
     TmphSendCmdInParams inParam = new TmphSendCmdInParams();
     TmphSendCmdOutParams outParam = new TmphSendCmdOutParams();
     uint bytesReturned = 0;
     IntPtr hDevice = CreateFile(@"\\.\Smartvsd", 0, 0, IntPtr.Zero, CREATE_NEW, 0, IntPtr.Zero);
     if (hDevice == IntPtr.Zero)
         throw new UnauthorizedAccessException("打开 smartvsd.vxd 文件失败。");
     if (0 == DeviceIoControl(hDevice, SMART_GET_VERSION,
         IntPtr.Zero, 0,
         ref vers, (uint)Marshal.SizeOf(vers), ref bytesReturned, IntPtr.Zero))
     {
         CloseHandle(hDevice);
         throw new IOException(string.Format(TmphResourcesApi.Win32_DeviceIoControlErr, "SMART_GET_VERSION"));
     }
     // 如果 IDE 的鉴定命令不被识别或失败
     if (0 == (vers.fCapabilities & 1))
     {
         CloseHandle(hDevice);
         throw new IOException(TmphResourcesApi.Win32_DeviceIoControlNotSupport);
     }
     if (0 != (driveIndex & 1))
         inParam.irDriveRegs.bDriveHeadReg = 0xb0;
     else
         inParam.irDriveRegs.bDriveHeadReg = 0xa0;
     if (0 != (vers.fCapabilities & (16 >> driveIndex)))
     {
         // 检测出IDE为ATAPI类型,无法处理
         CloseHandle(hDevice);
         throw new IOException(TmphResourcesApi.Win32_DeviceIoControlNotSupport);
     }
     else
         inParam.irDriveRegs.bCommandReg = 0xec;
     inParam.bDriveNumber = driveIndex;
     inParam.irDriveRegs.bSectorCountReg = 1;
     inParam.irDriveRegs.bSectorNumberReg = 1;
     inParam.cBufferSize = BUFFER_SIZE;
     if (0 == DeviceIoControl(hDevice, SMART_RCV_DRIVE_DATA, ref inParam, (uint)Marshal.SizeOf(inParam), ref outParam, (uint)Marshal.SizeOf(outParam), ref bytesReturned, IntPtr.Zero))
     {
         CloseHandle(hDevice);
         throw new IOException(string.Format(TmphResourcesApi.Win32_DeviceIoControlErr, "SMART_RCV_DRIVE_DATA"));
     }
     // 关闭文件句柄
     CloseHandle(hDevice);
     ChangeByteOrder(outParam.bBuffer.sModelNumber);
     ChangeByteOrder(outParam.bBuffer.sSerialNumber);
     ChangeByteOrder(outParam.bBuffer.sFirmwareRev);
     return GetHardDiskInfo(outParam.bBuffer);
 }
 private static extern int DeviceIoControl(IntPtr hDevice, uint dwIoControlCode, IntPtr lpInBuffer,
                                           uint nInBufferSize, ref TmphGetVersionOutParams lpOutBuffer,
                                           uint nOutBufferSize, ref uint lpBytesReturned,
                                           [Out] IntPtr lpOverlapped);
        /// <summary>
        /// 获取在NT平台下指定序列号的硬盘信息。
        /// </summary>
        /// <param name="driveIndex">物理磁盘的数量。</param>
        /// <returns></returns>
        private static TmphHDiskInfo GetHddInfoNT(byte driveIndex)
        {
            TmphGetVersionOutParams vers = new TmphGetVersionOutParams();
            TmphSendCmdInParams inParam = new TmphSendCmdInParams();
            TmphSendCmdOutParams outParam = new TmphSendCmdOutParams();
            uint bytesReturned = 0;

            // 使用 Win2000 或 Xp下的方法获取硬件信息

            // 获取设备的句柄。
            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 UnauthorizedAccessException("执行 Win32 API 函数 CreateFile 失败。");
            if (0 == DeviceIoControl(hDevice, SMART_GET_VERSION, IntPtr.Zero, 0, ref vers,
                (uint)Marshal.SizeOf(vers),
                ref bytesReturned,
                IntPtr.Zero))
            {
                CloseHandle(hDevice);
                throw new IOException(string.Format(TmphResourcesApi.Win32_DeviceIoControlErr, "SMART_GET_VERSION"));
            }
            // 检测IDE控制命令是否支持
            if (0 == (vers.fCapabilities & 1))
            {
                CloseHandle(hDevice);
                throw new IOException(TmphResourcesApi.Win32_DeviceIoControlNotSupport);
            }
            // 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 IOException(TmphResourcesApi.Win32_DeviceIoControlNotSupport);
            }
            else
                inParam.irDriveRegs.bCommandReg = 0xec;
            inParam.bDriveNumber = driveIndex;
            inParam.irDriveRegs.bSectorCountReg = 1;
            inParam.irDriveRegs.bSectorNumberReg = 1;
            inParam.cBufferSize = 512;

            if (0 == DeviceIoControl(
                hDevice,
                SMART_RCV_DRIVE_DATA,
                ref inParam,
                (uint)Marshal.SizeOf(inParam),
                ref outParam,
                (uint)Marshal.SizeOf(outParam),
                ref bytesReturned,
                IntPtr.Zero))
            {
                CloseHandle(hDevice);
                throw new IOException(
                        string.Format(TmphResourcesApi.Win32_DeviceIoControlErr, "SMART_RCV_DRIVE_DATA"));
            }
            CloseHandle(hDevice);
            ChangeByteOrder(outParam.bBuffer.sModelNumber);
            ChangeByteOrder(outParam.bBuffer.sSerialNumber);
            ChangeByteOrder(outParam.bBuffer.sFirmwareRev);
            return GetHardDiskInfo(outParam.bBuffer);
        }