首页
社区
课程
招聘
怎样获取ssd和scsi硬盘的物理序列号
发表于: 2010-1-30 16:22 17817

怎样获取ssd和scsi硬盘的物理序列号

2010-1-30 16:22
17817
收藏
免费 0
支持
分享
最新回复 (22)
雪    币: 30
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
使用C#获取CPU及硬盘序列号的源代码

  
首先需添加对System.Management的引用。

using System;
using System.Runtime.InteropServices;
using System.Management;

namespace Hardware
{
    /// ry>
    /// HardwareInfo 的摘要说明。
    /// ary>
    public class HardwareInfo
    {
        //取机器名  
        public string GetHostName()
        {
            return System.Net.Dns.GetHostName();
        }
        //取CPU编号
        public String GetCpuID()
        {
            try
            {
                ManagementClass mc = new ManagementClass("Win32_Processor");
                ManagementObjectCollection moc = mc.GetInstances();

                String strCpuID = null;
                foreach (ManagementObject mo in moc)
                {
                    strCpuID = mo.Properties["ProcessorId"].Value.ToString();
                    break;
                }
                return strCpuID;
            }
            catch
            {
                return "";
            }

        }//end method

        //取第一块硬盘编号
        public String GetHardDiskID()
        {
            try
            {
                ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMedia");
                String strHardDiskID = null;
                foreach (ManagementObject mo in searcher.Get())
                {
                    strHardDiskID = mo["SerialNumber"].ToString().Trim();
                    break;
                }
                return strHardDiskID;
            }
            catch
            {
                return "";
            }
        }//end  

        public enum NCBCONST
        {
            NCBNAMSZ = 16,      /* absolute length of a net name         */
            MAX_LANA = 254,      /* lana's in range 0 to MAX_LANA inclusive   */
            NCBENUM = 0x37,      /* NCB ENUMERATE LANA NUMBERS            */
            NRC_GOODRET = 0x00,      /* good return                              */
            NCBRESET = 0x32,      /* NCB RESET                        */
            NCBASTAT = 0x33,      /* NCB ADAPTER STATUS                  */
            NUM_NAMEBUF = 30,      /* Number of NAME's BUFFER               */
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct ADAPTER_STATUS
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
            public byte[] adapter_address;
            public byte rev_major;
            public byte reserved0;
            public byte adapter_type;
            public byte rev_minor;
            public ushort duration;
            public ushort frmr_recv;
            public ushort frmr_xmit;
            public ushort iframe_recv_err;
            public ushort xmit_aborts;
            public uint xmit_success;
            public uint recv_success;
            public ushort iframe_xmit_err;
            public ushort recv_buff_unavail;
            public ushort t1_timeouts;
            public ushort ti_timeouts;
            public uint reserved1;
            public ushort free_ncbs;
            public ushort max_cfg_ncbs;
            public ushort max_ncbs;
            public ushort xmit_buf_unavail;
            public ushort max_dgram_size;
            public ushort pending_sess;
            public ushort max_cfg_sess;
            public ushort max_sess;
            public ushort max_sess_pkt_size;
            public ushort name_count;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct NAME_BUFFER
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NCBCONST.NCBNAMSZ)]
            public byte[] name;
            public byte name_num;
            public byte name_flags;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct NCB
        {
            public byte ncb_command;
            public byte ncb_retcode;
            public byte ncb_lsn;
            public byte ncb_num;
            public IntPtr ncb_buffer;
            public ushort ncb_length;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NCBCONST.NCBNAMSZ)]
            public byte[] ncb_callname;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NCBCONST.NCBNAMSZ)]
            public byte[] ncb_name;
            public byte ncb_rto;
            public byte ncb_sto;
            public IntPtr ncb_post;
            public byte ncb_lana_num;
            public byte ncb_cmd_cplt;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
            public byte[] ncb_reserve;
            public IntPtr ncb_event;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct LANA_ENUM
        {
            public byte length;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NCBCONST.MAX_LANA)]
            public byte[] lana;
        }

        [StructLayout(LayoutKind.Auto)]
        public struct ASTAT
        {
            public ADAPTER_STATUS adapt;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NCBCONST.NUM_NAMEBUF)]
            public NAME_BUFFER[] NameBuff;
        }
        public class Win32API
        {
            [DllImport("NETAPI32.DLL")]
            public static extern char Netbios(ref NCB ncb);
        }

        public string GetMacAddress()
        {
            string addr = "";
            try
            {
                int cb;
                ASTAT adapter;
                NCB Ncb = new NCB();
                char uRetCode;
                LANA_ENUM lenum;

                Ncb.ncb_command = (byte)NCBCONST.NCBENUM;
                cb = Marshal.SizeOf(typeof(LANA_ENUM));
                Ncb.ncb_buffer = Marshal.AllocHGlobal(cb);
                Ncb.ncb_length = (ushort)cb;
                uRetCode = Win32API.Netbios(ref Ncb);
                lenum = (LANA_ENUM)Marshal.PtrToStructure(Ncb.ncb_buffer, typeof(LANA_ENUM));
                Marshal.FreeHGlobal(Ncb.ncb_buffer);
                if (uRetCode != (short)NCBCONST.NRC_GOODRET)
                    return "";

                for (int i = 0; i < lenum.length; i++)
                {
                    Ncb.ncb_command = (byte)NCBCONST.NCBRESET;
                    Ncb.ncb_lana_num = lenum.lana[i];
                    uRetCode = Win32API.Netbios(ref Ncb);
                    if (uRetCode != (short)NCBCONST.NRC_GOODRET)
                        return "";

                    Ncb.ncb_command = (byte)NCBCONST.NCBASTAT;
                    Ncb.ncb_lana_num = lenum.lana[i];
                    Ncb.ncb_callname[0] = (byte)'*';
                    cb = Marshal.SizeOf(typeof(ADAPTER_STATUS)) + Marshal.SizeOf(typeof(NAME_BUFFER)) * (int)NCBCONST.NUM_NAMEBUF;
                    Ncb.ncb_buffer = Marshal.AllocHGlobal(cb);
                    Ncb.ncb_length = (ushort)cb;
                    uRetCode = Win32API.Netbios(ref Ncb);
                    adapter.adapt = (ADAPTER_STATUS)Marshal.PtrToStructure(Ncb.ncb_buffer, typeof(ADAPTER_STATUS));
                    Marshal.FreeHGlobal(Ncb.ncb_buffer);

                    if (uRetCode == (short)NCBCONST.NRC_GOODRET)
                    {
                        if (i > 0)
                            addr += ":";
                        addr = string.Format("{0,2:X}{1,2:X}{2,2:X}{3,2:X}{4,2:X}{5,2:X}",
                         adapter.adapt.adapter_address[0],
                         adapter.adapt.adapter_address[1],
                         adapter.adapt.adapter_address[2],
                         adapter.adapt.adapter_address[3],
                         adapter.adapt.adapter_address[4],
                         adapter.adapt.adapter_address[5]);
                    }
                }
            }
            catch
            { }
            return addr.Replace(' ', '0');
        }
2010-1-30 21:03
0
雪    币: 3
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
获取序列号我早就知道啦,问题是如果ssd是pci-e接口的,或者硬盘是scsi接口的,这代码能用乎,我也没有这种机器来测试
2010-1-31 01:20
0
雪    币: 2096
活跃值: (100)
能力值: (RANK:420 )
在线值:
发帖
回帖
粉丝
4
我的筆記型電腦是 SSD 的,不是 SATA 也不是 SCSI 介面,我可以幫你測看看。
2010-1-31 13:03
0
雪    币: 3
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
太好啦,就是附件里的代码,用vc2008编译,里面release下面有个编译好的程序。
上传的附件:
2010-1-31 22:28
0
雪    币: 2096
活跃值: (100)
能力值: (RANK:420 )
在线值:
发帖
回帖
粉丝
6
就是 download naluload.zip 後,找 release 裡面的哪一個程序?
好吧,沒病毒的話,我就幫你 testing.
2010-2-1 08:30
0
雪    币: 131
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
要获取真正的硬件序列号才行
// WindowsNT/2000/XP系统下读取SCSI硬盘序列号
BOOL WinNTReadSCSIHDSerial (DWORD * buffer)
{       
      buffer[0]='\n';
      int controller = 0;
      HANDLE hScsiDriveIOCTL = 0;
      char   driveName [256];
      sprintf (driveName, "\\\\.\\Scsi%d:", controller);
     //  Windows NT/2000/XP下任何权限都可以进行
      hScsiDriveIOCTL = CreateFile (driveName,
                               GENERIC_READ | GENERIC_WRITE,
                               FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
                               OPEN_EXISTING, 0, NULL);

      if (hScsiDriveIOCTL != INVALID_HANDLE_VALUE)
      {
         int drive = 0;
         DWORD dummy;
         for (drive = 0; drive < 2; drive++)
         {
            char buffer [sizeof (SRB_IO_CONTROL) + SENDIDLENGTH];
            SRB_IO_CONTROL *p = (SRB_IO_CONTROL *) buffer;
            SENDCMDINPARAMS *pin =
                   (SENDCMDINPARAMS *) (buffer + sizeof (SRB_IO_CONTROL));           
            // 准备参数
            memset (buffer, 0, sizeof (buffer));
            p -> HeaderLength = sizeof (SRB_IO_CONTROL);
            p -> Timeout = 10000;
            p -> Length = SENDIDLENGTH;
            p -> ControlCode = IOCTL_SCSI_MINIPORT_IDENTIFY;
            strncpy ((char *) p -> Signature, "SCSIDISK", 8);  
            pin -> irDriveRegs.bCommandReg = IDE_ATA_IDENTIFY;
            pin -> bDriveNumber = drive;
            // 得到SCSI硬盘信息
            if (DeviceIoControl (hScsiDriveIOCTL, IOCTL_SCSI_MINIPORT,
                                 buffer,
                                 sizeof (SRB_IO_CONTROL) +
                                         sizeof (SENDCMDINPARAMS) - 1,
                                 buffer,
                                 sizeof (SRB_IO_CONTROL) + SENDIDLENGTH,
                                 &dummy, NULL))
            {
               SENDCMDOUTPARAMS *pOut =
                    (SENDCMDOUTPARAMS *) (buffer + sizeof (SRB_IO_CONTROL));
               IDSECTOR *pId = (IDSECTOR *) (pOut -> bBuffer);
               if (pId -> sModelNumber [0])
               {
                  int n = 0;
                  USHORT *pIdSector = (USHORT *) pId;
         
                  for (n = 0; n < 256; n++)
                      buffer[n] =pIdSector [n];
                  return TRUE;  // 读取成功
                           }
            }
                 }
         CloseHandle (hScsiDriveIOCTL);  // 关闭句柄
          }
   return FALSE;   // 读取失败
}

