获取本地硬盘信息

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

namespace driverId
{
    [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;
    }

    internal enum STORAGE_PROPERTY_ID
    {
        StorageDeviceProperty = 0,
        StorageAdapterProperty,
        StorageDeviceIdProperty,
        StorageDeviceUniqueIdProperty,
        StorageDeviceWriteCacheProperty,
        StorageMiniportProperty,
        StorageAccessAlignmentProperty
    }
    internal enum STORAGE_QUERY_TYPE
    {
        PropertyStandardQuery = 0,          // Retrieves the descriptor
        PropertyExistsQuery,                // Used to test whether the descriptor is supported
        PropertyMaskQuery,                  // Used to retrieve a mask of writeable fields in the descriptor
        PropertyQueryMaxDefined     // use to validate the value
    }
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    internal struct STORAGE_PROPERTY_QUERY
    {
        public STORAGE_PROPERTY_ID PropertyId;
        public STORAGE_QUERY_TYPE QueryType;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
        public byte[] AdditionalParameters;
    }


    internal enum STORAGE_BUS_TYPE
    {
        BusTypeUnknown = 0x00,
        BusTypeScsi,
        BusTypeAtapi,
        BusTypeAta,
        BusType1394,
        BusTypeSsa,
        BusTypeFibre,
        BusTypeUsb,
        BusTypeRAID,
        BusTypeiScsi,
        BusTypeSas,
        BusTypeSata,
        BusTypeSd,
        BusTypeMmc,
        BusTypeMax,
        BusTypeMaxReserved = 0x7F
    }
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    internal struct STORAGE_DEVICE_DESCRIPTOR
    {
        public UInt32 Version;
        public UInt32 Size;
        public byte DeviceType;
        public byte DeviceTypeModifier;
        public byte RemovableMedia;
        public byte CommandQueueing;
        public UInt32 VendorIdOffset;
        public UInt32 ProductIdOffset;
        public UInt32 ProductRevisionOffset;
        public UInt32 SerialNumberOffset;
        public STORAGE_BUS_TYPE BusType;
        public UInt32 RawPropertiesLength;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
        public byte[] RawDeviceProperties;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1000)]
        public byte[] buffer;
    }

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    internal struct SRB_IO_CONTROL
    {
        public UInt32 HeaderLength;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
        public byte[] Signature;
        public UInt32 Timeout;
        public UInt32 ControlCode;
        public UInt32 ReturnCode;
        public UInt32 Length;

        public SendCmdInParams pin;
    }

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    internal struct OUT_BUFFER
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x1c)]
        public byte[] sic;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x10)]
        public byte[] pout;
        public IdSector ids;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
        public byte[] buffer;
    }
    #endregion

    /// <summary>
    /// ATAPI驱动器相关
    /// </summary>
    public class DeviceID
    {
        #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);

        [DllImport("kernel32.dll")]
        static extern int DeviceIoControl(IntPtr hDevice, uint dwIoControlCode, ref STORAGE_PROPERTY_QUERY lpInBuffer, uint nInBufferSize, ref STORAGE_DEVICE_DESCRIPTOR lpOutBuffer, uint nOutBufferSize, ref uint lpBytesReturned, [Out] IntPtr lpOverlapped);

        [DllImport("kernel32.dll")]
        static extern int DeviceIoControl(IntPtr hDevice, uint dwIoControlCode, ref SRB_IO_CONTROL lpInBuffer, uint nInBufferSize, ref OUT_BUFFER 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 SMART_GET_VERSION = 0x00074080;
        const uint SMART_RCV_DRIVE_DATA = 0x0007c088;

        const uint IOCTL_STORAGE_QUERY_PROPERTY = 0x002d1400;
        const uint IOCTL_SCSI_MINIPORT_IDENTIFY=0x1b0501;
        const uint IOCTL_SCSI_MINIPORT = 0x0004D008;
        const byte IDE_ATA_IDENTIFY = 0xec;

        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;

        const byte ID_CMD = 0xec;

        #endregion

        #region GetHddInfo

        public static string GetHddInfo(byte driveIndex)
        {
            switch (Environment.OSVersion.Platform)
            {
                case PlatformID.Win32Windows:
                    throw new NotSupportedException("Win32s is not supported.");
                case PlatformID.Win32NT:
                    return GetHddInfoAsScsiDriveInNT(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 GetHddInfoNT

        //ReadPhysicalDriveInNTWithAdminRights (void)
        public static string GetHddInfoNTWithAdminRights(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)
                return "";

            if (DeviceIoControl(hDevice, DFP_GET_VERSION, IntPtr.Zero, 0, ref vers, (uint)Marshal.SizeOf(vers), ref bytesReturned, IntPtr.Zero) == 0)
            {
                CloseHandle(hDevice);
                return "";
            }
            // If IDE identify command not supported, fails
            if ((vers.fCapabilities & 1) == 0)
            {
                CloseHandle(hDevice);
                return "";
            }
            // Identify the IDE drives
            if ((driveIndex & 1) != 0)
            {
                inParam.irDriveRegs.bDriveHeadReg = 0xb0;
            }
            else
            {
                inParam.irDriveRegs.bDriveHeadReg = 0xa0;
            }
            if ((vers.fCapabilities & (16 >> driveIndex)) != 0)
            {
                // We don''t detect a ATAPI device.
                CloseHandle(hDevice);
                return "";
            }
            else
            {
                inParam.irDriveRegs.bCommandReg = 0xec;
            }
            inParam.bDriveNumber = driveIndex;
            inParam.irDriveRegs.bSectorCountReg = 1;
            inParam.irDriveRegs.bSectorNumberReg = 1;
            inParam.cBufferSize = 512;

            if (DeviceIoControl(hDevice, DFP_RECEIVE_DRIVE_DATA, ref inParam, (uint)Marshal.SizeOf(inParam), ref outParam, (uint)Marshal.SizeOf(outParam), ref bytesReturned, IntPtr.Zero) == 0)
            {
                CloseHandle(hDevice);
                return "";
            }
            CloseHandle(hDevice);

            return GetHardDiskInfo(outParam.bBuffer).SerialNumber;
        }
        //ReadPhysicalDriveInNTUsingSmart
        public static string GetHddInfoNTUsingSmart(byte driveIndex)
        {
            GetVersionOutParams vers = new GetVersionOutParams();
            SendCmdInParams inParam = new SendCmdInParams();
            SendCmdOutParams outParam = new SendCmdOutParams();
            uint bytesReturned = 0;

            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)
                return "";

            if (DeviceIoControl(hDevice, SMART_GET_VERSION, IntPtr.Zero, 0, ref vers, (uint)Marshal.SizeOf(vers), ref bytesReturned, IntPtr.Zero) == 0)
            {
                CloseHandle(hDevice);
                return "";
            }

            inParam.irDriveRegs.bCommandReg = ID_CMD;
            if (DeviceIoControl(hDevice, SMART_RCV_DRIVE_DATA, ref inParam, (uint)Marshal.SizeOf(inParam), ref outParam, (uint)Marshal.SizeOf(outParam), ref bytesReturned, IntPtr.Zero) == 0)
                return "";

            CloseHandle(hDevice);

            return GetHardDiskInfo(outParam.bBuffer).SerialNumber;
        }
        //ReadPhysicalDriveInNTWithZeroRights
        public static string GetHddInfoNTWithZeroRights(byte driveIndex)
        {
            IntPtr hDevice = CreateFile(string.Format(@"\\.\PhysicalDrive{0}", driveIndex), 0, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
            if (hDevice == IntPtr.Zero)
                return "";

            STORAGE_PROPERTY_QUERY query=new STORAGE_PROPERTY_QUERY();
            query.PropertyId = STORAGE_PROPERTY_ID.StorageDeviceProperty;
            query.QueryType = STORAGE_QUERY_TYPE.PropertyStandardQuery;

            uint bytesReturned = 0;
            STORAGE_DEVICE_DESCRIPTOR descrip=new STORAGE_DEVICE_DESCRIPTOR();
            if (DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY, ref query, (uint)Marshal.SizeOf(query), ref descrip, (uint)Marshal.SizeOf(descrip), ref bytesReturned, IntPtr.Zero) == 0)
            {
                CloseHandle(hDevice);
                return "";
            }
            CloseHandle(hDevice);

            uint offset = descrip.SerialNumberOffset - 0x25;
            int len=0;
            for(int i=0;i<descrip.buffer.Length;i++)
            {
                if(descrip.buffer[offset+i]==0)
                    break;
                len++;
            }
            byte[] temp=new byte[len];
            for (int i = 0; i < len; i++)
            {
                temp[i] = descrip.buffer[offset + i];
            }

            System.Text.ASCIIEncoding converter = new System.Text.ASCIIEncoding();
            string aa = converter.GetString(temp);
            byte[] mc = new byte[aa.Length/2];
            for (int i = 0; i < aa.Length / 2; i++)
                mc[i] = Convert.ToByte(aa.Substring(i * 2, 2), 16);

            ChangeByteOrder(mc);

            string id = converter.GetString(mc);

            id.Replace(" ", "");

            return id;
        }
        //ReadIdeDriveAsScsiDriveInNT
        public static string GetHddInfoAsScsiDriveInNT(byte driveIndex)
        {
            IntPtr hDevice = CreateFile(string.Format(@"\\.\Scsi{0}:", driveIndex), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
            if (hDevice == IntPtr.Zero)
                return "";

          
            SRB_IO_CONTROL sic = new SRB_IO_CONTROL();
            sic.HeaderLength =0x1c;
            sic.Timeout = 10000;
            sic.Length = 0x211;
            sic.ControlCode = IOCTL_SCSI_MINIPORT_IDENTIFY;
            sic.Signature = new byte[8];
            sic.Signature[0]=(byte)'S';
            sic.Signature[1] = (byte)'C';
            sic.Signature[2] = (byte)'S';
            sic.Signature[3] = (byte)'I';
            sic.Signature[4] = (byte)'D';
            sic.Signature[5] = (byte)'I';
            sic.Signature[6] = (byte)'S';
            sic.Signature[7] = (byte)'K';

            sic.pin.irDriveRegs.bCommandReg = IDE_ATA_IDENTIFY;
            sic.pin.bDriveNumber = driveIndex;

            OUT_BUFFER ob = new OUT_BUFFER();

            uint bytesReturned = 0;
            if (DeviceIoControl(hDevice, IOCTL_SCSI_MINIPORT,ref sic, 0x3c, ref ob, (uint)Marshal.SizeOf(ob), ref bytesReturned, IntPtr.Zero) == 0)
            {
                CloseHandle(hDevice);
                return "";
            }

            IntPtr pnt = Marshal.AllocHGlobal(1000);
           

            CloseHandle(hDevice);

            return (GetHardDiskInfo(ob.ids)).SerialNumber;
        }


        #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
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
现在USB设备却很多,因此对USB设备的查找与读写就必不可少了。但是能找到关于USB读写的资料很少。这里使用VC++示范了一些获得USB的信息的方法。 一、枚举USB设备   通过枚举USB控制器->枚举此控制器上的USB HUB->枚举HUB的各个端口->获得设备信息。 枚举控制器: wsprintf(HCName, "\\\\.\\HCD%d", HCNum); hHCDev = CreateFile(HCName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);   计算机上的USB主控制器以HCD1,HCD2等命名。通过控制器名称,使用CCreateFile 打开它。使用DeviceIoControl即可得到其驱动程序名,以及与它连接的HUB的名称。用CCreateFile打开HUB,获得连接信息。再枚举HUB的各个端口即可获得连接的设备信息。 二、枚举HID设备   HID设备是微软定义的标准人机接口规范。比如USB鼠标,USB游戏手柄等。不用查找具体设备的GUID,使用API HidD_GetHidGuid(&guidHID)即可得到GUID。有了GUID通过API SetupDiEnumDeviceInterfaces可获得是否有设备连接。如果此类设备连接通过SetupDiGetDeviceInterfaceDetail获得它的设备路径信息。使用CCreateFile 打开它,通过HidD_GetAttributes获得其基本属性信息。使用DeviceIoControl可以获得更详细的属性。在本代码中如果计算机上插有USB游戏手柄,可获得其信息。但不知道为什么xp下却不能获得USB鼠标的信息。 三 枚举U盘   先用GetDriveType API获得设备的类型,若类型为REMOVABLE(当然有些大容量U盘可能报告为FIXED,那就需要其他方法来确定了),即可能是U盘。用CCreateFile 打开之后,再用IOCTL_STORAGE_QUERY_PROPERTY为参数的DeviceIoControl来获得其属性。 四、结束语   示例工程在winxp+xpDDK+VC6下编译通过。USB设备种类比较多,也比较特殊,不同厂商的硬件不同,控制软件也不尽相同(我想主要是ICTL码不同,也不容易查到)。使得访问USB口的设备不象串口并口那么方便。这个例程只是展示了访问的基本方法。其中还有些问题还没有解决,发出来希望大家解决之后能通知我或者发表出来。 参考了USBPort,USBview等代码,一并致谢。
获取本地电脑设备信息需要使用系统相关的API,具体实现方法会因操作系统不同而有所区别。以下是一些常见操作系统的示例代码: Windows: ```python import wmi # 初始化WMI对象 w = wmi.WMI() # 获取CPU信息 for cpu in w.Win32_Processor(): print(cpu.Name) # 获取内存信息 for mem in w.Win32_PhysicalMemory(): print(mem.Capacity) # 获取硬盘信息 for disk in w.Win32_DiskDrive(): print(disk.Caption) # 获取显卡信息 for gpu in w.Win32_VideoController(): print(gpu.Description) ``` Linux: ```python import subprocess # 获取CPU信息 cmd = "lscpu | grep 'Model name'" result = subprocess.check_output(cmd, shell=True).decode().strip() print(result) # 获取内存信息 cmd = "grep MemTotal /proc/meminfo" result = subprocess.check_output(cmd, shell=True).decode().strip() print(result) # 获取硬盘信息 cmd = "lsblk -o NAME,SIZE,MODEL | grep disk" result = subprocess.check_output(cmd, shell=True).decode().strip() print(result) # 获取显卡信息 cmd = "lspci | grep 'VGA compatible controller'" result = subprocess.check_output(cmd, shell=True).decode().strip() print(result) ``` macOS: ```python import subprocess # 获取CPU信息 cmd = "sysctl -n machdep.cpu.brand_string" result = subprocess.check_output(cmd, shell=True).decode().strip() print(result) # 获取内存信息 cmd = "sysctl hw.memsize" result = subprocess.check_output(cmd, shell=True).decode().strip() print(result) # 获取硬盘信息 cmd = "diskutil list | grep '128' | awk '{print $4}'" result = subprocess.check_output(cmd, shell=True).decode().strip() print(result) # 获取显卡信息 cmd = "system_profiler SPDisplaysDataType | grep Chipset | awk '{print $3,$4}'" result = subprocess.check_output(cmd, shell=True).decode().strip() print(result) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值