CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VC/MFC >  基础类

如何得到一台电脑区别于其他电脑的唯一标志?

楼主shanglinhu(shanglinhu)2006-06-01 20:08:22 在 VC/MFC / 基础类 提问

大家好!我想问个问题,怎样在WIN98中操作系统中得到CPU的标识?比如我有一个程序,要使一个程序只能运行在一台电脑上,即同一个程序在不同电脑间不能复制,我现在运行环境是WIN98,VC中怎么做?在其他操作系统中我知道,但WIN98下不知道怎么写?谢谢! 问题点数:40、回复次数:7Top

1 楼kugou123(酷狗)(彪悍的人生,不需要解释 www.xiaozhou.net)回复于 2006-06-01 21:05:17 得分 5

CPU   ID   +   硬盘序列号   +   网卡MAC  
   
  综合判断Top

2 楼KeSummer([IN]LPVOID YourLove,[OUT]LPVOID MyLove)回复于 2006-06-01 21:14:38 得分 30

用汇编指令取得CPU信息:代码(VC)  
  //   “获得Intel   CPU   ID”按钮消息处理函数  
  void   CIntelCPUIDDlg::OnBtnCPUID()    
  {  
      unsigned   long   s1,s2;  
      unsigned   char   vendor_id[]="------------";//CPU提供商ID  
      CString   str1,str2,str3;  
      //   以下为获得CPU   ID的汇编语言指令  
      _asm         //   得到CPU提供商信息    
      {      
              xor   eax,eax       //   将eax清0  
              cpuid                   //   获取CPUID的指令  
              mov   dword   ptr   vendor_id,ebx  
              mov   dword   ptr   vendor_id[+4],edx  
              mov   dword   ptr   vendor_id[+8],ecx      
      }  
      str1.Format("%s",vendor_id);  
     
      _asm         //   得到CPU   ID的高32位    
      {    
      mov   eax,01h          
              xor   edx,edx  
              cpuid  
              mov   s2,eax  
      }  
      str2.Format("%08X-",s2);  
       
      _asm         //   得到CPU   ID的低64位  
      {    
      mov   eax,03h  
              xor   ecx,ecx  
              xor   edx,edx  
              cpuid  
              mov   s1,edx  
              mov   s2,ecx  
      }  
      str3.Format("%08X-%08X\n",s1,s2);  
   
      str2=str2+str3;  
      m_editVendor.SetWindowText(str1);  
      m_editCPUID.SetWindowText(str2);  
  }  
   
  Top

3 楼KeSummer([IN]LPVOID YourLove,[OUT]LPVOID MyLove)回复于 2006-06-01 21:15:48 得分 0

硬盘序列号  
  //   读取硬盘序列号函数  
  char*   CGetHDSerial::GetHDSerial()  
  {  
      m_buffer[0]='\n';  
      //   得到当前操作系统版本  
      OSVERSIONINFO   OSVersionInfo;  
      OSVersionInfo.dwOSVersionInfoSize   =   sizeof(OSVERSIONINFO);  
      GetVersionEx(   &OSVersionInfo);  
      if   (OSVersionInfo.dwPlatformId   !=   VER_PLATFORM_WIN32_NT)  
      {        
      //   Windows   9x/ME下读取硬盘序列号  
      WORD   m_wWin9xHDSerial[256];  
      Win9xReadHDSerial(m_wWin9xHDSerial);      
              strcpy   (m_buffer,   WORDToChar   (m_wWin9xHDSerial,   10,   19));  
      }  
      else  
      {  
              //   Windows   NT/2000/XP下读取硬盘序列号  
      DWORD   m_wWinNTHDSerial[256];      
      //   判断是否有SCSI硬盘  
              if   (   !   WinNTReadIDEHDSerial(m_wWinNTHDSerial))    
                WinNTReadSCSIHDSerial(m_wWinNTHDSerial);      
              strcpy   (m_buffer,   DWORDToChar   (m_wWinNTHDSerial,   10,   19));  
      }  
      return   m_buffer;  
  }  
   
  //   Windows9X/ME系统下读取硬盘序列号  
  void   _stdcall   CGetHDSerial::Win9xReadHDSerial(WORD   *   buffer)  
  {  
  int   i;  
  for(i=0;i<256;i++)    
  buffer[i]=0;  
          _asm  
          {  
              push   eax                  
                  //获取修改的中断的中断描述符(中断门)地址  
                  sidt   m_IDTR  
                  mov   eax,dword   ptr   [m_IDTR+02h]                  
                  add   eax,3*08h+04h  
                  cli  
                  //保存原先的中断入口地址  
                  push   ecx  
                  mov   ecx,dword   ptr   [eax]  
                  mov   cx,word   ptr   [eax-04h]  
                  mov   dword   ptr   m_OldInterruptAddress,ecx  
                  pop   ecx  
                  //设置修改的中断入口地址为新的中断处理程序入口地址  
                  push   ebx  
                  lea   ebx,InterruptProcess  
                  mov   word   ptr   [eax-04h],bx  
                  shr   ebx,10h  
                  mov   word   ptr   [eax+02h],bx  
                  pop   ebx  
                  //执行中断,转到Ring   0(类似CIH病毒原理)  
  int   3h  
                  //恢复原先的中断入口地址  
                  push   ecx  
                  mov   ecx,dword   ptr   m_OldInterruptAddress  
                  mov   word   ptr   [eax-04h],cx  
                  shr   ecx,10h  
                  mov   word   ptr   [eax+02h],cx  
                  pop   ecx  
                  sti  
                  pop   eax  
          }    
  for(i=0;i<256;i++)  
  buffer[i]=m_serial[i];  
  }  
   
  //   Windows   9x/ME系统下,将字类型(WORD)的硬盘信息转换为字符类型(char)  
  char   *   CGetHDSerial::WORDToChar   (WORD   diskdata   [256],   int   firstIndex,   int   lastIndex)  
  {  
        static   char   string   [1024];  
        int   index   =   0;  
        int   position   =   0;  
   
        //   按照高字节在前,低字节在后的顺序将字数组diskdata   中内容存入到字符串string中    
        for   (index   =   firstIndex;   index   <=   lastIndex;   index++)  
        {  
              //   存入字中的高字节  
              string   [position]   =   (char)   (diskdata   [index]   /   256);  
              position++;  
              //   存入字中的低字节  
              string   [position]   =   (char)   (diskdata   [index]   %   256);  
              position++;  
        }  
        //     添加字符串结束标志  
        string   [position]   =   '\0';  
   
        //     删除字符串中空格  
        for   (index   =   position   -   1;   index   >   0   &&   '   '   ==   string   [index];   index--)  
              string   [index]   =   '\0';  
   
        return   string;  
  }  
  Top