// Windows NT/2000/XP下读取IDE硬盘序列号
BOOL WinNTReadIDEHDSerial(DWORD * buffer)
{
   BYTE IdOutCmd [sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1];
   BOOL bFlag = FALSE;
   int  drive = 0;
   char driveName [256];
   HANDLE hPhysicalDriveIOCTL = 0;   
      
   sprintf (driveName, "\\\\.\\PhysicalDrive%d", drive);
   // Windows NT/2000/XP下创建文件需要管理员权限
   hPhysicalDriveIOCTL = CreateFile (driveName,
                            GENERIC_READ | GENERIC_WRITE,
                            FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
                            OPEN_EXISTING, 0, NULL);

   if (hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE)
   {
       GETVERSIONOUTPARAMS VersionParams;
       DWORD               cbBytesReturned = 0;

       // 得到驱动器的IO控制器版本
       memset ((void*) &VersionParams, 0, sizeof(VersionParams));
       if(DeviceIoControl (hPhysicalDriveIOCTL, IOCTL_GET_VERSION,
                               NULL, 0, &VersionParams,
                               sizeof(VersionParams),
                               &cbBytesReturned, NULL) )
           {        
          if (VersionParams.bIDEDeviceMap > 0)
                  {
              BYTE             bIDCmd = 0;   // IDE或者ATAPI识别命令
              SENDCMDINPARAMS  scip;

              // 如果驱动器是光驱,采用命令IDE_ATAPI_IDENTIFY, command,
              // 否则采用命令IDE_ATA_IDENTIFY读取驱动器信息
              bIDCmd = (VersionParams.bIDEDeviceMap >> drive & 0x10)?
                      IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;

              memset (&scip, 0, sizeof(scip));
              memset (IdOutCmd, 0, sizeof(IdOutCmd));
              // 获取驱动器信息
              if (WinNTGetIDEHDInfo (hPhysicalDriveIOCTL,
                                      &scip,
                                      (PSENDCMDOUTPARAMS)&IdOutCmd,
                                      (BYTE) bIDCmd,
                                      (BYTE) drive,
                                      &cbBytesReturned))
                          {
                  int m = 0;
                  USHORT *pIdSector = (USHORT *)
                             ((PSENDCMDOUTPARAMS) IdOutCmd) -> bBuffer;

                  for (m = 0; m < 256; m++)
                       buffer[m] = pIdSector [m];
                  bFlag = TRUE;  // 读取硬盘信息成功
                          }
                  }
           }
       CloseHandle (hPhysicalDriveIOCTL);  // 关闭句柄
   }
   return bFlag;
}
2010-2-1 11:06
0
雪    币: 131
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
各种型号的获取方法大致相同
2010-2-1 11:07
0
雪    币: 3
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
求代码测试,尤其是scsi硬盘,ssd硬盘,pci-e接口等等,还有操作系统,win7,win2008,winvista等。
代码添加了scsi硬盘的部分,不过在我的ide sata硬盘上我发现windowsxp不管是createfile(scsi0)还是createfile(harddrive0)都能返回正确的硬盘序列号。看来windows很多事情已经帮人搞定啦
上传的附件:
2010-2-1 16:16
0
雪    币: 3
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
对的,你在cmd下测试,得到结果。直接用我新上传的代码和程序。
当然没病毒啦,我已经把源码提供啦,你可以自己用vc2008打开编译。
2010-2-1 16:20
0
雪    币: 210
活跃值: (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
eh,我这好像SCSI服务器硬盘的没搞定
2010-2-3 18:21
0
雪    币: 3
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
贴出结果来,我看看
2010-2-3 19:19
0
雪    币: 210
活跃值: (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
在DELL poweredge 6850系列测试了,返回为空(SCSI硬盘)
2010-2-3 19:37
0
雪    币: 210
活跃值: (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
我写错了,是SCSI 的,刚才把机器型号说了,还不知道怎么用VC,呵呵,一直没用过那个
2010-2-3 19:48
0
雪    币: 2096
活跃值: (100)
能力值: (RANK:420 )
在线值:
发帖
回帖
粉丝
15
我沒 vc2008, 我電腦只有 Dev C++ 4.01 版~及 Microsoft Visual C++ 6.0 版~
不然你直接給我 exe file, 我 download 去運行看看~~我星期五晚上才會回到家~~
所以要星期六才能幫你 test~
2010-2-3 21:16
0
雪    币: 3
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
什么是你的系统?如果vista以上,要求administrator权限。另外你的系统是不是有raid?
2010-2-4 00:03
0
雪    币: 3
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
那个包里有编译好的exe
2010-2-4 00:05
0
雪    币: 3
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
算啦,用这个测试吧。我的程序不用啦。
http://www.winsim.com/diskid32/diskid32.html

下载
http://www.winsim.com/diskid32/diskid32.exe
网页上也有源码连接:
http://www.winsim.com/diskid32/diskid32.cpp
2010-2-4 01:56
0
雪    币: 3
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
谁能给我发一份windows drive kit下面的SCSI Pass Through Interface sample代码
2010-2-4 02:47
0
雪    币: 210
活跃值: (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
昨天下载了VC2008,这几天学习一下,上手应该不难
操作系统是windows 2003 sp1  做了raid raid有影响么
我原来只会用wmi来读取硬盘序列号,不知道你是使用什么原理来处理这个问题的
2010-2-4 08:53
0
雪    币: 210
活跃值: (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
才看到这个.... 才稍微运行了下
Linux win2003 winxp
sata ide scsi 目前看来都正常
2010-2-4 08:59
0
雪    币: 3
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
好,把结果贴出来我看看。有raid的话要采用另外的一些函数来读硬盘序列号。你看diskid32的网页上有介绍。
具体我也 不了解,我只是到处找代码而已。wmi是直接调用硬件驱动读序列号还是读注册表的?
有代码吗?
2010-2-5 19:39
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
ATA WDC WD2502ABYS-2 SCSI Disk Device 获取失败。
2011-6-6 15:34
0
游客
登录 | 注册 方可回帖
返回
//