4 楼KeSummer([IN]LPVOID YourLove,[OUT]LPVOID MyLove)回复于 2006-06-01 21:16:02 得分 0

 
  //   Windows   NT/2000/XP系统下,将双字类型(DWORD)的硬盘信息转换为字符类型(char)  
  char*   CGetHDSerial::DWORDToChar   (DWORD   diskdata   [256],   int   firstIndex,   int   lastIndex)  
  {  
        static   char   string   [1024];  
        int   index   =   0;  
        int   position   =   0;  
   
        //   按照高字节在前,低字节在后的顺序将双字中的低字存入到字符串string中    
        for   (index   =   firstIndex;   index   <=   lastIndex;   index++)  
        {  
              //   存入低字中的高字节  
              string   [position]   =   (char)   (diskdata   [index]   /   256);  
              position++;  
              //   存入低字中的低字节  
              string   [position]   =   (char)   (diskdata   [index]   %   256);  
              position++;  
        }  
        //     添加字符串结束标志  
        string   [position]   =   '\0';  
   
        //     删除字符串中空格  
        for   (index   =   position   -   1;   index   >   0   &&   '   '   ==   string   [index];   index--)  
              string   [index]   =   '\0';  
   
        return   string;  
  }  
   
  //   Windows   NT/2000/XP下读取IDE硬盘序列号  
  BOOL   CGetHDSerial::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;  
  }  
   
  //   WindowsNT/2000/XP系统下读取SCSI硬盘序列号  
  BOOL   CGetHDSerial::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   CGetHDSerial::WinNTGetIDEHDInfo   (HANDLE   hPhysicalDriveIOCTL,   PSENDCMDINPARAMS   pSCIP,  
                                    PSENDCMDOUTPARAMS   pSCOP,   BYTE   bIDCmd,   BYTE   bDriveNum,  
                                    PDWORD   lpcbBytesReturned)  
  {  
        //   为读取设备信息准备参数  
        pSCIP   ->   cBufferSize   =   IDENTIFY_BUFFER_SIZE;  
        pSCIP   ->   irDriveRegs.bFeaturesReg   =   0;  
        pSCIP   ->   irDriveRegs.bSectorCountReg   =   1;  
        pSCIP   ->   irDriveRegs.bSectorNumberReg   =   1;  
        pSCIP   ->   irDriveRegs.bCylLowReg   =   0;  
        pSCIP   ->   irDriveRegs.bCylHighReg   =   0;  
   
        //   计算驱动器位置  
        pSCIP   ->   irDriveRegs.bDriveHeadReg   =   0xA0   |   ((bDriveNum   &   1)   <<   4);  
   
        //   设置读取命令  
        pSCIP   ->   irDriveRegs.bCommandReg   =   bIDCmd;  
        pSCIP   ->   bDriveNumber   =   bDriveNum;  
        pSCIP   ->   cBufferSize   =   IDENTIFY_BUFFER_SIZE;  
         
        //   读取驱动器信息  
        return   (   DeviceIoControl   (hPhysicalDriveIOCTL,   IOCTL_GET_DRIVE_INFO,  
                                (LPVOID)   pSCIP,  
                                sizeof(SENDCMDINPARAMS)   -   1,  
                                (LPVOID)   pSCOP,  
                                sizeof(SENDCMDOUTPARAMS)   +   IDENTIFY_BUFFER_SIZE   -   1,  
                                lpcbBytesReturned,   NULL)   );  
  }Top

5 楼jacklzw88(不可爱咯)回复于 2006-06-02 09:21:10 得分 3

mac地址可以被改,还是CPU   ID   +   硬盘序列号   ,不错Top

6 楼SeRapHiw(灯芯草)回复于 2006-06-04 13:53:58 得分 2

其实获取主板信息是最好的,或者bios信息  
  不能不让人换硬盘吧?Top

7 楼gudulyn(冰楠)回复于 2006-06-04 15:33:50 得分 0

mark。Top

相关问题

关键词

得分解答快速导航

  • 帖主:shanglinhu
  • kugou123
  • KeSummer
  • jacklzw88
  • SeRapHiw

相关链接

  • Visual C++类图书
  • Visual C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo